2 driver for Grundig 29504-401 DVB-T Frontends based on
3 LSI L64781 COFDM demodulator as used in Technotrend DVB-T cards
5 Copyright (C) 2001 Holger Waechtler <holger@convergence.de>
6 for Convergence Integrated Media GmbH
7 Marko Kohtala <marko.kohtala@nokia.com>
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.
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.
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.
25 #include <linux/init.h>
26 #include <linux/kernel.h>
27 #include <linux/module.h>
28 #include <linux/string.h>
29 #include <linux/slab.h>
31 #include "dvb_frontend.h"
32 #include "dvb_functions.h"
36 #define dprintk if (debug) printk
38 struct grundig_state {
42 struct dvb_frontend_info grundig_29504_401_info = {
43 .name = "Grundig 29504-401",
45 /* .frequency_min = ???,*/
46 /* .frequency_max = ???,*/
47 .frequency_stepsize = 166666,
48 /* .frequency_tolerance = ???,*/
49 /* .symbol_rate_tolerance = ???,*/
51 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
52 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
53 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
58 static int l64781_writereg (struct dvb_i2c_bus *i2c, u8 reg, u8 data)
61 u8 buf [] = { reg, data };
62 struct i2c_msg msg = { .addr = 0x55, .flags = 0, .buf = buf, .len = 2 };
64 if ((ret = i2c->xfer (i2c, &msg, 1)) != 1)
65 dprintk ("%s: write_reg error (reg == %02x) = %02x!\n",
66 __FUNCTION__, reg, ret);
68 return (ret != 1) ? -1 : 0;
72 static u8 l64781_readreg (struct dvb_i2c_bus *i2c, u8 reg)
77 struct i2c_msg msg [] = { { .addr = 0x55, .flags = 0, .buf = b0, .len = 1 },
78 { .addr = 0x55, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
80 ret = i2c->xfer (i2c, msg, 2);
83 dprintk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret);
89 static int tsa5060_write (struct dvb_i2c_bus *i2c, u8 data [4])
92 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = 4 };
94 if ((ret = i2c->xfer (i2c, &msg, 1)) != 1)
95 dprintk ("%s: write_reg error == %02x!\n", __FUNCTION__, ret);
97 return (ret != 1) ? -1 : 0;
102 * set up the downconverter frequency divisor for a
103 * reference clock comparision frequency of 166666 Hz.
104 * frequency offset is 36125000 Hz.
106 static int tsa5060_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq)
111 u8 cfg, cpump, band_select;
113 div = (36125000 + freq) / 166666;
116 cpump = freq < 175000000 ? 2 : freq < 390000000 ? 1 :
117 freq < 470000000 ? 2 : freq < 750000000 ? 1 : 3;
119 band_select = freq < 175000000 ? 0x0e : freq < 470000000 ? 0x05 : 0x03;
121 buf [0] = (div >> 8) & 0x7f;
122 buf [1] = div & 0xff;
123 buf [2] = ((div >> 10) & 0x60) | cfg;
124 buf [3] = (cpump << 6) | band_select;
126 /* old code which seems to work better for at least one person */
131 div = (36000000 + freq) / 166666;
134 buf [0] = (div >> 8) & 0x7f;
135 buf [1] = div & 0xff;
136 buf [2] = ((div >> 10) & 0x60) | cfg;
140 return tsa5060_write (i2c, buf);
144 static void apply_tps (struct dvb_i2c_bus *i2c)
146 l64781_writereg (i2c, 0x2a, 0x00);
147 l64781_writereg (i2c, 0x2a, 0x01);
149 /* This here is a little bit questionable because it enables
150 the automatic update of TPS registers. I think we'd need to
151 handle the IRQ from FE to update some other registers as
152 well, or at least implement some magic to tuning to correct
153 to the TPS received from transmission. */
154 l64781_writereg (i2c, 0x2a, 0x02);
158 static void reset_afc (struct dvb_i2c_bus *i2c)
160 /* Set AFC stall for the AFC_INIT_FRQ setting, TIM_STALL for
162 l64781_writereg (i2c, 0x07, 0x9e); /* stall AFC */
163 l64781_writereg (i2c, 0x08, 0); /* AFC INIT FREQ */
164 l64781_writereg (i2c, 0x09, 0);
165 l64781_writereg (i2c, 0x0a, 0);
166 l64781_writereg (i2c, 0x07, 0x8e);
167 l64781_writereg (i2c, 0x0e, 0); /* AGC gain to zero in beginning */
168 l64781_writereg (i2c, 0x11, 0x80); /* stall TIM */
169 l64781_writereg (i2c, 0x10, 0); /* TIM_OFFSET_LSB */
170 l64781_writereg (i2c, 0x12, 0);
171 l64781_writereg (i2c, 0x13, 0);
172 l64781_writereg (i2c, 0x11, 0x00);
176 static int apply_frontend_param (struct dvb_i2c_bus *i2c,
177 struct dvb_frontend_parameters *param)
179 /* The coderates for FEC_NONE, FEC_4_5 and FEC_FEC_6_7 are arbitrary */
180 static const u8 fec_tab[] = { 7, 0, 1, 2, 9, 3, 10, 4 };
181 /* QPSK, QAM_16, QAM_64 */
182 static const u8 qam_tab [] = { 2, 4, 0, 6 };
183 static const u8 bw_tab [] = { 8, 7, 6 }; /* 8Mhz, 7MHz, 6MHz */
184 static const u8 guard_tab [] = { 1, 2, 4, 8 };
185 /* The Grundig 29504-401.04 Tuner comes with 18.432MHz crystal. */
186 static const u32 ppm = 8000;
187 struct dvb_ofdm_parameters *p = ¶m->u.ofdm;
188 u32 ddfs_offset_fixed;
189 /* u32 ddfs_offset_variable = 0x6000-((1000000UL+ppm)/ */
190 /* bw_tab[p->bandWidth]<<10)/15625; */
196 int bw = p->bandwidth - BANDWIDTH_8_MHZ;
198 if (param->inversion != INVERSION_ON &&
199 param->inversion != INVERSION_OFF)
202 if (bw < 0 || bw > 2)
205 if (p->code_rate_HP != FEC_1_2 && p->code_rate_HP != FEC_2_3 &&
206 p->code_rate_HP != FEC_3_4 && p->code_rate_HP != FEC_5_6 &&
207 p->code_rate_HP != FEC_7_8)
210 if (p->hierarchy_information != HIERARCHY_NONE &&
211 (p->code_rate_LP != FEC_1_2 && p->code_rate_LP != FEC_2_3 &&
212 p->code_rate_LP != FEC_3_4 && p->code_rate_LP != FEC_5_6 &&
213 p->code_rate_LP != FEC_7_8))
216 if (p->constellation != QPSK && p->constellation != QAM_16 &&
217 p->constellation != QAM_64)
220 if (p->transmission_mode != TRANSMISSION_MODE_2K &&
221 p->transmission_mode != TRANSMISSION_MODE_8K)
224 if (p->guard_interval < GUARD_INTERVAL_1_32 ||
225 p->guard_interval > GUARD_INTERVAL_1_4)
228 if (p->hierarchy_information < HIERARCHY_NONE ||
229 p->hierarchy_information > HIERARCHY_4)
232 ddfs_offset_fixed = 0x4000-(ppm<<16)/bw_tab[p->bandwidth]/1000000;
234 /* This works up to 20000 ppm, it overflows if too large ppm! */
235 init_freq = (((8UL<<25) + (8UL<<19) / 25*ppm / (15625/25)) /
236 bw_tab[p->bandwidth] & 0xFFFFFF);
238 /* SPI bias calculation is slightly modified to fit in 32bit */
239 /* will work for high ppm only... */
240 spi_bias = 378 * (1 << 10);
242 spi_bias *= bw_tab[p->bandwidth];
243 spi_bias *= qam_tab[p->constellation];
244 spi_bias /= p->code_rate_HP + 1;
245 spi_bias /= (guard_tab[p->guard_interval] + 32);
247 spi_bias /= 1000ULL + ppm/1000;
248 spi_bias *= p->code_rate_HP;
250 val0x04 = (p->transmission_mode << 2) | p->guard_interval;
251 val0x05 = fec_tab[p->code_rate_HP];
253 if (p->hierarchy_information != HIERARCHY_NONE)
254 val0x05 |= (p->code_rate_LP - FEC_1_2) << 3;
256 val0x06 = (p->hierarchy_information << 2) | p->constellation;
258 l64781_writereg (i2c, 0x04, val0x04);
259 l64781_writereg (i2c, 0x05, val0x05);
260 l64781_writereg (i2c, 0x06, val0x06);
264 /* Technical manual section 2.6.1, TIM_IIR_GAIN optimal values */
265 l64781_writereg (i2c, 0x15,
266 p->transmission_mode == TRANSMISSION_MODE_2K ? 1 : 3);
267 l64781_writereg (i2c, 0x16, init_freq & 0xff);
268 l64781_writereg (i2c, 0x17, (init_freq >> 8) & 0xff);
269 l64781_writereg (i2c, 0x18, (init_freq >> 16) & 0xff);
271 l64781_writereg (i2c, 0x1b, spi_bias & 0xff);
272 l64781_writereg (i2c, 0x1c, (spi_bias >> 8) & 0xff);
273 l64781_writereg (i2c, 0x1d, ((spi_bias >> 16) & 0x7f) |
274 (param->inversion == INVERSION_ON ? 0x80 : 0x00));
276 l64781_writereg (i2c, 0x22, ddfs_offset_fixed & 0xff);
277 l64781_writereg (i2c, 0x23, (ddfs_offset_fixed >> 8) & 0x3f);
279 l64781_readreg (i2c, 0x00); /* clear interrupt registers... */
280 l64781_readreg (i2c, 0x01); /* dto. */
288 static int reset_and_configure (struct dvb_i2c_bus *i2c)
290 u8 buf [] = { 0x06 };
291 struct i2c_msg msg = { .addr = 0x00, .flags = 0, .buf = buf, .len = 1 };
293 return (i2c->xfer (i2c, &msg, 1) == 1) ? 0 : -ENODEV;
297 static int get_frontend(struct dvb_i2c_bus* i2c, struct dvb_frontend_parameters* param)
302 tmp = l64781_readreg(i2c, 0x04);
305 param->u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
308 param->u.ofdm.guard_interval = GUARD_INTERVAL_1_16;
311 param->u.ofdm.guard_interval = GUARD_INTERVAL_1_8;
314 param->u.ofdm.guard_interval = GUARD_INTERVAL_1_4;
317 switch((tmp >> 2) & 3) {
319 param->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K;
322 param->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
325 printk("Unexpected value for transmission_mode\n");
330 tmp = l64781_readreg(i2c, 0x05);
333 param->u.ofdm.code_rate_HP = FEC_1_2;
336 param->u.ofdm.code_rate_HP = FEC_2_3;
339 param->u.ofdm.code_rate_HP = FEC_3_4;
342 param->u.ofdm.code_rate_HP = FEC_5_6;
345 param->u.ofdm.code_rate_HP = FEC_7_8;
348 printk("Unexpected value for code_rate_HP\n");
350 switch((tmp >> 3) & 7) {
352 param->u.ofdm.code_rate_LP = FEC_1_2;
355 param->u.ofdm.code_rate_LP = FEC_2_3;
358 param->u.ofdm.code_rate_LP = FEC_3_4;
361 param->u.ofdm.code_rate_LP = FEC_5_6;
364 param->u.ofdm.code_rate_LP = FEC_7_8;
367 printk("Unexpected value for code_rate_LP\n");
371 tmp = l64781_readreg(i2c, 0x06);
374 param->u.ofdm.constellation = QPSK;
377 param->u.ofdm.constellation = QAM_16;
380 param->u.ofdm.constellation = QAM_64;
383 printk("Unexpected value for constellation\n");
385 switch((tmp >> 2) & 7) {
387 param->u.ofdm.hierarchy_information = HIERARCHY_NONE;
390 param->u.ofdm.hierarchy_information = HIERARCHY_1;
393 param->u.ofdm.hierarchy_information = HIERARCHY_2;
396 param->u.ofdm.hierarchy_information = HIERARCHY_4;
399 printk("Unexpected value for hierarchy\n");
403 tmp = l64781_readreg (i2c, 0x1d);
404 param->inversion = (tmp & 0x80) ? INVERSION_ON : INVERSION_OFF;
406 tmp = (int) (l64781_readreg (i2c, 0x08) |
407 (l64781_readreg (i2c, 0x09) << 8) |
408 (l64781_readreg (i2c, 0x0a) << 16));
409 param->frequency += tmp;
415 static int init (struct dvb_i2c_bus *i2c)
417 reset_and_configure (i2c);
420 l64781_writereg (i2c, 0x3e, 0xa5);
423 l64781_writereg (i2c, 0x2a, 0x04);
424 l64781_writereg (i2c, 0x2a, 0x00);
426 /* Set tuner specific things */
427 /* AFC_POL, set also in reset_afc */
428 l64781_writereg (i2c, 0x07, 0x8e);
430 /* Use internal ADC */
431 l64781_writereg (i2c, 0x0b, 0x81);
433 /* AGC loop gain, and polarity is positive */
434 l64781_writereg (i2c, 0x0c, 0x84);
436 /* Internal ADC outputs two's complement */
437 l64781_writereg (i2c, 0x0d, 0x8c);
439 /* With ppm=8000, it seems the DTR_SENSITIVITY will result in
440 value of 2 with all possible bandwidths and guard
441 intervals, which is the initial value anyway. */
442 /*l64781_writereg (i2c, 0x19, 0x92);*/
444 /* Everything is two's complement, soft bit and CSI_OUT too */
445 l64781_writereg (i2c, 0x1e, 0x09);
452 int grundig_29504_401_ioctl (struct dvb_frontend *fe,
453 unsigned int cmd, void *arg)
455 struct dvb_i2c_bus *i2c = fe->i2c;
457 struct grundig_state* state = (struct grundig_state*) fe->data;
461 memcpy (arg, &grundig_29504_401_info,
462 sizeof(struct dvb_frontend_info));
467 fe_status_t *status = (fe_status_t *) arg;
468 int sync = l64781_readreg (i2c, 0x32);
469 int gain = l64781_readreg (i2c, 0x0e);
471 l64781_readreg (i2c, 0x00); /* clear interrupt registers... */
472 l64781_readreg (i2c, 0x01); /* dto. */
477 *status |= FE_HAS_SIGNAL;
479 if (sync & 0x02) /* VCXO locked, this criteria should be ok */
480 *status |= FE_HAS_CARRIER;
483 *status |= FE_HAS_VITERBI;
486 *status |= FE_HAS_SYNC;
489 *status |= FE_HAS_LOCK;
496 /* XXX FIXME: set up counting period (reg 0x26...0x28)
498 u32 *ber = (u32 *) arg;
499 *ber = l64781_readreg (i2c, 0x39)
500 | (l64781_readreg (i2c, 0x3a) << 8);
504 case FE_READ_SIGNAL_STRENGTH:
506 u8 gain = l64781_readreg (i2c, 0x0e);
507 *(u16 *) arg = (gain << 8) | gain;
513 u16 *snr = (u16 *) arg;
514 u8 avg_quality = 0xff - l64781_readreg (i2c, 0x33);
515 *snr = (avg_quality << 8) | avg_quality; /* not exact, but...*/
519 case FE_READ_UNCORRECTED_BLOCKS:
521 u32 *ub = (u32 *) arg;
522 *ub = l64781_readreg (i2c, 0x37)
523 | (l64781_readreg (i2c, 0x38) << 8);
527 case FE_SET_FRONTEND:
529 struct dvb_frontend_parameters *p = arg;
531 tsa5060_set_tv_freq (i2c, p->frequency);
532 return apply_frontend_param (i2c, p);
535 case FE_GET_FRONTEND:
537 struct dvb_frontend_parameters *p = arg;
538 return get_frontend(i2c, p);
543 return l64781_writereg (i2c, 0x3e, 0x5a);
547 if ((res == 0) && (state->first)) {
553 case FE_GET_TUNE_SETTINGS:
555 struct dvb_frontend_tune_settings* fesettings = (struct dvb_frontend_tune_settings*) arg;
556 fesettings->min_delay_ms = 200;
557 fesettings->step_size = 166667;
558 fesettings->max_drift = 166667*2;
563 dprintk ("%s: unknown command !!!\n", __FUNCTION__);
571 static int l64781_attach (struct dvb_i2c_bus *i2c, void **data)
576 struct i2c_msg msg [] = { { .addr = 0x55, .flags = 0, .buf = b0, .len = 1 },
577 { .addr = 0x55, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
578 struct grundig_state* state;
581 * the L64781 won't show up before we send the reset_and_configure()
582 * broadcast. If nothing responds there is no L64781 on the bus...
584 if (reset_and_configure(i2c) < 0) {
585 dprintk("no response on reset_and_configure() broadcast, bailing out...\n");
589 /* The chip always responds to reads */
590 if (i2c->xfer(i2c, msg, 2) != 2) {
591 dprintk("no response to read on I2C bus\n");
595 /* Save current register contents for bailout */
596 reg0x3e = l64781_readreg(i2c, 0x3e);
598 /* Reading the POWER_DOWN register always returns 0 */
600 dprintk("Device doesn't look like L64781\n");
604 /* Turn the chip off */
605 l64781_writereg (i2c, 0x3e, 0x5a);
607 /* Responds to all reads with 0 */
608 if (l64781_readreg(i2c, 0x1a) != 0) {
609 dprintk("Read 1 returned unexpcted value\n");
613 /* Turn the chip on */
614 l64781_writereg (i2c, 0x3e, 0xa5);
616 /* Responds with register default value */
617 if (l64781_readreg(i2c, 0x1a) != 0xa1) {
618 dprintk("Read 2 returned unexpcted value\n");
622 state = kmalloc(sizeof(struct grundig_state), GFP_KERNEL);
623 if (state == NULL) goto bailout;
627 return dvb_register_frontend (grundig_29504_401_ioctl, i2c, state,
628 &grundig_29504_401_info);
631 l64781_writereg (i2c, 0x3e, reg0x3e); /* restore reg 0x3e */
637 static void l64781_detach (struct dvb_i2c_bus *i2c, void *data)
640 dvb_unregister_frontend (grundig_29504_401_ioctl, i2c);
644 static int __init init_grundig_29504_401 (void)
646 return dvb_register_i2c_device (THIS_MODULE,
647 l64781_attach, l64781_detach);
651 static void __exit exit_grundig_29504_401 (void)
653 dvb_unregister_i2c_device (l64781_attach);
656 module_init(init_grundig_29504_401);
657 module_exit(exit_grundig_29504_401);
659 MODULE_PARM(debug,"i");
660 MODULE_PARM_DESC(debug, "enable verbose debug messages");
661 MODULE_DESCRIPTION("Grundig 29504-401 DVB-T Frontend");
662 MODULE_AUTHOR("Holger Waechtler, Marko Kohtala");
663 MODULE_LICENSE("GPL");