Am 04.01.2013 22:12, schrieb Mauro Carvalho Chehab: > Em Fri, 28 Dec 2012 00:02:45 +0100 > Frank Schäfer <fschaefer.oss@xxxxxxxxxxxxxx> escreveu: > >> Tested with device "Terratec Cinergy 200 USB". > Sorry, but this patch is completely wrong ;) Completely wrong ? That's not helpful... Please elaborate a bit more on this so that I can do things right next time. ;) Regards, Frank > The fix here is simple: just move the initialization to happen > earlier. > > I'm posting it right now, together with a bunch of other fixes for > I2C-based IR devices. > > Regards, > Mauro >> Signed-off-by: Frank Schäfer <fschaefer.oss@xxxxxxxxxxxxxx> >> --- >> drivers/media/usb/em28xx/em28xx-cards.c | 9 +- >> drivers/media/usb/em28xx/em28xx-i2c.c | 1 + >> drivers/media/usb/em28xx/em28xx-input.c | 142 +++++++++++++++++-------------- >> 3 Dateien geändert, 83 Zeilen hinzugefügt(+), 69 Zeilen entfernt(-) >> >> diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c >> index 40c3e45..3b226b1 100644 >> --- a/drivers/media/usb/em28xx/em28xx-cards.c >> +++ b/drivers/media/usb/em28xx/em28xx-cards.c >> @@ -488,6 +488,7 @@ struct em28xx_board em28xx_boards[] = { >> .name = "Terratec Cinergy 250 USB", >> .tuner_type = TUNER_LG_PAL_NEW_TAPC, >> .has_ir_i2c = 1, >> + .ir_codes = RC_MAP_EM_TERRATEC, >> .tda9887_conf = TDA9887_PRESENT, >> .decoder = EM28XX_SAA711X, >> .input = { { >> @@ -508,6 +509,7 @@ struct em28xx_board em28xx_boards[] = { >> .name = "Pinnacle PCTV USB 2", >> .tuner_type = TUNER_LG_PAL_NEW_TAPC, >> .has_ir_i2c = 1, >> + .ir_codes = RC_MAP_PINNACLE_GREY, >> .tda9887_conf = TDA9887_PRESENT, >> .decoder = EM28XX_SAA711X, >> .input = { { >> @@ -533,6 +535,7 @@ struct em28xx_board em28xx_boards[] = { >> .decoder = EM28XX_TVP5150, >> .has_msp34xx = 1, >> .has_ir_i2c = 1, >> + .ir_codes = RC_MAP_HAUPPAUGE, >> .input = { { >> .type = EM28XX_VMUX_TELEVISION, >> .vmux = TVP5150_COMPOSITE0, >> @@ -629,6 +632,7 @@ struct em28xx_board em28xx_boards[] = { >> .valid = EM28XX_BOARD_NOT_VALIDATED, >> .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, >> .has_ir_i2c = 1, >> + .ir_codes = RC_MAP_WINFAST_USBII_DELUXE, >> .tvaudio_addr = 0x58, >> .tda9887_conf = TDA9887_PRESENT | >> TDA9887_PORT2_ACTIVE | >> @@ -1222,6 +1226,7 @@ struct em28xx_board em28xx_boards[] = { >> .name = "Terratec Cinergy 200 USB", >> .is_em2800 = 1, >> .has_ir_i2c = 1, >> + .ir_codes = RC_MAP_EM_TERRATEC, >> .tuner_type = TUNER_LG_TALN, >> .tda9887_conf = TDA9887_PRESENT, >> .decoder = EM28XX_SAA711X, >> @@ -2912,7 +2917,7 @@ static void request_module_async(struct work_struct *work) >> >> if (dev->board.has_dvb) >> request_module("em28xx-dvb"); >> - if (dev->board.ir_codes && !disable_ir) >> + if ((dev->board.ir_codes || dev->board.has_ir_i2c) && !disable_ir) >> request_module("em28xx-rc"); >> #endif /* CONFIG_MODULES */ >> } >> @@ -2935,8 +2940,6 @@ static void flush_request_modules(struct em28xx *dev) >> */ >> void em28xx_release_resources(struct em28xx *dev) >> { >> - /*FIXME: I2C IR should be disconnected */ >> - >> em28xx_release_analog_resources(dev); >> >> em28xx_i2c_unregister(dev); >> diff --git a/drivers/media/usb/em28xx/em28xx-i2c.c b/drivers/media/usb/em28xx/em28xx-i2c.c >> index 44533e4..39c5a3e 100644 >> --- a/drivers/media/usb/em28xx/em28xx-i2c.c >> +++ b/drivers/media/usb/em28xx/em28xx-i2c.c >> @@ -470,6 +470,7 @@ static struct i2c_client em28xx_client_template = { >> static char *i2c_devs[128] = { >> [0x4a >> 1] = "saa7113h", >> [0x52 >> 1] = "drxk", >> + [0x3e >> 1] = "remote IR sensor", >> [0x60 >> 1] = "remote IR sensor", >> [0x8e >> 1] = "remote IR sensor", >> [0x86 >> 1] = "tda9887", >> diff --git a/drivers/media/usb/em28xx/em28xx-input.c b/drivers/media/usb/em28xx/em28xx-input.c >> index 3598221..631e252 100644 >> --- a/drivers/media/usb/em28xx/em28xx-input.c >> +++ b/drivers/media/usb/em28xx/em28xx-input.c >> @@ -5,6 +5,7 @@ >> Markus Rechberger <mrechberger@xxxxxxxxx> >> Mauro Carvalho Chehab <mchehab@xxxxxxxxxxxxx> >> Sascha Sommer <saschasommer@xxxxxxxxxx> >> + Copyright (C) 2012 Frank Schäfer <fschaefer.oss@xxxxxxxxxxxxxx> >> >> This program is free software; you can redistribute it and/or modify >> it under the terms of the GNU General Public License as published by >> @@ -34,6 +35,8 @@ >> #define EM28XX_SBUTTON_QUERY_INTERVAL 500 >> #define EM28XX_R0C_USBSUSP_SNAPSHOT 0x20 >> >> +#define EM28XX_RC_QUERY_INTERVAL 100 >> + >> static unsigned int ir_debug; >> module_param(ir_debug, int, 0644); >> MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]"); >> @@ -67,13 +70,14 @@ struct em28xx_IR { >> char name[32]; >> char phys[32]; >> >> - /* poll external decoder */ >> int polling; >> struct delayed_work work; >> unsigned int full_code:1; >> unsigned int last_readcount; >> u64 rc_type; >> >> + struct i2c_client *i2c_dev; /* external i2c IR receiver/decoder */ >> + >> int (*get_key)(struct em28xx_IR *, struct em28xx_ir_poll_result *); >> }; >> >> @@ -452,7 +456,7 @@ static int em28xx_ir_change_protocol(struct rc_dev *rc_dev, u64 *rc_type) >> } >> } >> >> -static void em28xx_register_i2c_ir(struct em28xx *dev) >> +static int em28xx_register_i2c_ir(struct em28xx *dev, struct rc_dev *rc_dev) >> { >> /* Leadtek winfast tv USBII deluxe can find a non working IR-device */ >> /* at address 0x18, so if that address is needed for another board in */ >> @@ -470,30 +474,46 @@ static void em28xx_register_i2c_ir(struct em28xx *dev) >> switch (dev->model) { >> case EM2800_BOARD_TERRATEC_CINERGY_200: >> case EM2820_BOARD_TERRATEC_CINERGY_250: >> - dev->init_data.ir_codes = RC_MAP_EM_TERRATEC; >> - dev->init_data.get_key = em28xx_get_key_terratec; >> dev->init_data.name = "i2c IR (EM28XX Terratec)"; >> + dev->init_data.type = RC_BIT_OTHER; >> + dev->init_data.get_key = em28xx_get_key_terratec; >> break; >> case EM2820_BOARD_PINNACLE_USB_2: >> - dev->init_data.ir_codes = RC_MAP_PINNACLE_GREY; >> - dev->init_data.get_key = em28xx_get_key_pinnacle_usb_grey; >> dev->init_data.name = "i2c IR (EM28XX Pinnacle PCTV)"; >> + dev->init_data.type = RC_BIT_OTHER; >> + dev->init_data.get_key = em28xx_get_key_pinnacle_usb_grey; >> break; >> case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2: >> - dev->init_data.ir_codes = RC_MAP_HAUPPAUGE; >> - dev->init_data.get_key = em28xx_get_key_em_haup; >> dev->init_data.name = "i2c IR (EM2840 Hauppauge)"; >> + dev->init_data.type = RC_BIT_RC5; >> + dev->init_data.get_key = em28xx_get_key_em_haup; >> break; >> case EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE: >> - dev->init_data.ir_codes = RC_MAP_WINFAST_USBII_DELUXE; >> - dev->init_data.get_key = em28xx_get_key_winfast_usbii_deluxe; >> dev->init_data.name = "i2c IR (EM2820 Winfast TV USBII Deluxe)"; >> + dev->init_data.type = RC_BIT_OTHER; >> + dev->init_data.get_key = em28xx_get_key_winfast_usbii_deluxe; >> break; >> } >> >> - if (dev->init_data.name) >> + if (dev->init_data.name && dev->board.ir_codes) { >> + dev->init_data.ir_codes = dev->board.ir_codes; >> + dev->init_data.polling_interval = EM28XX_RC_QUERY_INTERVAL; >> + dev->init_data.rc_dev = rc_dev; >> info.platform_data = &dev->init_data; >> - i2c_new_probed_device(&dev->i2c_adap, &info, addr_list, NULL); >> + } else { >> + em28xx_warn("Unknown i2c remote control device.\n"); >> + em28xx_warn("If the remote control doesn't work properly, please contact <linux-media@xxxxxxxxxxxxxxx>\n"); >> + } >> + >> + dev->ir->i2c_dev = i2c_new_probed_device(&dev->i2c_adap, &info, addr_list, NULL); >> + if (NULL == dev->ir->i2c_dev) >> + return -ENODEV; >> + >> +#if defined(CONFIG_MODULES) && defined(MODULE) >> + request_module("ir-kbd-i2c"); >> +#endif >> + >> + return 0; >> } >> >> /********************************************************** >> @@ -590,7 +610,7 @@ static int em28xx_ir_init(struct em28xx *dev) >> int err = -ENOMEM; >> u64 rc_type; >> >> - if (dev->board.ir_codes == NULL) { >> + if (dev->board.ir_codes == NULL && !dev->board.has_ir_i2c) { >> /* No remote control support */ >> em28xx_warn("Remote control support is not available for " >> "this card.\n"); >> @@ -607,68 +627,56 @@ static int em28xx_ir_init(struct em28xx *dev) >> dev->ir = ir; >> ir->rc = rc; >> >> - /* >> - * em2874 supports more protocols. For now, let's just announce >> - * the two protocols that were already tested >> - */ >> - rc->allowed_protos = RC_BIT_RC5 | RC_BIT_NEC; >> - rc->priv = ir; >> - rc->change_protocol = em28xx_ir_change_protocol; >> - rc->open = em28xx_ir_start; >> - rc->close = em28xx_ir_stop; >> - >> - switch (dev->chip_id) { >> - case CHIP_ID_EM2860: >> - case CHIP_ID_EM2883: >> - rc->allowed_protos = RC_BIT_RC5 | RC_BIT_NEC; >> - break; >> - case CHIP_ID_EM2884: >> - case CHIP_ID_EM2874: >> - case CHIP_ID_EM28174: >> - rc->allowed_protos = RC_BIT_RC5 | RC_BIT_NEC | RC_BIT_RC6_0; >> - break; >> - default: >> - err = -ENODEV; >> - goto error; >> - } >> - >> - /* By default, keep protocol field untouched */ >> - rc_type = RC_BIT_UNKNOWN; >> - err = em28xx_ir_change_protocol(rc, &rc_type); >> - if (err) >> - goto error; >> - >> - /* This is how often we ask the chip for IR information */ >> - ir->polling = 100; /* ms */ >> - >> - /* init input device */ >> - snprintf(ir->name, sizeof(ir->name), "em28xx IR (%s)", >> - dev->name); >> - >> + snprintf(ir->name, sizeof(ir->name), "em28xx IR (%s)", dev->name); >> usb_make_path(dev->udev, ir->phys, sizeof(ir->phys)); >> strlcat(ir->phys, "/input0", sizeof(ir->phys)); >> + ir->polling = EM28XX_RC_QUERY_INTERVAL; >> >> - rc->input_name = ir->name; >> - rc->input_phys = ir->phys; >> - rc->input_id.bustype = BUS_USB; >> rc->input_id.version = 1; >> rc->input_id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor); >> rc->input_id.product = le16_to_cpu(dev->udev->descriptor.idProduct); >> rc->dev.parent = &dev->udev->dev; >> - rc->map_name = dev->board.ir_codes; >> rc->driver_name = MODULE_NAME; >> >> - /* all done */ >> - err = rc_register_device(rc); >> - if (err) >> - goto error; >> - >> - em28xx_register_i2c_ir(dev); >> + if (dev->board.has_ir_i2c) { >> + err = em28xx_register_i2c_ir(dev, rc); >> + if (err < 0) >> + goto error; >> + } else { >> + switch (dev->chip_id) { >> + case CHIP_ID_EM2860: >> + case CHIP_ID_EM2883: >> + rc->allowed_protos = RC_BIT_RC5 | RC_BIT_NEC; >> + break; >> + case CHIP_ID_EM2884: >> + case CHIP_ID_EM2874: >> + case CHIP_ID_EM28174: >> + rc->allowed_protos = RC_BIT_RC5 | RC_BIT_NEC | RC_BIT_RC6_0; >> + break; >> + default: >> + err = -ENODEV; >> + goto error; >> + } >> + rc->priv = ir; >> + rc->change_protocol = em28xx_ir_change_protocol; >> + rc->open = em28xx_ir_start; >> + rc->close = em28xx_ir_stop; >> + rc->input_name = ir->name; >> + rc->input_phys = ir->phys; >> + rc->input_id.bustype = BUS_USB; >> + rc->map_name = dev->board.ir_codes; >> + >> + /* By default, keep protocol field untouched */ >> + rc_type = RC_BIT_UNKNOWN; >> + err = em28xx_ir_change_protocol(rc, &rc_type); >> + if (err) >> + goto error; >> + >> + err = rc_register_device(rc); >> + if (err < 0) >> + goto error; >> + } >> >> -#if defined(CONFIG_MODULES) && defined(MODULE) >> - if (dev->board.has_ir_i2c) >> - request_module("ir-kbd-i2c"); >> -#endif >> if (dev->board.has_snapshot_button) >> em28xx_register_snapshot_button(dev); >> >> @@ -691,7 +699,9 @@ static int em28xx_ir_fini(struct em28xx *dev) >> if (!ir) >> return 0; >> >> - if (ir->rc) >> + if (ir->i2c_dev) >> + i2c_unregister_device(ir->i2c_dev); >> + else if (ir->rc) >> rc_unregister_device(ir->rc); >> >> /* done */ -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html