x86/amd-iommu: Add function to complete a tlb flush
[linux/fpc-iii.git] / drivers / media / dvb / frontends / lgdt3305.c
blobfde8c59700fbee05d63b6b6433adedd7ec9499a9
1 /*
2 * Support for LGDT3305 - VSB/QAM
4 * Copyright (C) 2008, 2009 Michael Krufky <mkrufky@linuxtv.org>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
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.
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.
22 #include <asm/div64.h>
23 #include <linux/dvb/frontend.h>
24 #include "dvb_math.h"
25 #include "lgdt3305.h"
27 static int debug;
28 module_param(debug, int, 0644);
29 MODULE_PARM_DESC(debug, "set debug level (info=1, reg=2 (or-able))");
31 #define DBG_INFO 1
32 #define DBG_REG 2
34 #define lg_printk(kern, fmt, arg...) \
35 printk(kern "%s: " fmt, __func__, ##arg)
37 #define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3305: " fmt, ##arg)
38 #define lg_warn(fmt, arg...) lg_printk(KERN_WARNING, fmt, ##arg)
39 #define lg_err(fmt, arg...) lg_printk(KERN_ERR, fmt, ##arg)
40 #define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
41 lg_printk(KERN_DEBUG, fmt, ##arg)
42 #define lg_reg(fmt, arg...) if (debug & DBG_REG) \
43 lg_printk(KERN_DEBUG, fmt, ##arg)
45 #define lg_fail(ret) \
46 ({ \
47 int __ret; \
48 __ret = (ret < 0); \
49 if (__ret) \
50 lg_err("error %d on line %d\n", ret, __LINE__); \
51 __ret; \
54 struct lgdt3305_state {
55 struct i2c_adapter *i2c_adap;
56 const struct lgdt3305_config *cfg;
58 struct dvb_frontend frontend;
60 fe_modulation_t current_modulation;
61 u32 current_frequency;
62 u32 snr;
65 /* ------------------------------------------------------------------------ */
67 #define LGDT3305_GEN_CTRL_1 0x0000
68 #define LGDT3305_GEN_CTRL_2 0x0001
69 #define LGDT3305_GEN_CTRL_3 0x0002
70 #define LGDT3305_GEN_STATUS 0x0003
71 #define LGDT3305_GEN_CONTROL 0x0007
72 #define LGDT3305_GEN_CTRL_4 0x000a
73 #define LGDT3305_DGTL_AGC_REF_1 0x0012
74 #define LGDT3305_DGTL_AGC_REF_2 0x0013
75 #define LGDT3305_CR_CTR_FREQ_1 0x0106
76 #define LGDT3305_CR_CTR_FREQ_2 0x0107
77 #define LGDT3305_CR_CTR_FREQ_3 0x0108
78 #define LGDT3305_CR_CTR_FREQ_4 0x0109
79 #define LGDT3305_CR_MSE_1 0x011b
80 #define LGDT3305_CR_MSE_2 0x011c
81 #define LGDT3305_CR_LOCK_STATUS 0x011d
82 #define LGDT3305_CR_CTRL_7 0x0126
83 #define LGDT3305_AGC_POWER_REF_1 0x0300
84 #define LGDT3305_AGC_POWER_REF_2 0x0301
85 #define LGDT3305_AGC_DELAY_PT_1 0x0302
86 #define LGDT3305_AGC_DELAY_PT_2 0x0303
87 #define LGDT3305_RFAGC_LOOP_FLTR_BW_1 0x0306
88 #define LGDT3305_RFAGC_LOOP_FLTR_BW_2 0x0307
89 #define LGDT3305_IFBW_1 0x0308
90 #define LGDT3305_IFBW_2 0x0309
91 #define LGDT3305_AGC_CTRL_1 0x030c
92 #define LGDT3305_AGC_CTRL_4 0x0314
93 #define LGDT3305_EQ_MSE_1 0x0413
94 #define LGDT3305_EQ_MSE_2 0x0414
95 #define LGDT3305_EQ_MSE_3 0x0415
96 #define LGDT3305_PT_MSE_1 0x0417
97 #define LGDT3305_PT_MSE_2 0x0418
98 #define LGDT3305_PT_MSE_3 0x0419
99 #define LGDT3305_FEC_BLOCK_CTRL 0x0504
100 #define LGDT3305_FEC_LOCK_STATUS 0x050a
101 #define LGDT3305_FEC_PKT_ERR_1 0x050c
102 #define LGDT3305_FEC_PKT_ERR_2 0x050d
103 #define LGDT3305_TP_CTRL_1 0x050e
104 #define LGDT3305_BERT_PERIOD 0x0801
105 #define LGDT3305_BERT_ERROR_COUNT_1 0x080a
106 #define LGDT3305_BERT_ERROR_COUNT_2 0x080b
107 #define LGDT3305_BERT_ERROR_COUNT_3 0x080c
108 #define LGDT3305_BERT_ERROR_COUNT_4 0x080d
110 static int lgdt3305_write_reg(struct lgdt3305_state *state, u16 reg, u8 val)
112 int ret;
113 u8 buf[] = { reg >> 8, reg & 0xff, val };
114 struct i2c_msg msg = {
115 .addr = state->cfg->i2c_addr, .flags = 0,
116 .buf = buf, .len = 3,
119 lg_reg("reg: 0x%04x, val: 0x%02x\n", reg, val);
121 ret = i2c_transfer(state->i2c_adap, &msg, 1);
123 if (ret != 1) {
124 lg_err("error (addr %02x %02x <- %02x, err = %i)\n",
125 msg.buf[0], msg.buf[1], msg.buf[2], ret);
126 if (ret < 0)
127 return ret;
128 else
129 return -EREMOTEIO;
131 return 0;
134 static int lgdt3305_read_reg(struct lgdt3305_state *state, u16 reg, u8 *val)
136 int ret;
137 u8 reg_buf[] = { reg >> 8, reg & 0xff };
138 struct i2c_msg msg[] = {
139 { .addr = state->cfg->i2c_addr,
140 .flags = 0, .buf = reg_buf, .len = 2 },
141 { .addr = state->cfg->i2c_addr,
142 .flags = I2C_M_RD, .buf = val, .len = 1 },
145 lg_reg("reg: 0x%04x\n", reg);
147 ret = i2c_transfer(state->i2c_adap, msg, 2);
149 if (ret != 2) {
150 lg_err("error (addr %02x reg %04x error (ret == %i)\n",
151 state->cfg->i2c_addr, reg, ret);
152 if (ret < 0)
153 return ret;
154 else
155 return -EREMOTEIO;
157 return 0;
160 #define read_reg(state, reg) \
161 ({ \
162 u8 __val; \
163 int ret = lgdt3305_read_reg(state, reg, &__val); \
164 if (lg_fail(ret)) \
165 __val = 0; \
166 __val; \
169 static int lgdt3305_set_reg_bit(struct lgdt3305_state *state,
170 u16 reg, int bit, int onoff)
172 u8 val;
173 int ret;
175 lg_reg("reg: 0x%04x, bit: %d, level: %d\n", reg, bit, onoff);
177 ret = lgdt3305_read_reg(state, reg, &val);
178 if (lg_fail(ret))
179 goto fail;
181 val &= ~(1 << bit);
182 val |= (onoff & 1) << bit;
184 ret = lgdt3305_write_reg(state, reg, val);
185 fail:
186 return ret;
189 struct lgdt3305_reg {
190 u16 reg;
191 u8 val;
194 static int lgdt3305_write_regs(struct lgdt3305_state *state,
195 struct lgdt3305_reg *regs, int len)
197 int i, ret;
199 lg_reg("writing %d registers...\n", len);
201 for (i = 0; i < len - 1; i++) {
202 ret = lgdt3305_write_reg(state, regs[i].reg, regs[i].val);
203 if (lg_fail(ret))
204 return ret;
206 return 0;
209 /* ------------------------------------------------------------------------ */
211 static int lgdt3305_soft_reset(struct lgdt3305_state *state)
213 int ret;
215 lg_dbg("\n");
217 ret = lgdt3305_set_reg_bit(state, LGDT3305_GEN_CTRL_3, 0, 0);
218 if (lg_fail(ret))
219 goto fail;
221 msleep(20);
222 ret = lgdt3305_set_reg_bit(state, LGDT3305_GEN_CTRL_3, 0, 1);
223 fail:
224 return ret;
227 static inline int lgdt3305_mpeg_mode(struct lgdt3305_state *state,
228 enum lgdt3305_mpeg_mode mode)
230 lg_dbg("(%d)\n", mode);
231 return lgdt3305_set_reg_bit(state, LGDT3305_TP_CTRL_1, 5, mode);
234 static int lgdt3305_mpeg_mode_polarity(struct lgdt3305_state *state,
235 enum lgdt3305_tp_clock_edge edge,
236 enum lgdt3305_tp_valid_polarity valid)
238 u8 val;
239 int ret;
241 lg_dbg("edge = %d, valid = %d\n", edge, valid);
243 ret = lgdt3305_read_reg(state, LGDT3305_TP_CTRL_1, &val);
244 if (lg_fail(ret))
245 goto fail;
247 val &= ~0x09;
249 if (edge)
250 val |= 0x08;
251 if (valid)
252 val |= 0x01;
254 ret = lgdt3305_write_reg(state, LGDT3305_TP_CTRL_1, val);
255 if (lg_fail(ret))
256 goto fail;
258 ret = lgdt3305_soft_reset(state);
259 fail:
260 return ret;
263 static int lgdt3305_set_modulation(struct lgdt3305_state *state,
264 struct dvb_frontend_parameters *param)
266 u8 opermode;
267 int ret;
269 lg_dbg("\n");
271 ret = lgdt3305_read_reg(state, LGDT3305_GEN_CTRL_1, &opermode);
272 if (lg_fail(ret))
273 goto fail;
275 opermode &= ~0x03;
277 switch (param->u.vsb.modulation) {
278 case VSB_8:
279 opermode |= 0x03;
280 break;
281 case QAM_64:
282 opermode |= 0x00;
283 break;
284 case QAM_256:
285 opermode |= 0x01;
286 break;
287 default:
288 return -EINVAL;
290 ret = lgdt3305_write_reg(state, LGDT3305_GEN_CTRL_1, opermode);
291 fail:
292 return ret;
295 static int lgdt3305_set_filter_extension(struct lgdt3305_state *state,
296 struct dvb_frontend_parameters *param)
298 int val;
300 switch (param->u.vsb.modulation) {
301 case VSB_8:
302 val = 0;
303 break;
304 case QAM_64:
305 case QAM_256:
306 val = 1;
307 break;
308 default:
309 return -EINVAL;
311 lg_dbg("val = %d\n", val);
313 return lgdt3305_set_reg_bit(state, 0x043f, 2, val);
316 /* ------------------------------------------------------------------------ */
318 static int lgdt3305_passband_digital_agc(struct lgdt3305_state *state,
319 struct dvb_frontend_parameters *param)
321 u16 agc_ref;
323 switch (param->u.vsb.modulation) {
324 case VSB_8:
325 agc_ref = 0x32c4;
326 break;
327 case QAM_64:
328 agc_ref = 0x2a00;
329 break;
330 case QAM_256:
331 agc_ref = 0x2a80;
332 break;
333 default:
334 return -EINVAL;
337 lg_dbg("agc ref: 0x%04x\n", agc_ref);
339 lgdt3305_write_reg(state, LGDT3305_DGTL_AGC_REF_1, agc_ref >> 8);
340 lgdt3305_write_reg(state, LGDT3305_DGTL_AGC_REF_2, agc_ref & 0xff);
342 return 0;
345 static int lgdt3305_rfagc_loop(struct lgdt3305_state *state,
346 struct dvb_frontend_parameters *param)
348 u16 ifbw, rfbw, agcdelay;
350 switch (param->u.vsb.modulation) {
351 case VSB_8:
352 agcdelay = 0x04c0;
353 rfbw = 0x8000;
354 ifbw = 0x8000;
355 break;
356 case QAM_64:
357 case QAM_256:
358 agcdelay = 0x046b;
359 rfbw = 0x8889;
360 ifbw = 0x8888;
361 break;
362 default:
363 return -EINVAL;
366 if (state->cfg->rf_agc_loop) {
367 lg_dbg("agcdelay: 0x%04x, rfbw: 0x%04x\n", agcdelay, rfbw);
369 /* rf agc loop filter bandwidth */
370 lgdt3305_write_reg(state, LGDT3305_AGC_DELAY_PT_1,
371 agcdelay >> 8);
372 lgdt3305_write_reg(state, LGDT3305_AGC_DELAY_PT_2,
373 agcdelay & 0xff);
375 lgdt3305_write_reg(state, LGDT3305_RFAGC_LOOP_FLTR_BW_1,
376 rfbw >> 8);
377 lgdt3305_write_reg(state, LGDT3305_RFAGC_LOOP_FLTR_BW_2,
378 rfbw & 0xff);
379 } else {
380 lg_dbg("ifbw: 0x%04x\n", ifbw);
382 /* if agc loop filter bandwidth */
383 lgdt3305_write_reg(state, LGDT3305_IFBW_1, ifbw >> 8);
384 lgdt3305_write_reg(state, LGDT3305_IFBW_2, ifbw & 0xff);
387 return 0;
390 static int lgdt3305_agc_setup(struct lgdt3305_state *state,
391 struct dvb_frontend_parameters *param)
393 int lockdten, acqen;
395 switch (param->u.vsb.modulation) {
396 case VSB_8:
397 lockdten = 0;
398 acqen = 0;
399 break;
400 case QAM_64:
401 case QAM_256:
402 lockdten = 1;
403 acqen = 1;
404 break;
405 default:
406 return -EINVAL;
409 lg_dbg("lockdten = %d, acqen = %d\n", lockdten, acqen);
411 /* control agc function */
412 lgdt3305_write_reg(state, LGDT3305_AGC_CTRL_4, 0xe1 | lockdten << 1);
413 lgdt3305_set_reg_bit(state, LGDT3305_AGC_CTRL_1, 2, acqen);
415 return lgdt3305_rfagc_loop(state, param);
418 static int lgdt3305_set_agc_power_ref(struct lgdt3305_state *state,
419 struct dvb_frontend_parameters *param)
421 u16 usref = 0;
423 switch (param->u.vsb.modulation) {
424 case VSB_8:
425 if (state->cfg->usref_8vsb)
426 usref = state->cfg->usref_8vsb;
427 break;
428 case QAM_64:
429 if (state->cfg->usref_qam64)
430 usref = state->cfg->usref_qam64;
431 break;
432 case QAM_256:
433 if (state->cfg->usref_qam256)
434 usref = state->cfg->usref_qam256;
435 break;
436 default:
437 return -EINVAL;
440 if (usref) {
441 lg_dbg("set manual mode: 0x%04x\n", usref);
443 lgdt3305_set_reg_bit(state, LGDT3305_AGC_CTRL_1, 3, 1);
445 lgdt3305_write_reg(state, LGDT3305_AGC_POWER_REF_1,
446 0xff & (usref >> 8));
447 lgdt3305_write_reg(state, LGDT3305_AGC_POWER_REF_2,
448 0xff & (usref >> 0));
450 return 0;
453 /* ------------------------------------------------------------------------ */
455 static int lgdt3305_spectral_inversion(struct lgdt3305_state *state,
456 struct dvb_frontend_parameters *param,
457 int inversion)
459 int ret;
461 lg_dbg("(%d)\n", inversion);
463 switch (param->u.vsb.modulation) {
464 case VSB_8:
465 ret = lgdt3305_write_reg(state, LGDT3305_CR_CTRL_7,
466 inversion ? 0xf9 : 0x79);
467 break;
468 case QAM_64:
469 case QAM_256:
470 ret = lgdt3305_write_reg(state, LGDT3305_FEC_BLOCK_CTRL,
471 inversion ? 0xfd : 0xff);
472 break;
473 default:
474 ret = -EINVAL;
476 return ret;
479 static int lgdt3305_set_if(struct lgdt3305_state *state,
480 struct dvb_frontend_parameters *param)
482 u16 if_freq_khz;
483 u8 nco1, nco2, nco3, nco4;
484 u64 nco;
486 switch (param->u.vsb.modulation) {
487 case VSB_8:
488 if_freq_khz = state->cfg->vsb_if_khz;
489 break;
490 case QAM_64:
491 case QAM_256:
492 if_freq_khz = state->cfg->qam_if_khz;
493 break;
494 default:
495 return -EINVAL;
498 nco = if_freq_khz / 10;
500 switch (param->u.vsb.modulation) {
501 case VSB_8:
502 nco <<= 24;
503 do_div(nco, 625);
504 break;
505 case QAM_64:
506 case QAM_256:
507 nco <<= 28;
508 do_div(nco, 625);
509 break;
510 default:
511 return -EINVAL;
514 nco1 = (nco >> 24) & 0x3f;
515 nco1 |= 0x40;
516 nco2 = (nco >> 16) & 0xff;
517 nco3 = (nco >> 8) & 0xff;
518 nco4 = nco & 0xff;
520 lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_1, nco1);
521 lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_2, nco2);
522 lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_3, nco3);
523 lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_4, nco4);
525 lg_dbg("%d KHz -> [%02x%02x%02x%02x]\n",
526 if_freq_khz, nco1, nco2, nco3, nco4);
528 return 0;
531 /* ------------------------------------------------------------------------ */
533 static int lgdt3305_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
535 struct lgdt3305_state *state = fe->demodulator_priv;
537 if (state->cfg->deny_i2c_rptr)
538 return 0;
540 lg_dbg("(%d)\n", enable);
542 return lgdt3305_set_reg_bit(state, LGDT3305_GEN_CTRL_2, 5,
543 enable ? 0 : 1);
546 static int lgdt3305_sleep(struct dvb_frontend *fe)
548 struct lgdt3305_state *state = fe->demodulator_priv;
549 u8 gen_ctrl_3, gen_ctrl_4;
551 lg_dbg("\n");
553 gen_ctrl_3 = read_reg(state, LGDT3305_GEN_CTRL_3);
554 gen_ctrl_4 = read_reg(state, LGDT3305_GEN_CTRL_4);
556 /* hold in software reset while sleeping */
557 gen_ctrl_3 &= ~0x01;
558 /* tristate the IF-AGC pin */
559 gen_ctrl_3 |= 0x02;
560 /* tristate the RF-AGC pin */
561 gen_ctrl_3 |= 0x04;
563 /* disable vsb/qam module */
564 gen_ctrl_4 &= ~0x01;
565 /* disable adc module */
566 gen_ctrl_4 &= ~0x02;
568 lgdt3305_write_reg(state, LGDT3305_GEN_CTRL_3, gen_ctrl_3);
569 lgdt3305_write_reg(state, LGDT3305_GEN_CTRL_4, gen_ctrl_4);
571 return 0;
574 static int lgdt3305_init(struct dvb_frontend *fe)
576 struct lgdt3305_state *state = fe->demodulator_priv;
577 int ret;
579 static struct lgdt3305_reg lgdt3305_init_data[] = {
580 { .reg = LGDT3305_GEN_CTRL_1,
581 .val = 0x03, },
582 { .reg = LGDT3305_GEN_CTRL_2,
583 .val = 0xb0, },
584 { .reg = LGDT3305_GEN_CTRL_3,
585 .val = 0x01, },
586 { .reg = LGDT3305_GEN_CONTROL,
587 .val = 0x6f, },
588 { .reg = LGDT3305_GEN_CTRL_4,
589 .val = 0x03, },
590 { .reg = LGDT3305_DGTL_AGC_REF_1,
591 .val = 0x32, },
592 { .reg = LGDT3305_DGTL_AGC_REF_2,
593 .val = 0xc4, },
594 { .reg = LGDT3305_CR_CTR_FREQ_1,
595 .val = 0x00, },
596 { .reg = LGDT3305_CR_CTR_FREQ_2,
597 .val = 0x00, },
598 { .reg = LGDT3305_CR_CTR_FREQ_3,
599 .val = 0x00, },
600 { .reg = LGDT3305_CR_CTR_FREQ_4,
601 .val = 0x00, },
602 { .reg = LGDT3305_CR_CTRL_7,
603 .val = 0x79, },
604 { .reg = LGDT3305_AGC_POWER_REF_1,
605 .val = 0x32, },
606 { .reg = LGDT3305_AGC_POWER_REF_2,
607 .val = 0xc4, },
608 { .reg = LGDT3305_AGC_DELAY_PT_1,
609 .val = 0x0d, },
610 { .reg = LGDT3305_AGC_DELAY_PT_2,
611 .val = 0x30, },
612 { .reg = LGDT3305_RFAGC_LOOP_FLTR_BW_1,
613 .val = 0x80, },
614 { .reg = LGDT3305_RFAGC_LOOP_FLTR_BW_2,
615 .val = 0x00, },
616 { .reg = LGDT3305_IFBW_1,
617 .val = 0x80, },
618 { .reg = LGDT3305_IFBW_2,
619 .val = 0x00, },
620 { .reg = LGDT3305_AGC_CTRL_1,
621 .val = 0x30, },
622 { .reg = LGDT3305_AGC_CTRL_4,
623 .val = 0x61, },
624 { .reg = LGDT3305_FEC_BLOCK_CTRL,
625 .val = 0xff, },
626 { .reg = LGDT3305_TP_CTRL_1,
627 .val = 0x1b, },
630 lg_dbg("\n");
632 ret = lgdt3305_write_regs(state, lgdt3305_init_data,
633 ARRAY_SIZE(lgdt3305_init_data));
634 if (lg_fail(ret))
635 goto fail;
637 ret = lgdt3305_soft_reset(state);
638 fail:
639 return ret;
642 static int lgdt3305_set_parameters(struct dvb_frontend *fe,
643 struct dvb_frontend_parameters *param)
645 struct lgdt3305_state *state = fe->demodulator_priv;
646 int ret;
648 lg_dbg("(%d, %d)\n", param->frequency, param->u.vsb.modulation);
650 if (fe->ops.tuner_ops.set_params) {
651 ret = fe->ops.tuner_ops.set_params(fe, param);
652 if (fe->ops.i2c_gate_ctrl)
653 fe->ops.i2c_gate_ctrl(fe, 0);
654 if (lg_fail(ret))
655 goto fail;
656 state->current_frequency = param->frequency;
659 ret = lgdt3305_set_modulation(state, param);
660 if (lg_fail(ret))
661 goto fail;
663 ret = lgdt3305_passband_digital_agc(state, param);
664 if (lg_fail(ret))
665 goto fail;
666 ret = lgdt3305_set_agc_power_ref(state, param);
667 if (lg_fail(ret))
668 goto fail;
669 ret = lgdt3305_agc_setup(state, param);
670 if (lg_fail(ret))
671 goto fail;
673 /* low if */
674 ret = lgdt3305_write_reg(state, LGDT3305_GEN_CONTROL, 0x2f);
675 if (lg_fail(ret))
676 goto fail;
677 ret = lgdt3305_set_reg_bit(state, LGDT3305_CR_CTR_FREQ_1, 6, 1);
678 if (lg_fail(ret))
679 goto fail;
681 ret = lgdt3305_set_if(state, param);
682 if (lg_fail(ret))
683 goto fail;
684 ret = lgdt3305_spectral_inversion(state, param,
685 state->cfg->spectral_inversion
686 ? 1 : 0);
687 if (lg_fail(ret))
688 goto fail;
690 ret = lgdt3305_set_filter_extension(state, param);
691 if (lg_fail(ret))
692 goto fail;
694 state->current_modulation = param->u.vsb.modulation;
696 ret = lgdt3305_mpeg_mode(state, state->cfg->mpeg_mode);
697 if (lg_fail(ret))
698 goto fail;
700 /* lgdt3305_mpeg_mode_polarity calls lgdt3305_soft_reset */
701 ret = lgdt3305_mpeg_mode_polarity(state,
702 state->cfg->tpclk_edge,
703 state->cfg->tpvalid_polarity);
704 fail:
705 return ret;
708 static int lgdt3305_get_frontend(struct dvb_frontend *fe,
709 struct dvb_frontend_parameters *param)
711 struct lgdt3305_state *state = fe->demodulator_priv;
713 lg_dbg("\n");
715 param->u.vsb.modulation = state->current_modulation;
716 param->frequency = state->current_frequency;
717 return 0;
720 /* ------------------------------------------------------------------------ */
722 static int lgdt3305_read_cr_lock_status(struct lgdt3305_state *state,
723 int *locked)
725 u8 val;
726 int ret;
727 char *cr_lock_state = "";
729 *locked = 0;
731 ret = lgdt3305_read_reg(state, LGDT3305_CR_LOCK_STATUS, &val);
732 if (lg_fail(ret))
733 goto fail;
735 switch (state->current_modulation) {
736 case QAM_256:
737 case QAM_64:
738 if (val & (1 << 1))
739 *locked = 1;
741 switch (val & 0x07) {
742 case 0:
743 cr_lock_state = "QAM UNLOCK";
744 break;
745 case 4:
746 cr_lock_state = "QAM 1stLock";
747 break;
748 case 6:
749 cr_lock_state = "QAM 2ndLock";
750 break;
751 case 7:
752 cr_lock_state = "QAM FinalLock";
753 break;
754 default:
755 cr_lock_state = "CLOCKQAM-INVALID!";
756 break;
758 break;
759 case VSB_8:
760 if (val & (1 << 7)) {
761 *locked = 1;
762 cr_lock_state = "CLOCKVSB";
764 break;
765 default:
766 ret = -EINVAL;
768 lg_dbg("(%d) %s\n", *locked, cr_lock_state);
769 fail:
770 return ret;
773 static int lgdt3305_read_fec_lock_status(struct lgdt3305_state *state,
774 int *locked)
776 u8 val;
777 int ret, mpeg_lock, fec_lock, viterbi_lock;
779 *locked = 0;
781 switch (state->current_modulation) {
782 case QAM_256:
783 case QAM_64:
784 ret = lgdt3305_read_reg(state,
785 LGDT3305_FEC_LOCK_STATUS, &val);
786 if (lg_fail(ret))
787 goto fail;
789 mpeg_lock = (val & (1 << 0)) ? 1 : 0;
790 fec_lock = (val & (1 << 2)) ? 1 : 0;
791 viterbi_lock = (val & (1 << 3)) ? 1 : 0;
793 *locked = mpeg_lock && fec_lock && viterbi_lock;
795 lg_dbg("(%d) %s%s%s\n", *locked,
796 mpeg_lock ? "mpeg lock " : "",
797 fec_lock ? "fec lock " : "",
798 viterbi_lock ? "viterbi lock" : "");
799 break;
800 case VSB_8:
801 default:
802 ret = -EINVAL;
804 fail:
805 return ret;
808 static int lgdt3305_read_status(struct dvb_frontend *fe, fe_status_t *status)
810 struct lgdt3305_state *state = fe->demodulator_priv;
811 u8 val;
812 int ret, signal, inlock, nofecerr, snrgood,
813 cr_lock, fec_lock, sync_lock;
815 *status = 0;
817 ret = lgdt3305_read_reg(state, LGDT3305_GEN_STATUS, &val);
818 if (lg_fail(ret))
819 goto fail;
821 signal = (val & (1 << 4)) ? 1 : 0;
822 inlock = (val & (1 << 3)) ? 0 : 1;
823 sync_lock = (val & (1 << 2)) ? 1 : 0;
824 nofecerr = (val & (1 << 1)) ? 1 : 0;
825 snrgood = (val & (1 << 0)) ? 1 : 0;
827 lg_dbg("%s%s%s%s%s\n",
828 signal ? "SIGNALEXIST " : "",
829 inlock ? "INLOCK " : "",
830 sync_lock ? "SYNCLOCK " : "",
831 nofecerr ? "NOFECERR " : "",
832 snrgood ? "SNRGOOD " : "");
834 ret = lgdt3305_read_cr_lock_status(state, &cr_lock);
835 if (lg_fail(ret))
836 goto fail;
838 if (signal)
839 *status |= FE_HAS_SIGNAL;
840 if (cr_lock)
841 *status |= FE_HAS_CARRIER;
842 if (nofecerr)
843 *status |= FE_HAS_VITERBI;
844 if (sync_lock)
845 *status |= FE_HAS_SYNC;
847 switch (state->current_modulation) {
848 case QAM_256:
849 case QAM_64:
850 ret = lgdt3305_read_fec_lock_status(state, &fec_lock);
851 if (lg_fail(ret))
852 goto fail;
854 if (fec_lock)
855 *status |= FE_HAS_LOCK;
856 break;
857 case VSB_8:
858 if (inlock)
859 *status |= FE_HAS_LOCK;
860 break;
861 default:
862 ret = -EINVAL;
864 fail:
865 return ret;
868 /* ------------------------------------------------------------------------ */
870 /* borrowed from lgdt330x.c */
871 static u32 calculate_snr(u32 mse, u32 c)
873 if (mse == 0) /* no signal */
874 return 0;
876 mse = intlog10(mse);
877 if (mse > c) {
878 /* Negative SNR, which is possible, but realisticly the
879 demod will lose lock before the signal gets this bad. The
880 API only allows for unsigned values, so just return 0 */
881 return 0;
883 return 10*(c - mse);
886 static int lgdt3305_read_snr(struct dvb_frontend *fe, u16 *snr)
888 struct lgdt3305_state *state = fe->demodulator_priv;
889 u32 noise; /* noise value */
890 u32 c; /* per-modulation SNR calculation constant */
892 switch (state->current_modulation) {
893 case VSB_8:
894 #ifdef USE_PTMSE
895 /* Use Phase Tracker Mean-Square Error Register */
896 /* SNR for ranges from -13.11 to +44.08 */
897 noise = ((read_reg(state, LGDT3305_PT_MSE_1) & 0x07) << 16) |
898 (read_reg(state, LGDT3305_PT_MSE_2) << 8) |
899 (read_reg(state, LGDT3305_PT_MSE_3) & 0xff);
900 c = 73957994; /* log10(25*32^2)*2^24 */
901 #else
902 /* Use Equalizer Mean-Square Error Register */
903 /* SNR for ranges from -16.12 to +44.08 */
904 noise = ((read_reg(state, LGDT3305_EQ_MSE_1) & 0x0f) << 16) |
905 (read_reg(state, LGDT3305_EQ_MSE_2) << 8) |
906 (read_reg(state, LGDT3305_EQ_MSE_3) & 0xff);
907 c = 73957994; /* log10(25*32^2)*2^24 */
908 #endif
909 break;
910 case QAM_64:
911 case QAM_256:
912 noise = (read_reg(state, LGDT3305_CR_MSE_1) << 8) |
913 (read_reg(state, LGDT3305_CR_MSE_2) & 0xff);
915 c = (state->current_modulation == QAM_64) ?
916 97939837 : 98026066;
917 /* log10(688128)*2^24 and log10(696320)*2^24 */
918 break;
919 default:
920 return -EINVAL;
922 state->snr = calculate_snr(noise, c);
923 /* report SNR in dB * 10 */
924 *snr = (state->snr / ((1 << 24) / 10));
925 lg_dbg("noise = 0x%08x, snr = %d.%02d dB\n", noise,
926 state->snr >> 24, (((state->snr >> 8) & 0xffff) * 100) >> 16);
928 return 0;
931 static int lgdt3305_read_signal_strength(struct dvb_frontend *fe,
932 u16 *strength)
934 /* borrowed from lgdt330x.c
936 * Calculate strength from SNR up to 35dB
937 * Even though the SNR can go higher than 35dB,
938 * there is some comfort factor in having a range of
939 * strong signals that can show at 100%
941 struct lgdt3305_state *state = fe->demodulator_priv;
942 u16 snr;
943 int ret;
945 *strength = 0;
947 ret = fe->ops.read_snr(fe, &snr);
948 if (lg_fail(ret))
949 goto fail;
950 /* Rather than use the 8.8 value snr, use state->snr which is 8.24 */
951 /* scale the range 0 - 35*2^24 into 0 - 65535 */
952 if (state->snr >= 8960 * 0x10000)
953 *strength = 0xffff;
954 else
955 *strength = state->snr / 8960;
956 fail:
957 return ret;
960 /* ------------------------------------------------------------------------ */
962 static int lgdt3305_read_ber(struct dvb_frontend *fe, u32 *ber)
964 *ber = 0;
965 return 0;
968 static int lgdt3305_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
970 struct lgdt3305_state *state = fe->demodulator_priv;
972 *ucblocks =
973 (read_reg(state, LGDT3305_FEC_PKT_ERR_1) << 8) |
974 (read_reg(state, LGDT3305_FEC_PKT_ERR_2) & 0xff);
976 return 0;
979 static int lgdt3305_get_tune_settings(struct dvb_frontend *fe,
980 struct dvb_frontend_tune_settings
981 *fe_tune_settings)
983 fe_tune_settings->min_delay_ms = 500;
984 lg_dbg("\n");
985 return 0;
988 static void lgdt3305_release(struct dvb_frontend *fe)
990 struct lgdt3305_state *state = fe->demodulator_priv;
991 lg_dbg("\n");
992 kfree(state);
995 static struct dvb_frontend_ops lgdt3305_ops;
997 struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config,
998 struct i2c_adapter *i2c_adap)
1000 struct lgdt3305_state *state = NULL;
1001 int ret;
1002 u8 val;
1004 lg_dbg("(%d-%04x)\n",
1005 i2c_adap ? i2c_adapter_id(i2c_adap) : 0,
1006 config ? config->i2c_addr : 0);
1008 state = kzalloc(sizeof(struct lgdt3305_state), GFP_KERNEL);
1009 if (state == NULL)
1010 goto fail;
1012 state->cfg = config;
1013 state->i2c_adap = i2c_adap;
1015 memcpy(&state->frontend.ops, &lgdt3305_ops,
1016 sizeof(struct dvb_frontend_ops));
1017 state->frontend.demodulator_priv = state;
1019 /* verify that we're talking to a lg dt3305 */
1020 ret = lgdt3305_read_reg(state, LGDT3305_GEN_CTRL_2, &val);
1021 if ((lg_fail(ret)) | (val == 0))
1022 goto fail;
1023 ret = lgdt3305_write_reg(state, 0x0808, 0x80);
1024 if (lg_fail(ret))
1025 goto fail;
1026 ret = lgdt3305_read_reg(state, 0x0808, &val);
1027 if ((lg_fail(ret)) | (val != 0x80))
1028 goto fail;
1029 ret = lgdt3305_write_reg(state, 0x0808, 0x00);
1030 if (lg_fail(ret))
1031 goto fail;
1033 state->current_frequency = -1;
1034 state->current_modulation = -1;
1036 return &state->frontend;
1037 fail:
1038 lg_warn("unable to detect LGDT3305 hardware\n");
1039 kfree(state);
1040 return NULL;
1042 EXPORT_SYMBOL(lgdt3305_attach);
1044 static struct dvb_frontend_ops lgdt3305_ops = {
1045 .info = {
1046 .name = "LG Electronics LGDT3305 VSB/QAM Frontend",
1047 .type = FE_ATSC,
1048 .frequency_min = 54000000,
1049 .frequency_max = 858000000,
1050 .frequency_stepsize = 62500,
1051 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
1053 .i2c_gate_ctrl = lgdt3305_i2c_gate_ctrl,
1054 .init = lgdt3305_init,
1055 .sleep = lgdt3305_sleep,
1056 .set_frontend = lgdt3305_set_parameters,
1057 .get_frontend = lgdt3305_get_frontend,
1058 .get_tune_settings = lgdt3305_get_tune_settings,
1059 .read_status = lgdt3305_read_status,
1060 .read_ber = lgdt3305_read_ber,
1061 .read_signal_strength = lgdt3305_read_signal_strength,
1062 .read_snr = lgdt3305_read_snr,
1063 .read_ucblocks = lgdt3305_read_ucblocks,
1064 .release = lgdt3305_release,
1067 MODULE_DESCRIPTION("LG Electronics LGDT3305 ATSC/QAM-B Demodulator Driver");
1068 MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
1069 MODULE_LICENSE("GPL");
1070 MODULE_VERSION("0.1");
1073 * Local variables:
1074 * c-basic-offset: 8
1075 * End: