V4L/DVB (9629): Add support for the ATI TV Wonder HD 600 USB Remote Control
[safe/jmp/linux-2.6] / drivers / media / video / em28xx / em28xx-cards.c
index 9038927..75b2af2 100644 (file)
@@ -592,6 +592,7 @@ struct em28xx_board em28xx_boards[] = {
                .mts_firmware   = 1,
                .has_12mhz_i2s  = 1,
                .has_dvb        = 1,
+               .ir_codes       = ir_codes_hauppauge_new,
                .decoder        = EM28XX_TVP5150,
                .input          = { {
                        .type     = EM28XX_VMUX_TELEVISION,
@@ -615,6 +616,7 @@ struct em28xx_board em28xx_boards[] = {
                .mts_firmware   = 1,
                .has_12mhz_i2s  = 1,
                .has_dvb        = 1,
+               .ir_codes       = ir_codes_pinnacle_pctv_hd,
                .decoder        = EM28XX_TVP5150,
                .input          = { {
                        .type     = EM28XX_VMUX_TELEVISION,
@@ -638,6 +640,7 @@ struct em28xx_board em28xx_boards[] = {
                .mts_firmware   = 1,
                .has_12mhz_i2s  = 1,
                .has_dvb        = 1,
+               .ir_codes       = ir_codes_ati_tv_wonder_hd_600,
                .decoder        = EM28XX_TVP5150,
                .input          = { {
                        .type     = EM28XX_VMUX_TELEVISION,
@@ -1087,6 +1090,21 @@ struct em28xx_board em28xx_boards[] = {
                        .amux     = EM28XX_AMUX_LINE_IN,
                } },
        },
+       [EM2874_BOARD_PINNACLE_PCTV_80E] = {
+               .name         = "Pinnacle PCTV HD Mini",
+               .vchannels    = 0,
+               .tuner_type   = TUNER_ABSENT,
+               .has_dvb        = 1,
+               .ir_codes       = ir_codes_pinnacle_pctv_hd,
+               .decoder      = EM28XX_NODECODER,
+#ifdef DJH_DEBUG
+               .input          = { {
+                       .type     = EM28XX_VMUX_TELEVISION,
+                       .vmux     = TVP5150_COMPOSITE0,
+                       .amux     = EM28XX_AMUX_LINE_IN,
+               } },
+#endif
+       },
 };
 const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
 
@@ -1180,6 +1198,8 @@ struct usb_device_id em28xx_id_table [] = {
                        .driver_info = EM2882_BOARD_PINNACLE_HYBRID_PRO },
        { USB_DEVICE(0x2304, 0x0227),
                        .driver_info = EM2880_BOARD_PINNACLE_PCTV_HD_PRO },
+       { USB_DEVICE(0x2304, 0x023f),
+                       .driver_info = EM2874_BOARD_PINNACLE_PCTV_80E },
        { USB_DEVICE(0x0413, 0x6023),
                        .driver_info = EM2800_BOARD_LEADTEK_WINFAST_USBII },
        { USB_DEVICE(0x093b, 0xa005),
@@ -1255,6 +1275,17 @@ static struct em28xx_reg_seq em2882_terratec_hybrid_xs_digital[] = {
        {  -1,                  -1,     -1,               -1},
 };
 
+/* Pinnacle PCTV HD Mini (80e) GPIOs
+   0-5: not used
+   6:   demod reset, active low
+   7:   LED on, active high */
+static struct em28xx_reg_seq em2874_pinnacle_80e_digital[] = {
+       {EM28XX_R06_I2C_CLK,    0x45,   0xff,             10}, /*400 KHz*/
+       {EM2874_R80_GPIO,       0x80,   0xff,             100},/*Demod reset*/
+       {EM2874_R80_GPIO,       0xc0,   0xff,             10},
+       {  -1,                  -1,     -1,               -1},
+};
+
 /*
  * EEPROM hash table for devices with generic USB IDs
  */
@@ -1302,6 +1333,7 @@ static void em28xx_set_model(struct em28xx *dev)
        dev->max_range_640_480 = em28xx_boards[dev->model].max_range_640_480;
        dev->has_dvb = em28xx_boards[dev->model].has_dvb;
        dev->has_snapshot_button = em28xx_boards[dev->model].has_snapshot_button;
+       dev->ir_codes = em28xx_boards[dev->model].ir_codes;
        dev->valid = em28xx_boards[dev->model].valid;
 }
 
@@ -1312,11 +1344,13 @@ void em28xx_pre_card_setup(struct em28xx *dev)
 {
        int rc;
 
-       rc = em28xx_read_reg(dev, EM2880_R04_GPO);
-       if (rc >= 0)
-               dev->reg_gpo = rc;
+       /* Set the default GPO/GPIO for legacy devices */
+       dev->reg_gpo_num = EM2880_R04_GPO;
+       dev->reg_gpio_num = EM28XX_R08_GPIO;
 
        dev->wait_after_write = 5;
+
+       /* Based on the Chip ID, set the device configuration */
        rc = em28xx_read_reg(dev, EM28XX_R0A_CHIPID);
        if (rc > 0) {
                dev->chip_id = rc;
@@ -1326,6 +1360,7 @@ void em28xx_pre_card_setup(struct em28xx *dev)
                        break;
                case CHIP_ID_EM2874:
                        em28xx_info("chip ID is em2874\n");
+                       dev->reg_gpio_num = EM2874_R80_GPIO;
                        dev->wait_after_write = 0;
                        break;
                case CHIP_ID_EM2883:
@@ -1336,6 +1371,12 @@ void em28xx_pre_card_setup(struct em28xx *dev)
                        em28xx_info("em28xx chip ID = %d\n", rc);
                }
        }
+
+       /* Prepopulate cached GPO register content */
+       rc = em28xx_read_reg(dev, dev->reg_gpo_num);
+       if (rc >= 0)
+               dev->reg_gpo = rc;
+
        em28xx_set_model(dev);
 
        /* request some modules */
@@ -1509,6 +1550,13 @@ void em28xx_pre_card_setup(struct em28xx *dev)
                /* enables audio for that device */
                em28xx_write_regs_req(dev, 0x00, 0x08, "\xfd", 1);
                break;
+
+       case EM2874_BOARD_PINNACLE_PCTV_80E:
+               /* Set 400 KHz clock */
+               em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x45", 1);
+
+               dev->digital_gpio = em2874_pinnacle_80e_digital;
+               break;
        }
 
        em28xx_gpio_set(dev, dev->tun_analog_gpio);
@@ -1800,4 +1848,6 @@ void em28xx_card_setup(struct em28xx *dev)
 #endif
 
        em28xx_config_tuner(dev);
+
+       em28xx_ir_init(dev);
 }