lgdt3306a.c (4c7c3f9b1a85d26ffd4a8a31dd661856c7482357) lgdt3306a.c (4966c0c5c61c0c3a5fb0ebfed7495df02027205f)
1/*
2 * Support for LGDT3306A - 8VSB/QAM-B
3 *
4 * Copyright (C) 2013 Fred Richter <frichter@hauppauge.com>
5 * - driver structure based on lgdt3305.[ch] by Michael Krufky
6 * - code based on LG3306_V0.35 API by LG Electronics Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify

--- 16 unchanged lines hidden (view full) ---

25#include "lgdt3306a.h"
26#include <linux/i2c-mux.h>
27
28
29static int debug;
30module_param(debug, int, 0644);
31MODULE_PARM_DESC(debug, "set debug level (info=1, reg=2 (or-able))");
32
1/*
2 * Support for LGDT3306A - 8VSB/QAM-B
3 *
4 * Copyright (C) 2013 Fred Richter <frichter@hauppauge.com>
5 * - driver structure based on lgdt3305.[ch] by Michael Krufky
6 * - code based on LG3306_V0.35 API by LG Electronics Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify

--- 16 unchanged lines hidden (view full) ---

25#include "lgdt3306a.h"
26#include <linux/i2c-mux.h>
27
28
29static int debug;
30module_param(debug, int, 0644);
31MODULE_PARM_DESC(debug, "set debug level (info=1, reg=2 (or-able))");
32
33/*
34 * Older drivers treated QAM64 and QAM256 the same; that is the HW always
35 * used "Auto" mode during detection. Setting "forced_manual"=1 allows
36 * the user to treat these modes as separate. For backwards compatibility,
37 * it's off by default. QAM_AUTO can now be specified to achive that
38 * effect even if "forced_manual"=1
39 */
40static int forced_manual;
41module_param(forced_manual, int, 0644);
42MODULE_PARM_DESC(forced_manual, "if set, QAM64 and QAM256 will only lock to modulation specified");
43
33#define DBG_INFO 1
34#define DBG_REG 2
35#define DBG_DUMP 4 /* FGR - comment out to remove dump code */
36
37#define lg_debug(fmt, arg...) \
38 printk(KERN_DEBUG pr_fmt(fmt), ## arg)
39
40#define dbg_info(fmt, arg...) \

--- 520 unchanged lines hidden (view full) ---

561 val &= 0xe3; /* STDOPDETTMODE[2:0]=0 VSB Off */
562 ret = lgdt3306a_write_reg(state, 0x0009, val);
563 if (lg_chkerr(ret))
564 goto fail;
565
566 /* 3. : 64QAM/256QAM detection(manual, auto) */
567 ret = lgdt3306a_read_reg(state, 0x0009, &val);
568 val &= 0xfc;
44#define DBG_INFO 1
45#define DBG_REG 2
46#define DBG_DUMP 4 /* FGR - comment out to remove dump code */
47
48#define lg_debug(fmt, arg...) \
49 printk(KERN_DEBUG pr_fmt(fmt), ## arg)
50
51#define dbg_info(fmt, arg...) \

--- 520 unchanged lines hidden (view full) ---

572 val &= 0xe3; /* STDOPDETTMODE[2:0]=0 VSB Off */
573 ret = lgdt3306a_write_reg(state, 0x0009, val);
574 if (lg_chkerr(ret))
575 goto fail;
576
577 /* 3. : 64QAM/256QAM detection(manual, auto) */
578 ret = lgdt3306a_read_reg(state, 0x0009, &val);
579 val &= 0xfc;
569 val |= 0x02; /* STDOPDETCMODE[1:0]=1=Manual 2=Auto */
580 /* Check for forced Manual modulation modes; otherwise always "auto" */
581 if(forced_manual && (modulation != QAM_AUTO)){
582 val |= 0x01; /* STDOPDETCMODE[1:0]= 1=Manual */
583 } else {
584 val |= 0x02; /* STDOPDETCMODE[1:0]= 2=Auto */
585 }
570 ret = lgdt3306a_write_reg(state, 0x0009, val);
571 if (lg_chkerr(ret))
572 goto fail;
573
574 /* 3a. : 64QAM/256QAM selection for manual */
575 ret = lgdt3306a_read_reg(state, 0x101a, &val);
576 val &= 0xf8;
577 if (modulation == QAM_64)

--- 59 unchanged lines hidden (view full) ---

637
638 dbg_info("\n");
639
640 switch (p->modulation) {
641 case VSB_8:
642 ret = lgdt3306a_set_vsb(state);
643 break;
644 case QAM_64:
586 ret = lgdt3306a_write_reg(state, 0x0009, val);
587 if (lg_chkerr(ret))
588 goto fail;
589
590 /* 3a. : 64QAM/256QAM selection for manual */
591 ret = lgdt3306a_read_reg(state, 0x101a, &val);
592 val &= 0xf8;
593 if (modulation == QAM_64)

--- 59 unchanged lines hidden (view full) ---

653
654 dbg_info("\n");
655
656 switch (p->modulation) {
657 case VSB_8:
658 ret = lgdt3306a_set_vsb(state);
659 break;
660 case QAM_64:
645 ret = lgdt3306a_set_qam(state, QAM_64);
646 break;
647 case QAM_256:
661 case QAM_256:
648 ret = lgdt3306a_set_qam(state, QAM_256);
662 case QAM_AUTO:
663 ret = lgdt3306a_set_qam(state, p->modulation);
649 break;
650 default:
651 return -EINVAL;
652 }
653 if (lg_chkerr(ret))
654 goto fail;
655
656 state->current_modulation = p->modulation;

--- 10 unchanged lines hidden (view full) ---

667 /* TODO: anything we want to do here??? */
668 dbg_info("\n");
669
670 switch (p->modulation) {
671 case VSB_8:
672 break;
673 case QAM_64:
674 case QAM_256:
664 break;
665 default:
666 return -EINVAL;
667 }
668 if (lg_chkerr(ret))
669 goto fail;
670
671 state->current_modulation = p->modulation;

--- 10 unchanged lines hidden (view full) ---

682 /* TODO: anything we want to do here??? */
683 dbg_info("\n");
684
685 switch (p->modulation) {
686 case VSB_8:
687 break;
688 case QAM_64:
689 case QAM_256:
690 case QAM_AUTO:
675 break;
676 default:
677 return -EINVAL;
678 }
679 return 0;
680}
681
682/* ------------------------------------------------------------------------ */

--- 38 unchanged lines hidden (view full) ---

721
722 switch (p->modulation) {
723 case VSB_8:
724 /* Manual only for VSB */
725 ret = lgdt3306a_set_inversion_auto(state, 0);
726 break;
727 case QAM_64:
728 case QAM_256:
691 break;
692 default:
693 return -EINVAL;
694 }
695 return 0;
696}
697
698/* ------------------------------------------------------------------------ */

--- 38 unchanged lines hidden (view full) ---

737
738 switch (p->modulation) {
739 case VSB_8:
740 /* Manual only for VSB */
741 ret = lgdt3306a_set_inversion_auto(state, 0);
742 break;
743 case QAM_64:
744 case QAM_256:
745 case QAM_AUTO:
729 /* Auto ok for QAM */
730 ret = lgdt3306a_set_inversion_auto(state, 1);
731 break;
732 default:
733 ret = -EINVAL;
734 }
735#endif
736 return ret;

--- 7 unchanged lines hidden (view full) ---

744 u8 nco1, nco2;
745
746 switch (p->modulation) {
747 case VSB_8:
748 if_freq_khz = state->cfg->vsb_if_khz;
749 break;
750 case QAM_64:
751 case QAM_256:
746 /* Auto ok for QAM */
747 ret = lgdt3306a_set_inversion_auto(state, 1);
748 break;
749 default:
750 ret = -EINVAL;
751 }
752#endif
753 return ret;

--- 7 unchanged lines hidden (view full) ---

761 u8 nco1, nco2;
762
763 switch (p->modulation) {
764 case VSB_8:
765 if_freq_khz = state->cfg->vsb_if_khz;
766 break;
767 case QAM_64:
768 case QAM_256:
769 case QAM_AUTO:
752 if_freq_khz = state->cfg->qam_if_khz;
753 break;
754 default:
755 return -EINVAL;
756 }
757
758 switch (if_freq_khz) {
759 default:

--- 842 unchanged lines hidden (view full) ---

1602 *status = 0;
1603 if (lgdt3306a_neverlock_poll(state) == LG3306_NL_LOCK) {
1604 *status |= FE_HAS_SIGNAL;
1605 *status |= FE_HAS_CARRIER;
1606
1607 switch (state->current_modulation) {
1608 case QAM_256:
1609 case QAM_64:
770 if_freq_khz = state->cfg->qam_if_khz;
771 break;
772 default:
773 return -EINVAL;
774 }
775
776 switch (if_freq_khz) {
777 default:

--- 842 unchanged lines hidden (view full) ---

1620 *status = 0;
1621 if (lgdt3306a_neverlock_poll(state) == LG3306_NL_LOCK) {
1622 *status |= FE_HAS_SIGNAL;
1623 *status |= FE_HAS_CARRIER;
1624
1625 switch (state->current_modulation) {
1626 case QAM_256:
1627 case QAM_64:
1628 case QAM_AUTO:
1610 if (lgdt3306a_qam_lock_poll(state) == LG3306_LOCK) {
1611 *status |= FE_HAS_VITERBI;
1612 *status |= FE_HAS_SYNC;
1613
1614 *status |= FE_HAS_LOCK;
1615 }
1616 break;
1617 case VSB_8:

--- 27 unchanged lines hidden (view full) ---

1645
1646static int lgdt3306a_read_signal_strength(struct dvb_frontend *fe,
1647 u16 *strength)
1648{
1649 /*
1650 * Calculate some sort of "strength" from SNR
1651 */
1652 struct lgdt3306a_state *state = fe->demodulator_priv;
1629 if (lgdt3306a_qam_lock_poll(state) == LG3306_LOCK) {
1630 *status |= FE_HAS_VITERBI;
1631 *status |= FE_HAS_SYNC;
1632
1633 *status |= FE_HAS_LOCK;
1634 }
1635 break;
1636 case VSB_8:

--- 27 unchanged lines hidden (view full) ---

1664
1665static int lgdt3306a_read_signal_strength(struct dvb_frontend *fe,
1666 u16 *strength)
1667{
1668 /*
1669 * Calculate some sort of "strength" from SNR
1670 */
1671 struct lgdt3306a_state *state = fe->demodulator_priv;
1672 u8 val;
1653 u16 snr; /* snr_x10 */
1654 int ret;
1655 u32 ref_snr; /* snr*100 */
1656 u32 str;
1657
1658 *strength = 0;
1659
1660 switch (state->current_modulation) {
1661 case VSB_8:
1662 ref_snr = 1600; /* 16dB */
1663 break;
1664 case QAM_64:
1673 u16 snr; /* snr_x10 */
1674 int ret;
1675 u32 ref_snr; /* snr*100 */
1676 u32 str;
1677
1678 *strength = 0;
1679
1680 switch (state->current_modulation) {
1681 case VSB_8:
1682 ref_snr = 1600; /* 16dB */
1683 break;
1684 case QAM_64:
1665 ref_snr = 2200; /* 22dB */
1666 break;
1667 case QAM_256:
1685 case QAM_256:
1668 ref_snr = 2800; /* 28dB */
1669 break;
1686 case QAM_AUTO:
1687 /* need to know actual modulation to set proper SNR baseline */
1688 lgdt3306a_read_reg(state, 0x00a6, &val);
1689 if(val & 0x04)
1690 ref_snr = 2800; /* QAM-256 28dB */
1691 else
1692 ref_snr = 2200; /* QAM-64 22dB */
1693 break;
1670 default:
1671 return -EINVAL;
1672 }
1673
1674 ret = fe->ops.read_snr(fe, &snr);
1675 if (lg_chkerr(ret))
1676 goto fail;
1677

--- 453 unchanged lines hidden (view full) ---

2131
2132static const struct dvb_frontend_ops lgdt3306a_ops = {
2133 .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
2134 .info = {
2135 .name = "LG Electronics LGDT3306A VSB/QAM Frontend",
2136 .frequency_min = 54000000,
2137 .frequency_max = 858000000,
2138 .frequency_stepsize = 62500,
1694 default:
1695 return -EINVAL;
1696 }
1697
1698 ret = fe->ops.read_snr(fe, &snr);
1699 if (lg_chkerr(ret))
1700 goto fail;
1701

--- 453 unchanged lines hidden (view full) ---

2155
2156static const struct dvb_frontend_ops lgdt3306a_ops = {
2157 .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
2158 .info = {
2159 .name = "LG Electronics LGDT3306A VSB/QAM Frontend",
2160 .frequency_min = 54000000,
2161 .frequency_max = 858000000,
2162 .frequency_stepsize = 62500,
2139 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
2163 .caps = FE_CAN_QAM_AUTO | FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
2140 },
2141 .i2c_gate_ctrl = lgdt3306a_i2c_gate_ctrl,
2142 .init = lgdt3306a_init,
2143 .sleep = lgdt3306a_fe_sleep,
2144 /* if this is set, it overrides the default swzigzag */
2145 .tune = lgdt3306a_tune,
2146 .set_frontend = lgdt3306a_set_parameters,
2147 .get_frontend = lgdt3306a_get_frontend,

--- 122 unchanged lines hidden ---
2164 },
2165 .i2c_gate_ctrl = lgdt3306a_i2c_gate_ctrl,
2166 .init = lgdt3306a_init,
2167 .sleep = lgdt3306a_fe_sleep,
2168 /* if this is set, it overrides the default swzigzag */
2169 .tune = lgdt3306a_tune,
2170 .set_frontend = lgdt3306a_set_parameters,
2171 .get_frontend = lgdt3306a_get_frontend,

--- 122 unchanged lines hidden ---