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