aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2013-04-06 03:35:27 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-04-14 18:43:40 -0400
commita2192cf47f593681cd65798880853c5224066c81 (patch)
tree1883c7aa872f02413ff8c3da558e40c4f3b3ab1c /drivers
parentd047795c590f63d42160b84ac778b09af297d914 (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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/dvb-core/dvb_frontend.h2
-rw-r--r--drivers/media/tuners/tda9887.c14
-rw-r--r--drivers/media/v4l2-core/tuner-core.c14
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
599static int tda9887_get_afc(struct dvb_frontend *fe) 599static 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,&reg,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, &reg, 1))
614 return afc; 613 *afc = AFC_BITS_2_kHz[(reg >> 1) & 0x0f];
614 return 0;
615} 615}
616 616
617static void tda9887_standby(struct dvb_frontend *fe) 617static 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
231static 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
241static int fe_set_config(struct dvb_frontend *fe, void *priv_cfg) 231static 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) {