Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mfd: rtsx: Support RTS5227

Support new model RTS5227.

Signed-off-by: Roger Tseng <rogerable@realtek.com>
Reviewed-by: Wei WANG <wei_wang@realsil.com.cn>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>

authored by

Roger Tseng and committed by
Samuel Ortiz
e1237932 88a7ee37

+246 -1
+1 -1
drivers/mfd/Makefile
··· 9 9 obj-$(CONFIG_MFD_SM501) += sm501.o 10 10 obj-$(CONFIG_MFD_ASIC3) += asic3.o tmio_core.o 11 11 12 - rtsx_pci-objs := rtsx_pcr.o rts5209.o rts5229.o rtl8411.o 12 + rtsx_pci-objs := rtsx_pcr.o rts5209.o rts5229.o rtl8411.o rts5227.o 13 13 obj-$(CONFIG_MFD_RTSX_PCI) += rtsx_pci.o 14 14 15 15 obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o
+234
drivers/mfd/rts5227.c
··· 1 + /* Driver for Realtek PCI-Express card reader 2 + * 3 + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. 4 + * 5 + * This program is free software; you can redistribute it and/or modify it 6 + * under the terms of the GNU General Public License as published by the 7 + * Free Software Foundation; either version 2, or (at your option) any 8 + * later version. 9 + * 10 + * This program is distributed in the hope that it will be useful, but 11 + * WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 + * General Public License for more details. 14 + * 15 + * You should have received a copy of the GNU General Public License along 16 + * with this program; if not, see <http://www.gnu.org/licenses/>. 17 + * 18 + * Author: 19 + * Wei WANG <wei_wang@realsil.com.cn> 20 + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China 21 + * 22 + * Roger Tseng <rogerable@realtek.com> 23 + * No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan 24 + */ 25 + 26 + #include <linux/module.h> 27 + #include <linux/delay.h> 28 + #include <linux/mfd/rtsx_pci.h> 29 + 30 + #include "rtsx_pcr.h" 31 + 32 + static int rts5227_extra_init_hw(struct rtsx_pcr *pcr) 33 + { 34 + u16 cap; 35 + 36 + rtsx_pci_init_cmd(pcr); 37 + 38 + /* Configure GPIO as output */ 39 + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, GPIO_CTL, 0x02, 0x02); 40 + /* Switch LDO3318 source from DV33 to card_3v3 */ 41 + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x00); 42 + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x01); 43 + /* LED shine disabled, set initial shine cycle period */ 44 + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, OLT_LED_CTL, 0x0F, 0x02); 45 + /* Configure LTR */ 46 + pcie_capability_read_word(pcr->pci, PCI_EXP_DEVCTL2, &cap); 47 + if (cap & PCI_EXP_LTR_EN) 48 + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LTR_CTL, 0xFF, 0xA3); 49 + /* Configure OBFF */ 50 + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, OBFF_CFG, 0x03, 0x03); 51 + /* Configure force_clock_req 52 + * Maybe We should define 0xFF03 as some name 53 + */ 54 + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, 0xFF03, 0x08, 0x08); 55 + /* Correct driving */ 56 + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, 57 + SD30_CLK_DRIVE_SEL, 0xFF, 0x96); 58 + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, 59 + SD30_CMD_DRIVE_SEL, 0xFF, 0x96); 60 + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, 61 + SD30_DAT_DRIVE_SEL, 0xFF, 0x96); 62 + 63 + return rtsx_pci_send_cmd(pcr, 100); 64 + } 65 + 66 + static int rts5227_optimize_phy(struct rtsx_pcr *pcr) 67 + { 68 + /* Optimize RX sensitivity */ 69 + return rtsx_pci_write_phy_register(pcr, 0x00, 0xBA42); 70 + } 71 + 72 + static int rts5227_turn_on_led(struct rtsx_pcr *pcr) 73 + { 74 + return rtsx_pci_write_register(pcr, GPIO_CTL, 0x02, 0x02); 75 + } 76 + 77 + static int rts5227_turn_off_led(struct rtsx_pcr *pcr) 78 + { 79 + return rtsx_pci_write_register(pcr, GPIO_CTL, 0x02, 0x00); 80 + } 81 + 82 + static int rts5227_enable_auto_blink(struct rtsx_pcr *pcr) 83 + { 84 + return rtsx_pci_write_register(pcr, OLT_LED_CTL, 0x08, 0x08); 85 + } 86 + 87 + static int rts5227_disable_auto_blink(struct rtsx_pcr *pcr) 88 + { 89 + return rtsx_pci_write_register(pcr, OLT_LED_CTL, 0x08, 0x00); 90 + } 91 + 92 + static int rts5227_card_power_on(struct rtsx_pcr *pcr, int card) 93 + { 94 + int err; 95 + 96 + rtsx_pci_init_cmd(pcr); 97 + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL, 98 + SD_POWER_MASK, SD_PARTIAL_POWER_ON); 99 + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL, 100 + LDO3318_PWR_MASK, 0x02); 101 + err = rtsx_pci_send_cmd(pcr, 100); 102 + if (err < 0) 103 + return err; 104 + 105 + /* To avoid too large in-rush current */ 106 + udelay(150); 107 + 108 + rtsx_pci_init_cmd(pcr); 109 + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL, 110 + SD_POWER_MASK, SD_POWER_ON); 111 + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL, 112 + LDO3318_PWR_MASK, 0x06); 113 + err = rtsx_pci_send_cmd(pcr, 100); 114 + if (err < 0) 115 + return err; 116 + 117 + return 0; 118 + } 119 + 120 + static int rts5227_card_power_off(struct rtsx_pcr *pcr, int card) 121 + { 122 + rtsx_pci_init_cmd(pcr); 123 + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL, 124 + SD_POWER_MASK | PMOS_STRG_MASK, 125 + SD_POWER_OFF | PMOS_STRG_400mA); 126 + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL, 127 + LDO3318_PWR_MASK, 0X00); 128 + return rtsx_pci_send_cmd(pcr, 100); 129 + } 130 + 131 + static int rts5227_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage) 132 + { 133 + int err; 134 + u8 drive_sel; 135 + 136 + if (voltage == OUTPUT_3V3) { 137 + err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4FC0 | 0x24); 138 + if (err < 0) 139 + return err; 140 + drive_sel = 0x96; 141 + } else if (voltage == OUTPUT_1V8) { 142 + err = rtsx_pci_write_phy_register(pcr, 0x11, 0x3C02); 143 + if (err < 0) 144 + return err; 145 + err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4C80 | 0x24); 146 + if (err < 0) 147 + return err; 148 + drive_sel = 0xB3; 149 + } else { 150 + return -EINVAL; 151 + } 152 + 153 + /* set pad drive */ 154 + rtsx_pci_init_cmd(pcr); 155 + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CLK_DRIVE_SEL, 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); 162 + } 163 + 164 + static const struct pcr_ops rts5227_pcr_ops = { 165 + .extra_init_hw = rts5227_extra_init_hw, 166 + .optimize_phy = rts5227_optimize_phy, 167 + .turn_on_led = rts5227_turn_on_led, 168 + .turn_off_led = rts5227_turn_off_led, 169 + .enable_auto_blink = rts5227_enable_auto_blink, 170 + .disable_auto_blink = rts5227_disable_auto_blink, 171 + .card_power_on = rts5227_card_power_on, 172 + .card_power_off = rts5227_card_power_off, 173 + .switch_output_voltage = rts5227_switch_output_voltage, 174 + .cd_deglitch = NULL, 175 + .conv_clk_and_div_n = NULL, 176 + }; 177 + 178 + /* SD Pull Control Enable: 179 + * SD_DAT[3:0] ==> pull up 180 + * SD_CD ==> pull up 181 + * SD_WP ==> pull up 182 + * SD_CMD ==> pull up 183 + * SD_CLK ==> pull down 184 + */ 185 + static const u32 rts5227_sd_pull_ctl_enable_tbl[] = { 186 + RTSX_REG_PAIR(CARD_PULL_CTL2, 0xAA), 187 + RTSX_REG_PAIR(CARD_PULL_CTL3, 0xE9), 188 + 0, 189 + }; 190 + 191 + /* SD Pull Control Disable: 192 + * SD_DAT[3:0] ==> pull down 193 + * SD_CD ==> pull up 194 + * SD_WP ==> pull down 195 + * SD_CMD ==> pull down 196 + * SD_CLK ==> pull down 197 + */ 198 + static const u32 rts5227_sd_pull_ctl_disable_tbl[] = { 199 + RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55), 200 + RTSX_REG_PAIR(CARD_PULL_CTL3, 0xD5), 201 + 0, 202 + }; 203 + 204 + /* MS Pull Control Enable: 205 + * MS CD ==> pull up 206 + * others ==> pull down 207 + */ 208 + static const u32 rts5227_ms_pull_ctl_enable_tbl[] = { 209 + RTSX_REG_PAIR(CARD_PULL_CTL5, 0x55), 210 + RTSX_REG_PAIR(CARD_PULL_CTL6, 0x15), 211 + 0, 212 + }; 213 + 214 + /* MS Pull Control Disable: 215 + * MS CD ==> pull up 216 + * others ==> pull down 217 + */ 218 + static const u32 rts5227_ms_pull_ctl_disable_tbl[] = { 219 + RTSX_REG_PAIR(CARD_PULL_CTL5, 0x55), 220 + RTSX_REG_PAIR(CARD_PULL_CTL6, 0x15), 221 + 0, 222 + }; 223 + 224 + void rts5227_init_params(struct rtsx_pcr *pcr) 225 + { 226 + pcr->extra_caps = EXTRA_CAPS_SD_SDR50 | EXTRA_CAPS_SD_SDR104; 227 + pcr->num_slots = 2; 228 + pcr->ops = &rts5227_pcr_ops; 229 + 230 + 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; 232 + pcr->ms_pull_ctl_enable_tbl = rts5227_ms_pull_ctl_enable_tbl; 233 + pcr->ms_pull_ctl_disable_tbl = rts5227_ms_pull_ctl_disable_tbl; 234 + }
+5
drivers/mfd/rtsx_pcr.c
··· 55 55 { PCI_DEVICE(0x10EC, 0x5209), PCI_CLASS_OTHERS << 16, 0xFF0000 }, 56 56 { PCI_DEVICE(0x10EC, 0x5229), PCI_CLASS_OTHERS << 16, 0xFF0000 }, 57 57 { PCI_DEVICE(0x10EC, 0x5289), PCI_CLASS_OTHERS << 16, 0xFF0000 }, 58 + { PCI_DEVICE(0x10EC, 0x5227), PCI_CLASS_OTHERS << 16, 0xFF0000 }, 58 59 { 0, } 59 60 }; 60 61 ··· 998 997 999 998 case 0x5289: 1000 999 rtl8411_init_params(pcr); 1000 + break; 1001 + 1002 + case 0x5227: 1003 + rts5227_init_params(pcr); 1001 1004 break; 1002 1005 } 1003 1006
+1
drivers/mfd/rtsx_pcr.h
··· 31 31 void rts5209_init_params(struct rtsx_pcr *pcr); 32 32 void rts5229_init_params(struct rtsx_pcr *pcr); 33 33 void rtl8411_init_params(struct rtsx_pcr *pcr); 34 + void rts5227_init_params(struct rtsx_pcr *pcr); 34 35 35 36 #endif
+5
include/linux/mfd/rtsx_pci.h
··· 581 581 #define CARD_GPIO_DIR 0xFD57 582 582 #define CARD_GPIO 0xFD58 583 583 #define CARD_DATA_SOURCE 0xFD5B 584 + #define SD30_CLK_DRIVE_SEL 0xFD5A 584 585 #define CARD_SELECT 0xFD5C 585 586 #define SD30_DRIVE_SEL 0xFD5E 587 + #define SD30_CMD_DRIVE_SEL 0xFD5E 588 + #define SD30_DAT_DRIVE_SEL 0xFD5F 586 589 #define CARD_CLK_EN 0xFD69 587 590 #define SDIO_CTRL 0xFD6B 588 591 #define CD_PAD_CTL 0xFD73 ··· 658 655 #define MSGTXDATA3 0xFE47 659 656 #define MSGTXCTL 0xFE48 660 657 #define PETXCFG 0xFE49 658 + #define LTR_CTL 0xFE4A 659 + #define OBFF_CFG 0xFE4C 661 660 662 661 #define CDRESUMECTL 0xFE52 663 662 #define WAKE_SEL_CTL 0xFE54