12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2786baecfSMauro Carvalho Chehab /*
3786baecfSMauro Carvalho Chehab * TTUSB DVB driver
4786baecfSMauro Carvalho Chehab *
5786baecfSMauro Carvalho Chehab * Copyright (c) 2002 Holger Waechtler <holger@convergence.de>
6786baecfSMauro Carvalho Chehab * Copyright (c) 2003 Felix Domke <tmbinc@elitedvb.net>
7786baecfSMauro Carvalho Chehab */
8*883c84acSMauro Carvalho Chehab
9*883c84acSMauro Carvalho Chehab #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
10*883c84acSMauro Carvalho Chehab
11786baecfSMauro Carvalho Chehab #include <linux/init.h>
12786baecfSMauro Carvalho Chehab #include <linux/slab.h>
13786baecfSMauro Carvalho Chehab #include <linux/wait.h>
14786baecfSMauro Carvalho Chehab #include <linux/fs.h>
15786baecfSMauro Carvalho Chehab #include <linux/module.h>
16786baecfSMauro Carvalho Chehab #include <linux/usb.h>
17786baecfSMauro Carvalho Chehab #include <linux/delay.h>
18786baecfSMauro Carvalho Chehab #include <linux/time.h>
19786baecfSMauro Carvalho Chehab #include <linux/errno.h>
20786baecfSMauro Carvalho Chehab #include <linux/jiffies.h>
21786baecfSMauro Carvalho Chehab #include <linux/mutex.h>
22786baecfSMauro Carvalho Chehab #include <linux/firmware.h>
23786baecfSMauro Carvalho Chehab
24fada1935SMauro Carvalho Chehab #include <media/dvb_frontend.h>
25fada1935SMauro Carvalho Chehab #include <media/dmxdev.h>
26fada1935SMauro Carvalho Chehab #include <media/dvb_demux.h>
27fada1935SMauro Carvalho Chehab #include <media/dvb_net.h>
28786baecfSMauro Carvalho Chehab #include "ves1820.h"
29786baecfSMauro Carvalho Chehab #include "cx22700.h"
30786baecfSMauro Carvalho Chehab #include "tda1004x.h"
31786baecfSMauro Carvalho Chehab #include "stv0299.h"
32786baecfSMauro Carvalho Chehab #include "tda8083.h"
33786baecfSMauro Carvalho Chehab #include "stv0297.h"
34786baecfSMauro Carvalho Chehab #include "lnbp21.h"
35786baecfSMauro Carvalho Chehab
36786baecfSMauro Carvalho Chehab #include <linux/dvb/frontend.h>
37786baecfSMauro Carvalho Chehab #include <linux/dvb/dmx.h>
38786baecfSMauro Carvalho Chehab #include <linux/pci.h>
39786baecfSMauro Carvalho Chehab
40786baecfSMauro Carvalho Chehab /*
41786baecfSMauro Carvalho Chehab TTUSB_HWSECTIONS:
42786baecfSMauro Carvalho Chehab the DSP supports filtering in hardware, however, since the "muxstream"
43786baecfSMauro Carvalho Chehab is a bit braindead (no matching channel masks or no matching filter mask),
44786baecfSMauro Carvalho Chehab we won't support this - yet. it doesn't event support negative filters,
45786baecfSMauro Carvalho Chehab so the best way is maybe to keep TTUSB_HWSECTIONS undef'd and just
46786baecfSMauro Carvalho Chehab parse TS data. USB bandwidth will be a problem when having large
47786baecfSMauro Carvalho Chehab datastreams, especially for dvb-net, but hey, that's not my problem.
48786baecfSMauro Carvalho Chehab
49786baecfSMauro Carvalho Chehab TTUSB_DISEQC, TTUSB_TONE:
50786baecfSMauro Carvalho Chehab let the STC do the diseqc/tone stuff. this isn't supported at least with
51786baecfSMauro Carvalho Chehab my TTUSB, so let it undef'd unless you want to implement another
52786baecfSMauro Carvalho Chehab frontend. never tested.
53786baecfSMauro Carvalho Chehab
54786baecfSMauro Carvalho Chehab debug:
55786baecfSMauro Carvalho Chehab define it to > 3 for really hardcore debugging. you probably don't want
56786baecfSMauro Carvalho Chehab this unless the device doesn't load at all. > 2 for bandwidth statistics.
57786baecfSMauro Carvalho Chehab */
58786baecfSMauro Carvalho Chehab
59786baecfSMauro Carvalho Chehab static int debug;
60786baecfSMauro Carvalho Chehab module_param(debug, int, 0644);
61786baecfSMauro Carvalho Chehab MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
62786baecfSMauro Carvalho Chehab
63786baecfSMauro Carvalho Chehab DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
64786baecfSMauro Carvalho Chehab
65*883c84acSMauro Carvalho Chehab #define dprintk(fmt, arg...) do { \
66*883c84acSMauro Carvalho Chehab if (debug) \
67*883c84acSMauro Carvalho Chehab printk(KERN_DEBUG pr_fmt("%s: " fmt), \
68*883c84acSMauro Carvalho Chehab __func__, ##arg); \
69*883c84acSMauro Carvalho Chehab } while (0)
70*883c84acSMauro Carvalho Chehab
71786baecfSMauro Carvalho Chehab
72786baecfSMauro Carvalho Chehab #define ISO_BUF_COUNT 4
73786baecfSMauro Carvalho Chehab #define FRAMES_PER_ISO_BUF 4
74786baecfSMauro Carvalho Chehab #define ISO_FRAME_SIZE 912
75786baecfSMauro Carvalho Chehab #define TTUSB_MAXCHANNEL 32
76786baecfSMauro Carvalho Chehab #ifdef TTUSB_HWSECTIONS
77786baecfSMauro Carvalho Chehab #define TTUSB_MAXFILTER 16 /* ??? */
78786baecfSMauro Carvalho Chehab #endif
79786baecfSMauro Carvalho Chehab
80786baecfSMauro Carvalho Chehab #define TTUSB_REV_2_2 0x22
81786baecfSMauro Carvalho Chehab #define TTUSB_BUDGET_NAME "ttusb_stc_fw"
82786baecfSMauro Carvalho Chehab
8336e3cf0cSMauro Carvalho Chehab #define MAX_SEND 0x28
8436e3cf0cSMauro Carvalho Chehab #define MAX_RCV 0x20
8536e3cf0cSMauro Carvalho Chehab
86cba862dcSMauro Carvalho Chehab /*
87786baecfSMauro Carvalho Chehab * since we're casting (struct ttusb*) <-> (struct dvb_demux*) around
88786baecfSMauro Carvalho Chehab * the dvb_demux field must be the first in struct!!
89786baecfSMauro Carvalho Chehab */
90786baecfSMauro Carvalho Chehab struct ttusb {
91786baecfSMauro Carvalho Chehab struct dvb_demux dvb_demux;
92786baecfSMauro Carvalho Chehab struct dmxdev dmxdev;
93786baecfSMauro Carvalho Chehab struct dvb_net dvbnet;
94786baecfSMauro Carvalho Chehab
95786baecfSMauro Carvalho Chehab /* and one for USB access. */
96786baecfSMauro Carvalho Chehab struct mutex semi2c;
97786baecfSMauro Carvalho Chehab struct mutex semusb;
98786baecfSMauro Carvalho Chehab
99786baecfSMauro Carvalho Chehab struct dvb_adapter adapter;
100786baecfSMauro Carvalho Chehab struct usb_device *dev;
101786baecfSMauro Carvalho Chehab
102786baecfSMauro Carvalho Chehab struct i2c_adapter i2c_adap;
103786baecfSMauro Carvalho Chehab
104786baecfSMauro Carvalho Chehab int disconnecting;
105786baecfSMauro Carvalho Chehab int iso_streaming;
106786baecfSMauro Carvalho Chehab
107786baecfSMauro Carvalho Chehab unsigned int bulk_out_pipe;
108786baecfSMauro Carvalho Chehab unsigned int bulk_in_pipe;
109786baecfSMauro Carvalho Chehab unsigned int isoc_in_pipe;
110786baecfSMauro Carvalho Chehab
111786baecfSMauro Carvalho Chehab void *iso_buffer;
112786baecfSMauro Carvalho Chehab
113786baecfSMauro Carvalho Chehab struct urb *iso_urb[ISO_BUF_COUNT];
114786baecfSMauro Carvalho Chehab
115786baecfSMauro Carvalho Chehab int running_feed_count;
116786baecfSMauro Carvalho Chehab int last_channel;
117786baecfSMauro Carvalho Chehab int last_filter;
118786baecfSMauro Carvalho Chehab
119786baecfSMauro Carvalho Chehab u8 c; /* transaction counter, wraps around... */
1200df289a2SMauro Carvalho Chehab enum fe_sec_tone_mode tone;
1210df289a2SMauro Carvalho Chehab enum fe_sec_voltage voltage;
122786baecfSMauro Carvalho Chehab
123786baecfSMauro Carvalho Chehab int mux_state; // 0..2 - MuxSyncWord, 3 - nMuxPacks, 4 - muxpack
124786baecfSMauro Carvalho Chehab u8 mux_npacks;
125786baecfSMauro Carvalho Chehab u8 muxpack[256 + 8];
126786baecfSMauro Carvalho Chehab int muxpack_ptr, muxpack_len;
127786baecfSMauro Carvalho Chehab
128786baecfSMauro Carvalho Chehab int insync;
129786baecfSMauro Carvalho Chehab
130786baecfSMauro Carvalho Chehab int cc; /* MuxCounter - will increment on EVERY MUX PACKET */
131786baecfSMauro Carvalho Chehab /* (including stuffing. yes. really.) */
132786baecfSMauro Carvalho Chehab
13336e3cf0cSMauro Carvalho Chehab u8 send_buf[MAX_SEND];
13436e3cf0cSMauro Carvalho Chehab u8 last_result[MAX_RCV];
135786baecfSMauro Carvalho Chehab
136786baecfSMauro Carvalho Chehab int revision;
137786baecfSMauro Carvalho Chehab
138786baecfSMauro Carvalho Chehab struct dvb_frontend* fe;
139786baecfSMauro Carvalho Chehab };
140786baecfSMauro Carvalho Chehab
ttusb_cmd(struct ttusb * ttusb,u8 * data,int len,int len_result)14136e3cf0cSMauro Carvalho Chehab static int ttusb_cmd(struct ttusb *ttusb, u8 *data, int len, int len_result)
142786baecfSMauro Carvalho Chehab {
143786baecfSMauro Carvalho Chehab int actual_len;
144786baecfSMauro Carvalho Chehab int err;
145786baecfSMauro Carvalho Chehab
146786baecfSMauro Carvalho Chehab if (mutex_lock_interruptible(&ttusb->semusb) < 0)
147786baecfSMauro Carvalho Chehab return -EAGAIN;
148786baecfSMauro Carvalho Chehab
14936e3cf0cSMauro Carvalho Chehab if (debug >= 3)
150*883c84acSMauro Carvalho Chehab dprintk("> %*ph\n", len, data);
15136e3cf0cSMauro Carvalho Chehab
15236e3cf0cSMauro Carvalho Chehab memcpy(data, ttusb->send_buf, len);
15336e3cf0cSMauro Carvalho Chehab
154786baecfSMauro Carvalho Chehab err = usb_bulk_msg(ttusb->dev, ttusb->bulk_out_pipe,
15536e3cf0cSMauro Carvalho Chehab ttusb->send_buf, len, &actual_len, 1000);
156786baecfSMauro Carvalho Chehab if (err != 0) {
157*883c84acSMauro Carvalho Chehab dprintk("usb_bulk_msg(send) failed, err == %i!\n", err);
15836e3cf0cSMauro Carvalho Chehab goto err;
159786baecfSMauro Carvalho Chehab }
160786baecfSMauro Carvalho Chehab if (actual_len != len) {
16136e3cf0cSMauro Carvalho Chehab err = -EIO;
162*883c84acSMauro Carvalho Chehab dprintk("only wrote %d of %d bytes\n",
163786baecfSMauro Carvalho Chehab actual_len, len);
16436e3cf0cSMauro Carvalho Chehab goto err;
165786baecfSMauro Carvalho Chehab }
166786baecfSMauro Carvalho Chehab
167786baecfSMauro Carvalho Chehab err = usb_bulk_msg(ttusb->dev, ttusb->bulk_in_pipe,
16836e3cf0cSMauro Carvalho Chehab ttusb->last_result, MAX_RCV, &actual_len, 1000);
169786baecfSMauro Carvalho Chehab
170786baecfSMauro Carvalho Chehab if (err != 0) {
171*883c84acSMauro Carvalho Chehab pr_err("cmd xter failed, receive error %d\n", err);
17236e3cf0cSMauro Carvalho Chehab goto err;
173786baecfSMauro Carvalho Chehab }
174786baecfSMauro Carvalho Chehab
175786baecfSMauro Carvalho Chehab if (debug >= 3) {
176786baecfSMauro Carvalho Chehab actual_len = ttusb->last_result[3] + 4;
177*883c84acSMauro Carvalho Chehab dprintk("< %*ph\n", actual_len, ttusb->last_result);
178786baecfSMauro Carvalho Chehab }
179786baecfSMauro Carvalho Chehab
18036e3cf0cSMauro Carvalho Chehab if (len_result)
18136e3cf0cSMauro Carvalho Chehab memcpy(ttusb->send_buf, ttusb->last_result, len_result);
182786baecfSMauro Carvalho Chehab
18336e3cf0cSMauro Carvalho Chehab err:
184786baecfSMauro Carvalho Chehab mutex_unlock(&ttusb->semusb);
18536e3cf0cSMauro Carvalho Chehab return err;
186786baecfSMauro Carvalho Chehab }
187786baecfSMauro Carvalho Chehab
ttusb_i2c_msg(struct ttusb * ttusb,u8 addr,u8 * snd_buf,u8 snd_len,u8 * rcv_buf,u8 rcv_len)188786baecfSMauro Carvalho Chehab static int ttusb_i2c_msg(struct ttusb *ttusb,
189786baecfSMauro Carvalho Chehab u8 addr, u8 * snd_buf, u8 snd_len, u8 * rcv_buf,
190786baecfSMauro Carvalho Chehab u8 rcv_len)
191786baecfSMauro Carvalho Chehab {
19236e3cf0cSMauro Carvalho Chehab u8 b[MAX_SEND];
193786baecfSMauro Carvalho Chehab u8 id = ++ttusb->c;
194786baecfSMauro Carvalho Chehab int i, err;
195786baecfSMauro Carvalho Chehab
19636e3cf0cSMauro Carvalho Chehab if (snd_len > MAX_SEND - 7 || rcv_len > MAX_RCV - 7)
197786baecfSMauro Carvalho Chehab return -EINVAL;
198786baecfSMauro Carvalho Chehab
199786baecfSMauro Carvalho Chehab b[0] = 0xaa;
200786baecfSMauro Carvalho Chehab b[1] = id;
201786baecfSMauro Carvalho Chehab b[2] = 0x31;
202786baecfSMauro Carvalho Chehab b[3] = snd_len + 3;
203786baecfSMauro Carvalho Chehab b[4] = addr << 1;
204786baecfSMauro Carvalho Chehab b[5] = snd_len;
205786baecfSMauro Carvalho Chehab b[6] = rcv_len;
206786baecfSMauro Carvalho Chehab
207786baecfSMauro Carvalho Chehab for (i = 0; i < snd_len; i++)
208786baecfSMauro Carvalho Chehab b[7 + i] = snd_buf[i];
209786baecfSMauro Carvalho Chehab
21036e3cf0cSMauro Carvalho Chehab err = ttusb_cmd(ttusb, b, snd_len + 7, MAX_RCV);
211786baecfSMauro Carvalho Chehab
212786baecfSMauro Carvalho Chehab if (err)
213786baecfSMauro Carvalho Chehab return -EREMOTEIO;
214786baecfSMauro Carvalho Chehab
215786baecfSMauro Carvalho Chehab /* check if the i2c transaction was successful */
216786baecfSMauro Carvalho Chehab if ((snd_len != b[5]) || (rcv_len != b[6])) return -EREMOTEIO;
217786baecfSMauro Carvalho Chehab
218786baecfSMauro Carvalho Chehab if (rcv_len > 0) {
219786baecfSMauro Carvalho Chehab
220786baecfSMauro Carvalho Chehab if (err || b[0] != 0x55 || b[1] != id) {
221*883c84acSMauro Carvalho Chehab dprintk("usb_bulk_msg(recv) failed, err == %i, id == %02x, b == ",
222*883c84acSMauro Carvalho Chehab err, id);
223786baecfSMauro Carvalho Chehab return -EREMOTEIO;
224786baecfSMauro Carvalho Chehab }
225786baecfSMauro Carvalho Chehab
226786baecfSMauro Carvalho Chehab for (i = 0; i < rcv_len; i++)
227786baecfSMauro Carvalho Chehab rcv_buf[i] = b[7 + i];
228786baecfSMauro Carvalho Chehab }
229786baecfSMauro Carvalho Chehab
230786baecfSMauro Carvalho Chehab return rcv_len;
231786baecfSMauro Carvalho Chehab }
232786baecfSMauro Carvalho Chehab
master_xfer(struct i2c_adapter * adapter,struct i2c_msg * msg,int num)233786baecfSMauro Carvalho Chehab static int master_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, int num)
234786baecfSMauro Carvalho Chehab {
235786baecfSMauro Carvalho Chehab struct ttusb *ttusb = i2c_get_adapdata(adapter);
236786baecfSMauro Carvalho Chehab int i = 0;
237786baecfSMauro Carvalho Chehab int inc;
238786baecfSMauro Carvalho Chehab
239786baecfSMauro Carvalho Chehab if (mutex_lock_interruptible(&ttusb->semi2c) < 0)
240786baecfSMauro Carvalho Chehab return -EAGAIN;
241786baecfSMauro Carvalho Chehab
242786baecfSMauro Carvalho Chehab while (i < num) {
243786baecfSMauro Carvalho Chehab u8 addr, snd_len, rcv_len, *snd_buf, *rcv_buf;
244786baecfSMauro Carvalho Chehab int err;
245786baecfSMauro Carvalho Chehab
246786baecfSMauro Carvalho Chehab if (num > i + 1 && (msg[i + 1].flags & I2C_M_RD)) {
247786baecfSMauro Carvalho Chehab addr = msg[i].addr;
248786baecfSMauro Carvalho Chehab snd_buf = msg[i].buf;
249786baecfSMauro Carvalho Chehab snd_len = msg[i].len;
250786baecfSMauro Carvalho Chehab rcv_buf = msg[i + 1].buf;
251786baecfSMauro Carvalho Chehab rcv_len = msg[i + 1].len;
252786baecfSMauro Carvalho Chehab inc = 2;
253786baecfSMauro Carvalho Chehab } else {
254786baecfSMauro Carvalho Chehab addr = msg[i].addr;
255786baecfSMauro Carvalho Chehab snd_buf = msg[i].buf;
256786baecfSMauro Carvalho Chehab snd_len = msg[i].len;
257786baecfSMauro Carvalho Chehab rcv_buf = NULL;
258786baecfSMauro Carvalho Chehab rcv_len = 0;
259786baecfSMauro Carvalho Chehab inc = 1;
260786baecfSMauro Carvalho Chehab }
261786baecfSMauro Carvalho Chehab
262786baecfSMauro Carvalho Chehab err = ttusb_i2c_msg(ttusb, addr,
263786baecfSMauro Carvalho Chehab snd_buf, snd_len, rcv_buf, rcv_len);
264786baecfSMauro Carvalho Chehab
265786baecfSMauro Carvalho Chehab if (err < rcv_len) {
266*883c84acSMauro Carvalho Chehab dprintk("i == %i\n", i);
267786baecfSMauro Carvalho Chehab break;
268786baecfSMauro Carvalho Chehab }
269786baecfSMauro Carvalho Chehab
270786baecfSMauro Carvalho Chehab i += inc;
271786baecfSMauro Carvalho Chehab }
272786baecfSMauro Carvalho Chehab
273786baecfSMauro Carvalho Chehab mutex_unlock(&ttusb->semi2c);
274786baecfSMauro Carvalho Chehab return i;
275786baecfSMauro Carvalho Chehab }
276786baecfSMauro Carvalho Chehab
ttusb_boot_dsp(struct ttusb * ttusb)277786baecfSMauro Carvalho Chehab static int ttusb_boot_dsp(struct ttusb *ttusb)
278786baecfSMauro Carvalho Chehab {
279786baecfSMauro Carvalho Chehab const struct firmware *fw;
280786baecfSMauro Carvalho Chehab int i, err;
281786baecfSMauro Carvalho Chehab u8 b[40];
282786baecfSMauro Carvalho Chehab
283786baecfSMauro Carvalho Chehab err = request_firmware(&fw, "ttusb-budget/dspbootcode.bin",
284786baecfSMauro Carvalho Chehab &ttusb->dev->dev);
285786baecfSMauro Carvalho Chehab if (err) {
286*883c84acSMauro Carvalho Chehab pr_err("failed to request firmware\n");
287786baecfSMauro Carvalho Chehab return err;
288786baecfSMauro Carvalho Chehab }
289786baecfSMauro Carvalho Chehab
290786baecfSMauro Carvalho Chehab /* BootBlock */
291786baecfSMauro Carvalho Chehab b[0] = 0xaa;
292786baecfSMauro Carvalho Chehab b[2] = 0x13;
293786baecfSMauro Carvalho Chehab b[3] = 28;
294786baecfSMauro Carvalho Chehab
295786baecfSMauro Carvalho Chehab /* upload dsp code in 32 byte steps (36 didn't work for me ...) */
2963e4d8f48SMauro Carvalho Chehab /* 32 is max packet size, no messages should be split. */
297786baecfSMauro Carvalho Chehab for (i = 0; i < fw->size; i += 28) {
298786baecfSMauro Carvalho Chehab memcpy(&b[4], &fw->data[i], 28);
299786baecfSMauro Carvalho Chehab
300786baecfSMauro Carvalho Chehab b[1] = ++ttusb->c;
301786baecfSMauro Carvalho Chehab
302786baecfSMauro Carvalho Chehab err = ttusb_cmd(ttusb, b, 32, 0);
303786baecfSMauro Carvalho Chehab if (err)
304786baecfSMauro Carvalho Chehab goto done;
305786baecfSMauro Carvalho Chehab }
306786baecfSMauro Carvalho Chehab
307786baecfSMauro Carvalho Chehab /* last block ... */
308786baecfSMauro Carvalho Chehab b[1] = ++ttusb->c;
309786baecfSMauro Carvalho Chehab b[2] = 0x13;
310786baecfSMauro Carvalho Chehab b[3] = 0;
311786baecfSMauro Carvalho Chehab
312786baecfSMauro Carvalho Chehab err = ttusb_cmd(ttusb, b, 4, 0);
313786baecfSMauro Carvalho Chehab if (err)
314786baecfSMauro Carvalho Chehab goto done;
315786baecfSMauro Carvalho Chehab
316786baecfSMauro Carvalho Chehab /* BootEnd */
317786baecfSMauro Carvalho Chehab b[1] = ++ttusb->c;
318786baecfSMauro Carvalho Chehab b[2] = 0x14;
319786baecfSMauro Carvalho Chehab b[3] = 0;
320786baecfSMauro Carvalho Chehab
321786baecfSMauro Carvalho Chehab err = ttusb_cmd(ttusb, b, 4, 0);
322786baecfSMauro Carvalho Chehab
323786baecfSMauro Carvalho Chehab done:
324786baecfSMauro Carvalho Chehab release_firmware(fw);
325786baecfSMauro Carvalho Chehab if (err) {
326*883c84acSMauro Carvalho Chehab dprintk("usb_bulk_msg() failed, return value %i!\n", err);
327786baecfSMauro Carvalho Chehab }
328786baecfSMauro Carvalho Chehab
329786baecfSMauro Carvalho Chehab return err;
330786baecfSMauro Carvalho Chehab }
331786baecfSMauro Carvalho Chehab
ttusb_set_channel(struct ttusb * ttusb,int chan_id,int filter_type,int pid)332786baecfSMauro Carvalho Chehab static int ttusb_set_channel(struct ttusb *ttusb, int chan_id, int filter_type,
333786baecfSMauro Carvalho Chehab int pid)
334786baecfSMauro Carvalho Chehab {
335786baecfSMauro Carvalho Chehab int err;
336786baecfSMauro Carvalho Chehab /* SetChannel */
337786baecfSMauro Carvalho Chehab u8 b[] = { 0xaa, ++ttusb->c, 0x22, 4, chan_id, filter_type,
338786baecfSMauro Carvalho Chehab (pid >> 8) & 0xff, pid & 0xff
339786baecfSMauro Carvalho Chehab };
340786baecfSMauro Carvalho Chehab
341786baecfSMauro Carvalho Chehab err = ttusb_cmd(ttusb, b, sizeof(b), 0);
342786baecfSMauro Carvalho Chehab return err;
343786baecfSMauro Carvalho Chehab }
344786baecfSMauro Carvalho Chehab
ttusb_del_channel(struct ttusb * ttusb,int channel_id)345786baecfSMauro Carvalho Chehab static int ttusb_del_channel(struct ttusb *ttusb, int channel_id)
346786baecfSMauro Carvalho Chehab {
347786baecfSMauro Carvalho Chehab int err;
348786baecfSMauro Carvalho Chehab /* DelChannel */
349786baecfSMauro Carvalho Chehab u8 b[] = { 0xaa, ++ttusb->c, 0x23, 1, channel_id };
350786baecfSMauro Carvalho Chehab
351786baecfSMauro Carvalho Chehab err = ttusb_cmd(ttusb, b, sizeof(b), 0);
352786baecfSMauro Carvalho Chehab return err;
353786baecfSMauro Carvalho Chehab }
354786baecfSMauro Carvalho Chehab
355786baecfSMauro Carvalho Chehab #ifdef TTUSB_HWSECTIONS
ttusb_set_filter(struct ttusb * ttusb,int filter_id,int associated_chan,u8 filter[8],u8 mask[8])356786baecfSMauro Carvalho Chehab static int ttusb_set_filter(struct ttusb *ttusb, int filter_id,
357786baecfSMauro Carvalho Chehab int associated_chan, u8 filter[8], u8 mask[8])
358786baecfSMauro Carvalho Chehab {
359786baecfSMauro Carvalho Chehab int err;
360786baecfSMauro Carvalho Chehab /* SetFilter */
361786baecfSMauro Carvalho Chehab u8 b[] = { 0xaa, 0, 0x24, 0x1a, filter_id, associated_chan,
362786baecfSMauro Carvalho Chehab filter[0], filter[1], filter[2], filter[3],
363786baecfSMauro Carvalho Chehab filter[4], filter[5], filter[6], filter[7],
364786baecfSMauro Carvalho Chehab filter[8], filter[9], filter[10], filter[11],
365786baecfSMauro Carvalho Chehab mask[0], mask[1], mask[2], mask[3],
366786baecfSMauro Carvalho Chehab mask[4], mask[5], mask[6], mask[7],
367786baecfSMauro Carvalho Chehab mask[8], mask[9], mask[10], mask[11]
368786baecfSMauro Carvalho Chehab };
369786baecfSMauro Carvalho Chehab
370786baecfSMauro Carvalho Chehab err = ttusb_cmd(ttusb, b, sizeof(b), 0);
371786baecfSMauro Carvalho Chehab return err;
372786baecfSMauro Carvalho Chehab }
373786baecfSMauro Carvalho Chehab
ttusb_del_filter(struct ttusb * ttusb,int filter_id)374786baecfSMauro Carvalho Chehab static int ttusb_del_filter(struct ttusb *ttusb, int filter_id)
375786baecfSMauro Carvalho Chehab {
376786baecfSMauro Carvalho Chehab int err;
377786baecfSMauro Carvalho Chehab /* DelFilter */
378786baecfSMauro Carvalho Chehab u8 b[] = { 0xaa, ++ttusb->c, 0x25, 1, filter_id };
379786baecfSMauro Carvalho Chehab
380786baecfSMauro Carvalho Chehab err = ttusb_cmd(ttusb, b, sizeof(b), 0);
381786baecfSMauro Carvalho Chehab return err;
382786baecfSMauro Carvalho Chehab }
383786baecfSMauro Carvalho Chehab #endif
384786baecfSMauro Carvalho Chehab
ttusb_init_controller(struct ttusb * ttusb)385786baecfSMauro Carvalho Chehab static int ttusb_init_controller(struct ttusb *ttusb)
386786baecfSMauro Carvalho Chehab {
387786baecfSMauro Carvalho Chehab u8 b0[] = { 0xaa, ++ttusb->c, 0x15, 1, 0 };
388786baecfSMauro Carvalho Chehab u8 b1[] = { 0xaa, ++ttusb->c, 0x15, 1, 1 };
389786baecfSMauro Carvalho Chehab u8 b2[] = { 0xaa, ++ttusb->c, 0x32, 1, 0 };
390786baecfSMauro Carvalho Chehab /* i2c write read: 5 bytes, addr 0x10, 0x02 bytes write, 1 bytes read. */
391786baecfSMauro Carvalho Chehab u8 b3[] =
392786baecfSMauro Carvalho Chehab { 0xaa, ++ttusb->c, 0x31, 5, 0x10, 0x02, 0x01, 0x00, 0x1e };
393786baecfSMauro Carvalho Chehab
394786baecfSMauro Carvalho Chehab u8 get_version[] = { 0xaa, ++ttusb->c, 0x17, 5, 0, 0, 0, 0, 0 };
395786baecfSMauro Carvalho Chehab u8 get_dsp_version[0x20] =
396786baecfSMauro Carvalho Chehab { 0xaa, ++ttusb->c, 0x26, 28, 0, 0, 0, 0, 0 };
397786baecfSMauro Carvalho Chehab int err;
398786baecfSMauro Carvalho Chehab
399786baecfSMauro Carvalho Chehab /* reset board */
400786baecfSMauro Carvalho Chehab if ((err = ttusb_cmd(ttusb, b0, sizeof(b0), 0)))
401786baecfSMauro Carvalho Chehab return err;
402786baecfSMauro Carvalho Chehab
403786baecfSMauro Carvalho Chehab /* reset board (again?) */
404786baecfSMauro Carvalho Chehab if ((err = ttusb_cmd(ttusb, b1, sizeof(b1), 0)))
405786baecfSMauro Carvalho Chehab return err;
406786baecfSMauro Carvalho Chehab
407786baecfSMauro Carvalho Chehab ttusb_boot_dsp(ttusb);
408786baecfSMauro Carvalho Chehab
409786baecfSMauro Carvalho Chehab /* set i2c bit rate */
410786baecfSMauro Carvalho Chehab if ((err = ttusb_cmd(ttusb, b2, sizeof(b2), 0)))
411786baecfSMauro Carvalho Chehab return err;
412786baecfSMauro Carvalho Chehab
41336e3cf0cSMauro Carvalho Chehab if ((err = ttusb_cmd(ttusb, b3, sizeof(b3), 0)))
414786baecfSMauro Carvalho Chehab return err;
415786baecfSMauro Carvalho Chehab
41636e3cf0cSMauro Carvalho Chehab if ((err = ttusb_cmd(ttusb, get_version,
41736e3cf0cSMauro Carvalho Chehab sizeof(get_version), sizeof(get_version))))
418786baecfSMauro Carvalho Chehab return err;
419786baecfSMauro Carvalho Chehab
420*883c84acSMauro Carvalho Chehab dprintk("stc-version: %c%c%c%c%c\n", get_version[4], get_version[5],
421*883c84acSMauro Carvalho Chehab get_version[6], get_version[7], get_version[8]);
422786baecfSMauro Carvalho Chehab
423786baecfSMauro Carvalho Chehab if (memcmp(get_version + 4, "V 0.0", 5) &&
424786baecfSMauro Carvalho Chehab memcmp(get_version + 4, "V 1.1", 5) &&
425786baecfSMauro Carvalho Chehab memcmp(get_version + 4, "V 2.1", 5) &&
426786baecfSMauro Carvalho Chehab memcmp(get_version + 4, "V 2.2", 5)) {
427*883c84acSMauro Carvalho Chehab pr_err("unknown STC version %c%c%c%c%c, please report!\n",
428*883c84acSMauro Carvalho Chehab get_version[4], get_version[5],
429786baecfSMauro Carvalho Chehab get_version[6], get_version[7], get_version[8]);
430786baecfSMauro Carvalho Chehab }
431786baecfSMauro Carvalho Chehab
432786baecfSMauro Carvalho Chehab ttusb->revision = ((get_version[6] - '0') << 4) |
433786baecfSMauro Carvalho Chehab (get_version[8] - '0');
434786baecfSMauro Carvalho Chehab
435786baecfSMauro Carvalho Chehab err =
43636e3cf0cSMauro Carvalho Chehab ttusb_cmd(ttusb, get_dsp_version,
43736e3cf0cSMauro Carvalho Chehab sizeof(get_dsp_version), sizeof(get_dsp_version));
438786baecfSMauro Carvalho Chehab if (err)
439786baecfSMauro Carvalho Chehab return err;
440786baecfSMauro Carvalho Chehab
441*883c84acSMauro Carvalho Chehab pr_info("dsp-version: %c%c%c\n",
442786baecfSMauro Carvalho Chehab get_dsp_version[4], get_dsp_version[5], get_dsp_version[6]);
443786baecfSMauro Carvalho Chehab return 0;
444786baecfSMauro Carvalho Chehab }
445786baecfSMauro Carvalho Chehab
446786baecfSMauro Carvalho Chehab #ifdef TTUSB_DISEQC
ttusb_send_diseqc(struct dvb_frontend * fe,const struct dvb_diseqc_master_cmd * cmd)447786baecfSMauro Carvalho Chehab static int ttusb_send_diseqc(struct dvb_frontend* fe,
448786baecfSMauro Carvalho Chehab const struct dvb_diseqc_master_cmd *cmd)
449786baecfSMauro Carvalho Chehab {
450786baecfSMauro Carvalho Chehab struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
451786baecfSMauro Carvalho Chehab u8 b[12] = { 0xaa, ++ttusb->c, 0x18 };
452786baecfSMauro Carvalho Chehab
453786baecfSMauro Carvalho Chehab int err;
454786baecfSMauro Carvalho Chehab
455786baecfSMauro Carvalho Chehab b[3] = 4 + 2 + cmd->msg_len;
456786baecfSMauro Carvalho Chehab b[4] = 0xFF; /* send diseqc master, not burst */
457786baecfSMauro Carvalho Chehab b[5] = cmd->msg_len;
458786baecfSMauro Carvalho Chehab
459786baecfSMauro Carvalho Chehab memcpy(b + 5, cmd->msg, cmd->msg_len);
460786baecfSMauro Carvalho Chehab
461786baecfSMauro Carvalho Chehab /* Diseqc */
462786baecfSMauro Carvalho Chehab if ((err = ttusb_cmd(ttusb, b, 4 + b[3], 0))) {
463*883c84acSMauro Carvalho Chehab dprintk("usb_bulk_msg() failed, return value %i!\n", err);
464786baecfSMauro Carvalho Chehab }
465786baecfSMauro Carvalho Chehab
466786baecfSMauro Carvalho Chehab return err;
467786baecfSMauro Carvalho Chehab }
468786baecfSMauro Carvalho Chehab #endif
469786baecfSMauro Carvalho Chehab
ttusb_update_lnb(struct ttusb * ttusb)470786baecfSMauro Carvalho Chehab static int ttusb_update_lnb(struct ttusb *ttusb)
471786baecfSMauro Carvalho Chehab {
472786baecfSMauro Carvalho Chehab u8 b[] = { 0xaa, ++ttusb->c, 0x16, 5, /*power: */ 1,
473786baecfSMauro Carvalho Chehab ttusb->voltage == SEC_VOLTAGE_18 ? 0 : 1,
474786baecfSMauro Carvalho Chehab ttusb->tone == SEC_TONE_ON ? 1 : 0, 1, 1
475786baecfSMauro Carvalho Chehab };
476786baecfSMauro Carvalho Chehab int err;
477786baecfSMauro Carvalho Chehab
478786baecfSMauro Carvalho Chehab /* SetLNB */
479786baecfSMauro Carvalho Chehab if ((err = ttusb_cmd(ttusb, b, sizeof(b), 0))) {
480*883c84acSMauro Carvalho Chehab dprintk("usb_bulk_msg() failed, return value %i!\n", err);
481786baecfSMauro Carvalho Chehab }
482786baecfSMauro Carvalho Chehab
483786baecfSMauro Carvalho Chehab return err;
484786baecfSMauro Carvalho Chehab }
485786baecfSMauro Carvalho Chehab
ttusb_set_voltage(struct dvb_frontend * fe,enum fe_sec_voltage voltage)4860df289a2SMauro Carvalho Chehab static int ttusb_set_voltage(struct dvb_frontend *fe,
4870df289a2SMauro Carvalho Chehab enum fe_sec_voltage voltage)
488786baecfSMauro Carvalho Chehab {
489786baecfSMauro Carvalho Chehab struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
490786baecfSMauro Carvalho Chehab
491786baecfSMauro Carvalho Chehab ttusb->voltage = voltage;
492786baecfSMauro Carvalho Chehab return ttusb_update_lnb(ttusb);
493786baecfSMauro Carvalho Chehab }
494786baecfSMauro Carvalho Chehab
495786baecfSMauro Carvalho Chehab #ifdef TTUSB_TONE
ttusb_set_tone(struct dvb_frontend * fe,enum fe_sec_tone_mode tone)4960df289a2SMauro Carvalho Chehab static int ttusb_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone)
497786baecfSMauro Carvalho Chehab {
498786baecfSMauro Carvalho Chehab struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
499786baecfSMauro Carvalho Chehab
500786baecfSMauro Carvalho Chehab ttusb->tone = tone;
501786baecfSMauro Carvalho Chehab return ttusb_update_lnb(ttusb);
502786baecfSMauro Carvalho Chehab }
503786baecfSMauro Carvalho Chehab #endif
504786baecfSMauro Carvalho Chehab
505786baecfSMauro Carvalho Chehab
506786baecfSMauro Carvalho Chehab #if 0
507786baecfSMauro Carvalho Chehab static void ttusb_set_led_freq(struct ttusb *ttusb, u8 freq)
508786baecfSMauro Carvalho Chehab {
509786baecfSMauro Carvalho Chehab u8 b[] = { 0xaa, ++ttusb->c, 0x19, 1, freq };
510786baecfSMauro Carvalho Chehab int err, actual_len;
511786baecfSMauro Carvalho Chehab
512786baecfSMauro Carvalho Chehab err = ttusb_cmd(ttusb, b, sizeof(b), 0);
513786baecfSMauro Carvalho Chehab if (err) {
514*883c84acSMauro Carvalho Chehab dprintk("usb_bulk_msg() failed, return value %i!\n", err);
515786baecfSMauro Carvalho Chehab }
516786baecfSMauro Carvalho Chehab }
517786baecfSMauro Carvalho Chehab #endif
518786baecfSMauro Carvalho Chehab
519786baecfSMauro Carvalho Chehab /*****************************************************************************/
520786baecfSMauro Carvalho Chehab
521786baecfSMauro Carvalho Chehab #ifdef TTUSB_HWSECTIONS
522786baecfSMauro Carvalho Chehab static void ttusb_handle_ts_data(struct ttusb_channel *channel,
523786baecfSMauro Carvalho Chehab const u8 * data, int len);
524786baecfSMauro Carvalho Chehab static void ttusb_handle_sec_data(struct ttusb_channel *channel,
525786baecfSMauro Carvalho Chehab const u8 * data, int len);
526786baecfSMauro Carvalho Chehab #endif
527786baecfSMauro Carvalho Chehab
528786baecfSMauro Carvalho Chehab static int numpkt, numts, numstuff, numsec, numinvalid;
529786baecfSMauro Carvalho Chehab static unsigned long lastj;
530786baecfSMauro Carvalho Chehab
ttusb_process_muxpack(struct ttusb * ttusb,const u8 * muxpack,int len)531786baecfSMauro Carvalho Chehab static void ttusb_process_muxpack(struct ttusb *ttusb, const u8 * muxpack,
532786baecfSMauro Carvalho Chehab int len)
533786baecfSMauro Carvalho Chehab {
534786baecfSMauro Carvalho Chehab u16 csum = 0, cc;
535786baecfSMauro Carvalho Chehab int i;
536bf5bbed1SDan Carpenter
537bf5bbed1SDan Carpenter if (len < 4 || len & 0x1) {
538*883c84acSMauro Carvalho Chehab pr_warn("muxpack has invalid len %d\n", len);
539bf5bbed1SDan Carpenter numinvalid++;
540bf5bbed1SDan Carpenter return;
541bf5bbed1SDan Carpenter }
542bf5bbed1SDan Carpenter
543786baecfSMauro Carvalho Chehab for (i = 0; i < len; i += 2)
544786baecfSMauro Carvalho Chehab csum ^= le16_to_cpup((__le16 *) (muxpack + i));
545786baecfSMauro Carvalho Chehab if (csum) {
546*883c84acSMauro Carvalho Chehab pr_warn("muxpack with incorrect checksum, ignoring\n");
547786baecfSMauro Carvalho Chehab numinvalid++;
548786baecfSMauro Carvalho Chehab return;
549786baecfSMauro Carvalho Chehab }
550786baecfSMauro Carvalho Chehab
551786baecfSMauro Carvalho Chehab cc = (muxpack[len - 4] << 8) | muxpack[len - 3];
552786baecfSMauro Carvalho Chehab cc &= 0x7FFF;
553786baecfSMauro Carvalho Chehab if ((cc != ttusb->cc) && (ttusb->cc != -1))
554*883c84acSMauro Carvalho Chehab pr_warn("cc discontinuity (%d frames missing)\n",
555*883c84acSMauro Carvalho Chehab (cc - ttusb->cc) & 0x7FFF);
556786baecfSMauro Carvalho Chehab ttusb->cc = (cc + 1) & 0x7FFF;
557786baecfSMauro Carvalho Chehab if (muxpack[0] & 0x80) {
558786baecfSMauro Carvalho Chehab #ifdef TTUSB_HWSECTIONS
559786baecfSMauro Carvalho Chehab /* section data */
560786baecfSMauro Carvalho Chehab int pusi = muxpack[0] & 0x40;
561786baecfSMauro Carvalho Chehab int channel = muxpack[0] & 0x1F;
562786baecfSMauro Carvalho Chehab int payload = muxpack[1];
563786baecfSMauro Carvalho Chehab const u8 *data = muxpack + 2;
564786baecfSMauro Carvalho Chehab /* check offset flag */
565786baecfSMauro Carvalho Chehab if (muxpack[0] & 0x20)
566786baecfSMauro Carvalho Chehab data++;
567786baecfSMauro Carvalho Chehab
568786baecfSMauro Carvalho Chehab ttusb_handle_sec_data(ttusb->channel + channel, data,
569786baecfSMauro Carvalho Chehab payload);
570786baecfSMauro Carvalho Chehab data += payload;
571786baecfSMauro Carvalho Chehab
572786baecfSMauro Carvalho Chehab if ((!!(ttusb->muxpack[0] & 0x20)) ^
573786baecfSMauro Carvalho Chehab !!(ttusb->muxpack[1] & 1))
574786baecfSMauro Carvalho Chehab data++;
575786baecfSMauro Carvalho Chehab #warning TODO: pusi
576*883c84acSMauro Carvalho Chehab dprintk("cc: %04x\n", (data[0] << 8) | data[1]);
577786baecfSMauro Carvalho Chehab #endif
578786baecfSMauro Carvalho Chehab numsec++;
579786baecfSMauro Carvalho Chehab } else if (muxpack[0] == 0x47) {
580786baecfSMauro Carvalho Chehab #ifdef TTUSB_HWSECTIONS
581786baecfSMauro Carvalho Chehab /* we have TS data here! */
582786baecfSMauro Carvalho Chehab int pid = ((muxpack[1] & 0x0F) << 8) | muxpack[2];
583786baecfSMauro Carvalho Chehab int channel;
584786baecfSMauro Carvalho Chehab for (channel = 0; channel < TTUSB_MAXCHANNEL; ++channel)
585786baecfSMauro Carvalho Chehab if (ttusb->channel[channel].active
586786baecfSMauro Carvalho Chehab && (pid == ttusb->channel[channel].pid))
587786baecfSMauro Carvalho Chehab ttusb_handle_ts_data(ttusb->channel +
588786baecfSMauro Carvalho Chehab channel, muxpack,
589786baecfSMauro Carvalho Chehab 188);
590786baecfSMauro Carvalho Chehab #endif
591786baecfSMauro Carvalho Chehab numts++;
592786baecfSMauro Carvalho Chehab dvb_dmx_swfilter_packets(&ttusb->dvb_demux, muxpack, 1);
593786baecfSMauro Carvalho Chehab } else if (muxpack[0] != 0) {
594786baecfSMauro Carvalho Chehab numinvalid++;
595*883c84acSMauro Carvalho Chehab pr_err("illegal muxpack type %02x\n", muxpack[0]);
596786baecfSMauro Carvalho Chehab } else
597786baecfSMauro Carvalho Chehab numstuff++;
598786baecfSMauro Carvalho Chehab }
599786baecfSMauro Carvalho Chehab
ttusb_process_frame(struct ttusb * ttusb,u8 * data,int len)600786baecfSMauro Carvalho Chehab static void ttusb_process_frame(struct ttusb *ttusb, u8 * data, int len)
601786baecfSMauro Carvalho Chehab {
602786baecfSMauro Carvalho Chehab int maxwork = 1024;
603786baecfSMauro Carvalho Chehab while (len) {
604786baecfSMauro Carvalho Chehab if (!(maxwork--)) {
605*883c84acSMauro Carvalho Chehab pr_err("too much work\n");
606786baecfSMauro Carvalho Chehab break;
607786baecfSMauro Carvalho Chehab }
608786baecfSMauro Carvalho Chehab
609786baecfSMauro Carvalho Chehab switch (ttusb->mux_state) {
610786baecfSMauro Carvalho Chehab case 0:
611786baecfSMauro Carvalho Chehab case 1:
612786baecfSMauro Carvalho Chehab case 2:
613786baecfSMauro Carvalho Chehab len--;
614786baecfSMauro Carvalho Chehab if (*data++ == 0xAA)
615786baecfSMauro Carvalho Chehab ++ttusb->mux_state;
616786baecfSMauro Carvalho Chehab else {
617786baecfSMauro Carvalho Chehab ttusb->mux_state = 0;
618786baecfSMauro Carvalho Chehab if (ttusb->insync) {
619*883c84acSMauro Carvalho Chehab pr_info("lost sync.\n");
620786baecfSMauro Carvalho Chehab ttusb->insync = 0;
621786baecfSMauro Carvalho Chehab }
622786baecfSMauro Carvalho Chehab }
623786baecfSMauro Carvalho Chehab break;
624786baecfSMauro Carvalho Chehab case 3:
625786baecfSMauro Carvalho Chehab ttusb->insync = 1;
626786baecfSMauro Carvalho Chehab len--;
627786baecfSMauro Carvalho Chehab ttusb->mux_npacks = *data++;
628786baecfSMauro Carvalho Chehab ++ttusb->mux_state;
629786baecfSMauro Carvalho Chehab ttusb->muxpack_ptr = 0;
630786baecfSMauro Carvalho Chehab /* maximum bytes, until we know the length */
631786baecfSMauro Carvalho Chehab ttusb->muxpack_len = 2;
632786baecfSMauro Carvalho Chehab break;
633786baecfSMauro Carvalho Chehab case 4:
634786baecfSMauro Carvalho Chehab {
635786baecfSMauro Carvalho Chehab int avail;
636786baecfSMauro Carvalho Chehab avail = len;
637786baecfSMauro Carvalho Chehab if (avail >
638786baecfSMauro Carvalho Chehab (ttusb->muxpack_len -
639786baecfSMauro Carvalho Chehab ttusb->muxpack_ptr))
640786baecfSMauro Carvalho Chehab avail =
641786baecfSMauro Carvalho Chehab ttusb->muxpack_len -
642786baecfSMauro Carvalho Chehab ttusb->muxpack_ptr;
643786baecfSMauro Carvalho Chehab memcpy(ttusb->muxpack + ttusb->muxpack_ptr,
644786baecfSMauro Carvalho Chehab data, avail);
645786baecfSMauro Carvalho Chehab ttusb->muxpack_ptr += avail;
646786baecfSMauro Carvalho Chehab BUG_ON(ttusb->muxpack_ptr > 264);
647786baecfSMauro Carvalho Chehab data += avail;
648786baecfSMauro Carvalho Chehab len -= avail;
649786baecfSMauro Carvalho Chehab /* determine length */
650786baecfSMauro Carvalho Chehab if (ttusb->muxpack_ptr == 2) {
651786baecfSMauro Carvalho Chehab if (ttusb->muxpack[0] & 0x80) {
652786baecfSMauro Carvalho Chehab ttusb->muxpack_len =
653786baecfSMauro Carvalho Chehab ttusb->muxpack[1] + 2;
654786baecfSMauro Carvalho Chehab if (ttusb->
655786baecfSMauro Carvalho Chehab muxpack[0] & 0x20)
656786baecfSMauro Carvalho Chehab ttusb->
657786baecfSMauro Carvalho Chehab muxpack_len++;
658786baecfSMauro Carvalho Chehab if ((!!
659786baecfSMauro Carvalho Chehab (ttusb->
660786baecfSMauro Carvalho Chehab muxpack[0] & 0x20)) ^
661786baecfSMauro Carvalho Chehab !!(ttusb->
662786baecfSMauro Carvalho Chehab muxpack[1] & 1))
663786baecfSMauro Carvalho Chehab ttusb->
664786baecfSMauro Carvalho Chehab muxpack_len++;
665786baecfSMauro Carvalho Chehab ttusb->muxpack_len += 4;
666786baecfSMauro Carvalho Chehab } else if (ttusb->muxpack[0] ==
667786baecfSMauro Carvalho Chehab 0x47)
668786baecfSMauro Carvalho Chehab ttusb->muxpack_len =
669786baecfSMauro Carvalho Chehab 188 + 4;
670786baecfSMauro Carvalho Chehab else if (ttusb->muxpack[0] == 0x00)
671786baecfSMauro Carvalho Chehab ttusb->muxpack_len =
672786baecfSMauro Carvalho Chehab ttusb->muxpack[1] + 2 +
673786baecfSMauro Carvalho Chehab 4;
674786baecfSMauro Carvalho Chehab else {
675*883c84acSMauro Carvalho Chehab dprintk("invalid state: first byte is %x\n",
676786baecfSMauro Carvalho Chehab ttusb->muxpack[0]);
677786baecfSMauro Carvalho Chehab ttusb->mux_state = 0;
678786baecfSMauro Carvalho Chehab }
679786baecfSMauro Carvalho Chehab }
680786baecfSMauro Carvalho Chehab
681cba862dcSMauro Carvalho Chehab /*
682786baecfSMauro Carvalho Chehab * if length is valid and we reached the end:
683786baecfSMauro Carvalho Chehab * goto next muxpack
684786baecfSMauro Carvalho Chehab */
685786baecfSMauro Carvalho Chehab if ((ttusb->muxpack_ptr >= 2) &&
686786baecfSMauro Carvalho Chehab (ttusb->muxpack_ptr ==
687786baecfSMauro Carvalho Chehab ttusb->muxpack_len)) {
688786baecfSMauro Carvalho Chehab ttusb_process_muxpack(ttusb,
689786baecfSMauro Carvalho Chehab ttusb->
690786baecfSMauro Carvalho Chehab muxpack,
691786baecfSMauro Carvalho Chehab ttusb->
692786baecfSMauro Carvalho Chehab muxpack_ptr);
693786baecfSMauro Carvalho Chehab ttusb->muxpack_ptr = 0;
694786baecfSMauro Carvalho Chehab /* maximum bytes, until we know the length */
695786baecfSMauro Carvalho Chehab ttusb->muxpack_len = 2;
696786baecfSMauro Carvalho Chehab
697cba862dcSMauro Carvalho Chehab /*
698786baecfSMauro Carvalho Chehab * no muxpacks left?
699786baecfSMauro Carvalho Chehab * return to search-sync state
700786baecfSMauro Carvalho Chehab */
701786baecfSMauro Carvalho Chehab if (!ttusb->mux_npacks--) {
702786baecfSMauro Carvalho Chehab ttusb->mux_state = 0;
703786baecfSMauro Carvalho Chehab break;
704786baecfSMauro Carvalho Chehab }
705786baecfSMauro Carvalho Chehab }
706786baecfSMauro Carvalho Chehab break;
707786baecfSMauro Carvalho Chehab }
708786baecfSMauro Carvalho Chehab default:
709786baecfSMauro Carvalho Chehab BUG();
710786baecfSMauro Carvalho Chehab break;
711786baecfSMauro Carvalho Chehab }
712786baecfSMauro Carvalho Chehab }
713786baecfSMauro Carvalho Chehab }
714786baecfSMauro Carvalho Chehab
ttusb_iso_irq(struct urb * urb)715786baecfSMauro Carvalho Chehab static void ttusb_iso_irq(struct urb *urb)
716786baecfSMauro Carvalho Chehab {
717786baecfSMauro Carvalho Chehab struct ttusb *ttusb = urb->context;
718786baecfSMauro Carvalho Chehab struct usb_iso_packet_descriptor *d;
719786baecfSMauro Carvalho Chehab u8 *data;
720786baecfSMauro Carvalho Chehab int len, i;
721786baecfSMauro Carvalho Chehab
722786baecfSMauro Carvalho Chehab if (!ttusb->iso_streaming)
723786baecfSMauro Carvalho Chehab return;
724786baecfSMauro Carvalho Chehab
725786baecfSMauro Carvalho Chehab if (!urb->status) {
726786baecfSMauro Carvalho Chehab for (i = 0; i < urb->number_of_packets; ++i) {
727786baecfSMauro Carvalho Chehab numpkt++;
728786baecfSMauro Carvalho Chehab if (time_after_eq(jiffies, lastj + HZ)) {
72980ebec68SMauro Carvalho Chehab dprintk("frames/s: %lu (ts: %d, stuff %d, sec: %d, invalid: %d, all: %d)\n",
730786baecfSMauro Carvalho Chehab numpkt * HZ / (jiffies - lastj),
731786baecfSMauro Carvalho Chehab numts, numstuff, numsec, numinvalid,
732786baecfSMauro Carvalho Chehab numts + numstuff + numsec + numinvalid);
733786baecfSMauro Carvalho Chehab numts = numstuff = numsec = numinvalid = 0;
734786baecfSMauro Carvalho Chehab lastj = jiffies;
735786baecfSMauro Carvalho Chehab numpkt = 0;
736786baecfSMauro Carvalho Chehab }
737786baecfSMauro Carvalho Chehab d = &urb->iso_frame_desc[i];
738786baecfSMauro Carvalho Chehab data = urb->transfer_buffer + d->offset;
739786baecfSMauro Carvalho Chehab len = d->actual_length;
740786baecfSMauro Carvalho Chehab d->actual_length = 0;
741786baecfSMauro Carvalho Chehab d->status = 0;
742786baecfSMauro Carvalho Chehab ttusb_process_frame(ttusb, data, len);
743786baecfSMauro Carvalho Chehab }
744786baecfSMauro Carvalho Chehab }
745786baecfSMauro Carvalho Chehab usb_submit_urb(urb, GFP_ATOMIC);
746786baecfSMauro Carvalho Chehab }
747786baecfSMauro Carvalho Chehab
ttusb_free_iso_urbs(struct ttusb * ttusb)748786baecfSMauro Carvalho Chehab static void ttusb_free_iso_urbs(struct ttusb *ttusb)
749786baecfSMauro Carvalho Chehab {
750786baecfSMauro Carvalho Chehab int i;
751786baecfSMauro Carvalho Chehab
752786baecfSMauro Carvalho Chehab for (i = 0; i < ISO_BUF_COUNT; i++)
753786baecfSMauro Carvalho Chehab usb_free_urb(ttusb->iso_urb[i]);
754894f3009SChristoph Hellwig kfree(ttusb->iso_buffer);
755786baecfSMauro Carvalho Chehab }
756786baecfSMauro Carvalho Chehab
ttusb_alloc_iso_urbs(struct ttusb * ttusb)757786baecfSMauro Carvalho Chehab static int ttusb_alloc_iso_urbs(struct ttusb *ttusb)
758786baecfSMauro Carvalho Chehab {
759786baecfSMauro Carvalho Chehab int i;
760786baecfSMauro Carvalho Chehab
761894f3009SChristoph Hellwig ttusb->iso_buffer = kcalloc(FRAMES_PER_ISO_BUF * ISO_BUF_COUNT,
762894f3009SChristoph Hellwig ISO_FRAME_SIZE, GFP_KERNEL);
763894f3009SChristoph Hellwig if (!ttusb->iso_buffer)
764786baecfSMauro Carvalho Chehab return -ENOMEM;
765786baecfSMauro Carvalho Chehab
766786baecfSMauro Carvalho Chehab for (i = 0; i < ISO_BUF_COUNT; i++) {
767786baecfSMauro Carvalho Chehab struct urb *urb;
768786baecfSMauro Carvalho Chehab
769786baecfSMauro Carvalho Chehab if (!
770786baecfSMauro Carvalho Chehab (urb =
771786baecfSMauro Carvalho Chehab usb_alloc_urb(FRAMES_PER_ISO_BUF, GFP_ATOMIC))) {
772786baecfSMauro Carvalho Chehab ttusb_free_iso_urbs(ttusb);
773786baecfSMauro Carvalho Chehab return -ENOMEM;
774786baecfSMauro Carvalho Chehab }
775786baecfSMauro Carvalho Chehab
776786baecfSMauro Carvalho Chehab ttusb->iso_urb[i] = urb;
777786baecfSMauro Carvalho Chehab }
778786baecfSMauro Carvalho Chehab
779786baecfSMauro Carvalho Chehab return 0;
780786baecfSMauro Carvalho Chehab }
781786baecfSMauro Carvalho Chehab
ttusb_stop_iso_xfer(struct ttusb * ttusb)782786baecfSMauro Carvalho Chehab static void ttusb_stop_iso_xfer(struct ttusb *ttusb)
783786baecfSMauro Carvalho Chehab {
784786baecfSMauro Carvalho Chehab int i;
785786baecfSMauro Carvalho Chehab
786786baecfSMauro Carvalho Chehab for (i = 0; i < ISO_BUF_COUNT; i++)
787786baecfSMauro Carvalho Chehab usb_kill_urb(ttusb->iso_urb[i]);
788786baecfSMauro Carvalho Chehab
789786baecfSMauro Carvalho Chehab ttusb->iso_streaming = 0;
790786baecfSMauro Carvalho Chehab }
791786baecfSMauro Carvalho Chehab
ttusb_start_iso_xfer(struct ttusb * ttusb)792786baecfSMauro Carvalho Chehab static int ttusb_start_iso_xfer(struct ttusb *ttusb)
793786baecfSMauro Carvalho Chehab {
794786baecfSMauro Carvalho Chehab int i, j, err, buffer_offset = 0;
795786baecfSMauro Carvalho Chehab
796786baecfSMauro Carvalho Chehab if (ttusb->iso_streaming) {
797*883c84acSMauro Carvalho Chehab pr_err("iso xfer already running!\n");
798786baecfSMauro Carvalho Chehab return 0;
799786baecfSMauro Carvalho Chehab }
800786baecfSMauro Carvalho Chehab
801786baecfSMauro Carvalho Chehab ttusb->cc = -1;
802786baecfSMauro Carvalho Chehab ttusb->insync = 0;
803786baecfSMauro Carvalho Chehab ttusb->mux_state = 0;
804786baecfSMauro Carvalho Chehab
805786baecfSMauro Carvalho Chehab for (i = 0; i < ISO_BUF_COUNT; i++) {
806786baecfSMauro Carvalho Chehab int frame_offset = 0;
807786baecfSMauro Carvalho Chehab struct urb *urb = ttusb->iso_urb[i];
808786baecfSMauro Carvalho Chehab
809786baecfSMauro Carvalho Chehab urb->dev = ttusb->dev;
810786baecfSMauro Carvalho Chehab urb->context = ttusb;
811786baecfSMauro Carvalho Chehab urb->complete = ttusb_iso_irq;
812786baecfSMauro Carvalho Chehab urb->pipe = ttusb->isoc_in_pipe;
813786baecfSMauro Carvalho Chehab urb->transfer_flags = URB_ISO_ASAP;
814786baecfSMauro Carvalho Chehab urb->interval = 1;
815786baecfSMauro Carvalho Chehab urb->number_of_packets = FRAMES_PER_ISO_BUF;
816786baecfSMauro Carvalho Chehab urb->transfer_buffer_length =
817786baecfSMauro Carvalho Chehab ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF;
818786baecfSMauro Carvalho Chehab urb->transfer_buffer = ttusb->iso_buffer + buffer_offset;
819786baecfSMauro Carvalho Chehab buffer_offset += ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF;
820786baecfSMauro Carvalho Chehab
821786baecfSMauro Carvalho Chehab for (j = 0; j < FRAMES_PER_ISO_BUF; j++) {
822786baecfSMauro Carvalho Chehab urb->iso_frame_desc[j].offset = frame_offset;
823786baecfSMauro Carvalho Chehab urb->iso_frame_desc[j].length = ISO_FRAME_SIZE;
824786baecfSMauro Carvalho Chehab frame_offset += ISO_FRAME_SIZE;
825786baecfSMauro Carvalho Chehab }
826786baecfSMauro Carvalho Chehab }
827786baecfSMauro Carvalho Chehab
828786baecfSMauro Carvalho Chehab for (i = 0; i < ISO_BUF_COUNT; i++) {
829786baecfSMauro Carvalho Chehab if ((err = usb_submit_urb(ttusb->iso_urb[i], GFP_ATOMIC))) {
830786baecfSMauro Carvalho Chehab ttusb_stop_iso_xfer(ttusb);
831*883c84acSMauro Carvalho Chehab pr_err("failed urb submission (%i: err = %i)!\n",
832*883c84acSMauro Carvalho Chehab i, err);
833786baecfSMauro Carvalho Chehab return err;
834786baecfSMauro Carvalho Chehab }
835786baecfSMauro Carvalho Chehab }
836786baecfSMauro Carvalho Chehab
837786baecfSMauro Carvalho Chehab ttusb->iso_streaming = 1;
838786baecfSMauro Carvalho Chehab
839786baecfSMauro Carvalho Chehab return 0;
840786baecfSMauro Carvalho Chehab }
841786baecfSMauro Carvalho Chehab
842786baecfSMauro Carvalho Chehab #ifdef TTUSB_HWSECTIONS
ttusb_handle_ts_data(struct dvb_demux_feed * dvbdmxfeed,const u8 * data,int len)843786baecfSMauro Carvalho Chehab static void ttusb_handle_ts_data(struct dvb_demux_feed *dvbdmxfeed, const u8 * data,
844786baecfSMauro Carvalho Chehab int len)
845786baecfSMauro Carvalho Chehab {
846786baecfSMauro Carvalho Chehab dvbdmxfeed->cb.ts(data, len, 0, 0, &dvbdmxfeed->feed.ts, 0);
847786baecfSMauro Carvalho Chehab }
848786baecfSMauro Carvalho Chehab
ttusb_handle_sec_data(struct dvb_demux_feed * dvbdmxfeed,const u8 * data,int len)849786baecfSMauro Carvalho Chehab static void ttusb_handle_sec_data(struct dvb_demux_feed *dvbdmxfeed, const u8 * data,
850786baecfSMauro Carvalho Chehab int len)
851786baecfSMauro Carvalho Chehab {
852786baecfSMauro Carvalho Chehab // struct dvb_demux_feed *dvbdmxfeed = channel->dvbdmxfeed;
853786baecfSMauro Carvalho Chehab #error TODO: handle ugly stuff
854786baecfSMauro Carvalho Chehab // dvbdmxfeed->cb.sec(data, len, 0, 0, &dvbdmxfeed->feed.sec, 0);
855786baecfSMauro Carvalho Chehab }
856786baecfSMauro Carvalho Chehab #endif
857786baecfSMauro Carvalho Chehab
ttusb_start_feed(struct dvb_demux_feed * dvbdmxfeed)858786baecfSMauro Carvalho Chehab static int ttusb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
859786baecfSMauro Carvalho Chehab {
860786baecfSMauro Carvalho Chehab struct ttusb *ttusb = (struct ttusb *) dvbdmxfeed->demux;
861786baecfSMauro Carvalho Chehab int feed_type = 1;
862786baecfSMauro Carvalho Chehab
863786baecfSMauro Carvalho Chehab dprintk("ttusb_start_feed\n");
864786baecfSMauro Carvalho Chehab
865786baecfSMauro Carvalho Chehab switch (dvbdmxfeed->type) {
866786baecfSMauro Carvalho Chehab case DMX_TYPE_TS:
867786baecfSMauro Carvalho Chehab break;
868786baecfSMauro Carvalho Chehab case DMX_TYPE_SEC:
869786baecfSMauro Carvalho Chehab break;
870786baecfSMauro Carvalho Chehab default:
871786baecfSMauro Carvalho Chehab return -EINVAL;
872786baecfSMauro Carvalho Chehab }
873786baecfSMauro Carvalho Chehab
874786baecfSMauro Carvalho Chehab if (dvbdmxfeed->type == DMX_TYPE_TS) {
875786baecfSMauro Carvalho Chehab switch (dvbdmxfeed->pes_type) {
876fde04ab9SMauro Carvalho Chehab case DMX_PES_VIDEO:
877fde04ab9SMauro Carvalho Chehab case DMX_PES_AUDIO:
878fde04ab9SMauro Carvalho Chehab case DMX_PES_TELETEXT:
879fde04ab9SMauro Carvalho Chehab case DMX_PES_PCR:
880fde04ab9SMauro Carvalho Chehab case DMX_PES_OTHER:
881786baecfSMauro Carvalho Chehab break;
882786baecfSMauro Carvalho Chehab default:
883786baecfSMauro Carvalho Chehab return -EINVAL;
884786baecfSMauro Carvalho Chehab }
885786baecfSMauro Carvalho Chehab }
886786baecfSMauro Carvalho Chehab
887786baecfSMauro Carvalho Chehab #ifdef TTUSB_HWSECTIONS
888786baecfSMauro Carvalho Chehab #error TODO: allocate filters
889786baecfSMauro Carvalho Chehab if (dvbdmxfeed->type == DMX_TYPE_TS) {
890786baecfSMauro Carvalho Chehab feed_type = 1;
891786baecfSMauro Carvalho Chehab } else if (dvbdmxfeed->type == DMX_TYPE_SEC) {
892786baecfSMauro Carvalho Chehab feed_type = 2;
893786baecfSMauro Carvalho Chehab }
894786baecfSMauro Carvalho Chehab #endif
895786baecfSMauro Carvalho Chehab
896786baecfSMauro Carvalho Chehab ttusb_set_channel(ttusb, dvbdmxfeed->index, feed_type, dvbdmxfeed->pid);
897786baecfSMauro Carvalho Chehab
898786baecfSMauro Carvalho Chehab if (0 == ttusb->running_feed_count++)
899786baecfSMauro Carvalho Chehab ttusb_start_iso_xfer(ttusb);
900786baecfSMauro Carvalho Chehab
901786baecfSMauro Carvalho Chehab return 0;
902786baecfSMauro Carvalho Chehab }
903786baecfSMauro Carvalho Chehab
ttusb_stop_feed(struct dvb_demux_feed * dvbdmxfeed)904786baecfSMauro Carvalho Chehab static int ttusb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
905786baecfSMauro Carvalho Chehab {
906786baecfSMauro Carvalho Chehab struct ttusb *ttusb = (struct ttusb *) dvbdmxfeed->demux;
907786baecfSMauro Carvalho Chehab
908786baecfSMauro Carvalho Chehab ttusb_del_channel(ttusb, dvbdmxfeed->index);
909786baecfSMauro Carvalho Chehab
910786baecfSMauro Carvalho Chehab if (--ttusb->running_feed_count == 0)
911786baecfSMauro Carvalho Chehab ttusb_stop_iso_xfer(ttusb);
912786baecfSMauro Carvalho Chehab
913786baecfSMauro Carvalho Chehab return 0;
914786baecfSMauro Carvalho Chehab }
915786baecfSMauro Carvalho Chehab
ttusb_setup_interfaces(struct ttusb * ttusb)916786baecfSMauro Carvalho Chehab static int ttusb_setup_interfaces(struct ttusb *ttusb)
917786baecfSMauro Carvalho Chehab {
918786baecfSMauro Carvalho Chehab usb_set_interface(ttusb->dev, 1, 1);
919786baecfSMauro Carvalho Chehab
920786baecfSMauro Carvalho Chehab ttusb->bulk_out_pipe = usb_sndbulkpipe(ttusb->dev, 1);
921786baecfSMauro Carvalho Chehab ttusb->bulk_in_pipe = usb_rcvbulkpipe(ttusb->dev, 1);
922786baecfSMauro Carvalho Chehab ttusb->isoc_in_pipe = usb_rcvisocpipe(ttusb->dev, 2);
923786baecfSMauro Carvalho Chehab
924786baecfSMauro Carvalho Chehab return 0;
925786baecfSMauro Carvalho Chehab }
926786baecfSMauro Carvalho Chehab
927786baecfSMauro Carvalho Chehab #if 0
928786baecfSMauro Carvalho Chehab static u8 stc_firmware[8192];
929786baecfSMauro Carvalho Chehab
930786baecfSMauro Carvalho Chehab static int stc_open(struct inode *inode, struct file *file)
931786baecfSMauro Carvalho Chehab {
932786baecfSMauro Carvalho Chehab struct ttusb *ttusb = file->private_data;
933786baecfSMauro Carvalho Chehab int addr;
934786baecfSMauro Carvalho Chehab
935786baecfSMauro Carvalho Chehab for (addr = 0; addr < 8192; addr += 16) {
936786baecfSMauro Carvalho Chehab u8 snd_buf[2] = { addr >> 8, addr & 0xFF };
937786baecfSMauro Carvalho Chehab ttusb_i2c_msg(ttusb, 0x50, snd_buf, 2, stc_firmware + addr,
938786baecfSMauro Carvalho Chehab 16);
939786baecfSMauro Carvalho Chehab }
940786baecfSMauro Carvalho Chehab
941786baecfSMauro Carvalho Chehab return 0;
942786baecfSMauro Carvalho Chehab }
943786baecfSMauro Carvalho Chehab
944786baecfSMauro Carvalho Chehab static ssize_t stc_read(struct file *file, char *buf, size_t count,
945786baecfSMauro Carvalho Chehab loff_t *offset)
946786baecfSMauro Carvalho Chehab {
947786baecfSMauro Carvalho Chehab return simple_read_from_buffer(buf, count, offset, stc_firmware, 8192);
948786baecfSMauro Carvalho Chehab }
949786baecfSMauro Carvalho Chehab
950786baecfSMauro Carvalho Chehab static int stc_release(struct inode *inode, struct file *file)
951786baecfSMauro Carvalho Chehab {
952786baecfSMauro Carvalho Chehab return 0;
953786baecfSMauro Carvalho Chehab }
954786baecfSMauro Carvalho Chehab
955786baecfSMauro Carvalho Chehab static const struct file_operations stc_fops = {
956786baecfSMauro Carvalho Chehab .owner = THIS_MODULE,
957786baecfSMauro Carvalho Chehab .read = stc_read,
958786baecfSMauro Carvalho Chehab .open = stc_open,
959786baecfSMauro Carvalho Chehab .release = stc_release,
960786baecfSMauro Carvalho Chehab };
961786baecfSMauro Carvalho Chehab #endif
962786baecfSMauro Carvalho Chehab
functionality(struct i2c_adapter * adapter)963786baecfSMauro Carvalho Chehab static u32 functionality(struct i2c_adapter *adapter)
964786baecfSMauro Carvalho Chehab {
965786baecfSMauro Carvalho Chehab return I2C_FUNC_I2C;
966786baecfSMauro Carvalho Chehab }
967786baecfSMauro Carvalho Chehab
968786baecfSMauro Carvalho Chehab
969786baecfSMauro Carvalho Chehab
alps_tdmb7_tuner_set_params(struct dvb_frontend * fe)970786baecfSMauro Carvalho Chehab static int alps_tdmb7_tuner_set_params(struct dvb_frontend *fe)
971786baecfSMauro Carvalho Chehab {
972786baecfSMauro Carvalho Chehab struct dtv_frontend_properties *p = &fe->dtv_property_cache;
973786baecfSMauro Carvalho Chehab struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
974786baecfSMauro Carvalho Chehab u8 data[4];
975786baecfSMauro Carvalho Chehab struct i2c_msg msg = {.addr=0x61, .flags=0, .buf=data, .len=sizeof(data) };
976786baecfSMauro Carvalho Chehab u32 div;
977786baecfSMauro Carvalho Chehab
978786baecfSMauro Carvalho Chehab div = (p->frequency + 36166667) / 166667;
979786baecfSMauro Carvalho Chehab
980786baecfSMauro Carvalho Chehab data[0] = (div >> 8) & 0x7f;
981786baecfSMauro Carvalho Chehab data[1] = div & 0xff;
982786baecfSMauro Carvalho Chehab data[2] = ((div >> 10) & 0x60) | 0x85;
983786baecfSMauro Carvalho Chehab data[3] = p->frequency < 592000000 ? 0x40 : 0x80;
984786baecfSMauro Carvalho Chehab
985786baecfSMauro Carvalho Chehab if (fe->ops.i2c_gate_ctrl)
986786baecfSMauro Carvalho Chehab fe->ops.i2c_gate_ctrl(fe, 1);
987786baecfSMauro Carvalho Chehab if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1) return -EIO;
988786baecfSMauro Carvalho Chehab return 0;
989786baecfSMauro Carvalho Chehab }
990786baecfSMauro Carvalho Chehab
991786baecfSMauro Carvalho Chehab static struct cx22700_config alps_tdmb7_config = {
992786baecfSMauro Carvalho Chehab .demod_address = 0x43,
993786baecfSMauro Carvalho Chehab };
994786baecfSMauro Carvalho Chehab
995786baecfSMauro Carvalho Chehab
996786baecfSMauro Carvalho Chehab
997786baecfSMauro Carvalho Chehab
998786baecfSMauro Carvalho Chehab
philips_tdm1316l_tuner_init(struct dvb_frontend * fe)999786baecfSMauro Carvalho Chehab static int philips_tdm1316l_tuner_init(struct dvb_frontend* fe)
1000786baecfSMauro Carvalho Chehab {
1001786baecfSMauro Carvalho Chehab struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1002786baecfSMauro Carvalho Chehab static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab };
1003786baecfSMauro Carvalho Chehab static u8 disable_mc44BC374c[] = { 0x1d, 0x74, 0xa0, 0x68 };
1004786baecfSMauro Carvalho Chehab struct i2c_msg tuner_msg = { .addr=0x60, .flags=0, .buf=td1316_init, .len=sizeof(td1316_init) };
1005786baecfSMauro Carvalho Chehab
1006786baecfSMauro Carvalho Chehab // setup PLL configuration
1007786baecfSMauro Carvalho Chehab if (fe->ops.i2c_gate_ctrl)
1008786baecfSMauro Carvalho Chehab fe->ops.i2c_gate_ctrl(fe, 1);
1009786baecfSMauro Carvalho Chehab if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) return -EIO;
1010786baecfSMauro Carvalho Chehab msleep(1);
1011786baecfSMauro Carvalho Chehab
1012786baecfSMauro Carvalho Chehab // disable the mc44BC374c (do not check for errors)
1013786baecfSMauro Carvalho Chehab tuner_msg.addr = 0x65;
1014786baecfSMauro Carvalho Chehab tuner_msg.buf = disable_mc44BC374c;
1015786baecfSMauro Carvalho Chehab tuner_msg.len = sizeof(disable_mc44BC374c);
1016786baecfSMauro Carvalho Chehab if (fe->ops.i2c_gate_ctrl)
1017786baecfSMauro Carvalho Chehab fe->ops.i2c_gate_ctrl(fe, 1);
1018786baecfSMauro Carvalho Chehab if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) {
1019786baecfSMauro Carvalho Chehab i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1);
1020786baecfSMauro Carvalho Chehab }
1021786baecfSMauro Carvalho Chehab
1022786baecfSMauro Carvalho Chehab return 0;
1023786baecfSMauro Carvalho Chehab }
1024786baecfSMauro Carvalho Chehab
philips_tdm1316l_tuner_set_params(struct dvb_frontend * fe)1025786baecfSMauro Carvalho Chehab static int philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe)
1026786baecfSMauro Carvalho Chehab {
1027786baecfSMauro Carvalho Chehab struct dtv_frontend_properties *p = &fe->dtv_property_cache;
1028786baecfSMauro Carvalho Chehab struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1029786baecfSMauro Carvalho Chehab u8 tuner_buf[4];
1030786baecfSMauro Carvalho Chehab struct i2c_msg tuner_msg = {.addr=0x60, .flags=0, .buf=tuner_buf, .len=sizeof(tuner_buf) };
1031786baecfSMauro Carvalho Chehab int tuner_frequency = 0;
1032786baecfSMauro Carvalho Chehab u8 band, cp, filter;
1033786baecfSMauro Carvalho Chehab
1034786baecfSMauro Carvalho Chehab // determine charge pump
1035786baecfSMauro Carvalho Chehab tuner_frequency = p->frequency + 36130000;
1036786baecfSMauro Carvalho Chehab if (tuner_frequency < 87000000) return -EINVAL;
1037786baecfSMauro Carvalho Chehab else if (tuner_frequency < 130000000) cp = 3;
1038786baecfSMauro Carvalho Chehab else if (tuner_frequency < 160000000) cp = 5;
1039786baecfSMauro Carvalho Chehab else if (tuner_frequency < 200000000) cp = 6;
1040786baecfSMauro Carvalho Chehab else if (tuner_frequency < 290000000) cp = 3;
1041786baecfSMauro Carvalho Chehab else if (tuner_frequency < 420000000) cp = 5;
1042786baecfSMauro Carvalho Chehab else if (tuner_frequency < 480000000) cp = 6;
1043786baecfSMauro Carvalho Chehab else if (tuner_frequency < 620000000) cp = 3;
1044786baecfSMauro Carvalho Chehab else if (tuner_frequency < 830000000) cp = 5;
1045786baecfSMauro Carvalho Chehab else if (tuner_frequency < 895000000) cp = 7;
1046786baecfSMauro Carvalho Chehab else return -EINVAL;
1047786baecfSMauro Carvalho Chehab
1048786baecfSMauro Carvalho Chehab // determine band
1049786baecfSMauro Carvalho Chehab if (p->frequency < 49000000)
1050786baecfSMauro Carvalho Chehab return -EINVAL;
1051786baecfSMauro Carvalho Chehab else if (p->frequency < 159000000)
1052786baecfSMauro Carvalho Chehab band = 1;
1053786baecfSMauro Carvalho Chehab else if (p->frequency < 444000000)
1054786baecfSMauro Carvalho Chehab band = 2;
1055786baecfSMauro Carvalho Chehab else if (p->frequency < 861000000)
1056786baecfSMauro Carvalho Chehab band = 4;
1057786baecfSMauro Carvalho Chehab else return -EINVAL;
1058786baecfSMauro Carvalho Chehab
1059786baecfSMauro Carvalho Chehab // setup PLL filter
1060786baecfSMauro Carvalho Chehab switch (p->bandwidth_hz) {
1061786baecfSMauro Carvalho Chehab case 6000000:
1062786baecfSMauro Carvalho Chehab tda1004x_writereg(fe, 0x0C, 0);
1063786baecfSMauro Carvalho Chehab filter = 0;
1064786baecfSMauro Carvalho Chehab break;
1065786baecfSMauro Carvalho Chehab
1066786baecfSMauro Carvalho Chehab case 7000000:
1067786baecfSMauro Carvalho Chehab tda1004x_writereg(fe, 0x0C, 0);
1068786baecfSMauro Carvalho Chehab filter = 0;
1069786baecfSMauro Carvalho Chehab break;
1070786baecfSMauro Carvalho Chehab
1071786baecfSMauro Carvalho Chehab case 8000000:
1072786baecfSMauro Carvalho Chehab tda1004x_writereg(fe, 0x0C, 0xFF);
1073786baecfSMauro Carvalho Chehab filter = 1;
1074786baecfSMauro Carvalho Chehab break;
1075786baecfSMauro Carvalho Chehab
1076786baecfSMauro Carvalho Chehab default:
1077786baecfSMauro Carvalho Chehab return -EINVAL;
1078786baecfSMauro Carvalho Chehab }
1079786baecfSMauro Carvalho Chehab
1080786baecfSMauro Carvalho Chehab // calculate divisor
1081786baecfSMauro Carvalho Chehab // ((36130000+((1000000/6)/2)) + Finput)/(1000000/6)
1082786baecfSMauro Carvalho Chehab tuner_frequency = (((p->frequency / 1000) * 6) + 217280) / 1000;
1083786baecfSMauro Carvalho Chehab
1084786baecfSMauro Carvalho Chehab // setup tuner buffer
1085786baecfSMauro Carvalho Chehab tuner_buf[0] = tuner_frequency >> 8;
1086786baecfSMauro Carvalho Chehab tuner_buf[1] = tuner_frequency & 0xff;
1087786baecfSMauro Carvalho Chehab tuner_buf[2] = 0xca;
1088786baecfSMauro Carvalho Chehab tuner_buf[3] = (cp << 5) | (filter << 3) | band;
1089786baecfSMauro Carvalho Chehab
1090786baecfSMauro Carvalho Chehab if (fe->ops.i2c_gate_ctrl)
1091786baecfSMauro Carvalho Chehab fe->ops.i2c_gate_ctrl(fe, 1);
1092786baecfSMauro Carvalho Chehab if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1)
1093786baecfSMauro Carvalho Chehab return -EIO;
1094786baecfSMauro Carvalho Chehab
1095786baecfSMauro Carvalho Chehab msleep(1);
1096786baecfSMauro Carvalho Chehab return 0;
1097786baecfSMauro Carvalho Chehab }
1098786baecfSMauro Carvalho Chehab
philips_tdm1316l_request_firmware(struct dvb_frontend * fe,const struct firmware ** fw,char * name)1099786baecfSMauro Carvalho Chehab static int philips_tdm1316l_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
1100786baecfSMauro Carvalho Chehab {
1101786baecfSMauro Carvalho Chehab struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1102786baecfSMauro Carvalho Chehab
1103786baecfSMauro Carvalho Chehab return request_firmware(fw, name, &ttusb->dev->dev);
1104786baecfSMauro Carvalho Chehab }
1105786baecfSMauro Carvalho Chehab
1106786baecfSMauro Carvalho Chehab static struct tda1004x_config philips_tdm1316l_config = {
1107786baecfSMauro Carvalho Chehab
1108786baecfSMauro Carvalho Chehab .demod_address = 0x8,
1109786baecfSMauro Carvalho Chehab .invert = 1,
1110786baecfSMauro Carvalho Chehab .invert_oclk = 0,
1111786baecfSMauro Carvalho Chehab .request_firmware = philips_tdm1316l_request_firmware,
1112786baecfSMauro Carvalho Chehab };
1113786baecfSMauro Carvalho Chehab
1114786baecfSMauro Carvalho Chehab static u8 alps_bsbe1_inittab[] = {
1115786baecfSMauro Carvalho Chehab 0x01, 0x15,
1116786baecfSMauro Carvalho Chehab 0x02, 0x30,
1117786baecfSMauro Carvalho Chehab 0x03, 0x00,
1118786baecfSMauro Carvalho Chehab 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
1119786baecfSMauro Carvalho Chehab 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
1120786baecfSMauro Carvalho Chehab 0x06, 0x40, /* DAC not used, set to high impendance mode */
1121786baecfSMauro Carvalho Chehab 0x07, 0x00, /* DAC LSB */
1122786baecfSMauro Carvalho Chehab 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
1123786baecfSMauro Carvalho Chehab 0x09, 0x00, /* FIFO */
1124786baecfSMauro Carvalho Chehab 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
1125786baecfSMauro Carvalho Chehab 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
1126786baecfSMauro Carvalho Chehab 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
1127786baecfSMauro Carvalho Chehab 0x10, 0x3f, // AGC2 0x3d
1128786baecfSMauro Carvalho Chehab 0x11, 0x84,
1129786baecfSMauro Carvalho Chehab 0x12, 0xb9,
1130786baecfSMauro Carvalho Chehab 0x15, 0xc9, // lock detector threshold
1131786baecfSMauro Carvalho Chehab 0x16, 0x00,
1132786baecfSMauro Carvalho Chehab 0x17, 0x00,
1133786baecfSMauro Carvalho Chehab 0x18, 0x00,
1134786baecfSMauro Carvalho Chehab 0x19, 0x00,
1135786baecfSMauro Carvalho Chehab 0x1a, 0x00,
1136786baecfSMauro Carvalho Chehab 0x1f, 0x50,
1137786baecfSMauro Carvalho Chehab 0x20, 0x00,
1138786baecfSMauro Carvalho Chehab 0x21, 0x00,
1139786baecfSMauro Carvalho Chehab 0x22, 0x00,
1140786baecfSMauro Carvalho Chehab 0x23, 0x00,
1141786baecfSMauro Carvalho Chehab 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
1142786baecfSMauro Carvalho Chehab 0x29, 0x1e, // 1/2 threshold
1143786baecfSMauro Carvalho Chehab 0x2a, 0x14, // 2/3 threshold
1144786baecfSMauro Carvalho Chehab 0x2b, 0x0f, // 3/4 threshold
1145786baecfSMauro Carvalho Chehab 0x2c, 0x09, // 5/6 threshold
1146786baecfSMauro Carvalho Chehab 0x2d, 0x05, // 7/8 threshold
1147786baecfSMauro Carvalho Chehab 0x2e, 0x01,
1148786baecfSMauro Carvalho Chehab 0x31, 0x1f, // test all FECs
1149786baecfSMauro Carvalho Chehab 0x32, 0x19, // viterbi and synchro search
1150786baecfSMauro Carvalho Chehab 0x33, 0xfc, // rs control
1151786baecfSMauro Carvalho Chehab 0x34, 0x93, // error control
1152786baecfSMauro Carvalho Chehab 0x0f, 0x92,
1153786baecfSMauro Carvalho Chehab 0xff, 0xff
1154786baecfSMauro Carvalho Chehab };
1155786baecfSMauro Carvalho Chehab
1156786baecfSMauro Carvalho Chehab static u8 alps_bsru6_inittab[] = {
1157786baecfSMauro Carvalho Chehab 0x01, 0x15,
1158786baecfSMauro Carvalho Chehab 0x02, 0x30,
1159786baecfSMauro Carvalho Chehab 0x03, 0x00,
1160786baecfSMauro Carvalho Chehab 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
1161786baecfSMauro Carvalho Chehab 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
1162786baecfSMauro Carvalho Chehab 0x06, 0x40, /* DAC not used, set to high impendance mode */
1163786baecfSMauro Carvalho Chehab 0x07, 0x00, /* DAC LSB */
1164786baecfSMauro Carvalho Chehab 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
1165786baecfSMauro Carvalho Chehab 0x09, 0x00, /* FIFO */
1166786baecfSMauro Carvalho Chehab 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
1167786baecfSMauro Carvalho Chehab 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
1168786baecfSMauro Carvalho Chehab 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
1169786baecfSMauro Carvalho Chehab 0x10, 0x3f, // AGC2 0x3d
1170786baecfSMauro Carvalho Chehab 0x11, 0x84,
1171786baecfSMauro Carvalho Chehab 0x12, 0xb9,
1172786baecfSMauro Carvalho Chehab 0x15, 0xc9, // lock detector threshold
1173786baecfSMauro Carvalho Chehab 0x16, 0x00,
1174786baecfSMauro Carvalho Chehab 0x17, 0x00,
1175786baecfSMauro Carvalho Chehab 0x18, 0x00,
1176786baecfSMauro Carvalho Chehab 0x19, 0x00,
1177786baecfSMauro Carvalho Chehab 0x1a, 0x00,
1178786baecfSMauro Carvalho Chehab 0x1f, 0x50,
1179786baecfSMauro Carvalho Chehab 0x20, 0x00,
1180786baecfSMauro Carvalho Chehab 0x21, 0x00,
1181786baecfSMauro Carvalho Chehab 0x22, 0x00,
1182786baecfSMauro Carvalho Chehab 0x23, 0x00,
1183786baecfSMauro Carvalho Chehab 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
1184786baecfSMauro Carvalho Chehab 0x29, 0x1e, // 1/2 threshold
1185786baecfSMauro Carvalho Chehab 0x2a, 0x14, // 2/3 threshold
1186786baecfSMauro Carvalho Chehab 0x2b, 0x0f, // 3/4 threshold
1187786baecfSMauro Carvalho Chehab 0x2c, 0x09, // 5/6 threshold
1188786baecfSMauro Carvalho Chehab 0x2d, 0x05, // 7/8 threshold
1189786baecfSMauro Carvalho Chehab 0x2e, 0x01,
1190786baecfSMauro Carvalho Chehab 0x31, 0x1f, // test all FECs
1191786baecfSMauro Carvalho Chehab 0x32, 0x19, // viterbi and synchro search
1192786baecfSMauro Carvalho Chehab 0x33, 0xfc, // rs control
1193786baecfSMauro Carvalho Chehab 0x34, 0x93, // error control
1194786baecfSMauro Carvalho Chehab 0x0f, 0x52,
1195786baecfSMauro Carvalho Chehab 0xff, 0xff
1196786baecfSMauro Carvalho Chehab };
1197786baecfSMauro Carvalho Chehab
alps_stv0299_set_symbol_rate(struct dvb_frontend * fe,u32 srate,u32 ratio)1198786baecfSMauro Carvalho Chehab static int alps_stv0299_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
1199786baecfSMauro Carvalho Chehab {
1200786baecfSMauro Carvalho Chehab u8 aclk = 0;
1201786baecfSMauro Carvalho Chehab u8 bclk = 0;
1202786baecfSMauro Carvalho Chehab
1203786baecfSMauro Carvalho Chehab if (srate < 1500000) {
1204786baecfSMauro Carvalho Chehab aclk = 0xb7;
1205786baecfSMauro Carvalho Chehab bclk = 0x47;
1206786baecfSMauro Carvalho Chehab } else if (srate < 3000000) {
1207786baecfSMauro Carvalho Chehab aclk = 0xb7;
1208786baecfSMauro Carvalho Chehab bclk = 0x4b;
1209786baecfSMauro Carvalho Chehab } else if (srate < 7000000) {
1210786baecfSMauro Carvalho Chehab aclk = 0xb7;
1211786baecfSMauro Carvalho Chehab bclk = 0x4f;
1212786baecfSMauro Carvalho Chehab } else if (srate < 14000000) {
1213786baecfSMauro Carvalho Chehab aclk = 0xb7;
1214786baecfSMauro Carvalho Chehab bclk = 0x53;
1215786baecfSMauro Carvalho Chehab } else if (srate < 30000000) {
1216786baecfSMauro Carvalho Chehab aclk = 0xb6;
1217786baecfSMauro Carvalho Chehab bclk = 0x53;
1218786baecfSMauro Carvalho Chehab } else if (srate < 45000000) {
1219786baecfSMauro Carvalho Chehab aclk = 0xb4;
1220786baecfSMauro Carvalho Chehab bclk = 0x51;
1221786baecfSMauro Carvalho Chehab }
1222786baecfSMauro Carvalho Chehab
1223786baecfSMauro Carvalho Chehab stv0299_writereg(fe, 0x13, aclk);
1224786baecfSMauro Carvalho Chehab stv0299_writereg(fe, 0x14, bclk);
1225786baecfSMauro Carvalho Chehab stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
1226786baecfSMauro Carvalho Chehab stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
1227786baecfSMauro Carvalho Chehab stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
1228786baecfSMauro Carvalho Chehab
1229786baecfSMauro Carvalho Chehab return 0;
1230786baecfSMauro Carvalho Chehab }
1231786baecfSMauro Carvalho Chehab
philips_tsa5059_tuner_set_params(struct dvb_frontend * fe)1232786baecfSMauro Carvalho Chehab static int philips_tsa5059_tuner_set_params(struct dvb_frontend *fe)
1233786baecfSMauro Carvalho Chehab {
1234786baecfSMauro Carvalho Chehab struct dtv_frontend_properties *p = &fe->dtv_property_cache;
1235786baecfSMauro Carvalho Chehab struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1236786baecfSMauro Carvalho Chehab u8 buf[4];
1237786baecfSMauro Carvalho Chehab u32 div;
1238786baecfSMauro Carvalho Chehab struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
1239786baecfSMauro Carvalho Chehab
1240786baecfSMauro Carvalho Chehab if ((p->frequency < 950000) || (p->frequency > 2150000))
1241786baecfSMauro Carvalho Chehab return -EINVAL;
1242786baecfSMauro Carvalho Chehab
1243786baecfSMauro Carvalho Chehab div = (p->frequency + (125 - 1)) / 125; /* round correctly */
1244786baecfSMauro Carvalho Chehab buf[0] = (div >> 8) & 0x7f;
1245786baecfSMauro Carvalho Chehab buf[1] = div & 0xff;
1246786baecfSMauro Carvalho Chehab buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
1247786baecfSMauro Carvalho Chehab buf[3] = 0xC4;
1248786baecfSMauro Carvalho Chehab
1249786baecfSMauro Carvalho Chehab if (p->frequency > 1530000)
1250786baecfSMauro Carvalho Chehab buf[3] = 0xC0;
1251786baecfSMauro Carvalho Chehab
1252786baecfSMauro Carvalho Chehab /* BSBE1 wants XCE bit set */
1253786baecfSMauro Carvalho Chehab if (ttusb->revision == TTUSB_REV_2_2)
1254786baecfSMauro Carvalho Chehab buf[3] |= 0x20;
1255786baecfSMauro Carvalho Chehab
1256786baecfSMauro Carvalho Chehab if (fe->ops.i2c_gate_ctrl)
1257786baecfSMauro Carvalho Chehab fe->ops.i2c_gate_ctrl(fe, 1);
1258786baecfSMauro Carvalho Chehab if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1)
1259786baecfSMauro Carvalho Chehab return -EIO;
1260786baecfSMauro Carvalho Chehab
1261786baecfSMauro Carvalho Chehab return 0;
1262786baecfSMauro Carvalho Chehab }
1263786baecfSMauro Carvalho Chehab
1264786baecfSMauro Carvalho Chehab static struct stv0299_config alps_stv0299_config = {
1265786baecfSMauro Carvalho Chehab .demod_address = 0x68,
1266786baecfSMauro Carvalho Chehab .inittab = alps_bsru6_inittab,
1267786baecfSMauro Carvalho Chehab .mclk = 88000000UL,
1268786baecfSMauro Carvalho Chehab .invert = 1,
1269786baecfSMauro Carvalho Chehab .skip_reinit = 0,
1270786baecfSMauro Carvalho Chehab .lock_output = STV0299_LOCKOUTPUT_1,
1271786baecfSMauro Carvalho Chehab .volt13_op0_op1 = STV0299_VOLT13_OP1,
1272786baecfSMauro Carvalho Chehab .min_delay_ms = 100,
1273786baecfSMauro Carvalho Chehab .set_symbol_rate = alps_stv0299_set_symbol_rate,
1274786baecfSMauro Carvalho Chehab };
1275786baecfSMauro Carvalho Chehab
ttusb_novas_grundig_29504_491_tuner_set_params(struct dvb_frontend * fe)1276786baecfSMauro Carvalho Chehab static int ttusb_novas_grundig_29504_491_tuner_set_params(struct dvb_frontend *fe)
1277786baecfSMauro Carvalho Chehab {
1278786baecfSMauro Carvalho Chehab struct dtv_frontend_properties *p = &fe->dtv_property_cache;
1279786baecfSMauro Carvalho Chehab struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1280786baecfSMauro Carvalho Chehab u8 buf[4];
1281786baecfSMauro Carvalho Chehab u32 div;
1282786baecfSMauro Carvalho Chehab struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
1283786baecfSMauro Carvalho Chehab
1284786baecfSMauro Carvalho Chehab div = p->frequency / 125;
1285786baecfSMauro Carvalho Chehab
1286786baecfSMauro Carvalho Chehab buf[0] = (div >> 8) & 0x7f;
1287786baecfSMauro Carvalho Chehab buf[1] = div & 0xff;
1288786baecfSMauro Carvalho Chehab buf[2] = 0x8e;
1289786baecfSMauro Carvalho Chehab buf[3] = 0x00;
1290786baecfSMauro Carvalho Chehab
1291786baecfSMauro Carvalho Chehab if (fe->ops.i2c_gate_ctrl)
1292786baecfSMauro Carvalho Chehab fe->ops.i2c_gate_ctrl(fe, 1);
1293786baecfSMauro Carvalho Chehab if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1)
1294786baecfSMauro Carvalho Chehab return -EIO;
1295786baecfSMauro Carvalho Chehab
1296786baecfSMauro Carvalho Chehab return 0;
1297786baecfSMauro Carvalho Chehab }
1298786baecfSMauro Carvalho Chehab
1299786baecfSMauro Carvalho Chehab static struct tda8083_config ttusb_novas_grundig_29504_491_config = {
1300786baecfSMauro Carvalho Chehab
1301786baecfSMauro Carvalho Chehab .demod_address = 0x68,
1302786baecfSMauro Carvalho Chehab };
1303786baecfSMauro Carvalho Chehab
alps_tdbe2_tuner_set_params(struct dvb_frontend * fe)1304786baecfSMauro Carvalho Chehab static int alps_tdbe2_tuner_set_params(struct dvb_frontend *fe)
1305786baecfSMauro Carvalho Chehab {
1306786baecfSMauro Carvalho Chehab struct dtv_frontend_properties *p = &fe->dtv_property_cache;
1307786baecfSMauro Carvalho Chehab struct ttusb* ttusb = fe->dvb->priv;
1308786baecfSMauro Carvalho Chehab u32 div;
1309786baecfSMauro Carvalho Chehab u8 data[4];
1310786baecfSMauro Carvalho Chehab struct i2c_msg msg = { .addr = 0x62, .flags = 0, .buf = data, .len = sizeof(data) };
1311786baecfSMauro Carvalho Chehab
1312786baecfSMauro Carvalho Chehab div = (p->frequency + 35937500 + 31250) / 62500;
1313786baecfSMauro Carvalho Chehab
1314786baecfSMauro Carvalho Chehab data[0] = (div >> 8) & 0x7f;
1315786baecfSMauro Carvalho Chehab data[1] = div & 0xff;
1316786baecfSMauro Carvalho Chehab data[2] = 0x85 | ((div >> 10) & 0x60);
1317786baecfSMauro Carvalho Chehab data[3] = (p->frequency < 174000000 ? 0x88 : p->frequency < 470000000 ? 0x84 : 0x81);
1318786baecfSMauro Carvalho Chehab
1319786baecfSMauro Carvalho Chehab if (fe->ops.i2c_gate_ctrl)
1320786baecfSMauro Carvalho Chehab fe->ops.i2c_gate_ctrl(fe, 1);
1321786baecfSMauro Carvalho Chehab if (i2c_transfer (&ttusb->i2c_adap, &msg, 1) != 1)
1322786baecfSMauro Carvalho Chehab return -EIO;
1323786baecfSMauro Carvalho Chehab
1324786baecfSMauro Carvalho Chehab return 0;
1325786baecfSMauro Carvalho Chehab }
1326786baecfSMauro Carvalho Chehab
1327786baecfSMauro Carvalho Chehab
1328786baecfSMauro Carvalho Chehab static struct ves1820_config alps_tdbe2_config = {
1329786baecfSMauro Carvalho Chehab .demod_address = 0x09,
1330786baecfSMauro Carvalho Chehab .xin = 57840000UL,
1331786baecfSMauro Carvalho Chehab .invert = 1,
1332786baecfSMauro Carvalho Chehab .selagc = VES1820_SELAGC_SIGNAMPERR,
1333786baecfSMauro Carvalho Chehab };
1334786baecfSMauro Carvalho Chehab
read_pwm(struct ttusb * ttusb)1335786baecfSMauro Carvalho Chehab static u8 read_pwm(struct ttusb* ttusb)
1336786baecfSMauro Carvalho Chehab {
1337786baecfSMauro Carvalho Chehab u8 b = 0xff;
1338786baecfSMauro Carvalho Chehab u8 pwm;
1339786baecfSMauro Carvalho Chehab struct i2c_msg msg[] = { { .addr = 0x50,.flags = 0,.buf = &b,.len = 1 },
1340786baecfSMauro Carvalho Chehab { .addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1} };
1341786baecfSMauro Carvalho Chehab
1342786baecfSMauro Carvalho Chehab if ((i2c_transfer(&ttusb->i2c_adap, msg, 2) != 2) || (pwm == 0xff))
1343786baecfSMauro Carvalho Chehab pwm = 0x48;
1344786baecfSMauro Carvalho Chehab
1345786baecfSMauro Carvalho Chehab return pwm;
1346786baecfSMauro Carvalho Chehab }
1347786baecfSMauro Carvalho Chehab
1348786baecfSMauro Carvalho Chehab
dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend * fe)1349786baecfSMauro Carvalho Chehab static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe)
1350786baecfSMauro Carvalho Chehab {
1351786baecfSMauro Carvalho Chehab struct dtv_frontend_properties *p = &fe->dtv_property_cache;
1352786baecfSMauro Carvalho Chehab struct ttusb *ttusb = (struct ttusb *) fe->dvb->priv;
1353786baecfSMauro Carvalho Chehab u8 tuner_buf[5];
1354786baecfSMauro Carvalho Chehab struct i2c_msg tuner_msg = {.addr = 0x60,
1355786baecfSMauro Carvalho Chehab .flags = 0,
1356786baecfSMauro Carvalho Chehab .buf = tuner_buf,
1357786baecfSMauro Carvalho Chehab .len = sizeof(tuner_buf) };
1358786baecfSMauro Carvalho Chehab int tuner_frequency = 0;
1359786baecfSMauro Carvalho Chehab u8 band, cp, filter;
1360786baecfSMauro Carvalho Chehab
1361786baecfSMauro Carvalho Chehab // determine charge pump
1362786baecfSMauro Carvalho Chehab tuner_frequency = p->frequency;
1363786baecfSMauro Carvalho Chehab if (tuner_frequency < 87000000) {return -EINVAL;}
1364786baecfSMauro Carvalho Chehab else if (tuner_frequency < 130000000) {cp = 3; band = 1;}
1365786baecfSMauro Carvalho Chehab else if (tuner_frequency < 160000000) {cp = 5; band = 1;}
1366786baecfSMauro Carvalho Chehab else if (tuner_frequency < 200000000) {cp = 6; band = 1;}
1367786baecfSMauro Carvalho Chehab else if (tuner_frequency < 290000000) {cp = 3; band = 2;}
1368786baecfSMauro Carvalho Chehab else if (tuner_frequency < 420000000) {cp = 5; band = 2;}
1369786baecfSMauro Carvalho Chehab else if (tuner_frequency < 480000000) {cp = 6; band = 2;}
1370786baecfSMauro Carvalho Chehab else if (tuner_frequency < 620000000) {cp = 3; band = 4;}
1371786baecfSMauro Carvalho Chehab else if (tuner_frequency < 830000000) {cp = 5; band = 4;}
1372786baecfSMauro Carvalho Chehab else if (tuner_frequency < 895000000) {cp = 7; band = 4;}
1373786baecfSMauro Carvalho Chehab else {return -EINVAL;}
1374786baecfSMauro Carvalho Chehab
1375786baecfSMauro Carvalho Chehab // assume PLL filter should always be 8MHz for the moment.
1376786baecfSMauro Carvalho Chehab filter = 1;
1377786baecfSMauro Carvalho Chehab
1378786baecfSMauro Carvalho Chehab // calculate divisor
1379786baecfSMauro Carvalho Chehab // (Finput + Fif)/Fref; Fif = 36125000 Hz, Fref = 62500 Hz
1380786baecfSMauro Carvalho Chehab tuner_frequency = ((p->frequency + 36125000) / 62500);
1381786baecfSMauro Carvalho Chehab
1382786baecfSMauro Carvalho Chehab // setup tuner buffer
1383786baecfSMauro Carvalho Chehab tuner_buf[0] = tuner_frequency >> 8;
1384786baecfSMauro Carvalho Chehab tuner_buf[1] = tuner_frequency & 0xff;
1385786baecfSMauro Carvalho Chehab tuner_buf[2] = 0xc8;
1386786baecfSMauro Carvalho Chehab tuner_buf[3] = (cp << 5) | (filter << 3) | band;
1387786baecfSMauro Carvalho Chehab tuner_buf[4] = 0x80;
1388786baecfSMauro Carvalho Chehab
1389786baecfSMauro Carvalho Chehab if (fe->ops.i2c_gate_ctrl)
1390786baecfSMauro Carvalho Chehab fe->ops.i2c_gate_ctrl(fe, 1);
1391786baecfSMauro Carvalho Chehab if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) {
1392*883c84acSMauro Carvalho Chehab pr_err("dvbc_philips_tdm1316l_pll_set Error 1\n");
1393786baecfSMauro Carvalho Chehab return -EIO;
1394786baecfSMauro Carvalho Chehab }
1395786baecfSMauro Carvalho Chehab
1396786baecfSMauro Carvalho Chehab msleep(50);
1397786baecfSMauro Carvalho Chehab
1398786baecfSMauro Carvalho Chehab if (fe->ops.i2c_gate_ctrl)
1399786baecfSMauro Carvalho Chehab fe->ops.i2c_gate_ctrl(fe, 1);
1400786baecfSMauro Carvalho Chehab if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) {
1401*883c84acSMauro Carvalho Chehab pr_err("dvbc_philips_tdm1316l_pll_set Error 2\n");
1402786baecfSMauro Carvalho Chehab return -EIO;
1403786baecfSMauro Carvalho Chehab }
1404786baecfSMauro Carvalho Chehab
1405786baecfSMauro Carvalho Chehab msleep(1);
1406786baecfSMauro Carvalho Chehab
1407786baecfSMauro Carvalho Chehab return 0;
1408786baecfSMauro Carvalho Chehab }
1409786baecfSMauro Carvalho Chehab
1410786baecfSMauro Carvalho Chehab static u8 dvbc_philips_tdm1316l_inittab[] = {
1411786baecfSMauro Carvalho Chehab 0x80, 0x21,
1412786baecfSMauro Carvalho Chehab 0x80, 0x20,
1413786baecfSMauro Carvalho Chehab 0x81, 0x01,
1414786baecfSMauro Carvalho Chehab 0x81, 0x00,
1415786baecfSMauro Carvalho Chehab 0x00, 0x09,
1416786baecfSMauro Carvalho Chehab 0x01, 0x69,
1417786baecfSMauro Carvalho Chehab 0x03, 0x00,
1418786baecfSMauro Carvalho Chehab 0x04, 0x00,
1419786baecfSMauro Carvalho Chehab 0x07, 0x00,
1420786baecfSMauro Carvalho Chehab 0x08, 0x00,
1421786baecfSMauro Carvalho Chehab 0x20, 0x00,
1422786baecfSMauro Carvalho Chehab 0x21, 0x40,
1423786baecfSMauro Carvalho Chehab 0x22, 0x00,
1424786baecfSMauro Carvalho Chehab 0x23, 0x00,
1425786baecfSMauro Carvalho Chehab 0x24, 0x40,
1426786baecfSMauro Carvalho Chehab 0x25, 0x88,
1427786baecfSMauro Carvalho Chehab 0x30, 0xff,
1428786baecfSMauro Carvalho Chehab 0x31, 0x00,
1429786baecfSMauro Carvalho Chehab 0x32, 0xff,
1430786baecfSMauro Carvalho Chehab 0x33, 0x00,
1431786baecfSMauro Carvalho Chehab 0x34, 0x50,
1432786baecfSMauro Carvalho Chehab 0x35, 0x7f,
1433786baecfSMauro Carvalho Chehab 0x36, 0x00,
1434786baecfSMauro Carvalho Chehab 0x37, 0x20,
1435786baecfSMauro Carvalho Chehab 0x38, 0x00,
1436786baecfSMauro Carvalho Chehab 0x40, 0x1c,
1437786baecfSMauro Carvalho Chehab 0x41, 0xff,
1438786baecfSMauro Carvalho Chehab 0x42, 0x29,
1439786baecfSMauro Carvalho Chehab 0x43, 0x20,
1440786baecfSMauro Carvalho Chehab 0x44, 0xff,
1441786baecfSMauro Carvalho Chehab 0x45, 0x00,
1442786baecfSMauro Carvalho Chehab 0x46, 0x00,
1443786baecfSMauro Carvalho Chehab 0x49, 0x04,
1444786baecfSMauro Carvalho Chehab 0x4a, 0xff,
1445786baecfSMauro Carvalho Chehab 0x4b, 0x7f,
1446786baecfSMauro Carvalho Chehab 0x52, 0x30,
1447786baecfSMauro Carvalho Chehab 0x55, 0xae,
1448786baecfSMauro Carvalho Chehab 0x56, 0x47,
1449786baecfSMauro Carvalho Chehab 0x57, 0xe1,
1450786baecfSMauro Carvalho Chehab 0x58, 0x3a,
1451786baecfSMauro Carvalho Chehab 0x5a, 0x1e,
1452786baecfSMauro Carvalho Chehab 0x5b, 0x34,
1453786baecfSMauro Carvalho Chehab 0x60, 0x00,
1454786baecfSMauro Carvalho Chehab 0x63, 0x00,
1455786baecfSMauro Carvalho Chehab 0x64, 0x00,
1456786baecfSMauro Carvalho Chehab 0x65, 0x00,
1457786baecfSMauro Carvalho Chehab 0x66, 0x00,
1458786baecfSMauro Carvalho Chehab 0x67, 0x00,
1459786baecfSMauro Carvalho Chehab 0x68, 0x00,
1460786baecfSMauro Carvalho Chehab 0x69, 0x00,
1461786baecfSMauro Carvalho Chehab 0x6a, 0x02,
1462786baecfSMauro Carvalho Chehab 0x6b, 0x00,
1463786baecfSMauro Carvalho Chehab 0x70, 0xff,
1464786baecfSMauro Carvalho Chehab 0x71, 0x00,
1465786baecfSMauro Carvalho Chehab 0x72, 0x00,
1466786baecfSMauro Carvalho Chehab 0x73, 0x00,
1467786baecfSMauro Carvalho Chehab 0x74, 0x0c,
1468786baecfSMauro Carvalho Chehab 0x80, 0x00,
1469786baecfSMauro Carvalho Chehab 0x81, 0x00,
1470786baecfSMauro Carvalho Chehab 0x82, 0x00,
1471786baecfSMauro Carvalho Chehab 0x83, 0x00,
1472786baecfSMauro Carvalho Chehab 0x84, 0x04,
1473786baecfSMauro Carvalho Chehab 0x85, 0x80,
1474786baecfSMauro Carvalho Chehab 0x86, 0x24,
1475786baecfSMauro Carvalho Chehab 0x87, 0x78,
1476786baecfSMauro Carvalho Chehab 0x88, 0x00,
1477786baecfSMauro Carvalho Chehab 0x89, 0x00,
1478786baecfSMauro Carvalho Chehab 0x90, 0x01,
1479786baecfSMauro Carvalho Chehab 0x91, 0x01,
1480786baecfSMauro Carvalho Chehab 0xa0, 0x00,
1481786baecfSMauro Carvalho Chehab 0xa1, 0x00,
1482786baecfSMauro Carvalho Chehab 0xa2, 0x00,
1483786baecfSMauro Carvalho Chehab 0xb0, 0x91,
1484786baecfSMauro Carvalho Chehab 0xb1, 0x0b,
1485786baecfSMauro Carvalho Chehab 0xc0, 0x4b,
1486786baecfSMauro Carvalho Chehab 0xc1, 0x00,
1487786baecfSMauro Carvalho Chehab 0xc2, 0x00,
1488786baecfSMauro Carvalho Chehab 0xd0, 0x00,
1489786baecfSMauro Carvalho Chehab 0xd1, 0x00,
1490786baecfSMauro Carvalho Chehab 0xd2, 0x00,
1491786baecfSMauro Carvalho Chehab 0xd3, 0x00,
1492786baecfSMauro Carvalho Chehab 0xd4, 0x00,
1493786baecfSMauro Carvalho Chehab 0xd5, 0x00,
1494786baecfSMauro Carvalho Chehab 0xde, 0x00,
1495786baecfSMauro Carvalho Chehab 0xdf, 0x00,
1496786baecfSMauro Carvalho Chehab 0x61, 0x38,
1497786baecfSMauro Carvalho Chehab 0x62, 0x0a,
1498786baecfSMauro Carvalho Chehab 0x53, 0x13,
1499786baecfSMauro Carvalho Chehab 0x59, 0x08,
1500786baecfSMauro Carvalho Chehab 0x55, 0x00,
1501786baecfSMauro Carvalho Chehab 0x56, 0x40,
1502786baecfSMauro Carvalho Chehab 0x57, 0x08,
1503786baecfSMauro Carvalho Chehab 0x58, 0x3d,
1504786baecfSMauro Carvalho Chehab 0x88, 0x10,
1505786baecfSMauro Carvalho Chehab 0xa0, 0x00,
1506786baecfSMauro Carvalho Chehab 0xa0, 0x00,
1507786baecfSMauro Carvalho Chehab 0xa0, 0x00,
1508786baecfSMauro Carvalho Chehab 0xa0, 0x04,
1509786baecfSMauro Carvalho Chehab 0xff, 0xff,
1510786baecfSMauro Carvalho Chehab };
1511786baecfSMauro Carvalho Chehab
1512786baecfSMauro Carvalho Chehab static struct stv0297_config dvbc_philips_tdm1316l_config = {
1513786baecfSMauro Carvalho Chehab .demod_address = 0x1c,
1514786baecfSMauro Carvalho Chehab .inittab = dvbc_philips_tdm1316l_inittab,
1515786baecfSMauro Carvalho Chehab .invert = 0,
1516786baecfSMauro Carvalho Chehab };
1517786baecfSMauro Carvalho Chehab
frontend_init(struct ttusb * ttusb)1518786baecfSMauro Carvalho Chehab static void frontend_init(struct ttusb* ttusb)
1519786baecfSMauro Carvalho Chehab {
1520786baecfSMauro Carvalho Chehab switch(le16_to_cpu(ttusb->dev->descriptor.idProduct)) {
1521786baecfSMauro Carvalho Chehab case 0x1003: // Hauppauge/TT Nova-USB-S budget (stv0299/ALPS BSRU6|BSBE1(tsa5059))
1522786baecfSMauro Carvalho Chehab // try the stv0299 based first
1523786baecfSMauro Carvalho Chehab ttusb->fe = dvb_attach(stv0299_attach, &alps_stv0299_config, &ttusb->i2c_adap);
1524786baecfSMauro Carvalho Chehab if (ttusb->fe != NULL) {
1525786baecfSMauro Carvalho Chehab ttusb->fe->ops.tuner_ops.set_params = philips_tsa5059_tuner_set_params;
1526786baecfSMauro Carvalho Chehab
1527786baecfSMauro Carvalho Chehab if(ttusb->revision == TTUSB_REV_2_2) { // ALPS BSBE1
1528786baecfSMauro Carvalho Chehab alps_stv0299_config.inittab = alps_bsbe1_inittab;
1529786baecfSMauro Carvalho Chehab dvb_attach(lnbp21_attach, ttusb->fe, &ttusb->i2c_adap, 0, 0);
1530786baecfSMauro Carvalho Chehab } else { // ALPS BSRU6
1531786baecfSMauro Carvalho Chehab ttusb->fe->ops.set_voltage = ttusb_set_voltage;
1532786baecfSMauro Carvalho Chehab }
1533786baecfSMauro Carvalho Chehab break;
1534786baecfSMauro Carvalho Chehab }
1535786baecfSMauro Carvalho Chehab
1536786baecfSMauro Carvalho Chehab // Grundig 29504-491
1537786baecfSMauro Carvalho Chehab ttusb->fe = dvb_attach(tda8083_attach, &ttusb_novas_grundig_29504_491_config, &ttusb->i2c_adap);
1538786baecfSMauro Carvalho Chehab if (ttusb->fe != NULL) {
1539786baecfSMauro Carvalho Chehab ttusb->fe->ops.tuner_ops.set_params = ttusb_novas_grundig_29504_491_tuner_set_params;
1540786baecfSMauro Carvalho Chehab ttusb->fe->ops.set_voltage = ttusb_set_voltage;
1541786baecfSMauro Carvalho Chehab break;
1542786baecfSMauro Carvalho Chehab }
1543786baecfSMauro Carvalho Chehab break;
1544786baecfSMauro Carvalho Chehab
1545786baecfSMauro Carvalho Chehab case 0x1004: // Hauppauge/TT DVB-C budget (ves1820/ALPS TDBE2(sp5659))
1546786baecfSMauro Carvalho Chehab ttusb->fe = dvb_attach(ves1820_attach, &alps_tdbe2_config, &ttusb->i2c_adap, read_pwm(ttusb));
1547786baecfSMauro Carvalho Chehab if (ttusb->fe != NULL) {
1548786baecfSMauro Carvalho Chehab ttusb->fe->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params;
1549786baecfSMauro Carvalho Chehab break;
1550786baecfSMauro Carvalho Chehab }
1551786baecfSMauro Carvalho Chehab
1552786baecfSMauro Carvalho Chehab ttusb->fe = dvb_attach(stv0297_attach, &dvbc_philips_tdm1316l_config, &ttusb->i2c_adap);
1553786baecfSMauro Carvalho Chehab if (ttusb->fe != NULL) {
1554786baecfSMauro Carvalho Chehab ttusb->fe->ops.tuner_ops.set_params = dvbc_philips_tdm1316l_tuner_set_params;
1555786baecfSMauro Carvalho Chehab break;
1556786baecfSMauro Carvalho Chehab }
1557786baecfSMauro Carvalho Chehab break;
1558786baecfSMauro Carvalho Chehab
1559786baecfSMauro Carvalho Chehab case 0x1005: // Hauppauge/TT Nova-USB-t budget (tda10046/Philips td1316(tda6651tt) OR cx22700/ALPS TDMB7(??))
1560786baecfSMauro Carvalho Chehab // try the ALPS TDMB7 first
1561786baecfSMauro Carvalho Chehab ttusb->fe = dvb_attach(cx22700_attach, &alps_tdmb7_config, &ttusb->i2c_adap);
1562786baecfSMauro Carvalho Chehab if (ttusb->fe != NULL) {
1563786baecfSMauro Carvalho Chehab ttusb->fe->ops.tuner_ops.set_params = alps_tdmb7_tuner_set_params;
1564786baecfSMauro Carvalho Chehab break;
1565786baecfSMauro Carvalho Chehab }
1566786baecfSMauro Carvalho Chehab
1567786baecfSMauro Carvalho Chehab // Philips td1316
1568786baecfSMauro Carvalho Chehab ttusb->fe = dvb_attach(tda10046_attach, &philips_tdm1316l_config, &ttusb->i2c_adap);
1569786baecfSMauro Carvalho Chehab if (ttusb->fe != NULL) {
1570786baecfSMauro Carvalho Chehab ttusb->fe->ops.tuner_ops.init = philips_tdm1316l_tuner_init;
1571786baecfSMauro Carvalho Chehab ttusb->fe->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params;
1572786baecfSMauro Carvalho Chehab break;
1573786baecfSMauro Carvalho Chehab }
1574786baecfSMauro Carvalho Chehab break;
1575786baecfSMauro Carvalho Chehab }
1576786baecfSMauro Carvalho Chehab
1577786baecfSMauro Carvalho Chehab if (ttusb->fe == NULL) {
1578*883c84acSMauro Carvalho Chehab pr_err("no frontend driver found for device [%04x:%04x]\n",
1579786baecfSMauro Carvalho Chehab le16_to_cpu(ttusb->dev->descriptor.idVendor),
1580786baecfSMauro Carvalho Chehab le16_to_cpu(ttusb->dev->descriptor.idProduct));
1581786baecfSMauro Carvalho Chehab } else {
1582786baecfSMauro Carvalho Chehab if (dvb_register_frontend(&ttusb->adapter, ttusb->fe)) {
1583*883c84acSMauro Carvalho Chehab pr_err("Frontend registration failed!\n");
1584786baecfSMauro Carvalho Chehab dvb_frontend_detach(ttusb->fe);
1585786baecfSMauro Carvalho Chehab ttusb->fe = NULL;
1586786baecfSMauro Carvalho Chehab }
1587786baecfSMauro Carvalho Chehab }
1588786baecfSMauro Carvalho Chehab }
1589786baecfSMauro Carvalho Chehab
1590786baecfSMauro Carvalho Chehab
1591786baecfSMauro Carvalho Chehab
15928d08a4c1SGustavo A. R. Silva static const struct i2c_algorithm ttusb_dec_algo = {
1593786baecfSMauro Carvalho Chehab .master_xfer = master_xfer,
1594786baecfSMauro Carvalho Chehab .functionality = functionality,
1595786baecfSMauro Carvalho Chehab };
1596786baecfSMauro Carvalho Chehab
ttusb_probe(struct usb_interface * intf,const struct usb_device_id * id)1597786baecfSMauro Carvalho Chehab static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *id)
1598786baecfSMauro Carvalho Chehab {
1599786baecfSMauro Carvalho Chehab struct usb_device *udev;
1600786baecfSMauro Carvalho Chehab struct ttusb *ttusb;
1601786baecfSMauro Carvalho Chehab int result;
1602786baecfSMauro Carvalho Chehab
1603*883c84acSMauro Carvalho Chehab dprintk("TTUSB DVB connected\n");
1604786baecfSMauro Carvalho Chehab
1605786baecfSMauro Carvalho Chehab udev = interface_to_usbdev(intf);
1606786baecfSMauro Carvalho Chehab
1607786baecfSMauro Carvalho Chehab if (intf->altsetting->desc.bInterfaceNumber != 1) return -ENODEV;
1608786baecfSMauro Carvalho Chehab
1609786baecfSMauro Carvalho Chehab if (!(ttusb = kzalloc(sizeof(struct ttusb), GFP_KERNEL)))
1610786baecfSMauro Carvalho Chehab return -ENOMEM;
1611786baecfSMauro Carvalho Chehab
1612786baecfSMauro Carvalho Chehab ttusb->dev = udev;
1613786baecfSMauro Carvalho Chehab ttusb->c = 0;
1614786baecfSMauro Carvalho Chehab ttusb->mux_state = 0;
1615786baecfSMauro Carvalho Chehab mutex_init(&ttusb->semi2c);
1616786baecfSMauro Carvalho Chehab
1617786baecfSMauro Carvalho Chehab mutex_lock(&ttusb->semi2c);
1618786baecfSMauro Carvalho Chehab
1619786baecfSMauro Carvalho Chehab mutex_init(&ttusb->semusb);
1620786baecfSMauro Carvalho Chehab
1621786baecfSMauro Carvalho Chehab ttusb_setup_interfaces(ttusb);
1622786baecfSMauro Carvalho Chehab
1623786baecfSMauro Carvalho Chehab result = ttusb_alloc_iso_urbs(ttusb);
1624786baecfSMauro Carvalho Chehab if (result < 0) {
1625*883c84acSMauro Carvalho Chehab dprintk("ttusb_alloc_iso_urbs - failed\n");
1626786baecfSMauro Carvalho Chehab mutex_unlock(&ttusb->semi2c);
1627786baecfSMauro Carvalho Chehab kfree(ttusb);
1628786baecfSMauro Carvalho Chehab return result;
1629786baecfSMauro Carvalho Chehab }
1630786baecfSMauro Carvalho Chehab
1631786baecfSMauro Carvalho Chehab if (ttusb_init_controller(ttusb))
1632*883c84acSMauro Carvalho Chehab pr_err("ttusb_init_controller: error\n");
1633786baecfSMauro Carvalho Chehab
1634786baecfSMauro Carvalho Chehab mutex_unlock(&ttusb->semi2c);
1635786baecfSMauro Carvalho Chehab
1636786baecfSMauro Carvalho Chehab result = dvb_register_adapter(&ttusb->adapter,
1637786baecfSMauro Carvalho Chehab "Technotrend/Hauppauge Nova-USB",
1638786baecfSMauro Carvalho Chehab THIS_MODULE, &udev->dev, adapter_nr);
1639786baecfSMauro Carvalho Chehab if (result < 0) {
1640786baecfSMauro Carvalho Chehab ttusb_free_iso_urbs(ttusb);
1641786baecfSMauro Carvalho Chehab kfree(ttusb);
1642786baecfSMauro Carvalho Chehab return result;
1643786baecfSMauro Carvalho Chehab }
1644786baecfSMauro Carvalho Chehab ttusb->adapter.priv = ttusb;
1645786baecfSMauro Carvalho Chehab
1646786baecfSMauro Carvalho Chehab /* i2c */
1647786baecfSMauro Carvalho Chehab memset(&ttusb->i2c_adap, 0, sizeof(struct i2c_adapter));
1648cc1e6315SMauro Carvalho Chehab strscpy(ttusb->i2c_adap.name, "TTUSB DEC", sizeof(ttusb->i2c_adap.name));
1649786baecfSMauro Carvalho Chehab
1650786baecfSMauro Carvalho Chehab i2c_set_adapdata(&ttusb->i2c_adap, ttusb);
1651786baecfSMauro Carvalho Chehab
1652786baecfSMauro Carvalho Chehab ttusb->i2c_adap.algo = &ttusb_dec_algo;
1653786baecfSMauro Carvalho Chehab ttusb->i2c_adap.algo_data = NULL;
1654786baecfSMauro Carvalho Chehab ttusb->i2c_adap.dev.parent = &udev->dev;
1655786baecfSMauro Carvalho Chehab
1656786baecfSMauro Carvalho Chehab result = i2c_add_adapter(&ttusb->i2c_adap);
1657786baecfSMauro Carvalho Chehab if (result)
1658786baecfSMauro Carvalho Chehab goto err_unregister_adapter;
1659786baecfSMauro Carvalho Chehab
1660786baecfSMauro Carvalho Chehab memset(&ttusb->dvb_demux, 0, sizeof(ttusb->dvb_demux));
1661786baecfSMauro Carvalho Chehab
1662786baecfSMauro Carvalho Chehab ttusb->dvb_demux.dmx.capabilities =
1663786baecfSMauro Carvalho Chehab DMX_TS_FILTERING | DMX_SECTION_FILTERING;
1664786baecfSMauro Carvalho Chehab ttusb->dvb_demux.priv = NULL;
1665786baecfSMauro Carvalho Chehab #ifdef TTUSB_HWSECTIONS
1666786baecfSMauro Carvalho Chehab ttusb->dvb_demux.filternum = TTUSB_MAXFILTER;
1667786baecfSMauro Carvalho Chehab #else
1668786baecfSMauro Carvalho Chehab ttusb->dvb_demux.filternum = 32;
1669786baecfSMauro Carvalho Chehab #endif
1670786baecfSMauro Carvalho Chehab ttusb->dvb_demux.feednum = TTUSB_MAXCHANNEL;
1671786baecfSMauro Carvalho Chehab ttusb->dvb_demux.start_feed = ttusb_start_feed;
1672786baecfSMauro Carvalho Chehab ttusb->dvb_demux.stop_feed = ttusb_stop_feed;
1673786baecfSMauro Carvalho Chehab ttusb->dvb_demux.write_to_decoder = NULL;
1674786baecfSMauro Carvalho Chehab
1675786baecfSMauro Carvalho Chehab result = dvb_dmx_init(&ttusb->dvb_demux);
1676786baecfSMauro Carvalho Chehab if (result < 0) {
1677*883c84acSMauro Carvalho Chehab pr_err("dvb_dmx_init failed (errno = %d)\n", result);
1678786baecfSMauro Carvalho Chehab result = -ENODEV;
1679786baecfSMauro Carvalho Chehab goto err_i2c_del_adapter;
1680786baecfSMauro Carvalho Chehab }
1681786baecfSMauro Carvalho Chehab //FIXME dmxdev (nur WAS?)
1682786baecfSMauro Carvalho Chehab ttusb->dmxdev.filternum = ttusb->dvb_demux.filternum;
1683786baecfSMauro Carvalho Chehab ttusb->dmxdev.demux = &ttusb->dvb_demux.dmx;
1684786baecfSMauro Carvalho Chehab ttusb->dmxdev.capabilities = 0;
1685786baecfSMauro Carvalho Chehab
1686786baecfSMauro Carvalho Chehab result = dvb_dmxdev_init(&ttusb->dmxdev, &ttusb->adapter);
1687786baecfSMauro Carvalho Chehab if (result < 0) {
1688*883c84acSMauro Carvalho Chehab pr_err("dvb_dmxdev_init failed (errno = %d)\n",
1689786baecfSMauro Carvalho Chehab result);
1690786baecfSMauro Carvalho Chehab result = -ENODEV;
1691786baecfSMauro Carvalho Chehab goto err_release_dmx;
1692786baecfSMauro Carvalho Chehab }
1693786baecfSMauro Carvalho Chehab
1694786baecfSMauro Carvalho Chehab if (dvb_net_init(&ttusb->adapter, &ttusb->dvbnet, &ttusb->dvb_demux.dmx)) {
1695*883c84acSMauro Carvalho Chehab pr_err("dvb_net_init failed!\n");
1696786baecfSMauro Carvalho Chehab result = -ENODEV;
1697786baecfSMauro Carvalho Chehab goto err_release_dmxdev;
1698786baecfSMauro Carvalho Chehab }
1699786baecfSMauro Carvalho Chehab
1700786baecfSMauro Carvalho Chehab usb_set_intfdata(intf, (void *) ttusb);
1701786baecfSMauro Carvalho Chehab
1702786baecfSMauro Carvalho Chehab frontend_init(ttusb);
1703786baecfSMauro Carvalho Chehab
1704786baecfSMauro Carvalho Chehab return 0;
1705786baecfSMauro Carvalho Chehab
1706786baecfSMauro Carvalho Chehab err_release_dmxdev:
1707786baecfSMauro Carvalho Chehab dvb_dmxdev_release(&ttusb->dmxdev);
1708786baecfSMauro Carvalho Chehab err_release_dmx:
1709786baecfSMauro Carvalho Chehab dvb_dmx_release(&ttusb->dvb_demux);
1710786baecfSMauro Carvalho Chehab err_i2c_del_adapter:
1711786baecfSMauro Carvalho Chehab i2c_del_adapter(&ttusb->i2c_adap);
1712786baecfSMauro Carvalho Chehab err_unregister_adapter:
1713786baecfSMauro Carvalho Chehab dvb_unregister_adapter (&ttusb->adapter);
1714b9d4b2daSAlexey Khoroshilov ttusb_free_iso_urbs(ttusb);
1715b9d4b2daSAlexey Khoroshilov kfree(ttusb);
1716786baecfSMauro Carvalho Chehab return result;
1717786baecfSMauro Carvalho Chehab }
1718786baecfSMauro Carvalho Chehab
ttusb_disconnect(struct usb_interface * intf)1719786baecfSMauro Carvalho Chehab static void ttusb_disconnect(struct usb_interface *intf)
1720786baecfSMauro Carvalho Chehab {
1721786baecfSMauro Carvalho Chehab struct ttusb *ttusb = usb_get_intfdata(intf);
1722786baecfSMauro Carvalho Chehab
1723786baecfSMauro Carvalho Chehab usb_set_intfdata(intf, NULL);
1724786baecfSMauro Carvalho Chehab
1725786baecfSMauro Carvalho Chehab ttusb->disconnecting = 1;
1726786baecfSMauro Carvalho Chehab
1727786baecfSMauro Carvalho Chehab ttusb_stop_iso_xfer(ttusb);
1728786baecfSMauro Carvalho Chehab
1729786baecfSMauro Carvalho Chehab ttusb->dvb_demux.dmx.close(&ttusb->dvb_demux.dmx);
1730786baecfSMauro Carvalho Chehab dvb_net_release(&ttusb->dvbnet);
1731786baecfSMauro Carvalho Chehab dvb_dmxdev_release(&ttusb->dmxdev);
1732786baecfSMauro Carvalho Chehab dvb_dmx_release(&ttusb->dvb_demux);
1733786baecfSMauro Carvalho Chehab if (ttusb->fe != NULL) {
1734786baecfSMauro Carvalho Chehab dvb_unregister_frontend(ttusb->fe);
1735786baecfSMauro Carvalho Chehab dvb_frontend_detach(ttusb->fe);
1736786baecfSMauro Carvalho Chehab }
1737786baecfSMauro Carvalho Chehab i2c_del_adapter(&ttusb->i2c_adap);
1738786baecfSMauro Carvalho Chehab dvb_unregister_adapter(&ttusb->adapter);
1739786baecfSMauro Carvalho Chehab
1740786baecfSMauro Carvalho Chehab ttusb_free_iso_urbs(ttusb);
1741786baecfSMauro Carvalho Chehab
1742786baecfSMauro Carvalho Chehab kfree(ttusb);
1743786baecfSMauro Carvalho Chehab
1744*883c84acSMauro Carvalho Chehab dprintk("TTUSB DVB disconnected\n");
1745786baecfSMauro Carvalho Chehab }
1746786baecfSMauro Carvalho Chehab
17477fb2e072SArvind Yadav static const struct usb_device_id ttusb_table[] = {
1748786baecfSMauro Carvalho Chehab {USB_DEVICE(0xb48, 0x1003)},
1749786baecfSMauro Carvalho Chehab {USB_DEVICE(0xb48, 0x1004)},
1750786baecfSMauro Carvalho Chehab {USB_DEVICE(0xb48, 0x1005)},
1751786baecfSMauro Carvalho Chehab {}
1752786baecfSMauro Carvalho Chehab };
1753786baecfSMauro Carvalho Chehab
1754786baecfSMauro Carvalho Chehab MODULE_DEVICE_TABLE(usb, ttusb_table);
1755786baecfSMauro Carvalho Chehab
1756786baecfSMauro Carvalho Chehab static struct usb_driver ttusb_driver = {
1757786baecfSMauro Carvalho Chehab .name = "ttusb",
1758786baecfSMauro Carvalho Chehab .probe = ttusb_probe,
1759786baecfSMauro Carvalho Chehab .disconnect = ttusb_disconnect,
1760786baecfSMauro Carvalho Chehab .id_table = ttusb_table,
1761786baecfSMauro Carvalho Chehab };
1762786baecfSMauro Carvalho Chehab
1763786baecfSMauro Carvalho Chehab module_usb_driver(ttusb_driver);
1764786baecfSMauro Carvalho Chehab
1765786baecfSMauro Carvalho Chehab MODULE_AUTHOR("Holger Waechtler <holger@convergence.de>");
1766786baecfSMauro Carvalho Chehab MODULE_DESCRIPTION("TTUSB DVB Driver");
1767786baecfSMauro Carvalho Chehab MODULE_LICENSE("GPL");
1768786baecfSMauro Carvalho Chehab MODULE_FIRMWARE("ttusb-budget/dspbootcode.bin");
1769