1/* 2 * Abilis Systems Single DVB-T Receiver 3 * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com> 4 * Copyright (C) 2010 Devin Heitmueller <dheitmueller@kernellabs.com> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2, or (at your option) 9 * any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 */ 16#include <linux/kernel.h> 17#include <linux/errno.h> 18#include <linux/slab.h> 19#include <linux/mm.h> 20#include <linux/usb.h> 21 22#include "as102_drv.h" 23#include "as102_usb_drv.h" 24#include "as102_fw.h" 25 26static void as102_usb_disconnect(struct usb_interface *interface); 27static int as102_usb_probe(struct usb_interface *interface, 28 const struct usb_device_id *id); 29 30static int as102_usb_start_stream(struct as102_dev_t *dev); 31static void as102_usb_stop_stream(struct as102_dev_t *dev); 32 33static int as102_open(struct inode *inode, struct file *file); 34static int as102_release(struct inode *inode, struct file *file); 35 36static struct usb_device_id as102_usb_id_table[] = { 37 { USB_DEVICE(AS102_USB_DEVICE_VENDOR_ID, AS102_USB_DEVICE_PID_0001) }, 38 { USB_DEVICE(PCTV_74E_USB_VID, PCTV_74E_USB_PID) }, 39 { USB_DEVICE(ELGATO_EYETV_DTT_USB_VID, ELGATO_EYETV_DTT_USB_PID) }, 40 { USB_DEVICE(NBOX_DVBT_DONGLE_USB_VID, NBOX_DVBT_DONGLE_USB_PID) }, 41 { USB_DEVICE(SKY_IT_DIGITAL_KEY_USB_VID, SKY_IT_DIGITAL_KEY_USB_PID) }, 42 { } /* Terminating entry */ 43}; 44 45/* Note that this table must always have the same number of entries as the 46 as102_usb_id_table struct */ 47static const char * const as102_device_names[] = { 48 AS102_REFERENCE_DESIGN, 49 AS102_PCTV_74E, 50 AS102_ELGATO_EYETV_DTT_NAME, 51 AS102_NBOX_DVBT_DONGLE_NAME, 52 AS102_SKY_IT_DIGITAL_KEY_NAME, 53 NULL /* Terminating entry */ 54}; 55 56/* eLNA configuration: devices built on the reference design work best 57 with 0xA0, while custom designs seem to require 0xC0 */ 58static uint8_t const as102_elna_cfg[] = { 59 0xA0, 60 0xC0, 61 0xC0, 62 0xA0, 63 0xA0, 64 0x00 /* Terminating entry */ 65}; 66 67struct usb_driver as102_usb_driver = { 68 .name = DRIVER_FULL_NAME, 69 .probe = as102_usb_probe, 70 .disconnect = as102_usb_disconnect, 71 .id_table = as102_usb_id_table 72}; 73 74static const struct file_operations as102_dev_fops = { 75 .owner = THIS_MODULE, 76 .open = as102_open, 77 .release = as102_release, 78}; 79 80static struct usb_class_driver as102_usb_class_driver = { 81 .name = "aton2-%d", 82 .fops = &as102_dev_fops, 83 .minor_base = AS102_DEVICE_MAJOR, 84}; 85 86static int as102_usb_xfer_cmd(struct as10x_bus_adapter_t *bus_adap, 87 unsigned char *send_buf, int send_buf_len, 88 unsigned char *recv_buf, int recv_buf_len) 89{ 90 int ret = 0; 91 92 if (send_buf != NULL) { 93 ret = usb_control_msg(bus_adap->usb_dev, 94 usb_sndctrlpipe(bus_adap->usb_dev, 0), 95 AS102_USB_DEVICE_TX_CTRL_CMD, 96 USB_DIR_OUT | USB_TYPE_VENDOR | 97 USB_RECIP_DEVICE, 98 bus_adap->cmd_xid, /* value */ 99 0, /* index */ 100 send_buf, send_buf_len, 101 USB_CTRL_SET_TIMEOUT /* 200 */); 102 if (ret < 0) { 103 dev_dbg(&bus_adap->usb_dev->dev, 104 "usb_control_msg(send) failed, err %i\n", ret); 105 return ret; 106 } 107 108 if (ret != send_buf_len) { 109 dev_dbg(&bus_adap->usb_dev->dev, 110 "only wrote %d of %d bytes\n", ret, send_buf_len); 111 return -1; 112 } 113 } 114 115 if (recv_buf != NULL) { 116#ifdef TRACE 117 dev_dbg(bus_adap->usb_dev->dev, 118 "want to read: %d bytes\n", recv_buf_len); 119#endif 120 ret = usb_control_msg(bus_adap->usb_dev, 121 usb_rcvctrlpipe(bus_adap->usb_dev, 0), 122 AS102_USB_DEVICE_RX_CTRL_CMD, 123 USB_DIR_IN | USB_TYPE_VENDOR | 124 USB_RECIP_DEVICE, 125 bus_adap->cmd_xid, /* value */ 126 0, /* index */ 127 recv_buf, recv_buf_len, 128 USB_CTRL_GET_TIMEOUT /* 200 */); 129 if (ret < 0) { 130 dev_dbg(&bus_adap->usb_dev->dev, 131 "usb_control_msg(recv) failed, err %i\n", ret); 132 return ret; 133 } 134#ifdef TRACE 135 dev_dbg(bus_adap->usb_dev->dev, 136 "read %d bytes\n", recv_buf_len); 137#endif 138 } 139 140 return ret; 141} 142 143static int as102_send_ep1(struct as10x_bus_adapter_t *bus_adap, 144 unsigned char *send_buf, 145 int send_buf_len, 146 int swap32) 147{ 148 int ret, actual_len; 149 150 ret = usb_bulk_msg(bus_adap->usb_dev, 151 usb_sndbulkpipe(bus_adap->usb_dev, 1), 152 send_buf, send_buf_len, &actual_len, 200); 153 if (ret) { 154 dev_dbg(&bus_adap->usb_dev->dev, 155 "usb_bulk_msg(send) failed, err %i\n", ret); 156 return ret; 157 } 158 159 if (actual_len != send_buf_len) { 160 dev_dbg(&bus_adap->usb_dev->dev, "only wrote %d of %d bytes\n", 161 actual_len, send_buf_len); 162 return -1; 163 } 164 return actual_len; 165} 166 167static int as102_read_ep2(struct as10x_bus_adapter_t *bus_adap, 168 unsigned char *recv_buf, int recv_buf_len) 169{ 170 int ret, actual_len; 171 172 if (recv_buf == NULL) 173 return -EINVAL; 174 175 ret = usb_bulk_msg(bus_adap->usb_dev, 176 usb_rcvbulkpipe(bus_adap->usb_dev, 2), 177 recv_buf, recv_buf_len, &actual_len, 200); 178 if (ret) { 179 dev_dbg(&bus_adap->usb_dev->dev, 180 "usb_bulk_msg(recv) failed, err %i\n", ret); 181 return ret; 182 } 183 184 if (actual_len != recv_buf_len) { 185 dev_dbg(&bus_adap->usb_dev->dev, "only read %d of %d bytes\n", 186 actual_len, recv_buf_len); 187 return -1; 188 } 189 return actual_len; 190} 191 192static struct as102_priv_ops_t as102_priv_ops = { 193 .upload_fw_pkt = as102_send_ep1, 194 .xfer_cmd = as102_usb_xfer_cmd, 195 .as102_read_ep2 = as102_read_ep2, 196 .start_stream = as102_usb_start_stream, 197 .stop_stream = as102_usb_stop_stream, 198}; 199 200static int as102_submit_urb_stream(struct as102_dev_t *dev, struct urb *urb) 201{ 202 int err; 203 204 usb_fill_bulk_urb(urb, 205 dev->bus_adap.usb_dev, 206 usb_rcvbulkpipe(dev->bus_adap.usb_dev, 0x2), 207 urb->transfer_buffer, 208 AS102_USB_BUF_SIZE, 209 as102_urb_stream_irq, 210 dev); 211 212 err = usb_submit_urb(urb, GFP_ATOMIC); 213 if (err) 214 dev_dbg(&urb->dev->dev, 215 "%s: usb_submit_urb failed\n", __func__); 216 217 return err; 218} 219 220void as102_urb_stream_irq(struct urb *urb) 221{ 222 struct as102_dev_t *as102_dev = urb->context; 223 224 if (urb->actual_length > 0) { 225 dvb_dmx_swfilter(&as102_dev->dvb_dmx, 226 urb->transfer_buffer, 227 urb->actual_length); 228 } else { 229 if (urb->actual_length == 0) 230 memset(urb->transfer_buffer, 0, AS102_USB_BUF_SIZE); 231 } 232 233 /* is not stopped, re-submit urb */ 234 if (as102_dev->streaming) 235 as102_submit_urb_stream(as102_dev, urb); 236} 237 238static void as102_free_usb_stream_buffer(struct as102_dev_t *dev) 239{ 240 int i; 241 242 for (i = 0; i < MAX_STREAM_URB; i++) 243 usb_free_urb(dev->stream_urb[i]); 244 245 usb_free_coherent(dev->bus_adap.usb_dev, 246 MAX_STREAM_URB * AS102_USB_BUF_SIZE, 247 dev->stream, 248 dev->dma_addr); 249} 250 251static int as102_alloc_usb_stream_buffer(struct as102_dev_t *dev) 252{ 253 int i; 254 255 dev->stream = usb_alloc_coherent(dev->bus_adap.usb_dev, 256 MAX_STREAM_URB * AS102_USB_BUF_SIZE, 257 GFP_KERNEL, 258 &dev->dma_addr); 259 if (!dev->stream) { 260 dev_dbg(&dev->bus_adap.usb_dev->dev, 261 "%s: usb_buffer_alloc failed\n", __func__); 262 return -ENOMEM; 263 } 264 265 memset(dev->stream, 0, MAX_STREAM_URB * AS102_USB_BUF_SIZE); 266 267 /* init urb buffers */ 268 for (i = 0; i < MAX_STREAM_URB; i++) { 269 struct urb *urb; 270 271 urb = usb_alloc_urb(0, GFP_ATOMIC); 272 if (urb == NULL) { 273 dev_dbg(&dev->bus_adap.usb_dev->dev, 274 "%s: usb_alloc_urb failed\n", __func__); 275 as102_free_usb_stream_buffer(dev); 276 return -ENOMEM; 277 } 278 279 urb->transfer_buffer = dev->stream + (i * AS102_USB_BUF_SIZE); 280 urb->transfer_dma = dev->dma_addr + (i * AS102_USB_BUF_SIZE); 281 urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP; 282 urb->transfer_buffer_length = AS102_USB_BUF_SIZE; 283 284 dev->stream_urb[i] = urb; 285 } 286 return 0; 287} 288 289static void as102_usb_stop_stream(struct as102_dev_t *dev) 290{ 291 int i; 292 293 for (i = 0; i < MAX_STREAM_URB; i++) 294 usb_kill_urb(dev->stream_urb[i]); 295} 296 297static int as102_usb_start_stream(struct as102_dev_t *dev) 298{ 299 int i, ret = 0; 300 301 for (i = 0; i < MAX_STREAM_URB; i++) { 302 ret = as102_submit_urb_stream(dev, dev->stream_urb[i]); 303 if (ret) { 304 as102_usb_stop_stream(dev); 305 return ret; 306 } 307 } 308 309 return 0; 310} 311 312static void as102_usb_release(struct kref *kref) 313{ 314 struct as102_dev_t *as102_dev; 315 316 as102_dev = container_of(kref, struct as102_dev_t, kref); 317 if (as102_dev != NULL) { 318 usb_put_dev(as102_dev->bus_adap.usb_dev); 319 kfree(as102_dev); 320 } 321} 322 323static void as102_usb_disconnect(struct usb_interface *intf) 324{ 325 struct as102_dev_t *as102_dev; 326 327 /* extract as102_dev_t from usb_device private data */ 328 as102_dev = usb_get_intfdata(intf); 329 330 /* unregister dvb layer */ 331 as102_dvb_unregister(as102_dev); 332 333 /* free usb buffers */ 334 as102_free_usb_stream_buffer(as102_dev); 335 336 usb_set_intfdata(intf, NULL); 337 338 /* usb unregister device */ 339 usb_deregister_dev(intf, &as102_usb_class_driver); 340 341 /* decrement usage counter */ 342 kref_put(&as102_dev->kref, as102_usb_release); 343 344 pr_info("%s: device has been disconnected\n", DRIVER_NAME); 345} 346 347static int as102_usb_probe(struct usb_interface *intf, 348 const struct usb_device_id *id) 349{ 350 int ret; 351 struct as102_dev_t *as102_dev; 352 int i; 353 354 /* This should never actually happen */ 355 if (ARRAY_SIZE(as102_usb_id_table) != 356 (sizeof(as102_device_names) / sizeof(const char *))) { 357 pr_err("Device names table invalid size"); 358 return -EINVAL; 359 } 360 361 as102_dev = kzalloc(sizeof(struct as102_dev_t), GFP_KERNEL); 362 if (as102_dev == NULL) 363 return -ENOMEM; 364 365 /* Assign the user-friendly device name */ 366 for (i = 0; i < ARRAY_SIZE(as102_usb_id_table); i++) { 367 if (id == &as102_usb_id_table[i]) { 368 as102_dev->name = as102_device_names[i]; 369 as102_dev->elna_cfg = as102_elna_cfg[i]; 370 } 371 } 372 373 if (as102_dev->name == NULL) 374 as102_dev->name = "Unknown AS102 device"; 375 376 /* set private callback functions */ 377 as102_dev->bus_adap.ops = &as102_priv_ops; 378 379 /* init cmd token for usb bus */ 380 as102_dev->bus_adap.cmd = &as102_dev->bus_adap.token.usb.c; 381 as102_dev->bus_adap.rsp = &as102_dev->bus_adap.token.usb.r; 382 383 /* init kernel device reference */ 384 kref_init(&as102_dev->kref); 385 386 /* store as102 device to usb_device private data */ 387 usb_set_intfdata(intf, (void *) as102_dev); 388 389 /* store in as102 device the usb_device pointer */ 390 as102_dev->bus_adap.usb_dev = usb_get_dev(interface_to_usbdev(intf)); 391 392 /* we can register the device now, as it is ready */ 393 ret = usb_register_dev(intf, &as102_usb_class_driver); 394 if (ret < 0) { 395 /* something prevented us from registering this driver */ 396 dev_err(&intf->dev, 397 "%s: usb_register_dev() failed (errno = %d)\n", 398 __func__, ret); 399 goto failed; 400 } 401 402 pr_info("%s: device has been detected\n", DRIVER_NAME); 403 404 /* request buffer allocation for streaming */ 405 ret = as102_alloc_usb_stream_buffer(as102_dev); 406 if (ret != 0) 407 goto failed_stream; 408 409 /* register dvb layer */ 410 ret = as102_dvb_register(as102_dev); 411 if (ret != 0) 412 goto failed_dvb; 413 414 return ret; 415 416failed_dvb: 417 as102_free_usb_stream_buffer(as102_dev); 418failed_stream: 419 usb_deregister_dev(intf, &as102_usb_class_driver); 420failed: 421 usb_put_dev(as102_dev->bus_adap.usb_dev); 422 usb_set_intfdata(intf, NULL); 423 kfree(as102_dev); 424 return ret; 425} 426 427static int as102_open(struct inode *inode, struct file *file) 428{ 429 int ret = 0, minor = 0; 430 struct usb_interface *intf = NULL; 431 struct as102_dev_t *dev = NULL; 432 433 /* read minor from inode */ 434 minor = iminor(inode); 435 436 /* fetch device from usb interface */ 437 intf = usb_find_interface(&as102_usb_driver, minor); 438 if (intf == NULL) { 439 pr_err("%s: can't find device for minor %d\n", 440 __func__, minor); 441 ret = -ENODEV; 442 goto exit; 443 } 444 445 /* get our device */ 446 dev = usb_get_intfdata(intf); 447 if (dev == NULL) { 448 ret = -EFAULT; 449 goto exit; 450 } 451 452 /* save our device object in the file's private structure */ 453 file->private_data = dev; 454 455 /* increment our usage count for the device */ 456 kref_get(&dev->kref); 457 458exit: 459 return ret; 460} 461 462static int as102_release(struct inode *inode, struct file *file) 463{ 464 struct as102_dev_t *dev = NULL; 465 466 dev = file->private_data; 467 if (dev != NULL) { 468 /* decrement the count on our device */ 469 kref_put(&dev->kref, as102_usb_release); 470 } 471 472 return 0; 473} 474 475MODULE_DEVICE_TABLE(usb, as102_usb_id_table); 476