diff options
Diffstat (limited to 'drivers/media/common/tuners/tda8290.c')
| -rw-r--r-- | drivers/media/common/tuners/tda8290.c | 130 |
1 files changed, 74 insertions, 56 deletions
diff --git a/drivers/media/common/tuners/tda8290.c b/drivers/media/common/tuners/tda8290.c index c9062ceddc71..bc6a67768af1 100644 --- a/drivers/media/common/tuners/tda8290.c +++ b/drivers/media/common/tuners/tda8290.c | |||
| @@ -95,8 +95,7 @@ static int tda8295_i2c_bridge(struct dvb_frontend *fe, int close) | |||
| 95 | msleep(20); | 95 | msleep(20); |
| 96 | } else { | 96 | } else { |
| 97 | msg = disable; | 97 | msg = disable; |
| 98 | tuner_i2c_xfer_send(&priv->i2c_props, msg, 1); | 98 | tuner_i2c_xfer_send_recv(&priv->i2c_props, msg, 1, &msg[1], 1); |
| 99 | tuner_i2c_xfer_recv(&priv->i2c_props, &msg[1], 1); | ||
| 100 | 99 | ||
| 101 | buf[2] = msg[1]; | 100 | buf[2] = msg[1]; |
| 102 | buf[2] &= ~0x04; | 101 | buf[2] &= ~0x04; |
| @@ -233,19 +232,22 @@ static void tda8290_set_params(struct dvb_frontend *fe, | |||
| 233 | tuner_i2c_xfer_send(&priv->i2c_props, pll_bw_nom, 2); | 232 | tuner_i2c_xfer_send(&priv->i2c_props, pll_bw_nom, 2); |
| 234 | } | 233 | } |
| 235 | 234 | ||
| 235 | |||
| 236 | tda8290_i2c_bridge(fe, 1); | 236 | tda8290_i2c_bridge(fe, 1); |
| 237 | 237 | ||
| 238 | if (fe->ops.tuner_ops.set_analog_params) | 238 | if (fe->ops.tuner_ops.set_analog_params) |
| 239 | fe->ops.tuner_ops.set_analog_params(fe, params); | 239 | fe->ops.tuner_ops.set_analog_params(fe, params); |
| 240 | 240 | ||
| 241 | for (i = 0; i < 3; i++) { | 241 | for (i = 0; i < 3; i++) { |
| 242 | tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1); | 242 | tuner_i2c_xfer_send_recv(&priv->i2c_props, |
| 243 | tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1); | 243 | &addr_pll_stat, 1, &pll_stat, 1); |
| 244 | if (pll_stat & 0x80) { | 244 | if (pll_stat & 0x80) { |
| 245 | tuner_i2c_xfer_send(&priv->i2c_props, &addr_adc_sat, 1); | 245 | tuner_i2c_xfer_send_recv(&priv->i2c_props, |
| 246 | tuner_i2c_xfer_recv(&priv->i2c_props, &adc_sat, 1); | 246 | &addr_adc_sat, 1, |
| 247 | tuner_i2c_xfer_send(&priv->i2c_props, &addr_agc_stat, 1); | 247 | &adc_sat, 1); |
| 248 | tuner_i2c_xfer_recv(&priv->i2c_props, &agc_stat, 1); | 248 | tuner_i2c_xfer_send_recv(&priv->i2c_props, |
| 249 | &addr_agc_stat, 1, | ||
| 250 | &agc_stat, 1); | ||
| 249 | tuner_dbg("tda8290 is locked, AGC: %d\n", agc_stat); | 251 | tuner_dbg("tda8290 is locked, AGC: %d\n", agc_stat); |
| 250 | break; | 252 | break; |
| 251 | } else { | 253 | } else { |
| @@ -259,20 +261,22 @@ static void tda8290_set_params(struct dvb_frontend *fe, | |||
| 259 | agc_stat, adc_sat, pll_stat & 0x80); | 261 | agc_stat, adc_sat, pll_stat & 0x80); |
| 260 | tuner_i2c_xfer_send(&priv->i2c_props, gainset_2, 2); | 262 | tuner_i2c_xfer_send(&priv->i2c_props, gainset_2, 2); |
| 261 | msleep(100); | 263 | msleep(100); |
| 262 | tuner_i2c_xfer_send(&priv->i2c_props, &addr_agc_stat, 1); | 264 | tuner_i2c_xfer_send_recv(&priv->i2c_props, |
| 263 | tuner_i2c_xfer_recv(&priv->i2c_props, &agc_stat, 1); | 265 | &addr_agc_stat, 1, &agc_stat, 1); |
| 264 | tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1); | 266 | tuner_i2c_xfer_send_recv(&priv->i2c_props, |
| 265 | tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1); | 267 | &addr_pll_stat, 1, &pll_stat, 1); |
| 266 | if ((agc_stat > 115) || !(pll_stat & 0x80)) { | 268 | if ((agc_stat > 115) || !(pll_stat & 0x80)) { |
| 267 | tuner_dbg("adjust gain, step 2. Agc: %d, lock: %d\n", | 269 | tuner_dbg("adjust gain, step 2. Agc: %d, lock: %d\n", |
| 268 | agc_stat, pll_stat & 0x80); | 270 | agc_stat, pll_stat & 0x80); |
| 269 | if (priv->cfg.agcf) | 271 | if (priv->cfg.agcf) |
| 270 | priv->cfg.agcf(fe); | 272 | priv->cfg.agcf(fe); |
| 271 | msleep(100); | 273 | msleep(100); |
| 272 | tuner_i2c_xfer_send(&priv->i2c_props, &addr_agc_stat, 1); | 274 | tuner_i2c_xfer_send_recv(&priv->i2c_props, |
| 273 | tuner_i2c_xfer_recv(&priv->i2c_props, &agc_stat, 1); | 275 | &addr_agc_stat, 1, |
| 274 | tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1); | 276 | &agc_stat, 1); |
| 275 | tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1); | 277 | tuner_i2c_xfer_send_recv(&priv->i2c_props, |
| 278 | &addr_pll_stat, 1, | ||
| 279 | &pll_stat, 1); | ||
| 276 | if((agc_stat > 115) || !(pll_stat & 0x80)) { | 280 | if((agc_stat > 115) || !(pll_stat & 0x80)) { |
| 277 | tuner_dbg("adjust gain, step 3. Agc: %d\n", agc_stat); | 281 | tuner_dbg("adjust gain, step 3. Agc: %d\n", agc_stat); |
| 278 | tuner_i2c_xfer_send(&priv->i2c_props, adc_head_12, 2); | 282 | tuner_i2c_xfer_send(&priv->i2c_props, adc_head_12, 2); |
| @@ -284,10 +288,12 @@ static void tda8290_set_params(struct dvb_frontend *fe, | |||
| 284 | 288 | ||
| 285 | /* l/ l' deadlock? */ | 289 | /* l/ l' deadlock? */ |
| 286 | if(priv->tda8290_easy_mode & 0x60) { | 290 | if(priv->tda8290_easy_mode & 0x60) { |
| 287 | tuner_i2c_xfer_send(&priv->i2c_props, &addr_adc_sat, 1); | 291 | tuner_i2c_xfer_send_recv(&priv->i2c_props, |
| 288 | tuner_i2c_xfer_recv(&priv->i2c_props, &adc_sat, 1); | 292 | &addr_adc_sat, 1, |
| 289 | tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1); | 293 | &adc_sat, 1); |
| 290 | tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1); | 294 | tuner_i2c_xfer_send_recv(&priv->i2c_props, |
| 295 | &addr_pll_stat, 1, | ||
| 296 | &pll_stat, 1); | ||
| 291 | if ((adc_sat > 20) || !(pll_stat & 0x80)) { | 297 | if ((adc_sat > 20) || !(pll_stat & 0x80)) { |
| 292 | tuner_dbg("trying to resolve SECAM L deadlock\n"); | 298 | tuner_dbg("trying to resolve SECAM L deadlock\n"); |
| 293 | tuner_i2c_xfer_send(&priv->i2c_props, agc_rst_on, 2); | 299 | 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) | |||
| 307 | struct tda8290_priv *priv = fe->analog_demod_priv; | 313 | struct tda8290_priv *priv = fe->analog_demod_priv; |
| 308 | unsigned char buf[] = { 0x30, 0x00 }; /* clb_stdbt */ | 314 | unsigned char buf[] = { 0x30, 0x00 }; /* clb_stdbt */ |
| 309 | 315 | ||
| 310 | tuner_i2c_xfer_send(&priv->i2c_props, &buf[0], 1); | 316 | tuner_i2c_xfer_send_recv(&priv->i2c_props, &buf[0], 1, &buf[1], 1); |
| 311 | tuner_i2c_xfer_recv(&priv->i2c_props, &buf[1], 1); | ||
| 312 | 317 | ||
| 313 | if (enable) | 318 | if (enable) |
| 314 | buf[1] = 0x01; | 319 | buf[1] = 0x01; |
| @@ -323,8 +328,7 @@ static void tda8295_set_easy_mode(struct dvb_frontend *fe, int enable) | |||
| 323 | struct tda8290_priv *priv = fe->analog_demod_priv; | 328 | struct tda8290_priv *priv = fe->analog_demod_priv; |
| 324 | unsigned char buf[] = { 0x01, 0x00 }; | 329 | unsigned char buf[] = { 0x01, 0x00 }; |
| 325 | 330 | ||
| 326 | tuner_i2c_xfer_send(&priv->i2c_props, &buf[0], 1); | 331 | tuner_i2c_xfer_send_recv(&priv->i2c_props, &buf[0], 1, &buf[1], 1); |
| 327 | tuner_i2c_xfer_recv(&priv->i2c_props, &buf[1], 1); | ||
| 328 | 332 | ||
| 329 | if (enable) | 333 | if (enable) |
| 330 | buf[1] = 0x01; /* rising edge sets regs 0x02 - 0x23 */ | 334 | buf[1] = 0x01; /* rising edge sets regs 0x02 - 0x23 */ |
| @@ -353,8 +357,7 @@ static void tda8295_agc1_out(struct dvb_frontend *fe, int enable) | |||
| 353 | struct tda8290_priv *priv = fe->analog_demod_priv; | 357 | struct tda8290_priv *priv = fe->analog_demod_priv; |
| 354 | unsigned char buf[] = { 0x02, 0x00 }; /* DIV_FUNC */ | 358 | unsigned char buf[] = { 0x02, 0x00 }; /* DIV_FUNC */ |
| 355 | 359 | ||
| 356 | tuner_i2c_xfer_send(&priv->i2c_props, &buf[0], 1); | 360 | tuner_i2c_xfer_send_recv(&priv->i2c_props, &buf[0], 1, &buf[1], 1); |
| 357 | tuner_i2c_xfer_recv(&priv->i2c_props, &buf[1], 1); | ||
| 358 | 361 | ||
| 359 | if (enable) | 362 | if (enable) |
| 360 | buf[1] &= ~0x40; | 363 | buf[1] &= ~0x40; |
| @@ -370,10 +373,10 @@ static void tda8295_agc2_out(struct dvb_frontend *fe, int enable) | |||
| 370 | unsigned char set_gpio_cf[] = { 0x44, 0x00 }; | 373 | unsigned char set_gpio_cf[] = { 0x44, 0x00 }; |
| 371 | unsigned char set_gpio_val[] = { 0x46, 0x00 }; | 374 | unsigned char set_gpio_val[] = { 0x46, 0x00 }; |
| 372 | 375 | ||
| 373 | tuner_i2c_xfer_send(&priv->i2c_props, &set_gpio_cf[0], 1); | 376 | tuner_i2c_xfer_send_recv(&priv->i2c_props, |
| 374 | tuner_i2c_xfer_recv(&priv->i2c_props, &set_gpio_cf[1], 1); | 377 | &set_gpio_cf[0], 1, &set_gpio_cf[1], 1); |
| 375 | tuner_i2c_xfer_send(&priv->i2c_props, &set_gpio_val[0], 1); | 378 | tuner_i2c_xfer_send_recv(&priv->i2c_props, |
| 376 | tuner_i2c_xfer_recv(&priv->i2c_props, &set_gpio_val[1], 1); | 379 | &set_gpio_val[0], 1, &set_gpio_val[1], 1); |
| 377 | 380 | ||
| 378 | set_gpio_cf[1] &= 0xf0; /* clear GPIO_0 bits 3-0 */ | 381 | set_gpio_cf[1] &= 0xf0; /* clear GPIO_0 bits 3-0 */ |
| 379 | 382 | ||
| @@ -392,8 +395,7 @@ static int tda8295_has_signal(struct dvb_frontend *fe) | |||
| 392 | unsigned char hvpll_stat = 0x26; | 395 | unsigned char hvpll_stat = 0x26; |
| 393 | unsigned char ret; | 396 | unsigned char ret; |
| 394 | 397 | ||
| 395 | tuner_i2c_xfer_send(&priv->i2c_props, &hvpll_stat, 1); | 398 | tuner_i2c_xfer_send_recv(&priv->i2c_props, &hvpll_stat, 1, &ret, 1); |
| 396 | tuner_i2c_xfer_recv(&priv->i2c_props, &ret, 1); | ||
| 397 | return (ret & 0x01) ? 65535 : 0; | 399 | return (ret & 0x01) ? 65535 : 0; |
| 398 | } | 400 | } |
| 399 | 401 | ||
| @@ -413,8 +415,8 @@ static void tda8295_set_params(struct dvb_frontend *fe, | |||
| 413 | tda8295_power(fe, 1); | 415 | tda8295_power(fe, 1); |
| 414 | tda8295_agc1_out(fe, 1); | 416 | tda8295_agc1_out(fe, 1); |
| 415 | 417 | ||
| 416 | tuner_i2c_xfer_send(&priv->i2c_props, &blanking_mode[0], 1); | 418 | tuner_i2c_xfer_send_recv(&priv->i2c_props, |
| 417 | tuner_i2c_xfer_recv(&priv->i2c_props, &blanking_mode[1], 1); | 419 | &blanking_mode[0], 1, &blanking_mode[1], 1); |
| 418 | 420 | ||
| 419 | tda8295_set_video_std(fe); | 421 | tda8295_set_video_std(fe); |
| 420 | 422 | ||
| @@ -447,8 +449,8 @@ static int tda8290_has_signal(struct dvb_frontend *fe) | |||
| 447 | unsigned char i2c_get_afc[1] = { 0x1B }; | 449 | unsigned char i2c_get_afc[1] = { 0x1B }; |
| 448 | unsigned char afc = 0; | 450 | unsigned char afc = 0; |
| 449 | 451 | ||
| 450 | tuner_i2c_xfer_send(&priv->i2c_props, i2c_get_afc, ARRAY_SIZE(i2c_get_afc)); | 452 | tuner_i2c_xfer_send_recv(&priv->i2c_props, |
| 451 | tuner_i2c_xfer_recv(&priv->i2c_props, &afc, 1); | 453 | i2c_get_afc, ARRAY_SIZE(i2c_get_afc), &afc, 1); |
| 452 | return (afc & 0x80)? 65535:0; | 454 | return (afc & 0x80)? 65535:0; |
| 453 | } | 455 | } |
| 454 | 456 | ||
| @@ -654,20 +656,26 @@ static int tda829x_find_tuner(struct dvb_frontend *fe) | |||
| 654 | static int tda8290_probe(struct tuner_i2c_props *i2c_props) | 656 | static int tda8290_probe(struct tuner_i2c_props *i2c_props) |
| 655 | { | 657 | { |
| 656 | #define TDA8290_ID 0x89 | 658 | #define TDA8290_ID 0x89 |
| 657 | unsigned char tda8290_id[] = { 0x1f, 0x00 }; | 659 | u8 reg = 0x1f, id; |
| 660 | struct i2c_msg msg_read[] = { | ||
| 661 | { .addr = 0x4b, .flags = 0, .len = 1, .buf = ® }, | ||
| 662 | { .addr = 0x4b, .flags = I2C_M_RD, .len = 1, .buf = &id }, | ||
| 663 | }; | ||
| 658 | 664 | ||
| 659 | /* detect tda8290 */ | 665 | /* detect tda8290 */ |
| 660 | tuner_i2c_xfer_send(i2c_props, &tda8290_id[0], 1); | 666 | if (i2c_transfer(i2c_props->adap, msg_read, 2) != 2) { |
| 661 | tuner_i2c_xfer_recv(i2c_props, &tda8290_id[1], 1); | 667 | printk(KERN_WARNING "%s: tda8290 couldn't read register 0x%02x\n", |
| 668 | __func__, reg); | ||
| 669 | return -ENODEV; | ||
| 670 | } | ||
| 662 | 671 | ||
| 663 | if (tda8290_id[1] == TDA8290_ID) { | 672 | if (id == TDA8290_ID) { |
| 664 | if (debug) | 673 | if (debug) |
| 665 | printk(KERN_DEBUG "%s: tda8290 detected @ %d-%04x\n", | 674 | printk(KERN_DEBUG "%s: tda8290 detected @ %d-%04x\n", |
| 666 | __func__, i2c_adapter_id(i2c_props->adap), | 675 | __func__, i2c_adapter_id(i2c_props->adap), |
| 667 | i2c_props->addr); | 676 | i2c_props->addr); |
| 668 | return 0; | 677 | return 0; |
| 669 | } | 678 | } |
| 670 | |||
| 671 | return -ENODEV; | 679 | return -ENODEV; |
| 672 | } | 680 | } |
| 673 | 681 | ||
| @@ -675,16 +683,23 @@ static int tda8295_probe(struct tuner_i2c_props *i2c_props) | |||
| 675 | { | 683 | { |
| 676 | #define TDA8295_ID 0x8a | 684 | #define TDA8295_ID 0x8a |
| 677 | #define TDA8295C2_ID 0x8b | 685 | #define TDA8295C2_ID 0x8b |
| 678 | unsigned char tda8295_id[] = { 0x2f, 0x00 }; | 686 | u8 reg = 0x2f, id; |
| 687 | struct i2c_msg msg_read[] = { | ||
| 688 | { .addr = 0x4b, .flags = 0, .len = 1, .buf = ® }, | ||
| 689 | { .addr = 0x4b, .flags = I2C_M_RD, .len = 1, .buf = &id }, | ||
| 690 | }; | ||
| 679 | 691 | ||
| 680 | /* detect tda8295 */ | 692 | /* detect tda8290 */ |
| 681 | tuner_i2c_xfer_send(i2c_props, &tda8295_id[0], 1); | 693 | if (i2c_transfer(i2c_props->adap, msg_read, 2) != 2) { |
| 682 | tuner_i2c_xfer_recv(i2c_props, &tda8295_id[1], 1); | 694 | printk(KERN_WARNING "%s: tda8290 couldn't read register 0x%02x\n", |
| 695 | __func__, reg); | ||
| 696 | return -ENODEV; | ||
| 697 | } | ||
| 683 | 698 | ||
| 684 | if ((tda8295_id[1] & 0xfe) == TDA8295_ID) { | 699 | if ((id & 0xfe) == TDA8295_ID) { |
| 685 | if (debug) | 700 | if (debug) |
| 686 | printk(KERN_DEBUG "%s: %s detected @ %d-%04x\n", | 701 | printk(KERN_DEBUG "%s: %s detected @ %d-%04x\n", |
| 687 | __func__, (tda8295_id[1] == TDA8295_ID) ? | 702 | __func__, (id == TDA8295_ID) ? |
| 688 | "tda8295c1" : "tda8295c2", | 703 | "tda8295c1" : "tda8295c2", |
| 689 | i2c_adapter_id(i2c_props->adap), | 704 | i2c_adapter_id(i2c_props->adap), |
| 690 | i2c_props->addr); | 705 | i2c_props->addr); |
| @@ -740,9 +755,11 @@ struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe, | |||
| 740 | sizeof(struct analog_demod_ops)); | 755 | sizeof(struct analog_demod_ops)); |
| 741 | } | 756 | } |
| 742 | 757 | ||
| 743 | if ((!(cfg) || (TDA829X_PROBE_TUNER == cfg->probe_tuner)) && | 758 | if (!(cfg) || (TDA829X_PROBE_TUNER == cfg->probe_tuner)) { |
| 744 | (tda829x_find_tuner(fe) < 0)) | 759 | tda8295_power(fe, 1); |
| 745 | goto fail; | 760 | if (tda829x_find_tuner(fe) < 0) |
| 761 | goto fail; | ||
| 762 | } | ||
| 746 | 763 | ||
| 747 | switch (priv->ver) { | 764 | switch (priv->ver) { |
| 748 | case TDA8290: | 765 | case TDA8290: |
| @@ -786,6 +803,8 @@ struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe, | |||
| 786 | return fe; | 803 | return fe; |
| 787 | 804 | ||
| 788 | fail: | 805 | fail: |
| 806 | memset(&fe->ops.analog_ops, 0, sizeof(struct analog_demod_ops)); | ||
| 807 | |||
| 789 | tda829x_release(fe); | 808 | tda829x_release(fe); |
| 790 | return NULL; | 809 | return NULL; |
| 791 | } | 810 | } |
| @@ -809,8 +828,8 @@ int tda829x_probe(struct i2c_adapter *i2c_adap, u8 i2c_addr) | |||
| 809 | int i; | 828 | int i; |
| 810 | 829 | ||
| 811 | /* rule out tda9887, which would return the same byte repeatedly */ | 830 | /* rule out tda9887, which would return the same byte repeatedly */ |
| 812 | tuner_i2c_xfer_send(&i2c_props, soft_reset, 1); | 831 | tuner_i2c_xfer_send_recv(&i2c_props, |
| 813 | tuner_i2c_xfer_recv(&i2c_props, buf, PROBE_BUFFER_SIZE); | 832 | soft_reset, 1, buf, PROBE_BUFFER_SIZE); |
| 814 | for (i = 1; i < PROBE_BUFFER_SIZE; i++) { | 833 | for (i = 1; i < PROBE_BUFFER_SIZE; i++) { |
| 815 | if (buf[i] != buf[0]) | 834 | if (buf[i] != buf[0]) |
| 816 | break; | 835 | break; |
| @@ -827,13 +846,12 @@ int tda829x_probe(struct i2c_adapter *i2c_adap, u8 i2c_addr) | |||
| 827 | /* fall back to old probing method */ | 846 | /* fall back to old probing method */ |
| 828 | tuner_i2c_xfer_send(&i2c_props, easy_mode_b, 2); | 847 | tuner_i2c_xfer_send(&i2c_props, easy_mode_b, 2); |
| 829 | tuner_i2c_xfer_send(&i2c_props, soft_reset, 2); | 848 | tuner_i2c_xfer_send(&i2c_props, soft_reset, 2); |
| 830 | tuner_i2c_xfer_send(&i2c_props, &addr_dto_lsb, 1); | 849 | tuner_i2c_xfer_send_recv(&i2c_props, &addr_dto_lsb, 1, &data, 1); |
| 831 | tuner_i2c_xfer_recv(&i2c_props, &data, 1); | ||
| 832 | if (data == 0) { | 850 | if (data == 0) { |
| 833 | tuner_i2c_xfer_send(&i2c_props, easy_mode_g, 2); | 851 | tuner_i2c_xfer_send(&i2c_props, easy_mode_g, 2); |
| 834 | tuner_i2c_xfer_send(&i2c_props, soft_reset, 2); | 852 | tuner_i2c_xfer_send(&i2c_props, soft_reset, 2); |
| 835 | tuner_i2c_xfer_send(&i2c_props, &addr_dto_lsb, 1); | 853 | tuner_i2c_xfer_send_recv(&i2c_props, |
| 836 | tuner_i2c_xfer_recv(&i2c_props, &data, 1); | 854 | &addr_dto_lsb, 1, &data, 1); |
| 837 | if (data == 0x7b) { | 855 | if (data == 0x7b) { |
| 838 | return 0; | 856 | return 0; |
| 839 | } | 857 | } |
