]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/media/common/tuners/tda8290.c
Merge tag 'v2.6.38' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[mv-sheeva.git] / drivers / media / common / tuners / tda8290.c
index c9062ceddc719d25cb05fbe253c1f8d3dc46b8ae..8c4852114eeb41a06f6ff8406991957c6c01274a 100644 (file)
@@ -95,8 +95,7 @@ static int tda8295_i2c_bridge(struct dvb_frontend *fe, int close)
                msleep(20);
        } else {
                msg = disable;
-               tuner_i2c_xfer_send(&priv->i2c_props, msg, 1);
-               tuner_i2c_xfer_recv(&priv->i2c_props, &msg[1], 1);
+               tuner_i2c_xfer_send_recv(&priv->i2c_props, msg, 1, &msg[1], 1);
 
                buf[2] = msg[1];
                buf[2] &= ~0x04;
@@ -233,19 +232,22 @@ static void tda8290_set_params(struct dvb_frontend *fe,
                tuner_i2c_xfer_send(&priv->i2c_props, pll_bw_nom, 2);
        }
 
+
        tda8290_i2c_bridge(fe, 1);
 
        if (fe->ops.tuner_ops.set_analog_params)
                fe->ops.tuner_ops.set_analog_params(fe, params);
 
        for (i = 0; i < 3; i++) {
-               tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1);
-               tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1);
+               tuner_i2c_xfer_send_recv(&priv->i2c_props,
+                                        &addr_pll_stat, 1, &pll_stat, 1);
                if (pll_stat & 0x80) {
-                       tuner_i2c_xfer_send(&priv->i2c_props, &addr_adc_sat, 1);
-                       tuner_i2c_xfer_recv(&priv->i2c_props, &adc_sat, 1);
-                       tuner_i2c_xfer_send(&priv->i2c_props, &addr_agc_stat, 1);
-                       tuner_i2c_xfer_recv(&priv->i2c_props, &agc_stat, 1);
+                       tuner_i2c_xfer_send_recv(&priv->i2c_props,
+                                                &addr_adc_sat, 1,
+                                                &adc_sat, 1);
+                       tuner_i2c_xfer_send_recv(&priv->i2c_props,
+                                                &addr_agc_stat, 1,
+                                                &agc_stat, 1);
                        tuner_dbg("tda8290 is locked, AGC: %d\n", agc_stat);
                        break;
                } else {
@@ -259,20 +261,22 @@ static void tda8290_set_params(struct dvb_frontend *fe,
                           agc_stat, adc_sat, pll_stat & 0x80);
                tuner_i2c_xfer_send(&priv->i2c_props, gainset_2, 2);
                msleep(100);
-               tuner_i2c_xfer_send(&priv->i2c_props, &addr_agc_stat, 1);
-               tuner_i2c_xfer_recv(&priv->i2c_props, &agc_stat, 1);
-               tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1);
-               tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1);
+               tuner_i2c_xfer_send_recv(&priv->i2c_props,
+                                        &addr_agc_stat, 1, &agc_stat, 1);
+               tuner_i2c_xfer_send_recv(&priv->i2c_props,
+                                        &addr_pll_stat, 1, &pll_stat, 1);
                if ((agc_stat > 115) || !(pll_stat & 0x80)) {
                        tuner_dbg("adjust gain, step 2. Agc: %d, lock: %d\n",
                                   agc_stat, pll_stat & 0x80);
                        if (priv->cfg.agcf)
                                priv->cfg.agcf(fe);
                        msleep(100);
-                       tuner_i2c_xfer_send(&priv->i2c_props, &addr_agc_stat, 1);
-                       tuner_i2c_xfer_recv(&priv->i2c_props, &agc_stat, 1);
-                       tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1);
-                       tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1);
+                       tuner_i2c_xfer_send_recv(&priv->i2c_props,
+                                                &addr_agc_stat, 1,
+                                                &agc_stat, 1);
+                       tuner_i2c_xfer_send_recv(&priv->i2c_props,
+                                                &addr_pll_stat, 1,
+                                                &pll_stat, 1);
                        if((agc_stat > 115) || !(pll_stat & 0x80)) {
                                tuner_dbg("adjust gain, step 3. Agc: %d\n", agc_stat);
                                tuner_i2c_xfer_send(&priv->i2c_props, adc_head_12, 2);
@@ -284,10 +288,12 @@ static void tda8290_set_params(struct dvb_frontend *fe,
 
        /* l/ l' deadlock? */
        if(priv->tda8290_easy_mode & 0x60) {
-               tuner_i2c_xfer_send(&priv->i2c_props, &addr_adc_sat, 1);
-               tuner_i2c_xfer_recv(&priv->i2c_props, &adc_sat, 1);
-               tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1);
-               tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1);
+               tuner_i2c_xfer_send_recv(&priv->i2c_props,
+                                        &addr_adc_sat, 1,
+                                        &adc_sat, 1);
+               tuner_i2c_xfer_send_recv(&priv->i2c_props,
+                                        &addr_pll_stat, 1,
+                                        &pll_stat, 1);
                if ((adc_sat > 20) || !(pll_stat & 0x80)) {
                        tuner_dbg("trying to resolve SECAM L deadlock\n");
                        tuner_i2c_xfer_send(&priv->i2c_props, agc_rst_on, 2);
@@ -307,8 +313,7 @@ static void tda8295_power(struct dvb_frontend *fe, int enable)
        struct tda8290_priv *priv = fe->analog_demod_priv;
        unsigned char buf[] = { 0x30, 0x00 }; /* clb_stdbt */
 
-       tuner_i2c_xfer_send(&priv->i2c_props, &buf[0], 1);
-       tuner_i2c_xfer_recv(&priv->i2c_props, &buf[1], 1);
+       tuner_i2c_xfer_send_recv(&priv->i2c_props, &buf[0], 1, &buf[1], 1);
 
        if (enable)
                buf[1] = 0x01;
@@ -323,8 +328,7 @@ static void tda8295_set_easy_mode(struct dvb_frontend *fe, int enable)
        struct tda8290_priv *priv = fe->analog_demod_priv;
        unsigned char buf[] = { 0x01, 0x00 };
 
-       tuner_i2c_xfer_send(&priv->i2c_props, &buf[0], 1);
-       tuner_i2c_xfer_recv(&priv->i2c_props, &buf[1], 1);
+       tuner_i2c_xfer_send_recv(&priv->i2c_props, &buf[0], 1, &buf[1], 1);
 
        if (enable)
                buf[1] = 0x01; /* rising edge sets regs 0x02 - 0x23 */
@@ -353,8 +357,7 @@ static void tda8295_agc1_out(struct dvb_frontend *fe, int enable)
        struct tda8290_priv *priv = fe->analog_demod_priv;
        unsigned char buf[] = { 0x02, 0x00 }; /* DIV_FUNC */
 
-       tuner_i2c_xfer_send(&priv->i2c_props, &buf[0], 1);
-       tuner_i2c_xfer_recv(&priv->i2c_props, &buf[1], 1);
+       tuner_i2c_xfer_send_recv(&priv->i2c_props, &buf[0], 1, &buf[1], 1);
 
        if (enable)
                buf[1] &= ~0x40;
@@ -370,10 +373,10 @@ static void tda8295_agc2_out(struct dvb_frontend *fe, int enable)
        unsigned char set_gpio_cf[]    = { 0x44, 0x00 };
        unsigned char set_gpio_val[]   = { 0x46, 0x00 };
 
-       tuner_i2c_xfer_send(&priv->i2c_props, &set_gpio_cf[0], 1);
-       tuner_i2c_xfer_recv(&priv->i2c_props, &set_gpio_cf[1], 1);
-       tuner_i2c_xfer_send(&priv->i2c_props, &set_gpio_val[0], 1);
-       tuner_i2c_xfer_recv(&priv->i2c_props, &set_gpio_val[1], 1);
+       tuner_i2c_xfer_send_recv(&priv->i2c_props,
+                                &set_gpio_cf[0], 1, &set_gpio_cf[1], 1);
+       tuner_i2c_xfer_send_recv(&priv->i2c_props,
+                                &set_gpio_val[0], 1, &set_gpio_val[1], 1);
 
        set_gpio_cf[1] &= 0xf0; /* clear GPIO_0 bits 3-0 */
 
@@ -392,8 +395,7 @@ static int tda8295_has_signal(struct dvb_frontend *fe)
        unsigned char hvpll_stat = 0x26;
        unsigned char ret;
 
-       tuner_i2c_xfer_send(&priv->i2c_props, &hvpll_stat, 1);
-       tuner_i2c_xfer_recv(&priv->i2c_props, &ret, 1);
+       tuner_i2c_xfer_send_recv(&priv->i2c_props, &hvpll_stat, 1, &ret, 1);
        return (ret & 0x01) ? 65535 : 0;
 }
 
@@ -413,8 +415,8 @@ static void tda8295_set_params(struct dvb_frontend *fe,
        tda8295_power(fe, 1);
        tda8295_agc1_out(fe, 1);
 
-       tuner_i2c_xfer_send(&priv->i2c_props, &blanking_mode[0], 1);
-       tuner_i2c_xfer_recv(&priv->i2c_props, &blanking_mode[1], 1);
+       tuner_i2c_xfer_send_recv(&priv->i2c_props,
+                                &blanking_mode[0], 1, &blanking_mode[1], 1);
 
        tda8295_set_video_std(fe);
 
@@ -447,8 +449,8 @@ static int tda8290_has_signal(struct dvb_frontend *fe)
        unsigned char i2c_get_afc[1] = { 0x1B };
        unsigned char afc = 0;
 
-       tuner_i2c_xfer_send(&priv->i2c_props, i2c_get_afc, ARRAY_SIZE(i2c_get_afc));
-       tuner_i2c_xfer_recv(&priv->i2c_props, &afc, 1);
+       tuner_i2c_xfer_send_recv(&priv->i2c_props,
+                                i2c_get_afc, ARRAY_SIZE(i2c_get_afc), &afc, 1);
        return (afc & 0x80)? 65535:0;
 }
 
@@ -654,20 +656,26 @@ static int tda829x_find_tuner(struct dvb_frontend *fe)
 static int tda8290_probe(struct tuner_i2c_props *i2c_props)
 {
 #define TDA8290_ID 0x89
-       unsigned char tda8290_id[] = { 0x1f, 0x00 };
+       u8 reg = 0x1f, id;
+       struct i2c_msg msg_read[] = {
+               { .addr = i2c_props->addr, .flags = 0, .len = 1, .buf = &reg },
+               { .addr = i2c_props->addr, .flags = I2C_M_RD, .len = 1, .buf = &id },
+       };
 
        /* detect tda8290 */
-       tuner_i2c_xfer_send(i2c_props, &tda8290_id[0], 1);
-       tuner_i2c_xfer_recv(i2c_props, &tda8290_id[1], 1);
+       if (i2c_transfer(i2c_props->adap, msg_read, 2) != 2) {
+               printk(KERN_WARNING "%s: couldn't read register 0x%02x\n",
+                              __func__, reg);
+               return -ENODEV;
+       }
 
-       if (tda8290_id[1] == TDA8290_ID) {
+       if (id == TDA8290_ID) {
                if (debug)
                        printk(KERN_DEBUG "%s: tda8290 detected @ %d-%04x\n",
                               __func__, i2c_adapter_id(i2c_props->adap),
                               i2c_props->addr);
                return 0;
        }
-
        return -ENODEV;
 }
 
@@ -675,16 +683,23 @@ static int tda8295_probe(struct tuner_i2c_props *i2c_props)
 {
 #define TDA8295_ID 0x8a
 #define TDA8295C2_ID 0x8b
-       unsigned char tda8295_id[] = { 0x2f, 0x00 };
+       u8 reg = 0x2f, id;
+       struct i2c_msg msg_read[] = {
+               { .addr = i2c_props->addr, .flags = 0, .len = 1, .buf = &reg },
+               { .addr = i2c_props->addr, .flags = I2C_M_RD, .len = 1, .buf = &id },
+       };
 
        /* detect tda8295 */
-       tuner_i2c_xfer_send(i2c_props, &tda8295_id[0], 1);
-       tuner_i2c_xfer_recv(i2c_props, &tda8295_id[1], 1);
+       if (i2c_transfer(i2c_props->adap, msg_read, 2) != 2) {
+               printk(KERN_WARNING "%s: couldn't read register 0x%02x\n",
+                              __func__, reg);
+               return -ENODEV;
+       }
 
-       if ((tda8295_id[1] & 0xfe) == TDA8295_ID) {
+       if ((id & 0xfe) == TDA8295_ID) {
                if (debug)
                        printk(KERN_DEBUG "%s: %s detected @ %d-%04x\n",
-                              __func__, (tda8295_id[1] == TDA8295_ID) ?
+                              __func__, (id == TDA8295_ID) ?
                               "tda8295c1" : "tda8295c2",
                               i2c_adapter_id(i2c_props->adap),
                               i2c_props->addr);
@@ -740,9 +755,11 @@ struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe,
                       sizeof(struct analog_demod_ops));
        }
 
-       if ((!(cfg) || (TDA829X_PROBE_TUNER == cfg->probe_tuner)) &&
-           (tda829x_find_tuner(fe) < 0))
-               goto fail;
+       if (!(cfg) || (TDA829X_PROBE_TUNER == cfg->probe_tuner)) {
+               tda8295_power(fe, 1);
+               if (tda829x_find_tuner(fe) < 0)
+                       goto fail;
+       }
 
        switch (priv->ver) {
        case TDA8290:
@@ -786,6 +803,8 @@ struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe,
        return fe;
 
 fail:
+       memset(&fe->ops.analog_ops, 0, sizeof(struct analog_demod_ops));
+
        tda829x_release(fe);
        return NULL;
 }
@@ -809,8 +828,8 @@ int tda829x_probe(struct i2c_adapter *i2c_adap, u8 i2c_addr)
        int i;
 
        /* rule out tda9887, which would return the same byte repeatedly */
-       tuner_i2c_xfer_send(&i2c_props, soft_reset, 1);
-       tuner_i2c_xfer_recv(&i2c_props, buf, PROBE_BUFFER_SIZE);
+       tuner_i2c_xfer_send_recv(&i2c_props,
+                                soft_reset, 1, buf, PROBE_BUFFER_SIZE);
        for (i = 1; i < PROBE_BUFFER_SIZE; i++) {
                if (buf[i] != buf[0])
                        break;
@@ -827,13 +846,12 @@ int tda829x_probe(struct i2c_adapter *i2c_adap, u8 i2c_addr)
        /* fall back to old probing method */
        tuner_i2c_xfer_send(&i2c_props, easy_mode_b, 2);
        tuner_i2c_xfer_send(&i2c_props, soft_reset, 2);
-       tuner_i2c_xfer_send(&i2c_props, &addr_dto_lsb, 1);
-       tuner_i2c_xfer_recv(&i2c_props, &data, 1);
+       tuner_i2c_xfer_send_recv(&i2c_props, &addr_dto_lsb, 1, &data, 1);
        if (data == 0) {
                tuner_i2c_xfer_send(&i2c_props, easy_mode_g, 2);
                tuner_i2c_xfer_send(&i2c_props, soft_reset, 2);
-               tuner_i2c_xfer_send(&i2c_props, &addr_dto_lsb, 1);
-               tuner_i2c_xfer_recv(&i2c_props, &data, 1);
+               tuner_i2c_xfer_send_recv(&i2c_props,
+                                        &addr_dto_lsb, 1, &data, 1);
                if (data == 0x7b) {
                        return 0;
                }