1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun Driver for ST STV0299 demodulator
4*4882a593Smuzhiyun
5*4882a593Smuzhiyun Copyright (C) 2001-2002 Convergence Integrated Media GmbH
6*4882a593Smuzhiyun <ralph@convergence.de>,
7*4882a593Smuzhiyun <holger@convergence.de>,
8*4882a593Smuzhiyun <js@convergence.de>
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun Philips SU1278/SH
12*4882a593Smuzhiyun
13*4882a593Smuzhiyun Copyright (C) 2002 by Peter Schildmann <peter.schildmann@web.de>
14*4882a593Smuzhiyun
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun LG TDQF-S001F
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun Copyright (C) 2002 Felix Domke <tmbinc@elitedvb.net>
19*4882a593Smuzhiyun & Andreas Oberritter <obi@linuxtv.org>
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun
22*4882a593Smuzhiyun Support for Samsung TBMU24112IMB used on Technisat SkyStar2 rev. 2.6B
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun Copyright (C) 2003 Vadim Catana <skystar@moldova.cc>:
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun Support for Philips SU1278 on Technotrend hardware
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun Copyright (C) 2004 Andrew de Quincey <adq_dvb@lidskialf.net>
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun */
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun #include <linux/init.h>
34*4882a593Smuzhiyun #include <linux/kernel.h>
35*4882a593Smuzhiyun #include <linux/ktime.h>
36*4882a593Smuzhiyun #include <linux/module.h>
37*4882a593Smuzhiyun #include <linux/string.h>
38*4882a593Smuzhiyun #include <linux/slab.h>
39*4882a593Smuzhiyun #include <linux/jiffies.h>
40*4882a593Smuzhiyun #include <asm/div64.h>
41*4882a593Smuzhiyun
42*4882a593Smuzhiyun #include <media/dvb_frontend.h>
43*4882a593Smuzhiyun #include "stv0299.h"
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun struct stv0299_state {
46*4882a593Smuzhiyun struct i2c_adapter* i2c;
47*4882a593Smuzhiyun const struct stv0299_config* config;
48*4882a593Smuzhiyun struct dvb_frontend frontend;
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun u8 initialised:1;
51*4882a593Smuzhiyun u32 tuner_frequency;
52*4882a593Smuzhiyun u32 symbol_rate;
53*4882a593Smuzhiyun enum fe_code_rate fec_inner;
54*4882a593Smuzhiyun int errmode;
55*4882a593Smuzhiyun u32 ucblocks;
56*4882a593Smuzhiyun u8 mcr_reg;
57*4882a593Smuzhiyun };
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun #define STATUS_BER 0
60*4882a593Smuzhiyun #define STATUS_UCBLOCKS 1
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun static int debug;
63*4882a593Smuzhiyun static int debug_legacy_dish_switch;
64*4882a593Smuzhiyun #define dprintk(args...) \
65*4882a593Smuzhiyun do { \
66*4882a593Smuzhiyun if (debug) printk(KERN_DEBUG "stv0299: " args); \
67*4882a593Smuzhiyun } while (0)
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun
stv0299_writeregI(struct stv0299_state * state,u8 reg,u8 data)70*4882a593Smuzhiyun static int stv0299_writeregI (struct stv0299_state* state, u8 reg, u8 data)
71*4882a593Smuzhiyun {
72*4882a593Smuzhiyun int ret;
73*4882a593Smuzhiyun u8 buf [] = { reg, data };
74*4882a593Smuzhiyun struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun ret = i2c_transfer (state->i2c, &msg, 1);
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun if (ret != 1)
79*4882a593Smuzhiyun dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, ret == %i)\n",
80*4882a593Smuzhiyun __func__, reg, data, ret);
81*4882a593Smuzhiyun
82*4882a593Smuzhiyun return (ret != 1) ? -EREMOTEIO : 0;
83*4882a593Smuzhiyun }
84*4882a593Smuzhiyun
stv0299_write(struct dvb_frontend * fe,const u8 buf[],int len)85*4882a593Smuzhiyun static int stv0299_write(struct dvb_frontend* fe, const u8 buf[], int len)
86*4882a593Smuzhiyun {
87*4882a593Smuzhiyun struct stv0299_state* state = fe->demodulator_priv;
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun if (len != 2)
90*4882a593Smuzhiyun return -EINVAL;
91*4882a593Smuzhiyun
92*4882a593Smuzhiyun return stv0299_writeregI(state, buf[0], buf[1]);
93*4882a593Smuzhiyun }
94*4882a593Smuzhiyun
stv0299_readreg(struct stv0299_state * state,u8 reg)95*4882a593Smuzhiyun static u8 stv0299_readreg (struct stv0299_state* state, u8 reg)
96*4882a593Smuzhiyun {
97*4882a593Smuzhiyun int ret;
98*4882a593Smuzhiyun u8 b0 [] = { reg };
99*4882a593Smuzhiyun u8 b1 [] = { 0 };
100*4882a593Smuzhiyun struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
101*4882a593Smuzhiyun { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun ret = i2c_transfer (state->i2c, msg, 2);
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun if (ret != 2)
106*4882a593Smuzhiyun dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n",
107*4882a593Smuzhiyun __func__, reg, ret);
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun return b1[0];
110*4882a593Smuzhiyun }
111*4882a593Smuzhiyun
stv0299_readregs(struct stv0299_state * state,u8 reg1,u8 * b,u8 len)112*4882a593Smuzhiyun static int stv0299_readregs (struct stv0299_state* state, u8 reg1, u8 *b, u8 len)
113*4882a593Smuzhiyun {
114*4882a593Smuzhiyun int ret;
115*4882a593Smuzhiyun struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = ®1, .len = 1 },
116*4882a593Smuzhiyun { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b, .len = len } };
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun ret = i2c_transfer (state->i2c, msg, 2);
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun if (ret != 2)
121*4882a593Smuzhiyun dprintk("%s: readreg error (ret == %i)\n", __func__, ret);
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun return ret == 2 ? 0 : ret;
124*4882a593Smuzhiyun }
125*4882a593Smuzhiyun
stv0299_set_FEC(struct stv0299_state * state,enum fe_code_rate fec)126*4882a593Smuzhiyun static int stv0299_set_FEC(struct stv0299_state *state, enum fe_code_rate fec)
127*4882a593Smuzhiyun {
128*4882a593Smuzhiyun dprintk ("%s\n", __func__);
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun switch (fec) {
131*4882a593Smuzhiyun case FEC_AUTO:
132*4882a593Smuzhiyun {
133*4882a593Smuzhiyun return stv0299_writeregI (state, 0x31, 0x1f);
134*4882a593Smuzhiyun }
135*4882a593Smuzhiyun case FEC_1_2:
136*4882a593Smuzhiyun {
137*4882a593Smuzhiyun return stv0299_writeregI (state, 0x31, 0x01);
138*4882a593Smuzhiyun }
139*4882a593Smuzhiyun case FEC_2_3:
140*4882a593Smuzhiyun {
141*4882a593Smuzhiyun return stv0299_writeregI (state, 0x31, 0x02);
142*4882a593Smuzhiyun }
143*4882a593Smuzhiyun case FEC_3_4:
144*4882a593Smuzhiyun {
145*4882a593Smuzhiyun return stv0299_writeregI (state, 0x31, 0x04);
146*4882a593Smuzhiyun }
147*4882a593Smuzhiyun case FEC_5_6:
148*4882a593Smuzhiyun {
149*4882a593Smuzhiyun return stv0299_writeregI (state, 0x31, 0x08);
150*4882a593Smuzhiyun }
151*4882a593Smuzhiyun case FEC_7_8:
152*4882a593Smuzhiyun {
153*4882a593Smuzhiyun return stv0299_writeregI (state, 0x31, 0x10);
154*4882a593Smuzhiyun }
155*4882a593Smuzhiyun default:
156*4882a593Smuzhiyun {
157*4882a593Smuzhiyun return -EINVAL;
158*4882a593Smuzhiyun }
159*4882a593Smuzhiyun }
160*4882a593Smuzhiyun }
161*4882a593Smuzhiyun
stv0299_get_fec(struct stv0299_state * state)162*4882a593Smuzhiyun static enum fe_code_rate stv0299_get_fec(struct stv0299_state *state)
163*4882a593Smuzhiyun {
164*4882a593Smuzhiyun static enum fe_code_rate fec_tab[] = { FEC_2_3, FEC_3_4, FEC_5_6,
165*4882a593Smuzhiyun FEC_7_8, FEC_1_2 };
166*4882a593Smuzhiyun u8 index;
167*4882a593Smuzhiyun
168*4882a593Smuzhiyun dprintk ("%s\n", __func__);
169*4882a593Smuzhiyun
170*4882a593Smuzhiyun index = stv0299_readreg (state, 0x1b);
171*4882a593Smuzhiyun index &= 0x7;
172*4882a593Smuzhiyun
173*4882a593Smuzhiyun if (index > 4)
174*4882a593Smuzhiyun return FEC_AUTO;
175*4882a593Smuzhiyun
176*4882a593Smuzhiyun return fec_tab [index];
177*4882a593Smuzhiyun }
178*4882a593Smuzhiyun
stv0299_wait_diseqc_fifo(struct stv0299_state * state,int timeout)179*4882a593Smuzhiyun static int stv0299_wait_diseqc_fifo (struct stv0299_state* state, int timeout)
180*4882a593Smuzhiyun {
181*4882a593Smuzhiyun unsigned long start = jiffies;
182*4882a593Smuzhiyun
183*4882a593Smuzhiyun dprintk ("%s\n", __func__);
184*4882a593Smuzhiyun
185*4882a593Smuzhiyun while (stv0299_readreg(state, 0x0a) & 1) {
186*4882a593Smuzhiyun if (jiffies - start > timeout) {
187*4882a593Smuzhiyun dprintk ("%s: timeout!!\n", __func__);
188*4882a593Smuzhiyun return -ETIMEDOUT;
189*4882a593Smuzhiyun }
190*4882a593Smuzhiyun msleep(10);
191*4882a593Smuzhiyun }
192*4882a593Smuzhiyun
193*4882a593Smuzhiyun return 0;
194*4882a593Smuzhiyun }
195*4882a593Smuzhiyun
stv0299_wait_diseqc_idle(struct stv0299_state * state,int timeout)196*4882a593Smuzhiyun static int stv0299_wait_diseqc_idle (struct stv0299_state* state, int timeout)
197*4882a593Smuzhiyun {
198*4882a593Smuzhiyun unsigned long start = jiffies;
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun dprintk ("%s\n", __func__);
201*4882a593Smuzhiyun
202*4882a593Smuzhiyun while ((stv0299_readreg(state, 0x0a) & 3) != 2 ) {
203*4882a593Smuzhiyun if (jiffies - start > timeout) {
204*4882a593Smuzhiyun dprintk ("%s: timeout!!\n", __func__);
205*4882a593Smuzhiyun return -ETIMEDOUT;
206*4882a593Smuzhiyun }
207*4882a593Smuzhiyun msleep(10);
208*4882a593Smuzhiyun }
209*4882a593Smuzhiyun
210*4882a593Smuzhiyun return 0;
211*4882a593Smuzhiyun }
212*4882a593Smuzhiyun
stv0299_set_symbolrate(struct dvb_frontend * fe,u32 srate)213*4882a593Smuzhiyun static int stv0299_set_symbolrate (struct dvb_frontend* fe, u32 srate)
214*4882a593Smuzhiyun {
215*4882a593Smuzhiyun struct stv0299_state* state = fe->demodulator_priv;
216*4882a593Smuzhiyun u64 big = srate;
217*4882a593Smuzhiyun u32 ratio;
218*4882a593Smuzhiyun
219*4882a593Smuzhiyun // check rate is within limits
220*4882a593Smuzhiyun if ((srate < 1000000) || (srate > 45000000)) return -EINVAL;
221*4882a593Smuzhiyun
222*4882a593Smuzhiyun // calculate value to program
223*4882a593Smuzhiyun big = big << 20;
224*4882a593Smuzhiyun big += (state->config->mclk-1); // round correctly
225*4882a593Smuzhiyun do_div(big, state->config->mclk);
226*4882a593Smuzhiyun ratio = big << 4;
227*4882a593Smuzhiyun
228*4882a593Smuzhiyun return state->config->set_symbol_rate(fe, srate, ratio);
229*4882a593Smuzhiyun }
230*4882a593Smuzhiyun
stv0299_get_symbolrate(struct stv0299_state * state)231*4882a593Smuzhiyun static int stv0299_get_symbolrate (struct stv0299_state* state)
232*4882a593Smuzhiyun {
233*4882a593Smuzhiyun u32 Mclk = state->config->mclk / 4096L;
234*4882a593Smuzhiyun u32 srate;
235*4882a593Smuzhiyun s32 offset;
236*4882a593Smuzhiyun u8 sfr[3];
237*4882a593Smuzhiyun s8 rtf;
238*4882a593Smuzhiyun
239*4882a593Smuzhiyun dprintk ("%s\n", __func__);
240*4882a593Smuzhiyun
241*4882a593Smuzhiyun stv0299_readregs (state, 0x1f, sfr, 3);
242*4882a593Smuzhiyun stv0299_readregs (state, 0x1a, (u8 *)&rtf, 1);
243*4882a593Smuzhiyun
244*4882a593Smuzhiyun srate = (sfr[0] << 8) | sfr[1];
245*4882a593Smuzhiyun srate *= Mclk;
246*4882a593Smuzhiyun srate /= 16;
247*4882a593Smuzhiyun srate += (sfr[2] >> 4) * Mclk / 256;
248*4882a593Smuzhiyun offset = (s32) rtf * (srate / 4096L);
249*4882a593Smuzhiyun offset /= 128;
250*4882a593Smuzhiyun
251*4882a593Smuzhiyun dprintk ("%s : srate = %i\n", __func__, srate);
252*4882a593Smuzhiyun dprintk ("%s : ofset = %i\n", __func__, offset);
253*4882a593Smuzhiyun
254*4882a593Smuzhiyun srate += offset;
255*4882a593Smuzhiyun
256*4882a593Smuzhiyun srate += 1000;
257*4882a593Smuzhiyun srate /= 2000;
258*4882a593Smuzhiyun srate *= 2000;
259*4882a593Smuzhiyun
260*4882a593Smuzhiyun return srate;
261*4882a593Smuzhiyun }
262*4882a593Smuzhiyun
stv0299_send_diseqc_msg(struct dvb_frontend * fe,struct dvb_diseqc_master_cmd * m)263*4882a593Smuzhiyun static int stv0299_send_diseqc_msg (struct dvb_frontend* fe,
264*4882a593Smuzhiyun struct dvb_diseqc_master_cmd *m)
265*4882a593Smuzhiyun {
266*4882a593Smuzhiyun struct stv0299_state* state = fe->demodulator_priv;
267*4882a593Smuzhiyun u8 val;
268*4882a593Smuzhiyun int i;
269*4882a593Smuzhiyun
270*4882a593Smuzhiyun dprintk ("%s\n", __func__);
271*4882a593Smuzhiyun
272*4882a593Smuzhiyun if (stv0299_wait_diseqc_idle (state, 100) < 0)
273*4882a593Smuzhiyun return -ETIMEDOUT;
274*4882a593Smuzhiyun
275*4882a593Smuzhiyun val = stv0299_readreg (state, 0x08);
276*4882a593Smuzhiyun
277*4882a593Smuzhiyun if (stv0299_writeregI (state, 0x08, (val & ~0x7) | 0x6)) /* DiSEqC mode */
278*4882a593Smuzhiyun return -EREMOTEIO;
279*4882a593Smuzhiyun
280*4882a593Smuzhiyun for (i=0; i<m->msg_len; i++) {
281*4882a593Smuzhiyun if (stv0299_wait_diseqc_fifo (state, 100) < 0)
282*4882a593Smuzhiyun return -ETIMEDOUT;
283*4882a593Smuzhiyun
284*4882a593Smuzhiyun if (stv0299_writeregI (state, 0x09, m->msg[i]))
285*4882a593Smuzhiyun return -EREMOTEIO;
286*4882a593Smuzhiyun }
287*4882a593Smuzhiyun
288*4882a593Smuzhiyun if (stv0299_wait_diseqc_idle (state, 100) < 0)
289*4882a593Smuzhiyun return -ETIMEDOUT;
290*4882a593Smuzhiyun
291*4882a593Smuzhiyun return 0;
292*4882a593Smuzhiyun }
293*4882a593Smuzhiyun
stv0299_send_diseqc_burst(struct dvb_frontend * fe,enum fe_sec_mini_cmd burst)294*4882a593Smuzhiyun static int stv0299_send_diseqc_burst(struct dvb_frontend *fe,
295*4882a593Smuzhiyun enum fe_sec_mini_cmd burst)
296*4882a593Smuzhiyun {
297*4882a593Smuzhiyun struct stv0299_state* state = fe->demodulator_priv;
298*4882a593Smuzhiyun u8 val;
299*4882a593Smuzhiyun
300*4882a593Smuzhiyun dprintk ("%s\n", __func__);
301*4882a593Smuzhiyun
302*4882a593Smuzhiyun if (stv0299_wait_diseqc_idle (state, 100) < 0)
303*4882a593Smuzhiyun return -ETIMEDOUT;
304*4882a593Smuzhiyun
305*4882a593Smuzhiyun val = stv0299_readreg (state, 0x08);
306*4882a593Smuzhiyun
307*4882a593Smuzhiyun if (stv0299_writeregI (state, 0x08, (val & ~0x7) | 0x2)) /* burst mode */
308*4882a593Smuzhiyun return -EREMOTEIO;
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun if (stv0299_writeregI (state, 0x09, burst == SEC_MINI_A ? 0x00 : 0xff))
311*4882a593Smuzhiyun return -EREMOTEIO;
312*4882a593Smuzhiyun
313*4882a593Smuzhiyun if (stv0299_wait_diseqc_idle (state, 100) < 0)
314*4882a593Smuzhiyun return -ETIMEDOUT;
315*4882a593Smuzhiyun
316*4882a593Smuzhiyun if (stv0299_writeregI (state, 0x08, val))
317*4882a593Smuzhiyun return -EREMOTEIO;
318*4882a593Smuzhiyun
319*4882a593Smuzhiyun return 0;
320*4882a593Smuzhiyun }
321*4882a593Smuzhiyun
stv0299_set_tone(struct dvb_frontend * fe,enum fe_sec_tone_mode tone)322*4882a593Smuzhiyun static int stv0299_set_tone(struct dvb_frontend *fe,
323*4882a593Smuzhiyun enum fe_sec_tone_mode tone)
324*4882a593Smuzhiyun {
325*4882a593Smuzhiyun struct stv0299_state* state = fe->demodulator_priv;
326*4882a593Smuzhiyun u8 val;
327*4882a593Smuzhiyun
328*4882a593Smuzhiyun if (stv0299_wait_diseqc_idle (state, 100) < 0)
329*4882a593Smuzhiyun return -ETIMEDOUT;
330*4882a593Smuzhiyun
331*4882a593Smuzhiyun val = stv0299_readreg (state, 0x08);
332*4882a593Smuzhiyun
333*4882a593Smuzhiyun switch (tone) {
334*4882a593Smuzhiyun case SEC_TONE_ON:
335*4882a593Smuzhiyun return stv0299_writeregI (state, 0x08, val | 0x3);
336*4882a593Smuzhiyun
337*4882a593Smuzhiyun case SEC_TONE_OFF:
338*4882a593Smuzhiyun return stv0299_writeregI (state, 0x08, (val & ~0x3) | 0x02);
339*4882a593Smuzhiyun
340*4882a593Smuzhiyun default:
341*4882a593Smuzhiyun return -EINVAL;
342*4882a593Smuzhiyun }
343*4882a593Smuzhiyun }
344*4882a593Smuzhiyun
stv0299_set_voltage(struct dvb_frontend * fe,enum fe_sec_voltage voltage)345*4882a593Smuzhiyun static int stv0299_set_voltage(struct dvb_frontend *fe,
346*4882a593Smuzhiyun enum fe_sec_voltage voltage)
347*4882a593Smuzhiyun {
348*4882a593Smuzhiyun struct stv0299_state* state = fe->demodulator_priv;
349*4882a593Smuzhiyun u8 reg0x08;
350*4882a593Smuzhiyun u8 reg0x0c;
351*4882a593Smuzhiyun
352*4882a593Smuzhiyun dprintk("%s: %s\n", __func__,
353*4882a593Smuzhiyun voltage == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
354*4882a593Smuzhiyun voltage == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
355*4882a593Smuzhiyun
356*4882a593Smuzhiyun reg0x08 = stv0299_readreg (state, 0x08);
357*4882a593Smuzhiyun reg0x0c = stv0299_readreg (state, 0x0c);
358*4882a593Smuzhiyun
359*4882a593Smuzhiyun /*
360*4882a593Smuzhiyun * H/V switching over OP0, OP1 and OP2 are LNB power enable bits
361*4882a593Smuzhiyun */
362*4882a593Smuzhiyun reg0x0c &= 0x0f;
363*4882a593Smuzhiyun reg0x08 = (reg0x08 & 0x3f) | (state->config->lock_output << 6);
364*4882a593Smuzhiyun
365*4882a593Smuzhiyun switch (voltage) {
366*4882a593Smuzhiyun case SEC_VOLTAGE_13:
367*4882a593Smuzhiyun if (state->config->volt13_op0_op1 == STV0299_VOLT13_OP0)
368*4882a593Smuzhiyun reg0x0c |= 0x10; /* OP1 off, OP0 on */
369*4882a593Smuzhiyun else
370*4882a593Smuzhiyun reg0x0c |= 0x40; /* OP1 on, OP0 off */
371*4882a593Smuzhiyun break;
372*4882a593Smuzhiyun case SEC_VOLTAGE_18:
373*4882a593Smuzhiyun reg0x0c |= 0x50; /* OP1 on, OP0 on */
374*4882a593Smuzhiyun break;
375*4882a593Smuzhiyun case SEC_VOLTAGE_OFF:
376*4882a593Smuzhiyun /* LNB power off! */
377*4882a593Smuzhiyun reg0x08 = 0x00;
378*4882a593Smuzhiyun reg0x0c = 0x00;
379*4882a593Smuzhiyun break;
380*4882a593Smuzhiyun default:
381*4882a593Smuzhiyun return -EINVAL;
382*4882a593Smuzhiyun }
383*4882a593Smuzhiyun
384*4882a593Smuzhiyun if (state->config->op0_off)
385*4882a593Smuzhiyun reg0x0c &= ~0x10;
386*4882a593Smuzhiyun
387*4882a593Smuzhiyun stv0299_writeregI(state, 0x08, reg0x08);
388*4882a593Smuzhiyun return stv0299_writeregI(state, 0x0c, reg0x0c);
389*4882a593Smuzhiyun }
390*4882a593Smuzhiyun
stv0299_send_legacy_dish_cmd(struct dvb_frontend * fe,unsigned long cmd)391*4882a593Smuzhiyun static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long cmd)
392*4882a593Smuzhiyun {
393*4882a593Smuzhiyun struct stv0299_state* state = fe->demodulator_priv;
394*4882a593Smuzhiyun u8 reg0x08;
395*4882a593Smuzhiyun u8 reg0x0c;
396*4882a593Smuzhiyun u8 lv_mask = 0x40;
397*4882a593Smuzhiyun u8 last = 1;
398*4882a593Smuzhiyun int i;
399*4882a593Smuzhiyun ktime_t nexttime;
400*4882a593Smuzhiyun ktime_t tv[10];
401*4882a593Smuzhiyun
402*4882a593Smuzhiyun reg0x08 = stv0299_readreg (state, 0x08);
403*4882a593Smuzhiyun reg0x0c = stv0299_readreg (state, 0x0c);
404*4882a593Smuzhiyun reg0x0c &= 0x0f;
405*4882a593Smuzhiyun stv0299_writeregI (state, 0x08, (reg0x08 & 0x3f) | (state->config->lock_output << 6));
406*4882a593Smuzhiyun if (state->config->volt13_op0_op1 == STV0299_VOLT13_OP0)
407*4882a593Smuzhiyun lv_mask = 0x10;
408*4882a593Smuzhiyun
409*4882a593Smuzhiyun cmd = cmd << 1;
410*4882a593Smuzhiyun if (debug_legacy_dish_switch)
411*4882a593Smuzhiyun printk ("%s switch command: 0x%04lx\n",__func__, cmd);
412*4882a593Smuzhiyun
413*4882a593Smuzhiyun nexttime = ktime_get_boottime();
414*4882a593Smuzhiyun if (debug_legacy_dish_switch)
415*4882a593Smuzhiyun tv[0] = nexttime;
416*4882a593Smuzhiyun stv0299_writeregI (state, 0x0c, reg0x0c | 0x50); /* set LNB to 18V */
417*4882a593Smuzhiyun
418*4882a593Smuzhiyun dvb_frontend_sleep_until(&nexttime, 32000);
419*4882a593Smuzhiyun
420*4882a593Smuzhiyun for (i=0; i<9; i++) {
421*4882a593Smuzhiyun if (debug_legacy_dish_switch)
422*4882a593Smuzhiyun tv[i+1] = ktime_get_boottime();
423*4882a593Smuzhiyun if((cmd & 0x01) != last) {
424*4882a593Smuzhiyun /* set voltage to (last ? 13V : 18V) */
425*4882a593Smuzhiyun stv0299_writeregI (state, 0x0c, reg0x0c | (last ? lv_mask : 0x50));
426*4882a593Smuzhiyun last = (last) ? 0 : 1;
427*4882a593Smuzhiyun }
428*4882a593Smuzhiyun
429*4882a593Smuzhiyun cmd = cmd >> 1;
430*4882a593Smuzhiyun
431*4882a593Smuzhiyun if (i != 8)
432*4882a593Smuzhiyun dvb_frontend_sleep_until(&nexttime, 8000);
433*4882a593Smuzhiyun }
434*4882a593Smuzhiyun if (debug_legacy_dish_switch) {
435*4882a593Smuzhiyun printk ("%s(%d): switch delay (should be 32k followed by all 8k\n",
436*4882a593Smuzhiyun __func__, fe->dvb->num);
437*4882a593Smuzhiyun for (i = 1; i < 10; i++)
438*4882a593Smuzhiyun printk("%d: %d\n", i,
439*4882a593Smuzhiyun (int) ktime_us_delta(tv[i], tv[i-1]));
440*4882a593Smuzhiyun }
441*4882a593Smuzhiyun
442*4882a593Smuzhiyun return 0;
443*4882a593Smuzhiyun }
444*4882a593Smuzhiyun
stv0299_init(struct dvb_frontend * fe)445*4882a593Smuzhiyun static int stv0299_init (struct dvb_frontend* fe)
446*4882a593Smuzhiyun {
447*4882a593Smuzhiyun struct stv0299_state* state = fe->demodulator_priv;
448*4882a593Smuzhiyun int i;
449*4882a593Smuzhiyun u8 reg;
450*4882a593Smuzhiyun u8 val;
451*4882a593Smuzhiyun
452*4882a593Smuzhiyun dprintk("stv0299: init chip\n");
453*4882a593Smuzhiyun
454*4882a593Smuzhiyun stv0299_writeregI(state, 0x02, 0x30 | state->mcr_reg);
455*4882a593Smuzhiyun msleep(50);
456*4882a593Smuzhiyun
457*4882a593Smuzhiyun for (i = 0; ; i += 2) {
458*4882a593Smuzhiyun reg = state->config->inittab[i];
459*4882a593Smuzhiyun val = state->config->inittab[i+1];
460*4882a593Smuzhiyun if (reg == 0xff && val == 0xff)
461*4882a593Smuzhiyun break;
462*4882a593Smuzhiyun if (reg == 0x0c && state->config->op0_off)
463*4882a593Smuzhiyun val &= ~0x10;
464*4882a593Smuzhiyun if (reg == 0x2)
465*4882a593Smuzhiyun state->mcr_reg = val & 0xf;
466*4882a593Smuzhiyun stv0299_writeregI(state, reg, val);
467*4882a593Smuzhiyun }
468*4882a593Smuzhiyun
469*4882a593Smuzhiyun return 0;
470*4882a593Smuzhiyun }
471*4882a593Smuzhiyun
stv0299_read_status(struct dvb_frontend * fe,enum fe_status * status)472*4882a593Smuzhiyun static int stv0299_read_status(struct dvb_frontend *fe,
473*4882a593Smuzhiyun enum fe_status *status)
474*4882a593Smuzhiyun {
475*4882a593Smuzhiyun struct stv0299_state* state = fe->demodulator_priv;
476*4882a593Smuzhiyun
477*4882a593Smuzhiyun u8 signal = 0xff - stv0299_readreg (state, 0x18);
478*4882a593Smuzhiyun u8 sync = stv0299_readreg (state, 0x1b);
479*4882a593Smuzhiyun
480*4882a593Smuzhiyun dprintk ("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, sync);
481*4882a593Smuzhiyun *status = 0;
482*4882a593Smuzhiyun
483*4882a593Smuzhiyun if (signal > 10)
484*4882a593Smuzhiyun *status |= FE_HAS_SIGNAL;
485*4882a593Smuzhiyun
486*4882a593Smuzhiyun if (sync & 0x80)
487*4882a593Smuzhiyun *status |= FE_HAS_CARRIER;
488*4882a593Smuzhiyun
489*4882a593Smuzhiyun if (sync & 0x10)
490*4882a593Smuzhiyun *status |= FE_HAS_VITERBI;
491*4882a593Smuzhiyun
492*4882a593Smuzhiyun if (sync & 0x08)
493*4882a593Smuzhiyun *status |= FE_HAS_SYNC;
494*4882a593Smuzhiyun
495*4882a593Smuzhiyun if ((sync & 0x98) == 0x98)
496*4882a593Smuzhiyun *status |= FE_HAS_LOCK;
497*4882a593Smuzhiyun
498*4882a593Smuzhiyun return 0;
499*4882a593Smuzhiyun }
500*4882a593Smuzhiyun
stv0299_read_ber(struct dvb_frontend * fe,u32 * ber)501*4882a593Smuzhiyun static int stv0299_read_ber(struct dvb_frontend* fe, u32* ber)
502*4882a593Smuzhiyun {
503*4882a593Smuzhiyun struct stv0299_state* state = fe->demodulator_priv;
504*4882a593Smuzhiyun
505*4882a593Smuzhiyun if (state->errmode != STATUS_BER)
506*4882a593Smuzhiyun return -ENOSYS;
507*4882a593Smuzhiyun
508*4882a593Smuzhiyun *ber = stv0299_readreg(state, 0x1e) | (stv0299_readreg(state, 0x1d) << 8);
509*4882a593Smuzhiyun
510*4882a593Smuzhiyun return 0;
511*4882a593Smuzhiyun }
512*4882a593Smuzhiyun
stv0299_read_signal_strength(struct dvb_frontend * fe,u16 * strength)513*4882a593Smuzhiyun static int stv0299_read_signal_strength(struct dvb_frontend* fe, u16* strength)
514*4882a593Smuzhiyun {
515*4882a593Smuzhiyun struct stv0299_state* state = fe->demodulator_priv;
516*4882a593Smuzhiyun
517*4882a593Smuzhiyun s32 signal = 0xffff - ((stv0299_readreg (state, 0x18) << 8)
518*4882a593Smuzhiyun | stv0299_readreg (state, 0x19));
519*4882a593Smuzhiyun
520*4882a593Smuzhiyun dprintk ("%s : FE_READ_SIGNAL_STRENGTH : AGC2I: 0x%02x%02x, signal=0x%04x\n", __func__,
521*4882a593Smuzhiyun stv0299_readreg (state, 0x18),
522*4882a593Smuzhiyun stv0299_readreg (state, 0x19), (int) signal);
523*4882a593Smuzhiyun
524*4882a593Smuzhiyun signal = signal * 5 / 4;
525*4882a593Smuzhiyun *strength = (signal > 0xffff) ? 0xffff : (signal < 0) ? 0 : signal;
526*4882a593Smuzhiyun
527*4882a593Smuzhiyun return 0;
528*4882a593Smuzhiyun }
529*4882a593Smuzhiyun
stv0299_read_snr(struct dvb_frontend * fe,u16 * snr)530*4882a593Smuzhiyun static int stv0299_read_snr(struct dvb_frontend* fe, u16* snr)
531*4882a593Smuzhiyun {
532*4882a593Smuzhiyun struct stv0299_state* state = fe->demodulator_priv;
533*4882a593Smuzhiyun
534*4882a593Smuzhiyun s32 xsnr = 0xffff - ((stv0299_readreg (state, 0x24) << 8)
535*4882a593Smuzhiyun | stv0299_readreg (state, 0x25));
536*4882a593Smuzhiyun xsnr = 3 * (xsnr - 0xa100);
537*4882a593Smuzhiyun *snr = (xsnr > 0xffff) ? 0xffff : (xsnr < 0) ? 0 : xsnr;
538*4882a593Smuzhiyun
539*4882a593Smuzhiyun return 0;
540*4882a593Smuzhiyun }
541*4882a593Smuzhiyun
stv0299_read_ucblocks(struct dvb_frontend * fe,u32 * ucblocks)542*4882a593Smuzhiyun static int stv0299_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
543*4882a593Smuzhiyun {
544*4882a593Smuzhiyun struct stv0299_state* state = fe->demodulator_priv;
545*4882a593Smuzhiyun
546*4882a593Smuzhiyun if (state->errmode != STATUS_UCBLOCKS)
547*4882a593Smuzhiyun return -ENOSYS;
548*4882a593Smuzhiyun
549*4882a593Smuzhiyun state->ucblocks += stv0299_readreg(state, 0x1e);
550*4882a593Smuzhiyun state->ucblocks += (stv0299_readreg(state, 0x1d) << 8);
551*4882a593Smuzhiyun *ucblocks = state->ucblocks;
552*4882a593Smuzhiyun
553*4882a593Smuzhiyun return 0;
554*4882a593Smuzhiyun }
555*4882a593Smuzhiyun
stv0299_set_frontend(struct dvb_frontend * fe)556*4882a593Smuzhiyun static int stv0299_set_frontend(struct dvb_frontend *fe)
557*4882a593Smuzhiyun {
558*4882a593Smuzhiyun struct dtv_frontend_properties *p = &fe->dtv_property_cache;
559*4882a593Smuzhiyun struct stv0299_state* state = fe->demodulator_priv;
560*4882a593Smuzhiyun int invval = 0;
561*4882a593Smuzhiyun
562*4882a593Smuzhiyun dprintk ("%s : FE_SET_FRONTEND\n", __func__);
563*4882a593Smuzhiyun if (state->config->set_ts_params)
564*4882a593Smuzhiyun state->config->set_ts_params(fe, 0);
565*4882a593Smuzhiyun
566*4882a593Smuzhiyun // set the inversion
567*4882a593Smuzhiyun if (p->inversion == INVERSION_OFF) invval = 0;
568*4882a593Smuzhiyun else if (p->inversion == INVERSION_ON) invval = 1;
569*4882a593Smuzhiyun else {
570*4882a593Smuzhiyun printk("stv0299 does not support auto-inversion\n");
571*4882a593Smuzhiyun return -EINVAL;
572*4882a593Smuzhiyun }
573*4882a593Smuzhiyun if (state->config->invert) invval = (~invval) & 1;
574*4882a593Smuzhiyun stv0299_writeregI(state, 0x0c, (stv0299_readreg(state, 0x0c) & 0xfe) | invval);
575*4882a593Smuzhiyun
576*4882a593Smuzhiyun if (fe->ops.tuner_ops.set_params) {
577*4882a593Smuzhiyun fe->ops.tuner_ops.set_params(fe);
578*4882a593Smuzhiyun if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
579*4882a593Smuzhiyun }
580*4882a593Smuzhiyun
581*4882a593Smuzhiyun stv0299_set_FEC(state, p->fec_inner);
582*4882a593Smuzhiyun stv0299_set_symbolrate(fe, p->symbol_rate);
583*4882a593Smuzhiyun stv0299_writeregI(state, 0x22, 0x00);
584*4882a593Smuzhiyun stv0299_writeregI(state, 0x23, 0x00);
585*4882a593Smuzhiyun
586*4882a593Smuzhiyun state->tuner_frequency = p->frequency;
587*4882a593Smuzhiyun state->fec_inner = p->fec_inner;
588*4882a593Smuzhiyun state->symbol_rate = p->symbol_rate;
589*4882a593Smuzhiyun
590*4882a593Smuzhiyun return 0;
591*4882a593Smuzhiyun }
592*4882a593Smuzhiyun
stv0299_get_frontend(struct dvb_frontend * fe,struct dtv_frontend_properties * p)593*4882a593Smuzhiyun static int stv0299_get_frontend(struct dvb_frontend *fe,
594*4882a593Smuzhiyun struct dtv_frontend_properties *p)
595*4882a593Smuzhiyun {
596*4882a593Smuzhiyun struct stv0299_state* state = fe->demodulator_priv;
597*4882a593Smuzhiyun s32 derot_freq;
598*4882a593Smuzhiyun int invval;
599*4882a593Smuzhiyun
600*4882a593Smuzhiyun derot_freq = (s32)(s16) ((stv0299_readreg (state, 0x22) << 8)
601*4882a593Smuzhiyun | stv0299_readreg (state, 0x23));
602*4882a593Smuzhiyun
603*4882a593Smuzhiyun derot_freq *= (state->config->mclk >> 16);
604*4882a593Smuzhiyun derot_freq += 500;
605*4882a593Smuzhiyun derot_freq /= 1000;
606*4882a593Smuzhiyun
607*4882a593Smuzhiyun p->frequency += derot_freq;
608*4882a593Smuzhiyun
609*4882a593Smuzhiyun invval = stv0299_readreg (state, 0x0c) & 1;
610*4882a593Smuzhiyun if (state->config->invert) invval = (~invval) & 1;
611*4882a593Smuzhiyun p->inversion = invval ? INVERSION_ON : INVERSION_OFF;
612*4882a593Smuzhiyun
613*4882a593Smuzhiyun p->fec_inner = stv0299_get_fec(state);
614*4882a593Smuzhiyun p->symbol_rate = stv0299_get_symbolrate(state);
615*4882a593Smuzhiyun
616*4882a593Smuzhiyun return 0;
617*4882a593Smuzhiyun }
618*4882a593Smuzhiyun
stv0299_sleep(struct dvb_frontend * fe)619*4882a593Smuzhiyun static int stv0299_sleep(struct dvb_frontend* fe)
620*4882a593Smuzhiyun {
621*4882a593Smuzhiyun struct stv0299_state* state = fe->demodulator_priv;
622*4882a593Smuzhiyun
623*4882a593Smuzhiyun stv0299_writeregI(state, 0x02, 0xb0 | state->mcr_reg);
624*4882a593Smuzhiyun state->initialised = 0;
625*4882a593Smuzhiyun
626*4882a593Smuzhiyun return 0;
627*4882a593Smuzhiyun }
628*4882a593Smuzhiyun
stv0299_i2c_gate_ctrl(struct dvb_frontend * fe,int enable)629*4882a593Smuzhiyun static int stv0299_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
630*4882a593Smuzhiyun {
631*4882a593Smuzhiyun struct stv0299_state* state = fe->demodulator_priv;
632*4882a593Smuzhiyun
633*4882a593Smuzhiyun if (enable) {
634*4882a593Smuzhiyun stv0299_writeregI(state, 0x05, 0xb5);
635*4882a593Smuzhiyun } else {
636*4882a593Smuzhiyun stv0299_writeregI(state, 0x05, 0x35);
637*4882a593Smuzhiyun }
638*4882a593Smuzhiyun udelay(1);
639*4882a593Smuzhiyun return 0;
640*4882a593Smuzhiyun }
641*4882a593Smuzhiyun
stv0299_get_tune_settings(struct dvb_frontend * fe,struct dvb_frontend_tune_settings * fesettings)642*4882a593Smuzhiyun static int stv0299_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
643*4882a593Smuzhiyun {
644*4882a593Smuzhiyun struct stv0299_state* state = fe->demodulator_priv;
645*4882a593Smuzhiyun struct dtv_frontend_properties *p = &fe->dtv_property_cache;
646*4882a593Smuzhiyun
647*4882a593Smuzhiyun fesettings->min_delay_ms = state->config->min_delay_ms;
648*4882a593Smuzhiyun if (p->symbol_rate < 10000000) {
649*4882a593Smuzhiyun fesettings->step_size = p->symbol_rate / 32000;
650*4882a593Smuzhiyun fesettings->max_drift = 5000;
651*4882a593Smuzhiyun } else {
652*4882a593Smuzhiyun fesettings->step_size = p->symbol_rate / 16000;
653*4882a593Smuzhiyun fesettings->max_drift = p->symbol_rate / 2000;
654*4882a593Smuzhiyun }
655*4882a593Smuzhiyun return 0;
656*4882a593Smuzhiyun }
657*4882a593Smuzhiyun
stv0299_release(struct dvb_frontend * fe)658*4882a593Smuzhiyun static void stv0299_release(struct dvb_frontend* fe)
659*4882a593Smuzhiyun {
660*4882a593Smuzhiyun struct stv0299_state* state = fe->demodulator_priv;
661*4882a593Smuzhiyun kfree(state);
662*4882a593Smuzhiyun }
663*4882a593Smuzhiyun
664*4882a593Smuzhiyun static const struct dvb_frontend_ops stv0299_ops;
665*4882a593Smuzhiyun
stv0299_attach(const struct stv0299_config * config,struct i2c_adapter * i2c)666*4882a593Smuzhiyun struct dvb_frontend* stv0299_attach(const struct stv0299_config* config,
667*4882a593Smuzhiyun struct i2c_adapter* i2c)
668*4882a593Smuzhiyun {
669*4882a593Smuzhiyun struct stv0299_state* state = NULL;
670*4882a593Smuzhiyun int id;
671*4882a593Smuzhiyun
672*4882a593Smuzhiyun /* allocate memory for the internal state */
673*4882a593Smuzhiyun state = kzalloc(sizeof(struct stv0299_state), GFP_KERNEL);
674*4882a593Smuzhiyun if (state == NULL) goto error;
675*4882a593Smuzhiyun
676*4882a593Smuzhiyun /* setup the state */
677*4882a593Smuzhiyun state->config = config;
678*4882a593Smuzhiyun state->i2c = i2c;
679*4882a593Smuzhiyun state->initialised = 0;
680*4882a593Smuzhiyun state->tuner_frequency = 0;
681*4882a593Smuzhiyun state->symbol_rate = 0;
682*4882a593Smuzhiyun state->fec_inner = 0;
683*4882a593Smuzhiyun state->errmode = STATUS_BER;
684*4882a593Smuzhiyun
685*4882a593Smuzhiyun /* check if the demod is there */
686*4882a593Smuzhiyun stv0299_writeregI(state, 0x02, 0x30); /* standby off */
687*4882a593Smuzhiyun msleep(200);
688*4882a593Smuzhiyun id = stv0299_readreg(state, 0x00);
689*4882a593Smuzhiyun
690*4882a593Smuzhiyun /* register 0x00 contains 0xa1 for STV0299 and STV0299B */
691*4882a593Smuzhiyun /* register 0x00 might contain 0x80 when returning from standby */
692*4882a593Smuzhiyun if (id != 0xa1 && id != 0x80) goto error;
693*4882a593Smuzhiyun
694*4882a593Smuzhiyun /* create dvb_frontend */
695*4882a593Smuzhiyun memcpy(&state->frontend.ops, &stv0299_ops, sizeof(struct dvb_frontend_ops));
696*4882a593Smuzhiyun state->frontend.demodulator_priv = state;
697*4882a593Smuzhiyun return &state->frontend;
698*4882a593Smuzhiyun
699*4882a593Smuzhiyun error:
700*4882a593Smuzhiyun kfree(state);
701*4882a593Smuzhiyun return NULL;
702*4882a593Smuzhiyun }
703*4882a593Smuzhiyun
704*4882a593Smuzhiyun static const struct dvb_frontend_ops stv0299_ops = {
705*4882a593Smuzhiyun .delsys = { SYS_DVBS },
706*4882a593Smuzhiyun .info = {
707*4882a593Smuzhiyun .name = "ST STV0299 DVB-S",
708*4882a593Smuzhiyun .frequency_min_hz = 950 * MHz,
709*4882a593Smuzhiyun .frequency_max_hz = 2150 * MHz,
710*4882a593Smuzhiyun .frequency_stepsize_hz = 125 * kHz,
711*4882a593Smuzhiyun .symbol_rate_min = 1000000,
712*4882a593Smuzhiyun .symbol_rate_max = 45000000,
713*4882a593Smuzhiyun .symbol_rate_tolerance = 500, /* ppm */
714*4882a593Smuzhiyun .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
715*4882a593Smuzhiyun FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
716*4882a593Smuzhiyun FE_CAN_QPSK |
717*4882a593Smuzhiyun FE_CAN_FEC_AUTO
718*4882a593Smuzhiyun },
719*4882a593Smuzhiyun
720*4882a593Smuzhiyun .release = stv0299_release,
721*4882a593Smuzhiyun
722*4882a593Smuzhiyun .init = stv0299_init,
723*4882a593Smuzhiyun .sleep = stv0299_sleep,
724*4882a593Smuzhiyun .write = stv0299_write,
725*4882a593Smuzhiyun .i2c_gate_ctrl = stv0299_i2c_gate_ctrl,
726*4882a593Smuzhiyun
727*4882a593Smuzhiyun .set_frontend = stv0299_set_frontend,
728*4882a593Smuzhiyun .get_frontend = stv0299_get_frontend,
729*4882a593Smuzhiyun .get_tune_settings = stv0299_get_tune_settings,
730*4882a593Smuzhiyun
731*4882a593Smuzhiyun .read_status = stv0299_read_status,
732*4882a593Smuzhiyun .read_ber = stv0299_read_ber,
733*4882a593Smuzhiyun .read_signal_strength = stv0299_read_signal_strength,
734*4882a593Smuzhiyun .read_snr = stv0299_read_snr,
735*4882a593Smuzhiyun .read_ucblocks = stv0299_read_ucblocks,
736*4882a593Smuzhiyun
737*4882a593Smuzhiyun .diseqc_send_master_cmd = stv0299_send_diseqc_msg,
738*4882a593Smuzhiyun .diseqc_send_burst = stv0299_send_diseqc_burst,
739*4882a593Smuzhiyun .set_tone = stv0299_set_tone,
740*4882a593Smuzhiyun .set_voltage = stv0299_set_voltage,
741*4882a593Smuzhiyun .dishnetwork_send_legacy_command = stv0299_send_legacy_dish_cmd,
742*4882a593Smuzhiyun };
743*4882a593Smuzhiyun
744*4882a593Smuzhiyun module_param(debug_legacy_dish_switch, int, 0444);
745*4882a593Smuzhiyun MODULE_PARM_DESC(debug_legacy_dish_switch, "Enable timing analysis for Dish Network legacy switches");
746*4882a593Smuzhiyun
747*4882a593Smuzhiyun module_param(debug, int, 0644);
748*4882a593Smuzhiyun MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
749*4882a593Smuzhiyun
750*4882a593Smuzhiyun MODULE_DESCRIPTION("ST STV0299 DVB Demodulator driver");
751*4882a593Smuzhiyun MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Peter Schildmann, Felix Domke, Andreas Oberritter, Andrew de Quincey, Kenneth Aafly");
752*4882a593Smuzhiyun MODULE_LICENSE("GPL");
753*4882a593Smuzhiyun
754*4882a593Smuzhiyun EXPORT_SYMBOL(stv0299_attach);
755