Merge to Fedora kernel-2.6.18-1.2224_FC5 patched with stable patch-2.6.18.1-vs2.0...
[linux-2.6.git] / drivers / media / dvb / frontends / stv0297.c
index eb15676..1ca6424 100644 (file)
@@ -32,7 +32,6 @@
 
 struct stv0297_state {
        struct i2c_adapter *i2c;
-       struct dvb_frontend_ops ops;
        const struct stv0297_config *config;
        struct dvb_frontend frontend;
 
@@ -68,19 +67,25 @@ static int stv0297_readreg(struct stv0297_state *state, u8 reg)
        int ret;
        u8 b0[] = { reg };
        u8 b1[] = { 0 };
-       struct i2c_msg msg[] = { {.addr = state->config->demod_address,.flags = 0,.buf = b0,.len =
-                                 1},
-       {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b1,.len = 1}
-       };
+       struct i2c_msg msg[] = { {.addr = state->config->demod_address,.flags = 0,.buf = b0,.len = 1},
+                                {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b1,.len = 1}
+                              };
 
        // this device needs a STOP between the register and data
-       if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) {
-               dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret);
-               return -1;
-       }
-       if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) {
-               dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret);
-               return -1;
+       if (state->config->stop_during_read) {
+               if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) {
+                       dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret);
+                       return -1;
+               }
+               if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) {
+                       dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret);
+                       return -1;
+               }
+       } else {
+               if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) {
+                       dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret);
+                       return -1;
+               }
        }
 
        return b1[0];
@@ -107,13 +112,20 @@ static int stv0297_readregs(struct stv0297_state *state, u8 reg1, u8 * b, u8 len
        };
 
        // this device needs a STOP between the register and data
-       if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) {
-               dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret);
-               return -1;
-       }
-       if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) {
-               dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret);
-               return -1;
+       if (state->config->stop_during_read) {
+               if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) {
+                       dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret);
+                       return -1;
+               }
+               if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) {
+                       dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret);
+                       return -1;
+               }
+       } else {
+               if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) {
+                       dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret);
+                       return -1;
+               }
        }
 
        return 0;
@@ -276,12 +288,14 @@ static int stv0297_set_inversion(struct stv0297_state *state, fe_spectral_invers
        return 0;
 }
 
-int stv0297_enable_plli2c(struct dvb_frontend *fe)
+static int stv0297_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
 {
        struct stv0297_state *state = fe->demodulator_priv;
 
-       stv0297_writereg(state, 0x87, 0x78);
-       stv0297_writereg(state, 0x86, 0xc8);
+       if (enable) {
+               stv0297_writereg(state, 0x87, 0x78);
+               stv0297_writereg(state, 0x86, 0xc8);
+       }
 
        return 0;
 }
@@ -296,9 +310,6 @@ static int stv0297_init(struct dvb_frontend *fe)
                stv0297_writereg(state, state->config->inittab[i], state->config->inittab[i+1]);
        msleep(200);
 
-       if (state->config->pll_init)
-               state->config->pll_init(fe);
-
        return 0;
 }
 
@@ -389,7 +400,7 @@ static int stv0297_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par
        case QAM_32:
        case QAM_64:
                delay = 100;
-               sweeprate = 1500;
+               sweeprate = 1000;
                break;
 
        case QAM_128:
@@ -421,7 +432,10 @@ static int stv0297_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par
        }
 
        stv0297_init(fe);
-       state->config->pll_set(fe, p);
+       if (fe->ops.tuner_ops.set_params) {
+               fe->ops.tuner_ops.set_params(fe, p);
+               if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
+       }
 
        /* clear software interrupts */
        stv0297_writereg(state, 0x82, 0x0);
@@ -634,7 +648,6 @@ struct dvb_frontend *stv0297_attach(const struct stv0297_config *config,
        /* setup the state */
        state->config = config;
        state->i2c = i2c;
-       memcpy(&state->ops, &stv0297_ops, sizeof(struct dvb_frontend_ops));
        state->base_freq = 0;
 
        /* check if the demod is there */
@@ -642,7 +655,7 @@ struct dvb_frontend *stv0297_attach(const struct stv0297_config *config,
                goto error;
 
        /* create dvb_frontend */
-       state->frontend.ops = &state->ops;
+       memcpy(&state->frontend.ops, &stv0297_ops, sizeof(struct dvb_frontend_ops));
        state->frontend.demodulator_priv = state;
        return &state->frontend;
 
@@ -668,6 +681,7 @@ static struct dvb_frontend_ops stv0297_ops = {
 
        .init = stv0297_init,
        .sleep = stv0297_sleep,
+       .i2c_gate_ctrl = stv0297_i2c_gate_ctrl,
 
        .set_frontend = stv0297_set_frontend,
        .get_frontend = stv0297_get_frontend,
@@ -684,4 +698,3 @@ MODULE_AUTHOR("Dennis Noermann and Andrew de Quincey");
 MODULE_LICENSE("GPL");
 
 EXPORT_SYMBOL(stv0297_attach);
-EXPORT_SYMBOL(stv0297_enable_plli2c);