blob: e1c71afad214a33f0ec9f181a540d825b78503e9 [file] [log] [blame]
Mac Michaelsd8667cb2005-07-07 17:58:29 -07001/*
Michael Krufky1963c902005-08-08 09:22:43 -07002 * Support for LGDT3302 and LGDT3303 - VSB/QAM
Mac Michaelsd8667cb2005-07-07 17:58:29 -07003 *
4 * Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net>
5 *
Mac Michaelsd8667cb2005-07-07 17:58:29 -07006 * 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 *
Michael Krufky1963c902005-08-08 09:22:43 -070025 * This Linux driver supports:
26 * DViCO FusionHDTV 3 Gold-Q
27 * DViCO FusionHDTV 3 Gold-T
28 * DViCO FusionHDTV 5 Gold
Mac Michaelsd8667cb2005-07-07 17:58:29 -070029 *
30 * TODO:
Michael Krufky1963c902005-08-08 09:22:43 -070031 * signal strength always returns 0.
Mac Michaelsd8667cb2005-07-07 17:58:29 -070032 *
33 */
34
Mac Michaelsd8667cb2005-07-07 17:58:29 -070035#include <linux/kernel.h>
36#include <linux/module.h>
37#include <linux/moduleparam.h>
38#include <linux/init.h>
39#include <linux/delay.h>
40#include <asm/byteorder.h>
41
42#include "dvb_frontend.h"
Michael Krufky6ddcc912005-07-27 11:46:00 -070043#include "lgdt330x_priv.h"
44#include "lgdt330x.h"
Mac Michaelsd8667cb2005-07-07 17:58:29 -070045
46static int debug = 0;
47module_param(debug, int, 0644);
Michael Krufky6ddcc912005-07-27 11:46:00 -070048MODULE_PARM_DESC(debug,"Turn on/off lgdt330x frontend debugging (default:off).");
Mac Michaelsd8667cb2005-07-07 17:58:29 -070049#define dprintk(args...) \
50do { \
Michael Krufky6ddcc912005-07-27 11:46:00 -070051if (debug) printk(KERN_DEBUG "lgdt330x: " args); \
Mac Michaelsd8667cb2005-07-07 17:58:29 -070052} while (0)
53
Michael Krufky6ddcc912005-07-27 11:46:00 -070054struct lgdt330x_state
Mac Michaelsd8667cb2005-07-07 17:58:29 -070055{
56 struct i2c_adapter* i2c;
57 struct dvb_frontend_ops ops;
58
59 /* Configuration settings */
Michael Krufky6ddcc912005-07-27 11:46:00 -070060 const struct lgdt330x_config* config;
Mac Michaelsd8667cb2005-07-07 17:58:29 -070061
62 struct dvb_frontend frontend;
63
64 /* Demodulator private data */
65 fe_modulation_t current_modulation;
66
67 /* Tuner private data */
68 u32 current_frequency;
69};
70
Michael Krufky1963c902005-08-08 09:22:43 -070071static int i2c_write_demod_bytes (struct lgdt330x_state* state,
Mac Michaelsd8667cb2005-07-07 17:58:29 -070072 u8 *buf, /* data bytes to send */
73 int len /* number of bytes to send */ )
74{
Michael Krufkyb6aef072005-07-27 11:45:54 -070075 struct i2c_msg msg =
Michael Krufky1963c902005-08-08 09:22:43 -070076 { .addr = state->config->demod_address,
77 .flags = 0,
78 .buf = buf,
79 .len = 2 };
Michael Krufkyb6aef072005-07-27 11:45:54 -070080 int i;
Michael Krufky1963c902005-08-08 09:22:43 -070081 int err;
Mac Michaelsd8667cb2005-07-07 17:58:29 -070082
Michael Krufky1963c902005-08-08 09:22:43 -070083 for (i=0; i<len-1; i+=2){
Mac Michaelsd8667cb2005-07-07 17:58:29 -070084 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
Michael Krufky1963c902005-08-08 09:22:43 -070085 printk(KERN_WARNING "lgdt330x: %s error (addr %02x <- %02x, err = %i)\n", __FUNCTION__, msg.buf[0], msg.buf[1], err);
Michael Krufky58ba0062005-07-12 13:58:37 -070086 if (err < 0)
87 return err;
88 else
89 return -EREMOTEIO;
Mac Michaelsd8667cb2005-07-07 17:58:29 -070090 }
Michael Krufky1963c902005-08-08 09:22:43 -070091 msg.buf += 2;
Mac Michaelsd8667cb2005-07-07 17:58:29 -070092 }
93 return 0;
94}
Michael Krufkyb6aef072005-07-27 11:45:54 -070095
Mac Michaelsd8667cb2005-07-07 17:58:29 -070096/*
97 * This routine writes the register (reg) to the demod bus
98 * then reads the data returned for (len) bytes.
99 */
100
Michael Krufky1963c902005-08-08 09:22:43 -0700101static u8 i2c_read_demod_bytes (struct lgdt330x_state* state,
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700102 enum I2C_REG reg, u8* buf, int len)
103{
104 u8 wr [] = { reg };
105 struct i2c_msg msg [] = {
106 { .addr = state->config->demod_address,
107 .flags = 0, .buf = wr, .len = 1 },
108 { .addr = state->config->demod_address,
109 .flags = I2C_M_RD, .buf = buf, .len = len },
110 };
111 int ret;
112 ret = i2c_transfer(state->i2c, msg, 2);
113 if (ret != 2) {
Michael Krufky6ddcc912005-07-27 11:46:00 -0700114 printk(KERN_WARNING "lgdt330x: %s: addr 0x%02x select 0x%02x error (ret == %i)\n", __FUNCTION__, state->config->demod_address, reg, ret);
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700115 } else {
116 ret = 0;
117 }
118 return ret;
119}
120
121/* Software reset */
Michael Krufky1963c902005-08-08 09:22:43 -0700122static int lgdt3302_SwReset(struct lgdt330x_state* state)
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700123{
124 u8 ret;
125 u8 reset[] = {
126 IRQ_MASK,
127 0x00 /* bit 6 is active low software reset
128 * bits 5-0 are 1 to mask interrupts */
129 };
130
Michael Krufky1963c902005-08-08 09:22:43 -0700131 ret = i2c_write_demod_bytes(state,
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700132 reset, sizeof(reset));
133 if (ret == 0) {
Michael Krufky1963c902005-08-08 09:22:43 -0700134
135 /* force reset high (inactive) and unmask interrupts */
136 reset[1] = 0x7f;
137 ret = i2c_write_demod_bytes(state,
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700138 reset, sizeof(reset));
139 }
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700140 return ret;
141}
142
Michael Krufky1963c902005-08-08 09:22:43 -0700143static int lgdt3303_SwReset(struct lgdt330x_state* state)
144{
145 u8 ret;
146 u8 reset[] = {
147 0x02,
148 0x00 /* bit 0 is active low software reset */
149 };
150
151 ret = i2c_write_demod_bytes(state,
152 reset, sizeof(reset));
153 if (ret == 0) {
154
155 /* force reset high (inactive) */
156 reset[1] = 0x01;
157 ret = i2c_write_demod_bytes(state,
158 reset, sizeof(reset));
159 }
160 return ret;
161}
162
163static int lgdt330x_SwReset(struct lgdt330x_state* state)
164{
165 switch (state->config->demod_chip) {
166 case LGDT3302:
167 return lgdt3302_SwReset(state);
168 case LGDT3303:
169 return lgdt3303_SwReset(state);
170 default:
171 return -ENODEV;
172 }
173}
174
175#ifdef MUTE_TDA9887
176static int i2c_write_ntsc_demod (struct lgdt330x_state* state, u8 buf[2])
177{
178 struct i2c_msg msg =
179 { .addr = 0x43,
180 .flags = 0,
181 .buf = buf,
182 .len = 2 };
183 int err;
184
185 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
186 printk(KERN_WARNING "lgdt330x: %s error (addr %02x <- %02x, err = %i)\n", __FUNCTION__, msg.buf[0], msg.buf[1], err);
187 if (err < 0)
188 return err;
189 else
190 return -EREMOTEIO;
191 }
192 return 0;
193}
194
195static void fiddle_with_ntsc_if_demod(struct lgdt330x_state* state)
196{
197 // Experimental code
198 u8 buf0[] = {0x00, 0x20};
199 u8 buf1[] = {0x01, 0x00};
200 u8 buf2[] = {0x02, 0x00};
201
202 i2c_write_ntsc_demod(state, buf0);
203 i2c_write_ntsc_demod(state, buf1);
204 i2c_write_ntsc_demod(state, buf2);
205}
206#endif
207
Michael Krufky6ddcc912005-07-27 11:46:00 -0700208static int lgdt330x_init(struct dvb_frontend* fe)
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700209{
210 /* Hardware reset is done using gpio[0] of cx23880x chip.
211 * I'd like to do it here, but don't know how to find chip address.
212 * cx88-cards.c arranges for the reset bit to be inactive (high).
213 * Maybe there needs to be a callable function in cx88-core or
214 * the caller of this function needs to do it. */
215
Michael Krufky1963c902005-08-08 09:22:43 -0700216 /*
217 * Array of byte pairs <address, value>
218 * to initialize each different chip
219 */
220 static u8 lgdt3302_init_data[] = {
221 /* Use 50MHz parameter values from spec sheet since xtal is 50 */
222 /* Change the value of NCOCTFV[25:0] of carrier
223 recovery center frequency register */
224 VSB_CARRIER_FREQ0, 0x00,
225 VSB_CARRIER_FREQ1, 0x87,
226 VSB_CARRIER_FREQ2, 0x8e,
227 VSB_CARRIER_FREQ3, 0x01,
228 /* Change the TPCLK pin polarity
229 data is valid on falling clock */
230 DEMUX_CONTROL, 0xfb,
231 /* Change the value of IFBW[11:0] of
232 AGC IF/RF loop filter bandwidth register */
233 AGC_RF_BANDWIDTH0, 0x40,
234 AGC_RF_BANDWIDTH1, 0x93,
235 AGC_RF_BANDWIDTH2, 0x00,
236 /* Change the value of bit 6, 'nINAGCBY' and
237 'NSSEL[1:0] of ACG function control register 2 */
238 AGC_FUNC_CTRL2, 0xc6,
239 /* Change the value of bit 6 'RFFIX'
240 of AGC function control register 3 */
241 AGC_FUNC_CTRL3, 0x40,
242 /* Set the value of 'INLVTHD' register 0x2a/0x2c
243 to 0x7fe */
244 AGC_DELAY0, 0x07,
245 AGC_DELAY2, 0xfe,
246 /* Change the value of IAGCBW[15:8]
247 of inner AGC loop filter bandwith */
248 AGC_LOOP_BANDWIDTH0, 0x08,
249 AGC_LOOP_BANDWIDTH1, 0x9a
250 };
251
252 static u8 lgdt3303_init_data[] = {
253 0x4c, 0x14
254 };
255
256 struct lgdt330x_state* state = fe->demodulator_priv;
257 char *chip_name;
258 int err;
259
260 switch (state->config->demod_chip) {
261 case LGDT3302:
262 chip_name = "LGDT3302";
263 err = i2c_write_demod_bytes(state, lgdt3302_init_data,
264 sizeof(lgdt3302_init_data));
265 break;
266 case LGDT3303:
267 chip_name = "LGDT3303";
268 err = i2c_write_demod_bytes(state, lgdt3303_init_data,
269 sizeof(lgdt3303_init_data));
270#ifdef MUTE_TDA9887
271 fiddle_with_ntsc_if_demod(state);
272#endif
273 break;
274 default:
275 chip_name = "undefined";
276 printk (KERN_WARNING "Only LGDT3302 and LGDT3303 are supported chips.\n");
277 err = -ENODEV;
278 }
279 dprintk("%s entered as %s\n", __FUNCTION__, chip_name);
280 if (err < 0)
281 return err;
282 return lgdt330x_SwReset(state);
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700283}
284
Michael Krufky6ddcc912005-07-27 11:46:00 -0700285static int lgdt330x_read_ber(struct dvb_frontend* fe, u32* ber)
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700286{
Michael Krufky1963c902005-08-08 09:22:43 -0700287 *ber = 0; /* Not supplied by the demod chips */
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700288 return 0;
289}
290
Michael Krufky6ddcc912005-07-27 11:46:00 -0700291static int lgdt330x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700292{
Michael Krufky1963c902005-08-08 09:22:43 -0700293 struct lgdt330x_state* state = fe->demodulator_priv;
294 int err;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700295 u8 buf[2];
296
Michael Krufky1963c902005-08-08 09:22:43 -0700297 switch (state->config->demod_chip) {
298 case LGDT3302:
299 err = i2c_read_demod_bytes(state, LGDT3302_PACKET_ERR_COUNTER1,
300 buf, sizeof(buf));
301 break;
302 case LGDT3303:
303 err = i2c_read_demod_bytes(state, LGDT3303_PACKET_ERR_COUNTER1,
304 buf, sizeof(buf));
305 break;
306 default:
307 printk(KERN_WARNING
308 "Only LGDT3302 and LGDT3303 are supported chips.\n");
309 err = -ENODEV;
310 }
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700311
312 *ucblocks = (buf[0] << 8) | buf[1];
313 return 0;
314}
315
Michael Krufky6ddcc912005-07-27 11:46:00 -0700316static int lgdt330x_set_parameters(struct dvb_frontend* fe,
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700317 struct dvb_frontend_parameters *param)
318{
Michael Krufky1963c902005-08-08 09:22:43 -0700319 /*
320 * Array of byte pairs <address, value>
321 * to initialize 8VSB for lgdt3303 chip 50 MHz IF
322 */
323 static u8 lgdt3303_8vsb_44_data[] = {
324 0x04, 0x00,
325 0x0d, 0x40,
326 0x0e, 0x87,
327 0x0f, 0x8e,
328 0x10, 0x01,
329 0x47, 0x8b };
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700330
Michael Krufky1963c902005-08-08 09:22:43 -0700331 /*
332 * Array of byte pairs <address, value>
333 * to initialize QAM for lgdt3303 chip
334 */
335 static u8 lgdt3303_qam_data[] = {
336 0x04, 0x00,
337 0x0d, 0x00,
338 0x0e, 0x00,
339 0x0f, 0x00,
340 0x10, 0x00,
341 0x51, 0x63,
342 0x47, 0x66,
343 0x48, 0x66,
344 0x4d, 0x1a,
345 0x49, 0x08,
346 0x4a, 0x9b };
347
348 struct lgdt330x_state* state = fe->demodulator_priv;
349
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700350 static u8 top_ctrl_cfg[] = { TOP_CONTROL, 0x03 };
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700351
Michael Krufky1963c902005-08-08 09:22:43 -0700352 int err;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700353 /* Change only if we are actually changing the modulation */
354 if (state->current_modulation != param->u.vsb.modulation) {
355 switch(param->u.vsb.modulation) {
356 case VSB_8:
357 dprintk("%s: VSB_8 MODE\n", __FUNCTION__);
358
Michael Krufky1963c902005-08-08 09:22:43 -0700359 /* Select VSB mode */
360 top_ctrl_cfg[1] = 0x03;
Michael Krufky0ccef6d2005-07-27 11:45:55 -0700361
362 /* Select ANT connector if supported by card */
363 if (state->config->pll_rf_set)
364 state->config->pll_rf_set(fe, 1);
Michael Krufky1963c902005-08-08 09:22:43 -0700365
366 if (state->config->demod_chip == LGDT3303) {
367 err = i2c_write_demod_bytes(state, lgdt3303_8vsb_44_data,
368 sizeof(lgdt3303_8vsb_44_data));
369 }
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700370 break;
371
372 case QAM_64:
373 dprintk("%s: QAM_64 MODE\n", __FUNCTION__);
374
Michael Krufky1963c902005-08-08 09:22:43 -0700375 /* Select QAM_64 mode */
376 top_ctrl_cfg[1] = 0x00;
Michael Krufky0ccef6d2005-07-27 11:45:55 -0700377
378 /* Select CABLE connector if supported by card */
379 if (state->config->pll_rf_set)
380 state->config->pll_rf_set(fe, 0);
Michael Krufky1963c902005-08-08 09:22:43 -0700381
382 if (state->config->demod_chip == LGDT3303) {
383 err = i2c_write_demod_bytes(state, lgdt3303_qam_data,
384 sizeof(lgdt3303_qam_data));
385 }
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700386 break;
387
388 case QAM_256:
389 dprintk("%s: QAM_256 MODE\n", __FUNCTION__);
390
Michael Krufky1963c902005-08-08 09:22:43 -0700391 /* Select QAM_256 mode */
392 top_ctrl_cfg[1] = 0x01;
Michael Krufky0ccef6d2005-07-27 11:45:55 -0700393
394 /* Select CABLE connector if supported by card */
395 if (state->config->pll_rf_set)
396 state->config->pll_rf_set(fe, 0);
Michael Krufky1963c902005-08-08 09:22:43 -0700397
398 if (state->config->demod_chip == LGDT3303) {
399 err = i2c_write_demod_bytes(state, lgdt3303_qam_data,
400 sizeof(lgdt3303_qam_data));
401 }
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700402 break;
403 default:
Michael Krufky6ddcc912005-07-27 11:46:00 -0700404 printk(KERN_WARNING "lgdt330x: %s: Modulation type(%d) UNSUPPORTED\n", __FUNCTION__, param->u.vsb.modulation);
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700405 return -1;
406 }
Michael Krufky1963c902005-08-08 09:22:43 -0700407 /*
408 * select serial or parallel MPEG harware interface
409 * Serial: 0x04 for LGDT3302 or 0x40 for LGDT3303
410 * Parallel: 0x00
411 */
412 top_ctrl_cfg[1] |= state->config->serial_mpeg;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700413
414 /* Select the requested mode */
Michael Krufky1963c902005-08-08 09:22:43 -0700415 i2c_write_demod_bytes(state, top_ctrl_cfg,
416 sizeof(top_ctrl_cfg));
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700417 state->config->set_ts_params(fe, 0);
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700418 state->current_modulation = param->u.vsb.modulation;
419 }
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700420
421 /* Change only if we are actually changing the channel */
422 if (state->current_frequency != param->frequency) {
Michael Krufky1963c902005-08-08 09:22:43 -0700423 /* Tune to the new frequency */
424 state->config->pll_set(fe, param);
425 /* Keep track of the new frequency */
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700426 state->current_frequency = param->frequency;
427 }
Michael Krufky6ddcc912005-07-27 11:46:00 -0700428 lgdt330x_SwReset(state);
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700429 return 0;
430}
431
Michael Krufky6ddcc912005-07-27 11:46:00 -0700432static int lgdt330x_get_frontend(struct dvb_frontend* fe,
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700433 struct dvb_frontend_parameters* param)
434{
Michael Krufky6ddcc912005-07-27 11:46:00 -0700435 struct lgdt330x_state *state = fe->demodulator_priv;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700436 param->frequency = state->current_frequency;
437 return 0;
438}
439
Michael Krufky1963c902005-08-08 09:22:43 -0700440static int lgdt3302_read_status(struct dvb_frontend* fe, fe_status_t* status)
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700441{
Michael Krufky1963c902005-08-08 09:22:43 -0700442 struct lgdt330x_state* state = fe->demodulator_priv;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700443 u8 buf[3];
444
445 *status = 0; /* Reset status result */
446
Michael Krufky08d80522005-07-07 17:58:43 -0700447 /* AGC status register */
Michael Krufky1963c902005-08-08 09:22:43 -0700448 i2c_read_demod_bytes(state, AGC_STATUS, buf, 1);
Michael Krufky08d80522005-07-07 17:58:43 -0700449 dprintk("%s: AGC_STATUS = 0x%02x\n", __FUNCTION__, buf[0]);
450 if ((buf[0] & 0x0c) == 0x8){
451 /* Test signal does not exist flag */
452 /* as well as the AGC lock flag. */
453 *status |= FE_HAS_SIGNAL;
454 } else {
455 /* Without a signal all other status bits are meaningless */
456 return 0;
457 }
458
Michael Krufky1963c902005-08-08 09:22:43 -0700459 /*
460 * You must set the Mask bits to 1 in the IRQ_MASK in order
461 * to see that status bit in the IRQ_STATUS register.
462 * This is done in SwReset();
463 */
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700464 /* signal status */
Michael Krufky1963c902005-08-08 09:22:43 -0700465 i2c_read_demod_bytes(state, TOP_CONTROL, buf, sizeof(buf));
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700466 dprintk("%s: TOP_CONTROL = 0x%02x, IRO_MASK = 0x%02x, IRQ_STATUS = 0x%02x\n", __FUNCTION__, buf[0], buf[1], buf[2]);
Michael Krufky08d80522005-07-07 17:58:43 -0700467
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700468
469 /* sync status */
470 if ((buf[2] & 0x03) == 0x01) {
471 *status |= FE_HAS_SYNC;
472 }
473
474 /* FEC error status */
475 if ((buf[2] & 0x0c) == 0x08) {
476 *status |= FE_HAS_LOCK;
477 *status |= FE_HAS_VITERBI;
478 }
479
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700480 /* Carrier Recovery Lock Status Register */
Michael Krufky1963c902005-08-08 09:22:43 -0700481 i2c_read_demod_bytes(state, CARRIER_LOCK, buf, 1);
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700482 dprintk("%s: CARRIER_LOCK = 0x%02x\n", __FUNCTION__, buf[0]);
483 switch (state->current_modulation) {
484 case QAM_256:
485 case QAM_64:
486 /* Need to undestand why there are 3 lock levels here */
487 if ((buf[0] & 0x07) == 0x07)
488 *status |= FE_HAS_CARRIER;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700489 break;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700490 case VSB_8:
491 if ((buf[0] & 0x80) == 0x80)
492 *status |= FE_HAS_CARRIER;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700493 break;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700494 default:
Michael Krufky6ddcc912005-07-27 11:46:00 -0700495 printk("KERN_WARNING lgdt330x: %s: Modulation set to unsupported value\n", __FUNCTION__);
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700496 }
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700497
498 return 0;
499}
500
Michael Krufky1963c902005-08-08 09:22:43 -0700501static int lgdt3303_read_status(struct dvb_frontend* fe, fe_status_t* status)
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700502{
Michael Krufky1963c902005-08-08 09:22:43 -0700503 struct lgdt330x_state* state = fe->demodulator_priv;
504 int err;
505 u8 buf[3];
506
507 *status = 0; /* Reset status result */
508
509 /* lgdt3303 AGC status register */
510 err = i2c_read_demod_bytes(state, 0x58, buf, 1);
511 if (err < 0)
512 return err;
513
514 dprintk("%s: AGC_STATUS = 0x%02x\n", __FUNCTION__, buf[0]);
515 if ((buf[0] & 0x21) == 0x01){
516 /* Test input signal does not exist flag */
517 /* as well as the AGC lock flag. */
518 *status |= FE_HAS_SIGNAL;
519 } else {
520 /* Without a signal all other status bits are meaningless */
521 return 0;
522 }
523
524 /* Carrier Recovery Lock Status Register */
525 i2c_read_demod_bytes(state, CARRIER_LOCK, buf, 1);
526 dprintk("%s: CARRIER_LOCK = 0x%02x\n", __FUNCTION__, buf[0]);
527 switch (state->current_modulation) {
528 case QAM_256:
529 case QAM_64:
530 /* Need to undestand why there are 3 lock levels here */
531 if ((buf[0] & 0x07) == 0x07)
532 *status |= FE_HAS_CARRIER;
533 else
534 break;
535 i2c_read_demod_bytes(state, 0x8a, buf, 1);
536 if ((buf[0] & 0x04) == 0x04)
537 *status |= FE_HAS_SYNC;
538 if ((buf[0] & 0x01) == 0x01)
539 *status |= FE_HAS_LOCK;
540 if ((buf[0] & 0x08) == 0x08)
541 *status |= FE_HAS_VITERBI;
542 break;
543 case VSB_8:
544 if ((buf[0] & 0x80) == 0x80)
545 *status |= FE_HAS_CARRIER;
546 else
547 break;
548 i2c_read_demod_bytes(state, 0x38, buf, 1);
549 if ((buf[0] & 0x02) == 0x00)
550 *status |= FE_HAS_SYNC;
551 if ((buf[0] & 0x01) == 0x01) {
552 *status |= FE_HAS_LOCK;
553 *status |= FE_HAS_VITERBI;
554 }
555 break;
556 default:
557 printk("KERN_WARNING lgdt330x: %s: Modulation set to unsupported value\n", __FUNCTION__);
558 }
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700559 return 0;
560}
561
Michael Krufky1963c902005-08-08 09:22:43 -0700562static int lgdt330x_read_signal_strength(struct dvb_frontend* fe, u16* strength)
563{
564 /* not directly available. */
565 *strength = 0;
566 return 0;
567}
568
569static int lgdt3302_read_snr(struct dvb_frontend* fe, u16* snr)
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700570{
571#ifdef SNR_IN_DB
572 /*
573 * Spec sheet shows formula for SNR_EQ = 10 log10(25 * 24**2 / noise)
574 * and SNR_PH = 10 log10(25 * 32**2 / noise) for equalizer and phase tracker
575 * respectively. The following tables are built on these formulas.
576 * The usual definition is SNR = 20 log10(signal/noise)
577 * If the specification is wrong the value retuned is 1/2 the actual SNR in db.
578 *
579 * This table is a an ordered list of noise values computed by the
580 * formula from the spec sheet such that the index into the table
581 * starting at 43 or 45 is the SNR value in db. There are duplicate noise
582 * value entries at the beginning because the SNR varies more than
583 * 1 db for a change of 1 digit in noise at very small values of noise.
584 *
585 * Examples from SNR_EQ table:
586 * noise SNR
587 * 0 43
588 * 1 42
589 * 2 39
590 * 3 37
591 * 4 36
592 * 5 35
593 * 6 34
594 * 7 33
595 * 8 33
596 * 9 32
597 * 10 32
598 * 11 31
599 * 12 31
600 * 13 30
601 */
602
603 static const u32 SNR_EQ[] =
604 { 1, 2, 2, 2, 3, 3, 4, 4, 5, 7,
605 9, 11, 13, 17, 21, 26, 33, 41, 52, 65,
606 81, 102, 129, 162, 204, 257, 323, 406, 511, 644,
607 810, 1020, 1284, 1616, 2035, 2561, 3224, 4059, 5110, 6433,
608 8098, 10195, 12835, 16158, 20341, 25608, 32238, 40585, 51094, 64323,
609 80978, 101945, 128341, 161571, 203406, 256073, 0x40000
610 };
611
612 static const u32 SNR_PH[] =
613 { 1, 2, 2, 2, 3, 3, 4, 5, 6, 8,
614 10, 12, 15, 19, 23, 29, 37, 46, 58, 73,
615 91, 115, 144, 182, 229, 288, 362, 456, 574, 722,
616 909, 1144, 1440, 1813, 2282, 2873, 3617, 4553, 5732, 7216,
617 9084, 11436, 14396, 18124, 22817, 28724, 36161, 45524, 57312, 72151,
Michael Krufky1963c902005-08-08 09:22:43 -0700618 90833, 114351, 143960, 181235, 228161, 0x080000
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700619 };
620
621 static u8 buf[5];/* read data buffer */
622 static u32 noise; /* noise value */
623 static u32 snr_db; /* index into SNR_EQ[] */
Michael Krufky6ddcc912005-07-27 11:46:00 -0700624 struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700625
Michael Krufky1963c902005-08-08 09:22:43 -0700626 /* read both equalizer and phase tracker noise data */
627 i2c_read_demod_bytes(state, EQPH_ERR0, buf, sizeof(buf));
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700628
629 if (state->current_modulation == VSB_8) {
630 /* Equalizer Mean-Square Error Register for VSB */
631 noise = ((buf[0] & 7) << 16) | (buf[1] << 8) | buf[2];
632
633 /*
634 * Look up noise value in table.
635 * A better search algorithm could be used...
636 * watch out there are duplicate entries.
637 */
638 for (snr_db = 0; snr_db < sizeof(SNR_EQ); snr_db++) {
639 if (noise < SNR_EQ[snr_db]) {
640 *snr = 43 - snr_db;
641 break;
642 }
643 }
644 } else {
645 /* Phase Tracker Mean-Square Error Register for QAM */
646 noise = ((buf[0] & 7<<3) << 13) | (buf[3] << 8) | buf[4];
647
648 /* Look up noise value in table. */
649 for (snr_db = 0; snr_db < sizeof(SNR_PH); snr_db++) {
650 if (noise < SNR_PH[snr_db]) {
651 *snr = 45 - snr_db;
652 break;
653 }
654 }
655 }
656#else
657 /* Return the raw noise value */
658 static u8 buf[5];/* read data buffer */
659 static u32 noise; /* noise value */
Michael Krufky6ddcc912005-07-27 11:46:00 -0700660 struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700661
662 /* read both equalizer and pase tracker noise data */
Michael Krufky1963c902005-08-08 09:22:43 -0700663 i2c_read_demod_bytes(state, EQPH_ERR0, buf, sizeof(buf));
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700664
665 if (state->current_modulation == VSB_8) {
Michael Krufky1963c902005-08-08 09:22:43 -0700666 /* Phase Tracker Mean-Square Error Register for VSB */
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700667 noise = ((buf[0] & 7<<3) << 13) | (buf[3] << 8) | buf[4];
Michael Krufky1963c902005-08-08 09:22:43 -0700668 } else {
669
670 /* Carrier Recovery Mean-Square Error for QAM */
671 i2c_read_demod_bytes(state, 0x1a, buf, 2);
672 noise = ((buf[0] & 3) << 8) | buf[1];
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700673 }
674
675 /* Small values for noise mean signal is better so invert noise */
Michael Krufky1963c902005-08-08 09:22:43 -0700676 *snr = ~noise;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700677#endif
678
679 dprintk("%s: noise = 0x%05x, snr = %idb\n",__FUNCTION__, noise, *snr);
680
681 return 0;
682}
683
Michael Krufky1963c902005-08-08 09:22:43 -0700684static int lgdt3303_read_snr(struct dvb_frontend* fe, u16* snr)
685{
686 /* Return the raw noise value */
687 static u8 buf[5];/* read data buffer */
688 static u32 noise; /* noise value */
689 struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv;
690
691 if (state->current_modulation == VSB_8) {
692
693 /* Phase Tracker Mean-Square Error Register for VSB */
694 noise = ((buf[0] & 7) << 16) | (buf[3] << 8) | buf[4];
695 } else {
696
697 /* Carrier Recovery Mean-Square Error for QAM */
698 i2c_read_demod_bytes(state, 0x1a, buf, 2);
699 noise = (buf[0] << 8) | buf[1];
700 }
701
702 /* Small values for noise mean signal is better so invert noise */
703 *snr = ~noise;
704
705 dprintk("%s: noise = 0x%05x, snr = %idb\n",__FUNCTION__, noise, *snr);
706
707 return 0;
708}
709
Michael Krufky6ddcc912005-07-27 11:46:00 -0700710static int lgdt330x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fe_tune_settings)
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700711{
712 /* I have no idea about this - it may not be needed */
713 fe_tune_settings->min_delay_ms = 500;
714 fe_tune_settings->step_size = 0;
715 fe_tune_settings->max_drift = 0;
716 return 0;
717}
718
Michael Krufky6ddcc912005-07-27 11:46:00 -0700719static void lgdt330x_release(struct dvb_frontend* fe)
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700720{
Michael Krufky6ddcc912005-07-27 11:46:00 -0700721 struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700722 kfree(state);
723}
724
Michael Krufky1963c902005-08-08 09:22:43 -0700725static struct dvb_frontend_ops lgdt3302_ops;
726static struct dvb_frontend_ops lgdt3303_ops;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700727
Michael Krufky6ddcc912005-07-27 11:46:00 -0700728struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config,
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700729 struct i2c_adapter* i2c)
730{
Michael Krufky6ddcc912005-07-27 11:46:00 -0700731 struct lgdt330x_state* state = NULL;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700732 u8 buf[1];
733
734 /* Allocate memory for the internal state */
Michael Krufky6ddcc912005-07-27 11:46:00 -0700735 state = (struct lgdt330x_state*) kmalloc(sizeof(struct lgdt330x_state), GFP_KERNEL);
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700736 if (state == NULL)
737 goto error;
738 memset(state,0,sizeof(*state));
739
740 /* Setup the state */
741 state->config = config;
742 state->i2c = i2c;
Michael Krufky1963c902005-08-08 09:22:43 -0700743 switch (config->demod_chip) {
744 case LGDT3302:
745 memcpy(&state->ops, &lgdt3302_ops, sizeof(struct dvb_frontend_ops));
746 break;
747 case LGDT3303:
748 memcpy(&state->ops, &lgdt3303_ops, sizeof(struct dvb_frontend_ops));
749 break;
750 default:
751 goto error;
752 }
753
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700754 /* Verify communication with demod chip */
Michael Krufky1963c902005-08-08 09:22:43 -0700755 if (i2c_read_demod_bytes(state, 2, buf, 1))
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700756 goto error;
757
758 state->current_frequency = -1;
759 state->current_modulation = -1;
760
761 /* Create dvb_frontend */
762 state->frontend.ops = &state->ops;
763 state->frontend.demodulator_priv = state;
764 return &state->frontend;
765
766error:
767 if (state)
768 kfree(state);
769 dprintk("%s: ERROR\n",__FUNCTION__);
770 return NULL;
771}
772
Michael Krufky1963c902005-08-08 09:22:43 -0700773static struct dvb_frontend_ops lgdt3302_ops = {
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700774 .info = {
Michael Krufkye179d8b2005-08-09 17:48:54 -0700775 .name= "LG Electronics LGDT3302 VSB/QAM Frontend",
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700776 .type = FE_ATSC,
777 .frequency_min= 54000000,
778 .frequency_max= 858000000,
779 .frequency_stepsize= 62500,
780 /* Symbol rate is for all VSB modes need to check QAM */
781 .symbol_rate_min = 10762000,
782 .symbol_rate_max = 10762000,
783 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
784 },
Michael Krufky6ddcc912005-07-27 11:46:00 -0700785 .init = lgdt330x_init,
786 .set_frontend = lgdt330x_set_parameters,
787 .get_frontend = lgdt330x_get_frontend,
788 .get_tune_settings = lgdt330x_get_tune_settings,
Michael Krufky1963c902005-08-08 09:22:43 -0700789 .read_status = lgdt3302_read_status,
Michael Krufky6ddcc912005-07-27 11:46:00 -0700790 .read_ber = lgdt330x_read_ber,
791 .read_signal_strength = lgdt330x_read_signal_strength,
Michael Krufky1963c902005-08-08 09:22:43 -0700792 .read_snr = lgdt3302_read_snr,
Michael Krufky6ddcc912005-07-27 11:46:00 -0700793 .read_ucblocks = lgdt330x_read_ucblocks,
794 .release = lgdt330x_release,
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700795};
796
Michael Krufky1963c902005-08-08 09:22:43 -0700797static struct dvb_frontend_ops lgdt3303_ops = {
798 .info = {
799 .name= "LG Electronics LGDT3303 VSB/QAM Frontend",
800 .type = FE_ATSC,
801 .frequency_min= 54000000,
802 .frequency_max= 858000000,
803 .frequency_stepsize= 62500,
804 /* Symbol rate is for all VSB modes need to check QAM */
805 .symbol_rate_min = 10762000,
806 .symbol_rate_max = 10762000,
807 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
808 },
809 .init = lgdt330x_init,
810 .set_frontend = lgdt330x_set_parameters,
811 .get_frontend = lgdt330x_get_frontend,
812 .get_tune_settings = lgdt330x_get_tune_settings,
813 .read_status = lgdt3303_read_status,
814 .read_ber = lgdt330x_read_ber,
815 .read_signal_strength = lgdt330x_read_signal_strength,
816 .read_snr = lgdt3303_read_snr,
817 .read_ucblocks = lgdt330x_read_ucblocks,
818 .release = lgdt330x_release,
819};
820
821MODULE_DESCRIPTION("LGDT330X (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver");
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700822MODULE_AUTHOR("Wilson Michaels");
823MODULE_LICENSE("GPL");
824
Michael Krufky6ddcc912005-07-27 11:46:00 -0700825EXPORT_SYMBOL(lgdt330x_attach);
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700826
827/*
828 * Local variables:
829 * c-basic-offset: 8
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700830 * End:
831 */