From: Hans Verkuil <hans.verkuil@xxxxxxxxx> The get_rf_strength op in tuner-simple is valid only for the radio mode. But due to the way get_signal in analog_demod_ops was designed it would overwrite the signal value with a bogus value when in TV mode. Pass a pointer to the signal value instead, and when not in radio mode leave it alone in the tuner-simple. Signed-off-by: Hans Verkuil <hans.verkuil@xxxxxxxxx> --- drivers/media/dvb-core/dvb_frontend.h | 2 +- drivers/media/tuners/tda8290.c | 15 +++++++++------ drivers/media/tuners/tuner-simple.c | 5 ++++- drivers/media/v4l2-core/tuner-core.c | 29 +++++++++++++---------------- 4 files changed, 27 insertions(+), 24 deletions(-) diff --git a/drivers/media/dvb-core/dvb_frontend.h b/drivers/media/dvb-core/dvb_frontend.h index 44fad1c..371b6ca 100644 --- a/drivers/media/dvb-core/dvb_frontend.h +++ b/drivers/media/dvb-core/dvb_frontend.h @@ -245,7 +245,7 @@ struct analog_demod_ops { void (*set_params)(struct dvb_frontend *fe, struct analog_parameters *params); - int (*has_signal)(struct dvb_frontend *fe); + int (*has_signal)(struct dvb_frontend *fe, u16 *signal); int (*get_afc)(struct dvb_frontend *fe, s32 *afc); void (*tuner_status)(struct dvb_frontend *fe); void (*standby)(struct dvb_frontend *fe); diff --git a/drivers/media/tuners/tda8290.c b/drivers/media/tuners/tda8290.c index 8c48521..119339bd 100644 --- a/drivers/media/tuners/tda8290.c +++ b/drivers/media/tuners/tda8290.c @@ -388,7 +388,7 @@ static void tda8295_agc2_out(struct dvb_frontend *fe, int enable) tuner_i2c_xfer_send(&priv->i2c_props, set_gpio_val, 2); } -static int tda8295_has_signal(struct dvb_frontend *fe) +static int tda8295_has_signal(struct dvb_frontend *fe, u16 *signal) { struct tda8290_priv *priv = fe->analog_demod_priv; @@ -396,7 +396,8 @@ static int tda8295_has_signal(struct dvb_frontend *fe) unsigned char ret; tuner_i2c_xfer_send_recv(&priv->i2c_props, &hvpll_stat, 1, &ret, 1); - return (ret & 0x01) ? 65535 : 0; + *signal = (ret & 0x01) ? 65535 : 0; + return 0; } /*---------------------------------------------------------------------*/ @@ -405,7 +406,7 @@ static void tda8295_set_params(struct dvb_frontend *fe, struct analog_parameters *params) { struct tda8290_priv *priv = fe->analog_demod_priv; - + u16 signal = 0; unsigned char blanking_mode[] = { 0x1d, 0x00 }; set_audio(fe, params); @@ -432,7 +433,8 @@ static void tda8295_set_params(struct dvb_frontend *fe, if (priv->cfg.agcf) priv->cfg.agcf(fe); - if (tda8295_has_signal(fe)) + tda8295_has_signal(fe, &signal); + if (signal) tuner_dbg("tda8295 is locked\n"); else tuner_dbg("tda8295 not locked, no signal?\n"); @@ -442,7 +444,7 @@ static void tda8295_set_params(struct dvb_frontend *fe, /*---------------------------------------------------------------------*/ -static int tda8290_has_signal(struct dvb_frontend *fe) +static int tda8290_has_signal(struct dvb_frontend *fe, u16 *signal) { struct tda8290_priv *priv = fe->analog_demod_priv; @@ -451,7 +453,8 @@ static int tda8290_has_signal(struct dvb_frontend *fe) tuner_i2c_xfer_send_recv(&priv->i2c_props, i2c_get_afc, ARRAY_SIZE(i2c_get_afc), &afc, 1); - return (afc & 0x80)? 65535:0; + *signal = (afc & 0x80) ? 65535 : 0; + return 0; } /*---------------------------------------------------------------------*/ diff --git a/drivers/media/tuners/tuner-simple.c b/drivers/media/tuners/tuner-simple.c index 39e7e58..ca274c2 100644 --- a/drivers/media/tuners/tuner-simple.c +++ b/drivers/media/tuners/tuner-simple.c @@ -115,6 +115,7 @@ struct tuner_simple_priv { u32 frequency; u32 bandwidth; + bool radio_mode; }; /* ---------------------------------------------------------------------- */ @@ -189,7 +190,7 @@ static int simple_get_rf_strength(struct dvb_frontend *fe, u16 *strength) struct tuner_simple_priv *priv = fe->tuner_priv; int signal; - if (priv->i2c_props.adap == NULL) + if (priv->i2c_props.adap == NULL || !priv->radio_mode) return -EINVAL; signal = tuner_signal(tuner_read_status(fe)); @@ -776,11 +777,13 @@ static int simple_set_params(struct dvb_frontend *fe, switch (params->mode) { case V4L2_TUNER_RADIO: + priv->radio_mode = true; ret = simple_set_radio_freq(fe, params); priv->frequency = params->frequency * 125 / 2; break; case V4L2_TUNER_ANALOG_TV: case V4L2_TUNER_DIGITAL_TV: + priv->radio_mode = false; ret = simple_set_tv_freq(fe, params); priv->frequency = params->frequency * 62500; break; diff --git a/drivers/media/v4l2-core/tuner-core.c b/drivers/media/v4l2-core/tuner-core.c index b2d057d..7702159 100644 --- a/drivers/media/v4l2-core/tuner-core.c +++ b/drivers/media/v4l2-core/tuner-core.c @@ -218,16 +218,6 @@ static void fe_standby(struct dvb_frontend *fe) fe_tuner_ops->sleep(fe); } -static int fe_has_signal(struct dvb_frontend *fe) -{ - u16 strength; - - if (fe->ops.tuner_ops.get_rf_strength(fe, &strength) < 0) - return 0; - - return strength; -} - static int fe_set_config(struct dvb_frontend *fe, void *priv_cfg) { struct dvb_tuner_ops *fe_tuner_ops = &fe->ops.tuner_ops; @@ -442,7 +432,7 @@ static void set_type(struct i2c_client *c, unsigned int type, sizeof(struct analog_demod_ops)); if (fe_tuner_ops->get_rf_strength) - analog_ops->has_signal = fe_has_signal; + analog_ops->has_signal = fe_tuner_ops->get_rf_strength; if (fe_tuner_ops->get_afc) analog_ops->get_afc = fe_tuner_ops->get_afc; @@ -1066,9 +1056,12 @@ static void tuner_status(struct dvb_frontend *fe) if (tuner_status & TUNER_STATUS_STEREO) tuner_info("Stereo: yes\n"); } - if (analog_ops->has_signal) - tuner_info("Signal strength: %d\n", - analog_ops->has_signal(fe)); + if (analog_ops->has_signal) { + u16 signal; + + if (!analog_ops->has_signal(fe, &signal)) + tuner_info("Signal strength: %hu\n", signal); + } } /* @@ -1187,8 +1180,12 @@ static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) return 0; if (vt->type == t->mode && analog_ops->get_afc) analog_ops->get_afc(&t->fe, &vt->afc); - if (analog_ops->has_signal) - vt->signal = analog_ops->has_signal(&t->fe); + if (vt->type == t->mode && analog_ops->has_signal) { + u16 signal = (u16)vt->signal; + + if (!analog_ops->has_signal(&t->fe, &signal)) + vt->signal = signal; + } if (vt->type != V4L2_TUNER_RADIO) { vt->capability |= V4L2_TUNER_CAP_NORM; vt->rangelow = tv_range[0] * 16; -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html