Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /* Driver for Realtek PCI-Express card reader
0003  *
0004  * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
0005  *
0006  * Author:
0007  *   Wei WANG <wei_wang@realsil.com.cn>
0008  */
0009 
0010 #include <linux/module.h>
0011 #include <linux/delay.h>
0012 #include <linux/rtsx_pci.h>
0013 
0014 #include "rtsx_pcr.h"
0015 
0016 static u8 rts5229_get_ic_version(struct rtsx_pcr *pcr)
0017 {
0018     u8 val;
0019 
0020     rtsx_pci_read_register(pcr, DUMMY_REG_RESET_0, &val);
0021     return val & 0x0F;
0022 }
0023 
0024 static void rts5229_fetch_vendor_settings(struct rtsx_pcr *pcr)
0025 {
0026     struct pci_dev *pdev = pcr->pci;
0027     u32 reg;
0028 
0029     pci_read_config_dword(pdev, PCR_SETTING_REG1, &reg);
0030     pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
0031 
0032     if (!rtsx_vendor_setting_valid(reg))
0033         return;
0034 
0035     pcr->aspm_en = rtsx_reg_to_aspm(reg);
0036     pcr->sd30_drive_sel_1v8 =
0037         map_sd_drive(rtsx_reg_to_sd30_drive_sel_1v8(reg));
0038     pcr->card_drive_sel &= 0x3F;
0039     pcr->card_drive_sel |= rtsx_reg_to_card_drive_sel(reg);
0040 
0041     pci_read_config_dword(pdev, PCR_SETTING_REG2, &reg);
0042     pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg);
0043     pcr->sd30_drive_sel_3v3 =
0044         map_sd_drive(rtsx_reg_to_sd30_drive_sel_3v3(reg));
0045 }
0046 
0047 static void rts5229_force_power_down(struct rtsx_pcr *pcr, u8 pm_state, bool runtime)
0048 {
0049     rtsx_pci_write_register(pcr, FPDCTL, 0x03, 0x03);
0050 }
0051 
0052 static int rts5229_extra_init_hw(struct rtsx_pcr *pcr)
0053 {
0054     rtsx_pci_init_cmd(pcr);
0055 
0056     /* Configure GPIO as output */
0057     rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, GPIO_CTL, 0x02, 0x02);
0058     /* Reset ASPM state to default value */
0059     rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, ASPM_FORCE_CTL, 0x3F, 0);
0060     /* Force CLKREQ# PIN to drive 0 to request clock */
0061     rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0x08, 0x08);
0062     /* Switch LDO3318 source from DV33 to card_3v3 */
0063     rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x00);
0064     rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x01);
0065     /* LED shine disabled, set initial shine cycle period */
0066     rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, OLT_LED_CTL, 0x0F, 0x02);
0067     /* Configure driving */
0068     rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DRIVE_SEL,
0069             0xFF, pcr->sd30_drive_sel_3v3);
0070 
0071     return rtsx_pci_send_cmd(pcr, 100);
0072 }
0073 
0074 static int rts5229_optimize_phy(struct rtsx_pcr *pcr)
0075 {
0076     /* Optimize RX sensitivity */
0077     return rtsx_pci_write_phy_register(pcr, 0x00, 0xBA42);
0078 }
0079 
0080 static int rts5229_turn_on_led(struct rtsx_pcr *pcr)
0081 {
0082     return rtsx_pci_write_register(pcr, GPIO_CTL, 0x02, 0x02);
0083 }
0084 
0085 static int rts5229_turn_off_led(struct rtsx_pcr *pcr)
0086 {
0087     return rtsx_pci_write_register(pcr, GPIO_CTL, 0x02, 0x00);
0088 }
0089 
0090 static int rts5229_enable_auto_blink(struct rtsx_pcr *pcr)
0091 {
0092     return rtsx_pci_write_register(pcr, OLT_LED_CTL, 0x08, 0x08);
0093 }
0094 
0095 static int rts5229_disable_auto_blink(struct rtsx_pcr *pcr)
0096 {
0097     return rtsx_pci_write_register(pcr, OLT_LED_CTL, 0x08, 0x00);
0098 }
0099 
0100 static int rts5229_card_power_on(struct rtsx_pcr *pcr, int card)
0101 {
0102     int err;
0103 
0104     rtsx_pci_init_cmd(pcr);
0105     rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
0106             SD_POWER_MASK, SD_PARTIAL_POWER_ON);
0107     rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
0108             LDO3318_PWR_MASK, 0x02);
0109     err = rtsx_pci_send_cmd(pcr, 100);
0110     if (err < 0)
0111         return err;
0112 
0113     /* To avoid too large in-rush current */
0114     udelay(150);
0115 
0116     rtsx_pci_init_cmd(pcr);
0117     rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
0118             SD_POWER_MASK, SD_POWER_ON);
0119     rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
0120             LDO3318_PWR_MASK, 0x06);
0121     return rtsx_pci_send_cmd(pcr, 100);
0122 }
0123 
0124 static int rts5229_card_power_off(struct rtsx_pcr *pcr, int card)
0125 {
0126     rtsx_pci_init_cmd(pcr);
0127     rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
0128             SD_POWER_MASK | PMOS_STRG_MASK,
0129             SD_POWER_OFF | PMOS_STRG_400mA);
0130     rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
0131             LDO3318_PWR_MASK, 0x00);
0132     return rtsx_pci_send_cmd(pcr, 100);
0133 }
0134 
0135 static int rts5229_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
0136 {
0137     int err;
0138 
0139     if (voltage == OUTPUT_3V3) {
0140         err = rtsx_pci_write_register(pcr,
0141                 SD30_DRIVE_SEL, 0x07, pcr->sd30_drive_sel_3v3);
0142         if (err < 0)
0143             return err;
0144         err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4FC0 | 0x24);
0145         if (err < 0)
0146             return err;
0147     } else if (voltage == OUTPUT_1V8) {
0148         err = rtsx_pci_write_register(pcr,
0149                 SD30_DRIVE_SEL, 0x07, pcr->sd30_drive_sel_1v8);
0150         if (err < 0)
0151             return err;
0152         err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4C40 | 0x24);
0153         if (err < 0)
0154             return err;
0155     } else {
0156         return -EINVAL;
0157     }
0158 
0159     return 0;
0160 }
0161 
0162 static const struct pcr_ops rts5229_pcr_ops = {
0163     .fetch_vendor_settings = rts5229_fetch_vendor_settings,
0164     .extra_init_hw = rts5229_extra_init_hw,
0165     .optimize_phy = rts5229_optimize_phy,
0166     .turn_on_led = rts5229_turn_on_led,
0167     .turn_off_led = rts5229_turn_off_led,
0168     .enable_auto_blink = rts5229_enable_auto_blink,
0169     .disable_auto_blink = rts5229_disable_auto_blink,
0170     .card_power_on = rts5229_card_power_on,
0171     .card_power_off = rts5229_card_power_off,
0172     .switch_output_voltage = rts5229_switch_output_voltage,
0173     .cd_deglitch = NULL,
0174     .conv_clk_and_div_n = NULL,
0175     .force_power_down = rts5229_force_power_down,
0176 };
0177 
0178 /* SD Pull Control Enable:
0179  *     SD_DAT[3:0] ==> pull up
0180  *     SD_CD       ==> pull up
0181  *     SD_WP       ==> pull up
0182  *     SD_CMD      ==> pull up
0183  *     SD_CLK      ==> pull down
0184  */
0185 static const u32 rts5229_sd_pull_ctl_enable_tbl1[] = {
0186     RTSX_REG_PAIR(CARD_PULL_CTL2, 0xAA),
0187     RTSX_REG_PAIR(CARD_PULL_CTL3, 0xE9),
0188     0,
0189 };
0190 
0191 /* For RTS5229 version C */
0192 static const u32 rts5229_sd_pull_ctl_enable_tbl2[] = {
0193     RTSX_REG_PAIR(CARD_PULL_CTL2, 0xAA),
0194     RTSX_REG_PAIR(CARD_PULL_CTL3, 0xD9),
0195     0,
0196 };
0197 
0198 /* SD Pull Control Disable:
0199  *     SD_DAT[3:0] ==> pull down
0200  *     SD_CD       ==> pull up
0201  *     SD_WP       ==> pull down
0202  *     SD_CMD      ==> pull down
0203  *     SD_CLK      ==> pull down
0204  */
0205 static const u32 rts5229_sd_pull_ctl_disable_tbl1[] = {
0206     RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
0207     RTSX_REG_PAIR(CARD_PULL_CTL3, 0xD5),
0208     0,
0209 };
0210 
0211 /* For RTS5229 version C */
0212 static const u32 rts5229_sd_pull_ctl_disable_tbl2[] = {
0213     RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
0214     RTSX_REG_PAIR(CARD_PULL_CTL3, 0xE5),
0215     0,
0216 };
0217 
0218 /* MS Pull Control Enable:
0219  *     MS CD       ==> pull up
0220  *     others      ==> pull down
0221  */
0222 static const u32 rts5229_ms_pull_ctl_enable_tbl[] = {
0223     RTSX_REG_PAIR(CARD_PULL_CTL5, 0x55),
0224     RTSX_REG_PAIR(CARD_PULL_CTL6, 0x15),
0225     0,
0226 };
0227 
0228 /* MS Pull Control Disable:
0229  *     MS CD       ==> pull up
0230  *     others      ==> pull down
0231  */
0232 static const u32 rts5229_ms_pull_ctl_disable_tbl[] = {
0233     RTSX_REG_PAIR(CARD_PULL_CTL5, 0x55),
0234     RTSX_REG_PAIR(CARD_PULL_CTL6, 0x15),
0235     0,
0236 };
0237 
0238 void rts5229_init_params(struct rtsx_pcr *pcr)
0239 {
0240     pcr->extra_caps = EXTRA_CAPS_SD_SDR50 | EXTRA_CAPS_SD_SDR104;
0241     pcr->num_slots = 2;
0242     pcr->ops = &rts5229_pcr_ops;
0243 
0244     pcr->flags = 0;
0245     pcr->card_drive_sel = RTSX_CARD_DRIVE_DEFAULT;
0246     pcr->sd30_drive_sel_1v8 = DRIVER_TYPE_B;
0247     pcr->sd30_drive_sel_3v3 = DRIVER_TYPE_D;
0248     pcr->aspm_en = ASPM_L1_EN;
0249     pcr->aspm_mode = ASPM_MODE_CFG;
0250     pcr->tx_initial_phase = SET_CLOCK_PHASE(27, 27, 15);
0251     pcr->rx_initial_phase = SET_CLOCK_PHASE(30, 6, 6);
0252 
0253     pcr->ic_version = rts5229_get_ic_version(pcr);
0254     if (pcr->ic_version == IC_VER_C) {
0255         pcr->sd_pull_ctl_enable_tbl = rts5229_sd_pull_ctl_enable_tbl2;
0256         pcr->sd_pull_ctl_disable_tbl = rts5229_sd_pull_ctl_disable_tbl2;
0257     } else {
0258         pcr->sd_pull_ctl_enable_tbl = rts5229_sd_pull_ctl_enable_tbl1;
0259         pcr->sd_pull_ctl_disable_tbl = rts5229_sd_pull_ctl_disable_tbl1;
0260     }
0261     pcr->ms_pull_ctl_enable_tbl = rts5229_ms_pull_ctl_enable_tbl;
0262     pcr->ms_pull_ctl_disable_tbl = rts5229_ms_pull_ctl_disable_tbl;
0263 }