Merge ../torvalds-2.6/
[sfrench/cifs-2.6.git] / drivers / media / dvb / dvb-usb / dtt200u-fe.c
index d17d768038c62a60c8c639efb6e47e7e0a563df0..0a94ec22aeb863bc7423d8fc55882ff3daae640f 100644 (file)
@@ -1,5 +1,5 @@
-/* Frontend part of the Linux driver for the Yakumo/Hama/Typhoon DVB-T
- * USB2.0 receiver.
+/* Frontend part of the Linux driver for the WideView/ Yakumo/ Hama/
+ * Typhoon/ Yuan DVB-T USB2.0 receiver.
  *
  * Copyright (C) 2005 Patrick Boettcher <patrick.boettcher@desy.de>
  *
 struct dtt200u_fe_state {
        struct dvb_usb_device *d;
 
+       fe_status_t stat;
+
        struct dvb_frontend_parameters fep;
        struct dvb_frontend frontend;
+       struct dvb_frontend_ops ops;
 };
 
-#define moan(which,what) info("unexpected value in '%s' for cmd '%02x' - please report to linux-dvb@linuxtv.org",which,what)
-
 static int dtt200u_fe_read_status(struct dvb_frontend* fe, fe_status_t *stat)
 {
        struct dtt200u_fe_state *state = fe->demodulator_priv;
-       u8 bw = GET_TUNE_STAT;
-       u8 br[3] = { 0 };
-//     u8 bdeb[5] = { 0 };
+       u8 st = GET_TUNE_STATUS, b[3];
+
+       dvb_usb_generic_rw(state->d,&st,1,b,3,0);
 
-       dvb_usb_generic_rw(state->d,&bw,1,br,3,0);
-       switch (br[0]) {
+       switch (b[0]) {
                case 0x01:
-                       *stat = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
+                       *stat = FE_HAS_SIGNAL | FE_HAS_CARRIER |
+                               FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
                        break;
-               case 0x00:
-                       *stat = 0;
+               case 0x00: /* pending */
+                       *stat = FE_TIMEDOUT; /* during set_frontend */
                        break;
                default:
-                       moan("br[0]",GET_TUNE_STAT);
+               case 0x02: /* failed */
+                       *stat = 0;
                        break;
        }
-
-//     bw[0] = 0x88;
-//     dvb_usb_generic_rw(state->d,bw,1,bdeb,5,0);
-
-//     deb_info("%02x: %02x %02x %02x %02x %02x\n",bw[0],bdeb[0],bdeb[1],bdeb[2],bdeb[3],bdeb[4]);
-
        return 0;
 }
+
 static int dtt200u_fe_read_ber(struct dvb_frontend* fe, u32 *ber)
 {
        struct dtt200u_fe_state *state = fe->demodulator_priv;
-       u8 bw = GET_BER;
-       *ber = 0;
-       dvb_usb_generic_rw(state->d,&bw,1,(u8*) ber,3,0);
+       u8 bw = GET_VIT_ERR_CNT,b[3];
+       dvb_usb_generic_rw(state->d,&bw,1,b,3,0);
+       *ber = (b[0] << 16) | (b[1] << 8) | b[2];
        return 0;
 }
 
 static int dtt200u_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
 {
        struct dtt200u_fe_state *state = fe->demodulator_priv;
-       u8 bw = GET_UNK;
-       *unc = 0;
-       dvb_usb_generic_rw(state->d,&bw,1,(u8*) unc,3,0);
+       u8 bw = GET_RS_UNCOR_BLK_CNT,b[2];
+
+       dvb_usb_generic_rw(state->d,&bw,1,b,2,0);
+       *unc = (b[0] << 8) | b[1];
        return 0;
 }
 
 static int dtt200u_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
 {
        struct dtt200u_fe_state *state = fe->demodulator_priv;
-       u8 bw = GET_SIG_STRENGTH, b;
+       u8 bw = GET_AGC, b;
        dvb_usb_generic_rw(state->d,&bw,1,&b,1,0);
        *strength = (b << 8) | b;
        return 0;
@@ -86,7 +84,7 @@ static int dtt200u_fe_read_snr(struct dvb_frontend* fe, u16 *snr)
 static int dtt200u_fe_init(struct dvb_frontend* fe)
 {
        struct dtt200u_fe_state *state = fe->demodulator_priv;
-       u8 b = RESET_DEMOD;
+       u8 b = SET_INIT;
        return dvb_usb_generic_write(state->d,&b,1);
 }
 
@@ -98,8 +96,8 @@ static int dtt200u_fe_sleep(struct dvb_frontend* fe)
 static int dtt200u_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
 {
        tune->min_delay_ms = 1500;
-       tune->step_size = 166667;
-       tune->max_drift = 166667 * 2;
+       tune->step_size = 0;
+       tune->max_drift = 0;
        return 0;
 }
 
@@ -107,27 +105,32 @@ static int dtt200u_fe_set_frontend(struct dvb_frontend* fe,
                                  struct dvb_frontend_parameters *fep)
 {
        struct dtt200u_fe_state *state = fe->demodulator_priv;
+       int i;
+       fe_status_t st;
        u16 freq = fep->frequency / 250000;
-       u8 bw,bwbuf[2] = { SET_BANDWIDTH, 0 }, freqbuf[3] = { SET_FREQUENCY, 0, 0 };
+       u8 bwbuf[2] = { SET_BANDWIDTH, 0 },freqbuf[3] = { SET_RF_FREQ, 0, 0 };
 
        switch (fep->u.ofdm.bandwidth) {
-               case BANDWIDTH_8_MHZ: bw = 8; break;
-               case BANDWIDTH_7_MHZ: bw = 7; break;
-               case BANDWIDTH_6_MHZ: bw = 6; break;
+               case BANDWIDTH_8_MHZ: bwbuf[1] = 8; break;
+               case BANDWIDTH_7_MHZ: bwbuf[1] = 7; break;
+               case BANDWIDTH_6_MHZ: bwbuf[1] = 6; break;
                case BANDWIDTH_AUTO: return -EOPNOTSUPP;
                default:
                        return -EINVAL;
        }
-       deb_info("set_frontend\n");
 
-       bwbuf[1] = bw;
        dvb_usb_generic_write(state->d,bwbuf,2);
 
        freqbuf[1] = freq & 0xff;
        freqbuf[2] = (freq >> 8) & 0xff;
        dvb_usb_generic_write(state->d,freqbuf,3);
 
-       memcpy(&state->fep,fep,sizeof(struct dvb_frontend_parameters));
+       for (i = 0; i < 30; i++) {
+               msleep(20);
+               dtt200u_fe_read_status(fe, &st);
+               if (st & FE_TIMEDOUT)
+                       continue;
+       }
 
        return 0;
 }
@@ -161,8 +164,9 @@ struct dvb_frontend* dtt200u_fe_attach(struct dvb_usb_device *d)
        deb_info("attaching frontend dtt200u\n");
 
        state->d = d;
+       memcpy(&state->ops,&dtt200u_fe_ops,sizeof(struct dvb_frontend_ops));
 
-       state->frontend.ops = &dtt200u_fe_ops;
+       state->frontend.ops = &state->ops;
        state->frontend.demodulator_priv = state;
 
        goto success;
@@ -174,7 +178,7 @@ success:
 
 static struct dvb_frontend_ops dtt200u_fe_ops = {
        .info = {
-               .name                   = "DTT200U (Yakumo/Typhoon/Hama) DVB-T",
+               .name                   = "WideView USB DVB-T",
                .type                   = FE_OFDM,
                .frequency_min          = 44250000,
                .frequency_max          = 867250000,