V4L/DVB (5311): Tda1004x driver updates
[pandora-kernel.git] / drivers / media / dvb / frontends / tda1004x.c
index f4a9cf9..c47501a 100644 (file)
 #include "dvb_frontend.h"
 #include "tda1004x.h"
 
-enum tda1004x_demod {
-       TDA1004X_DEMOD_TDA10045,
-       TDA1004X_DEMOD_TDA10046,
-};
-
-struct tda1004x_state {
-       struct i2c_adapter* i2c;
-       const struct tda1004x_config* config;
-       struct dvb_frontend frontend;
-
-       /* private demod data */
-       enum tda1004x_demod demod_type;
-};
-
 static int debug;
 #define dprintk(args...) \
        do { \
@@ -507,8 +493,13 @@ static int tda10046_fwupload(struct dvb_frontend* fe)
                tda1004x_write_byteI(state, TDA1004X_CONFC4, 0x80);
        }
        tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0);
+       /* set GPIO 1 and 3 */
+       if (state->config->gpio_config != TDA10046_GPTRI) {
+               tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE2, 0x33);
+               tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0x0f, state->config->gpio_config &0x0f);
+       }
        /* let the clocks recover from sleep */
-       msleep(5);
+       msleep(10);
 
        /* The PLLs need to be reprogrammed after sleep */
        tda10046_init_plls(fe);
@@ -517,25 +508,29 @@ static int tda10046_fwupload(struct dvb_frontend* fe)
        if (tda1004x_check_upload_ok(state) == 0)
                return 0;
 
-       if (state->config->request_firmware != NULL) {
-               /* request the firmware, this will block until someone uploads it */
-               printk(KERN_INFO "tda1004x: waiting for firmware upload...\n");
-               ret = state->config->request_firmware(fe, &fw, TDA10046_DEFAULT_FIRMWARE);
+       printk(KERN_INFO "tda1004x: trying to boot from eeprom\n");
+       tda1004x_write_mask(state, TDA1004X_CONFC4, 4, 4);
+       msleep(300);
+       /* don't re-upload unless necessary */
+       if (tda1004x_check_upload_ok(state) == 0)
+               return 0;
+
+       /* request the firmware, this will block until someone uploads it */
+       printk(KERN_INFO "tda1004x: waiting for firmware upload...\n");
+       ret = state->config->request_firmware(fe, &fw, TDA10046_DEFAULT_FIRMWARE);
+       if (ret) {
+               /* remain compatible to old bug: try to load with tda10045 image name */
+               ret = state->config->request_firmware(fe, &fw, TDA10045_DEFAULT_FIRMWARE);
                if (ret) {
                        printk(KERN_ERR "tda1004x: no firmware upload (timeout or file not found?)\n");
                        return ret;
-               }
-               tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8); // going to boot from HOST
-               ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10046H_CODE_CPT, TDA10046H_CODE_IN);
-               release_firmware(fw);
-               if (ret)
-                       return ret;
-       } else {
-               /* boot from firmware eeprom */
-               printk(KERN_INFO "tda1004x: booting from eeprom\n");
-               tda1004x_write_mask(state, TDA1004X_CONFC4, 4, 4);
-               msleep(300);
+               } else
+                       printk(KERN_INFO "tda1004x: please rename the firmware file to %s\n",
+                                         TDA10046_DEFAULT_FIRMWARE);
        }
+       tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8); // going to boot from HOST
+       ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10046H_CODE_CPT, TDA10046H_CODE_IN);
+       release_firmware(fw);
        return tda1004x_check_upload_ok(state);
 }
 
@@ -638,37 +633,25 @@ static int tda10046_init(struct dvb_frontend* fe)
        switch (state->config->agc_config) {
        case TDA10046_AGC_DEFAULT:
                tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x00); // AGC setup
-               tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities
+               tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x60);  // set AGC polarities
                break;
        case TDA10046_AGC_IFO_AUTO_NEG:
                tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup
-               tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities
+               tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x60);  // set AGC polarities
                break;
        case TDA10046_AGC_IFO_AUTO_POS:
                tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup
-               tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x00); // set AGC polarities
+               tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x00);  // set AGC polarities
                break;
-       case TDA10046_AGC_TDA827X_GP11:
+       case TDA10046_AGC_TDA827X:
                tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02);   // AGC setup
                tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70);    // AGC Threshold
                tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize
-               tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x6a); // set AGC polarities
-               break;
-       case TDA10046_AGC_TDA827X_GP00:
-               tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02);   // AGC setup
-               tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70);    // AGC Threshold
-               tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize
-               tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities
-               break;
-       case TDA10046_AGC_TDA827X_GP01:
-               tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02);   // AGC setup
-               tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70);    // AGC Threshold
-               tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize
-               tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x62); // set AGC polarities
+               tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x60);  // set AGC polarities
                break;
        }
        tda1004x_write_byteI(state, TDA1004X_CONFADC2, 0x38);
-       tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0x61); // Turn both AGC outputs on
+       tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0x79); // Turn IF AGC output on
        tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MIN, 0);    // }
        tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MAX, 0xff); // } AGC min/max values
        tda1004x_write_byteI(state, TDA10046H_AGC_IF_MIN, 0);     // }
@@ -1165,6 +1148,7 @@ static int tda1004x_read_ber(struct dvb_frontend* fe, u32* ber)
 static int tda1004x_sleep(struct dvb_frontend* fe)
 {
        struct tda1004x_state* state = fe->demodulator_priv;
+       int gpio_conf;
 
        switch (state->demod_type) {
        case TDA1004X_DEMOD_TDA10045:
@@ -1174,6 +1158,12 @@ static int tda1004x_sleep(struct dvb_frontend* fe)
        case TDA1004X_DEMOD_TDA10046:
                /* set outputs to tristate */
                tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0xff);
+               /* invert GPIO 1 and 3 if desired*/
+               gpio_conf = state->config->gpio_config;
+               if (gpio_conf >= TDA10046_GP00_I)
+                       tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0x0f,
+                                                       (gpio_conf & 0x0f) ^ 0x0a);
+
                tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1);
                break;
        }