treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 371
[linux-2.6-block.git] / drivers / media / dvb-frontends / tda10021.c
CommitLineData
74ba9207 1// SPDX-License-Identifier: GPL-2.0-or-later
1da177e4
LT
2/*
3 TDA10021 - Single Chip Cable Channel Receiver driver module
59c51591 4 used on the Siemens DVB-C cards
1da177e4
LT
5
6 Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
7 Copyright (C) 2004 Markus Schulz <msc@antzsystem.de>
9101e622 8 Support for TDA10021
1da177e4 9
1da177e4
LT
10*/
11
1da177e4
LT
12#include <linux/delay.h>
13#include <linux/errno.h>
14#include <linux/init.h>
15#include <linux/kernel.h>
16#include <linux/module.h>
17#include <linux/string.h>
18#include <linux/slab.h>
19
fada1935 20#include <media/dvb_frontend.h>
aa323ac8 21#include "tda1002x.h"
1da177e4
LT
22
23
24struct tda10021_state {
25 struct i2c_adapter* i2c;
1da177e4 26 /* configuration settings */
aa323ac8 27 const struct tda1002x_config* config;
1da177e4
LT
28 struct dvb_frontend frontend;
29
30 u8 pwm;
31 u8 reg0;
32};
33
34
35#if 0
36#define dprintk(x...) printk(x)
37#else
38#define dprintk(x...)
39#endif
40
41static int verbose;
42
43#define XIN 57840000UL
1da177e4
LT
44
45#define FIN (XIN >> 4)
46
47static int tda10021_inittab_size = 0x40;
48static u8 tda10021_inittab[0x40]=
49{
50 0x73, 0x6a, 0x23, 0x0a, 0x02, 0x37, 0x77, 0x1a,
51 0x37, 0x6a, 0x17, 0x8a, 0x1e, 0x86, 0x43, 0x40,
fd9c66e2 52 0xb8, 0x3f, 0xa1, 0x00, 0xcd, 0x01, 0x00, 0xff,
1da177e4
LT
53 0x11, 0x00, 0x7c, 0x31, 0x30, 0x20, 0x00, 0x00,
54 0x02, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x00,
55 0x07, 0x00, 0x33, 0x11, 0x0d, 0x95, 0x08, 0x58,
56 0x00, 0x00, 0x80, 0x00, 0x80, 0xff, 0x00, 0x00,
57 0x04, 0x2d, 0x2f, 0xff, 0x00, 0x00, 0x00, 0x00,
58};
59
c10d14d6 60static int _tda10021_writereg (struct tda10021_state* state, u8 reg, u8 data)
1da177e4 61{
9101e622 62 u8 buf[] = { reg, data };
1da177e4 63 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
9101e622 64 int ret;
1da177e4
LT
65
66 ret = i2c_transfer (state->i2c, &msg, 1);
67 if (ret != 1)
4bd69e7b 68 printk("DVB: TDA10021(%d): %s, writereg error (reg == 0x%02x, val == 0x%02x, ret == %i)\n",
271ddbf7 69 state->frontend.dvb->num, __func__, reg, data, ret);
1da177e4
LT
70
71 msleep(10);
72 return (ret != 1) ? -EREMOTEIO : 0;
73}
74
75static u8 tda10021_readreg (struct tda10021_state* state, u8 reg)
76{
77 u8 b0 [] = { reg };
78 u8 b1 [] = { 0 };
79 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
50c25fff 80 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
1da177e4
LT
81 int ret;
82
83 ret = i2c_transfer (state->i2c, msg, 2);
dc120b07
HB
84 // Don't print an error message if the id is read.
85 if (ret != 2 && reg != 0x1a)
88bdcc5d 86 printk("DVB: TDA10021: %s: readreg error (ret == %i)\n",
271ddbf7 87 __func__, ret);
1da177e4
LT
88 return b1[0];
89}
90
91//get access to tuner
92static int lock_tuner(struct tda10021_state* state)
93{
94 u8 buf[2] = { 0x0f, tda10021_inittab[0x0f] | 0x80 };
95 struct i2c_msg msg = {.addr=state->config->demod_address, .flags=0, .buf=buf, .len=2};
96
97 if(i2c_transfer(state->i2c, &msg, 1) != 1)
98 {
99 printk("tda10021: lock tuner fails\n");
100 return -EREMOTEIO;
101 }
102 return 0;
103}
104
105//release access from tuner
106static int unlock_tuner(struct tda10021_state* state)
107{
108 u8 buf[2] = { 0x0f, tda10021_inittab[0x0f] & 0x7f };
109 struct i2c_msg msg_post={.addr=state->config->demod_address, .flags=0, .buf=buf, .len=2};
110
111 if(i2c_transfer(state->i2c, &msg_post, 1) != 1)
112 {
113 printk("tda10021: unlock tuner fails\n");
114 return -EREMOTEIO;
115 }
116 return 0;
117}
118
0df289a2
MCC
119static int tda10021_setup_reg0(struct tda10021_state *state, u8 reg0,
120 enum fe_spectral_inversion inversion)
1da177e4
LT
121{
122 reg0 |= state->reg0 & 0x63;
123
dc120b07
HB
124 if ((INVERSION_ON == inversion) ^ (state->config->invert == 0))
125 reg0 &= ~0x20;
126 else
127 reg0 |= 0x20;
1da177e4 128
c10d14d6
AQ
129 _tda10021_writereg (state, 0x00, reg0 & 0xfe);
130 _tda10021_writereg (state, 0x00, reg0 | 0x01);
1da177e4
LT
131
132 state->reg0 = reg0;
133 return 0;
134}
135
136static int tda10021_set_symbolrate (struct tda10021_state* state, u32 symbolrate)
137{
138 s32 BDR;
139 s32 BDRI;
140 s16 SFIL=0;
141 u16 NDEC = 0;
142 u32 tmp, ratio;
143
144 if (symbolrate > XIN/2)
145 symbolrate = XIN/2;
146 if (symbolrate < 500000)
147 symbolrate = 500000;
148
149 if (symbolrate < XIN/16) NDEC = 1;
150 if (symbolrate < XIN/32) NDEC = 2;
151 if (symbolrate < XIN/64) NDEC = 3;
152
153 if (symbolrate < (u32)(XIN/12.3)) SFIL = 1;
154 if (symbolrate < (u32)(XIN/16)) SFIL = 0;
155 if (symbolrate < (u32)(XIN/24.6)) SFIL = 1;
156 if (symbolrate < (u32)(XIN/32)) SFIL = 0;
157 if (symbolrate < (u32)(XIN/49.2)) SFIL = 1;
158 if (symbolrate < (u32)(XIN/64)) SFIL = 0;
159 if (symbolrate < (u32)(XIN/98.4)) SFIL = 1;
160
161 symbolrate <<= NDEC;
162 ratio = (symbolrate << 4) / FIN;
163 tmp = ((symbolrate << 4) % FIN) << 8;
164 ratio = (ratio << 8) + tmp / FIN;
165 tmp = (tmp % FIN) << 8;
75b697f7 166 ratio = (ratio << 8) + DIV_ROUND_CLOSEST(tmp, FIN);
1da177e4
LT
167
168 BDR = ratio;
169 BDRI = (((XIN << 5) / symbolrate) + 1) / 2;
170
171 if (BDRI > 0xFF)
172 BDRI = 0xFF;
173
174 SFIL = (SFIL << 4) | tda10021_inittab[0x0E];
175
176 NDEC = (NDEC << 6) | tda10021_inittab[0x03];
177
c10d14d6
AQ
178 _tda10021_writereg (state, 0x03, NDEC);
179 _tda10021_writereg (state, 0x0a, BDR&0xff);
180 _tda10021_writereg (state, 0x0b, (BDR>> 8)&0xff);
181 _tda10021_writereg (state, 0x0c, (BDR>>16)&0x3f);
1da177e4 182
c10d14d6
AQ
183 _tda10021_writereg (state, 0x0d, BDRI);
184 _tda10021_writereg (state, 0x0e, SFIL);
1da177e4
LT
185
186 return 0;
187}
188
189static int tda10021_init (struct dvb_frontend *fe)
190{
b8742700 191 struct tda10021_state* state = fe->demodulator_priv;
1da177e4
LT
192 int i;
193
194 dprintk("DVB: TDA10021(%d): init chip\n", fe->adapter->num);
195
c10d14d6 196 //_tda10021_writereg (fe, 0, 0);
1da177e4
LT
197
198 for (i=0; i<tda10021_inittab_size; i++)
c10d14d6 199 _tda10021_writereg (state, i, tda10021_inittab[i]);
1da177e4 200
c10d14d6 201 _tda10021_writereg (state, 0x34, state->pwm);
1da177e4
LT
202
203 //Comment by markus
204 //0x2A[3-0] == PDIV -> P multiplaying factor (P=PDIV+1)(default 0)
205 //0x2A[4] == BYPPLL -> Power down mode (default 1)
206 //0x2A[5] == LCK -> PLL Lock Flag
207 //0x2A[6] == POLAXIN -> Polarity of the input reference clock (default 0)
208
209 //Activate PLL
c10d14d6 210 _tda10021_writereg(state, 0x2a, tda10021_inittab[0x2a] & 0xef);
1da177e4
LT
211 return 0;
212}
213
27d9a5e9
MCC
214struct qam_params {
215 u8 conf, agcref, lthr, mseth, aref;
216};
217
7826bcd5 218static int tda10021_set_parameters(struct dvb_frontend *fe)
1da177e4 219{
1a5cd296
MCC
220 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
221 u32 delsys = c->delivery_system;
222 unsigned qam = c->modulation;
223 bool is_annex_c;
224 u32 reg0x3d;
b8742700 225 struct tda10021_state* state = fe->demodulator_priv;
27d9a5e9
MCC
226 static const struct qam_params qam_params[] = {
227 /* Modulation Conf AGCref LTHR MSETH AREF */
228 [QPSK] = { 0x14, 0x78, 0x78, 0x8c, 0x96 },
229 [QAM_16] = { 0x00, 0x8c, 0x87, 0xa2, 0x91 },
230 [QAM_32] = { 0x04, 0x8c, 0x64, 0x74, 0x96 },
231 [QAM_64] = { 0x08, 0x6a, 0x46, 0x43, 0x6a },
232 [QAM_128] = { 0x0c, 0x78, 0x36, 0x34, 0x7e },
233 [QAM_256] = { 0x10, 0x5c, 0x26, 0x23, 0x6b },
234 };
1a5cd296
MCC
235
236 switch (delsys) {
237 case SYS_DVBC_ANNEX_A:
238 is_annex_c = false;
239 break;
240 case SYS_DVBC_ANNEX_C:
241 is_annex_c = true;
242 break;
243 default:
244 return -EINVAL;
245 }
1da177e4 246
27d9a5e9 247 /*
5a13e40b 248 * gcc optimizes the code below the same way as it would code:
27d9a5e9
MCC
249 * "if (qam > 5) return -EINVAL;"
250 * Yet, the code is clearer, as it shows what QAM standards are
251 * supported by the driver, and avoids the usage of magic numbers on
252 * it.
253 */
254 switch (qam) {
255 case QPSK:
256 case QAM_16:
257 case QAM_32:
258 case QAM_64:
259 case QAM_128:
260 case QAM_256:
261 break;
262 default:
1da177e4 263 return -EINVAL;
27d9a5e9 264 }
1da177e4 265
1a5cd296 266 if (c->inversion != INVERSION_ON && c->inversion != INVERSION_OFF)
dc120b07
HB
267 return -EINVAL;
268
7826bcd5 269 /*printk("tda10021: set frequency to %d qam=%d symrate=%d\n", p->frequency,qam,p->symbol_rate);*/
1da177e4 270
dea74869 271 if (fe->ops.tuner_ops.set_params) {
14d24d14 272 fe->ops.tuner_ops.set_params(fe);
dea74869 273 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
f1e80919 274 }
1da177e4 275
1a5cd296 276 tda10021_set_symbolrate(state, c->symbol_rate);
27d9a5e9 277 _tda10021_writereg(state, 0x34, state->pwm);
1da177e4 278
27d9a5e9
MCC
279 _tda10021_writereg(state, 0x01, qam_params[qam].agcref);
280 _tda10021_writereg(state, 0x05, qam_params[qam].lthr);
281 _tda10021_writereg(state, 0x08, qam_params[qam].mseth);
282 _tda10021_writereg(state, 0x09, qam_params[qam].aref);
1a5cd296
MCC
283
284 /*
285 * Bit 0 == 0 means roll-off = 0.15 (Annex A)
286 * == 1 means roll-off = 0.13 (Annex C)
287 */
288 reg0x3d = tda10021_readreg (state, 0x3d);
289 if (is_annex_c)
290 _tda10021_writereg (state, 0x3d, 0x01 | reg0x3d);
291 else
292 _tda10021_writereg (state, 0x3d, 0xfe & reg0x3d);
293 tda10021_setup_reg0(state, qam_params[qam].conf, c->inversion);
1da177e4
LT
294
295 return 0;
296}
297
0df289a2
MCC
298static int tda10021_read_status(struct dvb_frontend *fe,
299 enum fe_status *status)
1da177e4 300{
b8742700 301 struct tda10021_state* state = fe->demodulator_priv;
1da177e4
LT
302 int sync;
303
304 *status = 0;
305 //0x11[0] == EQALGO -> Equalizer algorithms state
306 //0x11[1] == CARLOCK -> Carrier locked
307 //0x11[2] == FSYNC -> Frame synchronisation
308 //0x11[3] == FEL -> Front End locked
309 //0x11[6] == NODVB -> DVB Mode Information
310 sync = tda10021_readreg (state, 0x11);
311
312 if (sync & 2)
313 *status |= FE_HAS_SIGNAL|FE_HAS_CARRIER;
314
315 if (sync & 4)
316 *status |= FE_HAS_SYNC|FE_HAS_VITERBI;
317
318 if (sync & 8)
319 *status |= FE_HAS_LOCK;
320
321 return 0;
322}
323
324static int tda10021_read_ber(struct dvb_frontend* fe, u32* ber)
325{
b8742700 326 struct tda10021_state* state = fe->demodulator_priv;
1da177e4
LT
327
328 u32 _ber = tda10021_readreg(state, 0x14) |
329 (tda10021_readreg(state, 0x15) << 8) |
330 ((tda10021_readreg(state, 0x16) & 0x0f) << 16);
3de0e18b
HB
331 _tda10021_writereg(state, 0x10, (tda10021_readreg(state, 0x10) & ~0xc0)
332 | (tda10021_inittab[0x10] & 0xc0));
1da177e4
LT
333 *ber = 10 * _ber;
334
335 return 0;
336}
337
338static int tda10021_read_signal_strength(struct dvb_frontend* fe, u16* strength)
339{
b8742700 340 struct tda10021_state* state = fe->demodulator_priv;
1da177e4 341
7cccccc3 342 u8 config = tda10021_readreg(state, 0x02);
1da177e4 343 u8 gain = tda10021_readreg(state, 0x17);
7cccccc3
HB
344 if (config & 0x02)
345 /* the agc value is inverted */
346 gain = ~gain;
1da177e4
LT
347 *strength = (gain << 8) | gain;
348
349 return 0;
350}
351
352static int tda10021_read_snr(struct dvb_frontend* fe, u16* snr)
353{
b8742700 354 struct tda10021_state* state = fe->demodulator_priv;
1da177e4
LT
355
356 u8 quality = ~tda10021_readreg(state, 0x18);
357 *snr = (quality << 8) | quality;
358
359 return 0;
360}
361
362static int tda10021_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
363{
b8742700 364 struct tda10021_state* state = fe->demodulator_priv;
1da177e4
LT
365
366 *ucblocks = tda10021_readreg (state, 0x13) & 0x7f;
367 if (*ucblocks == 0x7f)
368 *ucblocks = 0xffffffff;
369
370 /* reset uncorrected block counter */
c10d14d6
AQ
371 _tda10021_writereg (state, 0x10, tda10021_inittab[0x10] & 0xdf);
372 _tda10021_writereg (state, 0x10, tda10021_inittab[0x10]);
1da177e4
LT
373
374 return 0;
375}
376
7e3e68bc
MCC
377static int tda10021_get_frontend(struct dvb_frontend *fe,
378 struct dtv_frontend_properties *p)
1da177e4 379{
b8742700 380 struct tda10021_state* state = fe->demodulator_priv;
1da177e4
LT
381 int sync;
382 s8 afc = 0;
383
384 sync = tda10021_readreg(state, 0x11);
385 afc = tda10021_readreg(state, 0x19);
386 if (verbose) {
387 /* AFC only valid when carrier has been recovered */
388 printk(sync & 2 ? "DVB: TDA10021(%d): AFC (%d) %dHz\n" :
389 "DVB: TDA10021(%d): [AFC (%d) %dHz]\n",
390 state->frontend.dvb->num, afc,
7826bcd5 391 -((s32)p->symbol_rate * afc) >> 10);
1da177e4
LT
392 }
393
dc120b07 394 p->inversion = ((state->reg0 & 0x20) == 0x20) ^ (state->config->invert != 0) ? INVERSION_ON : INVERSION_OFF;
7826bcd5 395 p->modulation = ((state->reg0 >> 2) & 7) + QAM_16;
1da177e4 396
7826bcd5 397 p->fec_inner = FEC_NONE;
1da177e4
LT
398 p->frequency = ((p->frequency + 31250) / 62500) * 62500;
399
400 if (sync & 2)
7826bcd5 401 p->frequency -= ((s32)p->symbol_rate * afc) >> 10;
1da177e4
LT
402
403 return 0;
404}
405
f1e80919
AQ
406static int tda10021_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
407{
408 struct tda10021_state* state = fe->demodulator_priv;
409
410 if (enable) {
411 lock_tuner(state);
412 } else {
413 unlock_tuner(state);
414 }
415 return 0;
416}
417
1da177e4
LT
418static int tda10021_sleep(struct dvb_frontend* fe)
419{
b8742700 420 struct tda10021_state* state = fe->demodulator_priv;
1da177e4 421
c10d14d6
AQ
422 _tda10021_writereg (state, 0x1b, 0x02); /* pdown ADC */
423 _tda10021_writereg (state, 0x00, 0x80); /* standby */
1da177e4
LT
424
425 return 0;
426}
427
428static void tda10021_release(struct dvb_frontend* fe)
429{
b8742700 430 struct tda10021_state* state = fe->demodulator_priv;
1da177e4
LT
431 kfree(state);
432}
433
bd336e63 434static const struct dvb_frontend_ops tda10021_ops;
1da177e4 435
aa323ac8 436struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config,
1da177e4
LT
437 struct i2c_adapter* i2c,
438 u8 pwm)
439{
440 struct tda10021_state* state = NULL;
dc120b07 441 u8 id;
1da177e4
LT
442
443 /* allocate memory for the internal state */
084e24ac 444 state = kzalloc(sizeof(struct tda10021_state), GFP_KERNEL);
1da177e4
LT
445 if (state == NULL) goto error;
446
447 /* setup the state */
448 state->config = config;
449 state->i2c = i2c;
1da177e4
LT
450 state->pwm = pwm;
451 state->reg0 = tda10021_inittab[0];
452
453 /* check if the demod is there */
dc120b07
HB
454 id = tda10021_readreg(state, 0x1a);
455 if ((id & 0xf0) != 0x70) goto error;
456
4af699c1
NE
457 /* Don't claim TDA10023 */
458 if (id == 0x7d)
459 goto error;
460
dc120b07
HB
461 printk("TDA10021: i2c-addr = 0x%02x, id = 0x%02x\n",
462 state->config->demod_address, id);
1da177e4
LT
463
464 /* create dvb_frontend */
dea74869 465 memcpy(&state->frontend.ops, &tda10021_ops, sizeof(struct dvb_frontend_ops));
1da177e4
LT
466 state->frontend.demodulator_priv = state;
467 return &state->frontend;
468
469error:
470 kfree(state);
471 return NULL;
472}
473
bd336e63 474static const struct dvb_frontend_ops tda10021_ops = {
7826bcd5 475 .delsys = { SYS_DVBC_ANNEX_A, SYS_DVBC_ANNEX_C },
1da177e4
LT
476 .info = {
477 .name = "Philips TDA10021 DVB-C",
f1b1eabf
MCC
478 .frequency_min_hz = 47 * MHz,
479 .frequency_max_hz = 862 * MHz,
480 .frequency_stepsize_hz = 62500,
481 .symbol_rate_min = (XIN / 2) / 64, /* SACLK/64 == (XIN/2)/64 */
482 .symbol_rate_max = (XIN / 2) / 4, /* SACLK/4 */
acf28212 483 #if 0
1da177e4
LT
484 .frequency_tolerance = ???,
485 .symbol_rate_tolerance = ???, /* ppm */ /* == 8% (spec p. 5) */
486 #endif
487 .caps = 0x400 | //FE_CAN_QAM_4
488 FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
489 FE_CAN_QAM_128 | FE_CAN_QAM_256 |
490 FE_CAN_FEC_AUTO
491 },
492
493 .release = tda10021_release,
494
495 .init = tda10021_init,
496 .sleep = tda10021_sleep,
f1e80919 497 .i2c_gate_ctrl = tda10021_i2c_gate_ctrl,
1da177e4 498
7826bcd5
MCC
499 .set_frontend = tda10021_set_parameters,
500 .get_frontend = tda10021_get_frontend,
1da177e4
LT
501
502 .read_status = tda10021_read_status,
503 .read_ber = tda10021_read_ber,
504 .read_signal_strength = tda10021_read_signal_strength,
505 .read_snr = tda10021_read_snr,
506 .read_ucblocks = tda10021_read_ucblocks,
507};
508
509module_param(verbose, int, 0644);
510MODULE_PARM_DESC(verbose, "print AFC offset after tuning for debugging the PWM setting");
511
512MODULE_DESCRIPTION("Philips TDA10021 DVB-C demodulator driver");
513MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Markus Schulz");
514MODULE_LICENSE("GPL");
515
516EXPORT_SYMBOL(tda10021_attach);