Am 04.01.2013 22:12, schrieb Mauro Carvalho Chehab:
> Em Fri, 28 Dec 2012 00:02:45 +0100
> Frank Schäfer <fschaefer....@googlemail.com> 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....@googlemail.com>
>> ---
>>  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 <mrechber...@gmail.com>
>>                    Mauro Carvalho Chehab <mche...@infradead.org>
>>                    Sascha Sommer <saschasom...@freenet.de>
>> +   Copyright (C) 2012 Frank Schäfer <fschaefer....@googlemail.com>
>>  
>>    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@vger.kernel.org>\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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to