blob: cf264512d36feecb95f59dc2726f875c83c99fcb [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * TTUSB DVB driver
3 *
4 * Copyright (c) 2002 Holger Waechtler <holger@convergence.de>
5 * Copyright (c) 2003 Felix Domke <tmbinc@elitedvb.net>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version.
11 */
12#include <linux/init.h>
13#include <linux/slab.h>
14#include <linux/wait.h>
15#include <linux/module.h>
16#include <linux/moduleparam.h>
17#include <linux/usb.h>
18#include <linux/delay.h>
19#include <linux/time.h>
20#include <linux/errno.h>
Marcelo Feitoza Parisi4da006c2005-09-09 13:03:15 -070021#include <linux/jiffies.h>
Ingo Molnar3593cab2006-02-07 06:49:14 -020022#include <linux/mutex.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070023
24#include "dvb_frontend.h"
25#include "dmxdev.h"
26#include "dvb_demux.h"
27#include "dvb_net.h"
Gavin Hamill53936392005-07-07 17:58:04 -070028#include "ves1820.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070029#include "cx22700.h"
30#include "tda1004x.h"
31#include "stv0299.h"
32#include "tda8083.h"
Thomas Kaiserb8d4c232006-04-27 21:45:20 -030033#include "stv0297.h"
Andrew de Quinceyd0205422006-04-27 21:45:01 -030034#include "lnbp21.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070035
36#include <linux/dvb/frontend.h>
37#include <linux/dvb/dmx.h>
38#include <linux/pci.h>
39
Linus Torvalds1da177e2005-04-16 15:20:36 -070040/*
41 TTUSB_HWSECTIONS:
42 the DSP supports filtering in hardware, however, since the "muxstream"
43 is a bit braindead (no matching channel masks or no matching filter mask),
44 we won't support this - yet. it doesn't event support negative filters,
45 so the best way is maybe to keep TTUSB_HWSECTIONS undef'd and just
46 parse TS data. USB bandwith will be a problem when having large
47 datastreams, especially for dvb-net, but hey, that's not my problem.
48
49 TTUSB_DISEQC, TTUSB_TONE:
50 let the STC do the diseqc/tone stuff. this isn't supported at least with
51 my TTUSB, so let it undef'd unless you want to implement another
52 frontend. never tested.
53
54 DEBUG:
55 define it to > 3 for really hardcore debugging. you probably don't want
56 this unless the device doesn't load at all. > 2 for bandwidth statistics.
57*/
58
59static int debug;
60
61module_param(debug, int, 0644);
62MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
63
64#define dprintk(x...) do { if (debug) printk(KERN_DEBUG x); } while (0)
65
66#define ISO_BUF_COUNT 4
67#define FRAMES_PER_ISO_BUF 4
68#define ISO_FRAME_SIZE 912
69#define TTUSB_MAXCHANNEL 32
70#ifdef TTUSB_HWSECTIONS
71#define TTUSB_MAXFILTER 16 /* ??? */
72#endif
73
74#define TTUSB_REV_2_2 0x22
75#define TTUSB_BUDGET_NAME "ttusb_stc_fw"
76
77/**
78 * since we're casting (struct ttusb*) <-> (struct dvb_demux*) around
79 * the dvb_demux field must be the first in struct!!
80 */
81struct ttusb {
82 struct dvb_demux dvb_demux;
83 struct dmxdev dmxdev;
84 struct dvb_net dvbnet;
85
86 /* and one for USB access. */
Ingo Molnar3593cab2006-02-07 06:49:14 -020087 struct mutex semi2c;
88 struct mutex semusb;
Linus Torvalds1da177e2005-04-16 15:20:36 -070089
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -070090 struct dvb_adapter adapter;
Linus Torvalds1da177e2005-04-16 15:20:36 -070091 struct usb_device *dev;
92
93 struct i2c_adapter i2c_adap;
94
95 int disconnecting;
96 int iso_streaming;
97
98 unsigned int bulk_out_pipe;
99 unsigned int bulk_in_pipe;
100 unsigned int isoc_in_pipe;
101
102 void *iso_buffer;
103 dma_addr_t iso_dma_handle;
104
105 struct urb *iso_urb[ISO_BUF_COUNT];
106
107 int running_feed_count;
108 int last_channel;
109 int last_filter;
110
111 u8 c; /* transaction counter, wraps around... */
112 fe_sec_tone_mode_t tone;
113 fe_sec_voltage_t voltage;
114
115 int mux_state; // 0..2 - MuxSyncWord, 3 - nMuxPacks, 4 - muxpack
116 u8 mux_npacks;
117 u8 muxpack[256 + 8];
118 int muxpack_ptr, muxpack_len;
119
120 int insync;
121
122 int cc; /* MuxCounter - will increment on EVERY MUX PACKET */
123 /* (including stuffing. yes. really.) */
124
125 u8 last_result[32];
126
127 int revision;
128
129#if 0
130 devfs_handle_t stc_devfs_handle;
131#endif
132
133 struct dvb_frontend* fe;
134};
135
136/* ugly workaround ... don't know why it's neccessary to read */
137/* all result codes. */
138
139#define DEBUG 0
140static int ttusb_cmd(struct ttusb *ttusb,
141 const u8 * data, int len, int needresult)
142{
143 int actual_len;
144 int err;
145#if DEBUG >= 3
146 int i;
147
148 printk(">");
149 for (i = 0; i < len; ++i)
150 printk(" %02x", data[i]);
151 printk("\n");
152#endif
153
Ingo Molnar3593cab2006-02-07 06:49:14 -0200154 if (mutex_lock_interruptible(&ttusb->semusb) < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700155 return -EAGAIN;
156
157 err = usb_bulk_msg(ttusb->dev, ttusb->bulk_out_pipe,
158 (u8 *) data, len, &actual_len, 1000);
159 if (err != 0) {
160 dprintk("%s: usb_bulk_msg(send) failed, err == %i!\n",
161 __FUNCTION__, err);
Ingo Molnar3593cab2006-02-07 06:49:14 -0200162 mutex_unlock(&ttusb->semusb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700163 return err;
164 }
165 if (actual_len != len) {
166 dprintk("%s: only wrote %d of %d bytes\n", __FUNCTION__,
167 actual_len, len);
Ingo Molnar3593cab2006-02-07 06:49:14 -0200168 mutex_unlock(&ttusb->semusb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700169 return -1;
170 }
171
172 err = usb_bulk_msg(ttusb->dev, ttusb->bulk_in_pipe,
173 ttusb->last_result, 32, &actual_len, 1000);
174
175 if (err != 0) {
176 printk("%s: failed, receive error %d\n", __FUNCTION__,
177 err);
Ingo Molnar3593cab2006-02-07 06:49:14 -0200178 mutex_unlock(&ttusb->semusb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700179 return err;
180 }
181#if DEBUG >= 3
182 actual_len = ttusb->last_result[3] + 4;
183 printk("<");
184 for (i = 0; i < actual_len; ++i)
185 printk(" %02x", ttusb->last_result[i]);
186 printk("\n");
187#endif
188 if (!needresult)
Ingo Molnar3593cab2006-02-07 06:49:14 -0200189 mutex_unlock(&ttusb->semusb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700190 return 0;
191}
192
193static int ttusb_result(struct ttusb *ttusb, u8 * data, int len)
194{
195 memcpy(data, ttusb->last_result, len);
Ingo Molnar3593cab2006-02-07 06:49:14 -0200196 mutex_unlock(&ttusb->semusb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700197 return 0;
198}
199
200static int ttusb_i2c_msg(struct ttusb *ttusb,
201 u8 addr, u8 * snd_buf, u8 snd_len, u8 * rcv_buf,
202 u8 rcv_len)
203{
204 u8 b[0x28];
205 u8 id = ++ttusb->c;
206 int i, err;
207
208 if (snd_len > 0x28 - 7 || rcv_len > 0x20 - 7)
209 return -EINVAL;
210
211 b[0] = 0xaa;
212 b[1] = id;
213 b[2] = 0x31;
214 b[3] = snd_len + 3;
215 b[4] = addr << 1;
216 b[5] = snd_len;
217 b[6] = rcv_len;
218
219 for (i = 0; i < snd_len; i++)
220 b[7 + i] = snd_buf[i];
221
222 err = ttusb_cmd(ttusb, b, snd_len + 7, 1);
223
224 if (err)
225 return -EREMOTEIO;
226
227 err = ttusb_result(ttusb, b, 0x20);
228
Mauro Carvalho Chehab9101e622005-12-12 00:37:24 -0800229 /* check if the i2c transaction was successful */
230 if ((snd_len != b[5]) || (rcv_len != b[6])) return -EREMOTEIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700231
232 if (rcv_len > 0) {
233
234 if (err || b[0] != 0x55 || b[1] != id) {
235 dprintk
236 ("%s: usb_bulk_msg(recv) failed, err == %i, id == %02x, b == ",
237 __FUNCTION__, err, id);
238 return -EREMOTEIO;
239 }
240
241 for (i = 0; i < rcv_len; i++)
242 rcv_buf[i] = b[7 + i];
243 }
244
245 return rcv_len;
246}
247
248static int master_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, int num)
249{
250 struct ttusb *ttusb = i2c_get_adapdata(adapter);
251 int i = 0;
252 int inc;
253
Ingo Molnar3593cab2006-02-07 06:49:14 -0200254 if (mutex_lock_interruptible(&ttusb->semi2c) < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700255 return -EAGAIN;
256
257 while (i < num) {
258 u8 addr, snd_len, rcv_len, *snd_buf, *rcv_buf;
259 int err;
260
261 if (num > i + 1 && (msg[i + 1].flags & I2C_M_RD)) {
262 addr = msg[i].addr;
263 snd_buf = msg[i].buf;
264 snd_len = msg[i].len;
265 rcv_buf = msg[i + 1].buf;
266 rcv_len = msg[i + 1].len;
267 inc = 2;
268 } else {
269 addr = msg[i].addr;
270 snd_buf = msg[i].buf;
271 snd_len = msg[i].len;
272 rcv_buf = NULL;
273 rcv_len = 0;
274 inc = 1;
275 }
276
277 err = ttusb_i2c_msg(ttusb, addr,
278 snd_buf, snd_len, rcv_buf, rcv_len);
279
280 if (err < rcv_len) {
281 dprintk("%s: i == %i\n", __FUNCTION__, i);
282 break;
283 }
284
285 i += inc;
286 }
287
Ingo Molnar3593cab2006-02-07 06:49:14 -0200288 mutex_unlock(&ttusb->semi2c);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700289 return i;
290}
291
292#include "dvb-ttusb-dspbootcode.h"
293
294static int ttusb_boot_dsp(struct ttusb *ttusb)
295{
296 int i, err;
297 u8 b[40];
298
299 /* BootBlock */
300 b[0] = 0xaa;
301 b[2] = 0x13;
302 b[3] = 28;
303
304 /* upload dsp code in 32 byte steps (36 didn't work for me ...) */
305 /* 32 is max packet size, no messages should be splitted. */
306 for (i = 0; i < sizeof(dsp_bootcode); i += 28) {
307 memcpy(&b[4], &dsp_bootcode[i], 28);
308
309 b[1] = ++ttusb->c;
310
311 err = ttusb_cmd(ttusb, b, 32, 0);
312 if (err)
313 goto done;
314 }
315
316 /* last block ... */
317 b[1] = ++ttusb->c;
318 b[2] = 0x13;
319 b[3] = 0;
320
321 err = ttusb_cmd(ttusb, b, 4, 0);
322 if (err)
323 goto done;
324
325 /* BootEnd */
326 b[1] = ++ttusb->c;
327 b[2] = 0x14;
328 b[3] = 0;
329
330 err = ttusb_cmd(ttusb, b, 4, 0);
331
332 done:
333 if (err) {
334 dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
335 __FUNCTION__, err);
336 }
337
338 return err;
339}
340
341static int ttusb_set_channel(struct ttusb *ttusb, int chan_id, int filter_type,
342 int pid)
343{
344 int err;
345 /* SetChannel */
346 u8 b[] = { 0xaa, ++ttusb->c, 0x22, 4, chan_id, filter_type,
347 (pid >> 8) & 0xff, pid & 0xff
348 };
349
350 err = ttusb_cmd(ttusb, b, sizeof(b), 0);
351 return err;
352}
353
354static int ttusb_del_channel(struct ttusb *ttusb, int channel_id)
355{
356 int err;
357 /* DelChannel */
358 u8 b[] = { 0xaa, ++ttusb->c, 0x23, 1, channel_id };
359
360 err = ttusb_cmd(ttusb, b, sizeof(b), 0);
361 return err;
362}
363
364#ifdef TTUSB_HWSECTIONS
365static int ttusb_set_filter(struct ttusb *ttusb, int filter_id,
366 int associated_chan, u8 filter[8], u8 mask[8])
367{
368 int err;
369 /* SetFilter */
370 u8 b[] = { 0xaa, 0, 0x24, 0x1a, filter_id, associated_chan,
371 filter[0], filter[1], filter[2], filter[3],
372 filter[4], filter[5], filter[6], filter[7],
373 filter[8], filter[9], filter[10], filter[11],
374 mask[0], mask[1], mask[2], mask[3],
375 mask[4], mask[5], mask[6], mask[7],
376 mask[8], mask[9], mask[10], mask[11]
377 };
378
379 err = ttusb_cmd(ttusb, b, sizeof(b), 0);
380 return err;
381}
382
383static int ttusb_del_filter(struct ttusb *ttusb, int filter_id)
384{
385 int err;
386 /* DelFilter */
387 u8 b[] = { 0xaa, ++ttusb->c, 0x25, 1, filter_id };
388
389 err = ttusb_cmd(ttusb, b, sizeof(b), 0);
390 return err;
391}
392#endif
393
394static int ttusb_init_controller(struct ttusb *ttusb)
395{
396 u8 b0[] = { 0xaa, ++ttusb->c, 0x15, 1, 0 };
397 u8 b1[] = { 0xaa, ++ttusb->c, 0x15, 1, 1 };
398 u8 b2[] = { 0xaa, ++ttusb->c, 0x32, 1, 0 };
399 /* i2c write read: 5 bytes, addr 0x10, 0x02 bytes write, 1 bytes read. */
400 u8 b3[] =
401 { 0xaa, ++ttusb->c, 0x31, 5, 0x10, 0x02, 0x01, 0x00, 0x1e };
402 u8 b4[] =
403 { 0x55, ttusb->c, 0x31, 4, 0x10, 0x02, 0x01, 0x00, 0x1e };
404
405 u8 get_version[] = { 0xaa, ++ttusb->c, 0x17, 5, 0, 0, 0, 0, 0 };
406 u8 get_dsp_version[0x20] =
407 { 0xaa, ++ttusb->c, 0x26, 28, 0, 0, 0, 0, 0 };
408 int err;
409
410 /* reset board */
411 if ((err = ttusb_cmd(ttusb, b0, sizeof(b0), 0)))
412 return err;
413
414 /* reset board (again?) */
415 if ((err = ttusb_cmd(ttusb, b1, sizeof(b1), 0)))
416 return err;
417
418 ttusb_boot_dsp(ttusb);
419
420 /* set i2c bit rate */
421 if ((err = ttusb_cmd(ttusb, b2, sizeof(b2), 0)))
422 return err;
423
424 if ((err = ttusb_cmd(ttusb, b3, sizeof(b3), 1)))
425 return err;
426
427 err = ttusb_result(ttusb, b4, sizeof(b4));
428
429 if ((err = ttusb_cmd(ttusb, get_version, sizeof(get_version), 1)))
430 return err;
431
432 if ((err = ttusb_result(ttusb, get_version, sizeof(get_version))))
433 return err;
434
435 dprintk("%s: stc-version: %c%c%c%c%c\n", __FUNCTION__,
436 get_version[4], get_version[5], get_version[6],
437 get_version[7], get_version[8]);
438
439 if (memcmp(get_version + 4, "V 0.0", 5) &&
440 memcmp(get_version + 4, "V 1.1", 5) &&
441 memcmp(get_version + 4, "V 2.1", 5) &&
442 memcmp(get_version + 4, "V 2.2", 5)) {
443 printk
444 ("%s: unknown STC version %c%c%c%c%c, please report!\n",
445 __FUNCTION__, get_version[4], get_version[5],
446 get_version[6], get_version[7], get_version[8]);
447 }
448
449 ttusb->revision = ((get_version[6] - '0') << 4) |
450 (get_version[8] - '0');
451
452 err =
453 ttusb_cmd(ttusb, get_dsp_version, sizeof(get_dsp_version), 1);
454 if (err)
455 return err;
456
457 err =
458 ttusb_result(ttusb, get_dsp_version, sizeof(get_dsp_version));
459 if (err)
460 return err;
461 printk("%s: dsp-version: %c%c%c\n", __FUNCTION__,
462 get_dsp_version[4], get_dsp_version[5], get_dsp_version[6]);
463 return 0;
464}
465
466#ifdef TTUSB_DISEQC
467static int ttusb_send_diseqc(struct dvb_frontend* fe,
468 const struct dvb_diseqc_master_cmd *cmd)
469{
470 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
471 u8 b[12] = { 0xaa, ++ttusb->c, 0x18 };
472
473 int err;
474
475 b[3] = 4 + 2 + cmd->msg_len;
476 b[4] = 0xFF; /* send diseqc master, not burst */
477 b[5] = cmd->msg_len;
478
479 memcpy(b + 5, cmd->msg, cmd->msg_len);
480
481 /* Diseqc */
482 if ((err = ttusb_cmd(ttusb, b, 4 + b[3], 0))) {
483 dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
484 __FUNCTION__, err);
485 }
486
487 return err;
488}
489#endif
490
Linus Torvalds1da177e2005-04-16 15:20:36 -0700491static int ttusb_update_lnb(struct ttusb *ttusb)
492{
493 u8 b[] = { 0xaa, ++ttusb->c, 0x16, 5, /*power: */ 1,
494 ttusb->voltage == SEC_VOLTAGE_18 ? 0 : 1,
495 ttusb->tone == SEC_TONE_ON ? 1 : 0, 1, 1
496 };
497 int err;
498
499 /* SetLNB */
500 if ((err = ttusb_cmd(ttusb, b, sizeof(b), 0))) {
501 dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
502 __FUNCTION__, err);
503 }
504
505 return err;
506}
507
508static int ttusb_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
509{
510 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
511
512 ttusb->voltage = voltage;
513 return ttusb_update_lnb(ttusb);
514}
515
516#ifdef TTUSB_TONE
517static int ttusb_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
518{
519 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
520
521 ttusb->tone = tone;
522 return ttusb_update_lnb(ttusb);
523}
524#endif
525
526
527#if 0
528static void ttusb_set_led_freq(struct ttusb *ttusb, u8 freq)
529{
530 u8 b[] = { 0xaa, ++ttusb->c, 0x19, 1, freq };
531 int err, actual_len;
532
533 err = ttusb_cmd(ttusb, b, sizeof(b), 0);
534 if (err) {
535 dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
536 __FUNCTION__, err);
537 }
538}
539#endif
540
541/*****************************************************************************/
542
543#ifdef TTUSB_HWSECTIONS
544static void ttusb_handle_ts_data(struct ttusb_channel *channel,
545 const u8 * data, int len);
546static void ttusb_handle_sec_data(struct ttusb_channel *channel,
547 const u8 * data, int len);
548#endif
549
Marcelo Feitoza Parisi4da006c2005-09-09 13:03:15 -0700550static int numpkt = 0, numts, numstuff, numsec, numinvalid;
551static unsigned long lastj;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700552
553static void ttusb_process_muxpack(struct ttusb *ttusb, const u8 * muxpack,
554 int len)
555{
556 u16 csum = 0, cc;
557 int i;
558 for (i = 0; i < len; i += 2)
559 csum ^= le16_to_cpup((u16 *) (muxpack + i));
560 if (csum) {
561 printk("%s: muxpack with incorrect checksum, ignoring\n",
562 __FUNCTION__);
563 numinvalid++;
564 return;
565 }
566
567 cc = (muxpack[len - 4] << 8) | muxpack[len - 3];
568 cc &= 0x7FFF;
569 if ((cc != ttusb->cc) && (ttusb->cc != -1))
570 printk("%s: cc discontinuity (%d frames missing)\n",
571 __FUNCTION__, (cc - ttusb->cc) & 0x7FFF);
572 ttusb->cc = (cc + 1) & 0x7FFF;
573 if (muxpack[0] & 0x80) {
574#ifdef TTUSB_HWSECTIONS
575 /* section data */
576 int pusi = muxpack[0] & 0x40;
577 int channel = muxpack[0] & 0x1F;
578 int payload = muxpack[1];
579 const u8 *data = muxpack + 2;
580 /* check offset flag */
581 if (muxpack[0] & 0x20)
582 data++;
583
584 ttusb_handle_sec_data(ttusb->channel + channel, data,
585 payload);
586 data += payload;
587
588 if ((!!(ttusb->muxpack[0] & 0x20)) ^
589 !!(ttusb->muxpack[1] & 1))
590 data++;
591#warning TODO: pusi
592 printk("cc: %04x\n", (data[0] << 8) | data[1]);
593#endif
594 numsec++;
595 } else if (muxpack[0] == 0x47) {
596#ifdef TTUSB_HWSECTIONS
597 /* we have TS data here! */
598 int pid = ((muxpack[1] & 0x0F) << 8) | muxpack[2];
599 int channel;
600 for (channel = 0; channel < TTUSB_MAXCHANNEL; ++channel)
601 if (ttusb->channel[channel].active
602 && (pid == ttusb->channel[channel].pid))
603 ttusb_handle_ts_data(ttusb->channel +
604 channel, muxpack,
605 188);
606#endif
607 numts++;
608 dvb_dmx_swfilter_packets(&ttusb->dvb_demux, muxpack, 1);
609 } else if (muxpack[0] != 0) {
610 numinvalid++;
611 printk("illegal muxpack type %02x\n", muxpack[0]);
612 } else
613 numstuff++;
614}
615
616static void ttusb_process_frame(struct ttusb *ttusb, u8 * data, int len)
617{
618 int maxwork = 1024;
619 while (len) {
620 if (!(maxwork--)) {
621 printk("%s: too much work\n", __FUNCTION__);
622 break;
623 }
624
625 switch (ttusb->mux_state) {
626 case 0:
627 case 1:
628 case 2:
629 len--;
630 if (*data++ == 0xAA)
631 ++ttusb->mux_state;
632 else {
633 ttusb->mux_state = 0;
634#if DEBUG > 3
635 if (ttusb->insync)
636 printk("%02x ", data[-1]);
637#else
638 if (ttusb->insync) {
639 printk("%s: lost sync.\n",
640 __FUNCTION__);
641 ttusb->insync = 0;
642 }
643#endif
644 }
645 break;
646 case 3:
647 ttusb->insync = 1;
648 len--;
649 ttusb->mux_npacks = *data++;
650 ++ttusb->mux_state;
651 ttusb->muxpack_ptr = 0;
652 /* maximum bytes, until we know the length */
653 ttusb->muxpack_len = 2;
654 break;
655 case 4:
656 {
657 int avail;
658 avail = len;
659 if (avail >
660 (ttusb->muxpack_len -
661 ttusb->muxpack_ptr))
662 avail =
663 ttusb->muxpack_len -
664 ttusb->muxpack_ptr;
665 memcpy(ttusb->muxpack + ttusb->muxpack_ptr,
666 data, avail);
667 ttusb->muxpack_ptr += avail;
Eric Sesterhennae246012006-03-13 13:17:11 -0300668 BUG_ON(ttusb->muxpack_ptr > 264);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700669 data += avail;
670 len -= avail;
671 /* determine length */
672 if (ttusb->muxpack_ptr == 2) {
673 if (ttusb->muxpack[0] & 0x80) {
674 ttusb->muxpack_len =
675 ttusb->muxpack[1] + 2;
676 if (ttusb->
677 muxpack[0] & 0x20)
678 ttusb->
679 muxpack_len++;
680 if ((!!
681 (ttusb->
682 muxpack[0] & 0x20)) ^
683 !!(ttusb->
684 muxpack[1] & 1))
685 ttusb->
686 muxpack_len++;
687 ttusb->muxpack_len += 4;
688 } else if (ttusb->muxpack[0] ==
689 0x47)
690 ttusb->muxpack_len =
691 188 + 4;
692 else if (ttusb->muxpack[0] == 0x00)
693 ttusb->muxpack_len =
694 ttusb->muxpack[1] + 2 +
695 4;
696 else {
697 dprintk
698 ("%s: invalid state: first byte is %x\n",
699 __FUNCTION__,
700 ttusb->muxpack[0]);
701 ttusb->mux_state = 0;
702 }
703 }
704
705 /**
706 * if length is valid and we reached the end:
707 * goto next muxpack
708 */
709 if ((ttusb->muxpack_ptr >= 2) &&
710 (ttusb->muxpack_ptr ==
711 ttusb->muxpack_len)) {
712 ttusb_process_muxpack(ttusb,
713 ttusb->
714 muxpack,
715 ttusb->
716 muxpack_ptr);
717 ttusb->muxpack_ptr = 0;
718 /* maximum bytes, until we know the length */
719 ttusb->muxpack_len = 2;
720
721 /**
722 * no muxpacks left?
723 * return to search-sync state
724 */
725 if (!ttusb->mux_npacks--) {
726 ttusb->mux_state = 0;
727 break;
728 }
729 }
730 break;
731 }
732 default:
733 BUG();
734 break;
735 }
736 }
737}
738
739static void ttusb_iso_irq(struct urb *urb, struct pt_regs *ptregs)
740{
741 struct ttusb *ttusb = urb->context;
742
743 if (!ttusb->iso_streaming)
744 return;
745
746#if 0
747 printk("%s: status %d, errcount == %d, length == %i\n",
748 __FUNCTION__,
749 urb->status, urb->error_count, urb->actual_length);
750#endif
751
752 if (!urb->status) {
753 int i;
754 for (i = 0; i < urb->number_of_packets; ++i) {
755 struct usb_iso_packet_descriptor *d;
756 u8 *data;
757 int len;
758 numpkt++;
Marcelo Feitoza Parisi4da006c2005-09-09 13:03:15 -0700759 if (time_after_eq(jiffies, lastj + HZ)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700760#if DEBUG > 2
761 printk
762 ("frames/s: %d (ts: %d, stuff %d, sec: %d, invalid: %d, all: %d)\n",
763 numpkt * HZ / (jiffies - lastj),
764 numts, numstuff, numsec, numinvalid,
765 numts + numstuff + numsec +
766 numinvalid);
767#endif
768 numts = numstuff = numsec = numinvalid = 0;
769 lastj = jiffies;
770 numpkt = 0;
771 }
772 d = &urb->iso_frame_desc[i];
773 data = urb->transfer_buffer + d->offset;
774 len = d->actual_length;
775 d->actual_length = 0;
776 d->status = 0;
777 ttusb_process_frame(ttusb, data, len);
778 }
779 }
780 usb_submit_urb(urb, GFP_ATOMIC);
781}
782
783static void ttusb_free_iso_urbs(struct ttusb *ttusb)
784{
785 int i;
786
787 for (i = 0; i < ISO_BUF_COUNT; i++)
788 if (ttusb->iso_urb[i])
789 usb_free_urb(ttusb->iso_urb[i]);
790
791 pci_free_consistent(NULL,
792 ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF *
793 ISO_BUF_COUNT, ttusb->iso_buffer,
794 ttusb->iso_dma_handle);
795}
796
797static int ttusb_alloc_iso_urbs(struct ttusb *ttusb)
798{
799 int i;
800
801 ttusb->iso_buffer = pci_alloc_consistent(NULL,
802 ISO_FRAME_SIZE *
803 FRAMES_PER_ISO_BUF *
804 ISO_BUF_COUNT,
805 &ttusb->iso_dma_handle);
806
807 memset(ttusb->iso_buffer, 0,
808 ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF * ISO_BUF_COUNT);
809
810 for (i = 0; i < ISO_BUF_COUNT; i++) {
811 struct urb *urb;
812
813 if (!
814 (urb =
815 usb_alloc_urb(FRAMES_PER_ISO_BUF, GFP_ATOMIC))) {
816 ttusb_free_iso_urbs(ttusb);
817 return -ENOMEM;
818 }
819
820 ttusb->iso_urb[i] = urb;
821 }
822
823 return 0;
824}
825
826static void ttusb_stop_iso_xfer(struct ttusb *ttusb)
827{
828 int i;
829
830 for (i = 0; i < ISO_BUF_COUNT; i++)
831 usb_kill_urb(ttusb->iso_urb[i]);
832
833 ttusb->iso_streaming = 0;
834}
835
836static int ttusb_start_iso_xfer(struct ttusb *ttusb)
837{
838 int i, j, err, buffer_offset = 0;
839
840 if (ttusb->iso_streaming) {
841 printk("%s: iso xfer already running!\n", __FUNCTION__);
842 return 0;
843 }
844
845 ttusb->cc = -1;
846 ttusb->insync = 0;
847 ttusb->mux_state = 0;
848
849 for (i = 0; i < ISO_BUF_COUNT; i++) {
850 int frame_offset = 0;
851 struct urb *urb = ttusb->iso_urb[i];
852
853 urb->dev = ttusb->dev;
854 urb->context = ttusb;
855 urb->complete = ttusb_iso_irq;
856 urb->pipe = ttusb->isoc_in_pipe;
857 urb->transfer_flags = URB_ISO_ASAP;
858 urb->interval = 1;
859 urb->number_of_packets = FRAMES_PER_ISO_BUF;
860 urb->transfer_buffer_length =
861 ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF;
862 urb->transfer_buffer = ttusb->iso_buffer + buffer_offset;
863 buffer_offset += ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF;
864
865 for (j = 0; j < FRAMES_PER_ISO_BUF; j++) {
866 urb->iso_frame_desc[j].offset = frame_offset;
867 urb->iso_frame_desc[j].length = ISO_FRAME_SIZE;
868 frame_offset += ISO_FRAME_SIZE;
869 }
870 }
871
872 for (i = 0; i < ISO_BUF_COUNT; i++) {
873 if ((err = usb_submit_urb(ttusb->iso_urb[i], GFP_ATOMIC))) {
874 ttusb_stop_iso_xfer(ttusb);
875 printk
876 ("%s: failed urb submission (%i: err = %i)!\n",
877 __FUNCTION__, i, err);
878 return err;
879 }
880 }
881
882 ttusb->iso_streaming = 1;
883
884 return 0;
885}
886
887#ifdef TTUSB_HWSECTIONS
888static void ttusb_handle_ts_data(struct dvb_demux_feed *dvbdmxfeed, const u8 * data,
889 int len)
890{
891 dvbdmxfeed->cb.ts(data, len, 0, 0, &dvbdmxfeed->feed.ts, 0);
892}
893
894static void ttusb_handle_sec_data(struct dvb_demux_feed *dvbdmxfeed, const u8 * data,
895 int len)
896{
897// struct dvb_demux_feed *dvbdmxfeed = channel->dvbdmxfeed;
898#error TODO: handle ugly stuff
899// dvbdmxfeed->cb.sec(data, len, 0, 0, &dvbdmxfeed->feed.sec, 0);
900}
901#endif
902
903static int ttusb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
904{
905 struct ttusb *ttusb = (struct ttusb *) dvbdmxfeed->demux;
906 int feed_type = 1;
907
908 dprintk("ttusb_start_feed\n");
909
910 switch (dvbdmxfeed->type) {
911 case DMX_TYPE_TS:
912 break;
913 case DMX_TYPE_SEC:
914 break;
915 default:
916 return -EINVAL;
917 }
918
919 if (dvbdmxfeed->type == DMX_TYPE_TS) {
920 switch (dvbdmxfeed->pes_type) {
921 case DMX_TS_PES_VIDEO:
922 case DMX_TS_PES_AUDIO:
923 case DMX_TS_PES_TELETEXT:
924 case DMX_TS_PES_PCR:
925 case DMX_TS_PES_OTHER:
926 break;
927 default:
928 return -EINVAL;
929 }
930 }
931
932#ifdef TTUSB_HWSECTIONS
933#error TODO: allocate filters
934 if (dvbdmxfeed->type == DMX_TYPE_TS) {
935 feed_type = 1;
936 } else if (dvbdmxfeed->type == DMX_TYPE_SEC) {
937 feed_type = 2;
938 }
939#endif
940
941 ttusb_set_channel(ttusb, dvbdmxfeed->index, feed_type, dvbdmxfeed->pid);
942
943 if (0 == ttusb->running_feed_count++)
944 ttusb_start_iso_xfer(ttusb);
945
946 return 0;
947}
948
949static int ttusb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
950{
951 struct ttusb *ttusb = (struct ttusb *) dvbdmxfeed->demux;
952
953 ttusb_del_channel(ttusb, dvbdmxfeed->index);
954
955 if (--ttusb->running_feed_count == 0)
956 ttusb_stop_iso_xfer(ttusb);
957
958 return 0;
959}
960
961static int ttusb_setup_interfaces(struct ttusb *ttusb)
962{
963 usb_set_interface(ttusb->dev, 1, 1);
964
965 ttusb->bulk_out_pipe = usb_sndbulkpipe(ttusb->dev, 1);
966 ttusb->bulk_in_pipe = usb_rcvbulkpipe(ttusb->dev, 1);
967 ttusb->isoc_in_pipe = usb_rcvisocpipe(ttusb->dev, 2);
968
969 return 0;
970}
971
972#if 0
973static u8 stc_firmware[8192];
974
975static int stc_open(struct inode *inode, struct file *file)
976{
977 struct ttusb *ttusb = file->private_data;
978 int addr;
979
980 for (addr = 0; addr < 8192; addr += 16) {
981 u8 snd_buf[2] = { addr >> 8, addr & 0xFF };
982 ttusb_i2c_msg(ttusb, 0x50, snd_buf, 2, stc_firmware + addr,
983 16);
984 }
985
986 return 0;
987}
988
989static ssize_t stc_read(struct file *file, char *buf, size_t count,
990 loff_t * offset)
991{
992 int tc = count;
993
994 if ((tc + *offset) > 8192)
995 tc = 8192 - *offset;
996
997 if (tc < 0)
998 return 0;
999
1000 if (copy_to_user(buf, stc_firmware + *offset, tc))
1001 return -EFAULT;
1002
1003 *offset += tc;
1004
1005 return tc;
1006}
1007
1008static int stc_release(struct inode *inode, struct file *file)
1009{
1010 return 0;
1011}
1012
1013static struct file_operations stc_fops = {
1014 .owner = THIS_MODULE,
1015 .read = stc_read,
1016 .open = stc_open,
1017 .release = stc_release,
1018};
1019#endif
1020
1021static u32 functionality(struct i2c_adapter *adapter)
1022{
1023 return I2C_FUNC_I2C;
1024}
1025
1026
1027
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001028static int alps_tdmb7_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001029{
1030 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1031 u8 data[4];
1032 struct i2c_msg msg = {.addr=0x61, .flags=0, .buf=data, .len=sizeof(data) };
1033 u32 div;
1034
1035 div = (params->frequency + 36166667) / 166667;
1036
1037 data[0] = (div >> 8) & 0x7f;
1038 data[1] = div & 0xff;
1039 data[2] = ((div >> 10) & 0x60) | 0x85;
1040 data[3] = params->frequency < 592000000 ? 0x40 : 0x80;
1041
1042 if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1) return -EIO;
1043 return 0;
1044}
1045
Johannes Stezenbachd91b7302005-05-16 21:54:38 -07001046static struct cx22700_config alps_tdmb7_config = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001047 .demod_address = 0x43,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001048};
1049
1050
1051
1052
1053
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001054static int philips_tdm1316l_tuner_init(struct dvb_frontend* fe)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001055{
1056 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1057 static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab };
1058 static u8 disable_mc44BC374c[] = { 0x1d, 0x74, 0xa0, 0x68 };
1059 struct i2c_msg tuner_msg = { .addr=0x60, .flags=0, .buf=td1316_init, .len=sizeof(td1316_init) };
1060
1061 // setup PLL configuration
1062 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) return -EIO;
1063 msleep(1);
1064
1065 // disable the mc44BC374c (do not check for errors)
1066 tuner_msg.addr = 0x65;
1067 tuner_msg.buf = disable_mc44BC374c;
1068 tuner_msg.len = sizeof(disable_mc44BC374c);
1069 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) {
1070 i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1);
1071 }
1072
1073 return 0;
1074}
1075
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001076static int philips_tdm1316l_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001077{
1078 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1079 u8 tuner_buf[4];
1080 struct i2c_msg tuner_msg = {.addr=0x60, .flags=0, .buf=tuner_buf, .len=sizeof(tuner_buf) };
1081 int tuner_frequency = 0;
1082 u8 band, cp, filter;
1083
1084 // determine charge pump
1085 tuner_frequency = params->frequency + 36130000;
1086 if (tuner_frequency < 87000000) return -EINVAL;
1087 else if (tuner_frequency < 130000000) cp = 3;
1088 else if (tuner_frequency < 160000000) cp = 5;
1089 else if (tuner_frequency < 200000000) cp = 6;
1090 else if (tuner_frequency < 290000000) cp = 3;
1091 else if (tuner_frequency < 420000000) cp = 5;
1092 else if (tuner_frequency < 480000000) cp = 6;
1093 else if (tuner_frequency < 620000000) cp = 3;
1094 else if (tuner_frequency < 830000000) cp = 5;
1095 else if (tuner_frequency < 895000000) cp = 7;
1096 else return -EINVAL;
1097
1098 // determine band
1099 if (params->frequency < 49000000) return -EINVAL;
1100 else if (params->frequency < 159000000) band = 1;
1101 else if (params->frequency < 444000000) band = 2;
1102 else if (params->frequency < 861000000) band = 4;
1103 else return -EINVAL;
1104
1105 // setup PLL filter
1106 switch (params->u.ofdm.bandwidth) {
1107 case BANDWIDTH_6_MHZ:
1108 tda1004x_write_byte(fe, 0x0C, 0);
1109 filter = 0;
1110 break;
1111
1112 case BANDWIDTH_7_MHZ:
1113 tda1004x_write_byte(fe, 0x0C, 0);
1114 filter = 0;
1115 break;
1116
1117 case BANDWIDTH_8_MHZ:
1118 tda1004x_write_byte(fe, 0x0C, 0xFF);
1119 filter = 1;
1120 break;
1121
1122 default:
1123 return -EINVAL;
1124 }
1125
1126 // calculate divisor
1127 // ((36130000+((1000000/6)/2)) + Finput)/(1000000/6)
1128 tuner_frequency = (((params->frequency / 1000) * 6) + 217280) / 1000;
1129
1130 // setup tuner buffer
1131 tuner_buf[0] = tuner_frequency >> 8;
1132 tuner_buf[1] = tuner_frequency & 0xff;
1133 tuner_buf[2] = 0xca;
1134 tuner_buf[3] = (cp << 5) | (filter << 3) | band;
1135
1136 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1)
1137 return -EIO;
1138
1139 msleep(1);
1140 return 0;
1141}
1142
1143static int philips_tdm1316l_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
1144{
1145 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1146
1147 return request_firmware(fw, name, &ttusb->dev->dev);
1148}
1149
1150static struct tda1004x_config philips_tdm1316l_config = {
1151
1152 .demod_address = 0x8,
1153 .invert = 1,
1154 .invert_oclk = 0,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001155 .request_firmware = philips_tdm1316l_request_firmware,
1156};
1157
1158static u8 alps_bsbe1_inittab[] = {
Mauro Carvalho Chehab9101e622005-12-12 00:37:24 -08001159 0x01, 0x15,
1160 0x02, 0x30,
1161 0x03, 0x00,
1162 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
1163 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
1164 0x06, 0x40, /* DAC not used, set to high impendance mode */
1165 0x07, 0x00, /* DAC LSB */
1166 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
1167 0x09, 0x00, /* FIFO */
1168 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
1169 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
1170 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
1171 0x10, 0x3f, // AGC2 0x3d
1172 0x11, 0x84,
1173 0x12, 0xb9,
1174 0x15, 0xc9, // lock detector threshold
1175 0x16, 0x00,
1176 0x17, 0x00,
1177 0x18, 0x00,
1178 0x19, 0x00,
1179 0x1a, 0x00,
1180 0x1f, 0x50,
1181 0x20, 0x00,
1182 0x21, 0x00,
1183 0x22, 0x00,
1184 0x23, 0x00,
1185 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
1186 0x29, 0x1e, // 1/2 threshold
1187 0x2a, 0x14, // 2/3 threshold
1188 0x2b, 0x0f, // 3/4 threshold
1189 0x2c, 0x09, // 5/6 threshold
1190 0x2d, 0x05, // 7/8 threshold
1191 0x2e, 0x01,
1192 0x31, 0x1f, // test all FECs
1193 0x32, 0x19, // viterbi and synchro search
1194 0x33, 0xfc, // rs control
1195 0x34, 0x93, // error control
1196 0x0f, 0x92,
1197 0xff, 0xff
Linus Torvalds1da177e2005-04-16 15:20:36 -07001198};
1199
1200static u8 alps_bsru6_inittab[] = {
1201 0x01, 0x15,
1202 0x02, 0x30,
1203 0x03, 0x00,
1204 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
1205 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
1206 0x06, 0x40, /* DAC not used, set to high impendance mode */
1207 0x07, 0x00, /* DAC LSB */
1208 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
1209 0x09, 0x00, /* FIFO */
1210 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
1211 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
1212 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
1213 0x10, 0x3f, // AGC2 0x3d
1214 0x11, 0x84,
Oliver Endriss7f44dcd2005-11-08 21:35:44 -08001215 0x12, 0xb9,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001216 0x15, 0xc9, // lock detector threshold
1217 0x16, 0x00,
1218 0x17, 0x00,
1219 0x18, 0x00,
1220 0x19, 0x00,
1221 0x1a, 0x00,
1222 0x1f, 0x50,
1223 0x20, 0x00,
1224 0x21, 0x00,
1225 0x22, 0x00,
1226 0x23, 0x00,
1227 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
1228 0x29, 0x1e, // 1/2 threshold
1229 0x2a, 0x14, // 2/3 threshold
1230 0x2b, 0x0f, // 3/4 threshold
1231 0x2c, 0x09, // 5/6 threshold
1232 0x2d, 0x05, // 7/8 threshold
1233 0x2e, 0x01,
1234 0x31, 0x1f, // test all FECs
1235 0x32, 0x19, // viterbi and synchro search
1236 0x33, 0xfc, // rs control
1237 0x34, 0x93, // error control
1238 0x0f, 0x52,
1239 0xff, 0xff
1240};
1241
1242static int alps_stv0299_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
1243{
1244 u8 aclk = 0;
1245 u8 bclk = 0;
1246
1247 if (srate < 1500000) {
1248 aclk = 0xb7;
1249 bclk = 0x47;
1250 } else if (srate < 3000000) {
1251 aclk = 0xb7;
1252 bclk = 0x4b;
1253 } else if (srate < 7000000) {
1254 aclk = 0xb7;
1255 bclk = 0x4f;
1256 } else if (srate < 14000000) {
1257 aclk = 0xb7;
1258 bclk = 0x53;
1259 } else if (srate < 30000000) {
1260 aclk = 0xb6;
1261 bclk = 0x53;
1262 } else if (srate < 45000000) {
1263 aclk = 0xb4;
1264 bclk = 0x51;
1265 }
1266
1267 stv0299_writereg(fe, 0x13, aclk);
1268 stv0299_writereg(fe, 0x14, bclk);
1269 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
1270 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
1271 stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
1272
1273 return 0;
1274}
1275
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001276static int philips_tsa5059_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001277{
1278 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1279 u8 buf[4];
1280 u32 div;
1281 struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
1282
1283 if ((params->frequency < 950000) || (params->frequency > 2150000))
1284 return -EINVAL;
1285
1286 div = (params->frequency + (125 - 1)) / 125; // round correctly
1287 buf[0] = (div >> 8) & 0x7f;
1288 buf[1] = div & 0xff;
1289 buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
1290 buf[3] = 0xC4;
1291
1292 if (params->frequency > 1530000)
1293 buf[3] = 0xC0;
1294
1295 /* BSBE1 wants XCE bit set */
1296 if (ttusb->revision == TTUSB_REV_2_2)
1297 buf[3] |= 0x20;
1298
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001299 if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001300 return -EIO;
1301
1302 return 0;
1303}
1304
1305static struct stv0299_config alps_stv0299_config = {
1306 .demod_address = 0x68,
1307 .inittab = alps_bsru6_inittab,
1308 .mclk = 88000000UL,
1309 .invert = 1,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001310 .skip_reinit = 0,
1311 .lock_output = STV0229_LOCKOUTPUT_1,
1312 .volt13_op0_op1 = STV0299_VOLT13_OP1,
1313 .min_delay_ms = 100,
1314 .set_symbol_rate = alps_stv0299_set_symbol_rate,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001315};
1316
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001317static int ttusb_novas_grundig_29504_491_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001318{
1319 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1320 u8 buf[4];
1321 u32 div;
1322 struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
1323
Mauro Carvalho Chehab9101e622005-12-12 00:37:24 -08001324 div = params->frequency / 125;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001325
1326 buf[0] = (div >> 8) & 0x7f;
1327 buf[1] = div & 0xff;
1328 buf[2] = 0x8e;
1329 buf[3] = 0x00;
1330
1331 if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1)
1332 return -EIO;
1333
1334 return 0;
1335}
1336
1337static struct tda8083_config ttusb_novas_grundig_29504_491_config = {
1338
1339 .demod_address = 0x68,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001340};
1341
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001342static int alps_tdbe2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
Gavin Hamill53936392005-07-07 17:58:04 -07001343{
1344 struct ttusb* ttusb = fe->dvb->priv;
1345 u32 div;
1346 u8 data[4];
1347 struct i2c_msg msg = { .addr = 0x62, .flags = 0, .buf = data, .len = sizeof(data) };
1348
1349 div = (params->frequency + 35937500 + 31250) / 62500;
1350
1351 data[0] = (div >> 8) & 0x7f;
1352 data[1] = div & 0xff;
1353 data[2] = 0x85 | ((div >> 10) & 0x60);
1354 data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81);
1355
1356 if (i2c_transfer (&ttusb->i2c_adap, &msg, 1) != 1)
1357 return -EIO;
1358
1359 return 0;
1360}
1361
1362
1363static struct ves1820_config alps_tdbe2_config = {
1364 .demod_address = 0x09,
1365 .xin = 57840000UL,
1366 .invert = 1,
1367 .selagc = VES1820_SELAGC_SIGNAMPERR,
Gavin Hamill53936392005-07-07 17:58:04 -07001368};
1369
1370static u8 read_pwm(struct ttusb* ttusb)
1371{
1372 u8 b = 0xff;
1373 u8 pwm;
1374 struct i2c_msg msg[] = { { .addr = 0x50,.flags = 0,.buf = &b,.len = 1 },
1375 { .addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1} };
1376
1377 if ((i2c_transfer(&ttusb->i2c_adap, msg, 2) != 2) || (pwm == 0xff))
1378 pwm = 0x48;
1379
1380 return pwm;
1381}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001382
1383
Thomas Kaiserb8d4c232006-04-27 21:45:20 -03001384static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
1385{
1386 struct ttusb *ttusb = (struct ttusb *) fe->dvb->priv;
1387 u8 tuner_buf[5];
1388 struct i2c_msg tuner_msg = {.addr = 0x60,
1389 .flags = 0,
1390 .buf = tuner_buf,
1391 .len = sizeof(tuner_buf) };
1392 int tuner_frequency = 0;
1393 u8 band, cp, filter;
1394
1395 // determine charge pump
1396 tuner_frequency = params->frequency;
1397 if (tuner_frequency < 87000000) {return -EINVAL;}
1398 else if (tuner_frequency < 130000000) {cp = 3; band = 1;}
1399 else if (tuner_frequency < 160000000) {cp = 5; band = 1;}
1400 else if (tuner_frequency < 200000000) {cp = 6; band = 1;}
1401 else if (tuner_frequency < 290000000) {cp = 3; band = 2;}
1402 else if (tuner_frequency < 420000000) {cp = 5; band = 2;}
1403 else if (tuner_frequency < 480000000) {cp = 6; band = 2;}
1404 else if (tuner_frequency < 620000000) {cp = 3; band = 4;}
1405 else if (tuner_frequency < 830000000) {cp = 5; band = 4;}
1406 else if (tuner_frequency < 895000000) {cp = 7; band = 4;}
1407 else {return -EINVAL;}
1408
1409 // assume PLL filter should always be 8MHz for the moment.
1410 filter = 1;
1411
1412 // calculate divisor
1413 // (Finput + Fif)/Fref; Fif = 36125000 Hz, Fref = 62500 Hz
1414 tuner_frequency = ((params->frequency + 36125000) / 62500);
1415
1416 // setup tuner buffer
1417 tuner_buf[0] = tuner_frequency >> 8;
1418 tuner_buf[1] = tuner_frequency & 0xff;
1419 tuner_buf[2] = 0xc8;
1420 tuner_buf[3] = (cp << 5) | (filter << 3) | band;
1421 tuner_buf[4] = 0x80;
1422
1423 if (fe->ops->i2c_gate_ctrl)
1424 fe->ops->i2c_gate_ctrl(fe, 1);
1425 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) {
1426 printk("dvb-ttusb-budget: dvbc_philips_tdm1316l_pll_set Error 1\n");
1427 return -EIO;
1428 }
1429
1430 msleep(50);
1431
1432 if (fe->ops->i2c_gate_ctrl)
1433 fe->ops->i2c_gate_ctrl(fe, 1);
1434 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) {
1435 printk("dvb-ttusb-budget: dvbc_philips_tdm1316l_pll_set Error 2\n");
1436 return -EIO;
1437 }
1438
1439 msleep(1);
1440
1441 return 0;
1442}
1443
1444static u8 dvbc_philips_tdm1316l_inittab[] = {
1445 0x80, 0x21,
1446 0x80, 0x20,
1447 0x81, 0x01,
1448 0x81, 0x00,
1449 0x00, 0x09,
1450 0x01, 0x69,
1451 0x03, 0x00,
1452 0x04, 0x00,
1453 0x07, 0x00,
1454 0x08, 0x00,
1455 0x20, 0x00,
1456 0x21, 0x40,
1457 0x22, 0x00,
1458 0x23, 0x00,
1459 0x24, 0x40,
1460 0x25, 0x88,
1461 0x30, 0xff,
1462 0x31, 0x00,
1463 0x32, 0xff,
1464 0x33, 0x00,
1465 0x34, 0x50,
1466 0x35, 0x7f,
1467 0x36, 0x00,
1468 0x37, 0x20,
1469 0x38, 0x00,
1470 0x40, 0x1c,
1471 0x41, 0xff,
1472 0x42, 0x29,
1473 0x43, 0x20,
1474 0x44, 0xff,
1475 0x45, 0x00,
1476 0x46, 0x00,
1477 0x49, 0x04,
1478 0x4a, 0xff,
1479 0x4b, 0x7f,
1480 0x52, 0x30,
1481 0x55, 0xae,
1482 0x56, 0x47,
1483 0x57, 0xe1,
1484 0x58, 0x3a,
1485 0x5a, 0x1e,
1486 0x5b, 0x34,
1487 0x60, 0x00,
1488 0x63, 0x00,
1489 0x64, 0x00,
1490 0x65, 0x00,
1491 0x66, 0x00,
1492 0x67, 0x00,
1493 0x68, 0x00,
1494 0x69, 0x00,
1495 0x6a, 0x02,
1496 0x6b, 0x00,
1497 0x70, 0xff,
1498 0x71, 0x00,
1499 0x72, 0x00,
1500 0x73, 0x00,
1501 0x74, 0x0c,
1502 0x80, 0x00,
1503 0x81, 0x00,
1504 0x82, 0x00,
1505 0x83, 0x00,
1506 0x84, 0x04,
1507 0x85, 0x80,
1508 0x86, 0x24,
1509 0x87, 0x78,
1510 0x88, 0x00,
1511 0x89, 0x00,
1512 0x90, 0x01,
1513 0x91, 0x01,
1514 0xa0, 0x00,
1515 0xa1, 0x00,
1516 0xa2, 0x00,
1517 0xb0, 0x91,
1518 0xb1, 0x0b,
1519 0xc0, 0x4b,
1520 0xc1, 0x00,
1521 0xc2, 0x00,
1522 0xd0, 0x00,
1523 0xd1, 0x00,
1524 0xd2, 0x00,
1525 0xd3, 0x00,
1526 0xd4, 0x00,
1527 0xd5, 0x00,
1528 0xde, 0x00,
1529 0xdf, 0x00,
1530 0x61, 0x38,
1531 0x62, 0x0a,
1532 0x53, 0x13,
1533 0x59, 0x08,
1534 0x55, 0x00,
1535 0x56, 0x40,
1536 0x57, 0x08,
1537 0x58, 0x3d,
1538 0x88, 0x10,
1539 0xa0, 0x00,
1540 0xa0, 0x00,
1541 0xa0, 0x00,
1542 0xa0, 0x04,
1543 0xff, 0xff,
1544};
1545
1546static struct stv0297_config dvbc_philips_tdm1316l_config = {
1547 .demod_address = 0x1c,
1548 .inittab = dvbc_philips_tdm1316l_inittab,
1549 .invert = 0,
1550};
1551
Linus Torvalds1da177e2005-04-16 15:20:36 -07001552static void frontend_init(struct ttusb* ttusb)
1553{
1554 switch(le16_to_cpu(ttusb->dev->descriptor.idProduct)) {
1555 case 0x1003: // Hauppauge/TT Nova-USB-S budget (stv0299/ALPS BSRU6|BSBE1(tsa5059))
1556 // try the stv0299 based first
1557 ttusb->fe = stv0299_attach(&alps_stv0299_config, &ttusb->i2c_adap);
1558 if (ttusb->fe != NULL) {
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001559 ttusb->fe->ops->tuner_ops.set_params = philips_tsa5059_tuner_set_params;
1560
Linus Torvalds1da177e2005-04-16 15:20:36 -07001561 if(ttusb->revision == TTUSB_REV_2_2) { // ALPS BSBE1
1562 alps_stv0299_config.inittab = alps_bsbe1_inittab;
Andrew de Quinceyd0205422006-04-27 21:45:01 -03001563 lnbp21_attach(ttusb->fe, &ttusb->i2c_adap, 0, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001564 } else { // ALPS BSRU6
1565 ttusb->fe->ops->set_voltage = ttusb_set_voltage;
1566 }
1567 break;
1568 }
1569
1570 // Grundig 29504-491
1571 ttusb->fe = tda8083_attach(&ttusb_novas_grundig_29504_491_config, &ttusb->i2c_adap);
1572 if (ttusb->fe != NULL) {
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001573 ttusb->fe->ops->tuner_ops.set_params = ttusb_novas_grundig_29504_491_tuner_set_params;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001574 ttusb->fe->ops->set_voltage = ttusb_set_voltage;
1575 break;
1576 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001577 break;
1578
Gavin Hamill53936392005-07-07 17:58:04 -07001579 case 0x1004: // Hauppauge/TT DVB-C budget (ves1820/ALPS TDBE2(sp5659))
1580 ttusb->fe = ves1820_attach(&alps_tdbe2_config, &ttusb->i2c_adap, read_pwm(ttusb));
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001581 if (ttusb->fe != NULL) {
1582 ttusb->fe->ops->tuner_ops.set_params = alps_tdbe2_tuner_set_params;
Gavin Hamill53936392005-07-07 17:58:04 -07001583 break;
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001584 }
Thomas Kaiserb8d4c232006-04-27 21:45:20 -03001585
1586 ttusb->fe = stv0297_attach(&dvbc_philips_tdm1316l_config, &ttusb->i2c_adap);
1587 if (ttusb->fe != NULL) {
1588 ttusb->fe->ops->tuner_ops.set_params = dvbc_philips_tdm1316l_tuner_set_params;
1589 break;
1590 }
Gavin Hamill53936392005-07-07 17:58:04 -07001591 break;
1592
Linus Torvalds1da177e2005-04-16 15:20:36 -07001593 case 0x1005: // Hauppauge/TT Nova-USB-t budget (tda10046/Philips td1316(tda6651tt) OR cx22700/ALPS TDMB7(??))
1594 // try the ALPS TDMB7 first
1595 ttusb->fe = cx22700_attach(&alps_tdmb7_config, &ttusb->i2c_adap);
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001596 if (ttusb->fe != NULL) {
1597 ttusb->fe->ops->tuner_ops.set_params = alps_tdmb7_tuner_set_params;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001598 break;
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001599 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001600
1601 // Philips td1316
1602 ttusb->fe = tda10046_attach(&philips_tdm1316l_config, &ttusb->i2c_adap);
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001603 if (ttusb->fe != NULL) {
1604 ttusb->fe->ops->tuner_ops.init = philips_tdm1316l_tuner_init;
1605 ttusb->fe->ops->tuner_ops.set_params = philips_tdm1316l_tuner_set_params;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001606 break;
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001607 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001608 break;
1609 }
1610
1611 if (ttusb->fe == NULL) {
1612 printk("dvb-ttusb-budget: A frontend driver was not found for device %04x/%04x\n",
1613 le16_to_cpu(ttusb->dev->descriptor.idVendor),
1614 le16_to_cpu(ttusb->dev->descriptor.idProduct));
1615 } else {
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001616 if (dvb_register_frontend(&ttusb->adapter, ttusb->fe)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001617 printk("dvb-ttusb-budget: Frontend registration failed!\n");
1618 if (ttusb->fe->ops->release)
1619 ttusb->fe->ops->release(ttusb->fe);
1620 ttusb->fe = NULL;
1621 }
1622 }
1623}
1624
1625
1626
1627static struct i2c_algorithm ttusb_dec_algo = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001628 .master_xfer = master_xfer,
1629 .functionality = functionality,
1630};
1631
1632static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *id)
1633{
1634 struct usb_device *udev;
1635 struct ttusb *ttusb;
1636 int result;
1637
1638 dprintk("%s: TTUSB DVB connected\n", __FUNCTION__);
1639
1640 udev = interface_to_usbdev(intf);
1641
Mauro Carvalho Chehab9101e622005-12-12 00:37:24 -08001642 if (intf->altsetting->desc.bInterfaceNumber != 1) return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001643
Panagiotis Issaris74081872006-01-11 19:40:56 -02001644 if (!(ttusb = kzalloc(sizeof(struct ttusb), GFP_KERNEL)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001645 return -ENOMEM;
1646
Linus Torvalds1da177e2005-04-16 15:20:36 -07001647 ttusb->dev = udev;
1648 ttusb->c = 0;
1649 ttusb->mux_state = 0;
Ingo Molnar3593cab2006-02-07 06:49:14 -02001650 mutex_init(&ttusb->semi2c);
1651
1652 mutex_lock(&ttusb->semi2c);
1653
1654 mutex_init(&ttusb->semusb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001655
1656 ttusb_setup_interfaces(ttusb);
1657
1658 ttusb_alloc_iso_urbs(ttusb);
1659 if (ttusb_init_controller(ttusb))
1660 printk("ttusb_init_controller: error\n");
1661
Ingo Molnar3593cab2006-02-07 06:49:14 -02001662 mutex_unlock(&ttusb->semi2c);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001663
Andrew de Quinceyd09dbf92006-04-10 09:27:37 -03001664 if ((result = dvb_register_adapter(&ttusb->adapter, "Technotrend/Hauppauge Nova-USB", THIS_MODULE, &udev->dev)) < 0) {
Andrew de Quinceya064fad2006-04-06 17:05:46 -03001665 ttusb_free_iso_urbs(ttusb);
1666 kfree(ttusb);
1667 return result;
1668 }
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001669 ttusb->adapter.priv = ttusb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001670
1671 /* i2c */
1672 memset(&ttusb->i2c_adap, 0, sizeof(struct i2c_adapter));
1673 strcpy(ttusb->i2c_adap.name, "TTUSB DEC");
1674
1675 i2c_set_adapdata(&ttusb->i2c_adap, ttusb);
1676
1677#ifdef I2C_ADAP_CLASS_TV_DIGITAL
1678 ttusb->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL;
1679#else
1680 ttusb->i2c_adap.class = I2C_CLASS_TV_DIGITAL;
1681#endif
1682 ttusb->i2c_adap.algo = &ttusb_dec_algo;
1683 ttusb->i2c_adap.algo_data = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001684
1685 result = i2c_add_adapter(&ttusb->i2c_adap);
1686 if (result) {
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001687 dvb_unregister_adapter (&ttusb->adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001688 return result;
1689 }
1690
1691 memset(&ttusb->dvb_demux, 0, sizeof(ttusb->dvb_demux));
1692
1693 ttusb->dvb_demux.dmx.capabilities =
1694 DMX_TS_FILTERING | DMX_SECTION_FILTERING;
1695 ttusb->dvb_demux.priv = NULL;
1696#ifdef TTUSB_HWSECTIONS
1697 ttusb->dvb_demux.filternum = TTUSB_MAXFILTER;
1698#else
1699 ttusb->dvb_demux.filternum = 32;
1700#endif
1701 ttusb->dvb_demux.feednum = TTUSB_MAXCHANNEL;
1702 ttusb->dvb_demux.start_feed = ttusb_start_feed;
1703 ttusb->dvb_demux.stop_feed = ttusb_stop_feed;
1704 ttusb->dvb_demux.write_to_decoder = NULL;
1705
1706 if ((result = dvb_dmx_init(&ttusb->dvb_demux)) < 0) {
1707 printk("ttusb_dvb: dvb_dmx_init failed (errno = %d)\n", result);
1708 i2c_del_adapter(&ttusb->i2c_adap);
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001709 dvb_unregister_adapter (&ttusb->adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001710 return -ENODEV;
1711 }
1712//FIXME dmxdev (nur WAS?)
1713 ttusb->dmxdev.filternum = ttusb->dvb_demux.filternum;
1714 ttusb->dmxdev.demux = &ttusb->dvb_demux.dmx;
1715 ttusb->dmxdev.capabilities = 0;
1716
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001717 if ((result = dvb_dmxdev_init(&ttusb->dmxdev, &ttusb->adapter)) < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001718 printk("ttusb_dvb: dvb_dmxdev_init failed (errno = %d)\n",
1719 result);
1720 dvb_dmx_release(&ttusb->dvb_demux);
1721 i2c_del_adapter(&ttusb->i2c_adap);
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001722 dvb_unregister_adapter (&ttusb->adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001723 return -ENODEV;
1724 }
1725
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001726 if (dvb_net_init(&ttusb->adapter, &ttusb->dvbnet, &ttusb->dvb_demux.dmx)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001727 printk("ttusb_dvb: dvb_net_init failed!\n");
1728 dvb_dmxdev_release(&ttusb->dmxdev);
1729 dvb_dmx_release(&ttusb->dvb_demux);
1730 i2c_del_adapter(&ttusb->i2c_adap);
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001731 dvb_unregister_adapter (&ttusb->adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001732 return -ENODEV;
1733 }
1734
1735#if 0
1736 ttusb->stc_devfs_handle =
1737 devfs_register(ttusb->adapter->devfs_handle, TTUSB_BUDGET_NAME,
1738 DEVFS_FL_DEFAULT, 0, 192,
1739 S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP
1740 | S_IROTH | S_IWOTH, &stc_fops, ttusb);
1741#endif
1742 usb_set_intfdata(intf, (void *) ttusb);
1743
1744 frontend_init(ttusb);
1745
1746 return 0;
1747}
1748
1749static void ttusb_disconnect(struct usb_interface *intf)
1750{
1751 struct ttusb *ttusb = usb_get_intfdata(intf);
1752
1753 usb_set_intfdata(intf, NULL);
1754
1755 ttusb->disconnecting = 1;
1756
1757 ttusb_stop_iso_xfer(ttusb);
1758
1759 ttusb->dvb_demux.dmx.close(&ttusb->dvb_demux.dmx);
1760 dvb_net_release(&ttusb->dvbnet);
1761 dvb_dmxdev_release(&ttusb->dmxdev);
1762 dvb_dmx_release(&ttusb->dvb_demux);
1763 if (ttusb->fe != NULL) dvb_unregister_frontend(ttusb->fe);
1764 i2c_del_adapter(&ttusb->i2c_adap);
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001765 dvb_unregister_adapter(&ttusb->adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001766
1767 ttusb_free_iso_urbs(ttusb);
1768
1769 kfree(ttusb);
1770
1771 dprintk("%s: TTUSB DVB disconnected\n", __FUNCTION__);
1772}
1773
1774static struct usb_device_id ttusb_table[] = {
1775 {USB_DEVICE(0xb48, 0x1003)},
Gavin Hamill53936392005-07-07 17:58:04 -07001776 {USB_DEVICE(0xb48, 0x1004)},
Linus Torvalds1da177e2005-04-16 15:20:36 -07001777 {USB_DEVICE(0xb48, 0x1005)},
1778 {}
1779};
1780
1781MODULE_DEVICE_TABLE(usb, ttusb_table);
1782
1783static struct usb_driver ttusb_driver = {
Julian Scheel27b05fd2005-07-12 13:58:39 -07001784 .name = "ttusb",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001785 .probe = ttusb_probe,
1786 .disconnect = ttusb_disconnect,
1787 .id_table = ttusb_table,
1788};
1789
1790static int __init ttusb_init(void)
1791{
1792 int err;
1793
1794 if ((err = usb_register(&ttusb_driver)) < 0) {
1795 printk("%s: usb_register failed! Error number %d",
1796 __FILE__, err);
1797 return err;
1798 }
1799
1800 return 0;
1801}
1802
1803static void __exit ttusb_exit(void)
1804{
1805 usb_deregister(&ttusb_driver);
1806}
1807
1808module_init(ttusb_init);
1809module_exit(ttusb_exit);
1810
1811MODULE_AUTHOR("Holger Waechtler <holger@convergence.de>");
1812MODULE_DESCRIPTION("TTUSB DVB Driver");
1813MODULE_LICENSE("GPL");