aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd/rtl8411.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/rtl8411.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/rtl8411.c')
-rw-r--r--drivers/mfd/rtl8411.c77
1 files changed, 71 insertions, 6 deletions
diff --git a/drivers/mfd/rtl8411.c b/drivers/mfd/rtl8411.c
index c436bf27e78d..5a68c9bdeddf 100644
--- a/drivers/mfd/rtl8411.c
+++ b/drivers/mfd/rtl8411.c
@@ -47,19 +47,70 @@ static int rtl8411b_is_qfn48(struct rtsx_pcr *pcr)
47 return 0; 47 return 0;
48} 48}
49 49
50static void rtl8411_fetch_vendor_settings(struct rtsx_pcr *pcr)
51{
52 u32 reg1;
53 u8 reg3;
54
55 rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, &reg1);
56 dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg1);
57
58 if (!rtsx_vendor_setting_valid(reg1))
59 return;
60
61 pcr->aspm_en = rtsx_reg_to_aspm(reg1);
62 pcr->sd30_drive_sel_1v8 =
63 map_sd_drive(rtsx_reg_to_sd30_drive_sel_1v8(reg1));
64 pcr->card_drive_sel &= 0x3F;
65 pcr->card_drive_sel |= rtsx_reg_to_card_drive_sel(reg1);
66
67 rtsx_pci_read_config_byte(pcr, PCR_SETTING_REG3, &reg3);
68 dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG3, reg3);
69 pcr->sd30_drive_sel_3v3 = rtl8411_reg_to_sd30_drive_sel_3v3(reg3);
70}
71
72static void rtl8411b_fetch_vendor_settings(struct rtsx_pcr *pcr)
73{
74 u32 reg;
75
76 rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, &reg);
77 dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
78
79 if (!rtsx_vendor_setting_valid(reg))
80 return;
81
82 pcr->aspm_en = rtsx_reg_to_aspm(reg);
83 pcr->sd30_drive_sel_1v8 =
84 map_sd_drive(rtsx_reg_to_sd30_drive_sel_1v8(reg));
85 pcr->sd30_drive_sel_3v3 =
86 map_sd_drive(rtl8411b_reg_to_sd30_drive_sel_3v3(reg));
87}
88
50static int rtl8411_extra_init_hw(struct rtsx_pcr *pcr) 89static int rtl8411_extra_init_hw(struct rtsx_pcr *pcr)
51{ 90{
52 return rtsx_pci_write_register(pcr, CD_PAD_CTL, 91 rtsx_pci_init_cmd(pcr);
92
93 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DRIVE_SEL,
94 0xFF, pcr->sd30_drive_sel_3v3);
95 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CD_PAD_CTL,
53 CD_DISABLE_MASK | CD_AUTO_DISABLE, CD_ENABLE); 96 CD_DISABLE_MASK | CD_AUTO_DISABLE, CD_ENABLE);
97
98 return rtsx_pci_send_cmd(pcr, 100);
54} 99}
55 100
56static int rtl8411b_extra_init_hw(struct rtsx_pcr *pcr) 101static int rtl8411b_extra_init_hw(struct rtsx_pcr *pcr)
57{ 102{
58 if (rtl8411b_is_qfn48(pcr)) 103 rtsx_pci_init_cmd(pcr);
59 rtsx_pci_write_register(pcr, CARD_PULL_CTL3, 0xFF, 0xF5);
60 104
61 return rtsx_pci_write_register(pcr, CD_PAD_CTL, 105 if (rtl8411b_is_qfn48(pcr))
106 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
107 CARD_PULL_CTL3, 0xFF, 0xF5);
108 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DRIVE_SEL,
109 0xFF, pcr->sd30_drive_sel_3v3);
110 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CD_PAD_CTL,
62 CD_DISABLE_MASK | CD_AUTO_DISABLE, CD_ENABLE); 111 CD_DISABLE_MASK | CD_AUTO_DISABLE, CD_ENABLE);
112
113 return rtsx_pci_send_cmd(pcr, 100);
63} 114}
64 115
65static int rtl8411_turn_on_led(struct rtsx_pcr *pcr) 116static int rtl8411_turn_on_led(struct rtsx_pcr *pcr)
@@ -141,13 +192,13 @@ static int rtl8411_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
141 mask = (BPP_REG_TUNED18 << BPP_TUNED18_SHIFT_8411) | BPP_PAD_MASK; 192 mask = (BPP_REG_TUNED18 << BPP_TUNED18_SHIFT_8411) | BPP_PAD_MASK;
142 if (voltage == OUTPUT_3V3) { 193 if (voltage == OUTPUT_3V3) {
143 err = rtsx_pci_write_register(pcr, 194 err = rtsx_pci_write_register(pcr,
144 SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_D); 195 SD30_DRIVE_SEL, 0x07, pcr->sd30_drive_sel_3v3);
145 if (err < 0) 196 if (err < 0)
146 return err; 197 return err;
147 val = (BPP_ASIC_3V3 << BPP_TUNED18_SHIFT_8411) | BPP_PAD_3V3; 198 val = (BPP_ASIC_3V3 << BPP_TUNED18_SHIFT_8411) | BPP_PAD_3V3;
148 } else if (voltage == OUTPUT_1V8) { 199 } else if (voltage == OUTPUT_1V8) {
149 err = rtsx_pci_write_register(pcr, 200 err = rtsx_pci_write_register(pcr,
150 SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_B); 201 SD30_DRIVE_SEL, 0x07, pcr->sd30_drive_sel_1v8);
151 if (err < 0) 202 if (err < 0)
152 return err; 203 return err;
153 val = (BPP_ASIC_1V8 << BPP_TUNED18_SHIFT_8411) | BPP_PAD_1V8; 204 val = (BPP_ASIC_1V8 << BPP_TUNED18_SHIFT_8411) | BPP_PAD_1V8;
@@ -222,6 +273,7 @@ static int rtl8411_conv_clk_and_div_n(int input, int dir)
222} 273}
223 274
224static const struct pcr_ops rtl8411_pcr_ops = { 275static const struct pcr_ops rtl8411_pcr_ops = {
276 .fetch_vendor_settings = rtl8411_fetch_vendor_settings,
225 .extra_init_hw = rtl8411_extra_init_hw, 277 .extra_init_hw = rtl8411_extra_init_hw,
226 .optimize_phy = NULL, 278 .optimize_phy = NULL,
227 .turn_on_led = rtl8411_turn_on_led, 279 .turn_on_led = rtl8411_turn_on_led,
@@ -236,6 +288,7 @@ static const struct pcr_ops rtl8411_pcr_ops = {
236}; 288};
237 289
238static const struct pcr_ops rtl8411b_pcr_ops = { 290static const struct pcr_ops rtl8411b_pcr_ops = {
291 .fetch_vendor_settings = rtl8411b_fetch_vendor_settings,
239 .extra_init_hw = rtl8411b_extra_init_hw, 292 .extra_init_hw = rtl8411b_extra_init_hw,
240 .optimize_phy = NULL, 293 .optimize_phy = NULL,
241 .turn_on_led = rtl8411_turn_on_led, 294 .turn_on_led = rtl8411_turn_on_led,
@@ -385,6 +438,12 @@ void rtl8411_init_params(struct rtsx_pcr *pcr)
385 pcr->num_slots = 2; 438 pcr->num_slots = 2;
386 pcr->ops = &rtl8411_pcr_ops; 439 pcr->ops = &rtl8411_pcr_ops;
387 440
441 pcr->flags = 0;
442 pcr->card_drive_sel = RTL8411_CARD_DRIVE_DEFAULT;
443 pcr->sd30_drive_sel_1v8 = DRIVER_TYPE_B;
444 pcr->sd30_drive_sel_3v3 = DRIVER_TYPE_D;
445 pcr->aspm_en = ASPM_L1_EN;
446
388 pcr->ic_version = rtl8411_get_ic_version(pcr); 447 pcr->ic_version = rtl8411_get_ic_version(pcr);
389 pcr->sd_pull_ctl_enable_tbl = rtl8411_sd_pull_ctl_enable_tbl; 448 pcr->sd_pull_ctl_enable_tbl = rtl8411_sd_pull_ctl_enable_tbl;
390 pcr->sd_pull_ctl_disable_tbl = rtl8411_sd_pull_ctl_disable_tbl; 449 pcr->sd_pull_ctl_disable_tbl = rtl8411_sd_pull_ctl_disable_tbl;
@@ -398,6 +457,12 @@ void rtl8411b_init_params(struct rtsx_pcr *pcr)
398 pcr->num_slots = 2; 457 pcr->num_slots = 2;
399 pcr->ops = &rtl8411b_pcr_ops; 458 pcr->ops = &rtl8411b_pcr_ops;
400 459
460 pcr->flags = 0;
461 pcr->card_drive_sel = RTL8411_CARD_DRIVE_DEFAULT;
462 pcr->sd30_drive_sel_1v8 = DRIVER_TYPE_B;
463 pcr->sd30_drive_sel_3v3 = DRIVER_TYPE_D;
464 pcr->aspm_en = ASPM_L1_EN;
465
401 pcr->ic_version = rtl8411_get_ic_version(pcr); 466 pcr->ic_version = rtl8411_get_ic_version(pcr);
402 467
403 if (rtl8411b_is_qfn48(pcr)) { 468 if (rtl8411b_is_qfn48(pcr)) {