From c668f32dca105d876e51862a003a302fa61e4ae4 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 13 May 2009 16:48:50 -0300 Subject: V4L/DVB (11844): ir-kbd-i2c: Switch to the new-style device binding model Let card drivers probe for IR receiver devices and instantiate them if found. Ultimately it would be better if we could stop probing completely, but I suspect this won't be possible for all card types. There's certainly room for cleanups. For example, some drivers are sharing I2C adapter IDs, so they also had to share the list of I2C addresses being probed for an IR receiver. Now that each driver explicitly says which addresses should be probed, maybe some addresses can be dropped from some drivers. Also, the special cases in saa7134-i2c should probably be handled on a per-board basis. This would be more efficient and less risky than always probing extra addresses on all boards. I'll give it a try later. Signed-off-by: Jean Delvare Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-i2c.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/media/video/em28xx/em28xx-i2c.c') diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c index f0bf1d960c75..d90294cbb70d 100644 --- a/drivers/media/video/em28xx/em28xx-i2c.c +++ b/drivers/media/video/em28xx/em28xx-i2c.c @@ -575,6 +575,9 @@ int em28xx_i2c_register(struct em28xx *dev) if (i2c_scan) em28xx_do_i2c_scan(dev); + /* Instantiate the IR receiver device, if present */ + em28xx_register_i2c_ir(dev); + return 0; } -- cgit v1.2.3 From 4d7a2d6721a6380d4ffc26d81d2c8232fd0d2dfc Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 13 May 2009 16:49:32 -0300 Subject: V4L/DVB (11845): ir-kbd-i2c: Use initialization data For specific boards, pass initialization data to ir-kbd-i2c instead of modifying the settings after the device is initialized. This is more efficient and easier to read. Signed-off-by: Jean Delvare Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx231xx/cx231xx-cards.c | 3 - drivers/media/video/cx231xx/cx231xx-i2c.c | 29 --------- drivers/media/video/cx231xx/cx231xx.h | 1 - drivers/media/video/em28xx/em28xx-cards.c | 31 +++++----- drivers/media/video/em28xx/em28xx-i2c.c | 22 ------- drivers/media/video/em28xx/em28xx.h | 1 - drivers/media/video/ir-kbd-i2c.c | 12 +++- drivers/media/video/saa7134/saa7134-i2c.c | 28 --------- drivers/media/video/saa7134/saa7134-input.c | 94 ++++++++++++++--------------- drivers/media/video/saa7134/saa7134.h | 1 - include/media/ir-kbd-i2c.h | 7 +++ 11 files changed, 79 insertions(+), 150 deletions(-) (limited to 'drivers/media/video/em28xx/em28xx-i2c.c') diff --git a/drivers/media/video/cx231xx/cx231xx-cards.c b/drivers/media/video/cx231xx/cx231xx-cards.c index 734f6eaefd9b..63d2239fd324 100644 --- a/drivers/media/video/cx231xx/cx231xx-cards.c +++ b/drivers/media/video/cx231xx/cx231xx-cards.c @@ -287,10 +287,7 @@ void cx231xx_register_i2c_ir(struct cx231xx *dev) return; /* REVISIT: instantiate IR device */ -} -void cx231xx_set_ir(struct cx231xx *dev, struct IR_i2c *ir) -{ /* detect & configure */ switch (dev->model) { diff --git a/drivers/media/video/cx231xx/cx231xx-i2c.c b/drivers/media/video/cx231xx/cx231xx-i2c.c index ac4099a49da0..33219dc4d649 100644 --- a/drivers/media/video/cx231xx/cx231xx-i2c.c +++ b/drivers/media/video/cx231xx/cx231xx-i2c.c @@ -424,34 +424,6 @@ static u32 functionality(struct i2c_adapter *adap) return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C; } -/* - * attach_inform() - * gets called when a device attaches to the i2c bus - * does some basic configuration - */ -static int attach_inform(struct i2c_client *client) -{ - struct cx231xx_i2c *bus = i2c_get_adapdata(client->adapter); - struct cx231xx *dev = bus->dev; - - switch (client->addr << 1) { - case 0x8e: - { - struct IR_i2c *ir = i2c_get_clientdata(client); - dprintk1(1, "attach_inform: IR detected (%s).\n", - ir->phys); - cx231xx_set_ir(dev, ir); - break; - } - break; - - default: - break; - } - - return 0; -} - static struct i2c_algorithm cx231xx_algo = { .master_xfer = cx231xx_i2c_xfer, .functionality = functionality, @@ -462,7 +434,6 @@ static struct i2c_adapter cx231xx_adap_template = { .name = "cx231xx", .id = I2C_HW_B_CX231XX, .algo = &cx231xx_algo, - .client_register = attach_inform, }; static struct i2c_client cx231xx_client_template = { diff --git a/drivers/media/video/cx231xx/cx231xx.h b/drivers/media/video/cx231xx/cx231xx.h index 8c300f60fdff..e38eb2d425f7 100644 --- a/drivers/media/video/cx231xx/cx231xx.h +++ b/drivers/media/video/cx231xx/cx231xx.h @@ -739,7 +739,6 @@ extern struct cx231xx_board cx231xx_boards[]; extern struct usb_device_id cx231xx_id_table[]; extern const unsigned int cx231xx_bcount; void cx231xx_register_i2c_ir(struct cx231xx *dev); -void cx231xx_set_ir(struct cx231xx *dev, struct IR_i2c *ir); int cx231xx_tuner_callback(void *ptr, int component, int command, int arg); /* Provided by cx231xx-input.c */ diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index edba71115a94..fe2a471e5f64 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -1915,6 +1915,7 @@ static int em28xx_hint_board(struct em28xx *dev) void em28xx_register_i2c_ir(struct em28xx *dev) { struct i2c_board_info info; + struct IR_i2c_init_data init_data; const unsigned short addr_list[] = { 0x30, 0x47, I2C_CLIENT_END }; @@ -1923,12 +1924,9 @@ void em28xx_register_i2c_ir(struct em28xx *dev) return; memset(&info, 0, sizeof(struct i2c_board_info)); + memset(&init_data, 0, sizeof(struct IR_i2c_init_data)); strlcpy(info.type, "ir_video", I2C_NAME_SIZE); - i2c_new_probed_device(&dev->i2c_adap, &info, addr_list); -} -void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir) -{ /* detect & configure */ switch (dev->model) { case (EM2800_BOARD_UNKNOWN): @@ -1937,22 +1935,19 @@ void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir) break; case (EM2800_BOARD_TERRATEC_CINERGY_200): case (EM2820_BOARD_TERRATEC_CINERGY_250): - ir->ir_codes = ir_codes_em_terratec; - ir->get_key = em28xx_get_key_terratec; - snprintf(ir->name, sizeof(ir->name), - "i2c IR (EM28XX Terratec)"); + init_data.ir_codes = ir_codes_em_terratec; + init_data.get_key = em28xx_get_key_terratec; + init_data.name = "i2c IR (EM28XX Terratec)"; break; case (EM2820_BOARD_PINNACLE_USB_2): - ir->ir_codes = ir_codes_pinnacle_grey; - ir->get_key = em28xx_get_key_pinnacle_usb_grey; - snprintf(ir->name, sizeof(ir->name), - "i2c IR (EM28XX Pinnacle PCTV)"); + init_data.ir_codes = ir_codes_pinnacle_grey; + init_data.get_key = em28xx_get_key_pinnacle_usb_grey; + init_data.name = "i2c IR (EM28XX Pinnacle PCTV)"; break; case (EM2820_BOARD_HAUPPAUGE_WINTV_USB_2): - ir->ir_codes = ir_codes_hauppauge_new; - ir->get_key = em28xx_get_key_em_haup; - snprintf(ir->name, sizeof(ir->name), - "i2c IR (EM2840 Hauppauge)"); + init_data.ir_codes = ir_codes_hauppauge_new; + init_data.get_key = em28xx_get_key_em_haup; + init_data.name = "i2c IR (EM2840 Hauppauge)"; break; case (EM2820_BOARD_MSI_VOX_USB_2): break; @@ -1963,6 +1958,10 @@ void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir) case (EM2800_BOARD_GRABBEEX_USB2800): break; } + + if (init_data.name) + info.platform_data = &init_data; + i2c_new_probed_device(&dev->i2c_adap, &info, addr_list); } void em28xx_card_setup(struct em28xx *dev) diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c index d90294cbb70d..2c86fcf089f5 100644 --- a/drivers/media/video/em28xx/em28xx-i2c.c +++ b/drivers/media/video/em28xx/em28xx-i2c.c @@ -451,27 +451,6 @@ static u32 functionality(struct i2c_adapter *adap) return I2C_FUNC_SMBUS_EMUL; } -/* - * attach_inform() - * gets called when a device attaches to the i2c bus - * does some basic configuration - */ -static int attach_inform(struct i2c_client *client) -{ - struct em28xx *dev = client->adapter->algo_data; - struct IR_i2c *ir = i2c_get_clientdata(client); - - switch (client->addr << 1) { - case 0x60: - case 0x8e: - dprintk1(1, "attach_inform: IR detected (%s).\n", ir->phys); - em28xx_set_ir(dev, ir); - break; - } - - return 0; -} - static struct i2c_algorithm em28xx_algo = { .master_xfer = em28xx_i2c_xfer, .functionality = functionality, @@ -482,7 +461,6 @@ static struct i2c_adapter em28xx_adap_template = { .name = "em28xx", .id = I2C_HW_B_EM28XX, .algo = &em28xx_algo, - .client_register = attach_inform, }; static struct i2c_client em28xx_client_template = { diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index 9c632541df10..8db797fedb7e 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h @@ -644,7 +644,6 @@ extern struct em28xx_board em28xx_boards[]; extern struct usb_device_id em28xx_id_table[]; extern const unsigned int em28xx_bcount; void em28xx_register_i2c_ir(struct em28xx *dev); -void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir); int em28xx_tuner_callback(void *ptr, int component, int command, int arg); void em28xx_release_resources(struct em28xx *dev); diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c index cb833a63041c..3a8880243b1f 100644 --- a/drivers/media/video/ir-kbd-i2c.c +++ b/drivers/media/video/ir-kbd-i2c.c @@ -298,7 +298,7 @@ static void ir_work(struct work_struct *work) static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) { IR_KEYTAB_TYPE *ir_codes = NULL; - char *name; + const char *name; int ir_type; struct IR_i2c *ir; struct input_dev *input_dev; @@ -386,6 +386,16 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) goto err_out_free; } + /* Let the caller override settings */ + if (client->dev.platform_data) { + const struct IR_i2c_init_data *init_data = + client->dev.platform_data; + + ir_codes = init_data->ir_codes; + name = init_data->name; + ir->get_key = init_data->get_key; + } + /* Sets name */ snprintf(ir->name, sizeof(ir->name), "i2c IR (%s)", name); ir->ir_codes = ir_codes; diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c index a96f75985cba..a8a355e28799 100644 --- a/drivers/media/video/saa7134/saa7134-i2c.c +++ b/drivers/media/video/saa7134/saa7134-i2c.c @@ -321,33 +321,6 @@ static u32 functionality(struct i2c_adapter *adap) return I2C_FUNC_SMBUS_EMUL; } -static int attach_inform(struct i2c_client *client) -{ - struct saa7134_dev *dev = client->adapter->algo_data; - - d1printk( "%s i2c attach [addr=0x%x,client=%s]\n", - client->driver->driver.name, client->addr, client->name); - - /* Am I an i2c remote control? */ - - switch (client->addr) { - case 0x7a: - case 0x47: - case 0x71: - case 0x2d: - case 0x30: - { - struct IR_i2c *ir = i2c_get_clientdata(client); - d1printk("%s i2c IR detected (%s).\n", - client->driver->driver.name, ir->phys); - saa7134_set_i2c_ir(dev,ir); - break; - } - } - - return 0; -} - static struct i2c_algorithm saa7134_algo = { .master_xfer = saa7134_i2c_xfer, .functionality = functionality, @@ -358,7 +331,6 @@ static struct i2c_adapter saa7134_adap_template = { .name = "saa7134", .id = I2C_HW_SAA7134, .algo = &saa7134_algo, - .client_register = attach_inform, }; static struct i2c_client saa7134_client_template = { diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index 4144ca9cc7e0..a20f687f81a8 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c @@ -685,6 +685,7 @@ void saa7134_input_fini(struct saa7134_dev *dev) void saa7134_probe_i2c_ir(struct saa7134_dev *dev) { struct i2c_board_info info; + struct IR_i2c_init_data init_data; const unsigned short addr_list[] = { 0x7a, 0x47, 0x71, 0x2d, I2C_CLIENT_END @@ -722,62 +723,35 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev) } memset(&info, 0, sizeof(struct i2c_board_info)); + memset(&init_data, 0, sizeof(struct IR_i2c_init_data)); strlcpy(info.type, "ir_video", I2C_NAME_SIZE); - client = i2c_new_probed_device(&dev->i2c_adap, &info, addr_list); - if (client) - return; - - /* MSI TV@nywhere Plus controller doesn't seem to - respond to probes unless we read something from - an existing device. Weird... */ - rc = i2c_transfer(&dev->i2c_adap, &msg_msi, 1); - dprintk(KERN_DEBUG "probe 0x%02x @ %s: %s\n", - msg_msi.addr, dev->i2c_adap.name, - (1 == rc) ? "yes" : "no"); - client = i2c_new_probed_device(&dev->i2c_adap, &info, addr_list_msi); - if (client) - return; - /* Special case for AVerMedia Cardbus remote */ - subaddr = 0x0d; - rc = i2c_transfer(&dev->i2c_adap, msg_avermedia, 2); - dprintk(KERN_DEBUG "probe 0x%02x/0x%02x @ %s: %s\n", - msg_avermedia[0].addr, subaddr, dev->i2c_adap.name, - (2 == rc) ? "yes" : "no"); - if (2 == rc) { - info.addr = msg_avermedia[0].addr; - i2c_new_device(&dev->i2c_adap, &info); - } -} - -void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir) -{ switch (dev->board) { case SAA7134_BOARD_PINNACLE_PCTV_110i: case SAA7134_BOARD_PINNACLE_PCTV_310i: - snprintf(ir->name, sizeof(ir->name), "Pinnacle PCTV"); + init_data.name = "Pinnacle PCTV"; if (pinnacle_remote == 0) { - ir->get_key = get_key_pinnacle_color; - ir->ir_codes = ir_codes_pinnacle_color; + init_data.get_key = get_key_pinnacle_color; + init_data.ir_codes = ir_codes_pinnacle_color; } else { - ir->get_key = get_key_pinnacle_grey; - ir->ir_codes = ir_codes_pinnacle_grey; + init_data.get_key = get_key_pinnacle_grey; + init_data.ir_codes = ir_codes_pinnacle_grey; } break; case SAA7134_BOARD_UPMOST_PURPLE_TV: - snprintf(ir->name, sizeof(ir->name), "Purple TV"); - ir->get_key = get_key_purpletv; - ir->ir_codes = ir_codes_purpletv; + init_data.name = "Purple TV"; + init_data.get_key = get_key_purpletv; + init_data.ir_codes = ir_codes_purpletv; break; case SAA7134_BOARD_MSI_TVATANYWHERE_PLUS: - snprintf(ir->name, sizeof(ir->name), "MSI TV@nywhere Plus"); - ir->get_key = get_key_msi_tvanywhere_plus; - ir->ir_codes = ir_codes_msi_tvanywhere_plus; + init_data.name = "MSI TV@nywhere Plus"; + init_data.get_key = get_key_msi_tvanywhere_plus; + init_data.ir_codes = ir_codes_msi_tvanywhere_plus; break; case SAA7134_BOARD_HAUPPAUGE_HVR1110: - snprintf(ir->name, sizeof(ir->name), "HVR 1110"); - ir->get_key = get_key_hvr1110; - ir->ir_codes = ir_codes_hauppauge_new; + init_data.name = "HVR 1110"; + init_data.get_key = get_key_hvr1110; + init_data.ir_codes = ir_codes_hauppauge_new; break; case SAA7134_BOARD_BEHOLD_607FM_MK3: case SAA7134_BOARD_BEHOLD_607FM_MK5: @@ -791,15 +765,39 @@ void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir) case SAA7134_BOARD_BEHOLD_M63: case SAA7134_BOARD_BEHOLD_M6_EXTRA: case SAA7134_BOARD_BEHOLD_H6: - snprintf(ir->name, sizeof(ir->name), "BeholdTV"); - ir->get_key = get_key_beholdm6xx; - ir->ir_codes = ir_codes_behold; - break; - default: - dprintk("Shouldn't get here: Unknown board %x for I2C IR?\n",dev->board); + init_data.name = "BeholdTV"; + init_data.get_key = get_key_beholdm6xx; + init_data.ir_codes = ir_codes_behold; break; } + if (init_data.name) + info.platform_data = &init_data; + client = i2c_new_probed_device(&dev->i2c_adap, &info, addr_list); + if (client) + return; + + /* MSI TV@nywhere Plus controller doesn't seem to + respond to probes unless we read something from + an existing device. Weird... */ + rc = i2c_transfer(&dev->i2c_adap, &msg_msi, 1); + dprintk(KERN_DEBUG "probe 0x%02x @ %s: %s\n", + msg_msi.addr, dev->i2c_adap.name, + (1 == rc) ? "yes" : "no"); + client = i2c_new_probed_device(&dev->i2c_adap, &info, addr_list_msi); + if (client) + return; + + /* Special case for AVerMedia Cardbus remote */ + subaddr = 0x0d; + rc = i2c_transfer(&dev->i2c_adap, msg_avermedia, 2); + dprintk(KERN_DEBUG "probe 0x%02x/0x%02x @ %s: %s\n", + msg_avermedia[0].addr, subaddr, dev->i2c_adap.name, + (2 == rc) ? "yes" : "no"); + if (2 == rc) { + info.addr = msg_avermedia[0].addr; + i2c_new_device(&dev->i2c_adap, &info); + } } static int saa7134_rc5_irq(struct saa7134_dev *dev) diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index 116534ec33eb..ae7602d343c1 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h @@ -800,7 +800,6 @@ int saa7134_input_init1(struct saa7134_dev *dev); void saa7134_input_fini(struct saa7134_dev *dev); void saa7134_input_irq(struct saa7134_dev *dev); void saa7134_probe_i2c_ir(struct saa7134_dev *dev); -void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir); void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir); void saa7134_ir_stop(struct saa7134_dev *dev); diff --git a/include/media/ir-kbd-i2c.h b/include/media/ir-kbd-i2c.h index 94a77b15a30a..3ad4ed5402fb 100644 --- a/include/media/ir-kbd-i2c.h +++ b/include/media/ir-kbd-i2c.h @@ -19,4 +19,11 @@ struct IR_i2c { char phys[32]; int (*get_key)(struct IR_i2c*, u32*, u32*); }; + +/* Can be passed when instantiating an ir_video i2c device */ +struct IR_i2c_init_data { + IR_KEYTAB_TYPE *ir_codes; + const char *name; + int (*get_key)(struct IR_i2c*, u32*, u32*); +}; #endif -- cgit v1.2.3