blob: cb5301865d07e9d0775bb9bb588ff3b05a3483fd [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 */
405 state->current_frequency = param->frequency;
406
Michael Krufky6ddcc912005-07-27 11:46:00 -0700407 lgdt330x_SwReset(state);
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700408 return 0;
409}
410
Michael Krufky6ddcc912005-07-27 11:46:00 -0700411static int lgdt330x_get_frontend(struct dvb_frontend* fe,
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700412 struct dvb_frontend_parameters* param)
413{
Michael Krufky6ddcc912005-07-27 11:46:00 -0700414 struct lgdt330x_state *state = fe->demodulator_priv;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700415 param->frequency = state->current_frequency;
416 return 0;
417}
418
Michael Krufky1963c902005-08-08 09:22:43 -0700419static int lgdt3302_read_status(struct dvb_frontend* fe, fe_status_t* status)
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700420{
Michael Krufky1963c902005-08-08 09:22:43 -0700421 struct lgdt330x_state* state = fe->demodulator_priv;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700422 u8 buf[3];
423
424 *status = 0; /* Reset status result */
425
Michael Krufky08d80522005-07-07 17:58:43 -0700426 /* AGC status register */
Michael Krufky1963c902005-08-08 09:22:43 -0700427 i2c_read_demod_bytes(state, AGC_STATUS, buf, 1);
Michael Krufky08d80522005-07-07 17:58:43 -0700428 dprintk("%s: AGC_STATUS = 0x%02x\n", __FUNCTION__, buf[0]);
429 if ((buf[0] & 0x0c) == 0x8){
430 /* Test signal does not exist flag */
431 /* as well as the AGC lock flag. */
432 *status |= FE_HAS_SIGNAL;
433 } else {
434 /* Without a signal all other status bits are meaningless */
435 return 0;
436 }
437
Michael Krufky1963c902005-08-08 09:22:43 -0700438 /*
439 * You must set the Mask bits to 1 in the IRQ_MASK in order
440 * to see that status bit in the IRQ_STATUS register.
441 * This is done in SwReset();
442 */
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700443 /* signal status */
Michael Krufky1963c902005-08-08 09:22:43 -0700444 i2c_read_demod_bytes(state, TOP_CONTROL, buf, sizeof(buf));
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700445 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 -0700446
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700447
448 /* sync status */
449 if ((buf[2] & 0x03) == 0x01) {
450 *status |= FE_HAS_SYNC;
451 }
452
453 /* FEC error status */
454 if ((buf[2] & 0x0c) == 0x08) {
455 *status |= FE_HAS_LOCK;
456 *status |= FE_HAS_VITERBI;
457 }
458
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700459 /* Carrier Recovery Lock Status Register */
Michael Krufky1963c902005-08-08 09:22:43 -0700460 i2c_read_demod_bytes(state, CARRIER_LOCK, buf, 1);
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700461 dprintk("%s: CARRIER_LOCK = 0x%02x\n", __FUNCTION__, buf[0]);
462 switch (state->current_modulation) {
463 case QAM_256:
464 case QAM_64:
465 /* Need to undestand why there are 3 lock levels here */
466 if ((buf[0] & 0x07) == 0x07)
467 *status |= FE_HAS_CARRIER;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700468 break;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700469 case VSB_8:
470 if ((buf[0] & 0x80) == 0x80)
471 *status |= FE_HAS_CARRIER;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700472 break;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700473 default:
Michael Krufky6ddcc912005-07-27 11:46:00 -0700474 printk("KERN_WARNING lgdt330x: %s: Modulation set to unsupported value\n", __FUNCTION__);
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700475 }
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700476
477 return 0;
478}
479
Michael Krufky1963c902005-08-08 09:22:43 -0700480static int lgdt3303_read_status(struct dvb_frontend* fe, fe_status_t* status)
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700481{
Michael Krufky1963c902005-08-08 09:22:43 -0700482 struct lgdt330x_state* state = fe->demodulator_priv;
483 int err;
484 u8 buf[3];
485
486 *status = 0; /* Reset status result */
487
488 /* lgdt3303 AGC status register */
489 err = i2c_read_demod_bytes(state, 0x58, buf, 1);
490 if (err < 0)
491 return err;
492
493 dprintk("%s: AGC_STATUS = 0x%02x\n", __FUNCTION__, buf[0]);
494 if ((buf[0] & 0x21) == 0x01){
495 /* Test input signal does not exist flag */
496 /* as well as the AGC lock flag. */
497 *status |= FE_HAS_SIGNAL;
498 } else {
499 /* Without a signal all other status bits are meaningless */
500 return 0;
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 }
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700538 return 0;
539}
540
Michael Krufky1963c902005-08-08 09:22:43 -0700541static int lgdt330x_read_signal_strength(struct dvb_frontend* fe, u16* strength)
542{
543 /* not directly available. */
544 *strength = 0;
545 return 0;
546}
547
548static int lgdt3302_read_snr(struct dvb_frontend* fe, u16* snr)
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700549{
550#ifdef SNR_IN_DB
551 /*
552 * Spec sheet shows formula for SNR_EQ = 10 log10(25 * 24**2 / noise)
553 * and SNR_PH = 10 log10(25 * 32**2 / noise) for equalizer and phase tracker
554 * respectively. The following tables are built on these formulas.
555 * The usual definition is SNR = 20 log10(signal/noise)
556 * If the specification is wrong the value retuned is 1/2 the actual SNR in db.
557 *
558 * This table is a an ordered list of noise values computed by the
559 * formula from the spec sheet such that the index into the table
560 * starting at 43 or 45 is the SNR value in db. There are duplicate noise
561 * value entries at the beginning because the SNR varies more than
562 * 1 db for a change of 1 digit in noise at very small values of noise.
563 *
564 * Examples from SNR_EQ table:
565 * noise SNR
566 * 0 43
567 * 1 42
568 * 2 39
569 * 3 37
570 * 4 36
571 * 5 35
572 * 6 34
573 * 7 33
574 * 8 33
575 * 9 32
576 * 10 32
577 * 11 31
578 * 12 31
579 * 13 30
580 */
581
582 static const u32 SNR_EQ[] =
583 { 1, 2, 2, 2, 3, 3, 4, 4, 5, 7,
584 9, 11, 13, 17, 21, 26, 33, 41, 52, 65,
585 81, 102, 129, 162, 204, 257, 323, 406, 511, 644,
586 810, 1020, 1284, 1616, 2035, 2561, 3224, 4059, 5110, 6433,
587 8098, 10195, 12835, 16158, 20341, 25608, 32238, 40585, 51094, 64323,
588 80978, 101945, 128341, 161571, 203406, 256073, 0x40000
589 };
590
591 static const u32 SNR_PH[] =
592 { 1, 2, 2, 2, 3, 3, 4, 5, 6, 8,
593 10, 12, 15, 19, 23, 29, 37, 46, 58, 73,
594 91, 115, 144, 182, 229, 288, 362, 456, 574, 722,
595 909, 1144, 1440, 1813, 2282, 2873, 3617, 4553, 5732, 7216,
596 9084, 11436, 14396, 18124, 22817, 28724, 36161, 45524, 57312, 72151,
Michael Krufky1963c902005-08-08 09:22:43 -0700597 90833, 114351, 143960, 181235, 228161, 0x080000
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700598 };
599
600 static u8 buf[5];/* read data buffer */
601 static u32 noise; /* noise value */
602 static u32 snr_db; /* index into SNR_EQ[] */
Michael Krufky6ddcc912005-07-27 11:46:00 -0700603 struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700604
Michael Krufky1963c902005-08-08 09:22:43 -0700605 /* read both equalizer and phase tracker noise data */
606 i2c_read_demod_bytes(state, EQPH_ERR0, buf, sizeof(buf));
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700607
608 if (state->current_modulation == VSB_8) {
609 /* Equalizer Mean-Square Error Register for VSB */
610 noise = ((buf[0] & 7) << 16) | (buf[1] << 8) | buf[2];
611
612 /*
613 * Look up noise value in table.
614 * A better search algorithm could be used...
615 * watch out there are duplicate entries.
616 */
617 for (snr_db = 0; snr_db < sizeof(SNR_EQ); snr_db++) {
618 if (noise < SNR_EQ[snr_db]) {
619 *snr = 43 - snr_db;
620 break;
621 }
622 }
623 } else {
624 /* Phase Tracker Mean-Square Error Register for QAM */
625 noise = ((buf[0] & 7<<3) << 13) | (buf[3] << 8) | buf[4];
626
627 /* Look up noise value in table. */
628 for (snr_db = 0; snr_db < sizeof(SNR_PH); snr_db++) {
629 if (noise < SNR_PH[snr_db]) {
630 *snr = 45 - snr_db;
631 break;
632 }
633 }
634 }
635#else
636 /* Return the raw noise value */
637 static u8 buf[5];/* read data buffer */
638 static u32 noise; /* noise value */
Michael Krufky6ddcc912005-07-27 11:46:00 -0700639 struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700640
641 /* read both equalizer and pase tracker noise data */
Michael Krufky1963c902005-08-08 09:22:43 -0700642 i2c_read_demod_bytes(state, EQPH_ERR0, buf, sizeof(buf));
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700643
644 if (state->current_modulation == VSB_8) {
Michael Krufky1963c902005-08-08 09:22:43 -0700645 /* Phase Tracker Mean-Square Error Register for VSB */
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700646 noise = ((buf[0] & 7<<3) << 13) | (buf[3] << 8) | buf[4];
Michael Krufky1963c902005-08-08 09:22:43 -0700647 } else {
648
649 /* Carrier Recovery Mean-Square Error for QAM */
650 i2c_read_demod_bytes(state, 0x1a, buf, 2);
651 noise = ((buf[0] & 3) << 8) | buf[1];
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700652 }
653
654 /* Small values for noise mean signal is better so invert noise */
Michael Krufky1963c902005-08-08 09:22:43 -0700655 *snr = ~noise;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700656#endif
657
658 dprintk("%s: noise = 0x%05x, snr = %idb\n",__FUNCTION__, noise, *snr);
659
660 return 0;
661}
662
Michael Krufky1963c902005-08-08 09:22:43 -0700663static int lgdt3303_read_snr(struct dvb_frontend* fe, u16* snr)
664{
665 /* Return the raw noise value */
666 static u8 buf[5];/* read data buffer */
667 static u32 noise; /* noise value */
668 struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv;
669
670 if (state->current_modulation == VSB_8) {
671
672 /* Phase Tracker Mean-Square Error Register for VSB */
673 noise = ((buf[0] & 7) << 16) | (buf[3] << 8) | buf[4];
674 } else {
675
676 /* Carrier Recovery Mean-Square Error for QAM */
677 i2c_read_demod_bytes(state, 0x1a, buf, 2);
678 noise = (buf[0] << 8) | buf[1];
679 }
680
681 /* Small values for noise mean signal is better so invert noise */
682 *snr = ~noise;
683
684 dprintk("%s: noise = 0x%05x, snr = %idb\n",__FUNCTION__, noise, *snr);
685
686 return 0;
687}
688
Michael Krufky6ddcc912005-07-27 11:46:00 -0700689static int lgdt330x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fe_tune_settings)
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700690{
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
Michael Krufky6ddcc912005-07-27 11:46:00 -0700698static void lgdt330x_release(struct dvb_frontend* fe)
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700699{
Michael Krufky6ddcc912005-07-27 11:46:00 -0700700 struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700701 kfree(state);
702}
703
Michael Krufky1963c902005-08-08 09:22:43 -0700704static struct dvb_frontend_ops lgdt3302_ops;
705static struct dvb_frontend_ops lgdt3303_ops;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700706
Michael Krufky6ddcc912005-07-27 11:46:00 -0700707struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config,
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700708 struct i2c_adapter* i2c)
709{
Michael Krufky6ddcc912005-07-27 11:46:00 -0700710 struct lgdt330x_state* state = NULL;
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700711 u8 buf[1];
712
713 /* Allocate memory for the internal state */
Michael Krufky6ddcc912005-07-27 11:46:00 -0700714 state = (struct lgdt330x_state*) kmalloc(sizeof(struct lgdt330x_state), GFP_KERNEL);
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700715 if (state == NULL)
716 goto error;
717 memset(state,0,sizeof(*state));
718
719 /* Setup the state */
720 state->config = config;
721 state->i2c = i2c;
Michael Krufky1963c902005-08-08 09:22:43 -0700722 switch (config->demod_chip) {
723 case LGDT3302:
724 memcpy(&state->ops, &lgdt3302_ops, sizeof(struct dvb_frontend_ops));
725 break;
726 case LGDT3303:
727 memcpy(&state->ops, &lgdt3303_ops, sizeof(struct dvb_frontend_ops));
728 break;
729 default:
730 goto error;
731 }
732
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700733 /* Verify communication with demod chip */
Michael Krufky1963c902005-08-08 09:22:43 -0700734 if (i2c_read_demod_bytes(state, 2, buf, 1))
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700735 goto error;
736
737 state->current_frequency = -1;
738 state->current_modulation = -1;
739
740 /* Create dvb_frontend */
741 state->frontend.ops = &state->ops;
742 state->frontend.demodulator_priv = state;
743 return &state->frontend;
744
745error:
Jesper Juhl2ea75332005-11-07 01:01:31 -0800746 kfree(state);
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700747 dprintk("%s: ERROR\n",__FUNCTION__);
748 return NULL;
749}
750
Michael Krufky1963c902005-08-08 09:22:43 -0700751static struct dvb_frontend_ops lgdt3302_ops = {
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700752 .info = {
Michael Krufkye179d8b2005-08-09 17:48:54 -0700753 .name= "LG Electronics LGDT3302 VSB/QAM Frontend",
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700754 .type = FE_ATSC,
755 .frequency_min= 54000000,
756 .frequency_max= 858000000,
757 .frequency_stepsize= 62500,
Michael Krufky66944e92005-11-08 21:35:55 -0800758 .symbol_rate_min = 5056941, /* QAM 64 */
759 .symbol_rate_max = 10762000, /* VSB 8 */
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700760 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
761 },
Michael Krufky6ddcc912005-07-27 11:46:00 -0700762 .init = lgdt330x_init,
763 .set_frontend = lgdt330x_set_parameters,
764 .get_frontend = lgdt330x_get_frontend,
765 .get_tune_settings = lgdt330x_get_tune_settings,
Michael Krufky1963c902005-08-08 09:22:43 -0700766 .read_status = lgdt3302_read_status,
Michael Krufky6ddcc912005-07-27 11:46:00 -0700767 .read_ber = lgdt330x_read_ber,
768 .read_signal_strength = lgdt330x_read_signal_strength,
Michael Krufky1963c902005-08-08 09:22:43 -0700769 .read_snr = lgdt3302_read_snr,
Michael Krufky6ddcc912005-07-27 11:46:00 -0700770 .read_ucblocks = lgdt330x_read_ucblocks,
771 .release = lgdt330x_release,
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700772};
773
Michael Krufky1963c902005-08-08 09:22:43 -0700774static struct dvb_frontend_ops lgdt3303_ops = {
775 .info = {
776 .name= "LG Electronics LGDT3303 VSB/QAM Frontend",
777 .type = FE_ATSC,
778 .frequency_min= 54000000,
779 .frequency_max= 858000000,
780 .frequency_stepsize= 62500,
Michael Krufky66944e92005-11-08 21:35:55 -0800781 .symbol_rate_min = 5056941, /* QAM 64 */
782 .symbol_rate_max = 10762000, /* VSB 8 */
Michael Krufky1963c902005-08-08 09:22:43 -0700783 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
784 },
785 .init = lgdt330x_init,
786 .set_frontend = lgdt330x_set_parameters,
787 .get_frontend = lgdt330x_get_frontend,
788 .get_tune_settings = lgdt330x_get_tune_settings,
789 .read_status = lgdt3303_read_status,
790 .read_ber = lgdt330x_read_ber,
791 .read_signal_strength = lgdt330x_read_signal_strength,
792 .read_snr = lgdt3303_read_snr,
793 .read_ucblocks = lgdt330x_read_ucblocks,
794 .release = lgdt330x_release,
795};
796
797MODULE_DESCRIPTION("LGDT330X (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver");
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700798MODULE_AUTHOR("Wilson Michaels");
799MODULE_LICENSE("GPL");
800
Michael Krufky6ddcc912005-07-27 11:46:00 -0700801EXPORT_SYMBOL(lgdt330x_attach);
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700802
803/*
804 * Local variables:
805 * c-basic-offset: 8
Mac Michaelsd8667cb2005-07-07 17:58:29 -0700806 * End:
807 */