aboutsummaryrefslogtreecommitdiff
path: root/drivers/media/dvb/dvb-core/dvb_frontend.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-09-15 09:22:18 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-15 09:22:18 -0700
commit043fe50f8085c12651c96f04576eae4d8a22f3d8 (patch)
tree214b4f985ce7d3b1a4961620e2c2f4f5f06e1c35 /drivers/media/dvb/dvb-core/dvb_frontend.c
parent227423904c709a8e60245c97081bbeb4fb500655 (diff)
parentea47689e74a1637fac4f5fc44890f3662c976849 (diff)
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (213 commits) V4L/DVB (12720): em28xx-cards: Add vendor/product id for Kworld DVD Maker 2 V4L/DVB (12713): em28xx: Cleanups at ir_i2c handler V4L/DVB (12712): em28xx: properly load ir-kbd-i2c when needed V4L/DVB (12701): saa7134: ir-kbd-i2c init data needs a persistent object V4L/DVB (12699): cx18: ir-kbd-i2c initialization data should point to a persistent object V4L/DVB (12698): em28xx: ir-kbd-i2c init data needs a persistent object V4L/DVB (12707): gspca - sn9c20x: Add SXGA support to MT9M111 V4L/DVB (12706): gspca - sn9c20x: disable exposure/gain controls for MT9M111 sensors. V4L/DVB (12705): gspca - sn9c20x: Add SXGA support to SOI968 V4L/DVB (12703): gspca - sn9c20x: Reduces size of object V4L/DVB (12704): gspca - sn9c20x: Fix exposure on SOI968 sensors V4L/DVB (12696): gspca - sonixj / sn9c102: Two drivers for 0c45:60fc and 0c45:613e. V4L/DVB (12695): gspca - vc032x: Do the LED work with the sensor hv7131r. V4L/DVB (12694): gspca - vc032x: Change the start exchanges of the sensor hv7131r. V4L/DVB (12693): gspca - sunplus: The brightness is signed. V4L/DVB (12692): gspca - sunplus: Optimize code. V4L/DVB (12691): gspca - sonixj: Don't use mdelay(). V4L/DVB (12690): gspca - pac7311: Webcam 06f8:3009 added. V4L/DVB (12686): dvb-core: check supported QAM modulations V4L/DVB (12685): dvb-core: check fe->ops.set_frontend return value ...
Diffstat (limited to 'drivers/media/dvb/dvb-core/dvb_frontend.c')
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c35
1 files changed, 30 insertions, 5 deletions
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index f50ca7292a7..d13ebcb0c6b 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -72,6 +72,7 @@ MODULE_PARM_DESC(dvb_mfe_wait_time, "Wait up to <mfe_wait_time> seconds on open(
#define FESTATE_ZIGZAG_FAST 32
#define FESTATE_ZIGZAG_SLOW 64
#define FESTATE_DISEQC 128
+#define FESTATE_ERROR 256
#define FESTATE_WAITFORLOCK (FESTATE_TUNING_FAST | FESTATE_TUNING_SLOW | FESTATE_ZIGZAG_FAST | FESTATE_ZIGZAG_SLOW | FESTATE_DISEQC)
#define FESTATE_SEARCHING_FAST (FESTATE_TUNING_FAST | FESTATE_ZIGZAG_FAST)
#define FESTATE_SEARCHING_SLOW (FESTATE_TUNING_SLOW | FESTATE_ZIGZAG_SLOW)
@@ -269,6 +270,7 @@ static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wra
{
int autoinversion;
int ready = 0;
+ int fe_set_err = 0;
struct dvb_frontend_private *fepriv = fe->frontend_priv;
int original_inversion = fepriv->parameters.inversion;
u32 original_frequency = fepriv->parameters.frequency;
@@ -345,7 +347,11 @@ static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wra
if (autoinversion)
fepriv->parameters.inversion = fepriv->inversion;
if (fe->ops.set_frontend)
- fe->ops.set_frontend(fe, &fepriv->parameters);
+ fe_set_err = fe->ops.set_frontend(fe, &fepriv->parameters);
+ if (fe_set_err < 0) {
+ fepriv->state = FESTATE_ERROR;
+ return fe_set_err;
+ }
fepriv->parameters.frequency = original_frequency;
fepriv->parameters.inversion = original_inversion;
@@ -357,6 +363,7 @@ static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wra
static void dvb_frontend_swzigzag(struct dvb_frontend *fe)
{
fe_status_t s = 0;
+ int retval = 0;
struct dvb_frontend_private *fepriv = fe->frontend_priv;
/* if we've got no parameters, just keep idling */
@@ -370,8 +377,12 @@ static void dvb_frontend_swzigzag(struct dvb_frontend *fe)
if (fepriv->tune_mode_flags & FE_TUNE_MODE_ONESHOT) {
if (fepriv->state & FESTATE_RETUNE) {
if (fe->ops.set_frontend)
- fe->ops.set_frontend(fe, &fepriv->parameters);
- fepriv->state = FESTATE_TUNED;
+ retval = fe->ops.set_frontend(fe,
+ &fepriv->parameters);
+ if (retval < 0)
+ fepriv->state = FESTATE_ERROR;
+ else
+ fepriv->state = FESTATE_TUNED;
}
fepriv->delay = 3*HZ;
fepriv->quality = 0;
@@ -449,7 +460,11 @@ static void dvb_frontend_swzigzag(struct dvb_frontend *fe)
fepriv->delay = fepriv->min_delay;
/* peform a tune */
- if (dvb_frontend_swzigzag_autotune(fe, fepriv->check_wrapped)) {
+ retval = dvb_frontend_swzigzag_autotune(fe,
+ fepriv->check_wrapped);
+ if (retval < 0) {
+ return;
+ } else if (retval) {
/* OK, if we've run out of trials at the fast speed.
* Drop back to slow for the _next_ attempt */
fepriv->state = FESTATE_SEARCHING_SLOW;
@@ -823,6 +838,15 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe,
}
}
+ /* check for supported modulation */
+ if (fe->ops.info.type == FE_QAM &&
+ (parms->u.qam.modulation > QAM_AUTO ||
+ !((1 << (parms->u.qam.modulation + 10)) & fe->ops.info.caps))) {
+ printk(KERN_WARNING "DVB: adapter %i frontend %i modulation %u not supported\n",
+ fe->dvb->num, fe->id, parms->u.qam.modulation);
+ return -EINVAL;
+ }
+
return 0;
}
@@ -1499,7 +1523,8 @@ static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *file,
/* if retune was requested but hasn't occured yet, prevent
* that user get signal state from previous tuning */
- if(fepriv->state == FESTATE_RETUNE) {
+ if (fepriv->state == FESTATE_RETUNE ||
+ fepriv->state == FESTATE_ERROR) {
err=0;
*status = 0;
break;