blob: de5829b863fd26edd62923cf6168bf9e883bb6ef [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 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 *
21 */
22
Linus Torvalds1da177e2005-04-16 15:20:36 -070023#include <linux/list.h>
24#include <linux/module.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070025#include <linux/pci.h>
26#include <linux/slab.h>
27#include <linux/spinlock.h>
28#include <linux/usb.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070029#include <linux/interrupt.h>
30#include <linux/firmware.h>
31#include <linux/crc32.h>
32#include <linux/init.h>
33#include <linux/input.h>
34
Trent Piepho68277092007-01-30 23:25:46 -030035#include <linux/mutex.h>
36
Linus Torvalds1da177e2005-04-16 15:20:36 -070037#include "dmxdev.h"
38#include "dvb_demux.h"
39#include "dvb_filter.h"
40#include "dvb_frontend.h"
41#include "dvb_net.h"
42#include "ttusbdecfe.h"
43
44static int debug;
45static int output_pva;
46static int enable_rc;
47
48module_param(debug, int, 0644);
49MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
50module_param(output_pva, int, 0444);
51MODULE_PARM_DESC(output_pva, "Output PVA from dvr device (default:off)");
52module_param(enable_rc, int, 0644);
53MODULE_PARM_DESC(enable_rc, "Turn on/off IR remote control(default: off)");
54
Janne Grunau78e92002008-04-09 19:13:13 -030055DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
56
Linus Torvalds1da177e2005-04-16 15:20:36 -070057#define dprintk if (debug) printk
58
59#define DRIVER_NAME "TechnoTrend/Hauppauge DEC USB"
60
61#define COMMAND_PIPE 0x03
62#define RESULT_PIPE 0x04
63#define IN_PIPE 0x08
64#define OUT_PIPE 0x07
65#define IRQ_PIPE 0x0A
66
67#define COMMAND_PACKET_SIZE 0x3c
68#define ARM_PACKET_SIZE 0x1000
69#define IRQ_PACKET_SIZE 0x8
70
71#define ISO_BUF_COUNT 0x04
72#define FRAMES_PER_ISO_BUF 0x04
73#define ISO_FRAME_SIZE 0x0380
74
75#define MAX_PVA_LENGTH 6144
76
77enum ttusb_dec_model {
78 TTUSB_DEC2000T,
79 TTUSB_DEC2540T,
80 TTUSB_DEC3000S
81};
82
83enum ttusb_dec_packet_type {
84 TTUSB_DEC_PACKET_PVA,
85 TTUSB_DEC_PACKET_SECTION,
86 TTUSB_DEC_PACKET_EMPTY
87};
88
89enum ttusb_dec_interface {
90 TTUSB_DEC_INTERFACE_INITIAL,
91 TTUSB_DEC_INTERFACE_IN,
92 TTUSB_DEC_INTERFACE_OUT
93};
94
95struct ttusb_dec {
96 enum ttusb_dec_model model;
97 char *model_name;
98 char *firmware_name;
99 int can_playback;
100
101 /* DVB bits */
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -0700102 struct dvb_adapter adapter;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700103 struct dmxdev dmxdev;
104 struct dvb_demux demux;
105 struct dmx_frontend frontend;
106 struct dvb_net dvb_net;
107 struct dvb_frontend* fe;
108
109 u16 pid[DMX_PES_OTHER];
110
111 /* USB bits */
112 struct usb_device *udev;
113 u8 trans_count;
114 unsigned int command_pipe;
115 unsigned int result_pipe;
116 unsigned int in_pipe;
117 unsigned int out_pipe;
118 unsigned int irq_pipe;
119 enum ttusb_dec_interface interface;
Ingo Molnar3593cab2006-02-07 06:49:14 -0200120 struct mutex usb_mutex;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700121
122 void *irq_buffer;
123 struct urb *irq_urb;
124 dma_addr_t irq_dma_handle;
125 void *iso_buffer;
126 dma_addr_t iso_dma_handle;
127 struct urb *iso_urb[ISO_BUF_COUNT];
128 int iso_stream_count;
Ingo Molnar3593cab2006-02-07 06:49:14 -0200129 struct mutex iso_mutex;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700130
131 u8 packet[MAX_PVA_LENGTH + 4];
132 enum ttusb_dec_packet_type packet_type;
133 int packet_state;
134 int packet_length;
135 int packet_payload_length;
136 u16 next_packet_id;
137
138 int pva_stream_count;
139 int filter_stream_count;
140
141 struct dvb_filter_pes2ts a_pes2ts;
142 struct dvb_filter_pes2ts v_pes2ts;
143
144 u8 v_pes[16 + MAX_PVA_LENGTH];
145 int v_pes_length;
146 int v_pes_postbytes;
147
148 struct list_head urb_frame_list;
149 struct tasklet_struct urb_tasklet;
150 spinlock_t urb_frame_list_lock;
151
152 struct dvb_demux_filter *audio_filter;
153 struct dvb_demux_filter *video_filter;
154 struct list_head filter_info_list;
155 spinlock_t filter_info_list_lock;
156
Dmitry Torokhovb7df3912005-09-15 02:01:53 -0500157 struct input_dev *rc_input_dev;
158 char rc_phys[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700159
160 int active; /* Loaded successfully */
161};
162
163struct urb_frame {
164 u8 data[ISO_FRAME_SIZE];
165 int length;
166 struct list_head urb_frame_list;
167};
168
169struct filter_info {
170 u8 stream_id;
171 struct dvb_demux_filter *filter;
172 struct list_head filter_info_list;
173};
174
175static u16 rc_keys[] = {
176 KEY_POWER,
177 KEY_MUTE,
178 KEY_1,
179 KEY_2,
180 KEY_3,
181 KEY_4,
182 KEY_5,
183 KEY_6,
184 KEY_7,
185 KEY_8,
186 KEY_9,
187 KEY_0,
188 KEY_CHANNELUP,
189 KEY_VOLUMEDOWN,
190 KEY_OK,
191 KEY_VOLUMEUP,
192 KEY_CHANNELDOWN,
193 KEY_PREVIOUS,
194 KEY_ESC,
195 KEY_RED,
196 KEY_GREEN,
197 KEY_YELLOW,
198 KEY_BLUE,
199 KEY_OPTION,
200 KEY_M,
201 KEY_RADIO
202};
203
204static void ttusb_dec_set_model(struct ttusb_dec *dec,
205 enum ttusb_dec_model model);
206
David Howells7d12e782006-10-05 14:55:46 +0100207static void ttusb_dec_handle_irq( struct urb *urb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700208{
209 struct ttusb_dec * dec = urb->context;
210 char *buffer = dec->irq_buffer;
211 int retval;
212
213 switch(urb->status) {
214 case 0: /*success*/
215 break;
216 case -ECONNRESET:
217 case -ENOENT:
218 case -ESHUTDOWN:
Pete Zaitcev38e2bfc2006-09-18 22:49:02 -0700219 case -ETIME:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700220 /* this urb is dead, cleanup */
221 dprintk("%s:urb shutting down with status: %d\n",
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300222 __func__, urb->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700223 return;
224 default:
225 dprintk("%s:nonzero status received: %d\n",
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300226 __func__,urb->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700227 goto exit;
228 }
229
230 if( (buffer[0] == 0x1) && (buffer[2] == 0x15) ) {
231 /* IR - Event */
232 /* this is an fact a bit too simple implementation;
233 * the box also reports a keyrepeat signal
234 * (with buffer[3] == 0x40) in an intervall of ~100ms.
235 * But to handle this correctly we had to imlemenent some
236 * kind of timer which signals a 'key up' event if no
237 * keyrepeat signal is recieved for lets say 200ms.
238 * this should/could be added later ...
239 * for now lets report each signal as a key down and up*/
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300240 dprintk("%s:rc signal:%d\n", __func__, buffer[4]);
Dmitry Torokhovb7df3912005-09-15 02:01:53 -0500241 input_report_key(dec->rc_input_dev, rc_keys[buffer[4] - 1], 1);
Dmitry Torokhovb07b4782006-11-20 10:23:04 -0300242 input_sync(dec->rc_input_dev);
Dmitry Torokhovb7df3912005-09-15 02:01:53 -0500243 input_report_key(dec->rc_input_dev, rc_keys[buffer[4] - 1], 0);
244 input_sync(dec->rc_input_dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700245 }
246
247exit: retval = usb_submit_urb(urb, GFP_ATOMIC);
248 if(retval)
249 printk("%s - usb_commit_urb failed with result: %d\n",
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300250 __func__, retval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700251}
252
253static u16 crc16(u16 crc, const u8 *buf, size_t len)
254{
255 u16 tmp;
256
257 while (len--) {
258 crc ^= *buf++;
259 crc ^= (u8)crc >> 4;
260 tmp = (u8)crc;
261 crc ^= (tmp ^ (tmp << 1)) << 4;
262 }
263 return crc;
264}
265
266static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command,
267 int param_length, const u8 params[],
268 int *result_length, u8 cmd_result[])
269{
270 int result, actual_len, i;
271 u8 *b;
272
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300273 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700274
275 b = kmalloc(COMMAND_PACKET_SIZE + 4, GFP_KERNEL);
276 if (!b)
277 return -ENOMEM;
278
Ingo Molnar3593cab2006-02-07 06:49:14 -0200279 if ((result = mutex_lock_interruptible(&dec->usb_mutex))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700280 kfree(b);
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300281 printk("%s: Failed to lock usb mutex.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700282 return result;
283 }
284
285 b[0] = 0xaa;
286 b[1] = ++dec->trans_count;
287 b[2] = command;
288 b[3] = param_length;
289
290 if (params)
291 memcpy(&b[4], params, param_length);
292
293 if (debug) {
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300294 printk("%s: command: ", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700295 for (i = 0; i < param_length + 4; i++)
296 printk("0x%02X ", b[i]);
297 printk("\n");
298 }
299
300 result = usb_bulk_msg(dec->udev, dec->command_pipe, b,
301 COMMAND_PACKET_SIZE + 4, &actual_len, 1000);
302
303 if (result) {
304 printk("%s: command bulk message failed: error %d\n",
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300305 __func__, result);
Ingo Molnar3593cab2006-02-07 06:49:14 -0200306 mutex_unlock(&dec->usb_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700307 kfree(b);
308 return result;
309 }
310
311 result = usb_bulk_msg(dec->udev, dec->result_pipe, b,
312 COMMAND_PACKET_SIZE + 4, &actual_len, 1000);
313
314 if (result) {
315 printk("%s: result bulk message failed: error %d\n",
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300316 __func__, result);
Ingo Molnar3593cab2006-02-07 06:49:14 -0200317 mutex_unlock(&dec->usb_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700318 kfree(b);
319 return result;
320 } else {
321 if (debug) {
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300322 printk("%s: result: ", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700323 for (i = 0; i < actual_len; i++)
324 printk("0x%02X ", b[i]);
325 printk("\n");
326 }
327
328 if (result_length)
329 *result_length = b[3];
330 if (cmd_result && b[3] > 0)
331 memcpy(cmd_result, &b[4], b[3]);
332
Ingo Molnar3593cab2006-02-07 06:49:14 -0200333 mutex_unlock(&dec->usb_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700334
335 kfree(b);
336 return 0;
337 }
338}
339
340static int ttusb_dec_get_stb_state (struct ttusb_dec *dec, unsigned int *mode,
341 unsigned int *model, unsigned int *version)
342{
343 u8 c[COMMAND_PACKET_SIZE];
344 int c_length;
345 int result;
Al Virod4f979a2008-05-21 00:31:31 -0300346 __be32 tmp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700347
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300348 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700349
350 result = ttusb_dec_send_command(dec, 0x08, 0, NULL, &c_length, c);
351 if (result)
352 return result;
353
354 if (c_length >= 0x0c) {
355 if (mode != NULL) {
356 memcpy(&tmp, c, 4);
357 *mode = ntohl(tmp);
358 }
359 if (model != NULL) {
360 memcpy(&tmp, &c[4], 4);
361 *model = ntohl(tmp);
362 }
363 if (version != NULL) {
364 memcpy(&tmp, &c[8], 4);
365 *version = ntohl(tmp);
366 }
367 return 0;
368 } else {
369 return -1;
370 }
371}
372
373static int ttusb_dec_audio_pes2ts_cb(void *priv, unsigned char *data)
374{
Alex Woodsf961e712006-01-09 15:25:24 -0200375 struct ttusb_dec *dec = priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700376
377 dec->audio_filter->feed->cb.ts(data, 188, NULL, 0,
378 &dec->audio_filter->feed->feed.ts,
379 DMX_OK);
380
381 return 0;
382}
383
384static int ttusb_dec_video_pes2ts_cb(void *priv, unsigned char *data)
385{
Alex Woodsf961e712006-01-09 15:25:24 -0200386 struct ttusb_dec *dec = priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700387
388 dec->video_filter->feed->cb.ts(data, 188, NULL, 0,
389 &dec->video_filter->feed->feed.ts,
390 DMX_OK);
391
392 return 0;
393}
394
395static void ttusb_dec_set_pids(struct ttusb_dec *dec)
396{
397 u8 b[] = { 0x00, 0x00, 0x00, 0x00,
398 0x00, 0x00, 0xff, 0xff,
399 0xff, 0xff, 0xff, 0xff };
400
Al Virod4f979a2008-05-21 00:31:31 -0300401 __be16 pcr = htons(dec->pid[DMX_PES_PCR]);
402 __be16 audio = htons(dec->pid[DMX_PES_AUDIO]);
403 __be16 video = htons(dec->pid[DMX_PES_VIDEO]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700404
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300405 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700406
407 memcpy(&b[0], &pcr, 2);
408 memcpy(&b[2], &audio, 2);
409 memcpy(&b[4], &video, 2);
410
411 ttusb_dec_send_command(dec, 0x50, sizeof(b), b, NULL, NULL);
412
413 dvb_filter_pes2ts_init(&dec->a_pes2ts, dec->pid[DMX_PES_AUDIO],
414 ttusb_dec_audio_pes2ts_cb, dec);
415 dvb_filter_pes2ts_init(&dec->v_pes2ts, dec->pid[DMX_PES_VIDEO],
416 ttusb_dec_video_pes2ts_cb, dec);
417 dec->v_pes_length = 0;
418 dec->v_pes_postbytes = 0;
419}
420
421static void ttusb_dec_process_pva(struct ttusb_dec *dec, u8 *pva, int length)
422{
423 if (length < 8) {
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300424 printk("%s: packet too short - discarding\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425 return;
426 }
427
428 if (length > 8 + MAX_PVA_LENGTH) {
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300429 printk("%s: packet too long - discarding\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700430 return;
431 }
432
433 switch (pva[2]) {
434
435 case 0x01: { /* VideoStream */
436 int prebytes = pva[5] & 0x03;
437 int postbytes = (pva[5] & 0x0c) >> 2;
Al Virod4f979a2008-05-21 00:31:31 -0300438 __be16 v_pes_payload_length;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700439
440 if (output_pva) {
441 dec->video_filter->feed->cb.ts(pva, length, NULL, 0,
442 &dec->video_filter->feed->feed.ts, DMX_OK);
443 return;
444 }
445
446 if (dec->v_pes_postbytes > 0 &&
447 dec->v_pes_postbytes == prebytes) {
448 memcpy(&dec->v_pes[dec->v_pes_length],
449 &pva[12], prebytes);
450
451 dvb_filter_pes2ts(&dec->v_pes2ts, dec->v_pes,
452 dec->v_pes_length + prebytes, 1);
453 }
454
455 if (pva[5] & 0x10) {
456 dec->v_pes[7] = 0x80;
457 dec->v_pes[8] = 0x05;
458
459 dec->v_pes[9] = 0x21 | ((pva[8] & 0xc0) >> 5);
460 dec->v_pes[10] = ((pva[8] & 0x3f) << 2) |
461 ((pva[9] & 0xc0) >> 6);
462 dec->v_pes[11] = 0x01 |
463 ((pva[9] & 0x3f) << 2) |
464 ((pva[10] & 0x80) >> 6);
465 dec->v_pes[12] = ((pva[10] & 0x7f) << 1) |
466 ((pva[11] & 0xc0) >> 7);
467 dec->v_pes[13] = 0x01 | ((pva[11] & 0x7f) << 1);
468
469 memcpy(&dec->v_pes[14], &pva[12 + prebytes],
470 length - 12 - prebytes);
471 dec->v_pes_length = 14 + length - 12 - prebytes;
472 } else {
473 dec->v_pes[7] = 0x00;
474 dec->v_pes[8] = 0x00;
475
476 memcpy(&dec->v_pes[9], &pva[8], length - 8);
477 dec->v_pes_length = 9 + length - 8;
478 }
479
480 dec->v_pes_postbytes = postbytes;
481
482 if (dec->v_pes[9 + dec->v_pes[8]] == 0x00 &&
483 dec->v_pes[10 + dec->v_pes[8]] == 0x00 &&
484 dec->v_pes[11 + dec->v_pes[8]] == 0x01)
485 dec->v_pes[6] = 0x84;
486 else
487 dec->v_pes[6] = 0x80;
488
489 v_pes_payload_length = htons(dec->v_pes_length - 6 +
490 postbytes);
491 memcpy(&dec->v_pes[4], &v_pes_payload_length, 2);
492
493 if (postbytes == 0)
494 dvb_filter_pes2ts(&dec->v_pes2ts, dec->v_pes,
495 dec->v_pes_length, 1);
496
497 break;
498 }
499
500 case 0x02: /* MainAudioStream */
501 if (output_pva) {
502 dec->audio_filter->feed->cb.ts(pva, length, NULL, 0,
503 &dec->audio_filter->feed->feed.ts, DMX_OK);
504 return;
505 }
506
507 dvb_filter_pes2ts(&dec->a_pes2ts, &pva[8], length - 8,
508 pva[5] & 0x10);
509 break;
510
511 default:
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300512 printk("%s: unknown PVA type: %02x.\n", __func__,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700513 pva[2]);
514 break;
515 }
516}
517
518static void ttusb_dec_process_filter(struct ttusb_dec *dec, u8 *packet,
519 int length)
520{
521 struct list_head *item;
522 struct filter_info *finfo;
523 struct dvb_demux_filter *filter = NULL;
524 unsigned long flags;
525 u8 sid;
526
527 sid = packet[1];
528 spin_lock_irqsave(&dec->filter_info_list_lock, flags);
529 for (item = dec->filter_info_list.next; item != &dec->filter_info_list;
530 item = item->next) {
531 finfo = list_entry(item, struct filter_info, filter_info_list);
532 if (finfo->stream_id == sid) {
533 filter = finfo->filter;
534 break;
535 }
536 }
537 spin_unlock_irqrestore(&dec->filter_info_list_lock, flags);
538
539 if (filter)
540 filter->feed->cb.sec(&packet[2], length - 2, NULL, 0,
541 &filter->filter, DMX_OK);
542}
543
544static void ttusb_dec_process_packet(struct ttusb_dec *dec)
545{
546 int i;
547 u16 csum = 0;
548 u16 packet_id;
549
550 if (dec->packet_length % 2) {
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300551 printk("%s: odd sized packet - discarding\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700552 return;
553 }
554
555 for (i = 0; i < dec->packet_length; i += 2)
556 csum ^= ((dec->packet[i] << 8) + dec->packet[i + 1]);
557
558 if (csum) {
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300559 printk("%s: checksum failed - discarding\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700560 return;
561 }
562
563 packet_id = dec->packet[dec->packet_length - 4] << 8;
564 packet_id += dec->packet[dec->packet_length - 3];
565
566 if ((packet_id != dec->next_packet_id) && dec->next_packet_id) {
567 printk("%s: warning: lost packets between %u and %u\n",
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300568 __func__, dec->next_packet_id - 1, packet_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700569 }
570
571 if (packet_id == 0xffff)
572 dec->next_packet_id = 0x8000;
573 else
574 dec->next_packet_id = packet_id + 1;
575
576 switch (dec->packet_type) {
577 case TTUSB_DEC_PACKET_PVA:
578 if (dec->pva_stream_count)
579 ttusb_dec_process_pva(dec, dec->packet,
580 dec->packet_payload_length);
581 break;
582
583 case TTUSB_DEC_PACKET_SECTION:
584 if (dec->filter_stream_count)
585 ttusb_dec_process_filter(dec, dec->packet,
586 dec->packet_payload_length);
587 break;
588
589 case TTUSB_DEC_PACKET_EMPTY:
590 break;
591 }
592}
593
594static void swap_bytes(u8 *b, int length)
595{
596 u8 c;
597
598 length -= length % 2;
599 for (; length; b += 2, length -= 2) {
600 c = *b;
601 *b = *(b + 1);
602 *(b + 1) = c;
603 }
604}
605
606static void ttusb_dec_process_urb_frame(struct ttusb_dec *dec, u8 *b,
607 int length)
608{
609 swap_bytes(b, length);
610
611 while (length) {
612 switch (dec->packet_state) {
613
614 case 0:
615 case 1:
616 case 2:
617 if (*b++ == 0xaa)
618 dec->packet_state++;
619 else
620 dec->packet_state = 0;
621
622 length--;
623 break;
624
625 case 3:
626 if (*b == 0x00) {
627 dec->packet_state++;
628 dec->packet_length = 0;
629 } else if (*b != 0xaa) {
630 dec->packet_state = 0;
631 }
632
633 b++;
634 length--;
635 break;
636
637 case 4:
638 dec->packet[dec->packet_length++] = *b++;
639
640 if (dec->packet_length == 2) {
641 if (dec->packet[0] == 'A' &&
642 dec->packet[1] == 'V') {
643 dec->packet_type =
644 TTUSB_DEC_PACKET_PVA;
645 dec->packet_state++;
646 } else if (dec->packet[0] == 'S') {
647 dec->packet_type =
648 TTUSB_DEC_PACKET_SECTION;
649 dec->packet_state++;
650 } else if (dec->packet[0] == 0x00) {
651 dec->packet_type =
652 TTUSB_DEC_PACKET_EMPTY;
653 dec->packet_payload_length = 2;
654 dec->packet_state = 7;
655 } else {
656 printk("%s: unknown packet type: "
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300657 "%02x%02x\n", __func__,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700658 dec->packet[0], dec->packet[1]);
659 dec->packet_state = 0;
660 }
661 }
662
663 length--;
664 break;
665
666 case 5:
667 dec->packet[dec->packet_length++] = *b++;
668
669 if (dec->packet_type == TTUSB_DEC_PACKET_PVA &&
670 dec->packet_length == 8) {
671 dec->packet_state++;
672 dec->packet_payload_length = 8 +
673 (dec->packet[6] << 8) +
674 dec->packet[7];
675 } else if (dec->packet_type ==
676 TTUSB_DEC_PACKET_SECTION &&
677 dec->packet_length == 5) {
678 dec->packet_state++;
679 dec->packet_payload_length = 5 +
680 ((dec->packet[3] & 0x0f) << 8) +
681 dec->packet[4];
682 }
683
684 length--;
685 break;
686
687 case 6: {
688 int remainder = dec->packet_payload_length -
689 dec->packet_length;
690
691 if (length >= remainder) {
692 memcpy(dec->packet + dec->packet_length,
693 b, remainder);
694 dec->packet_length += remainder;
695 b += remainder;
696 length -= remainder;
697 dec->packet_state++;
698 } else {
699 memcpy(&dec->packet[dec->packet_length],
700 b, length);
701 dec->packet_length += length;
702 length = 0;
703 }
704
705 break;
706 }
707
708 case 7: {
709 int tail = 4;
710
711 dec->packet[dec->packet_length++] = *b++;
712
713 if (dec->packet_type == TTUSB_DEC_PACKET_SECTION &&
714 dec->packet_payload_length % 2)
715 tail++;
716
717 if (dec->packet_length ==
718 dec->packet_payload_length + tail) {
719 ttusb_dec_process_packet(dec);
720 dec->packet_state = 0;
721 }
722
723 length--;
724 break;
725 }
726
727 default:
728 printk("%s: illegal packet state encountered.\n",
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300729 __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700730 dec->packet_state = 0;
731 }
732 }
733}
734
735static void ttusb_dec_process_urb_frame_list(unsigned long data)
736{
737 struct ttusb_dec *dec = (struct ttusb_dec *)data;
738 struct list_head *item;
739 struct urb_frame *frame;
740 unsigned long flags;
741
742 while (1) {
743 spin_lock_irqsave(&dec->urb_frame_list_lock, flags);
744 if ((item = dec->urb_frame_list.next) != &dec->urb_frame_list) {
745 frame = list_entry(item, struct urb_frame,
746 urb_frame_list);
747 list_del(&frame->urb_frame_list);
748 } else {
749 spin_unlock_irqrestore(&dec->urb_frame_list_lock,
750 flags);
751 return;
752 }
753 spin_unlock_irqrestore(&dec->urb_frame_list_lock, flags);
754
755 ttusb_dec_process_urb_frame(dec, frame->data, frame->length);
756 kfree(frame);
757 }
758}
759
David Howells7d12e782006-10-05 14:55:46 +0100760static void ttusb_dec_process_urb(struct urb *urb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700761{
762 struct ttusb_dec *dec = urb->context;
763
764 if (!urb->status) {
765 int i;
766
767 for (i = 0; i < FRAMES_PER_ISO_BUF; i++) {
768 struct usb_iso_packet_descriptor *d;
769 u8 *b;
770 int length;
771 struct urb_frame *frame;
772
773 d = &urb->iso_frame_desc[i];
774 b = urb->transfer_buffer + d->offset;
775 length = d->actual_length;
776
777 if ((frame = kmalloc(sizeof(struct urb_frame),
778 GFP_ATOMIC))) {
779 unsigned long flags;
780
781 memcpy(frame->data, b, length);
782 frame->length = length;
783
784 spin_lock_irqsave(&dec->urb_frame_list_lock,
785 flags);
786 list_add_tail(&frame->urb_frame_list,
787 &dec->urb_frame_list);
788 spin_unlock_irqrestore(&dec->urb_frame_list_lock,
789 flags);
790
791 tasklet_schedule(&dec->urb_tasklet);
792 }
793 }
794 } else {
795 /* -ENOENT is expected when unlinking urbs */
796 if (urb->status != -ENOENT)
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300797 dprintk("%s: urb error: %d\n", __func__,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700798 urb->status);
799 }
800
801 if (dec->iso_stream_count)
802 usb_submit_urb(urb, GFP_ATOMIC);
803}
804
805static void ttusb_dec_setup_urbs(struct ttusb_dec *dec)
806{
807 int i, j, buffer_offset = 0;
808
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300809 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700810
811 for (i = 0; i < ISO_BUF_COUNT; i++) {
812 int frame_offset = 0;
813 struct urb *urb = dec->iso_urb[i];
814
815 urb->dev = dec->udev;
816 urb->context = dec;
817 urb->complete = ttusb_dec_process_urb;
818 urb->pipe = dec->in_pipe;
819 urb->transfer_flags = URB_ISO_ASAP;
820 urb->interval = 1;
821 urb->number_of_packets = FRAMES_PER_ISO_BUF;
822 urb->transfer_buffer_length = ISO_FRAME_SIZE *
823 FRAMES_PER_ISO_BUF;
824 urb->transfer_buffer = dec->iso_buffer + buffer_offset;
825 buffer_offset += ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF;
826
827 for (j = 0; j < FRAMES_PER_ISO_BUF; j++) {
828 urb->iso_frame_desc[j].offset = frame_offset;
829 urb->iso_frame_desc[j].length = ISO_FRAME_SIZE;
830 frame_offset += ISO_FRAME_SIZE;
831 }
832 }
833}
834
835static void ttusb_dec_stop_iso_xfer(struct ttusb_dec *dec)
836{
837 int i;
838
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300839 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700840
Ingo Molnar3593cab2006-02-07 06:49:14 -0200841 if (mutex_lock_interruptible(&dec->iso_mutex))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700842 return;
843
844 dec->iso_stream_count--;
845
846 if (!dec->iso_stream_count) {
847 for (i = 0; i < ISO_BUF_COUNT; i++)
848 usb_kill_urb(dec->iso_urb[i]);
849 }
850
Ingo Molnar3593cab2006-02-07 06:49:14 -0200851 mutex_unlock(&dec->iso_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700852}
853
854/* Setting the interface of the DEC tends to take down the USB communications
855 * for a short period, so it's important not to call this function just before
856 * trying to talk to it.
857 */
858static int ttusb_dec_set_interface(struct ttusb_dec *dec,
859 enum ttusb_dec_interface interface)
860{
861 int result = 0;
862 u8 b[] = { 0x05 };
863
864 if (interface != dec->interface) {
865 switch (interface) {
866 case TTUSB_DEC_INTERFACE_INITIAL:
867 result = usb_set_interface(dec->udev, 0, 0);
868 break;
869 case TTUSB_DEC_INTERFACE_IN:
870 result = ttusb_dec_send_command(dec, 0x80, sizeof(b),
871 b, NULL, NULL);
872 if (result)
873 return result;
874 result = usb_set_interface(dec->udev, 0, 8);
875 break;
876 case TTUSB_DEC_INTERFACE_OUT:
877 result = usb_set_interface(dec->udev, 0, 1);
878 break;
879 }
880
881 if (result)
882 return result;
883
884 dec->interface = interface;
885 }
886
887 return 0;
888}
889
890static int ttusb_dec_start_iso_xfer(struct ttusb_dec *dec)
891{
892 int i, result;
893
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300894 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700895
Ingo Molnar3593cab2006-02-07 06:49:14 -0200896 if (mutex_lock_interruptible(&dec->iso_mutex))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700897 return -EAGAIN;
898
899 if (!dec->iso_stream_count) {
900 ttusb_dec_setup_urbs(dec);
901
902 dec->packet_state = 0;
903 dec->v_pes_postbytes = 0;
904 dec->next_packet_id = 0;
905
906 for (i = 0; i < ISO_BUF_COUNT; i++) {
907 if ((result = usb_submit_urb(dec->iso_urb[i],
908 GFP_ATOMIC))) {
909 printk("%s: failed urb submission %d: "
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300910 "error %d\n", __func__, i, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700911
912 while (i) {
913 usb_kill_urb(dec->iso_urb[i - 1]);
914 i--;
915 }
916
Ingo Molnar3593cab2006-02-07 06:49:14 -0200917 mutex_unlock(&dec->iso_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700918 return result;
919 }
920 }
921 }
922
923 dec->iso_stream_count++;
924
Ingo Molnar3593cab2006-02-07 06:49:14 -0200925 mutex_unlock(&dec->iso_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700926
927 return 0;
928}
929
930static int ttusb_dec_start_ts_feed(struct dvb_demux_feed *dvbdmxfeed)
931{
932 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
933 struct ttusb_dec *dec = dvbdmx->priv;
934 u8 b0[] = { 0x05 };
935 int result = 0;
936
Harvey Harrisone9815ce2008-04-08 23:20:00 -0300937 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700938
939 dprintk(" ts_type:");
940
941 if (dvbdmxfeed->ts_type & TS_DECODER)
942 dprintk(" TS_DECODER");
943
944 if (dvbdmxfeed->ts_type & TS_PACKET)
945 dprintk(" TS_PACKET");
946
947 if (dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY)
948 dprintk(" TS_PAYLOAD_ONLY");
949
950 dprintk("\n");
951
952 switch (dvbdmxfeed->pes_type) {
953
954 case DMX_TS_PES_VIDEO:
955 dprintk(" pes_type: DMX_TS_PES_VIDEO\n");
956 dec->pid[DMX_PES_PCR] = dvbdmxfeed->pid;
957 dec->pid[DMX_PES_VIDEO] = dvbdmxfeed->pid;
958 dec->video_filter = dvbdmxfeed->filter;
959 ttusb_dec_set_pids(dec);
960 break;
961
962 case DMX_TS_PES_AUDIO:
963 dprintk(" pes_type: DMX_TS_PES_AUDIO\n");
964 dec->pid[DMX_PES_AUDIO] = dvbdmxfeed->pid;
965 dec->audio_filter = dvbdmxfeed->filter;
966 ttusb_dec_set_pids(dec);
967 break;
968
969 case DMX_TS_PES_TELETEXT:
970 dec->pid[DMX_PES_TELETEXT] = dvbdmxfeed->pid;
Alex Woodsf961e712006-01-09 15:25:24 -0200971 dprintk(" pes_type: DMX_TS_PES_TELETEXT(not supported)\n");
972 return -ENOSYS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700973
974 case DMX_TS_PES_PCR:
975 dprintk(" pes_type: DMX_TS_PES_PCR\n");
976 dec->pid[DMX_PES_PCR] = dvbdmxfeed->pid;
977 ttusb_dec_set_pids(dec);
978 break;
979
980 case DMX_TS_PES_OTHER:
Alex Woodsf961e712006-01-09 15:25:24 -0200981 dprintk(" pes_type: DMX_TS_PES_OTHER(not supported)\n");
982 return -ENOSYS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700983
984 default:
985 dprintk(" pes_type: unknown (%d)\n", dvbdmxfeed->pes_type);
986 return -EINVAL;
987
988 }
989
990 result = ttusb_dec_send_command(dec, 0x80, sizeof(b0), b0, NULL, NULL);
991 if (result)
992 return result;
993
994 dec->pva_stream_count++;
995 return ttusb_dec_start_iso_xfer(dec);
996}
997
998static int ttusb_dec_start_sec_feed(struct dvb_demux_feed *dvbdmxfeed)
999{
1000 struct ttusb_dec *dec = dvbdmxfeed->demux->priv;
1001 u8 b0[] = { 0x00, 0x00, 0x00, 0x01,
1002 0x00, 0x00, 0x00, 0x00,
1003 0x00, 0x00, 0x00, 0x00,
1004 0x00, 0x00, 0x00, 0x00,
1005 0x00, 0xff, 0x00, 0x00,
1006 0x00, 0x00, 0x00, 0x00,
1007 0x00, 0x00, 0x00, 0x00,
1008 0x00 };
Al Virod4f979a2008-05-21 00:31:31 -03001009 __be16 pid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001010 u8 c[COMMAND_PACKET_SIZE];
1011 int c_length;
1012 int result;
1013 struct filter_info *finfo;
1014 unsigned long flags;
1015 u8 x = 1;
1016
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001017 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001018
1019 pid = htons(dvbdmxfeed->pid);
1020 memcpy(&b0[0], &pid, 2);
1021 memcpy(&b0[4], &x, 1);
1022 memcpy(&b0[5], &dvbdmxfeed->filter->filter.filter_value[0], 1);
1023
1024 result = ttusb_dec_send_command(dec, 0x60, sizeof(b0), b0,
1025 &c_length, c);
1026
1027 if (!result) {
1028 if (c_length == 2) {
1029 if (!(finfo = kmalloc(sizeof(struct filter_info),
1030 GFP_ATOMIC)))
1031 return -ENOMEM;
1032
1033 finfo->stream_id = c[1];
1034 finfo->filter = dvbdmxfeed->filter;
1035
1036 spin_lock_irqsave(&dec->filter_info_list_lock, flags);
1037 list_add_tail(&finfo->filter_info_list,
1038 &dec->filter_info_list);
1039 spin_unlock_irqrestore(&dec->filter_info_list_lock,
1040 flags);
1041
1042 dvbdmxfeed->priv = finfo;
1043
1044 dec->filter_stream_count++;
1045 return ttusb_dec_start_iso_xfer(dec);
1046 }
1047
1048 return -EAGAIN;
1049 } else
1050 return result;
1051}
1052
1053static int ttusb_dec_start_feed(struct dvb_demux_feed *dvbdmxfeed)
1054{
1055 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
1056
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001057 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001058
1059 if (!dvbdmx->dmx.frontend)
1060 return -EINVAL;
1061
1062 dprintk(" pid: 0x%04X\n", dvbdmxfeed->pid);
1063
1064 switch (dvbdmxfeed->type) {
1065
1066 case DMX_TYPE_TS:
1067 return ttusb_dec_start_ts_feed(dvbdmxfeed);
1068 break;
1069
1070 case DMX_TYPE_SEC:
1071 return ttusb_dec_start_sec_feed(dvbdmxfeed);
1072 break;
1073
1074 default:
1075 dprintk(" type: unknown (%d)\n", dvbdmxfeed->type);
1076 return -EINVAL;
1077
1078 }
1079}
1080
1081static int ttusb_dec_stop_ts_feed(struct dvb_demux_feed *dvbdmxfeed)
1082{
1083 struct ttusb_dec *dec = dvbdmxfeed->demux->priv;
1084 u8 b0[] = { 0x00 };
1085
1086 ttusb_dec_send_command(dec, 0x81, sizeof(b0), b0, NULL, NULL);
1087
1088 dec->pva_stream_count--;
1089
1090 ttusb_dec_stop_iso_xfer(dec);
1091
1092 return 0;
1093}
1094
1095static int ttusb_dec_stop_sec_feed(struct dvb_demux_feed *dvbdmxfeed)
1096{
1097 struct ttusb_dec *dec = dvbdmxfeed->demux->priv;
1098 u8 b0[] = { 0x00, 0x00 };
1099 struct filter_info *finfo = (struct filter_info *)dvbdmxfeed->priv;
1100 unsigned long flags;
1101
1102 b0[1] = finfo->stream_id;
1103 spin_lock_irqsave(&dec->filter_info_list_lock, flags);
1104 list_del(&finfo->filter_info_list);
1105 spin_unlock_irqrestore(&dec->filter_info_list_lock, flags);
1106 kfree(finfo);
1107 ttusb_dec_send_command(dec, 0x62, sizeof(b0), b0, NULL, NULL);
1108
1109 dec->filter_stream_count--;
1110
1111 ttusb_dec_stop_iso_xfer(dec);
1112
1113 return 0;
1114}
1115
1116static int ttusb_dec_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
1117{
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001118 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001119
1120 switch (dvbdmxfeed->type) {
1121 case DMX_TYPE_TS:
1122 return ttusb_dec_stop_ts_feed(dvbdmxfeed);
1123 break;
1124
1125 case DMX_TYPE_SEC:
1126 return ttusb_dec_stop_sec_feed(dvbdmxfeed);
1127 break;
1128 }
1129
1130 return 0;
1131}
1132
1133static void ttusb_dec_free_iso_urbs(struct ttusb_dec *dec)
1134{
1135 int i;
1136
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001137 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001138
1139 for (i = 0; i < ISO_BUF_COUNT; i++)
Mariusz Kozlowski5d02d022006-11-08 15:34:27 +01001140 usb_free_urb(dec->iso_urb[i]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001141
1142 pci_free_consistent(NULL,
1143 ISO_FRAME_SIZE * (FRAMES_PER_ISO_BUF *
1144 ISO_BUF_COUNT),
1145 dec->iso_buffer, dec->iso_dma_handle);
1146}
1147
1148static int ttusb_dec_alloc_iso_urbs(struct ttusb_dec *dec)
1149{
1150 int i;
1151
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001152 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001153
1154 dec->iso_buffer = pci_alloc_consistent(NULL,
1155 ISO_FRAME_SIZE *
1156 (FRAMES_PER_ISO_BUF *
1157 ISO_BUF_COUNT),
1158 &dec->iso_dma_handle);
1159
1160 memset(dec->iso_buffer, 0,
1161 ISO_FRAME_SIZE * (FRAMES_PER_ISO_BUF * ISO_BUF_COUNT));
1162
1163 for (i = 0; i < ISO_BUF_COUNT; i++) {
1164 struct urb *urb;
1165
1166 if (!(urb = usb_alloc_urb(FRAMES_PER_ISO_BUF, GFP_ATOMIC))) {
1167 ttusb_dec_free_iso_urbs(dec);
1168 return -ENOMEM;
1169 }
1170
1171 dec->iso_urb[i] = urb;
1172 }
1173
1174 ttusb_dec_setup_urbs(dec);
1175
1176 return 0;
1177}
1178
1179static void ttusb_dec_init_tasklet(struct ttusb_dec *dec)
1180{
1181 spin_lock_init(&dec->urb_frame_list_lock);
1182 INIT_LIST_HEAD(&dec->urb_frame_list);
1183 tasklet_init(&dec->urb_tasklet, ttusb_dec_process_urb_frame_list,
1184 (unsigned long)dec);
1185}
1186
Michael Krufky50c25ff2006-01-09 15:25:34 -02001187static int ttusb_init_rc( struct ttusb_dec *dec)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001188{
Dmitry Torokhovb7df3912005-09-15 02:01:53 -05001189 struct input_dev *input_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001190 u8 b[] = { 0x00, 0x01 };
1191 int i;
Dmitry Torokhovb07b4782006-11-20 10:23:04 -03001192 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001193
Dmitry Torokhovb7df3912005-09-15 02:01:53 -05001194 usb_make_path(dec->udev, dec->rc_phys, sizeof(dec->rc_phys));
1195 strlcpy(dec->rc_phys, "/input0", sizeof(dec->rc_phys));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001196
Dmitry Torokhovb07b4782006-11-20 10:23:04 -03001197 input_dev = input_allocate_device();
Dmitry Torokhovb7df3912005-09-15 02:01:53 -05001198 if (!input_dev)
1199 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001200
Dmitry Torokhovb7df3912005-09-15 02:01:53 -05001201 input_dev->name = "ttusb_dec remote control";
1202 input_dev->phys = dec->rc_phys;
Jiri Slaby7b19ada2007-10-18 23:40:32 -07001203 input_dev->evbit[0] = BIT_MASK(EV_KEY);
Dmitry Torokhovb7df3912005-09-15 02:01:53 -05001204 input_dev->keycodesize = sizeof(u16);
1205 input_dev->keycodemax = 0x1a;
1206 input_dev->keycode = rc_keys;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001207
Dmitry Torokhovb7df3912005-09-15 02:01:53 -05001208 for (i = 0; i < ARRAY_SIZE(rc_keys); i++)
Michael Krufky50c25ff2006-01-09 15:25:34 -02001209 set_bit(rc_keys[i], input_dev->keybit);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001210
Dmitry Torokhovb07b4782006-11-20 10:23:04 -03001211 err = input_register_device(input_dev);
1212 if (err) {
1213 input_free_device(input_dev);
1214 return err;
1215 }
Dmitry Torokhovb7df3912005-09-15 02:01:53 -05001216
Dmitry Torokhovb07b4782006-11-20 10:23:04 -03001217 dec->rc_input_dev = input_dev;
Dmitry Torokhovb7df3912005-09-15 02:01:53 -05001218 if (usb_submit_urb(dec->irq_urb, GFP_KERNEL))
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001219 printk("%s: usb_submit_urb failed\n",__func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001220 /* enable irq pipe */
1221 ttusb_dec_send_command(dec,0xb0,sizeof(b),b,NULL,NULL);
Dmitry Torokhovb7df3912005-09-15 02:01:53 -05001222
1223 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001224}
1225
1226static void ttusb_dec_init_v_pes(struct ttusb_dec *dec)
1227{
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001228 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001229
1230 dec->v_pes[0] = 0x00;
1231 dec->v_pes[1] = 0x00;
1232 dec->v_pes[2] = 0x01;
1233 dec->v_pes[3] = 0xe0;
1234}
1235
1236static int ttusb_dec_init_usb(struct ttusb_dec *dec)
1237{
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001238 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001239
Ingo Molnar3593cab2006-02-07 06:49:14 -02001240 mutex_init(&dec->usb_mutex);
1241 mutex_init(&dec->iso_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001242
1243 dec->command_pipe = usb_sndbulkpipe(dec->udev, COMMAND_PIPE);
1244 dec->result_pipe = usb_rcvbulkpipe(dec->udev, RESULT_PIPE);
1245 dec->in_pipe = usb_rcvisocpipe(dec->udev, IN_PIPE);
1246 dec->out_pipe = usb_sndisocpipe(dec->udev, OUT_PIPE);
1247 dec->irq_pipe = usb_rcvintpipe(dec->udev, IRQ_PIPE);
1248
1249 if(enable_rc) {
1250 dec->irq_urb = usb_alloc_urb(0, GFP_KERNEL);
1251 if(!dec->irq_urb) {
1252 return -ENOMEM;
1253 }
1254 dec->irq_buffer = usb_buffer_alloc(dec->udev,IRQ_PACKET_SIZE,
Christoph Lameter54e6ecb2006-12-06 20:33:16 -08001255 GFP_ATOMIC, &dec->irq_dma_handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001256 if(!dec->irq_buffer) {
1257 return -ENOMEM;
1258 }
1259 usb_fill_int_urb(dec->irq_urb, dec->udev,dec->irq_pipe,
1260 dec->irq_buffer, IRQ_PACKET_SIZE,
1261 ttusb_dec_handle_irq, dec, 1);
1262 dec->irq_urb->transfer_dma = dec->irq_dma_handle;
1263 dec->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
1264 }
1265
1266 return ttusb_dec_alloc_iso_urbs(dec);
1267}
1268
1269static int ttusb_dec_boot_dsp(struct ttusb_dec *dec)
1270{
1271 int i, j, actual_len, result, size, trans_count;
1272 u8 b0[] = { 0x00, 0x00, 0x00, 0x00,
1273 0x00, 0x00, 0x00, 0x00,
1274 0x61, 0x00 };
1275 u8 b1[] = { 0x61 };
1276 u8 *b;
1277 char idstring[21];
David Woodhouse99b6e4f2008-05-24 00:12:00 +01001278 const u8 *firmware = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001279 size_t firmware_size = 0;
1280 u16 firmware_csum = 0;
Al Virod4f979a2008-05-21 00:31:31 -03001281 __be16 firmware_csum_ns;
1282 __be32 firmware_size_nl;
1283 u32 crc32_csum, crc32_check;
1284 __be32 tmp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001285 const struct firmware *fw_entry = NULL;
1286
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001287 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001288
1289 if (request_firmware(&fw_entry, dec->firmware_name, &dec->udev->dev)) {
1290 printk(KERN_ERR "%s: Firmware (%s) unavailable.\n",
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001291 __func__, dec->firmware_name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001292 return 1;
1293 }
1294
1295 firmware = fw_entry->data;
1296 firmware_size = fw_entry->size;
1297
1298 if (firmware_size < 60) {
1299 printk("%s: firmware size too small for DSP code (%zu < 60).\n",
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001300 __func__, firmware_size);
Anssi Hannula0c744b02005-07-07 17:57:42 -07001301 release_firmware(fw_entry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001302 return -1;
1303 }
1304
1305 /* a 32 bit checksum over the first 56 bytes of the DSP Code is stored
1306 at offset 56 of file, so use it to check if the firmware file is
1307 valid. */
1308 crc32_csum = crc32(~0L, firmware, 56) ^ ~0L;
1309 memcpy(&tmp, &firmware[56], 4);
Al Virod4f979a2008-05-21 00:31:31 -03001310 crc32_check = ntohl(tmp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001311 if (crc32_csum != crc32_check) {
1312 printk("%s: crc32 check of DSP code failed (calculated "
1313 "0x%08x != 0x%08x in file), file invalid.\n",
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001314 __func__, crc32_csum, crc32_check);
Anssi Hannula0c744b02005-07-07 17:57:42 -07001315 release_firmware(fw_entry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001316 return -1;
1317 }
1318 memcpy(idstring, &firmware[36], 20);
1319 idstring[20] = '\0';
1320 printk(KERN_INFO "ttusb_dec: found DSP code \"%s\".\n", idstring);
1321
1322 firmware_size_nl = htonl(firmware_size);
1323 memcpy(b0, &firmware_size_nl, 4);
1324 firmware_csum = crc16(~0, firmware, firmware_size) ^ ~0;
1325 firmware_csum_ns = htons(firmware_csum);
1326 memcpy(&b0[6], &firmware_csum_ns, 2);
1327
1328 result = ttusb_dec_send_command(dec, 0x41, sizeof(b0), b0, NULL, NULL);
1329
Anssi Hannula0c744b02005-07-07 17:57:42 -07001330 if (result) {
1331 release_firmware(fw_entry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001332 return result;
Anssi Hannula0c744b02005-07-07 17:57:42 -07001333 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001334
1335 trans_count = 0;
1336 j = 0;
1337
1338 b = kmalloc(ARM_PACKET_SIZE, GFP_KERNEL);
Anssi Hannula0c744b02005-07-07 17:57:42 -07001339 if (b == NULL) {
1340 release_firmware(fw_entry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001341 return -ENOMEM;
Anssi Hannula0c744b02005-07-07 17:57:42 -07001342 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001343
1344 for (i = 0; i < firmware_size; i += COMMAND_PACKET_SIZE) {
1345 size = firmware_size - i;
1346 if (size > COMMAND_PACKET_SIZE)
1347 size = COMMAND_PACKET_SIZE;
1348
1349 b[j + 0] = 0xaa;
1350 b[j + 1] = trans_count++;
1351 b[j + 2] = 0xf0;
1352 b[j + 3] = size;
1353 memcpy(&b[j + 4], &firmware[i], size);
1354
1355 j += COMMAND_PACKET_SIZE + 4;
1356
1357 if (j >= ARM_PACKET_SIZE) {
1358 result = usb_bulk_msg(dec->udev, dec->command_pipe, b,
1359 ARM_PACKET_SIZE, &actual_len,
1360 100);
1361 j = 0;
1362 } else if (size < COMMAND_PACKET_SIZE) {
1363 result = usb_bulk_msg(dec->udev, dec->command_pipe, b,
1364 j - COMMAND_PACKET_SIZE + size,
1365 &actual_len, 100);
1366 }
1367 }
1368
1369 result = ttusb_dec_send_command(dec, 0x43, sizeof(b1), b1, NULL, NULL);
1370
Anssi Hannula0c744b02005-07-07 17:57:42 -07001371 release_firmware(fw_entry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001372 kfree(b);
1373
1374 return result;
1375}
1376
1377static int ttusb_dec_init_stb(struct ttusb_dec *dec)
1378{
1379 int result;
1380 unsigned int mode, model, version;
1381
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001382 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001383
1384 result = ttusb_dec_get_stb_state(dec, &mode, &model, &version);
1385
1386 if (!result) {
1387 if (!mode) {
1388 if (version == 0xABCDEFAB)
1389 printk(KERN_INFO "ttusb_dec: no version "
1390 "info in Firmware\n");
1391 else
1392 printk(KERN_INFO "ttusb_dec: Firmware "
1393 "%x.%02x%c%c\n",
1394 version >> 24, (version >> 16) & 0xff,
1395 (version >> 8) & 0xff, version & 0xff);
1396
1397 result = ttusb_dec_boot_dsp(dec);
1398 if (result)
1399 return result;
1400 else
1401 return 1;
1402 } else {
1403 /* We can't trust the USB IDs that some firmwares
1404 give the box */
1405 switch (model) {
Alex Woodsf961e712006-01-09 15:25:24 -02001406 case 0x00070001:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001407 case 0x00070008:
1408 case 0x0007000c:
1409 ttusb_dec_set_model(dec, TTUSB_DEC3000S);
1410 break;
1411 case 0x00070009:
1412 case 0x00070013:
1413 ttusb_dec_set_model(dec, TTUSB_DEC2000T);
1414 break;
1415 case 0x00070011:
1416 ttusb_dec_set_model(dec, TTUSB_DEC2540T);
1417 break;
1418 default:
1419 printk(KERN_ERR "%s: unknown model returned "
1420 "by firmware (%08x) - please report\n",
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001421 __func__, model);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001422 return -1;
1423 break;
1424 }
1425
1426 if (version >= 0x01770000)
1427 dec->can_playback = 1;
1428
1429 return 0;
1430 }
1431 }
1432 else
1433 return result;
1434}
1435
1436static int ttusb_dec_init_dvb(struct ttusb_dec *dec)
1437{
1438 int result;
1439
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001440 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001441
1442 if ((result = dvb_register_adapter(&dec->adapter,
Janne Grunau78e92002008-04-09 19:13:13 -03001443 dec->model_name, THIS_MODULE,
1444 &dec->udev->dev,
1445 adapter_nr)) < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001446 printk("%s: dvb_register_adapter failed: error %d\n",
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001447 __func__, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001448
1449 return result;
1450 }
1451
1452 dec->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
1453
1454 dec->demux.priv = (void *)dec;
1455 dec->demux.filternum = 31;
1456 dec->demux.feednum = 31;
1457 dec->demux.start_feed = ttusb_dec_start_feed;
1458 dec->demux.stop_feed = ttusb_dec_stop_feed;
1459 dec->demux.write_to_decoder = NULL;
1460
1461 if ((result = dvb_dmx_init(&dec->demux)) < 0) {
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001462 printk("%s: dvb_dmx_init failed: error %d\n", __func__,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001463 result);
1464
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001465 dvb_unregister_adapter(&dec->adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001466
1467 return result;
1468 }
1469
1470 dec->dmxdev.filternum = 32;
1471 dec->dmxdev.demux = &dec->demux.dmx;
1472 dec->dmxdev.capabilities = 0;
1473
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001474 if ((result = dvb_dmxdev_init(&dec->dmxdev, &dec->adapter)) < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001475 printk("%s: dvb_dmxdev_init failed: error %d\n",
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001476 __func__, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001477
1478 dvb_dmx_release(&dec->demux);
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001479 dvb_unregister_adapter(&dec->adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001480
1481 return result;
1482 }
1483
1484 dec->frontend.source = DMX_FRONTEND_0;
1485
1486 if ((result = dec->demux.dmx.add_frontend(&dec->demux.dmx,
1487 &dec->frontend)) < 0) {
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001488 printk("%s: dvb_dmx_init failed: error %d\n", __func__,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001489 result);
1490
1491 dvb_dmxdev_release(&dec->dmxdev);
1492 dvb_dmx_release(&dec->demux);
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001493 dvb_unregister_adapter(&dec->adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001494
1495 return result;
1496 }
1497
1498 if ((result = dec->demux.dmx.connect_frontend(&dec->demux.dmx,
1499 &dec->frontend)) < 0) {
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001500 printk("%s: dvb_dmx_init failed: error %d\n", __func__,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001501 result);
1502
1503 dec->demux.dmx.remove_frontend(&dec->demux.dmx, &dec->frontend);
1504 dvb_dmxdev_release(&dec->dmxdev);
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
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001511 dvb_net_init(&dec->adapter, &dec->dvb_net, &dec->demux.dmx);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001512
1513 return 0;
1514}
1515
1516static void ttusb_dec_exit_dvb(struct ttusb_dec *dec)
1517{
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001518 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001519
1520 dvb_net_release(&dec->dvb_net);
1521 dec->demux.dmx.close(&dec->demux.dmx);
1522 dec->demux.dmx.remove_frontend(&dec->demux.dmx, &dec->frontend);
1523 dvb_dmxdev_release(&dec->dmxdev);
1524 dvb_dmx_release(&dec->demux);
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001525 if (dec->fe) {
1526 dvb_unregister_frontend(dec->fe);
1527 if (dec->fe->ops.release)
1528 dec->fe->ops.release(dec->fe);
1529 }
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001530 dvb_unregister_adapter(&dec->adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001531}
1532
1533static void ttusb_dec_exit_rc(struct ttusb_dec *dec)
1534{
1535
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001536 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001537 /* we have to check whether the irq URB is already submitted.
1538 * As the irq is submitted after the interface is changed,
1539 * this is the best method i figured out.
1540 * Any others?*/
Dmitry Torokhovb7df3912005-09-15 02:01:53 -05001541 if (dec->interface == TTUSB_DEC_INTERFACE_IN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001542 usb_kill_urb(dec->irq_urb);
1543
1544 usb_free_urb(dec->irq_urb);
1545
1546 usb_buffer_free(dec->udev,IRQ_PACKET_SIZE,
Mauro Carvalho Chehab9101e622005-12-12 00:37:24 -08001547 dec->irq_buffer, dec->irq_dma_handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001548
Dmitry Torokhovb7df3912005-09-15 02:01:53 -05001549 if (dec->rc_input_dev) {
1550 input_unregister_device(dec->rc_input_dev);
1551 dec->rc_input_dev = NULL;
1552 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001553}
1554
1555
1556static void ttusb_dec_exit_usb(struct ttusb_dec *dec)
1557{
1558 int i;
1559
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001560 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001561
1562 dec->iso_stream_count = 0;
1563
1564 for (i = 0; i < ISO_BUF_COUNT; i++)
1565 usb_kill_urb(dec->iso_urb[i]);
1566
1567 ttusb_dec_free_iso_urbs(dec);
1568}
1569
1570static void ttusb_dec_exit_tasklet(struct ttusb_dec *dec)
1571{
1572 struct list_head *item;
1573 struct urb_frame *frame;
1574
1575 tasklet_kill(&dec->urb_tasklet);
1576
1577 while ((item = dec->urb_frame_list.next) != &dec->urb_frame_list) {
1578 frame = list_entry(item, struct urb_frame, urb_frame_list);
1579 list_del(&frame->urb_frame_list);
1580 kfree(frame);
1581 }
1582}
1583
1584static void ttusb_dec_init_filters(struct ttusb_dec *dec)
1585{
1586 INIT_LIST_HEAD(&dec->filter_info_list);
1587 spin_lock_init(&dec->filter_info_list_lock);
1588}
1589
1590static void ttusb_dec_exit_filters(struct ttusb_dec *dec)
1591{
1592 struct list_head *item;
1593 struct filter_info *finfo;
1594
1595 while ((item = dec->filter_info_list.next) != &dec->filter_info_list) {
1596 finfo = list_entry(item, struct filter_info, filter_info_list);
1597 list_del(&finfo->filter_info_list);
1598 kfree(finfo);
1599 }
1600}
1601
Johannes Stezenbachd91b7302005-05-16 21:54:38 -07001602static int fe_send_command(struct dvb_frontend* fe, const u8 command,
1603 int param_length, const u8 params[],
1604 int *result_length, u8 cmd_result[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07001605{
Alex Woodsf961e712006-01-09 15:25:24 -02001606 struct ttusb_dec* dec = fe->dvb->priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001607 return ttusb_dec_send_command(dec, command, param_length, params, result_length, cmd_result);
1608}
1609
Johannes Stezenbachd91b7302005-05-16 21:54:38 -07001610static struct ttusbdecfe_config fe_config = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001611 .send_command = fe_send_command
1612};
1613
1614static int ttusb_dec_probe(struct usb_interface *intf,
1615 const struct usb_device_id *id)
1616{
1617 struct usb_device *udev;
1618 struct ttusb_dec *dec;
1619
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001620 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001621
1622 udev = interface_to_usbdev(intf);
1623
Panagiotis Issaris74081872006-01-11 19:40:56 -02001624 if (!(dec = kzalloc(sizeof(struct ttusb_dec), GFP_KERNEL))) {
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001625 printk("%s: couldn't allocate memory.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001626 return -ENOMEM;
1627 }
1628
1629 usb_set_intfdata(intf, (void *)dec);
1630
Al Virod4f979a2008-05-21 00:31:31 -03001631 switch (id->idProduct) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001632 case 0x1006:
1633 ttusb_dec_set_model(dec, TTUSB_DEC3000S);
1634 break;
1635
1636 case 0x1008:
1637 ttusb_dec_set_model(dec, TTUSB_DEC2000T);
1638 break;
1639
1640 case 0x1009:
1641 ttusb_dec_set_model(dec, TTUSB_DEC2540T);
1642 break;
1643 }
1644
1645 dec->udev = udev;
1646
1647 if (ttusb_dec_init_usb(dec))
1648 return 0;
1649 if (ttusb_dec_init_stb(dec)) {
1650 ttusb_dec_exit_usb(dec);
1651 return 0;
1652 }
1653 ttusb_dec_init_dvb(dec);
1654
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001655 dec->adapter.priv = dec;
Al Virod4f979a2008-05-21 00:31:31 -03001656 switch (id->idProduct) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001657 case 0x1006:
1658 dec->fe = ttusbdecfe_dvbs_attach(&fe_config);
1659 break;
1660
1661 case 0x1008:
1662 case 0x1009:
1663 dec->fe = ttusbdecfe_dvbt_attach(&fe_config);
1664 break;
1665 }
1666
1667 if (dec->fe == NULL) {
1668 printk("dvb-ttusb-dec: A frontend driver was not found for device %04x/%04x\n",
1669 le16_to_cpu(dec->udev->descriptor.idVendor),
1670 le16_to_cpu(dec->udev->descriptor.idProduct));
1671 } else {
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001672 if (dvb_register_frontend(&dec->adapter, dec->fe)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001673 printk("budget-ci: Frontend registration failed!\n");
Patrick Boettcherdea74862006-05-14 05:01:31 -03001674 if (dec->fe->ops.release)
1675 dec->fe->ops.release(dec->fe);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001676 dec->fe = NULL;
1677 }
1678 }
1679
1680 ttusb_dec_init_v_pes(dec);
1681 ttusb_dec_init_filters(dec);
1682 ttusb_dec_init_tasklet(dec);
1683
1684 dec->active = 1;
1685
1686 ttusb_dec_set_interface(dec, TTUSB_DEC_INTERFACE_IN);
1687
Dmitry Torokhovb7df3912005-09-15 02:01:53 -05001688 if (enable_rc)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001689 ttusb_init_rc(dec);
1690
1691 return 0;
1692}
1693
1694static void ttusb_dec_disconnect(struct usb_interface *intf)
1695{
1696 struct ttusb_dec *dec = usb_get_intfdata(intf);
1697
1698 usb_set_intfdata(intf, NULL);
1699
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001700 dprintk("%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001701
1702 if (dec->active) {
1703 ttusb_dec_exit_tasklet(dec);
1704 ttusb_dec_exit_filters(dec);
1705 if(enable_rc)
1706 ttusb_dec_exit_rc(dec);
1707 ttusb_dec_exit_usb(dec);
1708 ttusb_dec_exit_dvb(dec);
1709 }
1710
1711 kfree(dec);
1712}
1713
1714static void ttusb_dec_set_model(struct ttusb_dec *dec,
1715 enum ttusb_dec_model model)
1716{
1717 dec->model = model;
1718
1719 switch (model) {
1720 case TTUSB_DEC2000T:
1721 dec->model_name = "DEC2000-t";
1722 dec->firmware_name = "dvb-ttusb-dec-2000t.fw";
1723 break;
1724
1725 case TTUSB_DEC2540T:
1726 dec->model_name = "DEC2540-t";
1727 dec->firmware_name = "dvb-ttusb-dec-2540t.fw";
1728 break;
1729
1730 case TTUSB_DEC3000S:
1731 dec->model_name = "DEC3000-s";
1732 dec->firmware_name = "dvb-ttusb-dec-3000s.fw";
1733 break;
1734 }
1735}
1736
1737static struct usb_device_id ttusb_dec_table[] = {
1738 {USB_DEVICE(0x0b48, 0x1006)}, /* DEC3000-s */
1739 /*{USB_DEVICE(0x0b48, 0x1007)}, Unconfirmed */
1740 {USB_DEVICE(0x0b48, 0x1008)}, /* DEC2000-t */
1741 {USB_DEVICE(0x0b48, 0x1009)}, /* DEC2540-t */
1742 {}
1743};
1744
1745static struct usb_driver ttusb_dec_driver = {
1746 .name = "ttusb-dec",
1747 .probe = ttusb_dec_probe,
1748 .disconnect = ttusb_dec_disconnect,
1749 .id_table = ttusb_dec_table,
1750};
1751
1752static int __init ttusb_dec_init(void)
1753{
1754 int result;
1755
1756 if ((result = usb_register(&ttusb_dec_driver)) < 0) {
Harvey Harrisone9815ce2008-04-08 23:20:00 -03001757 printk("%s: initialisation failed: error %d.\n", __func__,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001758 result);
1759 return result;
1760 }
1761
1762 return 0;
1763}
1764
1765static void __exit ttusb_dec_exit(void)
1766{
1767 usb_deregister(&ttusb_dec_driver);
1768}
1769
1770module_init(ttusb_dec_init);
1771module_exit(ttusb_dec_exit);
1772
1773MODULE_AUTHOR("Alex Woods <linux-dvb@giblets.org>");
1774MODULE_DESCRIPTION(DRIVER_NAME);
1775MODULE_LICENSE("GPL");
1776MODULE_DEVICE_TABLE(usb, ttusb_dec_table);