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