Commit 1d432a3d authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab

[media] tuner, xc2028: add support for get_afc()

Implement API support to return AFC frequency shift, as this device
supports it. The only other driver that implements it is tda9887,
and the frequency there is reported in Hz. So, use Hz also for this
tuner.
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 90acb85f
...@@ -924,7 +924,7 @@ static int xc2028_signal(struct dvb_frontend *fe, u16 *strength) ...@@ -924,7 +924,7 @@ static int xc2028_signal(struct dvb_frontend *fe, u16 *strength)
msleep(6); msleep(6);
} }
/* Frequency was not locked */ /* Frequency didn't lock */
if (frq_lock == 2) if (frq_lock == 2)
goto ret; goto ret;
...@@ -947,6 +947,49 @@ static int xc2028_signal(struct dvb_frontend *fe, u16 *strength) ...@@ -947,6 +947,49 @@ static int xc2028_signal(struct dvb_frontend *fe, u16 *strength)
return rc; return rc;
} }
static int xc2028_get_afc(struct dvb_frontend *fe, s32 *afc)
{
struct xc2028_data *priv = fe->tuner_priv;
int i, rc;
u16 frq_lock = 0;
s16 afc_reg = 0;
rc = check_device_status(priv);
if (rc < 0)
return rc;
mutex_lock(&priv->lock);
/* Sync Lock Indicator */
for (i = 0; i < 3; i++) {
rc = xc2028_get_reg(priv, XREG_LOCK, &frq_lock);
if (rc < 0)
goto ret;
if (frq_lock)
break;
msleep(6);
}
/* Frequency didn't lock */
if (frq_lock == 2)
goto ret;
/* Get AFC */
rc = xc2028_get_reg(priv, XREG_FREQ_ERROR, &afc_reg);
if (rc < 0)
return rc;
*afc = afc_reg * 15625; /* Hz */
tuner_dbg("AFC is %d Hz\n", *afc);
ret:
mutex_unlock(&priv->lock);
return rc;
}
#define DIV 15625 #define DIV 15625
static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */, static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */,
...@@ -1392,6 +1435,7 @@ static const struct dvb_tuner_ops xc2028_dvb_tuner_ops = { ...@@ -1392,6 +1435,7 @@ static const struct dvb_tuner_ops xc2028_dvb_tuner_ops = {
.release = xc2028_dvb_release, .release = xc2028_dvb_release,
.get_frequency = xc2028_get_frequency, .get_frequency = xc2028_get_frequency,
.get_rf_strength = xc2028_signal, .get_rf_strength = xc2028_signal,
.get_afc = xc2028_get_afc,
.set_params = xc2028_set_params, .set_params = xc2028_set_params,
.sleep = xc2028_sleep, .sleep = xc2028_sleep,
}; };
......
...@@ -220,6 +220,7 @@ struct dvb_tuner_ops { ...@@ -220,6 +220,7 @@ struct dvb_tuner_ops {
#define TUNER_STATUS_STEREO 2 #define TUNER_STATUS_STEREO 2
int (*get_status)(struct dvb_frontend *fe, u32 *status); int (*get_status)(struct dvb_frontend *fe, u32 *status);
int (*get_rf_strength)(struct dvb_frontend *fe, u16 *strength); int (*get_rf_strength)(struct dvb_frontend *fe, u16 *strength);
int (*get_afc)(struct dvb_frontend *fe, s32 *afc);
/** These are provided separately from set_params in order to facilitate silicon /** These are provided separately from set_params in order to facilitate silicon
* tuners which require sophisticated tuning loops, controlling each parameter separately. */ * tuners which require sophisticated tuning loops, controlling each parameter separately. */
......
...@@ -228,6 +228,16 @@ static int fe_has_signal(struct dvb_frontend *fe) ...@@ -228,6 +228,16 @@ static int fe_has_signal(struct dvb_frontend *fe)
return strength; return strength;
} }
static int fe_get_afc(struct dvb_frontend *fe)
{
s32 afc = 0;
if (fe->ops.tuner_ops.get_afc)
fe->ops.tuner_ops.get_afc(fe, &afc);
return 0;
}
static int fe_set_config(struct dvb_frontend *fe, void *priv_cfg) static int fe_set_config(struct dvb_frontend *fe, void *priv_cfg)
{ {
struct dvb_tuner_ops *fe_tuner_ops = &fe->ops.tuner_ops; struct dvb_tuner_ops *fe_tuner_ops = &fe->ops.tuner_ops;
...@@ -247,6 +257,7 @@ static struct analog_demod_ops tuner_analog_ops = { ...@@ -247,6 +257,7 @@ static struct analog_demod_ops tuner_analog_ops = {
.set_params = fe_set_params, .set_params = fe_set_params,
.standby = fe_standby, .standby = fe_standby,
.has_signal = fe_has_signal, .has_signal = fe_has_signal,
.get_afc = fe_get_afc,
.set_config = fe_set_config, .set_config = fe_set_config,
.tuner_status = tuner_status .tuner_status = tuner_status
}; };
......
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