aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/frontends/tda1004x.c
diff options
context:
space:
mode:
authorHartmut Hackmann <hartmut.hackmann@t-online.de>2007-04-27 11:31:10 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2007-04-27 14:43:29 -0400
commit1bb0e8667fab773d6c5a3d7caf506001deaeb7f5 (patch)
treed74d1dca69859a253e9bab9bb3fda2611abcac50 /drivers/media/dvb/frontends/tda1004x.c
parent2435be11ae1afb64ac7dfb25e10b6e3037ab0522 (diff)
V4L/DVB (5311): Tda1004x driver updates
There are the following changes: - separate configuration of IF and GPIOs. - set GPIOs before firmware load. This helps to avoid I2C address collisions. - if desired invert GPIOs at sleep (automatic return to analog mode of card). - added 3 tuner configuration bytes to config stuct. - added i2c gate address to config struct. - moved _state struct declaration to header file to make it accessible on board layer. - added "conf_probed" to the state struct to allow i.e. probing for correct tuner version. - changed firmware load mechanism to always: + check if already loaded + try to boot from eeprom + try downlad from host - corrected name of tda10046 firmware image (backward compatible). Signed-off-by: Hartmut Hackmann <hartmut.hackmann@t-online.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/dvb/frontends/tda1004x.c')
-rw-r--r--drivers/media/dvb/frontends/tda1004x.c86
1 files changed, 38 insertions, 48 deletions
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c
index f4a9cf9d26d..c47501ae8b0 100644
--- a/drivers/media/dvb/frontends/tda1004x.c
+++ b/drivers/media/dvb/frontends/tda1004x.c
@@ -40,20 +40,6 @@
40#include "dvb_frontend.h" 40#include "dvb_frontend.h"
41#include "tda1004x.h" 41#include "tda1004x.h"
42 42
43enum tda1004x_demod {
44 TDA1004X_DEMOD_TDA10045,
45 TDA1004X_DEMOD_TDA10046,
46};
47
48struct tda1004x_state {
49 struct i2c_adapter* i2c;
50 const struct tda1004x_config* config;
51 struct dvb_frontend frontend;
52
53 /* private demod data */
54 enum tda1004x_demod demod_type;
55};
56
57static int debug; 43static int debug;
58#define dprintk(args...) \ 44#define dprintk(args...) \
59 do { \ 45 do { \
@@ -507,8 +493,13 @@ static int tda10046_fwupload(struct dvb_frontend* fe)
507 tda1004x_write_byteI(state, TDA1004X_CONFC4, 0x80); 493 tda1004x_write_byteI(state, TDA1004X_CONFC4, 0x80);
508 } 494 }
509 tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0); 495 tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0);
496 /* set GPIO 1 and 3 */
497 if (state->config->gpio_config != TDA10046_GPTRI) {
498 tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE2, 0x33);
499 tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0x0f, state->config->gpio_config &0x0f);
500 }
510 /* let the clocks recover from sleep */ 501 /* let the clocks recover from sleep */
511 msleep(5); 502 msleep(10);
512 503
513 /* The PLLs need to be reprogrammed after sleep */ 504 /* The PLLs need to be reprogrammed after sleep */
514 tda10046_init_plls(fe); 505 tda10046_init_plls(fe);
@@ -517,25 +508,29 @@ static int tda10046_fwupload(struct dvb_frontend* fe)
517 if (tda1004x_check_upload_ok(state) == 0) 508 if (tda1004x_check_upload_ok(state) == 0)
518 return 0; 509 return 0;
519 510
520 if (state->config->request_firmware != NULL) { 511 printk(KERN_INFO "tda1004x: trying to boot from eeprom\n");
521 /* request the firmware, this will block until someone uploads it */ 512 tda1004x_write_mask(state, TDA1004X_CONFC4, 4, 4);
522 printk(KERN_INFO "tda1004x: waiting for firmware upload...\n"); 513 msleep(300);
523 ret = state->config->request_firmware(fe, &fw, TDA10046_DEFAULT_FIRMWARE); 514 /* don't re-upload unless necessary */
515 if (tda1004x_check_upload_ok(state) == 0)
516 return 0;
517
518 /* request the firmware, this will block until someone uploads it */
519 printk(KERN_INFO "tda1004x: waiting for firmware upload...\n");
520 ret = state->config->request_firmware(fe, &fw, TDA10046_DEFAULT_FIRMWARE);
521 if (ret) {
522 /* remain compatible to old bug: try to load with tda10045 image name */
523 ret = state->config->request_firmware(fe, &fw, TDA10045_DEFAULT_FIRMWARE);
524 if (ret) { 524 if (ret) {
525 printk(KERN_ERR "tda1004x: no firmware upload (timeout or file not found?)\n"); 525 printk(KERN_ERR "tda1004x: no firmware upload (timeout or file not found?)\n");
526 return ret; 526 return ret;
527 } 527 } else
528 tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8); // going to boot from HOST 528 printk(KERN_INFO "tda1004x: please rename the firmware file to %s\n",
529 ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10046H_CODE_CPT, TDA10046H_CODE_IN); 529 TDA10046_DEFAULT_FIRMWARE);
530 release_firmware(fw);
531 if (ret)
532 return ret;
533 } else {
534 /* boot from firmware eeprom */
535 printk(KERN_INFO "tda1004x: booting from eeprom\n");
536 tda1004x_write_mask(state, TDA1004X_CONFC4, 4, 4);
537 msleep(300);
538 } 530 }
531 tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8); // going to boot from HOST
532 ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10046H_CODE_CPT, TDA10046H_CODE_IN);
533 release_firmware(fw);
539 return tda1004x_check_upload_ok(state); 534 return tda1004x_check_upload_ok(state);
540} 535}
541 536
@@ -638,37 +633,25 @@ static int tda10046_init(struct dvb_frontend* fe)
638 switch (state->config->agc_config) { 633 switch (state->config->agc_config) {
639 case TDA10046_AGC_DEFAULT: 634 case TDA10046_AGC_DEFAULT:
640 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x00); // AGC setup 635 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x00); // AGC setup
641 tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities 636 tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x60); // set AGC polarities
642 break; 637 break;
643 case TDA10046_AGC_IFO_AUTO_NEG: 638 case TDA10046_AGC_IFO_AUTO_NEG:
644 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup 639 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup
645 tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities 640 tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x60); // set AGC polarities
646 break; 641 break;
647 case TDA10046_AGC_IFO_AUTO_POS: 642 case TDA10046_AGC_IFO_AUTO_POS:
648 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup 643 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup
649 tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x00); // set AGC polarities 644 tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x00); // set AGC polarities
650 break; 645 break;
651 case TDA10046_AGC_TDA827X_GP11: 646 case TDA10046_AGC_TDA827X:
652 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup 647 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup
653 tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold 648 tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold
654 tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize 649 tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize
655 tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x6a); // set AGC polarities 650 tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x60); // set AGC polarities
656 break;
657 case TDA10046_AGC_TDA827X_GP00:
658 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup
659 tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold
660 tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize
661 tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities
662 break;
663 case TDA10046_AGC_TDA827X_GP01:
664 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup
665 tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold
666 tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize
667 tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x62); // set AGC polarities
668 break; 651 break;
669 } 652 }
670 tda1004x_write_byteI(state, TDA1004X_CONFADC2, 0x38); 653 tda1004x_write_byteI(state, TDA1004X_CONFADC2, 0x38);
671 tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0x61); // Turn both AGC outputs on 654 tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0x79); // Turn IF AGC output on
672 tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MIN, 0); // } 655 tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MIN, 0); // }
673 tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MAX, 0xff); // } AGC min/max values 656 tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MAX, 0xff); // } AGC min/max values
674 tda1004x_write_byteI(state, TDA10046H_AGC_IF_MIN, 0); // } 657 tda1004x_write_byteI(state, TDA10046H_AGC_IF_MIN, 0); // }
@@ -1165,6 +1148,7 @@ static int tda1004x_read_ber(struct dvb_frontend* fe, u32* ber)
1165static int tda1004x_sleep(struct dvb_frontend* fe) 1148static int tda1004x_sleep(struct dvb_frontend* fe)
1166{ 1149{
1167 struct tda1004x_state* state = fe->demodulator_priv; 1150 struct tda1004x_state* state = fe->demodulator_priv;
1151 int gpio_conf;
1168 1152
1169 switch (state->demod_type) { 1153 switch (state->demod_type) {
1170 case TDA1004X_DEMOD_TDA10045: 1154 case TDA1004X_DEMOD_TDA10045:
@@ -1174,6 +1158,12 @@ static int tda1004x_sleep(struct dvb_frontend* fe)
1174 case TDA1004X_DEMOD_TDA10046: 1158 case TDA1004X_DEMOD_TDA10046:
1175 /* set outputs to tristate */ 1159 /* set outputs to tristate */
1176 tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0xff); 1160 tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0xff);
1161 /* invert GPIO 1 and 3 if desired*/
1162 gpio_conf = state->config->gpio_config;
1163 if (gpio_conf >= TDA10046_GP00_I)
1164 tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0x0f,
1165 (gpio_conf & 0x0f) ^ 0x0a);
1166
1177 tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1); 1167 tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1);
1178 break; 1168 break;
1179 } 1169 }