aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd/rts5227.c
diff options
context:
space:
mode:
authorWei WANG <wei_wang@realsil.com.cn>2013-08-20 02:18:51 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2013-08-20 04:22:00 -0400
commit773ccdfd9cc6f9bf8ec75a59fa742d7a663a5903 (patch)
tree3e9ac1a210e718aaeb459dc8950666e928ca68b1 /drivers/mfd/rts5227.c
parent74d85e47ab8a7cdeffde6373cf1550bfbd2feaa6 (diff)
mfd: rtsx: Read vendor setting from config space
Normally OEMs will set vendor setting to the config space of Realtek card reader in BIOS stage. This patch reads the setting at the first, and configure the internal registers according to it, to improve card reader's compatibility condition. Signed-off-by: Wei WANG <wei_wang@realsil.com.cn> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/mfd/rts5227.c')
-rw-r--r--drivers/mfd/rts5227.c91
1 files changed, 71 insertions, 20 deletions
diff --git a/drivers/mfd/rts5227.c b/drivers/mfd/rts5227.c
index fc831dcb1480..c3181d71fedd 100644
--- a/drivers/mfd/rts5227.c
+++ b/drivers/mfd/rts5227.c
@@ -29,6 +29,60 @@
29 29
30#include "rtsx_pcr.h" 30#include "rtsx_pcr.h"
31 31
32static void rts5227_fill_driving(struct rtsx_pcr *pcr, u8 voltage)
33{
34 u8 driving_3v3[4][3] = {
35 {0x13, 0x13, 0x13},
36 {0x96, 0x96, 0x96},
37 {0x7F, 0x7F, 0x7F},
38 {0x96, 0x96, 0x96},
39 };
40 u8 driving_1v8[4][3] = {
41 {0x99, 0x99, 0x99},
42 {0xAA, 0xAA, 0xAA},
43 {0xFE, 0xFE, 0xFE},
44 {0xB3, 0xB3, 0xB3},
45 };
46 u8 (*driving)[3], drive_sel;
47
48 if (voltage == OUTPUT_3V3) {
49 driving = driving_3v3;
50 drive_sel = pcr->sd30_drive_sel_3v3;
51 } else {
52 driving = driving_1v8;
53 drive_sel = pcr->sd30_drive_sel_1v8;
54 }
55
56 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CLK_DRIVE_SEL,
57 0xFF, driving[drive_sel][0]);
58 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CMD_DRIVE_SEL,
59 0xFF, driving[drive_sel][1]);
60 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DAT_DRIVE_SEL,
61 0xFF, driving[drive_sel][2]);
62}
63
64static void rts5227_fetch_vendor_settings(struct rtsx_pcr *pcr)
65{
66 u32 reg;
67
68 rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, &reg);
69 dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
70
71 if (!rtsx_vendor_setting_valid(reg))
72 return;
73
74 pcr->aspm_en = rtsx_reg_to_aspm(reg);
75 pcr->sd30_drive_sel_1v8 = rtsx_reg_to_sd30_drive_sel_1v8(reg);
76 pcr->card_drive_sel &= 0x3F;
77 pcr->card_drive_sel |= rtsx_reg_to_card_drive_sel(reg);
78
79 rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG2, &reg);
80 dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg);
81 pcr->sd30_drive_sel_3v3 = rtsx_reg_to_sd30_drive_sel_3v3(reg);
82 if (rtsx_reg_check_reverse_socket(reg))
83 pcr->flags |= PCR_REVERSE_SOCKET;
84}
85
32static int rts5227_extra_init_hw(struct rtsx_pcr *pcr) 86static int rts5227_extra_init_hw(struct rtsx_pcr *pcr)
33{ 87{
34 u16 cap; 88 u16 cap;
@@ -48,17 +102,15 @@ static int rts5227_extra_init_hw(struct rtsx_pcr *pcr)
48 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LTR_CTL, 0xFF, 0xA3); 102 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LTR_CTL, 0xFF, 0xA3);
49 /* Configure OBFF */ 103 /* Configure OBFF */
50 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, OBFF_CFG, 0x03, 0x03); 104 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, OBFF_CFG, 0x03, 0x03);
51 /* Configure force_clock_req 105 /* Configure driving */
52 * Maybe We should define 0xFF03 as some name 106 rts5227_fill_driving(pcr, OUTPUT_3V3);
53 */ 107 /* Configure force_clock_req */
54 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, 0xFF03, 0x08, 0x08); 108 if (pcr->flags & PCR_REVERSE_SOCKET)
55 /* Correct driving */ 109 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
56 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, 110 AUTOLOAD_CFG_BASE + 3, 0xB8, 0xB8);
57 SD30_CLK_DRIVE_SEL, 0xFF, 0x96); 111 else
58 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, 112 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
59 SD30_CMD_DRIVE_SEL, 0xFF, 0x96); 113 AUTOLOAD_CFG_BASE + 3, 0xB8, 0x88);
60 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
61 SD30_DAT_DRIVE_SEL, 0xFF, 0x96);
62 114
63 return rtsx_pci_send_cmd(pcr, 100); 115 return rtsx_pci_send_cmd(pcr, 100);
64} 116}
@@ -131,13 +183,11 @@ static int rts5227_card_power_off(struct rtsx_pcr *pcr, int card)
131static int rts5227_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage) 183static int rts5227_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
132{ 184{
133 int err; 185 int err;
134 u8 drive_sel;
135 186
136 if (voltage == OUTPUT_3V3) { 187 if (voltage == OUTPUT_3V3) {
137 err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4FC0 | 0x24); 188 err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4FC0 | 0x24);
138 if (err < 0) 189 if (err < 0)
139 return err; 190 return err;
140 drive_sel = 0x96;
141 } else if (voltage == OUTPUT_1V8) { 191 } else if (voltage == OUTPUT_1V8) {
142 err = rtsx_pci_write_phy_register(pcr, 0x11, 0x3C02); 192 err = rtsx_pci_write_phy_register(pcr, 0x11, 0x3C02);
143 if (err < 0) 193 if (err < 0)
@@ -145,23 +195,18 @@ static int rts5227_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
145 err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4C80 | 0x24); 195 err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4C80 | 0x24);
146 if (err < 0) 196 if (err < 0)
147 return err; 197 return err;
148 drive_sel = 0xB3;
149 } else { 198 } else {
150 return -EINVAL; 199 return -EINVAL;
151 } 200 }
152 201
153 /* set pad drive */ 202 /* set pad drive */
154 rtsx_pci_init_cmd(pcr); 203 rtsx_pci_init_cmd(pcr);
155 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CLK_DRIVE_SEL, 204 rts5227_fill_driving(pcr, voltage);
156 0xFF, drive_sel);
157 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CMD_DRIVE_SEL,
158 0xFF, drive_sel);
159 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DAT_DRIVE_SEL,
160 0xFF, drive_sel);
161 return rtsx_pci_send_cmd(pcr, 100); 205 return rtsx_pci_send_cmd(pcr, 100);
162} 206}
163 207
164static const struct pcr_ops rts5227_pcr_ops = { 208static const struct pcr_ops rts5227_pcr_ops = {
209 .fetch_vendor_settings = rts5227_fetch_vendor_settings,
165 .extra_init_hw = rts5227_extra_init_hw, 210 .extra_init_hw = rts5227_extra_init_hw,
166 .optimize_phy = rts5227_optimize_phy, 211 .optimize_phy = rts5227_optimize_phy,
167 .turn_on_led = rts5227_turn_on_led, 212 .turn_on_led = rts5227_turn_on_led,
@@ -227,6 +272,12 @@ void rts5227_init_params(struct rtsx_pcr *pcr)
227 pcr->num_slots = 2; 272 pcr->num_slots = 2;
228 pcr->ops = &rts5227_pcr_ops; 273 pcr->ops = &rts5227_pcr_ops;
229 274
275 pcr->flags = 0;
276 pcr->card_drive_sel = RTSX_CARD_DRIVE_DEFAULT;
277 pcr->sd30_drive_sel_1v8 = CFG_DRIVER_TYPE_B;
278 pcr->sd30_drive_sel_3v3 = CFG_DRIVER_TYPE_B;
279 pcr->aspm_en = ASPM_L1_EN;
280
230 pcr->sd_pull_ctl_enable_tbl = rts5227_sd_pull_ctl_enable_tbl; 281 pcr->sd_pull_ctl_enable_tbl = rts5227_sd_pull_ctl_enable_tbl;
231 pcr->sd_pull_ctl_disable_tbl = rts5227_sd_pull_ctl_disable_tbl; 282 pcr->sd_pull_ctl_disable_tbl = rts5227_sd_pull_ctl_disable_tbl;
232 pcr->ms_pull_ctl_enable_tbl = rts5227_ms_pull_ctl_enable_tbl; 283 pcr->ms_pull_ctl_enable_tbl = rts5227_ms_pull_ctl_enable_tbl;