diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-07-13 01:23:11 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-07-13 20:21:00 -0300 |
commit | a1ad5ec7f520c559becab2e989a397f1d6ac5eb0 (patch) | |
tree | 74e3d8b7b299113a8d08cb7bd92d1ff59fc72ae6 | |
parent | 2d1969312d6319d28ae9609a84f969b6933bd51c (diff) |
[media] tuner-core: fix a 2.6.39 regression with mt20xx
As Simon reported, digital TV broke with mt20xx tuner due to
commit ad020dc2fe9039628cf6cef42cd1b76531ee8411.
The mt20xx tuner passes V4L2_TUNER_DIGITAL_TV to tuner core. However, the
check_mode code now doesn't handle it well. Change the logic there to
avoid the breakage, and fix a test for analog-only at g_tuner.
Reported-by: Simon Arlott <simon@fire.lp0.eu>
Tested-by: Simon Arlott <simon@fire.lp0.eu>
Cc: stable@kernel.org
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/video/tuner-core.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index cfa9f7efe93..a03945ab9f0 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c @@ -714,10 +714,19 @@ static int tuner_remove(struct i2c_client *client) * returns 0. * This function is needed for boards that have a separate tuner for * radio (like devices with tea5767). + * NOTE: mt20xx uses V4L2_TUNER_DIGITAL_TV and calls set_tv_freq to + * select a TV frequency. So, t_mode = T_ANALOG_TV could actually + * be used to represent a Digital TV too. */ static inline int check_mode(struct tuner *t, enum v4l2_tuner_type mode) { - if ((1 << mode & t->mode_mask) == 0) + int t_mode; + if (mode == V4L2_TUNER_RADIO) + t_mode = T_RADIO; + else + t_mode = T_ANALOG_TV; + + if ((t_mode & t->mode_mask) == 0) return -EINVAL; return 0; @@ -984,7 +993,7 @@ static void tuner_status(struct dvb_frontend *fe) case V4L2_TUNER_RADIO: p = "radio"; break; - case V4L2_TUNER_DIGITAL_TV: + case V4L2_TUNER_DIGITAL_TV: /* Used by mt20xx */ p = "digital TV"; break; case V4L2_TUNER_ANALOG_TV: @@ -1135,9 +1144,8 @@ static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) return 0; if (vt->type == t->mode && analog_ops->get_afc) vt->afc = analog_ops->get_afc(&t->fe); - if (vt->type == V4L2_TUNER_ANALOG_TV) + if (t->mode != V4L2_TUNER_RADIO) { vt->capability |= V4L2_TUNER_CAP_NORM; - if (vt->type != V4L2_TUNER_RADIO) { vt->rangelow = tv_range[0] * 16; vt->rangehigh = tv_range[1] * 16; return 0; |