int __rtsx_pci_write_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 val) { int err, i, finished = 0; u8 tmp; rtsx_pci_init_cmd(pcr); rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PHYDATA0, 0xFF, (u8)val); rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PHYDATA1, 0xFF, (u8)(val >> 8)); rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PHYADDR, 0xFF, addr); rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PHYRWCTL, 0xFF, 0x81); err = rtsx_pci_send_cmd(pcr, 100); if (err < 0) return err; for (i = 0; i < 100000; i++) { err = rtsx_pci_read_register(pcr, PHYRWCTL, &tmp); if (err < 0) return err; if (!(tmp & 0x80)) { finished = 1; break; } } if (!finished) return -ETIMEDOUT; return 0; }
static u8 rts5229_get_ic_version(struct rtsx_pcr *pcr) { u8 val; rtsx_pci_read_register(pcr, 0xFE90, &val); return val & 0x0F; }
static int rtl8411b_is_qfn48(struct rtsx_pcr *pcr) { u8 val = 0; rtsx_pci_read_register(pcr, RTL8411B_PACKAGE_MODE, &val); if (val & 0x2) return 1; else return 0; }
static void sd_wait_data_idle(struct realtek_pci_sdmmc *host) { int err, i; u8 val = 0; for (i = 0; i < 100; i++) { err = rtsx_pci_read_register(host->pcr, SD_DATA_STATE, &val); if (val & SD_DATA_IDLE) return; udelay(100); } }
int rtsx_pci_read_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 *val) { int err, i, finished = 0; u16 data; u8 *ptr, tmp; rtsx_pci_init_cmd(pcr); rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PHYADDR, 0xFF, addr); rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PHYRWCTL, 0xFF, 0x80); err = rtsx_pci_send_cmd(pcr, 100); if (err < 0) return err; for (i = 0; i < 100000; i++) { err = rtsx_pci_read_register(pcr, PHYRWCTL, &tmp); if (err < 0) return err; if (!(tmp & 0x80)) { finished = 1; break; } } if (!finished) return -ETIMEDOUT; rtsx_pci_init_cmd(pcr); rtsx_pci_add_cmd(pcr, READ_REG_CMD, PHYDATA0, 0, 0); rtsx_pci_add_cmd(pcr, READ_REG_CMD, PHYDATA1, 0, 0); err = rtsx_pci_send_cmd(pcr, 100); if (err < 0) return err; ptr = rtsx_pci_get_cmd_data(pcr); data = ((u16)ptr[1] << 8) | ptr[0]; if (val) *val = data; return 0; }
static int ms_read_bytes(struct realtek_pci_ms *host, u8 tpc, u8 cfg, u8 cnt, u8 *data, u8 *int_reg) { struct rtsx_pcr *pcr = host->pcr; int err, i; u8 *ptr; dev_dbg(ms_dev(host), "%s: tpc = 0x%02x\n", __func__, tpc); if (!data) return -EINVAL; rtsx_pci_init_cmd(pcr); rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TPC, 0xFF, tpc); rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_BYTE_CNT, 0xFF, cnt); rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg); rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER); rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TRANSFER, 0xFF, MS_TRANSFER_START | MS_TM_READ_BYTES); rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, MS_TRANSFER, MS_TRANSFER_END, MS_TRANSFER_END); for (i = 0; i < cnt - 1; i++) rtsx_pci_add_cmd(pcr, READ_REG_CMD, PPBUF_BASE2 + i, 0, 0); if (cnt % 2) rtsx_pci_add_cmd(pcr, READ_REG_CMD, PPBUF_BASE2 + cnt, 0, 0); else rtsx_pci_add_cmd(pcr, READ_REG_CMD, PPBUF_BASE2 + cnt - 1, 0, 0); if (int_reg) rtsx_pci_add_cmd(pcr, READ_REG_CMD, MS_TRANS_CFG, 0, 0); err = rtsx_pci_send_cmd(pcr, 5000); if (err < 0) { u8 val; rtsx_pci_read_register(pcr, MS_TRANS_CFG, &val); dev_dbg(ms_dev(host), "MS_TRANS_CFG: 0x%02x\n", val); if (int_reg) *int_reg = val & 0x0F; ms_print_debug_regs(host); ms_clear_error(host); if (!(tpc & 0x08)) { if (val & MS_CRC16_ERR) return -EIO; } else { if (!(val & 0x80)) { if (val & (MS_INT_ERR | MS_INT_CMDNK)) return -EIO; } } return -ETIMEDOUT; } ptr = rtsx_pci_get_cmd_data(pcr) + 1; for (i = 0; i < cnt; i++) data[i] = *ptr++; if (int_reg) *int_reg = *ptr & 0x0F; return 0; }
static int ms_transfer_data(struct realtek_pci_ms *host, unsigned char data_dir, u8 tpc, u8 cfg, struct scatterlist *sg) { struct rtsx_pcr *pcr = host->pcr; int err; unsigned int length = sg->length; u16 sec_cnt = (u16)(length / 512); u8 val, trans_mode, dma_dir; struct memstick_dev *card = host->msh->card; bool pro_card = card->id.type == MEMSTICK_TYPE_PRO; dev_dbg(ms_dev(host), "%s: tpc = 0x%02x, data_dir = %s, length = %d\n", __func__, tpc, (data_dir == READ) ? "READ" : "WRITE", length); if (data_dir == READ) { dma_dir = DMA_DIR_FROM_CARD; trans_mode = pro_card ? MS_TM_AUTO_READ : MS_TM_NORMAL_READ; } else { dma_dir = DMA_DIR_TO_CARD; trans_mode = pro_card ? MS_TM_AUTO_WRITE : MS_TM_NORMAL_WRITE; } rtsx_pci_init_cmd(pcr); rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TPC, 0xFF, tpc); if (pro_card) { rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_SECTOR_CNT_H, 0xFF, (u8)(sec_cnt >> 8)); rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_SECTOR_CNT_L, 0xFF, (u8)sec_cnt); } rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg); rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, IRQSTAT0, DMA_DONE_INT, DMA_DONE_INT); rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC3, 0xFF, (u8)(length >> 24)); rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC2, 0xFF, (u8)(length >> 16)); rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC1, 0xFF, (u8)(length >> 8)); rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC0, 0xFF, (u8)length); rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMACTL, 0x03 | DMA_PACK_SIZE_MASK, dma_dir | DMA_EN | DMA_512); rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TRANSFER, 0xFF, MS_TRANSFER_START | trans_mode); rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, MS_TRANSFER, MS_TRANSFER_END, MS_TRANSFER_END); rtsx_pci_send_cmd_no_wait(pcr); err = rtsx_pci_transfer_data(pcr, sg, 1, data_dir == READ, 10000); if (err < 0) { ms_clear_error(host); return err; } rtsx_pci_read_register(pcr, MS_TRANS_CFG, &val); if (pro_card) { if (val & (MS_INT_CMDNK | MS_INT_ERR | MS_CRC16_ERR | MS_RDY_TIMEOUT)) return -EIO; } else { if (val & (MS_CRC16_ERR | MS_RDY_TIMEOUT)) return -EIO; } return 0; }
static int rts5260_get_ocpstat2(struct rtsx_pcr *pcr, u8 *val) { return rtsx_pci_read_register(pcr, REG_DV3318_OCPSTAT, val); }