+++ /dev/null
-From 807221d3c5ff6e3c91ff57bc82a0b7a541462e20 Mon Sep 17 00:00:00 2001
-From: Ricky Wu <ricky_wu@realtek.com>
-Date: Tue, 12 Aug 2025 14:35:21 +0800
-Subject: misc: rtsx_pci: Add separate CD/WP pin polarity reversal support
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-From: Ricky Wu <ricky_wu@realtek.com>
-
-commit 807221d3c5ff6e3c91ff57bc82a0b7a541462e20 upstream.
-
-Previously, the Card Detect (CD) and Write Protect (WP) pins shared the
-same reverse polarity setting in the configuration space. This meant both
-signals were reversed together, without the ability to configure them
-individually.
-
-This patch introduces two new parameters:
-sd_cd_reverse_en – enable reverse polarity for the CD pin.
-sd_wp_reverse_en – enable reverse polarity for the WP pin.
-
-With this change, the controller can now support:
-1.Reversing both CD and WP pins together (original behavior).
-2.Reversing CD and WP pins separately (newly added behavior), if
-supported by the configuration space.
-
-This provides greater flexibility when dealing with devices that have
-independent polarity requirements for CD and WP pins.
-
-Signed-off-by: Ricky Wu <ricky_wu@realtek.com>
-Link: https://lore.kernel.org/r/20250812063521.2427696-1-ricky_wu@realtek.com
-Cc: JP Dehollain <jpdehollain@gmail.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/misc/cardreader/rts5227.c | 13 ++++++++++---
- drivers/misc/cardreader/rts5228.c | 12 ++++++++++--
- drivers/misc/cardreader/rts5249.c | 16 +++++++++++++---
- drivers/misc/cardreader/rts5264.c | 20 ++++++++++++++++----
- drivers/misc/cardreader/rts5264.h | 1 +
- drivers/misc/cardreader/rtsx_pcr.h | 2 ++
- include/linux/rtsx_pci.h | 2 ++
- 7 files changed, 54 insertions(+), 12 deletions(-)
-
---- a/drivers/misc/cardreader/rts5227.c
-+++ b/drivers/misc/cardreader/rts5227.c
-@@ -79,6 +79,10 @@ static void rts5227_fetch_vendor_setting
- pcr->sd30_drive_sel_3v3 = rtsx_reg_to_sd30_drive_sel_3v3(reg);
- if (rtsx_reg_check_reverse_socket(reg))
- pcr->flags |= PCR_REVERSE_SOCKET;
-+ if (rtsx_reg_check_cd_reverse(reg))
-+ pcr->option.sd_cd_reverse_en = 1;
-+ if (rtsx_reg_check_wp_reverse(reg))
-+ pcr->option.sd_wp_reverse_en = 1;
- }
-
- static void rts5227_init_from_cfg(struct rtsx_pcr *pcr)
-@@ -127,8 +131,10 @@ static int rts5227_extra_init_hw(struct
- /* Configure force_clock_req */
- if (pcr->flags & PCR_REVERSE_SOCKET)
- rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0x30, 0x30);
-- else
-- rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0x30, 0x00);
-+ else {
-+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0x20, option->sd_cd_reverse_en << 5);
-+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0x10, option->sd_wp_reverse_en << 4);
-+ }
-
- if (CHK_PCI_PID(pcr, 0x522A))
- rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, RTS522A_AUTOLOAD_CFG1,
-@@ -350,6 +356,8 @@ void rts5227_init_params(struct rtsx_pcr
- pcr->ms_pull_ctl_disable_tbl = rts5227_ms_pull_ctl_disable_tbl;
-
- pcr->reg_pm_ctrl3 = PM_CTRL3;
-+ pcr->option.sd_cd_reverse_en = 0;
-+ pcr->option.sd_wp_reverse_en = 0;
- }
-
- static int rts522a_optimize_phy(struct rtsx_pcr *pcr)
-@@ -508,5 +516,4 @@ void rts522a_init_params(struct rtsx_pcr
- pcr->hw_param.interrupt_en |= SD_OC_INT_EN;
- pcr->hw_param.ocp_glitch = SD_OCP_GLITCH_10M;
- pcr->option.sd_800mA_ocp_thd = RTS522A_OCP_THD_800;
--
- }
---- a/drivers/misc/cardreader/rts5228.c
-+++ b/drivers/misc/cardreader/rts5228.c
-@@ -84,6 +84,10 @@ static void rtsx5228_fetch_vendor_settin
- pcr->sd30_drive_sel_3v3 = rtsx_reg_to_sd30_drive_sel_3v3(reg);
- if (rtsx_reg_check_reverse_socket(reg))
- pcr->flags |= PCR_REVERSE_SOCKET;
-+ if (rtsx_reg_check_cd_reverse(reg))
-+ pcr->option.sd_cd_reverse_en = 1;
-+ if (rtsx_reg_check_wp_reverse(reg))
-+ pcr->option.sd_wp_reverse_en = 1;
- }
-
- static int rts5228_optimize_phy(struct rtsx_pcr *pcr)
-@@ -432,8 +436,10 @@ static int rts5228_extra_init_hw(struct
-
- if (pcr->flags & PCR_REVERSE_SOCKET)
- rtsx_pci_write_register(pcr, PETXCFG, 0x30, 0x30);
-- else
-- rtsx_pci_write_register(pcr, PETXCFG, 0x30, 0x00);
-+ else {
-+ rtsx_pci_write_register(pcr, PETXCFG, 0x20, option->sd_cd_reverse_en << 5);
-+ rtsx_pci_write_register(pcr, PETXCFG, 0x10, option->sd_wp_reverse_en << 4);
-+ }
-
- /*
- * If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced
-@@ -720,4 +726,6 @@ void rts5228_init_params(struct rtsx_pcr
- hw_param->interrupt_en |= SD_OC_INT_EN;
- hw_param->ocp_glitch = SD_OCP_GLITCH_800U;
- option->sd_800mA_ocp_thd = RTS5228_LDO1_OCP_THD_930;
-+ option->sd_cd_reverse_en = 0;
-+ option->sd_wp_reverse_en = 0;
- }
---- a/drivers/misc/cardreader/rts5249.c
-+++ b/drivers/misc/cardreader/rts5249.c
-@@ -60,6 +60,7 @@ static void rtsx_base_fetch_vendor_setti
-
- pci_read_config_dword(pdev, PCR_SETTING_REG1, ®);
- pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
-+ pci_write_config_dword(pdev, 0x718, 0x0007C000);
-
- if (!rtsx_vendor_setting_valid(reg)) {
- pcr_dbg(pcr, "skip fetch vendor setting\n");
-@@ -82,6 +83,10 @@ static void rtsx_base_fetch_vendor_setti
- pcr->sd30_drive_sel_3v3 = rtsx_reg_to_sd30_drive_sel_3v3(reg);
- if (rtsx_reg_check_reverse_socket(reg))
- pcr->flags |= PCR_REVERSE_SOCKET;
-+ if (rtsx_reg_check_cd_reverse(reg))
-+ pcr->option.sd_cd_reverse_en = 1;
-+ if (rtsx_reg_check_wp_reverse(reg))
-+ pcr->option.sd_wp_reverse_en = 1;
- }
-
- static void rts5249_init_from_cfg(struct rtsx_pcr *pcr)
-@@ -254,9 +259,11 @@ static int rts5249_extra_init_hw(struct
- /* Configure driving */
- rts5249_fill_driving(pcr, OUTPUT_3V3);
- if (pcr->flags & PCR_REVERSE_SOCKET)
-- rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB0, 0xB0);
-- else
-- rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB0, 0x80);
-+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0x30, 0x30);
-+ else {
-+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0x20, option->sd_cd_reverse_en << 5);
-+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0x10, option->sd_wp_reverse_en << 4);
-+ }
-
- rtsx_pci_send_cmd(pcr, CMD_TIMEOUT_DEF);
-
-@@ -572,6 +579,9 @@ void rts5249_init_params(struct rtsx_pcr
- option->ltr_l1off_sspwrgate = LTR_L1OFF_SSPWRGATE_5249_DEF;
- option->ltr_l1off_snooze_sspwrgate =
- LTR_L1OFF_SNOOZE_SSPWRGATE_5249_DEF;
-+
-+ option->sd_cd_reverse_en = 0;
-+ option->sd_wp_reverse_en = 0;
- }
-
- static int rts524a_write_phy(struct rtsx_pcr *pcr, u8 addr, u16 val)
---- a/drivers/misc/cardreader/rts5264.c
-+++ b/drivers/misc/cardreader/rts5264.c
-@@ -473,8 +473,16 @@ static void rts5264_init_from_hw(struct
-
- pcr->rtd3_en = rts5264_reg_to_rtd3(lval2);
-
-- if (rts5264_reg_check_reverse_socket(lval2))
-- pcr->flags |= PCR_REVERSE_SOCKET;
-+ if (rts5264_reg_check_reverse_socket(lval2)) {
-+ if (is_version_higher_than(pcr, PID_5264, RTS5264_IC_VER_B))
-+ pcr->option.sd_cd_reverse_en = 1;
-+ else
-+ pcr->flags |= PCR_REVERSE_SOCKET;
-+ }
-+
-+ if (rts5264_reg_check_wp_reverse(lval2) &&
-+ is_version_higher_than(pcr, PID_5264, RTS5264_IC_VER_B))
-+ pcr->option.sd_wp_reverse_en = 1;
-
- pci_read_config_dword(pdev, setting_reg1, &lval1);
- pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", setting_reg1, lval1);
-@@ -568,8 +576,10 @@ static int rts5264_extra_init_hw(struct
-
- if (pcr->flags & PCR_REVERSE_SOCKET)
- rtsx_pci_write_register(pcr, PETXCFG, 0x30, 0x30);
-- else
-- rtsx_pci_write_register(pcr, PETXCFG, 0x30, 0x00);
-+ else {
-+ rtsx_pci_write_register(pcr, PETXCFG, 0x20, option->sd_cd_reverse_en << 5);
-+ rtsx_pci_write_register(pcr, PETXCFG, 0x10, option->sd_wp_reverse_en << 4);
-+ }
-
- /*
- * If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced
-@@ -883,4 +893,6 @@ void rts5264_init_params(struct rtsx_pcr
- hw_param->interrupt_en |= (SD_OC_INT_EN | SD_OVP_INT_EN);
- hw_param->ocp_glitch = SD_OCP_GLITCH_800U | SDVIO_OCP_GLITCH_800U;
- option->sd_800mA_ocp_thd = RTS5264_LDO1_OCP_THD_1150;
-+ option->sd_cd_reverse_en = 0;
-+ option->sd_wp_reverse_en = 0;
- }
---- a/drivers/misc/cardreader/rts5264.h
-+++ b/drivers/misc/cardreader/rts5264.h
-@@ -14,6 +14,7 @@
- #define rts5264_reg_to_aspm(reg) \
- (((~(reg) >> 28) & 0x02) | (((reg) >> 28) & 0x01))
- #define rts5264_reg_check_reverse_socket(reg) ((reg) & 0x04)
-+#define rts5264_reg_check_wp_reverse(reg) ((reg) & 0x8000)
- #define rts5264_reg_to_sd30_drive_sel_1v8(reg) (((reg) >> 22) & 0x03)
- #define rts5264_reg_to_sd30_drive_sel_3v3(reg) (((reg) >> 16) & 0x03)
- #define rts5264_reg_to_rtd3(reg) ((reg) & 0x08)
---- a/drivers/misc/cardreader/rtsx_pcr.h
-+++ b/drivers/misc/cardreader/rtsx_pcr.h
-@@ -100,6 +100,8 @@ static inline u8 map_sd_drive(int idx)
- #define rtsx_reg_to_sd30_drive_sel_3v3(reg) (((reg) >> 5) & 0x03)
- #define rtsx_reg_to_card_drive_sel(reg) ((((reg) >> 25) & 0x01) << 6)
- #define rtsx_reg_check_reverse_socket(reg) ((reg) & 0x4000)
-+#define rtsx_reg_check_cd_reverse(reg) ((reg) & 0x800000)
-+#define rtsx_reg_check_wp_reverse(reg) ((reg) & 0x400000)
- #define rts5209_reg_to_aspm(reg) (((reg) >> 5) & 0x03)
- #define rts5209_reg_check_ms_pmos(reg) (!((reg) & 0x08))
- #define rts5209_reg_to_sd30_drive_sel_1v8(reg) (((reg) >> 3) & 0x07)
---- a/include/linux/rtsx_pci.h
-+++ b/include/linux/rtsx_pci.h
-@@ -1160,6 +1160,8 @@ struct rtsx_cr_option {
- bool ocp_en;
- u8 sd_400mA_ocp_thd;
- u8 sd_800mA_ocp_thd;
-+ u8 sd_cd_reverse_en;
-+ u8 sd_wp_reverse_en;
- };
-
- /*