diff options
Diffstat (limited to 'drivers/media/common/tuners/tuner-xc2028.c')
-rw-r--r-- | drivers/media/common/tuners/tuner-xc2028.c | 116 |
1 files changed, 55 insertions, 61 deletions
diff --git a/drivers/media/common/tuners/tuner-xc2028.c b/drivers/media/common/tuners/tuner-xc2028.c index 3acbaa04e1b3..27555995f7e4 100644 --- a/drivers/media/common/tuners/tuner-xc2028.c +++ b/drivers/media/common/tuners/tuner-xc2028.c @@ -311,7 +311,7 @@ static int load_all_firmwares(struct dvb_frontend *fe) n_array, fname, name, priv->firm_version >> 8, priv->firm_version & 0xff); - priv->firm = kzalloc(sizeof(*priv->firm) * n_array, GFP_KERNEL); + priv->firm = kcalloc(n_array, sizeof(*priv->firm), GFP_KERNEL); if (priv->firm == NULL) { tuner_err("Not enough memory to load firmware file.\n"); rc = -ENOMEM; @@ -891,7 +891,7 @@ static int xc2028_signal(struct dvb_frontend *fe, u16 *strength) /* Frequency is locked */ if (frq_lock == 1) - signal = 32768; + signal = 1 << 11; /* Get SNR of the video signal */ rc = xc2028_get_reg(priv, 0x0040, &signal); @@ -962,14 +962,24 @@ static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */, * For DTV 7/8, the firmware uses BW = 8000, so it needs a * further adjustment to get the frequency center on VHF */ + + /* + * The firmware DTV78 used to work fine in UHF band (8 MHz + * bandwidth) but not at all in VHF band (7 MHz bandwidth). + * The real problem was connected to the formula used to + * calculate the center frequency offset in VHF band. + * In fact, removing the 500KHz adjustment fixed the problem. + * This is coherent to what was implemented for the DTV7 + * firmware. + * In the end, now the center frequency is the same for all 3 + * firmwares (DTV7, DTV8, DTV78) and doesn't depend on channel + * bandwidth. + */ + if (priv->cur_fw.type & DTV6) offset = 1750000; - else if (priv->cur_fw.type & DTV7) - offset = 2250000; - else /* DTV8 or DTV78 */ + else /* DTV7 or DTV8 or DTV78 */ offset = 2750000; - if ((priv->cur_fw.type & DTV78) && freq < 470000000) - offset -= 500000; /* * xc3028 additional "magic" @@ -979,17 +989,13 @@ static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */, * newer firmwares */ -#if 1 /* * The proper adjustment would be to do it at s-code table. * However, this didn't work, as reported by * Robert Lowery <rglowery@exemail.com.au> */ - if (priv->cur_fw.type & DTV7) - offset += 500000; - -#else +#if 0 /* * Still need tests for XC3028L (firmware 3.2 or upper) * So, for now, let's just comment the per-firmware @@ -1084,68 +1090,28 @@ static int xc2028_set_analog_freq(struct dvb_frontend *fe, V4L2_TUNER_ANALOG_TV, type, p->std, 0); } -static int xc2028_set_params(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int xc2028_set_params(struct dvb_frontend *fe) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + u32 delsys = c->delivery_system; + u32 bw = c->bandwidth_hz; struct xc2028_data *priv = fe->tuner_priv; unsigned int type=0; - fe_bandwidth_t bw = BANDWIDTH_8_MHZ; u16 demod = 0; tuner_dbg("%s called\n", __func__); - switch(fe->ops.info.type) { - case FE_OFDM: - bw = p->u.ofdm.bandwidth; + switch (delsys) { + case SYS_DVBT: + case SYS_DVBT2: /* * The only countries with 6MHz seem to be Taiwan/Uruguay. * Both seem to require QAM firmware for OFDM decoding * Tested in Taiwan by Terry Wu <terrywu2009@gmail.com> */ - if (bw == BANDWIDTH_6_MHZ) + if (bw <= 6000000) type |= QAM; - break; - case FE_ATSC: - bw = BANDWIDTH_6_MHZ; - /* The only ATSC firmware (at least on v2.7) is D2633 */ - type |= ATSC | D2633; - break; - /* DVB-S and pure QAM (FE_QAM) are not supported */ - default: - return -EINVAL; - } - - switch (bw) { - case BANDWIDTH_8_MHZ: - if (p->frequency < 470000000) - priv->ctrl.vhfbw7 = 0; - else - priv->ctrl.uhfbw8 = 1; - type |= (priv->ctrl.vhfbw7 && priv->ctrl.uhfbw8) ? DTV78 : DTV8; - type |= F8MHZ; - break; - case BANDWIDTH_7_MHZ: - if (p->frequency < 470000000) - priv->ctrl.vhfbw7 = 1; - else - priv->ctrl.uhfbw8 = 0; - type |= (priv->ctrl.vhfbw7 && priv->ctrl.uhfbw8) ? DTV78 : DTV7; - type |= F8MHZ; - break; - case BANDWIDTH_6_MHZ: - type |= DTV6; - priv->ctrl.vhfbw7 = 0; - priv->ctrl.uhfbw8 = 0; - break; - default: - tuner_err("error: bandwidth not supported.\n"); - }; - /* - Selects between D2633 or D2620 firmware. - It doesn't make sense for ATSC, since it should be D2633 on all cases - */ - if (fe->ops.info.type != FE_ATSC) { switch (priv->ctrl.type) { case XC2028_D2633: type |= D2633; @@ -1161,6 +1127,34 @@ static int xc2028_set_params(struct dvb_frontend *fe, else type |= D2620; } + break; + case SYS_ATSC: + /* The only ATSC firmware (at least on v2.7) is D2633 */ + type |= ATSC | D2633; + break; + /* DVB-S and pure QAM (FE_QAM) are not supported */ + default: + return -EINVAL; + } + + if (bw <= 6000000) { + type |= DTV6; + priv->ctrl.vhfbw7 = 0; + priv->ctrl.uhfbw8 = 0; + } else if (bw <= 7000000) { + if (c->frequency < 470000000) + priv->ctrl.vhfbw7 = 1; + else + priv->ctrl.uhfbw8 = 0; + type |= (priv->ctrl.vhfbw7 && priv->ctrl.uhfbw8) ? DTV78 : DTV7; + type |= F8MHZ; + } else { + if (c->frequency < 470000000) + priv->ctrl.vhfbw7 = 0; + else + priv->ctrl.uhfbw8 = 1; + type |= (priv->ctrl.vhfbw7 && priv->ctrl.uhfbw8) ? DTV78 : DTV8; + type |= F8MHZ; } /* All S-code tables need a 200kHz shift */ @@ -1185,7 +1179,7 @@ static int xc2028_set_params(struct dvb_frontend *fe, */ } - return generic_set_freq(fe, p->frequency, + return generic_set_freq(fe, c->frequency, V4L2_TUNER_DIGITAL_TV, type, 0, demod); } |