int chip_id;
u16 pll_register_no;
+ u8 init_status_supported;
+ u8 fw_checksum_supported;
};
/* Misc Defines */
#define XREG_BUSY 0x09
#define XREG_BUILD 0x0D
#define XREG_TOTALGAIN 0x0F
+#define XREG_FW_CHECKSUM 0x12
+#define XREG_INIT_STATUS 0x13
/*
Basic firmware description. This will remain with
char *name;
u16 size;
u16 pll_reg;
+ u8 init_status_supported;
+ u8 fw_checksum_supported;
};
#define XC5000A_FIRMWARE "dvb-fe-xc5000-1.6.114.fw"
.name = XC5000C_FIRMWARE,
.size = 16497,
.pll_reg = 0x13,
+ .init_status_supported = 1,
+ .fw_checksum_supported = 1,
};
static inline const struct xc5000_fw_cfg *xc5000_assign_firmware(int chip_id)
const struct xc5000_fw_cfg *desired_fw =
xc5000_assign_firmware(priv->chip_id);
priv->pll_register_no = desired_fw->pll_reg;
+ priv->init_status_supported = desired_fw->init_status_supported;
+ priv->fw_checksum_supported = desired_fw->fw_checksum_supported;
/* request the firmware, this will block and timeout */
printk(KERN_INFO "xc5000: waiting for firmware upload (%s)...\n",
struct xc5000_priv *priv = fe->tuner_priv;
int ret = XC_RESULT_SUCCESS;
u16 pll_lock_status;
+ u16 fw_ck;
if (force || xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) {
msleep(20);
+ if (priv->fw_checksum_supported) {
+ if (xc5000_readreg(priv, XREG_FW_CHECKSUM, &fw_ck)
+ != XC_RESULT_SUCCESS) {
+ dprintk(1, "%s() FW checksum reading failed.\n",
+ __func__);
+ goto fw_retry;
+ }
+
+ if (fw_ck == 0) {
+ dprintk(1, "%s() FW checksum failed = 0x%04x\n",
+ __func__, fw_ck);
+ goto fw_retry;
+ }
+ }
+
/* Start the tuner self-calibration process */
ret |= xc_initialize(priv);
*/
xc_wait(100);
+ if (priv->init_status_supported) {
+ if (xc5000_readreg(priv, XREG_INIT_STATUS, &fw_ck) != XC_RESULT_SUCCESS) {
+ dprintk(1, "%s() FW failed reading init status.\n",
+ __func__);
+ goto fw_retry;
+ }
+
+ if (fw_ck == 0) {
+ dprintk(1, "%s() FW init status failed = 0x%04x\n", __func__, fw_ck);
+ goto fw_retry;
+ }
+ }
+
if (priv->pll_register_no) {
xc5000_readreg(priv, priv->pll_register_no,
&pll_lock_status);