Commit 97f7a2ae authored by Andreas Regel's avatar Andreas Regel Committed by Mauro Carvalho Chehab

V4L/DVB (13975): [STV090x] Added internal structure with shared settings and data.

As the STV0900 features two demodulation paths in one chip there is
some information used by both instances of the driver when used in
dual mode. This information is now shared in an internal structure
referenced by I2C adapter and address.

Do initialisation of the demodulator only once when used in dual mode.
Moved global mutex demod_lock to internal structure.
Moved dev_ver and mclk to internal structure.
Removed unused tuner_refclk from stv090x_state.
Signed-off-by: default avatarAndreas Regel <andreas.regel@gmx.de>
Signed-off-by: default avatarManu Abraham <manu@linuxtv.org>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent b79c6df7
...@@ -37,7 +37,82 @@ ...@@ -37,7 +37,82 @@
static unsigned int verbose; static unsigned int verbose;
module_param(verbose, int, 0644); 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 */ /* DVBS1 and DSS C/N Lookup table */
static const struct stv090x_tab stv090x_s1cn_tab[] = { static const struct stv090x_tab stv090x_s1cn_tab[] = {
...@@ -755,13 +830,13 @@ static int stv090x_set_srate(struct stv090x_state *state, u32 srate) ...@@ -755,13 +830,13 @@ static int stv090x_set_srate(struct stv090x_state *state, u32 srate)
if (srate > 60000000) { if (srate > 60000000) {
sym = (srate << 4); /* SR * 2^16 / master_clk */ sym = (srate << 4); /* SR * 2^16 / master_clk */
sym /= (state->mclk >> 12); sym /= (state->internal->mclk >> 12);
} else if (srate > 6000000) { } else if (srate > 6000000) {
sym = (srate << 6); sym = (srate << 6);
sym /= (state->mclk >> 10); sym /= (state->internal->mclk >> 10);
} else { } else {
sym = (srate << 9); sym = (srate << 9);
sym /= (state->mclk >> 7); sym /= (state->internal->mclk >> 7);
} }
if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0x7f) < 0) /* MSB */ if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0x7f) < 0) /* MSB */
...@@ -782,13 +857,13 @@ static int stv090x_set_max_srate(struct stv090x_state *state, u32 clk, u32 srate ...@@ -782,13 +857,13 @@ static int stv090x_set_max_srate(struct stv090x_state *state, u32 clk, u32 srate
srate = 105 * (srate / 100); srate = 105 * (srate / 100);
if (srate > 60000000) { if (srate > 60000000) {
sym = (srate << 4); /* SR * 2^16 / master_clk */ sym = (srate << 4); /* SR * 2^16 / master_clk */
sym /= (state->mclk >> 12); sym /= (state->internal->mclk >> 12);
} else if (srate > 6000000) { } else if (srate > 6000000) {
sym = (srate << 6); sym = (srate << 6);
sym /= (state->mclk >> 10); sym /= (state->internal->mclk >> 10);
} else { } else {
sym = (srate << 9); sym = (srate << 9);
sym /= (state->mclk >> 7); sym /= (state->internal->mclk >> 7);
} }
if (sym < 0x7fff) { if (sym < 0x7fff) {
...@@ -816,13 +891,13 @@ static int stv090x_set_min_srate(struct stv090x_state *state, u32 clk, u32 srate ...@@ -816,13 +891,13 @@ static int stv090x_set_min_srate(struct stv090x_state *state, u32 clk, u32 srate
srate = 95 * (srate / 100); srate = 95 * (srate / 100);
if (srate > 60000000) { if (srate > 60000000) {
sym = (srate << 4); /* SR * 2^16 / master_clk */ sym = (srate << 4); /* SR * 2^16 / master_clk */
sym /= (state->mclk >> 12); sym /= (state->internal->mclk >> 12);
} else if (srate > 6000000) { } else if (srate > 6000000) {
sym = (srate << 6); sym = (srate << 6);
sym /= (state->mclk >> 10); sym /= (state->internal->mclk >> 10);
} else { } else {
sym = (srate << 9); sym = (srate << 9);
sym /= (state->mclk >> 7); sym /= (state->internal->mclk >> 7);
} }
if (STV090x_WRITE_DEMOD(state, SFRLOW1, ((sym >> 8) & 0x7f)) < 0) /* MSB */ if (STV090x_WRITE_DEMOD(state, SFRLOW1, ((sym >> 8) & 0x7f)) < 0) /* MSB */
...@@ -1103,21 +1178,21 @@ static int stv090x_vitclk_ctl(struct stv090x_state *state, int enable) ...@@ -1103,21 +1178,21 @@ static int stv090x_vitclk_ctl(struct stv090x_state *state, int enable)
switch (state->demod) { switch (state->demod) {
case STV090x_DEMODULATOR_0: case STV090x_DEMODULATOR_0:
mutex_lock(&demod_lock); mutex_lock(&state->internal->demod_lock);
reg = stv090x_read_reg(state, STV090x_STOPCLK2); reg = stv090x_read_reg(state, STV090x_STOPCLK2);
STV090x_SETFIELD(reg, STOP_CLKVIT1_FIELD, enable); STV090x_SETFIELD(reg, STOP_CLKVIT1_FIELD, enable);
if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0) if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
goto err; goto err;
mutex_unlock(&demod_lock); mutex_unlock(&state->internal->demod_lock);
break; break;
case STV090x_DEMODULATOR_1: case STV090x_DEMODULATOR_1:
mutex_lock(&demod_lock); mutex_lock(&state->internal->demod_lock);
reg = stv090x_read_reg(state, STV090x_STOPCLK2); reg = stv090x_read_reg(state, STV090x_STOPCLK2);
STV090x_SETFIELD(reg, STOP_CLKVIT2_FIELD, enable); STV090x_SETFIELD(reg, STOP_CLKVIT2_FIELD, enable);
if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0) if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
goto err; goto err;
mutex_unlock(&demod_lock); mutex_unlock(&state->internal->demod_lock);
break; break;
default: default:
...@@ -1126,14 +1201,14 @@ static int stv090x_vitclk_ctl(struct stv090x_state *state, int enable) ...@@ -1126,14 +1201,14 @@ static int stv090x_vitclk_ctl(struct stv090x_state *state, int enable)
} }
return 0; return 0;
err: err:
mutex_unlock(&demod_lock); mutex_unlock(&state->internal->demod_lock);
dprintk(FE_ERROR, 1, "I/O error"); dprintk(FE_ERROR, 1, "I/O error");
return -1; return -1;
} }
static int stv090x_dvbs_track_crl(struct stv090x_state *state) 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 */ /* Set ACLC BCLC optimised value vs SR */
if (state->srate >= 15000000) { if (state->srate >= 15000000) {
if (STV090x_WRITE_DEMOD(state, ACLC, 0x2b) < 0) if (STV090x_WRITE_DEMOD(state, ACLC, 0x2b) < 0)
...@@ -1215,7 +1290,7 @@ static int stv090x_delivery_search(struct stv090x_state *state) ...@@ -1215,7 +1290,7 @@ static int stv090x_delivery_search(struct stv090x_state *state)
if (STV090x_WRITE_DEMOD(state, BCLC, 0x09) < 0) if (STV090x_WRITE_DEMOD(state, BCLC, 0x09) < 0)
goto err; goto err;
if (state->dev_ver <= 0x20) { if (state->internal->dev_ver <= 0x20) {
/* enable S2 carrier loop */ /* enable S2 carrier loop */
if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x26) < 0) if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x26) < 0)
goto err; goto err;
...@@ -1261,7 +1336,7 @@ static int stv090x_delivery_search(struct stv090x_state *state) ...@@ -1261,7 +1336,7 @@ static int stv090x_delivery_search(struct stv090x_state *state)
if (stv090x_dvbs_track_crl(state) < 0) if (stv090x_dvbs_track_crl(state) < 0)
goto err; goto err;
if (state->dev_ver <= 0x20) { if (state->internal->dev_ver <= 0x20) {
/* enable S2 carrier loop */ /* enable S2 carrier loop */
if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x26) < 0) if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x26) < 0)
goto err; goto err;
...@@ -1308,7 +1383,7 @@ static int stv090x_start_search(struct stv090x_state *state) ...@@ -1308,7 +1383,7 @@ static int stv090x_start_search(struct stv090x_state *state)
if (STV090x_WRITE_DEMOD(state, DMDISTATE, reg) < 0) if (STV090x_WRITE_DEMOD(state, DMDISTATE, reg) < 0)
goto err; goto err;
if (state->dev_ver <= 0x20) { if (state->internal->dev_ver <= 0x20) {
if (state->srate <= 5000000) { if (state->srate <= 5000000) {
if (STV090x_WRITE_DEMOD(state, CARCFG, 0x44) < 0) if (STV090x_WRITE_DEMOD(state, CARCFG, 0x44) < 0)
goto err; goto err;
...@@ -1352,7 +1427,7 @@ static int stv090x_start_search(struct stv090x_state *state) ...@@ -1352,7 +1427,7 @@ static int stv090x_start_search(struct stv090x_state *state)
* CFR max = +1MHz * CFR max = +1MHz
*/ */
freq_abs = 1000 << 16; freq_abs = 1000 << 16;
freq_abs /= (state->mclk / 1000); freq_abs /= (state->internal->mclk / 1000);
freq = (s16) freq_abs; freq = (s16) freq_abs;
} else { } else {
/* COLD Start /* COLD Start
...@@ -1362,7 +1437,7 @@ static int stv090x_start_search(struct stv090x_state *state) ...@@ -1362,7 +1437,7 @@ static int stv090x_start_search(struct stv090x_state *state)
*/ */
freq_abs = (state->search_range / 2000) + 600; freq_abs = (state->search_range / 2000) + 600;
freq_abs = freq_abs << 16; freq_abs = freq_abs << 16;
freq_abs /= (state->mclk / 1000); freq_abs /= (state->internal->mclk / 1000);
freq = (s16) freq_abs; freq = (s16) freq_abs;
} }
...@@ -1385,7 +1460,7 @@ static int stv090x_start_search(struct stv090x_state *state) ...@@ -1385,7 +1460,7 @@ static int stv090x_start_search(struct stv090x_state *state)
if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0) < 0) if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0) < 0)
goto err; goto err;
if (state->dev_ver >= 0x20) { if (state->internal->dev_ver >= 0x20) {
if (STV090x_WRITE_DEMOD(state, EQUALCFG, 0x41) < 0) if (STV090x_WRITE_DEMOD(state, EQUALCFG, 0x41) < 0)
goto err; goto err;
if (STV090x_WRITE_DEMOD(state, FFECFG, 0x41) < 0) if (STV090x_WRITE_DEMOD(state, FFECFG, 0x41) < 0)
...@@ -1422,10 +1497,10 @@ static int stv090x_start_search(struct stv090x_state *state) ...@@ -1422,10 +1497,10 @@ static int stv090x_start_search(struct stv090x_state *state)
if (STV090x_WRITE_DEMOD(state, RTC, 0x88) < 0) if (STV090x_WRITE_DEMOD(state, RTC, 0x88) < 0)
goto err; goto err;
if (state->dev_ver >= 0x20) { if (state->internal->dev_ver >= 0x20) {
/*Frequency offset detector setting*/ /*Frequency offset detector setting*/
if (state->srate < 2000000) { if (state->srate < 2000000) {
if (state->dev_ver <= 0x20) { if (state->internal->dev_ver <= 0x20) {
/* Cut 2 */ /* Cut 2 */
if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x39) < 0) if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x39) < 0)
goto err; goto err;
...@@ -1516,7 +1591,7 @@ static int stv090x_get_agc2_min_level(struct stv090x_state *state) ...@@ -1516,7 +1591,7 @@ static int stv090x_get_agc2_min_level(struct stv090x_state *state)
steps = 1; steps = 1;
dir = 1; dir = 1;
freq_step = (1000000 * 256) / (state->mclk / 256); freq_step = (1000000 * 256) / (state->internal->mclk / 256);
freq_init = 0; freq_init = 0;
for (i = 0; i < steps; i++) { for (i = 0; i < steps; i++) {
...@@ -1587,7 +1662,7 @@ static u32 stv090x_srate_srch_coarse(struct stv090x_state *state) ...@@ -1587,7 +1662,7 @@ static u32 stv090x_srate_srch_coarse(struct stv090x_state *state)
u32 srate_coarse = 0, agc2 = 0, car_step = 1200, reg; u32 srate_coarse = 0, agc2 = 0, car_step = 1200, reg;
u32 agc2th; u32 agc2th;
if (state->dev_ver >= 0x30) if (state->internal->dev_ver >= 0x30)
agc2th = 0x2e00; agc2th = 0x2e00;
else else
agc2th = 0x1f00; agc2th = 0x1f00;
...@@ -1623,13 +1698,13 @@ static u32 stv090x_srate_srch_coarse(struct stv090x_state *state) ...@@ -1623,13 +1698,13 @@ static u32 stv090x_srate_srch_coarse(struct stv090x_state *state)
if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x50) < 0) if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x50) < 0)
goto err; goto err;
if (state->dev_ver >= 0x30) { if (state->internal->dev_ver >= 0x30) {
if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x99) < 0) if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x99) < 0)
goto err; goto err;
if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x98) < 0) if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x98) < 0)
goto err; goto err;
} else if (state->dev_ver >= 0x20) { } else if (state->internal->dev_ver >= 0x20) {
if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x6a) < 0) if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x6a) < 0)
goto err; goto err;
if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x95) < 0) if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x95) < 0)
...@@ -1681,7 +1756,7 @@ static u32 stv090x_srate_srch_coarse(struct stv090x_state *state) ...@@ -1681,7 +1756,7 @@ static u32 stv090x_srate_srch_coarse(struct stv090x_state *state)
STV090x_READ_DEMOD(state, AGC2I0); STV090x_READ_DEMOD(state, AGC2I0);
} }
agc2 /= 10; agc2 /= 10;
srate_coarse = stv090x_get_srate(state, state->mclk); srate_coarse = stv090x_get_srate(state, state->internal->mclk);
cur_step++; cur_step++;
dir *= -1; dir *= -1;
if ((tmg_cpt >= 5) && (agc2 < agc2th) && if ((tmg_cpt >= 5) && (agc2 < agc2th) &&
...@@ -1733,7 +1808,7 @@ static u32 stv090x_srate_srch_coarse(struct stv090x_state *state) ...@@ -1733,7 +1808,7 @@ static u32 stv090x_srate_srch_coarse(struct stv090x_state *state)
if (!tmg_lock) if (!tmg_lock)
srate_coarse = 0; srate_coarse = 0;
else else
srate_coarse = stv090x_get_srate(state, state->mclk); srate_coarse = stv090x_get_srate(state, state->internal->mclk);
return srate_coarse; return srate_coarse;
err: err:
...@@ -1745,7 +1820,7 @@ static u32 stv090x_srate_srch_fine(struct stv090x_state *state) ...@@ -1745,7 +1820,7 @@ static u32 stv090x_srate_srch_fine(struct stv090x_state *state)
{ {
u32 srate_coarse, freq_coarse, sym, reg; 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, CFR2) << 8;
freq_coarse |= STV090x_READ_DEMOD(state, CFR1); freq_coarse |= STV090x_READ_DEMOD(state, CFR1);
sym = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */ sym = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */
...@@ -1771,10 +1846,10 @@ static u32 stv090x_srate_srch_fine(struct stv090x_state *state) ...@@ -1771,10 +1846,10 @@ static u32 stv090x_srate_srch_fine(struct stv090x_state *state)
if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0) if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0)
goto err; goto err;
if (state->dev_ver >= 0x30) { if (state->internal->dev_ver >= 0x30) {
if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x79) < 0) if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x79) < 0)
goto err; goto err;
} else if (state->dev_ver >= 0x20) { } else if (state->internal->dev_ver >= 0x20) {
if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0) if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0)
goto err; goto err;
} }
...@@ -1782,20 +1857,20 @@ static u32 stv090x_srate_srch_fine(struct stv090x_state *state) ...@@ -1782,20 +1857,20 @@ static u32 stv090x_srate_srch_fine(struct stv090x_state *state)
if (srate_coarse > 3000000) { if (srate_coarse > 3000000) {
sym = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */ sym = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */
sym = (sym / 1000) * 65536; sym = (sym / 1000) * 65536;
sym /= (state->mclk / 1000); sym /= (state->internal->mclk / 1000);
if (STV090x_WRITE_DEMOD(state, SFRUP1, (sym >> 8) & 0x7f) < 0) if (STV090x_WRITE_DEMOD(state, SFRUP1, (sym >> 8) & 0x7f) < 0)
goto err; goto err;
if (STV090x_WRITE_DEMOD(state, SFRUP0, sym & 0xff) < 0) if (STV090x_WRITE_DEMOD(state, SFRUP0, sym & 0xff) < 0)
goto err; goto err;
sym = 10 * (srate_coarse / 13); /* SFRLOW = SFR - 30% */ sym = 10 * (srate_coarse / 13); /* SFRLOW = SFR - 30% */
sym = (sym / 1000) * 65536; sym = (sym / 1000) * 65536;
sym /= (state->mclk / 1000); sym /= (state->internal->mclk / 1000);
if (STV090x_WRITE_DEMOD(state, SFRLOW1, (sym >> 8) & 0x7f) < 0) if (STV090x_WRITE_DEMOD(state, SFRLOW1, (sym >> 8) & 0x7f) < 0)
goto err; goto err;
if (STV090x_WRITE_DEMOD(state, SFRLOW0, sym & 0xff) < 0) if (STV090x_WRITE_DEMOD(state, SFRLOW0, sym & 0xff) < 0)
goto err; goto err;
sym = (srate_coarse / 1000) * 65536; sym = (srate_coarse / 1000) * 65536;
sym /= (state->mclk / 1000); sym /= (state->internal->mclk / 1000);
if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0xff) < 0) if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0xff) < 0)
goto err; goto err;
if (STV090x_WRITE_DEMOD(state, SFRINIT0, sym & 0xff) < 0) if (STV090x_WRITE_DEMOD(state, SFRINIT0, sym & 0xff) < 0)
...@@ -1803,20 +1878,20 @@ static u32 stv090x_srate_srch_fine(struct stv090x_state *state) ...@@ -1803,20 +1878,20 @@ static u32 stv090x_srate_srch_fine(struct stv090x_state *state)
} else { } else {
sym = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */ sym = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */
sym = (sym / 100) * 65536; sym = (sym / 100) * 65536;
sym /= (state->mclk / 100); sym /= (state->internal->mclk / 100);
if (STV090x_WRITE_DEMOD(state, SFRUP1, (sym >> 8) & 0x7f) < 0) if (STV090x_WRITE_DEMOD(state, SFRUP1, (sym >> 8) & 0x7f) < 0)
goto err; goto err;
if (STV090x_WRITE_DEMOD(state, SFRUP0, sym & 0xff) < 0) if (STV090x_WRITE_DEMOD(state, SFRUP0, sym & 0xff) < 0)
goto err; goto err;
sym = 10 * (srate_coarse / 14); /* SFRLOW = SFR - 30% */ sym = 10 * (srate_coarse / 14); /* SFRLOW = SFR - 30% */
sym = (sym / 100) * 65536; sym = (sym / 100) * 65536;
sym /= (state->mclk / 100); sym /= (state->internal->mclk / 100);
if (STV090x_WRITE_DEMOD(state, SFRLOW1, (sym >> 8) & 0x7f) < 0) if (STV090x_WRITE_DEMOD(state, SFRLOW1, (sym >> 8) & 0x7f) < 0)
goto err; goto err;
if (STV090x_WRITE_DEMOD(state, SFRLOW0, sym & 0xff) < 0) if (STV090x_WRITE_DEMOD(state, SFRLOW0, sym & 0xff) < 0)
goto err; goto err;
sym = (srate_coarse / 100) * 65536; sym = (srate_coarse / 100) * 65536;
sym /= (state->mclk / 100); sym /= (state->internal->mclk / 100);
if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0xff) < 0) if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0xff) < 0)
goto err; goto err;
if (STV090x_WRITE_DEMOD(state, SFRINIT0, sym & 0xff) < 0) if (STV090x_WRITE_DEMOD(state, SFRINIT0, sym & 0xff) < 0)
...@@ -1885,11 +1960,11 @@ static int stv090x_blind_search(struct stv090x_state *state) ...@@ -1885,11 +1960,11 @@ static int stv090x_blind_search(struct stv090x_state *state)
agc2 = stv090x_get_agc2_min_level(state); 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; lock = 0;
} else { } else {
if (state->dev_ver <= 0x20) { if (state->internal->dev_ver <= 0x20) {
if (STV090x_WRITE_DEMOD(state, CARCFG, 0xc4) < 0) if (STV090x_WRITE_DEMOD(state, CARCFG, 0xc4) < 0)
goto err; goto err;
} else { } else {
...@@ -1901,7 +1976,7 @@ static int stv090x_blind_search(struct stv090x_state *state) ...@@ -1901,7 +1976,7 @@ static int stv090x_blind_search(struct stv090x_state *state)
if (STV090x_WRITE_DEMOD(state, RTCS2, 0x44) < 0) if (STV090x_WRITE_DEMOD(state, RTCS2, 0x44) < 0)
goto err; goto err;
if (state->dev_ver >= 0x20) { if (state->internal->dev_ver >= 0x20) {
if (STV090x_WRITE_DEMOD(state, EQUALCFG, 0x41) < 0) if (STV090x_WRITE_DEMOD(state, EQUALCFG, 0x41) < 0)
goto err; goto err;
if (STV090x_WRITE_DEMOD(state, FFECFG, 0x41) < 0) if (STV090x_WRITE_DEMOD(state, FFECFG, 0x41) < 0)
...@@ -2146,13 +2221,13 @@ static int stv090x_get_loop_params(struct stv090x_state *state, s32 *freq_inc, s ...@@ -2146,13 +2221,13 @@ static int stv090x_get_loop_params(struct stv090x_state *state, s32 *freq_inc, s
car_max = state->search_range / 1000; car_max = state->search_range / 1000;
car_max += car_max / 10; car_max += car_max / 10;
car_max = 65536 * (car_max / 2); car_max = 65536 * (car_max / 2);
car_max /= (state->mclk / 1000); car_max /= (state->internal->mclk / 1000);
if (car_max > 0x4000) if (car_max > 0x4000)
car_max = 0x4000 ; /* maxcarrier should be<= +-1/4 Mclk */ car_max = 0x4000 ; /* maxcarrier should be<= +-1/4 Mclk */
inc = srate; inc = srate;
inc /= state->mclk / 1000; inc /= state->internal->mclk / 1000;
inc *= 256; inc *= 256;
inc *= 256; inc *= 256;
inc /= 1000; inc /= 1000;
...@@ -2213,7 +2288,7 @@ static int stv090x_chk_signal(struct stv090x_state *state) ...@@ -2213,7 +2288,7 @@ static int stv090x_chk_signal(struct stv090x_state *state)
car_max += (car_max / 10); /* 10% margin */ car_max += (car_max / 10); /* 10% margin */
car_max = (65536 * car_max / 2); car_max = (65536 * car_max / 2);
car_max /= state->mclk / 1000; car_max /= state->internal->mclk / 1000;
if (car_max > 0x4000) if (car_max > 0x4000)
car_max = 0x4000; car_max = 0x4000;
...@@ -2238,7 +2313,7 @@ static int stv090x_search_car_loop(struct stv090x_state *state, s32 inc, s32 tim ...@@ -2238,7 +2313,7 @@ static int stv090x_search_car_loop(struct stv090x_state *state, s32 inc, s32 tim
car_max = state->search_range / 1000; car_max = state->search_range / 1000;
car_max += (car_max / 10); car_max += (car_max / 10);
car_max = (65536 * car_max / 2); car_max = (65536 * car_max / 2);
car_max /= (state->mclk / 1000); car_max /= (state->internal->mclk / 1000);
if (car_max > 0x4000) if (car_max > 0x4000)
car_max = 0x4000; car_max = 0x4000;
...@@ -2308,7 +2383,7 @@ static int stv090x_sw_algo(struct stv090x_state *state) ...@@ -2308,7 +2383,7 @@ static int stv090x_sw_algo(struct stv090x_state *state)
case STV090x_SEARCH_DVBS1: case STV090x_SEARCH_DVBS1:
case STV090x_SEARCH_DSS: case STV090x_SEARCH_DSS:
/* accelerate the frequency detector */ /* accelerate the frequency detector */
if (state->dev_ver >= 0x20) { if (state->internal->dev_ver >= 0x20) {
if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x3B) < 0) if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x3B) < 0)
goto err; goto err;
} }
...@@ -2319,7 +2394,7 @@ static int stv090x_sw_algo(struct stv090x_state *state) ...@@ -2319,7 +2394,7 @@ static int stv090x_sw_algo(struct stv090x_state *state)
break; break;
case STV090x_SEARCH_DVBS2: case STV090x_SEARCH_DVBS2:
if (state->dev_ver >= 0x20) { if (state->internal->dev_ver >= 0x20) {
if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0) if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0)
goto err; goto err;
} }
...@@ -2332,7 +2407,7 @@ static int stv090x_sw_algo(struct stv090x_state *state) ...@@ -2332,7 +2407,7 @@ static int stv090x_sw_algo(struct stv090x_state *state)
case STV090x_SEARCH_AUTO: case STV090x_SEARCH_AUTO:
default: default:
/* accelerate the frequency detector */ /* accelerate the frequency detector */
if (state->dev_ver >= 0x20) { if (state->internal->dev_ver >= 0x20) {
if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x3b) < 0) if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x3b) < 0)
goto err; goto err;
if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0) if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0)
...@@ -2354,7 +2429,7 @@ static int stv090x_sw_algo(struct stv090x_state *state) ...@@ -2354,7 +2429,7 @@ static int stv090x_sw_algo(struct stv090x_state *state)
/*run the SW search 2 times maximum*/ /*run the SW search 2 times maximum*/
if (lock || no_signal || (trials == 2)) { if (lock || no_signal || (trials == 2)) {
/*Check if the demod is not losing lock in DVBS2*/ /*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) if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0)
goto err; goto err;
if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x9e) < 0) if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x9e) < 0)
...@@ -2376,7 +2451,7 @@ static int stv090x_sw_algo(struct stv090x_state *state) ...@@ -2376,7 +2451,7 @@ static int stv090x_sw_algo(struct stv090x_state *state)
/*FALSE lock, The demod is loosing lock */ /*FALSE lock, The demod is loosing lock */
lock = 0; lock = 0;
if (trials < 2) { if (trials < 2) {
if (state->dev_ver >= 0x20) { if (state->internal->dev_ver >= 0x20) {
if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0) if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0)
goto err; goto err;
} }
...@@ -2426,11 +2501,11 @@ static s32 stv090x_get_car_freq(struct stv090x_state *state, u32 mclk) ...@@ -2426,11 +2501,11 @@ static s32 stv090x_get_car_freq(struct stv090x_state *state, u32 mclk)
derot |= STV090x_READ_DEMOD(state, CFR0); derot |= STV090x_READ_DEMOD(state, CFR0);
derot = comp2(derot, 24); derot = comp2(derot, 24);
int_1 = state->mclk >> 12; int_1 = mclk >> 12;
int_2 = derot >> 12; int_2 = derot >> 12;
/* carrier_frequency = MasterClock * Reg / 2^24 */ /* carrier_frequency = MasterClock * Reg / 2^24 */
tmp_1 = state->mclk % 0x1000; tmp_1 = mclk % 0x1000;
tmp_2 = derot % 0x1000; tmp_2 = derot % 0x1000;
derot = (int_1 * int_2) + derot = (int_1 * int_2) +
...@@ -2512,7 +2587,7 @@ static enum stv090x_signal_state stv090x_get_sig_params(struct stv090x_state *st ...@@ -2512,7 +2587,7 @@ static enum stv090x_signal_state stv090x_get_sig_params(struct stv090x_state *st
if (stv090x_i2c_gate_ctrl(fe, 0) < 0) if (stv090x_i2c_gate_ctrl(fe, 0) < 0)
goto err; 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; state->frequency += offst_freq;
if (stv090x_get_viterbi(state) < 0) if (stv090x_get_viterbi(state) < 0)
...@@ -2583,7 +2658,7 @@ static u8 stv090x_optimize_carloop(struct stv090x_state *state, enum stv090x_mod ...@@ -2583,7 +2658,7 @@ static u8 stv090x_optimize_carloop(struct stv090x_state *state, enum stv090x_mod
s32 i; s32 i;
struct stv090x_long_frame_crloop *car_loop, *car_loop_qpsk_low, *car_loop_apsk_low; 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 = stv090x_s2_crl_cut20;
car_loop_qpsk_low = stv090x_s2_lowqpsk_crl_cut20; car_loop_qpsk_low = stv090x_s2_lowqpsk_crl_cut20;
car_loop_apsk_low = stv090x_s2_apsk_crl_cut20; car_loop_apsk_low = stv090x_s2_apsk_crl_cut20;
...@@ -2704,7 +2779,7 @@ static u8 stv090x_optimize_carloop_short(struct stv090x_state *state) ...@@ -2704,7 +2779,7 @@ static u8 stv090x_optimize_carloop_short(struct stv090x_state *state)
break; break;
} }
if (state->dev_ver >= 0x30) { if (state->internal->dev_ver >= 0x30) {
/* Cut 3.0 and up */ /* Cut 3.0 and up */
short_crl = stv090x_s2_short_crl_cut30; short_crl = stv090x_s2_short_crl_cut30;
} else { } else {
...@@ -2736,7 +2811,7 @@ static int stv090x_optimize_track(struct stv090x_state *state) ...@@ -2736,7 +2811,7 @@ static int stv090x_optimize_track(struct stv090x_state *state)
s32 srate, pilots, aclc, f_1, f_0, i = 0, blind_tune = 0; s32 srate, pilots, aclc, f_1, f_0, i = 0, blind_tune = 0;
u32 reg; u32 reg;
srate = stv090x_get_srate(state, state->mclk); srate = stv090x_get_srate(state, state->internal->mclk);
srate += stv090x_get_tmgoffst(state, srate); srate += stv090x_get_tmgoffst(state, srate);
switch (state->delsys) { switch (state->delsys) {
...@@ -2755,7 +2830,7 @@ static int stv090x_optimize_track(struct stv090x_state *state) ...@@ -2755,7 +2830,7 @@ static int stv090x_optimize_track(struct stv090x_state *state)
if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0) if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0)
goto err; goto err;
if (state->dev_ver >= 0x30) { if (state->internal->dev_ver >= 0x30) {
if (stv090x_get_viterbi(state) < 0) if (stv090x_get_viterbi(state) < 0)
goto err; goto err;
...@@ -2872,7 +2947,7 @@ static int stv090x_optimize_track(struct stv090x_state *state) ...@@ -2872,7 +2947,7 @@ static int stv090x_optimize_track(struct stv090x_state *state)
goto err; goto err;
} }
if (state->dev_ver >= 0x20) { if (state->internal->dev_ver >= 0x20) {
if ((state->search_mode == STV090x_SEARCH_DVBS1) || if ((state->search_mode == STV090x_SEARCH_DVBS1) ||
(state->search_mode == STV090x_SEARCH_DSS) || (state->search_mode == STV090x_SEARCH_DSS) ||
(state->search_mode == STV090x_SEARCH_AUTO)) { (state->search_mode == STV090x_SEARCH_AUTO)) {
...@@ -2894,7 +2969,8 @@ static int stv090x_optimize_track(struct stv090x_state *state) ...@@ -2894,7 +2969,8 @@ static int stv090x_optimize_track(struct stv090x_state *state)
if (STV090x_WRITE_DEMOD(state, SFRLOW1, 0x80) < 0) if (STV090x_WRITE_DEMOD(state, SFRLOW1, 0x80) < 0)
goto err; 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 */ /* update initial carrier freq with the found freq offset */
if (STV090x_WRITE_DEMOD(state, CFRINIT1, f_1) < 0) if (STV090x_WRITE_DEMOD(state, CFRINIT1, f_1) < 0)
goto err; goto err;
...@@ -2902,7 +2978,7 @@ static int stv090x_optimize_track(struct stv090x_state *state) ...@@ -2902,7 +2978,7 @@ static int stv090x_optimize_track(struct stv090x_state *state)
goto err; goto err;
state->tuner_bw = stv090x_car_width(srate, state->rolloff) + 10000000; 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->algo != STV090x_WARM_SEARCH) {
...@@ -2954,7 +3030,7 @@ static int stv090x_optimize_track(struct stv090x_state *state) ...@@ -2954,7 +3030,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) if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0)
goto err; goto err;
} }
...@@ -3030,7 +3106,7 @@ static int stv090x_set_s2rolloff(struct stv090x_state *state) ...@@ -3030,7 +3106,7 @@ static int stv090x_set_s2rolloff(struct stv090x_state *state)
{ {
u32 reg; u32 reg;
if (state->dev_ver <= 0x20) { if (state->internal->dev_ver <= 0x20) {
/* rolloff to auto mode if DVBS2 */ /* rolloff to auto mode if DVBS2 */
reg = STV090x_READ_DEMOD(state, DEMOD); reg = STV090x_READ_DEMOD(state, DEMOD);
STV090x_SETFIELD_Px(reg, MANUAL_SXROLLOFF_FIELD, 0x00); STV090x_SETFIELD_Px(reg, MANUAL_SXROLLOFF_FIELD, 0x00);
...@@ -3066,7 +3142,7 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) ...@@ -3066,7 +3142,7 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state)
if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5c) < 0) /* Demod stop */ if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5c) < 0) /* Demod stop */
goto err; goto err;
if (state->dev_ver >= 0x20) { if (state->internal->dev_ver >= 0x20) {
if (state->srate > 5000000) { if (state->srate > 5000000) {
if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x9e) < 0) if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x9e) < 0)
goto err; goto err;
...@@ -3106,7 +3182,7 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) ...@@ -3106,7 +3182,7 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state)
if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0) if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0)
goto err; goto err;
if (state->dev_ver >= 0x20) { if (state->internal->dev_ver >= 0x20) {
if (STV090x_WRITE_DEMOD(state, KREFTMG, 0x5a) < 0) if (STV090x_WRITE_DEMOD(state, KREFTMG, 0x5a) < 0)
goto err; goto err;
if (state->algo == STV090x_COLD_SEARCH) if (state->algo == STV090x_COLD_SEARCH)
...@@ -3124,9 +3200,11 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) ...@@ -3124,9 +3200,11 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state)
if (stv090x_set_srate(state, state->srate) < 0) if (stv090x_set_srate(state, state->srate) < 0)
goto err; 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; 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; goto err;
if (state->srate >= 10000000) if (state->srate >= 10000000)
...@@ -3198,7 +3276,7 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) ...@@ -3198,7 +3276,7 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state)
reg = STV090x_READ_DEMOD(state, DEMOD); reg = STV090x_READ_DEMOD(state, DEMOD);
STV090x_SETFIELD_Px(reg, SPECINV_CONTROL_FIELD, state->inversion); 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 */ /* rolloff to auto mode if DVBS2 */
STV090x_SETFIELD_Px(reg, MANUAL_SXROLLOFF_FIELD, 1); STV090x_SETFIELD_Px(reg, MANUAL_SXROLLOFF_FIELD, 1);
} else { } else {
...@@ -3242,7 +3320,7 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) ...@@ -3242,7 +3320,7 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state)
if ((lock) && (signal_state == STV090x_RANGEOK)) { /* signal within Range */ if ((lock) && (signal_state == STV090x_RANGEOK)) { /* signal within Range */
stv090x_optimize_track(state); stv090x_optimize_track(state);
if (state->dev_ver >= 0x20) { if (state->internal->dev_ver >= 0x20) {
/* >= Cut 2.0 :release TS reset after /* >= Cut 2.0 :release TS reset after
* demod lock and optimized Tracking * demod lock and optimized Tracking
*/ */
...@@ -3774,6 +3852,15 @@ static void stv090x_release(struct dvb_frontend *fe) ...@@ -3774,6 +3852,15 @@ static void stv090x_release(struct dvb_frontend *fe)
{ {
struct stv090x_state *state = fe->demodulator_priv; 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); kfree(state);
} }
...@@ -3905,10 +3992,10 @@ static int stv090x_set_mclk(struct stv090x_state *state, u32 mclk, u32 clk) ...@@ -3905,10 +3992,10 @@ static int stv090x_set_mclk(struct stv090x_state *state, u32 mclk, u32 clk)
if (stv090x_write_reg(state, STV090x_NCOARSE, reg) < 0) if (stv090x_write_reg(state, STV090x_NCOARSE, reg) < 0)
goto err; goto err;
state->mclk = stv090x_get_mclk(state); state->internal->mclk = stv090x_get_mclk(state);
/*Set the DiseqC frequency to 22KHz */ /*Set the DiseqC frequency to 22KHz */
div = state->mclk / 704000; div = state->internal->mclk / 704000;
if (STV090x_WRITE_DEMOD(state, F22TX, div) < 0) if (STV090x_WRITE_DEMOD(state, F22TX, div) < 0)
goto err; goto err;
if (STV090x_WRITE_DEMOD(state, F22RX, div) < 0) if (STV090x_WRITE_DEMOD(state, F22RX, div) < 0)
...@@ -3924,7 +4011,7 @@ static int stv090x_set_tspath(struct stv090x_state *state) ...@@ -3924,7 +4011,7 @@ static int stv090x_set_tspath(struct stv090x_state *state)
{ {
u32 reg; u32 reg;
if (state->dev_ver >= 0x20) { if (state->internal->dev_ver >= 0x20) {
switch (state->config->ts1_mode) { switch (state->config->ts1_mode) {
case STV090x_TSMODE_PARALLEL_PUNCTURED: case STV090x_TSMODE_PARALLEL_PUNCTURED:
case STV090x_TSMODE_DVBCI: case STV090x_TSMODE_DVBCI:
...@@ -4192,16 +4279,26 @@ static int stv090x_setup(struct dvb_frontend *fe) ...@@ -4192,16 +4279,26 @@ static int stv090x_setup(struct dvb_frontend *fe)
} }
/* STV090x init */ /* 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; goto err;
msleep(5); 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; goto err;
/* I2C repeater OFF */
STV090x_SETFIELD_Px(reg, ENARPT_LEVEL_FIELD, config->repeater_level); 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; goto err;
if (stv090x_write_reg(state, STV090x_NCOARSE, 0x13) < 0) /* set PLL divider */ if (stv090x_write_reg(state, STV090x_NCOARSE, 0x13) < 0) /* set PLL divider */
...@@ -4220,8 +4317,8 @@ static int stv090x_setup(struct dvb_frontend *fe) ...@@ -4220,8 +4317,8 @@ static int stv090x_setup(struct dvb_frontend *fe)
goto err; goto err;
} }
state->dev_ver = stv090x_read_reg(state, STV090x_MID); state->internal->dev_ver = stv090x_read_reg(state, STV090x_MID);
if (state->dev_ver >= 0x20) { if (state->internal->dev_ver >= 0x20) {
if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x0c) < 0) if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x0c) < 0)
goto err; goto err;
...@@ -4232,15 +4329,15 @@ static int stv090x_setup(struct dvb_frontend *fe) ...@@ -4232,15 +4329,15 @@ static int stv090x_setup(struct dvb_frontend *fe)
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!", dprintk(FE_ERROR, 1, "ERROR: Unsupported Cut: 0x%02x!",
state->dev_ver); state->internal->dev_ver);
goto err; goto err;
} else if (state->dev_ver > 0x30) { } else if (state->internal->dev_ver > 0x30) {
/* we shouldn't bail out from here */ /* we shouldn't bail out from here */
dprintk(FE_ERROR, 1, "INFO: Cut: 0x%02x probably incomplete support!", 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) if (stv090x_write_reg(state, STV090x_TSTRES0, 0x80) < 0)
...@@ -4303,6 +4400,7 @@ struct dvb_frontend *stv090x_attach(const struct stv090x_config *config, ...@@ -4303,6 +4400,7 @@ struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
enum stv090x_demodulator demod) enum stv090x_demodulator demod)
{ {
struct stv090x_state *state = NULL; struct stv090x_state *state = NULL;
struct stv090x_dev *temp_int;
state = kzalloc(sizeof (struct stv090x_state), GFP_KERNEL); state = kzalloc(sizeof (struct stv090x_state), GFP_KERNEL);
if (state == NULL) if (state == NULL)
...@@ -4318,8 +4416,29 @@ struct dvb_frontend *stv090x_attach(const struct stv090x_config *config, ...@@ -4318,8 +4416,29 @@ struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
state->device = config->device; state->device = config->device;
state->rolloff = STV090x_RO_35; /* default */ state->rolloff = STV090x_RO_35; /* default */
if (state->demod == STV090x_DEMODULATOR_0) temp_int = find_dev(state->i2c,
mutex_init(&demod_lock); 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->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);
if (stv090x_sleep(&state->frontend) < 0) { if (stv090x_sleep(&state->frontend) < 0) {
dprintk(FE_ERROR, 1, "Error putting device to sleep"); dprintk(FE_ERROR, 1, "Error putting device to sleep");
...@@ -4335,10 +4454,10 @@ struct dvb_frontend *stv090x_attach(const struct stv090x_config *config, ...@@ -4335,10 +4454,10 @@ struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
goto error; 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", state->device == STV0900 ? "STV0900" : "STV0903",
demod, demod,
state->dev_ver); state->internal->dev_ver);
return &state->frontend; return &state->frontend;
......
...@@ -68,8 +68,6 @@ struct stv090x_config { ...@@ -68,8 +68,6 @@ struct stv090x_config {
u32 xtal; /* default: 8000000 */ u32 xtal; /* default: 8000000 */
u8 address; /* default: 0x68 */ u8 address; /* default: 0x68 */
u32 ref_clk; /* default: 16000000 FIXME to tuner config */
u8 ts1_mode; u8 ts1_mode;
u8 ts2_mode; u8 ts2_mode;
......
...@@ -230,11 +230,22 @@ struct stv090x_tab { ...@@ -230,11 +230,22 @@ struct stv090x_tab {
s32 read; s32 read;
}; };
struct stv090x_internal {
struct i2c_adapter *i2c_adap;
u8 i2c_addr;
struct mutex demod_lock; /* Lock access to shared register */
s32 mclk; /* Masterclock Divider factor */
u32 dev_ver;
int num_used;
};
struct stv090x_state { struct stv090x_state {
enum stv090x_device device; enum stv090x_device device;
enum stv090x_demodulator demod; enum stv090x_demodulator demod;
enum stv090x_mode demod_mode; enum stv090x_mode demod_mode;
u32 dev_ver; struct stv090x_internal *internal;
struct i2c_adapter *i2c; struct i2c_adapter *i2c;
const struct stv090x_config *config; const struct stv090x_config *config;
...@@ -256,11 +267,8 @@ struct stv090x_state { ...@@ -256,11 +267,8 @@ struct stv090x_state {
u32 frequency; u32 frequency;
u32 srate; u32 srate;
s32 mclk; /* Masterclock Divider factor */
s32 tuner_bw; s32 tuner_bw;
u32 tuner_refclk;
s32 search_range; s32 search_range;
s32 DemodTimeout; s32 DemodTimeout;
......
...@@ -435,7 +435,6 @@ static struct stv090x_config tt1600_stv090x_config = { ...@@ -435,7 +435,6 @@ static struct stv090x_config tt1600_stv090x_config = {
.xtal = 27000000, .xtal = 27000000,
.address = 0x68, .address = 0x68,
.ref_clk = 27000000,
.ts1_mode = STV090x_TSMODE_DVBCI, .ts1_mode = STV090x_TSMODE_DVBCI,
.ts2_mode = STV090x_TSMODE_SERIAL_CONTINUOUS, .ts2_mode = STV090x_TSMODE_SERIAL_CONTINUOUS,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment