mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-19 18:53:52 +08:00
V4L/DVB (3427): audmode and rxsubchans fixes (VIDIOC_G/S_TUNER)
- Audmode and rxsubchans fixes in msp3400, tuner, tvaudio and cx25840. - msp3400 cleanups Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
This commit is contained in:
parent
9aeb4b051b
commit
8a4b275f9c
@ -753,6 +753,7 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
|
||||
|
||||
memset(input, 0, sizeof(*input));
|
||||
input->index = state->aud_input;
|
||||
input->capability = V4L2_AUDCAP_STEREO;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -763,7 +764,6 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
|
||||
case VIDIOC_G_TUNER:
|
||||
{
|
||||
u8 mode = cx25840_read(client, 0x804);
|
||||
u8 pref = cx25840_read(client, 0x809) & 0xf;
|
||||
u8 vpres = cx25840_read(client, 0x80a) & 0x10;
|
||||
int val = 0;
|
||||
|
||||
@ -783,44 +783,49 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
|
||||
val |= V4L2_TUNER_SUB_MONO;
|
||||
|
||||
if (mode == 2 || mode == 4)
|
||||
val |= V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
|
||||
val = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
|
||||
|
||||
if (mode & 0x10)
|
||||
val |= V4L2_TUNER_SUB_SAP;
|
||||
|
||||
vt->rxsubchans = val;
|
||||
|
||||
switch (pref) {
|
||||
case 0:
|
||||
vt->audmode = V4L2_TUNER_MODE_MONO;
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
vt->audmode = V4L2_TUNER_MODE_LANG2;
|
||||
break;
|
||||
case 4:
|
||||
default:
|
||||
vt->audmode = V4L2_TUNER_MODE_STEREO;
|
||||
}
|
||||
vt->audmode = state->audmode;
|
||||
break;
|
||||
}
|
||||
|
||||
case VIDIOC_S_TUNER:
|
||||
if (state->radio)
|
||||
break;
|
||||
|
||||
switch (vt->audmode) {
|
||||
case V4L2_TUNER_MODE_MONO:
|
||||
case V4L2_TUNER_MODE_LANG1:
|
||||
/* Force PREF_MODE to MONO */
|
||||
/* mono -> mono
|
||||
stereo -> mono
|
||||
bilingual -> lang1 */
|
||||
cx25840_and_or(client, 0x809, ~0xf, 0x00);
|
||||
break;
|
||||
case V4L2_TUNER_MODE_STEREO:
|
||||
/* Force PREF_MODE to STEREO */
|
||||
case V4L2_TUNER_MODE_LANG1:
|
||||
/* mono -> mono
|
||||
stereo -> stereo
|
||||
bilingual -> lang1 */
|
||||
cx25840_and_or(client, 0x809, ~0xf, 0x04);
|
||||
break;
|
||||
case V4L2_TUNER_MODE_STEREO:
|
||||
/* mono -> mono
|
||||
stereo -> stereo
|
||||
bilingual -> lang1/lang2 */
|
||||
cx25840_and_or(client, 0x809, ~0xf, 0x07);
|
||||
break;
|
||||
case V4L2_TUNER_MODE_LANG2:
|
||||
/* Force PREF_MODE to LANG2 */
|
||||
/* mono -> mono
|
||||
stereo ->stereo
|
||||
bilingual -> lang2 */
|
||||
cx25840_and_or(client, 0x809, ~0xf, 0x01);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
state->audmode = vt->audmode;
|
||||
break;
|
||||
|
||||
case VIDIOC_G_FMT:
|
||||
@ -901,6 +906,7 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address,
|
||||
state->aud_input = CX25840_AUDIO8;
|
||||
state->audclk_freq = 48000;
|
||||
state->pvr150_workaround = 0;
|
||||
state->audmode = V4L2_TUNER_MODE_LANG1;
|
||||
|
||||
cx25840_initialize(client, 1);
|
||||
|
||||
|
@ -78,6 +78,7 @@ struct cx25840_state {
|
||||
enum cx25840_video_input vid_input;
|
||||
enum cx25840_audio_input aud_input;
|
||||
u32 audclk_freq;
|
||||
int audmode;
|
||||
};
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
@ -411,9 +411,9 @@ static int msp_mode_v4l2_to_v4l1(int rxsubchans)
|
||||
if (rxsubchans & V4L2_TUNER_SUB_STEREO)
|
||||
mode |= VIDEO_SOUND_STEREO;
|
||||
if (rxsubchans & V4L2_TUNER_SUB_LANG2)
|
||||
mode |= VIDEO_SOUND_LANG2;
|
||||
mode |= VIDEO_SOUND_LANG2 | VIDEO_SOUND_STEREO;
|
||||
if (rxsubchans & V4L2_TUNER_SUB_LANG1)
|
||||
mode |= VIDEO_SOUND_LANG1;
|
||||
mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_STEREO;
|
||||
if (mode == 0)
|
||||
mode |= VIDEO_SOUND_MONO;
|
||||
return mode;
|
||||
@ -430,21 +430,6 @@ static int msp_mode_v4l1_to_v4l2(int mode)
|
||||
return V4L2_TUNER_MODE_MONO;
|
||||
}
|
||||
|
||||
static void msp_any_detect_stereo(struct i2c_client *client)
|
||||
{
|
||||
struct msp_state *state = i2c_get_clientdata(client);
|
||||
|
||||
switch (state->opmode) {
|
||||
case OPMODE_MANUAL:
|
||||
case OPMODE_AUTODETECT:
|
||||
autodetect_stereo(client);
|
||||
break;
|
||||
case OPMODE_AUTOSELECT:
|
||||
msp34xxg_detect_stereo(client);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static struct v4l2_queryctrl msp_qctrl_std[] = {
|
||||
{
|
||||
.id = V4L2_CID_AUDIO_VOLUME,
|
||||
@ -506,22 +491,6 @@ static struct v4l2_queryctrl msp_qctrl_sound_processing[] = {
|
||||
};
|
||||
|
||||
|
||||
static void msp_any_set_audmode(struct i2c_client *client, int audmode)
|
||||
{
|
||||
struct msp_state *state = i2c_get_clientdata(client);
|
||||
|
||||
switch (state->opmode) {
|
||||
case OPMODE_MANUAL:
|
||||
case OPMODE_AUTODETECT:
|
||||
state->watch_stereo = 0;
|
||||
msp3400c_setstereo(client, audmode);
|
||||
break;
|
||||
case OPMODE_AUTOSELECT:
|
||||
msp34xxg_set_audmode(client, audmode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int msp_get_ctrl(struct i2c_client *client, struct v4l2_control *ctrl)
|
||||
{
|
||||
struct msp_state *state = i2c_get_clientdata(client);
|
||||
@ -656,7 +625,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
||||
msp_set_scart(client, scart, 0);
|
||||
msp_write_dsp(client, 0x000d, 0x1900);
|
||||
if (state->opmode != OPMODE_AUTOSELECT)
|
||||
msp3400c_setstereo(client, state->audmode);
|
||||
msp_set_audmode(client);
|
||||
}
|
||||
msp_wake_thread(client);
|
||||
break;
|
||||
@ -670,8 +639,8 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
||||
switch (state->opmode) {
|
||||
case OPMODE_MANUAL:
|
||||
/* set msp3400 to FM radio mode */
|
||||
msp3400c_setmode(client, MSP_MODE_FM_RADIO);
|
||||
msp3400c_setcarrier(client, MSP_CARRIER(10.7),
|
||||
msp3400c_set_mode(client, MSP_MODE_FM_RADIO);
|
||||
msp3400c_set_carrier(client, MSP_CARRIER(10.7),
|
||||
MSP_CARRIER(10.7));
|
||||
msp_set_audio(client);
|
||||
break;
|
||||
@ -705,7 +674,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
||||
if (state->radio)
|
||||
break;
|
||||
if (state->opmode == OPMODE_AUTOSELECT)
|
||||
msp_any_detect_stereo(client);
|
||||
msp_detect_stereo(client);
|
||||
va->mode = msp_mode_v4l2_to_v4l1(state->rxsubchans);
|
||||
break;
|
||||
}
|
||||
@ -721,8 +690,9 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
||||
state->treble = va->treble;
|
||||
msp_set_audio(client);
|
||||
|
||||
if (va->mode != 0 && state->radio == 0)
|
||||
msp_any_set_audmode(client, msp_mode_v4l1_to_v4l2(va->mode));
|
||||
if (va->mode != 0 && state->radio == 0) {
|
||||
state->audmode = msp_mode_v4l1_to_v4l2(va->mode);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -864,7 +834,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
||||
msp_set_scart(client, scart, 0);
|
||||
msp_write_dsp(client, 0x000d, 0x1900);
|
||||
}
|
||||
msp_any_set_audmode(client, state->audmode);
|
||||
msp_set_audmode(client);
|
||||
msp_wake_thread(client);
|
||||
break;
|
||||
}
|
||||
@ -876,7 +846,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
||||
if (state->radio)
|
||||
break;
|
||||
if (state->opmode == OPMODE_AUTOSELECT)
|
||||
msp_any_detect_stereo(client);
|
||||
msp_detect_stereo(client);
|
||||
vt->audmode = state->audmode;
|
||||
vt->rxsubchans = state->rxsubchans;
|
||||
vt->capability = V4L2_TUNER_CAP_STEREO |
|
||||
@ -890,8 +860,9 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
||||
|
||||
if (state->radio) /* TODO: add mono/stereo support for radio */
|
||||
break;
|
||||
state->audmode = vt->audmode;
|
||||
/* only set audmode */
|
||||
msp_any_set_audmode(client, vt->audmode);
|
||||
msp_set_audmode(client);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -981,7 +952,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
||||
const char *p;
|
||||
|
||||
if (state->opmode == OPMODE_AUTOSELECT)
|
||||
msp_any_detect_stereo(client);
|
||||
msp_detect_stereo(client);
|
||||
v4l_info(client, "%s rev1 = 0x%04x rev2 = 0x%04x\n",
|
||||
client->name, state->rev1, state->rev2);
|
||||
v4l_info(client, "Audio: volume %d%s\n",
|
||||
@ -1082,7 +1053,7 @@ static int msp_attach(struct i2c_adapter *adapter, int address, int kind)
|
||||
|
||||
memset(state, 0, sizeof(*state));
|
||||
state->v4l2_std = V4L2_STD_NTSC;
|
||||
state->audmode = V4L2_TUNER_MODE_STEREO;
|
||||
state->audmode = V4L2_TUNER_MODE_LANG1;
|
||||
state->volume = 58880; /* 0db gain */
|
||||
state->balance = 32768; /* 0db gain */
|
||||
state->bass = 32768;
|
||||
|
@ -109,7 +109,7 @@ static struct msp3400c_init_data_dem {
|
||||
{-2, -8, -10, 10, 50, 86},
|
||||
{-4, -12, -9, 23, 79, 126},
|
||||
MSP_CARRIER(6.5), MSP_CARRIER(6.5),
|
||||
0x00c6, 0x0140, 0x0120, 0x7c03
|
||||
0x00c6, 0x0140, 0x0120, 0x7c00
|
||||
},
|
||||
};
|
||||
|
||||
@ -154,53 +154,60 @@ const char *msp_standard_std_name(int std)
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
void msp3400c_setcarrier(struct i2c_client *client, int cdo1, int cdo2)
|
||||
void msp_set_source(struct i2c_client *client, u16 src)
|
||||
{
|
||||
struct msp_state *state = i2c_get_clientdata(client);
|
||||
|
||||
if (msp_dolby) {
|
||||
msp_write_dsp(client, 0x0008, 0x0520); /* I2S1 */
|
||||
msp_write_dsp(client, 0x0009, 0x0620); /* I2S2 */
|
||||
} else {
|
||||
msp_write_dsp(client, 0x0008, src);
|
||||
msp_write_dsp(client, 0x0009, src);
|
||||
}
|
||||
msp_write_dsp(client, 0x000a, src);
|
||||
msp_write_dsp(client, 0x000b, src);
|
||||
msp_write_dsp(client, 0x000c, src);
|
||||
if (state->has_scart23_in_scart2_out)
|
||||
msp_write_dsp(client, 0x0041, src);
|
||||
}
|
||||
|
||||
void msp3400c_set_carrier(struct i2c_client *client, int cdo1, int cdo2)
|
||||
{
|
||||
msp_write_dem(client, 0x0093, cdo1 & 0xfff);
|
||||
msp_write_dem(client, 0x009b, cdo1 >> 12);
|
||||
msp_write_dem(client, 0x00a3, cdo2 & 0xfff);
|
||||
msp_write_dem(client, 0x00ab, cdo2 >> 12);
|
||||
msp_write_dem(client, 0x0056, 0); /*LOAD_REG_1/2*/
|
||||
msp_write_dem(client, 0x0056, 0); /* LOAD_REG_1/2 */
|
||||
}
|
||||
|
||||
void msp3400c_setmode(struct i2c_client *client, int type)
|
||||
void msp3400c_set_mode(struct i2c_client *client, int mode)
|
||||
{
|
||||
struct msp_state *state = i2c_get_clientdata(client);
|
||||
struct msp3400c_init_data_dem *data = &msp3400c_init_data[mode];
|
||||
int i;
|
||||
|
||||
v4l_dbg(1, msp_debug, client, "setmode: %d\n", type);
|
||||
state->mode = type;
|
||||
v4l_dbg(1, msp_debug, client, "set_mode: %d\n", mode);
|
||||
state->mode = mode;
|
||||
state->rxsubchans = V4L2_TUNER_SUB_MONO;
|
||||
|
||||
msp_write_dem(client, 0x00bb, msp3400c_init_data[type].ad_cv);
|
||||
msp_write_dem(client, 0x00bb, data->ad_cv);
|
||||
|
||||
for (i = 5; i >= 0; i--) /* fir 1 */
|
||||
msp_write_dem(client, 0x0001, msp3400c_init_data[type].fir1[i]);
|
||||
msp_write_dem(client, 0x0001, data->fir1[i]);
|
||||
|
||||
msp_write_dem(client, 0x0005, 0x0004); /* fir 2 */
|
||||
msp_write_dem(client, 0x0005, 0x0040);
|
||||
msp_write_dem(client, 0x0005, 0x0000);
|
||||
for (i = 5; i >= 0; i--)
|
||||
msp_write_dem(client, 0x0005, msp3400c_init_data[type].fir2[i]);
|
||||
msp_write_dem(client, 0x0005, data->fir2[i]);
|
||||
|
||||
msp_write_dem(client, 0x0083, msp3400c_init_data[type].mode_reg);
|
||||
msp_write_dem(client, 0x0083, data->mode_reg);
|
||||
|
||||
msp3400c_setcarrier(client, msp3400c_init_data[type].cdo1,
|
||||
msp3400c_init_data[type].cdo2);
|
||||
msp3400c_set_carrier(client, data->cdo1, data->cdo2);
|
||||
|
||||
msp_write_dem(client, 0x0056, 0); /*LOAD_REG_1/2*/
|
||||
|
||||
if (msp_dolby) {
|
||||
msp_write_dsp(client, 0x0008, 0x0520); /* I2S1 */
|
||||
msp_write_dsp(client, 0x0009, 0x0620); /* I2S2 */
|
||||
msp_write_dsp(client, 0x000b, msp3400c_init_data[type].dsp_src);
|
||||
} else {
|
||||
msp_write_dsp(client, 0x0008, msp3400c_init_data[type].dsp_src);
|
||||
msp_write_dsp(client, 0x0009, msp3400c_init_data[type].dsp_src);
|
||||
msp_write_dsp(client, 0x000b, msp3400c_init_data[type].dsp_src);
|
||||
}
|
||||
msp_write_dsp(client, 0x000a, msp3400c_init_data[type].dsp_src);
|
||||
msp_write_dsp(client, 0x000e, msp3400c_init_data[type].dsp_matrix);
|
||||
msp_set_source(client, data->dsp_src);
|
||||
msp_write_dsp(client, 0x000e, data->dsp_matrix);
|
||||
|
||||
if (state->has_nicam) {
|
||||
/* nicam prescale */
|
||||
@ -208,29 +215,31 @@ void msp3400c_setmode(struct i2c_client *client, int type)
|
||||
}
|
||||
}
|
||||
|
||||
/* turn on/off nicam + stereo */
|
||||
void msp3400c_setstereo(struct i2c_client *client, int audmode)
|
||||
/* Set audio mode. Note that the pre-'G' models do not support BTSC+SAP,
|
||||
nor do they support stereo BTSC. */
|
||||
void msp3400c_set_audmode(struct i2c_client *client)
|
||||
{
|
||||
static char *strmode[] = { "mono", "stereo", "lang2", "lang1" };
|
||||
struct msp_state *state = i2c_get_clientdata(client);
|
||||
int nicam = 0; /* channel source: FM/AM or nicam */
|
||||
int src = 0;
|
||||
char *modestr = (state->audmode >= 0 && state->audmode < 4) ?
|
||||
strmode[state->audmode] : "unknown";
|
||||
int src = 0; /* channel source: FM/AM, nicam or SCART */
|
||||
|
||||
if (state->opmode == OPMODE_AUTOSELECT) {
|
||||
/* this method would break everything, let's make sure
|
||||
* it's never called
|
||||
*/
|
||||
v4l_dbg(1, msp_debug, client, "setstereo called with mode=%d instead of set_source (ignored)\n",
|
||||
audmode);
|
||||
v4l_dbg(1, msp_debug, client,
|
||||
"set_audmode called with mode=%d instead of set_source (ignored)\n",
|
||||
state->audmode);
|
||||
return;
|
||||
}
|
||||
|
||||
/* switch demodulator */
|
||||
switch (state->mode) {
|
||||
case MSP_MODE_FM_TERRA:
|
||||
v4l_dbg(1, msp_debug, client, "FM setstereo: %s\n", strmode[audmode]);
|
||||
msp3400c_setcarrier(client, state->second, state->main);
|
||||
switch (audmode) {
|
||||
v4l_dbg(1, msp_debug, client, "FM set_audmode: %s\n", modestr);
|
||||
switch (state->audmode) {
|
||||
case V4L2_TUNER_MODE_STEREO:
|
||||
msp_write_dsp(client, 0x000e, 0x3001);
|
||||
break;
|
||||
@ -242,50 +251,49 @@ void msp3400c_setstereo(struct i2c_client *client, int audmode)
|
||||
}
|
||||
break;
|
||||
case MSP_MODE_FM_SAT:
|
||||
v4l_dbg(1, msp_debug, client, "SAT setstereo: %s\n", strmode[audmode]);
|
||||
switch (audmode) {
|
||||
v4l_dbg(1, msp_debug, client, "SAT set_audmode: %s\n", modestr);
|
||||
switch (state->audmode) {
|
||||
case V4L2_TUNER_MODE_MONO:
|
||||
msp3400c_setcarrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5));
|
||||
msp3400c_set_carrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5));
|
||||
break;
|
||||
case V4L2_TUNER_MODE_STEREO:
|
||||
msp3400c_setcarrier(client, MSP_CARRIER(7.2), MSP_CARRIER(7.02));
|
||||
msp3400c_set_carrier(client, MSP_CARRIER(7.2), MSP_CARRIER(7.02));
|
||||
break;
|
||||
case V4L2_TUNER_MODE_LANG1:
|
||||
msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02));
|
||||
msp3400c_set_carrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02));
|
||||
break;
|
||||
case V4L2_TUNER_MODE_LANG2:
|
||||
msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02));
|
||||
msp3400c_set_carrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case MSP_MODE_FM_NICAM1:
|
||||
case MSP_MODE_FM_NICAM2:
|
||||
case MSP_MODE_AM_NICAM:
|
||||
v4l_dbg(1, msp_debug, client, "NICAM setstereo: %s\n",strmode[audmode]);
|
||||
msp3400c_setcarrier(client,state->second,state->main);
|
||||
v4l_dbg(1, msp_debug, client, "NICAM set_audmode: %s\n",modestr);
|
||||
msp3400c_set_carrier(client, state->second, state->main);
|
||||
if (state->nicam_on)
|
||||
nicam=0x0100;
|
||||
src = 0x0100; /* NICAM */
|
||||
break;
|
||||
case MSP_MODE_BTSC:
|
||||
v4l_dbg(1, msp_debug, client, "BTSC setstereo: %s\n",strmode[audmode]);
|
||||
nicam=0x0300;
|
||||
v4l_dbg(1, msp_debug, client, "BTSC set_audmode: %s\n",modestr);
|
||||
break;
|
||||
case MSP_MODE_EXTERN:
|
||||
v4l_dbg(1, msp_debug, client, "extern setstereo: %s\n",strmode[audmode]);
|
||||
nicam = 0x0200;
|
||||
v4l_dbg(1, msp_debug, client, "extern set_audmode: %s\n",modestr);
|
||||
src = 0x0200; /* SCART */
|
||||
break;
|
||||
case MSP_MODE_FM_RADIO:
|
||||
v4l_dbg(1, msp_debug, client, "FM-Radio setstereo: %s\n",strmode[audmode]);
|
||||
v4l_dbg(1, msp_debug, client, "FM-Radio set_audmode: %s\n",modestr);
|
||||
break;
|
||||
default:
|
||||
v4l_dbg(1, msp_debug, client, "mono setstereo\n");
|
||||
v4l_dbg(1, msp_debug, client, "mono set_audmode\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* switch audio */
|
||||
switch (audmode) {
|
||||
switch (state->audmode) {
|
||||
case V4L2_TUNER_MODE_STEREO:
|
||||
src = 0x0020 | nicam;
|
||||
src |= 0x0020;
|
||||
break;
|
||||
case V4L2_TUNER_MODE_MONO:
|
||||
if (state->mode == MSP_MODE_AM_NICAM) {
|
||||
@ -296,29 +304,22 @@ void msp3400c_setstereo(struct i2c_client *client, int audmode)
|
||||
src = 0x0200;
|
||||
break;
|
||||
}
|
||||
if (state->rxsubchans & V4L2_TUNER_SUB_STEREO)
|
||||
src = 0x0030;
|
||||
break;
|
||||
case V4L2_TUNER_MODE_LANG1:
|
||||
src = 0x0000 | nicam;
|
||||
/* switch to stereo for stereo transmission, otherwise
|
||||
keep first language */
|
||||
if (state->rxsubchans & V4L2_TUNER_SUB_STEREO)
|
||||
src |= 0x0020;
|
||||
break;
|
||||
case V4L2_TUNER_MODE_LANG2:
|
||||
src = 0x0010 | nicam;
|
||||
src |= 0x0010;
|
||||
break;
|
||||
}
|
||||
v4l_dbg(1, msp_debug, client, "setstereo final source/matrix = 0x%x\n", src);
|
||||
v4l_dbg(1, msp_debug, client, "set_audmode final source/matrix = 0x%x\n", src);
|
||||
|
||||
if (msp_dolby) {
|
||||
msp_write_dsp(client, 0x0008, 0x0520);
|
||||
msp_write_dsp(client, 0x0009, 0x0620);
|
||||
msp_write_dsp(client, 0x000a, src);
|
||||
msp_write_dsp(client, 0x000b, src);
|
||||
} else {
|
||||
msp_write_dsp(client, 0x0008, src);
|
||||
msp_write_dsp(client, 0x0009, src);
|
||||
msp_write_dsp(client, 0x000a, src);
|
||||
msp_write_dsp(client, 0x000b, src);
|
||||
msp_write_dsp(client, 0x000c, src);
|
||||
if (state->has_scart23_in_scart2_out)
|
||||
msp_write_dsp(client, 0x0041, src);
|
||||
}
|
||||
msp_set_source(client, src);
|
||||
}
|
||||
|
||||
static void msp3400c_print_mode(struct i2c_client *client)
|
||||
@ -346,12 +347,12 @@ static void msp3400c_print_mode(struct i2c_client *client)
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
int autodetect_stereo(struct i2c_client *client)
|
||||
static int msp3400c_detect_stereo(struct i2c_client *client)
|
||||
{
|
||||
struct msp_state *state = i2c_get_clientdata(client);
|
||||
int val;
|
||||
int rxsubchans = state->rxsubchans;
|
||||
int newnicam = state->nicam_on;
|
||||
int newnicam = state->nicam_on;
|
||||
int update = 0;
|
||||
|
||||
switch (state->mode) {
|
||||
@ -361,7 +362,7 @@ int autodetect_stereo(struct i2c_client *client)
|
||||
val -= 65536;
|
||||
v4l_dbg(2, msp_debug, client, "stereo detect register: %d\n", val);
|
||||
if (val > 4096) {
|
||||
rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
|
||||
rxsubchans = V4L2_TUNER_SUB_STEREO;
|
||||
} else if (val < -4096) {
|
||||
rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
|
||||
} else {
|
||||
@ -385,14 +386,11 @@ int autodetect_stereo(struct i2c_client *client)
|
||||
break;
|
||||
case 1:
|
||||
case 9:
|
||||
rxsubchans = V4L2_TUNER_SUB_MONO
|
||||
| V4L2_TUNER_SUB_LANG1;
|
||||
rxsubchans = V4L2_TUNER_SUB_MONO;
|
||||
break;
|
||||
case 2:
|
||||
case 10:
|
||||
rxsubchans = V4L2_TUNER_SUB_MONO
|
||||
| V4L2_TUNER_SUB_LANG1
|
||||
| V4L2_TUNER_SUB_LANG2;
|
||||
rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
|
||||
break;
|
||||
default:
|
||||
rxsubchans = V4L2_TUNER_SUB_MONO;
|
||||
@ -404,30 +402,17 @@ int autodetect_stereo(struct i2c_client *client)
|
||||
rxsubchans = V4L2_TUNER_SUB_MONO;
|
||||
}
|
||||
break;
|
||||
case MSP_MODE_BTSC:
|
||||
val = msp_read_dem(client, 0x200);
|
||||
v4l_dbg(2, msp_debug, client, "status=0x%x (pri=%s, sec=%s, %s%s%s)\n",
|
||||
val,
|
||||
(val & 0x0002) ? "no" : "yes",
|
||||
(val & 0x0004) ? "no" : "yes",
|
||||
(val & 0x0040) ? "stereo" : "mono",
|
||||
(val & 0x0080) ? ", nicam 2nd mono" : "",
|
||||
(val & 0x0100) ? ", bilingual/SAP" : "");
|
||||
rxsubchans = V4L2_TUNER_SUB_MONO;
|
||||
if (val & 0x0040) rxsubchans |= V4L2_TUNER_SUB_STEREO;
|
||||
if (val & 0x0100) rxsubchans |= V4L2_TUNER_SUB_LANG1;
|
||||
break;
|
||||
}
|
||||
if (rxsubchans != state->rxsubchans) {
|
||||
update = 1;
|
||||
v4l_dbg(1, msp_debug, client, "watch: rxsubchans %d => %d\n",
|
||||
state->rxsubchans,rxsubchans);
|
||||
v4l_dbg(1, msp_debug, client, "watch: rxsubchans %02x => %02x\n",
|
||||
state->rxsubchans, rxsubchans);
|
||||
state->rxsubchans = rxsubchans;
|
||||
}
|
||||
if (newnicam != state->nicam_on) {
|
||||
update = 1;
|
||||
v4l_dbg(1, msp_debug, client, "watch: nicam %d => %d\n",
|
||||
state->nicam_on,newnicam);
|
||||
state->nicam_on, newnicam);
|
||||
state->nicam_on = newnicam;
|
||||
}
|
||||
return update;
|
||||
@ -442,13 +427,8 @@ static void watch_stereo(struct i2c_client *client)
|
||||
{
|
||||
struct msp_state *state = i2c_get_clientdata(client);
|
||||
|
||||
if (autodetect_stereo(client)) {
|
||||
if (state->rxsubchans & V4L2_TUNER_SUB_STEREO)
|
||||
msp3400c_setstereo(client, V4L2_TUNER_MODE_STEREO);
|
||||
else if (state->rxsubchans & V4L2_TUNER_SUB_LANG1)
|
||||
msp3400c_setstereo(client, V4L2_TUNER_MODE_LANG1);
|
||||
else
|
||||
msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
|
||||
if (msp3400c_detect_stereo(client)) {
|
||||
msp3400c_set_audmode(client);
|
||||
}
|
||||
|
||||
if (msp_once)
|
||||
@ -460,7 +440,7 @@ int msp3400c_thread(void *data)
|
||||
struct i2c_client *client = data;
|
||||
struct msp_state *state = i2c_get_clientdata(client);
|
||||
struct msp3400c_carrier_detect *cd;
|
||||
int count, max1,max2,val1,val2, val,this;
|
||||
int count, max1, max2, val1, val2, val, this;
|
||||
|
||||
|
||||
v4l_dbg(1, msp_debug, client, "msp3400 daemon started\n");
|
||||
@ -470,7 +450,7 @@ int msp3400c_thread(void *data)
|
||||
v4l_dbg(2, msp_debug, client, "msp3400 thread: wakeup\n");
|
||||
|
||||
restart:
|
||||
v4l_dbg(1, msp_debug, client, "thread: restart scan\n");
|
||||
v4l_dbg(2, msp_debug, client, "thread: restart scan\n");
|
||||
state->restart = 0;
|
||||
if (kthread_should_stop())
|
||||
break;
|
||||
@ -484,13 +464,14 @@ int msp3400c_thread(void *data)
|
||||
|
||||
/* mute */
|
||||
msp_set_mute(client);
|
||||
msp3400c_setmode(client, MSP_MODE_AM_DETECT /* +1 */ );
|
||||
msp3400c_set_mode(client, MSP_MODE_AM_DETECT /* +1 */ );
|
||||
val1 = val2 = 0;
|
||||
max1 = max2 = -1;
|
||||
state->watch_stereo = 0;
|
||||
state->nicam_on = 0;
|
||||
|
||||
/* some time for the tuner to sync */
|
||||
if (msp_sleep(state,200))
|
||||
if (msp_sleep(state, 200))
|
||||
goto restart;
|
||||
|
||||
/* carrier detect pass #1 -- main carrier */
|
||||
@ -505,7 +486,7 @@ int msp3400c_thread(void *data)
|
||||
}
|
||||
|
||||
for (this = 0; this < count; this++) {
|
||||
msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo);
|
||||
msp3400c_set_carrier(client, cd[this].cdo, cd[this].cdo);
|
||||
if (msp_sleep(state,100))
|
||||
goto restart;
|
||||
val = msp_read_dsp(client, 0x1b);
|
||||
@ -541,7 +522,7 @@ int msp3400c_thread(void *data)
|
||||
max2 = 0;
|
||||
}
|
||||
for (this = 0; this < count; this++) {
|
||||
msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo);
|
||||
msp3400c_set_carrier(client, cd[this].cdo, cd[this].cdo);
|
||||
if (msp_sleep(state,100))
|
||||
goto restart;
|
||||
val = msp_read_dsp(client, 0x1b);
|
||||
@ -553,22 +534,20 @@ int msp3400c_thread(void *data)
|
||||
}
|
||||
|
||||
/* program the msp3400 according to the results */
|
||||
state->main = msp3400c_carrier_detect_main[max1].cdo;
|
||||
state->main = msp3400c_carrier_detect_main[max1].cdo;
|
||||
switch (max1) {
|
||||
case 1: /* 5.5 */
|
||||
if (max2 == 0) {
|
||||
/* B/G FM-stereo */
|
||||
state->second = msp3400c_carrier_detect_55[max2].cdo;
|
||||
msp3400c_setmode(client, MSP_MODE_FM_TERRA);
|
||||
state->nicam_on = 0;
|
||||
msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
|
||||
msp3400c_set_mode(client, MSP_MODE_FM_TERRA);
|
||||
state->watch_stereo = 1;
|
||||
} else if (max2 == 1 && state->has_nicam) {
|
||||
/* B/G NICAM */
|
||||
state->second = msp3400c_carrier_detect_55[max2].cdo;
|
||||
msp3400c_setmode(client, MSP_MODE_FM_NICAM1);
|
||||
msp3400c_set_mode(client, MSP_MODE_FM_NICAM1);
|
||||
msp3400c_set_carrier(client, state->second, state->main);
|
||||
state->nicam_on = 1;
|
||||
msp3400c_setcarrier(client, state->second, state->main);
|
||||
state->watch_stereo = 1;
|
||||
} else {
|
||||
goto no_second;
|
||||
@ -577,35 +556,31 @@ int msp3400c_thread(void *data)
|
||||
case 2: /* 6.0 */
|
||||
/* PAL I NICAM */
|
||||
state->second = MSP_CARRIER(6.552);
|
||||
msp3400c_setmode(client, MSP_MODE_FM_NICAM2);
|
||||
msp3400c_set_mode(client, MSP_MODE_FM_NICAM2);
|
||||
msp3400c_set_carrier(client, state->second, state->main);
|
||||
state->nicam_on = 1;
|
||||
msp3400c_setcarrier(client, state->second, state->main);
|
||||
state->watch_stereo = 1;
|
||||
break;
|
||||
case 3: /* 6.5 */
|
||||
if (max2 == 1 || max2 == 2) {
|
||||
/* D/K FM-stereo */
|
||||
state->second = msp3400c_carrier_detect_65[max2].cdo;
|
||||
msp3400c_setmode(client, MSP_MODE_FM_TERRA);
|
||||
state->nicam_on = 0;
|
||||
msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
|
||||
msp3400c_set_mode(client, MSP_MODE_FM_TERRA);
|
||||
state->watch_stereo = 1;
|
||||
} else if (max2 == 0 && (state->v4l2_std & V4L2_STD_SECAM)) {
|
||||
/* L NICAM or AM-mono */
|
||||
state->second = msp3400c_carrier_detect_65[max2].cdo;
|
||||
msp3400c_setmode(client, MSP_MODE_AM_NICAM);
|
||||
state->nicam_on = 0;
|
||||
msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
|
||||
msp3400c_setcarrier(client, state->second, state->main);
|
||||
msp3400c_set_mode(client, MSP_MODE_AM_NICAM);
|
||||
msp3400c_set_carrier(client, state->second, state->main);
|
||||
/* volume prescale for SCART (AM mono input) */
|
||||
msp_write_dsp(client, 0x000d, 0x1900);
|
||||
state->watch_stereo = 1;
|
||||
} else if (max2 == 0 && state->has_nicam) {
|
||||
/* D/K NICAM */
|
||||
state->second = msp3400c_carrier_detect_65[max2].cdo;
|
||||
msp3400c_setmode(client, MSP_MODE_FM_NICAM1);
|
||||
msp3400c_set_mode(client, MSP_MODE_FM_NICAM1);
|
||||
msp3400c_set_carrier(client, state->second, state->main);
|
||||
state->nicam_on = 1;
|
||||
msp3400c_setcarrier(client, state->second, state->main);
|
||||
state->watch_stereo = 1;
|
||||
} else {
|
||||
goto no_second;
|
||||
@ -615,23 +590,25 @@ int msp3400c_thread(void *data)
|
||||
default:
|
||||
no_second:
|
||||
state->second = msp3400c_carrier_detect_main[max1].cdo;
|
||||
msp3400c_setmode(client, MSP_MODE_FM_TERRA);
|
||||
state->nicam_on = 0;
|
||||
msp3400c_setcarrier(client, state->second, state->main);
|
||||
msp3400c_set_mode(client, MSP_MODE_FM_TERRA);
|
||||
msp3400c_set_carrier(client, state->second, state->main);
|
||||
state->rxsubchans = V4L2_TUNER_SUB_MONO;
|
||||
msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
|
||||
break;
|
||||
}
|
||||
|
||||
/* unmute */
|
||||
msp_set_audio(client);
|
||||
msp3400c_set_audmode(client);
|
||||
|
||||
if (msp_debug)
|
||||
msp3400c_print_mode(client);
|
||||
|
||||
/* monitor tv audio mode */
|
||||
/* monitor tv audio mode, the first time don't wait
|
||||
so long to get a quick stereo/bilingual result */
|
||||
if (msp_sleep(state, 1000))
|
||||
goto restart;
|
||||
while (state->watch_stereo) {
|
||||
if (msp_sleep(state,5000))
|
||||
if (msp_sleep(state, 5000))
|
||||
goto restart;
|
||||
watch_stereo(client);
|
||||
}
|
||||
@ -655,7 +632,7 @@ int msp3410d_thread(void *data)
|
||||
v4l_dbg(2, msp_debug, client, "msp3410 thread: wakeup\n");
|
||||
|
||||
restart:
|
||||
v4l_dbg(1, msp_debug, client, "thread: restart scan\n");
|
||||
v4l_dbg(2, msp_debug, client, "thread: restart scan\n");
|
||||
state->restart = 0;
|
||||
if (kthread_should_stop())
|
||||
break;
|
||||
@ -680,9 +657,10 @@ int msp3410d_thread(void *data)
|
||||
else
|
||||
std = (state->v4l2_std & V4L2_STD_NTSC) ? 0x20 : 1;
|
||||
state->watch_stereo = 0;
|
||||
state->nicam_on = 0;
|
||||
|
||||
if (msp_debug)
|
||||
v4l_dbg(1, msp_debug, client, "setting standard: %s (0x%04x)\n",
|
||||
v4l_dbg(2, msp_debug, client, "setting standard: %s (0x%04x)\n",
|
||||
msp_standard_std_name(std), std);
|
||||
|
||||
if (std != 1) {
|
||||
@ -699,7 +677,7 @@ int msp3410d_thread(void *data)
|
||||
val = msp_read_dem(client, 0x7e);
|
||||
if (val < 0x07ff)
|
||||
break;
|
||||
v4l_dbg(1, msp_debug, client, "detection still in progress\n");
|
||||
v4l_dbg(2, msp_debug, client, "detection still in progress\n");
|
||||
}
|
||||
}
|
||||
for (i = 0; msp_stdlist[i].name != NULL; i++)
|
||||
@ -738,46 +716,34 @@ int msp3410d_thread(void *data)
|
||||
state->rxsubchans = V4L2_TUNER_SUB_STEREO;
|
||||
state->nicam_on = 1;
|
||||
state->watch_stereo = 1;
|
||||
msp3400c_setstereo(client,V4L2_TUNER_MODE_STEREO);
|
||||
break;
|
||||
case 0x0009:
|
||||
state->mode = MSP_MODE_AM_NICAM;
|
||||
state->rxsubchans = V4L2_TUNER_SUB_MONO;
|
||||
state->nicam_on = 1;
|
||||
msp3400c_setstereo(client,V4L2_TUNER_MODE_MONO);
|
||||
state->watch_stereo = 1;
|
||||
break;
|
||||
case 0x0020: /* BTSC */
|
||||
/* just turn on stereo */
|
||||
/* The pre-'G' models only have BTSC-mono */
|
||||
state->mode = MSP_MODE_BTSC;
|
||||
state->rxsubchans = V4L2_TUNER_SUB_STEREO;
|
||||
state->nicam_on = 0;
|
||||
state->watch_stereo = 1;
|
||||
msp3400c_setstereo(client,V4L2_TUNER_MODE_STEREO);
|
||||
state->rxsubchans = V4L2_TUNER_SUB_MONO;
|
||||
break;
|
||||
case 0x0040: /* FM radio */
|
||||
state->mode = MSP_MODE_FM_RADIO;
|
||||
state->rxsubchans = V4L2_TUNER_SUB_STEREO;
|
||||
state->nicam_on = 0;
|
||||
state->watch_stereo = 0;
|
||||
/* not needed in theory if we have radio, but
|
||||
short programming enables carrier mute */
|
||||
msp3400c_setmode(client, MSP_MODE_FM_RADIO);
|
||||
msp3400c_setcarrier(client, MSP_CARRIER(10.7),
|
||||
msp3400c_set_mode(client, MSP_MODE_FM_RADIO);
|
||||
msp3400c_set_carrier(client, MSP_CARRIER(10.7),
|
||||
MSP_CARRIER(10.7));
|
||||
/* scart routing */
|
||||
/* scart routing (this doesn't belong here I think) */
|
||||
msp_set_scart(client,SCART_IN2,0);
|
||||
/* msp34xx does radio decoding */
|
||||
msp_write_dsp(client, 0x08, 0x0020);
|
||||
msp_write_dsp(client, 0x09, 0x0020);
|
||||
msp_write_dsp(client, 0x0b, 0x0020);
|
||||
break;
|
||||
case 0x0003:
|
||||
case 0x0004:
|
||||
case 0x0005:
|
||||
state->mode = MSP_MODE_FM_TERRA;
|
||||
state->rxsubchans = V4L2_TUNER_SUB_MONO;
|
||||
state->nicam_on = 0;
|
||||
state->watch_stereo = 1;
|
||||
break;
|
||||
}
|
||||
@ -788,11 +754,16 @@ int msp3410d_thread(void *data)
|
||||
if (state->has_i2s_conf)
|
||||
msp_write_dem(client, 0x40, state->i2s_mode);
|
||||
|
||||
/* monitor tv audio mode */
|
||||
msp3400c_set_audmode(client);
|
||||
|
||||
/* monitor tv audio mode, the first time don't wait
|
||||
so long to get a quick stereo/bilingual result */
|
||||
if (msp_sleep(state, 1000))
|
||||
goto restart;
|
||||
while (state->watch_stereo) {
|
||||
if (msp_sleep(state,5000))
|
||||
goto restart;
|
||||
watch_stereo(client);
|
||||
if (msp_sleep(state, 5000))
|
||||
goto restart;
|
||||
}
|
||||
}
|
||||
v4l_dbg(1, msp_debug, client, "thread: exit\n");
|
||||
@ -810,7 +781,7 @@ int msp3410d_thread(void *data)
|
||||
* the value for source is the same as bit 15:8 of DSP registers 0x08,
|
||||
* 0x0a and 0x0c: 0=mono, 1=stereo or A|B, 2=SCART, 3=stereo or A, 4=stereo or B
|
||||
*
|
||||
* this function replaces msp3400c_setstereo
|
||||
* this function replaces msp3400c_set_audmode
|
||||
*/
|
||||
static void msp34xxg_set_source(struct i2c_client *client, int source)
|
||||
{
|
||||
@ -823,12 +794,7 @@ static void msp34xxg_set_source(struct i2c_client *client, int source)
|
||||
int value = (source & 0x07) << 8 | (source == 0 ? 0x30 : 0x20);
|
||||
|
||||
v4l_dbg(1, msp_debug, client, "set source to %d (0x%x)\n", source, value);
|
||||
/* Loudspeaker Output */
|
||||
msp_write_dsp(client, 0x08, value);
|
||||
/* SCART1 DA Output */
|
||||
msp_write_dsp(client, 0x0a, value);
|
||||
/* Quasi-peak detector */
|
||||
msp_write_dsp(client, 0x0c, value);
|
||||
msp_set_source(client, value);
|
||||
/*
|
||||
* set identification threshold. Personally, I
|
||||
* I set it to a higher value that the default
|
||||
@ -945,13 +911,14 @@ int msp34xxg_thread(void *data)
|
||||
if (msp_write_dsp(client, 0x13, state->acb))
|
||||
return -1;
|
||||
|
||||
msp_write_dem(client, 0x40, state->i2s_mode);
|
||||
if (state->has_i2s_conf)
|
||||
msp_write_dem(client, 0x40, state->i2s_mode);
|
||||
}
|
||||
v4l_dbg(1, msp_debug, client, "thread: exit\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void msp34xxg_detect_stereo(struct i2c_client *client)
|
||||
static void msp34xxg_detect_stereo(struct i2c_client *client)
|
||||
{
|
||||
struct msp_state *state = i2c_get_clientdata(client);
|
||||
|
||||
@ -961,11 +928,11 @@ void msp34xxg_detect_stereo(struct i2c_client *client)
|
||||
|
||||
state->rxsubchans = 0;
|
||||
if (is_stereo)
|
||||
state->rxsubchans |= V4L2_TUNER_SUB_STEREO;
|
||||
state->rxsubchans = V4L2_TUNER_SUB_STEREO;
|
||||
else
|
||||
state->rxsubchans |= V4L2_TUNER_SUB_MONO;
|
||||
state->rxsubchans = V4L2_TUNER_SUB_MONO;
|
||||
if (is_bilingual) {
|
||||
state->rxsubchans |= V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
|
||||
state->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
|
||||
/* I'm supposed to check whether it's SAP or not
|
||||
* and set only LANG2/SAP in this case. Yet, the MSP
|
||||
* does a lot of work to hide this and handle everything
|
||||
@ -977,12 +944,12 @@ void msp34xxg_detect_stereo(struct i2c_client *client)
|
||||
status, is_stereo, is_bilingual, state->rxsubchans);
|
||||
}
|
||||
|
||||
void msp34xxg_set_audmode(struct i2c_client *client, int audmode)
|
||||
void msp34xxg_set_audmode(struct i2c_client *client)
|
||||
{
|
||||
struct msp_state *state = i2c_get_clientdata(client);
|
||||
int source;
|
||||
|
||||
switch (audmode) {
|
||||
switch (state->audmode) {
|
||||
case V4L2_TUNER_MODE_MONO:
|
||||
source = 0; /* mono only */
|
||||
break;
|
||||
@ -997,11 +964,40 @@ void msp34xxg_set_audmode(struct i2c_client *client, int audmode)
|
||||
source = 4; /* stereo or B */
|
||||
break;
|
||||
default:
|
||||
audmode = 0;
|
||||
source = 1;
|
||||
break;
|
||||
}
|
||||
state->audmode = audmode;
|
||||
msp34xxg_set_source(client, source);
|
||||
}
|
||||
|
||||
void msp_set_audmode(struct i2c_client *client)
|
||||
{
|
||||
struct msp_state *state = i2c_get_clientdata(client);
|
||||
|
||||
switch (state->opmode) {
|
||||
case OPMODE_MANUAL:
|
||||
case OPMODE_AUTODETECT:
|
||||
state->watch_stereo = 0;
|
||||
msp3400c_set_audmode(client);
|
||||
break;
|
||||
case OPMODE_AUTOSELECT:
|
||||
msp34xxg_set_audmode(client);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void msp_detect_stereo(struct i2c_client *client)
|
||||
{
|
||||
struct msp_state *state = i2c_get_clientdata(client);
|
||||
|
||||
switch (state->opmode) {
|
||||
case OPMODE_MANUAL:
|
||||
case OPMODE_AUTODETECT:
|
||||
msp3400c_detect_stereo(client);
|
||||
break;
|
||||
case OPMODE_AUTOSELECT:
|
||||
msp34xxg_detect_stereo(client);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -104,14 +104,13 @@ int msp_sleep(struct msp_state *state, int timeout);
|
||||
|
||||
/* msp3400-kthreads.c */
|
||||
const char *msp_standard_std_name(int std);
|
||||
void msp3400c_setcarrier(struct i2c_client *client, int cdo1, int cdo2);
|
||||
void msp3400c_setmode(struct i2c_client *client, int type);
|
||||
void msp3400c_setstereo(struct i2c_client *client, int mode);
|
||||
int autodetect_stereo(struct i2c_client *client);
|
||||
void msp_set_source(struct i2c_client *client, u16 src);
|
||||
void msp_set_audmode(struct i2c_client *client);
|
||||
void msp_detect_stereo(struct i2c_client *client);
|
||||
int msp3400c_thread(void *data);
|
||||
int msp3410d_thread(void *data);
|
||||
int msp34xxg_thread(void *data);
|
||||
void msp34xxg_detect_stereo(struct i2c_client *client);
|
||||
void msp34xxg_set_audmode(struct i2c_client *client, int audmode);
|
||||
void msp3400c_set_mode(struct i2c_client *client, int mode);
|
||||
void msp3400c_set_carrier(struct i2c_client *client, int cdo1, int cdo2);
|
||||
|
||||
#endif /* MSP3400_H */
|
||||
|
@ -398,15 +398,16 @@ static void tuner_status(struct i2c_client *client)
|
||||
tuner_info("Tuner mode: %s\n", p);
|
||||
tuner_info("Frequency: %lu.%02lu MHz\n", freq, freq_fraction);
|
||||
tuner_info("Standard: 0x%08llx\n", t->std);
|
||||
if (t->mode == V4L2_TUNER_RADIO) {
|
||||
if (t->has_signal) {
|
||||
tuner_info("Signal strength: %d\n", t->has_signal(client));
|
||||
}
|
||||
if (t->is_stereo) {
|
||||
tuner_info("Stereo: %s\n", t->is_stereo(client) ? "yes" : "no");
|
||||
}
|
||||
if (t->mode != V4L2_TUNER_RADIO)
|
||||
return;
|
||||
if (t->has_signal) {
|
||||
tuner_info("Signal strength: %d\n", t->has_signal(client));
|
||||
}
|
||||
if (t->is_stereo) {
|
||||
tuner_info("Stereo: %s\n", t->is_stereo(client) ? "yes" : "no");
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/* static var Used only in tuner_attach and tuner_probe */
|
||||
@ -737,33 +738,29 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
||||
return 0;
|
||||
switch_v4l2();
|
||||
|
||||
if (V4L2_TUNER_RADIO == t->mode) {
|
||||
|
||||
if (t->has_signal)
|
||||
tuner->signal = t->has_signal(client);
|
||||
|
||||
if (t->is_stereo) {
|
||||
if (t->is_stereo(client)) {
|
||||
tuner->rxsubchans =
|
||||
V4L2_TUNER_SUB_STEREO |
|
||||
V4L2_TUNER_SUB_MONO;
|
||||
} else {
|
||||
tuner->rxsubchans =
|
||||
V4L2_TUNER_SUB_MONO;
|
||||
}
|
||||
}
|
||||
|
||||
tuner->capability |=
|
||||
V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
|
||||
|
||||
tuner->audmode = t->audmode;
|
||||
|
||||
tuner->rangelow = radio_range[0] * 16000;
|
||||
tuner->rangehigh = radio_range[1] * 16000;
|
||||
} else {
|
||||
tuner->type = t->mode;
|
||||
if (t->mode != V4L2_TUNER_RADIO) {
|
||||
tuner->rangelow = tv_range[0] * 16;
|
||||
tuner->rangehigh = tv_range[1] * 16;
|
||||
break;
|
||||
}
|
||||
|
||||
/* radio mode */
|
||||
if (t->has_signal)
|
||||
tuner->signal = t->has_signal(client);
|
||||
|
||||
tuner->rxsubchans =
|
||||
V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
|
||||
if (t->is_stereo) {
|
||||
tuner->rxsubchans = t->is_stereo(client) ?
|
||||
V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO;
|
||||
}
|
||||
|
||||
tuner->capability |=
|
||||
V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
|
||||
tuner->audmode = t->audmode;
|
||||
tuner->rangelow = radio_range[0] * 16000;
|
||||
tuner->rangehigh = radio_range[1] * 16000;
|
||||
break;
|
||||
}
|
||||
case VIDIOC_S_TUNER:
|
||||
@ -775,10 +772,11 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
||||
|
||||
switch_v4l2();
|
||||
|
||||
if (V4L2_TUNER_RADIO == t->mode) {
|
||||
t->audmode = tuner->audmode;
|
||||
set_radio_freq(client, t->radio_freq);
|
||||
}
|
||||
/* do nothing unless we're a radio tuner */
|
||||
if (t->mode != V4L2_TUNER_RADIO)
|
||||
break;
|
||||
t->audmode = tuner->audmode;
|
||||
set_radio_freq(client, t->radio_freq);
|
||||
break;
|
||||
}
|
||||
case VIDIOC_LOG_STATUS:
|
||||
|
@ -130,6 +130,7 @@ struct CHIPSTATE {
|
||||
struct timer_list wt;
|
||||
int done;
|
||||
int watch_stereo;
|
||||
int audmode;
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@ -1514,6 +1515,7 @@ static int chip_attach(struct i2c_adapter *adap, int addr, int kind)
|
||||
chip->type = desc-chiplist;
|
||||
chip->shadow.count = desc->registers+1;
|
||||
chip->prevmode = -1;
|
||||
chip->audmode = V4L2_TUNER_MODE_LANG1;
|
||||
/* register */
|
||||
i2c_attach_client(&chip->c);
|
||||
|
||||
@ -1671,6 +1673,8 @@ static int chip_command(struct i2c_client *client,
|
||||
struct v4l2_tuner *vt = arg;
|
||||
int mode = 0;
|
||||
|
||||
if (chip->radio)
|
||||
break;
|
||||
switch (vt->audmode) {
|
||||
case V4L2_TUNER_MODE_MONO:
|
||||
mode = VIDEO_SOUND_MONO;
|
||||
@ -1685,8 +1689,9 @@ static int chip_command(struct i2c_client *client,
|
||||
mode = VIDEO_SOUND_LANG2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
return -EINVAL;
|
||||
}
|
||||
chip->audmode = vt->audmode;
|
||||
|
||||
if (desc->setmode && mode) {
|
||||
chip->watch_stereo = 0;
|
||||
@ -1704,7 +1709,7 @@ static int chip_command(struct i2c_client *client,
|
||||
|
||||
if (chip->radio)
|
||||
break;
|
||||
vt->audmode = 0;
|
||||
vt->audmode = chip->audmode;
|
||||
vt->rxsubchans = 0;
|
||||
vt->capability = V4L2_TUNER_CAP_STEREO |
|
||||
V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
|
||||
@ -1716,19 +1721,12 @@ static int chip_command(struct i2c_client *client,
|
||||
vt->rxsubchans |= V4L2_TUNER_SUB_MONO;
|
||||
if (mode & VIDEO_SOUND_STEREO)
|
||||
vt->rxsubchans |= V4L2_TUNER_SUB_STEREO;
|
||||
/* Note: for SAP it should be mono/lang2 or stereo/lang2.
|
||||
When this module is converted fully to v4l2, then this
|
||||
should change for those chips that can detect SAP. */
|
||||
if (mode & VIDEO_SOUND_LANG1)
|
||||
vt->rxsubchans |= V4L2_TUNER_SUB_LANG1 |
|
||||
V4L2_TUNER_SUB_LANG2;
|
||||
|
||||
mode = chip->mode;
|
||||
if (mode & VIDEO_SOUND_MONO)
|
||||
vt->audmode = V4L2_TUNER_MODE_MONO;
|
||||
if (mode & VIDEO_SOUND_STEREO)
|
||||
vt->audmode = V4L2_TUNER_MODE_STEREO;
|
||||
if (mode & VIDEO_SOUND_LANG1)
|
||||
vt->audmode = V4L2_TUNER_MODE_LANG1;
|
||||
if (mode & VIDEO_SOUND_LANG2)
|
||||
vt->audmode = V4L2_TUNER_MODE_LANG2;
|
||||
vt->rxsubchans = V4L2_TUNER_SUB_LANG1 |
|
||||
V4L2_TUNER_SUB_LANG2;
|
||||
break;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user