V4L/DVB (13985): [STV090x] reset mclk and dev_ver of internal structure after allocating
[safe/jmp/linux-2.6] / drivers / media / dvb / frontends / stv090x.c
index 2a25dd1..3c5fba8 100644 (file)
@@ -4199,6 +4199,71 @@ static int stv090x_set_tspath(struct stv090x_state *state)
        default:
                break;
        }
+
+       if (state->config->ts1_clk > 0) {
+               u32 speed;
+
+               switch (state->config->ts1_mode) {
+               case STV090x_TSMODE_PARALLEL_PUNCTURED:
+               case STV090x_TSMODE_DVBCI:
+               default:
+                       speed = state->internal->mclk /
+                               (state->config->ts1_clk / 4);
+                       if (speed < 0x08)
+                               speed = 0x08;
+                       if (speed > 0xFF)
+                               speed = 0xFF;
+                       break;
+               case STV090x_TSMODE_SERIAL_PUNCTURED:
+               case STV090x_TSMODE_SERIAL_CONTINUOUS:
+                       speed = state->internal->mclk /
+                               (state->config->ts1_clk / 32);
+                       if (speed < 0x20)
+                               speed = 0x20;
+                       if (speed > 0xFF)
+                               speed = 0xFF;
+                       break;
+               }
+               reg = stv090x_read_reg(state, STV090x_P1_TSCFGM);
+               STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3);
+               if (stv090x_write_reg(state, STV090x_P1_TSCFGM, reg) < 0)
+                       goto err;
+               if (stv090x_write_reg(state, STV090x_P1_TSSPEED, speed) < 0)
+                       goto err;
+       }
+
+       if (state->config->ts2_clk > 0) {
+               u32 speed;
+
+               switch (state->config->ts2_mode) {
+               case STV090x_TSMODE_PARALLEL_PUNCTURED:
+               case STV090x_TSMODE_DVBCI:
+               default:
+                       speed = state->internal->mclk /
+                               (state->config->ts2_clk / 4);
+                       if (speed < 0x08)
+                               speed = 0x08;
+                       if (speed > 0xFF)
+                               speed = 0xFF;
+                       break;
+               case STV090x_TSMODE_SERIAL_PUNCTURED:
+               case STV090x_TSMODE_SERIAL_CONTINUOUS:
+                       speed = state->internal->mclk /
+                               (state->config->ts2_clk / 32);
+                       if (speed < 0x20)
+                               speed = 0x20;
+                       if (speed > 0xFF)
+                               speed = 0xFF;
+                       break;
+               }
+               reg = stv090x_read_reg(state, STV090x_P2_TSCFGM);
+               STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3);
+               if (stv090x_write_reg(state, STV090x_P2_TSCFGM, reg) < 0)
+                       goto err;
+               if (stv090x_write_reg(state, STV090x_P2_TSSPEED, speed) < 0)
+                       goto err;
+       }
+
        reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);
        STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x01);
        if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
@@ -4227,6 +4292,15 @@ static int stv090x_init(struct dvb_frontend *fe)
        const struct stv090x_config *config = state->config;
        u32 reg;
 
+       if (state->internal->mclk == 0) {
+               stv090x_set_mclk(state, 135000000, config->xtal); /* 135 Mhz */
+               msleep(5);
+               if (stv090x_write_reg(state, STV090x_SYNTCTRL,
+                                     0x20 | config->clk_mode) < 0)
+                       goto err;
+               stv090x_get_mclk(state);
+       }
+
        if (stv090x_wakeup(fe) < 0) {
                dprintk(FE_ERROR, 1, "Error waking device");
                goto err;
@@ -4361,12 +4435,6 @@ static int stv090x_setup(struct dvb_frontend *fe)
        if (stv090x_write_reg(state, STV090x_TSTRES0, 0x00) < 0)
                goto err;
 
-       stv090x_set_mclk(state, 135000000, config->xtal); /* 135 Mhz */
-       msleep(5);
-       if (stv090x_write_reg(state, STV090x_SYNTCTRL, 0x20 | config->clk_mode) < 0)
-               goto err;
-       stv090x_get_mclk(state);
-
        return 0;
 err:
        dprintk(FE_ERROR, 1, "I/O error");
@@ -4449,6 +4517,8 @@ struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
                                          GFP_KERNEL);
                temp_int = append_internal(state->internal);
                state->internal->num_used = 1;
+               state->internal->mclk = 0;
+               state->internal->dev_ver = 0;
                state->internal->i2c_adap = state->i2c;
                state->internal->i2c_addr = state->config->address;
                dprintk(FE_INFO, 1, "Create New Internal Structure!");