|
@@ -30,6 +30,17 @@ static int debug;
|
|
|
module_param(debug, int, 0644);
|
|
|
MODULE_PARM_DESC(debug, "set debug level (info=1, reg=2 (or-able))");
|
|
|
|
|
|
+/*
|
|
|
+ * Older drivers treated QAM64 and QAM256 the same; that is the HW always
|
|
|
+ * used "Auto" mode during detection. Setting "forced_manual"=1 allows
|
|
|
+ * the user to treat these modes as separate. For backwards compatibility,
|
|
|
+ * it's off by default. QAM_AUTO can now be specified to achive that
|
|
|
+ * effect even if "forced_manual"=1
|
|
|
+ */
|
|
|
+static int forced_manual;
|
|
|
+module_param(forced_manual, int, 0644);
|
|
|
+MODULE_PARM_DESC(forced_manual, "if set, QAM64 and QAM256 will only lock to modulation specified");
|
|
|
+
|
|
|
#define DBG_INFO 1
|
|
|
#define DBG_REG 2
|
|
|
#define DBG_DUMP 4 /* FGR - comment out to remove dump code */
|
|
@@ -566,7 +577,12 @@ static int lgdt3306a_set_qam(struct lgdt3306a_state *state, int modulation)
|
|
|
/* 3. : 64QAM/256QAM detection(manual, auto) */
|
|
|
ret = lgdt3306a_read_reg(state, 0x0009, &val);
|
|
|
val &= 0xfc;
|
|
|
- val |= 0x02; /* STDOPDETCMODE[1:0]=1=Manual 2=Auto */
|
|
|
+ /* Check for forced Manual modulation modes; otherwise always "auto" */
|
|
|
+ if(forced_manual && (modulation != QAM_AUTO)){
|
|
|
+ val |= 0x01; /* STDOPDETCMODE[1:0]= 1=Manual */
|
|
|
+ } else {
|
|
|
+ val |= 0x02; /* STDOPDETCMODE[1:0]= 2=Auto */
|
|
|
+ }
|
|
|
ret = lgdt3306a_write_reg(state, 0x0009, val);
|
|
|
if (lg_chkerr(ret))
|
|
|
goto fail;
|
|
@@ -642,10 +658,9 @@ static int lgdt3306a_set_modulation(struct lgdt3306a_state *state,
|
|
|
ret = lgdt3306a_set_vsb(state);
|
|
|
break;
|
|
|
case QAM_64:
|
|
|
- ret = lgdt3306a_set_qam(state, QAM_64);
|
|
|
- break;
|
|
|
case QAM_256:
|
|
|
- ret = lgdt3306a_set_qam(state, QAM_256);
|
|
|
+ case QAM_AUTO:
|
|
|
+ ret = lgdt3306a_set_qam(state, p->modulation);
|
|
|
break;
|
|
|
default:
|
|
|
return -EINVAL;
|
|
@@ -672,6 +687,7 @@ static int lgdt3306a_agc_setup(struct lgdt3306a_state *state,
|
|
|
break;
|
|
|
case QAM_64:
|
|
|
case QAM_256:
|
|
|
+ case QAM_AUTO:
|
|
|
break;
|
|
|
default:
|
|
|
return -EINVAL;
|
|
@@ -726,6 +742,7 @@ static int lgdt3306a_spectral_inversion(struct lgdt3306a_state *state,
|
|
|
break;
|
|
|
case QAM_64:
|
|
|
case QAM_256:
|
|
|
+ case QAM_AUTO:
|
|
|
/* Auto ok for QAM */
|
|
|
ret = lgdt3306a_set_inversion_auto(state, 1);
|
|
|
break;
|
|
@@ -749,6 +766,7 @@ static int lgdt3306a_set_if(struct lgdt3306a_state *state,
|
|
|
break;
|
|
|
case QAM_64:
|
|
|
case QAM_256:
|
|
|
+ case QAM_AUTO:
|
|
|
if_freq_khz = state->cfg->qam_if_khz;
|
|
|
break;
|
|
|
default:
|
|
@@ -1607,6 +1625,7 @@ static int lgdt3306a_read_status(struct dvb_frontend *fe,
|
|
|
switch (state->current_modulation) {
|
|
|
case QAM_256:
|
|
|
case QAM_64:
|
|
|
+ case QAM_AUTO:
|
|
|
if (lgdt3306a_qam_lock_poll(state) == LG3306_LOCK) {
|
|
|
*status |= FE_HAS_VITERBI;
|
|
|
*status |= FE_HAS_SYNC;
|
|
@@ -1650,6 +1669,7 @@ static int lgdt3306a_read_signal_strength(struct dvb_frontend *fe,
|
|
|
* Calculate some sort of "strength" from SNR
|
|
|
*/
|
|
|
struct lgdt3306a_state *state = fe->demodulator_priv;
|
|
|
+ u8 val;
|
|
|
u16 snr; /* snr_x10 */
|
|
|
int ret;
|
|
|
u32 ref_snr; /* snr*100 */
|
|
@@ -1662,11 +1682,15 @@ static int lgdt3306a_read_signal_strength(struct dvb_frontend *fe,
|
|
|
ref_snr = 1600; /* 16dB */
|
|
|
break;
|
|
|
case QAM_64:
|
|
|
- ref_snr = 2200; /* 22dB */
|
|
|
- break;
|
|
|
case QAM_256:
|
|
|
- ref_snr = 2800; /* 28dB */
|
|
|
- break;
|
|
|
+ case QAM_AUTO:
|
|
|
+ /* need to know actual modulation to set proper SNR baseline */
|
|
|
+ lgdt3306a_read_reg(state, 0x00a6, &val);
|
|
|
+ if(val & 0x04)
|
|
|
+ ref_snr = 2800; /* QAM-256 28dB */
|
|
|
+ else
|
|
|
+ ref_snr = 2200; /* QAM-64 22dB */
|
|
|
+ break;
|
|
|
default:
|
|
|
return -EINVAL;
|
|
|
}
|
|
@@ -2136,7 +2160,7 @@ static const struct dvb_frontend_ops lgdt3306a_ops = {
|
|
|
.frequency_min = 54000000,
|
|
|
.frequency_max = 858000000,
|
|
|
.frequency_stepsize = 62500,
|
|
|
- .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
|
|
|
+ .caps = FE_CAN_QAM_AUTO | FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
|
|
|
},
|
|
|
.i2c_gate_ctrl = lgdt3306a_i2c_gate_ctrl,
|
|
|
.init = lgdt3306a_init,
|