aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd/rts5209.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/rts5209.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/rts5209.c')
-rw-r--r--drivers/mfd/rts5209.c48
1 files changed, 33 insertions, 15 deletions
diff --git a/drivers/mfd/rts5209.c b/drivers/mfd/rts5209.c
index ec78d9fb0879..2170449bd7e5 100644
--- a/drivers/mfd/rts5209.c
+++ b/drivers/mfd/rts5209.c
@@ -34,18 +34,28 @@ static u8 rts5209_get_ic_version(struct rtsx_pcr *pcr)
34 return val & 0x0F; 34 return val & 0x0F;
35} 35}
36 36
37static void rts5209_init_vendor_cfg(struct rtsx_pcr *pcr) 37static void rts5209_fetch_vendor_settings(struct rtsx_pcr *pcr)
38{ 38{
39 u32 val; 39 u32 reg;
40 40
41 rtsx_pci_read_config_dword(pcr, 0x724, &val); 41 rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, &reg);
42 dev_dbg(&(pcr->pci->dev), "Cfg 0x724: 0x%x\n", val); 42 dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
43 43
44 if (!(val & 0x80)) { 44 if (rts5209_vendor_setting1_valid(reg)) {
45 if (val & 0x08) 45 if (rts5209_reg_check_ms_pmos(reg))
46 pcr->ms_pmos = false; 46 pcr->flags |= PCR_MS_PMOS;
47 else 47 pcr->aspm_en = rts5209_reg_to_aspm(reg);
48 pcr->ms_pmos = true; 48 }
49
50 rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG2, &reg);
51 dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg);
52
53 if (rts5209_vendor_setting2_valid(reg)) {
54 pcr->sd30_drive_sel_1v8 =
55 rts5209_reg_to_sd30_drive_sel_1v8(reg);
56 pcr->sd30_drive_sel_3v3 =
57 rts5209_reg_to_sd30_drive_sel_3v3(reg);
58 pcr->card_drive_sel = rts5209_reg_to_card_drive_sel(reg);
49 } 59 }
50} 60}
51 61
@@ -57,6 +67,9 @@ static int rts5209_extra_init_hw(struct rtsx_pcr *pcr)
57 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_GPIO, 0xFF, 0x03); 67 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_GPIO, 0xFF, 0x03);
58 /* Configure GPIO as output */ 68 /* Configure GPIO as output */
59 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_GPIO_DIR, 0xFF, 0x03); 69 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_GPIO_DIR, 0xFF, 0x03);
70 /* Configure driving */
71 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DRIVE_SEL,
72 0xFF, pcr->sd30_drive_sel_3v3);
60 73
61 return rtsx_pci_send_cmd(pcr, 100); 74 return rtsx_pci_send_cmd(pcr, 100);
62} 75}
@@ -95,7 +108,7 @@ static int rts5209_card_power_on(struct rtsx_pcr *pcr, int card)
95 partial_pwr_on = SD_PARTIAL_POWER_ON; 108 partial_pwr_on = SD_PARTIAL_POWER_ON;
96 pwr_on = SD_POWER_ON; 109 pwr_on = SD_POWER_ON;
97 110
98 if (pcr->ms_pmos && (card == RTSX_MS_CARD)) { 111 if ((pcr->flags & PCR_MS_PMOS) && (card == RTSX_MS_CARD)) {
99 pwr_mask = MS_POWER_MASK; 112 pwr_mask = MS_POWER_MASK;
100 partial_pwr_on = MS_PARTIAL_POWER_ON; 113 partial_pwr_on = MS_PARTIAL_POWER_ON;
101 pwr_on = MS_POWER_ON; 114 pwr_on = MS_POWER_ON;
@@ -131,7 +144,7 @@ static int rts5209_card_power_off(struct rtsx_pcr *pcr, int card)
131 pwr_mask = SD_POWER_MASK; 144 pwr_mask = SD_POWER_MASK;
132 pwr_off = SD_POWER_OFF; 145 pwr_off = SD_POWER_OFF;
133 146
134 if (pcr->ms_pmos && (card == RTSX_MS_CARD)) { 147 if ((pcr->flags & PCR_MS_PMOS) && (card == RTSX_MS_CARD)) {
135 pwr_mask = MS_POWER_MASK; 148 pwr_mask = MS_POWER_MASK;
136 pwr_off = MS_POWER_OFF; 149 pwr_off = MS_POWER_OFF;
137 } 150 }
@@ -140,7 +153,7 @@ static int rts5209_card_power_off(struct rtsx_pcr *pcr, int card)
140 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL, 153 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
141 pwr_mask | PMOS_STRG_MASK, pwr_off | PMOS_STRG_400mA); 154 pwr_mask | PMOS_STRG_MASK, pwr_off | PMOS_STRG_400mA);
142 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL, 155 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
143 LDO3318_PWR_MASK, 0X06); 156 LDO3318_PWR_MASK, 0x06);
144 return rtsx_pci_send_cmd(pcr, 100); 157 return rtsx_pci_send_cmd(pcr, 100);
145} 158}
146 159
@@ -150,7 +163,7 @@ static int rts5209_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
150 163
151 if (voltage == OUTPUT_3V3) { 164 if (voltage == OUTPUT_3V3) {
152 err = rtsx_pci_write_register(pcr, 165 err = rtsx_pci_write_register(pcr,
153 SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_D); 166 SD30_DRIVE_SEL, 0x07, pcr->sd30_drive_sel_3v3);
154 if (err < 0) 167 if (err < 0)
155 return err; 168 return err;
156 err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4FC0 | 0x24); 169 err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4FC0 | 0x24);
@@ -158,7 +171,7 @@ static int rts5209_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
158 return err; 171 return err;
159 } else if (voltage == OUTPUT_1V8) { 172 } else if (voltage == OUTPUT_1V8) {
160 err = rtsx_pci_write_register(pcr, 173 err = rtsx_pci_write_register(pcr,
161 SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_B); 174 SD30_DRIVE_SEL, 0x07, pcr->sd30_drive_sel_1v8);
162 if (err < 0) 175 if (err < 0)
163 return err; 176 return err;
164 err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4C40 | 0x24); 177 err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4C40 | 0x24);
@@ -172,6 +185,7 @@ static int rts5209_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
172} 185}
173 186
174static const struct pcr_ops rts5209_pcr_ops = { 187static const struct pcr_ops rts5209_pcr_ops = {
188 .fetch_vendor_settings = rts5209_fetch_vendor_settings,
175 .extra_init_hw = rts5209_extra_init_hw, 189 .extra_init_hw = rts5209_extra_init_hw,
176 .optimize_phy = rts5209_optimize_phy, 190 .optimize_phy = rts5209_optimize_phy,
177 .turn_on_led = rts5209_turn_on_led, 191 .turn_on_led = rts5209_turn_on_led,
@@ -242,7 +256,11 @@ void rts5209_init_params(struct rtsx_pcr *pcr)
242 pcr->num_slots = 2; 256 pcr->num_slots = 2;
243 pcr->ops = &rts5209_pcr_ops; 257 pcr->ops = &rts5209_pcr_ops;
244 258
245 rts5209_init_vendor_cfg(pcr); 259 pcr->flags = 0;
260 pcr->card_drive_sel = RTS5209_CARD_DRIVE_DEFAULT;
261 pcr->sd30_drive_sel_1v8 = DRIVER_TYPE_B;
262 pcr->sd30_drive_sel_3v3 = DRIVER_TYPE_D;
263 pcr->aspm_en = ASPM_L1_EN;
246 264
247 pcr->ic_version = rts5209_get_ic_version(pcr); 265 pcr->ic_version = rts5209_get_ic_version(pcr);
248 pcr->sd_pull_ctl_enable_tbl = rts5209_sd_pull_ctl_enable_tbl; 266 pcr->sd_pull_ctl_enable_tbl = rts5209_sd_pull_ctl_enable_tbl;