Skip to content

Commit

Permalink
V4L/DVB (3697): More msp3400 and bttv fixes
Browse files Browse the repository at this point in the history
- remove obsolete VIDIOC_S_INPUT i2c call in bttv
- translate VIDIOCSFREQ to VIDIOC_S_FREQUENCY in i2c call
- improve muting during carrier scan in msp3400
- don't start scan unless really needed.
- no longer reset chip for msp3400c/d.
- remove v4l2 check in tuner-core (radio stops after using the TV)
- add missing VIDIOC_INT_ strings in v4l2-common.c

Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
  • Loading branch information
Hans Verkuil authored and Mauro Carvalho Chehab committed Apr 2, 2006
1 parent c097b04 commit 3bbe5a8
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 59 deletions.
13 changes: 8 additions & 5 deletions drivers/media/video/bt8xx/bttv-driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -1025,7 +1025,6 @@ i2c_vidiocschan(struct bttv *btv)
{
v4l2_std_id std = bttv_tvnorms[btv->tvnorm].v4l2_id;

bttv_call_i2c_clients(btv, VIDIOC_S_INPUT, &btv->input);
bttv_call_i2c_clients(btv, VIDIOC_S_STD, &std);
if (btv->c.type == BTTV_BOARD_VOODOOTV_FM)
bttv_tda9880_setnorm(btv,btv->tvnorm);
Expand Down Expand Up @@ -1603,12 +1602,16 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
}
case VIDIOCSFREQ:
{
unsigned long *freq = arg;
struct v4l2_frequency freq;

memset(&freq, 0, sizeof(freq));
freq.frequency = *(unsigned long *)arg;
mutex_lock(&btv->lock);
btv->freq=*freq;
bttv_call_i2c_clients(btv,VIDIOCSFREQ,freq);
freq.type = btv->radio_user ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
btv->freq = *(unsigned long *)arg;
bttv_call_i2c_clients(btv,VIDIOC_S_FREQUENCY,&freq);
if (btv->has_matchbox && btv->radio_user)
tea5757_set_freq(btv,*freq);
tea5757_set_freq(btv,*(unsigned long *)arg);
mutex_unlock(&btv->lock);
return 0;
}
Expand Down
32 changes: 18 additions & 14 deletions drivers/media/video/msp3400-driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -288,17 +288,19 @@ void msp_set_audio(struct i2c_client *client)
struct msp_state *state = i2c_get_clientdata(client);
int bal = 0, bass, treble, loudness;
int val = 0;
int reallymuted = state->muted | state->scan_in_progress;

if (!state->muted)
if (!reallymuted)
val = (state->volume * 0x7f / 65535) << 8;

v4l_dbg(1, msp_debug, client, "mute=%s volume=%d\n",
state->muted ? "on" : "off", state->volume);
v4l_dbg(1, msp_debug, client, "mute=%s scanning=%s volume=%d\n",
state->muted ? "on" : "off", state->scan_in_progress ? "yes" : "no",
state->volume);

msp_write_dsp(client, 0x0000, val);
msp_write_dsp(client, 0x0007, state->muted ? 0x1 : (val | 0x1));
msp_write_dsp(client, 0x0007, reallymuted ? 0x1 : (val | 0x1));
if (state->has_scart2_out_volume)
msp_write_dsp(client, 0x0040, state->muted ? 0x1 : (val | 0x1));
msp_write_dsp(client, 0x0040, reallymuted ? 0x1 : (val | 0x1));
if (state->has_headphones)
msp_write_dsp(client, 0x0006, val);
if (!state->has_sound_processing)
Expand Down Expand Up @@ -671,21 +673,23 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
int sc_in = rt->input & 0x7;
int sc1_out = rt->output & 0xf;
int sc2_out = (rt->output >> 4) & 0xf;
u16 val;
u16 val, reg;

if (state->routing.input == rt->input &&
state->routing.output == rt->output)
break;
state->routing = *rt;
if (state->opmode == OPMODE_AUTOSELECT) {
val = msp_read_dem(client, 0x30) & ~0x100;
msp_write_dem(client, 0x30, val | (tuner ? 0x100 : 0));
} else {
val = msp_read_dem(client, 0xbb) & ~0x100;
msp_write_dem(client, 0xbb, val | (tuner ? 0x100 : 0));
}
msp_set_scart(client, sc_in, 0);
msp_set_scart(client, sc1_out, 1);
msp_set_scart(client, sc2_out, 2);
msp_set_audmode(client);
msp_wake_thread(client);
reg = (state->opmode == OPMODE_AUTOSELECT) ? 0x30 : 0xbb;
val = msp_read_dem(client, reg);
if (tuner != ((val >> 8) & 1)) {
msp_write_dem(client, reg, (val & ~0x100) | (tuner << 8));
/* wake thread when a new tuner input is chosen */
msp_wake_thread(client);
}
break;
}

Expand Down
1 change: 1 addition & 0 deletions drivers/media/video/msp3400-driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ struct msp_state {
int volume, muted;
int balance, loudness;
int bass, treble;
int scan_in_progress;

/* thread */
struct task_struct *kthread;
Expand Down
62 changes: 27 additions & 35 deletions drivers/media/video/msp3400-kthreads.c
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ static int msp3400c_detect_stereo(struct i2c_client *client)
if (val > 32767)
val -= 65536;
v4l_dbg(2, msp_debug, client, "stereo detect register: %d\n", val);
if (val > 4096) {
if (val > 8192) {
rxsubchans = V4L2_TUNER_SUB_STEREO;
} else if (val < -4096) {
rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
Expand Down Expand Up @@ -480,20 +480,22 @@ int msp3400c_thread(void *data)
if (state->radio || MSP_MODE_EXTERN == state->mode) {
/* no carrier scan, just unmute */
v4l_dbg(1, msp_debug, client, "thread: no carrier scan\n");
state->scan_in_progress = 0;
msp_set_audio(client);
continue;
}

/* put into sane state (and mute) */
msp_reset(client);
/* mute audio */
state->scan_in_progress = 1;
msp_set_audio(client);

msp3400c_set_mode(client, MSP_MODE_AM_DETECT);
val1 = val2 = 0;
max1 = max2 = -1;
state->watch_stereo = 0;
state->nicam_on = 0;

/* some time for the tuner to sync */
/* wait for tuner to settle down after a channel change */
if (msp_sleep(state, 200))
goto restart;

Expand Down Expand Up @@ -608,28 +610,26 @@ int msp3400c_thread(void *data)
no_second:
state->second = msp3400c_carrier_detect_main[max1].cdo;
msp3400c_set_mode(client, MSP_MODE_FM_TERRA);
state->rxsubchans = V4L2_TUNER_SUB_MONO;
break;
}
msp3400c_set_carrier(client, state->second, state->main);

/* unmute, restore misc registers */
msp_set_audio(client);

msp_write_dsp(client, 0x13, state->acb);
/* unmute */
state->scan_in_progress = 0;
msp3400c_set_audmode(client);
msp_set_audio(client);

if (msp_debug)
msp3400c_print_mode(client);

/* monitor tv audio mode, the first time don't wait
so long to get a quick stereo/bilingual result */
count = 20;
count = 3;
while (state->watch_stereo) {
watch_stereo(client);
if (msp_sleep(state, count ? 200 : 5000))
if (msp_sleep(state, count ? 1000 : 5000))
goto restart;
if (count) count--;
watch_stereo(client);
}
}
v4l_dbg(1, msp_debug, client, "thread: exit\n");
Expand Down Expand Up @@ -659,16 +659,14 @@ int msp3410d_thread(void *data)
if (state->mode == MSP_MODE_EXTERN) {
/* no carrier scan needed, just unmute */
v4l_dbg(1, msp_debug, client, "thread: no carrier scan\n");
state->scan_in_progress = 0;
msp_set_audio(client);
continue;
}

/* put into sane state (and mute) */
msp_reset(client);

/* some time for the tuner to sync */
if (msp_sleep(state,200))
goto restart;
/* mute audio */
state->scan_in_progress = 1;
msp_set_audio(client);

/* start autodetect. Note: autodetect is not supported for
NTSC-M and radio, hence we force the standard in those cases. */
Expand All @@ -679,6 +677,10 @@ int msp3410d_thread(void *data)
state->watch_stereo = 0;
state->nicam_on = 0;

/* wait for tuner to settle down after a channel change */
if (msp_sleep(state, 200))
goto restart;

if (msp_debug)
v4l_dbg(2, msp_debug, client, "setting standard: %s (0x%04x)\n",
msp_standard_std_name(std), std);
Expand Down Expand Up @@ -708,6 +710,7 @@ int msp3410d_thread(void *data)
state->main = msp_stdlist[i].main;
state->second = msp_stdlist[i].second;
state->std = val;
state->rxsubchans = V4L2_TUNER_SUB_MONO;

if (msp_amsound && !state->radio && (state->v4l2_std & V4L2_STD_SECAM) &&
(val != 0x0009)) {
Expand All @@ -729,20 +732,17 @@ int msp3410d_thread(void *data)
else
state->mode = MSP_MODE_FM_NICAM1;
/* just turn on stereo */
state->rxsubchans = V4L2_TUNER_SUB_STEREO;
state->nicam_on = 1;
state->watch_stereo = 1;
break;
case 0x0009:
state->mode = MSP_MODE_AM_NICAM;
state->rxsubchans = V4L2_TUNER_SUB_MONO;
state->nicam_on = 1;
state->watch_stereo = 1;
break;
case 0x0020: /* BTSC */
/* The pre-'G' models only have BTSC-mono */
state->mode = MSP_MODE_BTSC;
state->rxsubchans = V4L2_TUNER_SUB_MONO;
break;
case 0x0040: /* FM radio */
state->mode = MSP_MODE_FM_RADIO;
Expand All @@ -752,15 +752,12 @@ int msp3410d_thread(void *data)
msp3400c_set_mode(client, MSP_MODE_FM_RADIO);
msp3400c_set_carrier(client, MSP_CARRIER(10.7),
MSP_CARRIER(10.7));
/* scart routing (this doesn't belong here I think) */
msp_set_scart(client,SCART_IN2,0);
break;
case 0x0002:
case 0x0003:
case 0x0004:
case 0x0005:
state->mode = MSP_MODE_FM_TERRA;
state->rxsubchans = V4L2_TUNER_SUB_MONO;
state->watch_stereo = 1;
break;
}
Expand All @@ -774,20 +771,19 @@ int msp3410d_thread(void *data)
if (state->has_i2s_conf)
msp_write_dem(client, 0x40, state->i2s_mode);

/* unmute, restore misc registers */
msp_set_audio(client);

msp_write_dsp(client, 0x13, state->acb);
/* unmute */
msp3400c_set_audmode(client);
state->scan_in_progress = 0;
msp_set_audio(client);

/* monitor tv audio mode, the first time don't wait
so long to get a quick stereo/bilingual result */
count = 20;
count = 3;
while (state->watch_stereo) {
watch_stereo(client);
if (msp_sleep(state, count ? 200 : 5000))
if (msp_sleep(state, count ? 1000 : 5000))
goto restart;
if (count) count--;
watch_stereo(client);
}
}
v4l_dbg(1, msp_debug, client, "thread: exit\n");
Expand Down Expand Up @@ -902,10 +898,6 @@ static void msp34xxg_reset(struct i2c_client *client)

msp_reset(client);

/* make sure that input/output is muted (paranoid mode) */
/* ACB, mute DSP input, mute SCART 1 */
msp_write_dsp(client, 0x13, 0x0f20);

if (state->has_i2s_conf)
msp_write_dem(client, 0x40, state->i2s_mode);

Expand Down
8 changes: 4 additions & 4 deletions drivers/media/video/tuner-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -558,10 +558,10 @@ static inline int set_mode(struct i2c_client *client, struct tuner *t, int mode,

static inline int check_v4l2(struct tuner *t)
{
if (t->using_v4l2) {
tuner_dbg ("ignore v4l1 call\n");
return EINVAL;
}
/* bttv still uses both v4l1 and v4l2 calls to the tuner (v4l2 for
TV, v4l1 for radio), until that is fixed this code is disabled.
Otherwise the radio (v4l1) wouldn't tune after using the TV (v4l2)
first. */
return 0;
}

Expand Down
8 changes: 7 additions & 1 deletion drivers/media/video/v4l2-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@ static const char *v4l2_int_ioctls[] = {
[_IOC_NR(TUNER_SET_STANDBY)] = "TUNER_SET_STANDBY",
[_IOC_NR(TDA9887_SET_CONFIG)] = "TDA9887_SET_CONFIG",

[_IOC_NR(VIDIOC_INT_S_TUNER_MODE)] = "VIDIOC_INT_S_TUNER_MODE",
[_IOC_NR(VIDIOC_INT_S_REGISTER)] = "VIDIOC_INT_S_REGISTER",
[_IOC_NR(VIDIOC_INT_G_REGISTER)] = "VIDIOC_INT_G_REGISTER",
[_IOC_NR(VIDIOC_INT_RESET)] = "VIDIOC_INT_RESET",
Expand All @@ -325,7 +326,12 @@ static const char *v4l2_int_ioctls[] = {
[_IOC_NR(VIDIOC_INT_S_VBI_DATA)] = "VIDIOC_INT_S_VBI_DATA",
[_IOC_NR(VIDIOC_INT_G_VBI_DATA)] = "VIDIOC_INT_G_VBI_DATA",
[_IOC_NR(VIDIOC_INT_G_CHIP_IDENT)] = "VIDIOC_INT_G_CHIP_IDENT",
[_IOC_NR(VIDIOC_INT_I2S_CLOCK_FREQ)] = "VIDIOC_INT_I2S_CLOCK_FREQ"
[_IOC_NR(VIDIOC_INT_I2S_CLOCK_FREQ)] = "VIDIOC_INT_I2S_CLOCK_FREQ",
[_IOC_NR(VIDIOC_INT_S_STANDBY)] = "VIDIOC_INT_S_STANDBY",
[_IOC_NR(VIDIOC_INT_S_AUDIO_ROUTING)] = "VIDIOC_INT_S_AUDIO_ROUTING",
[_IOC_NR(VIDIOC_INT_G_AUDIO_ROUTING)] = "VIDIOC_INT_G_AUDIO_ROUTING",
[_IOC_NR(VIDIOC_INT_S_VIDEO_ROUTING)] = "VIDIOC_INT_S_VIDEO_ROUTING",
[_IOC_NR(VIDIOC_INT_G_VIDEO_ROUTING)] = "VIDIOC_INT_G_VIDEO_ROUTING"
};
#define V4L2_INT_IOCTLS ARRAY_SIZE(v4l2_int_ioctls)

Expand Down

0 comments on commit 3bbe5a8

Please sign in to comment.