aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/frontends
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb/frontends')
-rw-r--r--drivers/media/dvb/frontends/Kconfig172
-rw-r--r--drivers/media/dvb/frontends/Makefile30
-rw-r--r--drivers/media/dvb/frontends/at76c651.c450
-rw-r--r--drivers/media/dvb/frontends/at76c651.h47
-rw-r--r--drivers/media/dvb/frontends/cx22700.c435
-rw-r--r--drivers/media/dvb/frontends/cx22700.h41
-rw-r--r--drivers/media/dvb/frontends/cx22702.c519
-rw-r--r--drivers/media/dvb/frontends/cx22702.h46
-rw-r--r--drivers/media/dvb/frontends/cx24110.c657
-rw-r--r--drivers/media/dvb/frontends/cx24110.h45
-rw-r--r--drivers/media/dvb/frontends/dib3000-common.c83
-rw-r--r--drivers/media/dvb/frontends/dib3000-common.h137
-rw-r--r--drivers/media/dvb/frontends/dib3000.h54
-rw-r--r--drivers/media/dvb/frontends/dib3000mb.c784
-rw-r--r--drivers/media/dvb/frontends/dib3000mb_priv.h467
-rw-r--r--drivers/media/dvb/frontends/dib3000mc.c931
-rw-r--r--drivers/media/dvb/frontends/dib3000mc_priv.h428
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.c168
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.h34
-rw-r--r--drivers/media/dvb/frontends/dvb_dummy_fe.c279
-rw-r--r--drivers/media/dvb/frontends/dvb_dummy_fe.h32
-rw-r--r--drivers/media/dvb/frontends/l64781.c602
-rw-r--r--drivers/media/dvb/frontends/l64781.h42
-rw-r--r--drivers/media/dvb/frontends/mt312.c729
-rw-r--r--drivers/media/dvb/frontends/mt312.h47
-rw-r--r--drivers/media/dvb/frontends/mt312_priv.h162
-rw-r--r--drivers/media/dvb/frontends/mt352.c610
-rw-r--r--drivers/media/dvb/frontends/mt352.h72
-rw-r--r--drivers/media/dvb/frontends/mt352_priv.h127
-rw-r--r--drivers/media/dvb/frontends/nxt2002.c705
-rw-r--r--drivers/media/dvb/frontends/nxt2002.h23
-rw-r--r--drivers/media/dvb/frontends/nxt6000.c554
-rw-r--r--drivers/media/dvb/frontends/nxt6000.h43
-rw-r--r--drivers/media/dvb/frontends/nxt6000_priv.h265
-rw-r--r--drivers/media/dvb/frontends/or51132.c628
-rw-r--r--drivers/media/dvb/frontends/or51132.h48
-rw-r--r--drivers/media/dvb/frontends/or51211.c631
-rw-r--r--drivers/media/dvb/frontends/or51211.h44
-rw-r--r--drivers/media/dvb/frontends/sp8870.c614
-rw-r--r--drivers/media/dvb/frontends/sp8870.h45
-rw-r--r--drivers/media/dvb/frontends/sp887x.c606
-rw-r--r--drivers/media/dvb/frontends/sp887x.h29
-rw-r--r--drivers/media/dvb/frontends/stv0297.c798
-rw-r--r--drivers/media/dvb/frontends/stv0297.h44
-rw-r--r--drivers/media/dvb/frontends/stv0299.c731
-rw-r--r--drivers/media/dvb/frontends/stv0299.h104
-rw-r--r--drivers/media/dvb/frontends/tda10021.c469
-rw-r--r--drivers/media/dvb/frontends/tda10021.h42
-rw-r--r--drivers/media/dvb/frontends/tda1004x.c1206
-rw-r--r--drivers/media/dvb/frontends/tda1004x.h56
-rw-r--r--drivers/media/dvb/frontends/tda8083.c456
-rw-r--r--drivers/media/dvb/frontends/tda8083.h45
-rw-r--r--drivers/media/dvb/frontends/tda80xx.c734
-rw-r--r--drivers/media/dvb/frontends/tda80xx.h51
-rw-r--r--drivers/media/dvb/frontends/ves1820.c450
-rw-r--r--drivers/media/dvb/frontends/ves1820.h51
-rw-r--r--drivers/media/dvb/frontends/ves1x93.c545
-rw-r--r--drivers/media/dvb/frontends/ves1x93.h50
58 files changed, 18297 insertions, 0 deletions
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
new file mode 100644
index 000000000000..0bfd4df17d08
--- /dev/null
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -0,0 +1,172 @@
1menu "Customise DVB Frontends"
2 depends on DVB_CORE
3
4comment "DVB-S (satellite) frontends"
5 depends on DVB_CORE
6
7config DVB_STV0299
8 tristate "ST STV0299 based"
9 depends on DVB_CORE
10 help
11 A DVB-S tuner module. Say Y when you want to support this frontend.
12
13config DVB_CX24110
14 tristate "Conexant CX24110 based"
15 depends on DVB_CORE
16 help
17 A DVB-S tuner module. Say Y when you want to support this frontend.
18
19config DVB_TDA8083
20 tristate "Philips TDA8083 based"
21 depends on DVB_CORE
22 help
23 A DVB-S tuner module. Say Y when you want to support this frontend.
24
25config DVB_TDA80XX
26 tristate "Philips TDA8044 or TDA8083 based"
27 depends on DVB_CORE
28 help
29 A DVB-S tuner module. Say Y when you want to support this frontend.
30
31config DVB_MT312
32 tristate "Zarlink MT312 based"
33 depends on DVB_CORE
34 help
35 A DVB-S tuner module. Say Y when you want to support this frontend.
36
37config DVB_VES1X93
38 tristate "VLSI VES1893 or VES1993 based"
39 depends on DVB_CORE
40 help
41 A DVB-S tuner module. Say Y when you want to support this frontend.
42
43comment "DVB-T (terrestrial) frontends"
44 depends on DVB_CORE
45
46config DVB_SP8870
47 tristate "Spase sp8870 based"
48 depends on DVB_CORE
49 select FW_LOADER
50 help
51 A DVB-T tuner module. Say Y when you want to support this frontend.
52
53 This driver needs external firmware. Please use the command
54 "<kerneldir>/Documentation/dvb/get_dvb_firmware sp8870" to
55 download/extract it, and then copy it to /usr/lib/hotplug/firmware.
56
57config DVB_SP887X
58 tristate "Spase sp887x based"
59 depends on DVB_CORE
60 select FW_LOADER
61 help
62 A DVB-T tuner module. Say Y when you want to support this frontend.
63
64 This driver needs external firmware. Please use the command
65 "<kerneldir>/Documentation/dvb/get_dvb_firmware sp887x" to
66 download/extract it, and then copy it to /usr/lib/hotplug/firmware.
67
68config DVB_CX22700
69 tristate "Conexant CX22700 based"
70 depends on DVB_CORE
71 help
72 A DVB-T tuner module. Say Y when you want to support this frontend.
73
74config DVB_CX22702
75 tristate "Conexant cx22702 demodulator (OFDM)"
76 depends on DVB_CORE
77 help
78 A DVB-T tuner module. Say Y when you want to support this frontend.
79
80config DVB_L64781
81 tristate "LSI L64781"
82 depends on DVB_CORE
83 help
84 A DVB-T tuner module. Say Y when you want to support this frontend.
85
86config DVB_TDA1004X
87 tristate "Philips TDA10045H/TDA10046H based"
88 depends on DVB_CORE
89 select FW_LOADER
90 help
91 A DVB-T tuner module. Say Y when you want to support this frontend.
92
93 This driver needs external firmware. Please use the commands
94 "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10045",
95 "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10046" to
96 download/extract them, and then copy them to /usr/lib/hotplug/firmware.
97
98config DVB_NXT6000
99 tristate "NxtWave Communications NXT6000 based"
100 depends on DVB_CORE
101 help
102 A DVB-T tuner module. Say Y when you want to support this frontend.
103
104config DVB_MT352
105 tristate "Zarlink MT352 based"
106 depends on DVB_CORE
107 help
108 A DVB-T tuner module. Say Y when you want to support this frontend.
109
110config DVB_DIB3000MB
111 tristate "DiBcom 3000M-B"
112 depends on DVB_CORE
113 help
114 A DVB-T tuner module. Designed for mobile usage. Say Y when you want
115 to support this frontend.
116
117config DVB_DIB3000MC
118 tristate "DiBcom 3000P/M-C"
119 depends on DVB_CORE
120 help
121 A DVB-T tuner module. Designed for mobile usage. Say Y when you want
122 to support this frontend.
123
124comment "DVB-C (cable) frontends"
125 depends on DVB_CORE
126
127config DVB_ATMEL_AT76C651
128 tristate "Atmel AT76C651 based"
129 depends on DVB_CORE
130 help
131 A DVB-C tuner module. Say Y when you want to support this frontend.
132
133config DVB_VES1820
134 tristate "VLSI VES1820 based"
135 depends on DVB_CORE
136 help
137 A DVB-C tuner module. Say Y when you want to support this frontend.
138
139config DVB_TDA10021
140 tristate "Philips TDA10021 based"
141 depends on DVB_CORE
142 help
143 A DVB-C tuner module. Say Y when you want to support this frontend.
144
145config DVB_STV0297
146 tristate "ST STV0297 based"
147 depends on DVB_CORE
148 help
149 A DVB-C tuner module. Say Y when you want to support this frontend.
150
151comment "ATSC (North American/Korean Terresterial DTV) frontends"
152 depends on DVB_CORE
153
154config DVB_NXT2002
155 tristate "Nxt2002 based"
156 depends on DVB_CORE
157 select FW_LOADER
158 help
159 An ATSC 8VSB tuner module. Say Y when you want to support this frontend.
160
161config DVB_OR51132
162 tristate "OR51132 based (pcHDTV)"
163 depends on DVB_CORE
164
165config DVB_OR51211
166 tristate "or51211 based (pcHDTV HD2000 card)"
167 depends on DVB_CORE
168 select FW_LOADER
169 help
170 An ATSC 8VSB tuner module. Say Y when you want to support this frontend.
171
172endmenu
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
new file mode 100644
index 000000000000..7f8784870eab
--- /dev/null
+++ b/drivers/media/dvb/frontends/Makefile
@@ -0,0 +1,30 @@
1#
2# Makefile for the kernel DVB frontend device drivers.
3#
4
5EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/
6
7obj-$(CONFIG_DVB_CORE) += dvb-pll.o
8obj-$(CONFIG_DVB_STV0299) += stv0299.o
9obj-$(CONFIG_DVB_SP8870) += sp8870.o
10obj-$(CONFIG_DVB_CX22700) += cx22700.o
11obj-$(CONFIG_DVB_ATMEL_AT76C651) += at76c651.o
12obj-$(CONFIG_DVB_CX24110) += cx24110.o
13obj-$(CONFIG_DVB_TDA8083) += tda8083.o
14obj-$(CONFIG_DVB_L64781) += l64781.o
15obj-$(CONFIG_DVB_DIB3000MB) += dib3000mb.o dib3000-common.o
16obj-$(CONFIG_DVB_DIB3000MC) += dib3000mc.o dib3000-common.o
17obj-$(CONFIG_DVB_MT312) += mt312.o
18obj-$(CONFIG_DVB_VES1820) += ves1820.o
19obj-$(CONFIG_DVB_VES1X93) += ves1x93.o
20obj-$(CONFIG_DVB_TDA1004X) += tda1004x.o
21obj-$(CONFIG_DVB_SP887X) += sp887x.o
22obj-$(CONFIG_DVB_NXT6000) += nxt6000.o
23obj-$(CONFIG_DVB_MT352) += mt352.o
24obj-$(CONFIG_DVB_CX22702) += cx22702.o
25obj-$(CONFIG_DVB_TDA80XX) += tda80xx.o
26obj-$(CONFIG_DVB_TDA10021) += tda10021.o
27obj-$(CONFIG_DVB_STV0297) += stv0297.o
28obj-$(CONFIG_DVB_NXT2002) += nxt2002.o
29obj-$(CONFIG_DVB_OR51211) += or51211.o
30obj-$(CONFIG_DVB_OR51132) += or51132.o
diff --git a/drivers/media/dvb/frontends/at76c651.c b/drivers/media/dvb/frontends/at76c651.c
new file mode 100644
index 000000000000..ce2eaa1640e8
--- /dev/null
+++ b/drivers/media/dvb/frontends/at76c651.c
@@ -0,0 +1,450 @@
1/*
2 * at76c651.c
3 *
4 * Atmel DVB-C Frontend Driver (at76c651/tua6010xs)
5 *
6 * Copyright (C) 2001 fnbrd <fnbrd@gmx.de>
7 * & 2002-2004 Andreas Oberritter <obi@linuxtv.org>
8 * & 2003 Wolfram Joost <dbox2@frokaschwei.de>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 * AT76C651
25 * http://www.nalanda.nitc.ac.in/industry/datasheets/atmel/acrobat/doc1293.pdf
26 * http://www.atmel.com/atmel/acrobat/doc1320.pdf
27 */
28
29#include <linux/init.h>
30#include <linux/module.h>
31#include <linux/moduleparam.h>
32#include <linux/kernel.h>
33#include <linux/string.h>
34#include <linux/slab.h>
35#include <linux/bitops.h>
36#include "dvb_frontend.h"
37#include "at76c651.h"
38
39
40struct at76c651_state {
41
42 struct i2c_adapter* i2c;
43
44 struct dvb_frontend_ops ops;
45
46 const struct at76c651_config* config;
47
48 struct dvb_frontend frontend;
49
50 /* revision of the chip */
51 u8 revision;
52
53 /* last QAM value set */
54 u8 qam;
55};
56
57static int debug;
58#define dprintk(args...) \
59 do { \
60 if (debug) printk(KERN_DEBUG "at76c651: " args); \
61 } while (0)
62
63
64#if ! defined(__powerpc__)
65static __inline__ int __ilog2(unsigned long x)
66{
67 int i;
68
69 if (x == 0)
70 return -1;
71
72 for (i = 0; x != 0; i++)
73 x >>= 1;
74
75 return i - 1;
76}
77#endif
78
79static int at76c651_writereg(struct at76c651_state* state, u8 reg, u8 data)
80{
81 int ret;
82 u8 buf[] = { reg, data };
83 struct i2c_msg msg =
84 { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
85
86 ret = i2c_transfer(state->i2c, &msg, 1);
87
88 if (ret != 1)
89 dprintk("%s: writereg error "
90 "(reg == 0x%02x, val == 0x%02x, ret == %i)\n",
91 __FUNCTION__, reg, data, ret);
92
93 msleep(10);
94
95 return (ret != 1) ? -EREMOTEIO : 0;
96}
97
98static u8 at76c651_readreg(struct at76c651_state* state, u8 reg)
99{
100 int ret;
101 u8 val;
102 struct i2c_msg msg[] = {
103 { .addr = state->config->demod_address, .flags = 0, .buf = &reg, .len = 1 },
104 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = &val, .len = 1 }
105 };
106
107 ret = i2c_transfer(state->i2c, msg, 2);
108
109 if (ret != 2)
110 dprintk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret);
111
112 return val;
113}
114
115static int at76c651_reset(struct at76c651_state* state)
116{
117 return at76c651_writereg(state, 0x07, 0x01);
118}
119
120static void at76c651_disable_interrupts(struct at76c651_state* state)
121{
122 at76c651_writereg(state, 0x0b, 0x00);
123}
124
125static int at76c651_set_auto_config(struct at76c651_state *state)
126{
127 /*
128 * Autoconfig
129 */
130
131 at76c651_writereg(state, 0x06, 0x01);
132
133 /*
134 * Performance optimizations, should be done after autoconfig
135 */
136
137 at76c651_writereg(state, 0x10, 0x06);
138 at76c651_writereg(state, 0x11, ((state->qam == 5) || (state->qam == 7)) ? 0x12 : 0x10);
139 at76c651_writereg(state, 0x15, 0x28);
140 at76c651_writereg(state, 0x20, 0x09);
141 at76c651_writereg(state, 0x24, ((state->qam == 5) || (state->qam == 7)) ? 0xC0 : 0x90);
142 at76c651_writereg(state, 0x30, 0x90);
143 if (state->qam == 5)
144 at76c651_writereg(state, 0x35, 0x2A);
145
146 /*
147 * Initialize A/D-converter
148 */
149
150 if (state->revision == 0x11) {
151 at76c651_writereg(state, 0x2E, 0x38);
152 at76c651_writereg(state, 0x2F, 0x13);
153 }
154
155 at76c651_disable_interrupts(state);
156
157 /*
158 * Restart operation
159 */
160
161 at76c651_reset(state);
162
163 return 0;
164}
165
166static void at76c651_set_bbfreq(struct at76c651_state* state)
167{
168 at76c651_writereg(state, 0x04, 0x3f);
169 at76c651_writereg(state, 0x05, 0xee);
170}
171
172static int at76c651_set_symbol_rate(struct at76c651_state* state, u32 symbol_rate)
173{
174 u8 exponent;
175 u32 mantissa;
176
177 if (symbol_rate > 9360000)
178 return -EINVAL;
179
180 /*
181 * FREF = 57800 kHz
182 * exponent = 10 + floor (log2(symbol_rate / FREF))
183 * mantissa = (symbol_rate / FREF) * (1 << (30 - exponent))
184 */
185
186 exponent = __ilog2((symbol_rate << 4) / 903125);
187 mantissa = ((symbol_rate / 3125) * (1 << (24 - exponent))) / 289;
188
189 at76c651_writereg(state, 0x00, mantissa >> 13);
190 at76c651_writereg(state, 0x01, mantissa >> 5);
191 at76c651_writereg(state, 0x02, (mantissa << 3) | exponent);
192
193 return 0;
194}
195
196static int at76c651_set_qam(struct at76c651_state *state, fe_modulation_t qam)
197{
198 switch (qam) {
199 case QPSK:
200 state->qam = 0x02;
201 break;
202 case QAM_16:
203 state->qam = 0x04;
204 break;
205 case QAM_32:
206 state->qam = 0x05;
207 break;
208 case QAM_64:
209 state->qam = 0x06;
210 break;
211 case QAM_128:
212 state->qam = 0x07;
213 break;
214 case QAM_256:
215 state->qam = 0x08;
216 break;
217#if 0
218 case QAM_512:
219 state->qam = 0x09;
220 break;
221 case QAM_1024:
222 state->qam = 0x0A;
223 break;
224#endif
225 default:
226 return -EINVAL;
227
228 }
229
230 return at76c651_writereg(state, 0x03, state->qam);
231}
232
233static int at76c651_set_inversion(struct at76c651_state* state, fe_spectral_inversion_t inversion)
234{
235 u8 feciqinv = at76c651_readreg(state, 0x60);
236
237 switch (inversion) {
238 case INVERSION_OFF:
239 feciqinv |= 0x02;
240 feciqinv &= 0xFE;
241 break;
242
243 case INVERSION_ON:
244 feciqinv |= 0x03;
245 break;
246
247 case INVERSION_AUTO:
248 feciqinv &= 0xFC;
249 break;
250
251 default:
252 return -EINVAL;
253 }
254
255 return at76c651_writereg(state, 0x60, feciqinv);
256}
257
258static int at76c651_set_parameters(struct dvb_frontend* fe,
259 struct dvb_frontend_parameters *p)
260{
261 int ret;
262 struct at76c651_state* state = (struct at76c651_state*) fe->demodulator_priv;
263
264 at76c651_writereg(state, 0x0c, 0xc3);
265 state->config->pll_set(fe, p);
266 at76c651_writereg(state, 0x0c, 0xc2);
267
268 if ((ret = at76c651_set_symbol_rate(state, p->u.qam.symbol_rate)))
269 return ret;
270
271 if ((ret = at76c651_set_inversion(state, p->inversion)))
272 return ret;
273
274 return at76c651_set_auto_config(state);
275}
276
277static int at76c651_set_defaults(struct dvb_frontend* fe)
278{
279 struct at76c651_state* state = (struct at76c651_state*) fe->demodulator_priv;
280
281 at76c651_set_symbol_rate(state, 6900000);
282 at76c651_set_qam(state, QAM_64);
283 at76c651_set_bbfreq(state);
284 at76c651_set_auto_config(state);
285
286 if (state->config->pll_init) {
287 at76c651_writereg(state, 0x0c, 0xc3);
288 state->config->pll_init(fe);
289 at76c651_writereg(state, 0x0c, 0xc2);
290 }
291
292 return 0;
293}
294
295static int at76c651_read_status(struct dvb_frontend* fe, fe_status_t* status)
296{
297 struct at76c651_state* state = (struct at76c651_state*) fe->demodulator_priv;
298 u8 sync;
299
300 /*
301 * Bits: FEC, CAR, EQU, TIM, AGC2, AGC1, ADC, PLL (PLL=0)
302 */
303 sync = at76c651_readreg(state, 0x80);
304 *status = 0;
305
306 if (sync & (0x04 | 0x10)) /* AGC1 || TIM */
307 *status |= FE_HAS_SIGNAL;
308 if (sync & 0x10) /* TIM */
309 *status |= FE_HAS_CARRIER;
310 if (sync & 0x80) /* FEC */
311 *status |= FE_HAS_VITERBI;
312 if (sync & 0x40) /* CAR */
313 *status |= FE_HAS_SYNC;
314 if ((sync & 0xF0) == 0xF0) /* TIM && EQU && CAR && FEC */
315 *status |= FE_HAS_LOCK;
316
317 return 0;
318}
319
320static int at76c651_read_ber(struct dvb_frontend* fe, u32* ber)
321{
322 struct at76c651_state* state = (struct at76c651_state*) fe->demodulator_priv;
323
324 *ber = (at76c651_readreg(state, 0x81) & 0x0F) << 16;
325 *ber |= at76c651_readreg(state, 0x82) << 8;
326 *ber |= at76c651_readreg(state, 0x83);
327 *ber *= 10;
328
329 return 0;
330}
331
332static int at76c651_read_signal_strength(struct dvb_frontend* fe, u16* strength)
333{
334 struct at76c651_state* state = (struct at76c651_state*) fe->demodulator_priv;
335
336 u8 gain = ~at76c651_readreg(state, 0x91);
337 *strength = (gain << 8) | gain;
338
339 return 0;
340}
341
342static int at76c651_read_snr(struct dvb_frontend* fe, u16* snr)
343{
344 struct at76c651_state* state = (struct at76c651_state*) fe->demodulator_priv;
345
346 *snr = 0xFFFF -
347 ((at76c651_readreg(state, 0x8F) << 8) |
348 at76c651_readreg(state, 0x90));
349
350 return 0;
351}
352
353static int at76c651_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
354{
355 struct at76c651_state* state = (struct at76c651_state*) fe->demodulator_priv;
356
357 *ucblocks = at76c651_readreg(state, 0x82);
358
359 return 0;
360}
361
362static int at76c651_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *fesettings)
363{
364 fesettings->min_delay_ms = 50;
365 fesettings->step_size = 0;
366 fesettings->max_drift = 0;
367 return 0;
368}
369
370static void at76c651_release(struct dvb_frontend* fe)
371{
372 struct at76c651_state* state = (struct at76c651_state*) fe->demodulator_priv;
373 kfree(state);
374}
375
376static struct dvb_frontend_ops at76c651_ops;
377
378struct dvb_frontend* at76c651_attach(const struct at76c651_config* config,
379 struct i2c_adapter* i2c)
380{
381 struct at76c651_state* state = NULL;
382
383 /* allocate memory for the internal state */
384 state = (struct at76c651_state*) kmalloc(sizeof(struct at76c651_state), GFP_KERNEL);
385 if (state == NULL) goto error;
386
387 /* setup the state */
388 state->config = config;
389 state->qam = 0;
390
391 /* check if the demod is there */
392 if (at76c651_readreg(state, 0x0e) != 0x65) goto error;
393
394 /* finalise state setup */
395 state->i2c = i2c;
396 state->revision = at76c651_readreg(state, 0x0f) & 0xfe;
397 memcpy(&state->ops, &at76c651_ops, sizeof(struct dvb_frontend_ops));
398
399 /* create dvb_frontend */
400 state->frontend.ops = &state->ops;
401 state->frontend.demodulator_priv = state;
402 return &state->frontend;
403
404error:
405 kfree(state);
406 return NULL;
407}
408
409static struct dvb_frontend_ops at76c651_ops = {
410
411 .info = {
412 .name = "Atmel AT76C651B DVB-C",
413 .type = FE_QAM,
414 .frequency_min = 48250000,
415 .frequency_max = 863250000,
416 .frequency_stepsize = 62500,
417 /*.frequency_tolerance = */ /* FIXME: 12% of SR */
418 .symbol_rate_min = 0, /* FIXME */
419 .symbol_rate_max = 9360000, /* FIXME */
420 .symbol_rate_tolerance = 4000,
421 .caps = FE_CAN_INVERSION_AUTO |
422 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
423 FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
424 FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
425 FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | FE_CAN_QAM_128 |
426 FE_CAN_MUTE_TS | FE_CAN_QAM_256 | FE_CAN_RECOVER
427 },
428
429 .release = at76c651_release,
430
431 .init = at76c651_set_defaults,
432
433 .set_frontend = at76c651_set_parameters,
434 .get_tune_settings = at76c651_get_tune_settings,
435
436 .read_status = at76c651_read_status,
437 .read_ber = at76c651_read_ber,
438 .read_signal_strength = at76c651_read_signal_strength,
439 .read_snr = at76c651_read_snr,
440 .read_ucblocks = at76c651_read_ucblocks,
441};
442
443module_param(debug, int, 0644);
444MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
445
446MODULE_DESCRIPTION("Atmel AT76C651 DVB-C Demodulator Driver");
447MODULE_AUTHOR("Andreas Oberritter <obi@linuxtv.org>");
448MODULE_LICENSE("GPL");
449
450EXPORT_SYMBOL(at76c651_attach);
diff --git a/drivers/media/dvb/frontends/at76c651.h b/drivers/media/dvb/frontends/at76c651.h
new file mode 100644
index 000000000000..34054df93608
--- /dev/null
+++ b/drivers/media/dvb/frontends/at76c651.h
@@ -0,0 +1,47 @@
1/*
2 * at76c651.c
3 *
4 * Atmel DVB-C Frontend Driver (at76c651)
5 *
6 * Copyright (C) 2001 fnbrd <fnbrd@gmx.de>
7 * & 2002-2004 Andreas Oberritter <obi@linuxtv.org>
8 * & 2003 Wolfram Joost <dbox2@frokaschwei.de>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 * AT76C651
25 * http://www.nalanda.nitc.ac.in/industry/datasheets/atmel/acrobat/doc1293.pdf
26 * http://www.atmel.com/atmel/acrobat/doc1320.pdf
27 */
28
29#ifndef AT76C651_H
30#define AT76C651_H
31
32#include <linux/dvb/frontend.h>
33
34struct at76c651_config
35{
36 /* the demodulator's i2c address */
37 u8 demod_address;
38
39 /* PLL maintenance */
40 int (*pll_init)(struct dvb_frontend* fe);
41 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
42};
43
44extern struct dvb_frontend* at76c651_attach(const struct at76c651_config* config,
45 struct i2c_adapter* i2c);
46
47#endif // AT76C651_H
diff --git a/drivers/media/dvb/frontends/cx22700.c b/drivers/media/dvb/frontends/cx22700.c
new file mode 100644
index 000000000000..a212279042b8
--- /dev/null
+++ b/drivers/media/dvb/frontends/cx22700.c
@@ -0,0 +1,435 @@
1/*
2 Conexant cx22700 DVB OFDM demodulator driver
3
4 Copyright (C) 2001-2002 Convergence Integrated Media GmbH
5 Holger Waechtler <holger@convergence.de>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21*/
22
23#include <linux/kernel.h>
24#include <linux/init.h>
25#include <linux/module.h>
26#include <linux/moduleparam.h>
27#include <linux/string.h>
28#include <linux/slab.h>
29#include "dvb_frontend.h"
30#include "cx22700.h"
31
32
33struct cx22700_state {
34
35 struct i2c_adapter* i2c;
36
37 struct dvb_frontend_ops ops;
38
39 const struct cx22700_config* config;
40
41 struct dvb_frontend frontend;
42};
43
44
45static int debug;
46#define dprintk(args...) \
47 do { \
48 if (debug) printk(KERN_DEBUG "cx22700: " args); \
49 } while (0)
50
51static u8 init_tab [] = {
52 0x04, 0x10,
53 0x05, 0x09,
54 0x06, 0x00,
55 0x08, 0x04,
56 0x09, 0x00,
57 0x0a, 0x01,
58 0x15, 0x40,
59 0x16, 0x10,
60 0x17, 0x87,
61 0x18, 0x17,
62 0x1a, 0x10,
63 0x25, 0x04,
64 0x2e, 0x00,
65 0x39, 0x00,
66 0x3a, 0x04,
67 0x45, 0x08,
68 0x46, 0x02,
69 0x47, 0x05,
70};
71
72
73static int cx22700_writereg (struct cx22700_state* state, u8 reg, u8 data)
74{
75 int ret;
76 u8 buf [] = { reg, data };
77 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
78
79 dprintk ("%s\n", __FUNCTION__);
80
81 ret = i2c_transfer (state->i2c, &msg, 1);
82
83 if (ret != 1)
84 printk("%s: writereg error (reg == 0x%02x, val == 0x%02x, ret == %i)\n",
85 __FUNCTION__, reg, data, ret);
86
87 return (ret != 1) ? -1 : 0;
88}
89
90static int cx22700_readreg (struct cx22700_state* state, u8 reg)
91{
92 int ret;
93 u8 b0 [] = { reg };
94 u8 b1 [] = { 0 };
95 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
96 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
97
98 dprintk ("%s\n", __FUNCTION__);
99
100 ret = i2c_transfer (state->i2c, msg, 2);
101
102 if (ret != 2) return -EIO;
103
104 return b1[0];
105}
106
107static int cx22700_set_inversion (struct cx22700_state* state, int inversion)
108{
109 u8 val;
110
111 dprintk ("%s\n", __FUNCTION__);
112
113 switch (inversion) {
114 case INVERSION_AUTO:
115 return -EOPNOTSUPP;
116 case INVERSION_ON:
117 val = cx22700_readreg (state, 0x09);
118 return cx22700_writereg (state, 0x09, val | 0x01);
119 case INVERSION_OFF:
120 val = cx22700_readreg (state, 0x09);
121 return cx22700_writereg (state, 0x09, val & 0xfe);
122 default:
123 return -EINVAL;
124 }
125}
126
127static int cx22700_set_tps (struct cx22700_state *state, struct dvb_ofdm_parameters *p)
128{
129 static const u8 qam_tab [4] = { 0, 1, 0, 2 };
130 static const u8 fec_tab [6] = { 0, 1, 2, 0, 3, 4 };
131 u8 val;
132
133 dprintk ("%s\n", __FUNCTION__);
134
135 if (p->code_rate_HP < FEC_1_2 || p->code_rate_HP > FEC_7_8)
136 return -EINVAL;
137
138 if (p->code_rate_LP < FEC_1_2 || p->code_rate_LP > FEC_7_8)
139
140 if (p->code_rate_HP == FEC_4_5 || p->code_rate_LP == FEC_4_5)
141 return -EINVAL;
142
143 if (p->guard_interval < GUARD_INTERVAL_1_32 ||
144 p->guard_interval > GUARD_INTERVAL_1_4)
145 return -EINVAL;
146
147 if (p->transmission_mode != TRANSMISSION_MODE_2K &&
148 p->transmission_mode != TRANSMISSION_MODE_8K)
149 return -EINVAL;
150
151 if (p->constellation != QPSK &&
152 p->constellation != QAM_16 &&
153 p->constellation != QAM_64)
154 return -EINVAL;
155
156 if (p->hierarchy_information < HIERARCHY_NONE ||
157 p->hierarchy_information > HIERARCHY_4)
158 return -EINVAL;
159
160 if (p->bandwidth < BANDWIDTH_8_MHZ && p->bandwidth > BANDWIDTH_6_MHZ)
161 return -EINVAL;
162
163 if (p->bandwidth == BANDWIDTH_7_MHZ)
164 cx22700_writereg (state, 0x09, cx22700_readreg (state, 0x09 | 0x10));
165 else
166 cx22700_writereg (state, 0x09, cx22700_readreg (state, 0x09 & ~0x10));
167
168 val = qam_tab[p->constellation - QPSK];
169 val |= p->hierarchy_information - HIERARCHY_NONE;
170
171 cx22700_writereg (state, 0x04, val);
172
173 val = fec_tab[p->code_rate_HP - FEC_1_2] << 3;
174 val |= fec_tab[p->code_rate_LP - FEC_1_2];
175
176 cx22700_writereg (state, 0x05, val);
177
178 val = (p->guard_interval - GUARD_INTERVAL_1_32) << 2;
179 val |= p->transmission_mode - TRANSMISSION_MODE_2K;
180
181 cx22700_writereg (state, 0x06, val);
182
183 cx22700_writereg (state, 0x08, 0x04 | 0x02); /* use user tps parameters */
184 cx22700_writereg (state, 0x08, 0x04); /* restart aquisition */
185
186 return 0;
187}
188
189static int cx22700_get_tps (struct cx22700_state* state, struct dvb_ofdm_parameters *p)
190{
191 static const fe_modulation_t qam_tab [3] = { QPSK, QAM_16, QAM_64 };
192 static const fe_code_rate_t fec_tab [5] = { FEC_1_2, FEC_2_3, FEC_3_4,
193 FEC_5_6, FEC_7_8 };
194 u8 val;
195
196 dprintk ("%s\n", __FUNCTION__);
197
198 if (!(cx22700_readreg(state, 0x07) & 0x20)) /* tps valid? */
199 return -EAGAIN;
200
201 val = cx22700_readreg (state, 0x01);
202
203 if ((val & 0x7) > 4)
204 p->hierarchy_information = HIERARCHY_AUTO;
205 else
206 p->hierarchy_information = HIERARCHY_NONE + (val & 0x7);
207
208 if (((val >> 3) & 0x3) > 2)
209 p->constellation = QAM_AUTO;
210 else
211 p->constellation = qam_tab[(val >> 3) & 0x3];
212
213 val = cx22700_readreg (state, 0x02);
214
215 if (((val >> 3) & 0x07) > 4)
216 p->code_rate_HP = FEC_AUTO;
217 else
218 p->code_rate_HP = fec_tab[(val >> 3) & 0x07];
219
220 if ((val & 0x07) > 4)
221 p->code_rate_LP = FEC_AUTO;
222 else
223 p->code_rate_LP = fec_tab[val & 0x07];
224
225 val = cx22700_readreg (state, 0x03);
226
227 p->guard_interval = GUARD_INTERVAL_1_32 + ((val >> 6) & 0x3);
228 p->transmission_mode = TRANSMISSION_MODE_2K + ((val >> 5) & 0x1);
229
230 return 0;
231}
232
233static int cx22700_init (struct dvb_frontend* fe)
234
235{ struct cx22700_state* state = (struct cx22700_state*) fe->demodulator_priv;
236 int i;
237
238 dprintk("cx22700_init: init chip\n");
239
240 cx22700_writereg (state, 0x00, 0x02); /* soft reset */
241 cx22700_writereg (state, 0x00, 0x00);
242
243 msleep(10);
244
245 for (i=0; i<sizeof(init_tab); i+=2)
246 cx22700_writereg (state, init_tab[i], init_tab[i+1]);
247
248 cx22700_writereg (state, 0x00, 0x01);
249
250 if (state->config->pll_init) {
251 cx22700_writereg (state, 0x0a, 0x00); /* open i2c bus switch */
252 state->config->pll_init(fe);
253 cx22700_writereg (state, 0x0a, 0x01); /* close i2c bus switch */
254 }
255
256 return 0;
257}
258
259static int cx22700_read_status(struct dvb_frontend* fe, fe_status_t* status)
260{
261 struct cx22700_state* state = (struct cx22700_state*) fe->demodulator_priv;
262
263 u16 rs_ber = (cx22700_readreg (state, 0x0d) << 9)
264 | (cx22700_readreg (state, 0x0e) << 1);
265 u8 sync = cx22700_readreg (state, 0x07);
266
267 *status = 0;
268
269 if (rs_ber < 0xff00)
270 *status |= FE_HAS_SIGNAL;
271
272 if (sync & 0x20)
273 *status |= FE_HAS_CARRIER;
274
275 if (sync & 0x10)
276 *status |= FE_HAS_VITERBI;
277
278 if (sync & 0x10)
279 *status |= FE_HAS_SYNC;
280
281 if (*status == 0x0f)
282 *status |= FE_HAS_LOCK;
283
284 return 0;
285}
286
287static int cx22700_read_ber(struct dvb_frontend* fe, u32* ber)
288{
289 struct cx22700_state* state = (struct cx22700_state*) fe->demodulator_priv;
290
291 *ber = cx22700_readreg (state, 0x0c) & 0x7f;
292 cx22700_writereg (state, 0x0c, 0x00);
293
294 return 0;
295}
296
297static int cx22700_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
298{
299 struct cx22700_state* state = (struct cx22700_state*) fe->demodulator_priv;
300
301 u16 rs_ber = (cx22700_readreg (state, 0x0d) << 9)
302 | (cx22700_readreg (state, 0x0e) << 1);
303 *signal_strength = ~rs_ber;
304
305 return 0;
306}
307
308static int cx22700_read_snr(struct dvb_frontend* fe, u16* snr)
309{
310 struct cx22700_state* state = (struct cx22700_state*) fe->demodulator_priv;
311
312 u16 rs_ber = (cx22700_readreg (state, 0x0d) << 9)
313 | (cx22700_readreg (state, 0x0e) << 1);
314 *snr = ~rs_ber;
315
316 return 0;
317}
318
319static int cx22700_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
320{
321 struct cx22700_state* state = (struct cx22700_state*) fe->demodulator_priv;
322
323 *ucblocks = cx22700_readreg (state, 0x0f);
324 cx22700_writereg (state, 0x0f, 0x00);
325
326 return 0;
327}
328
329static int cx22700_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
330{
331 struct cx22700_state* state = (struct cx22700_state*) fe->demodulator_priv;
332
333 cx22700_writereg (state, 0x00, 0x02); /* XXX CHECKME: soft reset*/
334 cx22700_writereg (state, 0x00, 0x00);
335
336 cx22700_writereg (state, 0x0a, 0x00); /* open i2c bus switch */
337 state->config->pll_set(fe, p);
338 cx22700_writereg (state, 0x0a, 0x01); /* close i2c bus switch */
339 cx22700_set_inversion (state, p->inversion);
340 cx22700_set_tps (state, &p->u.ofdm);
341 cx22700_writereg (state, 0x37, 0x01); /* PAL loop filter off */
342 cx22700_writereg (state, 0x00, 0x01); /* restart acquire */
343
344 return 0;
345}
346
347static int cx22700_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
348{
349 struct cx22700_state* state = (struct cx22700_state*) fe->demodulator_priv;
350 u8 reg09 = cx22700_readreg (state, 0x09);
351
352 p->inversion = reg09 & 0x1 ? INVERSION_ON : INVERSION_OFF;
353 return cx22700_get_tps (state, &p->u.ofdm);
354}
355
356static int cx22700_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
357{
358 fesettings->min_delay_ms = 150;
359 fesettings->step_size = 166667;
360 fesettings->max_drift = 166667*2;
361 return 0;
362}
363
364static void cx22700_release(struct dvb_frontend* fe)
365{
366 struct cx22700_state* state = (struct cx22700_state*) fe->demodulator_priv;
367 kfree(state);
368}
369
370static struct dvb_frontend_ops cx22700_ops;
371
372struct dvb_frontend* cx22700_attach(const struct cx22700_config* config,
373 struct i2c_adapter* i2c)
374{
375 struct cx22700_state* state = NULL;
376
377 /* allocate memory for the internal state */
378 state = (struct cx22700_state*) kmalloc(sizeof(struct cx22700_state), GFP_KERNEL);
379 if (state == NULL) goto error;
380
381 /* setup the state */
382 state->config = config;
383 state->i2c = i2c;
384 memcpy(&state->ops, &cx22700_ops, sizeof(struct dvb_frontend_ops));
385
386 /* check if the demod is there */
387 if (cx22700_readreg(state, 0x07) < 0) goto error;
388
389 /* create dvb_frontend */
390 state->frontend.ops = &state->ops;
391 state->frontend.demodulator_priv = state;
392 return &state->frontend;
393
394error:
395 kfree(state);
396 return NULL;
397}
398
399static struct dvb_frontend_ops cx22700_ops = {
400
401 .info = {
402 .name = "Conexant CX22700 DVB-T",
403 .type = FE_OFDM,
404 .frequency_min = 470000000,
405 .frequency_max = 860000000,
406 .frequency_stepsize = 166667,
407 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
408 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
409 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
410 FE_CAN_RECOVER
411 },
412
413 .release = cx22700_release,
414
415 .init = cx22700_init,
416
417 .set_frontend = cx22700_set_frontend,
418 .get_frontend = cx22700_get_frontend,
419 .get_tune_settings = cx22700_get_tune_settings,
420
421 .read_status = cx22700_read_status,
422 .read_ber = cx22700_read_ber,
423 .read_signal_strength = cx22700_read_signal_strength,
424 .read_snr = cx22700_read_snr,
425 .read_ucblocks = cx22700_read_ucblocks,
426};
427
428module_param(debug, int, 0644);
429MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
430
431MODULE_DESCRIPTION("Conexant CX22700 DVB-T Demodulator driver");
432MODULE_AUTHOR("Holger Waechtler");
433MODULE_LICENSE("GPL");
434
435EXPORT_SYMBOL(cx22700_attach);
diff --git a/drivers/media/dvb/frontends/cx22700.h b/drivers/media/dvb/frontends/cx22700.h
new file mode 100644
index 000000000000..c9145b45874b
--- /dev/null
+++ b/drivers/media/dvb/frontends/cx22700.h
@@ -0,0 +1,41 @@
1/*
2 Conexant CX22700 DVB OFDM demodulator driver
3
4 Copyright (C) 2001-2002 Convergence Integrated Media GmbH
5 Holger Waechtler <holger@convergence.de>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21*/
22
23#ifndef CX22700_H
24#define CX22700_H
25
26#include <linux/dvb/frontend.h>
27
28struct cx22700_config
29{
30 /* the demodulator's i2c address */
31 u8 demod_address;
32
33 /* PLL maintenance */
34 int (*pll_init)(struct dvb_frontend* fe);
35 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
36};
37
38extern struct dvb_frontend* cx22700_attach(const struct cx22700_config* config,
39 struct i2c_adapter* i2c);
40
41#endif // CX22700_H
diff --git a/drivers/media/dvb/frontends/cx22702.c b/drivers/media/dvb/frontends/cx22702.c
new file mode 100644
index 000000000000..1930b513eefa
--- /dev/null
+++ b/drivers/media/dvb/frontends/cx22702.c
@@ -0,0 +1,519 @@
1/*
2 Conexant 22702 DVB OFDM demodulator driver
3
4 based on:
5 Alps TDMB7 DVB OFDM demodulator driver
6
7 Copyright (C) 2001-2002 Convergence Integrated Media GmbH
8 Holger Waechtler <holger@convergence.de>
9
10 Copyright (C) 2004 Steven Toth <steve@toth.demon.co.uk>
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25
26*/
27
28#include <linux/kernel.h>
29#include <linux/init.h>
30#include <linux/module.h>
31#include <linux/string.h>
32#include <linux/slab.h>
33#include <linux/delay.h>
34#include "dvb_frontend.h"
35#include "cx22702.h"
36
37
38struct cx22702_state {
39
40 struct i2c_adapter* i2c;
41
42 struct dvb_frontend_ops ops;
43
44 /* configuration settings */
45 const struct cx22702_config* config;
46
47 struct dvb_frontend frontend;
48
49 /* previous uncorrected block counter */
50 u8 prevUCBlocks;
51};
52
53static int debug = 0;
54#define dprintk if (debug) printk
55
56/* Register values to initialise the demod */
57static u8 init_tab [] = {
58 0x00, 0x00, /* Stop aquisition */
59 0x0B, 0x06,
60 0x09, 0x01,
61 0x0D, 0x41,
62 0x16, 0x32,
63 0x20, 0x0A,
64 0x21, 0x17,
65 0x24, 0x3e,
66 0x26, 0xff,
67 0x27, 0x10,
68 0x28, 0x00,
69 0x29, 0x00,
70 0x2a, 0x10,
71 0x2b, 0x00,
72 0x2c, 0x10,
73 0x2d, 0x00,
74 0x48, 0xd4,
75 0x49, 0x56,
76 0x6b, 0x1e,
77 0xc8, 0x02,
78 0xf8, 0x02,
79 0xf9, 0x00,
80 0xfa, 0x00,
81 0xfb, 0x00,
82 0xfc, 0x00,
83 0xfd, 0x00,
84};
85
86static int cx22702_writereg (struct cx22702_state* state, u8 reg, u8 data)
87{
88 int ret;
89 u8 buf [] = { reg, data };
90 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
91
92 ret = i2c_transfer(state->i2c, &msg, 1);
93
94 if (ret != 1)
95 printk("%s: writereg error (reg == 0x%02x, val == 0x%02x, ret == %i)\n",
96 __FUNCTION__, reg, data, ret);
97
98 return (ret != 1) ? -1 : 0;
99}
100
101static u8 cx22702_readreg (struct cx22702_state* state, u8 reg)
102{
103 int ret;
104 u8 b0 [] = { reg };
105 u8 b1 [] = { 0 };
106
107 struct i2c_msg msg [] = {
108 { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
109 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
110
111 ret = i2c_transfer(state->i2c, msg, 2);
112
113 if (ret != 2)
114 printk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret);
115
116 return b1[0];
117}
118
119static int cx22702_set_inversion (struct cx22702_state *state, int inversion)
120{
121 u8 val;
122
123 switch (inversion) {
124
125 case INVERSION_AUTO:
126 return -EOPNOTSUPP;
127
128 case INVERSION_ON:
129 val = cx22702_readreg (state, 0x0C);
130 return cx22702_writereg (state, 0x0C, val | 0x01);
131
132 case INVERSION_OFF:
133 val = cx22702_readreg (state, 0x0C);
134 return cx22702_writereg (state, 0x0C, val & 0xfe);
135
136 default:
137 return -EINVAL;
138
139 }
140
141}
142
143/* Retrieve the demod settings */
144static int cx22702_get_tps (struct cx22702_state *state, struct dvb_ofdm_parameters *p)
145{
146 u8 val;
147
148 /* Make sure the TPS regs are valid */
149 if (!(cx22702_readreg(state, 0x0A) & 0x20))
150 return -EAGAIN;
151
152 val = cx22702_readreg (state, 0x01);
153 switch( (val&0x18)>>3) {
154 case 0: p->constellation = QPSK; break;
155 case 1: p->constellation = QAM_16; break;
156 case 2: p->constellation = QAM_64; break;
157 }
158 switch( val&0x07 ) {
159 case 0: p->hierarchy_information = HIERARCHY_NONE; break;
160 case 1: p->hierarchy_information = HIERARCHY_1; break;
161 case 2: p->hierarchy_information = HIERARCHY_2; break;
162 case 3: p->hierarchy_information = HIERARCHY_4; break;
163 }
164
165
166 val = cx22702_readreg (state, 0x02);
167 switch( (val&0x38)>>3 ) {
168 case 0: p->code_rate_HP = FEC_1_2; break;
169 case 1: p->code_rate_HP = FEC_2_3; break;
170 case 2: p->code_rate_HP = FEC_3_4; break;
171 case 3: p->code_rate_HP = FEC_5_6; break;
172 case 4: p->code_rate_HP = FEC_7_8; break;
173 }
174 switch( val&0x07 ) {
175 case 0: p->code_rate_LP = FEC_1_2; break;
176 case 1: p->code_rate_LP = FEC_2_3; break;
177 case 2: p->code_rate_LP = FEC_3_4; break;
178 case 3: p->code_rate_LP = FEC_5_6; break;
179 case 4: p->code_rate_LP = FEC_7_8; break;
180 }
181
182
183 val = cx22702_readreg (state, 0x03);
184 switch( (val&0x0c)>>2 ) {
185 case 0: p->guard_interval = GUARD_INTERVAL_1_32; break;
186 case 1: p->guard_interval = GUARD_INTERVAL_1_16; break;
187 case 2: p->guard_interval = GUARD_INTERVAL_1_8; break;
188 case 3: p->guard_interval = GUARD_INTERVAL_1_4; break;
189 }
190 switch( val&0x03 ) {
191 case 0: p->transmission_mode = TRANSMISSION_MODE_2K; break;
192 case 1: p->transmission_mode = TRANSMISSION_MODE_8K; break;
193 }
194
195 return 0;
196}
197
198/* Talk to the demod, set the FEC, GUARD, QAM settings etc */
199static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
200{
201 u8 val;
202 struct cx22702_state* state = (struct cx22702_state*) fe->demodulator_priv;
203
204 /* set PLL */
205 cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) &0xfe);
206 state->config->pll_set(fe, p);
207 cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) | 1);
208
209 /* set inversion */
210 cx22702_set_inversion (state, p->inversion);
211
212 /* set bandwidth */
213 switch(p->u.ofdm.bandwidth) {
214 case BANDWIDTH_6_MHZ:
215 cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xcf) | 0x20 );
216 break;
217 case BANDWIDTH_7_MHZ:
218 cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xcf) | 0x10 );
219 break;
220 case BANDWIDTH_8_MHZ:
221 cx22702_writereg(state, 0x0C, cx22702_readreg(state, 0x0C) &0xcf );
222 break;
223 default:
224 dprintk ("%s: invalid bandwidth\n",__FUNCTION__);
225 return -EINVAL;
226 }
227
228
229 p->u.ofdm.code_rate_LP = FEC_AUTO; //temp hack as manual not working
230
231 /* use auto configuration? */
232 if((p->u.ofdm.hierarchy_information==HIERARCHY_AUTO) ||
233 (p->u.ofdm.constellation==QAM_AUTO) ||
234 (p->u.ofdm.code_rate_HP==FEC_AUTO) ||
235 (p->u.ofdm.code_rate_LP==FEC_AUTO) ||
236 (p->u.ofdm.guard_interval==GUARD_INTERVAL_AUTO) ||
237 (p->u.ofdm.transmission_mode==TRANSMISSION_MODE_AUTO) ) {
238
239 /* TPS Source - use hardware driven values */
240 cx22702_writereg(state, 0x06, 0x10);
241 cx22702_writereg(state, 0x07, 0x9);
242 cx22702_writereg(state, 0x08, 0xC1);
243 cx22702_writereg(state, 0x0B, cx22702_readreg(state, 0x0B) & 0xfc );
244 cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40 );
245 cx22702_writereg(state, 0x00, 0x01); /* Begin aquisition */
246 printk("%s: Autodetecting\n",__FUNCTION__);
247 return 0;
248 }
249
250 /* manually programmed values */
251 val=0;
252 switch(p->u.ofdm.constellation) {
253 case QPSK: val = (val&0xe7); break;
254 case QAM_16: val = (val&0xe7)|0x08; break;
255 case QAM_64: val = (val&0xe7)|0x10; break;
256 default:
257 dprintk ("%s: invalid constellation\n",__FUNCTION__);
258 return -EINVAL;
259 }
260 switch(p->u.ofdm.hierarchy_information) {
261 case HIERARCHY_NONE: val = (val&0xf8); break;
262 case HIERARCHY_1: val = (val&0xf8)|1; break;
263 case HIERARCHY_2: val = (val&0xf8)|2; break;
264 case HIERARCHY_4: val = (val&0xf8)|3; break;
265 default:
266 dprintk ("%s: invalid hierarchy\n",__FUNCTION__);
267 return -EINVAL;
268 }
269 cx22702_writereg (state, 0x06, val);
270
271 val=0;
272 switch(p->u.ofdm.code_rate_HP) {
273 case FEC_NONE:
274 case FEC_1_2: val = (val&0xc7); break;
275 case FEC_2_3: val = (val&0xc7)|0x08; break;
276 case FEC_3_4: val = (val&0xc7)|0x10; break;
277 case FEC_5_6: val = (val&0xc7)|0x18; break;
278 case FEC_7_8: val = (val&0xc7)|0x20; break;
279 default:
280 dprintk ("%s: invalid code_rate_HP\n",__FUNCTION__);
281 return -EINVAL;
282 }
283 switch(p->u.ofdm.code_rate_LP) {
284 case FEC_NONE:
285 case FEC_1_2: val = (val&0xf8); break;
286 case FEC_2_3: val = (val&0xf8)|1; break;
287 case FEC_3_4: val = (val&0xf8)|2; break;
288 case FEC_5_6: val = (val&0xf8)|3; break;
289 case FEC_7_8: val = (val&0xf8)|4; break;
290 default:
291 dprintk ("%s: invalid code_rate_LP\n",__FUNCTION__);
292 return -EINVAL;
293 }
294 cx22702_writereg (state, 0x07, val);
295
296 val=0;
297 switch(p->u.ofdm.guard_interval) {
298 case GUARD_INTERVAL_1_32: val = (val&0xf3); break;
299 case GUARD_INTERVAL_1_16: val = (val&0xf3)|0x04; break;
300 case GUARD_INTERVAL_1_8: val = (val&0xf3)|0x08; break;
301 case GUARD_INTERVAL_1_4: val = (val&0xf3)|0x0c; break;
302 default:
303 dprintk ("%s: invalid guard_interval\n",__FUNCTION__);
304 return -EINVAL;
305 }
306 switch(p->u.ofdm.transmission_mode) {
307 case TRANSMISSION_MODE_2K: val = (val&0xfc); break;
308 case TRANSMISSION_MODE_8K: val = (val&0xfc)|1; break;
309 default:
310 dprintk ("%s: invalid transmission_mode\n",__FUNCTION__);
311 return -EINVAL;
312 }
313 cx22702_writereg(state, 0x08, val);
314 cx22702_writereg(state, 0x0B, (cx22702_readreg(state, 0x0B) & 0xfc) | 0x02 );
315 cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40 );
316
317 /* Begin channel aquisition */
318 cx22702_writereg(state, 0x00, 0x01);
319
320 return 0;
321}
322
323/* Reset the demod hardware and reset all of the configuration registers
324 to a default state. */
325static int cx22702_init (struct dvb_frontend* fe)
326{
327 int i;
328 struct cx22702_state* state = (struct cx22702_state*) fe->demodulator_priv;
329
330 cx22702_writereg (state, 0x00, 0x02);
331
332 msleep(10);
333
334 for (i=0; i<sizeof(init_tab); i+=2)
335 cx22702_writereg (state, init_tab[i], init_tab[i+1]);
336
337
338 /* init PLL */
339 if (state->config->pll_init) {
340 cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) &0xfe);
341 state->config->pll_init(fe);
342 cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) | 1);
343 }
344
345 return 0;
346}
347
348static int cx22702_read_status(struct dvb_frontend* fe, fe_status_t* status)
349{
350 struct cx22702_state* state = (struct cx22702_state*) fe->demodulator_priv;
351 u8 reg0A;
352 u8 reg23;
353
354 *status = 0;
355
356 reg0A = cx22702_readreg (state, 0x0A);
357 reg23 = cx22702_readreg (state, 0x23);
358
359 dprintk ("%s: status demod=0x%02x agc=0x%02x\n"
360 ,__FUNCTION__,reg0A,reg23);
361
362 if(reg0A & 0x10) {
363 *status |= FE_HAS_LOCK;
364 *status |= FE_HAS_VITERBI;
365 *status |= FE_HAS_SYNC;
366 }
367
368 if(reg0A & 0x20)
369 *status |= FE_HAS_CARRIER;
370
371 if(reg23 < 0xf0)
372 *status |= FE_HAS_SIGNAL;
373
374 return 0;
375}
376
377static int cx22702_read_ber(struct dvb_frontend* fe, u32* ber)
378{
379 struct cx22702_state* state = (struct cx22702_state*) fe->demodulator_priv;
380
381 if(cx22702_readreg (state, 0xE4) & 0x02) {
382 /* Realtime statistics */
383 *ber = (cx22702_readreg (state, 0xDE) & 0x7F) << 7
384 | (cx22702_readreg (state, 0xDF)&0x7F);
385 } else {
386 /* Averagtine statistics */
387 *ber = (cx22702_readreg (state, 0xDE) & 0x7F) << 7
388 | cx22702_readreg (state, 0xDF);
389 }
390
391 return 0;
392}
393
394static int cx22702_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
395{
396 struct cx22702_state* state = (struct cx22702_state*) fe->demodulator_priv;
397
398 *signal_strength = cx22702_readreg (state, 0x23);
399
400 return 0;
401}
402
403static int cx22702_read_snr(struct dvb_frontend* fe, u16* snr)
404{
405 struct cx22702_state* state = (struct cx22702_state*) fe->demodulator_priv;
406
407 u16 rs_ber=0;
408 if(cx22702_readreg (state, 0xE4) & 0x02) {
409 /* Realtime statistics */
410 rs_ber = (cx22702_readreg (state, 0xDE) & 0x7F) << 7
411 | (cx22702_readreg (state, 0xDF)& 0x7F);
412 } else {
413 /* Averagine statistics */
414 rs_ber = (cx22702_readreg (state, 0xDE) & 0x7F) << 8
415 | cx22702_readreg (state, 0xDF);
416 }
417 *snr = ~rs_ber;
418
419 return 0;
420}
421
422static int cx22702_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
423{
424 struct cx22702_state* state = (struct cx22702_state*) fe->demodulator_priv;
425
426 u8 _ucblocks;
427
428 /* RS Uncorrectable Packet Count then reset */
429 _ucblocks = cx22702_readreg (state, 0xE3);
430 if (state->prevUCBlocks < _ucblocks) *ucblocks = (_ucblocks - state->prevUCBlocks);
431 else *ucblocks = state->prevUCBlocks - _ucblocks;
432 state->prevUCBlocks = _ucblocks;
433
434 return 0;
435}
436
437static int cx22702_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
438{
439 struct cx22702_state* state = (struct cx22702_state*) fe->demodulator_priv;
440
441 u8 reg0C = cx22702_readreg (state, 0x0C);
442
443 p->inversion = reg0C & 0x1 ? INVERSION_ON : INVERSION_OFF;
444 return cx22702_get_tps (state, &p->u.ofdm);
445}
446
447static void cx22702_release(struct dvb_frontend* fe)
448{
449 struct cx22702_state* state = (struct cx22702_state*) fe->demodulator_priv;
450 kfree(state);
451}
452
453static struct dvb_frontend_ops cx22702_ops;
454
455struct dvb_frontend* cx22702_attach(const struct cx22702_config* config,
456 struct i2c_adapter* i2c)
457{
458 struct cx22702_state* state = NULL;
459
460 /* allocate memory for the internal state */
461 state = (struct cx22702_state*) kmalloc(sizeof(struct cx22702_state), GFP_KERNEL);
462 if (state == NULL) goto error;
463
464 /* setup the state */
465 state->config = config;
466 state->i2c = i2c;
467 memcpy(&state->ops, &cx22702_ops, sizeof(struct dvb_frontend_ops));
468 state->prevUCBlocks = 0;
469
470 /* check if the demod is there */
471 if (cx22702_readreg(state, 0x1f) != 0x3) goto error;
472
473 /* create dvb_frontend */
474 state->frontend.ops = &state->ops;
475 state->frontend.demodulator_priv = state;
476 return &state->frontend;
477
478error:
479 kfree(state);
480 return NULL;
481}
482
483static struct dvb_frontend_ops cx22702_ops = {
484
485 .info = {
486 .name = "Conexant CX22702 DVB-T",
487 .type = FE_OFDM,
488 .frequency_min = 177000000,
489 .frequency_max = 858000000,
490 .frequency_stepsize = 166666,
491 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
492 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
493 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
494 FE_CAN_HIERARCHY_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
495 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER
496 },
497
498 .release = cx22702_release,
499
500 .init = cx22702_init,
501
502 .set_frontend = cx22702_set_tps,
503 .get_frontend = cx22702_get_frontend,
504
505 .read_status = cx22702_read_status,
506 .read_ber = cx22702_read_ber,
507 .read_signal_strength = cx22702_read_signal_strength,
508 .read_snr = cx22702_read_snr,
509 .read_ucblocks = cx22702_read_ucblocks,
510};
511
512module_param(debug, int, 0644);
513MODULE_PARM_DESC(debug, "Enable verbose debug messages");
514
515MODULE_DESCRIPTION("Conexant CX22702 DVB-T Demodulator driver");
516MODULE_AUTHOR("Steven Toth");
517MODULE_LICENSE("GPL");
518
519EXPORT_SYMBOL(cx22702_attach);
diff --git a/drivers/media/dvb/frontends/cx22702.h b/drivers/media/dvb/frontends/cx22702.h
new file mode 100644
index 000000000000..6e34f997aba2
--- /dev/null
+++ b/drivers/media/dvb/frontends/cx22702.h
@@ -0,0 +1,46 @@
1/*
2 Conexant 22702 DVB OFDM demodulator driver
3
4 based on:
5 Alps TDMB7 DVB OFDM demodulator driver
6
7 Copyright (C) 2001-2002 Convergence Integrated Media GmbH
8 Holger Waechtler <holger@convergence.de>
9
10 Copyright (C) 2004 Steven Toth <steve@toth.demon.co.uk>
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25
26*/
27
28#ifndef CX22702_H
29#define CX22702_H
30
31#include <linux/dvb/frontend.h>
32
33struct cx22702_config
34{
35 /* the demodulator's i2c address */
36 u8 demod_address;
37
38 /* PLL maintenance */
39 int (*pll_init)(struct dvb_frontend* fe);
40 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
41};
42
43extern struct dvb_frontend* cx22702_attach(const struct cx22702_config* config,
44 struct i2c_adapter* i2c);
45
46#endif // CX22702_H
diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c
new file mode 100644
index 000000000000..ae16112a0653
--- /dev/null
+++ b/drivers/media/dvb/frontends/cx24110.c
@@ -0,0 +1,657 @@
1/*
2 cx24110 - Single Chip Satellite Channel Receiver driver module
3
4 Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@t-online.de> based on
5 work
6 Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22
23*/
24
25#include <linux/slab.h>
26#include <linux/kernel.h>
27#include <linux/module.h>
28#include <linux/moduleparam.h>
29#include <linux/init.h>
30
31#include "dvb_frontend.h"
32#include "cx24110.h"
33
34
35struct cx24110_state {
36
37 struct i2c_adapter* i2c;
38
39 struct dvb_frontend_ops ops;
40
41 const struct cx24110_config* config;
42
43 struct dvb_frontend frontend;
44
45 u32 lastber;
46 u32 lastbler;
47 u32 lastesn0;
48};
49
50static int debug;
51#define dprintk(args...) \
52 do { \
53 if (debug) printk(KERN_DEBUG "cx24110: " args); \
54 } while (0)
55
56static struct {u8 reg; u8 data;} cx24110_regdata[]=
57 /* Comments beginning with @ denote this value should
58 be the default */
59 {{0x09,0x01}, /* SoftResetAll */
60 {0x09,0x00}, /* release reset */
61 {0x01,0xe8}, /* MSB of code rate 27.5MS/s */
62 {0x02,0x17}, /* middle byte " */
63 {0x03,0x29}, /* LSB " */
64 {0x05,0x03}, /* @ DVB mode, standard code rate 3/4 */
65 {0x06,0xa5}, /* @ PLL 60MHz */
66 {0x07,0x01}, /* @ Fclk, i.e. sampling clock, 60MHz */
67 {0x0a,0x00}, /* @ partial chip disables, do not set */
68 {0x0b,0x01}, /* set output clock in gapped mode, start signal low
69 active for first byte */
70 {0x0c,0x11}, /* no parity bytes, large hold time, serial data out */
71 {0x0d,0x6f}, /* @ RS Sync/Unsync thresholds */
72 {0x10,0x40}, /* chip doc is misleading here: write bit 6 as 1
73 to avoid starting the BER counter. Reset the
74 CRC test bit. Finite counting selected */
75 {0x15,0xff}, /* @ size of the limited time window for RS BER
76 estimation. It is <value>*256 RS blocks, this
77 gives approx. 2.6 sec at 27.5MS/s, rate 3/4 */
78 {0x16,0x00}, /* @ enable all RS output ports */
79 {0x17,0x04}, /* @ time window allowed for the RS to sync */
80 {0x18,0xae}, /* @ allow all standard DVB code rates to be scanned
81 for automatically */
82 /* leave the current code rate and normalization
83 registers as they are after reset... */
84 {0x21,0x10}, /* @ during AutoAcq, search each viterbi setting
85 only once */
86 {0x23,0x18}, /* @ size of the limited time window for Viterbi BER
87 estimation. It is <value>*65536 channel bits, i.e.
88 approx. 38ms at 27.5MS/s, rate 3/4 */
89 {0x24,0x24}, /* do not trigger Viterbi CRC test. Finite count window */
90 /* leave front-end AGC parameters at default values */
91 /* leave decimation AGC parameters at default values */
92 {0x35,0x40}, /* disable all interrupts. They are not connected anyway */
93 {0x36,0xff}, /* clear all interrupt pending flags */
94 {0x37,0x00}, /* @ fully enable AutoAcqq state machine */
95 {0x38,0x07}, /* @ enable fade recovery, but not autostart AutoAcq */
96 /* leave the equalizer parameters on their default values */
97 /* leave the final AGC parameters on their default values */
98 {0x41,0x00}, /* @ MSB of front-end derotator frequency */
99 {0x42,0x00}, /* @ middle bytes " */
100 {0x43,0x00}, /* @ LSB " */
101 /* leave the carrier tracking loop parameters on default */
102 /* leave the bit timing loop parameters at gefault */
103 {0x56,0x4d}, /* set the filtune voltage to 2.7V, as recommended by */
104 /* the cx24108 data sheet for symbol rates above 15MS/s */
105 {0x57,0x00}, /* @ Filter sigma delta enabled, positive */
106 {0x61,0x95}, /* GPIO pins 1-4 have special function */
107 {0x62,0x05}, /* GPIO pin 5 has special function, pin 6 is GPIO */
108 {0x63,0x00}, /* All GPIO pins use CMOS output characteristics */
109 {0x64,0x20}, /* GPIO 6 is input, all others are outputs */
110 {0x6d,0x30}, /* tuner auto mode clock freq 62kHz */
111 {0x70,0x15}, /* use auto mode, tuner word is 21 bits long */
112 {0x73,0x00}, /* @ disable several demod bypasses */
113 {0x74,0x00}, /* @ " */
114 {0x75,0x00} /* @ " */
115 /* the remaining registers are for SEC */
116 };
117
118
119static int cx24110_writereg (struct cx24110_state* state, int reg, int data)
120{
121 u8 buf [] = { reg, data };
122 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
123 int err;
124
125 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
126 dprintk ("%s: writereg error (err == %i, reg == 0x%02x,"
127 " data == 0x%02x)\n", __FUNCTION__, err, reg, data);
128 return -EREMOTEIO;
129 }
130
131 return 0;
132}
133
134static int cx24110_readreg (struct cx24110_state* state, u8 reg)
135{
136 int ret;
137 u8 b0 [] = { reg };
138 u8 b1 [] = { 0 };
139 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
140 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
141
142 ret = i2c_transfer(state->i2c, msg, 2);
143
144 if (ret != 2) return ret;
145
146 return b1[0];
147}
148
149static int cx24110_set_inversion (struct cx24110_state* state, fe_spectral_inversion_t inversion)
150{
151/* fixme (low): error handling */
152
153 switch (inversion) {
154 case INVERSION_OFF:
155 cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)|0x1);
156 /* AcqSpectrInvDis on. No idea why someone should want this */
157 cx24110_writereg(state,0x5,cx24110_readreg(state,0x5)&0xf7);
158 /* Initial value 0 at start of acq */
159 cx24110_writereg(state,0x22,cx24110_readreg(state,0x22)&0xef);
160 /* current value 0 */
161 /* The cx24110 manual tells us this reg is read-only.
162 But what the heck... set it ayways */
163 break;
164 case INVERSION_ON:
165 cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)|0x1);
166 /* AcqSpectrInvDis on. No idea why someone should want this */
167 cx24110_writereg(state,0x5,cx24110_readreg(state,0x5)|0x08);
168 /* Initial value 1 at start of acq */
169 cx24110_writereg(state,0x22,cx24110_readreg(state,0x22)|0x10);
170 /* current value 1 */
171 break;
172 case INVERSION_AUTO:
173 cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)&0xfe);
174 /* AcqSpectrInvDis off. Leave initial & current states as is */
175 break;
176 default:
177 return -EINVAL;
178 }
179
180 return 0;
181}
182
183static int cx24110_set_fec (struct cx24110_state* state, fe_code_rate_t fec)
184{
185/* fixme (low): error handling */
186
187 static const int rate[]={-1,1,2,3,5,7,-1};
188 static const int g1[]={-1,0x01,0x02,0x05,0x15,0x45,-1};
189 static const int g2[]={-1,0x01,0x03,0x06,0x1a,0x7a,-1};
190
191 /* Well, the AutoAcq engine of the cx24106 and 24110 automatically
192 searches all enabled viterbi rates, and can handle non-standard
193 rates as well. */
194
195 if (fec>FEC_AUTO)
196 fec=FEC_AUTO;
197
198 if (fec==FEC_AUTO) { /* (re-)establish AutoAcq behaviour */
199 cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)&0xdf);
200 /* clear AcqVitDis bit */
201 cx24110_writereg(state,0x18,0xae);
202 /* allow all DVB standard code rates */
203 cx24110_writereg(state,0x05,(cx24110_readreg(state,0x05)&0xf0)|0x3);
204 /* set nominal Viterbi rate 3/4 */
205 cx24110_writereg(state,0x22,(cx24110_readreg(state,0x22)&0xf0)|0x3);
206 /* set current Viterbi rate 3/4 */
207 cx24110_writereg(state,0x1a,0x05); cx24110_writereg(state,0x1b,0x06);
208 /* set the puncture registers for code rate 3/4 */
209 return 0;
210 } else {
211 cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)|0x20);
212 /* set AcqVitDis bit */
213 if(rate[fec]>0) {
214 cx24110_writereg(state,0x05,(cx24110_readreg(state,0x05)&0xf0)|rate[fec]);
215 /* set nominal Viterbi rate */
216 cx24110_writereg(state,0x22,(cx24110_readreg(state,0x22)&0xf0)|rate[fec]);
217 /* set current Viterbi rate */
218 cx24110_writereg(state,0x1a,g1[fec]);
219 cx24110_writereg(state,0x1b,g2[fec]);
220 /* not sure if this is the right way: I always used AutoAcq mode */
221 } else
222 return -EOPNOTSUPP;
223/* fixme (low): which is the correct return code? */
224 };
225 return 0;
226}
227
228static fe_code_rate_t cx24110_get_fec (struct cx24110_state* state)
229{
230 int i;
231
232 i=cx24110_readreg(state,0x22)&0x0f;
233 if(!(i&0x08)) {
234 return FEC_1_2 + i - 1;
235 } else {
236/* fixme (low): a special code rate has been selected. In theory, we need to
237 return a denominator value, a numerator value, and a pair of puncture
238 maps to correctly describe this mode. But this should never happen in
239 practice, because it cannot be set by cx24110_get_fec. */
240 return FEC_NONE;
241 }
242}
243
244static int cx24110_set_symbolrate (struct cx24110_state* state, u32 srate)
245{
246/* fixme (low): add error handling */
247 u32 ratio;
248 u32 tmp, fclk, BDRI;
249
250 static const u32 bands[]={5000000UL,15000000UL,90999000UL/2};
251 int i;
252
253dprintk("cx24110 debug: entering %s(%d)\n",__FUNCTION__,srate);
254 if (srate>90999000UL/2)
255 srate=90999000UL/2;
256 if (srate<500000)
257 srate=500000;
258
259 for(i=0;(i<sizeof(bands)/sizeof(bands[0]))&&(srate>bands[i]);i++)
260 ;
261 /* first, check which sample rate is appropriate: 45, 60 80 or 90 MHz,
262 and set the PLL accordingly (R07[1:0] Fclk, R06[7:4] PLLmult,
263 R06[3:0] PLLphaseDetGain */
264 tmp=cx24110_readreg(state,0x07)&0xfc;
265 if(srate<90999000UL/4) { /* sample rate 45MHz*/
266 cx24110_writereg(state,0x07,tmp);
267 cx24110_writereg(state,0x06,0x78);
268 fclk=90999000UL/2;
269 } else if(srate<60666000UL/2) { /* sample rate 60MHz */
270 cx24110_writereg(state,0x07,tmp|0x1);
271 cx24110_writereg(state,0x06,0xa5);
272 fclk=60666000UL;
273 } else if(srate<80888000UL/2) { /* sample rate 80MHz */
274 cx24110_writereg(state,0x07,tmp|0x2);
275 cx24110_writereg(state,0x06,0x87);
276 fclk=80888000UL;
277 } else { /* sample rate 90MHz */
278 cx24110_writereg(state,0x07,tmp|0x3);
279 cx24110_writereg(state,0x06,0x78);
280 fclk=90999000UL;
281 };
282 dprintk("cx24110 debug: fclk %d Hz\n",fclk);
283 /* we need to divide two integers with approx. 27 bits in 32 bit
284 arithmetic giving a 25 bit result */
285 /* the maximum dividend is 90999000/2, 0x02b6446c, this number is
286 also the most complex divisor. Hence, the dividend has,
287 assuming 32bit unsigned arithmetic, 6 clear bits on top, the
288 divisor 2 unused bits at the bottom. Also, the quotient is
289 always less than 1/2. Borrowed from VES1893.c, of course */
290
291 tmp=srate<<6;
292 BDRI=fclk>>2;
293 ratio=(tmp/BDRI);
294
295 tmp=(tmp%BDRI)<<8;
296 ratio=(ratio<<8)+(tmp/BDRI);
297
298 tmp=(tmp%BDRI)<<8;
299 ratio=(ratio<<8)+(tmp/BDRI);
300
301 tmp=(tmp%BDRI)<<1;
302 ratio=(ratio<<1)+(tmp/BDRI);
303
304 dprintk("srate= %d (range %d, up to %d)\n", srate,i,bands[i]);
305 dprintk("fclk = %d\n", fclk);
306 dprintk("ratio= %08x\n", ratio);
307
308 cx24110_writereg(state, 0x1, (ratio>>16)&0xff);
309 cx24110_writereg(state, 0x2, (ratio>>8)&0xff);
310 cx24110_writereg(state, 0x3, (ratio)&0xff);
311
312 return 0;
313
314}
315
316int cx24110_pll_write (struct dvb_frontend* fe, u32 data)
317{
318 struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
319
320/* tuner data is 21 bits long, must be left-aligned in data */
321/* tuner cx24108 is written through a dedicated 3wire interface on the demod chip */
322/* FIXME (low): add error handling, avoid infinite loops if HW fails... */
323
324 dprintk("cx24110 debug: cx24108_write(%8.8x)\n",data);
325
326 cx24110_writereg(state,0x6d,0x30); /* auto mode at 62kHz */
327 cx24110_writereg(state,0x70,0x15); /* auto mode 21 bits */
328
329 /* if the auto tuner writer is still busy, clear it out */
330 while (cx24110_readreg(state,0x6d)&0x80)
331 cx24110_writereg(state,0x72,0);
332
333 /* write the topmost 8 bits */
334 cx24110_writereg(state,0x72,(data>>24)&0xff);
335
336 /* wait for the send to be completed */
337 while ((cx24110_readreg(state,0x6d)&0xc0)==0x80)
338 ;
339
340 /* send another 8 bytes */
341 cx24110_writereg(state,0x72,(data>>16)&0xff);
342 while ((cx24110_readreg(state,0x6d)&0xc0)==0x80)
343 ;
344
345 /* and the topmost 5 bits of this byte */
346 cx24110_writereg(state,0x72,(data>>8)&0xff);
347 while ((cx24110_readreg(state,0x6d)&0xc0)==0x80)
348 ;
349
350 /* now strobe the enable line once */
351 cx24110_writereg(state,0x6d,0x32);
352 cx24110_writereg(state,0x6d,0x30);
353
354 return 0;
355}
356
357static int cx24110_initfe(struct dvb_frontend* fe)
358{
359 struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
360/* fixme (low): error handling */
361 int i;
362
363 dprintk("%s: init chip\n", __FUNCTION__);
364
365 for(i=0;i<sizeof(cx24110_regdata)/sizeof(cx24110_regdata[0]);i++) {
366 cx24110_writereg(state, cx24110_regdata[i].reg, cx24110_regdata[i].data);
367 };
368
369 if (state->config->pll_init) state->config->pll_init(fe);
370
371 return 0;
372}
373
374static int cx24110_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage)
375{
376 struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
377
378 switch (voltage) {
379 case SEC_VOLTAGE_13:
380 return cx24110_writereg(state,0x76,(cx24110_readreg(state,0x76)&0x3b)|0xc0);
381 case SEC_VOLTAGE_18:
382 return cx24110_writereg(state,0x76,(cx24110_readreg(state,0x76)&0x3b)|0x40);
383 default:
384 return -EINVAL;
385 };
386}
387
388static int cx24110_diseqc_send_burst(struct dvb_frontend* fe,
389 fe_sec_mini_cmd_t burst)
390{
391 int rv, bit, i;
392 struct cx24110_state *state = fe->demodulator_priv;
393
394 if (burst == SEC_MINI_A)
395 bit = 0x00;
396 else if (burst == SEC_MINI_B)
397 bit = 0x08;
398 else
399 return -EINVAL;
400
401 rv = cx24110_readreg(state, 0x77);
402 cx24110_writereg(state, 0x77, rv|0x04);
403
404 rv = cx24110_readreg(state, 0x76);
405 cx24110_writereg(state, 0x76, ((rv & 0x90) | 0x40 | bit));
406 for (i = 500; i-- > 0 && !(cx24110_readreg(state,0x76)&0x40) ; )
407 ; /* wait for LNB ready */
408
409 return 0;
410}
411
412static int cx24110_send_diseqc_msg(struct dvb_frontend* fe,
413 struct dvb_diseqc_master_cmd *cmd)
414{
415 int i, rv;
416 struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
417
418 for (i = 0; i < cmd->msg_len; i++)
419 cx24110_writereg(state, 0x79 + i, cmd->msg[i]);
420
421 rv = cx24110_readreg(state, 0x77);
422 cx24110_writereg(state, 0x77, rv|0x04);
423
424 rv = cx24110_readreg(state, 0x76);
425
426 cx24110_writereg(state, 0x76, ((rv & 0x90) | 0x40) | ((cmd->msg_len-3) & 3));
427 for (i=500; i-- > 0 && !(cx24110_readreg(state,0x76)&0x40);)
428 ; /* wait for LNB ready */
429
430 return 0;
431}
432
433static int cx24110_read_status(struct dvb_frontend* fe, fe_status_t* status)
434{
435 struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
436
437 int sync = cx24110_readreg (state, 0x55);
438
439 *status = 0;
440
441 if (sync & 0x10)
442 *status |= FE_HAS_SIGNAL;
443
444 if (sync & 0x08)
445 *status |= FE_HAS_CARRIER;
446
447 sync = cx24110_readreg (state, 0x08);
448
449 if (sync & 0x40)
450 *status |= FE_HAS_VITERBI;
451
452 if (sync & 0x20)
453 *status |= FE_HAS_SYNC;
454
455 if ((sync & 0x60) == 0x60)
456 *status |= FE_HAS_LOCK;
457
458 return 0;
459}
460
461static int cx24110_read_ber(struct dvb_frontend* fe, u32* ber)
462{
463 struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
464
465 /* fixme (maybe): value range is 16 bit. Scale? */
466 if(cx24110_readreg(state,0x24)&0x10) {
467 /* the Viterbi error counter has finished one counting window */
468 cx24110_writereg(state,0x24,0x04); /* select the ber reg */
469 state->lastber=cx24110_readreg(state,0x25)|
470 (cx24110_readreg(state,0x26)<<8);
471 cx24110_writereg(state,0x24,0x04); /* start new count window */
472 cx24110_writereg(state,0x24,0x14);
473 }
474 *ber = state->lastber;
475
476 return 0;
477}
478
479static int cx24110_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
480{
481 struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
482
483/* no provision in hardware. Read the frontend AGC accumulator. No idea how to scale this, but I know it is 2s complement */
484 u8 signal = cx24110_readreg (state, 0x27)+128;
485 *signal_strength = (signal << 8) | signal;
486
487 return 0;
488}
489
490static int cx24110_read_snr(struct dvb_frontend* fe, u16* snr)
491{
492 struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
493
494 /* no provision in hardware. Can be computed from the Es/N0 estimator, but I don't know how. */
495 if(cx24110_readreg(state,0x6a)&0x80) {
496 /* the Es/N0 error counter has finished one counting window */
497 state->lastesn0=cx24110_readreg(state,0x69)|
498 (cx24110_readreg(state,0x68)<<8);
499 cx24110_writereg(state,0x6a,0x84); /* start new count window */
500 }
501 *snr = state->lastesn0;
502
503 return 0;
504}
505
506static int cx24110_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
507{
508 struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
509 u32 lastbyer;
510
511 if(cx24110_readreg(state,0x10)&0x40) {
512 /* the RS error counter has finished one counting window */
513 cx24110_writereg(state,0x10,0x60); /* select the byer reg */
514 lastbyer=cx24110_readreg(state,0x12)|
515 (cx24110_readreg(state,0x13)<<8)|
516 (cx24110_readreg(state,0x14)<<16);
517 cx24110_writereg(state,0x10,0x70); /* select the bler reg */
518 state->lastbler=cx24110_readreg(state,0x12)|
519 (cx24110_readreg(state,0x13)<<8)|
520 (cx24110_readreg(state,0x14)<<16);
521 cx24110_writereg(state,0x10,0x20); /* start new count window */
522 }
523 *ucblocks = state->lastbler;
524
525 return 0;
526}
527
528static int cx24110_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
529{
530 struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
531
532 state->config->pll_set(fe, p);
533 cx24110_set_inversion (state, p->inversion);
534 cx24110_set_fec (state, p->u.qpsk.fec_inner);
535 cx24110_set_symbolrate (state, p->u.qpsk.symbol_rate);
536 cx24110_writereg(state,0x04,0x05); /* start aquisition */
537
538 return 0;
539}
540
541static int cx24110_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
542{
543 struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
544 s32 afc; unsigned sclk;
545
546/* cannot read back tuner settings (freq). Need to have some private storage */
547
548 sclk = cx24110_readreg (state, 0x07) & 0x03;
549/* ok, real AFC (FEDR) freq. is afc/2^24*fsamp, fsamp=45/60/80/90MHz.
550 * Need 64 bit arithmetic. Is thiss possible in the kernel? */
551 if (sclk==0) sclk=90999000L/2L;
552 else if (sclk==1) sclk=60666000L;
553 else if (sclk==2) sclk=80888000L;
554 else sclk=90999000L;
555 sclk>>=8;
556 afc = sclk*(cx24110_readreg (state, 0x44)&0x1f)+
557 ((sclk*cx24110_readreg (state, 0x45))>>8)+
558 ((sclk*cx24110_readreg (state, 0x46))>>16);
559
560 p->frequency += afc;
561 p->inversion = (cx24110_readreg (state, 0x22) & 0x10) ?
562 INVERSION_ON : INVERSION_OFF;
563 p->u.qpsk.fec_inner = cx24110_get_fec (state);
564
565 return 0;
566}
567
568static int cx24110_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
569{
570 struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
571
572 return cx24110_writereg(state,0x76,(cx24110_readreg(state,0x76)&~0x10)|(((tone==SEC_TONE_ON))?0x10:0));
573}
574
575static void cx24110_release(struct dvb_frontend* fe)
576{
577 struct cx24110_state* state = (struct cx24110_state*) fe->demodulator_priv;
578 kfree(state);
579}
580
581static struct dvb_frontend_ops cx24110_ops;
582
583struct dvb_frontend* cx24110_attach(const struct cx24110_config* config,
584 struct i2c_adapter* i2c)
585{
586 struct cx24110_state* state = NULL;
587 int ret;
588
589 /* allocate memory for the internal state */
590 state = (struct cx24110_state*) kmalloc(sizeof(struct cx24110_state), GFP_KERNEL);
591 if (state == NULL) goto error;
592
593 /* setup the state */
594 state->config = config;
595 state->i2c = i2c;
596 memcpy(&state->ops, &cx24110_ops, sizeof(struct dvb_frontend_ops));
597 state->lastber = 0;
598 state->lastbler = 0;
599 state->lastesn0 = 0;
600
601 /* check if the demod is there */
602 ret = cx24110_readreg(state, 0x00);
603 if ((ret != 0x5a) && (ret != 0x69)) goto error;
604
605 /* create dvb_frontend */
606 state->frontend.ops = &state->ops;
607 state->frontend.demodulator_priv = state;
608 return &state->frontend;
609
610error:
611 kfree(state);
612 return NULL;
613}
614
615static struct dvb_frontend_ops cx24110_ops = {
616
617 .info = {
618 .name = "Conexant CX24110 DVB-S",
619 .type = FE_QPSK,
620 .frequency_min = 950000,
621 .frequency_max = 2150000,
622 .frequency_stepsize = 1011, /* kHz for QPSK frontends */
623 .frequency_tolerance = 29500,
624 .symbol_rate_min = 1000000,
625 .symbol_rate_max = 45000000,
626 .caps = FE_CAN_INVERSION_AUTO |
627 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
628 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
629 FE_CAN_QPSK | FE_CAN_RECOVER
630 },
631
632 .release = cx24110_release,
633
634 .init = cx24110_initfe,
635 .set_frontend = cx24110_set_frontend,
636 .get_frontend = cx24110_get_frontend,
637 .read_status = cx24110_read_status,
638 .read_ber = cx24110_read_ber,
639 .read_signal_strength = cx24110_read_signal_strength,
640 .read_snr = cx24110_read_snr,
641 .read_ucblocks = cx24110_read_ucblocks,
642
643 .diseqc_send_master_cmd = cx24110_send_diseqc_msg,
644 .set_tone = cx24110_set_tone,
645 .set_voltage = cx24110_set_voltage,
646 .diseqc_send_burst = cx24110_diseqc_send_burst,
647};
648
649module_param(debug, int, 0644);
650MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
651
652MODULE_DESCRIPTION("Conexant CX24110 DVB-S Demodulator driver");
653MODULE_AUTHOR("Peter Hettkamp");
654MODULE_LICENSE("GPL");
655
656EXPORT_SYMBOL(cx24110_attach);
657EXPORT_SYMBOL(cx24110_pll_write);
diff --git a/drivers/media/dvb/frontends/cx24110.h b/drivers/media/dvb/frontends/cx24110.h
new file mode 100644
index 000000000000..6b663f4744e0
--- /dev/null
+++ b/drivers/media/dvb/frontends/cx24110.h
@@ -0,0 +1,45 @@
1/*
2 cx24110 - Single Chip Satellite Channel Receiver driver module
3
4 Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@t-online.de> based on
5 work
6 Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22
23*/
24
25#ifndef CX24110_H
26#define CX24110_H
27
28#include <linux/dvb/frontend.h>
29
30struct cx24110_config
31{
32 /* the demodulator's i2c address */
33 u8 demod_address;
34
35 /* PLL maintenance */
36 int (*pll_init)(struct dvb_frontend* fe);
37 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
38};
39
40extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config,
41 struct i2c_adapter* i2c);
42
43extern int cx24110_pll_write(struct dvb_frontend* fe, u32 data);
44
45#endif // CX24110_H
diff --git a/drivers/media/dvb/frontends/dib3000-common.c b/drivers/media/dvb/frontends/dib3000-common.c
new file mode 100644
index 000000000000..47ab02e133d1
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib3000-common.c
@@ -0,0 +1,83 @@
1#include "dib3000-common.h"
2
3#ifdef CONFIG_DVB_DIBCOM_DEBUG
4static int debug;
5module_param(debug, int, 0644);
6MODULE_PARM_DESC(debug, "set debugging level (1=info,2=i2c,4=srch (|-able)).");
7#endif
8#define deb_info(args...) dprintk(0x01,args)
9#define deb_i2c(args...) dprintk(0x02,args)
10#define deb_srch(args...) dprintk(0x04,args)
11
12
13int dib3000_read_reg(struct dib3000_state *state, u16 reg)
14{
15 u8 wb[] = { ((reg >> 8) | 0x80) & 0xff, reg & 0xff };
16 u8 rb[2];
17 struct i2c_msg msg[] = {
18 { .addr = state->config.demod_address, .flags = 0, .buf = wb, .len = 2 },
19 { .addr = state->config.demod_address, .flags = I2C_M_RD, .buf = rb, .len = 2 },
20 };
21
22 if (i2c_transfer(state->i2c, msg, 2) != 2)
23 deb_i2c("i2c read error\n");
24
25 deb_i2c("reading i2c bus (reg: %5d 0x%04x, val: %5d 0x%04x)\n",reg,reg,
26 (rb[0] << 8) | rb[1],(rb[0] << 8) | rb[1]);
27
28 return (rb[0] << 8) | rb[1];
29}
30
31int dib3000_write_reg(struct dib3000_state *state, u16 reg, u16 val)
32{
33 u8 b[] = {
34 (reg >> 8) & 0xff, reg & 0xff,
35 (val >> 8) & 0xff, val & 0xff,
36 };
37 struct i2c_msg msg[] = {
38 { .addr = state->config.demod_address, .flags = 0, .buf = b, .len = 4 }
39 };
40 deb_i2c("writing i2c bus (reg: %5d 0x%04x, val: %5d 0x%04x)\n",reg,reg,val,val);
41
42 return i2c_transfer(state->i2c,msg, 1) != 1 ? -EREMOTEIO : 0;
43}
44
45int dib3000_search_status(u16 irq,u16 lock)
46{
47 if (irq & 0x02) {
48 if (lock & 0x01) {
49 deb_srch("auto search succeeded\n");
50 return 1; // auto search succeeded
51 } else {
52 deb_srch("auto search not successful\n");
53 return 0; // auto search failed
54 }
55 } else if (irq & 0x01) {
56 deb_srch("auto search failed\n");
57 return 0; // auto search failed
58 }
59 return -1; // try again
60}
61
62/* for auto search */
63u16 dib3000_seq[2][2][2] = /* fft,gua, inv */
64 { /* fft */
65 { /* gua */
66 { 0, 1 }, /* 0 0 { 0,1 } */
67 { 3, 9 }, /* 0 1 { 0,1 } */
68 },
69 {
70 { 2, 5 }, /* 1 0 { 0,1 } */
71 { 6, 11 }, /* 1 1 { 0,1 } */
72 }
73 };
74
75MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de");
76MODULE_DESCRIPTION("Common functions for the dib3000mb/dib3000mc dvb-frontend drivers");
77MODULE_LICENSE("GPL");
78
79EXPORT_SYMBOL(dib3000_seq);
80
81EXPORT_SYMBOL(dib3000_read_reg);
82EXPORT_SYMBOL(dib3000_write_reg);
83EXPORT_SYMBOL(dib3000_search_status);
diff --git a/drivers/media/dvb/frontends/dib3000-common.h b/drivers/media/dvb/frontends/dib3000-common.h
new file mode 100644
index 000000000000..c31d6df15472
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib3000-common.h
@@ -0,0 +1,137 @@
1/*
2 * .h-files for the common use of the frontend drivers made by DiBcom
3 * DiBcom 3000M-B/C, 3000P
4 *
5 * DiBcom (http://www.dibcom.fr/)
6 *
7 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
8 *
9 * based on GPL code from DibCom, which has
10 *
11 * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License as
15 * published by the Free Software Foundation, version 2.
16 *
17 * Acknowledgements
18 *
19 * Amaury Demol (ademol@dibcom.fr) from DiBcom for providing specs and driver
20 * sources, on which this driver (and the dvb-dibusb) are based.
21 *
22 * see Documentation/dvb/README.dibusb for more information
23 *
24 */
25
26#ifndef DIB3000_COMMON_H
27#define DIB3000_COMMON_H
28
29#include "dvb_frontend.h"
30#include "dib3000.h"
31
32/* info and err, taken from usb.h, if there is anything available like by default. */
33#define err(format, arg...) printk(KERN_ERR "dib3000: " format "\n" , ## arg)
34#define info(format, arg...) printk(KERN_INFO "dib3000: " format "\n" , ## arg)
35#define warn(format, arg...) printk(KERN_WARNING "dib3000: " format "\n" , ## arg)
36
37/* frontend state */
38struct dib3000_state {
39 struct i2c_adapter* i2c;
40
41 struct dvb_frontend_ops ops;
42
43/* configuration settings */
44 struct dib3000_config config;
45
46 struct dvb_frontend frontend;
47 int timing_offset;
48 int timing_offset_comp_done;
49
50 fe_bandwidth_t last_tuned_bw;
51 u32 last_tuned_freq;
52};
53
54/* commonly used methods by the dib3000mb/mc/p frontend */
55extern int dib3000_read_reg(struct dib3000_state *state, u16 reg);
56extern int dib3000_write_reg(struct dib3000_state *state, u16 reg, u16 val);
57
58extern int dib3000_search_status(u16 irq,u16 lock);
59
60/* handy shortcuts */
61#define rd(reg) dib3000_read_reg(state,reg)
62
63#define wr(reg,val) if (dib3000_write_reg(state,reg,val)) \
64 { err("while sending 0x%04x to 0x%04x.",val,reg); return -EREMOTEIO; }
65
66#define wr_foreach(a,v) { int i; \
67 if (sizeof(a) != sizeof(v)) \
68 err("sizeof: %zu %zu is different",sizeof(a),sizeof(v));\
69 for (i=0; i < sizeof(a)/sizeof(u16); i++) \
70 wr(a[i],v[i]); \
71 }
72
73#define set_or(reg,val) wr(reg,rd(reg) | val)
74
75#define set_and(reg,val) wr(reg,rd(reg) & val)
76
77
78/* debug */
79
80#ifdef CONFIG_DVB_DIBCOM_DEBUG
81#define dprintk(level,args...) \
82 do { if ((debug & level)) { printk(args); } } while (0)
83#else
84#define dprintk(args...) do { } while (0)
85#endif
86
87/* mask for enabling a specific pid for the pid_filter */
88#define DIB3000_ACTIVATE_PID_FILTERING (0x2000)
89
90/* common values for tuning */
91#define DIB3000_ALPHA_0 ( 0)
92#define DIB3000_ALPHA_1 ( 1)
93#define DIB3000_ALPHA_2 ( 2)
94#define DIB3000_ALPHA_4 ( 4)
95
96#define DIB3000_CONSTELLATION_QPSK ( 0)
97#define DIB3000_CONSTELLATION_16QAM ( 1)
98#define DIB3000_CONSTELLATION_64QAM ( 2)
99
100#define DIB3000_GUARD_TIME_1_32 ( 0)
101#define DIB3000_GUARD_TIME_1_16 ( 1)
102#define DIB3000_GUARD_TIME_1_8 ( 2)
103#define DIB3000_GUARD_TIME_1_4 ( 3)
104
105#define DIB3000_TRANSMISSION_MODE_2K ( 0)
106#define DIB3000_TRANSMISSION_MODE_8K ( 1)
107
108#define DIB3000_SELECT_LP ( 0)
109#define DIB3000_SELECT_HP ( 1)
110
111#define DIB3000_FEC_1_2 ( 1)
112#define DIB3000_FEC_2_3 ( 2)
113#define DIB3000_FEC_3_4 ( 3)
114#define DIB3000_FEC_5_6 ( 5)
115#define DIB3000_FEC_7_8 ( 7)
116
117#define DIB3000_HRCH_OFF ( 0)
118#define DIB3000_HRCH_ON ( 1)
119
120#define DIB3000_DDS_INVERSION_OFF ( 0)
121#define DIB3000_DDS_INVERSION_ON ( 1)
122
123#define DIB3000_TUNER_WRITE_ENABLE(a) (0xffff & (a << 8))
124#define DIB3000_TUNER_WRITE_DISABLE(a) (0xffff & ((a << 8) | (1 << 7)))
125
126/* for auto search */
127extern u16 dib3000_seq[2][2][2];
128
129#define DIB3000_REG_MANUFACTOR_ID ( 1025)
130#define DIB3000_I2C_ID_DIBCOM (0x01b3)
131
132#define DIB3000_REG_DEVICE_ID ( 1026)
133#define DIB3000MB_DEVICE_ID (0x3000)
134#define DIB3000MC_DEVICE_ID (0x3001)
135#define DIB3000P_DEVICE_ID (0x3002)
136
137#endif // DIB3000_COMMON_H
diff --git a/drivers/media/dvb/frontends/dib3000.h b/drivers/media/dvb/frontends/dib3000.h
new file mode 100644
index 000000000000..80687c130836
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib3000.h
@@ -0,0 +1,54 @@
1/*
2 * public header file of the frontend drivers for mobile DVB-T demodulators
3 * DiBcom 3000M-B and DiBcom 3000P/M-C (http://www.dibcom.fr/)
4 *
5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
6 *
7 * based on GPL code from DibCom, which has
8 *
9 * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation, version 2.
14 *
15 * Acknowledgements
16 *
17 * Amaury Demol (ademol@dibcom.fr) from DiBcom for providing specs and driver
18 * sources, on which this driver (and the dvb-dibusb) are based.
19 *
20 * see Documentation/dvb/README.dibusb for more information
21 *
22 */
23
24#ifndef DIB3000_H
25#define DIB3000_H
26
27#include <linux/dvb/frontend.h>
28
29struct dib3000_config
30{
31 /* the demodulator's i2c address */
32 u8 demod_address;
33
34 /* PLL maintenance and the i2c address of the PLL */
35 u8 (*pll_addr)(struct dvb_frontend *fe);
36 int (*pll_init)(struct dvb_frontend *fe, u8 pll_buf[5]);
37 int (*pll_set)(struct dvb_frontend *fe, struct dvb_frontend_parameters* params, u8 pll_buf[5]);
38};
39
40struct dib_fe_xfer_ops
41{
42 /* pid and transfer handling is done in the demodulator */
43 int (*pid_parse)(struct dvb_frontend *fe, int onoff);
44 int (*fifo_ctrl)(struct dvb_frontend *fe, int onoff);
45 int (*pid_ctrl)(struct dvb_frontend *fe, int index, int pid, int onoff);
46 int (*tuner_pass_ctrl)(struct dvb_frontend *fe, int onoff, u8 pll_ctrl);
47};
48
49extern struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config,
50 struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops);
51
52extern struct dvb_frontend* dib3000mc_attach(const struct dib3000_config* config,
53 struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops);
54#endif // DIB3000_H
diff --git a/drivers/media/dvb/frontends/dib3000mb.c b/drivers/media/dvb/frontends/dib3000mb.c
new file mode 100644
index 000000000000..a853d12a26f1
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib3000mb.c
@@ -0,0 +1,784 @@
1/*
2 * Frontend driver for mobile DVB-T demodulator DiBcom 3000M-B
3 * DiBcom (http://www.dibcom.fr/)
4 *
5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
6 *
7 * based on GPL code from DibCom, which has
8 *
9 * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation, version 2.
14 *
15 * Acknowledgements
16 *
17 * Amaury Demol (ademol@dibcom.fr) from DiBcom for providing specs and driver
18 * sources, on which this driver (and the dvb-dibusb) are based.
19 *
20 * see Documentation/dvb/README.dibusb for more information
21 *
22 */
23
24#include <linux/config.h>
25#include <linux/kernel.h>
26#include <linux/version.h>
27#include <linux/module.h>
28#include <linux/moduleparam.h>
29#include <linux/init.h>
30#include <linux/delay.h>
31
32#include "dib3000-common.h"
33#include "dib3000mb_priv.h"
34#include "dib3000.h"
35
36/* Version information */
37#define DRIVER_VERSION "0.1"
38#define DRIVER_DESC "DiBcom 3000M-B DVB-T demodulator"
39#define DRIVER_AUTHOR "Patrick Boettcher, patrick.boettcher@desy.de"
40
41#ifdef CONFIG_DVB_DIBCOM_DEBUG
42static int debug;
43module_param(debug, int, 0644);
44MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=setfe,8=getfe (|-able)).");
45#endif
46#define deb_info(args...) dprintk(0x01,args)
47#define deb_xfer(args...) dprintk(0x02,args)
48#define deb_setf(args...) dprintk(0x04,args)
49#define deb_getf(args...) dprintk(0x08,args)
50
51static int dib3000mb_tuner_pass_ctrl(struct dvb_frontend *fe, int onoff, u8 pll_addr);
52
53static int dib3000mb_get_frontend(struct dvb_frontend* fe,
54 struct dvb_frontend_parameters *fep);
55
56static int dib3000mb_set_frontend(struct dvb_frontend* fe,
57 struct dvb_frontend_parameters *fep, int tuner)
58{
59 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
60 struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm;
61 fe_code_rate_t fe_cr = FEC_NONE;
62 int search_state, seq;
63
64 if (tuner) {
65 dib3000mb_tuner_pass_ctrl(fe,1,state->config.pll_addr(fe));
66 state->config.pll_set(fe, fep, NULL);
67 dib3000mb_tuner_pass_ctrl(fe,0,state->config.pll_addr(fe));
68
69 deb_setf("bandwidth: ");
70 switch (ofdm->bandwidth) {
71 case BANDWIDTH_8_MHZ:
72 deb_setf("8 MHz\n");
73 wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[2]);
74 wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_8mhz);
75 break;
76 case BANDWIDTH_7_MHZ:
77 deb_setf("7 MHz\n");
78 wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[1]);
79 wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_7mhz);
80 break;
81 case BANDWIDTH_6_MHZ:
82 deb_setf("6 MHz\n");
83 wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[0]);
84 wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_6mhz);
85 break;
86 case BANDWIDTH_AUTO:
87 return -EOPNOTSUPP;
88 default:
89 err("unkown bandwidth value.");
90 return -EINVAL;
91 }
92 }
93 wr(DIB3000MB_REG_LOCK1_MASK, DIB3000MB_LOCK1_SEARCH_4);
94
95 deb_setf("transmission mode: ");
96 switch (ofdm->transmission_mode) {
97 case TRANSMISSION_MODE_2K:
98 deb_setf("2k\n");
99 wr(DIB3000MB_REG_FFT, DIB3000_TRANSMISSION_MODE_2K);
100 break;
101 case TRANSMISSION_MODE_8K:
102 deb_setf("8k\n");
103 wr(DIB3000MB_REG_FFT, DIB3000_TRANSMISSION_MODE_8K);
104 break;
105 case TRANSMISSION_MODE_AUTO:
106 deb_setf("auto\n");
107 break;
108 default:
109 return -EINVAL;
110 }
111
112 deb_setf("guard: ");
113 switch (ofdm->guard_interval) {
114 case GUARD_INTERVAL_1_32:
115 deb_setf("1_32\n");
116 wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_32);
117 break;
118 case GUARD_INTERVAL_1_16:
119 deb_setf("1_16\n");
120 wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_16);
121 break;
122 case GUARD_INTERVAL_1_8:
123 deb_setf("1_8\n");
124 wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_8);
125 break;
126 case GUARD_INTERVAL_1_4:
127 deb_setf("1_4\n");
128 wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_4);
129 break;
130 case GUARD_INTERVAL_AUTO:
131 deb_setf("auto\n");
132 break;
133 default:
134 return -EINVAL;
135 }
136
137 deb_setf("inversion: ");
138 switch (fep->inversion) {
139 case INVERSION_OFF:
140 deb_setf("off\n");
141 wr(DIB3000MB_REG_DDS_INV, DIB3000_DDS_INVERSION_OFF);
142 break;
143 case INVERSION_AUTO:
144 deb_setf("auto ");
145 break;
146 case INVERSION_ON:
147 deb_setf("on\n");
148 wr(DIB3000MB_REG_DDS_INV, DIB3000_DDS_INVERSION_ON);
149 break;
150 default:
151 return -EINVAL;
152 }
153
154 deb_setf("constellation: ");
155 switch (ofdm->constellation) {
156 case QPSK:
157 deb_setf("qpsk\n");
158 wr(DIB3000MB_REG_QAM, DIB3000_CONSTELLATION_QPSK);
159 break;
160 case QAM_16:
161 deb_setf("qam16\n");
162 wr(DIB3000MB_REG_QAM, DIB3000_CONSTELLATION_16QAM);
163 break;
164 case QAM_64:
165 deb_setf("qam64\n");
166 wr(DIB3000MB_REG_QAM, DIB3000_CONSTELLATION_64QAM);
167 break;
168 case QAM_AUTO:
169 break;
170 default:
171 return -EINVAL;
172 }
173 deb_setf("hierachy: ");
174 switch (ofdm->hierarchy_information) {
175 case HIERARCHY_NONE:
176 deb_setf("none ");
177 /* fall through */
178 case HIERARCHY_1:
179 deb_setf("alpha=1\n");
180 wr(DIB3000MB_REG_VIT_ALPHA, DIB3000_ALPHA_1);
181 break;
182 case HIERARCHY_2:
183 deb_setf("alpha=2\n");
184 wr(DIB3000MB_REG_VIT_ALPHA, DIB3000_ALPHA_2);
185 break;
186 case HIERARCHY_4:
187 deb_setf("alpha=4\n");
188 wr(DIB3000MB_REG_VIT_ALPHA, DIB3000_ALPHA_4);
189 break;
190 case HIERARCHY_AUTO:
191 deb_setf("alpha=auto\n");
192 break;
193 default:
194 return -EINVAL;
195 }
196
197 deb_setf("hierarchy: ");
198 if (ofdm->hierarchy_information == HIERARCHY_NONE) {
199 deb_setf("none\n");
200 wr(DIB3000MB_REG_VIT_HRCH, DIB3000_HRCH_OFF);
201 wr(DIB3000MB_REG_VIT_HP, DIB3000_SELECT_HP);
202 fe_cr = ofdm->code_rate_HP;
203 } else if (ofdm->hierarchy_information != HIERARCHY_AUTO) {
204 deb_setf("on\n");
205 wr(DIB3000MB_REG_VIT_HRCH, DIB3000_HRCH_ON);
206 wr(DIB3000MB_REG_VIT_HP, DIB3000_SELECT_LP);
207 fe_cr = ofdm->code_rate_LP;
208 }
209 deb_setf("fec: ");
210 switch (fe_cr) {
211 case FEC_1_2:
212 deb_setf("1_2\n");
213 wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_1_2);
214 break;
215 case FEC_2_3:
216 deb_setf("2_3\n");
217 wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_2_3);
218 break;
219 case FEC_3_4:
220 deb_setf("3_4\n");
221 wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_3_4);
222 break;
223 case FEC_5_6:
224 deb_setf("5_6\n");
225 wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_5_6);
226 break;
227 case FEC_7_8:
228 deb_setf("7_8\n");
229 wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_7_8);
230 break;
231 case FEC_NONE:
232 deb_setf("none ");
233 break;
234 case FEC_AUTO:
235 deb_setf("auto\n");
236 break;
237 default:
238 return -EINVAL;
239 }
240
241 seq = dib3000_seq
242 [ofdm->transmission_mode == TRANSMISSION_MODE_AUTO]
243 [ofdm->guard_interval == GUARD_INTERVAL_AUTO]
244 [fep->inversion == INVERSION_AUTO];
245
246 deb_setf("seq? %d\n", seq);
247
248 wr(DIB3000MB_REG_SEQ, seq);
249
250 wr(DIB3000MB_REG_ISI, seq ? DIB3000MB_ISI_INHIBIT : DIB3000MB_ISI_ACTIVATE);
251
252 if (ofdm->transmission_mode == TRANSMISSION_MODE_2K) {
253 if (ofdm->guard_interval == GUARD_INTERVAL_1_8) {
254 wr(DIB3000MB_REG_SYNC_IMPROVEMENT, DIB3000MB_SYNC_IMPROVE_2K_1_8);
255 } else {
256 wr(DIB3000MB_REG_SYNC_IMPROVEMENT, DIB3000MB_SYNC_IMPROVE_DEFAULT);
257 }
258
259 wr(DIB3000MB_REG_UNK_121, DIB3000MB_UNK_121_2K);
260 } else {
261 wr(DIB3000MB_REG_UNK_121, DIB3000MB_UNK_121_DEFAULT);
262 }
263
264 wr(DIB3000MB_REG_MOBILE_ALGO, DIB3000MB_MOBILE_ALGO_OFF);
265 wr(DIB3000MB_REG_MOBILE_MODE_QAM, DIB3000MB_MOBILE_MODE_QAM_OFF);
266 wr(DIB3000MB_REG_MOBILE_MODE, DIB3000MB_MOBILE_MODE_OFF);
267
268 wr_foreach(dib3000mb_reg_agc_bandwidth, dib3000mb_agc_bandwidth_high);
269
270 wr(DIB3000MB_REG_ISI, DIB3000MB_ISI_ACTIVATE);
271
272 wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_AGC + DIB3000MB_RESTART_CTRL);
273 wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_OFF);
274
275 /* wait for AGC lock */
276 msleep(70);
277
278 wr_foreach(dib3000mb_reg_agc_bandwidth, dib3000mb_agc_bandwidth_low);
279
280 /* something has to be auto searched */
281 if (ofdm->constellation == QAM_AUTO ||
282 ofdm->hierarchy_information == HIERARCHY_AUTO ||
283 fe_cr == FEC_AUTO ||
284 fep->inversion == INVERSION_AUTO) {
285 int as_count=0;
286
287 deb_setf("autosearch enabled.\n");
288
289 wr(DIB3000MB_REG_ISI, DIB3000MB_ISI_INHIBIT);
290
291 wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_AUTO_SEARCH);
292 wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_OFF);
293
294 while ((search_state =
295 dib3000_search_status(
296 rd(DIB3000MB_REG_AS_IRQ_PENDING),
297 rd(DIB3000MB_REG_LOCK2_VALUE))) < 0 && as_count++ < 100)
298 msleep(1);
299
300 deb_setf("search_state after autosearch %d after %d checks\n",search_state,as_count);
301
302 if (search_state == 1) {
303 struct dvb_frontend_parameters feps;
304 if (dib3000mb_get_frontend(fe, &feps) == 0) {
305 deb_setf("reading tuning data from frontend succeeded.\n");
306 return dib3000mb_set_frontend(fe, &feps, 0);
307 }
308 }
309
310 } else {
311 wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_CTRL);
312 wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_OFF);
313 }
314
315 return 0;
316}
317
318static int dib3000mb_fe_init(struct dvb_frontend* fe, int mobile_mode)
319{
320 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
321
322 deb_info("dib3000mb is getting up.\n");
323 wr(DIB3000MB_REG_POWER_CONTROL, DIB3000MB_POWER_UP);
324
325 wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_AGC);
326
327 wr(DIB3000MB_REG_RESET_DEVICE, DIB3000MB_RESET_DEVICE);
328 wr(DIB3000MB_REG_RESET_DEVICE, DIB3000MB_RESET_DEVICE_RST);
329
330 wr(DIB3000MB_REG_CLOCK, DIB3000MB_CLOCK_DEFAULT);
331
332 wr(DIB3000MB_REG_ELECT_OUT_MODE, DIB3000MB_ELECT_OUT_MODE_ON);
333
334 wr(DIB3000MB_REG_DDS_FREQ_MSB, DIB3000MB_DDS_FREQ_MSB);
335 wr(DIB3000MB_REG_DDS_FREQ_LSB, DIB3000MB_DDS_FREQ_LSB);
336
337 wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[2]);
338
339 wr_foreach(dib3000mb_reg_impulse_noise,
340 dib3000mb_impulse_noise_values[DIB3000MB_IMPNOISE_OFF]);
341
342 wr_foreach(dib3000mb_reg_agc_gain, dib3000mb_default_agc_gain);
343
344 wr(DIB3000MB_REG_PHASE_NOISE, DIB3000MB_PHASE_NOISE_DEFAULT);
345
346 wr_foreach(dib3000mb_reg_phase_noise, dib3000mb_default_noise_phase);
347
348 wr_foreach(dib3000mb_reg_lock_duration, dib3000mb_default_lock_duration);
349
350 wr_foreach(dib3000mb_reg_agc_bandwidth, dib3000mb_agc_bandwidth_low);
351
352 wr(DIB3000MB_REG_LOCK0_MASK, DIB3000MB_LOCK0_DEFAULT);
353 wr(DIB3000MB_REG_LOCK1_MASK, DIB3000MB_LOCK1_SEARCH_4);
354 wr(DIB3000MB_REG_LOCK2_MASK, DIB3000MB_LOCK2_DEFAULT);
355 wr(DIB3000MB_REG_SEQ, dib3000_seq[1][1][1]);
356
357 wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_8mhz);
358
359 wr(DIB3000MB_REG_UNK_68, DIB3000MB_UNK_68);
360 wr(DIB3000MB_REG_UNK_69, DIB3000MB_UNK_69);
361 wr(DIB3000MB_REG_UNK_71, DIB3000MB_UNK_71);
362 wr(DIB3000MB_REG_UNK_77, DIB3000MB_UNK_77);
363 wr(DIB3000MB_REG_UNK_78, DIB3000MB_UNK_78);
364 wr(DIB3000MB_REG_ISI, DIB3000MB_ISI_INHIBIT);
365 wr(DIB3000MB_REG_UNK_92, DIB3000MB_UNK_92);
366 wr(DIB3000MB_REG_UNK_96, DIB3000MB_UNK_96);
367 wr(DIB3000MB_REG_UNK_97, DIB3000MB_UNK_97);
368 wr(DIB3000MB_REG_UNK_106, DIB3000MB_UNK_106);
369 wr(DIB3000MB_REG_UNK_107, DIB3000MB_UNK_107);
370 wr(DIB3000MB_REG_UNK_108, DIB3000MB_UNK_108);
371 wr(DIB3000MB_REG_UNK_122, DIB3000MB_UNK_122);
372 wr(DIB3000MB_REG_MOBILE_MODE_QAM, DIB3000MB_MOBILE_MODE_QAM_OFF);
373 wr(DIB3000MB_REG_BERLEN, DIB3000MB_BERLEN_DEFAULT);
374
375 wr_foreach(dib3000mb_reg_filter_coeffs, dib3000mb_filter_coeffs);
376
377 wr(DIB3000MB_REG_MOBILE_ALGO, DIB3000MB_MOBILE_ALGO_ON);
378 wr(DIB3000MB_REG_MULTI_DEMOD_MSB, DIB3000MB_MULTI_DEMOD_MSB);
379 wr(DIB3000MB_REG_MULTI_DEMOD_LSB, DIB3000MB_MULTI_DEMOD_LSB);
380
381 wr(DIB3000MB_REG_OUTPUT_MODE, DIB3000MB_OUTPUT_MODE_SLAVE);
382
383 wr(DIB3000MB_REG_FIFO_142, DIB3000MB_FIFO_142);
384 wr(DIB3000MB_REG_MPEG2_OUT_MODE, DIB3000MB_MPEG2_OUT_MODE_188);
385 wr(DIB3000MB_REG_PID_PARSE, DIB3000MB_PID_PARSE_ACTIVATE);
386 wr(DIB3000MB_REG_FIFO, DIB3000MB_FIFO_INHIBIT);
387 wr(DIB3000MB_REG_FIFO_146, DIB3000MB_FIFO_146);
388 wr(DIB3000MB_REG_FIFO_147, DIB3000MB_FIFO_147);
389
390 wr(DIB3000MB_REG_DATA_IN_DIVERSITY, DIB3000MB_DATA_DIVERSITY_IN_OFF);
391
392 if (state->config.pll_init) {
393 dib3000mb_tuner_pass_ctrl(fe,1,state->config.pll_addr(fe));
394 state->config.pll_init(fe,NULL);
395 dib3000mb_tuner_pass_ctrl(fe,0,state->config.pll_addr(fe));
396 }
397
398 return 0;
399}
400
401static int dib3000mb_get_frontend(struct dvb_frontend* fe,
402 struct dvb_frontend_parameters *fep)
403{
404 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
405 struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm;
406 fe_code_rate_t *cr;
407 u16 tps_val;
408 int inv_test1,inv_test2;
409 u32 dds_val, threshold = 0x800000;
410
411 if (!rd(DIB3000MB_REG_TPS_LOCK))
412 return 0;
413
414 dds_val = ((rd(DIB3000MB_REG_DDS_VALUE_MSB) & 0xff) << 16) + rd(DIB3000MB_REG_DDS_VALUE_LSB);
415 deb_getf("DDS_VAL: %x %x %x",dds_val, rd(DIB3000MB_REG_DDS_VALUE_MSB), rd(DIB3000MB_REG_DDS_VALUE_LSB));
416 if (dds_val < threshold)
417 inv_test1 = 0;
418 else if (dds_val == threshold)
419 inv_test1 = 1;
420 else
421 inv_test1 = 2;
422
423 dds_val = ((rd(DIB3000MB_REG_DDS_FREQ_MSB) & 0xff) << 16) + rd(DIB3000MB_REG_DDS_FREQ_LSB);
424 deb_getf("DDS_FREQ: %x %x %x",dds_val, rd(DIB3000MB_REG_DDS_FREQ_MSB), rd(DIB3000MB_REG_DDS_FREQ_LSB));
425 if (dds_val < threshold)
426 inv_test2 = 0;
427 else if (dds_val == threshold)
428 inv_test2 = 1;
429 else
430 inv_test2 = 2;
431
432 fep->inversion =
433 ((inv_test2 == 2) && (inv_test1==1 || inv_test1==0)) ||
434 ((inv_test2 == 0) && (inv_test1==1 || inv_test1==2)) ?
435 INVERSION_ON : INVERSION_OFF;
436
437 deb_getf("inversion %d %d, %d\n", inv_test2, inv_test1, fep->inversion);
438
439 switch ((tps_val = rd(DIB3000MB_REG_TPS_QAM))) {
440 case DIB3000_CONSTELLATION_QPSK:
441 deb_getf("QPSK ");
442 ofdm->constellation = QPSK;
443 break;
444 case DIB3000_CONSTELLATION_16QAM:
445 deb_getf("QAM16 ");
446 ofdm->constellation = QAM_16;
447 break;
448 case DIB3000_CONSTELLATION_64QAM:
449 deb_getf("QAM64 ");
450 ofdm->constellation = QAM_64;
451 break;
452 default:
453 err("Unexpected constellation returned by TPS (%d)", tps_val);
454 break;
455 }
456 deb_getf("TPS: %d\n", tps_val);
457
458 if (rd(DIB3000MB_REG_TPS_HRCH)) {
459 deb_getf("HRCH ON\n");
460 cr = &ofdm->code_rate_LP;
461 ofdm->code_rate_HP = FEC_NONE;
462 switch ((tps_val = rd(DIB3000MB_REG_TPS_VIT_ALPHA))) {
463 case DIB3000_ALPHA_0:
464 deb_getf("HIERARCHY_NONE ");
465 ofdm->hierarchy_information = HIERARCHY_NONE;
466 break;
467 case DIB3000_ALPHA_1:
468 deb_getf("HIERARCHY_1 ");
469 ofdm->hierarchy_information = HIERARCHY_1;
470 break;
471 case DIB3000_ALPHA_2:
472 deb_getf("HIERARCHY_2 ");
473 ofdm->hierarchy_information = HIERARCHY_2;
474 break;
475 case DIB3000_ALPHA_4:
476 deb_getf("HIERARCHY_4 ");
477 ofdm->hierarchy_information = HIERARCHY_4;
478 break;
479 default:
480 err("Unexpected ALPHA value returned by TPS (%d)", tps_val);
481 break;
482 }
483 deb_getf("TPS: %d\n", tps_val);
484
485 tps_val = rd(DIB3000MB_REG_TPS_CODE_RATE_LP);
486 } else {
487 deb_getf("HRCH OFF\n");
488 cr = &ofdm->code_rate_HP;
489 ofdm->code_rate_LP = FEC_NONE;
490 ofdm->hierarchy_information = HIERARCHY_NONE;
491
492 tps_val = rd(DIB3000MB_REG_TPS_CODE_RATE_HP);
493 }
494
495 switch (tps_val) {
496 case DIB3000_FEC_1_2:
497 deb_getf("FEC_1_2 ");
498 *cr = FEC_1_2;
499 break;
500 case DIB3000_FEC_2_3:
501 deb_getf("FEC_2_3 ");
502 *cr = FEC_2_3;
503 break;
504 case DIB3000_FEC_3_4:
505 deb_getf("FEC_3_4 ");
506 *cr = FEC_3_4;
507 break;
508 case DIB3000_FEC_5_6:
509 deb_getf("FEC_5_6 ");
510 *cr = FEC_4_5;
511 break;
512 case DIB3000_FEC_7_8:
513 deb_getf("FEC_7_8 ");
514 *cr = FEC_7_8;
515 break;
516 default:
517 err("Unexpected FEC returned by TPS (%d)", tps_val);
518 break;
519 }
520 deb_getf("TPS: %d\n",tps_val);
521
522 switch ((tps_val = rd(DIB3000MB_REG_TPS_GUARD_TIME))) {
523 case DIB3000_GUARD_TIME_1_32:
524 deb_getf("GUARD_INTERVAL_1_32 ");
525 ofdm->guard_interval = GUARD_INTERVAL_1_32;
526 break;
527 case DIB3000_GUARD_TIME_1_16:
528 deb_getf("GUARD_INTERVAL_1_16 ");
529 ofdm->guard_interval = GUARD_INTERVAL_1_16;
530 break;
531 case DIB3000_GUARD_TIME_1_8:
532 deb_getf("GUARD_INTERVAL_1_8 ");
533 ofdm->guard_interval = GUARD_INTERVAL_1_8;
534 break;
535 case DIB3000_GUARD_TIME_1_4:
536 deb_getf("GUARD_INTERVAL_1_4 ");
537 ofdm->guard_interval = GUARD_INTERVAL_1_4;
538 break;
539 default:
540 err("Unexpected Guard Time returned by TPS (%d)", tps_val);
541 break;
542 }
543 deb_getf("TPS: %d\n", tps_val);
544
545 switch ((tps_val = rd(DIB3000MB_REG_TPS_FFT))) {
546 case DIB3000_TRANSMISSION_MODE_2K:
547 deb_getf("TRANSMISSION_MODE_2K ");
548 ofdm->transmission_mode = TRANSMISSION_MODE_2K;
549 break;
550 case DIB3000_TRANSMISSION_MODE_8K:
551 deb_getf("TRANSMISSION_MODE_8K ");
552 ofdm->transmission_mode = TRANSMISSION_MODE_8K;
553 break;
554 default:
555 err("unexpected transmission mode return by TPS (%d)", tps_val);
556 break;
557 }
558 deb_getf("TPS: %d\n", tps_val);
559
560 return 0;
561}
562
563static int dib3000mb_read_status(struct dvb_frontend* fe, fe_status_t *stat)
564{
565 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
566
567 *stat = 0;
568
569 if (rd(DIB3000MB_REG_AGC_LOCK))
570 *stat |= FE_HAS_SIGNAL;
571 if (rd(DIB3000MB_REG_CARRIER_LOCK))
572 *stat |= FE_HAS_CARRIER;
573 if (rd(DIB3000MB_REG_VIT_LCK))
574 *stat |= FE_HAS_VITERBI;
575 if (rd(DIB3000MB_REG_TS_SYNC_LOCK))
576 *stat |= (FE_HAS_SYNC | FE_HAS_LOCK);
577
578 deb_getf("actual status is %2x\n",*stat);
579
580 deb_getf("autoval: tps: %d, qam: %d, hrch: %d, alpha: %d, hp: %d, lp: %d, guard: %d, fft: %d cell: %d\n",
581 rd(DIB3000MB_REG_TPS_LOCK),
582 rd(DIB3000MB_REG_TPS_QAM),
583 rd(DIB3000MB_REG_TPS_HRCH),
584 rd(DIB3000MB_REG_TPS_VIT_ALPHA),
585 rd(DIB3000MB_REG_TPS_CODE_RATE_HP),
586 rd(DIB3000MB_REG_TPS_CODE_RATE_LP),
587 rd(DIB3000MB_REG_TPS_GUARD_TIME),
588 rd(DIB3000MB_REG_TPS_FFT),
589 rd(DIB3000MB_REG_TPS_CELL_ID));
590
591 //*stat = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
592 return 0;
593}
594
595static int dib3000mb_read_ber(struct dvb_frontend* fe, u32 *ber)
596{
597 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
598
599 *ber = ((rd(DIB3000MB_REG_BER_MSB) << 16) | rd(DIB3000MB_REG_BER_LSB));
600 return 0;
601}
602
603/* see dib3000-watch dvb-apps for exact calcuations of signal_strength and snr */
604static int dib3000mb_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
605{
606 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
607
608 *strength = rd(DIB3000MB_REG_SIGNAL_POWER) * 0xffff / 0x170;
609 return 0;
610}
611
612static int dib3000mb_read_snr(struct dvb_frontend* fe, u16 *snr)
613{
614 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
615 short sigpow = rd(DIB3000MB_REG_SIGNAL_POWER);
616 int icipow = ((rd(DIB3000MB_REG_NOISE_POWER_MSB) & 0xff) << 16) |
617 rd(DIB3000MB_REG_NOISE_POWER_LSB);
618 *snr = (sigpow << 8) / ((icipow > 0) ? icipow : 1);
619 return 0;
620}
621
622static int dib3000mb_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
623{
624 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
625
626 *unc = rd(DIB3000MB_REG_UNC);
627 return 0;
628}
629
630static int dib3000mb_sleep(struct dvb_frontend* fe)
631{
632 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
633 deb_info("dib3000mb is going to bed.\n");
634 wr(DIB3000MB_REG_POWER_CONTROL, DIB3000MB_POWER_DOWN);
635 return 0;
636}
637
638static int dib3000mb_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
639{
640 tune->min_delay_ms = 800;
641 tune->step_size = 166667;
642 tune->max_drift = 166667 * 2;
643
644 return 0;
645}
646
647static int dib3000mb_fe_init_nonmobile(struct dvb_frontend* fe)
648{
649 return dib3000mb_fe_init(fe, 0);
650}
651
652static int dib3000mb_set_frontend_and_tuner(struct dvb_frontend* fe, struct dvb_frontend_parameters *fep)
653{
654 return dib3000mb_set_frontend(fe, fep, 1);
655}
656
657static void dib3000mb_release(struct dvb_frontend* fe)
658{
659 struct dib3000_state *state = (struct dib3000_state*) fe->demodulator_priv;
660 kfree(state);
661}
662
663/* pid filter and transfer stuff */
664static int dib3000mb_pid_control(struct dvb_frontend *fe,int index, int pid,int onoff)
665{
666 struct dib3000_state *state = fe->demodulator_priv;
667 pid = (onoff ? pid | DIB3000_ACTIVATE_PID_FILTERING : 0);
668 wr(index+DIB3000MB_REG_FIRST_PID,pid);
669 return 0;
670}
671
672static int dib3000mb_fifo_control(struct dvb_frontend *fe, int onoff)
673{
674 struct dib3000_state *state = (struct dib3000_state*) fe->demodulator_priv;
675
676 deb_xfer("%s fifo\n",onoff ? "enabling" : "disabling");
677 if (onoff) {
678 wr(DIB3000MB_REG_FIFO, DIB3000MB_FIFO_ACTIVATE);
679 } else {
680 wr(DIB3000MB_REG_FIFO, DIB3000MB_FIFO_INHIBIT);
681 }
682 return 0;
683}
684
685static int dib3000mb_pid_parse(struct dvb_frontend *fe, int onoff)
686{
687 struct dib3000_state *state = fe->demodulator_priv;
688 deb_xfer("%s pid parsing\n",onoff ? "enabling" : "disabling");
689 wr(DIB3000MB_REG_PID_PARSE,onoff);
690 return 0;
691}
692
693static int dib3000mb_tuner_pass_ctrl(struct dvb_frontend *fe, int onoff, u8 pll_addr)
694{
695 struct dib3000_state *state = (struct dib3000_state*) fe->demodulator_priv;
696 if (onoff) {
697 wr(DIB3000MB_REG_TUNER, DIB3000_TUNER_WRITE_ENABLE(pll_addr));
698 } else {
699 wr(DIB3000MB_REG_TUNER, DIB3000_TUNER_WRITE_DISABLE(pll_addr));
700 }
701 return 0;
702}
703
704static struct dvb_frontend_ops dib3000mb_ops;
705
706struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config,
707 struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops)
708{
709 struct dib3000_state* state = NULL;
710
711 /* allocate memory for the internal state */
712 state = (struct dib3000_state*) kmalloc(sizeof(struct dib3000_state), GFP_KERNEL);
713 if (state == NULL)
714 goto error;
715 memset(state,0,sizeof(struct dib3000_state));
716
717 /* setup the state */
718 state->i2c = i2c;
719 memcpy(&state->config,config,sizeof(struct dib3000_config));
720 memcpy(&state->ops, &dib3000mb_ops, sizeof(struct dvb_frontend_ops));
721
722 /* check for the correct demod */
723 if (rd(DIB3000_REG_MANUFACTOR_ID) != DIB3000_I2C_ID_DIBCOM)
724 goto error;
725
726 if (rd(DIB3000_REG_DEVICE_ID) != DIB3000MB_DEVICE_ID)
727 goto error;
728
729 /* create dvb_frontend */
730 state->frontend.ops = &state->ops;
731 state->frontend.demodulator_priv = state;
732
733 /* set the xfer operations */
734 xfer_ops->pid_parse = dib3000mb_pid_parse;
735 xfer_ops->fifo_ctrl = dib3000mb_fifo_control;
736 xfer_ops->pid_ctrl = dib3000mb_pid_control;
737 xfer_ops->tuner_pass_ctrl = dib3000mb_tuner_pass_ctrl;
738
739 return &state->frontend;
740
741error:
742 kfree(state);
743 return NULL;
744}
745
746static struct dvb_frontend_ops dib3000mb_ops = {
747
748 .info = {
749 .name = "DiBcom 3000M-B DVB-T",
750 .type = FE_OFDM,
751 .frequency_min = 44250000,
752 .frequency_max = 867250000,
753 .frequency_stepsize = 62500,
754 .caps = FE_CAN_INVERSION_AUTO |
755 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
756 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
757 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
758 FE_CAN_TRANSMISSION_MODE_AUTO |
759 FE_CAN_GUARD_INTERVAL_AUTO |
760 FE_CAN_RECOVER |
761 FE_CAN_HIERARCHY_AUTO,
762 },
763
764 .release = dib3000mb_release,
765
766 .init = dib3000mb_fe_init_nonmobile,
767 .sleep = dib3000mb_sleep,
768
769 .set_frontend = dib3000mb_set_frontend_and_tuner,
770 .get_frontend = dib3000mb_get_frontend,
771 .get_tune_settings = dib3000mb_fe_get_tune_settings,
772
773 .read_status = dib3000mb_read_status,
774 .read_ber = dib3000mb_read_ber,
775 .read_signal_strength = dib3000mb_read_signal_strength,
776 .read_snr = dib3000mb_read_snr,
777 .read_ucblocks = dib3000mb_read_unc_blocks,
778};
779
780MODULE_AUTHOR(DRIVER_AUTHOR);
781MODULE_DESCRIPTION(DRIVER_DESC);
782MODULE_LICENSE("GPL");
783
784EXPORT_SYMBOL(dib3000mb_attach);
diff --git a/drivers/media/dvb/frontends/dib3000mb_priv.h b/drivers/media/dvb/frontends/dib3000mb_priv.h
new file mode 100644
index 000000000000..57e61aa5b07b
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib3000mb_priv.h
@@ -0,0 +1,467 @@
1/*
2 * dib3000mb_priv.h
3 *
4 * Copyright (C) 2004 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 *
10 * for more information see dib3000mb.c .
11 */
12
13#ifndef __DIB3000MB_PRIV_H_INCLUDED__
14#define __DIB3000MB_PRIV_H_INCLUDED__
15
16/* register addresses and some of their default values */
17
18/* restart subsystems */
19#define DIB3000MB_REG_RESTART ( 0)
20
21#define DIB3000MB_RESTART_OFF ( 0)
22#define DIB3000MB_RESTART_AUTO_SEARCH (1 << 1)
23#define DIB3000MB_RESTART_CTRL (1 << 2)
24#define DIB3000MB_RESTART_AGC (1 << 3)
25
26/* FFT size */
27#define DIB3000MB_REG_FFT ( 1)
28
29/* Guard time */
30#define DIB3000MB_REG_GUARD_TIME ( 2)
31
32/* QAM */
33#define DIB3000MB_REG_QAM ( 3)
34
35/* Alpha coefficient high priority Viterbi algorithm */
36#define DIB3000MB_REG_VIT_ALPHA ( 4)
37
38/* spectrum inversion */
39#define DIB3000MB_REG_DDS_INV ( 5)
40
41/* DDS frequency value (IF position) ad ? values don't match reg_3000mb.txt */
42#define DIB3000MB_REG_DDS_FREQ_MSB ( 6)
43#define DIB3000MB_REG_DDS_FREQ_LSB ( 7)
44#define DIB3000MB_DDS_FREQ_MSB ( 178)
45#define DIB3000MB_DDS_FREQ_LSB ( 8990)
46
47/* timing frequency (carrier spacing) */
48static u16 dib3000mb_reg_timing_freq[] = { 8,9 };
49static u16 dib3000mb_timing_freq[][2] = {
50 { 126 , 48873 }, /* 6 MHz */
51 { 147 , 57019 }, /* 7 MHz */
52 { 168 , 65164 }, /* 8 MHz */
53};
54
55/* impulse noise parameter */
56/* 36 ??? */
57
58static u16 dib3000mb_reg_impulse_noise[] = { 10,11,12,15,36 };
59
60enum dib3000mb_impulse_noise_type {
61 DIB3000MB_IMPNOISE_OFF,
62 DIB3000MB_IMPNOISE_MOBILE,
63 DIB3000MB_IMPNOISE_FIXED,
64 DIB3000MB_IMPNOISE_DEFAULT
65};
66
67static u16 dib3000mb_impulse_noise_values[][5] = {
68 { 0x0000, 0x0004, 0x0014, 0x01ff, 0x0399 }, /* off */
69 { 0x0001, 0x0004, 0x0014, 0x01ff, 0x037b }, /* mobile */
70 { 0x0001, 0x0004, 0x0020, 0x01bd, 0x0399 }, /* fixed */
71 { 0x0000, 0x0002, 0x000a, 0x01ff, 0x0399 }, /* default */
72};
73
74/*
75 * Dual Automatic-Gain-Control
76 * - gains RF in tuner (AGC1)
77 * - gains IF after filtering (AGC2)
78 */
79
80/* also from 16 to 18 */
81static u16 dib3000mb_reg_agc_gain[] = {
82 19,20,21,22,23,24,25,26,27,28,29,30,31,32
83};
84
85static u16 dib3000mb_default_agc_gain[] =
86 { 0x0001, 52429, 623, 128, 166, 195, 61, /* RF ??? */
87 0x0001, 53766, 38011, 0, 90, 33, 23 }; /* IF ??? */
88
89/* phase noise */
90/* 36 is set when setting the impulse noise */
91static u16 dib3000mb_reg_phase_noise[] = { 33,34,35,37,38 };
92
93static u16 dib3000mb_default_noise_phase[] = { 2, 544, 0, 5, 4 };
94
95/* lock duration */
96static u16 dib3000mb_reg_lock_duration[] = { 39,40 };
97static u16 dib3000mb_default_lock_duration[] = { 135, 135 };
98
99/* AGC loop bandwidth */
100static u16 dib3000mb_reg_agc_bandwidth[] = { 43,44,45,46,47,48,49,50 };
101
102static u16 dib3000mb_agc_bandwidth_low[] =
103 { 2088, 10, 2088, 10, 3448, 5, 3448, 5 };
104static u16 dib3000mb_agc_bandwidth_high[] =
105 { 2349, 5, 2349, 5, 2586, 2, 2586, 2 };
106
107/*
108 * lock0 definition (coff_lock)
109 */
110#define DIB3000MB_REG_LOCK0_MASK ( 51)
111#define DIB3000MB_LOCK0_DEFAULT ( 4)
112
113/*
114 * lock1 definition (cpil_lock)
115 * for auto search
116 * which values hide behind the lock masks
117 */
118#define DIB3000MB_REG_LOCK1_MASK ( 52)
119#define DIB3000MB_LOCK1_SEARCH_4 (0x0004)
120#define DIB3000MB_LOCK1_SEARCH_2048 (0x0800)
121#define DIB3000MB_LOCK1_DEFAULT (0x0001)
122
123/*
124 * lock2 definition (fec_lock) */
125#define DIB3000MB_REG_LOCK2_MASK ( 53)
126#define DIB3000MB_LOCK2_DEFAULT (0x0080)
127
128/*
129 * SEQ ? what was that again ... :)
130 * changes when, inversion, guard time and fft is
131 * either automatically detected or not
132 */
133#define DIB3000MB_REG_SEQ ( 54)
134
135/* bandwidth */
136static u16 dib3000mb_reg_bandwidth[] = { 55,56,57,58,59,60,61,62,63,64,65,66,67 };
137static u16 dib3000mb_bandwidth_6mhz[] =
138 { 0, 33, 53312, 112, 46635, 563, 36565, 0, 1000, 0, 1010, 1, 45264 };
139
140static u16 dib3000mb_bandwidth_7mhz[] =
141 { 0, 28, 64421, 96, 39973, 483, 3255, 0, 1000, 0, 1010, 1, 45264 };
142
143static u16 dib3000mb_bandwidth_8mhz[] =
144 { 0, 25, 23600, 84, 34976, 422, 43808, 0, 1000, 0, 1010, 1, 45264 };
145
146#define DIB3000MB_REG_UNK_68 ( 68)
147#define DIB3000MB_UNK_68 ( 0)
148
149#define DIB3000MB_REG_UNK_69 ( 69)
150#define DIB3000MB_UNK_69 ( 0)
151
152#define DIB3000MB_REG_UNK_71 ( 71)
153#define DIB3000MB_UNK_71 ( 0)
154
155#define DIB3000MB_REG_UNK_77 ( 77)
156#define DIB3000MB_UNK_77 ( 6)
157
158#define DIB3000MB_REG_UNK_78 ( 78)
159#define DIB3000MB_UNK_78 (0x0080)
160
161/* isi */
162#define DIB3000MB_REG_ISI ( 79)
163#define DIB3000MB_ISI_ACTIVATE ( 0)
164#define DIB3000MB_ISI_INHIBIT ( 1)
165
166/* sync impovement */
167#define DIB3000MB_REG_SYNC_IMPROVEMENT ( 84)
168#define DIB3000MB_SYNC_IMPROVE_2K_1_8 ( 3)
169#define DIB3000MB_SYNC_IMPROVE_DEFAULT ( 0)
170
171/* phase noise compensation inhibition */
172#define DIB3000MB_REG_PHASE_NOISE ( 87)
173#define DIB3000MB_PHASE_NOISE_DEFAULT ( 0)
174
175#define DIB3000MB_REG_UNK_92 ( 92)
176#define DIB3000MB_UNK_92 (0x0080)
177
178#define DIB3000MB_REG_UNK_96 ( 96)
179#define DIB3000MB_UNK_96 (0x0010)
180
181#define DIB3000MB_REG_UNK_97 ( 97)
182#define DIB3000MB_UNK_97 (0x0009)
183
184/* mobile mode ??? */
185#define DIB3000MB_REG_MOBILE_MODE ( 101)
186#define DIB3000MB_MOBILE_MODE_ON ( 1)
187#define DIB3000MB_MOBILE_MODE_OFF ( 0)
188
189#define DIB3000MB_REG_UNK_106 ( 106)
190#define DIB3000MB_UNK_106 (0x0080)
191
192#define DIB3000MB_REG_UNK_107 ( 107)
193#define DIB3000MB_UNK_107 (0x0080)
194
195#define DIB3000MB_REG_UNK_108 ( 108)
196#define DIB3000MB_UNK_108 (0x0080)
197
198/* fft */
199#define DIB3000MB_REG_UNK_121 ( 121)
200#define DIB3000MB_UNK_121_2K ( 7)
201#define DIB3000MB_UNK_121_DEFAULT ( 5)
202
203#define DIB3000MB_REG_UNK_122 ( 122)
204#define DIB3000MB_UNK_122 ( 2867)
205
206/* QAM for mobile mode */
207#define DIB3000MB_REG_MOBILE_MODE_QAM ( 126)
208#define DIB3000MB_MOBILE_MODE_QAM_64 ( 3)
209#define DIB3000MB_MOBILE_MODE_QAM_QPSK_16 ( 1)
210#define DIB3000MB_MOBILE_MODE_QAM_OFF ( 0)
211
212/*
213 * data diversity when having more than one chip on-board
214 * see also DIB3000MB_OUTPUT_MODE_DATA_DIVERSITY
215 */
216#define DIB3000MB_REG_DATA_IN_DIVERSITY ( 127)
217#define DIB3000MB_DATA_DIVERSITY_IN_OFF ( 0)
218#define DIB3000MB_DATA_DIVERSITY_IN_ON ( 2)
219
220/* vit hrch */
221#define DIB3000MB_REG_VIT_HRCH ( 128)
222
223/* vit code rate */
224#define DIB3000MB_REG_VIT_CODE_RATE ( 129)
225
226/* vit select hp */
227#define DIB3000MB_REG_VIT_HP ( 130)
228
229/* time frame for Bit-Error-Rate calculation */
230#define DIB3000MB_REG_BERLEN ( 135)
231#define DIB3000MB_BERLEN_LONG ( 0)
232#define DIB3000MB_BERLEN_DEFAULT ( 1)
233#define DIB3000MB_BERLEN_MEDIUM ( 2)
234#define DIB3000MB_BERLEN_SHORT ( 3)
235
236/* 142 - 152 FIFO parameters
237 * which is what ?
238 */
239
240#define DIB3000MB_REG_FIFO_142 ( 142)
241#define DIB3000MB_FIFO_142 ( 0)
242
243/* MPEG2 TS output mode */
244#define DIB3000MB_REG_MPEG2_OUT_MODE ( 143)
245#define DIB3000MB_MPEG2_OUT_MODE_204 ( 0)
246#define DIB3000MB_MPEG2_OUT_MODE_188 ( 1)
247
248#define DIB3000MB_REG_PID_PARSE ( 144)
249#define DIB3000MB_PID_PARSE_INHIBIT ( 0)
250#define DIB3000MB_PID_PARSE_ACTIVATE ( 1)
251
252#define DIB3000MB_REG_FIFO ( 145)
253#define DIB3000MB_FIFO_INHIBIT ( 1)
254#define DIB3000MB_FIFO_ACTIVATE ( 0)
255
256#define DIB3000MB_REG_FIFO_146 ( 146)
257#define DIB3000MB_FIFO_146 ( 3)
258
259#define DIB3000MB_REG_FIFO_147 ( 147)
260#define DIB3000MB_FIFO_147 (0x0100)
261
262/*
263 * pidfilter
264 * it is not a hardware pidfilter but a filter which drops all pids
265 * except the ones set. Necessary because of the limited USB1.1 bandwidth.
266 * regs 153-168
267 */
268
269#define DIB3000MB_REG_FIRST_PID ( 153)
270#define DIB3000MB_NUM_PIDS ( 16)
271
272/*
273 * output mode
274 * USB devices have to use 'slave'-mode
275 * see also DIB3000MB_REG_ELECT_OUT_MODE
276 */
277#define DIB3000MB_REG_OUTPUT_MODE ( 169)
278#define DIB3000MB_OUTPUT_MODE_GATED_CLK ( 0)
279#define DIB3000MB_OUTPUT_MODE_CONT_CLK ( 1)
280#define DIB3000MB_OUTPUT_MODE_SERIAL ( 2)
281#define DIB3000MB_OUTPUT_MODE_DATA_DIVERSITY ( 5)
282#define DIB3000MB_OUTPUT_MODE_SLAVE ( 6)
283
284/* irq event mask */
285#define DIB3000MB_REG_IRQ_EVENT_MASK ( 170)
286#define DIB3000MB_IRQ_EVENT_MASK ( 0)
287
288/* filter coefficients */
289static u16 dib3000mb_reg_filter_coeffs[] = {
290 171, 172, 173, 174, 175, 176, 177, 178,
291 179, 180, 181, 182, 183, 184, 185, 186,
292 188, 189, 190, 191, 192, 194
293};
294
295static u16 dib3000mb_filter_coeffs[] = {
296 226, 160, 29,
297 979, 998, 19,
298 22, 1019, 1006,
299 1022, 12, 6,
300 1017, 1017, 3,
301 6, 1019,
302 1021, 2, 3,
303 1, 0,
304};
305
306/*
307 * mobile algorithm (when you are moving with your device)
308 * but not faster than 90 km/h
309 */
310#define DIB3000MB_REG_MOBILE_ALGO ( 195)
311#define DIB3000MB_MOBILE_ALGO_ON ( 0)
312#define DIB3000MB_MOBILE_ALGO_OFF ( 1)
313
314/* multiple demodulators algorithm */
315#define DIB3000MB_REG_MULTI_DEMOD_MSB ( 206)
316#define DIB3000MB_REG_MULTI_DEMOD_LSB ( 207)
317
318/* terminator, no more demods */
319#define DIB3000MB_MULTI_DEMOD_MSB ( 32767)
320#define DIB3000MB_MULTI_DEMOD_LSB ( 4095)
321
322/* bring the device into a known */
323#define DIB3000MB_REG_RESET_DEVICE ( 1024)
324#define DIB3000MB_RESET_DEVICE (0x812c)
325#define DIB3000MB_RESET_DEVICE_RST ( 0)
326
327/* hardware clock configuration */
328#define DIB3000MB_REG_CLOCK ( 1027)
329#define DIB3000MB_CLOCK_DEFAULT (0x9000)
330#define DIB3000MB_CLOCK_DIVERSITY (0x92b0)
331
332/* power down config */
333#define DIB3000MB_REG_POWER_CONTROL ( 1028)
334#define DIB3000MB_POWER_DOWN ( 1)
335#define DIB3000MB_POWER_UP ( 0)
336
337/* electrical output mode */
338#define DIB3000MB_REG_ELECT_OUT_MODE ( 1029)
339#define DIB3000MB_ELECT_OUT_MODE_OFF ( 0)
340#define DIB3000MB_ELECT_OUT_MODE_ON ( 1)
341
342/* set the tuner i2c address */
343#define DIB3000MB_REG_TUNER ( 1089)
344
345/* monitoring registers (read only) */
346
347/* agc loop locked (size: 1) */
348#define DIB3000MB_REG_AGC_LOCK ( 324)
349
350/* agc power (size: 16) */
351#define DIB3000MB_REG_AGC_POWER ( 325)
352
353/* agc1 value (16) */
354#define DIB3000MB_REG_AGC1_VALUE ( 326)
355
356/* agc2 value (16) */
357#define DIB3000MB_REG_AGC2_VALUE ( 327)
358
359/* total RF power (16), can be used for signal strength */
360#define DIB3000MB_REG_RF_POWER ( 328)
361
362/* dds_frequency with offset (24) */
363#define DIB3000MB_REG_DDS_VALUE_MSB ( 339)
364#define DIB3000MB_REG_DDS_VALUE_LSB ( 340)
365
366/* timing offset signed (24) */
367#define DIB3000MB_REG_TIMING_OFFSET_MSB ( 341)
368#define DIB3000MB_REG_TIMING_OFFSET_LSB ( 342)
369
370/* fft start position (13) */
371#define DIB3000MB_REG_FFT_WINDOW_POS ( 353)
372
373/* carriers locked (1) */
374#define DIB3000MB_REG_CARRIER_LOCK ( 355)
375
376/* noise power (24) */
377#define DIB3000MB_REG_NOISE_POWER_MSB ( 372)
378#define DIB3000MB_REG_NOISE_POWER_LSB ( 373)
379
380#define DIB3000MB_REG_MOBILE_NOISE_MSB ( 374)
381#define DIB3000MB_REG_MOBILE_NOISE_LSB ( 375)
382
383/*
384 * signal power (16), this and the above can be
385 * used to calculate the signal/noise - ratio
386 */
387#define DIB3000MB_REG_SIGNAL_POWER ( 380)
388
389/* mer (24) */
390#define DIB3000MB_REG_MER_MSB ( 381)
391#define DIB3000MB_REG_MER_LSB ( 382)
392
393/*
394 * Transmission Parameter Signalling (TPS)
395 * the following registers can be used to get TPS-information.
396 * The values are according to the DVB-T standard.
397 */
398
399/* TPS locked (1) */
400#define DIB3000MB_REG_TPS_LOCK ( 394)
401
402/* QAM from TPS (2) (values according to DIB3000MB_REG_QAM) */
403#define DIB3000MB_REG_TPS_QAM ( 398)
404
405/* hierarchy from TPS (1) */
406#define DIB3000MB_REG_TPS_HRCH ( 399)
407
408/* alpha from TPS (3) (values according to DIB3000MB_REG_VIT_ALPHA) */
409#define DIB3000MB_REG_TPS_VIT_ALPHA ( 400)
410
411/* code rate high priority from TPS (3) (values according to DIB3000MB_FEC_*) */
412#define DIB3000MB_REG_TPS_CODE_RATE_HP ( 401)
413
414/* code rate low priority from TPS (3) if DIB3000MB_REG_TPS_VIT_ALPHA */
415#define DIB3000MB_REG_TPS_CODE_RATE_LP ( 402)
416
417/* guard time from TPS (2) (values according to DIB3000MB_REG_GUARD_TIME */
418#define DIB3000MB_REG_TPS_GUARD_TIME ( 403)
419
420/* fft size from TPS (2) (values according to DIB3000MB_REG_FFT) */
421#define DIB3000MB_REG_TPS_FFT ( 404)
422
423/* cell id from TPS (16) */
424#define DIB3000MB_REG_TPS_CELL_ID ( 406)
425
426/* TPS (68) */
427#define DIB3000MB_REG_TPS_1 ( 408)
428#define DIB3000MB_REG_TPS_2 ( 409)
429#define DIB3000MB_REG_TPS_3 ( 410)
430#define DIB3000MB_REG_TPS_4 ( 411)
431#define DIB3000MB_REG_TPS_5 ( 412)
432
433/* bit error rate (before RS correction) (21) */
434#define DIB3000MB_REG_BER_MSB ( 414)
435#define DIB3000MB_REG_BER_LSB ( 415)
436
437/* packet error rate (uncorrected TS packets) (16) */
438#define DIB3000MB_REG_PACKET_ERROR_RATE ( 417)
439
440/* uncorrected packet count (16) */
441#define DIB3000MB_REG_UNC ( 420)
442
443/* viterbi locked (1) */
444#define DIB3000MB_REG_VIT_LCK ( 421)
445
446/* viterbi inidcator (16) */
447#define DIB3000MB_REG_VIT_INDICATOR ( 422)
448
449/* transport stream sync lock (1) */
450#define DIB3000MB_REG_TS_SYNC_LOCK ( 423)
451
452/* transport stream RS lock (1) */
453#define DIB3000MB_REG_TS_RS_LOCK ( 424)
454
455/* lock mask 0 value (1) */
456#define DIB3000MB_REG_LOCK0_VALUE ( 425)
457
458/* lock mask 1 value (1) */
459#define DIB3000MB_REG_LOCK1_VALUE ( 426)
460
461/* lock mask 2 value (1) */
462#define DIB3000MB_REG_LOCK2_VALUE ( 427)
463
464/* interrupt pending for auto search */
465#define DIB3000MB_REG_AS_IRQ_PENDING ( 434)
466
467#endif
diff --git a/drivers/media/dvb/frontends/dib3000mc.c b/drivers/media/dvb/frontends/dib3000mc.c
new file mode 100644
index 000000000000..4a31c05eaecd
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib3000mc.c
@@ -0,0 +1,931 @@
1/*
2 * Frontend driver for mobile DVB-T demodulator DiBcom 3000P/M-C
3 * DiBcom (http://www.dibcom.fr/)
4 *
5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
6 *
7 * based on GPL code from DiBCom, which has
8 *
9 * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation, version 2.
14 *
15 * Acknowledgements
16 *
17 * Amaury Demol (ademol@dibcom.fr) from DiBcom for providing specs and driver
18 * sources, on which this driver (and the dvb-dibusb) are based.
19 *
20 * see Documentation/dvb/README.dibusb for more information
21 *
22 */
23#include <linux/config.h>
24#include <linux/kernel.h>
25#include <linux/version.h>
26#include <linux/module.h>
27#include <linux/moduleparam.h>
28#include <linux/init.h>
29#include <linux/delay.h>
30
31#include "dib3000-common.h"
32#include "dib3000mc_priv.h"
33#include "dib3000.h"
34
35/* Version information */
36#define DRIVER_VERSION "0.1"
37#define DRIVER_DESC "DiBcom 3000M-C DVB-T demodulator"
38#define DRIVER_AUTHOR "Patrick Boettcher, patrick.boettcher@desy.de"
39
40#ifdef CONFIG_DVB_DIBCOM_DEBUG
41static int debug;
42module_param(debug, int, 0644);
43MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=setfe,8=getfe,16=stat (|-able)).");
44#endif
45#define deb_info(args...) dprintk(0x01,args)
46#define deb_xfer(args...) dprintk(0x02,args)
47#define deb_setf(args...) dprintk(0x04,args)
48#define deb_getf(args...) dprintk(0x08,args)
49#define deb_stat(args...) dprintk(0x10,args)
50
51static int dib3000mc_tuner_pass_ctrl(struct dvb_frontend *fe, int onoff, u8 pll_addr);
52
53static int dib3000mc_set_impulse_noise(struct dib3000_state * state, int mode,
54 fe_transmit_mode_t transmission_mode, fe_bandwidth_t bandwidth)
55{
56 switch (transmission_mode) {
57 case TRANSMISSION_MODE_2K:
58 wr_foreach(dib3000mc_reg_fft,dib3000mc_fft_modes[0]);
59 break;
60 case TRANSMISSION_MODE_8K:
61 wr_foreach(dib3000mc_reg_fft,dib3000mc_fft_modes[1]);
62 break;
63 default:
64 break;
65 }
66
67 switch (bandwidth) {
68/* case BANDWIDTH_5_MHZ:
69 wr_foreach(dib3000mc_reg_impulse_noise,dib3000mc_impluse_noise[0]);
70 break; */
71 case BANDWIDTH_6_MHZ:
72 wr_foreach(dib3000mc_reg_impulse_noise,dib3000mc_impluse_noise[1]);
73 break;
74 case BANDWIDTH_7_MHZ:
75 wr_foreach(dib3000mc_reg_impulse_noise,dib3000mc_impluse_noise[2]);
76 break;
77 case BANDWIDTH_8_MHZ:
78 wr_foreach(dib3000mc_reg_impulse_noise,dib3000mc_impluse_noise[3]);
79 break;
80 default:
81 break;
82 }
83
84 switch (mode) {
85 case 0: /* no impulse */ /* fall through */
86 wr_foreach(dib3000mc_reg_imp_noise_ctl,dib3000mc_imp_noise_ctl[0]);
87 break;
88 case 1: /* new algo */
89 wr_foreach(dib3000mc_reg_imp_noise_ctl,dib3000mc_imp_noise_ctl[1]);
90 set_or(DIB3000MC_REG_IMP_NOISE_55,DIB3000MC_IMP_NEW_ALGO(0)); /* gives 1<<10 */
91 break;
92 default: /* old algo */
93 wr_foreach(dib3000mc_reg_imp_noise_ctl,dib3000mc_imp_noise_ctl[3]);
94 break;
95 }
96 return 0;
97}
98
99static int dib3000mc_set_timing(struct dib3000_state *state, int upd_offset,
100 fe_transmit_mode_t fft, fe_bandwidth_t bw)
101{
102 u16 timf_msb,timf_lsb;
103 s32 tim_offset,tim_sgn;
104 u64 comp1,comp2,comp=0;
105
106 switch (bw) {
107 case BANDWIDTH_8_MHZ: comp = DIB3000MC_CLOCK_REF*8; break;
108 case BANDWIDTH_7_MHZ: comp = DIB3000MC_CLOCK_REF*7; break;
109 case BANDWIDTH_6_MHZ: comp = DIB3000MC_CLOCK_REF*6; break;
110 default: err("unknown bandwidth (%d)",bw); break;
111 }
112 timf_msb = (comp >> 16) & 0xff;
113 timf_lsb = (comp & 0xffff);
114
115 // Update the timing offset ;
116 if (upd_offset > 0) {
117 if (!state->timing_offset_comp_done) {
118 msleep(200);
119 state->timing_offset_comp_done = 1;
120 }
121 tim_offset = rd(DIB3000MC_REG_TIMING_OFFS_MSB);
122 if ((tim_offset & 0x2000) == 0x2000)
123 tim_offset |= 0xC000;
124 if (fft == TRANSMISSION_MODE_2K)
125 tim_offset <<= 2;
126 state->timing_offset += tim_offset;
127 }
128
129 tim_offset = state->timing_offset;
130 if (tim_offset < 0) {
131 tim_sgn = 1;
132 tim_offset = -tim_offset;
133 } else
134 tim_sgn = 0;
135
136 comp1 = (u32)tim_offset * (u32)timf_lsb ;
137 comp2 = (u32)tim_offset * (u32)timf_msb ;
138 comp = ((comp1 >> 16) + comp2) >> 7;
139
140 if (tim_sgn == 0)
141 comp = (u32)(timf_msb << 16) + (u32) timf_lsb + comp;
142 else
143 comp = (u32)(timf_msb << 16) + (u32) timf_lsb - comp ;
144
145 timf_msb = (comp >> 16) & 0xff;
146 timf_lsb = comp & 0xffff;
147
148 wr(DIB3000MC_REG_TIMING_FREQ_MSB,timf_msb);
149 wr(DIB3000MC_REG_TIMING_FREQ_LSB,timf_lsb);
150 return 0;
151}
152
153static int dib3000mc_init_auto_scan(struct dib3000_state *state, fe_bandwidth_t bw, int boost)
154{
155 if (boost) {
156 wr(DIB3000MC_REG_SCAN_BOOST,DIB3000MC_SCAN_BOOST_ON);
157 } else {
158 wr(DIB3000MC_REG_SCAN_BOOST,DIB3000MC_SCAN_BOOST_OFF);
159 }
160 switch (bw) {
161 case BANDWIDTH_8_MHZ:
162 wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_8mhz);
163 break;
164 case BANDWIDTH_7_MHZ:
165 wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_7mhz);
166 break;
167 case BANDWIDTH_6_MHZ:
168 wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_6mhz);
169 break;
170/* case BANDWIDTH_5_MHZ:
171 wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_5mhz);
172 break;*/
173 case BANDWIDTH_AUTO:
174 return -EOPNOTSUPP;
175 default:
176 err("unknown bandwidth value (%d).",bw);
177 return -EINVAL;
178 }
179 if (boost) {
180 u32 timeout = (rd(DIB3000MC_REG_BW_TIMOUT_MSB) << 16) +
181 rd(DIB3000MC_REG_BW_TIMOUT_LSB);
182 timeout *= 85; timeout >>= 7;
183 wr(DIB3000MC_REG_BW_TIMOUT_MSB,(timeout >> 16) & 0xffff);
184 wr(DIB3000MC_REG_BW_TIMOUT_LSB,timeout & 0xffff);
185 }
186 return 0;
187}
188
189static int dib3000mc_set_adp_cfg(struct dib3000_state *state, fe_modulation_t con)
190{
191 switch (con) {
192 case QAM_64:
193 wr_foreach(dib3000mc_reg_adp_cfg,dib3000mc_adp_cfg[2]);
194 break;
195 case QAM_16:
196 wr_foreach(dib3000mc_reg_adp_cfg,dib3000mc_adp_cfg[1]);
197 break;
198 case QPSK:
199 wr_foreach(dib3000mc_reg_adp_cfg,dib3000mc_adp_cfg[0]);
200 break;
201 case QAM_AUTO:
202 break;
203 default:
204 warn("unkown constellation.");
205 break;
206 }
207 return 0;
208}
209
210static int dib3000mc_set_general_cfg(struct dib3000_state *state, struct dvb_frontend_parameters *fep, int *auto_val)
211{
212 struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm;
213 fe_code_rate_t fe_cr = FEC_NONE;
214 u8 fft=0, guard=0, qam=0, alpha=0, sel_hp=0, cr=0, hrch=0;
215 int seq;
216
217 switch (ofdm->transmission_mode) {
218 case TRANSMISSION_MODE_2K: fft = DIB3000_TRANSMISSION_MODE_2K; break;
219 case TRANSMISSION_MODE_8K: fft = DIB3000_TRANSMISSION_MODE_8K; break;
220 case TRANSMISSION_MODE_AUTO: break;
221 default: return -EINVAL;
222 }
223 switch (ofdm->guard_interval) {
224 case GUARD_INTERVAL_1_32: guard = DIB3000_GUARD_TIME_1_32; break;
225 case GUARD_INTERVAL_1_16: guard = DIB3000_GUARD_TIME_1_16; break;
226 case GUARD_INTERVAL_1_8: guard = DIB3000_GUARD_TIME_1_8; break;
227 case GUARD_INTERVAL_1_4: guard = DIB3000_GUARD_TIME_1_4; break;
228 case GUARD_INTERVAL_AUTO: break;
229 default: return -EINVAL;
230 }
231 switch (ofdm->constellation) {
232 case QPSK: qam = DIB3000_CONSTELLATION_QPSK; break;
233 case QAM_16: qam = DIB3000_CONSTELLATION_16QAM; break;
234 case QAM_64: qam = DIB3000_CONSTELLATION_64QAM; break;
235 case QAM_AUTO: break;
236 default: return -EINVAL;
237 }
238 switch (ofdm->hierarchy_information) {
239 case HIERARCHY_NONE: /* fall through */
240 case HIERARCHY_1: alpha = DIB3000_ALPHA_1; break;
241 case HIERARCHY_2: alpha = DIB3000_ALPHA_2; break;
242 case HIERARCHY_4: alpha = DIB3000_ALPHA_4; break;
243 case HIERARCHY_AUTO: break;
244 default: return -EINVAL;
245 }
246 if (ofdm->hierarchy_information == HIERARCHY_NONE) {
247 hrch = DIB3000_HRCH_OFF;
248 sel_hp = DIB3000_SELECT_HP;
249 fe_cr = ofdm->code_rate_HP;
250 } else if (ofdm->hierarchy_information != HIERARCHY_AUTO) {
251 hrch = DIB3000_HRCH_ON;
252 sel_hp = DIB3000_SELECT_LP;
253 fe_cr = ofdm->code_rate_LP;
254 }
255 switch (fe_cr) {
256 case FEC_1_2: cr = DIB3000_FEC_1_2; break;
257 case FEC_2_3: cr = DIB3000_FEC_2_3; break;
258 case FEC_3_4: cr = DIB3000_FEC_3_4; break;
259 case FEC_5_6: cr = DIB3000_FEC_5_6; break;
260 case FEC_7_8: cr = DIB3000_FEC_7_8; break;
261 case FEC_NONE: break;
262 case FEC_AUTO: break;
263 default: return -EINVAL;
264 }
265
266 wr(DIB3000MC_REG_DEMOD_PARM,DIB3000MC_DEMOD_PARM(alpha,qam,guard,fft));
267 wr(DIB3000MC_REG_HRCH_PARM,DIB3000MC_HRCH_PARM(sel_hp,cr,hrch));
268
269 switch (fep->inversion) {
270 case INVERSION_OFF:
271 wr(DIB3000MC_REG_SET_DDS_FREQ_MSB,DIB3000MC_DDS_FREQ_MSB_INV_OFF);
272 break;
273 case INVERSION_AUTO: /* fall through */
274 case INVERSION_ON:
275 wr(DIB3000MC_REG_SET_DDS_FREQ_MSB,DIB3000MC_DDS_FREQ_MSB_INV_ON);
276 break;
277 default:
278 return -EINVAL;
279 }
280
281 seq = dib3000_seq
282 [ofdm->transmission_mode == TRANSMISSION_MODE_AUTO]
283 [ofdm->guard_interval == GUARD_INTERVAL_AUTO]
284 [fep->inversion == INVERSION_AUTO];
285
286 deb_setf("seq? %d\n", seq);
287 wr(DIB3000MC_REG_SEQ_TPS,DIB3000MC_SEQ_TPS(seq,1));
288 *auto_val = ofdm->constellation == QAM_AUTO ||
289 ofdm->hierarchy_information == HIERARCHY_AUTO ||
290 ofdm->guard_interval == GUARD_INTERVAL_AUTO ||
291 ofdm->transmission_mode == TRANSMISSION_MODE_AUTO ||
292 fe_cr == FEC_AUTO ||
293 fep->inversion == INVERSION_AUTO;
294 return 0;
295}
296
297static int dib3000mc_get_frontend(struct dvb_frontend* fe,
298 struct dvb_frontend_parameters *fep)
299{
300 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
301 struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm;
302 fe_code_rate_t *cr;
303 u16 tps_val,cr_val;
304 int inv_test1,inv_test2;
305 u32 dds_val, threshold = 0x1000000;
306
307 if (!(rd(DIB3000MC_REG_LOCK_507) & DIB3000MC_LOCK_507))
308 return 0;
309
310 dds_val = (rd(DIB3000MC_REG_DDS_FREQ_MSB) << 16) + rd(DIB3000MC_REG_DDS_FREQ_LSB);
311 deb_getf("DDS_FREQ: %6x\n",dds_val);
312 if (dds_val < threshold)
313 inv_test1 = 0;
314 else if (dds_val == threshold)
315 inv_test1 = 1;
316 else
317 inv_test1 = 2;
318
319 dds_val = (rd(DIB3000MC_REG_SET_DDS_FREQ_MSB) << 16) + rd(DIB3000MC_REG_SET_DDS_FREQ_LSB);
320 deb_getf("DDS_SET_FREQ: %6x\n",dds_val);
321 if (dds_val < threshold)
322 inv_test2 = 0;
323 else if (dds_val == threshold)
324 inv_test2 = 1;
325 else
326 inv_test2 = 2;
327
328 fep->inversion =
329 ((inv_test2 == 2) && (inv_test1==1 || inv_test1==0)) ||
330 ((inv_test2 == 0) && (inv_test1==1 || inv_test1==2)) ?
331 INVERSION_ON : INVERSION_OFF;
332
333 deb_getf("inversion %d %d, %d\n", inv_test2, inv_test1, fep->inversion);
334
335 fep->frequency = state->last_tuned_freq;
336 fep->u.ofdm.bandwidth= state->last_tuned_bw;
337
338 tps_val = rd(DIB3000MC_REG_TUNING_PARM);
339
340 switch (DIB3000MC_TP_QAM(tps_val)) {
341 case DIB3000_CONSTELLATION_QPSK:
342 deb_getf("QPSK ");
343 ofdm->constellation = QPSK;
344 break;
345 case DIB3000_CONSTELLATION_16QAM:
346 deb_getf("QAM16 ");
347 ofdm->constellation = QAM_16;
348 break;
349 case DIB3000_CONSTELLATION_64QAM:
350 deb_getf("QAM64 ");
351 ofdm->constellation = QAM_64;
352 break;
353 default:
354 err("Unexpected constellation returned by TPS (%d)", tps_val);
355 break;
356 }
357
358 if (DIB3000MC_TP_HRCH(tps_val)) {
359 deb_getf("HRCH ON ");
360 cr = &ofdm->code_rate_LP;
361 ofdm->code_rate_HP = FEC_NONE;
362 switch (DIB3000MC_TP_ALPHA(tps_val)) {
363 case DIB3000_ALPHA_0:
364 deb_getf("HIERARCHY_NONE ");
365 ofdm->hierarchy_information = HIERARCHY_NONE;
366 break;
367 case DIB3000_ALPHA_1:
368 deb_getf("HIERARCHY_1 ");
369 ofdm->hierarchy_information = HIERARCHY_1;
370 break;
371 case DIB3000_ALPHA_2:
372 deb_getf("HIERARCHY_2 ");
373 ofdm->hierarchy_information = HIERARCHY_2;
374 break;
375 case DIB3000_ALPHA_4:
376 deb_getf("HIERARCHY_4 ");
377 ofdm->hierarchy_information = HIERARCHY_4;
378 break;
379 default:
380 err("Unexpected ALPHA value returned by TPS (%d)", tps_val);
381 break;
382 }
383 cr_val = DIB3000MC_TP_FEC_CR_LP(tps_val);
384 } else {
385 deb_getf("HRCH OFF ");
386 cr = &ofdm->code_rate_HP;
387 ofdm->code_rate_LP = FEC_NONE;
388 ofdm->hierarchy_information = HIERARCHY_NONE;
389 cr_val = DIB3000MC_TP_FEC_CR_HP(tps_val);
390 }
391
392 switch (cr_val) {
393 case DIB3000_FEC_1_2:
394 deb_getf("FEC_1_2 ");
395 *cr = FEC_1_2;
396 break;
397 case DIB3000_FEC_2_3:
398 deb_getf("FEC_2_3 ");
399 *cr = FEC_2_3;
400 break;
401 case DIB3000_FEC_3_4:
402 deb_getf("FEC_3_4 ");
403 *cr = FEC_3_4;
404 break;
405 case DIB3000_FEC_5_6:
406 deb_getf("FEC_5_6 ");
407 *cr = FEC_4_5;
408 break;
409 case DIB3000_FEC_7_8:
410 deb_getf("FEC_7_8 ");
411 *cr = FEC_7_8;
412 break;
413 default:
414 err("Unexpected FEC returned by TPS (%d)", tps_val);
415 break;
416 }
417
418 switch (DIB3000MC_TP_GUARD(tps_val)) {
419 case DIB3000_GUARD_TIME_1_32:
420 deb_getf("GUARD_INTERVAL_1_32 ");
421 ofdm->guard_interval = GUARD_INTERVAL_1_32;
422 break;
423 case DIB3000_GUARD_TIME_1_16:
424 deb_getf("GUARD_INTERVAL_1_16 ");
425 ofdm->guard_interval = GUARD_INTERVAL_1_16;
426 break;
427 case DIB3000_GUARD_TIME_1_8:
428 deb_getf("GUARD_INTERVAL_1_8 ");
429 ofdm->guard_interval = GUARD_INTERVAL_1_8;
430 break;
431 case DIB3000_GUARD_TIME_1_4:
432 deb_getf("GUARD_INTERVAL_1_4 ");
433 ofdm->guard_interval = GUARD_INTERVAL_1_4;
434 break;
435 default:
436 err("Unexpected Guard Time returned by TPS (%d)", tps_val);
437 break;
438 }
439
440 switch (DIB3000MC_TP_FFT(tps_val)) {
441 case DIB3000_TRANSMISSION_MODE_2K:
442 deb_getf("TRANSMISSION_MODE_2K ");
443 ofdm->transmission_mode = TRANSMISSION_MODE_2K;
444 break;
445 case DIB3000_TRANSMISSION_MODE_8K:
446 deb_getf("TRANSMISSION_MODE_8K ");
447 ofdm->transmission_mode = TRANSMISSION_MODE_8K;
448 break;
449 default:
450 err("unexpected transmission mode return by TPS (%d)", tps_val);
451 break;
452 }
453 deb_getf("\n");
454
455 return 0;
456}
457
458static int dib3000mc_set_frontend(struct dvb_frontend* fe,
459 struct dvb_frontend_parameters *fep, int tuner)
460{
461 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
462 struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm;
463 int search_state,auto_val;
464 u16 val;
465
466 if (tuner) { /* initial call from dvb */
467 dib3000mc_tuner_pass_ctrl(fe,1,state->config.pll_addr(fe));
468 state->config.pll_set(fe,fep,NULL);
469 dib3000mc_tuner_pass_ctrl(fe,0,state->config.pll_addr(fe));
470
471 state->last_tuned_freq = fep->frequency;
472 // if (!scanboost) {
473 dib3000mc_set_timing(state,0,ofdm->transmission_mode,ofdm->bandwidth);
474 dib3000mc_init_auto_scan(state, ofdm->bandwidth, 0);
475 state->last_tuned_bw = ofdm->bandwidth;
476
477 wr_foreach(dib3000mc_reg_agc_bandwidth,dib3000mc_agc_bandwidth);
478 wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_AGC);
479 wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_OFF);
480
481 /* Default cfg isi offset adp */
482 wr_foreach(dib3000mc_reg_offset,dib3000mc_offset[0]);
483
484 wr(DIB3000MC_REG_ISI,DIB3000MC_ISI_DEFAULT | DIB3000MC_ISI_INHIBIT);
485 dib3000mc_set_adp_cfg(state,ofdm->constellation);
486 wr(DIB3000MC_REG_UNK_133,DIB3000MC_UNK_133);
487
488 wr_foreach(dib3000mc_reg_bandwidth_general,dib3000mc_bandwidth_general);
489 /* power smoothing */
490 if (ofdm->bandwidth != BANDWIDTH_8_MHZ) {
491 wr_foreach(dib3000mc_reg_bw,dib3000mc_bw[0]);
492 } else {
493 wr_foreach(dib3000mc_reg_bw,dib3000mc_bw[3]);
494 }
495 auto_val = 0;
496 dib3000mc_set_general_cfg(state,fep,&auto_val);
497 dib3000mc_set_impulse_noise(state,0,ofdm->constellation,ofdm->bandwidth);
498
499 val = rd(DIB3000MC_REG_DEMOD_PARM);
500 wr(DIB3000MC_REG_DEMOD_PARM,val|DIB3000MC_DEMOD_RST_DEMOD_ON);
501 wr(DIB3000MC_REG_DEMOD_PARM,val);
502 // }
503 msleep(70);
504
505 /* something has to be auto searched */
506 if (auto_val) {
507 int as_count=0;
508
509 deb_setf("autosearch enabled.\n");
510
511 val = rd(DIB3000MC_REG_DEMOD_PARM);
512 wr(DIB3000MC_REG_DEMOD_PARM,val | DIB3000MC_DEMOD_RST_AUTO_SRCH_ON);
513 wr(DIB3000MC_REG_DEMOD_PARM,val);
514
515 while ((search_state = dib3000_search_status(
516 rd(DIB3000MC_REG_AS_IRQ),1)) < 0 && as_count++ < 100)
517 msleep(10);
518
519 deb_info("search_state after autosearch %d after %d checks\n",search_state,as_count);
520
521 if (search_state == 1) {
522 struct dvb_frontend_parameters feps;
523 if (dib3000mc_get_frontend(fe, &feps) == 0) {
524 deb_setf("reading tuning data from frontend succeeded.\n");
525 return dib3000mc_set_frontend(fe, &feps, 0);
526 }
527 }
528 } else {
529 dib3000mc_set_impulse_noise(state,0,ofdm->transmission_mode,ofdm->bandwidth);
530 wr(DIB3000MC_REG_ISI,DIB3000MC_ISI_DEFAULT|DIB3000MC_ISI_ACTIVATE);
531 dib3000mc_set_adp_cfg(state,ofdm->constellation);
532
533 /* set_offset_cfg */
534 wr_foreach(dib3000mc_reg_offset,
535 dib3000mc_offset[(ofdm->transmission_mode == TRANSMISSION_MODE_8K)+1]);
536 }
537 } else { /* second call, after autosearch (fka: set_WithKnownParams) */
538// dib3000mc_set_timing(state,1,ofdm->transmission_mode,ofdm->bandwidth);
539
540 auto_val = 0;
541 dib3000mc_set_general_cfg(state,fep,&auto_val);
542 if (auto_val)
543 deb_info("auto_val is true, even though an auto search was already performed.\n");
544
545 dib3000mc_set_impulse_noise(state,0,ofdm->constellation,ofdm->bandwidth);
546
547 val = rd(DIB3000MC_REG_DEMOD_PARM);
548 wr(DIB3000MC_REG_DEMOD_PARM,val | DIB3000MC_DEMOD_RST_AUTO_SRCH_ON);
549 wr(DIB3000MC_REG_DEMOD_PARM,val);
550
551 msleep(30);
552
553 wr(DIB3000MC_REG_ISI,DIB3000MC_ISI_DEFAULT|DIB3000MC_ISI_ACTIVATE);
554 dib3000mc_set_adp_cfg(state,ofdm->constellation);
555 wr_foreach(dib3000mc_reg_offset,
556 dib3000mc_offset[(ofdm->transmission_mode == TRANSMISSION_MODE_8K)+1]);
557
558
559 }
560 return 0;
561}
562
563static int dib3000mc_fe_init(struct dvb_frontend* fe, int mobile_mode)
564{
565 struct dib3000_state *state;
566
567 deb_info("init start\n");
568
569 state = fe->demodulator_priv;
570 state->timing_offset = 0;
571 state->timing_offset_comp_done = 0;
572
573 wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_CONFIG);
574 wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_OFF);
575 wr(DIB3000MC_REG_CLK_CFG_1,DIB3000MC_CLK_CFG_1_POWER_UP);
576 wr(DIB3000MC_REG_CLK_CFG_2,DIB3000MC_CLK_CFG_2_PUP_MOBILE);
577 wr(DIB3000MC_REG_CLK_CFG_3,DIB3000MC_CLK_CFG_3_POWER_UP);
578 wr(DIB3000MC_REG_CLK_CFG_7,DIB3000MC_CLK_CFG_7_INIT);
579
580 wr(DIB3000MC_REG_RST_UNC,DIB3000MC_RST_UNC_OFF);
581 wr(DIB3000MC_REG_UNK_19,DIB3000MC_UNK_19);
582
583 wr(33,5);
584 wr(36,81);
585 wr(DIB3000MC_REG_UNK_88,DIB3000MC_UNK_88);
586
587 wr(DIB3000MC_REG_UNK_99,DIB3000MC_UNK_99);
588 wr(DIB3000MC_REG_UNK_111,DIB3000MC_UNK_111_PH_N_MODE_0); /* phase noise algo off */
589
590 /* mobile mode - portable reception */
591 wr_foreach(dib3000mc_reg_mobile_mode,dib3000mc_mobile_mode[1]);
592
593/* TUNER_PANASONIC_ENV57H12D5: */
594 wr_foreach(dib3000mc_reg_agc_bandwidth,dib3000mc_agc_bandwidth);
595 wr_foreach(dib3000mc_reg_agc_bandwidth_general,dib3000mc_agc_bandwidth_general);
596 wr_foreach(dib3000mc_reg_agc,dib3000mc_agc_tuner[1]);
597
598 wr(DIB3000MC_REG_UNK_110,DIB3000MC_UNK_110);
599 wr(26,0x6680);
600 wr(DIB3000MC_REG_UNK_1,DIB3000MC_UNK_1);
601 wr(DIB3000MC_REG_UNK_2,DIB3000MC_UNK_2);
602 wr(DIB3000MC_REG_UNK_3,DIB3000MC_UNK_3);
603 wr(DIB3000MC_REG_SEQ_TPS,DIB3000MC_SEQ_TPS_DEFAULT);
604
605 wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_8mhz);
606 wr_foreach(dib3000mc_reg_bandwidth_general,dib3000mc_bandwidth_general);
607
608 wr(DIB3000MC_REG_UNK_4,DIB3000MC_UNK_4);
609
610 wr(DIB3000MC_REG_SET_DDS_FREQ_MSB,DIB3000MC_DDS_FREQ_MSB_INV_OFF);
611 wr(DIB3000MC_REG_SET_DDS_FREQ_LSB,DIB3000MC_DDS_FREQ_LSB);
612
613 dib3000mc_set_timing(state,0,TRANSMISSION_MODE_8K,BANDWIDTH_8_MHZ);
614// wr_foreach(dib3000mc_reg_timing_freq,dib3000mc_timing_freq[3]);
615
616 wr(DIB3000MC_REG_UNK_120,DIB3000MC_UNK_120);
617 wr(DIB3000MC_REG_UNK_134,DIB3000MC_UNK_134);
618 wr(DIB3000MC_REG_FEC_CFG,DIB3000MC_FEC_CFG);
619
620 wr(DIB3000MC_REG_DIVERSITY3,DIB3000MC_DIVERSITY3_IN_OFF);
621
622 dib3000mc_set_impulse_noise(state,0,TRANSMISSION_MODE_8K,BANDWIDTH_8_MHZ);
623
624/* output mode control, just the MPEG2_SLAVE */
625// set_or(DIB3000MC_REG_OUTMODE,DIB3000MC_OM_SLAVE);
626 wr(DIB3000MC_REG_OUTMODE,DIB3000MC_OM_SLAVE);
627 wr(DIB3000MC_REG_SMO_MODE,DIB3000MC_SMO_MODE_SLAVE);
628 wr(DIB3000MC_REG_FIFO_THRESHOLD,DIB3000MC_FIFO_THRESHOLD_SLAVE);
629 wr(DIB3000MC_REG_ELEC_OUT,DIB3000MC_ELEC_OUT_SLAVE);
630
631/* MPEG2_PARALLEL_CONTINUOUS_CLOCK
632 wr(DIB3000MC_REG_OUTMODE,
633 DIB3000MC_SET_OUTMODE(DIB3000MC_OM_PAR_CONT_CLK,
634 rd(DIB3000MC_REG_OUTMODE)));
635
636 wr(DIB3000MC_REG_SMO_MODE,
637 DIB3000MC_SMO_MODE_DEFAULT |
638 DIB3000MC_SMO_MODE_188);
639
640 wr(DIB3000MC_REG_FIFO_THRESHOLD,DIB3000MC_FIFO_THRESHOLD_DEFAULT);
641 wr(DIB3000MC_REG_ELEC_OUT,DIB3000MC_ELEC_OUT_DIV_OUT_ON);
642*/
643
644/* diversity */
645 wr(DIB3000MC_REG_DIVERSITY1,DIB3000MC_DIVERSITY1_DEFAULT);
646 wr(DIB3000MC_REG_DIVERSITY2,DIB3000MC_DIVERSITY2_DEFAULT);
647
648 set_and(DIB3000MC_REG_DIVERSITY3,DIB3000MC_DIVERSITY3_IN_OFF);
649
650 set_or(DIB3000MC_REG_CLK_CFG_7,DIB3000MC_CLK_CFG_7_DIV_IN_OFF);
651
652/* if (state->config->pll_init) {
653 dib3000mc_tuner_pass_ctrl(fe,1,state->config.pll_addr(fe));
654 state->config->pll_init(fe,NULL);
655 dib3000mc_tuner_pass_ctrl(fe,0,state->config.pll_addr(fe));
656 }*/
657 deb_info("init end\n");
658 return 0;
659}
660static int dib3000mc_read_status(struct dvb_frontend* fe, fe_status_t *stat)
661{
662 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
663 u16 lock = rd(DIB3000MC_REG_LOCKING);
664
665 *stat = 0;
666 if (DIB3000MC_AGC_LOCK(lock))
667 *stat |= FE_HAS_SIGNAL;
668 if (DIB3000MC_CARRIER_LOCK(lock))
669 *stat |= FE_HAS_CARRIER;
670 if (DIB3000MC_TPS_LOCK(lock))
671 *stat |= FE_HAS_VITERBI;
672 if (DIB3000MC_MPEG_SYNC_LOCK(lock))
673 *stat |= (FE_HAS_SYNC | FE_HAS_LOCK);
674
675 deb_stat("actual status is %2x fifo_level: %x,244: %x, 206: %x, 207: %x, 1040: %x\n",*stat,rd(510),rd(244),rd(206),rd(207),rd(1040));
676
677 return 0;
678}
679
680static int dib3000mc_read_ber(struct dvb_frontend* fe, u32 *ber)
681{
682 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
683 *ber = ((rd(DIB3000MC_REG_BER_MSB) << 16) | rd(DIB3000MC_REG_BER_LSB));
684 return 0;
685}
686
687static int dib3000mc_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
688{
689 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
690
691 *unc = rd(DIB3000MC_REG_PACKET_ERROR_COUNT);
692 return 0;
693}
694
695/* see dib3000mb.c for calculation comments */
696static int dib3000mc_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
697{
698 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
699 u16 val = rd(DIB3000MC_REG_SIGNAL_NOISE_LSB);
700 *strength = (((val >> 6) & 0xff) << 8) + (val & 0x3f);
701
702 deb_stat("signal: mantisse = %d, exponent = %d\n",(*strength >> 8) & 0xff, *strength & 0xff);
703 return 0;
704}
705
706/* see dib3000mb.c for calculation comments */
707static int dib3000mc_read_snr(struct dvb_frontend* fe, u16 *snr)
708{
709 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
710 u16 val = rd(DIB3000MC_REG_SIGNAL_NOISE_LSB),
711 val2 = rd(DIB3000MC_REG_SIGNAL_NOISE_MSB);
712 u16 sig,noise;
713
714 sig = (((val >> 6) & 0xff) << 8) + (val & 0x3f);
715 noise = (((val >> 4) & 0xff) << 8) + ((val & 0xf) << 2) + ((val2 >> 14) & 0x3);
716 if (noise == 0)
717 *snr = 0xffff;
718 else
719 *snr = (u16) sig/noise;
720
721 deb_stat("signal: mantisse = %d, exponent = %d\n",(sig >> 8) & 0xff, sig & 0xff);
722 deb_stat("noise: mantisse = %d, exponent = %d\n",(noise >> 8) & 0xff, noise & 0xff);
723 deb_stat("snr: %d\n",*snr);
724 return 0;
725}
726
727static int dib3000mc_sleep(struct dvb_frontend* fe)
728{
729 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
730
731 set_or(DIB3000MC_REG_CLK_CFG_7,DIB3000MC_CLK_CFG_7_PWR_DOWN);
732 wr(DIB3000MC_REG_CLK_CFG_1,DIB3000MC_CLK_CFG_1_POWER_DOWN);
733 wr(DIB3000MC_REG_CLK_CFG_2,DIB3000MC_CLK_CFG_2_POWER_DOWN);
734 wr(DIB3000MC_REG_CLK_CFG_3,DIB3000MC_CLK_CFG_3_POWER_DOWN);
735 return 0;
736}
737
738static int dib3000mc_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
739{
740 tune->min_delay_ms = 2000;
741 tune->step_size = 166667;
742 tune->max_drift = 166667 * 2;
743
744 return 0;
745}
746
747static int dib3000mc_fe_init_nonmobile(struct dvb_frontend* fe)
748{
749 return dib3000mc_fe_init(fe, 0);
750}
751
752static int dib3000mc_set_frontend_and_tuner(struct dvb_frontend* fe, struct dvb_frontend_parameters *fep)
753{
754 return dib3000mc_set_frontend(fe, fep, 1);
755}
756
757static void dib3000mc_release(struct dvb_frontend* fe)
758{
759 struct dib3000_state *state = (struct dib3000_state *) fe->demodulator_priv;
760 kfree(state);
761}
762
763/* pid filter and transfer stuff */
764static int dib3000mc_pid_control(struct dvb_frontend *fe,int index, int pid,int onoff)
765{
766 struct dib3000_state *state = fe->demodulator_priv;
767 pid = (onoff ? pid | DIB3000_ACTIVATE_PID_FILTERING : 0);
768 wr(index+DIB3000MC_REG_FIRST_PID,pid);
769 return 0;
770}
771
772static int dib3000mc_fifo_control(struct dvb_frontend *fe, int onoff)
773{
774 struct dib3000_state *state = (struct dib3000_state*) fe->demodulator_priv;
775 u16 tmp = rd(DIB3000MC_REG_SMO_MODE);
776
777 deb_xfer("%s fifo\n",onoff ? "enabling" : "disabling");
778
779 if (onoff) {
780 deb_xfer("%d %x\n",tmp & DIB3000MC_SMO_MODE_FIFO_UNFLUSH,tmp & DIB3000MC_SMO_MODE_FIFO_UNFLUSH);
781 wr(DIB3000MC_REG_SMO_MODE,tmp & DIB3000MC_SMO_MODE_FIFO_UNFLUSH);
782 } else {
783 deb_xfer("%d %x\n",tmp | DIB3000MC_SMO_MODE_FIFO_FLUSH,tmp | DIB3000MC_SMO_MODE_FIFO_FLUSH);
784 wr(DIB3000MC_REG_SMO_MODE,tmp | DIB3000MC_SMO_MODE_FIFO_FLUSH);
785 }
786 return 0;
787}
788
789static int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff)
790{
791 struct dib3000_state *state = fe->demodulator_priv;
792 u16 tmp = rd(DIB3000MC_REG_SMO_MODE);
793
794 deb_xfer("%s pid parsing\n",onoff ? "enabling" : "disabling");
795
796 if (onoff) {
797 wr(DIB3000MC_REG_SMO_MODE,tmp | DIB3000MC_SMO_MODE_PID_PARSE);
798 } else {
799 wr(DIB3000MC_REG_SMO_MODE,tmp & DIB3000MC_SMO_MODE_NO_PID_PARSE);
800 }
801 return 0;
802}
803
804static int dib3000mc_tuner_pass_ctrl(struct dvb_frontend *fe, int onoff, u8 pll_addr)
805{
806 struct dib3000_state *state = (struct dib3000_state*) fe->demodulator_priv;
807 if (onoff) {
808 wr(DIB3000MC_REG_TUNER, DIB3000_TUNER_WRITE_ENABLE(pll_addr));
809 } else {
810 wr(DIB3000MC_REG_TUNER, DIB3000_TUNER_WRITE_DISABLE(pll_addr));
811 }
812 return 0;
813}
814
815static int dib3000mc_demod_init(struct dib3000_state *state)
816{
817 u16 default_addr = 0x0a;
818 /* first init */
819 if (state->config.demod_address != default_addr) {
820 deb_info("initializing the demod the first time. Setting demod addr to 0x%x\n",default_addr);
821 wr(DIB3000MC_REG_ELEC_OUT,DIB3000MC_ELEC_OUT_DIV_OUT_ON);
822 wr(DIB3000MC_REG_OUTMODE,DIB3000MC_OM_PAR_CONT_CLK);
823
824 wr(DIB3000MC_REG_RST_I2C_ADDR,
825 DIB3000MC_DEMOD_ADDR(default_addr) |
826 DIB3000MC_DEMOD_ADDR_ON);
827
828 state->config.demod_address = default_addr;
829
830 wr(DIB3000MC_REG_RST_I2C_ADDR,
831 DIB3000MC_DEMOD_ADDR(default_addr));
832 } else
833 deb_info("demod is already initialized. Demod addr: 0x%x\n",state->config.demod_address);
834 return 0;
835}
836
837
838static struct dvb_frontend_ops dib3000mc_ops;
839
840struct dvb_frontend* dib3000mc_attach(const struct dib3000_config* config,
841 struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops)
842{
843 struct dib3000_state* state = NULL;
844 u16 devid;
845
846 /* allocate memory for the internal state */
847 state = (struct dib3000_state*) kmalloc(sizeof(struct dib3000_state), GFP_KERNEL);
848 if (state == NULL)
849 goto error;
850 memset(state,0,sizeof(struct dib3000_state));
851
852 /* setup the state */
853 state->i2c = i2c;
854 memcpy(&state->config,config,sizeof(struct dib3000_config));
855 memcpy(&state->ops, &dib3000mc_ops, sizeof(struct dvb_frontend_ops));
856
857 /* check for the correct demod */
858 if (rd(DIB3000_REG_MANUFACTOR_ID) != DIB3000_I2C_ID_DIBCOM)
859 goto error;
860
861 devid = rd(DIB3000_REG_DEVICE_ID);
862 if (devid != DIB3000MC_DEVICE_ID && devid != DIB3000P_DEVICE_ID)
863 goto error;
864
865 switch (devid) {
866 case DIB3000MC_DEVICE_ID:
867 info("Found a DiBcom 3000M-C, interesting...");
868 break;
869 case DIB3000P_DEVICE_ID:
870 info("Found a DiBcom 3000P.");
871 break;
872 }
873
874 /* create dvb_frontend */
875 state->frontend.ops = &state->ops;
876 state->frontend.demodulator_priv = state;
877
878 /* set the xfer operations */
879 xfer_ops->pid_parse = dib3000mc_pid_parse;
880 xfer_ops->fifo_ctrl = dib3000mc_fifo_control;
881 xfer_ops->pid_ctrl = dib3000mc_pid_control;
882 xfer_ops->tuner_pass_ctrl = dib3000mc_tuner_pass_ctrl;
883
884 dib3000mc_demod_init(state);
885
886 return &state->frontend;
887
888error:
889 kfree(state);
890 return NULL;
891}
892
893static struct dvb_frontend_ops dib3000mc_ops = {
894
895 .info = {
896 .name = "DiBcom 3000P/M-C DVB-T",
897 .type = FE_OFDM,
898 .frequency_min = 44250000,
899 .frequency_max = 867250000,
900 .frequency_stepsize = 62500,
901 .caps = FE_CAN_INVERSION_AUTO |
902 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
903 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
904 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
905 FE_CAN_TRANSMISSION_MODE_AUTO |
906 FE_CAN_GUARD_INTERVAL_AUTO |
907 FE_CAN_RECOVER |
908 FE_CAN_HIERARCHY_AUTO,
909 },
910
911 .release = dib3000mc_release,
912
913 .init = dib3000mc_fe_init_nonmobile,
914 .sleep = dib3000mc_sleep,
915
916 .set_frontend = dib3000mc_set_frontend_and_tuner,
917 .get_frontend = dib3000mc_get_frontend,
918 .get_tune_settings = dib3000mc_fe_get_tune_settings,
919
920 .read_status = dib3000mc_read_status,
921 .read_ber = dib3000mc_read_ber,
922 .read_signal_strength = dib3000mc_read_signal_strength,
923 .read_snr = dib3000mc_read_snr,
924 .read_ucblocks = dib3000mc_read_unc_blocks,
925};
926
927MODULE_AUTHOR(DRIVER_AUTHOR);
928MODULE_DESCRIPTION(DRIVER_DESC);
929MODULE_LICENSE("GPL");
930
931EXPORT_SYMBOL(dib3000mc_attach);
diff --git a/drivers/media/dvb/frontends/dib3000mc_priv.h b/drivers/media/dvb/frontends/dib3000mc_priv.h
new file mode 100644
index 000000000000..2930aac7591b
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib3000mc_priv.h
@@ -0,0 +1,428 @@
1/*
2 * dib3000mc_priv.h
3 *
4 * Copyright (C) 2004 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 *
10 * for more information see dib3000mc.c .
11 */
12
13#ifndef __DIB3000MC_PRIV_H__
14#define __DIB3000MC_PRIV_H__
15
16/*
17 * Demodulator parameters
18 * reg: 0 1 1 1 11 11 111
19 * | | | | | |
20 * | | | | | +-- alpha (000=0, 001=1, 010=2, 100=4)
21 * | | | | +----- constellation (00=QPSK, 01=16QAM, 10=64QAM)
22 * | | | +-------- guard (00=1/32, 01=1/16, 10=1/8, 11=1/4)
23 * | | +----------- transmission mode (0=2k, 1=8k)
24 * | |
25 * | +-------------- restart autosearch for parameters
26 * +---------------- restart the demodulator
27 * reg: 181 1 111 1
28 * | | |
29 * | | +- FEC applies for HP or LP (0=LP, 1=HP)
30 * | +---- FEC rate (001=1/2, 010=2/3, 011=3/4, 101=5/6, 111=7/8)
31 * +------- hierarchy on (0=no, 1=yes)
32 */
33
34/* demodulator tuning parameter and restart options */
35#define DIB3000MC_REG_DEMOD_PARM ( 0)
36#define DIB3000MC_DEMOD_PARM(a,c,g,t) ( \
37 (0x7 & a) | \
38 ((0x3 & c) << 3) | \
39 ((0x3 & g) << 5) | \
40 ((0x1 & t) << 7) )
41#define DIB3000MC_DEMOD_RST_AUTO_SRCH_ON (1 << 8)
42#define DIB3000MC_DEMOD_RST_AUTO_SRCH_OFF (0 << 8)
43#define DIB3000MC_DEMOD_RST_DEMOD_ON (1 << 9)
44#define DIB3000MC_DEMOD_RST_DEMOD_OFF (0 << 9)
45
46/* register for hierarchy parameters */
47#define DIB3000MC_REG_HRCH_PARM ( 181)
48#define DIB3000MC_HRCH_PARM(s,f,h) ( \
49 (0x1 & s) | \
50 ((0x7 & f) << 1) | \
51 ((0x1 & h) << 4) )
52
53/* timeout ??? */
54#define DIB3000MC_REG_UNK_1 ( 1)
55#define DIB3000MC_UNK_1 ( 0x04)
56
57/* timeout ??? */
58#define DIB3000MC_REG_UNK_2 ( 2)
59#define DIB3000MC_UNK_2 ( 0x04)
60
61/* timeout ??? */
62#define DIB3000MC_REG_UNK_3 ( 3)
63#define DIB3000MC_UNK_3 (0x1000)
64
65#define DIB3000MC_REG_UNK_4 ( 4)
66#define DIB3000MC_UNK_4 (0x0814)
67
68/* timeout ??? */
69#define DIB3000MC_REG_SEQ_TPS ( 5)
70#define DIB3000MC_SEQ_TPS_DEFAULT ( 1)
71#define DIB3000MC_SEQ_TPS(s,t) ( \
72 ((s & 0x0f) << 4) | \
73 ((t & 0x01) << 8) )
74#define DIB3000MC_IS_TPS(v) ((v << 8) & 0x1)
75#define DIB3000MC_IS_AS(v) ((v >> 4) & 0xf)
76
77/* parameters for the bandwidth */
78#define DIB3000MC_REG_BW_TIMOUT_MSB ( 6)
79#define DIB3000MC_REG_BW_TIMOUT_LSB ( 7)
80
81static u16 dib3000mc_reg_bandwidth[] = { 6,7,8,9,10,11,16,17 };
82
83/*static u16 dib3000mc_bandwidth_5mhz[] =
84 { 0x28, 0x9380, 0x87, 0x4100, 0x2a4, 0x4500, 0x1, 0xb0d0 };*/
85
86static u16 dib3000mc_bandwidth_6mhz[] =
87 { 0x21, 0xd040, 0x70, 0xb62b, 0x233, 0x8ed5, 0x1, 0xb0d0 };
88
89static u16 dib3000mc_bandwidth_7mhz[] =
90 { 0x1c, 0xfba5, 0x60, 0x9c25, 0x1e3, 0x0cb7, 0x1, 0xb0d0 };
91
92static u16 dib3000mc_bandwidth_8mhz[] =
93 { 0x19, 0x5c30, 0x54, 0x88a0, 0x1a6, 0xab20, 0x1, 0xb0d0 };
94
95static u16 dib3000mc_reg_bandwidth_general[] = { 12,13,14,15 };
96static u16 dib3000mc_bandwidth_general[] = { 0x0000, 0x03e8, 0x0000, 0x03f2 };
97
98/* lock mask */
99#define DIB3000MC_REG_LOCK_MASK ( 15)
100#define DIB3000MC_ACTIVATE_LOCK_MASK (0x0800)
101
102/* reset the uncorrected packet count (??? do it 5 times) */
103#define DIB3000MC_REG_RST_UNC ( 18)
104#define DIB3000MC_RST_UNC_ON ( 1)
105#define DIB3000MC_RST_UNC_OFF ( 0)
106
107#define DIB3000MC_REG_UNK_19 ( 19)
108#define DIB3000MC_UNK_19 ( 0)
109
110/* DDS frequency value (IF position) and inversion bit */
111#define DIB3000MC_REG_INVERSION ( 21)
112#define DIB3000MC_REG_SET_DDS_FREQ_MSB ( 21)
113#define DIB3000MC_DDS_FREQ_MSB_INV_OFF (0x0164)
114#define DIB3000MC_DDS_FREQ_MSB_INV_ON (0x0364)
115
116#define DIB3000MC_REG_SET_DDS_FREQ_LSB ( 22)
117#define DIB3000MC_DDS_FREQ_LSB (0x463d)
118
119/* timing frequencies setting */
120#define DIB3000MC_REG_TIMING_FREQ_MSB ( 23)
121#define DIB3000MC_REG_TIMING_FREQ_LSB ( 24)
122#define DIB3000MC_CLOCK_REF (0x151fd1)
123
124//static u16 dib3000mc_reg_timing_freq[] = { 23,24 };
125
126//static u16 dib3000mc_timing_freq[][2] = {
127// { 0x69, 0x9f18 }, /* 5 MHz */
128// { 0x7e ,0xbee9 }, /* 6 MHz */
129// { 0x93 ,0xdebb }, /* 7 MHz */
130// { 0xa8 ,0xfe8c }, /* 8 MHz */
131//};
132
133/* timeout ??? */
134static u16 dib3000mc_reg_offset[] = { 26,33 };
135
136static u16 dib3000mc_offset[][2] = {
137 { 26240, 5 }, /* default */
138 { 30336, 6 }, /* 8K */
139 { 38528, 8 }, /* 2K */
140};
141
142#define DIB3000MC_REG_ISI ( 29)
143#define DIB3000MC_ISI_DEFAULT (0x1073)
144#define DIB3000MC_ISI_ACTIVATE (0x0000)
145#define DIB3000MC_ISI_INHIBIT (0x0200)
146
147/* impulse noise control */
148static u16 dib3000mc_reg_imp_noise_ctl[] = { 34,35 };
149
150static u16 dib3000mc_imp_noise_ctl[][2] = {
151 { 0x1294, 0x1ff8 }, /* mode 0 */
152 { 0x1294, 0x1ff8 }, /* mode 1 */
153 { 0x1294, 0x1ff8 }, /* mode 2 */
154 { 0x1294, 0x1ff8 }, /* mode 3 */
155 { 0x1294, 0x1ff8 }, /* mode 4 */
156};
157
158/* AGC registers */
159static u16 dib3000mc_reg_agc[] = {
160 36,37,38,39,42,43,44,45,46,47,48,49
161};
162
163static u16 dib3000mc_agc_tuner[][12] = {
164 { 0x0051, 0x301d, 0x0000, 0x1cc7, 0xcf5c, 0x6666,
165 0xbae1, 0xa148, 0x3b5e, 0x3c1c, 0x001a, 0x2019
166 }, /* TUNER_PANASONIC_ENV77H04D5, */
167
168 { 0x0051, 0x301d, 0x0000, 0x1cc7, 0xdc29, 0x570a,
169 0xbae1, 0x8ccd, 0x3b6d, 0x551d, 0x000a, 0x951e
170 }, /* TUNER_PANASONIC_ENV57H13D5, TUNER_PANASONIC_ENV57H12D5 */
171
172 { 0x0051, 0x301d, 0x0000, 0x1cc7, 0xffff, 0xffff,
173 0xffff, 0x0000, 0xfdfd, 0x4040, 0x00fd, 0x4040
174 }, /* TUNER_SAMSUNG_DTOS333IH102, TUNER_RFAGCIN_UNKNOWN */
175
176 { 0x0196, 0x301d, 0x0000, 0x1cc7, 0xbd71, 0x5c29,
177 0xb5c3, 0x6148, 0x6569, 0x5127, 0x0033, 0x3537
178 }, /* TUNER_PROVIDER_X */
179 /* TODO TUNER_PANASONIC_ENV57H10D8, TUNER_PANASONIC_ENV57H11D8 */
180};
181
182/* AGC loop bandwidth */
183static u16 dib3000mc_reg_agc_bandwidth[] = { 40,41 };
184static u16 dib3000mc_agc_bandwidth[] = { 0x119,0x330 };
185
186static u16 dib3000mc_reg_agc_bandwidth_general[] = { 50,51,52,53,54 };
187static u16 dib3000mc_agc_bandwidth_general[] =
188 { 0x8000, 0x91ca, 0x01ba, 0x0087, 0x0087 };
189
190#define DIB3000MC_REG_IMP_NOISE_55 ( 55)
191#define DIB3000MC_IMP_NEW_ALGO(w) (w | (1<<10))
192
193/* Impulse noise params */
194static u16 dib3000mc_reg_impulse_noise[] = { 55,56,57 };
195static u16 dib3000mc_impluse_noise[][3] = {
196 { 0x489, 0x89, 0x72 }, /* 5 MHz */
197 { 0x4a5, 0xa5, 0x89 }, /* 6 MHz */
198 { 0x4c0, 0xc0, 0xa0 }, /* 7 MHz */
199 { 0x4db, 0xdb, 0xb7 }, /* 8 Mhz */
200};
201
202static u16 dib3000mc_reg_fft[] = {
203 58,59,60,61,62,63,64,65,66,67,68,69,
204 70,71,72,73,74,75,76,77,78,79,80,81,
205 82,83,84,85,86
206};
207
208static u16 dib3000mc_fft_modes[][29] = {
209 { 0x38, 0x6d9, 0x3f28, 0x7a7, 0x3a74, 0x196, 0x32a, 0x48c,
210 0x3ffe, 0x7f3, 0x2d94, 0x76, 0x53d,
211 0x3ff8, 0x7e3, 0x3320, 0x76, 0x5b3,
212 0x3feb, 0x7d2, 0x365e, 0x76, 0x48c,
213 0x3ffe, 0x5b3, 0x3feb, 0x76, 0x0, 0xd
214 }, /* fft mode 0 */
215 { 0x3b, 0x6d9, 0x3f28, 0x7a7, 0x3a74, 0x196, 0x32a, 0x48c,
216 0x3ffe, 0x7f3, 0x2d94, 0x76, 0x53d,
217 0x3ff8, 0x7e3, 0x3320, 0x76, 0x5b3,
218 0x3feb, 0x7d2, 0x365e, 0x76, 0x48c,
219 0x3ffe, 0x5b3, 0x3feb, 0x0, 0x8200, 0xd
220 }, /* fft mode 1 */
221};
222
223#define DIB3000MC_REG_UNK_88 ( 88)
224#define DIB3000MC_UNK_88 (0x0410)
225
226static u16 dib3000mc_reg_bw[] = { 93,94,95,96,97,98 };
227static u16 dib3000mc_bw[][6] = {
228 { 0,0,0,0,0,0 }, /* 5 MHz */
229 { 0,0,0,0,0,0 }, /* 6 MHz */
230 { 0,0,0,0,0,0 }, /* 7 MHz */
231 { 0x20, 0x21, 0x20, 0x23, 0x20, 0x27 }, /* 8 MHz */
232};
233
234
235/* phase noise control */
236#define DIB3000MC_REG_UNK_99 ( 99)
237#define DIB3000MC_UNK_99 (0x0220)
238
239#define DIB3000MC_REG_SCAN_BOOST ( 100)
240#define DIB3000MC_SCAN_BOOST_ON ((11 << 6) + 6)
241#define DIB3000MC_SCAN_BOOST_OFF ((16 << 6) + 9)
242
243/* timeout ??? */
244#define DIB3000MC_REG_UNK_110 ( 110)
245#define DIB3000MC_UNK_110 ( 3277)
246
247#define DIB3000MC_REG_UNK_111 ( 111)
248#define DIB3000MC_UNK_111_PH_N_MODE_0 ( 0)
249#define DIB3000MC_UNK_111_PH_N_MODE_1 (1 << 1)
250
251/* superious rm config */
252#define DIB3000MC_REG_UNK_120 ( 120)
253#define DIB3000MC_UNK_120 ( 8207)
254
255#define DIB3000MC_REG_UNK_133 ( 133)
256#define DIB3000MC_UNK_133 ( 15564)
257
258#define DIB3000MC_REG_UNK_134 ( 134)
259#define DIB3000MC_UNK_134 ( 0)
260
261/* adapter config for constellation */
262static u16 dib3000mc_reg_adp_cfg[] = { 129, 130, 131, 132 };
263
264static u16 dib3000mc_adp_cfg[][4] = {
265 { 0x99a, 0x7fae, 0x333, 0x7ff0 }, /* QPSK */
266 { 0x23d, 0x7fdf, 0x0a4, 0x7ff0 }, /* 16-QAM */
267 { 0x148, 0x7ff0, 0x0a4, 0x7ff8 }, /* 64-QAM */
268};
269
270static u16 dib3000mc_reg_mobile_mode[] = { 139, 140, 141, 175, 1032 };
271
272static u16 dib3000mc_mobile_mode[][5] = {
273 { 0x01, 0x0, 0x0, 0x00, 0x12c }, /* fixed */
274 { 0x01, 0x0, 0x0, 0x00, 0x12c }, /* portable */
275 { 0x00, 0x0, 0x0, 0x02, 0x000 }, /* mobile */
276 { 0x00, 0x0, 0x0, 0x02, 0x000 }, /* auto */
277};
278
279#define DIB3000MC_REG_DIVERSITY1 ( 177)
280#define DIB3000MC_DIVERSITY1_DEFAULT ( 1)
281
282#define DIB3000MC_REG_DIVERSITY2 ( 178)
283#define DIB3000MC_DIVERSITY2_DEFAULT ( 1)
284
285#define DIB3000MC_REG_DIVERSITY3 ( 180)
286#define DIB3000MC_DIVERSITY3_IN_OFF (0xfff0)
287#define DIB3000MC_DIVERSITY3_IN_ON (0xfff6)
288
289#define DIB3000MC_REG_FEC_CFG ( 195)
290#define DIB3000MC_FEC_CFG ( 0x10)
291
292/*
293 * reg 206, output mode
294 * 1111 1111
295 * |||| ||||
296 * |||| |||+- unk
297 * |||| ||+-- unk
298 * |||| |+--- unk (on by default)
299 * |||| +---- fifo_ctrl (1 = inhibit (flushed), 0 = active (unflushed))
300 * |||+------ pid_parse (1 = enabled, 0 = disabled)
301 * ||+------- outp_188 (1 = TS packet size 188, 0 = packet size 204)
302 * |+-------- unk
303 * +--------- unk
304 */
305
306#define DIB3000MC_REG_SMO_MODE ( 206)
307#define DIB3000MC_SMO_MODE_DEFAULT (1 << 2)
308#define DIB3000MC_SMO_MODE_FIFO_FLUSH (1 << 3)
309#define DIB3000MC_SMO_MODE_FIFO_UNFLUSH (0xfff7)
310#define DIB3000MC_SMO_MODE_PID_PARSE (1 << 4)
311#define DIB3000MC_SMO_MODE_NO_PID_PARSE (0xffef)
312#define DIB3000MC_SMO_MODE_188 (1 << 5)
313#define DIB3000MC_SMO_MODE_SLAVE (DIB3000MC_SMO_MODE_DEFAULT | \
314 DIB3000MC_SMO_MODE_188 | DIB3000MC_SMO_MODE_PID_PARSE | (1<<1))
315
316#define DIB3000MC_REG_FIFO_THRESHOLD ( 207)
317#define DIB3000MC_FIFO_THRESHOLD_DEFAULT ( 1792)
318#define DIB3000MC_FIFO_THRESHOLD_SLAVE ( 512)
319/*
320 * pidfilter
321 * it is not a hardware pidfilter but a filter which drops all pids
322 * except the ones set. When connected to USB1.1 bandwidth this is important.
323 * DiB3000P/M-C can filter up to 32 PIDs
324 */
325#define DIB3000MC_REG_FIRST_PID ( 212)
326#define DIB3000MC_NUM_PIDS ( 32)
327
328#define DIB3000MC_REG_OUTMODE ( 244)
329#define DIB3000MC_OM_PARALLEL_GATED_CLK ( 0)
330#define DIB3000MC_OM_PAR_CONT_CLK (1 << 11)
331#define DIB3000MC_OM_SERIAL (2 << 11)
332#define DIB3000MC_OM_DIVOUT_ON (4 << 11)
333#define DIB3000MC_OM_SLAVE (DIB3000MC_OM_DIVOUT_ON | DIB3000MC_OM_PAR_CONT_CLK)
334
335#define DIB3000MC_REG_RF_POWER ( 392)
336
337#define DIB3000MC_REG_FFT_POSITION ( 407)
338
339#define DIB3000MC_REG_DDS_FREQ_MSB ( 414)
340#define DIB3000MC_REG_DDS_FREQ_LSB ( 415)
341
342#define DIB3000MC_REG_TIMING_OFFS_MSB ( 416)
343#define DIB3000MC_REG_TIMING_OFFS_LSB ( 417)
344
345#define DIB3000MC_REG_TUNING_PARM ( 458)
346#define DIB3000MC_TP_QAM(v) ((v >> 13) & 0x03)
347#define DIB3000MC_TP_HRCH(v) ((v >> 12) & 0x01)
348#define DIB3000MC_TP_ALPHA(v) ((v >> 9) & 0x07)
349#define DIB3000MC_TP_FFT(v) ((v >> 8) & 0x01)
350#define DIB3000MC_TP_FEC_CR_HP(v) ((v >> 5) & 0x07)
351#define DIB3000MC_TP_FEC_CR_LP(v) ((v >> 2) & 0x07)
352#define DIB3000MC_TP_GUARD(v) (v & 0x03)
353
354#define DIB3000MC_REG_SIGNAL_NOISE_MSB ( 483)
355#define DIB3000MC_REG_SIGNAL_NOISE_LSB ( 484)
356
357#define DIB3000MC_REG_MER ( 485)
358
359#define DIB3000MC_REG_BER_MSB ( 500)
360#define DIB3000MC_REG_BER_LSB ( 501)
361
362#define DIB3000MC_REG_PACKET_ERRORS ( 503)
363
364#define DIB3000MC_REG_PACKET_ERROR_COUNT ( 506)
365
366#define DIB3000MC_REG_LOCK_507 ( 507)
367#define DIB3000MC_LOCK_507 (0x0002) // ? name correct ?
368
369#define DIB3000MC_REG_LOCKING ( 509)
370#define DIB3000MC_AGC_LOCK(v) (v & 0x8000)
371#define DIB3000MC_CARRIER_LOCK(v) (v & 0x2000)
372#define DIB3000MC_MPEG_SYNC_LOCK(v) (v & 0x0080)
373#define DIB3000MC_MPEG_DATA_LOCK(v) (v & 0x0040)
374#define DIB3000MC_TPS_LOCK(v) (v & 0x0004)
375
376#define DIB3000MC_REG_AS_IRQ ( 511)
377#define DIB3000MC_AS_IRQ_SUCCESS (1 << 1)
378#define DIB3000MC_AS_IRQ_FAIL ( 1)
379
380#define DIB3000MC_REG_TUNER ( 769)
381
382#define DIB3000MC_REG_RST_I2C_ADDR ( 1024)
383#define DIB3000MC_DEMOD_ADDR_ON ( 1)
384#define DIB3000MC_DEMOD_ADDR(a) ((a << 4) & 0x03F0)
385
386#define DIB3000MC_REG_RESTART ( 1027)
387#define DIB3000MC_RESTART_OFF (0x0000)
388#define DIB3000MC_RESTART_AGC (0x0800)
389#define DIB3000MC_RESTART_CONFIG (0x8000)
390
391#define DIB3000MC_REG_RESTART_VIT ( 1028)
392#define DIB3000MC_RESTART_VIT_OFF ( 0)
393#define DIB3000MC_RESTART_VIT_ON ( 1)
394
395#define DIB3000MC_REG_CLK_CFG_1 ( 1031)
396#define DIB3000MC_CLK_CFG_1_POWER_UP ( 0)
397#define DIB3000MC_CLK_CFG_1_POWER_DOWN (0xffff)
398
399#define DIB3000MC_REG_CLK_CFG_2 ( 1032)
400#define DIB3000MC_CLK_CFG_2_PUP_FIXED (0x012c)
401#define DIB3000MC_CLK_CFG_2_PUP_PORT (0x0104)
402#define DIB3000MC_CLK_CFG_2_PUP_MOBILE (0x0000)
403#define DIB3000MC_CLK_CFG_2_POWER_DOWN (0xffff)
404
405#define DIB3000MC_REG_CLK_CFG_3 ( 1033)
406#define DIB3000MC_CLK_CFG_3_POWER_UP ( 0)
407#define DIB3000MC_CLK_CFG_3_POWER_DOWN (0xfff5)
408
409#define DIB3000MC_REG_CLK_CFG_7 ( 1037)
410#define DIB3000MC_CLK_CFG_7_INIT ( 12592)
411#define DIB3000MC_CLK_CFG_7_POWER_UP (~0x0003)
412#define DIB3000MC_CLK_CFG_7_PWR_DOWN (0x0003)
413#define DIB3000MC_CLK_CFG_7_DIV_IN_OFF (1 << 8)
414
415/* was commented out ??? */
416#define DIB3000MC_REG_CLK_CFG_8 ( 1038)
417#define DIB3000MC_CLK_CFG_8_POWER_UP (0x160c)
418
419#define DIB3000MC_REG_CLK_CFG_9 ( 1039)
420#define DIB3000MC_CLK_CFG_9_POWER_UP ( 0)
421
422/* also clock ??? */
423#define DIB3000MC_REG_ELEC_OUT ( 1040)
424#define DIB3000MC_ELEC_OUT_HIGH_Z ( 0)
425#define DIB3000MC_ELEC_OUT_DIV_OUT_ON ( 1)
426#define DIB3000MC_ELEC_OUT_SLAVE ( 3)
427
428#endif
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c
new file mode 100644
index 000000000000..2a3c2ce7b2aa
--- /dev/null
+++ b/drivers/media/dvb/frontends/dvb-pll.c
@@ -0,0 +1,168 @@
1/*
2 * $Id: dvb-pll.c,v 1.7 2005/02/10 11:52:02 kraxel Exp $
3 *
4 * descriptions + helper functions for simple dvb plls.
5 *
6 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <linux/module.h>
24#include <linux/dvb/frontend.h>
25#include <asm/types.h>
26
27#include "dvb-pll.h"
28
29/* ----------------------------------------------------------- */
30/* descriptions */
31
32struct dvb_pll_desc dvb_pll_thomson_dtt7579 = {
33 .name = "Thomson dtt7579",
34 .min = 177000000,
35 .max = 858000000,
36 .count = 5,
37 .entries = {
38 { 0, 36166667, 166666, 0xb4, 0x03 }, /* go sleep */
39 { 443250000, 36166667, 166666, 0xb4, 0x02 },
40 { 542000000, 36166667, 166666, 0xb4, 0x08 },
41 { 771000000, 36166667, 166666, 0xbc, 0x08 },
42 { 999999999, 36166667, 166666, 0xf4, 0x08 },
43 },
44};
45EXPORT_SYMBOL(dvb_pll_thomson_dtt7579);
46
47struct dvb_pll_desc dvb_pll_thomson_dtt7610 = {
48 .name = "Thomson dtt7610",
49 .min = 44000000,
50 .max = 958000000,
51 .count = 3,
52 .entries = {
53 { 157250000, 44000000, 62500, 0x8e, 0x39 },
54 { 454000000, 44000000, 62500, 0x8e, 0x3a },
55 { 999999999, 44000000, 62500, 0x8e, 0x3c },
56 },
57};
58EXPORT_SYMBOL(dvb_pll_thomson_dtt7610);
59
60static void thomson_dtt759x_bw(u8 *buf, int bandwidth)
61{
62 if (BANDWIDTH_7_MHZ == bandwidth)
63 buf[3] |= 0x10;
64}
65
66struct dvb_pll_desc dvb_pll_thomson_dtt759x = {
67 .name = "Thomson dtt759x",
68 .min = 177000000,
69 .max = 896000000,
70 .setbw = thomson_dtt759x_bw,
71 .count = 6,
72 .entries = {
73 { 0, 36166667, 166666, 0x84, 0x03 },
74 { 264000000, 36166667, 166666, 0xb4, 0x02 },
75 { 470000000, 36166667, 166666, 0xbc, 0x02 },
76 { 735000000, 36166667, 166666, 0xbc, 0x08 },
77 { 835000000, 36166667, 166666, 0xf4, 0x08 },
78 { 999999999, 36166667, 166666, 0xfc, 0x08 },
79 },
80};
81EXPORT_SYMBOL(dvb_pll_thomson_dtt759x);
82
83struct dvb_pll_desc dvb_pll_lg_z201 = {
84 .name = "LG z201",
85 .min = 174000000,
86 .max = 862000000,
87 .count = 5,
88 .entries = {
89 { 0, 36166667, 166666, 0xbc, 0x03 },
90 { 443250000, 36166667, 166666, 0xbc, 0x01 },
91 { 542000000, 36166667, 166666, 0xbc, 0x02 },
92 { 830000000, 36166667, 166666, 0xf4, 0x02 },
93 { 999999999, 36166667, 166666, 0xfc, 0x02 },
94 },
95};
96EXPORT_SYMBOL(dvb_pll_lg_z201);
97
98struct dvb_pll_desc dvb_pll_unknown_1 = {
99 .name = "unknown 1", /* used by dntv live dvb-t */
100 .min = 174000000,
101 .max = 862000000,
102 .count = 9,
103 .entries = {
104 { 150000000, 36166667, 166666, 0xb4, 0x01 },
105 { 173000000, 36166667, 166666, 0xbc, 0x01 },
106 { 250000000, 36166667, 166666, 0xb4, 0x02 },
107 { 400000000, 36166667, 166666, 0xbc, 0x02 },
108 { 420000000, 36166667, 166666, 0xf4, 0x02 },
109 { 470000000, 36166667, 166666, 0xfc, 0x02 },
110 { 600000000, 36166667, 166666, 0xbc, 0x08 },
111 { 730000000, 36166667, 166666, 0xf4, 0x08 },
112 { 999999999, 36166667, 166666, 0xfc, 0x08 },
113 },
114};
115EXPORT_SYMBOL(dvb_pll_unknown_1);
116
117/* ----------------------------------------------------------- */
118/* code */
119
120static int debug = 0;
121module_param(debug, int, 0644);
122MODULE_PARM_DESC(debug, "enable verbose debug messages");
123
124int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
125 u32 freq, int bandwidth)
126{
127 u32 div;
128 int i;
129
130 if (freq != 0 && (freq < desc->min || freq > desc->max))
131 return -EINVAL;
132
133 for (i = 0; i < desc->count; i++) {
134 if (freq > desc->entries[i].limit)
135 continue;
136 break;
137 }
138 if (debug)
139 printk("pll: %s: freq=%d bw=%d | i=%d/%d\n",
140 desc->name, freq, bandwidth, i, desc->count);
141 BUG_ON(i == desc->count);
142
143 div = (freq + desc->entries[i].offset) / desc->entries[i].stepsize;
144 buf[0] = div >> 8;
145 buf[1] = div & 0xff;
146 buf[2] = desc->entries[i].cb1;
147 buf[3] = desc->entries[i].cb2;
148
149 if (desc->setbw)
150 desc->setbw(buf, bandwidth);
151
152 if (debug)
153 printk("pll: %s: div=%d | buf=0x%02x,0x%02x,0x%02x,0x%02x\n",
154 desc->name, div, buf[0], buf[1], buf[2], buf[3]);
155
156 return 0;
157}
158EXPORT_SYMBOL(dvb_pll_configure);
159
160MODULE_DESCRIPTION("dvb pll library");
161MODULE_AUTHOR("Gerd Knorr");
162MODULE_LICENSE("GPL");
163
164/*
165 * Local variables:
166 * c-basic-offset: 8
167 * End:
168 */
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h
new file mode 100644
index 000000000000..016c794a5677
--- /dev/null
+++ b/drivers/media/dvb/frontends/dvb-pll.h
@@ -0,0 +1,34 @@
1/*
2 * $Id: dvb-pll.h,v 1.2 2005/02/10 11:43:41 kraxel Exp $
3 */
4
5struct dvb_pll_desc {
6 char *name;
7 u32 min;
8 u32 max;
9 void (*setbw)(u8 *buf, int bandwidth);
10 int count;
11 struct {
12 u32 limit;
13 u32 offset;
14 u32 stepsize;
15 u8 cb1;
16 u8 cb2;
17 } entries[9];
18};
19
20extern struct dvb_pll_desc dvb_pll_thomson_dtt7579;
21extern struct dvb_pll_desc dvb_pll_thomson_dtt759x;
22extern struct dvb_pll_desc dvb_pll_thomson_dtt7610;
23extern struct dvb_pll_desc dvb_pll_lg_z201;
24extern struct dvb_pll_desc dvb_pll_unknown_1;
25
26int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
27 u32 freq, int bandwidth);
28
29/*
30 * Local variables:
31 * c-basic-offset: 8
32 * compile-command: "make DVB=1"
33 * End:
34 */
diff --git a/drivers/media/dvb/frontends/dvb_dummy_fe.c b/drivers/media/dvb/frontends/dvb_dummy_fe.c
new file mode 100644
index 000000000000..c05a9b05600c
--- /dev/null
+++ b/drivers/media/dvb/frontends/dvb_dummy_fe.c
@@ -0,0 +1,279 @@
1/*
2 * Driver for Dummy Frontend
3 *
4 * Written by Emard <emard@softhome.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
20 */
21
22#include <linux/module.h>
23#include <linux/moduleparam.h>
24#include <linux/init.h>
25
26#include "dvb_frontend.h"
27#include "dvb_dummy_fe.h"
28
29
30struct dvb_dummy_fe_state {
31 struct dvb_frontend_ops ops;
32 struct dvb_frontend frontend;
33};
34
35
36static int dvb_dummy_fe_read_status(struct dvb_frontend* fe, fe_status_t* status)
37{
38 *status = FE_HAS_SIGNAL
39 | FE_HAS_CARRIER
40 | FE_HAS_VITERBI
41 | FE_HAS_SYNC
42 | FE_HAS_LOCK;
43
44 return 0;
45}
46
47static int dvb_dummy_fe_read_ber(struct dvb_frontend* fe, u32* ber)
48{
49 *ber = 0;
50 return 0;
51}
52
53static int dvb_dummy_fe_read_signal_strength(struct dvb_frontend* fe, u16* strength)
54{
55 *strength = 0;
56 return 0;
57}
58
59static int dvb_dummy_fe_read_snr(struct dvb_frontend* fe, u16* snr)
60{
61 *snr = 0;
62 return 0;
63}
64
65static int dvb_dummy_fe_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
66{
67 *ucblocks = 0;
68 return 0;
69}
70
71static int dvb_dummy_fe_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
72{
73 return 0;
74}
75
76static int dvb_dummy_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
77{
78 return 0;
79}
80
81static int dvb_dummy_fe_sleep(struct dvb_frontend* fe)
82{
83 return 0;
84}
85
86static int dvb_dummy_fe_init(struct dvb_frontend* fe)
87{
88 return 0;
89}
90
91static int dvb_dummy_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
92{
93 return 0;
94}
95
96static int dvb_dummy_fe_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
97{
98 return 0;
99}
100
101static void dvb_dummy_fe_release(struct dvb_frontend* fe)
102{
103 struct dvb_dummy_fe_state* state = (struct dvb_dummy_fe_state*) fe->demodulator_priv;
104 kfree(state);
105}
106
107static struct dvb_frontend_ops dvb_dummy_fe_ofdm_ops;
108
109struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void)
110{
111 struct dvb_dummy_fe_state* state = NULL;
112
113 /* allocate memory for the internal state */
114 state = (struct dvb_dummy_fe_state*) kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
115 if (state == NULL) goto error;
116
117 /* setup the state */
118 memcpy(&state->ops, &dvb_dummy_fe_ofdm_ops, sizeof(struct dvb_frontend_ops));
119
120 /* create dvb_frontend */
121 state->frontend.ops = &state->ops;
122 state->frontend.demodulator_priv = state;
123 return &state->frontend;
124
125error:
126 kfree(state);
127 return NULL;
128}
129
130static struct dvb_frontend_ops dvb_dummy_fe_qpsk_ops;
131
132struct dvb_frontend* dvb_dummy_fe_qpsk_attach()
133{
134 struct dvb_dummy_fe_state* state = NULL;
135
136 /* allocate memory for the internal state */
137 state = (struct dvb_dummy_fe_state*) kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
138 if (state == NULL) goto error;
139
140 /* setup the state */
141 memcpy(&state->ops, &dvb_dummy_fe_qpsk_ops, sizeof(struct dvb_frontend_ops));
142
143 /* create dvb_frontend */
144 state->frontend.ops = &state->ops;
145 state->frontend.demodulator_priv = state;
146 return &state->frontend;
147
148error:
149 if (state) kfree(state);
150 return NULL;
151}
152
153static struct dvb_frontend_ops dvb_dummy_fe_qam_ops;
154
155struct dvb_frontend* dvb_dummy_fe_qam_attach()
156{
157 struct dvb_dummy_fe_state* state = NULL;
158
159 /* allocate memory for the internal state */
160 state = (struct dvb_dummy_fe_state*) kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
161 if (state == NULL) goto error;
162
163 /* setup the state */
164 memcpy(&state->ops, &dvb_dummy_fe_qam_ops, sizeof(struct dvb_frontend_ops));
165
166 /* create dvb_frontend */
167 state->frontend.ops = &state->ops;
168 state->frontend.demodulator_priv = state;
169 return &state->frontend;
170
171error:
172 if (state) kfree(state);
173 return NULL;
174}
175
176static struct dvb_frontend_ops dvb_dummy_fe_ofdm_ops = {
177
178 .info = {
179 .name = "Dummy DVB-T",
180 .type = FE_OFDM,
181 .frequency_min = 0,
182 .frequency_max = 863250000,
183 .frequency_stepsize = 62500,
184 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
185 FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
186 FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
187 FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
188 FE_CAN_TRANSMISSION_MODE_AUTO |
189 FE_CAN_GUARD_INTERVAL_AUTO |
190 FE_CAN_HIERARCHY_AUTO,
191 },
192
193 .release = dvb_dummy_fe_release,
194
195 .init = dvb_dummy_fe_init,
196 .sleep = dvb_dummy_fe_sleep,
197
198 .set_frontend = dvb_dummy_fe_set_frontend,
199 .get_frontend = dvb_dummy_fe_get_frontend,
200
201 .read_status = dvb_dummy_fe_read_status,
202 .read_ber = dvb_dummy_fe_read_ber,
203 .read_signal_strength = dvb_dummy_fe_read_signal_strength,
204 .read_snr = dvb_dummy_fe_read_snr,
205 .read_ucblocks = dvb_dummy_fe_read_ucblocks,
206};
207
208static struct dvb_frontend_ops dvb_dummy_fe_qam_ops = {
209
210 .info = {
211 .name = "Dummy DVB-C",
212 .type = FE_QAM,
213 .frequency_stepsize = 62500,
214 .frequency_min = 51000000,
215 .frequency_max = 858000000,
216 .symbol_rate_min = (57840000/2)/64, /* SACLK/64 == (XIN/2)/64 */
217 .symbol_rate_max = (57840000/2)/4, /* SACLK/4 */
218 .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
219 FE_CAN_QAM_128 | FE_CAN_QAM_256 |
220 FE_CAN_FEC_AUTO | FE_CAN_INVERSION_AUTO
221 },
222
223 .release = dvb_dummy_fe_release,
224
225 .init = dvb_dummy_fe_init,
226 .sleep = dvb_dummy_fe_sleep,
227
228 .set_frontend = dvb_dummy_fe_set_frontend,
229 .get_frontend = dvb_dummy_fe_get_frontend,
230
231 .read_status = dvb_dummy_fe_read_status,
232 .read_ber = dvb_dummy_fe_read_ber,
233 .read_signal_strength = dvb_dummy_fe_read_signal_strength,
234 .read_snr = dvb_dummy_fe_read_snr,
235 .read_ucblocks = dvb_dummy_fe_read_ucblocks,
236};
237
238static struct dvb_frontend_ops dvb_dummy_fe_qpsk_ops = {
239
240 .info = {
241 .name = "Dummy DVB-S",
242 .type = FE_QPSK,
243 .frequency_min = 950000,
244 .frequency_max = 2150000,
245 .frequency_stepsize = 250, /* kHz for QPSK frontends */
246 .frequency_tolerance = 29500,
247 .symbol_rate_min = 1000000,
248 .symbol_rate_max = 45000000,
249 .caps = FE_CAN_INVERSION_AUTO |
250 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
251 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
252 FE_CAN_QPSK
253 },
254
255 .release = dvb_dummy_fe_release,
256
257 .init = dvb_dummy_fe_init,
258 .sleep = dvb_dummy_fe_sleep,
259
260 .set_frontend = dvb_dummy_fe_set_frontend,
261 .get_frontend = dvb_dummy_fe_get_frontend,
262
263 .read_status = dvb_dummy_fe_read_status,
264 .read_ber = dvb_dummy_fe_read_ber,
265 .read_signal_strength = dvb_dummy_fe_read_signal_strength,
266 .read_snr = dvb_dummy_fe_read_snr,
267 .read_ucblocks = dvb_dummy_fe_read_ucblocks,
268
269 .set_voltage = dvb_dummy_fe_set_voltage,
270 .set_tone = dvb_dummy_fe_set_tone,
271};
272
273MODULE_DESCRIPTION("DVB DUMMY Frontend");
274MODULE_AUTHOR("Emard");
275MODULE_LICENSE("GPL");
276
277EXPORT_SYMBOL(dvb_dummy_fe_ofdm_attach);
278EXPORT_SYMBOL(dvb_dummy_fe_qam_attach);
279EXPORT_SYMBOL(dvb_dummy_fe_qpsk_attach);
diff --git a/drivers/media/dvb/frontends/dvb_dummy_fe.h b/drivers/media/dvb/frontends/dvb_dummy_fe.h
new file mode 100644
index 000000000000..8210f19d56ce
--- /dev/null
+++ b/drivers/media/dvb/frontends/dvb_dummy_fe.h
@@ -0,0 +1,32 @@
1/*
2 * Driver for Dummy Frontend
3 *
4 * Written by Emard <emard@softhome.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
20 */
21
22#ifndef DVB_DUMMY_FE_H
23#define DVB_DUMMY_FE_H
24
25#include <linux/dvb/frontend.h>
26#include "dvb_frontend.h"
27
28extern struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void);
29extern struct dvb_frontend* dvb_dummy_fe_qpsk_attach(void);
30extern struct dvb_frontend* dvb_dummy_fe_qam_attach(void);
31
32#endif // DVB_DUMMY_FE_H
diff --git a/drivers/media/dvb/frontends/l64781.c b/drivers/media/dvb/frontends/l64781.c
new file mode 100644
index 000000000000..9ac95de9834d
--- /dev/null
+++ b/drivers/media/dvb/frontends/l64781.c
@@ -0,0 +1,602 @@
1/*
2 driver for LSI L64781 COFDM demodulator
3
4 Copyright (C) 2001 Holger Waechtler for Convergence Integrated Media GmbH
5 Marko Kohtala <marko.kohtala@luukku.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21*/
22
23#include <linux/init.h>
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/moduleparam.h>
27#include <linux/string.h>
28#include <linux/slab.h>
29#include "dvb_frontend.h"
30#include "l64781.h"
31
32
33struct l64781_state {
34 struct i2c_adapter* i2c;
35 struct dvb_frontend_ops ops;
36 const struct l64781_config* config;
37 struct dvb_frontend frontend;
38
39 /* private demodulator data */
40 int first:1;
41};
42
43#define dprintk(args...) \
44 do { \
45 if (debug) printk(KERN_DEBUG "l64781: " args); \
46 } while (0)
47
48static int debug;
49
50module_param(debug, int, 0644);
51MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
52
53
54static int l64781_writereg (struct l64781_state* state, u8 reg, u8 data)
55{
56 int ret;
57 u8 buf [] = { reg, data };
58 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
59
60 if ((ret = i2c_transfer(state->i2c, &msg, 1)) != 1)
61 dprintk ("%s: write_reg error (reg == %02x) = %02x!\n",
62 __FUNCTION__, reg, ret);
63
64 return (ret != 1) ? -1 : 0;
65}
66
67static int l64781_readreg (struct l64781_state* state, u8 reg)
68{
69 int ret;
70 u8 b0 [] = { reg };
71 u8 b1 [] = { 0 };
72 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
73 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
74
75 ret = i2c_transfer(state->i2c, msg, 2);
76
77 if (ret != 2) return ret;
78
79 return b1[0];
80}
81
82static void apply_tps (struct l64781_state* state)
83{
84 l64781_writereg (state, 0x2a, 0x00);
85 l64781_writereg (state, 0x2a, 0x01);
86
87 /* This here is a little bit questionable because it enables
88 the automatic update of TPS registers. I think we'd need to
89 handle the IRQ from FE to update some other registers as
90 well, or at least implement some magic to tuning to correct
91 to the TPS received from transmission. */
92 l64781_writereg (state, 0x2a, 0x02);
93}
94
95
96static void reset_afc (struct l64781_state* state)
97{
98 /* Set AFC stall for the AFC_INIT_FRQ setting, TIM_STALL for
99 timing offset */
100 l64781_writereg (state, 0x07, 0x9e); /* stall AFC */
101 l64781_writereg (state, 0x08, 0); /* AFC INIT FREQ */
102 l64781_writereg (state, 0x09, 0);
103 l64781_writereg (state, 0x0a, 0);
104 l64781_writereg (state, 0x07, 0x8e);
105 l64781_writereg (state, 0x0e, 0); /* AGC gain to zero in beginning */
106 l64781_writereg (state, 0x11, 0x80); /* stall TIM */
107 l64781_writereg (state, 0x10, 0); /* TIM_OFFSET_LSB */
108 l64781_writereg (state, 0x12, 0);
109 l64781_writereg (state, 0x13, 0);
110 l64781_writereg (state, 0x11, 0x00);
111}
112
113static int reset_and_configure (struct l64781_state* state)
114{
115 u8 buf [] = { 0x06 };
116 struct i2c_msg msg = { .addr = 0x00, .flags = 0, .buf = buf, .len = 1 };
117 // NOTE: this is correct in writing to address 0x00
118
119 return (i2c_transfer(state->i2c, &msg, 1) == 1) ? 0 : -ENODEV;
120}
121
122static int apply_frontend_param (struct dvb_frontend* fe, struct dvb_frontend_parameters *param)
123{
124 struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv;
125 /* The coderates for FEC_NONE, FEC_4_5 and FEC_FEC_6_7 are arbitrary */
126 static const u8 fec_tab[] = { 7, 0, 1, 2, 9, 3, 10, 4 };
127 /* QPSK, QAM_16, QAM_64 */
128 static const u8 qam_tab [] = { 2, 4, 0, 6 };
129 static const u8 bw_tab [] = { 8, 7, 6 }; /* 8Mhz, 7MHz, 6MHz */
130 static const u8 guard_tab [] = { 1, 2, 4, 8 };
131 /* The Grundig 29504-401.04 Tuner comes with 18.432MHz crystal. */
132 static const u32 ppm = 8000;
133 struct dvb_ofdm_parameters *p = &param->u.ofdm;
134 u32 ddfs_offset_fixed;
135/* u32 ddfs_offset_variable = 0x6000-((1000000UL+ppm)/ */
136/* bw_tab[p->bandWidth]<<10)/15625; */
137 u32 init_freq;
138 u32 spi_bias;
139 u8 val0x04;
140 u8 val0x05;
141 u8 val0x06;
142 int bw = p->bandwidth - BANDWIDTH_8_MHZ;
143
144 state->config->pll_set(fe, param);
145
146 if (param->inversion != INVERSION_ON &&
147 param->inversion != INVERSION_OFF)
148 return -EINVAL;
149
150 if (bw < 0 || bw > 2)
151 return -EINVAL;
152
153 if (p->code_rate_HP != FEC_1_2 && p->code_rate_HP != FEC_2_3 &&
154 p->code_rate_HP != FEC_3_4 && p->code_rate_HP != FEC_5_6 &&
155 p->code_rate_HP != FEC_7_8)
156 return -EINVAL;
157
158 if (p->hierarchy_information != HIERARCHY_NONE &&
159 (p->code_rate_LP != FEC_1_2 && p->code_rate_LP != FEC_2_3 &&
160 p->code_rate_LP != FEC_3_4 && p->code_rate_LP != FEC_5_6 &&
161 p->code_rate_LP != FEC_7_8))
162 return -EINVAL;
163
164 if (p->constellation != QPSK && p->constellation != QAM_16 &&
165 p->constellation != QAM_64)
166 return -EINVAL;
167
168 if (p->transmission_mode != TRANSMISSION_MODE_2K &&
169 p->transmission_mode != TRANSMISSION_MODE_8K)
170 return -EINVAL;
171
172 if (p->guard_interval < GUARD_INTERVAL_1_32 ||
173 p->guard_interval > GUARD_INTERVAL_1_4)
174 return -EINVAL;
175
176 if (p->hierarchy_information < HIERARCHY_NONE ||
177 p->hierarchy_information > HIERARCHY_4)
178 return -EINVAL;
179
180 ddfs_offset_fixed = 0x4000-(ppm<<16)/bw_tab[p->bandwidth]/1000000;
181
182 /* This works up to 20000 ppm, it overflows if too large ppm! */
183 init_freq = (((8UL<<25) + (8UL<<19) / 25*ppm / (15625/25)) /
184 bw_tab[p->bandwidth] & 0xFFFFFF);
185
186 /* SPI bias calculation is slightly modified to fit in 32bit */
187 /* will work for high ppm only... */
188 spi_bias = 378 * (1 << 10);
189 spi_bias *= 16;
190 spi_bias *= bw_tab[p->bandwidth];
191 spi_bias *= qam_tab[p->constellation];
192 spi_bias /= p->code_rate_HP + 1;
193 spi_bias /= (guard_tab[p->guard_interval] + 32);
194 spi_bias *= 1000ULL;
195 spi_bias /= 1000ULL + ppm/1000;
196 spi_bias *= p->code_rate_HP;
197
198 val0x04 = (p->transmission_mode << 2) | p->guard_interval;
199 val0x05 = fec_tab[p->code_rate_HP];
200
201 if (p->hierarchy_information != HIERARCHY_NONE)
202 val0x05 |= (p->code_rate_LP - FEC_1_2) << 3;
203
204 val0x06 = (p->hierarchy_information << 2) | p->constellation;
205
206 l64781_writereg (state, 0x04, val0x04);
207 l64781_writereg (state, 0x05, val0x05);
208 l64781_writereg (state, 0x06, val0x06);
209
210 reset_afc (state);
211
212 /* Technical manual section 2.6.1, TIM_IIR_GAIN optimal values */
213 l64781_writereg (state, 0x15,
214 p->transmission_mode == TRANSMISSION_MODE_2K ? 1 : 3);
215 l64781_writereg (state, 0x16, init_freq & 0xff);
216 l64781_writereg (state, 0x17, (init_freq >> 8) & 0xff);
217 l64781_writereg (state, 0x18, (init_freq >> 16) & 0xff);
218
219 l64781_writereg (state, 0x1b, spi_bias & 0xff);
220 l64781_writereg (state, 0x1c, (spi_bias >> 8) & 0xff);
221 l64781_writereg (state, 0x1d, ((spi_bias >> 16) & 0x7f) |
222 (param->inversion == INVERSION_ON ? 0x80 : 0x00));
223
224 l64781_writereg (state, 0x22, ddfs_offset_fixed & 0xff);
225 l64781_writereg (state, 0x23, (ddfs_offset_fixed >> 8) & 0x3f);
226
227 l64781_readreg (state, 0x00); /* clear interrupt registers... */
228 l64781_readreg (state, 0x01); /* dto. */
229
230 apply_tps (state);
231
232 return 0;
233}
234
235static int get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters* param)
236{
237 struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv;
238 int tmp;
239
240
241 tmp = l64781_readreg(state, 0x04);
242 switch(tmp & 3) {
243 case 0:
244 param->u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
245 break;
246 case 1:
247 param->u.ofdm.guard_interval = GUARD_INTERVAL_1_16;
248 break;
249 case 2:
250 param->u.ofdm.guard_interval = GUARD_INTERVAL_1_8;
251 break;
252 case 3:
253 param->u.ofdm.guard_interval = GUARD_INTERVAL_1_4;
254 break;
255 }
256 switch((tmp >> 2) & 3) {
257 case 0:
258 param->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K;
259 break;
260 case 1:
261 param->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
262 break;
263 default:
264 printk("Unexpected value for transmission_mode\n");
265 }
266
267
268
269 tmp = l64781_readreg(state, 0x05);
270 switch(tmp & 7) {
271 case 0:
272 param->u.ofdm.code_rate_HP = FEC_1_2;
273 break;
274 case 1:
275 param->u.ofdm.code_rate_HP = FEC_2_3;
276 break;
277 case 2:
278 param->u.ofdm.code_rate_HP = FEC_3_4;
279 break;
280 case 3:
281 param->u.ofdm.code_rate_HP = FEC_5_6;
282 break;
283 case 4:
284 param->u.ofdm.code_rate_HP = FEC_7_8;
285 break;
286 default:
287 printk("Unexpected value for code_rate_HP\n");
288 }
289 switch((tmp >> 3) & 7) {
290 case 0:
291 param->u.ofdm.code_rate_LP = FEC_1_2;
292 break;
293 case 1:
294 param->u.ofdm.code_rate_LP = FEC_2_3;
295 break;
296 case 2:
297 param->u.ofdm.code_rate_LP = FEC_3_4;
298 break;
299 case 3:
300 param->u.ofdm.code_rate_LP = FEC_5_6;
301 break;
302 case 4:
303 param->u.ofdm.code_rate_LP = FEC_7_8;
304 break;
305 default:
306 printk("Unexpected value for code_rate_LP\n");
307 }
308
309
310 tmp = l64781_readreg(state, 0x06);
311 switch(tmp & 3) {
312 case 0:
313 param->u.ofdm.constellation = QPSK;
314 break;
315 case 1:
316 param->u.ofdm.constellation = QAM_16;
317 break;
318 case 2:
319 param->u.ofdm.constellation = QAM_64;
320 break;
321 default:
322 printk("Unexpected value for constellation\n");
323 }
324 switch((tmp >> 2) & 7) {
325 case 0:
326 param->u.ofdm.hierarchy_information = HIERARCHY_NONE;
327 break;
328 case 1:
329 param->u.ofdm.hierarchy_information = HIERARCHY_1;
330 break;
331 case 2:
332 param->u.ofdm.hierarchy_information = HIERARCHY_2;
333 break;
334 case 3:
335 param->u.ofdm.hierarchy_information = HIERARCHY_4;
336 break;
337 default:
338 printk("Unexpected value for hierarchy\n");
339 }
340
341
342 tmp = l64781_readreg (state, 0x1d);
343 param->inversion = (tmp & 0x80) ? INVERSION_ON : INVERSION_OFF;
344
345 tmp = (int) (l64781_readreg (state, 0x08) |
346 (l64781_readreg (state, 0x09) << 8) |
347 (l64781_readreg (state, 0x0a) << 16));
348 param->frequency += tmp;
349
350 return 0;
351}
352
353static int l64781_read_status(struct dvb_frontend* fe, fe_status_t* status)
354{
355 struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv;
356 int sync = l64781_readreg (state, 0x32);
357 int gain = l64781_readreg (state, 0x0e);
358
359 l64781_readreg (state, 0x00); /* clear interrupt registers... */
360 l64781_readreg (state, 0x01); /* dto. */
361
362 *status = 0;
363
364 if (gain > 5)
365 *status |= FE_HAS_SIGNAL;
366
367 if (sync & 0x02) /* VCXO locked, this criteria should be ok */
368 *status |= FE_HAS_CARRIER;
369
370 if (sync & 0x20)
371 *status |= FE_HAS_VITERBI;
372
373 if (sync & 0x40)
374 *status |= FE_HAS_SYNC;
375
376 if (sync == 0x7f)
377 *status |= FE_HAS_LOCK;
378
379 return 0;
380}
381
382static int l64781_read_ber(struct dvb_frontend* fe, u32* ber)
383{
384 struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv;
385
386 /* XXX FIXME: set up counting period (reg 0x26...0x28)
387 */
388 *ber = l64781_readreg (state, 0x39)
389 | (l64781_readreg (state, 0x3a) << 8);
390
391 return 0;
392}
393
394static int l64781_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
395{
396 struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv;
397
398 u8 gain = l64781_readreg (state, 0x0e);
399 *signal_strength = (gain << 8) | gain;
400
401 return 0;
402}
403
404static int l64781_read_snr(struct dvb_frontend* fe, u16* snr)
405{
406 struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv;
407
408 u8 avg_quality = 0xff - l64781_readreg (state, 0x33);
409 *snr = (avg_quality << 8) | avg_quality; /* not exact, but...*/
410
411 return 0;
412}
413
414static int l64781_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
415{
416 struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv;
417
418 *ucblocks = l64781_readreg (state, 0x37)
419 | (l64781_readreg (state, 0x38) << 8);
420
421 return 0;
422}
423
424static int l64781_sleep(struct dvb_frontend* fe)
425{
426 struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv;
427
428 /* Power down */
429 return l64781_writereg (state, 0x3e, 0x5a);
430}
431
432static int l64781_init(struct dvb_frontend* fe)
433{
434 struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv;
435
436 reset_and_configure (state);
437
438 /* Power up */
439 l64781_writereg (state, 0x3e, 0xa5);
440
441 /* Reset hard */
442 l64781_writereg (state, 0x2a, 0x04);
443 l64781_writereg (state, 0x2a, 0x00);
444
445 /* Set tuner specific things */
446 /* AFC_POL, set also in reset_afc */
447 l64781_writereg (state, 0x07, 0x8e);
448
449 /* Use internal ADC */
450 l64781_writereg (state, 0x0b, 0x81);
451
452 /* AGC loop gain, and polarity is positive */
453 l64781_writereg (state, 0x0c, 0x84);
454
455 /* Internal ADC outputs two's complement */
456 l64781_writereg (state, 0x0d, 0x8c);
457
458 /* With ppm=8000, it seems the DTR_SENSITIVITY will result in
459 value of 2 with all possible bandwidths and guard
460 intervals, which is the initial value anyway. */
461 /*l64781_writereg (state, 0x19, 0x92);*/
462
463 /* Everything is two's complement, soft bit and CSI_OUT too */
464 l64781_writereg (state, 0x1e, 0x09);
465
466 if (state->config->pll_init) state->config->pll_init(fe);
467
468 /* delay a bit after first init attempt */
469 if (state->first) {
470 state->first = 0;
471 msleep(200);
472 }
473
474 return 0;
475}
476
477static int l64781_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
478{
479 fesettings->min_delay_ms = 200;
480 fesettings->step_size = 166667;
481 fesettings->max_drift = 166667*2;
482 return 0;
483}
484
485static void l64781_release(struct dvb_frontend* fe)
486{
487 struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv;
488 kfree(state);
489}
490
491static struct dvb_frontend_ops l64781_ops;
492
493struct dvb_frontend* l64781_attach(const struct l64781_config* config,
494 struct i2c_adapter* i2c)
495{
496 struct l64781_state* state = NULL;
497 int reg0x3e = -1;
498 u8 b0 [] = { 0x1a };
499 u8 b1 [] = { 0x00 };
500 struct i2c_msg msg [] = { { .addr = config->demod_address, .flags = 0, .buf = b0, .len = 1 },
501 { .addr = config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
502
503 /* allocate memory for the internal state */
504 state = (struct l64781_state*) kmalloc(sizeof(struct l64781_state), GFP_KERNEL);
505 if (state == NULL) goto error;
506
507 /* setup the state */
508 state->config = config;
509 state->i2c = i2c;
510 memcpy(&state->ops, &l64781_ops, sizeof(struct dvb_frontend_ops));
511 state->first = 1;
512
513 /**
514 * the L64781 won't show up before we send the reset_and_configure()
515 * broadcast. If nothing responds there is no L64781 on the bus...
516 */
517 if (reset_and_configure(state) < 0) {
518 dprintk("No response to reset and configure broadcast...\n");
519 goto error;
520 }
521
522 /* The chip always responds to reads */
523 if (i2c_transfer(state->i2c, msg, 2) != 2) {
524 dprintk("No response to read on I2C bus\n");
525 goto error;
526 }
527
528 /* Save current register contents for bailout */
529 reg0x3e = l64781_readreg(state, 0x3e);
530
531 /* Reading the POWER_DOWN register always returns 0 */
532 if (reg0x3e != 0) {
533 dprintk("Device doesn't look like L64781\n");
534 goto error;
535 }
536
537 /* Turn the chip off */
538 l64781_writereg (state, 0x3e, 0x5a);
539
540 /* Responds to all reads with 0 */
541 if (l64781_readreg(state, 0x1a) != 0) {
542 dprintk("Read 1 returned unexpcted value\n");
543 goto error;
544 }
545
546 /* Turn the chip on */
547 l64781_writereg (state, 0x3e, 0xa5);
548
549 /* Responds with register default value */
550 if (l64781_readreg(state, 0x1a) != 0xa1) {
551 dprintk("Read 2 returned unexpcted value\n");
552 goto error;
553 }
554
555 /* create dvb_frontend */
556 state->frontend.ops = &state->ops;
557 state->frontend.demodulator_priv = state;
558 return &state->frontend;
559
560error:
561 if (reg0x3e >= 0) l64781_writereg (state, 0x3e, reg0x3e); /* restore reg 0x3e */
562 kfree(state);
563 return NULL;
564}
565
566static struct dvb_frontend_ops l64781_ops = {
567
568 .info = {
569 .name = "LSI L64781 DVB-T",
570 .type = FE_OFDM,
571 /* .frequency_min = ???,*/
572 /* .frequency_max = ???,*/
573 .frequency_stepsize = 166666,
574 /* .frequency_tolerance = ???,*/
575 /* .symbol_rate_tolerance = ???,*/
576 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
577 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
578 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
579 FE_CAN_MUTE_TS
580 },
581
582 .release = l64781_release,
583
584 .init = l64781_init,
585 .sleep = l64781_sleep,
586
587 .set_frontend = apply_frontend_param,
588 .get_frontend = get_frontend,
589 .get_tune_settings = l64781_get_tune_settings,
590
591 .read_status = l64781_read_status,
592 .read_ber = l64781_read_ber,
593 .read_signal_strength = l64781_read_signal_strength,
594 .read_snr = l64781_read_snr,
595 .read_ucblocks = l64781_read_ucblocks,
596};
597
598MODULE_DESCRIPTION("LSI L64781 DVB-T Demodulator driver");
599MODULE_AUTHOR("Holger Waechtler, Marko Kohtala");
600MODULE_LICENSE("GPL");
601
602EXPORT_SYMBOL(l64781_attach);
diff --git a/drivers/media/dvb/frontends/l64781.h b/drivers/media/dvb/frontends/l64781.h
new file mode 100644
index 000000000000..7e30fb0fdfa7
--- /dev/null
+++ b/drivers/media/dvb/frontends/l64781.h
@@ -0,0 +1,42 @@
1/*
2 driver for LSI L64781 COFDM demodulator
3
4 Copyright (C) 2001 Holger Waechtler for Convergence Integrated Media GmbH
5 Marko Kohtala <marko.kohtala@luukku.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21*/
22
23#ifndef L64781_H
24#define L64781_H
25
26#include <linux/dvb/frontend.h>
27
28struct l64781_config
29{
30 /* the demodulator's i2c address */
31 u8 demod_address;
32
33 /* PLL maintenance */
34 int (*pll_init)(struct dvb_frontend* fe);
35 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
36};
37
38
39extern struct dvb_frontend* l64781_attach(const struct l64781_config* config,
40 struct i2c_adapter* i2c);
41
42#endif // L64781_H
diff --git a/drivers/media/dvb/frontends/mt312.c b/drivers/media/dvb/frontends/mt312.c
new file mode 100644
index 000000000000..176a22e3441b
--- /dev/null
+++ b/drivers/media/dvb/frontends/mt312.c
@@ -0,0 +1,729 @@
1/*
2 Driver for Zarlink VP310/MT312 Satellite Channel Decoder
3
4 Copyright (C) 2003 Andreas Oberritter <obi@linuxtv.org>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 References:
22 http://products.zarlink.com/product_profiles/MT312.htm
23 http://products.zarlink.com/product_profiles/SL1935.htm
24*/
25
26#include <linux/delay.h>
27#include <linux/errno.h>
28#include <linux/init.h>
29#include <linux/kernel.h>
30#include <linux/module.h>
31#include <linux/moduleparam.h>
32
33#include "dvb_frontend.h"
34#include "mt312_priv.h"
35#include "mt312.h"
36
37
38struct mt312_state {
39 struct i2c_adapter* i2c;
40 struct dvb_frontend_ops ops;
41 /* configuration settings */
42 const struct mt312_config* config;
43 struct dvb_frontend frontend;
44
45 u8 id;
46 u8 frequency;
47};
48
49static int debug;
50#define dprintk(args...) \
51 do { \
52 if (debug) printk(KERN_DEBUG "mt312: " args); \
53 } while (0)
54
55#define MT312_SYS_CLK 90000000UL /* 90 MHz */
56#define MT312_LPOWER_SYS_CLK 60000000UL /* 60 MHz */
57#define MT312_PLL_CLK 10000000UL /* 10 MHz */
58
59static int mt312_read(struct mt312_state* state, const enum mt312_reg_addr reg,
60 void *buf, const size_t count)
61{
62 int ret;
63 struct i2c_msg msg[2];
64 u8 regbuf[1] = { reg };
65
66 msg[0].addr = state->config->demod_address;
67 msg[0].flags = 0;
68 msg[0].buf = regbuf;
69 msg[0].len = 1;
70 msg[1].addr = state->config->demod_address;
71 msg[1].flags = I2C_M_RD;
72 msg[1].buf = buf;
73 msg[1].len = count;
74
75 ret = i2c_transfer(state->i2c, msg, 2);
76
77 if (ret != 2) {
78 printk(KERN_ERR "%s: ret == %d\n", __FUNCTION__, ret);
79 return -EREMOTEIO;
80 }
81
82 if(debug) {
83 int i;
84 dprintk("R(%d):", reg & 0x7f);
85 for (i = 0; i < count; i++)
86 printk(" %02x", ((const u8 *) buf)[i]);
87 printk("\n");
88 }
89
90 return 0;
91}
92
93static int mt312_write(struct mt312_state* state, const enum mt312_reg_addr reg,
94 const void *src, const size_t count)
95{
96 int ret;
97 u8 buf[count + 1];
98 struct i2c_msg msg;
99
100 if(debug) {
101 int i;
102 dprintk("W(%d):", reg & 0x7f);
103 for (i = 0; i < count; i++)
104 printk(" %02x", ((const u8 *) src)[i]);
105 printk("\n");
106 }
107
108 buf[0] = reg;
109 memcpy(&buf[1], src, count);
110
111 msg.addr = state->config->demod_address;
112 msg.flags = 0;
113 msg.buf = buf;
114 msg.len = count + 1;
115
116 ret = i2c_transfer(state->i2c, &msg, 1);
117
118 if (ret != 1) {
119 dprintk("%s: ret == %d\n", __FUNCTION__, ret);
120 return -EREMOTEIO;
121 }
122
123 return 0;
124}
125
126static inline int mt312_readreg(struct mt312_state* state,
127 const enum mt312_reg_addr reg, u8 *val)
128{
129 return mt312_read(state, reg, val, 1);
130}
131
132static inline int mt312_writereg(struct mt312_state* state,
133 const enum mt312_reg_addr reg, const u8 val)
134{
135 return mt312_write(state, reg, &val, 1);
136}
137
138static inline u32 mt312_div(u32 a, u32 b)
139{
140 return (a + (b / 2)) / b;
141}
142
143static int mt312_reset(struct mt312_state* state, const u8 full)
144{
145 return mt312_writereg(state, RESET, full ? 0x80 : 0x40);
146}
147
148static int mt312_get_inversion(struct mt312_state* state,
149 fe_spectral_inversion_t *i)
150{
151 int ret;
152 u8 vit_mode;
153
154 if ((ret = mt312_readreg(state, VIT_MODE, &vit_mode)) < 0)
155 return ret;
156
157 if (vit_mode & 0x80) /* auto inversion was used */
158 *i = (vit_mode & 0x40) ? INVERSION_ON : INVERSION_OFF;
159
160 return 0;
161}
162
163static int mt312_get_symbol_rate(struct mt312_state* state, u32 *sr)
164{
165 int ret;
166 u8 sym_rate_h;
167 u8 dec_ratio;
168 u16 sym_rat_op;
169 u16 monitor;
170 u8 buf[2];
171
172 if ((ret = mt312_readreg(state, SYM_RATE_H, &sym_rate_h)) < 0)
173 return ret;
174
175 if (sym_rate_h & 0x80) { /* symbol rate search was used */
176 if ((ret = mt312_writereg(state, MON_CTRL, 0x03)) < 0)
177 return ret;
178
179 if ((ret = mt312_read(state, MONITOR_H, buf, sizeof(buf))) < 0)
180 return ret;
181
182 monitor = (buf[0] << 8) | buf[1];
183
184 dprintk(KERN_DEBUG "sr(auto) = %u\n",
185 mt312_div(monitor * 15625, 4));
186 } else {
187 if ((ret = mt312_writereg(state, MON_CTRL, 0x05)) < 0)
188 return ret;
189
190 if ((ret = mt312_read(state, MONITOR_H, buf, sizeof(buf))) < 0)
191 return ret;
192
193 dec_ratio = ((buf[0] >> 5) & 0x07) * 32;
194
195 if ((ret = mt312_read(state, SYM_RAT_OP_H, buf, sizeof(buf))) < 0)
196 return ret;
197
198 sym_rat_op = (buf[0] << 8) | buf[1];
199
200 dprintk(KERN_DEBUG "sym_rat_op=%d dec_ratio=%d\n",
201 sym_rat_op, dec_ratio);
202 dprintk(KERN_DEBUG "*sr(manual) = %lu\n",
203 (((MT312_PLL_CLK * 8192) / (sym_rat_op + 8192)) *
204 2) - dec_ratio);
205 }
206
207 return 0;
208}
209
210static int mt312_get_code_rate(struct mt312_state* state, fe_code_rate_t *cr)
211{
212 const fe_code_rate_t fec_tab[8] =
213 { FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_6_7, FEC_7_8,
214 FEC_AUTO, FEC_AUTO };
215
216 int ret;
217 u8 fec_status;
218
219 if ((ret = mt312_readreg(state, FEC_STATUS, &fec_status)) < 0)
220 return ret;
221
222 *cr = fec_tab[(fec_status >> 4) & 0x07];
223
224 return 0;
225}
226
227static int mt312_initfe(struct dvb_frontend* fe)
228{
229 struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
230 int ret;
231 u8 buf[2];
232
233 /* wake up */
234 if ((ret = mt312_writereg(state, CONFIG, (state->frequency == 60 ? 0x88 : 0x8c))) < 0)
235 return ret;
236
237 /* wait at least 150 usec */
238 udelay(150);
239
240 /* full reset */
241 if ((ret = mt312_reset(state, 1)) < 0)
242 return ret;
243
244// Per datasheet, write correct values. 09/28/03 ACCJr.
245// If we don't do this, we won't get FE_HAS_VITERBI in the VP310.
246 {
247 u8 buf_def[8]={0x14, 0x12, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00};
248
249 if ((ret = mt312_write(state, VIT_SETUP, buf_def, sizeof(buf_def))) < 0)
250 return ret;
251 }
252
253 /* SYS_CLK */
254 buf[0] = mt312_div((state->frequency == 60 ? MT312_LPOWER_SYS_CLK : MT312_SYS_CLK) * 2, 1000000);
255
256 /* DISEQC_RATIO */
257 buf[1] = mt312_div(MT312_PLL_CLK, 15000 * 4);
258
259 if ((ret = mt312_write(state, SYS_CLK, buf, sizeof(buf))) < 0)
260 return ret;
261
262 if ((ret = mt312_writereg(state, SNR_THS_HIGH, 0x32)) < 0)
263 return ret;
264
265 if ((ret = mt312_writereg(state, OP_CTRL, 0x53)) < 0)
266 return ret;
267
268 /* TS_SW_LIM */
269 buf[0] = 0x8c;
270 buf[1] = 0x98;
271
272 if ((ret = mt312_write(state, TS_SW_LIM_L, buf, sizeof(buf))) < 0)
273 return ret;
274
275 if ((ret = mt312_writereg(state, CS_SW_LIM, 0x69)) < 0)
276 return ret;
277
278 if (state->config->pll_init) {
279 mt312_writereg(state, GPP_CTRL, 0x40);
280 state->config->pll_init(fe);
281 mt312_writereg(state, GPP_CTRL, 0x00);
282 }
283
284 return 0;
285}
286
287static int mt312_send_master_cmd(struct dvb_frontend* fe,
288 struct dvb_diseqc_master_cmd *c)
289{
290 struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
291 int ret;
292 u8 diseqc_mode;
293
294 if ((c->msg_len == 0) || (c->msg_len > sizeof(c->msg)))
295 return -EINVAL;
296
297 if ((ret = mt312_readreg(state, DISEQC_MODE, &diseqc_mode)) < 0)
298 return ret;
299
300 if ((ret =
301 mt312_write(state, (0x80 | DISEQC_INSTR), c->msg, c->msg_len)) < 0)
302 return ret;
303
304 if ((ret =
305 mt312_writereg(state, DISEQC_MODE,
306 (diseqc_mode & 0x40) | ((c->msg_len - 1) << 3)
307 | 0x04)) < 0)
308 return ret;
309
310 /* set DISEQC_MODE[2:0] to zero if a return message is expected */
311 if (c->msg[0] & 0x02)
312 if ((ret =
313 mt312_writereg(state, DISEQC_MODE, (diseqc_mode & 0x40))) < 0)
314 return ret;
315
316 return 0;
317}
318
319static int mt312_send_burst(struct dvb_frontend* fe, const fe_sec_mini_cmd_t c)
320{
321 struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
322 const u8 mini_tab[2] = { 0x02, 0x03 };
323
324 int ret;
325 u8 diseqc_mode;
326
327 if (c > SEC_MINI_B)
328 return -EINVAL;
329
330 if ((ret = mt312_readreg(state, DISEQC_MODE, &diseqc_mode)) < 0)
331 return ret;
332
333 if ((ret =
334 mt312_writereg(state, DISEQC_MODE,
335 (diseqc_mode & 0x40) | mini_tab[c])) < 0)
336 return ret;
337
338 return 0;
339}
340
341static int mt312_set_tone(struct dvb_frontend* fe, const fe_sec_tone_mode_t t)
342{
343 struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
344 const u8 tone_tab[2] = { 0x01, 0x00 };
345
346 int ret;
347 u8 diseqc_mode;
348
349 if (t > SEC_TONE_OFF)
350 return -EINVAL;
351
352 if ((ret = mt312_readreg(state, DISEQC_MODE, &diseqc_mode)) < 0)
353 return ret;
354
355 if ((ret =
356 mt312_writereg(state, DISEQC_MODE,
357 (diseqc_mode & 0x40) | tone_tab[t])) < 0)
358 return ret;
359
360 return 0;
361}
362
363static int mt312_set_voltage(struct dvb_frontend* fe, const fe_sec_voltage_t v)
364{
365 struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
366 const u8 volt_tab[3] = { 0x00, 0x40, 0x00 };
367
368 if (v > SEC_VOLTAGE_OFF)
369 return -EINVAL;
370
371 return mt312_writereg(state, DISEQC_MODE, volt_tab[v]);
372}
373
374static int mt312_read_status(struct dvb_frontend* fe, fe_status_t *s)
375{
376 struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
377 int ret;
378 u8 status[3];
379
380 *s = 0;
381
382 if ((ret = mt312_read(state, QPSK_STAT_H, status, sizeof(status))) < 0)
383 return ret;
384
385 dprintk(KERN_DEBUG "QPSK_STAT_H: 0x%02x, QPSK_STAT_L: 0x%02x, FEC_STATUS: 0x%02x\n", status[0], status[1], status[2]);
386
387 if (status[0] & 0xc0)
388 *s |= FE_HAS_SIGNAL; /* signal noise ratio */
389 if (status[0] & 0x04)
390 *s |= FE_HAS_CARRIER; /* qpsk carrier lock */
391 if (status[2] & 0x02)
392 *s |= FE_HAS_VITERBI; /* viterbi lock */
393 if (status[2] & 0x04)
394 *s |= FE_HAS_SYNC; /* byte align lock */
395 if (status[0] & 0x01)
396 *s |= FE_HAS_LOCK; /* qpsk lock */
397
398 return 0;
399}
400
401static int mt312_read_ber(struct dvb_frontend* fe, u32 *ber)
402{
403 struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
404 int ret;
405 u8 buf[3];
406
407 if ((ret = mt312_read(state, RS_BERCNT_H, buf, 3)) < 0)
408 return ret;
409
410 *ber = ((buf[0] << 16) | (buf[1] << 8) | buf[2]) * 64;
411
412 return 0;
413}
414
415static int mt312_read_signal_strength(struct dvb_frontend* fe, u16 *signal_strength)
416{
417 struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
418 int ret;
419 u8 buf[3];
420 u16 agc;
421 s16 err_db;
422
423 if ((ret = mt312_read(state, AGC_H, buf, sizeof(buf))) < 0)
424 return ret;
425
426 agc = (buf[0] << 6) | (buf[1] >> 2);
427 err_db = (s16) (((buf[1] & 0x03) << 14) | buf[2] << 6) >> 6;
428
429 *signal_strength = agc;
430
431 dprintk(KERN_DEBUG "agc=%08x err_db=%hd\n", agc, err_db);
432
433 return 0;
434}
435
436static int mt312_read_snr(struct dvb_frontend* fe, u16 *snr)
437{
438 struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
439 int ret;
440 u8 buf[2];
441
442 if ((ret = mt312_read(state, M_SNR_H, &buf, sizeof(buf))) < 0)
443 return ret;
444
445 *snr = 0xFFFF - ((((buf[0] & 0x7f) << 8) | buf[1]) << 1);
446
447 return 0;
448}
449
450static int mt312_read_ucblocks(struct dvb_frontend* fe, u32 *ubc)
451{
452 struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
453 int ret;
454 u8 buf[2];
455
456 if ((ret = mt312_read(state, RS_UBC_H, &buf, sizeof(buf))) < 0)
457 return ret;
458
459 *ubc = (buf[0] << 8) | buf[1];
460
461 return 0;
462}
463
464static int mt312_set_frontend(struct dvb_frontend* fe,
465 struct dvb_frontend_parameters *p)
466{
467 struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
468 int ret;
469 u8 buf[5], config_val;
470 u16 sr;
471
472 const u8 fec_tab[10] =
473 { 0x00, 0x01, 0x02, 0x04, 0x3f, 0x08, 0x10, 0x20, 0x3f, 0x3f };
474 const u8 inv_tab[3] = { 0x00, 0x40, 0x80 };
475
476 dprintk("%s: Freq %d\n", __FUNCTION__, p->frequency);
477
478 if ((p->frequency < fe->ops->info.frequency_min)
479 || (p->frequency > fe->ops->info.frequency_max))
480 return -EINVAL;
481
482 if ((p->inversion < INVERSION_OFF)
483 || (p->inversion > INVERSION_ON))
484 return -EINVAL;
485
486 if ((p->u.qpsk.symbol_rate < fe->ops->info.symbol_rate_min)
487 || (p->u.qpsk.symbol_rate > fe->ops->info.symbol_rate_max))
488 return -EINVAL;
489
490 if ((p->u.qpsk.fec_inner < FEC_NONE)
491 || (p->u.qpsk.fec_inner > FEC_AUTO))
492 return -EINVAL;
493
494 if ((p->u.qpsk.fec_inner == FEC_4_5)
495 || (p->u.qpsk.fec_inner == FEC_8_9))
496 return -EINVAL;
497
498 switch (state->id) {
499 case ID_VP310:
500 // For now we will do this only for the VP310.
501 // It should be better for the mt312 as well, but tunning will be slower. ACCJr 09/29/03
502 if ((ret = mt312_readreg(state, CONFIG, &config_val) < 0))
503 return ret;
504 if (p->u.qpsk.symbol_rate >= 30000000) //Note that 30MS/s should use 90MHz
505 {
506 if ((config_val & 0x0c) == 0x08) { //We are running 60MHz
507 state->frequency = 90;
508 if ((ret = mt312_initfe(fe)) < 0)
509 return ret;
510 }
511 }
512 else
513 {
514 if ((config_val & 0x0c) == 0x0C) { //We are running 90MHz
515 state->frequency = 60;
516 if ((ret = mt312_initfe(fe)) < 0)
517 return ret;
518 }
519 }
520 break;
521
522 case ID_MT312:
523 break;
524
525 default:
526 return -EINVAL;
527 }
528
529 mt312_writereg(state, GPP_CTRL, 0x40);
530 state->config->pll_set(fe, p);
531 mt312_writereg(state, GPP_CTRL, 0x00);
532
533 /* sr = (u16)(sr * 256.0 / 1000000.0) */
534 sr = mt312_div(p->u.qpsk.symbol_rate * 4, 15625);
535
536 /* SYM_RATE */
537 buf[0] = (sr >> 8) & 0x3f;
538 buf[1] = (sr >> 0) & 0xff;
539
540 /* VIT_MODE */
541 buf[2] = inv_tab[p->inversion] | fec_tab[p->u.qpsk.fec_inner];
542
543 /* QPSK_CTRL */
544 buf[3] = 0x40; /* swap I and Q before QPSK demodulation */
545
546 if (p->u.qpsk.symbol_rate < 10000000)
547 buf[3] |= 0x04; /* use afc mode */
548
549 /* GO */
550 buf[4] = 0x01;
551
552 if ((ret = mt312_write(state, SYM_RATE_H, buf, sizeof(buf))) < 0)
553 return ret;
554
555 mt312_reset(state, 0);
556
557 return 0;
558}
559
560static int mt312_get_frontend(struct dvb_frontend* fe,
561 struct dvb_frontend_parameters *p)
562{
563 struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
564 int ret;
565
566 if ((ret = mt312_get_inversion(state, &p->inversion)) < 0)
567 return ret;
568
569 if ((ret = mt312_get_symbol_rate(state, &p->u.qpsk.symbol_rate)) < 0)
570 return ret;
571
572 if ((ret = mt312_get_code_rate(state, &p->u.qpsk.fec_inner)) < 0)
573 return ret;
574
575 return 0;
576}
577
578static int mt312_sleep(struct dvb_frontend* fe)
579{
580 struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
581 int ret;
582 u8 config;
583
584 /* reset all registers to defaults */
585 if ((ret = mt312_reset(state, 1)) < 0)
586 return ret;
587
588 if ((ret = mt312_readreg(state, CONFIG, &config)) < 0)
589 return ret;
590
591 /* enter standby */
592 if ((ret = mt312_writereg(state, CONFIG, config & 0x7f)) < 0)
593 return ret;
594
595 return 0;
596}
597
598static int mt312_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
599{
600 fesettings->min_delay_ms = 50;
601 fesettings->step_size = 0;
602 fesettings->max_drift = 0;
603 return 0;
604}
605
606static void mt312_release(struct dvb_frontend* fe)
607{
608 struct mt312_state* state = (struct mt312_state*) fe->demodulator_priv;
609 kfree(state);
610}
611
612static struct dvb_frontend_ops vp310_mt312_ops;
613
614struct dvb_frontend* vp310_attach(const struct mt312_config* config,
615 struct i2c_adapter* i2c)
616{
617 struct mt312_state* state = NULL;
618
619 /* allocate memory for the internal state */
620 state = (struct mt312_state*) kmalloc(sizeof(struct mt312_state), GFP_KERNEL);
621 if (state == NULL)
622 goto error;
623
624 /* setup the state */
625 state->config = config;
626 state->i2c = i2c;
627 memcpy(&state->ops, &vp310_mt312_ops, sizeof(struct dvb_frontend_ops));
628 strcpy(state->ops.info.name, "Zarlink VP310 DVB-S");
629
630 /* check if the demod is there */
631 if (mt312_readreg(state, ID, &state->id) < 0)
632 goto error;
633 if (state->id != ID_VP310) {
634 goto error;
635 }
636
637 /* create dvb_frontend */
638 state->frequency = 90;
639 state->frontend.ops = &state->ops;
640 state->frontend.demodulator_priv = state;
641 return &state->frontend;
642
643error:
644 kfree(state);
645 return NULL;
646}
647
648struct dvb_frontend* mt312_attach(const struct mt312_config* config,
649 struct i2c_adapter* i2c)
650{
651 struct mt312_state* state = NULL;
652
653 /* allocate memory for the internal state */
654 state = (struct mt312_state*) kmalloc(sizeof(struct mt312_state), GFP_KERNEL);
655 if (state == NULL)
656 goto error;
657
658 /* setup the state */
659 state->config = config;
660 state->i2c = i2c;
661 memcpy(&state->ops, &vp310_mt312_ops, sizeof(struct dvb_frontend_ops));
662 strcpy(state->ops.info.name, "Zarlink MT312 DVB-S");
663
664 /* check if the demod is there */
665 if (mt312_readreg(state, ID, &state->id) < 0)
666 goto error;
667 if (state->id != ID_MT312) {
668 goto error;
669 }
670
671 /* create dvb_frontend */
672 state->frequency = 60;
673 state->frontend.ops = &state->ops;
674 state->frontend.demodulator_priv = state;
675 return &state->frontend;
676
677error:
678 if (state)
679 kfree(state);
680 return NULL;
681}
682
683static struct dvb_frontend_ops vp310_mt312_ops = {
684
685 .info = {
686 .name = "Zarlink ???? DVB-S",
687 .type = FE_QPSK,
688 .frequency_min = 950000,
689 .frequency_max = 2150000,
690 .frequency_stepsize = (MT312_PLL_CLK / 1000) / 128,
691 .symbol_rate_min = MT312_SYS_CLK / 128,
692 .symbol_rate_max = MT312_SYS_CLK / 2,
693 .caps =
694 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
695 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
696 FE_CAN_FEC_AUTO | FE_CAN_QPSK | FE_CAN_MUTE_TS |
697 FE_CAN_RECOVER
698 },
699
700 .release = mt312_release,
701
702 .init = mt312_initfe,
703 .sleep = mt312_sleep,
704
705 .set_frontend = mt312_set_frontend,
706 .get_frontend = mt312_get_frontend,
707 .get_tune_settings = mt312_get_tune_settings,
708
709 .read_status = mt312_read_status,
710 .read_ber = mt312_read_ber,
711 .read_signal_strength = mt312_read_signal_strength,
712 .read_snr = mt312_read_snr,
713 .read_ucblocks = mt312_read_ucblocks,
714
715 .diseqc_send_master_cmd = mt312_send_master_cmd,
716 .diseqc_send_burst = mt312_send_burst,
717 .set_tone = mt312_set_tone,
718 .set_voltage = mt312_set_voltage,
719};
720
721module_param(debug, int, 0644);
722MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
723
724MODULE_DESCRIPTION("Zarlink VP310/MT312 DVB-S Demodulator driver");
725MODULE_AUTHOR("Andreas Oberritter <obi@linuxtv.org>");
726MODULE_LICENSE("GPL");
727
728EXPORT_SYMBOL(mt312_attach);
729EXPORT_SYMBOL(vp310_attach);
diff --git a/drivers/media/dvb/frontends/mt312.h b/drivers/media/dvb/frontends/mt312.h
new file mode 100644
index 000000000000..b3a53a73a117
--- /dev/null
+++ b/drivers/media/dvb/frontends/mt312.h
@@ -0,0 +1,47 @@
1/*
2 Driver for Zarlink MT312 Satellite Channel Decoder
3
4 Copyright (C) 2003 Andreas Oberritter <obi@linuxtv.org>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 References:
22 http://products.zarlink.com/product_profiles/MT312.htm
23 http://products.zarlink.com/product_profiles/SL1935.htm
24*/
25
26#ifndef MT312_H
27#define MT312_H
28
29#include <linux/dvb/frontend.h>
30
31struct mt312_config
32{
33 /* the demodulator's i2c address */
34 u8 demod_address;
35
36 /* PLL maintenance */
37 int (*pll_init)(struct dvb_frontend* fe);
38 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
39};
40
41extern struct dvb_frontend* mt312_attach(const struct mt312_config* config,
42 struct i2c_adapter* i2c);
43
44extern struct dvb_frontend* vp310_attach(const struct mt312_config* config,
45 struct i2c_adapter* i2c);
46
47#endif // MT312_H
diff --git a/drivers/media/dvb/frontends/mt312_priv.h b/drivers/media/dvb/frontends/mt312_priv.h
new file mode 100644
index 000000000000..5e0b95b5337b
--- /dev/null
+++ b/drivers/media/dvb/frontends/mt312_priv.h
@@ -0,0 +1,162 @@
1/*
2 Driver for Zarlink MT312 QPSK Frontend
3
4 Copyright (C) 2003 Andreas Oberritter <obi@linuxtv.org>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21*/
22
23#ifndef _DVB_FRONTENDS_MT312_PRIV
24#define _DVB_FRONTENDS_MT312_PRIV
25
26enum mt312_reg_addr {
27 QPSK_INT_H = 0,
28 QPSK_INT_M = 1,
29 QPSK_INT_L = 2,
30 FEC_INT = 3,
31 QPSK_STAT_H = 4,
32 QPSK_STAT_L = 5,
33 FEC_STATUS = 6,
34 LNB_FREQ_H = 7,
35 LNB_FREQ_L = 8,
36 M_SNR_H = 9,
37 M_SNR_L = 10,
38 VIT_ERRCNT_H = 11,
39 VIT_ERRCNT_M = 12,
40 VIT_ERRCNT_L = 13,
41 RS_BERCNT_H = 14,
42 RS_BERCNT_M = 15,
43 RS_BERCNT_L = 16,
44 RS_UBC_H = 17,
45 RS_UBC_L = 18,
46 SIG_LEVEL = 19,
47 GPP_CTRL = 20,
48 RESET = 21,
49 DISEQC_MODE = 22,
50 SYM_RATE_H = 23,
51 SYM_RATE_L = 24,
52 VIT_MODE = 25,
53 QPSK_CTRL = 26,
54 GO = 27,
55 IE_QPSK_H = 28,
56 IE_QPSK_M = 29,
57 IE_QPSK_L = 30,
58 IE_FEC = 31,
59 QPSK_STAT_EN = 32,
60 FEC_STAT_EN = 33,
61 SYS_CLK = 34,
62 DISEQC_RATIO = 35,
63 DISEQC_INSTR = 36,
64 FR_LIM = 37,
65 FR_OFF = 38,
66 AGC_CTRL = 39,
67 AGC_INIT = 40,
68 AGC_REF = 41,
69 AGC_MAX = 42,
70 AGC_MIN = 43,
71 AGC_LK_TH = 44,
72 TS_AGC_LK_TH = 45,
73 AGC_PWR_SET = 46,
74 QPSK_MISC = 47,
75 SNR_THS_LOW = 48,
76 SNR_THS_HIGH = 49,
77 TS_SW_RATE = 50,
78 TS_SW_LIM_L = 51,
79 TS_SW_LIM_H = 52,
80 CS_SW_RATE_1 = 53,
81 CS_SW_RATE_2 = 54,
82 CS_SW_RATE_3 = 55,
83 CS_SW_RATE_4 = 56,
84 CS_SW_LIM = 57,
85 TS_LPK = 58,
86 TS_LPK_M = 59,
87 TS_LPK_L = 60,
88 CS_KPROP_H = 61,
89 CS_KPROP_L = 62,
90 CS_KINT_H = 63,
91 CS_KINT_L = 64,
92 QPSK_SCALE = 65,
93 TLD_OUTCLK_TH = 66,
94 TLD_INCLK_TH = 67,
95 FLD_TH = 68,
96 PLD_OUTLK3 = 69,
97 PLD_OUTLK2 = 70,
98 PLD_OUTLK1 = 71,
99 PLD_OUTLK0 = 72,
100 PLD_INLK3 = 73,
101 PLD_INLK2 = 74,
102 PLD_INLK1 = 75,
103 PLD_INLK0 = 76,
104 PLD_ACC_TIME = 77,
105 SWEEP_PAR = 78,
106 STARTUP_TIME = 79,
107 LOSSLOCK_TH = 80,
108 FEC_LOCK_TM = 81,
109 LOSSLOCK_TM = 82,
110 VIT_ERRPER_H = 83,
111 VIT_ERRPER_M = 84,
112 VIT_ERRPER_L = 85,
113 VIT_SETUP = 86,
114 VIT_REF0 = 87,
115 VIT_REF1 = 88,
116 VIT_REF2 = 89,
117 VIT_REF3 = 90,
118 VIT_REF4 = 91,
119 VIT_REF5 = 92,
120 VIT_REF6 = 93,
121 VIT_MAXERR = 94,
122 BA_SETUPT = 95,
123 OP_CTRL = 96,
124 FEC_SETUP = 97,
125 PROG_SYNC = 98,
126 AFC_SEAR_TH = 99,
127 CSACC_DIF_TH = 100,
128 QPSK_LK_CT = 101,
129 QPSK_ST_CT = 102,
130 MON_CTRL = 103,
131 QPSK_RESET = 104,
132 QPSK_TST_CT = 105,
133 QPSK_TST_ST = 106,
134 TEST_R = 107,
135 AGC_H = 108,
136 AGC_M = 109,
137 AGC_L = 110,
138 FREQ_ERR1_H = 111,
139 FREQ_ERR1_M = 112,
140 FREQ_ERR1_L = 113,
141 FREQ_ERR2_H = 114,
142 FREQ_ERR2_L = 115,
143 SYM_RAT_OP_H = 116,
144 SYM_RAT_OP_L = 117,
145 DESEQC2_INT = 118,
146 DISEQC2_STAT = 119,
147 DISEQC2_FIFO = 120,
148 DISEQC2_CTRL1 = 121,
149 DISEQC2_CTRL2 = 122,
150 MONITOR_H = 123,
151 MONITOR_L = 124,
152 TEST_MODE = 125,
153 ID = 126,
154 CONFIG = 127
155};
156
157enum mt312_model_id {
158 ID_VP310 = 1,
159 ID_MT312 = 3
160};
161
162#endif /* DVB_FRONTENDS_MT312_PRIV */
diff --git a/drivers/media/dvb/frontends/mt352.c b/drivers/media/dvb/frontends/mt352.c
new file mode 100644
index 000000000000..50326c7248fa
--- /dev/null
+++ b/drivers/media/dvb/frontends/mt352.c
@@ -0,0 +1,610 @@
1/*
2 * Driver for Zarlink DVB-T MT352 demodulator
3 *
4 * Written by Holger Waechtler <holger@qanu.de>
5 * and Daniel Mack <daniel@qanu.de>
6 *
7 * AVerMedia AVerTV DVB-T 771 support by
8 * Wolfram Joost <dbox2@frokaschwei.de>
9 *
10 * Support for Samsung TDTC9251DH01C(M) tuner
11 * Copyright (C) 2004 Antonio Mancuso <antonio.mancuso@digitaltelevision.it>
12 * Amauri Celani <acelani@essegi.net>
13 *
14 * DVICO FusionHDTV DVB-T1 and DVICO FusionHDTV DVB-T Lite support by
15 * Christopher Pascoe <c.pascoe@itee.uq.edu.au>
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 *
26 * GNU General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
31 */
32
33#include <linux/kernel.h>
34#include <linux/module.h>
35#include <linux/moduleparam.h>
36#include <linux/init.h>
37#include <linux/delay.h>
38
39#include "dvb_frontend.h"
40#include "mt352_priv.h"
41#include "mt352.h"
42
43struct mt352_state {
44 struct i2c_adapter* i2c;
45 struct dvb_frontend frontend;
46 struct dvb_frontend_ops ops;
47
48 /* configuration settings */
49 const struct mt352_config* config;
50};
51
52static int debug;
53#define dprintk(args...) \
54 do { \
55 if (debug) printk(KERN_DEBUG "mt352: " args); \
56 } while (0)
57
58static int mt352_single_write(struct dvb_frontend *fe, u8 reg, u8 val)
59{
60 struct mt352_state* state = fe->demodulator_priv;
61 u8 buf[2] = { reg, val };
62 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0,
63 .buf = buf, .len = 2 };
64 int err = i2c_transfer(state->i2c, &msg, 1);
65 if (err != 1) {
66 printk("mt352_write() to reg %x failed (err = %d)!\n", reg, err);
67 return err;
68 }
69 return 0;
70}
71
72int mt352_write(struct dvb_frontend* fe, u8* ibuf, int ilen)
73{
74 int err,i;
75 for (i=0; i < ilen-1; i++)
76 if ((err = mt352_single_write(fe,ibuf[0]+i,ibuf[i+1])))
77 return err;
78
79 return 0;
80}
81
82static int mt352_read_register(struct mt352_state* state, u8 reg)
83{
84 int ret;
85 u8 b0 [] = { reg };
86 u8 b1 [] = { 0 };
87 struct i2c_msg msg [] = { { .addr = state->config->demod_address,
88 .flags = 0,
89 .buf = b0, .len = 1 },
90 { .addr = state->config->demod_address,
91 .flags = I2C_M_RD,
92 .buf = b1, .len = 1 } };
93
94 ret = i2c_transfer(state->i2c, msg, 2);
95
96 if (ret != 2) {
97 printk("%s: readreg error (reg=%d, ret==%i)\n",
98 __FUNCTION__, reg, ret);
99 return ret;
100 }
101
102 return b1[0];
103}
104
105int mt352_read(struct dvb_frontend *fe, u8 reg)
106{
107 return mt352_read_register(fe->demodulator_priv,reg);
108}
109
110static int mt352_sleep(struct dvb_frontend* fe)
111{
112 static u8 mt352_softdown[] = { CLOCK_CTL, 0x20, 0x08 };
113
114 mt352_write(fe, mt352_softdown, sizeof(mt352_softdown));
115 return 0;
116}
117
118static void mt352_calc_nominal_rate(struct mt352_state* state,
119 enum fe_bandwidth bandwidth,
120 unsigned char *buf)
121{
122 u32 adc_clock = 20480; /* 20.340 MHz */
123 u32 bw,value;
124
125 switch (bandwidth) {
126 case BANDWIDTH_6_MHZ:
127 bw = 6;
128 break;
129 case BANDWIDTH_7_MHZ:
130 bw = 7;
131 break;
132 case BANDWIDTH_8_MHZ:
133 default:
134 bw = 8;
135 break;
136 }
137 if (state->config->adc_clock)
138 adc_clock = state->config->adc_clock;
139
140 value = 64 * bw * (1<<16) / (7 * 8);
141 value = value * 1000 / adc_clock;
142 dprintk("%s: bw %d, adc_clock %d => 0x%x\n",
143 __FUNCTION__, bw, adc_clock, value);
144 buf[0] = msb(value);
145 buf[1] = lsb(value);
146}
147
148static void mt352_calc_input_freq(struct mt352_state* state,
149 unsigned char *buf)
150{
151 int adc_clock = 20480; /* 20.480000 MHz */
152 int if2 = 36167; /* 36.166667 MHz */
153 int ife,value;
154
155 if (state->config->adc_clock)
156 adc_clock = state->config->adc_clock;
157 if (state->config->if2)
158 if2 = state->config->if2;
159
160 ife = (2*adc_clock - if2);
161 value = -16374 * ife / adc_clock;
162 dprintk("%s: if2 %d, ife %d, adc_clock %d => %d / 0x%x\n",
163 __FUNCTION__, if2, ife, adc_clock, value, value & 0x3fff);
164 buf[0] = msb(value);
165 buf[1] = lsb(value);
166}
167
168static int mt352_set_parameters(struct dvb_frontend* fe,
169 struct dvb_frontend_parameters *param)
170{
171 struct mt352_state* state = fe->demodulator_priv;
172 unsigned char buf[13];
173 static unsigned char tuner_go[] = { 0x5d, 0x01 };
174 static unsigned char fsm_go[] = { 0x5e, 0x01 };
175 unsigned int tps = 0;
176 struct dvb_ofdm_parameters *op = &param->u.ofdm;
177
178 switch (op->code_rate_HP) {
179 case FEC_2_3:
180 tps |= (1 << 7);
181 break;
182 case FEC_3_4:
183 tps |= (2 << 7);
184 break;
185 case FEC_5_6:
186 tps |= (3 << 7);
187 break;
188 case FEC_7_8:
189 tps |= (4 << 7);
190 break;
191 case FEC_1_2:
192 case FEC_AUTO:
193 break;
194 default:
195 return -EINVAL;
196 }
197
198 switch (op->code_rate_LP) {
199 case FEC_2_3:
200 tps |= (1 << 4);
201 break;
202 case FEC_3_4:
203 tps |= (2 << 4);
204 break;
205 case FEC_5_6:
206 tps |= (3 << 4);
207 break;
208 case FEC_7_8:
209 tps |= (4 << 4);
210 break;
211 case FEC_1_2:
212 case FEC_AUTO:
213 break;
214 case FEC_NONE:
215 if (op->hierarchy_information == HIERARCHY_AUTO ||
216 op->hierarchy_information == HIERARCHY_NONE)
217 break;
218 default:
219 return -EINVAL;
220 }
221
222 switch (op->constellation) {
223 case QPSK:
224 break;
225 case QAM_AUTO:
226 case QAM_16:
227 tps |= (1 << 13);
228 break;
229 case QAM_64:
230 tps |= (2 << 13);
231 break;
232 default:
233 return -EINVAL;
234 }
235
236 switch (op->transmission_mode) {
237 case TRANSMISSION_MODE_2K:
238 case TRANSMISSION_MODE_AUTO:
239 break;
240 case TRANSMISSION_MODE_8K:
241 tps |= (1 << 0);
242 break;
243 default:
244 return -EINVAL;
245 }
246
247 switch (op->guard_interval) {
248 case GUARD_INTERVAL_1_32:
249 case GUARD_INTERVAL_AUTO:
250 break;
251 case GUARD_INTERVAL_1_16:
252 tps |= (1 << 2);
253 break;
254 case GUARD_INTERVAL_1_8:
255 tps |= (2 << 2);
256 break;
257 case GUARD_INTERVAL_1_4:
258 tps |= (3 << 2);
259 break;
260 default:
261 return -EINVAL;
262 }
263
264 switch (op->hierarchy_information) {
265 case HIERARCHY_AUTO:
266 case HIERARCHY_NONE:
267 break;
268 case HIERARCHY_1:
269 tps |= (1 << 10);
270 break;
271 case HIERARCHY_2:
272 tps |= (2 << 10);
273 break;
274 case HIERARCHY_4:
275 tps |= (3 << 10);
276 break;
277 default:
278 return -EINVAL;
279 }
280
281
282 buf[0] = TPS_GIVEN_1; /* TPS_GIVEN_1 and following registers */
283
284 buf[1] = msb(tps); /* TPS_GIVEN_(1|0) */
285 buf[2] = lsb(tps);
286
287 buf[3] = 0x50; // old
288// buf[3] = 0xf4; // pinnacle
289
290 mt352_calc_nominal_rate(state, op->bandwidth, buf+4);
291 mt352_calc_input_freq(state, buf+6);
292 state->config->pll_set(fe, param, buf+8);
293
294 mt352_write(fe, buf, sizeof(buf));
295 if (state->config->no_tuner) {
296 /* start decoding */
297 mt352_write(fe, fsm_go, 2);
298 } else {
299 /* start tuning */
300 mt352_write(fe, tuner_go, 2);
301 }
302 return 0;
303}
304
305static int mt352_get_parameters(struct dvb_frontend* fe,
306 struct dvb_frontend_parameters *param)
307{
308 struct mt352_state* state = fe->demodulator_priv;
309 u16 tps;
310 u16 div;
311 u8 trl;
312 struct dvb_ofdm_parameters *op = &param->u.ofdm;
313 static const u8 tps_fec_to_api[8] =
314 {
315 FEC_1_2,
316 FEC_2_3,
317 FEC_3_4,
318 FEC_5_6,
319 FEC_7_8,
320 FEC_AUTO,
321 FEC_AUTO,
322 FEC_AUTO
323 };
324
325 if ( (mt352_read_register(state,0x00) & 0xC0) != 0xC0 )
326 return -EINVAL;
327
328 /* Use TPS_RECEIVED-registers, not the TPS_CURRENT-registers because
329 * the mt352 sometimes works with the wrong parameters
330 */
331 tps = (mt352_read_register(state, TPS_RECEIVED_1) << 8) | mt352_read_register(state, TPS_RECEIVED_0);
332 div = (mt352_read_register(state, CHAN_START_1) << 8) | mt352_read_register(state, CHAN_START_0);
333 trl = mt352_read_register(state, TRL_NOMINAL_RATE_1);
334
335 op->code_rate_HP = tps_fec_to_api[(tps >> 7) & 7];
336 op->code_rate_LP = tps_fec_to_api[(tps >> 4) & 7];
337
338 switch ( (tps >> 13) & 3)
339 {
340 case 0:
341 op->constellation = QPSK;
342 break;
343 case 1:
344 op->constellation = QAM_16;
345 break;
346 case 2:
347 op->constellation = QAM_64;
348 break;
349 default:
350 op->constellation = QAM_AUTO;
351 break;
352 }
353
354 op->transmission_mode = (tps & 0x01) ? TRANSMISSION_MODE_8K : TRANSMISSION_MODE_2K;
355
356 switch ( (tps >> 2) & 3)
357 {
358 case 0:
359 op->guard_interval = GUARD_INTERVAL_1_32;
360 break;
361 case 1:
362 op->guard_interval = GUARD_INTERVAL_1_16;
363 break;
364 case 2:
365 op->guard_interval = GUARD_INTERVAL_1_8;
366 break;
367 case 3:
368 op->guard_interval = GUARD_INTERVAL_1_4;
369 break;
370 default:
371 op->guard_interval = GUARD_INTERVAL_AUTO;
372 break;
373 }
374
375 switch ( (tps >> 10) & 7)
376 {
377 case 0:
378 op->hierarchy_information = HIERARCHY_NONE;
379 break;
380 case 1:
381 op->hierarchy_information = HIERARCHY_1;
382 break;
383 case 2:
384 op->hierarchy_information = HIERARCHY_2;
385 break;
386 case 3:
387 op->hierarchy_information = HIERARCHY_4;
388 break;
389 default:
390 op->hierarchy_information = HIERARCHY_AUTO;
391 break;
392 }
393
394 param->frequency = ( 500 * (div - IF_FREQUENCYx6) ) / 3 * 1000;
395
396 if (trl == 0x72)
397 op->bandwidth = BANDWIDTH_8_MHZ;
398 else if (trl == 0x64)
399 op->bandwidth = BANDWIDTH_7_MHZ;
400 else
401 op->bandwidth = BANDWIDTH_6_MHZ;
402
403
404 if (mt352_read_register(state, STATUS_2) & 0x02)
405 param->inversion = INVERSION_OFF;
406 else
407 param->inversion = INVERSION_ON;
408
409 return 0;
410}
411
412static int mt352_read_status(struct dvb_frontend* fe, fe_status_t* status)
413{
414 struct mt352_state* state = fe->demodulator_priv;
415 int s0, s1, s3;
416
417 /* FIXME:
418 *
419 * The MT352 design manual from Zarlink states (page 46-47):
420 *
421 * Notes about the TUNER_GO register:
422 *
423 * If the Read_Tuner_Byte (bit-1) is activated, then the tuner status
424 * byte is copied from the tuner to the STATUS_3 register and
425 * completion of the read operation is indicated by bit-5 of the
426 * INTERRUPT_3 register.
427 */
428
429 if ((s0 = mt352_read_register(state, STATUS_0)) < 0)
430 return -EREMOTEIO;
431 if ((s1 = mt352_read_register(state, STATUS_1)) < 0)
432 return -EREMOTEIO;
433 if ((s3 = mt352_read_register(state, STATUS_3)) < 0)
434 return -EREMOTEIO;
435
436 *status = 0;
437 if (s0 & (1 << 4))
438 *status |= FE_HAS_CARRIER;
439 if (s0 & (1 << 1))
440 *status |= FE_HAS_VITERBI;
441 if (s0 & (1 << 5))
442 *status |= FE_HAS_LOCK;
443 if (s1 & (1 << 1))
444 *status |= FE_HAS_SYNC;
445 if (s3 & (1 << 6))
446 *status |= FE_HAS_SIGNAL;
447
448 if ((*status & (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) !=
449 (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC))
450 *status &= ~FE_HAS_LOCK;
451
452 return 0;
453}
454
455static int mt352_read_ber(struct dvb_frontend* fe, u32* ber)
456{
457 struct mt352_state* state = fe->demodulator_priv;
458
459 *ber = (mt352_read_register (state, RS_ERR_CNT_2) << 16) |
460 (mt352_read_register (state, RS_ERR_CNT_1) << 8) |
461 (mt352_read_register (state, RS_ERR_CNT_0));
462
463 return 0;
464}
465
466static int mt352_read_signal_strength(struct dvb_frontend* fe, u16* strength)
467{
468 struct mt352_state* state = fe->demodulator_priv;
469
470 u16 signal = ((mt352_read_register(state, AGC_GAIN_1) << 8) & 0x0f) |
471 (mt352_read_register(state, AGC_GAIN_0));
472
473 *strength = ~signal;
474 return 0;
475}
476
477static int mt352_read_snr(struct dvb_frontend* fe, u16* snr)
478{
479 struct mt352_state* state = fe->demodulator_priv;
480
481 u8 _snr = mt352_read_register (state, SNR);
482 *snr = (_snr << 8) | _snr;
483
484 return 0;
485}
486
487static int mt352_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
488{
489 struct mt352_state* state = fe->demodulator_priv;
490
491 *ucblocks = (mt352_read_register (state, RS_UBC_1) << 8) |
492 (mt352_read_register (state, RS_UBC_0));
493
494 return 0;
495}
496
497static int mt352_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fe_tune_settings)
498{
499 fe_tune_settings->min_delay_ms = 800;
500 fe_tune_settings->step_size = 0;
501 fe_tune_settings->max_drift = 0;
502
503 return 0;
504}
505
506static int mt352_init(struct dvb_frontend* fe)
507{
508 struct mt352_state* state = fe->demodulator_priv;
509
510 static u8 mt352_reset_attach [] = { RESET, 0xC0 };
511
512 dprintk("%s: hello\n",__FUNCTION__);
513
514 if ((mt352_read_register(state, CLOCK_CTL) & 0x10) == 0 ||
515 (mt352_read_register(state, CONFIG) & 0x20) == 0) {
516
517 /* Do a "hard" reset */
518 mt352_write(fe, mt352_reset_attach, sizeof(mt352_reset_attach));
519 return state->config->demod_init(fe);
520 }
521
522 return 0;
523}
524
525static void mt352_release(struct dvb_frontend* fe)
526{
527 struct mt352_state* state = fe->demodulator_priv;
528 kfree(state);
529}
530
531static struct dvb_frontend_ops mt352_ops;
532
533struct dvb_frontend* mt352_attach(const struct mt352_config* config,
534 struct i2c_adapter* i2c)
535{
536 struct mt352_state* state = NULL;
537
538 /* allocate memory for the internal state */
539 state = kmalloc(sizeof(struct mt352_state), GFP_KERNEL);
540 if (state == NULL) goto error;
541 memset(state,0,sizeof(*state));
542
543 /* setup the state */
544 state->config = config;
545 state->i2c = i2c;
546 memcpy(&state->ops, &mt352_ops, sizeof(struct dvb_frontend_ops));
547
548 /* check if the demod is there */
549 if (mt352_read_register(state, CHIP_ID) != ID_MT352) goto error;
550
551 /* create dvb_frontend */
552 state->frontend.ops = &state->ops;
553 state->frontend.demodulator_priv = state;
554 return &state->frontend;
555
556error:
557 kfree(state);
558 return NULL;
559}
560
561static struct dvb_frontend_ops mt352_ops = {
562
563 .info = {
564 .name = "Zarlink MT352 DVB-T",
565 .type = FE_OFDM,
566 .frequency_min = 174000000,
567 .frequency_max = 862000000,
568 .frequency_stepsize = 166667,
569 .frequency_tolerance = 0,
570 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
571 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
572 FE_CAN_FEC_AUTO |
573 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
574 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
575 FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER |
576 FE_CAN_MUTE_TS
577 },
578
579 .release = mt352_release,
580
581 .init = mt352_init,
582 .sleep = mt352_sleep,
583
584 .set_frontend = mt352_set_parameters,
585 .get_frontend = mt352_get_parameters,
586 .get_tune_settings = mt352_get_tune_settings,
587
588 .read_status = mt352_read_status,
589 .read_ber = mt352_read_ber,
590 .read_signal_strength = mt352_read_signal_strength,
591 .read_snr = mt352_read_snr,
592 .read_ucblocks = mt352_read_ucblocks,
593};
594
595module_param(debug, int, 0644);
596MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
597
598MODULE_DESCRIPTION("Zarlink MT352 DVB-T Demodulator driver");
599MODULE_AUTHOR("Holger Waechtler, Daniel Mack, Antonio Mancuso");
600MODULE_LICENSE("GPL");
601
602EXPORT_SYMBOL(mt352_attach);
603EXPORT_SYMBOL(mt352_write);
604EXPORT_SYMBOL(mt352_read);
605/*
606 * Local variables:
607 * c-basic-offset: 8
608 * compile-command: "make DVB=1"
609 * End:
610 */
diff --git a/drivers/media/dvb/frontends/mt352.h b/drivers/media/dvb/frontends/mt352.h
new file mode 100644
index 000000000000..f5d8a5aed8a9
--- /dev/null
+++ b/drivers/media/dvb/frontends/mt352.h
@@ -0,0 +1,72 @@
1/*
2 * Driver for Zarlink DVB-T MT352 demodulator
3 *
4 * Written by Holger Waechtler <holger@qanu.de>
5 * and Daniel Mack <daniel@qanu.de>
6 *
7 * AVerMedia AVerTV DVB-T 771 support by
8 * Wolfram Joost <dbox2@frokaschwei.de>
9 *
10 * Support for Samsung TDTC9251DH01C(M) tuner
11 * Copyright (C) 2004 Antonio Mancuso <antonio.mancuso@digitaltelevision.it>
12 * Amauri Celani <acelani@essegi.net>
13 *
14 * DVICO FusionHDTV DVB-T1 and DVICO FusionHDTV DVB-T Lite support by
15 * Christopher Pascoe <c.pascoe@itee.uq.edu.au>
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 *
26 * GNU General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
31 */
32
33#ifndef MT352_H
34#define MT352_H
35
36#include <linux/dvb/frontend.h>
37
38struct mt352_config
39{
40 /* the demodulator's i2c address */
41 u8 demod_address;
42
43 /* frequencies in kHz */
44 int adc_clock; // default: 20480
45 int if2; // default: 36166
46
47 /* set if no pll is connected to the secondary i2c bus */
48 int no_tuner;
49
50 /* Initialise the demodulator and PLL. Cannot be NULL */
51 int (*demod_init)(struct dvb_frontend* fe);
52
53 /* PLL setup - fill out the supplied 5 byte buffer with your PLL settings.
54 * byte0: Set to pll i2c address (nonlinux; left shifted by 1)
55 * byte1-4: PLL configuration.
56 */
57 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf);
58};
59
60extern struct dvb_frontend* mt352_attach(const struct mt352_config* config,
61 struct i2c_adapter* i2c);
62
63extern int mt352_write(struct dvb_frontend* fe, u8* ibuf, int ilen);
64extern int mt352_read(struct dvb_frontend *fe, u8 reg);
65
66#endif // MT352_H
67
68/*
69 * Local variables:
70 * c-basic-offset: 8
71 * End:
72 */
diff --git a/drivers/media/dvb/frontends/mt352_priv.h b/drivers/media/dvb/frontends/mt352_priv.h
new file mode 100644
index 000000000000..44ad0d4c8f12
--- /dev/null
+++ b/drivers/media/dvb/frontends/mt352_priv.h
@@ -0,0 +1,127 @@
1/*
2 * Driver for Zarlink DVB-T MT352 demodulator
3 *
4 * Written by Holger Waechtler <holger@qanu.de>
5 * and Daniel Mack <daniel@qanu.de>
6 *
7 * AVerMedia AVerTV DVB-T 771 support by
8 * Wolfram Joost <dbox2@frokaschwei.de>
9 *
10 * Support for Samsung TDTC9251DH01C(M) tuner
11 * Copyright (C) 2004 Antonio Mancuso <antonio.mancuso@digitaltelevision.it>
12 * Amauri Celani <acelani@essegi.net>
13 *
14 * DVICO FusionHDTV DVB-T1 and DVICO FusionHDTV DVB-T Lite support by
15 * Christopher Pascoe <c.pascoe@itee.uq.edu.au>
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 *
26 * GNU General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
31 */
32
33#ifndef _MT352_PRIV_
34#define _MT352_PRIV_
35
36#define ID_MT352 0x13
37
38#define msb(x) (((x) >> 8) & 0xff)
39#define lsb(x) ((x) & 0xff)
40
41enum mt352_reg_addr {
42 STATUS_0 = 0x00,
43 STATUS_1 = 0x01,
44 STATUS_2 = 0x02,
45 STATUS_3 = 0x03,
46 STATUS_4 = 0x04,
47 INTERRUPT_0 = 0x05,
48 INTERRUPT_1 = 0x06,
49 INTERRUPT_2 = 0x07,
50 INTERRUPT_3 = 0x08,
51 SNR = 0x09,
52 VIT_ERR_CNT_2 = 0x0A,
53 VIT_ERR_CNT_1 = 0x0B,
54 VIT_ERR_CNT_0 = 0x0C,
55 RS_ERR_CNT_2 = 0x0D,
56 RS_ERR_CNT_1 = 0x0E,
57 RS_ERR_CNT_0 = 0x0F,
58 RS_UBC_1 = 0x10,
59 RS_UBC_0 = 0x11,
60 AGC_GAIN_3 = 0x12,
61 AGC_GAIN_2 = 0x13,
62 AGC_GAIN_1 = 0x14,
63 AGC_GAIN_0 = 0x15,
64 FREQ_OFFSET_2 = 0x17,
65 FREQ_OFFSET_1 = 0x18,
66 FREQ_OFFSET_0 = 0x19,
67 TIMING_OFFSET_1 = 0x1A,
68 TIMING_OFFSET_0 = 0x1B,
69 CHAN_FREQ_1 = 0x1C,
70 CHAN_FREQ_0 = 0x1D,
71 TPS_RECEIVED_1 = 0x1E,
72 TPS_RECEIVED_0 = 0x1F,
73 TPS_CURRENT_1 = 0x20,
74 TPS_CURRENT_0 = 0x21,
75 TPS_CELL_ID_1 = 0x22,
76 TPS_CELL_ID_0 = 0x23,
77 TPS_MISC_DATA_2 = 0x24,
78 TPS_MISC_DATA_1 = 0x25,
79 TPS_MISC_DATA_0 = 0x26,
80 RESET = 0x50,
81 TPS_GIVEN_1 = 0x51,
82 TPS_GIVEN_0 = 0x52,
83 ACQ_CTL = 0x53,
84 TRL_NOMINAL_RATE_1 = 0x54,
85 TRL_NOMINAL_RATE_0 = 0x55,
86 INPUT_FREQ_1 = 0x56,
87 INPUT_FREQ_0 = 0x57,
88 TUNER_ADDR = 0x58,
89 CHAN_START_1 = 0x59,
90 CHAN_START_0 = 0x5A,
91 CONT_1 = 0x5B,
92 CONT_0 = 0x5C,
93 TUNER_GO = 0x5D,
94 STATUS_EN_0 = 0x5F,
95 STATUS_EN_1 = 0x60,
96 INTERRUPT_EN_0 = 0x61,
97 INTERRUPT_EN_1 = 0x62,
98 INTERRUPT_EN_2 = 0x63,
99 INTERRUPT_EN_3 = 0x64,
100 AGC_TARGET = 0x67,
101 AGC_CTL = 0x68,
102 CAPT_RANGE = 0x75,
103 SNR_SELECT_1 = 0x79,
104 SNR_SELECT_0 = 0x7A,
105 RS_ERR_PER_1 = 0x7C,
106 RS_ERR_PER_0 = 0x7D,
107 CHIP_ID = 0x7F,
108 CHAN_STOP_1 = 0x80,
109 CHAN_STOP_0 = 0x81,
110 CHAN_STEP_1 = 0x82,
111 CHAN_STEP_0 = 0x83,
112 FEC_LOCK_TIME = 0x85,
113 OFDM_LOCK_TIME = 0x86,
114 ACQ_DELAY = 0x87,
115 SCAN_CTL = 0x88,
116 CLOCK_CTL = 0x89,
117 CONFIG = 0x8A,
118 MCLK_RATIO = 0x8B,
119 GPP_CTL = 0x8C,
120 ADC_CTL_1 = 0x8E,
121 ADC_CTL_0 = 0x8F
122};
123
124/* here we assume 1/6MHz == 166.66kHz stepsize */
125#define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */
126
127#endif /* _MT352_PRIV_ */
diff --git a/drivers/media/dvb/frontends/nxt2002.c b/drivers/media/dvb/frontends/nxt2002.c
new file mode 100644
index 000000000000..4743aa17406e
--- /dev/null
+++ b/drivers/media/dvb/frontends/nxt2002.c
@@ -0,0 +1,705 @@
1/*
2 Support for B2C2/BBTI Technisat Air2PC - ATSC
3
4 Copyright (C) 2004 Taylor Jacob <rtjacob@earthlink.net>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
20*/
21
22/*
23 * This driver needs external firmware. Please use the command
24 * "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" to
25 * download/extract it, and then copy it to /usr/lib/hotplug/firmware.
26 */
27#define NXT2002_DEFAULT_FIRMWARE "dvb-fe-nxt2002.fw"
28#define CRC_CCIT_MASK 0x1021
29
30#include <linux/init.h>
31#include <linux/module.h>
32#include <linux/moduleparam.h>
33#include <linux/device.h>
34#include <linux/firmware.h>
35
36#include "dvb_frontend.h"
37#include "nxt2002.h"
38
39struct nxt2002_state {
40
41 struct i2c_adapter* i2c;
42 struct dvb_frontend_ops ops;
43 const struct nxt2002_config* config;
44 struct dvb_frontend frontend;
45
46 /* demodulator private data */
47 u8 initialised:1;
48};
49
50static int debug;
51#define dprintk(args...) \
52 do { \
53 if (debug) printk(KERN_DEBUG "nxt2002: " args); \
54 } while (0)
55
56static int i2c_writebytes (struct nxt2002_state* state, u8 reg, u8 *buf, u8 len)
57{
58 /* probbably a much better way or doing this */
59 u8 buf2 [256],x;
60 int err;
61 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf2, .len = len + 1 };
62
63 buf2[0] = reg;
64 for (x = 0 ; x < len ; x++)
65 buf2[x+1] = buf[x];
66
67 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
68 printk ("%s: i2c write error (addr %02x, err == %i)\n",
69 __FUNCTION__, state->config->demod_address, err);
70 return -EREMOTEIO;
71 }
72
73 return 0;
74}
75
76static u8 i2c_readbytes (struct nxt2002_state* state, u8 reg, u8* buf, u8 len)
77{
78 u8 reg2 [] = { reg };
79
80 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = reg2, .len = 1 },
81 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = buf, .len = len } };
82
83 int err;
84
85 if ((err = i2c_transfer (state->i2c, msg, 2)) != 2) {
86 printk ("%s: i2c read error (addr %02x, err == %i)\n",
87 __FUNCTION__, state->config->demod_address, err);
88 return -EREMOTEIO;
89 }
90
91 return 0;
92}
93
94static u16 nxt2002_crc(u16 crc, u8 c)
95{
96
97 u8 i;
98 u16 input = (u16) c & 0xFF;
99
100 input<<=8;
101 for(i=0 ;i<8 ;i++) {
102 if((crc ^ input) & 0x8000)
103 crc=(crc<<1)^CRC_CCIT_MASK;
104 else
105 crc<<=1;
106 input<<=1;
107 }
108 return crc;
109}
110
111static int nxt2002_writereg_multibyte (struct nxt2002_state* state, u8 reg, u8* data, u8 len)
112{
113 u8 buf;
114 dprintk("%s\n", __FUNCTION__);
115
116 /* set multi register length */
117 i2c_writebytes(state,0x34,&len,1);
118
119 /* set mutli register register */
120 i2c_writebytes(state,0x35,&reg,1);
121
122 /* send the actual data */
123 i2c_writebytes(state,0x36,data,len);
124
125 /* toggle the multireg write bit*/
126 buf = 0x02;
127 i2c_writebytes(state,0x21,&buf,1);
128
129 i2c_readbytes(state,0x21,&buf,1);
130
131 if ((buf & 0x02) == 0)
132 return 0;
133
134 dprintk("Error writing multireg register %02X\n",reg);
135
136 return 0;
137}
138
139static int nxt2002_readreg_multibyte (struct nxt2002_state* state, u8 reg, u8* data, u8 len)
140{
141 u8 len2;
142 dprintk("%s\n", __FUNCTION__);
143
144 /* set multi register length */
145 len2 = len & 0x80;
146 i2c_writebytes(state,0x34,&len2,1);
147
148 /* set mutli register register */
149 i2c_writebytes(state,0x35,&reg,1);
150
151 /* send the actual data */
152 i2c_readbytes(state,reg,data,len);
153
154 return 0;
155}
156
157static void nxt2002_microcontroller_stop (struct nxt2002_state* state)
158{
159 u8 buf[2],counter = 0;
160 dprintk("%s\n", __FUNCTION__);
161
162 buf[0] = 0x80;
163 i2c_writebytes(state,0x22,buf,1);
164
165 while (counter < 20) {
166 i2c_readbytes(state,0x31,buf,1);
167 if (buf[0] & 0x40)
168 return;
169 msleep(10);
170 counter++;
171 }
172
173 dprintk("Timeout waiting for micro to stop.. This is ok after firmware upload\n");
174 return;
175}
176
177static void nxt2002_microcontroller_start (struct nxt2002_state* state)
178{
179 u8 buf;
180 dprintk("%s\n", __FUNCTION__);
181
182 buf = 0x00;
183 i2c_writebytes(state,0x22,&buf,1);
184}
185
186static int nxt2002_writetuner (struct nxt2002_state* state, u8* data)
187{
188 u8 buf,count = 0;
189
190 dprintk("Tuner Bytes: %02X %02X %02X %02X\n",data[0],data[1],data[2],data[3]);
191
192 dprintk("%s\n", __FUNCTION__);
193 /* stop the micro first */
194 nxt2002_microcontroller_stop(state);
195
196 /* set the i2c transfer speed to the tuner */
197 buf = 0x03;
198 i2c_writebytes(state,0x20,&buf,1);
199
200 /* setup to transfer 4 bytes via i2c */
201 buf = 0x04;
202 i2c_writebytes(state,0x34,&buf,1);
203
204 /* write actual tuner bytes */
205 i2c_writebytes(state,0x36,data,4);
206
207 /* set tuner i2c address */
208 buf = 0xC2;
209 i2c_writebytes(state,0x35,&buf,1);
210
211 /* write UC Opmode to begin transfer */
212 buf = 0x80;
213 i2c_writebytes(state,0x21,&buf,1);
214
215 while (count < 20) {
216 i2c_readbytes(state,0x21,&buf,1);
217 if ((buf & 0x80)== 0x00)
218 return 0;
219 msleep(100);
220 count++;
221 }
222
223 printk("nxt2002: timeout error writing tuner\n");
224 return 0;
225}
226
227static void nxt2002_agc_reset(struct nxt2002_state* state)
228{
229 u8 buf;
230 dprintk("%s\n", __FUNCTION__);
231
232 buf = 0x08;
233 i2c_writebytes(state,0x08,&buf,1);
234
235 buf = 0x00;
236 i2c_writebytes(state,0x08,&buf,1);
237
238 return;
239}
240
241static int nxt2002_load_firmware (struct dvb_frontend* fe, const struct firmware *fw)
242{
243
244 struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv;
245 u8 buf[256],written = 0,chunkpos = 0;
246 u16 rambase,position,crc = 0;
247
248 dprintk("%s\n", __FUNCTION__);
249 dprintk("Firmware is %zu bytes\n",fw->size);
250
251 /* Get the RAM base for this nxt2002 */
252 i2c_readbytes(state,0x10,buf,1);
253
254 if (buf[0] & 0x10)
255 rambase = 0x1000;
256 else
257 rambase = 0x0000;
258
259 dprintk("rambase on this nxt2002 is %04X\n",rambase);
260
261 /* Hold the micro in reset while loading firmware */
262 buf[0] = 0x80;
263 i2c_writebytes(state,0x2B,buf,1);
264
265 for (position = 0; position < fw->size ; position++) {
266 if (written == 0) {
267 crc = 0;
268 chunkpos = 0x28;
269 buf[0] = ((rambase + position) >> 8);
270 buf[1] = (rambase + position) & 0xFF;
271 buf[2] = 0x81;
272 /* write starting address */
273 i2c_writebytes(state,0x29,buf,3);
274 }
275 written++;
276 chunkpos++;
277
278 if ((written % 4) == 0)
279 i2c_writebytes(state,chunkpos,&fw->data[position-3],4);
280
281 crc = nxt2002_crc(crc,fw->data[position]);
282
283 if ((written == 255) || (position+1 == fw->size)) {
284 /* write remaining bytes of firmware */
285 i2c_writebytes(state, chunkpos+4-(written %4),
286 &fw->data[position-(written %4) + 1],
287 written %4);
288 buf[0] = crc << 8;
289 buf[1] = crc & 0xFF;
290
291 /* write crc */
292 i2c_writebytes(state,0x2C,buf,2);
293
294 /* do a read to stop things */
295 i2c_readbytes(state,0x2A,buf,1);
296
297 /* set transfer mode to complete */
298 buf[0] = 0x80;
299 i2c_writebytes(state,0x2B,buf,1);
300
301 written = 0;
302 }
303 }
304
305 printk ("done.\n");
306 return 0;
307};
308
309static int nxt2002_setup_frontend_parameters (struct dvb_frontend* fe,
310 struct dvb_frontend_parameters *p)
311{
312 struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv;
313 u32 freq = 0;
314 u16 tunerfreq = 0;
315 u8 buf[4];
316
317 freq = 44000 + ( p->frequency / 1000 );
318
319 dprintk("freq = %d p->frequency = %d\n",freq,p->frequency);
320
321 tunerfreq = freq * 24/4000;
322
323 buf[0] = (tunerfreq >> 8) & 0x7F;
324 buf[1] = (tunerfreq & 0xFF);
325
326 if (p->frequency <= 214000000) {
327 buf[2] = 0x84 + (0x06 << 3);
328 buf[3] = (p->frequency <= 172000000) ? 0x01 : 0x02;
329 } else if (p->frequency <= 721000000) {
330 buf[2] = 0x84 + (0x07 << 3);
331 buf[3] = (p->frequency <= 467000000) ? 0x02 : 0x08;
332 } else if (p->frequency <= 841000000) {
333 buf[2] = 0x84 + (0x0E << 3);
334 buf[3] = 0x08;
335 } else {
336 buf[2] = 0x84 + (0x0F << 3);
337 buf[3] = 0x02;
338 }
339
340 /* write frequency information */
341 nxt2002_writetuner(state,buf);
342
343 /* reset the agc now that tuning has been completed */
344 nxt2002_agc_reset(state);
345
346
347
348 /* set target power level */
349 switch (p->u.vsb.modulation) {
350 case QAM_64:
351 case QAM_256:
352 buf[0] = 0x74;
353 break;
354 case VSB_8:
355 buf[0] = 0x70;
356 break;
357 default:
358 return -EINVAL;
359 break;
360 }
361 i2c_writebytes(state,0x42,buf,1);
362
363 /* configure sdm */
364 buf[0] = 0x87;
365 i2c_writebytes(state,0x57,buf,1);
366
367 /* write sdm1 input */
368 buf[0] = 0x10;
369 buf[1] = 0x00;
370 nxt2002_writereg_multibyte(state,0x58,buf,2);
371
372 /* write sdmx input */
373 switch (p->u.vsb.modulation) {
374 case QAM_64:
375 buf[0] = 0x68;
376 break;
377 case QAM_256:
378 buf[0] = 0x64;
379 break;
380 case VSB_8:
381 buf[0] = 0x60;
382 break;
383 default:
384 return -EINVAL;
385 break;
386 }
387 buf[1] = 0x00;
388 nxt2002_writereg_multibyte(state,0x5C,buf,2);
389
390 /* write adc power lpf fc */
391 buf[0] = 0x05;
392 i2c_writebytes(state,0x43,buf,1);
393
394 /* write adc power lpf fc */
395 buf[0] = 0x05;
396 i2c_writebytes(state,0x43,buf,1);
397
398 /* write accumulator2 input */
399 buf[0] = 0x80;
400 buf[1] = 0x00;
401 nxt2002_writereg_multibyte(state,0x4B,buf,2);
402
403 /* write kg1 */
404 buf[0] = 0x00;
405 i2c_writebytes(state,0x4D,buf,1);
406
407 /* write sdm12 lpf fc */
408 buf[0] = 0x44;
409 i2c_writebytes(state,0x55,buf,1);
410
411 /* write agc control reg */
412 buf[0] = 0x04;
413 i2c_writebytes(state,0x41,buf,1);
414
415 /* write agc ucgp0 */
416 switch (p->u.vsb.modulation) {
417 case QAM_64:
418 buf[0] = 0x02;
419 break;
420 case QAM_256:
421 buf[0] = 0x03;
422 break;
423 case VSB_8:
424 buf[0] = 0x00;
425 break;
426 default:
427 return -EINVAL;
428 break;
429 }
430 i2c_writebytes(state,0x30,buf,1);
431
432 /* write agc control reg */
433 buf[0] = 0x00;
434 i2c_writebytes(state,0x41,buf,1);
435
436 /* write accumulator2 input */
437 buf[0] = 0x80;
438 buf[1] = 0x00;
439 nxt2002_writereg_multibyte(state,0x49,buf,2);
440 nxt2002_writereg_multibyte(state,0x4B,buf,2);
441
442 /* write agc control reg */
443 buf[0] = 0x04;
444 i2c_writebytes(state,0x41,buf,1);
445
446 nxt2002_microcontroller_start(state);
447
448 /* adjacent channel detection should be done here, but I don't
449 have any stations with this need so I cannot test it */
450
451 return 0;
452}
453
454static int nxt2002_read_status(struct dvb_frontend* fe, fe_status_t* status)
455{
456 struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv;
457 u8 lock;
458 i2c_readbytes(state,0x31,&lock,1);
459
460 *status = 0;
461 if (lock & 0x20) {
462 *status |= FE_HAS_SIGNAL;
463 *status |= FE_HAS_CARRIER;
464 *status |= FE_HAS_VITERBI;
465 *status |= FE_HAS_SYNC;
466 *status |= FE_HAS_LOCK;
467 }
468 return 0;
469}
470
471static int nxt2002_read_ber(struct dvb_frontend* fe, u32* ber)
472{
473 struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv;
474 u8 b[3];
475
476 nxt2002_readreg_multibyte(state,0xE6,b,3);
477
478 *ber = ((b[0] << 8) + b[1]) * 8;
479
480 return 0;
481}
482
483static int nxt2002_read_signal_strength(struct dvb_frontend* fe, u16* strength)
484{
485 struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv;
486 u8 b[2];
487 u16 temp = 0;
488
489 /* setup to read cluster variance */
490 b[0] = 0x00;
491 i2c_writebytes(state,0xA1,b,1);
492
493 /* get multreg val */
494 nxt2002_readreg_multibyte(state,0xA6,b,2);
495
496 temp = (b[0] << 8) | b[1];
497 *strength = ((0x7FFF - temp) & 0x0FFF) * 16;
498
499 return 0;
500}
501
502static int nxt2002_read_snr(struct dvb_frontend* fe, u16* snr)
503{
504
505 struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv;
506 u8 b[2];
507 u16 temp = 0, temp2;
508 u32 snrdb = 0;
509
510 /* setup to read cluster variance */
511 b[0] = 0x00;
512 i2c_writebytes(state,0xA1,b,1);
513
514 /* get multreg val from 0xA6 */
515 nxt2002_readreg_multibyte(state,0xA6,b,2);
516
517 temp = (b[0] << 8) | b[1];
518 temp2 = 0x7FFF - temp;
519
520 /* snr will be in db */
521 if (temp2 > 0x7F00)
522 snrdb = 1000*24 + ( 1000*(30-24) * ( temp2 - 0x7F00 ) / ( 0x7FFF - 0x7F00 ) );
523 else if (temp2 > 0x7EC0)
524 snrdb = 1000*18 + ( 1000*(24-18) * ( temp2 - 0x7EC0 ) / ( 0x7F00 - 0x7EC0 ) );
525 else if (temp2 > 0x7C00)
526 snrdb = 1000*12 + ( 1000*(18-12) * ( temp2 - 0x7C00 ) / ( 0x7EC0 - 0x7C00 ) );
527 else
528 snrdb = 1000*0 + ( 1000*(12-0) * ( temp2 - 0 ) / ( 0x7C00 - 0 ) );
529
530 /* the value reported back from the frontend will be FFFF=32db 0000=0db */
531
532 *snr = snrdb * (0xFFFF/32000);
533
534 return 0;
535}
536
537static int nxt2002_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
538{
539 struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv;
540 u8 b[3];
541
542 nxt2002_readreg_multibyte(state,0xE6,b,3);
543 *ucblocks = b[2];
544
545 return 0;
546}
547
548static int nxt2002_sleep(struct dvb_frontend* fe)
549{
550 return 0;
551}
552
553static int nxt2002_init(struct dvb_frontend* fe)
554{
555 struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv;
556 const struct firmware *fw;
557 int ret;
558 u8 buf[2];
559
560 if (!state->initialised) {
561 /* request the firmware, this will block until someone uploads it */
562 printk("nxt2002: Waiting for firmware upload (%s)...\n", NXT2002_DEFAULT_FIRMWARE);
563 ret = state->config->request_firmware(fe, &fw, NXT2002_DEFAULT_FIRMWARE);
564 printk("nxt2002: Waiting for firmware upload(2)...\n");
565 if (ret) {
566 printk("nxt2002: no firmware upload (timeout or file not found?)\n");
567 return ret;
568 }
569
570 ret = nxt2002_load_firmware(fe, fw);
571 if (ret) {
572 printk("nxt2002: writing firmware to device failed\n");
573 release_firmware(fw);
574 return ret;
575 }
576 printk("nxt2002: firmware upload complete\n");
577
578 /* Put the micro into reset */
579 nxt2002_microcontroller_stop(state);
580
581 /* ensure transfer is complete */
582 buf[0]=0;
583 i2c_writebytes(state,0x2B,buf,1);
584
585 /* Put the micro into reset for real this time */
586 nxt2002_microcontroller_stop(state);
587
588 /* soft reset everything (agc,frontend,eq,fec)*/
589 buf[0] = 0x0F;
590 i2c_writebytes(state,0x08,buf,1);
591 buf[0] = 0x00;
592 i2c_writebytes(state,0x08,buf,1);
593
594 /* write agc sdm configure */
595 buf[0] = 0xF1;
596 i2c_writebytes(state,0x57,buf,1);
597
598 /* write mod output format */
599 buf[0] = 0x20;
600 i2c_writebytes(state,0x09,buf,1);
601
602 /* write fec mpeg mode */
603 buf[0] = 0x7E;
604 buf[1] = 0x00;
605 i2c_writebytes(state,0xE9,buf,2);
606
607 /* write mux selection */
608 buf[0] = 0x00;
609 i2c_writebytes(state,0xCC,buf,1);
610
611 state->initialised = 1;
612 }
613
614 return 0;
615}
616
617static int nxt2002_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
618{
619 fesettings->min_delay_ms = 500;
620 fesettings->step_size = 0;
621 fesettings->max_drift = 0;
622 return 0;
623}
624
625static void nxt2002_release(struct dvb_frontend* fe)
626{
627 struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv;
628 kfree(state);
629}
630
631static struct dvb_frontend_ops nxt2002_ops;
632
633struct dvb_frontend* nxt2002_attach(const struct nxt2002_config* config,
634 struct i2c_adapter* i2c)
635{
636 struct nxt2002_state* state = NULL;
637 u8 buf [] = {0,0,0,0,0};
638
639 /* allocate memory for the internal state */
640 state = (struct nxt2002_state*) kmalloc(sizeof(struct nxt2002_state), GFP_KERNEL);
641 if (state == NULL) goto error;
642
643 /* setup the state */
644 state->config = config;
645 state->i2c = i2c;
646 memcpy(&state->ops, &nxt2002_ops, sizeof(struct dvb_frontend_ops));
647 state->initialised = 0;
648
649 /* Check the first 5 registers to ensure this a revision we can handle */
650
651 i2c_readbytes(state, 0x00, buf, 5);
652 if (buf[0] != 0x04) goto error; /* device id */
653 if (buf[1] != 0x02) goto error; /* fab id */
654 if (buf[2] != 0x11) goto error; /* month */
655 if (buf[3] != 0x20) goto error; /* year msb */
656 if (buf[4] != 0x00) goto error; /* year lsb */
657
658 /* create dvb_frontend */
659 state->frontend.ops = &state->ops;
660 state->frontend.demodulator_priv = state;
661 return &state->frontend;
662
663error:
664 kfree(state);
665 return NULL;
666}
667
668static struct dvb_frontend_ops nxt2002_ops = {
669
670 .info = {
671 .name = "Nextwave nxt2002 VSB/QAM frontend",
672 .type = FE_ATSC,
673 .frequency_min = 54000000,
674 .frequency_max = 860000000,
675 /* stepsize is just a guess */
676 .frequency_stepsize = 166666,
677 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
678 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
679 FE_CAN_8VSB | FE_CAN_QAM_64 | FE_CAN_QAM_256
680 },
681
682 .release = nxt2002_release,
683
684 .init = nxt2002_init,
685 .sleep = nxt2002_sleep,
686
687 .set_frontend = nxt2002_setup_frontend_parameters,
688 .get_tune_settings = nxt2002_get_tune_settings,
689
690 .read_status = nxt2002_read_status,
691 .read_ber = nxt2002_read_ber,
692 .read_signal_strength = nxt2002_read_signal_strength,
693 .read_snr = nxt2002_read_snr,
694 .read_ucblocks = nxt2002_read_ucblocks,
695
696};
697
698module_param(debug, int, 0644);
699MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
700
701MODULE_DESCRIPTION("NXT2002 ATSC (8VSB & ITU J83 AnnexB FEC QAM64/256) demodulator driver");
702MODULE_AUTHOR("Taylor Jacob");
703MODULE_LICENSE("GPL");
704
705EXPORT_SYMBOL(nxt2002_attach);
diff --git a/drivers/media/dvb/frontends/nxt2002.h b/drivers/media/dvb/frontends/nxt2002.h
new file mode 100644
index 000000000000..462301f577ee
--- /dev/null
+++ b/drivers/media/dvb/frontends/nxt2002.h
@@ -0,0 +1,23 @@
1/*
2 Driver for the Nxt2002 demodulator
3*/
4
5#ifndef NXT2002_H
6#define NXT2002_H
7
8#include <linux/dvb/frontend.h>
9#include <linux/firmware.h>
10
11struct nxt2002_config
12{
13 /* the demodulator's i2c address */
14 u8 demod_address;
15
16 /* request firmware for device */
17 int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
18};
19
20extern struct dvb_frontend* nxt2002_attach(const struct nxt2002_config* config,
21 struct i2c_adapter* i2c);
22
23#endif // NXT2002_H
diff --git a/drivers/media/dvb/frontends/nxt6000.c b/drivers/media/dvb/frontends/nxt6000.c
new file mode 100644
index 000000000000..a41f7da8b842
--- /dev/null
+++ b/drivers/media/dvb/frontends/nxt6000.c
@@ -0,0 +1,554 @@
1/*
2 NxtWave Communications - NXT6000 demodulator driver
3
4 Copyright (C) 2002-2003 Florian Schirmer <jolt@tuxbox.org>
5 Copyright (C) 2003 Paul Andreassen <paul@andreassen.com.au>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20*/
21
22#include <linux/init.h>
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/string.h>
26#include <linux/slab.h>
27
28#include "dvb_frontend.h"
29#include "nxt6000_priv.h"
30#include "nxt6000.h"
31
32
33
34struct nxt6000_state {
35 struct i2c_adapter* i2c;
36 struct dvb_frontend_ops ops;
37 /* configuration settings */
38 const struct nxt6000_config* config;
39 struct dvb_frontend frontend;
40};
41
42static int debug = 0;
43#define dprintk if (debug) printk
44
45static int nxt6000_writereg(struct nxt6000_state* state, u8 reg, u8 data)
46{
47 u8 buf[] = { reg, data };
48 struct i2c_msg msg = {.addr = state->config->demod_address,.flags = 0,.buf = buf,.len = 2 };
49 int ret;
50
51 if ((ret = i2c_transfer(state->i2c, &msg, 1)) != 1)
52 dprintk("nxt6000: nxt6000_write error (reg: 0x%02X, data: 0x%02X, ret: %d)\n", reg, data, ret);
53
54 return (ret != 1) ? -EFAULT : 0;
55}
56
57static u8 nxt6000_readreg(struct nxt6000_state* state, u8 reg)
58{
59 int ret;
60 u8 b0[] = { reg };
61 u8 b1[] = { 0 };
62 struct i2c_msg msgs[] = {
63 {.addr = state->config->demod_address,.flags = 0,.buf = b0,.len = 1},
64 {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b1,.len = 1}
65 };
66
67 ret = i2c_transfer(state->i2c, msgs, 2);
68
69 if (ret != 2)
70 dprintk("nxt6000: nxt6000_read error (reg: 0x%02X, ret: %d)\n", reg, ret);
71
72 return b1[0];
73}
74
75static void nxt6000_reset(struct nxt6000_state* state)
76{
77 u8 val;
78
79 val = nxt6000_readreg(state, OFDM_COR_CTL);
80
81 nxt6000_writereg(state, OFDM_COR_CTL, val & ~COREACT);
82 nxt6000_writereg(state, OFDM_COR_CTL, val | COREACT);
83}
84
85static int nxt6000_set_bandwidth(struct nxt6000_state* state, fe_bandwidth_t bandwidth)
86{
87 u16 nominal_rate;
88 int result;
89
90 switch (bandwidth) {
91
92 case BANDWIDTH_6_MHZ:
93 nominal_rate = 0x55B7;
94 break;
95
96 case BANDWIDTH_7_MHZ:
97 nominal_rate = 0x6400;
98 break;
99
100 case BANDWIDTH_8_MHZ:
101 nominal_rate = 0x7249;
102 break;
103
104 default:
105 return -EINVAL;
106 }
107
108 if ((result = nxt6000_writereg(state, OFDM_TRL_NOMINALRATE_1, nominal_rate & 0xFF)) < 0)
109 return result;
110
111 return nxt6000_writereg(state, OFDM_TRL_NOMINALRATE_2, (nominal_rate >> 8) & 0xFF);
112}
113
114static int nxt6000_set_guard_interval(struct nxt6000_state* state, fe_guard_interval_t guard_interval)
115{
116 switch (guard_interval) {
117
118 case GUARD_INTERVAL_1_32:
119 return nxt6000_writereg(state, OFDM_COR_MODEGUARD, 0x00 | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x03));
120
121 case GUARD_INTERVAL_1_16:
122 return nxt6000_writereg(state, OFDM_COR_MODEGUARD, 0x01 | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x03));
123
124 case GUARD_INTERVAL_AUTO:
125 case GUARD_INTERVAL_1_8:
126 return nxt6000_writereg(state, OFDM_COR_MODEGUARD, 0x02 | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x03));
127
128 case GUARD_INTERVAL_1_4:
129 return nxt6000_writereg(state, OFDM_COR_MODEGUARD, 0x03 | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x03));
130
131 default:
132 return -EINVAL;
133 }
134}
135
136static int nxt6000_set_inversion(struct nxt6000_state* state, fe_spectral_inversion_t inversion)
137{
138 switch (inversion) {
139
140 case INVERSION_OFF:
141 return nxt6000_writereg(state, OFDM_ITB_CTL, 0x00);
142
143 case INVERSION_ON:
144 return nxt6000_writereg(state, OFDM_ITB_CTL, ITBINV);
145
146 default:
147 return -EINVAL;
148
149 }
150}
151
152static int nxt6000_set_transmission_mode(struct nxt6000_state* state, fe_transmit_mode_t transmission_mode)
153{
154 int result;
155
156 switch (transmission_mode) {
157
158 case TRANSMISSION_MODE_2K:
159 if ((result = nxt6000_writereg(state, EN_DMD_RACQ, 0x00 | (nxt6000_readreg(state, EN_DMD_RACQ) & ~0x03))) < 0)
160 return result;
161
162 return nxt6000_writereg(state, OFDM_COR_MODEGUARD, (0x00 << 2) | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x04));
163
164 case TRANSMISSION_MODE_8K:
165 case TRANSMISSION_MODE_AUTO:
166 if ((result = nxt6000_writereg(state, EN_DMD_RACQ, 0x02 | (nxt6000_readreg(state, EN_DMD_RACQ) & ~0x03))) < 0)
167 return result;
168
169 return nxt6000_writereg(state, OFDM_COR_MODEGUARD, (0x01 << 2) | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x04));
170
171 default:
172 return -EINVAL;
173
174 }
175}
176
177static void nxt6000_setup(struct dvb_frontend* fe)
178{
179 struct nxt6000_state* state = (struct nxt6000_state*) fe->demodulator_priv;
180
181 nxt6000_writereg(state, RS_COR_SYNC_PARAM, SYNC_PARAM);
182 nxt6000_writereg(state, BER_CTRL, /*(1 << 2) | */ (0x01 << 1) | 0x01);
183 nxt6000_writereg(state, VIT_COR_CTL, VIT_COR_RESYNC);
184 nxt6000_writereg(state, OFDM_COR_CTL, (0x01 << 5) | (nxt6000_readreg(state, OFDM_COR_CTL) & 0x0F));
185 nxt6000_writereg(state, OFDM_COR_MODEGUARD, FORCEMODE8K | 0x02);
186 nxt6000_writereg(state, OFDM_AGC_CTL, AGCLAST | INITIAL_AGC_BW);
187 nxt6000_writereg(state, OFDM_ITB_FREQ_1, 0x06);
188 nxt6000_writereg(state, OFDM_ITB_FREQ_2, 0x31);
189 nxt6000_writereg(state, OFDM_CAS_CTL, (0x01 << 7) | (0x02 << 3) | 0x04);
190 nxt6000_writereg(state, CAS_FREQ, 0xBB); /* CHECKME */
191 nxt6000_writereg(state, OFDM_SYR_CTL, 1 << 2);
192 nxt6000_writereg(state, OFDM_PPM_CTL_1, PPM256);
193 nxt6000_writereg(state, OFDM_TRL_NOMINALRATE_1, 0x49);
194 nxt6000_writereg(state, OFDM_TRL_NOMINALRATE_2, 0x72);
195 nxt6000_writereg(state, ANALOG_CONTROL_0, 1 << 5);
196 nxt6000_writereg(state, EN_DMD_RACQ, (1 << 7) | (3 << 4) | 2);
197 nxt6000_writereg(state, DIAG_CONFIG, TB_SET);
198
199 if (state->config->clock_inversion)
200 nxt6000_writereg(state, SUB_DIAG_MODE_SEL, CLKINVERSION);
201 else
202 nxt6000_writereg(state, SUB_DIAG_MODE_SEL, 0);
203
204 nxt6000_writereg(state, TS_FORMAT, 0);
205
206 if (state->config->pll_init) {
207 nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x01); /* open i2c bus switch */
208 state->config->pll_init(fe);
209 nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x00); /* close i2c bus switch */
210 }
211}
212
213static void nxt6000_dump_status(struct nxt6000_state *state)
214{
215 u8 val;
216
217/*
218 printk("RS_COR_STAT: 0x%02X\n", nxt6000_readreg(fe, RS_COR_STAT));
219 printk("VIT_SYNC_STATUS: 0x%02X\n", nxt6000_readreg(fe, VIT_SYNC_STATUS));
220 printk("OFDM_COR_STAT: 0x%02X\n", nxt6000_readreg(fe, OFDM_COR_STAT));
221 printk("OFDM_SYR_STAT: 0x%02X\n", nxt6000_readreg(fe, OFDM_SYR_STAT));
222 printk("OFDM_TPS_RCVD_1: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_1));
223 printk("OFDM_TPS_RCVD_2: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_2));
224 printk("OFDM_TPS_RCVD_3: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_3));
225 printk("OFDM_TPS_RCVD_4: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_4));
226 printk("OFDM_TPS_RESERVED_1: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RESERVED_1));
227 printk("OFDM_TPS_RESERVED_2: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RESERVED_2));
228*/
229 printk("NXT6000 status:");
230
231 val = nxt6000_readreg(state, RS_COR_STAT);
232
233 printk(" DATA DESCR LOCK: %d,", val & 0x01);
234 printk(" DATA SYNC LOCK: %d,", (val >> 1) & 0x01);
235
236 val = nxt6000_readreg(state, VIT_SYNC_STATUS);
237
238 printk(" VITERBI LOCK: %d,", (val >> 7) & 0x01);
239
240 switch ((val >> 4) & 0x07) {
241
242 case 0x00:
243 printk(" VITERBI CODERATE: 1/2,");
244 break;
245
246 case 0x01:
247 printk(" VITERBI CODERATE: 2/3,");
248 break;
249
250 case 0x02:
251 printk(" VITERBI CODERATE: 3/4,");
252 break;
253
254 case 0x03:
255 printk(" VITERBI CODERATE: 5/6,");
256 break;
257
258 case 0x04:
259 printk(" VITERBI CODERATE: 7/8,");
260 break;
261
262 default:
263 printk(" VITERBI CODERATE: Reserved,");
264
265 }
266
267 val = nxt6000_readreg(state, OFDM_COR_STAT);
268
269 printk(" CHCTrack: %d,", (val >> 7) & 0x01);
270 printk(" TPSLock: %d,", (val >> 6) & 0x01);
271 printk(" SYRLock: %d,", (val >> 5) & 0x01);
272 printk(" AGCLock: %d,", (val >> 4) & 0x01);
273
274 switch (val & 0x0F) {
275
276 case 0x00:
277 printk(" CoreState: IDLE,");
278 break;
279
280 case 0x02:
281 printk(" CoreState: WAIT_AGC,");
282 break;
283
284 case 0x03:
285 printk(" CoreState: WAIT_SYR,");
286 break;
287
288 case 0x04:
289 printk(" CoreState: WAIT_PPM,");
290 break;
291
292 case 0x01:
293 printk(" CoreState: WAIT_TRL,");
294 break;
295
296 case 0x05:
297 printk(" CoreState: WAIT_TPS,");
298 break;
299
300 case 0x06:
301 printk(" CoreState: MONITOR_TPS,");
302 break;
303
304 default:
305 printk(" CoreState: Reserved,");
306
307 }
308
309 val = nxt6000_readreg(state, OFDM_SYR_STAT);
310
311 printk(" SYRLock: %d,", (val >> 4) & 0x01);
312 printk(" SYRMode: %s,", (val >> 2) & 0x01 ? "8K" : "2K");
313
314 switch ((val >> 4) & 0x03) {
315
316 case 0x00:
317 printk(" SYRGuard: 1/32,");
318 break;
319
320 case 0x01:
321 printk(" SYRGuard: 1/16,");
322 break;
323
324 case 0x02:
325 printk(" SYRGuard: 1/8,");
326 break;
327
328 case 0x03:
329 printk(" SYRGuard: 1/4,");
330 break;
331 }
332
333 val = nxt6000_readreg(state, OFDM_TPS_RCVD_3);
334
335 switch ((val >> 4) & 0x07) {
336
337 case 0x00:
338 printk(" TPSLP: 1/2,");
339 break;
340
341 case 0x01:
342 printk(" TPSLP: 2/3,");
343 break;
344
345 case 0x02:
346 printk(" TPSLP: 3/4,");
347 break;
348
349 case 0x03:
350 printk(" TPSLP: 5/6,");
351 break;
352
353 case 0x04:
354 printk(" TPSLP: 7/8,");
355 break;
356
357 default:
358 printk(" TPSLP: Reserved,");
359
360 }
361
362 switch (val & 0x07) {
363
364 case 0x00:
365 printk(" TPSHP: 1/2,");
366 break;
367
368 case 0x01:
369 printk(" TPSHP: 2/3,");
370 break;
371
372 case 0x02:
373 printk(" TPSHP: 3/4,");
374 break;
375
376 case 0x03:
377 printk(" TPSHP: 5/6,");
378 break;
379
380 case 0x04:
381 printk(" TPSHP: 7/8,");
382 break;
383
384 default:
385 printk(" TPSHP: Reserved,");
386
387 }
388
389 val = nxt6000_readreg(state, OFDM_TPS_RCVD_4);
390
391 printk(" TPSMode: %s,", val & 0x01 ? "8K" : "2K");
392
393 switch ((val >> 4) & 0x03) {
394
395 case 0x00:
396 printk(" TPSGuard: 1/32,");
397 break;
398
399 case 0x01:
400 printk(" TPSGuard: 1/16,");
401 break;
402
403 case 0x02:
404 printk(" TPSGuard: 1/8,");
405 break;
406
407 case 0x03:
408 printk(" TPSGuard: 1/4,");
409 break;
410
411 }
412
413 /* Strange magic required to gain access to RF_AGC_STATUS */
414 nxt6000_readreg(state, RF_AGC_VAL_1);
415 val = nxt6000_readreg(state, RF_AGC_STATUS);
416 val = nxt6000_readreg(state, RF_AGC_STATUS);
417
418 printk(" RF AGC LOCK: %d,", (val >> 4) & 0x01);
419 printk("\n");
420}
421
422static int nxt6000_read_status(struct dvb_frontend* fe, fe_status_t* status)
423{
424 u8 core_status;
425 struct nxt6000_state* state = (struct nxt6000_state*) fe->demodulator_priv;
426
427 *status = 0;
428
429 core_status = nxt6000_readreg(state, OFDM_COR_STAT);
430
431 if (core_status & AGCLOCKED)
432 *status |= FE_HAS_SIGNAL;
433
434 if (nxt6000_readreg(state, OFDM_SYR_STAT) & GI14_SYR_LOCK)
435 *status |= FE_HAS_CARRIER;
436
437 if (nxt6000_readreg(state, VIT_SYNC_STATUS) & VITINSYNC)
438 *status |= FE_HAS_VITERBI;
439
440 if (nxt6000_readreg(state, RS_COR_STAT) & RSCORESTATUS)
441 *status |= FE_HAS_SYNC;
442
443 if ((core_status & TPSLOCKED) && (*status == (FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)))
444 *status |= FE_HAS_LOCK;
445
446 if (debug)
447 nxt6000_dump_status(state);
448
449 return 0;
450}
451
452static int nxt6000_init(struct dvb_frontend* fe)
453{
454 struct nxt6000_state* state = (struct nxt6000_state*) fe->demodulator_priv;
455
456 nxt6000_reset(state);
457 nxt6000_setup(fe);
458
459 return 0;
460}
461
462static int nxt6000_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *param)
463{
464 struct nxt6000_state* state = (struct nxt6000_state*) fe->demodulator_priv;
465 int result;
466
467 nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x01); /* open i2c bus switch */
468 state->config->pll_set(fe, param);
469 nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x00); /* close i2c bus switch */
470
471 if ((result = nxt6000_set_bandwidth(state, param->u.ofdm.bandwidth)) < 0)
472 return result;
473 if ((result = nxt6000_set_guard_interval(state, param->u.ofdm.guard_interval)) < 0)
474 return result;
475 if ((result = nxt6000_set_transmission_mode(state, param->u.ofdm.transmission_mode)) < 0)
476 return result;
477 if ((result = nxt6000_set_inversion(state, param->inversion)) < 0)
478 return result;
479
480 return 0;
481}
482
483static void nxt6000_release(struct dvb_frontend* fe)
484{
485 struct nxt6000_state* state = (struct nxt6000_state*) fe->demodulator_priv;
486 kfree(state);
487}
488
489static struct dvb_frontend_ops nxt6000_ops;
490
491struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config,
492 struct i2c_adapter* i2c)
493{
494 struct nxt6000_state* state = NULL;
495
496 /* allocate memory for the internal state */
497 state = (struct nxt6000_state*) kmalloc(sizeof(struct nxt6000_state), GFP_KERNEL);
498 if (state == NULL) goto error;
499
500 /* setup the state */
501 state->config = config;
502 state->i2c = i2c;
503 memcpy(&state->ops, &nxt6000_ops, sizeof(struct dvb_frontend_ops));
504
505 /* check if the demod is there */
506 if (nxt6000_readreg(state, OFDM_MSC_REV) != NXT6000ASICDEVICE) goto error;
507
508 /* create dvb_frontend */
509 state->frontend.ops = &state->ops;
510 state->frontend.demodulator_priv = state;
511 return &state->frontend;
512
513error:
514 kfree(state);
515 return NULL;
516}
517
518static struct dvb_frontend_ops nxt6000_ops = {
519
520 .info = {
521 .name = "NxtWave NXT6000 DVB-T",
522 .type = FE_OFDM,
523 .frequency_min = 0,
524 .frequency_max = 863250000,
525 .frequency_stepsize = 62500,
526 /*.frequency_tolerance = *//* FIXME: 12% of SR */
527 .symbol_rate_min = 0, /* FIXME */
528 .symbol_rate_max = 9360000, /* FIXME */
529 .symbol_rate_tolerance = 4000,
530 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
531 FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
532 FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
533 FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
534 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
535 FE_CAN_HIERARCHY_AUTO,
536 },
537
538 .release = nxt6000_release,
539
540 .init = nxt6000_init,
541
542 .set_frontend = nxt6000_set_frontend,
543
544 .read_status = nxt6000_read_status,
545};
546
547module_param(debug, int, 0644);
548MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
549
550MODULE_DESCRIPTION("NxtWave NXT6000 DVB-T demodulator driver");
551MODULE_AUTHOR("Florian Schirmer");
552MODULE_LICENSE("GPL");
553
554EXPORT_SYMBOL(nxt6000_attach);
diff --git a/drivers/media/dvb/frontends/nxt6000.h b/drivers/media/dvb/frontends/nxt6000.h
new file mode 100644
index 000000000000..b7d9bead3002
--- /dev/null
+++ b/drivers/media/dvb/frontends/nxt6000.h
@@ -0,0 +1,43 @@
1/*
2 NxtWave Communications - NXT6000 demodulator driver
3
4 Copyright (C) 2002-2003 Florian Schirmer <jolt@tuxbox.org>
5 Copyright (C) 2003 Paul Andreassen <paul@andreassen.com.au>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20*/
21
22#ifndef NXT6000_H
23#define NXT6000_H
24
25#include <linux/dvb/frontend.h>
26
27struct nxt6000_config
28{
29 /* the demodulator's i2c address */
30 u8 demod_address;
31
32 /* should clock inversion be used? */
33 u8 clock_inversion:1;
34
35 /* PLL maintenance */
36 int (*pll_init)(struct dvb_frontend* fe);
37 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
38};
39
40extern struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config,
41 struct i2c_adapter* i2c);
42
43#endif // NXT6000_H
diff --git a/drivers/media/dvb/frontends/nxt6000_priv.h b/drivers/media/dvb/frontends/nxt6000_priv.h
new file mode 100644
index 000000000000..64b1a89b2a22
--- /dev/null
+++ b/drivers/media/dvb/frontends/nxt6000_priv.h
@@ -0,0 +1,265 @@
1/*
2 * Public Include File for DRV6000 users
3 * (ie. NxtWave Communications - NXT6000 demodulator driver)
4 *
5 * Copyright (C) 2001 NxtWave Communications, Inc.
6 *
7 */
8
9/* Nxt6000 Register Addresses and Bit Masks */
10
11/* Maximum Register Number */
12#define MAXNXT6000REG (0x9A)
13
14/* 0x1B A_VIT_BER_0 aka 0x3A */
15#define A_VIT_BER_0 (0x1B)
16
17/* 0x1D A_VIT_BER_TIMER_0 aka 0x38 */
18#define A_VIT_BER_TIMER_0 (0x1D)
19
20/* 0x21 RS_COR_STAT */
21#define RS_COR_STAT (0x21)
22#define RSCORESTATUS (0x03)
23
24/* 0x22 RS_COR_INTEN */
25#define RS_COR_INTEN (0x22)
26
27/* 0x23 RS_COR_INSTAT */
28#define RS_COR_INSTAT (0x23)
29#define INSTAT_ERROR (0x04)
30#define LOCK_LOSS_BITS (0x03)
31
32/* 0x24 RS_COR_SYNC_PARAM */
33#define RS_COR_SYNC_PARAM (0x24)
34#define SYNC_PARAM (0x03)
35
36/* 0x25 BER_CTRL */
37#define BER_CTRL (0x25)
38#define BER_ENABLE (0x02)
39#define BER_RESET (0x01)
40
41/* 0x26 BER_PAY */
42#define BER_PAY (0x26)
43
44/* 0x27 BER_PKT_L */
45#define BER_PKT_L (0x27)
46#define BER_PKTOVERFLOW (0x80)
47
48/* 0x30 VIT_COR_CTL */
49#define VIT_COR_CTL (0x30)
50#define BER_CONTROL (0x02)
51#define VIT_COR_MASK (0x82)
52#define VIT_COR_RESYNC (0x80)
53
54
55/* 0x32 VIT_SYNC_STATUS */
56#define VIT_SYNC_STATUS (0x32)
57#define VITINSYNC (0x80)
58
59/* 0x33 VIT_COR_INTEN */
60#define VIT_COR_INTEN (0x33)
61#define GLOBAL_ENABLE (0x80)
62
63/* 0x34 VIT_COR_INTSTAT */
64#define VIT_COR_INTSTAT (0x34)
65#define BER_DONE (0x08)
66#define BER_OVERFLOW (0x10)
67
68 /* 0x38 OFDM_BERTimer *//* Use the alias registers */
69#define A_VIT_BER_TIMER_0 (0x1D)
70
71 /* 0x3A VIT_BER_TIMER_0 *//* Use the alias registers */
72#define A_VIT_BER_0 (0x1B)
73
74/* 0x40 OFDM_COR_CTL */
75#define OFDM_COR_CTL (0x40)
76#define COREACT (0x20)
77#define HOLDSM (0x10)
78#define WAIT_AGC (0x02)
79#define WAIT_SYR (0x03)
80
81/* 0x41 OFDM_COR_STAT */
82#define OFDM_COR_STAT (0x41)
83#define COR_STATUS (0x0F)
84#define MONITOR_TPS (0x06)
85#define TPSLOCKED (0x40)
86#define AGCLOCKED (0x10)
87
88/* 0x42 OFDM_COR_INTEN */
89#define OFDM_COR_INTEN (0x42)
90#define TPSRCVBAD (0x04)
91#define TPSRCVCHANGED (0x02)
92#define TPSRCVUPDATE (0x01)
93
94/* 0x43 OFDM_COR_INSTAT */
95#define OFDM_COR_INSTAT (0x43)
96
97/* 0x44 OFDM_COR_MODEGUARD */
98#define OFDM_COR_MODEGUARD (0x44)
99#define FORCEMODE (0x08)
100#define FORCEMODE8K (0x04)
101
102/* 0x45 OFDM_AGC_CTL */
103#define OFDM_AGC_CTL (0x45)
104#define INITIAL_AGC_BW (0x08)
105#define AGCNEG (0x02)
106#define AGCLAST (0x10)
107
108/* 0x48 OFDM_AGC_TARGET */
109#define OFDM_AGC_TARGET (0x48)
110#define OFDM_AGC_TARGET_DEFAULT (0x28)
111#define OFDM_AGC_TARGET_IMPULSE (0x38)
112
113/* 0x49 OFDM_AGC_GAIN_1 */
114#define OFDM_AGC_GAIN_1 (0x49)
115
116/* 0x4B OFDM_ITB_CTL */
117#define OFDM_ITB_CTL (0x4B)
118#define ITBINV (0x01)
119
120/* 0x4C OFDM_ITB_FREQ_1 */
121#define OFDM_ITB_FREQ_1 (0x4C)
122
123/* 0x4D OFDM_ITB_FREQ_2 */
124#define OFDM_ITB_FREQ_2 (0x4D)
125
126/* 0x4E OFDM_CAS_CTL */
127#define OFDM_CAS_CTL (0x4E)
128#define ACSDIS (0x40)
129#define CCSEN (0x80)
130
131/* 0x4F CAS_FREQ */
132#define CAS_FREQ (0x4F)
133
134/* 0x51 OFDM_SYR_CTL */
135#define OFDM_SYR_CTL (0x51)
136#define SIXTH_ENABLE (0x80)
137#define SYR_TRACKING_DISABLE (0x01)
138
139/* 0x52 OFDM_SYR_STAT */
140#define OFDM_SYR_STAT (0x52)
141#define GI14_2K_SYR_LOCK (0x13)
142#define GI14_8K_SYR_LOCK (0x17)
143#define GI14_SYR_LOCK (0x10)
144
145/* 0x55 OFDM_SYR_OFFSET_1 */
146#define OFDM_SYR_OFFSET_1 (0x55)
147
148/* 0x56 OFDM_SYR_OFFSET_2 */
149#define OFDM_SYR_OFFSET_2 (0x56)
150
151/* 0x58 OFDM_SCR_CTL */
152#define OFDM_SCR_CTL (0x58)
153#define SYR_ADJ_DECAY_MASK (0x70)
154#define SYR_ADJ_DECAY (0x30)
155
156/* 0x59 OFDM_PPM_CTL_1 */
157#define OFDM_PPM_CTL_1 (0x59)
158#define PPMMAX_MASK (0x30)
159#define PPM256 (0x30)
160
161/* 0x5B OFDM_TRL_NOMINALRATE_1 */
162#define OFDM_TRL_NOMINALRATE_1 (0x5B)
163
164/* 0x5C OFDM_TRL_NOMINALRATE_2 */
165#define OFDM_TRL_NOMINALRATE_2 (0x5C)
166
167/* 0x5D OFDM_TRL_TIME_1 */
168#define OFDM_TRL_TIME_1 (0x5D)
169
170/* 0x60 OFDM_CRL_FREQ_1 */
171#define OFDM_CRL_FREQ_1 (0x60)
172
173/* 0x63 OFDM_CHC_CTL_1 */
174#define OFDM_CHC_CTL_1 (0x63)
175#define MANMEAN1 (0xF0);
176#define CHCFIR (0x01)
177
178/* 0x64 OFDM_CHC_SNR */
179#define OFDM_CHC_SNR (0x64)
180
181/* 0x65 OFDM_BDI_CTL */
182#define OFDM_BDI_CTL (0x65)
183#define LP_SELECT (0x02)
184
185/* 0x67 OFDM_TPS_RCVD_1 */
186#define OFDM_TPS_RCVD_1 (0x67)
187#define TPSFRAME (0x03)
188
189/* 0x68 OFDM_TPS_RCVD_2 */
190#define OFDM_TPS_RCVD_2 (0x68)
191
192/* 0x69 OFDM_TPS_RCVD_3 */
193#define OFDM_TPS_RCVD_3 (0x69)
194
195/* 0x6A OFDM_TPS_RCVD_4 */
196#define OFDM_TPS_RCVD_4 (0x6A)
197
198/* 0x6B OFDM_TPS_RESERVED_1 */
199#define OFDM_TPS_RESERVED_1 (0x6B)
200
201/* 0x6C OFDM_TPS_RESERVED_2 */
202#define OFDM_TPS_RESERVED_2 (0x6C)
203
204/* 0x73 OFDM_MSC_REV */
205#define OFDM_MSC_REV (0x73)
206
207/* 0x76 OFDM_SNR_CARRIER_2 */
208#define OFDM_SNR_CARRIER_2 (0x76)
209#define MEAN_MASK (0x80)
210#define MEANBIT (0x80)
211
212/* 0x80 ANALOG_CONTROL_0 */
213#define ANALOG_CONTROL_0 (0x80)
214#define POWER_DOWN_ADC (0x40)
215
216/* 0x81 ENABLE_TUNER_IIC */
217#define ENABLE_TUNER_IIC (0x81)
218#define ENABLE_TUNER_BIT (0x01)
219
220/* 0x82 EN_DMD_RACQ */
221#define EN_DMD_RACQ (0x82)
222#define EN_DMD_RACQ_REG_VAL (0x81)
223#define EN_DMD_RACQ_REG_VAL_14 (0x01)
224
225/* 0x84 SNR_COMMAND */
226#define SNR_COMMAND (0x84)
227#define SNRStat (0x80)
228
229/* 0x85 SNRCARRIERNUMBER_LSB */
230#define SNRCARRIERNUMBER_LSB (0x85)
231
232/* 0x87 SNRMINTHRESHOLD_LSB */
233#define SNRMINTHRESHOLD_LSB (0x87)
234
235/* 0x89 SNR_PER_CARRIER_LSB */
236#define SNR_PER_CARRIER_LSB (0x89)
237
238/* 0x8B SNRBELOWTHRESHOLD_LSB */
239#define SNRBELOWTHRESHOLD_LSB (0x8B)
240
241/* 0x91 RF_AGC_VAL_1 */
242#define RF_AGC_VAL_1 (0x91)
243
244/* 0x92 RF_AGC_STATUS */
245#define RF_AGC_STATUS (0x92)
246
247/* 0x98 DIAG_CONFIG */
248#define DIAG_CONFIG (0x98)
249#define DIAG_MASK (0x70)
250#define TB_SET (0x10)
251#define TRAN_SELECT (0x07)
252#define SERIAL_SELECT (0x01)
253
254/* 0x99 SUB_DIAG_MODE_SEL */
255#define SUB_DIAG_MODE_SEL (0x99)
256#define CLKINVERSION (0x01)
257
258/* 0x9A TS_FORMAT */
259#define TS_FORMAT (0x9A)
260#define ERROR_SENSE (0x08)
261#define VALID_SENSE (0x04)
262#define SYNC_SENSE (0x02)
263#define GATED_CLOCK (0x01)
264
265#define NXT6000ASICDEVICE (0x0b)
diff --git a/drivers/media/dvb/frontends/or51132.c b/drivers/media/dvb/frontends/or51132.c
new file mode 100644
index 000000000000..df5dee7760a3
--- /dev/null
+++ b/drivers/media/dvb/frontends/or51132.c
@@ -0,0 +1,628 @@
1/*
2 * Support for OR51132 (pcHDTV HD-3000) - VSB/QAM
3 *
4 * Copyright (C) 2005 Kirk Lapray <kirk_lapray@bigfoot.com>
5 *
6 * Based on code from Jack Kelliher (kelliher@xmission.com)
7 * Copyright (C) 2002 & pcHDTV, inc.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23*/
24
25/*
26 * This driver needs two external firmware files. Please copy
27 * "dvb-fe-or51132-vsb.fw" and "dvb-fe-or51132-qam.fw" to
28 * /usr/lib/hotplug/firmware/ or /lib/firmware/
29 * (depending on configuration of firmware hotplug).
30 */
31#define OR51132_VSB_FIRMWARE "dvb-fe-or51132-vsb.fw"
32#define OR51132_QAM_FIRMWARE "dvb-fe-or51132-qam.fw"
33
34#include <linux/kernel.h>
35#include <linux/module.h>
36#include <linux/moduleparam.h>
37#include <linux/init.h>
38#include <linux/delay.h>
39#include <asm/byteorder.h>
40
41#include "dvb_frontend.h"
42#include "dvb-pll.h"
43#include "or51132.h"
44
45static int debug;
46#define dprintk(args...) \
47 do { \
48 if (debug) printk(KERN_DEBUG "or51132: " args); \
49 } while (0)
50
51
52struct or51132_state
53{
54 struct i2c_adapter* i2c;
55 struct dvb_frontend_ops ops;
56
57 /* Configuration settings */
58 const struct or51132_config* config;
59
60 struct dvb_frontend frontend;
61
62 /* Demodulator private data */
63 fe_modulation_t current_modulation;
64
65 /* Tuner private data */
66 u32 current_frequency;
67};
68
69static int i2c_writebytes (struct or51132_state* state, u8 reg, u8 *buf, int len)
70{
71 int err;
72 struct i2c_msg msg;
73 msg.addr = reg;
74 msg.flags = 0;
75 msg.len = len;
76 msg.buf = buf;
77
78 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
79 printk(KERN_WARNING "or51132: i2c_writebytes error (addr %02x, err == %i)\n", reg, err);
80 return -EREMOTEIO;
81 }
82
83 return 0;
84}
85
86static u8 i2c_readbytes (struct or51132_state* state, u8 reg, u8* buf, int len)
87{
88 int err;
89 struct i2c_msg msg;
90 msg.addr = reg;
91 msg.flags = I2C_M_RD;
92 msg.len = len;
93 msg.buf = buf;
94
95 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
96 printk(KERN_WARNING "or51132: i2c_readbytes error (addr %02x, err == %i)\n", reg, err);
97 return -EREMOTEIO;
98 }
99
100 return 0;
101}
102
103static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware *fw)
104{
105 struct or51132_state* state = (struct or51132_state*) fe->demodulator_priv;
106 static u8 run_buf[] = {0x7F,0x01};
107 static u8 get_ver_buf[] = {0x04,0x00,0x30,0x00,0x00};
108 u8 rec_buf[14];
109 u8 cmd_buf[14];
110 u32 firmwareAsize, firmwareBsize;
111 int i,ret;
112
113 dprintk("Firmware is %Zd bytes\n",fw->size);
114
115 /* Get size of firmware A and B */
116 firmwareAsize = le32_to_cpu(*((u32*)fw->data));
117 dprintk("FirmwareA is %i bytes\n",firmwareAsize);
118 firmwareBsize = le32_to_cpu(*((u32*)(fw->data+4)));
119 dprintk("FirmwareB is %i bytes\n",firmwareBsize);
120
121 /* Upload firmware */
122 if ((ret = i2c_writebytes(state,state->config->demod_address,
123 &fw->data[8],firmwareAsize))) {
124 printk(KERN_WARNING "or51132: load_firmware error 1\n");
125 return ret;
126 }
127 msleep(1); /* 1ms */
128 if ((ret = i2c_writebytes(state,state->config->demod_address,
129 &fw->data[8+firmwareAsize],firmwareBsize))) {
130 printk(KERN_WARNING "or51132: load_firmware error 2\n");
131 return ret;
132 }
133 msleep(1); /* 1ms */
134
135 if ((ret = i2c_writebytes(state,state->config->demod_address,
136 run_buf,2))) {
137 printk(KERN_WARNING "or51132: load_firmware error 3\n");
138 return ret;
139 }
140
141 /* Wait at least 5 msec */
142 msleep(20); /* 10ms */
143
144 if ((ret = i2c_writebytes(state,state->config->demod_address,
145 run_buf,2))) {
146 printk(KERN_WARNING "or51132: load_firmware error 4\n");
147 return ret;
148 }
149
150 /* 50ms for operation to begin */
151 msleep(50);
152
153 /* Read back ucode version to besure we loaded correctly and are really up and running */
154 /* Get uCode version */
155 cmd_buf[0] = 0x10;
156 cmd_buf[1] = 0x10;
157 cmd_buf[2] = 0x00;
158 cmd_buf[3] = 0x00;
159 msleep(20); /* 20ms */
160 if ((ret = i2c_writebytes(state,state->config->demod_address,
161 cmd_buf,3))) {
162 printk(KERN_WARNING "or51132: load_firmware error a\n");
163 return ret;
164 }
165
166 cmd_buf[0] = 0x04;
167 cmd_buf[1] = 0x17;
168 cmd_buf[2] = 0x00;
169 cmd_buf[3] = 0x00;
170 msleep(20); /* 20ms */
171 if ((ret = i2c_writebytes(state,state->config->demod_address,
172 cmd_buf,2))) {
173 printk(KERN_WARNING "or51132: load_firmware error b\n");
174 return ret;
175 }
176
177 cmd_buf[0] = 0x00;
178 cmd_buf[1] = 0x00;
179 cmd_buf[2] = 0x00;
180 cmd_buf[3] = 0x00;
181 msleep(20); /* 20ms */
182 if ((ret = i2c_writebytes(state,state->config->demod_address,
183 cmd_buf,2))) {
184 printk(KERN_WARNING "or51132: load_firmware error c\n");
185 return ret;
186 }
187
188 for(i=0;i<4;i++) {
189 msleep(20); /* 20ms */
190 get_ver_buf[4] = i+1;
191 if ((ret = i2c_readbytes(state,state->config->demod_address,
192 &rec_buf[i*2],2))) {
193 printk(KERN_WARNING
194 "or51132: load_firmware error d - %d\n",i);
195 return ret;
196 }
197 }
198
199 printk(KERN_WARNING
200 "or51132: Version: %02X%02X%02X%02X-%02X%02X%02X%02X (%02X%01X-%01X-%02X%01X-%01X)\n",
201 rec_buf[1],rec_buf[0],rec_buf[3],rec_buf[2],
202 rec_buf[5],rec_buf[4],rec_buf[7],rec_buf[6],
203 rec_buf[3],rec_buf[2]>>4,rec_buf[2]&0x0f,
204 rec_buf[5],rec_buf[4]>>4,rec_buf[4]&0x0f);
205
206 cmd_buf[0] = 0x10;
207 cmd_buf[1] = 0x00;
208 cmd_buf[2] = 0x00;
209 cmd_buf[3] = 0x00;
210 msleep(20); /* 20ms */
211 if ((ret = i2c_writebytes(state,state->config->demod_address,
212 cmd_buf,3))) {
213 printk(KERN_WARNING "or51132: load_firmware error e\n");
214 return ret;
215 }
216 return 0;
217};
218
219static int or51132_init(struct dvb_frontend* fe)
220{
221 return 0;
222}
223
224static int or51132_read_ber(struct dvb_frontend* fe, u32* ber)
225{
226 *ber = 0;
227 return 0;
228}
229
230static int or51132_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
231{
232 *ucblocks = 0;
233 return 0;
234}
235
236static int or51132_sleep(struct dvb_frontend* fe)
237{
238 return 0;
239}
240
241static int or51132_setmode(struct dvb_frontend* fe)
242{
243 struct or51132_state* state = (struct or51132_state*) fe->demodulator_priv;
244 unsigned char cmd_buf[4];
245
246 dprintk("setmode %d\n",(int)state->current_modulation);
247 /* set operation mode in Receiver 1 register; */
248 cmd_buf[0] = 0x04;
249 cmd_buf[1] = 0x01;
250 switch (state->current_modulation) {
251 case QAM_256:
252 case QAM_64:
253 case QAM_AUTO:
254 /* Auto-deinterleave; MPEG ser, MPEG2tr, phase noise-high*/
255 cmd_buf[2] = 0x5F;
256 break;
257 case VSB_8:
258 /* Auto CH, Auto NTSC rej, MPEGser, MPEG2tr, phase noise-high*/
259 cmd_buf[2] = 0x50;
260 break;
261 default:
262 printk("setmode:Modulation set to unsupported value\n");
263 };
264 cmd_buf[3] = 0x00;
265 if (i2c_writebytes(state,state->config->demod_address,
266 cmd_buf,3)) {
267 printk(KERN_WARNING "or51132: set_mode error 1\n");
268 return -1;
269 }
270 dprintk("or51132: set #1 to %02x\n", cmd_buf[2]);
271
272 /* Set operation mode in Receiver 6 register */
273 cmd_buf[0] = 0x1C;
274 switch (state->current_modulation) {
275 case QAM_AUTO:
276 /* REC MODE Normal Carrier Lock */
277 cmd_buf[1] = 0x00;
278 /* Channel MODE Auto QAM64/256 */
279 cmd_buf[2] = 0x4f;
280 break;
281 case QAM_256:
282 /* REC MODE Normal Carrier Lock */
283 cmd_buf[1] = 0x00;
284 /* Channel MODE QAM256 */
285 cmd_buf[2] = 0x45;
286 break;
287 case QAM_64:
288 /* REC MODE Normal Carrier Lock */
289 cmd_buf[1] = 0x00;
290 /* Channel MODE QAM64 */
291 cmd_buf[2] = 0x43;
292 break;
293 case VSB_8:
294 /* REC MODE inv IF spectrum, Normal */
295 cmd_buf[1] = 0x03;
296 /* Channel MODE ATSC/VSB8 */
297 cmd_buf[2] = 0x06;
298 break;
299 default:
300 printk("setmode: Modulation set to unsupported value\n");
301 };
302 cmd_buf[3] = 0x00;
303 msleep(20); /* 20ms */
304 if (i2c_writebytes(state,state->config->demod_address,
305 cmd_buf,3)) {
306 printk(KERN_WARNING "or51132: set_mode error 2\n");
307 return -1;
308 }
309 dprintk("or51132: set #6 to 0x%02x%02x\n", cmd_buf[1], cmd_buf[2]);
310
311 return 0;
312}
313
314static int or51132_set_parameters(struct dvb_frontend* fe,
315 struct dvb_frontend_parameters *param)
316{
317 int ret;
318 u8 buf[4];
319 struct or51132_state* state = (struct or51132_state*) fe->demodulator_priv;
320 const struct firmware *fw;
321
322 /* Change only if we are actually changing the modulation */
323 if (state->current_modulation != param->u.vsb.modulation) {
324 switch(param->u.vsb.modulation) {
325 case VSB_8:
326 dprintk("set_parameters VSB MODE\n");
327 printk("or51132: Waiting for firmware upload(%s)...\n",
328 OR51132_VSB_FIRMWARE);
329 ret = request_firmware(&fw, OR51132_VSB_FIRMWARE,
330 &state->i2c->dev);
331 if (ret){
332 printk(KERN_WARNING "or51132: No firmware up"
333 "loaded(timeout or file not found?)\n");
334 return ret;
335 }
336 /* Set non-punctured clock for VSB */
337 state->config->set_ts_params(fe, 0);
338 break;
339 case QAM_AUTO:
340 case QAM_64:
341 case QAM_256:
342 dprintk("set_parameters QAM MODE\n");
343 printk("or51132: Waiting for firmware upload(%s)...\n",
344 OR51132_QAM_FIRMWARE);
345 ret = request_firmware(&fw, OR51132_QAM_FIRMWARE,
346 &state->i2c->dev);
347 if (ret){
348 printk(KERN_WARNING "or51132: No firmware up"
349 "loaded(timeout or file not found?)\n");
350 return ret;
351 }
352 /* Set punctured clock for QAM */
353 state->config->set_ts_params(fe, 1);
354 break;
355 default:
356 printk("or51132:Modulation type(%d) UNSUPPORTED\n",
357 param->u.vsb.modulation);
358 return -1;
359 };
360 ret = or51132_load_firmware(fe, fw);
361 release_firmware(fw);
362 if (ret) {
363 printk(KERN_WARNING "or51132: Writing firmware to "
364 "device failed!\n");
365 return ret;
366 }
367 printk("or51132: Firmware upload complete.\n");
368
369 state->current_modulation = param->u.vsb.modulation;
370 or51132_setmode(fe);
371 }
372
373 /* Change only if we are actually changing the channel */
374 if (state->current_frequency != param->frequency) {
375 dvb_pll_configure(state->config->pll_desc, buf,
376 param->frequency, 0);
377 dprintk("set_parameters tuner bytes: 0x%02x 0x%02x "
378 "0x%02x 0x%02x\n",buf[0],buf[1],buf[2],buf[3]);
379 if (i2c_writebytes(state, state->config->pll_address ,buf, 4))
380 printk(KERN_WARNING "or51132: set_parameters error "
381 "writing to tuner\n");
382
383 /* Set to current mode */
384 or51132_setmode(fe);
385
386 /* Update current frequency */
387 state->current_frequency = param->frequency;
388 }
389 return 0;
390}
391
392static int or51132_read_status(struct dvb_frontend* fe, fe_status_t* status)
393{
394 struct or51132_state* state = (struct or51132_state*) fe->demodulator_priv;
395 unsigned char rec_buf[2];
396 unsigned char snd_buf[2];
397 *status = 0;
398
399 /* Receiver Status */
400 snd_buf[0]=0x04;
401 snd_buf[1]=0x00;
402 msleep(30); /* 30ms */
403 if (i2c_writebytes(state,state->config->demod_address,snd_buf,2)) {
404 printk(KERN_WARNING "or51132: read_status write error\n");
405 return -1;
406 }
407 msleep(30); /* 30ms */
408 if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) {
409 printk(KERN_WARNING "or51132: read_status read error\n");
410 return -1;
411 }
412 dprintk("read_status %x %x\n",rec_buf[0],rec_buf[1]);
413
414 if (rec_buf[1] & 0x01) { /* Receiver Lock */
415 *status |= FE_HAS_SIGNAL;
416 *status |= FE_HAS_CARRIER;
417 *status |= FE_HAS_VITERBI;
418 *status |= FE_HAS_SYNC;
419 *status |= FE_HAS_LOCK;
420 }
421 return 0;
422}
423
424/* log10-1 table at .5 increments from 1 to 100.5 */
425static unsigned int i100x20log10[] = {
426 0, 352, 602, 795, 954, 1088, 1204, 1306, 1397, 1480,
427 1556, 1625, 1690, 1750, 1806, 1858, 1908, 1955, 2000, 2042,
428 2082, 2121, 2158, 2193, 2227, 2260, 2292, 2322, 2352, 2380,
429 2408, 2434, 2460, 2486, 2510, 2534, 2557, 2580, 2602, 2623,
430 2644, 2664, 2684, 2704, 2723, 2742, 2760, 2778, 2795, 2813,
431 2829, 2846, 2862, 2878, 2894, 2909, 2924, 2939, 2954, 2968,
432 2982, 2996, 3010, 3023, 3037, 3050, 3062, 3075, 3088, 3100,
433 3112, 3124, 3136, 3148, 3159, 3170, 3182, 3193, 3204, 3214,
434 3225, 3236, 3246, 3256, 3266, 3276, 3286, 3296, 3306, 3316,
435 3325, 3334, 3344, 3353, 3362, 3371, 3380, 3389, 3397, 3406,
436 3415, 3423, 3432, 3440, 3448, 3456, 3464, 3472, 3480, 3488,
437 3496, 3504, 3511, 3519, 3526, 3534, 3541, 3549, 3556, 3563,
438 3570, 3577, 3584, 3591, 3598, 3605, 3612, 3619, 3625, 3632,
439 3639, 3645, 3652, 3658, 3665, 3671, 3677, 3683, 3690, 3696,
440 3702, 3708, 3714, 3720, 3726, 3732, 3738, 3744, 3750, 3755,
441 3761, 3767, 3772, 3778, 3784, 3789, 3795, 3800, 3806, 3811,
442 3816, 3822, 3827, 3832, 3838, 3843, 3848, 3853, 3858, 3863,
443 3868, 3874, 3879, 3884, 3888, 3893, 3898, 3903, 3908, 3913,
444 3918, 3922, 3927, 3932, 3936, 3941, 3946, 3950, 3955, 3960,
445 3964, 3969, 3973, 3978, 3982, 3986, 3991, 3995, 4000, 4004,
446};
447
448static unsigned int denom[] = {1,1,100,1000,10000,100000,1000000,10000000,100000000};
449
450static unsigned int i20Log10(unsigned short val)
451{
452 unsigned int rntval = 100;
453 unsigned int tmp = val;
454 unsigned int exp = 1;
455
456 while(tmp > 100) {tmp /= 100; exp++;}
457
458 val = (2 * val)/denom[exp];
459 if (exp > 1) rntval = 2000*exp;
460
461 rntval += i100x20log10[val];
462 return rntval;
463}
464
465static int or51132_read_signal_strength(struct dvb_frontend* fe, u16* strength)
466{
467 struct or51132_state* state = (struct or51132_state*) fe->demodulator_priv;
468 unsigned char rec_buf[2];
469 unsigned char snd_buf[2];
470 u8 rcvr_stat;
471 u16 snr_equ;
472 int usK;
473
474 snd_buf[0]=0x04;
475 snd_buf[1]=0x02; /* SNR after Equalizer */
476 msleep(30); /* 30ms */
477 if (i2c_writebytes(state,state->config->demod_address,snd_buf,2)) {
478 printk(KERN_WARNING "or51132: read_status write error\n");
479 return -1;
480 }
481 msleep(30); /* 30ms */
482 if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) {
483 printk(KERN_WARNING "or51132: read_status read error\n");
484 return -1;
485 }
486 snr_equ = rec_buf[0] | (rec_buf[1] << 8);
487 dprintk("read_signal_strength snr_equ %x %x (%i)\n",rec_buf[0],rec_buf[1],snr_equ);
488
489 /* Receiver Status */
490 snd_buf[0]=0x04;
491 snd_buf[1]=0x00;
492 msleep(30); /* 30ms */
493 if (i2c_writebytes(state,state->config->demod_address,snd_buf,2)) {
494 printk(KERN_WARNING "or51132: read_signal_strength read_status write error\n");
495 return -1;
496 }
497 msleep(30); /* 30ms */
498 if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) {
499 printk(KERN_WARNING "or51132: read_signal_strength read_status read error\n");
500 return -1;
501 }
502 dprintk("read_signal_strength read_status %x %x\n",rec_buf[0],rec_buf[1]);
503 rcvr_stat = rec_buf[1];
504 usK = (rcvr_stat & 0x10) ? 3 : 0;
505
506 /* The value reported back from the frontend will be FFFF=100% 0000=0% */
507 *strength = (((8952 - i20Log10(snr_equ) - usK*100)/3+5)*65535)/1000;
508 dprintk("read_signal_strength %i\n",*strength);
509
510 return 0;
511}
512
513static int or51132_read_snr(struct dvb_frontend* fe, u16* snr)
514{
515 struct or51132_state* state = (struct or51132_state*) fe->demodulator_priv;
516 unsigned char rec_buf[2];
517 unsigned char snd_buf[2];
518 u16 snr_equ;
519
520 snd_buf[0]=0x04;
521 snd_buf[1]=0x02; /* SNR after Equalizer */
522 msleep(30); /* 30ms */
523 if (i2c_writebytes(state,state->config->demod_address,snd_buf,2)) {
524 printk(KERN_WARNING "or51132: read_snr write error\n");
525 return -1;
526 }
527 msleep(30); /* 30ms */
528 if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) {
529 printk(KERN_WARNING "or51132: read_snr dvr read error\n");
530 return -1;
531 }
532 snr_equ = rec_buf[0] | (rec_buf[1] << 8);
533 dprintk("read_snr snr_equ %x %x (%i)\n",rec_buf[0],rec_buf[1],snr_equ);
534
535 *snr = 0xFFFF - snr_equ;
536 dprintk("read_snr %i\n",*snr);
537
538 return 0;
539}
540
541static int or51132_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fe_tune_settings)
542{
543 fe_tune_settings->min_delay_ms = 500;
544 fe_tune_settings->step_size = 0;
545 fe_tune_settings->max_drift = 0;
546
547 return 0;
548}
549
550static void or51132_release(struct dvb_frontend* fe)
551{
552 struct or51132_state* state = (struct or51132_state*) fe->demodulator_priv;
553 kfree(state);
554}
555
556static struct dvb_frontend_ops or51132_ops;
557
558struct dvb_frontend* or51132_attach(const struct or51132_config* config,
559 struct i2c_adapter* i2c)
560{
561 struct or51132_state* state = NULL;
562
563 /* Allocate memory for the internal state */
564 state = kmalloc(sizeof(struct or51132_state), GFP_KERNEL);
565 if (state == NULL)
566 goto error;
567
568 /* Setup the state */
569 state->config = config;
570 state->i2c = i2c;
571 memcpy(&state->ops, &or51132_ops, sizeof(struct dvb_frontend_ops));
572 state->current_frequency = -1;
573 state->current_modulation = -1;
574
575 /* Create dvb_frontend */
576 state->frontend.ops = &state->ops;
577 state->frontend.demodulator_priv = state;
578 return &state->frontend;
579
580error:
581 if (state)
582 kfree(state);
583 return NULL;
584}
585
586static struct dvb_frontend_ops or51132_ops = {
587
588 .info = {
589 .name = "Oren OR51132 VSB/QAM Frontend",
590 .type = FE_ATSC,
591 .frequency_min = 44000000,
592 .frequency_max = 958000000,
593 .frequency_stepsize = 166666,
594 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
595 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
596 FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_QAM_AUTO |
597 FE_CAN_8VSB
598 },
599
600 .release = or51132_release,
601
602 .init = or51132_init,
603 .sleep = or51132_sleep,
604
605 .set_frontend = or51132_set_parameters,
606 .get_tune_settings = or51132_get_tune_settings,
607
608 .read_status = or51132_read_status,
609 .read_ber = or51132_read_ber,
610 .read_signal_strength = or51132_read_signal_strength,
611 .read_snr = or51132_read_snr,
612 .read_ucblocks = or51132_read_ucblocks,
613};
614
615module_param(debug, int, 0644);
616MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
617
618MODULE_DESCRIPTION("OR51132 ATSC [pcHDTV HD-3000] (8VSB & ITU J83 AnnexB FEC QAM64/256) Demodulator Driver");
619MODULE_AUTHOR("Kirk Lapray");
620MODULE_LICENSE("GPL");
621
622EXPORT_SYMBOL(or51132_attach);
623
624/*
625 * Local variables:
626 * c-basic-offset: 8
627 * End:
628 */
diff --git a/drivers/media/dvb/frontends/or51132.h b/drivers/media/dvb/frontends/or51132.h
new file mode 100644
index 000000000000..622cdd18381b
--- /dev/null
+++ b/drivers/media/dvb/frontends/or51132.h
@@ -0,0 +1,48 @@
1/*
2 * Support for OR51132 (pcHDTV HD-3000) - VSB/QAM
3 *
4 * Copyright (C) 2005 Kirk Lapray <kirk_lapray@bigfoot.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20*/
21
22#ifndef OR51132_H
23#define OR51132_H
24
25#include <linux/firmware.h>
26#include <linux/dvb/frontend.h>
27
28struct or51132_config
29{
30 /* The demodulator's i2c address */
31 u8 demod_address;
32 u8 pll_address;
33 struct dvb_pll_desc *pll_desc;
34
35 /* Need to set device param for start_dma */
36 int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
37};
38
39extern struct dvb_frontend* or51132_attach(const struct or51132_config* config,
40 struct i2c_adapter* i2c);
41
42#endif // OR51132_H
43
44/*
45 * Local variables:
46 * c-basic-offset: 8
47 * End:
48 */
diff --git a/drivers/media/dvb/frontends/or51211.c b/drivers/media/dvb/frontends/or51211.c
new file mode 100644
index 000000000000..ad56a9958404
--- /dev/null
+++ b/drivers/media/dvb/frontends/or51211.c
@@ -0,0 +1,631 @@
1/*
2 * Support for OR51211 (pcHDTV HD-2000) - VSB
3 *
4 * Copyright (C) 2005 Kirk Lapray <kirk_lapray@bigfoot.com>
5 *
6 * Based on code from Jack Kelliher (kelliher@xmission.com)
7 * Copyright (C) 2002 & pcHDTV, inc.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23*/
24
25/*
26 * This driver needs external firmware. Please use the command
27 * "<kerneldir>/Documentation/dvb/get_dvb_firmware or51211" to
28 * download/extract it, and then copy it to /usr/lib/hotplug/firmware.
29 */
30#define OR51211_DEFAULT_FIRMWARE "dvb-fe-or51211.fw"
31
32#include <linux/kernel.h>
33#include <linux/module.h>
34#include <linux/moduleparam.h>
35#include <linux/device.h>
36#include <linux/firmware.h>
37#include <asm/byteorder.h>
38
39#include "dvb_frontend.h"
40#include "or51211.h"
41
42static int debug;
43#define dprintk(args...) \
44 do { \
45 if (debug) printk(KERN_DEBUG "or51211: " args); \
46 } while (0)
47
48static u8 run_buf[] = {0x7f,0x01};
49static u8 cmd_buf[] = {0x04,0x01,0x50,0x80,0x06}; // ATSC
50
51struct or51211_state {
52
53 struct i2c_adapter* i2c;
54 struct dvb_frontend_ops ops;
55
56 /* Configuration settings */
57 const struct or51211_config* config;
58
59 struct dvb_frontend frontend;
60 struct bt878* bt;
61
62 /* Demodulator private data */
63 u8 initialized:1;
64
65 /* Tuner private data */
66 u32 current_frequency;
67};
68
69static int i2c_writebytes (struct or51211_state* state, u8 reg, u8 *buf,
70 int len)
71{
72 int err;
73 struct i2c_msg msg;
74 msg.addr = reg;
75 msg.flags = 0;
76 msg.len = len;
77 msg.buf = buf;
78
79 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
80 printk(KERN_WARNING "or51211: i2c_writebytes error "
81 "(addr %02x, err == %i)\n", reg, err);
82 return -EREMOTEIO;
83 }
84
85 return 0;
86}
87
88static u8 i2c_readbytes (struct or51211_state* state, u8 reg, u8* buf, int len)
89{
90 int err;
91 struct i2c_msg msg;
92 msg.addr = reg;
93 msg.flags = I2C_M_RD;
94 msg.len = len;
95 msg.buf = buf;
96
97 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
98 printk(KERN_WARNING "or51211: i2c_readbytes error "
99 "(addr %02x, err == %i)\n", reg, err);
100 return -EREMOTEIO;
101 }
102
103 return 0;
104}
105
106static int or51211_load_firmware (struct dvb_frontend* fe,
107 const struct firmware *fw)
108{
109 struct or51211_state* state = fe->demodulator_priv;
110 u8 tudata[585];
111 int i;
112
113 dprintk("Firmware is %d bytes\n",fw->size);
114
115 /* Get eprom data */
116 tudata[0] = 17;
117 if (i2c_writebytes(state,0x50,tudata,1)) {
118 printk(KERN_WARNING "or51211:load_firmware error eprom addr\n");
119 return -1;
120 }
121 if (i2c_readbytes(state,0x50,&tudata[145],192)) {
122 printk(KERN_WARNING "or51211: load_firmware error eprom\n");
123 return -1;
124 }
125
126 /* Create firmware buffer */
127 for (i = 0; i < 145; i++)
128 tudata[i] = fw->data[i];
129
130 for (i = 0; i < 248; i++)
131 tudata[i+337] = fw->data[145+i];
132
133 state->config->reset(fe);
134
135 if (i2c_writebytes(state,state->config->demod_address,tudata,585)) {
136 printk(KERN_WARNING "or51211: load_firmware error 1\n");
137 return -1;
138 }
139 msleep(1);
140
141 if (i2c_writebytes(state,state->config->demod_address,
142 &fw->data[393],8125)) {
143 printk(KERN_WARNING "or51211: load_firmware error 2\n");
144 return -1;
145 }
146 msleep(1);
147
148 if (i2c_writebytes(state,state->config->demod_address,run_buf,2)) {
149 printk(KERN_WARNING "or51211: load_firmware error 3\n");
150 return -1;
151 }
152
153 /* Wait at least 5 msec */
154 msleep(10);
155 if (i2c_writebytes(state,state->config->demod_address,run_buf,2)) {
156 printk(KERN_WARNING "or51211: load_firmware error 4\n");
157 return -1;
158 }
159 msleep(10);
160
161 printk("or51211: Done.\n");
162 return 0;
163};
164
165static int or51211_setmode(struct dvb_frontend* fe, int mode)
166{
167 struct or51211_state* state = fe->demodulator_priv;
168 u8 rec_buf[14];
169
170 state->config->setmode(fe, mode);
171
172 if (i2c_writebytes(state,state->config->demod_address,run_buf,2)) {
173 printk(KERN_WARNING "or51211: setmode error 1\n");
174 return -1;
175 }
176
177 /* Wait at least 5 msec */
178 msleep(10);
179 if (i2c_writebytes(state,state->config->demod_address,run_buf,2)) {
180 printk(KERN_WARNING "or51211: setmode error 2\n");
181 return -1;
182 }
183
184 msleep(10);
185
186 /* Set operation mode in Receiver 1 register;
187 * type 1:
188 * data 0x50h Automatic sets receiver channel conditions
189 * Automatic NTSC rejection filter
190 * Enable MPEG serial data output
191 * MPEG2tr
192 * High tuner phase noise
193 * normal +/-150kHz Carrier acquisition range
194 */
195 if (i2c_writebytes(state,state->config->demod_address,cmd_buf,3)) {
196 printk(KERN_WARNING "or51211: setmode error 3\n");
197 return -1;
198 }
199
200 rec_buf[0] = 0x04;
201 rec_buf[1] = 0x00;
202 rec_buf[2] = 0x03;
203 rec_buf[3] = 0x00;
204 msleep(20);
205 if (i2c_writebytes(state,state->config->demod_address,rec_buf,3)) {
206 printk(KERN_WARNING "or51211: setmode error 5\n");
207 }
208 msleep(3);
209 if (i2c_readbytes(state,state->config->demod_address,&rec_buf[10],2)) {
210 printk(KERN_WARNING "or51211: setmode error 6");
211 return -1;
212 }
213 dprintk("setmode rec status %02x %02x\n",rec_buf[10],rec_buf[11]);
214
215 return 0;
216}
217
218static int or51211_set_parameters(struct dvb_frontend* fe,
219 struct dvb_frontend_parameters *param)
220{
221 struct or51211_state* state = fe->demodulator_priv;
222 u32 freq = 0;
223 u16 tunerfreq = 0;
224 u8 buf[4];
225
226 /* Change only if we are actually changing the channel */
227 if (state->current_frequency != param->frequency) {
228 freq = 44000 + (param->frequency/1000);
229 tunerfreq = freq * 16/1000;
230
231 dprintk("set_parameters frequency = %d (tunerfreq = %d)\n",
232 param->frequency,tunerfreq);
233
234 buf[0] = (tunerfreq >> 8) & 0x7F;
235 buf[1] = (tunerfreq & 0xFF);
236 buf[2] = 0x8E;
237
238 if (param->frequency < 157250000) {
239 buf[3] = 0xA0;
240 dprintk("set_parameters VHF low range\n");
241 } else if (param->frequency < 454000000) {
242 buf[3] = 0x90;
243 dprintk("set_parameters VHF high range\n");
244 } else {
245 buf[3] = 0x30;
246 dprintk("set_parameters UHF range\n");
247 }
248 dprintk("set_parameters tuner bytes: 0x%02x 0x%02x "
249 "0x%02x 0x%02x\n",buf[0],buf[1],buf[2],buf[3]);
250
251 if (i2c_writebytes(state,0xC2>>1,buf,4))
252 printk(KERN_WARNING "or51211:set_parameters error "
253 "writing to tuner\n");
254
255 /* Set to ATSC mode */
256 or51211_setmode(fe,0);
257
258 /* Update current frequency */
259 state->current_frequency = param->frequency;
260 }
261 return 0;
262}
263
264static int or51211_read_status(struct dvb_frontend* fe, fe_status_t* status)
265{
266 struct or51211_state* state = fe->demodulator_priv;
267 unsigned char rec_buf[2];
268 unsigned char snd_buf[] = {0x04,0x00,0x03,0x00};
269 *status = 0;
270
271 /* Receiver Status */
272 if (i2c_writebytes(state,state->config->demod_address,snd_buf,3)) {
273 printk(KERN_WARNING "or51132: read_status write error\n");
274 return -1;
275 }
276 msleep(3);
277 if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) {
278 printk(KERN_WARNING "or51132: read_status read error\n");
279 return -1;
280 }
281 dprintk("read_status %x %x\n",rec_buf[0],rec_buf[1]);
282
283 if (rec_buf[0] & 0x01) { /* Receiver Lock */
284 *status |= FE_HAS_SIGNAL;
285 *status |= FE_HAS_CARRIER;
286 *status |= FE_HAS_VITERBI;
287 *status |= FE_HAS_SYNC;
288 *status |= FE_HAS_LOCK;
289 }
290 return 0;
291}
292
293/* log10-1 table at .5 increments from 1 to 100.5 */
294static unsigned int i100x20log10[] = {
295 0, 352, 602, 795, 954, 1088, 1204, 1306, 1397, 1480,
296 1556, 1625, 1690, 1750, 1806, 1858, 1908, 1955, 2000, 2042,
297 2082, 2121, 2158, 2193, 2227, 2260, 2292, 2322, 2352, 2380,
298 2408, 2434, 2460, 2486, 2510, 2534, 2557, 2580, 2602, 2623,
299 2644, 2664, 2684, 2704, 2723, 2742, 2760, 2778, 2795, 2813,
300 2829, 2846, 2862, 2878, 2894, 2909, 2924, 2939, 2954, 2968,
301 2982, 2996, 3010, 3023, 3037, 3050, 3062, 3075, 3088, 3100,
302 3112, 3124, 3136, 3148, 3159, 3170, 3182, 3193, 3204, 3214,
303 3225, 3236, 3246, 3256, 3266, 3276, 3286, 3296, 3306, 3316,
304 3325, 3334, 3344, 3353, 3362, 3371, 3380, 3389, 3397, 3406,
305 3415, 3423, 3432, 3440, 3448, 3456, 3464, 3472, 3480, 3488,
306 3496, 3504, 3511, 3519, 3526, 3534, 3541, 3549, 3556, 3563,
307 3570, 3577, 3584, 3591, 3598, 3605, 3612, 3619, 3625, 3632,
308 3639, 3645, 3652, 3658, 3665, 3671, 3677, 3683, 3690, 3696,
309 3702, 3708, 3714, 3720, 3726, 3732, 3738, 3744, 3750, 3755,
310 3761, 3767, 3772, 3778, 3784, 3789, 3795, 3800, 3806, 3811,
311 3816, 3822, 3827, 3832, 3838, 3843, 3848, 3853, 3858, 3863,
312 3868, 3874, 3879, 3884, 3888, 3893, 3898, 3903, 3908, 3913,
313 3918, 3922, 3927, 3932, 3936, 3941, 3946, 3950, 3955, 3960,
314 3964, 3969, 3973, 3978, 3982, 3986, 3991, 3995, 4000, 4004,
315};
316
317static unsigned int denom[] = {1,1,100,1000,10000,100000,1000000,10000000,100000000};
318
319static unsigned int i20Log10(unsigned short val)
320{
321 unsigned int rntval = 100;
322 unsigned int tmp = val;
323 unsigned int exp = 1;
324
325 while(tmp > 100) {tmp /= 100; exp++;}
326
327 val = (2 * val)/denom[exp];
328 if (exp > 1) rntval = 2000*exp;
329
330 rntval += i100x20log10[val];
331 return rntval;
332}
333
334static int or51211_read_signal_strength(struct dvb_frontend* fe, u16* strength)
335{
336 struct or51211_state* state = fe->demodulator_priv;
337 u8 rec_buf[2];
338 u8 snd_buf[4];
339 u8 snr_equ;
340
341 /* SNR after Equalizer */
342 snd_buf[0] = 0x04;
343 snd_buf[1] = 0x00;
344 snd_buf[2] = 0x04;
345 snd_buf[3] = 0x00;
346
347 if (i2c_writebytes(state,state->config->demod_address,snd_buf,3)) {
348 printk(KERN_WARNING "or51211: read_status write error\n");
349 return -1;
350 }
351 msleep(3);
352 if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) {
353 printk(KERN_WARNING "or51211: read_status read error\n");
354 return -1;
355 }
356 snr_equ = rec_buf[0] & 0xff;
357
358 /* The value reported back from the frontend will be FFFF=100% 0000=0% */
359 *strength = (((5334 - i20Log10(snr_equ))/3+5)*65535)/1000;
360
361 dprintk("read_signal_strength %i\n",*strength);
362
363 return 0;
364}
365
366static int or51211_read_snr(struct dvb_frontend* fe, u16* snr)
367{
368 struct or51211_state* state = fe->demodulator_priv;
369 u8 rec_buf[2];
370 u8 snd_buf[4];
371
372 /* SNR after Equalizer */
373 snd_buf[0] = 0x04;
374 snd_buf[1] = 0x00;
375 snd_buf[2] = 0x04;
376 snd_buf[3] = 0x00;
377
378 if (i2c_writebytes(state,state->config->demod_address,snd_buf,3)) {
379 printk(KERN_WARNING "or51211: read_status write error\n");
380 return -1;
381 }
382 msleep(3);
383 if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) {
384 printk(KERN_WARNING "or51211: read_status read error\n");
385 return -1;
386 }
387 *snr = rec_buf[0] & 0xff;
388
389 dprintk("read_snr %i\n",*snr);
390
391 return 0;
392}
393
394static int or51211_read_ber(struct dvb_frontend* fe, u32* ber)
395{
396 *ber = -ENOSYS;
397 return 0;
398}
399
400static int or51211_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
401{
402 *ucblocks = -ENOSYS;
403 return 0;
404}
405
406static int or51211_sleep(struct dvb_frontend* fe)
407{
408 return 0;
409}
410
411static int or51211_init(struct dvb_frontend* fe)
412{
413 struct or51211_state* state = fe->demodulator_priv;
414 const struct or51211_config* config = state->config;
415 const struct firmware* fw;
416 unsigned char get_ver_buf[] = {0x04,0x00,0x30,0x00,0x00};
417 unsigned char rec_buf[14];
418 int ret,i;
419
420 if (!state->initialized) {
421 /* Request the firmware, this will block until it uploads */
422 printk(KERN_INFO "or51211: Waiting for firmware upload "
423 "(%s)...\n", OR51211_DEFAULT_FIRMWARE);
424 ret = config->request_firmware(fe, &fw,
425 OR51211_DEFAULT_FIRMWARE);
426 printk(KERN_INFO "or51211:Got Hotplug firmware\n");
427 if (ret) {
428 printk(KERN_WARNING "or51211: No firmware uploaded "
429 "(timeout or file not found?)\n");
430 return ret;
431 }
432
433 ret = or51211_load_firmware(fe, fw);
434 if (ret) {
435 printk(KERN_WARNING "or51211: Writing firmware to "
436 "device failed!\n");
437 release_firmware(fw);
438 return ret;
439 }
440 printk(KERN_INFO "or51211: Firmware upload complete.\n");
441
442 /* Set operation mode in Receiver 1 register;
443 * type 1:
444 * data 0x50h Automatic sets receiver channel conditions
445 * Automatic NTSC rejection filter
446 * Enable MPEG serial data output
447 * MPEG2tr
448 * High tuner phase noise
449 * normal +/-150kHz Carrier acquisition range
450 */
451 if (i2c_writebytes(state,state->config->demod_address,
452 cmd_buf,3)) {
453 printk(KERN_WARNING "or51211: Load DVR Error 5\n");
454 return -1;
455 }
456
457 /* Read back ucode version to besure we loaded correctly */
458 /* and are really up and running */
459 rec_buf[0] = 0x04;
460 rec_buf[1] = 0x00;
461 rec_buf[2] = 0x03;
462 rec_buf[3] = 0x00;
463 msleep(30);
464 if (i2c_writebytes(state,state->config->demod_address,
465 rec_buf,3)) {
466 printk(KERN_WARNING "or51211: Load DVR Error A\n");
467 return -1;
468 }
469 msleep(3);
470 if (i2c_readbytes(state,state->config->demod_address,
471 &rec_buf[10],2)) {
472 printk(KERN_WARNING "or51211: Load DVR Error B\n");
473 return -1;
474 }
475
476 rec_buf[0] = 0x04;
477 rec_buf[1] = 0x00;
478 rec_buf[2] = 0x01;
479 rec_buf[3] = 0x00;
480 msleep(20);
481 if (i2c_writebytes(state,state->config->demod_address,
482 rec_buf,3)) {
483 printk(KERN_WARNING "or51211: Load DVR Error C\n");
484 return -1;
485 }
486 msleep(3);
487 if (i2c_readbytes(state,state->config->demod_address,
488 &rec_buf[12],2)) {
489 printk(KERN_WARNING "or51211: Load DVR Error D\n");
490 return -1;
491 }
492
493 for (i = 0; i < 8; i++)
494 rec_buf[i]=0xed;
495
496 for (i = 0; i < 5; i++) {
497 msleep(30);
498 get_ver_buf[4] = i+1;
499 if (i2c_writebytes(state,state->config->demod_address,
500 get_ver_buf,5)) {
501 printk(KERN_WARNING "or51211:Load DVR Error 6"
502 " - %d\n",i);
503 return -1;
504 }
505 msleep(3);
506
507 if (i2c_readbytes(state,state->config->demod_address,
508 &rec_buf[i*2],2)) {
509 printk(KERN_WARNING "or51211:Load DVR Error 7"
510 " - %d\n",i);
511 return -1;
512 }
513 /* If we didn't receive the right index, try again */
514 if ((int)rec_buf[i*2+1]!=i+1){
515 i--;
516 }
517 }
518 dprintk("read_fwbits %x %x %x %x %x %x %x %x %x %x\n",
519 rec_buf[0], rec_buf[1], rec_buf[2], rec_buf[3],
520 rec_buf[4], rec_buf[5], rec_buf[6], rec_buf[7],
521 rec_buf[8], rec_buf[9]);
522
523 printk(KERN_INFO "or51211: ver TU%02x%02x%02x VSB mode %02x"
524 " Status %02x\n",
525 rec_buf[2], rec_buf[4],rec_buf[6],
526 rec_buf[12],rec_buf[10]);
527
528 rec_buf[0] = 0x04;
529 rec_buf[1] = 0x00;
530 rec_buf[2] = 0x03;
531 rec_buf[3] = 0x00;
532 msleep(20);
533 if (i2c_writebytes(state,state->config->demod_address,
534 rec_buf,3)) {
535 printk(KERN_WARNING "or51211: Load DVR Error 8\n");
536 return -1;
537 }
538 msleep(20);
539 if (i2c_readbytes(state,state->config->demod_address,
540 &rec_buf[8],2)) {
541 printk(KERN_WARNING "or51211: Load DVR Error 9\n");
542 return -1;
543 }
544 state->initialized = 1;
545 }
546
547 return 0;
548}
549
550static int or51211_get_tune_settings(struct dvb_frontend* fe,
551 struct dvb_frontend_tune_settings* fesettings)
552{
553 fesettings->min_delay_ms = 500;
554 fesettings->step_size = 0;
555 fesettings->max_drift = 0;
556 return 0;
557}
558
559static void or51211_release(struct dvb_frontend* fe)
560{
561 struct or51211_state* state = fe->demodulator_priv;
562 state->config->sleep(fe);
563 kfree(state);
564}
565
566static struct dvb_frontend_ops or51211_ops;
567
568struct dvb_frontend* or51211_attach(const struct or51211_config* config,
569 struct i2c_adapter* i2c)
570{
571 struct or51211_state* state = NULL;
572
573 /* Allocate memory for the internal state */
574 state = kmalloc(sizeof(struct or51211_state), GFP_KERNEL);
575 if (state == NULL)
576 goto error;
577
578 /* Setup the state */
579 state->config = config;
580 state->i2c = i2c;
581 memcpy(&state->ops, &or51211_ops, sizeof(struct dvb_frontend_ops));
582 state->initialized = 0;
583 state->current_frequency = 0;
584
585 /* Create dvb_frontend */
586 state->frontend.ops = &state->ops;
587 state->frontend.demodulator_priv = state;
588 return &state->frontend;
589
590error:
591 kfree(state);
592 return NULL;
593}
594
595static struct dvb_frontend_ops or51211_ops = {
596
597 .info = {
598 .name = "Oren OR51211 VSB Frontend",
599 .type = FE_ATSC,
600 .frequency_min = 44000000,
601 .frequency_max = 958000000,
602 .frequency_stepsize = 166666,
603 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
604 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
605 FE_CAN_8VSB
606 },
607
608 .release = or51211_release,
609
610 .init = or51211_init,
611 .sleep = or51211_sleep,
612
613 .set_frontend = or51211_set_parameters,
614 .get_tune_settings = or51211_get_tune_settings,
615
616 .read_status = or51211_read_status,
617 .read_ber = or51211_read_ber,
618 .read_signal_strength = or51211_read_signal_strength,
619 .read_snr = or51211_read_snr,
620 .read_ucblocks = or51211_read_ucblocks,
621};
622
623module_param(debug, int, 0644);
624MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
625
626MODULE_DESCRIPTION("Oren OR51211 VSB [pcHDTV HD-2000] Demodulator Driver");
627MODULE_AUTHOR("Kirk Lapray");
628MODULE_LICENSE("GPL");
629
630EXPORT_SYMBOL(or51211_attach);
631
diff --git a/drivers/media/dvb/frontends/or51211.h b/drivers/media/dvb/frontends/or51211.h
new file mode 100644
index 000000000000..13a5a3afbf8b
--- /dev/null
+++ b/drivers/media/dvb/frontends/or51211.h
@@ -0,0 +1,44 @@
1/*
2 * Support for OR51211 (pcHDTV HD-2000) - VSB
3 *
4 * Copyright (C) 2005 Kirk Lapray <kirk_lapray@bigfoot.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20*/
21
22#ifndef OR51211_H
23#define OR51211_H
24
25#include <linux/dvb/frontend.h>
26#include <linux/firmware.h>
27
28struct or51211_config
29{
30 /* The demodulator's i2c address */
31 u8 demod_address;
32
33 /* Request firmware for device */
34 int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
35 void (*setmode)(struct dvb_frontend * fe, int mode);
36 void (*reset)(struct dvb_frontend * fe);
37 void (*sleep)(struct dvb_frontend * fe);
38};
39
40extern struct dvb_frontend* or51211_attach(const struct or51211_config* config,
41 struct i2c_adapter* i2c);
42
43#endif // OR51211_H
44
diff --git a/drivers/media/dvb/frontends/sp8870.c b/drivers/media/dvb/frontends/sp8870.c
new file mode 100644
index 000000000000..58ad34ef0a00
--- /dev/null
+++ b/drivers/media/dvb/frontends/sp8870.c
@@ -0,0 +1,614 @@
1/*
2 Driver for Spase SP8870 demodulator
3
4 Copyright (C) 1999 Juergen Peitz
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21*/
22/*
23 * This driver needs external firmware. Please use the command
24 * "<kerneldir>/Documentation/dvb/get_dvb_firmware alps_tdlb7" to
25 * download/extract it, and then copy it to /usr/lib/hotplug/firmware.
26 */
27#define SP8870_DEFAULT_FIRMWARE "dvb-fe-sp8870.fw"
28
29#include <linux/init.h>
30#include <linux/module.h>
31#include <linux/moduleparam.h>
32#include <linux/device.h>
33#include <linux/firmware.h>
34#include <linux/delay.h>
35
36#include "dvb_frontend.h"
37#include "sp8870.h"
38
39
40struct sp8870_state {
41
42 struct i2c_adapter* i2c;
43
44 struct dvb_frontend_ops ops;
45
46 const struct sp8870_config* config;
47
48 struct dvb_frontend frontend;
49
50 /* demodulator private data */
51 u8 initialised:1;
52};
53
54static int debug;
55#define dprintk(args...) \
56 do { \
57 if (debug) printk(KERN_DEBUG "sp8870: " args); \
58 } while (0)
59
60/* firmware size for sp8870 */
61#define SP8870_FIRMWARE_SIZE 16382
62
63/* starting point for firmware in file 'Sc_main.mc' */
64#define SP8870_FIRMWARE_OFFSET 0x0A
65
66static int sp8870_writereg (struct sp8870_state* state, u16 reg, u16 data)
67{
68 u8 buf [] = { reg >> 8, reg & 0xff, data >> 8, data & 0xff };
69 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 4 };
70 int err;
71
72 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
73 dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __FUNCTION__, err, reg, data);
74 return -EREMOTEIO;
75 }
76
77 return 0;
78}
79
80static int sp8870_readreg (struct sp8870_state* state, u16 reg)
81{
82 int ret;
83 u8 b0 [] = { reg >> 8 , reg & 0xff };
84 u8 b1 [] = { 0, 0 };
85 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 2 },
86 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 2 } };
87
88 ret = i2c_transfer (state->i2c, msg, 2);
89
90 if (ret != 2) {
91 dprintk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret);
92 return -1;
93 }
94
95 return (b1[0] << 8 | b1[1]);
96}
97
98static int sp8870_firmware_upload (struct sp8870_state* state, const struct firmware *fw)
99{
100 struct i2c_msg msg;
101 char *fw_buf = fw->data;
102 int fw_pos;
103 u8 tx_buf[255];
104 int tx_len;
105 int err = 0;
106
107 dprintk ("%s: ...\n", __FUNCTION__);
108
109 if (fw->size < SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET)
110 return -EINVAL;
111
112 // system controller stop
113 sp8870_writereg(state, 0x0F00, 0x0000);
114
115 // instruction RAM register hiword
116 sp8870_writereg(state, 0x8F08, ((SP8870_FIRMWARE_SIZE / 2) & 0xFFFF));
117
118 // instruction RAM MWR
119 sp8870_writereg(state, 0x8F0A, ((SP8870_FIRMWARE_SIZE / 2) >> 16));
120
121 // do firmware upload
122 fw_pos = SP8870_FIRMWARE_OFFSET;
123 while (fw_pos < SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET){
124 tx_len = (fw_pos <= SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET - 252) ? 252 : SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET - fw_pos;
125 // write register 0xCF0A
126 tx_buf[0] = 0xCF;
127 tx_buf[1] = 0x0A;
128 memcpy(&tx_buf[2], fw_buf + fw_pos, tx_len);
129 msg.addr = state->config->demod_address;
130 msg.flags = 0;
131 msg.buf = tx_buf;
132 msg.len = tx_len + 2;
133 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
134 printk("%s: firmware upload failed!\n", __FUNCTION__);
135 printk ("%s: i2c error (err == %i)\n", __FUNCTION__, err);
136 return err;
137 }
138 fw_pos += tx_len;
139 }
140
141 dprintk ("%s: done!\n", __FUNCTION__);
142 return 0;
143};
144
145static void sp8870_microcontroller_stop (struct sp8870_state* state)
146{
147 sp8870_writereg(state, 0x0F08, 0x000);
148 sp8870_writereg(state, 0x0F09, 0x000);
149
150 // microcontroller STOP
151 sp8870_writereg(state, 0x0F00, 0x000);
152}
153
154static void sp8870_microcontroller_start (struct sp8870_state* state)
155{
156 sp8870_writereg(state, 0x0F08, 0x000);
157 sp8870_writereg(state, 0x0F09, 0x000);
158
159 // microcontroller START
160 sp8870_writereg(state, 0x0F00, 0x001);
161 // not documented but if we don't read 0x0D01 out here
162 // we don't get a correct data valid signal
163 sp8870_readreg(state, 0x0D01);
164}
165
166static int sp8870_read_data_valid_signal(struct sp8870_state* state)
167{
168 return (sp8870_readreg(state, 0x0D02) > 0);
169}
170
171static int configure_reg0xc05 (struct dvb_frontend_parameters *p, u16 *reg0xc05)
172{
173 int known_parameters = 1;
174
175 *reg0xc05 = 0x000;
176
177 switch (p->u.ofdm.constellation) {
178 case QPSK:
179 break;
180 case QAM_16:
181 *reg0xc05 |= (1 << 10);
182 break;
183 case QAM_64:
184 *reg0xc05 |= (2 << 10);
185 break;
186 case QAM_AUTO:
187 known_parameters = 0;
188 break;
189 default:
190 return -EINVAL;
191 };
192
193 switch (p->u.ofdm.hierarchy_information) {
194 case HIERARCHY_NONE:
195 break;
196 case HIERARCHY_1:
197 *reg0xc05 |= (1 << 7);
198 break;
199 case HIERARCHY_2:
200 *reg0xc05 |= (2 << 7);
201 break;
202 case HIERARCHY_4:
203 *reg0xc05 |= (3 << 7);
204 break;
205 case HIERARCHY_AUTO:
206 known_parameters = 0;
207 break;
208 default:
209 return -EINVAL;
210 };
211
212 switch (p->u.ofdm.code_rate_HP) {
213 case FEC_1_2:
214 break;
215 case FEC_2_3:
216 *reg0xc05 |= (1 << 3);
217 break;
218 case FEC_3_4:
219 *reg0xc05 |= (2 << 3);
220 break;
221 case FEC_5_6:
222 *reg0xc05 |= (3 << 3);
223 break;
224 case FEC_7_8:
225 *reg0xc05 |= (4 << 3);
226 break;
227 case FEC_AUTO:
228 known_parameters = 0;
229 break;
230 default:
231 return -EINVAL;
232 };
233
234 if (known_parameters)
235 *reg0xc05 |= (2 << 1); /* use specified parameters */
236 else
237 *reg0xc05 |= (1 << 1); /* enable autoprobing */
238
239 return 0;
240}
241
242static int sp8870_wake_up(struct sp8870_state* state)
243{
244 // enable TS output and interface pins
245 return sp8870_writereg(state, 0xC18, 0x00D);
246}
247
248static int sp8870_set_frontend_parameters (struct dvb_frontend* fe,
249 struct dvb_frontend_parameters *p)
250{
251 struct sp8870_state* state = (struct sp8870_state*) fe->demodulator_priv;
252 int err;
253 u16 reg0xc05;
254
255 if ((err = configure_reg0xc05(p, &reg0xc05)))
256 return err;
257
258 // system controller stop
259 sp8870_microcontroller_stop(state);
260
261 // set tuner parameters
262 sp8870_writereg(state, 0x206, 0x001);
263 state->config->pll_set(fe, p);
264 sp8870_writereg(state, 0x206, 0x000);
265
266 // sample rate correction bit [23..17]
267 sp8870_writereg(state, 0x0319, 0x000A);
268
269 // sample rate correction bit [16..0]
270 sp8870_writereg(state, 0x031A, 0x0AAB);
271
272 // integer carrier offset
273 sp8870_writereg(state, 0x0309, 0x0400);
274
275 // fractional carrier offset
276 sp8870_writereg(state, 0x030A, 0x0000);
277
278 // filter for 6/7/8 Mhz channel
279 if (p->u.ofdm.bandwidth == BANDWIDTH_6_MHZ)
280 sp8870_writereg(state, 0x0311, 0x0002);
281 else if (p->u.ofdm.bandwidth == BANDWIDTH_7_MHZ)
282 sp8870_writereg(state, 0x0311, 0x0001);
283 else
284 sp8870_writereg(state, 0x0311, 0x0000);
285
286 // scan order: 2k first = 0x0000, 8k first = 0x0001
287 if (p->u.ofdm.transmission_mode == TRANSMISSION_MODE_2K)
288 sp8870_writereg(state, 0x0338, 0x0000);
289 else
290 sp8870_writereg(state, 0x0338, 0x0001);
291
292 sp8870_writereg(state, 0xc05, reg0xc05);
293
294 // read status reg in order to clear pending irqs
295 sp8870_readreg(state, 0x200);
296
297 // system controller start
298 sp8870_microcontroller_start(state);
299
300 return 0;
301}
302
303static int sp8870_init (struct dvb_frontend* fe)
304{
305 struct sp8870_state* state = (struct sp8870_state*) fe->demodulator_priv;
306 const struct firmware *fw = NULL;
307
308 sp8870_wake_up(state);
309 if (state->initialised) return 0;
310 state->initialised = 1;
311
312 dprintk ("%s\n", __FUNCTION__);
313
314
315 /* request the firmware, this will block until someone uploads it */
316 printk("sp8870: waiting for firmware upload (%s)...\n", SP8870_DEFAULT_FIRMWARE);
317 if (state->config->request_firmware(fe, &fw, SP8870_DEFAULT_FIRMWARE)) {
318 printk("sp8870: no firmware upload (timeout or file not found?)\n");
319 release_firmware(fw);
320 return -EIO;
321 }
322
323 if (sp8870_firmware_upload(state, fw)) {
324 printk("sp8870: writing firmware to device failed\n");
325 release_firmware(fw);
326 return -EIO;
327 }
328 printk("sp8870: firmware upload complete\n");
329
330 /* enable TS output and interface pins */
331 sp8870_writereg(state, 0xc18, 0x00d);
332
333 // system controller stop
334 sp8870_microcontroller_stop(state);
335
336 // ADC mode
337 sp8870_writereg(state, 0x0301, 0x0003);
338
339 // Reed Solomon parity bytes passed to output
340 sp8870_writereg(state, 0x0C13, 0x0001);
341
342 // MPEG clock is suppressed if no valid data
343 sp8870_writereg(state, 0x0C14, 0x0001);
344
345 /* bit 0x010: enable data valid signal */
346 sp8870_writereg(state, 0x0D00, 0x010);
347 sp8870_writereg(state, 0x0D01, 0x000);
348
349 /* setup PLL */
350 if (state->config->pll_init) {
351 sp8870_writereg(state, 0x206, 0x001);
352 state->config->pll_init(fe);
353 sp8870_writereg(state, 0x206, 0x000);
354 }
355
356 return 0;
357}
358
359static int sp8870_read_status (struct dvb_frontend* fe, fe_status_t * fe_status)
360{
361 struct sp8870_state* state = (struct sp8870_state*) fe->demodulator_priv;
362 int status;
363 int signal;
364
365 *fe_status = 0;
366
367 status = sp8870_readreg (state, 0x0200);
368 if (status < 0)
369 return -EIO;
370
371 signal = sp8870_readreg (state, 0x0303);
372 if (signal < 0)
373 return -EIO;
374
375 if (signal > 0x0F)
376 *fe_status |= FE_HAS_SIGNAL;
377 if (status & 0x08)
378 *fe_status |= FE_HAS_SYNC;
379 if (status & 0x04)
380 *fe_status |= FE_HAS_LOCK | FE_HAS_CARRIER | FE_HAS_VITERBI;
381
382 return 0;
383}
384
385static int sp8870_read_ber (struct dvb_frontend* fe, u32 * ber)
386{
387 struct sp8870_state* state = (struct sp8870_state*) fe->demodulator_priv;
388 int ret;
389 u32 tmp;
390
391 *ber = 0;
392
393 ret = sp8870_readreg(state, 0xC08);
394 if (ret < 0)
395 return -EIO;
396
397 tmp = ret & 0x3F;
398
399 ret = sp8870_readreg(state, 0xC07);
400 if (ret < 0)
401 return -EIO;
402
403 tmp = ret << 6;
404
405 if (tmp >= 0x3FFF0)
406 tmp = ~0;
407
408 *ber = tmp;
409
410 return 0;
411}
412
413static int sp8870_read_signal_strength(struct dvb_frontend* fe, u16 * signal)
414{
415 struct sp8870_state* state = (struct sp8870_state*) fe->demodulator_priv;
416 int ret;
417 u16 tmp;
418
419 *signal = 0;
420
421 ret = sp8870_readreg (state, 0x306);
422 if (ret < 0)
423 return -EIO;
424
425 tmp = ret << 8;
426
427 ret = sp8870_readreg (state, 0x303);
428 if (ret < 0)
429 return -EIO;
430
431 tmp |= ret;
432
433 if (tmp)
434 *signal = 0xFFFF - tmp;
435
436 return 0;
437}
438
439static int sp8870_read_uncorrected_blocks (struct dvb_frontend* fe, u32* ublocks)
440{
441 struct sp8870_state* state = (struct sp8870_state*) fe->demodulator_priv;
442 int ret;
443
444 *ublocks = 0;
445
446 ret = sp8870_readreg(state, 0xC0C);
447 if (ret < 0)
448 return -EIO;
449
450 if (ret == 0xFFFF)
451 ret = ~0;
452
453 *ublocks = ret;
454
455 return 0;
456}
457
458// number of trials to recover from lockup
459#define MAXTRIALS 5
460// maximum checks for data valid signal
461#define MAXCHECKS 100
462
463// only for debugging: counter for detected lockups
464static int lockups = 0;
465// only for debugging: counter for channel switches
466static int switches = 0;
467
468static int sp8870_set_frontend (struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
469{
470 struct sp8870_state* state = (struct sp8870_state*) fe->demodulator_priv;
471
472 /*
473 The firmware of the sp8870 sometimes locks up after setting frontend parameters.
474 We try to detect this by checking the data valid signal.
475 If it is not set after MAXCHECKS we try to recover the lockup by setting
476 the frontend parameters again.
477 */
478
479 int err = 0;
480 int valid = 0;
481 int trials = 0;
482 int check_count = 0;
483
484 dprintk("%s: frequency = %i\n", __FUNCTION__, p->frequency);
485
486 for (trials = 1; trials <= MAXTRIALS; trials++) {
487
488 if ((err = sp8870_set_frontend_parameters(fe, p)))
489 return err;
490
491 for (check_count = 0; check_count < MAXCHECKS; check_count++) {
492// valid = ((sp8870_readreg(i2c, 0x0200) & 4) == 0);
493 valid = sp8870_read_data_valid_signal(state);
494 if (valid) {
495 dprintk("%s: delay = %i usec\n",
496 __FUNCTION__, check_count * 10);
497 break;
498 }
499 udelay(10);
500 }
501 if (valid)
502 break;
503 }
504
505 if (!valid) {
506 printk("%s: firmware crash!!!!!!\n", __FUNCTION__);
507 return -EIO;
508 }
509
510 if (debug) {
511 if (valid) {
512 if (trials > 1) {
513 printk("%s: firmware lockup!!!\n", __FUNCTION__);
514 printk("%s: recovered after %i trial(s))\n", __FUNCTION__, trials - 1);
515 lockups++;
516 }
517 }
518 switches++;
519 printk("%s: switches = %i lockups = %i\n", __FUNCTION__, switches, lockups);
520 }
521
522 return 0;
523}
524
525static int sp8870_sleep(struct dvb_frontend* fe)
526{
527 struct sp8870_state* state = (struct sp8870_state*) fe->demodulator_priv;
528
529 // tristate TS output and disable interface pins
530 return sp8870_writereg(state, 0xC18, 0x000);
531}
532
533static int sp8870_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
534{
535 fesettings->min_delay_ms = 350;
536 fesettings->step_size = 0;
537 fesettings->max_drift = 0;
538 return 0;
539}
540
541static void sp8870_release(struct dvb_frontend* fe)
542{
543 struct sp8870_state* state = (struct sp8870_state*) fe->demodulator_priv;
544 kfree(state);
545}
546
547static struct dvb_frontend_ops sp8870_ops;
548
549struct dvb_frontend* sp8870_attach(const struct sp8870_config* config,
550 struct i2c_adapter* i2c)
551{
552 struct sp8870_state* state = NULL;
553
554 /* allocate memory for the internal state */
555 state = (struct sp8870_state*) kmalloc(sizeof(struct sp8870_state), GFP_KERNEL);
556 if (state == NULL) goto error;
557
558 /* setup the state */
559 state->config = config;
560 state->i2c = i2c;
561 memcpy(&state->ops, &sp8870_ops, sizeof(struct dvb_frontend_ops));
562 state->initialised = 0;
563
564 /* check if the demod is there */
565 if (sp8870_readreg(state, 0x0200) < 0) goto error;
566
567 /* create dvb_frontend */
568 state->frontend.ops = &state->ops;
569 state->frontend.demodulator_priv = state;
570 return &state->frontend;
571
572error:
573 kfree(state);
574 return NULL;
575}
576
577static struct dvb_frontend_ops sp8870_ops = {
578
579 .info = {
580 .name = "Spase SP8870 DVB-T",
581 .type = FE_OFDM,
582 .frequency_min = 470000000,
583 .frequency_max = 860000000,
584 .frequency_stepsize = 166666,
585 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
586 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 |
587 FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
588 FE_CAN_QPSK | FE_CAN_QAM_16 |
589 FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
590 FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER
591 },
592
593 .release = sp8870_release,
594
595 .init = sp8870_init,
596 .sleep = sp8870_sleep,
597
598 .set_frontend = sp8870_set_frontend,
599 .get_tune_settings = sp8870_get_tune_settings,
600
601 .read_status = sp8870_read_status,
602 .read_ber = sp8870_read_ber,
603 .read_signal_strength = sp8870_read_signal_strength,
604 .read_ucblocks = sp8870_read_uncorrected_blocks,
605};
606
607module_param(debug, int, 0644);
608MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
609
610MODULE_DESCRIPTION("Spase SP8870 DVB-T Demodulator driver");
611MODULE_AUTHOR("Juergen Peitz");
612MODULE_LICENSE("GPL");
613
614EXPORT_SYMBOL(sp8870_attach);
diff --git a/drivers/media/dvb/frontends/sp8870.h b/drivers/media/dvb/frontends/sp8870.h
new file mode 100644
index 000000000000..f3b555dbc960
--- /dev/null
+++ b/drivers/media/dvb/frontends/sp8870.h
@@ -0,0 +1,45 @@
1/*
2 Driver for Spase SP8870 demodulator
3
4 Copyright (C) 1999 Juergen Peitz
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21*/
22
23#ifndef SP8870_H
24#define SP8870_H
25
26#include <linux/dvb/frontend.h>
27#include <linux/firmware.h>
28
29struct sp8870_config
30{
31 /* the demodulator's i2c address */
32 u8 demod_address;
33
34 /* PLL maintenance */
35 int (*pll_init)(struct dvb_frontend* fe);
36 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
37
38 /* request firmware for device */
39 int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
40};
41
42extern struct dvb_frontend* sp8870_attach(const struct sp8870_config* config,
43 struct i2c_adapter* i2c);
44
45#endif // SP8870_H
diff --git a/drivers/media/dvb/frontends/sp887x.c b/drivers/media/dvb/frontends/sp887x.c
new file mode 100644
index 000000000000..7eae833ece49
--- /dev/null
+++ b/drivers/media/dvb/frontends/sp887x.c
@@ -0,0 +1,606 @@
1/*
2 Driver for the Spase sp887x demodulator
3*/
4
5/*
6 * This driver needs external firmware. Please use the command
7 * "<kerneldir>/Documentation/dvb/get_dvb_firmware sp887x" to
8 * download/extract it, and then copy it to /usr/lib/hotplug/firmware.
9 */
10#define SP887X_DEFAULT_FIRMWARE "dvb-fe-sp887x.fw"
11
12#include <linux/init.h>
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/device.h>
16#include <linux/firmware.h>
17
18#include "dvb_frontend.h"
19#include "sp887x.h"
20
21
22struct sp887x_state {
23 struct i2c_adapter* i2c;
24 struct dvb_frontend_ops ops;
25 const struct sp887x_config* config;
26 struct dvb_frontend frontend;
27
28 /* demodulator private data */
29 u8 initialised:1;
30};
31
32static int debug;
33#define dprintk(args...) \
34 do { \
35 if (debug) printk(KERN_DEBUG "sp887x: " args); \
36 } while (0)
37
38static int i2c_writebytes (struct sp887x_state* state, u8 *buf, u8 len)
39{
40 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = len };
41 int err;
42
43 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
44 printk ("%s: i2c write error (addr %02x, err == %i)\n",
45 __FUNCTION__, state->config->demod_address, err);
46 return -EREMOTEIO;
47 }
48
49 return 0;
50}
51
52static int sp887x_writereg (struct sp887x_state* state, u16 reg, u16 data)
53{
54 u8 b0 [] = { reg >> 8 , reg & 0xff, data >> 8, data & 0xff };
55 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 4 };
56 int ret;
57
58 if ((ret = i2c_transfer(state->i2c, &msg, 1)) != 1) {
59 /**
60 * in case of soft reset we ignore ACK errors...
61 */
62 if (!(reg == 0xf1a && data == 0x000 &&
63 (ret == -EREMOTEIO || ret == -EFAULT)))
64 {
65 printk("%s: writereg error "
66 "(reg %03x, data %03x, ret == %i)\n",
67 __FUNCTION__, reg & 0xffff, data & 0xffff, ret);
68 return ret;
69 }
70 }
71
72 return 0;
73}
74
75static int sp887x_readreg (struct sp887x_state* state, u16 reg)
76{
77 u8 b0 [] = { reg >> 8 , reg & 0xff };
78 u8 b1 [2];
79 int ret;
80 struct i2c_msg msg[] = {{ .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 2 },
81 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 2 }};
82
83 if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) {
84 printk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret);
85 return -1;
86 }
87
88 return (((b1[0] << 8) | b1[1]) & 0xfff);
89}
90
91static void sp887x_microcontroller_stop (struct sp887x_state* state)
92{
93 dprintk("%s\n", __FUNCTION__);
94 sp887x_writereg(state, 0xf08, 0x000);
95 sp887x_writereg(state, 0xf09, 0x000);
96
97 /* microcontroller STOP */
98 sp887x_writereg(state, 0xf00, 0x000);
99}
100
101static void sp887x_microcontroller_start (struct sp887x_state* state)
102{
103 dprintk("%s\n", __FUNCTION__);
104 sp887x_writereg(state, 0xf08, 0x000);
105 sp887x_writereg(state, 0xf09, 0x000);
106
107 /* microcontroller START */
108 sp887x_writereg(state, 0xf00, 0x001);
109}
110
111static void sp887x_setup_agc (struct sp887x_state* state)
112{
113 /* setup AGC parameters */
114 dprintk("%s\n", __FUNCTION__);
115 sp887x_writereg(state, 0x33c, 0x054);
116 sp887x_writereg(state, 0x33b, 0x04c);
117 sp887x_writereg(state, 0x328, 0x000);
118 sp887x_writereg(state, 0x327, 0x005);
119 sp887x_writereg(state, 0x326, 0x001);
120 sp887x_writereg(state, 0x325, 0x001);
121 sp887x_writereg(state, 0x324, 0x001);
122 sp887x_writereg(state, 0x318, 0x050);
123 sp887x_writereg(state, 0x317, 0x3fe);
124 sp887x_writereg(state, 0x316, 0x001);
125 sp887x_writereg(state, 0x313, 0x005);
126 sp887x_writereg(state, 0x312, 0x002);
127 sp887x_writereg(state, 0x306, 0x000);
128 sp887x_writereg(state, 0x303, 0x000);
129}
130
131#define BLOCKSIZE 30
132#define FW_SIZE 0x4000
133/**
134 * load firmware and setup MPEG interface...
135 */
136static int sp887x_initial_setup (struct dvb_frontend* fe, const struct firmware *fw)
137{
138 struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv;
139 u8 buf [BLOCKSIZE+2];
140 int i;
141 int fw_size = fw->size;
142 unsigned char *mem = fw->data;
143
144 dprintk("%s\n", __FUNCTION__);
145
146 /* ignore the first 10 bytes, then we expect 0x4000 bytes of firmware */
147 if (fw_size < FW_SIZE+10)
148 return -ENODEV;
149
150 mem = fw->data + 10;
151
152 /* soft reset */
153 sp887x_writereg(state, 0xf1a, 0x000);
154
155 sp887x_microcontroller_stop (state);
156
157 printk ("%s: firmware upload... ", __FUNCTION__);
158
159 /* setup write pointer to -1 (end of memory) */
160 /* bit 0x8000 in address is set to enable 13bit mode */
161 sp887x_writereg(state, 0x8f08, 0x1fff);
162
163 /* dummy write (wrap around to start of memory) */
164 sp887x_writereg(state, 0x8f0a, 0x0000);
165
166 for (i = 0; i < FW_SIZE; i += BLOCKSIZE) {
167 int c = BLOCKSIZE;
168 int err;
169
170 if (i+c > FW_SIZE)
171 c = FW_SIZE - i;
172
173 /* bit 0x8000 in address is set to enable 13bit mode */
174 /* bit 0x4000 enables multibyte read/write transfers */
175 /* write register is 0xf0a */
176 buf[0] = 0xcf;
177 buf[1] = 0x0a;
178
179 memcpy(&buf[2], mem + i, c);
180
181 if ((err = i2c_writebytes (state, buf, c+2)) < 0) {
182 printk ("failed.\n");
183 printk ("%s: i2c error (err == %i)\n", __FUNCTION__, err);
184 return err;
185 }
186 }
187
188 /* don't write RS bytes between packets */
189 sp887x_writereg(state, 0xc13, 0x001);
190
191 /* suppress clock if (!data_valid) */
192 sp887x_writereg(state, 0xc14, 0x000);
193
194 /* setup MPEG interface... */
195 sp887x_writereg(state, 0xc1a, 0x872);
196 sp887x_writereg(state, 0xc1b, 0x001);
197 sp887x_writereg(state, 0xc1c, 0x000); /* parallel mode (serial mode == 1) */
198 sp887x_writereg(state, 0xc1a, 0x871);
199
200 /* ADC mode, 2 for MT8872, 3 for SP8870/SP8871 */
201 sp887x_writereg(state, 0x301, 0x002);
202
203 sp887x_setup_agc(state);
204
205 /* bit 0x010: enable data valid signal */
206 sp887x_writereg(state, 0xd00, 0x010);
207 sp887x_writereg(state, 0x0d1, 0x000);
208
209 /* setup the PLL */
210 if (state->config->pll_init) {
211 sp887x_writereg(state, 0x206, 0x001);
212 state->config->pll_init(fe);
213 sp887x_writereg(state, 0x206, 0x000);
214 }
215
216 printk ("done.\n");
217 return 0;
218};
219
220static int configure_reg0xc05 (struct dvb_frontend_parameters *p, u16 *reg0xc05)
221{
222 int known_parameters = 1;
223
224 *reg0xc05 = 0x000;
225
226 switch (p->u.ofdm.constellation) {
227 case QPSK:
228 break;
229 case QAM_16:
230 *reg0xc05 |= (1 << 10);
231 break;
232 case QAM_64:
233 *reg0xc05 |= (2 << 10);
234 break;
235 case QAM_AUTO:
236 known_parameters = 0;
237 break;
238 default:
239 return -EINVAL;
240 };
241
242 switch (p->u.ofdm.hierarchy_information) {
243 case HIERARCHY_NONE:
244 break;
245 case HIERARCHY_1:
246 *reg0xc05 |= (1 << 7);
247 break;
248 case HIERARCHY_2:
249 *reg0xc05 |= (2 << 7);
250 break;
251 case HIERARCHY_4:
252 *reg0xc05 |= (3 << 7);
253 break;
254 case HIERARCHY_AUTO:
255 known_parameters = 0;
256 break;
257 default:
258 return -EINVAL;
259 };
260
261 switch (p->u.ofdm.code_rate_HP) {
262 case FEC_1_2:
263 break;
264 case FEC_2_3:
265 *reg0xc05 |= (1 << 3);
266 break;
267 case FEC_3_4:
268 *reg0xc05 |= (2 << 3);
269 break;
270 case FEC_5_6:
271 *reg0xc05 |= (3 << 3);
272 break;
273 case FEC_7_8:
274 *reg0xc05 |= (4 << 3);
275 break;
276 case FEC_AUTO:
277 known_parameters = 0;
278 break;
279 default:
280 return -EINVAL;
281 };
282
283 if (known_parameters)
284 *reg0xc05 |= (2 << 1); /* use specified parameters */
285 else
286 *reg0xc05 |= (1 << 1); /* enable autoprobing */
287
288 return 0;
289}
290
291/**
292 * estimates division of two 24bit numbers,
293 * derived from the ves1820/stv0299 driver code
294 */
295static void divide (int n, int d, int *quotient_i, int *quotient_f)
296{
297 unsigned int q, r;
298
299 r = (n % d) << 8;
300 q = (r / d);
301
302 if (quotient_i)
303 *quotient_i = q;
304
305 if (quotient_f) {
306 r = (r % d) << 8;
307 q = (q << 8) | (r / d);
308 r = (r % d) << 8;
309 *quotient_f = (q << 8) | (r / d);
310 }
311}
312
313static void sp887x_correct_offsets (struct sp887x_state* state,
314 struct dvb_frontend_parameters *p,
315 int actual_freq)
316{
317 static const u32 srate_correction [] = { 1879617, 4544878, 8098561 };
318 int bw_index = p->u.ofdm.bandwidth - BANDWIDTH_8_MHZ;
319 int freq_offset = actual_freq - p->frequency;
320 int sysclock = 61003; //[kHz]
321 int ifreq = 36000000;
322 int freq;
323 int frequency_shift;
324
325 if (p->inversion == INVERSION_ON)
326 freq = ifreq - freq_offset;
327 else
328 freq = ifreq + freq_offset;
329
330 divide(freq / 333, sysclock, NULL, &frequency_shift);
331
332 if (p->inversion == INVERSION_ON)
333 frequency_shift = -frequency_shift;
334
335 /* sample rate correction */
336 sp887x_writereg(state, 0x319, srate_correction[bw_index] >> 12);
337 sp887x_writereg(state, 0x31a, srate_correction[bw_index] & 0xfff);
338
339 /* carrier offset correction */
340 sp887x_writereg(state, 0x309, frequency_shift >> 12);
341 sp887x_writereg(state, 0x30a, frequency_shift & 0xfff);
342}
343
344static int sp887x_setup_frontend_parameters (struct dvb_frontend* fe,
345 struct dvb_frontend_parameters *p)
346{
347 struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv;
348 int actual_freq, err;
349 u16 val, reg0xc05;
350
351 if (p->u.ofdm.bandwidth != BANDWIDTH_8_MHZ &&
352 p->u.ofdm.bandwidth != BANDWIDTH_7_MHZ &&
353 p->u.ofdm.bandwidth != BANDWIDTH_6_MHZ)
354 return -EINVAL;
355
356 if ((err = configure_reg0xc05(p, &reg0xc05)))
357 return err;
358
359 sp887x_microcontroller_stop(state);
360
361 /* setup the PLL */
362 sp887x_writereg(state, 0x206, 0x001);
363 actual_freq = state->config->pll_set(fe, p);
364 sp887x_writereg(state, 0x206, 0x000);
365
366 /* read status reg in order to clear <pending irqs */
367 sp887x_readreg(state, 0x200);
368
369 sp887x_correct_offsets(state, p, actual_freq);
370
371 /* filter for 6/7/8 Mhz channel */
372 if (p->u.ofdm.bandwidth == BANDWIDTH_6_MHZ)
373 val = 2;
374 else if (p->u.ofdm.bandwidth == BANDWIDTH_7_MHZ)
375 val = 1;
376 else
377 val = 0;
378
379 sp887x_writereg(state, 0x311, val);
380
381 /* scan order: 2k first = 0, 8k first = 1 */
382 if (p->u.ofdm.transmission_mode == TRANSMISSION_MODE_2K)
383 sp887x_writereg(state, 0x338, 0x000);
384 else
385 sp887x_writereg(state, 0x338, 0x001);
386
387 sp887x_writereg(state, 0xc05, reg0xc05);
388
389 if (p->u.ofdm.bandwidth == BANDWIDTH_6_MHZ)
390 val = 2 << 3;
391 else if (p->u.ofdm.bandwidth == BANDWIDTH_7_MHZ)
392 val = 3 << 3;
393 else
394 val = 0 << 3;
395
396 /* enable OFDM and SAW bits as lock indicators in sync register 0xf17,
397 * optimize algorithm for given bandwidth...
398 */
399 sp887x_writereg(state, 0xf14, 0x160 | val);
400 sp887x_writereg(state, 0xf15, 0x000);
401
402 sp887x_microcontroller_start(state);
403 return 0;
404}
405
406static int sp887x_read_status(struct dvb_frontend* fe, fe_status_t* status)
407{
408 struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv;
409 u16 snr12 = sp887x_readreg(state, 0xf16);
410 u16 sync0x200 = sp887x_readreg(state, 0x200);
411 u16 sync0xf17 = sp887x_readreg(state, 0xf17);
412
413 *status = 0;
414
415 if (snr12 > 0x00f)
416 *status |= FE_HAS_SIGNAL;
417
418 //if (sync0x200 & 0x004)
419 // *status |= FE_HAS_SYNC | FE_HAS_CARRIER;
420
421 //if (sync0x200 & 0x008)
422 // *status |= FE_HAS_VITERBI;
423
424 if ((sync0xf17 & 0x00f) == 0x002) {
425 *status |= FE_HAS_LOCK;
426 *status |= FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_CARRIER;
427 }
428
429 if (sync0x200 & 0x001) { /* tuner adjustment requested...*/
430 int steps = (sync0x200 >> 4) & 0x00f;
431 if (steps & 0x008)
432 steps = -steps;
433 dprintk("sp887x: implement tuner adjustment (%+i steps)!!\n",
434 steps);
435 }
436
437 return 0;
438}
439
440static int sp887x_read_ber(struct dvb_frontend* fe, u32* ber)
441{
442 struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv;
443
444 *ber = (sp887x_readreg(state, 0xc08) & 0x3f) |
445 (sp887x_readreg(state, 0xc07) << 6);
446 sp887x_writereg(state, 0xc08, 0x000);
447 sp887x_writereg(state, 0xc07, 0x000);
448 if (*ber >= 0x3fff0)
449 *ber = ~0;
450
451 return 0;
452}
453
454static int sp887x_read_signal_strength(struct dvb_frontend* fe, u16* strength)
455{
456 struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv;
457
458 u16 snr12 = sp887x_readreg(state, 0xf16);
459 u32 signal = 3 * (snr12 << 4);
460 *strength = (signal < 0xffff) ? signal : 0xffff;
461
462 return 0;
463}
464
465static int sp887x_read_snr(struct dvb_frontend* fe, u16* snr)
466{
467 struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv;
468
469 u16 snr12 = sp887x_readreg(state, 0xf16);
470 *snr = (snr12 << 4) | (snr12 >> 8);
471
472 return 0;
473}
474
475static int sp887x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
476{
477 struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv;
478
479 *ucblocks = sp887x_readreg(state, 0xc0c);
480 if (*ucblocks == 0xfff)
481 *ucblocks = ~0;
482
483 return 0;
484}
485
486static int sp887x_sleep(struct dvb_frontend* fe)
487{
488 struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv;
489
490 /* tristate TS output and disable interface pins */
491 sp887x_writereg(state, 0xc18, 0x000);
492
493 return 0;
494}
495
496static int sp887x_init(struct dvb_frontend* fe)
497{
498 struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv;
499 const struct firmware *fw = NULL;
500 int ret;
501
502 if (!state->initialised) {
503 /* request the firmware, this will block until someone uploads it */
504 printk("sp887x: waiting for firmware upload (%s)...\n", SP887X_DEFAULT_FIRMWARE);
505 ret = state->config->request_firmware(fe, &fw, SP887X_DEFAULT_FIRMWARE);
506 if (ret) {
507 printk("sp887x: no firmware upload (timeout or file not found?)\n");
508 return ret;
509 }
510
511 ret = sp887x_initial_setup(fe, fw);
512 if (ret) {
513 printk("sp887x: writing firmware to device failed\n");
514 release_firmware(fw);
515 return ret;
516 }
517 printk("sp887x: firmware upload complete\n");
518 state->initialised = 1;
519 }
520
521 /* enable TS output and interface pins */
522 sp887x_writereg(state, 0xc18, 0x00d);
523
524 return 0;
525}
526
527static int sp887x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
528{
529 fesettings->min_delay_ms = 350;
530 fesettings->step_size = 166666*2;
531 fesettings->max_drift = (166666*2)+1;
532 return 0;
533}
534
535static void sp887x_release(struct dvb_frontend* fe)
536{
537 struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv;
538 kfree(state);
539}
540
541static struct dvb_frontend_ops sp887x_ops;
542
543struct dvb_frontend* sp887x_attach(const struct sp887x_config* config,
544 struct i2c_adapter* i2c)
545{
546 struct sp887x_state* state = NULL;
547
548 /* allocate memory for the internal state */
549 state = (struct sp887x_state*) kmalloc(sizeof(struct sp887x_state), GFP_KERNEL);
550 if (state == NULL) goto error;
551
552 /* setup the state */
553 state->config = config;
554 state->i2c = i2c;
555 memcpy(&state->ops, &sp887x_ops, sizeof(struct dvb_frontend_ops));
556 state->initialised = 0;
557
558 /* check if the demod is there */
559 if (sp887x_readreg(state, 0x0200) < 0) goto error;
560
561 /* create dvb_frontend */
562 state->frontend.ops = &state->ops;
563 state->frontend.demodulator_priv = state;
564 return &state->frontend;
565
566error:
567 kfree(state);
568 return NULL;
569}
570
571static struct dvb_frontend_ops sp887x_ops = {
572
573 .info = {
574 .name = "Spase SP887x DVB-T",
575 .type = FE_OFDM,
576 .frequency_min = 50500000,
577 .frequency_max = 858000000,
578 .frequency_stepsize = 166666,
579 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
580 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
581 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
582 FE_CAN_RECOVER
583 },
584
585 .release = sp887x_release,
586
587 .init = sp887x_init,
588 .sleep = sp887x_sleep,
589
590 .set_frontend = sp887x_setup_frontend_parameters,
591 .get_tune_settings = sp887x_get_tune_settings,
592
593 .read_status = sp887x_read_status,
594 .read_ber = sp887x_read_ber,
595 .read_signal_strength = sp887x_read_signal_strength,
596 .read_snr = sp887x_read_snr,
597 .read_ucblocks = sp887x_read_ucblocks,
598};
599
600module_param(debug, int, 0644);
601MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
602
603MODULE_DESCRIPTION("Spase sp887x DVB-T demodulator driver");
604MODULE_LICENSE("GPL");
605
606EXPORT_SYMBOL(sp887x_attach);
diff --git a/drivers/media/dvb/frontends/sp887x.h b/drivers/media/dvb/frontends/sp887x.h
new file mode 100644
index 000000000000..6a05d8f8e8cc
--- /dev/null
+++ b/drivers/media/dvb/frontends/sp887x.h
@@ -0,0 +1,29 @@
1/*
2 Driver for the Spase sp887x demodulator
3*/
4
5#ifndef SP887X_H
6#define SP887X_H
7
8#include <linux/dvb/frontend.h>
9#include <linux/firmware.h>
10
11struct sp887x_config
12{
13 /* the demodulator's i2c address */
14 u8 demod_address;
15
16 /* PLL maintenance */
17 int (*pll_init)(struct dvb_frontend* fe);
18
19 /* this should return the actual frequency tuned to */
20 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
21
22 /* request firmware for device */
23 int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
24};
25
26extern struct dvb_frontend* sp887x_attach(const struct sp887x_config* config,
27 struct i2c_adapter* i2c);
28
29#endif // SP887X_H
diff --git a/drivers/media/dvb/frontends/stv0297.c b/drivers/media/dvb/frontends/stv0297.c
new file mode 100644
index 000000000000..502c6403dfc6
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0297.c
@@ -0,0 +1,798 @@
1/*
2 Driver for STV0297 demodulator
3
4 Copyright (C) 2004 Andrew de Quincey <adq_dvb@lidskialf.net>
5 Copyright (C) 2003-2004 Dennis Noermann <dennis.noermann@noernet.de>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20*/
21
22#include <linux/init.h>
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/string.h>
26#include <linux/delay.h>
27
28#include "dvb_frontend.h"
29#include "stv0297.h"
30
31struct stv0297_state {
32 struct i2c_adapter *i2c;
33 struct dvb_frontend_ops ops;
34 const struct stv0297_config *config;
35 struct dvb_frontend frontend;
36
37 unsigned long base_freq;
38 u8 pwm;
39};
40
41#if 1
42#define dprintk(x...) printk(x)
43#else
44#define dprintk(x...)
45#endif
46
47#define STV0297_CLOCK_KHZ 28900
48
49static u8 init_tab[] = {
50 0x00, 0x09,
51 0x01, 0x69,
52 0x03, 0x00,
53 0x04, 0x00,
54 0x07, 0x00,
55 0x08, 0x00,
56 0x20, 0x00,
57 0x21, 0x40,
58 0x22, 0x00,
59 0x23, 0x00,
60 0x24, 0x40,
61 0x25, 0x88,
62 0x30, 0xff,
63 0x31, 0x00,
64 0x32, 0xff,
65 0x33, 0x00,
66 0x34, 0x50,
67 0x35, 0x7f,
68 0x36, 0x00,
69 0x37, 0x20,
70 0x38, 0x00,
71 0x40, 0x1c,
72 0x41, 0xff,
73 0x42, 0x29,
74 0x43, 0x00,
75 0x44, 0xff,
76 0x45, 0x00,
77 0x46, 0x00,
78 0x49, 0x04,
79 0x4a, 0xff,
80 0x4b, 0x7f,
81 0x52, 0x30,
82 0x55, 0xae,
83 0x56, 0x47,
84 0x57, 0xe1,
85 0x58, 0x3a,
86 0x5a, 0x1e,
87 0x5b, 0x34,
88 0x60, 0x00,
89 0x63, 0x00,
90 0x64, 0x00,
91 0x65, 0x00,
92 0x66, 0x00,
93 0x67, 0x00,
94 0x68, 0x00,
95 0x69, 0x00,
96 0x6a, 0x02,
97 0x6b, 0x00,
98 0x70, 0xff,
99 0x71, 0x00,
100 0x72, 0x00,
101 0x73, 0x00,
102 0x74, 0x0c,
103 0x80, 0x00,
104 0x81, 0x00,
105 0x82, 0x00,
106 0x83, 0x00,
107 0x84, 0x04,
108 0x85, 0x80,
109 0x86, 0x24,
110 0x87, 0x78,
111 0x88, 0x00,
112 0x89, 0x00,
113 0x90, 0x01,
114 0x91, 0x01,
115 0xa0, 0x00,
116 0xa1, 0x00,
117 0xa2, 0x00,
118 0xb0, 0x91,
119 0xb1, 0x0b,
120 0xc0, 0x53,
121 0xc1, 0x70,
122 0xc2, 0x12,
123 0xd0, 0x00,
124 0xd1, 0x00,
125 0xd2, 0x00,
126 0xd3, 0x00,
127 0xd4, 0x00,
128 0xd5, 0x00,
129 0xde, 0x00,
130 0xdf, 0x00,
131 0x61, 0x49,
132 0x62, 0x0b,
133 0x53, 0x08,
134 0x59, 0x08,
135};
136
137
138static int stv0297_writereg(struct stv0297_state *state, u8 reg, u8 data)
139{
140 int ret;
141 u8 buf[] = { reg, data };
142 struct i2c_msg msg = {.addr = state->config->demod_address,.flags = 0,.buf = buf,.len = 2 };
143
144 ret = i2c_transfer(state->i2c, &msg, 1);
145
146 if (ret != 1)
147 dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, "
148 "ret == %i)\n", __FUNCTION__, reg, data, ret);
149
150 return (ret != 1) ? -1 : 0;
151}
152
153static int stv0297_readreg(struct stv0297_state *state, u8 reg)
154{
155 int ret;
156 u8 b0[] = { reg };
157 u8 b1[] = { 0 };
158 struct i2c_msg msg[] = { {.addr = state->config->demod_address,.flags = 0,.buf = b0,.len =
159 1},
160 {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b1,.len = 1}
161 };
162
163 // this device needs a STOP between the register and data
164 if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) {
165 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret);
166 return -1;
167 }
168 if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) {
169 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret);
170 return -1;
171 }
172
173 return b1[0];
174}
175
176static int stv0297_writereg_mask(struct stv0297_state *state, u8 reg, u8 mask, u8 data)
177{
178 int val;
179
180 val = stv0297_readreg(state, reg);
181 val &= ~mask;
182 val |= (data & mask);
183 stv0297_writereg(state, reg, val);
184
185 return 0;
186}
187
188static int stv0297_readregs(struct stv0297_state *state, u8 reg1, u8 * b, u8 len)
189{
190 int ret;
191 struct i2c_msg msg[] = { {.addr = state->config->demod_address,.flags = 0,.buf =
192 &reg1,.len = 1},
193 {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b,.len = len}
194 };
195
196 // this device needs a STOP between the register and data
197 if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) {
198 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret);
199 return -1;
200 }
201 if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) {
202 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret);
203 return -1;
204 }
205
206 return 0;
207}
208
209static u32 stv0297_get_symbolrate(struct stv0297_state *state)
210{
211 u64 tmp;
212
213 tmp = stv0297_readreg(state, 0x55);
214 tmp |= stv0297_readreg(state, 0x56) << 8;
215 tmp |= stv0297_readreg(state, 0x57) << 16;
216 tmp |= stv0297_readreg(state, 0x58) << 24;
217
218 tmp *= STV0297_CLOCK_KHZ;
219 tmp >>= 32;
220
221 return (u32) tmp;
222}
223
224static void stv0297_set_symbolrate(struct stv0297_state *state, u32 srate)
225{
226 long tmp;
227
228 tmp = 131072L * srate; /* 131072 = 2^17 */
229 tmp = tmp / (STV0297_CLOCK_KHZ / 4); /* 1/4 = 2^-2 */
230 tmp = tmp * 8192L; /* 8192 = 2^13 */
231
232 stv0297_writereg(state, 0x55, (unsigned char) (tmp & 0xFF));
233 stv0297_writereg(state, 0x56, (unsigned char) (tmp >> 8));
234 stv0297_writereg(state, 0x57, (unsigned char) (tmp >> 16));
235 stv0297_writereg(state, 0x58, (unsigned char) (tmp >> 24));
236}
237
238static void stv0297_set_sweeprate(struct stv0297_state *state, short fshift, long symrate)
239{
240 long tmp;
241
242 tmp = (long) fshift *262144L; /* 262144 = 2*18 */
243 tmp /= symrate;
244 tmp *= 1024; /* 1024 = 2*10 */
245
246 // adjust
247 if (tmp >= 0) {
248 tmp += 500000;
249 } else {
250 tmp -= 500000;
251 }
252 tmp /= 1000000;
253
254 stv0297_writereg(state, 0x60, tmp & 0xFF);
255 stv0297_writereg_mask(state, 0x69, 0xF0, (tmp >> 4) & 0xf0);
256}
257
258static void stv0297_set_carrieroffset(struct stv0297_state *state, long offset)
259{
260 long tmp;
261
262 /* symrate is hardcoded to 10000 */
263 tmp = offset * 26844L; /* (2**28)/10000 */
264 if (tmp < 0)
265 tmp += 0x10000000;
266 tmp &= 0x0FFFFFFF;
267
268 stv0297_writereg(state, 0x66, (unsigned char) (tmp & 0xFF));
269 stv0297_writereg(state, 0x67, (unsigned char) (tmp >> 8));
270 stv0297_writereg(state, 0x68, (unsigned char) (tmp >> 16));
271 stv0297_writereg_mask(state, 0x69, 0x0F, (tmp >> 24) & 0x0f);
272}
273
274/*
275static long stv0297_get_carrieroffset(struct stv0297_state *state)
276{
277 s64 tmp;
278
279 stv0297_writereg(state, 0x6B, 0x00);
280
281 tmp = stv0297_readreg(state, 0x66);
282 tmp |= (stv0297_readreg(state, 0x67) << 8);
283 tmp |= (stv0297_readreg(state, 0x68) << 16);
284 tmp |= (stv0297_readreg(state, 0x69) & 0x0F) << 24;
285
286 tmp *= stv0297_get_symbolrate(state);
287 tmp >>= 28;
288
289 return (s32) tmp;
290}
291*/
292
293static void stv0297_set_initialdemodfreq(struct stv0297_state *state, long freq)
294{
295 s32 tmp;
296
297 if (freq > 10000)
298 freq -= STV0297_CLOCK_KHZ;
299
300 tmp = (STV0297_CLOCK_KHZ * 1000) / (1 << 16);
301 tmp = (freq * 1000) / tmp;
302 if (tmp > 0xffff)
303 tmp = 0xffff;
304
305 stv0297_writereg_mask(state, 0x25, 0x80, 0x80);
306 stv0297_writereg(state, 0x21, tmp >> 8);
307 stv0297_writereg(state, 0x20, tmp);
308}
309
310static int stv0297_set_qam(struct stv0297_state *state, fe_modulation_t modulation)
311{
312 int val = 0;
313
314 switch (modulation) {
315 case QAM_16:
316 val = 0;
317 break;
318
319 case QAM_32:
320 val = 1;
321 break;
322
323 case QAM_64:
324 val = 4;
325 break;
326
327 case QAM_128:
328 val = 2;
329 break;
330
331 case QAM_256:
332 val = 3;
333 break;
334
335 default:
336 return -EINVAL;
337 }
338
339 stv0297_writereg_mask(state, 0x00, 0x70, val << 4);
340
341 return 0;
342}
343
344static int stv0297_set_inversion(struct stv0297_state *state, fe_spectral_inversion_t inversion)
345{
346 int val = 0;
347
348 switch (inversion) {
349 case INVERSION_OFF:
350 val = 0;
351 break;
352
353 case INVERSION_ON:
354 val = 1;
355 break;
356
357 default:
358 return -EINVAL;
359 }
360
361 stv0297_writereg_mask(state, 0x83, 0x08, val << 3);
362
363 return 0;
364}
365
366int stv0297_enable_plli2c(struct dvb_frontend *fe)
367{
368 struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;
369
370 stv0297_writereg(state, 0x87, 0x78);
371 stv0297_writereg(state, 0x86, 0xc8);
372
373 return 0;
374}
375
376static int stv0297_init(struct dvb_frontend *fe)
377{
378 struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;
379 int i;
380
381 /* soft reset */
382 stv0297_writereg_mask(state, 0x80, 1, 1);
383 stv0297_writereg_mask(state, 0x80, 1, 0);
384
385 /* reset deinterleaver */
386 stv0297_writereg_mask(state, 0x81, 1, 1);
387 stv0297_writereg_mask(state, 0x81, 1, 0);
388
389 /* load init table */
390 for (i = 0; i < sizeof(init_tab); i += 2) {
391 stv0297_writereg(state, init_tab[i], init_tab[i + 1]);
392 }
393
394 /* set a dummy symbol rate */
395 stv0297_set_symbolrate(state, 6900);
396
397 /* invert AGC1 polarity */
398 stv0297_writereg_mask(state, 0x88, 0x10, 0x10);
399
400 /* setup bit error counting */
401 stv0297_writereg_mask(state, 0xA0, 0x80, 0x00);
402 stv0297_writereg_mask(state, 0xA0, 0x10, 0x00);
403 stv0297_writereg_mask(state, 0xA0, 0x08, 0x00);
404 stv0297_writereg_mask(state, 0xA0, 0x07, 0x04);
405
406 /* min + max PWM */
407 stv0297_writereg(state, 0x4a, 0x00);
408 stv0297_writereg(state, 0x4b, state->pwm);
409 msleep(200);
410
411 if (state->config->pll_init)
412 state->config->pll_init(fe);
413
414 return 0;
415}
416
417static int stv0297_sleep(struct dvb_frontend *fe)
418{
419 struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;
420
421 stv0297_writereg_mask(state, 0x80, 1, 1);
422
423 return 0;
424}
425
426static int stv0297_read_status(struct dvb_frontend *fe, fe_status_t * status)
427{
428 struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;
429
430 u8 sync = stv0297_readreg(state, 0xDF);
431
432 *status = 0;
433 if (sync & 0x80)
434 *status |=
435 FE_HAS_SYNC | FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_LOCK;
436 return 0;
437}
438
439static int stv0297_read_ber(struct dvb_frontend *fe, u32 * ber)
440{
441 struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;
442 u8 BER[3];
443
444 stv0297_writereg(state, 0xA0, 0x80); // Start Counting bit errors for 4096 Bytes
445 mdelay(25); // Hopefully got 4096 Bytes
446 stv0297_readregs(state, 0xA0, BER, 3);
447 mdelay(25);
448 *ber = (BER[2] << 8 | BER[1]) / (8 * 4096);
449
450 return 0;
451}
452
453
454static int stv0297_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
455{
456 struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;
457 u8 STRENGTH[2];
458
459 stv0297_readregs(state, 0x41, STRENGTH, 2);
460 *strength = (STRENGTH[1] & 0x03) << 8 | STRENGTH[0];
461
462 return 0;
463}
464
465static int stv0297_read_snr(struct dvb_frontend *fe, u16 * snr)
466{
467 struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;
468 u8 SNR[2];
469
470 stv0297_readregs(state, 0x07, SNR, 2);
471 *snr = SNR[1] << 8 | SNR[0];
472
473 return 0;
474}
475
476static int stv0297_read_ucblocks(struct dvb_frontend *fe, u32 * ucblocks)
477{
478 struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;
479
480 *ucblocks = (stv0297_readreg(state, 0xD5) << 8)
481 | stv0297_readreg(state, 0xD4);
482
483 return 0;
484}
485
486static int stv0297_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
487{
488 struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;
489 int u_threshold;
490 int initial_u;
491 int blind_u;
492 int delay;
493 int sweeprate;
494 int carrieroffset;
495 unsigned long starttime;
496 unsigned long timeout;
497 fe_spectral_inversion_t inversion;
498
499 switch (p->u.qam.modulation) {
500 case QAM_16:
501 case QAM_32:
502 case QAM_64:
503 delay = 100;
504 sweeprate = 1500;
505 break;
506
507 case QAM_128:
508 delay = 150;
509 sweeprate = 1000;
510 break;
511
512 case QAM_256:
513 delay = 200;
514 sweeprate = 500;
515 break;
516
517 default:
518 return -EINVAL;
519 }
520
521 // determine inversion dependant parameters
522 inversion = p->inversion;
523 if (state->config->invert)
524 inversion = (inversion == INVERSION_ON) ? INVERSION_OFF : INVERSION_ON;
525 carrieroffset = -330;
526 switch (inversion) {
527 case INVERSION_OFF:
528 break;
529
530 case INVERSION_ON:
531 sweeprate = -sweeprate;
532 carrieroffset = -carrieroffset;
533 break;
534
535 default:
536 return -EINVAL;
537 }
538
539 stv0297_init(fe);
540 state->config->pll_set(fe, p);
541
542 /* clear software interrupts */
543 stv0297_writereg(state, 0x82, 0x0);
544
545 /* set initial demodulation frequency */
546 stv0297_set_initialdemodfreq(state, 7250);
547
548 /* setup AGC */
549 stv0297_writereg_mask(state, 0x43, 0x10, 0x00);
550 stv0297_writereg(state, 0x41, 0x00);
551 stv0297_writereg_mask(state, 0x42, 0x03, 0x01);
552 stv0297_writereg_mask(state, 0x36, 0x60, 0x00);
553 stv0297_writereg_mask(state, 0x36, 0x18, 0x00);
554 stv0297_writereg_mask(state, 0x71, 0x80, 0x80);
555 stv0297_writereg(state, 0x72, 0x00);
556 stv0297_writereg(state, 0x73, 0x00);
557 stv0297_writereg_mask(state, 0x74, 0x0F, 0x00);
558 stv0297_writereg_mask(state, 0x43, 0x08, 0x00);
559 stv0297_writereg_mask(state, 0x71, 0x80, 0x00);
560
561 /* setup STL */
562 stv0297_writereg_mask(state, 0x5a, 0x20, 0x20);
563 stv0297_writereg_mask(state, 0x5b, 0x02, 0x02);
564 stv0297_writereg_mask(state, 0x5b, 0x02, 0x00);
565 stv0297_writereg_mask(state, 0x5b, 0x01, 0x00);
566 stv0297_writereg_mask(state, 0x5a, 0x40, 0x40);
567
568 /* disable frequency sweep */
569 stv0297_writereg_mask(state, 0x6a, 0x01, 0x00);
570
571 /* reset deinterleaver */
572 stv0297_writereg_mask(state, 0x81, 0x01, 0x01);
573 stv0297_writereg_mask(state, 0x81, 0x01, 0x00);
574
575 /* ??? */
576 stv0297_writereg_mask(state, 0x83, 0x20, 0x20);
577 stv0297_writereg_mask(state, 0x83, 0x20, 0x00);
578
579 /* reset equaliser */
580 u_threshold = stv0297_readreg(state, 0x00) & 0xf;
581 initial_u = stv0297_readreg(state, 0x01) >> 4;
582 blind_u = stv0297_readreg(state, 0x01) & 0xf;
583 stv0297_writereg_mask(state, 0x84, 0x01, 0x01);
584 stv0297_writereg_mask(state, 0x84, 0x01, 0x00);
585 stv0297_writereg_mask(state, 0x00, 0x0f, u_threshold);
586 stv0297_writereg_mask(state, 0x01, 0xf0, initial_u << 4);
587 stv0297_writereg_mask(state, 0x01, 0x0f, blind_u);
588
589 /* data comes from internal A/D */
590 stv0297_writereg_mask(state, 0x87, 0x80, 0x00);
591
592 /* clear phase registers */
593 stv0297_writereg(state, 0x63, 0x00);
594 stv0297_writereg(state, 0x64, 0x00);
595 stv0297_writereg(state, 0x65, 0x00);
596 stv0297_writereg(state, 0x66, 0x00);
597 stv0297_writereg(state, 0x67, 0x00);
598 stv0297_writereg(state, 0x68, 0x00);
599 stv0297_writereg_mask(state, 0x69, 0x0f, 0x00);
600
601 /* set parameters */
602 stv0297_set_qam(state, p->u.qam.modulation);
603 stv0297_set_symbolrate(state, p->u.qam.symbol_rate / 1000);
604 stv0297_set_sweeprate(state, sweeprate, p->u.qam.symbol_rate / 1000);
605 stv0297_set_carrieroffset(state, carrieroffset);
606 stv0297_set_inversion(state, inversion);
607
608 /* kick off lock */
609 stv0297_writereg_mask(state, 0x88, 0x08, 0x08);
610 stv0297_writereg_mask(state, 0x5a, 0x20, 0x00);
611 stv0297_writereg_mask(state, 0x6a, 0x01, 0x01);
612 stv0297_writereg_mask(state, 0x43, 0x40, 0x40);
613 stv0297_writereg_mask(state, 0x5b, 0x30, 0x00);
614 stv0297_writereg_mask(state, 0x03, 0x0c, 0x0c);
615 stv0297_writereg_mask(state, 0x03, 0x03, 0x03);
616 stv0297_writereg_mask(state, 0x43, 0x10, 0x10);
617
618 /* wait for WGAGC lock */
619 starttime = jiffies;
620 timeout = jiffies + (200 * HZ) / 1000;
621 while (time_before(jiffies, timeout)) {
622 msleep(10);
623 if (stv0297_readreg(state, 0x43) & 0x08)
624 break;
625 }
626 if (time_after(jiffies, timeout)) {
627 goto timeout;
628 }
629 msleep(20);
630
631 /* wait for equaliser partial convergence */
632 timeout = jiffies + (50 * HZ) / 1000;
633 while (time_before(jiffies, timeout)) {
634 msleep(10);
635
636 if (stv0297_readreg(state, 0x82) & 0x04) {
637 break;
638 }
639 }
640 if (time_after(jiffies, timeout)) {
641 goto timeout;
642 }
643
644 /* wait for equaliser full convergence */
645 timeout = jiffies + (delay * HZ) / 1000;
646 while (time_before(jiffies, timeout)) {
647 msleep(10);
648
649 if (stv0297_readreg(state, 0x82) & 0x08) {
650 break;
651 }
652 }
653 if (time_after(jiffies, timeout)) {
654 goto timeout;
655 }
656
657 /* disable sweep */
658 stv0297_writereg_mask(state, 0x6a, 1, 0);
659 stv0297_writereg_mask(state, 0x88, 8, 0);
660
661 /* wait for main lock */
662 timeout = jiffies + (20 * HZ) / 1000;
663 while (time_before(jiffies, timeout)) {
664 msleep(10);
665
666 if (stv0297_readreg(state, 0xDF) & 0x80) {
667 break;
668 }
669 }
670 if (time_after(jiffies, timeout)) {
671 goto timeout;
672 }
673 msleep(100);
674
675 /* is it still locked after that delay? */
676 if (!(stv0297_readreg(state, 0xDF) & 0x80)) {
677 goto timeout;
678 }
679
680 /* success!! */
681 stv0297_writereg_mask(state, 0x5a, 0x40, 0x00);
682 state->base_freq = p->frequency;
683 return 0;
684
685timeout:
686 stv0297_writereg_mask(state, 0x6a, 0x01, 0x00);
687 return 0;
688}
689
690static int stv0297_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
691{
692 struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;
693 int reg_00, reg_83;
694
695 reg_00 = stv0297_readreg(state, 0x00);
696 reg_83 = stv0297_readreg(state, 0x83);
697
698 p->frequency = state->base_freq;
699 p->inversion = (reg_83 & 0x08) ? INVERSION_ON : INVERSION_OFF;
700 if (state->config->invert)
701 p->inversion = (p->inversion == INVERSION_ON) ? INVERSION_OFF : INVERSION_ON;
702 p->u.qam.symbol_rate = stv0297_get_symbolrate(state) * 1000;
703 p->u.qam.fec_inner = FEC_NONE;
704
705 switch ((reg_00 >> 4) & 0x7) {
706 case 0:
707 p->u.qam.modulation = QAM_16;
708 break;
709 case 1:
710 p->u.qam.modulation = QAM_32;
711 break;
712 case 2:
713 p->u.qam.modulation = QAM_128;
714 break;
715 case 3:
716 p->u.qam.modulation = QAM_256;
717 break;
718 case 4:
719 p->u.qam.modulation = QAM_64;
720 break;
721 }
722
723 return 0;
724}
725
726static void stv0297_release(struct dvb_frontend *fe)
727{
728 struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;
729 kfree(state);
730}
731
732static struct dvb_frontend_ops stv0297_ops;
733
734struct dvb_frontend *stv0297_attach(const struct stv0297_config *config,
735 struct i2c_adapter *i2c, int pwm)
736{
737 struct stv0297_state *state = NULL;
738
739 /* allocate memory for the internal state */
740 state = (struct stv0297_state *) kmalloc(sizeof(struct stv0297_state), GFP_KERNEL);
741 if (state == NULL)
742 goto error;
743
744 /* setup the state */
745 state->config = config;
746 state->i2c = i2c;
747 memcpy(&state->ops, &stv0297_ops, sizeof(struct dvb_frontend_ops));
748 state->base_freq = 0;
749 state->pwm = pwm;
750
751 /* check if the demod is there */
752 if ((stv0297_readreg(state, 0x80) & 0x70) != 0x20)
753 goto error;
754
755 /* create dvb_frontend */
756 state->frontend.ops = &state->ops;
757 state->frontend.demodulator_priv = state;
758 return &state->frontend;
759
760error:
761 kfree(state);
762 return NULL;
763}
764
765static struct dvb_frontend_ops stv0297_ops = {
766
767 .info = {
768 .name = "ST STV0297 DVB-C",
769 .type = FE_QAM,
770 .frequency_min = 64000000,
771 .frequency_max = 1300000000,
772 .frequency_stepsize = 62500,
773 .symbol_rate_min = 870000,
774 .symbol_rate_max = 11700000,
775 .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
776 FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO},
777
778 .release = stv0297_release,
779
780 .init = stv0297_init,
781 .sleep = stv0297_sleep,
782
783 .set_frontend = stv0297_set_frontend,
784 .get_frontend = stv0297_get_frontend,
785
786 .read_status = stv0297_read_status,
787 .read_ber = stv0297_read_ber,
788 .read_signal_strength = stv0297_read_signal_strength,
789 .read_snr = stv0297_read_snr,
790 .read_ucblocks = stv0297_read_ucblocks,
791};
792
793MODULE_DESCRIPTION("ST STV0297 DVB-C Demodulator driver");
794MODULE_AUTHOR("Dennis Noermann and Andrew de Quincey");
795MODULE_LICENSE("GPL");
796
797EXPORT_SYMBOL(stv0297_attach);
798EXPORT_SYMBOL(stv0297_enable_plli2c);
diff --git a/drivers/media/dvb/frontends/stv0297.h b/drivers/media/dvb/frontends/stv0297.h
new file mode 100644
index 000000000000..3be535989302
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0297.h
@@ -0,0 +1,44 @@
1/*
2 Driver for STV0297 demodulator
3
4 Copyright (C) 2003-2004 Dennis Noermann <dennis.noermann@noernet.de>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21#ifndef STV0297_H
22#define STV0297_H
23
24#include <linux/dvb/frontend.h>
25#include "dvb_frontend.h"
26
27struct stv0297_config
28{
29 /* the demodulator's i2c address */
30 u8 demod_address;
31
32 /* does the "inversion" need inverted? */
33 u8 invert:1;
34
35 /* PLL maintenance */
36 int (*pll_init)(struct dvb_frontend* fe);
37 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
38};
39
40extern struct dvb_frontend* stv0297_attach(const struct stv0297_config* config,
41 struct i2c_adapter* i2c, int pwm);
42extern int stv0297_enable_plli2c(struct dvb_frontend* fe);
43
44#endif // STV0297_H
diff --git a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c
new file mode 100644
index 000000000000..15b40541b62d
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0299.c
@@ -0,0 +1,731 @@
1/*
2 Driver for ST STV0299 demodulator
3
4 Copyright (C) 2001-2002 Convergence Integrated Media GmbH
5 <ralph@convergence.de>,
6 <holger@convergence.de>,
7 <js@convergence.de>
8
9
10 Philips SU1278/SH
11
12 Copyright (C) 2002 by Peter Schildmann <peter.schildmann@web.de>
13
14
15 LG TDQF-S001F
16
17 Copyright (C) 2002 Felix Domke <tmbinc@elitedvb.net>
18 & Andreas Oberritter <obi@linuxtv.org>
19
20
21 Support for Samsung TBMU24112IMB used on Technisat SkyStar2 rev. 2.6B
22
23 Copyright (C) 2003 Vadim Catana <skystar@moldova.cc>:
24
25 Support for Philips SU1278 on Technotrend hardware
26
27 Copyright (C) 2004 Andrew de Quincey <adq_dvb@lidskialf.net>
28
29 This program is free software; you can redistribute it and/or modify
30 it under the terms of the GNU General Public License as published by
31 the Free Software Foundation; either version 2 of the License, or
32 (at your option) any later version.
33
34 This program is distributed in the hope that it will be useful,
35 but WITHOUT ANY WARRANTY; without even the implied warranty of
36 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37 GNU General Public License for more details.
38
39 You should have received a copy of the GNU General Public License
40 along with this program; if not, write to the Free Software
41 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
42
43*/
44
45#include <linux/init.h>
46#include <linux/kernel.h>
47#include <linux/module.h>
48#include <linux/moduleparam.h>
49#include <linux/string.h>
50#include <linux/slab.h>
51#include <asm/div64.h>
52
53#include "dvb_frontend.h"
54#include "stv0299.h"
55
56struct stv0299_state {
57 struct i2c_adapter* i2c;
58 struct dvb_frontend_ops ops;
59 const struct stv0299_config* config;
60 struct dvb_frontend frontend;
61
62 u8 initialised:1;
63 u32 tuner_frequency;
64 u32 symbol_rate;
65 fe_code_rate_t fec_inner;
66 int errmode;
67};
68
69#define STATUS_BER 0
70#define STATUS_UCBLOCKS 1
71
72static int debug;
73#define dprintk(args...) \
74 do { \
75 if (debug) printk(KERN_DEBUG "stv0299: " args); \
76 } while (0)
77
78
79static int stv0299_writeregI (struct stv0299_state* state, u8 reg, u8 data)
80{
81 int ret;
82 u8 buf [] = { reg, data };
83 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
84
85 ret = i2c_transfer (state->i2c, &msg, 1);
86
87 if (ret != 1)
88 dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, "
89 "ret == %i)\n", __FUNCTION__, reg, data, ret);
90
91 return (ret != 1) ? -EREMOTEIO : 0;
92}
93
94int stv0299_writereg (struct dvb_frontend* fe, u8 reg, u8 data)
95{
96 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
97
98 return stv0299_writeregI(state, reg, data);
99}
100
101static u8 stv0299_readreg (struct stv0299_state* state, u8 reg)
102{
103 int ret;
104 u8 b0 [] = { reg };
105 u8 b1 [] = { 0 };
106 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
107 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
108
109 ret = i2c_transfer (state->i2c, msg, 2);
110
111 if (ret != 2)
112 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n",
113 __FUNCTION__, reg, ret);
114
115 return b1[0];
116}
117
118static int stv0299_readregs (struct stv0299_state* state, u8 reg1, u8 *b, u8 len)
119{
120 int ret;
121 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = &reg1, .len = 1 },
122 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b, .len = len } };
123
124 ret = i2c_transfer (state->i2c, msg, 2);
125
126 if (ret != 2)
127 dprintk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret);
128
129 return ret == 2 ? 0 : ret;
130}
131
132static int stv0299_set_FEC (struct stv0299_state* state, fe_code_rate_t fec)
133{
134 dprintk ("%s\n", __FUNCTION__);
135
136 switch (fec) {
137 case FEC_AUTO:
138 {
139 return stv0299_writeregI (state, 0x31, 0x1f);
140 }
141 case FEC_1_2:
142 {
143 return stv0299_writeregI (state, 0x31, 0x01);
144 }
145 case FEC_2_3:
146 {
147 return stv0299_writeregI (state, 0x31, 0x02);
148 }
149 case FEC_3_4:
150 {
151 return stv0299_writeregI (state, 0x31, 0x04);
152 }
153 case FEC_5_6:
154 {
155 return stv0299_writeregI (state, 0x31, 0x08);
156 }
157 case FEC_7_8:
158 {
159 return stv0299_writeregI (state, 0x31, 0x10);
160 }
161 default:
162 {
163 return -EINVAL;
164 }
165 }
166}
167
168static fe_code_rate_t stv0299_get_fec (struct stv0299_state* state)
169{
170 static fe_code_rate_t fec_tab [] = { FEC_2_3, FEC_3_4, FEC_5_6,
171 FEC_7_8, FEC_1_2 };
172 u8 index;
173
174 dprintk ("%s\n", __FUNCTION__);
175
176 index = stv0299_readreg (state, 0x1b);
177 index &= 0x7;
178
179 if (index > 4)
180 return FEC_AUTO;
181
182 return fec_tab [index];
183}
184
185static int stv0299_wait_diseqc_fifo (struct stv0299_state* state, int timeout)
186{
187 unsigned long start = jiffies;
188
189 dprintk ("%s\n", __FUNCTION__);
190
191 while (stv0299_readreg(state, 0x0a) & 1) {
192 if (jiffies - start > timeout) {
193 dprintk ("%s: timeout!!\n", __FUNCTION__);
194 return -ETIMEDOUT;
195 }
196 msleep(10);
197 };
198
199 return 0;
200}
201
202static int stv0299_wait_diseqc_idle (struct stv0299_state* state, int timeout)
203{
204 unsigned long start = jiffies;
205
206 dprintk ("%s\n", __FUNCTION__);
207
208 while ((stv0299_readreg(state, 0x0a) & 3) != 2 ) {
209 if (jiffies - start > timeout) {
210 dprintk ("%s: timeout!!\n", __FUNCTION__);
211 return -ETIMEDOUT;
212 }
213 msleep(10);
214 };
215
216 return 0;
217}
218
219static int stv0299_set_symbolrate (struct dvb_frontend* fe, u32 srate)
220{
221 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
222 u64 big = srate;
223 u32 ratio;
224
225 // check rate is within limits
226 if ((srate < 1000000) || (srate > 45000000)) return -EINVAL;
227
228 // calculate value to program
229 big = big << 20;
230 big += (state->config->mclk-1); // round correctly
231 do_div(big, state->config->mclk);
232 ratio = big << 4;
233
234 return state->config->set_symbol_rate(fe, srate, ratio);
235}
236
237static int stv0299_get_symbolrate (struct stv0299_state* state)
238{
239 u32 Mclk = state->config->mclk / 4096L;
240 u32 srate;
241 s32 offset;
242 u8 sfr[3];
243 s8 rtf;
244
245 dprintk ("%s\n", __FUNCTION__);
246
247 stv0299_readregs (state, 0x1f, sfr, 3);
248 stv0299_readregs (state, 0x1a, &rtf, 1);
249
250 srate = (sfr[0] << 8) | sfr[1];
251 srate *= Mclk;
252 srate /= 16;
253 srate += (sfr[2] >> 4) * Mclk / 256;
254 offset = (s32) rtf * (srate / 4096L);
255 offset /= 128;
256
257 dprintk ("%s : srate = %i\n", __FUNCTION__, srate);
258 dprintk ("%s : ofset = %i\n", __FUNCTION__, offset);
259
260 srate += offset;
261
262 srate += 1000;
263 srate /= 2000;
264 srate *= 2000;
265
266 return srate;
267}
268
269static int stv0299_send_diseqc_msg (struct dvb_frontend* fe,
270 struct dvb_diseqc_master_cmd *m)
271{
272 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
273 u8 val;
274 int i;
275
276 dprintk ("%s\n", __FUNCTION__);
277
278 if (stv0299_wait_diseqc_idle (state, 100) < 0)
279 return -ETIMEDOUT;
280
281 val = stv0299_readreg (state, 0x08);
282
283 if (stv0299_writeregI (state, 0x08, (val & ~0x7) | 0x6)) /* DiSEqC mode */
284 return -EREMOTEIO;
285
286 for (i=0; i<m->msg_len; i++) {
287 if (stv0299_wait_diseqc_fifo (state, 100) < 0)
288 return -ETIMEDOUT;
289
290 if (stv0299_writeregI (state, 0x09, m->msg[i]))
291 return -EREMOTEIO;
292 }
293
294 if (stv0299_wait_diseqc_idle (state, 100) < 0)
295 return -ETIMEDOUT;
296
297 return 0;
298}
299
300static int stv0299_send_diseqc_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
301{
302 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
303 u8 val;
304
305 dprintk ("%s\n", __FUNCTION__);
306
307 if (stv0299_wait_diseqc_idle (state, 100) < 0)
308 return -ETIMEDOUT;
309
310 val = stv0299_readreg (state, 0x08);
311
312 if (stv0299_writeregI (state, 0x08, (val & ~0x7) | 0x2)) /* burst mode */
313 return -EREMOTEIO;
314
315 if (stv0299_writeregI (state, 0x09, burst == SEC_MINI_A ? 0x00 : 0xff))
316 return -EREMOTEIO;
317
318 if (stv0299_wait_diseqc_idle (state, 100) < 0)
319 return -ETIMEDOUT;
320
321 if (stv0299_writeregI (state, 0x08, val))
322 return -EREMOTEIO;
323
324 return 0;
325}
326
327static int stv0299_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
328{
329 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
330 u8 val;
331
332 if (stv0299_wait_diseqc_idle (state, 100) < 0)
333 return -ETIMEDOUT;
334
335 val = stv0299_readreg (state, 0x08);
336
337 switch (tone) {
338 case SEC_TONE_ON:
339 return stv0299_writeregI (state, 0x08, val | 0x3);
340
341 case SEC_TONE_OFF:
342 return stv0299_writeregI (state, 0x08, (val & ~0x3) | 0x02);
343
344 default:
345 return -EINVAL;
346 }
347}
348
349static int stv0299_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage)
350{
351 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
352 u8 reg0x08;
353 u8 reg0x0c;
354
355 dprintk("%s: %s\n", __FUNCTION__,
356 voltage == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
357 voltage == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
358
359 reg0x08 = stv0299_readreg (state, 0x08);
360 reg0x0c = stv0299_readreg (state, 0x0c);
361
362 /**
363 * H/V switching over OP0, OP1 and OP2 are LNB power enable bits
364 */
365 reg0x0c &= 0x0f;
366
367 if (voltage == SEC_VOLTAGE_OFF) {
368 stv0299_writeregI (state, 0x0c, 0x00); /* LNB power off! */
369 return stv0299_writeregI (state, 0x08, 0x00); /* LNB power off! */
370 }
371
372 stv0299_writeregI (state, 0x08, (reg0x08 & 0x3f) | (state->config->lock_output << 6));
373
374 switch (voltage) {
375 case SEC_VOLTAGE_13:
376 if (state->config->volt13_op0_op1 == STV0299_VOLT13_OP0) reg0x0c |= 0x10;
377 else reg0x0c |= 0x40;
378
379 return stv0299_writeregI(state, 0x0c, reg0x0c);
380
381 case SEC_VOLTAGE_18:
382 return stv0299_writeregI(state, 0x0c, reg0x0c | 0x50);
383 default:
384 return -EINVAL;
385 };
386}
387
388static int stv0299_send_legacy_dish_cmd(struct dvb_frontend* fe, u32 cmd)
389{
390 u8 last = 1;
391 int i;
392
393 /* reset voltage at the end
394 if((0x50 & stv0299_readreg (i2c, 0x0c)) == 0x50)
395 cmd |= 0x80;
396 else
397 cmd &= 0x7F;
398 */
399
400 cmd = cmd << 1;
401 dprintk("%s switch command: 0x%04x\n",__FUNCTION__, cmd);
402
403 stv0299_set_voltage(fe,SEC_VOLTAGE_18);
404 msleep(32);
405
406 for (i=0; i<9; i++) {
407 if((cmd & 0x01) != last) {
408 stv0299_set_voltage(fe, last ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18);
409 last = (last) ? 0 : 1;
410 }
411
412 cmd = cmd >> 1;
413
414 if (i != 8)
415 msleep(8);
416 }
417
418 return 0;
419}
420
421static int stv0299_init (struct dvb_frontend* fe)
422{
423 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
424 int i;
425
426 dprintk("stv0299: init chip\n");
427
428 for (i=0; !(state->config->inittab[i] == 0xff && state->config->inittab[i+1] == 0xff); i+=2)
429 stv0299_writeregI(state, state->config->inittab[i], state->config->inittab[i+1]);
430
431 if (state->config->pll_init) {
432 stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */
433 state->config->pll_init(fe);
434 stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */
435 }
436
437 return 0;
438}
439
440static int stv0299_read_status(struct dvb_frontend* fe, fe_status_t* status)
441{
442 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
443
444 u8 signal = 0xff - stv0299_readreg (state, 0x18);
445 u8 sync = stv0299_readreg (state, 0x1b);
446
447 dprintk ("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __FUNCTION__, sync);
448 *status = 0;
449
450 if (signal > 10)
451 *status |= FE_HAS_SIGNAL;
452
453 if (sync & 0x80)
454 *status |= FE_HAS_CARRIER;
455
456 if (sync & 0x10)
457 *status |= FE_HAS_VITERBI;
458
459 if (sync & 0x08)
460 *status |= FE_HAS_SYNC;
461
462 if ((sync & 0x98) == 0x98)
463 *status |= FE_HAS_LOCK;
464
465 return 0;
466}
467
468static int stv0299_read_ber(struct dvb_frontend* fe, u32* ber)
469{
470 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
471
472 if (state->errmode != STATUS_BER) return 0;
473 *ber = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e);
474
475 return 0;
476}
477
478static int stv0299_read_signal_strength(struct dvb_frontend* fe, u16* strength)
479{
480 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
481
482 s32 signal = 0xffff - ((stv0299_readreg (state, 0x18) << 8)
483 | stv0299_readreg (state, 0x19));
484
485 dprintk ("%s : FE_READ_SIGNAL_STRENGTH : AGC2I: 0x%02x%02x, signal=0x%04x\n", __FUNCTION__,
486 stv0299_readreg (state, 0x18),
487 stv0299_readreg (state, 0x19), (int) signal);
488
489 signal = signal * 5 / 4;
490 *strength = (signal > 0xffff) ? 0xffff : (signal < 0) ? 0 : signal;
491
492 return 0;
493}
494
495static int stv0299_read_snr(struct dvb_frontend* fe, u16* snr)
496{
497 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
498
499 s32 xsnr = 0xffff - ((stv0299_readreg (state, 0x24) << 8)
500 | stv0299_readreg (state, 0x25));
501 xsnr = 3 * (xsnr - 0xa100);
502 *snr = (xsnr > 0xffff) ? 0xffff : (xsnr < 0) ? 0 : xsnr;
503
504 return 0;
505}
506
507static int stv0299_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
508{
509 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
510
511 if (state->errmode != STATUS_UCBLOCKS) *ucblocks = 0;
512 else *ucblocks = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e);
513
514 return 0;
515}
516
517static int stv0299_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters * p)
518{
519 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
520 int invval = 0;
521
522 dprintk ("%s : FE_SET_FRONTEND\n", __FUNCTION__);
523
524 // set the inversion
525 if (p->inversion == INVERSION_OFF) invval = 0;
526 else if (p->inversion == INVERSION_ON) invval = 1;
527 else {
528 printk("stv0299 does not support auto-inversion\n");
529 return -EINVAL;
530 }
531 if (state->config->invert) invval = (~invval) & 1;
532 stv0299_writeregI(state, 0x0c, (stv0299_readreg(state, 0x0c) & 0xfe) | invval);
533
534 if (state->config->enhanced_tuning) {
535 /* check if we should do a finetune */
536 int frequency_delta = p->frequency - state->tuner_frequency;
537 int minmax = p->u.qpsk.symbol_rate / 2000;
538 if (minmax < 5000) minmax = 5000;
539
540 if ((frequency_delta > -minmax) && (frequency_delta < minmax) && (frequency_delta != 0) &&
541 (state->fec_inner == p->u.qpsk.fec_inner) &&
542 (state->symbol_rate == p->u.qpsk.symbol_rate)) {
543 int Drot_freq = (frequency_delta << 16) / (state->config->mclk / 1000);
544
545 // zap the derotator registers first
546 stv0299_writeregI(state, 0x22, 0x00);
547 stv0299_writeregI(state, 0x23, 0x00);
548
549 // now set them as we want
550 stv0299_writeregI(state, 0x22, Drot_freq >> 8);
551 stv0299_writeregI(state, 0x23, Drot_freq);
552 } else {
553 /* A "normal" tune is requested */
554 stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */
555 state->config->pll_set(fe, p);
556 stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */
557
558 stv0299_writeregI(state, 0x32, 0x80);
559 stv0299_writeregI(state, 0x22, 0x00);
560 stv0299_writeregI(state, 0x23, 0x00);
561 stv0299_writeregI(state, 0x32, 0x19);
562 stv0299_set_symbolrate (fe, p->u.qpsk.symbol_rate);
563 stv0299_set_FEC (state, p->u.qpsk.fec_inner);
564 }
565 } else {
566 stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */
567 state->config->pll_set(fe, p);
568 stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */
569
570 stv0299_set_FEC (state, p->u.qpsk.fec_inner);
571 stv0299_set_symbolrate (fe, p->u.qpsk.symbol_rate);
572 stv0299_writeregI(state, 0x22, 0x00);
573 stv0299_writeregI(state, 0x23, 0x00);
574 stv0299_readreg (state, 0x23);
575 stv0299_writeregI(state, 0x12, 0xb9);
576 }
577
578 state->tuner_frequency = p->frequency;
579 state->fec_inner = p->u.qpsk.fec_inner;
580 state->symbol_rate = p->u.qpsk.symbol_rate;
581
582 return 0;
583}
584
585static int stv0299_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters * p)
586{
587 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
588 s32 derot_freq;
589 int invval;
590
591 derot_freq = (s32)(s16) ((stv0299_readreg (state, 0x22) << 8)
592 | stv0299_readreg (state, 0x23));
593
594 derot_freq *= (state->config->mclk >> 16);
595 derot_freq += 500;
596 derot_freq /= 1000;
597
598 p->frequency += derot_freq;
599
600 invval = stv0299_readreg (state, 0x0c) & 1;
601 if (state->config->invert) invval = (~invval) & 1;
602 p->inversion = invval ? INVERSION_ON : INVERSION_OFF;
603
604 p->u.qpsk.fec_inner = stv0299_get_fec (state);
605 p->u.qpsk.symbol_rate = stv0299_get_symbolrate (state);
606
607 return 0;
608}
609
610static int stv0299_sleep(struct dvb_frontend* fe)
611{
612 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
613
614 stv0299_writeregI(state, 0x02, 0x80);
615 state->initialised = 0;
616
617 return 0;
618}
619
620static int stv0299_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
621{
622 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
623
624 fesettings->min_delay_ms = state->config->min_delay_ms;
625 if (fesettings->parameters.u.qpsk.symbol_rate < 10000000) {
626 fesettings->step_size = fesettings->parameters.u.qpsk.symbol_rate / 32000;
627 fesettings->max_drift = 5000;
628 } else {
629 fesettings->step_size = fesettings->parameters.u.qpsk.symbol_rate / 16000;
630 fesettings->max_drift = fesettings->parameters.u.qpsk.symbol_rate / 2000;
631 }
632 return 0;
633}
634
635static void stv0299_release(struct dvb_frontend* fe)
636{
637 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
638 kfree(state);
639}
640
641static struct dvb_frontend_ops stv0299_ops;
642
643struct dvb_frontend* stv0299_attach(const struct stv0299_config* config,
644 struct i2c_adapter* i2c)
645{
646 struct stv0299_state* state = NULL;
647 int id;
648
649 /* allocate memory for the internal state */
650 state = (struct stv0299_state*) kmalloc(sizeof(struct stv0299_state), GFP_KERNEL);
651 if (state == NULL) goto error;
652
653 /* setup the state */
654 state->config = config;
655 state->i2c = i2c;
656 memcpy(&state->ops, &stv0299_ops, sizeof(struct dvb_frontend_ops));
657 state->initialised = 0;
658 state->tuner_frequency = 0;
659 state->symbol_rate = 0;
660 state->fec_inner = 0;
661 state->errmode = STATUS_BER;
662
663 /* check if the demod is there */
664 stv0299_writeregI(state, 0x02, 0x34); /* standby off */
665 msleep(200);
666 id = stv0299_readreg(state, 0x00);
667
668 /* register 0x00 contains 0xa1 for STV0299 and STV0299B */
669 /* register 0x00 might contain 0x80 when returning from standby */
670 if (id != 0xa1 && id != 0x80) goto error;
671
672 /* create dvb_frontend */
673 state->frontend.ops = &state->ops;
674 state->frontend.demodulator_priv = state;
675 return &state->frontend;
676
677error:
678 kfree(state);
679 return NULL;
680}
681
682static struct dvb_frontend_ops stv0299_ops = {
683
684 .info = {
685 .name = "ST STV0299 DVB-S",
686 .type = FE_QPSK,
687 .frequency_min = 950000,
688 .frequency_max = 2150000,
689 .frequency_stepsize = 125, /* kHz for QPSK frontends */
690 .frequency_tolerance = 0,
691 .symbol_rate_min = 1000000,
692 .symbol_rate_max = 45000000,
693 .symbol_rate_tolerance = 500, /* ppm */
694 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
695 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
696 FE_CAN_QPSK |
697 FE_CAN_FEC_AUTO
698 },
699
700 .release = stv0299_release,
701
702 .init = stv0299_init,
703 .sleep = stv0299_sleep,
704
705 .set_frontend = stv0299_set_frontend,
706 .get_frontend = stv0299_get_frontend,
707 .get_tune_settings = stv0299_get_tune_settings,
708
709 .read_status = stv0299_read_status,
710 .read_ber = stv0299_read_ber,
711 .read_signal_strength = stv0299_read_signal_strength,
712 .read_snr = stv0299_read_snr,
713 .read_ucblocks = stv0299_read_ucblocks,
714
715 .diseqc_send_master_cmd = stv0299_send_diseqc_msg,
716 .diseqc_send_burst = stv0299_send_diseqc_burst,
717 .set_tone = stv0299_set_tone,
718 .set_voltage = stv0299_set_voltage,
719 .dishnetwork_send_legacy_command = stv0299_send_legacy_dish_cmd,
720};
721
722module_param(debug, int, 0644);
723MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
724
725MODULE_DESCRIPTION("ST STV0299 DVB Demodulator driver");
726MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Peter Schildmann, Felix Domke, "
727 "Andreas Oberritter, Andrew de Quincey, Kenneth Aafløy");
728MODULE_LICENSE("GPL");
729
730EXPORT_SYMBOL(stv0299_writereg);
731EXPORT_SYMBOL(stv0299_attach);
diff --git a/drivers/media/dvb/frontends/stv0299.h b/drivers/media/dvb/frontends/stv0299.h
new file mode 100644
index 000000000000..79457a80a11f
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0299.h
@@ -0,0 +1,104 @@
1/*
2 Driver for ST STV0299 demodulator
3
4 Copyright (C) 2001-2002 Convergence Integrated Media GmbH
5 <ralph@convergence.de>,
6 <holger@convergence.de>,
7 <js@convergence.de>
8
9
10 Philips SU1278/SH
11
12 Copyright (C) 2002 by Peter Schildmann <peter.schildmann@web.de>
13
14
15 LG TDQF-S001F
16
17 Copyright (C) 2002 Felix Domke <tmbinc@elitedvb.net>
18 & Andreas Oberritter <obi@linuxtv.org>
19
20
21 Support for Samsung TBMU24112IMB used on Technisat SkyStar2 rev. 2.6B
22
23 Copyright (C) 2003 Vadim Catana <skystar@moldova.cc>:
24
25 Support for Philips SU1278 on Technotrend hardware
26
27 Copyright (C) 2004 Andrew de Quincey <adq_dvb@lidskialf.net>
28
29 This program is free software; you can redistribute it and/or modify
30 it under the terms of the GNU General Public License as published by
31 the Free Software Foundation; either version 2 of the License, or
32 (at your option) any later version.
33
34 This program is distributed in the hope that it will be useful,
35 but WITHOUT ANY WARRANTY; without even the implied warranty of
36 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37 GNU General Public License for more details.
38
39 You should have received a copy of the GNU General Public License
40 along with this program; if not, write to the Free Software
41 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
42
43*/
44
45#ifndef STV0299_H
46#define STV0299_H
47
48#include <linux/dvb/frontend.h>
49#include "dvb_frontend.h"
50
51#define STV0229_LOCKOUTPUT_0 0
52#define STV0229_LOCKOUTPUT_1 1
53#define STV0229_LOCKOUTPUT_CF 2
54#define STV0229_LOCKOUTPUT_LK 3
55
56#define STV0299_VOLT13_OP0 0
57#define STV0299_VOLT13_OP1 1
58
59struct stv0299_config
60{
61 /* the demodulator's i2c address */
62 u8 demod_address;
63
64 /* inittab - array of pairs of values.
65 * First of each pair is the register, second is the value.
66 * List should be terminated with an 0xff, 0xff pair.
67 */
68 u8* inittab;
69
70 /* master clock to use */
71 u32 mclk;
72
73 /* does the inversion require inversion? */
74 u8 invert:1;
75
76 /* Should the enhanced tuning code be used? */
77 u8 enhanced_tuning:1;
78
79 /* Skip reinitialisation? */
80 u8 skip_reinit:1;
81
82 /* LOCK OUTPUT setting */
83 u8 lock_output:2;
84
85 /* Is 13v controlled by OP0 or OP1? */
86 u8 volt13_op0_op1:1;
87
88 /* minimum delay before retuning */
89 int min_delay_ms;
90
91 /* Set the symbol rate */
92 int (*set_symbol_rate)(struct dvb_frontend* fe, u32 srate, u32 ratio);
93
94 /* PLL maintenance */
95 int (*pll_init)(struct dvb_frontend* fe);
96 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
97};
98
99extern int stv0299_writereg (struct dvb_frontend* fe, u8 reg, u8 data);
100
101extern struct dvb_frontend* stv0299_attach(const struct stv0299_config* config,
102 struct i2c_adapter* i2c);
103
104#endif // STV0299_H
diff --git a/drivers/media/dvb/frontends/tda10021.c b/drivers/media/dvb/frontends/tda10021.c
new file mode 100644
index 000000000000..4e40d95ee95d
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda10021.c
@@ -0,0 +1,469 @@
1/*
2 TDA10021 - Single Chip Cable Channel Receiver driver module
3 used on the the Siemens DVB-C cards
4
5 Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
6 Copyright (C) 2004 Markus Schulz <msc@antzsystem.de>
7 Support for TDA10021
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22*/
23
24#include <linux/config.h>
25#include <linux/delay.h>
26#include <linux/errno.h>
27#include <linux/init.h>
28#include <linux/kernel.h>
29#include <linux/module.h>
30#include <linux/string.h>
31#include <linux/slab.h>
32
33#include "dvb_frontend.h"
34#include "tda10021.h"
35
36
37struct tda10021_state {
38 struct i2c_adapter* i2c;
39 struct dvb_frontend_ops ops;
40 /* configuration settings */
41 const struct tda10021_config* config;
42 struct dvb_frontend frontend;
43
44 u8 pwm;
45 u8 reg0;
46};
47
48
49#if 0
50#define dprintk(x...) printk(x)
51#else
52#define dprintk(x...)
53#endif
54
55static int verbose;
56
57#define XIN 57840000UL
58#define DISABLE_INVERSION(reg0) do { reg0 |= 0x20; } while (0)
59#define ENABLE_INVERSION(reg0) do { reg0 &= ~0x20; } while (0)
60#define HAS_INVERSION(reg0) (!(reg0 & 0x20))
61
62#define FIN (XIN >> 4)
63
64static int tda10021_inittab_size = 0x40;
65static u8 tda10021_inittab[0x40]=
66{
67 0x73, 0x6a, 0x23, 0x0a, 0x02, 0x37, 0x77, 0x1a,
68 0x37, 0x6a, 0x17, 0x8a, 0x1e, 0x86, 0x43, 0x40,
69 0xb8, 0x3f, 0xa0, 0x00, 0xcd, 0x01, 0x00, 0xff,
70 0x11, 0x00, 0x7c, 0x31, 0x30, 0x20, 0x00, 0x00,
71 0x02, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x00,
72 0x07, 0x00, 0x33, 0x11, 0x0d, 0x95, 0x08, 0x58,
73 0x00, 0x00, 0x80, 0x00, 0x80, 0xff, 0x00, 0x00,
74 0x04, 0x2d, 0x2f, 0xff, 0x00, 0x00, 0x00, 0x00,
75};
76
77static int tda10021_writereg (struct tda10021_state* state, u8 reg, u8 data)
78{
79 u8 buf[] = { reg, data };
80 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
81 int ret;
82
83 ret = i2c_transfer (state->i2c, &msg, 1);
84 if (ret != 1)
85 printk("DVB: TDA10021(%d): %s, writereg error "
86 "(reg == 0x%02x, val == 0x%02x, ret == %i)\n",
87 state->frontend.dvb->num, __FUNCTION__, reg, data, ret);
88
89 msleep(10);
90 return (ret != 1) ? -EREMOTEIO : 0;
91}
92
93static u8 tda10021_readreg (struct tda10021_state* state, u8 reg)
94{
95 u8 b0 [] = { reg };
96 u8 b1 [] = { 0 };
97 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
98 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
99 int ret;
100
101 ret = i2c_transfer (state->i2c, msg, 2);
102 if (ret != 2)
103 printk("DVB: TDA10021(%d): %s: readreg error (ret == %i)\n",
104 state->frontend.dvb->num, __FUNCTION__, ret);
105 return b1[0];
106}
107
108//get access to tuner
109static int lock_tuner(struct tda10021_state* state)
110{
111 u8 buf[2] = { 0x0f, tda10021_inittab[0x0f] | 0x80 };
112 struct i2c_msg msg = {.addr=state->config->demod_address, .flags=0, .buf=buf, .len=2};
113
114 if(i2c_transfer(state->i2c, &msg, 1) != 1)
115 {
116 printk("tda10021: lock tuner fails\n");
117 return -EREMOTEIO;
118 }
119 return 0;
120}
121
122//release access from tuner
123static int unlock_tuner(struct tda10021_state* state)
124{
125 u8 buf[2] = { 0x0f, tda10021_inittab[0x0f] & 0x7f };
126 struct i2c_msg msg_post={.addr=state->config->demod_address, .flags=0, .buf=buf, .len=2};
127
128 if(i2c_transfer(state->i2c, &msg_post, 1) != 1)
129 {
130 printk("tda10021: unlock tuner fails\n");
131 return -EREMOTEIO;
132 }
133 return 0;
134}
135
136static int tda10021_setup_reg0 (struct tda10021_state* state, u8 reg0,
137 fe_spectral_inversion_t inversion)
138{
139 reg0 |= state->reg0 & 0x63;
140
141 if (INVERSION_ON == inversion)
142 ENABLE_INVERSION(reg0);
143 else if (INVERSION_OFF == inversion)
144 DISABLE_INVERSION(reg0);
145
146 tda10021_writereg (state, 0x00, reg0 & 0xfe);
147 tda10021_writereg (state, 0x00, reg0 | 0x01);
148
149 state->reg0 = reg0;
150 return 0;
151}
152
153static int tda10021_set_symbolrate (struct tda10021_state* state, u32 symbolrate)
154{
155 s32 BDR;
156 s32 BDRI;
157 s16 SFIL=0;
158 u16 NDEC = 0;
159 u32 tmp, ratio;
160
161 if (symbolrate > XIN/2)
162 symbolrate = XIN/2;
163 if (symbolrate < 500000)
164 symbolrate = 500000;
165
166 if (symbolrate < XIN/16) NDEC = 1;
167 if (symbolrate < XIN/32) NDEC = 2;
168 if (symbolrate < XIN/64) NDEC = 3;
169
170 if (symbolrate < (u32)(XIN/12.3)) SFIL = 1;
171 if (symbolrate < (u32)(XIN/16)) SFIL = 0;
172 if (symbolrate < (u32)(XIN/24.6)) SFIL = 1;
173 if (symbolrate < (u32)(XIN/32)) SFIL = 0;
174 if (symbolrate < (u32)(XIN/49.2)) SFIL = 1;
175 if (symbolrate < (u32)(XIN/64)) SFIL = 0;
176 if (symbolrate < (u32)(XIN/98.4)) SFIL = 1;
177
178 symbolrate <<= NDEC;
179 ratio = (symbolrate << 4) / FIN;
180 tmp = ((symbolrate << 4) % FIN) << 8;
181 ratio = (ratio << 8) + tmp / FIN;
182 tmp = (tmp % FIN) << 8;
183 ratio = (ratio << 8) + (tmp + FIN/2) / FIN;
184
185 BDR = ratio;
186 BDRI = (((XIN << 5) / symbolrate) + 1) / 2;
187
188 if (BDRI > 0xFF)
189 BDRI = 0xFF;
190
191 SFIL = (SFIL << 4) | tda10021_inittab[0x0E];
192
193 NDEC = (NDEC << 6) | tda10021_inittab[0x03];
194
195 tda10021_writereg (state, 0x03, NDEC);
196 tda10021_writereg (state, 0x0a, BDR&0xff);
197 tda10021_writereg (state, 0x0b, (BDR>> 8)&0xff);
198 tda10021_writereg (state, 0x0c, (BDR>>16)&0x3f);
199
200 tda10021_writereg (state, 0x0d, BDRI);
201 tda10021_writereg (state, 0x0e, SFIL);
202
203 return 0;
204}
205
206static int tda10021_init (struct dvb_frontend *fe)
207{
208 struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv;
209 int i;
210
211 dprintk("DVB: TDA10021(%d): init chip\n", fe->adapter->num);
212
213 //tda10021_writereg (fe, 0, 0);
214
215 for (i=0; i<tda10021_inittab_size; i++)
216 tda10021_writereg (state, i, tda10021_inittab[i]);
217
218 tda10021_writereg (state, 0x34, state->pwm);
219
220 //Comment by markus
221 //0x2A[3-0] == PDIV -> P multiplaying factor (P=PDIV+1)(default 0)
222 //0x2A[4] == BYPPLL -> Power down mode (default 1)
223 //0x2A[5] == LCK -> PLL Lock Flag
224 //0x2A[6] == POLAXIN -> Polarity of the input reference clock (default 0)
225
226 //Activate PLL
227 tda10021_writereg(state, 0x2a, tda10021_inittab[0x2a] & 0xef);
228
229 if (state->config->pll_init) {
230 lock_tuner(state);
231 state->config->pll_init(fe);
232 unlock_tuner(state);
233 }
234
235 return 0;
236}
237
238static int tda10021_set_parameters (struct dvb_frontend *fe,
239 struct dvb_frontend_parameters *p)
240{
241 struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv;
242
243 //table for QAM4-QAM256 ready QAM4 QAM16 QAM32 QAM64 QAM128 QAM256
244 //CONF
245 static const u8 reg0x00 [] = { 0x14, 0x00, 0x04, 0x08, 0x0c, 0x10 };
246 //AGCREF value
247 static const u8 reg0x01 [] = { 0x78, 0x8c, 0x8c, 0x6a, 0x78, 0x5c };
248 //LTHR value
249 static const u8 reg0x05 [] = { 0x78, 0x87, 0x64, 0x46, 0x36, 0x26 };
250 //MSETH
251 static const u8 reg0x08 [] = { 0x8c, 0xa2, 0x74, 0x43, 0x34, 0x23 };
252 //AREF
253 static const u8 reg0x09 [] = { 0x96, 0x91, 0x96, 0x6a, 0x7e, 0x6b };
254
255 int qam = p->u.qam.modulation;
256
257 if (qam < 0 || qam > 5)
258 return -EINVAL;
259
260 //printk("tda10021: set frequency to %d qam=%d symrate=%d\n", p->frequency,qam,p->u.qam.symbol_rate);
261
262 lock_tuner(state);
263 state->config->pll_set(fe, p);
264 unlock_tuner(state);
265
266 tda10021_set_symbolrate (state, p->u.qam.symbol_rate);
267 tda10021_writereg (state, 0x34, state->pwm);
268
269 tda10021_writereg (state, 0x01, reg0x01[qam]);
270 tda10021_writereg (state, 0x05, reg0x05[qam]);
271 tda10021_writereg (state, 0x08, reg0x08[qam]);
272 tda10021_writereg (state, 0x09, reg0x09[qam]);
273
274 tda10021_setup_reg0 (state, reg0x00[qam], p->inversion);
275
276 return 0;
277}
278
279static int tda10021_read_status(struct dvb_frontend* fe, fe_status_t* status)
280{
281 struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv;
282 int sync;
283
284 *status = 0;
285 //0x11[0] == EQALGO -> Equalizer algorithms state
286 //0x11[1] == CARLOCK -> Carrier locked
287 //0x11[2] == FSYNC -> Frame synchronisation
288 //0x11[3] == FEL -> Front End locked
289 //0x11[6] == NODVB -> DVB Mode Information
290 sync = tda10021_readreg (state, 0x11);
291
292 if (sync & 2)
293 *status |= FE_HAS_SIGNAL|FE_HAS_CARRIER;
294
295 if (sync & 4)
296 *status |= FE_HAS_SYNC|FE_HAS_VITERBI;
297
298 if (sync & 8)
299 *status |= FE_HAS_LOCK;
300
301 return 0;
302}
303
304static int tda10021_read_ber(struct dvb_frontend* fe, u32* ber)
305{
306 struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv;
307
308 u32 _ber = tda10021_readreg(state, 0x14) |
309 (tda10021_readreg(state, 0x15) << 8) |
310 ((tda10021_readreg(state, 0x16) & 0x0f) << 16);
311 *ber = 10 * _ber;
312
313 return 0;
314}
315
316static int tda10021_read_signal_strength(struct dvb_frontend* fe, u16* strength)
317{
318 struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv;
319
320 u8 gain = tda10021_readreg(state, 0x17);
321 *strength = (gain << 8) | gain;
322
323 return 0;
324}
325
326static int tda10021_read_snr(struct dvb_frontend* fe, u16* snr)
327{
328 struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv;
329
330 u8 quality = ~tda10021_readreg(state, 0x18);
331 *snr = (quality << 8) | quality;
332
333 return 0;
334}
335
336static int tda10021_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
337{
338 struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv;
339
340 *ucblocks = tda10021_readreg (state, 0x13) & 0x7f;
341 if (*ucblocks == 0x7f)
342 *ucblocks = 0xffffffff;
343
344 /* reset uncorrected block counter */
345 tda10021_writereg (state, 0x10, tda10021_inittab[0x10] & 0xdf);
346 tda10021_writereg (state, 0x10, tda10021_inittab[0x10]);
347
348 return 0;
349}
350
351static int tda10021_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
352{
353 struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv;
354 int sync;
355 s8 afc = 0;
356
357 sync = tda10021_readreg(state, 0x11);
358 afc = tda10021_readreg(state, 0x19);
359 if (verbose) {
360 /* AFC only valid when carrier has been recovered */
361 printk(sync & 2 ? "DVB: TDA10021(%d): AFC (%d) %dHz\n" :
362 "DVB: TDA10021(%d): [AFC (%d) %dHz]\n",
363 state->frontend.dvb->num, afc,
364 -((s32)p->u.qam.symbol_rate * afc) >> 10);
365 }
366
367 p->inversion = HAS_INVERSION(state->reg0) ? INVERSION_ON : INVERSION_OFF;
368 p->u.qam.modulation = ((state->reg0 >> 2) & 7) + QAM_16;
369
370 p->u.qam.fec_inner = FEC_NONE;
371 p->frequency = ((p->frequency + 31250) / 62500) * 62500;
372
373 if (sync & 2)
374 p->frequency -= ((s32)p->u.qam.symbol_rate * afc) >> 10;
375
376 return 0;
377}
378
379static int tda10021_sleep(struct dvb_frontend* fe)
380{
381 struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv;
382
383 tda10021_writereg (state, 0x1b, 0x02); /* pdown ADC */
384 tda10021_writereg (state, 0x00, 0x80); /* standby */
385
386 return 0;
387}
388
389static void tda10021_release(struct dvb_frontend* fe)
390{
391 struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv;
392 kfree(state);
393}
394
395static struct dvb_frontend_ops tda10021_ops;
396
397struct dvb_frontend* tda10021_attach(const struct tda10021_config* config,
398 struct i2c_adapter* i2c,
399 u8 pwm)
400{
401 struct tda10021_state* state = NULL;
402
403 /* allocate memory for the internal state */
404 state = (struct tda10021_state*) kmalloc(sizeof(struct tda10021_state), GFP_KERNEL);
405 if (state == NULL) goto error;
406
407 /* setup the state */
408 state->config = config;
409 state->i2c = i2c;
410 memcpy(&state->ops, &tda10021_ops, sizeof(struct dvb_frontend_ops));
411 state->pwm = pwm;
412 state->reg0 = tda10021_inittab[0];
413
414 /* check if the demod is there */
415 if ((tda10021_readreg(state, 0x1a) & 0xf0) != 0x70) goto error;
416
417 /* create dvb_frontend */
418 state->frontend.ops = &state->ops;
419 state->frontend.demodulator_priv = state;
420 return &state->frontend;
421
422error:
423 kfree(state);
424 return NULL;
425}
426
427static struct dvb_frontend_ops tda10021_ops = {
428
429 .info = {
430 .name = "Philips TDA10021 DVB-C",
431 .type = FE_QAM,
432 .frequency_stepsize = 62500,
433 .frequency_min = 51000000,
434 .frequency_max = 858000000,
435 .symbol_rate_min = (XIN/2)/64, /* SACLK/64 == (XIN/2)/64 */
436 .symbol_rate_max = (XIN/2)/4, /* SACLK/4 */
437 #if 0
438 .frequency_tolerance = ???,
439 .symbol_rate_tolerance = ???, /* ppm */ /* == 8% (spec p. 5) */
440 #endif
441 .caps = 0x400 | //FE_CAN_QAM_4
442 FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
443 FE_CAN_QAM_128 | FE_CAN_QAM_256 |
444 FE_CAN_FEC_AUTO
445 },
446
447 .release = tda10021_release,
448
449 .init = tda10021_init,
450 .sleep = tda10021_sleep,
451
452 .set_frontend = tda10021_set_parameters,
453 .get_frontend = tda10021_get_frontend,
454
455 .read_status = tda10021_read_status,
456 .read_ber = tda10021_read_ber,
457 .read_signal_strength = tda10021_read_signal_strength,
458 .read_snr = tda10021_read_snr,
459 .read_ucblocks = tda10021_read_ucblocks,
460};
461
462module_param(verbose, int, 0644);
463MODULE_PARM_DESC(verbose, "print AFC offset after tuning for debugging the PWM setting");
464
465MODULE_DESCRIPTION("Philips TDA10021 DVB-C demodulator driver");
466MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Markus Schulz");
467MODULE_LICENSE("GPL");
468
469EXPORT_SYMBOL(tda10021_attach);
diff --git a/drivers/media/dvb/frontends/tda10021.h b/drivers/media/dvb/frontends/tda10021.h
new file mode 100644
index 000000000000..7d6a51ce291e
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda10021.h
@@ -0,0 +1,42 @@
1/*
2 TDA10021 - Single Chip Cable Channel Receiver driver module
3 used on the the Siemens DVB-C cards
4
5 Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
6 Copyright (C) 2004 Markus Schulz <msc@antzsystem.de>
7 Support for TDA10021
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22*/
23
24#ifndef TDA10021_H
25#define TDA10021_H
26
27#include <linux/dvb/frontend.h>
28
29struct tda10021_config
30{
31 /* the demodulator's i2c address */
32 u8 demod_address;
33
34 /* PLL maintenance */
35 int (*pll_init)(struct dvb_frontend* fe);
36 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
37};
38
39extern struct dvb_frontend* tda10021_attach(const struct tda10021_config* config,
40 struct i2c_adapter* i2c, u8 pwm);
41
42#endif // TDA10021_H
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c
new file mode 100644
index 000000000000..687ad9cf3384
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda1004x.c
@@ -0,0 +1,1206 @@
1 /*
2 Driver for Philips tda1004xh OFDM Demodulator
3
4 (c) 2003, 2004 Andrew de Quincey & Robert Schlabbach
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 */
22/*
23 * This driver needs external firmware. Please use the commands
24 * "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10045",
25 * "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10046" to
26 * download/extract them, and then copy them to /usr/lib/hotplug/firmware.
27 */
28#define TDA10045_DEFAULT_FIRMWARE "dvb-fe-tda10045.fw"
29#define TDA10046_DEFAULT_FIRMWARE "dvb-fe-tda10046.fw"
30
31#include <linux/init.h>
32#include <linux/module.h>
33#include <linux/moduleparam.h>
34#include <linux/device.h>
35#include "dvb_frontend.h"
36#include "tda1004x.h"
37
38#define TDA1004X_DEMOD_TDA10045 0
39#define TDA1004X_DEMOD_TDA10046 1
40
41
42struct tda1004x_state {
43 struct i2c_adapter* i2c;
44 struct dvb_frontend_ops ops;
45 const struct tda1004x_config* config;
46 struct dvb_frontend frontend;
47
48 /* private demod data */
49 u8 initialised:1;
50 u8 demod_type;
51};
52
53
54static int debug;
55#define dprintk(args...) \
56 do { \
57 if (debug) printk(KERN_DEBUG "tda1004x: " args); \
58 } while (0)
59
60#define TDA1004X_CHIPID 0x00
61#define TDA1004X_AUTO 0x01
62#define TDA1004X_IN_CONF1 0x02
63#define TDA1004X_IN_CONF2 0x03
64#define TDA1004X_OUT_CONF1 0x04
65#define TDA1004X_OUT_CONF2 0x05
66#define TDA1004X_STATUS_CD 0x06
67#define TDA1004X_CONFC4 0x07
68#define TDA1004X_DSSPARE2 0x0C
69#define TDA10045H_CODE_IN 0x0D
70#define TDA10045H_FWPAGE 0x0E
71#define TDA1004X_SCAN_CPT 0x10
72#define TDA1004X_DSP_CMD 0x11
73#define TDA1004X_DSP_ARG 0x12
74#define TDA1004X_DSP_DATA1 0x13
75#define TDA1004X_DSP_DATA2 0x14
76#define TDA1004X_CONFADC1 0x15
77#define TDA1004X_CONFC1 0x16
78#define TDA10045H_S_AGC 0x1a
79#define TDA10046H_AGC_TUN_LEVEL 0x1a
80#define TDA1004X_SNR 0x1c
81#define TDA1004X_CONF_TS1 0x1e
82#define TDA1004X_CONF_TS2 0x1f
83#define TDA1004X_CBER_RESET 0x20
84#define TDA1004X_CBER_MSB 0x21
85#define TDA1004X_CBER_LSB 0x22
86#define TDA1004X_CVBER_LUT 0x23
87#define TDA1004X_VBER_MSB 0x24
88#define TDA1004X_VBER_MID 0x25
89#define TDA1004X_VBER_LSB 0x26
90#define TDA1004X_UNCOR 0x27
91
92#define TDA10045H_CONFPLL_P 0x2D
93#define TDA10045H_CONFPLL_M_MSB 0x2E
94#define TDA10045H_CONFPLL_M_LSB 0x2F
95#define TDA10045H_CONFPLL_N 0x30
96
97#define TDA10046H_CONFPLL1 0x2D
98#define TDA10046H_CONFPLL2 0x2F
99#define TDA10046H_CONFPLL3 0x30
100#define TDA10046H_TIME_WREF1 0x31
101#define TDA10046H_TIME_WREF2 0x32
102#define TDA10046H_TIME_WREF3 0x33
103#define TDA10046H_TIME_WREF4 0x34
104#define TDA10046H_TIME_WREF5 0x35
105
106#define TDA10045H_UNSURW_MSB 0x31
107#define TDA10045H_UNSURW_LSB 0x32
108#define TDA10045H_WREF_MSB 0x33
109#define TDA10045H_WREF_MID 0x34
110#define TDA10045H_WREF_LSB 0x35
111#define TDA10045H_MUXOUT 0x36
112#define TDA1004X_CONFADC2 0x37
113
114#define TDA10045H_IOFFSET 0x38
115
116#define TDA10046H_CONF_TRISTATE1 0x3B
117#define TDA10046H_CONF_TRISTATE2 0x3C
118#define TDA10046H_CONF_POLARITY 0x3D
119#define TDA10046H_FREQ_OFFSET 0x3E
120#define TDA10046H_GPIO_OUT_SEL 0x41
121#define TDA10046H_GPIO_SELECT 0x42
122#define TDA10046H_AGC_CONF 0x43
123#define TDA10046H_AGC_GAINS 0x46
124#define TDA10046H_AGC_TUN_MIN 0x47
125#define TDA10046H_AGC_TUN_MAX 0x48
126#define TDA10046H_AGC_IF_MIN 0x49
127#define TDA10046H_AGC_IF_MAX 0x4A
128
129#define TDA10046H_FREQ_PHY2_MSB 0x4D
130#define TDA10046H_FREQ_PHY2_LSB 0x4E
131
132#define TDA10046H_CVBER_CTRL 0x4F
133#define TDA10046H_AGC_IF_LEVEL 0x52
134#define TDA10046H_CODE_CPT 0x57
135#define TDA10046H_CODE_IN 0x58
136
137
138static int tda1004x_write_byteI(struct tda1004x_state *state, int reg, int data)
139{
140 int ret;
141 u8 buf[] = { reg, data };
142 struct i2c_msg msg = { .addr=0, .flags=0, .buf=buf, .len=2 };
143
144 dprintk("%s: reg=0x%x, data=0x%x\n", __FUNCTION__, reg, data);
145
146 msg.addr = state->config->demod_address;
147 ret = i2c_transfer(state->i2c, &msg, 1);
148
149 if (ret != 1)
150 dprintk("%s: error reg=0x%x, data=0x%x, ret=%i\n",
151 __FUNCTION__, reg, data, ret);
152
153 dprintk("%s: success reg=0x%x, data=0x%x, ret=%i\n", __FUNCTION__,
154 reg, data, ret);
155 return (ret != 1) ? -1 : 0;
156}
157
158static int tda1004x_read_byte(struct tda1004x_state *state, int reg)
159{
160 int ret;
161 u8 b0[] = { reg };
162 u8 b1[] = { 0 };
163 struct i2c_msg msg[] = {{ .addr=0, .flags=0, .buf=b0, .len=1},
164 { .addr=0, .flags=I2C_M_RD, .buf=b1, .len = 1}};
165
166 dprintk("%s: reg=0x%x\n", __FUNCTION__, reg);
167
168 msg[0].addr = state->config->demod_address;
169 msg[1].addr = state->config->demod_address;
170 ret = i2c_transfer(state->i2c, msg, 2);
171
172 if (ret != 2) {
173 dprintk("%s: error reg=0x%x, ret=%i\n", __FUNCTION__, reg,
174 ret);
175 return -1;
176 }
177
178 dprintk("%s: success reg=0x%x, data=0x%x, ret=%i\n", __FUNCTION__,
179 reg, b1[0], ret);
180 return b1[0];
181}
182
183static int tda1004x_write_mask(struct tda1004x_state *state, int reg, int mask, int data)
184{
185 int val;
186 dprintk("%s: reg=0x%x, mask=0x%x, data=0x%x\n", __FUNCTION__, reg,
187 mask, data);
188
189 // read a byte and check
190 val = tda1004x_read_byte(state, reg);
191 if (val < 0)
192 return val;
193
194 // mask if off
195 val = val & ~mask;
196 val |= data & 0xff;
197
198 // write it out again
199 return tda1004x_write_byteI(state, reg, val);
200}
201
202static int tda1004x_write_buf(struct tda1004x_state *state, int reg, unsigned char *buf, int len)
203{
204 int i;
205 int result;
206
207 dprintk("%s: reg=0x%x, len=0x%x\n", __FUNCTION__, reg, len);
208
209 result = 0;
210 for (i = 0; i < len; i++) {
211 result = tda1004x_write_byteI(state, reg + i, buf[i]);
212 if (result != 0)
213 break;
214 }
215
216 return result;
217}
218
219static int tda1004x_enable_tuner_i2c(struct tda1004x_state *state)
220{
221 int result;
222 dprintk("%s\n", __FUNCTION__);
223
224 result = tda1004x_write_mask(state, TDA1004X_CONFC4, 2, 2);
225 msleep(1);
226 return result;
227}
228
229static int tda1004x_disable_tuner_i2c(struct tda1004x_state *state)
230{
231 dprintk("%s\n", __FUNCTION__);
232
233 return tda1004x_write_mask(state, TDA1004X_CONFC4, 2, 0);
234}
235
236static int tda10045h_set_bandwidth(struct tda1004x_state *state,
237 fe_bandwidth_t bandwidth)
238{
239 static u8 bandwidth_6mhz[] = { 0x02, 0x00, 0x3d, 0x00, 0x60, 0x1e, 0xa7, 0x45, 0x4f };
240 static u8 bandwidth_7mhz[] = { 0x02, 0x00, 0x37, 0x00, 0x4a, 0x2f, 0x6d, 0x76, 0xdb };
241 static u8 bandwidth_8mhz[] = { 0x02, 0x00, 0x3d, 0x00, 0x48, 0x17, 0x89, 0xc7, 0x14 };
242
243 switch (bandwidth) {
244 case BANDWIDTH_6_MHZ:
245 tda1004x_write_buf(state, TDA10045H_CONFPLL_P, bandwidth_6mhz, sizeof(bandwidth_6mhz));
246 break;
247
248 case BANDWIDTH_7_MHZ:
249 tda1004x_write_buf(state, TDA10045H_CONFPLL_P, bandwidth_7mhz, sizeof(bandwidth_7mhz));
250 break;
251
252 case BANDWIDTH_8_MHZ:
253 tda1004x_write_buf(state, TDA10045H_CONFPLL_P, bandwidth_8mhz, sizeof(bandwidth_8mhz));
254 break;
255
256 default:
257 return -EINVAL;
258 }
259
260 tda1004x_write_byteI(state, TDA10045H_IOFFSET, 0);
261
262 return 0;
263}
264
265static int tda10046h_set_bandwidth(struct tda1004x_state *state,
266 fe_bandwidth_t bandwidth)
267{
268 static u8 bandwidth_6mhz[] = { 0x80, 0x15, 0xfe, 0xab, 0x8e };
269 static u8 bandwidth_7mhz[] = { 0x6e, 0x02, 0x53, 0xc8, 0x25 };
270 static u8 bandwidth_8mhz[] = { 0x60, 0x12, 0xa8, 0xe4, 0xbd };
271
272 switch (bandwidth) {
273 case BANDWIDTH_6_MHZ:
274 tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_6mhz, sizeof(bandwidth_6mhz));
275 break;
276
277 case BANDWIDTH_7_MHZ:
278 tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_7mhz, sizeof(bandwidth_7mhz));
279 break;
280
281 case BANDWIDTH_8_MHZ:
282 tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_8mhz, sizeof(bandwidth_8mhz));
283 break;
284
285 default:
286 return -EINVAL;
287 }
288
289 return 0;
290}
291
292static int tda1004x_do_upload(struct tda1004x_state *state,
293 unsigned char *mem, unsigned int len,
294 u8 dspCodeCounterReg, u8 dspCodeInReg)
295{
296 u8 buf[65];
297 struct i2c_msg fw_msg = {.addr = 0,.flags = 0,.buf = buf,.len = 0 };
298 int tx_size;
299 int pos = 0;
300
301 /* clear code counter */
302 tda1004x_write_byteI(state, dspCodeCounterReg, 0);
303 fw_msg.addr = state->config->demod_address;
304
305 buf[0] = dspCodeInReg;
306 while (pos != len) {
307
308 // work out how much to send this time
309 tx_size = len - pos;
310 if (tx_size > 0x10) {
311 tx_size = 0x10;
312 }
313
314 // send the chunk
315 memcpy(buf + 1, mem + pos, tx_size);
316 fw_msg.len = tx_size + 1;
317 if (i2c_transfer(state->i2c, &fw_msg, 1) != 1) {
318 printk("tda1004x: Error during firmware upload\n");
319 return -EIO;
320 }
321 pos += tx_size;
322
323 dprintk("%s: fw_pos=0x%x\n", __FUNCTION__, pos);
324 }
325 return 0;
326}
327
328static int tda1004x_check_upload_ok(struct tda1004x_state *state, u8 dspVersion)
329{
330 u8 data1, data2;
331
332 // check upload was OK
333 tda1004x_write_mask(state, TDA1004X_CONFC4, 0x10, 0); // we want to read from the DSP
334 tda1004x_write_byteI(state, TDA1004X_DSP_CMD, 0x67);
335
336 data1 = tda1004x_read_byte(state, TDA1004X_DSP_DATA1);
337 data2 = tda1004x_read_byte(state, TDA1004X_DSP_DATA2);
338 if (data1 != 0x67 || data2 != dspVersion) {
339 return -EIO;
340 }
341
342 return 0;
343}
344
345static int tda10045_fwupload(struct dvb_frontend* fe)
346{
347 struct tda1004x_state* state = fe->demodulator_priv;
348 int ret;
349 const struct firmware *fw;
350
351
352 /* don't re-upload unless necessary */
353 if (tda1004x_check_upload_ok(state, 0x2c) == 0) return 0;
354
355 /* request the firmware, this will block until someone uploads it */
356 printk("tda1004x: waiting for firmware upload (%s)...\n", TDA10045_DEFAULT_FIRMWARE);
357 ret = state->config->request_firmware(fe, &fw, TDA10045_DEFAULT_FIRMWARE);
358 if (ret) {
359 printk("tda1004x: no firmware upload (timeout or file not found?)\n");
360 return ret;
361 }
362
363 /* reset chip */
364 tda1004x_write_mask(state, TDA1004X_CONFC4, 0x10, 0);
365 tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8);
366 tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 0);
367 msleep(10);
368
369 /* set parameters */
370 tda10045h_set_bandwidth(state, BANDWIDTH_8_MHZ);
371
372 ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10045H_FWPAGE, TDA10045H_CODE_IN);
373 if (ret)
374 return ret;
375 printk("tda1004x: firmware upload complete\n");
376
377 /* wait for DSP to initialise */
378 /* DSPREADY doesn't seem to work on the TDA10045H */
379 msleep(100);
380
381 return tda1004x_check_upload_ok(state, 0x2c);
382}
383
384static int tda10046_fwupload(struct dvb_frontend* fe)
385{
386 struct tda1004x_state* state = fe->demodulator_priv;
387 unsigned long timeout;
388 int ret;
389 const struct firmware *fw;
390
391 /* reset + wake up chip */
392 tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 0);
393 tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0);
394 msleep(100);
395
396 /* don't re-upload unless necessary */
397 if (tda1004x_check_upload_ok(state, 0x20) == 0) return 0;
398
399 /* request the firmware, this will block until someone uploads it */
400 printk("tda1004x: waiting for firmware upload (%s)...\n", TDA10046_DEFAULT_FIRMWARE);
401 ret = state->config->request_firmware(fe, &fw, TDA10046_DEFAULT_FIRMWARE);
402 if (ret) {
403 printk("tda1004x: no firmware upload (timeout or file not found?)\n");
404 return ret;
405 }
406
407 /* set parameters */
408 tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 10);
409 tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0);
410 tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 99);
411 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4);
412 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x2c);
413 tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8); // going to boot from HOST
414
415 ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10046H_CODE_CPT, TDA10046H_CODE_IN);
416 if (ret)
417 return ret;
418 printk("tda1004x: firmware upload complete\n");
419
420 /* wait for DSP to initialise */
421 timeout = jiffies + HZ;
422 while(!(tda1004x_read_byte(state, TDA1004X_STATUS_CD) & 0x20)) {
423 if (time_after(jiffies, timeout)) {
424 printk("tda1004x: DSP failed to initialised.\n");
425 return -EIO;
426 }
427 msleep(1);
428 }
429
430 return tda1004x_check_upload_ok(state, 0x20);
431}
432
433static int tda1004x_encode_fec(int fec)
434{
435 // convert known FEC values
436 switch (fec) {
437 case FEC_1_2:
438 return 0;
439 case FEC_2_3:
440 return 1;
441 case FEC_3_4:
442 return 2;
443 case FEC_5_6:
444 return 3;
445 case FEC_7_8:
446 return 4;
447 }
448
449 // unsupported
450 return -EINVAL;
451}
452
453static int tda1004x_decode_fec(int tdafec)
454{
455 // convert known FEC values
456 switch (tdafec) {
457 case 0:
458 return FEC_1_2;
459 case 1:
460 return FEC_2_3;
461 case 2:
462 return FEC_3_4;
463 case 3:
464 return FEC_5_6;
465 case 4:
466 return FEC_7_8;
467 }
468
469 // unsupported
470 return -1;
471}
472
473int tda1004x_write_byte(struct dvb_frontend* fe, int reg, int data)
474{
475 struct tda1004x_state* state = fe->demodulator_priv;
476
477 return tda1004x_write_byteI(state, reg, data);
478}
479
480static int tda10045_init(struct dvb_frontend* fe)
481{
482 struct tda1004x_state* state = fe->demodulator_priv;
483
484 dprintk("%s\n", __FUNCTION__);
485
486 if (state->initialised) return 0;
487
488 if (tda10045_fwupload(fe)) {
489 printk("tda1004x: firmware upload failed\n");
490 return -EIO;
491 }
492
493 tda1004x_write_mask(state, TDA1004X_CONFADC1, 0x10, 0); // wake up the ADC
494
495 // Init the PLL
496 if (state->config->pll_init) {
497 tda1004x_enable_tuner_i2c(state);
498 state->config->pll_init(fe);
499 tda1004x_disable_tuner_i2c(state);
500 }
501
502 // tda setup
503 tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer
504 tda1004x_write_mask(state, TDA1004X_AUTO, 8, 0); // select HP stream
505 tda1004x_write_mask(state, TDA1004X_CONFC1, 0x40, 0); // set polarity of VAGC signal
506 tda1004x_write_mask(state, TDA1004X_CONFC1, 0x80, 0x80); // enable pulse killer
507 tda1004x_write_mask(state, TDA1004X_AUTO, 0x10, 0x10); // enable auto offset
508 tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0xC0, 0x0); // no frequency offset
509 tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 0); // setup MPEG2 TS interface
510 tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0); // setup MPEG2 TS interface
511 tda1004x_write_mask(state, TDA1004X_VBER_MSB, 0xe0, 0xa0); // 10^6 VBER measurement bits
512 tda1004x_write_mask(state, TDA1004X_CONFC1, 0x10, 0); // VAGC polarity
513 tda1004x_write_byteI(state, TDA1004X_CONFADC1, 0x2e);
514
515 tda1004x_write_mask(state, 0x1f, 0x01, state->config->invert_oclk);
516
517 state->initialised = 1;
518 return 0;
519}
520
521static int tda10046_init(struct dvb_frontend* fe)
522{
523 struct tda1004x_state* state = fe->demodulator_priv;
524 dprintk("%s\n", __FUNCTION__);
525
526 if (state->initialised) return 0;
527
528 if (tda10046_fwupload(fe)) {
529 printk("tda1004x: firmware upload failed\n");
530 return -EIO;
531 }
532
533 tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 0); // wake up the chip
534
535 // Init the PLL
536 if (state->config->pll_init) {
537 tda1004x_enable_tuner_i2c(state);
538 state->config->pll_init(fe);
539 tda1004x_disable_tuner_i2c(state);
540 }
541
542 // tda setup
543 tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer
544 tda1004x_write_mask(state, TDA1004X_CONFC1, 0x40, 0x40);
545 tda1004x_write_mask(state, TDA1004X_AUTO, 8, 0); // select HP stream
546 tda1004x_write_mask(state, TDA1004X_CONFC1, 0x80, 0); // disable pulse killer
547 tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 10); // PLL M = 10
548 tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0); // PLL P = N = 0
549 tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 99); // FREQOFFS = 99
550 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4); // } PHY2 = -11221
551 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x2c); // }
552 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0); // AGC setup
553 tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0x60, 0x60); // set AGC polarities
554 tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MIN, 0); // }
555 tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MAX, 0xff); // } AGC min/max values
556 tda1004x_write_byteI(state, TDA10046H_AGC_IF_MIN, 0); // }
557 tda1004x_write_byteI(state, TDA10046H_AGC_IF_MAX, 0xff); // }
558 tda1004x_write_mask(state, TDA10046H_CVBER_CTRL, 0x30, 0x10); // 10^6 VBER measurement bits
559 tda1004x_write_byteI(state, TDA10046H_AGC_GAINS, 1); // IF gain 2, TUN gain 1
560 tda1004x_write_mask(state, TDA1004X_AUTO, 0x80, 0); // crystal is 50ppm
561 tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config
562 tda1004x_write_mask(state, TDA1004X_CONF_TS2, 0x31, 0); // MPEG2 interface config
563 tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 0x9e, 0); // disable AGC_TUN
564 tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE2, 0xe1); // tristate setup
565 tda1004x_write_byteI(state, TDA10046H_GPIO_OUT_SEL, 0xcc); // GPIO output config
566 tda1004x_write_mask(state, TDA10046H_GPIO_SELECT, 8, 8); // GPIO select
567 tda10046h_set_bandwidth(state, BANDWIDTH_8_MHZ); // default bandwidth 8 MHz
568
569 tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7);
570
571 state->initialised = 1;
572 return 0;
573}
574
575static int tda1004x_set_fe(struct dvb_frontend* fe,
576 struct dvb_frontend_parameters *fe_params)
577{
578 struct tda1004x_state* state = fe->demodulator_priv;
579 int tmp;
580 int inversion;
581
582 dprintk("%s\n", __FUNCTION__);
583
584 if (state->demod_type == TDA1004X_DEMOD_TDA10046) {
585 // setup auto offset
586 tda1004x_write_mask(state, TDA1004X_AUTO, 0x10, 0x10);
587 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x80, 0);
588 tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0xC0, 0);
589
590 // disable agc_conf[2]
591 tda1004x_write_mask(state, TDA10046H_AGC_CONF, 4, 0);
592 }
593
594 // set frequency
595 tda1004x_enable_tuner_i2c(state);
596 state->config->pll_set(fe, fe_params);
597 tda1004x_disable_tuner_i2c(state);
598
599 if (state->demod_type == TDA1004X_DEMOD_TDA10046)
600 tda1004x_write_mask(state, TDA10046H_AGC_CONF, 4, 4);
601
602 // Hardcoded to use auto as much as possible on the TDA10045 as it
603 // is very unreliable if AUTO mode is _not_ used.
604 if (state->demod_type == TDA1004X_DEMOD_TDA10045) {
605 fe_params->u.ofdm.code_rate_HP = FEC_AUTO;
606 fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_AUTO;
607 fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO;
608 }
609
610 // Set standard params.. or put them to auto
611 if ((fe_params->u.ofdm.code_rate_HP == FEC_AUTO) ||
612 (fe_params->u.ofdm.code_rate_LP == FEC_AUTO) ||
613 (fe_params->u.ofdm.constellation == QAM_AUTO) ||
614 (fe_params->u.ofdm.hierarchy_information == HIERARCHY_AUTO)) {
615 tda1004x_write_mask(state, TDA1004X_AUTO, 1, 1); // enable auto
616 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x03, 0); // turn off constellation bits
617 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 0); // turn off hierarchy bits
618 tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0x3f, 0); // turn off FEC bits
619 } else {
620 tda1004x_write_mask(state, TDA1004X_AUTO, 1, 0); // disable auto
621
622 // set HP FEC
623 tmp = tda1004x_encode_fec(fe_params->u.ofdm.code_rate_HP);
624 if (tmp < 0) return tmp;
625 tda1004x_write_mask(state, TDA1004X_IN_CONF2, 7, tmp);
626
627 // set LP FEC
628 tmp = tda1004x_encode_fec(fe_params->u.ofdm.code_rate_LP);
629 if (tmp < 0) return tmp;
630 tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0x38, tmp << 3);
631
632 // set constellation
633 switch (fe_params->u.ofdm.constellation) {
634 case QPSK:
635 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 3, 0);
636 break;
637
638 case QAM_16:
639 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 3, 1);
640 break;
641
642 case QAM_64:
643 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 3, 2);
644 break;
645
646 default:
647 return -EINVAL;
648 }
649
650 // set hierarchy
651 switch (fe_params->u.ofdm.hierarchy_information) {
652 case HIERARCHY_NONE:
653 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 0 << 5);
654 break;
655
656 case HIERARCHY_1:
657 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 1 << 5);
658 break;
659
660 case HIERARCHY_2:
661 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 2 << 5);
662 break;
663
664 case HIERARCHY_4:
665 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 3 << 5);
666 break;
667
668 default:
669 return -EINVAL;
670 }
671 }
672
673 // set bandwidth
674 switch(state->demod_type) {
675 case TDA1004X_DEMOD_TDA10045:
676 tda10045h_set_bandwidth(state, fe_params->u.ofdm.bandwidth);
677 break;
678
679 case TDA1004X_DEMOD_TDA10046:
680 tda10046h_set_bandwidth(state, fe_params->u.ofdm.bandwidth);
681 break;
682 }
683
684 // set inversion
685 inversion = fe_params->inversion;
686 if (state->config->invert) inversion = inversion ? INVERSION_OFF : INVERSION_ON;
687 switch (inversion) {
688 case INVERSION_OFF:
689 tda1004x_write_mask(state, TDA1004X_CONFC1, 0x20, 0);
690 break;
691
692 case INVERSION_ON:
693 tda1004x_write_mask(state, TDA1004X_CONFC1, 0x20, 0x20);
694 break;
695
696 default:
697 return -EINVAL;
698 }
699
700 // set guard interval
701 switch (fe_params->u.ofdm.guard_interval) {
702 case GUARD_INTERVAL_1_32:
703 tda1004x_write_mask(state, TDA1004X_AUTO, 2, 0);
704 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 0 << 2);
705 break;
706
707 case GUARD_INTERVAL_1_16:
708 tda1004x_write_mask(state, TDA1004X_AUTO, 2, 0);
709 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 1 << 2);
710 break;
711
712 case GUARD_INTERVAL_1_8:
713 tda1004x_write_mask(state, TDA1004X_AUTO, 2, 0);
714 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 2 << 2);
715 break;
716
717 case GUARD_INTERVAL_1_4:
718 tda1004x_write_mask(state, TDA1004X_AUTO, 2, 0);
719 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 3 << 2);
720 break;
721
722 case GUARD_INTERVAL_AUTO:
723 tda1004x_write_mask(state, TDA1004X_AUTO, 2, 2);
724 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 0 << 2);
725 break;
726
727 default:
728 return -EINVAL;
729 }
730
731 // set transmission mode
732 switch (fe_params->u.ofdm.transmission_mode) {
733 case TRANSMISSION_MODE_2K:
734 tda1004x_write_mask(state, TDA1004X_AUTO, 4, 0);
735 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x10, 0 << 4);
736 break;
737
738 case TRANSMISSION_MODE_8K:
739 tda1004x_write_mask(state, TDA1004X_AUTO, 4, 0);
740 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x10, 1 << 4);
741 break;
742
743 case TRANSMISSION_MODE_AUTO:
744 tda1004x_write_mask(state, TDA1004X_AUTO, 4, 4);
745 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x10, 0);
746 break;
747
748 default:
749 return -EINVAL;
750 }
751
752 // start the lock
753 switch(state->demod_type) {
754 case TDA1004X_DEMOD_TDA10045:
755 tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8);
756 tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 0);
757 msleep(10);
758 break;
759
760 case TDA1004X_DEMOD_TDA10046:
761 tda1004x_write_mask(state, TDA1004X_AUTO, 0x40, 0x40);
762 msleep(10);
763 break;
764 }
765
766 return 0;
767}
768
769static int tda1004x_get_fe(struct dvb_frontend* fe, struct dvb_frontend_parameters *fe_params)
770{
771 struct tda1004x_state* state = fe->demodulator_priv;
772 dprintk("%s\n", __FUNCTION__);
773
774 // inversion status
775 fe_params->inversion = INVERSION_OFF;
776 if (tda1004x_read_byte(state, TDA1004X_CONFC1) & 0x20) {
777 fe_params->inversion = INVERSION_ON;
778 }
779 if (state->config->invert) fe_params->inversion = fe_params->inversion ? INVERSION_OFF : INVERSION_ON;
780
781 // bandwidth
782 switch(state->demod_type) {
783 case TDA1004X_DEMOD_TDA10045:
784 switch (tda1004x_read_byte(state, TDA10045H_WREF_LSB)) {
785 case 0x14:
786 fe_params->u.ofdm.bandwidth = BANDWIDTH_8_MHZ;
787 break;
788 case 0xdb:
789 fe_params->u.ofdm.bandwidth = BANDWIDTH_7_MHZ;
790 break;
791 case 0x4f:
792 fe_params->u.ofdm.bandwidth = BANDWIDTH_6_MHZ;
793 break;
794 }
795 break;
796
797 case TDA1004X_DEMOD_TDA10046:
798 switch (tda1004x_read_byte(state, TDA10046H_TIME_WREF1)) {
799 case 0x60:
800 fe_params->u.ofdm.bandwidth = BANDWIDTH_8_MHZ;
801 break;
802 case 0x6e:
803 fe_params->u.ofdm.bandwidth = BANDWIDTH_7_MHZ;
804 break;
805 case 0x80:
806 fe_params->u.ofdm.bandwidth = BANDWIDTH_6_MHZ;
807 break;
808 }
809 break;
810 }
811
812 // FEC
813 fe_params->u.ofdm.code_rate_HP =
814 tda1004x_decode_fec(tda1004x_read_byte(state, TDA1004X_OUT_CONF2) & 7);
815 fe_params->u.ofdm.code_rate_LP =
816 tda1004x_decode_fec((tda1004x_read_byte(state, TDA1004X_OUT_CONF2) >> 3) & 7);
817
818 // constellation
819 switch (tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 3) {
820 case 0:
821 fe_params->u.ofdm.constellation = QPSK;
822 break;
823 case 1:
824 fe_params->u.ofdm.constellation = QAM_16;
825 break;
826 case 2:
827 fe_params->u.ofdm.constellation = QAM_64;
828 break;
829 }
830
831 // transmission mode
832 fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K;
833 if (tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x10) {
834 fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
835 }
836
837 // guard interval
838 switch ((tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x0c) >> 2) {
839 case 0:
840 fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
841 break;
842 case 1:
843 fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_1_16;
844 break;
845 case 2:
846 fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_1_8;
847 break;
848 case 3:
849 fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_1_4;
850 break;
851 }
852
853 // hierarchy
854 switch ((tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x60) >> 5) {
855 case 0:
856 fe_params->u.ofdm.hierarchy_information = HIERARCHY_NONE;
857 break;
858 case 1:
859 fe_params->u.ofdm.hierarchy_information = HIERARCHY_1;
860 break;
861 case 2:
862 fe_params->u.ofdm.hierarchy_information = HIERARCHY_2;
863 break;
864 case 3:
865 fe_params->u.ofdm.hierarchy_information = HIERARCHY_4;
866 break;
867 }
868
869 return 0;
870}
871
872static int tda1004x_read_status(struct dvb_frontend* fe, fe_status_t * fe_status)
873{
874 struct tda1004x_state* state = fe->demodulator_priv;
875 int status;
876 int cber;
877 int vber;
878
879 dprintk("%s\n", __FUNCTION__);
880
881 // read status
882 status = tda1004x_read_byte(state, TDA1004X_STATUS_CD);
883 if (status == -1) {
884 return -EIO;
885 }
886
887 // decode
888 *fe_status = 0;
889 if (status & 4) *fe_status |= FE_HAS_SIGNAL;
890 if (status & 2) *fe_status |= FE_HAS_CARRIER;
891 if (status & 8) *fe_status |= FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
892
893 // if we don't already have VITERBI (i.e. not LOCKED), see if the viterbi
894 // is getting anything valid
895 if (!(*fe_status & FE_HAS_VITERBI)) {
896 // read the CBER
897 cber = tda1004x_read_byte(state, TDA1004X_CBER_LSB);
898 if (cber == -1) return -EIO;
899 status = tda1004x_read_byte(state, TDA1004X_CBER_MSB);
900 if (status == -1) return -EIO;
901 cber |= (status << 8);
902 tda1004x_read_byte(state, TDA1004X_CBER_RESET);
903
904 if (cber != 65535) {
905 *fe_status |= FE_HAS_VITERBI;
906 }
907 }
908
909 // if we DO have some valid VITERBI output, but don't already have SYNC
910 // bytes (i.e. not LOCKED), see if the RS decoder is getting anything valid.
911 if ((*fe_status & FE_HAS_VITERBI) && (!(*fe_status & FE_HAS_SYNC))) {
912 // read the VBER
913 vber = tda1004x_read_byte(state, TDA1004X_VBER_LSB);
914 if (vber == -1) return -EIO;
915 status = tda1004x_read_byte(state, TDA1004X_VBER_MID);
916 if (status == -1) return -EIO;
917 vber |= (status << 8);
918 status = tda1004x_read_byte(state, TDA1004X_VBER_MSB);
919 if (status == -1) return -EIO;
920 vber |= ((status << 16) & 0x0f);
921 tda1004x_read_byte(state, TDA1004X_CVBER_LUT);
922
923 // if RS has passed some valid TS packets, then we must be
924 // getting some SYNC bytes
925 if (vber < 16632) {
926 *fe_status |= FE_HAS_SYNC;
927 }
928 }
929
930 // success
931 dprintk("%s: fe_status=0x%x\n", __FUNCTION__, *fe_status);
932 return 0;
933}
934
935static int tda1004x_read_signal_strength(struct dvb_frontend* fe, u16 * signal)
936{
937 struct tda1004x_state* state = fe->demodulator_priv;
938 int tmp;
939 int reg = 0;
940
941 dprintk("%s\n", __FUNCTION__);
942
943 // determine the register to use
944 switch(state->demod_type) {
945 case TDA1004X_DEMOD_TDA10045:
946 reg = TDA10045H_S_AGC;
947 break;
948
949 case TDA1004X_DEMOD_TDA10046:
950 reg = TDA10046H_AGC_IF_LEVEL;
951 break;
952 }
953
954 // read it
955 tmp = tda1004x_read_byte(state, reg);
956 if (tmp < 0)
957 return -EIO;
958
959 *signal = (tmp << 8) | tmp;
960 dprintk("%s: signal=0x%x\n", __FUNCTION__, *signal);
961 return 0;
962}
963
964static int tda1004x_read_snr(struct dvb_frontend* fe, u16 * snr)
965{
966 struct tda1004x_state* state = fe->demodulator_priv;
967 int tmp;
968
969 dprintk("%s\n", __FUNCTION__);
970
971 // read it
972 tmp = tda1004x_read_byte(state, TDA1004X_SNR);
973 if (tmp < 0)
974 return -EIO;
975 if (tmp) {
976 tmp = 255 - tmp;
977 }
978
979 *snr = ((tmp << 8) | tmp);
980 dprintk("%s: snr=0x%x\n", __FUNCTION__, *snr);
981 return 0;
982}
983
984static int tda1004x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
985{
986 struct tda1004x_state* state = fe->demodulator_priv;
987 int tmp;
988 int tmp2;
989 int counter;
990
991 dprintk("%s\n", __FUNCTION__);
992
993 // read the UCBLOCKS and reset
994 counter = 0;
995 tmp = tda1004x_read_byte(state, TDA1004X_UNCOR);
996 if (tmp < 0)
997 return -EIO;
998 tmp &= 0x7f;
999 while (counter++ < 5) {
1000 tda1004x_write_mask(state, TDA1004X_UNCOR, 0x80, 0);
1001 tda1004x_write_mask(state, TDA1004X_UNCOR, 0x80, 0);
1002 tda1004x_write_mask(state, TDA1004X_UNCOR, 0x80, 0);
1003
1004 tmp2 = tda1004x_read_byte(state, TDA1004X_UNCOR);
1005 if (tmp2 < 0)
1006 return -EIO;
1007 tmp2 &= 0x7f;
1008 if ((tmp2 < tmp) || (tmp2 == 0))
1009 break;
1010 }
1011
1012 if (tmp != 0x7f) {
1013 *ucblocks = tmp;
1014 } else {
1015 *ucblocks = 0xffffffff;
1016 }
1017 dprintk("%s: ucblocks=0x%x\n", __FUNCTION__, *ucblocks);
1018 return 0;
1019}
1020
1021static int tda1004x_read_ber(struct dvb_frontend* fe, u32* ber)
1022{
1023 struct tda1004x_state* state = fe->demodulator_priv;
1024 int tmp;
1025
1026 dprintk("%s\n", __FUNCTION__);
1027
1028 // read it in
1029 tmp = tda1004x_read_byte(state, TDA1004X_CBER_LSB);
1030 if (tmp < 0) return -EIO;
1031 *ber = tmp << 1;
1032 tmp = tda1004x_read_byte(state, TDA1004X_CBER_MSB);
1033 if (tmp < 0) return -EIO;
1034 *ber |= (tmp << 9);
1035 tda1004x_read_byte(state, TDA1004X_CBER_RESET);
1036
1037 dprintk("%s: ber=0x%x\n", __FUNCTION__, *ber);
1038 return 0;
1039}
1040
1041static int tda1004x_sleep(struct dvb_frontend* fe)
1042{
1043 struct tda1004x_state* state = fe->demodulator_priv;
1044
1045 switch(state->demod_type) {
1046 case TDA1004X_DEMOD_TDA10045:
1047 tda1004x_write_mask(state, TDA1004X_CONFADC1, 0x10, 0x10);
1048 break;
1049
1050 case TDA1004X_DEMOD_TDA10046:
1051 tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1);
1052 break;
1053 }
1054 state->initialised = 0;
1055
1056 return 0;
1057}
1058
1059static int tda1004x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
1060{
1061 fesettings->min_delay_ms = 800;
1062 fesettings->step_size = 166667;
1063 fesettings->max_drift = 166667*2;
1064 return 0;
1065}
1066
1067static void tda1004x_release(struct dvb_frontend* fe)
1068{
1069 struct tda1004x_state* state = (struct tda1004x_state*) fe->demodulator_priv;
1070 kfree(state);
1071}
1072
1073static struct dvb_frontend_ops tda10045_ops;
1074
1075struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config,
1076 struct i2c_adapter* i2c)
1077{
1078 struct tda1004x_state* state = NULL;
1079
1080 /* allocate memory for the internal state */
1081 state = (struct tda1004x_state*) kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL);
1082 if (state == NULL) goto error;
1083
1084 /* setup the state */
1085 state->config = config;
1086 state->i2c = i2c;
1087 memcpy(&state->ops, &tda10045_ops, sizeof(struct dvb_frontend_ops));
1088 state->initialised = 0;
1089 state->demod_type = TDA1004X_DEMOD_TDA10045;
1090
1091 /* check if the demod is there */
1092 if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x25) goto error;
1093
1094 /* create dvb_frontend */
1095 state->frontend.ops = &state->ops;
1096 state->frontend.demodulator_priv = state;
1097 return &state->frontend;
1098
1099error:
1100 kfree(state);
1101 return NULL;
1102}
1103
1104static struct dvb_frontend_ops tda10046_ops;
1105
1106struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config,
1107 struct i2c_adapter* i2c)
1108{
1109 struct tda1004x_state* state = NULL;
1110
1111 /* allocate memory for the internal state */
1112 state = (struct tda1004x_state*) kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL);
1113 if (state == NULL) goto error;
1114
1115 /* setup the state */
1116 state->config = config;
1117 state->i2c = i2c;
1118 memcpy(&state->ops, &tda10046_ops, sizeof(struct dvb_frontend_ops));
1119 state->initialised = 0;
1120 state->demod_type = TDA1004X_DEMOD_TDA10046;
1121
1122 /* check if the demod is there */
1123 if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x46) goto error;
1124
1125 /* create dvb_frontend */
1126 state->frontend.ops = &state->ops;
1127 state->frontend.demodulator_priv = state;
1128 return &state->frontend;
1129
1130error:
1131 if (state) kfree(state);
1132 return NULL;
1133}
1134
1135static struct dvb_frontend_ops tda10045_ops = {
1136
1137 .info = {
1138 .name = "Philips TDA10045H DVB-T",
1139 .type = FE_OFDM,
1140 .frequency_min = 51000000,
1141 .frequency_max = 858000000,
1142 .frequency_stepsize = 166667,
1143 .caps =
1144 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1145 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1146 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
1147 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO
1148 },
1149
1150 .release = tda1004x_release,
1151
1152 .init = tda10045_init,
1153 .sleep = tda1004x_sleep,
1154
1155 .set_frontend = tda1004x_set_fe,
1156 .get_frontend = tda1004x_get_fe,
1157 .get_tune_settings = tda1004x_get_tune_settings,
1158
1159 .read_status = tda1004x_read_status,
1160 .read_ber = tda1004x_read_ber,
1161 .read_signal_strength = tda1004x_read_signal_strength,
1162 .read_snr = tda1004x_read_snr,
1163 .read_ucblocks = tda1004x_read_ucblocks,
1164};
1165
1166static struct dvb_frontend_ops tda10046_ops = {
1167
1168 .info = {
1169 .name = "Philips TDA10046H DVB-T",
1170 .type = FE_OFDM,
1171 .frequency_min = 51000000,
1172 .frequency_max = 858000000,
1173 .frequency_stepsize = 166667,
1174 .caps =
1175 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1176 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1177 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
1178 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO
1179 },
1180
1181 .release = tda1004x_release,
1182
1183 .init = tda10046_init,
1184 .sleep = tda1004x_sleep,
1185
1186 .set_frontend = tda1004x_set_fe,
1187 .get_frontend = tda1004x_get_fe,
1188 .get_tune_settings = tda1004x_get_tune_settings,
1189
1190 .read_status = tda1004x_read_status,
1191 .read_ber = tda1004x_read_ber,
1192 .read_signal_strength = tda1004x_read_signal_strength,
1193 .read_snr = tda1004x_read_snr,
1194 .read_ucblocks = tda1004x_read_ucblocks,
1195};
1196
1197module_param(debug, int, 0644);
1198MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
1199
1200MODULE_DESCRIPTION("Philips TDA10045H & TDA10046H DVB-T Demodulator");
1201MODULE_AUTHOR("Andrew de Quincey & Robert Schlabbach");
1202MODULE_LICENSE("GPL");
1203
1204EXPORT_SYMBOL(tda10045_attach);
1205EXPORT_SYMBOL(tda10046_attach);
1206EXPORT_SYMBOL(tda1004x_write_byte);
diff --git a/drivers/media/dvb/frontends/tda1004x.h b/drivers/media/dvb/frontends/tda1004x.h
new file mode 100644
index 000000000000..e452fc0bad11
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda1004x.h
@@ -0,0 +1,56 @@
1 /*
2 Driver for Philips tda1004xh OFDM Frontend
3
4 (c) 2004 Andrew de Quincey
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 */
22
23#ifndef TDA1004X_H
24#define TDA1004X_H
25
26#include <linux/dvb/frontend.h>
27#include <linux/firmware.h>
28
29struct tda1004x_config
30{
31 /* the demodulator's i2c address */
32 u8 demod_address;
33
34 /* does the "inversion" need inverted? */
35 u8 invert:1;
36
37 /* Does the OCLK signal need inverted? */
38 u8 invert_oclk:1;
39
40 /* PLL maintenance */
41 int (*pll_init)(struct dvb_frontend* fe);
42 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
43
44 /* request firmware for device */
45 int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
46};
47
48extern struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config,
49 struct i2c_adapter* i2c);
50
51extern struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config,
52 struct i2c_adapter* i2c);
53
54extern int tda1004x_write_byte(struct dvb_frontend* fe, int reg, int data);
55
56#endif // TDA1004X_H
diff --git a/drivers/media/dvb/frontends/tda8083.c b/drivers/media/dvb/frontends/tda8083.c
new file mode 100644
index 000000000000..da82e90d6d13
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda8083.c
@@ -0,0 +1,456 @@
1/*
2 Driver for Philips TDA8083 based QPSK Demodulator
3
4 Copyright (C) 2001 Convergence Integrated Media GmbH
5
6 written by Ralph Metzler <ralph@convergence.de>
7
8 adoption to the new DVB frontend API and diagnostic ioctl's
9 by Holger Waechtler <holger@convergence.de>
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24
25*/
26
27#include <linux/init.h>
28#include <linux/kernel.h>
29#include <linux/module.h>
30#include <linux/moduleparam.h>
31#include <linux/string.h>
32#include <linux/slab.h>
33#include "dvb_frontend.h"
34#include "tda8083.h"
35
36
37struct tda8083_state {
38 struct i2c_adapter* i2c;
39 struct dvb_frontend_ops ops;
40 /* configuration settings */
41 const struct tda8083_config* config;
42 struct dvb_frontend frontend;
43};
44
45static int debug;
46#define dprintk(args...) \
47 do { \
48 if (debug) printk(KERN_DEBUG "tda8083: " args); \
49 } while (0)
50
51
52static u8 tda8083_init_tab [] = {
53 0x04, 0x00, 0x4a, 0x79, 0x04, 0x00, 0xff, 0xea,
54 0x48, 0x42, 0x79, 0x60, 0x70, 0x52, 0x9a, 0x10,
55 0x0e, 0x10, 0xf2, 0xa7, 0x93, 0x0b, 0x05, 0xc8,
56 0x9d, 0x00, 0x42, 0x80, 0x00, 0x60, 0x40, 0x00,
57 0x00, 0x75, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00,
58 0x00, 0x00, 0x00, 0x00
59};
60
61
62static int tda8083_writereg (struct tda8083_state* state, u8 reg, u8 data)
63{
64 int ret;
65 u8 buf [] = { reg, data };
66 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
67
68 ret = i2c_transfer(state->i2c, &msg, 1);
69
70 if (ret != 1)
71 dprintk ("%s: writereg error (reg %02x, ret == %i)\n",
72 __FUNCTION__, reg, ret);
73
74 return (ret != 1) ? -1 : 0;
75}
76
77static int tda8083_readregs (struct tda8083_state* state, u8 reg1, u8 *b, u8 len)
78{
79 int ret;
80 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = &reg1, .len = 1 },
81 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b, .len = len } };
82
83 ret = i2c_transfer(state->i2c, msg, 2);
84
85 if (ret != 2)
86 dprintk ("%s: readreg error (reg %02x, ret == %i)\n",
87 __FUNCTION__, reg1, ret);
88
89 return ret == 2 ? 0 : -1;
90}
91
92static inline u8 tda8083_readreg (struct tda8083_state* state, u8 reg)
93{
94 u8 val;
95
96 tda8083_readregs (state, reg, &val, 1);
97
98 return val;
99}
100
101static int tda8083_set_inversion (struct tda8083_state* state, fe_spectral_inversion_t inversion)
102{
103 /* XXX FIXME: implement other modes than FEC_AUTO */
104 if (inversion == INVERSION_AUTO)
105 return 0;
106
107 return -EINVAL;
108}
109
110static int tda8083_set_fec (struct tda8083_state* state, fe_code_rate_t fec)
111{
112 if (fec == FEC_AUTO)
113 return tda8083_writereg (state, 0x07, 0xff);
114
115 if (fec >= FEC_1_2 && fec <= FEC_8_9)
116 return tda8083_writereg (state, 0x07, 1 << (FEC_8_9 - fec));
117
118 return -EINVAL;
119}
120
121static fe_code_rate_t tda8083_get_fec (struct tda8083_state* state)
122{
123 u8 index;
124 static fe_code_rate_t fec_tab [] = { FEC_8_9, FEC_1_2, FEC_2_3, FEC_3_4,
125 FEC_4_5, FEC_5_6, FEC_6_7, FEC_7_8 };
126
127 index = tda8083_readreg(state, 0x0e) & 0x07;
128
129 return fec_tab [index];
130}
131
132static int tda8083_set_symbolrate (struct tda8083_state* state, u32 srate)
133{
134 u32 ratio;
135 u32 tmp;
136 u8 filter;
137
138 if (srate > 32000000)
139 srate = 32000000;
140 if (srate < 500000)
141 srate = 500000;
142
143 filter = 0;
144 if (srate < 24000000)
145 filter = 2;
146 if (srate < 16000000)
147 filter = 3;
148
149 tmp = 31250 << 16;
150 ratio = tmp / srate;
151
152 tmp = (tmp % srate) << 8;
153 ratio = (ratio << 8) + tmp / srate;
154
155 tmp = (tmp % srate) << 8;
156 ratio = (ratio << 8) + tmp / srate;
157
158 dprintk("tda8083: ratio == %08x\n", (unsigned int) ratio);
159
160 tda8083_writereg (state, 0x05, filter);
161 tda8083_writereg (state, 0x02, (ratio >> 16) & 0xff);
162 tda8083_writereg (state, 0x03, (ratio >> 8) & 0xff);
163 tda8083_writereg (state, 0x04, (ratio ) & 0xff);
164
165 tda8083_writereg (state, 0x00, 0x3c);
166 tda8083_writereg (state, 0x00, 0x04);
167
168 return 1;
169}
170
171static void tda8083_wait_diseqc_fifo (struct tda8083_state* state, int timeout)
172{
173 unsigned long start = jiffies;
174
175 while (jiffies - start < timeout &&
176 !(tda8083_readreg(state, 0x02) & 0x80))
177 {
178 msleep(50);
179 };
180}
181
182static int tda8083_set_tone (struct tda8083_state* state, fe_sec_tone_mode_t tone)
183{
184 tda8083_writereg (state, 0x26, 0xf1);
185
186 switch (tone) {
187 case SEC_TONE_OFF:
188 return tda8083_writereg (state, 0x29, 0x00);
189 case SEC_TONE_ON:
190 return tda8083_writereg (state, 0x29, 0x80);
191 default:
192 return -EINVAL;
193 };
194}
195
196static int tda8083_set_voltage (struct tda8083_state* state, fe_sec_voltage_t voltage)
197{
198 switch (voltage) {
199 case SEC_VOLTAGE_13:
200 return tda8083_writereg (state, 0x20, 0x00);
201 case SEC_VOLTAGE_18:
202 return tda8083_writereg (state, 0x20, 0x11);
203 default:
204 return -EINVAL;
205 };
206}
207
208static int tda8083_send_diseqc_burst (struct tda8083_state* state, fe_sec_mini_cmd_t burst)
209{
210 switch (burst) {
211 case SEC_MINI_A:
212 tda8083_writereg (state, 0x29, (5 << 2)); /* send burst A */
213 break;
214 case SEC_MINI_B:
215 tda8083_writereg (state, 0x29, (7 << 2)); /* send B */
216 break;
217 default:
218 return -EINVAL;
219 };
220
221 tda8083_wait_diseqc_fifo (state, 100);
222
223 return 0;
224}
225
226static int tda8083_send_diseqc_msg (struct dvb_frontend* fe,
227 struct dvb_diseqc_master_cmd *m)
228{
229 struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
230 int i;
231
232 tda8083_writereg (state, 0x29, (m->msg_len - 3) | (1 << 2)); /* enable */
233
234 for (i=0; i<m->msg_len; i++)
235 tda8083_writereg (state, 0x23 + i, m->msg[i]);
236
237 tda8083_writereg (state, 0x29, (m->msg_len - 3) | (3 << 2)); /* send!! */
238
239 tda8083_wait_diseqc_fifo (state, 100);
240
241 return 0;
242}
243
244static int tda8083_read_status(struct dvb_frontend* fe, fe_status_t* status)
245{
246 struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
247
248 u8 signal = ~tda8083_readreg (state, 0x01);
249 u8 sync = tda8083_readreg (state, 0x02);
250
251 *status = 0;
252
253 if (signal > 10)
254 *status |= FE_HAS_SIGNAL;
255
256 if (sync & 0x01)
257 *status |= FE_HAS_CARRIER;
258
259 if (sync & 0x02)
260 *status |= FE_HAS_VITERBI;
261
262 if (sync & 0x10)
263 *status |= FE_HAS_SYNC;
264
265 if ((sync & 0x1f) == 0x1f)
266 *status |= FE_HAS_LOCK;
267
268 return 0;
269}
270
271static int tda8083_read_signal_strength(struct dvb_frontend* fe, u16* strength)
272{
273 struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
274
275 u8 signal = ~tda8083_readreg (state, 0x01);
276 *strength = (signal << 8) | signal;
277
278 return 0;
279}
280
281static int tda8083_read_snr(struct dvb_frontend* fe, u16* snr)
282{
283 struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
284
285 u8 _snr = tda8083_readreg (state, 0x08);
286 *snr = (_snr << 8) | _snr;
287
288 return 0;
289}
290
291static int tda8083_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
292{
293 struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
294
295 state->config->pll_set(fe, p);
296 tda8083_set_inversion (state, p->inversion);
297 tda8083_set_fec (state, p->u.qpsk.fec_inner);
298 tda8083_set_symbolrate (state, p->u.qpsk.symbol_rate);
299
300 tda8083_writereg (state, 0x00, 0x3c);
301 tda8083_writereg (state, 0x00, 0x04);
302
303 return 0;
304}
305
306static int tda8083_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
307{
308 struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
309
310 /* FIXME: get symbolrate & frequency offset...*/
311 /*p->frequency = ???;*/
312 p->inversion = (tda8083_readreg (state, 0x0e) & 0x80) ?
313 INVERSION_ON : INVERSION_OFF;
314 p->u.qpsk.fec_inner = tda8083_get_fec (state);
315 /*p->u.qpsk.symbol_rate = tda8083_get_symbolrate (state);*/
316
317 return 0;
318}
319
320static int tda8083_sleep(struct dvb_frontend* fe)
321{
322 struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
323
324 tda8083_writereg (state, 0x00, 0x02);
325 return 0;
326}
327
328static int tda8083_init(struct dvb_frontend* fe)
329{
330 struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
331 int i;
332
333 for (i=0; i<44; i++)
334 tda8083_writereg (state, i, tda8083_init_tab[i]);
335
336 if (state->config->pll_init) state->config->pll_init(fe);
337
338 tda8083_writereg (state, 0x00, 0x3c);
339 tda8083_writereg (state, 0x00, 0x04);
340
341 return 0;
342}
343
344static int tda8083_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
345{
346 struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
347
348 tda8083_send_diseqc_burst (state, burst);
349 tda8083_writereg (state, 0x00, 0x3c);
350 tda8083_writereg (state, 0x00, 0x04);
351
352 return 0;
353}
354
355static int tda8083_diseqc_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
356{
357 struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
358
359 tda8083_set_tone (state, tone);
360 tda8083_writereg (state, 0x00, 0x3c);
361 tda8083_writereg (state, 0x00, 0x04);
362
363 return 0;
364}
365
366static int tda8083_diseqc_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
367{
368 struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
369
370 tda8083_set_voltage (state, voltage);
371 tda8083_writereg (state, 0x00, 0x3c);
372 tda8083_writereg (state, 0x00, 0x04);
373
374 return 0;
375}
376
377static void tda8083_release(struct dvb_frontend* fe)
378{
379 struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
380 kfree(state);
381}
382
383static struct dvb_frontend_ops tda8083_ops;
384
385struct dvb_frontend* tda8083_attach(const struct tda8083_config* config,
386 struct i2c_adapter* i2c)
387{
388 struct tda8083_state* state = NULL;
389
390 /* allocate memory for the internal state */
391 state = (struct tda8083_state*) kmalloc(sizeof(struct tda8083_state), GFP_KERNEL);
392 if (state == NULL) goto error;
393
394 /* setup the state */
395 state->config = config;
396 state->i2c = i2c;
397 memcpy(&state->ops, &tda8083_ops, sizeof(struct dvb_frontend_ops));
398
399 /* check if the demod is there */
400 if ((tda8083_readreg(state, 0x00)) != 0x05) goto error;
401
402 /* create dvb_frontend */
403 state->frontend.ops = &state->ops;
404 state->frontend.demodulator_priv = state;
405 return &state->frontend;
406
407error:
408 kfree(state);
409 return NULL;
410}
411
412static struct dvb_frontend_ops tda8083_ops = {
413
414 .info = {
415 .name = "Philips TDA8083 DVB-S",
416 .type = FE_QPSK,
417 .frequency_min = 950000, /* FIXME: guessed! */
418 .frequency_max = 1400000, /* FIXME: guessed! */
419 .frequency_stepsize = 125, /* kHz for QPSK frontends */
420 /* .frequency_tolerance = ???,*/
421 .symbol_rate_min = 1000000, /* FIXME: guessed! */
422 .symbol_rate_max = 45000000, /* FIXME: guessed! */
423 /* .symbol_rate_tolerance = ???,*/
424 .caps = FE_CAN_INVERSION_AUTO |
425 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
426 FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
427 FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
428 FE_CAN_QPSK | FE_CAN_MUTE_TS
429 },
430
431 .release = tda8083_release,
432
433 .init = tda8083_init,
434 .sleep = tda8083_sleep,
435
436 .set_frontend = tda8083_set_frontend,
437 .get_frontend = tda8083_get_frontend,
438
439 .read_status = tda8083_read_status,
440 .read_signal_strength = tda8083_read_signal_strength,
441 .read_snr = tda8083_read_snr,
442
443 .diseqc_send_master_cmd = tda8083_send_diseqc_msg,
444 .diseqc_send_burst = tda8083_diseqc_send_burst,
445 .set_tone = tda8083_diseqc_set_tone,
446 .set_voltage = tda8083_diseqc_set_voltage,
447};
448
449module_param(debug, int, 0644);
450MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
451
452MODULE_DESCRIPTION("Philips TDA8083 DVB-S Demodulator");
453MODULE_AUTHOR("Ralph Metzler, Holger Waechtler");
454MODULE_LICENSE("GPL");
455
456EXPORT_SYMBOL(tda8083_attach);
diff --git a/drivers/media/dvb/frontends/tda8083.h b/drivers/media/dvb/frontends/tda8083.h
new file mode 100644
index 000000000000..466663307bf1
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda8083.h
@@ -0,0 +1,45 @@
1/*
2 Driver for Grundig 29504-491, a Philips TDA8083 based QPSK Frontend
3
4 Copyright (C) 2001 Convergence Integrated Media GmbH
5
6 written by Ralph Metzler <ralph@convergence.de>
7
8 adoption to the new DVB frontend API and diagnostic ioctl's
9 by Holger Waechtler <holger@convergence.de>
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24
25*/
26
27#ifndef TDA8083_H
28#define TDA8083_H
29
30#include <linux/dvb/frontend.h>
31
32struct tda8083_config
33{
34 /* the demodulator's i2c address */
35 u8 demod_address;
36
37 /* PLL maintenance */
38 int (*pll_init)(struct dvb_frontend* fe);
39 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
40};
41
42extern struct dvb_frontend* tda8083_attach(const struct tda8083_config* config,
43 struct i2c_adapter* i2c);
44
45#endif // TDA8083_H
diff --git a/drivers/media/dvb/frontends/tda80xx.c b/drivers/media/dvb/frontends/tda80xx.c
new file mode 100644
index 000000000000..c99632114283
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda80xx.c
@@ -0,0 +1,734 @@
1/*
2 * tda80xx.c
3 *
4 * Philips TDA8044 / TDA8083 QPSK demodulator driver
5 *
6 * Copyright (C) 2001 Felix Domke <tmbinc@elitedvb.net>
7 * Copyright (C) 2002-2004 Andreas Oberritter <obi@linuxtv.org>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/config.h>
25#include <linux/delay.h>
26#include <linux/init.h>
27#include <linux/spinlock.h>
28#include <linux/threads.h>
29#include <linux/interrupt.h>
30#include <asm/irq.h>
31#include <linux/kernel.h>
32#include <linux/module.h>
33#include <linux/slab.h>
34#include <asm/div64.h>
35
36#include "dvb_frontend.h"
37#include "tda80xx.h"
38
39enum {
40 ID_TDA8044 = 0x04,
41 ID_TDA8083 = 0x05,
42};
43
44
45struct tda80xx_state {
46
47 struct i2c_adapter* i2c;
48
49 struct dvb_frontend_ops ops;
50
51 /* configuration settings */
52 const struct tda80xx_config* config;
53
54 struct dvb_frontend frontend;
55
56 u32 clk;
57 int afc_loop;
58 struct work_struct worklet;
59 fe_code_rate_t code_rate;
60 fe_spectral_inversion_t spectral_inversion;
61 fe_status_t status;
62 u8 id;
63};
64
65static int debug = 1;
66#define dprintk if (debug) printk
67
68static u8 tda8044_inittab_pre[] = {
69 0x02, 0x00, 0x6f, 0xb5, 0x86, 0x22, 0x00, 0xea,
70 0x30, 0x42, 0x98, 0x68, 0x70, 0x42, 0x99, 0x58,
71 0x95, 0x10, 0xf5, 0xe7, 0x93, 0x0b, 0x15, 0x68,
72 0x9a, 0x90, 0x61, 0x80, 0x00, 0xe0, 0x40, 0x00,
73 0x0f, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
74 0x00, 0x00
75};
76
77static u8 tda8044_inittab_post[] = {
78 0x04, 0x00, 0x6f, 0xb5, 0x86, 0x22, 0x00, 0xea,
79 0x30, 0x42, 0x98, 0x68, 0x70, 0x42, 0x99, 0x50,
80 0x95, 0x10, 0xf5, 0xe7, 0x93, 0x0b, 0x15, 0x68,
81 0x9a, 0x90, 0x61, 0x80, 0x00, 0xe0, 0x40, 0x6c,
82 0x0f, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
83 0x00, 0x00
84};
85
86static u8 tda8083_inittab[] = {
87 0x04, 0x00, 0x4a, 0x79, 0x04, 0x00, 0xff, 0xea,
88 0x48, 0x42, 0x79, 0x60, 0x70, 0x52, 0x9a, 0x10,
89 0x0e, 0x10, 0xf2, 0xa7, 0x93, 0x0b, 0x05, 0xc8,
90 0x9d, 0x00, 0x42, 0x80, 0x00, 0x60, 0x40, 0x00,
91 0x00, 0x75, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00,
92 0x00, 0x00, 0x00, 0x00
93};
94
95static __inline__ u32 tda80xx_div(u32 a, u32 b)
96{
97 return (a + (b / 2)) / b;
98}
99
100static __inline__ u32 tda80xx_gcd(u32 a, u32 b)
101{
102 u32 r;
103
104 while ((r = a % b)) {
105 a = b;
106 b = r;
107 }
108
109 return b;
110}
111
112static int tda80xx_read(struct tda80xx_state* state, u8 reg, u8 *buf, u8 len)
113{
114 int ret;
115 struct i2c_msg msg[] = { { .addr = state->config->demod_address, .flags = 0, .buf = &reg, .len = 1 },
116 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = buf, .len = len } };
117
118 ret = i2c_transfer(state->i2c, msg, 2);
119
120 if (ret != 2)
121 dprintk("%s: readreg error (reg %02x, ret == %i)\n",
122 __FUNCTION__, reg, ret);
123
124 mdelay(10);
125
126 return (ret == 2) ? 0 : -EREMOTEIO;
127}
128
129static int tda80xx_write(struct tda80xx_state* state, u8 reg, const u8 *buf, u8 len)
130{
131 int ret;
132 u8 wbuf[len + 1];
133 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = wbuf, .len = len + 1 };
134
135 wbuf[0] = reg;
136 memcpy(&wbuf[1], buf, len);
137
138 ret = i2c_transfer(state->i2c, &msg, 1);
139
140 if (ret != 1)
141 dprintk("%s: i2c xfer error (ret == %i)\n", __FUNCTION__, ret);
142
143 mdelay(10);
144
145 return (ret == 1) ? 0 : -EREMOTEIO;
146}
147
148static __inline__ u8 tda80xx_readreg(struct tda80xx_state* state, u8 reg)
149{
150 u8 val;
151
152 tda80xx_read(state, reg, &val, 1);
153
154 return val;
155}
156
157static __inline__ int tda80xx_writereg(struct tda80xx_state* state, u8 reg, u8 data)
158{
159 return tda80xx_write(state, reg, &data, 1);
160}
161
162static int tda80xx_set_parameters(struct tda80xx_state* state,
163 fe_spectral_inversion_t inversion,
164 u32 symbol_rate,
165 fe_code_rate_t fec_inner)
166{
167 u8 buf[15];
168 u64 ratio;
169 u32 clk;
170 u32 k;
171 u32 sr = symbol_rate;
172 u32 gcd;
173 u8 scd;
174
175 if (symbol_rate > (state->clk * 3) / 16)
176 scd = 0;
177 else if (symbol_rate > (state->clk * 3) / 32)
178 scd = 1;
179 else if (symbol_rate > (state->clk * 3) / 64)
180 scd = 2;
181 else
182 scd = 3;
183
184 clk = scd ? (state->clk / (scd * 2)) : state->clk;
185
186 /*
187 * Viterbi decoder:
188 * Differential decoding off
189 * Spectral inversion unknown
190 * QPSK modulation
191 */
192 if (inversion == INVERSION_ON)
193 buf[0] = 0x60;
194 else if (inversion == INVERSION_OFF)
195 buf[0] = 0x20;
196 else
197 buf[0] = 0x00;
198
199 /*
200 * CLK ratio:
201 * system clock frequency is up to 64 or 96 MHz
202 *
203 * formula:
204 * r = k * clk / symbol_rate
205 *
206 * k: 2^21 for caa 0..3,
207 * 2^20 for caa 4..5,
208 * 2^19 for caa 6..7
209 */
210 if (symbol_rate <= (clk * 3) / 32)
211 k = (1 << 19);
212 else if (symbol_rate <= (clk * 3) / 16)
213 k = (1 << 20);
214 else
215 k = (1 << 21);
216
217 gcd = tda80xx_gcd(clk, sr);
218 clk /= gcd;
219 sr /= gcd;
220
221 gcd = tda80xx_gcd(k, sr);
222 k /= gcd;
223 sr /= gcd;
224
225 ratio = (u64)k * (u64)clk;
226 do_div(ratio, sr);
227
228 buf[1] = ratio >> 16;
229 buf[2] = ratio >> 8;
230 buf[3] = ratio;
231
232 /* nyquist filter roll-off factor 35% */
233 buf[4] = 0x20;
234
235 clk = scd ? (state->clk / (scd * 2)) : state->clk;
236
237 /* Anti Alias Filter */
238 if (symbol_rate < (clk * 3) / 64)
239 printk("tda80xx: unsupported symbol rate: %u\n", symbol_rate);
240 else if (symbol_rate <= clk / 16)
241 buf[4] |= 0x07;
242 else if (symbol_rate <= (clk * 3) / 32)
243 buf[4] |= 0x06;
244 else if (symbol_rate <= clk / 8)
245 buf[4] |= 0x05;
246 else if (symbol_rate <= (clk * 3) / 16)
247 buf[4] |= 0x04;
248 else if (symbol_rate <= clk / 4)
249 buf[4] |= 0x03;
250 else if (symbol_rate <= (clk * 3) / 8)
251 buf[4] |= 0x02;
252 else if (symbol_rate <= clk / 2)
253 buf[4] |= 0x01;
254 else
255 buf[4] |= 0x00;
256
257 /* Sigma Delta converter */
258 buf[5] = 0x00;
259
260 /* FEC: Possible puncturing rates */
261 if (fec_inner == FEC_NONE)
262 buf[6] = 0x00;
263 else if ((fec_inner >= FEC_1_2) && (fec_inner <= FEC_8_9))
264 buf[6] = (1 << (8 - fec_inner));
265 else if (fec_inner == FEC_AUTO)
266 buf[6] = 0xff;
267 else
268 return -EINVAL;
269
270 /* carrier lock detector threshold value */
271 buf[7] = 0x30;
272 /* AFC1: proportional part settings */
273 buf[8] = 0x42;
274 /* AFC1: integral part settings */
275 buf[9] = 0x98;
276 /* PD: Leaky integrator SCPC mode */
277 buf[10] = 0x28;
278 /* AFC2, AFC1 controls */
279 buf[11] = 0x30;
280 /* PD: proportional part settings */
281 buf[12] = 0x42;
282 /* PD: integral part settings */
283 buf[13] = 0x99;
284 /* AGC */
285 buf[14] = 0x50 | scd;
286
287 printk("symbol_rate=%u clk=%u\n", symbol_rate, clk);
288
289 return tda80xx_write(state, 0x01, buf, sizeof(buf));
290}
291
292static int tda80xx_set_clk(struct tda80xx_state* state)
293{
294 u8 buf[2];
295
296 /* CLK proportional part */
297 buf[0] = (0x06 << 5) | 0x08; /* CMP[2:0], CSP[4:0] */
298 /* CLK integral part */
299 buf[1] = (0x04 << 5) | 0x1a; /* CMI[2:0], CSI[4:0] */
300
301 return tda80xx_write(state, 0x17, buf, sizeof(buf));
302}
303
304#if 0
305static int tda80xx_set_scpc_freq_offset(struct tda80xx_state* state)
306{
307 /* a constant value is nonsense here imho */
308 return tda80xx_writereg(state, 0x22, 0xf9);
309}
310#endif
311
312static int tda80xx_close_loop(struct tda80xx_state* state)
313{
314 u8 buf[2];
315
316 /* PD: Loop closed, LD: lock detect enable, SCPC: Sweep mode - AFC1 loop closed */
317 buf[0] = 0x68;
318 /* AFC1: Loop closed, CAR Feedback: 8192 */
319 buf[1] = 0x70;
320
321 return tda80xx_write(state, 0x0b, buf, sizeof(buf));
322}
323
324static irqreturn_t tda80xx_irq(int irq, void *priv, struct pt_regs *pt)
325{
326 schedule_work(priv);
327
328 return IRQ_HANDLED;
329}
330
331static void tda80xx_read_status_int(struct tda80xx_state* state)
332{
333 u8 val;
334
335 static const fe_spectral_inversion_t inv_tab[] = {
336 INVERSION_OFF, INVERSION_ON
337 };
338
339 static const fe_code_rate_t fec_tab[] = {
340 FEC_8_9, FEC_1_2, FEC_2_3, FEC_3_4,
341 FEC_4_5, FEC_5_6, FEC_6_7, FEC_7_8,
342 };
343
344 val = tda80xx_readreg(state, 0x02);
345
346 state->status = 0;
347
348 if (val & 0x01) /* demodulator lock */
349 state->status |= FE_HAS_SIGNAL;
350 if (val & 0x02) /* clock recovery lock */
351 state->status |= FE_HAS_CARRIER;
352 if (val & 0x04) /* viterbi lock */
353 state->status |= FE_HAS_VITERBI;
354 if (val & 0x08) /* deinterleaver lock (packet sync) */
355 state->status |= FE_HAS_SYNC;
356 if (val & 0x10) /* derandomizer lock (frame sync) */
357 state->status |= FE_HAS_LOCK;
358 if (val & 0x20) /* frontend can not lock */
359 state->status |= FE_TIMEDOUT;
360
361 if ((state->status & (FE_HAS_CARRIER)) && (state->afc_loop)) {
362 printk("tda80xx: closing loop\n");
363 tda80xx_close_loop(state);
364 state->afc_loop = 0;
365 }
366
367 if (state->status & (FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK)) {
368 val = tda80xx_readreg(state, 0x0e);
369 state->code_rate = fec_tab[val & 0x07];
370 if (state->status & (FE_HAS_SYNC | FE_HAS_LOCK))
371 state->spectral_inversion = inv_tab[(val >> 7) & 0x01];
372 else
373 state->spectral_inversion = INVERSION_AUTO;
374 }
375 else {
376 state->code_rate = FEC_AUTO;
377 }
378}
379
380static void tda80xx_worklet(void *priv)
381{
382 struct tda80xx_state *state = priv;
383
384 tda80xx_writereg(state, 0x00, 0x04);
385 enable_irq(state->config->irq);
386
387 tda80xx_read_status_int(state);
388}
389
390static void tda80xx_wait_diseqc_fifo(struct tda80xx_state* state)
391{
392 size_t i;
393
394 for (i = 0; i < 100; i++) {
395 if (tda80xx_readreg(state, 0x02) & 0x80)
396 break;
397 msleep(10);
398 }
399}
400
401static int tda8044_init(struct dvb_frontend* fe)
402{
403 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
404 int ret;
405
406 /*
407 * this function is a mess...
408 */
409
410 if ((ret = tda80xx_write(state, 0x00, tda8044_inittab_pre, sizeof(tda8044_inittab_pre))))
411 return ret;
412
413 tda80xx_writereg(state, 0x0f, 0x50);
414#if 1
415 tda80xx_writereg(state, 0x20, 0x8F); /* FIXME */
416 tda80xx_writereg(state, 0x20, state->config->volt18setting); /* FIXME */
417 //tda80xx_writereg(state, 0x00, 0x04);
418 tda80xx_writereg(state, 0x00, 0x0C);
419#endif
420 //tda80xx_writereg(state, 0x00, 0x08); /* Reset AFC1 loop filter */
421
422 tda80xx_write(state, 0x00, tda8044_inittab_post, sizeof(tda8044_inittab_post));
423
424 if (state->config->pll_init) {
425 tda80xx_writereg(state, 0x1c, 0x80);
426 state->config->pll_init(fe);
427 tda80xx_writereg(state, 0x1c, 0x00);
428 }
429
430 return 0;
431}
432
433static int tda8083_init(struct dvb_frontend* fe)
434{
435 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
436
437 tda80xx_write(state, 0x00, tda8083_inittab, sizeof(tda8083_inittab));
438
439 if (state->config->pll_init) {
440 tda80xx_writereg(state, 0x1c, 0x80);
441 state->config->pll_init(fe);
442 tda80xx_writereg(state, 0x1c, 0x00);
443 }
444
445 return 0;
446}
447
448static int tda80xx_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
449{
450 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
451
452 switch (voltage) {
453 case SEC_VOLTAGE_13:
454 return tda80xx_writereg(state, 0x20, state->config->volt13setting);
455 case SEC_VOLTAGE_18:
456 return tda80xx_writereg(state, 0x20, state->config->volt18setting);
457 case SEC_VOLTAGE_OFF:
458 return tda80xx_writereg(state, 0x20, 0);
459 default:
460 return -EINVAL;
461 }
462}
463
464static int tda80xx_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
465{
466 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
467
468 switch (tone) {
469 case SEC_TONE_OFF:
470 return tda80xx_writereg(state, 0x29, 0x00);
471 case SEC_TONE_ON:
472 return tda80xx_writereg(state, 0x29, 0x80);
473 default:
474 return -EINVAL;
475 }
476}
477
478static int tda80xx_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd)
479{
480 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
481
482 if (cmd->msg_len > 6)
483 return -EINVAL;
484
485 tda80xx_writereg(state, 0x29, 0x08 | (cmd->msg_len - 3));
486 tda80xx_write(state, 0x23, cmd->msg, cmd->msg_len);
487 tda80xx_writereg(state, 0x29, 0x0c | (cmd->msg_len - 3));
488 tda80xx_wait_diseqc_fifo(state);
489
490 return 0;
491}
492
493static int tda80xx_send_diseqc_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t cmd)
494{
495 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
496
497 switch (cmd) {
498 case SEC_MINI_A:
499 tda80xx_writereg(state, 0x29, 0x14);
500 break;
501 case SEC_MINI_B:
502 tda80xx_writereg(state, 0x29, 0x1c);
503 break;
504 default:
505 return -EINVAL;
506 }
507
508 tda80xx_wait_diseqc_fifo(state);
509
510 return 0;
511}
512
513static int tda80xx_sleep(struct dvb_frontend* fe)
514{
515 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
516
517 tda80xx_writereg(state, 0x00, 0x02); /* enter standby */
518
519 return 0;
520}
521
522static int tda80xx_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
523{
524 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
525
526 tda80xx_writereg(state, 0x1c, 0x80);
527 state->config->pll_set(fe, p);
528 tda80xx_writereg(state, 0x1c, 0x00);
529
530 tda80xx_set_parameters(state, p->inversion, p->u.qpsk.symbol_rate, p->u.qpsk.fec_inner);
531 tda80xx_set_clk(state);
532 //tda80xx_set_scpc_freq_offset(state);
533 state->afc_loop = 1;
534
535 return 0;
536}
537
538static int tda80xx_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
539{
540 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
541
542 if (!state->config->irq)
543 tda80xx_read_status_int(state);
544
545 p->inversion = state->spectral_inversion;
546 p->u.qpsk.fec_inner = state->code_rate;
547
548 return 0;
549}
550
551static int tda80xx_read_status(struct dvb_frontend* fe, fe_status_t* status)
552{
553 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
554
555 if (!state->config->irq)
556 tda80xx_read_status_int(state);
557 *status = state->status;
558
559 return 0;
560}
561
562static int tda80xx_read_ber(struct dvb_frontend* fe, u32* ber)
563{
564 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
565 int ret;
566 u8 buf[3];
567
568 if ((ret = tda80xx_read(state, 0x0b, buf, sizeof(buf))))
569 return ret;
570
571 *ber = ((buf[0] & 0x1f) << 16) | (buf[1] << 8) | buf[2];
572
573 return 0;
574}
575
576static int tda80xx_read_signal_strength(struct dvb_frontend* fe, u16* strength)
577{
578 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
579
580 u8 gain = ~tda80xx_readreg(state, 0x01);
581 *strength = (gain << 8) | gain;
582
583 return 0;
584}
585
586static int tda80xx_read_snr(struct dvb_frontend* fe, u16* snr)
587{
588 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
589
590 u8 quality = tda80xx_readreg(state, 0x08);
591 *snr = (quality << 8) | quality;
592
593 return 0;
594}
595
596static int tda80xx_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
597{
598 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
599
600 *ucblocks = tda80xx_readreg(state, 0x0f);
601 if (*ucblocks == 0xff)
602 *ucblocks = 0xffffffff;
603
604 return 0;
605}
606
607static int tda80xx_init(struct dvb_frontend* fe)
608{
609 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
610
611 switch(state->id) {
612 case ID_TDA8044:
613 return tda8044_init(fe);
614
615 case ID_TDA8083:
616 return tda8083_init(fe);
617 }
618 return 0;
619}
620
621static void tda80xx_release(struct dvb_frontend* fe)
622{
623 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
624
625 if (state->config->irq)
626 free_irq(state->config->irq, &state->worklet);
627
628 kfree(state);
629}
630
631static struct dvb_frontend_ops tda80xx_ops;
632
633struct dvb_frontend* tda80xx_attach(const struct tda80xx_config* config,
634 struct i2c_adapter* i2c)
635{
636 struct tda80xx_state* state = NULL;
637 int ret;
638
639 /* allocate memory for the internal state */
640 state = (struct tda80xx_state*) kmalloc(sizeof(struct tda80xx_state), GFP_KERNEL);
641 if (state == NULL) goto error;
642
643 /* setup the state */
644 state->config = config;
645 state->i2c = i2c;
646 memcpy(&state->ops, &tda80xx_ops, sizeof(struct dvb_frontend_ops));
647 state->spectral_inversion = INVERSION_AUTO;
648 state->code_rate = FEC_AUTO;
649 state->status = 0;
650 state->afc_loop = 0;
651
652 /* check if the demod is there */
653 if (tda80xx_writereg(state, 0x89, 0x00) < 0) goto error;
654 state->id = tda80xx_readreg(state, 0x00);
655
656 switch (state->id) {
657 case ID_TDA8044:
658 state->clk = 96000000;
659 printk("tda80xx: Detected tda8044\n");
660 break;
661
662 case ID_TDA8083:
663 state->clk = 64000000;
664 printk("tda80xx: Detected tda8083\n");
665 break;
666
667 default:
668 goto error;
669 }
670
671 /* setup IRQ */
672 if (state->config->irq) {
673 INIT_WORK(&state->worklet, tda80xx_worklet, state);
674 if ((ret = request_irq(state->config->irq, tda80xx_irq, SA_ONESHOT, "tda80xx", &state->worklet)) < 0) {
675 printk(KERN_ERR "tda80xx: request_irq failed (%d)\n", ret);
676 goto error;
677 }
678 }
679
680 /* create dvb_frontend */
681 state->frontend.ops = &state->ops;
682 state->frontend.demodulator_priv = state;
683 return &state->frontend;
684
685error:
686 kfree(state);
687 return NULL;
688}
689
690static struct dvb_frontend_ops tda80xx_ops = {
691
692 .info = {
693 .name = "Philips TDA80xx DVB-S",
694 .type = FE_QPSK,
695 .frequency_min = 500000,
696 .frequency_max = 2700000,
697 .frequency_stepsize = 125,
698 .symbol_rate_min = 4500000,
699 .symbol_rate_max = 45000000,
700 .caps = FE_CAN_INVERSION_AUTO |
701 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
702 FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
703 FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
704 FE_CAN_QPSK |
705 FE_CAN_MUTE_TS
706 },
707
708 .release = tda80xx_release,
709
710 .init = tda80xx_init,
711 .sleep = tda80xx_sleep,
712
713 .set_frontend = tda80xx_set_frontend,
714 .get_frontend = tda80xx_get_frontend,
715
716 .read_status = tda80xx_read_status,
717 .read_ber = tda80xx_read_ber,
718 .read_signal_strength = tda80xx_read_signal_strength,
719 .read_snr = tda80xx_read_snr,
720 .read_ucblocks = tda80xx_read_ucblocks,
721
722 .diseqc_send_master_cmd = tda80xx_send_diseqc_msg,
723 .diseqc_send_burst = tda80xx_send_diseqc_burst,
724 .set_tone = tda80xx_set_tone,
725 .set_voltage = tda80xx_set_voltage,
726};
727
728module_param(debug, int, 0644);
729
730MODULE_DESCRIPTION("Philips TDA8044 / TDA8083 DVB-S Demodulator driver");
731MODULE_AUTHOR("Felix Domke, Andreas Oberritter");
732MODULE_LICENSE("GPL");
733
734EXPORT_SYMBOL(tda80xx_attach);
diff --git a/drivers/media/dvb/frontends/tda80xx.h b/drivers/media/dvb/frontends/tda80xx.h
new file mode 100644
index 000000000000..cd639a0aad55
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda80xx.h
@@ -0,0 +1,51 @@
1/*
2 * tda80xx.c
3 *
4 * Philips TDA8044 / TDA8083 QPSK demodulator driver
5 *
6 * Copyright (C) 2001 Felix Domke <tmbinc@elitedvb.net>
7 * Copyright (C) 2002-2004 Andreas Oberritter <obi@linuxtv.org>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#ifndef TDA80XX_H
25#define TDA80XX_H
26
27#include <linux/dvb/frontend.h>
28
29struct tda80xx_config
30{
31 /* the demodulator's i2c address */
32 u8 demod_address;
33
34 /* IRQ to use (0=>no IRQ used) */
35 u32 irq;
36
37 /* Register setting to use for 13v */
38 u8 volt13setting;
39
40 /* Register setting to use for 18v */
41 u8 volt18setting;
42
43 /* PLL maintenance */
44 int (*pll_init)(struct dvb_frontend* fe);
45 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
46};
47
48extern struct dvb_frontend* tda80xx_attach(const struct tda80xx_config* config,
49 struct i2c_adapter* i2c);
50
51#endif // TDA80XX_H
diff --git a/drivers/media/dvb/frontends/ves1820.c b/drivers/media/dvb/frontends/ves1820.c
new file mode 100644
index 000000000000..9c0d23e1d9e5
--- /dev/null
+++ b/drivers/media/dvb/frontends/ves1820.c
@@ -0,0 +1,450 @@
1/*
2 VES1820 - Single Chip Cable Channel Receiver driver module
3
4 Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21#include <linux/config.h>
22#include <linux/delay.h>
23#include <linux/errno.h>
24#include <linux/init.h>
25#include <linux/kernel.h>
26#include <linux/module.h>
27#include <linux/string.h>
28#include <linux/slab.h>
29#include <asm/div64.h>
30
31#include "dvb_frontend.h"
32#include "ves1820.h"
33
34
35
36struct ves1820_state {
37 struct i2c_adapter* i2c;
38 struct dvb_frontend_ops ops;
39 /* configuration settings */
40 const struct ves1820_config* config;
41 struct dvb_frontend frontend;
42
43 /* private demodulator data */
44 u8 reg0;
45 u8 pwm;
46};
47
48
49static int verbose;
50
51static u8 ves1820_inittab[] = {
52 0x69, 0x6A, 0x93, 0x12, 0x12, 0x46, 0x26, 0x1A,
53 0x43, 0x6A, 0xAA, 0xAA, 0x1E, 0x85, 0x43, 0x20,
54 0xE0, 0x00, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x00,
55 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
56 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
57 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
58 0x00, 0x00, 0x00, 0x00, 0x40
59};
60
61static int ves1820_writereg(struct ves1820_state *state, u8 reg, u8 data)
62{
63 u8 buf[] = { 0x00, reg, data };
64 struct i2c_msg msg = {.addr = state->config->demod_address,.flags = 0,.buf = buf,.len = 3 };
65 int ret;
66
67 ret = i2c_transfer(state->i2c, &msg, 1);
68
69 if (ret != 1)
70 printk("ves1820: %s(): writereg error (reg == 0x%02x,"
71 "val == 0x%02x, ret == %i)\n", __FUNCTION__, reg, data, ret);
72
73 msleep(10);
74 return (ret != 1) ? -EREMOTEIO : 0;
75}
76
77static u8 ves1820_readreg(struct ves1820_state *state, u8 reg)
78{
79 u8 b0[] = { 0x00, reg };
80 u8 b1[] = { 0 };
81 struct i2c_msg msg[] = {
82 {.addr = state->config->demod_address,.flags = 0,.buf = b0,.len = 2},
83 {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b1,.len = 1}
84 };
85 int ret;
86
87 ret = i2c_transfer(state->i2c, msg, 2);
88
89 if (ret != 2)
90 printk("ves1820: %s(): readreg error (reg == 0x%02x,"
91 "ret == %i)\n", __FUNCTION__, reg, ret);
92
93 return b1[0];
94}
95
96static int ves1820_setup_reg0(struct ves1820_state *state, u8 reg0, fe_spectral_inversion_t inversion)
97{
98 reg0 |= state->reg0 & 0x62;
99
100 if (INVERSION_ON == inversion) {
101 if (!state->config->invert) reg0 |= 0x20;
102 else reg0 &= ~0x20;
103 } else if (INVERSION_OFF == inversion) {
104 if (!state->config->invert) reg0 &= ~0x20;
105 else reg0 |= 0x20;
106 }
107
108 ves1820_writereg(state, 0x00, reg0 & 0xfe);
109 ves1820_writereg(state, 0x00, reg0 | 0x01);
110
111 state->reg0 = reg0;
112
113 return 0;
114}
115
116static int ves1820_set_symbolrate(struct ves1820_state *state, u32 symbolrate)
117{
118 s32 BDR;
119 s32 BDRI;
120 s16 SFIL = 0;
121 u16 NDEC = 0;
122 u32 ratio;
123 u32 fin;
124 u32 tmp;
125 u64 fptmp;
126 u64 fpxin;
127
128 if (symbolrate > state->config->xin / 2)
129 symbolrate = state->config->xin / 2;
130
131 if (symbolrate < 500000)
132 symbolrate = 500000;
133
134 if (symbolrate < state->config->xin / 16)
135 NDEC = 1;
136 if (symbolrate < state->config->xin / 32)
137 NDEC = 2;
138 if (symbolrate < state->config->xin / 64)
139 NDEC = 3;
140
141 /* yeuch! */
142 fpxin = state->config->xin * 10;
143 fptmp = fpxin; do_div(fptmp, 123);
144 if (symbolrate < fptmp);
145 SFIL = 1;
146 fptmp = fpxin; do_div(fptmp, 160);
147 if (symbolrate < fptmp);
148 SFIL = 0;
149 fptmp = fpxin; do_div(fptmp, 246);
150 if (symbolrate < fptmp);
151 SFIL = 1;
152 fptmp = fpxin; do_div(fptmp, 320);
153 if (symbolrate < fptmp);
154 SFIL = 0;
155 fptmp = fpxin; do_div(fptmp, 492);
156 if (symbolrate < fptmp);
157 SFIL = 1;
158 fptmp = fpxin; do_div(fptmp, 640);
159 if (symbolrate < fptmp);
160 SFIL = 0;
161 fptmp = fpxin; do_div(fptmp, 984);
162 if (symbolrate < fptmp);
163 SFIL = 1;
164
165 fin = state->config->xin >> 4;
166 symbolrate <<= NDEC;
167 ratio = (symbolrate << 4) / fin;
168 tmp = ((symbolrate << 4) % fin) << 8;
169 ratio = (ratio << 8) + tmp / fin;
170 tmp = (tmp % fin) << 8;
171 ratio = (ratio << 8) + (tmp + fin / 2) / fin;
172
173 BDR = ratio;
174 BDRI = (((state->config->xin << 5) / symbolrate) + 1) / 2;
175
176 if (BDRI > 0xFF)
177 BDRI = 0xFF;
178
179 SFIL = (SFIL << 4) | ves1820_inittab[0x0E];
180
181 NDEC = (NDEC << 6) | ves1820_inittab[0x03];
182
183 ves1820_writereg(state, 0x03, NDEC);
184 ves1820_writereg(state, 0x0a, BDR & 0xff);
185 ves1820_writereg(state, 0x0b, (BDR >> 8) & 0xff);
186 ves1820_writereg(state, 0x0c, (BDR >> 16) & 0x3f);
187
188 ves1820_writereg(state, 0x0d, BDRI);
189 ves1820_writereg(state, 0x0e, SFIL);
190
191 return 0;
192}
193
194static int ves1820_init(struct dvb_frontend* fe)
195{
196 struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv;
197 int i;
198 int val;
199
200 ves1820_writereg(state, 0, 0);
201
202 for (i = 0; i < 53; i++) {
203 val = ves1820_inittab[i];
204 if ((i == 2) && (state->config->selagc)) val |= 0x08;
205 ves1820_writereg(state, i, val);
206 }
207
208 ves1820_writereg(state, 0x34, state->pwm);
209
210 if (state->config->pll_init) state->config->pll_init(fe);
211
212 return 0;
213}
214
215static int ves1820_set_parameters(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
216{
217 struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv;
218 static const u8 reg0x00[] = { 0x00, 0x04, 0x08, 0x0c, 0x10 };
219 static const u8 reg0x01[] = { 140, 140, 106, 100, 92 };
220 static const u8 reg0x05[] = { 135, 100, 70, 54, 38 };
221 static const u8 reg0x08[] = { 162, 116, 67, 52, 35 };
222 static const u8 reg0x09[] = { 145, 150, 106, 126, 107 };
223 int real_qam = p->u.qam.modulation - QAM_16;
224
225 if (real_qam < 0 || real_qam > 4)
226 return -EINVAL;
227
228 state->config->pll_set(fe, p);
229 ves1820_set_symbolrate(state, p->u.qam.symbol_rate);
230 ves1820_writereg(state, 0x34, state->pwm);
231
232 ves1820_writereg(state, 0x01, reg0x01[real_qam]);
233 ves1820_writereg(state, 0x05, reg0x05[real_qam]);
234 ves1820_writereg(state, 0x08, reg0x08[real_qam]);
235 ves1820_writereg(state, 0x09, reg0x09[real_qam]);
236
237 ves1820_setup_reg0(state, reg0x00[real_qam], p->inversion);
238
239 return 0;
240}
241
242static int ves1820_read_status(struct dvb_frontend* fe, fe_status_t* status)
243{
244 struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv;
245 int sync;
246
247 *status = 0;
248 sync = ves1820_readreg(state, 0x11);
249
250 if (sync & 1)
251 *status |= FE_HAS_SIGNAL;
252
253 if (sync & 2)
254 *status |= FE_HAS_CARRIER;
255
256 if (sync & 2) /* XXX FIXME! */
257 *status |= FE_HAS_VITERBI;
258
259 if (sync & 4)
260 *status |= FE_HAS_SYNC;
261
262 if (sync & 8)
263 *status |= FE_HAS_LOCK;
264
265 return 0;
266}
267
268static int ves1820_read_ber(struct dvb_frontend* fe, u32* ber)
269{
270 struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv;
271
272 u32 _ber = ves1820_readreg(state, 0x14) |
273 (ves1820_readreg(state, 0x15) << 8) |
274 ((ves1820_readreg(state, 0x16) & 0x0f) << 16);
275 *ber = 10 * _ber;
276
277 return 0;
278}
279
280static int ves1820_read_signal_strength(struct dvb_frontend* fe, u16* strength)
281{
282 struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv;
283
284 u8 gain = ves1820_readreg(state, 0x17);
285 *strength = (gain << 8) | gain;
286
287 return 0;
288}
289
290static int ves1820_read_snr(struct dvb_frontend* fe, u16* snr)
291{
292 struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv;
293
294 u8 quality = ~ves1820_readreg(state, 0x18);
295 *snr = (quality << 8) | quality;
296
297 return 0;
298}
299
300static int ves1820_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
301{
302 struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv;
303
304 *ucblocks = ves1820_readreg(state, 0x13) & 0x7f;
305 if (*ucblocks == 0x7f)
306 *ucblocks = 0xffffffff;
307
308 /* reset uncorrected block counter */
309 ves1820_writereg(state, 0x10, ves1820_inittab[0x10] & 0xdf);
310 ves1820_writereg(state, 0x10, ves1820_inittab[0x10]);
311
312 return 0;
313}
314
315static int ves1820_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
316{
317 struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv;
318 int sync;
319 s8 afc = 0;
320
321 sync = ves1820_readreg(state, 0x11);
322 afc = ves1820_readreg(state, 0x19);
323 if (verbose) {
324 /* AFC only valid when carrier has been recovered */
325 printk(sync & 2 ? "ves1820: AFC (%d) %dHz\n" :
326 "ves1820: [AFC (%d) %dHz]\n", afc, -((s32) p->u.qam.symbol_rate * afc) >> 10);
327 }
328
329 if (!state->config->invert) {
330 p->inversion = (state->reg0 & 0x20) ? INVERSION_ON : INVERSION_OFF;
331 } else {
332 p->inversion = (!(state->reg0 & 0x20)) ? INVERSION_ON : INVERSION_OFF;
333 }
334
335 p->u.qam.modulation = ((state->reg0 >> 2) & 7) + QAM_16;
336
337 p->u.qam.fec_inner = FEC_NONE;
338
339 p->frequency = ((p->frequency + 31250) / 62500) * 62500;
340 if (sync & 2)
341 p->frequency -= ((s32) p->u.qam.symbol_rate * afc) >> 10;
342
343 return 0;
344}
345
346static int ves1820_sleep(struct dvb_frontend* fe)
347{
348 struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv;
349
350 ves1820_writereg(state, 0x1b, 0x02); /* pdown ADC */
351 ves1820_writereg(state, 0x00, 0x80); /* standby */
352
353 return 0;
354}
355
356static int ves1820_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
357{
358
359 fesettings->min_delay_ms = 200;
360 fesettings->step_size = 0;
361 fesettings->max_drift = 0;
362 return 0;
363}
364
365static void ves1820_release(struct dvb_frontend* fe)
366{
367 struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv;
368 kfree(state);
369}
370
371static struct dvb_frontend_ops ves1820_ops;
372
373struct dvb_frontend* ves1820_attach(const struct ves1820_config* config,
374 struct i2c_adapter* i2c,
375 u8 pwm)
376{
377 struct ves1820_state* state = NULL;
378
379 /* allocate memory for the internal state */
380 state = (struct ves1820_state*) kmalloc(sizeof(struct ves1820_state), GFP_KERNEL);
381 if (state == NULL)
382 goto error;
383
384 /* setup the state */
385 memcpy(&state->ops, &ves1820_ops, sizeof(struct dvb_frontend_ops));
386 state->reg0 = ves1820_inittab[0];
387 state->config = config;
388 state->i2c = i2c;
389 state->pwm = pwm;
390
391 /* check if the demod is there */
392 if ((ves1820_readreg(state, 0x1a) & 0xf0) != 0x70)
393 goto error;
394
395 if (verbose)
396 printk("ves1820: pwm=0x%02x\n", state->pwm);
397
398 state->ops.info.symbol_rate_min = (state->config->xin / 2) / 64; /* SACLK/64 == (XIN/2)/64 */
399 state->ops.info.symbol_rate_max = (state->config->xin / 2) / 4; /* SACLK/4 */
400
401 /* create dvb_frontend */
402 state->frontend.ops = &state->ops;
403 state->frontend.demodulator_priv = state;
404 return &state->frontend;
405
406error:
407 kfree(state);
408 return NULL;
409}
410
411static struct dvb_frontend_ops ves1820_ops = {
412
413 .info = {
414 .name = "VLSI VES1820 DVB-C",
415 .type = FE_QAM,
416 .frequency_stepsize = 62500,
417 .frequency_min = 51000000,
418 .frequency_max = 858000000,
419 .caps = FE_CAN_QAM_16 |
420 FE_CAN_QAM_32 |
421 FE_CAN_QAM_64 |
422 FE_CAN_QAM_128 |
423 FE_CAN_QAM_256 |
424 FE_CAN_FEC_AUTO
425 },
426
427 .release = ves1820_release,
428
429 .init = ves1820_init,
430 .sleep = ves1820_sleep,
431
432 .set_frontend = ves1820_set_parameters,
433 .get_frontend = ves1820_get_frontend,
434 .get_tune_settings = ves1820_get_tune_settings,
435
436 .read_status = ves1820_read_status,
437 .read_ber = ves1820_read_ber,
438 .read_signal_strength = ves1820_read_signal_strength,
439 .read_snr = ves1820_read_snr,
440 .read_ucblocks = ves1820_read_ucblocks,
441};
442
443module_param(verbose, int, 0644);
444MODULE_PARM_DESC(verbose, "print AFC offset after tuning for debugging the PWM setting");
445
446MODULE_DESCRIPTION("VLSI VES1820 DVB-C Demodulator driver");
447MODULE_AUTHOR("Ralph Metzler, Holger Waechtler");
448MODULE_LICENSE("GPL");
449
450EXPORT_SYMBOL(ves1820_attach);
diff --git a/drivers/media/dvb/frontends/ves1820.h b/drivers/media/dvb/frontends/ves1820.h
new file mode 100644
index 000000000000..355f130b1be8
--- /dev/null
+++ b/drivers/media/dvb/frontends/ves1820.h
@@ -0,0 +1,51 @@
1/*
2 VES1820 - Single Chip Cable Channel Receiver driver module
3
4 Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21#ifndef VES1820_H
22#define VES1820_H
23
24#include <linux/dvb/frontend.h>
25
26#define VES1820_SELAGC_PWM 0
27#define VES1820_SELAGC_SIGNAMPERR 1
28
29struct ves1820_config
30{
31 /* the demodulator's i2c address */
32 u8 demod_address;
33
34 /* value of XIN to use */
35 u32 xin;
36
37 /* does inversion need inverted? */
38 u8 invert:1;
39
40 /* SELAGC control */
41 u8 selagc:1;
42
43 /* PLL maintenance */
44 int (*pll_init)(struct dvb_frontend* fe);
45 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
46};
47
48extern struct dvb_frontend* ves1820_attach(const struct ves1820_config* config,
49 struct i2c_adapter* i2c, u8 pwm);
50
51#endif // VES1820_H
diff --git a/drivers/media/dvb/frontends/ves1x93.c b/drivers/media/dvb/frontends/ves1x93.c
new file mode 100644
index 000000000000..edcad283aa86
--- /dev/null
+++ b/drivers/media/dvb/frontends/ves1x93.c
@@ -0,0 +1,545 @@
1/*
2 Driver for VES1893 and VES1993 QPSK Demodulators
3
4 Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
5 Copyright (C) 2001 Ronny Strutz <3des@elitedvb.de>
6 Copyright (C) 2002 Dennis Noermann <dennis.noermann@noernet.de>
7 Copyright (C) 2002-2003 Andreas Oberritter <obi@linuxtv.org>
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23
24*/
25
26#include <linux/kernel.h>
27#include <linux/module.h>
28#include <linux/init.h>
29#include <linux/string.h>
30#include <linux/slab.h>
31#include <linux/delay.h>
32
33#include "dvb_frontend.h"
34#include "ves1x93.h"
35
36
37struct ves1x93_state {
38 struct i2c_adapter* i2c;
39 struct dvb_frontend_ops ops;
40 /* configuration settings */
41 const struct ves1x93_config* config;
42 struct dvb_frontend frontend;
43
44 /* previous uncorrected block counter */
45 fe_spectral_inversion_t inversion;
46 u8 *init_1x93_tab;
47 u8 *init_1x93_wtab;
48 u8 tab_size;
49 u8 demod_type;
50};
51
52static int debug = 0;
53#define dprintk if (debug) printk
54
55#define DEMOD_VES1893 0
56#define DEMOD_VES1993 1
57
58static u8 init_1893_tab [] = {
59 0x01, 0xa4, 0x35, 0x80, 0x2a, 0x0b, 0x55, 0xc4,
60 0x09, 0x69, 0x00, 0x86, 0x4c, 0x28, 0x7f, 0x00,
61 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62 0x80, 0x00, 0x21, 0xb0, 0x14, 0x00, 0xdc, 0x00,
63 0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
64 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
65 0x00, 0x55, 0x00, 0x00, 0x7f, 0x00
66};
67
68static u8 init_1993_tab [] = {
69 0x00, 0x9c, 0x35, 0x80, 0x6a, 0x09, 0x72, 0x8c,
70 0x09, 0x6b, 0x00, 0x00, 0x4c, 0x08, 0x00, 0x00,
71 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
72 0x80, 0x40, 0x21, 0xb0, 0x00, 0x00, 0x00, 0x10,
73 0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
74 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00,
75 0x00, 0x55, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03,
76 0x00, 0x00, 0x0e, 0x80, 0x00
77};
78
79static u8 init_1893_wtab[] =
80{
81 1,1,1,1,1,1,1,1, 1,1,0,0,1,1,0,0,
82 0,1,0,0,0,0,0,0, 1,0,1,1,0,0,0,1,
83 1,1,1,0,0,0,0,0, 0,0,1,1,0,0,0,0,
84 1,1,1,0,1,1
85};
86
87static u8 init_1993_wtab[] =
88{
89 1,1,1,1,1,1,1,1, 1,1,0,0,1,1,0,0,
90 0,1,0,0,0,0,0,0, 1,1,1,1,0,0,0,1,
91 1,1,1,0,0,0,0,0, 0,0,1,1,0,0,0,0,
92 1,1,1,0,1,1,1,1, 1,1,1,1,1
93};
94
95static int ves1x93_writereg (struct ves1x93_state* state, u8 reg, u8 data)
96{
97 u8 buf [] = { 0x00, reg, data };
98 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 3 };
99 int err;
100
101 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
102 dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __FUNCTION__, err, reg, data);
103 return -EREMOTEIO;
104 }
105
106 return 0;
107}
108
109static u8 ves1x93_readreg (struct ves1x93_state* state, u8 reg)
110{
111 int ret;
112 u8 b0 [] = { 0x00, reg };
113 u8 b1 [] = { 0 };
114 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 2 },
115 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
116
117 ret = i2c_transfer (state->i2c, msg, 2);
118
119 if (ret != 2) return ret;
120
121 return b1[0];
122}
123
124static int ves1x93_clr_bit (struct ves1x93_state* state)
125{
126 msleep(10);
127 ves1x93_writereg (state, 0, state->init_1x93_tab[0] & 0xfe);
128 ves1x93_writereg (state, 0, state->init_1x93_tab[0]);
129 msleep(50);
130 return 0;
131}
132
133static int ves1x93_set_inversion (struct ves1x93_state* state, fe_spectral_inversion_t inversion)
134{
135 u8 val;
136
137 /*
138 * inversion on/off are interchanged because i and q seem to
139 * be swapped on the hardware
140 */
141
142 switch (inversion) {
143 case INVERSION_OFF:
144 val = 0xc0;
145 break;
146 case INVERSION_ON:
147 val = 0x80;
148 break;
149 case INVERSION_AUTO:
150 val = 0x00;
151 break;
152 default:
153 return -EINVAL;
154 }
155
156 return ves1x93_writereg (state, 0x0c, (state->init_1x93_tab[0x0c] & 0x3f) | val);
157}
158
159static int ves1x93_set_fec (struct ves1x93_state* state, fe_code_rate_t fec)
160{
161 if (fec == FEC_AUTO)
162 return ves1x93_writereg (state, 0x0d, 0x08);
163 else if (fec < FEC_1_2 || fec > FEC_8_9)
164 return -EINVAL;
165 else
166 return ves1x93_writereg (state, 0x0d, fec - FEC_1_2);
167}
168
169static fe_code_rate_t ves1x93_get_fec (struct ves1x93_state* state)
170{
171 return FEC_1_2 + ((ves1x93_readreg (state, 0x0d) >> 4) & 0x7);
172}
173
174static int ves1x93_set_symbolrate (struct ves1x93_state* state, u32 srate)
175{
176 u32 BDR;
177 u32 ratio;
178 u8 ADCONF, FCONF, FNR, AGCR;
179 u32 BDRI;
180 u32 tmp;
181 u32 FIN;
182
183 dprintk("%s: srate == %d\n", __FUNCTION__, (unsigned int) srate);
184
185 if (srate > state->config->xin/2)
186 srate = state->config->xin/2;
187
188 if (srate < 500000)
189 srate = 500000;
190
191#define MUL (1UL<<26)
192
193 FIN = (state->config->xin + 6000) >> 4;
194
195 tmp = srate << 6;
196 ratio = tmp / FIN;
197
198 tmp = (tmp % FIN) << 8;
199 ratio = (ratio << 8) + tmp / FIN;
200
201 tmp = (tmp % FIN) << 8;
202 ratio = (ratio << 8) + tmp / FIN;
203
204 FNR = 0xff;
205
206 if (ratio < MUL/3) FNR = 0;
207 if (ratio < (MUL*11)/50) FNR = 1;
208 if (ratio < MUL/6) FNR = 2;
209 if (ratio < MUL/9) FNR = 3;
210 if (ratio < MUL/12) FNR = 4;
211 if (ratio < (MUL*11)/200) FNR = 5;
212 if (ratio < MUL/24) FNR = 6;
213 if (ratio < (MUL*27)/1000) FNR = 7;
214 if (ratio < MUL/48) FNR = 8;
215 if (ratio < (MUL*137)/10000) FNR = 9;
216
217 if (FNR == 0xff) {
218 ADCONF = 0x89;
219 FCONF = 0x80;
220 FNR = 0;
221 } else {
222 ADCONF = 0x81;
223 FCONF = 0x88 | (FNR >> 1) | ((FNR & 0x01) << 5);
224 /*FCONF = 0x80 | ((FNR & 0x01) << 5) | (((FNR > 1) & 0x03) << 3) | ((FNR >> 1) & 0x07);*/
225 }
226
227 BDR = (( (ratio << (FNR >> 1)) >> 4) + 1) >> 1;
228 BDRI = ( ((FIN << 8) / ((srate << (FNR >> 1)) >> 2)) + 1) >> 1;
229
230 dprintk("FNR= %d\n", FNR);
231 dprintk("ratio= %08x\n", (unsigned int) ratio);
232 dprintk("BDR= %08x\n", (unsigned int) BDR);
233 dprintk("BDRI= %02x\n", (unsigned int) BDRI);
234
235 if (BDRI > 0xff)
236 BDRI = 0xff;
237
238 ves1x93_writereg (state, 0x06, 0xff & BDR);
239 ves1x93_writereg (state, 0x07, 0xff & (BDR >> 8));
240 ves1x93_writereg (state, 0x08, 0x0f & (BDR >> 16));
241
242 ves1x93_writereg (state, 0x09, BDRI);
243 ves1x93_writereg (state, 0x20, ADCONF);
244 ves1x93_writereg (state, 0x21, FCONF);
245
246 AGCR = state->init_1x93_tab[0x05];
247 if (state->config->invert_pwm)
248 AGCR |= 0x20;
249
250 if (srate < 6000000)
251 AGCR |= 0x80;
252 else
253 AGCR &= ~0x80;
254
255 ves1x93_writereg (state, 0x05, AGCR);
256
257 /* ves1993 hates this, will lose lock */
258 if (state->demod_type != DEMOD_VES1993)
259 ves1x93_clr_bit (state);
260
261 return 0;
262}
263
264static int ves1x93_init (struct dvb_frontend* fe)
265{
266 struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv;
267 int i;
268 int val;
269
270 dprintk("%s: init chip\n", __FUNCTION__);
271
272 for (i = 0; i < state->tab_size; i++) {
273 if (state->init_1x93_wtab[i]) {
274 val = state->init_1x93_tab[i];
275
276 if (state->config->invert_pwm && (i == 0x05)) val |= 0x20; /* invert PWM */
277 ves1x93_writereg (state, i, val);
278 }
279 }
280
281 if (state->config->pll_init) {
282 ves1x93_writereg(state, 0x00, 0x11);
283 state->config->pll_init(fe);
284 ves1x93_writereg(state, 0x00, 0x01);
285 }
286
287 return 0;
288}
289
290static int ves1x93_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage)
291{
292 struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv;
293
294 switch (voltage) {
295 case SEC_VOLTAGE_13:
296 return ves1x93_writereg (state, 0x1f, 0x20);
297 case SEC_VOLTAGE_18:
298 return ves1x93_writereg (state, 0x1f, 0x30);
299 case SEC_VOLTAGE_OFF:
300 return ves1x93_writereg (state, 0x1f, 0x00);
301 default:
302 return -EINVAL;
303 }
304}
305
306static int ves1x93_read_status(struct dvb_frontend* fe, fe_status_t* status)
307{
308 struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv;
309
310 u8 sync = ves1x93_readreg (state, 0x0e);
311
312 /*
313 * The ves1893 sometimes returns sync values that make no sense,
314 * because, e.g., the SIGNAL bit is 0, while some of the higher
315 * bits are 1 (and how can there be a CARRIER w/o a SIGNAL?).
316 * Tests showed that the the VITERBI and SYNC bits are returned
317 * reliably, while the SIGNAL and CARRIER bits ar sometimes wrong.
318 * If such a case occurs, we read the value again, until we get a
319 * valid value.
320 */
321 int maxtry = 10; /* just for safety - let's not get stuck here */
322 while ((sync & 0x03) != 0x03 && (sync & 0x0c) && maxtry--) {
323 msleep(10);
324 sync = ves1x93_readreg (state, 0x0e);
325 }
326
327 *status = 0;
328
329 if (sync & 1)
330 *status |= FE_HAS_SIGNAL;
331
332 if (sync & 2)
333 *status |= FE_HAS_CARRIER;
334
335 if (sync & 4)
336 *status |= FE_HAS_VITERBI;
337
338 if (sync & 8)
339 *status |= FE_HAS_SYNC;
340
341 if ((sync & 0x1f) == 0x1f)
342 *status |= FE_HAS_LOCK;
343
344 return 0;
345}
346
347static int ves1x93_read_ber(struct dvb_frontend* fe, u32* ber)
348{
349 struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv;
350
351 *ber = ves1x93_readreg (state, 0x15);
352 *ber |= (ves1x93_readreg (state, 0x16) << 8);
353 *ber |= ((ves1x93_readreg (state, 0x17) & 0x0F) << 16);
354 *ber *= 10;
355
356 return 0;
357}
358
359static int ves1x93_read_signal_strength(struct dvb_frontend* fe, u16* strength)
360{
361 struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv;
362
363 u8 signal = ~ves1x93_readreg (state, 0x0b);
364 *strength = (signal << 8) | signal;
365
366 return 0;
367}
368
369static int ves1x93_read_snr(struct dvb_frontend* fe, u16* snr)
370{
371 struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv;
372
373 u8 _snr = ~ves1x93_readreg (state, 0x1c);
374 *snr = (_snr << 8) | _snr;
375
376 return 0;
377}
378
379static int ves1x93_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
380{
381 struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv;
382
383 *ucblocks = ves1x93_readreg (state, 0x18) & 0x7f;
384
385 if (*ucblocks == 0x7f)
386 *ucblocks = 0xffffffff; /* counter overflow... */
387
388 ves1x93_writereg (state, 0x18, 0x00); /* reset the counter */
389 ves1x93_writereg (state, 0x18, 0x80); /* dto. */
390
391 return 0;
392}
393
394static int ves1x93_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
395{
396 struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv;
397
398 ves1x93_writereg(state, 0x00, 0x11);
399 state->config->pll_set(fe, p);
400 ves1x93_writereg(state, 0x00, 0x01);
401 ves1x93_set_inversion (state, p->inversion);
402 ves1x93_set_fec (state, p->u.qpsk.fec_inner);
403 ves1x93_set_symbolrate (state, p->u.qpsk.symbol_rate);
404 state->inversion = p->inversion;
405
406 return 0;
407}
408
409static int ves1x93_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
410{
411 struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv;
412 int afc;
413
414 afc = ((int)((char)(ves1x93_readreg (state, 0x0a) << 1)))/2;
415 afc = (afc * (int)(p->u.qpsk.symbol_rate/1000/8))/16;
416
417 p->frequency -= afc;
418
419 /*
420 * inversion indicator is only valid
421 * if auto inversion was used
422 */
423 if (state->inversion == INVERSION_AUTO)
424 p->inversion = (ves1x93_readreg (state, 0x0f) & 2) ?
425 INVERSION_OFF : INVERSION_ON;
426 p->u.qpsk.fec_inner = ves1x93_get_fec (state);
427 /* XXX FIXME: timing offset !! */
428
429 return 0;
430}
431
432static int ves1x93_sleep(struct dvb_frontend* fe)
433{
434 struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv;
435
436 return ves1x93_writereg (state, 0x00, 0x08);
437}
438
439static void ves1x93_release(struct dvb_frontend* fe)
440{
441 struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv;
442 kfree(state);
443}
444
445static struct dvb_frontend_ops ves1x93_ops;
446
447struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config,
448 struct i2c_adapter* i2c)
449{
450 struct ves1x93_state* state = NULL;
451 u8 identity;
452
453 /* allocate memory for the internal state */
454 state = (struct ves1x93_state*) kmalloc(sizeof(struct ves1x93_state), GFP_KERNEL);
455 if (state == NULL) goto error;
456
457 /* setup the state */
458 state->config = config;
459 state->i2c = i2c;
460 memcpy(&state->ops, &ves1x93_ops, sizeof(struct dvb_frontend_ops));
461 state->inversion = INVERSION_OFF;
462
463 /* check if the demod is there + identify it */
464 identity = ves1x93_readreg(state, 0x1e);
465 switch (identity) {
466 case 0xdc: /* VES1893A rev1 */
467 printk("ves1x93: Detected ves1893a rev1\n");
468 state->demod_type = DEMOD_VES1893;
469 state->init_1x93_tab = init_1893_tab;
470 state->init_1x93_wtab = init_1893_wtab;
471 state->tab_size = sizeof(init_1893_tab);
472 break;
473
474 case 0xdd: /* VES1893A rev2 */
475 printk("ves1x93: Detected ves1893a rev2\n");
476 state->demod_type = DEMOD_VES1893;
477 state->init_1x93_tab = init_1893_tab;
478 state->init_1x93_wtab = init_1893_wtab;
479 state->tab_size = sizeof(init_1893_tab);
480 break;
481
482 case 0xde: /* VES1993 */
483 printk("ves1x93: Detected ves1993\n");
484 state->demod_type = DEMOD_VES1993;
485 state->init_1x93_tab = init_1993_tab;
486 state->init_1x93_wtab = init_1993_wtab;
487 state->tab_size = sizeof(init_1993_tab);
488 break;
489
490 default:
491 goto error;
492 }
493
494 /* create dvb_frontend */
495 state->frontend.ops = &state->ops;
496 state->frontend.demodulator_priv = state;
497 return &state->frontend;
498
499error:
500 kfree(state);
501 return NULL;
502}
503
504static struct dvb_frontend_ops ves1x93_ops = {
505
506 .info = {
507 .name = "VLSI VES1x93 DVB-S",
508 .type = FE_QPSK,
509 .frequency_min = 950000,
510 .frequency_max = 2150000,
511 .frequency_stepsize = 125, /* kHz for QPSK frontends */
512 .frequency_tolerance = 29500,
513 .symbol_rate_min = 1000000,
514 .symbol_rate_max = 45000000,
515 /* .symbol_rate_tolerance = ???,*/
516 .caps = FE_CAN_INVERSION_AUTO |
517 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
518 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
519 FE_CAN_QPSK
520 },
521
522 .release = ves1x93_release,
523
524 .init = ves1x93_init,
525 .sleep = ves1x93_sleep,
526
527 .set_frontend = ves1x93_set_frontend,
528 .get_frontend = ves1x93_get_frontend,
529
530 .read_status = ves1x93_read_status,
531 .read_ber = ves1x93_read_ber,
532 .read_signal_strength = ves1x93_read_signal_strength,
533 .read_snr = ves1x93_read_snr,
534 .read_ucblocks = ves1x93_read_ucblocks,
535
536 .set_voltage = ves1x93_set_voltage,
537};
538
539module_param(debug, int, 0644);
540
541MODULE_DESCRIPTION("VLSI VES1x93 DVB-S Demodulator driver");
542MODULE_AUTHOR("Ralph Metzler");
543MODULE_LICENSE("GPL");
544
545EXPORT_SYMBOL(ves1x93_attach);
diff --git a/drivers/media/dvb/frontends/ves1x93.h b/drivers/media/dvb/frontends/ves1x93.h
new file mode 100644
index 000000000000..1627e37c57a4
--- /dev/null
+++ b/drivers/media/dvb/frontends/ves1x93.h
@@ -0,0 +1,50 @@
1/*
2 Driver for VES1893 and VES1993 QPSK Demodulators
3
4 Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
5 Copyright (C) 2001 Ronny Strutz <3des@elitedvb.de>
6 Copyright (C) 2002 Dennis Noermann <dennis.noermann@noernet.de>
7 Copyright (C) 2002-2003 Andreas Oberritter <obi@linuxtv.org>
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23
24*/
25
26#ifndef VES1X93_H
27#define VES1X93_H
28
29#include <linux/dvb/frontend.h>
30
31struct ves1x93_config
32{
33 /* the demodulator's i2c address */
34 u8 demod_address;
35
36 /* value of XIN to use */
37 u32 xin;
38
39 /* should PWM be inverted? */
40 u8 invert_pwm:1;
41
42 /* PLL maintenance */
43 int (*pll_init)(struct dvb_frontend* fe);
44 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
45};
46
47extern struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config,
48 struct i2c_adapter* i2c);
49
50#endif // VES1X93_H