Commit dd03e970 authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab

V4L/DVB (9617): tvtime: remove generic_checkmode callback

generic_checkmode() were called, via a callback, for some tvaudio chips.
There's just one callback code used on all those boards. So, it makes no
sense on keeping this as a callback.

Since there were some OOPS reported on tvaudio on kerneloops.org, this
patch removes this callback, adding the code at the only place were it
is called: inside chip_tread. A flag were added to indicate the need for
a kernel thread to set stereo mode on cards that needs it.

Using this more direct approach simplifies the code, making it more
robust against human errors.
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent af1a9951
...@@ -58,7 +58,6 @@ typedef int (*checkit)(struct CHIPSTATE*); ...@@ -58,7 +58,6 @@ typedef int (*checkit)(struct CHIPSTATE*);
typedef int (*initialize)(struct CHIPSTATE*); typedef int (*initialize)(struct CHIPSTATE*);
typedef int (*getmode)(struct CHIPSTATE*); typedef int (*getmode)(struct CHIPSTATE*);
typedef void (*setmode)(struct CHIPSTATE*, int mode); typedef void (*setmode)(struct CHIPSTATE*, int mode);
typedef void (*checkmode)(struct CHIPSTATE*);
/* i2c command */ /* i2c command */
typedef struct AUDIOCMD { typedef struct AUDIOCMD {
...@@ -79,6 +78,7 @@ struct CHIPDESC { ...@@ -79,6 +78,7 @@ struct CHIPDESC {
#define CHIP_HAS_VOLUME 1 #define CHIP_HAS_VOLUME 1
#define CHIP_HAS_BASSTREBLE 2 #define CHIP_HAS_BASSTREBLE 2
#define CHIP_HAS_INPUTSEL 4 #define CHIP_HAS_INPUTSEL 4
#define CHIP_NEED_CHECKMODE 8
/* various i2c command sequences */ /* various i2c command sequences */
audiocmd init; audiocmd init;
...@@ -96,9 +96,6 @@ struct CHIPDESC { ...@@ -96,9 +96,6 @@ struct CHIPDESC {
getmode getmode; getmode getmode;
setmode setmode; setmode setmode;
/* check / autoswitch audio after channel switches */
checkmode checkmode;
/* input switch register + values for v4l inputs */ /* input switch register + values for v4l inputs */
int inputreg; int inputreg;
int inputmap[4]; int inputmap[4];
...@@ -264,6 +261,7 @@ static int chip_thread(void *data) ...@@ -264,6 +261,7 @@ static int chip_thread(void *data)
{ {
struct CHIPSTATE *chip = data; struct CHIPSTATE *chip = data;
struct CHIPDESC *desc = chiplist + chip->type; struct CHIPDESC *desc = chiplist + chip->type;
int mode;
v4l_dbg(1, debug, chip->c, "%s: thread started\n", chip->c->name); v4l_dbg(1, debug, chip->c, "%s: thread started\n", chip->c->name);
set_freezable(); set_freezable();
...@@ -282,7 +280,26 @@ static int chip_thread(void *data) ...@@ -282,7 +280,26 @@ static int chip_thread(void *data)
continue; continue;
/* have a look what's going on */ /* have a look what's going on */
desc->checkmode(chip); mode = desc->getmode(chip);
if (mode == chip->prevmode)
continue;
/* chip detected a new audio mode - set it */
v4l_dbg(1, debug, chip->c, "%s: thread checkmode\n",
chip->c->name);
chip->prevmode = mode;
if (mode & V4L2_TUNER_MODE_STEREO)
desc->setmode(chip, V4L2_TUNER_MODE_STEREO);
if (mode & V4L2_TUNER_MODE_LANG1_LANG2)
desc->setmode(chip, V4L2_TUNER_MODE_STEREO);
else if (mode & V4L2_TUNER_MODE_LANG1)
desc->setmode(chip, V4L2_TUNER_MODE_LANG1);
else if (mode & V4L2_TUNER_MODE_LANG2)
desc->setmode(chip, V4L2_TUNER_MODE_LANG2);
else
desc->setmode(chip, V4L2_TUNER_MODE_MONO);
/* schedule next check */ /* schedule next check */
mod_timer(&chip->wt, jiffies+msecs_to_jiffies(2000)); mod_timer(&chip->wt, jiffies+msecs_to_jiffies(2000));
...@@ -292,29 +309,6 @@ static int chip_thread(void *data) ...@@ -292,29 +309,6 @@ static int chip_thread(void *data)
return 0; return 0;
} }
static void generic_checkmode(struct CHIPSTATE *chip)
{
struct CHIPDESC *desc = chiplist + chip->type;
int mode = desc->getmode(chip);
if (mode == chip->prevmode)
return;
v4l_dbg(1, debug, chip->c, "%s: thread checkmode\n", chip->c->name);
chip->prevmode = mode;
if (mode & V4L2_TUNER_MODE_STEREO)
desc->setmode(chip,V4L2_TUNER_MODE_STEREO);
if (mode & V4L2_TUNER_MODE_LANG1_LANG2)
desc->setmode(chip,V4L2_TUNER_MODE_STEREO);
else if (mode & V4L2_TUNER_MODE_LANG1)
desc->setmode(chip,V4L2_TUNER_MODE_LANG1);
else if (mode & V4L2_TUNER_MODE_LANG2)
desc->setmode(chip,V4L2_TUNER_MODE_LANG2);
else
desc->setmode(chip,V4L2_TUNER_MODE_MONO);
}
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
/* audio chip descriptions - defines+functions for tda9840 */ /* audio chip descriptions - defines+functions for tda9840 */
...@@ -1259,12 +1253,12 @@ static struct CHIPDESC chiplist[] = { ...@@ -1259,12 +1253,12 @@ static struct CHIPDESC chiplist[] = {
.addr_lo = I2C_ADDR_TDA9840 >> 1, .addr_lo = I2C_ADDR_TDA9840 >> 1,
.addr_hi = I2C_ADDR_TDA9840 >> 1, .addr_hi = I2C_ADDR_TDA9840 >> 1,
.registers = 5, .registers = 5,
.flags = CHIP_NEED_CHECKMODE,
/* callbacks */ /* callbacks */
.checkit = tda9840_checkit, .checkit = tda9840_checkit,
.getmode = tda9840_getmode, .getmode = tda9840_getmode,
.setmode = tda9840_setmode, .setmode = tda9840_setmode,
.checkmode = generic_checkmode,
.init = { 2, { TDA9840_TEST, TDA9840_TEST_INT1SN .init = { 2, { TDA9840_TEST, TDA9840_TEST_INT1SN
/* ,TDA9840_SW, TDA9840_MONO */} } /* ,TDA9840_SW, TDA9840_MONO */} }
...@@ -1275,13 +1269,12 @@ static struct CHIPDESC chiplist[] = { ...@@ -1275,13 +1269,12 @@ static struct CHIPDESC chiplist[] = {
.addr_lo = I2C_ADDR_TDA985x_L >> 1, .addr_lo = I2C_ADDR_TDA985x_L >> 1,
.addr_hi = I2C_ADDR_TDA985x_H >> 1, .addr_hi = I2C_ADDR_TDA985x_H >> 1,
.registers = 3, .registers = 3,
.flags = CHIP_HAS_INPUTSEL, .flags = CHIP_HAS_INPUTSEL | CHIP_NEED_CHECKMODE,
/* callbacks */ /* callbacks */
.checkit = tda9873_checkit, .checkit = tda9873_checkit,
.getmode = tda9873_getmode, .getmode = tda9873_getmode,
.setmode = tda9873_setmode, .setmode = tda9873_setmode,
.checkmode = generic_checkmode,
.init = { 4, { TDA9873_SW, 0xa4, 0x06, 0x03 } }, .init = { 4, { TDA9873_SW, 0xa4, 0x06, 0x03 } },
.inputreg = TDA9873_SW, .inputreg = TDA9873_SW,
...@@ -1295,13 +1288,13 @@ static struct CHIPDESC chiplist[] = { ...@@ -1295,13 +1288,13 @@ static struct CHIPDESC chiplist[] = {
.insmodopt = &tda9874a, .insmodopt = &tda9874a,
.addr_lo = I2C_ADDR_TDA9874 >> 1, .addr_lo = I2C_ADDR_TDA9874 >> 1,
.addr_hi = I2C_ADDR_TDA9874 >> 1, .addr_hi = I2C_ADDR_TDA9874 >> 1,
.flags = CHIP_NEED_CHECKMODE,
/* callbacks */ /* callbacks */
.initialize = tda9874a_initialize, .initialize = tda9874a_initialize,
.checkit = tda9874a_checkit, .checkit = tda9874a_checkit,
.getmode = tda9874a_getmode, .getmode = tda9874a_getmode,
.setmode = tda9874a_setmode, .setmode = tda9874a_setmode,
.checkmode = generic_checkmode,
}, },
{ {
.name = "tda9850", .name = "tda9850",
...@@ -1444,11 +1437,11 @@ static struct CHIPDESC chiplist[] = { ...@@ -1444,11 +1437,11 @@ static struct CHIPDESC chiplist[] = {
.addr_lo = I2C_ADDR_TDA9840 >> 1, .addr_lo = I2C_ADDR_TDA9840 >> 1,
.addr_hi = I2C_ADDR_TDA9840 >> 1, .addr_hi = I2C_ADDR_TDA9840 >> 1,
.registers = 2, .registers = 2,
.flags = CHIP_NEED_CHECKMODE,
/* callbacks */ /* callbacks */
.getmode = ta8874z_getmode, .getmode = ta8874z_getmode,
.setmode = ta8874z_setmode, .setmode = ta8874z_setmode,
.checkmode = generic_checkmode,
.init = {2, { TA8874Z_MONO_SET, TA8874Z_SEPARATION_DEFAULT}}, .init = {2, { TA8874Z_MONO_SET, TA8874Z_SEPARATION_DEFAULT}},
}, },
...@@ -1531,7 +1524,7 @@ static int chip_probe(struct i2c_client *client, const struct i2c_device_id *id) ...@@ -1531,7 +1524,7 @@ static int chip_probe(struct i2c_client *client, const struct i2c_device_id *id)
} }
chip->thread = NULL; chip->thread = NULL;
if (desc->checkmode) { if (desc->flags & CHIP_NEED_CHECKMODE) {
/* start async thread */ /* start async thread */
init_timer(&chip->wt); init_timer(&chip->wt);
chip->wt.function = chip_thread_wake; chip->wt.function = chip_thread_wake;
...@@ -1804,12 +1797,18 @@ static int chip_command(struct i2c_client *client, ...@@ -1804,12 +1797,18 @@ static int chip_command(struct i2c_client *client,
break; break;
case VIDIOC_S_FREQUENCY: case VIDIOC_S_FREQUENCY:
chip->mode = 0; /* automatic */ chip->mode = 0; /* automatic */
if (desc->checkmode && desc->setmode) {
/* For chips that provide getmode, setmode and checkmode,
a kthread is created to automatically to set the audio
standard. In this case, start with MONO and wait 2 seconds
for the decoding to stablize. Then, run kthread to change
to stereo, if carrier detected.
*/
if (chip->thread) {
desc->setmode(chip,V4L2_TUNER_MODE_MONO); desc->setmode(chip,V4L2_TUNER_MODE_MONO);
if (chip->prevmode != 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));
/* the thread will call checkmode() later */
} }
break; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment