Merge master.kernel.org:/pub/scm/linux/kernel/git/sam/kbuild
[sfrench/cifs-2.6.git] / drivers / media / dvb / frontends / stv0299.c
index 2d62931f20b547b4588190148d879b71cda3d708..29c48665e1309eb1e95500eac5909d663b09f4b1 100644 (file)
@@ -48,6 +48,7 @@
 #include <linux/moduleparam.h>
 #include <linux/string.h>
 #include <linux/slab.h>
+#include <linux/jiffies.h>
 #include <asm/div64.h>
 
 #include "dvb_frontend.h"
@@ -63,8 +64,12 @@ struct stv0299_state {
        u32 tuner_frequency;
        u32 symbol_rate;
        fe_code_rate_t fec_inner;
+       int errmode;
 };
 
+#define STATUS_BER 0
+#define STATUS_UCBLOCKS 1
+
 static int debug;
 static int debug_legacy_dish_switch;
 #define dprintk(args...) \
@@ -382,36 +387,6 @@ static int stv0299_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltag
        };
 }
 
-static inline s32 stv0299_calc_usec_delay (struct timeval lasttime, struct timeval curtime)
-{
-       return ((curtime.tv_usec < lasttime.tv_usec) ?
-               1000000 - lasttime.tv_usec + curtime.tv_usec :
-               curtime.tv_usec - lasttime.tv_usec);
-}
-
-static void stv0299_sleep_until (struct timeval *waketime, u32 add_usec)
-{
-       struct timeval lasttime;
-       s32 delta, newdelta;
-
-       waketime->tv_usec += add_usec;
-       if (waketime->tv_usec >= 1000000) {
-               waketime->tv_usec -= 1000000;
-               waketime->tv_sec++;
-       }
-
-       do_gettimeofday (&lasttime);
-       delta = stv0299_calc_usec_delay (lasttime, *waketime);
-       if (delta > 2500) {
-               msleep ((delta - 1500) / 1000);
-               do_gettimeofday (&lasttime);
-               newdelta = stv0299_calc_usec_delay (lasttime, *waketime);
-               delta = (newdelta > delta) ? 0 : newdelta;
-       }
-       if (delta > 0)
-               udelay (delta);
-}
-
 static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, u32 cmd)
 {
        struct stv0299_state* state = fe->demodulator_priv;
@@ -439,7 +414,7 @@ static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, u32 cmd)
                memcpy (&tv[0], &nexttime, sizeof (struct timeval));
        stv0299_writeregI (state, 0x0c, reg0x0c | 0x50); /* set LNB to 18V */
 
-       stv0299_sleep_until (&nexttime, 32000);
+       dvb_frontend_sleep_until(&nexttime, 32000);
 
        for (i=0; i<9; i++) {
                if (debug_legacy_dish_switch)
@@ -453,13 +428,13 @@ static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, u32 cmd)
                cmd = cmd >> 1;
 
                if (i != 8)
-                       stv0299_sleep_until (&nexttime, 8000);
+                       dvb_frontend_sleep_until(&nexttime, 8000);
        }
        if (debug_legacy_dish_switch) {
                printk ("%s(%d): switch delay (should be 32k followed by all 8k\n",
                        __FUNCTION__, fe->dvb->num);
-               for (i=1; i < 10; i++)
-                       printk ("%d: %d\n", i, stv0299_calc_usec_delay (tv[i-1] , tv[i]));
+               for (i = 1; i < 10; i++)
+                       printk ("%d: %d\n", i, timeval_usec_diff(tv[i-1] , tv[i]));
        }
 
        return 0;
@@ -516,8 +491,7 @@ static int stv0299_read_ber(struct dvb_frontend* fe, u32* ber)
 {
         struct stv0299_state* state = fe->demodulator_priv;
 
-       stv0299_writeregI(state, 0x34, (stv0299_readreg(state, 0x34) & 0xcf) | 0x10);
-       msleep(100);
+       if (state->errmode != STATUS_BER) return 0;
        *ber = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e);
 
        return 0;
@@ -556,9 +530,8 @@ static int stv0299_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
 {
         struct stv0299_state* state = fe->demodulator_priv;
 
-       stv0299_writeregI(state, 0x34, (stv0299_readreg(state, 0x34) & 0xcf) | 0x30);
-       msleep(100);
-       *ucblocks = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e);
+       if (state->errmode != STATUS_UCBLOCKS) *ucblocks = 0;
+       else *ucblocks = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e);
 
        return 0;
 }
@@ -580,49 +553,14 @@ static int stv0299_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
        if (state->config->invert) invval = (~invval) & 1;
        stv0299_writeregI(state, 0x0c, (stv0299_readreg(state, 0x0c) & 0xfe) | invval);
 
-       if (state->config->enhanced_tuning) {
-               /* check if we should do a finetune */
-               int frequency_delta = p->frequency - state->tuner_frequency;
-               int minmax = p->u.qpsk.symbol_rate / 2000;
-               if (minmax < 5000) minmax = 5000;
-
-               if ((frequency_delta > -minmax) && (frequency_delta < minmax) && (frequency_delta != 0) &&
-                   (state->fec_inner == p->u.qpsk.fec_inner) &&
-                   (state->symbol_rate == p->u.qpsk.symbol_rate)) {
-                       int Drot_freq = (frequency_delta << 16) / (state->config->mclk / 1000);
-
-                       // zap the derotator registers first
-                       stv0299_writeregI(state, 0x22, 0x00);
-                       stv0299_writeregI(state, 0x23, 0x00);
-
-                       // now set them as we want
-                       stv0299_writeregI(state, 0x22, Drot_freq >> 8);
-                       stv0299_writeregI(state, 0x23, Drot_freq);
-               } else {
-                       /* A "normal" tune is requested */
-                       stv0299_writeregI(state, 0x05, 0xb5);   /*  enable i2c repeater on stv0299  */
-                       state->config->pll_set(fe, state->i2c, p);
-                       stv0299_writeregI(state, 0x05, 0x35);   /*  disable i2c repeater on stv0299  */
-
-                       stv0299_writeregI(state, 0x32, 0x80);
-                       stv0299_writeregI(state, 0x22, 0x00);
-                       stv0299_writeregI(state, 0x23, 0x00);
-                       stv0299_writeregI(state, 0x32, 0x19);
-                       stv0299_set_symbolrate (fe, p->u.qpsk.symbol_rate);
-                       stv0299_set_FEC (state, p->u.qpsk.fec_inner);
-               }
-       } else {
-               stv0299_writeregI(state, 0x05, 0xb5);   /*  enable i2c repeater on stv0299  */
-               state->config->pll_set(fe, state->i2c, p);
-               stv0299_writeregI(state, 0x05, 0x35);   /*  disable i2c repeater on stv0299  */
+       stv0299_writeregI(state, 0x05, 0xb5);   /*  enable i2c repeater on stv0299  */
+       state->config->pll_set(fe, state->i2c, p);
+       stv0299_writeregI(state, 0x05, 0x35);   /*  disable i2c repeater on stv0299  */
 
-               stv0299_set_FEC (state, p->u.qpsk.fec_inner);
-               stv0299_set_symbolrate (fe, p->u.qpsk.symbol_rate);
-               stv0299_writeregI(state, 0x22, 0x00);
-               stv0299_writeregI(state, 0x23, 0x00);
-               stv0299_readreg (state, 0x23);
-               stv0299_writeregI(state, 0x12, 0xb9);
-       }
+       stv0299_set_FEC (state, p->u.qpsk.fec_inner);
+       stv0299_set_symbolrate (fe, p->u.qpsk.symbol_rate);
+       stv0299_writeregI(state, 0x22, 0x00);
+       stv0299_writeregI(state, 0x23, 0x00);
 
        state->tuner_frequency = p->frequency;
        state->fec_inner = p->u.qpsk.fec_inner;
@@ -707,6 +645,7 @@ struct dvb_frontend* stv0299_attach(const struct stv0299_config* config,
        state->tuner_frequency = 0;
        state->symbol_rate = 0;
        state->fec_inner = 0;
+       state->errmode = STATUS_BER;
 
        /* check if the demod is there */
        stv0299_writeregI(state, 0x02, 0x34); /* standby off */