[media] mb86a20s: improve error handling at get_frontend
authorMauro Carvalho Chehab <mchehab@redhat.com>
Mon, 14 Jan 2013 12:26:09 +0000 (09:26 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Tue, 22 Jan 2013 10:10:52 +0000 (08:10 -0200)
The read/write errors are not handled well on get_frontend. Fix it,
by letting the frontend cached values to represent the DVB properties
that were successfully retrieved.
While here, use "c" for dtv_frontend_properties cache, instead of
"p", as this is more common.

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/dvb-frontends/mb86a20s.c

index fade566927c3ee93d65cba68a14309c798051d7b..4ff3a0c9d977984d9129be0f4c78d7f019e6b94f 100644 (file)
@@ -1,11 +1,9 @@
 /*
  *   Fujitu mb86a20s ISDB-T/ISDB-Tsb Module driver
  *
- *   Copyright (C) 2010 Mauro Carvalho Chehab <mchehab@redhat.com>
+ *   Copyright (C) 2010-2013 Mauro Carvalho Chehab <mchehab@redhat.com>
  *   Copyright (C) 2009-2010 Douglas Landgraf <dougsland@redhat.com>
  *
- *   FIXME: Need to port to DVB v5.2 API
- *
  *   This program is free software; you can redistribute it and/or
  *   modify it under the terms of the GNU General Public License as
  *   published by the Free Software Foundation version 2.
@@ -360,7 +358,7 @@ static int mb86a20s_set_frontend(struct dvb_frontend *fe)
        /*
         * FIXME: Properly implement the set frontend properties
         */
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 #endif
 
        dprintk("\n");
@@ -507,93 +505,117 @@ static int mb86a20s_get_segment_count(struct mb86a20s_state *state,
        return count;
 }
 
+static void mb86a20s_reset_frontend_cache(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+
+       /* Fixed parameters */
+       c->delivery_system = SYS_ISDBT;
+       c->bandwidth_hz = 6000000;
+
+       /* Initialize values that will be later autodetected */
+       c->isdbt_layer_enabled = 0;
+       c->transmission_mode = TRANSMISSION_MODE_AUTO;
+       c->guard_interval = GUARD_INTERVAL_AUTO;
+       c->isdbt_sb_mode = 0;
+       c->isdbt_sb_segment_count = 0;
+}
+
 static int mb86a20s_get_frontend(struct dvb_frontend *fe)
 {
        struct mb86a20s_state *state = fe->demodulator_priv;
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
        int i, rc;
 
-       /* Fixed parameters */
-       p->delivery_system = SYS_ISDBT;
-       p->bandwidth_hz = 6000000;
+       /* Reset frontend cache to default values */
+       mb86a20s_reset_frontend_cache(fe);
 
        if (fe->ops.i2c_gate_ctrl)
                fe->ops.i2c_gate_ctrl(fe, 0);
 
        /* Check for partial reception */
        rc = mb86a20s_writereg(state, 0x6d, 0x85);
-       if (rc >= 0)
-               rc = mb86a20s_readreg(state, 0x6e);
-       if (rc >= 0)
-               p->isdbt_partial_reception = (rc & 0x10) ? 1 : 0;
+       if (rc < 0)
+               return rc;
+       rc = mb86a20s_readreg(state, 0x6e);
+       if (rc < 0)
+               return rc;
+       c->isdbt_partial_reception = (rc & 0x10) ? 1 : 0;
 
        /* Get per-layer data */
-       p->isdbt_layer_enabled = 0;
+
        for (i = 0; i < 3; i++) {
                rc = mb86a20s_get_segment_count(state, i);
-                       if (rc >= 0 && rc < 14)
-                               p->layer[i].segment_count = rc;
-               if (rc == 0x0f)
+               if (rc < 0)
+                       goto error;
+               if (rc >= 0 && rc < 14)
+                       c->layer[i].segment_count = rc;
+               else {
+                       c->layer[i].segment_count = 0;
                        continue;
-               p->isdbt_layer_enabled |= 1 << i;
+               }
+               c->isdbt_layer_enabled |= 1 << i;
                rc = mb86a20s_get_modulation(state, i);
-                       if (rc >= 0)
-                               p->layer[i].modulation = rc;
+               if (rc < 0)
+                       goto error;
+               c->layer[i].modulation = rc;
                rc = mb86a20s_get_fec(state, i);
-                       if (rc >= 0)
-                               p->layer[i].fec = rc;
+               if (rc < 0)
+                       goto error;
+               c->layer[i].fec = rc;
                rc = mb86a20s_get_interleaving(state, i);
-                       if (rc >= 0)
-                               p->layer[i].interleaving = rc;
+               if (rc < 0)
+                       goto error;
+               c->layer[i].interleaving = rc;
        }
 
-       p->isdbt_sb_mode = 0;
        rc = mb86a20s_writereg(state, 0x6d, 0x84);
-       if ((rc >= 0) && ((rc & 0x60) == 0x20)) {
-               p->isdbt_sb_mode = 1;
+       if (rc < 0)
+               return rc;
+       if ((rc & 0x60) == 0x20) {
+               c->isdbt_sb_mode = 1;
                /* At least, one segment should exist */
-               if (!p->isdbt_sb_segment_count)
-                       p->isdbt_sb_segment_count = 1;
-       } else
-               p->isdbt_sb_segment_count = 0;
+               if (!c->isdbt_sb_segment_count)
+                       c->isdbt_sb_segment_count = 1;
+       }
 
        /* Get transmission mode and guard interval */
-       p->transmission_mode = TRANSMISSION_MODE_AUTO;
-       p->guard_interval = GUARD_INTERVAL_AUTO;
        rc = mb86a20s_readreg(state, 0x07);
-       if (rc >= 0) {
-               if ((rc & 0x60) == 0x20) {
-                       switch (rc & 0x0c >> 2) {
-                       case 0:
-                               p->transmission_mode = TRANSMISSION_MODE_2K;
-                               break;
-                       case 1:
-                               p->transmission_mode = TRANSMISSION_MODE_4K;
-                               break;
-                       case 2:
-                               p->transmission_mode = TRANSMISSION_MODE_8K;
-                               break;
-                       }
+       if (rc < 0)
+               return rc;
+       if ((rc & 0x60) == 0x20) {
+               switch (rc & 0x0c >> 2) {
+               case 0:
+                       c->transmission_mode = TRANSMISSION_MODE_2K;
+                       break;
+               case 1:
+                       c->transmission_mode = TRANSMISSION_MODE_4K;
+                       break;
+               case 2:
+                       c->transmission_mode = TRANSMISSION_MODE_8K;
+                       break;
                }
-               if (!(rc & 0x10)) {
-                       switch (rc & 0x3) {
-                       case 0:
-                               p->guard_interval = GUARD_INTERVAL_1_4;
-                               break;
-                       case 1:
-                               p->guard_interval = GUARD_INTERVAL_1_8;
-                               break;
-                       case 2:
-                               p->guard_interval = GUARD_INTERVAL_1_16;
-                               break;
-                       }
+       }
+       if (!(rc & 0x10)) {
+               switch (rc & 0x3) {
+               case 0:
+                       c->guard_interval = GUARD_INTERVAL_1_4;
+                       break;
+               case 1:
+                       c->guard_interval = GUARD_INTERVAL_1_8;
+                       break;
+               case 2:
+                       c->guard_interval = GUARD_INTERVAL_1_16;
+                       break;
                }
        }
 
+error:
        if (fe->ops.i2c_gate_ctrl)
                fe->ops.i2c_gate_ctrl(fe, 1);
 
-       return 0;
+       return rc;
+
 }
 
 static int mb86a20s_tune(struct dvb_frontend *fe,