diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-03-08 23:21:04 +0300 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-03-08 23:21:04 +0300 |
commit | 988addf82e4c03739375279de73929580a2d4a6a (patch) | |
tree | 989ae1cd4e264bbad80c65f04480486246e7b9f3 /drivers/media/dvb/frontends/stv090x.c | |
parent | 004c1c7096659d352b83047a7593e91d8a30e3c5 (diff) | |
parent | 25cf84cf377c0aae5dbcf937ea89bc7893db5176 (diff) | |
download | linux-988addf82e4c03739375279de73929580a2d4a6a.tar.xz |
Merge branch 'origin' into devel-stable
Conflicts:
arch/arm/mach-mx2/devices.c
arch/arm/mach-mx2/devices.h
sound/soc/pxa/pxa-ssp.c
Diffstat (limited to 'drivers/media/dvb/frontends/stv090x.c')
-rw-r--r-- | drivers/media/dvb/frontends/stv090x.c | 486 |
1 files changed, 365 insertions, 121 deletions
diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c index 1573466a5c74..c52c3357dc54 100644 --- a/drivers/media/dvb/frontends/stv090x.c +++ b/drivers/media/dvb/frontends/stv090x.c @@ -37,7 +37,82 @@ static unsigned int verbose; module_param(verbose, int, 0644); -struct mutex demod_lock; +/* internal params node */ +struct stv090x_dev { + /* pointer for internal params, one for each pair of demods */ + struct stv090x_internal *internal; + struct stv090x_dev *next_dev; +}; + +/* first internal params */ +static struct stv090x_dev *stv090x_first_dev; + +/* find chip by i2c adapter and i2c address */ +static struct stv090x_dev *find_dev(struct i2c_adapter *i2c_adap, + u8 i2c_addr) +{ + struct stv090x_dev *temp_dev = stv090x_first_dev; + + /* + Search of the last stv0900 chip or + find it by i2c adapter and i2c address */ + while ((temp_dev != NULL) && + ((temp_dev->internal->i2c_adap != i2c_adap) || + (temp_dev->internal->i2c_addr != i2c_addr))) { + + temp_dev = temp_dev->next_dev; + } + + return temp_dev; +} + +/* deallocating chip */ +static void remove_dev(struct stv090x_internal *internal) +{ + struct stv090x_dev *prev_dev = stv090x_first_dev; + struct stv090x_dev *del_dev = find_dev(internal->i2c_adap, + internal->i2c_addr); + + if (del_dev != NULL) { + if (del_dev == stv090x_first_dev) { + stv090x_first_dev = del_dev->next_dev; + } else { + while (prev_dev->next_dev != del_dev) + prev_dev = prev_dev->next_dev; + + prev_dev->next_dev = del_dev->next_dev; + } + + kfree(del_dev); + } +} + +/* allocating new chip */ +static struct stv090x_dev *append_internal(struct stv090x_internal *internal) +{ + struct stv090x_dev *new_dev; + struct stv090x_dev *temp_dev; + + new_dev = kmalloc(sizeof(struct stv090x_dev), GFP_KERNEL); + if (new_dev != NULL) { + new_dev->internal = internal; + new_dev->next_dev = NULL; + + /* append to list */ + if (stv090x_first_dev == NULL) { + stv090x_first_dev = new_dev; + } else { + temp_dev = stv090x_first_dev; + while (temp_dev->next_dev != NULL) + temp_dev = temp_dev->next_dev; + + temp_dev->next_dev = new_dev; + } + } + + return new_dev; +} + /* DVBS1 and DSS C/N Lookup table */ static const struct stv090x_tab stv090x_s1cn_tab[] = { @@ -683,6 +758,9 @@ static int stv090x_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) struct stv090x_state *state = fe->demodulator_priv; u32 reg; + if (enable) + mutex_lock(&state->internal->tuner_lock); + reg = STV090x_READ_DEMOD(state, I2CRPT); if (enable) { dprintk(FE_DEBUG, 1, "Enable Gate"); @@ -696,9 +774,14 @@ static int stv090x_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) if ((STV090x_WRITE_DEMOD(state, I2CRPT, reg)) < 0) goto err; } + + if (!enable) + mutex_unlock(&state->internal->tuner_lock); + return 0; err: dprintk(FE_ERROR, 1, "I/O error"); + mutex_unlock(&state->internal->tuner_lock); return -1; } @@ -755,13 +838,13 @@ static int stv090x_set_srate(struct stv090x_state *state, u32 srate) if (srate > 60000000) { sym = (srate << 4); /* SR * 2^16 / master_clk */ - sym /= (state->mclk >> 12); + sym /= (state->internal->mclk >> 12); } else if (srate > 6000000) { sym = (srate << 6); - sym /= (state->mclk >> 10); + sym /= (state->internal->mclk >> 10); } else { sym = (srate << 9); - sym /= (state->mclk >> 7); + sym /= (state->internal->mclk >> 7); } if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0x7f) < 0) /* MSB */ @@ -782,13 +865,13 @@ static int stv090x_set_max_srate(struct stv090x_state *state, u32 clk, u32 srate srate = 105 * (srate / 100); if (srate > 60000000) { sym = (srate << 4); /* SR * 2^16 / master_clk */ - sym /= (state->mclk >> 12); + sym /= (state->internal->mclk >> 12); } else if (srate > 6000000) { sym = (srate << 6); - sym /= (state->mclk >> 10); + sym /= (state->internal->mclk >> 10); } else { sym = (srate << 9); - sym /= (state->mclk >> 7); + sym /= (state->internal->mclk >> 7); } if (sym < 0x7fff) { @@ -816,13 +899,13 @@ static int stv090x_set_min_srate(struct stv090x_state *state, u32 clk, u32 srate srate = 95 * (srate / 100); if (srate > 60000000) { sym = (srate << 4); /* SR * 2^16 / master_clk */ - sym /= (state->mclk >> 12); + sym /= (state->internal->mclk >> 12); } else if (srate > 6000000) { sym = (srate << 6); - sym /= (state->mclk >> 10); + sym /= (state->internal->mclk >> 10); } else { sym = (srate << 9); - sym /= (state->mclk >> 7); + sym /= (state->internal->mclk >> 7); } if (STV090x_WRITE_DEMOD(state, SFRLOW1, ((sym >> 8) & 0x7f)) < 0) /* MSB */ @@ -1103,21 +1186,21 @@ static int stv090x_vitclk_ctl(struct stv090x_state *state, int enable) switch (state->demod) { case STV090x_DEMODULATOR_0: - mutex_lock(&demod_lock); + mutex_lock(&state->internal->demod_lock); reg = stv090x_read_reg(state, STV090x_STOPCLK2); STV090x_SETFIELD(reg, STOP_CLKVIT1_FIELD, enable); if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0) goto err; - mutex_unlock(&demod_lock); + mutex_unlock(&state->internal->demod_lock); break; case STV090x_DEMODULATOR_1: - mutex_lock(&demod_lock); + mutex_lock(&state->internal->demod_lock); reg = stv090x_read_reg(state, STV090x_STOPCLK2); STV090x_SETFIELD(reg, STOP_CLKVIT2_FIELD, enable); if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0) goto err; - mutex_unlock(&demod_lock); + mutex_unlock(&state->internal->demod_lock); break; default: @@ -1126,14 +1209,14 @@ static int stv090x_vitclk_ctl(struct stv090x_state *state, int enable) } return 0; err: - mutex_unlock(&demod_lock); + mutex_unlock(&state->internal->demod_lock); dprintk(FE_ERROR, 1, "I/O error"); return -1; } static int stv090x_dvbs_track_crl(struct stv090x_state *state) { - if (state->dev_ver >= 0x30) { + if (state->internal->dev_ver >= 0x30) { /* Set ACLC BCLC optimised value vs SR */ if (state->srate >= 15000000) { if (STV090x_WRITE_DEMOD(state, ACLC, 0x2b) < 0) @@ -1215,7 +1298,7 @@ static int stv090x_delivery_search(struct stv090x_state *state) if (STV090x_WRITE_DEMOD(state, BCLC, 0x09) < 0) goto err; - if (state->dev_ver <= 0x20) { + if (state->internal->dev_ver <= 0x20) { /* enable S2 carrier loop */ if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x26) < 0) goto err; @@ -1246,6 +1329,10 @@ static int stv090x_delivery_search(struct stv090x_state *state) default: /* enable DVB-S2 and DVB-S2 in Auto MODE */ reg = STV090x_READ_DEMOD(state, DMDCFGMD); + STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 0); + STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0); + if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) + goto err; STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1); STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1); if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) @@ -1257,7 +1344,7 @@ static int stv090x_delivery_search(struct stv090x_state *state) if (stv090x_dvbs_track_crl(state) < 0) goto err; - if (state->dev_ver <= 0x20) { + if (state->internal->dev_ver <= 0x20) { /* enable S2 carrier loop */ if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x26) < 0) goto err; @@ -1304,7 +1391,7 @@ static int stv090x_start_search(struct stv090x_state *state) if (STV090x_WRITE_DEMOD(state, DMDISTATE, reg) < 0) goto err; - if (state->dev_ver <= 0x20) { + if (state->internal->dev_ver <= 0x20) { if (state->srate <= 5000000) { if (STV090x_WRITE_DEMOD(state, CARCFG, 0x44) < 0) goto err; @@ -1348,7 +1435,7 @@ static int stv090x_start_search(struct stv090x_state *state) * CFR max = +1MHz */ freq_abs = 1000 << 16; - freq_abs /= (state->mclk / 1000); + freq_abs /= (state->internal->mclk / 1000); freq = (s16) freq_abs; } else { /* COLD Start @@ -1358,7 +1445,7 @@ static int stv090x_start_search(struct stv090x_state *state) */ freq_abs = (state->search_range / 2000) + 600; freq_abs = freq_abs << 16; - freq_abs /= (state->mclk / 1000); + freq_abs /= (state->internal->mclk / 1000); freq = (s16) freq_abs; } @@ -1381,7 +1468,7 @@ static int stv090x_start_search(struct stv090x_state *state) if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0) < 0) goto err; - if (state->dev_ver >= 0x20) { + if (state->internal->dev_ver >= 0x20) { if (STV090x_WRITE_DEMOD(state, EQUALCFG, 0x41) < 0) goto err; if (STV090x_WRITE_DEMOD(state, FFECFG, 0x41) < 0) @@ -1418,10 +1505,10 @@ static int stv090x_start_search(struct stv090x_state *state) if (STV090x_WRITE_DEMOD(state, RTC, 0x88) < 0) goto err; - if (state->dev_ver >= 0x20) { + if (state->internal->dev_ver >= 0x20) { /*Frequency offset detector setting*/ if (state->srate < 2000000) { - if (state->dev_ver <= 0x20) { + if (state->internal->dev_ver <= 0x20) { /* Cut 2 */ if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x39) < 0) goto err; @@ -1512,7 +1599,7 @@ static int stv090x_get_agc2_min_level(struct stv090x_state *state) steps = 1; dir = 1; - freq_step = (1000000 * 256) / (state->mclk / 256); + freq_step = (1000000 * 256) / (state->internal->mclk / 256); freq_init = 0; for (i = 0; i < steps; i++) { @@ -1583,7 +1670,7 @@ static u32 stv090x_srate_srch_coarse(struct stv090x_state *state) u32 srate_coarse = 0, agc2 = 0, car_step = 1200, reg; u32 agc2th; - if (state->dev_ver >= 0x30) + if (state->internal->dev_ver >= 0x30) agc2th = 0x2e00; else agc2th = 0x1f00; @@ -1619,13 +1706,13 @@ static u32 stv090x_srate_srch_coarse(struct stv090x_state *state) if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x50) < 0) goto err; - if (state->dev_ver >= 0x30) { + if (state->internal->dev_ver >= 0x30) { if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x99) < 0) goto err; if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x98) < 0) goto err; - } else if (state->dev_ver >= 0x20) { + } else if (state->internal->dev_ver >= 0x20) { if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x6a) < 0) goto err; if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x95) < 0) @@ -1677,7 +1764,7 @@ static u32 stv090x_srate_srch_coarse(struct stv090x_state *state) STV090x_READ_DEMOD(state, AGC2I0); } agc2 /= 10; - srate_coarse = stv090x_get_srate(state, state->mclk); + srate_coarse = stv090x_get_srate(state, state->internal->mclk); cur_step++; dir *= -1; if ((tmg_cpt >= 5) && (agc2 < agc2th) && @@ -1695,12 +1782,12 @@ static u32 stv090x_srate_srch_coarse(struct stv090x_state *state) if (state->config->tuner_set_frequency) { if (state->config->tuner_set_frequency(fe, freq) < 0) - goto err; + goto err_gateoff; } if (state->config->tuner_set_bandwidth) { if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0) - goto err; + goto err_gateoff; } if (stv090x_i2c_gate_ctrl(fe, 0) < 0) @@ -1713,7 +1800,7 @@ static u32 stv090x_srate_srch_coarse(struct stv090x_state *state) if (state->config->tuner_get_status) { if (state->config->tuner_get_status(fe, ®) < 0) - goto err; + goto err_gateoff; } if (reg) @@ -1729,9 +1816,12 @@ static u32 stv090x_srate_srch_coarse(struct stv090x_state *state) if (!tmg_lock) srate_coarse = 0; else - srate_coarse = stv090x_get_srate(state, state->mclk); + srate_coarse = stv090x_get_srate(state, state->internal->mclk); return srate_coarse; + +err_gateoff: + stv090x_i2c_gate_ctrl(fe, 0); err: dprintk(FE_ERROR, 1, "I/O error"); return -1; @@ -1741,7 +1831,7 @@ static u32 stv090x_srate_srch_fine(struct stv090x_state *state) { u32 srate_coarse, freq_coarse, sym, reg; - srate_coarse = stv090x_get_srate(state, state->mclk); + srate_coarse = stv090x_get_srate(state, state->internal->mclk); freq_coarse = STV090x_READ_DEMOD(state, CFR2) << 8; freq_coarse |= STV090x_READ_DEMOD(state, CFR1); sym = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */ @@ -1767,10 +1857,10 @@ static u32 stv090x_srate_srch_fine(struct stv090x_state *state) if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0) goto err; - if (state->dev_ver >= 0x30) { + if (state->internal->dev_ver >= 0x30) { if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x79) < 0) goto err; - } else if (state->dev_ver >= 0x20) { + } else if (state->internal->dev_ver >= 0x20) { if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0) goto err; } @@ -1778,20 +1868,20 @@ static u32 stv090x_srate_srch_fine(struct stv090x_state *state) if (srate_coarse > 3000000) { sym = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */ sym = (sym / 1000) * 65536; - sym /= (state->mclk / 1000); + sym /= (state->internal->mclk / 1000); if (STV090x_WRITE_DEMOD(state, SFRUP1, (sym >> 8) & 0x7f) < 0) goto err; if (STV090x_WRITE_DEMOD(state, SFRUP0, sym & 0xff) < 0) goto err; sym = 10 * (srate_coarse / 13); /* SFRLOW = SFR - 30% */ sym = (sym / 1000) * 65536; - sym /= (state->mclk / 1000); + sym /= (state->internal->mclk / 1000); if (STV090x_WRITE_DEMOD(state, SFRLOW1, (sym >> 8) & 0x7f) < 0) goto err; if (STV090x_WRITE_DEMOD(state, SFRLOW0, sym & 0xff) < 0) goto err; sym = (srate_coarse / 1000) * 65536; - sym /= (state->mclk / 1000); + sym /= (state->internal->mclk / 1000); if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0xff) < 0) goto err; if (STV090x_WRITE_DEMOD(state, SFRINIT0, sym & 0xff) < 0) @@ -1799,20 +1889,20 @@ static u32 stv090x_srate_srch_fine(struct stv090x_state *state) } else { sym = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */ sym = (sym / 100) * 65536; - sym /= (state->mclk / 100); + sym /= (state->internal->mclk / 100); if (STV090x_WRITE_DEMOD(state, SFRUP1, (sym >> 8) & 0x7f) < 0) goto err; if (STV090x_WRITE_DEMOD(state, SFRUP0, sym & 0xff) < 0) goto err; sym = 10 * (srate_coarse / 14); /* SFRLOW = SFR - 30% */ sym = (sym / 100) * 65536; - sym /= (state->mclk / 100); + sym /= (state->internal->mclk / 100); if (STV090x_WRITE_DEMOD(state, SFRLOW1, (sym >> 8) & 0x7f) < 0) goto err; if (STV090x_WRITE_DEMOD(state, SFRLOW0, sym & 0xff) < 0) goto err; sym = (srate_coarse / 100) * 65536; - sym /= (state->mclk / 100); + sym /= (state->internal->mclk / 100); if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0xff) < 0) goto err; if (STV090x_WRITE_DEMOD(state, SFRINIT0, sym & 0xff) < 0) @@ -1874,18 +1964,19 @@ static int stv090x_blind_search(struct stv090x_state *state) u32 agc2, reg, srate_coarse; s32 cpt_fail, agc2_ovflw, i; u8 k_ref, k_max, k_min; - int coarse_fail, lock; + int coarse_fail = 0; + int lock; k_max = 110; k_min = 10; agc2 = stv090x_get_agc2_min_level(state); - if (agc2 > STV090x_SEARCH_AGC2_TH(state->dev_ver)) { + if (agc2 > STV090x_SEARCH_AGC2_TH(state->internal->dev_ver)) { lock = 0; } else { - if (state->dev_ver <= 0x20) { + if (state->internal->dev_ver <= 0x20) { if (STV090x_WRITE_DEMOD(state, CARCFG, 0xc4) < 0) goto err; } else { @@ -1897,7 +1988,7 @@ static int stv090x_blind_search(struct stv090x_state *state) if (STV090x_WRITE_DEMOD(state, RTCS2, 0x44) < 0) goto err; - if (state->dev_ver >= 0x20) { + if (state->internal->dev_ver >= 0x20) { if (STV090x_WRITE_DEMOD(state, EQUALCFG, 0x41) < 0) goto err; if (STV090x_WRITE_DEMOD(state, FFECFG, 0x41) < 0) @@ -1956,7 +2047,7 @@ static int stv090x_chk_tmg(struct stv090x_state *state) u32 reg; s32 tmg_cpt = 0, i; u8 freq, tmg_thh, tmg_thl; - int tmg_lock; + int tmg_lock = 0; freq = STV090x_READ_DEMOD(state, CARFREQ); tmg_thh = STV090x_READ_DEMOD(state, TMGTHRISE); @@ -2080,12 +2171,12 @@ static int stv090x_get_coldlock(struct stv090x_state *state, s32 timeout_dmd) if (state->config->tuner_set_frequency) { if (state->config->tuner_set_frequency(fe, freq) < 0) - goto err; + goto err_gateoff; } if (state->config->tuner_set_bandwidth) { if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0) - goto err; + goto err_gateoff; } if (stv090x_i2c_gate_ctrl(fe, 0) < 0) @@ -2098,7 +2189,7 @@ static int stv090x_get_coldlock(struct stv090x_state *state, s32 timeout_dmd) if (state->config->tuner_get_status) { if (state->config->tuner_get_status(fe, ®) < 0) - goto err; + goto err_gateoff; } if (reg) @@ -2129,6 +2220,8 @@ static int stv090x_get_coldlock(struct stv090x_state *state, s32 timeout_dmd) return lock; +err_gateoff: + stv090x_i2c_gate_ctrl(fe, 0); err: dprintk(FE_ERROR, 1, "I/O error"); return -1; @@ -2142,13 +2235,13 @@ static int stv090x_get_loop_params(struct stv090x_state *state, s32 *freq_inc, s car_max = state->search_range / 1000; car_max += car_max / 10; car_max = 65536 * (car_max / 2); - car_max /= (state->mclk / 1000); + car_max /= (state->internal->mclk / 1000); if (car_max > 0x4000) car_max = 0x4000 ; /* maxcarrier should be<= +-1/4 Mclk */ inc = srate; - inc /= state->mclk / 1000; + inc /= state->internal->mclk / 1000; inc *= 256; inc *= 256; inc /= 1000; @@ -2209,7 +2302,7 @@ static int stv090x_chk_signal(struct stv090x_state *state) car_max += (car_max / 10); /* 10% margin */ car_max = (65536 * car_max / 2); - car_max /= state->mclk / 1000; + car_max /= state->internal->mclk / 1000; if (car_max > 0x4000) car_max = 0x4000; @@ -2234,7 +2327,7 @@ static int stv090x_search_car_loop(struct stv090x_state *state, s32 inc, s32 tim car_max = state->search_range / 1000; car_max += (car_max / 10); car_max = (65536 * car_max / 2); - car_max /= (state->mclk / 1000); + car_max /= (state->internal->mclk / 1000); if (car_max > 0x4000) car_max = 0x4000; @@ -2304,7 +2397,7 @@ static int stv090x_sw_algo(struct stv090x_state *state) case STV090x_SEARCH_DVBS1: case STV090x_SEARCH_DSS: /* accelerate the frequency detector */ - if (state->dev_ver >= 0x20) { + if (state->internal->dev_ver >= 0x20) { if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x3B) < 0) goto err; } @@ -2315,7 +2408,7 @@ static int stv090x_sw_algo(struct stv090x_state *state) break; case STV090x_SEARCH_DVBS2: - if (state->dev_ver >= 0x20) { + if (state->internal->dev_ver >= 0x20) { if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0) goto err; } @@ -2328,7 +2421,7 @@ static int stv090x_sw_algo(struct stv090x_state *state) case STV090x_SEARCH_AUTO: default: /* accelerate the frequency detector */ - if (state->dev_ver >= 0x20) { + if (state->internal->dev_ver >= 0x20) { if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x3b) < 0) goto err; if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0) @@ -2350,7 +2443,7 @@ static int stv090x_sw_algo(struct stv090x_state *state) /*run the SW search 2 times maximum*/ if (lock || no_signal || (trials == 2)) { /*Check if the demod is not losing lock in DVBS2*/ - if (state->dev_ver >= 0x20) { + if (state->internal->dev_ver >= 0x20) { if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0) goto err; if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x9e) < 0) @@ -2372,7 +2465,7 @@ static int stv090x_sw_algo(struct stv090x_state *state) /*FALSE lock, The demod is loosing lock */ lock = 0; if (trials < 2) { - if (state->dev_ver >= 0x20) { + if (state->internal->dev_ver >= 0x20) { if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0) goto err; } @@ -2422,11 +2515,11 @@ static s32 stv090x_get_car_freq(struct stv090x_state *state, u32 mclk) derot |= STV090x_READ_DEMOD(state, CFR0); derot = comp2(derot, 24); - int_1 = state->mclk >> 12; + int_1 = mclk >> 12; int_2 = derot >> 12; /* carrier_frequency = MasterClock * Reg / 2^24 */ - tmp_1 = state->mclk % 0x1000; + tmp_1 = mclk % 0x1000; tmp_2 = derot % 0x1000; derot = (int_1 * int_2) + @@ -2502,13 +2595,13 @@ static enum stv090x_signal_state stv090x_get_sig_params(struct stv090x_state *st if (state->config->tuner_get_frequency) { if (state->config->tuner_get_frequency(fe, &state->frequency) < 0) - goto err; + goto err_gateoff; } if (stv090x_i2c_gate_ctrl(fe, 0) < 0) goto err; - offst_freq = stv090x_get_car_freq(state, state->mclk) / 1000; + offst_freq = stv090x_get_car_freq(state, state->internal->mclk) / 1000; state->frequency += offst_freq; if (stv090x_get_viterbi(state) < 0) @@ -2530,7 +2623,7 @@ static enum stv090x_signal_state stv090x_get_sig_params(struct stv090x_state *st if (state->config->tuner_get_frequency) { if (state->config->tuner_get_frequency(fe, &state->frequency) < 0) - goto err; + goto err_gateoff; } if (stv090x_i2c_gate_ctrl(fe, 0) < 0) @@ -2550,6 +2643,9 @@ static enum stv090x_signal_state stv090x_get_sig_params(struct stv090x_state *st } return STV090x_OUTOFRANGE; + +err_gateoff: + stv090x_i2c_gate_ctrl(fe, 0); err: dprintk(FE_ERROR, 1, "I/O error"); return -1; @@ -2579,7 +2675,7 @@ static u8 stv090x_optimize_carloop(struct stv090x_state *state, enum stv090x_mod s32 i; struct stv090x_long_frame_crloop *car_loop, *car_loop_qpsk_low, *car_loop_apsk_low; - if (state->dev_ver == 0x20) { + if (state->internal->dev_ver == 0x20) { car_loop = stv090x_s2_crl_cut20; car_loop_qpsk_low = stv090x_s2_lowqpsk_crl_cut20; car_loop_apsk_low = stv090x_s2_apsk_crl_cut20; @@ -2700,7 +2796,7 @@ static u8 stv090x_optimize_carloop_short(struct stv090x_state *state) break; } - if (state->dev_ver >= 0x30) { + if (state->internal->dev_ver >= 0x30) { /* Cut 3.0 and up */ short_crl = stv090x_s2_short_crl_cut30; } else { @@ -2732,7 +2828,7 @@ static int stv090x_optimize_track(struct stv090x_state *state) s32 srate, pilots, aclc, f_1, f_0, i = 0, blind_tune = 0; u32 reg; - srate = stv090x_get_srate(state, state->mclk); + srate = stv090x_get_srate(state, state->internal->mclk); srate += stv090x_get_tmgoffst(state, srate); switch (state->delsys) { @@ -2751,7 +2847,7 @@ static int stv090x_optimize_track(struct stv090x_state *state) if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0) goto err; - if (state->dev_ver >= 0x30) { + if (state->internal->dev_ver >= 0x30) { if (stv090x_get_viterbi(state) < 0) goto err; @@ -2868,7 +2964,7 @@ static int stv090x_optimize_track(struct stv090x_state *state) goto err; } - if (state->dev_ver >= 0x20) { + if (state->internal->dev_ver >= 0x20) { if ((state->search_mode == STV090x_SEARCH_DVBS1) || (state->search_mode == STV090x_SEARCH_DSS) || (state->search_mode == STV090x_SEARCH_AUTO)) { @@ -2890,7 +2986,8 @@ static int stv090x_optimize_track(struct stv090x_state *state) if (STV090x_WRITE_DEMOD(state, SFRLOW1, 0x80) < 0) goto err; - if ((state->dev_ver >= 0x20) || (blind_tune == 1) || (state->srate < 10000000)) { + if ((state->internal->dev_ver >= 0x20) || (blind_tune == 1) || + (state->srate < 10000000)) { /* update initial carrier freq with the found freq offset */ if (STV090x_WRITE_DEMOD(state, CFRINIT1, f_1) < 0) goto err; @@ -2898,7 +2995,7 @@ static int stv090x_optimize_track(struct stv090x_state *state) goto err; state->tuner_bw = stv090x_car_width(srate, state->rolloff) + 10000000; - if ((state->dev_ver >= 0x20) || (blind_tune == 1)) { + if ((state->internal->dev_ver >= 0x20) || (blind_tune == 1)) { if (state->algo != STV090x_WARM_SEARCH) { @@ -2907,7 +3004,7 @@ static int stv090x_optimize_track(struct stv090x_state *state) if (state->config->tuner_set_bandwidth) { if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0) - goto err; + goto err_gateoff; } if (stv090x_i2c_gate_ctrl(fe, 0) < 0) @@ -2950,7 +3047,7 @@ static int stv090x_optimize_track(struct stv090x_state *state) } - if (state->dev_ver >= 0x20) { + if (state->internal->dev_ver >= 0x20) { if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0) goto err; } @@ -2959,6 +3056,9 @@ static int stv090x_optimize_track(struct stv090x_state *state) stv090x_set_vit_thtracq(state); return 0; + +err_gateoff: + stv090x_i2c_gate_ctrl(fe, 0); err: dprintk(FE_ERROR, 1, "I/O error"); return -1; @@ -3026,7 +3126,7 @@ static int stv090x_set_s2rolloff(struct stv090x_state *state) { u32 reg; - if (state->dev_ver <= 0x20) { + if (state->internal->dev_ver <= 0x20) { /* rolloff to auto mode if DVBS2 */ reg = STV090x_READ_DEMOD(state, DEMOD); STV090x_SETFIELD_Px(reg, MANUAL_SXROLLOFF_FIELD, 0x00); @@ -3062,7 +3162,7 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5c) < 0) /* Demod stop */ goto err; - if (state->dev_ver >= 0x20) { + if (state->internal->dev_ver >= 0x20) { if (state->srate > 5000000) { if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x9e) < 0) goto err; @@ -3102,7 +3202,7 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0) goto err; - if (state->dev_ver >= 0x20) { + if (state->internal->dev_ver >= 0x20) { if (STV090x_WRITE_DEMOD(state, KREFTMG, 0x5a) < 0) goto err; if (state->algo == STV090x_COLD_SEARCH) @@ -3120,9 +3220,11 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) if (stv090x_set_srate(state, state->srate) < 0) goto err; - if (stv090x_set_max_srate(state, state->mclk, state->srate) < 0) + if (stv090x_set_max_srate(state, state->internal->mclk, + state->srate) < 0) goto err; - if (stv090x_set_min_srate(state, state->mclk, state->srate) < 0) + if (stv090x_set_min_srate(state, state->internal->mclk, + state->srate) < 0) goto err; if (state->srate >= 10000000) @@ -3136,18 +3238,21 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) goto err; if (state->config->tuner_set_bbgain) { - if (state->config->tuner_set_bbgain(fe, 10) < 0) /* 10dB */ - goto err; + reg = state->config->tuner_bbgain; + if (reg == 0) + reg = 10; /* default: 10dB */ + if (state->config->tuner_set_bbgain(fe, reg) < 0) + goto err_gateoff; } if (state->config->tuner_set_frequency) { if (state->config->tuner_set_frequency(fe, state->frequency) < 0) - goto err; + goto err_gateoff; } if (state->config->tuner_set_bandwidth) { if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0) - goto err; + goto err_gateoff; } if (stv090x_i2c_gate_ctrl(fe, 0) < 0) @@ -3155,21 +3260,21 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) msleep(50); - if (stv090x_i2c_gate_ctrl(fe, 1) < 0) - goto err; - if (state->config->tuner_get_status) { + if (stv090x_i2c_gate_ctrl(fe, 1) < 0) + goto err; if (state->config->tuner_get_status(fe, ®) < 0) + goto err_gateoff; + if (stv090x_i2c_gate_ctrl(fe, 0) < 0) goto err; - } - if (reg) - dprintk(FE_DEBUG, 1, "Tuner phase locked"); - else - dprintk(FE_DEBUG, 1, "Tuner unlocked"); - - if (stv090x_i2c_gate_ctrl(fe, 0) < 0) - goto err; + if (reg) + dprintk(FE_DEBUG, 1, "Tuner phase locked"); + else { + dprintk(FE_DEBUG, 1, "Tuner unlocked"); + return STV090x_NOCARRIER; + } + } msleep(10); agc1_power = MAKEWORD16(STV090x_READ_DEMOD(state, AGCIQIN1), @@ -3194,7 +3299,7 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) reg = STV090x_READ_DEMOD(state, DEMOD); STV090x_SETFIELD_Px(reg, SPECINV_CONTROL_FIELD, state->inversion); - if (state->dev_ver <= 0x20) { + if (state->internal->dev_ver <= 0x20) { /* rolloff to auto mode if DVBS2 */ STV090x_SETFIELD_Px(reg, MANUAL_SXROLLOFF_FIELD, 1); } else { @@ -3238,7 +3343,7 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) if ((lock) && (signal_state == STV090x_RANGEOK)) { /* signal within Range */ stv090x_optimize_track(state); - if (state->dev_ver >= 0x20) { + if (state->internal->dev_ver >= 0x20) { /* >= Cut 2.0 :release TS reset after * demod lock and optimized Tracking */ @@ -3293,6 +3398,8 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) } return signal_state; +err_gateoff: + stv090x_i2c_gate_ctrl(fe, 0); err: dprintk(FE_ERROR, 1, "I/O error"); return -1; @@ -3303,6 +3410,9 @@ static enum dvbfe_search stv090x_search(struct dvb_frontend *fe, struct dvb_fron struct stv090x_state *state = fe->demodulator_priv; struct dtv_frontend_properties *props = &fe->dtv_property_cache; + if (p->frequency == 0) + return DVBFE_ALGO_SEARCH_INVALID; + state->delsys = props->delivery_system; state->frequency = p->frequency; state->srate = p->u.qpsk.symbol_rate; @@ -3353,7 +3463,8 @@ static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status) if (STV090x_GETFIELD_Px(reg, PKTDELIN_LOCK_FIELD)) { reg = STV090x_READ_DEMOD(state, TSSTATUS); if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD)) { - *status = FE_HAS_CARRIER | + *status = FE_HAS_SIGNAL | + FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; @@ -3370,7 +3481,11 @@ static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status) if (STV090x_GETFIELD_Px(reg, LOCKEDVIT_FIELD)) { reg = STV090x_READ_DEMOD(state, TSSTATUS); if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD)) { - *status = FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; + *status = FE_HAS_SIGNAL | + FE_HAS_CARRIER | + FE_HAS_VITERBI | + FE_HAS_SYNC | + FE_HAS_LOCK; } } } @@ -3770,6 +3885,15 @@ static void stv090x_release(struct dvb_frontend *fe) { struct stv090x_state *state = fe->demodulator_priv; + state->internal->num_used--; + if (state->internal->num_used <= 0) { + + dprintk(FE_ERROR, 1, "Actually removing"); + + remove_dev(state->internal); + kfree(state->internal); + } + kfree(state); } @@ -3901,10 +4025,10 @@ static int stv090x_set_mclk(struct stv090x_state *state, u32 mclk, u32 clk) if (stv090x_write_reg(state, STV090x_NCOARSE, reg) < 0) goto err; - state->mclk = stv090x_get_mclk(state); + state->internal->mclk = stv090x_get_mclk(state); /*Set the DiseqC frequency to 22KHz */ - div = state->mclk / 704000; + div = state->internal->mclk / 704000; if (STV090x_WRITE_DEMOD(state, F22TX, div) < 0) goto err; if (STV090x_WRITE_DEMOD(state, F22RX, div) < 0) @@ -3920,7 +4044,7 @@ static int stv090x_set_tspath(struct stv090x_state *state) { u32 reg; - if (state->dev_ver >= 0x20) { + if (state->internal->dev_ver >= 0x20) { switch (state->config->ts1_mode) { case STV090x_TSMODE_PARALLEL_PUNCTURED: case STV090x_TSMODE_DVBCI: @@ -4092,6 +4216,71 @@ static int stv090x_set_tspath(struct stv090x_state *state) default: break; } + + if (state->config->ts1_clk > 0) { + u32 speed; + + switch (state->config->ts1_mode) { + case STV090x_TSMODE_PARALLEL_PUNCTURED: + case STV090x_TSMODE_DVBCI: + default: + speed = state->internal->mclk / + (state->config->ts1_clk / 4); + if (speed < 0x08) + speed = 0x08; + if (speed > 0xFF) + speed = 0xFF; + break; + case STV090x_TSMODE_SERIAL_PUNCTURED: + case STV090x_TSMODE_SERIAL_CONTINUOUS: + speed = state->internal->mclk / + (state->config->ts1_clk / 32); + if (speed < 0x20) + speed = 0x20; + if (speed > 0xFF) + speed = 0xFF; + break; + } + reg = stv090x_read_reg(state, STV090x_P1_TSCFGM); + STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3); + if (stv090x_write_reg(state, STV090x_P1_TSCFGM, reg) < 0) + goto err; + if (stv090x_write_reg(state, STV090x_P1_TSSPEED, speed) < 0) + goto err; + } + + if (state->config->ts2_clk > 0) { + u32 speed; + + switch (state->config->ts2_mode) { + case STV090x_TSMODE_PARALLEL_PUNCTURED: + case STV090x_TSMODE_DVBCI: + default: + speed = state->internal->mclk / + (state->config->ts2_clk / 4); + if (speed < 0x08) + speed = 0x08; + if (speed > 0xFF) + speed = 0xFF; + break; + case STV090x_TSMODE_SERIAL_PUNCTURED: + case STV090x_TSMODE_SERIAL_CONTINUOUS: + speed = state->internal->mclk / + (state->config->ts2_clk / 32); + if (speed < 0x20) + speed = 0x20; + if (speed > 0xFF) + speed = 0xFF; + break; + } + reg = stv090x_read_reg(state, STV090x_P2_TSCFGM); + STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3); + if (stv090x_write_reg(state, STV090x_P2_TSCFGM, reg) < 0) + goto err; + if (stv090x_write_reg(state, STV090x_P2_TSSPEED, speed) < 0) + goto err; + } + reg = stv090x_read_reg(state, STV090x_P2_TSCFGH); STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x01); if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0) @@ -4120,6 +4309,15 @@ static int stv090x_init(struct dvb_frontend *fe) const struct stv090x_config *config = state->config; u32 reg; + if (state->internal->mclk == 0) { + stv090x_set_mclk(state, 135000000, config->xtal); /* 135 Mhz */ + msleep(5); + if (stv090x_write_reg(state, STV090x_SYNTCTRL, + 0x20 | config->clk_mode) < 0) + goto err; + stv090x_get_mclk(state); + } + if (stv090x_wakeup(fe) < 0) { dprintk(FE_ERROR, 1, "Error waking device"); goto err; @@ -4142,12 +4340,12 @@ static int stv090x_init(struct dvb_frontend *fe) if (config->tuner_set_mode) { if (config->tuner_set_mode(fe, TUNER_WAKE) < 0) - goto err; + goto err_gateoff; } if (config->tuner_init) { if (config->tuner_init(fe) < 0) - goto err; + goto err_gateoff; } if (stv090x_i2c_gate_ctrl(fe, 0) < 0) @@ -4157,6 +4355,9 @@ static int stv090x_init(struct dvb_frontend *fe) goto err; return 0; + +err_gateoff: + stv090x_i2c_gate_ctrl(fe, 0); err: dprintk(FE_ERROR, 1, "I/O error"); return -1; @@ -4188,16 +4389,26 @@ static int stv090x_setup(struct dvb_frontend *fe) } /* STV090x init */ - if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5c) < 0) /* Stop Demod */ + + /* Stop Demod */ + if (stv090x_write_reg(state, STV090x_P1_DMDISTATE, 0x5c) < 0) + goto err; + if (stv090x_write_reg(state, STV090x_P2_DMDISTATE, 0x5c) < 0) goto err; msleep(5); - if (STV090x_WRITE_DEMOD(state, TNRCFG, 0x6c) < 0) /* check register ! (No Tuner Mode) */ + /* Set No Tuner Mode */ + if (stv090x_write_reg(state, STV090x_P1_TNRCFG, 0x6c) < 0) + goto err; + if (stv090x_write_reg(state, STV090x_P2_TNRCFG, 0x6c) < 0) goto err; + /* I2C repeater OFF */ STV090x_SETFIELD_Px(reg, ENARPT_LEVEL_FIELD, config->repeater_level); - if (STV090x_WRITE_DEMOD(state, I2CRPT, reg) < 0) /* repeater OFF */ + if (stv090x_write_reg(state, STV090x_P1_I2CRPT, reg) < 0) + goto err; + if (stv090x_write_reg(state, STV090x_P2_I2CRPT, reg) < 0) goto err; if (stv090x_write_reg(state, STV090x_NCOARSE, 0x13) < 0) /* set PLL divider */ @@ -4216,8 +4427,8 @@ static int stv090x_setup(struct dvb_frontend *fe) goto err; } - state->dev_ver = stv090x_read_reg(state, STV090x_MID); - if (state->dev_ver >= 0x20) { + state->internal->dev_ver = stv090x_read_reg(state, STV090x_MID); + if (state->internal->dev_ver >= 0x20) { if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x0c) < 0) goto err; @@ -4228,27 +4439,35 @@ static int stv090x_setup(struct dvb_frontend *fe) goto err; } - } else if (state->dev_ver < 0x20) { + } else if (state->internal->dev_ver < 0x20) { dprintk(FE_ERROR, 1, "ERROR: Unsupported Cut: 0x%02x!", - state->dev_ver); + state->internal->dev_ver); goto err; - } else if (state->dev_ver > 0x30) { + } else if (state->internal->dev_ver > 0x30) { /* we shouldn't bail out from here */ dprintk(FE_ERROR, 1, "INFO: Cut: 0x%02x probably incomplete support!", - state->dev_ver); + state->internal->dev_ver); } - if (stv090x_write_reg(state, STV090x_TSTRES0, 0x80) < 0) + /* ADC1 range */ + reg = stv090x_read_reg(state, STV090x_TSTTNR1); + STV090x_SETFIELD(reg, ADC1_INMODE_FIELD, + (config->adc1_range == STV090x_ADC_1Vpp) ? 0 : 1); + if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0) goto err; - if (stv090x_write_reg(state, STV090x_TSTRES0, 0x00) < 0) + + /* ADC2 range */ + reg = stv090x_read_reg(state, STV090x_TSTTNR3); + STV090x_SETFIELD(reg, ADC2_INMODE_FIELD, + (config->adc2_range == STV090x_ADC_1Vpp) ? 0 : 1); + if (stv090x_write_reg(state, STV090x_TSTTNR3, reg) < 0) goto err; - stv090x_set_mclk(state, 135000000, config->xtal); /* 135 Mhz */ - msleep(5); - if (stv090x_write_reg(state, STV090x_SYNTCTRL, 0x20 | config->clk_mode) < 0) + if (stv090x_write_reg(state, STV090x_TSTRES0, 0x80) < 0) + goto err; + if (stv090x_write_reg(state, STV090x_TSTRES0, 0x00) < 0) goto err; - stv090x_get_mclk(state); return 0; err: @@ -4299,6 +4518,7 @@ struct dvb_frontend *stv090x_attach(const struct stv090x_config *config, enum stv090x_demodulator demod) { struct stv090x_state *state = NULL; + struct stv090x_dev *temp_int; state = kzalloc(sizeof (struct stv090x_state), GFP_KERNEL); if (state == NULL) @@ -4314,8 +4534,32 @@ struct dvb_frontend *stv090x_attach(const struct stv090x_config *config, state->device = config->device; state->rolloff = STV090x_RO_35; /* default */ - if (state->demod == STV090x_DEMODULATOR_0) - mutex_init(&demod_lock); + temp_int = find_dev(state->i2c, + state->config->address); + + if ((temp_int != NULL) && (state->demod_mode == STV090x_DUAL)) { + state->internal = temp_int->internal; + state->internal->num_used++; + dprintk(FE_INFO, 1, "Found Internal Structure!"); + dprintk(FE_ERROR, 1, "Attaching %s demodulator(%d) Cut=0x%02x", + state->device == STV0900 ? "STV0900" : "STV0903", + demod, + state->internal->dev_ver); + return &state->frontend; + } else { + state->internal = kmalloc(sizeof(struct stv090x_internal), + GFP_KERNEL); + temp_int = append_internal(state->internal); + state->internal->num_used = 1; + state->internal->mclk = 0; + state->internal->dev_ver = 0; + state->internal->i2c_adap = state->i2c; + state->internal->i2c_addr = state->config->address; + dprintk(FE_INFO, 1, "Create New Internal Structure!"); + } + + mutex_init(&state->internal->demod_lock); + mutex_init(&state->internal->tuner_lock); if (stv090x_sleep(&state->frontend) < 0) { dprintk(FE_ERROR, 1, "Error putting device to sleep"); @@ -4331,10 +4575,10 @@ struct dvb_frontend *stv090x_attach(const struct stv090x_config *config, goto error; } - dprintk(FE_ERROR, 1, "Attaching %s demodulator(%d) Cut=0x%02x\n", + dprintk(FE_ERROR, 1, "Attaching %s demodulator(%d) Cut=0x%02x", state->device == STV0900 ? "STV0900" : "STV0903", demod, - state->dev_ver); + state->internal->dev_ver); return &state->frontend; |