From 1784ea5527ed756f946958f45f74d1f15797c366 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 30 Mar 2009 01:04:44 +0200 Subject: v4l2: use old-style i2c API for kernels < 2.6.26 instead of < 2.6.22 From: Hans Verkuil Originally the intention was to switch to the new style i2c API starting with the introduction of the API in 2.6.22. However, the i2c_new_probed_device() function has a lethal bug that wasn't fixed until 2.6.25. Or more accurately, it was only fixed in the stable series of 2.6.25 and 2.6.26. Given the fact that the new i2c API also changed starting with 2.6.26 (the addition of i2c_device_id), it is easiest to switch APIs starting with 2.6.26. This patch updates all the legacy code accordingly. Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/cx18/cx18-i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/video/cx18/cx18-i2c.c') diff --git a/linux/drivers/media/video/cx18/cx18-i2c.c b/linux/drivers/media/video/cx18/cx18-i2c.c index bf15b648d..6c3c0449c 100644 --- a/linux/drivers/media/video/cx18/cx18-i2c.c +++ b/linux/drivers/media/video/cx18/cx18-i2c.c @@ -194,7 +194,7 @@ static struct i2c_adapter cx18_i2c_adap_template = { .algo = NULL, /* set by i2c-algo-bit */ .algo_data = NULL, /* filled from template */ .owner = THIS_MODULE, -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) .class = I2C_CLASS_TV_ANALOG, #endif }; -- cgit v1.2.3 From f0312f1d7b8dd5cde4035eef2a5b0fe7effdd838 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 1 Apr 2009 08:57:53 +0200 Subject: v4l2-common: add explicit v4l2_device pointer as first arg to new_(probed)_subdev From: Hans Verkuil The functions v4l2_i2c_new_subdev and v4l2_i2c_new_probed_subdev relied on i2c_get_adapdata to return the v4l2_device. However, this is not always possible on embedded platforms. So modify the API to pass the v4l2_device pointer explicitly. Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/cx18/cx18-i2c.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'linux/drivers/media/video/cx18/cx18-i2c.c') diff --git a/linux/drivers/media/video/cx18/cx18-i2c.c b/linux/drivers/media/video/cx18/cx18-i2c.c index 6c3c0449c..4bf737849 100644 --- a/linux/drivers/media/video/cx18/cx18-i2c.c +++ b/linux/drivers/media/video/cx18/cx18-i2c.c @@ -100,16 +100,16 @@ int cx18_i2c_register(struct cx18 *cx, unsigned idx) if (hw == CX18_HW_TUNER) { /* special tuner group handling */ - sd = v4l2_i2c_new_probed_subdev(adap, mod, type, - cx->card_i2c->radio); + sd = v4l2_i2c_new_probed_subdev(&cx->v4l2_dev, + adap, mod, type, cx->card_i2c->radio); if (sd != NULL) sd->grp_id = hw; - sd = v4l2_i2c_new_probed_subdev(adap, mod, type, - cx->card_i2c->demod); + sd = v4l2_i2c_new_probed_subdev(&cx->v4l2_dev, + adap, mod, type, cx->card_i2c->demod); if (sd != NULL) sd->grp_id = hw; - sd = v4l2_i2c_new_probed_subdev(adap, mod, type, - cx->card_i2c->tv); + sd = v4l2_i2c_new_probed_subdev(&cx->v4l2_dev, + adap, mod, type, cx->card_i2c->tv); if (sd != NULL) sd->grp_id = hw; return sd != NULL ? 0 : -1; @@ -120,7 +120,7 @@ int cx18_i2c_register(struct cx18 *cx, unsigned idx) return -1; /* It's an I2C device other than an analog tuner */ - sd = v4l2_i2c_new_subdev(adap, mod, type, hw_addrs[idx]); + sd = v4l2_i2c_new_subdev(&cx->v4l2_dev, adap, mod, type, hw_addrs[idx]); if (sd != NULL) sd->grp_id = hw; return sd != NULL ? 0 : -1; -- cgit v1.2.3 From d11015309b20086d70d49ef788bc935f0225144a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 17 Apr 2009 13:56:51 +0000 Subject: cx18: Fix the handling of i2c bus registration error From: Jean Delvare * Return actual error values as returned by the i2c subsystem, rather than 0 or 1. * If the registration of the second bus fails, unregister the first one before exiting, otherwise we are leaking resources. Signed-off-by: Jean Delvare Acked-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/cx18/cx18-i2c.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'linux/drivers/media/video/cx18/cx18-i2c.c') diff --git a/linux/drivers/media/video/cx18/cx18-i2c.c b/linux/drivers/media/video/cx18/cx18-i2c.c index 4bf737849..3c76a1e27 100644 --- a/linux/drivers/media/video/cx18/cx18-i2c.c +++ b/linux/drivers/media/video/cx18/cx18-i2c.c @@ -214,7 +214,7 @@ static struct i2c_algo_bit_data cx18_i2c_algo_template = { /* init + register i2c algo-bit adapter */ int init_cx18_i2c(struct cx18 *cx) { - int i; + int i, err; CX18_DEBUG_I2C("i2c init\n"); for (i = 0; i < 2; i++) { @@ -273,8 +273,18 @@ int init_cx18_i2c(struct cx18 *cx) cx18_call_hw(cx, CX18_HW_GPIO_RESET_CTRL, core, reset, (u32) CX18_GPIO_RESET_I2C); - return i2c_bit_add_bus(&cx->i2c_adap[0]) || - i2c_bit_add_bus(&cx->i2c_adap[1]); + err = i2c_bit_add_bus(&cx->i2c_adap[0]); + if (err) + goto err; + err = i2c_bit_add_bus(&cx->i2c_adap[1]); + if (err) + goto err_del_bus_0; + return 0; + + err_del_bus_0: + i2c_del_adapter(&cx->i2c_adap[0]); + err: + return err; } void exit_cx18_i2c(struct cx18 *cx) -- cgit v1.2.3 From f47aedd6b5ff27a36bee52be6cd41b022375b133 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 19 Jun 2009 19:56:56 +0000 Subject: Stop defining I2C adapter IDs nobody uses From: Jean Delvare There is no point in defining I2C adapter IDs when no code is using them. As this field might go away in the future, stop using it when we don't need to. Signed-off-by: Jean Delvare Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/cx18/cx18-i2c.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'linux/drivers/media/video/cx18/cx18-i2c.c') diff --git a/linux/drivers/media/video/cx18/cx18-i2c.c b/linux/drivers/media/video/cx18/cx18-i2c.c index 3c76a1e27..cee650c58 100644 --- a/linux/drivers/media/video/cx18/cx18-i2c.c +++ b/linux/drivers/media/video/cx18/cx18-i2c.c @@ -190,7 +190,9 @@ static int cx18_getsda(void *data) /* template for i2c-bit-algo */ static struct i2c_adapter cx18_i2c_adap_template = { .name = "cx18 i2c driver", +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31) .id = I2C_HW_B_CX2341X, +#endif .algo = NULL, /* set by i2c-algo-bit */ .algo_data = NULL, /* filled from template */ .owner = THIS_MODULE, -- cgit v1.2.3 From 0be3a0fdedcfa1995a6b1398ccea67554e7edad6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 28 Jul 2009 11:48:18 -0300 Subject: cx18: Add i2c initialization for Z8F0811/Hauppage IR transceivers From: Andy Walls This patch add support to the cx18 driver for setting up the Z8F0811/Hauppauge IR Tx/Rx chip with the i2c binding model in newer kernels. Priority: normal Signed-off-by: Andy Walls Reviewed-by: Jean Delvare Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/cx18/cx18-i2c.c | 63 +++++++++++++++++++++++++++---- 1 file changed, 55 insertions(+), 8 deletions(-) (limited to 'linux/drivers/media/video/cx18/cx18-i2c.c') diff --git a/linux/drivers/media/video/cx18/cx18-i2c.c b/linux/drivers/media/video/cx18/cx18-i2c.c index cee650c58..c551fcd47 100644 --- a/linux/drivers/media/video/cx18/cx18-i2c.c +++ b/linux/drivers/media/video/cx18/cx18-i2c.c @@ -28,6 +28,9 @@ #include "cx18-gpio.h" #include "cx18-i2c.h" #include "cx18-irq.h" +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30) +#include +#endif #define CX18_REG_I2C_1_WR 0xf15000 #define CX18_REG_I2C_1_RD 0xf15008 @@ -40,16 +43,20 @@ #define GETSDL_BIT 0x0008 #define CX18_CS5345_I2C_ADDR 0x4c +#define CX18_Z8F0811_IR_TX_I2C_ADDR 0x70 +#define CX18_Z8F0811_IR_RX_I2C_ADDR 0x71 /* This array should match the CX18_HW_ defines */ static const u8 hw_addrs[] = { - 0, /* CX18_HW_TUNER */ - 0, /* CX18_HW_TVEEPROM */ - CX18_CS5345_I2C_ADDR, /* CX18_HW_CS5345 */ - 0, /* CX18_HW_DVB */ - 0, /* CX18_HW_418_AV */ - 0, /* CX18_HW_GPIO_MUX */ - 0, /* CX18_HW_GPIO_RESET_CTRL */ + 0, /* CX18_HW_TUNER */ + 0, /* CX18_HW_TVEEPROM */ + CX18_CS5345_I2C_ADDR, /* CX18_HW_CS5345 */ + 0, /* CX18_HW_DVB */ + 0, /* CX18_HW_418_AV */ + 0, /* CX18_HW_GPIO_MUX */ + 0, /* CX18_HW_GPIO_RESET_CTRL */ + CX18_Z8F0811_IR_TX_I2C_ADDR, /* CX18_HW_Z8F0811_IR_TX_HAUP */ + CX18_Z8F0811_IR_RX_I2C_ADDR, /* CX18_HW_Z8F0811_IR_RX_HAUP */ }; /* This array should match the CX18_HW_ defines */ @@ -62,6 +69,8 @@ static const u8 hw_bus[] = { 0, /* CX18_HW_418_AV */ 0, /* CX18_HW_GPIO_MUX */ 0, /* CX18_HW_GPIO_RESET_CTRL */ + 0, /* CX18_HW_Z8F0811_IR_TX_HAUP */ + 0, /* CX18_HW_Z8F0811_IR_RX_HAUP */ }; /* This array should match the CX18_HW_ defines */ @@ -73,6 +82,8 @@ static const char * const hw_modules[] = { NULL, /* CX18_HW_418_AV */ NULL, /* CX18_HW_GPIO_MUX */ NULL, /* CX18_HW_GPIO_RESET_CTRL */ + NULL, /* CX18_HW_Z8F0811_IR_TX_HAUP */ + NULL, /* CX18_HW_Z8F0811_IR_RX_HAUP */ }; /* This array should match the CX18_HW_ defines */ @@ -84,8 +95,41 @@ static const char * const hw_devicenames[] = { "cx23418_AV", "gpio_mux", "gpio_reset_ctrl", + "ir_tx_z8f0811_haup", + "ir_rx_z8f0811_haup", }; +static int cx18_i2c_new_ir(struct i2c_adapter *adap, u32 hw, const char *type, + u8 addr) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30) + struct i2c_board_info info; + struct IR_i2c_init_data ir_init_data; + unsigned short addr_list[2] = { addr, I2C_CLIENT_END }; + + memset(&info, 0, sizeof(struct i2c_board_info)); + strlcpy(info.type, type, I2C_NAME_SIZE); + + /* Our default information for ir-kbd-i2c.c to use */ + switch (hw) { + case CX18_HW_Z8F0811_IR_RX_HAUP: + memset(&ir_init_data, 0, sizeof(struct IR_i2c_init_data)); + ir_init_data.ir_codes = ir_codes_hauppauge_new; + ir_init_data.internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR; + ir_init_data.type = IR_TYPE_RC5; + ir_init_data.name = "CX23418 Z8F0811 Hauppauge"; + info.platform_data = &ir_init_data; + break; + default: + break; + } + + return i2c_new_probed_device(adap, &info, addr_list) == NULL ? -1 : 0; +#else + return -1; +#endif +} + int cx18_i2c_register(struct cx18 *cx, unsigned idx) { struct v4l2_subdev *sd; @@ -115,11 +159,14 @@ int cx18_i2c_register(struct cx18 *cx, unsigned idx) return sd != NULL ? 0 : -1; } + if (hw & CX18_HW_Z8F0811_IR_HAUP) + return cx18_i2c_new_ir(adap, hw, type, hw_addrs[idx]); + /* Is it not an I2C device or one we do not wish to register? */ if (!hw_addrs[idx]) return -1; - /* It's an I2C device other than an analog tuner */ + /* It's an I2C device other than an analog tuner or IR chip */ sd = v4l2_i2c_new_subdev(&cx->v4l2_dev, adap, mod, type, hw_addrs[idx]); if (sd != NULL) sd->grp_id = hw; -- cgit v1.2.3 From 78b537e32fbc1e45a9d5fe1086c4e6c303661e53 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 10 Aug 2009 07:49:08 +0200 Subject: v4l: simplify v4l2_i2c_new_subdev and friends From: Hans Verkuil Rewrite v4l2_i2c_new_subdev as a simplified version of v4l2_i2c_new_subdev_cfg and remove v4l2_i2c_new_probed_subdev and v4l2_i2c_new_probed_subdev_addr. This simplifies this API substantially. Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/cx18/cx18-i2c.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'linux/drivers/media/video/cx18/cx18-i2c.c') diff --git a/linux/drivers/media/video/cx18/cx18-i2c.c b/linux/drivers/media/video/cx18/cx18-i2c.c index c551fcd47..7d4272d33 100644 --- a/linux/drivers/media/video/cx18/cx18-i2c.c +++ b/linux/drivers/media/video/cx18/cx18-i2c.c @@ -144,16 +144,16 @@ int cx18_i2c_register(struct cx18 *cx, unsigned idx) if (hw == CX18_HW_TUNER) { /* special tuner group handling */ - sd = v4l2_i2c_new_probed_subdev(&cx->v4l2_dev, - adap, mod, type, cx->card_i2c->radio); + sd = v4l2_i2c_new_subdev(&cx->v4l2_dev, + adap, mod, type, 0, cx->card_i2c->radio); if (sd != NULL) sd->grp_id = hw; - sd = v4l2_i2c_new_probed_subdev(&cx->v4l2_dev, - adap, mod, type, cx->card_i2c->demod); + sd = v4l2_i2c_new_subdev(&cx->v4l2_dev, + adap, mod, type, 0, cx->card_i2c->demod); if (sd != NULL) sd->grp_id = hw; - sd = v4l2_i2c_new_probed_subdev(&cx->v4l2_dev, - adap, mod, type, cx->card_i2c->tv); + sd = v4l2_i2c_new_subdev(&cx->v4l2_dev, + adap, mod, type, 0, cx->card_i2c->tv); if (sd != NULL) sd->grp_id = hw; return sd != NULL ? 0 : -1; @@ -167,7 +167,7 @@ int cx18_i2c_register(struct cx18 *cx, unsigned idx) return -1; /* It's an I2C device other than an analog tuner or IR chip */ - sd = v4l2_i2c_new_subdev(&cx->v4l2_dev, adap, mod, type, hw_addrs[idx]); + sd = v4l2_i2c_new_subdev(&cx->v4l2_dev, adap, mod, type, hw_addrs[idx], NULL); if (sd != NULL) sd->grp_id = hw; return sd != NULL ? 0 : -1; -- cgit v1.2.3