19 #include <linux/module.h>
20 #include <linux/slab.h>
32 #define SDHCI_CTRL_D3CD 0x08
34 #define SDHCI_VENDOR_SPEC 0xC0
35 #define SDHCI_VENDOR_SPEC_SDIO_QUIRK 0x00000002
36 #define SDHCI_WTMK_LVL 0x44
37 #define SDHCI_MIX_CTRL 0x48
45 #define SDHCI_INT_VENDOR_SPEC_DMA_ERR 0x10000000
58 #define ESDHC_FLAG_MULTIBLK_NO_INT (1 << 1)
81 .name =
"sdhci-esdhc-imx25",
84 .name =
"sdhci-esdhc-imx35",
87 .name =
"sdhci-esdhc-imx51",
90 .name =
"sdhci-esdhc-imx53",
93 .name =
"sdhci-usdhc-imx6q",
102 { .compatible =
"fsl,imx25-esdhc", .data = &imx_esdhc_devtype[
IMX25_ESDHC], },
103 { .compatible =
"fsl,imx35-esdhc", .data = &imx_esdhc_devtype[
IMX35_ESDHC], },
104 { .compatible =
"fsl,imx51-esdhc", .data = &imx_esdhc_devtype[
IMX51_ESDHC], },
105 { .compatible =
"fsl,imx53-esdhc", .data = &imx_esdhc_devtype[
IMX53_ESDHC], },
106 { .compatible =
"fsl,imx6q-usdhc", .data = &imx_esdhc_devtype[
IMX6Q_USDHC], },
139 u32 shift = (reg & 0x3) * 8;
141 writel(((
readl(base) & ~(mask << shift)) | (val << shift)), base);
154 && gpio_is_valid(boarddata->
cd_gpio))) {
172 val &= ~SDHCI_CAN_DO_ADMA1;
179 val &= ~SDHCI_INT_VENDOR_SPEC_DMA_ERR;
187 static void esdhc_writel_le(
struct sdhci_host *host,
u32 val,
int reg)
230 val &= ~SDHCI_INT_ADMA_ERROR;
254 static void esdhc_writew_le(
struct sdhci_host *host,
u16 val,
int reg)
267 && (host->
cmd->data->blocks > 1)
282 if (is_imx6q_usdhc(imx_data)) {
297 esdhc_clrset_le(host, 0xffff, val, reg);
300 static void esdhc_writeb_le(
struct sdhci_host *host,
u8 val,
int reg)
316 SDHCI_CTRL_4BITBUS | \
321 if (!is_imx25_esdhc(imx_data)) {
326 esdhc_clrset_le(host, 0xffff, new_val, reg);
329 esdhc_clrset_le(host, 0xff, val, reg);
343 static unsigned int esdhc_pltfm_get_max_clock(
struct sdhci_host *host)
350 static unsigned int esdhc_pltfm_get_min_clock(
struct sdhci_host *host)
357 static unsigned int esdhc_pltfm_get_ro(
struct sdhci_host *host)
365 if (gpio_is_valid(boarddata->
wp_gpio))
377 static struct sdhci_ops sdhci_esdhc_ops = {
378 .read_l = esdhc_readl_le,
379 .read_w = esdhc_readw_le,
380 .write_l = esdhc_writel_le,
381 .write_w = esdhc_writew_le,
382 .write_b = esdhc_writeb_le,
383 .set_clock = esdhc_set_clock,
384 .get_max_clock = esdhc_pltfm_get_max_clock,
385 .get_min_clock = esdhc_pltfm_get_min_clock,
386 .get_ro = esdhc_pltfm_get_ro,
394 .ops = &sdhci_esdhc_ops,
424 boarddata->
cd_gpio = of_get_named_gpio(np,
"cd-gpios", 0);
425 if (gpio_is_valid(boarddata->
cd_gpio))
428 boarddata->
wp_gpio = of_get_named_gpio(np,
"wp-gpios", 0);
429 if (gpio_is_valid(boarddata->
wp_gpio))
455 return PTR_ERR(host);
457 pltfm_host = sdhci_priv(host);
468 pltfm_host->
priv = imx_data;
471 if (IS_ERR(imx_data->
clk_ipg)) {
472 err = PTR_ERR(imx_data->
clk_ipg);
477 if (IS_ERR(imx_data->
clk_ahb)) {
478 err = PTR_ERR(imx_data->
clk_ahb);
483 if (IS_ERR(imx_data->
clk_per)) {
484 err = PTR_ERR(imx_data->
clk_per);
490 clk_prepare_enable(imx_data->
clk_per);
491 clk_prepare_enable(imx_data->
clk_ipg);
492 clk_prepare_enable(imx_data->
clk_ahb);
494 imx_data->
pinctrl = devm_pinctrl_get_select_default(&pdev->
dev);
495 if (IS_ERR(imx_data->
pinctrl)) {
496 err = PTR_ERR(imx_data->
pinctrl);
502 if (is_imx25_esdhc(imx_data) || is_imx35_esdhc(imx_data))
507 if (is_imx53_esdhc(imx_data))
514 if (is_imx6q_usdhc(imx_data))
518 if (sdhci_esdhc_imx_probe_dt(pdev, boarddata) < 0) {
519 if (!host->
mmc->parent->platform_data) {
525 host->
mmc->parent->platform_data);
533 "no write-protect pin available!\n");
549 "no card-detect pin available!\n");
550 goto no_card_detect_pin;
558 goto no_card_detect_irq;
582 if (gpio_is_valid(boarddata->
cd_gpio))
585 if (gpio_is_valid(boarddata->
cd_gpio))
587 if (gpio_is_valid(boarddata->
wp_gpio))
592 clk_disable_unprepare(imx_data->
clk_per);
593 clk_disable_unprepare(imx_data->
clk_ipg);
594 clk_disable_unprepare(imx_data->
clk_ahb);
604 struct sdhci_host *host = platform_get_drvdata(pdev);
612 if (gpio_is_valid(boarddata->
wp_gpio))
615 if (gpio_is_valid(boarddata->
cd_gpio)) {
620 clk_disable_unprepare(imx_data->
clk_per);
621 clk_disable_unprepare(imx_data->
clk_ipg);
622 clk_disable_unprepare(imx_data->
clk_ahb);
633 .name =
"sdhci-esdhc-imx",
635 .of_match_table = imx_esdhc_dt_ids,
638 .id_table = imx_esdhc_devtype,
639 .probe = sdhci_esdhc_imx_probe,