mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-30 08:02:30 +00:00
[media] tda9840: fix setting of the audio mode
You have to first detect the current rxsubchans (mono, stereo or bilingual), and depending on that you can set the audio mode. It does not automatically switch when the audio channels change. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
parent
aaab4951a6
commit
8bb5bafa80
1 changed files with 45 additions and 32 deletions
|
@ -66,41 +66,11 @@ static void tda9840_write(struct v4l2_subdev *sd, u8 reg, u8 val)
|
||||||
val, reg);
|
val, reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tda9840_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *t)
|
static int tda9840_status(struct v4l2_subdev *sd)
|
||||||
{
|
|
||||||
int byte;
|
|
||||||
|
|
||||||
if (t->index)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
switch (t->audmode) {
|
|
||||||
case V4L2_TUNER_MODE_STEREO:
|
|
||||||
byte = TDA9840_SET_STEREO;
|
|
||||||
break;
|
|
||||||
case V4L2_TUNER_MODE_LANG1_LANG2:
|
|
||||||
byte = TDA9840_SET_BOTH;
|
|
||||||
break;
|
|
||||||
case V4L2_TUNER_MODE_LANG1:
|
|
||||||
byte = TDA9840_SET_LANG1;
|
|
||||||
break;
|
|
||||||
case V4L2_TUNER_MODE_LANG2:
|
|
||||||
byte = TDA9840_SET_LANG2;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
byte = TDA9840_SET_MONO;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
v4l2_dbg(1, debug, sd, "TDA9840_SWITCH: 0x%02x\n", byte);
|
|
||||||
tda9840_write(sd, SWITCH, byte);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int tda9840_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *t)
|
|
||||||
{
|
{
|
||||||
struct i2c_client *client = v4l2_get_subdevdata(sd);
|
struct i2c_client *client = v4l2_get_subdevdata(sd);
|
||||||
u8 byte;
|
u8 byte;
|
||||||
|
|
||||||
t->rxsubchans = V4L2_TUNER_SUB_MONO;
|
|
||||||
if (1 != i2c_master_recv(client, &byte, 1)) {
|
if (1 != i2c_master_recv(client, &byte, 1)) {
|
||||||
v4l2_dbg(1, debug, sd,
|
v4l2_dbg(1, debug, sd,
|
||||||
"i2c_master_recv() failed\n");
|
"i2c_master_recv() failed\n");
|
||||||
|
@ -114,8 +84,51 @@ static int tda9840_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *t)
|
||||||
}
|
}
|
||||||
|
|
||||||
v4l2_dbg(1, debug, sd, "TDA9840_DETECT: byte: 0x%02x\n", byte);
|
v4l2_dbg(1, debug, sd, "TDA9840_DETECT: byte: 0x%02x\n", byte);
|
||||||
|
return byte & 0x60;
|
||||||
|
}
|
||||||
|
|
||||||
switch (byte & 0x60) {
|
static int tda9840_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *t)
|
||||||
|
{
|
||||||
|
int stat = tda9840_status(sd);
|
||||||
|
int byte;
|
||||||
|
|
||||||
|
if (t->index)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
stat = stat < 0 ? 0 : stat;
|
||||||
|
if (stat == 0 || stat == 0x60) /* mono input */
|
||||||
|
byte = TDA9840_SET_MONO;
|
||||||
|
else if (stat == 0x40) /* stereo input */
|
||||||
|
byte = (t->audmode == V4L2_TUNER_MODE_MONO) ?
|
||||||
|
TDA9840_SET_MONO : TDA9840_SET_STEREO;
|
||||||
|
else { /* bilingual */
|
||||||
|
switch (t->audmode) {
|
||||||
|
case V4L2_TUNER_MODE_LANG1_LANG2:
|
||||||
|
byte = TDA9840_SET_BOTH;
|
||||||
|
break;
|
||||||
|
case V4L2_TUNER_MODE_LANG2:
|
||||||
|
byte = TDA9840_SET_LANG2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
byte = TDA9840_SET_LANG1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
v4l2_dbg(1, debug, sd, "TDA9840_SWITCH: 0x%02x\n", byte);
|
||||||
|
tda9840_write(sd, SWITCH, byte);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tda9840_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *t)
|
||||||
|
{
|
||||||
|
int stat = tda9840_status(sd);
|
||||||
|
|
||||||
|
if (stat < 0)
|
||||||
|
return stat;
|
||||||
|
|
||||||
|
t->rxsubchans = V4L2_TUNER_SUB_MONO;
|
||||||
|
|
||||||
|
switch (stat & 0x60) {
|
||||||
case 0x00:
|
case 0x00:
|
||||||
t->rxsubchans = V4L2_TUNER_SUB_MONO;
|
t->rxsubchans = V4L2_TUNER_SUB_MONO;
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue