[media] cx231xx: Add digital support for HVR 930c-HD model 1113xx
authorMatthias Schwarzott <zzam@gentoo.org>
Tue, 22 Jul 2014 20:12:15 +0000 (17:12 -0300)
committerMauro Carvalho Chehab <m.chehab@samsung.com>
Sun, 27 Jul 2014 20:02:48 +0000 (17:02 -0300)
Add support for:
[2040:b130] Hauppauge WinTV 930C-HD (model 1113xx)

After loading the driver the first open to dvb device node fails.

Signed-off-by: Matthias Schwarzott <zzam@gentoo.org>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
drivers/media/usb/cx231xx/Kconfig
drivers/media/usb/cx231xx/cx231xx-avcore.c
drivers/media/usb/cx231xx/cx231xx-cards.c
drivers/media/usb/cx231xx/cx231xx-core.c
drivers/media/usb/cx231xx/cx231xx-dvb.c
drivers/media/usb/cx231xx/cx231xx.h

index f14c5e89a567b5875c0572590843a052978eeaa9..036454ede5c0cbdb96d3ccb13bb36abdf2cd77e6 100644 (file)
@@ -47,6 +47,7 @@ config VIDEO_CX231XX_DVB
        select DVB_MB86A20S if MEDIA_SUBDRV_AUTOSELECT
        select DVB_LGDT3305 if MEDIA_SUBDRV_AUTOSELECT
        select DVB_TDA18271C2DD if MEDIA_SUBDRV_AUTOSELECT
+       select DVB_SI2165 if MEDIA_SUBDRV_AUTOSELECT
 
        ---help---
          This adds support for DVB cards based on the
index 89de00bf4f8201f2b187892c42ff7ade070f531c..a428c10e1a1657dbcb1f767c90993f66fcba1ea4 100644 (file)
@@ -352,6 +352,7 @@ int cx231xx_afe_update_power_control(struct cx231xx *dev,
        case CX231XX_BOARD_CNXT_RDU_253S:
        case CX231XX_BOARD_CNXT_VIDEO_GRABBER:
        case CX231XX_BOARD_HAUPPAUGE_EXETER:
+       case CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx:
        case CX231XX_BOARD_HAUPPAUGE_USBLIVE2:
        case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID:
        case CX231XX_BOARD_HAUPPAUGE_USB2_FM_PAL:
index db69307d86aed002ab2bed6078530f23e078c459..5dd185e629cdac225ec428a14741b9fc63348197 100644 (file)
@@ -704,6 +704,45 @@ struct cx231xx_board cx231xx_boards[] = {
                        }
                },
        },
+       [CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx] = {
+               .name = "Hauppauge WinTV 930C-HD (1113xx)",
+               .tuner_type = TUNER_NXP_TDA18271,
+               .tuner_addr = 0x60,
+               .tuner_gpio = RDE250_XCV_TUNER,
+               .tuner_sif_gpio = 0x05,
+               .tuner_scl_gpio = 0x1a,
+               .tuner_sda_gpio = 0x1b,
+               .decoder = CX231XX_AVDECODER,
+               .output_mode = OUT_MODE_VIP11,
+               .demod_xfer_mode = 0,
+               .ctl_pin_status_mask = 0xFFFFFFC4,
+               .agc_analog_digital_select_gpio = 0x0c,
+               .gpio_pin_status_mask = 0x4001000,
+               .tuner_i2c_master = 1,
+               .demod_i2c_master = 2,
+               .has_dvb = 1,
+               .demod_addr = 0x0e,
+               .norm = V4L2_STD_PAL,
+
+               .input = {{
+                       .type = CX231XX_VMUX_TELEVISION,
+                       .vmux = CX231XX_VIN_3_1,
+                       .amux = CX231XX_AMUX_VIDEO,
+                       .gpio = NULL,
+               }, {
+                       .type = CX231XX_VMUX_COMPOSITE1,
+                       .vmux = CX231XX_VIN_2_1,
+                       .amux = CX231XX_AMUX_LINE_IN,
+                       .gpio = NULL,
+               }, {
+                       .type = CX231XX_VMUX_SVIDEO,
+                       .vmux = CX231XX_VIN_1_1 |
+                               (CX231XX_VIN_1_2 << 8) |
+                               CX25840_SVIDEO_ON,
+                       .amux = CX231XX_AMUX_LINE_IN,
+                       .gpio = NULL,
+               } },
+       },
 };
 const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards);
 
@@ -733,6 +772,8 @@ struct usb_device_id cx231xx_id_table[] = {
         .driver_info = CX231XX_BOARD_HAUPPAUGE_USB2_FM_NTSC},
        {USB_DEVICE(0x2040, 0xb120),
         .driver_info = CX231XX_BOARD_HAUPPAUGE_EXETER},
+       {USB_DEVICE(0x2040, 0xb130),
+        .driver_info = CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx},
        {USB_DEVICE(0x2040, 0xb140),
         .driver_info = CX231XX_BOARD_HAUPPAUGE_EXETER},
        {USB_DEVICE(0x2040, 0xc200),
@@ -886,6 +927,43 @@ static void cx231xx_config_tuner(struct cx231xx *dev)
 
 }
 
+static int read_eeprom(struct cx231xx *dev, u8 *eedata, int len)
+{
+       int ret = 0;
+       u8 addr = 0xa0 >> 1;
+       u8 start_offset = 0;
+       int len_todo = len;
+       u8 *eedata_cur = eedata;
+       int i;
+       struct i2c_msg msg_write = { .addr = addr, .flags = 0,
+               .buf = &start_offset, .len = 1 };
+       struct i2c_msg msg_read = { .addr = addr, .flags = I2C_M_RD };
+
+       /* mutex_lock(&dev->i2c_lock); */
+       cx231xx_enable_i2c_port_3(dev, false);
+
+       /* start reading at offset 0 */
+       ret = i2c_transfer(&dev->i2c_bus[1].i2c_adap, &msg_write, 1);
+
+       while (len_todo > 0) {
+               msg_read.len = (len_todo > 64) ? 64 : len_todo;
+               msg_read.buf = eedata_cur;
+
+               ret = i2c_transfer(&dev->i2c_bus[1].i2c_adap, &msg_read, 1);
+
+               eedata_cur += msg_read.len;
+               len_todo -= msg_read.len;
+       }
+
+       cx231xx_enable_i2c_port_3(dev, true);
+       /* mutex_unlock(&dev->i2c_lock); */
+
+       for (i = 0; i + 15 < len; i += 16)
+               cx231xx_info("i2c eeprom %02x: %*ph\n", i, 16, &eedata[i]);
+
+       return 0;
+}
+
 void cx231xx_card_setup(struct cx231xx *dev)
 {
 
@@ -917,6 +995,20 @@ void cx231xx_card_setup(struct cx231xx *dev)
                else
                        cx231xx_config_tuner(dev);
        }
+
+       switch (dev->model) {
+       case CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx:
+               {
+                       struct tveeprom tvee;
+                       static u8 eeprom[256];
+
+                       read_eeprom(dev, eeprom, sizeof(eeprom));
+                       tveeprom_hauppauge_analog(&dev->i2c_bus[1].i2c_client,
+                                               &tvee, eeprom + 0xc0);
+                       break;
+               }
+       }
+
 }
 
 /*
index 4ba3ce09b71380a18afe731a8db61e8b1bfe9ce4..513194aa6561c76d70f45a7286a6456c52153325 100644 (file)
@@ -726,6 +726,7 @@ int cx231xx_set_mode(struct cx231xx *dev, enum cx231xx_mode set_mode)
                        errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 1);
                        break;
                case CX231XX_BOARD_HAUPPAUGE_EXETER:
+               case CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx:
                        errCode = cx231xx_set_power_mode(dev,
                                                POLARIS_AVMODE_DIGITAL);
                        break;
@@ -744,6 +745,7 @@ int cx231xx_set_mode(struct cx231xx *dev, enum cx231xx_mode set_mode)
                case CX231XX_BOARD_CNXT_RDE_253S:
                case CX231XX_BOARD_CNXT_RDU_253S:
                case CX231XX_BOARD_HAUPPAUGE_EXETER:
+               case CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx:
                case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID:
                case CX231XX_BOARD_HAUPPAUGE_USB2_FM_PAL:
                case CX231XX_BOARD_HAUPPAUGE_USB2_FM_NTSC:
@@ -1379,6 +1381,7 @@ int cx231xx_dev_init(struct cx231xx *dev)
        case CX231XX_BOARD_CNXT_RDE_253S:
        case CX231XX_BOARD_CNXT_RDU_253S:
        case CX231XX_BOARD_HAUPPAUGE_EXETER:
+       case CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx:
        case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID:
        case CX231XX_BOARD_HAUPPAUGE_USB2_FM_PAL:
        case CX231XX_BOARD_HAUPPAUGE_USB2_FM_NTSC:
index 5c69be707a305b2d86dd192bcbbfbb322da17735..4ff6f7f7aa5c58bdef62a1cdf419a0e8416694ec 100644 (file)
@@ -32,6 +32,7 @@
 #include "tda18271.h"
 #include "s5h1411.h"
 #include "lgdt3305.h"
+#include "si2165.h"
 #include "mb86a20s.h"
 
 MODULE_DESCRIPTION("driver for cx231xx based DVB cards");
@@ -152,6 +153,12 @@ static struct tda18271_config pv_tda18271_config = {
        .small_i2c = TDA18271_03_BYTE_CHUNK_INIT,
 };
 
+static const struct si2165_config hauppauge_930C_HD_1113xx_si2165_config = {
+       .i2c_addr       = 0x64,
+       .chip_mode      = SI2165_MODE_PLL_XTAL,
+       .ref_freq_Hz    = 16000000,
+};
+
 static inline void print_err_status(struct cx231xx *dev, int packet, int status)
 {
        char *errmsg = "Unknown";
@@ -712,6 +719,33 @@ static int dvb_init(struct cx231xx *dev)
                           &hcw_tda18271_config);
                break;
 
+       case CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx:
+
+               dev->dvb->frontend = dvb_attach(si2165_attach,
+                       &hauppauge_930C_HD_1113xx_si2165_config,
+                       &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap
+                       );
+
+               if (dev->dvb->frontend == NULL) {
+                       printk(DRIVER_NAME
+                              ": Failed to attach SI2165 front end\n");
+                       result = -EINVAL;
+                       goto out_free;
+               }
+
+               dev->dvb->frontend->ops.i2c_gate_ctrl = 0;
+
+               /* define general-purpose callback pointer */
+               dvb->frontend->callback = cx231xx_tuner_callback;
+
+               dvb_attach(tda18271_attach, dev->dvb->frontend,
+                       0x60,
+                       &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap,
+                       &hcw_tda18271_config);
+
+               dev->cx231xx_reset_analog_tuner = NULL;
+               break;
+
        case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID:
        case CX231XX_BOARD_KWORLD_UB430_USB_HYBRID:
 
index babca7fb85e29ba035c2319b5e3c26d534133b71..a6373ba781ab9b3bfa96a6801f98be63f96fa17f 100644 (file)
@@ -73,6 +73,7 @@
 #define CX231XX_BOARD_ELGATO_VIDEO_CAPTURE_V2 16
 #define CX231XX_BOARD_OTG102 17
 #define CX231XX_BOARD_KWORLD_UB445_USB_HYBRID 18
+#define CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx 19
 
 /* Limits minimum and default number of buffers */
 #define CX231XX_MIN_BUF                 4