root/drivers/misc/cardreader/rts5227.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. rts5227_get_ic_version
  2. rts5227_fill_driving
  3. rts5227_fetch_vendor_settings
  4. rts5227_force_power_down
  5. rts5227_extra_init_hw
  6. rts5227_optimize_phy
  7. rts5227_turn_on_led
  8. rts5227_turn_off_led
  9. rts5227_enable_auto_blink
  10. rts5227_disable_auto_blink
  11. rts5227_card_power_on
  12. rts5227_card_power_off
  13. rts5227_switch_output_voltage
  14. rts5227_init_params
  15. rts522a_optimize_phy
  16. rts522a_extra_init_hw
  17. rts522a_switch_output_voltage
  18. rts522a_init_params

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /* Driver for Realtek PCI-Express card reader
   3  *
   4  * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
   5  *
   6  * Author:
   7  *   Wei WANG <wei_wang@realsil.com.cn>
   8  *   Roger Tseng <rogerable@realtek.com>
   9  */
  10 
  11 #include <linux/module.h>
  12 #include <linux/delay.h>
  13 #include <linux/rtsx_pci.h>
  14 
  15 #include "rtsx_pcr.h"
  16 
  17 static u8 rts5227_get_ic_version(struct rtsx_pcr *pcr)
  18 {
  19         u8 val;
  20 
  21         rtsx_pci_read_register(pcr, DUMMY_REG_RESET_0, &val);
  22         return val & 0x0F;
  23 }
  24 
  25 static void rts5227_fill_driving(struct rtsx_pcr *pcr, u8 voltage)
  26 {
  27         u8 driving_3v3[4][3] = {
  28                 {0x13, 0x13, 0x13},
  29                 {0x96, 0x96, 0x96},
  30                 {0x7F, 0x7F, 0x7F},
  31                 {0x96, 0x96, 0x96},
  32         };
  33         u8 driving_1v8[4][3] = {
  34                 {0x99, 0x99, 0x99},
  35                 {0xAA, 0xAA, 0xAA},
  36                 {0xFE, 0xFE, 0xFE},
  37                 {0xB3, 0xB3, 0xB3},
  38         };
  39         u8 (*driving)[3], drive_sel;
  40 
  41         if (voltage == OUTPUT_3V3) {
  42                 driving = driving_3v3;
  43                 drive_sel = pcr->sd30_drive_sel_3v3;
  44         } else {
  45                 driving = driving_1v8;
  46                 drive_sel = pcr->sd30_drive_sel_1v8;
  47         }
  48 
  49         rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CLK_DRIVE_SEL,
  50                         0xFF, driving[drive_sel][0]);
  51         rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CMD_DRIVE_SEL,
  52                         0xFF, driving[drive_sel][1]);
  53         rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DAT_DRIVE_SEL,
  54                         0xFF, driving[drive_sel][2]);
  55 }
  56 
  57 static void rts5227_fetch_vendor_settings(struct rtsx_pcr *pcr)
  58 {
  59         u32 reg;
  60 
  61         rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, &reg);
  62         pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
  63 
  64         if (!rtsx_vendor_setting_valid(reg))
  65                 return;
  66 
  67         pcr->aspm_en = rtsx_reg_to_aspm(reg);
  68         pcr->sd30_drive_sel_1v8 = rtsx_reg_to_sd30_drive_sel_1v8(reg);
  69         pcr->card_drive_sel &= 0x3F;
  70         pcr->card_drive_sel |= rtsx_reg_to_card_drive_sel(reg);
  71 
  72         rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG2, &reg);
  73         pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg);
  74         pcr->sd30_drive_sel_3v3 = rtsx_reg_to_sd30_drive_sel_3v3(reg);
  75         if (rtsx_reg_check_reverse_socket(reg))
  76                 pcr->flags |= PCR_REVERSE_SOCKET;
  77 }
  78 
  79 static void rts5227_force_power_down(struct rtsx_pcr *pcr, u8 pm_state)
  80 {
  81         /* Set relink_time to 0 */
  82         rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 1, 0xFF, 0);
  83         rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 2, 0xFF, 0);
  84         rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 3, 0x01, 0);
  85 
  86         if (pm_state == HOST_ENTER_S3)
  87                 rtsx_pci_write_register(pcr, pcr->reg_pm_ctrl3, 0x10, 0x10);
  88 
  89         rtsx_pci_write_register(pcr, FPDCTL, 0x03, 0x03);
  90 }
  91 
  92 static int rts5227_extra_init_hw(struct rtsx_pcr *pcr)
  93 {
  94         u16 cap;
  95 
  96         rtsx_pci_init_cmd(pcr);
  97 
  98         /* Configure GPIO as output */
  99         rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, GPIO_CTL, 0x02, 0x02);
 100         /* Reset ASPM state to default value */
 101         rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, ASPM_FORCE_CTL, 0x3F, 0);
 102         /* Switch LDO3318 source from DV33 to card_3v3 */
 103         rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x00);
 104         rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x01);
 105         /* LED shine disabled, set initial shine cycle period */
 106         rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, OLT_LED_CTL, 0x0F, 0x02);
 107         /* Configure LTR */
 108         pcie_capability_read_word(pcr->pci, PCI_EXP_DEVCTL2, &cap);
 109         if (cap & PCI_EXP_DEVCTL2_LTR_EN)
 110                 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LTR_CTL, 0xFF, 0xA3);
 111         /* Configure OBFF */
 112         rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, OBFF_CFG, 0x03, 0x03);
 113         /* Configure driving */
 114         rts5227_fill_driving(pcr, OUTPUT_3V3);
 115         /* Configure force_clock_req */
 116         if (pcr->flags & PCR_REVERSE_SOCKET)
 117                 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB8, 0xB8);
 118         else
 119                 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB8, 0x88);
 120         rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, pcr->reg_pm_ctrl3, 0x10, 0x00);
 121 
 122         return rtsx_pci_send_cmd(pcr, 100);
 123 }
 124 
 125 static int rts5227_optimize_phy(struct rtsx_pcr *pcr)
 126 {
 127         int err;
 128 
 129         err = rtsx_pci_write_register(pcr, PM_CTRL3, D3_DELINK_MODE_EN, 0x00);
 130         if (err < 0)
 131                 return err;
 132 
 133         /* Optimize RX sensitivity */
 134         return rtsx_pci_write_phy_register(pcr, 0x00, 0xBA42);
 135 }
 136 
 137 static int rts5227_turn_on_led(struct rtsx_pcr *pcr)
 138 {
 139         return rtsx_pci_write_register(pcr, GPIO_CTL, 0x02, 0x02);
 140 }
 141 
 142 static int rts5227_turn_off_led(struct rtsx_pcr *pcr)
 143 {
 144         return rtsx_pci_write_register(pcr, GPIO_CTL, 0x02, 0x00);
 145 }
 146 
 147 static int rts5227_enable_auto_blink(struct rtsx_pcr *pcr)
 148 {
 149         return rtsx_pci_write_register(pcr, OLT_LED_CTL, 0x08, 0x08);
 150 }
 151 
 152 static int rts5227_disable_auto_blink(struct rtsx_pcr *pcr)
 153 {
 154         return rtsx_pci_write_register(pcr, OLT_LED_CTL, 0x08, 0x00);
 155 }
 156 
 157 static int rts5227_card_power_on(struct rtsx_pcr *pcr, int card)
 158 {
 159         int err;
 160 
 161         if (pcr->option.ocp_en)
 162                 rtsx_pci_enable_ocp(pcr);
 163 
 164         rtsx_pci_init_cmd(pcr);
 165         rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
 166                         SD_POWER_MASK, SD_PARTIAL_POWER_ON);
 167 
 168         rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
 169                         LDO3318_PWR_MASK, 0x02);
 170 
 171         err = rtsx_pci_send_cmd(pcr, 100);
 172         if (err < 0)
 173                 return err;
 174 
 175         /* To avoid too large in-rush current */
 176         msleep(20);
 177         rtsx_pci_init_cmd(pcr);
 178         rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
 179                         SD_POWER_MASK, SD_POWER_ON);
 180 
 181         rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
 182                         LDO3318_PWR_MASK, 0x06);
 183 
 184         rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_OE,
 185                         SD_OUTPUT_EN, SD_OUTPUT_EN);
 186         rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_OE,
 187                         MS_OUTPUT_EN, MS_OUTPUT_EN);
 188         return rtsx_pci_send_cmd(pcr, 100);
 189 }
 190 
 191 static int rts5227_card_power_off(struct rtsx_pcr *pcr, int card)
 192 {
 193         if (pcr->option.ocp_en)
 194                 rtsx_pci_disable_ocp(pcr);
 195 
 196         rtsx_pci_write_register(pcr, CARD_PWR_CTL, SD_POWER_MASK |
 197                         PMOS_STRG_MASK, SD_POWER_OFF | PMOS_STRG_400mA);
 198         rtsx_pci_write_register(pcr, PWR_GATE_CTRL, LDO3318_PWR_MASK, 0X00);
 199 
 200         return 0;
 201 }
 202 
 203 static int rts5227_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
 204 {
 205         int err;
 206 
 207         if (voltage == OUTPUT_3V3) {
 208                 err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4FC0 | 0x24);
 209                 if (err < 0)
 210                         return err;
 211         } else if (voltage == OUTPUT_1V8) {
 212                 err = rtsx_pci_write_phy_register(pcr, 0x11, 0x3C02);
 213                 if (err < 0)
 214                         return err;
 215                 err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4C80 | 0x24);
 216                 if (err < 0)
 217                         return err;
 218         } else {
 219                 return -EINVAL;
 220         }
 221 
 222         /* set pad drive */
 223         rtsx_pci_init_cmd(pcr);
 224         rts5227_fill_driving(pcr, voltage);
 225         return rtsx_pci_send_cmd(pcr, 100);
 226 }
 227 
 228 static const struct pcr_ops rts5227_pcr_ops = {
 229         .fetch_vendor_settings = rts5227_fetch_vendor_settings,
 230         .extra_init_hw = rts5227_extra_init_hw,
 231         .optimize_phy = rts5227_optimize_phy,
 232         .turn_on_led = rts5227_turn_on_led,
 233         .turn_off_led = rts5227_turn_off_led,
 234         .enable_auto_blink = rts5227_enable_auto_blink,
 235         .disable_auto_blink = rts5227_disable_auto_blink,
 236         .card_power_on = rts5227_card_power_on,
 237         .card_power_off = rts5227_card_power_off,
 238         .switch_output_voltage = rts5227_switch_output_voltage,
 239         .cd_deglitch = NULL,
 240         .conv_clk_and_div_n = NULL,
 241         .force_power_down = rts5227_force_power_down,
 242 };
 243 
 244 /* SD Pull Control Enable:
 245  *     SD_DAT[3:0] ==> pull up
 246  *     SD_CD       ==> pull up
 247  *     SD_WP       ==> pull up
 248  *     SD_CMD      ==> pull up
 249  *     SD_CLK      ==> pull down
 250  */
 251 static const u32 rts5227_sd_pull_ctl_enable_tbl[] = {
 252         RTSX_REG_PAIR(CARD_PULL_CTL2, 0xAA),
 253         RTSX_REG_PAIR(CARD_PULL_CTL3, 0xE9),
 254         0,
 255 };
 256 
 257 /* SD Pull Control Disable:
 258  *     SD_DAT[3:0] ==> pull down
 259  *     SD_CD       ==> pull up
 260  *     SD_WP       ==> pull down
 261  *     SD_CMD      ==> pull down
 262  *     SD_CLK      ==> pull down
 263  */
 264 static const u32 rts5227_sd_pull_ctl_disable_tbl[] = {
 265         RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
 266         RTSX_REG_PAIR(CARD_PULL_CTL3, 0xD5),
 267         0,
 268 };
 269 
 270 /* MS Pull Control Enable:
 271  *     MS CD       ==> pull up
 272  *     others      ==> pull down
 273  */
 274 static const u32 rts5227_ms_pull_ctl_enable_tbl[] = {
 275         RTSX_REG_PAIR(CARD_PULL_CTL5, 0x55),
 276         RTSX_REG_PAIR(CARD_PULL_CTL6, 0x15),
 277         0,
 278 };
 279 
 280 /* MS Pull Control Disable:
 281  *     MS CD       ==> pull up
 282  *     others      ==> pull down
 283  */
 284 static const u32 rts5227_ms_pull_ctl_disable_tbl[] = {
 285         RTSX_REG_PAIR(CARD_PULL_CTL5, 0x55),
 286         RTSX_REG_PAIR(CARD_PULL_CTL6, 0x15),
 287         0,
 288 };
 289 
 290 void rts5227_init_params(struct rtsx_pcr *pcr)
 291 {
 292         pcr->extra_caps = EXTRA_CAPS_SD_SDR50 | EXTRA_CAPS_SD_SDR104;
 293         pcr->num_slots = 2;
 294         pcr->ops = &rts5227_pcr_ops;
 295 
 296         pcr->flags = 0;
 297         pcr->card_drive_sel = RTSX_CARD_DRIVE_DEFAULT;
 298         pcr->sd30_drive_sel_1v8 = CFG_DRIVER_TYPE_B;
 299         pcr->sd30_drive_sel_3v3 = CFG_DRIVER_TYPE_B;
 300         pcr->aspm_en = ASPM_L1_EN;
 301         pcr->tx_initial_phase = SET_CLOCK_PHASE(27, 27, 15);
 302         pcr->rx_initial_phase = SET_CLOCK_PHASE(30, 7, 7);
 303 
 304         pcr->ic_version = rts5227_get_ic_version(pcr);
 305         pcr->sd_pull_ctl_enable_tbl = rts5227_sd_pull_ctl_enable_tbl;
 306         pcr->sd_pull_ctl_disable_tbl = rts5227_sd_pull_ctl_disable_tbl;
 307         pcr->ms_pull_ctl_enable_tbl = rts5227_ms_pull_ctl_enable_tbl;
 308         pcr->ms_pull_ctl_disable_tbl = rts5227_ms_pull_ctl_disable_tbl;
 309 
 310         pcr->reg_pm_ctrl3 = PM_CTRL3;
 311 }
 312 
 313 static int rts522a_optimize_phy(struct rtsx_pcr *pcr)
 314 {
 315         int err;
 316 
 317         err = rtsx_pci_write_register(pcr, RTS522A_PM_CTRL3, D3_DELINK_MODE_EN,
 318                 0x00);
 319         if (err < 0)
 320                 return err;
 321 
 322         if (is_version(pcr, 0x522A, IC_VER_A)) {
 323                 err = rtsx_pci_write_phy_register(pcr, PHY_RCR2,
 324                         PHY_RCR2_INIT_27S);
 325                 if (err)
 326                         return err;
 327 
 328                 rtsx_pci_write_phy_register(pcr, PHY_RCR1, PHY_RCR1_INIT_27S);
 329                 rtsx_pci_write_phy_register(pcr, PHY_FLD0, PHY_FLD0_INIT_27S);
 330                 rtsx_pci_write_phy_register(pcr, PHY_FLD3, PHY_FLD3_INIT_27S);
 331                 rtsx_pci_write_phy_register(pcr, PHY_FLD4, PHY_FLD4_INIT_27S);
 332         }
 333 
 334         return 0;
 335 }
 336 
 337 static int rts522a_extra_init_hw(struct rtsx_pcr *pcr)
 338 {
 339         rts5227_extra_init_hw(pcr);
 340 
 341         rtsx_pci_write_register(pcr, FUNC_FORCE_CTL, FUNC_FORCE_UPME_XMT_DBG,
 342                 FUNC_FORCE_UPME_XMT_DBG);
 343         rtsx_pci_write_register(pcr, PCLK_CTL, 0x04, 0x04);
 344         rtsx_pci_write_register(pcr, PM_EVENT_DEBUG, PME_DEBUG_0, PME_DEBUG_0);
 345         rtsx_pci_write_register(pcr, PM_CLK_FORCE_CTL, 0xFF, 0x11);
 346 
 347         return 0;
 348 }
 349 
 350 static int rts522a_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
 351 {
 352         int err;
 353 
 354         if (voltage == OUTPUT_3V3) {
 355                 err = rtsx_pci_write_phy_register(pcr, 0x08, 0x57E4);
 356                 if (err < 0)
 357                         return err;
 358         } else if (voltage == OUTPUT_1V8) {
 359                 err = rtsx_pci_write_phy_register(pcr, 0x11, 0x3C02);
 360                 if (err < 0)
 361                         return err;
 362                 err = rtsx_pci_write_phy_register(pcr, 0x08, 0x54A4);
 363                 if (err < 0)
 364                         return err;
 365         } else {
 366                 return -EINVAL;
 367         }
 368 
 369         /* set pad drive */
 370         rtsx_pci_init_cmd(pcr);
 371         rts5227_fill_driving(pcr, voltage);
 372         return rtsx_pci_send_cmd(pcr, 100);
 373 }
 374 
 375 
 376 /* rts522a operations mainly derived from rts5227, except phy/hw init setting.
 377  */
 378 static const struct pcr_ops rts522a_pcr_ops = {
 379         .fetch_vendor_settings = rts5227_fetch_vendor_settings,
 380         .extra_init_hw = rts522a_extra_init_hw,
 381         .optimize_phy = rts522a_optimize_phy,
 382         .turn_on_led = rts5227_turn_on_led,
 383         .turn_off_led = rts5227_turn_off_led,
 384         .enable_auto_blink = rts5227_enable_auto_blink,
 385         .disable_auto_blink = rts5227_disable_auto_blink,
 386         .card_power_on = rts5227_card_power_on,
 387         .card_power_off = rts5227_card_power_off,
 388         .switch_output_voltage = rts522a_switch_output_voltage,
 389         .cd_deglitch = NULL,
 390         .conv_clk_and_div_n = NULL,
 391         .force_power_down = rts5227_force_power_down,
 392 };
 393 
 394 void rts522a_init_params(struct rtsx_pcr *pcr)
 395 {
 396         rts5227_init_params(pcr);
 397         pcr->ops = &rts522a_pcr_ops;
 398         pcr->tx_initial_phase = SET_CLOCK_PHASE(20, 20, 11);
 399         pcr->reg_pm_ctrl3 = RTS522A_PM_CTRL3;
 400 
 401         pcr->option.ocp_en = 1;
 402         if (pcr->option.ocp_en)
 403                 pcr->hw_param.interrupt_en |= SD_OC_INT_EN;
 404         pcr->hw_param.ocp_glitch = SD_OCP_GLITCH_10M;
 405         pcr->option.sd_800mA_ocp_thd = RTS522A_OCP_THD_800;
 406 
 407 }

/* [<][>][^][v][top][bottom][index][help] */