From: RickyWu <[email protected]>
this enables and adds OCP function for Realtek A series cardreader chips
and fixes some OCP flow in rts5260.c
Signed-off-by: RickyWu <[email protected]>
---
drivers/misc/cardreader/rts5227.c | 58 ++++++++++--
drivers/misc/cardreader/rts5249.c | 29 ++++--
drivers/misc/cardreader/rts5260.c | 136 ++++++++++-------------------
drivers/misc/cardreader/rtsx_pcr.c | 38 ++++++--
drivers/misc/cardreader/rtsx_pcr.h | 5 ++
5 files changed, 154 insertions(+), 112 deletions(-)
diff --git a/drivers/misc/cardreader/rts5227.c b/drivers/misc/cardreader/rts5227.c
index 024dcba8d6c8..95394c6ca5c7 100644
--- a/drivers/misc/cardreader/rts5227.c
+++ b/drivers/misc/cardreader/rts5227.c
@@ -170,6 +170,9 @@ static int rts5227_card_power_on(struct rtsx_pcr *pcr, int card)
{
int err;
+ if (pcr->option.ocp_en)
+ rtsx_pci_enable_ocp(pcr);
+
rtsx_pci_init_cmd(pcr);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
SD_POWER_MASK, SD_PARTIAL_POWER_ON);
@@ -180,25 +183,30 @@ static int rts5227_card_power_on(struct rtsx_pcr *pcr, int card)
return err;
/* To avoid too large in-rush current */
- udelay(150);
+ msleep(20);
rtsx_pci_init_cmd(pcr);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
SD_POWER_MASK, SD_POWER_ON);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
LDO3318_PWR_MASK, 0x06);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_OE,
+ SD_OUTPUT_EN, SD_OUTPUT_EN);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_OE,
+ MS_OUTPUT_EN, MS_OUTPUT_EN);
return rtsx_pci_send_cmd(pcr, 100);
}
static int rts5227_card_power_off(struct rtsx_pcr *pcr, int card)
{
- rtsx_pci_init_cmd(pcr);
- rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
- SD_POWER_MASK | PMOS_STRG_MASK,
- SD_POWER_OFF | PMOS_STRG_400mA);
- rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
- LDO3318_PWR_MASK, 0X00);
- return rtsx_pci_send_cmd(pcr, 100);
+ if (pcr->option.ocp_en)
+ rtsx_pci_disable_ocp(pcr);
+
+ rtsx_pci_write_register(pcr, CARD_PWR_CTL, SD_POWER_MASK |
+ PMOS_STRG_MASK, SD_POWER_OFF | PMOS_STRG_400mA);
+ rtsx_pci_write_register(pcr, PWR_GATE_CTRL, LDO3318_PWR_MASK, 0X00);
+
+ return 0;
}
static int rts5227_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
@@ -348,6 +356,32 @@ static int rts522a_extra_init_hw(struct rtsx_pcr *pcr)
return 0;
}
+static int rts522a_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
+{
+ int err;
+
+ if (voltage == OUTPUT_3V3) {
+ err = rtsx_pci_write_phy_register(pcr, 0x08, 0x57E4);
+ if (err < 0)
+ return err;
+ } else if (voltage == OUTPUT_1V8) {
+ err = rtsx_pci_write_phy_register(pcr, 0x11, 0x3C02);
+ if (err < 0)
+ return err;
+ err = rtsx_pci_write_phy_register(pcr, 0x08, 0x54A4);
+ if (err < 0)
+ return err;
+ } else {
+ return -EINVAL;
+ }
+
+ /* set pad drive */
+ rtsx_pci_init_cmd(pcr);
+ rts5227_fill_driving(pcr, voltage);
+ return rtsx_pci_send_cmd(pcr, 100);
+}
+
+
/* rts522a operations mainly derived from rts5227, except phy/hw init setting.
*/
static const struct pcr_ops rts522a_pcr_ops = {
@@ -360,7 +394,7 @@ static const struct pcr_ops rts522a_pcr_ops = {
.disable_auto_blink = rts5227_disable_auto_blink,
.card_power_on = rts5227_card_power_on,
.card_power_off = rts5227_card_power_off,
- .switch_output_voltage = rts5227_switch_output_voltage,
+ .switch_output_voltage = rts522a_switch_output_voltage,
.cd_deglitch = NULL,
.conv_clk_and_div_n = NULL,
.force_power_down = rts5227_force_power_down,
@@ -371,4 +405,10 @@ void rts522a_init_params(struct rtsx_pcr *pcr)
rts5227_init_params(pcr);
pcr->reg_pm_ctrl3 = RTS522A_PM_CTRL3;
+
+ pcr->option.ocp_en = 1;
+ 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;
+
}
diff --git a/drivers/misc/cardreader/rts5249.c b/drivers/misc/cardreader/rts5249.c
index dbe013abdb83..a3273669fb9c 100644
--- a/drivers/misc/cardreader/rts5249.c
+++ b/drivers/misc/cardreader/rts5249.c
@@ -283,8 +283,12 @@ static int rtsx_base_disable_auto_blink(struct rtsx_pcr *pcr)
static int rtsx_base_card_power_on(struct rtsx_pcr *pcr, int card)
{
+ struct rtsx_cr_option *option = &pcr->option;
int err;
+ if (option->ocp_en)
+ rtsx_pci_enable_ocp(pcr);
+
rtsx_pci_init_cmd(pcr);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
SD_POWER_MASK, SD_VCC_PARTIAL_POWER_ON);
@@ -306,12 +310,15 @@ static int rtsx_base_card_power_on(struct rtsx_pcr *pcr, int card)
static int rtsx_base_card_power_off(struct rtsx_pcr *pcr, int card)
{
- rtsx_pci_init_cmd(pcr);
- rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
- SD_POWER_MASK, SD_POWER_OFF);
- rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
- LDO3318_PWR_MASK, 0x00);
- return rtsx_pci_send_cmd(pcr, 100);
+ struct rtsx_cr_option *option = &pcr->option;
+
+ if (option->ocp_en)
+ rtsx_pci_disable_ocp(pcr);
+
+ rtsx_pci_write_register(pcr, CARD_PWR_CTL, SD_POWER_MASK, SD_POWER_OFF);
+
+ rtsx_pci_write_register(pcr, PWR_GATE_CTRL, LDO3318_PWR_MASK, 0x00);
+ return 0;
}
static int rtsx_base_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
@@ -629,6 +636,11 @@ void rts524a_init_params(struct rtsx_pcr *pcr)
pcr->reg_pm_ctrl3 = RTS524A_PM_CTRL3;
pcr->ops = &rts524a_pcr_ops;
+
+ pcr->option.ocp_en = 1;
+ pcr->hw_param.interrupt_en |= SD_OC_INT_EN;
+ pcr->hw_param.ocp_glitch = SD_OCP_GLITCH_10M;
+ pcr->option.sd_800mA_ocp_thd = RTS524A_OCP_THD_800;
}
static int rts525a_card_power_on(struct rtsx_pcr *pcr, int card)
@@ -737,4 +749,9 @@ void rts525a_init_params(struct rtsx_pcr *pcr)
pcr->reg_pm_ctrl3 = RTS524A_PM_CTRL3;
pcr->ops = &rts525a_pcr_ops;
+
+ pcr->option.ocp_en = 1;
+ pcr->hw_param.interrupt_en |= SD_OC_INT_EN;
+ pcr->hw_param.ocp_glitch = SD_OCP_GLITCH_10M;
+ pcr->option.sd_800mA_ocp_thd = RTS525A_OCP_THD_800;
}
diff --git a/drivers/misc/cardreader/rts5260.c b/drivers/misc/cardreader/rts5260.c
index a493b01c5bc6..ff303a770fef 100644
--- a/drivers/misc/cardreader/rts5260.c
+++ b/drivers/misc/cardreader/rts5260.c
@@ -64,11 +64,13 @@ static void rts5260_fill_driving(struct rtsx_pcr *pcr, u8 voltage)
drive_sel = pcr->sd30_drive_sel_1v8;
}
- rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CLK_DRIVE_SEL,
+ rtsx_pci_write_register(pcr, SD30_CLK_DRIVE_SEL,
0xFF, driving[drive_sel][0]);
- rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CMD_DRIVE_SEL,
+
+ rtsx_pci_write_register(pcr, SD30_CMD_DRIVE_SEL,
0xFF, driving[drive_sel][1]);
- rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DAT_DRIVE_SEL,
+
+ rtsx_pci_write_register(pcr, SD30_CMD_DRIVE_SEL,
0xFF, driving[drive_sel][2]);
}
@@ -193,7 +195,7 @@ static int sd_set_sample_push_timing_sd30(struct rtsx_pcr *pcr)
| SD_ASYNC_FIFO_NOT_RST, SD_30_MODE | SD_ASYNC_FIFO_NOT_RST);
rtsx_pci_write_register(pcr, CLK_CTL, CLK_LOW_FREQ, CLK_LOW_FREQ);
rtsx_pci_write_register(pcr, CARD_CLK_SOURCE, 0xFF,
- CRC_VAR_CLK0 | SD30_FIX_CLK | SAMPLE_VAR_CLK1);
+ CRC_VAR_CLK0 | SD30_FIX_CLK | SAMPLE_VAR_CLK1);
rtsx_pci_write_register(pcr, CLK_CTL, CLK_LOW_FREQ, 0);
return 0;
@@ -207,22 +209,16 @@ static int rts5260_card_power_on(struct rtsx_pcr *pcr, int card)
if (option->ocp_en)
rtsx_pci_enable_ocp(pcr);
- rtsx_pci_init_cmd(pcr);
- rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_CONFIG2,
- DV331812_VDD1, DV331812_VDD1);
- err = rtsx_pci_send_cmd(pcr, CMD_TIMEOUT_DEF);
- if (err < 0)
- return err;
- rtsx_pci_init_cmd(pcr);
- rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_VCC_CFG0,
- RTS5260_DVCC_TUNE_MASK, RTS5260_DVCC_33);
- rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_VCC_CFG1,
- LDO_POW_SDVDD1_MASK, LDO_POW_SDVDD1_ON);
- rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_CONFIG2,
- DV331812_POWERON, DV331812_POWERON);
- err = rtsx_pci_send_cmd(pcr, CMD_TIMEOUT_DEF);
+ rtsx_pci_write_register(pcr, LDO_CONFIG2, DV331812_VDD1, DV331812_VDD1);
+ rtsx_pci_write_register(pcr, LDO_VCC_CFG0,
+ RTS5260_DVCC_TUNE_MASK, RTS5260_DVCC_33);
+ rtsx_pci_write_register(pcr, LDO_VCC_CFG1, LDO_POW_SDVDD1_MASK,
+ LDO_POW_SDVDD1_ON);
+
+ rtsx_pci_write_register(pcr, LDO_CONFIG2,
+ DV331812_POWERON, DV331812_POWERON);
msleep(20);
if (pcr->extra_caps & EXTRA_CAPS_SD_SDR50 ||
@@ -273,9 +269,9 @@ static int rts5260_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
}
/* set pad drive */
- rtsx_pci_init_cmd(pcr);
rts5260_fill_driving(pcr, voltage);
- return rtsx_pci_send_cmd(pcr, CMD_TIMEOUT_DEF);
+
+ return 0;
}
static void rts5260_stop_cmd(struct rtsx_pcr *pcr)
@@ -290,29 +286,22 @@ static void rts5260_stop_cmd(struct rtsx_pcr *pcr)
static void rts5260_card_before_power_off(struct rtsx_pcr *pcr)
{
- struct rtsx_cr_option *option = &pcr->option;
-
rts5260_stop_cmd(pcr);
rts5260_switch_output_voltage(pcr, OUTPUT_3V3);
- if (option->ocp_en)
- rtsx_pci_disable_ocp(pcr);
}
static int rts5260_card_power_off(struct rtsx_pcr *pcr, int card)
{
- int err = 0;
-
rts5260_card_before_power_off(pcr);
+ rtsx_pci_write_register(pcr, LDO_VCC_CFG1,
+ LDO_POW_SDVDD1_MASK, LDO_POW_SDVDD1_OFF);
+ rtsx_pci_write_register(pcr, LDO_CONFIG2,
+ DV331812_POWERON, DV331812_POWEROFF);
+ if (pcr->option.ocp_en)
+ rtsx_pci_disable_ocp(pcr);
- rtsx_pci_init_cmd(pcr);
- rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_VCC_CFG1,
- LDO_POW_SDVDD1_MASK, LDO_POW_SDVDD1_OFF);
- rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_CONFIG2,
- DV331812_POWERON, DV331812_POWEROFF);
- err = rtsx_pci_send_cmd(pcr, CMD_TIMEOUT_DEF);
-
- return err;
+ return 0;
}
static void rts5260_init_ocp(struct rtsx_pcr *pcr)
@@ -322,41 +311,29 @@ static void rts5260_init_ocp(struct rtsx_pcr *pcr)
if (option->ocp_en) {
u8 mask, val;
- rtsx_pci_write_register(pcr, RTS5260_DVCC_CTRL,
- RTS5260_DVCC_OCP_EN |
- RTS5260_DVCC_OCP_CL_EN,
- RTS5260_DVCC_OCP_EN |
- RTS5260_DVCC_OCP_CL_EN);
- rtsx_pci_write_register(pcr, RTS5260_DVIO_CTRL,
- RTS5260_DVIO_OCP_EN |
- RTS5260_DVIO_OCP_CL_EN,
- RTS5260_DVIO_OCP_EN |
- RTS5260_DVIO_OCP_CL_EN);
rtsx_pci_write_register(pcr, RTS5260_DVCC_CTRL,
RTS5260_DVCC_OCP_THD_MASK,
- option->sd_400mA_ocp_thd);
-
- rtsx_pci_write_register(pcr, RTS5260_DVIO_CTRL,
- RTS5260_DVIO_OCP_THD_MASK,
- RTS5260_DVIO_OCP_THD_350);
+ option->sd_800mA_ocp_thd);
rtsx_pci_write_register(pcr, RTS5260_DV331812_CFG,
RTS5260_DV331812_OCP_THD_MASK,
- RTS5260_DV331812_OCP_THD_210);
+ RTS5260_DV331812_OCP_THD_270);
- mask = SD_OCP_GLITCH_MASK | SDVIO_OCP_GLITCH_MASK;
+ mask = SD_OCP_GLITCH_MASK;
val = pcr->hw_param.ocp_glitch;
rtsx_pci_write_register(pcr, REG_OCPGLITCH, mask, val);
+ rtsx_pci_write_register(pcr, RTS5260_DVCC_CTRL,
+ RTS5260_DVCC_OCP_EN |
+ RTS5260_DVCC_OCP_CL_EN,
+ RTS5260_DVCC_OCP_EN |
+ RTS5260_DVCC_OCP_CL_EN);
rtsx_pci_enable_ocp(pcr);
} else {
rtsx_pci_write_register(pcr, RTS5260_DVCC_CTRL,
RTS5260_DVCC_OCP_EN |
RTS5260_DVCC_OCP_CL_EN, 0);
- rtsx_pci_write_register(pcr, RTS5260_DVIO_CTRL,
- RTS5260_DVIO_OCP_EN |
- RTS5260_DVIO_OCP_CL_EN, 0);
}
}
@@ -364,14 +341,8 @@ static void rts5260_enable_ocp(struct rtsx_pcr *pcr)
{
u8 val = 0;
- rtsx_pci_write_register(pcr, FPDCTL, OC_POWER_DOWN, 0);
-
val = SD_OCP_INT_EN | SD_DETECT_EN;
- val |= SDVIO_OCP_INT_EN | SDVIO_DETECT_EN;
rtsx_pci_write_register(pcr, REG_OCPCTL, 0xFF, val);
- rtsx_pci_write_register(pcr, REG_DV3318_OCPCTL,
- DV3318_DETECT_EN | DV3318_OCP_INT_EN,
- DV3318_DETECT_EN | DV3318_OCP_INT_EN);
}
static void rts5260_disable_ocp(struct rtsx_pcr *pcr)
@@ -379,15 +350,10 @@ static void rts5260_disable_ocp(struct rtsx_pcr *pcr)
u8 mask = 0;
mask = SD_OCP_INT_EN | SD_DETECT_EN;
- mask |= SDVIO_OCP_INT_EN | SDVIO_DETECT_EN;
rtsx_pci_write_register(pcr, REG_OCPCTL, mask, 0);
- rtsx_pci_write_register(pcr, REG_DV3318_OCPCTL,
- DV3318_DETECT_EN | DV3318_OCP_INT_EN, 0);
-
- rtsx_pci_write_register(pcr, FPDCTL, OC_POWER_DOWN,
- OC_POWER_DOWN);
}
+
static int rts5260_get_ocpstat(struct rtsx_pcr *pcr, u8 *val)
{
return rtsx_pci_read_register(pcr, REG_OCPSTAT, val);
@@ -404,9 +370,7 @@ static void rts5260_clear_ocpstat(struct rtsx_pcr *pcr)
u8 val = 0;
mask = SD_OCP_INT_CLR | SD_OC_CLR;
- mask |= SDVIO_OCP_INT_CLR | SDVIO_OC_CLR;
val = SD_OCP_INT_CLR | SD_OC_CLR;
- val |= SDVIO_OCP_INT_CLR | SDVIO_OC_CLR;
rtsx_pci_write_register(pcr, REG_OCPCTL, mask, val);
rtsx_pci_write_register(pcr, REG_DV3318_OCPCTL,
@@ -425,36 +389,22 @@ static void rts5260_process_ocp(struct rtsx_pcr *pcr)
rtsx_pci_get_ocpstat(pcr, &pcr->ocp_stat);
rts5260_get_ocpstat2(pcr, &pcr->ocp_stat2);
- if (pcr->card_exist & SD_EXIST)
- rtsx_sd_power_off_card3v3(pcr);
- else if (pcr->card_exist & MS_EXIST)
- rtsx_ms_power_off_card3v3(pcr);
-
- if (!(pcr->card_exist & MS_EXIST) && !(pcr->card_exist & SD_EXIST)) {
- if ((pcr->ocp_stat & (SD_OC_NOW | SD_OC_EVER |
- SDVIO_OC_NOW | SDVIO_OC_EVER)) ||
- (pcr->ocp_stat2 & (DV3318_OCP_NOW | DV3318_OCP_EVER)))
- rtsx_pci_clear_ocpstat(pcr);
+
+ if ((pcr->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) ||
+ (pcr->ocp_stat2 & (DV3318_OCP_NOW | DV3318_OCP_EVER))) {
+ rtsx_pci_card_power_off(pcr, RTSX_SD_CARD);
+ rtsx_pci_write_register(pcr, CARD_OE, SD_OUTPUT_EN, 0);
+ rtsx_pci_clear_ocpstat(pcr);
pcr->ocp_stat = 0;
pcr->ocp_stat2 = 0;
}
- if ((pcr->ocp_stat & (SD_OC_NOW | SD_OC_EVER |
- SDVIO_OC_NOW | SDVIO_OC_EVER)) ||
- (pcr->ocp_stat2 & (DV3318_OCP_NOW | DV3318_OCP_EVER))) {
- if (pcr->card_exist & SD_EXIST)
- rtsx_pci_write_register(pcr, CARD_OE, SD_OUTPUT_EN, 0);
- else if (pcr->card_exist & MS_EXIST)
- rtsx_pci_write_register(pcr, CARD_OE, MS_OUTPUT_EN, 0);
- }
}
static int rts5260_init_hw(struct rtsx_pcr *pcr)
{
int err;
- rtsx_pci_init_ocp(pcr);
-
rtsx_pci_init_cmd(pcr);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, L1SUB_CONFIG1,
@@ -483,6 +433,8 @@ static int rts5260_init_hw(struct rtsx_pcr *pcr)
if (err < 0)
return err;
+ rtsx_pci_init_ocp(pcr);
+
return 0;
}
@@ -499,6 +451,12 @@ static void rts5260_pwr_saving_setting(struct rtsx_pcr *pcr)
pcr_dbg(pcr, "Set parameters for L1.2.");
rtsx_pci_write_register(pcr, PWR_GLOBAL_CTRL,
0xFF, PCIE_L1_2_EN);
+ rtsx_pci_write_register(pcr, RTS5260_DVCC_CTRL,
+ RTS5260_DVCC_OCP_EN |
+ RTS5260_DVCC_OCP_CL_EN,
+ RTS5260_DVCC_OCP_EN |
+ RTS5260_DVCC_OCP_CL_EN);
+
rtsx_pci_write_register(pcr, PWR_FE_CTL,
0xFF, PCIE_L1_2_PD_FE_EN);
} else if (lss_l1_1) {
@@ -742,7 +700,7 @@ void rts5260_init_params(struct rtsx_pcr *pcr)
option->ocp_en = 1;
if (option->ocp_en)
hw_param->interrupt_en |= SD_OC_INT_EN;
- hw_param->ocp_glitch = SD_OCP_GLITCH_10M | SDVIO_OCP_GLITCH_800U;
+ hw_param->ocp_glitch = SD_OCP_GLITCH_100U | SDVIO_OCP_GLITCH_800U;
option->sd_400mA_ocp_thd = RTS5260_DVCC_OCP_THD_550;
option->sd_800mA_ocp_thd = RTS5260_DVCC_OCP_THD_970;
}
diff --git a/drivers/misc/cardreader/rtsx_pcr.c b/drivers/misc/cardreader/rtsx_pcr.c
index da445223f4cc..e8072804d83a 100644
--- a/drivers/misc/cardreader/rtsx_pcr.c
+++ b/drivers/misc/cardreader/rtsx_pcr.c
@@ -703,7 +703,10 @@ EXPORT_SYMBOL_GPL(rtsx_pci_card_pull_ctl_disable);
static void rtsx_pci_enable_bus_int(struct rtsx_pcr *pcr)
{
- pcr->bier = TRANS_OK_INT_EN | TRANS_FAIL_INT_EN | SD_INT_EN;
+ struct rtsx_hw_param *hw_param = &pcr->hw_param;
+
+ pcr->bier = TRANS_OK_INT_EN | TRANS_FAIL_INT_EN | SD_INT_EN |
+ hw_param->interrupt_en;
if (pcr->num_slots > 1)
pcr->bier |= MS_INT_EN;
@@ -969,8 +972,19 @@ static void rtsx_pci_card_detect(struct work_struct *work)
static void rtsx_pci_process_ocp(struct rtsx_pcr *pcr)
{
- if (pcr->ops->process_ocp)
+ if (pcr->ops->process_ocp) {
pcr->ops->process_ocp(pcr);
+ } else {
+ if (!pcr->option.ocp_en)
+ return;
+ rtsx_pci_get_ocpstat(pcr, &pcr->ocp_stat);
+ if (pcr->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) {
+ rtsx_pci_card_power_off(pcr, RTSX_SD_CARD);
+ rtsx_pci_write_register(pcr, CARD_OE, SD_OUTPUT_EN, 0);
+ rtsx_pci_clear_ocpstat(pcr);
+ pcr->ocp_stat = 0;
+ }
+ }
}
static int rtsx_pci_process_ocp_interrupt(struct rtsx_pcr *pcr)
@@ -1039,7 +1053,7 @@ static irqreturn_t rtsx_pci_isr(int irq, void *dev_id)
}
}
- if (pcr->card_inserted || pcr->card_removed)
+ if ((pcr->card_inserted || pcr->card_removed) && !(int_reg & SD_OC_INT))
schedule_delayed_work(&pcr->carddet_work,
msecs_to_jiffies(200));
@@ -1144,10 +1158,12 @@ void rtsx_pci_enable_ocp(struct rtsx_pcr *pcr)
{
u8 val = SD_OCP_INT_EN | SD_DETECT_EN;
- if (pcr->ops->enable_ocp)
+ if (pcr->ops->enable_ocp) {
pcr->ops->enable_ocp(pcr);
- else
+ } else {
+ rtsx_pci_write_register(pcr, FPDCTL, OC_POWER_DOWN, 0);
rtsx_pci_write_register(pcr, REG_OCPCTL, 0xFF, val);
+ }
}
@@ -1155,10 +1171,13 @@ void rtsx_pci_disable_ocp(struct rtsx_pcr *pcr)
{
u8 mask = SD_OCP_INT_EN | SD_DETECT_EN;
- if (pcr->ops->disable_ocp)
+ if (pcr->ops->disable_ocp) {
pcr->ops->disable_ocp(pcr);
- else
+ } else {
rtsx_pci_write_register(pcr, REG_OCPCTL, mask, 0);
+ rtsx_pci_write_register(pcr, FPDCTL, OC_POWER_DOWN,
+ OC_POWER_DOWN);
+ }
}
void rtsx_pci_init_ocp(struct rtsx_pcr *pcr)
@@ -1169,7 +1188,7 @@ void rtsx_pci_init_ocp(struct rtsx_pcr *pcr)
struct rtsx_cr_option *option = &(pcr->option);
if (option->ocp_en) {
- u8 val = option->sd_400mA_ocp_thd;
+ u8 val = option->sd_800mA_ocp_thd;
rtsx_pci_write_register(pcr, FPDCTL, OC_POWER_DOWN, 0);
rtsx_pci_write_register(pcr, REG_OCPPARA1,
@@ -1204,6 +1223,7 @@ void rtsx_pci_clear_ocpstat(struct rtsx_pcr *pcr)
u8 val = SD_OCP_INT_CLR | SD_OC_CLR;
rtsx_pci_write_register(pcr, REG_OCPCTL, mask, val);
+ udelay(100);
rtsx_pci_write_register(pcr, REG_OCPCTL, mask, 0);
}
}
@@ -1313,6 +1333,8 @@ static int rtsx_pci_init_hw(struct rtsx_pcr *pcr)
break;
}
+ rtsx_pci_init_ocp(pcr);
+
/* Enable clk_request_n to enable clock power management */
rtsx_pci_write_config_byte(pcr, pcr->pcie_cap + PCI_EXP_LNKCTL + 1, 1);
/* Enter L1 when host tx idle */
diff --git a/drivers/misc/cardreader/rtsx_pcr.h b/drivers/misc/cardreader/rtsx_pcr.h
index 6ea1655db0bb..300fc31d8e67 100644
--- a/drivers/misc/cardreader/rtsx_pcr.h
+++ b/drivers/misc/cardreader/rtsx_pcr.h
@@ -46,6 +46,11 @@
#define SSC_CLOCK_STABLE_WAIT 130
+#define RTS524A_OCP_THD_800 0x04
+#define RTS525A_OCP_THD_800 0x05
+#define RTS522A_OCP_THD_800 0x06
+
+
int __rtsx_pci_write_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 val);
int __rtsx_pci_read_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 *val);
--
2.17.1
Dear all,
May I know how is this patch going on ?
Is it work well on your side?
We have some guest want to know what stage is this patch going to
Thank you
Best regards,
Ricky_wu
> -----Original Message-----
> From: ?d???? Ricky
> Sent: Thursday, March 07, 2019 5:44 PM
> To: [email protected]; [email protected]; [email protected];
> [email protected]; [email protected]
> Cc: ?d???? Ricky
> Subject: [PATCH v3] misc: rtsx: Enable OCP for rts522a rts524a rts525a rts5260
>
> From: RickyWu <[email protected]>
>
> this enables and adds OCP function for Realtek A series cardreader chips
> and fixes some OCP flow in rts5260.c
>
> Signed-off-by: RickyWu <[email protected]>
> ---
> drivers/misc/cardreader/rts5227.c | 58 ++++++++++--
> drivers/misc/cardreader/rts5249.c | 29 ++++--
> drivers/misc/cardreader/rts5260.c | 136 ++++++++++-------------------
> drivers/misc/cardreader/rtsx_pcr.c | 38 ++++++--
> drivers/misc/cardreader/rtsx_pcr.h | 5 ++
> 5 files changed, 154 insertions(+), 112 deletions(-)
>
> diff --git a/drivers/misc/cardreader/rts5227.c
> b/drivers/misc/cardreader/rts5227.c
> index 024dcba8d6c8..95394c6ca5c7 100644
> --- a/drivers/misc/cardreader/rts5227.c
> +++ b/drivers/misc/cardreader/rts5227.c
> @@ -170,6 +170,9 @@ static int rts5227_card_power_on(struct rtsx_pcr *pcr,
> int card)
> {
> int err;
>
> + if (pcr->option.ocp_en)
> + rtsx_pci_enable_ocp(pcr);
> +
> rtsx_pci_init_cmd(pcr);
> rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
> SD_POWER_MASK, SD_PARTIAL_POWER_ON);
> @@ -180,25 +183,30 @@ static int rts5227_card_power_on(struct rtsx_pcr
> *pcr, int card)
> return err;
>
> /* To avoid too large in-rush current */
> - udelay(150);
> + msleep(20);
>
> rtsx_pci_init_cmd(pcr);
> rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
> SD_POWER_MASK, SD_POWER_ON);
> rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
> LDO3318_PWR_MASK, 0x06);
> + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_OE,
> + SD_OUTPUT_EN, SD_OUTPUT_EN);
> + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_OE,
> + MS_OUTPUT_EN, MS_OUTPUT_EN);
> return rtsx_pci_send_cmd(pcr, 100);
> }
>
> static int rts5227_card_power_off(struct rtsx_pcr *pcr, int card)
> {
> - rtsx_pci_init_cmd(pcr);
> - rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
> - SD_POWER_MASK | PMOS_STRG_MASK,
> - SD_POWER_OFF | PMOS_STRG_400mA);
> - rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
> - LDO3318_PWR_MASK, 0X00);
> - return rtsx_pci_send_cmd(pcr, 100);
> + if (pcr->option.ocp_en)
> + rtsx_pci_disable_ocp(pcr);
> +
> + rtsx_pci_write_register(pcr, CARD_PWR_CTL, SD_POWER_MASK |
> + PMOS_STRG_MASK, SD_POWER_OFF | PMOS_STRG_400mA);
> + rtsx_pci_write_register(pcr, PWR_GATE_CTRL, LDO3318_PWR_MASK,
> 0X00);
> +
> + return 0;
> }
>
> static int rts5227_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
> @@ -348,6 +356,32 @@ static int rts522a_extra_init_hw(struct rtsx_pcr *pcr)
> return 0;
> }
>
> +static int rts522a_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
> +{
> + int err;
> +
> + if (voltage == OUTPUT_3V3) {
> + err = rtsx_pci_write_phy_register(pcr, 0x08, 0x57E4);
> + if (err < 0)
> + return err;
> + } else if (voltage == OUTPUT_1V8) {
> + err = rtsx_pci_write_phy_register(pcr, 0x11, 0x3C02);
> + if (err < 0)
> + return err;
> + err = rtsx_pci_write_phy_register(pcr, 0x08, 0x54A4);
> + if (err < 0)
> + return err;
> + } else {
> + return -EINVAL;
> + }
> +
> + /* set pad drive */
> + rtsx_pci_init_cmd(pcr);
> + rts5227_fill_driving(pcr, voltage);
> + return rtsx_pci_send_cmd(pcr, 100);
> +}
> +
> +
> /* rts522a operations mainly derived from rts5227, except phy/hw init setting.
> */
> static const struct pcr_ops rts522a_pcr_ops = {
> @@ -360,7 +394,7 @@ static const struct pcr_ops rts522a_pcr_ops = {
> .disable_auto_blink = rts5227_disable_auto_blink,
> .card_power_on = rts5227_card_power_on,
> .card_power_off = rts5227_card_power_off,
> - .switch_output_voltage = rts5227_switch_output_voltage,
> + .switch_output_voltage = rts522a_switch_output_voltage,
> .cd_deglitch = NULL,
> .conv_clk_and_div_n = NULL,
> .force_power_down = rts5227_force_power_down,
> @@ -371,4 +405,10 @@ void rts522a_init_params(struct rtsx_pcr *pcr)
> rts5227_init_params(pcr);
>
> pcr->reg_pm_ctrl3 = RTS522A_PM_CTRL3;
> +
> + pcr->option.ocp_en = 1;
> + 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;
> +
> }
> diff --git a/drivers/misc/cardreader/rts5249.c
> b/drivers/misc/cardreader/rts5249.c
> index dbe013abdb83..a3273669fb9c 100644
> --- a/drivers/misc/cardreader/rts5249.c
> +++ b/drivers/misc/cardreader/rts5249.c
> @@ -283,8 +283,12 @@ static int rtsx_base_disable_auto_blink(struct rtsx_pcr
> *pcr)
>
> static int rtsx_base_card_power_on(struct rtsx_pcr *pcr, int card)
> {
> + struct rtsx_cr_option *option = &pcr->option;
> int err;
>
> + if (option->ocp_en)
> + rtsx_pci_enable_ocp(pcr);
> +
> rtsx_pci_init_cmd(pcr);
> rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
> SD_POWER_MASK, SD_VCC_PARTIAL_POWER_ON);
> @@ -306,12 +310,15 @@ static int rtsx_base_card_power_on(struct rtsx_pcr
> *pcr, int card)
>
> static int rtsx_base_card_power_off(struct rtsx_pcr *pcr, int card)
> {
> - rtsx_pci_init_cmd(pcr);
> - rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
> - SD_POWER_MASK, SD_POWER_OFF);
> - rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
> - LDO3318_PWR_MASK, 0x00);
> - return rtsx_pci_send_cmd(pcr, 100);
> + struct rtsx_cr_option *option = &pcr->option;
> +
> + if (option->ocp_en)
> + rtsx_pci_disable_ocp(pcr);
> +
> + rtsx_pci_write_register(pcr, CARD_PWR_CTL, SD_POWER_MASK,
> SD_POWER_OFF);
> +
> + rtsx_pci_write_register(pcr, PWR_GATE_CTRL, LDO3318_PWR_MASK,
> 0x00);
> + return 0;
> }
>
> static int rtsx_base_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
> @@ -629,6 +636,11 @@ void rts524a_init_params(struct rtsx_pcr *pcr)
>
> pcr->reg_pm_ctrl3 = RTS524A_PM_CTRL3;
> pcr->ops = &rts524a_pcr_ops;
> +
> + pcr->option.ocp_en = 1;
> + pcr->hw_param.interrupt_en |= SD_OC_INT_EN;
> + pcr->hw_param.ocp_glitch = SD_OCP_GLITCH_10M;
> + pcr->option.sd_800mA_ocp_thd = RTS524A_OCP_THD_800;
> }
>
> static int rts525a_card_power_on(struct rtsx_pcr *pcr, int card)
> @@ -737,4 +749,9 @@ void rts525a_init_params(struct rtsx_pcr *pcr)
>
> pcr->reg_pm_ctrl3 = RTS524A_PM_CTRL3;
> pcr->ops = &rts525a_pcr_ops;
> +
> + pcr->option.ocp_en = 1;
> + pcr->hw_param.interrupt_en |= SD_OC_INT_EN;
> + pcr->hw_param.ocp_glitch = SD_OCP_GLITCH_10M;
> + pcr->option.sd_800mA_ocp_thd = RTS525A_OCP_THD_800;
> }
> diff --git a/drivers/misc/cardreader/rts5260.c
> b/drivers/misc/cardreader/rts5260.c
> index a493b01c5bc6..ff303a770fef 100644
> --- a/drivers/misc/cardreader/rts5260.c
> +++ b/drivers/misc/cardreader/rts5260.c
> @@ -64,11 +64,13 @@ static void rts5260_fill_driving(struct rtsx_pcr *pcr, u8
> voltage)
> drive_sel = pcr->sd30_drive_sel_1v8;
> }
>
> - rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CLK_DRIVE_SEL,
> + rtsx_pci_write_register(pcr, SD30_CLK_DRIVE_SEL,
> 0xFF, driving[drive_sel][0]);
> - rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CMD_DRIVE_SEL,
> +
> + rtsx_pci_write_register(pcr, SD30_CMD_DRIVE_SEL,
> 0xFF, driving[drive_sel][1]);
> - rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DAT_DRIVE_SEL,
> +
> + rtsx_pci_write_register(pcr, SD30_CMD_DRIVE_SEL,
> 0xFF, driving[drive_sel][2]);
> }
>
> @@ -193,7 +195,7 @@ static int sd_set_sample_push_timing_sd30(struct
> rtsx_pcr *pcr)
> | SD_ASYNC_FIFO_NOT_RST, SD_30_MODE |
> SD_ASYNC_FIFO_NOT_RST);
> rtsx_pci_write_register(pcr, CLK_CTL, CLK_LOW_FREQ, CLK_LOW_FREQ);
> rtsx_pci_write_register(pcr, CARD_CLK_SOURCE, 0xFF,
> - CRC_VAR_CLK0 | SD30_FIX_CLK | SAMPLE_VAR_CLK1);
> + CRC_VAR_CLK0 | SD30_FIX_CLK | SAMPLE_VAR_CLK1);
> rtsx_pci_write_register(pcr, CLK_CTL, CLK_LOW_FREQ, 0);
>
> return 0;
> @@ -207,22 +209,16 @@ static int rts5260_card_power_on(struct rtsx_pcr
> *pcr, int card)
> if (option->ocp_en)
> rtsx_pci_enable_ocp(pcr);
>
> - rtsx_pci_init_cmd(pcr);
> - rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_CONFIG2,
> - DV331812_VDD1, DV331812_VDD1);
> - err = rtsx_pci_send_cmd(pcr, CMD_TIMEOUT_DEF);
> - if (err < 0)
> - return err;
>
> - rtsx_pci_init_cmd(pcr);
> - rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_VCC_CFG0,
> - RTS5260_DVCC_TUNE_MASK, RTS5260_DVCC_33);
> - rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_VCC_CFG1,
> - LDO_POW_SDVDD1_MASK, LDO_POW_SDVDD1_ON);
> - rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_CONFIG2,
> - DV331812_POWERON, DV331812_POWERON);
> - err = rtsx_pci_send_cmd(pcr, CMD_TIMEOUT_DEF);
> + rtsx_pci_write_register(pcr, LDO_CONFIG2, DV331812_VDD1,
> DV331812_VDD1);
> + rtsx_pci_write_register(pcr, LDO_VCC_CFG0,
> + RTS5260_DVCC_TUNE_MASK, RTS5260_DVCC_33);
>
> + rtsx_pci_write_register(pcr, LDO_VCC_CFG1, LDO_POW_SDVDD1_MASK,
> + LDO_POW_SDVDD1_ON);
> +
> + rtsx_pci_write_register(pcr, LDO_CONFIG2,
> + DV331812_POWERON, DV331812_POWERON);
> msleep(20);
>
> if (pcr->extra_caps & EXTRA_CAPS_SD_SDR50 ||
> @@ -273,9 +269,9 @@ static int rts5260_switch_output_voltage(struct
> rtsx_pcr *pcr, u8 voltage)
> }
>
> /* set pad drive */
> - rtsx_pci_init_cmd(pcr);
> rts5260_fill_driving(pcr, voltage);
> - return rtsx_pci_send_cmd(pcr, CMD_TIMEOUT_DEF);
> +
> + return 0;
> }
>
> static void rts5260_stop_cmd(struct rtsx_pcr *pcr)
> @@ -290,29 +286,22 @@ static void rts5260_stop_cmd(struct rtsx_pcr *pcr)
>
> static void rts5260_card_before_power_off(struct rtsx_pcr *pcr)
> {
> - struct rtsx_cr_option *option = &pcr->option;
> -
> rts5260_stop_cmd(pcr);
> rts5260_switch_output_voltage(pcr, OUTPUT_3V3);
>
> - if (option->ocp_en)
> - rtsx_pci_disable_ocp(pcr);
> }
>
> static int rts5260_card_power_off(struct rtsx_pcr *pcr, int card)
> {
> - int err = 0;
> -
> rts5260_card_before_power_off(pcr);
> + rtsx_pci_write_register(pcr, LDO_VCC_CFG1,
> + LDO_POW_SDVDD1_MASK, LDO_POW_SDVDD1_OFF);
> + rtsx_pci_write_register(pcr, LDO_CONFIG2,
> + DV331812_POWERON, DV331812_POWEROFF);
> + if (pcr->option.ocp_en)
> + rtsx_pci_disable_ocp(pcr);
>
> - rtsx_pci_init_cmd(pcr);
> - rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_VCC_CFG1,
> - LDO_POW_SDVDD1_MASK, LDO_POW_SDVDD1_OFF);
> - rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_CONFIG2,
> - DV331812_POWERON, DV331812_POWEROFF);
> - err = rtsx_pci_send_cmd(pcr, CMD_TIMEOUT_DEF);
> -
> - return err;
> + return 0;
> }
>
> static void rts5260_init_ocp(struct rtsx_pcr *pcr)
> @@ -322,41 +311,29 @@ static void rts5260_init_ocp(struct rtsx_pcr *pcr)
> if (option->ocp_en) {
> u8 mask, val;
>
> - rtsx_pci_write_register(pcr, RTS5260_DVCC_CTRL,
> - RTS5260_DVCC_OCP_EN |
> - RTS5260_DVCC_OCP_CL_EN,
> - RTS5260_DVCC_OCP_EN |
> - RTS5260_DVCC_OCP_CL_EN);
> - rtsx_pci_write_register(pcr, RTS5260_DVIO_CTRL,
> - RTS5260_DVIO_OCP_EN |
> - RTS5260_DVIO_OCP_CL_EN,
> - RTS5260_DVIO_OCP_EN |
> - RTS5260_DVIO_OCP_CL_EN);
>
> rtsx_pci_write_register(pcr, RTS5260_DVCC_CTRL,
> RTS5260_DVCC_OCP_THD_MASK,
> - option->sd_400mA_ocp_thd);
> -
> - rtsx_pci_write_register(pcr, RTS5260_DVIO_CTRL,
> - RTS5260_DVIO_OCP_THD_MASK,
> - RTS5260_DVIO_OCP_THD_350);
> + option->sd_800mA_ocp_thd);
>
> rtsx_pci_write_register(pcr, RTS5260_DV331812_CFG,
> RTS5260_DV331812_OCP_THD_MASK,
> - RTS5260_DV331812_OCP_THD_210);
> + RTS5260_DV331812_OCP_THD_270);
>
> - mask = SD_OCP_GLITCH_MASK | SDVIO_OCP_GLITCH_MASK;
> + mask = SD_OCP_GLITCH_MASK;
> val = pcr->hw_param.ocp_glitch;
> rtsx_pci_write_register(pcr, REG_OCPGLITCH, mask, val);
> + rtsx_pci_write_register(pcr, RTS5260_DVCC_CTRL,
> + RTS5260_DVCC_OCP_EN |
> + RTS5260_DVCC_OCP_CL_EN,
> + RTS5260_DVCC_OCP_EN |
> + RTS5260_DVCC_OCP_CL_EN);
>
> rtsx_pci_enable_ocp(pcr);
> } else {
> rtsx_pci_write_register(pcr, RTS5260_DVCC_CTRL,
> RTS5260_DVCC_OCP_EN |
> RTS5260_DVCC_OCP_CL_EN, 0);
> - rtsx_pci_write_register(pcr, RTS5260_DVIO_CTRL,
> - RTS5260_DVIO_OCP_EN |
> - RTS5260_DVIO_OCP_CL_EN, 0);
> }
> }
>
> @@ -364,14 +341,8 @@ static void rts5260_enable_ocp(struct rtsx_pcr *pcr)
> {
> u8 val = 0;
>
> - rtsx_pci_write_register(pcr, FPDCTL, OC_POWER_DOWN, 0);
> -
> val = SD_OCP_INT_EN | SD_DETECT_EN;
> - val |= SDVIO_OCP_INT_EN | SDVIO_DETECT_EN;
> rtsx_pci_write_register(pcr, REG_OCPCTL, 0xFF, val);
> - rtsx_pci_write_register(pcr, REG_DV3318_OCPCTL,
> - DV3318_DETECT_EN | DV3318_OCP_INT_EN,
> - DV3318_DETECT_EN | DV3318_OCP_INT_EN);
> }
>
> static void rts5260_disable_ocp(struct rtsx_pcr *pcr)
> @@ -379,15 +350,10 @@ static void rts5260_disable_ocp(struct rtsx_pcr *pcr)
> u8 mask = 0;
>
> mask = SD_OCP_INT_EN | SD_DETECT_EN;
> - mask |= SDVIO_OCP_INT_EN | SDVIO_DETECT_EN;
> rtsx_pci_write_register(pcr, REG_OCPCTL, mask, 0);
> - rtsx_pci_write_register(pcr, REG_DV3318_OCPCTL,
> - DV3318_DETECT_EN | DV3318_OCP_INT_EN, 0);
> -
> - rtsx_pci_write_register(pcr, FPDCTL, OC_POWER_DOWN,
> - OC_POWER_DOWN);
> }
>
> +
> static int rts5260_get_ocpstat(struct rtsx_pcr *pcr, u8 *val)
> {
> return rtsx_pci_read_register(pcr, REG_OCPSTAT, val);
> @@ -404,9 +370,7 @@ static void rts5260_clear_ocpstat(struct rtsx_pcr *pcr)
> u8 val = 0;
>
> mask = SD_OCP_INT_CLR | SD_OC_CLR;
> - mask |= SDVIO_OCP_INT_CLR | SDVIO_OC_CLR;
> val = SD_OCP_INT_CLR | SD_OC_CLR;
> - val |= SDVIO_OCP_INT_CLR | SDVIO_OC_CLR;
>
> rtsx_pci_write_register(pcr, REG_OCPCTL, mask, val);
> rtsx_pci_write_register(pcr, REG_DV3318_OCPCTL,
> @@ -425,36 +389,22 @@ static void rts5260_process_ocp(struct rtsx_pcr *pcr)
>
> rtsx_pci_get_ocpstat(pcr, &pcr->ocp_stat);
> rts5260_get_ocpstat2(pcr, &pcr->ocp_stat2);
> - if (pcr->card_exist & SD_EXIST)
> - rtsx_sd_power_off_card3v3(pcr);
> - else if (pcr->card_exist & MS_EXIST)
> - rtsx_ms_power_off_card3v3(pcr);
> -
> - if (!(pcr->card_exist & MS_EXIST) && !(pcr->card_exist & SD_EXIST)) {
> - if ((pcr->ocp_stat & (SD_OC_NOW | SD_OC_EVER |
> - SDVIO_OC_NOW | SDVIO_OC_EVER)) ||
> - (pcr->ocp_stat2 & (DV3318_OCP_NOW | DV3318_OCP_EVER)))
> - rtsx_pci_clear_ocpstat(pcr);
> +
> + if ((pcr->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) ||
> + (pcr->ocp_stat2 & (DV3318_OCP_NOW | DV3318_OCP_EVER))) {
> + rtsx_pci_card_power_off(pcr, RTSX_SD_CARD);
> + rtsx_pci_write_register(pcr, CARD_OE, SD_OUTPUT_EN, 0);
> + rtsx_pci_clear_ocpstat(pcr);
> pcr->ocp_stat = 0;
> pcr->ocp_stat2 = 0;
> }
>
> - if ((pcr->ocp_stat & (SD_OC_NOW | SD_OC_EVER |
> - SDVIO_OC_NOW | SDVIO_OC_EVER)) ||
> - (pcr->ocp_stat2 & (DV3318_OCP_NOW | DV3318_OCP_EVER))) {
> - if (pcr->card_exist & SD_EXIST)
> - rtsx_pci_write_register(pcr, CARD_OE, SD_OUTPUT_EN, 0);
> - else if (pcr->card_exist & MS_EXIST)
> - rtsx_pci_write_register(pcr, CARD_OE, MS_OUTPUT_EN, 0);
> - }
> }
>
> static int rts5260_init_hw(struct rtsx_pcr *pcr)
> {
> int err;
>
> - rtsx_pci_init_ocp(pcr);
> -
> rtsx_pci_init_cmd(pcr);
>
> rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, L1SUB_CONFIG1,
> @@ -483,6 +433,8 @@ static int rts5260_init_hw(struct rtsx_pcr *pcr)
> if (err < 0)
> return err;
>
> + rtsx_pci_init_ocp(pcr);
> +
> return 0;
> }
>
> @@ -499,6 +451,12 @@ static void rts5260_pwr_saving_setting(struct rtsx_pcr
> *pcr)
> pcr_dbg(pcr, "Set parameters for L1.2.");
> rtsx_pci_write_register(pcr, PWR_GLOBAL_CTRL,
> 0xFF, PCIE_L1_2_EN);
> + rtsx_pci_write_register(pcr, RTS5260_DVCC_CTRL,
> + RTS5260_DVCC_OCP_EN |
> + RTS5260_DVCC_OCP_CL_EN,
> + RTS5260_DVCC_OCP_EN |
> + RTS5260_DVCC_OCP_CL_EN);
> +
> rtsx_pci_write_register(pcr, PWR_FE_CTL,
> 0xFF, PCIE_L1_2_PD_FE_EN);
> } else if (lss_l1_1) {
> @@ -742,7 +700,7 @@ void rts5260_init_params(struct rtsx_pcr *pcr)
> option->ocp_en = 1;
> if (option->ocp_en)
> hw_param->interrupt_en |= SD_OC_INT_EN;
> - hw_param->ocp_glitch = SD_OCP_GLITCH_10M |
> SDVIO_OCP_GLITCH_800U;
> + hw_param->ocp_glitch = SD_OCP_GLITCH_100U |
> SDVIO_OCP_GLITCH_800U;
> option->sd_400mA_ocp_thd = RTS5260_DVCC_OCP_THD_550;
> option->sd_800mA_ocp_thd = RTS5260_DVCC_OCP_THD_970;
> }
> diff --git a/drivers/misc/cardreader/rtsx_pcr.c
> b/drivers/misc/cardreader/rtsx_pcr.c
> index da445223f4cc..e8072804d83a 100644
> --- a/drivers/misc/cardreader/rtsx_pcr.c
> +++ b/drivers/misc/cardreader/rtsx_pcr.c
> @@ -703,7 +703,10 @@ EXPORT_SYMBOL_GPL(rtsx_pci_card_pull_ctl_disable);
>
> static void rtsx_pci_enable_bus_int(struct rtsx_pcr *pcr)
> {
> - pcr->bier = TRANS_OK_INT_EN | TRANS_FAIL_INT_EN | SD_INT_EN;
> + struct rtsx_hw_param *hw_param = &pcr->hw_param;
> +
> + pcr->bier = TRANS_OK_INT_EN | TRANS_FAIL_INT_EN | SD_INT_EN |
> + hw_param->interrupt_en;
>
> if (pcr->num_slots > 1)
> pcr->bier |= MS_INT_EN;
> @@ -969,8 +972,19 @@ static void rtsx_pci_card_detect(struct work_struct
> *work)
>
> static void rtsx_pci_process_ocp(struct rtsx_pcr *pcr)
> {
> - if (pcr->ops->process_ocp)
> + if (pcr->ops->process_ocp) {
> pcr->ops->process_ocp(pcr);
> + } else {
> + if (!pcr->option.ocp_en)
> + return;
> + rtsx_pci_get_ocpstat(pcr, &pcr->ocp_stat);
> + if (pcr->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) {
> + rtsx_pci_card_power_off(pcr, RTSX_SD_CARD);
> + rtsx_pci_write_register(pcr, CARD_OE, SD_OUTPUT_EN, 0);
> + rtsx_pci_clear_ocpstat(pcr);
> + pcr->ocp_stat = 0;
> + }
> + }
> }
>
> static int rtsx_pci_process_ocp_interrupt(struct rtsx_pcr *pcr)
> @@ -1039,7 +1053,7 @@ static irqreturn_t rtsx_pci_isr(int irq, void *dev_id)
> }
> }
>
> - if (pcr->card_inserted || pcr->card_removed)
> + if ((pcr->card_inserted || pcr->card_removed) && !(int_reg & SD_OC_INT))
> schedule_delayed_work(&pcr->carddet_work,
> msecs_to_jiffies(200));
>
> @@ -1144,10 +1158,12 @@ void rtsx_pci_enable_ocp(struct rtsx_pcr *pcr)
> {
> u8 val = SD_OCP_INT_EN | SD_DETECT_EN;
>
> - if (pcr->ops->enable_ocp)
> + if (pcr->ops->enable_ocp) {
> pcr->ops->enable_ocp(pcr);
> - else
> + } else {
> + rtsx_pci_write_register(pcr, FPDCTL, OC_POWER_DOWN, 0);
> rtsx_pci_write_register(pcr, REG_OCPCTL, 0xFF, val);
> + }
>
> }
>
> @@ -1155,10 +1171,13 @@ void rtsx_pci_disable_ocp(struct rtsx_pcr *pcr)
> {
> u8 mask = SD_OCP_INT_EN | SD_DETECT_EN;
>
> - if (pcr->ops->disable_ocp)
> + if (pcr->ops->disable_ocp) {
> pcr->ops->disable_ocp(pcr);
> - else
> + } else {
> rtsx_pci_write_register(pcr, REG_OCPCTL, mask, 0);
> + rtsx_pci_write_register(pcr, FPDCTL, OC_POWER_DOWN,
> + OC_POWER_DOWN);
> + }
> }
>
> void rtsx_pci_init_ocp(struct rtsx_pcr *pcr)
> @@ -1169,7 +1188,7 @@ void rtsx_pci_init_ocp(struct rtsx_pcr *pcr)
> struct rtsx_cr_option *option = &(pcr->option);
>
> if (option->ocp_en) {
> - u8 val = option->sd_400mA_ocp_thd;
> + u8 val = option->sd_800mA_ocp_thd;
>
> rtsx_pci_write_register(pcr, FPDCTL, OC_POWER_DOWN, 0);
> rtsx_pci_write_register(pcr, REG_OCPPARA1,
> @@ -1204,6 +1223,7 @@ void rtsx_pci_clear_ocpstat(struct rtsx_pcr *pcr)
> u8 val = SD_OCP_INT_CLR | SD_OC_CLR;
>
> rtsx_pci_write_register(pcr, REG_OCPCTL, mask, val);
> + udelay(100);
> rtsx_pci_write_register(pcr, REG_OCPCTL, mask, 0);
> }
> }
> @@ -1313,6 +1333,8 @@ static int rtsx_pci_init_hw(struct rtsx_pcr *pcr)
> break;
> }
>
> + rtsx_pci_init_ocp(pcr);
> +
> /* Enable clk_request_n to enable clock power management */
> rtsx_pci_write_config_byte(pcr, pcr->pcie_cap + PCI_EXP_LNKCTL + 1, 1);
> /* Enter L1 when host tx idle */
> diff --git a/drivers/misc/cardreader/rtsx_pcr.h
> b/drivers/misc/cardreader/rtsx_pcr.h
> index 6ea1655db0bb..300fc31d8e67 100644
> --- a/drivers/misc/cardreader/rtsx_pcr.h
> +++ b/drivers/misc/cardreader/rtsx_pcr.h
> @@ -46,6 +46,11 @@
>
> #define SSC_CLOCK_STABLE_WAIT 130
>
> +#define RTS524A_OCP_THD_800 0x04
> +#define RTS525A_OCP_THD_800 0x05
> +#define RTS522A_OCP_THD_800 0x06
> +
> +
> int __rtsx_pci_write_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 val);
> int __rtsx_pci_read_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 *val);
>
> --
> 2.17.1
On Mon, Apr 01, 2019 at 06:40:19AM +0000, 吳昊澄 Ricky wrote:
> Dear all,
>
> May I know how is this patch going on ?
> Is it work well on your side?
> We have some guest want to know what stage is this patch going to
This patch is already in the 5.1-rc1 release, you can see it on
git.kernel.org in Linus's tree. It will be in the final 5.1 release
which should happen in a few weeks.
thanks,
greg k-h
Dear Greg k-h,
Very thanks for your reply kindly
Ricky
> -----Original Message-----
> From: [email protected] [mailto:[email protected]]
> Sent: Monday, April 01, 2019 3:04 PM
> To: 吳昊澄 Ricky
> Cc: [email protected]; [email protected]; [email protected];
> [email protected]
> Subject: Re: [PATCH v3] misc: rtsx: Enable OCP for rts522a rts524a rts525a
> rts5260
>
> On Mon, Apr 01, 2019 at 06:40:19AM +0000, 吳昊澄 Ricky wrote:
> > Dear all,
> >
> > May I know how is this patch going on ?
> > Is it work well on your side?
> > We have some guest want to know what stage is this patch going to
>
> This patch is already in the 5.1-rc1 release, you can see it on
> git.kernel.org in Linus's tree. It will be in the final 5.1 release
> which should happen in a few weeks.
>
> thanks,
>
> greg k-h
>
> ------Please consider the environment before printing this e-mail.
Dear Greg k-h,
I saw the patch is already in Linus's tree
But I found it is not my v3-patch
Can you help me to check this status kindly?
Thank you
BR,
Ricky
> -----Original Message-----
> From: [email protected] [mailto:[email protected]]
> Sent: Monday, April 01, 2019 3:04 PM
> To: 吳昊澄 Ricky
> Cc: [email protected]; [email protected]; [email protected];
> [email protected]
> Subject: Re: [PATCH v3] misc: rtsx: Enable OCP for rts522a rts524a rts525a
> rts5260
>
> On Mon, Apr 01, 2019 at 06:40:19AM +0000, 吳昊澄 Ricky wrote:
> > Dear all,
> >
> > May I know how is this patch going on ?
> > Is it work well on your side?
> > We have some guest want to know what stage is this patch going to
>
> This patch is already in the 5.1-rc1 release, you can see it on
> git.kernel.org in Linus's tree. It will be in the final 5.1 release
> which should happen in a few weeks.
>
> thanks,
>
> greg k-h
>
> ------Please consider the environment before printing this e-mail.
On Mon, Apr 01, 2019 at 08:34:44AM +0000, 吳昊澄 Ricky wrote:
> Dear Greg k-h,
>
> I saw the patch is already in Linus's tree
> But I found it is not my v3-patch
> Can you help me to check this status kindly?
I had already applied and submitted your patch when you sent the v3
patch. I can not go back in time and change it. If there is a
follow-on change that needs to be made, to bring it up to whatever your
v3 patch is, please send that so it can be applied.
thanks,
greg k-h