diff options
author | Steven Toth <stoth@linuxtv.org> | 2008-06-21 20:06:02 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-06-26 14:58:58 -0400 |
commit | e470d8177ed6ae56f4310ce793a57bcb2fed1749 (patch) | |
tree | 25a184be6b95988133889b8e2ffc651da643976c /drivers/media | |
parent | 836c28584d4629fdc85365f083b84e1298e14312 (diff) |
V4L/DVB (8097): xc5000: check device hardware state to determine if firmware download is needed
This patch ensures that the xc5000 will have firmware loaded as needed if the
part is powered down or reset via gpio from the host. An example of this, in
some cases, could be after the system resumes from standby or hibernate modes.
Signed-off-by: Michael Krufky <mkrufky@linuxtv.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/common/tuners/xc5000.c | 30 | ||||
-rw-r--r-- | drivers/media/common/tuners/xc5000_priv.h | 1 |
2 files changed, 23 insertions, 8 deletions
diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c index ceae6db901ec..7cf4f5bdb2ec 100644 --- a/drivers/media/common/tuners/xc5000.c +++ b/drivers/media/common/tuners/xc5000.c | |||
@@ -177,6 +177,7 @@ static XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = { | |||
177 | {"FM Radio-INPUT1", 0x0208, 0x9002} | 177 | {"FM Radio-INPUT1", 0x0208, 0x9002} |
178 | }; | 178 | }; |
179 | 179 | ||
180 | static int xc5000_is_firmware_loaded(struct dvb_frontend *fe); | ||
180 | static int xc5000_writeregs(struct xc5000_priv *priv, u8 *buf, u8 len); | 181 | static int xc5000_writeregs(struct xc5000_priv *priv, u8 *buf, u8 len); |
181 | static int xc5000_readregs(struct xc5000_priv *priv, u8 *buf, u8 len); | 182 | static int xc5000_readregs(struct xc5000_priv *priv, u8 *buf, u8 len); |
182 | static void xc5000_TunerReset(struct dvb_frontend *fe); | 183 | static void xc5000_TunerReset(struct dvb_frontend *fe); |
@@ -352,7 +353,7 @@ static int xc_SetTVStandard(struct xc5000_priv *priv, | |||
352 | 353 | ||
353 | static int xc_shutdown(struct xc5000_priv *priv) | 354 | static int xc_shutdown(struct xc5000_priv *priv) |
354 | { | 355 | { |
355 | return 0; | 356 | return XC_RESULT_SUCCESS; |
356 | /* Fixme: cannot bring tuner back alive once shutdown | 357 | /* Fixme: cannot bring tuner back alive once shutdown |
357 | * without reloading the driver modules. | 358 | * without reloading the driver modules. |
358 | * return xc_write_reg(priv, XREG_POWER_DOWN, 0); | 359 | * return xc_write_reg(priv, XREG_POWER_DOWN, 0); |
@@ -685,6 +686,25 @@ static int xc5000_set_params(struct dvb_frontend *fe, | |||
685 | return 0; | 686 | return 0; |
686 | } | 687 | } |
687 | 688 | ||
689 | static int xc5000_is_firmware_loaded(struct dvb_frontend *fe) | ||
690 | { | ||
691 | struct xc5000_priv *priv = fe->tuner_priv; | ||
692 | int ret; | ||
693 | u16 id; | ||
694 | |||
695 | ret = xc5000_readreg(priv, XREG_PRODUCT_ID, &id); | ||
696 | if (ret == XC_RESULT_SUCCESS) { | ||
697 | if (id == XC_PRODUCT_ID_FW_NOT_LOADED) | ||
698 | ret = XC_RESULT_RESET_FAILURE; | ||
699 | else | ||
700 | ret = XC_RESULT_SUCCESS; | ||
701 | } | ||
702 | |||
703 | dprintk(1, "%s() returns %s id = 0x%x\n", __func__, | ||
704 | ret == XC_RESULT_SUCCESS ? "True" : "False", id); | ||
705 | return ret; | ||
706 | } | ||
707 | |||
688 | static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe); | 708 | static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe); |
689 | 709 | ||
690 | static int xc5000_set_analog_params(struct dvb_frontend *fe, | 710 | static int xc5000_set_analog_params(struct dvb_frontend *fe, |
@@ -693,7 +713,7 @@ static int xc5000_set_analog_params(struct dvb_frontend *fe, | |||
693 | struct xc5000_priv *priv = fe->tuner_priv; | 713 | struct xc5000_priv *priv = fe->tuner_priv; |
694 | int ret; | 714 | int ret; |
695 | 715 | ||
696 | if(priv->fwloaded == 0) | 716 | if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) |
697 | xc_load_fw_and_init_tuner(fe); | 717 | xc_load_fw_and_init_tuner(fe); |
698 | 718 | ||
699 | dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n", | 719 | dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n", |
@@ -808,11 +828,10 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe) | |||
808 | struct xc5000_priv *priv = fe->tuner_priv; | 828 | struct xc5000_priv *priv = fe->tuner_priv; |
809 | int ret = 0; | 829 | int ret = 0; |
810 | 830 | ||
811 | if (priv->fwloaded == 0) { | 831 | if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) { |
812 | ret = xc5000_fwupload(fe); | 832 | ret = xc5000_fwupload(fe); |
813 | if (ret != XC_RESULT_SUCCESS) | 833 | if (ret != XC_RESULT_SUCCESS) |
814 | return ret; | 834 | return ret; |
815 | priv->fwloaded = 1; | ||
816 | } | 835 | } |
817 | 836 | ||
818 | /* Start the tuner self-calibration process */ | 837 | /* Start the tuner self-calibration process */ |
@@ -852,7 +871,6 @@ static int xc5000_sleep(struct dvb_frontend *fe) | |||
852 | return -EREMOTEIO; | 871 | return -EREMOTEIO; |
853 | } | 872 | } |
854 | else { | 873 | else { |
855 | /* priv->fwloaded = 0; */ | ||
856 | return XC_RESULT_SUCCESS; | 874 | return XC_RESULT_SUCCESS; |
857 | } | 875 | } |
858 | } | 876 | } |
@@ -933,7 +951,6 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, | |||
933 | cfg->i2c_address); | 951 | cfg->i2c_address); |
934 | printk(KERN_INFO | 952 | printk(KERN_INFO |
935 | "xc5000: Firmware has been loaded previously\n"); | 953 | "xc5000: Firmware has been loaded previously\n"); |
936 | priv->fwloaded = 1; | ||
937 | break; | 954 | break; |
938 | case XC_PRODUCT_ID_FW_NOT_LOADED: | 955 | case XC_PRODUCT_ID_FW_NOT_LOADED: |
939 | printk(KERN_INFO | 956 | printk(KERN_INFO |
@@ -941,7 +958,6 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, | |||
941 | cfg->i2c_address); | 958 | cfg->i2c_address); |
942 | printk(KERN_INFO | 959 | printk(KERN_INFO |
943 | "xc5000: Firmware has not been loaded previously\n"); | 960 | "xc5000: Firmware has not been loaded previously\n"); |
944 | priv->fwloaded = 0; | ||
945 | break; | 961 | break; |
946 | default: | 962 | default: |
947 | printk(KERN_ERR | 963 | printk(KERN_ERR |
diff --git a/drivers/media/common/tuners/xc5000_priv.h b/drivers/media/common/tuners/xc5000_priv.h index ecebfe4745ad..a72a9887fe7f 100644 --- a/drivers/media/common/tuners/xc5000_priv.h +++ b/drivers/media/common/tuners/xc5000_priv.h | |||
@@ -30,7 +30,6 @@ struct xc5000_priv { | |||
30 | u32 bandwidth; | 30 | u32 bandwidth; |
31 | u8 video_standard; | 31 | u8 video_standard; |
32 | u8 rf_mode; | 32 | u8 rf_mode; |
33 | u8 fwloaded; | ||
34 | 33 | ||
35 | void *devptr; | 34 | void *devptr; |
36 | }; | 35 | }; |