blob: b60cdc93d6dbddab7031a69128acb3114c5f9852 [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
Adrian Bunk9aaeded2006-06-30 18:19:55 +020046 parse TS data. USB bandwidth will be a problem when having large
Linus Torvalds1da177e2005-04-16 15:20:36 -070047 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
Linus Torvalds1da177e2005-04-16 15:20:36 -0700129 struct dvb_frontend* fe;
130};
131
132/* ugly workaround ... don't know why it's neccessary to read */
133/* all result codes. */
134
135#define DEBUG 0
136static int ttusb_cmd(struct ttusb *ttusb,
137 const u8 * data, int len, int needresult)
138{
139 int actual_len;
140 int err;
141#if DEBUG >= 3
142 int i;
143
144 printk(">");
145 for (i = 0; i < len; ++i)
146 printk(" %02x", data[i]);
147 printk("\n");
148#endif
149
Ingo Molnar3593cab2006-02-07 06:49:14 -0200150 if (mutex_lock_interruptible(&ttusb->semusb) < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700151 return -EAGAIN;
152
153 err = usb_bulk_msg(ttusb->dev, ttusb->bulk_out_pipe,
154 (u8 *) data, len, &actual_len, 1000);
155 if (err != 0) {
156 dprintk("%s: usb_bulk_msg(send) failed, err == %i!\n",
157 __FUNCTION__, err);
Ingo Molnar3593cab2006-02-07 06:49:14 -0200158 mutex_unlock(&ttusb->semusb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700159 return err;
160 }
161 if (actual_len != len) {
162 dprintk("%s: only wrote %d of %d bytes\n", __FUNCTION__,
163 actual_len, len);
Ingo Molnar3593cab2006-02-07 06:49:14 -0200164 mutex_unlock(&ttusb->semusb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700165 return -1;
166 }
167
168 err = usb_bulk_msg(ttusb->dev, ttusb->bulk_in_pipe,
169 ttusb->last_result, 32, &actual_len, 1000);
170
171 if (err != 0) {
172 printk("%s: failed, receive error %d\n", __FUNCTION__,
173 err);
Ingo Molnar3593cab2006-02-07 06:49:14 -0200174 mutex_unlock(&ttusb->semusb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700175 return err;
176 }
177#if DEBUG >= 3
178 actual_len = ttusb->last_result[3] + 4;
179 printk("<");
180 for (i = 0; i < actual_len; ++i)
181 printk(" %02x", ttusb->last_result[i]);
182 printk("\n");
183#endif
184 if (!needresult)
Ingo Molnar3593cab2006-02-07 06:49:14 -0200185 mutex_unlock(&ttusb->semusb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700186 return 0;
187}
188
189static int ttusb_result(struct ttusb *ttusb, u8 * data, int len)
190{
191 memcpy(data, ttusb->last_result, len);
Ingo Molnar3593cab2006-02-07 06:49:14 -0200192 mutex_unlock(&ttusb->semusb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700193 return 0;
194}
195
196static int ttusb_i2c_msg(struct ttusb *ttusb,
197 u8 addr, u8 * snd_buf, u8 snd_len, u8 * rcv_buf,
198 u8 rcv_len)
199{
200 u8 b[0x28];
201 u8 id = ++ttusb->c;
202 int i, err;
203
204 if (snd_len > 0x28 - 7 || rcv_len > 0x20 - 7)
205 return -EINVAL;
206
207 b[0] = 0xaa;
208 b[1] = id;
209 b[2] = 0x31;
210 b[3] = snd_len + 3;
211 b[4] = addr << 1;
212 b[5] = snd_len;
213 b[6] = rcv_len;
214
215 for (i = 0; i < snd_len; i++)
216 b[7 + i] = snd_buf[i];
217
218 err = ttusb_cmd(ttusb, b, snd_len + 7, 1);
219
220 if (err)
221 return -EREMOTEIO;
222
223 err = ttusb_result(ttusb, b, 0x20);
224
Mauro Carvalho Chehab9101e622005-12-12 00:37:24 -0800225 /* check if the i2c transaction was successful */
226 if ((snd_len != b[5]) || (rcv_len != b[6])) return -EREMOTEIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700227
228 if (rcv_len > 0) {
229
230 if (err || b[0] != 0x55 || b[1] != id) {
231 dprintk
232 ("%s: usb_bulk_msg(recv) failed, err == %i, id == %02x, b == ",
233 __FUNCTION__, err, id);
234 return -EREMOTEIO;
235 }
236
237 for (i = 0; i < rcv_len; i++)
238 rcv_buf[i] = b[7 + i];
239 }
240
241 return rcv_len;
242}
243
244static int master_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, int num)
245{
246 struct ttusb *ttusb = i2c_get_adapdata(adapter);
247 int i = 0;
248 int inc;
249
Ingo Molnar3593cab2006-02-07 06:49:14 -0200250 if (mutex_lock_interruptible(&ttusb->semi2c) < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700251 return -EAGAIN;
252
253 while (i < num) {
254 u8 addr, snd_len, rcv_len, *snd_buf, *rcv_buf;
255 int err;
256
257 if (num > i + 1 && (msg[i + 1].flags & I2C_M_RD)) {
258 addr = msg[i].addr;
259 snd_buf = msg[i].buf;
260 snd_len = msg[i].len;
261 rcv_buf = msg[i + 1].buf;
262 rcv_len = msg[i + 1].len;
263 inc = 2;
264 } else {
265 addr = msg[i].addr;
266 snd_buf = msg[i].buf;
267 snd_len = msg[i].len;
268 rcv_buf = NULL;
269 rcv_len = 0;
270 inc = 1;
271 }
272
273 err = ttusb_i2c_msg(ttusb, addr,
274 snd_buf, snd_len, rcv_buf, rcv_len);
275
276 if (err < rcv_len) {
277 dprintk("%s: i == %i\n", __FUNCTION__, i);
278 break;
279 }
280
281 i += inc;
282 }
283
Ingo Molnar3593cab2006-02-07 06:49:14 -0200284 mutex_unlock(&ttusb->semi2c);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700285 return i;
286}
287
288#include "dvb-ttusb-dspbootcode.h"
289
290static int ttusb_boot_dsp(struct ttusb *ttusb)
291{
292 int i, err;
293 u8 b[40];
294
295 /* BootBlock */
296 b[0] = 0xaa;
297 b[2] = 0x13;
298 b[3] = 28;
299
300 /* upload dsp code in 32 byte steps (36 didn't work for me ...) */
301 /* 32 is max packet size, no messages should be splitted. */
302 for (i = 0; i < sizeof(dsp_bootcode); i += 28) {
303 memcpy(&b[4], &dsp_bootcode[i], 28);
304
305 b[1] = ++ttusb->c;
306
307 err = ttusb_cmd(ttusb, b, 32, 0);
308 if (err)
309 goto done;
310 }
311
312 /* last block ... */
313 b[1] = ++ttusb->c;
314 b[2] = 0x13;
315 b[3] = 0;
316
317 err = ttusb_cmd(ttusb, b, 4, 0);
318 if (err)
319 goto done;
320
321 /* BootEnd */
322 b[1] = ++ttusb->c;
323 b[2] = 0x14;
324 b[3] = 0;
325
326 err = ttusb_cmd(ttusb, b, 4, 0);
327
328 done:
329 if (err) {
330 dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
331 __FUNCTION__, err);
332 }
333
334 return err;
335}
336
337static int ttusb_set_channel(struct ttusb *ttusb, int chan_id, int filter_type,
338 int pid)
339{
340 int err;
341 /* SetChannel */
342 u8 b[] = { 0xaa, ++ttusb->c, 0x22, 4, chan_id, filter_type,
343 (pid >> 8) & 0xff, pid & 0xff
344 };
345
346 err = ttusb_cmd(ttusb, b, sizeof(b), 0);
347 return err;
348}
349
350static int ttusb_del_channel(struct ttusb *ttusb, int channel_id)
351{
352 int err;
353 /* DelChannel */
354 u8 b[] = { 0xaa, ++ttusb->c, 0x23, 1, channel_id };
355
356 err = ttusb_cmd(ttusb, b, sizeof(b), 0);
357 return err;
358}
359
360#ifdef TTUSB_HWSECTIONS
361static int ttusb_set_filter(struct ttusb *ttusb, int filter_id,
362 int associated_chan, u8 filter[8], u8 mask[8])
363{
364 int err;
365 /* SetFilter */
366 u8 b[] = { 0xaa, 0, 0x24, 0x1a, filter_id, associated_chan,
367 filter[0], filter[1], filter[2], filter[3],
368 filter[4], filter[5], filter[6], filter[7],
369 filter[8], filter[9], filter[10], filter[11],
370 mask[0], mask[1], mask[2], mask[3],
371 mask[4], mask[5], mask[6], mask[7],
372 mask[8], mask[9], mask[10], mask[11]
373 };
374
375 err = ttusb_cmd(ttusb, b, sizeof(b), 0);
376 return err;
377}
378
379static int ttusb_del_filter(struct ttusb *ttusb, int filter_id)
380{
381 int err;
382 /* DelFilter */
383 u8 b[] = { 0xaa, ++ttusb->c, 0x25, 1, filter_id };
384
385 err = ttusb_cmd(ttusb, b, sizeof(b), 0);
386 return err;
387}
388#endif
389
390static int ttusb_init_controller(struct ttusb *ttusb)
391{
392 u8 b0[] = { 0xaa, ++ttusb->c, 0x15, 1, 0 };
393 u8 b1[] = { 0xaa, ++ttusb->c, 0x15, 1, 1 };
394 u8 b2[] = { 0xaa, ++ttusb->c, 0x32, 1, 0 };
395 /* i2c write read: 5 bytes, addr 0x10, 0x02 bytes write, 1 bytes read. */
396 u8 b3[] =
397 { 0xaa, ++ttusb->c, 0x31, 5, 0x10, 0x02, 0x01, 0x00, 0x1e };
398 u8 b4[] =
399 { 0x55, ttusb->c, 0x31, 4, 0x10, 0x02, 0x01, 0x00, 0x1e };
400
401 u8 get_version[] = { 0xaa, ++ttusb->c, 0x17, 5, 0, 0, 0, 0, 0 };
402 u8 get_dsp_version[0x20] =
403 { 0xaa, ++ttusb->c, 0x26, 28, 0, 0, 0, 0, 0 };
404 int err;
405
406 /* reset board */
407 if ((err = ttusb_cmd(ttusb, b0, sizeof(b0), 0)))
408 return err;
409
410 /* reset board (again?) */
411 if ((err = ttusb_cmd(ttusb, b1, sizeof(b1), 0)))
412 return err;
413
414 ttusb_boot_dsp(ttusb);
415
416 /* set i2c bit rate */
417 if ((err = ttusb_cmd(ttusb, b2, sizeof(b2), 0)))
418 return err;
419
420 if ((err = ttusb_cmd(ttusb, b3, sizeof(b3), 1)))
421 return err;
422
423 err = ttusb_result(ttusb, b4, sizeof(b4));
424
425 if ((err = ttusb_cmd(ttusb, get_version, sizeof(get_version), 1)))
426 return err;
427
428 if ((err = ttusb_result(ttusb, get_version, sizeof(get_version))))
429 return err;
430
431 dprintk("%s: stc-version: %c%c%c%c%c\n", __FUNCTION__,
432 get_version[4], get_version[5], get_version[6],
433 get_version[7], get_version[8]);
434
435 if (memcmp(get_version + 4, "V 0.0", 5) &&
436 memcmp(get_version + 4, "V 1.1", 5) &&
437 memcmp(get_version + 4, "V 2.1", 5) &&
438 memcmp(get_version + 4, "V 2.2", 5)) {
439 printk
440 ("%s: unknown STC version %c%c%c%c%c, please report!\n",
441 __FUNCTION__, get_version[4], get_version[5],
442 get_version[6], get_version[7], get_version[8]);
443 }
444
445 ttusb->revision = ((get_version[6] - '0') << 4) |
446 (get_version[8] - '0');
447
448 err =
449 ttusb_cmd(ttusb, get_dsp_version, sizeof(get_dsp_version), 1);
450 if (err)
451 return err;
452
453 err =
454 ttusb_result(ttusb, get_dsp_version, sizeof(get_dsp_version));
455 if (err)
456 return err;
457 printk("%s: dsp-version: %c%c%c\n", __FUNCTION__,
458 get_dsp_version[4], get_dsp_version[5], get_dsp_version[6]);
459 return 0;
460}
461
462#ifdef TTUSB_DISEQC
463static int ttusb_send_diseqc(struct dvb_frontend* fe,
464 const struct dvb_diseqc_master_cmd *cmd)
465{
466 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
467 u8 b[12] = { 0xaa, ++ttusb->c, 0x18 };
468
469 int err;
470
471 b[3] = 4 + 2 + cmd->msg_len;
472 b[4] = 0xFF; /* send diseqc master, not burst */
473 b[5] = cmd->msg_len;
474
475 memcpy(b + 5, cmd->msg, cmd->msg_len);
476
477 /* Diseqc */
478 if ((err = ttusb_cmd(ttusb, b, 4 + b[3], 0))) {
479 dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
480 __FUNCTION__, err);
481 }
482
483 return err;
484}
485#endif
486
Linus Torvalds1da177e2005-04-16 15:20:36 -0700487static int ttusb_update_lnb(struct ttusb *ttusb)
488{
489 u8 b[] = { 0xaa, ++ttusb->c, 0x16, 5, /*power: */ 1,
490 ttusb->voltage == SEC_VOLTAGE_18 ? 0 : 1,
491 ttusb->tone == SEC_TONE_ON ? 1 : 0, 1, 1
492 };
493 int err;
494
495 /* SetLNB */
496 if ((err = ttusb_cmd(ttusb, b, sizeof(b), 0))) {
497 dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
498 __FUNCTION__, err);
499 }
500
501 return err;
502}
503
504static int ttusb_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
505{
506 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
507
508 ttusb->voltage = voltage;
509 return ttusb_update_lnb(ttusb);
510}
511
512#ifdef TTUSB_TONE
513static int ttusb_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
514{
515 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
516
517 ttusb->tone = tone;
518 return ttusb_update_lnb(ttusb);
519}
520#endif
521
522
523#if 0
524static void ttusb_set_led_freq(struct ttusb *ttusb, u8 freq)
525{
526 u8 b[] = { 0xaa, ++ttusb->c, 0x19, 1, freq };
527 int err, actual_len;
528
529 err = ttusb_cmd(ttusb, b, sizeof(b), 0);
530 if (err) {
531 dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
532 __FUNCTION__, err);
533 }
534}
535#endif
536
537/*****************************************************************************/
538
539#ifdef TTUSB_HWSECTIONS
540static void ttusb_handle_ts_data(struct ttusb_channel *channel,
541 const u8 * data, int len);
542static void ttusb_handle_sec_data(struct ttusb_channel *channel,
543 const u8 * data, int len);
544#endif
545
Marcelo Feitoza Parisi4da006c2005-09-09 13:03:15 -0700546static int numpkt = 0, numts, numstuff, numsec, numinvalid;
547static unsigned long lastj;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700548
549static void ttusb_process_muxpack(struct ttusb *ttusb, const u8 * muxpack,
550 int len)
551{
552 u16 csum = 0, cc;
553 int i;
554 for (i = 0; i < len; i += 2)
555 csum ^= le16_to_cpup((u16 *) (muxpack + i));
556 if (csum) {
557 printk("%s: muxpack with incorrect checksum, ignoring\n",
558 __FUNCTION__);
559 numinvalid++;
560 return;
561 }
562
563 cc = (muxpack[len - 4] << 8) | muxpack[len - 3];
564 cc &= 0x7FFF;
565 if ((cc != ttusb->cc) && (ttusb->cc != -1))
566 printk("%s: cc discontinuity (%d frames missing)\n",
567 __FUNCTION__, (cc - ttusb->cc) & 0x7FFF);
568 ttusb->cc = (cc + 1) & 0x7FFF;
569 if (muxpack[0] & 0x80) {
570#ifdef TTUSB_HWSECTIONS
571 /* section data */
572 int pusi = muxpack[0] & 0x40;
573 int channel = muxpack[0] & 0x1F;
574 int payload = muxpack[1];
575 const u8 *data = muxpack + 2;
576 /* check offset flag */
577 if (muxpack[0] & 0x20)
578 data++;
579
580 ttusb_handle_sec_data(ttusb->channel + channel, data,
581 payload);
582 data += payload;
583
584 if ((!!(ttusb->muxpack[0] & 0x20)) ^
585 !!(ttusb->muxpack[1] & 1))
586 data++;
587#warning TODO: pusi
588 printk("cc: %04x\n", (data[0] << 8) | data[1]);
589#endif
590 numsec++;
591 } else if (muxpack[0] == 0x47) {
592#ifdef TTUSB_HWSECTIONS
593 /* we have TS data here! */
594 int pid = ((muxpack[1] & 0x0F) << 8) | muxpack[2];
595 int channel;
596 for (channel = 0; channel < TTUSB_MAXCHANNEL; ++channel)
597 if (ttusb->channel[channel].active
598 && (pid == ttusb->channel[channel].pid))
599 ttusb_handle_ts_data(ttusb->channel +
600 channel, muxpack,
601 188);
602#endif
603 numts++;
604 dvb_dmx_swfilter_packets(&ttusb->dvb_demux, muxpack, 1);
605 } else if (muxpack[0] != 0) {
606 numinvalid++;
607 printk("illegal muxpack type %02x\n", muxpack[0]);
608 } else
609 numstuff++;
610}
611
612static void ttusb_process_frame(struct ttusb *ttusb, u8 * data, int len)
613{
614 int maxwork = 1024;
615 while (len) {
616 if (!(maxwork--)) {
617 printk("%s: too much work\n", __FUNCTION__);
618 break;
619 }
620
621 switch (ttusb->mux_state) {
622 case 0:
623 case 1:
624 case 2:
625 len--;
626 if (*data++ == 0xAA)
627 ++ttusb->mux_state;
628 else {
629 ttusb->mux_state = 0;
630#if DEBUG > 3
631 if (ttusb->insync)
632 printk("%02x ", data[-1]);
633#else
634 if (ttusb->insync) {
635 printk("%s: lost sync.\n",
636 __FUNCTION__);
637 ttusb->insync = 0;
638 }
639#endif
640 }
641 break;
642 case 3:
643 ttusb->insync = 1;
644 len--;
645 ttusb->mux_npacks = *data++;
646 ++ttusb->mux_state;
647 ttusb->muxpack_ptr = 0;
648 /* maximum bytes, until we know the length */
649 ttusb->muxpack_len = 2;
650 break;
651 case 4:
652 {
653 int avail;
654 avail = len;
655 if (avail >
656 (ttusb->muxpack_len -
657 ttusb->muxpack_ptr))
658 avail =
659 ttusb->muxpack_len -
660 ttusb->muxpack_ptr;
661 memcpy(ttusb->muxpack + ttusb->muxpack_ptr,
662 data, avail);
663 ttusb->muxpack_ptr += avail;
Eric Sesterhennae246012006-03-13 13:17:11 -0300664 BUG_ON(ttusb->muxpack_ptr > 264);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700665 data += avail;
666 len -= avail;
667 /* determine length */
668 if (ttusb->muxpack_ptr == 2) {
669 if (ttusb->muxpack[0] & 0x80) {
670 ttusb->muxpack_len =
671 ttusb->muxpack[1] + 2;
672 if (ttusb->
673 muxpack[0] & 0x20)
674 ttusb->
675 muxpack_len++;
676 if ((!!
677 (ttusb->
678 muxpack[0] & 0x20)) ^
679 !!(ttusb->
680 muxpack[1] & 1))
681 ttusb->
682 muxpack_len++;
683 ttusb->muxpack_len += 4;
684 } else if (ttusb->muxpack[0] ==
685 0x47)
686 ttusb->muxpack_len =
687 188 + 4;
688 else if (ttusb->muxpack[0] == 0x00)
689 ttusb->muxpack_len =
690 ttusb->muxpack[1] + 2 +
691 4;
692 else {
693 dprintk
694 ("%s: invalid state: first byte is %x\n",
695 __FUNCTION__,
696 ttusb->muxpack[0]);
697 ttusb->mux_state = 0;
698 }
699 }
700
701 /**
702 * if length is valid and we reached the end:
703 * goto next muxpack
704 */
705 if ((ttusb->muxpack_ptr >= 2) &&
706 (ttusb->muxpack_ptr ==
707 ttusb->muxpack_len)) {
708 ttusb_process_muxpack(ttusb,
709 ttusb->
710 muxpack,
711 ttusb->
712 muxpack_ptr);
713 ttusb->muxpack_ptr = 0;
714 /* maximum bytes, until we know the length */
715 ttusb->muxpack_len = 2;
716
717 /**
718 * no muxpacks left?
719 * return to search-sync state
720 */
721 if (!ttusb->mux_npacks--) {
722 ttusb->mux_state = 0;
723 break;
724 }
725 }
726 break;
727 }
728 default:
729 BUG();
730 break;
731 }
732 }
733}
734
David Howells7d12e782006-10-05 14:55:46 +0100735static void ttusb_iso_irq(struct urb *urb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700736{
737 struct ttusb *ttusb = urb->context;
738
739 if (!ttusb->iso_streaming)
740 return;
741
742#if 0
743 printk("%s: status %d, errcount == %d, length == %i\n",
744 __FUNCTION__,
745 urb->status, urb->error_count, urb->actual_length);
746#endif
747
748 if (!urb->status) {
749 int i;
750 for (i = 0; i < urb->number_of_packets; ++i) {
751 struct usb_iso_packet_descriptor *d;
752 u8 *data;
753 int len;
754 numpkt++;
Marcelo Feitoza Parisi4da006c2005-09-09 13:03:15 -0700755 if (time_after_eq(jiffies, lastj + HZ)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700756#if DEBUG > 2
757 printk
758 ("frames/s: %d (ts: %d, stuff %d, sec: %d, invalid: %d, all: %d)\n",
759 numpkt * HZ / (jiffies - lastj),
760 numts, numstuff, numsec, numinvalid,
761 numts + numstuff + numsec +
762 numinvalid);
763#endif
764 numts = numstuff = numsec = numinvalid = 0;
765 lastj = jiffies;
766 numpkt = 0;
767 }
768 d = &urb->iso_frame_desc[i];
769 data = urb->transfer_buffer + d->offset;
770 len = d->actual_length;
771 d->actual_length = 0;
772 d->status = 0;
773 ttusb_process_frame(ttusb, data, len);
774 }
775 }
776 usb_submit_urb(urb, GFP_ATOMIC);
777}
778
779static void ttusb_free_iso_urbs(struct ttusb *ttusb)
780{
781 int i;
782
783 for (i = 0; i < ISO_BUF_COUNT; i++)
784 if (ttusb->iso_urb[i])
785 usb_free_urb(ttusb->iso_urb[i]);
786
787 pci_free_consistent(NULL,
788 ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF *
789 ISO_BUF_COUNT, ttusb->iso_buffer,
790 ttusb->iso_dma_handle);
791}
792
793static int ttusb_alloc_iso_urbs(struct ttusb *ttusb)
794{
795 int i;
796
797 ttusb->iso_buffer = pci_alloc_consistent(NULL,
798 ISO_FRAME_SIZE *
799 FRAMES_PER_ISO_BUF *
800 ISO_BUF_COUNT,
801 &ttusb->iso_dma_handle);
802
803 memset(ttusb->iso_buffer, 0,
804 ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF * ISO_BUF_COUNT);
805
806 for (i = 0; i < ISO_BUF_COUNT; i++) {
807 struct urb *urb;
808
809 if (!
810 (urb =
811 usb_alloc_urb(FRAMES_PER_ISO_BUF, GFP_ATOMIC))) {
812 ttusb_free_iso_urbs(ttusb);
813 return -ENOMEM;
814 }
815
816 ttusb->iso_urb[i] = urb;
817 }
818
819 return 0;
820}
821
822static void ttusb_stop_iso_xfer(struct ttusb *ttusb)
823{
824 int i;
825
826 for (i = 0; i < ISO_BUF_COUNT; i++)
827 usb_kill_urb(ttusb->iso_urb[i]);
828
829 ttusb->iso_streaming = 0;
830}
831
832static int ttusb_start_iso_xfer(struct ttusb *ttusb)
833{
834 int i, j, err, buffer_offset = 0;
835
836 if (ttusb->iso_streaming) {
837 printk("%s: iso xfer already running!\n", __FUNCTION__);
838 return 0;
839 }
840
841 ttusb->cc = -1;
842 ttusb->insync = 0;
843 ttusb->mux_state = 0;
844
845 for (i = 0; i < ISO_BUF_COUNT; i++) {
846 int frame_offset = 0;
847 struct urb *urb = ttusb->iso_urb[i];
848
849 urb->dev = ttusb->dev;
850 urb->context = ttusb;
851 urb->complete = ttusb_iso_irq;
852 urb->pipe = ttusb->isoc_in_pipe;
853 urb->transfer_flags = URB_ISO_ASAP;
854 urb->interval = 1;
855 urb->number_of_packets = FRAMES_PER_ISO_BUF;
856 urb->transfer_buffer_length =
857 ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF;
858 urb->transfer_buffer = ttusb->iso_buffer + buffer_offset;
859 buffer_offset += ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF;
860
861 for (j = 0; j < FRAMES_PER_ISO_BUF; j++) {
862 urb->iso_frame_desc[j].offset = frame_offset;
863 urb->iso_frame_desc[j].length = ISO_FRAME_SIZE;
864 frame_offset += ISO_FRAME_SIZE;
865 }
866 }
867
868 for (i = 0; i < ISO_BUF_COUNT; i++) {
869 if ((err = usb_submit_urb(ttusb->iso_urb[i], GFP_ATOMIC))) {
870 ttusb_stop_iso_xfer(ttusb);
871 printk
872 ("%s: failed urb submission (%i: err = %i)!\n",
873 __FUNCTION__, i, err);
874 return err;
875 }
876 }
877
878 ttusb->iso_streaming = 1;
879
880 return 0;
881}
882
883#ifdef TTUSB_HWSECTIONS
884static void ttusb_handle_ts_data(struct dvb_demux_feed *dvbdmxfeed, const u8 * data,
885 int len)
886{
887 dvbdmxfeed->cb.ts(data, len, 0, 0, &dvbdmxfeed->feed.ts, 0);
888}
889
890static void ttusb_handle_sec_data(struct dvb_demux_feed *dvbdmxfeed, const u8 * data,
891 int len)
892{
893// struct dvb_demux_feed *dvbdmxfeed = channel->dvbdmxfeed;
894#error TODO: handle ugly stuff
895// dvbdmxfeed->cb.sec(data, len, 0, 0, &dvbdmxfeed->feed.sec, 0);
896}
897#endif
898
899static int ttusb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
900{
901 struct ttusb *ttusb = (struct ttusb *) dvbdmxfeed->demux;
902 int feed_type = 1;
903
904 dprintk("ttusb_start_feed\n");
905
906 switch (dvbdmxfeed->type) {
907 case DMX_TYPE_TS:
908 break;
909 case DMX_TYPE_SEC:
910 break;
911 default:
912 return -EINVAL;
913 }
914
915 if (dvbdmxfeed->type == DMX_TYPE_TS) {
916 switch (dvbdmxfeed->pes_type) {
917 case DMX_TS_PES_VIDEO:
918 case DMX_TS_PES_AUDIO:
919 case DMX_TS_PES_TELETEXT:
920 case DMX_TS_PES_PCR:
921 case DMX_TS_PES_OTHER:
922 break;
923 default:
924 return -EINVAL;
925 }
926 }
927
928#ifdef TTUSB_HWSECTIONS
929#error TODO: allocate filters
930 if (dvbdmxfeed->type == DMX_TYPE_TS) {
931 feed_type = 1;
932 } else if (dvbdmxfeed->type == DMX_TYPE_SEC) {
933 feed_type = 2;
934 }
935#endif
936
937 ttusb_set_channel(ttusb, dvbdmxfeed->index, feed_type, dvbdmxfeed->pid);
938
939 if (0 == ttusb->running_feed_count++)
940 ttusb_start_iso_xfer(ttusb);
941
942 return 0;
943}
944
945static int ttusb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
946{
947 struct ttusb *ttusb = (struct ttusb *) dvbdmxfeed->demux;
948
949 ttusb_del_channel(ttusb, dvbdmxfeed->index);
950
951 if (--ttusb->running_feed_count == 0)
952 ttusb_stop_iso_xfer(ttusb);
953
954 return 0;
955}
956
957static int ttusb_setup_interfaces(struct ttusb *ttusb)
958{
959 usb_set_interface(ttusb->dev, 1, 1);
960
961 ttusb->bulk_out_pipe = usb_sndbulkpipe(ttusb->dev, 1);
962 ttusb->bulk_in_pipe = usb_rcvbulkpipe(ttusb->dev, 1);
963 ttusb->isoc_in_pipe = usb_rcvisocpipe(ttusb->dev, 2);
964
965 return 0;
966}
967
968#if 0
969static u8 stc_firmware[8192];
970
971static int stc_open(struct inode *inode, struct file *file)
972{
973 struct ttusb *ttusb = file->private_data;
974 int addr;
975
976 for (addr = 0; addr < 8192; addr += 16) {
977 u8 snd_buf[2] = { addr >> 8, addr & 0xFF };
978 ttusb_i2c_msg(ttusb, 0x50, snd_buf, 2, stc_firmware + addr,
979 16);
980 }
981
982 return 0;
983}
984
985static ssize_t stc_read(struct file *file, char *buf, size_t count,
986 loff_t * offset)
987{
988 int tc = count;
989
990 if ((tc + *offset) > 8192)
991 tc = 8192 - *offset;
992
993 if (tc < 0)
994 return 0;
995
996 if (copy_to_user(buf, stc_firmware + *offset, tc))
997 return -EFAULT;
998
999 *offset += tc;
1000
1001 return tc;
1002}
1003
1004static int stc_release(struct inode *inode, struct file *file)
1005{
1006 return 0;
1007}
1008
1009static struct file_operations stc_fops = {
1010 .owner = THIS_MODULE,
1011 .read = stc_read,
1012 .open = stc_open,
1013 .release = stc_release,
1014};
1015#endif
1016
1017static u32 functionality(struct i2c_adapter *adapter)
1018{
1019 return I2C_FUNC_I2C;
1020}
1021
1022
1023
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001024static int alps_tdmb7_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001025{
1026 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1027 u8 data[4];
1028 struct i2c_msg msg = {.addr=0x61, .flags=0, .buf=data, .len=sizeof(data) };
1029 u32 div;
1030
1031 div = (params->frequency + 36166667) / 166667;
1032
1033 data[0] = (div >> 8) & 0x7f;
1034 data[1] = div & 0xff;
1035 data[2] = ((div >> 10) & 0x60) | 0x85;
1036 data[3] = params->frequency < 592000000 ? 0x40 : 0x80;
1037
Patrick Boettcherdea74862006-05-14 05:01:31 -03001038 if (fe->ops.i2c_gate_ctrl)
1039 fe->ops.i2c_gate_ctrl(fe, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001040 if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1) return -EIO;
1041 return 0;
1042}
1043
Johannes Stezenbachd91b7302005-05-16 21:54:38 -07001044static struct cx22700_config alps_tdmb7_config = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001045 .demod_address = 0x43,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001046};
1047
1048
1049
1050
1051
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001052static int philips_tdm1316l_tuner_init(struct dvb_frontend* fe)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001053{
1054 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1055 static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab };
1056 static u8 disable_mc44BC374c[] = { 0x1d, 0x74, 0xa0, 0x68 };
1057 struct i2c_msg tuner_msg = { .addr=0x60, .flags=0, .buf=td1316_init, .len=sizeof(td1316_init) };
1058
1059 // setup PLL configuration
Patrick Boettcherdea74862006-05-14 05:01:31 -03001060 if (fe->ops.i2c_gate_ctrl)
1061 fe->ops.i2c_gate_ctrl(fe, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001062 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);
Patrick Boettcherdea74862006-05-14 05:01:31 -03001069 if (fe->ops.i2c_gate_ctrl)
1070 fe->ops.i2c_gate_ctrl(fe, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001071 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) {
1072 i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1);
1073 }
1074
1075 return 0;
1076}
1077
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001078static int philips_tdm1316l_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001079{
1080 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1081 u8 tuner_buf[4];
1082 struct i2c_msg tuner_msg = {.addr=0x60, .flags=0, .buf=tuner_buf, .len=sizeof(tuner_buf) };
1083 int tuner_frequency = 0;
1084 u8 band, cp, filter;
1085
1086 // determine charge pump
1087 tuner_frequency = params->frequency + 36130000;
1088 if (tuner_frequency < 87000000) return -EINVAL;
1089 else if (tuner_frequency < 130000000) cp = 3;
1090 else if (tuner_frequency < 160000000) cp = 5;
1091 else if (tuner_frequency < 200000000) cp = 6;
1092 else if (tuner_frequency < 290000000) cp = 3;
1093 else if (tuner_frequency < 420000000) cp = 5;
1094 else if (tuner_frequency < 480000000) cp = 6;
1095 else if (tuner_frequency < 620000000) cp = 3;
1096 else if (tuner_frequency < 830000000) cp = 5;
1097 else if (tuner_frequency < 895000000) cp = 7;
1098 else return -EINVAL;
1099
1100 // determine band
1101 if (params->frequency < 49000000) return -EINVAL;
1102 else if (params->frequency < 159000000) band = 1;
1103 else if (params->frequency < 444000000) band = 2;
1104 else if (params->frequency < 861000000) band = 4;
1105 else return -EINVAL;
1106
1107 // setup PLL filter
1108 switch (params->u.ofdm.bandwidth) {
1109 case BANDWIDTH_6_MHZ:
Andrew de Quinceyc10d14d2006-08-08 09:10:08 -03001110 tda1004x_writereg(fe, 0x0C, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001111 filter = 0;
1112 break;
1113
1114 case BANDWIDTH_7_MHZ:
Andrew de Quinceyc10d14d2006-08-08 09:10:08 -03001115 tda1004x_writereg(fe, 0x0C, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001116 filter = 0;
1117 break;
1118
1119 case BANDWIDTH_8_MHZ:
Andrew de Quinceyc10d14d2006-08-08 09:10:08 -03001120 tda1004x_writereg(fe, 0x0C, 0xFF);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001121 filter = 1;
1122 break;
1123
1124 default:
1125 return -EINVAL;
1126 }
1127
1128 // calculate divisor
1129 // ((36130000+((1000000/6)/2)) + Finput)/(1000000/6)
1130 tuner_frequency = (((params->frequency / 1000) * 6) + 217280) / 1000;
1131
1132 // setup tuner buffer
1133 tuner_buf[0] = tuner_frequency >> 8;
1134 tuner_buf[1] = tuner_frequency & 0xff;
1135 tuner_buf[2] = 0xca;
1136 tuner_buf[3] = (cp << 5) | (filter << 3) | band;
1137
Patrick Boettcherdea74862006-05-14 05:01:31 -03001138 if (fe->ops.i2c_gate_ctrl)
1139 fe->ops.i2c_gate_ctrl(fe, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001140 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1)
1141 return -EIO;
1142
1143 msleep(1);
1144 return 0;
1145}
1146
1147static int philips_tdm1316l_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
1148{
1149 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1150
1151 return request_firmware(fw, name, &ttusb->dev->dev);
1152}
1153
1154static struct tda1004x_config philips_tdm1316l_config = {
1155
1156 .demod_address = 0x8,
1157 .invert = 1,
1158 .invert_oclk = 0,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001159 .request_firmware = philips_tdm1316l_request_firmware,
1160};
1161
1162static u8 alps_bsbe1_inittab[] = {
Mauro Carvalho Chehab9101e622005-12-12 00:37:24 -08001163 0x01, 0x15,
1164 0x02, 0x30,
1165 0x03, 0x00,
1166 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
1167 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
1168 0x06, 0x40, /* DAC not used, set to high impendance mode */
1169 0x07, 0x00, /* DAC LSB */
1170 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
1171 0x09, 0x00, /* FIFO */
1172 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
1173 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
1174 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
1175 0x10, 0x3f, // AGC2 0x3d
1176 0x11, 0x84,
1177 0x12, 0xb9,
1178 0x15, 0xc9, // lock detector threshold
1179 0x16, 0x00,
1180 0x17, 0x00,
1181 0x18, 0x00,
1182 0x19, 0x00,
1183 0x1a, 0x00,
1184 0x1f, 0x50,
1185 0x20, 0x00,
1186 0x21, 0x00,
1187 0x22, 0x00,
1188 0x23, 0x00,
1189 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
1190 0x29, 0x1e, // 1/2 threshold
1191 0x2a, 0x14, // 2/3 threshold
1192 0x2b, 0x0f, // 3/4 threshold
1193 0x2c, 0x09, // 5/6 threshold
1194 0x2d, 0x05, // 7/8 threshold
1195 0x2e, 0x01,
1196 0x31, 0x1f, // test all FECs
1197 0x32, 0x19, // viterbi and synchro search
1198 0x33, 0xfc, // rs control
1199 0x34, 0x93, // error control
1200 0x0f, 0x92,
1201 0xff, 0xff
Linus Torvalds1da177e2005-04-16 15:20:36 -07001202};
1203
1204static u8 alps_bsru6_inittab[] = {
1205 0x01, 0x15,
1206 0x02, 0x30,
1207 0x03, 0x00,
1208 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
1209 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
1210 0x06, 0x40, /* DAC not used, set to high impendance mode */
1211 0x07, 0x00, /* DAC LSB */
1212 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
1213 0x09, 0x00, /* FIFO */
1214 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
1215 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
1216 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
1217 0x10, 0x3f, // AGC2 0x3d
1218 0x11, 0x84,
Oliver Endriss7f44dcd2005-11-08 21:35:44 -08001219 0x12, 0xb9,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001220 0x15, 0xc9, // lock detector threshold
1221 0x16, 0x00,
1222 0x17, 0x00,
1223 0x18, 0x00,
1224 0x19, 0x00,
1225 0x1a, 0x00,
1226 0x1f, 0x50,
1227 0x20, 0x00,
1228 0x21, 0x00,
1229 0x22, 0x00,
1230 0x23, 0x00,
1231 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
1232 0x29, 0x1e, // 1/2 threshold
1233 0x2a, 0x14, // 2/3 threshold
1234 0x2b, 0x0f, // 3/4 threshold
1235 0x2c, 0x09, // 5/6 threshold
1236 0x2d, 0x05, // 7/8 threshold
1237 0x2e, 0x01,
1238 0x31, 0x1f, // test all FECs
1239 0x32, 0x19, // viterbi and synchro search
1240 0x33, 0xfc, // rs control
1241 0x34, 0x93, // error control
1242 0x0f, 0x52,
1243 0xff, 0xff
1244};
1245
1246static int alps_stv0299_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
1247{
1248 u8 aclk = 0;
1249 u8 bclk = 0;
1250
1251 if (srate < 1500000) {
1252 aclk = 0xb7;
1253 bclk = 0x47;
1254 } else if (srate < 3000000) {
1255 aclk = 0xb7;
1256 bclk = 0x4b;
1257 } else if (srate < 7000000) {
1258 aclk = 0xb7;
1259 bclk = 0x4f;
1260 } else if (srate < 14000000) {
1261 aclk = 0xb7;
1262 bclk = 0x53;
1263 } else if (srate < 30000000) {
1264 aclk = 0xb6;
1265 bclk = 0x53;
1266 } else if (srate < 45000000) {
1267 aclk = 0xb4;
1268 bclk = 0x51;
1269 }
1270
1271 stv0299_writereg(fe, 0x13, aclk);
1272 stv0299_writereg(fe, 0x14, bclk);
1273 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
1274 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
1275 stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
1276
1277 return 0;
1278}
1279
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001280static int philips_tsa5059_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001281{
1282 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1283 u8 buf[4];
1284 u32 div;
1285 struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
1286
1287 if ((params->frequency < 950000) || (params->frequency > 2150000))
1288 return -EINVAL;
1289
1290 div = (params->frequency + (125 - 1)) / 125; // round correctly
1291 buf[0] = (div >> 8) & 0x7f;
1292 buf[1] = div & 0xff;
1293 buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
1294 buf[3] = 0xC4;
1295
1296 if (params->frequency > 1530000)
1297 buf[3] = 0xC0;
1298
1299 /* BSBE1 wants XCE bit set */
1300 if (ttusb->revision == TTUSB_REV_2_2)
1301 buf[3] |= 0x20;
1302
Patrick Boettcherdea74862006-05-14 05:01:31 -03001303 if (fe->ops.i2c_gate_ctrl)
1304 fe->ops.i2c_gate_ctrl(fe, 1);
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001305 if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001306 return -EIO;
1307
1308 return 0;
1309}
1310
1311static struct stv0299_config alps_stv0299_config = {
1312 .demod_address = 0x68,
1313 .inittab = alps_bsru6_inittab,
1314 .mclk = 88000000UL,
1315 .invert = 1,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001316 .skip_reinit = 0,
1317 .lock_output = STV0229_LOCKOUTPUT_1,
1318 .volt13_op0_op1 = STV0299_VOLT13_OP1,
1319 .min_delay_ms = 100,
1320 .set_symbol_rate = alps_stv0299_set_symbol_rate,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001321};
1322
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001323static 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 -07001324{
1325 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1326 u8 buf[4];
1327 u32 div;
1328 struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
1329
Mauro Carvalho Chehab9101e622005-12-12 00:37:24 -08001330 div = params->frequency / 125;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001331
1332 buf[0] = (div >> 8) & 0x7f;
1333 buf[1] = div & 0xff;
1334 buf[2] = 0x8e;
1335 buf[3] = 0x00;
1336
Patrick Boettcherdea74862006-05-14 05:01:31 -03001337 if (fe->ops.i2c_gate_ctrl)
1338 fe->ops.i2c_gate_ctrl(fe, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001339 if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1)
1340 return -EIO;
1341
1342 return 0;
1343}
1344
1345static struct tda8083_config ttusb_novas_grundig_29504_491_config = {
1346
1347 .demod_address = 0x68,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001348};
1349
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001350static int alps_tdbe2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
Gavin Hamill53936392005-07-07 17:58:04 -07001351{
1352 struct ttusb* ttusb = fe->dvb->priv;
1353 u32 div;
1354 u8 data[4];
1355 struct i2c_msg msg = { .addr = 0x62, .flags = 0, .buf = data, .len = sizeof(data) };
1356
1357 div = (params->frequency + 35937500 + 31250) / 62500;
1358
1359 data[0] = (div >> 8) & 0x7f;
1360 data[1] = div & 0xff;
1361 data[2] = 0x85 | ((div >> 10) & 0x60);
1362 data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81);
1363
Patrick Boettcherdea74862006-05-14 05:01:31 -03001364 if (fe->ops.i2c_gate_ctrl)
1365 fe->ops.i2c_gate_ctrl(fe, 1);
Gavin Hamill53936392005-07-07 17:58:04 -07001366 if (i2c_transfer (&ttusb->i2c_adap, &msg, 1) != 1)
1367 return -EIO;
1368
1369 return 0;
1370}
1371
1372
1373static struct ves1820_config alps_tdbe2_config = {
1374 .demod_address = 0x09,
1375 .xin = 57840000UL,
1376 .invert = 1,
1377 .selagc = VES1820_SELAGC_SIGNAMPERR,
Gavin Hamill53936392005-07-07 17:58:04 -07001378};
1379
1380static u8 read_pwm(struct ttusb* ttusb)
1381{
1382 u8 b = 0xff;
1383 u8 pwm;
1384 struct i2c_msg msg[] = { { .addr = 0x50,.flags = 0,.buf = &b,.len = 1 },
1385 { .addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1} };
1386
1387 if ((i2c_transfer(&ttusb->i2c_adap, msg, 2) != 2) || (pwm == 0xff))
1388 pwm = 0x48;
1389
1390 return pwm;
1391}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001392
1393
Thomas Kaiserb8d4c232006-04-27 21:45:20 -03001394static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
1395{
1396 struct ttusb *ttusb = (struct ttusb *) fe->dvb->priv;
1397 u8 tuner_buf[5];
1398 struct i2c_msg tuner_msg = {.addr = 0x60,
1399 .flags = 0,
1400 .buf = tuner_buf,
1401 .len = sizeof(tuner_buf) };
1402 int tuner_frequency = 0;
1403 u8 band, cp, filter;
1404
1405 // determine charge pump
1406 tuner_frequency = params->frequency;
1407 if (tuner_frequency < 87000000) {return -EINVAL;}
1408 else if (tuner_frequency < 130000000) {cp = 3; band = 1;}
1409 else if (tuner_frequency < 160000000) {cp = 5; band = 1;}
1410 else if (tuner_frequency < 200000000) {cp = 6; band = 1;}
1411 else if (tuner_frequency < 290000000) {cp = 3; band = 2;}
1412 else if (tuner_frequency < 420000000) {cp = 5; band = 2;}
1413 else if (tuner_frequency < 480000000) {cp = 6; band = 2;}
1414 else if (tuner_frequency < 620000000) {cp = 3; band = 4;}
1415 else if (tuner_frequency < 830000000) {cp = 5; band = 4;}
1416 else if (tuner_frequency < 895000000) {cp = 7; band = 4;}
1417 else {return -EINVAL;}
1418
1419 // assume PLL filter should always be 8MHz for the moment.
1420 filter = 1;
1421
1422 // calculate divisor
1423 // (Finput + Fif)/Fref; Fif = 36125000 Hz, Fref = 62500 Hz
1424 tuner_frequency = ((params->frequency + 36125000) / 62500);
1425
1426 // setup tuner buffer
1427 tuner_buf[0] = tuner_frequency >> 8;
1428 tuner_buf[1] = tuner_frequency & 0xff;
1429 tuner_buf[2] = 0xc8;
1430 tuner_buf[3] = (cp << 5) | (filter << 3) | band;
1431 tuner_buf[4] = 0x80;
1432
Patrick Boettcherdea74862006-05-14 05:01:31 -03001433 if (fe->ops.i2c_gate_ctrl)
1434 fe->ops.i2c_gate_ctrl(fe, 1);
Thomas Kaiserb8d4c232006-04-27 21:45:20 -03001435 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) {
1436 printk("dvb-ttusb-budget: dvbc_philips_tdm1316l_pll_set Error 1\n");
1437 return -EIO;
1438 }
1439
1440 msleep(50);
1441
Patrick Boettcherdea74862006-05-14 05:01:31 -03001442 if (fe->ops.i2c_gate_ctrl)
1443 fe->ops.i2c_gate_ctrl(fe, 1);
Thomas Kaiserb8d4c232006-04-27 21:45:20 -03001444 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) {
1445 printk("dvb-ttusb-budget: dvbc_philips_tdm1316l_pll_set Error 2\n");
1446 return -EIO;
1447 }
1448
1449 msleep(1);
1450
1451 return 0;
1452}
1453
1454static u8 dvbc_philips_tdm1316l_inittab[] = {
1455 0x80, 0x21,
1456 0x80, 0x20,
1457 0x81, 0x01,
1458 0x81, 0x00,
1459 0x00, 0x09,
1460 0x01, 0x69,
1461 0x03, 0x00,
1462 0x04, 0x00,
1463 0x07, 0x00,
1464 0x08, 0x00,
1465 0x20, 0x00,
1466 0x21, 0x40,
1467 0x22, 0x00,
1468 0x23, 0x00,
1469 0x24, 0x40,
1470 0x25, 0x88,
1471 0x30, 0xff,
1472 0x31, 0x00,
1473 0x32, 0xff,
1474 0x33, 0x00,
1475 0x34, 0x50,
1476 0x35, 0x7f,
1477 0x36, 0x00,
1478 0x37, 0x20,
1479 0x38, 0x00,
1480 0x40, 0x1c,
1481 0x41, 0xff,
1482 0x42, 0x29,
1483 0x43, 0x20,
1484 0x44, 0xff,
1485 0x45, 0x00,
1486 0x46, 0x00,
1487 0x49, 0x04,
1488 0x4a, 0xff,
1489 0x4b, 0x7f,
1490 0x52, 0x30,
1491 0x55, 0xae,
1492 0x56, 0x47,
1493 0x57, 0xe1,
1494 0x58, 0x3a,
1495 0x5a, 0x1e,
1496 0x5b, 0x34,
1497 0x60, 0x00,
1498 0x63, 0x00,
1499 0x64, 0x00,
1500 0x65, 0x00,
1501 0x66, 0x00,
1502 0x67, 0x00,
1503 0x68, 0x00,
1504 0x69, 0x00,
1505 0x6a, 0x02,
1506 0x6b, 0x00,
1507 0x70, 0xff,
1508 0x71, 0x00,
1509 0x72, 0x00,
1510 0x73, 0x00,
1511 0x74, 0x0c,
1512 0x80, 0x00,
1513 0x81, 0x00,
1514 0x82, 0x00,
1515 0x83, 0x00,
1516 0x84, 0x04,
1517 0x85, 0x80,
1518 0x86, 0x24,
1519 0x87, 0x78,
1520 0x88, 0x00,
1521 0x89, 0x00,
1522 0x90, 0x01,
1523 0x91, 0x01,
1524 0xa0, 0x00,
1525 0xa1, 0x00,
1526 0xa2, 0x00,
1527 0xb0, 0x91,
1528 0xb1, 0x0b,
1529 0xc0, 0x4b,
1530 0xc1, 0x00,
1531 0xc2, 0x00,
1532 0xd0, 0x00,
1533 0xd1, 0x00,
1534 0xd2, 0x00,
1535 0xd3, 0x00,
1536 0xd4, 0x00,
1537 0xd5, 0x00,
1538 0xde, 0x00,
1539 0xdf, 0x00,
1540 0x61, 0x38,
1541 0x62, 0x0a,
1542 0x53, 0x13,
1543 0x59, 0x08,
1544 0x55, 0x00,
1545 0x56, 0x40,
1546 0x57, 0x08,
1547 0x58, 0x3d,
1548 0x88, 0x10,
1549 0xa0, 0x00,
1550 0xa0, 0x00,
1551 0xa0, 0x00,
1552 0xa0, 0x04,
1553 0xff, 0xff,
1554};
1555
1556static struct stv0297_config dvbc_philips_tdm1316l_config = {
1557 .demod_address = 0x1c,
1558 .inittab = dvbc_philips_tdm1316l_inittab,
1559 .invert = 0,
1560};
1561
Linus Torvalds1da177e2005-04-16 15:20:36 -07001562static void frontend_init(struct ttusb* ttusb)
1563{
1564 switch(le16_to_cpu(ttusb->dev->descriptor.idProduct)) {
1565 case 0x1003: // Hauppauge/TT Nova-USB-S budget (stv0299/ALPS BSRU6|BSBE1(tsa5059))
1566 // try the stv0299 based first
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001567 ttusb->fe = dvb_attach(stv0299_attach, &alps_stv0299_config, &ttusb->i2c_adap);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001568 if (ttusb->fe != NULL) {
Patrick Boettcherdea74862006-05-14 05:01:31 -03001569 ttusb->fe->ops.tuner_ops.set_params = philips_tsa5059_tuner_set_params;
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001570
Linus Torvalds1da177e2005-04-16 15:20:36 -07001571 if(ttusb->revision == TTUSB_REV_2_2) { // ALPS BSBE1
1572 alps_stv0299_config.inittab = alps_bsbe1_inittab;
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001573 dvb_attach(lnbp21_attach, ttusb->fe, &ttusb->i2c_adap, 0, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001574 } else { // ALPS BSRU6
Patrick Boettcherdea74862006-05-14 05:01:31 -03001575 ttusb->fe->ops.set_voltage = ttusb_set_voltage;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001576 }
1577 break;
1578 }
1579
1580 // Grundig 29504-491
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001581 ttusb->fe = dvb_attach(tda8083_attach, &ttusb_novas_grundig_29504_491_config, &ttusb->i2c_adap);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001582 if (ttusb->fe != NULL) {
Patrick Boettcherdea74862006-05-14 05:01:31 -03001583 ttusb->fe->ops.tuner_ops.set_params = ttusb_novas_grundig_29504_491_tuner_set_params;
1584 ttusb->fe->ops.set_voltage = ttusb_set_voltage;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001585 break;
1586 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001587 break;
1588
Gavin Hamill53936392005-07-07 17:58:04 -07001589 case 0x1004: // Hauppauge/TT DVB-C budget (ves1820/ALPS TDBE2(sp5659))
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001590 ttusb->fe = dvb_attach(ves1820_attach, &alps_tdbe2_config, &ttusb->i2c_adap, read_pwm(ttusb));
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001591 if (ttusb->fe != NULL) {
Patrick Boettcherdea74862006-05-14 05:01:31 -03001592 ttusb->fe->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params;
Gavin Hamill53936392005-07-07 17:58:04 -07001593 break;
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001594 }
Thomas Kaiserb8d4c232006-04-27 21:45:20 -03001595
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001596 ttusb->fe = dvb_attach(stv0297_attach, &dvbc_philips_tdm1316l_config, &ttusb->i2c_adap);
Thomas Kaiserb8d4c232006-04-27 21:45:20 -03001597 if (ttusb->fe != NULL) {
Patrick Boettcherdea74862006-05-14 05:01:31 -03001598 ttusb->fe->ops.tuner_ops.set_params = dvbc_philips_tdm1316l_tuner_set_params;
Thomas Kaiserb8d4c232006-04-27 21:45:20 -03001599 break;
1600 }
Gavin Hamill53936392005-07-07 17:58:04 -07001601 break;
1602
Linus Torvalds1da177e2005-04-16 15:20:36 -07001603 case 0x1005: // Hauppauge/TT Nova-USB-t budget (tda10046/Philips td1316(tda6651tt) OR cx22700/ALPS TDMB7(??))
1604 // try the ALPS TDMB7 first
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001605 ttusb->fe = dvb_attach(cx22700_attach, &alps_tdmb7_config, &ttusb->i2c_adap);
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001606 if (ttusb->fe != NULL) {
Patrick Boettcherdea74862006-05-14 05:01:31 -03001607 ttusb->fe->ops.tuner_ops.set_params = alps_tdmb7_tuner_set_params;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001608 break;
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001609 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001610
1611 // Philips td1316
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001612 ttusb->fe = dvb_attach(tda10046_attach, &philips_tdm1316l_config, &ttusb->i2c_adap);
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001613 if (ttusb->fe != NULL) {
Patrick Boettcherdea74862006-05-14 05:01:31 -03001614 ttusb->fe->ops.tuner_ops.init = philips_tdm1316l_tuner_init;
1615 ttusb->fe->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001616 break;
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001617 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001618 break;
1619 }
1620
1621 if (ttusb->fe == NULL) {
1622 printk("dvb-ttusb-budget: A frontend driver was not found for device %04x/%04x\n",
1623 le16_to_cpu(ttusb->dev->descriptor.idVendor),
1624 le16_to_cpu(ttusb->dev->descriptor.idProduct));
1625 } else {
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001626 if (dvb_register_frontend(&ttusb->adapter, ttusb->fe)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001627 printk("dvb-ttusb-budget: Frontend registration failed!\n");
Andrew de Quinceyf52a8382006-08-08 09:10:09 -03001628 dvb_frontend_detach(ttusb->fe);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001629 ttusb->fe = NULL;
1630 }
1631 }
1632}
1633
1634
1635
1636static struct i2c_algorithm ttusb_dec_algo = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001637 .master_xfer = master_xfer,
1638 .functionality = functionality,
1639};
1640
1641static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *id)
1642{
1643 struct usb_device *udev;
1644 struct ttusb *ttusb;
1645 int result;
1646
1647 dprintk("%s: TTUSB DVB connected\n", __FUNCTION__);
1648
1649 udev = interface_to_usbdev(intf);
1650
Mauro Carvalho Chehab9101e622005-12-12 00:37:24 -08001651 if (intf->altsetting->desc.bInterfaceNumber != 1) return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001652
Panagiotis Issaris74081872006-01-11 19:40:56 -02001653 if (!(ttusb = kzalloc(sizeof(struct ttusb), GFP_KERNEL)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001654 return -ENOMEM;
1655
Linus Torvalds1da177e2005-04-16 15:20:36 -07001656 ttusb->dev = udev;
1657 ttusb->c = 0;
1658 ttusb->mux_state = 0;
Ingo Molnar3593cab2006-02-07 06:49:14 -02001659 mutex_init(&ttusb->semi2c);
1660
1661 mutex_lock(&ttusb->semi2c);
1662
1663 mutex_init(&ttusb->semusb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001664
1665 ttusb_setup_interfaces(ttusb);
1666
1667 ttusb_alloc_iso_urbs(ttusb);
1668 if (ttusb_init_controller(ttusb))
1669 printk("ttusb_init_controller: error\n");
1670
Ingo Molnar3593cab2006-02-07 06:49:14 -02001671 mutex_unlock(&ttusb->semi2c);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001672
Andrew de Quinceyd09dbf92006-04-10 09:27:37 -03001673 if ((result = dvb_register_adapter(&ttusb->adapter, "Technotrend/Hauppauge Nova-USB", THIS_MODULE, &udev->dev)) < 0) {
Andrew de Quinceya064fad2006-04-06 17:05:46 -03001674 ttusb_free_iso_urbs(ttusb);
1675 kfree(ttusb);
1676 return result;
1677 }
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001678 ttusb->adapter.priv = ttusb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001679
1680 /* i2c */
1681 memset(&ttusb->i2c_adap, 0, sizeof(struct i2c_adapter));
1682 strcpy(ttusb->i2c_adap.name, "TTUSB DEC");
1683
1684 i2c_set_adapdata(&ttusb->i2c_adap, ttusb);
1685
1686#ifdef I2C_ADAP_CLASS_TV_DIGITAL
1687 ttusb->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL;
1688#else
1689 ttusb->i2c_adap.class = I2C_CLASS_TV_DIGITAL;
1690#endif
1691 ttusb->i2c_adap.algo = &ttusb_dec_algo;
1692 ttusb->i2c_adap.algo_data = NULL;
Jean Delvare12a917f2007-02-13 22:09:03 +01001693 ttusb->i2c_adap.dev.parent = &udev->dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001694
1695 result = i2c_add_adapter(&ttusb->i2c_adap);
1696 if (result) {
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001697 dvb_unregister_adapter (&ttusb->adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001698 return result;
1699 }
1700
1701 memset(&ttusb->dvb_demux, 0, sizeof(ttusb->dvb_demux));
1702
1703 ttusb->dvb_demux.dmx.capabilities =
1704 DMX_TS_FILTERING | DMX_SECTION_FILTERING;
1705 ttusb->dvb_demux.priv = NULL;
1706#ifdef TTUSB_HWSECTIONS
1707 ttusb->dvb_demux.filternum = TTUSB_MAXFILTER;
1708#else
1709 ttusb->dvb_demux.filternum = 32;
1710#endif
1711 ttusb->dvb_demux.feednum = TTUSB_MAXCHANNEL;
1712 ttusb->dvb_demux.start_feed = ttusb_start_feed;
1713 ttusb->dvb_demux.stop_feed = ttusb_stop_feed;
1714 ttusb->dvb_demux.write_to_decoder = NULL;
1715
1716 if ((result = dvb_dmx_init(&ttusb->dvb_demux)) < 0) {
1717 printk("ttusb_dvb: dvb_dmx_init failed (errno = %d)\n", result);
1718 i2c_del_adapter(&ttusb->i2c_adap);
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001719 dvb_unregister_adapter (&ttusb->adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001720 return -ENODEV;
1721 }
1722//FIXME dmxdev (nur WAS?)
1723 ttusb->dmxdev.filternum = ttusb->dvb_demux.filternum;
1724 ttusb->dmxdev.demux = &ttusb->dvb_demux.dmx;
1725 ttusb->dmxdev.capabilities = 0;
1726
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001727 if ((result = dvb_dmxdev_init(&ttusb->dmxdev, &ttusb->adapter)) < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001728 printk("ttusb_dvb: dvb_dmxdev_init failed (errno = %d)\n",
1729 result);
1730 dvb_dmx_release(&ttusb->dvb_demux);
1731 i2c_del_adapter(&ttusb->i2c_adap);
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001732 dvb_unregister_adapter (&ttusb->adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001733 return -ENODEV;
1734 }
1735
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001736 if (dvb_net_init(&ttusb->adapter, &ttusb->dvbnet, &ttusb->dvb_demux.dmx)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001737 printk("ttusb_dvb: dvb_net_init failed!\n");
1738 dvb_dmxdev_release(&ttusb->dmxdev);
1739 dvb_dmx_release(&ttusb->dvb_demux);
1740 i2c_del_adapter(&ttusb->i2c_adap);
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001741 dvb_unregister_adapter (&ttusb->adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001742 return -ENODEV;
1743 }
1744
Linus Torvalds1da177e2005-04-16 15:20:36 -07001745 usb_set_intfdata(intf, (void *) ttusb);
1746
1747 frontend_init(ttusb);
1748
1749 return 0;
1750}
1751
1752static void ttusb_disconnect(struct usb_interface *intf)
1753{
1754 struct ttusb *ttusb = usb_get_intfdata(intf);
1755
1756 usb_set_intfdata(intf, NULL);
1757
1758 ttusb->disconnecting = 1;
1759
1760 ttusb_stop_iso_xfer(ttusb);
1761
1762 ttusb->dvb_demux.dmx.close(&ttusb->dvb_demux.dmx);
1763 dvb_net_release(&ttusb->dvbnet);
1764 dvb_dmxdev_release(&ttusb->dmxdev);
1765 dvb_dmx_release(&ttusb->dvb_demux);
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001766 if (ttusb->fe != NULL) {
1767 dvb_unregister_frontend(ttusb->fe);
Andrew de Quinceyf52a8382006-08-08 09:10:09 -03001768 dvb_frontend_detach(ttusb->fe);
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001769 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001770 i2c_del_adapter(&ttusb->i2c_adap);
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001771 dvb_unregister_adapter(&ttusb->adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001772
1773 ttusb_free_iso_urbs(ttusb);
1774
1775 kfree(ttusb);
1776
1777 dprintk("%s: TTUSB DVB disconnected\n", __FUNCTION__);
1778}
1779
1780static struct usb_device_id ttusb_table[] = {
1781 {USB_DEVICE(0xb48, 0x1003)},
Gavin Hamill53936392005-07-07 17:58:04 -07001782 {USB_DEVICE(0xb48, 0x1004)},
Linus Torvalds1da177e2005-04-16 15:20:36 -07001783 {USB_DEVICE(0xb48, 0x1005)},
1784 {}
1785};
1786
1787MODULE_DEVICE_TABLE(usb, ttusb_table);
1788
1789static struct usb_driver ttusb_driver = {
Julian Scheel27b05fd2005-07-12 13:58:39 -07001790 .name = "ttusb",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001791 .probe = ttusb_probe,
1792 .disconnect = ttusb_disconnect,
1793 .id_table = ttusb_table,
1794};
1795
1796static int __init ttusb_init(void)
1797{
1798 int err;
1799
1800 if ((err = usb_register(&ttusb_driver)) < 0) {
1801 printk("%s: usb_register failed! Error number %d",
1802 __FILE__, err);
1803 return err;
1804 }
1805
1806 return 0;
1807}
1808
1809static void __exit ttusb_exit(void)
1810{
1811 usb_deregister(&ttusb_driver);
1812}
1813
1814module_init(ttusb_init);
1815module_exit(ttusb_exit);
1816
1817MODULE_AUTHOR("Holger Waechtler <holger@convergence.de>");
1818MODULE_DESCRIPTION("TTUSB DVB Driver");
1819MODULE_LICENSE("GPL");