blob: 56fcb9e97b572d8a3c3dc7af14c236cd11723dcf [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
Michael Krufky3cff00d2005-11-08 21:35:12 -080029 * DViCO FusionHDTV 5 Lite
Michael Krufkyc0b11b92005-11-08 21:35:32 -080030 * Air2PC/AirStar 2 ATSC 3rd generation (HD5000)
Mac Michaelsd8667cb2005-07-07 17:58:29 -070031 *
32 * TODO:
Michael Krufky1963c902005-08-08 09:22:43 -070033 * signal strength always returns 0.
Mac Michaelsd8667cb2005-07-07 17:58:29 -070034 *
35 */
36
Mac Michaelsd8667cb2005-07-07 17:58:29 -070037#include <linux/kernel.h>
38#include <linux/module.h>
39#include <linux/moduleparam.h>
40#include <linux/init.h>
41#include <linux/delay.h>
Tim Schmielau4e57b682005-10-30 15:03:48 -080042#include <linux/string.h>
43#include <linux/slab.h>
Mac Michaelsd8667cb2005-07-07 17:58:29 -070044#include <asm/byteorder.h>
45
46#include "dvb_frontend.h"
Michael Krufky6ddcc912005-07-27 11:46:00 -070047#include "lgdt330x_priv.h"
48#include "lgdt330x.h"
Mac Michaelsd8667cb2005-07-07 17:58:29 -070049
50static int debug = 0;
51module_param(debug, int, 0644);
Michael Krufky6ddcc912005-07-27 11:46:00 -070052MODULE_PARM_DESC(debug,"Turn on/off lgdt330x frontend debugging (default:off).");
Mac Michaelsd8667cb2005-07-07 17:58:29 -070053#define dprintk(args...) \
54do { \
Michael Krufky6ddcc912005-07-27 11:46:00 -070055if (debug) printk(KERN_DEBUG "lgdt330x: " args); \
Mac Michaelsd8667cb2005-07-07 17:58:29 -070056} while (0)
57
Michael Krufky6ddcc912005-07-27 11:46:00 -070058struct lgdt330x_state
Mac Michaelsd8667cb2005-07-07 17:58:29 -070059{
60 struct i2c_adapter* i2c;
61 struct dvb_frontend_ops ops;
62
63 /* Configuration settings */
Michael Krufky6ddcc912005-07-27 11:46:00 -070064 const struct lgdt330x_config* config;
Mac Michaelsd8667cb2005-07-07 17:58:29 -070065
66 struct dvb_frontend frontend;
67
68 /* Demodulator private data */
69 fe_modulation_t current_modulation;
70
71 /* Tuner private data */
72 u32 current_frequency;
73};
74
Michael Krufky1963c902005-08-08 09:22:43 -070075static int i2c_write_demod_bytes (struct lgdt330x_state* state,
Michael Krufkydc9ca2a2005-09-06 15:19:40 -070076 u8 *buf, /* data bytes to send */
77 int len /* number of bytes to send */ )
Mac Michaelsd8667cb2005-07-07 17:58:29 -070078{
Michael Krufkyb6aef072005-07-27 11:45:54 -070079 struct i2c_msg msg =
Michael Krufky1963c902005-08-08 09:22:43 -070080 { .addr = state->config->demod_address,
81 .flags = 0,
82 .buf = buf,
83 .len = 2 };
Michael Krufkyb6aef072005-07-27 11:45:54 -070084 int i;
Michael Krufky1963c902005-08-08 09:22:43 -070085 int err;
Mac Michaelsd8667cb2005-07-07 17:58:29 -070086
Michael Krufky1963c902005-08-08 09:22:43 -070087 for (i=0; i<len-1; i+=2){
Mac Michaelsd8667cb2005-07-07 17:58:29 -070088 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
Michael Krufky1963c902005-08-08 09:22:43 -070089 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 -070090 if (err < 0)
91 return err;
92 else
93 return -EREMOTEIO;
Mac Michaelsd8667cb2005-07-07 17:58:29 -070094 }
Michael Krufky1963c902005-08-08 09:22:43 -070095 msg.buf += 2;
Mac Michaelsd8667cb2005-07-07 17:58:29 -070096 }
97 return 0;
98}
Michael Krufkyb6aef072005-07-27 11:45:54 -070099
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700100/*
101 * This routine writes the register (reg) to the demod bus
102 * then reads the data returned for (len) bytes.
103 */
104
Michael Krufky1963c902005-08-08 09:22:43 -0700105static u8 i2c_read_demod_bytes (struct lgdt330x_state* state,
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700106 enum I2C_REG reg, u8* buf, int len)
107{
108 u8 wr [] = { reg };
109 struct i2c_msg msg [] = {
110 { .addr = state->config->demod_address,
111 .flags = 0, .buf = wr, .len = 1 },
112 { .addr = state->config->demod_address,
113 .flags = I2C_M_RD, .buf = buf, .len = len },
114 };
115 int ret;
116 ret = i2c_transfer(state->i2c, msg, 2);
117 if (ret != 2) {
Michael Krufky6ddcc912005-07-27 11:46:00 -0700118 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 -0700119 } else {
120 ret = 0;
121 }
122 return ret;
123}
124
125/* Software reset */
Michael Krufky1963c902005-08-08 09:22:43 -0700126static int lgdt3302_SwReset(struct lgdt330x_state* state)
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700127{
128 u8 ret;
129 u8 reset[] = {
130 IRQ_MASK,
131 0x00 /* bit 6 is active low software reset
132 * bits 5-0 are 1 to mask interrupts */
133 };
134
Michael Krufky1963c902005-08-08 09:22:43 -0700135 ret = i2c_write_demod_bytes(state,
Michael Krufkydc9ca2a2005-09-06 15:19:40 -0700136 reset, sizeof(reset));
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700137 if (ret == 0) {
Michael Krufky1963c902005-08-08 09:22:43 -0700138
139 /* force reset high (inactive) and unmask interrupts */
140 reset[1] = 0x7f;
141 ret = i2c_write_demod_bytes(state,
Michael Krufkydc9ca2a2005-09-06 15:19:40 -0700142 reset, sizeof(reset));
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700143 }
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700144 return ret;
145}
146
Michael Krufky1963c902005-08-08 09:22:43 -0700147static int lgdt3303_SwReset(struct lgdt330x_state* state)
148{
149 u8 ret;
150 u8 reset[] = {
151 0x02,
152 0x00 /* bit 0 is active low software reset */
153 };
154
155 ret = i2c_write_demod_bytes(state,
Michael Krufkydc9ca2a2005-09-06 15:19:40 -0700156 reset, sizeof(reset));
Michael Krufky1963c902005-08-08 09:22:43 -0700157 if (ret == 0) {
158
159 /* force reset high (inactive) */
160 reset[1] = 0x01;
161 ret = i2c_write_demod_bytes(state,
Michael Krufkydc9ca2a2005-09-06 15:19:40 -0700162 reset, sizeof(reset));
Michael Krufky1963c902005-08-08 09:22:43 -0700163 }
164 return ret;
165}
166
167static int lgdt330x_SwReset(struct lgdt330x_state* state)
168{
169 switch (state->config->demod_chip) {
170 case LGDT3302:
171 return lgdt3302_SwReset(state);
172 case LGDT3303:
173 return lgdt3303_SwReset(state);
174 default:
175 return -ENODEV;
176 }
177}
178
Michael Krufky6ddcc912005-07-27 11:46:00 -0700179static int lgdt330x_init(struct dvb_frontend* fe)
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700180{
181 /* Hardware reset is done using gpio[0] of cx23880x chip.
182 * I'd like to do it here, but don't know how to find chip address.
183 * cx88-cards.c arranges for the reset bit to be inactive (high).
184 * Maybe there needs to be a callable function in cx88-core or
185 * the caller of this function needs to do it. */
186
Michael Krufky1963c902005-08-08 09:22:43 -0700187 /*
188 * Array of byte pairs <address, value>
189 * to initialize each different chip
190 */
191 static u8 lgdt3302_init_data[] = {
192 /* Use 50MHz parameter values from spec sheet since xtal is 50 */
193 /* Change the value of NCOCTFV[25:0] of carrier
194 recovery center frequency register */
195 VSB_CARRIER_FREQ0, 0x00,
196 VSB_CARRIER_FREQ1, 0x87,
197 VSB_CARRIER_FREQ2, 0x8e,
198 VSB_CARRIER_FREQ3, 0x01,
199 /* Change the TPCLK pin polarity
200 data is valid on falling clock */
201 DEMUX_CONTROL, 0xfb,
202 /* Change the value of IFBW[11:0] of
203 AGC IF/RF loop filter bandwidth register */
204 AGC_RF_BANDWIDTH0, 0x40,
205 AGC_RF_BANDWIDTH1, 0x93,
206 AGC_RF_BANDWIDTH2, 0x00,
207 /* Change the value of bit 6, 'nINAGCBY' and
208 'NSSEL[1:0] of ACG function control register 2 */
209 AGC_FUNC_CTRL2, 0xc6,
210 /* Change the value of bit 6 'RFFIX'
211 of AGC function control register 3 */
212 AGC_FUNC_CTRL3, 0x40,
213 /* Set the value of 'INLVTHD' register 0x2a/0x2c
214 to 0x7fe */
215 AGC_DELAY0, 0x07,
216 AGC_DELAY2, 0xfe,
217 /* Change the value of IAGCBW[15:8]
218 of inner AGC loop filter bandwith */
219 AGC_LOOP_BANDWIDTH0, 0x08,
220 AGC_LOOP_BANDWIDTH1, 0x9a
221 };
222
223 static u8 lgdt3303_init_data[] = {
224 0x4c, 0x14
225 };
226
Michael Krufkyc0b11b92005-11-08 21:35:32 -0800227 static u8 flip_lgdt3303_init_data[] = {
228 0x4c, 0x14,
229 0x87, 0xf3
230 };
231
Michael Krufky1963c902005-08-08 09:22:43 -0700232 struct lgdt330x_state* state = fe->demodulator_priv;
233 char *chip_name;
234 int err;
235
236 switch (state->config->demod_chip) {
237 case LGDT3302:
238 chip_name = "LGDT3302";
239 err = i2c_write_demod_bytes(state, lgdt3302_init_data,
Michael Krufkydc9ca2a2005-09-06 15:19:40 -0700240 sizeof(lgdt3302_init_data));
241 break;
Michael Krufky1963c902005-08-08 09:22:43 -0700242 case LGDT3303:
243 chip_name = "LGDT3303";
Michael Krufkyc0b11b92005-11-08 21:35:32 -0800244 if (state->config->clock_polarity_flip) {
245 err = i2c_write_demod_bytes(state, flip_lgdt3303_init_data,
246 sizeof(flip_lgdt3303_init_data));
247 } else {
248 err = i2c_write_demod_bytes(state, lgdt3303_init_data,
249 sizeof(lgdt3303_init_data));
250 }
Michael Krufkydc9ca2a2005-09-06 15:19:40 -0700251 break;
Michael Krufky1963c902005-08-08 09:22:43 -0700252 default:
253 chip_name = "undefined";
254 printk (KERN_WARNING "Only LGDT3302 and LGDT3303 are supported chips.\n");
255 err = -ENODEV;
256 }
257 dprintk("%s entered as %s\n", __FUNCTION__, chip_name);
258 if (err < 0)
259 return err;
260 return lgdt330x_SwReset(state);
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700261}
262
Michael Krufky6ddcc912005-07-27 11:46:00 -0700263static int lgdt330x_read_ber(struct dvb_frontend* fe, u32* ber)
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700264{
Michael Krufky1963c902005-08-08 09:22:43 -0700265 *ber = 0; /* Not supplied by the demod chips */
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700266 return 0;
267}
268
Michael Krufky6ddcc912005-07-27 11:46:00 -0700269static int lgdt330x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700270{
Michael Krufky1963c902005-08-08 09:22:43 -0700271 struct lgdt330x_state* state = fe->demodulator_priv;
272 int err;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700273 u8 buf[2];
274
Michael Krufky1963c902005-08-08 09:22:43 -0700275 switch (state->config->demod_chip) {
276 case LGDT3302:
277 err = i2c_read_demod_bytes(state, LGDT3302_PACKET_ERR_COUNTER1,
Michael Krufkydc9ca2a2005-09-06 15:19:40 -0700278 buf, sizeof(buf));
279 break;
Michael Krufky1963c902005-08-08 09:22:43 -0700280 case LGDT3303:
281 err = i2c_read_demod_bytes(state, LGDT3303_PACKET_ERR_COUNTER1,
Michael Krufkydc9ca2a2005-09-06 15:19:40 -0700282 buf, sizeof(buf));
283 break;
Michael Krufky1963c902005-08-08 09:22:43 -0700284 default:
285 printk(KERN_WARNING
Michael Krufkydc9ca2a2005-09-06 15:19:40 -0700286 "Only LGDT3302 and LGDT3303 are supported chips.\n");
Michael Krufky1963c902005-08-08 09:22:43 -0700287 err = -ENODEV;
288 }
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700289
290 *ucblocks = (buf[0] << 8) | buf[1];
291 return 0;
292}
293
Michael Krufky6ddcc912005-07-27 11:46:00 -0700294static int lgdt330x_set_parameters(struct dvb_frontend* fe,
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700295 struct dvb_frontend_parameters *param)
296{
Michael Krufky1963c902005-08-08 09:22:43 -0700297 /*
298 * Array of byte pairs <address, value>
299 * to initialize 8VSB for lgdt3303 chip 50 MHz IF
300 */
301 static u8 lgdt3303_8vsb_44_data[] = {
302 0x04, 0x00,
303 0x0d, 0x40,
Mauro Carvalho Chehab9101e622005-12-12 00:37:24 -0800304 0x0e, 0x87,
305 0x0f, 0x8e,
306 0x10, 0x01,
307 0x47, 0x8b };
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700308
Michael Krufky1963c902005-08-08 09:22:43 -0700309 /*
310 * Array of byte pairs <address, value>
311 * to initialize QAM for lgdt3303 chip
312 */
313 static u8 lgdt3303_qam_data[] = {
314 0x04, 0x00,
315 0x0d, 0x00,
316 0x0e, 0x00,
317 0x0f, 0x00,
318 0x10, 0x00,
319 0x51, 0x63,
320 0x47, 0x66,
321 0x48, 0x66,
322 0x4d, 0x1a,
323 0x49, 0x08,
324 0x4a, 0x9b };
325
326 struct lgdt330x_state* state = fe->demodulator_priv;
327
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700328 static u8 top_ctrl_cfg[] = { TOP_CONTROL, 0x03 };
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700329
Michael Krufky1963c902005-08-08 09:22:43 -0700330 int err;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700331 /* Change only if we are actually changing the modulation */
332 if (state->current_modulation != param->u.vsb.modulation) {
333 switch(param->u.vsb.modulation) {
334 case VSB_8:
335 dprintk("%s: VSB_8 MODE\n", __FUNCTION__);
336
Michael Krufky1963c902005-08-08 09:22:43 -0700337 /* Select VSB mode */
338 top_ctrl_cfg[1] = 0x03;
Michael Krufky0ccef6d2005-07-27 11:45:55 -0700339
340 /* Select ANT connector if supported by card */
341 if (state->config->pll_rf_set)
342 state->config->pll_rf_set(fe, 1);
Michael Krufky1963c902005-08-08 09:22:43 -0700343
344 if (state->config->demod_chip == LGDT3303) {
345 err = i2c_write_demod_bytes(state, lgdt3303_8vsb_44_data,
Michael Krufkydc9ca2a2005-09-06 15:19:40 -0700346 sizeof(lgdt3303_8vsb_44_data));
Michael Krufky1963c902005-08-08 09:22:43 -0700347 }
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700348 break;
349
350 case QAM_64:
351 dprintk("%s: QAM_64 MODE\n", __FUNCTION__);
352
Michael Krufky1963c902005-08-08 09:22:43 -0700353 /* Select QAM_64 mode */
354 top_ctrl_cfg[1] = 0x00;
Michael Krufky0ccef6d2005-07-27 11:45:55 -0700355
356 /* Select CABLE connector if supported by card */
357 if (state->config->pll_rf_set)
358 state->config->pll_rf_set(fe, 0);
Michael Krufky1963c902005-08-08 09:22:43 -0700359
360 if (state->config->demod_chip == LGDT3303) {
361 err = i2c_write_demod_bytes(state, lgdt3303_qam_data,
362 sizeof(lgdt3303_qam_data));
363 }
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700364 break;
365
366 case QAM_256:
367 dprintk("%s: QAM_256 MODE\n", __FUNCTION__);
368
Michael Krufky1963c902005-08-08 09:22:43 -0700369 /* Select QAM_256 mode */
370 top_ctrl_cfg[1] = 0x01;
Michael Krufky0ccef6d2005-07-27 11:45:55 -0700371
372 /* Select CABLE connector if supported by card */
373 if (state->config->pll_rf_set)
374 state->config->pll_rf_set(fe, 0);
Michael Krufky1963c902005-08-08 09:22:43 -0700375
376 if (state->config->demod_chip == LGDT3303) {
377 err = i2c_write_demod_bytes(state, lgdt3303_qam_data,
378 sizeof(lgdt3303_qam_data));
379 }
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700380 break;
381 default:
Michael Krufky6ddcc912005-07-27 11:46:00 -0700382 printk(KERN_WARNING "lgdt330x: %s: Modulation type(%d) UNSUPPORTED\n", __FUNCTION__, param->u.vsb.modulation);
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700383 return -1;
384 }
Michael Krufky1963c902005-08-08 09:22:43 -0700385 /*
386 * select serial or parallel MPEG harware interface
387 * Serial: 0x04 for LGDT3302 or 0x40 for LGDT3303
388 * Parallel: 0x00
389 */
390 top_ctrl_cfg[1] |= state->config->serial_mpeg;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700391
392 /* Select the requested mode */
Michael Krufky1963c902005-08-08 09:22:43 -0700393 i2c_write_demod_bytes(state, top_ctrl_cfg,
Michael Krufkydc9ca2a2005-09-06 15:19:40 -0700394 sizeof(top_ctrl_cfg));
395 if (state->config->set_ts_params)
396 state->config->set_ts_params(fe, 0);
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700397 state->current_modulation = param->u.vsb.modulation;
398 }
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700399
Michael Krufkydc9ca2a2005-09-06 15:19:40 -0700400 /* Tune to the specified frequency */
401 if (state->config->pll_set)
Michael Krufky1963c902005-08-08 09:22:43 -0700402 state->config->pll_set(fe, param);
Michael Krufkydc9ca2a2005-09-06 15:19:40 -0700403
404 /* Keep track of the new frequency */
Mauro Carvalho Chehab4302c152006-01-09 15:25:22 -0200405 /* FIXME this is the wrong way to do this... */
406 /* The tuner is shared with the video4linux analog API */
Michael Krufkydc9ca2a2005-09-06 15:19:40 -0700407 state->current_frequency = param->frequency;
408
Michael Krufky6ddcc912005-07-27 11:46:00 -0700409 lgdt330x_SwReset(state);
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700410 return 0;
411}
412
Michael Krufky6ddcc912005-07-27 11:46:00 -0700413static int lgdt330x_get_frontend(struct dvb_frontend* fe,
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700414 struct dvb_frontend_parameters* param)
415{
Michael Krufky6ddcc912005-07-27 11:46:00 -0700416 struct lgdt330x_state *state = fe->demodulator_priv;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700417 param->frequency = state->current_frequency;
418 return 0;
419}
420
Michael Krufky1963c902005-08-08 09:22:43 -0700421static int lgdt3302_read_status(struct dvb_frontend* fe, fe_status_t* status)
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700422{
Michael Krufky1963c902005-08-08 09:22:43 -0700423 struct lgdt330x_state* state = fe->demodulator_priv;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700424 u8 buf[3];
425
426 *status = 0; /* Reset status result */
427
Michael Krufky08d80522005-07-07 17:58:43 -0700428 /* AGC status register */
Michael Krufky1963c902005-08-08 09:22:43 -0700429 i2c_read_demod_bytes(state, AGC_STATUS, buf, 1);
Michael Krufky08d80522005-07-07 17:58:43 -0700430 dprintk("%s: AGC_STATUS = 0x%02x\n", __FUNCTION__, buf[0]);
431 if ((buf[0] & 0x0c) == 0x8){
432 /* Test signal does not exist flag */
433 /* as well as the AGC lock flag. */
434 *status |= FE_HAS_SIGNAL;
435 } else {
436 /* Without a signal all other status bits are meaningless */
437 return 0;
438 }
439
Michael Krufky1963c902005-08-08 09:22:43 -0700440 /*
441 * You must set the Mask bits to 1 in the IRQ_MASK in order
442 * to see that status bit in the IRQ_STATUS register.
443 * This is done in SwReset();
444 */
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700445 /* signal status */
Michael Krufky1963c902005-08-08 09:22:43 -0700446 i2c_read_demod_bytes(state, TOP_CONTROL, buf, sizeof(buf));
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700447 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 -0700448
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700449
450 /* sync status */
451 if ((buf[2] & 0x03) == 0x01) {
452 *status |= FE_HAS_SYNC;
453 }
454
455 /* FEC error status */
456 if ((buf[2] & 0x0c) == 0x08) {
457 *status |= FE_HAS_LOCK;
458 *status |= FE_HAS_VITERBI;
459 }
460
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700461 /* Carrier Recovery Lock Status Register */
Michael Krufky1963c902005-08-08 09:22:43 -0700462 i2c_read_demod_bytes(state, CARRIER_LOCK, buf, 1);
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700463 dprintk("%s: CARRIER_LOCK = 0x%02x\n", __FUNCTION__, buf[0]);
464 switch (state->current_modulation) {
465 case QAM_256:
466 case QAM_64:
467 /* Need to undestand why there are 3 lock levels here */
468 if ((buf[0] & 0x07) == 0x07)
469 *status |= FE_HAS_CARRIER;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700470 break;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700471 case VSB_8:
472 if ((buf[0] & 0x80) == 0x80)
473 *status |= FE_HAS_CARRIER;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700474 break;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700475 default:
Michael Krufky6ddcc912005-07-27 11:46:00 -0700476 printk("KERN_WARNING lgdt330x: %s: Modulation set to unsupported value\n", __FUNCTION__);
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700477 }
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700478
479 return 0;
480}
481
Michael Krufky1963c902005-08-08 09:22:43 -0700482static int lgdt3303_read_status(struct dvb_frontend* fe, fe_status_t* status)
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700483{
Michael Krufky1963c902005-08-08 09:22:43 -0700484 struct lgdt330x_state* state = fe->demodulator_priv;
485 int err;
486 u8 buf[3];
487
488 *status = 0; /* Reset status result */
489
490 /* lgdt3303 AGC status register */
491 err = i2c_read_demod_bytes(state, 0x58, buf, 1);
492 if (err < 0)
493 return err;
494
495 dprintk("%s: AGC_STATUS = 0x%02x\n", __FUNCTION__, buf[0]);
496 if ((buf[0] & 0x21) == 0x01){
497 /* Test input signal does not exist flag */
498 /* as well as the AGC lock flag. */
499 *status |= FE_HAS_SIGNAL;
500 } else {
501 /* Without a signal all other status bits are meaningless */
502 return 0;
503 }
504
505 /* Carrier Recovery Lock Status Register */
506 i2c_read_demod_bytes(state, CARRIER_LOCK, buf, 1);
507 dprintk("%s: CARRIER_LOCK = 0x%02x\n", __FUNCTION__, buf[0]);
508 switch (state->current_modulation) {
509 case QAM_256:
510 case QAM_64:
511 /* Need to undestand why there are 3 lock levels here */
512 if ((buf[0] & 0x07) == 0x07)
513 *status |= FE_HAS_CARRIER;
514 else
515 break;
516 i2c_read_demod_bytes(state, 0x8a, buf, 1);
517 if ((buf[0] & 0x04) == 0x04)
518 *status |= FE_HAS_SYNC;
519 if ((buf[0] & 0x01) == 0x01)
520 *status |= FE_HAS_LOCK;
521 if ((buf[0] & 0x08) == 0x08)
522 *status |= FE_HAS_VITERBI;
523 break;
524 case VSB_8:
525 if ((buf[0] & 0x80) == 0x80)
526 *status |= FE_HAS_CARRIER;
527 else
528 break;
529 i2c_read_demod_bytes(state, 0x38, buf, 1);
530 if ((buf[0] & 0x02) == 0x00)
531 *status |= FE_HAS_SYNC;
532 if ((buf[0] & 0x01) == 0x01) {
533 *status |= FE_HAS_LOCK;
534 *status |= FE_HAS_VITERBI;
535 }
536 break;
537 default:
538 printk("KERN_WARNING lgdt330x: %s: Modulation set to unsupported value\n", __FUNCTION__);
539 }
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700540 return 0;
541}
542
Michael Krufky1963c902005-08-08 09:22:43 -0700543static int lgdt330x_read_signal_strength(struct dvb_frontend* fe, u16* strength)
544{
545 /* not directly available. */
546 *strength = 0;
547 return 0;
548}
549
550static int lgdt3302_read_snr(struct dvb_frontend* fe, u16* snr)
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700551{
552#ifdef SNR_IN_DB
553 /*
554 * Spec sheet shows formula for SNR_EQ = 10 log10(25 * 24**2 / noise)
555 * and SNR_PH = 10 log10(25 * 32**2 / noise) for equalizer and phase tracker
556 * respectively. The following tables are built on these formulas.
557 * The usual definition is SNR = 20 log10(signal/noise)
558 * If the specification is wrong the value retuned is 1/2 the actual SNR in db.
559 *
560 * This table is a an ordered list of noise values computed by the
561 * formula from the spec sheet such that the index into the table
562 * starting at 43 or 45 is the SNR value in db. There are duplicate noise
563 * value entries at the beginning because the SNR varies more than
564 * 1 db for a change of 1 digit in noise at very small values of noise.
565 *
566 * Examples from SNR_EQ table:
567 * noise SNR
568 * 0 43
569 * 1 42
570 * 2 39
571 * 3 37
572 * 4 36
573 * 5 35
574 * 6 34
575 * 7 33
576 * 8 33
577 * 9 32
578 * 10 32
579 * 11 31
580 * 12 31
581 * 13 30
582 */
583
584 static const u32 SNR_EQ[] =
585 { 1, 2, 2, 2, 3, 3, 4, 4, 5, 7,
586 9, 11, 13, 17, 21, 26, 33, 41, 52, 65,
587 81, 102, 129, 162, 204, 257, 323, 406, 511, 644,
588 810, 1020, 1284, 1616, 2035, 2561, 3224, 4059, 5110, 6433,
589 8098, 10195, 12835, 16158, 20341, 25608, 32238, 40585, 51094, 64323,
590 80978, 101945, 128341, 161571, 203406, 256073, 0x40000
591 };
592
593 static const u32 SNR_PH[] =
594 { 1, 2, 2, 2, 3, 3, 4, 5, 6, 8,
595 10, 12, 15, 19, 23, 29, 37, 46, 58, 73,
596 91, 115, 144, 182, 229, 288, 362, 456, 574, 722,
597 909, 1144, 1440, 1813, 2282, 2873, 3617, 4553, 5732, 7216,
598 9084, 11436, 14396, 18124, 22817, 28724, 36161, 45524, 57312, 72151,
Michael Krufky1963c902005-08-08 09:22:43 -0700599 90833, 114351, 143960, 181235, 228161, 0x080000
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700600 };
601
602 static u8 buf[5];/* read data buffer */
603 static u32 noise; /* noise value */
604 static u32 snr_db; /* index into SNR_EQ[] */
Michael Krufky6ddcc912005-07-27 11:46:00 -0700605 struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700606
Michael Krufky1963c902005-08-08 09:22:43 -0700607 /* read both equalizer and phase tracker noise data */
608 i2c_read_demod_bytes(state, EQPH_ERR0, buf, sizeof(buf));
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700609
610 if (state->current_modulation == VSB_8) {
611 /* Equalizer Mean-Square Error Register for VSB */
612 noise = ((buf[0] & 7) << 16) | (buf[1] << 8) | buf[2];
613
614 /*
615 * Look up noise value in table.
616 * A better search algorithm could be used...
617 * watch out there are duplicate entries.
618 */
619 for (snr_db = 0; snr_db < sizeof(SNR_EQ); snr_db++) {
620 if (noise < SNR_EQ[snr_db]) {
621 *snr = 43 - snr_db;
622 break;
623 }
624 }
625 } else {
626 /* Phase Tracker Mean-Square Error Register for QAM */
627 noise = ((buf[0] & 7<<3) << 13) | (buf[3] << 8) | buf[4];
628
629 /* Look up noise value in table. */
630 for (snr_db = 0; snr_db < sizeof(SNR_PH); snr_db++) {
631 if (noise < SNR_PH[snr_db]) {
632 *snr = 45 - snr_db;
633 break;
634 }
635 }
636 }
637#else
638 /* Return the raw noise value */
639 static u8 buf[5];/* read data buffer */
640 static u32 noise; /* noise value */
Michael Krufky6ddcc912005-07-27 11:46:00 -0700641 struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700642
643 /* read both equalizer and pase tracker noise data */
Michael Krufky1963c902005-08-08 09:22:43 -0700644 i2c_read_demod_bytes(state, EQPH_ERR0, buf, sizeof(buf));
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700645
646 if (state->current_modulation == VSB_8) {
Michael Krufky1963c902005-08-08 09:22:43 -0700647 /* Phase Tracker Mean-Square Error Register for VSB */
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700648 noise = ((buf[0] & 7<<3) << 13) | (buf[3] << 8) | buf[4];
Michael Krufky1963c902005-08-08 09:22:43 -0700649 } else {
650
651 /* Carrier Recovery Mean-Square Error for QAM */
652 i2c_read_demod_bytes(state, 0x1a, buf, 2);
653 noise = ((buf[0] & 3) << 8) | buf[1];
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700654 }
655
656 /* Small values for noise mean signal is better so invert noise */
Michael Krufky1963c902005-08-08 09:22:43 -0700657 *snr = ~noise;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700658#endif
659
660 dprintk("%s: noise = 0x%05x, snr = %idb\n",__FUNCTION__, noise, *snr);
661
662 return 0;
663}
664
Michael Krufky1963c902005-08-08 09:22:43 -0700665static int lgdt3303_read_snr(struct dvb_frontend* fe, u16* snr)
666{
667 /* Return the raw noise value */
668 static u8 buf[5];/* read data buffer */
669 static u32 noise; /* noise value */
670 struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv;
671
672 if (state->current_modulation == VSB_8) {
673
674 /* Phase Tracker Mean-Square Error Register for VSB */
675 noise = ((buf[0] & 7) << 16) | (buf[3] << 8) | buf[4];
676 } else {
677
678 /* Carrier Recovery Mean-Square Error for QAM */
679 i2c_read_demod_bytes(state, 0x1a, buf, 2);
680 noise = (buf[0] << 8) | buf[1];
681 }
682
683 /* Small values for noise mean signal is better so invert noise */
684 *snr = ~noise;
685
686 dprintk("%s: noise = 0x%05x, snr = %idb\n",__FUNCTION__, noise, *snr);
687
688 return 0;
689}
690
Michael Krufky6ddcc912005-07-27 11:46:00 -0700691static int lgdt330x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fe_tune_settings)
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700692{
693 /* I have no idea about this - it may not be needed */
694 fe_tune_settings->min_delay_ms = 500;
695 fe_tune_settings->step_size = 0;
696 fe_tune_settings->max_drift = 0;
697 return 0;
698}
699
Michael Krufky6ddcc912005-07-27 11:46:00 -0700700static void lgdt330x_release(struct dvb_frontend* fe)
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700701{
Michael Krufky6ddcc912005-07-27 11:46:00 -0700702 struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700703 kfree(state);
704}
705
Michael Krufky1963c902005-08-08 09:22:43 -0700706static struct dvb_frontend_ops lgdt3302_ops;
707static struct dvb_frontend_ops lgdt3303_ops;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700708
Michael Krufky6ddcc912005-07-27 11:46:00 -0700709struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config,
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700710 struct i2c_adapter* i2c)
711{
Michael Krufky6ddcc912005-07-27 11:46:00 -0700712 struct lgdt330x_state* state = NULL;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700713 u8 buf[1];
714
715 /* Allocate memory for the internal state */
Michael Krufky6ddcc912005-07-27 11:46:00 -0700716 state = (struct lgdt330x_state*) kmalloc(sizeof(struct lgdt330x_state), GFP_KERNEL);
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700717 if (state == NULL)
718 goto error;
719 memset(state,0,sizeof(*state));
720
721 /* Setup the state */
722 state->config = config;
723 state->i2c = i2c;
Michael Krufky1963c902005-08-08 09:22:43 -0700724 switch (config->demod_chip) {
725 case LGDT3302:
726 memcpy(&state->ops, &lgdt3302_ops, sizeof(struct dvb_frontend_ops));
727 break;
728 case LGDT3303:
729 memcpy(&state->ops, &lgdt3303_ops, sizeof(struct dvb_frontend_ops));
730 break;
731 default:
732 goto error;
733 }
734
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700735 /* Verify communication with demod chip */
Michael Krufky1963c902005-08-08 09:22:43 -0700736 if (i2c_read_demod_bytes(state, 2, buf, 1))
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700737 goto error;
738
739 state->current_frequency = -1;
740 state->current_modulation = -1;
741
742 /* Create dvb_frontend */
743 state->frontend.ops = &state->ops;
744 state->frontend.demodulator_priv = state;
745 return &state->frontend;
746
747error:
Jesper Juhl2ea75332005-11-07 01:01:31 -0800748 kfree(state);
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700749 dprintk("%s: ERROR\n",__FUNCTION__);
750 return NULL;
751}
752
Michael Krufky1963c902005-08-08 09:22:43 -0700753static struct dvb_frontend_ops lgdt3302_ops = {
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700754 .info = {
Michael Krufkye179d8b2005-08-09 17:48:54 -0700755 .name= "LG Electronics LGDT3302 VSB/QAM Frontend",
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700756 .type = FE_ATSC,
757 .frequency_min= 54000000,
758 .frequency_max= 858000000,
759 .frequency_stepsize= 62500,
Michael Krufky66944e92005-11-08 21:35:55 -0800760 .symbol_rate_min = 5056941, /* QAM 64 */
761 .symbol_rate_max = 10762000, /* VSB 8 */
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700762 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
763 },
Michael Krufky6ddcc912005-07-27 11:46:00 -0700764 .init = lgdt330x_init,
765 .set_frontend = lgdt330x_set_parameters,
766 .get_frontend = lgdt330x_get_frontend,
767 .get_tune_settings = lgdt330x_get_tune_settings,
Michael Krufky1963c902005-08-08 09:22:43 -0700768 .read_status = lgdt3302_read_status,
Michael Krufky6ddcc912005-07-27 11:46:00 -0700769 .read_ber = lgdt330x_read_ber,
770 .read_signal_strength = lgdt330x_read_signal_strength,
Michael Krufky1963c902005-08-08 09:22:43 -0700771 .read_snr = lgdt3302_read_snr,
Michael Krufky6ddcc912005-07-27 11:46:00 -0700772 .read_ucblocks = lgdt330x_read_ucblocks,
773 .release = lgdt330x_release,
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700774};
775
Michael Krufky1963c902005-08-08 09:22:43 -0700776static struct dvb_frontend_ops lgdt3303_ops = {
777 .info = {
778 .name= "LG Electronics LGDT3303 VSB/QAM Frontend",
779 .type = FE_ATSC,
780 .frequency_min= 54000000,
781 .frequency_max= 858000000,
782 .frequency_stepsize= 62500,
Michael Krufky66944e92005-11-08 21:35:55 -0800783 .symbol_rate_min = 5056941, /* QAM 64 */
784 .symbol_rate_max = 10762000, /* VSB 8 */
Michael Krufky1963c902005-08-08 09:22:43 -0700785 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
786 },
787 .init = lgdt330x_init,
788 .set_frontend = lgdt330x_set_parameters,
789 .get_frontend = lgdt330x_get_frontend,
790 .get_tune_settings = lgdt330x_get_tune_settings,
791 .read_status = lgdt3303_read_status,
792 .read_ber = lgdt330x_read_ber,
793 .read_signal_strength = lgdt330x_read_signal_strength,
794 .read_snr = lgdt3303_read_snr,
795 .read_ucblocks = lgdt330x_read_ucblocks,
796 .release = lgdt330x_release,
797};
798
799MODULE_DESCRIPTION("LGDT330X (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver");
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700800MODULE_AUTHOR("Wilson Michaels");
801MODULE_LICENSE("GPL");
802
Michael Krufky6ddcc912005-07-27 11:46:00 -0700803EXPORT_SYMBOL(lgdt330x_attach);
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700804
805/*
806 * Local variables:
807 * c-basic-offset: 8
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700808 * End:
809 */