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