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

Commit f412d36a authored by Andy Walls's avatar Andy Walls Committed by Mauro Carvalho Chehab
Browse files

V4L/DVB (13442): ivtv: Add module parameter to adjust I2C SCL clock period per board



Add a module parameter to adjust I2C SCL clock period per board.  This allows
some experimental fine tuning by end users to overcome quirky I2C device
problems.

Reported-by: default avatar"Aleksandr V. Piskunov" <aleksandr.v.piskunov@gmail.com>
Signed-off-by: default avatarAndy Walls <awalls@radix.net>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent e45e8f5c
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -91,10 +91,15 @@ static int radio[IVTV_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
				     -1, -1, -1, -1, -1, -1, -1, -1,
				     -1, -1, -1, -1, -1, -1, -1, -1,
				     -1, -1, -1, -1, -1, -1, -1, -1 };
static int i2c_clock_period[IVTV_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
					       -1, -1, -1, -1, -1, -1, -1, -1,
					       -1, -1, -1, -1, -1, -1, -1, -1,
					       -1, -1, -1, -1, -1, -1, -1, -1 };

static unsigned int cardtype_c = 1;
static unsigned int tuner_c = 1;
static unsigned int radio_c = 1;
static unsigned int i2c_clock_period_c = 1;
static char pal[] = "---";
static char secam[] = "--";
static char ntsc[] = "-";
@@ -151,6 +156,7 @@ module_param(dec_vbi_buffers, int, 0644);

module_param(tunertype, int, 0644);
module_param(newi2c, int, 0644);
module_param_array(i2c_clock_period, int, &i2c_clock_period_c, 0644);

MODULE_PARM_DESC(tuner, "Tuner type selection,\n"
			"\t\t\tsee tuner.h for values");
@@ -245,6 +251,10 @@ MODULE_PARM_DESC(newi2c,
		 "Use new I2C implementation\n"
		 "\t\t\t-1 is autodetect, 0 is off, 1 is on\n"
		 "\t\t\tDefault is autodetect");
MODULE_PARM_DESC(i2c_clock_period,
		 "Period of SCL for the I2C bus controlled by the CX23415/6\n"
		 "\t\t\tMin: 10 usec (100 kHz), Max: 4500 usec (222 Hz)\n"
		 "\t\t\tDefault: " __stringify(IVTV_DEFAULT_I2C_CLOCK_PERIOD));

MODULE_PARM_DESC(ivtv_first_minor, "Set device node number assigned to first card");

@@ -600,6 +610,15 @@ static void ivtv_process_options(struct ivtv *itv)
	itv->options.cardtype = cardtype[itv->instance];
	itv->options.tuner = tuner[itv->instance];
	itv->options.radio = radio[itv->instance];

	itv->options.i2c_clock_period = i2c_clock_period[itv->instance];
	if (itv->options.i2c_clock_period == -1)
		itv->options.i2c_clock_period = IVTV_DEFAULT_I2C_CLOCK_PERIOD;
	else if (itv->options.i2c_clock_period < 10)
		itv->options.i2c_clock_period = 10;
	else if (itv->options.i2c_clock_period > 4500)
		itv->options.i2c_clock_period = 4500;

	itv->options.newi2c = newi2c;
	if (tunertype < -1 || tunertype > 1) {
		IVTV_WARN("Invalid tunertype argument, will autodetect instead\n");
+4 −0
Original line number Diff line number Diff line
@@ -176,12 +176,16 @@ extern int ivtv_debug;

#define IVTV_MAX_PGM_INDEX (400)

/* Default I2C SCL period in microseconds */
#define IVTV_DEFAULT_I2C_CLOCK_PERIOD	20

struct ivtv_options {
	int kilobytes[IVTV_MAX_STREAMS];        /* size in kilobytes of each stream */
	int cardtype;				/* force card type on load */
	int tuner;				/* set tuner on load */
	int radio;				/* enable/disable radio */
	int newi2c;				/* new I2C algorithm */
	int i2c_clock_period;			/* period of SCL for I2C bus */
};

/* ivtv-specific mailbox template */
+5 −2
Original line number Diff line number Diff line
@@ -564,13 +564,15 @@ static struct i2c_adapter ivtv_i2c_adap_template = {
	.owner = THIS_MODULE,
};

#define IVTV_ALGO_BIT_TIMEOUT	(2)	/* seconds */

static const struct i2c_algo_bit_data ivtv_i2c_algo_template = {
	.setsda		= ivtv_setsda_old,
	.setscl		= ivtv_setscl_old,
	.getsda		= ivtv_getsda_old,
	.getscl		= ivtv_getscl_old,
	.udelay		= 10,
	.timeout	= 200,
	.udelay		= IVTV_DEFAULT_I2C_CLOCK_PERIOD / 2,  /* microseconds */
	.timeout	= IVTV_ALGO_BIT_TIMEOUT * HZ,         /* jiffies */
};

static struct i2c_client ivtv_i2c_client_template = {
@@ -602,6 +604,7 @@ int init_ivtv_i2c(struct ivtv *itv)
		memcpy(&itv->i2c_algo, &ivtv_i2c_algo_template,
		       sizeof(struct i2c_algo_bit_data));
	}
	itv->i2c_algo.udelay = itv->options.i2c_clock_period / 2;
	itv->i2c_algo.data = itv;
	itv->i2c_adap.algo_data = &itv->i2c_algo;