diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2013-04-06 03:35:27 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2013-04-14 18:43:40 -0400 |
commit | a2192cf47f593681cd65798880853c5224066c81 (patch) | |
tree | 1883c7aa872f02413ff8c3da558e40c4f3b3ab1c | |
parent | d047795c590f63d42160b84ac778b09af297d914 (diff) |
[media] tuner-core/tda9887: get_afc can be tuner mode specific
The get_afc op in tda9887 is valid only for the radio mode.
But due to the way get_afc in analog_demod_ops was designed it would
overwrite the afc value with a bogus value when in TV mode.
Pass a pointer to the afc value instead, and when not in radio mode
leave it alone in the tda9887.
This broke a long time ago in 2.6.19 when the get_afc op was introduced.
Before that the afc was only set for radio mode in the tda9887.
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/dvb-core/dvb_frontend.h | 2 | ||||
-rw-r--r-- | drivers/media/tuners/tda9887.c | 14 | ||||
-rw-r--r-- | drivers/media/v4l2-core/tuner-core.c | 14 |
3 files changed, 10 insertions, 20 deletions
diff --git a/drivers/media/dvb-core/dvb_frontend.h b/drivers/media/dvb-core/dvb_frontend.h index b34922a08156..44fad1cbcb09 100644 --- a/drivers/media/dvb-core/dvb_frontend.h +++ b/drivers/media/dvb-core/dvb_frontend.h | |||
@@ -246,7 +246,7 @@ struct analog_demod_ops { | |||
246 | void (*set_params)(struct dvb_frontend *fe, | 246 | void (*set_params)(struct dvb_frontend *fe, |
247 | struct analog_parameters *params); | 247 | struct analog_parameters *params); |
248 | int (*has_signal)(struct dvb_frontend *fe); | 248 | int (*has_signal)(struct dvb_frontend *fe); |
249 | int (*get_afc)(struct dvb_frontend *fe); | 249 | int (*get_afc)(struct dvb_frontend *fe, s32 *afc); |
250 | void (*tuner_status)(struct dvb_frontend *fe); | 250 | void (*tuner_status)(struct dvb_frontend *fe); |
251 | void (*standby)(struct dvb_frontend *fe); | 251 | void (*standby)(struct dvb_frontend *fe); |
252 | void (*release)(struct dvb_frontend *fe); | 252 | void (*release)(struct dvb_frontend *fe); |
diff --git a/drivers/media/tuners/tda9887.c b/drivers/media/tuners/tda9887.c index cdb645d57438..300005c535ba 100644 --- a/drivers/media/tuners/tda9887.c +++ b/drivers/media/tuners/tda9887.c | |||
@@ -596,22 +596,22 @@ static void tda9887_tuner_status(struct dvb_frontend *fe) | |||
596 | priv->data[1], priv->data[2], priv->data[3]); | 596 | priv->data[1], priv->data[2], priv->data[3]); |
597 | } | 597 | } |
598 | 598 | ||
599 | static int tda9887_get_afc(struct dvb_frontend *fe) | 599 | static int tda9887_get_afc(struct dvb_frontend *fe, s32 *afc) |
600 | { | 600 | { |
601 | struct tda9887_priv *priv = fe->analog_demod_priv; | 601 | struct tda9887_priv *priv = fe->analog_demod_priv; |
602 | static int AFC_BITS_2_kHz[] = { | 602 | static const int AFC_BITS_2_kHz[] = { |
603 | -12500, -37500, -62500, -97500, | 603 | -12500, -37500, -62500, -97500, |
604 | -112500, -137500, -162500, -187500, | 604 | -112500, -137500, -162500, -187500, |
605 | 187500, 162500, 137500, 112500, | 605 | 187500, 162500, 137500, 112500, |
606 | 97500 , 62500, 37500 , 12500 | 606 | 97500 , 62500, 37500 , 12500 |
607 | }; | 607 | }; |
608 | int afc=0; | ||
609 | __u8 reg = 0; | 608 | __u8 reg = 0; |
610 | 609 | ||
611 | if (1 == tuner_i2c_xfer_recv(&priv->i2c_props,®,1)) | 610 | if (priv->mode != V4L2_TUNER_RADIO) |
612 | afc = AFC_BITS_2_kHz[(reg>>1)&0x0f]; | 611 | return 0; |
613 | 612 | if (1 == tuner_i2c_xfer_recv(&priv->i2c_props, ®, 1)) | |
614 | return afc; | 613 | *afc = AFC_BITS_2_kHz[(reg >> 1) & 0x0f]; |
614 | return 0; | ||
615 | } | 615 | } |
616 | 616 | ||
617 | static void tda9887_standby(struct dvb_frontend *fe) | 617 | static void tda9887_standby(struct dvb_frontend *fe) |
diff --git a/drivers/media/v4l2-core/tuner-core.c b/drivers/media/v4l2-core/tuner-core.c index 7d60c5d38ca0..a0b10e6b55ed 100644 --- a/drivers/media/v4l2-core/tuner-core.c +++ b/drivers/media/v4l2-core/tuner-core.c | |||
@@ -228,16 +228,6 @@ static int fe_has_signal(struct dvb_frontend *fe) | |||
228 | return strength; | 228 | return strength; |
229 | } | 229 | } |
230 | 230 | ||
231 | static int fe_get_afc(struct dvb_frontend *fe) | ||
232 | { | ||
233 | s32 afc; | ||
234 | |||
235 | if (fe->ops.tuner_ops.get_afc(fe, &afc) < 0) | ||
236 | return 0; | ||
237 | |||
238 | return afc; | ||
239 | } | ||
240 | |||
241 | static int fe_set_config(struct dvb_frontend *fe, void *priv_cfg) | 231 | static int fe_set_config(struct dvb_frontend *fe, void *priv_cfg) |
242 | { | 232 | { |
243 | struct dvb_tuner_ops *fe_tuner_ops = &fe->ops.tuner_ops; | 233 | struct dvb_tuner_ops *fe_tuner_ops = &fe->ops.tuner_ops; |
@@ -448,7 +438,7 @@ static void set_type(struct i2c_client *c, unsigned int type, | |||
448 | if (fe_tuner_ops->get_rf_strength) | 438 | if (fe_tuner_ops->get_rf_strength) |
449 | analog_ops->has_signal = fe_has_signal; | 439 | analog_ops->has_signal = fe_has_signal; |
450 | if (fe_tuner_ops->get_afc) | 440 | if (fe_tuner_ops->get_afc) |
451 | analog_ops->get_afc = fe_get_afc; | 441 | analog_ops->get_afc = fe_tuner_ops->get_afc; |
452 | 442 | ||
453 | } else { | 443 | } else { |
454 | t->name = analog_ops->info.name; | 444 | t->name = analog_ops->info.name; |
@@ -1190,7 +1180,7 @@ static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) | |||
1190 | if (check_mode(t, vt->type) == -EINVAL) | 1180 | if (check_mode(t, vt->type) == -EINVAL) |
1191 | return 0; | 1181 | return 0; |
1192 | if (vt->type == t->mode && analog_ops->get_afc) | 1182 | if (vt->type == t->mode && analog_ops->get_afc) |
1193 | vt->afc = analog_ops->get_afc(&t->fe); | 1183 | analog_ops->get_afc(&t->fe, &vt->afc); |
1194 | if (analog_ops->has_signal) | 1184 | if (analog_ops->has_signal) |
1195 | vt->signal = analog_ops->has_signal(&t->fe); | 1185 | vt->signal = analog_ops->has_signal(&t->fe); |
1196 | if (vt->type != V4L2_TUNER_RADIO) { | 1186 | if (vt->type != V4L2_TUNER_RADIO) { |