[media] tuner-core/tda9887: get_afc can be tuner mode specific
authorHans Verkuil <hans.verkuil@cisco.com>
Sat, 6 Apr 2013 07:35:27 +0000 (04:35 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Sun, 14 Apr 2013 22:43:40 +0000 (19:43 -0300)
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>
drivers/media/dvb-core/dvb_frontend.h
drivers/media/tuners/tda9887.c
drivers/media/v4l2-core/tuner-core.c

index b34922a0815643986da4d0d12ba355f5674bce3d..44fad1cbcb09ae02eb55ad7aea646fa5d8f81dcf 100644 (file)
@@ -246,7 +246,7 @@ struct analog_demod_ops {
        void (*set_params)(struct dvb_frontend *fe,
                           struct analog_parameters *params);
        int  (*has_signal)(struct dvb_frontend *fe);
-       int  (*get_afc)(struct dvb_frontend *fe);
+       int  (*get_afc)(struct dvb_frontend *fe, s32 *afc);
        void (*tuner_status)(struct dvb_frontend *fe);
        void (*standby)(struct dvb_frontend *fe);
        void (*release)(struct dvb_frontend *fe);
index cdb645d574388230eefe87ad8326f58b8c4bdd27..300005c535ba076ba0e90bf0e7e58b1f25f223ab 100644 (file)
@@ -596,22 +596,22 @@ static void tda9887_tuner_status(struct dvb_frontend *fe)
                   priv->data[1], priv->data[2], priv->data[3]);
 }
 
-static int tda9887_get_afc(struct dvb_frontend *fe)
+static int tda9887_get_afc(struct dvb_frontend *fe, s32 *afc)
 {
        struct tda9887_priv *priv = fe->analog_demod_priv;
-       static int AFC_BITS_2_kHz[] = {
+       static const int AFC_BITS_2_kHz[] = {
                -12500,  -37500,  -62500,  -97500,
                -112500, -137500, -162500, -187500,
                187500,  162500,  137500,  112500,
                97500 ,  62500,   37500 ,  12500
        };
-       int afc=0;
        __u8 reg = 0;
 
-       if (1 == tuner_i2c_xfer_recv(&priv->i2c_props,&reg,1))
-               afc = AFC_BITS_2_kHz[(reg>>1)&0x0f];
-
-       return afc;
+       if (priv->mode != V4L2_TUNER_RADIO)
+               return 0;
+       if (1 == tuner_i2c_xfer_recv(&priv->i2c_props, &reg, 1))
+               *afc = AFC_BITS_2_kHz[(reg >> 1) & 0x0f];
+       return 0;
 }
 
 static void tda9887_standby(struct dvb_frontend *fe)
index 7d60c5d38ca0dd9e63017f4c8876c51d0db6219a..a0b10e6b55edc2279fb49033d3eb9856de6fa57c 100644 (file)
@@ -228,16 +228,6 @@ static int fe_has_signal(struct dvb_frontend *fe)
        return strength;
 }
 
-static int fe_get_afc(struct dvb_frontend *fe)
-{
-       s32 afc;
-
-       if (fe->ops.tuner_ops.get_afc(fe, &afc) < 0)
-               return 0;
-
-       return afc;
-}
-
 static int fe_set_config(struct dvb_frontend *fe, void *priv_cfg)
 {
        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,
                if (fe_tuner_ops->get_rf_strength)
                        analog_ops->has_signal = fe_has_signal;
                if (fe_tuner_ops->get_afc)
-                       analog_ops->get_afc = fe_get_afc;
+                       analog_ops->get_afc = fe_tuner_ops->get_afc;
 
        } else {
                t->name = analog_ops->info.name;
@@ -1190,7 +1180,7 @@ static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
        if (check_mode(t, vt->type) == -EINVAL)
                return 0;
        if (vt->type == t->mode && analog_ops->get_afc)
-               vt->afc = analog_ops->get_afc(&t->fe);
+               analog_ops->get_afc(&t->fe, &vt->afc);
        if (analog_ops->has_signal)
                vt->signal = analog_ops->has_signal(&t->fe);
        if (vt->type != V4L2_TUNER_RADIO) {