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