[media] tvaudio: obey V4L2 tuner audio matrix
V4L2 specifies the audio mode to use for combinations of possible (rxsubchans) and requested (audmode) audio modes. Up to now tvaudio has made these decisions automatically based on the possible audio modes from setting of the frequency until VIDIOC_S_TUNER was called. It then forced the hardware to use the mode requested by the user. With this patch it continues to adjust the audio mode while taking the requested mode into account. Signed-off-by: Daniel Glöckner <daniel-gl@gmx.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
Родитель
3322a59e09
Коммит
e21adca897
|
@ -118,7 +118,7 @@ struct CHIPSTATE {
|
||||||
audiocmd shadow;
|
audiocmd shadow;
|
||||||
|
|
||||||
/* current settings */
|
/* current settings */
|
||||||
__u16 left,right,treble,bass,muted,mode;
|
__u16 left, right, treble, bass, muted;
|
||||||
int prevmode;
|
int prevmode;
|
||||||
int radio;
|
int radio;
|
||||||
int input;
|
int input;
|
||||||
|
@ -287,7 +287,7 @@ static int chip_thread(void *data)
|
||||||
struct CHIPSTATE *chip = data;
|
struct CHIPSTATE *chip = data;
|
||||||
struct CHIPDESC *desc = chip->desc;
|
struct CHIPDESC *desc = chip->desc;
|
||||||
struct v4l2_subdev *sd = &chip->sd;
|
struct v4l2_subdev *sd = &chip->sd;
|
||||||
int mode;
|
int mode, selected;
|
||||||
|
|
||||||
v4l2_dbg(1, debug, sd, "thread started\n");
|
v4l2_dbg(1, debug, sd, "thread started\n");
|
||||||
set_freezable();
|
set_freezable();
|
||||||
|
@ -301,8 +301,8 @@ static int chip_thread(void *data)
|
||||||
break;
|
break;
|
||||||
v4l2_dbg(1, debug, sd, "thread wakeup\n");
|
v4l2_dbg(1, debug, sd, "thread wakeup\n");
|
||||||
|
|
||||||
/* don't do anything for radio or if mode != auto */
|
/* don't do anything for radio */
|
||||||
if (chip->radio || chip->mode != 0)
|
if (chip->radio)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* have a look what's going on */
|
/* have a look what's going on */
|
||||||
|
@ -315,16 +315,27 @@ static int chip_thread(void *data)
|
||||||
|
|
||||||
chip->prevmode = mode;
|
chip->prevmode = mode;
|
||||||
|
|
||||||
if (mode & V4L2_TUNER_SUB_STEREO)
|
selected = V4L2_TUNER_MODE_MONO;
|
||||||
desc->setmode(chip, V4L2_TUNER_MODE_STEREO);
|
switch (chip->audmode) {
|
||||||
if (mode & V4L2_TUNER_SUB_LANG1_LANG2)
|
case V4L2_TUNER_MODE_MONO:
|
||||||
desc->setmode(chip, V4L2_TUNER_MODE_STEREO);
|
if (mode & V4L2_TUNER_SUB_LANG1)
|
||||||
else if (mode & V4L2_SUB_MODE_LANG1)
|
selected = V4L2_TUNER_MODE_LANG1;
|
||||||
desc->setmode(chip, V4L2_TUNER_MODE_LANG1);
|
break;
|
||||||
else if (mode & V4L2_SUB_MODE_LANG2)
|
case V4L2_TUNER_MODE_STEREO:
|
||||||
desc->setmode(chip, V4L2_TUNER_MODE_LANG2);
|
case V4L2_TUNER_MODE_LANG1:
|
||||||
else
|
if (mode & V4L2_TUNER_SUB_LANG1)
|
||||||
desc->setmode(chip, V4L2_TUNER_MODE_MONO);
|
selected = V4L2_TUNER_MODE_LANG1;
|
||||||
|
else if (mode & V4L2_TUNER_SUB_STEREO)
|
||||||
|
selected = V4L2_TUNER_MODE_STEREO;
|
||||||
|
break;
|
||||||
|
case V4L2_TUNER_MODE_LANG2:
|
||||||
|
if (mode & V4L2_TUNER_SUB_LANG2)
|
||||||
|
selected = V4L2_TUNER_MODE_LANG2;
|
||||||
|
else if (mode & V4L2_TUNER_SUB_STEREO)
|
||||||
|
selected = V4L2_TUNER_MODE_STEREO;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
desc->setmode(chip, selected);
|
||||||
|
|
||||||
/* schedule next check */
|
/* schedule next check */
|
||||||
mod_timer(&chip->wt, jiffies+msecs_to_jiffies(2000));
|
mod_timer(&chip->wt, jiffies+msecs_to_jiffies(2000));
|
||||||
|
@ -712,7 +723,6 @@ static void tda9873_setmode(struct CHIPSTATE *chip, int mode)
|
||||||
sw_data |= TDA9873_TR_DUALB;
|
sw_data |= TDA9873_TR_DUALB;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
chip->mode = 0;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -944,7 +954,6 @@ static void tda9874a_setmode(struct CHIPSTATE *chip, int mode)
|
||||||
mdacosr = (tda9874a_mode) ? 0x83:0x81;
|
mdacosr = (tda9874a_mode) ? 0x83:0x81;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
chip->mode = 0;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
chip_write(chip, TDA9874A_AOSR, aosr);
|
chip_write(chip, TDA9874A_AOSR, aosr);
|
||||||
|
@ -979,7 +988,6 @@ static void tda9874a_setmode(struct CHIPSTATE *chip, int mode)
|
||||||
aosr = 0x20; /* dual B/B */
|
aosr = 0x20; /* dual B/B */
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
chip->mode = 0;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
chip_write(chip, TDA9874A_FMMR, fmmr);
|
chip_write(chip, TDA9874A_FMMR, fmmr);
|
||||||
|
@ -1799,7 +1807,6 @@ static int tvaudio_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
|
||||||
{
|
{
|
||||||
struct CHIPSTATE *chip = to_state(sd);
|
struct CHIPSTATE *chip = to_state(sd);
|
||||||
struct CHIPDESC *desc = chip->desc;
|
struct CHIPDESC *desc = chip->desc;
|
||||||
int mode = 0;
|
|
||||||
|
|
||||||
if (!desc->setmode)
|
if (!desc->setmode)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1811,21 +1818,20 @@ static int tvaudio_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
|
||||||
case V4L2_TUNER_MODE_STEREO:
|
case V4L2_TUNER_MODE_STEREO:
|
||||||
case V4L2_TUNER_MODE_LANG1:
|
case V4L2_TUNER_MODE_LANG1:
|
||||||
case V4L2_TUNER_MODE_LANG2:
|
case V4L2_TUNER_MODE_LANG2:
|
||||||
mode = vt->audmode;
|
|
||||||
break;
|
break;
|
||||||
case V4L2_TUNER_MODE_LANG1_LANG2:
|
case V4L2_TUNER_MODE_LANG1_LANG2:
|
||||||
mode = V4L2_TUNER_MODE_STEREO;
|
vt->audmode = V4L2_TUNER_MODE_STEREO;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
chip->audmode = vt->audmode;
|
chip->audmode = vt->audmode;
|
||||||
|
|
||||||
if (mode) {
|
if (chip->thread)
|
||||||
/* del_timer(&chip->wt); */
|
wake_up_process(chip->thread);
|
||||||
chip->mode = mode;
|
else
|
||||||
desc->setmode(chip, mode);
|
desc->setmode(chip, vt->audmode);
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1860,8 +1866,6 @@ static int tvaudio_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *fr
|
||||||
struct CHIPSTATE *chip = to_state(sd);
|
struct CHIPSTATE *chip = to_state(sd);
|
||||||
struct CHIPDESC *desc = chip->desc;
|
struct CHIPDESC *desc = chip->desc;
|
||||||
|
|
||||||
chip->mode = 0; /* automatic */
|
|
||||||
|
|
||||||
/* For chips that provide getmode and setmode, and doesn't
|
/* For chips that provide getmode and setmode, and doesn't
|
||||||
automatically follows the stereo carrier, a kthread is
|
automatically follows the stereo carrier, a kthread is
|
||||||
created to set the audio standard. In this case, when then
|
created to set the audio standard. In this case, when then
|
||||||
|
@ -1872,7 +1876,6 @@ static int tvaudio_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *fr
|
||||||
*/
|
*/
|
||||||
if (chip->thread) {
|
if (chip->thread) {
|
||||||
desc->setmode(chip, V4L2_TUNER_MODE_MONO);
|
desc->setmode(chip, V4L2_TUNER_MODE_MONO);
|
||||||
if (chip->prevmode != V4L2_TUNER_MODE_MONO)
|
|
||||||
chip->prevmode = -1; /* reset previous mode */
|
chip->prevmode = -1; /* reset previous mode */
|
||||||
mod_timer(&chip->wt, jiffies+msecs_to_jiffies(2000));
|
mod_timer(&chip->wt, jiffies+msecs_to_jiffies(2000));
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче