blob: 1d0afa340f47c22cf7710211debaef8e94bcf2bc [file] [log] [blame]
Thomas Gleixnerc942fdd2019-05-27 08:55:06 +02001// SPDX-License-Identifier: GPL-2.0-or-later
Linus Torvalds1da177e2005-04-16 15:20:36 -07002/*
3 * TTUSB DEC Driver
4 *
5 * Copyright (C) 2003-2004 Alex Woods <linux-dvb@giblets.org>
6 * IR support by Peter Beutner <p.beutner@gmx.net>
Linus Torvalds1da177e2005-04-16 15:20:36 -07007 */
8
Linus Torvalds1da177e2005-04-16 15:20:36 -07009#include <linux/list.h>
10#include <linux/module.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070011#include <linux/pci.h>
12#include <linux/slab.h>
13#include <linux/spinlock.h>
14#include <linux/usb.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070015#include <linux/interrupt.h>
16#include <linux/firmware.h>
17#include <linux/crc32.h>
18#include <linux/init.h>
19#include <linux/input.h>
20
Trent Piepho68277092007-01-30 23:25:46 -030021#include <linux/mutex.h>
22
Mauro Carvalho Chehabfada1932017-12-28 13:03:51 -050023#include <media/dmxdev.h>
24#include <media/dvb_demux.h>
25#include <media/dvb_frontend.h>
26#include <media/dvb_net.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include "ttusbdecfe.h"
28
29static int debug;
30static int output_pva;
31static int enable_rc;
32
33module_param(debug, int, 0644);
34MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
35module_param(output_pva, int, 0444);
36MODULE_PARM_DESC(output_pva, "Output PVA from dvr device (default:off)");
37module_param(enable_rc, int, 0644);
38MODULE_PARM_DESC(enable_rc, "Turn on/off IR remote control(default: off)");
39
Janne Grunau78e920062008-04-09 19:13:13 -030040DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
41
Linus Torvalds1da177e2005-04-16 15:20:36 -070042#define dprintk if (debug) printk
43
44#define DRIVER_NAME "TechnoTrend/Hauppauge DEC USB"
45
46#define COMMAND_PIPE 0x03
47#define RESULT_PIPE 0x04
48#define IN_PIPE 0x08
49#define OUT_PIPE 0x07
50#define IRQ_PIPE 0x0A
51
52#define COMMAND_PACKET_SIZE 0x3c
53#define ARM_PACKET_SIZE 0x1000
54#define IRQ_PACKET_SIZE 0x8
55
56#define ISO_BUF_COUNT 0x04
57#define FRAMES_PER_ISO_BUF 0x04
58#define ISO_FRAME_SIZE 0x0380
59
60#define MAX_PVA_LENGTH 6144
61
62enum ttusb_dec_model {
63 TTUSB_DEC2000T,
64 TTUSB_DEC2540T,
65 TTUSB_DEC3000S
66};
67
68enum ttusb_dec_packet_type {
69 TTUSB_DEC_PACKET_PVA,
70 TTUSB_DEC_PACKET_SECTION,
71 TTUSB_DEC_PACKET_EMPTY
72};
73
74enum ttusb_dec_interface {
75 TTUSB_DEC_INTERFACE_INITIAL,
76 TTUSB_DEC_INTERFACE_IN,
77 TTUSB_DEC_INTERFACE_OUT
78};
79
Mauro Carvalho Chehabb676e732016-10-13 07:41:38 -030080typedef int (dvb_filter_pes2ts_cb_t) (void *, unsigned char *);
81
82struct dvb_filter_pes2ts {
83 unsigned char buf[188];
84 unsigned char cc;
85 dvb_filter_pes2ts_cb_t *cb;
86 void *priv;
87};
88
Linus Torvalds1da177e2005-04-16 15:20:36 -070089struct ttusb_dec {
90 enum ttusb_dec_model model;
91 char *model_name;
92 char *firmware_name;
93 int can_playback;
94
95 /* DVB bits */
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -070096 struct dvb_adapter adapter;
Linus Torvalds1da177e2005-04-16 15:20:36 -070097 struct dmxdev dmxdev;
98 struct dvb_demux demux;
99 struct dmx_frontend frontend;
100 struct dvb_net dvb_net;
101 struct dvb_frontend* fe;
102
103 u16 pid[DMX_PES_OTHER];
104
105 /* USB bits */
106 struct usb_device *udev;
107 u8 trans_count;
108 unsigned int command_pipe;
109 unsigned int result_pipe;
110 unsigned int in_pipe;
111 unsigned int out_pipe;
112 unsigned int irq_pipe;
113 enum ttusb_dec_interface interface;
Ingo Molnar3593cab2006-02-07 06:49:14 -0200114 struct mutex usb_mutex;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700115
116 void *irq_buffer;
117 struct urb *irq_urb;
118 dma_addr_t irq_dma_handle;
119 void *iso_buffer;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700120 struct urb *iso_urb[ISO_BUF_COUNT];
121 int iso_stream_count;
Ingo Molnar3593cab2006-02-07 06:49:14 -0200122 struct mutex iso_mutex;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700123
124 u8 packet[MAX_PVA_LENGTH + 4];
125 enum ttusb_dec_packet_type packet_type;
126 int packet_state;
127 int packet_length;
128 int packet_payload_length;
129 u16 next_packet_id;
130
131 int pva_stream_count;
132 int filter_stream_count;
133
134 struct dvb_filter_pes2ts a_pes2ts;
135 struct dvb_filter_pes2ts v_pes2ts;
136
137 u8 v_pes[16 + MAX_PVA_LENGTH];
138 int v_pes_length;
139 int v_pes_postbytes;
140
141 struct list_head urb_frame_list;
142 struct tasklet_struct urb_tasklet;
143 spinlock_t urb_frame_list_lock;
144
145 struct dvb_demux_filter *audio_filter;
146 struct dvb_demux_filter *video_filter;
147 struct list_head filter_info_list;
148 spinlock_t filter_info_list_lock;
149
Dmitry Torokhovb7df3912005-09-15 02:01:53 -0500150 struct input_dev *rc_input_dev;
151 char rc_phys[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700152
153 int active; /* Loaded successfully */
154};
155
156struct urb_frame {
157 u8 data[ISO_FRAME_SIZE];
158 int length;
159 struct list_head urb_frame_list;
160};
161
162struct filter_info {
163 u8 stream_id;
164 struct dvb_demux_filter *filter;
165 struct list_head filter_info_list;
166};
167
168static u16 rc_keys[] = {
169 KEY_POWER,
170 KEY_MUTE,
171 KEY_1,
172 KEY_2,
173 KEY_3,
174 KEY_4,
175 KEY_5,
176 KEY_6,
177 KEY_7,
178 KEY_8,
179 KEY_9,
180 KEY_0,
181 KEY_CHANNELUP,
182 KEY_VOLUMEDOWN,
183 KEY_OK,
184 KEY_VOLUMEUP,
185 KEY_CHANNELDOWN,
186 KEY_PREVIOUS,
187 KEY_ESC,
188 KEY_RED,
189 KEY_GREEN,
190 KEY_YELLOW,
191 KEY_BLUE,
192 KEY_OPTION,
193 KEY_M,
194 KEY_RADIO
195};
196
Mauro Carvalho Chehabb676e732016-10-13 07:41:38 -0300197static void dvb_filter_pes2ts_init(struct dvb_filter_pes2ts *p2ts,
198 unsigned short pid,
199 dvb_filter_pes2ts_cb_t *cb, void *priv)
200{
201 unsigned char *buf=p2ts->buf;
202
203 buf[0]=0x47;
204 buf[1]=(pid>>8);
205 buf[2]=pid&0xff;
206 p2ts->cc=0;
207 p2ts->cb=cb;
208 p2ts->priv=priv;
209}
210
211static int dvb_filter_pes2ts(struct dvb_filter_pes2ts *p2ts,
212 unsigned char *pes, int len, int payload_start)
213{
214 unsigned char *buf=p2ts->buf;
215 int ret=0, rest;
216
217 //len=6+((pes[4]<<8)|pes[5]);
218
219 if (payload_start)
220 buf[1]|=0x40;
221 else
222 buf[1]&=~0x40;
223 while (len>=184) {
224 buf[3]=0x10|((p2ts->cc++)&0x0f);
225 memcpy(buf+4, pes, 184);
226 if ((ret=p2ts->cb(p2ts->priv, buf)))
227 return ret;
228 len-=184; pes+=184;
229 buf[1]&=~0x40;
230 }
231 if (!len)
232 return 0;
233 buf[3]=0x30|((p2ts->cc++)&0x0f);
234 rest=183-len;
235 if (rest) {
236 buf[5]=0x00;
237 if (rest-1)
238 memset(buf+6, 0xff, rest-1);
239 }
240 buf[4]=rest;
241 memcpy(buf+5+rest, pes, len);
242 return p2ts->cb(p2ts->priv, buf);
243}
244
Linus Torvalds1da177e2005-04-16 15:20:36 -0700245static void ttusb_dec_set_model(struct ttusb_dec *dec,
246 enum ttusb_dec_model model);
247
David Howells7d12e782006-10-05 14:55:46 +0100248static void ttusb_dec_handle_irq( struct urb *urb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700249{
Mauro Carvalho Chehab3cc26912016-09-22 14:09:18 -0300250 struct ttusb_dec *dec = urb->context;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700251 char *buffer = dec->irq_buffer;
252 int retval;
253
254 switch(urb->status) {
255 case 0: /*success*/
256 break;
257 case -ECONNRESET:
258 case -ENOENT:
259 case -ESHUTDOWN:
Pete Zaitcev38e2bfc2006-09-18 22:49:02 -0700260 case -ETIME:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700261 /* this urb is dead, cleanup */
262 dprintk("%s:urb shutting down with status: %d\n",
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300263 __func__, urb->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700264 return;
265 default:
266 dprintk("%s:nonzero status received: %d\n",
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300267 __func__,urb->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700268 goto exit;
269 }
270
Mauro Carvalho Chehab3cc26912016-09-22 14:09:18 -0300271 if ((buffer[0] == 0x1) && (buffer[2] == 0x15)) {
272 /*
273 * IR - Event
274 *
275 * this is an fact a bit too simple implementation;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700276 * the box also reports a keyrepeat signal
Mauro Carvalho Chehab3e4d8f42019-02-18 14:29:03 -0500277 * (with buffer[3] == 0x40) in an interval of ~100ms.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700278 * But to handle this correctly we had to imlemenent some
279 * kind of timer which signals a 'key up' event if no
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300280 * keyrepeat signal is received for lets say 200ms.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700281 * this should/could be added later ...
Mauro Carvalho Chehab3cc26912016-09-22 14:09:18 -0300282 * for now lets report each signal as a key down and up
283 */
284 if (buffer[4] - 1 < ARRAY_SIZE(rc_keys)) {
285 dprintk("%s:rc signal:%d\n", __func__, buffer[4]);
286 input_report_key(dec->rc_input_dev, rc_keys[buffer[4] - 1], 1);
287 input_sync(dec->rc_input_dev);
288 input_report_key(dec->rc_input_dev, rc_keys[buffer[4] - 1], 0);
289 input_sync(dec->rc_input_dev);
290 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700291 }
292
Mauro Carvalho Chehab3cc26912016-09-22 14:09:18 -0300293exit:
294 retval = usb_submit_urb(urb, GFP_ATOMIC);
295 if (retval)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700296 printk("%s - usb_commit_urb failed with result: %d\n",
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300297 __func__, retval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700298}
299
300static u16 crc16(u16 crc, const u8 *buf, size_t len)
301{
302 u16 tmp;
303
304 while (len--) {
305 crc ^= *buf++;
306 crc ^= (u8)crc >> 4;
307 tmp = (u8)crc;
308 crc ^= (tmp ^ (tmp << 1)) << 4;
309 }
310 return crc;
311}
312
313static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command,
314 int param_length, const u8 params[],
315 int *result_length, u8 cmd_result[])
316{
Mauro Carvalho Chehab61fc8742016-10-14 07:44:05 -0300317 int result, actual_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700318 u8 *b;
319
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300320 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700321
322 b = kmalloc(COMMAND_PACKET_SIZE + 4, GFP_KERNEL);
323 if (!b)
324 return -ENOMEM;
325
Ingo Molnar3593cab2006-02-07 06:49:14 -0200326 if ((result = mutex_lock_interruptible(&dec->usb_mutex))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700327 kfree(b);
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300328 printk("%s: Failed to lock usb mutex.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700329 return result;
330 }
331
332 b[0] = 0xaa;
333 b[1] = ++dec->trans_count;
334 b[2] = command;
335 b[3] = param_length;
336
337 if (params)
338 memcpy(&b[4], params, param_length);
339
340 if (debug) {
Mauro Carvalho Chehab61fc8742016-10-14 07:44:05 -0300341 printk(KERN_DEBUG "%s: command: %*ph\n",
342 __func__, param_length, b);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700343 }
344
345 result = usb_bulk_msg(dec->udev, dec->command_pipe, b,
346 COMMAND_PACKET_SIZE + 4, &actual_len, 1000);
347
348 if (result) {
349 printk("%s: command bulk message failed: error %d\n",
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300350 __func__, result);
Ingo Molnar3593cab2006-02-07 06:49:14 -0200351 mutex_unlock(&dec->usb_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700352 kfree(b);
353 return result;
354 }
355
356 result = usb_bulk_msg(dec->udev, dec->result_pipe, b,
357 COMMAND_PACKET_SIZE + 4, &actual_len, 1000);
358
359 if (result) {
360 printk("%s: result bulk message failed: error %d\n",
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300361 __func__, result);
Ingo Molnar3593cab2006-02-07 06:49:14 -0200362 mutex_unlock(&dec->usb_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700363 kfree(b);
364 return result;
365 } else {
366 if (debug) {
Mauro Carvalho Chehab61fc8742016-10-14 07:44:05 -0300367 printk(KERN_DEBUG "%s: result: %*ph\n",
368 __func__, actual_len, b);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700369 }
370
371 if (result_length)
372 *result_length = b[3];
373 if (cmd_result && b[3] > 0)
374 memcpy(cmd_result, &b[4], b[3]);
375
Ingo Molnar3593cab2006-02-07 06:49:14 -0200376 mutex_unlock(&dec->usb_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377
378 kfree(b);
379 return 0;
380 }
381}
382
383static int ttusb_dec_get_stb_state (struct ttusb_dec *dec, unsigned int *mode,
384 unsigned int *model, unsigned int *version)
385{
386 u8 c[COMMAND_PACKET_SIZE];
387 int c_length;
388 int result;
Al Virod4f979a2008-05-21 00:31:31 -0300389 __be32 tmp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300391 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700392
393 result = ttusb_dec_send_command(dec, 0x08, 0, NULL, &c_length, c);
394 if (result)
395 return result;
396
397 if (c_length >= 0x0c) {
398 if (mode != NULL) {
399 memcpy(&tmp, c, 4);
400 *mode = ntohl(tmp);
401 }
402 if (model != NULL) {
403 memcpy(&tmp, &c[4], 4);
404 *model = ntohl(tmp);
405 }
406 if (version != NULL) {
407 memcpy(&tmp, &c[8], 4);
408 *version = ntohl(tmp);
409 }
410 return 0;
411 } else {
Alexey Khoroshilovcf732b52013-10-02 13:00:26 -0300412 return -ENOENT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700413 }
414}
415
416static int ttusb_dec_audio_pes2ts_cb(void *priv, unsigned char *data)
417{
Alex Woodsf961e712006-01-09 15:25:24 -0200418 struct ttusb_dec *dec = priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419
420 dec->audio_filter->feed->cb.ts(data, 188, NULL, 0,
Mauro Carvalho Chehabfdbeb962018-02-09 07:30:46 -0500421 &dec->audio_filter->feed->feed.ts, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422
423 return 0;
424}
425
426static int ttusb_dec_video_pes2ts_cb(void *priv, unsigned char *data)
427{
Alex Woodsf961e712006-01-09 15:25:24 -0200428 struct ttusb_dec *dec = priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700429
430 dec->video_filter->feed->cb.ts(data, 188, NULL, 0,
Mauro Carvalho Chehabfdbeb962018-02-09 07:30:46 -0500431 &dec->video_filter->feed->feed.ts, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432
433 return 0;
434}
435
436static void ttusb_dec_set_pids(struct ttusb_dec *dec)
437{
438 u8 b[] = { 0x00, 0x00, 0x00, 0x00,
439 0x00, 0x00, 0xff, 0xff,
440 0xff, 0xff, 0xff, 0xff };
441
Al Virod4f979a2008-05-21 00:31:31 -0300442 __be16 pcr = htons(dec->pid[DMX_PES_PCR]);
443 __be16 audio = htons(dec->pid[DMX_PES_AUDIO]);
444 __be16 video = htons(dec->pid[DMX_PES_VIDEO]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700445
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300446 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700447
448 memcpy(&b[0], &pcr, 2);
449 memcpy(&b[2], &audio, 2);
450 memcpy(&b[4], &video, 2);
451
452 ttusb_dec_send_command(dec, 0x50, sizeof(b), b, NULL, NULL);
453
454 dvb_filter_pes2ts_init(&dec->a_pes2ts, dec->pid[DMX_PES_AUDIO],
455 ttusb_dec_audio_pes2ts_cb, dec);
456 dvb_filter_pes2ts_init(&dec->v_pes2ts, dec->pid[DMX_PES_VIDEO],
457 ttusb_dec_video_pes2ts_cb, dec);
458 dec->v_pes_length = 0;
459 dec->v_pes_postbytes = 0;
460}
461
462static void ttusb_dec_process_pva(struct ttusb_dec *dec, u8 *pva, int length)
463{
464 if (length < 8) {
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300465 printk("%s: packet too short - discarding\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700466 return;
467 }
468
469 if (length > 8 + MAX_PVA_LENGTH) {
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300470 printk("%s: packet too long - discarding\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700471 return;
472 }
473
474 switch (pva[2]) {
475
476 case 0x01: { /* VideoStream */
477 int prebytes = pva[5] & 0x03;
478 int postbytes = (pva[5] & 0x0c) >> 2;
Al Virod4f979a2008-05-21 00:31:31 -0300479 __be16 v_pes_payload_length;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700480
481 if (output_pva) {
482 dec->video_filter->feed->cb.ts(pva, length, NULL, 0,
Mauro Carvalho Chehabfdbeb962018-02-09 07:30:46 -0500483 &dec->video_filter->feed->feed.ts, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700484 return;
485 }
486
487 if (dec->v_pes_postbytes > 0 &&
488 dec->v_pes_postbytes == prebytes) {
489 memcpy(&dec->v_pes[dec->v_pes_length],
490 &pva[12], prebytes);
491
492 dvb_filter_pes2ts(&dec->v_pes2ts, dec->v_pes,
493 dec->v_pes_length + prebytes, 1);
494 }
495
496 if (pva[5] & 0x10) {
497 dec->v_pes[7] = 0x80;
498 dec->v_pes[8] = 0x05;
499
500 dec->v_pes[9] = 0x21 | ((pva[8] & 0xc0) >> 5);
501 dec->v_pes[10] = ((pva[8] & 0x3f) << 2) |
502 ((pva[9] & 0xc0) >> 6);
503 dec->v_pes[11] = 0x01 |
504 ((pva[9] & 0x3f) << 2) |
505 ((pva[10] & 0x80) >> 6);
506 dec->v_pes[12] = ((pva[10] & 0x7f) << 1) |
507 ((pva[11] & 0xc0) >> 7);
508 dec->v_pes[13] = 0x01 | ((pva[11] & 0x7f) << 1);
509
510 memcpy(&dec->v_pes[14], &pva[12 + prebytes],
511 length - 12 - prebytes);
512 dec->v_pes_length = 14 + length - 12 - prebytes;
513 } else {
514 dec->v_pes[7] = 0x00;
515 dec->v_pes[8] = 0x00;
516
517 memcpy(&dec->v_pes[9], &pva[8], length - 8);
518 dec->v_pes_length = 9 + length - 8;
519 }
520
521 dec->v_pes_postbytes = postbytes;
522
523 if (dec->v_pes[9 + dec->v_pes[8]] == 0x00 &&
524 dec->v_pes[10 + dec->v_pes[8]] == 0x00 &&
525 dec->v_pes[11 + dec->v_pes[8]] == 0x01)
526 dec->v_pes[6] = 0x84;
527 else
528 dec->v_pes[6] = 0x80;
529
530 v_pes_payload_length = htons(dec->v_pes_length - 6 +
531 postbytes);
532 memcpy(&dec->v_pes[4], &v_pes_payload_length, 2);
533
534 if (postbytes == 0)
535 dvb_filter_pes2ts(&dec->v_pes2ts, dec->v_pes,
536 dec->v_pes_length, 1);
537
538 break;
539 }
540
541 case 0x02: /* MainAudioStream */
542 if (output_pva) {
543 dec->audio_filter->feed->cb.ts(pva, length, NULL, 0,
Mauro Carvalho Chehabfdbeb962018-02-09 07:30:46 -0500544 &dec->audio_filter->feed->feed.ts, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700545 return;
546 }
547
548 dvb_filter_pes2ts(&dec->a_pes2ts, &pva[8], length - 8,
549 pva[5] & 0x10);
550 break;
551
552 default:
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300553 printk("%s: unknown PVA type: %02x.\n", __func__,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700554 pva[2]);
555 break;
556 }
557}
558
559static void ttusb_dec_process_filter(struct ttusb_dec *dec, u8 *packet,
560 int length)
561{
562 struct list_head *item;
563 struct filter_info *finfo;
564 struct dvb_demux_filter *filter = NULL;
565 unsigned long flags;
566 u8 sid;
567
568 sid = packet[1];
569 spin_lock_irqsave(&dec->filter_info_list_lock, flags);
570 for (item = dec->filter_info_list.next; item != &dec->filter_info_list;
571 item = item->next) {
572 finfo = list_entry(item, struct filter_info, filter_info_list);
573 if (finfo->stream_id == sid) {
574 filter = finfo->filter;
575 break;
576 }
577 }
578 spin_unlock_irqrestore(&dec->filter_info_list_lock, flags);
579
580 if (filter)
581 filter->feed->cb.sec(&packet[2], length - 2, NULL, 0,
Mauro Carvalho Chehabfdbeb962018-02-09 07:30:46 -0500582 &filter->filter, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700583}
584
585static void ttusb_dec_process_packet(struct ttusb_dec *dec)
586{
587 int i;
588 u16 csum = 0;
589 u16 packet_id;
590
591 if (dec->packet_length % 2) {
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300592 printk("%s: odd sized packet - discarding\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700593 return;
594 }
595
596 for (i = 0; i < dec->packet_length; i += 2)
597 csum ^= ((dec->packet[i] << 8) + dec->packet[i + 1]);
598
599 if (csum) {
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300600 printk("%s: checksum failed - discarding\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700601 return;
602 }
603
604 packet_id = dec->packet[dec->packet_length - 4] << 8;
605 packet_id += dec->packet[dec->packet_length - 3];
606
607 if ((packet_id != dec->next_packet_id) && dec->next_packet_id) {
608 printk("%s: warning: lost packets between %u and %u\n",
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300609 __func__, dec->next_packet_id - 1, packet_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700610 }
611
612 if (packet_id == 0xffff)
613 dec->next_packet_id = 0x8000;
614 else
615 dec->next_packet_id = packet_id + 1;
616
617 switch (dec->packet_type) {
618 case TTUSB_DEC_PACKET_PVA:
619 if (dec->pva_stream_count)
620 ttusb_dec_process_pva(dec, dec->packet,
621 dec->packet_payload_length);
622 break;
623
624 case TTUSB_DEC_PACKET_SECTION:
625 if (dec->filter_stream_count)
626 ttusb_dec_process_filter(dec, dec->packet,
627 dec->packet_payload_length);
628 break;
629
630 case TTUSB_DEC_PACKET_EMPTY:
631 break;
632 }
633}
634
635static void swap_bytes(u8 *b, int length)
636{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700637 length -= length % 2;
Fabian Frederick41cc14b2015-06-10 13:32:44 -0300638 for (; length; b += 2, length -= 2)
639 swap(*b, *(b + 1));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700640}
641
642static void ttusb_dec_process_urb_frame(struct ttusb_dec *dec, u8 *b,
643 int length)
644{
645 swap_bytes(b, length);
646
647 while (length) {
648 switch (dec->packet_state) {
649
650 case 0:
651 case 1:
652 case 2:
653 if (*b++ == 0xaa)
654 dec->packet_state++;
655 else
656 dec->packet_state = 0;
657
658 length--;
659 break;
660
661 case 3:
662 if (*b == 0x00) {
663 dec->packet_state++;
664 dec->packet_length = 0;
665 } else if (*b != 0xaa) {
666 dec->packet_state = 0;
667 }
668
669 b++;
670 length--;
671 break;
672
673 case 4:
674 dec->packet[dec->packet_length++] = *b++;
675
676 if (dec->packet_length == 2) {
677 if (dec->packet[0] == 'A' &&
678 dec->packet[1] == 'V') {
679 dec->packet_type =
680 TTUSB_DEC_PACKET_PVA;
681 dec->packet_state++;
682 } else if (dec->packet[0] == 'S') {
683 dec->packet_type =
684 TTUSB_DEC_PACKET_SECTION;
685 dec->packet_state++;
686 } else if (dec->packet[0] == 0x00) {
687 dec->packet_type =
688 TTUSB_DEC_PACKET_EMPTY;
689 dec->packet_payload_length = 2;
690 dec->packet_state = 7;
691 } else {
Mauro Carvalho Chehabbf769a42016-10-18 17:44:20 -0200692 printk("%s: unknown packet type: %02x%02x\n",
693 __func__,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700694 dec->packet[0], dec->packet[1]);
695 dec->packet_state = 0;
696 }
697 }
698
699 length--;
700 break;
701
702 case 5:
703 dec->packet[dec->packet_length++] = *b++;
704
705 if (dec->packet_type == TTUSB_DEC_PACKET_PVA &&
706 dec->packet_length == 8) {
707 dec->packet_state++;
708 dec->packet_payload_length = 8 +
709 (dec->packet[6] << 8) +
710 dec->packet[7];
711 } else if (dec->packet_type ==
712 TTUSB_DEC_PACKET_SECTION &&
713 dec->packet_length == 5) {
714 dec->packet_state++;
715 dec->packet_payload_length = 5 +
716 ((dec->packet[3] & 0x0f) << 8) +
717 dec->packet[4];
718 }
719
720 length--;
721 break;
722
723 case 6: {
724 int remainder = dec->packet_payload_length -
725 dec->packet_length;
726
727 if (length >= remainder) {
728 memcpy(dec->packet + dec->packet_length,
729 b, remainder);
730 dec->packet_length += remainder;
731 b += remainder;
732 length -= remainder;
733 dec->packet_state++;
734 } else {
735 memcpy(&dec->packet[dec->packet_length],
736 b, length);
737 dec->packet_length += length;
738 length = 0;
739 }
740
741 break;
742 }
743
744 case 7: {
745 int tail = 4;
746
747 dec->packet[dec->packet_length++] = *b++;
748
749 if (dec->packet_type == TTUSB_DEC_PACKET_SECTION &&
750 dec->packet_payload_length % 2)
751 tail++;
752
753 if (dec->packet_length ==
754 dec->packet_payload_length + tail) {
755 ttusb_dec_process_packet(dec);
756 dec->packet_state = 0;
757 }
758
759 length--;
760 break;
761 }
762
763 default:
764 printk("%s: illegal packet state encountered.\n",
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300765 __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700766 dec->packet_state = 0;
767 }
768 }
769}
770
771static void ttusb_dec_process_urb_frame_list(unsigned long data)
772{
773 struct ttusb_dec *dec = (struct ttusb_dec *)data;
774 struct list_head *item;
775 struct urb_frame *frame;
776 unsigned long flags;
777
778 while (1) {
779 spin_lock_irqsave(&dec->urb_frame_list_lock, flags);
780 if ((item = dec->urb_frame_list.next) != &dec->urb_frame_list) {
781 frame = list_entry(item, struct urb_frame,
782 urb_frame_list);
783 list_del(&frame->urb_frame_list);
784 } else {
785 spin_unlock_irqrestore(&dec->urb_frame_list_lock,
786 flags);
787 return;
788 }
789 spin_unlock_irqrestore(&dec->urb_frame_list_lock, flags);
790
791 ttusb_dec_process_urb_frame(dec, frame->data, frame->length);
792 kfree(frame);
793 }
794}
795
David Howells7d12e782006-10-05 14:55:46 +0100796static void ttusb_dec_process_urb(struct urb *urb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700797{
798 struct ttusb_dec *dec = urb->context;
799
800 if (!urb->status) {
801 int i;
802
803 for (i = 0; i < FRAMES_PER_ISO_BUF; i++) {
804 struct usb_iso_packet_descriptor *d;
805 u8 *b;
806 int length;
807 struct urb_frame *frame;
808
809 d = &urb->iso_frame_desc[i];
810 b = urb->transfer_buffer + d->offset;
811 length = d->actual_length;
812
813 if ((frame = kmalloc(sizeof(struct urb_frame),
814 GFP_ATOMIC))) {
815 unsigned long flags;
816
817 memcpy(frame->data, b, length);
818 frame->length = length;
819
820 spin_lock_irqsave(&dec->urb_frame_list_lock,
821 flags);
822 list_add_tail(&frame->urb_frame_list,
823 &dec->urb_frame_list);
824 spin_unlock_irqrestore(&dec->urb_frame_list_lock,
825 flags);
826
827 tasklet_schedule(&dec->urb_tasklet);
828 }
829 }
830 } else {
831 /* -ENOENT is expected when unlinking urbs */
832 if (urb->status != -ENOENT)
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300833 dprintk("%s: urb error: %d\n", __func__,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700834 urb->status);
835 }
836
837 if (dec->iso_stream_count)
838 usb_submit_urb(urb, GFP_ATOMIC);
839}
840
841static void ttusb_dec_setup_urbs(struct ttusb_dec *dec)
842{
843 int i, j, buffer_offset = 0;
844
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300845 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700846
847 for (i = 0; i < ISO_BUF_COUNT; i++) {
848 int frame_offset = 0;
849 struct urb *urb = dec->iso_urb[i];
850
851 urb->dev = dec->udev;
852 urb->context = dec;
853 urb->complete = ttusb_dec_process_urb;
854 urb->pipe = dec->in_pipe;
855 urb->transfer_flags = URB_ISO_ASAP;
856 urb->interval = 1;
857 urb->number_of_packets = FRAMES_PER_ISO_BUF;
858 urb->transfer_buffer_length = ISO_FRAME_SIZE *
859 FRAMES_PER_ISO_BUF;
860 urb->transfer_buffer = dec->iso_buffer + buffer_offset;
861 buffer_offset += ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF;
862
863 for (j = 0; j < FRAMES_PER_ISO_BUF; j++) {
864 urb->iso_frame_desc[j].offset = frame_offset;
865 urb->iso_frame_desc[j].length = ISO_FRAME_SIZE;
866 frame_offset += ISO_FRAME_SIZE;
867 }
868 }
869}
870
871static void ttusb_dec_stop_iso_xfer(struct ttusb_dec *dec)
872{
873 int i;
874
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300875 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700876
Ingo Molnar3593cab2006-02-07 06:49:14 -0200877 if (mutex_lock_interruptible(&dec->iso_mutex))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700878 return;
879
880 dec->iso_stream_count--;
881
882 if (!dec->iso_stream_count) {
883 for (i = 0; i < ISO_BUF_COUNT; i++)
884 usb_kill_urb(dec->iso_urb[i]);
885 }
886
Ingo Molnar3593cab2006-02-07 06:49:14 -0200887 mutex_unlock(&dec->iso_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700888}
889
890/* Setting the interface of the DEC tends to take down the USB communications
891 * for a short period, so it's important not to call this function just before
892 * trying to talk to it.
893 */
894static int ttusb_dec_set_interface(struct ttusb_dec *dec,
895 enum ttusb_dec_interface interface)
896{
897 int result = 0;
898 u8 b[] = { 0x05 };
899
900 if (interface != dec->interface) {
901 switch (interface) {
902 case TTUSB_DEC_INTERFACE_INITIAL:
903 result = usb_set_interface(dec->udev, 0, 0);
904 break;
905 case TTUSB_DEC_INTERFACE_IN:
906 result = ttusb_dec_send_command(dec, 0x80, sizeof(b),
907 b, NULL, NULL);
908 if (result)
909 return result;
910 result = usb_set_interface(dec->udev, 0, 8);
911 break;
912 case TTUSB_DEC_INTERFACE_OUT:
913 result = usb_set_interface(dec->udev, 0, 1);
914 break;
915 }
916
917 if (result)
918 return result;
919
920 dec->interface = interface;
921 }
922
923 return 0;
924}
925
926static int ttusb_dec_start_iso_xfer(struct ttusb_dec *dec)
927{
928 int i, result;
929
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300930 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700931
Ingo Molnar3593cab2006-02-07 06:49:14 -0200932 if (mutex_lock_interruptible(&dec->iso_mutex))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700933 return -EAGAIN;
934
935 if (!dec->iso_stream_count) {
936 ttusb_dec_setup_urbs(dec);
937
938 dec->packet_state = 0;
939 dec->v_pes_postbytes = 0;
940 dec->next_packet_id = 0;
941
942 for (i = 0; i < ISO_BUF_COUNT; i++) {
943 if ((result = usb_submit_urb(dec->iso_urb[i],
944 GFP_ATOMIC))) {
Mauro Carvalho Chehabbf769a42016-10-18 17:44:20 -0200945 printk("%s: failed urb submission %d: error %d\n",
946 __func__, i, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700947
948 while (i) {
949 usb_kill_urb(dec->iso_urb[i - 1]);
950 i--;
951 }
952
Ingo Molnar3593cab2006-02-07 06:49:14 -0200953 mutex_unlock(&dec->iso_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700954 return result;
955 }
956 }
957 }
958
959 dec->iso_stream_count++;
960
Ingo Molnar3593cab2006-02-07 06:49:14 -0200961 mutex_unlock(&dec->iso_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700962
963 return 0;
964}
965
966static int ttusb_dec_start_ts_feed(struct dvb_demux_feed *dvbdmxfeed)
967{
968 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
969 struct ttusb_dec *dec = dvbdmx->priv;
970 u8 b0[] = { 0x05 };
971 int result = 0;
972
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300973 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700974
975 dprintk(" ts_type:");
976
977 if (dvbdmxfeed->ts_type & TS_DECODER)
978 dprintk(" TS_DECODER");
979
980 if (dvbdmxfeed->ts_type & TS_PACKET)
981 dprintk(" TS_PACKET");
982
983 if (dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY)
984 dprintk(" TS_PAYLOAD_ONLY");
985
986 dprintk("\n");
987
988 switch (dvbdmxfeed->pes_type) {
989
Mauro Carvalho Chehabfde04ab2013-04-04 13:25:30 -0300990 case DMX_PES_VIDEO:
991 dprintk(" pes_type: DMX_PES_VIDEO\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700992 dec->pid[DMX_PES_PCR] = dvbdmxfeed->pid;
993 dec->pid[DMX_PES_VIDEO] = dvbdmxfeed->pid;
994 dec->video_filter = dvbdmxfeed->filter;
995 ttusb_dec_set_pids(dec);
996 break;
997
Mauro Carvalho Chehabfde04ab2013-04-04 13:25:30 -0300998 case DMX_PES_AUDIO:
999 dprintk(" pes_type: DMX_PES_AUDIO\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001000 dec->pid[DMX_PES_AUDIO] = dvbdmxfeed->pid;
1001 dec->audio_filter = dvbdmxfeed->filter;
1002 ttusb_dec_set_pids(dec);
1003 break;
1004
Mauro Carvalho Chehabfde04ab2013-04-04 13:25:30 -03001005 case DMX_PES_TELETEXT:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001006 dec->pid[DMX_PES_TELETEXT] = dvbdmxfeed->pid;
Mauro Carvalho Chehabfde04ab2013-04-04 13:25:30 -03001007 dprintk(" pes_type: DMX_PES_TELETEXT(not supported)\n");
Alex Woodsf961e712006-01-09 15:25:24 -02001008 return -ENOSYS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001009
Mauro Carvalho Chehabfde04ab2013-04-04 13:25:30 -03001010 case DMX_PES_PCR:
1011 dprintk(" pes_type: DMX_PES_PCR\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001012 dec->pid[DMX_PES_PCR] = dvbdmxfeed->pid;
1013 ttusb_dec_set_pids(dec);
1014 break;
1015
Mauro Carvalho Chehabfde04ab2013-04-04 13:25:30 -03001016 case DMX_PES_OTHER:
1017 dprintk(" pes_type: DMX_PES_OTHER(not supported)\n");
Alex Woodsf961e712006-01-09 15:25:24 -02001018 return -ENOSYS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001019
1020 default:
1021 dprintk(" pes_type: unknown (%d)\n", dvbdmxfeed->pes_type);
1022 return -EINVAL;
1023
1024 }
1025
1026 result = ttusb_dec_send_command(dec, 0x80, sizeof(b0), b0, NULL, NULL);
1027 if (result)
1028 return result;
1029
1030 dec->pva_stream_count++;
1031 return ttusb_dec_start_iso_xfer(dec);
1032}
1033
1034static int ttusb_dec_start_sec_feed(struct dvb_demux_feed *dvbdmxfeed)
1035{
1036 struct ttusb_dec *dec = dvbdmxfeed->demux->priv;
1037 u8 b0[] = { 0x00, 0x00, 0x00, 0x01,
1038 0x00, 0x00, 0x00, 0x00,
1039 0x00, 0x00, 0x00, 0x00,
1040 0x00, 0x00, 0x00, 0x00,
1041 0x00, 0xff, 0x00, 0x00,
1042 0x00, 0x00, 0x00, 0x00,
1043 0x00, 0x00, 0x00, 0x00,
1044 0x00 };
Al Virod4f979a2008-05-21 00:31:31 -03001045 __be16 pid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001046 u8 c[COMMAND_PACKET_SIZE];
1047 int c_length;
1048 int result;
1049 struct filter_info *finfo;
1050 unsigned long flags;
1051 u8 x = 1;
1052
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001053 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001054
1055 pid = htons(dvbdmxfeed->pid);
1056 memcpy(&b0[0], &pid, 2);
1057 memcpy(&b0[4], &x, 1);
1058 memcpy(&b0[5], &dvbdmxfeed->filter->filter.filter_value[0], 1);
1059
1060 result = ttusb_dec_send_command(dec, 0x60, sizeof(b0), b0,
1061 &c_length, c);
1062
1063 if (!result) {
1064 if (c_length == 2) {
1065 if (!(finfo = kmalloc(sizeof(struct filter_info),
1066 GFP_ATOMIC)))
1067 return -ENOMEM;
1068
1069 finfo->stream_id = c[1];
1070 finfo->filter = dvbdmxfeed->filter;
1071
1072 spin_lock_irqsave(&dec->filter_info_list_lock, flags);
1073 list_add_tail(&finfo->filter_info_list,
1074 &dec->filter_info_list);
1075 spin_unlock_irqrestore(&dec->filter_info_list_lock,
1076 flags);
1077
1078 dvbdmxfeed->priv = finfo;
1079
1080 dec->filter_stream_count++;
1081 return ttusb_dec_start_iso_xfer(dec);
1082 }
1083
1084 return -EAGAIN;
1085 } else
1086 return result;
1087}
1088
1089static int ttusb_dec_start_feed(struct dvb_demux_feed *dvbdmxfeed)
1090{
1091 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
1092
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001093 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001094
1095 if (!dvbdmx->dmx.frontend)
1096 return -EINVAL;
1097
1098 dprintk(" pid: 0x%04X\n", dvbdmxfeed->pid);
1099
1100 switch (dvbdmxfeed->type) {
1101
1102 case DMX_TYPE_TS:
1103 return ttusb_dec_start_ts_feed(dvbdmxfeed);
1104 break;
1105
1106 case DMX_TYPE_SEC:
1107 return ttusb_dec_start_sec_feed(dvbdmxfeed);
1108 break;
1109
1110 default:
1111 dprintk(" type: unknown (%d)\n", dvbdmxfeed->type);
1112 return -EINVAL;
1113
1114 }
1115}
1116
1117static int ttusb_dec_stop_ts_feed(struct dvb_demux_feed *dvbdmxfeed)
1118{
1119 struct ttusb_dec *dec = dvbdmxfeed->demux->priv;
1120 u8 b0[] = { 0x00 };
1121
1122 ttusb_dec_send_command(dec, 0x81, sizeof(b0), b0, NULL, NULL);
1123
1124 dec->pva_stream_count--;
1125
1126 ttusb_dec_stop_iso_xfer(dec);
1127
1128 return 0;
1129}
1130
1131static int ttusb_dec_stop_sec_feed(struct dvb_demux_feed *dvbdmxfeed)
1132{
1133 struct ttusb_dec *dec = dvbdmxfeed->demux->priv;
1134 u8 b0[] = { 0x00, 0x00 };
1135 struct filter_info *finfo = (struct filter_info *)dvbdmxfeed->priv;
1136 unsigned long flags;
1137
1138 b0[1] = finfo->stream_id;
1139 spin_lock_irqsave(&dec->filter_info_list_lock, flags);
1140 list_del(&finfo->filter_info_list);
1141 spin_unlock_irqrestore(&dec->filter_info_list_lock, flags);
1142 kfree(finfo);
1143 ttusb_dec_send_command(dec, 0x62, sizeof(b0), b0, NULL, NULL);
1144
1145 dec->filter_stream_count--;
1146
1147 ttusb_dec_stop_iso_xfer(dec);
1148
1149 return 0;
1150}
1151
1152static int ttusb_dec_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
1153{
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001154 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001155
1156 switch (dvbdmxfeed->type) {
1157 case DMX_TYPE_TS:
1158 return ttusb_dec_stop_ts_feed(dvbdmxfeed);
1159 break;
1160
1161 case DMX_TYPE_SEC:
1162 return ttusb_dec_stop_sec_feed(dvbdmxfeed);
1163 break;
1164 }
1165
1166 return 0;
1167}
1168
1169static void ttusb_dec_free_iso_urbs(struct ttusb_dec *dec)
1170{
1171 int i;
1172
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001173 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001174
1175 for (i = 0; i < ISO_BUF_COUNT; i++)
Mariusz Kozlowski5d02d022006-11-08 15:34:27 +01001176 usb_free_urb(dec->iso_urb[i]);
Christoph Hellwig8d669f92018-01-10 19:03:20 +01001177 kfree(dec->iso_buffer);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001178}
1179
1180static int ttusb_dec_alloc_iso_urbs(struct ttusb_dec *dec)
1181{
1182 int i;
1183
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001184 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001185
Christoph Hellwig8d669f92018-01-10 19:03:20 +01001186 dec->iso_buffer = kcalloc(FRAMES_PER_ISO_BUF * ISO_BUF_COUNT,
1187 ISO_FRAME_SIZE, GFP_KERNEL);
1188 if (!dec->iso_buffer)
Douglas Schilling Landgrafd7c31a12008-11-11 23:27:59 -03001189 return -ENOMEM;
Douglas Schilling Landgrafd7c31a12008-11-11 23:27:59 -03001190
Linus Torvalds1da177e2005-04-16 15:20:36 -07001191 for (i = 0; i < ISO_BUF_COUNT; i++) {
1192 struct urb *urb;
1193
1194 if (!(urb = usb_alloc_urb(FRAMES_PER_ISO_BUF, GFP_ATOMIC))) {
1195 ttusb_dec_free_iso_urbs(dec);
1196 return -ENOMEM;
1197 }
1198
1199 dec->iso_urb[i] = urb;
1200 }
1201
1202 ttusb_dec_setup_urbs(dec);
1203
1204 return 0;
1205}
1206
1207static void ttusb_dec_init_tasklet(struct ttusb_dec *dec)
1208{
1209 spin_lock_init(&dec->urb_frame_list_lock);
1210 INIT_LIST_HEAD(&dec->urb_frame_list);
1211 tasklet_init(&dec->urb_tasklet, ttusb_dec_process_urb_frame_list,
1212 (unsigned long)dec);
1213}
1214
Michael Krufky50c25ff2006-01-09 15:25:34 -02001215static int ttusb_init_rc( struct ttusb_dec *dec)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001216{
Dmitry Torokhovb7df3912005-09-15 02:01:53 -05001217 struct input_dev *input_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001218 u8 b[] = { 0x00, 0x01 };
1219 int i;
Dmitry Torokhovb07b4782006-11-20 10:23:04 -03001220 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001221
Dmitry Torokhovb7df3912005-09-15 02:01:53 -05001222 usb_make_path(dec->udev, dec->rc_phys, sizeof(dec->rc_phys));
Márton Némethb1858192009-11-21 13:46:12 -03001223 strlcat(dec->rc_phys, "/input0", sizeof(dec->rc_phys));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001224
Dmitry Torokhovb07b4782006-11-20 10:23:04 -03001225 input_dev = input_allocate_device();
Dmitry Torokhovb7df3912005-09-15 02:01:53 -05001226 if (!input_dev)
1227 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001228
Dmitry Torokhovb7df3912005-09-15 02:01:53 -05001229 input_dev->name = "ttusb_dec remote control";
1230 input_dev->phys = dec->rc_phys;
Jiri Slaby7b19ada2007-10-18 23:40:32 -07001231 input_dev->evbit[0] = BIT_MASK(EV_KEY);
Dmitry Torokhovb7df3912005-09-15 02:01:53 -05001232 input_dev->keycodesize = sizeof(u16);
1233 input_dev->keycodemax = 0x1a;
1234 input_dev->keycode = rc_keys;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001235
Dmitry Torokhovb7df3912005-09-15 02:01:53 -05001236 for (i = 0; i < ARRAY_SIZE(rc_keys); i++)
Michael Krufky50c25ff2006-01-09 15:25:34 -02001237 set_bit(rc_keys[i], input_dev->keybit);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001238
Dmitry Torokhovb07b4782006-11-20 10:23:04 -03001239 err = input_register_device(input_dev);
1240 if (err) {
1241 input_free_device(input_dev);
1242 return err;
1243 }
Dmitry Torokhovb7df3912005-09-15 02:01:53 -05001244
Dmitry Torokhovb07b4782006-11-20 10:23:04 -03001245 dec->rc_input_dev = input_dev;
Dmitry Torokhovb7df3912005-09-15 02:01:53 -05001246 if (usb_submit_urb(dec->irq_urb, GFP_KERNEL))
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001247 printk("%s: usb_submit_urb failed\n",__func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001248 /* enable irq pipe */
1249 ttusb_dec_send_command(dec,0xb0,sizeof(b),b,NULL,NULL);
Dmitry Torokhovb7df3912005-09-15 02:01:53 -05001250
1251 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001252}
1253
1254static void ttusb_dec_init_v_pes(struct ttusb_dec *dec)
1255{
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001256 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001257
1258 dec->v_pes[0] = 0x00;
1259 dec->v_pes[1] = 0x00;
1260 dec->v_pes[2] = 0x01;
1261 dec->v_pes[3] = 0xe0;
1262}
1263
1264static int ttusb_dec_init_usb(struct ttusb_dec *dec)
1265{
Alexey Khoroshilovcf732b52013-10-02 13:00:26 -03001266 int result;
1267
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001268 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001269
Ingo Molnar3593cab2006-02-07 06:49:14 -02001270 mutex_init(&dec->usb_mutex);
1271 mutex_init(&dec->iso_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001272
1273 dec->command_pipe = usb_sndbulkpipe(dec->udev, COMMAND_PIPE);
1274 dec->result_pipe = usb_rcvbulkpipe(dec->udev, RESULT_PIPE);
1275 dec->in_pipe = usb_rcvisocpipe(dec->udev, IN_PIPE);
1276 dec->out_pipe = usb_sndisocpipe(dec->udev, OUT_PIPE);
1277 dec->irq_pipe = usb_rcvintpipe(dec->udev, IRQ_PIPE);
1278
1279 if(enable_rc) {
1280 dec->irq_urb = usb_alloc_urb(0, GFP_KERNEL);
1281 if(!dec->irq_urb) {
1282 return -ENOMEM;
1283 }
Daniel Mack997ea582010-04-12 13:17:25 +02001284 dec->irq_buffer = usb_alloc_coherent(dec->udev,IRQ_PACKET_SIZE,
Alexey Khoroshilovcf732b52013-10-02 13:00:26 -03001285 GFP_KERNEL, &dec->irq_dma_handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001286 if(!dec->irq_buffer) {
Douglas Schilling Landgraf7935eea2008-11-11 23:47:57 -03001287 usb_free_urb(dec->irq_urb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001288 return -ENOMEM;
1289 }
1290 usb_fill_int_urb(dec->irq_urb, dec->udev,dec->irq_pipe,
1291 dec->irq_buffer, IRQ_PACKET_SIZE,
1292 ttusb_dec_handle_irq, dec, 1);
1293 dec->irq_urb->transfer_dma = dec->irq_dma_handle;
1294 dec->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
1295 }
1296
Alexey Khoroshilovcf732b52013-10-02 13:00:26 -03001297 result = ttusb_dec_alloc_iso_urbs(dec);
1298 if (result) {
1299 usb_free_urb(dec->irq_urb);
1300 usb_free_coherent(dec->udev, IRQ_PACKET_SIZE,
1301 dec->irq_buffer, dec->irq_dma_handle);
1302 }
1303 return result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001304}
1305
1306static int ttusb_dec_boot_dsp(struct ttusb_dec *dec)
1307{
1308 int i, j, actual_len, result, size, trans_count;
1309 u8 b0[] = { 0x00, 0x00, 0x00, 0x00,
1310 0x00, 0x00, 0x00, 0x00,
1311 0x61, 0x00 };
1312 u8 b1[] = { 0x61 };
1313 u8 *b;
1314 char idstring[21];
David Woodhouse99b6e4f2008-05-24 00:12:00 +01001315 const u8 *firmware = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001316 size_t firmware_size = 0;
1317 u16 firmware_csum = 0;
Al Virod4f979a2008-05-21 00:31:31 -03001318 __be16 firmware_csum_ns;
1319 __be32 firmware_size_nl;
1320 u32 crc32_csum, crc32_check;
1321 __be32 tmp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001322 const struct firmware *fw_entry = NULL;
1323
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001324 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001325
Alexey Khoroshilovcf732b52013-10-02 13:00:26 -03001326 result = request_firmware(&fw_entry, dec->firmware_name, &dec->udev->dev);
1327 if (result) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001328 printk(KERN_ERR "%s: Firmware (%s) unavailable.\n",
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001329 __func__, dec->firmware_name);
Alexey Khoroshilovcf732b52013-10-02 13:00:26 -03001330 return result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001331 }
1332
1333 firmware = fw_entry->data;
1334 firmware_size = fw_entry->size;
1335
1336 if (firmware_size < 60) {
1337 printk("%s: firmware size too small for DSP code (%zu < 60).\n",
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001338 __func__, firmware_size);
Anssi Hannula0c744b02005-07-07 17:57:42 -07001339 release_firmware(fw_entry);
Alexey Khoroshilovcf732b52013-10-02 13:00:26 -03001340 return -ENOENT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001341 }
1342
1343 /* a 32 bit checksum over the first 56 bytes of the DSP Code is stored
1344 at offset 56 of file, so use it to check if the firmware file is
1345 valid. */
1346 crc32_csum = crc32(~0L, firmware, 56) ^ ~0L;
1347 memcpy(&tmp, &firmware[56], 4);
Al Virod4f979a2008-05-21 00:31:31 -03001348 crc32_check = ntohl(tmp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001349 if (crc32_csum != crc32_check) {
Mauro Carvalho Chehabbf769a42016-10-18 17:44:20 -02001350 printk("%s: crc32 check of DSP code failed (calculated 0x%08x != 0x%08x in file), file invalid.\n",
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001351 __func__, crc32_csum, crc32_check);
Anssi Hannula0c744b02005-07-07 17:57:42 -07001352 release_firmware(fw_entry);
Alexey Khoroshilovcf732b52013-10-02 13:00:26 -03001353 return -ENOENT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001354 }
1355 memcpy(idstring, &firmware[36], 20);
1356 idstring[20] = '\0';
1357 printk(KERN_INFO "ttusb_dec: found DSP code \"%s\".\n", idstring);
1358
1359 firmware_size_nl = htonl(firmware_size);
1360 memcpy(b0, &firmware_size_nl, 4);
1361 firmware_csum = crc16(~0, firmware, firmware_size) ^ ~0;
1362 firmware_csum_ns = htons(firmware_csum);
1363 memcpy(&b0[6], &firmware_csum_ns, 2);
1364
1365 result = ttusb_dec_send_command(dec, 0x41, sizeof(b0), b0, NULL, NULL);
1366
Anssi Hannula0c744b02005-07-07 17:57:42 -07001367 if (result) {
1368 release_firmware(fw_entry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001369 return result;
Anssi Hannula0c744b02005-07-07 17:57:42 -07001370 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001371
1372 trans_count = 0;
1373 j = 0;
1374
1375 b = kmalloc(ARM_PACKET_SIZE, GFP_KERNEL);
Anssi Hannula0c744b02005-07-07 17:57:42 -07001376 if (b == NULL) {
1377 release_firmware(fw_entry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001378 return -ENOMEM;
Anssi Hannula0c744b02005-07-07 17:57:42 -07001379 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001380
1381 for (i = 0; i < firmware_size; i += COMMAND_PACKET_SIZE) {
1382 size = firmware_size - i;
1383 if (size > COMMAND_PACKET_SIZE)
1384 size = COMMAND_PACKET_SIZE;
1385
1386 b[j + 0] = 0xaa;
1387 b[j + 1] = trans_count++;
1388 b[j + 2] = 0xf0;
1389 b[j + 3] = size;
1390 memcpy(&b[j + 4], &firmware[i], size);
1391
1392 j += COMMAND_PACKET_SIZE + 4;
1393
1394 if (j >= ARM_PACKET_SIZE) {
1395 result = usb_bulk_msg(dec->udev, dec->command_pipe, b,
1396 ARM_PACKET_SIZE, &actual_len,
1397 100);
1398 j = 0;
1399 } else if (size < COMMAND_PACKET_SIZE) {
1400 result = usb_bulk_msg(dec->udev, dec->command_pipe, b,
1401 j - COMMAND_PACKET_SIZE + size,
1402 &actual_len, 100);
1403 }
1404 }
1405
1406 result = ttusb_dec_send_command(dec, 0x43, sizeof(b1), b1, NULL, NULL);
1407
Anssi Hannula0c744b02005-07-07 17:57:42 -07001408 release_firmware(fw_entry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001409 kfree(b);
1410
1411 return result;
1412}
1413
1414static int ttusb_dec_init_stb(struct ttusb_dec *dec)
1415{
1416 int result;
Hans Verkuilcf8e1932009-01-17 13:09:11 -03001417 unsigned int mode = 0, model = 0, version = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001418
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001419 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001420
1421 result = ttusb_dec_get_stb_state(dec, &mode, &model, &version);
Alexey Khoroshilovcf732b52013-10-02 13:00:26 -03001422 if (result)
1423 return result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001424
Alexey Khoroshilovcf732b52013-10-02 13:00:26 -03001425 if (!mode) {
1426 if (version == 0xABCDEFAB)
Mauro Carvalho Chehabbf769a42016-10-18 17:44:20 -02001427 printk(KERN_INFO "ttusb_dec: no version info in Firmware\n");
Alexey Khoroshilovcf732b52013-10-02 13:00:26 -03001428 else
Mauro Carvalho Chehabbf769a42016-10-18 17:44:20 -02001429 printk(KERN_INFO "ttusb_dec: Firmware %x.%02x%c%c\n",
Alexey Khoroshilovcf732b52013-10-02 13:00:26 -03001430 version >> 24, (version >> 16) & 0xff,
1431 (version >> 8) & 0xff, version & 0xff);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001432
Alexey Khoroshilovcf732b52013-10-02 13:00:26 -03001433 result = ttusb_dec_boot_dsp(dec);
1434 if (result)
1435 return result;
1436 } else {
1437 /* We can't trust the USB IDs that some firmwares
1438 give the box */
1439 switch (model) {
1440 case 0x00070001:
1441 case 0x00070008:
1442 case 0x0007000c:
1443 ttusb_dec_set_model(dec, TTUSB_DEC3000S);
1444 break;
1445 case 0x00070009:
1446 case 0x00070013:
1447 ttusb_dec_set_model(dec, TTUSB_DEC2000T);
1448 break;
1449 case 0x00070011:
1450 ttusb_dec_set_model(dec, TTUSB_DEC2540T);
1451 break;
1452 default:
Mauro Carvalho Chehabbf769a42016-10-18 17:44:20 -02001453 printk(KERN_ERR "%s: unknown model returned by firmware (%08x) - please report\n",
Alexey Khoroshilovcf732b52013-10-02 13:00:26 -03001454 __func__, model);
1455 return -ENOENT;
1456 }
Mauro Carvalho Chehab3ff105e2015-04-29 17:09:50 -03001457 if (version >= 0x01770000)
1458 dec->can_playback = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001459 }
Alexey Khoroshilovcf732b52013-10-02 13:00:26 -03001460 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001461}
1462
1463static int ttusb_dec_init_dvb(struct ttusb_dec *dec)
1464{
1465 int result;
1466
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001467 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001468
1469 if ((result = dvb_register_adapter(&dec->adapter,
Janne Grunau78e920062008-04-09 19:13:13 -03001470 dec->model_name, THIS_MODULE,
1471 &dec->udev->dev,
1472 adapter_nr)) < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001473 printk("%s: dvb_register_adapter failed: error %d\n",
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001474 __func__, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001475
1476 return result;
1477 }
1478
1479 dec->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
1480
1481 dec->demux.priv = (void *)dec;
1482 dec->demux.filternum = 31;
1483 dec->demux.feednum = 31;
1484 dec->demux.start_feed = ttusb_dec_start_feed;
1485 dec->demux.stop_feed = ttusb_dec_stop_feed;
1486 dec->demux.write_to_decoder = NULL;
1487
1488 if ((result = dvb_dmx_init(&dec->demux)) < 0) {
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001489 printk("%s: dvb_dmx_init failed: error %d\n", __func__,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001490 result);
1491
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001492 dvb_unregister_adapter(&dec->adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001493
1494 return result;
1495 }
1496
1497 dec->dmxdev.filternum = 32;
1498 dec->dmxdev.demux = &dec->demux.dmx;
1499 dec->dmxdev.capabilities = 0;
1500
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001501 if ((result = dvb_dmxdev_init(&dec->dmxdev, &dec->adapter)) < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001502 printk("%s: dvb_dmxdev_init failed: error %d\n",
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001503 __func__, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001504
1505 dvb_dmx_release(&dec->demux);
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001506 dvb_unregister_adapter(&dec->adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001507
1508 return result;
1509 }
1510
1511 dec->frontend.source = DMX_FRONTEND_0;
1512
1513 if ((result = dec->demux.dmx.add_frontend(&dec->demux.dmx,
1514 &dec->frontend)) < 0) {
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001515 printk("%s: dvb_dmx_init failed: error %d\n", __func__,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001516 result);
1517
1518 dvb_dmxdev_release(&dec->dmxdev);
1519 dvb_dmx_release(&dec->demux);
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001520 dvb_unregister_adapter(&dec->adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001521
1522 return result;
1523 }
1524
1525 if ((result = dec->demux.dmx.connect_frontend(&dec->demux.dmx,
1526 &dec->frontend)) < 0) {
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001527 printk("%s: dvb_dmx_init failed: error %d\n", __func__,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001528 result);
1529
1530 dec->demux.dmx.remove_frontend(&dec->demux.dmx, &dec->frontend);
1531 dvb_dmxdev_release(&dec->dmxdev);
1532 dvb_dmx_release(&dec->demux);
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001533 dvb_unregister_adapter(&dec->adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001534
1535 return result;
1536 }
1537
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001538 dvb_net_init(&dec->adapter, &dec->dvb_net, &dec->demux.dmx);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001539
1540 return 0;
1541}
1542
1543static void ttusb_dec_exit_dvb(struct ttusb_dec *dec)
1544{
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001545 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001546
1547 dvb_net_release(&dec->dvb_net);
1548 dec->demux.dmx.close(&dec->demux.dmx);
1549 dec->demux.dmx.remove_frontend(&dec->demux.dmx, &dec->frontend);
1550 dvb_dmxdev_release(&dec->dmxdev);
1551 dvb_dmx_release(&dec->demux);
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001552 if (dec->fe) {
1553 dvb_unregister_frontend(dec->fe);
1554 if (dec->fe->ops.release)
1555 dec->fe->ops.release(dec->fe);
1556 }
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001557 dvb_unregister_adapter(&dec->adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001558}
1559
1560static void ttusb_dec_exit_rc(struct ttusb_dec *dec)
1561{
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001562 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001563
Dmitry Torokhovb7df3912005-09-15 02:01:53 -05001564 if (dec->rc_input_dev) {
1565 input_unregister_device(dec->rc_input_dev);
1566 dec->rc_input_dev = NULL;
1567 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001568}
1569
1570
1571static void ttusb_dec_exit_usb(struct ttusb_dec *dec)
1572{
1573 int i;
1574
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001575 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001576
Alexey Khoroshilovcf732b52013-10-02 13:00:26 -03001577 if (enable_rc) {
1578 /* we have to check whether the irq URB is already submitted.
1579 * As the irq is submitted after the interface is changed,
1580 * this is the best method i figured out.
1581 * Any others?*/
1582 if (dec->interface == TTUSB_DEC_INTERFACE_IN)
1583 usb_kill_urb(dec->irq_urb);
1584
1585 usb_free_urb(dec->irq_urb);
1586
1587 usb_free_coherent(dec->udev, IRQ_PACKET_SIZE,
1588 dec->irq_buffer, dec->irq_dma_handle);
1589 }
1590
Linus Torvalds1da177e2005-04-16 15:20:36 -07001591 dec->iso_stream_count = 0;
1592
1593 for (i = 0; i < ISO_BUF_COUNT; i++)
1594 usb_kill_urb(dec->iso_urb[i]);
1595
1596 ttusb_dec_free_iso_urbs(dec);
1597}
1598
1599static void ttusb_dec_exit_tasklet(struct ttusb_dec *dec)
1600{
1601 struct list_head *item;
1602 struct urb_frame *frame;
1603
1604 tasklet_kill(&dec->urb_tasklet);
1605
1606 while ((item = dec->urb_frame_list.next) != &dec->urb_frame_list) {
1607 frame = list_entry(item, struct urb_frame, urb_frame_list);
1608 list_del(&frame->urb_frame_list);
1609 kfree(frame);
1610 }
1611}
1612
1613static void ttusb_dec_init_filters(struct ttusb_dec *dec)
1614{
1615 INIT_LIST_HEAD(&dec->filter_info_list);
1616 spin_lock_init(&dec->filter_info_list_lock);
1617}
1618
1619static void ttusb_dec_exit_filters(struct ttusb_dec *dec)
1620{
1621 struct list_head *item;
1622 struct filter_info *finfo;
1623
1624 while ((item = dec->filter_info_list.next) != &dec->filter_info_list) {
1625 finfo = list_entry(item, struct filter_info, filter_info_list);
1626 list_del(&finfo->filter_info_list);
1627 kfree(finfo);
1628 }
1629}
1630
Johannes Stezenbachd91b7302005-05-16 21:54:38 -07001631static int fe_send_command(struct dvb_frontend* fe, const u8 command,
1632 int param_length, const u8 params[],
1633 int *result_length, u8 cmd_result[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07001634{
Alex Woodsf961e712006-01-09 15:25:24 -02001635 struct ttusb_dec* dec = fe->dvb->priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001636 return ttusb_dec_send_command(dec, command, param_length, params, result_length, cmd_result);
1637}
1638
Julia Lawall9bca6262015-11-13 12:55:18 -02001639static const struct ttusbdecfe_config fe_config = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001640 .send_command = fe_send_command
1641};
1642
1643static int ttusb_dec_probe(struct usb_interface *intf,
1644 const struct usb_device_id *id)
1645{
1646 struct usb_device *udev;
1647 struct ttusb_dec *dec;
Alexey Khoroshilovcf732b52013-10-02 13:00:26 -03001648 int result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001649
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001650 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001651
1652 udev = interface_to_usbdev(intf);
1653
Panagiotis Issaris74081872006-01-11 19:40:56 -02001654 if (!(dec = kzalloc(sizeof(struct ttusb_dec), GFP_KERNEL))) {
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001655 printk("%s: couldn't allocate memory.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001656 return -ENOMEM;
1657 }
1658
1659 usb_set_intfdata(intf, (void *)dec);
1660
Al Virod4f979a2008-05-21 00:31:31 -03001661 switch (id->idProduct) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001662 case 0x1006:
1663 ttusb_dec_set_model(dec, TTUSB_DEC3000S);
1664 break;
1665
1666 case 0x1008:
1667 ttusb_dec_set_model(dec, TTUSB_DEC2000T);
1668 break;
1669
1670 case 0x1009:
1671 ttusb_dec_set_model(dec, TTUSB_DEC2540T);
1672 break;
1673 }
1674
1675 dec->udev = udev;
1676
Alexey Khoroshilovcf732b52013-10-02 13:00:26 -03001677 result = ttusb_dec_init_usb(dec);
1678 if (result)
1679 goto err_usb;
1680 result = ttusb_dec_init_stb(dec);
1681 if (result)
1682 goto err_stb;
1683 result = ttusb_dec_init_dvb(dec);
1684 if (result)
1685 goto err_stb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001686
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001687 dec->adapter.priv = dec;
Al Virod4f979a2008-05-21 00:31:31 -03001688 switch (id->idProduct) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001689 case 0x1006:
1690 dec->fe = ttusbdecfe_dvbs_attach(&fe_config);
1691 break;
1692
1693 case 0x1008:
1694 case 0x1009:
1695 dec->fe = ttusbdecfe_dvbt_attach(&fe_config);
1696 break;
1697 }
1698
1699 if (dec->fe == NULL) {
Bjorn Helgaas29e66a62008-09-04 17:24:51 -03001700 printk("dvb-ttusb-dec: A frontend driver was not found for device [%04x:%04x]\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001701 le16_to_cpu(dec->udev->descriptor.idVendor),
1702 le16_to_cpu(dec->udev->descriptor.idProduct));
1703 } else {
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001704 if (dvb_register_frontend(&dec->adapter, dec->fe)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001705 printk("budget-ci: Frontend registration failed!\n");
Patrick Boettcherdea74862006-05-14 05:01:31 -03001706 if (dec->fe->ops.release)
1707 dec->fe->ops.release(dec->fe);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001708 dec->fe = NULL;
1709 }
1710 }
1711
1712 ttusb_dec_init_v_pes(dec);
1713 ttusb_dec_init_filters(dec);
1714 ttusb_dec_init_tasklet(dec);
1715
1716 dec->active = 1;
1717
1718 ttusb_dec_set_interface(dec, TTUSB_DEC_INTERFACE_IN);
1719
Dmitry Torokhovb7df3912005-09-15 02:01:53 -05001720 if (enable_rc)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001721 ttusb_init_rc(dec);
1722
1723 return 0;
Alexey Khoroshilovcf732b52013-10-02 13:00:26 -03001724err_stb:
1725 ttusb_dec_exit_usb(dec);
1726err_usb:
1727 kfree(dec);
1728 return result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001729}
1730
1731static void ttusb_dec_disconnect(struct usb_interface *intf)
1732{
1733 struct ttusb_dec *dec = usb_get_intfdata(intf);
1734
1735 usb_set_intfdata(intf, NULL);
1736
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001737 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001738
1739 if (dec->active) {
1740 ttusb_dec_exit_tasklet(dec);
1741 ttusb_dec_exit_filters(dec);
1742 if(enable_rc)
1743 ttusb_dec_exit_rc(dec);
1744 ttusb_dec_exit_usb(dec);
1745 ttusb_dec_exit_dvb(dec);
1746 }
1747
1748 kfree(dec);
1749}
1750
1751static void ttusb_dec_set_model(struct ttusb_dec *dec,
1752 enum ttusb_dec_model model)
1753{
1754 dec->model = model;
1755
1756 switch (model) {
1757 case TTUSB_DEC2000T:
1758 dec->model_name = "DEC2000-t";
1759 dec->firmware_name = "dvb-ttusb-dec-2000t.fw";
1760 break;
1761
1762 case TTUSB_DEC2540T:
1763 dec->model_name = "DEC2540-t";
1764 dec->firmware_name = "dvb-ttusb-dec-2540t.fw";
1765 break;
1766
1767 case TTUSB_DEC3000S:
1768 dec->model_name = "DEC3000-s";
1769 dec->firmware_name = "dvb-ttusb-dec-3000s.fw";
1770 break;
1771 }
1772}
1773
Arvind Yadav7fb2e072017-08-13 04:54:43 -04001774static const struct usb_device_id ttusb_dec_table[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001775 {USB_DEVICE(0x0b48, 0x1006)}, /* DEC3000-s */
1776 /*{USB_DEVICE(0x0b48, 0x1007)}, Unconfirmed */
1777 {USB_DEVICE(0x0b48, 0x1008)}, /* DEC2000-t */
1778 {USB_DEVICE(0x0b48, 0x1009)}, /* DEC2540-t */
1779 {}
1780};
1781
1782static struct usb_driver ttusb_dec_driver = {
1783 .name = "ttusb-dec",
1784 .probe = ttusb_dec_probe,
1785 .disconnect = ttusb_dec_disconnect,
1786 .id_table = ttusb_dec_table,
1787};
1788
Greg Kroah-Hartmanecb3b2b2011-11-18 09:46:12 -08001789module_usb_driver(ttusb_dec_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001790
1791MODULE_AUTHOR("Alex Woods <linux-dvb@giblets.org>");
1792MODULE_DESCRIPTION(DRIVER_NAME);
1793MODULE_LICENSE("GPL");
1794MODULE_DEVICE_TABLE(usb, ttusb_dec_table);