blob: cbe2f0de1442f11f8b5f2ccb0efe3fdec10bf027 [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:
Jesper Juhlba0fd562011-02-06 17:49:02 -0300337 release_firmware(fw);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700338 if (err) {
339 dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300340 __func__, err);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700341 }
342
343 return err;
344}
345
346static int ttusb_set_channel(struct ttusb *ttusb, int chan_id, int filter_type,
347 int pid)
348{
349 int err;
350 /* SetChannel */
351 u8 b[] = { 0xaa, ++ttusb->c, 0x22, 4, chan_id, filter_type,
352 (pid >> 8) & 0xff, pid & 0xff
353 };
354
355 err = ttusb_cmd(ttusb, b, sizeof(b), 0);
356 return err;
357}
358
359static int ttusb_del_channel(struct ttusb *ttusb, int channel_id)
360{
361 int err;
362 /* DelChannel */
363 u8 b[] = { 0xaa, ++ttusb->c, 0x23, 1, channel_id };
364
365 err = ttusb_cmd(ttusb, b, sizeof(b), 0);
366 return err;
367}
368
369#ifdef TTUSB_HWSECTIONS
370static int ttusb_set_filter(struct ttusb *ttusb, int filter_id,
371 int associated_chan, u8 filter[8], u8 mask[8])
372{
373 int err;
374 /* SetFilter */
375 u8 b[] = { 0xaa, 0, 0x24, 0x1a, filter_id, associated_chan,
376 filter[0], filter[1], filter[2], filter[3],
377 filter[4], filter[5], filter[6], filter[7],
378 filter[8], filter[9], filter[10], filter[11],
379 mask[0], mask[1], mask[2], mask[3],
380 mask[4], mask[5], mask[6], mask[7],
381 mask[8], mask[9], mask[10], mask[11]
382 };
383
384 err = ttusb_cmd(ttusb, b, sizeof(b), 0);
385 return err;
386}
387
388static int ttusb_del_filter(struct ttusb *ttusb, int filter_id)
389{
390 int err;
391 /* DelFilter */
392 u8 b[] = { 0xaa, ++ttusb->c, 0x25, 1, filter_id };
393
394 err = ttusb_cmd(ttusb, b, sizeof(b), 0);
395 return err;
396}
397#endif
398
399static int ttusb_init_controller(struct ttusb *ttusb)
400{
401 u8 b0[] = { 0xaa, ++ttusb->c, 0x15, 1, 0 };
402 u8 b1[] = { 0xaa, ++ttusb->c, 0x15, 1, 1 };
403 u8 b2[] = { 0xaa, ++ttusb->c, 0x32, 1, 0 };
404 /* i2c write read: 5 bytes, addr 0x10, 0x02 bytes write, 1 bytes read. */
405 u8 b3[] =
406 { 0xaa, ++ttusb->c, 0x31, 5, 0x10, 0x02, 0x01, 0x00, 0x1e };
407 u8 b4[] =
408 { 0x55, ttusb->c, 0x31, 4, 0x10, 0x02, 0x01, 0x00, 0x1e };
409
410 u8 get_version[] = { 0xaa, ++ttusb->c, 0x17, 5, 0, 0, 0, 0, 0 };
411 u8 get_dsp_version[0x20] =
412 { 0xaa, ++ttusb->c, 0x26, 28, 0, 0, 0, 0, 0 };
413 int err;
414
415 /* reset board */
416 if ((err = ttusb_cmd(ttusb, b0, sizeof(b0), 0)))
417 return err;
418
419 /* reset board (again?) */
420 if ((err = ttusb_cmd(ttusb, b1, sizeof(b1), 0)))
421 return err;
422
423 ttusb_boot_dsp(ttusb);
424
425 /* set i2c bit rate */
426 if ((err = ttusb_cmd(ttusb, b2, sizeof(b2), 0)))
427 return err;
428
429 if ((err = ttusb_cmd(ttusb, b3, sizeof(b3), 1)))
430 return err;
431
432 err = ttusb_result(ttusb, b4, sizeof(b4));
433
434 if ((err = ttusb_cmd(ttusb, get_version, sizeof(get_version), 1)))
435 return err;
436
437 if ((err = ttusb_result(ttusb, get_version, sizeof(get_version))))
438 return err;
439
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300440 dprintk("%s: stc-version: %c%c%c%c%c\n", __func__,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700441 get_version[4], get_version[5], get_version[6],
442 get_version[7], get_version[8]);
443
444 if (memcmp(get_version + 4, "V 0.0", 5) &&
445 memcmp(get_version + 4, "V 1.1", 5) &&
446 memcmp(get_version + 4, "V 2.1", 5) &&
447 memcmp(get_version + 4, "V 2.2", 5)) {
448 printk
449 ("%s: unknown STC version %c%c%c%c%c, please report!\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300450 __func__, get_version[4], get_version[5],
Linus Torvalds1da177e2005-04-16 15:20:36 -0700451 get_version[6], get_version[7], get_version[8]);
452 }
453
454 ttusb->revision = ((get_version[6] - '0') << 4) |
455 (get_version[8] - '0');
456
457 err =
458 ttusb_cmd(ttusb, get_dsp_version, sizeof(get_dsp_version), 1);
459 if (err)
460 return err;
461
462 err =
463 ttusb_result(ttusb, get_dsp_version, sizeof(get_dsp_version));
464 if (err)
465 return err;
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300466 printk("%s: dsp-version: %c%c%c\n", __func__,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700467 get_dsp_version[4], get_dsp_version[5], get_dsp_version[6]);
468 return 0;
469}
470
471#ifdef TTUSB_DISEQC
472static int ttusb_send_diseqc(struct dvb_frontend* fe,
473 const struct dvb_diseqc_master_cmd *cmd)
474{
475 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
476 u8 b[12] = { 0xaa, ++ttusb->c, 0x18 };
477
478 int err;
479
480 b[3] = 4 + 2 + cmd->msg_len;
481 b[4] = 0xFF; /* send diseqc master, not burst */
482 b[5] = cmd->msg_len;
483
484 memcpy(b + 5, cmd->msg, cmd->msg_len);
485
486 /* Diseqc */
487 if ((err = ttusb_cmd(ttusb, b, 4 + b[3], 0))) {
488 dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300489 __func__, err);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700490 }
491
492 return err;
493}
494#endif
495
Linus Torvalds1da177e2005-04-16 15:20:36 -0700496static int ttusb_update_lnb(struct ttusb *ttusb)
497{
498 u8 b[] = { 0xaa, ++ttusb->c, 0x16, 5, /*power: */ 1,
499 ttusb->voltage == SEC_VOLTAGE_18 ? 0 : 1,
500 ttusb->tone == SEC_TONE_ON ? 1 : 0, 1, 1
501 };
502 int err;
503
504 /* SetLNB */
505 if ((err = ttusb_cmd(ttusb, b, sizeof(b), 0))) {
506 dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300507 __func__, err);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700508 }
509
510 return err;
511}
512
513static int ttusb_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
514{
515 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
516
517 ttusb->voltage = voltage;
518 return ttusb_update_lnb(ttusb);
519}
520
521#ifdef TTUSB_TONE
522static int ttusb_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
523{
524 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
525
526 ttusb->tone = tone;
527 return ttusb_update_lnb(ttusb);
528}
529#endif
530
531
532#if 0
533static void ttusb_set_led_freq(struct ttusb *ttusb, u8 freq)
534{
535 u8 b[] = { 0xaa, ++ttusb->c, 0x19, 1, freq };
536 int err, actual_len;
537
538 err = ttusb_cmd(ttusb, b, sizeof(b), 0);
539 if (err) {
540 dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300541 __func__, err);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700542 }
543}
544#endif
545
546/*****************************************************************************/
547
548#ifdef TTUSB_HWSECTIONS
549static void ttusb_handle_ts_data(struct ttusb_channel *channel,
550 const u8 * data, int len);
551static void ttusb_handle_sec_data(struct ttusb_channel *channel,
552 const u8 * data, int len);
553#endif
554
Douglas Schilling Landgrafff699e62008-04-22 14:41:48 -0300555static int numpkt, numts, numstuff, numsec, numinvalid;
Marcelo Feitoza Parisi4da006c2005-09-09 13:03:15 -0700556static unsigned long lastj;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700557
558static void ttusb_process_muxpack(struct ttusb *ttusb, const u8 * muxpack,
559 int len)
560{
561 u16 csum = 0, cc;
562 int i;
563 for (i = 0; i < len; i += 2)
Al Virod4f979a2008-05-21 00:31:31 -0300564 csum ^= le16_to_cpup((__le16 *) (muxpack + i));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700565 if (csum) {
566 printk("%s: muxpack with incorrect checksum, ignoring\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300567 __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700568 numinvalid++;
569 return;
570 }
571
572 cc = (muxpack[len - 4] << 8) | muxpack[len - 3];
573 cc &= 0x7FFF;
574 if ((cc != ttusb->cc) && (ttusb->cc != -1))
575 printk("%s: cc discontinuity (%d frames missing)\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300576 __func__, (cc - ttusb->cc) & 0x7FFF);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700577 ttusb->cc = (cc + 1) & 0x7FFF;
578 if (muxpack[0] & 0x80) {
579#ifdef TTUSB_HWSECTIONS
580 /* section data */
581 int pusi = muxpack[0] & 0x40;
582 int channel = muxpack[0] & 0x1F;
583 int payload = muxpack[1];
584 const u8 *data = muxpack + 2;
585 /* check offset flag */
586 if (muxpack[0] & 0x20)
587 data++;
588
589 ttusb_handle_sec_data(ttusb->channel + channel, data,
590 payload);
591 data += payload;
592
593 if ((!!(ttusb->muxpack[0] & 0x20)) ^
594 !!(ttusb->muxpack[1] & 1))
595 data++;
596#warning TODO: pusi
597 printk("cc: %04x\n", (data[0] << 8) | data[1]);
598#endif
599 numsec++;
600 } else if (muxpack[0] == 0x47) {
601#ifdef TTUSB_HWSECTIONS
602 /* we have TS data here! */
603 int pid = ((muxpack[1] & 0x0F) << 8) | muxpack[2];
604 int channel;
605 for (channel = 0; channel < TTUSB_MAXCHANNEL; ++channel)
606 if (ttusb->channel[channel].active
607 && (pid == ttusb->channel[channel].pid))
608 ttusb_handle_ts_data(ttusb->channel +
609 channel, muxpack,
610 188);
611#endif
612 numts++;
613 dvb_dmx_swfilter_packets(&ttusb->dvb_demux, muxpack, 1);
614 } else if (muxpack[0] != 0) {
615 numinvalid++;
616 printk("illegal muxpack type %02x\n", muxpack[0]);
617 } else
618 numstuff++;
619}
620
621static void ttusb_process_frame(struct ttusb *ttusb, u8 * data, int len)
622{
623 int maxwork = 1024;
624 while (len) {
625 if (!(maxwork--)) {
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300626 printk("%s: too much work\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700627 break;
628 }
629
630 switch (ttusb->mux_state) {
631 case 0:
632 case 1:
633 case 2:
634 len--;
635 if (*data++ == 0xAA)
636 ++ttusb->mux_state;
637 else {
638 ttusb->mux_state = 0;
639#if DEBUG > 3
640 if (ttusb->insync)
641 printk("%02x ", data[-1]);
642#else
643 if (ttusb->insync) {
644 printk("%s: lost sync.\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300645 __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700646 ttusb->insync = 0;
647 }
648#endif
649 }
650 break;
651 case 3:
652 ttusb->insync = 1;
653 len--;
654 ttusb->mux_npacks = *data++;
655 ++ttusb->mux_state;
656 ttusb->muxpack_ptr = 0;
657 /* maximum bytes, until we know the length */
658 ttusb->muxpack_len = 2;
659 break;
660 case 4:
661 {
662 int avail;
663 avail = len;
664 if (avail >
665 (ttusb->muxpack_len -
666 ttusb->muxpack_ptr))
667 avail =
668 ttusb->muxpack_len -
669 ttusb->muxpack_ptr;
670 memcpy(ttusb->muxpack + ttusb->muxpack_ptr,
671 data, avail);
672 ttusb->muxpack_ptr += avail;
Eric Sesterhennae246012006-03-13 13:17:11 -0300673 BUG_ON(ttusb->muxpack_ptr > 264);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700674 data += avail;
675 len -= avail;
676 /* determine length */
677 if (ttusb->muxpack_ptr == 2) {
678 if (ttusb->muxpack[0] & 0x80) {
679 ttusb->muxpack_len =
680 ttusb->muxpack[1] + 2;
681 if (ttusb->
682 muxpack[0] & 0x20)
683 ttusb->
684 muxpack_len++;
685 if ((!!
686 (ttusb->
687 muxpack[0] & 0x20)) ^
688 !!(ttusb->
689 muxpack[1] & 1))
690 ttusb->
691 muxpack_len++;
692 ttusb->muxpack_len += 4;
693 } else if (ttusb->muxpack[0] ==
694 0x47)
695 ttusb->muxpack_len =
696 188 + 4;
697 else if (ttusb->muxpack[0] == 0x00)
698 ttusb->muxpack_len =
699 ttusb->muxpack[1] + 2 +
700 4;
701 else {
702 dprintk
703 ("%s: invalid state: first byte is %x\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300704 __func__,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700705 ttusb->muxpack[0]);
706 ttusb->mux_state = 0;
707 }
708 }
709
710 /**
711 * if length is valid and we reached the end:
712 * goto next muxpack
713 */
714 if ((ttusb->muxpack_ptr >= 2) &&
715 (ttusb->muxpack_ptr ==
716 ttusb->muxpack_len)) {
717 ttusb_process_muxpack(ttusb,
718 ttusb->
719 muxpack,
720 ttusb->
721 muxpack_ptr);
722 ttusb->muxpack_ptr = 0;
723 /* maximum bytes, until we know the length */
724 ttusb->muxpack_len = 2;
725
726 /**
727 * no muxpacks left?
728 * return to search-sync state
729 */
730 if (!ttusb->mux_npacks--) {
731 ttusb->mux_state = 0;
732 break;
733 }
734 }
735 break;
736 }
737 default:
738 BUG();
739 break;
740 }
741 }
742}
743
David Howells7d12e782006-10-05 14:55:46 +0100744static void ttusb_iso_irq(struct urb *urb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700745{
746 struct ttusb *ttusb = urb->context;
747
748 if (!ttusb->iso_streaming)
749 return;
750
751#if 0
752 printk("%s: status %d, errcount == %d, length == %i\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300753 __func__,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700754 urb->status, urb->error_count, urb->actual_length);
755#endif
756
757 if (!urb->status) {
758 int i;
759 for (i = 0; i < urb->number_of_packets; ++i) {
760 struct usb_iso_packet_descriptor *d;
761 u8 *data;
762 int len;
763 numpkt++;
Marcelo Feitoza Parisi4da006c2005-09-09 13:03:15 -0700764 if (time_after_eq(jiffies, lastj + HZ)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700765#if DEBUG > 2
766 printk
767 ("frames/s: %d (ts: %d, stuff %d, sec: %d, invalid: %d, all: %d)\n",
768 numpkt * HZ / (jiffies - lastj),
769 numts, numstuff, numsec, numinvalid,
770 numts + numstuff + numsec +
771 numinvalid);
772#endif
773 numts = numstuff = numsec = numinvalid = 0;
774 lastj = jiffies;
775 numpkt = 0;
776 }
777 d = &urb->iso_frame_desc[i];
778 data = urb->transfer_buffer + d->offset;
779 len = d->actual_length;
780 d->actual_length = 0;
781 d->status = 0;
782 ttusb_process_frame(ttusb, data, len);
783 }
784 }
785 usb_submit_urb(urb, GFP_ATOMIC);
786}
787
788static void ttusb_free_iso_urbs(struct ttusb *ttusb)
789{
790 int i;
791
792 for (i = 0; i < ISO_BUF_COUNT; i++)
793 if (ttusb->iso_urb[i])
794 usb_free_urb(ttusb->iso_urb[i]);
795
796 pci_free_consistent(NULL,
797 ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF *
798 ISO_BUF_COUNT, ttusb->iso_buffer,
799 ttusb->iso_dma_handle);
800}
801
802static int ttusb_alloc_iso_urbs(struct ttusb *ttusb)
803{
804 int i;
805
806 ttusb->iso_buffer = pci_alloc_consistent(NULL,
807 ISO_FRAME_SIZE *
808 FRAMES_PER_ISO_BUF *
809 ISO_BUF_COUNT,
810 &ttusb->iso_dma_handle);
811
Douglas Schilling Landgraf11eb2602008-11-11 23:30:49 -0300812 if (!ttusb->iso_buffer) {
813 dprintk("%s: pci_alloc_consistent - not enough memory\n",
814 __func__);
815 return -ENOMEM;
816 }
817
Linus Torvalds1da177e2005-04-16 15:20:36 -0700818 memset(ttusb->iso_buffer, 0,
819 ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF * ISO_BUF_COUNT);
820
821 for (i = 0; i < ISO_BUF_COUNT; i++) {
822 struct urb *urb;
823
824 if (!
825 (urb =
826 usb_alloc_urb(FRAMES_PER_ISO_BUF, GFP_ATOMIC))) {
827 ttusb_free_iso_urbs(ttusb);
828 return -ENOMEM;
829 }
830
831 ttusb->iso_urb[i] = urb;
832 }
833
834 return 0;
835}
836
837static void ttusb_stop_iso_xfer(struct ttusb *ttusb)
838{
839 int i;
840
841 for (i = 0; i < ISO_BUF_COUNT; i++)
842 usb_kill_urb(ttusb->iso_urb[i]);
843
844 ttusb->iso_streaming = 0;
845}
846
847static int ttusb_start_iso_xfer(struct ttusb *ttusb)
848{
849 int i, j, err, buffer_offset = 0;
850
851 if (ttusb->iso_streaming) {
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300852 printk("%s: iso xfer already running!\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700853 return 0;
854 }
855
856 ttusb->cc = -1;
857 ttusb->insync = 0;
858 ttusb->mux_state = 0;
859
860 for (i = 0; i < ISO_BUF_COUNT; i++) {
861 int frame_offset = 0;
862 struct urb *urb = ttusb->iso_urb[i];
863
864 urb->dev = ttusb->dev;
865 urb->context = ttusb;
866 urb->complete = ttusb_iso_irq;
867 urb->pipe = ttusb->isoc_in_pipe;
868 urb->transfer_flags = URB_ISO_ASAP;
869 urb->interval = 1;
870 urb->number_of_packets = FRAMES_PER_ISO_BUF;
871 urb->transfer_buffer_length =
872 ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF;
873 urb->transfer_buffer = ttusb->iso_buffer + buffer_offset;
874 buffer_offset += ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF;
875
876 for (j = 0; j < FRAMES_PER_ISO_BUF; j++) {
877 urb->iso_frame_desc[j].offset = frame_offset;
878 urb->iso_frame_desc[j].length = ISO_FRAME_SIZE;
879 frame_offset += ISO_FRAME_SIZE;
880 }
881 }
882
883 for (i = 0; i < ISO_BUF_COUNT; i++) {
884 if ((err = usb_submit_urb(ttusb->iso_urb[i], GFP_ATOMIC))) {
885 ttusb_stop_iso_xfer(ttusb);
886 printk
887 ("%s: failed urb submission (%i: err = %i)!\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300888 __func__, i, err);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700889 return err;
890 }
891 }
892
893 ttusb->iso_streaming = 1;
894
895 return 0;
896}
897
898#ifdef TTUSB_HWSECTIONS
899static void ttusb_handle_ts_data(struct dvb_demux_feed *dvbdmxfeed, const u8 * data,
900 int len)
901{
902 dvbdmxfeed->cb.ts(data, len, 0, 0, &dvbdmxfeed->feed.ts, 0);
903}
904
905static void ttusb_handle_sec_data(struct dvb_demux_feed *dvbdmxfeed, const u8 * data,
906 int len)
907{
908// struct dvb_demux_feed *dvbdmxfeed = channel->dvbdmxfeed;
909#error TODO: handle ugly stuff
910// dvbdmxfeed->cb.sec(data, len, 0, 0, &dvbdmxfeed->feed.sec, 0);
911}
912#endif
913
914static int ttusb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
915{
916 struct ttusb *ttusb = (struct ttusb *) dvbdmxfeed->demux;
917 int feed_type = 1;
918
919 dprintk("ttusb_start_feed\n");
920
921 switch (dvbdmxfeed->type) {
922 case DMX_TYPE_TS:
923 break;
924 case DMX_TYPE_SEC:
925 break;
926 default:
927 return -EINVAL;
928 }
929
930 if (dvbdmxfeed->type == DMX_TYPE_TS) {
931 switch (dvbdmxfeed->pes_type) {
932 case DMX_TS_PES_VIDEO:
933 case DMX_TS_PES_AUDIO:
934 case DMX_TS_PES_TELETEXT:
935 case DMX_TS_PES_PCR:
936 case DMX_TS_PES_OTHER:
937 break;
938 default:
939 return -EINVAL;
940 }
941 }
942
943#ifdef TTUSB_HWSECTIONS
944#error TODO: allocate filters
945 if (dvbdmxfeed->type == DMX_TYPE_TS) {
946 feed_type = 1;
947 } else if (dvbdmxfeed->type == DMX_TYPE_SEC) {
948 feed_type = 2;
949 }
950#endif
951
952 ttusb_set_channel(ttusb, dvbdmxfeed->index, feed_type, dvbdmxfeed->pid);
953
954 if (0 == ttusb->running_feed_count++)
955 ttusb_start_iso_xfer(ttusb);
956
957 return 0;
958}
959
960static int ttusb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
961{
962 struct ttusb *ttusb = (struct ttusb *) dvbdmxfeed->demux;
963
964 ttusb_del_channel(ttusb, dvbdmxfeed->index);
965
966 if (--ttusb->running_feed_count == 0)
967 ttusb_stop_iso_xfer(ttusb);
968
969 return 0;
970}
971
972static int ttusb_setup_interfaces(struct ttusb *ttusb)
973{
974 usb_set_interface(ttusb->dev, 1, 1);
975
976 ttusb->bulk_out_pipe = usb_sndbulkpipe(ttusb->dev, 1);
977 ttusb->bulk_in_pipe = usb_rcvbulkpipe(ttusb->dev, 1);
978 ttusb->isoc_in_pipe = usb_rcvisocpipe(ttusb->dev, 2);
979
980 return 0;
981}
982
983#if 0
984static u8 stc_firmware[8192];
985
986static int stc_open(struct inode *inode, struct file *file)
987{
988 struct ttusb *ttusb = file->private_data;
989 int addr;
990
991 for (addr = 0; addr < 8192; addr += 16) {
992 u8 snd_buf[2] = { addr >> 8, addr & 0xFF };
993 ttusb_i2c_msg(ttusb, 0x50, snd_buf, 2, stc_firmware + addr,
994 16);
995 }
996
997 return 0;
998}
999
1000static ssize_t stc_read(struct file *file, char *buf, size_t count,
Akinobu Mitaa8a89b72008-07-04 06:33:20 -03001001 loff_t *offset)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001002{
Akinobu Mitaa8a89b72008-07-04 06:33:20 -03001003 return simple_read_from_buffer(buf, count, offset, stc_firmware, 8192);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001004}
1005
1006static int stc_release(struct inode *inode, struct file *file)
1007{
1008 return 0;
1009}
1010
Jan Engelhardt27a643b2008-04-22 14:42:01 -03001011static const struct file_operations stc_fops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001012 .owner = THIS_MODULE,
1013 .read = stc_read,
1014 .open = stc_open,
1015 .release = stc_release,
1016};
1017#endif
1018
1019static u32 functionality(struct i2c_adapter *adapter)
1020{
1021 return I2C_FUNC_I2C;
1022}
1023
1024
1025
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001026static int alps_tdmb7_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001027{
1028 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1029 u8 data[4];
1030 struct i2c_msg msg = {.addr=0x61, .flags=0, .buf=data, .len=sizeof(data) };
1031 u32 div;
1032
1033 div = (params->frequency + 36166667) / 166667;
1034
1035 data[0] = (div >> 8) & 0x7f;
1036 data[1] = div & 0xff;
1037 data[2] = ((div >> 10) & 0x60) | 0x85;
1038 data[3] = params->frequency < 592000000 ? 0x40 : 0x80;
1039
Patrick Boettcherdea74862006-05-14 05:01:31 -03001040 if (fe->ops.i2c_gate_ctrl)
1041 fe->ops.i2c_gate_ctrl(fe, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001042 if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1) return -EIO;
1043 return 0;
1044}
1045
Johannes Stezenbachd91b7302005-05-16 21:54:38 -07001046static struct cx22700_config alps_tdmb7_config = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001047 .demod_address = 0x43,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001048};
1049
1050
1051
1052
1053
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001054static int philips_tdm1316l_tuner_init(struct dvb_frontend* fe)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001055{
1056 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1057 static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab };
1058 static u8 disable_mc44BC374c[] = { 0x1d, 0x74, 0xa0, 0x68 };
1059 struct i2c_msg tuner_msg = { .addr=0x60, .flags=0, .buf=td1316_init, .len=sizeof(td1316_init) };
1060
1061 // setup PLL configuration
Patrick Boettcherdea74862006-05-14 05:01:31 -03001062 if (fe->ops.i2c_gate_ctrl)
1063 fe->ops.i2c_gate_ctrl(fe, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001064 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) return -EIO;
1065 msleep(1);
1066
1067 // disable the mc44BC374c (do not check for errors)
1068 tuner_msg.addr = 0x65;
1069 tuner_msg.buf = disable_mc44BC374c;
1070 tuner_msg.len = sizeof(disable_mc44BC374c);
Patrick Boettcherdea74862006-05-14 05:01:31 -03001071 if (fe->ops.i2c_gate_ctrl)
1072 fe->ops.i2c_gate_ctrl(fe, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001073 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) {
1074 i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1);
1075 }
1076
1077 return 0;
1078}
1079
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001080static int philips_tdm1316l_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001081{
1082 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1083 u8 tuner_buf[4];
1084 struct i2c_msg tuner_msg = {.addr=0x60, .flags=0, .buf=tuner_buf, .len=sizeof(tuner_buf) };
1085 int tuner_frequency = 0;
1086 u8 band, cp, filter;
1087
1088 // determine charge pump
1089 tuner_frequency = params->frequency + 36130000;
1090 if (tuner_frequency < 87000000) return -EINVAL;
1091 else if (tuner_frequency < 130000000) cp = 3;
1092 else if (tuner_frequency < 160000000) cp = 5;
1093 else if (tuner_frequency < 200000000) cp = 6;
1094 else if (tuner_frequency < 290000000) cp = 3;
1095 else if (tuner_frequency < 420000000) cp = 5;
1096 else if (tuner_frequency < 480000000) cp = 6;
1097 else if (tuner_frequency < 620000000) cp = 3;
1098 else if (tuner_frequency < 830000000) cp = 5;
1099 else if (tuner_frequency < 895000000) cp = 7;
1100 else return -EINVAL;
1101
1102 // determine band
1103 if (params->frequency < 49000000) return -EINVAL;
1104 else if (params->frequency < 159000000) band = 1;
1105 else if (params->frequency < 444000000) band = 2;
1106 else if (params->frequency < 861000000) band = 4;
1107 else return -EINVAL;
1108
1109 // setup PLL filter
1110 switch (params->u.ofdm.bandwidth) {
1111 case BANDWIDTH_6_MHZ:
Andrew de Quinceyc10d14d2006-08-08 09:10:08 -03001112 tda1004x_writereg(fe, 0x0C, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001113 filter = 0;
1114 break;
1115
1116 case BANDWIDTH_7_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_8_MHZ:
Andrew de Quinceyc10d14d2006-08-08 09:10:08 -03001122 tda1004x_writereg(fe, 0x0C, 0xFF);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001123 filter = 1;
1124 break;
1125
1126 default:
1127 return -EINVAL;
1128 }
1129
1130 // calculate divisor
1131 // ((36130000+((1000000/6)/2)) + Finput)/(1000000/6)
1132 tuner_frequency = (((params->frequency / 1000) * 6) + 217280) / 1000;
1133
1134 // setup tuner buffer
1135 tuner_buf[0] = tuner_frequency >> 8;
1136 tuner_buf[1] = tuner_frequency & 0xff;
1137 tuner_buf[2] = 0xca;
1138 tuner_buf[3] = (cp << 5) | (filter << 3) | band;
1139
Patrick Boettcherdea74862006-05-14 05:01:31 -03001140 if (fe->ops.i2c_gate_ctrl)
1141 fe->ops.i2c_gate_ctrl(fe, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001142 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1)
1143 return -EIO;
1144
1145 msleep(1);
1146 return 0;
1147}
1148
1149static int philips_tdm1316l_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
1150{
1151 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1152
1153 return request_firmware(fw, name, &ttusb->dev->dev);
1154}
1155
1156static struct tda1004x_config philips_tdm1316l_config = {
1157
1158 .demod_address = 0x8,
1159 .invert = 1,
1160 .invert_oclk = 0,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001161 .request_firmware = philips_tdm1316l_request_firmware,
1162};
1163
1164static u8 alps_bsbe1_inittab[] = {
Mauro Carvalho Chehab9101e622005-12-12 00:37:24 -08001165 0x01, 0x15,
1166 0x02, 0x30,
1167 0x03, 0x00,
1168 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
1169 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
1170 0x06, 0x40, /* DAC not used, set to high impendance mode */
1171 0x07, 0x00, /* DAC LSB */
1172 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
1173 0x09, 0x00, /* FIFO */
1174 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
1175 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
1176 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
1177 0x10, 0x3f, // AGC2 0x3d
1178 0x11, 0x84,
1179 0x12, 0xb9,
1180 0x15, 0xc9, // lock detector threshold
1181 0x16, 0x00,
1182 0x17, 0x00,
1183 0x18, 0x00,
1184 0x19, 0x00,
1185 0x1a, 0x00,
1186 0x1f, 0x50,
1187 0x20, 0x00,
1188 0x21, 0x00,
1189 0x22, 0x00,
1190 0x23, 0x00,
1191 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
1192 0x29, 0x1e, // 1/2 threshold
1193 0x2a, 0x14, // 2/3 threshold
1194 0x2b, 0x0f, // 3/4 threshold
1195 0x2c, 0x09, // 5/6 threshold
1196 0x2d, 0x05, // 7/8 threshold
1197 0x2e, 0x01,
1198 0x31, 0x1f, // test all FECs
1199 0x32, 0x19, // viterbi and synchro search
1200 0x33, 0xfc, // rs control
1201 0x34, 0x93, // error control
1202 0x0f, 0x92,
1203 0xff, 0xff
Linus Torvalds1da177e2005-04-16 15:20:36 -07001204};
1205
1206static u8 alps_bsru6_inittab[] = {
1207 0x01, 0x15,
1208 0x02, 0x30,
1209 0x03, 0x00,
1210 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
1211 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
1212 0x06, 0x40, /* DAC not used, set to high impendance mode */
1213 0x07, 0x00, /* DAC LSB */
1214 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
1215 0x09, 0x00, /* FIFO */
1216 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
1217 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
1218 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
1219 0x10, 0x3f, // AGC2 0x3d
1220 0x11, 0x84,
Oliver Endriss7f44dcd2005-11-08 21:35:44 -08001221 0x12, 0xb9,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001222 0x15, 0xc9, // lock detector threshold
1223 0x16, 0x00,
1224 0x17, 0x00,
1225 0x18, 0x00,
1226 0x19, 0x00,
1227 0x1a, 0x00,
1228 0x1f, 0x50,
1229 0x20, 0x00,
1230 0x21, 0x00,
1231 0x22, 0x00,
1232 0x23, 0x00,
1233 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
1234 0x29, 0x1e, // 1/2 threshold
1235 0x2a, 0x14, // 2/3 threshold
1236 0x2b, 0x0f, // 3/4 threshold
1237 0x2c, 0x09, // 5/6 threshold
1238 0x2d, 0x05, // 7/8 threshold
1239 0x2e, 0x01,
1240 0x31, 0x1f, // test all FECs
1241 0x32, 0x19, // viterbi and synchro search
1242 0x33, 0xfc, // rs control
1243 0x34, 0x93, // error control
1244 0x0f, 0x52,
1245 0xff, 0xff
1246};
1247
1248static int alps_stv0299_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
1249{
1250 u8 aclk = 0;
1251 u8 bclk = 0;
1252
1253 if (srate < 1500000) {
1254 aclk = 0xb7;
1255 bclk = 0x47;
1256 } else if (srate < 3000000) {
1257 aclk = 0xb7;
1258 bclk = 0x4b;
1259 } else if (srate < 7000000) {
1260 aclk = 0xb7;
1261 bclk = 0x4f;
1262 } else if (srate < 14000000) {
1263 aclk = 0xb7;
1264 bclk = 0x53;
1265 } else if (srate < 30000000) {
1266 aclk = 0xb6;
1267 bclk = 0x53;
1268 } else if (srate < 45000000) {
1269 aclk = 0xb4;
1270 bclk = 0x51;
1271 }
1272
1273 stv0299_writereg(fe, 0x13, aclk);
1274 stv0299_writereg(fe, 0x14, bclk);
1275 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
1276 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
1277 stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
1278
1279 return 0;
1280}
1281
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001282static int philips_tsa5059_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001283{
1284 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1285 u8 buf[4];
1286 u32 div;
1287 struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
1288
1289 if ((params->frequency < 950000) || (params->frequency > 2150000))
1290 return -EINVAL;
1291
1292 div = (params->frequency + (125 - 1)) / 125; // round correctly
1293 buf[0] = (div >> 8) & 0x7f;
1294 buf[1] = div & 0xff;
1295 buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
1296 buf[3] = 0xC4;
1297
1298 if (params->frequency > 1530000)
1299 buf[3] = 0xC0;
1300
1301 /* BSBE1 wants XCE bit set */
1302 if (ttusb->revision == TTUSB_REV_2_2)
1303 buf[3] |= 0x20;
1304
Patrick Boettcherdea74862006-05-14 05:01:31 -03001305 if (fe->ops.i2c_gate_ctrl)
1306 fe->ops.i2c_gate_ctrl(fe, 1);
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001307 if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001308 return -EIO;
1309
1310 return 0;
1311}
1312
1313static struct stv0299_config alps_stv0299_config = {
1314 .demod_address = 0x68,
1315 .inittab = alps_bsru6_inittab,
1316 .mclk = 88000000UL,
1317 .invert = 1,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001318 .skip_reinit = 0,
Oliver Endrissda2c7f62008-04-20 22:13:37 -03001319 .lock_output = STV0299_LOCKOUTPUT_1,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001320 .volt13_op0_op1 = STV0299_VOLT13_OP1,
1321 .min_delay_ms = 100,
1322 .set_symbol_rate = alps_stv0299_set_symbol_rate,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001323};
1324
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001325static 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 -07001326{
1327 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1328 u8 buf[4];
1329 u32 div;
1330 struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
1331
Mauro Carvalho Chehab9101e622005-12-12 00:37:24 -08001332 div = params->frequency / 125;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001333
1334 buf[0] = (div >> 8) & 0x7f;
1335 buf[1] = div & 0xff;
1336 buf[2] = 0x8e;
1337 buf[3] = 0x00;
1338
Patrick Boettcherdea74862006-05-14 05:01:31 -03001339 if (fe->ops.i2c_gate_ctrl)
1340 fe->ops.i2c_gate_ctrl(fe, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001341 if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1)
1342 return -EIO;
1343
1344 return 0;
1345}
1346
1347static struct tda8083_config ttusb_novas_grundig_29504_491_config = {
1348
1349 .demod_address = 0x68,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001350};
1351
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001352static int alps_tdbe2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
Gavin Hamill53936392005-07-07 17:58:04 -07001353{
1354 struct ttusb* ttusb = fe->dvb->priv;
1355 u32 div;
1356 u8 data[4];
1357 struct i2c_msg msg = { .addr = 0x62, .flags = 0, .buf = data, .len = sizeof(data) };
1358
1359 div = (params->frequency + 35937500 + 31250) / 62500;
1360
1361 data[0] = (div >> 8) & 0x7f;
1362 data[1] = div & 0xff;
1363 data[2] = 0x85 | ((div >> 10) & 0x60);
1364 data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81);
1365
Patrick Boettcherdea74862006-05-14 05:01:31 -03001366 if (fe->ops.i2c_gate_ctrl)
1367 fe->ops.i2c_gate_ctrl(fe, 1);
Gavin Hamill53936392005-07-07 17:58:04 -07001368 if (i2c_transfer (&ttusb->i2c_adap, &msg, 1) != 1)
1369 return -EIO;
1370
1371 return 0;
1372}
1373
1374
1375static struct ves1820_config alps_tdbe2_config = {
1376 .demod_address = 0x09,
1377 .xin = 57840000UL,
1378 .invert = 1,
1379 .selagc = VES1820_SELAGC_SIGNAMPERR,
Gavin Hamill53936392005-07-07 17:58:04 -07001380};
1381
1382static u8 read_pwm(struct ttusb* ttusb)
1383{
1384 u8 b = 0xff;
1385 u8 pwm;
1386 struct i2c_msg msg[] = { { .addr = 0x50,.flags = 0,.buf = &b,.len = 1 },
1387 { .addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1} };
1388
1389 if ((i2c_transfer(&ttusb->i2c_adap, msg, 2) != 2) || (pwm == 0xff))
1390 pwm = 0x48;
1391
1392 return pwm;
1393}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001394
1395
Thomas Kaiserb8d4c232006-04-27 21:45:20 -03001396static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
1397{
1398 struct ttusb *ttusb = (struct ttusb *) fe->dvb->priv;
1399 u8 tuner_buf[5];
1400 struct i2c_msg tuner_msg = {.addr = 0x60,
1401 .flags = 0,
1402 .buf = tuner_buf,
1403 .len = sizeof(tuner_buf) };
1404 int tuner_frequency = 0;
1405 u8 band, cp, filter;
1406
1407 // determine charge pump
1408 tuner_frequency = params->frequency;
1409 if (tuner_frequency < 87000000) {return -EINVAL;}
1410 else if (tuner_frequency < 130000000) {cp = 3; band = 1;}
1411 else if (tuner_frequency < 160000000) {cp = 5; band = 1;}
1412 else if (tuner_frequency < 200000000) {cp = 6; band = 1;}
1413 else if (tuner_frequency < 290000000) {cp = 3; band = 2;}
1414 else if (tuner_frequency < 420000000) {cp = 5; band = 2;}
1415 else if (tuner_frequency < 480000000) {cp = 6; band = 2;}
1416 else if (tuner_frequency < 620000000) {cp = 3; band = 4;}
1417 else if (tuner_frequency < 830000000) {cp = 5; band = 4;}
1418 else if (tuner_frequency < 895000000) {cp = 7; band = 4;}
1419 else {return -EINVAL;}
1420
1421 // assume PLL filter should always be 8MHz for the moment.
1422 filter = 1;
1423
1424 // calculate divisor
1425 // (Finput + Fif)/Fref; Fif = 36125000 Hz, Fref = 62500 Hz
1426 tuner_frequency = ((params->frequency + 36125000) / 62500);
1427
1428 // setup tuner buffer
1429 tuner_buf[0] = tuner_frequency >> 8;
1430 tuner_buf[1] = tuner_frequency & 0xff;
1431 tuner_buf[2] = 0xc8;
1432 tuner_buf[3] = (cp << 5) | (filter << 3) | band;
1433 tuner_buf[4] = 0x80;
1434
Patrick Boettcherdea74862006-05-14 05:01:31 -03001435 if (fe->ops.i2c_gate_ctrl)
1436 fe->ops.i2c_gate_ctrl(fe, 1);
Thomas Kaiserb8d4c232006-04-27 21:45:20 -03001437 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) {
1438 printk("dvb-ttusb-budget: dvbc_philips_tdm1316l_pll_set Error 1\n");
1439 return -EIO;
1440 }
1441
1442 msleep(50);
1443
Patrick Boettcherdea74862006-05-14 05:01:31 -03001444 if (fe->ops.i2c_gate_ctrl)
1445 fe->ops.i2c_gate_ctrl(fe, 1);
Thomas Kaiserb8d4c232006-04-27 21:45:20 -03001446 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) {
1447 printk("dvb-ttusb-budget: dvbc_philips_tdm1316l_pll_set Error 2\n");
1448 return -EIO;
1449 }
1450
1451 msleep(1);
1452
1453 return 0;
1454}
1455
1456static u8 dvbc_philips_tdm1316l_inittab[] = {
1457 0x80, 0x21,
1458 0x80, 0x20,
1459 0x81, 0x01,
1460 0x81, 0x00,
1461 0x00, 0x09,
1462 0x01, 0x69,
1463 0x03, 0x00,
1464 0x04, 0x00,
1465 0x07, 0x00,
1466 0x08, 0x00,
1467 0x20, 0x00,
1468 0x21, 0x40,
1469 0x22, 0x00,
1470 0x23, 0x00,
1471 0x24, 0x40,
1472 0x25, 0x88,
1473 0x30, 0xff,
1474 0x31, 0x00,
1475 0x32, 0xff,
1476 0x33, 0x00,
1477 0x34, 0x50,
1478 0x35, 0x7f,
1479 0x36, 0x00,
1480 0x37, 0x20,
1481 0x38, 0x00,
1482 0x40, 0x1c,
1483 0x41, 0xff,
1484 0x42, 0x29,
1485 0x43, 0x20,
1486 0x44, 0xff,
1487 0x45, 0x00,
1488 0x46, 0x00,
1489 0x49, 0x04,
1490 0x4a, 0xff,
1491 0x4b, 0x7f,
1492 0x52, 0x30,
1493 0x55, 0xae,
1494 0x56, 0x47,
1495 0x57, 0xe1,
1496 0x58, 0x3a,
1497 0x5a, 0x1e,
1498 0x5b, 0x34,
1499 0x60, 0x00,
1500 0x63, 0x00,
1501 0x64, 0x00,
1502 0x65, 0x00,
1503 0x66, 0x00,
1504 0x67, 0x00,
1505 0x68, 0x00,
1506 0x69, 0x00,
1507 0x6a, 0x02,
1508 0x6b, 0x00,
1509 0x70, 0xff,
1510 0x71, 0x00,
1511 0x72, 0x00,
1512 0x73, 0x00,
1513 0x74, 0x0c,
1514 0x80, 0x00,
1515 0x81, 0x00,
1516 0x82, 0x00,
1517 0x83, 0x00,
1518 0x84, 0x04,
1519 0x85, 0x80,
1520 0x86, 0x24,
1521 0x87, 0x78,
1522 0x88, 0x00,
1523 0x89, 0x00,
1524 0x90, 0x01,
1525 0x91, 0x01,
1526 0xa0, 0x00,
1527 0xa1, 0x00,
1528 0xa2, 0x00,
1529 0xb0, 0x91,
1530 0xb1, 0x0b,
1531 0xc0, 0x4b,
1532 0xc1, 0x00,
1533 0xc2, 0x00,
1534 0xd0, 0x00,
1535 0xd1, 0x00,
1536 0xd2, 0x00,
1537 0xd3, 0x00,
1538 0xd4, 0x00,
1539 0xd5, 0x00,
1540 0xde, 0x00,
1541 0xdf, 0x00,
1542 0x61, 0x38,
1543 0x62, 0x0a,
1544 0x53, 0x13,
1545 0x59, 0x08,
1546 0x55, 0x00,
1547 0x56, 0x40,
1548 0x57, 0x08,
1549 0x58, 0x3d,
1550 0x88, 0x10,
1551 0xa0, 0x00,
1552 0xa0, 0x00,
1553 0xa0, 0x00,
1554 0xa0, 0x04,
1555 0xff, 0xff,
1556};
1557
1558static struct stv0297_config dvbc_philips_tdm1316l_config = {
1559 .demod_address = 0x1c,
1560 .inittab = dvbc_philips_tdm1316l_inittab,
1561 .invert = 0,
1562};
1563
Linus Torvalds1da177e2005-04-16 15:20:36 -07001564static void frontend_init(struct ttusb* ttusb)
1565{
1566 switch(le16_to_cpu(ttusb->dev->descriptor.idProduct)) {
1567 case 0x1003: // Hauppauge/TT Nova-USB-S budget (stv0299/ALPS BSRU6|BSBE1(tsa5059))
1568 // try the stv0299 based first
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001569 ttusb->fe = dvb_attach(stv0299_attach, &alps_stv0299_config, &ttusb->i2c_adap);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001570 if (ttusb->fe != NULL) {
Patrick Boettcherdea74862006-05-14 05:01:31 -03001571 ttusb->fe->ops.tuner_ops.set_params = philips_tsa5059_tuner_set_params;
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001572
Linus Torvalds1da177e2005-04-16 15:20:36 -07001573 if(ttusb->revision == TTUSB_REV_2_2) { // ALPS BSBE1
1574 alps_stv0299_config.inittab = alps_bsbe1_inittab;
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001575 dvb_attach(lnbp21_attach, ttusb->fe, &ttusb->i2c_adap, 0, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001576 } else { // ALPS BSRU6
Patrick Boettcherdea74862006-05-14 05:01:31 -03001577 ttusb->fe->ops.set_voltage = ttusb_set_voltage;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001578 }
1579 break;
1580 }
1581
1582 // Grundig 29504-491
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001583 ttusb->fe = dvb_attach(tda8083_attach, &ttusb_novas_grundig_29504_491_config, &ttusb->i2c_adap);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001584 if (ttusb->fe != NULL) {
Patrick Boettcherdea74862006-05-14 05:01:31 -03001585 ttusb->fe->ops.tuner_ops.set_params = ttusb_novas_grundig_29504_491_tuner_set_params;
1586 ttusb->fe->ops.set_voltage = ttusb_set_voltage;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001587 break;
1588 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001589 break;
1590
Gavin Hamill53936392005-07-07 17:58:04 -07001591 case 0x1004: // Hauppauge/TT DVB-C budget (ves1820/ALPS TDBE2(sp5659))
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001592 ttusb->fe = dvb_attach(ves1820_attach, &alps_tdbe2_config, &ttusb->i2c_adap, read_pwm(ttusb));
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001593 if (ttusb->fe != NULL) {
Patrick Boettcherdea74862006-05-14 05:01:31 -03001594 ttusb->fe->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params;
Gavin Hamill53936392005-07-07 17:58:04 -07001595 break;
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001596 }
Thomas Kaiserb8d4c232006-04-27 21:45:20 -03001597
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001598 ttusb->fe = dvb_attach(stv0297_attach, &dvbc_philips_tdm1316l_config, &ttusb->i2c_adap);
Thomas Kaiserb8d4c232006-04-27 21:45:20 -03001599 if (ttusb->fe != NULL) {
Patrick Boettcherdea74862006-05-14 05:01:31 -03001600 ttusb->fe->ops.tuner_ops.set_params = dvbc_philips_tdm1316l_tuner_set_params;
Thomas Kaiserb8d4c232006-04-27 21:45:20 -03001601 break;
1602 }
Gavin Hamill53936392005-07-07 17:58:04 -07001603 break;
1604
Linus Torvalds1da177e2005-04-16 15:20:36 -07001605 case 0x1005: // Hauppauge/TT Nova-USB-t budget (tda10046/Philips td1316(tda6651tt) OR cx22700/ALPS TDMB7(??))
1606 // try the ALPS TDMB7 first
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001607 ttusb->fe = dvb_attach(cx22700_attach, &alps_tdmb7_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.set_params = alps_tdmb7_tuner_set_params;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001610 break;
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001611 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001612
1613 // Philips td1316
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001614 ttusb->fe = dvb_attach(tda10046_attach, &philips_tdm1316l_config, &ttusb->i2c_adap);
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001615 if (ttusb->fe != NULL) {
Patrick Boettcherdea74862006-05-14 05:01:31 -03001616 ttusb->fe->ops.tuner_ops.init = philips_tdm1316l_tuner_init;
1617 ttusb->fe->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001618 break;
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001619 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001620 break;
1621 }
1622
1623 if (ttusb->fe == NULL) {
Bjorn Helgaas29e66a62008-09-04 17:24:51 -03001624 printk("dvb-ttusb-budget: A frontend driver was not found for device [%04x:%04x]\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001625 le16_to_cpu(ttusb->dev->descriptor.idVendor),
1626 le16_to_cpu(ttusb->dev->descriptor.idProduct));
1627 } else {
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001628 if (dvb_register_frontend(&ttusb->adapter, ttusb->fe)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001629 printk("dvb-ttusb-budget: Frontend registration failed!\n");
Andrew de Quinceyf52a8382006-08-08 09:10:09 -03001630 dvb_frontend_detach(ttusb->fe);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001631 ttusb->fe = NULL;
1632 }
1633 }
1634}
1635
1636
1637
1638static struct i2c_algorithm ttusb_dec_algo = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001639 .master_xfer = master_xfer,
1640 .functionality = functionality,
1641};
1642
1643static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *id)
1644{
1645 struct usb_device *udev;
1646 struct ttusb *ttusb;
1647 int result;
1648
Harvey Harrisonfb9393b2008-04-08 23:20:00 -03001649 dprintk("%s: TTUSB DVB connected\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001650
1651 udev = interface_to_usbdev(intf);
1652
Mauro Carvalho Chehab9101e622005-12-12 00:37:24 -08001653 if (intf->altsetting->desc.bInterfaceNumber != 1) return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001654
Panagiotis Issaris74081872006-01-11 19:40:56 -02001655 if (!(ttusb = kzalloc(sizeof(struct ttusb), GFP_KERNEL)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001656 return -ENOMEM;
1657
Linus Torvalds1da177e2005-04-16 15:20:36 -07001658 ttusb->dev = udev;
1659 ttusb->c = 0;
1660 ttusb->mux_state = 0;
Ingo Molnar3593cab2006-02-07 06:49:14 -02001661 mutex_init(&ttusb->semi2c);
1662
1663 mutex_lock(&ttusb->semi2c);
1664
1665 mutex_init(&ttusb->semusb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001666
1667 ttusb_setup_interfaces(ttusb);
1668
Douglas Schilling Landgrafb7ed7852008-11-11 23:37:39 -03001669 result = ttusb_alloc_iso_urbs(ttusb);
1670 if (result < 0) {
1671 dprintk("%s: ttusb_alloc_iso_urbs - failed\n", __func__);
1672 mutex_unlock(&ttusb->semi2c);
1673 kfree(ttusb);
1674 return result;
1675 }
1676
Linus Torvalds1da177e2005-04-16 15:20:36 -07001677 if (ttusb_init_controller(ttusb))
1678 printk("ttusb_init_controller: error\n");
1679
Ingo Molnar3593cab2006-02-07 06:49:14 -02001680 mutex_unlock(&ttusb->semi2c);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001681
Janne Grunau78e92002008-04-09 19:13:13 -03001682 result = dvb_register_adapter(&ttusb->adapter,
1683 "Technotrend/Hauppauge Nova-USB",
1684 THIS_MODULE, &udev->dev, adapter_nr);
1685 if (result < 0) {
Andrew de Quinceya064fad2006-04-06 17:05:46 -03001686 ttusb_free_iso_urbs(ttusb);
1687 kfree(ttusb);
1688 return result;
1689 }
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001690 ttusb->adapter.priv = ttusb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001691
1692 /* i2c */
1693 memset(&ttusb->i2c_adap, 0, sizeof(struct i2c_adapter));
1694 strcpy(ttusb->i2c_adap.name, "TTUSB DEC");
1695
1696 i2c_set_adapdata(&ttusb->i2c_adap, ttusb);
1697
Linus Torvalds1da177e2005-04-16 15:20:36 -07001698 ttusb->i2c_adap.algo = &ttusb_dec_algo;
1699 ttusb->i2c_adap.algo_data = NULL;
Jean Delvare12a917f2007-02-13 22:09:03 +01001700 ttusb->i2c_adap.dev.parent = &udev->dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001701
1702 result = i2c_add_adapter(&ttusb->i2c_adap);
1703 if (result) {
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001704 dvb_unregister_adapter (&ttusb->adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001705 return result;
1706 }
1707
1708 memset(&ttusb->dvb_demux, 0, sizeof(ttusb->dvb_demux));
1709
1710 ttusb->dvb_demux.dmx.capabilities =
1711 DMX_TS_FILTERING | DMX_SECTION_FILTERING;
1712 ttusb->dvb_demux.priv = NULL;
1713#ifdef TTUSB_HWSECTIONS
1714 ttusb->dvb_demux.filternum = TTUSB_MAXFILTER;
1715#else
1716 ttusb->dvb_demux.filternum = 32;
1717#endif
1718 ttusb->dvb_demux.feednum = TTUSB_MAXCHANNEL;
1719 ttusb->dvb_demux.start_feed = ttusb_start_feed;
1720 ttusb->dvb_demux.stop_feed = ttusb_stop_feed;
1721 ttusb->dvb_demux.write_to_decoder = NULL;
1722
1723 if ((result = dvb_dmx_init(&ttusb->dvb_demux)) < 0) {
1724 printk("ttusb_dvb: dvb_dmx_init failed (errno = %d)\n", result);
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//FIXME dmxdev (nur WAS?)
1730 ttusb->dmxdev.filternum = ttusb->dvb_demux.filternum;
1731 ttusb->dmxdev.demux = &ttusb->dvb_demux.dmx;
1732 ttusb->dmxdev.capabilities = 0;
1733
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001734 if ((result = dvb_dmxdev_init(&ttusb->dmxdev, &ttusb->adapter)) < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001735 printk("ttusb_dvb: dvb_dmxdev_init failed (errno = %d)\n",
1736 result);
1737 dvb_dmx_release(&ttusb->dvb_demux);
1738 i2c_del_adapter(&ttusb->i2c_adap);
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001739 dvb_unregister_adapter (&ttusb->adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001740 return -ENODEV;
1741 }
1742
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001743 if (dvb_net_init(&ttusb->adapter, &ttusb->dvbnet, &ttusb->dvb_demux.dmx)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001744 printk("ttusb_dvb: dvb_net_init failed!\n");
1745 dvb_dmxdev_release(&ttusb->dmxdev);
1746 dvb_dmx_release(&ttusb->dvb_demux);
1747 i2c_del_adapter(&ttusb->i2c_adap);
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001748 dvb_unregister_adapter (&ttusb->adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001749 return -ENODEV;
1750 }
1751
Linus Torvalds1da177e2005-04-16 15:20:36 -07001752 usb_set_intfdata(intf, (void *) ttusb);
1753
1754 frontend_init(ttusb);
1755
1756 return 0;
1757}
1758
1759static void ttusb_disconnect(struct usb_interface *intf)
1760{
1761 struct ttusb *ttusb = usb_get_intfdata(intf);
1762
1763 usb_set_intfdata(intf, NULL);
1764
1765 ttusb->disconnecting = 1;
1766
1767 ttusb_stop_iso_xfer(ttusb);
1768
1769 ttusb->dvb_demux.dmx.close(&ttusb->dvb_demux.dmx);
1770 dvb_net_release(&ttusb->dvbnet);
1771 dvb_dmxdev_release(&ttusb->dmxdev);
1772 dvb_dmx_release(&ttusb->dvb_demux);
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001773 if (ttusb->fe != NULL) {
1774 dvb_unregister_frontend(ttusb->fe);
Andrew de Quinceyf52a8382006-08-08 09:10:09 -03001775 dvb_frontend_detach(ttusb->fe);
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001776 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001777 i2c_del_adapter(&ttusb->i2c_adap);
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001778 dvb_unregister_adapter(&ttusb->adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001779
1780 ttusb_free_iso_urbs(ttusb);
1781
1782 kfree(ttusb);
1783
Harvey Harrisonfb9393b2008-04-08 23:20:00 -03001784 dprintk("%s: TTUSB DVB disconnected\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001785}
1786
1787static struct usb_device_id ttusb_table[] = {
1788 {USB_DEVICE(0xb48, 0x1003)},
Gavin Hamill53936392005-07-07 17:58:04 -07001789 {USB_DEVICE(0xb48, 0x1004)},
Linus Torvalds1da177e2005-04-16 15:20:36 -07001790 {USB_DEVICE(0xb48, 0x1005)},
1791 {}
1792};
1793
1794MODULE_DEVICE_TABLE(usb, ttusb_table);
1795
1796static struct usb_driver ttusb_driver = {
Julian Scheel27b05fd2005-07-12 13:58:39 -07001797 .name = "ttusb",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001798 .probe = ttusb_probe,
1799 .disconnect = ttusb_disconnect,
1800 .id_table = ttusb_table,
1801};
1802
1803static int __init ttusb_init(void)
1804{
1805 int err;
1806
1807 if ((err = usb_register(&ttusb_driver)) < 0) {
1808 printk("%s: usb_register failed! Error number %d",
1809 __FILE__, err);
1810 return err;
1811 }
1812
1813 return 0;
1814}
1815
1816static void __exit ttusb_exit(void)
1817{
1818 usb_deregister(&ttusb_driver);
1819}
1820
1821module_init(ttusb_init);
1822module_exit(ttusb_exit);
1823
1824MODULE_AUTHOR("Holger Waechtler <holger@convergence.de>");
1825MODULE_DESCRIPTION("TTUSB DVB Driver");
1826MODULE_LICENSE("GPL");
David Woodhouse0a2a7362008-05-29 19:50:06 +03001827MODULE_FIRMWARE("ttusb-budget/dspbootcode.bin");