GNU Linux-libre 4.19.263-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 synchronously";
49                 break;
50         case -ECONNRESET:
51                 errmsg = "unlinked asynchronously";
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)
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) {
138                 usb_free_urb(dvb->bulk_urb);
139                 dvb->bulk_urb = NULL;
140                 return -ENOMEM;
141         }
142
143         usb_fill_bulk_urb(dvb->bulk_urb, dev->udev, pipe,
144                                                  dvb->bulk_urb->transfer_buffer,
145                                                  size,
146                                                  tm6000_urb_received, dev);
147
148         ret = usb_clear_halt(dev->udev, pipe);
149         if (ret < 0) {
150                 printk(KERN_ERR "tm6000: error %i in %s during pipe reset\n",
151                                                         ret, __func__);
152
153                 kfree(dvb->bulk_urb->transfer_buffer);
154                 usb_free_urb(dvb->bulk_urb);
155                 dvb->bulk_urb = NULL;
156                 return ret;
157         } else
158                 printk(KERN_ERR "tm6000: pipe resetted\n");
159
160 /*      mutex_lock(&tm6000_driver.open_close_mutex); */
161         ret = usb_submit_urb(dvb->bulk_urb, GFP_ATOMIC);
162
163 /*      mutex_unlock(&tm6000_driver.open_close_mutex); */
164         if (ret) {
165                 printk(KERN_ERR "tm6000: submit of urb failed (error=%i)\n",
166                                                                         ret);
167
168                 kfree(dvb->bulk_urb->transfer_buffer);
169                 usb_free_urb(dvb->bulk_urb);
170                 dvb->bulk_urb = NULL;
171                 return ret;
172         }
173
174         return 0;
175 }
176
177 static void tm6000_stop_stream(struct tm6000_core *dev)
178 {
179         struct tm6000_dvb *dvb = dev->dvb;
180
181         if (dvb->bulk_urb) {
182                 printk(KERN_INFO "urb killing\n");
183                 usb_kill_urb(dvb->bulk_urb);
184                 printk(KERN_INFO "urb buffer free\n");
185                 kfree(dvb->bulk_urb->transfer_buffer);
186                 usb_free_urb(dvb->bulk_urb);
187                 dvb->bulk_urb = NULL;
188         }
189 }
190
191 static int tm6000_start_feed(struct dvb_demux_feed *feed)
192 {
193         struct dvb_demux *demux = feed->demux;
194         struct tm6000_core *dev = demux->priv;
195         struct tm6000_dvb *dvb = dev->dvb;
196         printk(KERN_INFO "tm6000: got start feed request %s\n", __func__);
197
198         mutex_lock(&dvb->mutex);
199         if (dvb->streams == 0) {
200                 dvb->streams = 1;
201 /*              mutex_init(&tm6000_dev->streming_mutex); */
202                 tm6000_start_stream(dev);
203         } else
204                 ++(dvb->streams);
205         mutex_unlock(&dvb->mutex);
206
207         return 0;
208 }
209
210 static int tm6000_stop_feed(struct dvb_demux_feed *feed)
211 {
212         struct dvb_demux *demux = feed->demux;
213         struct tm6000_core *dev = demux->priv;
214         struct tm6000_dvb *dvb = dev->dvb;
215
216         printk(KERN_INFO "tm6000: got stop feed request %s\n", __func__);
217
218         mutex_lock(&dvb->mutex);
219
220         printk(KERN_INFO "stream %#x\n", dvb->streams);
221         --(dvb->streams);
222         if (dvb->streams == 0) {
223                 printk(KERN_INFO "stop stream\n");
224                 tm6000_stop_stream(dev);
225 /*              mutex_destroy(&tm6000_dev->streaming_mutex); */
226         }
227         mutex_unlock(&dvb->mutex);
228 /*      mutex_destroy(&tm6000_dev->streaming_mutex); */
229
230         return 0;
231 }
232
233 static int tm6000_dvb_attach_frontend(struct tm6000_core *dev)
234 {
235         struct tm6000_dvb *dvb = dev->dvb;
236
237         if (dev->caps.has_zl10353) {
238                 struct zl10353_config config = {
239                                      .demod_address = dev->demod_addr,
240                                      .no_tuner = 1,
241                                      .parallel_ts = 1,
242                                      .if2 = 45700,
243                                      .disable_i2c_gate_ctrl = 1,
244                                     };
245
246                 dvb->frontend = dvb_attach(zl10353_attach, &config,
247                                                            &dev->i2c_adap);
248         } else {
249                 printk(KERN_ERR "tm6000: no frontend defined for the device!\n");
250                 return -1;
251         }
252
253         return (!dvb->frontend) ? -1 : 0;
254 }
255
256 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
257
258 static int register_dvb(struct tm6000_core *dev)
259 {
260         int ret = -1;
261         struct tm6000_dvb *dvb = dev->dvb;
262
263         mutex_init(&dvb->mutex);
264
265         dvb->streams = 0;
266
267         /* attach the frontend */
268         ret = tm6000_dvb_attach_frontend(dev);
269         if (ret < 0) {
270                 printk(KERN_ERR "tm6000: couldn't attach the frontend!\n");
271                 goto err;
272         }
273
274         ret = dvb_register_adapter(&dvb->adapter, "Trident TVMaster 6000 DVB-T",
275                                         THIS_MODULE, &dev->udev->dev, adapter_nr);
276         if (ret < 0) {
277                 pr_err("tm6000: couldn't register the adapter!\n");
278                 goto err;
279         }
280
281         dvb->adapter.priv = dev;
282
283         if (dvb->frontend) {
284                 switch (dev->tuner_type) {
285                 case TUNER_XC2028: {
286                         struct xc2028_config cfg = {
287                                 .i2c_adap = &dev->i2c_adap,
288                                 .i2c_addr = dev->tuner_addr,
289                         };
290
291                         dvb->frontend->callback = tm6000_tuner_callback;
292                         ret = dvb_register_frontend(&dvb->adapter, dvb->frontend);
293                         if (ret < 0) {
294                                 printk(KERN_ERR
295                                         "tm6000: couldn't register frontend\n");
296                                 goto adapter_err;
297                         }
298
299                         if (!dvb_attach(xc2028_attach, dvb->frontend, &cfg)) {
300                                 printk(KERN_ERR "tm6000: couldn't register frontend (xc3028)\n");
301                                 ret = -EINVAL;
302                                 goto frontend_err;
303                         }
304                         printk(KERN_INFO "tm6000: XC2028/3028 asked to be attached to frontend!\n");
305                         break;
306                         }
307                 case TUNER_XC5000: {
308                         struct xc5000_config cfg = {
309                                 .i2c_address = dev->tuner_addr,
310                         };
311
312                         dvb->frontend->callback = tm6000_xc5000_callback;
313                         ret = dvb_register_frontend(&dvb->adapter, dvb->frontend);
314                         if (ret < 0) {
315                                 printk(KERN_ERR
316                                         "tm6000: couldn't register frontend\n");
317                                 goto adapter_err;
318                         }
319
320                         if (!dvb_attach(xc5000_attach, dvb->frontend, &dev->i2c_adap, &cfg)) {
321                                 printk(KERN_ERR "tm6000: couldn't register frontend (xc5000)\n");
322                                 ret = -EINVAL;
323                                 goto frontend_err;
324                         }
325                         printk(KERN_INFO "tm6000: XC5000 asked to be attached to frontend!\n");
326                         break;
327                         }
328                 }
329         } else
330                 printk(KERN_ERR "tm6000: no frontend found\n");
331
332         dvb->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING
333                                                             | DMX_MEMORY_BASED_FILTERING;
334         dvb->demux.priv = dev;
335         dvb->demux.filternum = 8;
336         dvb->demux.feednum = 8;
337         dvb->demux.start_feed = tm6000_start_feed;
338         dvb->demux.stop_feed = tm6000_stop_feed;
339         dvb->demux.write_to_decoder = NULL;
340         ret = dvb_dmx_init(&dvb->demux);
341         if (ret < 0) {
342                 printk(KERN_ERR "tm6000: dvb_dmx_init failed (errno = %d)\n", ret);
343                 goto frontend_err;
344         }
345
346         dvb->dmxdev.filternum = dev->dvb->demux.filternum;
347         dvb->dmxdev.demux = &dev->dvb->demux.dmx;
348         dvb->dmxdev.capabilities = 0;
349
350         ret =  dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter);
351         if (ret < 0) {
352                 printk(KERN_ERR "tm6000: dvb_dmxdev_init failed (errno = %d)\n", ret);
353                 goto dvb_dmx_err;
354         }
355
356         return 0;
357
358 dvb_dmx_err:
359         dvb_dmx_release(&dvb->demux);
360 frontend_err:
361         if (dvb->frontend) {
362                 dvb_unregister_frontend(dvb->frontend);
363                 dvb_frontend_detach(dvb->frontend);
364         }
365 adapter_err:
366         dvb_unregister_adapter(&dvb->adapter);
367 err:
368         return ret;
369 }
370
371 static void unregister_dvb(struct tm6000_core *dev)
372 {
373         struct tm6000_dvb *dvb = dev->dvb;
374
375         if (dvb->bulk_urb) {
376                 struct urb *bulk_urb = dvb->bulk_urb;
377
378                 kfree(bulk_urb->transfer_buffer);
379                 bulk_urb->transfer_buffer = NULL;
380                 usb_unlink_urb(bulk_urb);
381                 usb_free_urb(bulk_urb);
382         }
383
384 /*      mutex_lock(&tm6000_driver.open_close_mutex); */
385         if (dvb->frontend) {
386                 dvb_unregister_frontend(dvb->frontend);
387                 dvb_frontend_detach(dvb->frontend);
388         }
389
390         dvb_dmxdev_release(&dvb->dmxdev);
391         dvb_dmx_release(&dvb->demux);
392         dvb_unregister_adapter(&dvb->adapter);
393         mutex_destroy(&dvb->mutex);
394 /*      mutex_unlock(&tm6000_driver.open_close_mutex); */
395 }
396
397 static int dvb_init(struct tm6000_core *dev)
398 {
399         struct tm6000_dvb *dvb;
400         int rc;
401
402         if (!dev)
403                 return 0;
404
405         if (!dev->caps.has_dvb)
406                 return 0;
407
408         if (dev->udev->speed == USB_SPEED_FULL) {
409                 printk(KERN_INFO "This USB2.0 device cannot be run on a USB1.1 port. (it lacks a hardware PID filter)\n");
410                 return 0;
411         }
412
413         dvb = kzalloc(sizeof(struct tm6000_dvb), GFP_KERNEL);
414         if (!dvb)
415                 return -ENOMEM;
416
417         dev->dvb = dvb;
418
419         rc = register_dvb(dev);
420         if (rc < 0) {
421                 kfree(dvb);
422                 dev->dvb = NULL;
423                 return 0;
424         }
425
426         return 0;
427 }
428
429 static int dvb_fini(struct tm6000_core *dev)
430 {
431         if (!dev)
432                 return 0;
433
434         if (!dev->caps.has_dvb)
435                 return 0;
436
437         if (dev->dvb) {
438                 unregister_dvb(dev);
439                 kfree(dev->dvb);
440                 dev->dvb = NULL;
441         }
442
443         return 0;
444 }
445
446 static struct tm6000_ops dvb_ops = {
447         .type   = TM6000_DVB,
448         .name   = "TM6000 dvb Extension",
449         .init   = dvb_init,
450         .fini   = dvb_fini,
451 };
452
453 static int __init tm6000_dvb_register(void)
454 {
455         return tm6000_register_extension(&dvb_ops);
456 }
457
458 static void __exit tm6000_dvb_unregister(void)
459 {
460         tm6000_unregister_extension(&dvb_ops);
461 }
462
463 module_init(tm6000_dvb_register);
464 module_exit(tm6000_dvb_unregister);