xref: /OK3568_Linux_fs/kernel/drivers/media/usb/ttusb-dec/ttusb_dec.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * TTUSB DEC Driver
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (C) 2003-2004 Alex Woods <linux-dvb@giblets.org>
6*4882a593Smuzhiyun  * IR support by Peter Beutner <p.beutner@gmx.net>
7*4882a593Smuzhiyun  */
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun #include <linux/list.h>
10*4882a593Smuzhiyun #include <linux/module.h>
11*4882a593Smuzhiyun #include <linux/pci.h>
12*4882a593Smuzhiyun #include <linux/slab.h>
13*4882a593Smuzhiyun #include <linux/spinlock.h>
14*4882a593Smuzhiyun #include <linux/usb.h>
15*4882a593Smuzhiyun #include <linux/interrupt.h>
16*4882a593Smuzhiyun #include <linux/firmware.h>
17*4882a593Smuzhiyun #include <linux/crc32.h>
18*4882a593Smuzhiyun #include <linux/init.h>
19*4882a593Smuzhiyun #include <linux/input.h>
20*4882a593Smuzhiyun 
21*4882a593Smuzhiyun #include <linux/mutex.h>
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun #include <media/dmxdev.h>
24*4882a593Smuzhiyun #include <media/dvb_demux.h>
25*4882a593Smuzhiyun #include <media/dvb_frontend.h>
26*4882a593Smuzhiyun #include <media/dvb_net.h>
27*4882a593Smuzhiyun #include "ttusbdecfe.h"
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun static int debug;
30*4882a593Smuzhiyun static int output_pva;
31*4882a593Smuzhiyun static int enable_rc;
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun module_param(debug, int, 0644);
34*4882a593Smuzhiyun MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
35*4882a593Smuzhiyun module_param(output_pva, int, 0444);
36*4882a593Smuzhiyun MODULE_PARM_DESC(output_pva, "Output PVA from dvr device (default:off)");
37*4882a593Smuzhiyun module_param(enable_rc, int, 0644);
38*4882a593Smuzhiyun MODULE_PARM_DESC(enable_rc, "Turn on/off IR remote control(default: off)");
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun #define dprintk	if (debug) printk
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun #define DRIVER_NAME		"TechnoTrend/Hauppauge DEC USB"
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun #define COMMAND_PIPE		0x03
47*4882a593Smuzhiyun #define RESULT_PIPE		0x04
48*4882a593Smuzhiyun #define IN_PIPE			0x08
49*4882a593Smuzhiyun #define OUT_PIPE		0x07
50*4882a593Smuzhiyun #define IRQ_PIPE		0x0A
51*4882a593Smuzhiyun 
52*4882a593Smuzhiyun #define COMMAND_PACKET_SIZE	0x3c
53*4882a593Smuzhiyun #define ARM_PACKET_SIZE		0x1000
54*4882a593Smuzhiyun #define IRQ_PACKET_SIZE		0x8
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun #define ISO_BUF_COUNT		0x04
57*4882a593Smuzhiyun #define FRAMES_PER_ISO_BUF	0x04
58*4882a593Smuzhiyun #define ISO_FRAME_SIZE		0x0380
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun #define	MAX_PVA_LENGTH		6144
61*4882a593Smuzhiyun 
62*4882a593Smuzhiyun enum ttusb_dec_model {
63*4882a593Smuzhiyun 	TTUSB_DEC2000T,
64*4882a593Smuzhiyun 	TTUSB_DEC2540T,
65*4882a593Smuzhiyun 	TTUSB_DEC3000S
66*4882a593Smuzhiyun };
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun enum ttusb_dec_packet_type {
69*4882a593Smuzhiyun 	TTUSB_DEC_PACKET_PVA,
70*4882a593Smuzhiyun 	TTUSB_DEC_PACKET_SECTION,
71*4882a593Smuzhiyun 	TTUSB_DEC_PACKET_EMPTY
72*4882a593Smuzhiyun };
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun enum ttusb_dec_interface {
75*4882a593Smuzhiyun 	TTUSB_DEC_INTERFACE_INITIAL,
76*4882a593Smuzhiyun 	TTUSB_DEC_INTERFACE_IN,
77*4882a593Smuzhiyun 	TTUSB_DEC_INTERFACE_OUT
78*4882a593Smuzhiyun };
79*4882a593Smuzhiyun 
80*4882a593Smuzhiyun typedef int (dvb_filter_pes2ts_cb_t) (void *, unsigned char *);
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun struct dvb_filter_pes2ts {
83*4882a593Smuzhiyun 	unsigned char buf[188];
84*4882a593Smuzhiyun 	unsigned char cc;
85*4882a593Smuzhiyun 	dvb_filter_pes2ts_cb_t *cb;
86*4882a593Smuzhiyun 	void *priv;
87*4882a593Smuzhiyun };
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun struct ttusb_dec {
90*4882a593Smuzhiyun 	enum ttusb_dec_model		model;
91*4882a593Smuzhiyun 	char				*model_name;
92*4882a593Smuzhiyun 	char				*firmware_name;
93*4882a593Smuzhiyun 	int				can_playback;
94*4882a593Smuzhiyun 
95*4882a593Smuzhiyun 	/* DVB bits */
96*4882a593Smuzhiyun 	struct dvb_adapter		adapter;
97*4882a593Smuzhiyun 	struct dmxdev			dmxdev;
98*4882a593Smuzhiyun 	struct dvb_demux		demux;
99*4882a593Smuzhiyun 	struct dmx_frontend		frontend;
100*4882a593Smuzhiyun 	struct dvb_net			dvb_net;
101*4882a593Smuzhiyun 	struct dvb_frontend*		fe;
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun 	u16			pid[DMX_PES_OTHER];
104*4882a593Smuzhiyun 
105*4882a593Smuzhiyun 	/* USB bits */
106*4882a593Smuzhiyun 	struct usb_device		*udev;
107*4882a593Smuzhiyun 	u8				trans_count;
108*4882a593Smuzhiyun 	unsigned int			command_pipe;
109*4882a593Smuzhiyun 	unsigned int			result_pipe;
110*4882a593Smuzhiyun 	unsigned int			in_pipe;
111*4882a593Smuzhiyun 	unsigned int			out_pipe;
112*4882a593Smuzhiyun 	unsigned int			irq_pipe;
113*4882a593Smuzhiyun 	enum ttusb_dec_interface	interface;
114*4882a593Smuzhiyun 	struct mutex			usb_mutex;
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun 	void			*irq_buffer;
117*4882a593Smuzhiyun 	struct urb		*irq_urb;
118*4882a593Smuzhiyun 	dma_addr_t		irq_dma_handle;
119*4882a593Smuzhiyun 	void			*iso_buffer;
120*4882a593Smuzhiyun 	struct urb		*iso_urb[ISO_BUF_COUNT];
121*4882a593Smuzhiyun 	int			iso_stream_count;
122*4882a593Smuzhiyun 	struct mutex		iso_mutex;
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun 	u8				packet[MAX_PVA_LENGTH + 4];
125*4882a593Smuzhiyun 	enum ttusb_dec_packet_type	packet_type;
126*4882a593Smuzhiyun 	int				packet_state;
127*4882a593Smuzhiyun 	int				packet_length;
128*4882a593Smuzhiyun 	int				packet_payload_length;
129*4882a593Smuzhiyun 	u16				next_packet_id;
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun 	int				pva_stream_count;
132*4882a593Smuzhiyun 	int				filter_stream_count;
133*4882a593Smuzhiyun 
134*4882a593Smuzhiyun 	struct dvb_filter_pes2ts	a_pes2ts;
135*4882a593Smuzhiyun 	struct dvb_filter_pes2ts	v_pes2ts;
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun 	u8			v_pes[16 + MAX_PVA_LENGTH];
138*4882a593Smuzhiyun 	int			v_pes_length;
139*4882a593Smuzhiyun 	int			v_pes_postbytes;
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun 	struct list_head	urb_frame_list;
142*4882a593Smuzhiyun 	struct tasklet_struct	urb_tasklet;
143*4882a593Smuzhiyun 	spinlock_t		urb_frame_list_lock;
144*4882a593Smuzhiyun 
145*4882a593Smuzhiyun 	struct dvb_demux_filter	*audio_filter;
146*4882a593Smuzhiyun 	struct dvb_demux_filter	*video_filter;
147*4882a593Smuzhiyun 	struct list_head	filter_info_list;
148*4882a593Smuzhiyun 	spinlock_t		filter_info_list_lock;
149*4882a593Smuzhiyun 
150*4882a593Smuzhiyun 	struct input_dev	*rc_input_dev;
151*4882a593Smuzhiyun 	char			rc_phys[64];
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun 	int			active; /* Loaded successfully */
154*4882a593Smuzhiyun };
155*4882a593Smuzhiyun 
156*4882a593Smuzhiyun struct urb_frame {
157*4882a593Smuzhiyun 	u8			data[ISO_FRAME_SIZE];
158*4882a593Smuzhiyun 	int			length;
159*4882a593Smuzhiyun 	struct list_head	urb_frame_list;
160*4882a593Smuzhiyun };
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun struct filter_info {
163*4882a593Smuzhiyun 	u8			stream_id;
164*4882a593Smuzhiyun 	struct dvb_demux_filter	*filter;
165*4882a593Smuzhiyun 	struct list_head	filter_info_list;
166*4882a593Smuzhiyun };
167*4882a593Smuzhiyun 
168*4882a593Smuzhiyun static u16 rc_keys[] = {
169*4882a593Smuzhiyun 	KEY_POWER,
170*4882a593Smuzhiyun 	KEY_MUTE,
171*4882a593Smuzhiyun 	KEY_1,
172*4882a593Smuzhiyun 	KEY_2,
173*4882a593Smuzhiyun 	KEY_3,
174*4882a593Smuzhiyun 	KEY_4,
175*4882a593Smuzhiyun 	KEY_5,
176*4882a593Smuzhiyun 	KEY_6,
177*4882a593Smuzhiyun 	KEY_7,
178*4882a593Smuzhiyun 	KEY_8,
179*4882a593Smuzhiyun 	KEY_9,
180*4882a593Smuzhiyun 	KEY_0,
181*4882a593Smuzhiyun 	KEY_CHANNELUP,
182*4882a593Smuzhiyun 	KEY_VOLUMEDOWN,
183*4882a593Smuzhiyun 	KEY_OK,
184*4882a593Smuzhiyun 	KEY_VOLUMEUP,
185*4882a593Smuzhiyun 	KEY_CHANNELDOWN,
186*4882a593Smuzhiyun 	KEY_PREVIOUS,
187*4882a593Smuzhiyun 	KEY_ESC,
188*4882a593Smuzhiyun 	KEY_RED,
189*4882a593Smuzhiyun 	KEY_GREEN,
190*4882a593Smuzhiyun 	KEY_YELLOW,
191*4882a593Smuzhiyun 	KEY_BLUE,
192*4882a593Smuzhiyun 	KEY_OPTION,
193*4882a593Smuzhiyun 	KEY_M,
194*4882a593Smuzhiyun 	KEY_RADIO
195*4882a593Smuzhiyun };
196*4882a593Smuzhiyun 
dvb_filter_pes2ts_init(struct dvb_filter_pes2ts * p2ts,unsigned short pid,dvb_filter_pes2ts_cb_t * cb,void * priv)197*4882a593Smuzhiyun static void dvb_filter_pes2ts_init(struct dvb_filter_pes2ts *p2ts,
198*4882a593Smuzhiyun 				   unsigned short pid,
199*4882a593Smuzhiyun 				   dvb_filter_pes2ts_cb_t *cb, void *priv)
200*4882a593Smuzhiyun {
201*4882a593Smuzhiyun 	unsigned char *buf=p2ts->buf;
202*4882a593Smuzhiyun 
203*4882a593Smuzhiyun 	buf[0]=0x47;
204*4882a593Smuzhiyun 	buf[1]=(pid>>8);
205*4882a593Smuzhiyun 	buf[2]=pid&0xff;
206*4882a593Smuzhiyun 	p2ts->cc=0;
207*4882a593Smuzhiyun 	p2ts->cb=cb;
208*4882a593Smuzhiyun 	p2ts->priv=priv;
209*4882a593Smuzhiyun }
210*4882a593Smuzhiyun 
dvb_filter_pes2ts(struct dvb_filter_pes2ts * p2ts,unsigned char * pes,int len,int payload_start)211*4882a593Smuzhiyun static int dvb_filter_pes2ts(struct dvb_filter_pes2ts *p2ts,
212*4882a593Smuzhiyun 			     unsigned char *pes, int len, int payload_start)
213*4882a593Smuzhiyun {
214*4882a593Smuzhiyun 	unsigned char *buf=p2ts->buf;
215*4882a593Smuzhiyun 	int ret=0, rest;
216*4882a593Smuzhiyun 
217*4882a593Smuzhiyun 	//len=6+((pes[4]<<8)|pes[5]);
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun 	if (payload_start)
220*4882a593Smuzhiyun 		buf[1]|=0x40;
221*4882a593Smuzhiyun 	else
222*4882a593Smuzhiyun 		buf[1]&=~0x40;
223*4882a593Smuzhiyun 	while (len>=184) {
224*4882a593Smuzhiyun 		buf[3]=0x10|((p2ts->cc++)&0x0f);
225*4882a593Smuzhiyun 		memcpy(buf+4, pes, 184);
226*4882a593Smuzhiyun 		if ((ret=p2ts->cb(p2ts->priv, buf)))
227*4882a593Smuzhiyun 			return ret;
228*4882a593Smuzhiyun 		len-=184; pes+=184;
229*4882a593Smuzhiyun 		buf[1]&=~0x40;
230*4882a593Smuzhiyun 	}
231*4882a593Smuzhiyun 	if (!len)
232*4882a593Smuzhiyun 		return 0;
233*4882a593Smuzhiyun 	buf[3]=0x30|((p2ts->cc++)&0x0f);
234*4882a593Smuzhiyun 	rest=183-len;
235*4882a593Smuzhiyun 	if (rest) {
236*4882a593Smuzhiyun 		buf[5]=0x00;
237*4882a593Smuzhiyun 		if (rest-1)
238*4882a593Smuzhiyun 			memset(buf+6, 0xff, rest-1);
239*4882a593Smuzhiyun 	}
240*4882a593Smuzhiyun 	buf[4]=rest;
241*4882a593Smuzhiyun 	memcpy(buf+5+rest, pes, len);
242*4882a593Smuzhiyun 	return p2ts->cb(p2ts->priv, buf);
243*4882a593Smuzhiyun }
244*4882a593Smuzhiyun 
245*4882a593Smuzhiyun static void ttusb_dec_set_model(struct ttusb_dec *dec,
246*4882a593Smuzhiyun 				enum ttusb_dec_model model);
247*4882a593Smuzhiyun 
ttusb_dec_handle_irq(struct urb * urb)248*4882a593Smuzhiyun static void ttusb_dec_handle_irq( struct urb *urb)
249*4882a593Smuzhiyun {
250*4882a593Smuzhiyun 	struct ttusb_dec *dec = urb->context;
251*4882a593Smuzhiyun 	char *buffer = dec->irq_buffer;
252*4882a593Smuzhiyun 	int retval;
253*4882a593Smuzhiyun 	int index = buffer[4];
254*4882a593Smuzhiyun 
255*4882a593Smuzhiyun 	switch(urb->status) {
256*4882a593Smuzhiyun 		case 0: /*success*/
257*4882a593Smuzhiyun 			break;
258*4882a593Smuzhiyun 		case -ECONNRESET:
259*4882a593Smuzhiyun 		case -ENOENT:
260*4882a593Smuzhiyun 		case -ESHUTDOWN:
261*4882a593Smuzhiyun 		case -ETIME:
262*4882a593Smuzhiyun 			/* this urb is dead, cleanup */
263*4882a593Smuzhiyun 			dprintk("%s:urb shutting down with status: %d\n",
264*4882a593Smuzhiyun 					__func__, urb->status);
265*4882a593Smuzhiyun 			return;
266*4882a593Smuzhiyun 		default:
267*4882a593Smuzhiyun 			dprintk("%s:nonzero status received: %d\n",
268*4882a593Smuzhiyun 					__func__,urb->status);
269*4882a593Smuzhiyun 			goto exit;
270*4882a593Smuzhiyun 	}
271*4882a593Smuzhiyun 
272*4882a593Smuzhiyun 	if ((buffer[0] == 0x1) && (buffer[2] == 0x15))  {
273*4882a593Smuzhiyun 		/*
274*4882a593Smuzhiyun 		 * IR - Event
275*4882a593Smuzhiyun 		 *
276*4882a593Smuzhiyun 		 * this is an fact a bit too simple implementation;
277*4882a593Smuzhiyun 		 * the box also reports a keyrepeat signal
278*4882a593Smuzhiyun 		 * (with buffer[3] == 0x40) in an interval of ~100ms.
279*4882a593Smuzhiyun 		 * But to handle this correctly we had to imlemenent some
280*4882a593Smuzhiyun 		 * kind of timer which signals a 'key up' event if no
281*4882a593Smuzhiyun 		 * keyrepeat signal is received for lets say 200ms.
282*4882a593Smuzhiyun 		 * this should/could be added later ...
283*4882a593Smuzhiyun 		 * for now lets report each signal as a key down and up
284*4882a593Smuzhiyun 		 */
285*4882a593Smuzhiyun 		if (index - 1 < ARRAY_SIZE(rc_keys)) {
286*4882a593Smuzhiyun 			dprintk("%s:rc signal:%d\n", __func__, index);
287*4882a593Smuzhiyun 			input_report_key(dec->rc_input_dev, rc_keys[index - 1], 1);
288*4882a593Smuzhiyun 			input_sync(dec->rc_input_dev);
289*4882a593Smuzhiyun 			input_report_key(dec->rc_input_dev, rc_keys[index - 1], 0);
290*4882a593Smuzhiyun 			input_sync(dec->rc_input_dev);
291*4882a593Smuzhiyun 		}
292*4882a593Smuzhiyun 	}
293*4882a593Smuzhiyun 
294*4882a593Smuzhiyun exit:
295*4882a593Smuzhiyun 	retval = usb_submit_urb(urb, GFP_ATOMIC);
296*4882a593Smuzhiyun 	if (retval)
297*4882a593Smuzhiyun 		printk("%s - usb_commit_urb failed with result: %d\n",
298*4882a593Smuzhiyun 			__func__, retval);
299*4882a593Smuzhiyun }
300*4882a593Smuzhiyun 
crc16(u16 crc,const u8 * buf,size_t len)301*4882a593Smuzhiyun static u16 crc16(u16 crc, const u8 *buf, size_t len)
302*4882a593Smuzhiyun {
303*4882a593Smuzhiyun 	u16 tmp;
304*4882a593Smuzhiyun 
305*4882a593Smuzhiyun 	while (len--) {
306*4882a593Smuzhiyun 		crc ^= *buf++;
307*4882a593Smuzhiyun 		crc ^= (u8)crc >> 4;
308*4882a593Smuzhiyun 		tmp = (u8)crc;
309*4882a593Smuzhiyun 		crc ^= (tmp ^ (tmp << 1)) << 4;
310*4882a593Smuzhiyun 	}
311*4882a593Smuzhiyun 	return crc;
312*4882a593Smuzhiyun }
313*4882a593Smuzhiyun 
ttusb_dec_send_command(struct ttusb_dec * dec,const u8 command,int param_length,const u8 params[],int * result_length,u8 cmd_result[])314*4882a593Smuzhiyun static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command,
315*4882a593Smuzhiyun 				  int param_length, const u8 params[],
316*4882a593Smuzhiyun 				  int *result_length, u8 cmd_result[])
317*4882a593Smuzhiyun {
318*4882a593Smuzhiyun 	int result, actual_len;
319*4882a593Smuzhiyun 	u8 *b;
320*4882a593Smuzhiyun 
321*4882a593Smuzhiyun 	dprintk("%s\n", __func__);
322*4882a593Smuzhiyun 
323*4882a593Smuzhiyun 	b = kzalloc(COMMAND_PACKET_SIZE + 4, GFP_KERNEL);
324*4882a593Smuzhiyun 	if (!b)
325*4882a593Smuzhiyun 		return -ENOMEM;
326*4882a593Smuzhiyun 
327*4882a593Smuzhiyun 	if ((result = mutex_lock_interruptible(&dec->usb_mutex))) {
328*4882a593Smuzhiyun 		kfree(b);
329*4882a593Smuzhiyun 		printk("%s: Failed to lock usb mutex.\n", __func__);
330*4882a593Smuzhiyun 		return result;
331*4882a593Smuzhiyun 	}
332*4882a593Smuzhiyun 
333*4882a593Smuzhiyun 	b[0] = 0xaa;
334*4882a593Smuzhiyun 	b[1] = ++dec->trans_count;
335*4882a593Smuzhiyun 	b[2] = command;
336*4882a593Smuzhiyun 	b[3] = param_length;
337*4882a593Smuzhiyun 
338*4882a593Smuzhiyun 	if (params)
339*4882a593Smuzhiyun 		memcpy(&b[4], params, param_length);
340*4882a593Smuzhiyun 
341*4882a593Smuzhiyun 	if (debug) {
342*4882a593Smuzhiyun 		printk(KERN_DEBUG "%s: command: %*ph\n",
343*4882a593Smuzhiyun 		       __func__, param_length, b);
344*4882a593Smuzhiyun 	}
345*4882a593Smuzhiyun 
346*4882a593Smuzhiyun 	result = usb_bulk_msg(dec->udev, dec->command_pipe, b,
347*4882a593Smuzhiyun 			      COMMAND_PACKET_SIZE + 4, &actual_len, 1000);
348*4882a593Smuzhiyun 
349*4882a593Smuzhiyun 	if (result) {
350*4882a593Smuzhiyun 		printk("%s: command bulk message failed: error %d\n",
351*4882a593Smuzhiyun 		       __func__, result);
352*4882a593Smuzhiyun 		mutex_unlock(&dec->usb_mutex);
353*4882a593Smuzhiyun 		kfree(b);
354*4882a593Smuzhiyun 		return result;
355*4882a593Smuzhiyun 	}
356*4882a593Smuzhiyun 
357*4882a593Smuzhiyun 	result = usb_bulk_msg(dec->udev, dec->result_pipe, b,
358*4882a593Smuzhiyun 			      COMMAND_PACKET_SIZE + 4, &actual_len, 1000);
359*4882a593Smuzhiyun 
360*4882a593Smuzhiyun 	if (result) {
361*4882a593Smuzhiyun 		printk("%s: result bulk message failed: error %d\n",
362*4882a593Smuzhiyun 		       __func__, result);
363*4882a593Smuzhiyun 		mutex_unlock(&dec->usb_mutex);
364*4882a593Smuzhiyun 		kfree(b);
365*4882a593Smuzhiyun 		return result;
366*4882a593Smuzhiyun 	} else {
367*4882a593Smuzhiyun 		if (debug) {
368*4882a593Smuzhiyun 			printk(KERN_DEBUG "%s: result: %*ph\n",
369*4882a593Smuzhiyun 			       __func__, actual_len, b);
370*4882a593Smuzhiyun 		}
371*4882a593Smuzhiyun 
372*4882a593Smuzhiyun 		if (result_length)
373*4882a593Smuzhiyun 			*result_length = b[3];
374*4882a593Smuzhiyun 		if (cmd_result && b[3] > 0)
375*4882a593Smuzhiyun 			memcpy(cmd_result, &b[4], b[3]);
376*4882a593Smuzhiyun 
377*4882a593Smuzhiyun 		mutex_unlock(&dec->usb_mutex);
378*4882a593Smuzhiyun 
379*4882a593Smuzhiyun 		kfree(b);
380*4882a593Smuzhiyun 		return 0;
381*4882a593Smuzhiyun 	}
382*4882a593Smuzhiyun }
383*4882a593Smuzhiyun 
ttusb_dec_get_stb_state(struct ttusb_dec * dec,unsigned int * mode,unsigned int * model,unsigned int * version)384*4882a593Smuzhiyun static int ttusb_dec_get_stb_state (struct ttusb_dec *dec, unsigned int *mode,
385*4882a593Smuzhiyun 				    unsigned int *model, unsigned int *version)
386*4882a593Smuzhiyun {
387*4882a593Smuzhiyun 	u8 c[COMMAND_PACKET_SIZE];
388*4882a593Smuzhiyun 	int c_length;
389*4882a593Smuzhiyun 	int result;
390*4882a593Smuzhiyun 	__be32 tmp;
391*4882a593Smuzhiyun 
392*4882a593Smuzhiyun 	dprintk("%s\n", __func__);
393*4882a593Smuzhiyun 
394*4882a593Smuzhiyun 	result = ttusb_dec_send_command(dec, 0x08, 0, NULL, &c_length, c);
395*4882a593Smuzhiyun 	if (result)
396*4882a593Smuzhiyun 		return result;
397*4882a593Smuzhiyun 
398*4882a593Smuzhiyun 	if (c_length >= 0x0c) {
399*4882a593Smuzhiyun 		if (mode != NULL) {
400*4882a593Smuzhiyun 			memcpy(&tmp, c, 4);
401*4882a593Smuzhiyun 			*mode = ntohl(tmp);
402*4882a593Smuzhiyun 		}
403*4882a593Smuzhiyun 		if (model != NULL) {
404*4882a593Smuzhiyun 			memcpy(&tmp, &c[4], 4);
405*4882a593Smuzhiyun 			*model = ntohl(tmp);
406*4882a593Smuzhiyun 		}
407*4882a593Smuzhiyun 		if (version != NULL) {
408*4882a593Smuzhiyun 			memcpy(&tmp, &c[8], 4);
409*4882a593Smuzhiyun 			*version = ntohl(tmp);
410*4882a593Smuzhiyun 		}
411*4882a593Smuzhiyun 		return 0;
412*4882a593Smuzhiyun 	} else {
413*4882a593Smuzhiyun 		return -ENOENT;
414*4882a593Smuzhiyun 	}
415*4882a593Smuzhiyun }
416*4882a593Smuzhiyun 
ttusb_dec_audio_pes2ts_cb(void * priv,unsigned char * data)417*4882a593Smuzhiyun static int ttusb_dec_audio_pes2ts_cb(void *priv, unsigned char *data)
418*4882a593Smuzhiyun {
419*4882a593Smuzhiyun 	struct ttusb_dec *dec = priv;
420*4882a593Smuzhiyun 
421*4882a593Smuzhiyun 	dec->audio_filter->feed->cb.ts(data, 188, NULL, 0,
422*4882a593Smuzhiyun 				       &dec->audio_filter->feed->feed.ts, NULL);
423*4882a593Smuzhiyun 
424*4882a593Smuzhiyun 	return 0;
425*4882a593Smuzhiyun }
426*4882a593Smuzhiyun 
ttusb_dec_video_pes2ts_cb(void * priv,unsigned char * data)427*4882a593Smuzhiyun static int ttusb_dec_video_pes2ts_cb(void *priv, unsigned char *data)
428*4882a593Smuzhiyun {
429*4882a593Smuzhiyun 	struct ttusb_dec *dec = priv;
430*4882a593Smuzhiyun 
431*4882a593Smuzhiyun 	dec->video_filter->feed->cb.ts(data, 188, NULL, 0,
432*4882a593Smuzhiyun 				       &dec->video_filter->feed->feed.ts, NULL);
433*4882a593Smuzhiyun 
434*4882a593Smuzhiyun 	return 0;
435*4882a593Smuzhiyun }
436*4882a593Smuzhiyun 
ttusb_dec_set_pids(struct ttusb_dec * dec)437*4882a593Smuzhiyun static void ttusb_dec_set_pids(struct ttusb_dec *dec)
438*4882a593Smuzhiyun {
439*4882a593Smuzhiyun 	u8 b[] = { 0x00, 0x00, 0x00, 0x00,
440*4882a593Smuzhiyun 		   0x00, 0x00, 0xff, 0xff,
441*4882a593Smuzhiyun 		   0xff, 0xff, 0xff, 0xff };
442*4882a593Smuzhiyun 
443*4882a593Smuzhiyun 	__be16 pcr = htons(dec->pid[DMX_PES_PCR]);
444*4882a593Smuzhiyun 	__be16 audio = htons(dec->pid[DMX_PES_AUDIO]);
445*4882a593Smuzhiyun 	__be16 video = htons(dec->pid[DMX_PES_VIDEO]);
446*4882a593Smuzhiyun 
447*4882a593Smuzhiyun 	dprintk("%s\n", __func__);
448*4882a593Smuzhiyun 
449*4882a593Smuzhiyun 	memcpy(&b[0], &pcr, 2);
450*4882a593Smuzhiyun 	memcpy(&b[2], &audio, 2);
451*4882a593Smuzhiyun 	memcpy(&b[4], &video, 2);
452*4882a593Smuzhiyun 
453*4882a593Smuzhiyun 	ttusb_dec_send_command(dec, 0x50, sizeof(b), b, NULL, NULL);
454*4882a593Smuzhiyun 
455*4882a593Smuzhiyun 	dvb_filter_pes2ts_init(&dec->a_pes2ts, dec->pid[DMX_PES_AUDIO],
456*4882a593Smuzhiyun 			       ttusb_dec_audio_pes2ts_cb, dec);
457*4882a593Smuzhiyun 	dvb_filter_pes2ts_init(&dec->v_pes2ts, dec->pid[DMX_PES_VIDEO],
458*4882a593Smuzhiyun 			       ttusb_dec_video_pes2ts_cb, dec);
459*4882a593Smuzhiyun 	dec->v_pes_length = 0;
460*4882a593Smuzhiyun 	dec->v_pes_postbytes = 0;
461*4882a593Smuzhiyun }
462*4882a593Smuzhiyun 
ttusb_dec_process_pva(struct ttusb_dec * dec,u8 * pva,int length)463*4882a593Smuzhiyun static void ttusb_dec_process_pva(struct ttusb_dec *dec, u8 *pva, int length)
464*4882a593Smuzhiyun {
465*4882a593Smuzhiyun 	if (length < 8) {
466*4882a593Smuzhiyun 		printk("%s: packet too short - discarding\n", __func__);
467*4882a593Smuzhiyun 		return;
468*4882a593Smuzhiyun 	}
469*4882a593Smuzhiyun 
470*4882a593Smuzhiyun 	if (length > 8 + MAX_PVA_LENGTH) {
471*4882a593Smuzhiyun 		printk("%s: packet too long - discarding\n", __func__);
472*4882a593Smuzhiyun 		return;
473*4882a593Smuzhiyun 	}
474*4882a593Smuzhiyun 
475*4882a593Smuzhiyun 	switch (pva[2]) {
476*4882a593Smuzhiyun 
477*4882a593Smuzhiyun 	case 0x01: {		/* VideoStream */
478*4882a593Smuzhiyun 		int prebytes = pva[5] & 0x03;
479*4882a593Smuzhiyun 		int postbytes = (pva[5] & 0x0c) >> 2;
480*4882a593Smuzhiyun 		__be16 v_pes_payload_length;
481*4882a593Smuzhiyun 
482*4882a593Smuzhiyun 		if (output_pva) {
483*4882a593Smuzhiyun 			dec->video_filter->feed->cb.ts(pva, length, NULL, 0,
484*4882a593Smuzhiyun 				&dec->video_filter->feed->feed.ts, NULL);
485*4882a593Smuzhiyun 			return;
486*4882a593Smuzhiyun 		}
487*4882a593Smuzhiyun 
488*4882a593Smuzhiyun 		if (dec->v_pes_postbytes > 0 &&
489*4882a593Smuzhiyun 		    dec->v_pes_postbytes == prebytes) {
490*4882a593Smuzhiyun 			memcpy(&dec->v_pes[dec->v_pes_length],
491*4882a593Smuzhiyun 			       &pva[12], prebytes);
492*4882a593Smuzhiyun 
493*4882a593Smuzhiyun 			dvb_filter_pes2ts(&dec->v_pes2ts, dec->v_pes,
494*4882a593Smuzhiyun 					  dec->v_pes_length + prebytes, 1);
495*4882a593Smuzhiyun 		}
496*4882a593Smuzhiyun 
497*4882a593Smuzhiyun 		if (pva[5] & 0x10) {
498*4882a593Smuzhiyun 			dec->v_pes[7] = 0x80;
499*4882a593Smuzhiyun 			dec->v_pes[8] = 0x05;
500*4882a593Smuzhiyun 
501*4882a593Smuzhiyun 			dec->v_pes[9] = 0x21 | ((pva[8] & 0xc0) >> 5);
502*4882a593Smuzhiyun 			dec->v_pes[10] = ((pva[8] & 0x3f) << 2) |
503*4882a593Smuzhiyun 					 ((pva[9] & 0xc0) >> 6);
504*4882a593Smuzhiyun 			dec->v_pes[11] = 0x01 |
505*4882a593Smuzhiyun 					 ((pva[9] & 0x3f) << 2) |
506*4882a593Smuzhiyun 					 ((pva[10] & 0x80) >> 6);
507*4882a593Smuzhiyun 			dec->v_pes[12] = ((pva[10] & 0x7f) << 1) |
508*4882a593Smuzhiyun 					 ((pva[11] & 0xc0) >> 7);
509*4882a593Smuzhiyun 			dec->v_pes[13] = 0x01 | ((pva[11] & 0x7f) << 1);
510*4882a593Smuzhiyun 
511*4882a593Smuzhiyun 			memcpy(&dec->v_pes[14], &pva[12 + prebytes],
512*4882a593Smuzhiyun 			       length - 12 - prebytes);
513*4882a593Smuzhiyun 			dec->v_pes_length = 14 + length - 12 - prebytes;
514*4882a593Smuzhiyun 		} else {
515*4882a593Smuzhiyun 			dec->v_pes[7] = 0x00;
516*4882a593Smuzhiyun 			dec->v_pes[8] = 0x00;
517*4882a593Smuzhiyun 
518*4882a593Smuzhiyun 			memcpy(&dec->v_pes[9], &pva[8], length - 8);
519*4882a593Smuzhiyun 			dec->v_pes_length = 9 + length - 8;
520*4882a593Smuzhiyun 		}
521*4882a593Smuzhiyun 
522*4882a593Smuzhiyun 		dec->v_pes_postbytes = postbytes;
523*4882a593Smuzhiyun 
524*4882a593Smuzhiyun 		if (dec->v_pes[9 + dec->v_pes[8]] == 0x00 &&
525*4882a593Smuzhiyun 		    dec->v_pes[10 + dec->v_pes[8]] == 0x00 &&
526*4882a593Smuzhiyun 		    dec->v_pes[11 + dec->v_pes[8]] == 0x01)
527*4882a593Smuzhiyun 			dec->v_pes[6] = 0x84;
528*4882a593Smuzhiyun 		else
529*4882a593Smuzhiyun 			dec->v_pes[6] = 0x80;
530*4882a593Smuzhiyun 
531*4882a593Smuzhiyun 		v_pes_payload_length = htons(dec->v_pes_length - 6 +
532*4882a593Smuzhiyun 					     postbytes);
533*4882a593Smuzhiyun 		memcpy(&dec->v_pes[4], &v_pes_payload_length, 2);
534*4882a593Smuzhiyun 
535*4882a593Smuzhiyun 		if (postbytes == 0)
536*4882a593Smuzhiyun 			dvb_filter_pes2ts(&dec->v_pes2ts, dec->v_pes,
537*4882a593Smuzhiyun 					  dec->v_pes_length, 1);
538*4882a593Smuzhiyun 
539*4882a593Smuzhiyun 		break;
540*4882a593Smuzhiyun 	}
541*4882a593Smuzhiyun 
542*4882a593Smuzhiyun 	case 0x02:		/* MainAudioStream */
543*4882a593Smuzhiyun 		if (output_pva) {
544*4882a593Smuzhiyun 			dec->audio_filter->feed->cb.ts(pva, length, NULL, 0,
545*4882a593Smuzhiyun 				&dec->audio_filter->feed->feed.ts, NULL);
546*4882a593Smuzhiyun 			return;
547*4882a593Smuzhiyun 		}
548*4882a593Smuzhiyun 
549*4882a593Smuzhiyun 		dvb_filter_pes2ts(&dec->a_pes2ts, &pva[8], length - 8,
550*4882a593Smuzhiyun 				  pva[5] & 0x10);
551*4882a593Smuzhiyun 		break;
552*4882a593Smuzhiyun 
553*4882a593Smuzhiyun 	default:
554*4882a593Smuzhiyun 		printk("%s: unknown PVA type: %02x.\n", __func__,
555*4882a593Smuzhiyun 		       pva[2]);
556*4882a593Smuzhiyun 		break;
557*4882a593Smuzhiyun 	}
558*4882a593Smuzhiyun }
559*4882a593Smuzhiyun 
ttusb_dec_process_filter(struct ttusb_dec * dec,u8 * packet,int length)560*4882a593Smuzhiyun static void ttusb_dec_process_filter(struct ttusb_dec *dec, u8 *packet,
561*4882a593Smuzhiyun 				     int length)
562*4882a593Smuzhiyun {
563*4882a593Smuzhiyun 	struct list_head *item;
564*4882a593Smuzhiyun 	struct filter_info *finfo;
565*4882a593Smuzhiyun 	struct dvb_demux_filter *filter = NULL;
566*4882a593Smuzhiyun 	unsigned long flags;
567*4882a593Smuzhiyun 	u8 sid;
568*4882a593Smuzhiyun 
569*4882a593Smuzhiyun 	sid = packet[1];
570*4882a593Smuzhiyun 	spin_lock_irqsave(&dec->filter_info_list_lock, flags);
571*4882a593Smuzhiyun 	for (item = dec->filter_info_list.next; item != &dec->filter_info_list;
572*4882a593Smuzhiyun 	     item = item->next) {
573*4882a593Smuzhiyun 		finfo = list_entry(item, struct filter_info, filter_info_list);
574*4882a593Smuzhiyun 		if (finfo->stream_id == sid) {
575*4882a593Smuzhiyun 			filter = finfo->filter;
576*4882a593Smuzhiyun 			break;
577*4882a593Smuzhiyun 		}
578*4882a593Smuzhiyun 	}
579*4882a593Smuzhiyun 	spin_unlock_irqrestore(&dec->filter_info_list_lock, flags);
580*4882a593Smuzhiyun 
581*4882a593Smuzhiyun 	if (filter)
582*4882a593Smuzhiyun 		filter->feed->cb.sec(&packet[2], length - 2, NULL, 0,
583*4882a593Smuzhiyun 				     &filter->filter, NULL);
584*4882a593Smuzhiyun }
585*4882a593Smuzhiyun 
ttusb_dec_process_packet(struct ttusb_dec * dec)586*4882a593Smuzhiyun static void ttusb_dec_process_packet(struct ttusb_dec *dec)
587*4882a593Smuzhiyun {
588*4882a593Smuzhiyun 	int i;
589*4882a593Smuzhiyun 	u16 csum = 0;
590*4882a593Smuzhiyun 	u16 packet_id;
591*4882a593Smuzhiyun 
592*4882a593Smuzhiyun 	if (dec->packet_length % 2) {
593*4882a593Smuzhiyun 		printk("%s: odd sized packet - discarding\n", __func__);
594*4882a593Smuzhiyun 		return;
595*4882a593Smuzhiyun 	}
596*4882a593Smuzhiyun 
597*4882a593Smuzhiyun 	for (i = 0; i < dec->packet_length; i += 2)
598*4882a593Smuzhiyun 		csum ^= ((dec->packet[i] << 8) + dec->packet[i + 1]);
599*4882a593Smuzhiyun 
600*4882a593Smuzhiyun 	if (csum) {
601*4882a593Smuzhiyun 		printk("%s: checksum failed - discarding\n", __func__);
602*4882a593Smuzhiyun 		return;
603*4882a593Smuzhiyun 	}
604*4882a593Smuzhiyun 
605*4882a593Smuzhiyun 	packet_id = dec->packet[dec->packet_length - 4] << 8;
606*4882a593Smuzhiyun 	packet_id += dec->packet[dec->packet_length - 3];
607*4882a593Smuzhiyun 
608*4882a593Smuzhiyun 	if ((packet_id != dec->next_packet_id) && dec->next_packet_id) {
609*4882a593Smuzhiyun 		printk("%s: warning: lost packets between %u and %u\n",
610*4882a593Smuzhiyun 		       __func__, dec->next_packet_id - 1, packet_id);
611*4882a593Smuzhiyun 	}
612*4882a593Smuzhiyun 
613*4882a593Smuzhiyun 	if (packet_id == 0xffff)
614*4882a593Smuzhiyun 		dec->next_packet_id = 0x8000;
615*4882a593Smuzhiyun 	else
616*4882a593Smuzhiyun 		dec->next_packet_id = packet_id + 1;
617*4882a593Smuzhiyun 
618*4882a593Smuzhiyun 	switch (dec->packet_type) {
619*4882a593Smuzhiyun 	case TTUSB_DEC_PACKET_PVA:
620*4882a593Smuzhiyun 		if (dec->pva_stream_count)
621*4882a593Smuzhiyun 			ttusb_dec_process_pva(dec, dec->packet,
622*4882a593Smuzhiyun 					      dec->packet_payload_length);
623*4882a593Smuzhiyun 		break;
624*4882a593Smuzhiyun 
625*4882a593Smuzhiyun 	case TTUSB_DEC_PACKET_SECTION:
626*4882a593Smuzhiyun 		if (dec->filter_stream_count)
627*4882a593Smuzhiyun 			ttusb_dec_process_filter(dec, dec->packet,
628*4882a593Smuzhiyun 						 dec->packet_payload_length);
629*4882a593Smuzhiyun 		break;
630*4882a593Smuzhiyun 
631*4882a593Smuzhiyun 	case TTUSB_DEC_PACKET_EMPTY:
632*4882a593Smuzhiyun 		break;
633*4882a593Smuzhiyun 	}
634*4882a593Smuzhiyun }
635*4882a593Smuzhiyun 
swap_bytes(u8 * b,int length)636*4882a593Smuzhiyun static void swap_bytes(u8 *b, int length)
637*4882a593Smuzhiyun {
638*4882a593Smuzhiyun 	length -= length % 2;
639*4882a593Smuzhiyun 	for (; length; b += 2, length -= 2)
640*4882a593Smuzhiyun 		swap(*b, *(b + 1));
641*4882a593Smuzhiyun }
642*4882a593Smuzhiyun 
ttusb_dec_process_urb_frame(struct ttusb_dec * dec,u8 * b,int length)643*4882a593Smuzhiyun static void ttusb_dec_process_urb_frame(struct ttusb_dec *dec, u8 *b,
644*4882a593Smuzhiyun 					int length)
645*4882a593Smuzhiyun {
646*4882a593Smuzhiyun 	swap_bytes(b, length);
647*4882a593Smuzhiyun 
648*4882a593Smuzhiyun 	while (length) {
649*4882a593Smuzhiyun 		switch (dec->packet_state) {
650*4882a593Smuzhiyun 
651*4882a593Smuzhiyun 		case 0:
652*4882a593Smuzhiyun 		case 1:
653*4882a593Smuzhiyun 		case 2:
654*4882a593Smuzhiyun 			if (*b++ == 0xaa)
655*4882a593Smuzhiyun 				dec->packet_state++;
656*4882a593Smuzhiyun 			else
657*4882a593Smuzhiyun 				dec->packet_state = 0;
658*4882a593Smuzhiyun 
659*4882a593Smuzhiyun 			length--;
660*4882a593Smuzhiyun 			break;
661*4882a593Smuzhiyun 
662*4882a593Smuzhiyun 		case 3:
663*4882a593Smuzhiyun 			if (*b == 0x00) {
664*4882a593Smuzhiyun 				dec->packet_state++;
665*4882a593Smuzhiyun 				dec->packet_length = 0;
666*4882a593Smuzhiyun 			} else if (*b != 0xaa) {
667*4882a593Smuzhiyun 				dec->packet_state = 0;
668*4882a593Smuzhiyun 			}
669*4882a593Smuzhiyun 
670*4882a593Smuzhiyun 			b++;
671*4882a593Smuzhiyun 			length--;
672*4882a593Smuzhiyun 			break;
673*4882a593Smuzhiyun 
674*4882a593Smuzhiyun 		case 4:
675*4882a593Smuzhiyun 			dec->packet[dec->packet_length++] = *b++;
676*4882a593Smuzhiyun 
677*4882a593Smuzhiyun 			if (dec->packet_length == 2) {
678*4882a593Smuzhiyun 				if (dec->packet[0] == 'A' &&
679*4882a593Smuzhiyun 				    dec->packet[1] == 'V') {
680*4882a593Smuzhiyun 					dec->packet_type =
681*4882a593Smuzhiyun 						TTUSB_DEC_PACKET_PVA;
682*4882a593Smuzhiyun 					dec->packet_state++;
683*4882a593Smuzhiyun 				} else if (dec->packet[0] == 'S') {
684*4882a593Smuzhiyun 					dec->packet_type =
685*4882a593Smuzhiyun 						TTUSB_DEC_PACKET_SECTION;
686*4882a593Smuzhiyun 					dec->packet_state++;
687*4882a593Smuzhiyun 				} else if (dec->packet[0] == 0x00) {
688*4882a593Smuzhiyun 					dec->packet_type =
689*4882a593Smuzhiyun 						TTUSB_DEC_PACKET_EMPTY;
690*4882a593Smuzhiyun 					dec->packet_payload_length = 2;
691*4882a593Smuzhiyun 					dec->packet_state = 7;
692*4882a593Smuzhiyun 				} else {
693*4882a593Smuzhiyun 					printk("%s: unknown packet type: %02x%02x\n",
694*4882a593Smuzhiyun 					       __func__,
695*4882a593Smuzhiyun 					       dec->packet[0], dec->packet[1]);
696*4882a593Smuzhiyun 					dec->packet_state = 0;
697*4882a593Smuzhiyun 				}
698*4882a593Smuzhiyun 			}
699*4882a593Smuzhiyun 
700*4882a593Smuzhiyun 			length--;
701*4882a593Smuzhiyun 			break;
702*4882a593Smuzhiyun 
703*4882a593Smuzhiyun 		case 5:
704*4882a593Smuzhiyun 			dec->packet[dec->packet_length++] = *b++;
705*4882a593Smuzhiyun 
706*4882a593Smuzhiyun 			if (dec->packet_type == TTUSB_DEC_PACKET_PVA &&
707*4882a593Smuzhiyun 			    dec->packet_length == 8) {
708*4882a593Smuzhiyun 				dec->packet_state++;
709*4882a593Smuzhiyun 				dec->packet_payload_length = 8 +
710*4882a593Smuzhiyun 					(dec->packet[6] << 8) +
711*4882a593Smuzhiyun 					dec->packet[7];
712*4882a593Smuzhiyun 			} else if (dec->packet_type ==
713*4882a593Smuzhiyun 					TTUSB_DEC_PACKET_SECTION &&
714*4882a593Smuzhiyun 				   dec->packet_length == 5) {
715*4882a593Smuzhiyun 				dec->packet_state++;
716*4882a593Smuzhiyun 				dec->packet_payload_length = 5 +
717*4882a593Smuzhiyun 					((dec->packet[3] & 0x0f) << 8) +
718*4882a593Smuzhiyun 					dec->packet[4];
719*4882a593Smuzhiyun 			}
720*4882a593Smuzhiyun 
721*4882a593Smuzhiyun 			length--;
722*4882a593Smuzhiyun 			break;
723*4882a593Smuzhiyun 
724*4882a593Smuzhiyun 		case 6: {
725*4882a593Smuzhiyun 			int remainder = dec->packet_payload_length -
726*4882a593Smuzhiyun 					dec->packet_length;
727*4882a593Smuzhiyun 
728*4882a593Smuzhiyun 			if (length >= remainder) {
729*4882a593Smuzhiyun 				memcpy(dec->packet + dec->packet_length,
730*4882a593Smuzhiyun 				       b, remainder);
731*4882a593Smuzhiyun 				dec->packet_length += remainder;
732*4882a593Smuzhiyun 				b += remainder;
733*4882a593Smuzhiyun 				length -= remainder;
734*4882a593Smuzhiyun 				dec->packet_state++;
735*4882a593Smuzhiyun 			} else {
736*4882a593Smuzhiyun 				memcpy(&dec->packet[dec->packet_length],
737*4882a593Smuzhiyun 				       b, length);
738*4882a593Smuzhiyun 				dec->packet_length += length;
739*4882a593Smuzhiyun 				length = 0;
740*4882a593Smuzhiyun 			}
741*4882a593Smuzhiyun 
742*4882a593Smuzhiyun 			break;
743*4882a593Smuzhiyun 		}
744*4882a593Smuzhiyun 
745*4882a593Smuzhiyun 		case 7: {
746*4882a593Smuzhiyun 			int tail = 4;
747*4882a593Smuzhiyun 
748*4882a593Smuzhiyun 			dec->packet[dec->packet_length++] = *b++;
749*4882a593Smuzhiyun 
750*4882a593Smuzhiyun 			if (dec->packet_type == TTUSB_DEC_PACKET_SECTION &&
751*4882a593Smuzhiyun 			    dec->packet_payload_length % 2)
752*4882a593Smuzhiyun 				tail++;
753*4882a593Smuzhiyun 
754*4882a593Smuzhiyun 			if (dec->packet_length ==
755*4882a593Smuzhiyun 			    dec->packet_payload_length + tail) {
756*4882a593Smuzhiyun 				ttusb_dec_process_packet(dec);
757*4882a593Smuzhiyun 				dec->packet_state = 0;
758*4882a593Smuzhiyun 			}
759*4882a593Smuzhiyun 
760*4882a593Smuzhiyun 			length--;
761*4882a593Smuzhiyun 			break;
762*4882a593Smuzhiyun 		}
763*4882a593Smuzhiyun 
764*4882a593Smuzhiyun 		default:
765*4882a593Smuzhiyun 			printk("%s: illegal packet state encountered.\n",
766*4882a593Smuzhiyun 			       __func__);
767*4882a593Smuzhiyun 			dec->packet_state = 0;
768*4882a593Smuzhiyun 		}
769*4882a593Smuzhiyun 	}
770*4882a593Smuzhiyun }
771*4882a593Smuzhiyun 
ttusb_dec_process_urb_frame_list(struct tasklet_struct * t)772*4882a593Smuzhiyun static void ttusb_dec_process_urb_frame_list(struct tasklet_struct *t)
773*4882a593Smuzhiyun {
774*4882a593Smuzhiyun 	struct ttusb_dec *dec = from_tasklet(dec, t, urb_tasklet);
775*4882a593Smuzhiyun 	struct list_head *item;
776*4882a593Smuzhiyun 	struct urb_frame *frame;
777*4882a593Smuzhiyun 	unsigned long flags;
778*4882a593Smuzhiyun 
779*4882a593Smuzhiyun 	while (1) {
780*4882a593Smuzhiyun 		spin_lock_irqsave(&dec->urb_frame_list_lock, flags);
781*4882a593Smuzhiyun 		if ((item = dec->urb_frame_list.next) != &dec->urb_frame_list) {
782*4882a593Smuzhiyun 			frame = list_entry(item, struct urb_frame,
783*4882a593Smuzhiyun 					   urb_frame_list);
784*4882a593Smuzhiyun 			list_del(&frame->urb_frame_list);
785*4882a593Smuzhiyun 		} else {
786*4882a593Smuzhiyun 			spin_unlock_irqrestore(&dec->urb_frame_list_lock,
787*4882a593Smuzhiyun 					       flags);
788*4882a593Smuzhiyun 			return;
789*4882a593Smuzhiyun 		}
790*4882a593Smuzhiyun 		spin_unlock_irqrestore(&dec->urb_frame_list_lock, flags);
791*4882a593Smuzhiyun 
792*4882a593Smuzhiyun 		ttusb_dec_process_urb_frame(dec, frame->data, frame->length);
793*4882a593Smuzhiyun 		kfree(frame);
794*4882a593Smuzhiyun 	}
795*4882a593Smuzhiyun }
796*4882a593Smuzhiyun 
ttusb_dec_process_urb(struct urb * urb)797*4882a593Smuzhiyun static void ttusb_dec_process_urb(struct urb *urb)
798*4882a593Smuzhiyun {
799*4882a593Smuzhiyun 	struct ttusb_dec *dec = urb->context;
800*4882a593Smuzhiyun 
801*4882a593Smuzhiyun 	if (!urb->status) {
802*4882a593Smuzhiyun 		int i;
803*4882a593Smuzhiyun 
804*4882a593Smuzhiyun 		for (i = 0; i < FRAMES_PER_ISO_BUF; i++) {
805*4882a593Smuzhiyun 			struct usb_iso_packet_descriptor *d;
806*4882a593Smuzhiyun 			u8 *b;
807*4882a593Smuzhiyun 			int length;
808*4882a593Smuzhiyun 			struct urb_frame *frame;
809*4882a593Smuzhiyun 
810*4882a593Smuzhiyun 			d = &urb->iso_frame_desc[i];
811*4882a593Smuzhiyun 			b = urb->transfer_buffer + d->offset;
812*4882a593Smuzhiyun 			length = d->actual_length;
813*4882a593Smuzhiyun 
814*4882a593Smuzhiyun 			if ((frame = kmalloc(sizeof(struct urb_frame),
815*4882a593Smuzhiyun 					     GFP_ATOMIC))) {
816*4882a593Smuzhiyun 				unsigned long flags;
817*4882a593Smuzhiyun 
818*4882a593Smuzhiyun 				memcpy(frame->data, b, length);
819*4882a593Smuzhiyun 				frame->length = length;
820*4882a593Smuzhiyun 
821*4882a593Smuzhiyun 				spin_lock_irqsave(&dec->urb_frame_list_lock,
822*4882a593Smuzhiyun 						     flags);
823*4882a593Smuzhiyun 				list_add_tail(&frame->urb_frame_list,
824*4882a593Smuzhiyun 					      &dec->urb_frame_list);
825*4882a593Smuzhiyun 				spin_unlock_irqrestore(&dec->urb_frame_list_lock,
826*4882a593Smuzhiyun 						       flags);
827*4882a593Smuzhiyun 
828*4882a593Smuzhiyun 				tasklet_schedule(&dec->urb_tasklet);
829*4882a593Smuzhiyun 			}
830*4882a593Smuzhiyun 		}
831*4882a593Smuzhiyun 	} else {
832*4882a593Smuzhiyun 		 /* -ENOENT is expected when unlinking urbs */
833*4882a593Smuzhiyun 		if (urb->status != -ENOENT)
834*4882a593Smuzhiyun 			dprintk("%s: urb error: %d\n", __func__,
835*4882a593Smuzhiyun 				urb->status);
836*4882a593Smuzhiyun 	}
837*4882a593Smuzhiyun 
838*4882a593Smuzhiyun 	if (dec->iso_stream_count)
839*4882a593Smuzhiyun 		usb_submit_urb(urb, GFP_ATOMIC);
840*4882a593Smuzhiyun }
841*4882a593Smuzhiyun 
ttusb_dec_setup_urbs(struct ttusb_dec * dec)842*4882a593Smuzhiyun static void ttusb_dec_setup_urbs(struct ttusb_dec *dec)
843*4882a593Smuzhiyun {
844*4882a593Smuzhiyun 	int i, j, buffer_offset = 0;
845*4882a593Smuzhiyun 
846*4882a593Smuzhiyun 	dprintk("%s\n", __func__);
847*4882a593Smuzhiyun 
848*4882a593Smuzhiyun 	for (i = 0; i < ISO_BUF_COUNT; i++) {
849*4882a593Smuzhiyun 		int frame_offset = 0;
850*4882a593Smuzhiyun 		struct urb *urb = dec->iso_urb[i];
851*4882a593Smuzhiyun 
852*4882a593Smuzhiyun 		urb->dev = dec->udev;
853*4882a593Smuzhiyun 		urb->context = dec;
854*4882a593Smuzhiyun 		urb->complete = ttusb_dec_process_urb;
855*4882a593Smuzhiyun 		urb->pipe = dec->in_pipe;
856*4882a593Smuzhiyun 		urb->transfer_flags = URB_ISO_ASAP;
857*4882a593Smuzhiyun 		urb->interval = 1;
858*4882a593Smuzhiyun 		urb->number_of_packets = FRAMES_PER_ISO_BUF;
859*4882a593Smuzhiyun 		urb->transfer_buffer_length = ISO_FRAME_SIZE *
860*4882a593Smuzhiyun 					      FRAMES_PER_ISO_BUF;
861*4882a593Smuzhiyun 		urb->transfer_buffer = dec->iso_buffer + buffer_offset;
862*4882a593Smuzhiyun 		buffer_offset += ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF;
863*4882a593Smuzhiyun 
864*4882a593Smuzhiyun 		for (j = 0; j < FRAMES_PER_ISO_BUF; j++) {
865*4882a593Smuzhiyun 			urb->iso_frame_desc[j].offset = frame_offset;
866*4882a593Smuzhiyun 			urb->iso_frame_desc[j].length = ISO_FRAME_SIZE;
867*4882a593Smuzhiyun 			frame_offset += ISO_FRAME_SIZE;
868*4882a593Smuzhiyun 		}
869*4882a593Smuzhiyun 	}
870*4882a593Smuzhiyun }
871*4882a593Smuzhiyun 
ttusb_dec_stop_iso_xfer(struct ttusb_dec * dec)872*4882a593Smuzhiyun static void ttusb_dec_stop_iso_xfer(struct ttusb_dec *dec)
873*4882a593Smuzhiyun {
874*4882a593Smuzhiyun 	int i;
875*4882a593Smuzhiyun 
876*4882a593Smuzhiyun 	dprintk("%s\n", __func__);
877*4882a593Smuzhiyun 
878*4882a593Smuzhiyun 	if (mutex_lock_interruptible(&dec->iso_mutex))
879*4882a593Smuzhiyun 		return;
880*4882a593Smuzhiyun 
881*4882a593Smuzhiyun 	dec->iso_stream_count--;
882*4882a593Smuzhiyun 
883*4882a593Smuzhiyun 	if (!dec->iso_stream_count) {
884*4882a593Smuzhiyun 		for (i = 0; i < ISO_BUF_COUNT; i++)
885*4882a593Smuzhiyun 			usb_kill_urb(dec->iso_urb[i]);
886*4882a593Smuzhiyun 	}
887*4882a593Smuzhiyun 
888*4882a593Smuzhiyun 	mutex_unlock(&dec->iso_mutex);
889*4882a593Smuzhiyun }
890*4882a593Smuzhiyun 
891*4882a593Smuzhiyun /* Setting the interface of the DEC tends to take down the USB communications
892*4882a593Smuzhiyun  * for a short period, so it's important not to call this function just before
893*4882a593Smuzhiyun  * trying to talk to it.
894*4882a593Smuzhiyun  */
ttusb_dec_set_interface(struct ttusb_dec * dec,enum ttusb_dec_interface interface)895*4882a593Smuzhiyun static int ttusb_dec_set_interface(struct ttusb_dec *dec,
896*4882a593Smuzhiyun 				   enum ttusb_dec_interface interface)
897*4882a593Smuzhiyun {
898*4882a593Smuzhiyun 	int result = 0;
899*4882a593Smuzhiyun 	u8 b[] = { 0x05 };
900*4882a593Smuzhiyun 
901*4882a593Smuzhiyun 	if (interface != dec->interface) {
902*4882a593Smuzhiyun 		switch (interface) {
903*4882a593Smuzhiyun 		case TTUSB_DEC_INTERFACE_INITIAL:
904*4882a593Smuzhiyun 			result = usb_set_interface(dec->udev, 0, 0);
905*4882a593Smuzhiyun 			break;
906*4882a593Smuzhiyun 		case TTUSB_DEC_INTERFACE_IN:
907*4882a593Smuzhiyun 			result = ttusb_dec_send_command(dec, 0x80, sizeof(b),
908*4882a593Smuzhiyun 							b, NULL, NULL);
909*4882a593Smuzhiyun 			if (result)
910*4882a593Smuzhiyun 				return result;
911*4882a593Smuzhiyun 			result = usb_set_interface(dec->udev, 0, 8);
912*4882a593Smuzhiyun 			break;
913*4882a593Smuzhiyun 		case TTUSB_DEC_INTERFACE_OUT:
914*4882a593Smuzhiyun 			result = usb_set_interface(dec->udev, 0, 1);
915*4882a593Smuzhiyun 			break;
916*4882a593Smuzhiyun 		}
917*4882a593Smuzhiyun 
918*4882a593Smuzhiyun 		if (result)
919*4882a593Smuzhiyun 			return result;
920*4882a593Smuzhiyun 
921*4882a593Smuzhiyun 		dec->interface = interface;
922*4882a593Smuzhiyun 	}
923*4882a593Smuzhiyun 
924*4882a593Smuzhiyun 	return 0;
925*4882a593Smuzhiyun }
926*4882a593Smuzhiyun 
ttusb_dec_start_iso_xfer(struct ttusb_dec * dec)927*4882a593Smuzhiyun static int ttusb_dec_start_iso_xfer(struct ttusb_dec *dec)
928*4882a593Smuzhiyun {
929*4882a593Smuzhiyun 	int i, result;
930*4882a593Smuzhiyun 
931*4882a593Smuzhiyun 	dprintk("%s\n", __func__);
932*4882a593Smuzhiyun 
933*4882a593Smuzhiyun 	if (mutex_lock_interruptible(&dec->iso_mutex))
934*4882a593Smuzhiyun 		return -EAGAIN;
935*4882a593Smuzhiyun 
936*4882a593Smuzhiyun 	if (!dec->iso_stream_count) {
937*4882a593Smuzhiyun 		ttusb_dec_setup_urbs(dec);
938*4882a593Smuzhiyun 
939*4882a593Smuzhiyun 		dec->packet_state = 0;
940*4882a593Smuzhiyun 		dec->v_pes_postbytes = 0;
941*4882a593Smuzhiyun 		dec->next_packet_id = 0;
942*4882a593Smuzhiyun 
943*4882a593Smuzhiyun 		for (i = 0; i < ISO_BUF_COUNT; i++) {
944*4882a593Smuzhiyun 			if ((result = usb_submit_urb(dec->iso_urb[i],
945*4882a593Smuzhiyun 						     GFP_ATOMIC))) {
946*4882a593Smuzhiyun 				printk("%s: failed urb submission %d: error %d\n",
947*4882a593Smuzhiyun 				       __func__, i, result);
948*4882a593Smuzhiyun 
949*4882a593Smuzhiyun 				while (i) {
950*4882a593Smuzhiyun 					usb_kill_urb(dec->iso_urb[i - 1]);
951*4882a593Smuzhiyun 					i--;
952*4882a593Smuzhiyun 				}
953*4882a593Smuzhiyun 
954*4882a593Smuzhiyun 				mutex_unlock(&dec->iso_mutex);
955*4882a593Smuzhiyun 				return result;
956*4882a593Smuzhiyun 			}
957*4882a593Smuzhiyun 		}
958*4882a593Smuzhiyun 	}
959*4882a593Smuzhiyun 
960*4882a593Smuzhiyun 	dec->iso_stream_count++;
961*4882a593Smuzhiyun 
962*4882a593Smuzhiyun 	mutex_unlock(&dec->iso_mutex);
963*4882a593Smuzhiyun 
964*4882a593Smuzhiyun 	return 0;
965*4882a593Smuzhiyun }
966*4882a593Smuzhiyun 
ttusb_dec_start_ts_feed(struct dvb_demux_feed * dvbdmxfeed)967*4882a593Smuzhiyun static int ttusb_dec_start_ts_feed(struct dvb_demux_feed *dvbdmxfeed)
968*4882a593Smuzhiyun {
969*4882a593Smuzhiyun 	struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
970*4882a593Smuzhiyun 	struct ttusb_dec *dec = dvbdmx->priv;
971*4882a593Smuzhiyun 	u8 b0[] = { 0x05 };
972*4882a593Smuzhiyun 	int result = 0;
973*4882a593Smuzhiyun 
974*4882a593Smuzhiyun 	dprintk("%s\n", __func__);
975*4882a593Smuzhiyun 
976*4882a593Smuzhiyun 	dprintk("  ts_type:");
977*4882a593Smuzhiyun 
978*4882a593Smuzhiyun 	if (dvbdmxfeed->ts_type & TS_DECODER)
979*4882a593Smuzhiyun 		dprintk(" TS_DECODER");
980*4882a593Smuzhiyun 
981*4882a593Smuzhiyun 	if (dvbdmxfeed->ts_type & TS_PACKET)
982*4882a593Smuzhiyun 		dprintk(" TS_PACKET");
983*4882a593Smuzhiyun 
984*4882a593Smuzhiyun 	if (dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY)
985*4882a593Smuzhiyun 		dprintk(" TS_PAYLOAD_ONLY");
986*4882a593Smuzhiyun 
987*4882a593Smuzhiyun 	dprintk("\n");
988*4882a593Smuzhiyun 
989*4882a593Smuzhiyun 	switch (dvbdmxfeed->pes_type) {
990*4882a593Smuzhiyun 
991*4882a593Smuzhiyun 	case DMX_PES_VIDEO:
992*4882a593Smuzhiyun 		dprintk("  pes_type: DMX_PES_VIDEO\n");
993*4882a593Smuzhiyun 		dec->pid[DMX_PES_PCR] = dvbdmxfeed->pid;
994*4882a593Smuzhiyun 		dec->pid[DMX_PES_VIDEO] = dvbdmxfeed->pid;
995*4882a593Smuzhiyun 		dec->video_filter = dvbdmxfeed->filter;
996*4882a593Smuzhiyun 		ttusb_dec_set_pids(dec);
997*4882a593Smuzhiyun 		break;
998*4882a593Smuzhiyun 
999*4882a593Smuzhiyun 	case DMX_PES_AUDIO:
1000*4882a593Smuzhiyun 		dprintk("  pes_type: DMX_PES_AUDIO\n");
1001*4882a593Smuzhiyun 		dec->pid[DMX_PES_AUDIO] = dvbdmxfeed->pid;
1002*4882a593Smuzhiyun 		dec->audio_filter = dvbdmxfeed->filter;
1003*4882a593Smuzhiyun 		ttusb_dec_set_pids(dec);
1004*4882a593Smuzhiyun 		break;
1005*4882a593Smuzhiyun 
1006*4882a593Smuzhiyun 	case DMX_PES_TELETEXT:
1007*4882a593Smuzhiyun 		dec->pid[DMX_PES_TELETEXT] = dvbdmxfeed->pid;
1008*4882a593Smuzhiyun 		dprintk("  pes_type: DMX_PES_TELETEXT(not supported)\n");
1009*4882a593Smuzhiyun 		return -ENOSYS;
1010*4882a593Smuzhiyun 
1011*4882a593Smuzhiyun 	case DMX_PES_PCR:
1012*4882a593Smuzhiyun 		dprintk("  pes_type: DMX_PES_PCR\n");
1013*4882a593Smuzhiyun 		dec->pid[DMX_PES_PCR] = dvbdmxfeed->pid;
1014*4882a593Smuzhiyun 		ttusb_dec_set_pids(dec);
1015*4882a593Smuzhiyun 		break;
1016*4882a593Smuzhiyun 
1017*4882a593Smuzhiyun 	case DMX_PES_OTHER:
1018*4882a593Smuzhiyun 		dprintk("  pes_type: DMX_PES_OTHER(not supported)\n");
1019*4882a593Smuzhiyun 		return -ENOSYS;
1020*4882a593Smuzhiyun 
1021*4882a593Smuzhiyun 	default:
1022*4882a593Smuzhiyun 		dprintk("  pes_type: unknown (%d)\n", dvbdmxfeed->pes_type);
1023*4882a593Smuzhiyun 		return -EINVAL;
1024*4882a593Smuzhiyun 
1025*4882a593Smuzhiyun 	}
1026*4882a593Smuzhiyun 
1027*4882a593Smuzhiyun 	result = ttusb_dec_send_command(dec, 0x80, sizeof(b0), b0, NULL, NULL);
1028*4882a593Smuzhiyun 	if (result)
1029*4882a593Smuzhiyun 		return result;
1030*4882a593Smuzhiyun 
1031*4882a593Smuzhiyun 	dec->pva_stream_count++;
1032*4882a593Smuzhiyun 	return ttusb_dec_start_iso_xfer(dec);
1033*4882a593Smuzhiyun }
1034*4882a593Smuzhiyun 
ttusb_dec_start_sec_feed(struct dvb_demux_feed * dvbdmxfeed)1035*4882a593Smuzhiyun static int ttusb_dec_start_sec_feed(struct dvb_demux_feed *dvbdmxfeed)
1036*4882a593Smuzhiyun {
1037*4882a593Smuzhiyun 	struct ttusb_dec *dec = dvbdmxfeed->demux->priv;
1038*4882a593Smuzhiyun 	u8 b0[] = { 0x00, 0x00, 0x00, 0x01,
1039*4882a593Smuzhiyun 		    0x00, 0x00, 0x00, 0x00,
1040*4882a593Smuzhiyun 		    0x00, 0x00, 0x00, 0x00,
1041*4882a593Smuzhiyun 		    0x00, 0x00, 0x00, 0x00,
1042*4882a593Smuzhiyun 		    0x00, 0xff, 0x00, 0x00,
1043*4882a593Smuzhiyun 		    0x00, 0x00, 0x00, 0x00,
1044*4882a593Smuzhiyun 		    0x00, 0x00, 0x00, 0x00,
1045*4882a593Smuzhiyun 		    0x00 };
1046*4882a593Smuzhiyun 	__be16 pid;
1047*4882a593Smuzhiyun 	u8 c[COMMAND_PACKET_SIZE];
1048*4882a593Smuzhiyun 	int c_length;
1049*4882a593Smuzhiyun 	int result;
1050*4882a593Smuzhiyun 	struct filter_info *finfo;
1051*4882a593Smuzhiyun 	unsigned long flags;
1052*4882a593Smuzhiyun 	u8 x = 1;
1053*4882a593Smuzhiyun 
1054*4882a593Smuzhiyun 	dprintk("%s\n", __func__);
1055*4882a593Smuzhiyun 
1056*4882a593Smuzhiyun 	pid = htons(dvbdmxfeed->pid);
1057*4882a593Smuzhiyun 	memcpy(&b0[0], &pid, 2);
1058*4882a593Smuzhiyun 	memcpy(&b0[4], &x, 1);
1059*4882a593Smuzhiyun 	memcpy(&b0[5], &dvbdmxfeed->filter->filter.filter_value[0], 1);
1060*4882a593Smuzhiyun 
1061*4882a593Smuzhiyun 	result = ttusb_dec_send_command(dec, 0x60, sizeof(b0), b0,
1062*4882a593Smuzhiyun 					&c_length, c);
1063*4882a593Smuzhiyun 
1064*4882a593Smuzhiyun 	if (!result) {
1065*4882a593Smuzhiyun 		if (c_length == 2) {
1066*4882a593Smuzhiyun 			if (!(finfo = kmalloc(sizeof(struct filter_info),
1067*4882a593Smuzhiyun 					      GFP_ATOMIC)))
1068*4882a593Smuzhiyun 				return -ENOMEM;
1069*4882a593Smuzhiyun 
1070*4882a593Smuzhiyun 			finfo->stream_id = c[1];
1071*4882a593Smuzhiyun 			finfo->filter = dvbdmxfeed->filter;
1072*4882a593Smuzhiyun 
1073*4882a593Smuzhiyun 			spin_lock_irqsave(&dec->filter_info_list_lock, flags);
1074*4882a593Smuzhiyun 			list_add_tail(&finfo->filter_info_list,
1075*4882a593Smuzhiyun 				      &dec->filter_info_list);
1076*4882a593Smuzhiyun 			spin_unlock_irqrestore(&dec->filter_info_list_lock,
1077*4882a593Smuzhiyun 					       flags);
1078*4882a593Smuzhiyun 
1079*4882a593Smuzhiyun 			dvbdmxfeed->priv = finfo;
1080*4882a593Smuzhiyun 
1081*4882a593Smuzhiyun 			dec->filter_stream_count++;
1082*4882a593Smuzhiyun 			return ttusb_dec_start_iso_xfer(dec);
1083*4882a593Smuzhiyun 		}
1084*4882a593Smuzhiyun 
1085*4882a593Smuzhiyun 		return -EAGAIN;
1086*4882a593Smuzhiyun 	} else
1087*4882a593Smuzhiyun 		return result;
1088*4882a593Smuzhiyun }
1089*4882a593Smuzhiyun 
ttusb_dec_start_feed(struct dvb_demux_feed * dvbdmxfeed)1090*4882a593Smuzhiyun static int ttusb_dec_start_feed(struct dvb_demux_feed *dvbdmxfeed)
1091*4882a593Smuzhiyun {
1092*4882a593Smuzhiyun 	struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
1093*4882a593Smuzhiyun 
1094*4882a593Smuzhiyun 	dprintk("%s\n", __func__);
1095*4882a593Smuzhiyun 
1096*4882a593Smuzhiyun 	if (!dvbdmx->dmx.frontend)
1097*4882a593Smuzhiyun 		return -EINVAL;
1098*4882a593Smuzhiyun 
1099*4882a593Smuzhiyun 	dprintk("  pid: 0x%04X\n", dvbdmxfeed->pid);
1100*4882a593Smuzhiyun 
1101*4882a593Smuzhiyun 	switch (dvbdmxfeed->type) {
1102*4882a593Smuzhiyun 
1103*4882a593Smuzhiyun 	case DMX_TYPE_TS:
1104*4882a593Smuzhiyun 		return ttusb_dec_start_ts_feed(dvbdmxfeed);
1105*4882a593Smuzhiyun 		break;
1106*4882a593Smuzhiyun 
1107*4882a593Smuzhiyun 	case DMX_TYPE_SEC:
1108*4882a593Smuzhiyun 		return ttusb_dec_start_sec_feed(dvbdmxfeed);
1109*4882a593Smuzhiyun 		break;
1110*4882a593Smuzhiyun 
1111*4882a593Smuzhiyun 	default:
1112*4882a593Smuzhiyun 		dprintk("  type: unknown (%d)\n", dvbdmxfeed->type);
1113*4882a593Smuzhiyun 		return -EINVAL;
1114*4882a593Smuzhiyun 
1115*4882a593Smuzhiyun 	}
1116*4882a593Smuzhiyun }
1117*4882a593Smuzhiyun 
ttusb_dec_stop_ts_feed(struct dvb_demux_feed * dvbdmxfeed)1118*4882a593Smuzhiyun static int ttusb_dec_stop_ts_feed(struct dvb_demux_feed *dvbdmxfeed)
1119*4882a593Smuzhiyun {
1120*4882a593Smuzhiyun 	struct ttusb_dec *dec = dvbdmxfeed->demux->priv;
1121*4882a593Smuzhiyun 	u8 b0[] = { 0x00 };
1122*4882a593Smuzhiyun 
1123*4882a593Smuzhiyun 	ttusb_dec_send_command(dec, 0x81, sizeof(b0), b0, NULL, NULL);
1124*4882a593Smuzhiyun 
1125*4882a593Smuzhiyun 	dec->pva_stream_count--;
1126*4882a593Smuzhiyun 
1127*4882a593Smuzhiyun 	ttusb_dec_stop_iso_xfer(dec);
1128*4882a593Smuzhiyun 
1129*4882a593Smuzhiyun 	return 0;
1130*4882a593Smuzhiyun }
1131*4882a593Smuzhiyun 
ttusb_dec_stop_sec_feed(struct dvb_demux_feed * dvbdmxfeed)1132*4882a593Smuzhiyun static int ttusb_dec_stop_sec_feed(struct dvb_demux_feed *dvbdmxfeed)
1133*4882a593Smuzhiyun {
1134*4882a593Smuzhiyun 	struct ttusb_dec *dec = dvbdmxfeed->demux->priv;
1135*4882a593Smuzhiyun 	u8 b0[] = { 0x00, 0x00 };
1136*4882a593Smuzhiyun 	struct filter_info *finfo = (struct filter_info *)dvbdmxfeed->priv;
1137*4882a593Smuzhiyun 	unsigned long flags;
1138*4882a593Smuzhiyun 
1139*4882a593Smuzhiyun 	b0[1] = finfo->stream_id;
1140*4882a593Smuzhiyun 	spin_lock_irqsave(&dec->filter_info_list_lock, flags);
1141*4882a593Smuzhiyun 	list_del(&finfo->filter_info_list);
1142*4882a593Smuzhiyun 	spin_unlock_irqrestore(&dec->filter_info_list_lock, flags);
1143*4882a593Smuzhiyun 	kfree(finfo);
1144*4882a593Smuzhiyun 	ttusb_dec_send_command(dec, 0x62, sizeof(b0), b0, NULL, NULL);
1145*4882a593Smuzhiyun 
1146*4882a593Smuzhiyun 	dec->filter_stream_count--;
1147*4882a593Smuzhiyun 
1148*4882a593Smuzhiyun 	ttusb_dec_stop_iso_xfer(dec);
1149*4882a593Smuzhiyun 
1150*4882a593Smuzhiyun 	return 0;
1151*4882a593Smuzhiyun }
1152*4882a593Smuzhiyun 
ttusb_dec_stop_feed(struct dvb_demux_feed * dvbdmxfeed)1153*4882a593Smuzhiyun static int ttusb_dec_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
1154*4882a593Smuzhiyun {
1155*4882a593Smuzhiyun 	dprintk("%s\n", __func__);
1156*4882a593Smuzhiyun 
1157*4882a593Smuzhiyun 	switch (dvbdmxfeed->type) {
1158*4882a593Smuzhiyun 	case DMX_TYPE_TS:
1159*4882a593Smuzhiyun 		return ttusb_dec_stop_ts_feed(dvbdmxfeed);
1160*4882a593Smuzhiyun 		break;
1161*4882a593Smuzhiyun 
1162*4882a593Smuzhiyun 	case DMX_TYPE_SEC:
1163*4882a593Smuzhiyun 		return ttusb_dec_stop_sec_feed(dvbdmxfeed);
1164*4882a593Smuzhiyun 		break;
1165*4882a593Smuzhiyun 	}
1166*4882a593Smuzhiyun 
1167*4882a593Smuzhiyun 	return 0;
1168*4882a593Smuzhiyun }
1169*4882a593Smuzhiyun 
ttusb_dec_free_iso_urbs(struct ttusb_dec * dec)1170*4882a593Smuzhiyun static void ttusb_dec_free_iso_urbs(struct ttusb_dec *dec)
1171*4882a593Smuzhiyun {
1172*4882a593Smuzhiyun 	int i;
1173*4882a593Smuzhiyun 
1174*4882a593Smuzhiyun 	dprintk("%s\n", __func__);
1175*4882a593Smuzhiyun 
1176*4882a593Smuzhiyun 	for (i = 0; i < ISO_BUF_COUNT; i++)
1177*4882a593Smuzhiyun 		usb_free_urb(dec->iso_urb[i]);
1178*4882a593Smuzhiyun 	kfree(dec->iso_buffer);
1179*4882a593Smuzhiyun }
1180*4882a593Smuzhiyun 
ttusb_dec_alloc_iso_urbs(struct ttusb_dec * dec)1181*4882a593Smuzhiyun static int ttusb_dec_alloc_iso_urbs(struct ttusb_dec *dec)
1182*4882a593Smuzhiyun {
1183*4882a593Smuzhiyun 	int i;
1184*4882a593Smuzhiyun 
1185*4882a593Smuzhiyun 	dprintk("%s\n", __func__);
1186*4882a593Smuzhiyun 
1187*4882a593Smuzhiyun 	dec->iso_buffer = kcalloc(FRAMES_PER_ISO_BUF * ISO_BUF_COUNT,
1188*4882a593Smuzhiyun 			ISO_FRAME_SIZE, GFP_KERNEL);
1189*4882a593Smuzhiyun 	if (!dec->iso_buffer)
1190*4882a593Smuzhiyun 		return -ENOMEM;
1191*4882a593Smuzhiyun 
1192*4882a593Smuzhiyun 	for (i = 0; i < ISO_BUF_COUNT; i++) {
1193*4882a593Smuzhiyun 		struct urb *urb;
1194*4882a593Smuzhiyun 
1195*4882a593Smuzhiyun 		if (!(urb = usb_alloc_urb(FRAMES_PER_ISO_BUF, GFP_ATOMIC))) {
1196*4882a593Smuzhiyun 			ttusb_dec_free_iso_urbs(dec);
1197*4882a593Smuzhiyun 			return -ENOMEM;
1198*4882a593Smuzhiyun 		}
1199*4882a593Smuzhiyun 
1200*4882a593Smuzhiyun 		dec->iso_urb[i] = urb;
1201*4882a593Smuzhiyun 	}
1202*4882a593Smuzhiyun 
1203*4882a593Smuzhiyun 	ttusb_dec_setup_urbs(dec);
1204*4882a593Smuzhiyun 
1205*4882a593Smuzhiyun 	return 0;
1206*4882a593Smuzhiyun }
1207*4882a593Smuzhiyun 
ttusb_dec_init_tasklet(struct ttusb_dec * dec)1208*4882a593Smuzhiyun static void ttusb_dec_init_tasklet(struct ttusb_dec *dec)
1209*4882a593Smuzhiyun {
1210*4882a593Smuzhiyun 	spin_lock_init(&dec->urb_frame_list_lock);
1211*4882a593Smuzhiyun 	INIT_LIST_HEAD(&dec->urb_frame_list);
1212*4882a593Smuzhiyun 	tasklet_setup(&dec->urb_tasklet, ttusb_dec_process_urb_frame_list);
1213*4882a593Smuzhiyun }
1214*4882a593Smuzhiyun 
ttusb_init_rc(struct ttusb_dec * dec)1215*4882a593Smuzhiyun static int ttusb_init_rc( struct ttusb_dec *dec)
1216*4882a593Smuzhiyun {
1217*4882a593Smuzhiyun 	struct input_dev *input_dev;
1218*4882a593Smuzhiyun 	u8 b[] = { 0x00, 0x01 };
1219*4882a593Smuzhiyun 	int i;
1220*4882a593Smuzhiyun 	int err;
1221*4882a593Smuzhiyun 
1222*4882a593Smuzhiyun 	usb_make_path(dec->udev, dec->rc_phys, sizeof(dec->rc_phys));
1223*4882a593Smuzhiyun 	strlcat(dec->rc_phys, "/input0", sizeof(dec->rc_phys));
1224*4882a593Smuzhiyun 
1225*4882a593Smuzhiyun 	input_dev = input_allocate_device();
1226*4882a593Smuzhiyun 	if (!input_dev)
1227*4882a593Smuzhiyun 		return -ENOMEM;
1228*4882a593Smuzhiyun 
1229*4882a593Smuzhiyun 	input_dev->name = "ttusb_dec remote control";
1230*4882a593Smuzhiyun 	input_dev->phys = dec->rc_phys;
1231*4882a593Smuzhiyun 	input_dev->evbit[0] = BIT_MASK(EV_KEY);
1232*4882a593Smuzhiyun 	input_dev->keycodesize = sizeof(u16);
1233*4882a593Smuzhiyun 	input_dev->keycodemax = 0x1a;
1234*4882a593Smuzhiyun 	input_dev->keycode = rc_keys;
1235*4882a593Smuzhiyun 
1236*4882a593Smuzhiyun 	for (i = 0; i < ARRAY_SIZE(rc_keys); i++)
1237*4882a593Smuzhiyun 		  set_bit(rc_keys[i], input_dev->keybit);
1238*4882a593Smuzhiyun 
1239*4882a593Smuzhiyun 	err = input_register_device(input_dev);
1240*4882a593Smuzhiyun 	if (err) {
1241*4882a593Smuzhiyun 		input_free_device(input_dev);
1242*4882a593Smuzhiyun 		return err;
1243*4882a593Smuzhiyun 	}
1244*4882a593Smuzhiyun 
1245*4882a593Smuzhiyun 	dec->rc_input_dev = input_dev;
1246*4882a593Smuzhiyun 	if (usb_submit_urb(dec->irq_urb, GFP_KERNEL))
1247*4882a593Smuzhiyun 		printk("%s: usb_submit_urb failed\n",__func__);
1248*4882a593Smuzhiyun 	/* enable irq pipe */
1249*4882a593Smuzhiyun 	ttusb_dec_send_command(dec,0xb0,sizeof(b),b,NULL,NULL);
1250*4882a593Smuzhiyun 
1251*4882a593Smuzhiyun 	return 0;
1252*4882a593Smuzhiyun }
1253*4882a593Smuzhiyun 
ttusb_dec_init_v_pes(struct ttusb_dec * dec)1254*4882a593Smuzhiyun static void ttusb_dec_init_v_pes(struct ttusb_dec *dec)
1255*4882a593Smuzhiyun {
1256*4882a593Smuzhiyun 	dprintk("%s\n", __func__);
1257*4882a593Smuzhiyun 
1258*4882a593Smuzhiyun 	dec->v_pes[0] = 0x00;
1259*4882a593Smuzhiyun 	dec->v_pes[1] = 0x00;
1260*4882a593Smuzhiyun 	dec->v_pes[2] = 0x01;
1261*4882a593Smuzhiyun 	dec->v_pes[3] = 0xe0;
1262*4882a593Smuzhiyun }
1263*4882a593Smuzhiyun 
ttusb_dec_init_usb(struct ttusb_dec * dec)1264*4882a593Smuzhiyun static int ttusb_dec_init_usb(struct ttusb_dec *dec)
1265*4882a593Smuzhiyun {
1266*4882a593Smuzhiyun 	int result;
1267*4882a593Smuzhiyun 
1268*4882a593Smuzhiyun 	dprintk("%s\n", __func__);
1269*4882a593Smuzhiyun 
1270*4882a593Smuzhiyun 	mutex_init(&dec->usb_mutex);
1271*4882a593Smuzhiyun 	mutex_init(&dec->iso_mutex);
1272*4882a593Smuzhiyun 
1273*4882a593Smuzhiyun 	dec->command_pipe = usb_sndbulkpipe(dec->udev, COMMAND_PIPE);
1274*4882a593Smuzhiyun 	dec->result_pipe = usb_rcvbulkpipe(dec->udev, RESULT_PIPE);
1275*4882a593Smuzhiyun 	dec->in_pipe = usb_rcvisocpipe(dec->udev, IN_PIPE);
1276*4882a593Smuzhiyun 	dec->out_pipe = usb_sndisocpipe(dec->udev, OUT_PIPE);
1277*4882a593Smuzhiyun 	dec->irq_pipe = usb_rcvintpipe(dec->udev, IRQ_PIPE);
1278*4882a593Smuzhiyun 
1279*4882a593Smuzhiyun 	if(enable_rc) {
1280*4882a593Smuzhiyun 		dec->irq_urb = usb_alloc_urb(0, GFP_KERNEL);
1281*4882a593Smuzhiyun 		if(!dec->irq_urb) {
1282*4882a593Smuzhiyun 			return -ENOMEM;
1283*4882a593Smuzhiyun 		}
1284*4882a593Smuzhiyun 		dec->irq_buffer = usb_alloc_coherent(dec->udev,IRQ_PACKET_SIZE,
1285*4882a593Smuzhiyun 					GFP_KERNEL, &dec->irq_dma_handle);
1286*4882a593Smuzhiyun 		if(!dec->irq_buffer) {
1287*4882a593Smuzhiyun 			usb_free_urb(dec->irq_urb);
1288*4882a593Smuzhiyun 			return -ENOMEM;
1289*4882a593Smuzhiyun 		}
1290*4882a593Smuzhiyun 		usb_fill_int_urb(dec->irq_urb, dec->udev,dec->irq_pipe,
1291*4882a593Smuzhiyun 				 dec->irq_buffer, IRQ_PACKET_SIZE,
1292*4882a593Smuzhiyun 				 ttusb_dec_handle_irq, dec, 1);
1293*4882a593Smuzhiyun 		dec->irq_urb->transfer_dma = dec->irq_dma_handle;
1294*4882a593Smuzhiyun 		dec->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
1295*4882a593Smuzhiyun 	}
1296*4882a593Smuzhiyun 
1297*4882a593Smuzhiyun 	result = ttusb_dec_alloc_iso_urbs(dec);
1298*4882a593Smuzhiyun 	if (result) {
1299*4882a593Smuzhiyun 		usb_free_urb(dec->irq_urb);
1300*4882a593Smuzhiyun 		usb_free_coherent(dec->udev, IRQ_PACKET_SIZE,
1301*4882a593Smuzhiyun 				  dec->irq_buffer, dec->irq_dma_handle);
1302*4882a593Smuzhiyun 	}
1303*4882a593Smuzhiyun 	return result;
1304*4882a593Smuzhiyun }
1305*4882a593Smuzhiyun 
ttusb_dec_boot_dsp(struct ttusb_dec * dec)1306*4882a593Smuzhiyun static int ttusb_dec_boot_dsp(struct ttusb_dec *dec)
1307*4882a593Smuzhiyun {
1308*4882a593Smuzhiyun 	int i, j, actual_len, result, size, trans_count;
1309*4882a593Smuzhiyun 	u8 b0[] = { 0x00, 0x00, 0x00, 0x00,
1310*4882a593Smuzhiyun 		    0x00, 0x00, 0x00, 0x00,
1311*4882a593Smuzhiyun 		    0x61, 0x00 };
1312*4882a593Smuzhiyun 	u8 b1[] = { 0x61 };
1313*4882a593Smuzhiyun 	u8 *b;
1314*4882a593Smuzhiyun 	char idstring[21];
1315*4882a593Smuzhiyun 	const u8 *firmware = NULL;
1316*4882a593Smuzhiyun 	size_t firmware_size = 0;
1317*4882a593Smuzhiyun 	u16 firmware_csum = 0;
1318*4882a593Smuzhiyun 	__be16 firmware_csum_ns;
1319*4882a593Smuzhiyun 	__be32 firmware_size_nl;
1320*4882a593Smuzhiyun 	u32 crc32_csum, crc32_check;
1321*4882a593Smuzhiyun 	__be32 tmp;
1322*4882a593Smuzhiyun 	const struct firmware *fw_entry = NULL;
1323*4882a593Smuzhiyun 
1324*4882a593Smuzhiyun 	dprintk("%s\n", __func__);
1325*4882a593Smuzhiyun 
1326*4882a593Smuzhiyun 	result = request_firmware(&fw_entry, dec->firmware_name, &dec->udev->dev);
1327*4882a593Smuzhiyun 	if (result) {
1328*4882a593Smuzhiyun 		printk(KERN_ERR "%s: Firmware (%s) unavailable.\n",
1329*4882a593Smuzhiyun 		       __func__, dec->firmware_name);
1330*4882a593Smuzhiyun 		return result;
1331*4882a593Smuzhiyun 	}
1332*4882a593Smuzhiyun 
1333*4882a593Smuzhiyun 	firmware = fw_entry->data;
1334*4882a593Smuzhiyun 	firmware_size = fw_entry->size;
1335*4882a593Smuzhiyun 
1336*4882a593Smuzhiyun 	if (firmware_size < 60) {
1337*4882a593Smuzhiyun 		printk("%s: firmware size too small for DSP code (%zu < 60).\n",
1338*4882a593Smuzhiyun 			__func__, firmware_size);
1339*4882a593Smuzhiyun 		release_firmware(fw_entry);
1340*4882a593Smuzhiyun 		return -ENOENT;
1341*4882a593Smuzhiyun 	}
1342*4882a593Smuzhiyun 
1343*4882a593Smuzhiyun 	/* a 32 bit checksum over the first 56 bytes of the DSP Code is stored
1344*4882a593Smuzhiyun 	   at offset 56 of file, so use it to check if the firmware file is
1345*4882a593Smuzhiyun 	   valid. */
1346*4882a593Smuzhiyun 	crc32_csum = crc32(~0L, firmware, 56) ^ ~0L;
1347*4882a593Smuzhiyun 	memcpy(&tmp, &firmware[56], 4);
1348*4882a593Smuzhiyun 	crc32_check = ntohl(tmp);
1349*4882a593Smuzhiyun 	if (crc32_csum != crc32_check) {
1350*4882a593Smuzhiyun 		printk("%s: crc32 check of DSP code failed (calculated 0x%08x != 0x%08x in file), file invalid.\n",
1351*4882a593Smuzhiyun 			__func__, crc32_csum, crc32_check);
1352*4882a593Smuzhiyun 		release_firmware(fw_entry);
1353*4882a593Smuzhiyun 		return -ENOENT;
1354*4882a593Smuzhiyun 	}
1355*4882a593Smuzhiyun 	memcpy(idstring, &firmware[36], 20);
1356*4882a593Smuzhiyun 	idstring[20] = '\0';
1357*4882a593Smuzhiyun 	printk(KERN_INFO "ttusb_dec: found DSP code \"%s\".\n", idstring);
1358*4882a593Smuzhiyun 
1359*4882a593Smuzhiyun 	firmware_size_nl = htonl(firmware_size);
1360*4882a593Smuzhiyun 	memcpy(b0, &firmware_size_nl, 4);
1361*4882a593Smuzhiyun 	firmware_csum = crc16(~0, firmware, firmware_size) ^ ~0;
1362*4882a593Smuzhiyun 	firmware_csum_ns = htons(firmware_csum);
1363*4882a593Smuzhiyun 	memcpy(&b0[6], &firmware_csum_ns, 2);
1364*4882a593Smuzhiyun 
1365*4882a593Smuzhiyun 	result = ttusb_dec_send_command(dec, 0x41, sizeof(b0), b0, NULL, NULL);
1366*4882a593Smuzhiyun 
1367*4882a593Smuzhiyun 	if (result) {
1368*4882a593Smuzhiyun 		release_firmware(fw_entry);
1369*4882a593Smuzhiyun 		return result;
1370*4882a593Smuzhiyun 	}
1371*4882a593Smuzhiyun 
1372*4882a593Smuzhiyun 	trans_count = 0;
1373*4882a593Smuzhiyun 	j = 0;
1374*4882a593Smuzhiyun 
1375*4882a593Smuzhiyun 	b = kmalloc(ARM_PACKET_SIZE, GFP_KERNEL);
1376*4882a593Smuzhiyun 	if (b == NULL) {
1377*4882a593Smuzhiyun 		release_firmware(fw_entry);
1378*4882a593Smuzhiyun 		return -ENOMEM;
1379*4882a593Smuzhiyun 	}
1380*4882a593Smuzhiyun 
1381*4882a593Smuzhiyun 	for (i = 0; i < firmware_size; i += COMMAND_PACKET_SIZE) {
1382*4882a593Smuzhiyun 		size = firmware_size - i;
1383*4882a593Smuzhiyun 		if (size > COMMAND_PACKET_SIZE)
1384*4882a593Smuzhiyun 			size = COMMAND_PACKET_SIZE;
1385*4882a593Smuzhiyun 
1386*4882a593Smuzhiyun 		b[j + 0] = 0xaa;
1387*4882a593Smuzhiyun 		b[j + 1] = trans_count++;
1388*4882a593Smuzhiyun 		b[j + 2] = 0xf0;
1389*4882a593Smuzhiyun 		b[j + 3] = size;
1390*4882a593Smuzhiyun 		memcpy(&b[j + 4], &firmware[i], size);
1391*4882a593Smuzhiyun 
1392*4882a593Smuzhiyun 		j += COMMAND_PACKET_SIZE + 4;
1393*4882a593Smuzhiyun 
1394*4882a593Smuzhiyun 		if (j >= ARM_PACKET_SIZE) {
1395*4882a593Smuzhiyun 			result = usb_bulk_msg(dec->udev, dec->command_pipe, b,
1396*4882a593Smuzhiyun 					      ARM_PACKET_SIZE, &actual_len,
1397*4882a593Smuzhiyun 					      100);
1398*4882a593Smuzhiyun 			j = 0;
1399*4882a593Smuzhiyun 		} else if (size < COMMAND_PACKET_SIZE) {
1400*4882a593Smuzhiyun 			result = usb_bulk_msg(dec->udev, dec->command_pipe, b,
1401*4882a593Smuzhiyun 					      j - COMMAND_PACKET_SIZE + size,
1402*4882a593Smuzhiyun 					      &actual_len, 100);
1403*4882a593Smuzhiyun 		}
1404*4882a593Smuzhiyun 	}
1405*4882a593Smuzhiyun 
1406*4882a593Smuzhiyun 	result = ttusb_dec_send_command(dec, 0x43, sizeof(b1), b1, NULL, NULL);
1407*4882a593Smuzhiyun 
1408*4882a593Smuzhiyun 	release_firmware(fw_entry);
1409*4882a593Smuzhiyun 	kfree(b);
1410*4882a593Smuzhiyun 
1411*4882a593Smuzhiyun 	return result;
1412*4882a593Smuzhiyun }
1413*4882a593Smuzhiyun 
ttusb_dec_init_stb(struct ttusb_dec * dec)1414*4882a593Smuzhiyun static int ttusb_dec_init_stb(struct ttusb_dec *dec)
1415*4882a593Smuzhiyun {
1416*4882a593Smuzhiyun 	int result;
1417*4882a593Smuzhiyun 	unsigned int mode = 0, model = 0, version = 0;
1418*4882a593Smuzhiyun 
1419*4882a593Smuzhiyun 	dprintk("%s\n", __func__);
1420*4882a593Smuzhiyun 
1421*4882a593Smuzhiyun 	result = ttusb_dec_get_stb_state(dec, &mode, &model, &version);
1422*4882a593Smuzhiyun 	if (result)
1423*4882a593Smuzhiyun 		return result;
1424*4882a593Smuzhiyun 
1425*4882a593Smuzhiyun 	if (!mode) {
1426*4882a593Smuzhiyun 		if (version == 0xABCDEFAB)
1427*4882a593Smuzhiyun 			printk(KERN_INFO "ttusb_dec: no version info in Firmware\n");
1428*4882a593Smuzhiyun 		else
1429*4882a593Smuzhiyun 			printk(KERN_INFO "ttusb_dec: Firmware %x.%02x%c%c\n",
1430*4882a593Smuzhiyun 			       version >> 24, (version >> 16) & 0xff,
1431*4882a593Smuzhiyun 			       (version >> 8) & 0xff, version & 0xff);
1432*4882a593Smuzhiyun 
1433*4882a593Smuzhiyun 		result = ttusb_dec_boot_dsp(dec);
1434*4882a593Smuzhiyun 		if (result)
1435*4882a593Smuzhiyun 			return result;
1436*4882a593Smuzhiyun 	} else {
1437*4882a593Smuzhiyun 		/* We can't trust the USB IDs that some firmwares
1438*4882a593Smuzhiyun 		   give the box */
1439*4882a593Smuzhiyun 		switch (model) {
1440*4882a593Smuzhiyun 		case 0x00070001:
1441*4882a593Smuzhiyun 		case 0x00070008:
1442*4882a593Smuzhiyun 		case 0x0007000c:
1443*4882a593Smuzhiyun 			ttusb_dec_set_model(dec, TTUSB_DEC3000S);
1444*4882a593Smuzhiyun 			break;
1445*4882a593Smuzhiyun 		case 0x00070009:
1446*4882a593Smuzhiyun 		case 0x00070013:
1447*4882a593Smuzhiyun 			ttusb_dec_set_model(dec, TTUSB_DEC2000T);
1448*4882a593Smuzhiyun 			break;
1449*4882a593Smuzhiyun 		case 0x00070011:
1450*4882a593Smuzhiyun 			ttusb_dec_set_model(dec, TTUSB_DEC2540T);
1451*4882a593Smuzhiyun 			break;
1452*4882a593Smuzhiyun 		default:
1453*4882a593Smuzhiyun 			printk(KERN_ERR "%s: unknown model returned by firmware (%08x) - please report\n",
1454*4882a593Smuzhiyun 			       __func__, model);
1455*4882a593Smuzhiyun 			return -ENOENT;
1456*4882a593Smuzhiyun 		}
1457*4882a593Smuzhiyun 		if (version >= 0x01770000)
1458*4882a593Smuzhiyun 			dec->can_playback = 1;
1459*4882a593Smuzhiyun 	}
1460*4882a593Smuzhiyun 	return 0;
1461*4882a593Smuzhiyun }
1462*4882a593Smuzhiyun 
ttusb_dec_init_dvb(struct ttusb_dec * dec)1463*4882a593Smuzhiyun static int ttusb_dec_init_dvb(struct ttusb_dec *dec)
1464*4882a593Smuzhiyun {
1465*4882a593Smuzhiyun 	int result;
1466*4882a593Smuzhiyun 
1467*4882a593Smuzhiyun 	dprintk("%s\n", __func__);
1468*4882a593Smuzhiyun 
1469*4882a593Smuzhiyun 	if ((result = dvb_register_adapter(&dec->adapter,
1470*4882a593Smuzhiyun 					   dec->model_name, THIS_MODULE,
1471*4882a593Smuzhiyun 					   &dec->udev->dev,
1472*4882a593Smuzhiyun 					   adapter_nr)) < 0) {
1473*4882a593Smuzhiyun 		printk("%s: dvb_register_adapter failed: error %d\n",
1474*4882a593Smuzhiyun 		       __func__, result);
1475*4882a593Smuzhiyun 
1476*4882a593Smuzhiyun 		return result;
1477*4882a593Smuzhiyun 	}
1478*4882a593Smuzhiyun 
1479*4882a593Smuzhiyun 	dec->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
1480*4882a593Smuzhiyun 
1481*4882a593Smuzhiyun 	dec->demux.priv = (void *)dec;
1482*4882a593Smuzhiyun 	dec->demux.filternum = 31;
1483*4882a593Smuzhiyun 	dec->demux.feednum = 31;
1484*4882a593Smuzhiyun 	dec->demux.start_feed = ttusb_dec_start_feed;
1485*4882a593Smuzhiyun 	dec->demux.stop_feed = ttusb_dec_stop_feed;
1486*4882a593Smuzhiyun 	dec->demux.write_to_decoder = NULL;
1487*4882a593Smuzhiyun 
1488*4882a593Smuzhiyun 	if ((result = dvb_dmx_init(&dec->demux)) < 0) {
1489*4882a593Smuzhiyun 		printk("%s: dvb_dmx_init failed: error %d\n", __func__,
1490*4882a593Smuzhiyun 		       result);
1491*4882a593Smuzhiyun 
1492*4882a593Smuzhiyun 		dvb_unregister_adapter(&dec->adapter);
1493*4882a593Smuzhiyun 
1494*4882a593Smuzhiyun 		return result;
1495*4882a593Smuzhiyun 	}
1496*4882a593Smuzhiyun 
1497*4882a593Smuzhiyun 	dec->dmxdev.filternum = 32;
1498*4882a593Smuzhiyun 	dec->dmxdev.demux = &dec->demux.dmx;
1499*4882a593Smuzhiyun 	dec->dmxdev.capabilities = 0;
1500*4882a593Smuzhiyun 
1501*4882a593Smuzhiyun 	if ((result = dvb_dmxdev_init(&dec->dmxdev, &dec->adapter)) < 0) {
1502*4882a593Smuzhiyun 		printk("%s: dvb_dmxdev_init failed: error %d\n",
1503*4882a593Smuzhiyun 		       __func__, result);
1504*4882a593Smuzhiyun 
1505*4882a593Smuzhiyun 		dvb_dmx_release(&dec->demux);
1506*4882a593Smuzhiyun 		dvb_unregister_adapter(&dec->adapter);
1507*4882a593Smuzhiyun 
1508*4882a593Smuzhiyun 		return result;
1509*4882a593Smuzhiyun 	}
1510*4882a593Smuzhiyun 
1511*4882a593Smuzhiyun 	dec->frontend.source = DMX_FRONTEND_0;
1512*4882a593Smuzhiyun 
1513*4882a593Smuzhiyun 	if ((result = dec->demux.dmx.add_frontend(&dec->demux.dmx,
1514*4882a593Smuzhiyun 						  &dec->frontend)) < 0) {
1515*4882a593Smuzhiyun 		printk("%s: dvb_dmx_init failed: error %d\n", __func__,
1516*4882a593Smuzhiyun 		       result);
1517*4882a593Smuzhiyun 
1518*4882a593Smuzhiyun 		dvb_dmxdev_release(&dec->dmxdev);
1519*4882a593Smuzhiyun 		dvb_dmx_release(&dec->demux);
1520*4882a593Smuzhiyun 		dvb_unregister_adapter(&dec->adapter);
1521*4882a593Smuzhiyun 
1522*4882a593Smuzhiyun 		return result;
1523*4882a593Smuzhiyun 	}
1524*4882a593Smuzhiyun 
1525*4882a593Smuzhiyun 	if ((result = dec->demux.dmx.connect_frontend(&dec->demux.dmx,
1526*4882a593Smuzhiyun 						      &dec->frontend)) < 0) {
1527*4882a593Smuzhiyun 		printk("%s: dvb_dmx_init failed: error %d\n", __func__,
1528*4882a593Smuzhiyun 		       result);
1529*4882a593Smuzhiyun 
1530*4882a593Smuzhiyun 		dec->demux.dmx.remove_frontend(&dec->demux.dmx, &dec->frontend);
1531*4882a593Smuzhiyun 		dvb_dmxdev_release(&dec->dmxdev);
1532*4882a593Smuzhiyun 		dvb_dmx_release(&dec->demux);
1533*4882a593Smuzhiyun 		dvb_unregister_adapter(&dec->adapter);
1534*4882a593Smuzhiyun 
1535*4882a593Smuzhiyun 		return result;
1536*4882a593Smuzhiyun 	}
1537*4882a593Smuzhiyun 
1538*4882a593Smuzhiyun 	dvb_net_init(&dec->adapter, &dec->dvb_net, &dec->demux.dmx);
1539*4882a593Smuzhiyun 
1540*4882a593Smuzhiyun 	return 0;
1541*4882a593Smuzhiyun }
1542*4882a593Smuzhiyun 
ttusb_dec_exit_dvb(struct ttusb_dec * dec)1543*4882a593Smuzhiyun static void ttusb_dec_exit_dvb(struct ttusb_dec *dec)
1544*4882a593Smuzhiyun {
1545*4882a593Smuzhiyun 	dprintk("%s\n", __func__);
1546*4882a593Smuzhiyun 
1547*4882a593Smuzhiyun 	dvb_net_release(&dec->dvb_net);
1548*4882a593Smuzhiyun 	dec->demux.dmx.close(&dec->demux.dmx);
1549*4882a593Smuzhiyun 	dec->demux.dmx.remove_frontend(&dec->demux.dmx, &dec->frontend);
1550*4882a593Smuzhiyun 	dvb_dmxdev_release(&dec->dmxdev);
1551*4882a593Smuzhiyun 	dvb_dmx_release(&dec->demux);
1552*4882a593Smuzhiyun 	if (dec->fe) {
1553*4882a593Smuzhiyun 		dvb_unregister_frontend(dec->fe);
1554*4882a593Smuzhiyun 		if (dec->fe->ops.release)
1555*4882a593Smuzhiyun 			dec->fe->ops.release(dec->fe);
1556*4882a593Smuzhiyun 	}
1557*4882a593Smuzhiyun 	dvb_unregister_adapter(&dec->adapter);
1558*4882a593Smuzhiyun }
1559*4882a593Smuzhiyun 
ttusb_dec_exit_rc(struct ttusb_dec * dec)1560*4882a593Smuzhiyun static void ttusb_dec_exit_rc(struct ttusb_dec *dec)
1561*4882a593Smuzhiyun {
1562*4882a593Smuzhiyun 	dprintk("%s\n", __func__);
1563*4882a593Smuzhiyun 
1564*4882a593Smuzhiyun 	if (dec->rc_input_dev) {
1565*4882a593Smuzhiyun 		input_unregister_device(dec->rc_input_dev);
1566*4882a593Smuzhiyun 		dec->rc_input_dev = NULL;
1567*4882a593Smuzhiyun 	}
1568*4882a593Smuzhiyun }
1569*4882a593Smuzhiyun 
1570*4882a593Smuzhiyun 
ttusb_dec_exit_usb(struct ttusb_dec * dec)1571*4882a593Smuzhiyun static void ttusb_dec_exit_usb(struct ttusb_dec *dec)
1572*4882a593Smuzhiyun {
1573*4882a593Smuzhiyun 	int i;
1574*4882a593Smuzhiyun 
1575*4882a593Smuzhiyun 	dprintk("%s\n", __func__);
1576*4882a593Smuzhiyun 
1577*4882a593Smuzhiyun 	if (enable_rc) {
1578*4882a593Smuzhiyun 		/* we have to check whether the irq URB is already submitted.
1579*4882a593Smuzhiyun 		 * As the irq is submitted after the interface is changed,
1580*4882a593Smuzhiyun 		 * this is the best method i figured out.
1581*4882a593Smuzhiyun 		 * Any others?*/
1582*4882a593Smuzhiyun 		if (dec->interface == TTUSB_DEC_INTERFACE_IN)
1583*4882a593Smuzhiyun 			usb_kill_urb(dec->irq_urb);
1584*4882a593Smuzhiyun 
1585*4882a593Smuzhiyun 		usb_free_urb(dec->irq_urb);
1586*4882a593Smuzhiyun 
1587*4882a593Smuzhiyun 		usb_free_coherent(dec->udev, IRQ_PACKET_SIZE,
1588*4882a593Smuzhiyun 				  dec->irq_buffer, dec->irq_dma_handle);
1589*4882a593Smuzhiyun 	}
1590*4882a593Smuzhiyun 
1591*4882a593Smuzhiyun 	dec->iso_stream_count = 0;
1592*4882a593Smuzhiyun 
1593*4882a593Smuzhiyun 	for (i = 0; i < ISO_BUF_COUNT; i++)
1594*4882a593Smuzhiyun 		usb_kill_urb(dec->iso_urb[i]);
1595*4882a593Smuzhiyun 
1596*4882a593Smuzhiyun 	ttusb_dec_free_iso_urbs(dec);
1597*4882a593Smuzhiyun }
1598*4882a593Smuzhiyun 
ttusb_dec_exit_tasklet(struct ttusb_dec * dec)1599*4882a593Smuzhiyun static void ttusb_dec_exit_tasklet(struct ttusb_dec *dec)
1600*4882a593Smuzhiyun {
1601*4882a593Smuzhiyun 	struct list_head *item;
1602*4882a593Smuzhiyun 	struct urb_frame *frame;
1603*4882a593Smuzhiyun 
1604*4882a593Smuzhiyun 	tasklet_kill(&dec->urb_tasklet);
1605*4882a593Smuzhiyun 
1606*4882a593Smuzhiyun 	while ((item = dec->urb_frame_list.next) != &dec->urb_frame_list) {
1607*4882a593Smuzhiyun 		frame = list_entry(item, struct urb_frame, urb_frame_list);
1608*4882a593Smuzhiyun 		list_del(&frame->urb_frame_list);
1609*4882a593Smuzhiyun 		kfree(frame);
1610*4882a593Smuzhiyun 	}
1611*4882a593Smuzhiyun }
1612*4882a593Smuzhiyun 
ttusb_dec_init_filters(struct ttusb_dec * dec)1613*4882a593Smuzhiyun static void ttusb_dec_init_filters(struct ttusb_dec *dec)
1614*4882a593Smuzhiyun {
1615*4882a593Smuzhiyun 	INIT_LIST_HEAD(&dec->filter_info_list);
1616*4882a593Smuzhiyun 	spin_lock_init(&dec->filter_info_list_lock);
1617*4882a593Smuzhiyun }
1618*4882a593Smuzhiyun 
ttusb_dec_exit_filters(struct ttusb_dec * dec)1619*4882a593Smuzhiyun static void ttusb_dec_exit_filters(struct ttusb_dec *dec)
1620*4882a593Smuzhiyun {
1621*4882a593Smuzhiyun 	struct list_head *item;
1622*4882a593Smuzhiyun 	struct filter_info *finfo;
1623*4882a593Smuzhiyun 
1624*4882a593Smuzhiyun 	while ((item = dec->filter_info_list.next) != &dec->filter_info_list) {
1625*4882a593Smuzhiyun 		finfo = list_entry(item, struct filter_info, filter_info_list);
1626*4882a593Smuzhiyun 		list_del(&finfo->filter_info_list);
1627*4882a593Smuzhiyun 		kfree(finfo);
1628*4882a593Smuzhiyun 	}
1629*4882a593Smuzhiyun }
1630*4882a593Smuzhiyun 
fe_send_command(struct dvb_frontend * fe,const u8 command,int param_length,const u8 params[],int * result_length,u8 cmd_result[])1631*4882a593Smuzhiyun static int fe_send_command(struct dvb_frontend* fe, const u8 command,
1632*4882a593Smuzhiyun 			   int param_length, const u8 params[],
1633*4882a593Smuzhiyun 			   int *result_length, u8 cmd_result[])
1634*4882a593Smuzhiyun {
1635*4882a593Smuzhiyun 	struct ttusb_dec* dec = fe->dvb->priv;
1636*4882a593Smuzhiyun 	return ttusb_dec_send_command(dec, command, param_length, params, result_length, cmd_result);
1637*4882a593Smuzhiyun }
1638*4882a593Smuzhiyun 
1639*4882a593Smuzhiyun static const struct ttusbdecfe_config fe_config = {
1640*4882a593Smuzhiyun 	.send_command = fe_send_command
1641*4882a593Smuzhiyun };
1642*4882a593Smuzhiyun 
ttusb_dec_probe(struct usb_interface * intf,const struct usb_device_id * id)1643*4882a593Smuzhiyun static int ttusb_dec_probe(struct usb_interface *intf,
1644*4882a593Smuzhiyun 			   const struct usb_device_id *id)
1645*4882a593Smuzhiyun {
1646*4882a593Smuzhiyun 	struct usb_device *udev;
1647*4882a593Smuzhiyun 	struct ttusb_dec *dec;
1648*4882a593Smuzhiyun 	int result;
1649*4882a593Smuzhiyun 
1650*4882a593Smuzhiyun 	dprintk("%s\n", __func__);
1651*4882a593Smuzhiyun 
1652*4882a593Smuzhiyun 	udev = interface_to_usbdev(intf);
1653*4882a593Smuzhiyun 
1654*4882a593Smuzhiyun 	if (!(dec = kzalloc(sizeof(struct ttusb_dec), GFP_KERNEL))) {
1655*4882a593Smuzhiyun 		printk("%s: couldn't allocate memory.\n", __func__);
1656*4882a593Smuzhiyun 		return -ENOMEM;
1657*4882a593Smuzhiyun 	}
1658*4882a593Smuzhiyun 
1659*4882a593Smuzhiyun 	usb_set_intfdata(intf, (void *)dec);
1660*4882a593Smuzhiyun 
1661*4882a593Smuzhiyun 	switch (id->idProduct) {
1662*4882a593Smuzhiyun 	case 0x1006:
1663*4882a593Smuzhiyun 		ttusb_dec_set_model(dec, TTUSB_DEC3000S);
1664*4882a593Smuzhiyun 		break;
1665*4882a593Smuzhiyun 
1666*4882a593Smuzhiyun 	case 0x1008:
1667*4882a593Smuzhiyun 		ttusb_dec_set_model(dec, TTUSB_DEC2000T);
1668*4882a593Smuzhiyun 		break;
1669*4882a593Smuzhiyun 
1670*4882a593Smuzhiyun 	case 0x1009:
1671*4882a593Smuzhiyun 		ttusb_dec_set_model(dec, TTUSB_DEC2540T);
1672*4882a593Smuzhiyun 		break;
1673*4882a593Smuzhiyun 	}
1674*4882a593Smuzhiyun 
1675*4882a593Smuzhiyun 	dec->udev = udev;
1676*4882a593Smuzhiyun 
1677*4882a593Smuzhiyun 	result = ttusb_dec_init_usb(dec);
1678*4882a593Smuzhiyun 	if (result)
1679*4882a593Smuzhiyun 		goto err_usb;
1680*4882a593Smuzhiyun 	result = ttusb_dec_init_stb(dec);
1681*4882a593Smuzhiyun 	if (result)
1682*4882a593Smuzhiyun 		goto err_stb;
1683*4882a593Smuzhiyun 	result = ttusb_dec_init_dvb(dec);
1684*4882a593Smuzhiyun 	if (result)
1685*4882a593Smuzhiyun 		goto err_stb;
1686*4882a593Smuzhiyun 
1687*4882a593Smuzhiyun 	dec->adapter.priv = dec;
1688*4882a593Smuzhiyun 	switch (id->idProduct) {
1689*4882a593Smuzhiyun 	case 0x1006:
1690*4882a593Smuzhiyun 		dec->fe = ttusbdecfe_dvbs_attach(&fe_config);
1691*4882a593Smuzhiyun 		break;
1692*4882a593Smuzhiyun 
1693*4882a593Smuzhiyun 	case 0x1008:
1694*4882a593Smuzhiyun 	case 0x1009:
1695*4882a593Smuzhiyun 		dec->fe = ttusbdecfe_dvbt_attach(&fe_config);
1696*4882a593Smuzhiyun 		break;
1697*4882a593Smuzhiyun 	}
1698*4882a593Smuzhiyun 
1699*4882a593Smuzhiyun 	if (dec->fe == NULL) {
1700*4882a593Smuzhiyun 		printk("dvb-ttusb-dec: A frontend driver was not found for device [%04x:%04x]\n",
1701*4882a593Smuzhiyun 		       le16_to_cpu(dec->udev->descriptor.idVendor),
1702*4882a593Smuzhiyun 		       le16_to_cpu(dec->udev->descriptor.idProduct));
1703*4882a593Smuzhiyun 	} else {
1704*4882a593Smuzhiyun 		if (dvb_register_frontend(&dec->adapter, dec->fe)) {
1705*4882a593Smuzhiyun 			printk("budget-ci: Frontend registration failed!\n");
1706*4882a593Smuzhiyun 			if (dec->fe->ops.release)
1707*4882a593Smuzhiyun 				dec->fe->ops.release(dec->fe);
1708*4882a593Smuzhiyun 			dec->fe = NULL;
1709*4882a593Smuzhiyun 		}
1710*4882a593Smuzhiyun 	}
1711*4882a593Smuzhiyun 
1712*4882a593Smuzhiyun 	ttusb_dec_init_v_pes(dec);
1713*4882a593Smuzhiyun 	ttusb_dec_init_filters(dec);
1714*4882a593Smuzhiyun 	ttusb_dec_init_tasklet(dec);
1715*4882a593Smuzhiyun 
1716*4882a593Smuzhiyun 	dec->active = 1;
1717*4882a593Smuzhiyun 
1718*4882a593Smuzhiyun 	ttusb_dec_set_interface(dec, TTUSB_DEC_INTERFACE_IN);
1719*4882a593Smuzhiyun 
1720*4882a593Smuzhiyun 	if (enable_rc)
1721*4882a593Smuzhiyun 		ttusb_init_rc(dec);
1722*4882a593Smuzhiyun 
1723*4882a593Smuzhiyun 	return 0;
1724*4882a593Smuzhiyun err_stb:
1725*4882a593Smuzhiyun 	ttusb_dec_exit_usb(dec);
1726*4882a593Smuzhiyun err_usb:
1727*4882a593Smuzhiyun 	kfree(dec);
1728*4882a593Smuzhiyun 	return result;
1729*4882a593Smuzhiyun }
1730*4882a593Smuzhiyun 
ttusb_dec_disconnect(struct usb_interface * intf)1731*4882a593Smuzhiyun static void ttusb_dec_disconnect(struct usb_interface *intf)
1732*4882a593Smuzhiyun {
1733*4882a593Smuzhiyun 	struct ttusb_dec *dec = usb_get_intfdata(intf);
1734*4882a593Smuzhiyun 
1735*4882a593Smuzhiyun 	usb_set_intfdata(intf, NULL);
1736*4882a593Smuzhiyun 
1737*4882a593Smuzhiyun 	dprintk("%s\n", __func__);
1738*4882a593Smuzhiyun 
1739*4882a593Smuzhiyun 	if (dec->active) {
1740*4882a593Smuzhiyun 		ttusb_dec_exit_tasklet(dec);
1741*4882a593Smuzhiyun 		ttusb_dec_exit_filters(dec);
1742*4882a593Smuzhiyun 		if(enable_rc)
1743*4882a593Smuzhiyun 			ttusb_dec_exit_rc(dec);
1744*4882a593Smuzhiyun 		ttusb_dec_exit_usb(dec);
1745*4882a593Smuzhiyun 		ttusb_dec_exit_dvb(dec);
1746*4882a593Smuzhiyun 	}
1747*4882a593Smuzhiyun 
1748*4882a593Smuzhiyun 	kfree(dec);
1749*4882a593Smuzhiyun }
1750*4882a593Smuzhiyun 
ttusb_dec_set_model(struct ttusb_dec * dec,enum ttusb_dec_model model)1751*4882a593Smuzhiyun static void ttusb_dec_set_model(struct ttusb_dec *dec,
1752*4882a593Smuzhiyun 				enum ttusb_dec_model model)
1753*4882a593Smuzhiyun {
1754*4882a593Smuzhiyun 	dec->model = model;
1755*4882a593Smuzhiyun 
1756*4882a593Smuzhiyun 	switch (model) {
1757*4882a593Smuzhiyun 	case TTUSB_DEC2000T:
1758*4882a593Smuzhiyun 		dec->model_name = "DEC2000-t";
1759*4882a593Smuzhiyun 		dec->firmware_name = "dvb-ttusb-dec-2000t.fw";
1760*4882a593Smuzhiyun 		break;
1761*4882a593Smuzhiyun 
1762*4882a593Smuzhiyun 	case TTUSB_DEC2540T:
1763*4882a593Smuzhiyun 		dec->model_name = "DEC2540-t";
1764*4882a593Smuzhiyun 		dec->firmware_name = "dvb-ttusb-dec-2540t.fw";
1765*4882a593Smuzhiyun 		break;
1766*4882a593Smuzhiyun 
1767*4882a593Smuzhiyun 	case TTUSB_DEC3000S:
1768*4882a593Smuzhiyun 		dec->model_name = "DEC3000-s";
1769*4882a593Smuzhiyun 		dec->firmware_name = "dvb-ttusb-dec-3000s.fw";
1770*4882a593Smuzhiyun 		break;
1771*4882a593Smuzhiyun 	}
1772*4882a593Smuzhiyun }
1773*4882a593Smuzhiyun 
1774*4882a593Smuzhiyun static const struct usb_device_id ttusb_dec_table[] = {
1775*4882a593Smuzhiyun 	{USB_DEVICE(0x0b48, 0x1006)},	/* DEC3000-s */
1776*4882a593Smuzhiyun 	/*{USB_DEVICE(0x0b48, 0x1007)},	   Unconfirmed */
1777*4882a593Smuzhiyun 	{USB_DEVICE(0x0b48, 0x1008)},	/* DEC2000-t */
1778*4882a593Smuzhiyun 	{USB_DEVICE(0x0b48, 0x1009)},	/* DEC2540-t */
1779*4882a593Smuzhiyun 	{}
1780*4882a593Smuzhiyun };
1781*4882a593Smuzhiyun 
1782*4882a593Smuzhiyun static struct usb_driver ttusb_dec_driver = {
1783*4882a593Smuzhiyun 	.name		= "ttusb-dec",
1784*4882a593Smuzhiyun 	.probe		= ttusb_dec_probe,
1785*4882a593Smuzhiyun 	.disconnect	= ttusb_dec_disconnect,
1786*4882a593Smuzhiyun 	.id_table	= ttusb_dec_table,
1787*4882a593Smuzhiyun };
1788*4882a593Smuzhiyun 
1789*4882a593Smuzhiyun module_usb_driver(ttusb_dec_driver);
1790*4882a593Smuzhiyun 
1791*4882a593Smuzhiyun MODULE_AUTHOR("Alex Woods <linux-dvb@giblets.org>");
1792*4882a593Smuzhiyun MODULE_DESCRIPTION(DRIVER_NAME);
1793*4882a593Smuzhiyun MODULE_LICENSE("GPL");
1794*4882a593Smuzhiyun MODULE_DEVICE_TABLE(usb, ttusb_dec_table);
1795