GNU Linux-libre 4.14.303-gnu1
[releases.git] / drivers / media / usb / tm6000 / tm6000-dvb.c
1 /*
2  *  tm6000-dvb.c - dvb-t support for TM5600/TM6000/TM6010 USB video capture devices
3  *
4  *  Copyright (C) 2007 Michel Ludwig <michel.ludwig@gmail.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 version 2
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  */
15
16 #include <linux/kernel.h>
17 #include <linux/slab.h>
18 #include <linux/usb.h>
19
20 #include "tm6000.h"
21 #include "tm6000-regs.h"
22
23 #include "zl10353.h"
24
25 #include <media/tuner.h>
26
27 #include "tuner-xc2028.h"
28 #include "xc5000.h"
29
30 MODULE_DESCRIPTION("DVB driver extension module for tm5600/6000/6010 based TV cards");
31 MODULE_AUTHOR("Mauro Carvalho Chehab");
32 MODULE_LICENSE("GPL");
33
34 MODULE_SUPPORTED_DEVICE("{{Trident, tm5600},{{Trident, tm6000},{{Trident, tm6010}");
35
36 static int debug;
37
38 module_param(debug, int, 0644);
39 MODULE_PARM_DESC(debug, "enable debug message");
40
41 static inline void print_err_status(struct tm6000_core *dev,
42                                     int packet, int status)
43 {
44         char *errmsg = "Unknown";
45
46         switch (status) {
47         case -ENOENT:
48                 errmsg = "unlinked synchronuously";
49                 break;
50         case -ECONNRESET:
51                 errmsg = "unlinked asynchronuously";
52                 break;
53         case -ENOSR:
54                 errmsg = "Buffer error (overrun)";
55                 break;
56         case -EPIPE:
57                 errmsg = "Stalled (device not responding)";
58                 break;
59         case -EOVERFLOW:
60                 errmsg = "Babble (bad cable?)";
61                 break;
62         case -EPROTO:
63                 errmsg = "Bit-stuff error (bad cable?)";
64                 break;
65         case -EILSEQ:
66                 errmsg = "CRC/Timeout (could be anything)";
67                 break;
68         case -ETIME:
69                 errmsg = "Device does not respond";
70                 break;
71         }
72         if (packet < 0) {
73                 dprintk(dev, 1, "URB status %d [%s].\n",
74                         status, errmsg);
75         } else {
76                 dprintk(dev, 1, "URB packet %d, status %d [%s].\n",
77                         packet, status, errmsg);
78         }
79 }
80
81 static void tm6000_urb_received(struct urb *urb)
82 {
83         int ret;
84         struct tm6000_core *dev = urb->context;
85
86         switch (urb->status) {
87         case 0:
88         case -ETIMEDOUT:
89                 break;
90         case -ENOENT:
91         case -ECONNRESET:
92         case -ESHUTDOWN:
93                 return;
94         default:
95                 print_err_status(dev, 0, urb->status);
96         }
97
98         if (urb->actual_length > 0)
99                 dvb_dmx_swfilter(&dev->dvb->demux, urb->transfer_buffer,
100                                                    urb->actual_length);
101
102         if (dev->dvb->streams > 0) {
103                 ret = usb_submit_urb(urb, GFP_ATOMIC);
104                 if (ret < 0) {
105                         printk(KERN_ERR "tm6000:  error %s\n", __func__);
106                         kfree(urb->transfer_buffer);
107                         usb_free_urb(urb);
108                         dev->dvb->bulk_urb = NULL;
109                 }
110         }
111 }
112
113 static int tm6000_start_stream(struct tm6000_core *dev)
114 {
115         int ret;
116         unsigned int pipe, size;
117         struct tm6000_dvb *dvb = dev->dvb;
118
119         printk(KERN_INFO "tm6000: got start stream request %s\n", __func__);
120
121         if (dev->mode != TM6000_MODE_DIGITAL) {
122                 tm6000_init_digital_mode(dev);
123                 dev->mode = TM6000_MODE_DIGITAL;
124         }
125
126         dvb->bulk_urb = usb_alloc_urb(0, GFP_KERNEL);
127         if (dvb->bulk_urb == NULL)
128                 return -ENOMEM;
129
130         pipe = usb_rcvbulkpipe(dev->udev, dev->bulk_in.endp->desc.bEndpointAddress
131                                                           & USB_ENDPOINT_NUMBER_MASK);
132
133         size = usb_maxpacket(dev->udev, pipe, usb_pipeout(pipe));
134         size = size * 15; /* 512 x 8 or 12 or 15 */
135
136         dvb->bulk_urb->transfer_buffer = kzalloc(size, GFP_KERNEL);
137         if (dvb->bulk_urb->transfer_buffer == NULL) {
138                 usb_free_urb(dvb->bulk_urb);
139                 dvb->bulk_urb = NULL;
140                 printk(KERN_ERR "tm6000: couldn't allocate transfer buffer!\n");
141                 return -ENOMEM;
142         }
143
144         usb_fill_bulk_urb(dvb->bulk_urb, dev->udev, pipe,
145                                                  dvb->bulk_urb->transfer_buffer,
146                                                  size,
147                                                  tm6000_urb_received, dev);
148
149         ret = usb_clear_halt(dev->udev, pipe);
150         if (ret < 0) {
151                 printk(KERN_ERR "tm6000: error %i in %s during pipe reset\n",
152                                                         ret, __func__);
153
154                 kfree(dvb->bulk_urb->transfer_buffer);
155                 usb_free_urb(dvb->bulk_urb);
156                 dvb->bulk_urb = NULL;
157                 return ret;
158         } else
159                 printk(KERN_ERR "tm6000: pipe resetted\n");
160
161 /*      mutex_lock(&tm6000_driver.open_close_mutex); */
162         ret = usb_submit_urb(dvb->bulk_urb, GFP_ATOMIC);
163
164 /*      mutex_unlock(&tm6000_driver.open_close_mutex); */
165         if (ret) {
166                 printk(KERN_ERR "tm6000: submit of urb failed (error=%i)\n",
167                                                                         ret);
168
169                 kfree(dvb->bulk_urb->transfer_buffer);
170                 usb_free_urb(dvb->bulk_urb);
171                 dvb->bulk_urb = NULL;
172                 return ret;
173         }
174
175         return 0;
176 }
177
178 static void tm6000_stop_stream(struct tm6000_core *dev)
179 {
180         struct tm6000_dvb *dvb = dev->dvb;
181
182         if (dvb->bulk_urb) {
183                 printk(KERN_INFO "urb killing\n");
184                 usb_kill_urb(dvb->bulk_urb);
185                 printk(KERN_INFO "urb buffer free\n");
186                 kfree(dvb->bulk_urb->transfer_buffer);
187                 usb_free_urb(dvb->bulk_urb);
188                 dvb->bulk_urb = NULL;
189         }
190 }
191
192 static int tm6000_start_feed(struct dvb_demux_feed *feed)
193 {
194         struct dvb_demux *demux = feed->demux;
195         struct tm6000_core *dev = demux->priv;
196         struct tm6000_dvb *dvb = dev->dvb;
197         printk(KERN_INFO "tm6000: got start feed request %s\n", __func__);
198
199         mutex_lock(&dvb->mutex);
200         if (dvb->streams == 0) {
201                 dvb->streams = 1;
202 /*              mutex_init(&tm6000_dev->streming_mutex); */
203                 tm6000_start_stream(dev);
204         } else
205                 ++(dvb->streams);
206         mutex_unlock(&dvb->mutex);
207
208         return 0;
209 }
210
211 static int tm6000_stop_feed(struct dvb_demux_feed *feed)
212 {
213         struct dvb_demux *demux = feed->demux;
214         struct tm6000_core *dev = demux->priv;
215         struct tm6000_dvb *dvb = dev->dvb;
216
217         printk(KERN_INFO "tm6000: got stop feed request %s\n", __func__);
218
219         mutex_lock(&dvb->mutex);
220
221         printk(KERN_INFO "stream %#x\n", dvb->streams);
222         --(dvb->streams);
223         if (dvb->streams == 0) {
224                 printk(KERN_INFO "stop stream\n");
225                 tm6000_stop_stream(dev);
226 /*              mutex_destroy(&tm6000_dev->streaming_mutex); */
227         }
228         mutex_unlock(&dvb->mutex);
229 /*      mutex_destroy(&tm6000_dev->streaming_mutex); */
230
231         return 0;
232 }
233
234 static int tm6000_dvb_attach_frontend(struct tm6000_core *dev)
235 {
236         struct tm6000_dvb *dvb = dev->dvb;
237
238         if (dev->caps.has_zl10353) {
239                 struct zl10353_config config = {
240                                      .demod_address = dev->demod_addr,
241                                      .no_tuner = 1,
242                                      .parallel_ts = 1,
243                                      .if2 = 45700,
244                                      .disable_i2c_gate_ctrl = 1,
245                                     };
246
247                 dvb->frontend = dvb_attach(zl10353_attach, &config,
248                                                            &dev->i2c_adap);
249         } else {
250                 printk(KERN_ERR "tm6000: no frontend defined for the device!\n");
251                 return -1;
252         }
253
254         return (!dvb->frontend) ? -1 : 0;
255 }
256
257 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
258
259 static int register_dvb(struct tm6000_core *dev)
260 {
261         int ret = -1;
262         struct tm6000_dvb *dvb = dev->dvb;
263
264         mutex_init(&dvb->mutex);
265
266         dvb->streams = 0;
267
268         /* attach the frontend */
269         ret = tm6000_dvb_attach_frontend(dev);
270         if (ret < 0) {
271                 printk(KERN_ERR "tm6000: couldn't attach the frontend!\n");
272                 goto err;
273         }
274
275         ret = dvb_register_adapter(&dvb->adapter, "Trident TVMaster 6000 DVB-T",
276                                         THIS_MODULE, &dev->udev->dev, adapter_nr);
277         if (ret < 0) {
278                 pr_err("tm6000: couldn't register the adapter!\n");
279                 goto err;
280         }
281
282         dvb->adapter.priv = dev;
283
284         if (dvb->frontend) {
285                 switch (dev->tuner_type) {
286                 case TUNER_XC2028: {
287                         struct xc2028_config cfg = {
288                                 .i2c_adap = &dev->i2c_adap,
289                                 .i2c_addr = dev->tuner_addr,
290                         };
291
292                         dvb->frontend->callback = tm6000_tuner_callback;
293                         ret = dvb_register_frontend(&dvb->adapter, dvb->frontend);
294                         if (ret < 0) {
295                                 printk(KERN_ERR
296                                         "tm6000: couldn't register frontend\n");
297                                 goto adapter_err;
298                         }
299
300                         if (!dvb_attach(xc2028_attach, dvb->frontend, &cfg)) {
301                                 printk(KERN_ERR "tm6000: couldn't register frontend (xc3028)\n");
302                                 ret = -EINVAL;
303                                 goto frontend_err;
304                         }
305                         printk(KERN_INFO "tm6000: XC2028/3028 asked to be attached to frontend!\n");
306                         break;
307                         }
308                 case TUNER_XC5000: {
309                         struct xc5000_config cfg = {
310                                 .i2c_address = dev->tuner_addr,
311                         };
312
313                         dvb->frontend->callback = tm6000_xc5000_callback;
314                         ret = dvb_register_frontend(&dvb->adapter, dvb->frontend);
315                         if (ret < 0) {
316                                 printk(KERN_ERR
317                                         "tm6000: couldn't register frontend\n");
318                                 goto adapter_err;
319                         }
320
321                         if (!dvb_attach(xc5000_attach, dvb->frontend, &dev->i2c_adap, &cfg)) {
322                                 printk(KERN_ERR "tm6000: couldn't register frontend (xc5000)\n");
323                                 ret = -EINVAL;
324                                 goto frontend_err;
325                         }
326                         printk(KERN_INFO "tm6000: XC5000 asked to be attached to frontend!\n");
327                         break;
328                         }
329                 }
330         } else
331                 printk(KERN_ERR "tm6000: no frontend found\n");
332
333         dvb->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING
334                                                             | DMX_MEMORY_BASED_FILTERING;
335         dvb->demux.priv = dev;
336         dvb->demux.filternum = 8;
337         dvb->demux.feednum = 8;
338         dvb->demux.start_feed = tm6000_start_feed;
339         dvb->demux.stop_feed = tm6000_stop_feed;
340         dvb->demux.write_to_decoder = NULL;
341         ret = dvb_dmx_init(&dvb->demux);
342         if (ret < 0) {
343                 printk(KERN_ERR "tm6000: dvb_dmx_init failed (errno = %d)\n", ret);
344                 goto frontend_err;
345         }
346
347         dvb->dmxdev.filternum = dev->dvb->demux.filternum;
348         dvb->dmxdev.demux = &dev->dvb->demux.dmx;
349         dvb->dmxdev.capabilities = 0;
350
351         ret =  dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter);
352         if (ret < 0) {
353                 printk(KERN_ERR "tm6000: dvb_dmxdev_init failed (errno = %d)\n", ret);
354                 goto dvb_dmx_err;
355         }
356
357         return 0;
358
359 dvb_dmx_err:
360         dvb_dmx_release(&dvb->demux);
361 frontend_err:
362         if (dvb->frontend) {
363                 dvb_unregister_frontend(dvb->frontend);
364                 dvb_frontend_detach(dvb->frontend);
365         }
366 adapter_err:
367         dvb_unregister_adapter(&dvb->adapter);
368 err:
369         return ret;
370 }
371
372 static void unregister_dvb(struct tm6000_core *dev)
373 {
374         struct tm6000_dvb *dvb = dev->dvb;
375
376         if (dvb->bulk_urb != NULL) {
377                 struct urb *bulk_urb = dvb->bulk_urb;
378
379                 kfree(bulk_urb->transfer_buffer);
380                 bulk_urb->transfer_buffer = NULL;
381                 usb_unlink_urb(bulk_urb);
382                 usb_free_urb(bulk_urb);
383         }
384
385 /*      mutex_lock(&tm6000_driver.open_close_mutex); */
386         if (dvb->frontend) {
387                 dvb_unregister_frontend(dvb->frontend);
388                 dvb_frontend_detach(dvb->frontend);
389         }
390
391         dvb_dmxdev_release(&dvb->dmxdev);
392         dvb_dmx_release(&dvb->demux);
393         dvb_unregister_adapter(&dvb->adapter);
394         mutex_destroy(&dvb->mutex);
395 /*      mutex_unlock(&tm6000_driver.open_close_mutex); */
396 }
397
398 static int dvb_init(struct tm6000_core *dev)
399 {
400         struct tm6000_dvb *dvb;
401         int rc;
402
403         if (!dev)
404                 return 0;
405
406         if (!dev->caps.has_dvb)
407                 return 0;
408
409         if (dev->udev->speed == USB_SPEED_FULL) {
410                 printk(KERN_INFO "This USB2.0 device cannot be run on a USB1.1 port. (it lacks a hardware PID filter)\n");
411                 return 0;
412         }
413
414         dvb = kzalloc(sizeof(struct tm6000_dvb), GFP_KERNEL);
415         if (!dvb) {
416                 printk(KERN_INFO "Cannot allocate memory\n");
417                 return -ENOMEM;
418         }
419
420         dev->dvb = dvb;
421
422         rc = register_dvb(dev);
423         if (rc < 0) {
424                 kfree(dvb);
425                 dev->dvb = NULL;
426                 return 0;
427         }
428
429         return 0;
430 }
431
432 static int dvb_fini(struct tm6000_core *dev)
433 {
434         if (!dev)
435                 return 0;
436
437         if (!dev->caps.has_dvb)
438                 return 0;
439
440         if (dev->dvb) {
441                 unregister_dvb(dev);
442                 kfree(dev->dvb);
443                 dev->dvb = NULL;
444         }
445
446         return 0;
447 }
448
449 static struct tm6000_ops dvb_ops = {
450         .type   = TM6000_DVB,
451         .name   = "TM6000 dvb Extension",
452         .init   = dvb_init,
453         .fini   = dvb_fini,
454 };
455
456 static int __init tm6000_dvb_register(void)
457 {
458         return tm6000_register_extension(&dvb_ops);
459 }
460
461 static void __exit tm6000_dvb_unregister(void)
462 {
463         tm6000_unregister_extension(&dvb_ops);
464 }
465
466 module_init(tm6000_dvb_register);
467 module_exit(tm6000_dvb_unregister);