1
0
Files
kernel-49/arch/mips/rt2880/dev-mmc.c
Andrey Zolotarev 92b41e38d1 arch: mips: add support SoC mt7621 & mt7628, case 13803
Based on Ralink/MTK SDK.
2019-02-08 17:26:04 +03:00

109 lines
2.3 KiB
C

#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <asm/irq.h>
#include <asm/rt2880/rt_mmap.h>
#include <ralink/mtk_mmc_dev.h>
#define MTK_SDXC_MEM_START RALINK_MSDC_BASE
static struct resource mtk_mmc_resources[] = {
[0] = {
.start = MTK_SDXC_MEM_START,
.end = MTK_SDXC_MEM_START + 0x3fff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = SURFBOARDINT_SDXC,
.flags = IORESOURCE_IRQ,
},
};
#define CLKCFG1_REG (RALINK_SYSCTL_BASE + 0x30)
#define RSTCTRL_REG (RALINK_SYSCTL_BASE + 0x34)
static void mtk_mmc_power_on(void)
{
u32 val;
/* enable SDXC clock */
val = le32_to_cpu(*(volatile u32 *)(CLKCFG1_REG));
val |= (RALINK_SDXC_CLK_EN);
*(volatile u32 *)(CLKCFG1_REG) = cpu_to_le32(val);
mdelay(1);
/* release SDXC reset */
val = le32_to_cpu(*(volatile u32 *)(RSTCTRL_REG));
val &= ~(RALINK_SDXC_RST);
*(volatile u32 *)(RSTCTRL_REG) = cpu_to_le32(val);
mdelay(10);
}
static void mtk_mmc_power_off(void)
{
u32 val;
/* raise SDXC reset */
val = le32_to_cpu(*(volatile u32 *)(RSTCTRL_REG));
val |= (RALINK_SDXC_RST);
*(volatile u32 *)(RSTCTRL_REG) = cpu_to_le32(val);
udelay(100);
/* disable SDXC clock */
val = le32_to_cpu(*(volatile u32 *)(CLKCFG1_REG));
val &= ~(RALINK_SDXC_CLK_EN);
*(volatile u32 *)(CLKCFG1_REG) = cpu_to_le32(val);
}
static struct msdc_hw mtk_mmc_hw = {
.clk_src = 0,
.cmd_edge = MSDC_SMPL_FALLING,
.data_edge = MSDC_SMPL_FALLING,
.crc_edge = MSDC_SMPL_FALLING,
.clk_drv = 4,
.cmd_drv = 4,
.dat_drv = 4,
#if defined(CONFIG_MTK_MMC_EMMC_8BIT)
.data_pins = 8,
#else
.data_pins = 4,
#endif
.flags = MSDC_SYS_SUSPEND | MSDC_WP_PIN_EN | MSDC_CD_PIN_EN | MSDC_REMOVABLE | MSDC_HIGHSPEED,
.ext_power_on = mtk_mmc_power_on,
.ext_power_off = mtk_mmc_power_off,
};
static struct platform_device mtk_mmc_device = {
.name = MMC_DRV_NAME,
.id = 0,
.dev = {
.platform_data = &mtk_mmc_hw,
},
.num_resources = ARRAY_SIZE(mtk_mmc_resources),
.resource = mtk_mmc_resources,
};
int __init init_mtk_mmc(void)
{
int retval = 0;
retval = platform_device_register(&mtk_mmc_device);
if (retval != 0) {
printk(KERN_ERR "register %s device fail!\n", "MMC");
return retval;
}
return retval;
}
device_initcall(init_mtk_mmc);