This commit was manufactured by cvs2svn to create branch 'vserver'.
[linux-2.6.git] / drivers / media / dvb / dibusb / dvb-dibusb-core.c
1 /*
2  * Driver for mobile USB Budget DVB-T devices based on reference 
3  * design made by DiBcom (http://www.dibcom.fr/)
4  * 
5  * dvb-dibusb-core.c
6  * 
7  * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
8  * 
9  * based on GPL code from DiBcom, which has
10  * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
11  *
12  * Remote control code added by David Matthews (dm@prolingua.co.uk)
13  * 
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.
17  *
18  * Acknowledgements
19  * 
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.
22  * 
23  * see Documentation/dvb/README.dibusb for more information
24  */
25 #include "dvb-dibusb.h"
26
27 #include <linux/moduleparam.h>
28
29 /* debug */
30 int dvb_dibusb_debug;
31 module_param_named(debug, dvb_dibusb_debug,  int, 0644);
32
33 #ifdef CONFIG_DVB_DIBCOM_DEBUG
34 #define DBSTATUS ""
35 #else
36 #define DBSTATUS " (debugging is not enabled)"
37 #endif
38 MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=alotmore,8=ts,16=err,32=rc (|-able))." DBSTATUS);
39 #undef DBSTATUS
40
41 static int pid_parse;
42 module_param(pid_parse, int, 0644);
43 MODULE_PARM_DESC(pid_parse, "enable pid parsing (filtering) when running at USB2.0");
44
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)");
48
49 /* Vendor IDs */
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
63
64 /* Product IDs */
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
96
97 /* USB Driver stuff
98  * table of devices that this driver is working with
99  *
100  * ATTENTION: Never ever change the order of this table, the particular 
101  * devices depend on this order 
102  *
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.
107  */
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) },
112
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 
115  */
116 /* 03 */        { USB_DEVICE(USB_VID_AVERMEDIA,         USB_PID_YAKUMO_DTT200U_WARM) },
117
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) },
142         
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) },
145
146 /* 
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
149  */
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) },
156 #endif
157                         { }             /* Terminating entry */
158 };
159
160 MODULE_DEVICE_TABLE (usb, dib_table);
161
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 },
166 };
167
168 struct dibusb_tuner dibusb_tuner[] = {
169         { DIBUSB_TUNER_CABLE_THOMSON, 
170           0x61 
171         },
172         { DIBUSB_TUNER_COFDM_PANASONIC_ENV57H1XD5,
173           0x60 
174         },
175         { DIBUSB_TUNER_CABLE_LG_TDTP_E102P,
176           0x61
177         },
178         { DIBUSB_TUNER_COFDM_PANASONIC_ENV77H11D5,
179           0x60
180         },
181 };
182
183 static struct dibusb_demod dibusb_demod[] = {
184         { DIBUSB_DIB3000MB,
185           16,
186           { 0x8, 0 },
187         },
188         { DIBUSB_DIB3000MC,
189           32,
190           { 0x9, 0xa, 0xb, 0xc }, 
191         },
192         { DIBUSB_MT352,
193           254,
194           { 0xf, 0 }, 
195         },
196 };
197
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],
206         },
207         { DIBUSB1_1_AN2235, &dibusb_usb_ctrl[1],
208           "dvb-dibusb-an2235-1.fw",
209           0x01, 0x02, 
210           3, 4096,
211           DIBUSB_RC_NEC_PROTOCOL,
212           &dibusb_demod[DIBUSB_DIB3000MB],
213           &dibusb_tuner[DIBUSB_TUNER_CABLE_THOMSON],
214         },
215         { DIBUSB2_0,&dibusb_usb_ctrl[2],
216           "dvb-dibusb-6.0.0.5.fw",
217           0x01, 0x06, 
218           3, 188*210,
219           DIBUSB_RC_NEC_PROTOCOL,
220           &dibusb_demod[DIBUSB_DIB3000MC],
221           &dibusb_tuner[DIBUSB_TUNER_COFDM_PANASONIC_ENV57H1XD5],
222         },
223         { UMT2_0, &dibusb_usb_ctrl[2],
224           "dvb-dibusb-umt-1.fw",
225           0x01, 0x02, 
226           15, 188*21,
227           DIBUSB_RC_NO,
228           &dibusb_demod[DIBUSB_MT352],
229 //        &dibusb_tuner[DIBUSB_TUNER_COFDM_PANASONIC_ENV77H11D5],
230           &dibusb_tuner[DIBUSB_TUNER_CABLE_LG_TDTP_E102P],
231         },
232 };
233
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},
239         },
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 },
244         },
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 },
249         },
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 },
254         },
255         {       "Artec T1 USB1.1 TVBOX with AN2135",
256                 &dibusb_device_classes[DIBUSB1_1],
257                 { &dib_table[23], NULL },
258                 { &dib_table[24], NULL },
259         },
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 },
264         },
265         {       "Avermedia AverTV DVBT USB1.1",
266                 &dibusb_device_classes[DIBUSB1_1],
267                 { &dib_table[0],  NULL },
268                 { &dib_table[1],  NULL },
269         },
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 },
274         },
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 },
279         },
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 },
284         },
285         {       "Artec T1 USB2.0 TVBOX (please report the warm ID)",
286                 &dibusb_device_classes[DIBUSB2_0],
287                 { &dib_table[27], NULL },
288                 { NULL },
289         },
290         {       "AVermedia/Yakumo/Hama/Typhoon DVB-T USB2.0",
291                 &dibusb_device_classes[UMT2_0],
292                 { &dib_table[2], NULL },
293                 { NULL },
294         },      
295         {       "Hanftek UMT-010 DVB-T USB2.0",
296                 &dibusb_device_classes[UMT2_0],
297                 { &dib_table[28], NULL },
298                 { &dib_table[29], NULL },
299         },      
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 },
304                 { NULL },
305         },
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 */
310         },
311         {       "DiBcom USB1.1 DVB-T reference design (MOD3000) with AN2135 default IDs",
312                 &dibusb_device_classes[DIBUSB1_1],
313                 { &dib_table[33], NULL },
314                 { NULL },
315         },
316 #endif
317 };
318
319 static int dibusb_exit(struct usb_dibusb *dib)
320 {
321         deb_info("init_state before exiting everything: %x\n",dib->init_state);
322         dibusb_remote_exit(dib);
323         dibusb_fe_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;
330         kfree(dib);
331         return 0;
332 }
333
334 static int dibusb_init(struct usb_dibusb *dib)
335 {
336         int ret = 0;
337         sema_init(&dib->usb_sem, 1);
338         sema_init(&dib->i2c_sem, 1);
339
340         dib->init_state = DIBUSB_STATE_INIT;
341         
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))) {
346                 dibusb_exit(dib);
347                 return ret;
348         }
349
350         if ((ret = dibusb_fe_init(dib)))
351                 err("could not initialize a frontend.");
352         
353         if ((ret = dibusb_remote_init(dib)))
354                 err("could not initialize remote control.");
355         
356         return 0;
357 }
358
359 static struct dibusb_usb_device * dibusb_find_device (struct usb_device *udev,int *cold)
360 {
361         int i,j;
362         *cold = -1;
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)) {
368                                 *cold = 1;
369                                 return &dibusb_devices[i];
370                         }
371                 }
372
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)) {
377                                 *cold = 0;
378                                 return &dibusb_devices[i];
379                         }
380                 }
381         }
382         return NULL;
383 }
384
385 /*
386  * USB 
387  */
388 static int dibusb_probe(struct usb_interface *intf, 
389                 const struct usb_device_id *id)
390 {
391         struct usb_device *udev = interface_to_usbdev(intf);
392         struct usb_dibusb *dib = NULL;
393         struct dibusb_usb_device *dibdev = NULL;
394         
395         int ret = -ENOMEM,cold=0;
396
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));
400                 return -ENODEV;
401         }
402         
403         if (cold == 1) {
404                 info("found a '%s' in cold state, will try to load a firmware",dibdev->name);
405                 ret = dibusb_loadfirmware(udev,dibdev);
406         } else {
407                 info("found a '%s' in warm state.",dibdev->name);
408                 dib = kmalloc(sizeof(struct usb_dibusb),GFP_KERNEL);
409                 if (dib == NULL) {
410                         err("no memory");
411                         return ret;
412                 }
413                 memset(dib,0,sizeof(struct usb_dibusb));
414                 
415                 dib->udev = udev;
416                 dib->dibdev = dibdev;
417
418                 /* store parameters to structures */
419                 dib->rc_query_interval = rc_query_interval;
420                 dib->pid_parse = pid_parse;
421
422                 usb_set_intfdata(intf, dib);
423                 
424                 ret = dibusb_init(dib);
425         }
426         
427         if (ret == 0)
428                 info("%s successfully initialized and connected.",dibdev->name);
429         else 
430                 info("%s error while loading driver (%d)",dibdev->name,ret);
431         return ret;
432 }
433
434 static void dibusb_disconnect(struct usb_interface *intf)
435 {
436         struct usb_dibusb *dib = usb_get_intfdata(intf);
437         const char *name = DRIVER_DESC;
438         
439         usb_set_intfdata(intf,NULL);
440         if (dib != NULL && dib->dibdev != NULL) {
441                 name = dib->dibdev->name;
442                 dibusb_exit(dib);
443         }
444         info("%s successfully deinitialized and disconnected.",name);
445         
446 }
447
448 /* usb specific object needed to register this driver with the usb subsystem */
449 struct usb_driver dibusb_driver = {
450         .owner          = THIS_MODULE,
451         .name           = DRIVER_DESC,
452         .probe          = dibusb_probe,
453         .disconnect = dibusb_disconnect,
454         .id_table       = dib_table,
455 };
456
457 /* module stuff */
458 static int __init usb_dibusb_init(void)
459 {
460         int result;
461         if ((result = usb_register(&dibusb_driver))) {
462                 err("usb_register failed. Error number %d",result);
463                 return result;
464         }
465         
466         return 0;
467 }
468
469 static void __exit usb_dibusb_exit(void)
470 {
471         /* deregister this driver from the USB subsystem */
472         usb_deregister(&dibusb_driver);
473 }
474
475 module_init (usb_dibusb_init);
476 module_exit (usb_dibusb_exit);
477
478 MODULE_AUTHOR(DRIVER_AUTHOR);
479 MODULE_DESCRIPTION(DRIVER_DESC);
480 MODULE_LICENSE("GPL");