2 * Driver for mobile USB Budget DVB-T devices based on reference
3 * design made by DiBcom (http://www.dibcom.fr/)
7 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
9 * based on GPL code from DiBcom, which has
10 * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
12 * Remote control code added by David Matthews (dm@prolingua.co.uk)
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation, version 2.
20 * Amaury Demol (ademol@dibcom.fr) from DiBcom for providing specs and driver
21 * sources, on which this driver (and the dib3000mb/mc/p frontends) are based.
23 * see Documentation/dvb/README.dibusb for more information
25 #include "dvb-dibusb.h"
27 #include <linux/moduleparam.h>
31 module_param_named(debug, dvb_dibusb_debug, int, 0644);
33 #ifdef CONFIG_DVB_DIBCOM_DEBUG
36 #define DBSTATUS " (debugging is not enabled)"
38 MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=alotmore,8=ts,16=err,32=rc (|-able))." DBSTATUS);
42 module_param(pid_parse, int, 0644);
43 MODULE_PARM_DESC(pid_parse, "enable pid parsing (filtering) when running at USB2.0");
45 static int rc_query_interval;
46 module_param(rc_query_interval, int, 0644);
47 MODULE_PARM_DESC(rc_query_interval, "interval in msecs for remote control query (default: 100; min: 40)");
50 #define USB_VID_ANCHOR 0x0547
51 #define USB_VID_AVERMEDIA 0x14aa
52 #define USB_VID_COMPRO 0x185b
53 #define USB_VID_COMPRO_UNK 0x145f
54 #define USB_VID_CYPRESS 0x04b4
55 #define USB_VID_DIBCOM 0x10b8
56 #define USB_VID_EMPIA 0xeb1a
57 #define USB_VID_GRANDTEC 0x5032
58 #define USB_VID_HYPER_PALTEK 0x1025
59 #define USB_VID_HANFTEK 0x15f4
60 #define USB_VID_IMC_NETWORKS 0x13d3
61 #define USB_VID_TWINHAN 0x1822
62 #define USB_VID_ULTIMA_ELECTRONIC 0x05d8
65 #define USB_PID_AVERMEDIA_DVBT_USB_COLD 0x0001
66 #define USB_PID_AVERMEDIA_DVBT_USB_WARM 0x0002
67 #define USB_PID_COMPRO_DVBU2000_COLD 0xd000
68 #define USB_PID_COMPRO_DVBU2000_WARM 0xd001
69 #define USB_PID_COMPRO_DVBU2000_UNK_COLD 0x010c
70 #define USB_PID_COMPRO_DVBU2000_UNK_WARM 0x010d
71 #define USB_PID_DIBCOM_MOD3000_COLD 0x0bb8
72 #define USB_PID_DIBCOM_MOD3000_WARM 0x0bb9
73 #define USB_PID_DIBCOM_MOD3001_COLD 0x0bc6
74 #define USB_PID_DIBCOM_MOD3001_WARM 0x0bc7
75 #define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131
76 #define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0
77 #define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1
78 #define USB_PID_KWORLD_VSTREAM_COLD 0x17de
79 #define USB_PID_KWORLD_VSTREAM_WARM 0x17df
80 #define USB_PID_TWINHAN_VP7041_COLD 0x3201
81 #define USB_PID_TWINHAN_VP7041_WARM 0x3202
82 #define USB_PID_ULTIMA_TVBOX_COLD 0x8105
83 #define USB_PID_ULTIMA_TVBOX_WARM 0x8106
84 #define USB_PID_ULTIMA_TVBOX_AN2235_COLD 0x8107
85 #define USB_PID_ULTIMA_TVBOX_AN2235_WARM 0x8108
86 #define USB_PID_ULTIMA_TVBOX_ANCHOR_COLD 0x2235
87 #define USB_PID_ULTIMA_TVBOX_USB2_COLD 0x8109
88 #define USB_PID_ULTIMA_TVBOX_USB2_FX_COLD 0x8613
89 #define USB_PID_ULTIMA_TVBOX_USB2_FX_WARM 0x1002
90 #define USB_PID_UNK_HYPER_PALTEK_COLD 0x005e
91 #define USB_PID_UNK_HYPER_PALTEK_WARM 0x005f
92 #define USB_PID_HANFTEK_UMT_010_COLD 0x0001
93 #define USB_PID_HANFTEK_UMT_010_WARM 0x0025
94 #define USB_PID_YAKUMO_DTT200U_COLD 0x0201
95 #define USB_PID_YAKUMO_DTT200U_WARM 0x0301
98 * table of devices that this driver is working with
100 * ATTENTION: Never ever change the order of this table, the particular
101 * devices depend on this order
103 * Each entry is used as a reference in the device_struct. Currently this is
104 * the only non-redundant way of assigning USB ids to actual devices I'm aware
105 * of, because there is only one place in the code where the assignment of
106 * vendor and product id is done, here.
108 static struct usb_device_id dib_table [] = {
109 /* 00 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_DVBT_USB_COLD)},
110 /* 01 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_DVBT_USB_WARM)},
111 /* 02 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_YAKUMO_DTT200U_COLD) },
113 /* the following device is actually not supported, but when loading the
114 * correct firmware (ie. its usb ids will change) everything works fine then
116 /* 03 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_YAKUMO_DTT200U_WARM) },
118 /* 04 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_COLD) },
119 /* 05 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_WARM) },
120 /* 06 */ { USB_DEVICE(USB_VID_COMPRO_UNK, USB_PID_COMPRO_DVBU2000_UNK_COLD) },
121 /* 07 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_COLD) },
122 /* 08 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_WARM) },
123 /* 09 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3001_COLD) },
124 /* 10 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3001_WARM) },
125 /* 11 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_COLD) },
126 /* 12 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_WARM) },
127 /* 13 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_COLD) },
128 /* 14 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_WARM) },
129 /* 15 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_DIBCOM_MOD3000_COLD) },
130 /* 16 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_DIBCOM_MOD3000_WARM) },
131 /* 17 */ { USB_DEVICE(USB_VID_HYPER_PALTEK, USB_PID_UNK_HYPER_PALTEK_COLD) },
132 /* 18 */ { USB_DEVICE(USB_VID_HYPER_PALTEK, USB_PID_UNK_HYPER_PALTEK_WARM) },
133 /* 19 */ { USB_DEVICE(USB_VID_IMC_NETWORKS, USB_PID_TWINHAN_VP7041_COLD) },
134 /* 20 */ { USB_DEVICE(USB_VID_IMC_NETWORKS, USB_PID_TWINHAN_VP7041_WARM) },
135 /* 21 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_COLD) },
136 /* 22 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_WARM) },
137 /* 23 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_COLD) },
138 /* 24 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_WARM) },
139 /* 25 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_COLD) },
140 /* 26 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_WARM) },
141 /* 27 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_COLD) },
143 /* 28 */ { USB_DEVICE(USB_VID_HANFTEK, USB_PID_HANFTEK_UMT_010_COLD) },
144 /* 29 */ { USB_DEVICE(USB_VID_HANFTEK, USB_PID_HANFTEK_UMT_010_WARM) },
147 * activate the following define when you have one of the devices and want to
148 * build it from build-2.6 in dvb-kernel
150 // #define CONFIG_DVB_DIBUSB_MISDESIGNED_DEVICES
151 #ifdef CONFIG_DVB_DIBUSB_MISDESIGNED_DEVICES
152 /* 30 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) },
153 /* 31 */ { USB_DEVICE(USB_VID_CYPRESS, USB_PID_ULTIMA_TVBOX_USB2_FX_COLD) },
154 /* 32 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_USB2_FX_WARM) },
155 /* 33 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_DIBCOM_ANCHOR_2135_COLD) },
157 { } /* Terminating entry */
160 MODULE_DEVICE_TABLE (usb, dib_table);
162 static struct dibusb_usb_controller dibusb_usb_ctrl[] = {
163 { .name = "Cypress AN2135", .cpu_cs_register = 0x7f92 },
164 { .name = "Cypress AN2235", .cpu_cs_register = 0x7f92 },
165 { .name = "Cypress FX2", .cpu_cs_register = 0xe600 },
168 struct dibusb_tuner dibusb_tuner[] = {
169 { DIBUSB_TUNER_CABLE_THOMSON,
172 { DIBUSB_TUNER_COFDM_PANASONIC_ENV57H1XD5,
175 { DIBUSB_TUNER_CABLE_LG_TDTP_E102P,
178 { DIBUSB_TUNER_COFDM_PANASONIC_ENV77H11D5,
183 static struct dibusb_demod dibusb_demod[] = {
190 { 0x9, 0xa, 0xb, 0xc },
198 static struct dibusb_device_class dibusb_device_classes[] = {
199 { .id = DIBUSB1_1, .usb_ctrl = &dibusb_usb_ctrl[0],
200 .firmware = "dvb-dibusb-5.0.0.11.fw",
201 .pipe_cmd = 0x01, .pipe_data = 0x02,
202 .urb_count = 3, .urb_buffer_size = 4096,
203 DIBUSB_RC_NEC_PROTOCOL,
204 &dibusb_demod[DIBUSB_DIB3000MB],
205 &dibusb_tuner[DIBUSB_TUNER_CABLE_THOMSON],
207 { DIBUSB1_1_AN2235, &dibusb_usb_ctrl[1],
208 "dvb-dibusb-an2235-1.fw",
211 DIBUSB_RC_NEC_PROTOCOL,
212 &dibusb_demod[DIBUSB_DIB3000MB],
213 &dibusb_tuner[DIBUSB_TUNER_CABLE_THOMSON],
215 { DIBUSB2_0,&dibusb_usb_ctrl[2],
216 "dvb-dibusb-6.0.0.5.fw",
219 DIBUSB_RC_NEC_PROTOCOL,
220 &dibusb_demod[DIBUSB_DIB3000MC],
221 &dibusb_tuner[DIBUSB_TUNER_COFDM_PANASONIC_ENV57H1XD5],
223 { UMT2_0, &dibusb_usb_ctrl[2],
224 "dvb-dibusb-umt-1.fw",
228 &dibusb_demod[DIBUSB_MT352],
229 // &dibusb_tuner[DIBUSB_TUNER_COFDM_PANASONIC_ENV77H11D5],
230 &dibusb_tuner[DIBUSB_TUNER_CABLE_LG_TDTP_E102P],
234 static struct dibusb_usb_device dibusb_devices[] = {
235 { "TwinhanDTV USB1.1 / Magic Box / HAMA USB1.1 DVB-T device",
236 &dibusb_device_classes[DIBUSB1_1],
237 { &dib_table[19], &dib_table[21], NULL},
238 { &dib_table[20], &dib_table[22], NULL},
240 { "KWorld V-Stream XPERT DTV - DVB-T USB1.1",
241 &dibusb_device_classes[DIBUSB1_1],
242 { &dib_table[11], NULL },
243 { &dib_table[12], NULL },
245 { "Grandtec USB1.1 DVB-T",
246 &dibusb_device_classes[DIBUSB1_1],
247 { &dib_table[13], &dib_table[15], NULL },
248 { &dib_table[14], &dib_table[16], NULL },
250 { "DiBcom USB1.1 DVB-T reference design (MOD3000)",
251 &dibusb_device_classes[DIBUSB1_1],
252 { &dib_table[7], NULL },
253 { &dib_table[8], NULL },
255 { "Artec T1 USB1.1 TVBOX with AN2135",
256 &dibusb_device_classes[DIBUSB1_1],
257 { &dib_table[23], NULL },
258 { &dib_table[24], NULL },
260 { "Artec T1 USB1.1 TVBOX with AN2235",
261 &dibusb_device_classes[DIBUSB1_1_AN2235],
262 { &dib_table[25], NULL },
263 { &dib_table[26], NULL },
265 { "Avermedia AverTV DVBT USB1.1",
266 &dibusb_device_classes[DIBUSB1_1],
267 { &dib_table[0], NULL },
268 { &dib_table[1], NULL },
270 { "Compro Videomate DVB-U2000 - DVB-T USB1.1 (please confirm to linux-dvb)",
271 &dibusb_device_classes[DIBUSB1_1],
272 { &dib_table[4], &dib_table[6], NULL},
273 { &dib_table[5], NULL },
275 { "Unkown USB1.1 DVB-T device ???? please report the name to the author",
276 &dibusb_device_classes[DIBUSB1_1],
277 { &dib_table[17], NULL },
278 { &dib_table[18], NULL },
280 { "DiBcom USB2.0 DVB-T reference design (MOD3000P)",
281 &dibusb_device_classes[DIBUSB2_0],
282 { &dib_table[9], NULL },
283 { &dib_table[10], NULL },
285 { "Artec T1 USB2.0 TVBOX (please report the warm ID)",
286 &dibusb_device_classes[DIBUSB2_0],
287 { &dib_table[27], NULL },
290 { "AVermedia/Yakumo/Hama/Typhoon DVB-T USB2.0",
291 &dibusb_device_classes[UMT2_0],
292 { &dib_table[2], NULL },
295 { "Hanftek UMT-010 DVB-T USB2.0",
296 &dibusb_device_classes[UMT2_0],
297 { &dib_table[28], NULL },
298 { &dib_table[29], NULL },
300 #ifdef CONFIG_DVB_DIBUSB_MISDESIGNED_DEVICES
301 { "Artec T1 USB1.1 TVBOX with AN2235 (misdesigned)",
302 &dibusb_device_classes[DIBUSB1_1_AN2235],
303 { &dib_table[30], NULL },
306 { "Artec T1 USB2.0 TVBOX with FX2 IDs (misdesigned, please report the warm ID)",
307 &dibusb_device_classes[DIBUSB2_0],
308 { &dib_table[31], NULL },
309 { &dib_table[32], NULL }, /* undefined, it could be that the device will get another USB ID in warm state */
311 { "DiBcom USB1.1 DVB-T reference design (MOD3000) with AN2135 default IDs",
312 &dibusb_device_classes[DIBUSB1_1],
313 { &dib_table[33], NULL },
319 static int dibusb_exit(struct usb_dibusb *dib)
321 deb_info("init_state before exiting everything: %x\n",dib->init_state);
322 dibusb_remote_exit(dib);
324 dibusb_i2c_exit(dib);
325 dibusb_pid_list_exit(dib);
326 dibusb_dvb_exit(dib);
327 dibusb_urb_exit(dib);
328 deb_info("init_state should be zero now: %x\n",dib->init_state);
329 dib->init_state = DIBUSB_STATE_INIT;
334 static int dibusb_init(struct usb_dibusb *dib)
337 sema_init(&dib->usb_sem, 1);
338 sema_init(&dib->i2c_sem, 1);
340 dib->init_state = DIBUSB_STATE_INIT;
342 if ((ret = dibusb_urb_init(dib)) ||
343 (ret = dibusb_dvb_init(dib)) ||
344 (ret = dibusb_pid_list_init(dib)) ||
345 (ret = dibusb_i2c_init(dib))) {
350 if ((ret = dibusb_fe_init(dib)))
351 err("could not initialize a frontend.");
353 if ((ret = dibusb_remote_init(dib)))
354 err("could not initialize remote control.");
359 static struct dibusb_usb_device * dibusb_find_device (struct usb_device *udev,int *cold)
363 for (i = 0; i < sizeof(dibusb_devices)/sizeof(struct dibusb_usb_device); i++) {
364 for (j = 0; j < DIBUSB_ID_MAX_NUM && dibusb_devices[i].cold_ids[j] != NULL; j++) {
365 deb_info("check for cold %x %x\n",dibusb_devices[i].cold_ids[j]->idVendor, dibusb_devices[i].cold_ids[j]->idProduct);
366 if (dibusb_devices[i].cold_ids[j]->idVendor == le16_to_cpu(udev->descriptor.idVendor) &&
367 dibusb_devices[i].cold_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) {
369 return &dibusb_devices[i];
373 for (j = 0; j < DIBUSB_ID_MAX_NUM && dibusb_devices[i].warm_ids[j] != NULL; j++) {
374 deb_info("check for warm %x %x\n",dibusb_devices[i].warm_ids[j]->idVendor, dibusb_devices[i].warm_ids[j]->idProduct);
375 if (dibusb_devices[i].warm_ids[j]->idVendor == le16_to_cpu(udev->descriptor.idVendor) &&
376 dibusb_devices[i].warm_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) {
378 return &dibusb_devices[i];
388 static int dibusb_probe(struct usb_interface *intf,
389 const struct usb_device_id *id)
391 struct usb_device *udev = interface_to_usbdev(intf);
392 struct usb_dibusb *dib = NULL;
393 struct dibusb_usb_device *dibdev = NULL;
395 int ret = -ENOMEM,cold=0;
397 if ((dibdev = dibusb_find_device(udev,&cold)) == NULL) {
398 err("something went very wrong, "
399 "unknown product ID: %.4x",le16_to_cpu(udev->descriptor.idProduct));
404 info("found a '%s' in cold state, will try to load a firmware",dibdev->name);
405 ret = dibusb_loadfirmware(udev,dibdev);
407 info("found a '%s' in warm state.",dibdev->name);
408 dib = kmalloc(sizeof(struct usb_dibusb),GFP_KERNEL);
413 memset(dib,0,sizeof(struct usb_dibusb));
416 dib->dibdev = dibdev;
418 /* store parameters to structures */
419 dib->rc_query_interval = rc_query_interval;
420 dib->pid_parse = pid_parse;
422 usb_set_intfdata(intf, dib);
424 ret = dibusb_init(dib);
428 info("%s successfully initialized and connected.",dibdev->name);
430 info("%s error while loading driver (%d)",dibdev->name,ret);
434 static void dibusb_disconnect(struct usb_interface *intf)
436 struct usb_dibusb *dib = usb_get_intfdata(intf);
437 const char *name = DRIVER_DESC;
439 usb_set_intfdata(intf,NULL);
440 if (dib != NULL && dib->dibdev != NULL) {
441 name = dib->dibdev->name;
444 info("%s successfully deinitialized and disconnected.",name);
448 /* usb specific object needed to register this driver with the usb subsystem */
449 struct usb_driver dibusb_driver = {
450 .owner = THIS_MODULE,
452 .probe = dibusb_probe,
453 .disconnect = dibusb_disconnect,
454 .id_table = dib_table,
458 static int __init usb_dibusb_init(void)
461 if ((result = usb_register(&dibusb_driver))) {
462 err("usb_register failed. Error number %d",result);
469 static void __exit usb_dibusb_exit(void)
471 /* deregister this driver from the USB subsystem */
472 usb_deregister(&dibusb_driver);
475 module_init (usb_dibusb_init);
476 module_exit (usb_dibusb_exit);
478 MODULE_AUTHOR(DRIVER_AUTHOR);
479 MODULE_DESCRIPTION(DRIVER_DESC);
480 MODULE_LICENSE("GPL");