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