2 * $Id: lgdt3302.c,v 1.5 2005/07/07 03:47:15 mkrufky Exp $
4 * Support for LGDT3302 (DViCO FustionHDTV 3 Gold) - VSB/QAM
6 * Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net>
8 * Based on code from Kirk Lapray <kirk_lapray@bigfoot.com>
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 * NOTES ABOUT THIS DRIVER
30 * This driver supports DViCO FusionHDTV 3 Gold under Linux.
33 * BER and signal strength always return 0.
37 #include <linux/kernel.h>
38 #include <linux/module.h>
39 #include <linux/moduleparam.h>
40 #include <linux/init.h>
41 #include <linux/delay.h>
42 #include <asm/byteorder.h>
44 #include "dvb_frontend.h"
46 #include "lgdt3302_priv.h"
50 module_param(debug, int, 0644);
51 MODULE_PARM_DESC(debug,"Turn on/off lgdt3302 frontend debugging (default:off).");
52 #define dprintk(args...) \
54 if (debug) printk(KERN_DEBUG "lgdt3302: " args); \
59 struct i2c_adapter* i2c;
60 struct dvb_frontend_ops ops;
62 /* Configuration settings */
63 const struct lgdt3302_config* config;
65 struct dvb_frontend frontend;
67 /* Demodulator private data */
68 fe_modulation_t current_modulation;
70 /* Tuner private data */
71 u32 current_frequency;
74 static int i2c_writebytes (struct lgdt3302_state* state,
75 u8 addr, /* demod_address or pll_address */
76 u8 *buf, /* data bytes to send */
77 int len /* number of bytes to send */ )
79 if (addr == state->config->pll_address) {
81 { .addr = addr, .flags = 0, .buf = buf, .len = len };
84 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
85 printk(KERN_WARNING "lgdt3302: %s error (addr %02x <- %02x, err == %i)\n", __FUNCTION__, addr, buf[0], err);
89 u8 tmp[] = { buf[0], buf[1] };
91 { .addr = addr, .flags = 0, .buf = tmp, .len = 2 };
95 for (i=1; i<len; i++) {
97 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
98 printk(KERN_WARNING "lgdt3302: %s error (addr %02x <- %02x, err == %i)\n", __FUNCTION__, addr, buf[0], err);
106 static int i2c_readbytes (struct lgdt3302_state* state,
107 u8 addr, /* demod_address or pll_address */
108 u8 *buf, /* holds data bytes read */
109 int len /* number of bytes to read */ )
112 { .addr = addr, .flags = I2C_M_RD, .buf = buf, .len = len };
115 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
116 printk(KERN_WARNING "lgdt3302: %s error (addr %02x, err == %i)\n", __FUNCTION__, addr, err);
123 * This routine writes the register (reg) to the demod bus
124 * then reads the data returned for (len) bytes.
127 static u8 i2c_selectreadbytes (struct lgdt3302_state* state,
128 enum I2C_REG reg, u8* buf, int len)
131 struct i2c_msg msg [] = {
132 { .addr = state->config->demod_address,
133 .flags = 0, .buf = wr, .len = 1 },
134 { .addr = state->config->demod_address,
135 .flags = I2C_M_RD, .buf = buf, .len = len },
138 ret = i2c_transfer(state->i2c, msg, 2);
140 printk(KERN_WARNING "lgdt3302: %s: addr 0x%02x select 0x%02x error (ret == %i)\n", __FUNCTION__, state->config->demod_address, reg, ret);
148 int lgdt3302_SwReset(struct lgdt3302_state* state)
153 0x00 /* bit 6 is active low software reset
154 * bits 5-0 are 1 to mask interrupts */
157 ret = i2c_writebytes(state,
158 state->config->demod_address,
159 reset, sizeof(reset));
161 /* spec says reset takes 100 ns why wait */
162 /* mdelay(100); */ /* keep low for 100mS */
163 reset[1] = 0x7f; /* force reset high (inactive)
164 * and unmask interrupts */
165 ret = i2c_writebytes(state,
166 state->config->demod_address,
167 reset, sizeof(reset));
169 /* Spec does not indicate a need for this either */
170 /*mdelay(5); */ /* wait 5 msec before doing more */
174 static int lgdt3302_init(struct dvb_frontend* fe)
176 /* Hardware reset is done using gpio[0] of cx23880x chip.
177 * I'd like to do it here, but don't know how to find chip address.
178 * cx88-cards.c arranges for the reset bit to be inactive (high).
179 * Maybe there needs to be a callable function in cx88-core or
180 * the caller of this function needs to do it. */
182 dprintk("%s entered\n", __FUNCTION__);
183 return lgdt3302_SwReset((struct lgdt3302_state*) fe->demodulator_priv);
186 static int lgdt3302_read_ber(struct dvb_frontend* fe, u32* ber)
188 *ber = 0; /* Dummy out for now */
192 static int lgdt3302_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
194 struct lgdt3302_state* state = (struct lgdt3302_state*) fe->demodulator_priv;
197 i2c_selectreadbytes(state, PACKET_ERR_COUNTER1, buf, sizeof(buf));
199 *ucblocks = (buf[0] << 8) | buf[1];
203 static int lgdt3302_set_parameters(struct dvb_frontend* fe,
204 struct dvb_frontend_parameters *param)
207 struct lgdt3302_state* state =
208 (struct lgdt3302_state*) fe->demodulator_priv;
210 /* Use 50MHz parameter values from spec sheet since xtal is 50 */
211 static u8 top_ctrl_cfg[] = { TOP_CONTROL, 0x03 };
212 static u8 vsb_freq_cfg[] = { VSB_CARRIER_FREQ0, 0x00, 0x87, 0x8e, 0x01 };
213 static u8 demux_ctrl_cfg[] = { DEMUX_CONTROL, 0xfb };
214 static u8 agc_rf_cfg[] = { AGC_RF_BANDWIDTH0, 0x40, 0x93, 0x00 };
215 static u8 agc_ctrl_cfg[] = { AGC_FUNC_CTRL2, 0xc6, 0x40 };
216 static u8 agc_delay_cfg[] = { AGC_DELAY0, 0x00, 0x00, 0x00 };
217 static u8 agc_loop_cfg[] = { AGC_LOOP_BANDWIDTH0, 0x08, 0x9a };
219 /* Change only if we are actually changing the modulation */
220 if (state->current_modulation != param->u.vsb.modulation) {
221 switch(param->u.vsb.modulation) {
223 dprintk("%s: VSB_8 MODE\n", __FUNCTION__);
225 /* Select VSB mode and serial MPEG interface */
226 top_ctrl_cfg[1] = 0x07;
230 dprintk("%s: QAM_64 MODE\n", __FUNCTION__);
232 /* Select QAM_64 mode and serial MPEG interface */
233 top_ctrl_cfg[1] = 0x04;
237 dprintk("%s: QAM_256 MODE\n", __FUNCTION__);
239 /* Select QAM_256 mode and serial MPEG interface */
240 top_ctrl_cfg[1] = 0x05;
243 printk(KERN_WARNING "lgdt3302: %s: Modulation type(%d) UNSUPPORTED\n", __FUNCTION__, param->u.vsb.modulation);
246 /* Initializations common to all modes */
248 /* Select the requested mode */
249 i2c_writebytes(state, state->config->demod_address,
250 top_ctrl_cfg, sizeof(top_ctrl_cfg));
252 /* Change the value of IFBW[11:0]
253 of AGC IF/RF loop filter bandwidth register */
254 i2c_writebytes(state, state->config->demod_address,
255 agc_rf_cfg, sizeof(agc_rf_cfg));
257 /* Change the value of bit 6, 'nINAGCBY' and
258 'NSSEL[1:0] of ACG function control register 2 */
259 /* Change the value of bit 6 'RFFIX'
260 of AGC function control register 3 */
261 i2c_writebytes(state, state->config->demod_address,
262 agc_ctrl_cfg, sizeof(agc_ctrl_cfg));
264 /* Change the TPCLK pin polarity
265 data is valid on falling clock */
266 i2c_writebytes(state, state->config->demod_address,
267 demux_ctrl_cfg, sizeof(demux_ctrl_cfg));
269 if (param->u.vsb.modulation == VSB_8) {
270 /* Initialization for VSB modes only */
271 /* Change the value of NCOCTFV[25:0]of carrier
272 recovery center frequency register for VSB */
273 i2c_writebytes(state, state->config->demod_address,
274 vsb_freq_cfg, sizeof(vsb_freq_cfg));
276 /* Initialization for QAM modes only */
277 /* Set the value of 'INLVTHD' register 0x2a/0x2c
278 to value from 'IFACC' register 0x39/0x3b -1 */
280 i2c_selectreadbytes(state, AGC_RFIF_ACC0,
281 &agc_delay_cfg[1], 3);
282 value = ((agc_delay_cfg[1] & 0x0f) << 8) | agc_delay_cfg[3];
284 dprintk("%s IFACC -1 = 0x%03x\n", __FUNCTION__, value);
285 agc_delay_cfg[1] = (value >> 8) & 0x0f;
286 agc_delay_cfg[2] = 0x00;
287 agc_delay_cfg[3] = value & 0xff;
288 i2c_writebytes(state, state->config->demod_address,
289 agc_delay_cfg, sizeof(agc_delay_cfg));
291 /* Change the value of IAGCBW[15:8]
292 of inner AGC loop filter bandwith */
293 i2c_writebytes(state, state->config->demod_address,
294 agc_loop_cfg, sizeof(agc_loop_cfg));
297 state->config->set_ts_params(fe, 0);
298 lgdt3302_SwReset(state);
299 state->current_modulation = param->u.vsb.modulation;
302 /* Change only if we are actually changing the channel */
303 if (state->current_frequency != param->frequency) {
304 dvb_pll_configure(state->config->pll_desc, buf,
305 param->frequency, 0);
306 dprintk("%s: tuner bytes: 0x%02x 0x%02x "
307 "0x%02x 0x%02x\n", __FUNCTION__, buf[0],buf[1],buf[2],buf[3]);
308 i2c_writebytes(state, state->config->pll_address ,buf, 4);
310 /* Check the status of the tuner pll */
311 i2c_readbytes(state, state->config->pll_address, buf, 1);
312 dprintk("%s: tuner status byte = 0x%02x\n", __FUNCTION__, buf[0]);
314 lgdt3302_SwReset(state);
316 /* Update current frequency */
317 state->current_frequency = param->frequency;
322 static int lgdt3302_get_frontend(struct dvb_frontend* fe,
323 struct dvb_frontend_parameters* param)
325 struct lgdt3302_state *state = fe->demodulator_priv;
326 param->frequency = state->current_frequency;
330 static int lgdt3302_read_status(struct dvb_frontend* fe, fe_status_t* status)
332 struct lgdt3302_state* state = (struct lgdt3302_state*) fe->demodulator_priv;
335 *status = 0; /* Reset status result */
337 /* Check the status of the tuner pll */
338 i2c_readbytes(state, state->config->pll_address, buf, 1);
339 dprintk("%s: tuner status byte = 0x%02x\n", __FUNCTION__, buf[0]);
340 if ((buf[0] & 0xc0) != 0x40)
341 return 0; /* Tuner PLL not locked or not powered on */
344 * You must set the Mask bits to 1 in the IRQ_MASK in order
345 * to see that status bit in the IRQ_STATUS register.
346 * This is done in SwReset();
349 /* AGC status register */
350 i2c_selectreadbytes(state, AGC_STATUS, buf, 1);
351 dprintk("%s: AGC_STATUS = 0x%02x\n", __FUNCTION__, buf[0]);
352 if ((buf[0] & 0x0c) == 0x8){
353 /* Test signal does not exist flag */
354 /* as well as the AGC lock flag. */
355 *status |= FE_HAS_SIGNAL;
357 /* Without a signal all other status bits are meaningless */
362 i2c_selectreadbytes(state, TOP_CONTROL, buf, sizeof(buf));
363 dprintk("%s: TOP_CONTROL = 0x%02x, IRO_MASK = 0x%02x, IRQ_STATUS = 0x%02x\n", __FUNCTION__, buf[0], buf[1], buf[2]);
366 /* Alternative method to check for a signal */
367 /* using the SNR good/bad interrupts. */
368 if ((buf[2] & 0x30) == 0x10)
369 *status |= FE_HAS_SIGNAL;
373 if ((buf[2] & 0x03) == 0x01) {
374 *status |= FE_HAS_SYNC;
377 /* FEC error status */
378 if ((buf[2] & 0x0c) == 0x08) {
379 *status |= FE_HAS_LOCK;
380 *status |= FE_HAS_VITERBI;
383 /* Carrier Recovery Lock Status Register */
384 i2c_selectreadbytes(state, CARRIER_LOCK, buf, 1);
385 dprintk("%s: CARRIER_LOCK = 0x%02x\n", __FUNCTION__, buf[0]);
386 switch (state->current_modulation) {
389 /* Need to undestand why there are 3 lock levels here */
390 if ((buf[0] & 0x07) == 0x07)
391 *status |= FE_HAS_CARRIER;
394 if ((buf[0] & 0x80) == 0x80)
395 *status |= FE_HAS_CARRIER;
398 printk("KERN_WARNING lgdt3302: %s: Modulation set to unsupported value\n", __FUNCTION__);
404 static int lgdt3302_read_signal_strength(struct dvb_frontend* fe, u16* strength)
406 /* not directly available. */
410 static int lgdt3302_read_snr(struct dvb_frontend* fe, u16* snr)
414 * Spec sheet shows formula for SNR_EQ = 10 log10(25 * 24**2 / noise)
415 * and SNR_PH = 10 log10(25 * 32**2 / noise) for equalizer and phase tracker
416 * respectively. The following tables are built on these formulas.
417 * The usual definition is SNR = 20 log10(signal/noise)
418 * If the specification is wrong the value retuned is 1/2 the actual SNR in db.
420 * This table is a an ordered list of noise values computed by the
421 * formula from the spec sheet such that the index into the table
422 * starting at 43 or 45 is the SNR value in db. There are duplicate noise
423 * value entries at the beginning because the SNR varies more than
424 * 1 db for a change of 1 digit in noise at very small values of noise.
426 * Examples from SNR_EQ table:
444 static const u32 SNR_EQ[] =
445 { 1, 2, 2, 2, 3, 3, 4, 4, 5, 7,
446 9, 11, 13, 17, 21, 26, 33, 41, 52, 65,
447 81, 102, 129, 162, 204, 257, 323, 406, 511, 644,
448 810, 1020, 1284, 1616, 2035, 2561, 3224, 4059, 5110, 6433,
449 8098, 10195, 12835, 16158, 20341, 25608, 32238, 40585, 51094, 64323,
450 80978, 101945, 128341, 161571, 203406, 256073, 0x40000
453 static const u32 SNR_PH[] =
454 { 1, 2, 2, 2, 3, 3, 4, 5, 6, 8,
455 10, 12, 15, 19, 23, 29, 37, 46, 58, 73,
456 91, 115, 144, 182, 229, 288, 362, 456, 574, 722,
457 909, 1144, 1440, 1813, 2282, 2873, 3617, 4553, 5732, 7216,
458 9084, 11436, 14396, 18124, 22817, 28724, 36161, 45524, 57312, 72151,
459 90833, 114351, 143960, 181235, 228161, 0x040000
462 static u8 buf[5];/* read data buffer */
463 static u32 noise; /* noise value */
464 static u32 snr_db; /* index into SNR_EQ[] */
465 struct lgdt3302_state* state = (struct lgdt3302_state*) fe->demodulator_priv;
467 /* read both equalizer and pase tracker noise data */
468 i2c_selectreadbytes(state, EQPH_ERR0, buf, sizeof(buf));
470 if (state->current_modulation == VSB_8) {
471 /* Equalizer Mean-Square Error Register for VSB */
472 noise = ((buf[0] & 7) << 16) | (buf[1] << 8) | buf[2];
475 * Look up noise value in table.
476 * A better search algorithm could be used...
477 * watch out there are duplicate entries.
479 for (snr_db = 0; snr_db < sizeof(SNR_EQ); snr_db++) {
480 if (noise < SNR_EQ[snr_db]) {
486 /* Phase Tracker Mean-Square Error Register for QAM */
487 noise = ((buf[0] & 7<<3) << 13) | (buf[3] << 8) | buf[4];
489 /* Look up noise value in table. */
490 for (snr_db = 0; snr_db < sizeof(SNR_PH); snr_db++) {
491 if (noise < SNR_PH[snr_db]) {
498 /* Return the raw noise value */
499 static u8 buf[5];/* read data buffer */
500 static u32 noise; /* noise value */
501 struct lgdt3302_state* state = (struct lgdt3302_state*) fe->demodulator_priv;
503 /* read both equalizer and pase tracker noise data */
504 i2c_selectreadbytes(state, EQPH_ERR0, buf, sizeof(buf));
506 if (state->current_modulation == VSB_8) {
507 /* Equalizer Mean-Square Error Register for VSB */
508 noise = ((buf[0] & 7) << 16) | (buf[1] << 8) | buf[2];
510 /* Phase Tracker Mean-Square Error Register for QAM */
511 noise = ((buf[0] & 7<<3) << 13) | (buf[3] << 8) | buf[4];
514 /* Small values for noise mean signal is better so invert noise */
515 /* Noise is 19 bit value so discard 3 LSB*/
519 dprintk("%s: noise = 0x%05x, snr = %idb\n",__FUNCTION__, noise, *snr);
524 static int lgdt3302_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fe_tune_settings)
526 /* I have no idea about this - it may not be needed */
527 fe_tune_settings->min_delay_ms = 500;
528 fe_tune_settings->step_size = 0;
529 fe_tune_settings->max_drift = 0;
533 static void lgdt3302_release(struct dvb_frontend* fe)
535 struct lgdt3302_state* state = (struct lgdt3302_state*) fe->demodulator_priv;
539 static struct dvb_frontend_ops lgdt3302_ops;
541 struct dvb_frontend* lgdt3302_attach(const struct lgdt3302_config* config,
542 struct i2c_adapter* i2c)
544 struct lgdt3302_state* state = NULL;
547 /* Allocate memory for the internal state */
548 state = (struct lgdt3302_state*) kmalloc(sizeof(struct lgdt3302_state), GFP_KERNEL);
551 memset(state,0,sizeof(*state));
553 /* Setup the state */
554 state->config = config;
556 memcpy(&state->ops, &lgdt3302_ops, sizeof(struct dvb_frontend_ops));
557 /* Verify communication with demod chip */
558 if (i2c_selectreadbytes(state, 2, buf, 1))
561 state->current_frequency = -1;
562 state->current_modulation = -1;
564 /* Create dvb_frontend */
565 state->frontend.ops = &state->ops;
566 state->frontend.demodulator_priv = state;
567 return &state->frontend;
572 dprintk("%s: ERROR\n",__FUNCTION__);
576 static struct dvb_frontend_ops lgdt3302_ops = {
578 .name= "LG Electronics LGDT3302 VSB/QAM Frontend",
580 .frequency_min= 54000000,
581 .frequency_max= 858000000,
582 .frequency_stepsize= 62500,
583 /* Symbol rate is for all VSB modes need to check QAM */
584 .symbol_rate_min = 10762000,
585 .symbol_rate_max = 10762000,
586 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
588 .init = lgdt3302_init,
589 .set_frontend = lgdt3302_set_parameters,
590 .get_frontend = lgdt3302_get_frontend,
591 .get_tune_settings = lgdt3302_get_tune_settings,
592 .read_status = lgdt3302_read_status,
593 .read_ber = lgdt3302_read_ber,
594 .read_signal_strength = lgdt3302_read_signal_strength,
595 .read_snr = lgdt3302_read_snr,
596 .read_ucblocks = lgdt3302_read_ucblocks,
597 .release = lgdt3302_release,
600 MODULE_DESCRIPTION("LGDT3302 [DViCO FusionHDTV 3 Gold] (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver");
601 MODULE_AUTHOR("Wilson Michaels");
602 MODULE_LICENSE("GPL");
604 EXPORT_SYMBOL(lgdt3302_attach);
609 * compile-command: "make DVB=1"