aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/frontends/tda1004x.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-04-27 17:18:45 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-04-27 17:18:45 -0400
commitaa5bc2b58e3344da57f26b62e99e13e91c9e0a94 (patch)
treec6e9ea1b3ee8af88b3a050b3fba160ea2f77e404 /drivers/media/dvb/frontends/tda1004x.c
parentd868772fff6c4b881d66af8640251714e1aefa98 (diff)
parentd455cf5d0db9e3eb1b204cd4a61d8c5ccfe4305f (diff)
Merge branch 'master' of ssh://master.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb
* 'master' of ssh://master.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb: (184 commits) V4L/DVB (5563): Radio-maestro.c Replace radio_ioctl to use video_ioctl2 V4L/DVB (5562): Radio-gemtek-pci.c Replace gemtek_pci_ioctl to use video_ioctl2 V4L/DVB (5560): Ivtv: fix incorrect bitwise-and for command flags. V4L/DVB (5558): Opera: use 7-bit i2c addresses V4L/DVB (5557): Cafe_ccic: check return value of pci_enable_device V4L/DVB (5556): Radio-gemtek.c Replace gemtek_ioctl to use video_ioctl2 V4L/DVB (5555): Radio-aimslab.c Replace rt_ioctl to use video_ioctl2 V4L/DVB (5554): Fix: vidioc_g_parm were not zeroing the memory V4L/DVB (5553): Replace typhoon_do_ioctl to use video_ioctl2 V4L/DVB (5552): Plan-b: Switch to refcounting PCI API V4L/DVB (5551): Plan-b: header change V4L/DVB (5550): Radio-sf16fmi.c Replace fmi_do_ioctl to use video_ioctl2 V4L/DVB (5549): Radio-sf16fmr2.c Replace fmr2_do_ioctl to use video_ioctl2 V4L/DVB (5548): Fix v4l2 buffer to the length V4L/DVB (5547): Add ENUM_FRAMESIZES and ENUM_FRAMEINTERVALS ioctls V4L/DVB (5546): Radio-terratec.c Replace tt_do_ioctl to use video_ioctl2 V4L/DVB (5545): Saa7146: Release capture buffers on device close V4L/DVB (5544): Budget-av: Make inversion setting configurable, add KNC ONE V1.0 card V4L/DVB (5543): Tda10023: Add support for frontend TDA10023 V4L/DVB (5542): Budget-av: Remove polarity switching of the clock for DVB-C ...
Diffstat (limited to 'drivers/media/dvb/frontends/tda1004x.c')
-rw-r--r--drivers/media/dvb/frontends/tda1004x.c98
1 files changed, 52 insertions, 46 deletions
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c
index f4a9cf9d26d0..33a84372c9e6 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,35 +493,51 @@ 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);
506 tda1004x_write_mask(state, TDA1004X_CONFADC2, 0xc0, 0);
515 507
516 /* don't re-upload unless necessary */ 508 /* don't re-upload unless necessary */
517 if (tda1004x_check_upload_ok(state) == 0) 509 if (tda1004x_check_upload_ok(state) == 0)
518 return 0; 510 return 0;
519 511
512 printk(KERN_INFO "tda1004x: trying to boot from eeprom\n");
513 tda1004x_write_mask(state, TDA1004X_CONFC4, 4, 4);
514 msleep(300);
515 /* don't re-upload unless necessary */
516 if (tda1004x_check_upload_ok(state) == 0)
517 return 0;
518
520 if (state->config->request_firmware != NULL) { 519 if (state->config->request_firmware != NULL) {
521 /* request the firmware, this will block until someone uploads it */ 520 /* request the firmware, this will block until someone uploads it */
522 printk(KERN_INFO "tda1004x: waiting for firmware upload...\n"); 521 printk(KERN_INFO "tda1004x: waiting for firmware upload...\n");
523 ret = state->config->request_firmware(fe, &fw, TDA10046_DEFAULT_FIRMWARE); 522 ret = state->config->request_firmware(fe, &fw, TDA10046_DEFAULT_FIRMWARE);
524 if (ret) { 523 if (ret) {
525 printk(KERN_ERR "tda1004x: no firmware upload (timeout or file not found?)\n"); 524 /* remain compatible to old bug: try to load with tda10045 image name */
526 return ret; 525 ret = state->config->request_firmware(fe, &fw, TDA10045_DEFAULT_FIRMWARE);
526 if (ret) {
527 printk(KERN_ERR "tda1004x: no firmware upload (timeout or file not found?)\n");
528 return ret;
529 } else {
530 printk(KERN_INFO "tda1004x: please rename the firmware file to %s\n",
531 TDA10046_DEFAULT_FIRMWARE);
532 }
527 } 533 }
528 tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8); // going to boot from HOST
529 ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10046H_CODE_CPT, TDA10046H_CODE_IN);
530 release_firmware(fw);
531 if (ret)
532 return ret;
533 } else { 534 } else {
534 /* boot from firmware eeprom */ 535 printk(KERN_ERR "tda1004x: no request function defined, can't upload from file\n");
535 printk(KERN_INFO "tda1004x: booting from eeprom\n"); 536 return -EIO;
536 tda1004x_write_mask(state, TDA1004X_CONFC4, 4, 4);
537 msleep(300);
538 } 537 }
538 tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8); // going to boot from HOST
539 ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10046H_CODE_CPT, TDA10046H_CODE_IN);
540 release_firmware(fw);
539 return tda1004x_check_upload_ok(state); 541 return tda1004x_check_upload_ok(state);
540} 542}
541 543
@@ -638,37 +640,33 @@ static int tda10046_init(struct dvb_frontend* fe)
638 switch (state->config->agc_config) { 640 switch (state->config->agc_config) {
639 case TDA10046_AGC_DEFAULT: 641 case TDA10046_AGC_DEFAULT:
640 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x00); // AGC setup 642 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x00); // AGC setup
641 tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities 643 tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x60); // set AGC polarities
642 break; 644 break;
643 case TDA10046_AGC_IFO_AUTO_NEG: 645 case TDA10046_AGC_IFO_AUTO_NEG:
644 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup 646 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup
645 tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities 647 tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x60); // set AGC polarities
646 break; 648 break;
647 case TDA10046_AGC_IFO_AUTO_POS: 649 case TDA10046_AGC_IFO_AUTO_POS:
648 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup 650 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup
649 tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x00); // set AGC polarities 651 tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x00); // set AGC polarities
650 break;
651 case TDA10046_AGC_TDA827X_GP11:
652 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup
653 tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold
654 tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize
655 tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x6a); // 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; 652 break;
663 case TDA10046_AGC_TDA827X_GP01: 653 case TDA10046_AGC_TDA827X:
664 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup 654 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup
665 tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold 655 tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold
666 tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize 656 tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize
667 tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x62); // set AGC polarities 657 tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x60); // set AGC polarities
668 break; 658 break;
669 } 659 }
660 if (state->config->ts_mode == 0) {
661 tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 0xc0, 0x40);
662 tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7);
663 } else {
664 tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 0xc0, 0x80);
665 tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0x10,
666 state->config->invert_oclk << 4);
667 }
670 tda1004x_write_byteI(state, TDA1004X_CONFADC2, 0x38); 668 tda1004x_write_byteI(state, TDA1004X_CONFADC2, 0x38);
671 tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0x61); // Turn both AGC outputs on 669 tda1004x_write_mask (state, TDA10046H_CONF_TRISTATE1, 0x3e, 0x38); // Turn IF AGC output on
672 tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MIN, 0); // } 670 tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MIN, 0); // }
673 tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MAX, 0xff); // } AGC min/max values 671 tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MAX, 0xff); // } AGC min/max values
674 tda1004x_write_byteI(state, TDA10046H_AGC_IF_MIN, 0); // } 672 tda1004x_write_byteI(state, TDA10046H_AGC_IF_MIN, 0); // }
@@ -678,7 +676,6 @@ static int tda10046_init(struct dvb_frontend* fe)
678 tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config 676 tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config
679 tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0xc0); // MPEG2 interface config 677 tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0xc0); // MPEG2 interface config
680 // tda1004x_write_mask(state, 0x50, 0x80, 0x80); // handle out of guard echoes 678 // tda1004x_write_mask(state, 0x50, 0x80, 0x80); // handle out of guard echoes
681 tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7);
682 679
683 return 0; 680 return 0;
684} 681}
@@ -705,7 +702,8 @@ static int tda1004x_set_fe(struct dvb_frontend* fe,
705 // set frequency 702 // set frequency
706 if (fe->ops.tuner_ops.set_params) { 703 if (fe->ops.tuner_ops.set_params) {
707 fe->ops.tuner_ops.set_params(fe, fe_params); 704 fe->ops.tuner_ops.set_params(fe, fe_params);
708 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); 705 if (fe->ops.i2c_gate_ctrl)
706 fe->ops.i2c_gate_ctrl(fe, 0);
709 } 707 }
710 708
711 // Hardcoded to use auto as much as possible on the TDA10045 as it 709 // Hardcoded to use auto as much as possible on the TDA10045 as it
@@ -1165,6 +1163,7 @@ static int tda1004x_read_ber(struct dvb_frontend* fe, u32* ber)
1165static int tda1004x_sleep(struct dvb_frontend* fe) 1163static int tda1004x_sleep(struct dvb_frontend* fe)
1166{ 1164{
1167 struct tda1004x_state* state = fe->demodulator_priv; 1165 struct tda1004x_state* state = fe->demodulator_priv;
1166 int gpio_conf;
1168 1167
1169 switch (state->demod_type) { 1168 switch (state->demod_type) {
1170 case TDA1004X_DEMOD_TDA10045: 1169 case TDA1004X_DEMOD_TDA10045:
@@ -1174,6 +1173,13 @@ static int tda1004x_sleep(struct dvb_frontend* fe)
1174 case TDA1004X_DEMOD_TDA10046: 1173 case TDA1004X_DEMOD_TDA10046:
1175 /* set outputs to tristate */ 1174 /* set outputs to tristate */
1176 tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0xff); 1175 tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0xff);
1176 /* invert GPIO 1 and 3 if desired*/
1177 gpio_conf = state->config->gpio_config;
1178 if (gpio_conf >= TDA10046_GP00_I)
1179 tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0x0f,
1180 (gpio_conf & 0x0f) ^ 0x0a);
1181
1182 tda1004x_write_mask(state, TDA1004X_CONFADC2, 0xc0, 0xc0);
1177 tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1); 1183 tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1);
1178 break; 1184 break;
1179 } 1185 }