summaryrefslogtreecommitdiff
path: root/drivers/media/video/cx18/cx18-i2c.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/cx18/cx18-i2c.c')
-rw-r--r--drivers/media/video/cx18/cx18-i2c.c36
1 files changed, 26 insertions, 10 deletions
diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c
index 4f08a4058d1a..6023ba3bd3a6 100644
--- a/drivers/media/video/cx18/cx18-i2c.c
+++ b/drivers/media/video/cx18/cx18-i2c.c
@@ -39,10 +39,6 @@
#define GETSCL_BIT 0x0004
#define GETSDL_BIT 0x0008
-#ifndef I2C_ADAP_CLASS_TV_ANALOG
-#define I2C_ADAP_CLASS_TV_ANALOG I2C_CLASS_TV_ANALOG
-#endif
-
#define CX18_CS5345_I2C_ADDR 0x4c
/* This array should match the CX18_HW_ defines */
@@ -74,7 +70,7 @@ static const u8 hw_bus[] = {
};
/* This array should match the CX18_HW_ defines */
-static const char * const hw_drivernames[] = {
+static const char * const hw_devicenames[] = {
"tuner",
"tveeprom",
"cs5345",
@@ -95,8 +91,7 @@ int cx18_i2c_register(struct cx18 *cx, unsigned idx)
id = hw_driverids[idx];
bus = hw_bus[idx];
memset(&info, 0, sizeof(info));
- strlcpy(info.driver_name, hw_drivernames[idx],
- sizeof(info.driver_name));
+ strlcpy(info.type, hw_devicenames[idx], sizeof(info.type));
info.addr = hw_addrs[idx];
for (i = 0; i < I2C_CLIENTS_MAX; i++)
if (cx->i2c_clients[i] == NULL)
@@ -279,7 +274,7 @@ static const char *cx18_i2c_id_name(u32 id)
for (i = 0; i < ARRAY_SIZE(hw_driverids); i++)
if (hw_driverids[i] == id)
- return hw_drivernames[i];
+ return hw_devicenames[i];
return "unknown device";
}
@@ -290,7 +285,7 @@ static const char *cx18_i2c_hw_name(u32 hw)
for (i = 0; i < ARRAY_SIZE(hw_driverids); i++)
if (1 << i == hw)
- return hw_drivernames[i];
+ return hw_devicenames[i];
return "unknown device";
}
@@ -312,8 +307,12 @@ int cx18_i2c_hw(struct cx18 *cx, u32 hw, unsigned int cmd, void *arg)
{
int addr;
- if (hw == CX18_HW_GPIO || hw == 0)
+ if (hw == 0)
return 0;
+
+ if (hw == CX18_HW_GPIO)
+ return cx18_gpio(cx, cmd, arg);
+
if (hw == CX18_HW_CX23418)
return cx18_av_cmd(cx, cmd, arg);
@@ -351,6 +350,8 @@ void cx18_call_i2c_clients(struct cx18 *cx, unsigned int cmd, void *arg)
cx18_av_cmd(cx, cmd, arg);
i2c_clients_command(&cx->i2c_adap[0], cmd, arg);
i2c_clients_command(&cx->i2c_adap[1], cmd, arg);
+ if (cx->hw_flags & CX18_HW_GPIO)
+ cx18_gpio(cx, cmd, arg);
}
/* init + register i2c algo-bit adapter */
@@ -359,6 +360,18 @@ int init_cx18_i2c(struct cx18 *cx)
int i;
CX18_DEBUG_I2C("i2c init\n");
+ /* Sanity checks for the I2C hardware arrays. They must be the
+ * same size and GPIO/CX23418 must be the last entries.
+ */
+ if (ARRAY_SIZE(hw_driverids) != ARRAY_SIZE(hw_addrs) ||
+ ARRAY_SIZE(hw_devicenames) != ARRAY_SIZE(hw_addrs) ||
+ CX18_HW_GPIO != (1 << (ARRAY_SIZE(hw_addrs) - 2)) ||
+ CX18_HW_CX23418 != (1 << (ARRAY_SIZE(hw_addrs) - 1)) ||
+ hw_driverids[ARRAY_SIZE(hw_addrs) - 1]) {
+ CX18_ERR("Mismatched I2C hardware arrays\n");
+ return -ENODEV;
+ }
+
for (i = 0; i < 2; i++) {
memcpy(&cx->i2c_adap[i], &cx18_i2c_adap_template,
sizeof(struct i2c_adapter));
@@ -392,6 +405,7 @@ int init_cx18_i2c(struct cx18 *cx)
write_reg_sync(0x00c000c0, 0xc7001c);
mdelay(10);
write_reg_sync(0x00c00000, 0xc7001c);
+ mdelay(10);
write_reg_sync(0x00c00000, 0xc730c8); /* Set to edge-triggered intrs. */
write_reg_sync(0x00c00000, 0xc730c4); /* Clear any stale intrs */
@@ -406,6 +420,8 @@ int init_cx18_i2c(struct cx18 *cx)
cx18_setscl(&cx->i2c_algo_cb_data[1], 1);
cx18_setsda(&cx->i2c_algo_cb_data[1], 1);
+ cx18_reset_i2c_slaves_gpio(cx);
+
return i2c_bit_add_bus(&cx->i2c_adap[0]) ||
i2c_bit_add_bus(&cx->i2c_adap[1]);
}