0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/delay.h>
0014 #include <linux/device.h>
0015 #include <linux/mfd/core.h>
0016 #include <linux/mfd/tmio.h>
0017 #include <linux/mmc/host.h>
0018 #include <linux/module.h>
0019 #include <linux/pagemap.h>
0020 #include <linux/scatterlist.h>
0021
0022 #include "tmio_mmc.h"
0023
0024
0025 #define CTL_SDIO_REGS 0x100
0026 #define CTL_CLK_AND_WAIT_CTL 0x138
0027 #define CTL_RESET_SDIO 0x1e0
0028
0029 static void tmio_mmc_clk_start(struct tmio_mmc_host *host)
0030 {
0031 sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, CLK_CTL_SCLKEN |
0032 sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
0033
0034 usleep_range(10000, 11000);
0035 sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0100);
0036 usleep_range(10000, 11000);
0037 }
0038
0039 static void tmio_mmc_clk_stop(struct tmio_mmc_host *host)
0040 {
0041 sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0000);
0042 usleep_range(10000, 11000);
0043
0044 sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN &
0045 sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
0046
0047 usleep_range(10000, 11000);
0048 }
0049
0050 static void tmio_mmc_set_clock(struct tmio_mmc_host *host,
0051 unsigned int new_clock)
0052 {
0053 unsigned int divisor;
0054 u32 clk = 0;
0055 int clk_sel;
0056
0057 if (new_clock == 0) {
0058 tmio_mmc_clk_stop(host);
0059 return;
0060 }
0061
0062 divisor = host->pdata->hclk / new_clock;
0063
0064
0065 clk_sel = (divisor <= 1);
0066 clk = clk_sel ? 0 : (roundup_pow_of_two(divisor) >> 2);
0067
0068 host->pdata->set_clk_div(host->pdev, clk_sel);
0069
0070 sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN &
0071 sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
0072 sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, clk & CLK_CTL_DIV_MASK);
0073 usleep_range(10000, 11000);
0074
0075 tmio_mmc_clk_start(host);
0076 }
0077
0078 static void tmio_mmc_reset(struct tmio_mmc_host *host, bool preserve)
0079 {
0080 sd_ctrl_write16(host, CTL_RESET_SDIO, 0x0000);
0081 usleep_range(10000, 11000);
0082 sd_ctrl_write16(host, CTL_RESET_SDIO, 0x0001);
0083 usleep_range(10000, 11000);
0084 }
0085
0086 #ifdef CONFIG_PM_SLEEP
0087 static int tmio_mmc_suspend(struct device *dev)
0088 {
0089 struct platform_device *pdev = to_platform_device(dev);
0090 const struct mfd_cell *cell = mfd_get_cell(pdev);
0091 int ret;
0092
0093 ret = pm_runtime_force_suspend(dev);
0094
0095
0096 if (!ret && cell->disable)
0097 cell->disable(pdev);
0098
0099 return ret;
0100 }
0101
0102 static int tmio_mmc_resume(struct device *dev)
0103 {
0104 struct platform_device *pdev = to_platform_device(dev);
0105 const struct mfd_cell *cell = mfd_get_cell(pdev);
0106 int ret = 0;
0107
0108
0109 if (cell->resume)
0110 ret = cell->resume(pdev);
0111
0112 if (!ret)
0113 ret = pm_runtime_force_resume(dev);
0114
0115 return ret;
0116 }
0117 #endif
0118
0119 static int tmio_mmc_probe(struct platform_device *pdev)
0120 {
0121 const struct mfd_cell *cell = mfd_get_cell(pdev);
0122 struct tmio_mmc_data *pdata;
0123 struct tmio_mmc_host *host;
0124 struct resource *res;
0125 int ret = -EINVAL, irq;
0126
0127 if (pdev->num_resources != 2)
0128 goto out;
0129
0130 pdata = pdev->dev.platform_data;
0131 if (!pdata || !pdata->hclk)
0132 goto out;
0133
0134 irq = platform_get_irq(pdev, 0);
0135 if (irq < 0) {
0136 ret = irq;
0137 goto out;
0138 }
0139
0140
0141 if (cell->enable) {
0142 ret = cell->enable(pdev);
0143 if (ret)
0144 goto out;
0145 }
0146
0147 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0148 if (!res) {
0149 ret = -EINVAL;
0150 goto cell_disable;
0151 }
0152
0153 host = tmio_mmc_host_alloc(pdev, pdata);
0154 if (IS_ERR(host)) {
0155 ret = PTR_ERR(host);
0156 goto cell_disable;
0157 }
0158
0159
0160 host->bus_shift = resource_size(res) >> 10;
0161 host->set_clock = tmio_mmc_set_clock;
0162 host->reset = tmio_mmc_reset;
0163
0164 host->mmc->f_max = pdata->hclk;
0165 host->mmc->f_min = pdata->hclk / 512;
0166
0167 ret = tmio_mmc_host_probe(host);
0168 if (ret)
0169 goto host_free;
0170
0171 ret = devm_request_irq(&pdev->dev, irq, tmio_mmc_irq,
0172 IRQF_TRIGGER_FALLING,
0173 dev_name(&pdev->dev), host);
0174 if (ret)
0175 goto host_remove;
0176
0177 pr_info("%s at 0x%p irq %d\n", mmc_hostname(host->mmc), host->ctl, irq);
0178
0179 return 0;
0180
0181 host_remove:
0182 tmio_mmc_host_remove(host);
0183 host_free:
0184 tmio_mmc_host_free(host);
0185 cell_disable:
0186 if (cell->disable)
0187 cell->disable(pdev);
0188 out:
0189 return ret;
0190 }
0191
0192 static int tmio_mmc_remove(struct platform_device *pdev)
0193 {
0194 const struct mfd_cell *cell = mfd_get_cell(pdev);
0195 struct tmio_mmc_host *host = platform_get_drvdata(pdev);
0196
0197 tmio_mmc_host_remove(host);
0198 if (cell->disable)
0199 cell->disable(pdev);
0200
0201 return 0;
0202 }
0203
0204
0205
0206 static const struct dev_pm_ops tmio_mmc_dev_pm_ops = {
0207 SET_SYSTEM_SLEEP_PM_OPS(tmio_mmc_suspend, tmio_mmc_resume)
0208 SET_RUNTIME_PM_OPS(tmio_mmc_host_runtime_suspend,
0209 tmio_mmc_host_runtime_resume, NULL)
0210 };
0211
0212 static struct platform_driver tmio_mmc_driver = {
0213 .driver = {
0214 .name = "tmio-mmc",
0215 .probe_type = PROBE_PREFER_ASYNCHRONOUS,
0216 .pm = &tmio_mmc_dev_pm_ops,
0217 },
0218 .probe = tmio_mmc_probe,
0219 .remove = tmio_mmc_remove,
0220 };
0221
0222 module_platform_driver(tmio_mmc_driver);
0223
0224 MODULE_DESCRIPTION("Toshiba TMIO SD/MMC driver");
0225 MODULE_AUTHOR("Ian Molton <spyro@f2s.com>");
0226 MODULE_LICENSE("GPL v2");
0227 MODULE_ALIAS("platform:tmio-mmc");