vserver 2.0 rc7
[linux-2.6.git] / drivers / media / dvb / dibusb / dvb-dibusb-core.c
index 503ca57..26235f9 100644 (file)
@@ -42,11 +42,16 @@ static int pid_parse;
 module_param(pid_parse, int, 0644);
 MODULE_PARM_DESC(pid_parse, "enable pid parsing (filtering) when running at USB2.0");
 
-static int rc_query_interval;
+static int rc_query_interval = 100;
 module_param(rc_query_interval, int, 0644);
 MODULE_PARM_DESC(rc_query_interval, "interval in msecs for remote control query (default: 100; min: 40)");
 
+static int rc_key_repeat_count = 2;
+module_param(rc_key_repeat_count, int, 0644);
+MODULE_PARM_DESC(rc_key_repeat_count, "how many key repeats will be dropped before passing the key event again (default: 2)");
+
 /* Vendor IDs */
+#define USB_VID_ADSTECH                                                0x06e1
 #define USB_VID_ANCHOR                                         0x0547
 #define USB_VID_AVERMEDIA                                      0x14aa
 #define USB_VID_COMPRO                                         0x185b
@@ -55,13 +60,16 @@ MODULE_PARM_DESC(rc_query_interval, "interval in msecs for remote control query
 #define USB_VID_DIBCOM                                         0x10b8
 #define USB_VID_EMPIA                                          0xeb1a
 #define USB_VID_GRANDTEC                                       0x5032
-#define USB_VID_HYPER_PALTEK                           0x1025
 #define USB_VID_HANFTEK                                                0x15f4
+#define USB_VID_HAUPPAUGE                                      0x2040
+#define USB_VID_HYPER_PALTEK                           0x1025
 #define USB_VID_IMC_NETWORKS                           0x13d3
 #define USB_VID_TWINHAN                                                0x1822
 #define USB_VID_ULTIMA_ELECTRONIC                      0x05d8
 
 /* Product IDs */
+#define USB_PID_ADSTECH_USB2_COLD                      0xa333
+#define USB_PID_ADSTECH_USB2_WARM                      0xa334
 #define USB_PID_AVERMEDIA_DVBT_USB_COLD                0x0001
 #define USB_PID_AVERMEDIA_DVBT_USB_WARM                0x0002
 #define USB_PID_COMPRO_DVBU2000_COLD           0xd000
@@ -90,9 +98,11 @@ MODULE_PARM_DESC(rc_query_interval, "interval in msecs for remote control query
 #define USB_PID_UNK_HYPER_PALTEK_COLD          0x005e
 #define USB_PID_UNK_HYPER_PALTEK_WARM          0x005f
 #define USB_PID_HANFTEK_UMT_010_COLD           0x0001
-#define USB_PID_HANFTEK_UMT_010_WARM           0x0025
+#define USB_PID_HANFTEK_UMT_010_WARM           0x0015
 #define USB_PID_YAKUMO_DTT200U_COLD                    0x0201
 #define USB_PID_YAKUMO_DTT200U_WARM                    0x0301
+#define USB_PID_WINTV_NOVA_T_USB2_COLD         0x9300
+#define USB_PID_WINTV_NOVA_T_USB2_WARM         0x9301
 
 /* USB Driver stuff
  * table of devices that this driver is working with
@@ -109,10 +119,6 @@ static struct usb_device_id dib_table [] = {
 /* 00 */       { USB_DEVICE(USB_VID_AVERMEDIA,         USB_PID_AVERMEDIA_DVBT_USB_COLD)},
 /* 01 */       { USB_DEVICE(USB_VID_AVERMEDIA,         USB_PID_AVERMEDIA_DVBT_USB_WARM)},
 /* 02 */       { USB_DEVICE(USB_VID_AVERMEDIA,         USB_PID_YAKUMO_DTT200U_COLD) },
-
-/* the following device is actually not supported, but when loading the 
- * correct firmware (ie. its usb ids will change) everything works fine then 
- */
 /* 03 */       { USB_DEVICE(USB_VID_AVERMEDIA,         USB_PID_YAKUMO_DTT200U_WARM) },
 
 /* 04 */       { USB_DEVICE(USB_VID_COMPRO,            USB_PID_COMPRO_DVBU2000_COLD) },
@@ -143,16 +149,20 @@ static struct usb_device_id dib_table [] = {
 /* 28 */       { USB_DEVICE(USB_VID_HANFTEK,           USB_PID_HANFTEK_UMT_010_COLD) },
 /* 29 */       { USB_DEVICE(USB_VID_HANFTEK,           USB_PID_HANFTEK_UMT_010_WARM) },
 
+/* 30 */       { USB_DEVICE(USB_VID_HAUPPAUGE,         USB_PID_WINTV_NOVA_T_USB2_COLD) },
+/* 31 */       { USB_DEVICE(USB_VID_HAUPPAUGE,         USB_PID_WINTV_NOVA_T_USB2_WARM) },
+/* 32 */       { USB_DEVICE(USB_VID_ADSTECH,           USB_PID_ADSTECH_USB2_COLD) },
+/* 33 */       { USB_DEVICE(USB_VID_ADSTECH,           USB_PID_ADSTECH_USB2_WARM) },
 /* 
  * activate the following define when you have one of the devices and want to 
  * build it from build-2.6 in dvb-kernel
  */
-// #define CONFIG_DVB_DIBUSB_MISDESIGNED_DEVICES 
+// #define CONFIG_DVB_DIBUSB_MISDESIGNED_DEVICES
 #ifdef CONFIG_DVB_DIBUSB_MISDESIGNED_DEVICES
-/* 30 */       { USB_DEVICE(USB_VID_ANCHOR,            USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) },
-/* 31 */       { USB_DEVICE(USB_VID_CYPRESS,           USB_PID_ULTIMA_TVBOX_USB2_FX_COLD) },
-/* 32 */       { USB_DEVICE(USB_VID_ANCHOR,            USB_PID_ULTIMA_TVBOX_USB2_FX_WARM) },
-/* 33 */       { USB_DEVICE(USB_VID_ANCHOR,            USB_PID_DIBCOM_ANCHOR_2135_COLD) },
+/* 34 */       { USB_DEVICE(USB_VID_ANCHOR,            USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) },
+/* 35 */       { USB_DEVICE(USB_VID_CYPRESS,           USB_PID_ULTIMA_TVBOX_USB2_FX_COLD) },
+/* 36 */       { USB_DEVICE(USB_VID_ANCHOR,            USB_PID_ULTIMA_TVBOX_USB2_FX_WARM) },
+/* 37 */       { USB_DEVICE(USB_VID_ANCHOR,            USB_PID_DIBCOM_ANCHOR_2135_COLD) },
 #endif
                        { }             /* Terminating entry */
 };
@@ -193,13 +203,17 @@ static struct dibusb_demod dibusb_demod[] = {
          254,
          { 0xf, 0 }, 
        },
+       { DTT200U_FE,
+         8,
+         { 0xff,0 }, /* there is no i2c bus in this device */
+       }
 };
 
 static struct dibusb_device_class dibusb_device_classes[] = {
        { .id = DIBUSB1_1, .usb_ctrl = &dibusb_usb_ctrl[0],
          .firmware = "dvb-dibusb-5.0.0.11.fw",
          .pipe_cmd = 0x01, .pipe_data = 0x02, 
-         .urb_count = 3, .urb_buffer_size = 4096,
+         .urb_count = 7, .urb_buffer_size = 4096,
          DIBUSB_RC_NEC_PROTOCOL,
          &dibusb_demod[DIBUSB_DIB3000MB],
          &dibusb_tuner[DIBUSB_TUNER_CABLE_THOMSON],
@@ -207,7 +221,7 @@ static struct dibusb_device_class dibusb_device_classes[] = {
        { DIBUSB1_1_AN2235, &dibusb_usb_ctrl[1],
          "dvb-dibusb-an2235-1.fw",
          0x01, 0x02, 
-         3, 4096,
+         7, 4096,
          DIBUSB_RC_NEC_PROTOCOL,
          &dibusb_demod[DIBUSB_DIB3000MB],
          &dibusb_tuner[DIBUSB_TUNER_CABLE_THOMSON],
@@ -215,20 +229,43 @@ static struct dibusb_device_class dibusb_device_classes[] = {
        { DIBUSB2_0,&dibusb_usb_ctrl[2],
          "dvb-dibusb-6.0.0.5.fw",
          0x01, 0x06, 
-         3, 188*210,
+         7, 4096,
          DIBUSB_RC_NEC_PROTOCOL,
          &dibusb_demod[DIBUSB_DIB3000MC],
          &dibusb_tuner[DIBUSB_TUNER_COFDM_PANASONIC_ENV57H1XD5],
        },
        { UMT2_0, &dibusb_usb_ctrl[2],
-         "dvb-dibusb-umt-1.fw",
-         0x01, 0x02, 
-         15, 188*21,
+         "dvb-dibusb-umt-2.fw",
+         0x01, 0x06,
+         20, 512,
          DIBUSB_RC_NO,
          &dibusb_demod[DIBUSB_MT352],
-//       &dibusb_tuner[DIBUSB_TUNER_COFDM_PANASONIC_ENV77H11D5],
          &dibusb_tuner[DIBUSB_TUNER_CABLE_LG_TDTP_E102P],
        },
+       { DIBUSB2_0B,&dibusb_usb_ctrl[2],
+         "dvb-dibusb-adstech-usb2-1.fw",
+         0x01, 0x06,
+         7, 4096,
+         DIBUSB_RC_NEC_PROTOCOL,
+         &dibusb_demod[DIBUSB_DIB3000MB],
+         &dibusb_tuner[DIBUSB_TUNER_CABLE_THOMSON],
+       },
+       { NOVAT_USB2,&dibusb_usb_ctrl[2],
+         "dvb-dibusb-nova-t-1.fw",
+         0x01, 0x06,
+         7, 4096,
+         DIBUSB_RC_HAUPPAUGE_PROTO,
+         &dibusb_demod[DIBUSB_DIB3000MC],
+         &dibusb_tuner[DIBUSB_TUNER_COFDM_PANASONIC_ENV57H1XD5],
+       },
+       { DTT200U,&dibusb_usb_ctrl[2],
+         "dvb-dtt200u-1.fw",
+         0x01, 0x02,
+         7, 4096,
+         DIBUSB_RC_NO,
+         &dibusb_demod[DTT200U_FE],
+         NULL, /* no explicit tuner/pll-programming necessary (it has the ENV57H1XD5) */
+       },
 };
 
 static struct dibusb_usb_device dibusb_devices[] = {
@@ -287,30 +324,40 @@ static struct dibusb_usb_device dibusb_devices[] = {
                { &dib_table[27], NULL },
                { NULL },
        },
-       {       "AVermedia/Yakumo/Hama/Typhoon DVB-T USB2.0",
-               &dibusb_device_classes[UMT2_0],
+       {       "Hauppauge WinTV NOVA-T USB2",
+               &dibusb_device_classes[NOVAT_USB2],
+               { &dib_table[30], NULL },
+               { &dib_table[31], NULL },
+       },
+       {       "DTT200U (Yakumo/Hama/Typhoon) DVB-T USB2.0",
+               &dibusb_device_classes[DTT200U],
                { &dib_table[2], NULL },
-               { NULL },
+               { &dib_table[3], NULL },
        },      
        {       "Hanftek UMT-010 DVB-T USB2.0",
                &dibusb_device_classes[UMT2_0],
                { &dib_table[28], NULL },
                { &dib_table[29], NULL },
        },      
+       {       "KWorld/ADSTech Instant DVB-T USB 2.0",
+               &dibusb_device_classes[DIBUSB2_0B],
+               { &dib_table[32], NULL },
+               { &dib_table[33], NULL }, /* device ID with default DIBUSB2_0-firmware */
+       },
 #ifdef CONFIG_DVB_DIBUSB_MISDESIGNED_DEVICES
        {       "Artec T1 USB1.1 TVBOX with AN2235 (misdesigned)",
                &dibusb_device_classes[DIBUSB1_1_AN2235],
-               { &dib_table[30], NULL },
+               { &dib_table[34], NULL },
                { NULL },
        },
        {       "Artec T1 USB2.0 TVBOX with FX2 IDs (misdesigned, please report the warm ID)",
-               &dibusb_device_classes[DIBUSB2_0],
-               { &dib_table[31], NULL },
-               { &dib_table[32], NULL }, /* undefined, it could be that the device will get another USB ID in warm state */
+               &dibusb_device_classes[DTT200U],
+               { &dib_table[35], NULL },
+               { &dib_table[36], NULL }, /* undefined, it could be that the device will get another USB ID in warm state */
        },
        {       "DiBcom USB1.1 DVB-T reference design (MOD3000) with AN2135 default IDs",
                &dibusb_device_classes[DIBUSB1_1],
-               { &dib_table[33], NULL },
+               { &dib_table[37], NULL },
                { NULL },
        },
 #endif
@@ -322,7 +369,6 @@ static int dibusb_exit(struct usb_dibusb *dib)
        dibusb_remote_exit(dib);
        dibusb_fe_exit(dib);
        dibusb_i2c_exit(dib);
-       dibusb_pid_list_exit(dib);
        dibusb_dvb_exit(dib);
        dibusb_urb_exit(dib);
        deb_info("init_state should be zero now: %x\n",dib->init_state);
@@ -341,7 +387,6 @@ static int dibusb_init(struct usb_dibusb *dib)
        
        if ((ret = dibusb_urb_init(dib)) ||
                (ret = dibusb_dvb_init(dib)) || 
-               (ret = dibusb_pid_list_init(dib)) ||
                (ret = dibusb_i2c_init(dib))) {
                dibusb_exit(dib);
                return ret;
@@ -356,30 +401,62 @@ static int dibusb_init(struct usb_dibusb *dib)
        return 0;
 }
 
+static struct dibusb_usb_device * dibusb_device_class_quirk(struct usb_device *udev, struct dibusb_usb_device *dev)
+{
+       int i;
+
+       /* Quirk for the Kworld/ADSTech Instant USB2.0 device. It has the same USB
+        * IDs like the USB1.1 KWorld after loading the firmware. Which is a bad
+        * idea and make this quirk necessary.
+        */
+       if (dev->dev_cl->id == DIBUSB1_1 && udev->speed == USB_SPEED_HIGH) {
+               info("this seems to be the Kworld/ADSTech Instant USB2.0 device or equal.");
+               for (i = 0; i < sizeof(dibusb_devices)/sizeof(struct dibusb_usb_device); i++) {
+                       if (dibusb_devices[i].dev_cl->id == DIBUSB2_0B) {
+                               dev = &dibusb_devices[i];
+                               break;
+                       }
+               }
+       }
+
+       return dev;
+}
+
 static struct dibusb_usb_device * dibusb_find_device (struct usb_device *udev,int *cold)
 {
        int i,j;
+       struct dibusb_usb_device *dev = NULL;
        *cold = -1;
+
        for (i = 0; i < sizeof(dibusb_devices)/sizeof(struct dibusb_usb_device); i++) {
                for (j = 0; j < DIBUSB_ID_MAX_NUM && dibusb_devices[i].cold_ids[j] != NULL; j++) {
                        deb_info("check for cold %x %x\n",dibusb_devices[i].cold_ids[j]->idVendor, dibusb_devices[i].cold_ids[j]->idProduct);
                        if (dibusb_devices[i].cold_ids[j]->idVendor == le16_to_cpu(udev->descriptor.idVendor) &&
                                dibusb_devices[i].cold_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) {
                                *cold = 1;
-                               return &dibusb_devices[i];
+                               dev = &dibusb_devices[i];
+                               break;
                        }
                }
 
+               if (dev != NULL)
+                       break;
+
                for (j = 0; j < DIBUSB_ID_MAX_NUM && dibusb_devices[i].warm_ids[j] != NULL; j++) {
                        deb_info("check for warm %x %x\n",dibusb_devices[i].warm_ids[j]->idVendor, dibusb_devices[i].warm_ids[j]->idProduct);
                        if (dibusb_devices[i].warm_ids[j]->idVendor == le16_to_cpu(udev->descriptor.idVendor) &&
                                dibusb_devices[i].warm_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) {
                                *cold = 0;
-                               return &dibusb_devices[i];
+                               dev = &dibusb_devices[i];
+                               break;
                        }
                }
        }
-       return NULL;
+
+       if (dev != NULL)
+               dev = dibusb_device_class_quirk(udev,dev);
+
+       return dev;
 }
 
 /*
@@ -418,6 +495,7 @@ static int dibusb_probe(struct usb_interface *intf,
                /* store parameters to structures */
                dib->rc_query_interval = rc_query_interval;
                dib->pid_parse = pid_parse;
+               dib->rc_key_repeat_count = rc_key_repeat_count;
 
                usb_set_intfdata(intf, dib);
                
@@ -446,7 +524,7 @@ static void dibusb_disconnect(struct usb_interface *intf)
 }
 
 /* usb specific object needed to register this driver with the usb subsystem */
-struct usb_driver dibusb_driver = {
+static struct usb_driver dibusb_driver = {
        .owner          = THIS_MODULE,
        .name           = DRIVER_DESC,
        .probe          = dibusb_probe,