18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright(c) 2009 Ian Molton <spyro@f2s.com>
48c2ecf20Sopenharmony_ci */
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#include <linux/export.h>
78c2ecf20Sopenharmony_ci#include <linux/mfd/tmio.h>
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci#define CNF_CMD     0x04
108c2ecf20Sopenharmony_ci#define CNF_CTL_BASE   0x10
118c2ecf20Sopenharmony_ci#define CNF_INT_PIN  0x3d
128c2ecf20Sopenharmony_ci#define CNF_STOP_CLK_CTL 0x40
138c2ecf20Sopenharmony_ci#define CNF_GCLK_CTL 0x41
148c2ecf20Sopenharmony_ci#define CNF_SD_CLK_MODE 0x42
158c2ecf20Sopenharmony_ci#define CNF_PIN_STATUS 0x44
168c2ecf20Sopenharmony_ci#define CNF_PWR_CTL_1 0x48
178c2ecf20Sopenharmony_ci#define CNF_PWR_CTL_2 0x49
188c2ecf20Sopenharmony_ci#define CNF_PWR_CTL_3 0x4a
198c2ecf20Sopenharmony_ci#define CNF_CARD_DETECT_MODE 0x4c
208c2ecf20Sopenharmony_ci#define CNF_SD_SLOT 0x50
218c2ecf20Sopenharmony_ci#define CNF_EXT_GCLK_CTL_1 0xf0
228c2ecf20Sopenharmony_ci#define CNF_EXT_GCLK_CTL_2 0xf1
238c2ecf20Sopenharmony_ci#define CNF_EXT_GCLK_CTL_3 0xf9
248c2ecf20Sopenharmony_ci#define CNF_SD_LED_EN_1 0xfa
258c2ecf20Sopenharmony_ci#define CNF_SD_LED_EN_2 0xfe
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ci#define   SDCREN 0x2   /* Enable access to MMC CTL regs. (flag in COMMAND_REG)*/
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ciint tmio_core_mmc_enable(void __iomem *cnf, int shift, unsigned long base)
308c2ecf20Sopenharmony_ci{
318c2ecf20Sopenharmony_ci	/* Enable the MMC/SD Control registers */
328c2ecf20Sopenharmony_ci	sd_config_write16(cnf, shift, CNF_CMD, SDCREN);
338c2ecf20Sopenharmony_ci	sd_config_write32(cnf, shift, CNF_CTL_BASE, base & 0xfffe);
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci	/* Disable SD power during suspend */
368c2ecf20Sopenharmony_ci	sd_config_write8(cnf, shift, CNF_PWR_CTL_3, 0x01);
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_ci	/* The below is required but why? FIXME */
398c2ecf20Sopenharmony_ci	sd_config_write8(cnf, shift, CNF_STOP_CLK_CTL, 0x1f);
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ci	/* Power down SD bus */
428c2ecf20Sopenharmony_ci	sd_config_write8(cnf, shift, CNF_PWR_CTL_2, 0x00);
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci	return 0;
458c2ecf20Sopenharmony_ci}
468c2ecf20Sopenharmony_ciEXPORT_SYMBOL(tmio_core_mmc_enable);
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ciint tmio_core_mmc_resume(void __iomem *cnf, int shift, unsigned long base)
498c2ecf20Sopenharmony_ci{
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci	/* Enable the MMC/SD Control registers */
528c2ecf20Sopenharmony_ci	sd_config_write16(cnf, shift, CNF_CMD, SDCREN);
538c2ecf20Sopenharmony_ci	sd_config_write32(cnf, shift, CNF_CTL_BASE, base & 0xfffe);
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci	return 0;
568c2ecf20Sopenharmony_ci}
578c2ecf20Sopenharmony_ciEXPORT_SYMBOL(tmio_core_mmc_resume);
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_civoid tmio_core_mmc_pwr(void __iomem *cnf, int shift, int state)
608c2ecf20Sopenharmony_ci{
618c2ecf20Sopenharmony_ci	sd_config_write8(cnf, shift, CNF_PWR_CTL_2, state ? 0x02 : 0x00);
628c2ecf20Sopenharmony_ci}
638c2ecf20Sopenharmony_ciEXPORT_SYMBOL(tmio_core_mmc_pwr);
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_civoid tmio_core_mmc_clk_div(void __iomem *cnf, int shift, int state)
668c2ecf20Sopenharmony_ci{
678c2ecf20Sopenharmony_ci	sd_config_write8(cnf, shift, CNF_SD_CLK_MODE, state ? 1 : 0);
688c2ecf20Sopenharmony_ci}
698c2ecf20Sopenharmony_ciEXPORT_SYMBOL(tmio_core_mmc_clk_div);
708c2ecf20Sopenharmony_ci
71