diff options
Diffstat (limited to 'drivers/media/dvb')
155 files changed, 10085 insertions, 5222 deletions
diff --git a/drivers/media/dvb/b2c2/flexcop.c b/drivers/media/dvb/b2c2/flexcop.c index 2df1b0214dcd..b1e8c99f469b 100644 --- a/drivers/media/dvb/b2c2/flexcop.c +++ b/drivers/media/dvb/b2c2/flexcop.c @@ -86,7 +86,8 @@ static int flexcop_dvb_init(struct flexcop_device *fc) fc->demux.stop_feed = flexcop_dvb_stop_feed; fc->demux.write_to_decoder = NULL; - if ((ret = dvb_dmx_init(&fc->demux)) < 0) { + ret = dvb_dmx_init(&fc->demux); + if (ret < 0) { err("dvb_dmx failed: error %d", ret); goto err_dmx; } @@ -96,32 +97,42 @@ static int flexcop_dvb_init(struct flexcop_device *fc) fc->dmxdev.filternum = fc->demux.feednum; fc->dmxdev.demux = &fc->demux.dmx; fc->dmxdev.capabilities = 0; - if ((ret = dvb_dmxdev_init(&fc->dmxdev, &fc->dvb_adapter)) < 0) { + ret = dvb_dmxdev_init(&fc->dmxdev, &fc->dvb_adapter); + if (ret < 0) { err("dvb_dmxdev_init failed: error %d", ret); goto err_dmx_dev; } - if ((ret = fc->demux.dmx.add_frontend(&fc->demux.dmx, &fc->hw_frontend)) < 0) { + ret = fc->demux.dmx.add_frontend(&fc->demux.dmx, &fc->hw_frontend); + if (ret < 0) { err("adding hw_frontend to dmx failed: error %d", ret); goto err_dmx_add_hw_frontend; } fc->mem_frontend.source = DMX_MEMORY_FE; - if ((ret = fc->demux.dmx.add_frontend(&fc->demux.dmx, &fc->mem_frontend)) < 0) { + ret = fc->demux.dmx.add_frontend(&fc->demux.dmx, &fc->mem_frontend); + if (ret < 0) { err("adding mem_frontend to dmx failed: error %d", ret); goto err_dmx_add_mem_frontend; } - if ((ret = fc->demux.dmx.connect_frontend(&fc->demux.dmx, &fc->hw_frontend)) < 0) { + ret = fc->demux.dmx.connect_frontend(&fc->demux.dmx, &fc->hw_frontend); + if (ret < 0) { err("connect frontend failed: error %d", ret); goto err_connect_frontend; } - dvb_net_init(&fc->dvb_adapter, &fc->dvbnet, &fc->demux.dmx); + ret = dvb_net_init(&fc->dvb_adapter, &fc->dvbnet, &fc->demux.dmx); + if (ret < 0) { + err("dvb_net_init failed: error %d", ret); + goto err_net; + } fc->init_state |= FC_STATE_DVB_INIT; return 0; +err_net: + fc->demux.dmx.disconnect_frontend(&fc->demux.dmx); err_connect_frontend: fc->demux.dmx.remove_frontend(&fc->demux.dmx, &fc->mem_frontend); err_dmx_add_mem_frontend: @@ -254,7 +265,8 @@ int flexcop_device_initialize(struct flexcop_device *fc) flexcop_hw_filter_init(fc); flexcop_smc_ctrl(fc, 0); - if ((ret = flexcop_dvb_init(fc))) + ret = flexcop_dvb_init(fc); + if (ret) goto error; /* i2c has to be done before doing EEProm stuff - @@ -272,7 +284,8 @@ int flexcop_device_initialize(struct flexcop_device *fc) } else warn("reading of MAC address failed.\n"); - if ((ret = flexcop_frontend_init(fc))) + ret = flexcop_frontend_init(fc); + if (ret) goto error; flexcop_device_name(fc,"initialization of","complete"); diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c index caa4e18ed1c1..430b3eb11815 100644 --- a/drivers/media/dvb/bt8xx/dst.c +++ b/drivers/media/dvb/bt8xx/dst.c @@ -386,7 +386,7 @@ static int dst_set_freq(struct dst_state *state, u32 freq) return 0; } -static int dst_set_bandwidth(struct dst_state *state, fe_bandwidth_t bandwidth) +static int dst_set_bandwidth(struct dst_state *state, u32 bandwidth) { state->bandwidth = bandwidth; @@ -394,7 +394,7 @@ static int dst_set_bandwidth(struct dst_state *state, fe_bandwidth_t bandwidth) return -EOPNOTSUPP; switch (bandwidth) { - case BANDWIDTH_6_MHZ: + case 6000000: if (state->dst_hw_cap & DST_TYPE_HAS_CA) state->tx_tuna[7] = 0x06; else { @@ -402,7 +402,7 @@ static int dst_set_bandwidth(struct dst_state *state, fe_bandwidth_t bandwidth) state->tx_tuna[7] = 0x00; } break; - case BANDWIDTH_7_MHZ: + case 7000000: if (state->dst_hw_cap & DST_TYPE_HAS_CA) state->tx_tuna[7] = 0x07; else { @@ -410,7 +410,7 @@ static int dst_set_bandwidth(struct dst_state *state, fe_bandwidth_t bandwidth) state->tx_tuna[7] = 0x00; } break; - case BANDWIDTH_8_MHZ: + case 8000000: if (state->dst_hw_cap & DST_TYPE_HAS_CA) state->tx_tuna[7] = 0x08; else { @@ -1561,7 +1561,7 @@ static int dst_init(struct dvb_frontend *fe) state->tone = SEC_TONE_OFF; state->diseq_flags = 0; state->k22 = 0x02; - state->bandwidth = BANDWIDTH_7_MHZ; + state->bandwidth = 7000000; state->cur_jiff = jiffies; if (state->dst_type == DST_TYPE_IS_SAT) memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? sat_tuna_188 : sat_tuna_204), sizeof (sat_tuna_204)); @@ -1609,8 +1609,9 @@ static int dst_read_snr(struct dvb_frontend *fe, u16 *snr) return retval; } -static int dst_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) +static int dst_set_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; int retval = -EINVAL; struct dst_state *state = fe->demodulator_priv; @@ -1623,17 +1624,17 @@ static int dst_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_paramet if (state->dst_type == DST_TYPE_IS_SAT) { if (state->type_flags & DST_TYPE_HAS_OBS_REGS) dst_set_inversion(state, p->inversion); - dst_set_fec(state, p->u.qpsk.fec_inner); - dst_set_symbolrate(state, p->u.qpsk.symbol_rate); + dst_set_fec(state, p->fec_inner); + dst_set_symbolrate(state, p->symbol_rate); dst_set_polarization(state); - dprintk(verbose, DST_DEBUG, 1, "Set Symbolrate=[%d]", p->u.qpsk.symbol_rate); + dprintk(verbose, DST_DEBUG, 1, "Set Symbolrate=[%d]", p->symbol_rate); } else if (state->dst_type == DST_TYPE_IS_TERR) - dst_set_bandwidth(state, p->u.ofdm.bandwidth); + dst_set_bandwidth(state, p->bandwidth_hz); else if (state->dst_type == DST_TYPE_IS_CABLE) { - dst_set_fec(state, p->u.qam.fec_inner); - dst_set_symbolrate(state, p->u.qam.symbol_rate); - dst_set_modulation(state, p->u.qam.modulation); + dst_set_fec(state, p->fec_inner); + dst_set_symbolrate(state, p->symbol_rate); + dst_set_modulation(state, p->modulation); } retval = dst_write_tuna(fe); } @@ -1642,31 +1643,32 @@ static int dst_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_paramet } static int dst_tune_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters* p, + bool re_tune, unsigned int mode_flags, unsigned int *delay, fe_status_t *status) { struct dst_state *state = fe->demodulator_priv; + struct dtv_frontend_properties *p = &fe->dtv_property_cache; - if (p != NULL) { + if (re_tune) { dst_set_freq(state, p->frequency); dprintk(verbose, DST_DEBUG, 1, "Set Frequency=[%d]", p->frequency); if (state->dst_type == DST_TYPE_IS_SAT) { if (state->type_flags & DST_TYPE_HAS_OBS_REGS) dst_set_inversion(state, p->inversion); - dst_set_fec(state, p->u.qpsk.fec_inner); - dst_set_symbolrate(state, p->u.qpsk.symbol_rate); + dst_set_fec(state, p->fec_inner); + dst_set_symbolrate(state, p->symbol_rate); dst_set_polarization(state); - dprintk(verbose, DST_DEBUG, 1, "Set Symbolrate=[%d]", p->u.qpsk.symbol_rate); + dprintk(verbose, DST_DEBUG, 1, "Set Symbolrate=[%d]", p->symbol_rate); } else if (state->dst_type == DST_TYPE_IS_TERR) - dst_set_bandwidth(state, p->u.ofdm.bandwidth); + dst_set_bandwidth(state, p->bandwidth_hz); else if (state->dst_type == DST_TYPE_IS_CABLE) { - dst_set_fec(state, p->u.qam.fec_inner); - dst_set_symbolrate(state, p->u.qam.symbol_rate); - dst_set_modulation(state, p->u.qam.modulation); + dst_set_fec(state, p->fec_inner); + dst_set_symbolrate(state, p->symbol_rate); + dst_set_modulation(state, p->modulation); } dst_write_tuna(fe); } @@ -1683,22 +1685,23 @@ static int dst_get_tuning_algo(struct dvb_frontend *fe) return dst_algo ? DVBFE_ALGO_HW : DVBFE_ALGO_SW; } -static int dst_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) +static int dst_get_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct dst_state *state = fe->demodulator_priv; p->frequency = state->decode_freq; if (state->dst_type == DST_TYPE_IS_SAT) { if (state->type_flags & DST_TYPE_HAS_OBS_REGS) p->inversion = state->inversion; - p->u.qpsk.symbol_rate = state->symbol_rate; - p->u.qpsk.fec_inner = dst_get_fec(state); + p->symbol_rate = state->symbol_rate; + p->fec_inner = dst_get_fec(state); } else if (state->dst_type == DST_TYPE_IS_TERR) { - p->u.ofdm.bandwidth = state->bandwidth; + p->bandwidth_hz = state->bandwidth; } else if (state->dst_type == DST_TYPE_IS_CABLE) { - p->u.qam.symbol_rate = state->symbol_rate; - p->u.qam.fec_inner = dst_get_fec(state); - p->u.qam.modulation = dst_get_modulation(state); + p->symbol_rate = state->symbol_rate; + p->fec_inner = dst_get_fec(state); + p->modulation = dst_get_modulation(state); } return 0; @@ -1756,10 +1759,9 @@ struct dst_state *dst_attach(struct dst_state *state, struct dvb_adapter *dvb_ad EXPORT_SYMBOL(dst_attach); static struct dvb_frontend_ops dst_dvbt_ops = { - + .delsys = { SYS_DVBT }, .info = { .name = "DST DVB-T", - .type = FE_OFDM, .frequency_min = 137000000, .frequency_max = 858000000, .frequency_stepsize = 166667, @@ -1786,10 +1788,9 @@ static struct dvb_frontend_ops dst_dvbt_ops = { }; static struct dvb_frontend_ops dst_dvbs_ops = { - + .delsys = { SYS_DVBS }, .info = { .name = "DST DVB-S", - .type = FE_QPSK, .frequency_min = 950000, .frequency_max = 2150000, .frequency_stepsize = 1000, /* kHz for QPSK frontends */ @@ -1816,10 +1817,9 @@ static struct dvb_frontend_ops dst_dvbs_ops = { }; static struct dvb_frontend_ops dst_dvbc_ops = { - + .delsys = { SYS_DVBC_ANNEX_A }, .info = { .name = "DST DVB-C", - .type = FE_QAM, .frequency_stepsize = 62500, .frequency_min = 51000000, .frequency_max = 858000000, @@ -1846,9 +1846,9 @@ static struct dvb_frontend_ops dst_dvbc_ops = { }; static struct dvb_frontend_ops dst_atsc_ops = { + .delsys = { SYS_ATSC }, .info = { .name = "DST ATSC", - .type = FE_ATSC, .frequency_stepsize = 62500, .frequency_min = 510000000, .frequency_max = 858000000, diff --git a/drivers/media/dvb/bt8xx/dst_common.h b/drivers/media/dvb/bt8xx/dst_common.h index d88cf2add82b..d70d98f1a571 100644 --- a/drivers/media/dvb/bt8xx/dst_common.h +++ b/drivers/media/dvb/bt8xx/dst_common.h @@ -124,7 +124,7 @@ struct dst_state { u16 decode_snr; unsigned long cur_jiff; u8 k22; - fe_bandwidth_t bandwidth; + u32 bandwidth; u32 dst_hw_cap; u8 dst_fw_version; fe_sec_mini_cmd_t minicmd; diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c index 521d69104982..81fab9adc1ca 100644 --- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c +++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c @@ -19,6 +19,8 @@ * */ +#define pr_fmt(fmt) "dvb_bt8xx: " fmt + #include <linux/bitops.h> #include <linux/module.h> #include <linux/init.h> @@ -148,8 +150,9 @@ static int thomson_dtt7579_demod_init(struct dvb_frontend* fe) return 0; } -static int thomson_dtt7579_tuner_calc_regs(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf, int buf_len) +static int thomson_dtt7579_tuner_calc_regs(struct dvb_frontend *fe, u8* pllbuf, int buf_len) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; u32 div; unsigned char bs = 0; unsigned char cp = 0; @@ -157,18 +160,18 @@ static int thomson_dtt7579_tuner_calc_regs(struct dvb_frontend* fe, struct dvb_f if (buf_len < 5) return -EINVAL; - div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; + div = (((c->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; - if (params->frequency < 542000000) + if (c->frequency < 542000000) cp = 0xb4; - else if (params->frequency < 771000000) + else if (c->frequency < 771000000) cp = 0xbc; else cp = 0xf4; - if (params->frequency == 0) + if (c->frequency == 0) bs = 0x03; - else if (params->frequency < 443250000) + else if (c->frequency < 443250000) bs = 0x02; else bs = 0x08; @@ -191,13 +194,12 @@ static struct zl10353_config thomson_dtt7579_zl10353_config = { .demod_address = 0x0f, }; -static int cx24108_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) +static int cx24108_tuner_set_params(struct dvb_frontend *fe) { - u32 freq = params->frequency; - + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + u32 freq = c->frequency; int i, a, n, pump; u32 band, pll; - u32 osci[]={950000,1019000,1075000,1178000,1296000,1432000, 1576000,1718000,1856000,2036000,2150000}; u32 bandsel[]={0,0x00020000,0x00040000,0x00100800,0x00101000, @@ -205,7 +207,7 @@ static int cx24108_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend 0x00120000,0x00140000}; #define XTAL 1011100 /* Hz, really 1.0111 MHz and a /10 prescaler */ - printk("cx24108 debug: entering SetTunerFreq, freq=%d\n",freq); + dprintk("cx24108 debug: entering SetTunerFreq, freq=%d\n", freq); /* This is really the bit driving the tuner chip cx24108 */ @@ -216,7 +218,7 @@ static int cx24108_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend /* decide which VCO to use for the input frequency */ for(i = 1; (i < ARRAY_SIZE(osci) - 1) && (osci[i] < freq); i++); - printk("cx24108 debug: select vco #%d (f=%d)\n",i,freq); + dprintk("cx24108 debug: select vco #%d (f=%d)\n", i, freq); band=bandsel[i]; /* the gain values must be set by SetSymbolrate */ /* compute the pll divider needed, from Conexant data sheet, @@ -232,7 +234,7 @@ static int cx24108_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend ((a&0x1f)<<11); /* everything is shifted left 11 bits to left-align the bits in the 32bit word. Output to the tuner goes MSB-aligned, after all */ - printk("cx24108 debug: pump=%d, n=%d, a=%d\n",pump,n,a); + dprintk("cx24108 debug: pump=%d, n=%d, a=%d\n", pump, n, a); cx24110_pll_write(fe,band); /* set vga and vca to their widest-band settings, as a precaution. SetSymbolrate might not be called to set this up */ @@ -267,31 +269,32 @@ static struct cx24110_config pctvsat_config = { .demod_address = 0x55, }; -static int microtune_mt7202dtf_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) +static int microtune_mt7202dtf_tuner_set_params(struct dvb_frontend *fe) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv; u8 cfg, cpump, band_select; u8 data[4]; u32 div; struct i2c_msg msg = { .addr = 0x60, .flags = 0, .buf = data, .len = sizeof(data) }; - div = (36000000 + params->frequency + 83333) / 166666; + div = (36000000 + c->frequency + 83333) / 166666; cfg = 0x88; - if (params->frequency < 175000000) + if (c->frequency < 175000000) cpump = 2; - else if (params->frequency < 390000000) + else if (c->frequency < 390000000) cpump = 1; - else if (params->frequency < 470000000) + else if (c->frequency < 470000000) cpump = 2; - else if (params->frequency < 750000000) + else if (c->frequency < 750000000) cpump = 2; else cpump = 3; - if (params->frequency < 175000000) + if (c->frequency < 175000000) band_select = 0x0e; - else if (params->frequency < 470000000) + else if (c->frequency < 470000000) band_select = 0x05; else band_select = 0x03; @@ -342,50 +345,51 @@ static int advbt771_samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe) return 0; } -static int advbt771_samsung_tdtc9251dh0_tuner_calc_regs(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf, int buf_len) +static int advbt771_samsung_tdtc9251dh0_tuner_calc_regs(struct dvb_frontend *fe, u8 *pllbuf, int buf_len) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; u32 div; unsigned char bs = 0; unsigned char cp = 0; if (buf_len < 5) return -EINVAL; - div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; + div = (((c->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; - if (params->frequency < 150000000) + if (c->frequency < 150000000) cp = 0xB4; - else if (params->frequency < 173000000) + else if (c->frequency < 173000000) cp = 0xBC; - else if (params->frequency < 250000000) + else if (c->frequency < 250000000) cp = 0xB4; - else if (params->frequency < 400000000) + else if (c->frequency < 400000000) cp = 0xBC; - else if (params->frequency < 420000000) + else if (c->frequency < 420000000) cp = 0xF4; - else if (params->frequency < 470000000) + else if (c->frequency < 470000000) cp = 0xFC; - else if (params->frequency < 600000000) + else if (c->frequency < 600000000) cp = 0xBC; - else if (params->frequency < 730000000) + else if (c->frequency < 730000000) cp = 0xF4; else cp = 0xFC; - if (params->frequency < 150000000) + if (c->frequency < 150000000) bs = 0x01; - else if (params->frequency < 173000000) + else if (c->frequency < 173000000) bs = 0x01; - else if (params->frequency < 250000000) + else if (c->frequency < 250000000) bs = 0x02; - else if (params->frequency < 400000000) + else if (c->frequency < 400000000) bs = 0x02; - else if (params->frequency < 420000000) + else if (c->frequency < 420000000) bs = 0x02; - else if (params->frequency < 470000000) + else if (c->frequency < 470000000) bs = 0x02; - else if (params->frequency < 600000000) + else if (c->frequency < 600000000) bs = 0x08; - else if (params->frequency < 730000000) + else if (c->frequency < 730000000) bs = 0x08; else bs = 0x08; @@ -461,25 +465,26 @@ static struct or51211_config or51211_config = { .sleep = or51211_sleep, }; -static int vp3021_alps_tded4_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) +static int vp3021_alps_tded4_tuner_set_params(struct dvb_frontend *fe) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv; u8 buf[4]; u32 div; struct i2c_msg msg = { .addr = 0x60, .flags = 0, .buf = buf, .len = sizeof(buf) }; - div = (params->frequency + 36166667) / 166667; + div = (c->frequency + 36166667) / 166667; buf[0] = (div >> 8) & 0x7F; buf[1] = div & 0xFF; buf[2] = 0x85; - if ((params->frequency >= 47000000) && (params->frequency < 153000000)) + if ((c->frequency >= 47000000) && (c->frequency < 153000000)) buf[3] = 0x01; - else if ((params->frequency >= 153000000) && (params->frequency < 430000000)) + else if ((c->frequency >= 153000000) && (c->frequency < 430000000)) buf[3] = 0x02; - else if ((params->frequency >= 430000000) && (params->frequency < 824000000)) + else if ((c->frequency >= 430000000) && (c->frequency < 824000000)) buf[3] = 0x0C; - else if ((params->frequency >= 824000000) && (params->frequency < 863000000)) + else if ((c->frequency >= 824000000) && (c->frequency < 863000000)) buf[3] = 0x8C; else return -EINVAL; @@ -513,31 +518,31 @@ static int digitv_alps_tded4_demod_init(struct dvb_frontend* fe) return 0; } -static int digitv_alps_tded4_tuner_calc_regs(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf, int buf_len) +static int digitv_alps_tded4_tuner_calc_regs(struct dvb_frontend *fe, u8 *pllbuf, int buf_len) { u32 div; - struct dvb_ofdm_parameters *op = ¶ms->u.ofdm; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; if (buf_len < 5) return -EINVAL; - div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; + div = (((c->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; pllbuf[0] = 0x61; pllbuf[1] = (div >> 8) & 0x7F; pllbuf[2] = div & 0xFF; pllbuf[3] = 0x85; - dprintk("frequency %u, div %u\n", params->frequency, div); + dprintk("frequency %u, div %u\n", c->frequency, div); - if (params->frequency < 470000000) + if (c->frequency < 470000000) pllbuf[4] = 0x02; - else if (params->frequency > 823000000) + else if (c->frequency > 823000000) pllbuf[4] = 0x88; else pllbuf[4] = 0x08; - if (op->bandwidth == 8) + if (c->bandwidth_hz == 8000000) pllbuf[4] |= 0x04; return 5; @@ -663,7 +668,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) /* DST is not a frontend driver !!! */ state = kmalloc(sizeof (struct dst_state), GFP_KERNEL); if (!state) { - printk("dvb_bt8xx: No memory\n"); + pr_err("No memory\n"); break; } /* Setup the Card */ @@ -673,7 +678,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) state->dst_ca = NULL; /* DST is not a frontend, attaching the ASIC */ if (dvb_attach(dst_attach, state, &card->dvb_adapter) == NULL) { - printk("%s: Could not find a Twinhan DST.\n", __func__); + pr_err("%s: Could not find a Twinhan DST\n", __func__); break; } /* Attach other DST peripherals if any */ @@ -702,14 +707,14 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) } if (card->fe == NULL) - printk("dvb-bt8xx: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n", + pr_err("A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n", card->bt->dev->vendor, card->bt->dev->device, card->bt->dev->subsystem_vendor, card->bt->dev->subsystem_device); else if (dvb_register_frontend(&card->dvb_adapter, card->fe)) { - printk("dvb-bt8xx: Frontend registration failed!\n"); + pr_err("Frontend registration failed!\n"); dvb_frontend_detach(card->fe); card->fe = NULL; } @@ -723,7 +728,7 @@ static int __devinit dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type) THIS_MODULE, &card->bt->dev->dev, adapter_nr); if (result < 0) { - printk("dvb_bt8xx: dvb_register_adapter failed (errno = %d)\n", result); + pr_err("dvb_register_adapter failed (errno = %d)\n", result); return result; } card->dvb_adapter.priv = card; @@ -741,66 +746,69 @@ static int __devinit dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type) card->demux.stop_feed = dvb_bt8xx_stop_feed; card->demux.write_to_decoder = NULL; - if ((result = dvb_dmx_init(&card->demux)) < 0) { - printk("dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result); - - dvb_unregister_adapter(&card->dvb_adapter); - return result; + result = dvb_dmx_init(&card->demux); + if (result < 0) { + pr_err("dvb_dmx_init failed (errno = %d)\n", result); + goto err_unregister_adaptor; } card->dmxdev.filternum = 256; card->dmxdev.demux = &card->demux.dmx; card->dmxdev.capabilities = 0; - if ((result = dvb_dmxdev_init(&card->dmxdev, &card->dvb_adapter)) < 0) { - printk("dvb_bt8xx: dvb_dmxdev_init failed (errno = %d)\n", result); - - dvb_dmx_release(&card->demux); - dvb_unregister_adapter(&card->dvb_adapter); - return result; + result = dvb_dmxdev_init(&card->dmxdev, &card->dvb_adapter); + if (result < 0) { + pr_err("dvb_dmxdev_init failed (errno = %d)\n", result); + goto err_dmx_release; } card->fe_hw.source = DMX_FRONTEND_0; - if ((result = card->demux.dmx.add_frontend(&card->demux.dmx, &card->fe_hw)) < 0) { - printk("dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result); - - dvb_dmxdev_release(&card->dmxdev); - dvb_dmx_release(&card->demux); - dvb_unregister_adapter(&card->dvb_adapter); - return result; + result = card->demux.dmx.add_frontend(&card->demux.dmx, &card->fe_hw); + if (result < 0) { + pr_err("dvb_dmx_init failed (errno = %d)\n", result); + goto err_dmxdev_release; } card->fe_mem.source = DMX_MEMORY_FE; - if ((result = card->demux.dmx.add_frontend(&card->demux.dmx, &card->fe_mem)) < 0) { - printk("dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result); - - card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw); - dvb_dmxdev_release(&card->dmxdev); - dvb_dmx_release(&card->demux); - dvb_unregister_adapter(&card->dvb_adapter); - return result; + result = card->demux.dmx.add_frontend(&card->demux.dmx, &card->fe_mem); + if (result < 0) { + pr_err("dvb_dmx_init failed (errno = %d)\n", result); + goto err_remove_hw_frontend; } - if ((result = card->demux.dmx.connect_frontend(&card->demux.dmx, &card->fe_hw)) < 0) { - printk("dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result); - - card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_mem); - card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw); - dvb_dmxdev_release(&card->dmxdev); - dvb_dmx_release(&card->demux); - dvb_unregister_adapter(&card->dvb_adapter); - return result; + result = card->demux.dmx.connect_frontend(&card->demux.dmx, &card->fe_hw); + if (result < 0) { + pr_err("dvb_dmx_init failed (errno = %d)\n", result); + goto err_remove_mem_frontend; } - dvb_net_init(&card->dvb_adapter, &card->dvbnet, &card->demux.dmx); + result = dvb_net_init(&card->dvb_adapter, &card->dvbnet, &card->demux.dmx); + if (result < 0) { + pr_err("dvb_net_init failed (errno = %d)\n", result); + goto err_disconnect_frontend; + } tasklet_init(&card->bt->tasklet, dvb_bt8xx_task, (unsigned long) card); frontend_init(card, type); return 0; + +err_disconnect_frontend: + card->demux.dmx.disconnect_frontend(&card->demux.dmx); +err_remove_mem_frontend: + card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_mem); +err_remove_hw_frontend: + card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw); +err_dmxdev_release: + dvb_dmxdev_release(&card->dmxdev); +err_dmx_release: + dvb_dmx_release(&card->demux); +err_unregister_adaptor: + dvb_unregister_adapter(&card->dvb_adapter); + return result; } static int __devinit dvb_bt8xx_probe(struct bttv_sub_device *sub) @@ -881,8 +889,7 @@ static int __devinit dvb_bt8xx_probe(struct bttv_sub_device *sub) break; default: - printk(KERN_WARNING "dvb_bt8xx: Unknown bttv card type: %d.\n", - sub->core->type); + pr_err("Unknown bttv card type: %d\n", sub->core->type); kfree(card); return -ENODEV; } @@ -890,16 +897,14 @@ static int __devinit dvb_bt8xx_probe(struct bttv_sub_device *sub) dprintk("dvb_bt8xx: identified card%d as %s\n", card->bttv_nr, card->card_name); if (!(bttv_pci_dev = bttv_get_pcidev(card->bttv_nr))) { - printk("dvb_bt8xx: no pci device for card %d\n", card->bttv_nr); + pr_err("no pci device for card %d\n", card->bttv_nr); kfree(card); return -ENODEV; } if (!(card->bt = dvb_bt8xx_878_match(card->bttv_nr, bttv_pci_dev))) { - printk("dvb_bt8xx: unable to determine DMA core of card %d,\n", - card->bttv_nr); - printk("dvb_bt8xx: if you have the ALSA bt87x audio driver " - "installed, try removing it.\n"); + pr_err("unable to determine DMA core of card %d,\n", card->bttv_nr); + pr_err("if you have the ALSA bt87x audio driver installed, try removing it.\n"); kfree(card); return -ENODEV; diff --git a/drivers/media/dvb/ddbridge/ddbridge-core.c b/drivers/media/dvb/ddbridge/ddbridge-core.c index d1e91bc80e78..ce4f85849e7b 100644 --- a/drivers/media/dvb/ddbridge/ddbridge-core.c +++ b/drivers/media/dvb/ddbridge/ddbridge-core.c @@ -580,7 +580,7 @@ static int demod_attach_drxk(struct ddb_input *input) memset(&config, 0, sizeof(config)); config.adr = 0x29 + (input->nr & 1); - fe = input->fe = dvb_attach(drxk_attach, &config, i2c, &input->fe2); + fe = input->fe = dvb_attach(drxk_attach, &config, i2c); if (!input->fe) { printk(KERN_ERR "No DRXK found!\n"); return -ENODEV; diff --git a/drivers/media/dvb/dm1105/dm1105.c b/drivers/media/dvb/dm1105/dm1105.c index 55e6533f15e9..a609b3a9b146 100644 --- a/drivers/media/dvb/dm1105/dm1105.c +++ b/drivers/media/dvb/dm1105/dm1105.c @@ -1115,11 +1115,14 @@ static int __devinit dm1105_probe(struct pci_dev *pdev, if (ret < 0) goto err_remove_mem_frontend; - ret = frontend_init(dev); + ret = dvb_net_init(dvb_adapter, &dev->dvbnet, dmx); if (ret < 0) goto err_disconnect_frontend; - dvb_net_init(dvb_adapter, &dev->dvbnet, dmx); + ret = frontend_init(dev); + if (ret < 0) + goto err_dvb_net; + dm1105_ir_init(dev); INIT_WORK(&dev->work, dm1105_dmx_buffer); diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c index 7ea517b7e186..9be65a3b931f 100644 --- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c +++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c @@ -1306,6 +1306,10 @@ static ssize_t dvb_ca_en50221_io_write(struct file *file, /* fragment the packets & store in the buffer */ while (fragpos < count) { fraglen = ca->slot_info[slot].link_buf_size - 2; + if (fraglen < 0) + break; + if (fraglen > HOST_LINK_BUF_SIZE - 2) + fraglen = HOST_LINK_BUF_SIZE - 2; if ((count - fragpos) < fraglen) fraglen = count - fragpos; diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index 2c0acdb4d811..b15db4fe347b 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -25,6 +25,9 @@ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html */ +/* Enables DVBv3 compatibility bits at the headers */ +#define __DVB_CORE__ + #include <linux/string.h> #include <linux/kernel.h> #include <linux/sched.h> @@ -105,7 +108,6 @@ struct dvb_frontend_private { /* thread/frontend values */ struct dvb_device *dvbdev; - struct dvb_frontend_parameters parameters_in; struct dvb_frontend_parameters parameters_out; struct dvb_fe_events events; struct semaphore sem; @@ -139,6 +141,62 @@ struct dvb_frontend_private { }; static void dvb_frontend_wakeup(struct dvb_frontend *fe); +static int dtv_get_frontend(struct dvb_frontend *fe, + struct dvb_frontend_parameters *p_out); + +static bool has_get_frontend(struct dvb_frontend *fe) +{ + return fe->ops.get_frontend; +} + +/* + * Due to DVBv3 API calls, a delivery system should be mapped into one of + * the 4 DVBv3 delivery systems (FE_QPSK, FE_QAM, FE_OFDM or FE_ATSC), + * otherwise, a DVBv3 call will fail. + */ +enum dvbv3_emulation_type { + DVBV3_UNKNOWN, + DVBV3_QPSK, + DVBV3_QAM, + DVBV3_OFDM, + DVBV3_ATSC, +}; + +static enum dvbv3_emulation_type dvbv3_type(u32 delivery_system) +{ + switch (delivery_system) { + case SYS_DVBC_ANNEX_A: + case SYS_DVBC_ANNEX_C: + return DVBV3_QAM; + case SYS_DVBS: + case SYS_DVBS2: + case SYS_TURBO: + case SYS_ISDBS: + case SYS_DSS: + return DVBV3_QPSK; + case SYS_DVBT: + case SYS_DVBT2: + case SYS_ISDBT: + case SYS_DMBTH: + return DVBV3_OFDM; + case SYS_ATSC: + case SYS_DVBC_ANNEX_B: + return DVBV3_ATSC; + case SYS_UNDEFINED: + case SYS_ISDBC: + case SYS_DVBH: + case SYS_DAB: + case SYS_ATSCMH: + default: + /* + * Doesn't know how to emulate those types and/or + * there's no frontend driver from this type yet + * with some emulation code, so, we're not sure yet how + * to handle them, or they're not compatible with a DVBv3 call. + */ + return DVBV3_UNKNOWN; + } +} static void dvb_frontend_add_event(struct dvb_frontend *fe, fe_status_t status) { @@ -149,8 +207,8 @@ static void dvb_frontend_add_event(struct dvb_frontend *fe, fe_status_t status) dprintk ("%s\n", __func__); - if ((status & FE_HAS_LOCK) && fe->ops.get_frontend) - fe->ops.get_frontend(fe, &fepriv->parameters_out); + if ((status & FE_HAS_LOCK) && has_get_frontend(fe)) + dtv_get_frontend(fe, &fepriv->parameters_out); mutex_lock(&events->mtx); @@ -277,12 +335,13 @@ static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wra int ready = 0; int fe_set_err = 0; struct dvb_frontend_private *fepriv = fe->frontend_priv; - int original_inversion = fepriv->parameters_in.inversion; - u32 original_frequency = fepriv->parameters_in.frequency; + struct dtv_frontend_properties *c = &fe->dtv_property_cache, tmp; + int original_inversion = c->inversion; + u32 original_frequency = c->frequency; /* are we using autoinversion? */ autoinversion = ((!(fe->ops.info.caps & FE_CAN_INVERSION_AUTO)) && - (fepriv->parameters_in.inversion == INVERSION_AUTO)); + (c->inversion == INVERSION_AUTO)); /* setup parameters correctly */ while(!ready) { @@ -348,19 +407,20 @@ static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wra fepriv->auto_step, fepriv->auto_sub_step, fepriv->started_auto_step); /* set the frontend itself */ - fepriv->parameters_in.frequency += fepriv->lnb_drift; + c->frequency += fepriv->lnb_drift; if (autoinversion) - fepriv->parameters_in.inversion = fepriv->inversion; + c->inversion = fepriv->inversion; + tmp = *c; if (fe->ops.set_frontend) - fe_set_err = fe->ops.set_frontend(fe, &fepriv->parameters_in); - fepriv->parameters_out = fepriv->parameters_in; + fe_set_err = fe->ops.set_frontend(fe); + *c = tmp; if (fe_set_err < 0) { fepriv->state = FESTATE_ERROR; return fe_set_err; } - fepriv->parameters_in.frequency = original_frequency; - fepriv->parameters_in.inversion = original_inversion; + c->frequency = original_frequency; + c->inversion = original_inversion; fepriv->auto_sub_step++; return 0; @@ -371,6 +431,7 @@ static void dvb_frontend_swzigzag(struct dvb_frontend *fe) fe_status_t s = 0; int retval = 0; struct dvb_frontend_private *fepriv = fe->frontend_priv; + struct dtv_frontend_properties *c = &fe->dtv_property_cache, tmp; /* if we've got no parameters, just keep idling */ if (fepriv->state & FESTATE_IDLE) { @@ -382,10 +443,10 @@ static void dvb_frontend_swzigzag(struct dvb_frontend *fe) /* in SCAN mode, we just set the frontend when asked and leave it alone */ if (fepriv->tune_mode_flags & FE_TUNE_MODE_ONESHOT) { if (fepriv->state & FESTATE_RETUNE) { + tmp = *c; if (fe->ops.set_frontend) - retval = fe->ops.set_frontend(fe, - &fepriv->parameters_in); - fepriv->parameters_out = fepriv->parameters_in; + retval = fe->ops.set_frontend(fe); + *c = tmp; if (retval < 0) fepriv->state = FESTATE_ERROR; else @@ -415,8 +476,8 @@ static void dvb_frontend_swzigzag(struct dvb_frontend *fe) /* if we're tuned, then we have determined the correct inversion */ if ((!(fe->ops.info.caps & FE_CAN_INVERSION_AUTO)) && - (fepriv->parameters_in.inversion == INVERSION_AUTO)) { - fepriv->parameters_in.inversion = fepriv->inversion; + (c->inversion == INVERSION_AUTO)) { + c->inversion = fepriv->inversion; } return; } @@ -507,7 +568,7 @@ static int dvb_frontend_is_exiting(struct dvb_frontend *fe) return 1; if (fepriv->dvbdev->writers == 1) - if (time_after(jiffies, fepriv->release_jiffies + + if (time_after_eq(jiffies, fepriv->release_jiffies + dvb_shutdown_timeout * HZ)) return 1; @@ -540,7 +601,7 @@ static int dvb_frontend_thread(void *data) fe_status_t s; enum dvbfe_algo algo; - struct dvb_frontend_parameters *params; + bool re_tune = false; dprintk("%s\n", __func__); @@ -589,18 +650,15 @@ restart: switch (algo) { case DVBFE_ALGO_HW: dprintk("%s: Frontend ALGO = DVBFE_ALGO_HW\n", __func__); - params = NULL; /* have we been asked to RETUNE ? */ if (fepriv->state & FESTATE_RETUNE) { dprintk("%s: Retune requested, FESTATE_RETUNE\n", __func__); - params = &fepriv->parameters_in; + re_tune = true; fepriv->state = FESTATE_TUNED; } if (fe->ops.tune) - fe->ops.tune(fe, params, fepriv->tune_mode_flags, &fepriv->delay, &s); - if (params) - fepriv->parameters_out = *params; + fe->ops.tune(fe, re_tune, fepriv->tune_mode_flags, &fepriv->delay, &s); if (s != fepriv->status && !(fepriv->tune_mode_flags & FE_TUNE_MODE_ONESHOT)) { dprintk("%s: state changed, adding current state\n", __func__); @@ -624,7 +682,7 @@ restart: */ if (fepriv->algo_status & DVBFE_ALGO_SEARCH_AGAIN) { if (fe->ops.search) { - fepriv->algo_status = fe->ops.search(fe, &fepriv->parameters_in); + fepriv->algo_status = fe->ops.search(fe); /* We did do a search as was requested, the flags are * now unset as well and has the flags wrt to search. */ @@ -633,14 +691,10 @@ restart: } } /* Track the carrier if the search was successful */ - if (fepriv->algo_status == DVBFE_ALGO_SEARCH_SUCCESS) { - if (fe->ops.track) - fe->ops.track(fe, &fepriv->parameters_in); - } else { + if (fepriv->algo_status != DVBFE_ALGO_SEARCH_SUCCESS) { fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN; fepriv->delay = HZ / 2; } - fepriv->parameters_out = fepriv->parameters_in; fe->ops.read_status(fe, &s); if (s != fepriv->status) { dvb_frontend_add_event(fe, s); /* update event list */ @@ -807,52 +861,40 @@ static void dvb_frontend_get_frequency_limits(struct dvb_frontend *fe, fe->dvb->num,fe->id); } -static int dvb_frontend_check_parameters(struct dvb_frontend *fe, - struct dvb_frontend_parameters *parms) +static int dvb_frontend_check_parameters(struct dvb_frontend *fe) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; u32 freq_min; u32 freq_max; /* range check: frequency */ dvb_frontend_get_frequency_limits(fe, &freq_min, &freq_max); - if ((freq_min && parms->frequency < freq_min) || - (freq_max && parms->frequency > freq_max)) { + if ((freq_min && c->frequency < freq_min) || + (freq_max && c->frequency > freq_max)) { printk(KERN_WARNING "DVB: adapter %i frontend %i frequency %u out of range (%u..%u)\n", - fe->dvb->num, fe->id, parms->frequency, freq_min, freq_max); + fe->dvb->num, fe->id, c->frequency, freq_min, freq_max); return -EINVAL; } /* range check: symbol rate */ - if (fe->ops.info.type == FE_QPSK) { - if ((fe->ops.info.symbol_rate_min && - parms->u.qpsk.symbol_rate < fe->ops.info.symbol_rate_min) || - (fe->ops.info.symbol_rate_max && - parms->u.qpsk.symbol_rate > fe->ops.info.symbol_rate_max)) { - printk(KERN_WARNING "DVB: adapter %i frontend %i symbol rate %u out of range (%u..%u)\n", - fe->dvb->num, fe->id, parms->u.qpsk.symbol_rate, - fe->ops.info.symbol_rate_min, fe->ops.info.symbol_rate_max); - return -EINVAL; - } - - } else if (fe->ops.info.type == FE_QAM) { + switch (c->delivery_system) { + case SYS_DVBS: + case SYS_DVBS2: + case SYS_TURBO: + case SYS_DVBC_ANNEX_A: + case SYS_DVBC_ANNEX_C: if ((fe->ops.info.symbol_rate_min && - parms->u.qam.symbol_rate < fe->ops.info.symbol_rate_min) || + c->symbol_rate < fe->ops.info.symbol_rate_min) || (fe->ops.info.symbol_rate_max && - parms->u.qam.symbol_rate > fe->ops.info.symbol_rate_max)) { + c->symbol_rate > fe->ops.info.symbol_rate_max)) { printk(KERN_WARNING "DVB: adapter %i frontend %i symbol rate %u out of range (%u..%u)\n", - fe->dvb->num, fe->id, parms->u.qam.symbol_rate, - fe->ops.info.symbol_rate_min, fe->ops.info.symbol_rate_max); + fe->dvb->num, fe->id, c->symbol_rate, + fe->ops.info.symbol_rate_min, + fe->ops.info.symbol_rate_max); return -EINVAL; } - } - - /* check for supported modulation */ - if (fe->ops.info.type == FE_QAM && - (parms->u.qam.modulation > QAM_AUTO || - !((1 << (parms->u.qam.modulation + 10)) & fe->ops.info.caps))) { - printk(KERN_WARNING "DVB: adapter %i frontend %i modulation %u not supported\n", - fe->dvb->num, fe->id, parms->u.qam.modulation); - return -EINVAL; + default: + break; } return 0; @@ -866,28 +908,52 @@ static int dvb_frontend_clear_cache(struct dvb_frontend *fe) memset(c, 0, sizeof(struct dtv_frontend_properties)); c->state = DTV_CLEAR; - c->delivery_system = SYS_UNDEFINED; - c->inversion = INVERSION_AUTO; - c->fec_inner = FEC_AUTO; + + dprintk("%s() Clearing cache for delivery system %d\n", __func__, + c->delivery_system); + c->transmission_mode = TRANSMISSION_MODE_AUTO; - c->bandwidth_hz = BANDWIDTH_AUTO; + c->bandwidth_hz = 0; /* AUTO */ c->guard_interval = GUARD_INTERVAL_AUTO; c->hierarchy = HIERARCHY_AUTO; - c->symbol_rate = QAM_AUTO; + c->symbol_rate = 0; c->code_rate_HP = FEC_AUTO; c->code_rate_LP = FEC_AUTO; - - c->isdbt_partial_reception = -1; - c->isdbt_sb_mode = -1; - c->isdbt_sb_subchannel = -1; - c->isdbt_sb_segment_idx = -1; - c->isdbt_sb_segment_count = -1; - c->isdbt_layer_enabled = 0x7; + c->fec_inner = FEC_AUTO; + c->rolloff = ROLLOFF_AUTO; + c->voltage = SEC_VOLTAGE_OFF; + c->sectone = SEC_TONE_OFF; + c->pilot = PILOT_AUTO; + + c->isdbt_partial_reception = 0; + c->isdbt_sb_mode = 0; + c->isdbt_sb_subchannel = 0; + c->isdbt_sb_segment_idx = 0; + c->isdbt_sb_segment_count = 0; + c->isdbt_layer_enabled = 0; for (i = 0; i < 3; i++) { c->layer[i].fec = FEC_AUTO; c->layer[i].modulation = QAM_AUTO; - c->layer[i].interleaving = -1; - c->layer[i].segment_count = -1; + c->layer[i].interleaving = 0; + c->layer[i].segment_count = 0; + } + + c->isdbs_ts_id = 0; + c->dvbt2_plp_id = 0; + + switch (c->delivery_system) { + case SYS_DVBS: + case SYS_DVBS2: + case SYS_TURBO: + c->modulation = QPSK; /* implied for DVB-S in legacy API */ + c->rolloff = ROLLOFF_35;/* implied for DVB-S */ + break; + case SYS_ATSC: + c->modulation = VSB_8; + break; + default: + c->modulation = QAM_AUTO; + break; } return 0; @@ -973,6 +1039,8 @@ static struct dtv_cmds_h dtv_cmds[DTV_MAX_COMMAND + 1] = { _DTV_CMD(DTV_GUARD_INTERVAL, 0, 0), _DTV_CMD(DTV_TRANSMISSION_MODE, 0, 0), _DTV_CMD(DTV_HIERARCHY, 0, 0), + + _DTV_CMD(DTV_ENUM_DELSYS, 0, 0), }; static void dtv_property_dump(struct dtv_property *tvp) @@ -1006,70 +1074,54 @@ static void dtv_property_dump(struct dtv_property *tvp) dprintk("%s() tvp.u.data = 0x%08x\n", __func__, tvp->u.data); } -static int is_legacy_delivery_system(fe_delivery_system_t s) -{ - if((s == SYS_UNDEFINED) || (s == SYS_DVBC_ANNEX_AC) || - (s == SYS_DVBC_ANNEX_B) || (s == SYS_DVBT) || (s == SYS_DVBS) || - (s == SYS_ATSC)) - return 1; - - return 0; -} - -/* Initialize the cache with some default values derived from the - * legacy frontend_info structure. - */ -static void dtv_property_cache_init(struct dvb_frontend *fe, - struct dtv_frontend_properties *c) -{ - switch (fe->ops.info.type) { - case FE_QPSK: - c->modulation = QPSK; /* implied for DVB-S in legacy API */ - c->rolloff = ROLLOFF_35;/* implied for DVB-S */ - c->delivery_system = SYS_DVBS; - break; - case FE_QAM: - c->delivery_system = SYS_DVBC_ANNEX_AC; - break; - case FE_OFDM: - c->delivery_system = SYS_DVBT; - break; - case FE_ATSC: - break; - } -} - /* Synchronise the legacy tuning parameters into the cache, so that demodulator * drivers can use a single set_frontend tuning function, regardless of whether * it's being used for the legacy or new API, reducing code and complexity. */ -static void dtv_property_cache_sync(struct dvb_frontend *fe, - struct dtv_frontend_properties *c, - const struct dvb_frontend_parameters *p) +static int dtv_property_cache_sync(struct dvb_frontend *fe, + struct dtv_frontend_properties *c, + const struct dvb_frontend_parameters *p) { c->frequency = p->frequency; c->inversion = p->inversion; - switch (fe->ops.info.type) { - case FE_QPSK: + switch (dvbv3_type(c->delivery_system)) { + case DVBV3_QPSK: + dprintk("%s() Preparing QPSK req\n", __func__); c->symbol_rate = p->u.qpsk.symbol_rate; c->fec_inner = p->u.qpsk.fec_inner; break; - case FE_QAM: + case DVBV3_QAM: + dprintk("%s() Preparing QAM req\n", __func__); c->symbol_rate = p->u.qam.symbol_rate; c->fec_inner = p->u.qam.fec_inner; c->modulation = p->u.qam.modulation; break; - case FE_OFDM: - if (p->u.ofdm.bandwidth == BANDWIDTH_6_MHZ) - c->bandwidth_hz = 6000000; - else if (p->u.ofdm.bandwidth == BANDWIDTH_7_MHZ) - c->bandwidth_hz = 7000000; - else if (p->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) + case DVBV3_OFDM: + dprintk("%s() Preparing OFDM req\n", __func__); + switch (p->u.ofdm.bandwidth) { + case BANDWIDTH_10_MHZ: + c->bandwidth_hz = 10000000; + break; + case BANDWIDTH_8_MHZ: c->bandwidth_hz = 8000000; - else - /* Including BANDWIDTH_AUTO */ + break; + case BANDWIDTH_7_MHZ: + c->bandwidth_hz = 7000000; + break; + case BANDWIDTH_6_MHZ: + c->bandwidth_hz = 6000000; + break; + case BANDWIDTH_5_MHZ: + c->bandwidth_hz = 5000000; + break; + case BANDWIDTH_1_712_MHZ: + c->bandwidth_hz = 1712000; + break; + case BANDWIDTH_AUTO: c->bandwidth_hz = 0; + } + c->code_rate_HP = p->u.ofdm.code_rate_HP; c->code_rate_LP = p->u.ofdm.code_rate_LP; c->modulation = p->u.ofdm.constellation; @@ -1077,50 +1129,78 @@ static void dtv_property_cache_sync(struct dvb_frontend *fe, c->guard_interval = p->u.ofdm.guard_interval; c->hierarchy = p->u.ofdm.hierarchy_information; break; - case FE_ATSC: + case DVBV3_ATSC: + dprintk("%s() Preparing ATSC req\n", __func__); c->modulation = p->u.vsb.modulation; if ((c->modulation == VSB_8) || (c->modulation == VSB_16)) c->delivery_system = SYS_ATSC; else c->delivery_system = SYS_DVBC_ANNEX_B; break; + case DVBV3_UNKNOWN: + printk(KERN_ERR + "%s: doesn't know how to handle a DVBv3 call to delivery system %i\n", + __func__, c->delivery_system); + return -EINVAL; } + + return 0; } /* Ensure the cached values are set correctly in the frontend * legacy tuning structures, for the advanced tuning API. */ -static void dtv_property_legacy_params_sync(struct dvb_frontend *fe) +static int dtv_property_legacy_params_sync(struct dvb_frontend *fe, + struct dvb_frontend_parameters *p) { const struct dtv_frontend_properties *c = &fe->dtv_property_cache; - struct dvb_frontend_private *fepriv = fe->frontend_priv; - struct dvb_frontend_parameters *p = &fepriv->parameters_in; p->frequency = c->frequency; p->inversion = c->inversion; - switch (fe->ops.info.type) { - case FE_QPSK: + switch (dvbv3_type(c->delivery_system)) { + case DVBV3_UNKNOWN: + printk(KERN_ERR + "%s: doesn't know how to handle a DVBv3 call to delivery system %i\n", + __func__, c->delivery_system); + return -EINVAL; + case DVBV3_QPSK: dprintk("%s() Preparing QPSK req\n", __func__); p->u.qpsk.symbol_rate = c->symbol_rate; p->u.qpsk.fec_inner = c->fec_inner; break; - case FE_QAM: + case DVBV3_QAM: dprintk("%s() Preparing QAM req\n", __func__); p->u.qam.symbol_rate = c->symbol_rate; p->u.qam.fec_inner = c->fec_inner; p->u.qam.modulation = c->modulation; break; - case FE_OFDM: + case DVBV3_OFDM: dprintk("%s() Preparing OFDM req\n", __func__); - if (c->bandwidth_hz == 6000000) - p->u.ofdm.bandwidth = BANDWIDTH_6_MHZ; - else if (c->bandwidth_hz == 7000000) - p->u.ofdm.bandwidth = BANDWIDTH_7_MHZ; - else if (c->bandwidth_hz == 8000000) + + switch (c->bandwidth_hz) { + case 10000000: + p->u.ofdm.bandwidth = BANDWIDTH_10_MHZ; + break; + case 8000000: p->u.ofdm.bandwidth = BANDWIDTH_8_MHZ; - else + break; + case 7000000: + p->u.ofdm.bandwidth = BANDWIDTH_7_MHZ; + break; + case 6000000: + p->u.ofdm.bandwidth = BANDWIDTH_6_MHZ; + break; + case 5000000: + p->u.ofdm.bandwidth = BANDWIDTH_5_MHZ; + break; + case 1712000: + p->u.ofdm.bandwidth = BANDWIDTH_1_712_MHZ; + break; + case 0: + default: p->u.ofdm.bandwidth = BANDWIDTH_AUTO; + } p->u.ofdm.code_rate_HP = c->code_rate_HP; p->u.ofdm.code_rate_LP = c->code_rate_LP; p->u.ofdm.constellation = c->modulation; @@ -1128,78 +1208,40 @@ static void dtv_property_legacy_params_sync(struct dvb_frontend *fe) p->u.ofdm.guard_interval = c->guard_interval; p->u.ofdm.hierarchy_information = c->hierarchy; break; - case FE_ATSC: + case DVBV3_ATSC: dprintk("%s() Preparing VSB req\n", __func__); p->u.vsb.modulation = c->modulation; break; } + return 0; } -/* Ensure the cached values are set correctly in the frontend - * legacy tuning structures, for the legacy tuning API. +/** + * dtv_get_frontend - calls a callback for retrieving DTV parameters + * @fe: struct dvb_frontend pointer + * @c: struct dtv_frontend_properties pointer (DVBv5 cache) + * @p_out struct dvb_frontend_parameters pointer (DVBv3 FE struct) + * + * This routine calls either the DVBv3 or DVBv5 get_frontend call. + * If c is not null, it will update the DVBv5 cache struct pointed by it. + * If p_out is not null, it will update the DVBv3 params pointed by it. */ -static void dtv_property_adv_params_sync(struct dvb_frontend *fe) +static int dtv_get_frontend(struct dvb_frontend *fe, + struct dvb_frontend_parameters *p_out) { - const struct dtv_frontend_properties *c = &fe->dtv_property_cache; - struct dvb_frontend_private *fepriv = fe->frontend_priv; - struct dvb_frontend_parameters *p = &fepriv->parameters_in; - - p->frequency = c->frequency; - p->inversion = c->inversion; - - if (c->delivery_system == SYS_DSS || - c->delivery_system == SYS_DVBS || - c->delivery_system == SYS_DVBS2 || - c->delivery_system == SYS_ISDBS || - c->delivery_system == SYS_TURBO) { - p->u.qpsk.symbol_rate = c->symbol_rate; - p->u.qpsk.fec_inner = c->fec_inner; - } + int r; - /* Fake out a generic DVB-T request so we pass validation in the ioctl */ - if ((c->delivery_system == SYS_ISDBT) || - (c->delivery_system == SYS_DVBT2)) { - p->u.ofdm.constellation = QAM_AUTO; - p->u.ofdm.code_rate_HP = FEC_AUTO; - p->u.ofdm.code_rate_LP = FEC_AUTO; - p->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO; - p->u.ofdm.guard_interval = GUARD_INTERVAL_AUTO; - p->u.ofdm.hierarchy_information = HIERARCHY_AUTO; - if (c->bandwidth_hz == 8000000) - p->u.ofdm.bandwidth = BANDWIDTH_8_MHZ; - else if (c->bandwidth_hz == 7000000) - p->u.ofdm.bandwidth = BANDWIDTH_7_MHZ; - else if (c->bandwidth_hz == 6000000) - p->u.ofdm.bandwidth = BANDWIDTH_6_MHZ; - else - p->u.ofdm.bandwidth = BANDWIDTH_AUTO; + if (fe->ops.get_frontend) { + r = fe->ops.get_frontend(fe); + if (unlikely(r < 0)) + return r; + if (p_out) + dtv_property_legacy_params_sync(fe, p_out); + return 0; } -} - -static void dtv_property_cache_submit(struct dvb_frontend *fe) -{ - const struct dtv_frontend_properties *c = &fe->dtv_property_cache; - /* For legacy delivery systems we don't need the delivery_system to - * be specified, but we populate the older structures from the cache - * so we can call set_frontend on older drivers. - */ - if(is_legacy_delivery_system(c->delivery_system)) { - - dprintk("%s() legacy, modulation = %d\n", __func__, c->modulation); - dtv_property_legacy_params_sync(fe); - - } else { - dprintk("%s() adv, modulation = %d\n", __func__, c->modulation); - - /* For advanced delivery systems / modulation types ... - * we seed the lecacy dvb_frontend_parameters structure - * so that the sanity checking code later in the IOCTL processing - * can validate our basic frequency ranges, symbolrates, modulation - * etc. - */ - dtv_property_adv_params_sync(fe); - } + /* As everything is in cache, get_frontend fops are always supported */ + return 0; } static int dvb_frontend_ioctl_legacy(struct file *file, @@ -1208,25 +1250,21 @@ static int dvb_frontend_ioctl_properties(struct file *file, unsigned int cmd, void *parg); static int dtv_property_process_get(struct dvb_frontend *fe, + const struct dtv_frontend_properties *c, struct dtv_property *tvp, struct file *file) { - const struct dtv_frontend_properties *c = &fe->dtv_property_cache; - struct dvb_frontend_private *fepriv = fe->frontend_priv; - struct dtv_frontend_properties cdetected; - int r; - - /* - * If the driver implements a get_frontend function, then convert - * detected parameters to S2API properties. - */ - if (fe->ops.get_frontend) { - cdetected = *c; - dtv_property_cache_sync(fe, &cdetected, &fepriv->parameters_out); - c = &cdetected; - } + int r, ncaps; switch(tvp->cmd) { + case DTV_ENUM_DELSYS: + ncaps = 0; + while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) { + tvp->u.buffer.data[ncaps] = fe->ops.delsys[ncaps]; + ncaps++; + } + tvp->u.buffer.len = ncaps; + break; case DTV_FREQUENCY: tvp->u.data = c->frequency; break; @@ -1356,14 +1394,159 @@ static int dtv_property_process_get(struct dvb_frontend *fe, return 0; } +static int dtv_set_frontend(struct dvb_frontend *fe); + +static bool is_dvbv3_delsys(u32 delsys) +{ + bool status; + + status = (delsys == SYS_DVBT) || (delsys == SYS_DVBC_ANNEX_A) || + (delsys == SYS_DVBS) || (delsys == SYS_ATSC); + + return status; +} + +static int set_delivery_system(struct dvb_frontend *fe, u32 desired_system) +{ + int ncaps, i; + u32 delsys = SYS_UNDEFINED; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + enum dvbv3_emulation_type type; + + if (desired_system == SYS_UNDEFINED) { + /* + * A DVBv3 call doesn't know what's the desired system. + * Also, DVBv3 applications don't know that ops.info->type + * could be changed, and they simply dies when it doesn't + * match. + * So, don't change the current delivery system, as it + * may be trying to do the wrong thing, like setting an + * ISDB-T frontend as DVB-T. Instead, find the closest + * DVBv3 system that matches the delivery system. + */ + if (is_dvbv3_delsys(c->delivery_system)) { + dprintk("%s() Using delivery system to %d\n", + __func__, c->delivery_system); + return 0; + } + type = dvbv3_type(c->delivery_system); + switch (type) { + case DVBV3_QPSK: + desired_system = SYS_DVBS; + break; + case DVBV3_QAM: + desired_system = SYS_DVBC_ANNEX_A; + break; + case DVBV3_ATSC: + desired_system = SYS_ATSC; + break; + case DVBV3_OFDM: + desired_system = SYS_DVBT; + break; + default: + dprintk("%s(): This frontend doesn't support DVBv3 calls\n", + __func__); + return -EINVAL; + } + } else { + /* + * This is a DVBv5 call. So, it likely knows the supported + * delivery systems. + */ + + /* Check if the desired delivery system is supported */ + ncaps = 0; + while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) { + if (fe->ops.delsys[ncaps] == desired_system) { + c->delivery_system = desired_system; + dprintk("%s() Changing delivery system to %d\n", + __func__, desired_system); + return 0; + } + ncaps++; + } + type = dvbv3_type(desired_system); + + /* + * The delivery system is not supported. See if it can be + * emulated. + * The emulation only works if the desired system is one of the + * DVBv3 delivery systems + */ + if (!is_dvbv3_delsys(desired_system)) { + dprintk("%s() can't use a DVBv3 FE_SET_FRONTEND call on this frontend\n", + __func__); + return -EINVAL; + } + + /* + * Get the last non-DVBv3 delivery system that has the same type + * of the desired system + */ + ncaps = 0; + while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) { + if ((dvbv3_type(fe->ops.delsys[ncaps]) == type) && + !is_dvbv3_delsys(fe->ops.delsys[ncaps])) + delsys = fe->ops.delsys[ncaps]; + ncaps++; + } + /* There's nothing compatible with the desired delivery system */ + if (delsys == SYS_UNDEFINED) { + dprintk("%s() Incompatible DVBv3 FE_SET_FRONTEND call for this frontend\n", + __func__); + return -EINVAL; + } + c->delivery_system = delsys; + } + + /* + * The DVBv3 or DVBv5 call is requesting a different system. So, + * emulation is needed. + * + * Emulate newer delivery systems like ISDBT, DVBT and DMBTH + * for older DVBv5 applications. The emulation will try to use + * the auto mode for most things, and will assume that the desired + * delivery system is the last one at the ops.delsys[] array + */ + dprintk("%s() Using delivery system %d emulated as if it were a %d\n", + __func__, delsys, desired_system); + + /* + * For now, handles ISDB-T calls. More code may be needed here for the + * other emulated stuff + */ + if (type == DVBV3_OFDM) { + if (c->delivery_system == SYS_ISDBT) { + dprintk("%s() Using defaults for SYS_ISDBT\n", + __func__); + if (!c->bandwidth_hz) + c->bandwidth_hz = 6000000; + + c->isdbt_partial_reception = 0; + c->isdbt_sb_mode = 0; + c->isdbt_sb_subchannel = 0; + c->isdbt_sb_segment_idx = 0; + c->isdbt_sb_segment_count = 0; + c->isdbt_layer_enabled = 0; + for (i = 0; i < 3; i++) { + c->layer[i].fec = FEC_AUTO; + c->layer[i].modulation = QAM_AUTO; + c->layer[i].interleaving = 0; + c->layer[i].segment_count = 0; + } + } + } + dprintk("change delivery system on cache to %d\n", c->delivery_system); + + return 0; +} + static int dtv_property_process_set(struct dvb_frontend *fe, struct dtv_property *tvp, struct file *file) { int r = 0; struct dtv_frontend_properties *c = &fe->dtv_property_cache; - struct dvb_frontend_private *fepriv = fe->frontend_priv; - dtv_property_dump(tvp); /* Allow the frontend to validate incoming properties */ if (fe->ops.set_property) { @@ -1374,11 +1557,11 @@ static int dtv_property_process_set(struct dvb_frontend *fe, switch(tvp->cmd) { case DTV_CLEAR: - /* Reset a cache of data specific to the frontend here. This does + /* + * Reset a cache of data specific to the frontend here. This does * not effect hardware. */ dvb_frontend_clear_cache(fe); - dprintk("%s() Flushing property cache\n", __func__); break; case DTV_TUNE: /* interpret the cache of data, build either a traditional frontend @@ -1387,10 +1570,8 @@ static int dtv_property_process_set(struct dvb_frontend *fe, */ c->state = tvp->cmd; dprintk("%s() Finalised property cache\n", __func__); - dtv_property_cache_submit(fe); - r = dvb_frontend_ioctl_legacy(file, FE_SET_FRONTEND, - &fepriv->parameters_in); + r = dtv_set_frontend(fe); break; case DTV_FREQUENCY: c->frequency = tvp->u.data; @@ -1417,7 +1598,7 @@ static int dtv_property_process_set(struct dvb_frontend *fe, c->rolloff = tvp->u.data; break; case DTV_DELIVERY_SYSTEM: - c->delivery_system = tvp->u.data; + r = set_delivery_system(fe, tvp->u.data); break; case DTV_VOLTAGE: c->voltage = tvp->u.data; @@ -1594,7 +1775,6 @@ static int dvb_frontend_ioctl_properties(struct file *file, } else if(cmd == FE_GET_PROPERTY) { - tvps = (struct dtv_properties __user *)parg; dprintk("%s() properties.num = %d\n", __func__, tvps->num); @@ -1616,8 +1796,13 @@ static int dvb_frontend_ioctl_properties(struct file *file, goto out; } + /* + * Fills the cache out struct with the cache contents, plus + * the data retrieved from get_frontend. + */ + dtv_get_frontend(fe, NULL); for (i = 0; i < tvps->num; i++) { - err = dtv_property_process_get(fe, tvp + i, file); + err = dtv_property_process_get(fe, c, tvp + i, file); if (err < 0) goto out; (tvp + i)->result = err; @@ -1636,12 +1821,121 @@ out: return err; } +static int dtv_set_frontend(struct dvb_frontend *fe) +{ + struct dvb_frontend_private *fepriv = fe->frontend_priv; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + struct dvb_frontend_tune_settings fetunesettings; + u32 rolloff = 0; + + if (dvb_frontend_check_parameters(fe) < 0) + return -EINVAL; + + /* + * Be sure that the bandwidth will be filled for all + * non-satellite systems, as tuners need to know what + * low pass/Nyquist half filter should be applied, in + * order to avoid inter-channel noise. + * + * ISDB-T and DVB-T/T2 already sets bandwidth. + * ATSC and DVB-C don't set, so, the core should fill it. + * + * On DVB-C Annex A and C, the bandwidth is a function of + * the roll-off and symbol rate. Annex B defines different + * roll-off factors depending on the modulation. Fortunately, + * Annex B is only used with 6MHz, so there's no need to + * calculate it. + * + * While not officially supported, a side effect of handling it at + * the cache level is that a program could retrieve the bandwidth + * via DTV_BANDWIDTH_HZ, which may be useful for test programs. + */ + switch (c->delivery_system) { + case SYS_ATSC: + case SYS_DVBC_ANNEX_B: + c->bandwidth_hz = 6000000; + break; + case SYS_DVBC_ANNEX_A: + rolloff = 115; + break; + case SYS_DVBC_ANNEX_C: + rolloff = 113; + break; + default: + break; + } + if (rolloff) + c->bandwidth_hz = (c->symbol_rate * rolloff) / 100; + + /* force auto frequency inversion if requested */ + if (dvb_force_auto_inversion) + c->inversion = INVERSION_AUTO; + + /* + * without hierarchical coding code_rate_LP is irrelevant, + * so we tolerate the otherwise invalid FEC_NONE setting + */ + if (c->hierarchy == HIERARCHY_NONE && c->code_rate_LP == FEC_NONE) + c->code_rate_LP = FEC_AUTO; + + /* get frontend-specific tuning settings */ + memset(&fetunesettings, 0, sizeof(struct dvb_frontend_tune_settings)); + if (fe->ops.get_tune_settings && (fe->ops.get_tune_settings(fe, &fetunesettings) == 0)) { + fepriv->min_delay = (fetunesettings.min_delay_ms * HZ) / 1000; + fepriv->max_drift = fetunesettings.max_drift; + fepriv->step_size = fetunesettings.step_size; + } else { + /* default values */ + switch (c->delivery_system) { + case SYS_DVBC_ANNEX_A: + case SYS_DVBC_ANNEX_C: + fepriv->min_delay = HZ / 20; + fepriv->step_size = c->symbol_rate / 16000; + fepriv->max_drift = c->symbol_rate / 2000; + break; + case SYS_DVBT: + case SYS_DVBT2: + case SYS_ISDBT: + case SYS_DMBTH: + fepriv->min_delay = HZ / 20; + fepriv->step_size = fe->ops.info.frequency_stepsize * 2; + fepriv->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1; + break; + default: + /* + * FIXME: This sounds wrong! if freqency_stepsize is + * defined by the frontend, why not use it??? + */ + fepriv->min_delay = HZ / 20; + fepriv->step_size = 0; /* no zigzag */ + fepriv->max_drift = 0; + break; + } + } + if (dvb_override_tune_delay > 0) + fepriv->min_delay = (dvb_override_tune_delay * HZ) / 1000; + + fepriv->state = FESTATE_RETUNE; + + /* Request the search algorithm to search */ + fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN; + + dvb_frontend_clear_events(fe); + dvb_frontend_add_event(fe, 0); + dvb_frontend_wakeup(fe); + fepriv->status = 0; + + return 0; +} + + static int dvb_frontend_ioctl_legacy(struct file *file, unsigned int cmd, void *parg) { struct dvb_device *dvbdev = file->private_data; struct dvb_frontend *fe = dvbdev->priv; struct dvb_frontend_private *fepriv = fe->frontend_priv; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; int cb_err, err = -EOPNOTSUPP; if (fe->dvb->fe_ioctl_override) { @@ -1658,9 +1952,43 @@ static int dvb_frontend_ioctl_legacy(struct file *file, switch (cmd) { case FE_GET_INFO: { struct dvb_frontend_info* info = parg; + memcpy(info, &fe->ops.info, sizeof(struct dvb_frontend_info)); dvb_frontend_get_frequency_limits(fe, &info->frequency_min, &info->frequency_max); + /* + * Associate the 4 delivery systems supported by DVBv3 + * API with their DVBv5 counterpart. For the other standards, + * use the closest type, assuming that it would hopefully + * work with a DVBv3 application. + * It should be noticed that, on multi-frontend devices with + * different types (terrestrial and cable, for example), + * a pure DVBv3 application won't be able to use all delivery + * systems. Yet, changing the DVBv5 cache to the other delivery + * system should be enough for making it work. + */ + switch (dvbv3_type(c->delivery_system)) { + case DVBV3_QPSK: + info->type = FE_QPSK; + break; + case DVBV3_ATSC: + info->type = FE_ATSC; + break; + case DVBV3_QAM: + info->type = FE_QAM; + break; + case DVBV3_OFDM: + info->type = FE_OFDM; + break; + default: + printk(KERN_ERR + "%s: doesn't know how to handle a DVBv3 call to delivery system %i\n", + __func__, c->delivery_system); + fe->ops.info.type = FE_OFDM; + } + dprintk("current delivery system on cache: %d, V3 type: %d\n", + c->delivery_system, fe->ops.info.type); + /* Force the CAN_INVERSION_AUTO bit on. If the frontend doesn't * do it, it is done for it. */ info->caps |= FE_CAN_INVERSION_AUTO; @@ -1819,108 +2147,22 @@ static int dvb_frontend_ioctl_legacy(struct file *file, err = fe->ops.enable_high_lnb_voltage(fe, (long) parg); break; - case FE_SET_FRONTEND: { - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - struct dvb_frontend_tune_settings fetunesettings; - - if (c->state == DTV_TUNE) { - if (dvb_frontend_check_parameters(fe, &fepriv->parameters_in) < 0) { - err = -EINVAL; - break; - } - } else { - if (dvb_frontend_check_parameters(fe, parg) < 0) { - err = -EINVAL; - break; - } - - memcpy (&fepriv->parameters_in, parg, - sizeof (struct dvb_frontend_parameters)); - dtv_property_cache_init(fe, c); - dtv_property_cache_sync(fe, c, &fepriv->parameters_in); - } - - /* - * Initialize output parameters to match the values given by - * the user. FE_SET_FRONTEND triggers an initial frontend event - * with status = 0, which copies output parameters to userspace. - */ - fepriv->parameters_out = fepriv->parameters_in; - - memset(&fetunesettings, 0, sizeof(struct dvb_frontend_tune_settings)); - memcpy(&fetunesettings.parameters, parg, - sizeof (struct dvb_frontend_parameters)); - - /* force auto frequency inversion if requested */ - if (dvb_force_auto_inversion) { - fepriv->parameters_in.inversion = INVERSION_AUTO; - fetunesettings.parameters.inversion = INVERSION_AUTO; - } - if (fe->ops.info.type == FE_OFDM) { - /* without hierarchical coding code_rate_LP is irrelevant, - * so we tolerate the otherwise invalid FEC_NONE setting */ - if (fepriv->parameters_in.u.ofdm.hierarchy_information == HIERARCHY_NONE && - fepriv->parameters_in.u.ofdm.code_rate_LP == FEC_NONE) - fepriv->parameters_in.u.ofdm.code_rate_LP = FEC_AUTO; - } - - /* get frontend-specific tuning settings */ - if (fe->ops.get_tune_settings && (fe->ops.get_tune_settings(fe, &fetunesettings) == 0)) { - fepriv->min_delay = (fetunesettings.min_delay_ms * HZ) / 1000; - fepriv->max_drift = fetunesettings.max_drift; - fepriv->step_size = fetunesettings.step_size; - } else { - /* default values */ - switch(fe->ops.info.type) { - case FE_QPSK: - fepriv->min_delay = HZ/20; - fepriv->step_size = fepriv->parameters_in.u.qpsk.symbol_rate / 16000; - fepriv->max_drift = fepriv->parameters_in.u.qpsk.symbol_rate / 2000; - break; - - case FE_QAM: - fepriv->min_delay = HZ/20; - fepriv->step_size = 0; /* no zigzag */ - fepriv->max_drift = 0; - break; - - case FE_OFDM: - fepriv->min_delay = HZ/20; - fepriv->step_size = fe->ops.info.frequency_stepsize * 2; - fepriv->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1; - break; - case FE_ATSC: - fepriv->min_delay = HZ/20; - fepriv->step_size = 0; - fepriv->max_drift = 0; - break; - } - } - if (dvb_override_tune_delay > 0) - fepriv->min_delay = (dvb_override_tune_delay * HZ) / 1000; - - fepriv->state = FESTATE_RETUNE; - - /* Request the search algorithm to search */ - fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN; + case FE_SET_FRONTEND: + err = set_delivery_system(fe, SYS_UNDEFINED); + if (err) + break; - dvb_frontend_clear_events(fe); - dvb_frontend_add_event(fe, 0); - dvb_frontend_wakeup(fe); - fepriv->status = 0; - err = 0; + err = dtv_property_cache_sync(fe, c, parg); + if (err) + break; + err = dtv_set_frontend(fe); break; - } - case FE_GET_EVENT: err = dvb_frontend_get_event (fe, parg, file->f_flags); break; case FE_GET_FRONTEND: - if (fe->ops.get_frontend) { - err = fe->ops.get_frontend(fe, &fepriv->parameters_out); - memcpy(parg, &fepriv->parameters_out, sizeof(struct dvb_frontend_parameters)); - } + err = dtv_get_frontend(fe, parg); break; case FE_SET_FRONTEND_TUNE_MODE: @@ -2061,12 +2303,15 @@ static int dvb_frontend_release(struct inode *inode, struct file *file) dprintk ("%s\n", __func__); - if ((file->f_flags & O_ACCMODE) != O_RDONLY) + if ((file->f_flags & O_ACCMODE) != O_RDONLY) { fepriv->release_jiffies = jiffies; + mb(); + } ret = dvb_generic_release (inode, file); if (dvbdev->users == -1) { + wake_up(&fepriv->wait_queue); if (fepriv->exit != DVB_FE_NO_EXIT) { fops_put(file->f_op); file->f_op = NULL; @@ -2127,6 +2372,14 @@ int dvb_register_frontend(struct dvb_adapter* dvb, dvb_register_device (fe->dvb, &fepriv->dvbdev, &dvbdev_template, fe, DVB_DEVICE_FRONTEND); + /* + * Initialize the cache to the proper values according with the + * first supported delivery system (ops->delsys[0]) + */ + + fe->dtv_property_cache.delivery_system = fe->ops.delsys[0]; + dvb_frontend_clear_cache(fe); + mutex_unlock(&frontend_mutex); return 0; } diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h index 67bbfa728016..d63a8215fe03 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.h +++ b/drivers/media/dvb/dvb-core/dvb_frontend.h @@ -42,11 +42,16 @@ #include "dvbdev.h" +/* + * Maximum number of Delivery systems per frontend. It + * should be smaller or equal to 32 + */ +#define MAX_DELSYS 8 + struct dvb_frontend_tune_settings { int min_delay_ms; int step_size; int max_drift; - struct dvb_frontend_parameters parameters; }; struct dvb_frontend; @@ -198,11 +203,11 @@ struct dvb_tuner_ops { int (*sleep)(struct dvb_frontend *fe); /** This is for simple PLLs - set all parameters in one go. */ - int (*set_params)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p); + int (*set_params)(struct dvb_frontend *fe); int (*set_analog_params)(struct dvb_frontend *fe, struct analog_parameters *p); /** This is support for demods like the mt352 - fills out the supplied buffer with what to write. */ - int (*calc_regs)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p, u8 *buf, int buf_len); + int (*calc_regs)(struct dvb_frontend *fe, u8 *buf, int buf_len); /** This is to allow setting tuner-specific configs */ int (*set_config)(struct dvb_frontend *fe, void *priv_cfg); @@ -250,10 +255,14 @@ struct analog_demod_ops { int (*set_config)(struct dvb_frontend *fe, void *priv_cfg); }; +struct dtv_frontend_properties; + struct dvb_frontend_ops { struct dvb_frontend_info info; + u8 delsys[MAX_DELSYS]; + void (*release)(struct dvb_frontend* fe); void (*release_sec)(struct dvb_frontend* fe); @@ -264,7 +273,7 @@ struct dvb_frontend_ops { /* if this is set, it overrides the default swzigzag */ int (*tune)(struct dvb_frontend* fe, - struct dvb_frontend_parameters* params, + bool re_tune, unsigned int mode_flags, unsigned int *delay, fe_status_t *status); @@ -272,10 +281,10 @@ struct dvb_frontend_ops { enum dvbfe_algo (*get_frontend_algo)(struct dvb_frontend *fe); /* these two are only used for the swzigzag code */ - int (*set_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); + int (*set_frontend)(struct dvb_frontend *fe); int (*get_tune_settings)(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* settings); - int (*get_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); + int (*get_frontend)(struct dvb_frontend *fe); int (*read_status)(struct dvb_frontend* fe, fe_status_t* status); int (*read_ber)(struct dvb_frontend* fe, u32* ber); @@ -297,8 +306,7 @@ struct dvb_frontend_ops { /* These callbacks are for devices that implement their own * tuning algorithms, rather than a simple swzigzag */ - enum dvbfe_search (*search)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p); - int (*track)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p); + enum dvbfe_search (*search)(struct dvb_frontend *fe); struct dvb_tuner_ops tuner_ops; struct analog_demod_ops analog_ops; @@ -307,6 +315,7 @@ struct dvb_frontend_ops { int (*get_property)(struct dvb_frontend* fe, struct dtv_property* tvp); }; +#ifdef __DVB_CORE__ #define MAX_EVENT 8 struct dvb_fe_events { @@ -317,6 +326,7 @@ struct dvb_fe_events { wait_queue_head_t wait_queue; struct mutex mtx; }; +#endif struct dtv_frontend_properties { @@ -374,6 +384,7 @@ struct dvb_frontend { void *analog_demod_priv; struct dtv_frontend_properties dtv_property_cache; #define DVB_FRONTEND_COMPONENT_TUNER 0 +#define DVB_FRONTEND_COMPONENT_DEMOD 1 int (*callback)(void *adapter_priv, int component, int cmd, int arg); int id; }; diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c index 93d9869e0f15..8766ce8c354d 100644 --- a/drivers/media/dvb/dvb-core/dvb_net.c +++ b/drivers/media/dvb/dvb-core/dvb_net.c @@ -1510,9 +1510,7 @@ int dvb_net_init (struct dvb_adapter *adap, struct dvb_net *dvbnet, for (i=0; i<DVB_NET_DEVICES_MAX; i++) dvbnet->state[i] = 0; - dvb_register_device (adap, &dvbnet->dvbdev, &dvbdev_net, + return dvb_register_device(adap, &dvbnet->dvbdev, &dvbdev_net, dvbnet, DVB_DEVICE_NET); - - return 0; } EXPORT_SYMBOL(dvb_net_init); diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index 58257165761e..9f203c6767a6 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig @@ -311,6 +311,7 @@ config DVB_USB_ANYSEE select DVB_STV0900 if !DVB_FE_CUSTOMISE select DVB_STV6110 if !DVB_FE_CUSTOMISE select DVB_ISL6423 if !DVB_FE_CUSTOMISE + select DVB_CXD2820R if !DVB_FE_CUSTOMISE help Say Y here to support the Anysee E30, Anysee E30 Plus or Anysee E30 C Plus DVB USB2.0 receiver. @@ -340,7 +341,7 @@ config DVB_USB_AF9015 config DVB_USB_CE6230 tristate "Intel CE6230 DVB-T USB2.0 support" - depends on DVB_USB && EXPERIMENTAL + depends on DVB_USB select DVB_ZL10353 select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE help @@ -354,7 +355,7 @@ config DVB_USB_FRIIO config DVB_USB_EC168 tristate "E3C EC168 DVB-T USB2.0 support" - depends on DVB_USB && EXPERIMENTAL + depends on DVB_USB select DVB_EC100 select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE help diff --git a/drivers/media/dvb/dvb-usb/af9005-fe.c b/drivers/media/dvb/dvb-usb/af9005-fe.c index 3263e9749d09..740f3f496f12 100644 --- a/drivers/media/dvb/dvb-usb/af9005-fe.c +++ b/drivers/media/dvb/dvb-usb/af9005-fe.c @@ -303,7 +303,7 @@ static int af9005_get_pre_vit_err_bit_count(struct dvb_frontend *fe, return -EINVAL; } - /* read constellation mode */ + /* read modulation mode */ ret = af9005_read_register_bits(state->d, xd_g_reg_tpsd_const, reg_tpsd_const_pos, reg_tpsd_const_len, @@ -321,7 +321,7 @@ static int af9005_get_pre_vit_err_bit_count(struct dvb_frontend *fe, bits = 6; break; default: - err("invalid constellation mode"); + err("invalid modulation mode"); return -EINVAL; } *pre_bit_count = super_frame_count * 68 * 4 * x * bits; @@ -533,13 +533,13 @@ static int af9005_fe_read_signal_strength(struct dvb_frontend *fe, static int af9005_fe_read_snr(struct dvb_frontend *fe, u16 * snr) { - /* the snr can be derived from the ber and the constellation + /* the snr can be derived from the ber and the modulation but I don't think this kind of complex calculations belong in the driver. I may be wrong.... */ return -ENOSYS; } -static int af9005_fe_program_cfoe(struct dvb_usb_device *d, fe_bandwidth_t bw) +static int af9005_fe_program_cfoe(struct dvb_usb_device *d, u32 bw) { u8 temp0, temp1, temp2, temp3, buf[4]; int ret; @@ -551,7 +551,7 @@ static int af9005_fe_program_cfoe(struct dvb_usb_device *d, fe_bandwidth_t bw) u32 NS_coeff2_8k; switch (bw) { - case BANDWIDTH_6_MHZ: + case 6000000: NS_coeff1_2048Nu = 0x2ADB6DC; NS_coeff1_8191Nu = 0xAB7313; NS_coeff1_8192Nu = 0xAB6DB7; @@ -560,7 +560,7 @@ static int af9005_fe_program_cfoe(struct dvb_usb_device *d, fe_bandwidth_t bw) NS_coeff2_8k = 0x55B6DC; break; - case BANDWIDTH_7_MHZ: + case 7000000: NS_coeff1_2048Nu = 0x3200001; NS_coeff1_8191Nu = 0xC80640; NS_coeff1_8192Nu = 0xC80000; @@ -569,7 +569,7 @@ static int af9005_fe_program_cfoe(struct dvb_usb_device *d, fe_bandwidth_t bw) NS_coeff2_8k = 0x640000; break; - case BANDWIDTH_8_MHZ: + case 8000000: NS_coeff1_2048Nu = 0x3924926; NS_coeff1_8191Nu = 0xE4996E; NS_coeff1_8192Nu = 0xE49249; @@ -773,17 +773,17 @@ static int af9005_fe_program_cfoe(struct dvb_usb_device *d, fe_bandwidth_t bw) } -static int af9005_fe_select_bw(struct dvb_usb_device *d, fe_bandwidth_t bw) +static int af9005_fe_select_bw(struct dvb_usb_device *d, u32 bw) { u8 temp; switch (bw) { - case BANDWIDTH_6_MHZ: + case 6000000: temp = 0; break; - case BANDWIDTH_7_MHZ: + case 7000000: temp = 1; break; - case BANDWIDTH_8_MHZ: + case 8000000: temp = 2; break; default: @@ -930,10 +930,11 @@ static int af9005_fe_init(struct dvb_frontend *fe) /* init other parameters: program cfoe and select bandwidth */ deb_info("program cfoe\n"); - if ((ret = af9005_fe_program_cfoe(state->d, BANDWIDTH_6_MHZ))) + ret = af9005_fe_program_cfoe(state->d, 6000000); + if (ret) return ret; - /* set read-update bit for constellation */ - deb_info("set read-update bit for constellation\n"); + /* set read-update bit for modulation */ + deb_info("set read-update bit for modulation\n"); if ((ret = af9005_write_register_bits(state->d, xd_p_reg_feq_read_update, reg_feq_read_update_pos, @@ -943,8 +944,8 @@ static int af9005_fe_init(struct dvb_frontend *fe) /* sample code has a set MPEG TS code here but sniffing reveals that it doesn't do it */ - /* set read-update bit to 1 for DCA constellation */ - deb_info("set read-update bit 1 for DCA constellation\n"); + /* set read-update bit to 1 for DCA modulation */ + deb_info("set read-update bit 1 for DCA modulation\n"); if ((ret = af9005_write_register_bits(state->d, xd_p_reg_dca_read_update, reg_dca_read_update_pos, @@ -1099,15 +1100,15 @@ static int af9005_ts_bus_ctrl(struct dvb_frontend *fe, int acquire) return 0; } -static int af9005_fe_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *fep) +static int af9005_fe_set_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *fep = &fe->dtv_property_cache; struct af9005_fe_state *state = fe->demodulator_priv; int ret; u8 temp, temp0, temp1, temp2; deb_info("af9005_fe_set_frontend freq %d bw %d\n", fep->frequency, - fep->u.ofdm.bandwidth); + fep->bandwidth_hz); if (fe->ops.tuner_ops.release == NULL) { err("Tuner not attached"); return -ENODEV; @@ -1167,10 +1168,10 @@ static int af9005_fe_set_frontend(struct dvb_frontend *fe, /* select bandwidth */ deb_info("select bandwidth"); - ret = af9005_fe_select_bw(state->d, fep->u.ofdm.bandwidth); + ret = af9005_fe_select_bw(state->d, fep->bandwidth_hz); if (ret) return ret; - ret = af9005_fe_program_cfoe(state->d, fep->u.ofdm.bandwidth); + ret = af9005_fe_program_cfoe(state->d, fep->bandwidth_hz); if (ret) return ret; @@ -1189,7 +1190,7 @@ static int af9005_fe_set_frontend(struct dvb_frontend *fe, return ret; /* set tuner */ deb_info("set tuner\n"); - ret = fe->ops.tuner_ops.set_params(fe, fep); + ret = fe->ops.tuner_ops.set_params(fe); if (ret) return ret; @@ -1225,9 +1226,9 @@ static int af9005_fe_set_frontend(struct dvb_frontend *fe, return 0; } -static int af9005_fe_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *fep) +static int af9005_fe_get_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *fep = &fe->dtv_property_cache; struct af9005_fe_state *state = fe->demodulator_priv; int ret; u8 temp; @@ -1239,19 +1240,19 @@ static int af9005_fe_get_frontend(struct dvb_frontend *fe, &temp); if (ret) return ret; - deb_info("===== fe_get_frontend ==============\n"); + deb_info("===== fe_get_frontend_legacy = =============\n"); deb_info("CONSTELLATION "); switch (temp) { case 0: - fep->u.ofdm.constellation = QPSK; + fep->modulation = QPSK; deb_info("QPSK\n"); break; case 1: - fep->u.ofdm.constellation = QAM_16; + fep->modulation = QAM_16; deb_info("QAM_16\n"); break; case 2: - fep->u.ofdm.constellation = QAM_64; + fep->modulation = QAM_64; deb_info("QAM_64\n"); break; } @@ -1266,19 +1267,19 @@ static int af9005_fe_get_frontend(struct dvb_frontend *fe, deb_info("HIERARCHY "); switch (temp) { case 0: - fep->u.ofdm.hierarchy_information = HIERARCHY_NONE; + fep->hierarchy = HIERARCHY_NONE; deb_info("NONE\n"); break; case 1: - fep->u.ofdm.hierarchy_information = HIERARCHY_1; + fep->hierarchy = HIERARCHY_1; deb_info("1\n"); break; case 2: - fep->u.ofdm.hierarchy_information = HIERARCHY_2; + fep->hierarchy = HIERARCHY_2; deb_info("2\n"); break; case 3: - fep->u.ofdm.hierarchy_information = HIERARCHY_4; + fep->hierarchy = HIERARCHY_4; deb_info("4\n"); break; } @@ -1302,23 +1303,23 @@ static int af9005_fe_get_frontend(struct dvb_frontend *fe, deb_info("CODERATE HP "); switch (temp) { case 0: - fep->u.ofdm.code_rate_HP = FEC_1_2; + fep->code_rate_HP = FEC_1_2; deb_info("FEC_1_2\n"); break; case 1: - fep->u.ofdm.code_rate_HP = FEC_2_3; + fep->code_rate_HP = FEC_2_3; deb_info("FEC_2_3\n"); break; case 2: - fep->u.ofdm.code_rate_HP = FEC_3_4; + fep->code_rate_HP = FEC_3_4; deb_info("FEC_3_4\n"); break; case 3: - fep->u.ofdm.code_rate_HP = FEC_5_6; + fep->code_rate_HP = FEC_5_6; deb_info("FEC_5_6\n"); break; case 4: - fep->u.ofdm.code_rate_HP = FEC_7_8; + fep->code_rate_HP = FEC_7_8; deb_info("FEC_7_8\n"); break; } @@ -1333,23 +1334,23 @@ static int af9005_fe_get_frontend(struct dvb_frontend *fe, deb_info("CODERATE LP "); switch (temp) { case 0: - fep->u.ofdm.code_rate_LP = FEC_1_2; + fep->code_rate_LP = FEC_1_2; deb_info("FEC_1_2\n"); break; case 1: - fep->u.ofdm.code_rate_LP = FEC_2_3; + fep->code_rate_LP = FEC_2_3; deb_info("FEC_2_3\n"); break; case 2: - fep->u.ofdm.code_rate_LP = FEC_3_4; + fep->code_rate_LP = FEC_3_4; deb_info("FEC_3_4\n"); break; case 3: - fep->u.ofdm.code_rate_LP = FEC_5_6; + fep->code_rate_LP = FEC_5_6; deb_info("FEC_5_6\n"); break; case 4: - fep->u.ofdm.code_rate_LP = FEC_7_8; + fep->code_rate_LP = FEC_7_8; deb_info("FEC_7_8\n"); break; } @@ -1363,19 +1364,19 @@ static int af9005_fe_get_frontend(struct dvb_frontend *fe, deb_info("GUARD INTERVAL "); switch (temp) { case 0: - fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; + fep->guard_interval = GUARD_INTERVAL_1_32; deb_info("1_32\n"); break; case 1: - fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; + fep->guard_interval = GUARD_INTERVAL_1_16; deb_info("1_16\n"); break; case 2: - fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; + fep->guard_interval = GUARD_INTERVAL_1_8; deb_info("1_8\n"); break; case 3: - fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; + fep->guard_interval = GUARD_INTERVAL_1_4; deb_info("1_4\n"); break; } @@ -1390,11 +1391,11 @@ static int af9005_fe_get_frontend(struct dvb_frontend *fe, deb_info("TRANSMISSION MODE "); switch (temp) { case 0: - fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; + fep->transmission_mode = TRANSMISSION_MODE_2K; deb_info("2K\n"); break; case 1: - fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; + fep->transmission_mode = TRANSMISSION_MODE_8K; deb_info("8K\n"); break; } @@ -1406,15 +1407,15 @@ static int af9005_fe_get_frontend(struct dvb_frontend *fe, deb_info("BANDWIDTH "); switch (temp) { case 0: - fep->u.ofdm.bandwidth = BANDWIDTH_6_MHZ; + fep->bandwidth_hz = 6000000; deb_info("6\n"); break; case 1: - fep->u.ofdm.bandwidth = BANDWIDTH_7_MHZ; + fep->bandwidth_hz = 7000000; deb_info("7\n"); break; case 2: - fep->u.ofdm.bandwidth = BANDWIDTH_8_MHZ; + fep->bandwidth_hz = 8000000; deb_info("8\n"); break; } @@ -1454,9 +1455,9 @@ struct dvb_frontend *af9005_fe_attach(struct dvb_usb_device *d) } static struct dvb_frontend_ops af9005_fe_ops = { + .delsys = { SYS_DVBT }, .info = { .name = "AF9005 USB DVB-T", - .type = FE_OFDM, .frequency_min = 44250000, .frequency_max = 867250000, .frequency_stepsize = 250000, diff --git a/drivers/media/dvb/dvb-usb/af9005.c b/drivers/media/dvb/dvb-usb/af9005.c index bd51a764351b..af176b6ce738 100644 --- a/drivers/media/dvb/dvb-usb/af9005.c +++ b/drivers/media/dvb/dvb-usb/af9005.c @@ -30,7 +30,7 @@ MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4,reg=8,i2c=16,fw=32 (or-able))." DVB_USB_DEBUG_STATUS); /* enable obnoxious led */ -int dvb_usb_af9005_led = 1; +bool dvb_usb_af9005_led = 1; module_param_named(led, dvb_usb_af9005_led, bool, 0644); MODULE_PARM_DESC(led, "enable led (default: 1)."); @@ -977,11 +977,20 @@ static int af9005_usb_probe(struct usb_interface *intf, THIS_MODULE, NULL, adapter_nr); } +enum af9005_usb_table_entry { + AFATECH_AF9005, + TERRATEC_AF9005, + ANSONIC_AF9005, +}; + static struct usb_device_id af9005_usb_table[] = { - {USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9005)}, - {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_USB_XE)}, - {USB_DEVICE(USB_VID_ANSONIC, USB_PID_ANSONIC_DVBT_USB)}, - {0}, + [AFATECH_AF9005] = {USB_DEVICE(USB_VID_AFATECH, + USB_PID_AFATECH_AF9005)}, + [TERRATEC_AF9005] = {USB_DEVICE(USB_VID_TERRATEC, + USB_PID_TERRATEC_CINERGY_T_USB_XE)}, + [ANSONIC_AF9005] = {USB_DEVICE(USB_VID_ANSONIC, + USB_PID_ANSONIC_DVBT_USB)}, + { } }; MODULE_DEVICE_TABLE(usb, af9005_usb_table); @@ -1041,15 +1050,15 @@ static struct dvb_usb_device_properties af9005_properties = { .num_device_descs = 3, .devices = { {.name = "Afatech DVB-T USB1.1 stick", - .cold_ids = {&af9005_usb_table[0], NULL}, + .cold_ids = {&af9005_usb_table[AFATECH_AF9005], NULL}, .warm_ids = {NULL}, }, {.name = "TerraTec Cinergy T USB XE", - .cold_ids = {&af9005_usb_table[1], NULL}, + .cold_ids = {&af9005_usb_table[TERRATEC_AF9005], NULL}, .warm_ids = {NULL}, }, {.name = "Ansonic DVB-T USB1.1 stick", - .cold_ids = {&af9005_usb_table[2], NULL}, + .cold_ids = {&af9005_usb_table[ANSONIC_AF9005], NULL}, .warm_ids = {NULL}, }, {NULL}, diff --git a/drivers/media/dvb/dvb-usb/af9005.h b/drivers/media/dvb/dvb-usb/af9005.h index c71c77bd7f4b..6a2bf3de8456 100644 --- a/drivers/media/dvb/dvb-usb/af9005.h +++ b/drivers/media/dvb/dvb-usb/af9005.h @@ -35,7 +35,7 @@ extern int dvb_usb_af9005_debug; #define deb_i2c(args...) dprintk(dvb_usb_af9005_debug,0x10,args) #define deb_fw(args...) dprintk(dvb_usb_af9005_debug,0x20,args) -extern int dvb_usb_af9005_led; +extern bool dvb_usb_af9005_led; /* firmware */ #define FW_BULKOUT_SIZE 250 diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c index 56cbd3636c31..282a43d648df 100644 --- a/drivers/media/dvb/dvb-usb/af9015.c +++ b/drivers/media/dvb/dvb-usb/af9015.c @@ -50,14 +50,14 @@ static int af9015_properties_count = ARRAY_SIZE(af9015_properties); static struct af9013_config af9015_af9013_config[] = { { - .demod_address = AF9015_I2C_DEMOD, - .output_mode = AF9013_OUTPUT_MODE_USB, + .i2c_addr = AF9015_I2C_DEMOD, + .ts_mode = AF9013_TS_USB, .api_version = { 0, 1, 9, 0 }, .gpio[0] = AF9013_GPIO_HI, .gpio[3] = AF9013_GPIO_TUNER_ON, }, { - .output_mode = AF9013_OUTPUT_MODE_SERIAL, + .ts_mode = AF9013_TS_SERIAL, .api_version = { 0, 1, 9, 0 }, .gpio[0] = AF9013_GPIO_TUNER_ON, .gpio[1] = AF9013_GPIO_LO, @@ -216,8 +216,8 @@ static int af9015_write_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg, { struct req_t req = {WRITE_I2C, addr, reg, 1, 1, 1, &val}; - if (addr == af9015_af9013_config[0].demod_address || - addr == af9015_af9013_config[1].demod_address) + if (addr == af9015_af9013_config[0].i2c_addr || + addr == af9015_af9013_config[1].i2c_addr) req.addr_len = 3; return af9015_ctrl_msg(d, &req); @@ -228,8 +228,8 @@ static int af9015_read_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg, { struct req_t req = {READ_I2C, addr, reg, 0, 1, 1, val}; - if (addr == af9015_af9013_config[0].demod_address || - addr == af9015_af9013_config[1].demod_address) + if (addr == af9015_af9013_config[0].i2c_addr || + addr == af9015_af9013_config[1].i2c_addr) req.addr_len = 3; return af9015_ctrl_msg(d, &req); @@ -271,8 +271,8 @@ Due to that the only way to select correct tuner is use demodulator I2C-gate. return -EAGAIN; while (i < num) { - if (msg[i].addr == af9015_af9013_config[0].demod_address || - msg[i].addr == af9015_af9013_config[1].demod_address) { + if (msg[i].addr == af9015_af9013_config[0].i2c_addr || + msg[i].addr == af9015_af9013_config[1].i2c_addr) { addr = msg[i].buf[0] << 8; addr += msg[i].buf[1]; mbox = msg[i].buf[2]; @@ -288,8 +288,7 @@ Due to that the only way to select correct tuner is use demodulator I2C-gate. ret = -EOPNOTSUPP; goto error; } - if (msg[i].addr == - af9015_af9013_config[0].demod_address) + if (msg[i].addr == af9015_af9013_config[0].i2c_addr) req.cmd = READ_MEMORY; else req.cmd = READ_I2C; @@ -307,7 +306,7 @@ Due to that the only way to select correct tuner is use demodulator I2C-gate. goto error; } if (msg[i].addr == - af9015_af9013_config[0].demod_address) { + af9015_af9013_config[0].i2c_addr) { ret = -EINVAL; goto error; } @@ -325,8 +324,7 @@ Due to that the only way to select correct tuner is use demodulator I2C-gate. ret = -EOPNOTSUPP; goto error; } - if (msg[i].addr == - af9015_af9013_config[0].demod_address) + if (msg[i].addr == af9015_af9013_config[0].i2c_addr) req.cmd = WRITE_MEMORY; else req.cmd = WRITE_I2C; @@ -508,7 +506,7 @@ static int af9015_copy_firmware(struct dvb_usb_device *d) msleep(100); ret = af9015_read_reg_i2c(d, - af9015_af9013_config[1].demod_address, 0x98be, &val); + af9015_af9013_config[1].i2c_addr, 0x98be, &val); if (ret) goto error; else @@ -536,7 +534,7 @@ static int af9015_copy_firmware(struct dvb_usb_device *d) goto error; /* request boot firmware */ - ret = af9015_write_reg_i2c(d, af9015_af9013_config[1].demod_address, + ret = af9015_write_reg_i2c(d, af9015_af9013_config[1].i2c_addr, 0xe205, 1); deb_info("%s: firmware boot cmd status:%d\n", __func__, ret); if (ret) @@ -547,7 +545,7 @@ static int af9015_copy_firmware(struct dvb_usb_device *d) /* check firmware status */ ret = af9015_read_reg_i2c(d, - af9015_af9013_config[1].demod_address, 0x98be, &val); + af9015_af9013_config[1].i2c_addr, 0x98be, &val); deb_info("%s: firmware status cmd status:%d fw status:%02x\n", __func__, ret, val); if (ret) @@ -840,7 +838,7 @@ static int af9015_read_config(struct usb_device *udev) if (ret) goto error; - deb_info("%s: IR mode:%d\n", __func__, val); + deb_info("%s: IR mode=%d\n", __func__, val); for (i = 0; i < af9015_properties_count; i++) { if (val == AF9015_IR_MODE_DISABLED) af9015_properties[i].rc.core.rc_codes = NULL; @@ -854,7 +852,7 @@ static int af9015_read_config(struct usb_device *udev) if (ret) goto error; af9015_config.dual_mode = val; - deb_info("%s: TS mode:%d\n", __func__, af9015_config.dual_mode); + deb_info("%s: TS mode=%d\n", __func__, af9015_config.dual_mode); /* Set adapter0 buffer size according to USB port speed, adapter1 buffer size can be static because it is enabled only USB2.0 */ @@ -878,7 +876,7 @@ static int af9015_read_config(struct usb_device *udev) ret = af9015_rw_udev(udev, &req); if (ret) goto error; - af9015_af9013_config[1].demod_address = val; + af9015_af9013_config[1].i2c_addr = val; /* enable 2nd adapter */ for (i = 0; i < af9015_properties_count; i++) @@ -900,34 +898,38 @@ static int af9015_read_config(struct usb_device *udev) goto error; switch (val) { case 0: - af9015_af9013_config[i].adc_clock = 28800; + af9015_af9013_config[i].clock = 28800000; break; case 1: - af9015_af9013_config[i].adc_clock = 20480; + af9015_af9013_config[i].clock = 20480000; break; case 2: - af9015_af9013_config[i].adc_clock = 28000; + af9015_af9013_config[i].clock = 28000000; break; case 3: - af9015_af9013_config[i].adc_clock = 25000; + af9015_af9013_config[i].clock = 25000000; break; }; - deb_info("%s: [%d] xtal:%d set adc_clock:%d\n", __func__, i, - val, af9015_af9013_config[i].adc_clock); + deb_info("%s: [%d] xtal=%d set clock=%d\n", __func__, i, + val, af9015_af9013_config[i].clock); - /* tuner IF */ + /* IF frequency */ req.addr = AF9015_EEPROM_IF1H + offset; ret = af9015_rw_udev(udev, &req); if (ret) goto error; - af9015_af9013_config[i].tuner_if = val << 8; + + af9015_af9013_config[i].if_frequency = val << 8; + req.addr = AF9015_EEPROM_IF1L + offset; ret = af9015_rw_udev(udev, &req); if (ret) goto error; - af9015_af9013_config[i].tuner_if += val; - deb_info("%s: [%d] IF1:%d\n", __func__, i, - af9015_af9013_config[0].tuner_if); + + af9015_af9013_config[i].if_frequency += val; + af9015_af9013_config[i].if_frequency *= 1000; + deb_info("%s: [%d] IF frequency=%d\n", __func__, i, + af9015_af9013_config[0].if_frequency); /* MT2060 IF1 */ req.addr = AF9015_EEPROM_MT2060_IF1H + offset; @@ -940,7 +942,7 @@ static int af9015_read_config(struct usb_device *udev) if (ret) goto error; af9015_config.mt2060_if1[i] += val; - deb_info("%s: [%d] MT2060 IF1:%d\n", __func__, i, + deb_info("%s: [%d] MT2060 IF1=%d\n", __func__, i, af9015_config.mt2060_if1[i]); /* tuner */ @@ -957,30 +959,30 @@ static int af9015_read_config(struct usb_device *udev) case AF9013_TUNER_TDA18271: case AF9013_TUNER_QT1010A: case AF9013_TUNER_TDA18218: - af9015_af9013_config[i].rf_spec_inv = 1; + af9015_af9013_config[i].spec_inv = 1; break; case AF9013_TUNER_MXL5003D: case AF9013_TUNER_MXL5005D: case AF9013_TUNER_MXL5005R: case AF9013_TUNER_MXL5007T: - af9015_af9013_config[i].rf_spec_inv = 0; + af9015_af9013_config[i].spec_inv = 0; break; case AF9013_TUNER_MC44S803: af9015_af9013_config[i].gpio[1] = AF9013_GPIO_LO; - af9015_af9013_config[i].rf_spec_inv = 1; + af9015_af9013_config[i].spec_inv = 1; break; default: - warn("tuner id:%d not supported, please report!", val); + warn("tuner id=%d not supported, please report!", val); return -ENODEV; }; af9015_af9013_config[i].tuner = val; - deb_info("%s: [%d] tuner id:%d\n", __func__, i, val); + deb_info("%s: [%d] tuner id=%d\n", __func__, i, val); } error: if (ret) - err("eeprom read failed:%d", ret); + err("eeprom read failed=%d", ret); /* AverMedia AVerTV Volar Black HD (A850) device have bad EEPROM content :-( Override some wrong values here. Ditto for the @@ -998,7 +1000,7 @@ error: af9015_properties[i].num_adapters = 1; /* set correct IF */ - af9015_af9013_config[0].tuner_if = 4570; + af9015_af9013_config[0].if_frequency = 4570000; } return ret; @@ -1093,9 +1095,79 @@ error: return ret; } +/* override demod callbacks for resource locking */ +static int af9015_af9013_set_frontend(struct dvb_frontend *fe) +{ + int ret; + struct dvb_usb_adapter *adap = fe->dvb->priv; + struct af9015_state *priv = adap->dev->priv; + + if (mutex_lock_interruptible(&adap->dev->usb_mutex)) + return -EAGAIN; + + ret = priv->set_frontend[adap->id](fe); + + mutex_unlock(&adap->dev->usb_mutex); + + return ret; +} + +/* override demod callbacks for resource locking */ +static int af9015_af9013_read_status(struct dvb_frontend *fe, + fe_status_t *status) +{ + int ret; + struct dvb_usb_adapter *adap = fe->dvb->priv; + struct af9015_state *priv = adap->dev->priv; + + if (mutex_lock_interruptible(&adap->dev->usb_mutex)) + return -EAGAIN; + + ret = priv->read_status[adap->id](fe, status); + + mutex_unlock(&adap->dev->usb_mutex); + + return ret; +} + +/* override demod callbacks for resource locking */ +static int af9015_af9013_init(struct dvb_frontend *fe) +{ + int ret; + struct dvb_usb_adapter *adap = fe->dvb->priv; + struct af9015_state *priv = adap->dev->priv; + + if (mutex_lock_interruptible(&adap->dev->usb_mutex)) + return -EAGAIN; + + ret = priv->init[adap->id](fe); + + mutex_unlock(&adap->dev->usb_mutex); + + return ret; +} + +/* override demod callbacks for resource locking */ +static int af9015_af9013_sleep(struct dvb_frontend *fe) +{ + int ret; + struct dvb_usb_adapter *adap = fe->dvb->priv; + struct af9015_state *priv = adap->dev->priv; + + if (mutex_lock_interruptible(&adap->dev->usb_mutex)) + return -EAGAIN; + + ret = priv->sleep[adap->id](fe); + + mutex_unlock(&adap->dev->usb_mutex); + + return ret; +} + static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap) { int ret; + struct af9015_state *state = adap->dev->priv; if (adap->id == 1) { /* copy firmware to 2nd demodulator */ @@ -1116,6 +1188,32 @@ static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap) adap->fe_adap[0].fe = dvb_attach(af9013_attach, &af9015_af9013_config[adap->id], &adap->dev->i2c_adap); + /* + * AF9015 firmware does not like if it gets interrupted by I2C adapter + * request on some critical phases. During normal operation I2C adapter + * is used only 2nd demodulator and tuner on dual tuner devices. + * Override demodulator callbacks and use mutex for limit access to + * those "critical" paths to keep AF9015 happy. + * Note: we abuse unused usb_mutex here. + */ + if (adap->fe_adap[0].fe) { + state->set_frontend[adap->id] = + adap->fe_adap[0].fe->ops.set_frontend; + adap->fe_adap[0].fe->ops.set_frontend = + af9015_af9013_set_frontend; + + state->read_status[adap->id] = + adap->fe_adap[0].fe->ops.read_status; + adap->fe_adap[0].fe->ops.read_status = + af9015_af9013_read_status; + + state->init[adap->id] = adap->fe_adap[0].fe->ops.init; + adap->fe_adap[0].fe->ops.init = af9015_af9013_init; + + state->sleep[adap->id] = adap->fe_adap[0].fe->ops.sleep; + adap->fe_adap[0].fe->ops.sleep = af9015_af9013_sleep; + } + return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; } @@ -1245,49 +1343,112 @@ static int af9015_tuner_attach(struct dvb_usb_adapter *adap) return ret; } +enum af9015_usb_table_entry { + AFATECH_9015, + AFATECH_9016, + WINFAST_DTV_GOLD, + PINNACLE_PCTV_71E, + KWORLD_PLUSTV_399U, + TINYTWIN, + AZUREWAVE_TU700, + TERRATEC_AF9015, + KWORLD_PLUSTV_PC160, + AVERTV_VOLAR_X, + XTENSIONS_380U, + MSI_DIGIVOX_DUO, + AVERTV_VOLAR_X_REV2, + TELESTAR_STARSTICK_2, + AVERMEDIA_A309_USB, + MSI_DIGIVOX_MINI_III, + KWORLD_E396, + KWORLD_E39B, + KWORLD_E395, + TREKSTOR_DVBT, + AVERTV_A850, + AVERTV_A805, + CONCEPTRONIC_CTVDIGRCU, + KWORLD_MC810, + GENIUS_TVGO_DVB_T03, + KWORLD_399U_2, + KWORLD_PC160_T, + SVEON_STV20, + TINYTWIN_2, + WINFAST_DTV2000DS, + KWORLD_UB383_T, + KWORLD_E39A, + AVERMEDIA_A815M, + CINERGY_T_STICK_RC, + CINERGY_T_DUAL_RC, + AVERTV_A850T, + TINYTWIN_3, + SVEON_STV22, +}; + static struct usb_device_id af9015_usb_table[] = { -/* 0 */{USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9015)}, - {USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9016)}, - {USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_GOLD)}, - {USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV71E)}, - {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U)}, -/* 5 */{USB_DEVICE(USB_VID_VISIONPLUS, - USB_PID_TINYTWIN)}, - {USB_DEVICE(USB_VID_VISIONPLUS, - USB_PID_AZUREWAVE_AD_TU700)}, - {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_USB_XE_REV2)}, - {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_2T)}, - {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X)}, -/* 10 */{USB_DEVICE(USB_VID_XTENSIONS, USB_PID_XTENSIONS_XD_380)}, - {USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGIVOX_DUO)}, - {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X_2)}, - {USB_DEVICE(USB_VID_TELESTAR, USB_PID_TELESTAR_STARSTICK_2)}, - {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A309)}, -/* 15 */{USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGI_VOX_MINI_III)}, - {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U)}, - {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_2)}, - {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_3)}, - {USB_DEVICE(USB_VID_AFATECH, USB_PID_TREKSTOR_DVBT)}, -/* 20 */{USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850)}, - {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A805)}, - {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_CONCEPTRONIC_CTVDIGRCU)}, - {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_MC810)}, - {USB_DEVICE(USB_VID_KYE, USB_PID_GENIUS_TVGO_DVB_T03)}, -/* 25 */{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U_2)}, - {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_T)}, - {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV20)}, - {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_TINYTWIN_2)}, - {USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV2000DS)}, -/* 30 */{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB383_T)}, - {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_4)}, - {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A815M)}, - {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_STICK_RC)}, - {USB_DEVICE(USB_VID_TERRATEC, - USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC)}, -/* 35 */{USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850T)}, - {USB_DEVICE(USB_VID_GTEK, USB_PID_TINYTWIN_3)}, - {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV22)}, - {0}, + [AFATECH_9015] = + {USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9015)}, + [AFATECH_9016] = + {USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9016)}, + [WINFAST_DTV_GOLD] = + {USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_GOLD)}, + [PINNACLE_PCTV_71E] = + {USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV71E)}, + [KWORLD_PLUSTV_399U] = + {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U)}, + [TINYTWIN] = {USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TINYTWIN)}, + [AZUREWAVE_TU700] = + {USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_AZUREWAVE_AD_TU700)}, + [TERRATEC_AF9015] = {USB_DEVICE(USB_VID_TERRATEC, + USB_PID_TERRATEC_CINERGY_T_USB_XE_REV2)}, + [KWORLD_PLUSTV_PC160] = + {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_2T)}, + [AVERTV_VOLAR_X] = + {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X)}, + [XTENSIONS_380U] = + {USB_DEVICE(USB_VID_XTENSIONS, USB_PID_XTENSIONS_XD_380)}, + [MSI_DIGIVOX_DUO] = + {USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGIVOX_DUO)}, + [AVERTV_VOLAR_X_REV2] = + {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X_2)}, + [TELESTAR_STARSTICK_2] = + {USB_DEVICE(USB_VID_TELESTAR, USB_PID_TELESTAR_STARSTICK_2)}, + [AVERMEDIA_A309_USB] = + {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A309)}, + [MSI_DIGIVOX_MINI_III] = + {USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGI_VOX_MINI_III)}, + [KWORLD_E396] = {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U)}, + [KWORLD_E39B] = {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_2)}, + [KWORLD_E395] = {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_3)}, + [TREKSTOR_DVBT] = {USB_DEVICE(USB_VID_AFATECH, USB_PID_TREKSTOR_DVBT)}, + [AVERTV_A850] = {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850)}, + [AVERTV_A805] = {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A805)}, + [CONCEPTRONIC_CTVDIGRCU] = + {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_CONCEPTRONIC_CTVDIGRCU)}, + [KWORLD_MC810] = {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_MC810)}, + [GENIUS_TVGO_DVB_T03] = + {USB_DEVICE(USB_VID_KYE, USB_PID_GENIUS_TVGO_DVB_T03)}, + [KWORLD_399U_2] = {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U_2)}, + [KWORLD_PC160_T] = + {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_T)}, + [SVEON_STV20] = {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV20)}, + [TINYTWIN_2] = {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_TINYTWIN_2)}, + [WINFAST_DTV2000DS] = + {USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV2000DS)}, + [KWORLD_UB383_T] = + {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB383_T)}, + [KWORLD_E39A] = + {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_4)}, + [AVERMEDIA_A815M] = + {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A815M)}, + [CINERGY_T_STICK_RC] = {USB_DEVICE(USB_VID_TERRATEC, + USB_PID_TERRATEC_CINERGY_T_STICK_RC)}, + [CINERGY_T_DUAL_RC] = {USB_DEVICE(USB_VID_TERRATEC, + USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC)}, + [AVERTV_A850T] = + {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850T)}, + [TINYTWIN_3] = {USB_DEVICE(USB_VID_GTEK, USB_PID_TINYTWIN_3)}, + [SVEON_STV22] = {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV22)}, + { } }; MODULE_DEVICE_TABLE(usb, af9015_usb_table); @@ -1362,68 +1523,104 @@ static struct dvb_usb_device_properties af9015_properties[] = { .devices = { { .name = "Afatech AF9015 DVB-T USB2.0 stick", - .cold_ids = {&af9015_usb_table[0], - &af9015_usb_table[1], NULL}, + .cold_ids = { + &af9015_usb_table[AFATECH_9015], + &af9015_usb_table[AFATECH_9016], + NULL + }, .warm_ids = {NULL}, }, { .name = "Leadtek WinFast DTV Dongle Gold", - .cold_ids = {&af9015_usb_table[2], NULL}, + .cold_ids = { + &af9015_usb_table[WINFAST_DTV_GOLD], + NULL + }, .warm_ids = {NULL}, }, { .name = "Pinnacle PCTV 71e", - .cold_ids = {&af9015_usb_table[3], NULL}, + .cold_ids = { + &af9015_usb_table[PINNACLE_PCTV_71E], + NULL + }, .warm_ids = {NULL}, }, { .name = "KWorld PlusTV Dual DVB-T Stick " \ "(DVB-T 399U)", - .cold_ids = {&af9015_usb_table[4], - &af9015_usb_table[25], NULL}, + .cold_ids = { + &af9015_usb_table[KWORLD_PLUSTV_399U], + &af9015_usb_table[KWORLD_399U_2], + NULL + }, .warm_ids = {NULL}, }, { .name = "DigitalNow TinyTwin DVB-T Receiver", - .cold_ids = {&af9015_usb_table[5], - &af9015_usb_table[28], - &af9015_usb_table[36], NULL}, + .cold_ids = { + &af9015_usb_table[TINYTWIN], + &af9015_usb_table[TINYTWIN_2], + &af9015_usb_table[TINYTWIN_3], + NULL + }, .warm_ids = {NULL}, }, { .name = "TwinHan AzureWave AD-TU700(704J)", - .cold_ids = {&af9015_usb_table[6], NULL}, + .cold_ids = { + &af9015_usb_table[AZUREWAVE_TU700], + NULL + }, .warm_ids = {NULL}, }, { .name = "TerraTec Cinergy T USB XE", - .cold_ids = {&af9015_usb_table[7], NULL}, + .cold_ids = { + &af9015_usb_table[TERRATEC_AF9015], + NULL + }, .warm_ids = {NULL}, }, { .name = "KWorld PlusTV Dual DVB-T PCI " \ "(DVB-T PC160-2T)", - .cold_ids = {&af9015_usb_table[8], NULL}, + .cold_ids = { + &af9015_usb_table[KWORLD_PLUSTV_PC160], + NULL + }, .warm_ids = {NULL}, }, { .name = "AVerMedia AVerTV DVB-T Volar X", - .cold_ids = {&af9015_usb_table[9], NULL}, + .cold_ids = { + &af9015_usb_table[AVERTV_VOLAR_X], + NULL + }, .warm_ids = {NULL}, }, { .name = "TerraTec Cinergy T Stick RC", - .cold_ids = {&af9015_usb_table[33], NULL}, + .cold_ids = { + &af9015_usb_table[CINERGY_T_STICK_RC], + NULL + }, .warm_ids = {NULL}, }, { .name = "TerraTec Cinergy T Stick Dual RC", - .cold_ids = {&af9015_usb_table[34], NULL}, + .cold_ids = { + &af9015_usb_table[CINERGY_T_DUAL_RC], + NULL + }, .warm_ids = {NULL}, }, { .name = "AverMedia AVerTV Red HD+ (A850T)", - .cold_ids = {&af9015_usb_table[35], NULL}, + .cold_ids = { + &af9015_usb_table[AVERTV_A850T], + NULL + }, .warm_ids = {NULL}, }, } @@ -1496,57 +1693,87 @@ static struct dvb_usb_device_properties af9015_properties[] = { .devices = { { .name = "Xtensions XD-380", - .cold_ids = {&af9015_usb_table[10], NULL}, + .cold_ids = { + &af9015_usb_table[XTENSIONS_380U], + NULL + }, .warm_ids = {NULL}, }, { .name = "MSI DIGIVOX Duo", - .cold_ids = {&af9015_usb_table[11], NULL}, + .cold_ids = { + &af9015_usb_table[MSI_DIGIVOX_DUO], + NULL + }, .warm_ids = {NULL}, }, { .name = "Fujitsu-Siemens Slim Mobile USB DVB-T", - .cold_ids = {&af9015_usb_table[12], NULL}, + .cold_ids = { + &af9015_usb_table[AVERTV_VOLAR_X_REV2], + NULL + }, .warm_ids = {NULL}, }, { .name = "Telestar Starstick 2", - .cold_ids = {&af9015_usb_table[13], NULL}, + .cold_ids = { + &af9015_usb_table[TELESTAR_STARSTICK_2], + NULL + }, .warm_ids = {NULL}, }, { .name = "AVerMedia A309", - .cold_ids = {&af9015_usb_table[14], NULL}, + .cold_ids = { + &af9015_usb_table[AVERMEDIA_A309_USB], + NULL + }, .warm_ids = {NULL}, }, { .name = "MSI Digi VOX mini III", - .cold_ids = {&af9015_usb_table[15], NULL}, + .cold_ids = { + &af9015_usb_table[MSI_DIGIVOX_MINI_III], + NULL + }, .warm_ids = {NULL}, }, { .name = "KWorld USB DVB-T TV Stick II " \ "(VS-DVB-T 395U)", - .cold_ids = {&af9015_usb_table[16], - &af9015_usb_table[17], - &af9015_usb_table[18], - &af9015_usb_table[31], NULL}, + .cold_ids = { + &af9015_usb_table[KWORLD_E396], + &af9015_usb_table[KWORLD_E39B], + &af9015_usb_table[KWORLD_E395], + &af9015_usb_table[KWORLD_E39A], + NULL + }, .warm_ids = {NULL}, }, { .name = "TrekStor DVB-T USB Stick", - .cold_ids = {&af9015_usb_table[19], NULL}, + .cold_ids = { + &af9015_usb_table[TREKSTOR_DVBT], + NULL + }, .warm_ids = {NULL}, }, { .name = "AverMedia AVerTV Volar Black HD " \ "(A850)", - .cold_ids = {&af9015_usb_table[20], NULL}, + .cold_ids = { + &af9015_usb_table[AVERTV_A850], + NULL + }, .warm_ids = {NULL}, }, { .name = "Sveon STV22 Dual USB DVB-T Tuner HDTV", - .cold_ids = {&af9015_usb_table[37], NULL}, + .cold_ids = { + &af9015_usb_table[SVEON_STV22], + NULL + }, .warm_ids = {NULL}, }, } @@ -1619,50 +1846,77 @@ static struct dvb_usb_device_properties af9015_properties[] = { .devices = { { .name = "AverMedia AVerTV Volar GPS 805 (A805)", - .cold_ids = {&af9015_usb_table[21], NULL}, + .cold_ids = { + &af9015_usb_table[AVERTV_A805], + NULL + }, .warm_ids = {NULL}, }, { .name = "Conceptronic USB2.0 DVB-T CTVDIGRCU " \ "V3.0", - .cold_ids = {&af9015_usb_table[22], NULL}, + .cold_ids = { + &af9015_usb_table[CONCEPTRONIC_CTVDIGRCU], + NULL + }, .warm_ids = {NULL}, }, { .name = "KWorld Digial MC-810", - .cold_ids = {&af9015_usb_table[23], NULL}, + .cold_ids = { + &af9015_usb_table[KWORLD_MC810], + NULL + }, .warm_ids = {NULL}, }, { .name = "Genius TVGo DVB-T03", - .cold_ids = {&af9015_usb_table[24], NULL}, + .cold_ids = { + &af9015_usb_table[GENIUS_TVGO_DVB_T03], + NULL + }, .warm_ids = {NULL}, }, { .name = "KWorld PlusTV DVB-T PCI Pro Card " \ "(DVB-T PC160-T)", - .cold_ids = {&af9015_usb_table[26], NULL}, + .cold_ids = { + &af9015_usb_table[KWORLD_PC160_T], + NULL + }, .warm_ids = {NULL}, }, { .name = "Sveon STV20 Tuner USB DVB-T HDTV", - .cold_ids = {&af9015_usb_table[27], NULL}, + .cold_ids = { + &af9015_usb_table[SVEON_STV20], + NULL + }, .warm_ids = {NULL}, }, { .name = "Leadtek WinFast DTV2000DS", - .cold_ids = {&af9015_usb_table[29], NULL}, + .cold_ids = { + &af9015_usb_table[WINFAST_DTV2000DS], + NULL + }, .warm_ids = {NULL}, }, { .name = "KWorld USB DVB-T Stick Mobile " \ "(UB383-T)", - .cold_ids = {&af9015_usb_table[30], NULL}, + .cold_ids = { + &af9015_usb_table[KWORLD_UB383_T], + NULL + }, .warm_ids = {NULL}, }, { .name = "AverMedia AVerTV Volar M (A815Mac)", - .cold_ids = {&af9015_usb_table[32], NULL}, + .cold_ids = { + &af9015_usb_table[AVERMEDIA_A815M], + NULL + }, .warm_ids = {NULL}, }, } diff --git a/drivers/media/dvb/dvb-usb/af9015.h b/drivers/media/dvb/dvb-usb/af9015.h index 6252ea6c1904..f619063fa72f 100644 --- a/drivers/media/dvb/dvb-usb/af9015.h +++ b/drivers/media/dvb/dvb-usb/af9015.h @@ -102,6 +102,12 @@ struct af9015_state { u8 rc_repeat; u32 rc_keycode; u8 rc_last[4]; + + /* for demod callback override */ + int (*set_frontend[2]) (struct dvb_frontend *fe); + int (*read_status[2]) (struct dvb_frontend *fe, fe_status_t *status); + int (*init[2]) (struct dvb_frontend *fe); + int (*sleep[2]) (struct dvb_frontend *fe); }; struct af9015_config { diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c index b39f14f85e71..d66192974d68 100644 --- a/drivers/media/dvb/dvb-usb/anysee.c +++ b/drivers/media/dvb/dvb-usb/anysee.c @@ -41,6 +41,7 @@ #include "stv0900.h" #include "stv6110.h" #include "isl6423.h" +#include "cxd2820r.h" /* debug */ static int dvb_usb_anysee_debug; @@ -66,10 +67,12 @@ static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen, if (mutex_lock_interruptible(&anysee_usb_mutex) < 0) return -EAGAIN; + deb_xfer(">>> "); + debug_dump(buf, slen, deb_xfer); + /* We need receive one message more after dvb_usb_generic_rw due to weird transaction flow, which is 1 x send + 2 x receive. */ ret = dvb_usb_generic_rw(d, buf, sizeof(buf), buf, sizeof(buf), 0); - if (!ret) { /* receive 2nd answer */ ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev, @@ -79,7 +82,10 @@ static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen, err("%s: recv bulk message failed: %d", __func__, ret); else { deb_xfer("<<< "); - debug_dump(buf, act_len, deb_xfer); + debug_dump(buf, rlen, deb_xfer); + + if (buf[63] != 0x4f) + deb_info("%s: cmd failed\n", __func__); } } @@ -129,6 +135,29 @@ static int anysee_wr_reg_mask(struct dvb_usb_device *d, u16 reg, u8 val, return anysee_write_reg(d, reg, val); } +/* read single register with mask */ +static int anysee_rd_reg_mask(struct dvb_usb_device *d, u16 reg, u8 *val, + u8 mask) +{ + int ret, i; + u8 tmp; + + ret = anysee_read_reg(d, reg, &tmp); + if (ret) + return ret; + + tmp &= mask; + + /* find position of the first bit */ + for (i = 0; i < 8; i++) { + if ((mask >> i) & 0x01) + break; + } + *val = tmp >> i; + + return 0; +} + static int anysee_get_hw_info(struct dvb_usb_device *d, u8 *id) { u8 buf[] = {CMD_GET_HW_INFO}; @@ -156,22 +185,6 @@ static int anysee_ir_ctrl(struct dvb_usb_device *d, u8 onoff) return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0); } -static int anysee_init(struct dvb_usb_device *d) -{ - int ret; - /* LED light */ - ret = anysee_led_ctrl(d, 0x01, 0x03); - if (ret) - return ret; - - /* enable IR */ - ret = anysee_ir_ctrl(d, 1); - if (ret) - return ret; - - return 0; -} - /* I2C */ static int anysee_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num) @@ -297,7 +310,7 @@ static struct tda10023_config anysee_tda10023_tda18212_config = { .pll_m = 12, .pll_p = 3, .pll_n = 1, - .output_mode = TDA10023_OUTPUT_MODE_PARALLEL_C, + .output_mode = TDA10023_OUTPUT_MODE_PARALLEL_B, .deltaf = 0xba02, }; @@ -309,6 +322,17 @@ static struct tda18212_config anysee_tda18212_config = { .if_dvbc = 5000, }; +static struct tda18212_config anysee_tda18212_config2 = { + .i2c_address = 0x60 /* (0xc0 >> 1) */, + .if_dvbt_6 = 3550, + .if_dvbt_7 = 3700, + .if_dvbt_8 = 4150, + .if_dvbt2_6 = 3250, + .if_dvbt2_7 = 4000, + .if_dvbt2_8 = 4000, + .if_dvbc = 5000, +}; + static struct cx24116_config anysee_cx24116_config = { .demod_address = (0xaa >> 1), .mpg_clk_pos_pol = 0x00, @@ -339,6 +363,11 @@ static struct isl6423_config anysee_isl6423_config = { .addr = (0x10 >> 1), }; +static struct cxd2820r_config anysee_cxd2820r_config = { + .i2c_address = 0x6d, /* (0xda >> 1) */ + .ts_mode = 0x38, +}; + /* * New USB device strings: Mfr=1, Product=2, SerialNumber=0 * Manufacturer: AMT.CO.KR @@ -421,6 +450,14 @@ static struct isl6423_config anysee_isl6423_config = { * IOA[7] TS 1=enabled * IOE[5] STV0903 1=enabled * + * E7 T2C VID=1c73 PID=861f HW=20 FW=0.1 AMTCI=0.5 "anysee-E7T2C(LP)" + * PCB: 508T2C (rev0.3) + * parts: DNOQ44QCH106A(CXD2820R, TDA18212), TDA8024 + * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff + * IOA=4d IOB=00 IOC=cc IOD=48 IOE=e4 + * IOA[7] TS 1=enabled + * IOE[5] CXD2820R 1=enabled + * * E7 PTC VID=1c73 PID=861f HW=21 FW=0.1 AMTCI=?? "anysee-E7PTC(LP)" * PCB: 508PTC (rev0.5) * parts: ZL10353, TDA10023, DNOD44CDH086A(TDA18212) @@ -437,7 +474,7 @@ static struct isl6423_config anysee_isl6423_config = { * IOD[6] ZL10353 1=enabled * IOE[0] IF 0=enabled * - * E7 S2 VID=1c73 PID=861f HW=22 FW=0.1 AMTCI=?? "anysee-E7PS2(LP)" + * E7 PS2 VID=1c73 PID=861f HW=22 FW=0.1 AMTCI=?? "anysee-E7PS2(LP)" * PCB: 508PS2 (rev0.4) * parts: DNBU10512IST(STV0903, STV6110), ISL6423 * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff @@ -446,6 +483,16 @@ static struct isl6423_config anysee_isl6423_config = { * IOE[5] STV0903 1=enabled */ + +/* external I2C gate used for DNOD44CDH086A(TDA18212) tuner module */ +static int anysee_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) +{ + struct dvb_usb_adapter *adap = fe->dvb->priv; + + /* enable / disable tuner access on IOE[4] */ + return anysee_wr_reg_mask(adap->dev, REG_IOE, (enable << 4), 0x10); +} + static int anysee_frontend_ctrl(struct dvb_frontend *fe, int onoff) { struct dvb_usb_adapter *adap = fe->dvb->priv; @@ -577,7 +624,8 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) /* detect hardware only once */ if (adap->fe_adap[0].fe == NULL) { /* Check which hardware we have. - * We must do this call two times to get reliable values (hw bug). + * We must do this call two times to get reliable values + * (hw/fw bug). */ ret = anysee_get_hw_info(adap->dev, hw_info); if (ret) @@ -606,14 +654,14 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) break; /* attach demod */ - adap->fe_adap[0].fe = dvb_attach(mt352_attach, &anysee_mt352_config, - &adap->dev->i2c_adap); + adap->fe_adap[0].fe = dvb_attach(mt352_attach, + &anysee_mt352_config, &adap->dev->i2c_adap); if (adap->fe_adap[0].fe) break; /* attach demod */ - adap->fe_adap[0].fe = dvb_attach(zl10353_attach, &anysee_zl10353_config, - &adap->dev->i2c_adap); + adap->fe_adap[0].fe = dvb_attach(zl10353_attach, + &anysee_zl10353_config, &adap->dev->i2c_adap); break; case ANYSEE_HW_507CD: /* 6 */ @@ -665,8 +713,8 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) goto error; /* attach demod */ - adap->fe_adap[0].fe = dvb_attach(cx24116_attach, &anysee_cx24116_config, - &adap->dev->i2c_adap); + adap->fe_adap[0].fe = dvb_attach(cx24116_attach, + &anysee_cx24116_config, &adap->dev->i2c_adap); break; case ANYSEE_HW_507FA: /* 15 */ @@ -747,17 +795,19 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) } } + /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */ + if (tmp == 0xc7) { + if (adap->fe_adap[state->fe_id].fe) + adap->fe_adap[state->fe_id].fe->ops.i2c_gate_ctrl = + anysee_i2c_gate_ctrl; + } + break; case ANYSEE_HW_508TC: /* 18 */ case ANYSEE_HW_508PTC: /* 21 */ /* E7 TC */ /* E7 PTC */ - /* enable transport stream on IOA[7] */ - ret = anysee_wr_reg_mask(adap->dev, REG_IOA, (1 << 7), 0x80); - if (ret) - goto error; - if ((state->fe_id ^ dvb_usb_anysee_delsys) == 0) { /* disable DVB-T demod on IOD[6] */ ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 6), @@ -772,7 +822,8 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) goto error; /* attach demod */ - adap->fe_adap[state->fe_id].fe = dvb_attach(tda10023_attach, + adap->fe_adap[state->fe_id].fe = + dvb_attach(tda10023_attach, &anysee_tda10023_tda18212_config, &adap->dev->i2c_adap, 0x48); } else { @@ -789,11 +840,19 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) goto error; /* attach demod */ - adap->fe_adap[state->fe_id].fe = dvb_attach(zl10353_attach, + adap->fe_adap[state->fe_id].fe = + dvb_attach(zl10353_attach, &anysee_zl10353_tda18212_config, &adap->dev->i2c_adap); } + /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */ + if (adap->fe_adap[state->fe_id].fe) + adap->fe_adap[state->fe_id].fe->ops.i2c_gate_ctrl = + anysee_i2c_gate_ctrl; + + state->has_ci = true; + break; case ANYSEE_HW_508S2: /* 19 */ case ANYSEE_HW_508PS2: /* 22 */ @@ -803,19 +862,41 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) if (state->fe_id) break; - /* enable transport stream on IOA[7] */ - ret = anysee_wr_reg_mask(adap->dev, REG_IOA, (1 << 7), 0x80); + /* enable DVB-S/S2 demod on IOE[5] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 5), 0x20); if (ret) goto error; - /* enable DVB-S/S2 demod on IOE[5] */ + /* attach demod */ + adap->fe_adap[0].fe = dvb_attach(stv0900_attach, + &anysee_stv0900_config, &adap->dev->i2c_adap, 0); + + state->has_ci = true; + + break; + case ANYSEE_HW_508T2C: /* 20 */ + /* E7 T2C */ + + /* enable DVB-T/T2/C demod on IOE[5] */ ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 5), 0x20); if (ret) goto error; - /* attach demod */ - adap->fe_adap[0].fe = dvb_attach(stv0900_attach, &anysee_stv0900_config, - &adap->dev->i2c_adap, 0); + if (state->fe_id == 0) { + /* DVB-T/T2 */ + adap->fe_adap[state->fe_id].fe = + dvb_attach(cxd2820r_attach, + &anysee_cxd2820r_config, + &adap->dev->i2c_adap, NULL); + } else { + /* DVB-C */ + adap->fe_adap[state->fe_id].fe = + dvb_attach(cxd2820r_attach, + &anysee_cxd2820r_config, + &adap->dev->i2c_adap, adap->fe_adap[0].fe); + } + + state->has_ci = true; break; } @@ -842,24 +923,26 @@ static int anysee_tuner_attach(struct dvb_usb_adapter *adap) /* E30 */ /* attach tuner */ - fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, (0xc2 >> 1), - NULL, DVB_PLL_THOMSON_DTT7579); + fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, + (0xc2 >> 1), NULL, DVB_PLL_THOMSON_DTT7579); break; case ANYSEE_HW_507CD: /* 6 */ /* E30 Plus */ /* attach tuner */ - fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, (0xc2 >> 1), - &adap->dev->i2c_adap, DVB_PLL_THOMSON_DTT7579); + fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, + (0xc2 >> 1), &adap->dev->i2c_adap, + DVB_PLL_THOMSON_DTT7579); break; case ANYSEE_HW_507DC: /* 10 */ /* E30 C Plus */ /* attach tuner */ - fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, (0xc0 >> 1), - &adap->dev->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A); + fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, + (0xc0 >> 1), &adap->dev->i2c_adap, + DVB_PLL_SAMSUNG_DTOS403IH102A); break; case ANYSEE_HW_507SI: /* 11 */ @@ -877,22 +960,12 @@ static int anysee_tuner_attach(struct dvb_usb_adapter *adap) /* Try first attach TDA18212 silicon tuner on IOE[4], if that * fails attach old simple PLL. */ - /* enable tuner on IOE[4] */ - ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 4), 0x10); - if (ret) - goto error; - /* attach tuner */ fe = dvb_attach(tda18212_attach, adap->fe_adap[state->fe_id].fe, &adap->dev->i2c_adap, &anysee_tda18212_config); if (fe) break; - /* disable tuner on IOE[4] */ - ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 4), 0x10); - if (ret) - goto error; - /* attach tuner */ fe = dvb_attach(dvb_pll_attach, adap->fe_adap[state->fe_id].fe, (0xc0 >> 1), &adap->dev->i2c_adap, @@ -904,11 +977,6 @@ static int anysee_tuner_attach(struct dvb_usb_adapter *adap) /* E7 TC */ /* E7 PTC */ - /* enable tuner on IOE[4] */ - ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 4), 0x10); - if (ret) - goto error; - /* attach tuner */ fe = dvb_attach(tda18212_attach, adap->fe_adap[state->fe_id].fe, &adap->dev->i2c_adap, &anysee_tda18212_config); @@ -930,6 +998,15 @@ static int anysee_tuner_attach(struct dvb_usb_adapter *adap) } break; + + case ANYSEE_HW_508T2C: /* 20 */ + /* E7 T2C */ + + /* attach tuner */ + fe = dvb_attach(tda18212_attach, adap->fe_adap[state->fe_id].fe, + &adap->dev->i2c_adap, &anysee_tda18212_config2); + + break; default: fe = NULL; } @@ -939,7 +1016,6 @@ static int anysee_tuner_attach(struct dvb_usb_adapter *adap) else ret = -ENODEV; -error: return ret; } @@ -969,6 +1045,201 @@ static int anysee_rc_query(struct dvb_usb_device *d) return 0; } +static int anysee_ci_read_attribute_mem(struct dvb_ca_en50221 *ci, int slot, + int addr) +{ + struct dvb_usb_device *d = ci->data; + int ret; + u8 buf[] = {CMD_CI, 0x02, 0x40 | addr >> 8, addr & 0xff, 0x00, 1}; + u8 val; + + ret = anysee_ctrl_msg(d, buf, sizeof(buf), &val, 1); + if (ret) + return ret; + + return val; +} + +static int anysee_ci_write_attribute_mem(struct dvb_ca_en50221 *ci, int slot, + int addr, u8 val) +{ + struct dvb_usb_device *d = ci->data; + int ret; + u8 buf[] = {CMD_CI, 0x03, 0x40 | addr >> 8, addr & 0xff, 0x00, 1, val}; + + ret = anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0); + if (ret) + return ret; + + return 0; +} + +static int anysee_ci_read_cam_control(struct dvb_ca_en50221 *ci, int slot, + u8 addr) +{ + struct dvb_usb_device *d = ci->data; + int ret; + u8 buf[] = {CMD_CI, 0x04, 0x40, addr, 0x00, 1}; + u8 val; + + ret = anysee_ctrl_msg(d, buf, sizeof(buf), &val, 1); + if (ret) + return ret; + + return val; +} + +static int anysee_ci_write_cam_control(struct dvb_ca_en50221 *ci, int slot, + u8 addr, u8 val) +{ + struct dvb_usb_device *d = ci->data; + int ret; + u8 buf[] = {CMD_CI, 0x05, 0x40, addr, 0x00, 1, val}; + + ret = anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0); + if (ret) + return ret; + + return 0; +} + +static int anysee_ci_slot_reset(struct dvb_ca_en50221 *ci, int slot) +{ + struct dvb_usb_device *d = ci->data; + int ret; + struct anysee_state *state = d->priv; + + state->ci_cam_ready = jiffies + msecs_to_jiffies(1000); + + ret = anysee_wr_reg_mask(d, REG_IOA, (0 << 7), 0x80); + if (ret) + return ret; + + msleep(300); + + ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80); + if (ret) + return ret; + + return 0; +} + +static int anysee_ci_slot_shutdown(struct dvb_ca_en50221 *ci, int slot) +{ + struct dvb_usb_device *d = ci->data; + int ret; + + ret = anysee_wr_reg_mask(d, REG_IOA, (0 << 7), 0x80); + if (ret) + return ret; + + msleep(30); + + ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80); + if (ret) + return ret; + + return 0; +} + +static int anysee_ci_slot_ts_enable(struct dvb_ca_en50221 *ci, int slot) +{ + struct dvb_usb_device *d = ci->data; + int ret; + + ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 1), 0x02); + if (ret) + return ret; + + return 0; +} + +static int anysee_ci_poll_slot_status(struct dvb_ca_en50221 *ci, int slot, + int open) +{ + struct dvb_usb_device *d = ci->data; + struct anysee_state *state = d->priv; + int ret; + u8 tmp; + + ret = anysee_rd_reg_mask(d, REG_IOC, &tmp, 0x40); + if (ret) + return ret; + + if (tmp == 0) { + ret = DVB_CA_EN50221_POLL_CAM_PRESENT; + if (time_after(jiffies, state->ci_cam_ready)) + ret |= DVB_CA_EN50221_POLL_CAM_READY; + } + + return ret; +} + +static int anysee_ci_init(struct dvb_usb_device *d) +{ + struct anysee_state *state = d->priv; + int ret; + + state->ci.owner = THIS_MODULE; + state->ci.read_attribute_mem = anysee_ci_read_attribute_mem; + state->ci.write_attribute_mem = anysee_ci_write_attribute_mem; + state->ci.read_cam_control = anysee_ci_read_cam_control; + state->ci.write_cam_control = anysee_ci_write_cam_control; + state->ci.slot_reset = anysee_ci_slot_reset; + state->ci.slot_shutdown = anysee_ci_slot_shutdown; + state->ci.slot_ts_enable = anysee_ci_slot_ts_enable; + state->ci.poll_slot_status = anysee_ci_poll_slot_status; + state->ci.data = d; + + ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80); + if (ret) + return ret; + + ret = dvb_ca_en50221_init(&d->adapter[0].dvb_adap, &state->ci, 0, 1); + if (ret) + return ret; + + return 0; +} + +static void anysee_ci_release(struct dvb_usb_device *d) +{ + struct anysee_state *state = d->priv; + + /* detach CI */ + if (state->has_ci) + dvb_ca_en50221_release(&state->ci); + + return; +} + +static int anysee_init(struct dvb_usb_device *d) +{ + struct anysee_state *state = d->priv; + int ret; + + /* LED light */ + ret = anysee_led_ctrl(d, 0x01, 0x03); + if (ret) + return ret; + + /* enable IR */ + ret = anysee_ir_ctrl(d, 1); + if (ret) + return ret; + + /* attach CI */ + if (state->has_ci) { + ret = anysee_ci_init(d); + if (ret) { + state->has_ci = false; + return ret; + } + } + + return 0; +} + /* DVB USB Driver stuff */ static struct dvb_usb_device_properties anysee_properties; @@ -1010,6 +1281,16 @@ static int anysee_probe(struct usb_interface *intf, return anysee_init(d); } +static void anysee_disconnect(struct usb_interface *intf) +{ + struct dvb_usb_device *d = usb_get_intfdata(intf); + + anysee_ci_release(d); + dvb_usb_device_exit(intf); + + return; +} + static struct usb_device_id anysee_table[] = { { USB_DEVICE(USB_VID_CYPRESS, USB_PID_ANYSEE) }, { USB_DEVICE(USB_VID_AMT, USB_PID_ANYSEE) }, @@ -1029,7 +1310,7 @@ static struct dvb_usb_device_properties anysee_properties = { { .num_frontends = 2, .frontend_ctrl = anysee_frontend_ctrl, - .fe = {{ + .fe = { { .streaming_ctrl = anysee_streaming_ctrl, .frontend_attach = anysee_frontend_attach, .tuner_attach = anysee_tuner_attach, @@ -1057,7 +1338,7 @@ static struct dvb_usb_device_properties anysee_properties = { } } }, - }}, + } }, } }, @@ -1087,7 +1368,7 @@ static struct dvb_usb_device_properties anysee_properties = { static struct usb_driver anysee_driver = { .name = "dvb_usb_anysee", .probe = anysee_probe, - .disconnect = dvb_usb_device_exit, + .disconnect = anysee_disconnect, .id_table = anysee_table, }; diff --git a/drivers/media/dvb/dvb-usb/anysee.h b/drivers/media/dvb/dvb-usb/anysee.h index 57ee500b8c0e..8ac879431540 100644 --- a/drivers/media/dvb/dvb-usb/anysee.h +++ b/drivers/media/dvb/dvb-usb/anysee.h @@ -36,6 +36,7 @@ #define DVB_USB_LOG_PREFIX "anysee" #include "dvb-usb.h" +#include "dvb_ca_en50221.h" #define deb_info(args...) dprintk(dvb_usb_anysee_debug, 0x01, args) #define deb_xfer(args...) dprintk(dvb_usb_anysee_debug, 0x02, args) @@ -54,12 +55,16 @@ enum cmd { CMD_GET_IR_CODE = 0x41, CMD_GET_HW_INFO = 0x19, CMD_SMARTCARD = 0x34, + CMD_CI = 0x37, }; struct anysee_state { u8 hw; /* PCB ID */ u8 seq; u8 fe_id:1; /* frondend ID */ + u8 has_ci:1; + struct dvb_ca_en50221 ci; + unsigned long ci_cam_ready; /* jiffies */ }; #define ANYSEE_HW_507T 2 /* E30 */ @@ -69,6 +74,7 @@ struct anysee_state { #define ANYSEE_HW_507FA 15 /* E30 Combo Plus / E30 C Plus */ #define ANYSEE_HW_508TC 18 /* E7 TC */ #define ANYSEE_HW_508S2 19 /* E7 S2 */ +#define ANYSEE_HW_508T2C 20 /* E7 T2C */ #define ANYSEE_HW_508PTC 21 /* E7 PTC Plus */ #define ANYSEE_HW_508PS2 22 /* E7 PS2 Plus */ diff --git a/drivers/media/dvb/dvb-usb/cinergyT2-fe.c b/drivers/media/dvb/dvb-usb/cinergyT2-fe.c index 9cd51ac12076..8a57ed8272de 100644 --- a/drivers/media/dvb/dvb-usb/cinergyT2-fe.c +++ b/drivers/media/dvb/dvb-usb/cinergyT2-fe.c @@ -40,9 +40,8 @@ * We replace errornous fields by default TPS fields (the ones with value 0). */ -static uint16_t compute_tps(struct dvb_frontend_parameters *p) +static uint16_t compute_tps(struct dtv_frontend_properties *op) { - struct dvb_ofdm_parameters *op = &p->u.ofdm; uint16_t tps = 0; switch (op->code_rate_HP) { @@ -83,7 +82,7 @@ static uint16_t compute_tps(struct dvb_frontend_parameters *p) /* tps |= (0 << 4) */; } - switch (op->constellation) { + switch (op->modulation) { case QAM_16: tps |= (1 << 13); break; @@ -119,7 +118,7 @@ static uint16_t compute_tps(struct dvb_frontend_parameters *p) /* tps |= (0 << 2) */; } - switch (op->hierarchy_information) { + switch (op->hierarchy) { case HIERARCHY_1: tps |= (1 << 10); break; @@ -263,9 +262,9 @@ static int cinergyt2_fe_get_tune_settings(struct dvb_frontend *fe, return 0; } -static int cinergyt2_fe_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *fep) +static int cinergyt2_fe_set_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *fep = &fe->dtv_property_cache; struct cinergyt2_fe_state *state = fe->demodulator_priv; struct dvbt_set_parameters_msg param; char result[2]; @@ -274,9 +273,20 @@ static int cinergyt2_fe_set_frontend(struct dvb_frontend *fe, param.cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS; param.tps = cpu_to_le16(compute_tps(fep)); param.freq = cpu_to_le32(fep->frequency / 1000); - param.bandwidth = 8 - fep->u.ofdm.bandwidth - BANDWIDTH_8_MHZ; param.flags = 0; + switch (fep->bandwidth_hz) { + case 8000000: + param.bandwidth = 0; + break; + case 7000000: + param.bandwidth = 1; + break; + case 6000000: + param.bandwidth = 2; + break; + } + err = dvb_usb_generic_rw(state->d, (char *)¶m, sizeof(param), result, sizeof(result), 0); @@ -286,12 +296,6 @@ static int cinergyt2_fe_set_frontend(struct dvb_frontend *fe, return (err < 0) ? err : 0; } -static int cinergyt2_fe_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *fep) -{ - return 0; -} - static void cinergyt2_fe_release(struct dvb_frontend *fe) { struct cinergyt2_fe_state *state = fe->demodulator_priv; @@ -316,9 +320,9 @@ struct dvb_frontend *cinergyt2_fe_attach(struct dvb_usb_device *d) static struct dvb_frontend_ops cinergyt2_fe_ops = { + .delsys = { SYS_DVBT }, .info = { .name = DRIVER_NAME, - .type = FE_OFDM, .frequency_min = 174000000, .frequency_max = 862000000, .frequency_stepsize = 166667, @@ -341,7 +345,6 @@ static struct dvb_frontend_ops cinergyt2_fe_ops = { .sleep = cinergyt2_fe_sleep, .set_frontend = cinergyt2_fe_set_frontend, - .get_frontend = cinergyt2_fe_get_frontend, .get_tune_settings = cinergyt2_fe_get_tune_settings, .read_status = cinergyt2_fe_read_status, diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c index 949ea1bc0aae..3940bb0f9ef6 100644 --- a/drivers/media/dvb/dvb-usb/cxusb.c +++ b/drivers/media/dvb/dvb-usb/cxusb.c @@ -1067,18 +1067,17 @@ static struct dib0070_config dib7070p_dib0070_config = { }; struct dib0700_adapter_state { - int (*set_param_save) (struct dvb_frontend *, - struct dvb_frontend_parameters *); + int (*set_param_save) (struct dvb_frontend *); }; -static int dib7070_set_param_override(struct dvb_frontend *fe, - struct dvb_frontend_parameters *fep) +static int dib7070_set_param_override(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct dvb_usb_adapter *adap = fe->dvb->priv; struct dib0700_adapter_state *state = adap->priv; u16 offset; - u8 band = BAND_OF_FREQUENCY(fep->frequency/1000); + u8 band = BAND_OF_FREQUENCY(p->frequency/1000); switch (band) { case BAND_VHF: offset = 950; break; default: @@ -1087,7 +1086,7 @@ static int dib7070_set_param_override(struct dvb_frontend *fe, dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe)); - return state->set_param_save(fe, fep); + return state->set_param_save(fe); } static int cxusb_dualdig4_rev2_tuner_attach(struct dvb_usb_adapter *adap) diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index f313182eb9d5..81ef4b46f790 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -30,7 +30,7 @@ MODULE_PARM_DESC(force_lna_activation, "force the activation of Low-Noise-Amplif "if applicable for the device (default: 0=automatic/off)."); struct dib0700_adapter_state { - int (*set_param_save) (struct dvb_frontend *, struct dvb_frontend_parameters *); + int (*set_param_save) (struct dvb_frontend *); const struct firmware *frontend_firmware; }; @@ -804,13 +804,14 @@ static struct dib0070_config dib7770p_dib0070_config = { .charge_pump = 2, }; -static int dib7070_set_param_override(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) +static int dib7070_set_param_override(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct dvb_usb_adapter *adap = fe->dvb->priv; struct dib0700_adapter_state *state = adap->priv; u16 offset; - u8 band = BAND_OF_FREQUENCY(fep->frequency/1000); + u8 band = BAND_OF_FREQUENCY(p->frequency/1000); switch (band) { case BAND_VHF: offset = 950; break; case BAND_UHF: @@ -818,17 +819,17 @@ static int dib7070_set_param_override(struct dvb_frontend *fe, struct dvb_fronte } deb_info("WBD for DiB7000P: %d\n", offset + dib0070_wbd_offset(fe)); dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe)); - return state->set_param_save(fe, fep); + return state->set_param_save(fe); } -static int dib7770_set_param_override(struct dvb_frontend *fe, - struct dvb_frontend_parameters *fep) +static int dib7770_set_param_override(struct dvb_frontend *fe) { - struct dvb_usb_adapter *adap = fe->dvb->priv; - struct dib0700_adapter_state *state = adap->priv; + struct dtv_frontend_properties *p = &fe->dtv_property_cache; + struct dvb_usb_adapter *adap = fe->dvb->priv; + struct dib0700_adapter_state *state = adap->priv; u16 offset; - u8 band = BAND_OF_FREQUENCY(fep->frequency/1000); + u8 band = BAND_OF_FREQUENCY(p->frequency/1000); switch (band) { case BAND_VHF: dib7000p_set_gpio(fe, 0, 0, 1); @@ -842,7 +843,7 @@ static int dib7770_set_param_override(struct dvb_frontend *fe, } deb_info("WBD for DiB7000P: %d\n", offset + dib0070_wbd_offset(fe)); dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe)); - return state->set_param_save(fe, fep); + return state->set_param_save(fe); } static int dib7770p_tuner_attach(struct dvb_usb_adapter *adap) @@ -1205,14 +1206,14 @@ static struct dib0070_config dib807x_dib0070_config[2] = { } }; -static int dib807x_set_param_override(struct dvb_frontend *fe, - struct dvb_frontend_parameters *fep) +static int dib807x_set_param_override(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct dvb_usb_adapter *adap = fe->dvb->priv; struct dib0700_adapter_state *state = adap->priv; u16 offset = dib0070_wbd_offset(fe); - u8 band = BAND_OF_FREQUENCY(fep->frequency/1000); + u8 band = BAND_OF_FREQUENCY(p->frequency/1000); switch (band) { case BAND_VHF: offset += 750; @@ -1224,7 +1225,7 @@ static int dib807x_set_param_override(struct dvb_frontend *fe, deb_info("WBD for DiB8000: %d\n", offset); dib8000_set_wbd_ref(fe, offset); - return state->set_param_save(fe, fep); + return state->set_param_save(fe); } static int dib807x_tuner_attach(struct dvb_usb_adapter *adap) @@ -1279,7 +1280,7 @@ static int stk807x_frontend_attach(struct dvb_usb_adapter *adap) dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, - 0x80); + 0x80, 0); adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib807x_dib8000_config[0]); @@ -1308,7 +1309,7 @@ static int stk807xpvr_frontend_attach0(struct dvb_usb_adapter *adap) dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); /* initialize IC 0 */ - dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x22, 0x80); + dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x22, 0x80, 0); adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib807x_dib8000_config[0]); @@ -1319,7 +1320,7 @@ static int stk807xpvr_frontend_attach0(struct dvb_usb_adapter *adap) static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap) { /* initialize IC 1 */ - dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x12, 0x82); + dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x12, 0x82, 0); adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x82, &dib807x_dib8000_config[1]); @@ -1328,7 +1329,7 @@ static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap) } /* STK8096GP */ -struct dibx000_agc_config dib8090_agc_config[2] = { +static struct dibx000_agc_config dib8090_agc_config[2] = { { BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND, /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, @@ -1503,22 +1504,22 @@ static struct dib0090_config dib809x_dib0090_config = { .fref_clock_ratio = 6, }; -static int dib8096_set_param_override(struct dvb_frontend *fe, - struct dvb_frontend_parameters *fep) +static int dib8096_set_param_override(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct dvb_usb_adapter *adap = fe->dvb->priv; struct dib0700_adapter_state *state = adap->priv; - u8 band = BAND_OF_FREQUENCY(fep->frequency/1000); + u8 band = BAND_OF_FREQUENCY(p->frequency/1000); u16 target; int ret = 0; enum frontend_tune_state tune_state = CT_SHUTDOWN; u16 ltgain, rf_gain_limit; - ret = state->set_param_save(fe, fep); + ret = state->set_param_save(fe); if (ret < 0) return ret; - target = (dib0090_get_wbd_offset(fe) * 8 * 18 / 33 + 1) / 2; + target = (dib0090_get_wbd_target(fe) * 8 * 18 / 33 + 1) / 2; dib8000_set_wbd_ref(fe, target); @@ -1578,7 +1579,7 @@ static int stk809x_frontend_attach(struct dvb_usb_adapter *adap) msleep(10); dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); - dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 0x80); + dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 0x80, 0); adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]); @@ -1629,7 +1630,7 @@ static int nim8096md_frontend_attach(struct dvb_usb_adapter *adap) msleep(20); dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); - dib8000_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, 0x80); + dib8000_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, 0x80, 0); adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]); if (adap->fe_adap[0].fe == NULL) @@ -1641,6 +1642,261 @@ static int nim8096md_frontend_attach(struct dvb_usb_adapter *adap) return fe_slave == NULL ? -ENODEV : 0; } +/* TFE8096P */ +static struct dibx000_agc_config dib8096p_agc_config[2] = { + { + .band_caps = BAND_UHF, + /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, + P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0, + P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0, + P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, + P_agc_write=0 */ + .setup = (0 << 15) | (0 << 14) | (5 << 11) + | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) + | (0 << 4) | (5 << 1) | (0 << 0), + + .inv_gain = 684, + .time_stabiliz = 10, + + .alpha_level = 0, + .thlock = 118, + + .wbd_inv = 0, + .wbd_ref = 1200, + .wbd_sel = 3, + .wbd_alpha = 5, + + .agc1_max = 65535, + .agc1_min = 0, + + .agc2_max = 32767, + .agc2_min = 0, + + .agc1_pt1 = 0, + .agc1_pt2 = 0, + .agc1_pt3 = 105, + .agc1_slope1 = 0, + .agc1_slope2 = 156, + .agc2_pt1 = 105, + .agc2_pt2 = 255, + .agc2_slope1 = 54, + .agc2_slope2 = 0, + + .alpha_mant = 28, + .alpha_exp = 26, + .beta_mant = 31, + .beta_exp = 51, + + .perform_agc_softsplit = 0, + } , { + .band_caps = BAND_FM | BAND_VHF | BAND_CBAND, + /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, + P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0, + P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0, + P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, + P_agc_write=0 */ + .setup = (0 << 15) | (0 << 14) | (5 << 11) + | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) + | (0 << 4) | (5 << 1) | (0 << 0), + + .inv_gain = 732, + .time_stabiliz = 10, + + .alpha_level = 0, + .thlock = 118, + + .wbd_inv = 0, + .wbd_ref = 1200, + .wbd_sel = 3, + .wbd_alpha = 5, + + .agc1_max = 65535, + .agc1_min = 0, + + .agc2_max = 32767, + .agc2_min = 0, + + .agc1_pt1 = 0, + .agc1_pt2 = 0, + .agc1_pt3 = 98, + .agc1_slope1 = 0, + .agc1_slope2 = 167, + .agc2_pt1 = 98, + .agc2_pt2 = 255, + .agc2_slope1 = 52, + .agc2_slope2 = 0, + + .alpha_mant = 28, + .alpha_exp = 26, + .beta_mant = 31, + .beta_exp = 51, + + .perform_agc_softsplit = 0, + } +}; + +static struct dibx000_bandwidth_config dib8096p_clock_config_12_mhz = { + 108000, 13500, + 1, 9, 1, 0, 0, + 0, 0, 0, 0, 2, + (3 << 14) | (1 << 12) | (524 << 0), + (0 << 25) | 0, + 20199729, + 12000000, +}; + +static struct dib8000_config tfe8096p_dib8000_config = { + .output_mpeg2_in_188_bytes = 1, + .hostbus_diversity = 1, + .update_lna = NULL, + + .agc_config_count = 2, + .agc = dib8096p_agc_config, + .pll = &dib8096p_clock_config_12_mhz, + + .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS, + .gpio_val = DIB8000_GPIO_DEFAULT_VALUES, + .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS, + + .agc_control = NULL, + .diversity_delay = 48, + .output_mode = OUTMODE_MPEG2_FIFO, + .enMpegOutput = 1, +}; + +static struct dib0090_wbd_slope dib8096p_wbd_table[] = { + { 380, 81, 850, 64, 540, 4}, + { 860, 51, 866, 21, 375, 4}, + {1700, 0, 250, 0, 100, 6}, + {2600, 0, 250, 0, 100, 6}, + { 0xFFFF, 0, 0, 0, 0, 0}, +}; + +static const struct dib0090_config tfe8096p_dib0090_config = { + .io.clock_khz = 12000, + .io.pll_bypass = 0, + .io.pll_range = 0, + .io.pll_prediv = 3, + .io.pll_loopdiv = 6, + .io.adc_clock_ratio = 0, + .io.pll_int_loop_filt = 0, + .reset = dib8096p_tuner_sleep, + .sleep = dib8096p_tuner_sleep, + + .freq_offset_khz_uhf = -143, + .freq_offset_khz_vhf = -143, + + .get_adc_power = dib8090_get_adc_power, + + .clkouttobamse = 1, + .analog_output = 0, + + .wbd_vhf_offset = 0, + .wbd_cband_offset = 0, + .use_pwm_agc = 1, + .clkoutdrive = 0, + + .fref_clock_ratio = 1, + + .wbd = dib8096p_wbd_table, + + .ls_cfg_pad_drv = 0, + .data_tx_drv = 0, + .low_if = NULL, + .in_soc = 1, + .force_cband_input = 0, +}; + +struct dibx090p_adc { + u32 freq; /* RF freq MHz */ + u32 timf; /* New Timf */ + u32 pll_loopdiv; /* New prediv */ + u32 pll_prediv; /* New loopdiv */ +}; + +struct dibx090p_adc dib8090p_adc_tab[] = { + { 50000, 17043521, 16, 3}, /* 64 MHz */ + {878000, 20199729, 9, 1}, /* 60 MHz */ + {0xffffffff, 0, 0, 0}, /* 60 MHz */ +}; + +static int dib8096p_agc_startup(struct dvb_frontend *fe) +{ + struct dtv_frontend_properties *p = &fe->dtv_property_cache; + struct dvb_usb_adapter *adap = fe->dvb->priv; + struct dib0700_adapter_state *state = adap->priv; + struct dibx000_bandwidth_config pll; + u16 target; + int better_sampling_freq = 0, ret; + struct dibx090p_adc *adc_table = &dib8090p_adc_tab[0]; + + ret = state->set_param_save(fe); + if (ret < 0) + return ret; + memset(&pll, 0, sizeof(struct dibx000_bandwidth_config)); + + dib0090_pwm_gain_reset(fe); + /* dib0090_get_wbd_target is returning any possible + temperature compensated wbd-target */ + target = (dib0090_get_wbd_target(fe) * 8 + 1) / 2; + dib8000_set_wbd_ref(fe, target); + + + while (p->frequency / 1000 > adc_table->freq) { + better_sampling_freq = 1; + adc_table++; + } + + if ((adc_table->freq != 0xffffffff) && better_sampling_freq) { + pll.pll_ratio = adc_table->pll_loopdiv; + pll.pll_prediv = adc_table->pll_prediv; + dib8000_update_pll(fe, &pll); + dib8000_ctrl_timf(fe, DEMOD_TIMF_SET, adc_table->timf); + } + return 0; +} + +static int tfe8096p_frontend_attach(struct dvb_usb_adapter *adap) +{ + dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); + msleep(20); + dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); + + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); + + dib0700_ctrl_clock(adap->dev, 72, 1); + + msleep(20); + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); + msleep(20); + dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); + + dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, 0x80, 1); + + adap->fe_adap[0].fe = dvb_attach(dib8000_attach, + &adap->dev->i2c_adap, 0x80, &tfe8096p_dib8000_config); + + return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; +} + +static int tfe8096p_tuner_attach(struct dvb_usb_adapter *adap) +{ + struct dib0700_adapter_state *st = adap->priv; + struct i2c_adapter *tun_i2c = dib8096p_get_i2c_tuner(adap->fe_adap[0].fe); + + if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, + &tfe8096p_dib0090_config) == NULL) + return -ENODEV; + + dib8000_set_gpio(adap->fe_adap[0].fe, 8, 0, 1); + + st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params; + adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib8096p_agc_startup; + return 0; +} + /* STK9090M */ static int dib90x0_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff) { @@ -1883,7 +2139,7 @@ static int dib9090_tuner_attach(struct dvb_usb_adapter *adap) i2c = dib9000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_1_2, 0); if (dib01x0_pmu_update(i2c, data_dib190, 10) != 0) return -ENODEV; - dib0700_set_i2c_speed(adap->dev, 2000); + dib0700_set_i2c_speed(adap->dev, 1500); if (dib9000_firmware_post_pll_init(adap->fe_adap[0].fe) < 0) return -ENODEV; release_firmware(state->frontend_firmware); @@ -1962,7 +2218,8 @@ static int nim9090md_tuner_attach(struct dvb_usb_adapter *adap) i2c = dib9000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_1_2, 0); if (dib01x0_pmu_update(i2c, data_dib190, 10) < 0) return -ENODEV; - dib0700_set_i2c_speed(adap->dev, 2000); + + dib0700_set_i2c_speed(adap->dev, 1500); if (dib9000_firmware_post_pll_init(adap->fe_adap[0].fe) < 0) return -ENODEV; @@ -1975,7 +2232,7 @@ static int nim9090md_tuner_attach(struct dvb_usb_adapter *adap) if (dvb_attach(dib0090_fw_register, fe_slave, i2c, &nim9090md_dib0090_config[1]) == NULL) return -ENODEV; fe_slave->dvb = adap->fe_adap[0].fe->dvb; - dib9000_fw_set_component_bus_speed(adap->fe_adap[0].fe, 2000); + dib9000_fw_set_component_bus_speed(adap->fe_adap[0].fe, 1500); if (dib9000_firmware_post_pll_init(fe_slave) < 0) return -ENODEV; } @@ -2064,7 +2321,7 @@ static int dib7090p_get_best_sampling(struct dvb_frontend *fe , struct dib7090p_ return 0; } -static int dib7090_agc_startup(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) +static int dib7090_agc_startup(struct dvb_frontend *fe) { struct dvb_usb_adapter *adap = fe->dvb->priv; struct dib0700_adapter_state *state = adap->priv; @@ -2073,13 +2330,13 @@ static int dib7090_agc_startup(struct dvb_frontend *fe, struct dvb_frontend_para struct dib7090p_best_adc adc; int ret; - ret = state->set_param_save(fe, fep); + ret = state->set_param_save(fe); if (ret < 0) return ret; memset(&pll, 0, sizeof(struct dibx000_bandwidth_config)); dib0090_pwm_gain_reset(fe); - target = (dib0090_get_wbd_offset(fe) * 8 + 1) / 2; + target = (dib0090_get_wbd_target(fe) * 8 + 1) / 2; dib7000p_set_wbd_ref(fe, target); if (dib7090p_get_best_sampling(fe, &adc) == 0) { @@ -2092,6 +2349,49 @@ static int dib7090_agc_startup(struct dvb_frontend *fe, struct dvb_frontend_para return 0; } +static int dib7090_agc_restart(struct dvb_frontend *fe, u8 restart) +{ + deb_info("AGC restart callback: %d", restart); + if (restart == 0) /* before AGC startup */ + dib0090_set_dc_servo(fe, 1); + return 0; +} + +static int dib7090e_update_lna(struct dvb_frontend *fe, u16 agc_global) +{ + u16 agc1 = 0, agc2, wbd = 0, wbd_target, wbd_offset, threshold_agc1; + s16 wbd_delta; + + if ((fe->dtv_property_cache.frequency) < 400000000) + threshold_agc1 = 25000; + else + threshold_agc1 = 30000; + + wbd_target = (dib0090_get_wbd_target(fe)*8+1)/2; + wbd_offset = dib0090_get_wbd_offset(fe); + dib7000p_get_agc_values(fe, NULL, &agc1, &agc2, &wbd); + wbd_delta = (s16)wbd - (((s16)wbd_offset+10)*4) ; + + deb_info("update lna, agc_global=%d agc1=%d agc2=%d", + agc_global, agc1, agc2); + deb_info("update lna, wbd=%d wbd target=%d wbd offset=%d wbd delta=%d", + wbd, wbd_target, wbd_offset, wbd_delta); + + if ((agc1 < threshold_agc1) && (wbd_delta > 0)) { + dib0090_set_switch(fe, 1, 1, 1); + dib0090_set_vga(fe, 0); + dib0090_update_rframp_7090(fe, 0); + dib0090_update_tuning_table_7090(fe, 0); + } else { + dib0090_set_vga(fe, 1); + dib0090_update_rframp_7090(fe, 1); + dib0090_update_tuning_table_7090(fe, 1); + dib0090_set_switch(fe, 0, 0, 0); + } + + return 0; +} + static struct dib0090_wbd_slope dib7090_wbd_table[] = { { 380, 81, 850, 64, 540, 4}, { 860, 51, 866, 21, 375, 4}, @@ -2100,7 +2400,16 @@ static struct dib0090_wbd_slope dib7090_wbd_table[] = { { 0xFFFF, 0, 0, 0, 0, 0}, }; -struct dibx000_agc_config dib7090_agc_config[2] = { +static struct dib0090_wbd_slope dib7090e_wbd_table[] = { + { 380, 81, 850, 64, 540, 4}, + { 700, 51, 866, 21, 320, 4}, + { 860, 48, 666, 18, 330, 6}, + {1700, 0, 250, 0, 100, 6}, + {2600, 0, 250, 0, 100, 6}, + { 0xFFFF, 0, 0, 0, 0, 0}, +}; + +static struct dibx000_agc_config dib7090_agc_config[2] = { { .band_caps = BAND_UHF, /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, @@ -2278,6 +2587,34 @@ static struct dib7000p_config tfe7090pvr_dib7000p_config[2] = { } }; +static struct dib7000p_config tfe7090e_dib7000p_config = { + .output_mpeg2_in_188_bytes = 1, + .hostbus_diversity = 1, + .tuner_is_baseband = 1, + .update_lna = dib7090e_update_lna, + + .agc_config_count = 2, + .agc = dib7090_agc_config, + + .bw = &dib7090_clock_config_12_mhz, + + .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS, + .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES, + .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS, + + .pwm_freq_div = 0, + + .agc_control = dib7090_agc_restart, + + .spur_protect = 0, + .disable_sample_and_hold = 0, + .enable_current_mirror = 0, + .diversity_delay = 0, + + .output_mode = OUTMODE_MPEG2_FIFO, + .enMpegOutput = 1, +}; + static const struct dib0090_config nim7090_dib0090_config = { .io.clock_khz = 12000, .io.pll_bypass = 0, @@ -2312,6 +2649,107 @@ static const struct dib0090_config nim7090_dib0090_config = { .in_soc = 1, }; +static const struct dib0090_config tfe7090e_dib0090_config = { + .io.clock_khz = 12000, + .io.pll_bypass = 0, + .io.pll_range = 0, + .io.pll_prediv = 3, + .io.pll_loopdiv = 6, + .io.adc_clock_ratio = 0, + .io.pll_int_loop_filt = 0, + .reset = dib7090_tuner_sleep, + .sleep = dib7090_tuner_sleep, + + .freq_offset_khz_uhf = 0, + .freq_offset_khz_vhf = 0, + + .get_adc_power = dib7090_get_adc_power, + + .clkouttobamse = 1, + .analog_output = 0, + + .wbd_vhf_offset = 0, + .wbd_cband_offset = 0, + .use_pwm_agc = 1, + .clkoutdrive = 0, + + .fref_clock_ratio = 0, + + .wbd = dib7090e_wbd_table, + + .ls_cfg_pad_drv = 0, + .data_tx_drv = 0, + .low_if = NULL, + .in_soc = 1, + .force_cband_input = 1, + .is_dib7090e = 1, +}; + +static struct dib7000p_config tfe7790e_dib7000p_config = { + .output_mpeg2_in_188_bytes = 1, + .hostbus_diversity = 1, + .tuner_is_baseband = 1, + .update_lna = dib7090e_update_lna, + + .agc_config_count = 2, + .agc = dib7090_agc_config, + + .bw = &dib7090_clock_config_12_mhz, + + .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS, + .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES, + .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS, + + .pwm_freq_div = 0, + + .agc_control = dib7090_agc_restart, + + .spur_protect = 0, + .disable_sample_and_hold = 0, + .enable_current_mirror = 0, + .diversity_delay = 0, + + .output_mode = OUTMODE_MPEG2_PAR_GATED_CLK, + .enMpegOutput = 1, +}; + +static const struct dib0090_config tfe7790e_dib0090_config = { + .io.clock_khz = 12000, + .io.pll_bypass = 0, + .io.pll_range = 0, + .io.pll_prediv = 3, + .io.pll_loopdiv = 6, + .io.adc_clock_ratio = 0, + .io.pll_int_loop_filt = 0, + .reset = dib7090_tuner_sleep, + .sleep = dib7090_tuner_sleep, + + .freq_offset_khz_uhf = 0, + .freq_offset_khz_vhf = 0, + + .get_adc_power = dib7090_get_adc_power, + + .clkouttobamse = 1, + .analog_output = 0, + + .wbd_vhf_offset = 0, + .wbd_cband_offset = 0, + .use_pwm_agc = 1, + .clkoutdrive = 0, + + .fref_clock_ratio = 0, + + .wbd = dib7090e_wbd_table, + + .ls_cfg_pad_drv = 0, + .data_tx_drv = 0, + .low_if = NULL, + .in_soc = 1, + .force_cband_input = 1, + .is_dib7090e = 1, + .force_crystal_mode = 1, +}; + static const struct dib0090_config tfe7090pvr_dib0090_config[2] = { { .io.clock_khz = 12000, @@ -2504,6 +2942,97 @@ static int tfe7090pvr_tuner1_attach(struct dvb_usb_adapter *adap) return 0; } +static int tfe7090e_frontend_attach(struct dvb_usb_adapter *adap) +{ + dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); + msleep(20); + dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); + + msleep(20); + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); + msleep(20); + dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); + + if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, + 1, 0x10, &tfe7090e_dib7000p_config) != 0) { + err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", + __func__); + return -ENODEV; + } + adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, + 0x80, &tfe7090e_dib7000p_config); + + return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; +} + +static int tfe7790e_frontend_attach(struct dvb_usb_adapter *adap) +{ + struct dib0700_state *st = adap->dev->priv; + + /* The TFE7790E requires the dib0700 to not be in master mode */ + st->disable_streaming_master_mode = 1; + + dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); + msleep(20); + dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); + msleep(20); + dib0700_ctrl_clock(adap->dev, 72, 1); + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); + msleep(20); + dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); + + if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, + 1, 0x10, &tfe7790e_dib7000p_config) != 0) { + err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", + __func__); + return -ENODEV; + } + adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, + 0x80, &tfe7790e_dib7000p_config); + + return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; +} + +static int tfe7790e_tuner_attach(struct dvb_usb_adapter *adap) +{ + struct dib0700_adapter_state *st = adap->priv; + struct i2c_adapter *tun_i2c = + dib7090_get_i2c_tuner(adap->fe_adap[0].fe); + + if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, + &tfe7790e_dib0090_config) == NULL) + return -ENODEV; + + dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1); + + st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params; + adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7090_agc_startup; + return 0; +} + +static int tfe7090e_tuner_attach(struct dvb_usb_adapter *adap) +{ + struct dib0700_adapter_state *st = adap->priv; + struct i2c_adapter *tun_i2c = + dib7090_get_i2c_tuner(adap->fe_adap[0].fe); + + if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, + &tfe7090e_dib0090_config) == NULL) + return -ENODEV; + + dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1); + + st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params; + adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7090_agc_startup; + return 0; +} + /* STK7070PD */ static struct dib7000p_config stk7070pd_dib7000p_config[2] = { { @@ -2960,6 +3489,9 @@ struct usb_device_id dib0700_usb_id_table[] = { /* 75 */{ USB_DEVICE(USB_VID_MEDION, USB_PID_CREATIX_CTX1921) }, { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV340E) }, { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV340E_SE) }, + { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE7090E) }, + { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE7790E) }, +/* 80 */{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE8096P) }, { 0 } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); @@ -4025,6 +4557,127 @@ struct dvb_usb_device_properties dib0700_devices[] = { RC_TYPE_NEC, .change_protocol = dib0700_change_protocol, }, + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, + .num_adapters = 1, + .adapter = { + { + .num_frontends = 1, + .fe = {{ + .caps = DVB_USB_ADAP_HAS_PID_FILTER | + DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, + .pid_filter_count = 32, + .pid_filter = stk70x0p_pid_filter, + .pid_filter_ctrl = stk70x0p_pid_filter_ctrl, + .frontend_attach = tfe7090e_frontend_attach, + .tuner_attach = tfe7090e_tuner_attach, + + DIB0700_DEFAULT_STREAMING_CONFIG(0x02), + } }, + + .size_of_priv = + sizeof(struct dib0700_adapter_state), + }, + }, + + .num_device_descs = 1, + .devices = { + { "DiBcom TFE7090E reference design", + { &dib0700_usb_id_table[78], NULL }, + { NULL }, + }, + }, + + .rc.core = { + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_codes = RC_MAP_DIB0700_RC5_TABLE, + .module_name = "dib0700", + .rc_query = dib0700_rc_query_old_firmware, + .allowed_protos = RC_TYPE_RC5 | + RC_TYPE_RC6 | + RC_TYPE_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, + .num_adapters = 1, + .adapter = { + { + .num_frontends = 1, + .fe = {{ + .caps = DVB_USB_ADAP_HAS_PID_FILTER | + DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, + .pid_filter_count = 32, + .pid_filter = stk70x0p_pid_filter, + .pid_filter_ctrl = stk70x0p_pid_filter_ctrl, + .frontend_attach = tfe7790e_frontend_attach, + .tuner_attach = tfe7790e_tuner_attach, + + DIB0700_DEFAULT_STREAMING_CONFIG(0x03), + } }, + + .size_of_priv = + sizeof(struct dib0700_adapter_state), + }, + }, + + .num_device_descs = 1, + .devices = { + { "DiBcom TFE7790E reference design", + { &dib0700_usb_id_table[79], NULL }, + { NULL }, + }, + }, + + .rc.core = { + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_codes = RC_MAP_DIB0700_RC5_TABLE, + .module_name = "dib0700", + .rc_query = dib0700_rc_query_old_firmware, + .allowed_protos = RC_TYPE_RC5 | + RC_TYPE_RC6 | + RC_TYPE_NEC, + .change_protocol = dib0700_change_protocol, + }, + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, + .num_adapters = 1, + .adapter = { + { + .num_frontends = 1, + .fe = {{ + .caps = DVB_USB_ADAP_HAS_PID_FILTER | + DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, + .pid_filter_count = 32, + .pid_filter = stk80xx_pid_filter, + .pid_filter_ctrl = stk80xx_pid_filter_ctrl, + .frontend_attach = tfe8096p_frontend_attach, + .tuner_attach = tfe8096p_tuner_attach, + + DIB0700_DEFAULT_STREAMING_CONFIG(0x02), + + } }, + + .size_of_priv = + sizeof(struct dib0700_adapter_state), + }, + }, + + .num_device_descs = 1, + .devices = { + { "DiBcom TFE8096P reference design", + { &dib0700_usb_id_table[80], NULL }, + { NULL }, + }, + }, + + .rc.core = { + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_codes = RC_MAP_DIB0700_RC5_TABLE, + .module_name = "dib0700", + .rc_query = dib0700_rc_query_old_firmware, + .allowed_protos = RC_TYPE_RC5 | + RC_TYPE_RC6 | + RC_TYPE_NEC, + .change_protocol = dib0700_change_protocol, + }, }, }; diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c index 0a9a79820f26..ff34419a4c88 100644 --- a/drivers/media/dvb/dvb-usb/digitv.c +++ b/drivers/media/dvb/dvb-usb/digitv.c @@ -118,12 +118,12 @@ static struct mt352_config digitv_mt352_config = { .demod_init = digitv_mt352_demod_init, }; -static int digitv_nxt6000_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) +static int digitv_nxt6000_tuner_set_params(struct dvb_frontend *fe) { struct dvb_usb_adapter *adap = fe->dvb->priv; u8 b[5]; - fe->ops.tuner_ops.calc_regs(fe, fep, b, sizeof(b)); + fe->ops.tuner_ops.calc_regs(fe, b, sizeof(b)); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); return digitv_ctrl_msg(adap->dev, USB_WRITE_TUNER, 0, &b[1], 4, NULL, 0); diff --git a/drivers/media/dvb/dvb-usb/dtt200u-fe.c b/drivers/media/dvb/dvb-usb/dtt200u-fe.c index 17413adec7a1..3d81daa49172 100644 --- a/drivers/media/dvb/dvb-usb/dtt200u-fe.c +++ b/drivers/media/dvb/dvb-usb/dtt200u-fe.c @@ -16,7 +16,7 @@ struct dtt200u_fe_state { fe_status_t stat; - struct dvb_frontend_parameters fep; + struct dtv_frontend_properties fep; struct dvb_frontend frontend; }; @@ -100,22 +100,27 @@ static int dtt200u_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_fron return 0; } -static int dtt200u_fe_set_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) +static int dtt200u_fe_set_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *fep = &fe->dtv_property_cache; struct dtt200u_fe_state *state = fe->demodulator_priv; int i; fe_status_t st; u16 freq = fep->frequency / 250000; u8 bwbuf[2] = { SET_BANDWIDTH, 0 },freqbuf[3] = { SET_RF_FREQ, 0, 0 }; - switch (fep->u.ofdm.bandwidth) { - case BANDWIDTH_8_MHZ: bwbuf[1] = 8; break; - case BANDWIDTH_7_MHZ: bwbuf[1] = 7; break; - case BANDWIDTH_6_MHZ: bwbuf[1] = 6; break; - case BANDWIDTH_AUTO: return -EOPNOTSUPP; - default: - return -EINVAL; + switch (fep->bandwidth_hz) { + case 8000000: + bwbuf[1] = 8; + break; + case 7000000: + bwbuf[1] = 7; + break; + case 6000000: + bwbuf[1] = 6; + break; + default: + return -EINVAL; } dvb_usb_generic_write(state->d,bwbuf,2); @@ -134,11 +139,11 @@ static int dtt200u_fe_set_frontend(struct dvb_frontend* fe, return 0; } -static int dtt200u_fe_get_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) +static int dtt200u_fe_get_frontend(struct dvb_frontend* fe) { + struct dtv_frontend_properties *fep = &fe->dtv_property_cache; struct dtt200u_fe_state *state = fe->demodulator_priv; - memcpy(fep,&state->fep,sizeof(struct dvb_frontend_parameters)); + memcpy(fep, &state->fep, sizeof(struct dtv_frontend_properties)); return 0; } @@ -172,9 +177,9 @@ error: } static struct dvb_frontend_ops dtt200u_fe_ops = { + .delsys = { SYS_DVBT }, .info = { .name = "WideView USB DVB-T", - .type = FE_OFDM, .frequency_min = 44250000, .frequency_max = 867250000, .frequency_stepsize = 250000, diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c index ba4a7517354f..ddf282f355b3 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c @@ -141,11 +141,17 @@ int dvb_usb_adapter_dvb_init(struct dvb_usb_adapter *adap, short *adapter_nums) goto err_dmx_dev; } - dvb_net_init(&adap->dvb_adap, &adap->dvb_net, &adap->demux.dmx); + if ((ret = dvb_net_init(&adap->dvb_adap, &adap->dvb_net, + &adap->demux.dmx)) < 0) { + err("dvb_net_init failed: error %d",ret); + goto err_net_init; + } adap->state |= DVB_USB_ADAP_STATE_DVB; return 0; +err_net_init: + dvb_dmxdev_release(&adap->dmxdev); err_dmx_dev: dvb_dmx_release(&adap->demux); err_dmx: diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 2d08c9b5128a..d390ddaa5a53 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -109,10 +109,13 @@ #define USB_PID_DIBCOM_STK807XPVR 0x1f98 #define USB_PID_DIBCOM_STK8096GP 0x1fa0 #define USB_PID_DIBCOM_NIM8096MD 0x1fa8 +#define USB_PID_DIBCOM_TFE8096P 0x1f9C #define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131 #define USB_PID_DIBCOM_STK7770P 0x1e80 #define USB_PID_DIBCOM_NIM7090 0x1bb2 #define USB_PID_DIBCOM_TFE7090PVR 0x1bb4 +#define USB_PID_DIBCOM_TFE7090E 0x1bb7 +#define USB_PID_DIBCOM_TFE7790E 0x1e6e #define USB_PID_DIBCOM_NIM9090M 0x2383 #define USB_PID_DIBCOM_NIM9090MD 0x2384 #define USB_PID_DPOSH_M9206_COLD 0x9206 @@ -128,6 +131,8 @@ #define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1 #define USB_PID_INTEL_CE9500 0x9500 #define USB_PID_ITETECH_IT9135 0x9135 +#define USB_PID_ITETECH_IT9135_9005 0x9005 +#define USB_PID_ITETECH_IT9135_9006 0x9006 #define USB_PID_KWORLD_399U 0xe399 #define USB_PID_KWORLD_399U_2 0xe400 #define USB_PID_KWORLD_395U 0xe396 @@ -322,6 +327,7 @@ #define USB_PID_TVWAY_PLUS 0x0002 #define USB_PID_SVEON_STV20 0xe39d #define USB_PID_SVEON_STV22 0xe401 +#define USB_PID_SVEON_STV22_IT9137 0xe411 #define USB_PID_AZUREWAVE_AZ6027 0x3275 #define USB_PID_TERRATEC_DVBS2CI_V1 0x10a4 #define USB_PID_TERRATEC_DVBS2CI_V2 0x10ac diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c index ff941d20e6b7..451c5a7adfb2 100644 --- a/drivers/media/dvb/dvb-usb/dw2102.c +++ b/drivers/media/dvb/dvb-usb/dw2102.c @@ -1435,22 +1435,40 @@ static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state) return 0; } +enum dw2102_table_entry { + CYPRESS_DW2102, + CYPRESS_DW2101, + CYPRESS_DW2104, + TEVII_S650, + TERRATEC_CINERGY_S, + CYPRESS_DW3101, + TEVII_S630, + PROF_1100, + TEVII_S660, + PROF_7500, + GENIATECH_SU3000, + TERRATEC_CINERGY_S2, + TEVII_S480_1, + TEVII_S480_2, + X3M_SPC1400HD, +}; + static struct usb_device_id dw2102_table[] = { - {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2102)}, - {USB_DEVICE(USB_VID_CYPRESS, 0x2101)}, - {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2104)}, - {USB_DEVICE(0x9022, USB_PID_TEVII_S650)}, - {USB_DEVICE(USB_VID_TERRATEC, USB_PID_CINERGY_S)}, - {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW3101)}, - {USB_DEVICE(0x9022, USB_PID_TEVII_S630)}, - {USB_DEVICE(0x3011, USB_PID_PROF_1100)}, - {USB_DEVICE(0x9022, USB_PID_TEVII_S660)}, - {USB_DEVICE(0x3034, 0x7500)}, - {USB_DEVICE(0x1f4d, 0x3000)}, - {USB_DEVICE(USB_VID_TERRATEC, 0x00a8)}, - {USB_DEVICE(0x9022, USB_PID_TEVII_S480_1)}, - {USB_DEVICE(0x9022, USB_PID_TEVII_S480_2)}, - {USB_DEVICE(0x1f4d, 0x3100)}, + [CYPRESS_DW2102] = {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2102)}, + [CYPRESS_DW2101] = {USB_DEVICE(USB_VID_CYPRESS, 0x2101)}, + [CYPRESS_DW2104] = {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2104)}, + [TEVII_S650] = {USB_DEVICE(0x9022, USB_PID_TEVII_S650)}, + [TERRATEC_CINERGY_S] = {USB_DEVICE(USB_VID_TERRATEC, USB_PID_CINERGY_S)}, + [CYPRESS_DW3101] = {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW3101)}, + [TEVII_S630] = {USB_DEVICE(0x9022, USB_PID_TEVII_S630)}, + [PROF_1100] = {USB_DEVICE(0x3011, USB_PID_PROF_1100)}, + [TEVII_S660] = {USB_DEVICE(0x9022, USB_PID_TEVII_S660)}, + [PROF_7500] = {USB_DEVICE(0x3034, 0x7500)}, + [GENIATECH_SU3000] = {USB_DEVICE(0x1f4d, 0x3000)}, + [TERRATEC_CINERGY_S2] = {USB_DEVICE(USB_VID_TERRATEC, 0x00a8)}, + [TEVII_S480_1] = {USB_DEVICE(0x9022, USB_PID_TEVII_S480_1)}, + [TEVII_S480_2] = {USB_DEVICE(0x9022, USB_PID_TEVII_S480_2)}, + [X3M_SPC1400HD] = {USB_DEVICE(0x1f4d, 0x3100)}, { } }; @@ -1610,15 +1628,15 @@ static struct dvb_usb_device_properties dw2102_properties = { .num_device_descs = 3, .devices = { {"DVBWorld DVB-S 2102 USB2.0", - {&dw2102_table[0], NULL}, + {&dw2102_table[CYPRESS_DW2102], NULL}, {NULL}, }, {"DVBWorld DVB-S 2101 USB2.0", - {&dw2102_table[1], NULL}, + {&dw2102_table[CYPRESS_DW2101], NULL}, {NULL}, }, {"TerraTec Cinergy S USB", - {&dw2102_table[4], NULL}, + {&dw2102_table[TERRATEC_CINERGY_S], NULL}, {NULL}, }, } @@ -1664,11 +1682,11 @@ static struct dvb_usb_device_properties dw2104_properties = { .num_device_descs = 2, .devices = { { "DVBWorld DW2104 USB2.0", - {&dw2102_table[2], NULL}, + {&dw2102_table[CYPRESS_DW2104], NULL}, {NULL}, }, { "TeVii S650 USB2.0", - {&dw2102_table[3], NULL}, + {&dw2102_table[TEVII_S650], NULL}, {NULL}, }, } @@ -1715,7 +1733,7 @@ static struct dvb_usb_device_properties dw3101_properties = { .num_device_descs = 1, .devices = { { "DVBWorld DVB-C 3101 USB2.0", - {&dw2102_table[5], NULL}, + {&dw2102_table[CYPRESS_DW3101], NULL}, {NULL}, }, } @@ -1761,7 +1779,7 @@ static struct dvb_usb_device_properties s6x0_properties = { .num_device_descs = 1, .devices = { {"TeVii S630 USB", - {&dw2102_table[6], NULL}, + {&dw2102_table[TEVII_S630], NULL}, {NULL}, }, } @@ -1770,33 +1788,33 @@ static struct dvb_usb_device_properties s6x0_properties = { struct dvb_usb_device_properties *p1100; static struct dvb_usb_device_description d1100 = { "Prof 1100 USB ", - {&dw2102_table[7], NULL}, + {&dw2102_table[PROF_1100], NULL}, {NULL}, }; struct dvb_usb_device_properties *s660; static struct dvb_usb_device_description d660 = { "TeVii S660 USB", - {&dw2102_table[8], NULL}, + {&dw2102_table[TEVII_S660], NULL}, {NULL}, }; static struct dvb_usb_device_description d480_1 = { "TeVii S480.1 USB", - {&dw2102_table[12], NULL}, + {&dw2102_table[TEVII_S480_1], NULL}, {NULL}, }; static struct dvb_usb_device_description d480_2 = { "TeVii S480.2 USB", - {&dw2102_table[13], NULL}, + {&dw2102_table[TEVII_S480_2], NULL}, {NULL}, }; struct dvb_usb_device_properties *p7500; static struct dvb_usb_device_description d7500 = { "Prof 7500 USB DVB-S2", - {&dw2102_table[9], NULL}, + {&dw2102_table[PROF_7500], NULL}, {NULL}, }; @@ -1842,15 +1860,15 @@ static struct dvb_usb_device_properties su3000_properties = { .num_device_descs = 3, .devices = { { "SU3000HD DVB-S USB2.0", - { &dw2102_table[10], NULL }, + { &dw2102_table[GENIATECH_SU3000], NULL }, { NULL }, }, { "Terratec Cinergy S2 USB HD", - { &dw2102_table[11], NULL }, + { &dw2102_table[TERRATEC_CINERGY_S2], NULL }, { NULL }, }, { "X3M TV SPC1400HD PCI", - { &dw2102_table[14], NULL }, + { &dw2102_table[X3M_SPC1400HD], NULL }, { NULL }, }, } @@ -1859,12 +1877,11 @@ static struct dvb_usb_device_properties su3000_properties = { static int dw2102_probe(struct usb_interface *intf, const struct usb_device_id *id) { - p1100 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL); + p1100 = kmemdup(&s6x0_properties, + sizeof(struct dvb_usb_device_properties), GFP_KERNEL); if (!p1100) return -ENOMEM; /* copy default structure */ - memcpy(p1100, &s6x0_properties, - sizeof(struct dvb_usb_device_properties)); /* fill only different fields */ p1100->firmware = "dvb-usb-p1100.fw"; p1100->devices[0] = d1100; @@ -1872,13 +1889,12 @@ static int dw2102_probe(struct usb_interface *intf, p1100->rc.legacy.rc_map_size = ARRAY_SIZE(rc_map_tbs_table); p1100->adapter->fe[0].frontend_attach = stv0288_frontend_attach; - s660 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL); + s660 = kmemdup(&s6x0_properties, + sizeof(struct dvb_usb_device_properties), GFP_KERNEL); if (!s660) { kfree(p1100); return -ENOMEM; } - memcpy(s660, &s6x0_properties, - sizeof(struct dvb_usb_device_properties)); s660->firmware = "dvb-usb-s660.fw"; s660->num_device_descs = 3; s660->devices[0] = d660; @@ -1886,14 +1902,13 @@ static int dw2102_probe(struct usb_interface *intf, s660->devices[2] = d480_2; s660->adapter->fe[0].frontend_attach = ds3000_frontend_attach; - p7500 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL); + p7500 = kmemdup(&s6x0_properties, + sizeof(struct dvb_usb_device_properties), GFP_KERNEL); if (!p7500) { kfree(p1100); kfree(s660); return -ENOMEM; } - memcpy(p7500, &s6x0_properties, - sizeof(struct dvb_usb_device_properties)); p7500->firmware = "dvb-usb-p7500.fw"; p7500->devices[0] = d7500; p7500->rc.legacy.rc_map_table = rc_map_tbs_table; diff --git a/drivers/media/dvb/dvb-usb/friio-fe.c b/drivers/media/dvb/dvb-usb/friio-fe.c index 015b4e8af1a5..90a70c66a96e 100644 --- a/drivers/media/dvb/dvb-usb/friio-fe.c +++ b/drivers/media/dvb/dvb-usb/friio-fe.c @@ -282,23 +282,24 @@ static int jdvbt90502_set_property(struct dvb_frontend *fe, return r; } -static int jdvbt90502_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int jdvbt90502_get_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; p->inversion = INVERSION_AUTO; - p->u.ofdm.bandwidth = BANDWIDTH_6_MHZ; - p->u.ofdm.code_rate_HP = FEC_AUTO; - p->u.ofdm.code_rate_LP = FEC_AUTO; - p->u.ofdm.constellation = QAM_64; - p->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO; - p->u.ofdm.guard_interval = GUARD_INTERVAL_AUTO; - p->u.ofdm.hierarchy_information = HIERARCHY_AUTO; + p->bandwidth_hz = 6000000; + p->code_rate_HP = FEC_AUTO; + p->code_rate_LP = FEC_AUTO; + p->modulation = QAM_64; + p->transmission_mode = TRANSMISSION_MODE_AUTO; + p->guard_interval = GUARD_INTERVAL_AUTO; + p->hierarchy = HIERARCHY_AUTO; return 0; } -static int jdvbt90502_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int jdvbt90502_set_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; + /** * NOTE: ignore all the parameters except frequency. * others should be fixed to the proper value for ISDB-T, @@ -438,14 +439,12 @@ error: } static struct dvb_frontend_ops jdvbt90502_ops = { - + .delsys = { SYS_ISDBT }, .info = { .name = "Comtech JDVBT90502 ISDB-T", - .type = FE_OFDM, .frequency_min = 473000000, /* UHF 13ch, center */ .frequency_max = 767142857, /* UHF 62ch, center */ - .frequency_stepsize = JDVBT90502_PLL_CLK / - JDVBT90502_PLL_DIVIDER, + .frequency_stepsize = JDVBT90502_PLL_CLK / JDVBT90502_PLL_DIVIDER, .frequency_tolerance = 0, /* NOTE: this driver ignores all parameters but frequency. */ diff --git a/drivers/media/dvb/dvb-usb/gp8psk-fe.c b/drivers/media/dvb/dvb-usb/gp8psk-fe.c index 5426267980c7..67957dd99ede 100644 --- a/drivers/media/dvb/dvb-usb/gp8psk-fe.c +++ b/drivers/media/dvb/dvb-usb/gp8psk-fe.c @@ -113,28 +113,12 @@ static int gp8psk_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_front return 0; } -static int gp8psk_fe_set_property(struct dvb_frontend *fe, - struct dtv_property *tvp) -{ - deb_fe("%s(..)\n", __func__); - return 0; -} - -static int gp8psk_fe_get_property(struct dvb_frontend *fe, - struct dtv_property *tvp) -{ - deb_fe("%s(..)\n", __func__); - return 0; -} - - -static int gp8psk_fe_set_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) +static int gp8psk_fe_set_frontend(struct dvb_frontend *fe) { struct gp8psk_fe_state *state = fe->demodulator_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache; u8 cmd[10]; - u32 freq = fep->frequency * 1000; + u32 freq = c->frequency * 1000; int gp_product_id = le16_to_cpu(state->d->udev->descriptor.idProduct); deb_fe("%s()\n", __func__); @@ -342,9 +326,9 @@ success: static struct dvb_frontend_ops gp8psk_fe_ops = { + .delsys = { SYS_DVBS }, .info = { .name = "Genpix DVB-S", - .type = FE_QPSK, .frequency_min = 800000, .frequency_max = 2250000, .frequency_stepsize = 100, @@ -366,8 +350,6 @@ static struct dvb_frontend_ops gp8psk_fe_ops = { .init = NULL, .sleep = NULL, - .set_property = gp8psk_fe_set_property, - .get_property = gp8psk_fe_get_property, .set_frontend = gp8psk_fe_set_frontend, .get_tune_settings = gp8psk_fe_get_tune_settings, diff --git a/drivers/media/dvb/dvb-usb/it913x.c b/drivers/media/dvb/dvb-usb/it913x.c index 67094b879bb4..9f01cd7a6e3f 100644 --- a/drivers/media/dvb/dvb-usb/it913x.c +++ b/drivers/media/dvb/dvb-usb/it913x.c @@ -52,42 +52,59 @@ static int pid_filter; module_param_named(pid, pid_filter, int, 0644); MODULE_PARM_DESC(pid, "set default 0=on 1=off"); +static int dvb_usb_it913x_firmware; +module_param_named(firmware, dvb_usb_it913x_firmware, int, 0644); +MODULE_PARM_DESC(firmware, "set firmware 0=auto 1=IT9137 2=IT9135V1"); + + int cmd_counter; DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); struct it913x_state { u8 id; -}; - -struct ite_config { - u8 chip_ver; - u16 chip_type; - u32 firmware; - u8 tuner_id_0; - u8 tuner_id_1; - u8 dual_mode; + struct ite_config it913x_config; }; struct ite_config it913x_config; +#define IT913X_RETRY 10 +#define IT913X_SND_TIMEOUT 100 +#define IT913X_RCV_TIMEOUT 200 + static int it913x_bulk_write(struct usb_device *dev, u8 *snd, int len, u8 pipe) { - int ret, actual_l; + int ret, actual_l, i; + + for (i = 0; i < IT913X_RETRY; i++) { + ret = usb_bulk_msg(dev, usb_sndbulkpipe(dev, pipe), + snd, len , &actual_l, IT913X_SND_TIMEOUT); + if (ret == 0 || ret != -EBUSY || ret != -ETIMEDOUT) + break; + } + + if (len != actual_l && ret == 0) + ret = -EAGAIN; - ret = usb_bulk_msg(dev, usb_sndbulkpipe(dev, pipe), - snd, len , &actual_l, 100); return ret; } static int it913x_bulk_read(struct usb_device *dev, u8 *rev, int len, u8 pipe) { - int ret, actual_l; + int ret, actual_l, i; + + for (i = 0; i < IT913X_RETRY; i++) { + ret = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, pipe), + rev, len , &actual_l, IT913X_RCV_TIMEOUT); + if (ret == 0 || ret != -EBUSY || ret != -ETIMEDOUT) + break; + } + + if (len != actual_l && ret == 0) + ret = -EAGAIN; - ret = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, pipe), - rev, len , &actual_l, 200); return ret; } @@ -100,7 +117,7 @@ static u16 check_sum(u8 *p, u8 len) return ~sum; } -static int it913x_io(struct usb_device *udev, u8 mode, u8 pro, +static int it913x_usb_talk(struct usb_device *udev, u8 mode, u8 pro, u8 cmd, u32 reg, u8 addr, u8 *data, u8 len) { int ret = 0, i, buf_size = 1; @@ -159,22 +176,41 @@ static int it913x_io(struct usb_device *udev, u8 mode, u8 pro, buff[buf_size++] = (chk_sum & 0xff); ret = it913x_bulk_write(udev, buff, buf_size , 0x02); + if (ret < 0) + goto error; - ret |= it913x_bulk_read(udev, buff, (mode & 1) ? + ret = it913x_bulk_read(udev, buff, (mode & 1) ? 5 : len + 5 , 0x01); + if (ret < 0) + goto error; rlen = (mode & 0x1) ? 0x1 : len; if (mode & 1) - ret |= buff[2]; + ret = buff[2]; else memcpy(data, &buff[3], rlen); cmd_counter++; - kfree(buff); +error: kfree(buff); - return (ret < 0) ? -ENODEV : 0; + return ret; +} + +static int it913x_io(struct usb_device *udev, u8 mode, u8 pro, + u8 cmd, u32 reg, u8 addr, u8 *data, u8 len) +{ + int ret, i; + + for (i = 0; i < IT913X_RETRY; i++) { + ret = it913x_usb_talk(udev, mode, pro, + cmd, reg, addr, data, len); + if (ret != -EAGAIN) + break; + } + + return ret; } static int it913x_wr_reg(struct usb_device *udev, u8 pro, u32 reg , u8 data) @@ -223,15 +259,15 @@ static u32 it913x_query(struct usb_device *udev, u8 pro) static int it913x_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff) { - int ret = 0; + struct usb_device *udev = adap->dev->udev; + int ret; u8 pro = (adap->id == 0) ? DEV_0_DMOD : DEV_1_DMOD; if (mutex_lock_interruptible(&adap->dev->i2c_mutex) < 0) return -EAGAIN; deb_info(1, "PID_C (%02x)", onoff); - if (!onoff) - ret = it913x_wr_reg(adap->dev->udev, pro, PID_RST, 0x1); + ret = it913x_wr_reg(udev, pro, PID_EN, onoff); mutex_unlock(&adap->dev->i2c_mutex); return ret; @@ -241,27 +277,20 @@ static int it913x_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, int onoff) { struct usb_device *udev = adap->dev->udev; - int ret = 0; + int ret; u8 pro = (adap->id == 0) ? DEV_0_DMOD : DEV_1_DMOD; - if (pid_filter > 0) - return 0; - if (mutex_lock_interruptible(&adap->dev->i2c_mutex) < 0) return -EAGAIN; deb_info(1, "PID_F (%02x)", onoff); - if (onoff) { - ret = it913x_wr_reg(udev, pro, PID_EN, 0x1); - - ret |= it913x_wr_reg(udev, pro, PID_LSB, (u8)(pid & 0xff)); - ret |= it913x_wr_reg(udev, pro, PID_MSB, (u8)(pid >> 8)); + ret = it913x_wr_reg(udev, pro, PID_LSB, (u8)(pid & 0xff)); - ret |= it913x_wr_reg(udev, pro, PID_INX_EN, (u8)onoff); + ret |= it913x_wr_reg(udev, pro, PID_MSB, (u8)(pid >> 8)); - ret |= it913x_wr_reg(udev, pro, PID_INX, (u8)(index & 0x1f)); + ret |= it913x_wr_reg(udev, pro, PID_INX_EN, (u8)onoff); - } + ret |= it913x_wr_reg(udev, pro, PID_INX, (u8)(index & 0x1f)); mutex_unlock(&adap->dev->i2c_mutex); return 0; @@ -337,15 +366,73 @@ static int it913x_rc_query(struct dvb_usb_device *d) if ((ibuf[2] + ibuf[3]) == 0xff) { key = ibuf[2]; - key += ibuf[0] << 8; - deb_info(1, "INT Key =%08x", key); + key += ibuf[0] << 16; + key += ibuf[1] << 8; + deb_info(1, "NEC Extended Key =%08x", key); if (d->rc_dev != NULL) rc_keydown(d->rc_dev, key, 0); } + mutex_unlock(&d->i2c_mutex); return ret; } + +/* Firmware sets raw */ +const char fw_it9135_v1[] = "dvb-usb-it9135-01.fw"; +const char fw_it9135_v2[] = "dvb-usb-it9135-02.fw"; +const char fw_it9137[] = "dvb-usb-it9137-01.fw"; + +static int ite_firmware_select(struct usb_device *udev, + struct dvb_usb_device_properties *props) +{ + int sw; + /* auto switch */ + if (le16_to_cpu(udev->descriptor.idProduct) == + USB_PID_ITETECH_IT9135) + sw = IT9135_V1_FW; + else if (le16_to_cpu(udev->descriptor.idProduct) == + USB_PID_ITETECH_IT9135_9005) + sw = IT9135_V1_FW; + else if (le16_to_cpu(udev->descriptor.idProduct) == + USB_PID_ITETECH_IT9135_9006) { + sw = IT9135_V2_FW; + if (it913x_config.tuner_id_0 == 0) + it913x_config.tuner_id_0 = IT9135_60; + } else + sw = IT9137_FW; + + /* force switch */ + if (dvb_usb_it913x_firmware != IT9135_AUTO) + sw = dvb_usb_it913x_firmware; + + switch (sw) { + case IT9135_V1_FW: + it913x_config.firmware_ver = 1; + it913x_config.adc_x2 = 1; + props->firmware = fw_it9135_v1; + break; + case IT9135_V2_FW: + it913x_config.firmware_ver = 1; + it913x_config.adc_x2 = 1; + props->firmware = fw_it9135_v2; + break; + case IT9137_FW: + default: + it913x_config.firmware_ver = 0; + it913x_config.adc_x2 = 0; + props->firmware = fw_it9137; + } + + return 0; +} + +#define TS_MPEG_PKT_SIZE 188 +#define EP_LOW 21 +#define TS_BUFFER_SIZE_PID (EP_LOW*TS_MPEG_PKT_SIZE) +#define EP_HIGH 348 +#define TS_BUFFER_SIZE_MAX (EP_HIGH*TS_MPEG_PKT_SIZE) + static int it913x_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props, struct dvb_usb_device_description **desc, @@ -359,6 +446,19 @@ static int it913x_identify_state(struct usb_device *udev, /* checnk for dual mode */ it913x_config.dual_mode = it913x_read_reg(udev, 0x49c5); + if (udev->speed != USB_SPEED_HIGH) { + props->adapter[0].fe[0].pid_filter_count = 5; + info("USB 1 low speed mode - connect to USB 2 port"); + if (pid_filter > 0) + pid_filter = 0; + if (it913x_config.dual_mode) { + it913x_config.dual_mode = 0; + info("Dual mode not supported in USB 1"); + } + } else /* For replugging */ + if(props->adapter[0].fe[0].pid_filter_count == 5) + props->adapter[0].fe[0].pid_filter_count = 31; + /* TODO different remotes */ remote = it913x_read_reg(udev, 0x49ac); /* Remote */ if (remote == 0) @@ -370,6 +470,28 @@ static int it913x_identify_state(struct usb_device *udev, info("Dual mode=%x Remote=%x Tuner Type=%x", it913x_config.dual_mode , remote, it913x_config.tuner_id_0); + /* Select Stream Buffer Size and pid filter option*/ + if (pid_filter) { + props->adapter[0].fe[0].stream.u.bulk.buffersize = + TS_BUFFER_SIZE_MAX; + props->adapter[0].fe[0].caps &= + ~DVB_USB_ADAP_NEED_PID_FILTERING; + } else + props->adapter[0].fe[0].stream.u.bulk.buffersize = + TS_BUFFER_SIZE_PID; + + if (it913x_config.dual_mode) { + props->adapter[1].fe[0].stream.u.bulk.buffersize = + props->adapter[0].fe[0].stream.u.bulk.buffersize; + props->num_adapters = 2; + if (pid_filter) + props->adapter[1].fe[0].caps = + props->adapter[0].fe[0].caps; + } else + props->num_adapters = 1; + + ret = ite_firmware_select(udev, props); + if (firm_no > 0) { *cold = 0; return 0; @@ -391,18 +513,22 @@ static int it913x_identify_state(struct usb_device *udev, ret = it913x_wr_reg(udev, DEV_0, GPIOH1_O, 0x0); } - props->num_adapters = 2; - } else - props->num_adapters = 1; + } reg = it913x_read_reg(udev, IO_MUX_POWER_CLK); if (it913x_config.dual_mode) { ret |= it913x_wr_reg(udev, DEV_0, 0x4bfb, CHIP2_I2C_ADDR); - ret |= it913x_wr_reg(udev, DEV_0, CLK_O_EN, 0x1); + if (it913x_config.firmware_ver == 1) + ret |= it913x_wr_reg(udev, DEV_0, 0xcfff, 0x1); + else + ret |= it913x_wr_reg(udev, DEV_0, CLK_O_EN, 0x1); } else { ret |= it913x_wr_reg(udev, DEV_0, 0x4bfb, 0x0); - ret |= it913x_wr_reg(udev, DEV_0, CLK_O_EN, 0x0); + if (it913x_config.firmware_ver == 1) + ret |= it913x_wr_reg(udev, DEV_0, 0xcfff, 0x0); + else + ret |= it913x_wr_reg(udev, DEV_0, CLK_O_EN, 0x0); } *cold = 1; @@ -428,35 +554,45 @@ static int it913x_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) return ret; } - static int it913x_download_firmware(struct usb_device *udev, const struct firmware *fw) { - int ret = 0, i; - u8 packet_size, dlen; + int ret = 0, i = 0, pos = 0; + u8 packet_size, min_pkt; u8 *fw_data; - packet_size = 0x29; - ret = it913x_wr_reg(udev, DEV_0, I2C_CLK, I2C_CLK_100); info("FRM Starting Firmware Download"); - /* This uses scatter write firmware headers follow */ - /* 03 XX 00 XX = chip number? */ - - for (i = 0; i < fw->size; i += packet_size) { - if (i > 0) - packet_size = 0x39; - fw_data = (u8 *)(fw->data + i); - dlen = ((i + packet_size) > fw->size) - ? (fw->size - i) : packet_size; - ret |= it913x_io(udev, WRITE_DATA, DEV_0, - CMD_SCATTER_WRITE, 0, 0, fw_data, dlen); - udelay(1000); + + /* Multi firmware loader */ + /* This uses scatter write firmware headers */ + /* The firmware must start with 03 XX 00 */ + /* and be the extact firmware length */ + + if (it913x_config.chip_ver == 2) + min_pkt = 0x11; + else + min_pkt = 0x19; + + while (i <= fw->size) { + if (((fw->data[i] == 0x3) && (fw->data[i + 2] == 0x0)) + || (i == fw->size)) { + packet_size = i - pos; + if ((packet_size > min_pkt) || (i == fw->size)) { + fw_data = (u8 *)(fw->data + pos); + pos += packet_size; + if (packet_size > 0) + ret |= it913x_io(udev, WRITE_DATA, + DEV_0, CMD_SCATTER_WRITE, 0, + 0, fw_data, packet_size); + udelay(1000); + } + } + i++; } - ret |= it913x_io(udev, WRITE_CMD, DEV_0, - CMD_BOOT, 0, 0, NULL, 0); + ret |= it913x_io(udev, WRITE_CMD, DEV_0, CMD_BOOT, 0, 0, NULL, 0); msleep(100); @@ -474,12 +610,17 @@ static int it913x_download_firmware(struct usb_device *udev, /* Tuner function */ if (it913x_config.dual_mode) ret |= it913x_wr_reg(udev, DEV_0_DMOD , 0xec4c, 0xa0); - - ret |= it913x_wr_reg(udev, DEV_0, PADODPU, 0x0); - ret |= it913x_wr_reg(udev, DEV_0, AGC_O_D, 0x0); - if (it913x_config.dual_mode) { - ret |= it913x_wr_reg(udev, DEV_1, PADODPU, 0x0); - ret |= it913x_wr_reg(udev, DEV_1, AGC_O_D, 0x0); + else + ret |= it913x_wr_reg(udev, DEV_0_DMOD , 0xec4c, 0x68); + + if ((it913x_config.chip_ver == 1) && + (it913x_config.chip_type == 0x9135)) { + ret |= it913x_wr_reg(udev, DEV_0, PADODPU, 0x0); + ret |= it913x_wr_reg(udev, DEV_0, AGC_O_D, 0x0); + if (it913x_config.dual_mode) { + ret |= it913x_wr_reg(udev, DEV_1, PADODPU, 0x0); + ret |= it913x_wr_reg(udev, DEV_1, AGC_O_D, 0x0); + } } return (ret < 0) ? -ENODEV : 0; @@ -500,32 +641,23 @@ static int it913x_name(struct dvb_usb_adapter *adap) static int it913x_frontend_attach(struct dvb_usb_adapter *adap) { struct usb_device *udev = adap->dev->udev; + struct it913x_state *st = adap->dev->priv; int ret = 0; - u8 adf = it913x_read_reg(udev, IO_MUX_POWER_CLK); u8 adap_addr = I2C_BASE_ADDR + (adap->id << 5); - u16 ep_size = adap->props.fe[0].stream.u.bulk.buffersize; - u8 tuner_id, tuner_type; + u16 ep_size = adap->props.fe[0].stream.u.bulk.buffersize / 4; + u8 pkt_size = 0x80; + + if (adap->dev->udev->speed != USB_SPEED_HIGH) + pkt_size = 0x10; + + it913x_config.adf = it913x_read_reg(udev, IO_MUX_POWER_CLK); if (adap->id == 0) - tuner_id = it913x_config.tuner_id_0; - else - tuner_id = it913x_config.tuner_id_1; - - /* TODO we always use IT9137 possible references here*/ - /* Documentation suggests don't care */ - switch (tuner_id) { - case 0x51: - case 0x52: - case 0x60: - case 0x61: - case 0x62: - default: - case 0x38: - tuner_type = IT9137; - } + memcpy(&st->it913x_config, &it913x_config, + sizeof(struct ite_config)); adap->fe_adap[0].fe = dvb_attach(it913x_fe_attach, - &adap->dev->i2c_adap, adap_addr, adf, tuner_type); + &adap->dev->i2c_adap, adap_addr, &st->it913x_config); if (adap->id == 0 && adap->fe_adap[0].fe) { ret = it913x_wr_reg(udev, DEV_0_DMOD, MP2_SW_RST, 0x1); @@ -536,13 +668,13 @@ static int it913x_frontend_attach(struct dvb_usb_adapter *adap) ret = it913x_wr_reg(udev, DEV_0, EP4_TX_LEN_LSB, ep_size & 0xff); ret = it913x_wr_reg(udev, DEV_0, EP4_TX_LEN_MSB, ep_size >> 8); - ret = it913x_wr_reg(udev, DEV_0, EP4_MAX_PKT, 0x80); + ret = it913x_wr_reg(udev, DEV_0, EP4_MAX_PKT, pkt_size); } else if (adap->id == 1 && adap->fe_adap[0].fe) { ret = it913x_wr_reg(udev, DEV_0, EP0_TX_EN, 0x6f); ret = it913x_wr_reg(udev, DEV_0, EP5_TX_LEN_LSB, ep_size & 0xff); ret = it913x_wr_reg(udev, DEV_0, EP5_TX_LEN_MSB, ep_size >> 8); - ret = it913x_wr_reg(udev, DEV_0, EP5_MAX_PKT, 0x80); + ret = it913x_wr_reg(udev, DEV_0, EP5_MAX_PKT, pkt_size); ret = it913x_wr_reg(udev, DEV_0_DMOD, MP2IF2_EN, 0x1); ret = it913x_wr_reg(udev, DEV_1_DMOD, MP2IF_SERIAL, 0x1); ret = it913x_wr_reg(udev, DEV_1, TOP_HOSTB_SER_MODE, 0x1); @@ -582,6 +714,9 @@ static int it913x_probe(struct usb_interface *intf, static struct usb_device_id it913x_table[] = { { USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB499_2T_T09) }, { USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135) }, + { USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV22_IT9137) }, + { USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135_9005) }, + { USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135_9006) }, {} /* Terminating entry */ }; @@ -614,8 +749,8 @@ static struct dvb_usb_device_properties it913x_properties = { .endpoint = 0x04, .u = {/* Keep Low if PID filter on */ .bulk = { - .buffersize = 3584, - + .buffersize = + TS_BUFFER_SIZE_PID, } } } @@ -639,8 +774,8 @@ static struct dvb_usb_device_properties it913x_properties = { .endpoint = 0x05, .u = { .bulk = { - .buffersize = 3584, - + .buffersize = + TS_BUFFER_SIZE_PID, } } } @@ -654,10 +789,10 @@ static struct dvb_usb_device_properties it913x_properties = { .rc_query = it913x_rc_query, .rc_interval = IT913X_POLL, .allowed_protos = RC_TYPE_NEC, - .rc_codes = RC_MAP_KWORLD_315U, + .rc_codes = RC_MAP_MSI_DIGIVOX_III, }, .i2c_algo = &it913x_i2c_algo, - .num_device_descs = 2, + .num_device_descs = 5, .devices = { { "Kworld UB499-2T T09(IT9137)", { &it913x_table[0], NULL }, @@ -665,6 +800,15 @@ static struct dvb_usb_device_properties it913x_properties = { { "ITE 9135 Generic", { &it913x_table[1], NULL }, }, + { "Sveon STV22 Dual DVB-T HDTV(IT9137)", + { &it913x_table[2], NULL }, + }, + { "ITE 9135(9005) Generic", + { &it913x_table[3], NULL }, + }, + { "ITE 9135(9006) Generic", + { &it913x_table[4], NULL }, + }, } }; @@ -679,5 +823,5 @@ module_usb_driver(it913x_driver); MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>"); MODULE_DESCRIPTION("it913x USB 2 Driver"); -MODULE_VERSION("1.07"); +MODULE_VERSION("1.22"); MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/lmedm04.c b/drivers/media/dvb/dvb-usb/lmedm04.c index 1a876a65ed56..b3fe05bbffc9 100644 --- a/drivers/media/dvb/dvb-usb/lmedm04.c +++ b/drivers/media/dvb/dvb-usb/lmedm04.c @@ -388,8 +388,7 @@ static int lme2510_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, deb_info(3, "%s PID=%04x Index=%04x onoff=%02x", __func__, pid, index, onoff); - if (onoff) - if (!pid_filter) { + if (onoff) { ret = mutex_lock_interruptible(&adap->dev->i2c_mutex); if (ret < 0) return -EAGAIN; @@ -654,6 +653,9 @@ static int lme2510_identify_state(struct usb_device *udev, struct dvb_usb_device_description **desc, int *cold) { + if (pid_filter > 0) + props->adapter[0].fe[0].caps &= + ~DVB_USB_ADAP_NEED_PID_FILTERING; *cold = 0; return 0; } @@ -1293,5 +1295,5 @@ module_usb_driver(lme2510_driver); MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>"); MODULE_DESCRIPTION("LME2510(C) DVB-S USB2.0"); -MODULE_VERSION("1.90"); +MODULE_VERSION("1.91"); MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-demod.c b/drivers/media/dvb/dvb-usb/mxl111sf-demod.c index d1f58371c711..d83df4bb72d3 100644 --- a/drivers/media/dvb/dvb-usb/mxl111sf-demod.c +++ b/drivers/media/dvb/dvb-usb/mxl111sf-demod.c @@ -102,8 +102,8 @@ fail: } static -int mxl1x1sf_demod_get_tps_constellation(struct mxl111sf_demod_state *state, - fe_modulation_t *constellation) +int mxl1x1sf_demod_get_tps_modulation(struct mxl111sf_demod_state *state, + fe_modulation_t *modulation) { u8 val; int ret = mxl111sf_demod_read_reg(state, V6_MODORDER_TPS_REG, &val); @@ -113,13 +113,13 @@ int mxl1x1sf_demod_get_tps_constellation(struct mxl111sf_demod_state *state, switch ((val & V6_PARAM_CONSTELLATION_MASK) >> 4) { case 0: - *constellation = QPSK; + *modulation = QPSK; break; case 1: - *constellation = QAM_16; + *modulation = QAM_16; break; case 2: - *constellation = QAM_64; + *modulation = QAM_64; break; } fail: @@ -284,8 +284,7 @@ static int mxl1x1sf_demod_reset_irq_status(struct mxl111sf_demod_state *state) /* ------------------------------------------------------------------------ */ -static int mxl111sf_demod_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *param) +static int mxl111sf_demod_set_frontend(struct dvb_frontend *fe) { struct mxl111sf_demod_state *state = fe->demodulator_priv; int ret = 0; @@ -303,7 +302,7 @@ static int mxl111sf_demod_set_frontend(struct dvb_frontend *fe, mxl_dbg("()"); if (fe->ops.tuner_ops.set_params) { - ret = fe->ops.tuner_ops.set_params(fe, param); + ret = fe->ops.tuner_ops.set_params(fe); if (mxl_fail(ret)) goto fail; msleep(50); @@ -481,13 +480,13 @@ static int mxl111sf_demod_read_signal_strength(struct dvb_frontend *fe, u16 *signal_strength) { struct mxl111sf_demod_state *state = fe->demodulator_priv; - fe_modulation_t constellation; + fe_modulation_t modulation; u16 snr; mxl111sf_demod_calc_snr(state, &snr); - mxl1x1sf_demod_get_tps_constellation(state, &constellation); + mxl1x1sf_demod_get_tps_modulation(state, &modulation); - switch (constellation) { + switch (modulation) { case QPSK: *signal_strength = (snr >= 1300) ? min(65535, snr * 44) : snr * 38; @@ -508,9 +507,9 @@ static int mxl111sf_demod_read_signal_strength(struct dvb_frontend *fe, return 0; } -static int mxl111sf_demod_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int mxl111sf_demod_get_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct mxl111sf_demod_state *state = fe->demodulator_priv; mxl_dbg("()"); @@ -518,18 +517,18 @@ static int mxl111sf_demod_get_frontend(struct dvb_frontend *fe, p->inversion = /* FIXME */ ? INVERSION_ON : INVERSION_OFF; #endif if (fe->ops.tuner_ops.get_bandwidth) - fe->ops.tuner_ops.get_bandwidth(fe, &p->u.ofdm.bandwidth); + fe->ops.tuner_ops.get_bandwidth(fe, &p->bandwidth_hz); if (fe->ops.tuner_ops.get_frequency) fe->ops.tuner_ops.get_frequency(fe, &p->frequency); - mxl1x1sf_demod_get_tps_code_rate(state, &p->u.ofdm.code_rate_HP); - mxl1x1sf_demod_get_tps_code_rate(state, &p->u.ofdm.code_rate_LP); - mxl1x1sf_demod_get_tps_constellation(state, &p->u.ofdm.constellation); + mxl1x1sf_demod_get_tps_code_rate(state, &p->code_rate_HP); + mxl1x1sf_demod_get_tps_code_rate(state, &p->code_rate_LP); + mxl1x1sf_demod_get_tps_modulation(state, &p->modulation); mxl1x1sf_demod_get_tps_guard_fft_mode(state, - &p->u.ofdm.transmission_mode); + &p->transmission_mode); mxl1x1sf_demod_get_tps_guard_interval(state, - &p->u.ofdm.guard_interval); + &p->guard_interval); mxl1x1sf_demod_get_tps_hierarchy(state, - &p->u.ofdm.hierarchy_information); + &p->hierarchy); return 0; } @@ -551,10 +550,9 @@ static void mxl111sf_demod_release(struct dvb_frontend *fe) } static struct dvb_frontend_ops mxl111sf_demod_ops = { - + .delsys = { SYS_DVBT }, .info = { .name = "MaxLinear MxL111SF DVB-T demodulator", - .type = FE_OFDM, .frequency_min = 177000000, .frequency_max = 858000000, .frequency_stepsize = 166666, diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-tuner.c b/drivers/media/dvb/dvb-usb/mxl111sf-tuner.c index a6341058c4e7..72db6eef4b9c 100644 --- a/drivers/media/dvb/dvb-usb/mxl111sf-tuner.c +++ b/drivers/media/dvb/dvb-usb/mxl111sf-tuner.c @@ -38,6 +38,8 @@ struct mxl111sf_tuner_state { struct mxl111sf_tuner_config *cfg; + enum mxl_if_freq if_freq; + u32 frequency; u32 bandwidth; }; @@ -186,7 +188,10 @@ static int mxl1x1sf_tuner_set_if_output_freq(struct mxl111sf_tuner_state *state) ctrl = iffcw & 0x00ff; #endif ret = mxl111sf_tuner_write_reg(state, V6_TUNER_IF_FCW_REG, ctrl); - mxl_fail(ret); + if (mxl_fail(ret)) + goto fail; + + state->if_freq = state->cfg->if_freq; fail: return ret; } @@ -267,55 +272,49 @@ static int mxl1x1sf_tuner_loop_thru_ctrl(struct mxl111sf_tuner_state *state, /* ------------------------------------------------------------------------ */ -static int mxl111sf_tuner_set_params(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) +static int mxl111sf_tuner_set_params(struct dvb_frontend *fe) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + u32 delsys = c->delivery_system; struct mxl111sf_tuner_state *state = fe->tuner_priv; int ret; u8 bw; mxl_dbg("()"); - if (fe->ops.info.type == FE_ATSC) { - switch (params->u.vsb.modulation) { - case VSB_8: - case VSB_16: - bw = 0; /* ATSC */ - break; - case QAM_64: - case QAM_256: - bw = 1; /* US CABLE */ - break; - default: - err("%s: modulation not set!", __func__); - return -EINVAL; - } - } else if (fe->ops.info.type == FE_OFDM) { - switch (params->u.ofdm.bandwidth) { - case BANDWIDTH_6_MHZ: + switch (delsys) { + case SYS_ATSC: + bw = 0; /* ATSC */ + break; + case SYS_DVBC_ANNEX_B: + bw = 1; /* US CABLE */ + break; + case SYS_DVBT: + switch (c->bandwidth_hz) { + case 6000000: bw = 6; break; - case BANDWIDTH_7_MHZ: + case 7000000: bw = 7; break; - case BANDWIDTH_8_MHZ: + case 8000000: bw = 8; break; default: err("%s: bandwidth not set!", __func__); return -EINVAL; } - } else { + break; + default: err("%s: modulation type not supported!", __func__); return -EINVAL; } - ret = mxl1x1sf_tune_rf(fe, params->frequency, bw); + ret = mxl1x1sf_tune_rf(fe, c->frequency, bw); if (mxl_fail(ret)) goto fail; - state->frequency = params->frequency; - state->bandwidth = (fe->ops.info.type == FE_OFDM) ? - params->u.ofdm.bandwidth : 0; + state->frequency = c->frequency; + state->bandwidth = c->bandwidth_hz; fail: return ret; } @@ -407,6 +406,54 @@ static int mxl111sf_tuner_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) return 0; } +static int mxl111sf_tuner_get_if_frequency(struct dvb_frontend *fe, + u32 *frequency) +{ + struct mxl111sf_tuner_state *state = fe->tuner_priv; + + *frequency = 0; + + switch (state->if_freq) { + case MXL_IF_4_0: /* 4.0 MHz */ + *frequency = 4000000; + break; + case MXL_IF_4_5: /* 4.5 MHz */ + *frequency = 4500000; + break; + case MXL_IF_4_57: /* 4.57 MHz */ + *frequency = 4570000; + break; + case MXL_IF_5_0: /* 5.0 MHz */ + *frequency = 5000000; + break; + case MXL_IF_5_38: /* 5.38 MHz */ + *frequency = 5380000; + break; + case MXL_IF_6_0: /* 6.0 MHz */ + *frequency = 6000000; + break; + case MXL_IF_6_28: /* 6.28 MHz */ + *frequency = 6280000; + break; + case MXL_IF_7_2: /* 7.2 MHz */ + *frequency = 7200000; + break; + case MXL_IF_35_25: /* 35.25 MHz */ + *frequency = 35250000; + break; + case MXL_IF_36: /* 36 MHz */ + *frequency = 36000000; + break; + case MXL_IF_36_15: /* 36.15 MHz */ + *frequency = 36150000; + break; + case MXL_IF_44: /* 44 MHz */ + *frequency = 44000000; + break; + } + return 0; +} + static int mxl111sf_tuner_release(struct dvb_frontend *fe) { struct mxl111sf_tuner_state *state = fe->tuner_priv; @@ -436,6 +483,7 @@ static struct dvb_tuner_ops mxl111sf_tuner_tuner_ops = { .get_rf_strength = mxl111sf_get_rf_strength, .get_frequency = mxl111sf_tuner_get_frequency, .get_bandwidth = mxl111sf_tuner_get_bandwidth, + .get_if_frequency = mxl111sf_tuner_get_if_frequency, .release = mxl111sf_tuner_release, }; diff --git a/drivers/media/dvb/dvb-usb/mxl111sf.c b/drivers/media/dvb/dvb-usb/mxl111sf.c index 825a8b242e09..38ef0253d3b5 100644 --- a/drivers/media/dvb/dvb-usb/mxl111sf.c +++ b/drivers/media/dvb/dvb-usb/mxl111sf.c @@ -758,6 +758,7 @@ MODULE_DEVICE_TABLE(usb, mxl111sf_table); #define MXL111SF_EP4_BULK_STREAMING_CONFIG \ + .size_of_priv = sizeof(struct mxl111sf_adap_state), \ .streaming_ctrl = mxl111sf_ep4_streaming_ctrl, \ .stream = { \ .type = USB_BULK, \ @@ -772,6 +773,7 @@ MODULE_DEVICE_TABLE(usb, mxl111sf_table); /* FIXME: works for v6 but not v8 silicon */ #define MXL111SF_EP4_ISOC_STREAMING_CONFIG \ + .size_of_priv = sizeof(struct mxl111sf_adap_state), \ .streaming_ctrl = mxl111sf_ep4_streaming_ctrl, \ .stream = { \ .type = USB_ISOC, \ @@ -788,6 +790,7 @@ MODULE_DEVICE_TABLE(usb, mxl111sf_table); } #define MXL111SF_EP6_BULK_STREAMING_CONFIG \ + .size_of_priv = sizeof(struct mxl111sf_adap_state), \ .streaming_ctrl = mxl111sf_ep6_streaming_ctrl, \ .stream = { \ .type = USB_BULK, \ @@ -802,6 +805,7 @@ MODULE_DEVICE_TABLE(usb, mxl111sf_table); /* FIXME */ #define MXL111SF_EP6_ISOC_STREAMING_CONFIG \ + .size_of_priv = sizeof(struct mxl111sf_adap_state), \ .streaming_ctrl = mxl111sf_ep6_streaming_ctrl, \ .stream = { \ .type = USB_ISOC, \ @@ -839,8 +843,6 @@ static struct dvb_usb_device_properties mxl111sf_dvbt_bulk_properties = { .fe_ioctl_override = mxl111sf_fe_ioctl_override, .num_frontends = 1, .fe = {{ - .size_of_priv = sizeof(struct mxl111sf_adap_state), - .frontend_attach = mxl111sf_attach_demod, .tuner_attach = mxl111sf_attach_tuner, @@ -883,8 +885,6 @@ static struct dvb_usb_device_properties mxl111sf_dvbt_isoc_properties = { .fe_ioctl_override = mxl111sf_fe_ioctl_override, .num_frontends = 1, .fe = {{ - .size_of_priv = sizeof(struct mxl111sf_adap_state), - .frontend_attach = mxl111sf_attach_demod, .tuner_attach = mxl111sf_attach_tuner, @@ -927,16 +927,12 @@ static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties = { .fe_ioctl_override = mxl111sf_fe_ioctl_override, .num_frontends = 2, .fe = {{ - .size_of_priv = sizeof(struct mxl111sf_adap_state), - .frontend_attach = mxl111sf_lgdt3305_frontend_attach, .tuner_attach = mxl111sf_attach_tuner, MXL111SF_EP6_BULK_STREAMING_CONFIG, }, { - .size_of_priv = sizeof(struct mxl111sf_adap_state), - .frontend_attach = mxl111sf_attach_demod, .tuner_attach = mxl111sf_attach_tuner, @@ -992,16 +988,12 @@ static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties = { .fe_ioctl_override = mxl111sf_fe_ioctl_override, .num_frontends = 2, .fe = {{ - .size_of_priv = sizeof(struct mxl111sf_adap_state), - .frontend_attach = mxl111sf_lgdt3305_frontend_attach, .tuner_attach = mxl111sf_attach_tuner, MXL111SF_EP6_ISOC_STREAMING_CONFIG, }, { - .size_of_priv = sizeof(struct mxl111sf_adap_state), - .frontend_attach = mxl111sf_attach_demod, .tuner_attach = mxl111sf_attach_tuner, diff --git a/drivers/media/dvb/dvb-usb/ttusb2.c b/drivers/media/dvb/dvb-usb/ttusb2.c index 56acf8e55d50..e53a1061cb8e 100644 --- a/drivers/media/dvb/dvb-usb/ttusb2.c +++ b/drivers/media/dvb/dvb-usb/ttusb2.c @@ -75,10 +75,18 @@ static int ttusb2_msg(struct dvb_usb_device *d, u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen) { struct ttusb2_state *st = d->priv; - u8 s[wlen+4],r[64] = { 0 }; + u8 *s, *r = NULL; int ret = 0; - memset(s,0,wlen+4); + s = kzalloc(wlen+4, GFP_KERNEL); + if (!s) + return -ENOMEM; + + r = kzalloc(64, GFP_KERNEL); + if (!r) { + kfree(s); + return -ENOMEM; + } s[0] = 0xaa; s[1] = ++st->id; @@ -94,12 +102,17 @@ static int ttusb2_msg(struct dvb_usb_device *d, u8 cmd, r[2] != cmd || (rlen > 0 && r[3] != rlen)) { warn("there might have been an error during control message transfer. (rlen = %d, was %d)",rlen,r[3]); + kfree(s); + kfree(r); return -EIO; } if (rlen > 0) memcpy(rbuf, &r[4], rlen); + kfree(s); + kfree(r); + return 0; } @@ -384,7 +397,7 @@ static int ttusb2_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num memcpy(&obuf[3], msg[i].buf, msg[i].len); - if (ttusb2_msg(d, CMD_I2C_XFER, obuf, msg[i].len+3, ibuf, obuf[2] + 3) < 0) { + if (ttusb2_msg(d, CMD_I2C_XFER, obuf, obuf[1]+3, ibuf, obuf[2] + 3) < 0) { err("i2c transfer failed."); break; } diff --git a/drivers/media/dvb/dvb-usb/vp702x-fe.c b/drivers/media/dvb/dvb-usb/vp702x-fe.c index 2bb8d4cc8d88..5eab468dd904 100644 --- a/drivers/media/dvb/dvb-usb/vp702x-fe.c +++ b/drivers/media/dvb/dvb-usb/vp702x-fe.c @@ -135,9 +135,9 @@ static int vp702x_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_front return 0; } -static int vp702x_fe_set_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) +static int vp702x_fe_set_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *fep = &fe->dtv_property_cache; struct vp702x_fe_state *st = fe->demodulator_priv; struct vp702x_device_state *dst = st->d->priv; u32 freq = fep->frequency/1000; @@ -155,14 +155,14 @@ static int vp702x_fe_set_frontend(struct dvb_frontend* fe, cmd[1] = freq & 0xff; cmd[2] = 1; /* divrate == 4 -> frequencyRef[1] -> 1 here */ - sr = (u64) (fep->u.qpsk.symbol_rate/1000) << 20; + sr = (u64) (fep->symbol_rate/1000) << 20; do_div(sr,88000); cmd[3] = (sr >> 12) & 0xff; cmd[4] = (sr >> 4) & 0xff; cmd[5] = (sr << 4) & 0xf0; deb_fe("setting frontend to: %u -> %u (%x) LNB-based GHz, symbolrate: %d -> %lu (%lx)\n", - fep->frequency,freq,freq, fep->u.qpsk.symbol_rate, + fep->frequency, freq, freq, fep->symbol_rate, (unsigned long) sr, (unsigned long) sr); /* if (fep->inversion == INVERSION_ON) @@ -171,7 +171,7 @@ static int vp702x_fe_set_frontend(struct dvb_frontend* fe, if (st->voltage == SEC_VOLTAGE_18) cmd[6] |= 0x40; -/* if (fep->u.qpsk.symbol_rate > 8000000) +/* if (fep->symbol_rate > 8000000) cmd[6] |= 0x20; if (fep->frequency < 1531000) @@ -211,13 +211,6 @@ static int vp702x_fe_sleep(struct dvb_frontend *fe) return 0; } -static int vp702x_fe_get_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) -{ - deb_fe("%s\n",__func__); - return 0; -} - static int vp702x_fe_send_diseqc_msg (struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *m) { @@ -350,9 +343,9 @@ error: static struct dvb_frontend_ops vp702x_fe_ops = { + .delsys = { SYS_DVBS }, .info = { .name = "Twinhan DST-like frontend (VP7021/VP7020) DVB-S", - .type = FE_QPSK, .frequency_min = 950000, .frequency_max = 2150000, .frequency_stepsize = 1000, /* kHz for QPSK frontends */ @@ -371,7 +364,6 @@ static struct dvb_frontend_ops vp702x_fe_ops = { .sleep = vp702x_fe_sleep, .set_frontend = vp702x_fe_set_frontend, - .get_frontend = vp702x_fe_get_frontend, .get_tune_settings = vp702x_fe_get_tune_settings, .read_status = vp702x_fe_read_status, diff --git a/drivers/media/dvb/dvb-usb/vp7045-fe.c b/drivers/media/dvb/dvb-usb/vp7045-fe.c index 8452eef90322..b8825b18c003 100644 --- a/drivers/media/dvb/dvb-usb/vp7045-fe.c +++ b/drivers/media/dvb/dvb-usb/vp7045-fe.c @@ -103,9 +103,9 @@ static int vp7045_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_front return 0; } -static int vp7045_fe_set_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) +static int vp7045_fe_set_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *fep = &fe->dtv_property_cache; struct vp7045_fe_state *state = fe->demodulator_priv; u8 buf[5]; u32 freq = fep->frequency / 1000; @@ -115,25 +115,24 @@ static int vp7045_fe_set_frontend(struct dvb_frontend* fe, buf[2] = freq & 0xff; buf[3] = 0; - switch (fep->u.ofdm.bandwidth) { - case BANDWIDTH_8_MHZ: buf[4] = 8; break; - case BANDWIDTH_7_MHZ: buf[4] = 7; break; - case BANDWIDTH_6_MHZ: buf[4] = 6; break; - case BANDWIDTH_AUTO: return -EOPNOTSUPP; - default: - return -EINVAL; + switch (fep->bandwidth_hz) { + case 8000000: + buf[4] = 8; + break; + case 7000000: + buf[4] = 7; + break; + case 6000000: + buf[4] = 6; + break; + default: + return -EINVAL; } vp7045_usb_op(state->d,LOCK_TUNER_COMMAND,buf,5,NULL,0,200); return 0; } -static int vp7045_fe_get_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) -{ - return 0; -} - static void vp7045_fe_release(struct dvb_frontend* fe) { struct vp7045_fe_state *state = fe->demodulator_priv; @@ -159,9 +158,9 @@ error: static struct dvb_frontend_ops vp7045_fe_ops = { + .delsys = { SYS_DVBT }, .info = { .name = "Twinhan VP7045/46 USB DVB-T", - .type = FE_OFDM, .frequency_min = 44250000, .frequency_max = 867250000, .frequency_stepsize = 1000, @@ -181,7 +180,6 @@ static struct dvb_frontend_ops vp7045_fe_ops = { .sleep = vp7045_fe_sleep, .set_frontend = vp7045_fe_set_frontend, - .get_frontend = vp7045_fe_get_frontend, .get_tune_settings = vp7045_fe_get_tune_settings, .read_status = vp7045_fe_read_status, diff --git a/drivers/media/dvb/firewire/firedtv-avc.c b/drivers/media/dvb/firewire/firedtv-avc.c index 489ae8245867..d1a1a1324ef8 100644 --- a/drivers/media/dvb/firewire/firedtv-avc.c +++ b/drivers/media/dvb/firewire/firedtv-avc.c @@ -335,7 +335,7 @@ static int add_pid_filter(struct firedtv *fdtv, u8 *operand) * (not supported by the AVC standard) */ static int avc_tuner_tuneqpsk(struct firedtv *fdtv, - struct dvb_frontend_parameters *params) + struct dtv_frontend_properties *p) { struct avc_command_frame *c = (void *)fdtv->avc_data; @@ -349,15 +349,15 @@ static int avc_tuner_tuneqpsk(struct firedtv *fdtv, else c->operand[3] = SFE_VENDOR_OPCODE_TUNE_QPSK; - c->operand[4] = (params->frequency >> 24) & 0xff; - c->operand[5] = (params->frequency >> 16) & 0xff; - c->operand[6] = (params->frequency >> 8) & 0xff; - c->operand[7] = params->frequency & 0xff; + c->operand[4] = (p->frequency >> 24) & 0xff; + c->operand[5] = (p->frequency >> 16) & 0xff; + c->operand[6] = (p->frequency >> 8) & 0xff; + c->operand[7] = p->frequency & 0xff; - c->operand[8] = ((params->u.qpsk.symbol_rate / 1000) >> 8) & 0xff; - c->operand[9] = (params->u.qpsk.symbol_rate / 1000) & 0xff; + c->operand[8] = ((p->symbol_rate / 1000) >> 8) & 0xff; + c->operand[9] = (p->symbol_rate / 1000) & 0xff; - switch (params->u.qpsk.fec_inner) { + switch (p->fec_inner) { case FEC_1_2: c->operand[10] = 0x1; break; case FEC_2_3: c->operand[10] = 0x2; break; case FEC_3_4: c->operand[10] = 0x3; break; @@ -392,10 +392,11 @@ static int avc_tuner_tuneqpsk(struct firedtv *fdtv, default: c->operand[13] = 0x2; break; } switch (fdtv->fe.dtv_property_cache.rolloff) { - case ROLLOFF_AUTO: c->operand[14] = 0x2; break; case ROLLOFF_35: c->operand[14] = 0x2; break; case ROLLOFF_20: c->operand[14] = 0x0; break; case ROLLOFF_25: c->operand[14] = 0x1; break; + case ROLLOFF_AUTO: + default: c->operand[14] = 0x2; break; /* case ROLLOFF_NONE: c->operand[14] = 0xff; break; */ } switch (fdtv->fe.dtv_property_cache.pilot) { @@ -415,7 +416,7 @@ static int avc_tuner_tuneqpsk(struct firedtv *fdtv, } static int avc_tuner_dsd_dvb_c(struct firedtv *fdtv, - struct dvb_frontend_parameters *params) + struct dtv_frontend_properties *p) { struct avc_command_frame *c = (void *)fdtv->avc_data; @@ -434,8 +435,8 @@ static int avc_tuner_dsd_dvb_c(struct firedtv *fdtv, | 1 << 4 /* Frequency */ | 1 << 3 /* Symbol_Rate */ | 0 << 2 /* FEC_outer */ - | (params->u.qam.fec_inner != FEC_AUTO ? 1 << 1 : 0) - | (params->u.qam.modulation != QAM_AUTO ? 1 << 0 : 0); + | (p->fec_inner != FEC_AUTO ? 1 << 1 : 0) + | (p->modulation != QAM_AUTO ? 1 << 0 : 0); /* multiplex_valid_flags, low byte */ c->operand[6] = 0 << 7 /* NetworkID */ @@ -446,15 +447,15 @@ static int avc_tuner_dsd_dvb_c(struct firedtv *fdtv, c->operand[9] = 0x00; c->operand[10] = 0x00; - c->operand[11] = (((params->frequency / 4000) >> 16) & 0xff) | (2 << 6); - c->operand[12] = ((params->frequency / 4000) >> 8) & 0xff; - c->operand[13] = (params->frequency / 4000) & 0xff; - c->operand[14] = ((params->u.qpsk.symbol_rate / 1000) >> 12) & 0xff; - c->operand[15] = ((params->u.qpsk.symbol_rate / 1000) >> 4) & 0xff; - c->operand[16] = ((params->u.qpsk.symbol_rate / 1000) << 4) & 0xf0; + c->operand[11] = (((p->frequency / 4000) >> 16) & 0xff) | (2 << 6); + c->operand[12] = ((p->frequency / 4000) >> 8) & 0xff; + c->operand[13] = (p->frequency / 4000) & 0xff; + c->operand[14] = ((p->symbol_rate / 1000) >> 12) & 0xff; + c->operand[15] = ((p->symbol_rate / 1000) >> 4) & 0xff; + c->operand[16] = ((p->symbol_rate / 1000) << 4) & 0xf0; c->operand[17] = 0x00; - switch (params->u.qpsk.fec_inner) { + switch (p->fec_inner) { case FEC_1_2: c->operand[18] = 0x1; break; case FEC_2_3: c->operand[18] = 0x2; break; case FEC_3_4: c->operand[18] = 0x3; break; @@ -466,7 +467,7 @@ static int avc_tuner_dsd_dvb_c(struct firedtv *fdtv, default: c->operand[18] = 0x0; } - switch (params->u.qam.modulation) { + switch (p->modulation) { case QAM_16: c->operand[19] = 0x08; break; case QAM_32: c->operand[19] = 0x10; break; case QAM_64: c->operand[19] = 0x18; break; @@ -483,9 +484,8 @@ static int avc_tuner_dsd_dvb_c(struct firedtv *fdtv, } static int avc_tuner_dsd_dvb_t(struct firedtv *fdtv, - struct dvb_frontend_parameters *params) + struct dtv_frontend_properties *p) { - struct dvb_ofdm_parameters *ofdm = ¶ms->u.ofdm; struct avc_command_frame *c = (void *)fdtv->avc_data; c->opcode = AVC_OPCODE_DSD; @@ -500,42 +500,42 @@ static int avc_tuner_dsd_dvb_t(struct firedtv *fdtv, c->operand[5] = 0 << 7 /* reserved */ | 1 << 6 /* CenterFrequency */ - | (ofdm->bandwidth != BANDWIDTH_AUTO ? 1 << 5 : 0) - | (ofdm->constellation != QAM_AUTO ? 1 << 4 : 0) - | (ofdm->hierarchy_information != HIERARCHY_AUTO ? 1 << 3 : 0) - | (ofdm->code_rate_HP != FEC_AUTO ? 1 << 2 : 0) - | (ofdm->code_rate_LP != FEC_AUTO ? 1 << 1 : 0) - | (ofdm->guard_interval != GUARD_INTERVAL_AUTO ? 1 << 0 : 0); + | (p->bandwidth_hz != 0 ? 1 << 5 : 0) + | (p->modulation != QAM_AUTO ? 1 << 4 : 0) + | (p->hierarchy != HIERARCHY_AUTO ? 1 << 3 : 0) + | (p->code_rate_HP != FEC_AUTO ? 1 << 2 : 0) + | (p->code_rate_LP != FEC_AUTO ? 1 << 1 : 0) + | (p->guard_interval != GUARD_INTERVAL_AUTO ? 1 << 0 : 0); /* multiplex_valid_flags, low byte */ c->operand[6] = 0 << 7 /* NetworkID */ - | (ofdm->transmission_mode != TRANSMISSION_MODE_AUTO ? 1 << 6 : 0) + | (p->transmission_mode != TRANSMISSION_MODE_AUTO ? 1 << 6 : 0) | 0 << 5 /* OtherFrequencyFlag */ | 0 << 0 /* reserved */ ; c->operand[7] = 0x0; - c->operand[8] = (params->frequency / 10) >> 24; - c->operand[9] = ((params->frequency / 10) >> 16) & 0xff; - c->operand[10] = ((params->frequency / 10) >> 8) & 0xff; - c->operand[11] = (params->frequency / 10) & 0xff; - - switch (ofdm->bandwidth) { - case BANDWIDTH_7_MHZ: c->operand[12] = 0x20; break; - case BANDWIDTH_8_MHZ: - case BANDWIDTH_6_MHZ: /* not defined by AVC spec */ - case BANDWIDTH_AUTO: + c->operand[8] = (p->frequency / 10) >> 24; + c->operand[9] = ((p->frequency / 10) >> 16) & 0xff; + c->operand[10] = ((p->frequency / 10) >> 8) & 0xff; + c->operand[11] = (p->frequency / 10) & 0xff; + + switch (p->bandwidth_hz) { + case 7000000: c->operand[12] = 0x20; break; + case 8000000: + case 6000000: /* not defined by AVC spec */ + case 0: default: c->operand[12] = 0x00; } - switch (ofdm->constellation) { + switch (p->modulation) { case QAM_16: c->operand[13] = 1 << 6; break; case QAM_64: c->operand[13] = 2 << 6; break; case QPSK: default: c->operand[13] = 0x00; } - switch (ofdm->hierarchy_information) { + switch (p->hierarchy) { case HIERARCHY_1: c->operand[13] |= 1 << 3; break; case HIERARCHY_2: c->operand[13] |= 2 << 3; break; case HIERARCHY_4: c->operand[13] |= 3 << 3; break; @@ -544,7 +544,7 @@ static int avc_tuner_dsd_dvb_t(struct firedtv *fdtv, default: break; } - switch (ofdm->code_rate_HP) { + switch (p->code_rate_HP) { case FEC_2_3: c->operand[13] |= 1; break; case FEC_3_4: c->operand[13] |= 2; break; case FEC_5_6: c->operand[13] |= 3; break; @@ -553,7 +553,7 @@ static int avc_tuner_dsd_dvb_t(struct firedtv *fdtv, default: break; } - switch (ofdm->code_rate_LP) { + switch (p->code_rate_LP) { case FEC_2_3: c->operand[14] = 1 << 5; break; case FEC_3_4: c->operand[14] = 2 << 5; break; case FEC_5_6: c->operand[14] = 3 << 5; break; @@ -562,7 +562,7 @@ static int avc_tuner_dsd_dvb_t(struct firedtv *fdtv, default: c->operand[14] = 0x00; break; } - switch (ofdm->guard_interval) { + switch (p->guard_interval) { case GUARD_INTERVAL_1_16: c->operand[14] |= 1 << 3; break; case GUARD_INTERVAL_1_8: c->operand[14] |= 2 << 3; break; case GUARD_INTERVAL_1_4: c->operand[14] |= 3 << 3; break; @@ -571,7 +571,7 @@ static int avc_tuner_dsd_dvb_t(struct firedtv *fdtv, default: break; } - switch (ofdm->transmission_mode) { + switch (p->transmission_mode) { case TRANSMISSION_MODE_8K: c->operand[14] |= 1 << 1; break; case TRANSMISSION_MODE_2K: case TRANSMISSION_MODE_AUTO: @@ -585,7 +585,7 @@ static int avc_tuner_dsd_dvb_t(struct firedtv *fdtv, } int avc_tuner_dsd(struct firedtv *fdtv, - struct dvb_frontend_parameters *params) + struct dtv_frontend_properties *p) { struct avc_command_frame *c = (void *)fdtv->avc_data; int pos, ret; @@ -597,9 +597,9 @@ int avc_tuner_dsd(struct firedtv *fdtv, switch (fdtv->type) { case FIREDTV_DVB_S: - case FIREDTV_DVB_S2: pos = avc_tuner_tuneqpsk(fdtv, params); break; - case FIREDTV_DVB_C: pos = avc_tuner_dsd_dvb_c(fdtv, params); break; - case FIREDTV_DVB_T: pos = avc_tuner_dsd_dvb_t(fdtv, params); break; + case FIREDTV_DVB_S2: pos = avc_tuner_tuneqpsk(fdtv, p); break; + case FIREDTV_DVB_C: pos = avc_tuner_dsd_dvb_c(fdtv, p); break; + case FIREDTV_DVB_T: pos = avc_tuner_dsd_dvb_t(fdtv, p); break; default: BUG(); } diff --git a/drivers/media/dvb/firewire/firedtv-dvb.c b/drivers/media/dvb/firewire/firedtv-dvb.c index fd8bbbfa5c59..eb7496eab130 100644 --- a/drivers/media/dvb/firewire/firedtv-dvb.c +++ b/drivers/media/dvb/firewire/firedtv-dvb.c @@ -203,7 +203,9 @@ int fdtv_dvb_register(struct firedtv *fdtv, const char *name) if (err) goto fail_rem_frontend; - dvb_net_init(&fdtv->adapter, &fdtv->dvbnet, &fdtv->demux.dmx); + err = dvb_net_init(&fdtv->adapter, &fdtv->dvbnet, &fdtv->demux.dmx); + if (err) + goto fail_disconnect_frontend; fdtv_frontend_init(fdtv, name); err = dvb_register_frontend(&fdtv->adapter, &fdtv->fe); @@ -218,6 +220,7 @@ int fdtv_dvb_register(struct firedtv *fdtv, const char *name) fail_net_release: dvb_net_release(&fdtv->dvbnet); +fail_disconnect_frontend: fdtv->demux.dmx.close(&fdtv->demux.dmx); fail_rem_frontend: fdtv->demux.dmx.remove_frontend(&fdtv->demux.dmx, &fdtv->frontend); diff --git a/drivers/media/dvb/firewire/firedtv-fe.c b/drivers/media/dvb/firewire/firedtv-fe.c index 8748a61be73d..6fe9793b98b3 100644 --- a/drivers/media/dvb/firewire/firedtv-fe.c +++ b/drivers/media/dvb/firewire/firedtv-fe.c @@ -141,28 +141,12 @@ static int fdtv_read_uncorrected_blocks(struct dvb_frontend *fe, u32 *ucblocks) return -EOPNOTSUPP; } -static int fdtv_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) +static int fdtv_set_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct firedtv *fdtv = fe->sec_priv; - return avc_tuner_dsd(fdtv, params); -} - -static int fdtv_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) -{ - return -EOPNOTSUPP; -} - -static int fdtv_get_property(struct dvb_frontend *fe, struct dtv_property *tvp) -{ - return 0; -} - -static int fdtv_set_property(struct dvb_frontend *fe, struct dtv_property *tvp) -{ - return 0; + return avc_tuner_dsd(fdtv, p); } void fdtv_frontend_init(struct firedtv *fdtv, const char *name) @@ -174,10 +158,6 @@ void fdtv_frontend_init(struct firedtv *fdtv, const char *name) ops->sleep = fdtv_sleep; ops->set_frontend = fdtv_set_frontend; - ops->get_frontend = fdtv_get_frontend; - - ops->get_property = fdtv_get_property; - ops->set_property = fdtv_set_property; ops->read_status = fdtv_read_status; ops->read_ber = fdtv_read_ber; @@ -192,7 +172,7 @@ void fdtv_frontend_init(struct firedtv *fdtv, const char *name) switch (fdtv->type) { case FIREDTV_DVB_S: - fi->type = FE_QPSK; + ops->delsys[0] = SYS_DVBS; fi->frequency_min = 950000; fi->frequency_max = 2150000; @@ -211,7 +191,8 @@ void fdtv_frontend_init(struct firedtv *fdtv, const char *name) break; case FIREDTV_DVB_S2: - fi->type = FE_QPSK; + ops->delsys[0] = SYS_DVBS; + ops->delsys[1] = SYS_DVBS2; fi->frequency_min = 950000; fi->frequency_max = 2150000; @@ -231,7 +212,7 @@ void fdtv_frontend_init(struct firedtv *fdtv, const char *name) break; case FIREDTV_DVB_C: - fi->type = FE_QAM; + ops->delsys[0] = SYS_DVBC_ANNEX_A; fi->frequency_min = 47000000; fi->frequency_max = 866000000; @@ -249,7 +230,7 @@ void fdtv_frontend_init(struct firedtv *fdtv, const char *name) break; case FIREDTV_DVB_T: - fi->type = FE_OFDM; + ops->delsys[0] = SYS_DVBT; fi->frequency_min = 49000000; fi->frequency_max = 861000000; diff --git a/drivers/media/dvb/firewire/firedtv.h b/drivers/media/dvb/firewire/firedtv.h index bd00b04e079d..4fdcd8cb7530 100644 --- a/drivers/media/dvb/firewire/firedtv.h +++ b/drivers/media/dvb/firewire/firedtv.h @@ -112,8 +112,8 @@ struct firedtv { /* firedtv-avc.c */ int avc_recv(struct firedtv *fdtv, void *data, size_t length); int avc_tuner_status(struct firedtv *fdtv, struct firedtv_tuner_status *stat); -struct dvb_frontend_parameters; -int avc_tuner_dsd(struct firedtv *fdtv, struct dvb_frontend_parameters *params); +struct dtv_frontend_properties; +int avc_tuner_dsd(struct firedtv *fdtv, struct dtv_frontend_properties *params); int avc_tuner_set_pids(struct firedtv *fdtv, unsigned char pidc, u16 pid[]); int avc_tuner_get_ts(struct firedtv *fdtv); int avc_identify_subunit(struct firedtv *fdtv); diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index 4a2d2e6c91ab..ebb5ed7a7783 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig @@ -404,6 +404,13 @@ config DVB_EC100 help Say Y when you want to support this frontend. +config DVB_HD29L2 + tristate "HDIC HD29L2" + depends on DVB_CORE && I2C + default m if DVB_FE_CUSTOMISE + help + Say Y when you want to support this frontend. + config DVB_STV0367 tristate "ST STV0367 based" depends on DVB_CORE && I2C diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile index f639f6781551..00a20636df62 100644 --- a/drivers/media/dvb/frontends/Makefile +++ b/drivers/media/dvb/frontends/Makefile @@ -84,6 +84,7 @@ obj-$(CONFIG_DVB_STV090x) += stv090x.o obj-$(CONFIG_DVB_STV6110x) += stv6110x.o obj-$(CONFIG_DVB_ISL6423) += isl6423.o obj-$(CONFIG_DVB_EC100) += ec100.o +obj-$(CONFIG_DVB_HD29L2) += hd29l2.o obj-$(CONFIG_DVB_DS3000) += ds3000.o obj-$(CONFIG_DVB_MB86A16) += mb86a16.o obj-$(CONFIG_DVB_MB86A20S) += mb86a20s.o diff --git a/drivers/media/dvb/frontends/af9013.c b/drivers/media/dvb/frontends/af9013.c index 345311c33383..6bcbcf543b38 100644 --- a/drivers/media/dvb/frontends/af9013.c +++ b/drivers/media/dvb/frontends/af9013.c @@ -2,6 +2,7 @@ * Afatech AF9013 demodulator driver * * Copyright (C) 2007 Antti Palosaari <crope@iki.fi> + * Copyright (C) 2011 Antti Palosaari <crope@iki.fi> * * Thanks to Afatech who kindly provided information. * @@ -21,25 +22,15 @@ * */ -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <linux/firmware.h> - -#include "dvb_frontend.h" #include "af9013_priv.h" -#include "af9013.h" int af9013_debug; +module_param_named(debug, af9013_debug, int, 0644); +MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); struct af9013_state { struct i2c_adapter *i2c; - struct dvb_frontend frontend; - + struct dvb_frontend fe; struct af9013_config config; /* tuner/demod RF and IF AGC limits used for signal strength calc */ @@ -48,107 +39,178 @@ struct af9013_state { u32 ber; u32 ucblocks; u16 snr; - u32 frequency; - unsigned long next_statistics_check; + u32 bandwidth_hz; + fe_status_t fe_status; + unsigned long set_frontend_jiffies; + unsigned long read_status_jiffies; + bool first_tune; + bool i2c_gate_state; + unsigned int statistics_step:3; + struct delayed_work statistics_work; }; -static u8 regmask[8] = { 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff }; - -static int af9013_write_regs(struct af9013_state *state, u8 mbox, u16 reg, - u8 *val, u8 len) +/* write multiple registers */ +static int af9013_wr_regs_i2c(struct af9013_state *priv, u8 mbox, u16 reg, + const u8 *val, int len) { + int ret; u8 buf[3+len]; - struct i2c_msg msg = { - .addr = state->config.demod_address, - .flags = 0, - .len = sizeof(buf), - .buf = buf }; - - buf[0] = reg >> 8; - buf[1] = reg & 0xff; + struct i2c_msg msg[1] = { + { + .addr = priv->config.i2c_addr, + .flags = 0, + .len = sizeof(buf), + .buf = buf, + } + }; + + buf[0] = (reg >> 8) & 0xff; + buf[1] = (reg >> 0) & 0xff; buf[2] = mbox; memcpy(&buf[3], val, len); - if (i2c_transfer(state->i2c, &msg, 1) != 1) { - warn("I2C write failed reg:%04x len:%d", reg, len); - return -EREMOTEIO; + ret = i2c_transfer(priv->i2c, msg, 1); + if (ret == 1) { + ret = 0; + } else { + warn("i2c wr failed=%d reg=%04x len=%d", ret, reg, len); + ret = -EREMOTEIO; } - return 0; + return ret; } -static int af9013_write_ofdm_regs(struct af9013_state *state, u16 reg, u8 *val, - u8 len) +/* read multiple registers */ +static int af9013_rd_regs_i2c(struct af9013_state *priv, u8 mbox, u16 reg, + u8 *val, int len) { - u8 mbox = (1 << 0)|(1 << 1)|((len - 1) << 2)|(0 << 6)|(0 << 7); - return af9013_write_regs(state, mbox, reg, val, len); + int ret; + u8 buf[3]; + struct i2c_msg msg[2] = { + { + .addr = priv->config.i2c_addr, + .flags = 0, + .len = 3, + .buf = buf, + }, { + .addr = priv->config.i2c_addr, + .flags = I2C_M_RD, + .len = len, + .buf = val, + } + }; + + buf[0] = (reg >> 8) & 0xff; + buf[1] = (reg >> 0) & 0xff; + buf[2] = mbox; + + ret = i2c_transfer(priv->i2c, msg, 2); + if (ret == 2) { + ret = 0; + } else { + warn("i2c rd failed=%d reg=%04x len=%d", ret, reg, len); + ret = -EREMOTEIO; + } + return ret; } -static int af9013_write_ofsm_regs(struct af9013_state *state, u16 reg, u8 *val, - u8 len) +/* write multiple registers */ +static int af9013_wr_regs(struct af9013_state *priv, u16 reg, const u8 *val, + int len) +{ + int ret, i; + u8 mbox = (0 << 7)|(0 << 6)|(1 << 1)|(1 << 0); + + if ((priv->config.ts_mode == AF9013_TS_USB) && + ((reg & 0xff00) != 0xff00) && ((reg & 0xff00) != 0xae00)) { + mbox |= ((len - 1) << 2); + ret = af9013_wr_regs_i2c(priv, mbox, reg, val, len); + } else { + for (i = 0; i < len; i++) { + ret = af9013_wr_regs_i2c(priv, mbox, reg+i, val+i, 1); + if (ret) + goto err; + } + } + +err: + return 0; +} + +/* read multiple registers */ +static int af9013_rd_regs(struct af9013_state *priv, u16 reg, u8 *val, int len) { - u8 mbox = (1 << 0)|(1 << 1)|((len - 1) << 2)|(1 << 6)|(1 << 7); - return af9013_write_regs(state, mbox, reg, val, len); + int ret, i; + u8 mbox = (0 << 7)|(0 << 6)|(1 << 1)|(0 << 0); + + if ((priv->config.ts_mode == AF9013_TS_USB) && + ((reg & 0xff00) != 0xff00) && ((reg & 0xff00) != 0xae00)) { + mbox |= ((len - 1) << 2); + ret = af9013_rd_regs_i2c(priv, mbox, reg, val, len); + } else { + for (i = 0; i < len; i++) { + ret = af9013_rd_regs_i2c(priv, mbox, reg+i, val+i, 1); + if (ret) + goto err; + } + } + +err: + return 0; } /* write single register */ -static int af9013_write_reg(struct af9013_state *state, u16 reg, u8 val) +static int af9013_wr_reg(struct af9013_state *priv, u16 reg, u8 val) { - return af9013_write_ofdm_regs(state, reg, &val, 1); + return af9013_wr_regs(priv, reg, &val, 1); } /* read single register */ -static int af9013_read_reg(struct af9013_state *state, u16 reg, u8 *val) +static int af9013_rd_reg(struct af9013_state *priv, u16 reg, u8 *val) { - u8 obuf[3] = { reg >> 8, reg & 0xff, 0 }; - u8 ibuf[1]; - struct i2c_msg msg[2] = { - { - .addr = state->config.demod_address, - .flags = 0, - .len = sizeof(obuf), - .buf = obuf - }, { - .addr = state->config.demod_address, - .flags = I2C_M_RD, - .len = sizeof(ibuf), - .buf = ibuf - } - }; + return af9013_rd_regs(priv, reg, val, 1); +} - if (i2c_transfer(state->i2c, msg, 2) != 2) { - warn("I2C read failed reg:%04x", reg); - return -EREMOTEIO; - } - *val = ibuf[0]; - return 0; +static int af9013_write_ofsm_regs(struct af9013_state *state, u16 reg, u8 *val, + u8 len) +{ + u8 mbox = (1 << 7)|(1 << 6)|((len - 1) << 2)|(1 << 1)|(1 << 0); + return af9013_wr_regs_i2c(state, mbox, reg, val, len); } -static int af9013_write_reg_bits(struct af9013_state *state, u16 reg, u8 pos, - u8 len, u8 val) +static int af9013_wr_reg_bits(struct af9013_state *state, u16 reg, int pos, + int len, u8 val) { int ret; u8 tmp, mask; - ret = af9013_read_reg(state, reg, &tmp); - if (ret) - return ret; + /* no need for read if whole reg is written */ + if (len != 8) { + ret = af9013_rd_reg(state, reg, &tmp); + if (ret) + return ret; - mask = regmask[len - 1] << pos; - tmp = (tmp & ~mask) | ((val << pos) & mask); + mask = (0xff >> (8 - len)) << pos; + val <<= pos; + tmp &= ~mask; + val |= tmp; + } - return af9013_write_reg(state, reg, tmp); + return af9013_wr_reg(state, reg, val); } -static int af9013_read_reg_bits(struct af9013_state *state, u16 reg, u8 pos, - u8 len, u8 *val) +static int af9013_rd_reg_bits(struct af9013_state *state, u16 reg, int pos, + int len, u8 *val) { int ret; u8 tmp; - ret = af9013_read_reg(state, reg, &tmp); + ret = af9013_rd_reg(state, reg, &tmp); if (ret) return ret; - *val = (tmp >> pos) & regmask[len - 1]; + + *val = (tmp >> pos); + *val &= (0xff >> (8 - len)); + return 0; } @@ -157,10 +219,13 @@ static int af9013_set_gpio(struct af9013_state *state, u8 gpio, u8 gpioval) int ret; u8 pos; u16 addr; - deb_info("%s: gpio:%d gpioval:%02x\n", __func__, gpio, gpioval); -/* GPIO0 & GPIO1 0xd735 - GPIO2 & GPIO3 0xd736 */ + dbg("%s: gpio=%d gpioval=%02x", __func__, gpio, gpioval); + + /* + * GPIO0 & GPIO1 0xd735 + * GPIO2 & GPIO3 0xd736 + */ switch (gpio) { case 0: @@ -175,7 +240,7 @@ static int af9013_set_gpio(struct af9013_state *state, u8 gpio, u8 gpioval) default: err("invalid gpio:%d\n", gpio); ret = -EINVAL; - goto error; + goto err; }; switch (gpio) { @@ -190,16 +255,21 @@ static int af9013_set_gpio(struct af9013_state *state, u8 gpio, u8 gpioval) break; }; - ret = af9013_write_reg_bits(state, addr, pos, 4, gpioval); + ret = af9013_wr_reg_bits(state, addr, pos, 4, gpioval); + if (ret) + goto err; -error: + return ret; +err: + dbg("%s: failed=%d", __func__, ret); return ret; } static u32 af913_div(u32 a, u32 b, u32 x) { u32 r = 0, c = 0, i; - deb_info("%s: a:%d b:%d x:%d\n", __func__, a, b, x); + + dbg("%s: a=%d b=%d x=%d", __func__, a, b, x); if (a > b) { c = a / b; @@ -216,205 +286,407 @@ static u32 af913_div(u32 a, u32 b, u32 x) } r = (c << (u32)x) + r; - deb_info("%s: a:%d b:%d x:%d r:%d r:%x\n", __func__, a, b, x, r, r); + dbg("%s: a=%d b=%d x=%d r=%x", __func__, a, b, x, r); return r; } -static int af9013_set_coeff(struct af9013_state *state, fe_bandwidth_t bw) +static int af9013_power_ctrl(struct af9013_state *state, u8 onoff) { - int ret, i, j, found; - deb_info("%s: adc_clock:%d bw:%d\n", __func__, - state->config.adc_clock, bw); - - /* lookup coeff from table */ - for (i = 0, found = 0; i < ARRAY_SIZE(coeff_table); i++) { - if (coeff_table[i].adc_clock == state->config.adc_clock && - coeff_table[i].bw == bw) { - found = 1; - break; - } - } + int ret, i; + u8 tmp; - if (!found) { - err("invalid bw or clock"); - ret = -EINVAL; - goto error; + dbg("%s: onoff=%d", __func__, onoff); + + /* enable reset */ + ret = af9013_wr_reg_bits(state, 0xd417, 4, 1, 1); + if (ret) + goto err; + + /* start reset mechanism */ + ret = af9013_wr_reg(state, 0xaeff, 1); + if (ret) + goto err; + + /* wait reset performs */ + for (i = 0; i < 150; i++) { + ret = af9013_rd_reg_bits(state, 0xd417, 1, 1, &tmp); + if (ret) + goto err; + + if (tmp) + break; /* reset done */ + + usleep_range(5000, 25000); } - deb_info("%s: coeff: ", __func__); - debug_dump(coeff_table[i].val, sizeof(coeff_table[i].val), deb_info); + if (!tmp) + return -ETIMEDOUT; - /* program */ - for (j = 0; j < sizeof(coeff_table[i].val); j++) { - ret = af9013_write_reg(state, 0xae00 + j, - coeff_table[i].val[j]); + if (onoff) { + /* clear reset */ + ret = af9013_wr_reg_bits(state, 0xd417, 1, 1, 0); if (ret) - break; + goto err; + + /* disable reset */ + ret = af9013_wr_reg_bits(state, 0xd417, 4, 1, 0); + + /* power on */ + ret = af9013_wr_reg_bits(state, 0xd73a, 3, 1, 0); + } else { + /* power off */ + ret = af9013_wr_reg_bits(state, 0xd73a, 3, 1, 1); } -error: + return ret; +err: + dbg("%s: failed=%d", __func__, ret); + return ret; +} + +static int af9013_statistics_ber_unc_start(struct dvb_frontend *fe) +{ + struct af9013_state *state = fe->demodulator_priv; + int ret; + + dbg("%s", __func__); + + /* reset and start BER counter */ + ret = af9013_wr_reg_bits(state, 0xd391, 4, 1, 1); + if (ret) + goto err; + + return ret; +err: + dbg("%s: failed=%d", __func__, ret); return ret; } -static int af9013_set_adc_ctrl(struct af9013_state *state) +static int af9013_statistics_ber_unc_result(struct dvb_frontend *fe) { + struct af9013_state *state = fe->demodulator_priv; int ret; - u8 buf[3], tmp, i; - u32 adc_cw; + u8 buf[5]; - deb_info("%s: adc_clock:%d\n", __func__, state->config.adc_clock); + dbg("%s", __func__); - /* adc frequency type */ - switch (state->config.adc_clock) { - case 28800: /* 28.800 MHz */ - tmp = 0; - break; - case 20480: /* 20.480 MHz */ - tmp = 1; + /* check if error bit count is ready */ + ret = af9013_rd_reg_bits(state, 0xd391, 4, 1, &buf[0]); + if (ret) + goto err; + + if (!buf[0]) { + dbg("%s: not ready", __func__); + return 0; + } + + ret = af9013_rd_regs(state, 0xd387, buf, 5); + if (ret) + goto err; + + state->ber = (buf[2] << 16) | (buf[1] << 8) | buf[0]; + state->ucblocks += (buf[4] << 8) | buf[3]; + + return ret; +err: + dbg("%s: failed=%d", __func__, ret); + return ret; +} + +static int af9013_statistics_snr_start(struct dvb_frontend *fe) +{ + struct af9013_state *state = fe->demodulator_priv; + int ret; + + dbg("%s", __func__); + + /* start SNR meas */ + ret = af9013_wr_reg_bits(state, 0xd2e1, 3, 1, 1); + if (ret) + goto err; + + return ret; +err: + dbg("%s: failed=%d", __func__, ret); + return ret; +} + +static int af9013_statistics_snr_result(struct dvb_frontend *fe) +{ + struct af9013_state *state = fe->demodulator_priv; + int ret, i, len; + u8 buf[3], tmp; + u32 snr_val; + const struct af9013_snr *uninitialized_var(snr_lut); + + dbg("%s", __func__); + + /* check if SNR ready */ + ret = af9013_rd_reg_bits(state, 0xd2e1, 3, 1, &tmp); + if (ret) + goto err; + + if (!tmp) { + dbg("%s: not ready", __func__); + return 0; + } + + /* read value */ + ret = af9013_rd_regs(state, 0xd2e3, buf, 3); + if (ret) + goto err; + + snr_val = (buf[2] << 16) | (buf[1] << 8) | buf[0]; + + /* read current modulation */ + ret = af9013_rd_reg(state, 0xd3c1, &tmp); + if (ret) + goto err; + + switch ((tmp >> 6) & 3) { + case 0: + len = ARRAY_SIZE(qpsk_snr_lut); + snr_lut = qpsk_snr_lut; break; - case 28000: /* 28.000 MHz */ - tmp = 2; + case 1: + len = ARRAY_SIZE(qam16_snr_lut); + snr_lut = qam16_snr_lut; break; - case 25000: /* 25.000 MHz */ - tmp = 3; + case 2: + len = ARRAY_SIZE(qam64_snr_lut); + snr_lut = qam64_snr_lut; break; default: - err("invalid xtal"); - return -EINVAL; + goto err; + break; } - adc_cw = af913_div(state->config.adc_clock*1000, 1000000ul, 19ul); + for (i = 0; i < len; i++) { + tmp = snr_lut[i].snr; - buf[0] = (u8) ((adc_cw & 0x000000ff)); - buf[1] = (u8) ((adc_cw & 0x0000ff00) >> 8); - buf[2] = (u8) ((adc_cw & 0x00ff0000) >> 16); + if (snr_val < snr_lut[i].val) + break; + } + state->snr = tmp * 10; /* dB/10 */ - deb_info("%s: adc_cw:", __func__); - debug_dump(buf, sizeof(buf), deb_info); + return ret; +err: + dbg("%s: failed=%d", __func__, ret); + return ret; +} + +static int af9013_statistics_signal_strength(struct dvb_frontend *fe) +{ + struct af9013_state *state = fe->demodulator_priv; + int ret = 0; + u8 buf[2], rf_gain, if_gain; + int signal_strength; + + dbg("%s", __func__); + + if (!state->signal_strength_en) + return 0; + + ret = af9013_rd_regs(state, 0xd07c, buf, 2); + if (ret) + goto err; + + rf_gain = buf[0]; + if_gain = buf[1]; + + signal_strength = (0xffff / \ + (9 * (state->rf_50 + state->if_50) - \ + 11 * (state->rf_80 + state->if_80))) * \ + (10 * (rf_gain + if_gain) - \ + 11 * (state->rf_80 + state->if_80)); + if (signal_strength < 0) + signal_strength = 0; + else if (signal_strength > 0xffff) + signal_strength = 0xffff; + + state->signal_strength = signal_strength; - /* program */ - for (i = 0; i < sizeof(buf); i++) { - ret = af9013_write_reg(state, 0xd180 + i, buf[i]); - if (ret) - goto error; - } - ret = af9013_write_reg_bits(state, 0x9bd2, 0, 4, tmp); -error: + return ret; +err: + dbg("%s: failed=%d", __func__, ret); return ret; } -static int af9013_set_freq_ctrl(struct af9013_state *state, fe_bandwidth_t bw) +static void af9013_statistics_work(struct work_struct *work) { int ret; - u16 addr; - u8 buf[3], i, j; - u32 adc_freq, freq_cw; - s8 bfs_spec_inv; - int if_sample_freq; - - for (j = 0; j < 3; j++) { - if (j == 0) { - addr = 0xd140; /* fcw normal */ - bfs_spec_inv = state->config.rf_spec_inv ? -1 : 1; - } else if (j == 1) { - addr = 0x9be7; /* fcw dummy ram */ - bfs_spec_inv = state->config.rf_spec_inv ? -1 : 1; - } else { - addr = 0x9bea; /* fcw inverted */ - bfs_spec_inv = state->config.rf_spec_inv ? 1 : -1; - } + struct af9013_state *state = container_of(work, + struct af9013_state, statistics_work.work); + unsigned int next_msec; + + /* update only signal strength when demod is not locked */ + if (!(state->fe_status & FE_HAS_LOCK)) { + state->statistics_step = 0; + state->ber = 0; + state->snr = 0; + } + + switch (state->statistics_step) { + default: + state->statistics_step = 0; + case 0: + ret = af9013_statistics_signal_strength(&state->fe); + state->statistics_step++; + next_msec = 300; + break; + case 1: + ret = af9013_statistics_snr_start(&state->fe); + state->statistics_step++; + next_msec = 200; + break; + case 2: + ret = af9013_statistics_ber_unc_start(&state->fe); + state->statistics_step++; + next_msec = 1000; + break; + case 3: + ret = af9013_statistics_snr_result(&state->fe); + state->statistics_step++; + next_msec = 400; + break; + case 4: + ret = af9013_statistics_ber_unc_result(&state->fe); + state->statistics_step++; + next_msec = 100; + break; + } - adc_freq = state->config.adc_clock * 1000; - if_sample_freq = state->config.tuner_if * 1000; + schedule_delayed_work(&state->statistics_work, + msecs_to_jiffies(next_msec)); - /* TDA18271 uses different sampling freq for every bw */ - if (state->config.tuner == AF9013_TUNER_TDA18271) { - switch (bw) { - case BANDWIDTH_6_MHZ: - if_sample_freq = 3300000; /* 3.3 MHz */ - break; - case BANDWIDTH_7_MHZ: - if_sample_freq = 3500000; /* 3.5 MHz */ - break; - case BANDWIDTH_8_MHZ: - default: - if_sample_freq = 4000000; /* 4.0 MHz */ - break; - } - } else if (state->config.tuner == AF9013_TUNER_TDA18218) { - switch (bw) { - case BANDWIDTH_6_MHZ: - if_sample_freq = 3000000; /* 3 MHz */ - break; - case BANDWIDTH_7_MHZ: - if_sample_freq = 3500000; /* 3.5 MHz */ - break; - case BANDWIDTH_8_MHZ: - default: - if_sample_freq = 4000000; /* 4 MHz */ + return; +} + +static int af9013_get_tune_settings(struct dvb_frontend *fe, + struct dvb_frontend_tune_settings *fesettings) +{ + fesettings->min_delay_ms = 800; + fesettings->step_size = 0; + fesettings->max_drift = 0; + + return 0; +} + +static int af9013_set_frontend(struct dvb_frontend *fe) +{ + struct af9013_state *state = fe->demodulator_priv; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + int ret, i, sampling_freq; + bool auto_mode, spec_inv; + u8 buf[6]; + u32 if_frequency, freq_cw; + + dbg("%s: frequency=%d bandwidth_hz=%d", __func__, + c->frequency, c->bandwidth_hz); + + /* program tuner */ + if (fe->ops.tuner_ops.set_params) + fe->ops.tuner_ops.set_params(fe); + + /* program CFOE coefficients */ + if (c->bandwidth_hz != state->bandwidth_hz) { + for (i = 0; i < ARRAY_SIZE(coeff_lut); i++) { + if (coeff_lut[i].clock == state->config.clock && + coeff_lut[i].bandwidth_hz == c->bandwidth_hz) { break; } } - while (if_sample_freq > (adc_freq / 2)) - if_sample_freq = if_sample_freq - adc_freq; + ret = af9013_wr_regs(state, 0xae00, coeff_lut[i].val, + sizeof(coeff_lut[i].val)); + } - if (if_sample_freq >= 0) - bfs_spec_inv = bfs_spec_inv * (-1); + /* program frequency control */ + if (c->bandwidth_hz != state->bandwidth_hz || state->first_tune) { + /* get used IF frequency */ + if (fe->ops.tuner_ops.get_if_frequency) + fe->ops.tuner_ops.get_if_frequency(fe, &if_frequency); else - if_sample_freq = if_sample_freq * (-1); + if_frequency = state->config.if_frequency; + + sampling_freq = if_frequency; - freq_cw = af913_div(if_sample_freq, adc_freq, 23ul); + while (sampling_freq > (state->config.clock / 2)) + sampling_freq -= state->config.clock; - if (bfs_spec_inv == -1) - freq_cw = 0x00800000 - freq_cw; + if (sampling_freq < 0) { + sampling_freq *= -1; + spec_inv = state->config.spec_inv; + } else { + spec_inv = !state->config.spec_inv; + } - buf[0] = (u8) ((freq_cw & 0x000000ff)); - buf[1] = (u8) ((freq_cw & 0x0000ff00) >> 8); - buf[2] = (u8) ((freq_cw & 0x007f0000) >> 16); + freq_cw = af913_div(sampling_freq, state->config.clock, 23); + if (spec_inv) + freq_cw = 0x800000 - freq_cw; - deb_info("%s: freq_cw:", __func__); - debug_dump(buf, sizeof(buf), deb_info); + buf[0] = (freq_cw >> 0) & 0xff; + buf[1] = (freq_cw >> 8) & 0xff; + buf[2] = (freq_cw >> 16) & 0x7f; - /* program */ - for (i = 0; i < sizeof(buf); i++) { - ret = af9013_write_reg(state, addr++, buf[i]); - if (ret) - goto error; - } + freq_cw = 0x800000 - freq_cw; + + buf[3] = (freq_cw >> 0) & 0xff; + buf[4] = (freq_cw >> 8) & 0xff; + buf[5] = (freq_cw >> 16) & 0x7f; + + ret = af9013_wr_regs(state, 0xd140, buf, 3); + if (ret) + goto err; + + ret = af9013_wr_regs(state, 0x9be7, buf, 6); + if (ret) + goto err; } -error: - return ret; -} -static int af9013_set_ofdm_params(struct af9013_state *state, - struct dvb_ofdm_parameters *params, u8 *auto_mode) -{ - int ret; - u8 i, buf[3] = {0, 0, 0}; - *auto_mode = 0; /* set if parameters are requested to auto set */ + /* clear TPS lock flag */ + ret = af9013_wr_reg_bits(state, 0xd330, 3, 1, 1); + if (ret) + goto err; + + /* clear MPEG2 lock flag */ + ret = af9013_wr_reg_bits(state, 0xd507, 6, 1, 0); + if (ret) + goto err; + + /* empty channel function */ + ret = af9013_wr_reg_bits(state, 0x9bfe, 0, 1, 0); + if (ret) + goto err; - /* Try auto-detect transmission parameters in case of AUTO requested or - garbage parameters given by application for compatibility. - MPlayer seems to provide garbage parameters currently. */ + /* empty DVB-T channel function */ + ret = af9013_wr_reg_bits(state, 0x9bc2, 0, 1, 0); + if (ret) + goto err; + + /* transmission parameters */ + auto_mode = false; + memset(buf, 0, 3); - switch (params->transmission_mode) { + switch (c->transmission_mode) { case TRANSMISSION_MODE_AUTO: - *auto_mode = 1; + auto_mode = 1; + break; case TRANSMISSION_MODE_2K: break; case TRANSMISSION_MODE_8K: buf[0] |= (1 << 0); break; default: - deb_info("%s: invalid transmission_mode\n", __func__); - *auto_mode = 1; + dbg("%s: invalid transmission_mode", __func__); + auto_mode = 1; } - switch (params->guard_interval) { + switch (c->guard_interval) { case GUARD_INTERVAL_AUTO: - *auto_mode = 1; + auto_mode = 1; + break; case GUARD_INTERVAL_1_32: break; case GUARD_INTERVAL_1_16: @@ -427,13 +699,14 @@ static int af9013_set_ofdm_params(struct af9013_state *state, buf[0] |= (3 << 2); break; default: - deb_info("%s: invalid guard_interval\n", __func__); - *auto_mode = 1; + dbg("%s: invalid guard_interval", __func__); + auto_mode = 1; } - switch (params->hierarchy_information) { + switch (c->hierarchy) { case HIERARCHY_AUTO: - *auto_mode = 1; + auto_mode = 1; + break; case HIERARCHY_NONE: break; case HIERARCHY_1: @@ -446,13 +719,14 @@ static int af9013_set_ofdm_params(struct af9013_state *state, buf[0] |= (3 << 4); break; default: - deb_info("%s: invalid hierarchy_information\n", __func__); - *auto_mode = 1; + dbg("%s: invalid hierarchy", __func__); + auto_mode = 1; }; - switch (params->constellation) { + switch (c->modulation) { case QAM_AUTO: - *auto_mode = 1; + auto_mode = 1; + break; case QPSK: break; case QAM_16: @@ -462,16 +736,17 @@ static int af9013_set_ofdm_params(struct af9013_state *state, buf[1] |= (2 << 6); break; default: - deb_info("%s: invalid constellation\n", __func__); - *auto_mode = 1; + dbg("%s: invalid modulation", __func__); + auto_mode = 1; } /* Use HP. How and which case we can switch to LP? */ buf[1] |= (1 << 4); - switch (params->code_rate_HP) { + switch (c->code_rate_HP) { case FEC_AUTO: - *auto_mode = 1; + auto_mode = 1; + break; case FEC_1_2: break; case FEC_2_3: @@ -487,16 +762,14 @@ static int af9013_set_ofdm_params(struct af9013_state *state, buf[2] |= (4 << 0); break; default: - deb_info("%s: invalid code_rate_HP\n", __func__); - *auto_mode = 1; + dbg("%s: invalid code_rate_HP", __func__); + auto_mode = 1; } - switch (params->code_rate_LP) { + switch (c->code_rate_LP) { case FEC_AUTO: - /* if HIERARCHY_NONE and FEC_NONE then LP FEC is set to FEC_AUTO - by dvb_frontend.c for compatibility */ - if (params->hierarchy_information != HIERARCHY_NONE) - *auto_mode = 1; + auto_mode = 1; + break; case FEC_1_2: break; case FEC_2_3: @@ -512,709 +785,373 @@ static int af9013_set_ofdm_params(struct af9013_state *state, buf[2] |= (4 << 3); break; case FEC_NONE: - if (params->hierarchy_information == HIERARCHY_AUTO) - break; + break; default: - deb_info("%s: invalid code_rate_LP\n", __func__); - *auto_mode = 1; + dbg("%s: invalid code_rate_LP", __func__); + auto_mode = 1; } - switch (params->bandwidth) { - case BANDWIDTH_6_MHZ: + switch (c->bandwidth_hz) { + case 6000000: break; - case BANDWIDTH_7_MHZ: + case 7000000: buf[1] |= (1 << 2); break; - case BANDWIDTH_8_MHZ: + case 8000000: buf[1] |= (2 << 2); break; default: - deb_info("%s: invalid bandwidth\n", __func__); - buf[1] |= (2 << 2); /* cannot auto-detect BW, try 8 MHz */ - } - - /* program */ - for (i = 0; i < sizeof(buf); i++) { - ret = af9013_write_reg(state, 0xd3c0 + i, buf[i]); - if (ret) - break; + dbg("%s: invalid bandwidth_hz", __func__); + ret = -EINVAL; + goto err; } - return ret; -} - -static int af9013_reset(struct af9013_state *state, u8 sleep) -{ - int ret; - u8 tmp, i; - deb_info("%s\n", __func__); - - /* enable OFDM reset */ - ret = af9013_write_reg_bits(state, 0xd417, 4, 1, 1); - if (ret) - goto error; - - /* start reset mechanism */ - ret = af9013_write_reg(state, 0xaeff, 1); + ret = af9013_wr_regs(state, 0xd3c0, buf, 3); if (ret) - goto error; + goto err; - /* reset is done when bit 1 is set */ - for (i = 0; i < 150; i++) { - ret = af9013_read_reg_bits(state, 0xd417, 1, 1, &tmp); - if (ret) - goto error; - if (tmp) - break; /* reset done */ - msleep(10); - } - if (!tmp) - return -ETIMEDOUT; - - /* don't clear reset when going to sleep */ - if (!sleep) { - /* clear OFDM reset */ - ret = af9013_write_reg_bits(state, 0xd417, 1, 1, 0); + if (auto_mode) { + /* clear easy mode flag */ + ret = af9013_wr_reg(state, 0xaefd, 0); if (ret) - goto error; - - /* disable OFDM reset */ - ret = af9013_write_reg_bits(state, 0xd417, 4, 1, 0); - } -error: - return ret; -} - -static int af9013_power_ctrl(struct af9013_state *state, u8 onoff) -{ - int ret; - deb_info("%s: onoff:%d\n", __func__, onoff); + goto err; - if (onoff) { - /* power on */ - ret = af9013_write_reg_bits(state, 0xd73a, 3, 1, 0); - if (ret) - goto error; - ret = af9013_write_reg_bits(state, 0xd417, 1, 1, 0); - if (ret) - goto error; - ret = af9013_write_reg_bits(state, 0xd417, 4, 1, 0); + dbg("%s: auto params", __func__); } else { - /* power off */ - ret = af9013_reset(state, 1); + /* set easy mode flag */ + ret = af9013_wr_reg(state, 0xaefd, 1); if (ret) - goto error; - ret = af9013_write_reg_bits(state, 0xd73a, 3, 1, 1); - } -error: - return ret; -} - -static int af9013_lock_led(struct af9013_state *state, u8 onoff) -{ - deb_info("%s: onoff:%d\n", __func__, onoff); - - return af9013_write_reg_bits(state, 0xd730, 0, 1, onoff); -} - -static int af9013_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) -{ - struct af9013_state *state = fe->demodulator_priv; - int ret; - u8 auto_mode; /* auto set TPS */ + goto err; - deb_info("%s: freq:%d bw:%d\n", __func__, params->frequency, - params->u.ofdm.bandwidth); - - state->frequency = params->frequency; - - /* program tuner */ - if (fe->ops.tuner_ops.set_params) - fe->ops.tuner_ops.set_params(fe, params); - - /* program CFOE coefficients */ - ret = af9013_set_coeff(state, params->u.ofdm.bandwidth); - if (ret) - goto error; - - /* program frequency control */ - ret = af9013_set_freq_ctrl(state, params->u.ofdm.bandwidth); - if (ret) - goto error; - - /* clear TPS lock flag (inverted flag) */ - ret = af9013_write_reg_bits(state, 0xd330, 3, 1, 1); - if (ret) - goto error; - - /* clear MPEG2 lock flag */ - ret = af9013_write_reg_bits(state, 0xd507, 6, 1, 0); - if (ret) - goto error; - - /* empty channel function */ - ret = af9013_write_reg_bits(state, 0x9bfe, 0, 1, 0); - if (ret) - goto error; - - /* empty DVB-T channel function */ - ret = af9013_write_reg_bits(state, 0x9bc2, 0, 1, 0); - if (ret) - goto error; - - /* program TPS and bandwidth, check if auto mode needed */ - ret = af9013_set_ofdm_params(state, ¶ms->u.ofdm, &auto_mode); - if (ret) - goto error; - - if (auto_mode) { - /* clear easy mode flag */ - ret = af9013_write_reg(state, 0xaefd, 0); - deb_info("%s: auto TPS\n", __func__); - } else { - /* set easy mode flag */ - ret = af9013_write_reg(state, 0xaefd, 1); + ret = af9013_wr_reg(state, 0xaefe, 0); if (ret) - goto error; - ret = af9013_write_reg(state, 0xaefe, 0); - deb_info("%s: manual TPS\n", __func__); + goto err; + + dbg("%s: manual params", __func__); } - if (ret) - goto error; - /* everything is set, lets try to receive channel - OFSM GO! */ - ret = af9013_write_reg(state, 0xffff, 0); + /* tune */ + ret = af9013_wr_reg(state, 0xffff, 0); if (ret) - goto error; + goto err; + + state->bandwidth_hz = c->bandwidth_hz; + state->set_frontend_jiffies = jiffies; + state->first_tune = false; -error: + return ret; +err: + dbg("%s: failed=%d", __func__, ret); return ret; } -static int af9013_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int af9013_get_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct af9013_state *state = fe->demodulator_priv; int ret; - u8 i, buf[3]; - deb_info("%s\n", __func__); + u8 buf[3]; - /* read TPS registers */ - for (i = 0; i < 3; i++) { - ret = af9013_read_reg(state, 0xd3c0 + i, &buf[i]); - if (ret) - goto error; - } + dbg("%s", __func__); + + ret = af9013_rd_regs(state, 0xd3c0, buf, 3); + if (ret) + goto err; switch ((buf[1] >> 6) & 3) { case 0: - p->u.ofdm.constellation = QPSK; + c->modulation = QPSK; break; case 1: - p->u.ofdm.constellation = QAM_16; + c->modulation = QAM_16; break; case 2: - p->u.ofdm.constellation = QAM_64; + c->modulation = QAM_64; break; } switch ((buf[0] >> 0) & 3) { case 0: - p->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; + c->transmission_mode = TRANSMISSION_MODE_2K; break; case 1: - p->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; + c->transmission_mode = TRANSMISSION_MODE_8K; } switch ((buf[0] >> 2) & 3) { case 0: - p->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; + c->guard_interval = GUARD_INTERVAL_1_32; break; case 1: - p->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; + c->guard_interval = GUARD_INTERVAL_1_16; break; case 2: - p->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; + c->guard_interval = GUARD_INTERVAL_1_8; break; case 3: - p->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; + c->guard_interval = GUARD_INTERVAL_1_4; break; } switch ((buf[0] >> 4) & 7) { case 0: - p->u.ofdm.hierarchy_information = HIERARCHY_NONE; + c->hierarchy = HIERARCHY_NONE; break; case 1: - p->u.ofdm.hierarchy_information = HIERARCHY_1; + c->hierarchy = HIERARCHY_1; break; case 2: - p->u.ofdm.hierarchy_information = HIERARCHY_2; + c->hierarchy = HIERARCHY_2; break; case 3: - p->u.ofdm.hierarchy_information = HIERARCHY_4; + c->hierarchy = HIERARCHY_4; break; } switch ((buf[2] >> 0) & 7) { case 0: - p->u.ofdm.code_rate_HP = FEC_1_2; + c->code_rate_HP = FEC_1_2; break; case 1: - p->u.ofdm.code_rate_HP = FEC_2_3; + c->code_rate_HP = FEC_2_3; break; case 2: - p->u.ofdm.code_rate_HP = FEC_3_4; + c->code_rate_HP = FEC_3_4; break; case 3: - p->u.ofdm.code_rate_HP = FEC_5_6; + c->code_rate_HP = FEC_5_6; break; case 4: - p->u.ofdm.code_rate_HP = FEC_7_8; + c->code_rate_HP = FEC_7_8; break; } switch ((buf[2] >> 3) & 7) { case 0: - p->u.ofdm.code_rate_LP = FEC_1_2; + c->code_rate_LP = FEC_1_2; break; case 1: - p->u.ofdm.code_rate_LP = FEC_2_3; + c->code_rate_LP = FEC_2_3; break; case 2: - p->u.ofdm.code_rate_LP = FEC_3_4; + c->code_rate_LP = FEC_3_4; break; case 3: - p->u.ofdm.code_rate_LP = FEC_5_6; + c->code_rate_LP = FEC_5_6; break; case 4: - p->u.ofdm.code_rate_LP = FEC_7_8; + c->code_rate_LP = FEC_7_8; break; } switch ((buf[1] >> 2) & 3) { case 0: - p->u.ofdm.bandwidth = BANDWIDTH_6_MHZ; + c->bandwidth_hz = 6000000; break; case 1: - p->u.ofdm.bandwidth = BANDWIDTH_7_MHZ; + c->bandwidth_hz = 7000000; break; case 2: - p->u.ofdm.bandwidth = BANDWIDTH_8_MHZ; + c->bandwidth_hz = 8000000; break; } - p->inversion = INVERSION_AUTO; - p->frequency = state->frequency; - -error: return ret; -} - -static int af9013_update_ber_unc(struct dvb_frontend *fe) -{ - struct af9013_state *state = fe->demodulator_priv; - int ret; - u8 buf[3], i; - u32 error_bit_count = 0; - u32 total_bit_count = 0; - u32 abort_packet_count = 0; - - state->ber = 0; - - /* check if error bit count is ready */ - ret = af9013_read_reg_bits(state, 0xd391, 4, 1, &buf[0]); - if (ret) - goto error; - if (!buf[0]) - goto exit; - - /* get RSD packet abort count */ - for (i = 0; i < 2; i++) { - ret = af9013_read_reg(state, 0xd38a + i, &buf[i]); - if (ret) - goto error; - } - abort_packet_count = (buf[1] << 8) + buf[0]; - - /* get error bit count */ - for (i = 0; i < 3; i++) { - ret = af9013_read_reg(state, 0xd387 + i, &buf[i]); - if (ret) - goto error; - } - error_bit_count = (buf[2] << 16) + (buf[1] << 8) + buf[0]; - error_bit_count = error_bit_count - abort_packet_count * 8 * 8; - - /* get used RSD counting period (10000 RSD packets used) */ - for (i = 0; i < 2; i++) { - ret = af9013_read_reg(state, 0xd385 + i, &buf[i]); - if (ret) - goto error; - } - total_bit_count = (buf[1] << 8) + buf[0]; - total_bit_count = total_bit_count - abort_packet_count; - total_bit_count = total_bit_count * 204 * 8; - - if (total_bit_count) - state->ber = error_bit_count * 1000000000 / total_bit_count; - - state->ucblocks += abort_packet_count; - - deb_info("%s: err bits:%d total bits:%d abort count:%d\n", __func__, - error_bit_count, total_bit_count, abort_packet_count); - - /* set BER counting range */ - ret = af9013_write_reg(state, 0xd385, 10000 & 0xff); - if (ret) - goto error; - ret = af9013_write_reg(state, 0xd386, 10000 >> 8); - if (ret) - goto error; - /* reset and start BER counter */ - ret = af9013_write_reg_bits(state, 0xd391, 4, 1, 1); - if (ret) - goto error; - -exit: -error: +err: + dbg("%s: failed=%d", __func__, ret); return ret; } -static int af9013_update_snr(struct dvb_frontend *fe) +static int af9013_read_status(struct dvb_frontend *fe, fe_status_t *status) { struct af9013_state *state = fe->demodulator_priv; int ret; - u8 buf[3], i, len; - u32 quant = 0; - struct snr_table *uninitialized_var(snr_table); - - /* check if quantizer ready (for snr) */ - ret = af9013_read_reg_bits(state, 0xd2e1, 3, 1, &buf[0]); - if (ret) - goto error; - if (buf[0]) { - /* quantizer ready - read it */ - for (i = 0; i < 3; i++) { - ret = af9013_read_reg(state, 0xd2e3 + i, &buf[i]); - if (ret) - goto error; - } - quant = (buf[2] << 16) + (buf[1] << 8) + buf[0]; - - /* read current constellation */ - ret = af9013_read_reg(state, 0xd3c1, &buf[0]); - if (ret) - goto error; - - switch ((buf[0] >> 6) & 3) { - case 0: - len = ARRAY_SIZE(qpsk_snr_table); - snr_table = qpsk_snr_table; - break; - case 1: - len = ARRAY_SIZE(qam16_snr_table); - snr_table = qam16_snr_table; - break; - case 2: - len = ARRAY_SIZE(qam64_snr_table); - snr_table = qam64_snr_table; - break; - default: - len = 0; - break; - } - - if (len) { - for (i = 0; i < len; i++) { - if (quant < snr_table[i].val) { - state->snr = snr_table[i].snr * 10; - break; - } - } - } - - /* set quantizer super frame count */ - ret = af9013_write_reg(state, 0xd2e2, 1); - if (ret) - goto error; - - /* check quantizer availability */ - for (i = 0; i < 10; i++) { - msleep(10); - ret = af9013_read_reg_bits(state, 0xd2e6, 0, 1, - &buf[0]); - if (ret) - goto error; - if (!buf[0]) - break; - } - - /* reset quantizer */ - ret = af9013_write_reg_bits(state, 0xd2e1, 3, 1, 1); - if (ret) - goto error; - } - -error: - return ret; -} - -static int af9013_update_signal_strength(struct dvb_frontend *fe) -{ - struct af9013_state *state = fe->demodulator_priv; - int ret = 0; - u8 rf_gain, if_gain; - int signal_strength; - - deb_info("%s\n", __func__); + u8 tmp; - if (state->signal_strength_en) { - ret = af9013_read_reg(state, 0xd07c, &rf_gain); - if (ret) - goto error; - ret = af9013_read_reg(state, 0xd07d, &if_gain); - if (ret) - goto error; - signal_strength = (0xffff / \ - (9 * (state->rf_50 + state->if_50) - \ - 11 * (state->rf_80 + state->if_80))) * \ - (10 * (rf_gain + if_gain) - \ - 11 * (state->rf_80 + state->if_80)); - if (signal_strength < 0) - signal_strength = 0; - else if (signal_strength > 0xffff) - signal_strength = 0xffff; - - state->signal_strength = signal_strength; + /* + * Return status from the cache if it is younger than 2000ms with the + * exception of last tune is done during 4000ms. + */ + if (time_is_after_jiffies( + state->read_status_jiffies + msecs_to_jiffies(2000)) && + time_is_before_jiffies( + state->set_frontend_jiffies + msecs_to_jiffies(4000)) + ) { + *status = state->fe_status; + return 0; } else { - state->signal_strength = 0; + *status = 0; } -error: - return ret; -} - -static int af9013_update_statistics(struct dvb_frontend *fe) -{ - struct af9013_state *state = fe->demodulator_priv; - int ret; - - if (time_before(jiffies, state->next_statistics_check)) - return 0; - - /* set minimum statistic update interval */ - state->next_statistics_check = jiffies + msecs_to_jiffies(1200); - - ret = af9013_update_signal_strength(fe); - if (ret) - goto error; - ret = af9013_update_snr(fe); - if (ret) - goto error; - ret = af9013_update_ber_unc(fe); - if (ret) - goto error; - -error: - return ret; -} - -static int af9013_get_tune_settings(struct dvb_frontend *fe, - struct dvb_frontend_tune_settings *fesettings) -{ - fesettings->min_delay_ms = 800; - fesettings->step_size = 0; - fesettings->max_drift = 0; - - return 0; -} - -static int af9013_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct af9013_state *state = fe->demodulator_priv; - int ret = 0; - u8 tmp; - *status = 0; - /* MPEG2 lock */ - ret = af9013_read_reg_bits(state, 0xd507, 6, 1, &tmp); + ret = af9013_rd_reg_bits(state, 0xd507, 6, 1, &tmp); if (ret) - goto error; + goto err; + if (tmp) *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; if (!*status) { /* TPS lock */ - ret = af9013_read_reg_bits(state, 0xd330, 3, 1, &tmp); + ret = af9013_rd_reg_bits(state, 0xd330, 3, 1, &tmp); if (ret) - goto error; + goto err; + if (tmp) *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI; } - if (!*status) { - /* CFO lock */ - ret = af9013_read_reg_bits(state, 0xd333, 7, 1, &tmp); - if (ret) - goto error; - if (tmp) - *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER; - } - - if (!*status) { - /* SFOE lock */ - ret = af9013_read_reg_bits(state, 0xd334, 6, 1, &tmp); - if (ret) - goto error; - if (tmp) - *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER; - } + state->fe_status = *status; + state->read_status_jiffies = jiffies; - if (!*status) { - /* AGC lock */ - ret = af9013_read_reg_bits(state, 0xd1a0, 6, 1, &tmp); - if (ret) - goto error; - if (tmp) - *status |= FE_HAS_SIGNAL; - } - - ret = af9013_update_statistics(fe); - -error: + return ret; +err: + dbg("%s: failed=%d", __func__, ret); return ret; } - -static int af9013_read_ber(struct dvb_frontend *fe, u32 *ber) +static int af9013_read_snr(struct dvb_frontend *fe, u16 *snr) { struct af9013_state *state = fe->demodulator_priv; - int ret; - ret = af9013_update_statistics(fe); - *ber = state->ber; - return ret; + *snr = state->snr; + return 0; } static int af9013_read_signal_strength(struct dvb_frontend *fe, u16 *strength) { struct af9013_state *state = fe->demodulator_priv; - int ret; - ret = af9013_update_statistics(fe); *strength = state->signal_strength; - return ret; + return 0; } -static int af9013_read_snr(struct dvb_frontend *fe, u16 *snr) +static int af9013_read_ber(struct dvb_frontend *fe, u32 *ber) { struct af9013_state *state = fe->demodulator_priv; - int ret; - ret = af9013_update_statistics(fe); - *snr = state->snr; - return ret; + *ber = state->ber; + return 0; } static int af9013_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) { struct af9013_state *state = fe->demodulator_priv; - int ret; - ret = af9013_update_statistics(fe); *ucblocks = state->ucblocks; - return ret; -} - -static int af9013_sleep(struct dvb_frontend *fe) -{ - struct af9013_state *state = fe->demodulator_priv; - int ret; - deb_info("%s\n", __func__); - - ret = af9013_lock_led(state, 0); - if (ret) - goto error; - - ret = af9013_power_ctrl(state, 0); -error: - return ret; + return 0; } static int af9013_init(struct dvb_frontend *fe) { struct af9013_state *state = fe->demodulator_priv; int ret, i, len; - u8 tmp0, tmp1; - struct regdesc *init; - deb_info("%s\n", __func__); + u8 buf[3], tmp; + u32 adc_cw; + const struct af9013_reg_bit *init; - /* reset OFDM */ - ret = af9013_reset(state, 0); - if (ret) - goto error; + dbg("%s", __func__); /* power on */ ret = af9013_power_ctrl(state, 1); if (ret) - goto error; + goto err; /* enable ADC */ - ret = af9013_write_reg(state, 0xd73a, 0xa4); + ret = af9013_wr_reg(state, 0xd73a, 0xa4); if (ret) - goto error; + goto err; /* write API version to firmware */ - for (i = 0; i < sizeof(state->config.api_version); i++) { - ret = af9013_write_reg(state, 0x9bf2 + i, - state->config.api_version[i]); - if (ret) - goto error; - } + ret = af9013_wr_regs(state, 0x9bf2, state->config.api_version, 4); + if (ret) + goto err; /* program ADC control */ - ret = af9013_set_adc_ctrl(state); + switch (state->config.clock) { + case 28800000: /* 28.800 MHz */ + tmp = 0; + break; + case 20480000: /* 20.480 MHz */ + tmp = 1; + break; + case 28000000: /* 28.000 MHz */ + tmp = 2; + break; + case 25000000: /* 25.000 MHz */ + tmp = 3; + break; + default: + err("invalid clock"); + return -EINVAL; + } + + adc_cw = af913_div(state->config.clock, 1000000ul, 19); + buf[0] = (adc_cw >> 0) & 0xff; + buf[1] = (adc_cw >> 8) & 0xff; + buf[2] = (adc_cw >> 16) & 0xff; + + ret = af9013_wr_regs(state, 0xd180, buf, 3); + if (ret) + goto err; + + ret = af9013_wr_reg_bits(state, 0x9bd2, 0, 4, tmp); if (ret) - goto error; + goto err; /* set I2C master clock */ - ret = af9013_write_reg(state, 0xd416, 0x14); + ret = af9013_wr_reg(state, 0xd416, 0x14); if (ret) - goto error; + goto err; /* set 16 embx */ - ret = af9013_write_reg_bits(state, 0xd700, 1, 1, 1); + ret = af9013_wr_reg_bits(state, 0xd700, 1, 1, 1); if (ret) - goto error; + goto err; /* set no trigger */ - ret = af9013_write_reg_bits(state, 0xd700, 2, 1, 0); + ret = af9013_wr_reg_bits(state, 0xd700, 2, 1, 0); if (ret) - goto error; + goto err; /* set read-update bit for constellation */ - ret = af9013_write_reg_bits(state, 0xd371, 1, 1, 1); + ret = af9013_wr_reg_bits(state, 0xd371, 1, 1, 1); if (ret) - goto error; + goto err; - /* enable FEC monitor */ - ret = af9013_write_reg_bits(state, 0xd392, 1, 1, 1); + /* settings for mp2if */ + if (state->config.ts_mode == AF9013_TS_USB) { + /* AF9015 split PSB to 1.5k + 0.5k */ + ret = af9013_wr_reg_bits(state, 0xd50b, 2, 1, 1); + if (ret) + goto err; + } else { + /* AF9013 change the output bit to data7 */ + ret = af9013_wr_reg_bits(state, 0xd500, 3, 1, 1); + if (ret) + goto err; + + /* AF9013 set mpeg to full speed */ + ret = af9013_wr_reg_bits(state, 0xd502, 4, 1, 1); + if (ret) + goto err; + } + + ret = af9013_wr_reg_bits(state, 0xd520, 4, 1, 1); if (ret) - goto error; + goto err; /* load OFSM settings */ - deb_info("%s: load ofsm settings\n", __func__); + dbg("%s: load ofsm settings", __func__); len = ARRAY_SIZE(ofsm_init); init = ofsm_init; for (i = 0; i < len; i++) { - ret = af9013_write_reg_bits(state, init[i].addr, init[i].pos, + ret = af9013_wr_reg_bits(state, init[i].addr, init[i].pos, init[i].len, init[i].val); if (ret) - goto error; + goto err; } /* load tuner specific settings */ - deb_info("%s: load tuner specific settings\n", __func__); + dbg("%s: load tuner specific settings", __func__); switch (state->config.tuner) { case AF9013_TUNER_MXL5003D: len = ARRAY_SIZE(tuner_init_mxl5003d); @@ -1260,65 +1197,133 @@ static int af9013_init(struct dvb_frontend *fe) } for (i = 0; i < len; i++) { - ret = af9013_write_reg_bits(state, init[i].addr, init[i].pos, + ret = af9013_wr_reg_bits(state, init[i].addr, init[i].pos, init[i].len, init[i].val); if (ret) - goto error; + goto err; } - /* set TS mode */ - deb_info("%s: setting ts mode\n", __func__); - tmp0 = 0; /* parallel mode */ - tmp1 = 0; /* serial mode */ - switch (state->config.output_mode) { - case AF9013_OUTPUT_MODE_PARALLEL: - tmp0 = 1; - break; - case AF9013_OUTPUT_MODE_SERIAL: - tmp1 = 1; - break; - case AF9013_OUTPUT_MODE_USB: - /* usb mode for AF9015 */ - default: - break; - } - ret = af9013_write_reg_bits(state, 0xd500, 1, 1, tmp0); /* parallel */ + /* TS mode */ + ret = af9013_wr_reg_bits(state, 0xd500, 1, 2, state->config.ts_mode); if (ret) - goto error; - ret = af9013_write_reg_bits(state, 0xd500, 2, 1, tmp1); /* serial */ - if (ret) - goto error; + goto err; /* enable lock led */ - ret = af9013_lock_led(state, 1); + ret = af9013_wr_reg_bits(state, 0xd730, 0, 1, 1); if (ret) - goto error; + goto err; - /* read values needed for signal strength calculation */ - ret = af9013_read_reg_bits(state, 0x9bee, 0, 1, - &state->signal_strength_en); - if (ret) - goto error; + /* check if we support signal strength */ + if (!state->signal_strength_en) { + ret = af9013_rd_reg_bits(state, 0x9bee, 0, 1, + &state->signal_strength_en); + if (ret) + goto err; + } - if (state->signal_strength_en) { - ret = af9013_read_reg(state, 0x9bbd, &state->rf_50); + /* read values needed for signal strength calculation */ + if (state->signal_strength_en && !state->rf_50) { + ret = af9013_rd_reg(state, 0x9bbd, &state->rf_50); if (ret) - goto error; - ret = af9013_read_reg(state, 0x9bd0, &state->rf_80); + goto err; + + ret = af9013_rd_reg(state, 0x9bd0, &state->rf_80); if (ret) - goto error; - ret = af9013_read_reg(state, 0x9be2, &state->if_50); + goto err; + + ret = af9013_rd_reg(state, 0x9be2, &state->if_50); if (ret) - goto error; - ret = af9013_read_reg(state, 0x9be4, &state->if_80); + goto err; + + ret = af9013_rd_reg(state, 0x9be4, &state->if_80); if (ret) - goto error; + goto err; } -error: + /* SNR */ + ret = af9013_wr_reg(state, 0xd2e2, 1); + if (ret) + goto err; + + /* BER / UCB */ + buf[0] = (10000 >> 0) & 0xff; + buf[1] = (10000 >> 8) & 0xff; + ret = af9013_wr_regs(state, 0xd385, buf, 2); + if (ret) + goto err; + + /* enable FEC monitor */ + ret = af9013_wr_reg_bits(state, 0xd392, 1, 1, 1); + if (ret) + goto err; + + state->first_tune = true; + schedule_delayed_work(&state->statistics_work, msecs_to_jiffies(400)); + + return ret; +err: + dbg("%s: failed=%d", __func__, ret); return ret; } +static int af9013_sleep(struct dvb_frontend *fe) +{ + struct af9013_state *state = fe->demodulator_priv; + int ret; + + dbg("%s", __func__); + + /* stop statistics polling */ + cancel_delayed_work_sync(&state->statistics_work); + + /* disable lock led */ + ret = af9013_wr_reg_bits(state, 0xd730, 0, 1, 0); + if (ret) + goto err; + + /* power off */ + ret = af9013_power_ctrl(state, 0); + if (ret) + goto err; + + return ret; +err: + dbg("%s: failed=%d", __func__, ret); + return ret; +} + +static int af9013_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) +{ + int ret; + struct af9013_state *state = fe->demodulator_priv; + + dbg("%s: enable=%d", __func__, enable); + + /* gate already open or close */ + if (state->i2c_gate_state == enable) + return 0; + + if (state->config.ts_mode == AF9013_TS_USB) + ret = af9013_wr_reg_bits(state, 0xd417, 3, 1, enable); + else + ret = af9013_wr_reg_bits(state, 0xd607, 2, 1, enable); + if (ret) + goto err; + + state->i2c_gate_state = enable; + + return ret; +err: + dbg("%s: failed=%d", __func__, ret); + return ret; +} + +static void af9013_release(struct dvb_frontend *fe) +{ + struct af9013_state *state = fe->demodulator_priv; + kfree(state); +} + static struct dvb_frontend_ops af9013_ops; static int af9013_download_firmware(struct af9013_state *state) @@ -1332,11 +1337,11 @@ static int af9013_download_firmware(struct af9013_state *state) msleep(100); /* check whether firmware is already running */ - ret = af9013_read_reg(state, 0x98be, &val); + ret = af9013_rd_reg(state, 0x98be, &val); if (ret) - goto error; + goto err; else - deb_info("%s: firmware status:%02x\n", __func__, val); + dbg("%s: firmware status=%02x", __func__, val); if (val == 0x0c) /* fw is running, no need for download */ goto exit; @@ -1351,7 +1356,7 @@ static int af9013_download_firmware(struct af9013_state *state) "Please see linux/Documentation/dvb/ for more details" \ " on firmware-problems. (%d)", fw_file, ret); - goto error; + goto err; } info("downloading firmware from file '%s'", fw_file); @@ -1369,7 +1374,7 @@ static int af9013_download_firmware(struct af9013_state *state) ret = af9013_write_ofsm_regs(state, 0x50fc, fw_params, sizeof(fw_params)); if (ret) - goto error_release; + goto err_release; #define FW_ADDR 0x5100 /* firmware start address */ #define LEN_MAX 16 /* max packet size */ @@ -1383,24 +1388,24 @@ static int af9013_download_firmware(struct af9013_state *state) (u8 *) &fw->data[fw->size - remaining], len); if (ret) { err("firmware download failed:%d", ret); - goto error_release; + goto err_release; } } /* request boot firmware */ - ret = af9013_write_reg(state, 0xe205, 1); + ret = af9013_wr_reg(state, 0xe205, 1); if (ret) - goto error_release; + goto err_release; for (i = 0; i < 15; i++) { msleep(100); /* check firmware status */ - ret = af9013_read_reg(state, 0x98be, &val); + ret = af9013_rd_reg(state, 0x98be, &val); if (ret) - goto error_release; + goto err_release; - deb_info("%s: firmware status:%02x\n", __func__, val); + dbg("%s: firmware status=%02x", __func__, val); if (val == 0x0c || val == 0x04) /* success or fail */ break; @@ -1408,43 +1413,21 @@ static int af9013_download_firmware(struct af9013_state *state) if (val == 0x04) { err("firmware did not run"); - ret = -1; + ret = -ENODEV; } else if (val != 0x0c) { err("firmware boot timeout"); - ret = -1; + ret = -ENODEV; } -error_release: +err_release: release_firmware(fw); -error: +err: exit: if (!ret) info("found a '%s' in warm state.", af9013_ops.info.name); return ret; } -static int af9013_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) -{ - int ret; - struct af9013_state *state = fe->demodulator_priv; - deb_info("%s: enable:%d\n", __func__, enable); - - if (state->config.output_mode == AF9013_OUTPUT_MODE_USB) - ret = af9013_write_reg_bits(state, 0xd417, 3, 1, enable); - else - ret = af9013_write_reg_bits(state, 0xd607, 2, 1, enable); - - return ret; -} - -static void af9013_release(struct dvb_frontend *fe) -{ - struct af9013_state *state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops af9013_ops; - struct dvb_frontend *af9013_attach(const struct af9013_config *config, struct i2c_adapter *i2c) { @@ -1455,91 +1438,65 @@ struct dvb_frontend *af9013_attach(const struct af9013_config *config, /* allocate memory for the internal state */ state = kzalloc(sizeof(struct af9013_state), GFP_KERNEL); if (state == NULL) - goto error; + goto err; /* setup the state */ state->i2c = i2c; memcpy(&state->config, config, sizeof(struct af9013_config)); /* download firmware */ - if (state->config.output_mode != AF9013_OUTPUT_MODE_USB) { + if (state->config.ts_mode != AF9013_TS_USB) { ret = af9013_download_firmware(state); if (ret) - goto error; + goto err; } /* firmware version */ - for (i = 0; i < 4; i++) { - ret = af9013_read_reg(state, 0x5103 + i, &buf[i]); - if (ret) - goto error; - } - info("firmware version:%d.%d.%d.%d", buf[0], buf[1], buf[2], buf[3]); - - /* chip version */ - ret = af9013_read_reg_bits(state, 0xd733, 4, 4, &buf[2]); + ret = af9013_rd_regs(state, 0x5103, buf, 4); if (ret) - goto error; + goto err; - /* ROM version */ - for (i = 0; i < 2; i++) { - ret = af9013_read_reg(state, 0x116b + i, &buf[i]); - if (ret) - goto error; - } - deb_info("%s: chip version:%d ROM version:%d.%d\n", __func__, - buf[2], buf[0], buf[1]); - - /* settings for mp2if */ - if (state->config.output_mode == AF9013_OUTPUT_MODE_USB) { - /* AF9015 split PSB to 1.5k + 0.5k */ - ret = af9013_write_reg_bits(state, 0xd50b, 2, 1, 1); - } else { - /* AF9013 change the output bit to data7 */ - ret = af9013_write_reg_bits(state, 0xd500, 3, 1, 1); - if (ret) - goto error; - /* AF9013 set mpeg to full speed */ - ret = af9013_write_reg_bits(state, 0xd502, 4, 1, 1); - } - if (ret) - goto error; - ret = af9013_write_reg_bits(state, 0xd520, 4, 1, 1); - if (ret) - goto error; + info("firmware version %d.%d.%d.%d", buf[0], buf[1], buf[2], buf[3]); /* set GPIOs */ for (i = 0; i < sizeof(state->config.gpio); i++) { ret = af9013_set_gpio(state, i, state->config.gpio[i]); if (ret) - goto error; + goto err; } /* create dvb_frontend */ - memcpy(&state->frontend.ops, &af9013_ops, + memcpy(&state->fe.ops, &af9013_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; + state->fe.demodulator_priv = state; + + INIT_DELAYED_WORK(&state->statistics_work, af9013_statistics_work); - return &state->frontend; -error: + return &state->fe; +err: kfree(state); return NULL; } EXPORT_SYMBOL(af9013_attach); static struct dvb_frontend_ops af9013_ops = { + .delsys = { SYS_DVBT }, .info = { - .name = "Afatech AF9013 DVB-T", - .type = FE_OFDM, + .name = "Afatech AF9013", .frequency_min = 174000000, .frequency_max = 862000000, .frequency_stepsize = 250000, .frequency_tolerance = 0, - .caps = - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | - FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | + .caps = FE_CAN_FEC_1_2 | + FE_CAN_FEC_2_3 | + FE_CAN_FEC_3_4 | + FE_CAN_FEC_5_6 | + FE_CAN_FEC_7_8 | + FE_CAN_FEC_AUTO | + FE_CAN_QPSK | + FE_CAN_QAM_16 | + FE_CAN_QAM_64 | + FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO | @@ -1548,24 +1505,22 @@ static struct dvb_frontend_ops af9013_ops = { }, .release = af9013_release, + .init = af9013_init, .sleep = af9013_sleep, - .i2c_gate_ctrl = af9013_i2c_gate_ctrl, + .get_tune_settings = af9013_get_tune_settings, .set_frontend = af9013_set_frontend, .get_frontend = af9013_get_frontend, - .get_tune_settings = af9013_get_tune_settings, - .read_status = af9013_read_status, - .read_ber = af9013_read_ber, - .read_signal_strength = af9013_read_signal_strength, .read_snr = af9013_read_snr, + .read_signal_strength = af9013_read_signal_strength, + .read_ber = af9013_read_ber, .read_ucblocks = af9013_read_ucblocks, -}; -module_param_named(debug, af9013_debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); + .i2c_gate_ctrl = af9013_i2c_gate_ctrl, +}; MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); MODULE_DESCRIPTION("Afatech AF9013 DVB-T demodulator driver"); diff --git a/drivers/media/dvb/frontends/af9013.h b/drivers/media/dvb/frontends/af9013.h index e53d873f7555..b973fc5a0384 100644 --- a/drivers/media/dvb/frontends/af9013.h +++ b/drivers/media/dvb/frontends/af9013.h @@ -2,6 +2,7 @@ * Afatech AF9013 demodulator driver * * Copyright (C) 2007 Antti Palosaari <crope@iki.fi> + * Copyright (C) 2011 Antti Palosaari <crope@iki.fi> * * Thanks to Afatech who kindly provided information. * @@ -21,33 +22,11 @@ * */ -#ifndef _AF9013_H_ -#define _AF9013_H_ +#ifndef AF9013_H +#define AF9013_H #include <linux/dvb/frontend.h> -enum af9013_ts_mode { - AF9013_OUTPUT_MODE_PARALLEL, - AF9013_OUTPUT_MODE_SERIAL, - AF9013_OUTPUT_MODE_USB, /* only for AF9015 */ -}; - -enum af9013_tuner { - AF9013_TUNER_MXL5003D = 3, /* MaxLinear */ - AF9013_TUNER_MXL5005D = 13, /* MaxLinear */ - AF9013_TUNER_MXL5005R = 30, /* MaxLinear */ - AF9013_TUNER_ENV77H11D5 = 129, /* Panasonic */ - AF9013_TUNER_MT2060 = 130, /* Microtune */ - AF9013_TUNER_MC44S803 = 133, /* Freescale */ - AF9013_TUNER_QT1010 = 134, /* Quantek */ - AF9013_TUNER_UNKNOWN = 140, /* for can tuners ? */ - AF9013_TUNER_MT2060_2 = 147, /* Microtune */ - AF9013_TUNER_TDA18271 = 156, /* NXP */ - AF9013_TUNER_QT1010A = 162, /* Quantek */ - AF9013_TUNER_MXL5007T = 177, /* MaxLinear */ - AF9013_TUNER_TDA18218 = 179, /* NXP */ -}; - /* AF9013/5 GPIOs (mostly guessed) demod#1-gpio#0 - set demod#2 i2c-addr for dual devices demod#1-gpio#1 - xtal setting (?) @@ -55,44 +34,74 @@ enum af9013_tuner { demod#2-gpio#0 - tuner#2 demod#2-gpio#1 - xtal setting (?) */ + +struct af9013_config { + /* + * I2C address + */ + u8 i2c_addr; + + /* + * clock + * 20480000, 25000000, 28000000, 28800000 + */ + u32 clock; + + /* + * tuner + */ +#define AF9013_TUNER_MXL5003D 3 /* MaxLinear */ +#define AF9013_TUNER_MXL5005D 13 /* MaxLinear */ +#define AF9013_TUNER_MXL5005R 30 /* MaxLinear */ +#define AF9013_TUNER_ENV77H11D5 129 /* Panasonic */ +#define AF9013_TUNER_MT2060 130 /* Microtune */ +#define AF9013_TUNER_MC44S803 133 /* Freescale */ +#define AF9013_TUNER_QT1010 134 /* Quantek */ +#define AF9013_TUNER_UNKNOWN 140 /* for can tuners ? */ +#define AF9013_TUNER_MT2060_2 147 /* Microtune */ +#define AF9013_TUNER_TDA18271 156 /* NXP */ +#define AF9013_TUNER_QT1010A 162 /* Quantek */ +#define AF9013_TUNER_MXL5007T 177 /* MaxLinear */ +#define AF9013_TUNER_TDA18218 179 /* NXP */ + u8 tuner; + + /* + * IF frequency + */ + u32 if_frequency; + + /* + * TS settings + */ +#define AF9013_TS_USB 0 +#define AF9013_TS_PARALLEL 1 +#define AF9013_TS_SERIAL 2 + u8 ts_mode:2; + + /* + * input spectrum inversion + */ + bool spec_inv; + + /* + * firmware API version + */ + u8 api_version[4]; + + /* + * GPIOs + */ #define AF9013_GPIO_ON (1 << 0) #define AF9013_GPIO_EN (1 << 1) #define AF9013_GPIO_O (1 << 2) #define AF9013_GPIO_I (1 << 3) - #define AF9013_GPIO_LO (AF9013_GPIO_ON|AF9013_GPIO_EN) #define AF9013_GPIO_HI (AF9013_GPIO_ON|AF9013_GPIO_EN|AF9013_GPIO_O) - #define AF9013_GPIO_TUNER_ON (AF9013_GPIO_ON|AF9013_GPIO_EN) #define AF9013_GPIO_TUNER_OFF (AF9013_GPIO_ON|AF9013_GPIO_EN|AF9013_GPIO_O) - -struct af9013_config { - /* demodulator's I2C address */ - u8 demod_address; - - /* frequencies in kHz */ - u32 adc_clock; - - /* tuner ID */ - u8 tuner; - - /* tuner IF */ - u16 tuner_if; - - /* TS data output mode */ - u8 output_mode:2; - - /* RF spectrum inversion */ - u8 rf_spec_inv:1; - - /* API version */ - u8 api_version[4]; - - /* GPIOs */ u8 gpio[4]; }; - #if defined(CONFIG_DVB_AF9013) || \ (defined(CONFIG_DVB_AF9013_MODULE) && defined(MODULE)) extern struct dvb_frontend *af9013_attach(const struct af9013_config *config, @@ -106,4 +115,4 @@ const struct af9013_config *config, struct i2c_adapter *i2c) } #endif /* CONFIG_DVB_AF9013 */ -#endif /* _AF9013_H_ */ +#endif /* AF9013_H */ diff --git a/drivers/media/dvb/frontends/af9013_priv.h b/drivers/media/dvb/frontends/af9013_priv.h index e00b2a4a2db6..fa848af6e9b4 100644 --- a/drivers/media/dvb/frontends/af9013_priv.h +++ b/drivers/media/dvb/frontends/af9013_priv.h @@ -2,6 +2,7 @@ * Afatech AF9013 demodulator driver * * Copyright (C) 2007 Antti Palosaari <crope@iki.fi> + * Copyright (C) 2011 Antti Palosaari <crope@iki.fi> * * Thanks to Afatech who kindly provided information. * @@ -21,24 +22,19 @@ * */ -#ifndef _AF9013_PRIV_ -#define _AF9013_PRIV_ +#ifndef AF9013_PRIV_H +#define AF9013_PRIV_H -#define LOG_PREFIX "af9013" -extern int af9013_debug; - -#define dprintk(var, level, args...) \ - do { if ((var & level)) printk(args); } while (0) +#include "dvb_frontend.h" +#include "af9013.h" +#include <linux/firmware.h> -#define debug_dump(b, l, func) {\ - int loop_; \ - for (loop_ = 0; loop_ < l; loop_++) \ - func("%02x ", b[loop_]); \ - func("\n");\ -} - -#define deb_info(args...) dprintk(af9013_debug, 0x01, args) +#define LOG_PREFIX "af9013" +#undef dbg +#define dbg(f, arg...) \ + if (af9013_debug) \ + printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg) #undef err #define err(f, arg...) printk(KERN_ERR LOG_PREFIX": " f "\n" , ## arg) #undef info @@ -48,70 +44,71 @@ extern int af9013_debug; #define AF9013_DEFAULT_FIRMWARE "dvb-fe-af9013.fw" -struct regdesc { +struct af9013_reg_bit { u16 addr; u8 pos:4; u8 len:4; u8 val; }; -struct snr_table { +struct af9013_snr { u32 val; u8 snr; }; -struct coeff { - u32 adc_clock; - fe_bandwidth_t bw; +struct af9013_coeff { + u32 clock; + u32 bandwidth_hz; u8 val[24]; }; /* pre-calculated coeff lookup table */ -static struct coeff coeff_table[] = { +static const struct af9013_coeff coeff_lut[] = { /* 28.800 MHz */ - { 28800, BANDWIDTH_8_MHZ, { 0x02, 0x8a, 0x28, 0xa3, 0x05, 0x14, + { 28800000, 8000000, { 0x02, 0x8a, 0x28, 0xa3, 0x05, 0x14, 0x51, 0x11, 0x00, 0xa2, 0x8f, 0x3d, 0x00, 0xa2, 0x8a, 0x29, 0x00, 0xa2, 0x85, 0x14, 0x01, 0x45, 0x14, 0x14 } }, - { 28800, BANDWIDTH_7_MHZ, { 0x02, 0x38, 0xe3, 0x8e, 0x04, 0x71, + { 28800000, 7000000, { 0x02, 0x38, 0xe3, 0x8e, 0x04, 0x71, 0xc7, 0x07, 0x00, 0x8e, 0x3d, 0x55, 0x00, 0x8e, 0x38, 0xe4, 0x00, 0x8e, 0x34, 0x72, 0x01, 0x1c, 0x71, 0x32 } }, - { 28800, BANDWIDTH_6_MHZ, { 0x01, 0xe7, 0x9e, 0x7a, 0x03, 0xcf, + { 28800000, 6000000, { 0x01, 0xe7, 0x9e, 0x7a, 0x03, 0xcf, 0x3c, 0x3d, 0x00, 0x79, 0xeb, 0x6e, 0x00, 0x79, 0xe7, 0x9e, 0x00, 0x79, 0xe3, 0xcf, 0x00, 0xf3, 0xcf, 0x0f } }, /* 20.480 MHz */ - { 20480, BANDWIDTH_8_MHZ, { 0x03, 0x92, 0x49, 0x26, 0x07, 0x24, + { 20480000, 8000000, { 0x03, 0x92, 0x49, 0x26, 0x07, 0x24, 0x92, 0x13, 0x00, 0xe4, 0x99, 0x6e, 0x00, 0xe4, 0x92, 0x49, 0x00, 0xe4, 0x8b, 0x25, 0x01, 0xc9, 0x24, 0x25 } }, - { 20480, BANDWIDTH_7_MHZ, { 0x03, 0x20, 0x00, 0x01, 0x06, 0x40, + { 20480000, 7000000, { 0x03, 0x20, 0x00, 0x01, 0x06, 0x40, 0x00, 0x00, 0x00, 0xc8, 0x06, 0x40, 0x00, 0xc8, 0x00, 0x00, 0x00, 0xc7, 0xf9, 0xc0, 0x01, 0x90, 0x00, 0x00 } }, - { 20480, BANDWIDTH_6_MHZ, { 0x02, 0xad, 0xb6, 0xdc, 0x05, 0x5b, + { 20480000, 6000000, { 0x02, 0xad, 0xb6, 0xdc, 0x05, 0x5b, 0x6d, 0x2e, 0x00, 0xab, 0x73, 0x13, 0x00, 0xab, 0x6d, 0xb7, 0x00, 0xab, 0x68, 0x5c, 0x01, 0x56, 0xdb, 0x1c } }, /* 28.000 MHz */ - { 28000, BANDWIDTH_8_MHZ, { 0x02, 0x9c, 0xbc, 0x15, 0x05, 0x39, + { 28000000, 8000000, { 0x02, 0x9c, 0xbc, 0x15, 0x05, 0x39, 0x78, 0x0a, 0x00, 0xa7, 0x34, 0x3f, 0x00, 0xa7, 0x2f, 0x05, 0x00, 0xa7, 0x29, 0xcc, 0x01, 0x4e, 0x5e, 0x03 } }, - { 28000, BANDWIDTH_7_MHZ, { 0x02, 0x49, 0x24, 0x92, 0x04, 0x92, + { 28000000, 7000000, { 0x02, 0x49, 0x24, 0x92, 0x04, 0x92, 0x49, 0x09, 0x00, 0x92, 0x4d, 0xb7, 0x00, 0x92, 0x49, 0x25, 0x00, 0x92, 0x44, 0x92, 0x01, 0x24, 0x92, 0x12 } }, - { 28000, BANDWIDTH_6_MHZ, { 0x01, 0xf5, 0x8d, 0x10, 0x03, 0xeb, + { 28000000, 6000000, { 0x01, 0xf5, 0x8d, 0x10, 0x03, 0xeb, 0x1a, 0x08, 0x00, 0x7d, 0x67, 0x2f, 0x00, 0x7d, 0x63, 0x44, 0x00, 0x7d, 0x5f, 0x59, 0x00, 0xfa, 0xc6, 0x22 } }, /* 25.000 MHz */ - { 25000, BANDWIDTH_8_MHZ, { 0x02, 0xec, 0xfb, 0x9d, 0x05, 0xd9, + { 25000000, 8000000, { 0x02, 0xec, 0xfb, 0x9d, 0x05, 0xd9, 0xf7, 0x0e, 0x00, 0xbb, 0x44, 0xc1, 0x00, 0xbb, 0x3e, 0xe7, 0x00, 0xbb, 0x39, 0x0d, 0x01, 0x76, 0x7d, 0x34 } }, - { 25000, BANDWIDTH_7_MHZ, { 0x02, 0x8f, 0x5c, 0x29, 0x05, 0x1e, + { 25000000, 7000000, { 0x02, 0x8f, 0x5c, 0x29, 0x05, 0x1e, 0xb8, 0x14, 0x00, 0xa3, 0xdc, 0x29, 0x00, 0xa3, 0xd7, 0x0a, 0x00, 0xa3, 0xd1, 0xec, 0x01, 0x47, 0xae, 0x05 } }, - { 25000, BANDWIDTH_6_MHZ, { 0x02, 0x31, 0xbc, 0xb5, 0x04, 0x63, + { 25000000, 6000000, { 0x02, 0x31, 0xbc, 0xb5, 0x04, 0x63, 0x79, 0x1b, 0x00, 0x8c, 0x73, 0x91, 0x00, 0x8c, 0x6f, 0x2d, 0x00, 0x8c, 0x6a, 0xca, 0x01, 0x18, 0xde, 0x17 } }, }; /* QPSK SNR lookup table */ -static struct snr_table qpsk_snr_table[] = { +static const struct af9013_snr qpsk_snr_lut[] = { + { 0x000000, 0 }, { 0x0b4771, 0 }, { 0x0c1aed, 1 }, { 0x0d0d27, 2 }, @@ -131,7 +128,8 @@ static struct snr_table qpsk_snr_table[] = { }; /* QAM16 SNR lookup table */ -static struct snr_table qam16_snr_table[] = { +static const struct af9013_snr qam16_snr_lut[] = { + { 0x000000, 0 }, { 0x05eb62, 5 }, { 0x05fecf, 6 }, { 0x060b80, 7 }, @@ -151,7 +149,8 @@ static struct snr_table qam16_snr_table[] = { }; /* QAM64 SNR lookup table */ -static struct snr_table qam64_snr_table[] = { +static const struct af9013_snr qam64_snr_lut[] = { + { 0x000000, 0 }, { 0x03109b, 12 }, { 0x0310d4, 13 }, { 0x031920, 14 }, @@ -170,7 +169,7 @@ static struct snr_table qam64_snr_table[] = { { 0xffffff, 27 }, }; -static struct regdesc ofsm_init[] = { +static const struct af9013_reg_bit ofsm_init[] = { { 0xd73a, 0, 8, 0xa1 }, { 0xd73b, 0, 8, 0x1f }, { 0xd73c, 4, 4, 0x0a }, @@ -252,7 +251,7 @@ static struct regdesc ofsm_init[] = { /* Panasonic ENV77H11D5 tuner init AF9013_TUNER_ENV77H11D5 = 129 */ -static struct regdesc tuner_init_env77h11d5[] = { +static const struct af9013_reg_bit tuner_init_env77h11d5[] = { { 0x9bd5, 0, 8, 0x01 }, { 0x9bd6, 0, 8, 0x03 }, { 0x9bbe, 0, 8, 0x01 }, @@ -318,7 +317,7 @@ static struct regdesc tuner_init_env77h11d5[] = { /* Microtune MT2060 tuner init AF9013_TUNER_MT2060 = 130 */ -static struct regdesc tuner_init_mt2060[] = { +static const struct af9013_reg_bit tuner_init_mt2060[] = { { 0x9bd5, 0, 8, 0x01 }, { 0x9bd6, 0, 8, 0x07 }, { 0xd1a0, 1, 1, 0x01 }, @@ -395,7 +394,7 @@ static struct regdesc tuner_init_mt2060[] = { /* Microtune MT2060 tuner init AF9013_TUNER_MT2060_2 = 147 */ -static struct regdesc tuner_init_mt2060_2[] = { +static const struct af9013_reg_bit tuner_init_mt2060_2[] = { { 0x9bd5, 0, 8, 0x01 }, { 0x9bd6, 0, 8, 0x06 }, { 0x9bbe, 0, 8, 0x01 }, @@ -462,7 +461,7 @@ static struct regdesc tuner_init_mt2060_2[] = { /* MaxLinear MXL5003 tuner init AF9013_TUNER_MXL5003D = 3 */ -static struct regdesc tuner_init_mxl5003d[] = { +static const struct af9013_reg_bit tuner_init_mxl5003d[] = { { 0x9bd5, 0, 8, 0x01 }, { 0x9bd6, 0, 8, 0x09 }, { 0xd1a0, 1, 1, 0x01 }, @@ -534,7 +533,7 @@ static struct regdesc tuner_init_mxl5003d[] = { AF9013_TUNER_MXL5005D = 13 AF9013_TUNER_MXL5005R = 30 AF9013_TUNER_MXL5007T = 177 */ -static struct regdesc tuner_init_mxl5005[] = { +static const struct af9013_reg_bit tuner_init_mxl5005[] = { { 0x9bd5, 0, 8, 0x01 }, { 0x9bd6, 0, 8, 0x07 }, { 0xd1a0, 1, 1, 0x01 }, @@ -613,7 +612,7 @@ static struct regdesc tuner_init_mxl5005[] = { /* Quantek QT1010 tuner init AF9013_TUNER_QT1010 = 134 AF9013_TUNER_QT1010A = 162 */ -static struct regdesc tuner_init_qt1010[] = { +static const struct af9013_reg_bit tuner_init_qt1010[] = { { 0x9bd5, 0, 8, 0x01 }, { 0x9bd6, 0, 8, 0x09 }, { 0xd1a0, 1, 1, 0x01 }, @@ -690,7 +689,7 @@ static struct regdesc tuner_init_qt1010[] = { /* Freescale MC44S803 tuner init AF9013_TUNER_MC44S803 = 133 */ -static struct regdesc tuner_init_mc44s803[] = { +static const struct af9013_reg_bit tuner_init_mc44s803[] = { { 0x9bd5, 0, 8, 0x01 }, { 0x9bd6, 0, 8, 0x06 }, { 0xd1a0, 1, 1, 0x01 }, @@ -772,7 +771,7 @@ static struct regdesc tuner_init_mc44s803[] = { /* unknown, probably for tin can tuner, tuner init AF9013_TUNER_UNKNOWN = 140 */ -static struct regdesc tuner_init_unknown[] = { +static const struct af9013_reg_bit tuner_init_unknown[] = { { 0x9bd5, 0, 8, 0x01 }, { 0x9bd6, 0, 8, 0x02 }, { 0xd1a0, 1, 1, 0x01 }, @@ -845,7 +844,7 @@ static struct regdesc tuner_init_unknown[] = { /* NXP TDA18271 & TDA18218 tuner init AF9013_TUNER_TDA18271 = 156 AF9013_TUNER_TDA18218 = 179 */ -static struct regdesc tuner_init_tda18271[] = { +static const struct af9013_reg_bit tuner_init_tda18271[] = { { 0x9bd5, 0, 8, 0x01 }, { 0x9bd6, 0, 8, 0x04 }, { 0xd1a0, 1, 1, 0x01 }, @@ -920,4 +919,4 @@ static struct regdesc tuner_init_tda18271[] = { { 0x9bee, 0, 1, 0x01 }, }; -#endif /* _AF9013_PRIV_ */ +#endif /* AF9013_PRIV_H */ diff --git a/drivers/media/dvb/frontends/atbm8830.c b/drivers/media/dvb/frontends/atbm8830.c index 1539ea1f81ac..a2261ea2cf82 100644 --- a/drivers/media/dvb/frontends/atbm8830.c +++ b/drivers/media/dvb/frontends/atbm8830.c @@ -267,8 +267,7 @@ static void atbm8830_release(struct dvb_frontend *fe) kfree(state); } -static int atbm8830_set_fe(struct dvb_frontend *fe, - struct dvb_frontend_parameters *fe_params) +static int atbm8830_set_fe(struct dvb_frontend *fe) { struct atbm_state *priv = fe->demodulator_priv; int i; @@ -279,7 +278,7 @@ static int atbm8830_set_fe(struct dvb_frontend *fe, if (fe->ops.tuner_ops.set_params) { if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); - fe->ops.tuner_ops.set_params(fe, fe_params); + fe->ops.tuner_ops.set_params(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); } @@ -298,31 +297,31 @@ static int atbm8830_set_fe(struct dvb_frontend *fe, return 0; } -static int atbm8830_get_fe(struct dvb_frontend *fe, - struct dvb_frontend_parameters *fe_params) +static int atbm8830_get_fe(struct dvb_frontend *fe) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; dprintk("%s\n", __func__); /* TODO: get real readings from device */ /* inversion status */ - fe_params->inversion = INVERSION_OFF; + c->inversion = INVERSION_OFF; /* bandwidth */ - fe_params->u.ofdm.bandwidth = BANDWIDTH_8_MHZ; + c->bandwidth_hz = 8000000; - fe_params->u.ofdm.code_rate_HP = FEC_AUTO; - fe_params->u.ofdm.code_rate_LP = FEC_AUTO; + c->code_rate_HP = FEC_AUTO; + c->code_rate_LP = FEC_AUTO; - fe_params->u.ofdm.constellation = QAM_AUTO; + c->modulation = QAM_AUTO; /* transmission mode */ - fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO; + c->transmission_mode = TRANSMISSION_MODE_AUTO; /* guard interval */ - fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_AUTO; + c->guard_interval = GUARD_INTERVAL_AUTO; /* hierarchy */ - fe_params->u.ofdm.hierarchy_information = HIERARCHY_NONE; + c->hierarchy = HIERARCHY_NONE; return 0; } @@ -429,9 +428,9 @@ static int atbm8830_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) } static struct dvb_frontend_ops atbm8830_ops = { + .delsys = { SYS_DMBTH }, .info = { .name = "AltoBeam ATBM8830/8831 DMB-TH", - .type = FE_OFDM, .frequency_min = 474000000, .frequency_max = 858000000, .frequency_stepsize = 10000, diff --git a/drivers/media/dvb/frontends/au8522_dig.c b/drivers/media/dvb/frontends/au8522_dig.c index 1d572940e243..c688b95df486 100644 --- a/drivers/media/dvb/frontends/au8522_dig.c +++ b/drivers/media/dvb/frontends/au8522_dig.c @@ -576,19 +576,19 @@ static int au8522_enable_modulation(struct dvb_frontend *fe, } /* Talk to the demod, set the FEC, GUARD, QAM settings etc */ -static int au8522_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int au8522_set_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct au8522_state *state = fe->demodulator_priv; int ret = -EINVAL; - dprintk("%s(frequency=%d)\n", __func__, p->frequency); + dprintk("%s(frequency=%d)\n", __func__, c->frequency); - if ((state->current_frequency == p->frequency) && - (state->current_modulation == p->u.vsb.modulation)) + if ((state->current_frequency == c->frequency) && + (state->current_modulation == c->modulation)) return 0; - au8522_enable_modulation(fe, p->u.vsb.modulation); + au8522_enable_modulation(fe, c->modulation); /* Allow the demod to settle */ msleep(100); @@ -596,7 +596,7 @@ static int au8522_set_frontend(struct dvb_frontend *fe, if (fe->ops.tuner_ops.set_params) { if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); - ret = fe->ops.tuner_ops.set_params(fe, p); + ret = fe->ops.tuner_ops.set_params(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); } @@ -604,7 +604,7 @@ static int au8522_set_frontend(struct dvb_frontend *fe, if (ret < 0) return ret; - state->current_frequency = p->frequency; + state->current_frequency = c->frequency; return 0; } @@ -862,7 +862,36 @@ static int au8522_read_snr(struct dvb_frontend *fe, u16 *snr) static int au8522_read_signal_strength(struct dvb_frontend *fe, u16 *signal_strength) { - return au8522_read_snr(fe, signal_strength); + /* borrowed from lgdt330x.c + * + * Calculate strength from SNR up to 35dB + * Even though the SNR can go higher than 35dB, + * there is some comfort factor in having a range of + * strong signals that can show at 100% + */ + u16 snr; + u32 tmp; + int ret = au8522_read_snr(fe, &snr); + + *signal_strength = 0; + + if (0 == ret) { + /* The following calculation method was chosen + * purely for the sake of code re-use from the + * other demod drivers that use this method */ + + /* Convert from SNR in dB * 10 to 8.24 fixed-point */ + tmp = (snr * ((1 << 24) / 10)); + + /* Convert from 8.24 fixed-point to + * scale the range 0 - 35*2^24 into 0 - 65535*/ + if (tmp >= 8960 * 0x10000) + *signal_strength = 0xffff; + else + *signal_strength = tmp / 8960; + } + + return ret; } static int au8522_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) @@ -882,13 +911,13 @@ static int au8522_read_ber(struct dvb_frontend *fe, u32 *ber) return au8522_read_ucblocks(fe, ber); } -static int au8522_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int au8522_get_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct au8522_state *state = fe->demodulator_priv; - p->frequency = state->current_frequency; - p->u.vsb.modulation = state->current_modulation; + c->frequency = state->current_frequency; + c->modulation = state->current_modulation; return 0; } @@ -981,10 +1010,9 @@ error: EXPORT_SYMBOL(au8522_attach); static struct dvb_frontend_ops au8522_ops = { - + .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, .info = { .name = "Auvitek AU8522 QAM/8VSB Frontend", - .type = FE_ATSC, .frequency_min = 54000000, .frequency_max = 858000000, .frequency_stepsize = 62500, diff --git a/drivers/media/dvb/frontends/bcm3510.c b/drivers/media/dvb/frontends/bcm3510.c index 8aff5868a5e1..033cd7ad3ca2 100644 --- a/drivers/media/dvb/frontends/bcm3510.c +++ b/drivers/media/dvb/frontends/bcm3510.c @@ -479,16 +479,16 @@ static int bcm3510_set_freq(struct bcm3510_state* st,u32 freq) return -EINVAL; } -static int bcm3510_set_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *p) +static int bcm3510_set_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct bcm3510_state* st = fe->demodulator_priv; struct bcm3510_hab_cmd_ext_acquire cmd; struct bcm3510_hab_cmd_bert_control bert; int ret; memset(&cmd,0,sizeof(cmd)); - switch (p->u.vsb.modulation) { + switch (c->modulation) { case QAM_256: cmd.ACQUIRE0.MODE = 0x1; cmd.ACQUIRE1.SYM_RATE = 0x1; @@ -499,7 +499,8 @@ static int bcm3510_set_frontend(struct dvb_frontend* fe, cmd.ACQUIRE1.SYM_RATE = 0x2; cmd.ACQUIRE1.IF_FREQ = 0x1; break; -/* case QAM_256: +#if 0 + case QAM_256: cmd.ACQUIRE0.MODE = 0x3; break; case QAM_128: @@ -513,7 +514,8 @@ static int bcm3510_set_frontend(struct dvb_frontend* fe, break; case QAM_16: cmd.ACQUIRE0.MODE = 0x7; - break;*/ + break; +#endif case VSB_8: cmd.ACQUIRE0.MODE = 0x8; cmd.ACQUIRE1.SYM_RATE = 0x0; @@ -552,7 +554,8 @@ static int bcm3510_set_frontend(struct dvb_frontend* fe, bcm3510_bert_reset(st); - if ((ret = bcm3510_set_freq(st,p->frequency)) < 0) + ret = bcm3510_set_freq(st, c->frequency); + if (ret < 0) return ret; memset(&st->status1,0,sizeof(st->status1)); @@ -819,10 +822,9 @@ error: EXPORT_SYMBOL(bcm3510_attach); static struct dvb_frontend_ops bcm3510_ops = { - + .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, .info = { .name = "Broadcom BCM3510 VSB/QAM frontend", - .type = FE_ATSC, .frequency_min = 54000000, .frequency_max = 803000000, /* stepsize is just a guess */ diff --git a/drivers/media/dvb/frontends/bsbe1.h b/drivers/media/dvb/frontends/bsbe1.h index 5e431ebd089b..53e4d0dbb745 100644 --- a/drivers/media/dvb/frontends/bsbe1.h +++ b/drivers/media/dvb/frontends/bsbe1.h @@ -69,18 +69,19 @@ static int alps_bsbe1_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ra return 0; } -static int alps_bsbe1_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) +static int alps_bsbe1_tuner_set_params(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; int ret; u8 data[4]; u32 div; struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; struct i2c_adapter *i2c = fe->tuner_priv; - if ((params->frequency < 950000) || (params->frequency > 2150000)) + if ((p->frequency < 950000) || (p->frequency > 2150000)) return -EINVAL; - div = params->frequency / 1000; + div = p->frequency / 1000; data[0] = (div >> 8) & 0x7f; data[1] = div & 0xff; data[2] = 0x80 | ((div & 0x18000) >> 10) | 0x1; diff --git a/drivers/media/dvb/frontends/bsru6.h b/drivers/media/dvb/frontends/bsru6.h index c480c839b302..c2a578e1314d 100644 --- a/drivers/media/dvb/frontends/bsru6.h +++ b/drivers/media/dvb/frontends/bsru6.h @@ -101,23 +101,24 @@ static int alps_bsru6_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ra return 0; } -static int alps_bsru6_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) +static int alps_bsru6_tuner_set_params(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; u8 buf[4]; u32 div; struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; struct i2c_adapter *i2c = fe->tuner_priv; - if ((params->frequency < 950000) || (params->frequency > 2150000)) + if ((p->frequency < 950000) || (p->frequency > 2150000)) return -EINVAL; - div = (params->frequency + (125 - 1)) / 125; // round correctly + div = (p->frequency + (125 - 1)) / 125; /* round correctly */ buf[0] = (div >> 8) & 0x7f; buf[1] = div & 0xff; buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4; buf[3] = 0xC4; - if (params->frequency > 1530000) + if (p->frequency > 1530000) buf[3] = 0xc0; if (fe->ops.i2c_gate_ctrl) diff --git a/drivers/media/dvb/frontends/cx22700.c b/drivers/media/dvb/frontends/cx22700.c index 0142214b0133..f2a90f990ce3 100644 --- a/drivers/media/dvb/frontends/cx22700.c +++ b/drivers/media/dvb/frontends/cx22700.c @@ -121,7 +121,8 @@ static int cx22700_set_inversion (struct cx22700_state* state, int inversion) } } -static int cx22700_set_tps (struct cx22700_state *state, struct dvb_ofdm_parameters *p) +static int cx22700_set_tps(struct cx22700_state *state, + struct dtv_frontend_properties *p) { static const u8 qam_tab [4] = { 0, 1, 0, 2 }; static const u8 fec_tab [6] = { 0, 1, 2, 0, 3, 4 }; @@ -146,25 +147,25 @@ static int cx22700_set_tps (struct cx22700_state *state, struct dvb_ofdm_paramet p->transmission_mode != TRANSMISSION_MODE_8K) return -EINVAL; - if (p->constellation != QPSK && - p->constellation != QAM_16 && - p->constellation != QAM_64) + if (p->modulation != QPSK && + p->modulation != QAM_16 && + p->modulation != QAM_64) return -EINVAL; - if (p->hierarchy_information < HIERARCHY_NONE || - p->hierarchy_information > HIERARCHY_4) + if (p->hierarchy < HIERARCHY_NONE || + p->hierarchy > HIERARCHY_4) return -EINVAL; - if (p->bandwidth < BANDWIDTH_8_MHZ || p->bandwidth > BANDWIDTH_6_MHZ) + if (p->bandwidth_hz > 8000000 || p->bandwidth_hz < 6000000) return -EINVAL; - if (p->bandwidth == BANDWIDTH_7_MHZ) + if (p->bandwidth_hz == 7000000) cx22700_writereg (state, 0x09, cx22700_readreg (state, 0x09 | 0x10)); else cx22700_writereg (state, 0x09, cx22700_readreg (state, 0x09 & ~0x10)); - val = qam_tab[p->constellation - QPSK]; - val |= p->hierarchy_information - HIERARCHY_NONE; + val = qam_tab[p->modulation - QPSK]; + val |= p->hierarchy - HIERARCHY_NONE; cx22700_writereg (state, 0x04, val); @@ -184,7 +185,8 @@ static int cx22700_set_tps (struct cx22700_state *state, struct dvb_ofdm_paramet return 0; } -static int cx22700_get_tps (struct cx22700_state* state, struct dvb_ofdm_parameters *p) +static int cx22700_get_tps(struct cx22700_state *state, + struct dtv_frontend_properties *p) { static const fe_modulation_t qam_tab [3] = { QPSK, QAM_16, QAM_64 }; static const fe_code_rate_t fec_tab [5] = { FEC_1_2, FEC_2_3, FEC_3_4, @@ -199,14 +201,14 @@ static int cx22700_get_tps (struct cx22700_state* state, struct dvb_ofdm_paramet val = cx22700_readreg (state, 0x01); if ((val & 0x7) > 4) - p->hierarchy_information = HIERARCHY_AUTO; + p->hierarchy = HIERARCHY_AUTO; else - p->hierarchy_information = HIERARCHY_NONE + (val & 0x7); + p->hierarchy = HIERARCHY_NONE + (val & 0x7); if (((val >> 3) & 0x3) > 2) - p->constellation = QAM_AUTO; + p->modulation = QAM_AUTO; else - p->constellation = qam_tab[(val >> 3) & 0x3]; + p->modulation = qam_tab[(val >> 3) & 0x3]; val = cx22700_readreg (state, 0x02); @@ -318,33 +320,35 @@ static int cx22700_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) return 0; } -static int cx22700_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) +static int cx22700_set_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct cx22700_state* state = fe->demodulator_priv; cx22700_writereg (state, 0x00, 0x02); /* XXX CHECKME: soft reset*/ cx22700_writereg (state, 0x00, 0x00); if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); + fe->ops.tuner_ops.set_params(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); } - cx22700_set_inversion (state, p->inversion); - cx22700_set_tps (state, &p->u.ofdm); + cx22700_set_inversion(state, c->inversion); + cx22700_set_tps(state, c); cx22700_writereg (state, 0x37, 0x01); /* PAL loop filter off */ cx22700_writereg (state, 0x00, 0x01); /* restart acquire */ return 0; } -static int cx22700_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) +static int cx22700_get_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct cx22700_state* state = fe->demodulator_priv; u8 reg09 = cx22700_readreg (state, 0x09); - p->inversion = reg09 & 0x1 ? INVERSION_ON : INVERSION_OFF; - return cx22700_get_tps (state, &p->u.ofdm); + c->inversion = reg09 & 0x1 ? INVERSION_ON : INVERSION_OFF; + return cx22700_get_tps(state, c); } static int cx22700_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) @@ -401,10 +405,9 @@ error: } static struct dvb_frontend_ops cx22700_ops = { - + .delsys = { SYS_DVBT }, .info = { .name = "Conexant CX22700 DVB-T", - .type = FE_OFDM, .frequency_min = 470000000, .frequency_max = 860000000, .frequency_stepsize = 166667, diff --git a/drivers/media/dvb/frontends/cx22702.c b/drivers/media/dvb/frontends/cx22702.c index 3139558148ba..faba82485086 100644 --- a/drivers/media/dvb/frontends/cx22702.c +++ b/drivers/media/dvb/frontends/cx22702.c @@ -146,7 +146,7 @@ static int cx22702_set_inversion(struct cx22702_state *state, int inversion) /* Retrieve the demod settings */ static int cx22702_get_tps(struct cx22702_state *state, - struct dvb_ofdm_parameters *p) + struct dtv_frontend_properties *p) { u8 val; @@ -157,27 +157,27 @@ static int cx22702_get_tps(struct cx22702_state *state, val = cx22702_readreg(state, 0x01); switch ((val & 0x18) >> 3) { case 0: - p->constellation = QPSK; + p->modulation = QPSK; break; case 1: - p->constellation = QAM_16; + p->modulation = QAM_16; break; case 2: - p->constellation = QAM_64; + p->modulation = QAM_64; break; } switch (val & 0x07) { case 0: - p->hierarchy_information = HIERARCHY_NONE; + p->hierarchy = HIERARCHY_NONE; break; case 1: - p->hierarchy_information = HIERARCHY_1; + p->hierarchy = HIERARCHY_1; break; case 2: - p->hierarchy_information = HIERARCHY_2; + p->hierarchy = HIERARCHY_2; break; case 3: - p->hierarchy_information = HIERARCHY_4; + p->hierarchy = HIERARCHY_4; break; } @@ -260,14 +260,14 @@ static int cx22702_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) } /* Talk to the demod, set the FEC, GUARD, QAM settings etc */ -static int cx22702_set_tps(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int cx22702_set_tps(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; u8 val; struct cx22702_state *state = fe->demodulator_priv; if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); + fe->ops.tuner_ops.set_params(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); } @@ -277,14 +277,14 @@ static int cx22702_set_tps(struct dvb_frontend *fe, /* set bandwidth */ val = cx22702_readreg(state, 0x0C) & 0xcf; - switch (p->u.ofdm.bandwidth) { - case BANDWIDTH_6_MHZ: + switch (p->bandwidth_hz) { + case 6000000: val |= 0x20; break; - case BANDWIDTH_7_MHZ: + case 7000000: val |= 0x10; break; - case BANDWIDTH_8_MHZ: + case 8000000: break; default: dprintk("%s: invalid bandwidth\n", __func__); @@ -292,15 +292,15 @@ static int cx22702_set_tps(struct dvb_frontend *fe, } cx22702_writereg(state, 0x0C, val); - p->u.ofdm.code_rate_LP = FEC_AUTO; /* temp hack as manual not working */ + p->code_rate_LP = FEC_AUTO; /* temp hack as manual not working */ /* use auto configuration? */ - if ((p->u.ofdm.hierarchy_information == HIERARCHY_AUTO) || - (p->u.ofdm.constellation == QAM_AUTO) || - (p->u.ofdm.code_rate_HP == FEC_AUTO) || - (p->u.ofdm.code_rate_LP == FEC_AUTO) || - (p->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO) || - (p->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO)) { + if ((p->hierarchy == HIERARCHY_AUTO) || + (p->modulation == QAM_AUTO) || + (p->code_rate_HP == FEC_AUTO) || + (p->code_rate_LP == FEC_AUTO) || + (p->guard_interval == GUARD_INTERVAL_AUTO) || + (p->transmission_mode == TRANSMISSION_MODE_AUTO)) { /* TPS Source - use hardware driven values */ cx22702_writereg(state, 0x06, 0x10); @@ -316,7 +316,7 @@ static int cx22702_set_tps(struct dvb_frontend *fe, } /* manually programmed values */ - switch (p->u.ofdm.constellation) { /* mask 0x18 */ + switch (p->modulation) { /* mask 0x18 */ case QPSK: val = 0x00; break; @@ -327,10 +327,10 @@ static int cx22702_set_tps(struct dvb_frontend *fe, val = 0x10; break; default: - dprintk("%s: invalid constellation\n", __func__); + dprintk("%s: invalid modulation\n", __func__); return -EINVAL; } - switch (p->u.ofdm.hierarchy_information) { /* mask 0x07 */ + switch (p->hierarchy) { /* mask 0x07 */ case HIERARCHY_NONE: break; case HIERARCHY_1: @@ -348,7 +348,7 @@ static int cx22702_set_tps(struct dvb_frontend *fe, } cx22702_writereg(state, 0x06, val); - switch (p->u.ofdm.code_rate_HP) { /* mask 0x38 */ + switch (p->code_rate_HP) { /* mask 0x38 */ case FEC_NONE: case FEC_1_2: val = 0x00; @@ -369,7 +369,7 @@ static int cx22702_set_tps(struct dvb_frontend *fe, dprintk("%s: invalid code_rate_HP\n", __func__); return -EINVAL; } - switch (p->u.ofdm.code_rate_LP) { /* mask 0x07 */ + switch (p->code_rate_LP) { /* mask 0x07 */ case FEC_NONE: case FEC_1_2: break; @@ -391,7 +391,7 @@ static int cx22702_set_tps(struct dvb_frontend *fe, } cx22702_writereg(state, 0x07, val); - switch (p->u.ofdm.guard_interval) { /* mask 0x0c */ + switch (p->guard_interval) { /* mask 0x0c */ case GUARD_INTERVAL_1_32: val = 0x00; break; @@ -408,7 +408,7 @@ static int cx22702_set_tps(struct dvb_frontend *fe, dprintk("%s: invalid guard_interval\n", __func__); return -EINVAL; } - switch (p->u.ofdm.transmission_mode) { /* mask 0x03 */ + switch (p->transmission_mode) { /* mask 0x03 */ case TRANSMISSION_MODE_2K: break; case TRANSMISSION_MODE_8K: @@ -546,15 +546,15 @@ static int cx22702_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) return 0; } -static int cx22702_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int cx22702_get_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct cx22702_state *state = fe->demodulator_priv; u8 reg0C = cx22702_readreg(state, 0x0C); - p->inversion = reg0C & 0x1 ? INVERSION_ON : INVERSION_OFF; - return cx22702_get_tps(state, &p->u.ofdm); + c->inversion = reg0C & 0x1 ? INVERSION_ON : INVERSION_OFF; + return cx22702_get_tps(state, c); } static int cx22702_get_tune_settings(struct dvb_frontend *fe, @@ -603,10 +603,9 @@ error: EXPORT_SYMBOL(cx22702_attach); static const struct dvb_frontend_ops cx22702_ops = { - + .delsys = { SYS_DVBT }, .info = { .name = "Conexant CX22702 DVB-T", - .type = FE_OFDM, .frequency_min = 177000000, .frequency_max = 858000000, .frequency_stepsize = 166666, diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c index bf9c999aa470..5101f10f2d7a 100644 --- a/drivers/media/dvb/frontends/cx24110.c +++ b/drivers/media/dvb/frontends/cx24110.c @@ -531,26 +531,27 @@ static int cx24110_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) return 0; } -static int cx24110_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) +static int cx24110_set_frontend(struct dvb_frontend *fe) { struct cx24110_state *state = fe->demodulator_priv; - + struct dtv_frontend_properties *p = &fe->dtv_property_cache; if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); + fe->ops.tuner_ops.set_params(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); } - cx24110_set_inversion (state, p->inversion); - cx24110_set_fec (state, p->u.qpsk.fec_inner); - cx24110_set_symbolrate (state, p->u.qpsk.symbol_rate); + cx24110_set_inversion(state, p->inversion); + cx24110_set_fec(state, p->fec_inner); + cx24110_set_symbolrate(state, p->symbol_rate); cx24110_writereg(state,0x04,0x05); /* start acquisition */ return 0; } -static int cx24110_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) +static int cx24110_get_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct cx24110_state *state = fe->demodulator_priv; s32 afc; unsigned sclk; @@ -571,7 +572,7 @@ static int cx24110_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_par p->frequency += afc; p->inversion = (cx24110_readreg (state, 0x22) & 0x10) ? INVERSION_ON : INVERSION_OFF; - p->u.qpsk.fec_inner = cx24110_get_fec (state); + p->fec_inner = cx24110_get_fec(state); return 0; } @@ -623,10 +624,9 @@ error: } static struct dvb_frontend_ops cx24110_ops = { - + .delsys = { SYS_DVBS }, .info = { .name = "Conexant CX24110 DVB-S", - .type = FE_QPSK, .frequency_min = 950000, .frequency_max = 2150000, .frequency_stepsize = 1011, /* kHz for QPSK frontends */ diff --git a/drivers/media/dvb/frontends/cx24113.c b/drivers/media/dvb/frontends/cx24113.c index c341d57d5e81..3883c3b31aef 100644 --- a/drivers/media/dvb/frontends/cx24113.c +++ b/drivers/media/dvb/frontends/cx24113.c @@ -476,21 +476,21 @@ static int cx24113_init(struct dvb_frontend *fe) return ret; } -static int cx24113_set_params(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int cx24113_set_params(struct dvb_frontend *fe) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct cx24113_state *state = fe->tuner_priv; /* for a ROLL-OFF factor of 0.35, 0.2: 600, 0.25: 625 */ u32 roll_off = 675; u32 bw; - bw = ((p->u.qpsk.symbol_rate/100) * roll_off) / 1000; + bw = ((c->symbol_rate/100) * roll_off) / 1000; bw += (10000000/100) + 5; bw /= 10; bw += 1000; cx24113_set_bandwidth(state, bw); - cx24113_set_frequency(state, p->frequency); + cx24113_set_frequency(state, c->frequency); msleep(5); return cx24113_get_status(fe, &bw); } @@ -547,11 +547,9 @@ static const struct dvb_tuner_ops cx24113_tuner_ops = { .release = cx24113_release, .init = cx24113_init, - .sleep = NULL, .set_params = cx24113_set_params, .get_frequency = cx24113_get_frequency, - .get_bandwidth = NULL, .get_status = cx24113_get_status, }; diff --git a/drivers/media/dvb/frontends/cx24116.c b/drivers/media/dvb/frontends/cx24116.c index ccd05255d527..b48879186537 100644 --- a/drivers/media/dvb/frontends/cx24116.c +++ b/drivers/media/dvb/frontends/cx24116.c @@ -1212,25 +1212,10 @@ static int cx24116_sleep(struct dvb_frontend *fe) return 0; } -static int cx24116_set_property(struct dvb_frontend *fe, - struct dtv_property *tvp) -{ - dprintk("%s(..)\n", __func__); - return 0; -} - -static int cx24116_get_property(struct dvb_frontend *fe, - struct dtv_property *tvp) -{ - dprintk("%s(..)\n", __func__); - return 0; -} - /* dvb-core told us to tune, the tv property cache will be complete, * it's safe for is to pull values and use them for tuning purposes. */ -static int cx24116_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int cx24116_set_frontend(struct dvb_frontend *fe) { struct cx24116_state *state = fe->demodulator_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache; @@ -1455,12 +1440,20 @@ tuned: /* Set/Reset B/W */ return cx24116_cmd_execute(fe, &cmd); } -static int cx24116_tune(struct dvb_frontend *fe, struct dvb_frontend_parameters *params, +static int cx24116_tune(struct dvb_frontend *fe, bool re_tune, unsigned int mode_flags, unsigned int *delay, fe_status_t *status) { + /* + * It is safe to discard "params" here, as the DVB core will sync + * fe->dtv_property_cache with fepriv->parameters_in, where the + * DVBv3 params are stored. The only practical usage for it indicate + * that re-tuning is needed, e. g. (fepriv->state & FESTATE_RETUNE) is + * true. + */ + *delay = HZ / 5; - if (params) { - int ret = cx24116_set_frontend(fe, params); + if (re_tune) { + int ret = cx24116_set_frontend(fe); if (ret) return ret; } @@ -1473,10 +1466,9 @@ static int cx24116_get_algo(struct dvb_frontend *fe) } static struct dvb_frontend_ops cx24116_ops = { - + .delsys = { SYS_DVBS, SYS_DVBS2 }, .info = { .name = "Conexant CX24116/CX24118", - .type = FE_QPSK, .frequency_min = 950000, .frequency_max = 2150000, .frequency_stepsize = 1011, /* kHz for QPSK frontends */ @@ -1507,8 +1499,6 @@ static struct dvb_frontend_ops cx24116_ops = { .get_frontend_algo = cx24116_get_algo, .tune = cx24116_tune, - .set_property = cx24116_set_property, - .get_property = cx24116_get_property, .set_frontend = cx24116_set_frontend, }; diff --git a/drivers/media/dvb/frontends/cx24123.c b/drivers/media/dvb/frontends/cx24123.c index b1dd8acc607a..7e28b4ee7d4f 100644 --- a/drivers/media/dvb/frontends/cx24123.c +++ b/drivers/media/dvb/frontends/cx24123.c @@ -526,9 +526,9 @@ static int cx24123_set_symbolrate(struct cx24123_state *state, u32 srate) * to be configured and the correct band selected. * Calculate those values. */ -static int cx24123_pll_calculate(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int cx24123_pll_calculate(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct cx24123_state *state = fe->demodulator_priv; u32 ndiv = 0, adiv = 0, vco_div = 0; int i = 0; @@ -548,8 +548,8 @@ static int cx24123_pll_calculate(struct dvb_frontend *fe, * FILTUNE programming bits */ for (i = 0; i < ARRAY_SIZE(cx24123_AGC_vals); i++) { agcv = &cx24123_AGC_vals[i]; - if ((agcv->symbolrate_low <= p->u.qpsk.symbol_rate) && - (agcv->symbolrate_high >= p->u.qpsk.symbol_rate)) { + if ((agcv->symbolrate_low <= p->symbol_rate) && + (agcv->symbolrate_high >= p->symbol_rate)) { state->VCAarg = agcv->VCAprogdata; state->VGAarg = agcv->VGAprogdata; state->FILTune = agcv->FILTune; @@ -601,8 +601,7 @@ static int cx24123_pll_calculate(struct dvb_frontend *fe, * Tuner cx24109 is written through a dedicated 3wire interface * on the demod chip. */ -static int cx24123_pll_writereg(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p, u32 data) +static int cx24123_pll_writereg(struct dvb_frontend *fe, u32 data) { struct cx24123_state *state = fe->demodulator_priv; unsigned long timeout; @@ -659,26 +658,26 @@ static int cx24123_pll_writereg(struct dvb_frontend *fe, return 0; } -static int cx24123_pll_tune(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int cx24123_pll_tune(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct cx24123_state *state = fe->demodulator_priv; u8 val; dprintk("frequency=%i\n", p->frequency); - if (cx24123_pll_calculate(fe, p) != 0) { + if (cx24123_pll_calculate(fe) != 0) { err("%s: cx24123_pll_calcutate failed\n", __func__); return -EINVAL; } /* Write the new VCO/VGA */ - cx24123_pll_writereg(fe, p, state->VCAarg); - cx24123_pll_writereg(fe, p, state->VGAarg); + cx24123_pll_writereg(fe, state->VCAarg); + cx24123_pll_writereg(fe, state->VGAarg); /* Write the new bandselect and pll args */ - cx24123_pll_writereg(fe, p, state->bandselectarg); - cx24123_pll_writereg(fe, p, state->pllarg); + cx24123_pll_writereg(fe, state->bandselectarg); + cx24123_pll_writereg(fe, state->pllarg); /* set the FILTUNE voltage */ val = cx24123_readreg(state, 0x28) & ~0x3; @@ -925,10 +924,10 @@ static int cx24123_read_snr(struct dvb_frontend *fe, u16 *snr) return 0; } -static int cx24123_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int cx24123_set_frontend(struct dvb_frontend *fe) { struct cx24123_state *state = fe->demodulator_priv; + struct dtv_frontend_properties *p = &fe->dtv_property_cache; dprintk("\n"); @@ -936,16 +935,16 @@ static int cx24123_set_frontend(struct dvb_frontend *fe, state->config->set_ts_params(fe, 0); state->currentfreq = p->frequency; - state->currentsymbolrate = p->u.qpsk.symbol_rate; + state->currentsymbolrate = p->symbol_rate; cx24123_set_inversion(state, p->inversion); - cx24123_set_fec(state, p->u.qpsk.fec_inner); - cx24123_set_symbolrate(state, p->u.qpsk.symbol_rate); + cx24123_set_fec(state, p->fec_inner); + cx24123_set_symbolrate(state, p->symbol_rate); if (!state->config->dont_use_pll) - cx24123_pll_tune(fe, p); + cx24123_pll_tune(fe); else if (fe->ops.tuner_ops.set_params) - fe->ops.tuner_ops.set_params(fe, p); + fe->ops.tuner_ops.set_params(fe); else err("it seems I don't have a tuner..."); @@ -960,9 +959,9 @@ static int cx24123_set_frontend(struct dvb_frontend *fe, return 0; } -static int cx24123_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int cx24123_get_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct cx24123_state *state = fe->demodulator_priv; dprintk("\n"); @@ -971,12 +970,12 @@ static int cx24123_get_frontend(struct dvb_frontend *fe, err("%s: Failed to get inversion status\n", __func__); return -EREMOTEIO; } - if (cx24123_get_fec(state, &p->u.qpsk.fec_inner) != 0) { + if (cx24123_get_fec(state, &p->fec_inner) != 0) { err("%s: Failed to get fec status\n", __func__); return -EREMOTEIO; } p->frequency = state->currentfreq; - p->u.qpsk.symbol_rate = state->currentsymbolrate; + p->symbol_rate = state->currentsymbolrate; return 0; } @@ -1007,15 +1006,15 @@ static int cx24123_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) } static int cx24123_tune(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params, + bool re_tune, unsigned int mode_flags, unsigned int *delay, fe_status_t *status) { int retval = 0; - if (params != NULL) - retval = cx24123_set_frontend(fe, params); + if (re_tune) + retval = cx24123_set_frontend(fe); if (!(mode_flags & FE_TUNE_MODE_ONESHOT)) cx24123_read_status(fe, status); @@ -1126,10 +1125,9 @@ error: EXPORT_SYMBOL(cx24123_attach); static struct dvb_frontend_ops cx24123_ops = { - + .delsys = { SYS_DVBS }, .info = { .name = "Conexant CX24123/CX24109", - .type = FE_QPSK, .frequency_min = 950000, .frequency_max = 2150000, .frequency_stepsize = 1011, /* kHz for QPSK frontends */ diff --git a/drivers/media/dvb/frontends/cxd2820r.h b/drivers/media/dvb/frontends/cxd2820r.h index 03cab7b547fb..cf0f546aa1d1 100644 --- a/drivers/media/dvb/frontends/cxd2820r.h +++ b/drivers/media/dvb/frontends/cxd2820r.h @@ -63,19 +63,6 @@ struct cxd2820r_config { */ bool spec_inv; - /* IFs for all used modes. - * Default: none, must set - * Values: <kHz> - */ - u16 if_dvbt_6; - u16 if_dvbt_7; - u16 if_dvbt_8; - u16 if_dvbt2_5; - u16 if_dvbt2_6; - u16 if_dvbt2_7; - u16 if_dvbt2_8; - u16 if_dvbc; - /* GPIOs for all used modes. * Default: none, disabled * Values: <see above> diff --git a/drivers/media/dvb/frontends/cxd2820r_c.c b/drivers/media/dvb/frontends/cxd2820r_c.c index b85f5011e344..945404991529 100644 --- a/drivers/media/dvb/frontends/cxd2820r_c.c +++ b/drivers/media/dvb/frontends/cxd2820r_c.c @@ -21,13 +21,13 @@ #include "cxd2820r_priv.h" -int cxd2820r_set_frontend_c(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) +int cxd2820r_set_frontend_c(struct dvb_frontend *fe) { struct cxd2820r_priv *priv = fe->demodulator_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache; int ret, i; u8 buf[2]; + u32 if_freq; u16 if_ctl; u64 num; struct reg_val_mask tab[] = { @@ -56,9 +56,9 @@ int cxd2820r_set_frontend_c(struct dvb_frontend *fe, /* program tuner */ if (fe->ops.tuner_ops.set_params) - fe->ops.tuner_ops.set_params(fe, params); + fe->ops.tuner_ops.set_params(fe); - if (priv->delivery_system != SYS_DVBC_ANNEX_AC) { + if (priv->delivery_system != SYS_DVBC_ANNEX_A) { for (i = 0; i < ARRAY_SIZE(tab); i++) { ret = cxd2820r_wr_reg_mask(priv, tab[i].reg, tab[i].val, tab[i].mask); @@ -67,10 +67,20 @@ int cxd2820r_set_frontend_c(struct dvb_frontend *fe, } } - priv->delivery_system = SYS_DVBC_ANNEX_AC; + priv->delivery_system = SYS_DVBC_ANNEX_A; priv->ber_running = 0; /* tune stops BER counter */ - num = priv->cfg.if_dvbc; + /* program IF frequency */ + if (fe->ops.tuner_ops.get_if_frequency) { + ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_freq); + if (ret) + goto error; + } else + if_freq = 0; + + dbg("%s: if_freq=%d", __func__, if_freq); + + num = if_freq / 1000; /* Hz => kHz */ num *= 0x4000; if_ctl = cxd2820r_div_u64_round_closest(num, 41000); buf[0] = (if_ctl >> 8) & 0x3f; @@ -94,8 +104,7 @@ error: return ret; } -int cxd2820r_get_frontend_c(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +int cxd2820r_get_frontend_c(struct dvb_frontend *fe) { struct cxd2820r_priv *priv = fe->demodulator_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache; diff --git a/drivers/media/dvb/frontends/cxd2820r_core.c b/drivers/media/dvb/frontends/cxd2820r_core.c index 036480f967b7..93e1b12e7907 100644 --- a/drivers/media/dvb/frontends/cxd2820r_core.c +++ b/drivers/media/dvb/frontends/cxd2820r_core.c @@ -240,422 +240,234 @@ error: return ret; } -/* lock FE */ -static int cxd2820r_lock(struct cxd2820r_priv *priv, int active_fe) -{ - int ret = 0; - dbg("%s: active_fe=%d", __func__, active_fe); - - mutex_lock(&priv->fe_lock); - - /* -1=NONE, 0=DVB-T/T2, 1=DVB-C */ - if (priv->active_fe == active_fe) - ; - else if (priv->active_fe == -1) - priv->active_fe = active_fe; - else - ret = -EBUSY; - - mutex_unlock(&priv->fe_lock); - - return ret; -} - -/* unlock FE */ -static void cxd2820r_unlock(struct cxd2820r_priv *priv, int active_fe) -{ - dbg("%s: active_fe=%d", __func__, active_fe); - - mutex_lock(&priv->fe_lock); - - /* -1=NONE, 0=DVB-T/T2, 1=DVB-C */ - if (priv->active_fe == active_fe) - priv->active_fe = -1; - - mutex_unlock(&priv->fe_lock); - - return; -} - /* 64 bit div with round closest, like DIV_ROUND_CLOSEST but 64 bit */ u32 cxd2820r_div_u64_round_closest(u64 dividend, u32 divisor) { return div_u64(dividend + (divisor / 2), divisor); } -static int cxd2820r_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int cxd2820r_set_frontend(struct dvb_frontend *fe) { - struct cxd2820r_priv *priv = fe->demodulator_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache; int ret; - dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system); - if (fe->ops.info.type == FE_OFDM) { - /* DVB-T/T2 */ - ret = cxd2820r_lock(priv, 0); - if (ret) - return ret; - - switch (priv->delivery_system) { - case SYS_UNDEFINED: - if (c->delivery_system == SYS_DVBT) { - /* SLEEP => DVB-T */ - ret = cxd2820r_set_frontend_t(fe, p); - } else { - /* SLEEP => DVB-T2 */ - ret = cxd2820r_set_frontend_t2(fe, p); - } - break; - case SYS_DVBT: - if (c->delivery_system == SYS_DVBT) { - /* DVB-T => DVB-T */ - ret = cxd2820r_set_frontend_t(fe, p); - } else if (c->delivery_system == SYS_DVBT2) { - /* DVB-T => DVB-T2 */ - ret = cxd2820r_sleep_t(fe); - if (ret) - break; - ret = cxd2820r_set_frontend_t2(fe, p); - } - break; - case SYS_DVBT2: - if (c->delivery_system == SYS_DVBT2) { - /* DVB-T2 => DVB-T2 */ - ret = cxd2820r_set_frontend_t2(fe, p); - } else if (c->delivery_system == SYS_DVBT) { - /* DVB-T2 => DVB-T */ - ret = cxd2820r_sleep_t2(fe); - if (ret) - break; - ret = cxd2820r_set_frontend_t(fe, p); - } - break; - default: - dbg("%s: error state=%d", __func__, - priv->delivery_system); - ret = -EINVAL; - } - } else { - /* DVB-C */ - ret = cxd2820r_lock(priv, 1); - if (ret) - return ret; - - ret = cxd2820r_set_frontend_c(fe, p); + dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system); + switch (c->delivery_system) { + case SYS_DVBT: + ret = cxd2820r_init_t(fe); + if (ret < 0) + goto err; + ret = cxd2820r_set_frontend_t(fe); + if (ret < 0) + goto err; + break; + case SYS_DVBT2: + ret = cxd2820r_init_t(fe); + if (ret < 0) + goto err; + ret = cxd2820r_set_frontend_t2(fe); + if (ret < 0) + goto err; + break; + case SYS_DVBC_ANNEX_A: + ret = cxd2820r_init_c(fe); + if (ret < 0) + goto err; + ret = cxd2820r_set_frontend_c(fe); + if (ret < 0) + goto err; + break; + default: + dbg("%s: error state=%d", __func__, fe->dtv_property_cache.delivery_system); + ret = -EINVAL; + break; } - +err: return ret; } - static int cxd2820r_read_status(struct dvb_frontend *fe, fe_status_t *status) { - struct cxd2820r_priv *priv = fe->demodulator_priv; int ret; - dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system); - - if (fe->ops.info.type == FE_OFDM) { - /* DVB-T/T2 */ - ret = cxd2820r_lock(priv, 0); - if (ret) - return ret; - - switch (fe->dtv_property_cache.delivery_system) { - case SYS_DVBT: - ret = cxd2820r_read_status_t(fe, status); - break; - case SYS_DVBT2: - ret = cxd2820r_read_status_t2(fe, status); - break; - default: - ret = -EINVAL; - } - } else { - /* DVB-C */ - ret = cxd2820r_lock(priv, 1); - if (ret) - return ret; + dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system); + switch (fe->dtv_property_cache.delivery_system) { + case SYS_DVBT: + ret = cxd2820r_read_status_t(fe, status); + break; + case SYS_DVBT2: + ret = cxd2820r_read_status_t2(fe, status); + break; + case SYS_DVBC_ANNEX_A: ret = cxd2820r_read_status_c(fe, status); + break; + default: + ret = -EINVAL; + break; } - return ret; } -static int cxd2820r_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int cxd2820r_get_frontend(struct dvb_frontend *fe) { - struct cxd2820r_priv *priv = fe->demodulator_priv; int ret; - dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system); - if (fe->ops.info.type == FE_OFDM) { - /* DVB-T/T2 */ - ret = cxd2820r_lock(priv, 0); - if (ret) - return ret; - - switch (fe->dtv_property_cache.delivery_system) { - case SYS_DVBT: - ret = cxd2820r_get_frontend_t(fe, p); - break; - case SYS_DVBT2: - ret = cxd2820r_get_frontend_t2(fe, p); - break; - default: - ret = -EINVAL; - } - } else { - /* DVB-C */ - ret = cxd2820r_lock(priv, 1); - if (ret) - return ret; - - ret = cxd2820r_get_frontend_c(fe, p); + dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system); + switch (fe->dtv_property_cache.delivery_system) { + case SYS_DVBT: + ret = cxd2820r_get_frontend_t(fe); + break; + case SYS_DVBT2: + ret = cxd2820r_get_frontend_t2(fe); + break; + case SYS_DVBC_ANNEX_A: + ret = cxd2820r_get_frontend_c(fe); + break; + default: + ret = -EINVAL; + break; } - return ret; } static int cxd2820r_read_ber(struct dvb_frontend *fe, u32 *ber) { - struct cxd2820r_priv *priv = fe->demodulator_priv; int ret; - dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system); - - if (fe->ops.info.type == FE_OFDM) { - /* DVB-T/T2 */ - ret = cxd2820r_lock(priv, 0); - if (ret) - return ret; - - switch (fe->dtv_property_cache.delivery_system) { - case SYS_DVBT: - ret = cxd2820r_read_ber_t(fe, ber); - break; - case SYS_DVBT2: - ret = cxd2820r_read_ber_t2(fe, ber); - break; - default: - ret = -EINVAL; - } - } else { - /* DVB-C */ - ret = cxd2820r_lock(priv, 1); - if (ret) - return ret; + dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system); + switch (fe->dtv_property_cache.delivery_system) { + case SYS_DVBT: + ret = cxd2820r_read_ber_t(fe, ber); + break; + case SYS_DVBT2: + ret = cxd2820r_read_ber_t2(fe, ber); + break; + case SYS_DVBC_ANNEX_A: ret = cxd2820r_read_ber_c(fe, ber); + break; + default: + ret = -EINVAL; + break; } - return ret; } static int cxd2820r_read_signal_strength(struct dvb_frontend *fe, u16 *strength) { - struct cxd2820r_priv *priv = fe->demodulator_priv; int ret; - dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system); - - if (fe->ops.info.type == FE_OFDM) { - /* DVB-T/T2 */ - ret = cxd2820r_lock(priv, 0); - if (ret) - return ret; - - switch (fe->dtv_property_cache.delivery_system) { - case SYS_DVBT: - ret = cxd2820r_read_signal_strength_t(fe, strength); - break; - case SYS_DVBT2: - ret = cxd2820r_read_signal_strength_t2(fe, strength); - break; - default: - ret = -EINVAL; - } - } else { - /* DVB-C */ - ret = cxd2820r_lock(priv, 1); - if (ret) - return ret; + dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system); + switch (fe->dtv_property_cache.delivery_system) { + case SYS_DVBT: + ret = cxd2820r_read_signal_strength_t(fe, strength); + break; + case SYS_DVBT2: + ret = cxd2820r_read_signal_strength_t2(fe, strength); + break; + case SYS_DVBC_ANNEX_A: ret = cxd2820r_read_signal_strength_c(fe, strength); + break; + default: + ret = -EINVAL; + break; } - return ret; } static int cxd2820r_read_snr(struct dvb_frontend *fe, u16 *snr) { - struct cxd2820r_priv *priv = fe->demodulator_priv; int ret; - dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system); - - if (fe->ops.info.type == FE_OFDM) { - /* DVB-T/T2 */ - ret = cxd2820r_lock(priv, 0); - if (ret) - return ret; - - switch (fe->dtv_property_cache.delivery_system) { - case SYS_DVBT: - ret = cxd2820r_read_snr_t(fe, snr); - break; - case SYS_DVBT2: - ret = cxd2820r_read_snr_t2(fe, snr); - break; - default: - ret = -EINVAL; - } - } else { - /* DVB-C */ - ret = cxd2820r_lock(priv, 1); - if (ret) - return ret; + dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system); + switch (fe->dtv_property_cache.delivery_system) { + case SYS_DVBT: + ret = cxd2820r_read_snr_t(fe, snr); + break; + case SYS_DVBT2: + ret = cxd2820r_read_snr_t2(fe, snr); + break; + case SYS_DVBC_ANNEX_A: ret = cxd2820r_read_snr_c(fe, snr); + break; + default: + ret = -EINVAL; + break; } - return ret; } static int cxd2820r_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) { - struct cxd2820r_priv *priv = fe->demodulator_priv; int ret; - dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system); - - if (fe->ops.info.type == FE_OFDM) { - /* DVB-T/T2 */ - ret = cxd2820r_lock(priv, 0); - if (ret) - return ret; - - switch (fe->dtv_property_cache.delivery_system) { - case SYS_DVBT: - ret = cxd2820r_read_ucblocks_t(fe, ucblocks); - break; - case SYS_DVBT2: - ret = cxd2820r_read_ucblocks_t2(fe, ucblocks); - break; - default: - ret = -EINVAL; - } - } else { - /* DVB-C */ - ret = cxd2820r_lock(priv, 1); - if (ret) - return ret; + dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system); + switch (fe->dtv_property_cache.delivery_system) { + case SYS_DVBT: + ret = cxd2820r_read_ucblocks_t(fe, ucblocks); + break; + case SYS_DVBT2: + ret = cxd2820r_read_ucblocks_t2(fe, ucblocks); + break; + case SYS_DVBC_ANNEX_A: ret = cxd2820r_read_ucblocks_c(fe, ucblocks); + break; + default: + ret = -EINVAL; + break; } - return ret; } static int cxd2820r_init(struct dvb_frontend *fe) { - struct cxd2820r_priv *priv = fe->demodulator_priv; - int ret; - dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system); - - priv->delivery_system = SYS_UNDEFINED; - /* delivery system is unknown at that (init) phase */ - - if (fe->ops.info.type == FE_OFDM) { - /* DVB-T/T2 */ - ret = cxd2820r_lock(priv, 0); - if (ret) - return ret; - - ret = cxd2820r_init_t(fe); - } else { - /* DVB-C */ - ret = cxd2820r_lock(priv, 1); - if (ret) - return ret; - - ret = cxd2820r_init_c(fe); - } - - return ret; + return 0; } static int cxd2820r_sleep(struct dvb_frontend *fe) { - struct cxd2820r_priv *priv = fe->demodulator_priv; int ret; - dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system); - - if (fe->ops.info.type == FE_OFDM) { - /* DVB-T/T2 */ - ret = cxd2820r_lock(priv, 0); - if (ret) - return ret; - - switch (fe->dtv_property_cache.delivery_system) { - case SYS_DVBT: - ret = cxd2820r_sleep_t(fe); - break; - case SYS_DVBT2: - ret = cxd2820r_sleep_t2(fe); - break; - default: - ret = -EINVAL; - } - - cxd2820r_unlock(priv, 0); - } else { - /* DVB-C */ - ret = cxd2820r_lock(priv, 1); - if (ret) - return ret; + dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system); + switch (fe->dtv_property_cache.delivery_system) { + case SYS_DVBT: + ret = cxd2820r_sleep_t(fe); + break; + case SYS_DVBT2: + ret = cxd2820r_sleep_t2(fe); + break; + case SYS_DVBC_ANNEX_A: ret = cxd2820r_sleep_c(fe); - - cxd2820r_unlock(priv, 1); + break; + default: + ret = -EINVAL; + break; } - return ret; } static int cxd2820r_get_tune_settings(struct dvb_frontend *fe, - struct dvb_frontend_tune_settings *s) + struct dvb_frontend_tune_settings *s) { - struct cxd2820r_priv *priv = fe->demodulator_priv; int ret; - dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system); - - if (fe->ops.info.type == FE_OFDM) { - /* DVB-T/T2 */ - ret = cxd2820r_lock(priv, 0); - if (ret) - return ret; - - switch (fe->dtv_property_cache.delivery_system) { - case SYS_DVBT: - ret = cxd2820r_get_tune_settings_t(fe, s); - break; - case SYS_DVBT2: - ret = cxd2820r_get_tune_settings_t2(fe, s); - break; - default: - ret = -EINVAL; - } - } else { - /* DVB-C */ - ret = cxd2820r_lock(priv, 1); - if (ret) - return ret; + dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system); + switch (fe->dtv_property_cache.delivery_system) { + case SYS_DVBT: + ret = cxd2820r_get_tune_settings_t(fe, s); + break; + case SYS_DVBT2: + ret = cxd2820r_get_tune_settings_t2(fe, s); + break; + case SYS_DVBC_ANNEX_A: ret = cxd2820r_get_tune_settings_c(fe, s); + break; + default: + ret = -EINVAL; + break; } - return ret; } -static enum dvbfe_search cxd2820r_search(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static enum dvbfe_search cxd2820r_search(struct dvb_frontend *fe) { struct cxd2820r_priv *priv = fe->demodulator_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache; @@ -664,7 +476,7 @@ static enum dvbfe_search cxd2820r_search(struct dvb_frontend *fe, dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system); /* switch between DVB-T and DVB-T2 when tune fails */ - if (priv->last_tune_failed) { + if (priv->last_tune_failed && (priv->delivery_system != SYS_DVBC_ANNEX_A)) { if (priv->delivery_system == SYS_DVBT) c->delivery_system = SYS_DVBT2; else @@ -672,7 +484,7 @@ static enum dvbfe_search cxd2820r_search(struct dvb_frontend *fe, } /* set frontend */ - ret = cxd2820r_set_frontend(fe, p); + ret = cxd2820r_set_frontend(fe); if (ret) goto error; @@ -727,9 +539,7 @@ static void cxd2820r_release(struct dvb_frontend *fe) struct cxd2820r_priv *priv = fe->demodulator_priv; dbg("%s", __func__); - if (fe->ops.info.type == FE_OFDM) - kfree(priv); - + kfree(priv); return; } @@ -742,128 +552,79 @@ static int cxd2820r_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) return cxd2820r_wr_reg_mask(priv, 0xdb, enable ? 1 : 0, 0x1); } -static const struct dvb_frontend_ops cxd2820r_ops[2]; +static const struct dvb_frontend_ops cxd2820r_ops = { + .delsys = { SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A }, + /* default: DVB-T/T2 */ + .info = { + .name = "Sony CXD2820R (DVB-T/T2)", + + .caps = FE_CAN_FEC_1_2 | + FE_CAN_FEC_2_3 | + FE_CAN_FEC_3_4 | + FE_CAN_FEC_5_6 | + FE_CAN_FEC_7_8 | + FE_CAN_FEC_AUTO | + FE_CAN_QPSK | + FE_CAN_QAM_16 | + FE_CAN_QAM_64 | + FE_CAN_QAM_256 | + FE_CAN_QAM_AUTO | + FE_CAN_TRANSMISSION_MODE_AUTO | + FE_CAN_GUARD_INTERVAL_AUTO | + FE_CAN_HIERARCHY_AUTO | + FE_CAN_MUTE_TS | + FE_CAN_2G_MODULATION + }, -struct dvb_frontend *cxd2820r_attach(const struct cxd2820r_config *cfg, - struct i2c_adapter *i2c, struct dvb_frontend *fe) -{ - int ret; - struct cxd2820r_priv *priv = NULL; - u8 tmp; + .release = cxd2820r_release, + .init = cxd2820r_init, + .sleep = cxd2820r_sleep, - if (fe == NULL) { - /* FE0 */ - /* allocate memory for the internal priv */ - priv = kzalloc(sizeof(struct cxd2820r_priv), GFP_KERNEL); - if (priv == NULL) - goto error; + .get_tune_settings = cxd2820r_get_tune_settings, + .i2c_gate_ctrl = cxd2820r_i2c_gate_ctrl, - /* setup the priv */ - priv->i2c = i2c; - memcpy(&priv->cfg, cfg, sizeof(struct cxd2820r_config)); - mutex_init(&priv->fe_lock); + .get_frontend = cxd2820r_get_frontend, - priv->active_fe = -1; /* NONE */ + .get_frontend_algo = cxd2820r_get_frontend_algo, + .search = cxd2820r_search, - /* check if the demod is there */ - priv->bank[0] = priv->bank[1] = 0xff; - ret = cxd2820r_rd_reg(priv, 0x000fd, &tmp); - dbg("%s: chip id=%02x", __func__, tmp); - if (ret || tmp != 0xe1) - goto error; + .read_status = cxd2820r_read_status, + .read_snr = cxd2820r_read_snr, + .read_ber = cxd2820r_read_ber, + .read_ucblocks = cxd2820r_read_ucblocks, + .read_signal_strength = cxd2820r_read_signal_strength, +}; - /* create frontends */ - memcpy(&priv->fe[0].ops, &cxd2820r_ops[0], - sizeof(struct dvb_frontend_ops)); - memcpy(&priv->fe[1].ops, &cxd2820r_ops[1], - sizeof(struct dvb_frontend_ops)); +struct dvb_frontend *cxd2820r_attach(const struct cxd2820r_config *cfg, + struct i2c_adapter *i2c, + struct dvb_frontend *fe) +{ + struct cxd2820r_priv *priv = NULL; + int ret; + u8 tmp; - priv->fe[0].demodulator_priv = priv; - priv->fe[1].demodulator_priv = priv; + priv = kzalloc(sizeof (struct cxd2820r_priv), GFP_KERNEL); + if (!priv) + goto error; - return &priv->fe[0]; + priv->i2c = i2c; + memcpy(&priv->cfg, cfg, sizeof (struct cxd2820r_config)); - } else { - /* FE1: FE0 given as pointer, just return FE1 we have - * already created */ - priv = fe->demodulator_priv; - return &priv->fe[1]; - } + priv->bank[0] = priv->bank[1] = 0xff; + ret = cxd2820r_rd_reg(priv, 0x000fd, &tmp); + dbg("%s: chip id=%02x", __func__, tmp); + if (ret || tmp != 0xe1) + goto error; + memcpy(&priv->fe.ops, &cxd2820r_ops, sizeof (struct dvb_frontend_ops)); + priv->fe.demodulator_priv = priv; + return &priv->fe; error: kfree(priv); return NULL; } EXPORT_SYMBOL(cxd2820r_attach); -static const struct dvb_frontend_ops cxd2820r_ops[2] = { - { - /* DVB-T/T2 */ - .info = { - .name = "Sony CXD2820R (DVB-T/T2)", - .type = FE_OFDM, - .caps = - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | - FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | - FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | - FE_CAN_QAM_64 | FE_CAN_QAM_256 | - FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | - FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_HIERARCHY_AUTO | - FE_CAN_MUTE_TS | - FE_CAN_2G_MODULATION - }, - - .release = cxd2820r_release, - .init = cxd2820r_init, - .sleep = cxd2820r_sleep, - - .get_tune_settings = cxd2820r_get_tune_settings, - .i2c_gate_ctrl = cxd2820r_i2c_gate_ctrl, - - .get_frontend = cxd2820r_get_frontend, - - .get_frontend_algo = cxd2820r_get_frontend_algo, - .search = cxd2820r_search, - - .read_status = cxd2820r_read_status, - .read_snr = cxd2820r_read_snr, - .read_ber = cxd2820r_read_ber, - .read_ucblocks = cxd2820r_read_ucblocks, - .read_signal_strength = cxd2820r_read_signal_strength, - }, - { - /* DVB-C */ - .info = { - .name = "Sony CXD2820R (DVB-C)", - .type = FE_QAM, - .caps = - FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | - FE_CAN_QAM_128 | FE_CAN_QAM_256 | - FE_CAN_FEC_AUTO - }, - - .release = cxd2820r_release, - .init = cxd2820r_init, - .sleep = cxd2820r_sleep, - - .get_tune_settings = cxd2820r_get_tune_settings, - .i2c_gate_ctrl = cxd2820r_i2c_gate_ctrl, - - .set_frontend = cxd2820r_set_frontend, - .get_frontend = cxd2820r_get_frontend, - - .read_status = cxd2820r_read_status, - .read_snr = cxd2820r_read_snr, - .read_ber = cxd2820r_read_ber, - .read_ucblocks = cxd2820r_read_ucblocks, - .read_signal_strength = cxd2820r_read_signal_strength, - }, -}; - - MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); MODULE_DESCRIPTION("Sony CXD2820R demodulator driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/cxd2820r_priv.h b/drivers/media/dvb/frontends/cxd2820r_priv.h index 95539134efdb..9a9822cad9cd 100644 --- a/drivers/media/dvb/frontends/cxd2820r_priv.h +++ b/drivers/media/dvb/frontends/cxd2820r_priv.h @@ -48,12 +48,9 @@ struct reg_val_mask { struct cxd2820r_priv { struct i2c_adapter *i2c; - struct dvb_frontend fe[2]; + struct dvb_frontend fe; struct cxd2820r_config cfg; - struct mutex fe_lock; /*Â FE lock */ - int active_fe:2; /* FE lock, -1=NONE, 0=DVB-T/T2, 1=DVB-C */ - bool ber_running; u8 bank[2]; @@ -89,11 +86,9 @@ int cxd2820r_rd_reg(struct cxd2820r_priv *priv, u32 reg, u8 *val); /* cxd2820r_c.c */ -int cxd2820r_get_frontend_c(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p); +int cxd2820r_get_frontend_c(struct dvb_frontend *fe); -int cxd2820r_set_frontend_c(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params); +int cxd2820r_set_frontend_c(struct dvb_frontend *fe); int cxd2820r_read_status_c(struct dvb_frontend *fe, fe_status_t *status); @@ -114,11 +109,9 @@ int cxd2820r_get_tune_settings_c(struct dvb_frontend *fe, /* cxd2820r_t.c */ -int cxd2820r_get_frontend_t(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p); +int cxd2820r_get_frontend_t(struct dvb_frontend *fe); -int cxd2820r_set_frontend_t(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params); +int cxd2820r_set_frontend_t(struct dvb_frontend *fe); int cxd2820r_read_status_t(struct dvb_frontend *fe, fe_status_t *status); @@ -139,11 +132,9 @@ int cxd2820r_get_tune_settings_t(struct dvb_frontend *fe, /* cxd2820r_t2.c */ -int cxd2820r_get_frontend_t2(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p); +int cxd2820r_get_frontend_t2(struct dvb_frontend *fe); -int cxd2820r_set_frontend_t2(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params); +int cxd2820r_set_frontend_t2(struct dvb_frontend *fe); int cxd2820r_read_status_t2(struct dvb_frontend *fe, fe_status_t *status); diff --git a/drivers/media/dvb/frontends/cxd2820r_t.c b/drivers/media/dvb/frontends/cxd2820r_t.c index a04f9c810101..1a026239cdcc 100644 --- a/drivers/media/dvb/frontends/cxd2820r_t.c +++ b/drivers/media/dvb/frontends/cxd2820r_t.c @@ -21,13 +21,12 @@ #include "cxd2820r_priv.h" -int cxd2820r_set_frontend_t(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +int cxd2820r_set_frontend_t(struct dvb_frontend *fe) { struct cxd2820r_priv *priv = fe->demodulator_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache; - int ret, i; - u32 if_khz, if_ctl; + int ret, i, bw_i; + u32 if_freq, if_ctl; u64 num; u8 buf[3], bw_param; u8 bw_params1[][5] = { @@ -57,6 +56,23 @@ int cxd2820r_set_frontend_t(struct dvb_frontend *fe, dbg("%s: RF=%d BW=%d", __func__, c->frequency, c->bandwidth_hz); + switch (c->bandwidth_hz) { + case 6000000: + bw_i = 0; + bw_param = 2; + break; + case 7000000: + bw_i = 1; + bw_param = 1; + break; + case 8000000: + bw_i = 2; + bw_param = 0; + break; + default: + return -EINVAL; + } + /* update GPIOs */ ret = cxd2820r_gpio(fe); if (ret) @@ -64,7 +80,7 @@ int cxd2820r_set_frontend_t(struct dvb_frontend *fe, /* program tuner */ if (fe->ops.tuner_ops.set_params) - fe->ops.tuner_ops.set_params(fe, p); + fe->ops.tuner_ops.set_params(fe); if (priv->delivery_system != SYS_DVBT) { for (i = 0; i < ARRAY_SIZE(tab); i++) { @@ -78,27 +94,17 @@ int cxd2820r_set_frontend_t(struct dvb_frontend *fe, priv->delivery_system = SYS_DVBT; priv->ber_running = 0; /* tune stops BER counter */ - switch (c->bandwidth_hz) { - case 6000000: - if_khz = priv->cfg.if_dvbt_6; - i = 0; - bw_param = 2; - break; - case 7000000: - if_khz = priv->cfg.if_dvbt_7; - i = 1; - bw_param = 1; - break; - case 8000000: - if_khz = priv->cfg.if_dvbt_8; - i = 2; - bw_param = 0; - break; - default: - return -EINVAL; - } + /* program IF frequency */ + if (fe->ops.tuner_ops.get_if_frequency) { + ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_freq); + if (ret) + goto error; + } else + if_freq = 0; + + dbg("%s: if_freq=%d", __func__, if_freq); - num = if_khz; + num = if_freq / 1000; /* Hz => kHz */ num *= 0x1000000; if_ctl = cxd2820r_div_u64_round_closest(num, 41000); buf[0] = ((if_ctl >> 16) & 0xff); @@ -109,7 +115,7 @@ int cxd2820r_set_frontend_t(struct dvb_frontend *fe, if (ret) goto error; - ret = cxd2820r_wr_regs(priv, 0x0009f, bw_params1[i], 5); + ret = cxd2820r_wr_regs(priv, 0x0009f, bw_params1[bw_i], 5); if (ret) goto error; @@ -117,7 +123,7 @@ int cxd2820r_set_frontend_t(struct dvb_frontend *fe, if (ret) goto error; - ret = cxd2820r_wr_regs(priv, 0x000d9, bw_params2[i], 2); + ret = cxd2820r_wr_regs(priv, 0x000d9, bw_params2[bw_i], 2); if (ret) goto error; @@ -135,8 +141,7 @@ error: return ret; } -int cxd2820r_get_frontend_t(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +int cxd2820r_get_frontend_t(struct dvb_frontend *fe) { struct cxd2820r_priv *priv = fe->demodulator_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache; diff --git a/drivers/media/dvb/frontends/cxd2820r_t2.c b/drivers/media/dvb/frontends/cxd2820r_t2.c index 6548588309f7..3a5759e0d235 100644 --- a/drivers/media/dvb/frontends/cxd2820r_t2.c +++ b/drivers/media/dvb/frontends/cxd2820r_t2.c @@ -21,13 +21,12 @@ #include "cxd2820r_priv.h" -int cxd2820r_set_frontend_t2(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) +int cxd2820r_set_frontend_t2(struct dvb_frontend *fe) { struct cxd2820r_priv *priv = fe->demodulator_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache; - int ret, i; - u32 if_khz, if_ctl; + int ret, i, bw_i; + u32 if_freq, if_ctl; u64 num; u8 buf[3], bw_param; u8 bw_params1[][5] = { @@ -71,6 +70,27 @@ int cxd2820r_set_frontend_t2(struct dvb_frontend *fe, dbg("%s: RF=%d BW=%d", __func__, c->frequency, c->bandwidth_hz); + switch (c->bandwidth_hz) { + case 5000000: + bw_i = 0; + bw_param = 3; + break; + case 6000000: + bw_i = 1; + bw_param = 2; + break; + case 7000000: + bw_i = 2; + bw_param = 1; + break; + case 8000000: + bw_i = 3; + bw_param = 0; + break; + default: + return -EINVAL; + } + /* update GPIOs */ ret = cxd2820r_gpio(fe); if (ret) @@ -78,7 +98,7 @@ int cxd2820r_set_frontend_t2(struct dvb_frontend *fe, /* program tuner */ if (fe->ops.tuner_ops.set_params) - fe->ops.tuner_ops.set_params(fe, params); + fe->ops.tuner_ops.set_params(fe); if (priv->delivery_system != SYS_DVBT2) { for (i = 0; i < ARRAY_SIZE(tab); i++) { @@ -91,32 +111,17 @@ int cxd2820r_set_frontend_t2(struct dvb_frontend *fe, priv->delivery_system = SYS_DVBT2; - switch (c->bandwidth_hz) { - case 5000000: - if_khz = priv->cfg.if_dvbt2_5; - i = 0; - bw_param = 3; - break; - case 6000000: - if_khz = priv->cfg.if_dvbt2_6; - i = 1; - bw_param = 2; - break; - case 7000000: - if_khz = priv->cfg.if_dvbt2_7; - i = 2; - bw_param = 1; - break; - case 8000000: - if_khz = priv->cfg.if_dvbt2_8; - i = 3; - bw_param = 0; - break; - default: - return -EINVAL; - } + /* program IF frequency */ + if (fe->ops.tuner_ops.get_if_frequency) { + ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_freq); + if (ret) + goto error; + } else + if_freq = 0; + + dbg("%s: if_freq=%d", __func__, if_freq); - num = if_khz; + num = if_freq / 1000; /* Hz => kHz */ num *= 0x1000000; if_ctl = cxd2820r_div_u64_round_closest(num, 41000); buf[0] = ((if_ctl >> 16) & 0xff); @@ -127,7 +132,7 @@ int cxd2820r_set_frontend_t2(struct dvb_frontend *fe, if (ret) goto error; - ret = cxd2820r_wr_regs(priv, 0x0209f, bw_params1[i], 5); + ret = cxd2820r_wr_regs(priv, 0x0209f, bw_params1[bw_i], 5); if (ret) goto error; @@ -150,8 +155,7 @@ error: } -int cxd2820r_get_frontend_t2(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +int cxd2820r_get_frontend_t2(struct dvb_frontend *fe) { struct cxd2820r_priv *priv = fe->demodulator_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache; diff --git a/drivers/media/dvb/frontends/dib0070.c b/drivers/media/dvb/frontends/dib0070.c index dc1cb17a6ea7..3b024bfe980a 100644 --- a/drivers/media/dvb/frontends/dib0070.c +++ b/drivers/media/dvb/frontends/dib0070.c @@ -150,7 +150,7 @@ static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val) } \ } while (0) -static int dib0070_set_bandwidth(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch) +static int dib0070_set_bandwidth(struct dvb_frontend *fe) { struct dib0070_state *state = fe->tuner_priv; u16 tmp = dib0070_read_reg(state, 0x02) & 0x3fff; @@ -335,7 +335,7 @@ static const struct dib0070_lna_match dib0070_lna[] = { }; #define LPF 100 -static int dib0070_tune_digital(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch) +static int dib0070_tune_digital(struct dvb_frontend *fe) { struct dib0070_state *state = fe->tuner_priv; @@ -507,7 +507,7 @@ static int dib0070_tune_digital(struct dvb_frontend *fe, struct dvb_frontend_par *tune_state = CT_TUNER_STEP_5; } else if (*tune_state == CT_TUNER_STEP_5) { - dib0070_set_bandwidth(fe, ch); + dib0070_set_bandwidth(fe); *tune_state = CT_TUNER_STOP; } else { ret = FE_CALLBACK_TIME_NEVER; /* tuner finished, time to call again infinite */ @@ -516,7 +516,7 @@ static int dib0070_tune_digital(struct dvb_frontend *fe, struct dvb_frontend_par } -static int dib0070_tune(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) +static int dib0070_tune(struct dvb_frontend *fe) { struct dib0070_state *state = fe->tuner_priv; uint32_t ret; @@ -524,7 +524,7 @@ static int dib0070_tune(struct dvb_frontend *fe, struct dvb_frontend_parameters state->tune_state = CT_TUNER_START; do { - ret = dib0070_tune_digital(fe, p); + ret = dib0070_tune_digital(fe); if (ret != FE_CALLBACK_TIME_NEVER) msleep(ret/10); else diff --git a/drivers/media/dvb/frontends/dib0090.c b/drivers/media/dvb/frontends/dib0090.c index b174d1c78583..224d81e85091 100644 --- a/drivers/media/dvb/frontends/dib0090.c +++ b/drivers/media/dvb/frontends/dib0090.c @@ -717,6 +717,34 @@ static const u16 rf_ramp_pwm_cband_7090[] = { (0 << 10) | 109, /* RF_RAMP4, LNA 4 */ }; +static const uint16_t rf_ramp_pwm_cband_7090e_sensitivity[] = { + 186, + 40, + 746, + (10 << 10) | 345, + (0 << 10) | 746, + (0 << 10) | 0, + (0 << 10) | 0, + (28 << 10) | 200, + (0 << 10) | 345, + (20 << 10) | 0, + (0 << 10) | 200, +}; + +static const uint16_t rf_ramp_pwm_cband_7090e_aci[] = { + 86, + 40, + 345, + (0 << 10) | 0, + (0 << 10) | 0, + (0 << 10) | 0, + (0 << 10) | 0, + (28 << 10) | 200, + (0 << 10) | 345, + (20 << 10) | 0, + (0 << 10) | 200, +}; + static const u16 rf_ramp_pwm_cband_8090[] = { 345, /* max RF gain in 10th of dB */ 29, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */ @@ -1076,8 +1104,16 @@ void dib0090_pwm_gain_reset(struct dvb_frontend *fe) dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal_socs); if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1) dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband_8090); - else if (state->identity.version == SOC_7090_P1G_11R1 || state->identity.version == SOC_7090_P1G_21R1) - dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband_7090); + else if (state->identity.version == SOC_7090_P1G_11R1 + || state->identity.version == SOC_7090_P1G_21R1) { + if (state->config->is_dib7090e) { + if (state->rf_ramp == NULL) + dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband_7090e_sensitivity); + else + dib0090_set_rframp_pwm(state, state->rf_ramp); + } else + dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband_7090); + } } else { dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband); dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal); @@ -1112,13 +1148,21 @@ void dib0090_pwm_gain_reset(struct dvb_frontend *fe) else dib0090_write_reg(state, 0x32, (0 << 11)); - dib0090_write_reg(state, 0x04, 0x01); + dib0090_write_reg(state, 0x04, 0x03); dib0090_write_reg(state, 0x39, (1 << 10)); } } EXPORT_SYMBOL(dib0090_pwm_gain_reset); +void dib0090_set_dc_servo(struct dvb_frontend *fe, u8 DC_servo_cutoff) +{ + struct dib0090_state *state = fe->tuner_priv; + if (DC_servo_cutoff < 4) + dib0090_write_reg(state, 0x04, DC_servo_cutoff); +} +EXPORT_SYMBOL(dib0090_set_dc_servo); + static u32 dib0090_get_slow_adc_val(struct dib0090_state *state) { u16 adc_val = dib0090_read_reg(state, 0x1d); @@ -1305,7 +1349,7 @@ void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * EXPORT_SYMBOL(dib0090_get_current_gain); -u16 dib0090_get_wbd_offset(struct dvb_frontend *fe) +u16 dib0090_get_wbd_target(struct dvb_frontend *fe) { struct dib0090_state *state = fe->tuner_priv; u32 f_MHz = state->fe->dtv_property_cache.frequency / 1000000; @@ -1342,9 +1386,57 @@ u16 dib0090_get_wbd_offset(struct dvb_frontend *fe) return state->wbd_offset + wbd_tcold; } +EXPORT_SYMBOL(dib0090_get_wbd_target); +u16 dib0090_get_wbd_offset(struct dvb_frontend *fe) +{ + struct dib0090_state *state = fe->tuner_priv; + return state->wbd_offset; +} EXPORT_SYMBOL(dib0090_get_wbd_offset); +int dib0090_set_switch(struct dvb_frontend *fe, u8 sw1, u8 sw2, u8 sw3) +{ + struct dib0090_state *state = fe->tuner_priv; + + dib0090_write_reg(state, 0x0b, (dib0090_read_reg(state, 0x0b) & 0xfff8) + | ((sw3 & 1) << 2) | ((sw2 & 1) << 1) | (sw1 & 1)); + + return 0; +} +EXPORT_SYMBOL(dib0090_set_switch); + +int dib0090_set_vga(struct dvb_frontend *fe, u8 onoff) +{ + struct dib0090_state *state = fe->tuner_priv; + + dib0090_write_reg(state, 0x09, (dib0090_read_reg(state, 0x09) & 0x7fff) + | ((onoff & 1) << 15)); + return 0; +} +EXPORT_SYMBOL(dib0090_set_vga); + +int dib0090_update_rframp_7090(struct dvb_frontend *fe, u8 cfg_sensitivity) +{ + struct dib0090_state *state = fe->tuner_priv; + + if ((!state->identity.p1g) || (!state->identity.in_soc) + || ((state->identity.version != SOC_7090_P1G_21R1) + && (state->identity.version != SOC_7090_P1G_11R1))) { + dprintk("%s() function can only be used for dib7090P", __func__); + return -ENODEV; + } + + if (cfg_sensitivity) + state->rf_ramp = (const u16 *)&rf_ramp_pwm_cband_7090e_sensitivity; + else + state->rf_ramp = (const u16 *)&rf_ramp_pwm_cband_7090e_aci; + dib0090_pwm_gain_reset(fe); + + return 0; +} +EXPORT_SYMBOL(dib0090_update_rframp_7090); + static const u16 dib0090_defaults[] = { 25, 0x01, @@ -1430,7 +1522,7 @@ static void dib0090_set_default_config(struct dib0090_state *state, const u16 * #define POLY_MIN (u8) 0 #define POLY_MAX (u8) 8 -void dib0090_set_EFUSE(struct dib0090_state *state) +static void dib0090_set_EFUSE(struct dib0090_state *state) { u8 c, h, n; u16 e2, e4; @@ -1505,7 +1597,10 @@ static int dib0090_reset(struct dvb_frontend *fe) dib0090_set_EFUSE(state); /* Congigure in function of the crystal */ - if (state->config->io.clock_khz >= 24000) + if (state->config->force_crystal_mode != 0) + dib0090_write_reg(state, 0x14, + state->config->force_crystal_mode & 3); + else if (state->config->io.clock_khz >= 24000) dib0090_write_reg(state, 0x14, 1); else dib0090_write_reg(state, 0x14, 2); @@ -1951,6 +2046,52 @@ static const struct dib0090_tuning dib0090_tuning_table_cband_7090[] = { #endif }; +static const struct dib0090_tuning dib0090_tuning_table_cband_7090e_sensitivity[] = { +#ifdef CONFIG_BAND_CBAND + { 300000, 0 , 3, 0x8105, 0x2c0, 0x2d12, 0xb84e, EN_CAB }, + { 380000, 0 , 10, 0x810F, 0x2c0, 0x2d12, 0xb84e, EN_CAB }, + { 600000, 0 , 10, 0x815E, 0x280, 0x2d12, 0xb84e, EN_CAB }, + { 660000, 0 , 5, 0x85E3, 0x280, 0x2d12, 0xb84e, EN_CAB }, + { 720000, 0 , 5, 0x852E, 0x280, 0x2d12, 0xb84e, EN_CAB }, + { 860000, 0 , 4, 0x85E5, 0x280, 0x2d12, 0xb84e, EN_CAB }, +#endif +}; + +int dib0090_update_tuning_table_7090(struct dvb_frontend *fe, + u8 cfg_sensitivity) +{ + struct dib0090_state *state = fe->tuner_priv; + const struct dib0090_tuning *tune = + dib0090_tuning_table_cband_7090e_sensitivity; + const struct dib0090_tuning dib0090_tuning_table_cband_7090e_aci[] = { + { 300000, 0 , 3, 0x8165, 0x2c0, 0x2d12, 0xb84e, EN_CAB }, + { 650000, 0 , 4, 0x815B, 0x280, 0x2d12, 0xb84e, EN_CAB }, + { 860000, 0 , 5, 0x84EF, 0x280, 0x2d12, 0xb84e, EN_CAB }, + }; + + if ((!state->identity.p1g) || (!state->identity.in_soc) + || ((state->identity.version != SOC_7090_P1G_21R1) + && (state->identity.version != SOC_7090_P1G_11R1))) { + dprintk("%s() function can only be used for dib7090", __func__); + return -ENODEV; + } + + if (cfg_sensitivity) + tune = dib0090_tuning_table_cband_7090e_sensitivity; + else + tune = dib0090_tuning_table_cband_7090e_aci; + + while (state->rf_request > tune->max_freq) + tune++; + + dib0090_write_reg(state, 0x09, (dib0090_read_reg(state, 0x09) & 0x8000) + | (tune->lna_bias & 0x7fff)); + dib0090_write_reg(state, 0x0b, (dib0090_read_reg(state, 0x0b) & 0xf83f) + | ((tune->lna_tune << 6) & 0x07c0)); + return 0; +} +EXPORT_SYMBOL(dib0090_update_tuning_table_7090); + static int dib0090_captrim_search(struct dib0090_state *state, enum frontend_tune_state *tune_state) { int ret = 0; @@ -2199,12 +2340,18 @@ static int dib0090_tune(struct dvb_frontend *fe) if (state->current_band & BAND_CBAND || state->current_band & BAND_FM || state->current_band & BAND_VHF || state->current_band & BAND_UHF) { state->current_band = BAND_CBAND; - tune = dib0090_tuning_table_cband_7090; + if (state->config->is_dib7090e) + tune = dib0090_tuning_table_cband_7090e_sensitivity; + else + tune = dib0090_tuning_table_cband_7090; } } else { /* Use the CBAND input for all band under UHF */ if (state->current_band & BAND_CBAND || state->current_band & BAND_FM || state->current_band & BAND_VHF) { state->current_band = BAND_CBAND; - tune = dib0090_tuning_table_cband_7090; + if (state->config->is_dib7090e) + tune = dib0090_tuning_table_cband_7090e_sensitivity; + else + tune = dib0090_tuning_table_cband_7090; } } } else @@ -2419,7 +2566,7 @@ static int dib0090_get_frequency(struct dvb_frontend *fe, u32 * frequency) return 0; } -static int dib0090_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) +static int dib0090_set_params(struct dvb_frontend *fe) { struct dib0090_state *state = fe->tuner_priv; u32 ret; diff --git a/drivers/media/dvb/frontends/dib0090.h b/drivers/media/dvb/frontends/dib0090.h index 13d85244ec16..781dc49de45b 100644 --- a/drivers/media/dvb/frontends/dib0090.h +++ b/drivers/media/dvb/frontends/dib0090.h @@ -71,6 +71,8 @@ struct dib0090_config { u8 fref_clock_ratio; u16 force_cband_input; struct dib0090_wbd_slope *wbd; + u8 is_dib7090e; + u8 force_crystal_mode; }; #if defined(CONFIG_DVB_TUNER_DIB0090) || (defined(CONFIG_DVB_TUNER_DIB0090_MODULE) && defined(MODULE)) @@ -78,13 +80,21 @@ extern struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c extern struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config); extern void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast); extern void dib0090_pwm_gain_reset(struct dvb_frontend *fe); -extern u16 dib0090_get_wbd_offset(struct dvb_frontend *tuner); +extern u16 dib0090_get_wbd_target(struct dvb_frontend *tuner); +extern u16 dib0090_get_wbd_offset(struct dvb_frontend *fe); extern int dib0090_gain_control(struct dvb_frontend *fe); extern enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe); extern int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state); extern void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * rf_gain_limit, u16 * rflt); +extern void dib0090_set_dc_servo(struct dvb_frontend *fe, u8 DC_servo_cutoff); +extern int dib0090_set_switch(struct dvb_frontend *fe, u8 sw1, u8 sw2, u8 sw3); +extern int dib0090_set_vga(struct dvb_frontend *fe, u8 onoff); +extern int dib0090_update_rframp_7090(struct dvb_frontend *fe, + u8 cfg_sensitivity); +extern int dib0090_update_tuning_table_7090(struct dvb_frontend *fe, + u8 cfg_sensitivity); #else -static inline struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0090_config *config) +static inline struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; @@ -106,7 +116,13 @@ static inline void dib0090_pwm_gain_reset(struct dvb_frontend *fe) printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); } -static inline u16 dib0090_get_wbd_offset(struct dvb_frontend *tuner) +static inline u16 dib0090_get_wbd_target(struct dvb_frontend *tuner) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return 0; +} + +static inline u16 dib0090_get_wbd_offset(struct dvb_frontend *fe) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return 0; @@ -134,6 +150,38 @@ static inline void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); } + +static inline void dib0090_set_dc_servo(struct dvb_frontend *fe, u8 DC_servo_cutoff) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); +} + +static inline int dib0090_set_switch(struct dvb_frontend *fe, + u8 sw1, u8 sw2, u8 sw3) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return -ENODEV; +} + +static inline int dib0090_set_vga(struct dvb_frontend *fe, u8 onoff) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return -ENODEV; +} + +static inline int dib0090_update_rframp_7090(struct dvb_frontend *fe, + u8 cfg_sensitivity) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return -ENODEV; +} + +static inline int dib0090_update_tuning_table_7090(struct dvb_frontend *fe, + u8 cfg_sensitivity) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return -ENODEV; +} #endif #endif diff --git a/drivers/media/dvb/frontends/dib3000mb.c b/drivers/media/dvb/frontends/dib3000mb.c index 437904cbf3e6..af91e0c92339 100644 --- a/drivers/media/dvb/frontends/dib3000mb.c +++ b/drivers/media/dvb/frontends/dib3000mb.c @@ -112,39 +112,37 @@ static u16 dib3000_seq[2][2][2] = /* fft,gua, inv */ } }; -static int dib3000mb_get_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep); +static int dib3000mb_get_frontend(struct dvb_frontend* fe); -static int dib3000mb_set_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep, int tuner) +static int dib3000mb_set_frontend(struct dvb_frontend *fe, int tuner) { struct dib3000_state* state = fe->demodulator_priv; - struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; fe_code_rate_t fe_cr = FEC_NONE; int search_state, seq; if (tuner && fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, fep); + fe->ops.tuner_ops.set_params(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); deb_setf("bandwidth: "); - switch (ofdm->bandwidth) { - case BANDWIDTH_8_MHZ: + switch (c->bandwidth_hz) { + case 8000000: deb_setf("8 MHz\n"); wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[2]); wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_8mhz); break; - case BANDWIDTH_7_MHZ: + case 7000000: deb_setf("7 MHz\n"); wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[1]); wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_7mhz); break; - case BANDWIDTH_6_MHZ: + case 6000000: deb_setf("6 MHz\n"); wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[0]); wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_6mhz); break; - case BANDWIDTH_AUTO: + case 0: return -EOPNOTSUPP; default: err("unknown bandwidth value."); @@ -154,7 +152,7 @@ static int dib3000mb_set_frontend(struct dvb_frontend* fe, wr(DIB3000MB_REG_LOCK1_MASK, DIB3000MB_LOCK1_SEARCH_4); deb_setf("transmission mode: "); - switch (ofdm->transmission_mode) { + switch (c->transmission_mode) { case TRANSMISSION_MODE_2K: deb_setf("2k\n"); wr(DIB3000MB_REG_FFT, DIB3000_TRANSMISSION_MODE_2K); @@ -171,7 +169,7 @@ static int dib3000mb_set_frontend(struct dvb_frontend* fe, } deb_setf("guard: "); - switch (ofdm->guard_interval) { + switch (c->guard_interval) { case GUARD_INTERVAL_1_32: deb_setf("1_32\n"); wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_32); @@ -196,7 +194,7 @@ static int dib3000mb_set_frontend(struct dvb_frontend* fe, } deb_setf("inversion: "); - switch (fep->inversion) { + switch (c->inversion) { case INVERSION_OFF: deb_setf("off\n"); wr(DIB3000MB_REG_DDS_INV, DIB3000_DDS_INVERSION_OFF); @@ -212,8 +210,8 @@ static int dib3000mb_set_frontend(struct dvb_frontend* fe, return -EINVAL; } - deb_setf("constellation: "); - switch (ofdm->constellation) { + deb_setf("modulation: "); + switch (c->modulation) { case QPSK: deb_setf("qpsk\n"); wr(DIB3000MB_REG_QAM, DIB3000_CONSTELLATION_QPSK); @@ -232,7 +230,7 @@ static int dib3000mb_set_frontend(struct dvb_frontend* fe, return -EINVAL; } deb_setf("hierarchy: "); - switch (ofdm->hierarchy_information) { + switch (c->hierarchy) { case HIERARCHY_NONE: deb_setf("none "); /* fall through */ @@ -256,16 +254,16 @@ static int dib3000mb_set_frontend(struct dvb_frontend* fe, } deb_setf("hierarchy: "); - if (ofdm->hierarchy_information == HIERARCHY_NONE) { + if (c->hierarchy == HIERARCHY_NONE) { deb_setf("none\n"); wr(DIB3000MB_REG_VIT_HRCH, DIB3000_HRCH_OFF); wr(DIB3000MB_REG_VIT_HP, DIB3000_SELECT_HP); - fe_cr = ofdm->code_rate_HP; - } else if (ofdm->hierarchy_information != HIERARCHY_AUTO) { + fe_cr = c->code_rate_HP; + } else if (c->hierarchy != HIERARCHY_AUTO) { deb_setf("on\n"); wr(DIB3000MB_REG_VIT_HRCH, DIB3000_HRCH_ON); wr(DIB3000MB_REG_VIT_HP, DIB3000_SELECT_LP); - fe_cr = ofdm->code_rate_LP; + fe_cr = c->code_rate_LP; } deb_setf("fec: "); switch (fe_cr) { @@ -300,9 +298,9 @@ static int dib3000mb_set_frontend(struct dvb_frontend* fe, } seq = dib3000_seq - [ofdm->transmission_mode == TRANSMISSION_MODE_AUTO] - [ofdm->guard_interval == GUARD_INTERVAL_AUTO] - [fep->inversion == INVERSION_AUTO]; + [c->transmission_mode == TRANSMISSION_MODE_AUTO] + [c->guard_interval == GUARD_INTERVAL_AUTO] + [c->inversion == INVERSION_AUTO]; deb_setf("seq? %d\n", seq); @@ -310,8 +308,8 @@ static int dib3000mb_set_frontend(struct dvb_frontend* fe, wr(DIB3000MB_REG_ISI, seq ? DIB3000MB_ISI_INHIBIT : DIB3000MB_ISI_ACTIVATE); - if (ofdm->transmission_mode == TRANSMISSION_MODE_2K) { - if (ofdm->guard_interval == GUARD_INTERVAL_1_8) { + if (c->transmission_mode == TRANSMISSION_MODE_2K) { + if (c->guard_interval == GUARD_INTERVAL_1_8) { wr(DIB3000MB_REG_SYNC_IMPROVEMENT, DIB3000MB_SYNC_IMPROVE_2K_1_8); } else { wr(DIB3000MB_REG_SYNC_IMPROVEMENT, DIB3000MB_SYNC_IMPROVE_DEFAULT); @@ -339,10 +337,10 @@ static int dib3000mb_set_frontend(struct dvb_frontend* fe, wr_foreach(dib3000mb_reg_agc_bandwidth, dib3000mb_agc_bandwidth_low); /* something has to be auto searched */ - if (ofdm->constellation == QAM_AUTO || - ofdm->hierarchy_information == HIERARCHY_AUTO || + if (c->modulation == QAM_AUTO || + c->hierarchy == HIERARCHY_AUTO || fe_cr == FEC_AUTO || - fep->inversion == INVERSION_AUTO) { + c->inversion == INVERSION_AUTO) { int as_count=0; deb_setf("autosearch enabled.\n"); @@ -361,10 +359,9 @@ static int dib3000mb_set_frontend(struct dvb_frontend* fe, deb_setf("search_state after autosearch %d after %d checks\n",search_state,as_count); if (search_state == 1) { - struct dvb_frontend_parameters feps; - if (dib3000mb_get_frontend(fe, &feps) == 0) { + if (dib3000mb_get_frontend(fe) == 0) { deb_setf("reading tuning data from frontend succeeded.\n"); - return dib3000mb_set_frontend(fe, &feps, 0); + return dib3000mb_set_frontend(fe, 0); } } @@ -453,11 +450,10 @@ static int dib3000mb_fe_init(struct dvb_frontend* fe, int mobile_mode) return 0; } -static int dib3000mb_get_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) +static int dib3000mb_get_frontend(struct dvb_frontend* fe) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct dib3000_state* state = fe->demodulator_priv; - struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm; fe_code_rate_t *cr; u16 tps_val; int inv_test1,inv_test2; @@ -484,25 +480,25 @@ static int dib3000mb_get_frontend(struct dvb_frontend* fe, else inv_test2 = 2; - fep->inversion = + c->inversion = ((inv_test2 == 2) && (inv_test1==1 || inv_test1==0)) || ((inv_test2 == 0) && (inv_test1==1 || inv_test1==2)) ? INVERSION_ON : INVERSION_OFF; - deb_getf("inversion %d %d, %d\n", inv_test2, inv_test1, fep->inversion); + deb_getf("inversion %d %d, %d\n", inv_test2, inv_test1, c->inversion); switch ((tps_val = rd(DIB3000MB_REG_TPS_QAM))) { case DIB3000_CONSTELLATION_QPSK: deb_getf("QPSK "); - ofdm->constellation = QPSK; + c->modulation = QPSK; break; case DIB3000_CONSTELLATION_16QAM: deb_getf("QAM16 "); - ofdm->constellation = QAM_16; + c->modulation = QAM_16; break; case DIB3000_CONSTELLATION_64QAM: deb_getf("QAM64 "); - ofdm->constellation = QAM_64; + c->modulation = QAM_64; break; default: err("Unexpected constellation returned by TPS (%d)", tps_val); @@ -512,24 +508,24 @@ static int dib3000mb_get_frontend(struct dvb_frontend* fe, if (rd(DIB3000MB_REG_TPS_HRCH)) { deb_getf("HRCH ON\n"); - cr = &ofdm->code_rate_LP; - ofdm->code_rate_HP = FEC_NONE; + cr = &c->code_rate_LP; + c->code_rate_HP = FEC_NONE; switch ((tps_val = rd(DIB3000MB_REG_TPS_VIT_ALPHA))) { case DIB3000_ALPHA_0: deb_getf("HIERARCHY_NONE "); - ofdm->hierarchy_information = HIERARCHY_NONE; + c->hierarchy = HIERARCHY_NONE; break; case DIB3000_ALPHA_1: deb_getf("HIERARCHY_1 "); - ofdm->hierarchy_information = HIERARCHY_1; + c->hierarchy = HIERARCHY_1; break; case DIB3000_ALPHA_2: deb_getf("HIERARCHY_2 "); - ofdm->hierarchy_information = HIERARCHY_2; + c->hierarchy = HIERARCHY_2; break; case DIB3000_ALPHA_4: deb_getf("HIERARCHY_4 "); - ofdm->hierarchy_information = HIERARCHY_4; + c->hierarchy = HIERARCHY_4; break; default: err("Unexpected ALPHA value returned by TPS (%d)", tps_val); @@ -540,9 +536,9 @@ static int dib3000mb_get_frontend(struct dvb_frontend* fe, tps_val = rd(DIB3000MB_REG_TPS_CODE_RATE_LP); } else { deb_getf("HRCH OFF\n"); - cr = &ofdm->code_rate_HP; - ofdm->code_rate_LP = FEC_NONE; - ofdm->hierarchy_information = HIERARCHY_NONE; + cr = &c->code_rate_HP; + c->code_rate_LP = FEC_NONE; + c->hierarchy = HIERARCHY_NONE; tps_val = rd(DIB3000MB_REG_TPS_CODE_RATE_HP); } @@ -577,19 +573,19 @@ static int dib3000mb_get_frontend(struct dvb_frontend* fe, switch ((tps_val = rd(DIB3000MB_REG_TPS_GUARD_TIME))) { case DIB3000_GUARD_TIME_1_32: deb_getf("GUARD_INTERVAL_1_32 "); - ofdm->guard_interval = GUARD_INTERVAL_1_32; + c->guard_interval = GUARD_INTERVAL_1_32; break; case DIB3000_GUARD_TIME_1_16: deb_getf("GUARD_INTERVAL_1_16 "); - ofdm->guard_interval = GUARD_INTERVAL_1_16; + c->guard_interval = GUARD_INTERVAL_1_16; break; case DIB3000_GUARD_TIME_1_8: deb_getf("GUARD_INTERVAL_1_8 "); - ofdm->guard_interval = GUARD_INTERVAL_1_8; + c->guard_interval = GUARD_INTERVAL_1_8; break; case DIB3000_GUARD_TIME_1_4: deb_getf("GUARD_INTERVAL_1_4 "); - ofdm->guard_interval = GUARD_INTERVAL_1_4; + c->guard_interval = GUARD_INTERVAL_1_4; break; default: err("Unexpected Guard Time returned by TPS (%d)", tps_val); @@ -600,11 +596,11 @@ static int dib3000mb_get_frontend(struct dvb_frontend* fe, switch ((tps_val = rd(DIB3000MB_REG_TPS_FFT))) { case DIB3000_TRANSMISSION_MODE_2K: deb_getf("TRANSMISSION_MODE_2K "); - ofdm->transmission_mode = TRANSMISSION_MODE_2K; + c->transmission_mode = TRANSMISSION_MODE_2K; break; case DIB3000_TRANSMISSION_MODE_8K: deb_getf("TRANSMISSION_MODE_8K "); - ofdm->transmission_mode = TRANSMISSION_MODE_8K; + c->transmission_mode = TRANSMISSION_MODE_8K; break; default: err("unexpected transmission mode return by TPS (%d)", tps_val); @@ -701,9 +697,9 @@ static int dib3000mb_fe_init_nonmobile(struct dvb_frontend* fe) return dib3000mb_fe_init(fe, 0); } -static int dib3000mb_set_frontend_and_tuner(struct dvb_frontend* fe, struct dvb_frontend_parameters *fep) +static int dib3000mb_set_frontend_and_tuner(struct dvb_frontend *fe) { - return dib3000mb_set_frontend(fe, fep, 1); + return dib3000mb_set_frontend(fe, 1); } static void dib3000mb_release(struct dvb_frontend* fe) @@ -794,10 +790,9 @@ error: } static struct dvb_frontend_ops dib3000mb_ops = { - + .delsys = { SYS_DVBT }, .info = { .name = "DiBcom 3000M-B DVB-T", - .type = FE_OFDM, .frequency_min = 44250000, .frequency_max = 867250000, .frequency_stepsize = 62500, diff --git a/drivers/media/dvb/frontends/dib3000mb_priv.h b/drivers/media/dvb/frontends/dib3000mb_priv.h index 16c526591f36..9dc235aa44b7 100644 --- a/drivers/media/dvb/frontends/dib3000mb_priv.h +++ b/drivers/media/dvb/frontends/dib3000mb_priv.h @@ -98,7 +98,7 @@ struct dib3000_state { int timing_offset; int timing_offset_comp_done; - fe_bandwidth_t last_tuned_bw; + u32 last_tuned_bw; u32 last_tuned_freq; }; diff --git a/drivers/media/dvb/frontends/dib3000mc.c b/drivers/media/dvb/frontends/dib3000mc.c index 088e7fadbe3d..ffad181a9692 100644 --- a/drivers/media/dvb/frontends/dib3000mc.c +++ b/drivers/media/dvb/frontends/dib3000mc.c @@ -40,7 +40,7 @@ struct dib3000mc_state { u32 timf; - fe_bandwidth_t current_bandwidth; + u32 current_bandwidth; u16 dev_id; @@ -438,11 +438,14 @@ static void dib3000mc_set_adp_cfg(struct dib3000mc_state *state, s16 qam) dib3000mc_write_word(state, reg, cfg[reg - 129]); } -static void dib3000mc_set_channel_cfg(struct dib3000mc_state *state, struct dvb_frontend_parameters *ch, u16 seq) +static void dib3000mc_set_channel_cfg(struct dib3000mc_state *state, + struct dtv_frontend_properties *ch, u16 seq) { u16 value; - dib3000mc_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth)); - dib3000mc_set_timing(state, ch->u.ofdm.transmission_mode, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth), 0); + u32 bw = BANDWIDTH_TO_KHZ(ch->bandwidth_hz); + + dib3000mc_set_bandwidth(state, bw); + dib3000mc_set_timing(state, ch->transmission_mode, bw, 0); // if (boost) // dib3000mc_write_word(state, 100, (11 << 6) + 6); @@ -471,22 +474,22 @@ static void dib3000mc_set_channel_cfg(struct dib3000mc_state *state, struct dvb_ dib3000mc_write_word(state, 97,0); dib3000mc_write_word(state, 98,0); - dib3000mc_set_impulse_noise(state, 0, ch->u.ofdm.transmission_mode); + dib3000mc_set_impulse_noise(state, 0, ch->transmission_mode); value = 0; - switch (ch->u.ofdm.transmission_mode) { + switch (ch->transmission_mode) { case TRANSMISSION_MODE_2K: value |= (0 << 7); break; default: case TRANSMISSION_MODE_8K: value |= (1 << 7); break; } - switch (ch->u.ofdm.guard_interval) { + switch (ch->guard_interval) { case GUARD_INTERVAL_1_32: value |= (0 << 5); break; case GUARD_INTERVAL_1_16: value |= (1 << 5); break; case GUARD_INTERVAL_1_4: value |= (3 << 5); break; default: case GUARD_INTERVAL_1_8: value |= (2 << 5); break; } - switch (ch->u.ofdm.constellation) { + switch (ch->modulation) { case QPSK: value |= (0 << 3); break; case QAM_16: value |= (1 << 3); break; default: @@ -502,11 +505,11 @@ static void dib3000mc_set_channel_cfg(struct dib3000mc_state *state, struct dvb_ dib3000mc_write_word(state, 5, (1 << 8) | ((seq & 0xf) << 4)); value = 0; - if (ch->u.ofdm.hierarchy_information == 1) + if (ch->hierarchy == 1) value |= (1 << 4); if (1 == 1) value |= 1; - switch ((ch->u.ofdm.hierarchy_information == 0 || 1 == 1) ? ch->u.ofdm.code_rate_HP : ch->u.ofdm.code_rate_LP) { + switch ((ch->hierarchy == 0 || 1 == 1) ? ch->code_rate_HP : ch->code_rate_LP) { case FEC_2_3: value |= (2 << 1); break; case FEC_3_4: value |= (3 << 1); break; case FEC_5_6: value |= (5 << 1); break; @@ -517,12 +520,12 @@ static void dib3000mc_set_channel_cfg(struct dib3000mc_state *state, struct dvb_ dib3000mc_write_word(state, 181, value); // diversity synchro delay add 50% SFN margin - switch (ch->u.ofdm.transmission_mode) { + switch (ch->transmission_mode) { case TRANSMISSION_MODE_8K: value = 256; break; case TRANSMISSION_MODE_2K: default: value = 64; break; } - switch (ch->u.ofdm.guard_interval) { + switch (ch->guard_interval) { case GUARD_INTERVAL_1_16: value *= 2; break; case GUARD_INTERVAL_1_8: value *= 4; break; case GUARD_INTERVAL_1_4: value *= 8; break; @@ -540,27 +543,28 @@ static void dib3000mc_set_channel_cfg(struct dib3000mc_state *state, struct dvb_ msleep(30); - dib3000mc_set_impulse_noise(state, state->cfg->impulse_noise_mode, ch->u.ofdm.transmission_mode); + dib3000mc_set_impulse_noise(state, state->cfg->impulse_noise_mode, ch->transmission_mode); } -static int dib3000mc_autosearch_start(struct dvb_frontend *demod, struct dvb_frontend_parameters *chan) +static int dib3000mc_autosearch_start(struct dvb_frontend *demod) { + struct dtv_frontend_properties *chan = &demod->dtv_property_cache; struct dib3000mc_state *state = demod->demodulator_priv; u16 reg; // u32 val; - struct dvb_frontend_parameters schan; + struct dtv_frontend_properties schan; schan = *chan; /* TODO what is that ? */ /* a channel for autosearch */ - schan.u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; - schan.u.ofdm.guard_interval = GUARD_INTERVAL_1_32; - schan.u.ofdm.constellation = QAM_64; - schan.u.ofdm.code_rate_HP = FEC_2_3; - schan.u.ofdm.code_rate_LP = FEC_2_3; - schan.u.ofdm.hierarchy_information = 0; + schan.transmission_mode = TRANSMISSION_MODE_8K; + schan.guard_interval = GUARD_INTERVAL_1_32; + schan.modulation = QAM_64; + schan.code_rate_HP = FEC_2_3; + schan.code_rate_LP = FEC_2_3; + schan.hierarchy = 0; dib3000mc_set_channel_cfg(state, &schan, 11); @@ -586,8 +590,9 @@ static int dib3000mc_autosearch_is_irq(struct dvb_frontend *demod) return 0; // still pending } -static int dib3000mc_tune(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch) +static int dib3000mc_tune(struct dvb_frontend *demod) { + struct dtv_frontend_properties *ch = &demod->dtv_property_cache; struct dib3000mc_state *state = demod->demodulator_priv; // ** configure demod ** @@ -603,8 +608,8 @@ static int dib3000mc_tune(struct dvb_frontend *demod, struct dvb_frontend_parame dib3000mc_write_word(state, 108, 0x0000); // P_pha3_force_pha_shift } - dib3000mc_set_adp_cfg(state, (u8)ch->u.ofdm.constellation); - if (ch->u.ofdm.transmission_mode == TRANSMISSION_MODE_8K) { + dib3000mc_set_adp_cfg(state, (u8)ch->modulation); + if (ch->transmission_mode == TRANSMISSION_MODE_8K) { dib3000mc_write_word(state, 26, 38528); dib3000mc_write_word(state, 33, 8); } else { @@ -613,7 +618,8 @@ static int dib3000mc_tune(struct dvb_frontend *demod, struct dvb_frontend_parame } if (dib3000mc_read_word(state, 509) & 0x80) - dib3000mc_set_timing(state, ch->u.ofdm.transmission_mode, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth), 1); + dib3000mc_set_timing(state, ch->transmission_mode, + BANDWIDTH_TO_KHZ(ch->bandwidth_hz), 1); return 0; } @@ -626,87 +632,87 @@ struct i2c_adapter * dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod, EXPORT_SYMBOL(dib3000mc_get_tuner_i2c_master); -static int dib3000mc_get_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) +static int dib3000mc_get_frontend(struct dvb_frontend* fe) { + struct dtv_frontend_properties *fep = &fe->dtv_property_cache; struct dib3000mc_state *state = fe->demodulator_priv; u16 tps = dib3000mc_read_word(state,458); fep->inversion = INVERSION_AUTO; - fep->u.ofdm.bandwidth = state->current_bandwidth; + fep->bandwidth_hz = state->current_bandwidth; switch ((tps >> 8) & 0x1) { - case 0: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; break; - case 1: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; break; + case 0: fep->transmission_mode = TRANSMISSION_MODE_2K; break; + case 1: fep->transmission_mode = TRANSMISSION_MODE_8K; break; } switch (tps & 0x3) { - case 0: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; break; - case 1: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; break; - case 2: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; break; - case 3: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; break; + case 0: fep->guard_interval = GUARD_INTERVAL_1_32; break; + case 1: fep->guard_interval = GUARD_INTERVAL_1_16; break; + case 2: fep->guard_interval = GUARD_INTERVAL_1_8; break; + case 3: fep->guard_interval = GUARD_INTERVAL_1_4; break; } switch ((tps >> 13) & 0x3) { - case 0: fep->u.ofdm.constellation = QPSK; break; - case 1: fep->u.ofdm.constellation = QAM_16; break; + case 0: fep->modulation = QPSK; break; + case 1: fep->modulation = QAM_16; break; case 2: - default: fep->u.ofdm.constellation = QAM_64; break; + default: fep->modulation = QAM_64; break; } /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */ /* (tps >> 12) & 0x1 == hrch is used, (tps >> 9) & 0x7 == alpha */ - fep->u.ofdm.hierarchy_information = HIERARCHY_NONE; + fep->hierarchy = HIERARCHY_NONE; switch ((tps >> 5) & 0x7) { - case 1: fep->u.ofdm.code_rate_HP = FEC_1_2; break; - case 2: fep->u.ofdm.code_rate_HP = FEC_2_3; break; - case 3: fep->u.ofdm.code_rate_HP = FEC_3_4; break; - case 5: fep->u.ofdm.code_rate_HP = FEC_5_6; break; + case 1: fep->code_rate_HP = FEC_1_2; break; + case 2: fep->code_rate_HP = FEC_2_3; break; + case 3: fep->code_rate_HP = FEC_3_4; break; + case 5: fep->code_rate_HP = FEC_5_6; break; case 7: - default: fep->u.ofdm.code_rate_HP = FEC_7_8; break; + default: fep->code_rate_HP = FEC_7_8; break; } switch ((tps >> 2) & 0x7) { - case 1: fep->u.ofdm.code_rate_LP = FEC_1_2; break; - case 2: fep->u.ofdm.code_rate_LP = FEC_2_3; break; - case 3: fep->u.ofdm.code_rate_LP = FEC_3_4; break; - case 5: fep->u.ofdm.code_rate_LP = FEC_5_6; break; + case 1: fep->code_rate_LP = FEC_1_2; break; + case 2: fep->code_rate_LP = FEC_2_3; break; + case 3: fep->code_rate_LP = FEC_3_4; break; + case 5: fep->code_rate_LP = FEC_5_6; break; case 7: - default: fep->u.ofdm.code_rate_LP = FEC_7_8; break; + default: fep->code_rate_LP = FEC_7_8; break; } return 0; } -static int dib3000mc_set_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) +static int dib3000mc_set_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *fep = &fe->dtv_property_cache; struct dib3000mc_state *state = fe->demodulator_priv; - int ret; + int ret; dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z); - state->current_bandwidth = fep->u.ofdm.bandwidth; - dib3000mc_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->u.ofdm.bandwidth)); + state->current_bandwidth = fep->bandwidth_hz; + dib3000mc_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->bandwidth_hz)); /* maybe the parameter has been changed */ state->sfn_workaround_active = buggy_sfn_workaround; if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, fep); + fe->ops.tuner_ops.set_params(fe); msleep(100); } - if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO || - fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO || - fep->u.ofdm.constellation == QAM_AUTO || - fep->u.ofdm.code_rate_HP == FEC_AUTO) { + if (fep->transmission_mode == TRANSMISSION_MODE_AUTO || + fep->guard_interval == GUARD_INTERVAL_AUTO || + fep->modulation == QAM_AUTO || + fep->code_rate_HP == FEC_AUTO) { int i = 1000, found; - dib3000mc_autosearch_start(fe, fep); + dib3000mc_autosearch_start(fe); do { msleep(1); found = dib3000mc_autosearch_is_irq(fe); @@ -716,14 +722,14 @@ static int dib3000mc_set_frontend(struct dvb_frontend* fe, if (found == 0 || found == 1) return 0; // no channel found - dib3000mc_get_frontend(fe, fep); + dib3000mc_get_frontend(fe); } - ret = dib3000mc_tune(fe, fep); + ret = dib3000mc_tune(fe); /* make this a config parameter */ dib3000mc_set_output_mode(state, OUTMODE_MPEG2_FIFO); - return ret; + return ret; } static int dib3000mc_read_status(struct dvb_frontend *fe, fe_status_t *stat) @@ -897,9 +903,9 @@ error: EXPORT_SYMBOL(dib3000mc_attach); static struct dvb_frontend_ops dib3000mc_ops = { + .delsys = { SYS_DVBT }, .info = { .name = "DiBcom 3000MC/P", - .type = FE_OFDM, .frequency_min = 44250000, .frequency_max = 867250000, .frequency_stepsize = 62500, diff --git a/drivers/media/dvb/frontends/dib7000m.c b/drivers/media/dvb/frontends/dib7000m.c index dbb76d75c932..148bf79236fb 100644 --- a/drivers/media/dvb/frontends/dib7000m.c +++ b/drivers/media/dvb/frontends/dib7000m.c @@ -38,7 +38,7 @@ struct dib7000m_state { u16 wbd_ref; u8 current_band; - fe_bandwidth_t current_bandwidth; + u32 current_bandwidth; struct dibx000_agc_config *current_agc; u32 timf; u32 timf_default; @@ -313,6 +313,9 @@ static int dib7000m_set_bandwidth(struct dib7000m_state *state, u32 bw) { u32 timf; + if (!bw) + bw = 8000; + // store the current bandwidth for later use state->current_bandwidth = bw; @@ -742,8 +745,9 @@ static void dib7000m_update_timf(struct dib7000m_state *state) dprintk( "updated timf_frequency: %d (default: %d)",state->timf, state->timf_default); } -static int dib7000m_agc_startup(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch) +static int dib7000m_agc_startup(struct dvb_frontend *demod) { + struct dtv_frontend_properties *ch = &demod->dtv_property_cache; struct dib7000m_state *state = demod->demodulator_priv; u16 cfg_72 = dib7000m_read_word(state, 72); int ret = -1; @@ -832,28 +836,29 @@ static int dib7000m_agc_startup(struct dvb_frontend *demod, struct dvb_frontend_ return ret; } -static void dib7000m_set_channel(struct dib7000m_state *state, struct dvb_frontend_parameters *ch, u8 seq) +static void dib7000m_set_channel(struct dib7000m_state *state, struct dtv_frontend_properties *ch, + u8 seq) { u16 value, est[4]; - dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth)); + dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->bandwidth_hz)); /* nfft, guard, qam, alpha */ value = 0; - switch (ch->u.ofdm.transmission_mode) { + switch (ch->transmission_mode) { case TRANSMISSION_MODE_2K: value |= (0 << 7); break; case TRANSMISSION_MODE_4K: value |= (2 << 7); break; default: case TRANSMISSION_MODE_8K: value |= (1 << 7); break; } - switch (ch->u.ofdm.guard_interval) { + switch (ch->guard_interval) { case GUARD_INTERVAL_1_32: value |= (0 << 5); break; case GUARD_INTERVAL_1_16: value |= (1 << 5); break; case GUARD_INTERVAL_1_4: value |= (3 << 5); break; default: case GUARD_INTERVAL_1_8: value |= (2 << 5); break; } - switch (ch->u.ofdm.constellation) { + switch (ch->modulation) { case QPSK: value |= (0 << 3); break; case QAM_16: value |= (1 << 3); break; default: @@ -872,11 +877,11 @@ static void dib7000m_set_channel(struct dib7000m_state *state, struct dvb_fronte value = 0; if (1 != 0) value |= (1 << 6); - if (ch->u.ofdm.hierarchy_information == 1) + if (ch->hierarchy == 1) value |= (1 << 4); if (1 == 1) value |= 1; - switch ((ch->u.ofdm.hierarchy_information == 0 || 1 == 1) ? ch->u.ofdm.code_rate_HP : ch->u.ofdm.code_rate_LP) { + switch ((ch->hierarchy == 0 || 1 == 1) ? ch->code_rate_HP : ch->code_rate_LP) { case FEC_2_3: value |= (2 << 1); break; case FEC_3_4: value |= (3 << 1); break; case FEC_5_6: value |= (5 << 1); break; @@ -901,13 +906,13 @@ static void dib7000m_set_channel(struct dib7000m_state *state, struct dvb_fronte dib7000m_write_word(state, 33, (0 << 4) | 0x5); /* P_dvsy_sync_wait */ - switch (ch->u.ofdm.transmission_mode) { + switch (ch->transmission_mode) { case TRANSMISSION_MODE_8K: value = 256; break; case TRANSMISSION_MODE_4K: value = 128; break; case TRANSMISSION_MODE_2K: default: value = 64; break; } - switch (ch->u.ofdm.guard_interval) { + switch (ch->guard_interval) { case GUARD_INTERVAL_1_16: value *= 2; break; case GUARD_INTERVAL_1_8: value *= 4; break; case GUARD_INTERVAL_1_4: value *= 8; break; @@ -925,7 +930,7 @@ static void dib7000m_set_channel(struct dib7000m_state *state, struct dvb_fronte dib7000m_set_diversity_in(&state->demod, state->div_state); /* channel estimation fine configuration */ - switch (ch->u.ofdm.constellation) { + switch (ch->modulation) { case QAM_64: est[0] = 0x0148; /* P_adp_regul_cnt 0.04 */ est[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */ @@ -952,25 +957,26 @@ static void dib7000m_set_channel(struct dib7000m_state *state, struct dvb_fronte dib7000m_set_power_mode(state, DIB7000M_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD); } -static int dib7000m_autosearch_start(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch) +static int dib7000m_autosearch_start(struct dvb_frontend *demod) { + struct dtv_frontend_properties *ch = &demod->dtv_property_cache; struct dib7000m_state *state = demod->demodulator_priv; - struct dvb_frontend_parameters schan; + struct dtv_frontend_properties schan; int ret = 0; u32 value, factor; schan = *ch; - schan.u.ofdm.constellation = QAM_64; - schan.u.ofdm.guard_interval = GUARD_INTERVAL_1_32; - schan.u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; - schan.u.ofdm.code_rate_HP = FEC_2_3; - schan.u.ofdm.code_rate_LP = FEC_3_4; - schan.u.ofdm.hierarchy_information = 0; + schan.modulation = QAM_64; + schan.guard_interval = GUARD_INTERVAL_1_32; + schan.transmission_mode = TRANSMISSION_MODE_8K; + schan.code_rate_HP = FEC_2_3; + schan.code_rate_LP = FEC_3_4; + schan.hierarchy = 0; dib7000m_set_channel(state, &schan, 7); - factor = BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth); + factor = BANDWIDTH_TO_KHZ(schan.bandwidth_hz); if (factor >= 5000) factor = 1; else @@ -1027,8 +1033,9 @@ static int dib7000m_autosearch_is_irq(struct dvb_frontend *demod) return dib7000m_autosearch_irq(state, 537); } -static int dib7000m_tune(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch) +static int dib7000m_tune(struct dvb_frontend *demod) { + struct dtv_frontend_properties *ch = &demod->dtv_property_cache; struct dib7000m_state *state = demod->demodulator_priv; int ret = 0; u16 value; @@ -1055,7 +1062,7 @@ static int dib7000m_tune(struct dvb_frontend *demod, struct dvb_frontend_paramet //dump_reg(state); /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */ value = (6 << 8) | 0x80; - switch (ch->u.ofdm.transmission_mode) { + switch (ch->transmission_mode) { case TRANSMISSION_MODE_2K: value |= (7 << 12); break; case TRANSMISSION_MODE_4K: value |= (8 << 12); break; default: @@ -1065,7 +1072,7 @@ static int dib7000m_tune(struct dvb_frontend *demod, struct dvb_frontend_paramet /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */ value = (0 << 4); - switch (ch->u.ofdm.transmission_mode) { + switch (ch->transmission_mode) { case TRANSMISSION_MODE_2K: value |= 0x6; break; case TRANSMISSION_MODE_4K: value |= 0x7; break; default: @@ -1075,7 +1082,7 @@ static int dib7000m_tune(struct dvb_frontend *demod, struct dvb_frontend_paramet /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */ value = (0 << 4); - switch (ch->u.ofdm.transmission_mode) { + switch (ch->transmission_mode) { case TRANSMISSION_MODE_2K: value |= 0x6; break; case TRANSMISSION_MODE_4K: value |= 0x7; break; default: @@ -1087,7 +1094,7 @@ static int dib7000m_tune(struct dvb_frontend *demod, struct dvb_frontend_paramet if ((dib7000m_read_word(state, 535) >> 6) & 0x1) dib7000m_update_timf(state); - dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth)); + dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->bandwidth_hz)); return ret; } @@ -1147,57 +1154,57 @@ static int dib7000m_identify(struct dib7000m_state *state) } -static int dib7000m_get_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) +static int dib7000m_get_frontend(struct dvb_frontend* fe) { + struct dtv_frontend_properties *fep = &fe->dtv_property_cache; struct dib7000m_state *state = fe->demodulator_priv; u16 tps = dib7000m_read_word(state,480); fep->inversion = INVERSION_AUTO; - fep->u.ofdm.bandwidth = state->current_bandwidth; + fep->bandwidth_hz = BANDWIDTH_TO_HZ(state->current_bandwidth); switch ((tps >> 8) & 0x3) { - case 0: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; break; - case 1: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; break; - /* case 2: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_4K; break; */ + case 0: fep->transmission_mode = TRANSMISSION_MODE_2K; break; + case 1: fep->transmission_mode = TRANSMISSION_MODE_8K; break; + /* case 2: fep->transmission_mode = TRANSMISSION_MODE_4K; break; */ } switch (tps & 0x3) { - case 0: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; break; - case 1: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; break; - case 2: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; break; - case 3: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; break; + case 0: fep->guard_interval = GUARD_INTERVAL_1_32; break; + case 1: fep->guard_interval = GUARD_INTERVAL_1_16; break; + case 2: fep->guard_interval = GUARD_INTERVAL_1_8; break; + case 3: fep->guard_interval = GUARD_INTERVAL_1_4; break; } switch ((tps >> 14) & 0x3) { - case 0: fep->u.ofdm.constellation = QPSK; break; - case 1: fep->u.ofdm.constellation = QAM_16; break; + case 0: fep->modulation = QPSK; break; + case 1: fep->modulation = QAM_16; break; case 2: - default: fep->u.ofdm.constellation = QAM_64; break; + default: fep->modulation = QAM_64; break; } /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */ /* (tps >> 13) & 0x1 == hrch is used, (tps >> 10) & 0x7 == alpha */ - fep->u.ofdm.hierarchy_information = HIERARCHY_NONE; + fep->hierarchy = HIERARCHY_NONE; switch ((tps >> 5) & 0x7) { - case 1: fep->u.ofdm.code_rate_HP = FEC_1_2; break; - case 2: fep->u.ofdm.code_rate_HP = FEC_2_3; break; - case 3: fep->u.ofdm.code_rate_HP = FEC_3_4; break; - case 5: fep->u.ofdm.code_rate_HP = FEC_5_6; break; + case 1: fep->code_rate_HP = FEC_1_2; break; + case 2: fep->code_rate_HP = FEC_2_3; break; + case 3: fep->code_rate_HP = FEC_3_4; break; + case 5: fep->code_rate_HP = FEC_5_6; break; case 7: - default: fep->u.ofdm.code_rate_HP = FEC_7_8; break; + default: fep->code_rate_HP = FEC_7_8; break; } switch ((tps >> 2) & 0x7) { - case 1: fep->u.ofdm.code_rate_LP = FEC_1_2; break; - case 2: fep->u.ofdm.code_rate_LP = FEC_2_3; break; - case 3: fep->u.ofdm.code_rate_LP = FEC_3_4; break; - case 5: fep->u.ofdm.code_rate_LP = FEC_5_6; break; + case 1: fep->code_rate_LP = FEC_1_2; break; + case 2: fep->code_rate_LP = FEC_2_3; break; + case 3: fep->code_rate_LP = FEC_3_4; break; + case 5: fep->code_rate_LP = FEC_5_6; break; case 7: - default: fep->u.ofdm.code_rate_LP = FEC_7_8; break; + default: fep->code_rate_LP = FEC_7_8; break; } /* native interleaver: (dib7000m_read_word(state, 481) >> 5) & 0x1 */ @@ -1205,35 +1212,34 @@ static int dib7000m_get_frontend(struct dvb_frontend* fe, return 0; } -static int dib7000m_set_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) +static int dib7000m_set_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *fep = &fe->dtv_property_cache; struct dib7000m_state *state = fe->demodulator_priv; int time, ret; - dib7000m_set_output_mode(state, OUTMODE_HIGH_Z); + dib7000m_set_output_mode(state, OUTMODE_HIGH_Z); - state->current_bandwidth = fep->u.ofdm.bandwidth; - dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->u.ofdm.bandwidth)); + dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->bandwidth_hz)); if (fe->ops.tuner_ops.set_params) - fe->ops.tuner_ops.set_params(fe, fep); + fe->ops.tuner_ops.set_params(fe); /* start up the AGC */ state->agc_state = 0; do { - time = dib7000m_agc_startup(fe, fep); + time = dib7000m_agc_startup(fe); if (time != -1) msleep(time); } while (time != -1); - if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO || - fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO || - fep->u.ofdm.constellation == QAM_AUTO || - fep->u.ofdm.code_rate_HP == FEC_AUTO) { + if (fep->transmission_mode == TRANSMISSION_MODE_AUTO || + fep->guard_interval == GUARD_INTERVAL_AUTO || + fep->modulation == QAM_AUTO || + fep->code_rate_HP == FEC_AUTO) { int i = 800, found; - dib7000m_autosearch_start(fe, fep); + dib7000m_autosearch_start(fe); do { msleep(1); found = dib7000m_autosearch_is_irq(fe); @@ -1243,10 +1249,10 @@ static int dib7000m_set_frontend(struct dvb_frontend* fe, if (found == 0 || found == 1) return 0; // no channel found - dib7000m_get_frontend(fe, fep); + dib7000m_get_frontend(fe); } - ret = dib7000m_tune(fe, fep); + ret = dib7000m_tune(fe); /* make this a config parameter */ dib7000m_set_output_mode(state, OUTMODE_MPEG2_FIFO); @@ -1430,9 +1436,9 @@ error: EXPORT_SYMBOL(dib7000m_attach); static struct dvb_frontend_ops dib7000m_ops = { + .delsys = { SYS_DVBT }, .info = { .name = "DiBcom 7000MA/MB/PA/PB/MC", - .type = FE_OFDM, .frequency_min = 44250000, .frequency_max = 867250000, .frequency_stepsize = 62500, diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c index ce8534ff142e..5ceadc285b3a 100644 --- a/drivers/media/dvb/frontends/dib7000p.c +++ b/drivers/media/dvb/frontends/dib7000p.c @@ -70,6 +70,8 @@ struct dib7000p_state { u8 i2c_write_buffer[4]; u8 i2c_read_buffer[2]; struct mutex i2c_buffer_lock; + + u8 input_mode_mpeg; }; enum dib7000p_power_mode { @@ -78,8 +80,11 @@ enum dib7000p_power_mode { DIB7000P_POWER_INTERFACE_ONLY, }; +/* dib7090 specific fonctions */ static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode); static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff); +static void dib7090_setDibTxMux(struct dib7000p_state *state, int mode); +static void dib7090_setHostBusMux(struct dib7000p_state *state, int mode); static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg) { @@ -276,17 +281,23 @@ static int dib7000p_set_power_mode(struct dib7000p_state *state, enum dib7000p_p dib7000p_write_word(state, 774, reg_774); dib7000p_write_word(state, 775, reg_775); dib7000p_write_word(state, 776, reg_776); - dib7000p_write_word(state, 899, reg_899); dib7000p_write_word(state, 1280, reg_1280); + if (state->version != SOC7090) + dib7000p_write_word(state, 899, reg_899); return 0; } static void dib7000p_set_adc_state(struct dib7000p_state *state, enum dibx000_adc_states no) { - u16 reg_908 = dib7000p_read_word(state, 908), reg_909 = dib7000p_read_word(state, 909); + u16 reg_908 = 0, reg_909 = 0; u16 reg; + if (state->version != SOC7090) { + reg_908 = dib7000p_read_word(state, 908); + reg_909 = dib7000p_read_word(state, 909); + } + switch (no) { case DIBX000_SLOW_ADC_ON: if (state->version == SOC7090) { @@ -342,8 +353,10 @@ static void dib7000p_set_adc_state(struct dib7000p_state *state, enum dibx000_ad reg_909 |= (state->cfg.disable_sample_and_hold & 1) << 4; reg_908 |= (state->cfg.enable_current_mirror & 1) << 7; - dib7000p_write_word(state, 908, reg_908); - dib7000p_write_word(state, 909, reg_909); + if (state->version != SOC7090) { + dib7000p_write_word(state, 908, reg_908); + dib7000p_write_word(state, 909, reg_909); + } } static int dib7000p_set_bandwidth(struct dib7000p_state *state, u32 bw) @@ -398,6 +411,24 @@ int dib7000p_set_wbd_ref(struct dvb_frontend *demod, u16 value) } EXPORT_SYMBOL(dib7000p_set_wbd_ref); +int dib7000p_get_agc_values(struct dvb_frontend *fe, + u16 *agc_global, u16 *agc1, u16 *agc2, u16 *wbd) +{ + struct dib7000p_state *state = fe->demodulator_priv; + + if (agc_global != NULL) + *agc_global = dib7000p_read_word(state, 394); + if (agc1 != NULL) + *agc1 = dib7000p_read_word(state, 392); + if (agc2 != NULL) + *agc2 = dib7000p_read_word(state, 393); + if (wbd != NULL) + *wbd = dib7000p_read_word(state, 397); + + return 0; +} +EXPORT_SYMBOL(dib7000p_get_agc_values); + static void dib7000p_reset_pll(struct dib7000p_state *state) { struct dibx000_bandwidth_config *bw = &state->cfg.bw[0]; @@ -519,7 +550,7 @@ static u16 dib7000p_defaults[] = { // auto search configuration 3, 2, 0x0004, - 0x1000, + (1<<3)|(1<<11)|(1<<12)|(1<<13), 0x0814, /* Equal Lock */ 12, 6, @@ -595,13 +626,6 @@ static u16 dib7000p_defaults[] = { 1, 235, 0x0062, - 2, 901, - 0x0006, - (3 << 10) | (1 << 6), - - 1, 905, - 0x2c8e, - 0, }; @@ -618,15 +642,18 @@ static int dib7000p_demod_reset(struct dib7000p_state *state) dib7000p_write_word(state, 770, 0xffff); dib7000p_write_word(state, 771, 0xffff); dib7000p_write_word(state, 772, 0x001f); - dib7000p_write_word(state, 898, 0x0003); dib7000p_write_word(state, 1280, 0x001f - ((1 << 4) | (1 << 3))); dib7000p_write_word(state, 770, 0); dib7000p_write_word(state, 771, 0); dib7000p_write_word(state, 772, 0); - dib7000p_write_word(state, 898, 0); dib7000p_write_word(state, 1280, 0); + if (state->version != SOC7090) { + dib7000p_write_word(state, 898, 0x0003); + dib7000p_write_word(state, 898, 0); + } + /* default */ dib7000p_reset_pll(state); @@ -640,7 +667,7 @@ static int dib7000p_demod_reset(struct dib7000p_state *state) dib7000p_write_word(state, 42, (1<<5) | 3); /* P_iqc_thsat_ipc = 1 ; P_iqc_win2 = 3 */ dib7000p_write_word(state, 43, 0x2d4); /*-300 fag P_iqc_dect_min = -280 */ dib7000p_write_word(state, 44, 300); /* 300 fag P_iqc_dect_min = +280 */ - dib7000p_write_word(state, 273, (1<<6) | 30); + dib7000p_write_word(state, 273, (0<<6) | 30); } if (dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) != 0) dprintk("OUTPUT_MODE could not be reset."); @@ -655,7 +682,7 @@ static int dib7000p_demod_reset(struct dib7000p_state *state) dib7000p_set_bandwidth(state, 8000); if (state->version == SOC7090) { - dib7000p_write_word(state, 36, 0x5755);/* P_iqc_impnc_on =1 & P_iqc_corr_inh = 1 for impulsive noise */ + dib7000p_write_word(state, 36, 0x0755);/* P_iqc_impnc_on =1 & P_iqc_corr_inh = 1 for impulsive noise */ } else { if (state->cfg.tuner_is_baseband) dib7000p_write_word(state, 36, 0x0755); @@ -664,6 +691,11 @@ static int dib7000p_demod_reset(struct dib7000p_state *state) } dib7000p_write_tab(state, dib7000p_defaults); + if (state->version != SOC7090) { + dib7000p_write_word(state, 901, 0x0006); + dib7000p_write_word(state, 902, (3 << 10) | (1 << 6)); + dib7000p_write_word(state, 905, 0x2c8e); + } dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY); @@ -780,8 +812,9 @@ static void dib7000p_set_dds(struct dib7000p_state *state, s32 offset_khz) } } -static int dib7000p_agc_startup(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch) +static int dib7000p_agc_startup(struct dvb_frontend *demod) { + struct dtv_frontend_properties *ch = &demod->dtv_property_cache; struct dib7000p_state *state = demod->demodulator_priv; int ret = -1; u8 *agc_state = &state->agc_state; @@ -904,15 +937,16 @@ u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf) } EXPORT_SYMBOL(dib7000p_ctrl_timf); -static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_frontend_parameters *ch, u8 seq) +static void dib7000p_set_channel(struct dib7000p_state *state, + struct dtv_frontend_properties *ch, u8 seq) { u16 value, est[4]; - dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth)); + dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->bandwidth_hz)); /* nfft, guard, qam, alpha */ value = 0; - switch (ch->u.ofdm.transmission_mode) { + switch (ch->transmission_mode) { case TRANSMISSION_MODE_2K: value |= (0 << 7); break; @@ -924,7 +958,7 @@ static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_fronte value |= (1 << 7); break; } - switch (ch->u.ofdm.guard_interval) { + switch (ch->guard_interval) { case GUARD_INTERVAL_1_32: value |= (0 << 5); break; @@ -939,7 +973,7 @@ static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_fronte value |= (2 << 5); break; } - switch (ch->u.ofdm.constellation) { + switch (ch->modulation) { case QPSK: value |= (0 << 3); break; @@ -970,11 +1004,11 @@ static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_fronte value = 0; if (1 != 0) value |= (1 << 6); - if (ch->u.ofdm.hierarchy_information == 1) + if (ch->hierarchy == 1) value |= (1 << 4); if (1 == 1) value |= 1; - switch ((ch->u.ofdm.hierarchy_information == 0 || 1 == 1) ? ch->u.ofdm.code_rate_HP : ch->u.ofdm.code_rate_LP) { + switch ((ch->hierarchy == 0 || 1 == 1) ? ch->code_rate_HP : ch->code_rate_LP) { case FEC_2_3: value |= (2 << 1); break; @@ -1001,7 +1035,7 @@ static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_fronte dib7000p_write_word(state, 33, 0x0005); /* P_dvsy_sync_wait */ - switch (ch->u.ofdm.transmission_mode) { + switch (ch->transmission_mode) { case TRANSMISSION_MODE_8K: value = 256; break; @@ -1013,7 +1047,7 @@ static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_fronte value = 64; break; } - switch (ch->u.ofdm.guard_interval) { + switch (ch->guard_interval) { case GUARD_INTERVAL_1_16: value *= 2; break; @@ -1034,11 +1068,11 @@ static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_fronte state->div_sync_wait = (value * 3) / 2 + state->cfg.diversity_delay; /* deactive the possibility of diversity reception if extended interleaver */ - state->div_force_off = !1 && ch->u.ofdm.transmission_mode != TRANSMISSION_MODE_8K; + state->div_force_off = !1 && ch->transmission_mode != TRANSMISSION_MODE_8K; dib7000p_set_diversity_in(&state->demod, state->div_state); /* channel estimation fine configuration */ - switch (ch->u.ofdm.constellation) { + switch (ch->modulation) { case QAM_64: est[0] = 0x0148; /* P_adp_regul_cnt 0.04 */ est[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */ @@ -1062,27 +1096,31 @@ static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_fronte dib7000p_write_word(state, 187 + value, est[value]); } -static int dib7000p_autosearch_start(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch) +static int dib7000p_autosearch_start(struct dvb_frontend *demod) { + struct dtv_frontend_properties *ch = &demod->dtv_property_cache; struct dib7000p_state *state = demod->demodulator_priv; - struct dvb_frontend_parameters schan; + struct dtv_frontend_properties schan; u32 value, factor; u32 internal = dib7000p_get_internal_freq(state); schan = *ch; - schan.u.ofdm.constellation = QAM_64; - schan.u.ofdm.guard_interval = GUARD_INTERVAL_1_32; - schan.u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; - schan.u.ofdm.code_rate_HP = FEC_2_3; - schan.u.ofdm.code_rate_LP = FEC_3_4; - schan.u.ofdm.hierarchy_information = 0; + schan.modulation = QAM_64; + schan.guard_interval = GUARD_INTERVAL_1_32; + schan.transmission_mode = TRANSMISSION_MODE_8K; + schan.code_rate_HP = FEC_2_3; + schan.code_rate_LP = FEC_3_4; + schan.hierarchy = 0; dib7000p_set_channel(state, &schan, 7); - factor = BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth); - if (factor >= 5000) - factor = 1; - else + factor = BANDWIDTH_TO_KHZ(ch->bandwidth_hz); + if (factor >= 5000) { + if (state->version == SOC7090) + factor = 2; + else + factor = 1; + } else factor = 6; value = 30 * internal * factor; @@ -1205,8 +1243,9 @@ static void dib7000p_spur_protect(struct dib7000p_state *state, u32 rf_khz, u32 dib7000p_write_word(state, 143, 0); } -static int dib7000p_tune(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch) +static int dib7000p_tune(struct dvb_frontend *demod) { + struct dtv_frontend_properties *ch = &demod->dtv_property_cache; struct dib7000p_state *state = demod->demodulator_priv; u16 tmp = 0; @@ -1239,7 +1278,7 @@ static int dib7000p_tune(struct dvb_frontend *demod, struct dvb_frontend_paramet /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */ tmp = (6 << 8) | 0x80; - switch (ch->u.ofdm.transmission_mode) { + switch (ch->transmission_mode) { case TRANSMISSION_MODE_2K: tmp |= (2 << 12); break; @@ -1255,7 +1294,7 @@ static int dib7000p_tune(struct dvb_frontend *demod, struct dvb_frontend_paramet /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */ tmp = (0 << 4); - switch (ch->u.ofdm.transmission_mode) { + switch (ch->transmission_mode) { case TRANSMISSION_MODE_2K: tmp |= 0x6; break; @@ -1271,7 +1310,7 @@ static int dib7000p_tune(struct dvb_frontend *demod, struct dvb_frontend_paramet /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */ tmp = (0 << 4); - switch (ch->u.ofdm.transmission_mode) { + switch (ch->transmission_mode) { case TRANSMISSION_MODE_2K: tmp |= 0x6; break; @@ -1303,9 +1342,9 @@ static int dib7000p_tune(struct dvb_frontend *demod, struct dvb_frontend_paramet } if (state->cfg.spur_protect) - dib7000p_spur_protect(state, ch->frequency / 1000, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth)); + dib7000p_spur_protect(state, ch->frequency / 1000, BANDWIDTH_TO_KHZ(ch->bandwidth_hz)); - dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth)); + dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->bandwidth_hz)); return 0; } @@ -1323,7 +1362,7 @@ static int dib7000p_sleep(struct dvb_frontend *demod) { struct dib7000p_state *state = demod->demodulator_priv; if (state->version == SOC7090) - return dib7090_set_output_mode(demod, OUTMODE_HIGH_Z) | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY); + return dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY); return dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY); } @@ -1345,93 +1384,94 @@ static int dib7000p_identify(struct dib7000p_state *st) return 0; } -static int dib7000p_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) +static int dib7000p_get_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *fep = &fe->dtv_property_cache; struct dib7000p_state *state = fe->demodulator_priv; u16 tps = dib7000p_read_word(state, 463); fep->inversion = INVERSION_AUTO; - fep->u.ofdm.bandwidth = BANDWIDTH_TO_INDEX(state->current_bandwidth); + fep->bandwidth_hz = BANDWIDTH_TO_HZ(state->current_bandwidth); switch ((tps >> 8) & 0x3) { case 0: - fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; + fep->transmission_mode = TRANSMISSION_MODE_2K; break; case 1: - fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; + fep->transmission_mode = TRANSMISSION_MODE_8K; break; - /* case 2: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_4K; break; */ + /* case 2: fep->transmission_mode = TRANSMISSION_MODE_4K; break; */ } switch (tps & 0x3) { case 0: - fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; + fep->guard_interval = GUARD_INTERVAL_1_32; break; case 1: - fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; + fep->guard_interval = GUARD_INTERVAL_1_16; break; case 2: - fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; + fep->guard_interval = GUARD_INTERVAL_1_8; break; case 3: - fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; + fep->guard_interval = GUARD_INTERVAL_1_4; break; } switch ((tps >> 14) & 0x3) { case 0: - fep->u.ofdm.constellation = QPSK; + fep->modulation = QPSK; break; case 1: - fep->u.ofdm.constellation = QAM_16; + fep->modulation = QAM_16; break; case 2: default: - fep->u.ofdm.constellation = QAM_64; + fep->modulation = QAM_64; break; } /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */ /* (tps >> 13) & 0x1 == hrch is used, (tps >> 10) & 0x7 == alpha */ - fep->u.ofdm.hierarchy_information = HIERARCHY_NONE; + fep->hierarchy = HIERARCHY_NONE; switch ((tps >> 5) & 0x7) { case 1: - fep->u.ofdm.code_rate_HP = FEC_1_2; + fep->code_rate_HP = FEC_1_2; break; case 2: - fep->u.ofdm.code_rate_HP = FEC_2_3; + fep->code_rate_HP = FEC_2_3; break; case 3: - fep->u.ofdm.code_rate_HP = FEC_3_4; + fep->code_rate_HP = FEC_3_4; break; case 5: - fep->u.ofdm.code_rate_HP = FEC_5_6; + fep->code_rate_HP = FEC_5_6; break; case 7: default: - fep->u.ofdm.code_rate_HP = FEC_7_8; + fep->code_rate_HP = FEC_7_8; break; } switch ((tps >> 2) & 0x7) { case 1: - fep->u.ofdm.code_rate_LP = FEC_1_2; + fep->code_rate_LP = FEC_1_2; break; case 2: - fep->u.ofdm.code_rate_LP = FEC_2_3; + fep->code_rate_LP = FEC_2_3; break; case 3: - fep->u.ofdm.code_rate_LP = FEC_3_4; + fep->code_rate_LP = FEC_3_4; break; case 5: - fep->u.ofdm.code_rate_LP = FEC_5_6; + fep->code_rate_LP = FEC_5_6; break; case 7: default: - fep->u.ofdm.code_rate_LP = FEC_7_8; + fep->code_rate_LP = FEC_7_8; break; } @@ -1440,36 +1480,36 @@ static int dib7000p_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_pa return 0; } -static int dib7000p_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) +static int dib7000p_set_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *fep = &fe->dtv_property_cache; struct dib7000p_state *state = fe->demodulator_priv; int time, ret; - if (state->version == SOC7090) { + if (state->version == SOC7090) dib7090_set_diversity_in(fe, 0); - dib7090_set_output_mode(fe, OUTMODE_HIGH_Z); - } else + else dib7000p_set_output_mode(state, OUTMODE_HIGH_Z); /* maybe the parameter has been changed */ state->sfn_workaround_active = buggy_sfn_workaround; if (fe->ops.tuner_ops.set_params) - fe->ops.tuner_ops.set_params(fe, fep); + fe->ops.tuner_ops.set_params(fe); /* start up the AGC */ state->agc_state = 0; do { - time = dib7000p_agc_startup(fe, fep); + time = dib7000p_agc_startup(fe); if (time != -1) msleep(time); } while (time != -1); - if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO || - fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO || fep->u.ofdm.constellation == QAM_AUTO || fep->u.ofdm.code_rate_HP == FEC_AUTO) { + if (fep->transmission_mode == TRANSMISSION_MODE_AUTO || + fep->guard_interval == GUARD_INTERVAL_AUTO || fep->modulation == QAM_AUTO || fep->code_rate_HP == FEC_AUTO) { int i = 800, found; - dib7000p_autosearch_start(fe, fep); + dib7000p_autosearch_start(fe); do { msleep(1); found = dib7000p_autosearch_is_irq(fe); @@ -1479,15 +1519,19 @@ static int dib7000p_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_pa if (found == 0 || found == 1) return 0; - dib7000p_get_frontend(fe, fep); + dib7000p_get_frontend(fe); } - ret = dib7000p_tune(fe, fep); + ret = dib7000p_tune(fe); /* make this a config parameter */ - if (state->version == SOC7090) + if (state->version == SOC7090) { dib7090_set_output_mode(fe, state->cfg.output_mode); - else + if (state->cfg.enMpegOutput == 0) { + dib7090_setDibTxMux(state, MPEG_ON_DIBTX); + dib7090_setHostBusMux(state, DIBTX_ON_HOSTBUS); + } + } else dib7000p_set_output_mode(state, state->cfg.output_mode); return ret; @@ -1831,7 +1875,8 @@ static int w7090p_tuner_rw_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg m return num; } -int dib7090p_rw_on_apb(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num, u16 apb_address) +static int dib7090p_rw_on_apb(struct i2c_adapter *i2c_adap, + struct i2c_msg msg[], int num, u16 apb_address) { struct dib7000p_state *state = i2c_get_adapdata(i2c_adap); u16 word; @@ -1933,10 +1978,10 @@ static int dib7090_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[] apb_address = 915; break; case 0x27: - apb_address = 916; + apb_address = 917; break; case 0x28: - apb_address = 917; + apb_address = 916; break; case 0x1d: i = ((dib7000p_read_word(state, 72) >> 12) & 0x3); @@ -2031,12 +2076,7 @@ static u32 dib7090_calcSyncFreq(u32 P_Kin, u32 P_Kout, u32 insertExtSynchro, u32 static int dib7090_cfg_DibTx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout, u32 insertExtSynchro, u32 synchroMode, u32 syncWord, u32 syncSize) { - u8 index_buf; - u16 rx_copy_buf[22]; - dprintk("Configure DibStream Tx"); - for (index_buf = 0; index_buf < 22; index_buf++) - rx_copy_buf[index_buf] = dib7000p_read_word(state, 1536+index_buf); dib7000p_write_word(state, 1615, 1); dib7000p_write_word(state, 1603, P_Kin); @@ -2048,9 +2088,6 @@ static int dib7090_cfg_DibTx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout dib7000p_write_word(state, 1612, syncSize); dib7000p_write_word(state, 1615, 0); - for (index_buf = 0; index_buf < 22; index_buf++) - dib7000p_write_word(state, 1536+index_buf, rx_copy_buf[index_buf]); - return 0; } @@ -2077,109 +2114,121 @@ static int dib7090_cfg_DibRx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout return 0; } -static int dib7090_enDivOnHostBus(struct dib7000p_state *state) -{ - u16 reg; - - dprintk("Enable Diversity on host bus"); - reg = (1 << 8) | (1 << 5); - dib7000p_write_word(state, 1288, reg); - - return dib7090_cfg_DibTx(state, 5, 5, 0, 0, 0, 0); -} - -static int dib7090_enAdcOnHostBus(struct dib7000p_state *state) -{ - u16 reg; - - dprintk("Enable ADC on host bus"); - reg = (1 << 7) | (1 << 5); - dib7000p_write_word(state, 1288, reg); - - return dib7090_cfg_DibTx(state, 20, 5, 10, 0, 0, 0); -} - -static int dib7090_enMpegOnHostBus(struct dib7000p_state *state) +static void dib7090_enMpegMux(struct dib7000p_state *state, int onoff) { - u16 reg; - - dprintk("Enable Mpeg on host bus"); - reg = (1 << 9) | (1 << 5); - dib7000p_write_word(state, 1288, reg); + u16 reg_1287 = dib7000p_read_word(state, 1287); - return dib7090_cfg_DibTx(state, 8, 5, 0, 0, 0, 0); -} + switch (onoff) { + case 1: + reg_1287 &= ~(1<<7); + break; + case 0: + reg_1287 |= (1<<7); + break; + } -static int dib7090_enMpegInput(struct dib7000p_state *state) -{ - dprintk("Enable Mpeg input"); - return dib7090_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0); /*outputRate = 8 */ + dib7000p_write_word(state, 1287, reg_1287); } -static int dib7090_enMpegMux(struct dib7000p_state *state, u16 pulseWidth, u16 enSerialMode, u16 enSerialClkDiv2) +static void dib7090_configMpegMux(struct dib7000p_state *state, + u16 pulseWidth, u16 enSerialMode, u16 enSerialClkDiv2) { - u16 reg = (1 << 7) | ((pulseWidth & 0x1f) << 2) | ((enSerialMode & 0x1) << 1) | (enSerialClkDiv2 & 0x1); - dprintk("Enable Mpeg mux"); - dib7000p_write_word(state, 1287, reg); - reg &= ~(1 << 7); - dib7000p_write_word(state, 1287, reg); + dib7090_enMpegMux(state, 0); - reg = (1 << 4); - dib7000p_write_word(state, 1288, reg); + /* If the input mode is MPEG do not divide the serial clock */ + if ((enSerialMode == 1) && (state->input_mode_mpeg == 1)) + enSerialClkDiv2 = 0; - return 0; + dib7000p_write_word(state, 1287, ((pulseWidth & 0x1f) << 2) + | ((enSerialMode & 0x1) << 1) + | (enSerialClkDiv2 & 0x1)); + + dib7090_enMpegMux(state, 1); } -static int dib7090_disableMpegMux(struct dib7000p_state *state) +static void dib7090_setDibTxMux(struct dib7000p_state *state, int mode) { - u16 reg; - - dprintk("Disable Mpeg mux"); - dib7000p_write_word(state, 1288, 0); - - reg = dib7000p_read_word(state, 1287); - reg &= ~(1 << 7); - dib7000p_write_word(state, 1287, reg); + u16 reg_1288 = dib7000p_read_word(state, 1288) & ~(0x7 << 7); - return 0; + switch (mode) { + case MPEG_ON_DIBTX: + dprintk("SET MPEG ON DIBSTREAM TX"); + dib7090_cfg_DibTx(state, 8, 5, 0, 0, 0, 0); + reg_1288 |= (1<<9); + break; + case DIV_ON_DIBTX: + dprintk("SET DIV_OUT ON DIBSTREAM TX"); + dib7090_cfg_DibTx(state, 5, 5, 0, 0, 0, 0); + reg_1288 |= (1<<8); + break; + case ADC_ON_DIBTX: + dprintk("SET ADC_OUT ON DIBSTREAM TX"); + dib7090_cfg_DibTx(state, 20, 5, 10, 0, 0, 0); + reg_1288 |= (1<<7); + break; + default: + break; + } + dib7000p_write_word(state, 1288, reg_1288); } -static int dib7090_set_input_mode(struct dvb_frontend *fe, int mode) +static void dib7090_setHostBusMux(struct dib7000p_state *state, int mode) { - struct dib7000p_state *state = fe->demodulator_priv; + u16 reg_1288 = dib7000p_read_word(state, 1288) & ~(0x7 << 4); switch (mode) { - case INPUT_MODE_DIVERSITY: - dprintk("Enable diversity INPUT"); - dib7090_cfg_DibRx(state, 5, 5, 0, 0, 0, 0, 0); + case DEMOUT_ON_HOSTBUS: + dprintk("SET DEM OUT OLD INTERF ON HOST BUS"); + dib7090_enMpegMux(state, 0); + reg_1288 |= (1<<6); + break; + case DIBTX_ON_HOSTBUS: + dprintk("SET DIBSTREAM TX ON HOST BUS"); + dib7090_enMpegMux(state, 0); + reg_1288 |= (1<<5); break; - case INPUT_MODE_MPEG: - dprintk("Enable Mpeg INPUT"); - dib7090_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0); /*outputRate = 8 */ + case MPEG_ON_HOSTBUS: + dprintk("SET MPEG MUX ON HOST BUS"); + reg_1288 |= (1<<4); break; - case INPUT_MODE_OFF: default: - dprintk("Disable INPUT"); - dib7090_cfg_DibRx(state, 0, 0, 0, 0, 0, 0, 0); break; } - return 0; + dib7000p_write_word(state, 1288, reg_1288); } -static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff) +int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff) { + struct dib7000p_state *state = fe->demodulator_priv; + u16 reg_1287; + switch (onoff) { - case 0: /* only use the internal way - not the diversity input */ - dib7090_set_input_mode(fe, INPUT_MODE_MPEG); - break; - case 1: /* both ways */ - case 2: /* only the diversity input */ - dib7090_set_input_mode(fe, INPUT_MODE_DIVERSITY); - break; + case 0: /* only use the internal way - not the diversity input */ + dprintk("%s mode OFF : by default Enable Mpeg INPUT", __func__); + dib7090_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0); + + /* Do not divide the serial clock of MPEG MUX */ + /* in SERIAL MODE in case input mode MPEG is used */ + reg_1287 = dib7000p_read_word(state, 1287); + /* enSerialClkDiv2 == 1 ? */ + if ((reg_1287 & 0x1) == 1) { + /* force enSerialClkDiv2 = 0 */ + reg_1287 &= ~0x1; + dib7000p_write_word(state, 1287, reg_1287); + } + state->input_mode_mpeg = 1; + break; + case 1: /* both ways */ + case 2: /* only the diversity input */ + dprintk("%s ON : Enable diversity INPUT", __func__); + dib7090_cfg_DibRx(state, 5, 5, 0, 0, 0, 0, 0); + state->input_mode_mpeg = 0; + break; } + dib7000p_set_diversity_in(&state->demod, onoff); return 0; } @@ -2204,69 +2253,63 @@ static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode) case OUTMODE_MPEG2_SERIAL: if (prefer_mpeg_mux_use) { - dprintk("Sip 7090P setting output mode TS_SERIAL using Mpeg Mux"); - dib7090_enMpegOnHostBus(state); - dib7090_enMpegInput(state); - if (state->cfg.enMpegOutput == 1) - dib7090_enMpegMux(state, 3, 1, 1); - - } else { /* Use Smooth block */ - dprintk("Sip 7090P setting output mode TS_SERIAL using Smooth bloc"); - dib7090_disableMpegMux(state); - dib7000p_write_word(state, 1288, (1 << 6)); - outreg |= (2 << 6) | (0 << 1); + dprintk("setting output mode TS_SERIAL using Mpeg Mux"); + dib7090_configMpegMux(state, 3, 1, 1); + dib7090_setHostBusMux(state, MPEG_ON_HOSTBUS); + } else {/* Use Smooth block */ + dprintk("setting output mode TS_SERIAL using Smooth bloc"); + dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS); + outreg |= (2<<6) | (0 << 1); } break; case OUTMODE_MPEG2_PAR_GATED_CLK: if (prefer_mpeg_mux_use) { - dprintk("Sip 7090P setting output mode TS_PARALLEL_GATED using Mpeg Mux"); - dib7090_enMpegOnHostBus(state); - dib7090_enMpegInput(state); - if (state->cfg.enMpegOutput == 1) - dib7090_enMpegMux(state, 2, 0, 0); - } else { /* Use Smooth block */ - dprintk("Sip 7090P setting output mode TS_PARALLEL_GATED using Smooth block"); - dib7090_disableMpegMux(state); - dib7000p_write_word(state, 1288, (1 << 6)); - outreg |= (0 << 6); + dprintk("setting output mode TS_PARALLEL_GATED using Mpeg Mux"); + dib7090_configMpegMux(state, 2, 0, 0); + dib7090_setHostBusMux(state, MPEG_ON_HOSTBUS); + } else { /* Use Smooth block */ + dprintk("setting output mode TS_PARALLEL_GATED using Smooth block"); + dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS); + outreg |= (0<<6); } break; case OUTMODE_MPEG2_PAR_CONT_CLK: /* Using Smooth block only */ - dprintk("Sip 7090P setting output mode TS_PARALLEL_CONT using Smooth block"); - dib7090_disableMpegMux(state); - dib7000p_write_word(state, 1288, (1 << 6)); - outreg |= (1 << 6); + dprintk("setting output mode TS_PARALLEL_CONT using Smooth block"); + dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS); + outreg |= (1<<6); break; case OUTMODE_MPEG2_FIFO: /* Using Smooth block because not supported by new Mpeg Mux bloc */ - dprintk("Sip 7090P setting output mode TS_FIFO using Smooth block"); - dib7090_disableMpegMux(state); - dib7000p_write_word(state, 1288, (1 << 6)); - outreg |= (5 << 6); + dprintk("setting output mode TS_FIFO using Smooth block"); + dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS); + outreg |= (5<<6); smo_mode |= (3 << 1); fifo_threshold = 512; break; case OUTMODE_DIVERSITY: - dprintk("Sip 7090P setting output mode MODE_DIVERSITY"); - dib7090_disableMpegMux(state); - dib7090_enDivOnHostBus(state); + dprintk("setting output mode MODE_DIVERSITY"); + dib7090_setDibTxMux(state, DIV_ON_DIBTX); + dib7090_setHostBusMux(state, DIBTX_ON_HOSTBUS); break; case OUTMODE_ANALOG_ADC: - dprintk("Sip 7090P setting output mode MODE_ANALOG_ADC"); - dib7090_enAdcOnHostBus(state); + dprintk("setting output mode MODE_ANALOG_ADC"); + dib7090_setDibTxMux(state, ADC_ON_DIBTX); + dib7090_setHostBusMux(state, DIBTX_ON_HOSTBUS); break; } + if (mode != OUTMODE_HIGH_Z) + outreg |= (1 << 10); if (state->cfg.output_mpeg2_in_188_bytes) smo_mode |= (1 << 5); ret |= dib7000p_write_word(state, 235, smo_mode); ret |= dib7000p_write_word(state, 236, fifo_threshold); /* synchronous fread */ - ret |= dib7000p_write_word(state, 1286, outreg | (1 << 10)); /* allways set Dout active = 1 !!! */ + ret |= dib7000p_write_word(state, 1286, outreg); return ret; } @@ -2296,13 +2339,6 @@ int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff) } EXPORT_SYMBOL(dib7090_tuner_sleep); -int dib7090_agc_restart(struct dvb_frontend *fe, u8 restart) -{ - dprintk("AGC restart callback: %d", restart); - return 0; -} -EXPORT_SYMBOL(dib7090_agc_restart); - int dib7090_get_adc_power(struct dvb_frontend *fe) { return dib7000p_get_adc_power(fe); @@ -2391,9 +2427,9 @@ error: EXPORT_SYMBOL(dib7000p_attach); static struct dvb_frontend_ops dib7000p_ops = { + .delsys = { SYS_DVBT }, .info = { .name = "DiBcom 7000PC", - .type = FE_OFDM, .frequency_min = 44250000, .frequency_max = 867250000, .frequency_stepsize = 62500, diff --git a/drivers/media/dvb/frontends/dib7000p.h b/drivers/media/dvb/frontends/dib7000p.h index 0179f9474bac..b61b03a6e1ed 100644 --- a/drivers/media/dvb/frontends/dib7000p.h +++ b/drivers/media/dvb/frontends/dib7000p.h @@ -56,11 +56,12 @@ extern int dib7000p_pid_filter(struct dvb_frontend *, u8 id, u16 pid, u8 onoff); extern int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff); extern int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw); extern u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf); -extern int dib7090_agc_restart(struct dvb_frontend *fe, u8 restart); extern int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff); extern int dib7090_get_adc_power(struct dvb_frontend *fe); extern struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe); extern int dib7090_slave_reset(struct dvb_frontend *fe); +extern int dib7000p_get_agc_values(struct dvb_frontend *fe, + u16 *agc_global, u16 *agc1, u16 *agc2, u16 *wbd); #else static inline struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg) { @@ -122,12 +123,6 @@ static inline u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf) return 0; } -static inline int dib7090_agc_restart(struct dvb_frontend *fe, u8 restart) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return -ENODEV; -} - static inline int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); @@ -151,6 +146,13 @@ static inline int dib7090_slave_reset(struct dvb_frontend *fe) printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return -ENODEV; } + +static inline int dib7000p_get_agc_values(struct dvb_frontend *fe, + u16 *agc_global, u16 *agc1, u16 *agc2, u16 *wbd) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return -ENODEV; +} #endif #endif diff --git a/drivers/media/dvb/frontends/dib8000.c b/drivers/media/dvb/frontends/dib8000.c index fe284d5292f5..9ca34f495009 100644 --- a/drivers/media/dvb/frontends/dib8000.c +++ b/drivers/media/dvb/frontends/dib8000.c @@ -81,11 +81,15 @@ struct dib8000_state { u8 i2c_write_buffer[4]; u8 i2c_read_buffer[2]; struct mutex i2c_buffer_lock; + u8 input_mode_mpeg; + + u16 tuner_enable; + struct i2c_adapter dib8096p_tuner_adap; }; enum dib8000_power_mode { - DIB8000M_POWER_ALL = 0, - DIB8000M_POWER_INTERFACE_ONLY, + DIB8000_POWER_ALL = 0, + DIB8000_POWER_INTERFACE_ONLY, }; static u16 dib8000_i2c_read16(struct i2c_device *i2c, u16 reg) @@ -428,20 +432,31 @@ static void dib8000_set_power_mode(struct dib8000_state *state, enum dib8000_pow /* by default everything is going to be powered off */ u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0xffff, reg_900 = (dib8000_read_word(state, 900) & 0xfffc) | 0x3, + reg_1280; + + if (state->revision != 0x8090) reg_1280 = (dib8000_read_word(state, 1280) & 0x00ff) | 0xff00; + else + reg_1280 = (dib8000_read_word(state, 1280) & 0x707f) | 0x8f80; /* now, depending on the requested mode, we power on */ switch (mode) { /* power up everything in the demod */ - case DIB8000M_POWER_ALL: + case DIB8000_POWER_ALL: reg_774 = 0x0000; reg_775 = 0x0000; reg_776 = 0x0000; reg_900 &= 0xfffc; - reg_1280 &= 0x00ff; + if (state->revision != 0x8090) + reg_1280 &= 0x00ff; + else + reg_1280 &= 0x707f; break; - case DIB8000M_POWER_INTERFACE_ONLY: - reg_1280 &= 0x00ff; + case DIB8000_POWER_INTERFACE_ONLY: + if (state->revision != 0x8090) + reg_1280 &= 0x00ff; + else + reg_1280 &= 0xfa7b; break; } @@ -453,19 +468,67 @@ static void dib8000_set_power_mode(struct dib8000_state *state, enum dib8000_pow dib8000_write_word(state, 1280, reg_1280); } +static int dib8000_init_sdram(struct dib8000_state *state) +{ + u16 reg = 0; + dprintk("Init sdram"); + + reg = dib8000_read_word(state, 274)&0xfff0; + /* P_dintlv_delay_ram = 7 because of MobileSdram */ + dib8000_write_word(state, 274, reg | 0x7); + + dib8000_write_word(state, 1803, (7<<2)); + + reg = dib8000_read_word(state, 1280); + /* force restart P_restart_sdram */ + dib8000_write_word(state, 1280, reg | (1<<2)); + + /* release restart P_restart_sdram */ + dib8000_write_word(state, 1280, reg); + + return 0; +} + static int dib8000_set_adc_state(struct dib8000_state *state, enum dibx000_adc_states no) { int ret = 0; - u16 reg_907 = dib8000_read_word(state, 907), reg_908 = dib8000_read_word(state, 908); + u16 reg, reg_907 = dib8000_read_word(state, 907); + u16 reg_908 = dib8000_read_word(state, 908); switch (no) { case DIBX000_SLOW_ADC_ON: - reg_908 |= (1 << 1) | (1 << 0); - ret |= dib8000_write_word(state, 908, reg_908); - reg_908 &= ~(1 << 1); + if (state->revision != 0x8090) { + reg_908 |= (1 << 1) | (1 << 0); + ret |= dib8000_write_word(state, 908, reg_908); + reg_908 &= ~(1 << 1); + } else { + reg = dib8000_read_word(state, 1925); + /* en_slowAdc = 1 & reset_sladc = 1 */ + dib8000_write_word(state, 1925, reg | + (1<<4) | (1<<2)); + + /* read acces to make it works... strange ... */ + reg = dib8000_read_word(state, 1925); + msleep(20); + /* en_slowAdc = 1 & reset_sladc = 0 */ + dib8000_write_word(state, 1925, reg & ~(1<<4)); + + reg = dib8000_read_word(state, 921) & ~((0x3 << 14) + | (0x3 << 12)); + /* ref = Vin1 => Vbg ; sel = Vin0 or Vin3 ; + (Vin2 = Vcm) */ + dib8000_write_word(state, 921, reg | (1 << 14) + | (3 << 12)); + } break; case DIBX000_SLOW_ADC_OFF: + if (state->revision == 0x8090) { + reg = dib8000_read_word(state, 1925); + /* reset_sladc = 1 en_slowAdc = 0 */ + dib8000_write_word(state, 1925, + (reg & ~(1<<2)) | (1<<4)); + } reg_908 |= (1 << 1) | (1 << 0); break; @@ -521,7 +584,12 @@ static int dib8000_set_bandwidth(struct dvb_frontend *fe, u32 bw) static int dib8000_sad_calib(struct dib8000_state *state) { -/* internal */ + if (state->revision == 0x8090) { + dprintk("%s: the sad calibration is not needed for the dib8096P", + __func__); + return 0; + } + /* internal */ dib8000_write_word(state, 923, (0 << 1) | (0 << 0)); dib8000_write_word(state, 924, 776); // 0.625*3.3 / 4096 @@ -546,48 +614,129 @@ EXPORT_SYMBOL(dib8000_set_wbd_ref); static void dib8000_reset_pll_common(struct dib8000_state *state, const struct dibx000_bandwidth_config *bw) { dprintk("ifreq: %d %x, inversion: %d", bw->ifreq, bw->ifreq, bw->ifreq >> 25); - dib8000_write_word(state, 23, (u16) (((bw->internal * 1000) >> 16) & 0xffff)); /* P_sec_len */ - dib8000_write_word(state, 24, (u16) ((bw->internal * 1000) & 0xffff)); + if (state->revision != 0x8090) { + dib8000_write_word(state, 23, + (u16) (((bw->internal * 1000) >> 16) & 0xffff)); + dib8000_write_word(state, 24, + (u16) ((bw->internal * 1000) & 0xffff)); + } else { + dib8000_write_word(state, 23, (u16) (((bw->internal / 2 * 1000) >> 16) & 0xffff)); + dib8000_write_word(state, 24, + (u16) ((bw->internal / 2 * 1000) & 0xffff)); + } dib8000_write_word(state, 27, (u16) ((bw->ifreq >> 16) & 0x01ff)); dib8000_write_word(state, 28, (u16) (bw->ifreq & 0xffff)); dib8000_write_word(state, 26, (u16) ((bw->ifreq >> 25) & 0x0003)); - dib8000_write_word(state, 922, bw->sad_cfg); + if (state->revision != 0x8090) + dib8000_write_word(state, 922, bw->sad_cfg); } static void dib8000_reset_pll(struct dib8000_state *state) { const struct dibx000_bandwidth_config *pll = state->cfg.pll; - u16 clk_cfg1; - - // clk_cfg0 - dib8000_write_word(state, 901, (pll->pll_prediv << 8) | (pll->pll_ratio << 0)); - - // clk_cfg1 - clk_cfg1 = (1 << 10) | (0 << 9) | (pll->IO_CLK_en_core << 8) | - (pll->bypclk_div << 5) | (pll->enable_refdiv << 4) | (1 << 3) | - (pll->pll_range << 1) | (pll->pll_reset << 0); - - dib8000_write_word(state, 902, clk_cfg1); - clk_cfg1 = (clk_cfg1 & 0xfff7) | (pll->pll_bypass << 3); - dib8000_write_word(state, 902, clk_cfg1); - - dprintk("clk_cfg1: 0x%04x", clk_cfg1); /* 0x507 1 0 1 000 0 0 11 1 */ - - /* smpl_cfg: P_refclksel=2, P_ensmplsel=1 nodivsmpl=1 */ - if (state->cfg.pll->ADClkSrc == 0) - dib8000_write_word(state, 904, (0 << 15) | (0 << 12) | (0 << 10) | - (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1)); - else if (state->cfg.refclksel != 0) - dib8000_write_word(state, 904, (0 << 15) | (1 << 12) | - ((state->cfg.refclksel & 0x3) << 10) | (pll->modulo << 8) | - (pll->ADClkSrc << 7) | (0 << 1)); - else - dib8000_write_word(state, 904, (0 << 15) | (1 << 12) | (3 << 10) | (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1)); + u16 clk_cfg1, reg; + + if (state->revision != 0x8090) { + dib8000_write_word(state, 901, + (pll->pll_prediv << 8) | (pll->pll_ratio << 0)); + + clk_cfg1 = (1 << 10) | (0 << 9) | (pll->IO_CLK_en_core << 8) | + (pll->bypclk_div << 5) | (pll->enable_refdiv << 4) | + (1 << 3) | (pll->pll_range << 1) | + (pll->pll_reset << 0); + + dib8000_write_word(state, 902, clk_cfg1); + clk_cfg1 = (clk_cfg1 & 0xfff7) | (pll->pll_bypass << 3); + dib8000_write_word(state, 902, clk_cfg1); + + dprintk("clk_cfg1: 0x%04x", clk_cfg1); + + /* smpl_cfg: P_refclksel=2, P_ensmplsel=1 nodivsmpl=1 */ + if (state->cfg.pll->ADClkSrc == 0) + dib8000_write_word(state, 904, + (0 << 15) | (0 << 12) | (0 << 10) | + (pll->modulo << 8) | + (pll->ADClkSrc << 7) | (0 << 1)); + else if (state->cfg.refclksel != 0) + dib8000_write_word(state, 904, (0 << 15) | (1 << 12) | + ((state->cfg.refclksel & 0x3) << 10) | + (pll->modulo << 8) | + (pll->ADClkSrc << 7) | (0 << 1)); + else + dib8000_write_word(state, 904, (0 << 15) | (1 << 12) | + (3 << 10) | (pll->modulo << 8) | + (pll->ADClkSrc << 7) | (0 << 1)); + } else { + dib8000_write_word(state, 1856, (!pll->pll_reset<<13) | + (pll->pll_range<<12) | (pll->pll_ratio<<6) | + (pll->pll_prediv)); + + reg = dib8000_read_word(state, 1857); + dib8000_write_word(state, 1857, reg|(!pll->pll_bypass<<15)); + + reg = dib8000_read_word(state, 1858); /* Force clk out pll /2 */ + dib8000_write_word(state, 1858, reg | 1); + + dib8000_write_word(state, 904, (pll->modulo << 8)); + } dib8000_reset_pll_common(state, pll); } +int dib8000_update_pll(struct dvb_frontend *fe, + struct dibx000_bandwidth_config *pll) +{ + struct dib8000_state *state = fe->demodulator_priv; + u16 reg_1857, reg_1856 = dib8000_read_word(state, 1856); + u8 loopdiv, prediv; + u32 internal, xtal; + + /* get back old values */ + prediv = reg_1856 & 0x3f; + loopdiv = (reg_1856 >> 6) & 0x3f; + + if ((pll != NULL) && (pll->pll_prediv != prediv || + pll->pll_ratio != loopdiv)) { + dprintk("Updating pll (prediv: old = %d new = %d ; loopdiv : old = %d new = %d)", prediv, pll->pll_prediv, loopdiv, pll->pll_ratio); + reg_1856 &= 0xf000; + reg_1857 = dib8000_read_word(state, 1857); + /* disable PLL */ + dib8000_write_word(state, 1857, reg_1857 & ~(1 << 15)); + + dib8000_write_word(state, 1856, reg_1856 | + ((pll->pll_ratio & 0x3f) << 6) | + (pll->pll_prediv & 0x3f)); + + /* write new system clk into P_sec_len */ + internal = dib8000_read32(state, 23) / 1000; + dprintk("Old Internal = %d", internal); + xtal = 2 * (internal / loopdiv) * prediv; + internal = 1000 * (xtal/pll->pll_prediv) * pll->pll_ratio; + dprintk("Xtal = %d , New Fmem = %d New Fdemod = %d, New Fsampling = %d", xtal, internal/1000, internal/2000, internal/8000); + dprintk("New Internal = %d", internal); + + dib8000_write_word(state, 23, + (u16) (((internal / 2) >> 16) & 0xffff)); + dib8000_write_word(state, 24, (u16) ((internal / 2) & 0xffff)); + /* enable PLL */ + dib8000_write_word(state, 1857, reg_1857 | (1 << 15)); + + while (((dib8000_read_word(state, 1856)>>15)&0x1) != 1) + dprintk("Waiting for PLL to lock"); + + /* verify */ + reg_1856 = dib8000_read_word(state, 1856); + dprintk("PLL Updated with prediv = %d and loopdiv = %d", + reg_1856&0x3f, (reg_1856>>6)&0x3f); + + return 0; + } + return -EINVAL; +} +EXPORT_SYMBOL(dib8000_update_pll); + + static int dib8000_reset_gpio(struct dib8000_state *st) { /* reset the GPIOs */ @@ -721,9 +870,6 @@ static const u16 dib8000_defaults[] = { (3 << 5) | /* P_ctrl_pre_freq_step=3 */ (1 << 0), /* P_pre_freq_win_len=1 */ - 1, 903, - (0 << 4) | 2, // P_divclksel=0 P_divbitsel=2 (was clk=3,bit=1 for MPW) - 0, }; @@ -740,7 +886,8 @@ static u16 dib8000_identify(struct i2c_device *client) } value = dib8000_i2c_read16(client, 897); - if (value != 0x8000 && value != 0x8001 && value != 0x8002) { + if (value != 0x8000 && value != 0x8001 && + value != 0x8002 && value != 0x8090) { dprintk("wrong Device ID (%x)", value); return 0; } @@ -755,6 +902,9 @@ static u16 dib8000_identify(struct i2c_device *client) case 0x8002: dprintk("found DiB8000C"); break; + case 0x8090: + dprintk("found DiB8096P"); + break; } return value; } @@ -763,17 +913,19 @@ static int dib8000_reset(struct dvb_frontend *fe) { struct dib8000_state *state = fe->demodulator_priv; - dib8000_write_word(state, 1287, 0x0003); /* sram lead in, rdy */ - if ((state->revision = dib8000_identify(&state->i2c)) == 0) return -EINVAL; + /* sram lead in, rdy */ + if (state->revision != 0x8090) + dib8000_write_word(state, 1287, 0x0003); + if (state->revision == 0x8000) dprintk("error : dib8000 MA not supported"); dibx000_reset_i2c_master(&state->i2c_master); - dib8000_set_power_mode(state, DIB8000M_POWER_ALL); + dib8000_set_power_mode(state, DIB8000_POWER_ALL); /* always leave the VBG voltage on - it consumes almost nothing but takes a long time to start */ dib8000_set_adc_state(state, DIBX000_VBG_ENABLE); @@ -782,8 +934,10 @@ static int dib8000_reset(struct dvb_frontend *fe) dib8000_write_word(state, 770, 0xffff); dib8000_write_word(state, 771, 0xffff); dib8000_write_word(state, 772, 0xfffc); - dib8000_write_word(state, 898, 0x000c); // sad - dib8000_write_word(state, 1280, 0x004d); + if (state->revision == 0x8090) + dib8000_write_word(state, 1280, 0x0045); + else + dib8000_write_word(state, 1280, 0x004d); dib8000_write_word(state, 1281, 0x000c); dib8000_write_word(state, 770, 0x0000); @@ -794,19 +948,25 @@ static int dib8000_reset(struct dvb_frontend *fe) dib8000_write_word(state, 1281, 0x0000); /* drives */ - if (state->cfg.drives) - dib8000_write_word(state, 906, state->cfg.drives); - else { - dprintk("using standard PAD-drive-settings, please adjust settings in config-struct to be optimal."); - dib8000_write_word(state, 906, 0x2d98); // min drive SDRAM - not optimal - adjust + if (state->revision != 0x8090) { + if (state->cfg.drives) + dib8000_write_word(state, 906, state->cfg.drives); + else { + dprintk("using standard PAD-drive-settings, please adjust settings in config-struct to be optimal."); + /* min drive SDRAM - not optimal - adjust */ + dib8000_write_word(state, 906, 0x2d98); + } } dib8000_reset_pll(state); + if (state->revision != 0x8090) + dib8000_write_word(state, 898, 0x0004); if (dib8000_reset_gpio(state) != 0) dprintk("GPIO reset was not successful."); - if (dib8000_set_output_mode(fe, OUTMODE_HIGH_Z) != 0) + if ((state->revision != 0x8090) && + (dib8000_set_output_mode(fe, OUTMODE_HIGH_Z) != 0)) dprintk("OUTPUT_MODE could not be resetted."); state->current_agc = NULL; @@ -832,6 +992,8 @@ static int dib8000_reset(struct dvb_frontend *fe) l = *n++; } } + if (state->revision != 0x8090) + dib8000_write_word(state, 903, (0 << 4) | 2); state->isdbt_cfg_loaded = 0; //div_cfg override for special configs @@ -844,10 +1006,12 @@ static int dib8000_reset(struct dvb_frontend *fe) dib8000_set_bandwidth(fe, 6000); dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON); - dib8000_sad_calib(state); - dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF); + if (state->revision != 0x8090) { + dib8000_sad_calib(state); + dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF); + } - dib8000_set_power_mode(state, DIB8000M_POWER_INTERFACE_ONLY); + dib8000_set_power_mode(state, DIB8000_POWER_INTERFACE_ONLY); return 0; } @@ -879,6 +1043,8 @@ static int dib8000_set_agc_config(struct dib8000_state *state, u8 band) { struct dibx000_agc_config *agc = NULL; int i; + u16 reg; + if (state->current_band == band && state->current_agc != NULL) return 0; state->current_band = band; @@ -914,6 +1080,12 @@ static int dib8000_set_agc_config(struct dib8000_state *state, u8 band) dib8000_write_word(state, 106, state->wbd_ref); else // use default dib8000_write_word(state, 106, agc->wbd_ref); + + if (state->revision == 0x8090) { + reg = dib8000_read_word(state, 922) & (0x3 << 2); + dib8000_write_word(state, 922, reg | (agc->wbd_sel << 2)); + } + dib8000_write_word(state, 107, (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8)); dib8000_write_word(state, 108, agc->agc1_max); dib8000_write_word(state, 109, agc->agc1_min); @@ -925,7 +1097,10 @@ static int dib8000_set_agc_config(struct dib8000_state *state, u8 band) dib8000_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2); dib8000_write_word(state, 75, agc->agc1_pt3); - dib8000_write_word(state, 923, (dib8000_read_word(state, 923) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2)); /*LB : 929 -> 923 */ + if (state->revision != 0x8090) + dib8000_write_word(state, 923, + (dib8000_read_word(state, 923) & 0xffe3) | + (agc->wbd_inv << 4) | (agc->wbd_sel << 2)); return 0; } @@ -968,14 +1143,30 @@ static int dib8000_agc_startup(struct dvb_frontend *fe) { struct dib8000_state *state = fe->demodulator_priv; enum frontend_tune_state *tune_state = &state->tune_state; - int ret = 0; + u16 reg, upd_demod_gain_period = 0x8000; switch (*tune_state) { case CT_AGC_START: // set power-up level: interf+analog+AGC - dib8000_set_adc_state(state, DIBX000_ADC_ON); + if (state->revision != 0x8090) + dib8000_set_adc_state(state, DIBX000_ADC_ON); + else { + dib8000_set_power_mode(state, DIB8000_POWER_ALL); + + reg = dib8000_read_word(state, 1947)&0xff00; + dib8000_write_word(state, 1946, + upd_demod_gain_period & 0xFFFF); + /* bit 14 = enDemodGain */ + dib8000_write_word(state, 1947, reg | (1<<14) | + ((upd_demod_gain_period >> 16) & 0xFF)); + + /* enable adc i & q */ + reg = dib8000_read_word(state, 1920); + dib8000_write_word(state, 1920, (reg | 0x3) & + (~(1 << 7))); + } if (dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000))) != 0) { *tune_state = CT_AGC_STOP; @@ -1026,6 +1217,579 @@ static int dib8000_agc_startup(struct dvb_frontend *fe) } +static void dib8096p_host_bus_drive(struct dib8000_state *state, u8 drive) +{ + u16 reg; + + drive &= 0x7; + + /* drive host bus 2, 3, 4 */ + reg = dib8000_read_word(state, 1798) & + ~(0x7 | (0x7 << 6) | (0x7 << 12)); + reg |= (drive<<12) | (drive<<6) | drive; + dib8000_write_word(state, 1798, reg); + + /* drive host bus 5,6 */ + reg = dib8000_read_word(state, 1799) & ~((0x7 << 2) | (0x7 << 8)); + reg |= (drive<<8) | (drive<<2); + dib8000_write_word(state, 1799, reg); + + /* drive host bus 7, 8, 9 */ + reg = dib8000_read_word(state, 1800) & + ~(0x7 | (0x7 << 6) | (0x7 << 12)); + reg |= (drive<<12) | (drive<<6) | drive; + dib8000_write_word(state, 1800, reg); + + /* drive host bus 10, 11 */ + reg = dib8000_read_word(state, 1801) & ~((0x7 << 2) | (0x7 << 8)); + reg |= (drive<<8) | (drive<<2); + dib8000_write_word(state, 1801, reg); + + /* drive host bus 12, 13, 14 */ + reg = dib8000_read_word(state, 1802) & + ~(0x7 | (0x7 << 6) | (0x7 << 12)); + reg |= (drive<<12) | (drive<<6) | drive; + dib8000_write_word(state, 1802, reg); +} + +static u32 dib8096p_calcSyncFreq(u32 P_Kin, u32 P_Kout, + u32 insertExtSynchro, u32 syncSize) +{ + u32 quantif = 3; + u32 nom = (insertExtSynchro * P_Kin+syncSize); + u32 denom = P_Kout; + u32 syncFreq = ((nom << quantif) / denom); + + if ((syncFreq & ((1 << quantif) - 1)) != 0) + syncFreq = (syncFreq >> quantif) + 1; + else + syncFreq = (syncFreq >> quantif); + + if (syncFreq != 0) + syncFreq = syncFreq - 1; + + return syncFreq; +} + +static void dib8096p_cfg_DibTx(struct dib8000_state *state, u32 P_Kin, + u32 P_Kout, u32 insertExtSynchro, u32 synchroMode, + u32 syncWord, u32 syncSize) +{ + dprintk("Configure DibStream Tx"); + + dib8000_write_word(state, 1615, 1); + dib8000_write_word(state, 1603, P_Kin); + dib8000_write_word(state, 1605, P_Kout); + dib8000_write_word(state, 1606, insertExtSynchro); + dib8000_write_word(state, 1608, synchroMode); + dib8000_write_word(state, 1609, (syncWord >> 16) & 0xffff); + dib8000_write_word(state, 1610, syncWord & 0xffff); + dib8000_write_word(state, 1612, syncSize); + dib8000_write_word(state, 1615, 0); +} + +static void dib8096p_cfg_DibRx(struct dib8000_state *state, u32 P_Kin, + u32 P_Kout, u32 synchroMode, u32 insertExtSynchro, + u32 syncWord, u32 syncSize, u32 dataOutRate) +{ + u32 syncFreq; + + dprintk("Configure DibStream Rx synchroMode = %d", synchroMode); + + if ((P_Kin != 0) && (P_Kout != 0)) { + syncFreq = dib8096p_calcSyncFreq(P_Kin, P_Kout, + insertExtSynchro, syncSize); + dib8000_write_word(state, 1542, syncFreq); + } + + dib8000_write_word(state, 1554, 1); + dib8000_write_word(state, 1536, P_Kin); + dib8000_write_word(state, 1537, P_Kout); + dib8000_write_word(state, 1539, synchroMode); + dib8000_write_word(state, 1540, (syncWord >> 16) & 0xffff); + dib8000_write_word(state, 1541, syncWord & 0xffff); + dib8000_write_word(state, 1543, syncSize); + dib8000_write_word(state, 1544, dataOutRate); + dib8000_write_word(state, 1554, 0); +} + +static void dib8096p_enMpegMux(struct dib8000_state *state, int onoff) +{ + u16 reg_1287; + + reg_1287 = dib8000_read_word(state, 1287); + + switch (onoff) { + case 1: + reg_1287 &= ~(1 << 8); + break; + case 0: + reg_1287 |= (1 << 8); + break; + } + + dib8000_write_word(state, 1287, reg_1287); +} + +static void dib8096p_configMpegMux(struct dib8000_state *state, + u16 pulseWidth, u16 enSerialMode, u16 enSerialClkDiv2) +{ + u16 reg_1287; + + dprintk("Enable Mpeg mux"); + + dib8096p_enMpegMux(state, 0); + + /* If the input mode is MPEG do not divide the serial clock */ + if ((enSerialMode == 1) && (state->input_mode_mpeg == 1)) + enSerialClkDiv2 = 0; + + reg_1287 = ((pulseWidth & 0x1f) << 3) | + ((enSerialMode & 0x1) << 2) | (enSerialClkDiv2 & 0x1); + dib8000_write_word(state, 1287, reg_1287); + + dib8096p_enMpegMux(state, 1); +} + +static void dib8096p_setDibTxMux(struct dib8000_state *state, int mode) +{ + u16 reg_1288 = dib8000_read_word(state, 1288) & ~(0x7 << 7); + + switch (mode) { + case MPEG_ON_DIBTX: + dprintk("SET MPEG ON DIBSTREAM TX"); + dib8096p_cfg_DibTx(state, 8, 5, 0, 0, 0, 0); + reg_1288 |= (1 << 9); break; + case DIV_ON_DIBTX: + dprintk("SET DIV_OUT ON DIBSTREAM TX"); + dib8096p_cfg_DibTx(state, 5, 5, 0, 0, 0, 0); + reg_1288 |= (1 << 8); break; + case ADC_ON_DIBTX: + dprintk("SET ADC_OUT ON DIBSTREAM TX"); + dib8096p_cfg_DibTx(state, 20, 5, 10, 0, 0, 0); + reg_1288 |= (1 << 7); break; + default: + break; + } + dib8000_write_word(state, 1288, reg_1288); +} + +static void dib8096p_setHostBusMux(struct dib8000_state *state, int mode) +{ + u16 reg_1288 = dib8000_read_word(state, 1288) & ~(0x7 << 4); + + switch (mode) { + case DEMOUT_ON_HOSTBUS: + dprintk("SET DEM OUT OLD INTERF ON HOST BUS"); + dib8096p_enMpegMux(state, 0); + reg_1288 |= (1 << 6); + break; + case DIBTX_ON_HOSTBUS: + dprintk("SET DIBSTREAM TX ON HOST BUS"); + dib8096p_enMpegMux(state, 0); + reg_1288 |= (1 << 5); + break; + case MPEG_ON_HOSTBUS: + dprintk("SET MPEG MUX ON HOST BUS"); + reg_1288 |= (1 << 4); + break; + default: + break; + } + dib8000_write_word(state, 1288, reg_1288); +} + +static int dib8096p_set_diversity_in(struct dvb_frontend *fe, int onoff) +{ + struct dib8000_state *state = fe->demodulator_priv; + u16 reg_1287; + + switch (onoff) { + case 0: /* only use the internal way - not the diversity input */ + dprintk("%s mode OFF : by default Enable Mpeg INPUT", + __func__); + /* outputRate = 8 */ + dib8096p_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0); + + /* Do not divide the serial clock of MPEG MUX in + SERIAL MODE in case input mode MPEG is used */ + reg_1287 = dib8000_read_word(state, 1287); + /* enSerialClkDiv2 == 1 ? */ + if ((reg_1287 & 0x1) == 1) { + /* force enSerialClkDiv2 = 0 */ + reg_1287 &= ~0x1; + dib8000_write_word(state, 1287, reg_1287); + } + state->input_mode_mpeg = 1; + break; + case 1: /* both ways */ + case 2: /* only the diversity input */ + dprintk("%s ON : Enable diversity INPUT", __func__); + dib8096p_cfg_DibRx(state, 5, 5, 0, 0, 0, 0, 0); + state->input_mode_mpeg = 0; + break; + } + + dib8000_set_diversity_in(state->fe[0], onoff); + return 0; +} + +static int dib8096p_set_output_mode(struct dvb_frontend *fe, int mode) +{ + struct dib8000_state *state = fe->demodulator_priv; + u16 outreg, smo_mode, fifo_threshold; + u8 prefer_mpeg_mux_use = 1; + int ret = 0; + + dib8096p_host_bus_drive(state, 1); + + fifo_threshold = 1792; + smo_mode = (dib8000_read_word(state, 299) & 0x0050) | (1 << 1); + outreg = dib8000_read_word(state, 1286) & + ~((1 << 10) | (0x7 << 6) | (1 << 1)); + + switch (mode) { + case OUTMODE_HIGH_Z: + outreg = 0; + break; + + case OUTMODE_MPEG2_SERIAL: + if (prefer_mpeg_mux_use) { + dprintk("dib8096P setting output mode TS_SERIAL using Mpeg Mux"); + dib8096p_configMpegMux(state, 3, 1, 1); + dib8096p_setHostBusMux(state, MPEG_ON_HOSTBUS); + } else {/* Use Smooth block */ + dprintk("dib8096P setting output mode TS_SERIAL using Smooth bloc"); + dib8096p_setHostBusMux(state, + DEMOUT_ON_HOSTBUS); + outreg |= (2 << 6) | (0 << 1); + } + break; + + case OUTMODE_MPEG2_PAR_GATED_CLK: + if (prefer_mpeg_mux_use) { + dprintk("dib8096P setting output mode TS_PARALLEL_GATED using Mpeg Mux"); + dib8096p_configMpegMux(state, 2, 0, 0); + dib8096p_setHostBusMux(state, MPEG_ON_HOSTBUS); + } else { /* Use Smooth block */ + dprintk("dib8096P setting output mode TS_PARALLEL_GATED using Smooth block"); + dib8096p_setHostBusMux(state, + DEMOUT_ON_HOSTBUS); + outreg |= (0 << 6); + } + break; + + case OUTMODE_MPEG2_PAR_CONT_CLK: /* Using Smooth block only */ + dprintk("dib8096P setting output mode TS_PARALLEL_CONT using Smooth block"); + dib8096p_setHostBusMux(state, DEMOUT_ON_HOSTBUS); + outreg |= (1 << 6); + break; + + case OUTMODE_MPEG2_FIFO: + /* Using Smooth block because not supported + by new Mpeg Mux bloc */ + dprintk("dib8096P setting output mode TS_FIFO using Smooth block"); + dib8096p_setHostBusMux(state, DEMOUT_ON_HOSTBUS); + outreg |= (5 << 6); + smo_mode |= (3 << 1); + fifo_threshold = 512; + break; + + case OUTMODE_DIVERSITY: + dprintk("dib8096P setting output mode MODE_DIVERSITY"); + dib8096p_setDibTxMux(state, DIV_ON_DIBTX); + dib8096p_setHostBusMux(state, DIBTX_ON_HOSTBUS); + break; + + case OUTMODE_ANALOG_ADC: + dprintk("dib8096P setting output mode MODE_ANALOG_ADC"); + dib8096p_setDibTxMux(state, ADC_ON_DIBTX); + dib8096p_setHostBusMux(state, DIBTX_ON_HOSTBUS); + break; + } + + if (mode != OUTMODE_HIGH_Z) + outreg |= (1<<10); + + dprintk("output_mpeg2_in_188_bytes = %d", + state->cfg.output_mpeg2_in_188_bytes); + if (state->cfg.output_mpeg2_in_188_bytes) + smo_mode |= (1 << 5); + + ret |= dib8000_write_word(state, 299, smo_mode); + /* synchronous fread */ + ret |= dib8000_write_word(state, 299 + 1, fifo_threshold); + ret |= dib8000_write_word(state, 1286, outreg); + + return ret; +} + +static int map_addr_to_serpar_number(struct i2c_msg *msg) +{ + if (msg->buf[0] <= 15) + msg->buf[0] -= 1; + else if (msg->buf[0] == 17) + msg->buf[0] = 15; + else if (msg->buf[0] == 16) + msg->buf[0] = 17; + else if (msg->buf[0] == 19) + msg->buf[0] = 16; + else if (msg->buf[0] >= 21 && msg->buf[0] <= 25) + msg->buf[0] -= 3; + else if (msg->buf[0] == 28) + msg->buf[0] = 23; + else if (msg->buf[0] == 99) + msg->buf[0] = 99; + else + return -EINVAL; + return 0; +} + +static int dib8096p_tuner_write_serpar(struct i2c_adapter *i2c_adap, + struct i2c_msg msg[], int num) +{ + struct dib8000_state *state = i2c_get_adapdata(i2c_adap); + u8 n_overflow = 1; + u16 i = 1000; + u16 serpar_num = msg[0].buf[0]; + + while (n_overflow == 1 && i) { + n_overflow = (dib8000_read_word(state, 1984) >> 1) & 0x1; + i--; + if (i == 0) + dprintk("Tuner ITF: write busy (overflow)"); + } + dib8000_write_word(state, 1985, (1 << 6) | (serpar_num & 0x3f)); + dib8000_write_word(state, 1986, (msg[0].buf[1] << 8) | msg[0].buf[2]); + + return num; +} + +static int dib8096p_tuner_read_serpar(struct i2c_adapter *i2c_adap, + struct i2c_msg msg[], int num) +{ + struct dib8000_state *state = i2c_get_adapdata(i2c_adap); + u8 n_overflow = 1, n_empty = 1; + u16 i = 1000; + u16 serpar_num = msg[0].buf[0]; + u16 read_word; + + while (n_overflow == 1 && i) { + n_overflow = (dib8000_read_word(state, 1984) >> 1) & 0x1; + i--; + if (i == 0) + dprintk("TunerITF: read busy (overflow)"); + } + dib8000_write_word(state, 1985, (0<<6) | (serpar_num&0x3f)); + + i = 1000; + while (n_empty == 1 && i) { + n_empty = dib8000_read_word(state, 1984)&0x1; + i--; + if (i == 0) + dprintk("TunerITF: read busy (empty)"); + } + + read_word = dib8000_read_word(state, 1987); + msg[1].buf[0] = (read_word >> 8) & 0xff; + msg[1].buf[1] = (read_word) & 0xff; + + return num; +} + +static int dib8096p_tuner_rw_serpar(struct i2c_adapter *i2c_adap, + struct i2c_msg msg[], int num) +{ + if (map_addr_to_serpar_number(&msg[0]) == 0) { + if (num == 1) /* write */ + return dib8096p_tuner_write_serpar(i2c_adap, msg, 1); + else /* read */ + return dib8096p_tuner_read_serpar(i2c_adap, msg, 2); + } + return num; +} + +static int dib8096p_rw_on_apb(struct i2c_adapter *i2c_adap, + struct i2c_msg msg[], int num, u16 apb_address) +{ + struct dib8000_state *state = i2c_get_adapdata(i2c_adap); + u16 word; + + if (num == 1) { /* write */ + dib8000_write_word(state, apb_address, + ((msg[0].buf[1] << 8) | (msg[0].buf[2]))); + } else { + word = dib8000_read_word(state, apb_address); + msg[1].buf[0] = (word >> 8) & 0xff; + msg[1].buf[1] = (word) & 0xff; + } + return num; +} + +static int dib8096p_tuner_xfer(struct i2c_adapter *i2c_adap, + struct i2c_msg msg[], int num) +{ + struct dib8000_state *state = i2c_get_adapdata(i2c_adap); + u16 apb_address = 0, word; + int i = 0; + + switch (msg[0].buf[0]) { + case 0x12: + apb_address = 1920; + break; + case 0x14: + apb_address = 1921; + break; + case 0x24: + apb_address = 1922; + break; + case 0x1a: + apb_address = 1923; + break; + case 0x22: + apb_address = 1924; + break; + case 0x33: + apb_address = 1926; + break; + case 0x34: + apb_address = 1927; + break; + case 0x35: + apb_address = 1928; + break; + case 0x36: + apb_address = 1929; + break; + case 0x37: + apb_address = 1930; + break; + case 0x38: + apb_address = 1931; + break; + case 0x39: + apb_address = 1932; + break; + case 0x2a: + apb_address = 1935; + break; + case 0x2b: + apb_address = 1936; + break; + case 0x2c: + apb_address = 1937; + break; + case 0x2d: + apb_address = 1938; + break; + case 0x2e: + apb_address = 1939; + break; + case 0x2f: + apb_address = 1940; + break; + case 0x30: + apb_address = 1941; + break; + case 0x31: + apb_address = 1942; + break; + case 0x32: + apb_address = 1943; + break; + case 0x3e: + apb_address = 1944; + break; + case 0x3f: + apb_address = 1945; + break; + case 0x40: + apb_address = 1948; + break; + case 0x25: + apb_address = 936; + break; + case 0x26: + apb_address = 937; + break; + case 0x27: + apb_address = 938; + break; + case 0x28: + apb_address = 939; + break; + case 0x1d: + /* get sad sel request */ + i = ((dib8000_read_word(state, 921) >> 12)&0x3); + word = dib8000_read_word(state, 924+i); + msg[1].buf[0] = (word >> 8) & 0xff; + msg[1].buf[1] = (word) & 0xff; + return num; + case 0x1f: + if (num == 1) { /* write */ + word = (u16) ((msg[0].buf[1] << 8) | + msg[0].buf[2]); + /* in the VGAMODE Sel are located on bit 0/1 */ + word &= 0x3; + word = (dib8000_read_word(state, 921) & + ~(3<<12)) | (word<<12); + /* Set the proper input */ + dib8000_write_word(state, 921, word); + return num; + } + } + + if (apb_address != 0) /* R/W acces via APB */ + return dib8096p_rw_on_apb(i2c_adap, msg, num, apb_address); + else /* R/W access via SERPAR */ + return dib8096p_tuner_rw_serpar(i2c_adap, msg, num); + + return 0; +} + +static u32 dib8096p_i2c_func(struct i2c_adapter *adapter) +{ + return I2C_FUNC_I2C; +} + +static struct i2c_algorithm dib8096p_tuner_xfer_algo = { + .master_xfer = dib8096p_tuner_xfer, + .functionality = dib8096p_i2c_func, +}; + +struct i2c_adapter *dib8096p_get_i2c_tuner(struct dvb_frontend *fe) +{ + struct dib8000_state *st = fe->demodulator_priv; + return &st->dib8096p_tuner_adap; +} +EXPORT_SYMBOL(dib8096p_get_i2c_tuner); + +int dib8096p_tuner_sleep(struct dvb_frontend *fe, int onoff) +{ + struct dib8000_state *state = fe->demodulator_priv; + u16 en_cur_state; + + dprintk("sleep dib8096p: %d", onoff); + + en_cur_state = dib8000_read_word(state, 1922); + + /* LNAs and MIX are ON and therefore it is a valid configuration */ + if (en_cur_state > 0xff) + state->tuner_enable = en_cur_state ; + + if (onoff) + en_cur_state &= 0x00ff; + else { + if (state->tuner_enable != 0) + en_cur_state = state->tuner_enable; + } + + dib8000_write_word(state, 1922, en_cur_state); + + return 0; +} +EXPORT_SYMBOL(dib8096p_tuner_sleep); + static const s32 lut_1000ln_mant[] = { 908, 7003, 7090, 7170, 7244, 7313, 7377, 7438, 7495, 7549, 7600 @@ -1051,6 +1815,26 @@ s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode) } EXPORT_SYMBOL(dib8000_get_adc_power); +int dib8090p_get_dc_power(struct dvb_frontend *fe, u8 IQ) +{ + struct dib8000_state *state = fe->demodulator_priv; + int val = 0; + + switch (IQ) { + case 1: + val = dib8000_read_word(state, 403); + break; + case 0: + val = dib8000_read_word(state, 404); + break; + } + if (val & 0x200) + val -= 1024; + + return val; +} +EXPORT_SYMBOL(dib8090p_get_dc_power); + static void dib8000_update_timf(struct dib8000_state *state) { u32 timf = state->timf = dib8000_read32(state, 435); @@ -1060,6 +1844,26 @@ static void dib8000_update_timf(struct dib8000_state *state) dprintk("Updated timing frequency: %d (default: %d)", state->timf, state->timf_default); } +u32 dib8000_ctrl_timf(struct dvb_frontend *fe, uint8_t op, uint32_t timf) +{ + struct dib8000_state *state = fe->demodulator_priv; + + switch (op) { + case DEMOD_TIMF_SET: + state->timf = timf; + break; + case DEMOD_TIMF_UPDATE: + dib8000_update_timf(state); + break; + case DEMOD_TIMF_GET: + break; + } + dib8000_set_bandwidth(state->fe[0], 6000); + + return state->timf; +} +EXPORT_SYMBOL(dib8000_ctrl_timf); + static const u16 adc_target_16dB[11] = { (1 << 13) - 825 - 117, (1 << 13) - 837 - 117, @@ -1086,6 +1890,9 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear u16 init_prbs = 0xfff; u16 ana_gain = 0; + if (state->revision == 0x8090) + dib8000_init_sdram(state); + if (state->ber_monitored_layer != LAYER_ALL) dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & 0x60) | state->ber_monitored_layer); else @@ -1418,7 +2225,10 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear dprintk("nbseg_diff = %X (%d)", seg_diff_mask, seg_diff_mask); state->differential_constellation = (seg_diff_mask != 0); - dib8000_set_diversity_in(state->fe[0], state->diversity_onoff); + if (state->revision != 0x8090) + dib8000_set_diversity_in(state->fe[0], state->diversity_onoff); + else + dib8096p_set_diversity_in(state->fe[0], state->diversity_onoff); if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) { if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 1) @@ -1870,7 +2680,7 @@ static int dib8000_tune(struct dvb_frontend *fe) { struct dib8000_state *state = fe->demodulator_priv; int ret = 0; - u16 value, mode = fft_to_mode(state); + u16 lock, value, mode = fft_to_mode(state); // we are already tuned - just resuming from suspend if (state == NULL) @@ -1924,7 +2734,11 @@ static int dib8000_tune(struct dvb_frontend *fe) } // we achieved a coff_cpil_lock - it's time to update the timf - if ((dib8000_read_word(state, 568) >> 11) & 0x1) + if (state->revision != 0x8090) + lock = dib8000_read_word(state, 568); + else + lock = dib8000_read_word(state, 570); + if ((lock >> 11) & 0x1) dib8000_update_timf(state); //now that tune is finished, lock0 should lock on fec_mpeg to output this lock on MP_LOCK. It's changed in autosearch start @@ -1946,11 +2760,14 @@ static int dib8000_wakeup(struct dvb_frontend *fe) u8 index_frontend; int ret; - dib8000_set_power_mode(state, DIB8000M_POWER_ALL); + dib8000_set_power_mode(state, DIB8000_POWER_ALL); dib8000_set_adc_state(state, DIBX000_ADC_ON); if (dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0) dprintk("could not start Slow ADC"); + if (state->revision != 0x8090) + dib8000_sad_calib(state); + for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { ret = state->fe[index_frontend]->ops.init(state->fe[index_frontend]); if (ret < 0) @@ -1972,8 +2789,9 @@ static int dib8000_sleep(struct dvb_frontend *fe) return ret; } - dib8000_set_output_mode(fe, OUTMODE_HIGH_Z); - dib8000_set_power_mode(state, DIB8000M_POWER_INTERFACE_ONLY); + if (state->revision != 0x8090) + dib8000_set_output_mode(fe, OUTMODE_HIGH_Z); + dib8000_set_power_mode(state, DIB8000_POWER_INTERFACE_ONLY); return dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF) | dib8000_set_adc_state(state, DIBX000_ADC_OFF); } @@ -1992,7 +2810,7 @@ int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tun } EXPORT_SYMBOL(dib8000_set_tune_state); -static int dib8000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) +static int dib8000_get_frontend(struct dvb_frontend *fe) { struct dib8000_state *state = fe->demodulator_priv; u16 i, val = 0; @@ -2006,7 +2824,7 @@ static int dib8000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_par if (stat&FE_HAS_SYNC) { dprintk("TMCC lock on the slave%i", index_frontend); /* synchronize the cache with the other frontends */ - state->fe[index_frontend]->ops.get_frontend(state->fe[index_frontend], fep); + state->fe[index_frontend]->ops.get_frontend(state->fe[index_frontend]); for (sub_index_frontend = 0; (sub_index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[sub_index_frontend] != NULL); sub_index_frontend++) { if (sub_index_frontend != index_frontend) { state->fe[sub_index_frontend]->dtv_property_cache.isdbt_sb_mode = state->fe[index_frontend]->dtv_property_cache.isdbt_sb_mode; @@ -2028,7 +2846,10 @@ static int dib8000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_par fe->dtv_property_cache.isdbt_sb_mode = dib8000_read_word(state, 508) & 0x1; - val = dib8000_read_word(state, 570); + if (state->revision == 0x8090) + val = dib8000_read_word(state, 572); + else + val = dib8000_read_word(state, 570); fe->dtv_property_cache.inversion = (val & 0x40) >> 6; switch ((val & 0x30) >> 4) { case 1: @@ -2135,7 +2956,7 @@ static int dib8000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_par return 0; } -static int dib8000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) +static int dib8000_set_frontend(struct dvb_frontend *fe) { struct dib8000_state *state = fe->demodulator_priv; u8 nbr_pending, exit_condition, index_frontend; @@ -2158,9 +2979,14 @@ static int dib8000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par state->fe[index_frontend]->dtv_property_cache.delivery_system = SYS_ISDBT; memcpy(&state->fe[index_frontend]->dtv_property_cache, &fe->dtv_property_cache, sizeof(struct dtv_frontend_properties)); - dib8000_set_output_mode(state->fe[index_frontend], OUTMODE_HIGH_Z); + if (state->revision != 0x8090) + dib8000_set_output_mode(state->fe[index_frontend], + OUTMODE_HIGH_Z); + else + dib8096p_set_output_mode(state->fe[index_frontend], + OUTMODE_HIGH_Z); if (state->fe[index_frontend]->ops.tuner_ops.set_params) - state->fe[index_frontend]->ops.tuner_ops.set_params(state->fe[index_frontend], fep); + state->fe[index_frontend]->ops.tuner_ops.set_params(state->fe[index_frontend]); dib8000_set_tune_state(state->fe[index_frontend], CT_AGC_START); } @@ -2215,7 +3041,7 @@ static int dib8000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par ((state->fe[0]->dtv_property_cache.layer[1].segment_count == 0) || ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (2 << 0)) == 0)) && ((state->fe[0]->dtv_property_cache.layer[2].segment_count == 0) || ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (3 << 0)) == 0)))) { - int i = 80000; + int i = 100; u8 found = 0; u8 tune_failed = 0; @@ -2243,6 +3069,7 @@ static int dib8000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par default: dprintk("unhandled autosearch result"); case 1: + tune_failed |= (1 << index_frontend); dprintk("autosearch failed for the frontend%i", index_frontend); break; } @@ -2261,21 +3088,44 @@ static int dib8000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par dprintk("tune success on frontend%i", index_frontend_success); - dib8000_get_frontend(fe, fep); + dib8000_get_frontend(fe); } for (index_frontend = 0, ret = 0; (ret >= 0) && (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) ret = dib8000_tune(state->fe[index_frontend]); /* set output mode and diversity input */ - dib8000_set_output_mode(state->fe[0], state->cfg.output_mode); - for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { - dib8000_set_output_mode(state->fe[index_frontend], OUTMODE_DIVERSITY); - dib8000_set_diversity_in(state->fe[index_frontend-1], 1); - } + if (state->revision != 0x8090) { + dib8000_set_output_mode(state->fe[0], state->cfg.output_mode); + for (index_frontend = 1; + (index_frontend < MAX_NUMBER_OF_FRONTENDS) && + (state->fe[index_frontend] != NULL); + index_frontend++) { + dib8000_set_output_mode(state->fe[index_frontend], + OUTMODE_DIVERSITY); + dib8000_set_diversity_in(state->fe[index_frontend-1], 1); + } - /* turn off the diversity of the last chip */ - dib8000_set_diversity_in(state->fe[index_frontend-1], 0); + /* turn off the diversity of the last chip */ + dib8000_set_diversity_in(state->fe[index_frontend-1], 0); + } else { + dib8096p_set_output_mode(state->fe[0], state->cfg.output_mode); + if (state->cfg.enMpegOutput == 0) { + dib8096p_setDibTxMux(state, MPEG_ON_DIBTX); + dib8096p_setHostBusMux(state, DIBTX_ON_HOSTBUS); + } + for (index_frontend = 1; + (index_frontend < MAX_NUMBER_OF_FRONTENDS) && + (state->fe[index_frontend] != NULL); + index_frontend++) { + dib8096p_set_output_mode(state->fe[index_frontend], + OUTMODE_DIVERSITY); + dib8096p_set_diversity_in(state->fe[index_frontend-1], 1); + } + + /* turn off the diversity of the last chip */ + dib8096p_set_diversity_in(state->fe[index_frontend-1], 0); + } return ret; } @@ -2284,15 +3134,22 @@ static u16 dib8000_read_lock(struct dvb_frontend *fe) { struct dib8000_state *state = fe->demodulator_priv; + if (state->revision == 0x8090) + return dib8000_read_word(state, 570); return dib8000_read_word(state, 568); } static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat) { struct dib8000_state *state = fe->demodulator_priv; - u16 lock_slave = 0, lock = dib8000_read_word(state, 568); + u16 lock_slave = 0, lock; u8 index_frontend; + if (state->revision == 0x8090) + lock = dib8000_read_word(state, 570); + else + lock = dib8000_read_word(state, 568); + for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) lock_slave |= dib8000_read_lock(state->fe[index_frontend]); @@ -2330,14 +3187,26 @@ static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat) static int dib8000_read_ber(struct dvb_frontend *fe, u32 * ber) { struct dib8000_state *state = fe->demodulator_priv; - *ber = (dib8000_read_word(state, 560) << 16) | dib8000_read_word(state, 561); // 13 segments + + /* 13 segments */ + if (state->revision == 0x8090) + *ber = (dib8000_read_word(state, 562) << 16) | + dib8000_read_word(state, 563); + else + *ber = (dib8000_read_word(state, 560) << 16) | + dib8000_read_word(state, 561); return 0; } static int dib8000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc) { struct dib8000_state *state = fe->demodulator_priv; - *unc = dib8000_read_word(state, 565); // packet error on 13 seg + + /* packet error on 13 seg */ + if (state->revision == 0x8090) + *unc = dib8000_read_word(state, 567); + else + *unc = dib8000_read_word(state, 565); return 0; } @@ -2370,14 +3239,20 @@ static u32 dib8000_get_snr(struct dvb_frontend *fe) u32 n, s, exp; u16 val; - val = dib8000_read_word(state, 542); + if (state->revision != 0x8090) + val = dib8000_read_word(state, 542); + else + val = dib8000_read_word(state, 544); n = (val >> 6) & 0xff; exp = (val & 0x3f); if ((exp & 0x20) != 0) exp -= 0x40; n <<= exp+16; - val = dib8000_read_word(state, 543); + if (state->revision != 0x8090) + val = dib8000_read_word(state, 543); + else + val = dib8000_read_word(state, 545); s = (val >> 6) & 0xff; exp = (val & 0x3f); if ((exp & 0x20) != 0) @@ -2401,7 +3276,7 @@ static int dib8000_read_snr(struct dvb_frontend *fe, u16 * snr) for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) snr_master += dib8000_get_snr(state->fe[index_frontend]); - if (snr_master != 0) { + if ((snr_master >> 16) != 0) { snr_master = 10*intlog10(snr_master>>16); *snr = snr_master / ((1 << 24) / 10); } @@ -2458,7 +3333,8 @@ struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int sla EXPORT_SYMBOL(dib8000_get_slave_frontend); -int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr) +int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, + u8 default_addr, u8 first_addr, u8 is_dib8096p) { int k = 0, ret = 0; u8 new_addr = 0; @@ -2488,9 +3364,12 @@ int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 defau new_addr = first_addr + (k << 1); client.addr = new_addr; - dib8000_i2c_write16(&client, 1287, 0x0003); /* sram lead in, rdy */ - if (dib8000_identify(&client) == 0) { + if (!is_dib8096p) dib8000_i2c_write16(&client, 1287, 0x0003); /* sram lead in, rdy */ + if (dib8000_identify(&client) == 0) { + /* sram lead in, rdy */ + if (!is_dib8096p) + dib8000_i2c_write16(&client, 1287, 0x0003); client.addr = default_addr; if (dib8000_identify(&client) == 0) { dprintk("#%d: not identified", k); @@ -2549,6 +3428,7 @@ static void dib8000_release(struct dvb_frontend *fe) dvb_frontend_detach(st->fe[index_frontend]); dibx000_exit_i2c_master(&st->i2c_master); + i2c_del_adapter(&st->dib8096p_tuner_adap); kfree(st->fe[0]); kfree(st); } @@ -2581,9 +3461,9 @@ int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff) EXPORT_SYMBOL(dib8000_pid_filter); static const struct dvb_frontend_ops dib8000_ops = { + .delsys = { SYS_ISDBT }, .info = { .name = "DiBcom 8000 ISDB-T", - .type = FE_OFDM, .frequency_min = 44250000, .frequency_max = 867250000, .frequency_stepsize = 62500, @@ -2651,6 +3531,15 @@ struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, s dibx000_init_i2c_master(&state->i2c_master, DIB8000, state->i2c.adap, state->i2c.addr); + /* init 8096p tuner adapter */ + strncpy(state->dib8096p_tuner_adap.name, "DiB8096P tuner interface", + sizeof(state->dib8096p_tuner_adap.name)); + state->dib8096p_tuner_adap.algo = &dib8096p_tuner_xfer_algo; + state->dib8096p_tuner_adap.algo_data = NULL; + state->dib8096p_tuner_adap.dev.parent = state->i2c.adap->dev.parent; + i2c_set_adapdata(&state->dib8096p_tuner_adap, state); + i2c_add_adapter(&state->dib8096p_tuner_adap); + dib8000_reset(fe); dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & ~0x60) | (3 << 5)); /* ber_rs_len = 3 */ diff --git a/drivers/media/dvb/frontends/dib8000.h b/drivers/media/dvb/frontends/dib8000.h index 617f9eba3a09..39591bb172c1 100644 --- a/drivers/media/dvb/frontends/dib8000.h +++ b/drivers/media/dvb/frontends/dib8000.h @@ -32,6 +32,7 @@ struct dib8000_config { u8 div_cfg; u8 output_mode; u8 refclksel; + u8 enMpegOutput:1; }; #define DEFAULT_DIB8000_I2C_ADDRESS 18 @@ -40,7 +41,8 @@ struct dib8000_config { extern struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg); extern struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int); -extern int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr); +extern int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, + u8 default_addr, u8 first_addr, u8 is_dib8096p); extern int dib8000_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val); extern int dib8000_set_wbd_ref(struct dvb_frontend *, u16 value); @@ -50,6 +52,13 @@ extern int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_st extern enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe); extern void dib8000_pwm_agc_reset(struct dvb_frontend *fe); extern s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode); +extern struct i2c_adapter *dib8096p_get_i2c_tuner(struct dvb_frontend *fe); +extern int dib8096p_tuner_sleep(struct dvb_frontend *fe, int onoff); +extern int dib8090p_get_dc_power(struct dvb_frontend *fe, u8 IQ); +extern u32 dib8000_ctrl_timf(struct dvb_frontend *fe, + uint8_t op, uint32_t timf); +extern int dib8000_update_pll(struct dvb_frontend *fe, + struct dibx000_bandwidth_config *pll); extern int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave); extern int dib8000_remove_slave_frontend(struct dvb_frontend *fe); extern struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index); @@ -66,7 +75,9 @@ static inline struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *fe return NULL; } -static inline int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr) +static inline int dib8000_i2c_enumeration(struct i2c_adapter *host, + int no_of_demods, u8 default_addr, u8 first_addr, + u8 is_dib8096p) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return -ENODEV; @@ -109,11 +120,38 @@ static inline void dib8000_pwm_agc_reset(struct dvb_frontend *fe) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); } +static inline struct i2c_adapter *dib8096p_get_i2c_tuner(struct dvb_frontend *fe) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} +static inline int dib8096p_tuner_sleep(struct dvb_frontend *fe, int onoff) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return 0; +} static inline s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return 0; } +static inline int dib8090p_get_dc_power(struct dvb_frontend *fe, u8 IQ) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return 0; +} +static inline u32 dib8000_ctrl_timf(struct dvb_frontend *fe, + uint8_t op, uint32_t timf) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return 0; +} +static inline int dib8000_update_pll(struct dvb_frontend *fe, + struct dibx000_bandwidth_config *pll) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return -ENODEV; +} static inline int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); diff --git a/drivers/media/dvb/frontends/dib9000.c b/drivers/media/dvb/frontends/dib9000.c index 660f80661ed4..863ef3cfab9f 100644 --- a/drivers/media/dvb/frontends/dib9000.c +++ b/drivers/media/dvb/frontends/dib9000.c @@ -1136,7 +1136,7 @@ static int dib9000_fw_init(struct dib9000_state *state) return 0; } -static void dib9000_fw_set_channel_head(struct dib9000_state *state, struct dvb_frontend_parameters *ch) +static void dib9000_fw_set_channel_head(struct dib9000_state *state) { u8 b[9]; u32 freq = state->fe[0]->dtv_property_cache.frequency / 1000; @@ -1157,7 +1157,7 @@ static void dib9000_fw_set_channel_head(struct dib9000_state *state, struct dvb_ dib9000_risc_mem_write(state, FE_MM_W_CHANNEL_HEAD, b); } -static int dib9000_fw_get_channel(struct dvb_frontend *fe, struct dvb_frontend_parameters *channel) +static int dib9000_fw_get_channel(struct dvb_frontend *fe) { struct dib9000_state *state = fe->demodulator_priv; struct dibDVBTChannel { @@ -1309,7 +1309,7 @@ error: return ret; } -static int dib9000_fw_set_channel_union(struct dvb_frontend *fe, struct dvb_frontend_parameters *channel) +static int dib9000_fw_set_channel_union(struct dvb_frontend *fe) { struct dib9000_state *state = fe->demodulator_priv; struct dibDVBTChannel { @@ -1454,7 +1454,7 @@ static int dib9000_fw_set_channel_union(struct dvb_frontend *fe, struct dvb_fron return 0; } -static int dib9000_fw_tune(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch) +static int dib9000_fw_tune(struct dvb_frontend *fe) { struct dib9000_state *state = fe->demodulator_priv; int ret = 10, search = state->channel_status.status == CHANNEL_STATUS_PARAMETERS_UNKNOWN; @@ -1462,7 +1462,7 @@ static int dib9000_fw_tune(struct dvb_frontend *fe, struct dvb_frontend_paramete switch (state->tune_state) { case CT_DEMOD_START: - dib9000_fw_set_channel_head(state, ch); + dib9000_fw_set_channel_head(state); /* write the channel context - a channel is initialized to 0, so it is OK */ dib9000_risc_mem_write(state, FE_MM_W_CHANNEL_CONTEXT, (u8 *) fe_info); @@ -1471,7 +1471,7 @@ static int dib9000_fw_tune(struct dvb_frontend *fe, struct dvb_frontend_paramete if (search) dib9000_mbx_send(state, OUT_MSG_FE_CHANNEL_SEARCH, NULL, 0); else { - dib9000_fw_set_channel_union(fe, ch); + dib9000_fw_set_channel_union(fe); dib9000_mbx_send(state, OUT_MSG_FE_CHANNEL_TUNE, NULL, 0); } state->tune_state = CT_DEMOD_STEP_1; @@ -1867,7 +1867,7 @@ static int dib9000_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_fron return 0; } -static int dib9000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) +static int dib9000_get_frontend(struct dvb_frontend *fe) { struct dib9000_state *state = fe->demodulator_priv; u8 index_frontend, sub_index_frontend; @@ -1883,7 +1883,7 @@ static int dib9000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_par dprintk("TPS lock on the slave%i", index_frontend); /* synchronize the cache with the other frontends */ - state->fe[index_frontend]->ops.get_frontend(state->fe[index_frontend], fep); + state->fe[index_frontend]->ops.get_frontend(state->fe[index_frontend]); for (sub_index_frontend = 0; (sub_index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[sub_index_frontend] != NULL); sub_index_frontend++) { if (sub_index_frontend != index_frontend) { @@ -1911,7 +1911,7 @@ static int dib9000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_par } /* get the channel from master chip */ - ret = dib9000_fw_get_channel(fe, fep); + ret = dib9000_fw_get_channel(fe); if (ret != 0) goto return_value; @@ -1958,7 +1958,7 @@ static int dib9000_set_channel_status(struct dvb_frontend *fe, struct dvb_fronte return 0; } -static int dib9000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) +static int dib9000_set_frontend(struct dvb_frontend *fe) { struct dib9000_state *state = fe->demodulator_priv; int sleep_time, sleep_time_slave; @@ -1983,8 +1983,10 @@ static int dib9000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par fe->dtv_property_cache.delivery_system = SYS_DVBT; /* set the master status */ - if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO || - fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO || fep->u.ofdm.constellation == QAM_AUTO || fep->u.ofdm.code_rate_HP == FEC_AUTO) { + if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO || + state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO || + state->fe[0]->dtv_property_cache.modulation == QAM_AUTO || + state->fe[0]->dtv_property_cache.code_rate_HP == FEC_AUTO) { /* no channel specified, autosearch the channel */ state->channel_status.status = CHANNEL_STATUS_PARAMETERS_UNKNOWN; } else @@ -2008,9 +2010,9 @@ static int dib9000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par exit_condition = 0; /* 0: tune pending; 1: tune failed; 2:tune success */ index_frontend_success = 0; do { - sleep_time = dib9000_fw_tune(state->fe[0], NULL); + sleep_time = dib9000_fw_tune(state->fe[0]); for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { - sleep_time_slave = dib9000_fw_tune(state->fe[index_frontend], NULL); + sleep_time_slave = dib9000_fw_tune(state->fe[index_frontend]); if (sleep_time == FE_CALLBACK_TIME_NEVER) sleep_time = sleep_time_slave; else if ((sleep_time_slave != FE_CALLBACK_TIME_NEVER) && (sleep_time_slave > sleep_time)) @@ -2052,7 +2054,7 @@ static int dib9000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par /* synchronize all the channel cache */ state->get_frontend_internal = 1; - dib9000_get_frontend(state->fe[0], fep); + dib9000_get_frontend(state->fe[0]); state->get_frontend_internal = 0; /* retune the other frontends with the found channel */ @@ -2068,7 +2070,7 @@ static int dib9000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par sleep_time = FE_CALLBACK_TIME_NEVER; for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { if (index_frontend != index_frontend_success) { - sleep_time_slave = dib9000_fw_tune(state->fe[index_frontend], NULL); + sleep_time_slave = dib9000_fw_tune(state->fe[index_frontend]); if (sleep_time == FE_CALLBACK_TIME_NEVER) sleep_time = sleep_time_slave; else if ((sleep_time_slave != FE_CALLBACK_TIME_NEVER) && (sleep_time_slave > sleep_time)) @@ -2495,9 +2497,9 @@ error: EXPORT_SYMBOL(dib9000_attach); static struct dvb_frontend_ops dib9000_ops = { + .delsys = { SYS_DVBT }, .info = { .name = "DiBcom 9000", - .type = FE_OFDM, .frequency_min = 44250000, .frequency_max = 867250000, .frequency_stepsize = 62500, diff --git a/drivers/media/dvb/frontends/dibx000_common.h b/drivers/media/dvb/frontends/dibx000_common.h index 5e011474be43..5f484881d7b1 100644 --- a/drivers/media/dvb/frontends/dibx000_common.h +++ b/drivers/media/dvb/frontends/dibx000_common.h @@ -146,14 +146,8 @@ enum dibx000_adc_states { DIBX000_VBG_DISABLE, }; -#define BANDWIDTH_TO_KHZ(v) ((v) == BANDWIDTH_8_MHZ ? 8000 : \ - (v) == BANDWIDTH_7_MHZ ? 7000 : \ - (v) == BANDWIDTH_6_MHZ ? 6000 : 8000) - -#define BANDWIDTH_TO_INDEX(v) ( \ - (v) == 8000 ? BANDWIDTH_8_MHZ : \ - (v) == 7000 ? BANDWIDTH_7_MHZ : \ - (v) == 6000 ? BANDWIDTH_6_MHZ : BANDWIDTH_8_MHZ ) +#define BANDWIDTH_TO_KHZ(v) ((v) / 1000) +#define BANDWIDTH_TO_HZ(v) ((v) * 1000) /* Chip output mode. */ #define OUTMODE_HIGH_Z 0 @@ -276,4 +270,11 @@ struct dibSubbandSelection { #define DEMOD_TIMF_GET 0x01 #define DEMOD_TIMF_UPDATE 0x02 +#define MPEG_ON_DIBTX 1 +#define DIV_ON_DIBTX 2 +#define ADC_ON_DIBTX 3 +#define DEMOUT_ON_HOSTBUS 4 +#define DIBTX_ON_HOSTBUS 5 +#define MPEG_ON_HOSTBUS 6 + #endif diff --git a/drivers/media/dvb/frontends/drxd.h b/drivers/media/dvb/frontends/drxd.h index 7113535844f2..34398738f9bc 100644 --- a/drivers/media/dvb/frontends/drxd.h +++ b/drivers/media/dvb/frontends/drxd.h @@ -48,8 +48,6 @@ struct drxd_config { u8 disable_i2c_gate_ctrl; u32 IF; - int (*pll_set) (void *priv, void *priv_params, - u8 pll_addr, u8 demoda_addr, s32 *off); s16(*osc_deviation) (void *priv, s16 dev, int flag); }; diff --git a/drivers/media/dvb/frontends/drxd_hard.c b/drivers/media/dvb/frontends/drxd_hard.c index 88e46f4cdbb2..7bf39cda83c5 100644 --- a/drivers/media/dvb/frontends/drxd_hard.c +++ b/drivers/media/dvb/frontends/drxd_hard.c @@ -120,7 +120,7 @@ enum EIFFilter { struct drxd_state { struct dvb_frontend frontend; struct dvb_frontend_ops ops; - struct dvb_frontend_parameters param; + struct dtv_frontend_properties props; const struct firmware *fw; struct device *dev; @@ -914,14 +914,13 @@ static int load_firmware(struct drxd_state *state, const char *fw_name) return -EIO; } - state->microcode = kmalloc(fw->size, GFP_KERNEL); + state->microcode = kmemdup(fw->data, fw->size, GFP_KERNEL); if (state->microcode == NULL) { release_firmware(fw); printk(KERN_ERR "drxd: firmware load failure: no memory\n"); return -ENOMEM; } - memcpy(state->microcode, fw->data, fw->size); state->microcode_length = fw->size; release_firmware(fw); return 0; @@ -1622,14 +1621,14 @@ static int CorrectSysClockDeviation(struct drxd_state *state) break; } - switch (state->param.u.ofdm.bandwidth) { - case BANDWIDTH_8_MHZ: + switch (state->props.bandwidth_hz) { + case 8000000: bandwidth = DRXD_BANDWIDTH_8MHZ_IN_HZ; break; - case BANDWIDTH_7_MHZ: + case 7000000: bandwidth = DRXD_BANDWIDTH_7MHZ_IN_HZ; break; - case BANDWIDTH_6_MHZ: + case 6000000: bandwidth = DRXD_BANDWIDTH_6MHZ_IN_HZ; break; default: @@ -1804,7 +1803,7 @@ static int StartDiversity(struct drxd_state *state) status = WriteTable(state, state->m_StartDiversityEnd); if (status < 0) break; - if (state->param.u.ofdm.bandwidth == BANDWIDTH_8_MHZ) { + if (state->props.bandwidth_hz == 8000000) { status = WriteTable(state, state->m_DiversityDelay8MHZ); if (status < 0) break; @@ -1906,7 +1905,7 @@ static int SetCfgNoiseCalibration(struct drxd_state *state, static int DRX_Start(struct drxd_state *state, s32 off) { - struct dvb_ofdm_parameters *p = &state->param.u.ofdm; + struct dtv_frontend_properties *p = &state->props; int status; u16 transmissionParams = 0; @@ -1971,7 +1970,7 @@ static int DRX_Start(struct drxd_state *state, s32 off) if (status < 0) break; - mirrorFreqSpect = (state->param.inversion == INVERSION_ON); + mirrorFreqSpect = (state->props.inversion == INVERSION_ON); switch (p->transmission_mode) { default: /* Not set, detect it automatically */ @@ -2021,7 +2020,7 @@ static int DRX_Start(struct drxd_state *state, s32 off) break; } - switch (p->hierarchy_information) { + switch (p->hierarchy) { case HIERARCHY_1: transmissionParams |= SC_RA_RAM_OP_PARAM_HIER_A1; if (state->type_A) { @@ -2147,7 +2146,7 @@ static int DRX_Start(struct drxd_state *state, s32 off) if (status < 0) break; - switch (p->constellation) { + switch (p->modulation) { default: operationMode |= SC_RA_RAM_OP_AUTO_CONST__M; /* fall through , try first guess @@ -2331,9 +2330,11 @@ static int DRX_Start(struct drxd_state *state, s32 off) by SC for fix for some 8K,1/8 guard but is restored by InitEC and ResetEC functions */ - switch (p->bandwidth) { - case BANDWIDTH_AUTO: - case BANDWIDTH_8_MHZ: + switch (p->bandwidth_hz) { + case 0: + p->bandwidth_hz = 8000000; + /* fall through */ + case 8000000: /* (64/7)*(8/8)*1000000 */ bandwidth = DRXD_BANDWIDTH_8MHZ_IN_HZ; @@ -2341,14 +2342,14 @@ static int DRX_Start(struct drxd_state *state, s32 off) status = Write16(state, FE_AG_REG_IND_DEL__A, 50, 0x0000); break; - case BANDWIDTH_7_MHZ: + case 7000000: /* (64/7)*(7/8)*1000000 */ bandwidth = DRXD_BANDWIDTH_7MHZ_IN_HZ; bandwidthParam = 0x4807; /*binary:0100 1000 0000 0111 */ status = Write16(state, FE_AG_REG_IND_DEL__A, 59, 0x0000); break; - case BANDWIDTH_6_MHZ: + case 6000000: /* (64/7)*(6/8)*1000000 */ bandwidth = DRXD_BANDWIDTH_6MHZ_IN_HZ; bandwidthParam = 0x0F07; /*binary: 0000 1111 0000 0111 */ @@ -2887,41 +2888,26 @@ static int drxd_sleep(struct dvb_frontend *fe) return 0; } -static int drxd_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *param) -{ - return 0; -} - static int drxd_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) { return drxd_config_i2c(fe, enable); } -static int drxd_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *param) +static int drxd_set_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct drxd_state *state = fe->demodulator_priv; s32 off = 0; - state->param = *param; + state->props = *p; DRX_Stop(state); if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, param); + fe->ops.tuner_ops.set_params(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); } - /* FIXME: move PLL drivers */ - if (state->config.pll_set && - state->config.pll_set(state->priv, param, - state->config.pll_address, - state->config.demoda_address, &off) < 0) { - printk(KERN_ERR "Error in pll_set\n"); - return -1; - } - msleep(200); return DRX_Start(state, off); @@ -2935,10 +2921,9 @@ static void drxd_release(struct dvb_frontend *fe) } static struct dvb_frontend_ops drxd_ops = { - + .delsys = { SYS_DVBT}, .info = { .name = "Micronas DRXD DVB-T", - .type = FE_OFDM, .frequency_min = 47125000, .frequency_max = 855250000, .frequency_stepsize = 166667, @@ -2958,7 +2943,6 @@ static struct dvb_frontend_ops drxd_ops = { .i2c_gate_ctrl = drxd_i2c_gate_ctrl, .set_frontend = drxd_set_frontend, - .get_frontend = drxd_get_frontend, .get_tune_settings = drxd_get_tune_settings, .read_status = drxd_read_status, diff --git a/drivers/media/dvb/frontends/drxk.h b/drivers/media/dvb/frontends/drxk.h index 58baf419560c..020981844a86 100644 --- a/drivers/media/dvb/frontends/drxk.h +++ b/drivers/media/dvb/frontends/drxk.h @@ -8,6 +8,8 @@ * struct drxk_config - Configure the initial parameters for DRX-K * * adr: I2C Address of the DRX-K + * parallel_ts: true means that the device uses parallel TS, + * Serial otherwise. * single_master: Device is on the single master mode * no_i2c_bridge: Don't switch the I2C bridge to talk with tuner * antenna_gpio: GPIO bit used to control the antenna @@ -22,22 +24,23 @@ struct drxk_config { u8 adr; bool single_master; bool no_i2c_bridge; + bool parallel_ts; bool antenna_dvbt; u16 antenna_gpio; + int chunk_size; + const char *microcode_name; }; #if defined(CONFIG_DVB_DRXK) || (defined(CONFIG_DVB_DRXK_MODULE) \ && defined(MODULE)) extern struct dvb_frontend *drxk_attach(const struct drxk_config *config, - struct i2c_adapter *i2c, - struct dvb_frontend **fe_t); + struct i2c_adapter *i2c); #else static inline struct dvb_frontend *drxk_attach(const struct drxk_config *config, - struct i2c_adapter *i2c, - struct dvb_frontend **fe_t) + struct i2c_adapter *i2c) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; diff --git a/drivers/media/dvb/frontends/drxk_hard.c b/drivers/media/dvb/frontends/drxk_hard.c index f6431ef827dc..6980ed7b8786 100644 --- a/drivers/media/dvb/frontends/drxk_hard.c +++ b/drivers/media/dvb/frontends/drxk_hard.c @@ -368,10 +368,10 @@ static int i2c_read(struct i2c_adapter *adap, } if (debug > 2) { int i; - dprintk(2, ": read from "); + dprintk(2, ": read from"); for (i = 0; i < len; i++) printk(KERN_CONT " %02x", msg[i]); - printk(KERN_CONT "Value = "); + printk(KERN_CONT ", value = "); for (i = 0; i < alen; i++) printk(KERN_CONT " %02x", answ[i]); printk(KERN_CONT "\n"); @@ -660,7 +660,6 @@ static int init_state(struct drxk_state *state) /* io_pad_cfg_mode output mode is drive always */ /* io_pad_cfg_drive is set to power 2 (23 mA) */ u32 ulGPIOCfg = 0x0113; - u32 ulSerialMode = 1; u32 ulInvertTSClock = 0; u32 ulTSDataStrength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH; u32 ulTSClockkStrength = DRXK_MPEG_OUTPUT_CLK_DRIVE_STRENGTH; @@ -681,7 +680,8 @@ static int init_state(struct drxk_state *state) state->m_hasOOB = false; state->m_hasAudio = false; - state->m_ChunkSize = 124; + if (!state->m_ChunkSize) + state->m_ChunkSize = 124; state->m_oscClockFreq = 0; state->m_smartAntInverted = false; @@ -810,8 +810,6 @@ static int init_state(struct drxk_state *state) /* MPEG output configuration */ state->m_enableMPEGOutput = true; /* If TRUE; enable MPEG ouput */ state->m_insertRSByte = false; /* If TRUE; insert RS byte */ - state->m_enableParallel = true; /* If TRUE; - parallel out otherwise serial */ state->m_invertDATA = false; /* If TRUE; invert DATA signals */ state->m_invertERR = false; /* If TRUE; invert ERR signal */ state->m_invertSTR = false; /* If TRUE; invert STR signals */ @@ -856,8 +854,6 @@ static int init_state(struct drxk_state *state) state->m_bPowerDown = false; state->m_currentPowerMode = DRX_POWER_DOWN; - state->m_enableParallel = (ulSerialMode == 0); - state->m_rfmirror = (ulRfMirror == 0); state->m_IfAgcPol = false; return 0; @@ -946,6 +942,9 @@ static int GetDeviceCapabilities(struct drxk_state *state) status = read32(state, SIO_TOP_JTAGID_LO__A, &sioTopJtagidLo); if (status < 0) goto error; + +printk(KERN_ERR "drxk: status = 0x%08x\n", sioTopJtagidLo); + /* driver 0.9.0 */ switch ((sioTopJtagidLo >> 29) & 0xF) { case 0: @@ -963,7 +962,8 @@ static int GetDeviceCapabilities(struct drxk_state *state) default: state->m_deviceSpin = DRXK_SPIN_UNKNOWN; status = -EINVAL; - printk(KERN_ERR "drxk: Spin unknown\n"); + printk(KERN_ERR "drxk: Spin %d unknown\n", + (sioTopJtagidLo >> 29) & 0xF); goto error2; } switch ((sioTopJtagidLo >> 12) & 0xFF) { @@ -1190,7 +1190,9 @@ static int MPEGTSConfigurePins(struct drxk_state *state, bool mpegEnable) u16 sioPdrMclkCfg = 0; u16 sioPdrMdxCfg = 0; - dprintk(1, "\n"); + dprintk(1, ": mpeg %s, %s mode\n", + mpegEnable ? "enable" : "disable", + state->m_enableParallel ? "parallel" : "serial"); /* stop lock indicator process */ status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE); @@ -1846,6 +1848,7 @@ static int SetOperationMode(struct drxk_state *state, */ switch (oMode) { case OM_DVBT: + dprintk(1, ": DVB-T\n"); state->m_OperationMode = oMode; status = SetDVBTStandard(state, oMode); if (status < 0) @@ -1853,6 +1856,8 @@ static int SetOperationMode(struct drxk_state *state, break; case OM_QAM_ITU_A: /* fallthrough */ case OM_QAM_ITU_C: + dprintk(1, ": DVB-C Annex %c\n", + (state->m_OperationMode == OM_QAM_ITU_A) ? 'A' : 'C'); state->m_OperationMode = oMode; status = SetQAMStandard(state, oMode); if (status < 0) @@ -1881,7 +1886,7 @@ static int Start(struct drxk_state *state, s32 offsetFreq, state->m_DrxkState != DRXK_DTV_STARTED) goto error; - state->m_bMirrorFreqSpect = (state->param.inversion == INVERSION_ON); + state->m_bMirrorFreqSpect = (state->props.inversion == INVERSION_ON); if (IntermediateFrequency < 0) { state->m_bMirrorFreqSpect = !state->m_bMirrorFreqSpect; @@ -2503,7 +2508,7 @@ static int GetQAMSignalToNoise(struct drxk_state *state, u16 qamSlErrPower = 0; /* accum. error between raw and sliced symbols */ u32 qamSlSigPower = 0; /* used for MER, depends of - QAM constellation */ + QAM modulation */ u32 qamSlMer = 0; /* QAM MER */ dprintk(1, "\n"); @@ -2517,7 +2522,7 @@ static int GetQAMSignalToNoise(struct drxk_state *state, return -EINVAL; } - switch (state->param.u.qam.modulation) { + switch (state->props.modulation) { case QAM_16: qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM16 << 2; break; @@ -2748,7 +2753,7 @@ static int GetDVBCQuality(struct drxk_state *state, s32 *pQuality) if (status < 0) break; - switch (state->param.u.qam.modulation) { + switch (state->props.modulation) { case QAM_16: SignalToNoiseRel = SignalToNoise - 200; break; @@ -3813,7 +3818,7 @@ static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz, /*== Write channel settings to device =====================================*/ /* mode */ - switch (state->param.u.ofdm.transmission_mode) { + switch (state->props.transmission_mode) { case TRANSMISSION_MODE_AUTO: default: operationMode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M; @@ -3827,7 +3832,7 @@ static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz, } /* guard */ - switch (state->param.u.ofdm.guard_interval) { + switch (state->props.guard_interval) { default: case GUARD_INTERVAL_AUTO: operationMode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M; @@ -3847,7 +3852,7 @@ static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz, } /* hierarchy */ - switch (state->param.u.ofdm.hierarchy_information) { + switch (state->props.hierarchy) { case HIERARCHY_AUTO: case HIERARCHY_NONE: default: @@ -3867,8 +3872,8 @@ static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz, } - /* constellation */ - switch (state->param.u.ofdm.constellation) { + /* modulation */ + switch (state->props.modulation) { case QAM_AUTO: default: operationMode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M; @@ -3911,7 +3916,7 @@ static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz, #endif /* coderate */ - switch (state->param.u.ofdm.code_rate_HP) { + switch (state->props.code_rate_HP) { case FEC_AUTO: default: operationMode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M; @@ -3940,9 +3945,11 @@ static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz, /* Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is changed by SC for fix for some 8K,1/8 guard but is restored by InitEC and ResetEC functions */ - switch (state->param.u.ofdm.bandwidth) { - case BANDWIDTH_AUTO: - case BANDWIDTH_8_MHZ: + switch (state->props.bandwidth_hz) { + case 0: + state->props.bandwidth_hz = 8000000; + /* fall though */ + case 8000000: bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ; status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3052); if (status < 0) @@ -3961,7 +3968,7 @@ static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz, if (status < 0) goto error; break; - case BANDWIDTH_7_MHZ: + case 7000000: bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ; status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3491); if (status < 0) @@ -3980,7 +3987,7 @@ static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz, if (status < 0) goto error; break; - case BANDWIDTH_6_MHZ: + case 6000000: bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ; status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 4073); if (status < 0) @@ -4187,7 +4194,7 @@ error: /** * \brief Setup of the QAM Measurement intervals for signal quality * \param demod instance of demod. -* \param constellation current constellation. +* \param modulation current modulation. * \return DRXStatus_t. * * NOTE: @@ -4196,7 +4203,7 @@ error: * */ static int SetQAMMeasurement(struct drxk_state *state, - enum EDrxkConstellation constellation, + enum EDrxkConstellation modulation, u32 symbolRate) { u32 fecBitsDesired = 0; /* BER accounting period */ @@ -4210,11 +4217,11 @@ static int SetQAMMeasurement(struct drxk_state *state, fecRsPrescale = 1; /* fecBitsDesired = symbolRate [kHz] * FrameLenght [ms] * - (constellation + 1) * + (modulation + 1) * SyncLoss (== 1) * ViterbiLoss (==1) */ - switch (constellation) { + switch (modulation) { case DRX_CONSTELLATION_QAM16: fecBitsDesired = 4 * symbolRate; break; @@ -5281,12 +5288,12 @@ static int QAMSetSymbolrate(struct drxk_state *state) /* Select & calculate correct IQM rate */ adcFrequency = (state->m_sysClockFreq * 1000) / 3; ratesel = 0; - /* printk(KERN_DEBUG "drxk: SR %d\n", state->param.u.qam.symbol_rate); */ - if (state->param.u.qam.symbol_rate <= 1188750) + /* printk(KERN_DEBUG "drxk: SR %d\n", state->props.symbol_rate); */ + if (state->props.symbol_rate <= 1188750) ratesel = 3; - else if (state->param.u.qam.symbol_rate <= 2377500) + else if (state->props.symbol_rate <= 2377500) ratesel = 2; - else if (state->param.u.qam.symbol_rate <= 4755000) + else if (state->props.symbol_rate <= 4755000) ratesel = 1; status = write16(state, IQM_FD_RATESEL__A, ratesel); if (status < 0) @@ -5295,7 +5302,7 @@ static int QAMSetSymbolrate(struct drxk_state *state) /* IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23) */ - symbFreq = state->param.u.qam.symbol_rate * (1 << ratesel); + symbFreq = state->props.symbol_rate * (1 << ratesel); if (symbFreq == 0) { /* Divide by zero */ status = -EINVAL; @@ -5311,7 +5318,7 @@ static int QAMSetSymbolrate(struct drxk_state *state) /* LcSymbFreq = round (.125 * symbolrate / adcFreq * (1<<15)) */ - symbFreq = state->param.u.qam.symbol_rate; + symbFreq = state->props.symbol_rate; if (adcFrequency == 0) { /* Divide by zero */ status = -EINVAL; @@ -5412,7 +5419,7 @@ static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz, goto error; /* Set params */ - switch (state->param.u.qam.modulation) { + switch (state->props.modulation) { case QAM_256: state->m_Constellation = DRX_CONSTELLATION_QAM256; break; @@ -5435,7 +5442,7 @@ static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz, } if (status < 0) goto error; - setParamParameters[0] = state->m_Constellation; /* constellation */ + setParamParameters[0] = state->m_Constellation; /* modulation */ setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */ if (state->m_OperationMode == OM_QAM_ITU_C) setParamParameters[2] = QAM_TOP_ANNEX_C; @@ -5457,7 +5464,7 @@ static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz, if (status < 0) goto error; - setParamParameters[0] = state->m_Constellation; /* constellation */ + setParamParameters[0] = state->m_Constellation; /* modulation */ setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */ status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 2, setParamParameters, 1, &cmdResult); } @@ -5466,7 +5473,7 @@ static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz, /* * STEP 3: enable the system in a mode where the ADC provides valid - * signal setup constellation independent registers + * signal setup modulation independent registers */ #if 0 status = SetFrequency(channel, tunerFreqOffset)); @@ -5478,7 +5485,7 @@ static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz, goto error; /* Setup BER measurement */ - status = SetQAMMeasurement(state, state->m_Constellation, state->param.u. qam.symbol_rate); + status = SetQAMMeasurement(state, state->m_Constellation, state->props.symbol_rate); if (status < 0) goto error; @@ -5560,8 +5567,8 @@ static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz, if (status < 0) goto error; - /* STEP 4: constellation specific setup */ - switch (state->param.u.qam.modulation) { + /* STEP 4: modulation specific setup */ + switch (state->props.modulation) { case QAM_16: status = SetQAM16(state); break; @@ -5591,7 +5598,7 @@ static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz, goto error; /* Re-configure MPEG output, requires knowledge of channel bitrate */ - /* extAttr->currentChannel.constellation = channel->constellation; */ + /* extAttr->currentChannel.modulation = channel->modulation; */ /* extAttr->currentChannel.symbolrate = channel->symbolrate; */ status = MPEGTSDtoSetup(state, state->m_OperationMode); if (status < 0) @@ -6167,7 +6174,7 @@ error: return status; } -static void drxk_c_release(struct dvb_frontend *fe) +static void drxk_release(struct dvb_frontend *fe) { struct drxk_state *state = fe->demodulator_priv; @@ -6175,24 +6182,12 @@ static void drxk_c_release(struct dvb_frontend *fe) kfree(state); } -static int drxk_c_init(struct dvb_frontend *fe) -{ - struct drxk_state *state = fe->demodulator_priv; - - dprintk(1, "\n"); - if (mutex_trylock(&state->ctlock) == 0) - return -EBUSY; - SetOperationMode(state, OM_QAM_ITU_A); - return 0; -} - -static int drxk_c_sleep(struct dvb_frontend *fe) +static int drxk_sleep(struct dvb_frontend *fe) { struct drxk_state *state = fe->demodulator_priv; dprintk(1, "\n"); ShutDown(state); - mutex_unlock(&state->ctlock); return 0; } @@ -6204,9 +6199,10 @@ static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) return ConfigureI2CBridge(state, enable ? true : false); } -static int drxk_set_parameters(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int drxk_set_parameters(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; + u32 delsys = p->delivery_system, old_delsys; struct drxk_state *state = fe->demodulator_priv; u32 IF; @@ -6218,14 +6214,39 @@ static int drxk_set_parameters(struct dvb_frontend *fe, return -EINVAL; } - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); if (fe->ops.tuner_ops.set_params) - fe->ops.tuner_ops.set_params(fe, p); + fe->ops.tuner_ops.set_params(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - state->param = *p; + + old_delsys = state->props.delivery_system; + state->props = *p; + + if (old_delsys != delsys) { + ShutDown(state); + switch (delsys) { + case SYS_DVBC_ANNEX_A: + case SYS_DVBC_ANNEX_C: + if (!state->m_hasDVBC) + return -EINVAL; + state->m_itut_annex_c = (delsys == SYS_DVBC_ANNEX_C) ? true : false; + if (state->m_itut_annex_c) + SetOperationMode(state, OM_QAM_ITU_C); + else + SetOperationMode(state, OM_QAM_ITU_A); + break; + case SYS_DVBT: + if (!state->m_hasDVBT) + return -EINVAL; + SetOperationMode(state, OM_DVBT); + break; + default: + return -EINVAL; + } + } + fe->ops.tuner_ops.get_if_frequency(fe, &IF); Start(state, 0, IF); @@ -6234,13 +6255,6 @@ static int drxk_set_parameters(struct dvb_frontend *fe, return 0; } -static int drxk_c_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - dprintk(1, "\n"); - return 0; -} - static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status) { struct drxk_state *state = fe->demodulator_priv; @@ -6300,102 +6314,54 @@ static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) return 0; } -static int drxk_c_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings +static int drxk_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *sets) { - dprintk(1, "\n"); - sets->min_delay_ms = 3000; - sets->max_drift = 0; - sets->step_size = 0; - return 0; -} - -static void drxk_t_release(struct dvb_frontend *fe) -{ - /* - * There's nothing to release here, as the state struct - * is already freed by drxk_c_release. - */ -} - -static int drxk_t_init(struct dvb_frontend *fe) -{ - struct drxk_state *state = fe->demodulator_priv; + struct dtv_frontend_properties *p = &fe->dtv_property_cache; dprintk(1, "\n"); - if (mutex_trylock(&state->ctlock) == 0) - return -EBUSY; - SetOperationMode(state, OM_DVBT); - return 0; -} - -static int drxk_t_sleep(struct dvb_frontend *fe) -{ - struct drxk_state *state = fe->demodulator_priv; - - dprintk(1, "\n"); - mutex_unlock(&state->ctlock); - return 0; -} - -static int drxk_t_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - dprintk(1, "\n"); - - return 0; + switch (p->delivery_system) { + case SYS_DVBC_ANNEX_A: + case SYS_DVBC_ANNEX_C: + sets->min_delay_ms = 3000; + sets->max_drift = 0; + sets->step_size = 0; + return 0; + default: + /* + * For DVB-T, let it use the default DVB core way, that is: + * fepriv->step_size = fe->ops.info.frequency_stepsize * 2 + */ + return -EINVAL; + } } -static struct dvb_frontend_ops drxk_c_ops = { +static struct dvb_frontend_ops drxk_ops = { + /* .delsys will be filled dynamically */ .info = { - .name = "DRXK DVB-C", - .type = FE_QAM, - .frequency_stepsize = 62500, - .frequency_min = 47000000, - .frequency_max = 862000000, - .symbol_rate_min = 870000, - .symbol_rate_max = 11700000, - .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | - FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO}, - .release = drxk_c_release, - .init = drxk_c_init, - .sleep = drxk_c_sleep, + .name = "DRXK", + .frequency_min = 47000000, + .frequency_max = 865000000, + /* For DVB-C */ + .symbol_rate_min = 870000, + .symbol_rate_max = 11700000, + /* For DVB-T */ + .frequency_stepsize = 166667, + + .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | + FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO | + FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | + FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_MUTE_TS | + FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER | + FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO + }, + + .release = drxk_release, + .sleep = drxk_sleep, .i2c_gate_ctrl = drxk_gate_ctrl, .set_frontend = drxk_set_parameters, - .get_frontend = drxk_c_get_frontend, - .get_tune_settings = drxk_c_get_tune_settings, - - .read_status = drxk_read_status, - .read_ber = drxk_read_ber, - .read_signal_strength = drxk_read_signal_strength, - .read_snr = drxk_read_snr, - .read_ucblocks = drxk_read_ucblocks, -}; - -static struct dvb_frontend_ops drxk_t_ops = { - .info = { - .name = "DRXK DVB-T", - .type = FE_OFDM, - .frequency_min = 47125000, - .frequency_max = 865000000, - .frequency_stepsize = 166667, - .frequency_tolerance = 0, - .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | - FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | - FE_CAN_FEC_AUTO | - FE_CAN_QAM_16 | FE_CAN_QAM_64 | - FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | - FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | FE_CAN_MUTE_TS}, - .release = drxk_t_release, - .init = drxk_t_init, - .sleep = drxk_t_sleep, - .i2c_gate_ctrl = drxk_gate_ctrl, - - .set_frontend = drxk_set_parameters, - .get_frontend = drxk_t_get_frontend, + .get_tune_settings = drxk_get_tune_settings, .read_status = drxk_read_status, .read_ber = drxk_read_ber, @@ -6405,9 +6371,10 @@ static struct dvb_frontend_ops drxk_t_ops = { }; struct dvb_frontend *drxk_attach(const struct drxk_config *config, - struct i2c_adapter *i2c, - struct dvb_frontend **fe_t) + struct i2c_adapter *i2c) { + int n; + struct drxk_state *state = NULL; u8 adr = config->adr; @@ -6423,6 +6390,12 @@ struct dvb_frontend *drxk_attach(const struct drxk_config *config, state->no_i2c_bridge = config->no_i2c_bridge; state->antenna_gpio = config->antenna_gpio; state->antenna_dvbt = config->antenna_dvbt; + state->m_ChunkSize = config->chunk_size; + + if (config->parallel_ts) + state->m_enableParallel = true; + else + state->m_enableParallel = false; /* NOTE: as more UIO bits will be used, add them to the mask */ state->UIO_mask = config->antenna_gpio; @@ -6434,21 +6407,30 @@ struct dvb_frontend *drxk_attach(const struct drxk_config *config, state->m_GPIO &= ~state->antenna_gpio; mutex_init(&state->mutex); - mutex_init(&state->ctlock); - memcpy(&state->c_frontend.ops, &drxk_c_ops, - sizeof(struct dvb_frontend_ops)); - memcpy(&state->t_frontend.ops, &drxk_t_ops, - sizeof(struct dvb_frontend_ops)); - state->c_frontend.demodulator_priv = state; - state->t_frontend.demodulator_priv = state; + memcpy(&state->frontend.ops, &drxk_ops, sizeof(drxk_ops)); + state->frontend.demodulator_priv = state; init_state(state); if (init_drxk(state) < 0) goto error; - *fe_t = &state->t_frontend; - return &state->c_frontend; + /* Initialize the supported delivery systems */ + n = 0; + if (state->m_hasDVBC) { + state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_A; + state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_C; + strlcat(state->frontend.ops.info.name, " DVB-C", + sizeof(state->frontend.ops.info.name)); + } + if (state->m_hasDVBT) { + state->frontend.ops.delsys[n++] = SYS_DVBT; + strlcat(state->frontend.ops.info.name, " DVB-T", + sizeof(state->frontend.ops.info.name)); + } + + printk(KERN_INFO "drxk: frontend initialized.\n"); + return &state->frontend; error: printk(KERN_ERR "drxk: not found\n"); diff --git a/drivers/media/dvb/frontends/drxk_hard.h b/drivers/media/dvb/frontends/drxk_hard.h index a05c32eecdcc..3a58b73eb9b9 100644 --- a/drivers/media/dvb/frontends/drxk_hard.h +++ b/drivers/media/dvb/frontends/drxk_hard.h @@ -195,9 +195,8 @@ struct DRXKOfdmScCmd_t { }; struct drxk_state { - struct dvb_frontend c_frontend; - struct dvb_frontend t_frontend; - struct dvb_frontend_parameters param; + struct dvb_frontend frontend; + struct dtv_frontend_properties props; struct device *dev; struct i2c_adapter *i2c; @@ -205,7 +204,6 @@ struct drxk_state { void *priv; struct mutex mutex; - struct mutex ctlock; u32 m_Instance; /**< Channel 1,2,3 or 4 */ @@ -263,6 +261,8 @@ struct drxk_state { u8 m_TSDataStrength; u8 m_TSClockkStrength; + bool m_itut_annex_c; /* If true, uses ITU-T DVB-C Annex C, instead of Annex A */ + enum DRXMPEGStrWidth_t m_widthSTR; /**< MPEG start width */ u32 m_mpegTsStaticBitrate; /**< Maximum bitrate in b/s in case static clockrate is selected */ diff --git a/drivers/media/dvb/frontends/ds3000.c b/drivers/media/dvb/frontends/ds3000.c index 90bf573308b0..938777065de6 100644 --- a/drivers/media/dvb/frontends/ds3000.c +++ b/drivers/media/dvb/frontends/ds3000.c @@ -934,20 +934,6 @@ error2: } EXPORT_SYMBOL(ds3000_attach); -static int ds3000_set_property(struct dvb_frontend *fe, - struct dtv_property *tvp) -{ - dprintk("%s(..)\n", __func__); - return 0; -} - -static int ds3000_get_property(struct dvb_frontend *fe, - struct dtv_property *tvp) -{ - dprintk("%s(..)\n", __func__); - return 0; -} - static int ds3000_set_carrier_offset(struct dvb_frontend *fe, s32 carrier_offset_khz) { @@ -967,8 +953,7 @@ static int ds3000_set_carrier_offset(struct dvb_frontend *fe, return 0; } -static int ds3000_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int ds3000_set_frontend(struct dvb_frontend *fe) { struct ds3000_state *state = fe->demodulator_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache; @@ -994,15 +979,15 @@ static int ds3000_set_frontend(struct dvb_frontend *fe, div4 = 0; /* calculate and set freq divider */ - if (p->frequency < 1146000) { + if (c->frequency < 1146000) { ds3000_tuner_writereg(state, 0x10, 0x11); div4 = 1; - ndiv = ((p->frequency * (6 + 8) * 4) + + ndiv = ((c->frequency * (6 + 8) * 4) + (DS3000_XTAL_FREQ / 2)) / DS3000_XTAL_FREQ - 1024; } else { ds3000_tuner_writereg(state, 0x10, 0x01); - ndiv = ((p->frequency * (6 + 8) * 2) + + ndiv = ((c->frequency * (6 + 8) * 2) + (DS3000_XTAL_FREQ / 2)) / DS3000_XTAL_FREQ - 1024; } @@ -1101,7 +1086,7 @@ static int ds3000_set_frontend(struct dvb_frontend *fe, msleep(60); offset_khz = (ndiv - ndiv % 2 + 1024) * DS3000_XTAL_FREQ - / (6 + 8) / (div4 + 1) / 2 - p->frequency; + / (6 + 8) / (div4 + 1) / 2 - c->frequency; /* ds3000 global reset */ ds3000_writereg(state, 0x07, 0x80); @@ -1220,13 +1205,13 @@ static int ds3000_set_frontend(struct dvb_frontend *fe, } static int ds3000_tune(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p, + bool re_tune, unsigned int mode_flags, unsigned int *delay, fe_status_t *status) { - if (p) { - int ret = ds3000_set_frontend(fe, p); + if (re_tune) { + int ret = ds3000_set_frontend(fe); if (ret) return ret; } @@ -1279,10 +1264,9 @@ static int ds3000_sleep(struct dvb_frontend *fe) } static struct dvb_frontend_ops ds3000_ops = { - + .delsys = { SYS_DVBS, SYS_DVBS2}, .info = { .name = "Montage Technology DS3000/TS2020", - .type = FE_QPSK, .frequency_min = 950000, .frequency_max = 2150000, .frequency_stepsize = 1011, /* kHz for QPSK frontends */ @@ -1312,8 +1296,6 @@ static struct dvb_frontend_ops ds3000_ops = { .diseqc_send_burst = ds3000_diseqc_send_burst, .get_frontend_algo = ds3000_get_algo, - .set_property = ds3000_set_property, - .get_property = ds3000_get_property, .set_frontend = ds3000_set_frontend, .tune = ds3000_tune, }; diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c index 62a65efdf8d6..1ab34838221c 100644 --- a/drivers/media/dvb/frontends/dvb-pll.c +++ b/drivers/media/dvb/frontends/dvb-pll.c @@ -61,8 +61,7 @@ struct dvb_pll_desc { u32 min; u32 max; u32 iffreq; - void (*set)(struct dvb_frontend *fe, u8 *buf, - const struct dvb_frontend_parameters *params); + void (*set)(struct dvb_frontend *fe, u8 *buf); u8 *initdata; u8 *initdata2; u8 *sleepdata; @@ -93,10 +92,10 @@ static struct dvb_pll_desc dvb_pll_thomson_dtt7579 = { }, }; -static void thomson_dtt759x_bw(struct dvb_frontend *fe, u8 *buf, - const struct dvb_frontend_parameters *params) +static void thomson_dtt759x_bw(struct dvb_frontend *fe, u8 *buf) { - if (BANDWIDTH_7_MHZ == params->u.ofdm.bandwidth) + u32 bw = fe->dtv_property_cache.bandwidth_hz; + if (bw == 7000000) buf[3] |= 0x10; } @@ -186,10 +185,10 @@ static struct dvb_pll_desc dvb_pll_env57h1xd5 = { /* Philips TDA6650/TDA6651 * used in Panasonic ENV77H11D5 */ -static void tda665x_bw(struct dvb_frontend *fe, u8 *buf, - const struct dvb_frontend_parameters *params) +static void tda665x_bw(struct dvb_frontend *fe, u8 *buf) { - if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) + u32 bw = fe->dtv_property_cache.bandwidth_hz; + if (bw == 8000000) buf[3] |= 0x08; } @@ -220,10 +219,10 @@ static struct dvb_pll_desc dvb_pll_tda665x = { /* Infineon TUA6034 * used in LG TDTP E102P */ -static void tua6034_bw(struct dvb_frontend *fe, u8 *buf, - const struct dvb_frontend_parameters *params) +static void tua6034_bw(struct dvb_frontend *fe, u8 *buf) { - if (BANDWIDTH_7_MHZ != params->u.ofdm.bandwidth) + u32 bw = fe->dtv_property_cache.bandwidth_hz; + if (bw == 7000000) buf[3] |= 0x08; } @@ -244,10 +243,10 @@ static struct dvb_pll_desc dvb_pll_tua6034 = { /* ALPS TDED4 * used in Nebula-Cards and USB boxes */ -static void tded4_bw(struct dvb_frontend *fe, u8 *buf, - const struct dvb_frontend_parameters *params) +static void tded4_bw(struct dvb_frontend *fe, u8 *buf) { - if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) + u32 bw = fe->dtv_property_cache.bandwidth_hz; + if (bw == 8000000) buf[3] |= 0x04; } @@ -319,11 +318,11 @@ static struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261 = { }, }; -static void opera1_bw(struct dvb_frontend *fe, u8 *buf, - const struct dvb_frontend_parameters *params) +static void opera1_bw(struct dvb_frontend *fe, u8 *buf) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct dvb_pll_priv *priv = fe->tuner_priv; - u32 b_w = (params->u.qpsk.symbol_rate * 27) / 32000; + u32 b_w = (c->symbol_rate * 27) / 32000; struct i2c_msg msg = { .addr = priv->pll_i2c_address, .flags = 0, @@ -392,8 +391,7 @@ static struct dvb_pll_desc dvb_pll_opera1 = { } }; -static void samsung_dtos403ih102a_set(struct dvb_frontend *fe, u8 *buf, - const struct dvb_frontend_parameters *params) +static void samsung_dtos403ih102a_set(struct dvb_frontend *fe, u8 *buf) { struct dvb_pll_priv *priv = fe->tuner_priv; struct i2c_msg msg = { @@ -537,30 +535,29 @@ static struct dvb_pll_desc *pll_list[] = { /* code */ static int dvb_pll_configure(struct dvb_frontend *fe, u8 *buf, - const struct dvb_frontend_parameters *params) + const u32 frequency) { struct dvb_pll_priv *priv = fe->tuner_priv; struct dvb_pll_desc *desc = priv->pll_desc; u32 div; int i; - if (params->frequency != 0 && (params->frequency < desc->min || - params->frequency > desc->max)) + if (frequency && (frequency < desc->min || frequency > desc->max)) return -EINVAL; for (i = 0; i < desc->count; i++) { - if (params->frequency > desc->entries[i].limit) + if (frequency > desc->entries[i].limit) continue; break; } if (debug) printk("pll: %s: freq=%d | i=%d/%d\n", desc->name, - params->frequency, i, desc->count); + frequency, i, desc->count); if (i == desc->count) return -EINVAL; - div = (params->frequency + desc->iffreq + + div = (frequency + desc->iffreq + desc->entries[i].stepsize/2) / desc->entries[i].stepsize; buf[0] = div >> 8; buf[1] = div & 0xff; @@ -568,7 +565,7 @@ static int dvb_pll_configure(struct dvb_frontend *fe, u8 *buf, buf[3] = desc->entries[i].cb; if (desc->set) - desc->set(fe, buf, params); + desc->set(fe, buf); if (debug) printk("pll: %s: div=%d | buf=0x%02x,0x%02x,0x%02x,0x%02x\n", @@ -611,9 +608,9 @@ static int dvb_pll_sleep(struct dvb_frontend *fe) return -EINVAL; } -static int dvb_pll_set_params(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) +static int dvb_pll_set_params(struct dvb_frontend *fe) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct dvb_pll_priv *priv = fe->tuner_priv; u8 buf[4]; struct i2c_msg msg = @@ -625,7 +622,8 @@ static int dvb_pll_set_params(struct dvb_frontend *fe, if (priv->i2c == NULL) return -EINVAL; - if ((result = dvb_pll_configure(fe, buf, params)) < 0) + result = dvb_pll_configure(fe, buf, c->frequency); + if (result < 0) return result; else frequency = result; @@ -637,15 +635,15 @@ static int dvb_pll_set_params(struct dvb_frontend *fe, } priv->frequency = frequency; - priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0; + priv->bandwidth = c->bandwidth_hz; return 0; } static int dvb_pll_calc_regs(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params, u8 *buf, int buf_len) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct dvb_pll_priv *priv = fe->tuner_priv; int result; u32 frequency = 0; @@ -653,7 +651,8 @@ static int dvb_pll_calc_regs(struct dvb_frontend *fe, if (buf_len < 5) return -EINVAL; - if ((result = dvb_pll_configure(fe, buf+1, params)) < 0) + result = dvb_pll_configure(fe, buf + 1, c->frequency); + if (result < 0) return result; else frequency = result; @@ -661,7 +660,7 @@ static int dvb_pll_calc_regs(struct dvb_frontend *fe, buf[0] = priv->pll_i2c_address; priv->frequency = frequency; - priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0; + priv->bandwidth = c->bandwidth_hz; return 5; } diff --git a/drivers/media/dvb/frontends/dvb_dummy_fe.c b/drivers/media/dvb/frontends/dvb_dummy_fe.c index a7fc7e53a551..dcfc902c8678 100644 --- a/drivers/media/dvb/frontends/dvb_dummy_fe.c +++ b/drivers/media/dvb/frontends/dvb_dummy_fe.c @@ -68,15 +68,18 @@ static int dvb_dummy_fe_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) return 0; } -static int dvb_dummy_fe_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) +/* + * Only needed if it actually reads something from the hardware + */ +static int dvb_dummy_fe_get_frontend(struct dvb_frontend *fe) { return 0; } -static int dvb_dummy_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) +static int dvb_dummy_fe_set_frontend(struct dvb_frontend *fe) { if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); + fe->ops.tuner_ops.set_params(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); } @@ -171,10 +174,9 @@ error: } static struct dvb_frontend_ops dvb_dummy_fe_ofdm_ops = { - + .delsys = { SYS_DVBT }, .info = { .name = "Dummy DVB-T", - .type = FE_OFDM, .frequency_min = 0, .frequency_max = 863250000, .frequency_stepsize = 62500, @@ -203,10 +205,9 @@ static struct dvb_frontend_ops dvb_dummy_fe_ofdm_ops = { }; static struct dvb_frontend_ops dvb_dummy_fe_qam_ops = { - + .delsys = { SYS_DVBC_ANNEX_A }, .info = { .name = "Dummy DVB-C", - .type = FE_QAM, .frequency_stepsize = 62500, .frequency_min = 51000000, .frequency_max = 858000000, @@ -233,10 +234,9 @@ static struct dvb_frontend_ops dvb_dummy_fe_qam_ops = { }; static struct dvb_frontend_ops dvb_dummy_fe_qpsk_ops = { - + .delsys = { SYS_DVBS }, .info = { .name = "Dummy DVB-S", - .type = FE_QPSK, .frequency_min = 950000, .frequency_max = 2150000, .frequency_stepsize = 250, /* kHz for QPSK frontends */ diff --git a/drivers/media/dvb/frontends/ec100.c b/drivers/media/dvb/frontends/ec100.c index 2414dc6ee5d9..c56fddbf53b7 100644 --- a/drivers/media/dvb/frontends/ec100.c +++ b/drivers/media/dvb/frontends/ec100.c @@ -76,19 +76,19 @@ static int ec100_read_reg(struct ec100_state *state, u8 reg, u8 *val) return 0; } -static int ec100_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) +static int ec100_set_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct ec100_state *state = fe->demodulator_priv; int ret; u8 tmp, tmp2; - deb_info("%s: freq:%d bw:%d\n", __func__, params->frequency, - params->u.ofdm.bandwidth); + deb_info("%s: freq:%d bw:%d\n", __func__, c->frequency, + c->bandwidth_hz); /* program tuner */ if (fe->ops.tuner_ops.set_params) - fe->ops.tuner_ops.set_params(fe, params); + fe->ops.tuner_ops.set_params(fe); ret = ec100_write_reg(state, 0x04, 0x06); if (ret) @@ -108,16 +108,16 @@ static int ec100_set_frontend(struct dvb_frontend *fe, B 0x1b | 0xb7 | 0x00 | 0x49 B 0x1c | 0x55 | 0x64 | 0x72 */ - switch (params->u.ofdm.bandwidth) { - case BANDWIDTH_6_MHZ: + switch (c->bandwidth_hz) { + case 6000000: tmp = 0xb7; tmp2 = 0x55; break; - case BANDWIDTH_7_MHZ: + case 7000000: tmp = 0x00; tmp2 = 0x64; break; - case BANDWIDTH_8_MHZ: + case 8000000: default: tmp = 0x49; tmp2 = 0x72; @@ -306,9 +306,9 @@ error: EXPORT_SYMBOL(ec100_attach); static struct dvb_frontend_ops ec100_ops = { + .delsys = { SYS_DVBT }, .info = { .name = "E3C EC100 DVB-T", - .type = FE_OFDM, .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | diff --git a/drivers/media/dvb/frontends/hd29l2.c b/drivers/media/dvb/frontends/hd29l2.c new file mode 100644 index 000000000000..a00318190837 --- /dev/null +++ b/drivers/media/dvb/frontends/hd29l2.c @@ -0,0 +1,861 @@ +/* + * HDIC HD29L2 DMB-TH demodulator driver + * + * Copyright (C) 2011 Metropolia University of Applied Sciences, Electria R&D + * + * Author: Antti Palosaari <crope@iki.fi> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "hd29l2_priv.h" + +int hd29l2_debug; +module_param_named(debug, hd29l2_debug, int, 0644); +MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); + +/* write multiple registers */ +static int hd29l2_wr_regs(struct hd29l2_priv *priv, u8 reg, u8 *val, int len) +{ + int ret; + u8 buf[2 + len]; + struct i2c_msg msg[1] = { + { + .addr = priv->cfg.i2c_addr, + .flags = 0, + .len = sizeof(buf), + .buf = buf, + } + }; + + buf[0] = 0x00; + buf[1] = reg; + memcpy(&buf[2], val, len); + + ret = i2c_transfer(priv->i2c, msg, 1); + if (ret == 1) { + ret = 0; + } else { + warn("i2c wr failed=%d reg=%02x len=%d", ret, reg, len); + ret = -EREMOTEIO; + } + + return ret; +} + +/* read multiple registers */ +static int hd29l2_rd_regs(struct hd29l2_priv *priv, u8 reg, u8 *val, int len) +{ + int ret; + u8 buf[2] = { 0x00, reg }; + struct i2c_msg msg[2] = { + { + .addr = priv->cfg.i2c_addr, + .flags = 0, + .len = 2, + .buf = buf, + }, { + .addr = priv->cfg.i2c_addr, + .flags = I2C_M_RD, + .len = len, + .buf = val, + } + }; + + ret = i2c_transfer(priv->i2c, msg, 2); + if (ret == 2) { + ret = 0; + } else { + warn("i2c rd failed=%d reg=%02x len=%d", ret, reg, len); + ret = -EREMOTEIO; + } + + return ret; +} + +/* write single register */ +static int hd29l2_wr_reg(struct hd29l2_priv *priv, u8 reg, u8 val) +{ + return hd29l2_wr_regs(priv, reg, &val, 1); +} + +/* read single register */ +static int hd29l2_rd_reg(struct hd29l2_priv *priv, u8 reg, u8 *val) +{ + return hd29l2_rd_regs(priv, reg, val, 1); +} + +/* write single register with mask */ +static int hd29l2_wr_reg_mask(struct hd29l2_priv *priv, u8 reg, u8 val, u8 mask) +{ + int ret; + u8 tmp; + + /* no need for read if whole reg is written */ + if (mask != 0xff) { + ret = hd29l2_rd_regs(priv, reg, &tmp, 1); + if (ret) + return ret; + + val &= mask; + tmp &= ~mask; + val |= tmp; + } + + return hd29l2_wr_regs(priv, reg, &val, 1); +} + +/* read single register with mask */ +int hd29l2_rd_reg_mask(struct hd29l2_priv *priv, u8 reg, u8 *val, u8 mask) +{ + int ret, i; + u8 tmp; + + ret = hd29l2_rd_regs(priv, reg, &tmp, 1); + if (ret) + return ret; + + tmp &= mask; + + /* find position of the first bit */ + for (i = 0; i < 8; i++) { + if ((mask >> i) & 0x01) + break; + } + *val = tmp >> i; + + return 0; +} + +static int hd29l2_soft_reset(struct hd29l2_priv *priv) +{ + int ret; + u8 tmp; + + ret = hd29l2_rd_reg(priv, 0x26, &tmp); + if (ret) + goto err; + + ret = hd29l2_wr_reg(priv, 0x26, 0x0d); + if (ret) + goto err; + + usleep_range(10000, 20000); + + ret = hd29l2_wr_reg(priv, 0x26, tmp); + if (ret) + goto err; + + return 0; +err: + dbg("%s: failed=%d", __func__, ret); + return ret; +} + +static int hd29l2_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) +{ + int ret, i; + struct hd29l2_priv *priv = fe->demodulator_priv; + u8 tmp; + + dbg("%s: enable=%d", __func__, enable); + + /* set tuner address for demod */ + if (!priv->tuner_i2c_addr_programmed && enable) { + /* no need to set tuner address every time, once is enough */ + ret = hd29l2_wr_reg(priv, 0x9d, priv->cfg.tuner_i2c_addr << 1); + if (ret) + goto err; + + priv->tuner_i2c_addr_programmed = true; + } + + /* open / close gate */ + ret = hd29l2_wr_reg(priv, 0x9f, enable); + if (ret) + goto err; + + /* wait demod ready */ + for (i = 10; i; i--) { + ret = hd29l2_rd_reg(priv, 0x9e, &tmp); + if (ret) + goto err; + + if (tmp == enable) + break; + + usleep_range(5000, 10000); + } + + dbg("%s: loop=%d", __func__, i); + + return ret; +err: + dbg("%s: failed=%d", __func__, ret); + return ret; +} + +static int hd29l2_read_status(struct dvb_frontend *fe, fe_status_t *status) +{ + int ret; + struct hd29l2_priv *priv = fe->demodulator_priv; + u8 buf[2]; + + *status = 0; + + ret = hd29l2_rd_reg(priv, 0x05, &buf[0]); + if (ret) + goto err; + + if (buf[0] & 0x01) { + /* full lock */ + *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | + FE_HAS_SYNC | FE_HAS_LOCK; + } else { + ret = hd29l2_rd_reg(priv, 0x0d, &buf[1]); + if (ret) + goto err; + + if ((buf[1] & 0xfe) == 0x78) + /* partial lock */ + *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | + FE_HAS_VITERBI | FE_HAS_SYNC; + } + + priv->fe_status = *status; + + return 0; +err: + dbg("%s: failed=%d", __func__, ret); + return ret; +} + +static int hd29l2_read_snr(struct dvb_frontend *fe, u16 *snr) +{ + int ret; + struct hd29l2_priv *priv = fe->demodulator_priv; + u8 buf[2]; + u16 tmp; + + if (!(priv->fe_status & FE_HAS_LOCK)) { + *snr = 0; + ret = 0; + goto err; + } + + ret = hd29l2_rd_regs(priv, 0x0b, buf, 2); + if (ret) + goto err; + + tmp = (buf[0] << 8) | buf[1]; + + /* report SNR in dB * 10 */ + #define LOG10_20736_24 72422627 /* log10(20736) << 24 */ + if (tmp) + *snr = (LOG10_20736_24 - intlog10(tmp)) / ((1 << 24) / 100); + else + *snr = 0; + + return 0; +err: + dbg("%s: failed=%d", __func__, ret); + return ret; +} + +static int hd29l2_read_signal_strength(struct dvb_frontend *fe, u16 *strength) +{ + int ret; + struct hd29l2_priv *priv = fe->demodulator_priv; + u8 buf[2]; + u16 tmp; + + *strength = 0; + + ret = hd29l2_rd_regs(priv, 0xd5, buf, 2); + if (ret) + goto err; + + tmp = buf[0] << 8 | buf[1]; + tmp = ~tmp & 0x0fff; + + /* scale value to 0x0000-0xffff from 0x0000-0x0fff */ + *strength = tmp * 0xffff / 0x0fff; + + return 0; +err: + dbg("%s: failed=%d", __func__, ret); + return ret; +} + +static int hd29l2_read_ber(struct dvb_frontend *fe, u32 *ber) +{ + int ret; + struct hd29l2_priv *priv = fe->demodulator_priv; + u8 buf[2]; + + if (!(priv->fe_status & FE_HAS_SYNC)) { + *ber = 0; + ret = 0; + goto err; + } + + ret = hd29l2_rd_regs(priv, 0xd9, buf, 2); + if (ret) { + *ber = 0; + goto err; + } + + /* LDPC BER */ + *ber = ((buf[0] & 0x0f) << 8) | buf[1]; + + return 0; +err: + dbg("%s: failed=%d", __func__, ret); + return ret; +} + +static int hd29l2_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) +{ + /* no way to read? */ + *ucblocks = 0; + return 0; +} + +static enum dvbfe_search hd29l2_search(struct dvb_frontend *fe) +{ + int ret, i; + struct hd29l2_priv *priv = fe->demodulator_priv; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + u8 tmp, buf[3]; + u8 modulation, carrier, guard_interval, interleave, code_rate; + u64 num64; + u32 if_freq, if_ctl; + bool auto_mode; + + dbg("%s: delivery_system=%d frequency=%d bandwidth_hz=%d " \ + "modulation=%d inversion=%d fec_inner=%d guard_interval=%d", + __func__, + c->delivery_system, c->frequency, c->bandwidth_hz, + c->modulation, c->inversion, c->fec_inner, c->guard_interval); + + /* as for now we detect always params automatically */ + auto_mode = true; + + /* program tuner */ + if (fe->ops.tuner_ops.set_params) + fe->ops.tuner_ops.set_params(fe); + + /* get and program IF */ + if (fe->ops.tuner_ops.get_if_frequency) + fe->ops.tuner_ops.get_if_frequency(fe, &if_freq); + else + if_freq = 0; + + if (if_freq) { + /* normal IF */ + + /* calc IF control value */ + num64 = if_freq; + num64 *= 0x800000; + num64 = div_u64(num64, HD29L2_XTAL); + num64 -= 0x800000; + if_ctl = num64; + + tmp = 0xfc; /* tuner type normal */ + } else { + /* zero IF */ + if_ctl = 0; + tmp = 0xfe; /* tuner type Zero-IF */ + } + + buf[0] = ((if_ctl >> 0) & 0xff); + buf[1] = ((if_ctl >> 8) & 0xff); + buf[2] = ((if_ctl >> 16) & 0xff); + + /* program IF control */ + ret = hd29l2_wr_regs(priv, 0x14, buf, 3); + if (ret) + goto err; + + /* program tuner type */ + ret = hd29l2_wr_reg(priv, 0xab, tmp); + if (ret) + goto err; + + dbg("%s: if_freq=%d if_ctl=%x", __func__, if_freq, if_ctl); + + if (auto_mode) { + /* + * use auto mode + */ + + /* disable quick mode */ + ret = hd29l2_wr_reg_mask(priv, 0xac, 0 << 7, 0x80); + if (ret) + goto err; + + ret = hd29l2_wr_reg_mask(priv, 0x82, 1 << 1, 0x02); + if (ret) + goto err; + + /* enable auto mode */ + ret = hd29l2_wr_reg_mask(priv, 0x7d, 1 << 6, 0x40); + if (ret) + goto err; + + ret = hd29l2_wr_reg_mask(priv, 0x81, 1 << 3, 0x08); + if (ret) + goto err; + + /* soft reset */ + ret = hd29l2_soft_reset(priv); + if (ret) + goto err; + + /* detect modulation */ + for (i = 30; i; i--) { + msleep(100); + + ret = hd29l2_rd_reg(priv, 0x0d, &tmp); + if (ret) + goto err; + + if ((((tmp & 0xf0) >= 0x10) && + ((tmp & 0x0f) == 0x08)) || (tmp >= 0x2c)) + break; + } + + dbg("%s: loop=%d", __func__, i); + + if (i == 0) + /* detection failed */ + return DVBFE_ALGO_SEARCH_FAILED; + + /* read modulation */ + ret = hd29l2_rd_reg_mask(priv, 0x7d, &modulation, 0x07); + if (ret) + goto err; + } else { + /* + * use manual mode + */ + + modulation = HD29L2_QAM64; + carrier = HD29L2_CARRIER_MULTI; + guard_interval = HD29L2_PN945; + interleave = HD29L2_INTERLEAVER_420; + code_rate = HD29L2_CODE_RATE_08; + + tmp = (code_rate << 3) | modulation; + ret = hd29l2_wr_reg_mask(priv, 0x7d, tmp, 0x5f); + if (ret) + goto err; + + tmp = (carrier << 2) | guard_interval; + ret = hd29l2_wr_reg_mask(priv, 0x81, tmp, 0x0f); + if (ret) + goto err; + + tmp = interleave; + ret = hd29l2_wr_reg_mask(priv, 0x82, tmp, 0x03); + if (ret) + goto err; + } + + /* ensure modulation validy */ + /* 0=QAM4_NR, 1=QAM4, 2=QAM16, 3=QAM32, 4=QAM64 */ + if (modulation > (ARRAY_SIZE(reg_mod_vals_tab[0].val) - 1)) { + dbg("%s: modulation=%d not valid", __func__, modulation); + goto err; + } + + /* program registers according to modulation */ + for (i = 0; i < ARRAY_SIZE(reg_mod_vals_tab); i++) { + ret = hd29l2_wr_reg(priv, reg_mod_vals_tab[i].reg, + reg_mod_vals_tab[i].val[modulation]); + if (ret) + goto err; + } + + /* read guard interval */ + ret = hd29l2_rd_reg_mask(priv, 0x81, &guard_interval, 0x03); + if (ret) + goto err; + + /* read carrier mode */ + ret = hd29l2_rd_reg_mask(priv, 0x81, &carrier, 0x04); + if (ret) + goto err; + + dbg("%s: modulation=%d guard_interval=%d carrier=%d", + __func__, modulation, guard_interval, carrier); + + if ((carrier == HD29L2_CARRIER_MULTI) && (modulation == HD29L2_QAM64) && + (guard_interval == HD29L2_PN945)) { + dbg("%s: C=3780 && QAM64 && PN945", __func__); + + ret = hd29l2_wr_reg(priv, 0x42, 0x33); + if (ret) + goto err; + + ret = hd29l2_wr_reg(priv, 0xdd, 0x01); + if (ret) + goto err; + } + + usleep_range(10000, 20000); + + /* soft reset */ + ret = hd29l2_soft_reset(priv); + if (ret) + goto err; + + /* wait demod lock */ + for (i = 30; i; i--) { + msleep(100); + + /* read lock bit */ + ret = hd29l2_rd_reg_mask(priv, 0x05, &tmp, 0x01); + if (ret) + goto err; + + if (tmp) + break; + } + + dbg("%s: loop=%d", __func__, i); + + if (i == 0) + return DVBFE_ALGO_SEARCH_AGAIN; + + return DVBFE_ALGO_SEARCH_SUCCESS; +err: + dbg("%s: failed=%d", __func__, ret); + return DVBFE_ALGO_SEARCH_ERROR; +} + +static int hd29l2_get_frontend_algo(struct dvb_frontend *fe) +{ + return DVBFE_ALGO_CUSTOM; +} + +static int hd29l2_get_frontend(struct dvb_frontend *fe) +{ + int ret; + struct hd29l2_priv *priv = fe->demodulator_priv; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + u8 buf[3]; + u32 if_ctl; + char *str_constellation, *str_code_rate, *str_constellation_code_rate, + *str_guard_interval, *str_carrier, *str_guard_interval_carrier, + *str_interleave, *str_interleave_; + + ret = hd29l2_rd_reg(priv, 0x7d, &buf[0]); + if (ret) + goto err; + + ret = hd29l2_rd_regs(priv, 0x81, &buf[1], 2); + if (ret) + goto err; + + /* constellation, 0x7d[2:0] */ + switch ((buf[0] >> 0) & 0x07) { + case 0: /* QAM4NR */ + str_constellation = "QAM4NR"; + c->modulation = QAM_AUTO; /* FIXME */ + break; + case 1: /* QAM4 */ + str_constellation = "QAM4"; + c->modulation = QPSK; /* FIXME */ + break; + case 2: + str_constellation = "QAM16"; + c->modulation = QAM_16; + break; + case 3: + str_constellation = "QAM32"; + c->modulation = QAM_32; + break; + case 4: + str_constellation = "QAM64"; + c->modulation = QAM_64; + break; + default: + str_constellation = "?"; + } + + /* LDPC code rate, 0x7d[4:3] */ + switch ((buf[0] >> 3) & 0x03) { + case 0: /* 0.4 */ + str_code_rate = "0.4"; + c->fec_inner = FEC_AUTO; /* FIXME */ + break; + case 1: /* 0.6 */ + str_code_rate = "0.6"; + c->fec_inner = FEC_3_5; + break; + case 2: /* 0.8 */ + str_code_rate = "0.8"; + c->fec_inner = FEC_4_5; + break; + default: + str_code_rate = "?"; + } + + /* constellation & code rate set, 0x7d[6] */ + switch ((buf[0] >> 6) & 0x01) { + case 0: + str_constellation_code_rate = "manual"; + break; + case 1: + str_constellation_code_rate = "auto"; + break; + default: + str_constellation_code_rate = "?"; + } + + /* frame header, 0x81[1:0] */ + switch ((buf[1] >> 0) & 0x03) { + case 0: /* PN945 */ + str_guard_interval = "PN945"; + c->guard_interval = GUARD_INTERVAL_AUTO; /* FIXME */ + break; + case 1: /* PN595 */ + str_guard_interval = "PN595"; + c->guard_interval = GUARD_INTERVAL_AUTO; /* FIXME */ + break; + case 2: /* PN420 */ + str_guard_interval = "PN420"; + c->guard_interval = GUARD_INTERVAL_AUTO; /* FIXME */ + break; + default: + str_guard_interval = "?"; + } + + /* carrier, 0x81[2] */ + switch ((buf[1] >> 2) & 0x01) { + case 0: + str_carrier = "C=1"; + break; + case 1: + str_carrier = "C=3780"; + break; + default: + str_carrier = "?"; + } + + /* frame header & carrier set, 0x81[3] */ + switch ((buf[1] >> 3) & 0x01) { + case 0: + str_guard_interval_carrier = "manual"; + break; + case 1: + str_guard_interval_carrier = "auto"; + break; + default: + str_guard_interval_carrier = "?"; + } + + /* interleave, 0x82[0] */ + switch ((buf[2] >> 0) & 0x01) { + case 0: + str_interleave = "M=720"; + break; + case 1: + str_interleave = "M=240"; + break; + default: + str_interleave = "?"; + } + + /* interleave set, 0x82[1] */ + switch ((buf[2] >> 1) & 0x01) { + case 0: + str_interleave_ = "manual"; + break; + case 1: + str_interleave_ = "auto"; + break; + default: + str_interleave_ = "?"; + } + + /* + * We can read out current detected NCO and use that value next + * time instead of calculating new value from targed IF. + * I think it will not effect receiver sensitivity but gaining lock + * after tune could be easier... + */ + ret = hd29l2_rd_regs(priv, 0xb1, &buf[0], 3); + if (ret) + goto err; + + if_ctl = (buf[0] << 16) | ((buf[1] - 7) << 8) | buf[2]; + + dbg("%s: %s %s %s | %s %s %s | %s %s | NCO=%06x", __func__, + str_constellation, str_code_rate, str_constellation_code_rate, + str_guard_interval, str_carrier, str_guard_interval_carrier, + str_interleave, str_interleave_, if_ctl); + + return 0; +err: + dbg("%s: failed=%d", __func__, ret); + return ret; +} + +static int hd29l2_init(struct dvb_frontend *fe) +{ + int ret, i; + struct hd29l2_priv *priv = fe->demodulator_priv; + u8 tmp; + static const struct reg_val tab[] = { + { 0x3a, 0x06 }, + { 0x3b, 0x03 }, + { 0x3c, 0x04 }, + { 0xaf, 0x06 }, + { 0xb0, 0x1b }, + { 0x80, 0x64 }, + { 0x10, 0x38 }, + }; + + dbg("%s:", __func__); + + /* reset demod */ + /* it is recommended to HW reset chip using RST_N pin */ + if (fe->callback) { + ret = fe->callback(fe, DVB_FRONTEND_COMPONENT_DEMOD, 0, 0); + if (ret) + goto err; + + /* reprogramming needed because HW reset clears registers */ + priv->tuner_i2c_addr_programmed = false; + } + + /* init */ + for (i = 0; i < ARRAY_SIZE(tab); i++) { + ret = hd29l2_wr_reg(priv, tab[i].reg, tab[i].val); + if (ret) + goto err; + } + + /* TS params */ + ret = hd29l2_rd_reg(priv, 0x36, &tmp); + if (ret) + goto err; + + tmp &= 0x1b; + tmp |= priv->cfg.ts_mode; + ret = hd29l2_wr_reg(priv, 0x36, tmp); + if (ret) + goto err; + + ret = hd29l2_rd_reg(priv, 0x31, &tmp); + tmp &= 0xef; + + if (!(priv->cfg.ts_mode >> 7)) + /* set b4 for serial TS */ + tmp |= 0x10; + + ret = hd29l2_wr_reg(priv, 0x31, tmp); + if (ret) + goto err; + + return ret; +err: + dbg("%s: failed=%d", __func__, ret); + return ret; +} + +static void hd29l2_release(struct dvb_frontend *fe) +{ + struct hd29l2_priv *priv = fe->demodulator_priv; + kfree(priv); +} + +static struct dvb_frontend_ops hd29l2_ops; + +struct dvb_frontend *hd29l2_attach(const struct hd29l2_config *config, + struct i2c_adapter *i2c) +{ + int ret; + struct hd29l2_priv *priv = NULL; + u8 tmp; + + /* allocate memory for the internal state */ + priv = kzalloc(sizeof(struct hd29l2_priv), GFP_KERNEL); + if (priv == NULL) + goto err; + + /* setup the state */ + priv->i2c = i2c; + memcpy(&priv->cfg, config, sizeof(struct hd29l2_config)); + + + /* check if the demod is there */ + ret = hd29l2_rd_reg(priv, 0x00, &tmp); + if (ret) + goto err; + + /* create dvb_frontend */ + memcpy(&priv->fe.ops, &hd29l2_ops, sizeof(struct dvb_frontend_ops)); + priv->fe.demodulator_priv = priv; + + return &priv->fe; +err: + kfree(priv); + return NULL; +} +EXPORT_SYMBOL(hd29l2_attach); + +static struct dvb_frontend_ops hd29l2_ops = { + .delsys = { SYS_DVBT }, + .info = { + .name = "HDIC HD29L2 DMB-TH", + .frequency_min = 474000000, + .frequency_max = 858000000, + .frequency_stepsize = 10000, + .caps = FE_CAN_FEC_AUTO | + FE_CAN_QPSK | + FE_CAN_QAM_16 | + FE_CAN_QAM_32 | + FE_CAN_QAM_64 | + FE_CAN_QAM_AUTO | + FE_CAN_TRANSMISSION_MODE_AUTO | + FE_CAN_BANDWIDTH_AUTO | + FE_CAN_GUARD_INTERVAL_AUTO | + FE_CAN_HIERARCHY_AUTO | + FE_CAN_RECOVER + }, + + .release = hd29l2_release, + + .init = hd29l2_init, + + .get_frontend_algo = hd29l2_get_frontend_algo, + .search = hd29l2_search, + .get_frontend = hd29l2_get_frontend, + + .read_status = hd29l2_read_status, + .read_snr = hd29l2_read_snr, + .read_signal_strength = hd29l2_read_signal_strength, + .read_ber = hd29l2_read_ber, + .read_ucblocks = hd29l2_read_ucblocks, + + .i2c_gate_ctrl = hd29l2_i2c_gate_ctrl, +}; + +MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); +MODULE_DESCRIPTION("HDIC HD29L2 DMB-TH demodulator driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/hd29l2.h b/drivers/media/dvb/frontends/hd29l2.h new file mode 100644 index 000000000000..a7a64431364d --- /dev/null +++ b/drivers/media/dvb/frontends/hd29l2.h @@ -0,0 +1,66 @@ +/* + * HDIC HD29L2 DMB-TH demodulator driver + * + * Copyright (C) 2011 Metropolia University of Applied Sciences, Electria R&D + * + * Author: Antti Palosaari <crope@iki.fi> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef HD29L2_H +#define HD29L2_H + +#include <linux/dvb/frontend.h> + +struct hd29l2_config { + /* + * demodulator I2C address + */ + u8 i2c_addr; + + /* + * tuner I2C address + * only needed when tuner is behind demod I2C-gate + */ + u8 tuner_i2c_addr; + + /* + * TS settings + */ +#define HD29L2_TS_SERIAL 0x00 +#define HD29L2_TS_PARALLEL 0x80 +#define HD29L2_TS_CLK_NORMAL 0x40 +#define HD29L2_TS_CLK_INVERTED 0x00 +#define HD29L2_TS_CLK_GATED 0x20 +#define HD29L2_TS_CLK_FREE 0x00 + u8 ts_mode; +}; + + +#if defined(CONFIG_DVB_HD29L2) || \ + (defined(CONFIG_DVB_HD29L2_MODULE) && defined(MODULE)) +extern struct dvb_frontend *hd29l2_attach(const struct hd29l2_config *config, + struct i2c_adapter *i2c); +#else +static inline struct dvb_frontend *hd29l2_attach( +const struct hd29l2_config *config, struct i2c_adapter *i2c) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} +#endif + +#endif /* HD29L2_H */ diff --git a/drivers/media/dvb/frontends/hd29l2_priv.h b/drivers/media/dvb/frontends/hd29l2_priv.h new file mode 100644 index 000000000000..ba16dc3ec2bd --- /dev/null +++ b/drivers/media/dvb/frontends/hd29l2_priv.h @@ -0,0 +1,314 @@ +/* + * HDIC HD29L2 DMB-TH demodulator driver + * + * Copyright (C) 2011 Metropolia University of Applied Sciences, Electria R&D + * + * Author: Antti Palosaari <crope@iki.fi> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef HD29L2_PRIV +#define HD29L2_PRIV + +#include <linux/dvb/version.h> +#include "dvb_frontend.h" +#include "dvb_math.h" +#include "hd29l2.h" + +#define LOG_PREFIX "hd29l2" + +#undef dbg +#define dbg(f, arg...) \ + if (hd29l2_debug) \ + printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg) +#undef err +#define err(f, arg...) printk(KERN_ERR LOG_PREFIX": " f "\n" , ## arg) +#undef info +#define info(f, arg...) printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg) +#undef warn +#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg) + +#define HD29L2_XTAL 30400000 /* Hz */ + + +#define HD29L2_QAM4NR 0x00 +#define HD29L2_QAM4 0x01 +#define HD29L2_QAM16 0x02 +#define HD29L2_QAM32 0x03 +#define HD29L2_QAM64 0x04 + +#define HD29L2_CODE_RATE_04 0x00 +#define HD29L2_CODE_RATE_06 0x08 +#define HD29L2_CODE_RATE_08 0x10 + +#define HD29L2_PN945 0x00 +#define HD29L2_PN595 0x01 +#define HD29L2_PN420 0x02 + +#define HD29L2_CARRIER_SINGLE 0x00 +#define HD29L2_CARRIER_MULTI 0x01 + +#define HD29L2_INTERLEAVER_720 0x00 +#define HD29L2_INTERLEAVER_420 0x01 + +struct reg_val { + u8 reg; + u8 val; +}; + +struct reg_mod_vals { + u8 reg; + u8 val[5]; +}; + +struct hd29l2_priv { + struct i2c_adapter *i2c; + struct dvb_frontend fe; + struct hd29l2_config cfg; + u8 tuner_i2c_addr_programmed:1; + + fe_status_t fe_status; +}; + +static const struct reg_mod_vals reg_mod_vals_tab[] = { + /* REG, QAM4NR, QAM4,QAM16,QAM32,QAM64 */ + { 0x01, { 0x10, 0x10, 0x10, 0x10, 0x10 } }, + { 0x02, { 0x07, 0x07, 0x07, 0x07, 0x07 } }, + { 0x03, { 0x10, 0x10, 0x10, 0x10, 0x10 } }, + { 0x04, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 0x05, { 0x61, 0x60, 0x60, 0x61, 0x60 } }, + { 0x06, { 0xff, 0xff, 0xff, 0xff, 0xff } }, + { 0x07, { 0xff, 0xff, 0xff, 0xff, 0xff } }, + { 0x08, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 0x09, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 0x0a, { 0x15, 0x15, 0x03, 0x03, 0x03 } }, + { 0x0d, { 0x78, 0x78, 0x88, 0x78, 0x78 } }, + { 0x0e, { 0xa0, 0x90, 0xa0, 0xa0, 0xa0 } }, + { 0x0f, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 0x10, { 0xa0, 0xa0, 0x58, 0x38, 0x38 } }, + { 0x11, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 0x12, { 0x5a, 0x5a, 0x5a, 0x5a, 0x5a } }, + { 0x13, { 0xa2, 0xa2, 0xa2, 0xa2, 0xa2 } }, + { 0x17, { 0x40, 0x40, 0x40, 0x40, 0x40 } }, + { 0x18, { 0x21, 0x21, 0x42, 0x52, 0x42 } }, + { 0x19, { 0x21, 0x21, 0x62, 0x72, 0x62 } }, + { 0x1a, { 0x32, 0x43, 0xa9, 0xb9, 0xa9 } }, + { 0x1b, { 0x32, 0x43, 0xb9, 0xd8, 0xb9 } }, + { 0x1c, { 0x02, 0x02, 0x03, 0x02, 0x03 } }, + { 0x1d, { 0x0c, 0x0c, 0x01, 0x02, 0x02 } }, + { 0x1e, { 0x02, 0x02, 0x02, 0x01, 0x02 } }, + { 0x1f, { 0x02, 0x02, 0x01, 0x02, 0x04 } }, + { 0x20, { 0x01, 0x02, 0x01, 0x01, 0x01 } }, + { 0x21, { 0x08, 0x08, 0x0a, 0x0a, 0x0a } }, + { 0x22, { 0x06, 0x06, 0x04, 0x05, 0x05 } }, + { 0x23, { 0x06, 0x06, 0x05, 0x03, 0x05 } }, + { 0x24, { 0x08, 0x08, 0x05, 0x07, 0x07 } }, + { 0x25, { 0x16, 0x10, 0x10, 0x0a, 0x10 } }, + { 0x26, { 0x14, 0x14, 0x04, 0x04, 0x04 } }, + { 0x27, { 0x58, 0x58, 0x58, 0x5c, 0x58 } }, + { 0x28, { 0x0a, 0x0a, 0x0a, 0x0a, 0x0a } }, + { 0x29, { 0x0a, 0x0a, 0x0a, 0x0a, 0x0a } }, + { 0x2a, { 0x08, 0x0a, 0x08, 0x08, 0x08 } }, + { 0x2b, { 0x08, 0x08, 0x08, 0x08, 0x08 } }, + { 0x2c, { 0x06, 0x06, 0x06, 0x06, 0x06 } }, + { 0x2d, { 0x05, 0x06, 0x06, 0x06, 0x06 } }, + { 0x2e, { 0x21, 0x21, 0x21, 0x21, 0x21 } }, + { 0x2f, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 0x30, { 0x14, 0x14, 0x14, 0x14, 0x14 } }, + { 0x33, { 0xb7, 0xb7, 0xb7, 0xb7, 0xb7 } }, + { 0x34, { 0x81, 0x81, 0x81, 0x81, 0x81 } }, + { 0x35, { 0x80, 0x80, 0x80, 0x80, 0x80 } }, + { 0x37, { 0x70, 0x70, 0x70, 0x70, 0x70 } }, + { 0x38, { 0x04, 0x04, 0x02, 0x02, 0x02 } }, + { 0x39, { 0x07, 0x07, 0x05, 0x05, 0x05 } }, + { 0x3a, { 0x06, 0x06, 0x06, 0x06, 0x06 } }, + { 0x3b, { 0x03, 0x03, 0x03, 0x03, 0x03 } }, + { 0x3c, { 0x07, 0x06, 0x04, 0x04, 0x04 } }, + { 0x3d, { 0xf0, 0xf0, 0xf0, 0xf0, 0x80 } }, + { 0x3e, { 0x60, 0x60, 0x60, 0x60, 0xff } }, + { 0x3f, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 0x40, { 0x5b, 0x5b, 0x5b, 0x57, 0x50 } }, + { 0x41, { 0x30, 0x30, 0x30, 0x30, 0x18 } }, + { 0x42, { 0x20, 0x20, 0x20, 0x00, 0x30 } }, + { 0x43, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 0x44, { 0x3f, 0x3f, 0x3f, 0x3f, 0x3f } }, + { 0x45, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 0x46, { 0x0a, 0x0a, 0x0a, 0x0a, 0x0a } }, + { 0x47, { 0x00, 0x00, 0x95, 0x00, 0x95 } }, + { 0x48, { 0xc0, 0xc0, 0xc0, 0xc0, 0xc0 } }, + { 0x49, { 0xc0, 0xc0, 0xc0, 0xc0, 0xc0 } }, + { 0x4a, { 0x40, 0x40, 0x33, 0x11, 0x11 } }, + { 0x4b, { 0x40, 0x40, 0x00, 0x00, 0x00 } }, + { 0x4c, { 0x40, 0x40, 0x99, 0x11, 0x11 } }, + { 0x4d, { 0x40, 0x40, 0x00, 0x00, 0x00 } }, + { 0x4e, { 0x40, 0x40, 0x66, 0x77, 0x77 } }, + { 0x4f, { 0x40, 0x40, 0x00, 0x00, 0x00 } }, + { 0x50, { 0x40, 0x40, 0x88, 0x33, 0x11 } }, + { 0x51, { 0x40, 0x40, 0x00, 0x00, 0x00 } }, + { 0x52, { 0x40, 0x40, 0x88, 0x02, 0x02 } }, + { 0x53, { 0x40, 0x40, 0x00, 0x02, 0x02 } }, + { 0x54, { 0x00, 0x00, 0x88, 0x33, 0x33 } }, + { 0x55, { 0x40, 0x40, 0x00, 0x00, 0x00 } }, + { 0x56, { 0x00, 0x00, 0x00, 0x0b, 0x00 } }, + { 0x57, { 0x40, 0x40, 0x0a, 0x0b, 0x0a } }, + { 0x58, { 0xaa, 0x00, 0x00, 0x00, 0x00 } }, + { 0x59, { 0x7a, 0x40, 0x02, 0x02, 0x02 } }, + { 0x5a, { 0x18, 0x18, 0x01, 0x01, 0x01 } }, + { 0x5b, { 0x18, 0x18, 0x01, 0x01, 0x01 } }, + { 0x5c, { 0x18, 0x18, 0x01, 0x01, 0x01 } }, + { 0x5d, { 0x18, 0x18, 0x01, 0x01, 0x01 } }, + { 0x5e, { 0xc0, 0xc0, 0xc0, 0xff, 0xc0 } }, + { 0x5f, { 0xc0, 0xc0, 0xc0, 0xff, 0xc0 } }, + { 0x60, { 0x40, 0x40, 0x00, 0x30, 0x30 } }, + { 0x61, { 0x40, 0x40, 0x10, 0x30, 0x30 } }, + { 0x62, { 0x40, 0x40, 0x00, 0x30, 0x30 } }, + { 0x63, { 0x40, 0x40, 0x05, 0x30, 0x30 } }, + { 0x64, { 0x40, 0x40, 0x06, 0x00, 0x30 } }, + { 0x65, { 0x40, 0x40, 0x06, 0x08, 0x30 } }, + { 0x66, { 0x40, 0x40, 0x00, 0x00, 0x20 } }, + { 0x67, { 0x40, 0x40, 0x01, 0x04, 0x20 } }, + { 0x68, { 0x00, 0x00, 0x30, 0x00, 0x20 } }, + { 0x69, { 0xa0, 0xa0, 0x00, 0x08, 0x20 } }, + { 0x6a, { 0x00, 0x00, 0x30, 0x00, 0x25 } }, + { 0x6b, { 0xa0, 0xa0, 0x00, 0x06, 0x25 } }, + { 0x6c, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 0x6d, { 0xa0, 0x60, 0x0c, 0x03, 0x0c } }, + { 0x6e, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 0x6f, { 0xa0, 0x60, 0x04, 0x01, 0x04 } }, + { 0x70, { 0x58, 0x58, 0xaa, 0xaa, 0xaa } }, + { 0x71, { 0x58, 0x58, 0xaa, 0xaa, 0xaa } }, + { 0x72, { 0x58, 0x58, 0xff, 0xff, 0xff } }, + { 0x73, { 0x58, 0x58, 0xff, 0xff, 0xff } }, + { 0x74, { 0x06, 0x06, 0x09, 0x05, 0x05 } }, + { 0x75, { 0x06, 0x06, 0x0a, 0x10, 0x10 } }, + { 0x76, { 0x10, 0x10, 0x06, 0x0a, 0x0a } }, + { 0x77, { 0x12, 0x18, 0x28, 0x10, 0x28 } }, + { 0x78, { 0xf8, 0xf8, 0xf8, 0xf8, 0xf8 } }, + { 0x79, { 0x15, 0x15, 0x03, 0x03, 0x03 } }, + { 0x7a, { 0x02, 0x02, 0x01, 0x04, 0x03 } }, + { 0x7b, { 0x01, 0x02, 0x03, 0x03, 0x03 } }, + { 0x7c, { 0x28, 0x28, 0x28, 0x28, 0x28 } }, + { 0x7f, { 0x25, 0x92, 0x5f, 0x17, 0x2d } }, + { 0x80, { 0x64, 0x64, 0x64, 0x74, 0x64 } }, + { 0x83, { 0x06, 0x03, 0x04, 0x04, 0x04 } }, + { 0x84, { 0xff, 0xff, 0xff, 0xff, 0xff } }, + { 0x85, { 0x05, 0x05, 0x05, 0x05, 0x05 } }, + { 0x86, { 0x00, 0x00, 0x11, 0x11, 0x11 } }, + { 0x87, { 0x03, 0x03, 0x03, 0x03, 0x03 } }, + { 0x88, { 0x09, 0x09, 0x09, 0x09, 0x09 } }, + { 0x89, { 0x20, 0x20, 0x30, 0x20, 0x20 } }, + { 0x8a, { 0x03, 0x03, 0x02, 0x03, 0x02 } }, + { 0x8b, { 0x00, 0x07, 0x09, 0x00, 0x09 } }, + { 0x8c, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 0x8d, { 0x4f, 0x4f, 0x4f, 0x3f, 0x4f } }, + { 0x8e, { 0xf0, 0xf0, 0x60, 0xf0, 0xa0 } }, + { 0x8f, { 0xe8, 0xe8, 0xe8, 0xe8, 0xe8 } }, + { 0x90, { 0x10, 0x10, 0x10, 0x10, 0x10 } }, + { 0x91, { 0x40, 0x40, 0x70, 0x70, 0x10 } }, + { 0x92, { 0x00, 0x00, 0x00, 0x00, 0x04 } }, + { 0x93, { 0x60, 0x60, 0x60, 0x60, 0x60 } }, + { 0x94, { 0x00, 0x00, 0x00, 0x00, 0x03 } }, + { 0x95, { 0x09, 0x09, 0x47, 0x47, 0x47 } }, + { 0x96, { 0x80, 0xa0, 0xa0, 0x40, 0xa0 } }, + { 0x97, { 0x60, 0x60, 0x60, 0x60, 0x60 } }, + { 0x98, { 0x50, 0x50, 0x50, 0x30, 0x50 } }, + { 0x99, { 0x10, 0x10, 0x10, 0x10, 0x10 } }, + { 0x9a, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 0x9b, { 0x40, 0x40, 0x40, 0x30, 0x40 } }, + { 0x9c, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 0xa0, { 0xf0, 0xf0, 0xf0, 0xf0, 0xf0 } }, + { 0xa1, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 0xa2, { 0x30, 0x30, 0x00, 0x30, 0x00 } }, + { 0xa3, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 0xa4, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 0xa5, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 0xa6, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 0xa7, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 0xa8, { 0x77, 0x77, 0x77, 0x77, 0x77 } }, + { 0xa9, { 0x02, 0x02, 0x02, 0x02, 0x02 } }, + { 0xaa, { 0x40, 0x40, 0x40, 0x40, 0x40 } }, + { 0xac, { 0x1f, 0x1f, 0x1f, 0x1f, 0x1f } }, + { 0xad, { 0x14, 0x14, 0x14, 0x14, 0x14 } }, + { 0xae, { 0x78, 0x78, 0x78, 0x78, 0x78 } }, + { 0xaf, { 0x06, 0x06, 0x06, 0x06, 0x07 } }, + { 0xb0, { 0x1b, 0x1b, 0x1b, 0x19, 0x1b } }, + { 0xb1, { 0x18, 0x17, 0x17, 0x18, 0x17 } }, + { 0xb2, { 0x35, 0x82, 0x82, 0x38, 0x82 } }, + { 0xb3, { 0xb6, 0xce, 0xc7, 0x5c, 0xb0 } }, + { 0xb4, { 0x3f, 0x3e, 0x3e, 0x3f, 0x3e } }, + { 0xb5, { 0x70, 0x58, 0x50, 0x68, 0x50 } }, + { 0xb6, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 0xb7, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 0xb8, { 0x03, 0x03, 0x01, 0x01, 0x01 } }, + { 0xb9, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 0xba, { 0x06, 0x06, 0x0a, 0x05, 0x0a } }, + { 0xbb, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 0xbc, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 0xbd, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 0xbe, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 0xbf, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 0xc0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 0xc1, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 0xc2, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 0xc3, { 0x00, 0x00, 0x88, 0x66, 0x88 } }, + { 0xc4, { 0x10, 0x10, 0x00, 0x00, 0x00 } }, + { 0xc5, { 0x00, 0x00, 0x44, 0x60, 0x44 } }, + { 0xc6, { 0x10, 0x0a, 0x00, 0x00, 0x00 } }, + { 0xc7, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 0xc8, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 0xc9, { 0x90, 0x04, 0x00, 0x00, 0x00 } }, + { 0xca, { 0x90, 0x08, 0x01, 0x01, 0x01 } }, + { 0xcb, { 0xa0, 0x04, 0x00, 0x44, 0x00 } }, + { 0xcc, { 0xa0, 0x10, 0x03, 0x00, 0x03 } }, + { 0xcd, { 0x06, 0x06, 0x06, 0x05, 0x06 } }, + { 0xce, { 0x05, 0x05, 0x01, 0x01, 0x01 } }, + { 0xcf, { 0x40, 0x20, 0x18, 0x18, 0x18 } }, + { 0xd0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 0xd1, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 0xd2, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 0xd3, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 0xd4, { 0x05, 0x05, 0x05, 0x05, 0x05 } }, + { 0xd5, { 0x05, 0x05, 0x05, 0x03, 0x05 } }, + { 0xd6, { 0xac, 0x22, 0xca, 0x8f, 0xca } }, + { 0xd7, { 0x20, 0x20, 0x20, 0x20, 0x20 } }, + { 0xd8, { 0x01, 0x01, 0x01, 0x01, 0x01 } }, + { 0xd9, { 0x00, 0x00, 0x0f, 0x00, 0x0f } }, + { 0xda, { 0x00, 0xff, 0xff, 0x0e, 0xff } }, + { 0xdb, { 0x0a, 0x0a, 0x0a, 0x0a, 0x0a } }, + { 0xdc, { 0x0a, 0x0a, 0x0a, 0x0a, 0x0a } }, + { 0xdd, { 0x05, 0x05, 0x05, 0x05, 0x05 } }, + { 0xde, { 0x0a, 0x0a, 0x0a, 0x0a, 0x0a } }, + { 0xdf, { 0x42, 0x42, 0x44, 0x44, 0x04 } }, + { 0xe0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 0xe1, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 0xe2, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 0xe3, { 0x00, 0x00, 0x26, 0x06, 0x26 } }, + { 0xe4, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 0xe5, { 0x01, 0x0a, 0x01, 0x01, 0x01 } }, + { 0xe6, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 0xe7, { 0x08, 0x08, 0x08, 0x08, 0x08 } }, + { 0xe8, { 0x63, 0x63, 0x63, 0x63, 0x63 } }, + { 0xe9, { 0x59, 0x59, 0x59, 0x59, 0x59 } }, + { 0xea, { 0x80, 0x80, 0x20, 0x80, 0x80 } }, + { 0xeb, { 0x37, 0x37, 0x78, 0x37, 0x77 } }, + { 0xec, { 0x1f, 0x1f, 0x25, 0x25, 0x25 } }, + { 0xed, { 0x0a, 0x0a, 0x0a, 0x0a, 0x0a } }, + { 0xee, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 0xef, { 0x70, 0x70, 0x58, 0x38, 0x58 } }, + { 0xf0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, +}; + +#endif /* HD29L2_PRIV */ diff --git a/drivers/media/dvb/frontends/it913x-fe-priv.h b/drivers/media/dvb/frontends/it913x-fe-priv.h index 1c6fb4b66255..93b086ea7e1c 100644 --- a/drivers/media/dvb/frontends/it913x-fe-priv.h +++ b/drivers/media/dvb/frontends/it913x-fe-priv.h @@ -22,126 +22,126 @@ struct adctable { u32 adcFrequency; /* clock and coeff tables only table 3 is used with IT9137*/ /* TODO other tables relate AF9035 may be removed */ static struct adctable tab1[] = { - { 20156250, BANDWIDTH_6_MHZ, + { 20156250, 6000000, 0x02b8ba6e, 0x015c5d37, 0x00ae340d, 0x00ae2e9b, 0x00ae292a, 0x015c5d37, 0x00ae2e9b, 0x0057174e, 0x02f1, 0x015c }, - { 20156250, BANDWIDTH_7_MHZ, + { 20156250, 7000000, 0x032cd980, 0x01966cc0, 0x00cb3cba, 0x00cb3660, 0x00cb3007, 0x01966cc0, 0x00cb3660, 0x00659b30, 0x0285, 0x0196 }, - { 20156250, BANDWIDTH_8_MHZ, + { 20156250, 8000000, 0x03a0f893, 0x01d07c49, 0x00e84567, 0x00e83e25, 0x00e836e3, 0x01d07c49, 0x00e83e25, 0x00741f12, 0x0234, 0x01d0 }, - { 20156250, BANDWIDTH_5_MHZ, + { 20156250, 5000000, 0x02449b5c, 0x01224dae, 0x00912b60, 0x009126d7, 0x0091224e, 0x01224dae, 0x009126d7, 0x0048936b, 0x0387, 0x0122 } }; static struct adctable tab2[] = { - { 20187500, BANDWIDTH_6_MHZ, + { 20187500, 6000000, 0x02b7a654, 0x015bd32a, 0x00adef04, 0x00ade995, 0x00ade426, 0x015bd32a, 0x00ade995, 0x0056f4ca, 0x02f2, 0x015c }, - { 20187500, BANDWIDTH_7_MHZ, + { 20187500, 7000000, 0x032b9761, 0x0195cbb1, 0x00caec30, 0x00cae5d8, 0x00cadf81, 0x0195cbb1, 0x00cae5d8, 0x006572ec, 0x0286, 0x0196 }, - { 20187500, BANDWIDTH_8_MHZ, + { 20187500, 8000000, 0x039f886f, 0x01cfc438, 0x00e7e95b, 0x00e7e21c, 0x00e7dadd, 0x01cfc438, 0x00e7e21c, 0x0073f10e, 0x0235, 0x01d0 }, - { 20187500, BANDWIDTH_5_MHZ, + { 20187500, 5000000, 0x0243b546, 0x0121daa3, 0x0090f1d9, 0x0090ed51, 0x0090e8ca, 0x0121daa3, 0x0090ed51, 0x004876a9, 0x0388, 0x0122 } }; static struct adctable tab3[] = { - { 20250000, BANDWIDTH_6_MHZ, + { 20250000, 6000000, 0x02b580ad, 0x015ac057, 0x00ad6597, 0x00ad602b, 0x00ad5ac1, 0x015ac057, 0x00ad602b, 0x0056b016, 0x02f4, 0x015b }, - { 20250000, BANDWIDTH_7_MHZ, + { 20250000, 7000000, 0x03291620, 0x01948b10, 0x00ca4bda, 0x00ca4588, 0x00ca3f36, 0x01948b10, 0x00ca4588, 0x006522c4, 0x0288, 0x0195 }, - { 20250000, BANDWIDTH_8_MHZ, + { 20250000, 8000000, 0x039cab92, 0x01ce55c9, 0x00e7321e, 0x00e72ae4, 0x00e723ab, 0x01ce55c9, 0x00e72ae4, 0x00739572, 0x0237, 0x01ce }, - { 20250000, BANDWIDTH_5_MHZ, + { 20250000, 5000000, 0x0241eb3b, 0x0120f59e, 0x00907f53, 0x00907acf, 0x0090764b, 0x0120f59e, 0x00907acf, 0x00483d67, 0x038b, 0x0121 } }; static struct adctable tab4[] = { - { 20583333, BANDWIDTH_6_MHZ, + { 20583333, 6000000, 0x02aa4598, 0x015522cc, 0x00aa96bb, 0x00aa9166, 0x00aa8c12, 0x015522cc, 0x00aa9166, 0x005548b3, 0x0300, 0x0155 }, - { 20583333, BANDWIDTH_7_MHZ, + { 20583333, 7000000, 0x031bfbdc, 0x018dfdee, 0x00c7052f, 0x00c6fef7, 0x00c6f8bf, 0x018dfdee, 0x00c6fef7, 0x00637f7b, 0x0293, 0x018e }, - { 20583333, BANDWIDTH_8_MHZ, + { 20583333, 8000000, 0x038db21f, 0x01c6d910, 0x00e373a3, 0x00e36c88, 0x00e3656d, 0x01c6d910, 0x00e36c88, 0x0071b644, 0x0240, 0x01c7 }, - { 20583333, BANDWIDTH_5_MHZ, + { 20583333, 5000000, 0x02388f54, 0x011c47aa, 0x008e2846, 0x008e23d5, 0x008e1f64, 0x011c47aa, 0x008e23d5, 0x004711ea, 0x039a, 0x011c } }; static struct adctable tab5[] = { - { 20416667, BANDWIDTH_6_MHZ, + { 20416667, 6000000, 0x02afd765, 0x0157ebb3, 0x00abfb39, 0x00abf5d9, 0x00abf07a, 0x0157ebb3, 0x00abf5d9, 0x0055faed, 0x02fa, 0x0158 }, - { 20416667, BANDWIDTH_7_MHZ, + { 20416667, 7000000, 0x03227b4b, 0x01913da6, 0x00c8a518, 0x00c89ed3, 0x00c8988e, 0x01913da6, 0x00c89ed3, 0x00644f69, 0x028d, 0x0191 }, - { 20416667, BANDWIDTH_8_MHZ, + { 20416667, 8000000, 0x03951f32, 0x01ca8f99, 0x00e54ef7, 0x00e547cc, 0x00e540a2, 0x01ca8f99, 0x00e547cc, 0x0072a3e6, 0x023c, 0x01cb }, - { 20416667, BANDWIDTH_5_MHZ, + { 20416667, 5000000, 0x023d337f, 0x011e99c0, 0x008f515a, 0x008f4ce0, 0x008f4865, 0x011e99c0, 0x008f4ce0, 0x0047a670, 0x0393, 0x011f } }; static struct adctable tab6[] = { - { 20480000, BANDWIDTH_6_MHZ, + { 20480000, 6000000, 0x02adb6db, 0x0156db6e, 0x00ab7312, 0x00ab6db7, 0x00ab685c, 0x0156db6e, 0x00ab6db7, 0x0055b6db, 0x02fd, 0x0157 }, - { 20480000, BANDWIDTH_7_MHZ, + { 20480000, 7000000, 0x03200000, 0x01900000, 0x00c80640, 0x00c80000, 0x00c7f9c0, 0x01900000, 0x00c80000, 0x00640000, 0x028f, 0x0190 }, - { 20480000, BANDWIDTH_8_MHZ, + { 20480000, 8000000, 0x03924925, 0x01c92492, 0x00e4996e, 0x00e49249, 0x00e48b25, 0x01c92492, 0x00e49249, 0x00724925, 0x023d, 0x01c9 }, - { 20480000, BANDWIDTH_5_MHZ, + { 20480000, 5000000, 0x023b6db7, 0x011db6db, 0x008edfe5, 0x008edb6e, 0x008ed6f7, 0x011db6db, 0x008edb6e, 0x00476db7, 0x0396, 0x011e } }; static struct adctable tab7[] = { - { 20500000, BANDWIDTH_6_MHZ, + { 20500000, 6000000, 0x02ad0b99, 0x015685cc, 0x00ab4840, 0x00ab42e6, 0x00ab3d8c, 0x015685cc, 0x00ab42e6, 0x0055a173, 0x02fd, 0x0157 }, - { 20500000, BANDWIDTH_7_MHZ, + { 20500000, 7000000, 0x031f3832, 0x018f9c19, 0x00c7d44b, 0x00c7ce0c, 0x00c7c7ce, 0x018f9c19, 0x00c7ce0c, 0x0063e706, 0x0290, 0x0190 }, - { 20500000, BANDWIDTH_8_MHZ, + { 20500000, 8000000, 0x039164cb, 0x01c8b266, 0x00e46056, 0x00e45933, 0x00e45210, 0x01c8b266, 0x00e45933, 0x00722c99, 0x023e, 0x01c9 }, - { 20500000, BANDWIDTH_5_MHZ, + { 20500000, 5000000, 0x023adeff, 0x011d6f80, 0x008ebc36, 0x008eb7c0, 0x008eb34a, 0x011d6f80, 0x008eb7c0, 0x00475be0, 0x0396, 0x011d } }; static struct adctable tab8[] = { - { 20625000, BANDWIDTH_6_MHZ, + { 20625000, 6000000, 0x02a8e4bd, 0x0154725e, 0x00aa3e81, 0x00aa392f, 0x00aa33de, 0x0154725e, 0x00aa392f, 0x00551c98, 0x0302, 0x0154 }, - { 20625000, BANDWIDTH_7_MHZ, + { 20625000, 7000000, 0x031a6032, 0x018d3019, 0x00c69e41, 0x00c6980c, 0x00c691d8, 0x018d3019, 0x00c6980c, 0x00634c06, 0x0294, 0x018d }, - { 20625000, BANDWIDTH_8_MHZ, + { 20625000, 8000000, 0x038bdba6, 0x01c5edd3, 0x00e2fe02, 0x00e2f6ea, 0x00e2efd2, 0x01c5edd3, 0x00e2f6ea, 0x00717b75, 0x0242, 0x01c6 }, - { 20625000, BANDWIDTH_5_MHZ, + { 20625000, 5000000, 0x02376948, 0x011bb4a4, 0x008ddec1, 0x008dda52, 0x008dd5e3, 0x011bb4a4, 0x008dda52, 0x0046ed29, 0x039c, 0x011c } @@ -153,8 +153,7 @@ struct table { }; static struct table fe_clockTable[] = { - {12000000, tab3}, /* FPGA */ - {16384000, tab6}, /* 16.38MHz */ + {12000000, tab3}, /* 12.00MHz */ {20480000, tab6}, /* 20.48MHz */ {36000000, tab3}, /* 36.00MHz */ {30000000, tab1}, /* 30.00MHz */ @@ -164,7 +163,6 @@ static struct table fe_clockTable[] = { {34000000, tab2}, /* 34.00MHz */ {24000000, tab1}, /* 24.00MHz */ {22000000, tab8}, /* 22.00MHz */ - {12000000, tab3} /* 12.00MHz */ }; /* fe get */ @@ -205,6 +203,10 @@ fe_modulation_t fe_con[] = { /* Standard demodulator functions */ static struct it913xset set_solo_fe[] = { + {PRO_LINK, GPIOH5_EN, {0x01}, 0x01}, + {PRO_LINK, GPIOH5_ON, {0x01}, 0x01}, + {PRO_LINK, GPIOH5_O, {0x00}, 0x01}, + {PRO_LINK, GPIOH5_O, {0x01}, 0x01}, {PRO_LINK, DVBT_INTEN, {0x04}, 0x01}, {PRO_LINK, DVBT_ENABLE, {0x05}, 0x01}, {PRO_DMOD, MP2IF_MPEG_PAR_MODE, {0x00}, 0x01}, @@ -228,13 +230,127 @@ static struct it913xset init_1[] = { {PRO_LINK, LOCK3_OUT, {0x01}, 0x01}, {PRO_LINK, PADMISCDRSR, {0x01}, 0x01}, {PRO_LINK, PADMISCDR2, {0x00}, 0x01}, + {PRO_DMOD, 0xec57, {0x00, 0x00}, 0x02}, {PRO_LINK, PADMISCDR4, {0x00}, 0x01}, /* Power up */ {PRO_LINK, PADMISCDR8, {0x00}, 0x01}, {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */ }; -/* ---------IT9137 0x38 tuner init---------- */ -static struct it913xset it9137_set[] = { + +/* Version 1 types */ +static struct it913xset it9135_v1[] = { + {PRO_DMOD, 0x0051, {0x01}, 0x01}, + {PRO_DMOD, 0x0070, {0x0a}, 0x01}, + {PRO_DMOD, 0x007e, {0x04}, 0x01}, + {PRO_DMOD, 0x0081, {0x0a}, 0x01}, + {PRO_DMOD, 0x008a, {0x01}, 0x01}, + {PRO_DMOD, 0x008e, {0x01}, 0x01}, + {PRO_DMOD, 0x0092, {0x06}, 0x01}, + {PRO_DMOD, 0x0099, {0x01}, 0x01}, + {PRO_DMOD, 0x009f, {0xe1}, 0x01}, + {PRO_DMOD, 0x00a0, {0xcf}, 0x01}, + {PRO_DMOD, 0x00a3, {0x01}, 0x01}, + {PRO_DMOD, 0x00a5, {0x01}, 0x01}, + {PRO_DMOD, 0x00a6, {0x01}, 0x01}, + {PRO_DMOD, 0x00a9, {0x00}, 0x01}, + {PRO_DMOD, 0x00aa, {0x01}, 0x01}, + {PRO_DMOD, 0x00b0, {0x01}, 0x01}, + {PRO_DMOD, 0x00c2, {0x05}, 0x01}, + {PRO_DMOD, 0x00c6, {0x19}, 0x01}, + {PRO_DMOD, 0xf000, {0x0f}, 0x01}, + {PRO_DMOD, 0xf016, {0x10}, 0x01}, + {PRO_DMOD, 0xf017, {0x04}, 0x01}, + {PRO_DMOD, 0xf018, {0x05}, 0x01}, + {PRO_DMOD, 0xf019, {0x04}, 0x01}, + {PRO_DMOD, 0xf01a, {0x05}, 0x01}, + {PRO_DMOD, 0xf021, {0x03}, 0x01}, + {PRO_DMOD, 0xf022, {0x0a}, 0x01}, + {PRO_DMOD, 0xf023, {0x0a}, 0x01}, + {PRO_DMOD, 0xf02b, {0x00}, 0x01}, + {PRO_DMOD, 0xf02c, {0x01}, 0x01}, + {PRO_DMOD, 0xf064, {0x03}, 0x01}, + {PRO_DMOD, 0xf065, {0xf9}, 0x01}, + {PRO_DMOD, 0xf066, {0x03}, 0x01}, + {PRO_DMOD, 0xf067, {0x01}, 0x01}, + {PRO_DMOD, 0xf06f, {0xe0}, 0x01}, + {PRO_DMOD, 0xf070, {0x03}, 0x01}, + {PRO_DMOD, 0xf072, {0x0f}, 0x01}, + {PRO_DMOD, 0xf073, {0x03}, 0x01}, + {PRO_DMOD, 0xf078, {0x00}, 0x01}, + {PRO_DMOD, 0xf087, {0x00}, 0x01}, + {PRO_DMOD, 0xf09b, {0x3f}, 0x01}, + {PRO_DMOD, 0xf09c, {0x00}, 0x01}, + {PRO_DMOD, 0xf09d, {0x20}, 0x01}, + {PRO_DMOD, 0xf09e, {0x00}, 0x01}, + {PRO_DMOD, 0xf09f, {0x0c}, 0x01}, + {PRO_DMOD, 0xf0a0, {0x00}, 0x01}, + {PRO_DMOD, 0xf130, {0x04}, 0x01}, + {PRO_DMOD, 0xf132, {0x04}, 0x01}, + {PRO_DMOD, 0xf144, {0x1a}, 0x01}, + {PRO_DMOD, 0xf146, {0x00}, 0x01}, + {PRO_DMOD, 0xf14a, {0x01}, 0x01}, + {PRO_DMOD, 0xf14c, {0x00}, 0x01}, + {PRO_DMOD, 0xf14d, {0x00}, 0x01}, + {PRO_DMOD, 0xf14f, {0x04}, 0x01}, + {PRO_DMOD, 0xf158, {0x7f}, 0x01}, + {PRO_DMOD, 0xf15a, {0x00}, 0x01}, + {PRO_DMOD, 0xf15b, {0x08}, 0x01}, + {PRO_DMOD, 0xf15d, {0x03}, 0x01}, + {PRO_DMOD, 0xf15e, {0x05}, 0x01}, + {PRO_DMOD, 0xf163, {0x05}, 0x01}, + {PRO_DMOD, 0xf166, {0x01}, 0x01}, + {PRO_DMOD, 0xf167, {0x40}, 0x01}, + {PRO_DMOD, 0xf168, {0x0f}, 0x01}, + {PRO_DMOD, 0xf17a, {0x00}, 0x01}, + {PRO_DMOD, 0xf17b, {0x00}, 0x01}, + {PRO_DMOD, 0xf183, {0x01}, 0x01}, + {PRO_DMOD, 0xf19d, {0x40}, 0x01}, + {PRO_DMOD, 0xf1bc, {0x36}, 0x01}, + {PRO_DMOD, 0xf1bd, {0x00}, 0x01}, + {PRO_DMOD, 0xf1cb, {0xa0}, 0x01}, + {PRO_DMOD, 0xf1cc, {0x01}, 0x01}, + {PRO_DMOD, 0xf204, {0x10}, 0x01}, + {PRO_DMOD, 0xf214, {0x00}, 0x01}, + {PRO_DMOD, 0xf40e, {0x0a}, 0x01}, + {PRO_DMOD, 0xf40f, {0x40}, 0x01}, + {PRO_DMOD, 0xf410, {0x08}, 0x01}, + {PRO_DMOD, 0xf55f, {0x0a}, 0x01}, + {PRO_DMOD, 0xf561, {0x15}, 0x01}, + {PRO_DMOD, 0xf562, {0x20}, 0x01}, + {PRO_DMOD, 0xf5df, {0xfb}, 0x01}, + {PRO_DMOD, 0xf5e0, {0x00}, 0x01}, + {PRO_DMOD, 0xf5e3, {0x09}, 0x01}, + {PRO_DMOD, 0xf5e4, {0x01}, 0x01}, + {PRO_DMOD, 0xf5e5, {0x01}, 0x01}, + {PRO_DMOD, 0xf5f8, {0x01}, 0x01}, + {PRO_DMOD, 0xf5fd, {0x01}, 0x01}, + {PRO_DMOD, 0xf600, {0x05}, 0x01}, + {PRO_DMOD, 0xf601, {0x08}, 0x01}, + {PRO_DMOD, 0xf602, {0x0b}, 0x01}, + {PRO_DMOD, 0xf603, {0x0e}, 0x01}, + {PRO_DMOD, 0xf604, {0x11}, 0x01}, + {PRO_DMOD, 0xf605, {0x14}, 0x01}, + {PRO_DMOD, 0xf606, {0x17}, 0x01}, + {PRO_DMOD, 0xf607, {0x1f}, 0x01}, + {PRO_DMOD, 0xf60e, {0x00}, 0x01}, + {PRO_DMOD, 0xf60f, {0x04}, 0x01}, + {PRO_DMOD, 0xf610, {0x32}, 0x01}, + {PRO_DMOD, 0xf611, {0x10}, 0x01}, + {PRO_DMOD, 0xf707, {0xfc}, 0x01}, + {PRO_DMOD, 0xf708, {0x00}, 0x01}, + {PRO_DMOD, 0xf709, {0x37}, 0x01}, + {PRO_DMOD, 0xf70a, {0x00}, 0x01}, + {PRO_DMOD, 0xf78b, {0x01}, 0x01}, + {PRO_DMOD, 0xf80f, {0x40}, 0x01}, + {PRO_DMOD, 0xf810, {0x54}, 0x01}, + {PRO_DMOD, 0xf811, {0x5a}, 0x01}, + {PRO_DMOD, 0xf905, {0x01}, 0x01}, + {PRO_DMOD, 0xfb06, {0x03}, 0x01}, + {PRO_DMOD, 0xfd8b, {0x00}, 0x01}, + {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */ +}; + +static struct it913xset it9135_38[] = { {PRO_DMOD, 0x0043, {0x00}, 0x01}, {PRO_DMOD, 0x0046, {0x38}, 0x01}, {PRO_DMOD, 0x0051, {0x01}, 0x01}, @@ -244,7 +360,7 @@ static struct it913xset it9137_set[] = { {PRO_DMOD, 0x0075, {0x8c, 0x8c, 0x8c, 0xc8, 0x01}, 0x05}, {PRO_DMOD, 0x007e, {0x04, 0x00}, 0x02}, {PRO_DMOD, 0x0081, { 0x0a, 0x12, 0x02, 0x0a, 0x03, 0xc8, 0xb8, - 0xd0, 0xc3, 0x01 }, 0x0a}, + 0xd0, 0xc3, 0x01}, 0x0a}, {PRO_DMOD, 0x008e, {0x01}, 0x01}, {PRO_DMOD, 0x0092, {0x06, 0x00, 0x00, 0x00, 0x00}, 0x05}, {PRO_DMOD, 0x0099, {0x01}, 0x01}, @@ -262,15 +378,25 @@ static struct it913xset it9137_set[] = { {PRO_DMOD, 0x00f3, {0x05, 0x8c, 0x8c}, 0x03}, {PRO_DMOD, 0x00f8, {0x03, 0x06, 0x06}, 0x03}, {PRO_DMOD, 0x00fc, { 0x02, 0x02, 0x02, 0x09, 0x50, 0x7b, 0x77, - 0x00, 0x02, 0xc8, 0x05, 0x7b }, 0x0c}, + 0x00, 0x02, 0xc8, 0x05, 0x7b}, 0x0c}, {PRO_DMOD, 0x0109, {0x02}, 0x01}, - {PRO_DMOD, 0x0115, {0x0a, 0x03}, 0x02}, - {PRO_DMOD, 0x011a, {0xc8, 0x7b, 0xbc, 0xa0}, 0x04}, + {PRO_DMOD, 0x0115, {0x0a, 0x03, 0x02, 0x80}, 0x04}, + {PRO_DMOD, 0x011a, {0xc8, 0x7b, 0x8a, 0xa0}, 0x04}, {PRO_DMOD, 0x0122, {0x02, 0x18, 0xc3}, 0x03}, {PRO_DMOD, 0x0127, {0x00, 0x07}, 0x02}, {PRO_DMOD, 0x012a, {0x53, 0x51, 0x4e, 0x43}, 0x04}, {PRO_DMOD, 0x0137, {0x01, 0x00, 0x07, 0x00, 0x06}, 0x05}, - {PRO_DMOD, 0x013d, {0x00, 0x01, 0x5b, 0xc8}, 0x04}, + {PRO_DMOD, 0x013d, {0x00, 0x01, 0x5b, 0xc8, 0x59}, 0x05}, + {PRO_DMOD, 0xf000, {0x0f}, 0x01}, + {PRO_DMOD, 0xf016, {0x10, 0x04, 0x05, 0x04, 0x05}, 0x05}, + {PRO_DMOD, 0xf01f, {0x8c, 0x00, 0x03, 0x0a, 0x0a}, 0x05}, + {PRO_DMOD, 0xf029, {0x8c, 0x00, 0x00, 0x01}, 0x04}, + {PRO_DMOD, 0xf064, {0x03, 0xf9, 0x03, 0x01}, 0x04}, + {PRO_DMOD, 0xf06f, {0xe0, 0x03}, 0x02}, + {PRO_DMOD, 0xf072, {0x0f, 0x03}, 0x02}, + {PRO_DMOD, 0xf077, {0x01, 0x00}, 0x02}, + {PRO_DMOD, 0xf085, {0x00, 0x02, 0x00}, 0x03}, + {PRO_DMOD, 0xf09b, {0x3f, 0x00, 0x20, 0x00, 0x0c, 0x00}, 0x06}, {PRO_DMOD, 0xf130, {0x04}, 0x01}, {PRO_DMOD, 0xf132, {0x04}, 0x01}, {PRO_DMOD, 0xf144, {0x1a}, 0x01}, @@ -301,7 +427,7 @@ static struct it913xset it9137_set[] = { {PRO_DMOD, 0xf5f8, {0x01}, 0x01}, {PRO_DMOD, 0xf5fd, {0x01}, 0x01}, {PRO_DMOD, 0xf600, { 0x05, 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x17, - 0x1f }, 0x08}, + 0x1f}, 0x08}, {PRO_DMOD, 0xf60e, {0x00, 0x04, 0x32, 0x10}, 0x04}, {PRO_DMOD, 0xf707, {0xfc, 0x00, 0x37, 0x00}, 0x04}, {PRO_DMOD, 0xf78b, {0x01}, 0x01}, @@ -309,21 +435,605 @@ static struct it913xset it9137_set[] = { {PRO_DMOD, 0xf905, {0x01}, 0x01}, {PRO_DMOD, 0xfb06, {0x03}, 0x01}, {PRO_DMOD, 0xfd8b, {0x00}, 0x01}, - {PRO_LINK, GPIOH5_EN, {0x01}, 0x01}, - {PRO_LINK, GPIOH5_ON, {0x01}, 0x01}, - {PRO_LINK, GPIOH5_O, {0x00}, 0x01}, - {PRO_LINK, GPIOH5_O, {0x01}, 0x01}, - {0xff, 0x0000, {0x00}, 0x00}, /* Terminating Entry */ + {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */ +}; + +static struct it913xset it9135_51[] = { + {PRO_DMOD, 0x0043, {0x00}, 0x01}, + {PRO_DMOD, 0x0046, {0x51}, 0x01}, + {PRO_DMOD, 0x0051, {0x01}, 0x01}, + {PRO_DMOD, 0x005f, {0x00, 0x00}, 0x02}, + {PRO_DMOD, 0x0068, {0x0a}, 0x01}, + {PRO_DMOD, 0x0070, {0x0a, 0x06, 0x02}, 0x03}, + {PRO_DMOD, 0x0075, {0x8c, 0x8c, 0x8c, 0xc8, 0x01}, 0x05}, + {PRO_DMOD, 0x007e, {0x04, 0x00}, 0x02}, + {PRO_DMOD, 0x0081, { 0x0a, 0x12, 0x02, 0x0a, 0x03, 0xc0, 0x96, + 0xcf, 0xc3, 0x01}, 0x0a}, + {PRO_DMOD, 0x008e, {0x01}, 0x01}, + {PRO_DMOD, 0x0092, {0x06, 0x00, 0x00, 0x00, 0x00}, 0x05}, + {PRO_DMOD, 0x0099, {0x01}, 0x01}, + {PRO_DMOD, 0x009b, {0x3c, 0x28}, 0x02}, + {PRO_DMOD, 0x009f, {0xe1, 0xcf}, 0x02}, + {PRO_DMOD, 0x00a3, {0x01, 0x5a, 0x01, 0x01}, 0x04}, + {PRO_DMOD, 0x00a9, {0x00, 0x01}, 0x02}, + {PRO_DMOD, 0x00b0, {0x01}, 0x01}, + {PRO_DMOD, 0x00b3, {0x02, 0x3c}, 0x02}, + {PRO_DMOD, 0x00b6, {0x14}, 0x01}, + {PRO_DMOD, 0x00c0, {0x11, 0x00, 0x05}, 0x03}, + {PRO_DMOD, 0x00c4, {0x00}, 0x01}, + {PRO_DMOD, 0x00c6, {0x19, 0x00}, 0x02}, + {PRO_DMOD, 0x00cc, {0x2e, 0x51, 0x33}, 0x03}, + {PRO_DMOD, 0x00f3, {0x05, 0x8c, 0x8c}, 0x03}, + {PRO_DMOD, 0x00f8, {0x03, 0x06, 0x06}, 0x03}, + {PRO_DMOD, 0x00fc, { 0x03, 0x02, 0x02, 0x09, 0x50, 0x7a, 0x77, + 0x01, 0x02, 0xb0, 0x02, 0x7a}, 0x0c}, + {PRO_DMOD, 0x0109, {0x02}, 0x01}, + {PRO_DMOD, 0x0115, {0x0a, 0x03, 0x02, 0x80}, 0x04}, + {PRO_DMOD, 0x011a, {0xc0, 0x7a, 0xac, 0x8c}, 0x04}, + {PRO_DMOD, 0x0122, {0x02, 0x70, 0xa4}, 0x03}, + {PRO_DMOD, 0x0127, {0x00, 0x07}, 0x02}, + {PRO_DMOD, 0x012a, {0x53, 0x51, 0x4e, 0x43}, 0x04}, + {PRO_DMOD, 0x0137, {0x01, 0x00, 0x07, 0x00, 0x06}, 0x05}, + {PRO_DMOD, 0x013d, {0x00, 0x01, 0x5b, 0xc0, 0x59}, 0x05}, + {PRO_DMOD, 0xf000, {0x0f}, 0x01}, + {PRO_DMOD, 0xf016, {0x10, 0x04, 0x05, 0x04, 0x05}, 0x05}, + {PRO_DMOD, 0xf01f, {0x8c, 0x00, 0x03, 0x0a, 0x0a}, 0x05}, + {PRO_DMOD, 0xf029, {0x8c, 0x00, 0x00, 0x01}, 0x04}, + {PRO_DMOD, 0xf064, {0x03, 0xf9, 0x03, 0x01}, 0x04}, + {PRO_DMOD, 0xf06f, {0xe0, 0x03}, 0x02}, + {PRO_DMOD, 0xf072, {0x0f, 0x03}, 0x02}, + {PRO_DMOD, 0xf077, {0x01, 0x00}, 0x02}, + {PRO_DMOD, 0xf085, {0xc0, 0x01, 0x00}, 0x03}, + {PRO_DMOD, 0xf09b, {0x3f, 0x00, 0x20, 0x00, 0x0c, 0x00}, 0x06}, + {PRO_DMOD, 0xf130, {0x04}, 0x01}, + {PRO_DMOD, 0xf132, {0x04}, 0x01}, + {PRO_DMOD, 0xf144, {0x1a}, 0x01}, + {PRO_DMOD, 0xf146, {0x00}, 0x01}, + {PRO_DMOD, 0xf14a, {0x01}, 0x01}, + {PRO_DMOD, 0xf14c, {0x00, 0x00}, 0x02}, + {PRO_DMOD, 0xf14f, {0x04}, 0x01}, + {PRO_DMOD, 0xf158, {0x7f}, 0x01}, + {PRO_DMOD, 0xf15a, {0x00, 0x08}, 0x02}, + {PRO_DMOD, 0xf15d, {0x03, 0x05}, 0x02}, + {PRO_DMOD, 0xf163, {0x05}, 0x01}, + {PRO_DMOD, 0xf166, {0x01, 0x40, 0x0f}, 0x03}, + {PRO_DMOD, 0xf17a, {0x00, 0x00}, 0x02}, + {PRO_DMOD, 0xf183, {0x01}, 0x01}, + {PRO_DMOD, 0xf19d, {0x40}, 0x01}, + {PRO_DMOD, 0xf1bc, {0x36, 0x00}, 0x02}, + {PRO_DMOD, 0xf1cb, {0xa0, 0x01}, 0x02}, + {PRO_DMOD, 0xf204, {0x10}, 0x01}, + {PRO_DMOD, 0xf214, {0x00}, 0x01}, + {PRO_DMOD, 0xf24c, {0x88, 0x95, 0x9a, 0x90}, 0x04}, + {PRO_DMOD, 0xf25a, {0x07, 0xe8, 0x03, 0xb0, 0x04}, 0x05}, + {PRO_DMOD, 0xf270, {0x01, 0x02, 0x01, 0x02}, 0x04}, + {PRO_DMOD, 0xf40e, {0x0a, 0x40, 0x08}, 0x03}, + {PRO_DMOD, 0xf55f, {0x0a}, 0x01}, + {PRO_DMOD, 0xf561, {0x15, 0x20}, 0x02}, + {PRO_DMOD, 0xf5df, {0xfb, 0x00}, 0x02}, + {PRO_DMOD, 0xf5e3, {0x09, 0x01, 0x01}, 0x03}, + {PRO_DMOD, 0xf5f8, {0x01}, 0x01}, + {PRO_DMOD, 0xf5fd, {0x01}, 0x01}, + {PRO_DMOD, 0xf600, { 0x05, 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x17, + 0x1f}, 0x08}, + {PRO_DMOD, 0xf60e, {0x00, 0x04, 0x32, 0x10}, 0x04}, + {PRO_DMOD, 0xf707, {0xfc, 0x00, 0x37, 0x00}, 0x04}, + {PRO_DMOD, 0xf78b, {0x01}, 0x01}, + {PRO_DMOD, 0xf80f, {0x40, 0x54, 0x5a}, 0x03}, + {PRO_DMOD, 0xf905, {0x01}, 0x01}, + {PRO_DMOD, 0xfb06, {0x03}, 0x01}, + {PRO_DMOD, 0xfd8b, {0x00}, 0x01}, + {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */ +}; + +static struct it913xset it9135_52[] = { + {PRO_DMOD, 0x0043, {0x00}, 0x01}, + {PRO_DMOD, 0x0046, {0x52}, 0x01}, + {PRO_DMOD, 0x0051, {0x01}, 0x01}, + {PRO_DMOD, 0x005f, {0x00, 0x00}, 0x02}, + {PRO_DMOD, 0x0068, {0x10}, 0x01}, + {PRO_DMOD, 0x0070, {0x0a, 0x05, 0x02}, 0x03}, + {PRO_DMOD, 0x0075, {0x8c, 0x8c, 0x8c, 0xa0, 0x01}, 0x05}, + {PRO_DMOD, 0x007e, {0x04, 0x00}, 0x02}, + {PRO_DMOD, 0x0081, { 0x0a, 0x12, 0x03, 0x0a, 0x03, 0xb3, 0x97, + 0xc0, 0x9e, 0x01}, 0x0a}, + {PRO_DMOD, 0x008e, {0x01}, 0x01}, + {PRO_DMOD, 0x0092, {0x06, 0x00, 0x00, 0x00, 0x00}, 0x05}, + {PRO_DMOD, 0x0099, {0x01}, 0x01}, + {PRO_DMOD, 0x009b, {0x3c, 0x28}, 0x02}, + {PRO_DMOD, 0x009f, {0xe1, 0xcf}, 0x02}, + {PRO_DMOD, 0x00a3, {0x01, 0x5c, 0x01, 0x01}, 0x04}, + {PRO_DMOD, 0x00a9, {0x00, 0x01}, 0x02}, + {PRO_DMOD, 0x00b0, {0x01}, 0x01}, + {PRO_DMOD, 0x00b3, {0x02, 0x3c}, 0x02}, + {PRO_DMOD, 0x00b6, {0x14}, 0x01}, + {PRO_DMOD, 0x00c0, {0x11, 0x00, 0x05}, 0x03}, + {PRO_DMOD, 0x00c4, {0x00}, 0x01}, + {PRO_DMOD, 0x00c6, {0x19, 0x00}, 0x02}, + {PRO_DMOD, 0x00cc, {0x2e, 0x51, 0x33}, 0x03}, + {PRO_DMOD, 0x00f3, {0x05, 0x91, 0x8c}, 0x03}, + {PRO_DMOD, 0x00f8, {0x03, 0x06, 0x06}, 0x03}, + {PRO_DMOD, 0x00fc, { 0x03, 0x02, 0x02, 0x09, 0x50, 0x74, 0x77, + 0x02, 0x02, 0xae, 0x02, 0x6e}, 0x0c}, + {PRO_DMOD, 0x0109, {0x02}, 0x01}, + {PRO_DMOD, 0x0115, {0x0a, 0x03, 0x02, 0x80}, 0x04}, + {PRO_DMOD, 0x011a, {0xcd, 0x62, 0xa4, 0x8c}, 0x04}, + {PRO_DMOD, 0x0122, {0x03, 0x18, 0x9e}, 0x03}, + {PRO_DMOD, 0x0127, {0x00, 0x07}, 0x02}, + {PRO_DMOD, 0x012a, {0x53, 0x51, 0x4e, 0x43}, 0x04}, + {PRO_DMOD, 0x0137, {0x00, 0x00, 0x07, 0x00, 0x06}, 0x05}, + {PRO_DMOD, 0x013d, {0x00, 0x01, 0x5b, 0xb6, 0x59}, 0x05}, + {PRO_DMOD, 0xf000, {0x0f}, 0x01}, + {PRO_DMOD, 0xf016, {0x10, 0x04, 0x05, 0x04, 0x05}, 0x05}, + {PRO_DMOD, 0xf01f, {0x8c, 0x00, 0x03, 0x0a, 0x0a}, 0x05}, + {PRO_DMOD, 0xf029, {0x8c, 0x00, 0x00, 0x01}, 0x04}, + {PRO_DMOD, 0xf064, {0x03, 0xf9, 0x03, 0x01}, 0x04}, + {PRO_DMOD, 0xf06f, {0xe0, 0x03}, 0x02}, + {PRO_DMOD, 0xf072, {0x0f, 0x03}, 0x02}, + {PRO_DMOD, 0xf077, {0x01, 0x00}, 0x02}, + {PRO_DMOD, 0xf085, {0xc0, 0x01, 0x00}, 0x03}, + {PRO_DMOD, 0xf09b, {0x3f, 0x00, 0x20, 0x00, 0x0c, 0x00}, 0x06}, + {PRO_DMOD, 0xf130, {0x04}, 0x01}, + {PRO_DMOD, 0xf132, {0x04}, 0x01}, + {PRO_DMOD, 0xf144, {0x1a}, 0x01}, + {PRO_DMOD, 0xf146, {0x00}, 0x01}, + {PRO_DMOD, 0xf14a, {0x01}, 0x01}, + {PRO_DMOD, 0xf14c, {0x00, 0x00}, 0x02}, + {PRO_DMOD, 0xf14f, {0x04}, 0x01}, + {PRO_DMOD, 0xf158, {0x7f}, 0x01}, + {PRO_DMOD, 0xf15a, {0x00, 0x08}, 0x02}, + {PRO_DMOD, 0xf15d, {0x03, 0x05}, 0x02}, + {PRO_DMOD, 0xf163, {0x05}, 0x01}, + {PRO_DMOD, 0xf166, {0x01, 0x40, 0x0f}, 0x03}, + {PRO_DMOD, 0xf17a, {0x00, 0x00}, 0x02}, + {PRO_DMOD, 0xf183, {0x01}, 0x01}, + {PRO_DMOD, 0xf19d, {0x40}, 0x01}, + {PRO_DMOD, 0xf1bc, {0x36, 0x00}, 0x02}, + {PRO_DMOD, 0xf1cb, {0xa0, 0x01}, 0x02}, + {PRO_DMOD, 0xf204, {0x10}, 0x01}, + {PRO_DMOD, 0xf214, {0x00}, 0x01}, + {PRO_DMOD, 0xf24c, {0x88, 0x95, 0x9a, 0x90}, 0x04}, + {PRO_DMOD, 0xf25a, {0x07, 0xe8, 0x03, 0xb0, 0x04}, 0x05}, + {PRO_DMOD, 0xf270, {0x01, 0x02, 0x01, 0x02}, 0x04}, + {PRO_DMOD, 0xf40e, {0x0a, 0x40, 0x08}, 0x03}, + {PRO_DMOD, 0xf55f, {0x0a}, 0x01}, + {PRO_DMOD, 0xf561, {0x15, 0x20}, 0x02}, + {PRO_DMOD, 0xf5df, {0xfb, 0x00}, 0x02}, + {PRO_DMOD, 0xf5e3, {0x09, 0x01, 0x01}, 0x03}, + {PRO_DMOD, 0xf5f8, {0x01}, 0x01}, + {PRO_DMOD, 0xf5fd, {0x01}, 0x01}, + {PRO_DMOD, 0xf600, {0x05, 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x17, + 0x1f}, 0x08}, + {PRO_DMOD, 0xf60e, {0x00, 0x04, 0x32, 0x10}, 0x04}, + {PRO_DMOD, 0xf707, {0xfc, 0x00, 0x37, 0x00}, 0x04}, + {PRO_DMOD, 0xf78b, {0x01}, 0x01}, + {PRO_DMOD, 0xf80f, {0x40, 0x54, 0x5a}, 0x03}, + {PRO_DMOD, 0xf905, {0x01}, 0x01}, + {PRO_DMOD, 0xfb06, {0x03}, 0x01}, + {PRO_DMOD, 0xfd8b, {0x00}, 0x01}, + {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */ }; +/* Version 2 types */ +static struct it913xset it9135_v2[] = { + {PRO_DMOD, 0x0051, {0x01}, 0x01}, + {PRO_DMOD, 0x0070, {0x0a}, 0x01}, + {PRO_DMOD, 0x007e, {0x04}, 0x01}, + {PRO_DMOD, 0x0081, {0x0a}, 0x01}, + {PRO_DMOD, 0x008a, {0x01}, 0x01}, + {PRO_DMOD, 0x008e, {0x01}, 0x01}, + {PRO_DMOD, 0x0092, {0x06}, 0x01}, + {PRO_DMOD, 0x0099, {0x01}, 0x01}, + {PRO_DMOD, 0x009f, {0xe1}, 0x01}, + {PRO_DMOD, 0x00a0, {0xcf}, 0x01}, + {PRO_DMOD, 0x00a3, {0x01}, 0x01}, + {PRO_DMOD, 0x00a5, {0x01}, 0x01}, + {PRO_DMOD, 0x00a6, {0x01}, 0x01}, + {PRO_DMOD, 0x00a9, {0x00}, 0x01}, + {PRO_DMOD, 0x00aa, {0x01}, 0x01}, + {PRO_DMOD, 0x00b0, {0x01}, 0x01}, + {PRO_DMOD, 0x00c2, {0x05}, 0x01}, + {PRO_DMOD, 0x00c6, {0x19}, 0x01}, + {PRO_DMOD, 0xf000, {0x0f}, 0x01}, + {PRO_DMOD, 0xf02b, {0x00}, 0x01}, + {PRO_DMOD, 0xf064, {0x03}, 0x01}, + {PRO_DMOD, 0xf065, {0xf9}, 0x01}, + {PRO_DMOD, 0xf066, {0x03}, 0x01}, + {PRO_DMOD, 0xf067, {0x01}, 0x01}, + {PRO_DMOD, 0xf06f, {0xe0}, 0x01}, + {PRO_DMOD, 0xf070, {0x03}, 0x01}, + {PRO_DMOD, 0xf072, {0x0f}, 0x01}, + {PRO_DMOD, 0xf073, {0x03}, 0x01}, + {PRO_DMOD, 0xf078, {0x00}, 0x01}, + {PRO_DMOD, 0xf087, {0x00}, 0x01}, + {PRO_DMOD, 0xf09b, {0x3f}, 0x01}, + {PRO_DMOD, 0xf09c, {0x00}, 0x01}, + {PRO_DMOD, 0xf09d, {0x20}, 0x01}, + {PRO_DMOD, 0xf09e, {0x00}, 0x01}, + {PRO_DMOD, 0xf09f, {0x0c}, 0x01}, + {PRO_DMOD, 0xf0a0, {0x00}, 0x01}, + {PRO_DMOD, 0xf130, {0x04}, 0x01}, + {PRO_DMOD, 0xf132, {0x04}, 0x01}, + {PRO_DMOD, 0xf144, {0x1a}, 0x01}, + {PRO_DMOD, 0xf146, {0x00}, 0x01}, + {PRO_DMOD, 0xf14a, {0x01}, 0x01}, + {PRO_DMOD, 0xf14c, {0x00}, 0x01}, + {PRO_DMOD, 0xf14d, {0x00}, 0x01}, + {PRO_DMOD, 0xf14f, {0x04}, 0x01}, + {PRO_DMOD, 0xf158, {0x7f}, 0x01}, + {PRO_DMOD, 0xf15a, {0x00}, 0x01}, + {PRO_DMOD, 0xf15b, {0x08}, 0x01}, + {PRO_DMOD, 0xf15d, {0x03}, 0x01}, + {PRO_DMOD, 0xf15e, {0x05}, 0x01}, + {PRO_DMOD, 0xf163, {0x05}, 0x01}, + {PRO_DMOD, 0xf166, {0x01}, 0x01}, + {PRO_DMOD, 0xf167, {0x40}, 0x01}, + {PRO_DMOD, 0xf168, {0x0f}, 0x01}, + {PRO_DMOD, 0xf17a, {0x00}, 0x01}, + {PRO_DMOD, 0xf17b, {0x00}, 0x01}, + {PRO_DMOD, 0xf183, {0x01}, 0x01}, + {PRO_DMOD, 0xf19d, {0x40}, 0x01}, + {PRO_DMOD, 0xf1bc, {0x36}, 0x01}, + {PRO_DMOD, 0xf1bd, {0x00}, 0x01}, + {PRO_DMOD, 0xf1cb, {0xa0}, 0x01}, + {PRO_DMOD, 0xf1cc, {0x01}, 0x01}, + {PRO_DMOD, 0xf204, {0x10}, 0x01}, + {PRO_DMOD, 0xf214, {0x00}, 0x01}, + {PRO_DMOD, 0xf40e, {0x0a}, 0x01}, + {PRO_DMOD, 0xf40f, {0x40}, 0x01}, + {PRO_DMOD, 0xf410, {0x08}, 0x01}, + {PRO_DMOD, 0xf55f, {0x0a}, 0x01}, + {PRO_DMOD, 0xf561, {0x15}, 0x01}, + {PRO_DMOD, 0xf562, {0x20}, 0x01}, + {PRO_DMOD, 0xf5e3, {0x09}, 0x01}, + {PRO_DMOD, 0xf5e4, {0x01}, 0x01}, + {PRO_DMOD, 0xf5e5, {0x01}, 0x01}, + {PRO_DMOD, 0xf600, {0x05}, 0x01}, + {PRO_DMOD, 0xf601, {0x08}, 0x01}, + {PRO_DMOD, 0xf602, {0x0b}, 0x01}, + {PRO_DMOD, 0xf603, {0x0e}, 0x01}, + {PRO_DMOD, 0xf604, {0x11}, 0x01}, + {PRO_DMOD, 0xf605, {0x14}, 0x01}, + {PRO_DMOD, 0xf606, {0x17}, 0x01}, + {PRO_DMOD, 0xf607, {0x1f}, 0x01}, + {PRO_DMOD, 0xf60e, {0x00}, 0x01}, + {PRO_DMOD, 0xf60f, {0x04}, 0x01}, + {PRO_DMOD, 0xf610, {0x32}, 0x01}, + {PRO_DMOD, 0xf611, {0x10}, 0x01}, + {PRO_DMOD, 0xf707, {0xfc}, 0x01}, + {PRO_DMOD, 0xf708, {0x00}, 0x01}, + {PRO_DMOD, 0xf709, {0x37}, 0x01}, + {PRO_DMOD, 0xf70a, {0x00}, 0x01}, + {PRO_DMOD, 0xf78b, {0x01}, 0x01}, + {PRO_DMOD, 0xf80f, {0x40}, 0x01}, + {PRO_DMOD, 0xf810, {0x54}, 0x01}, + {PRO_DMOD, 0xf811, {0x5a}, 0x01}, + {PRO_DMOD, 0xf905, {0x01}, 0x01}, + {PRO_DMOD, 0xfb06, {0x03}, 0x01}, + {PRO_DMOD, 0xfd8b, {0x00}, 0x01}, + {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */ +}; + +static struct it913xset it9135_60[] = { + {PRO_DMOD, 0x0043, {0x00}, 0x01}, + {PRO_DMOD, 0x0046, {0x60}, 0x01}, + {PRO_DMOD, 0x0051, {0x01}, 0x01}, + {PRO_DMOD, 0x005f, {0x00, 0x00}, 0x02}, + {PRO_DMOD, 0x0068, {0x0a}, 0x01}, + {PRO_DMOD, 0x006a, {0x03}, 0x01}, + {PRO_DMOD, 0x0070, {0x0a, 0x05, 0x02}, 0x03}, + {PRO_DMOD, 0x0075, {0x8c, 0x8c, 0x8c, 0x8c, 0x01}, 0x05}, + {PRO_DMOD, 0x007e, {0x04}, 0x01}, + {PRO_DMOD, 0x0081, {0x0a, 0x12}, 0x02}, + {PRO_DMOD, 0x0084, {0x0a, 0x33, 0xbe, 0xa0, 0xc6, 0xb6, 0x01}, 0x07}, + {PRO_DMOD, 0x008e, {0x01}, 0x01}, + {PRO_DMOD, 0x0092, {0x06, 0x00, 0x00, 0x00, 0x00}, 0x05}, + {PRO_DMOD, 0x0099, {0x01}, 0x01}, + {PRO_DMOD, 0x009b, {0x3c, 0x28}, 0x02}, + {PRO_DMOD, 0x009f, {0xe1, 0xcf}, 0x02}, + {PRO_DMOD, 0x00a3, {0x01, 0x5a, 0x01, 0x01}, 0x04}, + {PRO_DMOD, 0x00a9, {0x00, 0x01}, 0x02}, + {PRO_DMOD, 0x00b0, {0x01}, 0x01}, + {PRO_DMOD, 0x00b3, {0x02, 0x3a}, 0x02}, + {PRO_DMOD, 0x00b6, {0x14}, 0x01}, + {PRO_DMOD, 0x00c0, {0x11, 0x00, 0x05, 0x01, 0x00}, 0x05}, + {PRO_DMOD, 0x00c6, {0x19, 0x00}, 0x02}, + {PRO_DMOD, 0x00cb, {0x32, 0x2c, 0x4f, 0x30}, 0x04}, + {PRO_DMOD, 0x00f3, {0x05, 0xa0, 0x8c}, 0x03}, + {PRO_DMOD, 0x00f8, {0x03, 0x06, 0x06}, 0x03}, + {PRO_DMOD, 0x00fc, { 0x03, 0x03, 0x02, 0x0a, 0x50, 0x7b, 0x8c, + 0x00, 0x02, 0xbe, 0x00}, 0x0b}, + {PRO_DMOD, 0x0109, {0x02}, 0x01}, + {PRO_DMOD, 0x0115, {0x0a, 0x03}, 0x02}, + {PRO_DMOD, 0x011a, {0xbe}, 0x01}, + {PRO_DMOD, 0x0124, {0xae}, 0x01}, + {PRO_DMOD, 0x0127, {0x00}, 0x01}, + {PRO_DMOD, 0x012a, {0x56, 0x50, 0x47, 0x42}, 0x04}, + {PRO_DMOD, 0x0137, {0x00}, 0x01}, + {PRO_DMOD, 0x013b, {0x08}, 0x01}, + {PRO_DMOD, 0x013f, {0x5b}, 0x01}, + {PRO_DMOD, 0x0141, { 0x59, 0xf9, 0x19, 0x19, 0x8c, 0x8c, 0x8c, + 0x6e, 0x8c, 0x50, 0x8c, 0x8c, 0xac, 0xc6, + 0x33}, 0x0f}, + {PRO_DMOD, 0x0151, {0x28}, 0x01}, + {PRO_DMOD, 0x0153, {0xbc}, 0x01}, + {PRO_DMOD, 0x0178, {0x09}, 0x01}, + {PRO_DMOD, 0x0181, {0x94, 0x6e}, 0x02}, + {PRO_DMOD, 0x0185, {0x24}, 0x01}, + {PRO_DMOD, 0x0187, {0x00, 0x00, 0xbe, 0x02, 0x80}, 0x05}, + {PRO_DMOD, 0xed02, {0xff}, 0x01}, + {PRO_DMOD, 0xee42, {0xff}, 0x01}, + {PRO_DMOD, 0xee82, {0xff}, 0x01}, + {PRO_DMOD, 0xf000, {0x0f}, 0x01}, + {PRO_DMOD, 0xf01f, {0x8c, 0x00}, 0x02}, + {PRO_DMOD, 0xf029, {0x8c, 0x00, 0x00}, 0x03}, + {PRO_DMOD, 0xf064, {0x03, 0xf9, 0x03, 0x01}, 0x04}, + {PRO_DMOD, 0xf06f, {0xe0, 0x03}, 0x02}, + {PRO_DMOD, 0xf072, {0x0f, 0x03}, 0x02}, + {PRO_DMOD, 0xf077, {0x01, 0x00}, 0x02}, + {PRO_DMOD, 0xf087, {0x00}, 0x01}, + {PRO_DMOD, 0xf09b, {0x3f, 0x00, 0x20, 0x00, 0x0c, 0x00}, 0x06}, + {PRO_DMOD, 0xf130, {0x04}, 0x01}, + {PRO_DMOD, 0xf132, {0x04}, 0x01}, + {PRO_DMOD, 0xf144, {0x1a}, 0x01}, + {PRO_DMOD, 0xf146, {0x00}, 0x01}, + {PRO_DMOD, 0xf14a, {0x01}, 0x01}, + {PRO_DMOD, 0xf14c, {0x00, 0x00}, 0x02}, + {PRO_DMOD, 0xf14f, {0x04}, 0x01}, + {PRO_DMOD, 0xf158, {0x7f}, 0x01}, + {PRO_DMOD, 0xf15a, {0x00, 0x08}, 0x02}, + {PRO_DMOD, 0xf15d, {0x03, 0x05}, 0x02}, + {PRO_DMOD, 0xf163, {0x05}, 0x01}, + {PRO_DMOD, 0xf166, {0x01, 0x40, 0x0f}, 0x03}, + {PRO_DMOD, 0xf17a, {0x00, 0x00}, 0x02}, + {PRO_DMOD, 0xf183, {0x01}, 0x01}, + {PRO_DMOD, 0xf19d, {0x40}, 0x01}, + {PRO_DMOD, 0xf1bc, {0x36, 0x00}, 0x02}, + {PRO_DMOD, 0xf1cb, {0xa0, 0x01}, 0x02}, + {PRO_DMOD, 0xf204, {0x10}, 0x01}, + {PRO_DMOD, 0xf214, {0x00}, 0x01}, + {PRO_DMOD, 0xf24c, {0x88, 0x95, 0x9a, 0x90}, 0x04}, + {PRO_DMOD, 0xf25a, {0x07, 0xe8, 0x03, 0xb0, 0x04}, 0x05}, + {PRO_DMOD, 0xf270, {0x01, 0x02, 0x01, 0x02}, 0x04}, + {PRO_DMOD, 0xf40e, {0x0a, 0x40, 0x08}, 0x03}, + {PRO_DMOD, 0xf55f, {0x0a}, 0x01}, + {PRO_DMOD, 0xf561, {0x15, 0x20}, 0x02}, + {PRO_DMOD, 0xf5e3, {0x09, 0x01, 0x01}, 0x03}, + {PRO_DMOD, 0xf600, {0x05, 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x17 + , 0x1f}, 0x08}, + {PRO_DMOD, 0xf60e, {0x00, 0x04, 0x32, 0x10}, 0x04}, + {PRO_DMOD, 0xf707, {0xfc, 0x00, 0x37, 0x00}, 0x04}, + {PRO_DMOD, 0xf78b, {0x01}, 0x01}, + {PRO_DMOD, 0xf80f, {0x40, 0x54, 0x5a}, 0x03}, + {PRO_DMOD, 0xf905, {0x01}, 0x01}, + {PRO_DMOD, 0xfb06, {0x03}, 0x01}, + {PRO_DMOD, 0xfd8b, {0x00}, 0x01}, + {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */ +}; + +static struct it913xset it9135_61[] = { + {PRO_DMOD, 0x0043, {0x00}, 0x01}, + {PRO_DMOD, 0x0046, {0x61}, 0x01}, + {PRO_DMOD, 0x0051, {0x01}, 0x01}, + {PRO_DMOD, 0x005f, {0x00, 0x00}, 0x02}, + {PRO_DMOD, 0x0068, {0x06}, 0x01}, + {PRO_DMOD, 0x006a, {0x03}, 0x01}, + {PRO_DMOD, 0x0070, {0x0a, 0x05, 0x02}, 0x03}, + {PRO_DMOD, 0x0075, {0x8c, 0x8c, 0x8c, 0x90, 0x01}, 0x05}, + {PRO_DMOD, 0x007e, {0x04}, 0x01}, + {PRO_DMOD, 0x0081, {0x0a, 0x12}, 0x02}, + {PRO_DMOD, 0x0084, {0x0a, 0x33, 0xbc, 0x9c, 0xcc, 0xa8, 0x01}, 0x07}, + {PRO_DMOD, 0x008e, {0x01}, 0x01}, + {PRO_DMOD, 0x0092, {0x06, 0x00, 0x00, 0x00, 0x00}, 0x05}, + {PRO_DMOD, 0x0099, {0x01}, 0x01}, + {PRO_DMOD, 0x009b, {0x3c, 0x28}, 0x02}, + {PRO_DMOD, 0x009f, {0xe1, 0xcf}, 0x02}, + {PRO_DMOD, 0x00a3, {0x01, 0x5c, 0x01, 0x01}, 0x04}, + {PRO_DMOD, 0x00a9, {0x00, 0x01}, 0x02}, + {PRO_DMOD, 0x00b0, {0x01}, 0x01}, + {PRO_DMOD, 0x00b3, {0x02, 0x3a}, 0x02}, + {PRO_DMOD, 0x00b6, {0x14}, 0x01}, + {PRO_DMOD, 0x00c0, {0x11, 0x00, 0x05, 0x01, 0x00}, 0x05}, + {PRO_DMOD, 0x00c6, {0x19, 0x00}, 0x02}, + {PRO_DMOD, 0x00cb, {0x32, 0x2c, 0x4f, 0x30}, 0x04}, + {PRO_DMOD, 0x00f3, {0x05, 0xa0, 0x8c}, 0x03}, + {PRO_DMOD, 0x00f8, {0x03, 0x06, 0x06}, 0x03}, + {PRO_DMOD, 0x00fc, { 0x03, 0x03, 0x02, 0x08, 0x50, 0x7b, 0x8c, + 0x01, 0x02, 0xc8, 0x00}, 0x0b}, + {PRO_DMOD, 0x0109, {0x02}, 0x01}, + {PRO_DMOD, 0x0115, {0x0a, 0x03}, 0x02}, + {PRO_DMOD, 0x011a, {0xc6}, 0x01}, + {PRO_DMOD, 0x0124, {0xa8}, 0x01}, + {PRO_DMOD, 0x0127, {0x00}, 0x01}, + {PRO_DMOD, 0x012a, {0x59, 0x50, 0x47, 0x42}, 0x04}, + {PRO_DMOD, 0x0137, {0x00}, 0x01}, + {PRO_DMOD, 0x013b, {0x05}, 0x01}, + {PRO_DMOD, 0x013f, {0x5b}, 0x01}, + {PRO_DMOD, 0x0141, { 0x59, 0xf9, 0x59, 0x59, 0x8c, 0x8c, 0x8c, + 0x7b, 0x8c, 0x50, 0x8c, 0x8c, 0xa8, 0xc6, + 0x33}, 0x0f}, + {PRO_DMOD, 0x0151, {0x28}, 0x01}, + {PRO_DMOD, 0x0153, {0xcc}, 0x01}, + {PRO_DMOD, 0x0178, {0x09}, 0x01}, + {PRO_DMOD, 0x0181, {0x9c, 0x76}, 0x02}, + {PRO_DMOD, 0x0185, {0x28}, 0x01}, + {PRO_DMOD, 0x0187, {0x01, 0x00, 0xaa, 0x02, 0x80}, 0x05}, + {PRO_DMOD, 0xed02, {0xff}, 0x01}, + {PRO_DMOD, 0xee42, {0xff}, 0x01}, + {PRO_DMOD, 0xee82, {0xff}, 0x01}, + {PRO_DMOD, 0xf000, {0x0f}, 0x01}, + {PRO_DMOD, 0xf01f, {0x8c, 0x00}, 0x02}, + {PRO_DMOD, 0xf029, {0x8c, 0x00, 0x00}, 0x03}, + {PRO_DMOD, 0xf064, {0x03, 0xf9, 0x03, 0x01}, 0x04}, + {PRO_DMOD, 0xf06f, {0xe0, 0x03}, 0x02}, + {PRO_DMOD, 0xf072, {0x0f, 0x03}, 0x02}, + {PRO_DMOD, 0xf077, {0x01, 0x00}, 0x02}, + {PRO_DMOD, 0xf087, {0x00}, 0x01}, + {PRO_DMOD, 0xf09b, {0x3f, 0x00, 0x20, 0x00, 0x0c, 0x00}, 0x06}, + {PRO_DMOD, 0xf130, {0x04}, 0x01}, + {PRO_DMOD, 0xf132, {0x04}, 0x01}, + {PRO_DMOD, 0xf144, {0x1a}, 0x01}, + {PRO_DMOD, 0xf146, {0x00}, 0x01}, + {PRO_DMOD, 0xf14a, {0x01}, 0x01}, + {PRO_DMOD, 0xf14c, {0x00, 0x00}, 0x02}, + {PRO_DMOD, 0xf14f, {0x04}, 0x01}, + {PRO_DMOD, 0xf158, {0x7f}, 0x01}, + {PRO_DMOD, 0xf15a, {0x00, 0x08}, 0x02}, + {PRO_DMOD, 0xf15d, {0x03, 0x05}, 0x02}, + {PRO_DMOD, 0xf163, {0x05}, 0x01}, + {PRO_DMOD, 0xf166, {0x01, 0x40, 0x0f}, 0x03}, + {PRO_DMOD, 0xf17a, {0x00, 0x00}, 0x02}, + {PRO_DMOD, 0xf183, {0x01}, 0x01}, + {PRO_DMOD, 0xf19d, {0x40}, 0x01}, + {PRO_DMOD, 0xf1bc, {0x36, 0x00}, 0x02}, + {PRO_DMOD, 0xf1cb, {0xa0, 0x01}, 0x02}, + {PRO_DMOD, 0xf204, {0x10}, 0x01}, + {PRO_DMOD, 0xf214, {0x00}, 0x01}, + {PRO_DMOD, 0xf24c, {0x88, 0x95, 0x9a, 0x90}, 0x04}, + {PRO_DMOD, 0xf25a, {0x07, 0xe8, 0x03, 0xb0, 0x04}, 0x05}, + {PRO_DMOD, 0xf270, {0x01, 0x02, 0x01, 0x02}, 0x04}, + {PRO_DMOD, 0xf40e, {0x0a, 0x40, 0x08}, 0x03}, + {PRO_DMOD, 0xf55f, {0x0a}, 0x01}, + {PRO_DMOD, 0xf561, {0x15, 0x20}, 0x02}, + {PRO_DMOD, 0xf5e3, {0x09, 0x01, 0x01}, 0x03}, + {PRO_DMOD, 0xf600, { 0x05, 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x17, + 0x1f}, 0x08}, + {PRO_DMOD, 0xf60e, {0x00, 0x04, 0x32, 0x10}, 0x04}, + {PRO_DMOD, 0xf707, {0xfc, 0x00, 0x37, 0x00}, 0x04}, + {PRO_DMOD, 0xf78b, {0x01}, 0x01}, + {PRO_DMOD, 0xf80f, {0x40, 0x54, 0x5a}, 0x03}, + {PRO_DMOD, 0xf905, {0x01}, 0x01}, + {PRO_DMOD, 0xfb06, {0x03}, 0x01}, + {PRO_DMOD, 0xfd8b, {0x00}, 0x01}, + {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */ +}; + +static struct it913xset it9135_62[] = { + {PRO_DMOD, 0x0043, {0x00}, 0x01}, + {PRO_DMOD, 0x0046, {0x62}, 0x01}, + {PRO_DMOD, 0x0051, {0x01}, 0x01}, + {PRO_DMOD, 0x005f, {0x00, 0x00}, 0x02}, + {PRO_DMOD, 0x0068, {0x0a}, 0x01}, + {PRO_DMOD, 0x006a, {0x03}, 0x01}, + {PRO_DMOD, 0x0070, {0x0a, 0x05, 0x02}, 0x03}, + {PRO_DMOD, 0x0075, {0x8c, 0x8c, 0x8c, 0x8c, 0x01}, 0x05}, + {PRO_DMOD, 0x007e, {0x04}, 0x01}, + {PRO_DMOD, 0x0081, {0x0a, 0x12}, 0x02}, + {PRO_DMOD, 0x0084, { 0x0a, 0x33, 0xb8, 0x9c, 0xb2, 0xa6, 0x01}, + 0x07}, + {PRO_DMOD, 0x008e, {0x01}, 0x01}, + {PRO_DMOD, 0x0092, {0x06, 0x00, 0x00, 0x00, 0x00}, 0x05}, + {PRO_DMOD, 0x0099, {0x01}, 0x01}, + {PRO_DMOD, 0x009b, {0x3c, 0x28}, 0x02}, + {PRO_DMOD, 0x009f, {0xe1, 0xcf}, 0x02}, + {PRO_DMOD, 0x00a3, {0x01, 0x5a, 0x01, 0x01}, 0x04}, + {PRO_DMOD, 0x00a9, {0x00, 0x01}, 0x02}, + {PRO_DMOD, 0x00b0, {0x01}, 0x01}, + {PRO_DMOD, 0x00b3, {0x02, 0x3a}, 0x02}, + {PRO_DMOD, 0x00b6, {0x14}, 0x01}, + {PRO_DMOD, 0x00c0, {0x11, 0x00, 0x05, 0x01, 0x00}, 0x05}, + {PRO_DMOD, 0x00c6, {0x19, 0x00}, 0x02}, + {PRO_DMOD, 0x00cb, {0x32, 0x2c, 0x4f, 0x30}, 0x04}, + {PRO_DMOD, 0x00f3, {0x05, 0x8c, 0x8c}, 0x03}, + {PRO_DMOD, 0x00f8, {0x03, 0x06, 0x06}, 0x03}, + {PRO_DMOD, 0x00fc, { 0x02, 0x03, 0x02, 0x09, 0x50, 0x6e, 0x8c, + 0x02, 0x02, 0xc2, 0x00}, 0x0b}, + {PRO_DMOD, 0x0109, {0x02}, 0x01}, + {PRO_DMOD, 0x0115, {0x0a, 0x03}, 0x02}, + {PRO_DMOD, 0x011a, {0xb8}, 0x01}, + {PRO_DMOD, 0x0124, {0xa8}, 0x01}, + {PRO_DMOD, 0x0127, {0x00}, 0x01}, + {PRO_DMOD, 0x012a, {0x53, 0x51, 0x4e, 0x43}, 0x04}, + {PRO_DMOD, 0x0137, {0x00}, 0x01}, + {PRO_DMOD, 0x013b, {0x05}, 0x01}, + {PRO_DMOD, 0x013f, {0x5b}, 0x01}, + {PRO_DMOD, 0x0141, { 0x59, 0xf9, 0x59, 0x19, 0x8c, 0x8c, 0x8c, + 0x7b, 0x8c, 0x50, 0x70, 0x8c, 0x96, 0xd0, + 0x33}, 0x0f}, + {PRO_DMOD, 0x0151, {0x28}, 0x01}, + {PRO_DMOD, 0x0153, {0xb2}, 0x01}, + {PRO_DMOD, 0x0178, {0x09}, 0x01}, + {PRO_DMOD, 0x0181, {0x9c, 0x6e}, 0x02}, + {PRO_DMOD, 0x0185, {0x24}, 0x01}, + {PRO_DMOD, 0x0187, {0x00, 0x00, 0xb8, 0x02, 0x80}, 0x05}, + {PRO_DMOD, 0xed02, {0xff}, 0x01}, + {PRO_DMOD, 0xee42, {0xff}, 0x01}, + {PRO_DMOD, 0xee82, {0xff}, 0x01}, + {PRO_DMOD, 0xf000, {0x0f}, 0x01}, + {PRO_DMOD, 0xf01f, {0x8c, 0x00}, 0x02}, + {PRO_DMOD, 0xf029, {0x8c, 0x00, 0x00}, 0x03}, + {PRO_DMOD, 0xf064, {0x03, 0xf9, 0x03, 0x01}, 0x04}, + {PRO_DMOD, 0xf06f, {0xe0, 0x03}, 0x02}, + {PRO_DMOD, 0xf072, {0x0f, 0x03}, 0x02}, + {PRO_DMOD, 0xf077, {0x01, 0x00}, 0x02}, + {PRO_DMOD, 0xf087, {0x00}, 0x01}, + {PRO_DMOD, 0xf09b, {0x3f, 0x00, 0x20, 0x00, 0x0c, 0x00}, 0x06}, + {PRO_DMOD, 0xf130, {0x04}, 0x01}, + {PRO_DMOD, 0xf132, {0x04}, 0x01}, + {PRO_DMOD, 0xf144, {0x1a}, 0x01}, + {PRO_DMOD, 0xf146, {0x00}, 0x01}, + {PRO_DMOD, 0xf14a, {0x01}, 0x01}, + {PRO_DMOD, 0xf14c, {0x00, 0x00}, 0x02}, + {PRO_DMOD, 0xf14f, {0x04}, 0x01}, + {PRO_DMOD, 0xf158, {0x7f}, 0x01}, + {PRO_DMOD, 0xf15a, {0x00, 0x08}, 0x02}, + {PRO_DMOD, 0xf15d, {0x03, 0x05}, 0x02}, + {PRO_DMOD, 0xf163, {0x05}, 0x01}, + {PRO_DMOD, 0xf166, {0x01, 0x40, 0x0f}, 0x03}, + {PRO_DMOD, 0xf17a, {0x00, 0x00}, 0x02}, + {PRO_DMOD, 0xf183, {0x01}, 0x01}, + {PRO_DMOD, 0xf19d, {0x40}, 0x01}, + {PRO_DMOD, 0xf1bc, {0x36, 0x00}, 0x02}, + {PRO_DMOD, 0xf1cb, {0xa0, 0x01}, 0x02}, + {PRO_DMOD, 0xf204, {0x10}, 0x01}, + {PRO_DMOD, 0xf214, {0x00}, 0x01}, + {PRO_DMOD, 0xf24c, {0x88, 0x95, 0x9a, 0x90}, 0x04}, + {PRO_DMOD, 0xf25a, {0x07, 0xe8, 0x03, 0xb0, 0x04}, 0x05}, + {PRO_DMOD, 0xf270, {0x01, 0x02, 0x01, 0x02}, 0x04}, + {PRO_DMOD, 0xf40e, {0x0a, 0x40, 0x08}, 0x03}, + {PRO_DMOD, 0xf55f, {0x0a}, 0x01}, + {PRO_DMOD, 0xf561, {0x15, 0x20}, 0x02}, + {PRO_DMOD, 0xf5e3, {0x09, 0x01, 0x01}, 0x03}, + {PRO_DMOD, 0xf600, { 0x05, 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x17, + 0x1f}, 0x08}, + {PRO_DMOD, 0xf60e, {0x00, 0x04, 0x32, 0x10}, 0x04}, + {PRO_DMOD, 0xf707, {0xfc, 0x00, 0x37, 0x00}, 0x04}, + {PRO_DMOD, 0xf78b, {0x01}, 0x01}, + {PRO_DMOD, 0xf80f, {0x40, 0x54, 0x5a}, 0x03}, + {PRO_DMOD, 0xf905, {0x01}, 0x01}, + {PRO_DMOD, 0xfb06, {0x03}, 0x01}, + {PRO_DMOD, 0xfd8b, {0x00}, 0x01}, + {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */ +}; + +/* Tuner setting scripts (still keeping it9137) */ static struct it913xset it9137_tuner_off[] = { {PRO_DMOD, 0xfba8, {0x01}, 0x01}, /* Tuner Clock Off */ {PRO_DMOD, 0xec40, {0x00}, 0x01}, /* Power Down Tuner */ {PRO_DMOD, 0xec02, {0x3f, 0x1f, 0x3f, 0x3f}, 0x04}, + {PRO_DMOD, 0xec06, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, 0x0c}, + {PRO_DMOD, 0xec12, {0x00, 0x00, 0x00, 0x00}, 0x04}, + {PRO_DMOD, 0xec17, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00}, 0x09}, + {PRO_DMOD, 0xec22, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00}, 0x0a}, + {PRO_DMOD, 0xec20, {0x00}, 0x01}, {PRO_DMOD, 0xec3f, {0x01}, 0x01}, {0xff, 0x0000, {0x00}, 0x00}, /* Terminating Entry */ }; +static struct it913xset set_it9135_template[] = { + {PRO_DMOD, 0xee06, {0x00}, 0x01}, + {PRO_DMOD, 0xec56, {0x00}, 0x01}, + {PRO_DMOD, 0xec4c, {0x00}, 0x01}, + {PRO_DMOD, 0xec4d, {0x00}, 0x01}, + {PRO_DMOD, 0xec4e, {0x00}, 0x01}, + {PRO_DMOD, 0x011e, {0x00}, 0x01}, /* Older Devices */ + {PRO_DMOD, 0x011f, {0x00}, 0x01}, + {0xff, 0x0000, {0x00}, 0x00}, /* Terminating Entry */ +}; + static struct it913xset set_it9137_template[] = { {PRO_DMOD, 0xee06, {0x00}, 0x01}, {PRO_DMOD, 0xec56, {0x00}, 0x01}, diff --git a/drivers/media/dvb/frontends/it913x-fe.c b/drivers/media/dvb/frontends/it913x-fe.c index d4bd24eb4700..ccc36bf2deb4 100644 --- a/drivers/media/dvb/frontends/it913x-fe.c +++ b/drivers/media/dvb/frontends/it913x-fe.c @@ -46,13 +46,17 @@ MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able))."); dprintk(level, name" (%02x%02x%02x%02x%02x%02x%02x%02x)", \ *p, *(p+1), *(p+2), *(p+3), *(p+4), \ *(p+5), *(p+6), *(p+7)); +#define info(format, arg...) \ + printk(KERN_INFO "it913x-fe: " format "\n" , ## arg) struct it913x_fe_state { struct dvb_frontend frontend; struct i2c_adapter *i2c_adap; + struct ite_config *config; u8 i2c_addr; u32 frequency; - u8 adf; + fe_modulation_t constellation; + fe_transmit_mode_t transmission_mode; u32 crystalFrequency; u32 adcFrequency; u8 tuner_type; @@ -62,6 +66,7 @@ struct it913x_fe_state { u8 tun_fdiv; u8 tun_clk_mode; u32 tun_fn_min; + u32 ucblocks; }; static int it913x_read_reg(struct it913x_fe_state *state, @@ -211,20 +216,24 @@ static int it913x_init_tuner(struct it913x_fe_state *state) state->tun_fn_min /= (state->tun_fdiv * nv_val); deb_info("Tuner fn_min %d", state->tun_fn_min); - for (i = 0; i < 50; i++) { - reg = it913x_read_reg_u8(state, 0xec82); - if (reg > 0) - break; - if (reg < 0) - return -ENODEV; - udelay(2000); + if (state->config->chip_ver > 1) + msleep(50); + else { + for (i = 0; i < 50; i++) { + reg = it913x_read_reg_u8(state, 0xec82); + if (reg > 0) + break; + if (reg < 0) + return -ENODEV; + udelay(2000); + } } return it913x_write_reg(state, PRO_DMOD, 0xed81, val); } static int it9137_set_tuner(struct it913x_fe_state *state, - enum fe_bandwidth bandwidth, u32 frequency_m) + u32 bandwidth, u32 frequency_m) { struct it913xset *set_tuner = set_it9137_template; int ret, reg; @@ -237,6 +246,11 @@ static int it9137_set_tuner(struct it913x_fe_state *state, u8 lna_band; u8 bw; + if (state->config->firmware_ver == 1) + set_tuner = set_it9135_template; + else + set_tuner = set_it9137_template; + deb_info("Tuner Frequency %d Bandwidth %d", frequency, bandwidth); if (frequency >= 51000 && frequency <= 440000) { @@ -273,16 +287,21 @@ static int it9137_set_tuner(struct it913x_fe_state *state, return -EINVAL; set_tuner[0].reg[0] = lna_band; - if (bandwidth == BANDWIDTH_5_MHZ) + switch (bandwidth) { + case 5000000: bw = 0; - else if (bandwidth == BANDWIDTH_6_MHZ) + break; + case 6000000: bw = 2; - else if (bandwidth == BANDWIDTH_7_MHZ) + break; + case 7000000: bw = 4; - else if (bandwidth == BANDWIDTH_8_MHZ) - bw = 6; - else + break; + default: + case 8000000: bw = 6; + break; + } set_tuner[1].reg[0] = bw; set_tuner[2].reg[0] = 0xa0 | (l_band << 3); @@ -361,7 +380,7 @@ static int it9137_set_tuner(struct it913x_fe_state *state, } static int it913x_fe_select_bw(struct it913x_fe_state *state, - enum fe_bandwidth bandwidth, u32 adcFrequency) + u32 bandwidth, u32 adcFrequency) { int ret, i; u8 buffer[256]; @@ -374,17 +393,21 @@ static int it913x_fe_select_bw(struct it913x_fe_state *state, deb_info("Bandwidth %d Adc %d", bandwidth, adcFrequency); - if (bandwidth == BANDWIDTH_5_MHZ) + switch (bandwidth) { + case 5000000: bw = 3; - else if (bandwidth == BANDWIDTH_6_MHZ) + break; + case 6000000: bw = 0; - else if (bandwidth == BANDWIDTH_7_MHZ) + break; + case 7000000: bw = 1; - else if (bandwidth == BANDWIDTH_8_MHZ) - bw = 2; - else + break; + default: + case 8000000: bw = 2; - + break; + } ret = it913x_write_reg(state, PRO_DMOD, REG_BW, bw); if (state->table == NULL) @@ -492,31 +515,79 @@ static int it913x_fe_read_signal_strength(struct dvb_frontend *fe, return 0; } -static int it913x_fe_read_snr(struct dvb_frontend *fe, u16* snr) +static int it913x_fe_read_snr(struct dvb_frontend *fe, u16 *snr) { struct it913x_fe_state *state = fe->demodulator_priv; - int ret = it913x_read_reg_u8(state, SIGNAL_QUALITY); - ret = (ret * 0xff) / 0x64; - ret |= (ret << 0x8); - *snr = ~ret; - return 0; + int ret; + u8 reg[3]; + u32 snr_val, snr_min, snr_max; + u32 temp; + + ret = it913x_read_reg(state, 0x2c, reg, sizeof(reg)); + + snr_val = (u32)(reg[2] << 16) | (reg[1] << 8) | reg[0]; + + ret |= it913x_read_reg(state, 0xf78b, reg, 1); + if (reg[0]) + snr_val /= reg[0]; + + if (state->transmission_mode == TRANSMISSION_MODE_2K) + snr_val *= 4; + else if (state->transmission_mode == TRANSMISSION_MODE_4K) + snr_val *= 2; + + if (state->constellation == QPSK) { + snr_min = 0xb4711; + snr_max = 0x191451; + } else if (state->constellation == QAM_16) { + snr_min = 0x4f0d5; + snr_max = 0xc7925; + } else if (state->constellation == QAM_64) { + snr_min = 0x256d0; + snr_max = 0x626be; + } else + return -EINVAL; + + if (snr_val < snr_min) + *snr = 0; + else if (snr_val < snr_max) { + temp = (snr_val - snr_min) >> 5; + temp *= 0xffff; + temp /= (snr_max - snr_min) >> 5; + *snr = (u16)temp; + } else + *snr = 0xffff; + + return (ret < 0) ? -ENODEV : 0; } static int it913x_fe_read_ber(struct dvb_frontend *fe, u32 *ber) { - *ber = 0; + struct it913x_fe_state *state = fe->demodulator_priv; + int ret; + u8 reg[5]; + /* Read Aborted Packets and Pre-Viterbi error rate 5 bytes */ + ret = it913x_read_reg(state, RSD_ABORT_PKT_LSB, reg, sizeof(reg)); + state->ucblocks += (u32)(reg[1] << 8) | reg[0]; + *ber = (u32)(reg[4] << 16) | (reg[3] << 8) | reg[2]; return 0; } static int it913x_fe_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) { - *ucblocks = 0; - return 0; + struct it913x_fe_state *state = fe->demodulator_priv; + int ret; + u8 reg[2]; + /* Aborted Packets */ + ret = it913x_read_reg(state, RSD_ABORT_PKT_LSB, reg, sizeof(reg)); + state->ucblocks += (u32)(reg[1] << 8) | reg[0]; + *ucblocks = state->ucblocks; + return ret; } -static int it913x_fe_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int it913x_fe_get_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct it913x_fe_state *state = fe->demodulator_priv; int ret; u8 reg[8]; @@ -524,26 +595,30 @@ static int it913x_fe_get_frontend(struct dvb_frontend *fe, ret = it913x_read_reg(state, REG_TPSD_TX_MODE, reg, sizeof(reg)); if (reg[3] < 3) - p->u.ofdm.constellation = fe_con[reg[3]]; + p->modulation = fe_con[reg[3]]; if (reg[0] < 3) - p->u.ofdm.transmission_mode = fe_mode[reg[0]]; + p->transmission_mode = fe_mode[reg[0]]; if (reg[1] < 4) - p->u.ofdm.guard_interval = fe_gi[reg[1]]; + p->guard_interval = fe_gi[reg[1]]; if (reg[2] < 4) - p->u.ofdm.hierarchy_information = fe_hi[reg[2]]; + p->hierarchy = fe_hi[reg[2]]; + + p->code_rate_HP = (reg[6] < 6) ? fe_code[reg[6]] : FEC_NONE; + p->code_rate_LP = (reg[7] < 6) ? fe_code[reg[7]] : FEC_NONE; - p->u.ofdm.code_rate_HP = (reg[6] < 6) ? fe_code[reg[6]] : FEC_NONE; - p->u.ofdm.code_rate_LP = (reg[7] < 6) ? fe_code[reg[7]] : FEC_NONE; + /* Update internal state to reflect the autodetected props */ + state->constellation = p->modulation; + state->transmission_mode = p->transmission_mode; return 0; } -static int it913x_fe_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int it913x_fe_set_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct it913x_fe_state *state = fe->demodulator_priv; int ret, i; u8 empty_ch, last_ch; @@ -551,7 +626,7 @@ static int it913x_fe_set_frontend(struct dvb_frontend *fe, state->it913x_status = 0; /* Set bw*/ - ret = it913x_fe_select_bw(state, p->u.ofdm.bandwidth, + ret = it913x_fe_select_bw(state, p->bandwidth_hz, state->adcFrequency); /* Training Mode Off */ @@ -571,20 +646,25 @@ static int it913x_fe_set_frontend(struct dvb_frontend *fe, i = 1; else if ((p->frequency >= 1450000000) && (p->frequency <= 1680000000)) i = 2; - else - return -EOPNOTSUPP; + else + return -EOPNOTSUPP; ret = it913x_write_reg(state, PRO_DMOD, FREE_BAND, i); deb_info("Frontend Set Tuner Type %02x", state->tuner_type); switch (state->tuner_type) { - case IT9137: /* Tuner type 0x38 */ + case IT9135_38: + case IT9135_51: + case IT9135_52: + case IT9135_60: + case IT9135_61: + case IT9135_62: ret = it9137_set_tuner(state, - p->u.ofdm.bandwidth, p->frequency); + p->bandwidth_hz, p->frequency); break; default: if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); + fe->ops.tuner_ops.set_params(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); } @@ -678,16 +758,19 @@ static u32 compute_div(u32 a, u32 b, u32 x) static int it913x_fe_start(struct it913x_fe_state *state) { - struct it913xset *set_fe; + struct it913xset *set_lna; struct it913xset *set_mode; int ret; - u8 adf = (state->adf & 0xf); + u8 adf = (state->config->adf & 0xf); u32 adc, xtal; u8 b[4]; - ret = it913x_init_tuner(state); + if (state->config->chip_ver == 1) + ret = it913x_init_tuner(state); + + info("ADF table value :%02x", adf); - if (adf < 12) { + if (adf < 10) { state->crystalFrequency = fe_clockTable[adf].xtal ; state->table = fe_clockTable[adf].table; state->adcFrequency = state->table->adcFrequency; @@ -698,9 +781,6 @@ static int it913x_fe_start(struct it913x_fe_state *state) } else return -EINVAL; - deb_info("Xtal Freq :%d Adc Freq :%d Adc %08x Xtal %08x", - state->crystalFrequency, state->adcFrequency, adc, xtal); - /* Set LED indicator on GPIOH3 */ ret = it913x_write_reg(state, PRO_LINK, GPIOH3_EN, 0x1); ret |= it913x_write_reg(state, PRO_LINK, GPIOH3_ON, 0x1); @@ -721,22 +801,71 @@ static int it913x_fe_start(struct it913x_fe_state *state) b[2] = (adc >> 16) & 0xff; ret |= it913x_write(state, PRO_DMOD, ADC_FREQ, b, 3); + if (state->config->adc_x2) + ret |= it913x_write_reg(state, PRO_DMOD, ADC_X_2, 0x01); + b[0] = 0; + b[1] = 0; + b[2] = 0; + ret |= it913x_write(state, PRO_DMOD, 0x0029, b, 3); + + info("Crystal Frequency :%d Adc Frequency :%d ADC X2: %02x", + state->crystalFrequency, state->adcFrequency, + state->config->adc_x2); + deb_info("Xtal value :%04x Adc value :%04x", xtal, adc); + + if (ret < 0) + return -ENODEV; + + /* v1 or v2 tuner script */ + if (state->config->chip_ver > 1) + ret = it913x_fe_script_loader(state, it9135_v2); + else + ret = it913x_fe_script_loader(state, it9135_v1); + if (ret < 0) + return ret; + + /* LNA Scripts */ switch (state->tuner_type) { - case IT9137: /* Tuner type 0x38 */ - set_fe = it9137_set; + case IT9135_51: + set_lna = it9135_51; + break; + case IT9135_52: + set_lna = it9135_52; + break; + case IT9135_60: + set_lna = it9135_60; + break; + case IT9135_61: + set_lna = it9135_61; break; + case IT9135_62: + set_lna = it9135_62; + break; + case IT9135_38: default: - return -EINVAL; + set_lna = it9135_38; } + info("Tuner LNA type :%02x", state->tuner_type); + + ret = it913x_fe_script_loader(state, set_lna); + if (ret < 0) + return ret; + + if (state->config->chip_ver == 2) { + ret = it913x_write_reg(state, PRO_DMOD, TRIGGER_OFSM, 0x1); + ret |= it913x_write_reg(state, PRO_LINK, PADODPU, 0x0); + ret |= it913x_write_reg(state, PRO_LINK, AGC_O_D, 0x0); + ret |= it913x_init_tuner(state); + } + if (ret < 0) + return -ENODEV; - /* set the demod */ - ret = it913x_fe_script_loader(state, set_fe); /* Always solo frontend */ set_mode = set_solo_fe; ret |= it913x_fe_script_loader(state, set_mode); ret |= it913x_fe_suspend(state); - return 0; + return (ret < 0) ? -ENODEV : 0; } static int it913x_fe_init(struct dvb_frontend *fe) @@ -746,17 +875,11 @@ static int it913x_fe_init(struct dvb_frontend *fe) /* Power Up Tuner - common all versions */ ret = it913x_write_reg(state, PRO_DMOD, 0xec40, 0x1); - ret |= it913x_write_reg(state, PRO_DMOD, AFE_MEM0, 0x0); - ret |= it913x_fe_script_loader(state, init_1); - switch (state->tuner_type) { - case IT9137: - ret |= it913x_write_reg(state, PRO_DMOD, 0xfba8, 0x0); - break; - default: - return -EINVAL; - } + ret |= it913x_write_reg(state, PRO_DMOD, AFE_MEM0, 0x0); + + ret |= it913x_write_reg(state, PRO_DMOD, 0xfba8, 0x0); return (ret < 0) ? -ENODEV : 0; } @@ -770,19 +893,34 @@ static void it913x_fe_release(struct dvb_frontend *fe) static struct dvb_frontend_ops it913x_fe_ofdm_ops; struct dvb_frontend *it913x_fe_attach(struct i2c_adapter *i2c_adap, - u8 i2c_addr, u8 adf, u8 type) + u8 i2c_addr, struct ite_config *config) { struct it913x_fe_state *state = NULL; int ret; + /* allocate memory for the internal state */ state = kzalloc(sizeof(struct it913x_fe_state), GFP_KERNEL); if (state == NULL) + return NULL; + if (config == NULL) goto error; state->i2c_adap = i2c_adap; state->i2c_addr = i2c_addr; - state->adf = adf; - state->tuner_type = type; + state->config = config; + + switch (state->config->tuner_id_0) { + case IT9135_51: + case IT9135_52: + case IT9135_60: + case IT9135_61: + case IT9135_62: + state->tuner_type = state->config->tuner_id_0; + break; + default: + case IT9135_38: + state->tuner_type = IT9135_38; + } ret = it913x_fe_start(state); if (ret < 0) @@ -802,10 +940,9 @@ error: EXPORT_SYMBOL(it913x_fe_attach); static struct dvb_frontend_ops it913x_fe_ofdm_ops = { - + .delsys = { SYS_DVBT }, .info = { .name = "it913x-fe DVB-T", - .type = FE_OFDM, .frequency_min = 51000000, .frequency_max = 1680000000, .frequency_stepsize = 62500, @@ -835,5 +972,5 @@ static struct dvb_frontend_ops it913x_fe_ofdm_ops = { MODULE_DESCRIPTION("it913x Frontend and it9137 tuner"); MODULE_AUTHOR("Malcolm Priestley tvboxspy@gmail.com"); -MODULE_VERSION("1.07"); +MODULE_VERSION("1.13"); MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/it913x-fe.h b/drivers/media/dvb/frontends/it913x-fe.h index 9d97f32e690b..c4a908e354e0 100644 --- a/drivers/media/dvb/frontends/it913x-fe.h +++ b/drivers/media/dvb/frontends/it913x-fe.h @@ -23,13 +23,27 @@ #include <linux/dvb/frontend.h> #include "dvb_frontend.h" + +struct ite_config { + u8 chip_ver; + u16 chip_type; + u32 firmware; + u8 firmware_ver; + u8 adc_x2; + u8 tuner_id_0; + u8 tuner_id_1; + u8 dual_mode; + u8 adf; +}; + #if defined(CONFIG_DVB_IT913X_FE) || (defined(CONFIG_DVB_IT913X_FE_MODULE) && \ defined(MODULE)) extern struct dvb_frontend *it913x_fe_attach(struct i2c_adapter *i2c_adap, - u8 i2c_addr, u8 adf, u8 type); + u8 i2c_addr, struct ite_config *config); #else static inline struct dvb_frontend *it913x_fe_attach( - struct i2c_adapter *i2c_adap, u8 i2c_addr, u8 adf, u8 type) + struct i2c_adapter *i2c_adap, + u8 i2c_addr, struct ite_config *config) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; @@ -134,6 +148,16 @@ static inline struct dvb_frontend *it913x_fe_attach( #define COEFF_1_2048 0x0001 #define XTAL_CLK 0x0025 #define BFS_FCW 0x0029 + +/* Error Regs */ +#define RSD_ABORT_PKT_LSB 0x0032 +#define RSD_ABORT_PKT_MSB 0x0033 +#define RSD_BIT_ERR_0_7 0x0034 +#define RSD_BIT_ERR_8_15 0x0035 +#define RSD_BIT_ERR_23_16 0x0036 +#define RSD_BIT_COUNT_LSB 0x0037 +#define RSD_BIT_COUNT_MSB 0x0038 + #define TPSD_LOCK 0x003c #define TRAINING_MODE 0x0040 #define ADC_X_2 0x0045 @@ -144,8 +168,14 @@ static inline struct dvb_frontend *it913x_fe_attach( #define EST_SIGNAL_LEVEL 0x004a #define FREE_BAND 0x004b #define SUSPEND_FLAG 0x004c -/* Build in tuners */ +/* Build in tuner types */ #define IT9137 0x38 +#define IT9135_38 0x38 +#define IT9135_51 0x51 +#define IT9135_52 0x52 +#define IT9135_60 0x60 +#define IT9135_61 0x61 +#define IT9135_62 0x62 enum { CMD_DEMOD_READ = 0, @@ -193,4 +223,11 @@ enum { WRITE_CMD, }; +enum { + IT9135_AUTO = 0, + IT9137_FW, + IT9135_V1_FW, + IT9135_V2_FW, +}; + #endif /* IT913X_FE_H */ diff --git a/drivers/media/dvb/frontends/itd1000.c b/drivers/media/dvb/frontends/itd1000.c index aa9ccb821fa5..316457584fe7 100644 --- a/drivers/media/dvb/frontends/itd1000.c +++ b/drivers/media/dvb/frontends/itd1000.c @@ -250,13 +250,14 @@ static void itd1000_set_lo(struct itd1000_state *state, u32 freq_khz) itd1000_set_vco(state, freq_khz); } -static int itd1000_set_parameters(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) +static int itd1000_set_parameters(struct dvb_frontend *fe) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct itd1000_state *state = fe->tuner_priv; u8 pllcon1; - itd1000_set_lo(state, p->frequency); - itd1000_set_lpf_bw(state, p->u.qpsk.symbol_rate); + itd1000_set_lo(state, c->frequency); + itd1000_set_lpf_bw(state, c->symbol_rate); pllcon1 = itd1000_read_reg(state, PLLCON1) & 0x7f; itd1000_write_reg(state, PLLCON1, pllcon1 | (1 << 7)); diff --git a/drivers/media/dvb/frontends/ix2505v.c b/drivers/media/dvb/frontends/ix2505v.c index 9a517a4bf96d..bc5a82082aaa 100644 --- a/drivers/media/dvb/frontends/ix2505v.c +++ b/drivers/media/dvb/frontends/ix2505v.c @@ -129,12 +129,12 @@ static int ix2505v_release(struct dvb_frontend *fe) * 1 -> 8 -> 6 */ -static int ix2505v_set_params(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) +static int ix2505v_set_params(struct dvb_frontend *fe) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct ix2505v_state *state = fe->tuner_priv; - u32 frequency = params->frequency; - u32 b_w = (params->u.qpsk.symbol_rate * 27) / 32000; + u32 frequency = c->frequency; + u32 b_w = (c->symbol_rate * 27) / 32000; u32 div_factor, N , A, x; int ret = 0, len; u8 gain, cc, ref, psc, local_osc, lpf; diff --git a/drivers/media/dvb/frontends/l64781.c b/drivers/media/dvb/frontends/l64781.c index 445fa1068064..36fcf559e361 100644 --- a/drivers/media/dvb/frontends/l64781.c +++ b/drivers/media/dvb/frontends/l64781.c @@ -117,18 +117,17 @@ static int reset_and_configure (struct l64781_state* state) return (i2c_transfer(state->i2c, &msg, 1) == 1) ? 0 : -ENODEV; } -static int apply_frontend_param (struct dvb_frontend* fe, struct dvb_frontend_parameters *param) +static int apply_frontend_param(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct l64781_state* state = fe->demodulator_priv; /* The coderates for FEC_NONE, FEC_4_5 and FEC_FEC_6_7 are arbitrary */ static const u8 fec_tab[] = { 7, 0, 1, 2, 9, 3, 10, 4 }; /* QPSK, QAM_16, QAM_64 */ static const u8 qam_tab [] = { 2, 4, 0, 6 }; - static const u8 bw_tab [] = { 8, 7, 6 }; /* 8Mhz, 7MHz, 6MHz */ static const u8 guard_tab [] = { 1, 2, 4, 8 }; /* The Grundig 29504-401.04 Tuner comes with 18.432MHz crystal. */ static const u32 ppm = 8000; - struct dvb_ofdm_parameters *p = ¶m->u.ofdm; u32 ddfs_offset_fixed; /* u32 ddfs_offset_variable = 0x6000-((1000000UL+ppm)/ */ /* bw_tab[p->bandWidth]<<10)/15625; */ @@ -137,18 +136,29 @@ static int apply_frontend_param (struct dvb_frontend* fe, struct dvb_frontend_pa u8 val0x04; u8 val0x05; u8 val0x06; - int bw = p->bandwidth - BANDWIDTH_8_MHZ; + int bw; + + switch (p->bandwidth_hz) { + case 8000000: + bw = 8; + break; + case 7000000: + bw = 7; + break; + case 6000000: + bw = 6; + break; + default: + return -EINVAL; + } if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, param); + fe->ops.tuner_ops.set_params(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); } - if (param->inversion != INVERSION_ON && - param->inversion != INVERSION_OFF) - return -EINVAL; - - if (bw < 0 || bw > 2) + if (p->inversion != INVERSION_ON && + p->inversion != INVERSION_OFF) return -EINVAL; if (p->code_rate_HP != FEC_1_2 && p->code_rate_HP != FEC_2_3 && @@ -156,14 +166,14 @@ static int apply_frontend_param (struct dvb_frontend* fe, struct dvb_frontend_pa p->code_rate_HP != FEC_7_8) return -EINVAL; - if (p->hierarchy_information != HIERARCHY_NONE && + if (p->hierarchy != HIERARCHY_NONE && (p->code_rate_LP != FEC_1_2 && p->code_rate_LP != FEC_2_3 && p->code_rate_LP != FEC_3_4 && p->code_rate_LP != FEC_5_6 && p->code_rate_LP != FEC_7_8)) return -EINVAL; - if (p->constellation != QPSK && p->constellation != QAM_16 && - p->constellation != QAM_64) + if (p->modulation != QPSK && p->modulation != QAM_16 && + p->modulation != QAM_64) return -EINVAL; if (p->transmission_mode != TRANSMISSION_MODE_2K && @@ -174,22 +184,22 @@ static int apply_frontend_param (struct dvb_frontend* fe, struct dvb_frontend_pa p->guard_interval > GUARD_INTERVAL_1_4) return -EINVAL; - if (p->hierarchy_information < HIERARCHY_NONE || - p->hierarchy_information > HIERARCHY_4) + if (p->hierarchy < HIERARCHY_NONE || + p->hierarchy > HIERARCHY_4) return -EINVAL; - ddfs_offset_fixed = 0x4000-(ppm<<16)/bw_tab[p->bandwidth]/1000000; + ddfs_offset_fixed = 0x4000-(ppm<<16)/bw/1000000; /* This works up to 20000 ppm, it overflows if too large ppm! */ init_freq = (((8UL<<25) + (8UL<<19) / 25*ppm / (15625/25)) / - bw_tab[p->bandwidth] & 0xFFFFFF); + bw & 0xFFFFFF); /* SPI bias calculation is slightly modified to fit in 32bit */ /* will work for high ppm only... */ spi_bias = 378 * (1 << 10); spi_bias *= 16; - spi_bias *= bw_tab[p->bandwidth]; - spi_bias *= qam_tab[p->constellation]; + spi_bias *= bw; + spi_bias *= qam_tab[p->modulation]; spi_bias /= p->code_rate_HP + 1; spi_bias /= (guard_tab[p->guard_interval] + 32); spi_bias *= 1000; @@ -199,10 +209,10 @@ static int apply_frontend_param (struct dvb_frontend* fe, struct dvb_frontend_pa val0x04 = (p->transmission_mode << 2) | p->guard_interval; val0x05 = fec_tab[p->code_rate_HP]; - if (p->hierarchy_information != HIERARCHY_NONE) + if (p->hierarchy != HIERARCHY_NONE) val0x05 |= (p->code_rate_LP - FEC_1_2) << 3; - val0x06 = (p->hierarchy_information << 2) | p->constellation; + val0x06 = (p->hierarchy << 2) | p->modulation; l64781_writereg (state, 0x04, val0x04); l64781_writereg (state, 0x05, val0x05); @@ -220,7 +230,7 @@ static int apply_frontend_param (struct dvb_frontend* fe, struct dvb_frontend_pa l64781_writereg (state, 0x1b, spi_bias & 0xff); l64781_writereg (state, 0x1c, (spi_bias >> 8) & 0xff); l64781_writereg (state, 0x1d, ((spi_bias >> 16) & 0x7f) | - (param->inversion == INVERSION_ON ? 0x80 : 0x00)); + (p->inversion == INVERSION_ON ? 0x80 : 0x00)); l64781_writereg (state, 0x22, ddfs_offset_fixed & 0xff); l64781_writereg (state, 0x23, (ddfs_offset_fixed >> 8) & 0x3f); @@ -233,8 +243,9 @@ static int apply_frontend_param (struct dvb_frontend* fe, struct dvb_frontend_pa return 0; } -static int get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters* param) +static int get_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct l64781_state* state = fe->demodulator_priv; int tmp; @@ -242,98 +253,95 @@ static int get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters* tmp = l64781_readreg(state, 0x04); switch(tmp & 3) { case 0: - param->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; + p->guard_interval = GUARD_INTERVAL_1_32; break; case 1: - param->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; + p->guard_interval = GUARD_INTERVAL_1_16; break; case 2: - param->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; + p->guard_interval = GUARD_INTERVAL_1_8; break; case 3: - param->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; + p->guard_interval = GUARD_INTERVAL_1_4; break; } switch((tmp >> 2) & 3) { case 0: - param->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; + p->transmission_mode = TRANSMISSION_MODE_2K; break; case 1: - param->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; + p->transmission_mode = TRANSMISSION_MODE_8K; break; default: - printk("Unexpected value for transmission_mode\n"); + printk(KERN_WARNING "Unexpected value for transmission_mode\n"); } - - tmp = l64781_readreg(state, 0x05); switch(tmp & 7) { case 0: - param->u.ofdm.code_rate_HP = FEC_1_2; + p->code_rate_HP = FEC_1_2; break; case 1: - param->u.ofdm.code_rate_HP = FEC_2_3; + p->code_rate_HP = FEC_2_3; break; case 2: - param->u.ofdm.code_rate_HP = FEC_3_4; + p->code_rate_HP = FEC_3_4; break; case 3: - param->u.ofdm.code_rate_HP = FEC_5_6; + p->code_rate_HP = FEC_5_6; break; case 4: - param->u.ofdm.code_rate_HP = FEC_7_8; + p->code_rate_HP = FEC_7_8; break; default: printk("Unexpected value for code_rate_HP\n"); } switch((tmp >> 3) & 7) { case 0: - param->u.ofdm.code_rate_LP = FEC_1_2; + p->code_rate_LP = FEC_1_2; break; case 1: - param->u.ofdm.code_rate_LP = FEC_2_3; + p->code_rate_LP = FEC_2_3; break; case 2: - param->u.ofdm.code_rate_LP = FEC_3_4; + p->code_rate_LP = FEC_3_4; break; case 3: - param->u.ofdm.code_rate_LP = FEC_5_6; + p->code_rate_LP = FEC_5_6; break; case 4: - param->u.ofdm.code_rate_LP = FEC_7_8; + p->code_rate_LP = FEC_7_8; break; default: printk("Unexpected value for code_rate_LP\n"); } - tmp = l64781_readreg(state, 0x06); switch(tmp & 3) { case 0: - param->u.ofdm.constellation = QPSK; + p->modulation = QPSK; break; case 1: - param->u.ofdm.constellation = QAM_16; + p->modulation = QAM_16; break; case 2: - param->u.ofdm.constellation = QAM_64; + p->modulation = QAM_64; break; default: - printk("Unexpected value for constellation\n"); + printk(KERN_WARNING "Unexpected value for modulation\n"); } switch((tmp >> 2) & 7) { case 0: - param->u.ofdm.hierarchy_information = HIERARCHY_NONE; + p->hierarchy = HIERARCHY_NONE; break; case 1: - param->u.ofdm.hierarchy_information = HIERARCHY_1; + p->hierarchy = HIERARCHY_1; break; case 2: - param->u.ofdm.hierarchy_information = HIERARCHY_2; + p->hierarchy = HIERARCHY_2; break; case 3: - param->u.ofdm.hierarchy_information = HIERARCHY_4; + p->hierarchy = HIERARCHY_4; break; default: printk("Unexpected value for hierarchy\n"); @@ -341,12 +349,12 @@ static int get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters* tmp = l64781_readreg (state, 0x1d); - param->inversion = (tmp & 0x80) ? INVERSION_ON : INVERSION_OFF; + p->inversion = (tmp & 0x80) ? INVERSION_ON : INVERSION_OFF; tmp = (int) (l64781_readreg (state, 0x08) | (l64781_readreg (state, 0x09) << 8) | (l64781_readreg (state, 0x0a) << 16)); - param->frequency += tmp; + p->frequency += tmp; return 0; } @@ -564,10 +572,9 @@ error: } static struct dvb_frontend_ops l64781_ops = { - + .delsys = { SYS_DVBT }, .info = { .name = "LSI L64781 DVB-T", - .type = FE_OFDM, /* .frequency_min = ???,*/ /* .frequency_max = ???,*/ .frequency_stepsize = 166666, diff --git a/drivers/media/dvb/frontends/lgdt3305.c b/drivers/media/dvb/frontends/lgdt3305.c index 3272881cb112..1d2c47378cf8 100644 --- a/drivers/media/dvb/frontends/lgdt3305.c +++ b/drivers/media/dvb/frontends/lgdt3305.c @@ -266,7 +266,7 @@ fail: } static int lgdt3305_set_modulation(struct lgdt3305_state *state, - struct dvb_frontend_parameters *param) + struct dtv_frontend_properties *p) { u8 opermode; int ret; @@ -279,7 +279,7 @@ static int lgdt3305_set_modulation(struct lgdt3305_state *state, opermode &= ~0x03; - switch (param->u.vsb.modulation) { + switch (p->modulation) { case VSB_8: opermode |= 0x03; break; @@ -298,11 +298,11 @@ fail: } static int lgdt3305_set_filter_extension(struct lgdt3305_state *state, - struct dvb_frontend_parameters *param) + struct dtv_frontend_properties *p) { int val; - switch (param->u.vsb.modulation) { + switch (p->modulation) { case VSB_8: val = 0; break; @@ -321,11 +321,11 @@ static int lgdt3305_set_filter_extension(struct lgdt3305_state *state, /* ------------------------------------------------------------------------ */ static int lgdt3305_passband_digital_agc(struct lgdt3305_state *state, - struct dvb_frontend_parameters *param) + struct dtv_frontend_properties *p) { u16 agc_ref; - switch (param->u.vsb.modulation) { + switch (p->modulation) { case VSB_8: agc_ref = 0x32c4; break; @@ -348,11 +348,11 @@ static int lgdt3305_passband_digital_agc(struct lgdt3305_state *state, } static int lgdt3305_rfagc_loop(struct lgdt3305_state *state, - struct dvb_frontend_parameters *param) + struct dtv_frontend_properties *p) { u16 ifbw, rfbw, agcdelay; - switch (param->u.vsb.modulation) { + switch (p->modulation) { case VSB_8: agcdelay = 0x04c0; rfbw = 0x8000; @@ -398,11 +398,11 @@ static int lgdt3305_rfagc_loop(struct lgdt3305_state *state, } static int lgdt3305_agc_setup(struct lgdt3305_state *state, - struct dvb_frontend_parameters *param) + struct dtv_frontend_properties *p) { int lockdten, acqen; - switch (param->u.vsb.modulation) { + switch (p->modulation) { case VSB_8: lockdten = 0; acqen = 0; @@ -432,15 +432,15 @@ static int lgdt3305_agc_setup(struct lgdt3305_state *state, return -EINVAL; } - return lgdt3305_rfagc_loop(state, param); + return lgdt3305_rfagc_loop(state, p); } static int lgdt3305_set_agc_power_ref(struct lgdt3305_state *state, - struct dvb_frontend_parameters *param) + struct dtv_frontend_properties *p) { u16 usref = 0; - switch (param->u.vsb.modulation) { + switch (p->modulation) { case VSB_8: if (state->cfg->usref_8vsb) usref = state->cfg->usref_8vsb; @@ -473,14 +473,14 @@ static int lgdt3305_set_agc_power_ref(struct lgdt3305_state *state, /* ------------------------------------------------------------------------ */ static int lgdt3305_spectral_inversion(struct lgdt3305_state *state, - struct dvb_frontend_parameters *param, + struct dtv_frontend_properties *p, int inversion) { int ret; lg_dbg("(%d)\n", inversion); - switch (param->u.vsb.modulation) { + switch (p->modulation) { case VSB_8: ret = lgdt3305_write_reg(state, LGDT3305_CR_CTRL_7, inversion ? 0xf9 : 0x79); @@ -497,13 +497,13 @@ static int lgdt3305_spectral_inversion(struct lgdt3305_state *state, } static int lgdt3305_set_if(struct lgdt3305_state *state, - struct dvb_frontend_parameters *param) + struct dtv_frontend_properties *p) { u16 if_freq_khz; u8 nco1, nco2, nco3, nco4; u64 nco; - switch (param->u.vsb.modulation) { + switch (p->modulation) { case VSB_8: if_freq_khz = state->cfg->vsb_if_khz; break; @@ -517,7 +517,7 @@ static int lgdt3305_set_if(struct lgdt3305_state *state, nco = if_freq_khz / 10; - switch (param->u.vsb.modulation) { + switch (p->modulation) { case VSB_8: nco <<= 24; do_div(nco, 625); @@ -677,37 +677,37 @@ fail: return ret; } -static int lgdt3304_set_parameters(struct dvb_frontend *fe, - struct dvb_frontend_parameters *param) +static int lgdt3304_set_parameters(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct lgdt3305_state *state = fe->demodulator_priv; int ret; - lg_dbg("(%d, %d)\n", param->frequency, param->u.vsb.modulation); + lg_dbg("(%d, %d)\n", p->frequency, p->modulation); if (fe->ops.tuner_ops.set_params) { - ret = fe->ops.tuner_ops.set_params(fe, param); + ret = fe->ops.tuner_ops.set_params(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); if (lg_fail(ret)) goto fail; - state->current_frequency = param->frequency; + state->current_frequency = p->frequency; } - ret = lgdt3305_set_modulation(state, param); + ret = lgdt3305_set_modulation(state, p); if (lg_fail(ret)) goto fail; - ret = lgdt3305_passband_digital_agc(state, param); + ret = lgdt3305_passband_digital_agc(state, p); if (lg_fail(ret)) goto fail; - ret = lgdt3305_agc_setup(state, param); + ret = lgdt3305_agc_setup(state, p); if (lg_fail(ret)) goto fail; /* reg 0x030d is 3304-only... seen in vsb and qam usbsnoops... */ - switch (param->u.vsb.modulation) { + switch (p->modulation) { case VSB_8: lgdt3305_write_reg(state, 0x030d, 0x00); lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_1, 0x4f); @@ -718,7 +718,7 @@ static int lgdt3304_set_parameters(struct dvb_frontend *fe, case QAM_64: case QAM_256: lgdt3305_write_reg(state, 0x030d, 0x14); - ret = lgdt3305_set_if(state, param); + ret = lgdt3305_set_if(state, p); if (lg_fail(ret)) goto fail; break; @@ -727,13 +727,13 @@ static int lgdt3304_set_parameters(struct dvb_frontend *fe, } - ret = lgdt3305_spectral_inversion(state, param, + ret = lgdt3305_spectral_inversion(state, p, state->cfg->spectral_inversion ? 1 : 0); if (lg_fail(ret)) goto fail; - state->current_modulation = param->u.vsb.modulation; + state->current_modulation = p->modulation; ret = lgdt3305_mpeg_mode(state, state->cfg->mpeg_mode); if (lg_fail(ret)) @@ -747,34 +747,34 @@ fail: return ret; } -static int lgdt3305_set_parameters(struct dvb_frontend *fe, - struct dvb_frontend_parameters *param) +static int lgdt3305_set_parameters(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct lgdt3305_state *state = fe->demodulator_priv; int ret; - lg_dbg("(%d, %d)\n", param->frequency, param->u.vsb.modulation); + lg_dbg("(%d, %d)\n", p->frequency, p->modulation); if (fe->ops.tuner_ops.set_params) { - ret = fe->ops.tuner_ops.set_params(fe, param); + ret = fe->ops.tuner_ops.set_params(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); if (lg_fail(ret)) goto fail; - state->current_frequency = param->frequency; + state->current_frequency = p->frequency; } - ret = lgdt3305_set_modulation(state, param); + ret = lgdt3305_set_modulation(state, p); if (lg_fail(ret)) goto fail; - ret = lgdt3305_passband_digital_agc(state, param); + ret = lgdt3305_passband_digital_agc(state, p); if (lg_fail(ret)) goto fail; - ret = lgdt3305_set_agc_power_ref(state, param); + ret = lgdt3305_set_agc_power_ref(state, p); if (lg_fail(ret)) goto fail; - ret = lgdt3305_agc_setup(state, param); + ret = lgdt3305_agc_setup(state, p); if (lg_fail(ret)) goto fail; @@ -786,20 +786,20 @@ static int lgdt3305_set_parameters(struct dvb_frontend *fe, if (lg_fail(ret)) goto fail; - ret = lgdt3305_set_if(state, param); + ret = lgdt3305_set_if(state, p); if (lg_fail(ret)) goto fail; - ret = lgdt3305_spectral_inversion(state, param, + ret = lgdt3305_spectral_inversion(state, p, state->cfg->spectral_inversion ? 1 : 0); if (lg_fail(ret)) goto fail; - ret = lgdt3305_set_filter_extension(state, param); + ret = lgdt3305_set_filter_extension(state, p); if (lg_fail(ret)) goto fail; - state->current_modulation = param->u.vsb.modulation; + state->current_modulation = p->modulation; ret = lgdt3305_mpeg_mode(state, state->cfg->mpeg_mode); if (lg_fail(ret)) @@ -813,15 +813,15 @@ fail: return ret; } -static int lgdt3305_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *param) +static int lgdt3305_get_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct lgdt3305_state *state = fe->demodulator_priv; lg_dbg("\n"); - param->u.vsb.modulation = state->current_modulation; - param->frequency = state->current_frequency; + p->modulation = state->current_modulation; + p->frequency = state->current_frequency; return 0; } @@ -1166,9 +1166,9 @@ fail: EXPORT_SYMBOL(lgdt3305_attach); static struct dvb_frontend_ops lgdt3304_ops = { + .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, .info = { .name = "LG Electronics LGDT3304 VSB/QAM Frontend", - .type = FE_ATSC, .frequency_min = 54000000, .frequency_max = 858000000, .frequency_stepsize = 62500, @@ -1188,9 +1188,9 @@ static struct dvb_frontend_ops lgdt3304_ops = { }; static struct dvb_frontend_ops lgdt3305_ops = { + .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, .info = { .name = "LG Electronics LGDT3305 VSB/QAM Frontend", - .type = FE_ATSC, .frequency_min = 54000000, .frequency_max = 858000000, .frequency_stepsize = 62500, diff --git a/drivers/media/dvb/frontends/lgdt330x.c b/drivers/media/dvb/frontends/lgdt330x.c index 43971e63baa7..c990d35a13dc 100644 --- a/drivers/media/dvb/frontends/lgdt330x.c +++ b/drivers/media/dvb/frontends/lgdt330x.c @@ -288,6 +288,8 @@ static int lgdt330x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) int err; u8 buf[2]; + *ucblocks = 0; + switch (state->config->demod_chip) { case LGDT3302: err = i2c_read_demod_bytes(state, LGDT3302_PACKET_ERR_COUNTER1, @@ -302,14 +304,16 @@ static int lgdt330x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) "Only LGDT3302 and LGDT3303 are supported chips.\n"); err = -ENODEV; } + if (err < 0) + return err; *ucblocks = (buf[0] << 8) | buf[1]; return 0; } -static int lgdt330x_set_parameters(struct dvb_frontend* fe, - struct dvb_frontend_parameters *param) +static int lgdt330x_set_parameters(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; /* * Array of byte pairs <address, value> * to initialize 8VSB for lgdt3303 chip 50 MHz IF @@ -343,10 +347,10 @@ static int lgdt330x_set_parameters(struct dvb_frontend* fe, static u8 top_ctrl_cfg[] = { TOP_CONTROL, 0x03 }; - int err; + int err = 0; /* Change only if we are actually changing the modulation */ - if (state->current_modulation != param->u.vsb.modulation) { - switch(param->u.vsb.modulation) { + if (state->current_modulation != p->modulation) { + switch (p->modulation) { case VSB_8: dprintk("%s: VSB_8 MODE\n", __func__); @@ -395,9 +399,14 @@ static int lgdt330x_set_parameters(struct dvb_frontend* fe, } break; default: - printk(KERN_WARNING "lgdt330x: %s: Modulation type(%d) UNSUPPORTED\n", __func__, param->u.vsb.modulation); + printk(KERN_WARNING "lgdt330x: %s: Modulation type(%d) UNSUPPORTED\n", __func__, p->modulation); return -1; } + if (err < 0) + printk(KERN_WARNING "lgdt330x: %s: error blasting " + "bytes to lgdt3303 for modulation type(%d)\n", + __func__, p->modulation); + /* * select serial or parallel MPEG harware interface * Serial: 0x04 for LGDT3302 or 0x40 for LGDT3303 @@ -410,29 +419,29 @@ static int lgdt330x_set_parameters(struct dvb_frontend* fe, sizeof(top_ctrl_cfg)); if (state->config->set_ts_params) state->config->set_ts_params(fe, 0); - state->current_modulation = param->u.vsb.modulation; + state->current_modulation = p->modulation; } /* Tune to the specified frequency */ if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, param); + fe->ops.tuner_ops.set_params(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); } /* Keep track of the new frequency */ /* FIXME this is the wrong way to do this... */ /* The tuner is shared with the video4linux analog API */ - state->current_frequency = param->frequency; + state->current_frequency = p->frequency; lgdt330x_SwReset(state); return 0; } -static int lgdt330x_get_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters* param) +static int lgdt330x_get_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct lgdt330x_state *state = fe->demodulator_priv; - param->frequency = state->current_frequency; + p->frequency = state->current_frequency; return 0; } @@ -762,9 +771,9 @@ error: } static struct dvb_frontend_ops lgdt3302_ops = { + .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, .info = { .name= "LG Electronics LGDT3302 VSB/QAM Frontend", - .type = FE_ATSC, .frequency_min= 54000000, .frequency_max= 858000000, .frequency_stepsize= 62500, @@ -785,9 +794,9 @@ static struct dvb_frontend_ops lgdt3302_ops = { }; static struct dvb_frontend_ops lgdt3303_ops = { + .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, .info = { .name= "LG Electronics LGDT3303 VSB/QAM Frontend", - .type = FE_ATSC, .frequency_min= 54000000, .frequency_max= 858000000, .frequency_stepsize= 62500, diff --git a/drivers/media/dvb/frontends/lgs8gl5.c b/drivers/media/dvb/frontends/lgs8gl5.c index bb37ed289a05..2cec8041a106 100644 --- a/drivers/media/dvb/frontends/lgs8gl5.c +++ b/drivers/media/dvb/frontends/lgs8gl5.c @@ -311,18 +311,18 @@ lgs8gl5_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) static int -lgs8gl5_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +lgs8gl5_set_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct lgs8gl5_state *state = fe->demodulator_priv; dprintk("%s\n", __func__); - if (p->u.ofdm.bandwidth != BANDWIDTH_8_MHZ) + if (p->bandwidth_hz != 8000000) return -EINVAL; if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); + fe->ops.tuner_ops.set_params(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); } @@ -336,22 +336,21 @@ lgs8gl5_set_frontend(struct dvb_frontend *fe, static int -lgs8gl5_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +lgs8gl5_get_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct lgs8gl5_state *state = fe->demodulator_priv; u8 inv = lgs8gl5_read_reg(state, REG_INVERSION); - struct dvb_ofdm_parameters *o = &p->u.ofdm; p->inversion = (inv & REG_INVERSION_ON) ? INVERSION_ON : INVERSION_OFF; - o->code_rate_HP = FEC_1_2; - o->code_rate_LP = FEC_7_8; - o->guard_interval = GUARD_INTERVAL_1_32; - o->transmission_mode = TRANSMISSION_MODE_2K; - o->constellation = QAM_64; - o->hierarchy_information = HIERARCHY_NONE; - o->bandwidth = BANDWIDTH_8_MHZ; + p->code_rate_HP = FEC_1_2; + p->code_rate_LP = FEC_7_8; + p->guard_interval = GUARD_INTERVAL_1_32; + p->transmission_mode = TRANSMISSION_MODE_2K; + p->modulation = QAM_64; + p->hierarchy = HIERARCHY_NONE; + p->bandwidth_hz = 8000000; return 0; } @@ -413,9 +412,9 @@ EXPORT_SYMBOL(lgs8gl5_attach); static struct dvb_frontend_ops lgs8gl5_ops = { + .delsys = { SYS_DMBTH }, .info = { .name = "Legend Silicon LGS-8GL5 DMB-TH", - .type = FE_OFDM, .frequency_min = 474000000, .frequency_max = 858000000, .frequency_stepsize = 10000, diff --git a/drivers/media/dvb/frontends/lgs8gxx.c b/drivers/media/dvb/frontends/lgs8gxx.c index 1172b54689f8..4de1d3520cd2 100644 --- a/drivers/media/dvb/frontends/lgs8gxx.c +++ b/drivers/media/dvb/frontends/lgs8gxx.c @@ -669,16 +669,16 @@ static int lgs8gxx_write(struct dvb_frontend *fe, const u8 buf[], int len) return lgs8gxx_write_reg(priv, buf[0], buf[1]); } -static int lgs8gxx_set_fe(struct dvb_frontend *fe, - struct dvb_frontend_parameters *fe_params) +static int lgs8gxx_set_fe(struct dvb_frontend *fe) { + struct lgs8gxx_state *priv = fe->demodulator_priv; dprintk("%s\n", __func__); /* set frequency */ if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, fe_params); + fe->ops.tuner_ops.set_params(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); } @@ -691,9 +691,9 @@ static int lgs8gxx_set_fe(struct dvb_frontend *fe, return 0; } -static int lgs8gxx_get_fe(struct dvb_frontend *fe, - struct dvb_frontend_parameters *fe_params) +static int lgs8gxx_get_fe(struct dvb_frontend *fe) { + struct dtv_frontend_properties *fe_params = &fe->dtv_property_cache; dprintk("%s\n", __func__); /* TODO: get real readings from device */ @@ -701,21 +701,21 @@ static int lgs8gxx_get_fe(struct dvb_frontend *fe, fe_params->inversion = INVERSION_OFF; /* bandwidth */ - fe_params->u.ofdm.bandwidth = BANDWIDTH_8_MHZ; + fe_params->bandwidth_hz = 8000000; - fe_params->u.ofdm.code_rate_HP = FEC_AUTO; - fe_params->u.ofdm.code_rate_LP = FEC_AUTO; + fe_params->code_rate_HP = FEC_AUTO; + fe_params->code_rate_LP = FEC_AUTO; - fe_params->u.ofdm.constellation = QAM_AUTO; + fe_params->modulation = QAM_AUTO; /* transmission mode */ - fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO; + fe_params->transmission_mode = TRANSMISSION_MODE_AUTO; /* guard interval */ - fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_AUTO; + fe_params->guard_interval = GUARD_INTERVAL_AUTO; /* hierarchy */ - fe_params->u.ofdm.hierarchy_information = HIERARCHY_NONE; + fe_params->hierarchy = HIERARCHY_NONE; return 0; } @@ -994,9 +994,9 @@ static int lgs8gxx_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) } static struct dvb_frontend_ops lgs8gxx_ops = { + .delsys = { SYS_DMBTH }, .info = { .name = "Legend Silicon LGS8913/LGS8GXX DMB-TH", - .type = FE_OFDM, .frequency_min = 474000000, .frequency_max = 858000000, .frequency_stepsize = 10000, diff --git a/drivers/media/dvb/frontends/mb86a16.c b/drivers/media/dvb/frontends/mb86a16.c index c283112051b1..9ae40abfd71a 100644 --- a/drivers/media/dvb/frontends/mb86a16.c +++ b/drivers/media/dvb/frontends/mb86a16.c @@ -1621,13 +1621,13 @@ err: return -EREMOTEIO; } -static enum dvbfe_search mb86a16_search(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static enum dvbfe_search mb86a16_search(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct mb86a16_state *state = fe->demodulator_priv; state->frequency = p->frequency / 1000; - state->srate = p->u.qpsk.symbol_rate / 1000; + state->srate = p->symbol_rate / 1000; if (!mb86a16_set_fe(state)) { dprintk(verbose, MB86A16_ERROR, 1, "Successfully acquired LOCK"); @@ -1814,9 +1814,9 @@ static enum dvbfe_algo mb86a16_frontend_algo(struct dvb_frontend *fe) } static struct dvb_frontend_ops mb86a16_ops = { + .delsys = { SYS_DVBS }, .info = { .name = "Fujitsu MB86A16 DVB-S", - .type = FE_QPSK, .frequency_min = 950000, .frequency_max = 2150000, .frequency_stepsize = 3000, diff --git a/drivers/media/dvb/frontends/mb86a20s.c b/drivers/media/dvb/frontends/mb86a20s.c index 0f867a5055fb..7fa3e472cdca 100644 --- a/drivers/media/dvb/frontends/mb86a20s.c +++ b/drivers/media/dvb/frontends/mb86a20s.c @@ -61,244 +61,111 @@ static struct regdata mb86a20s_init[] = { { 0x70, 0xff }, { 0x08, 0x01 }, { 0x09, 0x3e }, - { 0x50, 0xd1 }, - { 0x51, 0x22 }, + { 0x50, 0xd1 }, { 0x51, 0x22 }, { 0x39, 0x01 }, { 0x71, 0x00 }, - { 0x28, 0x2a }, - { 0x29, 0x00 }, - { 0x2a, 0xff }, - { 0x2b, 0x80 }, - { 0x28, 0x20 }, - { 0x29, 0x33 }, - { 0x2a, 0xdf }, - { 0x2b, 0xa9 }, + { 0x28, 0x2a }, { 0x29, 0x00 }, { 0x2a, 0xff }, { 0x2b, 0x80 }, + { 0x28, 0x20 }, { 0x29, 0x33 }, { 0x2a, 0xdf }, { 0x2b, 0xa9 }, + { 0x28, 0x22 }, { 0x29, 0x00 }, { 0x2a, 0x1f }, { 0x2b, 0xf0 }, { 0x3b, 0x21 }, { 0x3c, 0x3a }, { 0x01, 0x0d }, - { 0x04, 0x08 }, - { 0x05, 0x05 }, - { 0x04, 0x0e }, - { 0x05, 0x00 }, - { 0x04, 0x0f }, - { 0x05, 0x14 }, - { 0x04, 0x0b }, - { 0x05, 0x8c }, - { 0x04, 0x00 }, - { 0x05, 0x00 }, - { 0x04, 0x01 }, - { 0x05, 0x07 }, - { 0x04, 0x02 }, - { 0x05, 0x0f }, - { 0x04, 0x03 }, - { 0x05, 0xa0 }, - { 0x04, 0x09 }, - { 0x05, 0x00 }, - { 0x04, 0x0a }, - { 0x05, 0xff }, - { 0x04, 0x27 }, - { 0x05, 0x64 }, - { 0x04, 0x28 }, - { 0x05, 0x00 }, - { 0x04, 0x1e }, - { 0x05, 0xff }, - { 0x04, 0x29 }, - { 0x05, 0x0a }, - { 0x04, 0x32 }, - { 0x05, 0x0a }, - { 0x04, 0x14 }, - { 0x05, 0x02 }, - { 0x04, 0x04 }, - { 0x05, 0x00 }, - { 0x04, 0x05 }, - { 0x05, 0x22 }, - { 0x04, 0x06 }, - { 0x05, 0x0e }, - { 0x04, 0x07 }, - { 0x05, 0xd8 }, - { 0x04, 0x12 }, - { 0x05, 0x00 }, - { 0x04, 0x13 }, - { 0x05, 0xff }, + { 0x04, 0x08 }, { 0x05, 0x05 }, + { 0x04, 0x0e }, { 0x05, 0x00 }, + { 0x04, 0x0f }, { 0x05, 0x14 }, + { 0x04, 0x0b }, { 0x05, 0x8c }, + { 0x04, 0x00 }, { 0x05, 0x00 }, + { 0x04, 0x01 }, { 0x05, 0x07 }, + { 0x04, 0x02 }, { 0x05, 0x0f }, + { 0x04, 0x03 }, { 0x05, 0xa0 }, + { 0x04, 0x09 }, { 0x05, 0x00 }, + { 0x04, 0x0a }, { 0x05, 0xff }, + { 0x04, 0x27 }, { 0x05, 0x64 }, + { 0x04, 0x28 }, { 0x05, 0x00 }, + { 0x04, 0x1e }, { 0x05, 0xff }, + { 0x04, 0x29 }, { 0x05, 0x0a }, + { 0x04, 0x32 }, { 0x05, 0x0a }, + { 0x04, 0x14 }, { 0x05, 0x02 }, + { 0x04, 0x04 }, { 0x05, 0x00 }, + { 0x04, 0x05 }, { 0x05, 0x22 }, + { 0x04, 0x06 }, { 0x05, 0x0e }, + { 0x04, 0x07 }, { 0x05, 0xd8 }, + { 0x04, 0x12 }, { 0x05, 0x00 }, + { 0x04, 0x13 }, { 0x05, 0xff }, + { 0x04, 0x15 }, { 0x05, 0x4e }, + { 0x04, 0x16 }, { 0x05, 0x20 }, { 0x52, 0x01 }, - { 0x50, 0xa7 }, - { 0x51, 0x00 }, - { 0x50, 0xa8 }, - { 0x51, 0xff }, - { 0x50, 0xa9 }, - { 0x51, 0xff }, - { 0x50, 0xaa }, - { 0x51, 0x00 }, - { 0x50, 0xab }, - { 0x51, 0xff }, - { 0x50, 0xac }, - { 0x51, 0xff }, - { 0x50, 0xad }, - { 0x51, 0x00 }, - { 0x50, 0xae }, - { 0x51, 0xff }, - { 0x50, 0xaf }, - { 0x51, 0xff }, + { 0x50, 0xa7 }, { 0x51, 0xff }, + { 0x50, 0xa8 }, { 0x51, 0xff }, + { 0x50, 0xa9 }, { 0x51, 0xff }, + { 0x50, 0xaa }, { 0x51, 0xff }, + { 0x50, 0xab }, { 0x51, 0xff }, + { 0x50, 0xac }, { 0x51, 0xff }, + { 0x50, 0xad }, { 0x51, 0xff }, + { 0x50, 0xae }, { 0x51, 0xff }, + { 0x50, 0xaf }, { 0x51, 0xff }, { 0x5e, 0x07 }, - { 0x50, 0xdc }, - { 0x51, 0x01 }, - { 0x50, 0xdd }, - { 0x51, 0xf4 }, - { 0x50, 0xde }, - { 0x51, 0x01 }, - { 0x50, 0xdf }, - { 0x51, 0xf4 }, - { 0x50, 0xe0 }, - { 0x51, 0x01 }, - { 0x50, 0xe1 }, - { 0x51, 0xf4 }, - { 0x50, 0xb0 }, - { 0x51, 0x07 }, - { 0x50, 0xb2 }, - { 0x51, 0xff }, - { 0x50, 0xb3 }, - { 0x51, 0xff }, - { 0x50, 0xb4 }, - { 0x51, 0xff }, - { 0x50, 0xb5 }, - { 0x51, 0xff }, - { 0x50, 0xb6 }, - { 0x51, 0xff }, - { 0x50, 0xb7 }, - { 0x51, 0xff }, - { 0x50, 0x50 }, - { 0x51, 0x02 }, - { 0x50, 0x51 }, - { 0x51, 0x04 }, + { 0x50, 0xdc }, { 0x51, 0x01 }, + { 0x50, 0xdd }, { 0x51, 0xf4 }, + { 0x50, 0xde }, { 0x51, 0x01 }, + { 0x50, 0xdf }, { 0x51, 0xf4 }, + { 0x50, 0xe0 }, { 0x51, 0x01 }, + { 0x50, 0xe1 }, { 0x51, 0xf4 }, + { 0x50, 0xb0 }, { 0x51, 0x07 }, + { 0x50, 0xb2 }, { 0x51, 0xff }, + { 0x50, 0xb3 }, { 0x51, 0xff }, + { 0x50, 0xb4 }, { 0x51, 0xff }, + { 0x50, 0xb5 }, { 0x51, 0xff }, + { 0x50, 0xb6 }, { 0x51, 0xff }, + { 0x50, 0xb7 }, { 0x51, 0xff }, + { 0x50, 0x50 }, { 0x51, 0x02 }, + { 0x50, 0x51 }, { 0x51, 0x04 }, { 0x45, 0x04 }, { 0x48, 0x04 }, - { 0x50, 0xd5 }, - { 0x51, 0x01 }, /* Serial */ - { 0x50, 0xd6 }, - { 0x51, 0x1f }, - { 0x50, 0xd2 }, - { 0x51, 0x03 }, - { 0x50, 0xd7 }, - { 0x51, 0x3f }, + { 0x50, 0xd5 }, { 0x51, 0x01 }, /* Serial */ + { 0x50, 0xd6 }, { 0x51, 0x1f }, + { 0x50, 0xd2 }, { 0x51, 0x03 }, + { 0x50, 0xd7 }, { 0x51, 0x3f }, + { 0x28, 0x74 }, { 0x29, 0x00 }, { 0x28, 0x74 }, { 0x29, 0x40 }, + { 0x28, 0x46 }, { 0x29, 0x2c }, { 0x28, 0x46 }, { 0x29, 0x0c }, + { 0x04, 0x40 }, { 0x05, 0x01 }, + { 0x28, 0x00 }, { 0x29, 0x10 }, + { 0x28, 0x05 }, { 0x29, 0x02 }, { 0x1c, 0x01 }, - { 0x28, 0x06 }, - { 0x29, 0x00 }, - { 0x2a, 0x00 }, - { 0x2b, 0x03 }, - { 0x28, 0x07 }, - { 0x29, 0x00 }, - { 0x2a, 0x00 }, - { 0x2b, 0x0d }, - { 0x28, 0x08 }, - { 0x29, 0x00 }, - { 0x2a, 0x00 }, - { 0x2b, 0x02 }, - { 0x28, 0x09 }, - { 0x29, 0x00 }, - { 0x2a, 0x00 }, - { 0x2b, 0x01 }, - { 0x28, 0x0a }, - { 0x29, 0x00 }, - { 0x2a, 0x00 }, - { 0x2b, 0x21 }, - { 0x28, 0x0b }, - { 0x29, 0x00 }, - { 0x2a, 0x00 }, - { 0x2b, 0x29 }, - { 0x28, 0x0c }, - { 0x29, 0x00 }, - { 0x2a, 0x00 }, - { 0x2b, 0x16 }, - { 0x28, 0x0d }, - { 0x29, 0x00 }, - { 0x2a, 0x00 }, - { 0x2b, 0x31 }, - { 0x28, 0x0e }, - { 0x29, 0x00 }, - { 0x2a, 0x00 }, - { 0x2b, 0x0e }, - { 0x28, 0x0f }, - { 0x29, 0x00 }, - { 0x2a, 0x00 }, - { 0x2b, 0x4e }, - { 0x28, 0x10 }, - { 0x29, 0x00 }, - { 0x2a, 0x00 }, - { 0x2b, 0x46 }, - { 0x28, 0x11 }, - { 0x29, 0x00 }, - { 0x2a, 0x00 }, - { 0x2b, 0x0f }, - { 0x28, 0x12 }, - { 0x29, 0x00 }, - { 0x2a, 0x00 }, - { 0x2b, 0x56 }, - { 0x28, 0x13 }, - { 0x29, 0x00 }, - { 0x2a, 0x00 }, - { 0x2b, 0x35 }, - { 0x28, 0x14 }, - { 0x29, 0x00 }, - { 0x2a, 0x01 }, - { 0x2b, 0xbe }, - { 0x28, 0x15 }, - { 0x29, 0x00 }, - { 0x2a, 0x01 }, - { 0x2b, 0x84 }, - { 0x28, 0x16 }, - { 0x29, 0x00 }, - { 0x2a, 0x03 }, - { 0x2b, 0xee }, - { 0x28, 0x17 }, - { 0x29, 0x00 }, - { 0x2a, 0x00 }, - { 0x2b, 0x98 }, - { 0x28, 0x18 }, - { 0x29, 0x00 }, - { 0x2a, 0x00 }, - { 0x2b, 0x9f }, - { 0x28, 0x19 }, - { 0x29, 0x00 }, - { 0x2a, 0x07 }, - { 0x2b, 0xb2 }, - { 0x28, 0x1a }, - { 0x29, 0x00 }, - { 0x2a, 0x06 }, - { 0x2b, 0xc2 }, - { 0x28, 0x1b }, - { 0x29, 0x00 }, - { 0x2a, 0x07 }, - { 0x2b, 0x4a }, - { 0x28, 0x1c }, - { 0x29, 0x00 }, - { 0x2a, 0x01 }, - { 0x2b, 0xbc }, - { 0x28, 0x1d }, - { 0x29, 0x00 }, - { 0x2a, 0x04 }, - { 0x2b, 0xba }, - { 0x28, 0x1e }, - { 0x29, 0x00 }, - { 0x2a, 0x06 }, - { 0x2b, 0x14 }, - { 0x50, 0x1e }, - { 0x51, 0x5d }, - { 0x50, 0x22 }, - { 0x51, 0x00 }, - { 0x50, 0x23 }, - { 0x51, 0xc8 }, - { 0x50, 0x24 }, - { 0x51, 0x00 }, - { 0x50, 0x25 }, - { 0x51, 0xf0 }, - { 0x50, 0x26 }, - { 0x51, 0x00 }, - { 0x50, 0x27 }, - { 0x51, 0xc3 }, - { 0x50, 0x39 }, - { 0x51, 0x02 }, - { 0x50, 0xd5 }, - { 0x51, 0x01 }, + { 0x28, 0x06 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x03 }, + { 0x28, 0x07 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0d }, + { 0x28, 0x08 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x02 }, + { 0x28, 0x09 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x01 }, + { 0x28, 0x0a }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x21 }, + { 0x28, 0x0b }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x29 }, + { 0x28, 0x0c }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x16 }, + { 0x28, 0x0d }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x31 }, + { 0x28, 0x0e }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0e }, + { 0x28, 0x0f }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x4e }, + { 0x28, 0x10 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x46 }, + { 0x28, 0x11 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0f }, + { 0x28, 0x12 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x56 }, + { 0x28, 0x13 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x35 }, + { 0x28, 0x14 }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0xbe }, + { 0x28, 0x15 }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0x84 }, + { 0x28, 0x16 }, { 0x29, 0x00 }, { 0x2a, 0x03 }, { 0x2b, 0xee }, + { 0x28, 0x17 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x98 }, + { 0x28, 0x18 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x9f }, + { 0x28, 0x19 }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0xb2 }, + { 0x28, 0x1a }, { 0x29, 0x00 }, { 0x2a, 0x06 }, { 0x2b, 0xc2 }, + { 0x28, 0x1b }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0x4a }, + { 0x28, 0x1c }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0xbc }, + { 0x28, 0x1d }, { 0x29, 0x00 }, { 0x2a, 0x04 }, { 0x2b, 0xba }, + { 0x28, 0x1e }, { 0x29, 0x00 }, { 0x2a, 0x06 }, { 0x2b, 0x14 }, + { 0x50, 0x1e }, { 0x51, 0x5d }, + { 0x50, 0x22 }, { 0x51, 0x00 }, + { 0x50, 0x23 }, { 0x51, 0xc8 }, + { 0x50, 0x24 }, { 0x51, 0x00 }, + { 0x50, 0x25 }, { 0x51, 0xf0 }, + { 0x50, 0x26 }, { 0x51, 0x00 }, + { 0x50, 0x27 }, { 0x51, 0xc3 }, + { 0x50, 0x39 }, { 0x51, 0x02 }, + { 0x28, 0x6a }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x00 }, { 0xd0, 0x00 }, }; @@ -485,18 +352,23 @@ static int mb86a20s_read_status(struct dvb_frontend *fe, fe_status_t *status) return 0; } -static int mb86a20s_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int mb86a20s_set_frontend(struct dvb_frontend *fe) { struct mb86a20s_state *state = fe->demodulator_priv; int rc; +#if 0 + /* + * FIXME: Properly implement the set frontend properties + */ + struct dtv_frontend_properties *p = &fe->dtv_property_cache; +#endif dprintk("\n"); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); dprintk("Calling tuner set parameters\n"); - fe->ops.tuner_ops.set_params(fe, p); + fe->ops.tuner_ops.set_params(fe); /* * Make it more reliable: if, for some reason, the initial @@ -520,22 +392,212 @@ static int mb86a20s_set_frontend(struct dvb_frontend *fe, return rc; } -static int mb86a20s_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int mb86a20s_get_modulation(struct mb86a20s_state *state, + unsigned layer) +{ + int rc; + static unsigned char reg[] = { + [0] = 0x86, /* Layer A */ + [1] = 0x8a, /* Layer B */ + [2] = 0x8e, /* Layer C */ + }; + + if (layer > ARRAY_SIZE(reg)) + return -EINVAL; + rc = mb86a20s_writereg(state, 0x6d, reg[layer]); + if (rc < 0) + return rc; + rc = mb86a20s_readreg(state, 0x6e); + if (rc < 0) + return rc; + switch ((rc & 0x70) >> 4) { + case 0: + return DQPSK; + case 1: + return QPSK; + case 2: + return QAM_16; + case 3: + return QAM_64; + default: + return QAM_AUTO; + } +} + +static int mb86a20s_get_fec(struct mb86a20s_state *state, + unsigned layer) { + int rc; - /* FIXME: For now, it does nothing */ + static unsigned char reg[] = { + [0] = 0x87, /* Layer A */ + [1] = 0x8b, /* Layer B */ + [2] = 0x8f, /* Layer C */ + }; - fe->dtv_property_cache.bandwidth_hz = 6000000; - fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_AUTO; - fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_AUTO; - fe->dtv_property_cache.isdbt_partial_reception = 0; + if (layer > ARRAY_SIZE(reg)) + return -EINVAL; + rc = mb86a20s_writereg(state, 0x6d, reg[layer]); + if (rc < 0) + return rc; + rc = mb86a20s_readreg(state, 0x6e); + if (rc < 0) + return rc; + switch (rc) { + case 0: + return FEC_1_2; + case 1: + return FEC_2_3; + case 2: + return FEC_3_4; + case 3: + return FEC_5_6; + case 4: + return FEC_7_8; + default: + return FEC_AUTO; + } +} + +static int mb86a20s_get_interleaving(struct mb86a20s_state *state, + unsigned layer) +{ + int rc; + + static unsigned char reg[] = { + [0] = 0x88, /* Layer A */ + [1] = 0x8c, /* Layer B */ + [2] = 0x90, /* Layer C */ + }; + + if (layer > ARRAY_SIZE(reg)) + return -EINVAL; + rc = mb86a20s_writereg(state, 0x6d, reg[layer]); + if (rc < 0) + return rc; + rc = mb86a20s_readreg(state, 0x6e); + if (rc < 0) + return rc; + if (rc > 3) + return -EINVAL; /* Not used */ + return rc; +} + +static int mb86a20s_get_segment_count(struct mb86a20s_state *state, + unsigned layer) +{ + int rc, count; + + static unsigned char reg[] = { + [0] = 0x89, /* Layer A */ + [1] = 0x8d, /* Layer B */ + [2] = 0x91, /* Layer C */ + }; + + if (layer > ARRAY_SIZE(reg)) + return -EINVAL; + rc = mb86a20s_writereg(state, 0x6d, reg[layer]); + if (rc < 0) + return rc; + rc = mb86a20s_readreg(state, 0x6e); + if (rc < 0) + return rc; + count = (rc >> 4) & 0x0f; + + return count; +} + +static int mb86a20s_get_frontend(struct dvb_frontend *fe) +{ + struct mb86a20s_state *state = fe->demodulator_priv; + struct dtv_frontend_properties *p = &fe->dtv_property_cache; + int i, rc; + + /* Fixed parameters */ + p->delivery_system = SYS_ISDBT; + p->bandwidth_hz = 6000000; + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + + /* Check for partial reception */ + rc = mb86a20s_writereg(state, 0x6d, 0x85); + if (rc >= 0) + rc = mb86a20s_readreg(state, 0x6e); + if (rc >= 0) + p->isdbt_partial_reception = (rc & 0x10) ? 1 : 0; + + /* Get per-layer data */ + p->isdbt_layer_enabled = 0; + for (i = 0; i < 3; i++) { + rc = mb86a20s_get_segment_count(state, i); + if (rc >= 0 && rc < 14) + p->layer[i].segment_count = rc; + if (rc == 0x0f) + continue; + p->isdbt_layer_enabled |= 1 << i; + rc = mb86a20s_get_modulation(state, i); + if (rc >= 0) + p->layer[i].modulation = rc; + rc = mb86a20s_get_fec(state, i); + if (rc >= 0) + p->layer[i].fec = rc; + rc = mb86a20s_get_interleaving(state, i); + if (rc >= 0) + p->layer[i].interleaving = rc; + } + + p->isdbt_sb_mode = 0; + rc = mb86a20s_writereg(state, 0x6d, 0x84); + if ((rc >= 0) && ((rc & 0x60) == 0x20)) { + p->isdbt_sb_mode = 1; + /* At least, one segment should exist */ + if (!p->isdbt_sb_segment_count) + p->isdbt_sb_segment_count = 1; + } else + p->isdbt_sb_segment_count = 0; + + /* Get transmission mode and guard interval */ + p->transmission_mode = TRANSMISSION_MODE_AUTO; + p->guard_interval = GUARD_INTERVAL_AUTO; + rc = mb86a20s_readreg(state, 0x07); + if (rc >= 0) { + if ((rc & 0x60) == 0x20) { + switch (rc & 0x0c >> 2) { + case 0: + p->transmission_mode = TRANSMISSION_MODE_2K; + break; + case 1: + p->transmission_mode = TRANSMISSION_MODE_4K; + break; + case 2: + p->transmission_mode = TRANSMISSION_MODE_8K; + break; + } + } + if (!(rc & 0x10)) { + switch (rc & 0x3) { + case 0: + p->guard_interval = GUARD_INTERVAL_1_4; + break; + case 1: + p->guard_interval = GUARD_INTERVAL_1_8; + break; + case 2: + p->guard_interval = GUARD_INTERVAL_1_16; + break; + } + } + } + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); return 0; } static int mb86a20s_tune(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params, + bool re_tune, unsigned int mode_flags, unsigned int *delay, fe_status_t *status) @@ -544,8 +606,8 @@ static int mb86a20s_tune(struct dvb_frontend *fe, dprintk("\n"); - if (params != NULL) - rc = mb86a20s_set_frontend(fe, params); + if (re_tune) + rc = mb86a20s_set_frontend(fe); if (!(mode_flags & FE_TUNE_MODE_ONESHOT)) mb86a20s_read_status(fe, status); @@ -608,10 +670,10 @@ error: EXPORT_SYMBOL(mb86a20s_attach); static struct dvb_frontend_ops mb86a20s_ops = { + .delsys = { SYS_ISDBT }, /* Use dib8000 values per default */ .info = { .name = "Fujitsu mb86A20s", - .type = FE_OFDM, .caps = FE_CAN_INVERSION_AUTO | FE_CAN_RECOVER | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | diff --git a/drivers/media/dvb/frontends/mt312.c b/drivers/media/dvb/frontends/mt312.c index 83e6f1a1b700..e20bf13aa860 100644 --- a/drivers/media/dvb/frontends/mt312.c +++ b/drivers/media/dvb/frontends/mt312.c @@ -531,9 +531,9 @@ static int mt312_read_ucblocks(struct dvb_frontend *fe, u32 *ubc) return 0; } -static int mt312_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int mt312_set_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct mt312_state *state = fe->demodulator_priv; int ret; u8 buf[5], config_val; @@ -553,16 +553,16 @@ static int mt312_set_frontend(struct dvb_frontend *fe, || (p->inversion > INVERSION_ON)) return -EINVAL; - if ((p->u.qpsk.symbol_rate < fe->ops.info.symbol_rate_min) - || (p->u.qpsk.symbol_rate > fe->ops.info.symbol_rate_max)) + if ((p->symbol_rate < fe->ops.info.symbol_rate_min) + || (p->symbol_rate > fe->ops.info.symbol_rate_max)) return -EINVAL; - if ((p->u.qpsk.fec_inner < FEC_NONE) - || (p->u.qpsk.fec_inner > FEC_AUTO)) + if ((p->fec_inner < FEC_NONE) + || (p->fec_inner > FEC_AUTO)) return -EINVAL; - if ((p->u.qpsk.fec_inner == FEC_4_5) - || (p->u.qpsk.fec_inner == FEC_8_9)) + if ((p->fec_inner == FEC_4_5) + || (p->fec_inner == FEC_8_9)) return -EINVAL; switch (state->id) { @@ -574,7 +574,7 @@ static int mt312_set_frontend(struct dvb_frontend *fe, ret = mt312_readreg(state, CONFIG, &config_val); if (ret < 0) return ret; - if (p->u.qpsk.symbol_rate >= 30000000) { + if (p->symbol_rate >= 30000000) { /* Note that 30MS/s should use 90MHz */ if (state->freq_mult == 6) { /* We are running 60MHz */ @@ -603,25 +603,25 @@ static int mt312_set_frontend(struct dvb_frontend *fe, } if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); + fe->ops.tuner_ops.set_params(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); } /* sr = (u16)(sr * 256.0 / 1000000.0) */ - sr = mt312_div(p->u.qpsk.symbol_rate * 4, 15625); + sr = mt312_div(p->symbol_rate * 4, 15625); /* SYM_RATE */ buf[0] = (sr >> 8) & 0x3f; buf[1] = (sr >> 0) & 0xff; /* VIT_MODE */ - buf[2] = inv_tab[p->inversion] | fec_tab[p->u.qpsk.fec_inner]; + buf[2] = inv_tab[p->inversion] | fec_tab[p->fec_inner]; /* QPSK_CTRL */ buf[3] = 0x40; /* swap I and Q before QPSK demodulation */ - if (p->u.qpsk.symbol_rate < 10000000) + if (p->symbol_rate < 10000000) buf[3] |= 0x04; /* use afc mode */ /* GO */ @@ -636,9 +636,9 @@ static int mt312_set_frontend(struct dvb_frontend *fe, return 0; } -static int mt312_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int mt312_get_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct mt312_state *state = fe->demodulator_priv; int ret; @@ -646,11 +646,11 @@ static int mt312_get_frontend(struct dvb_frontend *fe, if (ret < 0) return ret; - ret = mt312_get_symbol_rate(state, &p->u.qpsk.symbol_rate); + ret = mt312_get_symbol_rate(state, &p->symbol_rate); if (ret < 0) return ret; - ret = mt312_get_code_rate(state, &p->u.qpsk.fec_inner); + ret = mt312_get_code_rate(state, &p->fec_inner); if (ret < 0) return ret; @@ -738,10 +738,9 @@ static void mt312_release(struct dvb_frontend *fe) #define MT312_SYS_CLK 90000000UL /* 90 MHz */ static struct dvb_frontend_ops mt312_ops = { - + .delsys = { SYS_DVBS }, .info = { .name = "Zarlink ???? DVB-S", - .type = FE_QPSK, .frequency_min = 950000, .frequency_max = 2150000, /* FIXME: adjust freq to real used xtal */ diff --git a/drivers/media/dvb/frontends/mt352.c b/drivers/media/dvb/frontends/mt352.c index 319672f8e1a7..2c3b50e828d7 100644 --- a/drivers/media/dvb/frontends/mt352.c +++ b/drivers/media/dvb/frontends/mt352.c @@ -111,20 +111,20 @@ static int mt352_sleep(struct dvb_frontend* fe) } static void mt352_calc_nominal_rate(struct mt352_state* state, - enum fe_bandwidth bandwidth, + u32 bandwidth, unsigned char *buf) { u32 adc_clock = 20480; /* 20.340 MHz */ u32 bw,value; switch (bandwidth) { - case BANDWIDTH_6_MHZ: + case 6000000: bw = 6; break; - case BANDWIDTH_7_MHZ: + case 7000000: bw = 7; break; - case BANDWIDTH_8_MHZ: + case 8000000: default: bw = 8; break; @@ -166,15 +166,14 @@ static void mt352_calc_input_freq(struct mt352_state* state, buf[1] = lsb(value); } -static int mt352_set_parameters(struct dvb_frontend* fe, - struct dvb_frontend_parameters *param) +static int mt352_set_parameters(struct dvb_frontend *fe) { + struct dtv_frontend_properties *op = &fe->dtv_property_cache; struct mt352_state* state = fe->demodulator_priv; unsigned char buf[13]; static unsigned char tuner_go[] = { 0x5d, 0x01 }; static unsigned char fsm_go[] = { 0x5e, 0x01 }; unsigned int tps = 0; - struct dvb_ofdm_parameters *op = ¶m->u.ofdm; switch (op->code_rate_HP) { case FEC_2_3: @@ -213,14 +212,14 @@ static int mt352_set_parameters(struct dvb_frontend* fe, case FEC_AUTO: break; case FEC_NONE: - if (op->hierarchy_information == HIERARCHY_AUTO || - op->hierarchy_information == HIERARCHY_NONE) + if (op->hierarchy == HIERARCHY_AUTO || + op->hierarchy == HIERARCHY_NONE) break; default: return -EINVAL; } - switch (op->constellation) { + switch (op->modulation) { case QPSK: break; case QAM_AUTO: @@ -262,7 +261,7 @@ static int mt352_set_parameters(struct dvb_frontend* fe, return -EINVAL; } - switch (op->hierarchy_information) { + switch (op->hierarchy) { case HIERARCHY_AUTO: case HIERARCHY_NONE: break; @@ -288,12 +287,12 @@ static int mt352_set_parameters(struct dvb_frontend* fe, buf[3] = 0x50; // old // buf[3] = 0xf4; // pinnacle - mt352_calc_nominal_rate(state, op->bandwidth, buf+4); + mt352_calc_nominal_rate(state, op->bandwidth_hz, buf+4); mt352_calc_input_freq(state, buf+6); if (state->config.no_tuner) { if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, param); + fe->ops.tuner_ops.set_params(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); } @@ -302,7 +301,7 @@ static int mt352_set_parameters(struct dvb_frontend* fe, _mt352_write(fe, fsm_go, 2); } else { if (fe->ops.tuner_ops.calc_regs) { - fe->ops.tuner_ops.calc_regs(fe, param, buf+8, 5); + fe->ops.tuner_ops.calc_regs(fe, buf+8, 5); buf[8] <<= 1; _mt352_write(fe, buf, sizeof(buf)); _mt352_write(fe, tuner_go, 2); @@ -312,14 +311,13 @@ static int mt352_set_parameters(struct dvb_frontend* fe, return 0; } -static int mt352_get_parameters(struct dvb_frontend* fe, - struct dvb_frontend_parameters *param) +static int mt352_get_parameters(struct dvb_frontend* fe) { + struct dtv_frontend_properties *op = &fe->dtv_property_cache; struct mt352_state* state = fe->demodulator_priv; u16 tps; u16 div; u8 trl; - struct dvb_ofdm_parameters *op = ¶m->u.ofdm; static const u8 tps_fec_to_api[8] = { FEC_1_2, @@ -348,16 +346,16 @@ static int mt352_get_parameters(struct dvb_frontend* fe, switch ( (tps >> 13) & 3) { case 0: - op->constellation = QPSK; + op->modulation = QPSK; break; case 1: - op->constellation = QAM_16; + op->modulation = QAM_16; break; case 2: - op->constellation = QAM_64; + op->modulation = QAM_64; break; default: - op->constellation = QAM_AUTO; + op->modulation = QAM_AUTO; break; } @@ -385,36 +383,36 @@ static int mt352_get_parameters(struct dvb_frontend* fe, switch ( (tps >> 10) & 7) { case 0: - op->hierarchy_information = HIERARCHY_NONE; + op->hierarchy = HIERARCHY_NONE; break; case 1: - op->hierarchy_information = HIERARCHY_1; + op->hierarchy = HIERARCHY_1; break; case 2: - op->hierarchy_information = HIERARCHY_2; + op->hierarchy = HIERARCHY_2; break; case 3: - op->hierarchy_information = HIERARCHY_4; + op->hierarchy = HIERARCHY_4; break; default: - op->hierarchy_information = HIERARCHY_AUTO; + op->hierarchy = HIERARCHY_AUTO; break; } - param->frequency = ( 500 * (div - IF_FREQUENCYx6) ) / 3 * 1000; + op->frequency = (500 * (div - IF_FREQUENCYx6)) / 3 * 1000; if (trl == 0x72) - op->bandwidth = BANDWIDTH_8_MHZ; + op->bandwidth_hz = 8000000; else if (trl == 0x64) - op->bandwidth = BANDWIDTH_7_MHZ; + op->bandwidth_hz = 7000000; else - op->bandwidth = BANDWIDTH_6_MHZ; + op->bandwidth_hz = 6000000; if (mt352_read_register(state, STATUS_2) & 0x02) - param->inversion = INVERSION_OFF; + op->inversion = INVERSION_OFF; else - param->inversion = INVERSION_ON; + op->inversion = INVERSION_ON; return 0; } @@ -569,10 +567,9 @@ error: } static struct dvb_frontend_ops mt352_ops = { - + .delsys = { SYS_DVBT }, .info = { .name = "Zarlink MT352 DVB-T", - .type = FE_OFDM, .frequency_min = 174000000, .frequency_max = 862000000, .frequency_stepsize = 166667, diff --git a/drivers/media/dvb/frontends/nxt200x.c b/drivers/media/dvb/frontends/nxt200x.c index eac20650499f..49ca78d883b1 100644 --- a/drivers/media/dvb/frontends/nxt200x.c +++ b/drivers/media/dvb/frontends/nxt200x.c @@ -528,9 +528,9 @@ static int nxt2004_load_firmware (struct dvb_frontend* fe, const struct firmware return 0; }; -static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe, - struct dvb_frontend_parameters *p) +static int nxt200x_setup_frontend_parameters(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct nxt200x_state* state = fe->demodulator_priv; u8 buf[5]; @@ -546,7 +546,7 @@ static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe, } /* set additional params */ - switch (p->u.vsb.modulation) { + switch (p->modulation) { case QAM_64: case QAM_256: /* Set punctured clock for QAM */ @@ -566,7 +566,7 @@ static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe, if (fe->ops.tuner_ops.calc_regs) { /* get tuning information */ - fe->ops.tuner_ops.calc_regs(fe, p, buf, 5); + fe->ops.tuner_ops.calc_regs(fe, buf, 5); /* write frequency information */ nxt200x_writetuner(state, buf); @@ -576,7 +576,7 @@ static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe, nxt200x_agc_reset(state); /* set target power level */ - switch (p->u.vsb.modulation) { + switch (p->modulation) { case QAM_64: case QAM_256: buf[0] = 0x74; @@ -620,7 +620,7 @@ static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe, } /* write sdmx input */ - switch (p->u.vsb.modulation) { + switch (p->modulation) { case QAM_64: buf[0] = 0x68; break; @@ -714,7 +714,7 @@ static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe, } /* write agc ucgp0 */ - switch (p->u.vsb.modulation) { + switch (p->modulation) { case QAM_64: buf[0] = 0x02; break; @@ -1203,10 +1203,9 @@ error: } static struct dvb_frontend_ops nxt200x_ops = { - + .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, .info = { .name = "Nextwave NXT200X VSB/QAM frontend", - .type = FE_ATSC, .frequency_min = 54000000, .frequency_max = 860000000, .frequency_stepsize = 166666, /* stepsize is just a guess */ diff --git a/drivers/media/dvb/frontends/nxt6000.c b/drivers/media/dvb/frontends/nxt6000.c index 6599b8fea9e9..90ae6c72c0e3 100644 --- a/drivers/media/dvb/frontends/nxt6000.c +++ b/drivers/media/dvb/frontends/nxt6000.c @@ -81,22 +81,21 @@ static void nxt6000_reset(struct nxt6000_state* state) nxt6000_writereg(state, OFDM_COR_CTL, val | COREACT); } -static int nxt6000_set_bandwidth(struct nxt6000_state* state, fe_bandwidth_t bandwidth) +static int nxt6000_set_bandwidth(struct nxt6000_state *state, u32 bandwidth) { u16 nominal_rate; int result; switch (bandwidth) { - - case BANDWIDTH_6_MHZ: + case 6000000: nominal_rate = 0x55B7; break; - case BANDWIDTH_7_MHZ: + case 7000000: nominal_rate = 0x6400; break; - case BANDWIDTH_8_MHZ: + case 8000000: nominal_rate = 0x7249; break; @@ -457,23 +456,31 @@ static int nxt6000_init(struct dvb_frontend* fe) return 0; } -static int nxt6000_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *param) +static int nxt6000_set_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct nxt6000_state* state = fe->demodulator_priv; int result; if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, param); + fe->ops.tuner_ops.set_params(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); } - if ((result = nxt6000_set_bandwidth(state, param->u.ofdm.bandwidth)) < 0) + result = nxt6000_set_bandwidth(state, p->bandwidth_hz); + if (result < 0) return result; - if ((result = nxt6000_set_guard_interval(state, param->u.ofdm.guard_interval)) < 0) + + result = nxt6000_set_guard_interval(state, p->guard_interval); + if (result < 0) return result; - if ((result = nxt6000_set_transmission_mode(state, param->u.ofdm.transmission_mode)) < 0) + + result = nxt6000_set_transmission_mode(state, p->transmission_mode); + if (result < 0) return result; - if ((result = nxt6000_set_inversion(state, param->inversion)) < 0) + + result = nxt6000_set_inversion(state, p->inversion); + if (result < 0) return result; msleep(500); @@ -566,10 +573,9 @@ error: } static struct dvb_frontend_ops nxt6000_ops = { - + .delsys = { SYS_DVBT }, .info = { .name = "NxtWave NXT6000 DVB-T", - .type = FE_OFDM, .frequency_min = 0, .frequency_max = 863250000, .frequency_stepsize = 62500, diff --git a/drivers/media/dvb/frontends/or51132.c b/drivers/media/dvb/frontends/or51132.c index 38e67accb8c3..5ef921823c15 100644 --- a/drivers/media/dvb/frontends/or51132.c +++ b/drivers/media/dvb/frontends/or51132.c @@ -306,9 +306,9 @@ static int modulation_fw_class(fe_modulation_t modulation) } } -static int or51132_set_parameters(struct dvb_frontend* fe, - struct dvb_frontend_parameters *param) +static int or51132_set_parameters(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; int ret; struct or51132_state* state = fe->demodulator_priv; const struct firmware *fw; @@ -317,8 +317,8 @@ static int or51132_set_parameters(struct dvb_frontend* fe, /* Upload new firmware only if we need a different one */ if (modulation_fw_class(state->current_modulation) != - modulation_fw_class(param->u.vsb.modulation)) { - switch(modulation_fw_class(param->u.vsb.modulation)) { + modulation_fw_class(p->modulation)) { + switch (modulation_fw_class(p->modulation)) { case MOD_FWCLASS_VSB: dprintk("set_parameters VSB MODE\n"); fwname = OR51132_VSB_FIRMWARE; @@ -335,7 +335,7 @@ static int or51132_set_parameters(struct dvb_frontend* fe, break; default: printk("or51132: Modulation type(%d) UNSUPPORTED\n", - param->u.vsb.modulation); + p->modulation); return -1; } printk("or51132: Waiting for firmware upload(%s)...\n", @@ -357,13 +357,13 @@ static int or51132_set_parameters(struct dvb_frontend* fe, state->config->set_ts_params(fe, clock_mode); } /* Change only if we are actually changing the modulation */ - if (state->current_modulation != param->u.vsb.modulation) { - state->current_modulation = param->u.vsb.modulation; + if (state->current_modulation != p->modulation) { + state->current_modulation = p->modulation; or51132_setmode(fe); } if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, param); + fe->ops.tuner_ops.set_params(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); } @@ -371,13 +371,13 @@ static int or51132_set_parameters(struct dvb_frontend* fe, or51132_setmode(fe); /* Update current frequency */ - state->current_frequency = param->frequency; + state->current_frequency = p->frequency; return 0; } -static int or51132_get_parameters(struct dvb_frontend* fe, - struct dvb_frontend_parameters *param) +static int or51132_get_parameters(struct dvb_frontend* fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct or51132_state* state = fe->demodulator_priv; int status; int retry = 1; @@ -389,21 +389,28 @@ start: return -EREMOTEIO; } switch(status&0xff) { - case 0x06: param->u.vsb.modulation = VSB_8; break; - case 0x43: param->u.vsb.modulation = QAM_64; break; - case 0x45: param->u.vsb.modulation = QAM_256; break; - default: - if (retry--) goto start; - printk(KERN_WARNING "or51132: unknown status 0x%02x\n", - status&0xff); - return -EREMOTEIO; + case 0x06: + p->modulation = VSB_8; + break; + case 0x43: + p->modulation = QAM_64; + break; + case 0x45: + p->modulation = QAM_256; + break; + default: + if (retry--) + goto start; + printk(KERN_WARNING "or51132: unknown status 0x%02x\n", + status&0xff); + return -EREMOTEIO; } /* FIXME: Read frequency from frontend, take AFC into account */ - param->frequency = state->current_frequency; + p->frequency = state->current_frequency; /* FIXME: How to read inversion setting? Receiver 6 register? */ - param->inversion = INVERSION_AUTO; + p->inversion = INVERSION_AUTO; return 0; } @@ -579,10 +586,9 @@ struct dvb_frontend* or51132_attach(const struct or51132_config* config, } static struct dvb_frontend_ops or51132_ops = { - + .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, .info = { .name = "Oren OR51132 VSB/QAM Frontend", - .type = FE_ATSC, .frequency_min = 44000000, .frequency_max = 958000000, .frequency_stepsize = 166666, diff --git a/drivers/media/dvb/frontends/or51211.c b/drivers/media/dvb/frontends/or51211.c index c709ce6771c8..c625b57b4333 100644 --- a/drivers/media/dvb/frontends/or51211.c +++ b/drivers/media/dvb/frontends/or51211.c @@ -218,15 +218,15 @@ static int or51211_setmode(struct dvb_frontend* fe, int mode) return 0; } -static int or51211_set_parameters(struct dvb_frontend* fe, - struct dvb_frontend_parameters *param) +static int or51211_set_parameters(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct or51211_state* state = fe->demodulator_priv; /* Change only if we are actually changing the channel */ - if (state->current_frequency != param->frequency) { + if (state->current_frequency != p->frequency) { if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, param); + fe->ops.tuner_ops.set_params(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); } @@ -234,7 +234,7 @@ static int or51211_set_parameters(struct dvb_frontend* fe, or51211_setmode(fe,0); /* Update current frequency */ - state->current_frequency = param->frequency; + state->current_frequency = p->frequency; } return 0; } @@ -544,10 +544,9 @@ struct dvb_frontend* or51211_attach(const struct or51211_config* config, } static struct dvb_frontend_ops or51211_ops = { - + .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, .info = { .name = "Oren OR51211 VSB Frontend", - .type = FE_ATSC, .frequency_min = 44000000, .frequency_max = 958000000, .frequency_stepsize = 166666, diff --git a/drivers/media/dvb/frontends/s5h1409.c b/drivers/media/dvb/frontends/s5h1409.c index 0e2f61a8978f..f71b06221e14 100644 --- a/drivers/media/dvb/frontends/s5h1409.c +++ b/drivers/media/dvb/frontends/s5h1409.c @@ -631,9 +631,9 @@ static void s5h1409_set_qam_interleave_mode_legacy(struct dvb_frontend *fe) } /* Talk to the demod, set the FEC, GUARD, QAM settings etc */ -static int s5h1409_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int s5h1409_set_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct s5h1409_state *state = fe->demodulator_priv; dprintk("%s(frequency=%d)\n", __func__, p->frequency); @@ -642,12 +642,12 @@ static int s5h1409_set_frontend(struct dvb_frontend *fe, state->current_frequency = p->frequency; - s5h1409_enable_modulation(fe, p->u.vsb.modulation); + s5h1409_enable_modulation(fe, p->modulation); if (fe->ops.tuner_ops.set_params) { if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); - fe->ops.tuner_ops.set_params(fe, p); + fe->ops.tuner_ops.set_params(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); } @@ -879,7 +879,36 @@ static int s5h1409_read_snr(struct dvb_frontend *fe, u16 *snr) static int s5h1409_read_signal_strength(struct dvb_frontend *fe, u16 *signal_strength) { - return s5h1409_read_snr(fe, signal_strength); + /* borrowed from lgdt330x.c + * + * Calculate strength from SNR up to 35dB + * Even though the SNR can go higher than 35dB, + * there is some comfort factor in having a range of + * strong signals that can show at 100% + */ + u16 snr; + u32 tmp; + int ret = s5h1409_read_snr(fe, &snr); + + *signal_strength = 0; + + if (0 == ret) { + /* The following calculation method was chosen + * purely for the sake of code re-use from the + * other demod drivers that use this method */ + + /* Convert from SNR in dB * 10 to 8.24 fixed-point */ + tmp = (snr * ((1 << 24) / 10)); + + /* Convert from 8.24 fixed-point to + * scale the range 0 - 35*2^24 into 0 - 65535*/ + if (tmp >= 8960 * 0x10000) + *signal_strength = 0xffff; + else + *signal_strength = tmp / 8960; + } + + return ret; } static int s5h1409_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) @@ -896,13 +925,13 @@ static int s5h1409_read_ber(struct dvb_frontend *fe, u32 *ber) return s5h1409_read_ucblocks(fe, ber); } -static int s5h1409_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int s5h1409_get_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct s5h1409_state *state = fe->demodulator_priv; p->frequency = state->current_frequency; - p->u.vsb.modulation = state->current_modulation; + p->modulation = state->current_modulation; return 0; } @@ -967,10 +996,9 @@ error: EXPORT_SYMBOL(s5h1409_attach); static struct dvb_frontend_ops s5h1409_ops = { - + .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, .info = { .name = "Samsung S5H1409 QAM/8VSB Frontend", - .type = FE_ATSC, .frequency_min = 54000000, .frequency_max = 858000000, .frequency_stepsize = 62500, diff --git a/drivers/media/dvb/frontends/s5h1411.c b/drivers/media/dvb/frontends/s5h1411.c index d8adf1e32019..6cc4b7a9dd60 100644 --- a/drivers/media/dvb/frontends/s5h1411.c +++ b/drivers/media/dvb/frontends/s5h1411.c @@ -585,9 +585,9 @@ static int s5h1411_register_reset(struct dvb_frontend *fe) } /* Talk to the demod, set the FEC, GUARD, QAM settings etc */ -static int s5h1411_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int s5h1411_set_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct s5h1411_state *state = fe->demodulator_priv; dprintk("%s(frequency=%d)\n", __func__, p->frequency); @@ -596,13 +596,13 @@ static int s5h1411_set_frontend(struct dvb_frontend *fe, state->current_frequency = p->frequency; - s5h1411_enable_modulation(fe, p->u.vsb.modulation); + s5h1411_enable_modulation(fe, p->modulation); if (fe->ops.tuner_ops.set_params) { if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); - fe->ops.tuner_ops.set_params(fe, p); + fe->ops.tuner_ops.set_params(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); @@ -794,7 +794,36 @@ static int s5h1411_read_snr(struct dvb_frontend *fe, u16 *snr) static int s5h1411_read_signal_strength(struct dvb_frontend *fe, u16 *signal_strength) { - return s5h1411_read_snr(fe, signal_strength); + /* borrowed from lgdt330x.c + * + * Calculate strength from SNR up to 35dB + * Even though the SNR can go higher than 35dB, + * there is some comfort factor in having a range of + * strong signals that can show at 100% + */ + u16 snr; + u32 tmp; + int ret = s5h1411_read_snr(fe, &snr); + + *signal_strength = 0; + + if (0 == ret) { + /* The following calculation method was chosen + * purely for the sake of code re-use from the + * other demod drivers that use this method */ + + /* Convert from SNR in dB * 10 to 8.24 fixed-point */ + tmp = (snr * ((1 << 24) / 10)); + + /* Convert from 8.24 fixed-point to + * scale the range 0 - 35*2^24 into 0 - 65535*/ + if (tmp >= 8960 * 0x10000) + *signal_strength = 0xffff; + else + *signal_strength = tmp / 8960; + } + + return ret; } static int s5h1411_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) @@ -811,13 +840,13 @@ static int s5h1411_read_ber(struct dvb_frontend *fe, u32 *ber) return s5h1411_read_ucblocks(fe, ber); } -static int s5h1411_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int s5h1411_get_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct s5h1411_state *state = fe->demodulator_priv; p->frequency = state->current_frequency; - p->u.vsb.modulation = state->current_modulation; + p->modulation = state->current_modulation; return 0; } @@ -886,10 +915,9 @@ error: EXPORT_SYMBOL(s5h1411_attach); static struct dvb_frontend_ops s5h1411_ops = { - + .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, .info = { .name = "Samsung S5H1411 QAM/8VSB Frontend", - .type = FE_ATSC, .frequency_min = 54000000, .frequency_max = 858000000, .frequency_stepsize = 62500, diff --git a/drivers/media/dvb/frontends/s5h1420.c b/drivers/media/dvb/frontends/s5h1420.c index 3879d2e378aa..2322257c69ae 100644 --- a/drivers/media/dvb/frontends/s5h1420.c +++ b/drivers/media/dvb/frontends/s5h1420.c @@ -472,15 +472,15 @@ static void s5h1420_reset(struct s5h1420_state* state) } static void s5h1420_setsymbolrate(struct s5h1420_state* state, - struct dvb_frontend_parameters *p) + struct dtv_frontend_properties *p) { u8 v; u64 val; dprintk("enter %s\n", __func__); - val = ((u64) p->u.qpsk.symbol_rate / 1000ULL) * (1ULL<<24); - if (p->u.qpsk.symbol_rate < 29000000) + val = ((u64) p->symbol_rate / 1000ULL) * (1ULL<<24); + if (p->symbol_rate < 29000000) val *= 2; do_div(val, (state->fclk / 1000)); @@ -543,7 +543,7 @@ static int s5h1420_getfreqoffset(struct s5h1420_state* state) } static void s5h1420_setfec_inversion(struct s5h1420_state* state, - struct dvb_frontend_parameters *p) + struct dtv_frontend_properties *p) { u8 inversion = 0; u8 vit08, vit09; @@ -555,11 +555,11 @@ static void s5h1420_setfec_inversion(struct s5h1420_state* state, else if (p->inversion == INVERSION_ON) inversion = state->config->invert ? 0 : 0x08; - if ((p->u.qpsk.fec_inner == FEC_AUTO) || (p->inversion == INVERSION_AUTO)) { + if ((p->fec_inner == FEC_AUTO) || (p->inversion == INVERSION_AUTO)) { vit08 = 0x3f; vit09 = 0; } else { - switch(p->u.qpsk.fec_inner) { + switch (p->fec_inner) { case FEC_1_2: vit08 = 0x01; vit09 = 0x10; break; @@ -628,9 +628,9 @@ static fe_spectral_inversion_t s5h1420_getinversion(struct s5h1420_state* state) return INVERSION_OFF; } -static int s5h1420_set_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *p) +static int s5h1420_set_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct s5h1420_state* state = fe->demodulator_priv; int frequency_delta; struct dvb_frontend_tune_settings fesettings; @@ -639,17 +639,16 @@ static int s5h1420_set_frontend(struct dvb_frontend* fe, dprintk("enter %s\n", __func__); /* check if we should do a fast-tune */ - memcpy(&fesettings.parameters, p, sizeof(struct dvb_frontend_parameters)); s5h1420_get_tune_settings(fe, &fesettings); frequency_delta = p->frequency - state->tunedfreq; if ((frequency_delta > -fesettings.max_drift) && (frequency_delta < fesettings.max_drift) && (frequency_delta != 0) && - (state->fec_inner == p->u.qpsk.fec_inner) && - (state->symbol_rate == p->u.qpsk.symbol_rate)) { + (state->fec_inner == p->fec_inner) && + (state->symbol_rate == p->symbol_rate)) { if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); + fe->ops.tuner_ops.set_params(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); } if (fe->ops.tuner_ops.get_frequency) { @@ -669,13 +668,13 @@ static int s5h1420_set_frontend(struct dvb_frontend* fe, s5h1420_reset(state); /* set s5h1420 fclk PLL according to desired symbol rate */ - if (p->u.qpsk.symbol_rate > 33000000) + if (p->symbol_rate > 33000000) state->fclk = 80000000; - else if (p->u.qpsk.symbol_rate > 28500000) + else if (p->symbol_rate > 28500000) state->fclk = 59000000; - else if (p->u.qpsk.symbol_rate > 25000000) + else if (p->symbol_rate > 25000000) state->fclk = 86000000; - else if (p->u.qpsk.symbol_rate > 1900000) + else if (p->symbol_rate > 1900000) state->fclk = 88000000; else state->fclk = 44000000; @@ -705,7 +704,7 @@ static int s5h1420_set_frontend(struct dvb_frontend* fe, s5h1420_writereg(state, DiS01, (state->fclk + (TONE_FREQ * 32) - 1) / (TONE_FREQ * 32)); /* TODO DC offset removal, config parameter ? */ - if (p->u.qpsk.symbol_rate > 29000000) + if (p->symbol_rate > 29000000) s5h1420_writereg(state, QPSK01, 0xae | 0x10); else s5h1420_writereg(state, QPSK01, 0xac | 0x10); @@ -718,15 +717,15 @@ static int s5h1420_set_frontend(struct dvb_frontend* fe, s5h1420_writereg(state, Loop01, 0xF0); s5h1420_writereg(state, Loop02, 0x2a); /* e7 for s5h1420 */ s5h1420_writereg(state, Loop03, 0x79); /* 78 for s5h1420 */ - if (p->u.qpsk.symbol_rate > 20000000) + if (p->symbol_rate > 20000000) s5h1420_writereg(state, Loop04, 0x79); else s5h1420_writereg(state, Loop04, 0x58); s5h1420_writereg(state, Loop05, 0x6b); - if (p->u.qpsk.symbol_rate >= 8000000) + if (p->symbol_rate >= 8000000) s5h1420_writereg(state, Post01, (0 << 6) | 0x10); - else if (p->u.qpsk.symbol_rate >= 4000000) + else if (p->symbol_rate >= 4000000) s5h1420_writereg(state, Post01, (1 << 6) | 0x10); else s5h1420_writereg(state, Post01, (3 << 6) | 0x10); @@ -744,7 +743,7 @@ static int s5h1420_set_frontend(struct dvb_frontend* fe, /* set tuner PLL */ if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); + fe->ops.tuner_ops.set_params(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); s5h1420_setfreqoffset(state, 0); @@ -757,8 +756,8 @@ static int s5h1420_set_frontend(struct dvb_frontend* fe, /* start QPSK */ s5h1420_writereg(state, QPSK01, s5h1420_readreg(state, QPSK01) | 1); - state->fec_inner = p->u.qpsk.fec_inner; - state->symbol_rate = p->u.qpsk.symbol_rate; + state->fec_inner = p->fec_inner; + state->symbol_rate = p->symbol_rate; state->postlocked = 0; state->tunedfreq = p->frequency; @@ -766,15 +765,15 @@ static int s5h1420_set_frontend(struct dvb_frontend* fe, return 0; } -static int s5h1420_get_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *p) +static int s5h1420_get_frontend(struct dvb_frontend* fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct s5h1420_state* state = fe->demodulator_priv; p->frequency = state->tunedfreq + s5h1420_getfreqoffset(state); p->inversion = s5h1420_getinversion(state); - p->u.qpsk.symbol_rate = s5h1420_getsymbolrate(state); - p->u.qpsk.fec_inner = s5h1420_getfec(state); + p->symbol_rate = s5h1420_getsymbolrate(state); + p->fec_inner = s5h1420_getfec(state); return 0; } @@ -782,29 +781,30 @@ static int s5h1420_get_frontend(struct dvb_frontend* fe, static int s5h1420_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) { - if (fesettings->parameters.u.qpsk.symbol_rate > 20000000) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; + if (p->symbol_rate > 20000000) { fesettings->min_delay_ms = 50; fesettings->step_size = 2000; fesettings->max_drift = 8000; - } else if (fesettings->parameters.u.qpsk.symbol_rate > 12000000) { + } else if (p->symbol_rate > 12000000) { fesettings->min_delay_ms = 100; fesettings->step_size = 1500; fesettings->max_drift = 9000; - } else if (fesettings->parameters.u.qpsk.symbol_rate > 8000000) { + } else if (p->symbol_rate > 8000000) { fesettings->min_delay_ms = 100; fesettings->step_size = 1000; fesettings->max_drift = 8000; - } else if (fesettings->parameters.u.qpsk.symbol_rate > 4000000) { + } else if (p->symbol_rate > 4000000) { fesettings->min_delay_ms = 100; fesettings->step_size = 500; fesettings->max_drift = 7000; - } else if (fesettings->parameters.u.qpsk.symbol_rate > 2000000) { + } else if (p->symbol_rate > 2000000) { fesettings->min_delay_ms = 200; - fesettings->step_size = (fesettings->parameters.u.qpsk.symbol_rate / 8000); + fesettings->step_size = (p->symbol_rate / 8000); fesettings->max_drift = 14 * fesettings->step_size; } else { fesettings->min_delay_ms = 200; - fesettings->step_size = (fesettings->parameters.u.qpsk.symbol_rate / 8000); + fesettings->step_size = (p->symbol_rate / 8000); fesettings->max_drift = 18 * fesettings->step_size; } @@ -937,10 +937,9 @@ error: EXPORT_SYMBOL(s5h1420_attach); static struct dvb_frontend_ops s5h1420_ops = { - + .delsys = { SYS_DVBS }, .info = { .name = "Samsung S5H1420/PnpNetwork PN1010 DVB-S", - .type = FE_QPSK, .frequency_min = 950000, .frequency_max = 2150000, .frequency_stepsize = 125, /* kHz for QPSK frontends */ diff --git a/drivers/media/dvb/frontends/s5h1432.c b/drivers/media/dvb/frontends/s5h1432.c index 0c6dcb90d168..8352ce1c9556 100644 --- a/drivers/media/dvb/frontends/s5h1432.c +++ b/drivers/media/dvb/frontends/s5h1432.c @@ -178,9 +178,9 @@ static int s5h1432_set_IF(struct dvb_frontend *fe, u32 ifFreqHz) } /* Talk to the demod, set the FEC, GUARD, QAM settings etc */ -static int s5h1432_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int s5h1432_set_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; u32 dvb_bandwidth = 8; struct s5h1432_state *state = fe->demodulator_priv; @@ -188,26 +188,26 @@ static int s5h1432_set_frontend(struct dvb_frontend *fe, /*current_frequency = p->frequency; */ /*state->current_frequency = p->frequency; */ } else { - fe->ops.tuner_ops.set_params(fe, p); + fe->ops.tuner_ops.set_params(fe); msleep(300); s5h1432_set_channel_bandwidth(fe, dvb_bandwidth); - switch (p->u.ofdm.bandwidth) { - case BANDWIDTH_6_MHZ: + switch (p->bandwidth_hz) { + case 6000000: dvb_bandwidth = 6; s5h1432_set_IF(fe, IF_FREQ_4_MHZ); break; - case BANDWIDTH_7_MHZ: + case 7000000: dvb_bandwidth = 7; s5h1432_set_IF(fe, IF_FREQ_4_MHZ); break; - case BANDWIDTH_8_MHZ: + case 8000000: dvb_bandwidth = 8; s5h1432_set_IF(fe, IF_FREQ_4_MHZ); break; default: return 0; } - /*fe->ops.tuner_ops.set_params(fe, p); */ + /*fe->ops.tuner_ops.set_params(fe); */ /*Soft Reset chip*/ msleep(30); s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1a); @@ -215,23 +215,23 @@ static int s5h1432_set_frontend(struct dvb_frontend *fe, s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1b); s5h1432_set_channel_bandwidth(fe, dvb_bandwidth); - switch (p->u.ofdm.bandwidth) { - case BANDWIDTH_6_MHZ: + switch (p->bandwidth_hz) { + case 6000000: dvb_bandwidth = 6; s5h1432_set_IF(fe, IF_FREQ_4_MHZ); break; - case BANDWIDTH_7_MHZ: + case 7000000: dvb_bandwidth = 7; s5h1432_set_IF(fe, IF_FREQ_4_MHZ); break; - case BANDWIDTH_8_MHZ: + case 8000000: dvb_bandwidth = 8; s5h1432_set_IF(fe, IF_FREQ_4_MHZ); break; default: return 0; } - /*fe->ops.tuner_ops.set_params(fe,p); */ + /*fe->ops.tuner_ops.set_params(fe); */ /*Soft Reset chip*/ msleep(30); s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1a); @@ -329,12 +329,6 @@ static int s5h1432_read_ber(struct dvb_frontend *fe, u32 *ber) return 0; } -static int s5h1432_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - return 0; -} - static int s5h1432_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune) { @@ -381,10 +375,9 @@ error: EXPORT_SYMBOL(s5h1432_attach); static struct dvb_frontend_ops s5h1432_ops = { - + .delsys = { SYS_DVBT }, .info = { .name = "Samsung s5h1432 DVB-T Frontend", - .type = FE_OFDM, .frequency_min = 177000000, .frequency_max = 858000000, .frequency_stepsize = 166666, @@ -397,7 +390,6 @@ static struct dvb_frontend_ops s5h1432_ops = { .init = s5h1432_init, .sleep = s5h1432_sleep, .set_frontend = s5h1432_set_frontend, - .get_frontend = s5h1432_get_frontend, .get_tune_settings = s5h1432_get_tune_settings, .read_status = s5h1432_read_status, .read_ber = s5h1432_read_ber, diff --git a/drivers/media/dvb/frontends/s921.c b/drivers/media/dvb/frontends/s921.c index ca0103d5f148..cd2288c07147 100644 --- a/drivers/media/dvb/frontends/s921.c +++ b/drivers/media/dvb/frontends/s921.c @@ -262,9 +262,9 @@ static int s921_i2c_readreg(struct s921_state *state, u8 i2c_addr, u8 reg) s921_i2c_writeregdata(state, state->config->demod_address, \ regdata, ARRAY_SIZE(regdata)) -static int s921_pll_tune(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int s921_pll_tune(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct s921_state *state = fe->demodulator_priv; int band, rc, i; unsigned long f_offset; @@ -414,9 +414,9 @@ static int s921_read_signal_strength(struct dvb_frontend *fe, u16 *strength) return 0; } -static int s921_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int s921_set_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct s921_state *state = fe->demodulator_priv; int rc; @@ -424,7 +424,7 @@ static int s921_set_frontend(struct dvb_frontend *fe, /* FIXME: We don't know how to use non-auto mode */ - rc = s921_pll_tune(fe, p); + rc = s921_pll_tune(fe); if (rc < 0) return rc; @@ -433,19 +433,20 @@ static int s921_set_frontend(struct dvb_frontend *fe, return 0; } -static int s921_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int s921_get_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct s921_state *state = fe->demodulator_priv; /* FIXME: Probably it is possible to get it from regs f1 and f2 */ p->frequency = state->currentfreq; + p->delivery_system = SYS_ISDBT; return 0; } static int s921_tune(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params, + bool re_tune, unsigned int mode_flags, unsigned int *delay, fe_status_t *status) @@ -454,8 +455,8 @@ static int s921_tune(struct dvb_frontend *fe, dprintk("\n"); - if (params != NULL) - rc = s921_set_frontend(fe, params); + if (re_tune) + rc = s921_set_frontend(fe); if (!(mode_flags & FE_TUNE_MODE_ONESHOT)) s921_read_status(fe, status); @@ -510,10 +511,10 @@ rcor: EXPORT_SYMBOL(s921_attach); static struct dvb_frontend_ops s921_ops = { + .delsys = { SYS_ISDBT }, /* Use dib8000 values per default */ .info = { .name = "Sharp S921", - .type = FE_OFDM, .frequency_min = 470000000, /* * Max should be 770MHz instead, according with Sharp docs, diff --git a/drivers/media/dvb/frontends/si21xx.c b/drivers/media/dvb/frontends/si21xx.c index 4b0c99a08a85..a68a64800df7 100644 --- a/drivers/media/dvb/frontends/si21xx.c +++ b/drivers/media/dvb/frontends/si21xx.c @@ -690,20 +690,7 @@ static int si21xx_setacquire(struct dvb_frontend *fe, int symbrate, return status; } -static int si21xx_set_property(struct dvb_frontend *fe, struct dtv_property *p) -{ - dprintk("%s(..)\n", __func__); - return 0; -} - -static int si21xx_get_property(struct dvb_frontend *fe, struct dtv_property *p) -{ - dprintk("%s(..)\n", __func__); - return 0; -} - -static int si21xx_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *dfp) +static int si21xx_set_frontend(struct dvb_frontend *fe) { struct si21xx_state *state = fe->demodulator_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache; @@ -877,10 +864,9 @@ static void si21xx_release(struct dvb_frontend *fe) } static struct dvb_frontend_ops si21xx_ops = { - + .delsys = { SYS_DVBS }, .info = { .name = "SL SI21XX DVB-S", - .type = FE_QPSK, .frequency_min = 950000, .frequency_max = 2150000, .frequency_stepsize = 125, /* kHz for QPSK frontends */ @@ -908,8 +894,6 @@ static struct dvb_frontend_ops si21xx_ops = { .set_tone = si21xx_set_tone, .set_voltage = si21xx_set_voltage, - .set_property = si21xx_set_property, - .get_property = si21xx_get_property, .set_frontend = si21xx_set_frontend, }; diff --git a/drivers/media/dvb/frontends/sp8870.c b/drivers/media/dvb/frontends/sp8870.c index b85eb60a893e..e37274c8f14e 100644 --- a/drivers/media/dvb/frontends/sp8870.c +++ b/drivers/media/dvb/frontends/sp8870.c @@ -168,13 +168,13 @@ static int sp8870_read_data_valid_signal(struct sp8870_state* state) return (sp8870_readreg(state, 0x0D02) > 0); } -static int configure_reg0xc05 (struct dvb_frontend_parameters *p, u16 *reg0xc05) +static int configure_reg0xc05 (struct dtv_frontend_properties *p, u16 *reg0xc05) { int known_parameters = 1; *reg0xc05 = 0x000; - switch (p->u.ofdm.constellation) { + switch (p->modulation) { case QPSK: break; case QAM_16: @@ -190,7 +190,7 @@ static int configure_reg0xc05 (struct dvb_frontend_parameters *p, u16 *reg0xc05) return -EINVAL; }; - switch (p->u.ofdm.hierarchy_information) { + switch (p->hierarchy) { case HIERARCHY_NONE: break; case HIERARCHY_1: @@ -209,7 +209,7 @@ static int configure_reg0xc05 (struct dvb_frontend_parameters *p, u16 *reg0xc05) return -EINVAL; }; - switch (p->u.ofdm.code_rate_HP) { + switch (p->code_rate_HP) { case FEC_1_2: break; case FEC_2_3: @@ -245,9 +245,9 @@ static int sp8870_wake_up(struct sp8870_state* state) return sp8870_writereg(state, 0xC18, 0x00D); } -static int sp8870_set_frontend_parameters (struct dvb_frontend* fe, - struct dvb_frontend_parameters *p) +static int sp8870_set_frontend_parameters(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct sp8870_state* state = fe->demodulator_priv; int err; u16 reg0xc05; @@ -260,7 +260,7 @@ static int sp8870_set_frontend_parameters (struct dvb_frontend* fe, // set tuner parameters if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); + fe->ops.tuner_ops.set_params(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); } @@ -277,15 +277,15 @@ static int sp8870_set_frontend_parameters (struct dvb_frontend* fe, sp8870_writereg(state, 0x030A, 0x0000); // filter for 6/7/8 Mhz channel - if (p->u.ofdm.bandwidth == BANDWIDTH_6_MHZ) + if (p->bandwidth_hz == 6000000) sp8870_writereg(state, 0x0311, 0x0002); - else if (p->u.ofdm.bandwidth == BANDWIDTH_7_MHZ) + else if (p->bandwidth_hz == 7000000) sp8870_writereg(state, 0x0311, 0x0001); else sp8870_writereg(state, 0x0311, 0x0000); // scan order: 2k first = 0x0000, 8k first = 0x0001 - if (p->u.ofdm.transmission_mode == TRANSMISSION_MODE_2K) + if (p->transmission_mode == TRANSMISSION_MODE_2K) sp8870_writereg(state, 0x0338, 0x0000); else sp8870_writereg(state, 0x0338, 0x0001); @@ -459,8 +459,9 @@ static int lockups; /* only for debugging: counter for channel switches */ static int switches; -static int sp8870_set_frontend (struct dvb_frontend* fe, struct dvb_frontend_parameters *p) +static int sp8870_set_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct sp8870_state* state = fe->demodulator_priv; /* @@ -479,7 +480,8 @@ static int sp8870_set_frontend (struct dvb_frontend* fe, struct dvb_frontend_par for (trials = 1; trials <= MAXTRIALS; trials++) { - if ((err = sp8870_set_frontend_parameters(fe, p))) + err = sp8870_set_frontend_parameters(fe); + if (err) return err; for (check_count = 0; check_count < MAXCHECKS; check_count++) { @@ -579,10 +581,9 @@ error: } static struct dvb_frontend_ops sp8870_ops = { - + .delsys = { SYS_DVBT }, .info = { .name = "Spase SP8870 DVB-T", - .type = FE_OFDM, .frequency_min = 470000000, .frequency_max = 860000000, .frequency_stepsize = 166666, diff --git a/drivers/media/dvb/frontends/sp887x.c b/drivers/media/dvb/frontends/sp887x.c index 4a7c3d842608..f4096ccb226e 100644 --- a/drivers/media/dvb/frontends/sp887x.c +++ b/drivers/media/dvb/frontends/sp887x.c @@ -209,13 +209,13 @@ static int sp887x_initial_setup (struct dvb_frontend* fe, const struct firmware return 0; }; -static int configure_reg0xc05 (struct dvb_frontend_parameters *p, u16 *reg0xc05) +static int configure_reg0xc05(struct dtv_frontend_properties *p, u16 *reg0xc05) { int known_parameters = 1; *reg0xc05 = 0x000; - switch (p->u.ofdm.constellation) { + switch (p->modulation) { case QPSK: break; case QAM_16: @@ -231,7 +231,7 @@ static int configure_reg0xc05 (struct dvb_frontend_parameters *p, u16 *reg0xc05) return -EINVAL; }; - switch (p->u.ofdm.hierarchy_information) { + switch (p->hierarchy) { case HIERARCHY_NONE: break; case HIERARCHY_1: @@ -250,7 +250,7 @@ static int configure_reg0xc05 (struct dvb_frontend_parameters *p, u16 *reg0xc05) return -EINVAL; }; - switch (p->u.ofdm.code_rate_HP) { + switch (p->code_rate_HP) { case FEC_1_2: break; case FEC_2_3: @@ -303,17 +303,30 @@ static void divide (int n, int d, int *quotient_i, int *quotient_f) } static void sp887x_correct_offsets (struct sp887x_state* state, - struct dvb_frontend_parameters *p, + struct dtv_frontend_properties *p, int actual_freq) { static const u32 srate_correction [] = { 1879617, 4544878, 8098561 }; - int bw_index = p->u.ofdm.bandwidth - BANDWIDTH_8_MHZ; + int bw_index; int freq_offset = actual_freq - p->frequency; int sysclock = 61003; //[kHz] int ifreq = 36000000; int freq; int frequency_shift; + switch (p->bandwidth_hz) { + default: + case 8000000: + bw_index = 0; + break; + case 7000000: + bw_index = 1; + break; + case 6000000: + bw_index = 2; + break; + } + if (p->inversion == INVERSION_ON) freq = ifreq - freq_offset; else @@ -333,17 +346,17 @@ static void sp887x_correct_offsets (struct sp887x_state* state, sp887x_writereg(state, 0x30a, frequency_shift & 0xfff); } -static int sp887x_setup_frontend_parameters (struct dvb_frontend* fe, - struct dvb_frontend_parameters *p) +static int sp887x_setup_frontend_parameters(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct sp887x_state* state = fe->demodulator_priv; unsigned actual_freq; int err; u16 val, reg0xc05; - if (p->u.ofdm.bandwidth != BANDWIDTH_8_MHZ && - p->u.ofdm.bandwidth != BANDWIDTH_7_MHZ && - p->u.ofdm.bandwidth != BANDWIDTH_6_MHZ) + if (p->bandwidth_hz != 8000000 && + p->bandwidth_hz != 7000000 && + p->bandwidth_hz != 6000000) return -EINVAL; if ((err = configure_reg0xc05(p, ®0xc05))) @@ -353,7 +366,7 @@ static int sp887x_setup_frontend_parameters (struct dvb_frontend* fe, /* setup the PLL */ if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); + fe->ops.tuner_ops.set_params(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); } if (fe->ops.tuner_ops.get_frequency) { @@ -369,9 +382,9 @@ static int sp887x_setup_frontend_parameters (struct dvb_frontend* fe, sp887x_correct_offsets(state, p, actual_freq); /* filter for 6/7/8 Mhz channel */ - if (p->u.ofdm.bandwidth == BANDWIDTH_6_MHZ) + if (p->bandwidth_hz == 6000000) val = 2; - else if (p->u.ofdm.bandwidth == BANDWIDTH_7_MHZ) + else if (p->bandwidth_hz == 7000000) val = 1; else val = 0; @@ -379,16 +392,16 @@ static int sp887x_setup_frontend_parameters (struct dvb_frontend* fe, sp887x_writereg(state, 0x311, val); /* scan order: 2k first = 0, 8k first = 1 */ - if (p->u.ofdm.transmission_mode == TRANSMISSION_MODE_2K) + if (p->transmission_mode == TRANSMISSION_MODE_2K) sp887x_writereg(state, 0x338, 0x000); else sp887x_writereg(state, 0x338, 0x001); sp887x_writereg(state, 0xc05, reg0xc05); - if (p->u.ofdm.bandwidth == BANDWIDTH_6_MHZ) + if (p->bandwidth_hz == 6000000) val = 2 << 3; - else if (p->u.ofdm.bandwidth == BANDWIDTH_7_MHZ) + else if (p->bandwidth_hz == 7000000) val = 3 << 3; else val = 0 << 3; @@ -579,10 +592,9 @@ error: } static struct dvb_frontend_ops sp887x_ops = { - + .delsys = { SYS_DVBT }, .info = { .name = "Spase SP887x DVB-T", - .type = FE_OFDM, .frequency_min = 50500000, .frequency_max = 858000000, .frequency_stepsize = 166666, diff --git a/drivers/media/dvb/frontends/stb0899_drv.c b/drivers/media/dvb/frontends/stb0899_drv.c index 8408ef877b4b..38565beafe23 100644 --- a/drivers/media/dvb/frontends/stb0899_drv.c +++ b/drivers/media/dvb/frontends/stb0899_drv.c @@ -1431,7 +1431,7 @@ static void stb0899_set_iterations(struct stb0899_state *state) stb0899_write_s2reg(state, STB0899_S2FEC, STB0899_BASE_MAX_ITER, STB0899_OFF0_MAX_ITER, reg); } -static enum dvbfe_search stb0899_search(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) +static enum dvbfe_search stb0899_search(struct dvb_frontend *fe) { struct stb0899_state *state = fe->demodulator_priv; struct stb0899_params *i_params = &state->params; @@ -1441,8 +1441,8 @@ static enum dvbfe_search stb0899_search(struct dvb_frontend *fe, struct dvb_fron u32 SearchRange, gain; - i_params->freq = p->frequency; - i_params->srate = p->u.qpsk.symbol_rate; + i_params->freq = props->frequency; + i_params->srate = props->symbol_rate; state->delsys = props->delivery_system; dprintk(state->verbose, FE_DEBUG, 1, "delivery system=%d", state->delsys); @@ -1568,34 +1568,15 @@ static enum dvbfe_search stb0899_search(struct dvb_frontend *fe, struct dvb_fron return DVBFE_ALGO_SEARCH_ERROR; } -/* - * stb0899_track - * periodically check the signal level against a specified - * threshold level and perform derotator centering. - * called once we have a lock from a successful search - * event. - * - * Will be called periodically called to maintain the - * lock. - * - * Will be used to get parameters as well as info from - * the decoded baseband header - * - * Once a new lock has established, the internal state - * frequency (internal->freq) is updated - */ -static int stb0899_track(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) -{ - return 0; -} -static int stb0899_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) +static int stb0899_get_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct stb0899_state *state = fe->demodulator_priv; struct stb0899_internal *internal = &state->internal; dprintk(state->verbose, FE_DEBUG, 1, "Get params"); - p->u.qpsk.symbol_rate = internal->srate; + p->symbol_rate = internal->srate; return 0; } @@ -1606,10 +1587,9 @@ static enum dvbfe_algo stb0899_frontend_algo(struct dvb_frontend *fe) } static struct dvb_frontend_ops stb0899_ops = { - + .delsys = { SYS_DVBS, SYS_DVBS2, SYS_DSS }, .info = { .name = "STB0899 Multistandard", - .type = FE_QPSK, .frequency_min = 950000, .frequency_max = 2150000, .frequency_stepsize = 0, @@ -1632,8 +1612,7 @@ static struct dvb_frontend_ops stb0899_ops = { .get_frontend_algo = stb0899_frontend_algo, .search = stb0899_search, - .track = stb0899_track, - .get_frontend = stb0899_get_frontend, + .get_frontend = stb0899_get_frontend, .read_status = stb0899_read_status, diff --git a/drivers/media/dvb/frontends/stb6000.c b/drivers/media/dvb/frontends/stb6000.c index ed699647050e..a0c3c526b132 100644 --- a/drivers/media/dvb/frontends/stb6000.c +++ b/drivers/media/dvb/frontends/stb6000.c @@ -75,9 +75,9 @@ static int stb6000_sleep(struct dvb_frontend *fe) return (ret == 1) ? 0 : ret; } -static int stb6000_set_params(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) +static int stb6000_set_params(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct stb6000_priv *priv = fe->tuner_priv; unsigned int n, m; int ret; @@ -93,8 +93,8 @@ static int stb6000_set_params(struct dvb_frontend *fe, dprintk("%s:\n", __func__); - freq_mhz = params->frequency / 1000; - bandwidth = params->u.qpsk.symbol_rate / 1000000; + freq_mhz = p->frequency / 1000; + bandwidth = p->symbol_rate / 1000000; if (bandwidth > 31) bandwidth = 31; diff --git a/drivers/media/dvb/frontends/stb6100.c b/drivers/media/dvb/frontends/stb6100.c index bc1a8af4f6e1..def88abb30bf 100644 --- a/drivers/media/dvb/frontends/stb6100.c +++ b/drivers/media/dvb/frontends/stb6100.c @@ -327,7 +327,7 @@ static int stb6100_set_frequency(struct dvb_frontend *fe, u32 frequency) int rc; const struct stb6100_lkup *ptr; struct stb6100_state *state = fe->tuner_priv; - struct dvb_frontend_parameters p; + struct dtv_frontend_properties *p = &fe->dtv_property_cache; u32 srate = 0, fvco, nint, nfrac; u8 regs[STB6100_NUMREGS]; @@ -337,9 +337,9 @@ static int stb6100_set_frequency(struct dvb_frontend *fe, u32 frequency) if (fe->ops.get_frontend) { dprintk(verbose, FE_DEBUG, 1, "Get frontend parameters"); - fe->ops.get_frontend(fe, &p); + fe->ops.get_frontend(fe); } - srate = p.u.qpsk.symbol_rate; + srate = p->symbol_rate; /* Set up tuner cleanly, LPF calibration on */ rc = stb6100_write_reg(state, STB6100_FCCK, 0x4d | STB6100_FCCK_FCCK); diff --git a/drivers/media/dvb/frontends/stv0288.c b/drivers/media/dvb/frontends/stv0288.c index 0aa3962ff18b..fb5548a82208 100644 --- a/drivers/media/dvb/frontends/stv0288.c +++ b/drivers/media/dvb/frontends/stv0288.c @@ -452,14 +452,7 @@ static int stv0288_set_property(struct dvb_frontend *fe, struct dtv_property *p) return 0; } -static int stv0288_get_property(struct dvb_frontend *fe, struct dtv_property *p) -{ - dprintk("%s(..)\n", __func__); - return 0; -} - -static int stv0288_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *dfp) +static int stv0288_set_frontend(struct dvb_frontend *fe) { struct stv0288_state *state = fe->demodulator_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache; @@ -481,10 +474,8 @@ static int stv0288_set_frontend(struct dvb_frontend *fe, state->config->set_ts_params(fe, 0); /* only frequency & symbol_rate are used for tuner*/ - dfp->frequency = c->frequency; - dfp->u.qpsk.symbol_rate = c->symbol_rate; if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, dfp); + fe->ops.tuner_ops.set_params(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); } @@ -545,10 +536,9 @@ static void stv0288_release(struct dvb_frontend *fe) } static struct dvb_frontend_ops stv0288_ops = { - + .delsys = { SYS_DVBS }, .info = { .name = "ST STV0288 DVB-S", - .type = FE_QPSK, .frequency_min = 950000, .frequency_max = 2150000, .frequency_stepsize = 1000, /* kHz for QPSK frontends */ @@ -578,7 +568,6 @@ static struct dvb_frontend_ops stv0288_ops = { .set_voltage = stv0288_set_voltage, .set_property = stv0288_set_property, - .get_property = stv0288_get_property, .set_frontend = stv0288_set_frontend, }; diff --git a/drivers/media/dvb/frontends/stv0297.c b/drivers/media/dvb/frontends/stv0297.c index 84d88f33275e..85c157a1fe5e 100644 --- a/drivers/media/dvb/frontends/stv0297.c +++ b/drivers/media/dvb/frontends/stv0297.c @@ -404,8 +404,9 @@ static int stv0297_read_ucblocks(struct dvb_frontend *fe, u32 * ucblocks) return 0; } -static int stv0297_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) +static int stv0297_set_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct stv0297_state *state = fe->demodulator_priv; int u_threshold; int initial_u; @@ -417,7 +418,7 @@ static int stv0297_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par unsigned long timeout; fe_spectral_inversion_t inversion; - switch (p->u.qam.modulation) { + switch (p->modulation) { case QAM_16: case QAM_32: case QAM_64: @@ -455,7 +456,7 @@ static int stv0297_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par stv0297_init(fe); if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); + fe->ops.tuner_ops.set_params(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); } @@ -519,16 +520,16 @@ static int stv0297_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par stv0297_writereg_mask(state, 0x69, 0x0f, 0x00); /* set parameters */ - stv0297_set_qam(state, p->u.qam.modulation); - stv0297_set_symbolrate(state, p->u.qam.symbol_rate / 1000); - stv0297_set_sweeprate(state, sweeprate, p->u.qam.symbol_rate / 1000); + stv0297_set_qam(state, p->modulation); + stv0297_set_symbolrate(state, p->symbol_rate / 1000); + stv0297_set_sweeprate(state, sweeprate, p->symbol_rate / 1000); stv0297_set_carrieroffset(state, carrieroffset); stv0297_set_inversion(state, inversion); /* kick off lock */ /* Disable corner detection for higher QAMs */ - if (p->u.qam.modulation == QAM_128 || - p->u.qam.modulation == QAM_256) + if (p->modulation == QAM_128 || + p->modulation == QAM_256) stv0297_writereg_mask(state, 0x88, 0x08, 0x00); else stv0297_writereg_mask(state, 0x88, 0x08, 0x08); @@ -613,8 +614,9 @@ timeout: return 0; } -static int stv0297_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) +static int stv0297_get_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct stv0297_state *state = fe->demodulator_priv; int reg_00, reg_83; @@ -625,24 +627,24 @@ static int stv0297_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_par p->inversion = (reg_83 & 0x08) ? INVERSION_ON : INVERSION_OFF; if (state->config->invert) p->inversion = (p->inversion == INVERSION_ON) ? INVERSION_OFF : INVERSION_ON; - p->u.qam.symbol_rate = stv0297_get_symbolrate(state) * 1000; - p->u.qam.fec_inner = FEC_NONE; + p->symbol_rate = stv0297_get_symbolrate(state) * 1000; + p->fec_inner = FEC_NONE; switch ((reg_00 >> 4) & 0x7) { case 0: - p->u.qam.modulation = QAM_16; + p->modulation = QAM_16; break; case 1: - p->u.qam.modulation = QAM_32; + p->modulation = QAM_32; break; case 2: - p->u.qam.modulation = QAM_128; + p->modulation = QAM_128; break; case 3: - p->u.qam.modulation = QAM_256; + p->modulation = QAM_256; break; case 4: - p->u.qam.modulation = QAM_64; + p->modulation = QAM_64; break; } @@ -688,10 +690,9 @@ error: } static struct dvb_frontend_ops stv0297_ops = { - + .delsys = { SYS_DVBC_ANNEX_A }, .info = { .name = "ST STV0297 DVB-C", - .type = FE_QAM, .frequency_min = 47000000, .frequency_max = 862000000, .frequency_stepsize = 62500, diff --git a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c index 42684bec8883..057b5f8effc0 100644 --- a/drivers/media/dvb/frontends/stv0299.c +++ b/drivers/media/dvb/frontends/stv0299.c @@ -559,8 +559,9 @@ static int stv0299_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) return 0; } -static int stv0299_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters * p) +static int stv0299_set_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct stv0299_state* state = fe->demodulator_priv; int invval = 0; @@ -579,24 +580,25 @@ static int stv0299_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par stv0299_writeregI(state, 0x0c, (stv0299_readreg(state, 0x0c) & 0xfe) | invval); if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); + fe->ops.tuner_ops.set_params(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); } - stv0299_set_FEC (state, p->u.qpsk.fec_inner); - stv0299_set_symbolrate (fe, p->u.qpsk.symbol_rate); + stv0299_set_FEC(state, p->fec_inner); + stv0299_set_symbolrate(fe, p->symbol_rate); stv0299_writeregI(state, 0x22, 0x00); stv0299_writeregI(state, 0x23, 0x00); state->tuner_frequency = p->frequency; - state->fec_inner = p->u.qpsk.fec_inner; - state->symbol_rate = p->u.qpsk.symbol_rate; + state->fec_inner = p->fec_inner; + state->symbol_rate = p->symbol_rate; return 0; } -static int stv0299_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters * p) +static int stv0299_get_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct stv0299_state* state = fe->demodulator_priv; s32 derot_freq; int invval; @@ -614,8 +616,8 @@ static int stv0299_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_par if (state->config->invert) invval = (~invval) & 1; p->inversion = invval ? INVERSION_ON : INVERSION_OFF; - p->u.qpsk.fec_inner = stv0299_get_fec (state); - p->u.qpsk.symbol_rate = stv0299_get_symbolrate (state); + p->fec_inner = stv0299_get_fec(state); + p->symbol_rate = stv0299_get_symbolrate(state); return 0; } @@ -646,14 +648,15 @@ static int stv0299_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) static int stv0299_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) { struct stv0299_state* state = fe->demodulator_priv; + struct dtv_frontend_properties *p = &fe->dtv_property_cache; fesettings->min_delay_ms = state->config->min_delay_ms; - if (fesettings->parameters.u.qpsk.symbol_rate < 10000000) { - fesettings->step_size = fesettings->parameters.u.qpsk.symbol_rate / 32000; + if (p->symbol_rate < 10000000) { + fesettings->step_size = p->symbol_rate / 32000; fesettings->max_drift = 5000; } else { - fesettings->step_size = fesettings->parameters.u.qpsk.symbol_rate / 16000; - fesettings->max_drift = fesettings->parameters.u.qpsk.symbol_rate / 2000; + fesettings->step_size = p->symbol_rate / 16000; + fesettings->max_drift = p->symbol_rate / 2000; } return 0; } @@ -705,10 +708,9 @@ error: } static struct dvb_frontend_ops stv0299_ops = { - + .delsys = { SYS_DVBS }, .info = { .name = "ST STV0299 DVB-S", - .type = FE_QPSK, .frequency_min = 950000, .frequency_max = 2150000, .frequency_stepsize = 125, /* kHz for QPSK frontends */ diff --git a/drivers/media/dvb/frontends/stv0367.c b/drivers/media/dvb/frontends/stv0367.c index e57ab53e2e27..fdd20c7737b5 100644 --- a/drivers/media/dvb/frontends/stv0367.c +++ b/drivers/media/dvb/frontends/stv0367.c @@ -1577,9 +1577,9 @@ int stv0367ter_init(struct dvb_frontend *fe) return 0; } -static int stv0367ter_algo(struct dvb_frontend *fe, - struct dvb_frontend_parameters *param) +static int stv0367ter_algo(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct stv0367_state *state = fe->demodulator_priv; struct stv0367ter_state *ter_state = state->ter_state; int offset = 0, tempo = 0; @@ -1591,7 +1591,7 @@ static int stv0367ter_algo(struct dvb_frontend *fe, dprintk("%s:\n", __func__); - ter_state->frequency = param->frequency; + ter_state->frequency = p->frequency; ter_state->force = FE_TER_FORCENONE + stv0367_readbits(state, F367TER_FORCE) * 2; ter_state->if_iq_mode = state->config->if_iq_mode; @@ -1620,7 +1620,7 @@ static int stv0367ter_algo(struct dvb_frontend *fe, usleep_range(5000, 7000); - switch (param->inversion) { + switch (p->inversion) { case INVERSION_AUTO: default: dprintk("%s: inversion AUTO\n", __func__); @@ -1636,10 +1636,10 @@ static int stv0367ter_algo(struct dvb_frontend *fe, case INVERSION_OFF: if (ter_state->if_iq_mode == FE_TER_IQ_TUNER) stv0367_writebits(state, F367TER_IQ_INVERT, - param->inversion); + p->inversion); else stv0367_writebits(state, F367TER_INV_SPECTR, - param->inversion); + p->inversion); break; } @@ -1806,10 +1806,9 @@ static int stv0367ter_algo(struct dvb_frontend *fe, return 0; } -static int stv0367ter_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *param) +static int stv0367ter_set_frontend(struct dvb_frontend *fe) { - struct dvb_ofdm_parameters *op = ¶m->u.ofdm; + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct stv0367_state *state = fe->demodulator_priv; struct stv0367ter_state *ter_state = state->ter_state; @@ -1822,12 +1821,12 @@ static int stv0367ter_set_frontend(struct dvb_frontend *fe, if (fe->ops.tuner_ops.set_params) { if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); - fe->ops.tuner_ops.set_params(fe, param); + fe->ops.tuner_ops.set_params(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); } - switch (op->transmission_mode) { + switch (p->transmission_mode) { default: case TRANSMISSION_MODE_AUTO: case TRANSMISSION_MODE_2K: @@ -1841,34 +1840,34 @@ static int stv0367ter_set_frontend(struct dvb_frontend *fe, break; } - switch (op->guard_interval) { + switch (p->guard_interval) { default: case GUARD_INTERVAL_1_32: case GUARD_INTERVAL_1_16: case GUARD_INTERVAL_1_8: case GUARD_INTERVAL_1_4: - ter_state->guard = op->guard_interval; + ter_state->guard = p->guard_interval; break; case GUARD_INTERVAL_AUTO: ter_state->guard = GUARD_INTERVAL_1_32; break; } - switch (op->bandwidth) { - case BANDWIDTH_6_MHZ: + switch (p->bandwidth_hz) { + case 6000000: ter_state->bw = FE_TER_CHAN_BW_6M; break; - case BANDWIDTH_7_MHZ: + case 7000000: ter_state->bw = FE_TER_CHAN_BW_7M; break; - case BANDWIDTH_8_MHZ: + case 8000000: default: ter_state->bw = FE_TER_CHAN_BW_8M; } ter_state->hierarchy = FE_TER_HIER_NONE; - switch (param->inversion) { + switch (p->inversion) { case INVERSION_OFF: case INVERSION_ON: num_trials = 1; @@ -1885,14 +1884,14 @@ static int stv0367ter_set_frontend(struct dvb_frontend *fe, while (((index) < num_trials) && (ter_state->state != FE_TER_LOCKOK)) { if (!ter_state->first_lock) { - if (param->inversion == INVERSION_AUTO) + if (p->inversion == INVERSION_AUTO) ter_state->sense = SenseTrials[index]; } - stv0367ter_algo(fe,/* &pLook, result,*/ param); + stv0367ter_algo(fe); if ((ter_state->state == FE_TER_LOCKOK) && - (param->inversion == INVERSION_AUTO) && + (p->inversion == INVERSION_AUTO) && (index == 1)) { /* invert spectrum sense */ SenseTrials[index] = SenseTrials[0]; @@ -1927,50 +1926,48 @@ static int stv0367ter_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) return 0; } -static int stv0367ter_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *param) +static int stv0367ter_get_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct stv0367_state *state = fe->demodulator_priv; struct stv0367ter_state *ter_state = state->ter_state; - struct dvb_ofdm_parameters *op = ¶m->u.ofdm; - struct dtv_frontend_properties *c = &fe->dtv_property_cache; int error = 0; enum stv0367_ter_mode mode; int constell = 0,/* snr = 0,*/ Data = 0; - param->frequency = stv0367_get_tuner_freq(fe); - if ((int)param->frequency < 0) - param->frequency = c->frequency; + p->frequency = stv0367_get_tuner_freq(fe); + if ((int)p->frequency < 0) + p->frequency = -p->frequency; constell = stv0367_readbits(state, F367TER_TPS_CONST); if (constell == 0) - op->constellation = QPSK; + p->modulation = QPSK; else if (constell == 1) - op->constellation = QAM_16; + p->modulation = QAM_16; else - op->constellation = QAM_64; + p->modulation = QAM_64; - param->inversion = stv0367_readbits(state, F367TER_INV_SPECTR); + p->inversion = stv0367_readbits(state, F367TER_INV_SPECTR); /* Get the Hierarchical mode */ Data = stv0367_readbits(state, F367TER_TPS_HIERMODE); switch (Data) { case 0: - op->hierarchy_information = HIERARCHY_NONE; + p->hierarchy = HIERARCHY_NONE; break; case 1: - op->hierarchy_information = HIERARCHY_1; + p->hierarchy = HIERARCHY_1; break; case 2: - op->hierarchy_information = HIERARCHY_2; + p->hierarchy = HIERARCHY_2; break; case 3: - op->hierarchy_information = HIERARCHY_4; + p->hierarchy = HIERARCHY_4; break; default: - op->hierarchy_information = HIERARCHY_AUTO; + p->hierarchy = HIERARCHY_AUTO; break; /* error */ } @@ -1982,22 +1979,22 @@ static int stv0367ter_get_frontend(struct dvb_frontend *fe, switch (Data) { case 0: - op->code_rate_HP = FEC_1_2; + p->code_rate_HP = FEC_1_2; break; case 1: - op->code_rate_HP = FEC_2_3; + p->code_rate_HP = FEC_2_3; break; case 2: - op->code_rate_HP = FEC_3_4; + p->code_rate_HP = FEC_3_4; break; case 3: - op->code_rate_HP = FEC_5_6; + p->code_rate_HP = FEC_5_6; break; case 4: - op->code_rate_HP = FEC_7_8; + p->code_rate_HP = FEC_7_8; break; default: - op->code_rate_HP = FEC_AUTO; + p->code_rate_HP = FEC_AUTO; break; /* error */ } @@ -2005,19 +2002,19 @@ static int stv0367ter_get_frontend(struct dvb_frontend *fe, switch (mode) { case FE_TER_MODE_2K: - op->transmission_mode = TRANSMISSION_MODE_2K; + p->transmission_mode = TRANSMISSION_MODE_2K; break; /* case FE_TER_MODE_4K: - op->transmission_mode = TRANSMISSION_MODE_4K; + p->transmission_mode = TRANSMISSION_MODE_4K; break;*/ case FE_TER_MODE_8K: - op->transmission_mode = TRANSMISSION_MODE_8K; + p->transmission_mode = TRANSMISSION_MODE_8K; break; default: - op->transmission_mode = TRANSMISSION_MODE_AUTO; + p->transmission_mode = TRANSMISSION_MODE_AUTO; } - op->guard_interval = stv0367_readbits(state, F367TER_SYR_GUARD); + p->guard_interval = stv0367_readbits(state, F367TER_SYR_GUARD); return error; } @@ -2265,9 +2262,9 @@ static void stv0367_release(struct dvb_frontend *fe) } static struct dvb_frontend_ops stv0367ter_ops = { + .delsys = { SYS_DVBT }, .info = { .name = "ST STV0367 DVB-T", - .type = FE_OFDM, .frequency_min = 47000000, .frequency_max = 862000000, .frequency_stepsize = 15625, @@ -2822,9 +2819,8 @@ int stv0367cab_init(struct dvb_frontend *fe) } static enum stv0367_cab_signal_type stv0367cab_algo(struct stv0367_state *state, - struct dvb_frontend_parameters *param) + struct dtv_frontend_properties *p) { - struct dvb_qam_parameters *op = ¶m->u.qam; struct stv0367cab_state *cab_state = state->cab_state; enum stv0367_cab_signal_type signalType = FE_CAB_NOAGC; u32 QAMFEC_Lock, QAM_Lock, u32_tmp, @@ -2839,7 +2835,7 @@ enum stv0367_cab_signal_type stv0367cab_algo(struct stv0367_state *state, /* A max lock time of 25 ms is allowed for delayed AGC */ AGCTimeOut = 25; /* 100000 symbols needed by the TRL as a maximum value */ - TRLTimeOut = 100000000 / op->symbol_rate; + TRLTimeOut = 100000000 / p->symbol_rate; /* CRLSymbols is the needed number of symbols to achieve a lock within [-4%, +4%] of the symbol rate. CRL timeout is calculated @@ -2849,7 +2845,7 @@ enum stv0367_cab_signal_type stv0367cab_algo(struct stv0367_state *state, A characterization must be performed with these echoes to get new timeout values. */ - switch (op->modulation) { + switch (p->modulation) { case QAM_16: CRLSymbols = 150000; EQLTimeOut = 100; @@ -2883,9 +2879,9 @@ enum stv0367_cab_signal_type stv0367cab_algo(struct stv0367_state *state, } else #endif CRLTimeOut = (25 * CRLSymbols * (cab_state->search_range / 1000)) / - (op->symbol_rate / 1000); + (p->symbol_rate / 1000); - CRLTimeOut = (1000 * CRLTimeOut) / op->symbol_rate; + CRLTimeOut = (1000 * CRLTimeOut) / p->symbol_rate; /* Timeouts below 50ms are coerced */ if (CRLTimeOut < 50) CRLTimeOut = 50; @@ -2915,7 +2911,7 @@ enum stv0367_cab_signal_type stv0367cab_algo(struct stv0367_state *state, stv0367cab_set_derot_freq(state, cab_state->adc_clk, (1000 * (s32)state->config->if_khz + cab_state->derot_offset)); /* Disable the Allpass Filter when the symbol rate is out of range */ - if ((op->symbol_rate > 10800000) | (op->symbol_rate < 1800000)) { + if ((p->symbol_rate > 10800000) | (p->symbol_rate < 1800000)) { stv0367_writebits(state, F367CAB_ADJ_EN, 0); stv0367_writebits(state, F367CAB_ALLPASSFILT_EN, 0); } @@ -2999,7 +2995,7 @@ enum stv0367_cab_signal_type stv0367cab_algo(struct stv0367_state *state, if (QAMFEC_Lock) { signalType = FE_CAB_DATAOK; - cab_state->modulation = op->modulation; + cab_state->modulation = p->modulation; cab_state->spect_inv = stv0367_readbits(state, F367CAB_QUAD_INV); #if 0 @@ -3081,20 +3077,19 @@ enum stv0367_cab_signal_type stv0367cab_algo(struct stv0367_state *state, return signalType; } -static int stv0367cab_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *param) +static int stv0367cab_set_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct stv0367_state *state = fe->demodulator_priv; struct stv0367cab_state *cab_state = state->cab_state; - struct dvb_qam_parameters *op = ¶m->u.qam; enum stv0367cab_mod QAMSize = 0; dprintk("%s: freq = %d, srate = %d\n", __func__, - param->frequency, op->symbol_rate); + p->frequency, p->symbol_rate); cab_state->derot_offset = 0; - switch (op->modulation) { + switch (p->modulation) { case QAM_16: QAMSize = FE_CAB_MOD_QAM16; break; @@ -3120,77 +3115,76 @@ static int stv0367cab_set_frontend(struct dvb_frontend *fe, if (fe->ops.tuner_ops.set_params) { if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); - fe->ops.tuner_ops.set_params(fe, param); + fe->ops.tuner_ops.set_params(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); } stv0367cab_SetQamSize( state, - op->symbol_rate, + p->symbol_rate, QAMSize); stv0367cab_set_srate(state, cab_state->adc_clk, cab_state->mclk, - op->symbol_rate, + p->symbol_rate, QAMSize); /* Search algorithm launch, [-1.1*RangeOffset, +1.1*RangeOffset] scan */ - cab_state->state = stv0367cab_algo(state, param); + cab_state->state = stv0367cab_algo(state, p); return 0; } -static int stv0367cab_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *param) +static int stv0367cab_get_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct stv0367_state *state = fe->demodulator_priv; struct stv0367cab_state *cab_state = state->cab_state; - struct dvb_qam_parameters *op = ¶m->u.qam; enum stv0367cab_mod QAMSize; dprintk("%s:\n", __func__); - op->symbol_rate = stv0367cab_GetSymbolRate(state, cab_state->mclk); + p->symbol_rate = stv0367cab_GetSymbolRate(state, cab_state->mclk); QAMSize = stv0367_readbits(state, F367CAB_QAM_MODE); switch (QAMSize) { case FE_CAB_MOD_QAM16: - op->modulation = QAM_16; + p->modulation = QAM_16; break; case FE_CAB_MOD_QAM32: - op->modulation = QAM_32; + p->modulation = QAM_32; break; case FE_CAB_MOD_QAM64: - op->modulation = QAM_64; + p->modulation = QAM_64; break; case FE_CAB_MOD_QAM128: - op->modulation = QAM_128; + p->modulation = QAM_128; break; case QAM_256: - op->modulation = QAM_256; + p->modulation = QAM_256; break; default: break; } - param->frequency = stv0367_get_tuner_freq(fe); + p->frequency = stv0367_get_tuner_freq(fe); - dprintk("%s: tuner frequency = %d\n", __func__, param->frequency); + dprintk("%s: tuner frequency = %d\n", __func__, p->frequency); if (state->config->if_khz == 0) { - param->frequency += + p->frequency += (stv0367cab_get_derot_freq(state, cab_state->adc_clk) - cab_state->adc_clk / 4000); return 0; } if (state->config->if_khz > cab_state->adc_clk / 1000) - param->frequency += (state->config->if_khz + p->frequency += (state->config->if_khz - stv0367cab_get_derot_freq(state, cab_state->adc_clk) - cab_state->adc_clk / 1000); else - param->frequency += (state->config->if_khz + p->frequency += (state->config->if_khz - stv0367cab_get_derot_freq(state, cab_state->adc_clk)); return 0; @@ -3386,9 +3380,9 @@ static int stv0367cab_read_ucblcks(struct dvb_frontend *fe, u32 *ucblocks) }; static struct dvb_frontend_ops stv0367cab_ops = { + .delsys = { SYS_DVBC_ANNEX_A }, .info = { .name = "ST STV0367 DVB-C", - .type = FE_QAM, .frequency_min = 47000000, .frequency_max = 862000000, .frequency_stepsize = 62500, diff --git a/drivers/media/dvb/frontends/stv0900_core.c b/drivers/media/dvb/frontends/stv0900_core.c index 0ca316d6fffa..7f1badaf0d03 100644 --- a/drivers/media/dvb/frontends/stv0900_core.c +++ b/drivers/media/dvb/frontends/stv0900_core.c @@ -973,22 +973,6 @@ static enum dvbfe_algo stv0900_frontend_algo(struct dvb_frontend *fe) return DVBFE_ALGO_CUSTOM; } -static int stb0900_set_property(struct dvb_frontend *fe, - struct dtv_property *tvp) -{ - dprintk("%s(..)\n", __func__); - - return 0; -} - -static int stb0900_get_property(struct dvb_frontend *fe, - struct dtv_property *tvp) -{ - dprintk("%s(..)\n", __func__); - - return 0; -} - void stv0900_start_search(struct stv0900_internal *intp, enum fe_stv0900_demod_num demod) { @@ -1574,8 +1558,7 @@ static int stv0900_status(struct stv0900_internal *intp, return locked; } -static enum dvbfe_search stv0900_search(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) +static enum dvbfe_search stv0900_search(struct dvb_frontend *fe) { struct stv0900_state *state = fe->demodulator_priv; struct stv0900_internal *intp = state->internal; @@ -1675,12 +1658,6 @@ static int stv0900_read_status(struct dvb_frontend *fe, enum fe_status *status) return 0; } -static int stv0900_track(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - return 0; -} - static int stv0900_stop_ts(struct dvb_frontend *fe, int stop_ts) { @@ -1866,24 +1843,23 @@ static int stv0900_sleep(struct dvb_frontend *fe) return 0; } -static int stv0900_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int stv0900_get_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct stv0900_state *state = fe->demodulator_priv; struct stv0900_internal *intp = state->internal; enum fe_stv0900_demod_num demod = state->demod; struct stv0900_signal_info p_result = intp->result[demod]; p->frequency = p_result.locked ? p_result.frequency : 0; - p->u.qpsk.symbol_rate = p_result.locked ? p_result.symbol_rate : 0; + p->symbol_rate = p_result.locked ? p_result.symbol_rate : 0; return 0; } static struct dvb_frontend_ops stv0900_ops = { - + .delsys = { SYS_DVBS, SYS_DVBS2, SYS_DSS }, .info = { .name = "STV0900 frontend", - .type = FE_QPSK, .frequency_min = 950000, .frequency_max = 2150000, .frequency_stepsize = 125, @@ -1907,10 +1883,7 @@ static struct dvb_frontend_ops stv0900_ops = { .diseqc_send_burst = stv0900_send_burst, .diseqc_recv_slave_reply = stv0900_recv_slave_reply, .set_tone = stv0900_set_tone, - .set_property = stb0900_set_property, - .get_property = stb0900_get_property, .search = stv0900_search, - .track = stv0900_track, .read_status = stv0900_read_status, .read_ber = stv0900_read_ber, .read_signal_strength = stv0900_read_signal_strength, diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c index ebda41936b90..4aef1877ed42 100644 --- a/drivers/media/dvb/frontends/stv090x.c +++ b/drivers/media/dvb/frontends/stv090x.c @@ -3427,17 +3427,17 @@ err: return -1; } -static enum dvbfe_search stv090x_search(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) +static enum dvbfe_search stv090x_search(struct dvb_frontend *fe) { struct stv090x_state *state = fe->demodulator_priv; struct dtv_frontend_properties *props = &fe->dtv_property_cache; - if (p->frequency == 0) + if (props->frequency == 0) return DVBFE_ALGO_SEARCH_INVALID; state->delsys = props->delivery_system; - state->frequency = p->frequency; - state->srate = p->u.qpsk.symbol_rate; + state->frequency = props->frequency; + state->srate = props->symbol_rate; state->search_mode = STV090x_SEARCH_AUTO; state->algo = STV090x_COLD_SEARCH; state->fec = STV090x_PRERR; @@ -4712,10 +4712,9 @@ int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio, u8 dir, u8 value, EXPORT_SYMBOL(stv090x_set_gpio); static struct dvb_frontend_ops stv090x_ops = { - + .delsys = { SYS_DVBS, SYS_DVBS2, SYS_DSS }, .info = { .name = "STV090x Multistandard", - .type = FE_QPSK, .frequency_min = 950000, .frequency_max = 2150000, .frequency_stepsize = 0, @@ -4743,7 +4742,7 @@ static struct dvb_frontend_ops stv090x_ops = { .read_status = stv090x_read_status, .read_ber = stv090x_read_per, .read_signal_strength = stv090x_read_signal_strength, - .read_snr = stv090x_read_cnr + .read_snr = stv090x_read_cnr, }; diff --git a/drivers/media/dvb/frontends/stv6110.c b/drivers/media/dvb/frontends/stv6110.c index 2dca7c8e5148..20b5fa92c53e 100644 --- a/drivers/media/dvb/frontends/stv6110.c +++ b/drivers/media/dvb/frontends/stv6110.c @@ -347,8 +347,7 @@ static int stv6110_set_frequency(struct dvb_frontend *fe, u32 frequency) return 0; } -static int stv6110_set_params(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) +static int stv6110_set_params(struct dvb_frontend *fe) { struct dtv_frontend_properties *c = &fe->dtv_property_cache; u32 bandwidth = carrier_width(c->symbol_rate, c->rolloff); diff --git a/drivers/media/dvb/frontends/tda10021.c b/drivers/media/dvb/frontends/tda10021.c index 6ca533ea0f0e..1bff7f457e19 100644 --- a/drivers/media/dvb/frontends/tda10021.c +++ b/drivers/media/dvb/frontends/tda10021.c @@ -224,47 +224,86 @@ static int tda10021_init (struct dvb_frontend *fe) return 0; } -static int tda10021_set_parameters (struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +struct qam_params { + u8 conf, agcref, lthr, mseth, aref; +}; + +static int tda10021_set_parameters(struct dvb_frontend *fe) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + u32 delsys = c->delivery_system; + unsigned qam = c->modulation; + bool is_annex_c; + u32 reg0x3d; struct tda10021_state* state = fe->demodulator_priv; + static const struct qam_params qam_params[] = { + /* Modulation Conf AGCref LTHR MSETH AREF */ + [QPSK] = { 0x14, 0x78, 0x78, 0x8c, 0x96 }, + [QAM_16] = { 0x00, 0x8c, 0x87, 0xa2, 0x91 }, + [QAM_32] = { 0x04, 0x8c, 0x64, 0x74, 0x96 }, + [QAM_64] = { 0x08, 0x6a, 0x46, 0x43, 0x6a }, + [QAM_128] = { 0x0c, 0x78, 0x36, 0x34, 0x7e }, + [QAM_256] = { 0x10, 0x5c, 0x26, 0x23, 0x6b }, + }; + + switch (delsys) { + case SYS_DVBC_ANNEX_A: + is_annex_c = false; + break; + case SYS_DVBC_ANNEX_C: + is_annex_c = true; + break; + default: + return -EINVAL; + } - //table for QAM4-QAM256 ready QAM4 QAM16 QAM32 QAM64 QAM128 QAM256 - //CONF - static const u8 reg0x00 [] = { 0x14, 0x00, 0x04, 0x08, 0x0c, 0x10 }; - //AGCREF value - static const u8 reg0x01 [] = { 0x78, 0x8c, 0x8c, 0x6a, 0x78, 0x5c }; - //LTHR value - static const u8 reg0x05 [] = { 0x78, 0x87, 0x64, 0x46, 0x36, 0x26 }; - //MSETH - static const u8 reg0x08 [] = { 0x8c, 0xa2, 0x74, 0x43, 0x34, 0x23 }; - //AREF - static const u8 reg0x09 [] = { 0x96, 0x91, 0x96, 0x6a, 0x7e, 0x6b }; - - int qam = p->u.qam.modulation; - - if (qam < 0 || qam > 5) + /* + * gcc optimizes the code bellow the same way as it would code: + * "if (qam > 5) return -EINVAL;" + * Yet, the code is clearer, as it shows what QAM standards are + * supported by the driver, and avoids the usage of magic numbers on + * it. + */ + switch (qam) { + case QPSK: + case QAM_16: + case QAM_32: + case QAM_64: + case QAM_128: + case QAM_256: + break; + default: return -EINVAL; + } - if (p->inversion != INVERSION_ON && p->inversion != INVERSION_OFF) + if (c->inversion != INVERSION_ON && c->inversion != INVERSION_OFF) return -EINVAL; - //printk("tda10021: set frequency to %d qam=%d symrate=%d\n", p->frequency,qam,p->u.qam.symbol_rate); + /*printk("tda10021: set frequency to %d qam=%d symrate=%d\n", p->frequency,qam,p->symbol_rate);*/ if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); + fe->ops.tuner_ops.set_params(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); } - tda10021_set_symbolrate (state, p->u.qam.symbol_rate); - _tda10021_writereg (state, 0x34, state->pwm); - - _tda10021_writereg (state, 0x01, reg0x01[qam]); - _tda10021_writereg (state, 0x05, reg0x05[qam]); - _tda10021_writereg (state, 0x08, reg0x08[qam]); - _tda10021_writereg (state, 0x09, reg0x09[qam]); - - tda10021_setup_reg0 (state, reg0x00[qam], p->inversion); + tda10021_set_symbolrate(state, c->symbol_rate); + _tda10021_writereg(state, 0x34, state->pwm); + + _tda10021_writereg(state, 0x01, qam_params[qam].agcref); + _tda10021_writereg(state, 0x05, qam_params[qam].lthr); + _tda10021_writereg(state, 0x08, qam_params[qam].mseth); + _tda10021_writereg(state, 0x09, qam_params[qam].aref); + + /* + * Bit 0 == 0 means roll-off = 0.15 (Annex A) + * == 1 means roll-off = 0.13 (Annex C) + */ + reg0x3d = tda10021_readreg (state, 0x3d); + if (is_annex_c) + _tda10021_writereg (state, 0x3d, 0x01 | reg0x3d); + else + _tda10021_writereg (state, 0x3d, 0xfe & reg0x3d); + tda10021_setup_reg0(state, qam_params[qam].conf, c->inversion); return 0; } @@ -347,8 +386,9 @@ static int tda10021_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) return 0; } -static int tda10021_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) +static int tda10021_get_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct tda10021_state* state = fe->demodulator_priv; int sync; s8 afc = 0; @@ -360,17 +400,17 @@ static int tda10021_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_pa printk(sync & 2 ? "DVB: TDA10021(%d): AFC (%d) %dHz\n" : "DVB: TDA10021(%d): [AFC (%d) %dHz]\n", state->frontend.dvb->num, afc, - -((s32)p->u.qam.symbol_rate * afc) >> 10); + -((s32)p->symbol_rate * afc) >> 10); } p->inversion = ((state->reg0 & 0x20) == 0x20) ^ (state->config->invert != 0) ? INVERSION_ON : INVERSION_OFF; - p->u.qam.modulation = ((state->reg0 >> 2) & 7) + QAM_16; + p->modulation = ((state->reg0 >> 2) & 7) + QAM_16; - p->u.qam.fec_inner = FEC_NONE; + p->fec_inner = FEC_NONE; p->frequency = ((p->frequency + 31250) / 62500) * 62500; if (sync & 2) - p->frequency -= ((s32)p->u.qam.symbol_rate * afc) >> 10; + p->frequency -= ((s32)p->symbol_rate * afc) >> 10; return 0; } @@ -444,10 +484,9 @@ error: } static struct dvb_frontend_ops tda10021_ops = { - + .delsys = { SYS_DVBC_ANNEX_A, SYS_DVBC_ANNEX_C }, .info = { .name = "Philips TDA10021 DVB-C", - .type = FE_QAM, .frequency_stepsize = 62500, .frequency_min = 47000000, .frequency_max = 862000000, diff --git a/drivers/media/dvb/frontends/tda10023.c b/drivers/media/dvb/frontends/tda10023.c index a3c34eecdee9..ca1e0d54b69a 100644 --- a/drivers/media/dvb/frontends/tda10023.c +++ b/drivers/media/dvb/frontends/tda10023.c @@ -298,42 +298,80 @@ static int tda10023_init (struct dvb_frontend *fe) return 0; } -static int tda10023_set_parameters (struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +struct qam_params { + u8 qam, lockthr, mseth, aref, agcrefnyq, eragnyq_thd; +}; + +static int tda10023_set_parameters(struct dvb_frontend *fe) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + u32 delsys = c->delivery_system; + unsigned qam = c->modulation; + bool is_annex_c; struct tda10023_state* state = fe->demodulator_priv; - - static int qamvals[6][6] = { - // QAM LOCKTHR MSETH AREF AGCREFNYQ ERAGCNYQ_THD - { (5<<2), 0x78, 0x8c, 0x96, 0x78, 0x4c }, // 4 QAM - { (0<<2), 0x87, 0xa2, 0x91, 0x8c, 0x57 }, // 16 QAM - { (1<<2), 0x64, 0x74, 0x96, 0x8c, 0x57 }, // 32 QAM - { (2<<2), 0x46, 0x43, 0x6a, 0x6a, 0x44 }, // 64 QAM - { (3<<2), 0x36, 0x34, 0x7e, 0x78, 0x4c }, // 128 QAM - { (4<<2), 0x26, 0x23, 0x6c, 0x5c, 0x3c }, // 256 QAM + static const struct qam_params qam_params[] = { + /* Modulation QAM LOCKTHR MSETH AREF AGCREFNYQ ERAGCNYQ_THD */ + [QPSK] = { (5<<2), 0x78, 0x8c, 0x96, 0x78, 0x4c }, + [QAM_16] = { (0<<2), 0x87, 0xa2, 0x91, 0x8c, 0x57 }, + [QAM_32] = { (1<<2), 0x64, 0x74, 0x96, 0x8c, 0x57 }, + [QAM_64] = { (2<<2), 0x46, 0x43, 0x6a, 0x6a, 0x44 }, + [QAM_128] = { (3<<2), 0x36, 0x34, 0x7e, 0x78, 0x4c }, + [QAM_256] = { (4<<2), 0x26, 0x23, 0x6c, 0x5c, 0x3c }, }; - int qam = p->u.qam.modulation; + switch (delsys) { + case SYS_DVBC_ANNEX_A: + is_annex_c = false; + break; + case SYS_DVBC_ANNEX_C: + is_annex_c = true; + break; + default: + return -EINVAL; + } - if (qam < 0 || qam > 5) + /* + * gcc optimizes the code bellow the same way as it would code: + * "if (qam > 5) return -EINVAL;" + * Yet, the code is clearer, as it shows what QAM standards are + * supported by the driver, and avoids the usage of magic numbers on + * it. + */ + switch (qam) { + case QPSK: + case QAM_16: + case QAM_32: + case QAM_64: + case QAM_128: + case QAM_256: + break; + default: return -EINVAL; + } if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); + fe->ops.tuner_ops.set_params(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); } - tda10023_set_symbolrate (state, p->u.qam.symbol_rate); - tda10023_writereg (state, 0x05, qamvals[qam][1]); - tda10023_writereg (state, 0x08, qamvals[qam][2]); - tda10023_writereg (state, 0x09, qamvals[qam][3]); - tda10023_writereg (state, 0xb4, qamvals[qam][4]); - tda10023_writereg (state, 0xb6, qamvals[qam][5]); - -// tda10023_writereg (state, 0x04, (p->inversion?0x12:0x32)); -// tda10023_writebit (state, 0x04, 0x60, (p->inversion?0:0x20)); - tda10023_writebit (state, 0x04, 0x40, 0x40); - tda10023_setup_reg0 (state, qamvals[qam][0]); + tda10023_set_symbolrate(state, c->symbol_rate); + tda10023_writereg(state, 0x05, qam_params[qam].lockthr); + tda10023_writereg(state, 0x08, qam_params[qam].mseth); + tda10023_writereg(state, 0x09, qam_params[qam].aref); + tda10023_writereg(state, 0xb4, qam_params[qam].agcrefnyq); + tda10023_writereg(state, 0xb6, qam_params[qam].eragnyq_thd); +#if 0 + tda10023_writereg(state, 0x04, (c->inversion ? 0x12 : 0x32)); + tda10023_writebit(state, 0x04, 0x60, (c->inversion ? 0 : 0x20)); +#endif + tda10023_writebit(state, 0x04, 0x40, 0x40); + + if (is_annex_c) + tda10023_writebit(state, 0x3d, 0xfc, 0x03); + else + tda10023_writebit(state, 0x3d, 0xfc, 0x02); + + tda10023_setup_reg0(state, qam_params[qam].qam); return 0; } @@ -418,8 +456,9 @@ static int tda10023_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) return 0; } -static int tda10023_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) +static int tda10023_get_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct tda10023_state* state = fe->demodulator_priv; int sync,inv; s8 afc = 0; @@ -433,17 +472,17 @@ static int tda10023_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_pa printk(sync & 2 ? "DVB: TDA10023(%d): AFC (%d) %dHz\n" : "DVB: TDA10023(%d): [AFC (%d) %dHz]\n", state->frontend.dvb->num, afc, - -((s32)p->u.qam.symbol_rate * afc) >> 10); + -((s32)p->symbol_rate * afc) >> 10); } p->inversion = (inv&0x20?0:1); - p->u.qam.modulation = ((state->reg0 >> 2) & 7) + QAM_16; + p->modulation = ((state->reg0 >> 2) & 7) + QAM_16; - p->u.qam.fec_inner = FEC_NONE; + p->fec_inner = FEC_NONE; p->frequency = ((p->frequency + 31250) / 62500) * 62500; if (sync & 2) - p->frequency -= ((s32)p->u.qam.symbol_rate * afc) >> 10; + p->frequency -= ((s32)p->symbol_rate * afc) >> 10; return 0; } @@ -534,10 +573,9 @@ error: } static struct dvb_frontend_ops tda10023_ops = { - + .delsys = { SYS_DVBC_ANNEX_A, SYS_DVBC_ANNEX_C }, .info = { .name = "Philips TDA10023 DVB-C", - .type = FE_QAM, .frequency_stepsize = 62500, .frequency_min = 47000000, .frequency_max = 862000000, @@ -557,7 +595,6 @@ static struct dvb_frontend_ops tda10023_ops = { .set_frontend = tda10023_set_parameters, .get_frontend = tda10023_get_frontend, - .read_status = tda10023_read_status, .read_ber = tda10023_read_ber, .read_signal_strength = tda10023_read_signal_strength, diff --git a/drivers/media/dvb/frontends/tda10048.c b/drivers/media/dvb/frontends/tda10048.c index 7f105946a434..71fb63299de7 100644 --- a/drivers/media/dvb/frontends/tda10048.c +++ b/drivers/media/dvb/frontends/tda10048.c @@ -153,7 +153,7 @@ struct tda10048_state { u32 pll_pfactor; u32 sample_freq; - enum fe_bandwidth bandwidth; + u32 bandwidth; }; static struct init_tab { @@ -341,21 +341,14 @@ static int tda10048_set_wref(struct dvb_frontend *fe, u32 sample_freq_hz, { struct tda10048_state *state = fe->demodulator_priv; u64 t, z; - u32 b = 8000000; dprintk(1, "%s()\n", __func__); if (sample_freq_hz == 0) return -EINVAL; - if (bw == BANDWIDTH_6_MHZ) - b = 6000000; - else - if (bw == BANDWIDTH_7_MHZ) - b = 7000000; - /* WREF = (B / (7 * fs)) * 2^31 */ - t = b * 10; + t = bw * 10; /* avoid warning: this decimal constant is unsigned only in ISO C90 */ /* t *= 2147483648 on 32bit platforms */ t *= (2048 * 1024); @@ -378,25 +371,18 @@ static int tda10048_set_invwref(struct dvb_frontend *fe, u32 sample_freq_hz, { struct tda10048_state *state = fe->demodulator_priv; u64 t; - u32 b = 8000000; dprintk(1, "%s()\n", __func__); if (sample_freq_hz == 0) return -EINVAL; - if (bw == BANDWIDTH_6_MHZ) - b = 6000000; - else - if (bw == BANDWIDTH_7_MHZ) - b = 7000000; - /* INVWREF = ((7 * fs) / B) * 2^5 */ t = sample_freq_hz; t *= 7; t *= 32; t *= 10; - do_div(t, b); + do_div(t, bw); t += 5; do_div(t, 10); @@ -407,16 +393,16 @@ static int tda10048_set_invwref(struct dvb_frontend *fe, u32 sample_freq_hz, } static int tda10048_set_bandwidth(struct dvb_frontend *fe, - enum fe_bandwidth bw) + u32 bw) { struct tda10048_state *state = fe->demodulator_priv; dprintk(1, "%s(bw=%d)\n", __func__, bw); /* Bandwidth setting may need to be adjusted */ switch (bw) { - case BANDWIDTH_6_MHZ: - case BANDWIDTH_7_MHZ: - case BANDWIDTH_8_MHZ: + case 6000000: + case 7000000: + case 8000000: tda10048_set_wref(fe, state->sample_freq, bw); tda10048_set_invwref(fe, state->sample_freq, bw); break; @@ -430,7 +416,7 @@ static int tda10048_set_bandwidth(struct dvb_frontend *fe, return 0; } -static int tda10048_set_if(struct dvb_frontend *fe, enum fe_bandwidth bw) +static int tda10048_set_if(struct dvb_frontend *fe, u32 bw) { struct tda10048_state *state = fe->demodulator_priv; struct tda10048_config *config = &state->config; @@ -441,13 +427,13 @@ static int tda10048_set_if(struct dvb_frontend *fe, enum fe_bandwidth bw) /* based on target bandwidth and clk we calculate pll factors */ switch (bw) { - case BANDWIDTH_6_MHZ: + case 6000000: if_freq_khz = config->dtv6_if_freq_khz; break; - case BANDWIDTH_7_MHZ: + case 7000000: if_freq_khz = config->dtv7_if_freq_khz; break; - case BANDWIDTH_8_MHZ: + case 8000000: if_freq_khz = config->dtv8_if_freq_khz; break; default: @@ -601,7 +587,7 @@ static int tda10048_set_inversion(struct dvb_frontend *fe, int inversion) /* Retrieve the demod settings */ static int tda10048_get_tps(struct tda10048_state *state, - struct dvb_ofdm_parameters *p) + struct dtv_frontend_properties *p) { u8 val; @@ -612,27 +598,27 @@ static int tda10048_get_tps(struct tda10048_state *state, val = tda10048_readreg(state, TDA10048_OUT_CONF2); switch ((val & 0x60) >> 5) { case 0: - p->constellation = QPSK; + p->modulation = QPSK; break; case 1: - p->constellation = QAM_16; + p->modulation = QAM_16; break; case 2: - p->constellation = QAM_64; + p->modulation = QAM_64; break; } switch ((val & 0x18) >> 3) { case 0: - p->hierarchy_information = HIERARCHY_NONE; + p->hierarchy = HIERARCHY_NONE; break; case 1: - p->hierarchy_information = HIERARCHY_1; + p->hierarchy = HIERARCHY_1; break; case 2: - p->hierarchy_information = HIERARCHY_2; + p->hierarchy = HIERARCHY_2; break; case 3: - p->hierarchy_information = HIERARCHY_4; + p->hierarchy = HIERARCHY_4; break; } switch (val & 0x07) { @@ -738,17 +724,17 @@ static int tda10048_output_mode(struct dvb_frontend *fe, int serial) /* Talk to the demod, set the FEC, GUARD, QAM settings etc */ /* TODO: Support manual tuning with specific params */ -static int tda10048_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int tda10048_set_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct tda10048_state *state = fe->demodulator_priv; dprintk(1, "%s(frequency=%d)\n", __func__, p->frequency); /* Update the I/F pll's if the bandwidth changes */ - if (p->u.ofdm.bandwidth != state->bandwidth) { - tda10048_set_if(fe, p->u.ofdm.bandwidth); - tda10048_set_bandwidth(fe, p->u.ofdm.bandwidth); + if (p->bandwidth_hz != state->bandwidth) { + tda10048_set_if(fe, p->bandwidth_hz); + tda10048_set_bandwidth(fe, p->bandwidth_hz); } if (fe->ops.tuner_ops.set_params) { @@ -756,7 +742,7 @@ static int tda10048_set_frontend(struct dvb_frontend *fe, if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); - fe->ops.tuner_ops.set_params(fe, p); + fe->ops.tuner_ops.set_params(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); @@ -797,8 +783,8 @@ static int tda10048_init(struct dvb_frontend *fe) tda10048_set_inversion(fe, config->inversion); /* Establish default RF values */ - tda10048_set_if(fe, BANDWIDTH_8_MHZ); - tda10048_set_bandwidth(fe, BANDWIDTH_8_MHZ); + tda10048_set_if(fe, 8000000); + tda10048_set_bandwidth(fe, 8000000); /* Ensure we leave the gate closed */ tda10048_i2c_gate_ctrl(fe, 0); @@ -1042,9 +1028,9 @@ static int tda10048_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) return 0; } -static int tda10048_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int tda10048_get_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct tda10048_state *state = fe->demodulator_priv; dprintk(1, "%s()\n", __func__); @@ -1052,7 +1038,7 @@ static int tda10048_get_frontend(struct dvb_frontend *fe, p->inversion = tda10048_readreg(state, TDA10048_CONF_C1_1) & 0x20 ? INVERSION_ON : INVERSION_OFF; - return tda10048_get_tps(state, &p->u.ofdm); + return tda10048_get_tps(state, p); } static int tda10048_get_tune_settings(struct dvb_frontend *fe, @@ -1126,7 +1112,7 @@ struct dvb_frontend *tda10048_attach(const struct tda10048_config *config, memcpy(&state->config, config, sizeof(*config)); state->i2c = i2c; state->fwloaded = config->no_firmware; - state->bandwidth = BANDWIDTH_8_MHZ; + state->bandwidth = 8000000; /* check if the demod is present */ if (tda10048_readreg(state, TDA10048_IDENTITY) != 0x048) @@ -1152,11 +1138,11 @@ struct dvb_frontend *tda10048_attach(const struct tda10048_config *config, tda10048_establish_defaults(&state->frontend); /* Set the xtal and freq defaults */ - if (tda10048_set_if(&state->frontend, BANDWIDTH_8_MHZ) != 0) + if (tda10048_set_if(&state->frontend, 8000000) != 0) goto error; /* Default bandwidth */ - if (tda10048_set_bandwidth(&state->frontend, BANDWIDTH_8_MHZ) != 0) + if (tda10048_set_bandwidth(&state->frontend, 8000000) != 0) goto error; /* Leave the gate closed */ @@ -1171,10 +1157,9 @@ error: EXPORT_SYMBOL(tda10048_attach); static struct dvb_frontend_ops tda10048_ops = { - + .delsys = { SYS_DVBT }, .info = { .name = "NXP TDA10048HN DVB-T", - .type = FE_OFDM, .frequency_min = 177000000, .frequency_max = 858000000, .frequency_stepsize = 166666, diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c index ea485d923550..ae6f22aae677 100644 --- a/drivers/media/dvb/frontends/tda1004x.c +++ b/drivers/media/dvb/frontends/tda1004x.c @@ -224,22 +224,22 @@ static int tda1004x_disable_tuner_i2c(struct tda1004x_state *state) } static int tda10045h_set_bandwidth(struct tda1004x_state *state, - fe_bandwidth_t bandwidth) + u32 bandwidth) { static u8 bandwidth_6mhz[] = { 0x02, 0x00, 0x3d, 0x00, 0x60, 0x1e, 0xa7, 0x45, 0x4f }; static u8 bandwidth_7mhz[] = { 0x02, 0x00, 0x37, 0x00, 0x4a, 0x2f, 0x6d, 0x76, 0xdb }; static u8 bandwidth_8mhz[] = { 0x02, 0x00, 0x3d, 0x00, 0x48, 0x17, 0x89, 0xc7, 0x14 }; switch (bandwidth) { - case BANDWIDTH_6_MHZ: + case 6000000: tda1004x_write_buf(state, TDA10045H_CONFPLL_P, bandwidth_6mhz, sizeof(bandwidth_6mhz)); break; - case BANDWIDTH_7_MHZ: + case 7000000: tda1004x_write_buf(state, TDA10045H_CONFPLL_P, bandwidth_7mhz, sizeof(bandwidth_7mhz)); break; - case BANDWIDTH_8_MHZ: + case 8000000: tda1004x_write_buf(state, TDA10045H_CONFPLL_P, bandwidth_8mhz, sizeof(bandwidth_8mhz)); break; @@ -253,7 +253,7 @@ static int tda10045h_set_bandwidth(struct tda1004x_state *state, } static int tda10046h_set_bandwidth(struct tda1004x_state *state, - fe_bandwidth_t bandwidth) + u32 bandwidth) { static u8 bandwidth_6mhz_53M[] = { 0x7b, 0x2e, 0x11, 0xf0, 0xd2 }; static u8 bandwidth_7mhz_53M[] = { 0x6a, 0x02, 0x6a, 0x43, 0x9f }; @@ -270,7 +270,7 @@ static int tda10046h_set_bandwidth(struct tda1004x_state *state, else tda10046_clk53m = 1; switch (bandwidth) { - case BANDWIDTH_6_MHZ: + case 6000000: if (tda10046_clk53m) tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_6mhz_53M, sizeof(bandwidth_6mhz_53M)); @@ -283,7 +283,7 @@ static int tda10046h_set_bandwidth(struct tda1004x_state *state, } break; - case BANDWIDTH_7_MHZ: + case 7000000: if (tda10046_clk53m) tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_7mhz_53M, sizeof(bandwidth_7mhz_53M)); @@ -296,7 +296,7 @@ static int tda10046h_set_bandwidth(struct tda1004x_state *state, } break; - case BANDWIDTH_8_MHZ: + case 8000000: if (tda10046_clk53m) tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_8mhz_53M, sizeof(bandwidth_8mhz_53M)); @@ -409,7 +409,7 @@ static int tda10045_fwupload(struct dvb_frontend* fe) msleep(10); /* set parameters */ - tda10045h_set_bandwidth(state, BANDWIDTH_8_MHZ); + tda10045h_set_bandwidth(state, 8000000); ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10045H_FWPAGE, TDA10045H_CODE_IN); release_firmware(fw); @@ -473,7 +473,7 @@ static void tda10046_init_plls(struct dvb_frontend* fe) tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x3f); break; } - tda10046h_set_bandwidth(state, BANDWIDTH_8_MHZ); // default bandwidth 8 MHz + tda10046h_set_bandwidth(state, 8000000); /* default bandwidth 8 MHz */ /* let the PLLs settle */ msleep(120); } @@ -697,9 +697,9 @@ static int tda10046_init(struct dvb_frontend* fe) return 0; } -static int tda1004x_set_fe(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fe_params) +static int tda1004x_set_fe(struct dvb_frontend *fe) { + struct dtv_frontend_properties *fe_params = &fe->dtv_property_cache; struct tda1004x_state* state = fe->demodulator_priv; int tmp; int inversion; @@ -718,7 +718,7 @@ static int tda1004x_set_fe(struct dvb_frontend* fe, // set frequency if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, fe_params); + fe->ops.tuner_ops.set_params(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); } @@ -726,37 +726,37 @@ static int tda1004x_set_fe(struct dvb_frontend* fe, // Hardcoded to use auto as much as possible on the TDA10045 as it // is very unreliable if AUTO mode is _not_ used. if (state->demod_type == TDA1004X_DEMOD_TDA10045) { - fe_params->u.ofdm.code_rate_HP = FEC_AUTO; - fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_AUTO; - fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO; + fe_params->code_rate_HP = FEC_AUTO; + fe_params->guard_interval = GUARD_INTERVAL_AUTO; + fe_params->transmission_mode = TRANSMISSION_MODE_AUTO; } // Set standard params.. or put them to auto - if ((fe_params->u.ofdm.code_rate_HP == FEC_AUTO) || - (fe_params->u.ofdm.code_rate_LP == FEC_AUTO) || - (fe_params->u.ofdm.constellation == QAM_AUTO) || - (fe_params->u.ofdm.hierarchy_information == HIERARCHY_AUTO)) { + if ((fe_params->code_rate_HP == FEC_AUTO) || + (fe_params->code_rate_LP == FEC_AUTO) || + (fe_params->modulation == QAM_AUTO) || + (fe_params->hierarchy == HIERARCHY_AUTO)) { tda1004x_write_mask(state, TDA1004X_AUTO, 1, 1); // enable auto - tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x03, 0); // turn off constellation bits + tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x03, 0); /* turn off modulation bits */ tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 0); // turn off hierarchy bits tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0x3f, 0); // turn off FEC bits } else { tda1004x_write_mask(state, TDA1004X_AUTO, 1, 0); // disable auto // set HP FEC - tmp = tda1004x_encode_fec(fe_params->u.ofdm.code_rate_HP); + tmp = tda1004x_encode_fec(fe_params->code_rate_HP); if (tmp < 0) return tmp; tda1004x_write_mask(state, TDA1004X_IN_CONF2, 7, tmp); // set LP FEC - tmp = tda1004x_encode_fec(fe_params->u.ofdm.code_rate_LP); + tmp = tda1004x_encode_fec(fe_params->code_rate_LP); if (tmp < 0) return tmp; tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0x38, tmp << 3); - // set constellation - switch (fe_params->u.ofdm.constellation) { + /* set modulation */ + switch (fe_params->modulation) { case QPSK: tda1004x_write_mask(state, TDA1004X_IN_CONF1, 3, 0); break; @@ -774,7 +774,7 @@ static int tda1004x_set_fe(struct dvb_frontend* fe, } // set hierarchy - switch (fe_params->u.ofdm.hierarchy_information) { + switch (fe_params->hierarchy) { case HIERARCHY_NONE: tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 0 << 5); break; @@ -799,11 +799,11 @@ static int tda1004x_set_fe(struct dvb_frontend* fe, // set bandwidth switch (state->demod_type) { case TDA1004X_DEMOD_TDA10045: - tda10045h_set_bandwidth(state, fe_params->u.ofdm.bandwidth); + tda10045h_set_bandwidth(state, fe_params->bandwidth_hz); break; case TDA1004X_DEMOD_TDA10046: - tda10046h_set_bandwidth(state, fe_params->u.ofdm.bandwidth); + tda10046h_set_bandwidth(state, fe_params->bandwidth_hz); break; } @@ -825,7 +825,7 @@ static int tda1004x_set_fe(struct dvb_frontend* fe, } // set guard interval - switch (fe_params->u.ofdm.guard_interval) { + switch (fe_params->guard_interval) { case GUARD_INTERVAL_1_32: tda1004x_write_mask(state, TDA1004X_AUTO, 2, 0); tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 0 << 2); @@ -856,7 +856,7 @@ static int tda1004x_set_fe(struct dvb_frontend* fe, } // set transmission mode - switch (fe_params->u.ofdm.transmission_mode) { + switch (fe_params->transmission_mode) { case TRANSMISSION_MODE_2K: tda1004x_write_mask(state, TDA1004X_AUTO, 4, 0); tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x10, 0 << 4); @@ -895,8 +895,9 @@ static int tda1004x_set_fe(struct dvb_frontend* fe, return 0; } -static int tda1004x_get_fe(struct dvb_frontend* fe, struct dvb_frontend_parameters *fe_params) +static int tda1004x_get_fe(struct dvb_frontend *fe) { + struct dtv_frontend_properties *fe_params = &fe->dtv_property_cache; struct tda1004x_state* state = fe->demodulator_priv; dprintk("%s\n", __func__); @@ -913,13 +914,13 @@ static int tda1004x_get_fe(struct dvb_frontend* fe, struct dvb_frontend_paramete case TDA1004X_DEMOD_TDA10045: switch (tda1004x_read_byte(state, TDA10045H_WREF_LSB)) { case 0x14: - fe_params->u.ofdm.bandwidth = BANDWIDTH_8_MHZ; + fe_params->bandwidth_hz = 8000000; break; case 0xdb: - fe_params->u.ofdm.bandwidth = BANDWIDTH_7_MHZ; + fe_params->bandwidth_hz = 7000000; break; case 0x4f: - fe_params->u.ofdm.bandwidth = BANDWIDTH_6_MHZ; + fe_params->bandwidth_hz = 6000000; break; } break; @@ -927,73 +928,73 @@ static int tda1004x_get_fe(struct dvb_frontend* fe, struct dvb_frontend_paramete switch (tda1004x_read_byte(state, TDA10046H_TIME_WREF1)) { case 0x5c: case 0x54: - fe_params->u.ofdm.bandwidth = BANDWIDTH_8_MHZ; + fe_params->bandwidth_hz = 8000000; break; case 0x6a: case 0x60: - fe_params->u.ofdm.bandwidth = BANDWIDTH_7_MHZ; + fe_params->bandwidth_hz = 7000000; break; case 0x7b: case 0x70: - fe_params->u.ofdm.bandwidth = BANDWIDTH_6_MHZ; + fe_params->bandwidth_hz = 6000000; break; } break; } // FEC - fe_params->u.ofdm.code_rate_HP = + fe_params->code_rate_HP = tda1004x_decode_fec(tda1004x_read_byte(state, TDA1004X_OUT_CONF2) & 7); - fe_params->u.ofdm.code_rate_LP = + fe_params->code_rate_LP = tda1004x_decode_fec((tda1004x_read_byte(state, TDA1004X_OUT_CONF2) >> 3) & 7); - // constellation + /* modulation */ switch (tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 3) { case 0: - fe_params->u.ofdm.constellation = QPSK; + fe_params->modulation = QPSK; break; case 1: - fe_params->u.ofdm.constellation = QAM_16; + fe_params->modulation = QAM_16; break; case 2: - fe_params->u.ofdm.constellation = QAM_64; + fe_params->modulation = QAM_64; break; } // transmission mode - fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; + fe_params->transmission_mode = TRANSMISSION_MODE_2K; if (tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x10) - fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; + fe_params->transmission_mode = TRANSMISSION_MODE_8K; // guard interval switch ((tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x0c) >> 2) { case 0: - fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; + fe_params->guard_interval = GUARD_INTERVAL_1_32; break; case 1: - fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; + fe_params->guard_interval = GUARD_INTERVAL_1_16; break; case 2: - fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; + fe_params->guard_interval = GUARD_INTERVAL_1_8; break; case 3: - fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; + fe_params->guard_interval = GUARD_INTERVAL_1_4; break; } // hierarchy switch ((tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x60) >> 5) { case 0: - fe_params->u.ofdm.hierarchy_information = HIERARCHY_NONE; + fe_params->hierarchy = HIERARCHY_NONE; break; case 1: - fe_params->u.ofdm.hierarchy_information = HIERARCHY_1; + fe_params->hierarchy = HIERARCHY_1; break; case 2: - fe_params->u.ofdm.hierarchy_information = HIERARCHY_2; + fe_params->hierarchy = HIERARCHY_2; break; case 3: - fe_params->u.ofdm.hierarchy_information = HIERARCHY_4; + fe_params->hierarchy = HIERARCHY_4; break; } @@ -1231,9 +1232,9 @@ static void tda1004x_release(struct dvb_frontend* fe) } static struct dvb_frontend_ops tda10045_ops = { + .delsys = { SYS_DVBT }, .info = { .name = "Philips TDA10045H DVB-T", - .type = FE_OFDM, .frequency_min = 51000000, .frequency_max = 858000000, .frequency_stepsize = 166667, @@ -1301,9 +1302,9 @@ struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, } static struct dvb_frontend_ops tda10046_ops = { + .delsys = { SYS_DVBT }, .info = { .name = "Philips TDA10046H DVB-T", - .type = FE_OFDM, .frequency_min = 51000000, .frequency_max = 858000000, .frequency_stepsize = 166667, diff --git a/drivers/media/dvb/frontends/tda10071.c b/drivers/media/dvb/frontends/tda10071.c index 0c37434d19e2..a99205026751 100644 --- a/drivers/media/dvb/frontends/tda10071.c +++ b/drivers/media/dvb/frontends/tda10071.c @@ -636,8 +636,7 @@ error: return ret; } -static int tda10071_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) +static int tda10071_set_frontend(struct dvb_frontend *fe) { struct tda10071_priv *priv = fe->demodulator_priv; struct tda10071_cmd cmd; @@ -777,8 +776,7 @@ error: return ret; } -static int tda10071_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int tda10071_get_frontend(struct dvb_frontend *fe) { struct tda10071_priv *priv = fe->demodulator_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache; @@ -1217,9 +1215,9 @@ error: EXPORT_SYMBOL(tda10071_attach); static struct dvb_frontend_ops tda10071_ops = { + .delsys = { SYS_DVBT, SYS_DVBT2 }, .info = { .name = "NXP TDA10071", - .type = FE_QPSK, .frequency_min = 950000, .frequency_max = 2150000, .frequency_tolerance = 5000, diff --git a/drivers/media/dvb/frontends/tda10086.c b/drivers/media/dvb/frontends/tda10086.c index f2c8faac6f36..fcfe2e080cb0 100644 --- a/drivers/media/dvb/frontends/tda10086.c +++ b/drivers/media/dvb/frontends/tda10086.c @@ -267,7 +267,7 @@ static int tda10086_send_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t minic } static int tda10086_set_inversion(struct tda10086_state *state, - struct dvb_frontend_parameters *fe_params) + struct dtv_frontend_properties *fe_params) { u8 invval = 0x80; @@ -292,7 +292,7 @@ static int tda10086_set_inversion(struct tda10086_state *state, } static int tda10086_set_symbol_rate(struct tda10086_state *state, - struct dvb_frontend_parameters *fe_params) + struct dtv_frontend_properties *fe_params) { u8 dfn = 0; u8 afs = 0; @@ -303,7 +303,7 @@ static int tda10086_set_symbol_rate(struct tda10086_state *state, u32 tmp; u32 bdr; u32 bdri; - u32 symbol_rate = fe_params->u.qpsk.symbol_rate; + u32 symbol_rate = fe_params->symbol_rate; dprintk ("%s %i\n", __func__, symbol_rate); @@ -367,13 +367,13 @@ static int tda10086_set_symbol_rate(struct tda10086_state *state, } static int tda10086_set_fec(struct tda10086_state *state, - struct dvb_frontend_parameters *fe_params) + struct dtv_frontend_properties *fe_params) { u8 fecval; - dprintk ("%s %i\n", __func__, fe_params->u.qpsk.fec_inner); + dprintk("%s %i\n", __func__, fe_params->fec_inner); - switch(fe_params->u.qpsk.fec_inner) { + switch (fe_params->fec_inner) { case FEC_1_2: fecval = 0x00; break; @@ -409,9 +409,9 @@ static int tda10086_set_fec(struct tda10086_state *state, return 0; } -static int tda10086_set_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fe_params) +static int tda10086_set_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *fe_params = &fe->dtv_property_cache; struct tda10086_state *state = fe->demodulator_priv; int ret; u32 freq = 0; @@ -425,7 +425,7 @@ static int tda10086_set_frontend(struct dvb_frontend* fe, /* set params */ if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, fe_params); + fe->ops.tuner_ops.set_params(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); @@ -452,13 +452,14 @@ static int tda10086_set_frontend(struct dvb_frontend* fe, tda10086_write_mask(state, 0x10, 0x40, 0x40); tda10086_write_mask(state, 0x00, 0x01, 0x00); - state->symbol_rate = fe_params->u.qpsk.symbol_rate; + state->symbol_rate = fe_params->symbol_rate; state->frequency = fe_params->frequency; return 0; } -static int tda10086_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *fe_params) +static int tda10086_get_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *fe_params = &fe->dtv_property_cache; struct tda10086_state* state = fe->demodulator_priv; u8 val; int tmp; @@ -467,7 +468,7 @@ static int tda10086_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_pa dprintk ("%s\n", __func__); /* check for invalid symbol rate */ - if (fe_params->u.qpsk.symbol_rate < 500000) + if (fe_params->symbol_rate < 500000) return -EINVAL; /* calculate the updated frequency (note: we convert from Hz->kHz) */ @@ -516,34 +517,34 @@ static int tda10086_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_pa tmp |= 0xffffff00; tmp = (tmp * 480 * (1<<1)) / 128; tmp = ((state->symbol_rate/1000) * tmp) / (1000000/1000); - fe_params->u.qpsk.symbol_rate = state->symbol_rate + tmp; + fe_params->symbol_rate = state->symbol_rate + tmp; /* the FEC */ val = (tda10086_read_byte(state, 0x0d) & 0x70) >> 4; switch(val) { case 0x00: - fe_params->u.qpsk.fec_inner = FEC_1_2; + fe_params->fec_inner = FEC_1_2; break; case 0x01: - fe_params->u.qpsk.fec_inner = FEC_2_3; + fe_params->fec_inner = FEC_2_3; break; case 0x02: - fe_params->u.qpsk.fec_inner = FEC_3_4; + fe_params->fec_inner = FEC_3_4; break; case 0x03: - fe_params->u.qpsk.fec_inner = FEC_4_5; + fe_params->fec_inner = FEC_4_5; break; case 0x04: - fe_params->u.qpsk.fec_inner = FEC_5_6; + fe_params->fec_inner = FEC_5_6; break; case 0x05: - fe_params->u.qpsk.fec_inner = FEC_6_7; + fe_params->fec_inner = FEC_6_7; break; case 0x06: - fe_params->u.qpsk.fec_inner = FEC_7_8; + fe_params->fec_inner = FEC_7_8; break; case 0x07: - fe_params->u.qpsk.fec_inner = FEC_8_9; + fe_params->fec_inner = FEC_8_9; break; } @@ -664,29 +665,31 @@ static int tda10086_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) static int tda10086_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) { - if (fesettings->parameters.u.qpsk.symbol_rate > 20000000) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; + + if (p->symbol_rate > 20000000) { fesettings->min_delay_ms = 50; fesettings->step_size = 2000; fesettings->max_drift = 8000; - } else if (fesettings->parameters.u.qpsk.symbol_rate > 12000000) { + } else if (p->symbol_rate > 12000000) { fesettings->min_delay_ms = 100; fesettings->step_size = 1500; fesettings->max_drift = 9000; - } else if (fesettings->parameters.u.qpsk.symbol_rate > 8000000) { + } else if (p->symbol_rate > 8000000) { fesettings->min_delay_ms = 100; fesettings->step_size = 1000; fesettings->max_drift = 8000; - } else if (fesettings->parameters.u.qpsk.symbol_rate > 4000000) { + } else if (p->symbol_rate > 4000000) { fesettings->min_delay_ms = 100; fesettings->step_size = 500; fesettings->max_drift = 7000; - } else if (fesettings->parameters.u.qpsk.symbol_rate > 2000000) { + } else if (p->symbol_rate > 2000000) { fesettings->min_delay_ms = 200; - fesettings->step_size = (fesettings->parameters.u.qpsk.symbol_rate / 8000); + fesettings->step_size = p->symbol_rate / 8000; fesettings->max_drift = 14 * fesettings->step_size; } else { fesettings->min_delay_ms = 200; - fesettings->step_size = (fesettings->parameters.u.qpsk.symbol_rate / 8000); + fesettings->step_size = p->symbol_rate / 8000; fesettings->max_drift = 18 * fesettings->step_size; } @@ -701,10 +704,9 @@ static void tda10086_release(struct dvb_frontend* fe) } static struct dvb_frontend_ops tda10086_ops = { - + .delsys = { SYS_DVBS }, .info = { .name = "Philips TDA10086 DVB-S", - .type = FE_QPSK, .frequency_min = 950000, .frequency_max = 2150000, .frequency_stepsize = 125, /* kHz for QPSK frontends */ diff --git a/drivers/media/dvb/frontends/tda18271c2dd.c b/drivers/media/dvb/frontends/tda18271c2dd.c index 1b1bf200c55c..86da3d816498 100644 --- a/drivers/media/dvb/frontends/tda18271c2dd.c +++ b/drivers/media/dvb/frontends/tda18271c2dd.c @@ -1123,55 +1123,51 @@ static int release(struct dvb_frontend *fe) return 0; } -/* - * As defined on EN 300 429 Annex A and on ITU-T J.83 annex A, the DVB-C - * roll-off factor is 0.15. - * According with the specs, the amount of the needed bandwith is given by: - * Bw = Symbol_rate * (1 + 0.15) - * As such, the maximum symbol rate supported by 6 MHz is - * max_symbol_rate = 6 MHz / 1.15 = 5217391 Bauds - *NOTE: For ITU-T J.83 Annex C, the roll-off factor is 0.13. So: - * max_symbol_rate = 6 MHz / 1.13 = 5309735 Baud - * That means that an adjustment is needed for Japan, - * but, as currently DRX-K is hardcoded to Annex A, let's stick - * with 0.15 roll-off factor. - */ -#define MAX_SYMBOL_RATE_6MHz 5217391 -static int set_params(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) +static int set_params(struct dvb_frontend *fe) { struct tda_state *state = fe->tuner_priv; int status = 0; int Standard; + u32 bw = fe->dtv_property_cache.bandwidth_hz; + u32 delsys = fe->dtv_property_cache.delivery_system; - state->m_Frequency = params->frequency; + state->m_Frequency = fe->dtv_property_cache.frequency; - if (fe->ops.info.type == FE_OFDM) - switch (params->u.ofdm.bandwidth) { - case BANDWIDTH_6_MHZ: + switch (delsys) { + case SYS_DVBT: + case SYS_DVBT2: + switch (bw) { + case 6000000: Standard = HF_DVBT_6MHZ; break; - case BANDWIDTH_7_MHZ: + case 7000000: Standard = HF_DVBT_7MHZ; break; - default: - case BANDWIDTH_8_MHZ: + case 8000000: Standard = HF_DVBT_8MHZ; break; + default: + return -EINVAL; } - else if (fe->ops.info.type == FE_QAM) { - if (params->u.qam.symbol_rate <= MAX_SYMBOL_RATE_6MHz) + case SYS_DVBC_ANNEX_A: + case SYS_DVBC_ANNEX_C: + if (bw <= 6000000) Standard = HF_DVBC_6MHZ; + else if (bw <= 7000000) + Standard = HF_DVBC_7MHZ; else Standard = HF_DVBC_8MHZ; - } else + break; + default: return -EINVAL; + } do { - status = RFTrackingFiltersCorrection(state, params->frequency); + status = RFTrackingFiltersCorrection(state, state->m_Frequency); if (status < 0) break; - status = ChannelConfiguration(state, params->frequency, Standard); + status = ChannelConfiguration(state, state->m_Frequency, + Standard); if (status < 0) break; diff --git a/drivers/media/dvb/frontends/tda8083.c b/drivers/media/dvb/frontends/tda8083.c index 9369f7442f27..15912c96926a 100644 --- a/drivers/media/dvb/frontends/tda8083.c +++ b/drivers/media/dvb/frontends/tda8083.c @@ -315,18 +315,19 @@ static int tda8083_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) return 0; } -static int tda8083_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) +static int tda8083_set_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct tda8083_state* state = fe->demodulator_priv; if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); + fe->ops.tuner_ops.set_params(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); } tda8083_set_inversion (state, p->inversion); - tda8083_set_fec (state, p->u.qpsk.fec_inner); - tda8083_set_symbolrate (state, p->u.qpsk.symbol_rate); + tda8083_set_fec(state, p->fec_inner); + tda8083_set_symbolrate(state, p->symbol_rate); tda8083_writereg (state, 0x00, 0x3c); tda8083_writereg (state, 0x00, 0x04); @@ -334,16 +335,17 @@ static int tda8083_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par return 0; } -static int tda8083_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) +static int tda8083_get_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct tda8083_state* state = fe->demodulator_priv; /* FIXME: get symbolrate & frequency offset...*/ /*p->frequency = ???;*/ p->inversion = (tda8083_readreg (state, 0x0e) & 0x80) ? INVERSION_ON : INVERSION_OFF; - p->u.qpsk.fec_inner = tda8083_get_fec (state); - /*p->u.qpsk.symbol_rate = tda8083_get_symbolrate (state);*/ + p->fec_inner = tda8083_get_fec(state); + /*p->symbol_rate = tda8083_get_symbolrate (state);*/ return 0; } @@ -438,10 +440,9 @@ error: } static struct dvb_frontend_ops tda8083_ops = { - + .delsys = { SYS_DVBS }, .info = { .name = "Philips TDA8083 DVB-S", - .type = FE_QPSK, .frequency_min = 920000, /* TDA8060 */ .frequency_max = 2200000, /* TDA8060 */ .frequency_stepsize = 125, /* kHz for QPSK frontends */ diff --git a/drivers/media/dvb/frontends/tda826x.c b/drivers/media/dvb/frontends/tda826x.c index 06c94800b940..04bbcc24de0a 100644 --- a/drivers/media/dvb/frontends/tda826x.c +++ b/drivers/media/dvb/frontends/tda826x.c @@ -71,8 +71,9 @@ static int tda826x_sleep(struct dvb_frontend *fe) return (ret == 1) ? 0 : ret; } -static int tda826x_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) +static int tda826x_set_params(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct tda826x_priv *priv = fe->tuner_priv; int ret; u32 div; @@ -83,11 +84,11 @@ static int tda826x_set_params(struct dvb_frontend *fe, struct dvb_frontend_param dprintk("%s:\n", __func__); - div = (params->frequency + (1000-1)) / 1000; + div = (p->frequency + (1000-1)) / 1000; /* BW = ((1 + RO) * SR/2 + 5) * 1.3 [SR in MSPS, BW in MHz] */ /* with R0 = 0.35 and some transformations: */ - ksyms = params->u.qpsk.symbol_rate / 1000; + ksyms = p->symbol_rate / 1000; bandwidth = (878 * ksyms + 6500000) / 1000000 + 1; if (bandwidth < 5) bandwidth = 5; diff --git a/drivers/media/dvb/frontends/tdhd1.h b/drivers/media/dvb/frontends/tdhd1.h index 51f170678650..17750985db0c 100644 --- a/drivers/media/dvb/frontends/tdhd1.h +++ b/drivers/media/dvb/frontends/tdhd1.h @@ -40,24 +40,25 @@ static struct tda1004x_config alps_tdhd1_204a_config = { .request_firmware = alps_tdhd1_204_request_firmware }; -static int alps_tdhd1_204a_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) +static int alps_tdhd1_204a_tuner_set_params(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct i2c_adapter *i2c = fe->tuner_priv; u8 data[4]; struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; u32 div; - div = (params->frequency + 36166666) / 166666; + div = (p->frequency + 36166666) / 166666; data[0] = (div >> 8) & 0x7f; data[1] = div & 0xff; data[2] = 0x85; - if (params->frequency >= 174000000 && params->frequency <= 230000000) + if (p->frequency >= 174000000 && p->frequency <= 230000000) data[3] = 0x02; - else if (params->frequency >= 470000000 && params->frequency <= 823000000) + else if (p->frequency >= 470000000 && p->frequency <= 823000000) data[3] = 0x0C; - else if (params->frequency > 823000000 && params->frequency <= 862000000) + else if (p->frequency > 823000000 && p->frequency <= 862000000) data[3] = 0x8C; else return -EINVAL; diff --git a/drivers/media/dvb/frontends/tua6100.c b/drivers/media/dvb/frontends/tua6100.c index bcb95c2ef296..029384d1fddd 100644 --- a/drivers/media/dvb/frontends/tua6100.c +++ b/drivers/media/dvb/frontends/tua6100.c @@ -67,9 +67,9 @@ static int tua6100_sleep(struct dvb_frontend *fe) return (ret == 1) ? 0 : ret; } -static int tua6100_set_params(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) +static int tua6100_set_params(struct dvb_frontend *fe) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct tua6100_priv *priv = fe->tuner_priv; u32 div; u32 prediv; @@ -85,36 +85,37 @@ static int tua6100_set_params(struct dvb_frontend *fe, #define _ri 4000000 // setup register 0 - if (params->frequency < 2000000) { + if (c->frequency < 2000000) reg0[1] = 0x03; - } else { + else reg0[1] = 0x07; - } // setup register 1 - if (params->frequency < 1630000) { + if (c->frequency < 1630000) reg1[1] = 0x2c; - } else { + else reg1[1] = 0x0c; - } + if (_P == 64) reg1[1] |= 0x40; - if (params->frequency >= 1525000) + if (c->frequency >= 1525000) reg1[1] |= 0x80; // register 2 reg2[1] = (_R >> 8) & 0x03; reg2[2] = _R; - if (params->frequency < 1455000) { + if (c->frequency < 1455000) reg2[1] |= 0x1c; - } else if (params->frequency < 1630000) { + else if (c->frequency < 1630000) reg2[1] |= 0x0c; - } else { + else reg2[1] |= 0x1c; - } - // The N divisor ratio (note: params->frequency is in kHz, but we need it in Hz) - prediv = (params->frequency * _R) / (_ri / 1000); + /* + * The N divisor ratio (note: c->frequency is in kHz, but we + * need it in Hz) + */ + prediv = (c->frequency * _R) / (_ri / 1000); div = prediv / _P; reg1[1] |= (div >> 9) & 0x03; reg1[2] = div >> 1; diff --git a/drivers/media/dvb/frontends/ves1820.c b/drivers/media/dvb/frontends/ves1820.c index 550a07a8a997..bb42b563c42d 100644 --- a/drivers/media/dvb/frontends/ves1820.c +++ b/drivers/media/dvb/frontends/ves1820.c @@ -205,25 +205,26 @@ static int ves1820_init(struct dvb_frontend* fe) return 0; } -static int ves1820_set_parameters(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) +static int ves1820_set_parameters(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct ves1820_state* state = fe->demodulator_priv; static const u8 reg0x00[] = { 0x00, 0x04, 0x08, 0x0c, 0x10 }; static const u8 reg0x01[] = { 140, 140, 106, 100, 92 }; static const u8 reg0x05[] = { 135, 100, 70, 54, 38 }; static const u8 reg0x08[] = { 162, 116, 67, 52, 35 }; static const u8 reg0x09[] = { 145, 150, 106, 126, 107 }; - int real_qam = p->u.qam.modulation - QAM_16; + int real_qam = p->modulation - QAM_16; if (real_qam < 0 || real_qam > 4) return -EINVAL; if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); + fe->ops.tuner_ops.set_params(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); } - ves1820_set_symbolrate(state, p->u.qam.symbol_rate); + ves1820_set_symbolrate(state, p->symbol_rate); ves1820_writereg(state, 0x34, state->pwm); ves1820_writereg(state, 0x01, reg0x01[real_qam]); @@ -309,8 +310,9 @@ static int ves1820_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) return 0; } -static int ves1820_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) +static int ves1820_get_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct ves1820_state* state = fe->demodulator_priv; int sync; s8 afc = 0; @@ -320,7 +322,7 @@ static int ves1820_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_par if (verbose) { /* AFC only valid when carrier has been recovered */ printk(sync & 2 ? "ves1820: AFC (%d) %dHz\n" : - "ves1820: [AFC (%d) %dHz]\n", afc, -((s32) p->u.qam.symbol_rate * afc) >> 10); + "ves1820: [AFC (%d) %dHz]\n", afc, -((s32) p->symbol_rate * afc) >> 10); } if (!state->config->invert) { @@ -329,13 +331,13 @@ static int ves1820_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_par p->inversion = (!(state->reg0 & 0x20)) ? INVERSION_ON : INVERSION_OFF; } - p->u.qam.modulation = ((state->reg0 >> 2) & 7) + QAM_16; + p->modulation = ((state->reg0 >> 2) & 7) + QAM_16; - p->u.qam.fec_inner = FEC_NONE; + p->fec_inner = FEC_NONE; p->frequency = ((p->frequency + 31250) / 62500) * 62500; if (sync & 2) - p->frequency -= ((s32) p->u.qam.symbol_rate * afc) >> 10; + p->frequency -= ((s32) p->symbol_rate * afc) >> 10; return 0; } @@ -405,10 +407,9 @@ error: } static struct dvb_frontend_ops ves1820_ops = { - + .delsys = { SYS_DVBC_ANNEX_A }, .info = { .name = "VLSI VES1820 DVB-C", - .type = FE_QAM, .frequency_stepsize = 62500, .frequency_min = 47000000, .frequency_max = 862000000, diff --git a/drivers/media/dvb/frontends/ves1x93.c b/drivers/media/dvb/frontends/ves1x93.c index 8d7854c2fb0c..9c17eacaec24 100644 --- a/drivers/media/dvb/frontends/ves1x93.c +++ b/drivers/media/dvb/frontends/ves1x93.c @@ -46,6 +46,7 @@ struct ves1x93_state { u8 *init_1x93_wtab; u8 tab_size; u8 demod_type; + u32 frequency; }; static int debug; @@ -384,31 +385,34 @@ static int ves1x93_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) return 0; } -static int ves1x93_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) +static int ves1x93_set_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct ves1x93_state* state = fe->demodulator_priv; if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); + fe->ops.tuner_ops.set_params(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); } ves1x93_set_inversion (state, p->inversion); - ves1x93_set_fec (state, p->u.qpsk.fec_inner); - ves1x93_set_symbolrate (state, p->u.qpsk.symbol_rate); + ves1x93_set_fec(state, p->fec_inner); + ves1x93_set_symbolrate(state, p->symbol_rate); state->inversion = p->inversion; + state->frequency = p->frequency; return 0; } -static int ves1x93_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) +static int ves1x93_get_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct ves1x93_state* state = fe->demodulator_priv; int afc; afc = ((int)((char)(ves1x93_readreg (state, 0x0a) << 1)))/2; - afc = (afc * (int)(p->u.qpsk.symbol_rate/1000/8))/16; + afc = (afc * (int)(p->symbol_rate/1000/8))/16; - p->frequency -= afc; + p->frequency = state->frequency - afc; /* * inversion indicator is only valid @@ -417,7 +421,7 @@ static int ves1x93_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_par if (state->inversion == INVERSION_AUTO) p->inversion = (ves1x93_readreg (state, 0x0f) & 2) ? INVERSION_OFF : INVERSION_ON; - p->u.qpsk.fec_inner = ves1x93_get_fec (state); + p->fec_inner = ves1x93_get_fec(state); /* XXX FIXME: timing offset !! */ return 0; @@ -506,10 +510,9 @@ error: } static struct dvb_frontend_ops ves1x93_ops = { - + .delsys = { SYS_DVBS }, .info = { .name = "VLSI VES1x93 DVB-S", - .type = FE_QPSK, .frequency_min = 950000, .frequency_max = 2150000, .frequency_stepsize = 125, /* kHz for QPSK frontends */ diff --git a/drivers/media/dvb/frontends/zl10036.c b/drivers/media/dvb/frontends/zl10036.c index 81aa984c551f..0903d461b8fa 100644 --- a/drivers/media/dvb/frontends/zl10036.c +++ b/drivers/media/dvb/frontends/zl10036.c @@ -305,12 +305,12 @@ static int zl10036_set_gain_params(struct zl10036_state *state, return zl10036_write(state, buf, sizeof(buf)); } -static int zl10036_set_params(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) +static int zl10036_set_params(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct zl10036_state *state = fe->tuner_priv; int ret = 0; - u32 frequency = params->frequency; + u32 frequency = p->frequency; u32 fbw; int i; u8 c; @@ -326,7 +326,7 @@ static int zl10036_set_params(struct dvb_frontend *fe, * fBW = (alpha*symbolrate)/(2*0.8) * 1.35 / (2*0.8) = 27 / 32 */ - fbw = (27 * params->u.qpsk.symbol_rate) / 32; + fbw = (27 * p->symbol_rate) / 32; /* scale to kHz */ fbw /= 1000; @@ -353,7 +353,7 @@ static int zl10036_set_params(struct dvb_frontend *fe, if (ret < 0) goto error; - ret = zl10036_set_frequency(state, params->frequency); + ret = zl10036_set_frequency(state, p->frequency); if (ret < 0) goto error; diff --git a/drivers/media/dvb/frontends/zl10039.c b/drivers/media/dvb/frontends/zl10039.c index c085e58a94bf..eff9c5fde50a 100644 --- a/drivers/media/dvb/frontends/zl10039.c +++ b/drivers/media/dvb/frontends/zl10039.c @@ -176,9 +176,9 @@ static int zl10039_sleep(struct dvb_frontend *fe) return 0; } -static int zl10039_set_params(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) +static int zl10039_set_params(struct dvb_frontend *fe) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct zl10039_state *state = fe->tuner_priv; u8 buf[6]; u8 bf; @@ -188,12 +188,12 @@ static int zl10039_set_params(struct dvb_frontend *fe, dprintk("%s\n", __func__); dprintk("Set frequency = %d, symbol rate = %d\n", - params->frequency, params->u.qpsk.symbol_rate); + c->frequency, c->symbol_rate); /* Assumed 10.111 MHz crystal oscillator */ /* Cancelled num/den 80 to prevent overflow */ - div = (params->frequency * 1000) / 126387; - fbw = (params->u.qpsk.symbol_rate * 27) / 32000; + div = (c->frequency * 1000) / 126387; + fbw = (c->symbol_rate * 27) / 32000; /* Cancelled num/den 10 to prevent overflow */ bf = ((fbw * 5088) / 1011100) - 1; diff --git a/drivers/media/dvb/frontends/zl10353.c b/drivers/media/dvb/frontends/zl10353.c index adbbf6d3d044..ac7237891374 100644 --- a/drivers/media/dvb/frontends/zl10353.c +++ b/drivers/media/dvb/frontends/zl10353.c @@ -37,9 +37,9 @@ struct zl10353_state { struct zl10353_config config; - enum fe_bandwidth bandwidth; - u32 ucblocks; - u32 frequency; + u32 bandwidth; + u32 ucblocks; + u32 frequency; }; static int debug; @@ -122,30 +122,17 @@ static void zl10353_dump_regs(struct dvb_frontend *fe) } static void zl10353_calc_nominal_rate(struct dvb_frontend *fe, - enum fe_bandwidth bandwidth, + u32 bandwidth, u16 *nominal_rate) { struct zl10353_state *state = fe->demodulator_priv; u32 adc_clock = 450560; /* 45.056 MHz */ u64 value; - u8 bw; + u8 bw = bandwidth / 1000000; if (state->config.adc_clock) adc_clock = state->config.adc_clock; - switch (bandwidth) { - case BANDWIDTH_6_MHZ: - bw = 6; - break; - case BANDWIDTH_7_MHZ: - bw = 7; - break; - case BANDWIDTH_8_MHZ: - default: - bw = 8; - break; - } - value = (u64)10 * (1 << 23) / 7 * 125; value = (bw * value) + adc_clock / 2; do_div(value, adc_clock); @@ -192,16 +179,15 @@ static int zl10353_sleep(struct dvb_frontend *fe) return 0; } -static int zl10353_set_parameters(struct dvb_frontend *fe, - struct dvb_frontend_parameters *param) +static int zl10353_set_parameters(struct dvb_frontend *fe) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct zl10353_state *state = fe->demodulator_priv; u16 nominal_rate, input_freq; u8 pllbuf[6] = { 0x67 }, acq_ctl = 0; u16 tps = 0; - struct dvb_ofdm_parameters *op = ¶m->u.ofdm; - state->frequency = param->frequency; + state->frequency = c->frequency; zl10353_single_write(fe, RESET, 0x80); udelay(200); @@ -211,42 +197,44 @@ static int zl10353_set_parameters(struct dvb_frontend *fe, zl10353_single_write(fe, AGC_TARGET, 0x28); - if (op->transmission_mode != TRANSMISSION_MODE_AUTO) + if (c->transmission_mode != TRANSMISSION_MODE_AUTO) acq_ctl |= (1 << 0); - if (op->guard_interval != GUARD_INTERVAL_AUTO) + if (c->guard_interval != GUARD_INTERVAL_AUTO) acq_ctl |= (1 << 1); zl10353_single_write(fe, ACQ_CTL, acq_ctl); - switch (op->bandwidth) { - case BANDWIDTH_6_MHZ: + switch (c->bandwidth_hz) { + case 6000000: /* These are extrapolated from the 7 and 8MHz values */ zl10353_single_write(fe, MCLK_RATIO, 0x97); zl10353_single_write(fe, 0x64, 0x34); zl10353_single_write(fe, 0xcc, 0xdd); break; - case BANDWIDTH_7_MHZ: + case 7000000: zl10353_single_write(fe, MCLK_RATIO, 0x86); zl10353_single_write(fe, 0x64, 0x35); zl10353_single_write(fe, 0xcc, 0x73); break; - case BANDWIDTH_8_MHZ: default: + c->bandwidth_hz = 8000000; + /* fall though */ + case 8000000: zl10353_single_write(fe, MCLK_RATIO, 0x75); zl10353_single_write(fe, 0x64, 0x36); zl10353_single_write(fe, 0xcc, 0x73); } - zl10353_calc_nominal_rate(fe, op->bandwidth, &nominal_rate); + zl10353_calc_nominal_rate(fe, c->bandwidth_hz, &nominal_rate); zl10353_single_write(fe, TRL_NOMINAL_RATE_1, msb(nominal_rate)); zl10353_single_write(fe, TRL_NOMINAL_RATE_0, lsb(nominal_rate)); - state->bandwidth = op->bandwidth; + state->bandwidth = c->bandwidth_hz; zl10353_calc_input_freq(fe, &input_freq); zl10353_single_write(fe, INPUT_FREQ_1, msb(input_freq)); zl10353_single_write(fe, INPUT_FREQ_0, lsb(input_freq)); /* Hint at TPS settings */ - switch (op->code_rate_HP) { + switch (c->code_rate_HP) { case FEC_2_3: tps |= (1 << 7); break; @@ -266,7 +254,7 @@ static int zl10353_set_parameters(struct dvb_frontend *fe, return -EINVAL; } - switch (op->code_rate_LP) { + switch (c->code_rate_LP) { case FEC_2_3: tps |= (1 << 4); break; @@ -283,14 +271,14 @@ static int zl10353_set_parameters(struct dvb_frontend *fe, case FEC_AUTO: break; case FEC_NONE: - if (op->hierarchy_information == HIERARCHY_AUTO || - op->hierarchy_information == HIERARCHY_NONE) + if (c->hierarchy == HIERARCHY_AUTO || + c->hierarchy == HIERARCHY_NONE) break; default: return -EINVAL; } - switch (op->constellation) { + switch (c->modulation) { case QPSK: break; case QAM_AUTO: @@ -304,7 +292,7 @@ static int zl10353_set_parameters(struct dvb_frontend *fe, return -EINVAL; } - switch (op->transmission_mode) { + switch (c->transmission_mode) { case TRANSMISSION_MODE_2K: case TRANSMISSION_MODE_AUTO: break; @@ -315,7 +303,7 @@ static int zl10353_set_parameters(struct dvb_frontend *fe, return -EINVAL; } - switch (op->guard_interval) { + switch (c->guard_interval) { case GUARD_INTERVAL_1_32: case GUARD_INTERVAL_AUTO: break; @@ -332,7 +320,7 @@ static int zl10353_set_parameters(struct dvb_frontend *fe, return -EINVAL; } - switch (op->hierarchy_information) { + switch (c->hierarchy) { case HIERARCHY_AUTO: case HIERARCHY_NONE: break; @@ -362,12 +350,12 @@ static int zl10353_set_parameters(struct dvb_frontend *fe, */ if (state->config.no_tuner) { if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, param); + fe->ops.tuner_ops.set_params(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); } } else if (fe->ops.tuner_ops.calc_regs) { - fe->ops.tuner_ops.calc_regs(fe, param, pllbuf + 1, 5); + fe->ops.tuner_ops.calc_regs(fe, pllbuf + 1, 5); pllbuf[1] <<= 1; zl10353_write(fe, pllbuf, sizeof(pllbuf)); } @@ -383,11 +371,10 @@ static int zl10353_set_parameters(struct dvb_frontend *fe, return 0; } -static int zl10353_get_parameters(struct dvb_frontend *fe, - struct dvb_frontend_parameters *param) +static int zl10353_get_parameters(struct dvb_frontend *fe) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct zl10353_state *state = fe->demodulator_priv; - struct dvb_ofdm_parameters *op = ¶m->u.ofdm; int s6, s9; u16 tps; static const u8 tps_fec_to_api[8] = { @@ -411,66 +398,66 @@ static int zl10353_get_parameters(struct dvb_frontend *fe, tps = zl10353_read_register(state, TPS_RECEIVED_1) << 8 | zl10353_read_register(state, TPS_RECEIVED_0); - op->code_rate_HP = tps_fec_to_api[(tps >> 7) & 7]; - op->code_rate_LP = tps_fec_to_api[(tps >> 4) & 7]; + c->code_rate_HP = tps_fec_to_api[(tps >> 7) & 7]; + c->code_rate_LP = tps_fec_to_api[(tps >> 4) & 7]; switch ((tps >> 13) & 3) { case 0: - op->constellation = QPSK; + c->modulation = QPSK; break; case 1: - op->constellation = QAM_16; + c->modulation = QAM_16; break; case 2: - op->constellation = QAM_64; + c->modulation = QAM_64; break; default: - op->constellation = QAM_AUTO; + c->modulation = QAM_AUTO; break; } - op->transmission_mode = (tps & 0x01) ? TRANSMISSION_MODE_8K : + c->transmission_mode = (tps & 0x01) ? TRANSMISSION_MODE_8K : TRANSMISSION_MODE_2K; switch ((tps >> 2) & 3) { case 0: - op->guard_interval = GUARD_INTERVAL_1_32; + c->guard_interval = GUARD_INTERVAL_1_32; break; case 1: - op->guard_interval = GUARD_INTERVAL_1_16; + c->guard_interval = GUARD_INTERVAL_1_16; break; case 2: - op->guard_interval = GUARD_INTERVAL_1_8; + c->guard_interval = GUARD_INTERVAL_1_8; break; case 3: - op->guard_interval = GUARD_INTERVAL_1_4; + c->guard_interval = GUARD_INTERVAL_1_4; break; default: - op->guard_interval = GUARD_INTERVAL_AUTO; + c->guard_interval = GUARD_INTERVAL_AUTO; break; } switch ((tps >> 10) & 7) { case 0: - op->hierarchy_information = HIERARCHY_NONE; + c->hierarchy = HIERARCHY_NONE; break; case 1: - op->hierarchy_information = HIERARCHY_1; + c->hierarchy = HIERARCHY_1; break; case 2: - op->hierarchy_information = HIERARCHY_2; + c->hierarchy = HIERARCHY_2; break; case 3: - op->hierarchy_information = HIERARCHY_4; + c->hierarchy = HIERARCHY_4; break; default: - op->hierarchy_information = HIERARCHY_AUTO; + c->hierarchy = HIERARCHY_AUTO; break; } - param->frequency = state->frequency; - op->bandwidth = state->bandwidth; - param->inversion = INVERSION_AUTO; + c->frequency = state->frequency; + c->bandwidth_hz = state->bandwidth; + c->inversion = INVERSION_AUTO; return 0; } @@ -651,10 +638,9 @@ error: } static struct dvb_frontend_ops zl10353_ops = { - + .delsys = { SYS_DVBT }, .info = { .name = "Zarlink ZL10353 DVB-T", - .type = FE_OFDM, .frequency_min = 174000000, .frequency_max = 862000000, .frequency_stepsize = 166667, diff --git a/drivers/media/dvb/mantis/mantis_vp1033.c b/drivers/media/dvb/mantis/mantis_vp1033.c index 2ae0afa7756b..ad013e93ed11 100644 --- a/drivers/media/dvb/mantis/mantis_vp1033.c +++ b/drivers/media/dvb/mantis/mantis_vp1033.c @@ -83,9 +83,9 @@ u8 lgtdqcs001f_inittab[] = { #define MANTIS_MODEL_NAME "VP-1033" #define MANTIS_DEV_TYPE "DVB-S/DSS" -int lgtdqcs001f_tuner_set(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) +int lgtdqcs001f_tuner_set(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct mantis_pci *mantis = fe->dvb->priv; struct i2c_adapter *adapter = &mantis->adapter; @@ -95,14 +95,14 @@ int lgtdqcs001f_tuner_set(struct dvb_frontend *fe, struct i2c_msg msg = {.addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf)}; - div = params->frequency / 250; + div = p->frequency / 250; buf[0] = (div >> 8) & 0x7f; buf[1] = div & 0xff; buf[2] = 0x83; buf[3] = 0xc0; - if (params->frequency < 1531000) + if (p->frequency < 1531000) buf[3] |= 0x04; else buf[3] &= ~0x04; diff --git a/drivers/media/dvb/mantis/mantis_vp2033.c b/drivers/media/dvb/mantis/mantis_vp2033.c index 06da0ddf05a7..1ca6837fbe46 100644 --- a/drivers/media/dvb/mantis/mantis_vp2033.c +++ b/drivers/media/dvb/mantis/mantis_vp2033.c @@ -65,8 +65,9 @@ static u8 read_pwm(struct mantis_pci *mantis) return pwm; } -static int tda1002x_cu1216_tuner_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) +static int tda1002x_cu1216_tuner_set(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct mantis_pci *mantis = fe->dvb->priv; struct i2c_adapter *adapter = &mantis->adapter; @@ -77,13 +78,13 @@ static int tda1002x_cu1216_tuner_set(struct dvb_frontend *fe, struct dvb_fronten #define CU1216_IF 36125000 #define TUNER_MUL 62500 - u32 div = (params->frequency + CU1216_IF + TUNER_MUL / 2) / TUNER_MUL; + u32 div = (p->frequency + CU1216_IF + TUNER_MUL / 2) / TUNER_MUL; buf[0] = (div >> 8) & 0x7f; buf[1] = div & 0xff; buf[2] = 0xce; - buf[3] = (params->frequency < 150000000 ? 0x01 : - params->frequency < 445000000 ? 0x02 : 0x04); + buf[3] = (p->frequency < 150000000 ? 0x01 : + p->frequency < 445000000 ? 0x02 : 0x04); buf[4] = 0xde; buf[5] = 0x20; diff --git a/drivers/media/dvb/mantis/mantis_vp2040.c b/drivers/media/dvb/mantis/mantis_vp2040.c index f72b137b7652..d480741afd78 100644 --- a/drivers/media/dvb/mantis/mantis_vp2040.c +++ b/drivers/media/dvb/mantis/mantis_vp2040.c @@ -47,8 +47,9 @@ struct tda10023_config vp2040_tda10023_cu1216_config = { .invert = 1, }; -static int tda1002x_cu1216_tuner_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) +static int tda1002x_cu1216_tuner_set(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct mantis_pci *mantis = fe->dvb->priv; struct i2c_adapter *adapter = &mantis->adapter; @@ -59,13 +60,13 @@ static int tda1002x_cu1216_tuner_set(struct dvb_frontend *fe, struct dvb_fronten #define CU1216_IF 36125000 #define TUNER_MUL 62500 - u32 div = (params->frequency + CU1216_IF + TUNER_MUL / 2) / TUNER_MUL; + u32 div = (p->frequency + CU1216_IF + TUNER_MUL / 2) / TUNER_MUL; buf[0] = (div >> 8) & 0x7f; buf[1] = div & 0xff; buf[2] = 0xce; - buf[3] = (params->frequency < 150000000 ? 0x01 : - params->frequency < 445000000 ? 0x02 : 0x04); + buf[3] = (p->frequency < 150000000 ? 0x01 : + p->frequency < 445000000 ? 0x02 : 0x04); buf[4] = 0xde; buf[5] = 0x20; diff --git a/drivers/media/dvb/ngene/ngene-cards.c b/drivers/media/dvb/ngene/ngene-cards.c index 056419228363..8418c02bcefe 100644 --- a/drivers/media/dvb/ngene/ngene-cards.c +++ b/drivers/media/dvb/ngene/ngene-cards.c @@ -218,7 +218,7 @@ static int demod_attach_drxk(struct ngene_channel *chan, memset(&config, 0, sizeof(config)); config.adr = 0x29 + (chan->number ^ 2); - chan->fe = dvb_attach(drxk_attach, &config, i2c, &chan->fe2); + chan->fe = dvb_attach(drxk_attach, &config, i2c); if (!chan->fe) { printk(KERN_ERR "No DRXK found!\n"); return -ENODEV; diff --git a/drivers/media/dvb/pluto2/pluto2.c b/drivers/media/dvb/pluto2/pluto2.c index 80fb51004461..e1f20c236989 100644 --- a/drivers/media/dvb/pluto2/pluto2.c +++ b/drivers/media/dvb/pluto2/pluto2.c @@ -445,9 +445,9 @@ static inline u32 divide(u32 numerator, u32 denominator) } /* LG Innotek TDTE-E001P (Infineon TUA6034) */ -static int lg_tdtpe001p_tuner_set_params(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int lg_tdtpe001p_tuner_set_params(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct pluto *pluto = frontend_to_pluto(fe); struct i2c_msg msg; int ret; @@ -478,7 +478,7 @@ static int lg_tdtpe001p_tuner_set_params(struct dvb_frontend *fe, else buf[3] = 0x04; - if (p->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) + if (p->bandwidth_hz == 8000000) buf[3] |= 0x08; if (sizeof(buf) == 6) { diff --git a/drivers/media/dvb/pt1/va1j5jf8007s.c b/drivers/media/dvb/pt1/va1j5jf8007s.c index 451641c0c1d2..d980dfb21e5e 100644 --- a/drivers/media/dvb/pt1/va1j5jf8007s.c +++ b/drivers/media/dvb/pt1/va1j5jf8007s.c @@ -385,7 +385,7 @@ va1j5jf8007s_check_ts_id(struct va1j5jf8007s_state *state, int *lock) static int va1j5jf8007s_tune(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params, + bool re_tune, unsigned int mode_flags, unsigned int *delay, fe_status_t *status) { @@ -395,7 +395,7 @@ va1j5jf8007s_tune(struct dvb_frontend *fe, state = fe->demodulator_priv; - if (params != NULL) + if (re_tune) state->tune_state = VA1J5JF8007S_SET_FREQUENCY_1; switch (state->tune_state) { @@ -579,9 +579,9 @@ static void va1j5jf8007s_release(struct dvb_frontend *fe) } static struct dvb_frontend_ops va1j5jf8007s_ops = { + .delsys = { SYS_ISDBS }, .info = { .name = "VA1J5JF8007/VA1J5JF8011 ISDB-S", - .type = FE_QPSK, .frequency_min = 950000, .frequency_max = 2150000, .frequency_stepsize = 1000, diff --git a/drivers/media/dvb/pt1/va1j5jf8007t.c b/drivers/media/dvb/pt1/va1j5jf8007t.c index 0f085c3e571b..2db15159d514 100644 --- a/drivers/media/dvb/pt1/va1j5jf8007t.c +++ b/drivers/media/dvb/pt1/va1j5jf8007t.c @@ -264,7 +264,7 @@ static int va1j5jf8007t_check_modulation(struct va1j5jf8007t_state *state, static int va1j5jf8007t_tune(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params, + bool re_tune, unsigned int mode_flags, unsigned int *delay, fe_status_t *status) { @@ -274,7 +274,7 @@ va1j5jf8007t_tune(struct dvb_frontend *fe, state = fe->demodulator_priv; - if (params != NULL) + if (re_tune) state->tune_state = VA1J5JF8007T_SET_FREQUENCY; switch (state->tune_state) { @@ -428,9 +428,9 @@ static void va1j5jf8007t_release(struct dvb_frontend *fe) } static struct dvb_frontend_ops va1j5jf8007t_ops = { + .delsys = { SYS_ISDBT }, .info = { .name = "VA1J5JF8007/VA1J5JF8011 ISDB-T", - .type = FE_OFDM, .frequency_min = 90000000, .frequency_max = 770000000, .frequency_stepsize = 142857, diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c index 37c594f82782..654685c9303e 100644 --- a/drivers/media/dvb/siano/smsdvb.c +++ b/drivers/media/dvb/siano/smsdvb.c @@ -50,7 +50,7 @@ struct smsdvb_client_t { struct completion tune_done; /* todo: save freq/band instead whole struct */ - struct dvb_frontend_parameters fe_params; + struct dtv_frontend_properties fe_params; struct SMSHOSTLIB_STATISTICS_DVB_S sms_stat_dvb; int event_fe_state; @@ -591,8 +591,7 @@ static int smsdvb_get_tune_settings(struct dvb_frontend *fe, return 0; } -static int smsdvb_dvbt_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int smsdvb_dvbt_set_frontend(struct dvb_frontend *fe) { struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct smsdvb_client_t *client = @@ -658,8 +657,7 @@ static int smsdvb_dvbt_set_frontend(struct dvb_frontend *fe, &client->tune_done); } -static int smsdvb_isdbt_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int smsdvb_isdbt_set_frontend(struct dvb_frontend *fe) { struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct smsdvb_client_t *client = @@ -723,8 +721,7 @@ static int smsdvb_isdbt_set_frontend(struct dvb_frontend *fe, &client->tune_done); } -static int smsdvb_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *fep) +static int smsdvb_set_frontend(struct dvb_frontend *fe) { struct smsdvb_client_t *client = container_of(fe, struct smsdvb_client_t, frontend); @@ -733,18 +730,18 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe, switch (smscore_get_device_mode(coredev)) { case DEVICE_MODE_DVBT: case DEVICE_MODE_DVBT_BDA: - return smsdvb_dvbt_set_frontend(fe, fep); + return smsdvb_dvbt_set_frontend(fe); case DEVICE_MODE_ISDBT: case DEVICE_MODE_ISDBT_BDA: - return smsdvb_isdbt_set_frontend(fe, fep); + return smsdvb_isdbt_set_frontend(fe); default: return -EINVAL; } } -static int smsdvb_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *fep) +static int smsdvb_get_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *fep = &fe->dtv_property_cache; struct smsdvb_client_t *client = container_of(fe, struct smsdvb_client_t, frontend); @@ -752,7 +749,7 @@ static int smsdvb_get_frontend(struct dvb_frontend *fe, /* todo: */ memcpy(fep, &client->fe_params, - sizeof(struct dvb_frontend_parameters)); + sizeof(struct dtv_frontend_properties)); return 0; } @@ -789,7 +786,6 @@ static void smsdvb_release(struct dvb_frontend *fe) static struct dvb_frontend_ops smsdvb_fe_ops = { .info = { .name = "Siano Mobile Digital MDTV Receiver", - .type = FE_OFDM, .frequency_min = 44250000, .frequency_max = 867250000, .frequency_stepsize = 250000, @@ -873,6 +869,17 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev, memcpy(&client->frontend.ops, &smsdvb_fe_ops, sizeof(struct dvb_frontend_ops)); + switch (smscore_get_device_mode(coredev)) { + case DEVICE_MODE_DVBT: + case DEVICE_MODE_DVBT_BDA: + smsdvb_fe_ops.delsys[0] = SYS_DVBT; + break; + case DEVICE_MODE_ISDBT: + case DEVICE_MODE_ISDBT_BDA: + smsdvb_fe_ops.delsys[0] = SYS_ISDBT; + break; + } + rc = dvb_register_frontend(&client->adapter, &client->frontend); if (rc < 0) { sms_err("frontend registration failed %d", rc); diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c index 3d20719fce1a..6ecbcf614878 100644 --- a/drivers/media/dvb/ttpci/av7110.c +++ b/drivers/media/dvb/ttpci/av7110.c @@ -991,7 +991,7 @@ static int av7110_start_feed(struct dvb_demux_feed *feed) if (feed->type == DMX_TYPE_TS) { if ((feed->ts_type & TS_DECODER) && - (feed->pes_type < DMX_TS_PES_OTHER)) { + (feed->pes_type <= DMX_TS_PES_PCR)) { switch (demux->dmx.frontend->source) { case DMX_MEMORY_FE: if (feed->ts_type & TS_DECODER) @@ -1568,20 +1568,27 @@ static int get_firmware(struct av7110* av7110) return ret; } -static int alps_bsrv2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) +static int alps_bsrv2_tuner_set_params(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct av7110* av7110 = fe->dvb->priv; u8 pwr = 0; u8 buf[4]; struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; - u32 div = (params->frequency + 479500) / 125; + u32 div = (p->frequency + 479500) / 125; - if (params->frequency > 2000000) pwr = 3; - else if (params->frequency > 1800000) pwr = 2; - else if (params->frequency > 1600000) pwr = 1; - else if (params->frequency > 1200000) pwr = 0; - else if (params->frequency >= 1100000) pwr = 1; - else pwr = 2; + if (p->frequency > 2000000) + pwr = 3; + else if (p->frequency > 1800000) + pwr = 2; + else if (p->frequency > 1600000) + pwr = 1; + else if (p->frequency > 1200000) + pwr = 0; + else if (p->frequency >= 1100000) + pwr = 1; + else + pwr = 2; buf[0] = (div >> 8) & 0x7f; buf[1] = div & 0xff; @@ -1604,19 +1611,20 @@ static struct ves1x93_config alps_bsrv2_config = { .invert_pwm = 0, }; -static int alps_tdbe2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) +static int alps_tdbe2_tuner_set_params(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct av7110* av7110 = fe->dvb->priv; u32 div; u8 data[4]; struct i2c_msg msg = { .addr = 0x62, .flags = 0, .buf = data, .len = sizeof(data) }; - div = (params->frequency + 35937500 + 31250) / 62500; + div = (p->frequency + 35937500 + 31250) / 62500; data[0] = (div >> 8) & 0x7f; data[1] = div & 0xff; data[2] = 0x85 | ((div >> 10) & 0x60); - data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81); + data[3] = (p->frequency < 174000000 ? 0x88 : p->frequency < 470000000 ? 0x84 : 0x81); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); @@ -1635,14 +1643,15 @@ static struct ves1820_config alps_tdbe2_config = { -static int grundig_29504_451_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) +static int grundig_29504_451_tuner_set_params(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct av7110* av7110 = fe->dvb->priv; u32 div; u8 data[4]; struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; - div = params->frequency / 125; + div = p->frequency / 125; data[0] = (div >> 8) & 0x7f; data[1] = div & 0xff; data[2] = 0x8e; @@ -1661,11 +1670,12 @@ static struct tda8083_config grundig_29504_451_config = { -static int philips_cd1516_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) +static int philips_cd1516_tuner_set_params(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct av7110* av7110 = fe->dvb->priv; u32 div; - u32 f = params->frequency; + u32 f = p->frequency; u8 data[4]; struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; @@ -1692,16 +1702,17 @@ static struct ves1820_config philips_cd1516_config = { -static int alps_tdlb7_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) +static int alps_tdlb7_tuner_set_params(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct av7110* av7110 = fe->dvb->priv; u32 div, pwr; u8 data[4]; struct i2c_msg msg = { .addr = 0x60, .flags = 0, .buf = data, .len = sizeof(data) }; - div = (params->frequency + 36200000) / 166666; + div = (p->frequency + 36200000) / 166666; - if (params->frequency <= 782000000) + if (p->frequency <= 782000000) pwr = 1; else pwr = 2; @@ -1829,8 +1840,9 @@ static u8 nexusca_stv0297_inittab[] = { 0xff, 0xff, }; -static int nexusca_stv0297_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) +static int nexusca_stv0297_tuner_set_params(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct av7110* av7110 = fe->dvb->priv; u32 div; u8 data[4]; @@ -1838,19 +1850,19 @@ static int nexusca_stv0297_tuner_set_params(struct dvb_frontend* fe, struct dvb_ struct i2c_msg readmsg = { .addr = 0x63, .flags = I2C_M_RD, .buf = data, .len = 1 }; int i; - div = (params->frequency + 36150000 + 31250) / 62500; + div = (p->frequency + 36150000 + 31250) / 62500; data[0] = (div >> 8) & 0x7f; data[1] = div & 0xff; data[2] = 0xce; - if (params->frequency < 45000000) + if (p->frequency < 45000000) return -EINVAL; - else if (params->frequency < 137000000) + else if (p->frequency < 137000000) data[3] = 0x01; - else if (params->frequency < 403000000) + else if (p->frequency < 403000000) data[3] = 0x02; - else if (params->frequency < 860000000) + else if (p->frequency < 860000000) data[3] = 0x04; else return -EINVAL; @@ -1884,27 +1896,36 @@ static struct stv0297_config nexusca_stv0297_config = { -static int grundig_29504_401_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) +static int grundig_29504_401_tuner_set_params(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct av7110* av7110 = fe->dvb->priv; u32 div; u8 cfg, cpump, band_select; u8 data[4]; struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; - div = (36125000 + params->frequency) / 166666; + div = (36125000 + p->frequency) / 166666; cfg = 0x88; - if (params->frequency < 175000000) cpump = 2; - else if (params->frequency < 390000000) cpump = 1; - else if (params->frequency < 470000000) cpump = 2; - else if (params->frequency < 750000000) cpump = 1; - else cpump = 3; + if (p->frequency < 175000000) + cpump = 2; + else if (p->frequency < 390000000) + cpump = 1; + else if (p->frequency < 470000000) + cpump = 2; + else if (p->frequency < 750000000) + cpump = 1; + else + cpump = 3; - if (params->frequency < 175000000) band_select = 0x0e; - else if (params->frequency < 470000000) band_select = 0x05; - else band_select = 0x03; + if (p->frequency < 175000000) + band_select = 0x0e; + else if (p->frequency < 470000000) + band_select = 0x05; + else + band_select = 0x03; data[0] = (div >> 8) & 0x7f; data[1] = div & 0xff; @@ -1964,15 +1985,14 @@ static int av7110_fe_lock_fix(struct av7110* av7110, fe_status_t status) return ret; } -static int av7110_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) +static int av7110_fe_set_frontend(struct dvb_frontend *fe) { struct av7110* av7110 = fe->dvb->priv; int ret = av7110_fe_lock_fix(av7110, 0); - if (!ret) { - av7110->saved_fe_params = *params; - ret = av7110->fe_set_frontend(fe, params); - } + if (!ret) + ret = av7110->fe_set_frontend(fe); + return ret; } @@ -2081,7 +2101,7 @@ static void dvb_s_recover(struct av7110* av7110) msleep(20); av7110_fe_set_tone(av7110->fe, av7110->saved_tone); - av7110_fe_set_frontend(av7110->fe, &av7110->saved_fe_params); + av7110_fe_set_frontend(av7110->fe); } static u8 read_pwm(struct av7110* av7110) diff --git a/drivers/media/dvb/ttpci/av7110.h b/drivers/media/dvb/ttpci/av7110.h index d85b8512ac30..88b3b2d6cc0e 100644 --- a/drivers/media/dvb/ttpci/av7110.h +++ b/drivers/media/dvb/ttpci/av7110.h @@ -272,7 +272,6 @@ struct av7110 { /* crash recovery */ void (*recover)(struct av7110* av7110); - struct dvb_frontend_parameters saved_fe_params; fe_sec_voltage_t saved_voltage; fe_sec_tone_mode_t saved_tone; struct dvb_diseqc_master_cmd saved_master_cmd; @@ -286,7 +285,7 @@ struct av7110 { int (*fe_set_tone)(struct dvb_frontend* fe, fe_sec_tone_mode_t tone); int (*fe_set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage); int (*fe_dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned long cmd); - int (*fe_set_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); + int (*fe_set_frontend)(struct dvb_frontend *fe); }; diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c index 78d32f7e49fc..8b32e282bf5d 100644 --- a/drivers/media/dvb/ttpci/budget-av.c +++ b/drivers/media/dvb/ttpci/budget-av.c @@ -502,33 +502,33 @@ static int philips_su1278_ty_ci_set_symbol_rate(struct dvb_frontend *fe, u32 sra return 0; } -static int philips_su1278_ty_ci_tuner_set_params(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) +static int philips_su1278_ty_ci_tuner_set_params(struct dvb_frontend *fe) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; u32 div; u8 buf[4]; struct budget *budget = (struct budget *) fe->dvb->priv; struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) }; - if ((params->frequency < 950000) || (params->frequency > 2150000)) + if ((c->frequency < 950000) || (c->frequency > 2150000)) return -EINVAL; - div = (params->frequency + (125 - 1)) / 125; // round correctly + div = (c->frequency + (125 - 1)) / 125; /* round correctly */ buf[0] = (div >> 8) & 0x7f; buf[1] = div & 0xff; buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4; buf[3] = 0x20; - if (params->u.qpsk.symbol_rate < 4000000) + if (c->symbol_rate < 4000000) buf[3] |= 1; - if (params->frequency < 1250000) + if (c->frequency < 1250000) buf[3] |= 0; - else if (params->frequency < 1550000) + else if (c->frequency < 1550000) buf[3] |= 0x40; - else if (params->frequency < 2050000) + else if (c->frequency < 2050000) buf[3] |= 0x80; - else if (params->frequency < 2150000) + else if (c->frequency < 2150000) buf[3] |= 0xC0; if (fe->ops.i2c_gate_ctrl) @@ -617,8 +617,9 @@ static struct stv0299_config cinergy_1200s_1894_0010_config = { .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate, }; -static int philips_cu1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) +static int philips_cu1216_tuner_set_params(struct dvb_frontend *fe) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct budget *budget = (struct budget *) fe->dvb->priv; u8 buf[6]; struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) }; @@ -627,13 +628,13 @@ static int philips_cu1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_f #define CU1216_IF 36125000 #define TUNER_MUL 62500 - u32 div = (params->frequency + CU1216_IF + TUNER_MUL / 2) / TUNER_MUL; + u32 div = (c->frequency + CU1216_IF + TUNER_MUL / 2) / TUNER_MUL; buf[0] = (div >> 8) & 0x7f; buf[1] = div & 0xff; buf[2] = 0xce; - buf[3] = (params->frequency < 150000000 ? 0x01 : - params->frequency < 445000000 ? 0x02 : 0x04); + buf[3] = (c->frequency < 150000000 ? 0x01 : + c->frequency < 445000000 ? 0x02 : 0x04); buf[4] = 0xde; buf[5] = 0x20; @@ -697,8 +698,9 @@ static int philips_tu1216_tuner_init(struct dvb_frontend *fe) return 0; } -static int philips_tu1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) +static int philips_tu1216_tuner_set_params(struct dvb_frontend *fe) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct budget *budget = (struct budget *) fe->dvb->priv; u8 tuner_buf[4]; struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf,.len = @@ -707,7 +709,7 @@ static int philips_tu1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_f u8 band, cp, filter; // determine charge pump - tuner_frequency = params->frequency + 36166000; + tuner_frequency = c->frequency + 36166000; if (tuner_frequency < 87000000) return -EINVAL; else if (tuner_frequency < 130000000) @@ -732,28 +734,28 @@ static int philips_tu1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_f return -EINVAL; // determine band - if (params->frequency < 49000000) + if (c->frequency < 49000000) return -EINVAL; - else if (params->frequency < 161000000) + else if (c->frequency < 161000000) band = 1; - else if (params->frequency < 444000000) + else if (c->frequency < 444000000) band = 2; - else if (params->frequency < 861000000) + else if (c->frequency < 861000000) band = 4; else return -EINVAL; // setup PLL filter - switch (params->u.ofdm.bandwidth) { - case BANDWIDTH_6_MHZ: + switch (c->bandwidth_hz) { + case 6000000: filter = 0; break; - case BANDWIDTH_7_MHZ: + case 7000000: filter = 0; break; - case BANDWIDTH_8_MHZ: + case 8000000: filter = 1; break; @@ -763,7 +765,7 @@ static int philips_tu1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_f // calculate divisor // ((36166000+((1000000/6)/2)) + Finput)/(1000000/6) - tuner_frequency = (((params->frequency / 1000) * 6) + 217496) / 1000; + tuner_frequency = (((c->frequency / 1000) * 6) + 217496) / 1000; // setup tuner buffer tuner_buf[0] = (tuner_frequency >> 8) & 0x7f; diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c index ca02e9722172..98e524178765 100644 --- a/drivers/media/dvb/ttpci/budget-ci.c +++ b/drivers/media/dvb/ttpci/budget-ci.c @@ -193,7 +193,6 @@ static int msp430_ir_init(struct budget_ci *budget_ci) dev->input_phys = budget_ci->ir.phys; dev->input_id.bustype = BUS_PCI; dev->input_id.version = 1; - dev->scanmask = 0xff; if (saa->pci->subsystem_vendor) { dev->input_id.vendor = saa->pci->subsystem_vendor; dev->input_id.product = saa->pci->subsystem_device; @@ -234,6 +233,8 @@ static int msp430_ir_init(struct budget_ci *budget_ci) dev->map_name = RC_MAP_BUDGET_CI_OLD; break; } + if (!budget_ci->ir.full_rc5) + dev->scanmask = 0xff; error = rc_register_device(dev); if (error) { @@ -659,33 +660,33 @@ static int philips_su1278_tt_set_symbol_rate(struct dvb_frontend *fe, u32 srate, return 0; } -static int philips_su1278_tt_tuner_set_params(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) +static int philips_su1278_tt_tuner_set_params(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv; u32 div; u8 buf[4]; struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) }; - if ((params->frequency < 950000) || (params->frequency > 2150000)) + if ((p->frequency < 950000) || (p->frequency > 2150000)) return -EINVAL; - div = (params->frequency + (500 - 1)) / 500; // round correctly + div = (p->frequency + (500 - 1)) / 500; /* round correctly */ buf[0] = (div >> 8) & 0x7f; buf[1] = div & 0xff; buf[2] = 0x80 | ((div & 0x18000) >> 10) | 2; buf[3] = 0x20; - if (params->u.qpsk.symbol_rate < 4000000) + if (p->symbol_rate < 4000000) buf[3] |= 1; - if (params->frequency < 1250000) + if (p->frequency < 1250000) buf[3] |= 0; - else if (params->frequency < 1550000) + else if (p->frequency < 1550000) buf[3] |= 0x40; - else if (params->frequency < 2050000) + else if (p->frequency < 2050000) buf[3] |= 0x80; - else if (params->frequency < 2150000) + else if (p->frequency < 2150000) buf[3] |= 0xC0; if (fe->ops.i2c_gate_ctrl) @@ -740,8 +741,9 @@ static int philips_tdm1316l_tuner_init(struct dvb_frontend *fe) return 0; } -static int philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) +static int philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv; u8 tuner_buf[4]; struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,.flags = 0,.buf = tuner_buf,.len = sizeof(tuner_buf) }; @@ -749,7 +751,7 @@ static int philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struct dvb u8 band, cp, filter; // determine charge pump - tuner_frequency = params->frequency + 36130000; + tuner_frequency = p->frequency + 36130000; if (tuner_frequency < 87000000) return -EINVAL; else if (tuner_frequency < 130000000) @@ -774,30 +776,30 @@ static int philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struct dvb return -EINVAL; // determine band - if (params->frequency < 49000000) + if (p->frequency < 49000000) return -EINVAL; - else if (params->frequency < 159000000) + else if (p->frequency < 159000000) band = 1; - else if (params->frequency < 444000000) + else if (p->frequency < 444000000) band = 2; - else if (params->frequency < 861000000) + else if (p->frequency < 861000000) band = 4; else return -EINVAL; // setup PLL filter and TDA9889 - switch (params->u.ofdm.bandwidth) { - case BANDWIDTH_6_MHZ: + switch (p->bandwidth_hz) { + case 6000000: tda1004x_writereg(fe, 0x0C, 0x14); filter = 0; break; - case BANDWIDTH_7_MHZ: + case 7000000: tda1004x_writereg(fe, 0x0C, 0x80); filter = 0; break; - case BANDWIDTH_8_MHZ: + case 8000000: tda1004x_writereg(fe, 0x0C, 0x14); filter = 1; break; @@ -808,7 +810,7 @@ static int philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struct dvb // calculate divisor // ((36130000+((1000000/6)/2)) + Finput)/(1000000/6) - tuner_frequency = (((params->frequency / 1000) * 6) + 217280) / 1000; + tuner_frequency = (((p->frequency / 1000) * 6) + 217280) / 1000; // setup tuner buffer tuner_buf[0] = tuner_frequency >> 8; @@ -855,8 +857,9 @@ static struct tda1004x_config philips_tdm1316l_config_invert = { .request_firmware = philips_tdm1316l_request_firmware, }; -static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) +static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv; u8 tuner_buf[5]; struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address, @@ -867,7 +870,7 @@ static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struc u8 band, cp, filter; // determine charge pump - tuner_frequency = params->frequency + 36125000; + tuner_frequency = p->frequency + 36125000; if (tuner_frequency < 87000000) return -EINVAL; else if (tuner_frequency < 130000000) { @@ -904,7 +907,7 @@ static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struc filter = 1; // calculate divisor - tuner_frequency = (params->frequency + 36125000 + (62500/2)) / 62500; + tuner_frequency = (p->frequency + 36125000 + (62500/2)) / 62500; // setup tuner buffer tuner_buf[0] = tuner_frequency >> 8; diff --git a/drivers/media/dvb/ttpci/budget-patch.c b/drivers/media/dvb/ttpci/budget-patch.c index 3395d1a90516..2cb35c23d2ac 100644 --- a/drivers/media/dvb/ttpci/budget-patch.c +++ b/drivers/media/dvb/ttpci/budget-patch.c @@ -261,19 +261,25 @@ static int budget_patch_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_c return 0; } -static int alps_bsrv2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) +static int alps_bsrv2_tuner_set_params(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv; u8 pwr = 0; u8 buf[4]; struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; - u32 div = (params->frequency + 479500) / 125; - - if (params->frequency > 2000000) pwr = 3; - else if (params->frequency > 1800000) pwr = 2; - else if (params->frequency > 1600000) pwr = 1; - else if (params->frequency > 1200000) pwr = 0; - else if (params->frequency >= 1100000) pwr = 1; + u32 div = (p->frequency + 479500) / 125; + + if (p->frequency > 2000000) + pwr = 3; + else if (p->frequency > 1800000) + pwr = 2; + else if (p->frequency > 1600000) + pwr = 1; + else if (p->frequency > 1200000) + pwr = 0; + else if (p->frequency >= 1100000) + pwr = 1; else pwr = 2; buf[0] = (div >> 8) & 0x7f; @@ -297,14 +303,15 @@ static struct ves1x93_config alps_bsrv2_config = { .invert_pwm = 0, }; -static int grundig_29504_451_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) +static int grundig_29504_451_tuner_set_params(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv; u32 div; u8 data[4]; struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; - div = params->frequency / 125; + div = p->frequency / 125; data[0] = (div >> 8) & 0x7f; data[1] = div & 0xff; data[2] = 0x8e; diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c index d238fb9371a7..b21bcce66708 100644 --- a/drivers/media/dvb/ttpci/budget.c +++ b/drivers/media/dvb/ttpci/budget.c @@ -200,19 +200,25 @@ static int budget_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t m return 0; } -static int alps_bsrv2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) +static int alps_bsrv2_tuner_set_params(struct dvb_frontend *fe) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct budget* budget = (struct budget*) fe->dvb->priv; u8 pwr = 0; u8 buf[4]; struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; - u32 div = (params->frequency + 479500) / 125; - - if (params->frequency > 2000000) pwr = 3; - else if (params->frequency > 1800000) pwr = 2; - else if (params->frequency > 1600000) pwr = 1; - else if (params->frequency > 1200000) pwr = 0; - else if (params->frequency >= 1100000) pwr = 1; + u32 div = (c->frequency + 479500) / 125; + + if (c->frequency > 2000000) + pwr = 3; + else if (c->frequency > 1800000) + pwr = 2; + else if (c->frequency > 1600000) + pwr = 1; + else if (c->frequency > 1200000) + pwr = 0; + else if (c->frequency >= 1100000) + pwr = 1; else pwr = 2; buf[0] = (div >> 8) & 0x7f; @@ -236,19 +242,20 @@ static struct ves1x93_config alps_bsrv2_config = .invert_pwm = 0, }; -static int alps_tdbe2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) +static int alps_tdbe2_tuner_set_params(struct dvb_frontend *fe) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct budget* budget = (struct budget*) fe->dvb->priv; u32 div; u8 data[4]; struct i2c_msg msg = { .addr = 0x62, .flags = 0, .buf = data, .len = sizeof(data) }; - div = (params->frequency + 35937500 + 31250) / 62500; + div = (c->frequency + 35937500 + 31250) / 62500; data[0] = (div >> 8) & 0x7f; data[1] = div & 0xff; data[2] = 0x85 | ((div >> 10) & 0x60); - data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81); + data[3] = (c->frequency < 174000000 ? 0x88 : c->frequency < 470000000 ? 0x84 : 0x81); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); @@ -263,8 +270,9 @@ static struct ves1820_config alps_tdbe2_config = { .selagc = VES1820_SELAGC_SIGNAMPERR, }; -static int grundig_29504_401_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) +static int grundig_29504_401_tuner_set_params(struct dvb_frontend *fe) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct budget *budget = fe->dvb->priv; u8 *tuner_addr = fe->tuner_priv; u32 div; @@ -277,19 +285,27 @@ static int grundig_29504_401_tuner_set_params(struct dvb_frontend* fe, struct dv else msg.addr = 0x61; - div = (36125000 + params->frequency) / 166666; + div = (36125000 + c->frequency) / 166666; cfg = 0x88; - if (params->frequency < 175000000) cpump = 2; - else if (params->frequency < 390000000) cpump = 1; - else if (params->frequency < 470000000) cpump = 2; - else if (params->frequency < 750000000) cpump = 1; - else cpump = 3; + if (c->frequency < 175000000) + cpump = 2; + else if (c->frequency < 390000000) + cpump = 1; + else if (c->frequency < 470000000) + cpump = 2; + else if (c->frequency < 750000000) + cpump = 1; + else + cpump = 3; - if (params->frequency < 175000000) band_select = 0x0e; - else if (params->frequency < 470000000) band_select = 0x05; - else band_select = 0x03; + if (c->frequency < 175000000) + band_select = 0x0e; + else if (c->frequency < 470000000) + band_select = 0x05; + else + band_select = 0x03; data[0] = (div >> 8) & 0x7f; data[1] = div & 0xff; @@ -312,14 +328,15 @@ static struct l64781_config grundig_29504_401_config_activy = { static u8 tuner_address_grundig_29504_401_activy = 0x60; -static int grundig_29504_451_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) +static int grundig_29504_451_tuner_set_params(struct dvb_frontend *fe) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct budget* budget = (struct budget*) fe->dvb->priv; u32 div; u8 data[4]; struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; - div = params->frequency / 125; + div = c->frequency / 125; data[0] = (div >> 8) & 0x7f; data[1] = div & 0xff; data[2] = 0x8e; @@ -335,14 +352,15 @@ static struct tda8083_config grundig_29504_451_config = { .demod_address = 0x68, }; -static int s5h1420_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) +static int s5h1420_tuner_set_params(struct dvb_frontend *fe) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct budget* budget = (struct budget*) fe->dvb->priv; u32 div; u8 data[4]; struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; - div = params->frequency / 1000; + div = c->frequency / 1000; data[0] = (div >> 8) & 0x7f; data[1] = div & 0xff; data[2] = 0xc2; diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c index e90192fdde11..5b682cc4c814 100644 --- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c +++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c @@ -1017,19 +1017,20 @@ static u32 functionality(struct i2c_adapter *adapter) -static int alps_tdmb7_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) +static int alps_tdmb7_tuner_set_params(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; u8 data[4]; struct i2c_msg msg = {.addr=0x61, .flags=0, .buf=data, .len=sizeof(data) }; u32 div; - div = (params->frequency + 36166667) / 166667; + div = (p->frequency + 36166667) / 166667; data[0] = (div >> 8) & 0x7f; data[1] = div & 0xff; data[2] = ((div >> 10) & 0x60) | 0x85; - data[3] = params->frequency < 592000000 ? 0x40 : 0x80; + data[3] = p->frequency < 592000000 ? 0x40 : 0x80; if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); @@ -1071,8 +1072,9 @@ static int philips_tdm1316l_tuner_init(struct dvb_frontend* fe) return 0; } -static int philips_tdm1316l_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) +static int philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; u8 tuner_buf[4]; struct i2c_msg tuner_msg = {.addr=0x60, .flags=0, .buf=tuner_buf, .len=sizeof(tuner_buf) }; @@ -1080,7 +1082,7 @@ static int philips_tdm1316l_tuner_set_params(struct dvb_frontend* fe, struct dvb u8 band, cp, filter; // determine charge pump - tuner_frequency = params->frequency + 36130000; + tuner_frequency = p->frequency + 36130000; if (tuner_frequency < 87000000) return -EINVAL; else if (tuner_frequency < 130000000) cp = 3; else if (tuner_frequency < 160000000) cp = 5; @@ -1094,25 +1096,29 @@ static int philips_tdm1316l_tuner_set_params(struct dvb_frontend* fe, struct dvb else return -EINVAL; // determine band - if (params->frequency < 49000000) return -EINVAL; - else if (params->frequency < 159000000) band = 1; - else if (params->frequency < 444000000) band = 2; - else if (params->frequency < 861000000) band = 4; + if (p->frequency < 49000000) + return -EINVAL; + else if (p->frequency < 159000000) + band = 1; + else if (p->frequency < 444000000) + band = 2; + else if (p->frequency < 861000000) + band = 4; else return -EINVAL; // setup PLL filter - switch (params->u.ofdm.bandwidth) { - case BANDWIDTH_6_MHZ: + switch (p->bandwidth_hz) { + case 6000000: tda1004x_writereg(fe, 0x0C, 0); filter = 0; break; - case BANDWIDTH_7_MHZ: + case 7000000: tda1004x_writereg(fe, 0x0C, 0); filter = 0; break; - case BANDWIDTH_8_MHZ: + case 8000000: tda1004x_writereg(fe, 0x0C, 0xFF); filter = 1; break; @@ -1123,7 +1129,7 @@ static int philips_tdm1316l_tuner_set_params(struct dvb_frontend* fe, struct dvb // calculate divisor // ((36130000+((1000000/6)/2)) + Finput)/(1000000/6) - tuner_frequency = (((params->frequency / 1000) * 6) + 217280) / 1000; + tuner_frequency = (((p->frequency / 1000) * 6) + 217280) / 1000; // setup tuner buffer tuner_buf[0] = tuner_frequency >> 8; @@ -1273,23 +1279,24 @@ static int alps_stv0299_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 return 0; } -static int philips_tsa5059_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) +static int philips_tsa5059_tuner_set_params(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; u8 buf[4]; u32 div; struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) }; - if ((params->frequency < 950000) || (params->frequency > 2150000)) + if ((p->frequency < 950000) || (p->frequency > 2150000)) return -EINVAL; - div = (params->frequency + (125 - 1)) / 125; // round correctly + div = (p->frequency + (125 - 1)) / 125; /* round correctly */ buf[0] = (div >> 8) & 0x7f; buf[1] = div & 0xff; buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4; buf[3] = 0xC4; - if (params->frequency > 1530000) + if (p->frequency > 1530000) buf[3] = 0xC0; /* BSBE1 wants XCE bit set */ @@ -1316,14 +1323,15 @@ static struct stv0299_config alps_stv0299_config = { .set_symbol_rate = alps_stv0299_set_symbol_rate, }; -static int ttusb_novas_grundig_29504_491_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) +static int ttusb_novas_grundig_29504_491_tuner_set_params(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; u8 buf[4]; u32 div; struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) }; - div = params->frequency / 125; + div = p->frequency / 125; buf[0] = (div >> 8) & 0x7f; buf[1] = div & 0xff; @@ -1343,19 +1351,20 @@ static struct tda8083_config ttusb_novas_grundig_29504_491_config = { .demod_address = 0x68, }; -static int alps_tdbe2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) +static int alps_tdbe2_tuner_set_params(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct ttusb* ttusb = fe->dvb->priv; u32 div; u8 data[4]; struct i2c_msg msg = { .addr = 0x62, .flags = 0, .buf = data, .len = sizeof(data) }; - div = (params->frequency + 35937500 + 31250) / 62500; + div = (p->frequency + 35937500 + 31250) / 62500; data[0] = (div >> 8) & 0x7f; data[1] = div & 0xff; data[2] = 0x85 | ((div >> 10) & 0x60); - data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81); + data[3] = (p->frequency < 174000000 ? 0x88 : p->frequency < 470000000 ? 0x84 : 0x81); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); @@ -1387,8 +1396,9 @@ static u8 read_pwm(struct ttusb* ttusb) } -static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) +static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct ttusb *ttusb = (struct ttusb *) fe->dvb->priv; u8 tuner_buf[5]; struct i2c_msg tuner_msg = {.addr = 0x60, @@ -1399,7 +1409,7 @@ static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struc u8 band, cp, filter; // determine charge pump - tuner_frequency = params->frequency; + tuner_frequency = p->frequency; if (tuner_frequency < 87000000) {return -EINVAL;} else if (tuner_frequency < 130000000) {cp = 3; band = 1;} else if (tuner_frequency < 160000000) {cp = 5; band = 1;} @@ -1417,7 +1427,7 @@ static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struc // calculate divisor // (Finput + Fif)/Fref; Fif = 36125000 Hz, Fref = 62500 Hz - tuner_frequency = ((params->frequency + 36125000) / 62500); + tuner_frequency = ((p->frequency + 36125000) / 62500); // setup tuner buffer tuner_buf[0] = tuner_frequency >> 8; @@ -1694,10 +1704,8 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i ttusb->i2c_adap.dev.parent = &udev->dev; result = i2c_add_adapter(&ttusb->i2c_adap); - if (result) { - dvb_unregister_adapter (&ttusb->adapter); - return result; - } + if (result) + goto err_unregister_adapter; memset(&ttusb->dvb_demux, 0, sizeof(ttusb->dvb_demux)); @@ -1714,33 +1722,29 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i ttusb->dvb_demux.stop_feed = ttusb_stop_feed; ttusb->dvb_demux.write_to_decoder = NULL; - if ((result = dvb_dmx_init(&ttusb->dvb_demux)) < 0) { + result = dvb_dmx_init(&ttusb->dvb_demux); + if (result < 0) { printk("ttusb_dvb: dvb_dmx_init failed (errno = %d)\n", result); - i2c_del_adapter(&ttusb->i2c_adap); - dvb_unregister_adapter (&ttusb->adapter); - return -ENODEV; + result = -ENODEV; + goto err_i2c_del_adapter; } //FIXME dmxdev (nur WAS?) ttusb->dmxdev.filternum = ttusb->dvb_demux.filternum; ttusb->dmxdev.demux = &ttusb->dvb_demux.dmx; ttusb->dmxdev.capabilities = 0; - if ((result = dvb_dmxdev_init(&ttusb->dmxdev, &ttusb->adapter)) < 0) { + result = dvb_dmxdev_init(&ttusb->dmxdev, &ttusb->adapter); + if (result < 0) { printk("ttusb_dvb: dvb_dmxdev_init failed (errno = %d)\n", result); - dvb_dmx_release(&ttusb->dvb_demux); - i2c_del_adapter(&ttusb->i2c_adap); - dvb_unregister_adapter (&ttusb->adapter); - return -ENODEV; + result = -ENODEV; + goto err_release_dmx; } if (dvb_net_init(&ttusb->adapter, &ttusb->dvbnet, &ttusb->dvb_demux.dmx)) { printk("ttusb_dvb: dvb_net_init failed!\n"); - dvb_dmxdev_release(&ttusb->dmxdev); - dvb_dmx_release(&ttusb->dvb_demux); - i2c_del_adapter(&ttusb->i2c_adap); - dvb_unregister_adapter (&ttusb->adapter); - return -ENODEV; + result = -ENODEV; + goto err_release_dmxdev; } usb_set_intfdata(intf, (void *) ttusb); @@ -1748,6 +1752,16 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i frontend_init(ttusb); return 0; + +err_release_dmxdev: + dvb_dmxdev_release(&ttusb->dmxdev); +err_release_dmx: + dvb_dmx_release(&ttusb->dvb_demux); +err_i2c_del_adapter: + i2c_del_adapter(&ttusb->i2c_adap); +err_unregister_adapter: + dvb_unregister_adapter (&ttusb->adapter); + return result; } static void ttusb_disconnect(struct usb_interface *intf) diff --git a/drivers/media/dvb/ttusb-dec/ttusbdecfe.c b/drivers/media/dvb/ttusb-dec/ttusbdecfe.c index 21260aad1e54..5c45c9d0712d 100644 --- a/drivers/media/dvb/ttusb-dec/ttusbdecfe.c +++ b/drivers/media/dvb/ttusb-dec/ttusbdecfe.c @@ -87,8 +87,9 @@ static int ttusbdecfe_dvbt_read_status(struct dvb_frontend *fe, return 0; } -static int ttusbdecfe_dvbt_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) +static int ttusbdecfe_dvbt_set_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv; u8 b[] = { 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, @@ -113,8 +114,9 @@ static int ttusbdecfe_dvbt_get_tune_settings(struct dvb_frontend* fe, return 0; } -static int ttusbdecfe_dvbs_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) +static int ttusbdecfe_dvbs_set_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv; u8 b[] = { 0x00, 0x00, 0x00, 0x01, @@ -135,7 +137,7 @@ static int ttusbdecfe_dvbs_set_frontend(struct dvb_frontend* fe, struct dvb_fron freq = htonl(p->frequency + (state->hi_band ? LOF_HI : LOF_LO)); memcpy(&b[4], &freq, sizeof(u32)); - sym_rate = htonl(p->u.qam.symbol_rate); + sym_rate = htonl(p->symbol_rate); memcpy(&b[12], &sym_rate, sizeof(u32)); band = htonl(state->hi_band ? LOF_HI : LOF_LO); memcpy(&b[24], &band, sizeof(u32)); @@ -241,10 +243,9 @@ struct dvb_frontend* ttusbdecfe_dvbs_attach(const struct ttusbdecfe_config* conf } static struct dvb_frontend_ops ttusbdecfe_dvbt_ops = { - + .delsys = { SYS_DVBT }, .info = { .name = "TechnoTrend/Hauppauge DEC2000-t Frontend", - .type = FE_OFDM, .frequency_min = 51000000, .frequency_max = 858000000, .frequency_stepsize = 62500, @@ -265,10 +266,9 @@ static struct dvb_frontend_ops ttusbdecfe_dvbt_ops = { }; static struct dvb_frontend_ops ttusbdecfe_dvbs_ops = { - + .delsys = { SYS_DVBS }, .info = { .name = "TechnoTrend/Hauppauge DEC3000-s Frontend", - .type = FE_QPSK, .frequency_min = 950000, .frequency_max = 2150000, .frequency_stepsize = 125, |