blob: cdefb5dfbbdcda39fbe1bbc840c5042836d3bc15 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * TTUSB DEC Driver
3 *
4 * Copyright (C) 2003-2004 Alex Woods <linux-dvb@giblets.org>
5 * IR support by Peter Beutner <p.beutner@gmx.net>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070017 */
18
Linus Torvalds1da177e2005-04-16 15:20:36 -070019#include <linux/list.h>
20#include <linux/module.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070021#include <linux/pci.h>
22#include <linux/slab.h>
23#include <linux/spinlock.h>
24#include <linux/usb.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070025#include <linux/interrupt.h>
26#include <linux/firmware.h>
27#include <linux/crc32.h>
28#include <linux/init.h>
29#include <linux/input.h>
30
Trent Piepho68277092007-01-30 23:25:46 -030031#include <linux/mutex.h>
32
Linus Torvalds1da177e2005-04-16 15:20:36 -070033#include "dmxdev.h"
34#include "dvb_demux.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070035#include "dvb_frontend.h"
36#include "dvb_net.h"
37#include "ttusbdecfe.h"
38
39static int debug;
40static int output_pva;
41static int enable_rc;
42
43module_param(debug, int, 0644);
44MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
45module_param(output_pva, int, 0444);
46MODULE_PARM_DESC(output_pva, "Output PVA from dvr device (default:off)");
47module_param(enable_rc, int, 0644);
48MODULE_PARM_DESC(enable_rc, "Turn on/off IR remote control(default: off)");
49
Janne Grunau78e920062008-04-09 19:13:13 -030050DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
51
Linus Torvalds1da177e2005-04-16 15:20:36 -070052#define dprintk if (debug) printk
53
54#define DRIVER_NAME "TechnoTrend/Hauppauge DEC USB"
55
56#define COMMAND_PIPE 0x03
57#define RESULT_PIPE 0x04
58#define IN_PIPE 0x08
59#define OUT_PIPE 0x07
60#define IRQ_PIPE 0x0A
61
62#define COMMAND_PACKET_SIZE 0x3c
63#define ARM_PACKET_SIZE 0x1000
64#define IRQ_PACKET_SIZE 0x8
65
66#define ISO_BUF_COUNT 0x04
67#define FRAMES_PER_ISO_BUF 0x04
68#define ISO_FRAME_SIZE 0x0380
69
70#define MAX_PVA_LENGTH 6144
71
72enum ttusb_dec_model {
73 TTUSB_DEC2000T,
74 TTUSB_DEC2540T,
75 TTUSB_DEC3000S
76};
77
78enum ttusb_dec_packet_type {
79 TTUSB_DEC_PACKET_PVA,
80 TTUSB_DEC_PACKET_SECTION,
81 TTUSB_DEC_PACKET_EMPTY
82};
83
84enum ttusb_dec_interface {
85 TTUSB_DEC_INTERFACE_INITIAL,
86 TTUSB_DEC_INTERFACE_IN,
87 TTUSB_DEC_INTERFACE_OUT
88};
89
Mauro Carvalho Chehabb676e732016-10-13 07:41:38 -030090typedef int (dvb_filter_pes2ts_cb_t) (void *, unsigned char *);
91
92struct dvb_filter_pes2ts {
93 unsigned char buf[188];
94 unsigned char cc;
95 dvb_filter_pes2ts_cb_t *cb;
96 void *priv;
97};
98
Linus Torvalds1da177e2005-04-16 15:20:36 -070099struct ttusb_dec {
100 enum ttusb_dec_model model;
101 char *model_name;
102 char *firmware_name;
103 int can_playback;
104
105 /* DVB bits */
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -0700106 struct dvb_adapter adapter;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700107 struct dmxdev dmxdev;
108 struct dvb_demux demux;
109 struct dmx_frontend frontend;
110 struct dvb_net dvb_net;
111 struct dvb_frontend* fe;
112
113 u16 pid[DMX_PES_OTHER];
114
115 /* USB bits */
116 struct usb_device *udev;
117 u8 trans_count;
118 unsigned int command_pipe;
119 unsigned int result_pipe;
120 unsigned int in_pipe;
121 unsigned int out_pipe;
122 unsigned int irq_pipe;
123 enum ttusb_dec_interface interface;
Ingo Molnar3593cab2006-02-07 06:49:14 -0200124 struct mutex usb_mutex;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125
126 void *irq_buffer;
127 struct urb *irq_urb;
128 dma_addr_t irq_dma_handle;
129 void *iso_buffer;
130 dma_addr_t iso_dma_handle;
131 struct urb *iso_urb[ISO_BUF_COUNT];
132 int iso_stream_count;
Ingo Molnar3593cab2006-02-07 06:49:14 -0200133 struct mutex iso_mutex;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700134
135 u8 packet[MAX_PVA_LENGTH + 4];
136 enum ttusb_dec_packet_type packet_type;
137 int packet_state;
138 int packet_length;
139 int packet_payload_length;
140 u16 next_packet_id;
141
142 int pva_stream_count;
143 int filter_stream_count;
144
145 struct dvb_filter_pes2ts a_pes2ts;
146 struct dvb_filter_pes2ts v_pes2ts;
147
148 u8 v_pes[16 + MAX_PVA_LENGTH];
149 int v_pes_length;
150 int v_pes_postbytes;
151
152 struct list_head urb_frame_list;
153 struct tasklet_struct urb_tasklet;
154 spinlock_t urb_frame_list_lock;
155
156 struct dvb_demux_filter *audio_filter;
157 struct dvb_demux_filter *video_filter;
158 struct list_head filter_info_list;
159 spinlock_t filter_info_list_lock;
160
Dmitry Torokhovb7df3912005-09-15 02:01:53 -0500161 struct input_dev *rc_input_dev;
162 char rc_phys[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700163
164 int active; /* Loaded successfully */
165};
166
167struct urb_frame {
168 u8 data[ISO_FRAME_SIZE];
169 int length;
170 struct list_head urb_frame_list;
171};
172
173struct filter_info {
174 u8 stream_id;
175 struct dvb_demux_filter *filter;
176 struct list_head filter_info_list;
177};
178
179static u16 rc_keys[] = {
180 KEY_POWER,
181 KEY_MUTE,
182 KEY_1,
183 KEY_2,
184 KEY_3,
185 KEY_4,
186 KEY_5,
187 KEY_6,
188 KEY_7,
189 KEY_8,
190 KEY_9,
191 KEY_0,
192 KEY_CHANNELUP,
193 KEY_VOLUMEDOWN,
194 KEY_OK,
195 KEY_VOLUMEUP,
196 KEY_CHANNELDOWN,
197 KEY_PREVIOUS,
198 KEY_ESC,
199 KEY_RED,
200 KEY_GREEN,
201 KEY_YELLOW,
202 KEY_BLUE,
203 KEY_OPTION,
204 KEY_M,
205 KEY_RADIO
206};
207
Mauro Carvalho Chehabb676e732016-10-13 07:41:38 -0300208static void dvb_filter_pes2ts_init(struct dvb_filter_pes2ts *p2ts,
209 unsigned short pid,
210 dvb_filter_pes2ts_cb_t *cb, void *priv)
211{
212 unsigned char *buf=p2ts->buf;
213
214 buf[0]=0x47;
215 buf[1]=(pid>>8);
216 buf[2]=pid&0xff;
217 p2ts->cc=0;
218 p2ts->cb=cb;
219 p2ts->priv=priv;
220}
221
222static int dvb_filter_pes2ts(struct dvb_filter_pes2ts *p2ts,
223 unsigned char *pes, int len, int payload_start)
224{
225 unsigned char *buf=p2ts->buf;
226 int ret=0, rest;
227
228 //len=6+((pes[4]<<8)|pes[5]);
229
230 if (payload_start)
231 buf[1]|=0x40;
232 else
233 buf[1]&=~0x40;
234 while (len>=184) {
235 buf[3]=0x10|((p2ts->cc++)&0x0f);
236 memcpy(buf+4, pes, 184);
237 if ((ret=p2ts->cb(p2ts->priv, buf)))
238 return ret;
239 len-=184; pes+=184;
240 buf[1]&=~0x40;
241 }
242 if (!len)
243 return 0;
244 buf[3]=0x30|((p2ts->cc++)&0x0f);
245 rest=183-len;
246 if (rest) {
247 buf[5]=0x00;
248 if (rest-1)
249 memset(buf+6, 0xff, rest-1);
250 }
251 buf[4]=rest;
252 memcpy(buf+5+rest, pes, len);
253 return p2ts->cb(p2ts->priv, buf);
254}
255
Linus Torvalds1da177e2005-04-16 15:20:36 -0700256static void ttusb_dec_set_model(struct ttusb_dec *dec,
257 enum ttusb_dec_model model);
258
David Howells7d12e782006-10-05 14:55:46 +0100259static void ttusb_dec_handle_irq( struct urb *urb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700260{
Mauro Carvalho Chehab3cc26912016-09-22 14:09:18 -0300261 struct ttusb_dec *dec = urb->context;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700262 char *buffer = dec->irq_buffer;
263 int retval;
264
265 switch(urb->status) {
266 case 0: /*success*/
267 break;
268 case -ECONNRESET:
269 case -ENOENT:
270 case -ESHUTDOWN:
Pete Zaitcev38e2bfc2006-09-18 22:49:02 -0700271 case -ETIME:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700272 /* this urb is dead, cleanup */
273 dprintk("%s:urb shutting down with status: %d\n",
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300274 __func__, urb->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700275 return;
276 default:
277 dprintk("%s:nonzero status received: %d\n",
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300278 __func__,urb->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279 goto exit;
280 }
281
Mauro Carvalho Chehab3cc26912016-09-22 14:09:18 -0300282 if ((buffer[0] == 0x1) && (buffer[2] == 0x15)) {
283 /*
284 * IR - Event
285 *
286 * this is an fact a bit too simple implementation;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700287 * the box also reports a keyrepeat signal
288 * (with buffer[3] == 0x40) in an intervall of ~100ms.
289 * But to handle this correctly we had to imlemenent some
290 * kind of timer which signals a 'key up' event if no
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300291 * keyrepeat signal is received for lets say 200ms.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700292 * this should/could be added later ...
Mauro Carvalho Chehab3cc26912016-09-22 14:09:18 -0300293 * for now lets report each signal as a key down and up
294 */
295 if (buffer[4] - 1 < ARRAY_SIZE(rc_keys)) {
296 dprintk("%s:rc signal:%d\n", __func__, buffer[4]);
297 input_report_key(dec->rc_input_dev, rc_keys[buffer[4] - 1], 1);
298 input_sync(dec->rc_input_dev);
299 input_report_key(dec->rc_input_dev, rc_keys[buffer[4] - 1], 0);
300 input_sync(dec->rc_input_dev);
301 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700302 }
303
Mauro Carvalho Chehab3cc26912016-09-22 14:09:18 -0300304exit:
305 retval = usb_submit_urb(urb, GFP_ATOMIC);
306 if (retval)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700307 printk("%s - usb_commit_urb failed with result: %d\n",
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300308 __func__, retval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700309}
310
311static u16 crc16(u16 crc, const u8 *buf, size_t len)
312{
313 u16 tmp;
314
315 while (len--) {
316 crc ^= *buf++;
317 crc ^= (u8)crc >> 4;
318 tmp = (u8)crc;
319 crc ^= (tmp ^ (tmp << 1)) << 4;
320 }
321 return crc;
322}
323
324static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command,
325 int param_length, const u8 params[],
326 int *result_length, u8 cmd_result[])
327{
Mauro Carvalho Chehab61fc8742016-10-14 07:44:05 -0300328 int result, actual_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700329 u8 *b;
330
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300331 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700332
333 b = kmalloc(COMMAND_PACKET_SIZE + 4, GFP_KERNEL);
334 if (!b)
335 return -ENOMEM;
336
Ingo Molnar3593cab2006-02-07 06:49:14 -0200337 if ((result = mutex_lock_interruptible(&dec->usb_mutex))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700338 kfree(b);
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300339 printk("%s: Failed to lock usb mutex.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700340 return result;
341 }
342
343 b[0] = 0xaa;
344 b[1] = ++dec->trans_count;
345 b[2] = command;
346 b[3] = param_length;
347
348 if (params)
349 memcpy(&b[4], params, param_length);
350
351 if (debug) {
Mauro Carvalho Chehab61fc8742016-10-14 07:44:05 -0300352 printk(KERN_DEBUG "%s: command: %*ph\n",
353 __func__, param_length, b);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700354 }
355
356 result = usb_bulk_msg(dec->udev, dec->command_pipe, b,
357 COMMAND_PACKET_SIZE + 4, &actual_len, 1000);
358
359 if (result) {
360 printk("%s: command 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 }
366
367 result = usb_bulk_msg(dec->udev, dec->result_pipe, b,
368 COMMAND_PACKET_SIZE + 4, &actual_len, 1000);
369
370 if (result) {
371 printk("%s: result bulk message failed: error %d\n",
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300372 __func__, result);
Ingo Molnar3593cab2006-02-07 06:49:14 -0200373 mutex_unlock(&dec->usb_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700374 kfree(b);
375 return result;
376 } else {
377 if (debug) {
Mauro Carvalho Chehab61fc8742016-10-14 07:44:05 -0300378 printk(KERN_DEBUG "%s: result: %*ph\n",
379 __func__, actual_len, b);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700380 }
381
382 if (result_length)
383 *result_length = b[3];
384 if (cmd_result && b[3] > 0)
385 memcpy(cmd_result, &b[4], b[3]);
386
Ingo Molnar3593cab2006-02-07 06:49:14 -0200387 mutex_unlock(&dec->usb_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700388
389 kfree(b);
390 return 0;
391 }
392}
393
394static int ttusb_dec_get_stb_state (struct ttusb_dec *dec, unsigned int *mode,
395 unsigned int *model, unsigned int *version)
396{
397 u8 c[COMMAND_PACKET_SIZE];
398 int c_length;
399 int result;
Al Virod4f979a2008-05-21 00:31:31 -0300400 __be32 tmp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700401
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300402 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700403
404 result = ttusb_dec_send_command(dec, 0x08, 0, NULL, &c_length, c);
405 if (result)
406 return result;
407
408 if (c_length >= 0x0c) {
409 if (mode != NULL) {
410 memcpy(&tmp, c, 4);
411 *mode = ntohl(tmp);
412 }
413 if (model != NULL) {
414 memcpy(&tmp, &c[4], 4);
415 *model = ntohl(tmp);
416 }
417 if (version != NULL) {
418 memcpy(&tmp, &c[8], 4);
419 *version = ntohl(tmp);
420 }
421 return 0;
422 } else {
Alexey Khoroshilovcf732b52013-10-02 13:00:26 -0300423 return -ENOENT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700424 }
425}
426
427static int ttusb_dec_audio_pes2ts_cb(void *priv, unsigned char *data)
428{
Alex Woodsf961e712006-01-09 15:25:24 -0200429 struct ttusb_dec *dec = priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700430
431 dec->audio_filter->feed->cb.ts(data, 188, NULL, 0,
Mauro Carvalho Chehab2f684b22015-10-06 19:53:02 -0300432 &dec->audio_filter->feed->feed.ts);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700433
434 return 0;
435}
436
437static int ttusb_dec_video_pes2ts_cb(void *priv, unsigned char *data)
438{
Alex Woodsf961e712006-01-09 15:25:24 -0200439 struct ttusb_dec *dec = priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700440
441 dec->video_filter->feed->cb.ts(data, 188, NULL, 0,
Mauro Carvalho Chehab2f684b22015-10-06 19:53:02 -0300442 &dec->video_filter->feed->feed.ts);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700443
444 return 0;
445}
446
447static void ttusb_dec_set_pids(struct ttusb_dec *dec)
448{
449 u8 b[] = { 0x00, 0x00, 0x00, 0x00,
450 0x00, 0x00, 0xff, 0xff,
451 0xff, 0xff, 0xff, 0xff };
452
Al Virod4f979a2008-05-21 00:31:31 -0300453 __be16 pcr = htons(dec->pid[DMX_PES_PCR]);
454 __be16 audio = htons(dec->pid[DMX_PES_AUDIO]);
455 __be16 video = htons(dec->pid[DMX_PES_VIDEO]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700456
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300457 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700458
459 memcpy(&b[0], &pcr, 2);
460 memcpy(&b[2], &audio, 2);
461 memcpy(&b[4], &video, 2);
462
463 ttusb_dec_send_command(dec, 0x50, sizeof(b), b, NULL, NULL);
464
465 dvb_filter_pes2ts_init(&dec->a_pes2ts, dec->pid[DMX_PES_AUDIO],
466 ttusb_dec_audio_pes2ts_cb, dec);
467 dvb_filter_pes2ts_init(&dec->v_pes2ts, dec->pid[DMX_PES_VIDEO],
468 ttusb_dec_video_pes2ts_cb, dec);
469 dec->v_pes_length = 0;
470 dec->v_pes_postbytes = 0;
471}
472
473static void ttusb_dec_process_pva(struct ttusb_dec *dec, u8 *pva, int length)
474{
475 if (length < 8) {
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300476 printk("%s: packet too short - discarding\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700477 return;
478 }
479
480 if (length > 8 + MAX_PVA_LENGTH) {
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300481 printk("%s: packet too long - discarding\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700482 return;
483 }
484
485 switch (pva[2]) {
486
487 case 0x01: { /* VideoStream */
488 int prebytes = pva[5] & 0x03;
489 int postbytes = (pva[5] & 0x0c) >> 2;
Al Virod4f979a2008-05-21 00:31:31 -0300490 __be16 v_pes_payload_length;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700491
492 if (output_pva) {
493 dec->video_filter->feed->cb.ts(pva, length, NULL, 0,
Mauro Carvalho Chehab2f684b22015-10-06 19:53:02 -0300494 &dec->video_filter->feed->feed.ts);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700495 return;
496 }
497
498 if (dec->v_pes_postbytes > 0 &&
499 dec->v_pes_postbytes == prebytes) {
500 memcpy(&dec->v_pes[dec->v_pes_length],
501 &pva[12], prebytes);
502
503 dvb_filter_pes2ts(&dec->v_pes2ts, dec->v_pes,
504 dec->v_pes_length + prebytes, 1);
505 }
506
507 if (pva[5] & 0x10) {
508 dec->v_pes[7] = 0x80;
509 dec->v_pes[8] = 0x05;
510
511 dec->v_pes[9] = 0x21 | ((pva[8] & 0xc0) >> 5);
512 dec->v_pes[10] = ((pva[8] & 0x3f) << 2) |
513 ((pva[9] & 0xc0) >> 6);
514 dec->v_pes[11] = 0x01 |
515 ((pva[9] & 0x3f) << 2) |
516 ((pva[10] & 0x80) >> 6);
517 dec->v_pes[12] = ((pva[10] & 0x7f) << 1) |
518 ((pva[11] & 0xc0) >> 7);
519 dec->v_pes[13] = 0x01 | ((pva[11] & 0x7f) << 1);
520
521 memcpy(&dec->v_pes[14], &pva[12 + prebytes],
522 length - 12 - prebytes);
523 dec->v_pes_length = 14 + length - 12 - prebytes;
524 } else {
525 dec->v_pes[7] = 0x00;
526 dec->v_pes[8] = 0x00;
527
528 memcpy(&dec->v_pes[9], &pva[8], length - 8);
529 dec->v_pes_length = 9 + length - 8;
530 }
531
532 dec->v_pes_postbytes = postbytes;
533
534 if (dec->v_pes[9 + dec->v_pes[8]] == 0x00 &&
535 dec->v_pes[10 + dec->v_pes[8]] == 0x00 &&
536 dec->v_pes[11 + dec->v_pes[8]] == 0x01)
537 dec->v_pes[6] = 0x84;
538 else
539 dec->v_pes[6] = 0x80;
540
541 v_pes_payload_length = htons(dec->v_pes_length - 6 +
542 postbytes);
543 memcpy(&dec->v_pes[4], &v_pes_payload_length, 2);
544
545 if (postbytes == 0)
546 dvb_filter_pes2ts(&dec->v_pes2ts, dec->v_pes,
547 dec->v_pes_length, 1);
548
549 break;
550 }
551
552 case 0x02: /* MainAudioStream */
553 if (output_pva) {
554 dec->audio_filter->feed->cb.ts(pva, length, NULL, 0,
Mauro Carvalho Chehab2f684b22015-10-06 19:53:02 -0300555 &dec->audio_filter->feed->feed.ts);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700556 return;
557 }
558
559 dvb_filter_pes2ts(&dec->a_pes2ts, &pva[8], length - 8,
560 pva[5] & 0x10);
561 break;
562
563 default:
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300564 printk("%s: unknown PVA type: %02x.\n", __func__,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700565 pva[2]);
566 break;
567 }
568}
569
570static void ttusb_dec_process_filter(struct ttusb_dec *dec, u8 *packet,
571 int length)
572{
573 struct list_head *item;
574 struct filter_info *finfo;
575 struct dvb_demux_filter *filter = NULL;
576 unsigned long flags;
577 u8 sid;
578
579 sid = packet[1];
580 spin_lock_irqsave(&dec->filter_info_list_lock, flags);
581 for (item = dec->filter_info_list.next; item != &dec->filter_info_list;
582 item = item->next) {
583 finfo = list_entry(item, struct filter_info, filter_info_list);
584 if (finfo->stream_id == sid) {
585 filter = finfo->filter;
586 break;
587 }
588 }
589 spin_unlock_irqrestore(&dec->filter_info_list_lock, flags);
590
591 if (filter)
592 filter->feed->cb.sec(&packet[2], length - 2, NULL, 0,
Mauro Carvalho Chehab2f684b22015-10-06 19:53:02 -0300593 &filter->filter);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700594}
595
596static void ttusb_dec_process_packet(struct ttusb_dec *dec)
597{
598 int i;
599 u16 csum = 0;
600 u16 packet_id;
601
602 if (dec->packet_length % 2) {
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300603 printk("%s: odd sized packet - discarding\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700604 return;
605 }
606
607 for (i = 0; i < dec->packet_length; i += 2)
608 csum ^= ((dec->packet[i] << 8) + dec->packet[i + 1]);
609
610 if (csum) {
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300611 printk("%s: checksum failed - discarding\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700612 return;
613 }
614
615 packet_id = dec->packet[dec->packet_length - 4] << 8;
616 packet_id += dec->packet[dec->packet_length - 3];
617
618 if ((packet_id != dec->next_packet_id) && dec->next_packet_id) {
619 printk("%s: warning: lost packets between %u and %u\n",
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300620 __func__, dec->next_packet_id - 1, packet_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700621 }
622
623 if (packet_id == 0xffff)
624 dec->next_packet_id = 0x8000;
625 else
626 dec->next_packet_id = packet_id + 1;
627
628 switch (dec->packet_type) {
629 case TTUSB_DEC_PACKET_PVA:
630 if (dec->pva_stream_count)
631 ttusb_dec_process_pva(dec, dec->packet,
632 dec->packet_payload_length);
633 break;
634
635 case TTUSB_DEC_PACKET_SECTION:
636 if (dec->filter_stream_count)
637 ttusb_dec_process_filter(dec, dec->packet,
638 dec->packet_payload_length);
639 break;
640
641 case TTUSB_DEC_PACKET_EMPTY:
642 break;
643 }
644}
645
646static void swap_bytes(u8 *b, int length)
647{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700648 length -= length % 2;
Fabian Frederick41cc14b2015-06-10 13:32:44 -0300649 for (; length; b += 2, length -= 2)
650 swap(*b, *(b + 1));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700651}
652
653static void ttusb_dec_process_urb_frame(struct ttusb_dec *dec, u8 *b,
654 int length)
655{
656 swap_bytes(b, length);
657
658 while (length) {
659 switch (dec->packet_state) {
660
661 case 0:
662 case 1:
663 case 2:
664 if (*b++ == 0xaa)
665 dec->packet_state++;
666 else
667 dec->packet_state = 0;
668
669 length--;
670 break;
671
672 case 3:
673 if (*b == 0x00) {
674 dec->packet_state++;
675 dec->packet_length = 0;
676 } else if (*b != 0xaa) {
677 dec->packet_state = 0;
678 }
679
680 b++;
681 length--;
682 break;
683
684 case 4:
685 dec->packet[dec->packet_length++] = *b++;
686
687 if (dec->packet_length == 2) {
688 if (dec->packet[0] == 'A' &&
689 dec->packet[1] == 'V') {
690 dec->packet_type =
691 TTUSB_DEC_PACKET_PVA;
692 dec->packet_state++;
693 } else if (dec->packet[0] == 'S') {
694 dec->packet_type =
695 TTUSB_DEC_PACKET_SECTION;
696 dec->packet_state++;
697 } else if (dec->packet[0] == 0x00) {
698 dec->packet_type =
699 TTUSB_DEC_PACKET_EMPTY;
700 dec->packet_payload_length = 2;
701 dec->packet_state = 7;
702 } else {
Mauro Carvalho Chehabbf769a42016-10-18 17:44:20 -0200703 printk("%s: unknown packet type: %02x%02x\n",
704 __func__,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700705 dec->packet[0], dec->packet[1]);
706 dec->packet_state = 0;
707 }
708 }
709
710 length--;
711 break;
712
713 case 5:
714 dec->packet[dec->packet_length++] = *b++;
715
716 if (dec->packet_type == TTUSB_DEC_PACKET_PVA &&
717 dec->packet_length == 8) {
718 dec->packet_state++;
719 dec->packet_payload_length = 8 +
720 (dec->packet[6] << 8) +
721 dec->packet[7];
722 } else if (dec->packet_type ==
723 TTUSB_DEC_PACKET_SECTION &&
724 dec->packet_length == 5) {
725 dec->packet_state++;
726 dec->packet_payload_length = 5 +
727 ((dec->packet[3] & 0x0f) << 8) +
728 dec->packet[4];
729 }
730
731 length--;
732 break;
733
734 case 6: {
735 int remainder = dec->packet_payload_length -
736 dec->packet_length;
737
738 if (length >= remainder) {
739 memcpy(dec->packet + dec->packet_length,
740 b, remainder);
741 dec->packet_length += remainder;
742 b += remainder;
743 length -= remainder;
744 dec->packet_state++;
745 } else {
746 memcpy(&dec->packet[dec->packet_length],
747 b, length);
748 dec->packet_length += length;
749 length = 0;
750 }
751
752 break;
753 }
754
755 case 7: {
756 int tail = 4;
757
758 dec->packet[dec->packet_length++] = *b++;
759
760 if (dec->packet_type == TTUSB_DEC_PACKET_SECTION &&
761 dec->packet_payload_length % 2)
762 tail++;
763
764 if (dec->packet_length ==
765 dec->packet_payload_length + tail) {
766 ttusb_dec_process_packet(dec);
767 dec->packet_state = 0;
768 }
769
770 length--;
771 break;
772 }
773
774 default:
775 printk("%s: illegal packet state encountered.\n",
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300776 __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700777 dec->packet_state = 0;
778 }
779 }
780}
781
782static void ttusb_dec_process_urb_frame_list(unsigned long data)
783{
784 struct ttusb_dec *dec = (struct ttusb_dec *)data;
785 struct list_head *item;
786 struct urb_frame *frame;
787 unsigned long flags;
788
789 while (1) {
790 spin_lock_irqsave(&dec->urb_frame_list_lock, flags);
791 if ((item = dec->urb_frame_list.next) != &dec->urb_frame_list) {
792 frame = list_entry(item, struct urb_frame,
793 urb_frame_list);
794 list_del(&frame->urb_frame_list);
795 } else {
796 spin_unlock_irqrestore(&dec->urb_frame_list_lock,
797 flags);
798 return;
799 }
800 spin_unlock_irqrestore(&dec->urb_frame_list_lock, flags);
801
802 ttusb_dec_process_urb_frame(dec, frame->data, frame->length);
803 kfree(frame);
804 }
805}
806
David Howells7d12e782006-10-05 14:55:46 +0100807static void ttusb_dec_process_urb(struct urb *urb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700808{
809 struct ttusb_dec *dec = urb->context;
810
811 if (!urb->status) {
812 int i;
813
814 for (i = 0; i < FRAMES_PER_ISO_BUF; i++) {
815 struct usb_iso_packet_descriptor *d;
816 u8 *b;
817 int length;
818 struct urb_frame *frame;
819
820 d = &urb->iso_frame_desc[i];
821 b = urb->transfer_buffer + d->offset;
822 length = d->actual_length;
823
824 if ((frame = kmalloc(sizeof(struct urb_frame),
825 GFP_ATOMIC))) {
826 unsigned long flags;
827
828 memcpy(frame->data, b, length);
829 frame->length = length;
830
831 spin_lock_irqsave(&dec->urb_frame_list_lock,
832 flags);
833 list_add_tail(&frame->urb_frame_list,
834 &dec->urb_frame_list);
835 spin_unlock_irqrestore(&dec->urb_frame_list_lock,
836 flags);
837
838 tasklet_schedule(&dec->urb_tasklet);
839 }
840 }
841 } else {
842 /* -ENOENT is expected when unlinking urbs */
843 if (urb->status != -ENOENT)
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300844 dprintk("%s: urb error: %d\n", __func__,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700845 urb->status);
846 }
847
848 if (dec->iso_stream_count)
849 usb_submit_urb(urb, GFP_ATOMIC);
850}
851
852static void ttusb_dec_setup_urbs(struct ttusb_dec *dec)
853{
854 int i, j, buffer_offset = 0;
855
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300856 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700857
858 for (i = 0; i < ISO_BUF_COUNT; i++) {
859 int frame_offset = 0;
860 struct urb *urb = dec->iso_urb[i];
861
862 urb->dev = dec->udev;
863 urb->context = dec;
864 urb->complete = ttusb_dec_process_urb;
865 urb->pipe = dec->in_pipe;
866 urb->transfer_flags = URB_ISO_ASAP;
867 urb->interval = 1;
868 urb->number_of_packets = FRAMES_PER_ISO_BUF;
869 urb->transfer_buffer_length = ISO_FRAME_SIZE *
870 FRAMES_PER_ISO_BUF;
871 urb->transfer_buffer = dec->iso_buffer + buffer_offset;
872 buffer_offset += ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF;
873
874 for (j = 0; j < FRAMES_PER_ISO_BUF; j++) {
875 urb->iso_frame_desc[j].offset = frame_offset;
876 urb->iso_frame_desc[j].length = ISO_FRAME_SIZE;
877 frame_offset += ISO_FRAME_SIZE;
878 }
879 }
880}
881
882static void ttusb_dec_stop_iso_xfer(struct ttusb_dec *dec)
883{
884 int i;
885
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300886 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700887
Ingo Molnar3593cab2006-02-07 06:49:14 -0200888 if (mutex_lock_interruptible(&dec->iso_mutex))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700889 return;
890
891 dec->iso_stream_count--;
892
893 if (!dec->iso_stream_count) {
894 for (i = 0; i < ISO_BUF_COUNT; i++)
895 usb_kill_urb(dec->iso_urb[i]);
896 }
897
Ingo Molnar3593cab2006-02-07 06:49:14 -0200898 mutex_unlock(&dec->iso_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700899}
900
901/* Setting the interface of the DEC tends to take down the USB communications
902 * for a short period, so it's important not to call this function just before
903 * trying to talk to it.
904 */
905static int ttusb_dec_set_interface(struct ttusb_dec *dec,
906 enum ttusb_dec_interface interface)
907{
908 int result = 0;
909 u8 b[] = { 0x05 };
910
911 if (interface != dec->interface) {
912 switch (interface) {
913 case TTUSB_DEC_INTERFACE_INITIAL:
914 result = usb_set_interface(dec->udev, 0, 0);
915 break;
916 case TTUSB_DEC_INTERFACE_IN:
917 result = ttusb_dec_send_command(dec, 0x80, sizeof(b),
918 b, NULL, NULL);
919 if (result)
920 return result;
921 result = usb_set_interface(dec->udev, 0, 8);
922 break;
923 case TTUSB_DEC_INTERFACE_OUT:
924 result = usb_set_interface(dec->udev, 0, 1);
925 break;
926 }
927
928 if (result)
929 return result;
930
931 dec->interface = interface;
932 }
933
934 return 0;
935}
936
937static int ttusb_dec_start_iso_xfer(struct ttusb_dec *dec)
938{
939 int i, result;
940
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300941 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700942
Ingo Molnar3593cab2006-02-07 06:49:14 -0200943 if (mutex_lock_interruptible(&dec->iso_mutex))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700944 return -EAGAIN;
945
946 if (!dec->iso_stream_count) {
947 ttusb_dec_setup_urbs(dec);
948
949 dec->packet_state = 0;
950 dec->v_pes_postbytes = 0;
951 dec->next_packet_id = 0;
952
953 for (i = 0; i < ISO_BUF_COUNT; i++) {
954 if ((result = usb_submit_urb(dec->iso_urb[i],
955 GFP_ATOMIC))) {
Mauro Carvalho Chehabbf769a42016-10-18 17:44:20 -0200956 printk("%s: failed urb submission %d: error %d\n",
957 __func__, i, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700958
959 while (i) {
960 usb_kill_urb(dec->iso_urb[i - 1]);
961 i--;
962 }
963
Ingo Molnar3593cab2006-02-07 06:49:14 -0200964 mutex_unlock(&dec->iso_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700965 return result;
966 }
967 }
968 }
969
970 dec->iso_stream_count++;
971
Ingo Molnar3593cab2006-02-07 06:49:14 -0200972 mutex_unlock(&dec->iso_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700973
974 return 0;
975}
976
977static int ttusb_dec_start_ts_feed(struct dvb_demux_feed *dvbdmxfeed)
978{
979 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
980 struct ttusb_dec *dec = dvbdmx->priv;
981 u8 b0[] = { 0x05 };
982 int result = 0;
983
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300984 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700985
986 dprintk(" ts_type:");
987
988 if (dvbdmxfeed->ts_type & TS_DECODER)
989 dprintk(" TS_DECODER");
990
991 if (dvbdmxfeed->ts_type & TS_PACKET)
992 dprintk(" TS_PACKET");
993
994 if (dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY)
995 dprintk(" TS_PAYLOAD_ONLY");
996
997 dprintk("\n");
998
999 switch (dvbdmxfeed->pes_type) {
1000
Mauro Carvalho Chehabfde04ab2013-04-04 13:25:30 -03001001 case DMX_PES_VIDEO:
1002 dprintk(" pes_type: DMX_PES_VIDEO\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001003 dec->pid[DMX_PES_PCR] = dvbdmxfeed->pid;
1004 dec->pid[DMX_PES_VIDEO] = dvbdmxfeed->pid;
1005 dec->video_filter = dvbdmxfeed->filter;
1006 ttusb_dec_set_pids(dec);
1007 break;
1008
Mauro Carvalho Chehabfde04ab2013-04-04 13:25:30 -03001009 case DMX_PES_AUDIO:
1010 dprintk(" pes_type: DMX_PES_AUDIO\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001011 dec->pid[DMX_PES_AUDIO] = dvbdmxfeed->pid;
1012 dec->audio_filter = dvbdmxfeed->filter;
1013 ttusb_dec_set_pids(dec);
1014 break;
1015
Mauro Carvalho Chehabfde04ab2013-04-04 13:25:30 -03001016 case DMX_PES_TELETEXT:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001017 dec->pid[DMX_PES_TELETEXT] = dvbdmxfeed->pid;
Mauro Carvalho Chehabfde04ab2013-04-04 13:25:30 -03001018 dprintk(" pes_type: DMX_PES_TELETEXT(not supported)\n");
Alex Woodsf961e712006-01-09 15:25:24 -02001019 return -ENOSYS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001020
Mauro Carvalho Chehabfde04ab2013-04-04 13:25:30 -03001021 case DMX_PES_PCR:
1022 dprintk(" pes_type: DMX_PES_PCR\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001023 dec->pid[DMX_PES_PCR] = dvbdmxfeed->pid;
1024 ttusb_dec_set_pids(dec);
1025 break;
1026
Mauro Carvalho Chehabfde04ab2013-04-04 13:25:30 -03001027 case DMX_PES_OTHER:
1028 dprintk(" pes_type: DMX_PES_OTHER(not supported)\n");
Alex Woodsf961e712006-01-09 15:25:24 -02001029 return -ENOSYS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001030
1031 default:
1032 dprintk(" pes_type: unknown (%d)\n", dvbdmxfeed->pes_type);
1033 return -EINVAL;
1034
1035 }
1036
1037 result = ttusb_dec_send_command(dec, 0x80, sizeof(b0), b0, NULL, NULL);
1038 if (result)
1039 return result;
1040
1041 dec->pva_stream_count++;
1042 return ttusb_dec_start_iso_xfer(dec);
1043}
1044
1045static int ttusb_dec_start_sec_feed(struct dvb_demux_feed *dvbdmxfeed)
1046{
1047 struct ttusb_dec *dec = dvbdmxfeed->demux->priv;
1048 u8 b0[] = { 0x00, 0x00, 0x00, 0x01,
1049 0x00, 0x00, 0x00, 0x00,
1050 0x00, 0x00, 0x00, 0x00,
1051 0x00, 0x00, 0x00, 0x00,
1052 0x00, 0xff, 0x00, 0x00,
1053 0x00, 0x00, 0x00, 0x00,
1054 0x00, 0x00, 0x00, 0x00,
1055 0x00 };
Al Virod4f979a2008-05-21 00:31:31 -03001056 __be16 pid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001057 u8 c[COMMAND_PACKET_SIZE];
1058 int c_length;
1059 int result;
1060 struct filter_info *finfo;
1061 unsigned long flags;
1062 u8 x = 1;
1063
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001064 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001065
1066 pid = htons(dvbdmxfeed->pid);
1067 memcpy(&b0[0], &pid, 2);
1068 memcpy(&b0[4], &x, 1);
1069 memcpy(&b0[5], &dvbdmxfeed->filter->filter.filter_value[0], 1);
1070
1071 result = ttusb_dec_send_command(dec, 0x60, sizeof(b0), b0,
1072 &c_length, c);
1073
1074 if (!result) {
1075 if (c_length == 2) {
1076 if (!(finfo = kmalloc(sizeof(struct filter_info),
1077 GFP_ATOMIC)))
1078 return -ENOMEM;
1079
1080 finfo->stream_id = c[1];
1081 finfo->filter = dvbdmxfeed->filter;
1082
1083 spin_lock_irqsave(&dec->filter_info_list_lock, flags);
1084 list_add_tail(&finfo->filter_info_list,
1085 &dec->filter_info_list);
1086 spin_unlock_irqrestore(&dec->filter_info_list_lock,
1087 flags);
1088
1089 dvbdmxfeed->priv = finfo;
1090
1091 dec->filter_stream_count++;
1092 return ttusb_dec_start_iso_xfer(dec);
1093 }
1094
1095 return -EAGAIN;
1096 } else
1097 return result;
1098}
1099
1100static int ttusb_dec_start_feed(struct dvb_demux_feed *dvbdmxfeed)
1101{
1102 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
1103
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001104 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001105
1106 if (!dvbdmx->dmx.frontend)
1107 return -EINVAL;
1108
1109 dprintk(" pid: 0x%04X\n", dvbdmxfeed->pid);
1110
1111 switch (dvbdmxfeed->type) {
1112
1113 case DMX_TYPE_TS:
1114 return ttusb_dec_start_ts_feed(dvbdmxfeed);
1115 break;
1116
1117 case DMX_TYPE_SEC:
1118 return ttusb_dec_start_sec_feed(dvbdmxfeed);
1119 break;
1120
1121 default:
1122 dprintk(" type: unknown (%d)\n", dvbdmxfeed->type);
1123 return -EINVAL;
1124
1125 }
1126}
1127
1128static int ttusb_dec_stop_ts_feed(struct dvb_demux_feed *dvbdmxfeed)
1129{
1130 struct ttusb_dec *dec = dvbdmxfeed->demux->priv;
1131 u8 b0[] = { 0x00 };
1132
1133 ttusb_dec_send_command(dec, 0x81, sizeof(b0), b0, NULL, NULL);
1134
1135 dec->pva_stream_count--;
1136
1137 ttusb_dec_stop_iso_xfer(dec);
1138
1139 return 0;
1140}
1141
1142static int ttusb_dec_stop_sec_feed(struct dvb_demux_feed *dvbdmxfeed)
1143{
1144 struct ttusb_dec *dec = dvbdmxfeed->demux->priv;
1145 u8 b0[] = { 0x00, 0x00 };
1146 struct filter_info *finfo = (struct filter_info *)dvbdmxfeed->priv;
1147 unsigned long flags;
1148
1149 b0[1] = finfo->stream_id;
1150 spin_lock_irqsave(&dec->filter_info_list_lock, flags);
1151 list_del(&finfo->filter_info_list);
1152 spin_unlock_irqrestore(&dec->filter_info_list_lock, flags);
1153 kfree(finfo);
1154 ttusb_dec_send_command(dec, 0x62, sizeof(b0), b0, NULL, NULL);
1155
1156 dec->filter_stream_count--;
1157
1158 ttusb_dec_stop_iso_xfer(dec);
1159
1160 return 0;
1161}
1162
1163static int ttusb_dec_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
1164{
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001165 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001166
1167 switch (dvbdmxfeed->type) {
1168 case DMX_TYPE_TS:
1169 return ttusb_dec_stop_ts_feed(dvbdmxfeed);
1170 break;
1171
1172 case DMX_TYPE_SEC:
1173 return ttusb_dec_stop_sec_feed(dvbdmxfeed);
1174 break;
1175 }
1176
1177 return 0;
1178}
1179
1180static void ttusb_dec_free_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
1186 for (i = 0; i < ISO_BUF_COUNT; i++)
Mariusz Kozlowski5d02d022006-11-08 15:34:27 +01001187 usb_free_urb(dec->iso_urb[i]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001188
1189 pci_free_consistent(NULL,
1190 ISO_FRAME_SIZE * (FRAMES_PER_ISO_BUF *
1191 ISO_BUF_COUNT),
1192 dec->iso_buffer, dec->iso_dma_handle);
1193}
1194
1195static int ttusb_dec_alloc_iso_urbs(struct ttusb_dec *dec)
1196{
1197 int i;
1198
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001199 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001200
Joe Perches6850aea2014-08-08 14:24:21 -07001201 dec->iso_buffer = pci_zalloc_consistent(NULL,
1202 ISO_FRAME_SIZE * (FRAMES_PER_ISO_BUF * ISO_BUF_COUNT),
1203 &dec->iso_dma_handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001204
Douglas Schilling Landgrafd7c31a12008-11-11 23:27:59 -03001205 if (!dec->iso_buffer) {
1206 dprintk("%s: pci_alloc_consistent - not enough memory\n",
1207 __func__);
1208 return -ENOMEM;
1209 }
1210
Linus Torvalds1da177e2005-04-16 15:20:36 -07001211 for (i = 0; i < ISO_BUF_COUNT; i++) {
1212 struct urb *urb;
1213
1214 if (!(urb = usb_alloc_urb(FRAMES_PER_ISO_BUF, GFP_ATOMIC))) {
1215 ttusb_dec_free_iso_urbs(dec);
1216 return -ENOMEM;
1217 }
1218
1219 dec->iso_urb[i] = urb;
1220 }
1221
1222 ttusb_dec_setup_urbs(dec);
1223
1224 return 0;
1225}
1226
1227static void ttusb_dec_init_tasklet(struct ttusb_dec *dec)
1228{
1229 spin_lock_init(&dec->urb_frame_list_lock);
1230 INIT_LIST_HEAD(&dec->urb_frame_list);
1231 tasklet_init(&dec->urb_tasklet, ttusb_dec_process_urb_frame_list,
1232 (unsigned long)dec);
1233}
1234
Michael Krufky50c25ff2006-01-09 15:25:34 -02001235static int ttusb_init_rc( struct ttusb_dec *dec)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001236{
Dmitry Torokhovb7df3912005-09-15 02:01:53 -05001237 struct input_dev *input_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001238 u8 b[] = { 0x00, 0x01 };
1239 int i;
Dmitry Torokhovb07b4782006-11-20 10:23:04 -03001240 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001241
Dmitry Torokhovb7df3912005-09-15 02:01:53 -05001242 usb_make_path(dec->udev, dec->rc_phys, sizeof(dec->rc_phys));
Márton Némethb1858192009-11-21 13:46:12 -03001243 strlcat(dec->rc_phys, "/input0", sizeof(dec->rc_phys));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001244
Dmitry Torokhovb07b4782006-11-20 10:23:04 -03001245 input_dev = input_allocate_device();
Dmitry Torokhovb7df3912005-09-15 02:01:53 -05001246 if (!input_dev)
1247 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001248
Dmitry Torokhovb7df3912005-09-15 02:01:53 -05001249 input_dev->name = "ttusb_dec remote control";
1250 input_dev->phys = dec->rc_phys;
Jiri Slaby7b19ada2007-10-18 23:40:32 -07001251 input_dev->evbit[0] = BIT_MASK(EV_KEY);
Dmitry Torokhovb7df3912005-09-15 02:01:53 -05001252 input_dev->keycodesize = sizeof(u16);
1253 input_dev->keycodemax = 0x1a;
1254 input_dev->keycode = rc_keys;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001255
Dmitry Torokhovb7df3912005-09-15 02:01:53 -05001256 for (i = 0; i < ARRAY_SIZE(rc_keys); i++)
Michael Krufky50c25ff2006-01-09 15:25:34 -02001257 set_bit(rc_keys[i], input_dev->keybit);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001258
Dmitry Torokhovb07b4782006-11-20 10:23:04 -03001259 err = input_register_device(input_dev);
1260 if (err) {
1261 input_free_device(input_dev);
1262 return err;
1263 }
Dmitry Torokhovb7df3912005-09-15 02:01:53 -05001264
Dmitry Torokhovb07b4782006-11-20 10:23:04 -03001265 dec->rc_input_dev = input_dev;
Dmitry Torokhovb7df3912005-09-15 02:01:53 -05001266 if (usb_submit_urb(dec->irq_urb, GFP_KERNEL))
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001267 printk("%s: usb_submit_urb failed\n",__func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001268 /* enable irq pipe */
1269 ttusb_dec_send_command(dec,0xb0,sizeof(b),b,NULL,NULL);
Dmitry Torokhovb7df3912005-09-15 02:01:53 -05001270
1271 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001272}
1273
1274static void ttusb_dec_init_v_pes(struct ttusb_dec *dec)
1275{
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001276 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001277
1278 dec->v_pes[0] = 0x00;
1279 dec->v_pes[1] = 0x00;
1280 dec->v_pes[2] = 0x01;
1281 dec->v_pes[3] = 0xe0;
1282}
1283
1284static int ttusb_dec_init_usb(struct ttusb_dec *dec)
1285{
Alexey Khoroshilovcf732b52013-10-02 13:00:26 -03001286 int result;
1287
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001288 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001289
Ingo Molnar3593cab2006-02-07 06:49:14 -02001290 mutex_init(&dec->usb_mutex);
1291 mutex_init(&dec->iso_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001292
1293 dec->command_pipe = usb_sndbulkpipe(dec->udev, COMMAND_PIPE);
1294 dec->result_pipe = usb_rcvbulkpipe(dec->udev, RESULT_PIPE);
1295 dec->in_pipe = usb_rcvisocpipe(dec->udev, IN_PIPE);
1296 dec->out_pipe = usb_sndisocpipe(dec->udev, OUT_PIPE);
1297 dec->irq_pipe = usb_rcvintpipe(dec->udev, IRQ_PIPE);
1298
1299 if(enable_rc) {
1300 dec->irq_urb = usb_alloc_urb(0, GFP_KERNEL);
1301 if(!dec->irq_urb) {
1302 return -ENOMEM;
1303 }
Daniel Mack997ea582010-04-12 13:17:25 +02001304 dec->irq_buffer = usb_alloc_coherent(dec->udev,IRQ_PACKET_SIZE,
Alexey Khoroshilovcf732b52013-10-02 13:00:26 -03001305 GFP_KERNEL, &dec->irq_dma_handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001306 if(!dec->irq_buffer) {
Douglas Schilling Landgraf7935eea2008-11-11 23:47:57 -03001307 usb_free_urb(dec->irq_urb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001308 return -ENOMEM;
1309 }
1310 usb_fill_int_urb(dec->irq_urb, dec->udev,dec->irq_pipe,
1311 dec->irq_buffer, IRQ_PACKET_SIZE,
1312 ttusb_dec_handle_irq, dec, 1);
1313 dec->irq_urb->transfer_dma = dec->irq_dma_handle;
1314 dec->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
1315 }
1316
Alexey Khoroshilovcf732b52013-10-02 13:00:26 -03001317 result = ttusb_dec_alloc_iso_urbs(dec);
1318 if (result) {
1319 usb_free_urb(dec->irq_urb);
1320 usb_free_coherent(dec->udev, IRQ_PACKET_SIZE,
1321 dec->irq_buffer, dec->irq_dma_handle);
1322 }
1323 return result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001324}
1325
1326static int ttusb_dec_boot_dsp(struct ttusb_dec *dec)
1327{
1328 int i, j, actual_len, result, size, trans_count;
1329 u8 b0[] = { 0x00, 0x00, 0x00, 0x00,
1330 0x00, 0x00, 0x00, 0x00,
1331 0x61, 0x00 };
1332 u8 b1[] = { 0x61 };
1333 u8 *b;
1334 char idstring[21];
David Woodhouse99b6e4f2008-05-24 00:12:00 +01001335 const u8 *firmware = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001336 size_t firmware_size = 0;
1337 u16 firmware_csum = 0;
Al Virod4f979a2008-05-21 00:31:31 -03001338 __be16 firmware_csum_ns;
1339 __be32 firmware_size_nl;
1340 u32 crc32_csum, crc32_check;
1341 __be32 tmp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001342 const struct firmware *fw_entry = NULL;
1343
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001344 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001345
Alexey Khoroshilovcf732b52013-10-02 13:00:26 -03001346 result = request_firmware(&fw_entry, dec->firmware_name, &dec->udev->dev);
1347 if (result) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001348 printk(KERN_ERR "%s: Firmware (%s) unavailable.\n",
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001349 __func__, dec->firmware_name);
Alexey Khoroshilovcf732b52013-10-02 13:00:26 -03001350 return result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001351 }
1352
1353 firmware = fw_entry->data;
1354 firmware_size = fw_entry->size;
1355
1356 if (firmware_size < 60) {
1357 printk("%s: firmware size too small for DSP code (%zu < 60).\n",
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001358 __func__, firmware_size);
Anssi Hannula0c744b02005-07-07 17:57:42 -07001359 release_firmware(fw_entry);
Alexey Khoroshilovcf732b52013-10-02 13:00:26 -03001360 return -ENOENT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001361 }
1362
1363 /* a 32 bit checksum over the first 56 bytes of the DSP Code is stored
1364 at offset 56 of file, so use it to check if the firmware file is
1365 valid. */
1366 crc32_csum = crc32(~0L, firmware, 56) ^ ~0L;
1367 memcpy(&tmp, &firmware[56], 4);
Al Virod4f979a2008-05-21 00:31:31 -03001368 crc32_check = ntohl(tmp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001369 if (crc32_csum != crc32_check) {
Mauro Carvalho Chehabbf769a42016-10-18 17:44:20 -02001370 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 -03001371 __func__, crc32_csum, crc32_check);
Anssi Hannula0c744b02005-07-07 17:57:42 -07001372 release_firmware(fw_entry);
Alexey Khoroshilovcf732b52013-10-02 13:00:26 -03001373 return -ENOENT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001374 }
1375 memcpy(idstring, &firmware[36], 20);
1376 idstring[20] = '\0';
1377 printk(KERN_INFO "ttusb_dec: found DSP code \"%s\".\n", idstring);
1378
1379 firmware_size_nl = htonl(firmware_size);
1380 memcpy(b0, &firmware_size_nl, 4);
1381 firmware_csum = crc16(~0, firmware, firmware_size) ^ ~0;
1382 firmware_csum_ns = htons(firmware_csum);
1383 memcpy(&b0[6], &firmware_csum_ns, 2);
1384
1385 result = ttusb_dec_send_command(dec, 0x41, sizeof(b0), b0, NULL, NULL);
1386
Anssi Hannula0c744b02005-07-07 17:57:42 -07001387 if (result) {
1388 release_firmware(fw_entry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001389 return result;
Anssi Hannula0c744b02005-07-07 17:57:42 -07001390 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001391
1392 trans_count = 0;
1393 j = 0;
1394
1395 b = kmalloc(ARM_PACKET_SIZE, GFP_KERNEL);
Anssi Hannula0c744b02005-07-07 17:57:42 -07001396 if (b == NULL) {
1397 release_firmware(fw_entry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001398 return -ENOMEM;
Anssi Hannula0c744b02005-07-07 17:57:42 -07001399 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001400
1401 for (i = 0; i < firmware_size; i += COMMAND_PACKET_SIZE) {
1402 size = firmware_size - i;
1403 if (size > COMMAND_PACKET_SIZE)
1404 size = COMMAND_PACKET_SIZE;
1405
1406 b[j + 0] = 0xaa;
1407 b[j + 1] = trans_count++;
1408 b[j + 2] = 0xf0;
1409 b[j + 3] = size;
1410 memcpy(&b[j + 4], &firmware[i], size);
1411
1412 j += COMMAND_PACKET_SIZE + 4;
1413
1414 if (j >= ARM_PACKET_SIZE) {
1415 result = usb_bulk_msg(dec->udev, dec->command_pipe, b,
1416 ARM_PACKET_SIZE, &actual_len,
1417 100);
1418 j = 0;
1419 } else if (size < COMMAND_PACKET_SIZE) {
1420 result = usb_bulk_msg(dec->udev, dec->command_pipe, b,
1421 j - COMMAND_PACKET_SIZE + size,
1422 &actual_len, 100);
1423 }
1424 }
1425
1426 result = ttusb_dec_send_command(dec, 0x43, sizeof(b1), b1, NULL, NULL);
1427
Anssi Hannula0c744b02005-07-07 17:57:42 -07001428 release_firmware(fw_entry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001429 kfree(b);
1430
1431 return result;
1432}
1433
1434static int ttusb_dec_init_stb(struct ttusb_dec *dec)
1435{
1436 int result;
Hans Verkuilcf8e1932009-01-17 13:09:11 -03001437 unsigned int mode = 0, model = 0, version = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001438
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001439 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001440
1441 result = ttusb_dec_get_stb_state(dec, &mode, &model, &version);
Alexey Khoroshilovcf732b52013-10-02 13:00:26 -03001442 if (result)
1443 return result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001444
Alexey Khoroshilovcf732b52013-10-02 13:00:26 -03001445 if (!mode) {
1446 if (version == 0xABCDEFAB)
Mauro Carvalho Chehabbf769a42016-10-18 17:44:20 -02001447 printk(KERN_INFO "ttusb_dec: no version info in Firmware\n");
Alexey Khoroshilovcf732b52013-10-02 13:00:26 -03001448 else
Mauro Carvalho Chehabbf769a42016-10-18 17:44:20 -02001449 printk(KERN_INFO "ttusb_dec: Firmware %x.%02x%c%c\n",
Alexey Khoroshilovcf732b52013-10-02 13:00:26 -03001450 version >> 24, (version >> 16) & 0xff,
1451 (version >> 8) & 0xff, version & 0xff);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001452
Alexey Khoroshilovcf732b52013-10-02 13:00:26 -03001453 result = ttusb_dec_boot_dsp(dec);
1454 if (result)
1455 return result;
1456 } else {
1457 /* We can't trust the USB IDs that some firmwares
1458 give the box */
1459 switch (model) {
1460 case 0x00070001:
1461 case 0x00070008:
1462 case 0x0007000c:
1463 ttusb_dec_set_model(dec, TTUSB_DEC3000S);
1464 break;
1465 case 0x00070009:
1466 case 0x00070013:
1467 ttusb_dec_set_model(dec, TTUSB_DEC2000T);
1468 break;
1469 case 0x00070011:
1470 ttusb_dec_set_model(dec, TTUSB_DEC2540T);
1471 break;
1472 default:
Mauro Carvalho Chehabbf769a42016-10-18 17:44:20 -02001473 printk(KERN_ERR "%s: unknown model returned by firmware (%08x) - please report\n",
Alexey Khoroshilovcf732b52013-10-02 13:00:26 -03001474 __func__, model);
1475 return -ENOENT;
1476 }
Mauro Carvalho Chehab3ff105e2015-04-29 17:09:50 -03001477 if (version >= 0x01770000)
1478 dec->can_playback = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001479 }
Alexey Khoroshilovcf732b52013-10-02 13:00:26 -03001480 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001481}
1482
1483static int ttusb_dec_init_dvb(struct ttusb_dec *dec)
1484{
1485 int result;
1486
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001487 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001488
1489 if ((result = dvb_register_adapter(&dec->adapter,
Janne Grunau78e920062008-04-09 19:13:13 -03001490 dec->model_name, THIS_MODULE,
1491 &dec->udev->dev,
1492 adapter_nr)) < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001493 printk("%s: dvb_register_adapter failed: error %d\n",
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001494 __func__, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001495
1496 return result;
1497 }
1498
1499 dec->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
1500
1501 dec->demux.priv = (void *)dec;
1502 dec->demux.filternum = 31;
1503 dec->demux.feednum = 31;
1504 dec->demux.start_feed = ttusb_dec_start_feed;
1505 dec->demux.stop_feed = ttusb_dec_stop_feed;
1506 dec->demux.write_to_decoder = NULL;
1507
1508 if ((result = dvb_dmx_init(&dec->demux)) < 0) {
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001509 printk("%s: dvb_dmx_init failed: error %d\n", __func__,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001510 result);
1511
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001512 dvb_unregister_adapter(&dec->adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001513
1514 return result;
1515 }
1516
1517 dec->dmxdev.filternum = 32;
1518 dec->dmxdev.demux = &dec->demux.dmx;
1519 dec->dmxdev.capabilities = 0;
1520
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001521 if ((result = dvb_dmxdev_init(&dec->dmxdev, &dec->adapter)) < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001522 printk("%s: dvb_dmxdev_init failed: error %d\n",
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001523 __func__, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001524
1525 dvb_dmx_release(&dec->demux);
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001526 dvb_unregister_adapter(&dec->adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001527
1528 return result;
1529 }
1530
1531 dec->frontend.source = DMX_FRONTEND_0;
1532
1533 if ((result = dec->demux.dmx.add_frontend(&dec->demux.dmx,
1534 &dec->frontend)) < 0) {
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001535 printk("%s: dvb_dmx_init failed: error %d\n", __func__,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001536 result);
1537
1538 dvb_dmxdev_release(&dec->dmxdev);
1539 dvb_dmx_release(&dec->demux);
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001540 dvb_unregister_adapter(&dec->adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001541
1542 return result;
1543 }
1544
1545 if ((result = dec->demux.dmx.connect_frontend(&dec->demux.dmx,
1546 &dec->frontend)) < 0) {
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001547 printk("%s: dvb_dmx_init failed: error %d\n", __func__,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001548 result);
1549
1550 dec->demux.dmx.remove_frontend(&dec->demux.dmx, &dec->frontend);
1551 dvb_dmxdev_release(&dec->dmxdev);
1552 dvb_dmx_release(&dec->demux);
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001553 dvb_unregister_adapter(&dec->adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001554
1555 return result;
1556 }
1557
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001558 dvb_net_init(&dec->adapter, &dec->dvb_net, &dec->demux.dmx);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001559
1560 return 0;
1561}
1562
1563static void ttusb_dec_exit_dvb(struct ttusb_dec *dec)
1564{
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001565 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001566
1567 dvb_net_release(&dec->dvb_net);
1568 dec->demux.dmx.close(&dec->demux.dmx);
1569 dec->demux.dmx.remove_frontend(&dec->demux.dmx, &dec->frontend);
1570 dvb_dmxdev_release(&dec->dmxdev);
1571 dvb_dmx_release(&dec->demux);
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001572 if (dec->fe) {
1573 dvb_unregister_frontend(dec->fe);
1574 if (dec->fe->ops.release)
1575 dec->fe->ops.release(dec->fe);
1576 }
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001577 dvb_unregister_adapter(&dec->adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001578}
1579
1580static void ttusb_dec_exit_rc(struct ttusb_dec *dec)
1581{
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001582 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001583
Dmitry Torokhovb7df3912005-09-15 02:01:53 -05001584 if (dec->rc_input_dev) {
1585 input_unregister_device(dec->rc_input_dev);
1586 dec->rc_input_dev = NULL;
1587 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001588}
1589
1590
1591static void ttusb_dec_exit_usb(struct ttusb_dec *dec)
1592{
1593 int i;
1594
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001595 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001596
Alexey Khoroshilovcf732b52013-10-02 13:00:26 -03001597 if (enable_rc) {
1598 /* we have to check whether the irq URB is already submitted.
1599 * As the irq is submitted after the interface is changed,
1600 * this is the best method i figured out.
1601 * Any others?*/
1602 if (dec->interface == TTUSB_DEC_INTERFACE_IN)
1603 usb_kill_urb(dec->irq_urb);
1604
1605 usb_free_urb(dec->irq_urb);
1606
1607 usb_free_coherent(dec->udev, IRQ_PACKET_SIZE,
1608 dec->irq_buffer, dec->irq_dma_handle);
1609 }
1610
Linus Torvalds1da177e2005-04-16 15:20:36 -07001611 dec->iso_stream_count = 0;
1612
1613 for (i = 0; i < ISO_BUF_COUNT; i++)
1614 usb_kill_urb(dec->iso_urb[i]);
1615
1616 ttusb_dec_free_iso_urbs(dec);
1617}
1618
1619static void ttusb_dec_exit_tasklet(struct ttusb_dec *dec)
1620{
1621 struct list_head *item;
1622 struct urb_frame *frame;
1623
1624 tasklet_kill(&dec->urb_tasklet);
1625
1626 while ((item = dec->urb_frame_list.next) != &dec->urb_frame_list) {
1627 frame = list_entry(item, struct urb_frame, urb_frame_list);
1628 list_del(&frame->urb_frame_list);
1629 kfree(frame);
1630 }
1631}
1632
1633static void ttusb_dec_init_filters(struct ttusb_dec *dec)
1634{
1635 INIT_LIST_HEAD(&dec->filter_info_list);
1636 spin_lock_init(&dec->filter_info_list_lock);
1637}
1638
1639static void ttusb_dec_exit_filters(struct ttusb_dec *dec)
1640{
1641 struct list_head *item;
1642 struct filter_info *finfo;
1643
1644 while ((item = dec->filter_info_list.next) != &dec->filter_info_list) {
1645 finfo = list_entry(item, struct filter_info, filter_info_list);
1646 list_del(&finfo->filter_info_list);
1647 kfree(finfo);
1648 }
1649}
1650
Johannes Stezenbachd91b7302005-05-16 21:54:38 -07001651static int fe_send_command(struct dvb_frontend* fe, const u8 command,
1652 int param_length, const u8 params[],
1653 int *result_length, u8 cmd_result[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07001654{
Alex Woodsf961e712006-01-09 15:25:24 -02001655 struct ttusb_dec* dec = fe->dvb->priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001656 return ttusb_dec_send_command(dec, command, param_length, params, result_length, cmd_result);
1657}
1658
Julia Lawall9bca6262015-11-13 12:55:18 -02001659static const struct ttusbdecfe_config fe_config = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001660 .send_command = fe_send_command
1661};
1662
1663static int ttusb_dec_probe(struct usb_interface *intf,
1664 const struct usb_device_id *id)
1665{
1666 struct usb_device *udev;
1667 struct ttusb_dec *dec;
Alexey Khoroshilovcf732b52013-10-02 13:00:26 -03001668 int result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001669
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001670 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001671
1672 udev = interface_to_usbdev(intf);
1673
Panagiotis Issaris74081872006-01-11 19:40:56 -02001674 if (!(dec = kzalloc(sizeof(struct ttusb_dec), GFP_KERNEL))) {
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001675 printk("%s: couldn't allocate memory.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001676 return -ENOMEM;
1677 }
1678
1679 usb_set_intfdata(intf, (void *)dec);
1680
Al Virod4f979a2008-05-21 00:31:31 -03001681 switch (id->idProduct) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001682 case 0x1006:
1683 ttusb_dec_set_model(dec, TTUSB_DEC3000S);
1684 break;
1685
1686 case 0x1008:
1687 ttusb_dec_set_model(dec, TTUSB_DEC2000T);
1688 break;
1689
1690 case 0x1009:
1691 ttusb_dec_set_model(dec, TTUSB_DEC2540T);
1692 break;
1693 }
1694
1695 dec->udev = udev;
1696
Alexey Khoroshilovcf732b52013-10-02 13:00:26 -03001697 result = ttusb_dec_init_usb(dec);
1698 if (result)
1699 goto err_usb;
1700 result = ttusb_dec_init_stb(dec);
1701 if (result)
1702 goto err_stb;
1703 result = ttusb_dec_init_dvb(dec);
1704 if (result)
1705 goto err_stb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001706
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001707 dec->adapter.priv = dec;
Al Virod4f979a2008-05-21 00:31:31 -03001708 switch (id->idProduct) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001709 case 0x1006:
1710 dec->fe = ttusbdecfe_dvbs_attach(&fe_config);
1711 break;
1712
1713 case 0x1008:
1714 case 0x1009:
1715 dec->fe = ttusbdecfe_dvbt_attach(&fe_config);
1716 break;
1717 }
1718
1719 if (dec->fe == NULL) {
Bjorn Helgaas29e66a62008-09-04 17:24:51 -03001720 printk("dvb-ttusb-dec: A frontend driver was not found for device [%04x:%04x]\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001721 le16_to_cpu(dec->udev->descriptor.idVendor),
1722 le16_to_cpu(dec->udev->descriptor.idProduct));
1723 } else {
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001724 if (dvb_register_frontend(&dec->adapter, dec->fe)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001725 printk("budget-ci: Frontend registration failed!\n");
Patrick Boettcherdea74862006-05-14 05:01:31 -03001726 if (dec->fe->ops.release)
1727 dec->fe->ops.release(dec->fe);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001728 dec->fe = NULL;
1729 }
1730 }
1731
1732 ttusb_dec_init_v_pes(dec);
1733 ttusb_dec_init_filters(dec);
1734 ttusb_dec_init_tasklet(dec);
1735
1736 dec->active = 1;
1737
1738 ttusb_dec_set_interface(dec, TTUSB_DEC_INTERFACE_IN);
1739
Dmitry Torokhovb7df3912005-09-15 02:01:53 -05001740 if (enable_rc)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001741 ttusb_init_rc(dec);
1742
1743 return 0;
Alexey Khoroshilovcf732b52013-10-02 13:00:26 -03001744err_stb:
1745 ttusb_dec_exit_usb(dec);
1746err_usb:
1747 kfree(dec);
1748 return result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001749}
1750
1751static void ttusb_dec_disconnect(struct usb_interface *intf)
1752{
1753 struct ttusb_dec *dec = usb_get_intfdata(intf);
1754
1755 usb_set_intfdata(intf, NULL);
1756
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001757 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001758
1759 if (dec->active) {
1760 ttusb_dec_exit_tasklet(dec);
1761 ttusb_dec_exit_filters(dec);
1762 if(enable_rc)
1763 ttusb_dec_exit_rc(dec);
1764 ttusb_dec_exit_usb(dec);
1765 ttusb_dec_exit_dvb(dec);
1766 }
1767
1768 kfree(dec);
1769}
1770
1771static void ttusb_dec_set_model(struct ttusb_dec *dec,
1772 enum ttusb_dec_model model)
1773{
1774 dec->model = model;
1775
1776 switch (model) {
1777 case TTUSB_DEC2000T:
1778 dec->model_name = "DEC2000-t";
1779 dec->firmware_name = "dvb-ttusb-dec-2000t.fw";
1780 break;
1781
1782 case TTUSB_DEC2540T:
1783 dec->model_name = "DEC2540-t";
1784 dec->firmware_name = "dvb-ttusb-dec-2540t.fw";
1785 break;
1786
1787 case TTUSB_DEC3000S:
1788 dec->model_name = "DEC3000-s";
1789 dec->firmware_name = "dvb-ttusb-dec-3000s.fw";
1790 break;
1791 }
1792}
1793
Arvind Yadav7fb2e072017-08-13 04:54:43 -04001794static const struct usb_device_id ttusb_dec_table[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001795 {USB_DEVICE(0x0b48, 0x1006)}, /* DEC3000-s */
1796 /*{USB_DEVICE(0x0b48, 0x1007)}, Unconfirmed */
1797 {USB_DEVICE(0x0b48, 0x1008)}, /* DEC2000-t */
1798 {USB_DEVICE(0x0b48, 0x1009)}, /* DEC2540-t */
1799 {}
1800};
1801
1802static struct usb_driver ttusb_dec_driver = {
1803 .name = "ttusb-dec",
1804 .probe = ttusb_dec_probe,
1805 .disconnect = ttusb_dec_disconnect,
1806 .id_table = ttusb_dec_table,
1807};
1808
Greg Kroah-Hartmanecb3b2b2011-11-18 09:46:12 -08001809module_usb_driver(ttusb_dec_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001810
1811MODULE_AUTHOR("Alex Woods <linux-dvb@giblets.org>");
1812MODULE_DESCRIPTION(DRIVER_NAME);
1813MODULE_LICENSE("GPL");
1814MODULE_DEVICE_TABLE(usb, ttusb_dec_table);