History

mfd: rtsx: Add output voltage switch hook

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.

Wei WANG committed 13 years ago

Commit d817ac41 parent 00441b55 files · +85 −4Browse files

Unified · Split

5 files
  1. drivers/mfd/rtl8411.c +16 −0
  2. drivers/mfd/rts5209.c +20 −0
  3. drivers/mfd/rts5229.c +20 −0
  4. drivers/mfd/rtsx_pcr.c +9 −0
  5. include/linux/mfd/rtsx_pci.h +20 −4
drivers/mfd/rtl8411.c+16−0
@@ -112,6 +112,21 @@ static int rtl8411_card_power_off(struct rtsx_pcr *pcr, int card) · 111 unmodified lines
112112 BPP_LDO_POWB, BPP_LDO_SUSPEND);
113113 }
114114
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+
115130 static unsigned int rtl8411_cd_deglitch(struct rtsx_pcr *pcr)
116131 {
117132 unsigned int card_exist;
@@ -172,6 +187,7 @@ static const struct pcr_ops rtl8411_pcr_ops = { · 54 unmodified lines
172187 .disable_auto_blink = rtl8411_disable_auto_blink,
173188 .card_power_on = rtl8411_card_power_on,
174189 .card_power_off = rtl8411_card_power_off,
190+ .switch_output_voltage = rtl8411_switch_output_voltage,
175191 .cd_deglitch = rtl8411_cd_deglitch,
176192 };
177193
drivers/mfd/rts5209.c+20−0
@@ -144,6 +144,25 @@ static int rts5209_card_power_off(struct rtsx_pcr *pcr, int card) · 143 unmodified lines
144144 return rtsx_pci_send_cmd(pcr, 100);
145145 }
146146
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+
147166 static const struct pcr_ops rts5209_pcr_ops = {
148167 .extra_init_hw = rts5209_extra_init_hw,
149168 .optimize_phy = rts5209_optimize_phy,
@@ -153,6 +172,7 @@ static const struct pcr_ops rts5209_pcr_ops = { · 3 unmodified lines
153172 .disable_auto_blink = rts5209_disable_auto_blink,
154173 .card_power_on = rts5209_card_power_on,
155174 .card_power_off = rts5209_card_power_off,
175+ .switch_output_voltage = rts5209_switch_output_voltage,
156176 .cd_deglitch = NULL,
157177 };
158178
drivers/mfd/rts5229.c+20−0
@@ -114,6 +114,25 @@ static int rts5229_card_power_off(struct rtsx_pcr *pcr, int card) · 113 unmodified lines
114114 return rtsx_pci_send_cmd(pcr, 100);
115115 }
116116
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+
117136 static const struct pcr_ops rts5229_pcr_ops = {
118137 .extra_init_hw = rts5229_extra_init_hw,
119138 .optimize_phy = rts5229_optimize_phy,
@@ -123,6 +142,7 @@ static const struct pcr_ops rts5229_pcr_ops = { · 3 unmodified lines
123142 .disable_auto_blink = rts5229_disable_auto_blink,
124143 .card_power_on = rts5229_card_power_on,
125144 .card_power_off = rts5229_card_power_off,
145+ .switch_output_voltage = rts5229_switch_output_voltage,
126146 .cd_deglitch = NULL,
127147 };
128148
drivers/mfd/rtsx_pcr.c+9−0
@@ -703,6 +703,15 @@ int rtsx_pci_card_power_off(struct rtsx_pcr *pcr, int card) · 702 unmodified lines
703703 }
704704 EXPORT_SYMBOL_GPL(rtsx_pci_card_power_off);
705705
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+
706715 unsigned int rtsx_pci_card_exist(struct rtsx_pcr *pcr)
707716 {
708717 unsigned int val;
include/linux/mfd/rtsx_pci.h+20−4
@@ -158,10 +158,9 @@ · 157 unmodified lines
158158 #define SG_TRANS_DATA (0x02 << 4)
159159 #define SG_LINK_DESC (0x03 << 4)
160160
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
165164
166165 /* Card Clock Enable Register */
167166 #define SD_CLK_EN 0x04
@@ -201,6 +200,20 @@ · 33 unmodified lines
201200 #define CHANGE_CLK 0x01
202201
203202 /* 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
204217 #define BPP_LDO_POWB 0x03
205218 #define BPP_LDO_ON 0x00
206219 #define BPP_LDO_SUSPEND 0x02
@@ -688,6 +701,8 @@ struct pcr_ops { · 481 unmodified lines
688701 int (*disable_auto_blink)(struct rtsx_pcr *pcr);
689702 int (*card_power_on)(struct rtsx_pcr *pcr, int card);
690703 int (*card_power_off)(struct rtsx_pcr *pcr, int card);
704+ int (*switch_output_voltage)(struct rtsx_pcr *pcr,
705+ u8 voltage);
691706 unsigned int (*cd_deglitch)(struct rtsx_pcr *pcr);
692707 };
693708
@@ -783,6 +798,7 @@ int rtsx_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock, · 89 unmodified lines
783798 u8 ssc_depth, bool initial_mode, bool double_clk, bool vpclk);
784799 int rtsx_pci_card_power_on(struct rtsx_pcr *pcr, int card);
785800 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);
786802 unsigned int rtsx_pci_card_exist(struct rtsx_pcr *pcr);
787803 void rtsx_pci_complete_unfinished_transfer(struct rtsx_pcr *pcr);
788804