• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500v2-V1.0.0.60_1.0.38/src/linux/linux-2.6/drivers/media/dvb/frontends/
1/*
2 *    Support for LGDT3302 and LGDT3303 - VSB/QAM
3 *
4 *    Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net>
5 *
6 *    This program is free software; you can redistribute it and/or modify
7 *    it under the terms of the GNU General Public License as published by
8 *    the Free Software Foundation; either version 2 of the License, or
9 *    (at your option) any later version.
10 *
11 *    This program is distributed in the hope that it will be useful,
12 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
13 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 *    GNU General Public License for more details.
15 *
16 *    You should have received a copy of the GNU General Public License
17 *    along with this program; if not, write to the Free Software
18 *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 */
21
22/*
23 *                      NOTES ABOUT THIS DRIVER
24 *
25 * This Linux driver supports:
26 *   DViCO FusionHDTV 3 Gold-Q
27 *   DViCO FusionHDTV 3 Gold-T
28 *   DViCO FusionHDTV 5 Gold
29 *   DViCO FusionHDTV 5 Lite
30 *   DViCO FusionHDTV 5 USB Gold
31 *   Air2PC/AirStar 2 ATSC 3rd generation (HD5000)
32 *   pcHDTV HD5500
33 *
34 */
35
36#include <linux/kernel.h>
37#include <linux/module.h>
38#include <linux/moduleparam.h>
39#include <linux/init.h>
40#include <linux/delay.h>
41#include <linux/string.h>
42#include <linux/slab.h>
43#include <asm/byteorder.h>
44
45#include "dvb_frontend.h"
46#include "dvb_math.h"
47#include "lgdt330x_priv.h"
48#include "lgdt330x.h"
49
50/* Use Equalizer Mean Squared Error instead of Phaser Tracker MSE */
51/* #define USE_EQMSE */
52
53static int debug = 0;
54module_param(debug, int, 0644);
55MODULE_PARM_DESC(debug,"Turn on/off lgdt330x frontend debugging (default:off).");
56#define dprintk(args...) \
57do { \
58if (debug) printk(KERN_DEBUG "lgdt330x: " args); \
59} while (0)
60
61struct lgdt330x_state
62{
63	struct i2c_adapter* i2c;
64
65	/* Configuration settings */
66	const struct lgdt330x_config* config;
67
68	struct dvb_frontend frontend;
69
70	/* Demodulator private data */
71	fe_modulation_t current_modulation;
72	u32 snr; /* Result of last SNR calculation */
73
74	/* Tuner private data */
75	u32 current_frequency;
76};
77
78static int i2c_write_demod_bytes (struct lgdt330x_state* state,
79				  u8 *buf, /* data bytes to send */
80				  int len  /* number of bytes to send */ )
81{
82	struct i2c_msg msg =
83		{ .addr = state->config->demod_address,
84		  .flags = 0,
85		  .buf = buf,
86		  .len = 2 };
87	int i;
88	int err;
89
90	for (i=0; i<len-1; i+=2){
91		if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
92			printk(KERN_WARNING "lgdt330x: %s error (addr %02x <- %02x, err = %i)\n", __FUNCTION__, msg.buf[0], msg.buf[1], err);
93			if (err < 0)
94				return err;
95			else
96				return -EREMOTEIO;
97		}
98		msg.buf += 2;
99	}
100	return 0;
101}
102
103/*
104 * This routine writes the register (reg) to the demod bus
105 * then reads the data returned for (len) bytes.
106 */
107
108static u8 i2c_read_demod_bytes (struct lgdt330x_state* state,
109			       enum I2C_REG reg, u8* buf, int len)
110{
111	u8 wr [] = { reg };
112	struct i2c_msg msg [] = {
113		{ .addr = state->config->demod_address,
114		  .flags = 0, .buf = wr,  .len = 1 },
115		{ .addr = state->config->demod_address,
116		  .flags = I2C_M_RD, .buf = buf, .len = len },
117	};
118	int ret;
119	ret = i2c_transfer(state->i2c, msg, 2);
120	if (ret != 2) {
121		printk(KERN_WARNING "lgdt330x: %s: addr 0x%02x select 0x%02x error (ret == %i)\n", __FUNCTION__, state->config->demod_address, reg, ret);
122	} else {
123		ret = 0;
124	}
125	return ret;
126}
127
128/* Software reset */
129static int lgdt3302_SwReset(struct lgdt330x_state* state)
130{
131	u8 ret;
132	u8 reset[] = {
133		IRQ_MASK,
134		0x00 /* bit 6 is active low software reset
135		      *	bits 5-0 are 1 to mask interrupts */
136	};
137
138	ret = i2c_write_demod_bytes(state,
139				    reset, sizeof(reset));
140	if (ret == 0) {
141
142		/* force reset high (inactive) and unmask interrupts */
143		reset[1] = 0x7f;
144		ret = i2c_write_demod_bytes(state,
145					    reset, sizeof(reset));
146	}
147	return ret;
148}
149
150static int lgdt3303_SwReset(struct lgdt330x_state* state)
151{
152	u8 ret;
153	u8 reset[] = {
154		0x02,
155		0x00 /* bit 0 is active low software reset */
156	};
157
158	ret = i2c_write_demod_bytes(state,
159				    reset, sizeof(reset));
160	if (ret == 0) {
161
162		/* force reset high (inactive) */
163		reset[1] = 0x01;
164		ret = i2c_write_demod_bytes(state,
165					    reset, sizeof(reset));
166	}
167	return ret;
168}
169
170static int lgdt330x_SwReset(struct lgdt330x_state* state)
171{
172	switch (state->config->demod_chip) {
173	case LGDT3302:
174		return lgdt3302_SwReset(state);
175	case LGDT3303:
176		return lgdt3303_SwReset(state);
177	default:
178		return -ENODEV;
179	}
180}
181
182static int lgdt330x_init(struct dvb_frontend* fe)
183{
184	/* Hardware reset is done using gpio[0] of cx23880x chip.
185	 * I'd like to do it here, but don't know how to find chip address.
186	 * cx88-cards.c arranges for the reset bit to be inactive (high).
187	 * Maybe there needs to be a callable function in cx88-core or
188	 * the caller of this function needs to do it. */
189
190	/*
191	 * Array of byte pairs <address, value>
192	 * to initialize each different chip
193	 */
194	static u8 lgdt3302_init_data[] = {
195		/* Use 50MHz parameter values from spec sheet since xtal is 50 */
196		/* Change the value of NCOCTFV[25:0] of carrier
197		   recovery center frequency register */
198		VSB_CARRIER_FREQ0, 0x00,
199		VSB_CARRIER_FREQ1, 0x87,
200		VSB_CARRIER_FREQ2, 0x8e,
201		VSB_CARRIER_FREQ3, 0x01,
202		/* Change the TPCLK pin polarity
203		   data is valid on falling clock */
204		DEMUX_CONTROL, 0xfb,
205		/* Change the value of IFBW[11:0] of
206		   AGC IF/RF loop filter bandwidth register */
207		AGC_RF_BANDWIDTH0, 0x40,
208		AGC_RF_BANDWIDTH1, 0x93,
209		AGC_RF_BANDWIDTH2, 0x00,
210		/* Change the value of bit 6, 'nINAGCBY' and
211		   'NSSEL[1:0] of ACG function control register 2 */
212		AGC_FUNC_CTRL2, 0xc6,
213		/* Change the value of bit 6 'RFFIX'
214		   of AGC function control register 3 */
215		AGC_FUNC_CTRL3, 0x40,
216		/* Set the value of 'INLVTHD' register 0x2a/0x2c
217		   to 0x7fe */
218		AGC_DELAY0, 0x07,
219		AGC_DELAY2, 0xfe,
220		/* Change the value of IAGCBW[15:8]
221		   of inner AGC loop filter bandwidth */
222		AGC_LOOP_BANDWIDTH0, 0x08,
223		AGC_LOOP_BANDWIDTH1, 0x9a
224	};
225
226	static u8 lgdt3303_init_data[] = {
227		0x4c, 0x14
228	};
229
230	static u8 flip_lgdt3303_init_data[] = {
231		0x4c, 0x14,
232		0x87, 0xf3
233	};
234
235	struct lgdt330x_state* state = fe->demodulator_priv;
236	char  *chip_name;
237	int    err;
238
239	switch (state->config->demod_chip) {
240	case LGDT3302:
241		chip_name = "LGDT3302";
242		err = i2c_write_demod_bytes(state, lgdt3302_init_data,
243					    sizeof(lgdt3302_init_data));
244		break;
245	case LGDT3303:
246		chip_name = "LGDT3303";
247		if (state->config->clock_polarity_flip) {
248			err = i2c_write_demod_bytes(state, flip_lgdt3303_init_data,
249						    sizeof(flip_lgdt3303_init_data));
250		} else {
251			err = i2c_write_demod_bytes(state, lgdt3303_init_data,
252						    sizeof(lgdt3303_init_data));
253		}
254		break;
255	default:
256		chip_name = "undefined";
257		printk (KERN_WARNING "Only LGDT3302 and LGDT3303 are supported chips.\n");
258		err = -ENODEV;
259	}
260	dprintk("%s entered as %s\n", __FUNCTION__, chip_name);
261	if (err < 0)
262		return err;
263	return lgdt330x_SwReset(state);
264}
265
266static int lgdt330x_read_ber(struct dvb_frontend* fe, u32* ber)
267{
268	*ber = 0; /* Not supplied by the demod chips */
269	return 0;
270}
271
272static int lgdt330x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
273{
274	struct lgdt330x_state* state = fe->demodulator_priv;
275	int err;
276	u8 buf[2];
277
278	switch (state->config->demod_chip) {
279	case LGDT3302:
280		err = i2c_read_demod_bytes(state, LGDT3302_PACKET_ERR_COUNTER1,
281					   buf, sizeof(buf));
282		break;
283	case LGDT3303:
284		err = i2c_read_demod_bytes(state, LGDT3303_PACKET_ERR_COUNTER1,
285					   buf, sizeof(buf));
286		break;
287	default:
288		printk(KERN_WARNING
289		       "Only LGDT3302 and LGDT3303 are supported chips.\n");
290		err = -ENODEV;
291	}
292
293	*ucblocks = (buf[0] << 8) | buf[1];
294	return 0;
295}
296
297static int lgdt330x_set_parameters(struct dvb_frontend* fe,
298				   struct dvb_frontend_parameters *param)
299{
300	/*
301	 * Array of byte pairs <address, value>
302	 * to initialize 8VSB for lgdt3303 chip 50 MHz IF
303	 */
304	static u8 lgdt3303_8vsb_44_data[] = {
305		0x04, 0x00,
306		0x0d, 0x40,
307		0x0e, 0x87,
308		0x0f, 0x8e,
309		0x10, 0x01,
310		0x47, 0x8b };
311
312	/*
313	 * Array of byte pairs <address, value>
314	 * to initialize QAM for lgdt3303 chip
315	 */
316	static u8 lgdt3303_qam_data[] = {
317		0x04, 0x00,
318		0x0d, 0x00,
319		0x0e, 0x00,
320		0x0f, 0x00,
321		0x10, 0x00,
322		0x51, 0x63,
323		0x47, 0x66,
324		0x48, 0x66,
325		0x4d, 0x1a,
326		0x49, 0x08,
327		0x4a, 0x9b };
328
329	struct lgdt330x_state* state = fe->demodulator_priv;
330
331	static u8 top_ctrl_cfg[]   = { TOP_CONTROL, 0x03 };
332
333	int err;
334	/* Change only if we are actually changing the modulation */
335	if (state->current_modulation != param->u.vsb.modulation) {
336		switch(param->u.vsb.modulation) {
337		case VSB_8:
338			dprintk("%s: VSB_8 MODE\n", __FUNCTION__);
339
340			/* Select VSB mode */
341			top_ctrl_cfg[1] = 0x03;
342
343			/* Select ANT connector if supported by card */
344			if (state->config->pll_rf_set)
345				state->config->pll_rf_set(fe, 1);
346
347			if (state->config->demod_chip == LGDT3303) {
348				err = i2c_write_demod_bytes(state, lgdt3303_8vsb_44_data,
349							    sizeof(lgdt3303_8vsb_44_data));
350			}
351			break;
352
353		case QAM_64:
354			dprintk("%s: QAM_64 MODE\n", __FUNCTION__);
355
356			/* Select QAM_64 mode */
357			top_ctrl_cfg[1] = 0x00;
358
359			/* Select CABLE connector if supported by card */
360			if (state->config->pll_rf_set)
361				state->config->pll_rf_set(fe, 0);
362
363			if (state->config->demod_chip == LGDT3303) {
364				err = i2c_write_demod_bytes(state, lgdt3303_qam_data,
365											sizeof(lgdt3303_qam_data));
366			}
367			break;
368
369		case QAM_256:
370			dprintk("%s: QAM_256 MODE\n", __FUNCTION__);
371
372			/* Select QAM_256 mode */
373			top_ctrl_cfg[1] = 0x01;
374
375			/* Select CABLE connector if supported by card */
376			if (state->config->pll_rf_set)
377				state->config->pll_rf_set(fe, 0);
378
379			if (state->config->demod_chip == LGDT3303) {
380				err = i2c_write_demod_bytes(state, lgdt3303_qam_data,
381											sizeof(lgdt3303_qam_data));
382			}
383			break;
384		default:
385			printk(KERN_WARNING "lgdt330x: %s: Modulation type(%d) UNSUPPORTED\n", __FUNCTION__, param->u.vsb.modulation);
386			return -1;
387		}
388		/*
389		 * select serial or parallel MPEG harware interface
390		 * Serial:   0x04 for LGDT3302 or 0x40 for LGDT3303
391		 * Parallel: 0x00
392		 */
393		top_ctrl_cfg[1] |= state->config->serial_mpeg;
394
395		/* Select the requested mode */
396		i2c_write_demod_bytes(state, top_ctrl_cfg,
397				      sizeof(top_ctrl_cfg));
398		if (state->config->set_ts_params)
399			state->config->set_ts_params(fe, 0);
400		state->current_modulation = param->u.vsb.modulation;
401	}
402
403	/* Tune to the specified frequency */
404	if (fe->ops.tuner_ops.set_params) {
405		fe->ops.tuner_ops.set_params(fe, param);
406		if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
407	}
408
409	/* Keep track of the new frequency */
410	/* The tuner is shared with the video4linux analog API */
411	state->current_frequency = param->frequency;
412
413	lgdt330x_SwReset(state);
414	return 0;
415}
416
417static int lgdt330x_get_frontend(struct dvb_frontend* fe,
418				 struct dvb_frontend_parameters* param)
419{
420	struct lgdt330x_state *state = fe->demodulator_priv;
421	param->frequency = state->current_frequency;
422	return 0;
423}
424
425static int lgdt3302_read_status(struct dvb_frontend* fe, fe_status_t* status)
426{
427	struct lgdt330x_state* state = fe->demodulator_priv;
428	u8 buf[3];
429
430	*status = 0; /* Reset status result */
431
432	/* AGC status register */
433	i2c_read_demod_bytes(state, AGC_STATUS, buf, 1);
434	dprintk("%s: AGC_STATUS = 0x%02x\n", __FUNCTION__, buf[0]);
435	if ((buf[0] & 0x0c) == 0x8){
436		/* Test signal does not exist flag */
437		/* as well as the AGC lock flag.   */
438		*status |= FE_HAS_SIGNAL;
439	}
440
441	/*
442	 * You must set the Mask bits to 1 in the IRQ_MASK in order
443	 * to see that status bit in the IRQ_STATUS register.
444	 * This is done in SwReset();
445	 */
446	/* signal status */
447	i2c_read_demod_bytes(state, TOP_CONTROL, buf, sizeof(buf));
448	dprintk("%s: TOP_CONTROL = 0x%02x, IRO_MASK = 0x%02x, IRQ_STATUS = 0x%02x\n", __FUNCTION__, buf[0], buf[1], buf[2]);
449
450
451	/* sync status */
452	if ((buf[2] & 0x03) == 0x01) {
453		*status |= FE_HAS_SYNC;
454	}
455
456	/* FEC error status */
457	if ((buf[2] & 0x0c) == 0x08) {
458		*status |= FE_HAS_LOCK;
459		*status |= FE_HAS_VITERBI;
460	}
461
462	/* Carrier Recovery Lock Status Register */
463	i2c_read_demod_bytes(state, CARRIER_LOCK, buf, 1);
464	dprintk("%s: CARRIER_LOCK = 0x%02x\n", __FUNCTION__, buf[0]);
465	switch (state->current_modulation) {
466	case QAM_256:
467	case QAM_64:
468		/* Need to undestand why there are 3 lock levels here */
469		if ((buf[0] & 0x07) == 0x07)
470			*status |= FE_HAS_CARRIER;
471		break;
472	case VSB_8:
473		if ((buf[0] & 0x80) == 0x80)
474			*status |= FE_HAS_CARRIER;
475		break;
476	default:
477		printk(KERN_WARNING "lgdt330x: %s: Modulation set to unsupported value\n", __FUNCTION__);
478	}
479
480	return 0;
481}
482
483static int lgdt3303_read_status(struct dvb_frontend* fe, fe_status_t* status)
484{
485	struct lgdt330x_state* state = fe->demodulator_priv;
486	int err;
487	u8 buf[3];
488
489	*status = 0; /* Reset status result */
490
491	/* lgdt3303 AGC status register */
492	err = i2c_read_demod_bytes(state, 0x58, buf, 1);
493	if (err < 0)
494		return err;
495
496	dprintk("%s: AGC_STATUS = 0x%02x\n", __FUNCTION__, buf[0]);
497	if ((buf[0] & 0x21) == 0x01){
498		/* Test input signal does not exist flag */
499		/* as well as the AGC lock flag.   */
500		*status |= FE_HAS_SIGNAL;
501	}
502
503	/* Carrier Recovery Lock Status Register */
504	i2c_read_demod_bytes(state, CARRIER_LOCK, buf, 1);
505	dprintk("%s: CARRIER_LOCK = 0x%02x\n", __FUNCTION__, buf[0]);
506	switch (state->current_modulation) {
507	case QAM_256:
508	case QAM_64:
509		/* Need to undestand why there are 3 lock levels here */
510		if ((buf[0] & 0x07) == 0x07)
511			*status |= FE_HAS_CARRIER;
512		else
513			break;
514		i2c_read_demod_bytes(state, 0x8a, buf, 1);
515		if ((buf[0] & 0x04) == 0x04)
516			*status |= FE_HAS_SYNC;
517		if ((buf[0] & 0x01) == 0x01)
518			*status |= FE_HAS_LOCK;
519		if ((buf[0] & 0x08) == 0x08)
520			*status |= FE_HAS_VITERBI;
521		break;
522	case VSB_8:
523		if ((buf[0] & 0x80) == 0x80)
524			*status |= FE_HAS_CARRIER;
525		else
526			break;
527		i2c_read_demod_bytes(state, 0x38, buf, 1);
528		if ((buf[0] & 0x02) == 0x00)
529			*status |= FE_HAS_SYNC;
530		if ((buf[0] & 0x01) == 0x01) {
531			*status |= FE_HAS_LOCK;
532			*status |= FE_HAS_VITERBI;
533		}
534		break;
535	default:
536		printk(KERN_WARNING "lgdt330x: %s: Modulation set to unsupported value\n", __FUNCTION__);
537	}
538	return 0;
539}
540
541/* Calculate SNR estimation (scaled by 2^24)
542
543   8-VSB SNR equations from LGDT3302 and LGDT3303 datasheets, QAM
544   equations from LGDT3303 datasheet.  VSB is the same between the '02
545   and '03, so maybe QAM is too?  Perhaps someone with a newer datasheet
546   that has QAM information could verify?
547
548   For 8-VSB: (two ways, take your pick)
549   LGDT3302:
550     SNR_EQ = 10 * log10(25 * 24^2 / EQ_MSE)
551   LGDT3303:
552     SNR_EQ = 10 * log10(25 * 32^2 / EQ_MSE)
553   LGDT3302 & LGDT3303:
554     SNR_PT = 10 * log10(25 * 32^2 / PT_MSE)  (we use this one)
555   For 64-QAM:
556     SNR    = 10 * log10( 688128   / MSEQAM)
557   For 256-QAM:
558     SNR    = 10 * log10( 696320   / MSEQAM)
559
560   We re-write the snr equation as:
561     SNR * 2^24 = 10*(c - intlog10(MSE))
562   Where for 256-QAM, c = log10(696320) * 2^24, and so on. */
563
564static u32 calculate_snr(u32 mse, u32 c)
565{
566	if (mse == 0) /* No signal */
567		return 0;
568
569	mse = intlog10(mse);
570	if (mse > c) {
571		/* Negative SNR, which is possible, but realisticly the
572		demod will lose lock before the signal gets this bad.  The
573		API only allows for unsigned values, so just return 0 */
574		return 0;
575	}
576	return 10*(c - mse);
577}
578
579static int lgdt3302_read_snr(struct dvb_frontend* fe, u16* snr)
580{
581	struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv;
582	u8 buf[5];	/* read data buffer */
583	u32 noise;	/* noise value */
584	u32 c;		/* per-modulation SNR calculation constant */
585
586	switch(state->current_modulation) {
587	case VSB_8:
588		i2c_read_demod_bytes(state, LGDT3302_EQPH_ERR0, buf, 5);
589#ifdef USE_EQMSE
590		/* Use Equalizer Mean-Square Error Register */
591		/* SNR for ranges from -15.61 to +41.58 */
592		noise = ((buf[0] & 7) << 16) | (buf[1] << 8) | buf[2];
593		c = 69765745; /* log10(25*24^2)*2^24 */
594#else
595		/* Use Phase Tracker Mean-Square Error Register */
596		/* SNR for ranges from -13.11 to +44.08 */
597		noise = ((buf[0] & 7<<3) << 13) | (buf[3] << 8) | buf[4];
598		c = 73957994; /* log10(25*32^2)*2^24 */
599#endif
600		break;
601	case QAM_64:
602	case QAM_256:
603		i2c_read_demod_bytes(state, CARRIER_MSEQAM1, buf, 2);
604		noise = ((buf[0] & 3) << 8) | buf[1];
605		c = state->current_modulation == QAM_64 ? 97939837 : 98026066;
606		/* log10(688128)*2^24 and log10(696320)*2^24 */
607		break;
608	default:
609		printk(KERN_ERR "lgdt330x: %s: Modulation set to unsupported value\n",
610		       __FUNCTION__);
611		return -EREMOTEIO; /* return -EDRIVER_IS_GIBBERED; */
612	}
613
614	state->snr = calculate_snr(noise, c);
615	*snr = (state->snr) >> 16; /* Convert from 8.24 fixed-point to 8.8 */
616
617	dprintk("%s: noise = 0x%08x, snr = %d.%02d dB\n", __FUNCTION__, noise,
618		state->snr >> 24, (((state->snr>>8) & 0xffff) * 100) >> 16);
619
620	return 0;
621}
622
623static int lgdt3303_read_snr(struct dvb_frontend* fe, u16* snr)
624{
625	struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv;
626	u8 buf[5];	/* read data buffer */
627	u32 noise;	/* noise value */
628	u32 c;		/* per-modulation SNR calculation constant */
629
630	switch(state->current_modulation) {
631	case VSB_8:
632		i2c_read_demod_bytes(state, LGDT3303_EQPH_ERR0, buf, 5);
633#ifdef USE_EQMSE
634		/* Use Equalizer Mean-Square Error Register */
635		/* SNR for ranges from -16.12 to +44.08 */
636		noise = ((buf[0] & 0x78) << 13) | (buf[1] << 8) | buf[2];
637		c = 73957994; /* log10(25*32^2)*2^24 */
638#else
639		/* Use Phase Tracker Mean-Square Error Register */
640		/* SNR for ranges from -13.11 to +44.08 */
641		noise = ((buf[0] & 7) << 16) | (buf[3] << 8) | buf[4];
642		c = 73957994; /* log10(25*32^2)*2^24 */
643#endif
644		break;
645	case QAM_64:
646	case QAM_256:
647		i2c_read_demod_bytes(state, CARRIER_MSEQAM1, buf, 2);
648		noise = (buf[0] << 8) | buf[1];
649		c = state->current_modulation == QAM_64 ? 97939837 : 98026066;
650		/* log10(688128)*2^24 and log10(696320)*2^24 */
651		break;
652	default:
653		printk(KERN_ERR "lgdt330x: %s: Modulation set to unsupported value\n",
654		       __FUNCTION__);
655		return -EREMOTEIO; /* return -EDRIVER_IS_GIBBERED; */
656	}
657
658	state->snr = calculate_snr(noise, c);
659	*snr = (state->snr) >> 16; /* Convert from 8.24 fixed-point to 8.8 */
660
661	dprintk("%s: noise = 0x%08x, snr = %d.%02d dB\n", __FUNCTION__, noise,
662		state->snr >> 24, (((state->snr >> 8) & 0xffff) * 100) >> 16);
663
664	return 0;
665}
666
667static int lgdt330x_read_signal_strength(struct dvb_frontend* fe, u16* strength)
668{
669	/* Calculate Strength from SNR up to 35dB */
670	/* Even though the SNR can go higher than 35dB, there is some comfort */
671	/* factor in having a range of strong signals that can show at 100%   */
672	struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv;
673	u16 snr;
674	int ret;
675
676	ret = fe->ops.read_snr(fe, &snr);
677	if (ret != 0)
678		return ret;
679	/* Rather than use the 8.8 value snr, use state->snr which is 8.24 */
680	/* scale the range 0 - 35*2^24 into 0 - 65535 */
681	if (state->snr >= 8960 * 0x10000)
682		*strength = 0xffff;
683	else
684		*strength = state->snr / 8960;
685
686	return 0;
687}
688
689static int lgdt330x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fe_tune_settings)
690{
691	/* I have no idea about this - it may not be needed */
692	fe_tune_settings->min_delay_ms = 500;
693	fe_tune_settings->step_size = 0;
694	fe_tune_settings->max_drift = 0;
695	return 0;
696}
697
698static void lgdt330x_release(struct dvb_frontend* fe)
699{
700	struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv;
701	kfree(state);
702}
703
704static struct dvb_frontend_ops lgdt3302_ops;
705static struct dvb_frontend_ops lgdt3303_ops;
706
707struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config,
708				     struct i2c_adapter* i2c)
709{
710	struct lgdt330x_state* state = NULL;
711	u8 buf[1];
712
713	/* Allocate memory for the internal state */
714	state = kzalloc(sizeof(struct lgdt330x_state), GFP_KERNEL);
715	if (state == NULL)
716		goto error;
717
718	/* Setup the state */
719	state->config = config;
720	state->i2c = i2c;
721
722	/* Create dvb_frontend */
723	switch (config->demod_chip) {
724	case LGDT3302:
725		memcpy(&state->frontend.ops, &lgdt3302_ops, sizeof(struct dvb_frontend_ops));
726		break;
727	case LGDT3303:
728		memcpy(&state->frontend.ops, &lgdt3303_ops, sizeof(struct dvb_frontend_ops));
729		break;
730	default:
731		goto error;
732	}
733	state->frontend.demodulator_priv = state;
734
735	/* Verify communication with demod chip */
736	if (i2c_read_demod_bytes(state, 2, buf, 1))
737		goto error;
738
739	state->current_frequency = -1;
740	state->current_modulation = -1;
741
742	return &state->frontend;
743
744error:
745	kfree(state);
746	dprintk("%s: ERROR\n",__FUNCTION__);
747	return NULL;
748}
749
750static struct dvb_frontend_ops lgdt3302_ops = {
751	.info = {
752		.name= "LG Electronics LGDT3302 VSB/QAM Frontend",
753		.type = FE_ATSC,
754		.frequency_min= 54000000,
755		.frequency_max= 858000000,
756		.frequency_stepsize= 62500,
757		.symbol_rate_min    = 5056941,	/* QAM 64 */
758		.symbol_rate_max    = 10762000,	/* VSB 8  */
759		.caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
760	},
761	.init                 = lgdt330x_init,
762	.set_frontend         = lgdt330x_set_parameters,
763	.get_frontend         = lgdt330x_get_frontend,
764	.get_tune_settings    = lgdt330x_get_tune_settings,
765	.read_status          = lgdt3302_read_status,
766	.read_ber             = lgdt330x_read_ber,
767	.read_signal_strength = lgdt330x_read_signal_strength,
768	.read_snr             = lgdt3302_read_snr,
769	.read_ucblocks        = lgdt330x_read_ucblocks,
770	.release              = lgdt330x_release,
771};
772
773static struct dvb_frontend_ops lgdt3303_ops = {
774	.info = {
775		.name= "LG Electronics LGDT3303 VSB/QAM Frontend",
776		.type = FE_ATSC,
777		.frequency_min= 54000000,
778		.frequency_max= 858000000,
779		.frequency_stepsize= 62500,
780		.symbol_rate_min    = 5056941,	/* QAM 64 */
781		.symbol_rate_max    = 10762000,	/* VSB 8  */
782		.caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
783	},
784	.init                 = lgdt330x_init,
785	.set_frontend         = lgdt330x_set_parameters,
786	.get_frontend         = lgdt330x_get_frontend,
787	.get_tune_settings    = lgdt330x_get_tune_settings,
788	.read_status          = lgdt3303_read_status,
789	.read_ber             = lgdt330x_read_ber,
790	.read_signal_strength = lgdt330x_read_signal_strength,
791	.read_snr             = lgdt3303_read_snr,
792	.read_ucblocks        = lgdt330x_read_ucblocks,
793	.release              = lgdt330x_release,
794};
795
796MODULE_DESCRIPTION("LGDT330X (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver");
797MODULE_AUTHOR("Wilson Michaels");
798MODULE_LICENSE("GPL");
799
800EXPORT_SYMBOL(lgdt330x_attach);
801
802/*
803 * Local variables:
804 * c-basic-offset: 8
805 * End:
806 */
807