diff options
author | Adrian Bunk <bunk@stusta.de> | 2006-02-07 03:49:15 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2006-02-07 03:55:43 -0500 |
commit | ed2099293627a1f6220c711b265528128f8ad50e (patch) | |
tree | ed49eac05dca9be25c1917c203d06ad4be07f526 | |
parent | 62b2c00addf2e7d441c4f29e2dd804110b9d9475 (diff) |
V4L/DVB (3318e): DVB: remove the at76c651/tda80xx frontends
The at76c651 and tda80xx frontends are currently completely unused, IOW
their only effect is making the kernel larger for people accitentially
enabling them.
The current in-kernel drivers differ from the drivers at cvs.tuxbox.org,
and re-adding them when parts of the dbox2 project get merged should be
trivial.
Signed-off-by: Adrian Bunk <bunk@stusta.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
-rw-r--r-- | drivers/media/dvb/frontends/Kconfig | 12 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/Makefile | 2 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/at76c651.c | 450 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/at76c651.h | 47 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/tda80xx.c | 734 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/tda80xx.h | 51 |
6 files changed, 0 insertions, 1296 deletions
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index f09e3da669fe..76b6a2aef32f 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig | |||
@@ -28,12 +28,6 @@ config DVB_TDA8083 | |||
28 | help | 28 | help |
29 | A DVB-S tuner module. Say Y when you want to support this frontend. | 29 | A DVB-S tuner module. Say Y when you want to support this frontend. |
30 | 30 | ||
31 | config DVB_TDA80XX | ||
32 | tristate "Philips TDA8044 or TDA8083 based" | ||
33 | depends on DVB_CORE | ||
34 | help | ||
35 | A DVB-S tuner module. Say Y when you want to support this frontend. | ||
36 | |||
37 | config DVB_MT312 | 31 | config DVB_MT312 |
38 | tristate "Zarlink MT312 based" | 32 | tristate "Zarlink MT312 based" |
39 | depends on DVB_CORE | 33 | depends on DVB_CORE |
@@ -139,12 +133,6 @@ config DVB_DIB3000MC | |||
139 | comment "DVB-C (cable) frontends" | 133 | comment "DVB-C (cable) frontends" |
140 | depends on DVB_CORE | 134 | depends on DVB_CORE |
141 | 135 | ||
142 | config DVB_ATMEL_AT76C651 | ||
143 | tristate "Atmel AT76C651 based" | ||
144 | depends on DVB_CORE | ||
145 | help | ||
146 | A DVB-C tuner module. Say Y when you want to support this frontend. | ||
147 | |||
148 | config DVB_VES1820 | 136 | config DVB_VES1820 |
149 | tristate "VLSI VES1820 based" | 137 | tristate "VLSI VES1820 based" |
150 | depends on DVB_CORE | 138 | depends on DVB_CORE |
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile index 8f301468568d..1af769cd90c0 100644 --- a/drivers/media/dvb/frontends/Makefile +++ b/drivers/media/dvb/frontends/Makefile | |||
@@ -8,7 +8,6 @@ obj-$(CONFIG_DVB_CORE) += dvb-pll.o | |||
8 | obj-$(CONFIG_DVB_STV0299) += stv0299.o | 8 | obj-$(CONFIG_DVB_STV0299) += stv0299.o |
9 | obj-$(CONFIG_DVB_SP8870) += sp8870.o | 9 | obj-$(CONFIG_DVB_SP8870) += sp8870.o |
10 | obj-$(CONFIG_DVB_CX22700) += cx22700.o | 10 | obj-$(CONFIG_DVB_CX22700) += cx22700.o |
11 | obj-$(CONFIG_DVB_ATMEL_AT76C651) += at76c651.o | ||
12 | obj-$(CONFIG_DVB_CX24110) += cx24110.o | 11 | obj-$(CONFIG_DVB_CX24110) += cx24110.o |
13 | obj-$(CONFIG_DVB_TDA8083) += tda8083.o | 12 | obj-$(CONFIG_DVB_TDA8083) += tda8083.o |
14 | obj-$(CONFIG_DVB_L64781) += l64781.o | 13 | obj-$(CONFIG_DVB_L64781) += l64781.o |
@@ -22,7 +21,6 @@ obj-$(CONFIG_DVB_SP887X) += sp887x.o | |||
22 | obj-$(CONFIG_DVB_NXT6000) += nxt6000.o | 21 | obj-$(CONFIG_DVB_NXT6000) += nxt6000.o |
23 | obj-$(CONFIG_DVB_MT352) += mt352.o | 22 | obj-$(CONFIG_DVB_MT352) += mt352.o |
24 | obj-$(CONFIG_DVB_CX22702) += cx22702.o | 23 | obj-$(CONFIG_DVB_CX22702) += cx22702.o |
25 | obj-$(CONFIG_DVB_TDA80XX) += tda80xx.o | ||
26 | obj-$(CONFIG_DVB_TDA10021) += tda10021.o | 24 | obj-$(CONFIG_DVB_TDA10021) += tda10021.o |
27 | obj-$(CONFIG_DVB_STV0297) += stv0297.o | 25 | obj-$(CONFIG_DVB_STV0297) += stv0297.o |
28 | obj-$(CONFIG_DVB_NXT200X) += nxt200x.o | 26 | obj-$(CONFIG_DVB_NXT200X) += nxt200x.o |
diff --git a/drivers/media/dvb/frontends/at76c651.c b/drivers/media/dvb/frontends/at76c651.c deleted file mode 100644 index 8e0f4b3a1417..000000000000 --- a/drivers/media/dvb/frontends/at76c651.c +++ /dev/null | |||
@@ -1,450 +0,0 @@ | |||
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 | |||
40 | struct 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 | |||
57 | static 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__) | ||
65 | static __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 | |||
79 | static 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 | |||
98 | static 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 = ®, .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 | |||
115 | static int at76c651_reset(struct at76c651_state* state) | ||
116 | { | ||
117 | return at76c651_writereg(state, 0x07, 0x01); | ||
118 | } | ||
119 | |||
120 | static void at76c651_disable_interrupts(struct at76c651_state* state) | ||
121 | { | ||
122 | at76c651_writereg(state, 0x0b, 0x00); | ||
123 | } | ||
124 | |||
125 | static 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 | |||
166 | static void at76c651_set_bbfreq(struct at76c651_state* state) | ||
167 | { | ||
168 | at76c651_writereg(state, 0x04, 0x3f); | ||
169 | at76c651_writereg(state, 0x05, 0xee); | ||
170 | } | ||
171 | |||
172 | static 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 | |||
196 | static 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 | |||
233 | static 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 | |||
258 | static int at76c651_set_parameters(struct dvb_frontend* fe, | ||
259 | struct dvb_frontend_parameters *p) | ||
260 | { | ||
261 | int ret; | ||
262 | struct at76c651_state* 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 | |||
277 | static int at76c651_set_defaults(struct dvb_frontend* fe) | ||
278 | { | ||
279 | struct at76c651_state* 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 | |||
295 | static int at76c651_read_status(struct dvb_frontend* fe, fe_status_t* status) | ||
296 | { | ||
297 | struct at76c651_state* 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 | |||
320 | static int at76c651_read_ber(struct dvb_frontend* fe, u32* ber) | ||
321 | { | ||
322 | struct at76c651_state* 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 | |||
332 | static int at76c651_read_signal_strength(struct dvb_frontend* fe, u16* strength) | ||
333 | { | ||
334 | struct at76c651_state* state = fe->demodulator_priv; | ||
335 | |||
336 | u8 gain = ~at76c651_readreg(state, 0x91); | ||
337 | *strength = (gain << 8) | gain; | ||
338 | |||
339 | return 0; | ||
340 | } | ||
341 | |||
342 | static int at76c651_read_snr(struct dvb_frontend* fe, u16* snr) | ||
343 | { | ||
344 | struct at76c651_state* 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 | |||
353 | static int at76c651_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | ||
354 | { | ||
355 | struct at76c651_state* state = fe->demodulator_priv; | ||
356 | |||
357 | *ucblocks = at76c651_readreg(state, 0x82); | ||
358 | |||
359 | return 0; | ||
360 | } | ||
361 | |||
362 | static 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 | |||
370 | static void at76c651_release(struct dvb_frontend* fe) | ||
371 | { | ||
372 | struct at76c651_state* state = fe->demodulator_priv; | ||
373 | kfree(state); | ||
374 | } | ||
375 | |||
376 | static struct dvb_frontend_ops at76c651_ops; | ||
377 | |||
378 | struct 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 = 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 | |||
404 | error: | ||
405 | kfree(state); | ||
406 | return NULL; | ||
407 | } | ||
408 | |||
409 | static 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 | |||
443 | module_param(debug, int, 0644); | ||
444 | MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); | ||
445 | |||
446 | MODULE_DESCRIPTION("Atmel AT76C651 DVB-C Demodulator Driver"); | ||
447 | MODULE_AUTHOR("Andreas Oberritter <obi@linuxtv.org>"); | ||
448 | MODULE_LICENSE("GPL"); | ||
449 | |||
450 | EXPORT_SYMBOL(at76c651_attach); | ||
diff --git a/drivers/media/dvb/frontends/at76c651.h b/drivers/media/dvb/frontends/at76c651.h deleted file mode 100644 index 34054df93608..000000000000 --- a/drivers/media/dvb/frontends/at76c651.h +++ /dev/null | |||
@@ -1,47 +0,0 @@ | |||
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 | |||
34 | struct 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 | |||
44 | extern 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/tda80xx.c b/drivers/media/dvb/frontends/tda80xx.c deleted file mode 100644 index d1cabb6a0a13..000000000000 --- a/drivers/media/dvb/frontends/tda80xx.c +++ /dev/null | |||
@@ -1,734 +0,0 @@ | |||
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 <linux/kernel.h> | ||
31 | #include <linux/module.h> | ||
32 | #include <linux/slab.h> | ||
33 | #include <asm/irq.h> | ||
34 | #include <asm/div64.h> | ||
35 | |||
36 | #include "dvb_frontend.h" | ||
37 | #include "tda80xx.h" | ||
38 | |||
39 | enum { | ||
40 | ID_TDA8044 = 0x04, | ||
41 | ID_TDA8083 = 0x05, | ||
42 | }; | ||
43 | |||
44 | |||
45 | struct 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 | |||
65 | static int debug = 1; | ||
66 | #define dprintk if (debug) printk | ||
67 | |||
68 | static 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 | |||
77 | static 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 | |||
86 | static 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 | |||
95 | static __inline__ u32 tda80xx_div(u32 a, u32 b) | ||
96 | { | ||
97 | return (a + (b / 2)) / b; | ||
98 | } | ||
99 | |||
100 | static __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 | |||
112 | static 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 = ®, .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 | |||
129 | static 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 | |||
148 | static __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 | |||
157 | static __inline__ int tda80xx_writereg(struct tda80xx_state* state, u8 reg, u8 data) | ||
158 | { | ||
159 | return tda80xx_write(state, reg, &data, 1); | ||
160 | } | ||
161 | |||
162 | static 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 | |||
292 | static 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 | ||
305 | static 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 | |||
312 | static 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 | |||
324 | static irqreturn_t tda80xx_irq(int irq, void *priv, struct pt_regs *pt) | ||
325 | { | ||
326 | schedule_work(priv); | ||
327 | |||
328 | return IRQ_HANDLED; | ||
329 | } | ||
330 | |||
331 | static 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 | |||
380 | static 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 | |||
390 | static 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 | |||
401 | static int tda8044_init(struct dvb_frontend* fe) | ||
402 | { | ||
403 | struct tda80xx_state* 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 | |||
433 | static int tda8083_init(struct dvb_frontend* fe) | ||
434 | { | ||
435 | struct tda80xx_state* 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 | |||
448 | static int tda80xx_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) | ||
449 | { | ||
450 | struct tda80xx_state* 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 | |||
464 | static int tda80xx_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) | ||
465 | { | ||
466 | struct tda80xx_state* 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 | |||
478 | static int tda80xx_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd) | ||
479 | { | ||
480 | struct tda80xx_state* 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 | |||
493 | static int tda80xx_send_diseqc_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t cmd) | ||
494 | { | ||
495 | struct tda80xx_state* 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 | |||
513 | static int tda80xx_sleep(struct dvb_frontend* fe) | ||
514 | { | ||
515 | struct tda80xx_state* state = fe->demodulator_priv; | ||
516 | |||
517 | tda80xx_writereg(state, 0x00, 0x02); /* enter standby */ | ||
518 | |||
519 | return 0; | ||
520 | } | ||
521 | |||
522 | static int tda80xx_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | ||
523 | { | ||
524 | struct tda80xx_state* 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 | |||
538 | static int tda80xx_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | ||
539 | { | ||
540 | struct tda80xx_state* 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 | |||
551 | static int tda80xx_read_status(struct dvb_frontend* fe, fe_status_t* status) | ||
552 | { | ||
553 | struct tda80xx_state* 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 | |||
562 | static int tda80xx_read_ber(struct dvb_frontend* fe, u32* ber) | ||
563 | { | ||
564 | struct tda80xx_state* 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 | |||
576 | static int tda80xx_read_signal_strength(struct dvb_frontend* fe, u16* strength) | ||
577 | { | ||
578 | struct tda80xx_state* state = fe->demodulator_priv; | ||
579 | |||
580 | u8 gain = ~tda80xx_readreg(state, 0x01); | ||
581 | *strength = (gain << 8) | gain; | ||
582 | |||
583 | return 0; | ||
584 | } | ||
585 | |||
586 | static int tda80xx_read_snr(struct dvb_frontend* fe, u16* snr) | ||
587 | { | ||
588 | struct tda80xx_state* state = fe->demodulator_priv; | ||
589 | |||
590 | u8 quality = tda80xx_readreg(state, 0x08); | ||
591 | *snr = (quality << 8) | quality; | ||
592 | |||
593 | return 0; | ||
594 | } | ||
595 | |||
596 | static int tda80xx_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | ||
597 | { | ||
598 | struct tda80xx_state* state = fe->demodulator_priv; | ||
599 | |||
600 | *ucblocks = tda80xx_readreg(state, 0x0f); | ||
601 | if (*ucblocks == 0xff) | ||
602 | *ucblocks = 0xffffffff; | ||
603 | |||
604 | return 0; | ||
605 | } | ||
606 | |||
607 | static int tda80xx_init(struct dvb_frontend* fe) | ||
608 | { | ||
609 | struct tda80xx_state* 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 | |||
621 | static void tda80xx_release(struct dvb_frontend* fe) | ||
622 | { | ||
623 | struct tda80xx_state* state = fe->demodulator_priv; | ||
624 | |||
625 | if (state->config->irq) | ||
626 | free_irq(state->config->irq, &state->worklet); | ||
627 | |||
628 | kfree(state); | ||
629 | } | ||
630 | |||
631 | static struct dvb_frontend_ops tda80xx_ops; | ||
632 | |||
633 | struct 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 = 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 | |||
685 | error: | ||
686 | kfree(state); | ||
687 | return NULL; | ||
688 | } | ||
689 | |||
690 | static 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 | |||
728 | module_param(debug, int, 0644); | ||
729 | |||
730 | MODULE_DESCRIPTION("Philips TDA8044 / TDA8083 DVB-S Demodulator driver"); | ||
731 | MODULE_AUTHOR("Felix Domke, Andreas Oberritter"); | ||
732 | MODULE_LICENSE("GPL"); | ||
733 | |||
734 | EXPORT_SYMBOL(tda80xx_attach); | ||
diff --git a/drivers/media/dvb/frontends/tda80xx.h b/drivers/media/dvb/frontends/tda80xx.h deleted file mode 100644 index cd639a0aad55..000000000000 --- a/drivers/media/dvb/frontends/tda80xx.h +++ /dev/null | |||
@@ -1,51 +0,0 @@ | |||
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 | |||
29 | struct 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 | |||
48 | extern struct dvb_frontend* tda80xx_attach(const struct tda80xx_config* config, | ||
49 | struct i2c_adapter* i2c); | ||
50 | |||
51 | #endif // TDA80XX_H | ||