Linux-2.6.12-rc2
[linux-flexiantxendom0-natty.git] / drivers / media / dvb / b2c2 / b2c2-usb-core.c
1 /*
2  * Copyright (C) 2004 Patrick Boettcher <patrick.boettcher@desy.de>,
3  *                    Luca Bertagnolio <>,
4  *
5  * based on information provided by John Jurrius from BBTI, Inc.
6  *
7  *      This program is free software; you can redistribute it and/or
8  *      modify it under the terms of the GNU General Public License as
9  *      published by the Free Software Foundation, version 2.
10  *
11  */
12
13 #include <linux/config.h>
14 #include <linux/kernel.h>
15 #include <linux/usb.h>
16 #include <linux/moduleparam.h>
17 #include <linux/pci.h>
18 #include <linux/version.h>
19
20 #include "dmxdev.h"
21 #include "dvb_demux.h"
22 #include "dvb_filter.h"
23 #include "dvb_net.h"
24 #include "dvb_frontend.h"
25
26 /* debug */
27 #define dprintk(level,args...) \
28             do { if ((debug & level)) { printk(args); } } while (0)
29 #define debug_dump(b,l) if (debug) {\
30         int i; deb_xfer("%s: %d > ",__FUNCTION__,l); \
31         for (i = 0; i < l; i++) deb_xfer("%02x ", b[i]); \
32         deb_xfer("\n");\
33 }
34
35 static int debug;
36 module_param(debug, int, 0644);
37 MODULE_PARM_DESC(debug, "set debugging level (1=info,ts=2,ctrl=4 (or-able)).");
38
39 #define deb_info(args...) dprintk(0x01,args)
40 #define deb_ts(args...)   dprintk(0x02,args)
41 #define deb_ctrl(args...) dprintk(0x04,args)
42
43 /* Version information */
44 #define DRIVER_VERSION "0.0"
45 #define DRIVER_DESC "Driver for B2C2/Technisat Air/Cable/Sky-2-PC USB devices"
46 #define DRIVER_AUTHOR "Patrick Boettcher, patrick.boettcher@desy.de"
47
48 /* transfer parameters */
49 #define B2C2_USB_FRAMES_PER_ISO         4
50 #define B2C2_USB_NUM_ISO_URB            4    /* TODO check out a good value */
51
52 #define B2C2_USB_CTRL_PIPE_IN           usb_rcvctrlpipe(b2c2->udev,0)
53 #define B2C2_USB_CTRL_PIPE_OUT          usb_sndctrlpipe(b2c2->udev,0)
54 #define B2C2_USB_DATA_PIPE                      usb_rcvisocpipe(b2c2->udev,0x81)
55
56 struct usb_b2c2_usb {
57         struct usb_device *udev;
58         struct usb_interface *uintf;
59
60         u8 *iso_buffer;
61         int buffer_size;
62         dma_addr_t iso_dma_handle;
63         struct urb *iso_urb[B2C2_USB_NUM_ISO_URB];
64 };
65
66
67 /*
68  * USB
69  * 10 90 34 12 78 56 04 00
70  * usb_control_msg(udev, usb_sndctrlpipe(udev,0),
71  * 0x90,
72  * 0x10,
73  * 0x1234,
74  * 0x5678,
75  * buf,
76  * 4,
77  * 5*HZ);
78  *
79  * extern int usb_control_msg(struct usb_device *dev, unsigned int pipe,
80  * __u8 request,
81  * __u8 requesttype,
82  * __u16 value,
83  * __u16 index,
84  * void *data,
85  * __u16 size,
86  * int timeout);
87  *
88  */
89
90 /* request types */
91 typedef enum {
92
93 /* something is wrong with this part
94         RTYPE_READ_DW         = (1 << 6),
95         RTYPE_WRITE_DW_1      = (3 << 6),
96         RTYPE_READ_V8_MEMORY  = (6 << 6),
97         RTYPE_WRITE_V8_MEMORY = (7 << 6),
98         RTYPE_WRITE_V8_FLASH  = (8 << 6),
99         RTYPE_GENERIC         = (9 << 6),
100 */
101         RTYPE_READ_DW = (3 << 6),
102         RTYPE_WRITE_DW_1 = (1 << 6),
103         
104         RTYPE_READ_V8_MEMORY  = (6 << 6),
105         RTYPE_WRITE_V8_MEMORY = (7 << 6),
106         RTYPE_WRITE_V8_FLASH  = (8 << 6),
107         RTYPE_GENERIC         = (9 << 6),
108 } b2c2_usb_request_type_t;
109
110 /* request */
111 typedef enum {
112         B2C2_USB_WRITE_V8_MEM = 0x04,
113         B2C2_USB_READ_V8_MEM  = 0x05,
114         B2C2_USB_READ_REG     = 0x08,
115         B2C2_USB_WRITE_REG    = 0x0A,
116 /*      B2C2_USB_WRITEREGLO   = 0x0A, */
117         B2C2_USB_WRITEREGHI   = 0x0B,
118         B2C2_USB_FLASH_BLOCK  = 0x10,
119         B2C2_USB_I2C_REQUEST  = 0x11,
120         B2C2_USB_UTILITY      = 0x12,
121 } b2c2_usb_request_t;
122
123 /* function definition for I2C_REQUEST */
124 typedef enum {
125         USB_FUNC_I2C_WRITE       = 0x01,
126         USB_FUNC_I2C_MULTIWRITE  = 0x02,
127         USB_FUNC_I2C_READ        = 0x03,
128         USB_FUNC_I2C_REPEATWRITE = 0x04,
129         USB_FUNC_GET_DESCRIPTOR  = 0x05,
130         USB_FUNC_I2C_REPEATREAD  = 0x06,
131 /* DKT 020208 - add this to support special case of DiSEqC */
132         USB_FUNC_I2C_CHECKWRITE  = 0x07,
133         USB_FUNC_I2C_CHECKRESULT = 0x08,
134 } b2c2_usb_i2c_function_t;
135
136 /*
137  * function definition for UTILITY request 0x12
138  * DKT 020304 - new utility function
139  */
140 typedef enum {
141         UTILITY_SET_FILTER          = 0x01,
142         UTILITY_DATA_ENABLE         = 0x02,
143         UTILITY_FLEX_MULTIWRITE     = 0x03,
144         UTILITY_SET_BUFFER_SIZE     = 0x04,
145         UTILITY_FLEX_OPERATOR       = 0x05,
146         UTILITY_FLEX_RESET300_START = 0x06,
147         UTILITY_FLEX_RESET300_STOP  = 0x07,
148         UTILITY_FLEX_RESET300       = 0x08,
149         UTILITY_SET_ISO_SIZE        = 0x09,
150         UTILITY_DATA_RESET          = 0x0A,
151         UTILITY_GET_DATA_STATUS     = 0x10,
152         UTILITY_GET_V8_REG          = 0x11,
153 /* DKT 020326 - add function for v1.14 */
154         UTILITY_SRAM_WRITE          = 0x12,
155         UTILITY_SRAM_READ           = 0x13,
156         UTILITY_SRAM_TESTFILL       = 0x14,
157         UTILITY_SRAM_TESTSET        = 0x15,
158         UTILITY_SRAM_TESTVERIFY     = 0x16,
159 } b2c2_usb_utility_function_t;
160
161 #define B2C2_WAIT_FOR_OPERATION_RW  1  // 1 s
162 #define B2C2_WAIT_FOR_OPERATION_RDW 3  // 3 s
163 #define B2C2_WAIT_FOR_OPERATION_WDW 1  // 1 s
164
165 #define B2C2_WAIT_FOR_OPERATION_V8READ   3  // 3 s
166 #define B2C2_WAIT_FOR_OPERATION_V8WRITE  3  // 3 s
167 #define B2C2_WAIT_FOR_OPERATION_V8FLASH  3  // 3 s
168
169 /* JLP 111700: we will include the 1 bit gap between the upper and lower 3 bits
170  * in the IBI address, to make the V8 code simpler.
171  * PCI ADDRESS FORMAT: 0x71C -> 0000 0111 0001 1100 (these are the six bits used)
172  *                  in general: 0000 0HHH 000L LL00
173  * IBI ADDRESS FORMAT:                    RHHH BLLL
174  *
175  * where R is the read(1)/write(0) bit, B is the busy bit
176  * and HHH and LLL are the two sets of three bits from the PCI address.
177  */
178 #define B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(usPCI) (u8) (((usPCI >> 2) & 0x07) + ((usPCI >> 4) & 0x70))
179 #define B2C2_FLEX_INTERNALADDR_TO_PCIOFFSET(ucAddr) (u16) (((ucAddr & 0x07) << 2) + ((ucAddr & 0x70) << 4))
180
181 /*
182  * DKT 020228 - forget about this VENDOR_BUFFER_SIZE, read and write register
183  * deal with DWORD or 4 bytes, that should be should from now on
184  */
185 static u32 b2c2_usb_read_dw(struct usb_b2c2_usb *b2c2, u16 wRegOffsPCI)
186 {
187         u32 val;
188         u16 wAddress = B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(wRegOffsPCI) | 0x0080;
189         int len = usb_control_msg(b2c2->udev,
190                         B2C2_USB_CTRL_PIPE_IN,
191                         B2C2_USB_READ_REG,
192                         RTYPE_READ_DW,
193                         wAddress,
194                         0,
195                         &val,
196                         sizeof(u32),
197                         B2C2_WAIT_FOR_OPERATION_RDW * 1000);
198
199         if (len != sizeof(u32)) {
200                 err("error while reading dword from %d (%d).",wAddress,wRegOffsPCI);
201                 return -EIO;
202         } else
203                 return val;
204 }
205
206 /*
207  * DKT 020228 - from now on, we don't support anything older than firm 1.00
208  * I eliminated the write register as a 2 trip of writing hi word and lo word
209  * and force this to write only 4 bytes at a time.
210  * NOTE: this should work with all the firmware from 1.00 and newer
211  */
212 static int b2c2_usb_write_dw(struct usb_b2c2_usb *b2c2, u16 wRegOffsPCI, u32 val)
213 {
214         u16 wAddress = B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(wRegOffsPCI);
215         int len = usb_control_msg(b2c2->udev,
216                         B2C2_USB_CTRL_PIPE_OUT,
217                         B2C2_USB_WRITE_REG,
218                         RTYPE_WRITE_DW_1,
219                         wAddress,
220                         0,
221                         &val,
222                         sizeof(u32),
223                         B2C2_WAIT_FOR_OPERATION_RDW * 1000);
224
225         if (len != sizeof(u32)) {
226                 err("error while reading dword from %d (%d).",wAddress,wRegOffsPCI);
227                 return -EIO;
228         } else
229                 return 0;
230 }
231
232 /*
233  * DKT 010817 - add support for V8 memory read/write and flash update
234  */
235 static int b2c2_usb_v8_memory_req(struct usb_b2c2_usb *b2c2,
236                 b2c2_usb_request_t req, u8 page, u16 wAddress,
237                 u16 buflen, u8 *pbBuffer)
238 {
239         u8 dwRequestType;
240         u16 wIndex;
241         int nWaitTime,pipe,len;
242
243         wIndex = page << 8;
244
245         switch (req) {
246                 case B2C2_USB_READ_V8_MEM:
247                         nWaitTime = B2C2_WAIT_FOR_OPERATION_V8READ;
248                         dwRequestType = (u8) RTYPE_READ_V8_MEMORY;
249                         pipe = B2C2_USB_CTRL_PIPE_IN;
250                 break;
251                 case B2C2_USB_WRITE_V8_MEM:
252                         wIndex |= pbBuffer[0];
253                         nWaitTime = B2C2_WAIT_FOR_OPERATION_V8WRITE;
254                         dwRequestType = (u8) RTYPE_WRITE_V8_MEMORY;
255                         pipe = B2C2_USB_CTRL_PIPE_OUT;
256                 break;
257                 case B2C2_USB_FLASH_BLOCK:
258                         nWaitTime = B2C2_WAIT_FOR_OPERATION_V8FLASH;
259                         dwRequestType = (u8) RTYPE_WRITE_V8_FLASH;
260                         pipe = B2C2_USB_CTRL_PIPE_OUT;
261                 break;
262                 default:
263                         deb_info("unsupported request for v8_mem_req %x.\n",req);
264                 return -EINVAL;
265         }
266         len = usb_control_msg(b2c2->udev,pipe,
267                         req,
268                         dwRequestType,
269                         wAddress,
270                         wIndex,
271                         pbBuffer,
272                         buflen,
273                         nWaitTime * 1000);
274         return len == buflen ? 0 : -EIO;
275 }
276
277 static int b2c2_usb_i2c_req(struct usb_b2c2_usb *b2c2,
278                 b2c2_usb_request_t req, b2c2_usb_i2c_function_t func,
279                 u8 port, u8 chipaddr, u8 addr, u8 buflen, u8 *buf)
280 {
281         u16 wValue, wIndex;
282         int nWaitTime,pipe,len;
283         u8 dwRequestType;
284
285         switch (func) {
286                 case USB_FUNC_I2C_WRITE:
287                 case USB_FUNC_I2C_MULTIWRITE:
288                 case USB_FUNC_I2C_REPEATWRITE:
289                 /* DKT 020208 - add this to support special case of DiSEqC */
290                 case USB_FUNC_I2C_CHECKWRITE:
291                         pipe = B2C2_USB_CTRL_PIPE_OUT;
292                         nWaitTime = 2;
293                         dwRequestType = (u8) RTYPE_GENERIC;
294                 break;
295                 case USB_FUNC_I2C_READ:
296                 case USB_FUNC_I2C_REPEATREAD:
297                         pipe = B2C2_USB_CTRL_PIPE_IN;
298                         nWaitTime = 2;
299                         dwRequestType = (u8) RTYPE_GENERIC;
300                 break;
301                 default:
302                         deb_info("unsupported function for i2c_req %x\n",func);
303                         return -EINVAL;
304         }
305         wValue = (func << 8 ) | port;
306         wIndex = (chipaddr << 8 ) | addr;
307
308         len = usb_control_msg(b2c2->udev,pipe,
309                         req,
310                         dwRequestType,
311                         addr,
312                         wIndex,
313                         buf,
314                         buflen,
315                         nWaitTime * 1000);
316         return len == buflen ? 0 : -EIO;
317 }
318
319 int static b2c2_usb_utility_req(struct usb_b2c2_usb *b2c2, int set,
320                 b2c2_usb_utility_function_t func, u8 extra, u16 wIndex,
321                 u16 buflen, u8 *pvBuffer)
322 {
323         u16 wValue;
324         int nWaitTime = 2,
325                 pipe = set ? B2C2_USB_CTRL_PIPE_OUT : B2C2_USB_CTRL_PIPE_IN,
326                 len;
327
328         wValue = (func << 8) | extra;
329
330         len = usb_control_msg(b2c2->udev,pipe,
331                         B2C2_USB_UTILITY,
332                         (u8) RTYPE_GENERIC,
333                         wValue,
334                         wIndex,
335                         pvBuffer,
336                         buflen,
337                         nWaitTime * 1000);
338         return len == buflen ? 0 : -EIO;
339 }
340
341
342
343 static void b2c2_dumpfourreg(struct usb_b2c2_usb *b2c2, u16 offs)
344 {
345         u32 r0,r1,r2,r3;
346         r0 = r1 = r2 = r3 = 0;
347         r0 = b2c2_usb_read_dw(b2c2,offs);
348         r1 = b2c2_usb_read_dw(b2c2,offs + 0x04);
349         r2 = b2c2_usb_read_dw(b2c2,offs + 0x08);
350         r3 = b2c2_usb_read_dw(b2c2,offs + 0x0c);
351         deb_ctrl("dump: offset: %03x, %08x, %08x, %08x, %08x\n",offs,r0,r1,r2,r3);
352 }
353
354 static void b2c2_urb_complete(struct urb *urb, struct pt_regs *ptregs)
355 {
356         struct usb_b2c2_usb *b2c2 = urb->context;
357         deb_ts("urb completed, bufsize: %d\n",urb->transfer_buffer_length);
358
359 //      urb_submit_urb(urb,GFP_ATOMIC); enable for real action
360 }
361
362 static void b2c2_exit_usb(struct usb_b2c2_usb *b2c2)
363 {
364         int i;
365         for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++)
366                 if (b2c2->iso_urb[i] != NULL) { /* not sure about unlink_urb and iso-urbs TODO */
367                         deb_info("unlinking/killing urb no. %d\n",i);
368 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,7)
369                         usb_unlink_urb(b2c2->iso_urb[i]);
370 #else
371                         usb_kill_urb(b2c2->iso_urb[i]);
372 #endif
373                         usb_free_urb(b2c2->iso_urb[i]);
374                 }
375
376         if (b2c2->iso_buffer != NULL)
377                 pci_free_consistent(NULL,b2c2->buffer_size, b2c2->iso_buffer, b2c2->iso_dma_handle);
378
379 }
380
381 static int b2c2_init_usb(struct usb_b2c2_usb *b2c2)
382 {
383         u16 frame_size = le16_to_cpu(b2c2->uintf->cur_altsetting->endpoint[0].desc.wMaxPacketSize);
384         int bufsize = B2C2_USB_NUM_ISO_URB * B2C2_USB_FRAMES_PER_ISO * frame_size,i,j,ret;
385         int buffer_offset = 0;
386
387         deb_info("creating %d iso-urbs with %d frames each of %d bytes size = %d.\n",
388                         B2C2_USB_NUM_ISO_URB, B2C2_USB_FRAMES_PER_ISO, frame_size,bufsize);
389
390         b2c2->iso_buffer = pci_alloc_consistent(NULL,bufsize,&b2c2->iso_dma_handle);
391         if (b2c2->iso_buffer == NULL)
392                 return -ENOMEM;
393         memset(b2c2->iso_buffer, 0, bufsize);
394         b2c2->buffer_size = bufsize;
395
396         /* creating iso urbs */
397         for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++)
398                 if (!(b2c2->iso_urb[i] = usb_alloc_urb(B2C2_USB_FRAMES_PER_ISO,GFP_ATOMIC))) {
399                         ret = -ENOMEM;
400                         goto urb_error;
401                 }
402         /* initialising and submitting iso urbs */
403         for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++) {
404                 int frame_offset = 0;
405                 struct urb *urb = b2c2->iso_urb[i];
406                 deb_info("initializing and submitting urb no. %d (buf_offset: %d).\n",i,buffer_offset);
407
408                 urb->dev = b2c2->udev;
409                 urb->context = b2c2;
410                 urb->complete = b2c2_urb_complete;
411                 urb->pipe = B2C2_USB_DATA_PIPE;
412                 urb->transfer_flags = URB_ISO_ASAP;
413                 urb->interval = 1;
414                 urb->number_of_packets = B2C2_USB_FRAMES_PER_ISO;
415                 urb->transfer_buffer_length = frame_size * B2C2_USB_FRAMES_PER_ISO;
416                 urb->transfer_buffer = b2c2->iso_buffer + buffer_offset;
417
418                 buffer_offset += frame_size * B2C2_USB_FRAMES_PER_ISO;
419                 for (j = 0; j < B2C2_USB_FRAMES_PER_ISO; j++) {
420                         deb_info("urb no: %d, frame: %d, frame_offset: %d\n",i,j,frame_offset);
421                         urb->iso_frame_desc[j].offset = frame_offset;
422                         urb->iso_frame_desc[j].length = frame_size;
423                         frame_offset += frame_size;
424                 }
425
426                 if ((ret = usb_submit_urb(b2c2->iso_urb[i],GFP_ATOMIC))) {
427                         err("submitting urb %d failed with %d.",i,ret);
428                         goto urb_error;
429                 }
430                 deb_info("submitted urb no. %d.\n",i);
431         }
432
433         ret = 0;
434         goto success;
435 urb_error:
436         b2c2_exit_usb(b2c2);
437 success:
438         return ret;
439 }
440
441 static int b2c2_usb_probe(struct usb_interface *intf,
442                 const struct usb_device_id *id)
443 {
444         struct usb_device *udev = interface_to_usbdev(intf);
445         struct usb_b2c2_usb *b2c2 = NULL;
446         int ret;
447
448         b2c2 = kmalloc(sizeof(struct usb_b2c2_usb),GFP_KERNEL);
449         if (b2c2 == NULL) {
450                 err("no memory");
451                 return -ENOMEM;
452         }
453         b2c2->udev = udev;
454         b2c2->uintf = intf;
455
456         /* use the alternate setting with the larges buffer */
457         usb_set_interface(udev,0,1);
458
459         if ((ret = b2c2_init_usb(b2c2)))
460                 goto usb_init_error;
461
462         usb_set_intfdata(intf,b2c2);
463
464         switch (udev->speed) {
465                 case USB_SPEED_LOW:
466                         err("cannot handle USB speed because it is to sLOW.");
467                         break;
468                 case USB_SPEED_FULL:
469                         info("running at FULL speed.");
470                         break;
471                 case USB_SPEED_HIGH:
472                         info("running at HIGH speed.");
473                         break;
474                 case USB_SPEED_UNKNOWN: /* fall through */
475                 default:
476                         err("cannot handle USB speed because it is unkown.");
477                 break;
478         }
479
480         b2c2_dumpfourreg(b2c2,0x200);
481         b2c2_dumpfourreg(b2c2,0x300);
482         b2c2_dumpfourreg(b2c2,0x400);
483         b2c2_dumpfourreg(b2c2,0x700);
484
485
486         if (ret == 0)
487                 info("%s successfully initialized and connected.",DRIVER_DESC);
488         else
489                 info("%s error while loading driver (%d)",DRIVER_DESC,ret);
490
491         ret = 0;
492         goto success;
493
494 usb_init_error:
495         kfree(b2c2);
496 success:
497         return ret;
498 }
499
500 static void b2c2_usb_disconnect(struct usb_interface *intf)
501 {
502         struct usb_b2c2_usb *b2c2 = usb_get_intfdata(intf);
503         usb_set_intfdata(intf,NULL);
504         if (b2c2 != NULL) {
505                 b2c2_exit_usb(b2c2);
506                 kfree(b2c2);
507         }
508         info("%s successfully deinitialized and disconnected.",DRIVER_DESC);
509
510 }
511
512 static struct usb_device_id b2c2_usb_table [] = {
513             { USB_DEVICE(0x0af7, 0x0101) }
514 };
515
516 /* usb specific object needed to register this driver with the usb subsystem */
517 static struct usb_driver b2c2_usb_driver = {
518         .owner          = THIS_MODULE,
519         .name           = "dvb_b2c2_usb",
520         .probe          = b2c2_usb_probe,
521         .disconnect = b2c2_usb_disconnect,
522         .id_table       = b2c2_usb_table,
523 };
524
525 /* module stuff */
526 static int __init b2c2_usb_init(void)
527 {
528         int result;
529         if ((result = usb_register(&b2c2_usb_driver))) {
530                 err("usb_register failed. Error number %d",result);
531                 return result;
532         }
533
534         return 0;
535 }
536
537 static void __exit b2c2_usb_exit(void)
538 {
539         /* deregister this driver from the USB subsystem */
540         usb_deregister(&b2c2_usb_driver);
541 }
542
543 module_init (b2c2_usb_init);
544 module_exit (b2c2_usb_exit);
545
546 MODULE_AUTHOR(DRIVER_AUTHOR);
547 MODULE_DESCRIPTION(DRIVER_DESC);
548 MODULE_LICENSE("GPL");
549 MODULE_DEVICE_TABLE(usb, b2c2_usb_table);