summaryrefslogtreecommitdiff
path: root/drivers/misc/cardreader
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/cardreader')
-rw-r--r--drivers/misc/cardreader/alcor_pci.c13
-rw-r--r--drivers/misc/cardreader/rts5264.c80
-rw-r--r--drivers/misc/cardreader/rts5264.h6
-rw-r--r--drivers/misc/cardreader/rtsx_pcr.c48
-rw-r--r--drivers/misc/cardreader/rtsx_pcr.h2
-rw-r--r--drivers/misc/cardreader/rtsx_usb.c18
6 files changed, 99 insertions, 68 deletions
diff --git a/drivers/misc/cardreader/alcor_pci.c b/drivers/misc/cardreader/alcor_pci.c
index a5549eaf52d0..8e7ea2c9142d 100644
--- a/drivers/misc/cardreader/alcor_pci.c
+++ b/drivers/misc/cardreader/alcor_pci.c
@@ -121,23 +121,23 @@ static int alcor_pci_probe(struct pci_dev *pdev,
priv->cfg = cfg;
priv->irq = pdev->irq;
- ret = pci_request_regions(pdev, DRV_NAME_ALCOR_PCI);
+ ret = pcim_request_all_regions(pdev, DRV_NAME_ALCOR_PCI);
if (ret) {
dev_err(&pdev->dev, "Cannot request region\n");
- ret = -ENOMEM;
+ ret = -EBUSY;
goto error_free_ida;
}
if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM)) {
dev_err(&pdev->dev, "BAR %d is not iomem. Aborting.\n", bar);
ret = -ENODEV;
- goto error_release_regions;
+ goto error_free_ida;
}
priv->iobase = pcim_iomap(pdev, bar, 0);
if (!priv->iobase) {
ret = -ENOMEM;
- goto error_release_regions;
+ goto error_free_ida;
}
/* make sure irqs are disabled */
@@ -147,7 +147,7 @@ static int alcor_pci_probe(struct pci_dev *pdev,
ret = dma_set_mask_and_coherent(priv->dev, AU6601_SDMA_MASK);
if (ret) {
dev_err(priv->dev, "Failed to set DMA mask\n");
- goto error_release_regions;
+ goto error_free_ida;
}
pci_set_master(pdev);
@@ -169,8 +169,6 @@ static int alcor_pci_probe(struct pci_dev *pdev,
error_clear_drvdata:
pci_clear_master(pdev);
pci_set_drvdata(pdev, NULL);
-error_release_regions:
- pci_release_regions(pdev);
error_free_ida:
ida_free(&alcor_pci_idr, priv->id);
return ret;
@@ -186,7 +184,6 @@ static void alcor_pci_remove(struct pci_dev *pdev)
ida_free(&alcor_pci_idr, priv->id);
- pci_release_regions(pdev);
pci_clear_master(pdev);
pci_set_drvdata(pdev, NULL);
}
diff --git a/drivers/misc/cardreader/rts5264.c b/drivers/misc/cardreader/rts5264.c
index 8be4ed7d9d47..d050c9fff7ac 100644
--- a/drivers/misc/cardreader/rts5264.c
+++ b/drivers/misc/cardreader/rts5264.c
@@ -413,8 +413,8 @@ static void rts5264_init_from_hw(struct rtsx_pcr *pcr)
{
struct pci_dev *pdev = pcr->pci;
u32 lval1, lval2, i;
- u16 setting_reg1, setting_reg2;
- u8 valid, efuse_valid, tmp;
+ u16 setting_reg1, setting_reg2, phy_val;
+ u8 valid, efuse_valid, tmp, efuse_len;
rtsx_pci_write_register(pcr, RTS5264_REG_PME_FORCE_CTL,
REG_EFUSE_POR | REG_EFUSE_POWER_MASK,
@@ -433,6 +433,8 @@ static void rts5264_init_from_hw(struct rtsx_pcr *pcr)
break;
}
rtsx_pci_read_register(pcr, RTS5264_EFUSE_READ_DATA, &tmp);
+ efuse_len = ((tmp & 0x70) >> 4);
+ pcr_dbg(pcr, "Load efuse len: 0x%x\n", efuse_len);
efuse_valid = ((tmp & 0x0C) >> 2);
pcr_dbg(pcr, "Load efuse valid: 0x%x\n", efuse_valid);
@@ -445,6 +447,58 @@ static void rts5264_init_from_hw(struct rtsx_pcr *pcr)
REG_EFUSE_POR, 0);
pcr_dbg(pcr, "Disable efuse por!\n");
+ if (is_version(pcr, PID_5264, RTS5264_IC_VER_B)) {
+ pci_write_config_dword(pdev, 0x718, 0x0007C000);
+ rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE, 0xFF, 0x88);
+ rtsx_pci_read_phy_register(pcr, _PHY_REV0, &phy_val);
+ phy_val &= 0xFFFD;
+
+ if (efuse_len == 0) {
+ rtsx_pci_write_register(pcr, RTS5264_FW_CFG_INFO2, 0x0F, 0x0F);
+ rtsx_pci_write_register(pcr, 0xFF14, 0xFF, 0x79);
+ rtsx_pci_write_register(pcr, 0xFF15, 0xFF, 0xFF);
+ rtsx_pci_write_register(pcr, 0xFF16, 0xFF, 0x3D);
+ rtsx_pci_write_register(pcr, 0xFF17, 0xFF, 0xFE);
+
+ rtsx_pci_write_register(pcr, 0xFF18, 0xFF, 0x5B);
+ rtsx_pci_write_register(pcr, 0xFF19, 0xFF, 0xFF);
+ rtsx_pci_write_register(pcr, 0xFF1A, 0xFF, 0x3E);
+ rtsx_pci_write_register(pcr, 0xFF1B, 0xFF, 0xFE);
+
+ rtsx_pci_write_register(pcr, 0xFF1C, 0xFF, 0x00);
+ rtsx_pci_write_register(pcr, 0xFF1D, 0xFF, 0xFF);
+ rtsx_pci_write_register(pcr, 0xFF1E, 0xFF, 0x3F);
+ rtsx_pci_write_register(pcr, 0xFF1F, 0xFF, 0xFE);
+
+ rtsx_pci_write_register(pcr, 0xFF20, 0xFF, 0x81);
+ rtsx_pci_write_register(pcr, 0xFF21, 0xFF, 0xFF);
+ rtsx_pci_write_register(pcr, 0xFF22, 0xFF, 0x3C);
+ rtsx_pci_write_register(pcr, 0xFF23, 0xFF, 0xFE);
+ }
+
+ rtsx_pci_write_register(pcr, 0xFF24, 0xFF, 0x79);
+ rtsx_pci_write_register(pcr, 0xFF25, 0xFF, 0x5B);
+ rtsx_pci_write_register(pcr, 0xFF26, 0xFF, 0x00);
+ rtsx_pci_write_register(pcr, 0xFF27, 0xFF, 0x40);
+
+ rtsx_pci_write_register(pcr, 0xFF28, 0xFF, (u8)phy_val);
+ rtsx_pci_write_register(pcr, 0xFF29, 0xFF, (u8)(phy_val >> 8));
+ rtsx_pci_write_register(pcr, 0xFF2A, 0xFF, 0x19);
+ rtsx_pci_write_register(pcr, 0xFF2B, 0xFF, 0x40);
+
+ rtsx_pci_write_register(pcr, 0xFF2C, 0xFF, 0x20);
+ rtsx_pci_write_register(pcr, 0xFF2D, 0xFF, 0xDA);
+ rtsx_pci_write_register(pcr, 0xFF2E, 0xFF, 0x0A);
+ rtsx_pci_write_register(pcr, 0xFF2F, 0xFF, 0x40);
+
+ rtsx_pci_write_register(pcr, 0xFF30, 0xFF, 0x20);
+ rtsx_pci_write_register(pcr, 0xFF31, 0xFF, 0xD2);
+ rtsx_pci_write_register(pcr, 0xFF32, 0xFF, 0x0A);
+ rtsx_pci_write_register(pcr, 0xFF33, 0xFF, 0x40);
+ } else {
+ rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE, 0x80, 0x80);
+ }
+
if (efuse_valid == 2 || efuse_valid == 3) {
if (valid == 3) {
/* Bypass efuse */
@@ -605,6 +659,25 @@ static int rts5264_extra_init_hw(struct rtsx_pcr *pcr)
return 0;
}
+static int rts5264_optimize_phy(struct rtsx_pcr *pcr)
+{
+ u16 subvendor, subdevice, val;
+
+ subvendor = pcr->pci->subsystem_vendor;
+ subdevice = pcr->pci->subsystem_device;
+
+ if ((subvendor == 0x1028) && (subdevice == 0x0CE1)) {
+ rtsx_pci_read_phy_register(pcr, _PHY_REV0, &val);
+ if ((val & 0xFE00) > 0x3800)
+ rtsx_pci_update_phy(pcr, _PHY_REV0, 0x1FF, 0x3800);
+ }
+
+ if (is_version(pcr, PID_5264, RTS5264_IC_VER_B))
+ rtsx_pci_write_phy_register(pcr, 0x00, 0x5B79);
+
+ return 0;
+}
+
static void rts5264_enable_aspm(struct rtsx_pcr *pcr, bool enable)
{
u8 val = FORCE_ASPM_CTL0 | FORCE_ASPM_CTL1;
@@ -682,6 +755,7 @@ static const struct pcr_ops rts5264_pcr_ops = {
.turn_on_led = rts5264_turn_on_led,
.turn_off_led = rts5264_turn_off_led,
.extra_init_hw = rts5264_extra_init_hw,
+ .optimize_phy = rts5264_optimize_phy,
.enable_auto_blink = rts5264_enable_auto_blink,
.disable_auto_blink = rts5264_disable_auto_blink,
.card_power_on = rts5264_card_power_on,
@@ -803,7 +877,7 @@ int rts5264_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock,
SSC_DEPTH_MASK, ssc_depth);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_DIV_N_0, 0xFF, n);
- if (is_version(pcr, 0x5264, IC_VER_A)) {
+ if (is_version(pcr, PID_5264, RTS5264_IC_VER_A)) {
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, 0);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, RTS5264_CARD_CLK_SRC2,
RTS5264_REG_BIG_KVCO_A, 0);
diff --git a/drivers/misc/cardreader/rts5264.h b/drivers/misc/cardreader/rts5264.h
index e3cbbf2fe1a4..f3e81daa708d 100644
--- a/drivers/misc/cardreader/rts5264.h
+++ b/drivers/misc/cardreader/rts5264.h
@@ -61,6 +61,8 @@
/* DMACTL 0xFE2C */
#define RTS5264_DMA_PACK_SIZE_MASK 0x70
+#define RTS5264_FW_CFG_INFO2 0xFF52
+
#define RTS5264_FW_CFG1 0xFF55
#define RTS5264_SYS_CLK_SEL_MCU_CLK (0x01<<7)
#define RTS5264_CRC_CLK_SEL_MCU_CLK (0x01<<6)
@@ -272,6 +274,10 @@
#define SD_LUN 1
#define SD_EXPRESS_LUN 2
+#define RTS5264_IC_VER_A 0
+#define RTS5264_IC_VER_B 2
+#define RTS5264_IC_VER_C 3
+
int rts5264_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock,
u8 ssc_depth, bool initial_mode, bool double_clk, bool vpclk);
diff --git a/drivers/misc/cardreader/rtsx_pcr.c b/drivers/misc/cardreader/rtsx_pcr.c
index be3d4e0e50cc..f9952d76d6ed 100644
--- a/drivers/misc/cardreader/rtsx_pcr.c
+++ b/drivers/misc/cardreader/rtsx_pcr.c
@@ -420,25 +420,6 @@ static void rtsx_pci_add_sg_tbl(struct rtsx_pcr *pcr,
pcr->sgi++;
}
-int rtsx_pci_transfer_data(struct rtsx_pcr *pcr, struct scatterlist *sglist,
- int num_sg, bool read, int timeout)
-{
- int err = 0, count;
-
- pcr_dbg(pcr, "--> %s: num_sg = %d\n", __func__, num_sg);
- count = rtsx_pci_dma_map_sg(pcr, sglist, num_sg, read);
- if (count < 1)
- return -EINVAL;
- pcr_dbg(pcr, "DMA mapping count: %d\n", count);
-
- err = rtsx_pci_dma_transfer(pcr, sglist, count, read, timeout);
-
- rtsx_pci_dma_unmap_sg(pcr, sglist, num_sg, read);
-
- return err;
-}
-EXPORT_SYMBOL_GPL(rtsx_pci_transfer_data);
-
int rtsx_pci_dma_map_sg(struct rtsx_pcr *pcr, struct scatterlist *sglist,
int num_sg, bool read)
{
@@ -1197,33 +1178,6 @@ void rtsx_pci_disable_oobs_polling(struct rtsx_pcr *pcr)
}
-int rtsx_sd_power_off_card3v3(struct rtsx_pcr *pcr)
-{
- rtsx_pci_write_register(pcr, CARD_CLK_EN, SD_CLK_EN |
- MS_CLK_EN | SD40_CLK_EN, 0);
- rtsx_pci_write_register(pcr, CARD_OE, SD_OUTPUT_EN, 0);
- rtsx_pci_card_power_off(pcr, RTSX_SD_CARD);
-
- msleep(50);
-
- rtsx_pci_card_pull_ctl_disable(pcr, RTSX_SD_CARD);
-
- return 0;
-}
-
-int rtsx_ms_power_off_card3v3(struct rtsx_pcr *pcr)
-{
- rtsx_pci_write_register(pcr, CARD_CLK_EN, SD_CLK_EN |
- MS_CLK_EN | SD40_CLK_EN, 0);
-
- rtsx_pci_card_pull_ctl_disable(pcr, RTSX_MS_CARD);
-
- rtsx_pci_write_register(pcr, CARD_OE, MS_OUTPUT_EN, 0);
- rtsx_pci_card_power_off(pcr, RTSX_MS_CARD);
-
- return 0;
-}
-
static int rtsx_pci_init_hw(struct rtsx_pcr *pcr)
{
struct pci_dev *pdev = pcr->pci;
@@ -1282,7 +1236,7 @@ static int rtsx_pci_init_hw(struct rtsx_pcr *pcr)
else if (PCI_PID(pcr) == PID_5228)
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL2, 0xFF,
RTS5228_SSC_DEPTH_2M);
- else if (is_version(pcr, 0x5264, IC_VER_A))
+ else if (is_version(pcr, PID_5264, RTS5264_IC_VER_A))
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, 0);
else if (PCI_PID(pcr) == PID_5264)
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL2, 0xFF,
diff --git a/drivers/misc/cardreader/rtsx_pcr.h b/drivers/misc/cardreader/rtsx_pcr.h
index 9215d66de00c..8e5951b61143 100644
--- a/drivers/misc/cardreader/rtsx_pcr.h
+++ b/drivers/misc/cardreader/rtsx_pcr.h
@@ -127,7 +127,5 @@ int rtsx_pci_get_ocpstat(struct rtsx_pcr *pcr, u8 *val);
void rtsx_pci_clear_ocpstat(struct rtsx_pcr *pcr);
void rtsx_pci_enable_oobs_polling(struct rtsx_pcr *pcr);
void rtsx_pci_disable_oobs_polling(struct rtsx_pcr *pcr);
-int rtsx_sd_power_off_card3v3(struct rtsx_pcr *pcr);
-int rtsx_ms_power_off_card3v3(struct rtsx_pcr *pcr);
#endif
diff --git a/drivers/misc/cardreader/rtsx_usb.c b/drivers/misc/cardreader/rtsx_usb.c
index 7314c8d9ae75..d007a4455ce5 100644
--- a/drivers/misc/cardreader/rtsx_usb.c
+++ b/drivers/misc/cardreader/rtsx_usb.c
@@ -31,7 +31,7 @@ static const struct mfd_cell rtsx_usb_cells[] = {
static void rtsx_usb_sg_timed_out(struct timer_list *t)
{
- struct rtsx_ucr *ucr = from_timer(ucr, t, sg_timer);
+ struct rtsx_ucr *ucr = timer_container_of(ucr, t, sg_timer);
dev_dbg(&ucr->pusb_intf->dev, "%s: sg transfer timed out", __func__);
usb_sg_cancel(&ucr->current_sg);
@@ -698,6 +698,12 @@ static void rtsx_usb_disconnect(struct usb_interface *intf)
}
#ifdef CONFIG_PM
+static int rtsx_usb_resume_child(struct device *dev, void *data)
+{
+ pm_request_resume(dev);
+ return 0;
+}
+
static int rtsx_usb_suspend(struct usb_interface *intf, pm_message_t message)
{
struct rtsx_ucr *ucr =
@@ -713,8 +719,10 @@ static int rtsx_usb_suspend(struct usb_interface *intf, pm_message_t message)
mutex_unlock(&ucr->dev_mutex);
/* Defer the autosuspend if card exists */
- if (val & (SD_CD | MS_CD))
+ if (val & (SD_CD | MS_CD)) {
+ device_for_each_child(&intf->dev, NULL, rtsx_usb_resume_child);
return -EAGAIN;
+ }
} else {
/* There is an ongoing operation*/
return -EAGAIN;
@@ -724,12 +732,6 @@ static int rtsx_usb_suspend(struct usb_interface *intf, pm_message_t message)
return 0;
}
-static int rtsx_usb_resume_child(struct device *dev, void *data)
-{
- pm_request_resume(dev);
- return 0;
-}
-
static int rtsx_usb_resume(struct usb_interface *intf)
{
device_for_each_child(&intf->dev, NULL, rtsx_usb_resume_child);