6 #define FC_LOG_PREFIX "flexcop_usb"
11 #define DRIVER_VERSION "0.1"
12 #define DRIVER_NAME "Technisat/B2C2 FlexCop II/IIb/III Digital TV USB Driver"
16 #ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG
17 #define dprintk(level,args...) \
18 do { if ((debug & level)) printk(args); } while (0)
20 #define debug_dump(b, l, method) do {\
22 for (i = 0; i < l; i++) \
23 method("%02x ", b[i]); \
29 #define dprintk(level, args...)
30 #define debug_dump(b, l, method)
31 #define DEBSTATUS " (debugging is not enabled)"
37 "ctrl=4,i2c=8,v8mem=16 (or-able))." DEBSTATUS);
40 #define deb_info(args...) dprintk(0x01, args)
41 #define deb_ts(args...) dprintk(0x02, args)
42 #define deb_ctrl(args...) dprintk(0x04, args)
43 #define deb_i2c(args...) dprintk(0x08, args)
44 #define deb_v8(args...) dprintk(0x10, args)
55 #define B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(usPCI) (u8) \
56 (((usPCI >> 2) & 0x07) + ((usPCI >> 4) & 0x70))
57 #define B2C2_FLEX_INTERNALADDR_TO_PCIOFFSET(ucAddr) (u16) \
58 (((ucAddr & 0x07) << 2) + ((ucAddr & 0x70) << 4))
87 if (len !=
sizeof(
u32)) {
88 err(
"error while %s dword from %d (%d).", read ?
"reading" :
89 "writing", wAddress, wRegOffsPCI);
97 static int flexcop_usb_v8_memory_req(
struct flexcop_usb *fc_usb,
113 wIndex |= pbBuffer[0];
124 deb_info(
"unsupported request for v8_mem_req %x.\n", req);
127 deb_v8(
"v8mem: %02x %02x %04x %04x, len: %d\n", request_type, req,
128 wAddress, wIndex, buflen);
140 return len == buflen ? 0 : -
EIO;
143 #define bytes_left_to_read_on_page(paddr,buflen) \
144 ((V8_MEMORY_PAGE_SIZE - (paddr & V8_MEMORY_PAGE_MASK)) > buflen \
145 ? buflen : (V8_MEMORY_PAGE_SIZE - (paddr & V8_MEMORY_PAGE_MASK)))
147 static int flexcop_usb_memory_req(
struct flexcop_usb *fc_usb,
169 for (i = 0; i < len;) {
178 ret = flexcop_usb_v8_memory_req(fc_usb, req,
180 (addr & V8_MEMORY_PAGE_MASK) |
192 static int flexcop_usb_get_mac_addr(
struct flexcop_device *
fc,
int extended)
200 static int flexcop_usb_utility_req(
struct flexcop_usb *fc_usb,
int set,
202 u16 buflen,
u8 *pvBuffer)
208 wValue = (func << 8) | extra;
218 return len == buflen ? 0 : -
EIO;
229 int nWaitTime,
pipe,len;
249 deb_info(
"unsupported function for i2c_req %x\n", func);
252 wValue = (func << 8) | (i2c->
port << 4);
253 wIndex = (chipaddr << 8 ) | addr;
255 deb_i2c(
"i2c %2d: %02x %02x %02x %02x %02x %02x\n",
256 func, request_type, req,
257 wValue & 0xff, wValue >> 8,
258 wIndex & 0xff, wIndex >> 8);
278 flexcop_usb_readwrite_dw(fc, reg, &val.
raw, 1);
285 return flexcop_usb_readwrite_dw(fc, reg, &val.
raw, 0);
299 static void flexcop_usb_process_frame(
struct flexcop_usb *fc_usb,
305 deb_ts(
"tmp_buffer_length=%d, buffer_length=%d\n",
321 switch (*(b+1) & 0x03) {
327 deb_ts(
"not ts packet %*ph\n", 4, b+2);
332 deb_ts(
"wrong packet type\n");
347 static void flexcop_usb_urb_complete(
struct urb *
urb)
352 if (urb->actual_length > 0)
353 deb_ts(
"urb completed, bufsize: %d actlen; %d\n",
354 urb->transfer_buffer_length, urb->actual_length);
356 for (i = 0; i < urb->number_of_packets; i++) {
357 if (urb->iso_frame_desc[i].status < 0) {
358 err(
"iso frame descriptor %d has an error: %d\n", i,
359 urb->iso_frame_desc[i].status);
361 if (urb->iso_frame_desc[i].actual_length > 0) {
362 deb_ts(
"passed %d bytes to the demux\n",
363 urb->iso_frame_desc[i].actual_length);
365 flexcop_usb_process_frame(fc_usb,
366 urb->transfer_buffer +
367 urb->iso_frame_desc[i].offset,
368 urb->iso_frame_desc[i].actual_length);
370 urb->iso_frame_desc[
i].status = 0;
371 urb->iso_frame_desc[
i].actual_length = 0;
382 static void flexcop_usb_transfer_exit(
struct flexcop_usb *fc_usb)
387 deb_ts(
"unlinking/killing urb no. %d\n",i);
398 static int flexcop_usb_transfer_init(
struct flexcop_usb *fc_usb)
401 fc_usb->
uintf->cur_altsetting->endpoint[0].desc.wMaxPacketSize);
403 frame_size,
i,
j,
ret;
404 int buffer_offset = 0;
406 deb_ts(
"creating %d iso-urbs with %d frames "
407 "each of %d bytes size = %d.\n", B2C2_USB_NUM_ISO_URB,
431 struct urb *urb = fc_usb->
iso_urb[
i];
432 deb_ts(
"initializing and submitting urb no. %d "
433 "(buf_offset: %d).\n", i, buffer_offset);
435 urb->dev = fc_usb->
udev;
436 urb->context = fc_usb;
437 urb->complete = flexcop_usb_urb_complete;
439 urb->transfer_flags = URB_ISO_ASAP;
443 urb->transfer_buffer = fc_usb->
iso_buffer + buffer_offset;
447 deb_ts(
"urb no: %d, frame: %d, frame_offset: %d\n",
450 urb->iso_frame_desc[
j].length = frame_size;
451 frame_offset += frame_size;
455 err(
"submitting urb %d failed with %d.", i, ret);
458 deb_ts(
"submitted urb no. %d.\n",i);
470 flexcop_usb_transfer_exit(fc_usb);
474 static int flexcop_usb_init(
struct flexcop_usb *fc_usb)
478 switch (fc_usb->
udev->speed) {
480 err(
"cannot handle USB speed because it is too slow.");
484 info(
"running at FULL speed.");
487 info(
"running at HIGH speed.");
491 err(
"cannot handle USB speed because it is unknown.");
494 usb_set_intfdata(fc_usb->
uintf, fc_usb);
498 static void flexcop_usb_exit(
struct flexcop_usb *fc_usb)
506 struct usb_device *
udev = interface_to_usbdev(intf);
512 err(
"out of memory\n");
530 fc->
dev = &udev->dev;
536 if ((ret = flexcop_usb_init(fc_usb)) != 0)
544 if ((ret = flexcop_usb_transfer_init(fc_usb)) != 0)
553 flexcop_usb_exit(fc_usb);
559 static void flexcop_usb_disconnect(
struct usb_interface *intf)
561 struct flexcop_usb *fc_usb = usb_get_intfdata(intf);
562 flexcop_usb_transfer_exit(fc_usb);
564 flexcop_usb_exit(fc_usb);
570 { USB_DEVICE(0x0af7, 0x0101) },
576 static struct usb_driver flexcop_usb_driver = {
577 .name =
"b2c2_flexcop_usb",
578 .probe = flexcop_usb_probe,
579 .disconnect = flexcop_usb_disconnect,
580 .id_table = flexcop_usb_table,