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