blob: 21b9049c7b3fa111fbedb61b71782f7e699651c5 [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
Jarod Wilson68a49a42011-03-24 12:56:16 -030055 debug:
Linus Torvalds1da177e2005-04-16 15:20:36 -070056 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
Linus Torvalds1da177e2005-04-16 15:20:36 -0700137static int ttusb_cmd(struct ttusb *ttusb,
138 const u8 * data, int len, int needresult)
139{
140 int actual_len;
141 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700142 int i;
143
Jarod Wilson68a49a42011-03-24 12:56:16 -0300144 if (debug >= 3) {
145 printk(KERN_DEBUG ">");
146 for (i = 0; i < len; ++i)
147 printk(KERN_CONT " %02x", data[i]);
148 printk(KERN_CONT "\n");
149 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700150
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 }
Jarod Wilson68a49a42011-03-24 12:56:16 -0300178
179 if (debug >= 3) {
180 actual_len = ttusb->last_result[3] + 4;
181 printk(KERN_DEBUG "<");
182 for (i = 0; i < actual_len; ++i)
183 printk(KERN_CONT " %02x", ttusb->last_result[i]);
184 printk(KERN_CONT "\n");
185 }
186
Linus Torvalds1da177e2005-04-16 15:20:36 -0700187 if (!needresult)
Ingo Molnar3593cab2006-02-07 06:49:14 -0200188 mutex_unlock(&ttusb->semusb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700189 return 0;
190}
191
192static int ttusb_result(struct ttusb *ttusb, u8 * data, int len)
193{
194 memcpy(data, ttusb->last_result, len);
Ingo Molnar3593cab2006-02-07 06:49:14 -0200195 mutex_unlock(&ttusb->semusb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700196 return 0;
197}
198
199static int ttusb_i2c_msg(struct ttusb *ttusb,
200 u8 addr, u8 * snd_buf, u8 snd_len, u8 * rcv_buf,
201 u8 rcv_len)
202{
203 u8 b[0x28];
204 u8 id = ++ttusb->c;
205 int i, err;
206
207 if (snd_len > 0x28 - 7 || rcv_len > 0x20 - 7)
208 return -EINVAL;
209
210 b[0] = 0xaa;
211 b[1] = id;
212 b[2] = 0x31;
213 b[3] = snd_len + 3;
214 b[4] = addr << 1;
215 b[5] = snd_len;
216 b[6] = rcv_len;
217
218 for (i = 0; i < snd_len; i++)
219 b[7 + i] = snd_buf[i];
220
221 err = ttusb_cmd(ttusb, b, snd_len + 7, 1);
222
223 if (err)
224 return -EREMOTEIO;
225
226 err = ttusb_result(ttusb, b, 0x20);
227
Mauro Carvalho Chehab9101e622005-12-12 00:37:24 -0800228 /* check if the i2c transaction was successful */
229 if ((snd_len != b[5]) || (rcv_len != b[6])) return -EREMOTEIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700230
231 if (rcv_len > 0) {
232
233 if (err || b[0] != 0x55 || b[1] != id) {
234 dprintk
235 ("%s: usb_bulk_msg(recv) failed, err == %i, id == %02x, b == ",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300236 __func__, err, id);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700237 return -EREMOTEIO;
238 }
239
240 for (i = 0; i < rcv_len; i++)
241 rcv_buf[i] = b[7 + i];
242 }
243
244 return rcv_len;
245}
246
247static int master_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, int num)
248{
249 struct ttusb *ttusb = i2c_get_adapdata(adapter);
250 int i = 0;
251 int inc;
252
Ingo Molnar3593cab2006-02-07 06:49:14 -0200253 if (mutex_lock_interruptible(&ttusb->semi2c) < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700254 return -EAGAIN;
255
256 while (i < num) {
257 u8 addr, snd_len, rcv_len, *snd_buf, *rcv_buf;
258 int err;
259
260 if (num > i + 1 && (msg[i + 1].flags & I2C_M_RD)) {
261 addr = msg[i].addr;
262 snd_buf = msg[i].buf;
263 snd_len = msg[i].len;
264 rcv_buf = msg[i + 1].buf;
265 rcv_len = msg[i + 1].len;
266 inc = 2;
267 } else {
268 addr = msg[i].addr;
269 snd_buf = msg[i].buf;
270 snd_len = msg[i].len;
271 rcv_buf = NULL;
272 rcv_len = 0;
273 inc = 1;
274 }
275
276 err = ttusb_i2c_msg(ttusb, addr,
277 snd_buf, snd_len, rcv_buf, rcv_len);
278
279 if (err < rcv_len) {
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300280 dprintk("%s: i == %i\n", __func__, i);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700281 break;
282 }
283
284 i += inc;
285 }
286
Ingo Molnar3593cab2006-02-07 06:49:14 -0200287 mutex_unlock(&ttusb->semi2c);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700288 return i;
289}
290
Linus Torvalds1da177e2005-04-16 15:20:36 -0700291static int ttusb_boot_dsp(struct ttusb *ttusb)
292{
David Woodhouse0a2a7362008-05-29 19:50:06 +0300293 const struct firmware *fw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700294 int i, err;
295 u8 b[40];
296
David Woodhouse0a2a7362008-05-29 19:50:06 +0300297 err = request_firmware(&fw, "ttusb-budget/dspbootcode.bin",
298 &ttusb->dev->dev);
299 if (err) {
300 printk(KERN_ERR "ttusb-budget: failed to request firmware\n");
301 return err;
302 }
303
Linus Torvalds1da177e2005-04-16 15:20:36 -0700304 /* BootBlock */
305 b[0] = 0xaa;
306 b[2] = 0x13;
307 b[3] = 28;
308
309 /* upload dsp code in 32 byte steps (36 didn't work for me ...) */
310 /* 32 is max packet size, no messages should be splitted. */
David Woodhouse0a2a7362008-05-29 19:50:06 +0300311 for (i = 0; i < fw->size; i += 28) {
312 memcpy(&b[4], &fw->data[i], 28);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700313
314 b[1] = ++ttusb->c;
315
316 err = ttusb_cmd(ttusb, b, 32, 0);
317 if (err)
318 goto done;
319 }
320
321 /* last block ... */
322 b[1] = ++ttusb->c;
323 b[2] = 0x13;
324 b[3] = 0;
325
326 err = ttusb_cmd(ttusb, b, 4, 0);
327 if (err)
328 goto done;
329
330 /* BootEnd */
331 b[1] = ++ttusb->c;
332 b[2] = 0x14;
333 b[3] = 0;
334
335 err = ttusb_cmd(ttusb, b, 4, 0);
336
337 done:
Jesper Juhlba0fd562011-02-06 17:49:02 -0300338 release_firmware(fw);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700339 if (err) {
340 dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300341 __func__, err);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700342 }
343
344 return err;
345}
346
347static int ttusb_set_channel(struct ttusb *ttusb, int chan_id, int filter_type,
348 int pid)
349{
350 int err;
351 /* SetChannel */
352 u8 b[] = { 0xaa, ++ttusb->c, 0x22, 4, chan_id, filter_type,
353 (pid >> 8) & 0xff, pid & 0xff
354 };
355
356 err = ttusb_cmd(ttusb, b, sizeof(b), 0);
357 return err;
358}
359
360static int ttusb_del_channel(struct ttusb *ttusb, int channel_id)
361{
362 int err;
363 /* DelChannel */
364 u8 b[] = { 0xaa, ++ttusb->c, 0x23, 1, channel_id };
365
366 err = ttusb_cmd(ttusb, b, sizeof(b), 0);
367 return err;
368}
369
370#ifdef TTUSB_HWSECTIONS
371static int ttusb_set_filter(struct ttusb *ttusb, int filter_id,
372 int associated_chan, u8 filter[8], u8 mask[8])
373{
374 int err;
375 /* SetFilter */
376 u8 b[] = { 0xaa, 0, 0x24, 0x1a, filter_id, associated_chan,
377 filter[0], filter[1], filter[2], filter[3],
378 filter[4], filter[5], filter[6], filter[7],
379 filter[8], filter[9], filter[10], filter[11],
380 mask[0], mask[1], mask[2], mask[3],
381 mask[4], mask[5], mask[6], mask[7],
382 mask[8], mask[9], mask[10], mask[11]
383 };
384
385 err = ttusb_cmd(ttusb, b, sizeof(b), 0);
386 return err;
387}
388
389static int ttusb_del_filter(struct ttusb *ttusb, int filter_id)
390{
391 int err;
392 /* DelFilter */
393 u8 b[] = { 0xaa, ++ttusb->c, 0x25, 1, filter_id };
394
395 err = ttusb_cmd(ttusb, b, sizeof(b), 0);
396 return err;
397}
398#endif
399
400static int ttusb_init_controller(struct ttusb *ttusb)
401{
402 u8 b0[] = { 0xaa, ++ttusb->c, 0x15, 1, 0 };
403 u8 b1[] = { 0xaa, ++ttusb->c, 0x15, 1, 1 };
404 u8 b2[] = { 0xaa, ++ttusb->c, 0x32, 1, 0 };
405 /* i2c write read: 5 bytes, addr 0x10, 0x02 bytes write, 1 bytes read. */
406 u8 b3[] =
407 { 0xaa, ++ttusb->c, 0x31, 5, 0x10, 0x02, 0x01, 0x00, 0x1e };
408 u8 b4[] =
409 { 0x55, ttusb->c, 0x31, 4, 0x10, 0x02, 0x01, 0x00, 0x1e };
410
411 u8 get_version[] = { 0xaa, ++ttusb->c, 0x17, 5, 0, 0, 0, 0, 0 };
412 u8 get_dsp_version[0x20] =
413 { 0xaa, ++ttusb->c, 0x26, 28, 0, 0, 0, 0, 0 };
414 int err;
415
416 /* reset board */
417 if ((err = ttusb_cmd(ttusb, b0, sizeof(b0), 0)))
418 return err;
419
420 /* reset board (again?) */
421 if ((err = ttusb_cmd(ttusb, b1, sizeof(b1), 0)))
422 return err;
423
424 ttusb_boot_dsp(ttusb);
425
426 /* set i2c bit rate */
427 if ((err = ttusb_cmd(ttusb, b2, sizeof(b2), 0)))
428 return err;
429
430 if ((err = ttusb_cmd(ttusb, b3, sizeof(b3), 1)))
431 return err;
432
433 err = ttusb_result(ttusb, b4, sizeof(b4));
434
435 if ((err = ttusb_cmd(ttusb, get_version, sizeof(get_version), 1)))
436 return err;
437
438 if ((err = ttusb_result(ttusb, get_version, sizeof(get_version))))
439 return err;
440
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300441 dprintk("%s: stc-version: %c%c%c%c%c\n", __func__,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700442 get_version[4], get_version[5], get_version[6],
443 get_version[7], get_version[8]);
444
445 if (memcmp(get_version + 4, "V 0.0", 5) &&
446 memcmp(get_version + 4, "V 1.1", 5) &&
447 memcmp(get_version + 4, "V 2.1", 5) &&
448 memcmp(get_version + 4, "V 2.2", 5)) {
449 printk
450 ("%s: unknown STC version %c%c%c%c%c, please report!\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300451 __func__, get_version[4], get_version[5],
Linus Torvalds1da177e2005-04-16 15:20:36 -0700452 get_version[6], get_version[7], get_version[8]);
453 }
454
455 ttusb->revision = ((get_version[6] - '0') << 4) |
456 (get_version[8] - '0');
457
458 err =
459 ttusb_cmd(ttusb, get_dsp_version, sizeof(get_dsp_version), 1);
460 if (err)
461 return err;
462
463 err =
464 ttusb_result(ttusb, get_dsp_version, sizeof(get_dsp_version));
465 if (err)
466 return err;
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300467 printk("%s: dsp-version: %c%c%c\n", __func__,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700468 get_dsp_version[4], get_dsp_version[5], get_dsp_version[6]);
469 return 0;
470}
471
472#ifdef TTUSB_DISEQC
473static int ttusb_send_diseqc(struct dvb_frontend* fe,
474 const struct dvb_diseqc_master_cmd *cmd)
475{
476 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
477 u8 b[12] = { 0xaa, ++ttusb->c, 0x18 };
478
479 int err;
480
481 b[3] = 4 + 2 + cmd->msg_len;
482 b[4] = 0xFF; /* send diseqc master, not burst */
483 b[5] = cmd->msg_len;
484
485 memcpy(b + 5, cmd->msg, cmd->msg_len);
486
487 /* Diseqc */
488 if ((err = ttusb_cmd(ttusb, b, 4 + b[3], 0))) {
489 dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300490 __func__, err);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700491 }
492
493 return err;
494}
495#endif
496
Linus Torvalds1da177e2005-04-16 15:20:36 -0700497static int ttusb_update_lnb(struct ttusb *ttusb)
498{
499 u8 b[] = { 0xaa, ++ttusb->c, 0x16, 5, /*power: */ 1,
500 ttusb->voltage == SEC_VOLTAGE_18 ? 0 : 1,
501 ttusb->tone == SEC_TONE_ON ? 1 : 0, 1, 1
502 };
503 int err;
504
505 /* SetLNB */
506 if ((err = ttusb_cmd(ttusb, b, sizeof(b), 0))) {
507 dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300508 __func__, err);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700509 }
510
511 return err;
512}
513
514static int ttusb_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
515{
516 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
517
518 ttusb->voltage = voltage;
519 return ttusb_update_lnb(ttusb);
520}
521
522#ifdef TTUSB_TONE
523static int ttusb_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
524{
525 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
526
527 ttusb->tone = tone;
528 return ttusb_update_lnb(ttusb);
529}
530#endif
531
532
533#if 0
534static void ttusb_set_led_freq(struct ttusb *ttusb, u8 freq)
535{
536 u8 b[] = { 0xaa, ++ttusb->c, 0x19, 1, freq };
537 int err, actual_len;
538
539 err = ttusb_cmd(ttusb, b, sizeof(b), 0);
540 if (err) {
541 dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300542 __func__, err);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700543 }
544}
545#endif
546
547/*****************************************************************************/
548
549#ifdef TTUSB_HWSECTIONS
550static void ttusb_handle_ts_data(struct ttusb_channel *channel,
551 const u8 * data, int len);
552static void ttusb_handle_sec_data(struct ttusb_channel *channel,
553 const u8 * data, int len);
554#endif
555
Douglas Schilling Landgrafff699e62008-04-22 14:41:48 -0300556static int numpkt, numts, numstuff, numsec, numinvalid;
Marcelo Feitoza Parisi4da006c2005-09-09 13:03:15 -0700557static unsigned long lastj;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700558
559static void ttusb_process_muxpack(struct ttusb *ttusb, const u8 * muxpack,
560 int len)
561{
562 u16 csum = 0, cc;
563 int i;
Dan Carpenterbf5bbed2013-02-07 04:24:49 -0300564
565 if (len < 4 || len & 0x1) {
566 pr_warn("%s: muxpack has invalid len %d\n", __func__, len);
567 numinvalid++;
568 return;
569 }
570
Linus Torvalds1da177e2005-04-16 15:20:36 -0700571 for (i = 0; i < len; i += 2)
Al Virod4f979a2008-05-21 00:31:31 -0300572 csum ^= le16_to_cpup((__le16 *) (muxpack + i));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700573 if (csum) {
574 printk("%s: muxpack with incorrect checksum, ignoring\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300575 __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700576 numinvalid++;
577 return;
578 }
579
580 cc = (muxpack[len - 4] << 8) | muxpack[len - 3];
581 cc &= 0x7FFF;
582 if ((cc != ttusb->cc) && (ttusb->cc != -1))
583 printk("%s: cc discontinuity (%d frames missing)\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300584 __func__, (cc - ttusb->cc) & 0x7FFF);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700585 ttusb->cc = (cc + 1) & 0x7FFF;
586 if (muxpack[0] & 0x80) {
587#ifdef TTUSB_HWSECTIONS
588 /* section data */
589 int pusi = muxpack[0] & 0x40;
590 int channel = muxpack[0] & 0x1F;
591 int payload = muxpack[1];
592 const u8 *data = muxpack + 2;
593 /* check offset flag */
594 if (muxpack[0] & 0x20)
595 data++;
596
597 ttusb_handle_sec_data(ttusb->channel + channel, data,
598 payload);
599 data += payload;
600
601 if ((!!(ttusb->muxpack[0] & 0x20)) ^
602 !!(ttusb->muxpack[1] & 1))
603 data++;
604#warning TODO: pusi
605 printk("cc: %04x\n", (data[0] << 8) | data[1]);
606#endif
607 numsec++;
608 } else if (muxpack[0] == 0x47) {
609#ifdef TTUSB_HWSECTIONS
610 /* we have TS data here! */
611 int pid = ((muxpack[1] & 0x0F) << 8) | muxpack[2];
612 int channel;
613 for (channel = 0; channel < TTUSB_MAXCHANNEL; ++channel)
614 if (ttusb->channel[channel].active
615 && (pid == ttusb->channel[channel].pid))
616 ttusb_handle_ts_data(ttusb->channel +
617 channel, muxpack,
618 188);
619#endif
620 numts++;
621 dvb_dmx_swfilter_packets(&ttusb->dvb_demux, muxpack, 1);
622 } else if (muxpack[0] != 0) {
623 numinvalid++;
624 printk("illegal muxpack type %02x\n", muxpack[0]);
625 } else
626 numstuff++;
627}
628
629static void ttusb_process_frame(struct ttusb *ttusb, u8 * data, int len)
630{
631 int maxwork = 1024;
632 while (len) {
633 if (!(maxwork--)) {
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300634 printk("%s: too much work\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700635 break;
636 }
637
638 switch (ttusb->mux_state) {
639 case 0:
640 case 1:
641 case 2:
642 len--;
643 if (*data++ == 0xAA)
644 ++ttusb->mux_state;
645 else {
646 ttusb->mux_state = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700647 if (ttusb->insync) {
Jarod Wilson68a49a42011-03-24 12:56:16 -0300648 dprintk("%s: %02x\n",
649 __func__, data[-1]);
650 printk(KERN_INFO "%s: lost sync.\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300651 __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700652 ttusb->insync = 0;
653 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700654 }
655 break;
656 case 3:
657 ttusb->insync = 1;
658 len--;
659 ttusb->mux_npacks = *data++;
660 ++ttusb->mux_state;
661 ttusb->muxpack_ptr = 0;
662 /* maximum bytes, until we know the length */
663 ttusb->muxpack_len = 2;
664 break;
665 case 4:
666 {
667 int avail;
668 avail = len;
669 if (avail >
670 (ttusb->muxpack_len -
671 ttusb->muxpack_ptr))
672 avail =
673 ttusb->muxpack_len -
674 ttusb->muxpack_ptr;
675 memcpy(ttusb->muxpack + ttusb->muxpack_ptr,
676 data, avail);
677 ttusb->muxpack_ptr += avail;
Eric Sesterhennae246012006-03-13 13:17:11 -0300678 BUG_ON(ttusb->muxpack_ptr > 264);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700679 data += avail;
680 len -= avail;
681 /* determine length */
682 if (ttusb->muxpack_ptr == 2) {
683 if (ttusb->muxpack[0] & 0x80) {
684 ttusb->muxpack_len =
685 ttusb->muxpack[1] + 2;
686 if (ttusb->
687 muxpack[0] & 0x20)
688 ttusb->
689 muxpack_len++;
690 if ((!!
691 (ttusb->
692 muxpack[0] & 0x20)) ^
693 !!(ttusb->
694 muxpack[1] & 1))
695 ttusb->
696 muxpack_len++;
697 ttusb->muxpack_len += 4;
698 } else if (ttusb->muxpack[0] ==
699 0x47)
700 ttusb->muxpack_len =
701 188 + 4;
702 else if (ttusb->muxpack[0] == 0x00)
703 ttusb->muxpack_len =
704 ttusb->muxpack[1] + 2 +
705 4;
706 else {
707 dprintk
708 ("%s: invalid state: first byte is %x\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300709 __func__,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700710 ttusb->muxpack[0]);
711 ttusb->mux_state = 0;
712 }
713 }
714
715 /**
716 * if length is valid and we reached the end:
717 * goto next muxpack
718 */
719 if ((ttusb->muxpack_ptr >= 2) &&
720 (ttusb->muxpack_ptr ==
721 ttusb->muxpack_len)) {
722 ttusb_process_muxpack(ttusb,
723 ttusb->
724 muxpack,
725 ttusb->
726 muxpack_ptr);
727 ttusb->muxpack_ptr = 0;
728 /* maximum bytes, until we know the length */
729 ttusb->muxpack_len = 2;
730
731 /**
732 * no muxpacks left?
733 * return to search-sync state
734 */
735 if (!ttusb->mux_npacks--) {
736 ttusb->mux_state = 0;
737 break;
738 }
739 }
740 break;
741 }
742 default:
743 BUG();
744 break;
745 }
746 }
747}
748
David Howells7d12e782006-10-05 14:55:46 +0100749static void ttusb_iso_irq(struct urb *urb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700750{
751 struct ttusb *ttusb = urb->context;
Jarod Wilson68a49a42011-03-24 12:56:16 -0300752 struct usb_iso_packet_descriptor *d;
753 u8 *data;
754 int len, i;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700755
756 if (!ttusb->iso_streaming)
757 return;
758
759#if 0
760 printk("%s: status %d, errcount == %d, length == %i\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300761 __func__,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700762 urb->status, urb->error_count, urb->actual_length);
763#endif
764
765 if (!urb->status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700766 for (i = 0; i < urb->number_of_packets; ++i) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700767 numpkt++;
Marcelo Feitoza Parisi4da006c2005-09-09 13:03:15 -0700768 if (time_after_eq(jiffies, lastj + HZ)) {
Jarod Wilson68a49a42011-03-24 12:56:16 -0300769 dprintk("frames/s: %lu (ts: %d, stuff %d, "
770 "sec: %d, invalid: %d, all: %d)\n",
771 numpkt * HZ / (jiffies - lastj),
772 numts, numstuff, numsec, numinvalid,
773 numts + numstuff + numsec + numinvalid);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700774 numts = numstuff = numsec = numinvalid = 0;
775 lastj = jiffies;
776 numpkt = 0;
777 }
778 d = &urb->iso_frame_desc[i];
779 data = urb->transfer_buffer + d->offset;
780 len = d->actual_length;
781 d->actual_length = 0;
782 d->status = 0;
783 ttusb_process_frame(ttusb, data, len);
784 }
785 }
786 usb_submit_urb(urb, GFP_ATOMIC);
787}
788
789static void ttusb_free_iso_urbs(struct ttusb *ttusb)
790{
791 int i;
792
793 for (i = 0; i < ISO_BUF_COUNT; i++)
794 if (ttusb->iso_urb[i])
795 usb_free_urb(ttusb->iso_urb[i]);
796
797 pci_free_consistent(NULL,
798 ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF *
799 ISO_BUF_COUNT, ttusb->iso_buffer,
800 ttusb->iso_dma_handle);
801}
802
803static int ttusb_alloc_iso_urbs(struct ttusb *ttusb)
804{
805 int i;
806
807 ttusb->iso_buffer = pci_alloc_consistent(NULL,
808 ISO_FRAME_SIZE *
809 FRAMES_PER_ISO_BUF *
810 ISO_BUF_COUNT,
811 &ttusb->iso_dma_handle);
812
Douglas Schilling Landgraf11eb2602008-11-11 23:30:49 -0300813 if (!ttusb->iso_buffer) {
814 dprintk("%s: pci_alloc_consistent - not enough memory\n",
815 __func__);
816 return -ENOMEM;
817 }
818
Linus Torvalds1da177e2005-04-16 15:20:36 -0700819 memset(ttusb->iso_buffer, 0,
820 ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF * ISO_BUF_COUNT);
821
822 for (i = 0; i < ISO_BUF_COUNT; i++) {
823 struct urb *urb;
824
825 if (!
826 (urb =
827 usb_alloc_urb(FRAMES_PER_ISO_BUF, GFP_ATOMIC))) {
828 ttusb_free_iso_urbs(ttusb);
829 return -ENOMEM;
830 }
831
832 ttusb->iso_urb[i] = urb;
833 }
834
835 return 0;
836}
837
838static void ttusb_stop_iso_xfer(struct ttusb *ttusb)
839{
840 int i;
841
842 for (i = 0; i < ISO_BUF_COUNT; i++)
843 usb_kill_urb(ttusb->iso_urb[i]);
844
845 ttusb->iso_streaming = 0;
846}
847
848static int ttusb_start_iso_xfer(struct ttusb *ttusb)
849{
850 int i, j, err, buffer_offset = 0;
851
852 if (ttusb->iso_streaming) {
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300853 printk("%s: iso xfer already running!\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700854 return 0;
855 }
856
857 ttusb->cc = -1;
858 ttusb->insync = 0;
859 ttusb->mux_state = 0;
860
861 for (i = 0; i < ISO_BUF_COUNT; i++) {
862 int frame_offset = 0;
863 struct urb *urb = ttusb->iso_urb[i];
864
865 urb->dev = ttusb->dev;
866 urb->context = ttusb;
867 urb->complete = ttusb_iso_irq;
868 urb->pipe = ttusb->isoc_in_pipe;
869 urb->transfer_flags = URB_ISO_ASAP;
870 urb->interval = 1;
871 urb->number_of_packets = FRAMES_PER_ISO_BUF;
872 urb->transfer_buffer_length =
873 ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF;
874 urb->transfer_buffer = ttusb->iso_buffer + buffer_offset;
875 buffer_offset += ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF;
876
877 for (j = 0; j < FRAMES_PER_ISO_BUF; j++) {
878 urb->iso_frame_desc[j].offset = frame_offset;
879 urb->iso_frame_desc[j].length = ISO_FRAME_SIZE;
880 frame_offset += ISO_FRAME_SIZE;
881 }
882 }
883
884 for (i = 0; i < ISO_BUF_COUNT; i++) {
885 if ((err = usb_submit_urb(ttusb->iso_urb[i], GFP_ATOMIC))) {
886 ttusb_stop_iso_xfer(ttusb);
887 printk
888 ("%s: failed urb submission (%i: err = %i)!\n",
Harvey Harrisonfb9393b2008-04-08 23:20:00 -0300889 __func__, i, err);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700890 return err;
891 }
892 }
893
894 ttusb->iso_streaming = 1;
895
896 return 0;
897}
898
899#ifdef TTUSB_HWSECTIONS
900static void ttusb_handle_ts_data(struct dvb_demux_feed *dvbdmxfeed, const u8 * data,
901 int len)
902{
903 dvbdmxfeed->cb.ts(data, len, 0, 0, &dvbdmxfeed->feed.ts, 0);
904}
905
906static void ttusb_handle_sec_data(struct dvb_demux_feed *dvbdmxfeed, const u8 * data,
907 int len)
908{
909// struct dvb_demux_feed *dvbdmxfeed = channel->dvbdmxfeed;
910#error TODO: handle ugly stuff
911// dvbdmxfeed->cb.sec(data, len, 0, 0, &dvbdmxfeed->feed.sec, 0);
912}
913#endif
914
915static int ttusb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
916{
917 struct ttusb *ttusb = (struct ttusb *) dvbdmxfeed->demux;
918 int feed_type = 1;
919
920 dprintk("ttusb_start_feed\n");
921
922 switch (dvbdmxfeed->type) {
923 case DMX_TYPE_TS:
924 break;
925 case DMX_TYPE_SEC:
926 break;
927 default:
928 return -EINVAL;
929 }
930
931 if (dvbdmxfeed->type == DMX_TYPE_TS) {
932 switch (dvbdmxfeed->pes_type) {
Mauro Carvalho Chehabfde04ab2013-04-04 13:25:30 -0300933 case DMX_PES_VIDEO:
934 case DMX_PES_AUDIO:
935 case DMX_PES_TELETEXT:
936 case DMX_PES_PCR:
937 case DMX_PES_OTHER:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700938 break;
939 default:
940 return -EINVAL;
941 }
942 }
943
944#ifdef TTUSB_HWSECTIONS
945#error TODO: allocate filters
946 if (dvbdmxfeed->type == DMX_TYPE_TS) {
947 feed_type = 1;
948 } else if (dvbdmxfeed->type == DMX_TYPE_SEC) {
949 feed_type = 2;
950 }
951#endif
952
953 ttusb_set_channel(ttusb, dvbdmxfeed->index, feed_type, dvbdmxfeed->pid);
954
955 if (0 == ttusb->running_feed_count++)
956 ttusb_start_iso_xfer(ttusb);
957
958 return 0;
959}
960
961static int ttusb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
962{
963 struct ttusb *ttusb = (struct ttusb *) dvbdmxfeed->demux;
964
965 ttusb_del_channel(ttusb, dvbdmxfeed->index);
966
967 if (--ttusb->running_feed_count == 0)
968 ttusb_stop_iso_xfer(ttusb);
969
970 return 0;
971}
972
973static int ttusb_setup_interfaces(struct ttusb *ttusb)
974{
975 usb_set_interface(ttusb->dev, 1, 1);
976
977 ttusb->bulk_out_pipe = usb_sndbulkpipe(ttusb->dev, 1);
978 ttusb->bulk_in_pipe = usb_rcvbulkpipe(ttusb->dev, 1);
979 ttusb->isoc_in_pipe = usb_rcvisocpipe(ttusb->dev, 2);
980
981 return 0;
982}
983
984#if 0
985static u8 stc_firmware[8192];
986
987static int stc_open(struct inode *inode, struct file *file)
988{
989 struct ttusb *ttusb = file->private_data;
990 int addr;
991
992 for (addr = 0; addr < 8192; addr += 16) {
993 u8 snd_buf[2] = { addr >> 8, addr & 0xFF };
994 ttusb_i2c_msg(ttusb, 0x50, snd_buf, 2, stc_firmware + addr,
995 16);
996 }
997
998 return 0;
999}
1000
1001static ssize_t stc_read(struct file *file, char *buf, size_t count,
Akinobu Mitaa8a89b72008-07-04 06:33:20 -03001002 loff_t *offset)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001003{
Akinobu Mitaa8a89b72008-07-04 06:33:20 -03001004 return simple_read_from_buffer(buf, count, offset, stc_firmware, 8192);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001005}
1006
1007static int stc_release(struct inode *inode, struct file *file)
1008{
1009 return 0;
1010}
1011
Jan Engelhardt27a643b2008-04-22 14:42:01 -03001012static const struct file_operations stc_fops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001013 .owner = THIS_MODULE,
1014 .read = stc_read,
1015 .open = stc_open,
1016 .release = stc_release,
1017};
1018#endif
1019
1020static u32 functionality(struct i2c_adapter *adapter)
1021{
1022 return I2C_FUNC_I2C;
1023}
1024
1025
1026
Mauro Carvalho Chehab14d24d12011-12-24 12:24:33 -03001027static int alps_tdmb7_tuner_set_params(struct dvb_frontend *fe)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001028{
Mauro Carvalho Chehab57605c92011-12-23 07:15:40 -03001029 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001030 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1031 u8 data[4];
1032 struct i2c_msg msg = {.addr=0x61, .flags=0, .buf=data, .len=sizeof(data) };
1033 u32 div;
1034
Mauro Carvalho Chehab57605c92011-12-23 07:15:40 -03001035 div = (p->frequency + 36166667) / 166667;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001036
1037 data[0] = (div >> 8) & 0x7f;
1038 data[1] = div & 0xff;
1039 data[2] = ((div >> 10) & 0x60) | 0x85;
Mauro Carvalho Chehab57605c92011-12-23 07:15:40 -03001040 data[3] = p->frequency < 592000000 ? 0x40 : 0x80;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001041
Patrick Boettcherdea74862006-05-14 05:01:31 -03001042 if (fe->ops.i2c_gate_ctrl)
1043 fe->ops.i2c_gate_ctrl(fe, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001044 if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1) return -EIO;
1045 return 0;
1046}
1047
Johannes Stezenbachd91b7302005-05-16 21:54:38 -07001048static struct cx22700_config alps_tdmb7_config = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001049 .demod_address = 0x43,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001050};
1051
1052
1053
1054
1055
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001056static int philips_tdm1316l_tuner_init(struct dvb_frontend* fe)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001057{
1058 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1059 static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab };
1060 static u8 disable_mc44BC374c[] = { 0x1d, 0x74, 0xa0, 0x68 };
1061 struct i2c_msg tuner_msg = { .addr=0x60, .flags=0, .buf=td1316_init, .len=sizeof(td1316_init) };
1062
1063 // setup PLL configuration
Patrick Boettcherdea74862006-05-14 05:01:31 -03001064 if (fe->ops.i2c_gate_ctrl)
1065 fe->ops.i2c_gate_ctrl(fe, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001066 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) return -EIO;
1067 msleep(1);
1068
1069 // disable the mc44BC374c (do not check for errors)
1070 tuner_msg.addr = 0x65;
1071 tuner_msg.buf = disable_mc44BC374c;
1072 tuner_msg.len = sizeof(disable_mc44BC374c);
Patrick Boettcherdea74862006-05-14 05:01:31 -03001073 if (fe->ops.i2c_gate_ctrl)
1074 fe->ops.i2c_gate_ctrl(fe, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001075 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) {
1076 i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1);
1077 }
1078
1079 return 0;
1080}
1081
Mauro Carvalho Chehab14d24d12011-12-24 12:24:33 -03001082static int philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001083{
Mauro Carvalho Chehab57605c92011-12-23 07:15:40 -03001084 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1086 u8 tuner_buf[4];
1087 struct i2c_msg tuner_msg = {.addr=0x60, .flags=0, .buf=tuner_buf, .len=sizeof(tuner_buf) };
1088 int tuner_frequency = 0;
1089 u8 band, cp, filter;
1090
1091 // determine charge pump
Mauro Carvalho Chehab57605c92011-12-23 07:15:40 -03001092 tuner_frequency = p->frequency + 36130000;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001093 if (tuner_frequency < 87000000) return -EINVAL;
1094 else if (tuner_frequency < 130000000) cp = 3;
1095 else if (tuner_frequency < 160000000) cp = 5;
1096 else if (tuner_frequency < 200000000) cp = 6;
1097 else if (tuner_frequency < 290000000) cp = 3;
1098 else if (tuner_frequency < 420000000) cp = 5;
1099 else if (tuner_frequency < 480000000) cp = 6;
1100 else if (tuner_frequency < 620000000) cp = 3;
1101 else if (tuner_frequency < 830000000) cp = 5;
1102 else if (tuner_frequency < 895000000) cp = 7;
1103 else return -EINVAL;
1104
1105 // determine band
Mauro Carvalho Chehab57605c92011-12-23 07:15:40 -03001106 if (p->frequency < 49000000)
1107 return -EINVAL;
1108 else if (p->frequency < 159000000)
1109 band = 1;
1110 else if (p->frequency < 444000000)
1111 band = 2;
1112 else if (p->frequency < 861000000)
1113 band = 4;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001114 else return -EINVAL;
1115
1116 // setup PLL filter
Mauro Carvalho Chehab57605c92011-12-23 07:15:40 -03001117 switch (p->bandwidth_hz) {
1118 case 6000000:
Andrew de Quinceyc10d14d2006-08-08 09:10:08 -03001119 tda1004x_writereg(fe, 0x0C, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001120 filter = 0;
1121 break;
1122
Mauro Carvalho Chehab57605c92011-12-23 07:15:40 -03001123 case 7000000:
Andrew de Quinceyc10d14d2006-08-08 09:10:08 -03001124 tda1004x_writereg(fe, 0x0C, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001125 filter = 0;
1126 break;
1127
Mauro Carvalho Chehab57605c92011-12-23 07:15:40 -03001128 case 8000000:
Andrew de Quinceyc10d14d2006-08-08 09:10:08 -03001129 tda1004x_writereg(fe, 0x0C, 0xFF);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001130 filter = 1;
1131 break;
1132
1133 default:
1134 return -EINVAL;
1135 }
1136
1137 // calculate divisor
1138 // ((36130000+((1000000/6)/2)) + Finput)/(1000000/6)
Mauro Carvalho Chehab57605c92011-12-23 07:15:40 -03001139 tuner_frequency = (((p->frequency / 1000) * 6) + 217280) / 1000;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001140
1141 // setup tuner buffer
1142 tuner_buf[0] = tuner_frequency >> 8;
1143 tuner_buf[1] = tuner_frequency & 0xff;
1144 tuner_buf[2] = 0xca;
1145 tuner_buf[3] = (cp << 5) | (filter << 3) | band;
1146
Patrick Boettcherdea74862006-05-14 05:01:31 -03001147 if (fe->ops.i2c_gate_ctrl)
1148 fe->ops.i2c_gate_ctrl(fe, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001149 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1)
1150 return -EIO;
1151
1152 msleep(1);
1153 return 0;
1154}
1155
1156static int philips_tdm1316l_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
1157{
1158 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1159
1160 return request_firmware(fw, name, &ttusb->dev->dev);
1161}
1162
1163static struct tda1004x_config philips_tdm1316l_config = {
1164
1165 .demod_address = 0x8,
1166 .invert = 1,
1167 .invert_oclk = 0,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001168 .request_firmware = philips_tdm1316l_request_firmware,
1169};
1170
1171static u8 alps_bsbe1_inittab[] = {
Mauro Carvalho Chehab9101e622005-12-12 00:37:24 -08001172 0x01, 0x15,
1173 0x02, 0x30,
1174 0x03, 0x00,
1175 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
1176 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
1177 0x06, 0x40, /* DAC not used, set to high impendance mode */
1178 0x07, 0x00, /* DAC LSB */
1179 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
1180 0x09, 0x00, /* FIFO */
1181 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
1182 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
1183 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
1184 0x10, 0x3f, // AGC2 0x3d
1185 0x11, 0x84,
1186 0x12, 0xb9,
1187 0x15, 0xc9, // lock detector threshold
1188 0x16, 0x00,
1189 0x17, 0x00,
1190 0x18, 0x00,
1191 0x19, 0x00,
1192 0x1a, 0x00,
1193 0x1f, 0x50,
1194 0x20, 0x00,
1195 0x21, 0x00,
1196 0x22, 0x00,
1197 0x23, 0x00,
1198 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
1199 0x29, 0x1e, // 1/2 threshold
1200 0x2a, 0x14, // 2/3 threshold
1201 0x2b, 0x0f, // 3/4 threshold
1202 0x2c, 0x09, // 5/6 threshold
1203 0x2d, 0x05, // 7/8 threshold
1204 0x2e, 0x01,
1205 0x31, 0x1f, // test all FECs
1206 0x32, 0x19, // viterbi and synchro search
1207 0x33, 0xfc, // rs control
1208 0x34, 0x93, // error control
1209 0x0f, 0x92,
1210 0xff, 0xff
Linus Torvalds1da177e2005-04-16 15:20:36 -07001211};
1212
1213static u8 alps_bsru6_inittab[] = {
1214 0x01, 0x15,
1215 0x02, 0x30,
1216 0x03, 0x00,
1217 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
1218 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
1219 0x06, 0x40, /* DAC not used, set to high impendance mode */
1220 0x07, 0x00, /* DAC LSB */
1221 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
1222 0x09, 0x00, /* FIFO */
1223 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
1224 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
1225 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
1226 0x10, 0x3f, // AGC2 0x3d
1227 0x11, 0x84,
Oliver Endriss7f44dcd2005-11-08 21:35:44 -08001228 0x12, 0xb9,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001229 0x15, 0xc9, // lock detector threshold
1230 0x16, 0x00,
1231 0x17, 0x00,
1232 0x18, 0x00,
1233 0x19, 0x00,
1234 0x1a, 0x00,
1235 0x1f, 0x50,
1236 0x20, 0x00,
1237 0x21, 0x00,
1238 0x22, 0x00,
1239 0x23, 0x00,
1240 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
1241 0x29, 0x1e, // 1/2 threshold
1242 0x2a, 0x14, // 2/3 threshold
1243 0x2b, 0x0f, // 3/4 threshold
1244 0x2c, 0x09, // 5/6 threshold
1245 0x2d, 0x05, // 7/8 threshold
1246 0x2e, 0x01,
1247 0x31, 0x1f, // test all FECs
1248 0x32, 0x19, // viterbi and synchro search
1249 0x33, 0xfc, // rs control
1250 0x34, 0x93, // error control
1251 0x0f, 0x52,
1252 0xff, 0xff
1253};
1254
1255static int alps_stv0299_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
1256{
1257 u8 aclk = 0;
1258 u8 bclk = 0;
1259
1260 if (srate < 1500000) {
1261 aclk = 0xb7;
1262 bclk = 0x47;
1263 } else if (srate < 3000000) {
1264 aclk = 0xb7;
1265 bclk = 0x4b;
1266 } else if (srate < 7000000) {
1267 aclk = 0xb7;
1268 bclk = 0x4f;
1269 } else if (srate < 14000000) {
1270 aclk = 0xb7;
1271 bclk = 0x53;
1272 } else if (srate < 30000000) {
1273 aclk = 0xb6;
1274 bclk = 0x53;
1275 } else if (srate < 45000000) {
1276 aclk = 0xb4;
1277 bclk = 0x51;
1278 }
1279
1280 stv0299_writereg(fe, 0x13, aclk);
1281 stv0299_writereg(fe, 0x14, bclk);
1282 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
1283 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
1284 stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
1285
1286 return 0;
1287}
1288
Mauro Carvalho Chehab14d24d12011-12-24 12:24:33 -03001289static int philips_tsa5059_tuner_set_params(struct dvb_frontend *fe)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001290{
Mauro Carvalho Chehab57605c92011-12-23 07:15:40 -03001291 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001292 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1293 u8 buf[4];
1294 u32 div;
1295 struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
1296
Mauro Carvalho Chehab57605c92011-12-23 07:15:40 -03001297 if ((p->frequency < 950000) || (p->frequency > 2150000))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001298 return -EINVAL;
1299
Mauro Carvalho Chehab57605c92011-12-23 07:15:40 -03001300 div = (p->frequency + (125 - 1)) / 125; /* round correctly */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001301 buf[0] = (div >> 8) & 0x7f;
1302 buf[1] = div & 0xff;
1303 buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
1304 buf[3] = 0xC4;
1305
Mauro Carvalho Chehab57605c92011-12-23 07:15:40 -03001306 if (p->frequency > 1530000)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001307 buf[3] = 0xC0;
1308
1309 /* BSBE1 wants XCE bit set */
1310 if (ttusb->revision == TTUSB_REV_2_2)
1311 buf[3] |= 0x20;
1312
Patrick Boettcherdea74862006-05-14 05:01:31 -03001313 if (fe->ops.i2c_gate_ctrl)
1314 fe->ops.i2c_gate_ctrl(fe, 1);
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001315 if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001316 return -EIO;
1317
1318 return 0;
1319}
1320
1321static struct stv0299_config alps_stv0299_config = {
1322 .demod_address = 0x68,
1323 .inittab = alps_bsru6_inittab,
1324 .mclk = 88000000UL,
1325 .invert = 1,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001326 .skip_reinit = 0,
Oliver Endrissda2c7f62008-04-20 22:13:37 -03001327 .lock_output = STV0299_LOCKOUTPUT_1,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001328 .volt13_op0_op1 = STV0299_VOLT13_OP1,
1329 .min_delay_ms = 100,
1330 .set_symbol_rate = alps_stv0299_set_symbol_rate,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001331};
1332
Mauro Carvalho Chehab14d24d12011-12-24 12:24:33 -03001333static int ttusb_novas_grundig_29504_491_tuner_set_params(struct dvb_frontend *fe)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001334{
Mauro Carvalho Chehab57605c92011-12-23 07:15:40 -03001335 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001336 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1337 u8 buf[4];
1338 u32 div;
1339 struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
1340
Mauro Carvalho Chehab57605c92011-12-23 07:15:40 -03001341 div = p->frequency / 125;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001342
1343 buf[0] = (div >> 8) & 0x7f;
1344 buf[1] = div & 0xff;
1345 buf[2] = 0x8e;
1346 buf[3] = 0x00;
1347
Patrick Boettcherdea74862006-05-14 05:01:31 -03001348 if (fe->ops.i2c_gate_ctrl)
1349 fe->ops.i2c_gate_ctrl(fe, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001350 if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1)
1351 return -EIO;
1352
1353 return 0;
1354}
1355
1356static struct tda8083_config ttusb_novas_grundig_29504_491_config = {
1357
1358 .demod_address = 0x68,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001359};
1360
Mauro Carvalho Chehab14d24d12011-12-24 12:24:33 -03001361static int alps_tdbe2_tuner_set_params(struct dvb_frontend *fe)
Gavin Hamill53936392005-07-07 17:58:04 -07001362{
Mauro Carvalho Chehab57605c92011-12-23 07:15:40 -03001363 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
Gavin Hamill53936392005-07-07 17:58:04 -07001364 struct ttusb* ttusb = fe->dvb->priv;
1365 u32 div;
1366 u8 data[4];
1367 struct i2c_msg msg = { .addr = 0x62, .flags = 0, .buf = data, .len = sizeof(data) };
1368
Mauro Carvalho Chehab57605c92011-12-23 07:15:40 -03001369 div = (p->frequency + 35937500 + 31250) / 62500;
Gavin Hamill53936392005-07-07 17:58:04 -07001370
1371 data[0] = (div >> 8) & 0x7f;
1372 data[1] = div & 0xff;
1373 data[2] = 0x85 | ((div >> 10) & 0x60);
Mauro Carvalho Chehab57605c92011-12-23 07:15:40 -03001374 data[3] = (p->frequency < 174000000 ? 0x88 : p->frequency < 470000000 ? 0x84 : 0x81);
Gavin Hamill53936392005-07-07 17:58:04 -07001375
Patrick Boettcherdea74862006-05-14 05:01:31 -03001376 if (fe->ops.i2c_gate_ctrl)
1377 fe->ops.i2c_gate_ctrl(fe, 1);
Gavin Hamill53936392005-07-07 17:58:04 -07001378 if (i2c_transfer (&ttusb->i2c_adap, &msg, 1) != 1)
1379 return -EIO;
1380
1381 return 0;
1382}
1383
1384
1385static struct ves1820_config alps_tdbe2_config = {
1386 .demod_address = 0x09,
1387 .xin = 57840000UL,
1388 .invert = 1,
1389 .selagc = VES1820_SELAGC_SIGNAMPERR,
Gavin Hamill53936392005-07-07 17:58:04 -07001390};
1391
1392static u8 read_pwm(struct ttusb* ttusb)
1393{
1394 u8 b = 0xff;
1395 u8 pwm;
1396 struct i2c_msg msg[] = { { .addr = 0x50,.flags = 0,.buf = &b,.len = 1 },
1397 { .addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1} };
1398
1399 if ((i2c_transfer(&ttusb->i2c_adap, msg, 2) != 2) || (pwm == 0xff))
1400 pwm = 0x48;
1401
1402 return pwm;
1403}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001404
1405
Mauro Carvalho Chehab14d24d12011-12-24 12:24:33 -03001406static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe)
Thomas Kaiserb8d4c232006-04-27 21:45:20 -03001407{
Mauro Carvalho Chehab57605c92011-12-23 07:15:40 -03001408 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
Thomas Kaiserb8d4c232006-04-27 21:45:20 -03001409 struct ttusb *ttusb = (struct ttusb *) fe->dvb->priv;
1410 u8 tuner_buf[5];
1411 struct i2c_msg tuner_msg = {.addr = 0x60,
1412 .flags = 0,
1413 .buf = tuner_buf,
1414 .len = sizeof(tuner_buf) };
1415 int tuner_frequency = 0;
1416 u8 band, cp, filter;
1417
1418 // determine charge pump
Mauro Carvalho Chehab57605c92011-12-23 07:15:40 -03001419 tuner_frequency = p->frequency;
Thomas Kaiserb8d4c232006-04-27 21:45:20 -03001420 if (tuner_frequency < 87000000) {return -EINVAL;}
1421 else if (tuner_frequency < 130000000) {cp = 3; band = 1;}
1422 else if (tuner_frequency < 160000000) {cp = 5; band = 1;}
1423 else if (tuner_frequency < 200000000) {cp = 6; band = 1;}
1424 else if (tuner_frequency < 290000000) {cp = 3; band = 2;}
1425 else if (tuner_frequency < 420000000) {cp = 5; band = 2;}
1426 else if (tuner_frequency < 480000000) {cp = 6; band = 2;}
1427 else if (tuner_frequency < 620000000) {cp = 3; band = 4;}
1428 else if (tuner_frequency < 830000000) {cp = 5; band = 4;}
1429 else if (tuner_frequency < 895000000) {cp = 7; band = 4;}
1430 else {return -EINVAL;}
1431
1432 // assume PLL filter should always be 8MHz for the moment.
1433 filter = 1;
1434
1435 // calculate divisor
1436 // (Finput + Fif)/Fref; Fif = 36125000 Hz, Fref = 62500 Hz
Mauro Carvalho Chehab57605c92011-12-23 07:15:40 -03001437 tuner_frequency = ((p->frequency + 36125000) / 62500);
Thomas Kaiserb8d4c232006-04-27 21:45:20 -03001438
1439 // setup tuner buffer
1440 tuner_buf[0] = tuner_frequency >> 8;
1441 tuner_buf[1] = tuner_frequency & 0xff;
1442 tuner_buf[2] = 0xc8;
1443 tuner_buf[3] = (cp << 5) | (filter << 3) | band;
1444 tuner_buf[4] = 0x80;
1445
Patrick Boettcherdea74862006-05-14 05:01:31 -03001446 if (fe->ops.i2c_gate_ctrl)
1447 fe->ops.i2c_gate_ctrl(fe, 1);
Thomas Kaiserb8d4c232006-04-27 21:45:20 -03001448 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) {
1449 printk("dvb-ttusb-budget: dvbc_philips_tdm1316l_pll_set Error 1\n");
1450 return -EIO;
1451 }
1452
1453 msleep(50);
1454
Patrick Boettcherdea74862006-05-14 05:01:31 -03001455 if (fe->ops.i2c_gate_ctrl)
1456 fe->ops.i2c_gate_ctrl(fe, 1);
Thomas Kaiserb8d4c232006-04-27 21:45:20 -03001457 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) {
1458 printk("dvb-ttusb-budget: dvbc_philips_tdm1316l_pll_set Error 2\n");
1459 return -EIO;
1460 }
1461
1462 msleep(1);
1463
1464 return 0;
1465}
1466
1467static u8 dvbc_philips_tdm1316l_inittab[] = {
1468 0x80, 0x21,
1469 0x80, 0x20,
1470 0x81, 0x01,
1471 0x81, 0x00,
1472 0x00, 0x09,
1473 0x01, 0x69,
1474 0x03, 0x00,
1475 0x04, 0x00,
1476 0x07, 0x00,
1477 0x08, 0x00,
1478 0x20, 0x00,
1479 0x21, 0x40,
1480 0x22, 0x00,
1481 0x23, 0x00,
1482 0x24, 0x40,
1483 0x25, 0x88,
1484 0x30, 0xff,
1485 0x31, 0x00,
1486 0x32, 0xff,
1487 0x33, 0x00,
1488 0x34, 0x50,
1489 0x35, 0x7f,
1490 0x36, 0x00,
1491 0x37, 0x20,
1492 0x38, 0x00,
1493 0x40, 0x1c,
1494 0x41, 0xff,
1495 0x42, 0x29,
1496 0x43, 0x20,
1497 0x44, 0xff,
1498 0x45, 0x00,
1499 0x46, 0x00,
1500 0x49, 0x04,
1501 0x4a, 0xff,
1502 0x4b, 0x7f,
1503 0x52, 0x30,
1504 0x55, 0xae,
1505 0x56, 0x47,
1506 0x57, 0xe1,
1507 0x58, 0x3a,
1508 0x5a, 0x1e,
1509 0x5b, 0x34,
1510 0x60, 0x00,
1511 0x63, 0x00,
1512 0x64, 0x00,
1513 0x65, 0x00,
1514 0x66, 0x00,
1515 0x67, 0x00,
1516 0x68, 0x00,
1517 0x69, 0x00,
1518 0x6a, 0x02,
1519 0x6b, 0x00,
1520 0x70, 0xff,
1521 0x71, 0x00,
1522 0x72, 0x00,
1523 0x73, 0x00,
1524 0x74, 0x0c,
1525 0x80, 0x00,
1526 0x81, 0x00,
1527 0x82, 0x00,
1528 0x83, 0x00,
1529 0x84, 0x04,
1530 0x85, 0x80,
1531 0x86, 0x24,
1532 0x87, 0x78,
1533 0x88, 0x00,
1534 0x89, 0x00,
1535 0x90, 0x01,
1536 0x91, 0x01,
1537 0xa0, 0x00,
1538 0xa1, 0x00,
1539 0xa2, 0x00,
1540 0xb0, 0x91,
1541 0xb1, 0x0b,
1542 0xc0, 0x4b,
1543 0xc1, 0x00,
1544 0xc2, 0x00,
1545 0xd0, 0x00,
1546 0xd1, 0x00,
1547 0xd2, 0x00,
1548 0xd3, 0x00,
1549 0xd4, 0x00,
1550 0xd5, 0x00,
1551 0xde, 0x00,
1552 0xdf, 0x00,
1553 0x61, 0x38,
1554 0x62, 0x0a,
1555 0x53, 0x13,
1556 0x59, 0x08,
1557 0x55, 0x00,
1558 0x56, 0x40,
1559 0x57, 0x08,
1560 0x58, 0x3d,
1561 0x88, 0x10,
1562 0xa0, 0x00,
1563 0xa0, 0x00,
1564 0xa0, 0x00,
1565 0xa0, 0x04,
1566 0xff, 0xff,
1567};
1568
1569static struct stv0297_config dvbc_philips_tdm1316l_config = {
1570 .demod_address = 0x1c,
1571 .inittab = dvbc_philips_tdm1316l_inittab,
1572 .invert = 0,
1573};
1574
Linus Torvalds1da177e2005-04-16 15:20:36 -07001575static void frontend_init(struct ttusb* ttusb)
1576{
1577 switch(le16_to_cpu(ttusb->dev->descriptor.idProduct)) {
1578 case 0x1003: // Hauppauge/TT Nova-USB-S budget (stv0299/ALPS BSRU6|BSBE1(tsa5059))
1579 // try the stv0299 based first
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001580 ttusb->fe = dvb_attach(stv0299_attach, &alps_stv0299_config, &ttusb->i2c_adap);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001581 if (ttusb->fe != NULL) {
Patrick Boettcherdea74862006-05-14 05:01:31 -03001582 ttusb->fe->ops.tuner_ops.set_params = philips_tsa5059_tuner_set_params;
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001583
Linus Torvalds1da177e2005-04-16 15:20:36 -07001584 if(ttusb->revision == TTUSB_REV_2_2) { // ALPS BSBE1
1585 alps_stv0299_config.inittab = alps_bsbe1_inittab;
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001586 dvb_attach(lnbp21_attach, ttusb->fe, &ttusb->i2c_adap, 0, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001587 } else { // ALPS BSRU6
Patrick Boettcherdea74862006-05-14 05:01:31 -03001588 ttusb->fe->ops.set_voltage = ttusb_set_voltage;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001589 }
1590 break;
1591 }
1592
1593 // Grundig 29504-491
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001594 ttusb->fe = dvb_attach(tda8083_attach, &ttusb_novas_grundig_29504_491_config, &ttusb->i2c_adap);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001595 if (ttusb->fe != NULL) {
Patrick Boettcherdea74862006-05-14 05:01:31 -03001596 ttusb->fe->ops.tuner_ops.set_params = ttusb_novas_grundig_29504_491_tuner_set_params;
1597 ttusb->fe->ops.set_voltage = ttusb_set_voltage;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001598 break;
1599 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001600 break;
1601
Gavin Hamill53936392005-07-07 17:58:04 -07001602 case 0x1004: // Hauppauge/TT DVB-C budget (ves1820/ALPS TDBE2(sp5659))
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001603 ttusb->fe = dvb_attach(ves1820_attach, &alps_tdbe2_config, &ttusb->i2c_adap, read_pwm(ttusb));
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001604 if (ttusb->fe != NULL) {
Patrick Boettcherdea74862006-05-14 05:01:31 -03001605 ttusb->fe->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params;
Gavin Hamill53936392005-07-07 17:58:04 -07001606 break;
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001607 }
Thomas Kaiserb8d4c232006-04-27 21:45:20 -03001608
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001609 ttusb->fe = dvb_attach(stv0297_attach, &dvbc_philips_tdm1316l_config, &ttusb->i2c_adap);
Thomas Kaiserb8d4c232006-04-27 21:45:20 -03001610 if (ttusb->fe != NULL) {
Patrick Boettcherdea74862006-05-14 05:01:31 -03001611 ttusb->fe->ops.tuner_ops.set_params = dvbc_philips_tdm1316l_tuner_set_params;
Thomas Kaiserb8d4c232006-04-27 21:45:20 -03001612 break;
1613 }
Gavin Hamill53936392005-07-07 17:58:04 -07001614 break;
1615
Linus Torvalds1da177e2005-04-16 15:20:36 -07001616 case 0x1005: // Hauppauge/TT Nova-USB-t budget (tda10046/Philips td1316(tda6651tt) OR cx22700/ALPS TDMB7(??))
1617 // try the ALPS TDMB7 first
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001618 ttusb->fe = dvb_attach(cx22700_attach, &alps_tdmb7_config, &ttusb->i2c_adap);
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001619 if (ttusb->fe != NULL) {
Patrick Boettcherdea74862006-05-14 05:01:31 -03001620 ttusb->fe->ops.tuner_ops.set_params = alps_tdmb7_tuner_set_params;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001621 break;
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001622 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001623
1624 // Philips td1316
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001625 ttusb->fe = dvb_attach(tda10046_attach, &philips_tdm1316l_config, &ttusb->i2c_adap);
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001626 if (ttusb->fe != NULL) {
Patrick Boettcherdea74862006-05-14 05:01:31 -03001627 ttusb->fe->ops.tuner_ops.init = philips_tdm1316l_tuner_init;
1628 ttusb->fe->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001629 break;
Andrew de Quincey651b81b2006-04-18 17:47:11 -03001630 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001631 break;
1632 }
1633
1634 if (ttusb->fe == NULL) {
Bjorn Helgaas29e66a62008-09-04 17:24:51 -03001635 printk("dvb-ttusb-budget: A frontend driver was not found for device [%04x:%04x]\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001636 le16_to_cpu(ttusb->dev->descriptor.idVendor),
1637 le16_to_cpu(ttusb->dev->descriptor.idProduct));
1638 } else {
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001639 if (dvb_register_frontend(&ttusb->adapter, ttusb->fe)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001640 printk("dvb-ttusb-budget: Frontend registration failed!\n");
Andrew de Quinceyf52a8382006-08-08 09:10:09 -03001641 dvb_frontend_detach(ttusb->fe);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001642 ttusb->fe = NULL;
1643 }
1644 }
1645}
1646
1647
1648
1649static struct i2c_algorithm ttusb_dec_algo = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001650 .master_xfer = master_xfer,
1651 .functionality = functionality,
1652};
1653
1654static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *id)
1655{
1656 struct usb_device *udev;
1657 struct ttusb *ttusb;
1658 int result;
1659
Harvey Harrisonfb9393b2008-04-08 23:20:00 -03001660 dprintk("%s: TTUSB DVB connected\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001661
1662 udev = interface_to_usbdev(intf);
1663
Mauro Carvalho Chehab9101e622005-12-12 00:37:24 -08001664 if (intf->altsetting->desc.bInterfaceNumber != 1) return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001665
Panagiotis Issaris74081872006-01-11 19:40:56 -02001666 if (!(ttusb = kzalloc(sizeof(struct ttusb), GFP_KERNEL)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001667 return -ENOMEM;
1668
Linus Torvalds1da177e2005-04-16 15:20:36 -07001669 ttusb->dev = udev;
1670 ttusb->c = 0;
1671 ttusb->mux_state = 0;
Ingo Molnar3593cab2006-02-07 06:49:14 -02001672 mutex_init(&ttusb->semi2c);
1673
1674 mutex_lock(&ttusb->semi2c);
1675
1676 mutex_init(&ttusb->semusb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001677
1678 ttusb_setup_interfaces(ttusb);
1679
Douglas Schilling Landgrafb7ed7852008-11-11 23:37:39 -03001680 result = ttusb_alloc_iso_urbs(ttusb);
1681 if (result < 0) {
1682 dprintk("%s: ttusb_alloc_iso_urbs - failed\n", __func__);
1683 mutex_unlock(&ttusb->semi2c);
1684 kfree(ttusb);
1685 return result;
1686 }
1687
Linus Torvalds1da177e2005-04-16 15:20:36 -07001688 if (ttusb_init_controller(ttusb))
1689 printk("ttusb_init_controller: error\n");
1690
Ingo Molnar3593cab2006-02-07 06:49:14 -02001691 mutex_unlock(&ttusb->semi2c);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001692
Janne Grunau78e92002008-04-09 19:13:13 -03001693 result = dvb_register_adapter(&ttusb->adapter,
1694 "Technotrend/Hauppauge Nova-USB",
1695 THIS_MODULE, &udev->dev, adapter_nr);
1696 if (result < 0) {
Andrew de Quinceya064fad2006-04-06 17:05:46 -03001697 ttusb_free_iso_urbs(ttusb);
1698 kfree(ttusb);
1699 return result;
1700 }
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001701 ttusb->adapter.priv = ttusb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001702
1703 /* i2c */
1704 memset(&ttusb->i2c_adap, 0, sizeof(struct i2c_adapter));
1705 strcpy(ttusb->i2c_adap.name, "TTUSB DEC");
1706
1707 i2c_set_adapdata(&ttusb->i2c_adap, ttusb);
1708
Linus Torvalds1da177e2005-04-16 15:20:36 -07001709 ttusb->i2c_adap.algo = &ttusb_dec_algo;
1710 ttusb->i2c_adap.algo_data = NULL;
Jean Delvare12a917f2007-02-13 22:09:03 +01001711 ttusb->i2c_adap.dev.parent = &udev->dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001712
1713 result = i2c_add_adapter(&ttusb->i2c_adap);
Jonathan Nieder42702de2011-12-31 08:01:56 -03001714 if (result)
1715 goto err_unregister_adapter;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001716
1717 memset(&ttusb->dvb_demux, 0, sizeof(ttusb->dvb_demux));
1718
1719 ttusb->dvb_demux.dmx.capabilities =
1720 DMX_TS_FILTERING | DMX_SECTION_FILTERING;
1721 ttusb->dvb_demux.priv = NULL;
1722#ifdef TTUSB_HWSECTIONS
1723 ttusb->dvb_demux.filternum = TTUSB_MAXFILTER;
1724#else
1725 ttusb->dvb_demux.filternum = 32;
1726#endif
1727 ttusb->dvb_demux.feednum = TTUSB_MAXCHANNEL;
1728 ttusb->dvb_demux.start_feed = ttusb_start_feed;
1729 ttusb->dvb_demux.stop_feed = ttusb_stop_feed;
1730 ttusb->dvb_demux.write_to_decoder = NULL;
1731
Jonathan Nieder42702de2011-12-31 08:01:56 -03001732 result = dvb_dmx_init(&ttusb->dvb_demux);
1733 if (result < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001734 printk("ttusb_dvb: dvb_dmx_init failed (errno = %d)\n", result);
Jonathan Nieder42702de2011-12-31 08:01:56 -03001735 result = -ENODEV;
1736 goto err_i2c_del_adapter;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001737 }
1738//FIXME dmxdev (nur WAS?)
1739 ttusb->dmxdev.filternum = ttusb->dvb_demux.filternum;
1740 ttusb->dmxdev.demux = &ttusb->dvb_demux.dmx;
1741 ttusb->dmxdev.capabilities = 0;
1742
Jonathan Nieder42702de2011-12-31 08:01:56 -03001743 result = dvb_dmxdev_init(&ttusb->dmxdev, &ttusb->adapter);
1744 if (result < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001745 printk("ttusb_dvb: dvb_dmxdev_init failed (errno = %d)\n",
1746 result);
Jonathan Nieder42702de2011-12-31 08:01:56 -03001747 result = -ENODEV;
1748 goto err_release_dmx;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001749 }
1750
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001751 if (dvb_net_init(&ttusb->adapter, &ttusb->dvbnet, &ttusb->dvb_demux.dmx)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001752 printk("ttusb_dvb: dvb_net_init failed!\n");
Jonathan Nieder42702de2011-12-31 08:01:56 -03001753 result = -ENODEV;
1754 goto err_release_dmxdev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001755 }
1756
Linus Torvalds1da177e2005-04-16 15:20:36 -07001757 usb_set_intfdata(intf, (void *) ttusb);
1758
1759 frontend_init(ttusb);
1760
1761 return 0;
Jonathan Nieder42702de2011-12-31 08:01:56 -03001762
1763err_release_dmxdev:
1764 dvb_dmxdev_release(&ttusb->dmxdev);
1765err_release_dmx:
1766 dvb_dmx_release(&ttusb->dvb_demux);
1767err_i2c_del_adapter:
1768 i2c_del_adapter(&ttusb->i2c_adap);
1769err_unregister_adapter:
1770 dvb_unregister_adapter (&ttusb->adapter);
1771 return result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001772}
1773
1774static void ttusb_disconnect(struct usb_interface *intf)
1775{
1776 struct ttusb *ttusb = usb_get_intfdata(intf);
1777
1778 usb_set_intfdata(intf, NULL);
1779
1780 ttusb->disconnecting = 1;
1781
1782 ttusb_stop_iso_xfer(ttusb);
1783
1784 ttusb->dvb_demux.dmx.close(&ttusb->dvb_demux.dmx);
1785 dvb_net_release(&ttusb->dvbnet);
1786 dvb_dmxdev_release(&ttusb->dmxdev);
1787 dvb_dmx_release(&ttusb->dvb_demux);
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001788 if (ttusb->fe != NULL) {
1789 dvb_unregister_frontend(ttusb->fe);
Andrew de Quinceyf52a8382006-08-08 09:10:09 -03001790 dvb_frontend_detach(ttusb->fe);
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001791 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001792 i2c_del_adapter(&ttusb->i2c_adap);
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001793 dvb_unregister_adapter(&ttusb->adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001794
1795 ttusb_free_iso_urbs(ttusb);
1796
1797 kfree(ttusb);
1798
Harvey Harrisonfb9393b2008-04-08 23:20:00 -03001799 dprintk("%s: TTUSB DVB disconnected\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001800}
1801
1802static struct usb_device_id ttusb_table[] = {
1803 {USB_DEVICE(0xb48, 0x1003)},
Gavin Hamill53936392005-07-07 17:58:04 -07001804 {USB_DEVICE(0xb48, 0x1004)},
Linus Torvalds1da177e2005-04-16 15:20:36 -07001805 {USB_DEVICE(0xb48, 0x1005)},
1806 {}
1807};
1808
1809MODULE_DEVICE_TABLE(usb, ttusb_table);
1810
1811static struct usb_driver ttusb_driver = {
Julian Scheel27b05fd2005-07-12 13:58:39 -07001812 .name = "ttusb",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001813 .probe = ttusb_probe,
1814 .disconnect = ttusb_disconnect,
1815 .id_table = ttusb_table,
1816};
1817
Greg Kroah-Hartmanecb3b2b2011-11-18 09:46:12 -08001818module_usb_driver(ttusb_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001819
1820MODULE_AUTHOR("Holger Waechtler <holger@convergence.de>");
1821MODULE_DESCRIPTION("TTUSB DVB Driver");
1822MODULE_LICENSE("GPL");
David Woodhouse0a2a7362008-05-29 19:50:06 +03001823MODULE_FIRMWARE("ttusb-budget/dspbootcode.bin");