]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/media/video/cx231xx/cx231xx-cards.c
Merge tag 'v2.6.38' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[mv-sheeva.git] / drivers / media / video / cx231xx / cx231xx-cards.c
index 2c78d188bb0650dcd9c33b5a5495cf568c49043a..588f3e8f028b28c04db0c381abfaf62421a9b2ec 100644 (file)
@@ -34,6 +34,7 @@
 #include <media/cx25840.h>
 #include "dvb-usb-ids.h"
 #include "xc5000.h"
+#include "tda18271.h"
 
 #include "cx231xx.h"
 
@@ -395,6 +396,45 @@ struct cx231xx_board cx231xx_boards[] = {
                        .gpio = 0,
                } },
        },
+       [CX231XX_BOARD_PV_PLAYTV_USB_HYBRID] = {
+               .name = "Pixelview PlayTV USB Hybrid",
+               .tuner_type = TUNER_NXP_TDA18271,
+               .tuner_addr = 0x60,
+               .decoder = CX231XX_AVDECODER,
+               .output_mode = OUT_MODE_VIP11,
+               .demod_xfer_mode = 0,
+               .ctl_pin_status_mask = 0xFFFFFFC4,
+               .agc_analog_digital_select_gpio = 0x00, /* According with PV cxPolaris.inf file */
+               .tuner_sif_gpio = -1,
+               .tuner_scl_gpio = -1,
+               .tuner_sda_gpio = -1,
+               .gpio_pin_status_mask = 0x4001000,
+               .tuner_i2c_master = 2,
+               .demod_i2c_master = 1,
+               .ir_i2c_master = 2,
+               .rc_map_name = RC_MAP_PIXELVIEW_002T,
+               .has_dvb = 1,
+               .demod_addr = 0x10,
+               .norm = V4L2_STD_PAL_M,
+               .input = {{
+                       .type = CX231XX_VMUX_TELEVISION,
+                       .vmux = CX231XX_VIN_3_1,
+                       .amux = CX231XX_AMUX_VIDEO,
+                       .gpio = 0,
+               }, {
+                       .type = CX231XX_VMUX_COMPOSITE1,
+                       .vmux = CX231XX_VIN_2_1,
+                       .amux = CX231XX_AMUX_LINE_IN,
+                       .gpio = 0,
+               }, {
+                       .type = CX231XX_VMUX_SVIDEO,
+                       .vmux = CX231XX_VIN_1_1 |
+                               (CX231XX_VIN_1_2 << 8) |
+                               CX25840_SVIDEO_ON,
+                       .amux = CX231XX_AMUX_LINE_IN,
+                       .gpio = 0,
+               } },
+       },
 };
 const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards);
 
@@ -402,8 +442,6 @@ const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards);
 struct usb_device_id cx231xx_id_table[] = {
        {USB_DEVICE(0x0572, 0x5A3C),
         .driver_info = CX231XX_BOARD_UNKNOWN},
-       {USB_DEVICE_VER(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD, 0x4000,0x4fff),
-        .driver_info = CX231XX_BOARD_UNKNOWN},
        {USB_DEVICE(0x0572, 0x58A2),
         .driver_info = CX231XX_BOARD_CNXT_CARRAERA},
        {USB_DEVICE(0x0572, 0x58A1),
@@ -424,6 +462,8 @@ struct usb_device_id cx231xx_id_table[] = {
         .driver_info = CX231XX_BOARD_HAUPPAUGE_EXETER},
        {USB_DEVICE(0x2040, 0xc200),
         .driver_info = CX231XX_BOARD_HAUPPAUGE_USBLIVE2},
+       {USB_DEVICE_VER(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD, 0x4000, 0x4001),
+        .driver_info = CX231XX_BOARD_PV_PLAYTV_USB_HYBRID},
        {},
 };
 
@@ -453,6 +493,16 @@ int cx231xx_tuner_callback(void *ptr, int component, int command, int arg)
                                               1);
                        msleep(10);
                }
+       } else if (dev->tuner_type == TUNER_NXP_TDA18271) {
+               switch (command) {
+               case TDA18271_CALLBACK_CMD_AGC_ENABLE:
+                       if (dev->model == CX231XX_BOARD_PV_PLAYTV_USB_HYBRID)
+                               rc = cx231xx_set_agc_analog_digital_mux_select(dev, arg);
+                       break;
+               default:
+                       rc = -EINVAL;
+                       break;
+               }
        }
        return rc;
 }
@@ -615,8 +665,11 @@ void cx231xx_release_resources(struct cx231xx *dev)
 
        cx231xx_remove_from_devlist(dev);
 
+       /* Release I2C buses */
        cx231xx_dev_uninit(dev);
 
+       cx231xx_ir_exit(dev);
+
        usb_put_dev(dev->udev);
 
        /* Mark device as unused */
@@ -731,16 +784,14 @@ static int cx231xx_init_dev(struct cx231xx **devhandle, struct usb_device *udev,
        retval = cx231xx_register_analog_devices(dev);
        if (retval < 0) {
                cx231xx_release_resources(dev);
-               goto fail_reg_devices;
+               return retval;
        }
 
+       cx231xx_ir_init(dev);
+
        cx231xx_init_extension(dev);
 
        return 0;
-
-fail_reg_devices:
-       mutex_unlock(&dev->lock);
-       return retval;
 }
 
 #if defined(CONFIG_MODULES) && defined(MODULE)
@@ -762,8 +813,14 @@ static void request_modules(struct cx231xx *dev)
        INIT_WORK(&dev->request_module_wk, request_module_async);
        schedule_work(&dev->request_module_wk);
 }
+
+static void flush_request_modules(struct cx231xx *dev)
+{
+       flush_work_sync(&dev->request_module_wk);
+}
 #else
 #define request_modules(dev)
+#define flush_request_modules(dev)
 #endif /* CONFIG_MODULES */
 
 /*
@@ -1096,6 +1153,8 @@ static void cx231xx_usb_disconnect(struct usb_interface *interface)
        if (!dev->udev)
                return;
 
+       flush_request_modules(dev);
+
        /* delete v4l2 device */
        v4l2_device_unregister(&dev->v4l2_dev);