CHROMIUM: [media] rk3288-vpu: Add VP8 decoder to V4L2 API implementation
[firefly-linux-kernel-4.4.55.git] / drivers / media / dvb-frontends / stv090x.c
index 56d470ad5a823ae9825d7d36dcff383a6dfb87a4..25bdf6e0f9632d18a64c0c4e42bda005d0d80c51 100644 (file)
@@ -35,6 +35,9 @@
 #include "stv090x.h"
 #include "stv090x_priv.h"
 
+/* Max transfer size done by I2C transfer functions */
+#define MAX_XFER_SIZE  64
+
 static unsigned int verbose;
 module_param(verbose, int, 0644);
 
@@ -722,9 +725,16 @@ static int stv090x_write_regs(struct stv090x_state *state, unsigned int reg, u8
 {
        const struct stv090x_config *config = state->config;
        int ret;
-       u8 buf[2 + count];
+       u8 buf[MAX_XFER_SIZE];
        struct i2c_msg i2c_msg = { .addr = config->address, .flags = 0, .buf = buf, .len = 2 + count };
 
+       if (2 + count > sizeof(buf)) {
+               printk(KERN_WARNING
+                      "%s: i2c wr reg=%04x: len=%d is too big!\n",
+                      KBUILD_MODNAME, reg, count);
+               return -EINVAL;
+       }
+
        buf[0] = reg >> 8;
        buf[1] = reg & 0xff;
        memcpy(&buf[2], data, count);
@@ -2136,7 +2146,7 @@ static int stv090x_get_coldlock(struct stv090x_state *state, s32 timeout_dmd)
 
        u32 reg;
        s32 car_step, steps, cur_step, dir, freq, timeout_lock;
-       int lock = 0;
+       int lock;
 
        if (state->srate >= 10000000)
                timeout_lock = timeout_dmd / 3;
@@ -2144,98 +2154,96 @@ static int stv090x_get_coldlock(struct stv090x_state *state, s32 timeout_dmd)
                timeout_lock = timeout_dmd / 2;
 
        lock = stv090x_get_dmdlock(state, timeout_lock); /* cold start wait */
-       if (!lock) {
-               if (state->srate >= 10000000) {
-                       if (stv090x_chk_tmg(state)) {
-                               if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
-                                       goto err;
-                               if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0)
-                                       goto err;
-                               lock = stv090x_get_dmdlock(state, timeout_dmd);
-                       } else {
-                               lock = 0;
-                       }
-               } else {
-                       if (state->srate <= 4000000)
-                               car_step = 1000;
-                       else if (state->srate <= 7000000)
-                               car_step = 2000;
-                       else if (state->srate <= 10000000)
-                               car_step = 3000;
-                       else
-                               car_step = 5000;
-
-                       steps  = (state->search_range / 1000) / car_step;
-                       steps /= 2;
-                       steps  = 2 * (steps + 1);
-                       if (steps < 0)
-                               steps = 2;
-                       else if (steps > 12)
-                               steps = 12;
-
-                       cur_step = 1;
-                       dir = 1;
-
-                       if (!lock) {
-                               freq = state->frequency;
-                               state->tuner_bw = stv090x_car_width(state->srate, state->rolloff) + state->srate;
-                               while ((cur_step <= steps) && (!lock)) {
-                                       if (dir > 0)
-                                               freq += cur_step * car_step;
-                                       else
-                                               freq -= cur_step * car_step;
-
-                                       /* Setup tuner */
-                                       if (stv090x_i2c_gate_ctrl(state, 1) < 0)
-                                               goto err;
+       if (lock)
+               return lock;
 
-                                       if (state->config->tuner_set_frequency) {
-                                               if (state->config->tuner_set_frequency(fe, freq) < 0)
-                                                       goto err_gateoff;
-                                       }
+       if (state->srate >= 10000000) {
+               if (stv090x_chk_tmg(state)) {
+                       if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
+                               goto err;
+                       if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0)
+                               goto err;
+                       return stv090x_get_dmdlock(state, timeout_dmd);
+               }
+               return 0;
+       }
 
-                                       if (state->config->tuner_set_bandwidth) {
-                                               if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0)
-                                                       goto err_gateoff;
-                                       }
+       if (state->srate <= 4000000)
+               car_step = 1000;
+       else if (state->srate <= 7000000)
+               car_step = 2000;
+       else if (state->srate <= 10000000)
+               car_step = 3000;
+       else
+               car_step = 5000;
 
-                                       if (stv090x_i2c_gate_ctrl(state, 0) < 0)
-                                               goto err;
+       steps  = (state->search_range / 1000) / car_step;
+       steps /= 2;
+       steps  = 2 * (steps + 1);
+       if (steps < 0)
+               steps = 2;
+       else if (steps > 12)
+               steps = 12;
 
-                                       msleep(50);
+       cur_step = 1;
+       dir = 1;
 
-                                       if (stv090x_i2c_gate_ctrl(state, 1) < 0)
-                                               goto err;
+       freq = state->frequency;
+       state->tuner_bw = stv090x_car_width(state->srate, state->rolloff) + state->srate;
+       while ((cur_step <= steps) && (!lock)) {
+               if (dir > 0)
+                       freq += cur_step * car_step;
+               else
+                       freq -= cur_step * car_step;
 
-                                       if (state->config->tuner_get_status) {
-                                               if (state->config->tuner_get_status(fe, &reg) < 0)
-                                                       goto err_gateoff;
-                                       }
+               /* Setup tuner */
+               if (stv090x_i2c_gate_ctrl(state, 1) < 0)
+                       goto err;
 
-                                       if (reg)
-                                               dprintk(FE_DEBUG, 1, "Tuner phase locked");
-                                       else
-                                               dprintk(FE_DEBUG, 1, "Tuner unlocked");
+               if (state->config->tuner_set_frequency) {
+                       if (state->config->tuner_set_frequency(fe, freq) < 0)
+                               goto err_gateoff;
+               }
 
-                                       if (stv090x_i2c_gate_ctrl(state, 0) < 0)
-                                               goto err;
+               if (state->config->tuner_set_bandwidth) {
+                       if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0)
+                               goto err_gateoff;
+               }
 
-                                       STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1c);
-                                       if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0x00) < 0)
-                                               goto err;
-                                       if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0x00) < 0)
-                                               goto err;
-                                       if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
-                                               goto err;
-                                       if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0)
-                                               goto err;
-                                       lock = stv090x_get_dmdlock(state, (timeout_dmd / 3));
+               if (stv090x_i2c_gate_ctrl(state, 0) < 0)
+                       goto err;
 
-                                       dir *= -1;
-                                       cur_step++;
-                               }
-                       }
+               msleep(50);
+
+               if (stv090x_i2c_gate_ctrl(state, 1) < 0)
+                       goto err;
+
+               if (state->config->tuner_get_status) {
+                       if (state->config->tuner_get_status(fe, &reg) < 0)
+                               goto err_gateoff;
                }
+
+               if (reg)
+                       dprintk(FE_DEBUG, 1, "Tuner phase locked");
+               else
+                       dprintk(FE_DEBUG, 1, "Tuner unlocked");
+
+               if (stv090x_i2c_gate_ctrl(state, 0) < 0)
+                       goto err;
+
+               STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1c);
+               if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0x00) < 0)
+                       goto err;
+               if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0x00) < 0)
+                       goto err;
+               if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
+                       goto err;
+               if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0)
+                       goto err;
+               lock = stv090x_get_dmdlock(state, (timeout_dmd / 3));
+
+               dir *= -1;
+               cur_step++;
        }
 
        return lock;
@@ -2653,13 +2661,9 @@ static enum stv090x_signal_state stv090x_get_sig_params(struct stv090x_state *st
                        return STV090x_RANGEOK;
                else if (abs(offst_freq) <= (stv090x_car_width(state->srate, state->rolloff) / 2000))
                        return STV090x_RANGEOK;
-               else
-                       return STV090x_OUTOFRANGE; /* Out of Range */
        } else {
                if (abs(offst_freq) <= ((state->search_range / 2000) + 500))
                        return STV090x_RANGEOK;
-               else
-                       return STV090x_OUTOFRANGE;
        }
 
        return STV090x_OUTOFRANGE;
@@ -2779,6 +2783,12 @@ static u8 stv090x_optimize_carloop(struct stv090x_state *state, enum stv090x_mod
                                aclc = car_loop[i].crl_pilots_off_30;
                }
        } else { /* 16APSK and 32APSK */
+               /*
+                * This should never happen in practice, except if
+                * something is really wrong at the car_loop table.
+                */
+               if (i >= 11)
+                       i = 10;
                if (state->srate <= 3000000)
                        aclc = car_loop_apsk_low[i].crl_pilots_on_2;
                else if (state->srate <= 7000000)
@@ -3460,7 +3470,20 @@ static enum dvbfe_search stv090x_search(struct dvb_frontend *fe)
        if (props->frequency == 0)
                return DVBFE_ALGO_SEARCH_INVALID;
 
-       state->delsys = props->delivery_system;
+       switch (props->delivery_system) {
+       case SYS_DSS:
+               state->delsys = STV090x_DSS;
+               break;
+       case SYS_DVBS:
+               state->delsys = STV090x_DVBS1;
+               break;
+       case SYS_DVBS2:
+               state->delsys = STV090x_DVBS2;
+               break;
+       default:
+               return DVBFE_ALGO_SEARCH_INVALID;
+       }
+
        state->frequency = props->frequency;
        state->srate = props->symbol_rate;
        state->search_mode = STV090x_SEARCH_AUTO;
@@ -3709,7 +3732,7 @@ static int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr)
        return 0;
 }
 
-static int stv090x_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
+static int stv090x_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone)
 {
        struct stv090x_state *state = fe->demodulator_priv;
        u32 reg;
@@ -3799,7 +3822,8 @@ err:
        return -1;
 }
 
-static int stv090x_send_diseqc_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst)
+static int stv090x_send_diseqc_burst(struct dvb_frontend *fe,
+                                    enum fe_sec_mini_cmd burst)
 {
        struct stv090x_state *state = fe->demodulator_priv;
        u32 reg, idle = 0, fifo_full = 1;
@@ -4849,8 +4873,8 @@ err:
        return -1;
 }
 
-int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio, u8 dir, u8 value,
-               u8 xor_value)
+static int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio, u8 dir,
+                           u8 value, u8 xor_value)
 {
        struct stv090x_state *state = fe->demodulator_priv;
        u8 reg = 0;
@@ -4861,7 +4885,6 @@ int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio, u8 dir, u8 value,
 
        return stv090x_write_reg(state, STV090x_GPIOxCFG(gpio), reg);
 }
-EXPORT_SYMBOL(stv090x_set_gpio);
 
 static struct dvb_frontend_ops stv090x_ops = {
        .delsys = { SYS_DVBS, SYS_DVBS2, SYS_DSS },
@@ -4898,7 +4921,7 @@ static struct dvb_frontend_ops stv090x_ops = {
 };
 
 
-struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
+struct dvb_frontend *stv090x_attach(struct stv090x_config *config,
                                    struct i2c_adapter *i2c,
                                    enum stv090x_demodulator demod)
 {
@@ -4959,6 +4982,8 @@ struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
        if (config->diseqc_envelope_mode)
                stv090x_send_diseqc_burst(&state->frontend, SEC_MINI_A);
 
+       config->set_gpio = stv090x_set_gpio;
+
        dprintk(FE_ERROR, 1, "Attaching %s demodulator(%d) Cut=0x%02x",
               state->device == STV0900 ? "STV0900" : "STV0903",
               demod,