Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 366639
b: refs/heads/master
c: 59a7a23
h: refs/heads/master
i:
  366637: 27ae34b
  366635: c4733f3
  366631: 0849a30
  366623: d62349f
v: v3
  • Loading branch information
Mauro Carvalho Chehab committed Mar 21, 2013
1 parent 92c95a6 commit 2c2347a
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 18 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 8f3741e02831d1181be9ca0ea711dd0c8d7f8a7b
refs/heads/master: 59a7a23c4755f12757fe17234c693188a9e6bcf5
126 changes: 109 additions & 17 deletions trunk/drivers/media/dvb-frontends/drxk_hard.c
Original file line number Diff line number Diff line change
Expand Up @@ -6390,6 +6390,107 @@ static int drxk_set_parameters(struct dvb_frontend *fe)
return 0;
}

static int get_strength(struct drxk_state *state, u64 *strength)
{
int status;
struct SCfgAgc rfAgc, ifAgc;
u32 totalGain = 0;
u32 atten = 0;
u32 agcRange = 0;
u16 scu_lvl = 0;
u16 scu_coc = 0;
/* FIXME: those are part of the tuner presets */
u16 tunerRfGain = 50; /* Default value on az6007 driver */
u16 tunerIfGain = 40; /* Default value on az6007 driver */

*strength = 0;

if (IsDVBT(state)) {
rfAgc = state->m_dvbtRfAgcCfg;
ifAgc = state->m_dvbtIfAgcCfg;
} else if (IsQAM(state)) {
rfAgc = state->m_qamRfAgcCfg;
ifAgc = state->m_qamIfAgcCfg;
} else {
rfAgc = state->m_atvRfAgcCfg;
ifAgc = state->m_atvIfAgcCfg;
}

if (rfAgc.ctrlMode == DRXK_AGC_CTRL_AUTO) {
/* SCU outputLevel */
status = read16(state, SCU_RAM_AGC_RF_IACCU_HI__A, &scu_lvl);
if (status < 0)
return status;

/* SCU c.o.c. */
read16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, &scu_coc);
if (status < 0)
return status;

if (((u32) scu_lvl + (u32) scu_coc) < 0xffff)
rfAgc.outputLevel = scu_lvl + scu_coc;
else
rfAgc.outputLevel = 0xffff;

/* Take RF gain into account */
totalGain += tunerRfGain;

/* clip output value */
if (rfAgc.outputLevel < rfAgc.minOutputLevel)
rfAgc.outputLevel = rfAgc.minOutputLevel;
if (rfAgc.outputLevel > rfAgc.maxOutputLevel)
rfAgc.outputLevel = rfAgc.maxOutputLevel;

agcRange = (u32) (rfAgc.maxOutputLevel - rfAgc.minOutputLevel);
if (agcRange > 0) {
atten += 100UL *
((u32)(tunerRfGain)) *
((u32)(rfAgc.outputLevel - rfAgc.minOutputLevel))
/ agcRange;
}
}

if (ifAgc.ctrlMode == DRXK_AGC_CTRL_AUTO) {
status = read16(state, SCU_RAM_AGC_IF_IACCU_HI__A,
&ifAgc.outputLevel);
if (status < 0)
return status;

status = read16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A,
&ifAgc.top);
if (status < 0)
return status;

/* Take IF gain into account */
totalGain += (u32) tunerIfGain;

/* clip output value */
if (ifAgc.outputLevel < ifAgc.minOutputLevel)
ifAgc.outputLevel = ifAgc.minOutputLevel;
if (ifAgc.outputLevel > ifAgc.maxOutputLevel)
ifAgc.outputLevel = ifAgc.maxOutputLevel;

agcRange = (u32) (ifAgc.maxOutputLevel - ifAgc.minOutputLevel);
if (agcRange > 0) {
atten += 100UL *
((u32)(tunerIfGain)) *
((u32)(ifAgc.outputLevel - ifAgc.minOutputLevel))
/ agcRange;
}
}

/*
* Convert to 0..65535 scale.
* If it can't be measured (AGC is disabled), just show 100%.
*/
if (totalGain > 0)
*strength = (65535UL * atten / totalGain);
else
*strength = 65535;

return 0;
}

static int drxk_get_stats(struct dvb_frontend *fe)
{
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
Expand All @@ -6404,7 +6505,7 @@ static int drxk_get_stats(struct dvb_frontend *fe)
u32 pre_bit_count;
u32 pkt_count;
u32 pkt_error_count;
s32 cnr, gain;
s32 cnr;

if (state->m_DrxkState == DRXK_NO_DEV)
return -ENODEV;
Expand All @@ -6421,6 +6522,13 @@ static int drxk_get_stats(struct dvb_frontend *fe)
if (stat == DEMOD_LOCK)
state->fe_status |= 0x07;

/*
* Estimate signal strength from AGC
*/
get_strength(state, &c->strength.stat[0].uvalue);
c->strength.stat[0].scale = FE_SCALE_RELATIVE;


if (stat >= DEMOD_LOCK) {
GetSignalToNoise(state, &cnr);
c->cnr.stat[0].svalue = cnr * 100;
Expand Down Expand Up @@ -6500,22 +6608,6 @@ static int drxk_get_stats(struct dvb_frontend *fe)
c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
c->post_bit_count.stat[0].uvalue += post_bit_count;

/*
* Read AGC gain
*
* IFgain = (IQM_AF_AGC_IF__A * 26.75) (nA)
*/
status = read16(state, IQM_AF_AGC_IF__A, &reg16);
if (status < 0) {
printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
return status;
}
gain = 2675 * (reg16 - DRXK_AGC_DAC_OFFSET) / 100;

/* FIXME: it makes sense to fix the scale here to dBm */
c->strength.stat[0].scale = FE_SCALE_RELATIVE;
c->strength.stat[0].uvalue = gain;

error:
return status;
}
Expand Down

0 comments on commit 2c2347a

Please sign in to comment.