]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/media/dvb/frontends/stb0899_drv.c
V4L/DVB (9416): Hmmph, a proper calculation broke the working behaviour.
[linux-2.6-omap-h63xx.git] / drivers / media / dvb / frontends / stb0899_drv.c
index 598e3348d53473e8107cb17a353f430cbc434af6..cc5db0e8ad06230b452335313da39aa812596b46 100644 (file)
@@ -251,7 +251,6 @@ int _stb0899_read_reg(struct stb0899_state *state, unsigned int reg)
                dprintk(verbose, FE_ERROR, 1, "Reg=[0x%02x], data=%02x",
                        reg, buf);
 
-
        return (unsigned int)buf;
 }
 
@@ -797,6 +796,42 @@ static int stb0899_send_diseqc_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t
        return 0;
 }
 
+static int stb0899_diseqc_init(struct stb0899_state *state)
+{
+       struct dvb_diseqc_master_cmd tx_data;
+       struct dvb_diseqc_slave_reply rx_data;
+
+       u8 f22_tx, f22_rx, reg;
+
+       u32 mclk, tx_freq = 22000, count = 0, i;
+
+       u32 trial = 0;  /* try max = 2 (try 20khz and 17.5 khz) */
+       u32 ret_1 = 0;  /* 20 Khz status        */
+       u32 ret_2 = 0;  /* 17.5 Khz status      */
+
+       tx_data.msg[0] = 0xe2;
+       tx_data.msg_len = 3;
+       reg = stb0899_read_reg(state, STB0899_DISCNTRL2);
+       STB0899_SETFIELD_VAL(ONECHIP_TRX, reg, 0);
+       stb0899_write_reg(state, STB0899_DISCNTRL2, reg);
+
+       /* disable Tx spy       */
+       reg = stb0899_read_reg(state, STB0899_DISCNTRL1);
+       STB0899_SETFIELD_VAL(DISEQCRESET, reg, 1);
+       stb0899_write_reg(state, STB0899_DISCNTRL1, reg);
+
+       reg = stb0899_read_reg(state, STB0899_DISCNTRL1);
+       STB0899_SETFIELD_VAL(DISEQCRESET, reg, 0);
+       stb0899_write_reg(state, STB0899_DISCNTRL1, reg);
+
+       mclk = stb0899_get_mclk(state);
+       f22_tx = mclk / (tx_freq * 32);
+       stb0899_write_reg(state, STB0899_DISF22, f22_tx); /* DiSEqC Tx freq     */
+       state->rx_freq = 20000;
+       f22_rx = mclk / (state->rx_freq * 32);
+
+       return 0;
+}
 
 static int stb0899_sleep(struct dvb_frontend *fe)
 {
@@ -812,6 +847,13 @@ static int stb0899_wakeup(struct dvb_frontend *fe)
        int rc;
        struct stb0899_state *state = fe->demodulator_priv;
 
+       if ((rc = stb0899_write_reg(state, STB0899_SYNTCTRL, STB0899_SELOSCI)))
+               return rc;
+       /* Activate all clocks; DVB-S2 registers are inaccessible otherwise. */
+       if ((rc = stb0899_write_reg(state, STB0899_STOPCLK1, 0x00)))
+               return rc;
+       if ((rc = stb0899_write_reg(state, STB0899_STOPCLK2, 0x00)))
+               return rc;
 
        return 0;
 }
@@ -857,7 +899,7 @@ static int stb0899_init(struct dvb_frontend *fe)
                stb0899_write_reg(state, config->init_tst[i].address, config->init_tst[i].data);
 
        stb0899_init_calc(state);
-//     stb0899_diseqc_init(state);
+       stb0899_diseqc_init(state);
 
        return 0;
 }
@@ -1139,7 +1181,7 @@ static int stb0899_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
        struct stb0899_state *state = fe->demodulator_priv;
        struct stb0899_internal *internal = &state->internal;
 
-       u8 div;
+       u8 div, reg;
 
        /* wait for diseqc idle */
        if (stb0899_wait_diseqc_txidle(state, 100) < 0)
@@ -1150,7 +1192,9 @@ static int stb0899_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
                div = (internal->master_clk / 100) / 5632;
                div = (div + 5) / 10;
                stb0899_write_reg(state, STB0899_DISEQCOCFG, 0x66);
-               stb0899_write_reg(state, STB0899_ACRPRESC, 0x31);
+               reg = stb0899_read_reg(state, STB0899_ACRPRESC);
+               STB0899_SETFIELD_VAL(ACRPRESC, reg, 0x03);
+               stb0899_write_reg(state, STB0899_ACRPRESC, reg);
                stb0899_write_reg(state, STB0899_ACRDIV1, div);
                break;
        case SEC_TONE_OFF:
@@ -1475,8 +1519,8 @@ static enum dvbfe_search stb0899_search(struct dvb_frontend *fe, struct dvbfe_pa
        }
        dprintk(verbose, FE_DEBUG, 1, "delivery system=%d", state->delsys);
 
-//     SearchRange = 3000000; /* Search Bandwidth (3 Mhz, was initially 10  Mhz)       */
-       SearchRange = 10000000; /* Search Bandwidth (3 Mhz, was initially 10  Mhz)      */
+       SearchRange = 3000000; /* Search Bandwidth (3 Mhz, was initially 10  Mhz)       */
+//     SearchRange = 10000000; /* Search Bandwidth (3 Mhz, was initially 10  Mhz)      */
        dprintk(verbose, FE_DEBUG, 1, "Frequency=%d, Srate=%d", i_params->freq, i_params->srate);
        /* checking Search Range is meaningless for a fixed 3 Mhz                       */
        if (INRANGE(i_params->srate, 1000000, 45000000)) {
@@ -1515,7 +1559,7 @@ static enum dvbfe_search stb0899_search(struct dvb_frontend *fe, struct dvbfe_pa
 
                        /* What to do for tuners having no bandwidth setup ?    */
                        if (state->config->tuner_set_bandwidth)
-                               state->config->tuner_set_bandwidth(fe, (13 * (stb0899_carr_width(state) + 10000000)) / 10);
+                               state->config->tuner_set_bandwidth(fe, (135 * (stb0899_carr_width(state) + SearchRange)) / 100);
                        if (state->config->tuner_get_bandwidth)
                                state->config->tuner_get_bandwidth(fe, &internal->tuner_bw);
                        /* Set DVB-S1 AGC               */
@@ -1547,7 +1591,7 @@ static enum dvbfe_search stb0899_search(struct dvb_frontend *fe, struct dvbfe_pa
                        internal->srch_range            = SearchRange;
 
                        if (state->config->tuner_set_bandwidth)
-                               state->config->tuner_set_bandwidth(fe, (stb0899_carr_width(state) + 10000000));
+                               state->config->tuner_set_bandwidth(fe, (135 * (stb0899_carr_width(state) + SearchRange)) / 100);
                        if (state->config->tuner_get_bandwidth)
                                state->config->tuner_get_bandwidth(fe, &internal->tuner_bw);
 
@@ -1825,7 +1869,6 @@ static int stb0899_get_params(struct dvb_frontend *fe, struct dvbfe_params *para
                dprintk(verbose, FE_DEBUG, 1, "Get DSS params");
                params->delsys.dss.symbol_rate          = internal->srate;
                params->delsys.dss.modulation           = DVBFE_MOD_QPSK;
-
                break;
        case DVBFE_DELSYS_DVBS2:
                dprintk(verbose, FE_DEBUG, 1, "Get DVB-S2 params");
@@ -1881,17 +1924,19 @@ static struct dvb_frontend_ops stb0899_ops = {
 struct dvb_frontend *stb0899_attach(struct stb0899_config *config, struct i2c_adapter *i2c)
 {
        struct stb0899_state *state = NULL;
+       enum stb0899_inversion inversion;
 
        state = kzalloc(sizeof (struct stb0899_state), GFP_KERNEL);
        if (state == NULL)
                goto error;
 
+       inversion                               = config->inversion;
        state->verbose                          = verbose;
        state->config                           = config;
        state->i2c                              = i2c;
        state->frontend.ops                     = stb0899_ops;
        state->frontend.demodulator_priv        = state;
-       state->internal.inversion               = IQ_SWAP_AUTO;
+       state->internal.inversion               = inversion;
 
        stb0899_wakeup(&state->frontend);
        if (stb0899_get_dev_id(state) == -ENODEV) {