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[] = {
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");
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;
}
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 */
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) {
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 */
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:
}
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)
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;
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)
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;
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;
* 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
*/
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;
}
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)
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;
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++) {
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;
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)
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) &&
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)
if (state->config->tuner_get_status) {
if (state->config->tuner_get_status(fe, ®) < 0)
- goto err;
+ goto err_gateoff;
}
if (reg)
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;
{
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% */
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;
}
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)
} 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)
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 {
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)
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)
if (state->config->tuner_get_status) {
if (state->config->tuner_get_status(fe, ®) < 0)
- goto err;
+ goto err_gateoff;
}
if (reg)
return lock;
+err_gateoff:
+ stv090x_i2c_gate_ctrl(fe, 0);
err:
dprintk(FE_ERROR, 1, "I/O error");
return -1;
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;
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;
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;
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;
}
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;
}
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)
/*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)
/*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;
}
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) +
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)
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)
}
return STV090x_OUTOFRANGE;
+
+err_gateoff:
+ stv090x_i2c_gate_ctrl(fe, 0);
err:
dprintk(FE_ERROR, 1, "I/O error");
return -1;
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;
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 {
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) {
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;
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)) {
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;
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) {
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)
}
- if (state->dev_ver >= 0x20) {
+ if (state->internal->dev_ver >= 0x20) {
if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0)
goto err;
}
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;
{
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);
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;
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)
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)
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)
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),
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 {
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
*/
}
return signal_state;
+err_gateoff:
+ stv090x_i2c_gate_ctrl(fe, 0);
err:
dprintk(FE_ERROR, 1, "I/O error");
return -1;
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;
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;
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;
}
}
}
{
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);
}
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)
{
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:
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)
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;
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)
goto err;
return 0;
+
+err_gateoff:
+ stv090x_i2c_gate_ctrl(fe, 0);
err:
dprintk(FE_ERROR, 1, "I/O error");
return -1;
}
/* 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 */
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;
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:
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)
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");
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;