Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+35 −36
Original line number Original line Diff line number Diff line
@@ -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 {
#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 {
	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)
{
{
	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,25 +280,14 @@ 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);

		/* schedule next check */
		mod_timer(&chip->wt, jiffies+msecs_to_jiffies(2000));
	}

	v4l_dbg(1, debug, chip->c, "%s: thread exiting\n", chip->c->name);
	return 0;
}

static void generic_checkmode(struct CHIPSTATE *chip)
{
	struct CHIPDESC  *desc = chiplist + chip->type;
	int mode = desc->getmode(chip);

		if (mode == chip->prevmode)
		if (mode == chip->prevmode)
	return;
			continue;

		/* chip detected a new audio mode - set it */
		v4l_dbg(1, debug, chip->c, "%s: thread checkmode\n",
			chip->c->name);


	v4l_dbg(1, debug, chip->c, "%s: thread checkmode\n", chip->c->name);
		chip->prevmode = mode;
		chip->prevmode = mode;


		if (mode & V4L2_TUNER_MODE_STEREO)
		if (mode & V4L2_TUNER_MODE_STEREO)
@@ -313,6 +300,13 @@ static void generic_checkmode(struct CHIPSTATE *chip)
			desc->setmode(chip, V4L2_TUNER_MODE_LANG2);
			desc->setmode(chip, V4L2_TUNER_MODE_LANG2);
		else
		else
			desc->setmode(chip, V4L2_TUNER_MODE_MONO);
			desc->setmode(chip, V4L2_TUNER_MODE_MONO);

		/* schedule next check */
		mod_timer(&chip->wt, jiffies+msecs_to_jiffies(2000));
	}

	v4l_dbg(1, debug, chip->c, "%s: thread exiting\n", chip->c->name);
	return 0;
}
}


/* ---------------------------------------------------------------------- */
/* ---------------------------------------------------------------------- */
@@ -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[] = {
		.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[] = {
		.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[] = {
		.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)
	}
	}


	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,
		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;