Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
[linux-2.6-block.git] / drivers / media / dvb-frontends / l64781.c
CommitLineData
74ba9207 1// SPDX-License-Identifier: GPL-2.0-or-later
1da177e4
LT
2/*
3 driver for LSI L64781 COFDM demodulator
4
5 Copyright (C) 2001 Holger Waechtler for Convergence Integrated Media GmbH
9101e622 6 Marko Kohtala <marko.kohtala@luukku.com>
1da177e4 7
1da177e4
LT
8
9*/
10
11#include <linux/init.h>
12#include <linux/kernel.h>
13#include <linux/module.h>
1da177e4
LT
14#include <linux/string.h>
15#include <linux/slab.h>
fada1935 16#include <media/dvb_frontend.h>
1da177e4
LT
17#include "l64781.h"
18
19
20struct l64781_state {
21 struct i2c_adapter* i2c;
1da177e4
LT
22 const struct l64781_config* config;
23 struct dvb_frontend frontend;
24
25 /* private demodulator data */
940cc2df 26 unsigned int first:1;
1da177e4
LT
27};
28
29#define dprintk(args...) \
30 do { \
31 if (debug) printk(KERN_DEBUG "l64781: " args); \
32 } while (0)
33
34static int debug;
35
36module_param(debug, int, 0644);
37MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
38
39
40static int l64781_writereg (struct l64781_state* state, u8 reg, u8 data)
41{
42 int ret;
43 u8 buf [] = { reg, data };
44 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
45
46 if ((ret = i2c_transfer(state->i2c, &msg, 1)) != 1)
47 dprintk ("%s: write_reg error (reg == %02x) = %02x!\n",
271ddbf7 48 __func__, reg, ret);
1da177e4
LT
49
50 return (ret != 1) ? -1 : 0;
51}
52
53static int l64781_readreg (struct l64781_state* state, u8 reg)
54{
55 int ret;
56 u8 b0 [] = { reg };
57 u8 b1 [] = { 0 };
58 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
59 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
60
61 ret = i2c_transfer(state->i2c, msg, 2);
62
63 if (ret != 2) return ret;
64
65 return b1[0];
66}
67
68static void apply_tps (struct l64781_state* state)
69{
70 l64781_writereg (state, 0x2a, 0x00);
71 l64781_writereg (state, 0x2a, 0x01);
72
73 /* This here is a little bit questionable because it enables
74 the automatic update of TPS registers. I think we'd need to
75 handle the IRQ from FE to update some other registers as
76 well, or at least implement some magic to tuning to correct
77 to the TPS received from transmission. */
78 l64781_writereg (state, 0x2a, 0x02);
79}
80
81
82static void reset_afc (struct l64781_state* state)
83{
84 /* Set AFC stall for the AFC_INIT_FRQ setting, TIM_STALL for
85 timing offset */
86 l64781_writereg (state, 0x07, 0x9e); /* stall AFC */
87 l64781_writereg (state, 0x08, 0); /* AFC INIT FREQ */
88 l64781_writereg (state, 0x09, 0);
89 l64781_writereg (state, 0x0a, 0);
90 l64781_writereg (state, 0x07, 0x8e);
91 l64781_writereg (state, 0x0e, 0); /* AGC gain to zero in beginning */
92 l64781_writereg (state, 0x11, 0x80); /* stall TIM */
93 l64781_writereg (state, 0x10, 0); /* TIM_OFFSET_LSB */
94 l64781_writereg (state, 0x12, 0);
95 l64781_writereg (state, 0x13, 0);
96 l64781_writereg (state, 0x11, 0x00);
97}
98
99static int reset_and_configure (struct l64781_state* state)
100{
101 u8 buf [] = { 0x06 };
102 struct i2c_msg msg = { .addr = 0x00, .flags = 0, .buf = buf, .len = 1 };
103 // NOTE: this is correct in writing to address 0x00
104
105 return (i2c_transfer(state->i2c, &msg, 1) == 1) ? 0 : -ENODEV;
106}
107
2de5f412 108static int apply_frontend_param(struct dvb_frontend *fe)
1da177e4 109{
2de5f412 110 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
b8742700 111 struct l64781_state* state = fe->demodulator_priv;
1da177e4
LT
112 /* The coderates for FEC_NONE, FEC_4_5 and FEC_FEC_6_7 are arbitrary */
113 static const u8 fec_tab[] = { 7, 0, 1, 2, 9, 3, 10, 4 };
114 /* QPSK, QAM_16, QAM_64 */
115 static const u8 qam_tab [] = { 2, 4, 0, 6 };
1da177e4
LT
116 static const u8 guard_tab [] = { 1, 2, 4, 8 };
117 /* The Grundig 29504-401.04 Tuner comes with 18.432MHz crystal. */
118 static const u32 ppm = 8000;
1da177e4
LT
119 u32 ddfs_offset_fixed;
120/* u32 ddfs_offset_variable = 0x6000-((1000000UL+ppm)/ */
121/* bw_tab[p->bandWidth]<<10)/15625; */
122 u32 init_freq;
123 u32 spi_bias;
124 u8 val0x04;
125 u8 val0x05;
126 u8 val0x06;
2de5f412
MCC
127 int bw;
128
129 switch (p->bandwidth_hz) {
130 case 8000000:
131 bw = 8;
132 break;
133 case 7000000:
134 bw = 7;
135 break;
136 case 6000000:
137 bw = 6;
138 break;
139 default:
140 return -EINVAL;
141 }
1da177e4 142
dea74869 143 if (fe->ops.tuner_ops.set_params) {
14d24d14 144 fe->ops.tuner_ops.set_params(fe);
dea74869 145 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
b800aae3 146 }
1da177e4 147
2de5f412
MCC
148 if (p->inversion != INVERSION_ON &&
149 p->inversion != INVERSION_OFF)
1da177e4
LT
150 return -EINVAL;
151
152 if (p->code_rate_HP != FEC_1_2 && p->code_rate_HP != FEC_2_3 &&
153 p->code_rate_HP != FEC_3_4 && p->code_rate_HP != FEC_5_6 &&
154 p->code_rate_HP != FEC_7_8)
155 return -EINVAL;
156
2de5f412 157 if (p->hierarchy != HIERARCHY_NONE &&
1da177e4
LT
158 (p->code_rate_LP != FEC_1_2 && p->code_rate_LP != FEC_2_3 &&
159 p->code_rate_LP != FEC_3_4 && p->code_rate_LP != FEC_5_6 &&
160 p->code_rate_LP != FEC_7_8))
161 return -EINVAL;
162
2de5f412
MCC
163 if (p->modulation != QPSK && p->modulation != QAM_16 &&
164 p->modulation != QAM_64)
1da177e4
LT
165 return -EINVAL;
166
167 if (p->transmission_mode != TRANSMISSION_MODE_2K &&
168 p->transmission_mode != TRANSMISSION_MODE_8K)
169 return -EINVAL;
170
830e4b55 171 if ((int)p->guard_interval < GUARD_INTERVAL_1_32 ||
1da177e4
LT
172 p->guard_interval > GUARD_INTERVAL_1_4)
173 return -EINVAL;
174
830e4b55 175 if ((int)p->hierarchy < HIERARCHY_NONE ||
2de5f412 176 p->hierarchy > HIERARCHY_4)
1da177e4
LT
177 return -EINVAL;
178
2de5f412 179 ddfs_offset_fixed = 0x4000-(ppm<<16)/bw/1000000;
1da177e4
LT
180
181 /* This works up to 20000 ppm, it overflows if too large ppm! */
182 init_freq = (((8UL<<25) + (8UL<<19) / 25*ppm / (15625/25)) /
2de5f412 183 bw & 0xFFFFFF);
1da177e4
LT
184
185 /* SPI bias calculation is slightly modified to fit in 32bit */
186 /* will work for high ppm only... */
187 spi_bias = 378 * (1 << 10);
188 spi_bias *= 16;
2de5f412
MCC
189 spi_bias *= bw;
190 spi_bias *= qam_tab[p->modulation];
1da177e4
LT
191 spi_bias /= p->code_rate_HP + 1;
192 spi_bias /= (guard_tab[p->guard_interval] + 32);
c1db53b3
RG
193 spi_bias *= 1000;
194 spi_bias /= 1000 + ppm/1000;
1da177e4
LT
195 spi_bias *= p->code_rate_HP;
196
197 val0x04 = (p->transmission_mode << 2) | p->guard_interval;
198 val0x05 = fec_tab[p->code_rate_HP];
199
2de5f412 200 if (p->hierarchy != HIERARCHY_NONE)
1da177e4
LT
201 val0x05 |= (p->code_rate_LP - FEC_1_2) << 3;
202
2de5f412 203 val0x06 = (p->hierarchy << 2) | p->modulation;
1da177e4
LT
204
205 l64781_writereg (state, 0x04, val0x04);
206 l64781_writereg (state, 0x05, val0x05);
207 l64781_writereg (state, 0x06, val0x06);
208
209 reset_afc (state);
210
211 /* Technical manual section 2.6.1, TIM_IIR_GAIN optimal values */
212 l64781_writereg (state, 0x15,
213 p->transmission_mode == TRANSMISSION_MODE_2K ? 1 : 3);
214 l64781_writereg (state, 0x16, init_freq & 0xff);
215 l64781_writereg (state, 0x17, (init_freq >> 8) & 0xff);
216 l64781_writereg (state, 0x18, (init_freq >> 16) & 0xff);
217
218 l64781_writereg (state, 0x1b, spi_bias & 0xff);
219 l64781_writereg (state, 0x1c, (spi_bias >> 8) & 0xff);
220 l64781_writereg (state, 0x1d, ((spi_bias >> 16) & 0x7f) |
2de5f412 221 (p->inversion == INVERSION_ON ? 0x80 : 0x00));
1da177e4
LT
222
223 l64781_writereg (state, 0x22, ddfs_offset_fixed & 0xff);
224 l64781_writereg (state, 0x23, (ddfs_offset_fixed >> 8) & 0x3f);
225
226 l64781_readreg (state, 0x00); /* clear interrupt registers... */
227 l64781_readreg (state, 0x01); /* dto. */
228
229 apply_tps (state);
230
231 return 0;
232}
233
7e3e68bc
MCC
234static int get_frontend(struct dvb_frontend *fe,
235 struct dtv_frontend_properties *p)
1da177e4 236{
b8742700 237 struct l64781_state* state = fe->demodulator_priv;
1da177e4
LT
238 int tmp;
239
240
241 tmp = l64781_readreg(state, 0x04);
242 switch(tmp & 3) {
243 case 0:
2de5f412 244 p->guard_interval = GUARD_INTERVAL_1_32;
1da177e4
LT
245 break;
246 case 1:
2de5f412 247 p->guard_interval = GUARD_INTERVAL_1_16;
1da177e4
LT
248 break;
249 case 2:
2de5f412 250 p->guard_interval = GUARD_INTERVAL_1_8;
1da177e4
LT
251 break;
252 case 3:
2de5f412 253 p->guard_interval = GUARD_INTERVAL_1_4;
1da177e4
LT
254 break;
255 }
256 switch((tmp >> 2) & 3) {
257 case 0:
2de5f412 258 p->transmission_mode = TRANSMISSION_MODE_2K;
1da177e4
LT
259 break;
260 case 1:
2de5f412 261 p->transmission_mode = TRANSMISSION_MODE_8K;
1da177e4
LT
262 break;
263 default:
2de5f412 264 printk(KERN_WARNING "Unexpected value for transmission_mode\n");
1da177e4
LT
265 }
266
1da177e4
LT
267 tmp = l64781_readreg(state, 0x05);
268 switch(tmp & 7) {
269 case 0:
2de5f412 270 p->code_rate_HP = FEC_1_2;
1da177e4
LT
271 break;
272 case 1:
2de5f412 273 p->code_rate_HP = FEC_2_3;
1da177e4
LT
274 break;
275 case 2:
2de5f412 276 p->code_rate_HP = FEC_3_4;
1da177e4
LT
277 break;
278 case 3:
2de5f412 279 p->code_rate_HP = FEC_5_6;
1da177e4
LT
280 break;
281 case 4:
2de5f412 282 p->code_rate_HP = FEC_7_8;
1da177e4
LT
283 break;
284 default:
285 printk("Unexpected value for code_rate_HP\n");
286 }
287 switch((tmp >> 3) & 7) {
288 case 0:
2de5f412 289 p->code_rate_LP = FEC_1_2;
1da177e4
LT
290 break;
291 case 1:
2de5f412 292 p->code_rate_LP = FEC_2_3;
1da177e4
LT
293 break;
294 case 2:
2de5f412 295 p->code_rate_LP = FEC_3_4;
1da177e4
LT
296 break;
297 case 3:
2de5f412 298 p->code_rate_LP = FEC_5_6;
1da177e4
LT
299 break;
300 case 4:
2de5f412 301 p->code_rate_LP = FEC_7_8;
1da177e4
LT
302 break;
303 default:
304 printk("Unexpected value for code_rate_LP\n");
305 }
306
1da177e4
LT
307 tmp = l64781_readreg(state, 0x06);
308 switch(tmp & 3) {
309 case 0:
2de5f412 310 p->modulation = QPSK;
1da177e4
LT
311 break;
312 case 1:
2de5f412 313 p->modulation = QAM_16;
1da177e4
LT
314 break;
315 case 2:
2de5f412 316 p->modulation = QAM_64;
1da177e4
LT
317 break;
318 default:
2de5f412 319 printk(KERN_WARNING "Unexpected value for modulation\n");
1da177e4
LT
320 }
321 switch((tmp >> 2) & 7) {
322 case 0:
2de5f412 323 p->hierarchy = HIERARCHY_NONE;
1da177e4
LT
324 break;
325 case 1:
2de5f412 326 p->hierarchy = HIERARCHY_1;
1da177e4
LT
327 break;
328 case 2:
2de5f412 329 p->hierarchy = HIERARCHY_2;
1da177e4
LT
330 break;
331 case 3:
2de5f412 332 p->hierarchy = HIERARCHY_4;
1da177e4
LT
333 break;
334 default:
335 printk("Unexpected value for hierarchy\n");
336 }
337
338
339 tmp = l64781_readreg (state, 0x1d);
2de5f412 340 p->inversion = (tmp & 0x80) ? INVERSION_ON : INVERSION_OFF;
1da177e4
LT
341
342 tmp = (int) (l64781_readreg (state, 0x08) |
343 (l64781_readreg (state, 0x09) << 8) |
344 (l64781_readreg (state, 0x0a) << 16));
2de5f412 345 p->frequency += tmp;
1da177e4
LT
346
347 return 0;
348}
349
0df289a2 350static int l64781_read_status(struct dvb_frontend *fe, enum fe_status *status)
1da177e4 351{
b8742700 352 struct l64781_state* state = fe->demodulator_priv;
1da177e4
LT
353 int sync = l64781_readreg (state, 0x32);
354 int gain = l64781_readreg (state, 0x0e);
355
356 l64781_readreg (state, 0x00); /* clear interrupt registers... */
357 l64781_readreg (state, 0x01); /* dto. */
358
359 *status = 0;
360
361 if (gain > 5)
362 *status |= FE_HAS_SIGNAL;
363
364 if (sync & 0x02) /* VCXO locked, this criteria should be ok */
365 *status |= FE_HAS_CARRIER;
366
367 if (sync & 0x20)
368 *status |= FE_HAS_VITERBI;
369
370 if (sync & 0x40)
371 *status |= FE_HAS_SYNC;
372
373 if (sync == 0x7f)
374 *status |= FE_HAS_LOCK;
375
376 return 0;
377}
378
379static int l64781_read_ber(struct dvb_frontend* fe, u32* ber)
380{
b8742700 381 struct l64781_state* state = fe->demodulator_priv;
1da177e4
LT
382
383 /* XXX FIXME: set up counting period (reg 0x26...0x28)
384 */
385 *ber = l64781_readreg (state, 0x39)
386 | (l64781_readreg (state, 0x3a) << 8);
387
388 return 0;
389}
390
391static int l64781_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
392{
b8742700 393 struct l64781_state* state = fe->demodulator_priv;
1da177e4
LT
394
395 u8 gain = l64781_readreg (state, 0x0e);
396 *signal_strength = (gain << 8) | gain;
397
398 return 0;
399}
400
401static int l64781_read_snr(struct dvb_frontend* fe, u16* snr)
402{
b8742700 403 struct l64781_state* state = fe->demodulator_priv;
1da177e4
LT
404
405 u8 avg_quality = 0xff - l64781_readreg (state, 0x33);
406 *snr = (avg_quality << 8) | avg_quality; /* not exact, but...*/
407
408 return 0;
409}
410
411static int l64781_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
412{
b8742700 413 struct l64781_state* state = fe->demodulator_priv;
1da177e4
LT
414
415 *ucblocks = l64781_readreg (state, 0x37)
416 | (l64781_readreg (state, 0x38) << 8);
417
418 return 0;
419}
420
421static int l64781_sleep(struct dvb_frontend* fe)
422{
b8742700 423 struct l64781_state* state = fe->demodulator_priv;
1da177e4
LT
424
425 /* Power down */
426 return l64781_writereg (state, 0x3e, 0x5a);
427}
428
429static int l64781_init(struct dvb_frontend* fe)
430{
b8742700 431 struct l64781_state* state = fe->demodulator_priv;
1da177e4 432
9101e622 433 reset_and_configure (state);
1da177e4
LT
434
435 /* Power up */
436 l64781_writereg (state, 0x3e, 0xa5);
437
438 /* Reset hard */
439 l64781_writereg (state, 0x2a, 0x04);
440 l64781_writereg (state, 0x2a, 0x00);
441
442 /* Set tuner specific things */
443 /* AFC_POL, set also in reset_afc */
444 l64781_writereg (state, 0x07, 0x8e);
445
446 /* Use internal ADC */
447 l64781_writereg (state, 0x0b, 0x81);
448
449 /* AGC loop gain, and polarity is positive */
450 l64781_writereg (state, 0x0c, 0x84);
451
452 /* Internal ADC outputs two's complement */
453 l64781_writereg (state, 0x0d, 0x8c);
454
455 /* With ppm=8000, it seems the DTR_SENSITIVITY will result in
9101e622
MCC
456 value of 2 with all possible bandwidths and guard
457 intervals, which is the initial value anyway. */
458 /*l64781_writereg (state, 0x19, 0x92);*/
1da177e4
LT
459
460 /* Everything is two's complement, soft bit and CSI_OUT too */
461 l64781_writereg (state, 0x1e, 0x09);
462
1da177e4
LT
463 /* delay a bit after first init attempt */
464 if (state->first) {
465 state->first = 0;
466 msleep(200);
467 }
468
469 return 0;
470}
471
80064b80
JS
472static int l64781_get_tune_settings(struct dvb_frontend* fe,
473 struct dvb_frontend_tune_settings* fesettings)
1da177e4 474{
9101e622
MCC
475 fesettings->min_delay_ms = 4000;
476 fesettings->step_size = 0;
477 fesettings->max_drift = 0;
478 return 0;
1da177e4
LT
479}
480
481static void l64781_release(struct dvb_frontend* fe)
482{
b8742700 483 struct l64781_state* state = fe->demodulator_priv;
1da177e4
LT
484 kfree(state);
485}
486
bd336e63 487static const struct dvb_frontend_ops l64781_ops;
1da177e4
LT
488
489struct dvb_frontend* l64781_attach(const struct l64781_config* config,
490 struct i2c_adapter* i2c)
491{
492 struct l64781_state* state = NULL;
493 int reg0x3e = -1;
494 u8 b0 [] = { 0x1a };
495 u8 b1 [] = { 0x00 };
496 struct i2c_msg msg [] = { { .addr = config->demod_address, .flags = 0, .buf = b0, .len = 1 },
497 { .addr = config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
498
499 /* allocate memory for the internal state */
084e24ac 500 state = kzalloc(sizeof(struct l64781_state), GFP_KERNEL);
1da177e4
LT
501 if (state == NULL) goto error;
502
503 /* setup the state */
504 state->config = config;
505 state->i2c = i2c;
1da177e4
LT
506 state->first = 1;
507
b95b0c98 508 /*
1da177e4
LT
509 * the L64781 won't show up before we send the reset_and_configure()
510 * broadcast. If nothing responds there is no L64781 on the bus...
511 */
512 if (reset_and_configure(state) < 0) {
513 dprintk("No response to reset and configure broadcast...\n");
514 goto error;
515 }
516
517 /* The chip always responds to reads */
518 if (i2c_transfer(state->i2c, msg, 2) != 2) {
9101e622 519 dprintk("No response to read on I2C bus\n");
1da177e4
LT
520 goto error;
521 }
522
523 /* Save current register contents for bailout */
524 reg0x3e = l64781_readreg(state, 0x3e);
525
526 /* Reading the POWER_DOWN register always returns 0 */
527 if (reg0x3e != 0) {
9101e622 528 dprintk("Device doesn't look like L64781\n");
1da177e4
LT
529 goto error;
530 }
531
532 /* Turn the chip off */
533 l64781_writereg (state, 0x3e, 0x5a);
534
535 /* Responds to all reads with 0 */
536 if (l64781_readreg(state, 0x1a) != 0) {
715b703d 537 dprintk("Read 1 returned unexpected value\n");
1da177e4
LT
538 goto error;
539 }
540
541 /* Turn the chip on */
542 l64781_writereg (state, 0x3e, 0xa5);
543
544 /* Responds with register default value */
545 if (l64781_readreg(state, 0x1a) != 0xa1) {
715b703d 546 dprintk("Read 2 returned unexpected value\n");
1da177e4
LT
547 goto error;
548 }
549
550 /* create dvb_frontend */
dea74869 551 memcpy(&state->frontend.ops, &l64781_ops, sizeof(struct dvb_frontend_ops));
1da177e4
LT
552 state->frontend.demodulator_priv = state;
553 return &state->frontend;
554
555error:
2ea75330
JJ
556 if (reg0x3e >= 0)
557 l64781_writereg (state, 0x3e, reg0x3e); /* restore reg 0x3e */
1da177e4
LT
558 kfree(state);
559 return NULL;
560}
561
bd336e63 562static const struct dvb_frontend_ops l64781_ops = {
2de5f412 563 .delsys = { SYS_DVBT },
1da177e4
LT
564 .info = {
565 .name = "LSI L64781 DVB-T",
f1b1eabf
MCC
566 /* .frequency_min_hz = ???,*/
567 /* .frequency_max_hz = ???,*/
568 .frequency_stepsize_hz = 166666,
1da177e4
LT
569 /* .symbol_rate_tolerance = ???,*/
570 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
571 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
572 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
573 FE_CAN_MUTE_TS
574 },
575
576 .release = l64781_release,
577
578 .init = l64781_init,
579 .sleep = l64781_sleep,
580
2de5f412
MCC
581 .set_frontend = apply_frontend_param,
582 .get_frontend = get_frontend,
1da177e4
LT
583 .get_tune_settings = l64781_get_tune_settings,
584
585 .read_status = l64781_read_status,
586 .read_ber = l64781_read_ber,
587 .read_signal_strength = l64781_read_signal_strength,
588 .read_snr = l64781_read_snr,
589 .read_ucblocks = l64781_read_ucblocks,
590};
591
592MODULE_DESCRIPTION("LSI L64781 DVB-T Demodulator driver");
593MODULE_AUTHOR("Holger Waechtler, Marko Kohtala");
594MODULE_LICENSE("GPL");
595
596EXPORT_SYMBOL(l64781_attach);