static unsigned int rtl8411_cd_deglitch(struct rtsx_pcr *pcr) { unsigned int card_exist; card_exist = rtsx_pci_readl(pcr, RTSX_BIPR); card_exist &= CARD_EXIST; if (!card_exist) { /* Enable card CD */ rtsx_pci_write_register(pcr, CD_PAD_CTL, CD_DISABLE_MASK, CD_ENABLE); /* Enable card interrupt */ rtsx_pci_write_register(pcr, EFUSE_CONTENT, 0xe0, 0x00); return 0; } if (hweight32(card_exist) > 1) { rtsx_pci_write_register(pcr, CARD_PWR_CTL, BPP_POWER_MASK, BPP_POWER_5_PERCENT_ON); msleep(100); card_exist = rtsx_pci_readl(pcr, RTSX_BIPR); if (card_exist & MS_EXIST) card_exist = MS_EXIST; else if (card_exist & SD_EXIST) card_exist = SD_EXIST; else card_exist = 0; rtsx_pci_write_register(pcr, CARD_PWR_CTL, BPP_POWER_MASK, BPP_POWER_OFF); dev_dbg(&(pcr->pci->dev), "After CD deglitch, card_exist = 0x%x\n", card_exist); } if (card_exist & MS_EXIST) { /* Disable SD interrupt */ rtsx_pci_write_register(pcr, EFUSE_CONTENT, 0xe0, 0x40); rtsx_pci_write_register(pcr, CD_PAD_CTL, CD_DISABLE_MASK, MS_CD_EN_ONLY); } else if (card_exist & SD_EXIST) { /* Disable MS interrupt */ rtsx_pci_write_register(pcr, EFUSE_CONTENT, 0xe0, 0x80); rtsx_pci_write_register(pcr, CD_PAD_CTL, CD_DISABLE_MASK, SD_CD_EN_ONLY); } return card_exist; }
static void rts5250_set_l1off_cfg_sub_d0(struct rtsx_pcr *pcr, int active) { struct rtsx_cr_option *option = &(pcr->option); u32 interrupt = rtsx_pci_readl(pcr, RTSX_BIPR); int card_exist = (interrupt & SD_EXIST) | (interrupt & MS_EXIST); int aspm_L1_1, aspm_L1_2; u8 val = 0; aspm_L1_1 = rtsx_check_dev_flag(pcr, ASPM_L1_1_EN); aspm_L1_2 = rtsx_check_dev_flag(pcr, ASPM_L1_2_EN); if (active) { /* Run, latency: 60us */ if (aspm_L1_1) val = option->ltr_l1off_snooze_sspwrgate; } else { /* L1off, latency: 300us */ if (aspm_L1_2) val = option->ltr_l1off_sspwrgate; } if (aspm_L1_1 || aspm_L1_2) { if (rtsx_check_dev_flag(pcr, LTR_L1SS_PWR_GATE_CHECK_CARD_EN)) { if (card_exist) val &= ~L1OFF_MBIAS2_EN_5250; else val |= L1OFF_MBIAS2_EN_5250; } } rtsx_set_l1off_sub(pcr, val); }
int rtsx_pci_write_register(struct rtsx_pcr *pcr, u16 addr, u8 mask, u8 data) { int i; u32 val = HAIMR_WRITE_START; val |= (u32)(addr & 0x3FFF) << 16; val |= (u32)mask << 8; val |= (u32)data; rtsx_pci_writel(pcr, RTSX_HAIMR, val); for (i = 0; i < MAX_RW_REG_CNT; i++) { val = rtsx_pci_readl(pcr, RTSX_HAIMR); if ((val & HAIMR_TRANS_END) == 0) { if (data != (u8)val) return -EIO; return 0; } } return -ETIMEDOUT; }
int rtsx_pci_read_register(struct rtsx_pcr *pcr, u16 addr, u8 *data) { u32 val = HAIMR_READ_START; int i; val |= (u32)(addr & 0x3FFF) << 16; rtsx_pci_writel(pcr, RTSX_HAIMR, val); for (i = 0; i < MAX_RW_REG_CNT; i++) { val = rtsx_pci_readl(pcr, RTSX_HAIMR); if ((val & HAIMR_TRANS_END) == 0) break; } if (i >= MAX_RW_REG_CNT) return -ETIMEDOUT; if (data) *data = (u8)(val & 0xFF); return 0; }