Attached is a patch to eliminate the duplicative i2c_algo_bit callback
functions in cx18-i2c.c (e.g. cx18_setsdl1() & cx18_setsdl2()) by
augmenting the private callback data sent to these functions.
This patch will *not* fix anyone's I2C bus problems with the HVR-1600,
but it should not cause problems either.
I am not asking for this patch to be committed yet. It is simply a step
in preparation for further changes to cx18 i2c bus handling (whether
that be porting the newi2c code from ivtv or adding interrupt driven I2C
handling).
Can you please check to see that I caught everything and provide any
other comments (e.g. a better way to make the change or arguments
against making the change)?
Regards,
Andy
--- cx18-f763c5864f9a/linux/drivers/media/video/cx18/cx18-driver.h.orig 2008-04-12 09:15:52.000000000 -0400
+++ cx18-f763c5864f9a/linux/drivers/media/video/cx18/cx18-driver.h 2008-04-12 10:13:43.000000000 -0400
@@ -343,6 +343,13 @@ struct vbi_info {
u32 sliced_size;
};
+/* Per cx23418, per I2C bus private algo callback data */
+struct cx18_i2c_algo_callback_data {
+ struct cx18 *cx;
+ u32 wr_reg_addr; /* WR reg offset for cx23418's 1st or 2nd I2C bus */
+ u32 rd_reg_addr; /* RD reg offset for cx23418's 1st or 2nd I2C bus */
+};
+
/* Struct to hold info about cx18 cards */
struct cx18 {
int num; /* board number, -1 during init! */
@@ -425,6 +432,7 @@ struct cx18 {
/* i2c */
struct i2c_adapter i2c_adap[2];
struct i2c_algo_bit_data i2c_algo[2];
+ struct cx18_i2c_algo_callback_data i2c_algo_cb_data[2];
struct i2c_client i2c_client[2];
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 15)
struct mutex i2c_bus_lock[2];
--- cx18-f763c5864f9a/linux/drivers/media/video/cx18/cx18-i2c.c.orig 2008-04-12 07:59:27.000000000 -0400
+++ cx18-f763c5864f9a/linux/drivers/media/video/cx18/cx18-i2c.c 2008-04-12 10:20:17.000000000 -0400
@@ -172,76 +172,44 @@ static int detach_inform(struct i2c_clie
return 0;
}
-static void cx18_setscl1(void *data, int state)
+static void cx18_setscl(void *data, int state)
{
- struct cx18 *cx = (struct cx18 *)data;
- u32 r = read_reg(CX18_REG_I2C_1_WR);
+ struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
+ u32 addr = ((struct cx18_i2c_algo_callback_data *)data)->wr_reg_addr;
+ u32 r = read_reg(addr);
if (state)
- write_reg(r | SETSCL_BIT, CX18_REG_I2C_1_WR);
+ write_reg(r | SETSCL_BIT, addr);
else
- write_reg(r & ~SETSCL_BIT, CX18_REG_I2C_1_WR);
+ write_reg(r & ~SETSCL_BIT, addr);
}
-static void cx18_setsda1(void *data, int state)
+static void cx18_setsda(void *data, int state)
{
- struct cx18 *cx = (struct cx18 *)data;
- u32 r = read_reg(CX18_REG_I2C_1_WR);
+ struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
+ u32 addr = ((struct cx18_i2c_algo_callback_data *)data)->wr_reg_addr;
+ u32 r = read_reg(addr);
if (state)
- write_reg(r | SETSDL_BIT, CX18_REG_I2C_1_WR);
+ write_reg(r | SETSDL_BIT, addr);
else
- write_reg(r & ~SETSDL_BIT, CX18_REG_I2C_1_WR);
+ write_reg(r & ~SETSDL_BIT, addr);
}
-static int cx18_getscl1(void *data)
+static int cx18_getscl(void *data)
{
- struct cx18 *cx = (struct cx18 *)data;
+ struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
+ u32 addr = ((struct cx18_i2c_algo_callback_data *)data)->rd_reg_addr;
- return read_reg(CX18_REG_I2C_1_RD) & GETSCL_BIT;
+ return read_reg(addr) & GETSCL_BIT;
}
-static int cx18_getsda1(void *data)
+static int cx18_getsda(void *data)
{
- struct cx18 *cx = (struct cx18 *)data;
+ struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
+ u32 addr = ((struct cx18_i2c_algo_callback_data *)data)->rd_reg_addr;
- return read_reg(CX18_REG_I2C_1_RD) & GETSDL_BIT;
-}
-
-static void cx18_setscl2(void *data, int state)
-{
- struct cx18 *cx = (struct cx18 *)data;
- u32 r = read_reg(CX18_REG_I2C_2_WR);
-
- if (state)
- write_reg(r | SETSCL_BIT, CX18_REG_I2C_2_WR);
- else
- write_reg(r & ~SETSCL_BIT, CX18_REG_I2C_2_WR);
-}
-
-static void cx18_setsda2(void *data, int state)
-{
- struct cx18 *cx = (struct cx18 *)data;
- u32 r = read_reg(CX18_REG_I2C_2_WR);
-
- if (state)
- write_reg(r | SETSDL_BIT, CX18_REG_I2C_2_WR);
- else
- write_reg(r & ~SETSDL_BIT, CX18_REG_I2C_2_WR);
-}
-
-static int cx18_getscl2(void *data)
-{
- struct cx18 *cx = (struct cx18 *)data;
-
- return read_reg(CX18_REG_I2C_2_RD) & GETSCL_BIT;
-}
-
-static int cx18_getsda2(void *data)
-{
- struct cx18 *cx = (struct cx18 *)data;
-
- return read_reg(CX18_REG_I2C_2_RD) & GETSDL_BIT;
+ return read_reg(addr) & GETSDL_BIT;
}
/* template for i2c-bit-algo */
@@ -260,23 +228,13 @@ static struct i2c_adapter cx18_i2c_adap_
#endif
};
-static struct i2c_algo_bit_data cx18_i2c_algo_template[2] = {
- {
- .setsda = cx18_setsda1,
- .setscl = cx18_setscl1,
- .getsda = cx18_getsda1,
- .getscl = cx18_getscl1,
- .udelay = 10,
- .timeout = 200,
- },
- {
- .setsda = cx18_setsda2,
- .setscl = cx18_setscl2,
- .getsda = cx18_getsda2,
- .getscl = cx18_getscl2,
- .udelay = 10,
- .timeout = 200,
- }
+static struct i2c_algo_bit_data cx18_i2c_algo_template = {
+ .setsda = cx18_setsda,
+ .setscl = cx18_setscl,
+ .getsda = cx18_getsda,
+ .getscl = cx18_getscl,
+ .udelay = 10,
+ .timeout = 200,
};
static struct i2c_client cx18_i2c_client_template = {
@@ -415,9 +373,16 @@ int init_cx18_i2c(struct cx18 *cx)
for (i = 0; i < 2; i++) {
memcpy(&cx->i2c_adap[i], &cx18_i2c_adap_template,
sizeof(struct i2c_adapter));
- memcpy(&cx->i2c_algo[i], &cx18_i2c_algo_template[i],
+ memcpy(&cx->i2c_algo[i], &cx18_i2c_algo_template,
sizeof(struct i2c_algo_bit_data));
- cx->i2c_algo[i].data = cx;
+ cx->i2c_algo_cb_data[i].cx = cx;
+ cx->i2c_algo_cb_data[i].wr_reg_addr = (i == 0)
+ ? CX18_REG_I2C_1_WR
+ : CX18_REG_I2C_2_WR;
+ cx->i2c_algo_cb_data[i].rd_reg_addr = (i == 0)
+ ? CX18_REG_I2C_1_RD
+ : CX18_REG_I2C_2_RD;
+ cx->i2c_algo[i].data = &(cx->i2c_algo_cb_data[i]);
cx->i2c_adap[i].algo_data = &cx->i2c_algo[i];
sprintf(cx->i2c_adap[i].name + strlen(cx->i2c_adap[i].name), " #%d-%d", cx->num, i);
@@ -449,12 +414,12 @@ int init_cx18_i2c(struct cx18 *cx)
write_reg(0x00c00000, 0xc730c4); /* Clear any stale intrs */
write_reg(0x00021c0f & ~4, CX18_REG_I2C_1_WR); /* Hw I2C1 Clock Freq ~100kHz */
- cx18_setscl1(cx, 1);
- cx18_setsda1(cx, 1);
+ cx18_setscl(&(cx->i2c_algo_cb_data[0]), 1);
+ cx18_setsda(&(cx->i2c_algo_cb_data[0]), 1);
write_reg(0x00021c0f & ~4, CX18_REG_I2C_2_WR); /* Hw I2C2 Clock Freq ~100kHz */
- cx18_setscl2(cx, 1);
- cx18_setsda2(cx, 1);
+ cx18_setscl(&(cx->i2c_algo_cb_data[1]), 1);
+ cx18_setsda(&(cx->i2c_algo_cb_data[1]), 1);
return i2c_bit_add_bus(&cx->i2c_adap[0]) || i2c_bit_add_bus(&cx->i2c_adap[1]);
}
_______________________________________________
ivtv-devel mailing list
[email protected]
http://ivtvdriver.org/mailman/listinfo/ivtv-devel