diff options
Diffstat (limited to 'drivers/media/tuners/xc5000.c')
-rw-r--r-- | drivers/media/tuners/xc5000.c | 73 |
1 files changed, 38 insertions, 35 deletions
diff --git a/drivers/media/tuners/xc5000.c b/drivers/media/tuners/xc5000.c index 460df44aa1ad..39f9fb1001d8 100644 --- a/drivers/media/tuners/xc5000.c +++ b/drivers/media/tuners/xc5000.c | |||
@@ -625,48 +625,30 @@ static int xc_set_xtal(struct dvb_frontend *fe) | |||
625 | return ret; | 625 | return ret; |
626 | } | 626 | } |
627 | 627 | ||
628 | static int xc5000_fwupload(struct dvb_frontend *fe) | 628 | static int xc5000_fwupload(struct dvb_frontend *fe, |
629 | const struct xc5000_fw_cfg *desired_fw, | ||
630 | const struct firmware *fw) | ||
629 | { | 631 | { |
630 | struct xc5000_priv *priv = fe->tuner_priv; | 632 | struct xc5000_priv *priv = fe->tuner_priv; |
631 | const struct firmware *fw; | ||
632 | int ret; | 633 | int ret; |
633 | const struct xc5000_fw_cfg *desired_fw = | ||
634 | xc5000_assign_firmware(priv->chip_id); | ||
635 | priv->pll_register_no = desired_fw->pll_reg; | ||
636 | priv->init_status_supported = desired_fw->init_status_supported; | ||
637 | priv->fw_checksum_supported = desired_fw->fw_checksum_supported; | ||
638 | 634 | ||
639 | /* request the firmware, this will block and timeout */ | 635 | /* request the firmware, this will block and timeout */ |
640 | printk(KERN_INFO "xc5000: waiting for firmware upload (%s)...\n", | 636 | dprintk(1, "waiting for firmware upload (%s)...\n", |
641 | desired_fw->name); | 637 | desired_fw->name); |
642 | 638 | ||
643 | ret = request_firmware(&fw, desired_fw->name, | 639 | priv->pll_register_no = desired_fw->pll_reg; |
644 | priv->i2c_props.adap->dev.parent); | 640 | priv->init_status_supported = desired_fw->init_status_supported; |
645 | if (ret) { | 641 | priv->fw_checksum_supported = desired_fw->fw_checksum_supported; |
646 | printk(KERN_ERR "xc5000: Upload failed. (file not found?)\n"); | ||
647 | goto out; | ||
648 | } else { | ||
649 | printk(KERN_DEBUG "xc5000: firmware read %Zu bytes.\n", | ||
650 | fw->size); | ||
651 | ret = 0; | ||
652 | } | ||
653 | 642 | ||
654 | if (fw->size != desired_fw->size) { | ||
655 | printk(KERN_ERR "xc5000: firmware incorrect size\n"); | ||
656 | ret = -EINVAL; | ||
657 | } else { | ||
658 | printk(KERN_INFO "xc5000: firmware uploading...\n"); | ||
659 | ret = xc_load_i2c_sequence(fe, fw->data); | ||
660 | if (0 == ret) | ||
661 | ret = xc_set_xtal(fe); | ||
662 | if (0 == ret) | ||
663 | printk(KERN_INFO "xc5000: firmware upload complete...\n"); | ||
664 | else | ||
665 | printk(KERN_ERR "xc5000: firmware upload failed...\n"); | ||
666 | } | ||
667 | 643 | ||
668 | out: | 644 | dprintk(1, "firmware uploading...\n"); |
669 | release_firmware(fw); | 645 | ret = xc_load_i2c_sequence(fe, fw->data); |
646 | if (!ret) { | ||
647 | ret = xc_set_xtal(fe); | ||
648 | dprintk(1, "Firmware upload complete...\n"); | ||
649 | } else | ||
650 | printk(KERN_ERR "xc5000: firmware upload failed...\n"); | ||
651 | |||
670 | return ret; | 652 | return ret; |
671 | } | 653 | } |
672 | 654 | ||
@@ -1101,6 +1083,8 @@ static int xc5000_get_status(struct dvb_frontend *fe, u32 *status) | |||
1101 | static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe, int force) | 1083 | static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe, int force) |
1102 | { | 1084 | { |
1103 | struct xc5000_priv *priv = fe->tuner_priv; | 1085 | struct xc5000_priv *priv = fe->tuner_priv; |
1086 | const struct xc5000_fw_cfg *desired_fw = xc5000_assign_firmware(priv->chip_id); | ||
1087 | const struct firmware *fw; | ||
1104 | int ret, i; | 1088 | int ret, i; |
1105 | u16 pll_lock_status; | 1089 | u16 pll_lock_status; |
1106 | u16 fw_ck; | 1090 | u16 fw_ck; |
@@ -1110,11 +1094,26 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe, int force) | |||
1110 | if (!force && xc5000_is_firmware_loaded(fe) == 0) | 1094 | if (!force && xc5000_is_firmware_loaded(fe) == 0) |
1111 | return 0; | 1095 | return 0; |
1112 | 1096 | ||
1097 | ret = request_firmware(&fw, desired_fw->name, | ||
1098 | priv->i2c_props.adap->dev.parent); | ||
1099 | if (ret) { | ||
1100 | printk(KERN_ERR "xc5000: Upload failed. (file not found?)\n"); | ||
1101 | return ret; | ||
1102 | } | ||
1103 | |||
1104 | dprintk(1, "firmware read %Zu bytes.\n", fw->size); | ||
1105 | |||
1106 | if (fw->size != desired_fw->size) { | ||
1107 | printk(KERN_ERR "xc5000: firmware file with incorrect size\n"); | ||
1108 | ret = -EINVAL; | ||
1109 | goto err; | ||
1110 | } | ||
1111 | |||
1113 | /* Try up to 5 times to load firmware */ | 1112 | /* Try up to 5 times to load firmware */ |
1114 | for (i = 0; i < 5; i++) { | 1113 | for (i = 0; i < 5; i++) { |
1115 | ret = xc5000_fwupload(fe); | 1114 | ret = xc5000_fwupload(fe, desired_fw, fw); |
1116 | if (ret != 0) | 1115 | if (ret != 0) |
1117 | return ret; | 1116 | goto err; |
1118 | 1117 | ||
1119 | msleep(20); | 1118 | msleep(20); |
1120 | 1119 | ||
@@ -1171,9 +1170,13 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe, int force) | |||
1171 | 1170 | ||
1172 | /* Default to "CABLE" mode */ | 1171 | /* Default to "CABLE" mode */ |
1173 | ret = xc_write_reg(priv, XREG_SIGNALSOURCE, XC_RF_MODE_CABLE); | 1172 | ret = xc_write_reg(priv, XREG_SIGNALSOURCE, XC_RF_MODE_CABLE); |
1173 | printk(KERN_INFO "xc5000: Firmware %s loaded and running.\n", | ||
1174 | desired_fw->name); | ||
1174 | break; | 1175 | break; |
1175 | } | 1176 | } |
1176 | 1177 | ||
1178 | err: | ||
1179 | release_firmware(fw); | ||
1177 | return ret; | 1180 | return ret; |
1178 | } | 1181 | } |
1179 | 1182 | ||