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 26 static void as102_usb_disconnect(struct usb_interface *interface); 27 static int as102_usb_probe(struct usb_interface *interface, 28 const struct usb_device_id *id); 29 30 static int as102_usb_start_stream(struct as102_dev_t *dev); 31 static void as102_usb_stop_stream(struct as102_dev_t *dev); 32 33 static int as102_open(struct inode *inode, struct file *file); 34 static int as102_release(struct inode *inode, struct file *file); 35 36 static 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 */ 47 static 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 */ 58 static uint8_t const as102_elna_cfg[] = { 59 0xA0, 60 0xC0, 61 0xC0, 62 0xA0, 63 0xA0, 64 0x00 /* Terminating entry */ 65 }; 66 67 struct 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 74 static const struct file_operations as102_dev_fops = { 75 .owner = THIS_MODULE, 76 .open = as102_open, 77 .release = as102_release, 78 }; 79 80 static 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 86 static 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 143 static 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 167 static 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 192 static const 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 200 static 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 220 void 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 238 static 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 251 static 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 as102_free_usb_stream_buffer(dev); 274 return -ENOMEM; 275 } 276 277 urb->transfer_buffer = dev->stream + (i * AS102_USB_BUF_SIZE); 278 urb->transfer_dma = dev->dma_addr + (i * AS102_USB_BUF_SIZE); 279 urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP; 280 urb->transfer_buffer_length = AS102_USB_BUF_SIZE; 281 282 dev->stream_urb[i] = urb; 283 } 284 return 0; 285 } 286 287 static void as102_usb_stop_stream(struct as102_dev_t *dev) 288 { 289 int i; 290 291 for (i = 0; i < MAX_STREAM_URB; i++) 292 usb_kill_urb(dev->stream_urb[i]); 293 } 294 295 static int as102_usb_start_stream(struct as102_dev_t *dev) 296 { 297 int i, ret = 0; 298 299 for (i = 0; i < MAX_STREAM_URB; i++) { 300 ret = as102_submit_urb_stream(dev, dev->stream_urb[i]); 301 if (ret) { 302 as102_usb_stop_stream(dev); 303 return ret; 304 } 305 } 306 307 return 0; 308 } 309 310 static void as102_usb_release(struct kref *kref) 311 { 312 struct as102_dev_t *as102_dev; 313 314 as102_dev = container_of(kref, struct as102_dev_t, kref); 315 if (as102_dev != NULL) { 316 usb_put_dev(as102_dev->bus_adap.usb_dev); 317 kfree(as102_dev); 318 } 319 } 320 321 static void as102_usb_disconnect(struct usb_interface *intf) 322 { 323 struct as102_dev_t *as102_dev; 324 325 /* extract as102_dev_t from usb_device private data */ 326 as102_dev = usb_get_intfdata(intf); 327 328 /* unregister dvb layer */ 329 as102_dvb_unregister(as102_dev); 330 331 /* free usb buffers */ 332 as102_free_usb_stream_buffer(as102_dev); 333 334 usb_set_intfdata(intf, NULL); 335 336 /* usb unregister device */ 337 usb_deregister_dev(intf, &as102_usb_class_driver); 338 339 /* decrement usage counter */ 340 kref_put(&as102_dev->kref, as102_usb_release); 341 342 pr_info("%s: device has been disconnected\n", DRIVER_NAME); 343 } 344 345 static int as102_usb_probe(struct usb_interface *intf, 346 const struct usb_device_id *id) 347 { 348 int ret; 349 struct as102_dev_t *as102_dev; 350 int i; 351 352 /* This should never actually happen */ 353 if (ARRAY_SIZE(as102_usb_id_table) != 354 (sizeof(as102_device_names) / sizeof(const char *))) { 355 pr_err("Device names table invalid size"); 356 return -EINVAL; 357 } 358 359 as102_dev = kzalloc(sizeof(struct as102_dev_t), GFP_KERNEL); 360 if (as102_dev == NULL) 361 return -ENOMEM; 362 363 /* Assign the user-friendly device name */ 364 for (i = 0; i < ARRAY_SIZE(as102_usb_id_table); i++) { 365 if (id == &as102_usb_id_table[i]) { 366 as102_dev->name = as102_device_names[i]; 367 as102_dev->elna_cfg = as102_elna_cfg[i]; 368 } 369 } 370 371 if (as102_dev->name == NULL) 372 as102_dev->name = "Unknown AS102 device"; 373 374 /* set private callback functions */ 375 as102_dev->bus_adap.ops = &as102_priv_ops; 376 377 /* init cmd token for usb bus */ 378 as102_dev->bus_adap.cmd = &as102_dev->bus_adap.token.usb.c; 379 as102_dev->bus_adap.rsp = &as102_dev->bus_adap.token.usb.r; 380 381 /* init kernel device reference */ 382 kref_init(&as102_dev->kref); 383 384 /* store as102 device to usb_device private data */ 385 usb_set_intfdata(intf, (void *) as102_dev); 386 387 /* store in as102 device the usb_device pointer */ 388 as102_dev->bus_adap.usb_dev = usb_get_dev(interface_to_usbdev(intf)); 389 390 /* we can register the device now, as it is ready */ 391 ret = usb_register_dev(intf, &as102_usb_class_driver); 392 if (ret < 0) { 393 /* something prevented us from registering this driver */ 394 dev_err(&intf->dev, 395 "%s: usb_register_dev() failed (errno = %d)\n", 396 __func__, ret); 397 goto failed; 398 } 399 400 pr_info("%s: device has been detected\n", DRIVER_NAME); 401 402 /* request buffer allocation for streaming */ 403 ret = as102_alloc_usb_stream_buffer(as102_dev); 404 if (ret != 0) 405 goto failed_stream; 406 407 /* register dvb layer */ 408 ret = as102_dvb_register(as102_dev); 409 if (ret != 0) 410 goto failed_dvb; 411 412 return ret; 413 414 failed_dvb: 415 as102_free_usb_stream_buffer(as102_dev); 416 failed_stream: 417 usb_deregister_dev(intf, &as102_usb_class_driver); 418 failed: 419 usb_put_dev(as102_dev->bus_adap.usb_dev); 420 usb_set_intfdata(intf, NULL); 421 kfree(as102_dev); 422 return ret; 423 } 424 425 static int as102_open(struct inode *inode, struct file *file) 426 { 427 int ret = 0, minor = 0; 428 struct usb_interface *intf = NULL; 429 struct as102_dev_t *dev = NULL; 430 431 /* read minor from inode */ 432 minor = iminor(inode); 433 434 /* fetch device from usb interface */ 435 intf = usb_find_interface(&as102_usb_driver, minor); 436 if (intf == NULL) { 437 pr_err("%s: can't find device for minor %d\n", 438 __func__, minor); 439 ret = -ENODEV; 440 goto exit; 441 } 442 443 /* get our device */ 444 dev = usb_get_intfdata(intf); 445 if (dev == NULL) { 446 ret = -EFAULT; 447 goto exit; 448 } 449 450 /* save our device object in the file's private structure */ 451 file->private_data = dev; 452 453 /* increment our usage count for the device */ 454 kref_get(&dev->kref); 455 456 exit: 457 return ret; 458 } 459 460 static int as102_release(struct inode *inode, struct file *file) 461 { 462 struct as102_dev_t *dev = NULL; 463 464 dev = file->private_data; 465 if (dev != NULL) { 466 /* decrement the count on our device */ 467 kref_put(&dev->kref, as102_usb_release); 468 } 469 470 return 0; 471 } 472 473 MODULE_DEVICE_TABLE(usb, as102_usb_id_table); 474