Different card reader has different method to switch output voltage, add this callback to let the card reader implement its individual switch function. This is needed as rtl8411 has a specific switch output voltage procedure.
Unified · Split
| @@ -112,6 +112,21 @@ static int rtl8411_card_power_off(struct rtsx_pcr *pcr, int card) · 111 unmodified lines | ||
| 112 | 112 | BPP_LDO_POWB, BPP_LDO_SUSPEND); |
| 113 | 113 | } |
| 114 | 114 | |
| 115 | +static int rtl8411_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage) | |
| 116 | +{ | |
| 117 | + u8 mask, val; | |
| 118 | + | |
| 119 | + mask = (BPP_REG_TUNED18 << BPP_TUNED18_SHIFT_8411) | BPP_PAD_MASK; | |
| 120 | + if (voltage == OUTPUT_3V3) | |
| 121 | + val = (BPP_ASIC_3V3 << BPP_TUNED18_SHIFT_8411) | BPP_PAD_3V3; | |
| 122 | + else if (voltage == OUTPUT_1V8) | |
| 123 | + val = (BPP_ASIC_1V8 << BPP_TUNED18_SHIFT_8411) | BPP_PAD_1V8; | |
| 124 | + else | |
| 125 | + return -EINVAL; | |
| 126 | + | |
| 127 | + return rtsx_pci_write_register(pcr, LDO_CTL, mask, val); | |
| 128 | +} | |
| 129 | + | |
| 115 | 130 | static unsigned int rtl8411_cd_deglitch(struct rtsx_pcr *pcr) |
| 116 | 131 | { |
| 117 | 132 | unsigned int card_exist; |
| @@ -172,6 +187,7 @@ static const struct pcr_ops rtl8411_pcr_ops = { · 54 unmodified lines | ||
| 172 | 187 | .disable_auto_blink = rtl8411_disable_auto_blink, |
| 173 | 188 | .card_power_on = rtl8411_card_power_on, |
| 174 | 189 | .card_power_off = rtl8411_card_power_off, |
| 190 | + .switch_output_voltage = rtl8411_switch_output_voltage, | |
| 175 | 191 | .cd_deglitch = rtl8411_cd_deglitch, |
| 176 | 192 | }; |
| 177 | 193 | |
| @@ -144,6 +144,25 @@ static int rts5209_card_power_off(struct rtsx_pcr *pcr, int card) · 143 unmodified lines | ||
| 144 | 144 | return rtsx_pci_send_cmd(pcr, 100); |
| 145 | 145 | } |
| 146 | 146 | |
| 147 | +static int rts5209_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage) | |
| 148 | +{ | |
| 149 | + int err; | |
| 150 | + | |
| 151 | + if (voltage == OUTPUT_3V3) { | |
| 152 | + err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4FC0 | 0x24); | |
| 153 | + if (err < 0) | |
| 154 | + return err; | |
| 155 | + } else if (voltage == OUTPUT_1V8) { | |
| 156 | + err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4C40 | 0x24); | |
| 157 | + if (err < 0) | |
| 158 | + return err; | |
| 159 | + } else { | |
| 160 | + return -EINVAL; | |
| 161 | + } | |
| 162 | + | |
| 163 | + return 0; | |
| 164 | +} | |
| 165 | + | |
| 147 | 166 | static const struct pcr_ops rts5209_pcr_ops = { |
| 148 | 167 | .extra_init_hw = rts5209_extra_init_hw, |
| 149 | 168 | .optimize_phy = rts5209_optimize_phy, |
| @@ -153,6 +172,7 @@ static const struct pcr_ops rts5209_pcr_ops = { · 3 unmodified lines | ||
| 153 | 172 | .disable_auto_blink = rts5209_disable_auto_blink, |
| 154 | 173 | .card_power_on = rts5209_card_power_on, |
| 155 | 174 | .card_power_off = rts5209_card_power_off, |
| 175 | + .switch_output_voltage = rts5209_switch_output_voltage, | |
| 156 | 176 | .cd_deglitch = NULL, |
| 157 | 177 | }; |
| 158 | 178 | |
| @@ -114,6 +114,25 @@ static int rts5229_card_power_off(struct rtsx_pcr *pcr, int card) · 113 unmodified lines | ||
| 114 | 114 | return rtsx_pci_send_cmd(pcr, 100); |
| 115 | 115 | } |
| 116 | 116 | |
| 117 | +static int rts5229_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage) | |
| 118 | +{ | |
| 119 | + int err; | |
| 120 | + | |
| 121 | + if (voltage == OUTPUT_3V3) { | |
| 122 | + err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4FC0 | 0x24); | |
| 123 | + if (err < 0) | |
| 124 | + return err; | |
| 125 | + } else if (voltage == OUTPUT_1V8) { | |
| 126 | + err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4C40 | 0x24); | |
| 127 | + if (err < 0) | |
| 128 | + return err; | |
| 129 | + } else { | |
| 130 | + return -EINVAL; | |
| 131 | + } | |
| 132 | + | |
| 133 | + return 0; | |
| 134 | +} | |
| 135 | + | |
| 117 | 136 | static const struct pcr_ops rts5229_pcr_ops = { |
| 118 | 137 | .extra_init_hw = rts5229_extra_init_hw, |
| 119 | 138 | .optimize_phy = rts5229_optimize_phy, |
| @@ -123,6 +142,7 @@ static const struct pcr_ops rts5229_pcr_ops = { · 3 unmodified lines | ||
| 123 | 142 | .disable_auto_blink = rts5229_disable_auto_blink, |
| 124 | 143 | .card_power_on = rts5229_card_power_on, |
| 125 | 144 | .card_power_off = rts5229_card_power_off, |
| 145 | + .switch_output_voltage = rts5229_switch_output_voltage, | |
| 126 | 146 | .cd_deglitch = NULL, |
| 127 | 147 | }; |
| 128 | 148 | |
| @@ -703,6 +703,15 @@ int rtsx_pci_card_power_off(struct rtsx_pcr *pcr, int card) · 702 unmodified lines | ||
| 703 | 703 | } |
| 704 | 704 | EXPORT_SYMBOL_GPL(rtsx_pci_card_power_off); |
| 705 | 705 | |
| 706 | +int rtsx_pci_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage) | |
| 707 | +{ | |
| 708 | + if (pcr->ops->switch_output_voltage) | |
| 709 | + return pcr->ops->switch_output_voltage(pcr, voltage); | |
| 710 | + | |
| 711 | + return 0; | |
| 712 | +} | |
| 713 | +EXPORT_SYMBOL_GPL(rtsx_pci_switch_output_voltage); | |
| 714 | + | |
| 706 | 715 | unsigned int rtsx_pci_card_exist(struct rtsx_pcr *pcr) |
| 707 | 716 | { |
| 708 | 717 | unsigned int val; |
| @@ -158,10 +158,9 @@ · 157 unmodified lines | ||
| 158 | 158 | #define SG_TRANS_DATA (0x02 << 4) |
| 159 | 159 | #define SG_LINK_DESC (0x03 << 4) |
| 160 | 160 | |
| 161 | −/* SD bank voltage */ | |
| 162 | −#define SD_IO_3V3 0 | |
| 163 | −#define SD_IO_1V8 1 | |
| 164 | − | |
| 161 | +/* Output voltage */ | |
| 162 | +#define OUTPUT_3V3 0 | |
| 163 | +#define OUTPUT_1V8 1 | |
| 165 | 164 | |
| 166 | 165 | /* Card Clock Enable Register */ |
| 167 | 166 | #define SD_CLK_EN 0x04 |
| @@ -201,6 +200,20 @@ · 33 unmodified lines | ||
| 201 | 200 | #define CHANGE_CLK 0x01 |
| 202 | 201 | |
| 203 | 202 | /* LDO_CTL */ |
| 203 | +#define BPP_ASIC_1V7 0x00 | |
| 204 | +#define BPP_ASIC_1V8 0x01 | |
| 205 | +#define BPP_ASIC_1V9 0x02 | |
| 206 | +#define BPP_ASIC_2V0 0x03 | |
| 207 | +#define BPP_ASIC_2V7 0x04 | |
| 208 | +#define BPP_ASIC_2V8 0x05 | |
| 209 | +#define BPP_ASIC_3V2 0x06 | |
| 210 | +#define BPP_ASIC_3V3 0x07 | |
| 211 | +#define BPP_REG_TUNED18 0x07 | |
| 212 | +#define BPP_TUNED18_SHIFT_8402 5 | |
| 213 | +#define BPP_TUNED18_SHIFT_8411 4 | |
| 214 | +#define BPP_PAD_MASK 0x04 | |
| 215 | +#define BPP_PAD_3V3 0x04 | |
| 216 | +#define BPP_PAD_1V8 0x00 | |
| 204 | 217 | #define BPP_LDO_POWB 0x03 |
| 205 | 218 | #define BPP_LDO_ON 0x00 |
| 206 | 219 | #define BPP_LDO_SUSPEND 0x02 |
| @@ -688,6 +701,8 @@ struct pcr_ops { · 481 unmodified lines | ||
| 688 | 701 | int (*disable_auto_blink)(struct rtsx_pcr *pcr); |
| 689 | 702 | int (*card_power_on)(struct rtsx_pcr *pcr, int card); |
| 690 | 703 | int (*card_power_off)(struct rtsx_pcr *pcr, int card); |
| 704 | + int (*switch_output_voltage)(struct rtsx_pcr *pcr, | |
| 705 | + u8 voltage); | |
| 691 | 706 | unsigned int (*cd_deglitch)(struct rtsx_pcr *pcr); |
| 692 | 707 | }; |
| 693 | 708 | |
| @@ -783,6 +798,7 @@ int rtsx_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock, · 89 unmodified lines | ||
| 783 | 798 | u8 ssc_depth, bool initial_mode, bool double_clk, bool vpclk); |
| 784 | 799 | int rtsx_pci_card_power_on(struct rtsx_pcr *pcr, int card); |
| 785 | 800 | int rtsx_pci_card_power_off(struct rtsx_pcr *pcr, int card); |
| 801 | +int rtsx_pci_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage); | |
| 786 | 802 | unsigned int rtsx_pci_card_exist(struct rtsx_pcr *pcr); |
| 787 | 803 | void rtsx_pci_complete_unfinished_transfer(struct rtsx_pcr *pcr); |
| 788 | 804 | |