blob: bc2043e44ebdef143d1615dbb9e0b4aab2976753 [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>
David Woodhouse0a2a7362008-05-29 19:50:06 +030022#include <linux/firmware.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070023
24#include "dvb_frontend.h"
25#include "dmxdev.h"
26#include "dvb_demux.h"
27#include "dvb_net.h"
Gavin Hamill53936392005-07-07 17:58:04 -070028#include "ves1820.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070029#include "cx22700.h"
30#include "tda1004x.h"
31#include "stv0299.h"
32#include "tda8083.h"
Thomas Kaiserb8d4c232006-04-27 21:45:20 -030033#include "stv0297.h"
Andrew de Quinceyd0205422006-04-27 21:45:01 -030034#include "lnbp21.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070035
36#include <linux/dvb/frontend.h>
37#include <linux/dvb/dmx.h>
38#include <linux/pci.h>
39
Linus Torvalds1da177e2005-04-16 15:20:36 -070040/*
41 TTUSB_HWSECTIONS:
42 the DSP supports filtering in hardware, however, since the "muxstream"
43 is a bit braindead (no matching channel masks or no matching filter mask),
44 we won't support this - yet. it doesn't event support negative filters,
45 so the best way is maybe to keep TTUSB_HWSECTIONS undef'd and just
Adrian Bunk9aaeded2006-06-30 18:19:55 +020046 parse TS data. USB bandwidth will be a problem when having large
Linus Torvalds1da177e2005-04-16 15:20:36 -070047 datastreams, especially for dvb-net, but hey, that's not my problem.
48
49 TTUSB_DISEQC, TTUSB_TONE:
50 let the STC do the diseqc/tone stuff. this isn't supported at least with
51 my TTUSB, so let it undef'd unless you want to implement another
52 frontend. never tested.
53
54 DEBUG:
55 define it to > 3 for really hardcore debugging. you probably don't want
56 this unless the device doesn't load at all. > 2 for bandwidth statistics.
57*/
58
59static int debug;
Linus Torvalds1da177e2005-04-16 15:20:36 -070060module_param(debug, int, 0644);
61MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
62
Janne Grunau78e920062008-04-09 19:13:13 -030063DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
64
Linus Torvalds1da177e2005-04-16 15:20:36 -070065#define dprintk(x...) do { if (debug) printk(KERN_DEBUG x); } while (0)
66
67#define ISO_BUF_COUNT 4
68#define FRAMES_PER_ISO_BUF 4
69#define ISO_FRAME_SIZE 912
70#define TTUSB_MAXCHANNEL 32
71#ifdef TTUSB_HWSECTIONS
72#define TTUSB_MAXFILTER 16 /* ??? */
73#endif
74
75#define TTUSB_REV_2_2 0x22
76#define TTUSB_BUDGET_NAME "ttusb_stc_fw"
77
78/**
79 * since we're casting (struct ttusb*) <-> (struct dvb_demux*) around
80 * the dvb_demux field must be the first in struct!!
81 */
82struct ttusb {
83 struct dvb_demux dvb_demux;
84 struct dmxdev dmxdev;
85 struct dvb_net dvbnet;
86
87 /* and one for USB access. */
Ingo Molnar3593cab2006-02-07 06:49:14 -020088 struct mutex semi2c;
89 struct mutex semusb;
Linus Torvalds1da177e2005-04-16 15:20:36 -070090
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -070091 struct dvb_adapter adapter;
Linus Torvalds1da177e2005-04-16 15:20:36 -070092 struct usb_device *dev;
93
94 struct i2c_adapter i2c_adap;
95
96 int disconnecting;
97 int iso_streaming;
98
99 unsigned int bulk_out_pipe;
100 unsigned int bulk_in_pipe;
101 unsigned int isoc_in_pipe;
102
103 void *iso_buffer;
104 dma_addr_t iso_dma_handle;
105
106 struct urb *iso_urb[ISO_BUF_COUNT];
107
108 int running_feed_count;
109 int last_channel;
110 int last_filter;
111
112 u8 c; /* transaction counter, wraps around... */
113 fe_sec_tone_mode_t tone;
114 fe_sec_voltage_t voltage;
115
116 int mux_state; // 0..2 - MuxSyncWord, 3 - nMuxPacks, 4 - muxpack
117 u8 mux_npacks;
118 u8 muxpack[256 + 8];
119 int muxpack_ptr, muxpack_len;
120
121 int insync;
122
123 int cc; /* MuxCounter - will increment on EVERY MUX PACKET */
124 /* (including stuffing. yes. really.) */
125
126 u8 last_result[32];
127
128 int revision;
129
Linus Torvalds1da177e2005-04-16 15:20:36 -0700130 struct dvb_frontend* fe;
131};
132
Robert P. J. Day3a4fa0a2007-10-19 23:10:43 +0200133/* ugly workaround ... don't know why it's necessary to read */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700134/* all result codes. */
135
136#define DEBUG 0
137static int ttusb_cmd(struct ttusb *ttusb,
138 const u8 * data, int len, int needresult)
139{
140 int actual_len;
141 int err;
142#if DEBUG >= 3
143 int i;
144
145 printk(">");
146 for (i = 0; i < len; ++i)
147 printk(" %02x", data[i]);
148 printk("\n");
149#endif
150
Ingo Molnar3593cab2006-02-07 06:49:14 -0200151 if (mutex_lock_interruptible(&ttusb->semusb) < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700152 return -EAGAIN;
153
154 err = usb_bulk_msg(ttusb->dev, ttusb->bulk_out_pipe,
155 (u8 *) data, len, &actual_len, 1000);
156 if (err != 0) {
157 dprintk("%s: usb_bulk_msg(send) failed, err == %i!\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300158 __func__, err);
Ingo Molnar3593cab2006-02-07 06:49:14 -0200159 mutex_unlock(&ttusb->semusb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700160 return err;
161 }
162 if (actual_len != len) {
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300163 dprintk("%s: only wrote %d of %d bytes\n", __func__,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700164 actual_len, len);
Ingo Molnar3593cab2006-02-07 06:49:14 -0200165 mutex_unlock(&ttusb->semusb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700166 return -1;
167 }
168
169 err = usb_bulk_msg(ttusb->dev, ttusb->bulk_in_pipe,
170 ttusb->last_result, 32, &actual_len, 1000);
171
172 if (err != 0) {
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300173 printk("%s: failed, receive error %d\n", __func__,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700174 err);
Ingo Molnar3593cab2006-02-07 06:49:14 -0200175 mutex_unlock(&ttusb->semusb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700176 return err;
177 }
178#if DEBUG >= 3
179 actual_len = ttusb->last_result[3] + 4;
180 printk("<");
181 for (i = 0; i < actual_len; ++i)
182 printk(" %02x", ttusb->last_result[i]);
183 printk("\n");
184#endif
185 if (!needresult)
Ingo Molnar3593cab2006-02-07 06:49:14 -0200186 mutex_unlock(&ttusb->semusb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700187 return 0;
188}
189
190static int ttusb_result(struct ttusb *ttusb, u8 * data, int len)
191{
192 memcpy(data, ttusb->last_result, len);
Ingo Molnar3593cab2006-02-07 06:49:14 -0200193 mutex_unlock(&ttusb->semusb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700194 return 0;
195}
196
197static int ttusb_i2c_msg(struct ttusb *ttusb,
198 u8 addr, u8 * snd_buf, u8 snd_len, u8 * rcv_buf,
199 u8 rcv_len)
200{
201 u8 b[0x28];
202 u8 id = ++ttusb->c;
203 int i, err;
204
205 if (snd_len > 0x28 - 7 || rcv_len > 0x20 - 7)
206 return -EINVAL;
207
208 b[0] = 0xaa;
209 b[1] = id;
210 b[2] = 0x31;
211 b[3] = snd_len + 3;
212 b[4] = addr << 1;
213 b[5] = snd_len;
214 b[6] = rcv_len;
215
216 for (i = 0; i < snd_len; i++)
217 b[7 + i] = snd_buf[i];
218
219 err = ttusb_cmd(ttusb, b, snd_len + 7, 1);
220
221 if (err)
222 return -EREMOTEIO;
223
224 err = ttusb_result(ttusb, b, 0x20);
225
Mauro Carvalho Chehab9101e622005-12-12 00:37:24 -0800226 /* check if the i2c transaction was successful */
227 if ((snd_len != b[5]) || (rcv_len != b[6])) return -EREMOTEIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700228
229 if (rcv_len > 0) {
230
231 if (err || b[0] != 0x55 || b[1] != id) {
232 dprintk
233 ("%s: usb_bulk_msg(recv) failed, err == %i, id == %02x, b == ",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300234 __func__, err, id);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700235 return -EREMOTEIO;
236 }
237
238 for (i = 0; i < rcv_len; i++)
239 rcv_buf[i] = b[7 + i];
240 }
241
242 return rcv_len;
243}
244
245static int master_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, int num)
246{
247 struct ttusb *ttusb = i2c_get_adapdata(adapter);
248 int i = 0;
249 int inc;
250
Ingo Molnar3593cab2006-02-07 06:49:14 -0200251 if (mutex_lock_interruptible(&ttusb->semi2c) < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700252 return -EAGAIN;
253
254 while (i < num) {
255 u8 addr, snd_len, rcv_len, *snd_buf, *rcv_buf;
256 int err;
257
258 if (num > i + 1 && (msg[i + 1].flags & I2C_M_RD)) {
259 addr = msg[i].addr;
260 snd_buf = msg[i].buf;
261 snd_len = msg[i].len;
262 rcv_buf = msg[i + 1].buf;
263 rcv_len = msg[i + 1].len;
264 inc = 2;
265 } else {
266 addr = msg[i].addr;
267 snd_buf = msg[i].buf;
268 snd_len = msg[i].len;
269 rcv_buf = NULL;
270 rcv_len = 0;
271 inc = 1;
272 }
273
274 err = ttusb_i2c_msg(ttusb, addr,
275 snd_buf, snd_len, rcv_buf, rcv_len);
276
277 if (err < rcv_len) {
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300278 dprintk("%s: i == %i\n", __func__, i);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279 break;
280 }
281
282 i += inc;
283 }
284
Ingo Molnar3593cab2006-02-07 06:49:14 -0200285 mutex_unlock(&ttusb->semi2c);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700286 return i;
287}
288
Linus Torvalds1da177e2005-04-16 15:20:36 -0700289static int ttusb_boot_dsp(struct ttusb *ttusb)
290{
David Woodhouse0a2a7362008-05-29 19:50:06 +0300291 const struct firmware *fw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700292 int i, err;
293 u8 b[40];
294
David Woodhouse0a2a7362008-05-29 19:50:06 +0300295 err = request_firmware(&fw, "ttusb-budget/dspbootcode.bin",
296 &ttusb->dev->dev);
297 if (err) {
298 printk(KERN_ERR "ttusb-budget: failed to request firmware\n");
299 return err;
300 }
301
Linus Torvalds1da177e2005-04-16 15:20:36 -0700302 /* BootBlock */
303 b[0] = 0xaa;
304 b[2] = 0x13;
305 b[3] = 28;
306
307 /* upload dsp code in 32 byte steps (36 didn't work for me ...) */
308 /* 32 is max packet size, no messages should be splitted. */
David Woodhouse0a2a7362008-05-29 19:50:06 +0300309 for (i = 0; i < fw->size; i += 28) {
310 memcpy(&b[4], &fw->data[i], 28);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700311
312 b[1] = ++ttusb->c;
313
314 err = ttusb_cmd(ttusb, b, 32, 0);
315 if (err)
316 goto done;
317 }
318
319 /* last block ... */
320 b[1] = ++ttusb->c;
321 b[2] = 0x13;
322 b[3] = 0;
323
324 err = ttusb_cmd(ttusb, b, 4, 0);
325 if (err)
326 goto done;
327
328 /* BootEnd */
329 b[1] = ++ttusb->c;
330 b[2] = 0x14;
331 b[3] = 0;
332
333 err = ttusb_cmd(ttusb, b, 4, 0);
334
335 done:
336 if (err) {
337 dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300338 __func__, err);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700339 }
340
341 return err;
342}
343
344static int ttusb_set_channel(struct ttusb *ttusb, int chan_id, int filter_type,
345 int pid)
346{
347 int err;
348 /* SetChannel */
349 u8 b[] = { 0xaa, ++ttusb->c, 0x22, 4, chan_id, filter_type,
350 (pid >> 8) & 0xff, pid & 0xff
351 };
352
353 err = ttusb_cmd(ttusb, b, sizeof(b), 0);
354 return err;
355}
356
357static int ttusb_del_channel(struct ttusb *ttusb, int channel_id)
358{
359 int err;
360 /* DelChannel */
361 u8 b[] = { 0xaa, ++ttusb->c, 0x23, 1, channel_id };
362
363 err = ttusb_cmd(ttusb, b, sizeof(b), 0);
364 return err;
365}
366
367#ifdef TTUSB_HWSECTIONS
368static int ttusb_set_filter(struct ttusb *ttusb, int filter_id,
369 int associated_chan, u8 filter[8], u8 mask[8])
370{
371 int err;
372 /* SetFilter */
373 u8 b[] = { 0xaa, 0, 0x24, 0x1a, filter_id, associated_chan,
374 filter[0], filter[1], filter[2], filter[3],
375 filter[4], filter[5], filter[6], filter[7],
376 filter[8], filter[9], filter[10], filter[11],
377 mask[0], mask[1], mask[2], mask[3],
378 mask[4], mask[5], mask[6], mask[7],
379 mask[8], mask[9], mask[10], mask[11]
380 };
381
382 err = ttusb_cmd(ttusb, b, sizeof(b), 0);
383 return err;
384}
385
386static int ttusb_del_filter(struct ttusb *ttusb, int filter_id)
387{
388 int err;
389 /* DelFilter */
390 u8 b[] = { 0xaa, ++ttusb->c, 0x25, 1, filter_id };
391
392 err = ttusb_cmd(ttusb, b, sizeof(b), 0);
393 return err;
394}
395#endif
396
397static int ttusb_init_controller(struct ttusb *ttusb)
398{
399 u8 b0[] = { 0xaa, ++ttusb->c, 0x15, 1, 0 };
400 u8 b1[] = { 0xaa, ++ttusb->c, 0x15, 1, 1 };
401 u8 b2[] = { 0xaa, ++ttusb->c, 0x32, 1, 0 };
402 /* i2c write read: 5 bytes, addr 0x10, 0x02 bytes write, 1 bytes read. */
403 u8 b3[] =
404 { 0xaa, ++ttusb->c, 0x31, 5, 0x10, 0x02, 0x01, 0x00, 0x1e };
405 u8 b4[] =
406 { 0x55, ttusb->c, 0x31, 4, 0x10, 0x02, 0x01, 0x00, 0x1e };
407
408 u8 get_version[] = { 0xaa, ++ttusb->c, 0x17, 5, 0, 0, 0, 0, 0 };
409 u8 get_dsp_version[0x20] =
410 { 0xaa, ++ttusb->c, 0x26, 28, 0, 0, 0, 0, 0 };
411 int err;
412
413 /* reset board */
414 if ((err = ttusb_cmd(ttusb, b0, sizeof(b0), 0)))
415 return err;
416
417 /* reset board (again?) */
418 if ((err = ttusb_cmd(ttusb, b1, sizeof(b1), 0)))
419 return err;
420
421 ttusb_boot_dsp(ttusb);
422
423 /* set i2c bit rate */
424 if ((err = ttusb_cmd(ttusb, b2, sizeof(b2), 0)))
425 return err;
426
427 if ((err = ttusb_cmd(ttusb, b3, sizeof(b3), 1)))
428 return err;
429
430 err = ttusb_result(ttusb, b4, sizeof(b4));
431
432 if ((err = ttusb_cmd(ttusb, get_version, sizeof(get_version), 1)))
433 return err;
434
435 if ((err = ttusb_result(ttusb, get_version, sizeof(get_version))))
436 return err;
437
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300438 dprintk("%s: stc-version: %c%c%c%c%c\n", __func__,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700439 get_version[4], get_version[5], get_version[6],
440 get_version[7], get_version[8]);
441
442 if (memcmp(get_version + 4, "V 0.0", 5) &&
443 memcmp(get_version + 4, "V 1.1", 5) &&
444 memcmp(get_version + 4, "V 2.1", 5) &&
445 memcmp(get_version + 4, "V 2.2", 5)) {
446 printk
447 ("%s: unknown STC version %c%c%c%c%c, please report!\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300448 __func__, get_version[4], get_version[5],
Linus Torvalds1da177e2005-04-16 15:20:36 -0700449 get_version[6], get_version[7], get_version[8]);
450 }
451
452 ttusb->revision = ((get_version[6] - '0') << 4) |
453 (get_version[8] - '0');
454
455 err =
456 ttusb_cmd(ttusb, get_dsp_version, sizeof(get_dsp_version), 1);
457 if (err)
458 return err;
459
460 err =
461 ttusb_result(ttusb, get_dsp_version, sizeof(get_dsp_version));
462 if (err)
463 return err;
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300464 printk("%s: dsp-version: %c%c%c\n", __func__,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700465 get_dsp_version[4], get_dsp_version[5], get_dsp_version[6]);
466 return 0;
467}
468
469#ifdef TTUSB_DISEQC
470static int ttusb_send_diseqc(struct dvb_frontend* fe,
471 const struct dvb_diseqc_master_cmd *cmd)
472{
473 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
474 u8 b[12] = { 0xaa, ++ttusb->c, 0x18 };
475
476 int err;
477
478 b[3] = 4 + 2 + cmd->msg_len;
479 b[4] = 0xFF; /* send diseqc master, not burst */
480 b[5] = cmd->msg_len;
481
482 memcpy(b + 5, cmd->msg, cmd->msg_len);
483
484 /* Diseqc */
485 if ((err = ttusb_cmd(ttusb, b, 4 + b[3], 0))) {
486 dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300487 __func__, err);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700488 }
489
490 return err;
491}
492#endif
493
Linus Torvalds1da177e2005-04-16 15:20:36 -0700494static int ttusb_update_lnb(struct ttusb *ttusb)
495{
496 u8 b[] = { 0xaa, ++ttusb->c, 0x16, 5, /*power: */ 1,
497 ttusb->voltage == SEC_VOLTAGE_18 ? 0 : 1,
498 ttusb->tone == SEC_TONE_ON ? 1 : 0, 1, 1
499 };
500 int err;
501
502 /* SetLNB */
503 if ((err = ttusb_cmd(ttusb, b, sizeof(b), 0))) {
504 dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300505 __func__, err);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700506 }
507
508 return err;
509}
510
511static int ttusb_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
512{
513 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
514
515 ttusb->voltage = voltage;
516 return ttusb_update_lnb(ttusb);
517}
518
519#ifdef TTUSB_TONE
520static int ttusb_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
521{
522 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
523
524 ttusb->tone = tone;
525 return ttusb_update_lnb(ttusb);
526}
527#endif
528
529
530#if 0
531static void ttusb_set_led_freq(struct ttusb *ttusb, u8 freq)
532{
533 u8 b[] = { 0xaa, ++ttusb->c, 0x19, 1, freq };
534 int err, actual_len;
535
536 err = ttusb_cmd(ttusb, b, sizeof(b), 0);
537 if (err) {
538 dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300539 __func__, err);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700540 }
541}
542#endif
543
544/*****************************************************************************/
545
546#ifdef TTUSB_HWSECTIONS
547static void ttusb_handle_ts_data(struct ttusb_channel *channel,
548 const u8 * data, int len);
549static void ttusb_handle_sec_data(struct ttusb_channel *channel,
550 const u8 * data, int len);
551#endif
552
Douglas Schilling Landgrafff699e62008-04-22 14:41:48 -0300553static int numpkt, numts, numstuff, numsec, numinvalid;
Marcelo Feitoza Parisi4da006c2005-09-09 13:03:15 -0700554static unsigned long lastj;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700555
556static void ttusb_process_muxpack(struct ttusb *ttusb, const u8 * muxpack,
557 int len)
558{
559 u16 csum = 0, cc;
560 int i;
561 for (i = 0; i < len; i += 2)
Al Virod4f979a2008-05-21 00:31:31 -0300562 csum ^= le16_to_cpup((__le16 *) (muxpack + i));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700563 if (csum) {
564 printk("%s: muxpack with incorrect checksum, ignoring\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300565 __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700566 numinvalid++;
567 return;
568 }
569
570 cc = (muxpack[len - 4] << 8) | muxpack[len - 3];
571 cc &= 0x7FFF;
572 if ((cc != ttusb->cc) && (ttusb->cc != -1))
573 printk("%s: cc discontinuity (%d frames missing)\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300574 __func__, (cc - ttusb->cc) & 0x7FFF);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700575 ttusb->cc = (cc + 1) & 0x7FFF;
576 if (muxpack[0] & 0x80) {
577#ifdef TTUSB_HWSECTIONS
578 /* section data */
579 int pusi = muxpack[0] & 0x40;
580 int channel = muxpack[0] & 0x1F;
581 int payload = muxpack[1];
582 const u8 *data = muxpack + 2;
583 /* check offset flag */
584 if (muxpack[0] & 0x20)
585 data++;
586
587 ttusb_handle_sec_data(ttusb->channel + channel, data,
588 payload);
589 data += payload;
590
591 if ((!!(ttusb->muxpack[0] & 0x20)) ^
592 !!(ttusb->muxpack[1] & 1))
593 data++;
594#warning TODO: pusi
595 printk("cc: %04x\n", (data[0] << 8) | data[1]);
596#endif
597 numsec++;
598 } else if (muxpack[0] == 0x47) {
599#ifdef TTUSB_HWSECTIONS
600 /* we have TS data here! */
601 int pid = ((muxpack[1] & 0x0F) << 8) | muxpack[2];
602 int channel;
603 for (channel = 0; channel < TTUSB_MAXCHANNEL; ++channel)
604 if (ttusb->channel[channel].active
605 && (pid == ttusb->channel[channel].pid))
606 ttusb_handle_ts_data(ttusb->channel +
607 channel, muxpack,
608 188);
609#endif
610 numts++;
611 dvb_dmx_swfilter_packets(&ttusb->dvb_demux, muxpack, 1);
612 } else if (muxpack[0] != 0) {
613 numinvalid++;
614 printk("illegal muxpack type %02x\n", muxpack[0]);
615 } else
616 numstuff++;
617}
618
619static void ttusb_process_frame(struct ttusb *ttusb, u8 * data, int len)
620{
621 int maxwork = 1024;
622 while (len) {
623 if (!(maxwork--)) {
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300624 printk("%s: too much work\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700625 break;
626 }
627
628 switch (ttusb->mux_state) {
629 case 0:
630 case 1:
631 case 2:
632 len--;
633 if (*data++ == 0xAA)
634 ++ttusb->mux_state;
635 else {
636 ttusb->mux_state = 0;
637#if DEBUG > 3
638 if (ttusb->insync)
639 printk("%02x ", data[-1]);
640#else
641 if (ttusb->insync) {
642 printk("%s: lost sync.\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300643 __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700644 ttusb->insync = 0;
645 }
646#endif
647 }
648 break;
649 case 3:
650 ttusb->insync = 1;
651 len--;
652 ttusb->mux_npacks = *data++;
653 ++ttusb->mux_state;
654 ttusb->muxpack_ptr = 0;
655 /* maximum bytes, until we know the length */
656 ttusb->muxpack_len = 2;
657 break;
658 case 4:
659 {
660 int avail;
661 avail = len;
662 if (avail >
663 (ttusb->muxpack_len -
664 ttusb->muxpack_ptr))
665 avail =
666 ttusb->muxpack_len -
667 ttusb->muxpack_ptr;
668 memcpy(ttusb->muxpack + ttusb->muxpack_ptr,
669 data, avail);
670 ttusb->muxpack_ptr += avail;
Eric Sesterhennae246012006-03-13 13:17:11 -0300671 BUG_ON(ttusb->muxpack_ptr > 264);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700672 data += avail;
673 len -= avail;
674 /* determine length */
675 if (ttusb->muxpack_ptr == 2) {
676 if (ttusb->muxpack[0] & 0x80) {
677 ttusb->muxpack_len =
678 ttusb->muxpack[1] + 2;
679 if (ttusb->
680 muxpack[0] & 0x20)
681 ttusb->
682 muxpack_len++;
683 if ((!!
684 (ttusb->
685 muxpack[0] & 0x20)) ^
686 !!(ttusb->
687 muxpack[1] & 1))
688 ttusb->
689 muxpack_len++;
690 ttusb->muxpack_len += 4;
691 } else if (ttusb->muxpack[0] ==
692 0x47)
693 ttusb->muxpack_len =
694 188 + 4;
695 else if (ttusb->muxpack[0] == 0x00)
696 ttusb->muxpack_len =
697 ttusb->muxpack[1] + 2 +
698 4;
699 else {
700 dprintk
701 ("%s: invalid state: first byte is %x\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300702 __func__,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700703 ttusb->muxpack[0]);
704 ttusb->mux_state = 0;
705 }
706 }
707
708 /**
709 * if length is valid and we reached the end:
710 * goto next muxpack
711 */
712 if ((ttusb->muxpack_ptr >= 2) &&
713 (ttusb->muxpack_ptr ==
714 ttusb->muxpack_len)) {
715 ttusb_process_muxpack(ttusb,
716 ttusb->
717 muxpack,
718 ttusb->
719 muxpack_ptr);
720 ttusb->muxpack_ptr = 0;
721 /* maximum bytes, until we know the length */
722 ttusb->muxpack_len = 2;
723
724 /**
725 * no muxpacks left?
726 * return to search-sync state
727 */
728 if (!ttusb->mux_npacks--) {
729 ttusb->mux_state = 0;
730 break;
731 }
732 }
733 break;
734 }
735 default:
736 BUG();
737 break;
738 }
739 }
740}
741
David Howells7d12e782006-10-05 14:55:46 +0100742static void ttusb_iso_irq(struct urb *urb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700743{
744 struct ttusb *ttusb = urb->context;
745
746 if (!ttusb->iso_streaming)
747 return;
748
749#if 0
750 printk("%s: status %d, errcount == %d, length == %i\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300751 __func__,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700752 urb->status, urb->error_count, urb->actual_length);
753#endif
754
755 if (!urb->status) {
756 int i;
757 for (i = 0; i < urb->number_of_packets; ++i) {
758 struct usb_iso_packet_descriptor *d;
759 u8 *data;
760 int len;
761 numpkt++;
Marcelo Feitoza Parisi4da006c2005-09-09 13:03:15 -0700762 if (time_after_eq(jiffies, lastj + HZ)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700763#if DEBUG > 2
764 printk
765 ("frames/s: %d (ts: %d, stuff %d, sec: %d, invalid: %d, all: %d)\n",
766 numpkt * HZ / (jiffies - lastj),
767 numts, numstuff, numsec, numinvalid,
768 numts + numstuff + numsec +
769 numinvalid);
770#endif
771 numts = numstuff = numsec = numinvalid = 0;
772 lastj = jiffies;
773 numpkt = 0;
774 }
775 d = &urb->iso_frame_desc[i];
776 data = urb->transfer_buffer + d->offset;
777 len = d->actual_length;
778 d->actual_length = 0;
779 d->status = 0;
780 ttusb_process_frame(ttusb, data, len);
781 }
782 }
783 usb_submit_urb(urb, GFP_ATOMIC);
784}
785
786static void ttusb_free_iso_urbs(struct ttusb *ttusb)
787{
788 int i;
789
790 for (i = 0; i < ISO_BUF_COUNT; i++)
791 if (ttusb->iso_urb[i])
792 usb_free_urb(ttusb->iso_urb[i]);
793
794 pci_free_consistent(NULL,
795 ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF *
796 ISO_BUF_COUNT, ttusb->iso_buffer,
797 ttusb->iso_dma_handle);
798}
799
800static int ttusb_alloc_iso_urbs(struct ttusb *ttusb)
801{
802 int i;
803
804 ttusb->iso_buffer = pci_alloc_consistent(NULL,
805 ISO_FRAME_SIZE *
806 FRAMES_PER_ISO_BUF *
807 ISO_BUF_COUNT,
808 &ttusb->iso_dma_handle);
809
810 memset(ttusb->iso_buffer, 0,
811 ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF * ISO_BUF_COUNT);
812
813 for (i = 0; i < ISO_BUF_COUNT; i++) {
814 struct urb *urb;
815
816 if (!
817 (urb =
818 usb_alloc_urb(FRAMES_PER_ISO_BUF, GFP_ATOMIC))) {
819 ttusb_free_iso_urbs(ttusb);
820 return -ENOMEM;
821 }
822
823 ttusb->iso_urb[i] = urb;
824 }
825
826 return 0;
827}
828
829static void ttusb_stop_iso_xfer(struct ttusb *ttusb)
830{
831 int i;
832
833 for (i = 0; i < ISO_BUF_COUNT; i++)
834 usb_kill_urb(ttusb->iso_urb[i]);
835
836 ttusb->iso_streaming = 0;
837}
838
839static int ttusb_start_iso_xfer(struct ttusb *ttusb)
840{
841 int i, j, err, buffer_offset = 0;
842
843 if (ttusb->iso_streaming) {
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300844 printk("%s: iso xfer already running!\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700845 return 0;
846 }
847
848 ttusb->cc = -1;
849 ttusb->insync = 0;
850 ttusb->mux_state = 0;
851
852 for (i = 0; i < ISO_BUF_COUNT; i++) {
853 int frame_offset = 0;
854 struct urb *urb = ttusb->iso_urb[i];
855
856 urb->dev = ttusb->dev;
857 urb->context = ttusb;
858 urb->complete = ttusb_iso_irq;
859 urb->pipe = ttusb->isoc_in_pipe;
860 urb->transfer_flags = URB_ISO_ASAP;
861 urb->interval = 1;
862 urb->number_of_packets = FRAMES_PER_ISO_BUF;
863 urb->transfer_buffer_length =
864 ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF;
865 urb->transfer_buffer = ttusb->iso_buffer + buffer_offset;
866 buffer_offset += ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF;
867
868 for (j = 0; j < FRAMES_PER_ISO_BUF; j++) {
869 urb->iso_frame_desc[j].offset = frame_offset;
870 urb->iso_frame_desc[j].length = ISO_FRAME_SIZE;
871 frame_offset += ISO_FRAME_SIZE;
872 }
873 }
874
875 for (i = 0; i < ISO_BUF_COUNT; i++) {
876 if ((err = usb_submit_urb(ttusb->iso_urb[i], GFP_ATOMIC))) {
877 ttusb_stop_iso_xfer(ttusb);
878 printk
879 ("%s: failed urb submission (%i: err = %i)!\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300880 __func__, i, err);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700881 return err;
882 }
883 }
884
885 ttusb->iso_streaming = 1;
886
887 return 0;
888}
889
890#ifdef TTUSB_HWSECTIONS
891static void ttusb_handle_ts_data(struct dvb_demux_feed *dvbdmxfeed, const u8 * data,
892 int len)
893{
894 dvbdmxfeed->cb.ts(data, len, 0, 0, &dvbdmxfeed->feed.ts, 0);
895}
896
897static void ttusb_handle_sec_data(struct dvb_demux_feed *dvbdmxfeed, const u8 * data,
898 int len)
899{
900// struct dvb_demux_feed *dvbdmxfeed = channel->dvbdmxfeed;
901#error TODO: handle ugly stuff
902// dvbdmxfeed->cb.sec(data, len, 0, 0, &dvbdmxfeed->feed.sec, 0);
903}
904#endif
905
906static int ttusb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
907{
908 struct ttusb *ttusb = (struct ttusb *) dvbdmxfeed->demux;
909 int feed_type = 1;
910
911 dprintk("ttusb_start_feed\n");
912
913 switch (dvbdmxfeed->type) {
914 case DMX_TYPE_TS:
915 break;
916 case DMX_TYPE_SEC:
917 break;
918 default:
919 return -EINVAL;
920 }
921
922 if (dvbdmxfeed->type == DMX_TYPE_TS) {
923 switch (dvbdmxfeed->pes_type) {
924 case DMX_TS_PES_VIDEO:
925 case DMX_TS_PES_AUDIO:
926 case DMX_TS_PES_TELETEXT:
927 case DMX_TS_PES_PCR:
928 case DMX_TS_PES_OTHER:
929 break;
930 default:
931 return -EINVAL;
932 }
933 }
934
935#ifdef TTUSB_HWSECTIONS
936#error TODO: allocate filters
937 if (dvbdmxfeed->type == DMX_TYPE_TS) {
938 feed_type = 1;
939 } else if (dvbdmxfeed->type == DMX_TYPE_SEC) {
940 feed_type = 2;
941 }
942#endif
943
944 ttusb_set_channel(ttusb, dvbdmxfeed->index, feed_type, dvbdmxfeed->pid);
945
946 if (0 == ttusb->running_feed_count++)
947 ttusb_start_iso_xfer(ttusb);
948
949 return 0;
950}
951
952static int ttusb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
953{
954 struct ttusb *ttusb = (struct ttusb *) dvbdmxfeed->demux;
955
956 ttusb_del_channel(ttusb, dvbdmxfeed->index);
957
958 if (--ttusb->running_feed_count == 0)
959 ttusb_stop_iso_xfer(ttusb);
960
961 return 0;
962}
963
964static int ttusb_setup_interfaces(struct ttusb *ttusb)
965{
966 usb_set_interface(ttusb->dev, 1, 1);
967
968 ttusb->bulk_out_pipe = usb_sndbulkpipe(ttusb->dev, 1);
969 ttusb->bulk_in_pipe = usb_rcvbulkpipe(ttusb->dev, 1);
970 ttusb->isoc_in_pipe = usb_rcvisocpipe(ttusb->dev, 2);
971
972 return 0;
973}
974
975#if 0
976static u8 stc_firmware[8192];
977
978static int stc_open(struct inode *inode, struct file *file)
979{
980 struct ttusb *ttusb = file->private_data;
981 int addr;
982
983 for (addr = 0; addr < 8192; addr += 16) {
984 u8 snd_buf[2] = { addr >> 8, addr & 0xFF };
985 ttusb_i2c_msg(ttusb, 0x50, snd_buf, 2, stc_firmware + addr,
986 16);
987 }
988
989 return 0;
990}
991
992static ssize_t stc_read(struct file *file, char *buf, size_t count,
993 loff_t * offset)
994{
995 int tc = count;
996
997 if ((tc + *offset) > 8192)
998 tc = 8192 - *offset;
999
1000 if (tc < 0)
1001 return 0;
1002
1003 if (copy_to_user(buf, stc_firmware + *offset, tc))
1004 return -EFAULT;
1005
1006 *offset += tc;
1007
1008 return tc;
1009}
1010
1011static int stc_release(struct inode *inode, struct file *file)
1012{
1013 return 0;
1014}
1015
Jan Engelhardt27a643b2008-04-22 14:42:01 -03001016static const struct file_operations stc_fops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001017 .owner = THIS_MODULE,
1018 .read = stc_read,
1019 .open = stc_open,
1020 .release = stc_release,
1021};
1022#endif
1023
1024static u32 functionality(struct i2c_adapter *adapter)
1025{
1026 return I2C_FUNC_I2C;
1027}
1028
1029
1030
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001031static int alps_tdmb7_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001032{
1033 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1034 u8 data[4];
1035 struct i2c_msg msg = {.addr=0x61, .flags=0, .buf=data, .len=sizeof(data) };
1036 u32 div;
1037
1038 div = (params->frequency + 36166667) / 166667;
1039
1040 data[0] = (div >> 8) & 0x7f;
1041 data[1] = div & 0xff;
1042 data[2] = ((div >> 10) & 0x60) | 0x85;
1043 data[3] = params->frequency < 592000000 ? 0x40 : 0x80;
1044
Patrick Boettcherdea74862006-05-14 05:01:31 -03001045 if (fe->ops.i2c_gate_ctrl)
1046 fe->ops.i2c_gate_ctrl(fe, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001047 if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1) return -EIO;
1048 return 0;
1049}
1050
Johannes Stezenbachd91b7302005-05-16 21:54:38 -07001051static struct cx22700_config alps_tdmb7_config = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001052 .demod_address = 0x43,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001053};
1054
1055
1056
1057
1058
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001059static int philips_tdm1316l_tuner_init(struct dvb_frontend* fe)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001060{
1061 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1062 static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab };
1063 static u8 disable_mc44BC374c[] = { 0x1d, 0x74, 0xa0, 0x68 };
1064 struct i2c_msg tuner_msg = { .addr=0x60, .flags=0, .buf=td1316_init, .len=sizeof(td1316_init) };
1065
1066 // setup PLL configuration
Patrick Boettcherdea74862006-05-14 05:01:31 -03001067 if (fe->ops.i2c_gate_ctrl)
1068 fe->ops.i2c_gate_ctrl(fe, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001069 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) return -EIO;
1070 msleep(1);
1071
1072 // disable the mc44BC374c (do not check for errors)
1073 tuner_msg.addr = 0x65;
1074 tuner_msg.buf = disable_mc44BC374c;
1075 tuner_msg.len = sizeof(disable_mc44BC374c);
Patrick Boettcherdea74862006-05-14 05:01:31 -03001076 if (fe->ops.i2c_gate_ctrl)
1077 fe->ops.i2c_gate_ctrl(fe, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001078 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) {
1079 i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1);
1080 }
1081
1082 return 0;
1083}
1084
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001085static int philips_tdm1316l_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001086{
1087 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1088 u8 tuner_buf[4];
1089 struct i2c_msg tuner_msg = {.addr=0x60, .flags=0, .buf=tuner_buf, .len=sizeof(tuner_buf) };
1090 int tuner_frequency = 0;
1091 u8 band, cp, filter;
1092
1093 // determine charge pump
1094 tuner_frequency = params->frequency + 36130000;
1095 if (tuner_frequency < 87000000) return -EINVAL;
1096 else if (tuner_frequency < 130000000) cp = 3;
1097 else if (tuner_frequency < 160000000) cp = 5;
1098 else if (tuner_frequency < 200000000) cp = 6;
1099 else if (tuner_frequency < 290000000) cp = 3;
1100 else if (tuner_frequency < 420000000) cp = 5;
1101 else if (tuner_frequency < 480000000) cp = 6;
1102 else if (tuner_frequency < 620000000) cp = 3;
1103 else if (tuner_frequency < 830000000) cp = 5;
1104 else if (tuner_frequency < 895000000) cp = 7;
1105 else return -EINVAL;
1106
1107 // determine band
1108 if (params->frequency < 49000000) return -EINVAL;
1109 else if (params->frequency < 159000000) band = 1;
1110 else if (params->frequency < 444000000) band = 2;
1111 else if (params->frequency < 861000000) band = 4;
1112 else return -EINVAL;
1113
1114 // setup PLL filter
1115 switch (params->u.ofdm.bandwidth) {
1116 case BANDWIDTH_6_MHZ:
Andrew de Quinceyc10d14d2006-08-08 09:10:08 -03001117 tda1004x_writereg(fe, 0x0C, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001118 filter = 0;
1119 break;
1120
1121 case BANDWIDTH_7_MHZ:
Andrew de Quinceyc10d14d2006-08-08 09:10:08 -03001122 tda1004x_writereg(fe, 0x0C, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001123 filter = 0;
1124 break;
1125
1126 case BANDWIDTH_8_MHZ:
Andrew de Quinceyc10d14d2006-08-08 09:10:08 -03001127 tda1004x_writereg(fe, 0x0C, 0xFF);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001128 filter = 1;
1129 break;
1130
1131 default:
1132 return -EINVAL;
1133 }
1134
1135 // calculate divisor
1136 // ((36130000+((1000000/6)/2)) + Finput)/(1000000/6)
1137 tuner_frequency = (((params->frequency / 1000) * 6) + 217280) / 1000;
1138
1139 // setup tuner buffer
1140 tuner_buf[0] = tuner_frequency >> 8;
1141 tuner_buf[1] = tuner_frequency & 0xff;
1142 tuner_buf[2] = 0xca;
1143 tuner_buf[3] = (cp << 5) | (filter << 3) | band;
1144
Patrick Boettcherdea74862006-05-14 05:01:31 -03001145 if (fe->ops.i2c_gate_ctrl)
1146 fe->ops.i2c_gate_ctrl(fe, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001147 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1)
1148 return -EIO;
1149
1150 msleep(1);
1151 return 0;
1152}
1153
1154static int philips_tdm1316l_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
1155{
1156 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1157
1158 return request_firmware(fw, name, &ttusb->dev->dev);
1159}
1160
1161static struct tda1004x_config philips_tdm1316l_config = {
1162
1163 .demod_address = 0x8,
1164 .invert = 1,
1165 .invert_oclk = 0,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001166 .request_firmware = philips_tdm1316l_request_firmware,
1167};
1168
1169static u8 alps_bsbe1_inittab[] = {
Mauro Carvalho Chehab9101e622005-12-12 00:37:24 -08001170 0x01, 0x15,
1171 0x02, 0x30,
1172 0x03, 0x00,
1173 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
1174 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
1175 0x06, 0x40, /* DAC not used, set to high impendance mode */
1176 0x07, 0x00, /* DAC LSB */
1177 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
1178 0x09, 0x00, /* FIFO */
1179 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
1180 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
1181 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
1182 0x10, 0x3f, // AGC2 0x3d
1183 0x11, 0x84,
1184 0x12, 0xb9,
1185 0x15, 0xc9, // lock detector threshold
1186 0x16, 0x00,
1187 0x17, 0x00,
1188 0x18, 0x00,
1189 0x19, 0x00,
1190 0x1a, 0x00,
1191 0x1f, 0x50,
1192 0x20, 0x00,
1193 0x21, 0x00,
1194 0x22, 0x00,
1195 0x23, 0x00,
1196 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
1197 0x29, 0x1e, // 1/2 threshold
1198 0x2a, 0x14, // 2/3 threshold
1199 0x2b, 0x0f, // 3/4 threshold
1200 0x2c, 0x09, // 5/6 threshold
1201 0x2d, 0x05, // 7/8 threshold
1202 0x2e, 0x01,
1203 0x31, 0x1f, // test all FECs
1204 0x32, 0x19, // viterbi and synchro search
1205 0x33, 0xfc, // rs control
1206 0x34, 0x93, // error control
1207 0x0f, 0x92,
1208 0xff, 0xff
Linus Torvalds1da177e2005-04-16 15:20:36 -07001209};
1210
1211static u8 alps_bsru6_inittab[] = {
1212 0x01, 0x15,
1213 0x02, 0x30,
1214 0x03, 0x00,
1215 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
1216 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
1217 0x06, 0x40, /* DAC not used, set to high impendance mode */
1218 0x07, 0x00, /* DAC LSB */
1219 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
1220 0x09, 0x00, /* FIFO */
1221 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
1222 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
1223 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
1224 0x10, 0x3f, // AGC2 0x3d
1225 0x11, 0x84,
Oliver Endriss7f44dcd2005-11-08 21:35:44 -08001226 0x12, 0xb9,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001227 0x15, 0xc9, // lock detector threshold
1228 0x16, 0x00,
1229 0x17, 0x00,
1230 0x18, 0x00,
1231 0x19, 0x00,
1232 0x1a, 0x00,
1233 0x1f, 0x50,
1234 0x20, 0x00,
1235 0x21, 0x00,
1236 0x22, 0x00,
1237 0x23, 0x00,
1238 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
1239 0x29, 0x1e, // 1/2 threshold
1240 0x2a, 0x14, // 2/3 threshold
1241 0x2b, 0x0f, // 3/4 threshold
1242 0x2c, 0x09, // 5/6 threshold
1243 0x2d, 0x05, // 7/8 threshold
1244 0x2e, 0x01,
1245 0x31, 0x1f, // test all FECs
1246 0x32, 0x19, // viterbi and synchro search
1247 0x33, 0xfc, // rs control
1248 0x34, 0x93, // error control
1249 0x0f, 0x52,
1250 0xff, 0xff
1251};
1252
1253static int alps_stv0299_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
1254{
1255 u8 aclk = 0;
1256 u8 bclk = 0;
1257
1258 if (srate < 1500000) {
1259 aclk = 0xb7;
1260 bclk = 0x47;
1261 } else if (srate < 3000000) {
1262 aclk = 0xb7;
1263 bclk = 0x4b;
1264 } else if (srate < 7000000) {
1265 aclk = 0xb7;
1266 bclk = 0x4f;
1267 } else if (srate < 14000000) {
1268 aclk = 0xb7;
1269 bclk = 0x53;
1270 } else if (srate < 30000000) {
1271 aclk = 0xb6;
1272 bclk = 0x53;
1273 } else if (srate < 45000000) {
1274 aclk = 0xb4;
1275 bclk = 0x51;
1276 }
1277
1278 stv0299_writereg(fe, 0x13, aclk);
1279 stv0299_writereg(fe, 0x14, bclk);
1280 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
1281 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
1282 stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
1283
1284 return 0;
1285}
1286
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001287static int philips_tsa5059_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001288{
1289 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1290 u8 buf[4];
1291 u32 div;
1292 struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
1293
1294 if ((params->frequency < 950000) || (params->frequency > 2150000))
1295 return -EINVAL;
1296
1297 div = (params->frequency + (125 - 1)) / 125; // round correctly
1298 buf[0] = (div >> 8) & 0x7f;
1299 buf[1] = div & 0xff;
1300 buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
1301 buf[3] = 0xC4;
1302
1303 if (params->frequency > 1530000)
1304 buf[3] = 0xC0;
1305
1306 /* BSBE1 wants XCE bit set */
1307 if (ttusb->revision == TTUSB_REV_2_2)
1308 buf[3] |= 0x20;
1309
Patrick Boettcherdea74862006-05-14 05:01:31 -03001310 if (fe->ops.i2c_gate_ctrl)
1311 fe->ops.i2c_gate_ctrl(fe, 1);
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001312 if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001313 return -EIO;
1314
1315 return 0;
1316}
1317
1318static struct stv0299_config alps_stv0299_config = {
1319 .demod_address = 0x68,
1320 .inittab = alps_bsru6_inittab,
1321 .mclk = 88000000UL,
1322 .invert = 1,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001323 .skip_reinit = 0,
Oliver Endrissda2c7f62008-04-20 22:13:37 -03001324 .lock_output = STV0299_LOCKOUTPUT_1,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001325 .volt13_op0_op1 = STV0299_VOLT13_OP1,
1326 .min_delay_ms = 100,
1327 .set_symbol_rate = alps_stv0299_set_symbol_rate,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001328};
1329
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001330static 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 -07001331{
1332 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1333 u8 buf[4];
1334 u32 div;
1335 struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
1336
Mauro Carvalho Chehab9101e622005-12-12 00:37:24 -08001337 div = params->frequency / 125;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001338
1339 buf[0] = (div >> 8) & 0x7f;
1340 buf[1] = div & 0xff;
1341 buf[2] = 0x8e;
1342 buf[3] = 0x00;
1343
Patrick Boettcherdea74862006-05-14 05:01:31 -03001344 if (fe->ops.i2c_gate_ctrl)
1345 fe->ops.i2c_gate_ctrl(fe, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001346 if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1)
1347 return -EIO;
1348
1349 return 0;
1350}
1351
1352static struct tda8083_config ttusb_novas_grundig_29504_491_config = {
1353
1354 .demod_address = 0x68,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001355};
1356
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001357static int alps_tdbe2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
Gavin Hamill53936392005-07-07 17:58:04 -07001358{
1359 struct ttusb* ttusb = fe->dvb->priv;
1360 u32 div;
1361 u8 data[4];
1362 struct i2c_msg msg = { .addr = 0x62, .flags = 0, .buf = data, .len = sizeof(data) };
1363
1364 div = (params->frequency + 35937500 + 31250) / 62500;
1365
1366 data[0] = (div >> 8) & 0x7f;
1367 data[1] = div & 0xff;
1368 data[2] = 0x85 | ((div >> 10) & 0x60);
1369 data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81);
1370
Patrick Boettcherdea74862006-05-14 05:01:31 -03001371 if (fe->ops.i2c_gate_ctrl)
1372 fe->ops.i2c_gate_ctrl(fe, 1);
Gavin Hamill53936392005-07-07 17:58:04 -07001373 if (i2c_transfer (&ttusb->i2c_adap, &msg, 1) != 1)
1374 return -EIO;
1375
1376 return 0;
1377}
1378
1379
1380static struct ves1820_config alps_tdbe2_config = {
1381 .demod_address = 0x09,
1382 .xin = 57840000UL,
1383 .invert = 1,
1384 .selagc = VES1820_SELAGC_SIGNAMPERR,
Gavin Hamill53936392005-07-07 17:58:04 -07001385};
1386
1387static u8 read_pwm(struct ttusb* ttusb)
1388{
1389 u8 b = 0xff;
1390 u8 pwm;
1391 struct i2c_msg msg[] = { { .addr = 0x50,.flags = 0,.buf = &b,.len = 1 },
1392 { .addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1} };
1393
1394 if ((i2c_transfer(&ttusb->i2c_adap, msg, 2) != 2) || (pwm == 0xff))
1395 pwm = 0x48;
1396
1397 return pwm;
1398}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001399
1400
Thomas Kaiserb8d4c232006-04-27 21:45:20 -03001401static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
1402{
1403 struct ttusb *ttusb = (struct ttusb *) fe->dvb->priv;
1404 u8 tuner_buf[5];
1405 struct i2c_msg tuner_msg = {.addr = 0x60,
1406 .flags = 0,
1407 .buf = tuner_buf,
1408 .len = sizeof(tuner_buf) };
1409 int tuner_frequency = 0;
1410 u8 band, cp, filter;
1411
1412 // determine charge pump
1413 tuner_frequency = params->frequency;
1414 if (tuner_frequency < 87000000) {return -EINVAL;}
1415 else if (tuner_frequency < 130000000) {cp = 3; band = 1;}
1416 else if (tuner_frequency < 160000000) {cp = 5; band = 1;}
1417 else if (tuner_frequency < 200000000) {cp = 6; band = 1;}
1418 else if (tuner_frequency < 290000000) {cp = 3; band = 2;}
1419 else if (tuner_frequency < 420000000) {cp = 5; band = 2;}
1420 else if (tuner_frequency < 480000000) {cp = 6; band = 2;}
1421 else if (tuner_frequency < 620000000) {cp = 3; band = 4;}
1422 else if (tuner_frequency < 830000000) {cp = 5; band = 4;}
1423 else if (tuner_frequency < 895000000) {cp = 7; band = 4;}
1424 else {return -EINVAL;}
1425
1426 // assume PLL filter should always be 8MHz for the moment.
1427 filter = 1;
1428
1429 // calculate divisor
1430 // (Finput + Fif)/Fref; Fif = 36125000 Hz, Fref = 62500 Hz
1431 tuner_frequency = ((params->frequency + 36125000) / 62500);
1432
1433 // setup tuner buffer
1434 tuner_buf[0] = tuner_frequency >> 8;
1435 tuner_buf[1] = tuner_frequency & 0xff;
1436 tuner_buf[2] = 0xc8;
1437 tuner_buf[3] = (cp << 5) | (filter << 3) | band;
1438 tuner_buf[4] = 0x80;
1439
Patrick Boettcherdea74862006-05-14 05:01:31 -03001440 if (fe->ops.i2c_gate_ctrl)
1441 fe->ops.i2c_gate_ctrl(fe, 1);
Thomas Kaiserb8d4c232006-04-27 21:45:20 -03001442 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) {
1443 printk("dvb-ttusb-budget: dvbc_philips_tdm1316l_pll_set Error 1\n");
1444 return -EIO;
1445 }
1446
1447 msleep(50);
1448
Patrick Boettcherdea74862006-05-14 05:01:31 -03001449 if (fe->ops.i2c_gate_ctrl)
1450 fe->ops.i2c_gate_ctrl(fe, 1);
Thomas Kaiserb8d4c232006-04-27 21:45:20 -03001451 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) {
1452 printk("dvb-ttusb-budget: dvbc_philips_tdm1316l_pll_set Error 2\n");
1453 return -EIO;
1454 }
1455
1456 msleep(1);
1457
1458 return 0;
1459}
1460
1461static u8 dvbc_philips_tdm1316l_inittab[] = {
1462 0x80, 0x21,
1463 0x80, 0x20,
1464 0x81, 0x01,
1465 0x81, 0x00,
1466 0x00, 0x09,
1467 0x01, 0x69,
1468 0x03, 0x00,
1469 0x04, 0x00,
1470 0x07, 0x00,
1471 0x08, 0x00,
1472 0x20, 0x00,
1473 0x21, 0x40,
1474 0x22, 0x00,
1475 0x23, 0x00,
1476 0x24, 0x40,
1477 0x25, 0x88,
1478 0x30, 0xff,
1479 0x31, 0x00,
1480 0x32, 0xff,
1481 0x33, 0x00,
1482 0x34, 0x50,
1483 0x35, 0x7f,
1484 0x36, 0x00,
1485 0x37, 0x20,
1486 0x38, 0x00,
1487 0x40, 0x1c,
1488 0x41, 0xff,
1489 0x42, 0x29,
1490 0x43, 0x20,
1491 0x44, 0xff,
1492 0x45, 0x00,
1493 0x46, 0x00,
1494 0x49, 0x04,
1495 0x4a, 0xff,
1496 0x4b, 0x7f,
1497 0x52, 0x30,
1498 0x55, 0xae,
1499 0x56, 0x47,
1500 0x57, 0xe1,
1501 0x58, 0x3a,
1502 0x5a, 0x1e,
1503 0x5b, 0x34,
1504 0x60, 0x00,
1505 0x63, 0x00,
1506 0x64, 0x00,
1507 0x65, 0x00,
1508 0x66, 0x00,
1509 0x67, 0x00,
1510 0x68, 0x00,
1511 0x69, 0x00,
1512 0x6a, 0x02,
1513 0x6b, 0x00,
1514 0x70, 0xff,
1515 0x71, 0x00,
1516 0x72, 0x00,
1517 0x73, 0x00,
1518 0x74, 0x0c,
1519 0x80, 0x00,
1520 0x81, 0x00,
1521 0x82, 0x00,
1522 0x83, 0x00,
1523 0x84, 0x04,
1524 0x85, 0x80,
1525 0x86, 0x24,
1526 0x87, 0x78,
1527 0x88, 0x00,
1528 0x89, 0x00,
1529 0x90, 0x01,
1530 0x91, 0x01,
1531 0xa0, 0x00,
1532 0xa1, 0x00,
1533 0xa2, 0x00,
1534 0xb0, 0x91,
1535 0xb1, 0x0b,
1536 0xc0, 0x4b,
1537 0xc1, 0x00,
1538 0xc2, 0x00,
1539 0xd0, 0x00,
1540 0xd1, 0x00,
1541 0xd2, 0x00,
1542 0xd3, 0x00,
1543 0xd4, 0x00,
1544 0xd5, 0x00,
1545 0xde, 0x00,
1546 0xdf, 0x00,
1547 0x61, 0x38,
1548 0x62, 0x0a,
1549 0x53, 0x13,
1550 0x59, 0x08,
1551 0x55, 0x00,
1552 0x56, 0x40,
1553 0x57, 0x08,
1554 0x58, 0x3d,
1555 0x88, 0x10,
1556 0xa0, 0x00,
1557 0xa0, 0x00,
1558 0xa0, 0x00,
1559 0xa0, 0x04,
1560 0xff, 0xff,
1561};
1562
1563static struct stv0297_config dvbc_philips_tdm1316l_config = {
1564 .demod_address = 0x1c,
1565 .inittab = dvbc_philips_tdm1316l_inittab,
1566 .invert = 0,
1567};
1568
Linus Torvalds1da177e2005-04-16 15:20:36 -07001569static void frontend_init(struct ttusb* ttusb)
1570{
1571 switch(le16_to_cpu(ttusb->dev->descriptor.idProduct)) {
1572 case 0x1003: // Hauppauge/TT Nova-USB-S budget (stv0299/ALPS BSRU6|BSBE1(tsa5059))
1573 // try the stv0299 based first
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001574 ttusb->fe = dvb_attach(stv0299_attach, &alps_stv0299_config, &ttusb->i2c_adap);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001575 if (ttusb->fe != NULL) {
Patrick Boettcherdea74862006-05-14 05:01:31 -03001576 ttusb->fe->ops.tuner_ops.set_params = philips_tsa5059_tuner_set_params;
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001577
Linus Torvalds1da177e2005-04-16 15:20:36 -07001578 if(ttusb->revision == TTUSB_REV_2_2) { // ALPS BSBE1
1579 alps_stv0299_config.inittab = alps_bsbe1_inittab;
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001580 dvb_attach(lnbp21_attach, ttusb->fe, &ttusb->i2c_adap, 0, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001581 } else { // ALPS BSRU6
Patrick Boettcherdea74862006-05-14 05:01:31 -03001582 ttusb->fe->ops.set_voltage = ttusb_set_voltage;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001583 }
1584 break;
1585 }
1586
1587 // Grundig 29504-491
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001588 ttusb->fe = dvb_attach(tda8083_attach, &ttusb_novas_grundig_29504_491_config, &ttusb->i2c_adap);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001589 if (ttusb->fe != NULL) {
Patrick Boettcherdea74862006-05-14 05:01:31 -03001590 ttusb->fe->ops.tuner_ops.set_params = ttusb_novas_grundig_29504_491_tuner_set_params;
1591 ttusb->fe->ops.set_voltage = ttusb_set_voltage;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001592 break;
1593 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001594 break;
1595
Gavin Hamill53936392005-07-07 17:58:04 -07001596 case 0x1004: // Hauppauge/TT DVB-C budget (ves1820/ALPS TDBE2(sp5659))
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001597 ttusb->fe = dvb_attach(ves1820_attach, &alps_tdbe2_config, &ttusb->i2c_adap, read_pwm(ttusb));
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001598 if (ttusb->fe != NULL) {
Patrick Boettcherdea74862006-05-14 05:01:31 -03001599 ttusb->fe->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params;
Gavin Hamill53936392005-07-07 17:58:04 -07001600 break;
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001601 }
Thomas Kaiserb8d4c232006-04-27 21:45:20 -03001602
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001603 ttusb->fe = dvb_attach(stv0297_attach, &dvbc_philips_tdm1316l_config, &ttusb->i2c_adap);
Thomas Kaiserb8d4c232006-04-27 21:45:20 -03001604 if (ttusb->fe != NULL) {
Patrick Boettcherdea74862006-05-14 05:01:31 -03001605 ttusb->fe->ops.tuner_ops.set_params = dvbc_philips_tdm1316l_tuner_set_params;
Thomas Kaiserb8d4c232006-04-27 21:45:20 -03001606 break;
1607 }
Gavin Hamill53936392005-07-07 17:58:04 -07001608 break;
1609
Linus Torvalds1da177e2005-04-16 15:20:36 -07001610 case 0x1005: // Hauppauge/TT Nova-USB-t budget (tda10046/Philips td1316(tda6651tt) OR cx22700/ALPS TDMB7(??))
1611 // try the ALPS TDMB7 first
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001612 ttusb->fe = dvb_attach(cx22700_attach, &alps_tdmb7_config, &ttusb->i2c_adap);
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001613 if (ttusb->fe != NULL) {
Patrick Boettcherdea74862006-05-14 05:01:31 -03001614 ttusb->fe->ops.tuner_ops.set_params = alps_tdmb7_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
1618 // Philips td1316
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001619 ttusb->fe = dvb_attach(tda10046_attach, &philips_tdm1316l_config, &ttusb->i2c_adap);
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001620 if (ttusb->fe != NULL) {
Patrick Boettcherdea74862006-05-14 05:01:31 -03001621 ttusb->fe->ops.tuner_ops.init = philips_tdm1316l_tuner_init;
1622 ttusb->fe->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001623 break;
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001624 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001625 break;
1626 }
1627
1628 if (ttusb->fe == NULL) {
1629 printk("dvb-ttusb-budget: A frontend driver was not found for device %04x/%04x\n",
1630 le16_to_cpu(ttusb->dev->descriptor.idVendor),
1631 le16_to_cpu(ttusb->dev->descriptor.idProduct));
1632 } else {
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001633 if (dvb_register_frontend(&ttusb->adapter, ttusb->fe)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001634 printk("dvb-ttusb-budget: Frontend registration failed!\n");
Andrew de Quinceyf52a8382006-08-08 09:10:09 -03001635 dvb_frontend_detach(ttusb->fe);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001636 ttusb->fe = NULL;
1637 }
1638 }
1639}
1640
1641
1642
1643static struct i2c_algorithm ttusb_dec_algo = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001644 .master_xfer = master_xfer,
1645 .functionality = functionality,
1646};
1647
1648static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *id)
1649{
1650 struct usb_device *udev;
1651 struct ttusb *ttusb;
1652 int result;
1653
Harvey Harrisonfb9393b2008-04-08 23:20:00 -03001654 dprintk("%s: TTUSB DVB connected\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001655
1656 udev = interface_to_usbdev(intf);
1657
Mauro Carvalho Chehab9101e622005-12-12 00:37:24 -08001658 if (intf->altsetting->desc.bInterfaceNumber != 1) return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001659
Panagiotis Issaris74081872006-01-11 19:40:56 -02001660 if (!(ttusb = kzalloc(sizeof(struct ttusb), GFP_KERNEL)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001661 return -ENOMEM;
1662
Linus Torvalds1da177e2005-04-16 15:20:36 -07001663 ttusb->dev = udev;
1664 ttusb->c = 0;
1665 ttusb->mux_state = 0;
Ingo Molnar3593cab2006-02-07 06:49:14 -02001666 mutex_init(&ttusb->semi2c);
1667
1668 mutex_lock(&ttusb->semi2c);
1669
1670 mutex_init(&ttusb->semusb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001671
1672 ttusb_setup_interfaces(ttusb);
1673
1674 ttusb_alloc_iso_urbs(ttusb);
1675 if (ttusb_init_controller(ttusb))
1676 printk("ttusb_init_controller: error\n");
1677
Ingo Molnar3593cab2006-02-07 06:49:14 -02001678 mutex_unlock(&ttusb->semi2c);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001679
Janne Grunau78e920062008-04-09 19:13:13 -03001680 result = dvb_register_adapter(&ttusb->adapter,
1681 "Technotrend/Hauppauge Nova-USB",
1682 THIS_MODULE, &udev->dev, adapter_nr);
1683 if (result < 0) {
Andrew de Quinceya064fad2006-04-06 17:05:46 -03001684 ttusb_free_iso_urbs(ttusb);
1685 kfree(ttusb);
1686 return result;
1687 }
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001688 ttusb->adapter.priv = ttusb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001689
1690 /* i2c */
1691 memset(&ttusb->i2c_adap, 0, sizeof(struct i2c_adapter));
1692 strcpy(ttusb->i2c_adap.name, "TTUSB DEC");
1693
1694 i2c_set_adapdata(&ttusb->i2c_adap, ttusb);
1695
1696#ifdef I2C_ADAP_CLASS_TV_DIGITAL
1697 ttusb->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL;
1698#else
1699 ttusb->i2c_adap.class = I2C_CLASS_TV_DIGITAL;
1700#endif
1701 ttusb->i2c_adap.algo = &ttusb_dec_algo;
1702 ttusb->i2c_adap.algo_data = NULL;
Jean Delvare12a917f2007-02-13 22:09:03 +01001703 ttusb->i2c_adap.dev.parent = &udev->dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001704
1705 result = i2c_add_adapter(&ttusb->i2c_adap);
1706 if (result) {
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001707 dvb_unregister_adapter (&ttusb->adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001708 return result;
1709 }
1710
1711 memset(&ttusb->dvb_demux, 0, sizeof(ttusb->dvb_demux));
1712
1713 ttusb->dvb_demux.dmx.capabilities =
1714 DMX_TS_FILTERING | DMX_SECTION_FILTERING;
1715 ttusb->dvb_demux.priv = NULL;
1716#ifdef TTUSB_HWSECTIONS
1717 ttusb->dvb_demux.filternum = TTUSB_MAXFILTER;
1718#else
1719 ttusb->dvb_demux.filternum = 32;
1720#endif
1721 ttusb->dvb_demux.feednum = TTUSB_MAXCHANNEL;
1722 ttusb->dvb_demux.start_feed = ttusb_start_feed;
1723 ttusb->dvb_demux.stop_feed = ttusb_stop_feed;
1724 ttusb->dvb_demux.write_to_decoder = NULL;
1725
1726 if ((result = dvb_dmx_init(&ttusb->dvb_demux)) < 0) {
1727 printk("ttusb_dvb: dvb_dmx_init failed (errno = %d)\n", result);
1728 i2c_del_adapter(&ttusb->i2c_adap);
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001729 dvb_unregister_adapter (&ttusb->adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001730 return -ENODEV;
1731 }
1732//FIXME dmxdev (nur WAS?)
1733 ttusb->dmxdev.filternum = ttusb->dvb_demux.filternum;
1734 ttusb->dmxdev.demux = &ttusb->dvb_demux.dmx;
1735 ttusb->dmxdev.capabilities = 0;
1736
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001737 if ((result = dvb_dmxdev_init(&ttusb->dmxdev, &ttusb->adapter)) < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001738 printk("ttusb_dvb: dvb_dmxdev_init failed (errno = %d)\n",
1739 result);
1740 dvb_dmx_release(&ttusb->dvb_demux);
1741 i2c_del_adapter(&ttusb->i2c_adap);
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001742 dvb_unregister_adapter (&ttusb->adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001743 return -ENODEV;
1744 }
1745
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001746 if (dvb_net_init(&ttusb->adapter, &ttusb->dvbnet, &ttusb->dvb_demux.dmx)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001747 printk("ttusb_dvb: dvb_net_init failed!\n");
1748 dvb_dmxdev_release(&ttusb->dmxdev);
1749 dvb_dmx_release(&ttusb->dvb_demux);
1750 i2c_del_adapter(&ttusb->i2c_adap);
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001751 dvb_unregister_adapter (&ttusb->adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001752 return -ENODEV;
1753 }
1754
Linus Torvalds1da177e2005-04-16 15:20:36 -07001755 usb_set_intfdata(intf, (void *) ttusb);
1756
1757 frontend_init(ttusb);
1758
1759 return 0;
1760}
1761
1762static void ttusb_disconnect(struct usb_interface *intf)
1763{
1764 struct ttusb *ttusb = usb_get_intfdata(intf);
1765
1766 usb_set_intfdata(intf, NULL);
1767
1768 ttusb->disconnecting = 1;
1769
1770 ttusb_stop_iso_xfer(ttusb);
1771
1772 ttusb->dvb_demux.dmx.close(&ttusb->dvb_demux.dmx);
1773 dvb_net_release(&ttusb->dvbnet);
1774 dvb_dmxdev_release(&ttusb->dmxdev);
1775 dvb_dmx_release(&ttusb->dvb_demux);
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001776 if (ttusb->fe != NULL) {
1777 dvb_unregister_frontend(ttusb->fe);
Andrew de Quinceyf52a8382006-08-08 09:10:09 -03001778 dvb_frontend_detach(ttusb->fe);
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001779 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001780 i2c_del_adapter(&ttusb->i2c_adap);
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001781 dvb_unregister_adapter(&ttusb->adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001782
1783 ttusb_free_iso_urbs(ttusb);
1784
1785 kfree(ttusb);
1786
Harvey Harrisonfb9393b2008-04-08 23:20:00 -03001787 dprintk("%s: TTUSB DVB disconnected\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001788}
1789
1790static struct usb_device_id ttusb_table[] = {
1791 {USB_DEVICE(0xb48, 0x1003)},
Gavin Hamill53936392005-07-07 17:58:04 -07001792 {USB_DEVICE(0xb48, 0x1004)},
Linus Torvalds1da177e2005-04-16 15:20:36 -07001793 {USB_DEVICE(0xb48, 0x1005)},
1794 {}
1795};
1796
1797MODULE_DEVICE_TABLE(usb, ttusb_table);
1798
1799static struct usb_driver ttusb_driver = {
Julian Scheel27b05fd2005-07-12 13:58:39 -07001800 .name = "ttusb",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001801 .probe = ttusb_probe,
1802 .disconnect = ttusb_disconnect,
1803 .id_table = ttusb_table,
1804};
1805
1806static int __init ttusb_init(void)
1807{
1808 int err;
1809
1810 if ((err = usb_register(&ttusb_driver)) < 0) {
1811 printk("%s: usb_register failed! Error number %d",
1812 __FILE__, err);
1813 return err;
1814 }
1815
1816 return 0;
1817}
1818
1819static void __exit ttusb_exit(void)
1820{
1821 usb_deregister(&ttusb_driver);
1822}
1823
1824module_init(ttusb_init);
1825module_exit(ttusb_exit);
1826
1827MODULE_AUTHOR("Holger Waechtler <holger@convergence.de>");
1828MODULE_DESCRIPTION("TTUSB DVB Driver");
1829MODULE_LICENSE("GPL");
David Woodhouse0a2a7362008-05-29 19:50:06 +03001830MODULE_FIRMWARE("ttusb-budget/dspbootcode.bin");