blob: 66ab0c6e9783da4f8a99cca3699c3a32dd51ec58 [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>
Akinobu Mitaa8a89b72008-07-04 06:33:20 -030015#include <linux/fs.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070016#include <linux/module.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070017#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>
David Woodhouse0a2a7362008-05-29 19:50:06 +030023#include <linux/firmware.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070024
25#include "dvb_frontend.h"
26#include "dmxdev.h"
27#include "dvb_demux.h"
28#include "dvb_net.h"
Gavin Hamill53936392005-07-07 17:58:04 -070029#include "ves1820.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070030#include "cx22700.h"
31#include "tda1004x.h"
32#include "stv0299.h"
33#include "tda8083.h"
Thomas Kaiserb8d4c232006-04-27 21:45:20 -030034#include "stv0297.h"
Andrew de Quinceyd0205422006-04-27 21:45:01 -030035#include "lnbp21.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070036
37#include <linux/dvb/frontend.h>
38#include <linux/dvb/dmx.h>
39#include <linux/pci.h>
40
Linus Torvalds1da177e2005-04-16 15:20:36 -070041/*
42 TTUSB_HWSECTIONS:
43 the DSP supports filtering in hardware, however, since the "muxstream"
44 is a bit braindead (no matching channel masks or no matching filter mask),
45 we won't support this - yet. it doesn't event support negative filters,
46 so the best way is maybe to keep TTUSB_HWSECTIONS undef'd and just
Adrian Bunk9aaeded2006-06-30 18:19:55 +020047 parse TS data. USB bandwidth will be a problem when having large
Linus Torvalds1da177e2005-04-16 15:20:36 -070048 datastreams, especially for dvb-net, but hey, that's not my problem.
49
50 TTUSB_DISEQC, TTUSB_TONE:
51 let the STC do the diseqc/tone stuff. this isn't supported at least with
52 my TTUSB, so let it undef'd unless you want to implement another
53 frontend. never tested.
54
55 DEBUG:
56 define it to > 3 for really hardcore debugging. you probably don't want
57 this unless the device doesn't load at all. > 2 for bandwidth statistics.
58*/
59
60static int debug;
Linus Torvalds1da177e2005-04-16 15:20:36 -070061module_param(debug, int, 0644);
62MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
63
Janne Grunau78e92002008-04-09 19:13:13 -030064DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
65
Linus Torvalds1da177e2005-04-16 15:20:36 -070066#define dprintk(x...) do { if (debug) printk(KERN_DEBUG x); } while (0)
67
68#define ISO_BUF_COUNT 4
69#define FRAMES_PER_ISO_BUF 4
70#define ISO_FRAME_SIZE 912
71#define TTUSB_MAXCHANNEL 32
72#ifdef TTUSB_HWSECTIONS
73#define TTUSB_MAXFILTER 16 /* ??? */
74#endif
75
76#define TTUSB_REV_2_2 0x22
77#define TTUSB_BUDGET_NAME "ttusb_stc_fw"
78
79/**
80 * since we're casting (struct ttusb*) <-> (struct dvb_demux*) around
81 * the dvb_demux field must be the first in struct!!
82 */
83struct ttusb {
84 struct dvb_demux dvb_demux;
85 struct dmxdev dmxdev;
86 struct dvb_net dvbnet;
87
88 /* and one for USB access. */
Ingo Molnar3593cab2006-02-07 06:49:14 -020089 struct mutex semi2c;
90 struct mutex semusb;
Linus Torvalds1da177e2005-04-16 15:20:36 -070091
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -070092 struct dvb_adapter adapter;
Linus Torvalds1da177e2005-04-16 15:20:36 -070093 struct usb_device *dev;
94
95 struct i2c_adapter i2c_adap;
96
97 int disconnecting;
98 int iso_streaming;
99
100 unsigned int bulk_out_pipe;
101 unsigned int bulk_in_pipe;
102 unsigned int isoc_in_pipe;
103
104 void *iso_buffer;
105 dma_addr_t iso_dma_handle;
106
107 struct urb *iso_urb[ISO_BUF_COUNT];
108
109 int running_feed_count;
110 int last_channel;
111 int last_filter;
112
113 u8 c; /* transaction counter, wraps around... */
114 fe_sec_tone_mode_t tone;
115 fe_sec_voltage_t voltage;
116
117 int mux_state; // 0..2 - MuxSyncWord, 3 - nMuxPacks, 4 - muxpack
118 u8 mux_npacks;
119 u8 muxpack[256 + 8];
120 int muxpack_ptr, muxpack_len;
121
122 int insync;
123
124 int cc; /* MuxCounter - will increment on EVERY MUX PACKET */
125 /* (including stuffing. yes. really.) */
126
127 u8 last_result[32];
128
129 int revision;
130
Linus Torvalds1da177e2005-04-16 15:20:36 -0700131 struct dvb_frontend* fe;
132};
133
Robert P. J. Day3a4fa0a2007-10-19 23:10:43 +0200134/* ugly workaround ... don't know why it's necessary to read */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700135/* all result codes. */
136
137#define DEBUG 0
138static int ttusb_cmd(struct ttusb *ttusb,
139 const u8 * data, int len, int needresult)
140{
141 int actual_len;
142 int err;
143#if DEBUG >= 3
144 int i;
145
146 printk(">");
147 for (i = 0; i < len; ++i)
148 printk(" %02x", data[i]);
149 printk("\n");
150#endif
151
Ingo Molnar3593cab2006-02-07 06:49:14 -0200152 if (mutex_lock_interruptible(&ttusb->semusb) < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700153 return -EAGAIN;
154
155 err = usb_bulk_msg(ttusb->dev, ttusb->bulk_out_pipe,
156 (u8 *) data, len, &actual_len, 1000);
157 if (err != 0) {
158 dprintk("%s: usb_bulk_msg(send) failed, err == %i!\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300159 __func__, err);
Ingo Molnar3593cab2006-02-07 06:49:14 -0200160 mutex_unlock(&ttusb->semusb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700161 return err;
162 }
163 if (actual_len != len) {
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300164 dprintk("%s: only wrote %d of %d bytes\n", __func__,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700165 actual_len, len);
Ingo Molnar3593cab2006-02-07 06:49:14 -0200166 mutex_unlock(&ttusb->semusb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700167 return -1;
168 }
169
170 err = usb_bulk_msg(ttusb->dev, ttusb->bulk_in_pipe,
171 ttusb->last_result, 32, &actual_len, 1000);
172
173 if (err != 0) {
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300174 printk("%s: failed, receive error %d\n", __func__,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700175 err);
Ingo Molnar3593cab2006-02-07 06:49:14 -0200176 mutex_unlock(&ttusb->semusb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700177 return err;
178 }
179#if DEBUG >= 3
180 actual_len = ttusb->last_result[3] + 4;
181 printk("<");
182 for (i = 0; i < actual_len; ++i)
183 printk(" %02x", ttusb->last_result[i]);
184 printk("\n");
185#endif
186 if (!needresult)
Ingo Molnar3593cab2006-02-07 06:49:14 -0200187 mutex_unlock(&ttusb->semusb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700188 return 0;
189}
190
191static int ttusb_result(struct ttusb *ttusb, u8 * data, int len)
192{
193 memcpy(data, ttusb->last_result, len);
Ingo Molnar3593cab2006-02-07 06:49:14 -0200194 mutex_unlock(&ttusb->semusb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700195 return 0;
196}
197
198static int ttusb_i2c_msg(struct ttusb *ttusb,
199 u8 addr, u8 * snd_buf, u8 snd_len, u8 * rcv_buf,
200 u8 rcv_len)
201{
202 u8 b[0x28];
203 u8 id = ++ttusb->c;
204 int i, err;
205
206 if (snd_len > 0x28 - 7 || rcv_len > 0x20 - 7)
207 return -EINVAL;
208
209 b[0] = 0xaa;
210 b[1] = id;
211 b[2] = 0x31;
212 b[3] = snd_len + 3;
213 b[4] = addr << 1;
214 b[5] = snd_len;
215 b[6] = rcv_len;
216
217 for (i = 0; i < snd_len; i++)
218 b[7 + i] = snd_buf[i];
219
220 err = ttusb_cmd(ttusb, b, snd_len + 7, 1);
221
222 if (err)
223 return -EREMOTEIO;
224
225 err = ttusb_result(ttusb, b, 0x20);
226
Mauro Carvalho Chehab9101e622005-12-12 00:37:24 -0800227 /* check if the i2c transaction was successful */
228 if ((snd_len != b[5]) || (rcv_len != b[6])) return -EREMOTEIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700229
230 if (rcv_len > 0) {
231
232 if (err || b[0] != 0x55 || b[1] != id) {
233 dprintk
234 ("%s: usb_bulk_msg(recv) failed, err == %i, id == %02x, b == ",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300235 __func__, err, id);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700236 return -EREMOTEIO;
237 }
238
239 for (i = 0; i < rcv_len; i++)
240 rcv_buf[i] = b[7 + i];
241 }
242
243 return rcv_len;
244}
245
246static int master_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, int num)
247{
248 struct ttusb *ttusb = i2c_get_adapdata(adapter);
249 int i = 0;
250 int inc;
251
Ingo Molnar3593cab2006-02-07 06:49:14 -0200252 if (mutex_lock_interruptible(&ttusb->semi2c) < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700253 return -EAGAIN;
254
255 while (i < num) {
256 u8 addr, snd_len, rcv_len, *snd_buf, *rcv_buf;
257 int err;
258
259 if (num > i + 1 && (msg[i + 1].flags & I2C_M_RD)) {
260 addr = msg[i].addr;
261 snd_buf = msg[i].buf;
262 snd_len = msg[i].len;
263 rcv_buf = msg[i + 1].buf;
264 rcv_len = msg[i + 1].len;
265 inc = 2;
266 } else {
267 addr = msg[i].addr;
268 snd_buf = msg[i].buf;
269 snd_len = msg[i].len;
270 rcv_buf = NULL;
271 rcv_len = 0;
272 inc = 1;
273 }
274
275 err = ttusb_i2c_msg(ttusb, addr,
276 snd_buf, snd_len, rcv_buf, rcv_len);
277
278 if (err < rcv_len) {
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300279 dprintk("%s: i == %i\n", __func__, i);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700280 break;
281 }
282
283 i += inc;
284 }
285
Ingo Molnar3593cab2006-02-07 06:49:14 -0200286 mutex_unlock(&ttusb->semi2c);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700287 return i;
288}
289
Linus Torvalds1da177e2005-04-16 15:20:36 -0700290static int ttusb_boot_dsp(struct ttusb *ttusb)
291{
David Woodhouse0a2a7362008-05-29 19:50:06 +0300292 const struct firmware *fw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700293 int i, err;
294 u8 b[40];
295
David Woodhouse0a2a7362008-05-29 19:50:06 +0300296 err = request_firmware(&fw, "ttusb-budget/dspbootcode.bin",
297 &ttusb->dev->dev);
298 if (err) {
299 printk(KERN_ERR "ttusb-budget: failed to request firmware\n");
300 return err;
301 }
302
Linus Torvalds1da177e2005-04-16 15:20:36 -0700303 /* BootBlock */
304 b[0] = 0xaa;
305 b[2] = 0x13;
306 b[3] = 28;
307
308 /* upload dsp code in 32 byte steps (36 didn't work for me ...) */
309 /* 32 is max packet size, no messages should be splitted. */
David Woodhouse0a2a7362008-05-29 19:50:06 +0300310 for (i = 0; i < fw->size; i += 28) {
311 memcpy(&b[4], &fw->data[i], 28);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700312
313 b[1] = ++ttusb->c;
314
315 err = ttusb_cmd(ttusb, b, 32, 0);
316 if (err)
317 goto done;
318 }
319
320 /* last block ... */
321 b[1] = ++ttusb->c;
322 b[2] = 0x13;
323 b[3] = 0;
324
325 err = ttusb_cmd(ttusb, b, 4, 0);
326 if (err)
327 goto done;
328
329 /* BootEnd */
330 b[1] = ++ttusb->c;
331 b[2] = 0x14;
332 b[3] = 0;
333
334 err = ttusb_cmd(ttusb, b, 4, 0);
335
336 done:
337 if (err) {
338 dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300339 __func__, err);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700340 }
341
342 return err;
343}
344
345static int ttusb_set_channel(struct ttusb *ttusb, int chan_id, int filter_type,
346 int pid)
347{
348 int err;
349 /* SetChannel */
350 u8 b[] = { 0xaa, ++ttusb->c, 0x22, 4, chan_id, filter_type,
351 (pid >> 8) & 0xff, pid & 0xff
352 };
353
354 err = ttusb_cmd(ttusb, b, sizeof(b), 0);
355 return err;
356}
357
358static int ttusb_del_channel(struct ttusb *ttusb, int channel_id)
359{
360 int err;
361 /* DelChannel */
362 u8 b[] = { 0xaa, ++ttusb->c, 0x23, 1, channel_id };
363
364 err = ttusb_cmd(ttusb, b, sizeof(b), 0);
365 return err;
366}
367
368#ifdef TTUSB_HWSECTIONS
369static int ttusb_set_filter(struct ttusb *ttusb, int filter_id,
370 int associated_chan, u8 filter[8], u8 mask[8])
371{
372 int err;
373 /* SetFilter */
374 u8 b[] = { 0xaa, 0, 0x24, 0x1a, filter_id, associated_chan,
375 filter[0], filter[1], filter[2], filter[3],
376 filter[4], filter[5], filter[6], filter[7],
377 filter[8], filter[9], filter[10], filter[11],
378 mask[0], mask[1], mask[2], mask[3],
379 mask[4], mask[5], mask[6], mask[7],
380 mask[8], mask[9], mask[10], mask[11]
381 };
382
383 err = ttusb_cmd(ttusb, b, sizeof(b), 0);
384 return err;
385}
386
387static int ttusb_del_filter(struct ttusb *ttusb, int filter_id)
388{
389 int err;
390 /* DelFilter */
391 u8 b[] = { 0xaa, ++ttusb->c, 0x25, 1, filter_id };
392
393 err = ttusb_cmd(ttusb, b, sizeof(b), 0);
394 return err;
395}
396#endif
397
398static int ttusb_init_controller(struct ttusb *ttusb)
399{
400 u8 b0[] = { 0xaa, ++ttusb->c, 0x15, 1, 0 };
401 u8 b1[] = { 0xaa, ++ttusb->c, 0x15, 1, 1 };
402 u8 b2[] = { 0xaa, ++ttusb->c, 0x32, 1, 0 };
403 /* i2c write read: 5 bytes, addr 0x10, 0x02 bytes write, 1 bytes read. */
404 u8 b3[] =
405 { 0xaa, ++ttusb->c, 0x31, 5, 0x10, 0x02, 0x01, 0x00, 0x1e };
406 u8 b4[] =
407 { 0x55, ttusb->c, 0x31, 4, 0x10, 0x02, 0x01, 0x00, 0x1e };
408
409 u8 get_version[] = { 0xaa, ++ttusb->c, 0x17, 5, 0, 0, 0, 0, 0 };
410 u8 get_dsp_version[0x20] =
411 { 0xaa, ++ttusb->c, 0x26, 28, 0, 0, 0, 0, 0 };
412 int err;
413
414 /* reset board */
415 if ((err = ttusb_cmd(ttusb, b0, sizeof(b0), 0)))
416 return err;
417
418 /* reset board (again?) */
419 if ((err = ttusb_cmd(ttusb, b1, sizeof(b1), 0)))
420 return err;
421
422 ttusb_boot_dsp(ttusb);
423
424 /* set i2c bit rate */
425 if ((err = ttusb_cmd(ttusb, b2, sizeof(b2), 0)))
426 return err;
427
428 if ((err = ttusb_cmd(ttusb, b3, sizeof(b3), 1)))
429 return err;
430
431 err = ttusb_result(ttusb, b4, sizeof(b4));
432
433 if ((err = ttusb_cmd(ttusb, get_version, sizeof(get_version), 1)))
434 return err;
435
436 if ((err = ttusb_result(ttusb, get_version, sizeof(get_version))))
437 return err;
438
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300439 dprintk("%s: stc-version: %c%c%c%c%c\n", __func__,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700440 get_version[4], get_version[5], get_version[6],
441 get_version[7], get_version[8]);
442
443 if (memcmp(get_version + 4, "V 0.0", 5) &&
444 memcmp(get_version + 4, "V 1.1", 5) &&
445 memcmp(get_version + 4, "V 2.1", 5) &&
446 memcmp(get_version + 4, "V 2.2", 5)) {
447 printk
448 ("%s: unknown STC version %c%c%c%c%c, please report!\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300449 __func__, get_version[4], get_version[5],
Linus Torvalds1da177e2005-04-16 15:20:36 -0700450 get_version[6], get_version[7], get_version[8]);
451 }
452
453 ttusb->revision = ((get_version[6] - '0') << 4) |
454 (get_version[8] - '0');
455
456 err =
457 ttusb_cmd(ttusb, get_dsp_version, sizeof(get_dsp_version), 1);
458 if (err)
459 return err;
460
461 err =
462 ttusb_result(ttusb, get_dsp_version, sizeof(get_dsp_version));
463 if (err)
464 return err;
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300465 printk("%s: dsp-version: %c%c%c\n", __func__,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700466 get_dsp_version[4], get_dsp_version[5], get_dsp_version[6]);
467 return 0;
468}
469
470#ifdef TTUSB_DISEQC
471static int ttusb_send_diseqc(struct dvb_frontend* fe,
472 const struct dvb_diseqc_master_cmd *cmd)
473{
474 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
475 u8 b[12] = { 0xaa, ++ttusb->c, 0x18 };
476
477 int err;
478
479 b[3] = 4 + 2 + cmd->msg_len;
480 b[4] = 0xFF; /* send diseqc master, not burst */
481 b[5] = cmd->msg_len;
482
483 memcpy(b + 5, cmd->msg, cmd->msg_len);
484
485 /* Diseqc */
486 if ((err = ttusb_cmd(ttusb, b, 4 + b[3], 0))) {
487 dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300488 __func__, err);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700489 }
490
491 return err;
492}
493#endif
494
Linus Torvalds1da177e2005-04-16 15:20:36 -0700495static int ttusb_update_lnb(struct ttusb *ttusb)
496{
497 u8 b[] = { 0xaa, ++ttusb->c, 0x16, 5, /*power: */ 1,
498 ttusb->voltage == SEC_VOLTAGE_18 ? 0 : 1,
499 ttusb->tone == SEC_TONE_ON ? 1 : 0, 1, 1
500 };
501 int err;
502
503 /* SetLNB */
504 if ((err = ttusb_cmd(ttusb, b, sizeof(b), 0))) {
505 dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300506 __func__, err);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700507 }
508
509 return err;
510}
511
512static int ttusb_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
513{
514 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
515
516 ttusb->voltage = voltage;
517 return ttusb_update_lnb(ttusb);
518}
519
520#ifdef TTUSB_TONE
521static int ttusb_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
522{
523 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
524
525 ttusb->tone = tone;
526 return ttusb_update_lnb(ttusb);
527}
528#endif
529
530
531#if 0
532static void ttusb_set_led_freq(struct ttusb *ttusb, u8 freq)
533{
534 u8 b[] = { 0xaa, ++ttusb->c, 0x19, 1, freq };
535 int err, actual_len;
536
537 err = ttusb_cmd(ttusb, b, sizeof(b), 0);
538 if (err) {
539 dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300540 __func__, err);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700541 }
542}
543#endif
544
545/*****************************************************************************/
546
547#ifdef TTUSB_HWSECTIONS
548static void ttusb_handle_ts_data(struct ttusb_channel *channel,
549 const u8 * data, int len);
550static void ttusb_handle_sec_data(struct ttusb_channel *channel,
551 const u8 * data, int len);
552#endif
553
Douglas Schilling Landgrafff699e62008-04-22 14:41:48 -0300554static int numpkt, numts, numstuff, numsec, numinvalid;
Marcelo Feitoza Parisi4da006c2005-09-09 13:03:15 -0700555static unsigned long lastj;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700556
557static void ttusb_process_muxpack(struct ttusb *ttusb, const u8 * muxpack,
558 int len)
559{
560 u16 csum = 0, cc;
561 int i;
562 for (i = 0; i < len; i += 2)
Al Virod4f979a2008-05-21 00:31:31 -0300563 csum ^= le16_to_cpup((__le16 *) (muxpack + i));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700564 if (csum) {
565 printk("%s: muxpack with incorrect checksum, ignoring\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300566 __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567 numinvalid++;
568 return;
569 }
570
571 cc = (muxpack[len - 4] << 8) | muxpack[len - 3];
572 cc &= 0x7FFF;
573 if ((cc != ttusb->cc) && (ttusb->cc != -1))
574 printk("%s: cc discontinuity (%d frames missing)\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300575 __func__, (cc - ttusb->cc) & 0x7FFF);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700576 ttusb->cc = (cc + 1) & 0x7FFF;
577 if (muxpack[0] & 0x80) {
578#ifdef TTUSB_HWSECTIONS
579 /* section data */
580 int pusi = muxpack[0] & 0x40;
581 int channel = muxpack[0] & 0x1F;
582 int payload = muxpack[1];
583 const u8 *data = muxpack + 2;
584 /* check offset flag */
585 if (muxpack[0] & 0x20)
586 data++;
587
588 ttusb_handle_sec_data(ttusb->channel + channel, data,
589 payload);
590 data += payload;
591
592 if ((!!(ttusb->muxpack[0] & 0x20)) ^
593 !!(ttusb->muxpack[1] & 1))
594 data++;
595#warning TODO: pusi
596 printk("cc: %04x\n", (data[0] << 8) | data[1]);
597#endif
598 numsec++;
599 } else if (muxpack[0] == 0x47) {
600#ifdef TTUSB_HWSECTIONS
601 /* we have TS data here! */
602 int pid = ((muxpack[1] & 0x0F) << 8) | muxpack[2];
603 int channel;
604 for (channel = 0; channel < TTUSB_MAXCHANNEL; ++channel)
605 if (ttusb->channel[channel].active
606 && (pid == ttusb->channel[channel].pid))
607 ttusb_handle_ts_data(ttusb->channel +
608 channel, muxpack,
609 188);
610#endif
611 numts++;
612 dvb_dmx_swfilter_packets(&ttusb->dvb_demux, muxpack, 1);
613 } else if (muxpack[0] != 0) {
614 numinvalid++;
615 printk("illegal muxpack type %02x\n", muxpack[0]);
616 } else
617 numstuff++;
618}
619
620static void ttusb_process_frame(struct ttusb *ttusb, u8 * data, int len)
621{
622 int maxwork = 1024;
623 while (len) {
624 if (!(maxwork--)) {
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300625 printk("%s: too much work\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700626 break;
627 }
628
629 switch (ttusb->mux_state) {
630 case 0:
631 case 1:
632 case 2:
633 len--;
634 if (*data++ == 0xAA)
635 ++ttusb->mux_state;
636 else {
637 ttusb->mux_state = 0;
638#if DEBUG > 3
639 if (ttusb->insync)
640 printk("%02x ", data[-1]);
641#else
642 if (ttusb->insync) {
643 printk("%s: lost sync.\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300644 __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700645 ttusb->insync = 0;
646 }
647#endif
648 }
649 break;
650 case 3:
651 ttusb->insync = 1;
652 len--;
653 ttusb->mux_npacks = *data++;
654 ++ttusb->mux_state;
655 ttusb->muxpack_ptr = 0;
656 /* maximum bytes, until we know the length */
657 ttusb->muxpack_len = 2;
658 break;
659 case 4:
660 {
661 int avail;
662 avail = len;
663 if (avail >
664 (ttusb->muxpack_len -
665 ttusb->muxpack_ptr))
666 avail =
667 ttusb->muxpack_len -
668 ttusb->muxpack_ptr;
669 memcpy(ttusb->muxpack + ttusb->muxpack_ptr,
670 data, avail);
671 ttusb->muxpack_ptr += avail;
Eric Sesterhennae246012006-03-13 13:17:11 -0300672 BUG_ON(ttusb->muxpack_ptr > 264);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700673 data += avail;
674 len -= avail;
675 /* determine length */
676 if (ttusb->muxpack_ptr == 2) {
677 if (ttusb->muxpack[0] & 0x80) {
678 ttusb->muxpack_len =
679 ttusb->muxpack[1] + 2;
680 if (ttusb->
681 muxpack[0] & 0x20)
682 ttusb->
683 muxpack_len++;
684 if ((!!
685 (ttusb->
686 muxpack[0] & 0x20)) ^
687 !!(ttusb->
688 muxpack[1] & 1))
689 ttusb->
690 muxpack_len++;
691 ttusb->muxpack_len += 4;
692 } else if (ttusb->muxpack[0] ==
693 0x47)
694 ttusb->muxpack_len =
695 188 + 4;
696 else if (ttusb->muxpack[0] == 0x00)
697 ttusb->muxpack_len =
698 ttusb->muxpack[1] + 2 +
699 4;
700 else {
701 dprintk
702 ("%s: invalid state: first byte is %x\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300703 __func__,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700704 ttusb->muxpack[0]);
705 ttusb->mux_state = 0;
706 }
707 }
708
709 /**
710 * if length is valid and we reached the end:
711 * goto next muxpack
712 */
713 if ((ttusb->muxpack_ptr >= 2) &&
714 (ttusb->muxpack_ptr ==
715 ttusb->muxpack_len)) {
716 ttusb_process_muxpack(ttusb,
717 ttusb->
718 muxpack,
719 ttusb->
720 muxpack_ptr);
721 ttusb->muxpack_ptr = 0;
722 /* maximum bytes, until we know the length */
723 ttusb->muxpack_len = 2;
724
725 /**
726 * no muxpacks left?
727 * return to search-sync state
728 */
729 if (!ttusb->mux_npacks--) {
730 ttusb->mux_state = 0;
731 break;
732 }
733 }
734 break;
735 }
736 default:
737 BUG();
738 break;
739 }
740 }
741}
742
David Howells7d12e782006-10-05 14:55:46 +0100743static void ttusb_iso_irq(struct urb *urb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700744{
745 struct ttusb *ttusb = urb->context;
746
747 if (!ttusb->iso_streaming)
748 return;
749
750#if 0
751 printk("%s: status %d, errcount == %d, length == %i\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300752 __func__,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700753 urb->status, urb->error_count, urb->actual_length);
754#endif
755
756 if (!urb->status) {
757 int i;
758 for (i = 0; i < urb->number_of_packets; ++i) {
759 struct usb_iso_packet_descriptor *d;
760 u8 *data;
761 int len;
762 numpkt++;
Marcelo Feitoza Parisi4da006c2005-09-09 13:03:15 -0700763 if (time_after_eq(jiffies, lastj + HZ)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700764#if DEBUG > 2
765 printk
766 ("frames/s: %d (ts: %d, stuff %d, sec: %d, invalid: %d, all: %d)\n",
767 numpkt * HZ / (jiffies - lastj),
768 numts, numstuff, numsec, numinvalid,
769 numts + numstuff + numsec +
770 numinvalid);
771#endif
772 numts = numstuff = numsec = numinvalid = 0;
773 lastj = jiffies;
774 numpkt = 0;
775 }
776 d = &urb->iso_frame_desc[i];
777 data = urb->transfer_buffer + d->offset;
778 len = d->actual_length;
779 d->actual_length = 0;
780 d->status = 0;
781 ttusb_process_frame(ttusb, data, len);
782 }
783 }
784 usb_submit_urb(urb, GFP_ATOMIC);
785}
786
787static void ttusb_free_iso_urbs(struct ttusb *ttusb)
788{
789 int i;
790
791 for (i = 0; i < ISO_BUF_COUNT; i++)
792 if (ttusb->iso_urb[i])
793 usb_free_urb(ttusb->iso_urb[i]);
794
795 pci_free_consistent(NULL,
796 ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF *
797 ISO_BUF_COUNT, ttusb->iso_buffer,
798 ttusb->iso_dma_handle);
799}
800
801static int ttusb_alloc_iso_urbs(struct ttusb *ttusb)
802{
803 int i;
804
805 ttusb->iso_buffer = pci_alloc_consistent(NULL,
806 ISO_FRAME_SIZE *
807 FRAMES_PER_ISO_BUF *
808 ISO_BUF_COUNT,
809 &ttusb->iso_dma_handle);
810
811 memset(ttusb->iso_buffer, 0,
812 ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF * ISO_BUF_COUNT);
813
814 for (i = 0; i < ISO_BUF_COUNT; i++) {
815 struct urb *urb;
816
817 if (!
818 (urb =
819 usb_alloc_urb(FRAMES_PER_ISO_BUF, GFP_ATOMIC))) {
820 ttusb_free_iso_urbs(ttusb);
821 return -ENOMEM;
822 }
823
824 ttusb->iso_urb[i] = urb;
825 }
826
827 return 0;
828}
829
830static void ttusb_stop_iso_xfer(struct ttusb *ttusb)
831{
832 int i;
833
834 for (i = 0; i < ISO_BUF_COUNT; i++)
835 usb_kill_urb(ttusb->iso_urb[i]);
836
837 ttusb->iso_streaming = 0;
838}
839
840static int ttusb_start_iso_xfer(struct ttusb *ttusb)
841{
842 int i, j, err, buffer_offset = 0;
843
844 if (ttusb->iso_streaming) {
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300845 printk("%s: iso xfer already running!\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700846 return 0;
847 }
848
849 ttusb->cc = -1;
850 ttusb->insync = 0;
851 ttusb->mux_state = 0;
852
853 for (i = 0; i < ISO_BUF_COUNT; i++) {
854 int frame_offset = 0;
855 struct urb *urb = ttusb->iso_urb[i];
856
857 urb->dev = ttusb->dev;
858 urb->context = ttusb;
859 urb->complete = ttusb_iso_irq;
860 urb->pipe = ttusb->isoc_in_pipe;
861 urb->transfer_flags = URB_ISO_ASAP;
862 urb->interval = 1;
863 urb->number_of_packets = FRAMES_PER_ISO_BUF;
864 urb->transfer_buffer_length =
865 ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF;
866 urb->transfer_buffer = ttusb->iso_buffer + buffer_offset;
867 buffer_offset += ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF;
868
869 for (j = 0; j < FRAMES_PER_ISO_BUF; j++) {
870 urb->iso_frame_desc[j].offset = frame_offset;
871 urb->iso_frame_desc[j].length = ISO_FRAME_SIZE;
872 frame_offset += ISO_FRAME_SIZE;
873 }
874 }
875
876 for (i = 0; i < ISO_BUF_COUNT; i++) {
877 if ((err = usb_submit_urb(ttusb->iso_urb[i], GFP_ATOMIC))) {
878 ttusb_stop_iso_xfer(ttusb);
879 printk
880 ("%s: failed urb submission (%i: err = %i)!\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300881 __func__, i, err);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700882 return err;
883 }
884 }
885
886 ttusb->iso_streaming = 1;
887
888 return 0;
889}
890
891#ifdef TTUSB_HWSECTIONS
892static void ttusb_handle_ts_data(struct dvb_demux_feed *dvbdmxfeed, const u8 * data,
893 int len)
894{
895 dvbdmxfeed->cb.ts(data, len, 0, 0, &dvbdmxfeed->feed.ts, 0);
896}
897
898static void ttusb_handle_sec_data(struct dvb_demux_feed *dvbdmxfeed, const u8 * data,
899 int len)
900{
901// struct dvb_demux_feed *dvbdmxfeed = channel->dvbdmxfeed;
902#error TODO: handle ugly stuff
903// dvbdmxfeed->cb.sec(data, len, 0, 0, &dvbdmxfeed->feed.sec, 0);
904}
905#endif
906
907static int ttusb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
908{
909 struct ttusb *ttusb = (struct ttusb *) dvbdmxfeed->demux;
910 int feed_type = 1;
911
912 dprintk("ttusb_start_feed\n");
913
914 switch (dvbdmxfeed->type) {
915 case DMX_TYPE_TS:
916 break;
917 case DMX_TYPE_SEC:
918 break;
919 default:
920 return -EINVAL;
921 }
922
923 if (dvbdmxfeed->type == DMX_TYPE_TS) {
924 switch (dvbdmxfeed->pes_type) {
925 case DMX_TS_PES_VIDEO:
926 case DMX_TS_PES_AUDIO:
927 case DMX_TS_PES_TELETEXT:
928 case DMX_TS_PES_PCR:
929 case DMX_TS_PES_OTHER:
930 break;
931 default:
932 return -EINVAL;
933 }
934 }
935
936#ifdef TTUSB_HWSECTIONS
937#error TODO: allocate filters
938 if (dvbdmxfeed->type == DMX_TYPE_TS) {
939 feed_type = 1;
940 } else if (dvbdmxfeed->type == DMX_TYPE_SEC) {
941 feed_type = 2;
942 }
943#endif
944
945 ttusb_set_channel(ttusb, dvbdmxfeed->index, feed_type, dvbdmxfeed->pid);
946
947 if (0 == ttusb->running_feed_count++)
948 ttusb_start_iso_xfer(ttusb);
949
950 return 0;
951}
952
953static int ttusb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
954{
955 struct ttusb *ttusb = (struct ttusb *) dvbdmxfeed->demux;
956
957 ttusb_del_channel(ttusb, dvbdmxfeed->index);
958
959 if (--ttusb->running_feed_count == 0)
960 ttusb_stop_iso_xfer(ttusb);
961
962 return 0;
963}
964
965static int ttusb_setup_interfaces(struct ttusb *ttusb)
966{
967 usb_set_interface(ttusb->dev, 1, 1);
968
969 ttusb->bulk_out_pipe = usb_sndbulkpipe(ttusb->dev, 1);
970 ttusb->bulk_in_pipe = usb_rcvbulkpipe(ttusb->dev, 1);
971 ttusb->isoc_in_pipe = usb_rcvisocpipe(ttusb->dev, 2);
972
973 return 0;
974}
975
976#if 0
977static u8 stc_firmware[8192];
978
979static int stc_open(struct inode *inode, struct file *file)
980{
981 struct ttusb *ttusb = file->private_data;
982 int addr;
983
984 for (addr = 0; addr < 8192; addr += 16) {
985 u8 snd_buf[2] = { addr >> 8, addr & 0xFF };
986 ttusb_i2c_msg(ttusb, 0x50, snd_buf, 2, stc_firmware + addr,
987 16);
988 }
989
990 return 0;
991}
992
993static ssize_t stc_read(struct file *file, char *buf, size_t count,
Akinobu Mitaa8a89b72008-07-04 06:33:20 -0300994 loff_t *offset)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700995{
Akinobu Mitaa8a89b72008-07-04 06:33:20 -0300996 return simple_read_from_buffer(buf, count, offset, stc_firmware, 8192);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700997}
998
999static int stc_release(struct inode *inode, struct file *file)
1000{
1001 return 0;
1002}
1003
Jan Engelhardt27a643b2008-04-22 14:42:01 -03001004static const struct file_operations stc_fops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001005 .owner = THIS_MODULE,
1006 .read = stc_read,
1007 .open = stc_open,
1008 .release = stc_release,
1009};
1010#endif
1011
1012static u32 functionality(struct i2c_adapter *adapter)
1013{
1014 return I2C_FUNC_I2C;
1015}
1016
1017
1018
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001019static int alps_tdmb7_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001020{
1021 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1022 u8 data[4];
1023 struct i2c_msg msg = {.addr=0x61, .flags=0, .buf=data, .len=sizeof(data) };
1024 u32 div;
1025
1026 div = (params->frequency + 36166667) / 166667;
1027
1028 data[0] = (div >> 8) & 0x7f;
1029 data[1] = div & 0xff;
1030 data[2] = ((div >> 10) & 0x60) | 0x85;
1031 data[3] = params->frequency < 592000000 ? 0x40 : 0x80;
1032
Patrick Boettcherdea74862006-05-14 05:01:31 -03001033 if (fe->ops.i2c_gate_ctrl)
1034 fe->ops.i2c_gate_ctrl(fe, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001035 if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1) return -EIO;
1036 return 0;
1037}
1038
Johannes Stezenbachd91b7302005-05-16 21:54:38 -07001039static struct cx22700_config alps_tdmb7_config = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001040 .demod_address = 0x43,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001041};
1042
1043
1044
1045
1046
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001047static int philips_tdm1316l_tuner_init(struct dvb_frontend* fe)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001048{
1049 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1050 static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab };
1051 static u8 disable_mc44BC374c[] = { 0x1d, 0x74, 0xa0, 0x68 };
1052 struct i2c_msg tuner_msg = { .addr=0x60, .flags=0, .buf=td1316_init, .len=sizeof(td1316_init) };
1053
1054 // setup PLL configuration
Patrick Boettcherdea74862006-05-14 05:01:31 -03001055 if (fe->ops.i2c_gate_ctrl)
1056 fe->ops.i2c_gate_ctrl(fe, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001057 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) return -EIO;
1058 msleep(1);
1059
1060 // disable the mc44BC374c (do not check for errors)
1061 tuner_msg.addr = 0x65;
1062 tuner_msg.buf = disable_mc44BC374c;
1063 tuner_msg.len = sizeof(disable_mc44BC374c);
Patrick Boettcherdea74862006-05-14 05:01:31 -03001064 if (fe->ops.i2c_gate_ctrl)
1065 fe->ops.i2c_gate_ctrl(fe, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001066 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) {
1067 i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1);
1068 }
1069
1070 return 0;
1071}
1072
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001073static int philips_tdm1316l_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001074{
1075 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1076 u8 tuner_buf[4];
1077 struct i2c_msg tuner_msg = {.addr=0x60, .flags=0, .buf=tuner_buf, .len=sizeof(tuner_buf) };
1078 int tuner_frequency = 0;
1079 u8 band, cp, filter;
1080
1081 // determine charge pump
1082 tuner_frequency = params->frequency + 36130000;
1083 if (tuner_frequency < 87000000) return -EINVAL;
1084 else if (tuner_frequency < 130000000) cp = 3;
1085 else if (tuner_frequency < 160000000) cp = 5;
1086 else if (tuner_frequency < 200000000) cp = 6;
1087 else if (tuner_frequency < 290000000) cp = 3;
1088 else if (tuner_frequency < 420000000) cp = 5;
1089 else if (tuner_frequency < 480000000) cp = 6;
1090 else if (tuner_frequency < 620000000) cp = 3;
1091 else if (tuner_frequency < 830000000) cp = 5;
1092 else if (tuner_frequency < 895000000) cp = 7;
1093 else return -EINVAL;
1094
1095 // determine band
1096 if (params->frequency < 49000000) return -EINVAL;
1097 else if (params->frequency < 159000000) band = 1;
1098 else if (params->frequency < 444000000) band = 2;
1099 else if (params->frequency < 861000000) band = 4;
1100 else return -EINVAL;
1101
1102 // setup PLL filter
1103 switch (params->u.ofdm.bandwidth) {
1104 case BANDWIDTH_6_MHZ:
Andrew de Quinceyc10d14d2006-08-08 09:10:08 -03001105 tda1004x_writereg(fe, 0x0C, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001106 filter = 0;
1107 break;
1108
1109 case BANDWIDTH_7_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_8_MHZ:
Andrew de Quinceyc10d14d2006-08-08 09:10:08 -03001115 tda1004x_writereg(fe, 0x0C, 0xFF);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001116 filter = 1;
1117 break;
1118
1119 default:
1120 return -EINVAL;
1121 }
1122
1123 // calculate divisor
1124 // ((36130000+((1000000/6)/2)) + Finput)/(1000000/6)
1125 tuner_frequency = (((params->frequency / 1000) * 6) + 217280) / 1000;
1126
1127 // setup tuner buffer
1128 tuner_buf[0] = tuner_frequency >> 8;
1129 tuner_buf[1] = tuner_frequency & 0xff;
1130 tuner_buf[2] = 0xca;
1131 tuner_buf[3] = (cp << 5) | (filter << 3) | band;
1132
Patrick Boettcherdea74862006-05-14 05:01:31 -03001133 if (fe->ops.i2c_gate_ctrl)
1134 fe->ops.i2c_gate_ctrl(fe, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001135 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1)
1136 return -EIO;
1137
1138 msleep(1);
1139 return 0;
1140}
1141
1142static int philips_tdm1316l_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
1143{
1144 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1145
1146 return request_firmware(fw, name, &ttusb->dev->dev);
1147}
1148
1149static struct tda1004x_config philips_tdm1316l_config = {
1150
1151 .demod_address = 0x8,
1152 .invert = 1,
1153 .invert_oclk = 0,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001154 .request_firmware = philips_tdm1316l_request_firmware,
1155};
1156
1157static u8 alps_bsbe1_inittab[] = {
Mauro Carvalho Chehab9101e622005-12-12 00:37:24 -08001158 0x01, 0x15,
1159 0x02, 0x30,
1160 0x03, 0x00,
1161 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
1162 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
1163 0x06, 0x40, /* DAC not used, set to high impendance mode */
1164 0x07, 0x00, /* DAC LSB */
1165 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
1166 0x09, 0x00, /* FIFO */
1167 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
1168 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
1169 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
1170 0x10, 0x3f, // AGC2 0x3d
1171 0x11, 0x84,
1172 0x12, 0xb9,
1173 0x15, 0xc9, // lock detector threshold
1174 0x16, 0x00,
1175 0x17, 0x00,
1176 0x18, 0x00,
1177 0x19, 0x00,
1178 0x1a, 0x00,
1179 0x1f, 0x50,
1180 0x20, 0x00,
1181 0x21, 0x00,
1182 0x22, 0x00,
1183 0x23, 0x00,
1184 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
1185 0x29, 0x1e, // 1/2 threshold
1186 0x2a, 0x14, // 2/3 threshold
1187 0x2b, 0x0f, // 3/4 threshold
1188 0x2c, 0x09, // 5/6 threshold
1189 0x2d, 0x05, // 7/8 threshold
1190 0x2e, 0x01,
1191 0x31, 0x1f, // test all FECs
1192 0x32, 0x19, // viterbi and synchro search
1193 0x33, 0xfc, // rs control
1194 0x34, 0x93, // error control
1195 0x0f, 0x92,
1196 0xff, 0xff
Linus Torvalds1da177e2005-04-16 15:20:36 -07001197};
1198
1199static u8 alps_bsru6_inittab[] = {
1200 0x01, 0x15,
1201 0x02, 0x30,
1202 0x03, 0x00,
1203 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
1204 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
1205 0x06, 0x40, /* DAC not used, set to high impendance mode */
1206 0x07, 0x00, /* DAC LSB */
1207 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
1208 0x09, 0x00, /* FIFO */
1209 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
1210 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
1211 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
1212 0x10, 0x3f, // AGC2 0x3d
1213 0x11, 0x84,
Oliver Endriss7f44dcd2005-11-08 21:35:44 -08001214 0x12, 0xb9,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001215 0x15, 0xc9, // lock detector threshold
1216 0x16, 0x00,
1217 0x17, 0x00,
1218 0x18, 0x00,
1219 0x19, 0x00,
1220 0x1a, 0x00,
1221 0x1f, 0x50,
1222 0x20, 0x00,
1223 0x21, 0x00,
1224 0x22, 0x00,
1225 0x23, 0x00,
1226 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
1227 0x29, 0x1e, // 1/2 threshold
1228 0x2a, 0x14, // 2/3 threshold
1229 0x2b, 0x0f, // 3/4 threshold
1230 0x2c, 0x09, // 5/6 threshold
1231 0x2d, 0x05, // 7/8 threshold
1232 0x2e, 0x01,
1233 0x31, 0x1f, // test all FECs
1234 0x32, 0x19, // viterbi and synchro search
1235 0x33, 0xfc, // rs control
1236 0x34, 0x93, // error control
1237 0x0f, 0x52,
1238 0xff, 0xff
1239};
1240
1241static int alps_stv0299_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
1242{
1243 u8 aclk = 0;
1244 u8 bclk = 0;
1245
1246 if (srate < 1500000) {
1247 aclk = 0xb7;
1248 bclk = 0x47;
1249 } else if (srate < 3000000) {
1250 aclk = 0xb7;
1251 bclk = 0x4b;
1252 } else if (srate < 7000000) {
1253 aclk = 0xb7;
1254 bclk = 0x4f;
1255 } else if (srate < 14000000) {
1256 aclk = 0xb7;
1257 bclk = 0x53;
1258 } else if (srate < 30000000) {
1259 aclk = 0xb6;
1260 bclk = 0x53;
1261 } else if (srate < 45000000) {
1262 aclk = 0xb4;
1263 bclk = 0x51;
1264 }
1265
1266 stv0299_writereg(fe, 0x13, aclk);
1267 stv0299_writereg(fe, 0x14, bclk);
1268 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
1269 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
1270 stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
1271
1272 return 0;
1273}
1274
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001275static int philips_tsa5059_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001276{
1277 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1278 u8 buf[4];
1279 u32 div;
1280 struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
1281
1282 if ((params->frequency < 950000) || (params->frequency > 2150000))
1283 return -EINVAL;
1284
1285 div = (params->frequency + (125 - 1)) / 125; // round correctly
1286 buf[0] = (div >> 8) & 0x7f;
1287 buf[1] = div & 0xff;
1288 buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
1289 buf[3] = 0xC4;
1290
1291 if (params->frequency > 1530000)
1292 buf[3] = 0xC0;
1293
1294 /* BSBE1 wants XCE bit set */
1295 if (ttusb->revision == TTUSB_REV_2_2)
1296 buf[3] |= 0x20;
1297
Patrick Boettcherdea74862006-05-14 05:01:31 -03001298 if (fe->ops.i2c_gate_ctrl)
1299 fe->ops.i2c_gate_ctrl(fe, 1);
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001300 if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001301 return -EIO;
1302
1303 return 0;
1304}
1305
1306static struct stv0299_config alps_stv0299_config = {
1307 .demod_address = 0x68,
1308 .inittab = alps_bsru6_inittab,
1309 .mclk = 88000000UL,
1310 .invert = 1,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001311 .skip_reinit = 0,
Oliver Endrissda2c7f62008-04-20 22:13:37 -03001312 .lock_output = STV0299_LOCKOUTPUT_1,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001313 .volt13_op0_op1 = STV0299_VOLT13_OP1,
1314 .min_delay_ms = 100,
1315 .set_symbol_rate = alps_stv0299_set_symbol_rate,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001316};
1317
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001318static 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 -07001319{
1320 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1321 u8 buf[4];
1322 u32 div;
1323 struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
1324
Mauro Carvalho Chehab9101e622005-12-12 00:37:24 -08001325 div = params->frequency / 125;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001326
1327 buf[0] = (div >> 8) & 0x7f;
1328 buf[1] = div & 0xff;
1329 buf[2] = 0x8e;
1330 buf[3] = 0x00;
1331
Patrick Boettcherdea74862006-05-14 05:01:31 -03001332 if (fe->ops.i2c_gate_ctrl)
1333 fe->ops.i2c_gate_ctrl(fe, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001334 if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1)
1335 return -EIO;
1336
1337 return 0;
1338}
1339
1340static struct tda8083_config ttusb_novas_grundig_29504_491_config = {
1341
1342 .demod_address = 0x68,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001343};
1344
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001345static int alps_tdbe2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
Gavin Hamill53936392005-07-07 17:58:04 -07001346{
1347 struct ttusb* ttusb = fe->dvb->priv;
1348 u32 div;
1349 u8 data[4];
1350 struct i2c_msg msg = { .addr = 0x62, .flags = 0, .buf = data, .len = sizeof(data) };
1351
1352 div = (params->frequency + 35937500 + 31250) / 62500;
1353
1354 data[0] = (div >> 8) & 0x7f;
1355 data[1] = div & 0xff;
1356 data[2] = 0x85 | ((div >> 10) & 0x60);
1357 data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81);
1358
Patrick Boettcherdea74862006-05-14 05:01:31 -03001359 if (fe->ops.i2c_gate_ctrl)
1360 fe->ops.i2c_gate_ctrl(fe, 1);
Gavin Hamill53936392005-07-07 17:58:04 -07001361 if (i2c_transfer (&ttusb->i2c_adap, &msg, 1) != 1)
1362 return -EIO;
1363
1364 return 0;
1365}
1366
1367
1368static struct ves1820_config alps_tdbe2_config = {
1369 .demod_address = 0x09,
1370 .xin = 57840000UL,
1371 .invert = 1,
1372 .selagc = VES1820_SELAGC_SIGNAMPERR,
Gavin Hamill53936392005-07-07 17:58:04 -07001373};
1374
1375static u8 read_pwm(struct ttusb* ttusb)
1376{
1377 u8 b = 0xff;
1378 u8 pwm;
1379 struct i2c_msg msg[] = { { .addr = 0x50,.flags = 0,.buf = &b,.len = 1 },
1380 { .addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1} };
1381
1382 if ((i2c_transfer(&ttusb->i2c_adap, msg, 2) != 2) || (pwm == 0xff))
1383 pwm = 0x48;
1384
1385 return pwm;
1386}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001387
1388
Thomas Kaiserb8d4c232006-04-27 21:45:20 -03001389static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
1390{
1391 struct ttusb *ttusb = (struct ttusb *) fe->dvb->priv;
1392 u8 tuner_buf[5];
1393 struct i2c_msg tuner_msg = {.addr = 0x60,
1394 .flags = 0,
1395 .buf = tuner_buf,
1396 .len = sizeof(tuner_buf) };
1397 int tuner_frequency = 0;
1398 u8 band, cp, filter;
1399
1400 // determine charge pump
1401 tuner_frequency = params->frequency;
1402 if (tuner_frequency < 87000000) {return -EINVAL;}
1403 else if (tuner_frequency < 130000000) {cp = 3; band = 1;}
1404 else if (tuner_frequency < 160000000) {cp = 5; band = 1;}
1405 else if (tuner_frequency < 200000000) {cp = 6; band = 1;}
1406 else if (tuner_frequency < 290000000) {cp = 3; band = 2;}
1407 else if (tuner_frequency < 420000000) {cp = 5; band = 2;}
1408 else if (tuner_frequency < 480000000) {cp = 6; band = 2;}
1409 else if (tuner_frequency < 620000000) {cp = 3; band = 4;}
1410 else if (tuner_frequency < 830000000) {cp = 5; band = 4;}
1411 else if (tuner_frequency < 895000000) {cp = 7; band = 4;}
1412 else {return -EINVAL;}
1413
1414 // assume PLL filter should always be 8MHz for the moment.
1415 filter = 1;
1416
1417 // calculate divisor
1418 // (Finput + Fif)/Fref; Fif = 36125000 Hz, Fref = 62500 Hz
1419 tuner_frequency = ((params->frequency + 36125000) / 62500);
1420
1421 // setup tuner buffer
1422 tuner_buf[0] = tuner_frequency >> 8;
1423 tuner_buf[1] = tuner_frequency & 0xff;
1424 tuner_buf[2] = 0xc8;
1425 tuner_buf[3] = (cp << 5) | (filter << 3) | band;
1426 tuner_buf[4] = 0x80;
1427
Patrick Boettcherdea74862006-05-14 05:01:31 -03001428 if (fe->ops.i2c_gate_ctrl)
1429 fe->ops.i2c_gate_ctrl(fe, 1);
Thomas Kaiserb8d4c232006-04-27 21:45:20 -03001430 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) {
1431 printk("dvb-ttusb-budget: dvbc_philips_tdm1316l_pll_set Error 1\n");
1432 return -EIO;
1433 }
1434
1435 msleep(50);
1436
Patrick Boettcherdea74862006-05-14 05:01:31 -03001437 if (fe->ops.i2c_gate_ctrl)
1438 fe->ops.i2c_gate_ctrl(fe, 1);
Thomas Kaiserb8d4c232006-04-27 21:45:20 -03001439 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) {
1440 printk("dvb-ttusb-budget: dvbc_philips_tdm1316l_pll_set Error 2\n");
1441 return -EIO;
1442 }
1443
1444 msleep(1);
1445
1446 return 0;
1447}
1448
1449static u8 dvbc_philips_tdm1316l_inittab[] = {
1450 0x80, 0x21,
1451 0x80, 0x20,
1452 0x81, 0x01,
1453 0x81, 0x00,
1454 0x00, 0x09,
1455 0x01, 0x69,
1456 0x03, 0x00,
1457 0x04, 0x00,
1458 0x07, 0x00,
1459 0x08, 0x00,
1460 0x20, 0x00,
1461 0x21, 0x40,
1462 0x22, 0x00,
1463 0x23, 0x00,
1464 0x24, 0x40,
1465 0x25, 0x88,
1466 0x30, 0xff,
1467 0x31, 0x00,
1468 0x32, 0xff,
1469 0x33, 0x00,
1470 0x34, 0x50,
1471 0x35, 0x7f,
1472 0x36, 0x00,
1473 0x37, 0x20,
1474 0x38, 0x00,
1475 0x40, 0x1c,
1476 0x41, 0xff,
1477 0x42, 0x29,
1478 0x43, 0x20,
1479 0x44, 0xff,
1480 0x45, 0x00,
1481 0x46, 0x00,
1482 0x49, 0x04,
1483 0x4a, 0xff,
1484 0x4b, 0x7f,
1485 0x52, 0x30,
1486 0x55, 0xae,
1487 0x56, 0x47,
1488 0x57, 0xe1,
1489 0x58, 0x3a,
1490 0x5a, 0x1e,
1491 0x5b, 0x34,
1492 0x60, 0x00,
1493 0x63, 0x00,
1494 0x64, 0x00,
1495 0x65, 0x00,
1496 0x66, 0x00,
1497 0x67, 0x00,
1498 0x68, 0x00,
1499 0x69, 0x00,
1500 0x6a, 0x02,
1501 0x6b, 0x00,
1502 0x70, 0xff,
1503 0x71, 0x00,
1504 0x72, 0x00,
1505 0x73, 0x00,
1506 0x74, 0x0c,
1507 0x80, 0x00,
1508 0x81, 0x00,
1509 0x82, 0x00,
1510 0x83, 0x00,
1511 0x84, 0x04,
1512 0x85, 0x80,
1513 0x86, 0x24,
1514 0x87, 0x78,
1515 0x88, 0x00,
1516 0x89, 0x00,
1517 0x90, 0x01,
1518 0x91, 0x01,
1519 0xa0, 0x00,
1520 0xa1, 0x00,
1521 0xa2, 0x00,
1522 0xb0, 0x91,
1523 0xb1, 0x0b,
1524 0xc0, 0x4b,
1525 0xc1, 0x00,
1526 0xc2, 0x00,
1527 0xd0, 0x00,
1528 0xd1, 0x00,
1529 0xd2, 0x00,
1530 0xd3, 0x00,
1531 0xd4, 0x00,
1532 0xd5, 0x00,
1533 0xde, 0x00,
1534 0xdf, 0x00,
1535 0x61, 0x38,
1536 0x62, 0x0a,
1537 0x53, 0x13,
1538 0x59, 0x08,
1539 0x55, 0x00,
1540 0x56, 0x40,
1541 0x57, 0x08,
1542 0x58, 0x3d,
1543 0x88, 0x10,
1544 0xa0, 0x00,
1545 0xa0, 0x00,
1546 0xa0, 0x00,
1547 0xa0, 0x04,
1548 0xff, 0xff,
1549};
1550
1551static struct stv0297_config dvbc_philips_tdm1316l_config = {
1552 .demod_address = 0x1c,
1553 .inittab = dvbc_philips_tdm1316l_inittab,
1554 .invert = 0,
1555};
1556
Linus Torvalds1da177e2005-04-16 15:20:36 -07001557static void frontend_init(struct ttusb* ttusb)
1558{
1559 switch(le16_to_cpu(ttusb->dev->descriptor.idProduct)) {
1560 case 0x1003: // Hauppauge/TT Nova-USB-S budget (stv0299/ALPS BSRU6|BSBE1(tsa5059))
1561 // try the stv0299 based first
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001562 ttusb->fe = dvb_attach(stv0299_attach, &alps_stv0299_config, &ttusb->i2c_adap);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001563 if (ttusb->fe != NULL) {
Patrick Boettcherdea74862006-05-14 05:01:31 -03001564 ttusb->fe->ops.tuner_ops.set_params = philips_tsa5059_tuner_set_params;
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001565
Linus Torvalds1da177e2005-04-16 15:20:36 -07001566 if(ttusb->revision == TTUSB_REV_2_2) { // ALPS BSBE1
1567 alps_stv0299_config.inittab = alps_bsbe1_inittab;
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001568 dvb_attach(lnbp21_attach, ttusb->fe, &ttusb->i2c_adap, 0, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001569 } else { // ALPS BSRU6
Patrick Boettcherdea74862006-05-14 05:01:31 -03001570 ttusb->fe->ops.set_voltage = ttusb_set_voltage;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001571 }
1572 break;
1573 }
1574
1575 // Grundig 29504-491
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001576 ttusb->fe = dvb_attach(tda8083_attach, &ttusb_novas_grundig_29504_491_config, &ttusb->i2c_adap);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001577 if (ttusb->fe != NULL) {
Patrick Boettcherdea74862006-05-14 05:01:31 -03001578 ttusb->fe->ops.tuner_ops.set_params = ttusb_novas_grundig_29504_491_tuner_set_params;
1579 ttusb->fe->ops.set_voltage = ttusb_set_voltage;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001580 break;
1581 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001582 break;
1583
Gavin Hamill53936392005-07-07 17:58:04 -07001584 case 0x1004: // Hauppauge/TT DVB-C budget (ves1820/ALPS TDBE2(sp5659))
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001585 ttusb->fe = dvb_attach(ves1820_attach, &alps_tdbe2_config, &ttusb->i2c_adap, read_pwm(ttusb));
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001586 if (ttusb->fe != NULL) {
Patrick Boettcherdea74862006-05-14 05:01:31 -03001587 ttusb->fe->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params;
Gavin Hamill53936392005-07-07 17:58:04 -07001588 break;
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001589 }
Thomas Kaiserb8d4c232006-04-27 21:45:20 -03001590
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001591 ttusb->fe = dvb_attach(stv0297_attach, &dvbc_philips_tdm1316l_config, &ttusb->i2c_adap);
Thomas Kaiserb8d4c232006-04-27 21:45:20 -03001592 if (ttusb->fe != NULL) {
Patrick Boettcherdea74862006-05-14 05:01:31 -03001593 ttusb->fe->ops.tuner_ops.set_params = dvbc_philips_tdm1316l_tuner_set_params;
Thomas Kaiserb8d4c232006-04-27 21:45:20 -03001594 break;
1595 }
Gavin Hamill53936392005-07-07 17:58:04 -07001596 break;
1597
Linus Torvalds1da177e2005-04-16 15:20:36 -07001598 case 0x1005: // Hauppauge/TT Nova-USB-t budget (tda10046/Philips td1316(tda6651tt) OR cx22700/ALPS TDMB7(??))
1599 // try the ALPS TDMB7 first
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001600 ttusb->fe = dvb_attach(cx22700_attach, &alps_tdmb7_config, &ttusb->i2c_adap);
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001601 if (ttusb->fe != NULL) {
Patrick Boettcherdea74862006-05-14 05:01:31 -03001602 ttusb->fe->ops.tuner_ops.set_params = alps_tdmb7_tuner_set_params;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001603 break;
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001604 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001605
1606 // Philips td1316
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001607 ttusb->fe = dvb_attach(tda10046_attach, &philips_tdm1316l_config, &ttusb->i2c_adap);
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001608 if (ttusb->fe != NULL) {
Patrick Boettcherdea74862006-05-14 05:01:31 -03001609 ttusb->fe->ops.tuner_ops.init = philips_tdm1316l_tuner_init;
1610 ttusb->fe->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001611 break;
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001612 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001613 break;
1614 }
1615
1616 if (ttusb->fe == NULL) {
Bjorn Helgaas29e66a62008-09-04 17:24:51 -03001617 printk("dvb-ttusb-budget: A frontend driver was not found for device [%04x:%04x]\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001618 le16_to_cpu(ttusb->dev->descriptor.idVendor),
1619 le16_to_cpu(ttusb->dev->descriptor.idProduct));
1620 } else {
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001621 if (dvb_register_frontend(&ttusb->adapter, ttusb->fe)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001622 printk("dvb-ttusb-budget: Frontend registration failed!\n");
Andrew de Quinceyf52a8382006-08-08 09:10:09 -03001623 dvb_frontend_detach(ttusb->fe);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001624 ttusb->fe = NULL;
1625 }
1626 }
1627}
1628
1629
1630
1631static struct i2c_algorithm ttusb_dec_algo = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001632 .master_xfer = master_xfer,
1633 .functionality = functionality,
1634};
1635
1636static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *id)
1637{
1638 struct usb_device *udev;
1639 struct ttusb *ttusb;
1640 int result;
1641
Harvey Harrisonfb9393b2008-04-08 23:20:00 -03001642 dprintk("%s: TTUSB DVB connected\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001643
1644 udev = interface_to_usbdev(intf);
1645
Mauro Carvalho Chehab9101e622005-12-12 00:37:24 -08001646 if (intf->altsetting->desc.bInterfaceNumber != 1) return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001647
Panagiotis Issaris74081872006-01-11 19:40:56 -02001648 if (!(ttusb = kzalloc(sizeof(struct ttusb), GFP_KERNEL)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001649 return -ENOMEM;
1650
Linus Torvalds1da177e2005-04-16 15:20:36 -07001651 ttusb->dev = udev;
1652 ttusb->c = 0;
1653 ttusb->mux_state = 0;
Ingo Molnar3593cab2006-02-07 06:49:14 -02001654 mutex_init(&ttusb->semi2c);
1655
1656 mutex_lock(&ttusb->semi2c);
1657
1658 mutex_init(&ttusb->semusb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001659
1660 ttusb_setup_interfaces(ttusb);
1661
1662 ttusb_alloc_iso_urbs(ttusb);
1663 if (ttusb_init_controller(ttusb))
1664 printk("ttusb_init_controller: error\n");
1665
Ingo Molnar3593cab2006-02-07 06:49:14 -02001666 mutex_unlock(&ttusb->semi2c);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001667
Janne Grunau78e92002008-04-09 19:13:13 -03001668 result = dvb_register_adapter(&ttusb->adapter,
1669 "Technotrend/Hauppauge Nova-USB",
1670 THIS_MODULE, &udev->dev, adapter_nr);
1671 if (result < 0) {
Andrew de Quinceya064fad2006-04-06 17:05:46 -03001672 ttusb_free_iso_urbs(ttusb);
1673 kfree(ttusb);
1674 return result;
1675 }
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001676 ttusb->adapter.priv = ttusb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001677
1678 /* i2c */
1679 memset(&ttusb->i2c_adap, 0, sizeof(struct i2c_adapter));
1680 strcpy(ttusb->i2c_adap.name, "TTUSB DEC");
1681
1682 i2c_set_adapdata(&ttusb->i2c_adap, ttusb);
1683
Linus Torvalds1da177e2005-04-16 15:20:36 -07001684 ttusb->i2c_adap.class = I2C_CLASS_TV_DIGITAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001685 ttusb->i2c_adap.algo = &ttusb_dec_algo;
1686 ttusb->i2c_adap.algo_data = NULL;
Jean Delvare12a917f2007-02-13 22:09:03 +01001687 ttusb->i2c_adap.dev.parent = &udev->dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001688
1689 result = i2c_add_adapter(&ttusb->i2c_adap);
1690 if (result) {
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001691 dvb_unregister_adapter (&ttusb->adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001692 return result;
1693 }
1694
1695 memset(&ttusb->dvb_demux, 0, sizeof(ttusb->dvb_demux));
1696
1697 ttusb->dvb_demux.dmx.capabilities =
1698 DMX_TS_FILTERING | DMX_SECTION_FILTERING;
1699 ttusb->dvb_demux.priv = NULL;
1700#ifdef TTUSB_HWSECTIONS
1701 ttusb->dvb_demux.filternum = TTUSB_MAXFILTER;
1702#else
1703 ttusb->dvb_demux.filternum = 32;
1704#endif
1705 ttusb->dvb_demux.feednum = TTUSB_MAXCHANNEL;
1706 ttusb->dvb_demux.start_feed = ttusb_start_feed;
1707 ttusb->dvb_demux.stop_feed = ttusb_stop_feed;
1708 ttusb->dvb_demux.write_to_decoder = NULL;
1709
1710 if ((result = dvb_dmx_init(&ttusb->dvb_demux)) < 0) {
1711 printk("ttusb_dvb: dvb_dmx_init failed (errno = %d)\n", result);
1712 i2c_del_adapter(&ttusb->i2c_adap);
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001713 dvb_unregister_adapter (&ttusb->adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001714 return -ENODEV;
1715 }
1716//FIXME dmxdev (nur WAS?)
1717 ttusb->dmxdev.filternum = ttusb->dvb_demux.filternum;
1718 ttusb->dmxdev.demux = &ttusb->dvb_demux.dmx;
1719 ttusb->dmxdev.capabilities = 0;
1720
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001721 if ((result = dvb_dmxdev_init(&ttusb->dmxdev, &ttusb->adapter)) < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001722 printk("ttusb_dvb: dvb_dmxdev_init failed (errno = %d)\n",
1723 result);
1724 dvb_dmx_release(&ttusb->dvb_demux);
1725 i2c_del_adapter(&ttusb->i2c_adap);
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001726 dvb_unregister_adapter (&ttusb->adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001727 return -ENODEV;
1728 }
1729
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001730 if (dvb_net_init(&ttusb->adapter, &ttusb->dvbnet, &ttusb->dvb_demux.dmx)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001731 printk("ttusb_dvb: dvb_net_init failed!\n");
1732 dvb_dmxdev_release(&ttusb->dmxdev);
1733 dvb_dmx_release(&ttusb->dvb_demux);
1734 i2c_del_adapter(&ttusb->i2c_adap);
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001735 dvb_unregister_adapter (&ttusb->adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001736 return -ENODEV;
1737 }
1738
Linus Torvalds1da177e2005-04-16 15:20:36 -07001739 usb_set_intfdata(intf, (void *) ttusb);
1740
1741 frontend_init(ttusb);
1742
1743 return 0;
1744}
1745
1746static void ttusb_disconnect(struct usb_interface *intf)
1747{
1748 struct ttusb *ttusb = usb_get_intfdata(intf);
1749
1750 usb_set_intfdata(intf, NULL);
1751
1752 ttusb->disconnecting = 1;
1753
1754 ttusb_stop_iso_xfer(ttusb);
1755
1756 ttusb->dvb_demux.dmx.close(&ttusb->dvb_demux.dmx);
1757 dvb_net_release(&ttusb->dvbnet);
1758 dvb_dmxdev_release(&ttusb->dmxdev);
1759 dvb_dmx_release(&ttusb->dvb_demux);
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001760 if (ttusb->fe != NULL) {
1761 dvb_unregister_frontend(ttusb->fe);
Andrew de Quinceyf52a8382006-08-08 09:10:09 -03001762 dvb_frontend_detach(ttusb->fe);
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001763 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001764 i2c_del_adapter(&ttusb->i2c_adap);
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001765 dvb_unregister_adapter(&ttusb->adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001766
1767 ttusb_free_iso_urbs(ttusb);
1768
1769 kfree(ttusb);
1770
Harvey Harrisonfb9393b2008-04-08 23:20:00 -03001771 dprintk("%s: TTUSB DVB disconnected\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001772}
1773
1774static struct usb_device_id ttusb_table[] = {
1775 {USB_DEVICE(0xb48, 0x1003)},
Gavin Hamill53936392005-07-07 17:58:04 -07001776 {USB_DEVICE(0xb48, 0x1004)},
Linus Torvalds1da177e2005-04-16 15:20:36 -07001777 {USB_DEVICE(0xb48, 0x1005)},
1778 {}
1779};
1780
1781MODULE_DEVICE_TABLE(usb, ttusb_table);
1782
1783static struct usb_driver ttusb_driver = {
Julian Scheel27b05fd2005-07-12 13:58:39 -07001784 .name = "ttusb",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001785 .probe = ttusb_probe,
1786 .disconnect = ttusb_disconnect,
1787 .id_table = ttusb_table,
1788};
1789
1790static int __init ttusb_init(void)
1791{
1792 int err;
1793
1794 if ((err = usb_register(&ttusb_driver)) < 0) {
1795 printk("%s: usb_register failed! Error number %d",
1796 __FILE__, err);
1797 return err;
1798 }
1799
1800 return 0;
1801}
1802
1803static void __exit ttusb_exit(void)
1804{
1805 usb_deregister(&ttusb_driver);
1806}
1807
1808module_init(ttusb_init);
1809module_exit(ttusb_exit);
1810
1811MODULE_AUTHOR("Holger Waechtler <holger@convergence.de>");
1812MODULE_DESCRIPTION("TTUSB DVB Driver");
1813MODULE_LICENSE("GPL");
David Woodhouse0a2a7362008-05-29 19:50:06 +03001814MODULE_FIRMWARE("ttusb-budget/dspbootcode.bin");