Patch 1/4: Collapse per I2C bus callback functions into a common set.
This patch is required for the patches that follow. It changes the cx18
driver to use a common set of callback routines for i2c-algo-bit for
both i2c buses, instead of having a separate copy of each routine for
each bus the cx23418 drives.
-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-17 17:42:06.000000000 -0400
@@ -343,6 +343,12 @@ struct vbi_info {
u32 sliced_size;
};
+/* Per cx23418, per I2C bus private algo callback data */
+struct cx18_i2c_algo_callback_data {
+ struct cx18 *cx;
+ int bus_index; /* 0 or 1 for the 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 +431,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-17 18:06:21.000000000 -0400
@@ -172,76 +172,48 @@ 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;
+ int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index;
+ u32 addr = bus_index ? CX18_REG_I2C_2_WR : CX18_REG_I2C_1_WR;
+ 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;
+ int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index;
+ u32 addr = bus_index ? CX18_REG_I2C_2_WR : CX18_REG_I2C_1_WR;
+ 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;
+ int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index;
+ u32 addr = bus_index ? CX18_REG_I2C_2_RD : CX18_REG_I2C_1_RD;
- 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;
+ int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index;
+ u32 addr = bus_index ? CX18_REG_I2C_2_RD : CX18_REG_I2C_1_RD;
- 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 +232,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 +377,11 @@ 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].bus_index = i;
+ 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 +413,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