mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2026-06-13 15:03:58 +03:00
Merge tag 'mmc-power-2025-10-30' of https://source.denx.de/u-boot/custodians/u-boot-mmc
CI: https://source.denx.de/u-boot/custodians/u-boot-mmc/-/pipelines/28083 - Add support for Samsung Exynos 7870 DW-MMC device - Add support for Samsung S2MPU05 PMIC device - Add compatible string for Exynos5250 in Exynos DW-MMC driver - Add support for handling UHS-I voltage signaling without power-cycle - Minor misc cleanup
This commit is contained in:
@@ -419,6 +419,10 @@ static int dwmci_send_cmd_common(struct dwmci_host *host, struct mmc_cmd *cmd,
|
||||
if (cmd->resp_type & MMC_RSP_CRC)
|
||||
flags |= DWMCI_CMD_CHECK_CRC;
|
||||
|
||||
host->volt_switching = (cmd->cmdidx == SD_CMD_SWITCH_UHS18V);
|
||||
if (host->volt_switching)
|
||||
flags |= DWMCI_CMD_VOLT_SWITCH;
|
||||
|
||||
flags |= cmd->cmdidx | DWMCI_CMD_START | DWMCI_CMD_USE_HOLD_REG;
|
||||
|
||||
debug("Sending CMD%d\n", cmd->cmdidx);
|
||||
@@ -427,6 +431,10 @@ static int dwmci_send_cmd_common(struct dwmci_host *host, struct mmc_cmd *cmd,
|
||||
|
||||
for (i = 0; i < retry; i++) {
|
||||
mask = dwmci_readl(host, DWMCI_RINTSTS);
|
||||
if (host->volt_switching && (mask & DWMCI_INTMSK_VOLTSW)) {
|
||||
dwmci_writel(host, DWMCI_RINTSTS, DWMCI_INTMSK_VOLTSW);
|
||||
break;
|
||||
}
|
||||
if (mask & DWMCI_INTMSK_CDONE) {
|
||||
if (!data)
|
||||
dwmci_writel(host, DWMCI_RINTSTS, mask);
|
||||
@@ -482,8 +490,8 @@ static int dwmci_send_cmd_common(struct dwmci_host *host, struct mmc_cmd *cmd,
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DM_MMC
|
||||
static int dwmci_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
|
||||
struct mmc_data *data)
|
||||
int dwmci_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
|
||||
struct mmc_data *data)
|
||||
{
|
||||
struct mmc *mmc = mmc_get_mmc_dev(dev);
|
||||
#else
|
||||
@@ -507,20 +515,24 @@ static int dwmci_control_clken(struct dwmci_host *host, bool on)
|
||||
{
|
||||
const u32 val = on ? DWMCI_CLKEN_ENABLE | DWMCI_CLKEN_LOW_PWR : 0;
|
||||
const u32 cmd_only_clk = DWMCI_CMD_PRV_DAT_WAIT | DWMCI_CMD_UPD_CLK;
|
||||
int timeout = 10000;
|
||||
u32 status;
|
||||
int i, timeout = 10000;
|
||||
u32 flags, mask;
|
||||
|
||||
dwmci_writel(host, DWMCI_CLKENA, val);
|
||||
|
||||
/* Inform CIU */
|
||||
dwmci_writel(host, DWMCI_CMD, DWMCI_CMD_START | cmd_only_clk);
|
||||
do {
|
||||
status = dwmci_readl(host, DWMCI_CMD);
|
||||
if (timeout-- < 0) {
|
||||
debug("%s: Timeout!\n", __func__);
|
||||
return -ETIMEDOUT;
|
||||
flags = DWMCI_CMD_START | cmd_only_clk;
|
||||
if (host->volt_switching)
|
||||
flags |= DWMCI_CMD_VOLT_SWITCH;
|
||||
dwmci_writel(host, DWMCI_CMD, flags);
|
||||
|
||||
for (i = 0; i < timeout; i++) {
|
||||
mask = dwmci_readl(host, DWMCI_RINTSTS);
|
||||
if (mask & DWMCI_INTMSK_CDONE) {
|
||||
dwmci_writel(host, DWMCI_RINTSTS, DWMCI_INTMSK_CDONE);
|
||||
break;
|
||||
}
|
||||
} while (status & DWMCI_CMD_START);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -554,7 +566,7 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq)
|
||||
unsigned long sclk;
|
||||
int ret;
|
||||
|
||||
if (freq == host->clock || freq == 0)
|
||||
if (!freq)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
@@ -585,7 +597,7 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DM_MMC
|
||||
static int dwmci_set_ios(struct udevice *dev)
|
||||
int dwmci_set_ios(struct udevice *dev)
|
||||
{
|
||||
struct mmc *mmc = mmc_get_mmc_dev(dev);
|
||||
#else
|
||||
@@ -632,17 +644,11 @@ static int dwmci_set_ios(struct mmc *mmc)
|
||||
if (mmc->vqmmc_supply) {
|
||||
int ret;
|
||||
|
||||
ret = regulator_set_enable_if_allowed(mmc->vqmmc_supply, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (mmc->signal_voltage == MMC_SIGNAL_VOLTAGE_180)
|
||||
regulator_set_value(mmc->vqmmc_supply, 1800000);
|
||||
ret = regulator_set_value(mmc->vqmmc_supply, 1800000);
|
||||
else
|
||||
regulator_set_value(mmc->vqmmc_supply, 3300000);
|
||||
|
||||
ret = regulator_set_enable_if_allowed(mmc->vqmmc_supply, true);
|
||||
if (ret)
|
||||
ret = regulator_set_value(mmc->vqmmc_supply, 3300000);
|
||||
if (ret && ret != -ENOSYS)
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -18,13 +18,18 @@
|
||||
#include <linux/printk.h>
|
||||
|
||||
#define DWMMC_MAX_CH_NUM 4
|
||||
#define DWMMC_MAX_FREQ 52000000
|
||||
#define DWMMC_MAX_FREQ 208000000
|
||||
#define DWMMC_MIN_FREQ 400000
|
||||
#define DWMMC_MMC0_SDR_TIMING_VAL 0x03030001
|
||||
#define DWMMC_MMC2_SDR_TIMING_VAL 0x03020001
|
||||
|
||||
#define EXYNOS4412_FIXED_CIU_CLK_DIV 4
|
||||
|
||||
/* CLKSEL register defines */
|
||||
#define CLKSEL_CCLK_SAMPLE(x) (((x) & 7) << 0)
|
||||
#define CLKSEL_UP_SAMPLE(x, y) (((x) & ~CLKSEL_CCLK_SAMPLE(7)) |\
|
||||
CLKSEL_CCLK_SAMPLE(y))
|
||||
|
||||
/* Quirks */
|
||||
#define DWMCI_QUIRK_DISABLE_SMU BIT(0)
|
||||
|
||||
@@ -121,22 +126,6 @@ static int exynos_dwmmc_set_sclk(struct dwmci_host *host, unsigned long rate)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Configure CLKSEL register with chosen timing values */
|
||||
static int exynos_dwmci_clksel(struct dwmci_host *host)
|
||||
{
|
||||
struct dwmci_exynos_priv_data *priv = exynos_dwmmc_get_priv(host);
|
||||
u32 timing;
|
||||
|
||||
if (host->mmc->selected_mode == MMC_DDR_52)
|
||||
timing = priv->ddr_timing;
|
||||
else
|
||||
timing = priv->sdr_timing;
|
||||
|
||||
dwmci_writel(host, priv->chip->clksel, timing);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* exynos_dwmmc_get_ciu_div - Get internal clock divider value
|
||||
* @host: MMC controller object
|
||||
@@ -160,14 +149,42 @@ static u8 exynos_dwmmc_get_ciu_div(struct dwmci_host *host)
|
||||
& DWMCI_DIVRATIO_MASK) + 1;
|
||||
}
|
||||
|
||||
/* Configure CLKSEL register with chosen timing values */
|
||||
static int exynos_dwmci_clksel(struct dwmci_host *host)
|
||||
{
|
||||
struct dwmci_exynos_priv_data *priv = exynos_dwmmc_get_priv(host);
|
||||
u8 clk_div = exynos_dwmmc_get_ciu_div(host) - 1;
|
||||
u32 timing;
|
||||
|
||||
switch (host->mmc->selected_mode) {
|
||||
case MMC_DDR_52:
|
||||
timing = priv->ddr_timing;
|
||||
break;
|
||||
case UHS_SDR104:
|
||||
case UHS_SDR50:
|
||||
timing = (priv->sdr_timing & 0xfff8ffff) | (clk_div << 16);
|
||||
break;
|
||||
case UHS_DDR50:
|
||||
timing = (priv->ddr_timing & 0xfff8ffff) | (clk_div << 16);
|
||||
break;
|
||||
default:
|
||||
timing = priv->sdr_timing;
|
||||
}
|
||||
|
||||
dwmci_writel(host, priv->chip->clksel, timing);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int exynos_dwmci_get_clk(struct dwmci_host *host, uint freq)
|
||||
{
|
||||
unsigned long sclk;
|
||||
u8 clk_div;
|
||||
int err;
|
||||
|
||||
/* Should be double rate for DDR mode */
|
||||
if (host->mmc->selected_mode == MMC_DDR_52 && host->mmc->bus_width == 8)
|
||||
/* Should be double rate for DDR or HS mode */
|
||||
if ((host->mmc->selected_mode == MMC_DDR_52 && host->mmc->bus_width == 8) ||
|
||||
host->mmc->selected_mode == MMC_HS_400)
|
||||
freq *= 2;
|
||||
|
||||
clk_div = exynos_dwmmc_get_ciu_div(host);
|
||||
@@ -282,6 +299,74 @@ static int exynos_dwmmc_of_to_plat(struct udevice *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if CONFIG_IS_ENABLED(MMC_SUPPORTS_TUNING)
|
||||
static int exynos_dwmmc_get_best_clksmpl(u8 candidates)
|
||||
{
|
||||
u8 i;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
candidates = (candidates >> 1) | (candidates << 7); /* ror */
|
||||
if ((candidates & 0xc7) == 0xc7)
|
||||
return i;
|
||||
}
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
candidates = (candidates >> 1) | (candidates << 7); /* ror */
|
||||
if ((candidates & 0x83) == 0x83)
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
* If no valid clock sample values are found, use the first
|
||||
* canditate bit for clock sample value.
|
||||
*/
|
||||
for (i = 0; i < 8; i++) {
|
||||
candidates = (candidates >> 1) | (candidates << 7); /* ror */
|
||||
if ((candidates & 0x1) == 0x1)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
static int exynos_dwmmc_execute_tuning(struct udevice *dev, u32 opcode)
|
||||
{
|
||||
struct dwmci_exynos_priv_data *priv = dev_get_priv(dev);
|
||||
struct dwmci_host *host = &priv->host;
|
||||
struct mmc *mmc = mmc_get_mmc_dev(dev);
|
||||
u8 start_smpl, smpl, candidates = 0;
|
||||
u32 clksel;
|
||||
int ret;
|
||||
|
||||
clksel = dwmci_readl(host, priv->chip->clksel);
|
||||
start_smpl = CLKSEL_CCLK_SAMPLE(clksel);
|
||||
|
||||
do {
|
||||
dwmci_writel(host, DWMCI_TMOUT, ~0);
|
||||
|
||||
/* move to the next clksmpl */
|
||||
smpl = (clksel + 1) & 0x7;
|
||||
clksel = CLKSEL_UP_SAMPLE(clksel, smpl);
|
||||
dwmci_writel(host, priv->chip->clksel, clksel);
|
||||
|
||||
if (!mmc_send_tuning(mmc, opcode))
|
||||
candidates |= (1 << smpl);
|
||||
|
||||
} while (start_smpl != smpl);
|
||||
|
||||
ret = exynos_dwmmc_get_best_clksmpl(candidates);
|
||||
if (ret < 0) {
|
||||
printf("DWMMC%d: No candidates for clksmpl\n", host->dev_index);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dwmci_writel(host, priv->chip->clksel,
|
||||
CLKSEL_UP_SAMPLE(clksel, ret));
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int exynos_dwmmc_probe(struct udevice *dev)
|
||||
{
|
||||
struct exynos_mmc_plat *plat = dev_get_plat(dev);
|
||||
@@ -321,7 +406,8 @@ static int exynos_dwmmc_probe(struct udevice *dev)
|
||||
|
||||
host->name = dev->name;
|
||||
host->board_init = exynos_dwmci_board_init;
|
||||
host->caps = MMC_MODE_DDR_52MHz;
|
||||
host->caps = MMC_MODE_DDR_52MHz | MMC_MODE_HS200 | MMC_MODE_HS400 |
|
||||
UHS_CAPS;
|
||||
host->clksel = exynos_dwmci_clksel;
|
||||
host->get_mmc_clk = exynos_dwmci_get_clk;
|
||||
|
||||
@@ -378,16 +464,30 @@ static const struct udevice_id exynos_dwmmc_ids[] = {
|
||||
}, {
|
||||
.compatible = "samsung,exynos5420-dw-mshc",
|
||||
.data = (ulong)&exynos5_drv_data,
|
||||
}, {
|
||||
.compatible = "samsung,exynos5250-dw-mshc",
|
||||
.data = (ulong)&exynos5_drv_data,
|
||||
}, {
|
||||
.compatible = "samsung,exynos-dwmmc",
|
||||
.data = (ulong)&exynos5_drv_data,
|
||||
}, {
|
||||
.compatible = "samsung,exynos7-dw-mshc-smu",
|
||||
.data = (ulong)&exynos7_smu_drv_data,
|
||||
}, {
|
||||
.compatible = "samsung,exynos7870-dw-mshc-smu",
|
||||
.data = (ulong)&exynos7_smu_drv_data,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
struct dm_mmc_ops exynos_dwmmc_ops = {
|
||||
.send_cmd = dwmci_send_cmd,
|
||||
.set_ios = dwmci_set_ios,
|
||||
#if CONFIG_IS_ENABLED(MMC_SUPPORTS_TUNING)
|
||||
.execute_tuning = exynos_dwmmc_execute_tuning,
|
||||
#endif
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(exynos_dwmmc_drv) = {
|
||||
.name = "exynos_dwmmc",
|
||||
.id = UCLASS_MMC,
|
||||
@@ -395,7 +495,7 @@ U_BOOT_DRIVER(exynos_dwmmc_drv) = {
|
||||
.of_to_plat = exynos_dwmmc_of_to_plat,
|
||||
.bind = exynos_dwmmc_bind,
|
||||
.probe = exynos_dwmmc_probe,
|
||||
.ops = &dm_dwmci_ops,
|
||||
.ops = &exynos_dwmmc_ops,
|
||||
.priv_auto = sizeof(struct dwmci_exynos_priv_data),
|
||||
.plat_auto = sizeof(struct exynos_mmc_plat),
|
||||
};
|
||||
|
||||
@@ -643,6 +643,19 @@ static int mmc_switch_voltage(struct mmc *mmc, int signal_voltage)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool mmc_sd_card_using_v18(struct mmc *mmc)
|
||||
{
|
||||
/*
|
||||
* According to the SD spec., the Bus Speed Mode (function group 1) bits
|
||||
* 2 to 4 are zero if the card is initialized at 3.3V signal level. Thus
|
||||
* they can be used to determine if the card has already switched to
|
||||
* 1.8V signaling.
|
||||
*/
|
||||
bool volt = mmc->sd3_bus_mode &
|
||||
(SD_MODE_UHS_SDR50 | SD_MODE_UHS_SDR104 | SD_MODE_UHS_DDR50);
|
||||
return volt;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int sd_send_op_cond(struct mmc *mmc, bool uhs_en)
|
||||
@@ -1369,9 +1382,6 @@ static int sd_get_capabilities(struct mmc *mmc)
|
||||
ALLOC_CACHE_ALIGN_BUFFER(__be32, switch_status, 16);
|
||||
struct mmc_data data;
|
||||
int timeout;
|
||||
#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
|
||||
u32 sd3_bus_mode;
|
||||
#endif
|
||||
|
||||
mmc->card_caps = MMC_MODE_1BIT | MMC_CAP(MMC_LEGACY);
|
||||
|
||||
@@ -1451,16 +1461,16 @@ static int sd_get_capabilities(struct mmc *mmc)
|
||||
if (mmc->version < SD_VERSION_3)
|
||||
return 0;
|
||||
|
||||
sd3_bus_mode = __be32_to_cpu(switch_status[3]) >> 16 & 0x1f;
|
||||
if (sd3_bus_mode & SD_MODE_UHS_SDR104)
|
||||
mmc->sd3_bus_mode = __be32_to_cpu(switch_status[3]) >> 16 & 0x1f;
|
||||
if (mmc->sd3_bus_mode & SD_MODE_UHS_SDR104)
|
||||
mmc->card_caps |= MMC_CAP(UHS_SDR104);
|
||||
if (sd3_bus_mode & SD_MODE_UHS_SDR50)
|
||||
if (mmc->sd3_bus_mode & SD_MODE_UHS_SDR50)
|
||||
mmc->card_caps |= MMC_CAP(UHS_SDR50);
|
||||
if (sd3_bus_mode & SD_MODE_UHS_SDR25)
|
||||
if (mmc->sd3_bus_mode & SD_MODE_UHS_SDR25)
|
||||
mmc->card_caps |= MMC_CAP(UHS_SDR25);
|
||||
if (sd3_bus_mode & SD_MODE_UHS_SDR12)
|
||||
if (mmc->sd3_bus_mode & SD_MODE_UHS_SDR12)
|
||||
mmc->card_caps |= MMC_CAP(UHS_SDR12);
|
||||
if (sd3_bus_mode & SD_MODE_UHS_DDR50)
|
||||
if (mmc->sd3_bus_mode & SD_MODE_UHS_DDR50)
|
||||
mmc->card_caps |= MMC_CAP(UHS_DDR50);
|
||||
#endif
|
||||
|
||||
@@ -1830,7 +1840,11 @@ static int sd_select_mode_and_width(struct mmc *mmc, uint card_caps)
|
||||
uint widths[] = {MMC_MODE_4BIT, MMC_MODE_1BIT};
|
||||
const struct mode_width_tuning *mwt;
|
||||
#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
|
||||
bool uhs_en = (mmc->ocr & OCR_S18R) ? true : false;
|
||||
/*
|
||||
* Enable UHS mode if the card advertises 1.8V support (S18R in OCR)
|
||||
* or is already operating at 1.8V signaling.
|
||||
*/
|
||||
bool uhs_en = (mmc->ocr & OCR_S18R) || mmc_sd_card_using_v18(mmc);
|
||||
#else
|
||||
bool uhs_en = false;
|
||||
#endif
|
||||
@@ -2701,6 +2715,27 @@ static int mmc_startup(struct mmc *mmc)
|
||||
err = sd_get_capabilities(mmc);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
|
||||
/*
|
||||
* If the card has already switched to 1.8V signaling, then
|
||||
* set the signal voltage to 1.8V.
|
||||
*/
|
||||
if (mmc_sd_card_using_v18(mmc)) {
|
||||
/*
|
||||
* During a signal voltage level switch, the clock must be gated
|
||||
* for 5 ms according to the SD spec.
|
||||
*/
|
||||
mmc_set_clock(mmc, mmc->clock, MMC_CLK_DISABLE);
|
||||
err = mmc_set_signal_voltage(mmc, MMC_SIGNAL_VOLTAGE_180);
|
||||
if (err)
|
||||
return err;
|
||||
/* Keep clock gated for at least 10 ms, though spec only says 5 ms */
|
||||
mdelay(10);
|
||||
mmc_set_clock(mmc, mmc->clock, MMC_CLK_ENABLE);
|
||||
}
|
||||
#endif
|
||||
|
||||
err = sd_select_mode_and_width(mmc, mmc->card_caps);
|
||||
} else {
|
||||
err = mmc_get_capabilities(mmc);
|
||||
@@ -2844,6 +2879,16 @@ static int mmc_power_on(struct mmc *mmc)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (mmc->vqmmc_supply) {
|
||||
int ret = regulator_set_enable_if_allowed(mmc->vqmmc_supply,
|
||||
true);
|
||||
|
||||
if (ret && ret != -ENOSYS) {
|
||||
printf("Error enabling VQMMC supply : %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@@ -2861,6 +2906,16 @@ static int mmc_power_off(struct mmc *mmc)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (mmc->vqmmc_supply) {
|
||||
int ret = regulator_set_enable_if_allowed(mmc->vqmmc_supply,
|
||||
false);
|
||||
|
||||
if (ret && ret != -ENOSYS) {
|
||||
pr_debug("Error disabling VQMMC supply : %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -13,15 +13,28 @@
|
||||
#include <power/pmic.h>
|
||||
#include <power/s2mps11.h>
|
||||
|
||||
static const struct pmic_child_info pmic_children_info[] = {
|
||||
static const struct pmic_child_info s2mps11_pmic_children_info[] = {
|
||||
{ .prefix = S2MPS11_OF_LDO_PREFIX, .driver = S2MPS11_LDO_DRIVER },
|
||||
{ .prefix = S2MPS11_OF_BUCK_PREFIX, .driver = S2MPS11_BUCK_DRIVER },
|
||||
{ },
|
||||
};
|
||||
|
||||
static const struct pmic_child_info s2mpu05_pmic_children_info[] = {
|
||||
{ .prefix = S2MPU05_OF_LDO_PREFIX, .driver = S2MPS11_LDO_DRIVER },
|
||||
{ .prefix = S2MPU05_OF_BUCK_PREFIX, .driver = S2MPS11_BUCK_DRIVER },
|
||||
{ },
|
||||
};
|
||||
|
||||
static int s2mps11_reg_count(struct udevice *dev)
|
||||
{
|
||||
return S2MPS11_REG_COUNT;
|
||||
switch (dev_get_driver_data(dev)) {
|
||||
case VARIANT_S2MPS11:
|
||||
return S2MPS11_REG_COUNT;
|
||||
case VARIANT_S2MPU05:
|
||||
return S2MPU05_REG_COUNT;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static int s2mps11_write(struct udevice *dev, uint reg, const uint8_t *buff,
|
||||
@@ -47,10 +60,11 @@ static int s2mps11_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int s2mps11_probe(struct udevice *dev)
|
||||
static int s2mps11_bind(struct udevice *dev)
|
||||
{
|
||||
ofnode regulators_node;
|
||||
int children;
|
||||
const struct pmic_child_info *pmic_children_info;
|
||||
|
||||
regulators_node = dev_read_subnode(dev, "regulators");
|
||||
if (!ofnode_valid(regulators_node)) {
|
||||
@@ -61,6 +75,18 @@ static int s2mps11_probe(struct udevice *dev)
|
||||
|
||||
debug("%s: '%s' - found regulators subnode\n", __func__, dev->name);
|
||||
|
||||
switch (dev_get_driver_data(dev)) {
|
||||
case VARIANT_S2MPS11:
|
||||
pmic_children_info = s2mps11_pmic_children_info;
|
||||
break;
|
||||
case VARIANT_S2MPU05:
|
||||
pmic_children_info = s2mpu05_pmic_children_info;
|
||||
break;
|
||||
default:
|
||||
debug("%s: unknown device type\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
children = pmic_bind_children(dev, regulators_node, pmic_children_info);
|
||||
if (!children)
|
||||
debug("%s: %s - no child found\n", __func__, dev->name);
|
||||
@@ -75,7 +101,8 @@ static struct dm_pmic_ops s2mps11_ops = {
|
||||
};
|
||||
|
||||
static const struct udevice_id s2mps11_ids[] = {
|
||||
{ .compatible = "samsung,s2mps11-pmic" },
|
||||
{ .compatible = "samsung,s2mps11-pmic", .data = VARIANT_S2MPS11 },
|
||||
{ .compatible = "samsung,s2mpu05-pmic", .data = VARIANT_S2MPU05 },
|
||||
{ }
|
||||
};
|
||||
|
||||
@@ -84,5 +111,5 @@ U_BOOT_DRIVER(pmic_s2mps11) = {
|
||||
.id = UCLASS_PMIC,
|
||||
.of_match = s2mps11_ids,
|
||||
.ops = &s2mps11_ops,
|
||||
.probe = s2mps11_probe,
|
||||
.bind = s2mps11_bind,
|
||||
};
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include <asm/gpio.h>
|
||||
#include <power/pmic.h>
|
||||
#include <power/regulator.h>
|
||||
#include "regulator_common.h"
|
||||
|
||||
#include "regulator_common.h"
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include <linux/printk.h>
|
||||
#include <power/pmic.h>
|
||||
#include <power/regulator.h>
|
||||
#include "regulator_common.h"
|
||||
|
||||
#include "regulator_common.h"
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include <asm/gpio.h>
|
||||
#include <linux/delay.h>
|
||||
#include <power/regulator.h>
|
||||
#include "regulator_common.h"
|
||||
|
||||
#include "regulator_common.h"
|
||||
|
||||
|
||||
@@ -13,6 +13,193 @@
|
||||
#include <power/regulator.h>
|
||||
#include <power/s2mps11.h>
|
||||
|
||||
#define regulator_desc_s2mps11_buck(num, mask, min, step, max_hex) \
|
||||
[num] = { \
|
||||
.mode_reg = S2MPS11_REG_B##num##CTRL1, \
|
||||
.mode_mask = S2MPS11_BUCK_MODE_MASK << S2MPS11_BUCK_MODE_SHIFT, \
|
||||
.volt_reg = S2MPS11_REG_B##num##CTRL2, \
|
||||
.volt_mask = mask, \
|
||||
.volt_min = min, \
|
||||
.volt_step = step, \
|
||||
.volt_max_hex = max_hex, \
|
||||
}
|
||||
|
||||
#define regulator_desc_s2mps11_buck1_2_3_4_6(num) \
|
||||
regulator_desc_s2mps11_buck(num, S2MPS11_BUCK_VOLT_MASK, \
|
||||
S2MPS11_BUCK_UV_MIN, \
|
||||
S2MPS11_BUCK_LSTEP, \
|
||||
S2MPS11_BUCK_VOLT_MAX_HEX)
|
||||
|
||||
#define regulator_desc_s2mps11_buck5 \
|
||||
regulator_desc_s2mps11_buck(5, S2MPS11_BUCK_VOLT_MASK, \
|
||||
S2MPS11_BUCK_UV_MIN, \
|
||||
S2MPS11_BUCK_LSTEP, \
|
||||
S2MPS11_BUCK5_VOLT_MAX_HEX)
|
||||
|
||||
#define regulator_desc_s2mps11_buck7_8_10(num) \
|
||||
regulator_desc_s2mps11_buck(num, S2MPS11_BUCK_VOLT_MASK, \
|
||||
S2MPS11_BUCK_UV_HMIN, \
|
||||
S2MPS11_BUCK_HSTEP, \
|
||||
S2MPS11_BUCK7_8_10_VOLT_MAX_HEX)
|
||||
|
||||
#define regulator_desc_s2mps11_buck9 \
|
||||
regulator_desc_s2mps11_buck(9, S2MPS11_BUCK9_VOLT_MASK, \
|
||||
S2MPS11_BUCK_UV_MIN, \
|
||||
S2MPS11_BUCK9_STEP, \
|
||||
S2MPS11_BUCK9_VOLT_MAX_HEX)
|
||||
|
||||
static const struct sec_regulator_desc s2mps11_buck_desc[] = {
|
||||
regulator_desc_s2mps11_buck1_2_3_4_6(1),
|
||||
regulator_desc_s2mps11_buck1_2_3_4_6(2),
|
||||
regulator_desc_s2mps11_buck1_2_3_4_6(3),
|
||||
regulator_desc_s2mps11_buck1_2_3_4_6(4),
|
||||
regulator_desc_s2mps11_buck5,
|
||||
regulator_desc_s2mps11_buck1_2_3_4_6(6),
|
||||
regulator_desc_s2mps11_buck7_8_10(7),
|
||||
regulator_desc_s2mps11_buck7_8_10(8),
|
||||
regulator_desc_s2mps11_buck9,
|
||||
regulator_desc_s2mps11_buck7_8_10(10),
|
||||
};
|
||||
|
||||
#define regulator_desc_s2mps11_ldo(num, step) \
|
||||
[num] = { \
|
||||
.mode_reg = S2MPS11_REG_L##num##CTRL, \
|
||||
.mode_mask = S2MPS11_LDO_MODE_MASK << S2MPS11_LDO_MODE_SHIFT, \
|
||||
.volt_reg = S2MPS11_REG_L##num##CTRL, \
|
||||
.volt_mask = S2MPS11_LDO_VOLT_MASK, \
|
||||
.volt_min = S2MPS11_LDO_UV_MIN, \
|
||||
.volt_step = step, \
|
||||
.volt_max_hex = S2MPS11_LDO_VOLT_MAX_HEX \
|
||||
}
|
||||
|
||||
#define regulator_desc_s2mps11_ldo_type1(num) \
|
||||
regulator_desc_s2mps11_ldo(num, S2MPS11_LDO_STEP)
|
||||
|
||||
#define regulator_desc_s2mps11_ldo_type2(num) \
|
||||
regulator_desc_s2mps11_ldo(num, S2MPS11_LDO_STEP * 2)
|
||||
|
||||
static const struct sec_regulator_desc s2mps11_ldo_desc[] = {
|
||||
regulator_desc_s2mps11_ldo_type1(1),
|
||||
regulator_desc_s2mps11_ldo_type2(2),
|
||||
regulator_desc_s2mps11_ldo_type2(3),
|
||||
regulator_desc_s2mps11_ldo_type2(4),
|
||||
regulator_desc_s2mps11_ldo_type2(5),
|
||||
regulator_desc_s2mps11_ldo_type1(6),
|
||||
regulator_desc_s2mps11_ldo_type2(7),
|
||||
regulator_desc_s2mps11_ldo_type2(8),
|
||||
regulator_desc_s2mps11_ldo_type2(9),
|
||||
regulator_desc_s2mps11_ldo_type2(10),
|
||||
regulator_desc_s2mps11_ldo_type1(11),
|
||||
regulator_desc_s2mps11_ldo_type2(12),
|
||||
regulator_desc_s2mps11_ldo_type2(13),
|
||||
regulator_desc_s2mps11_ldo_type2(14),
|
||||
regulator_desc_s2mps11_ldo_type2(15),
|
||||
regulator_desc_s2mps11_ldo_type2(16),
|
||||
regulator_desc_s2mps11_ldo_type2(17),
|
||||
regulator_desc_s2mps11_ldo_type2(18),
|
||||
regulator_desc_s2mps11_ldo_type2(19),
|
||||
regulator_desc_s2mps11_ldo_type2(20),
|
||||
regulator_desc_s2mps11_ldo_type2(21),
|
||||
regulator_desc_s2mps11_ldo_type1(22),
|
||||
regulator_desc_s2mps11_ldo_type1(23),
|
||||
regulator_desc_s2mps11_ldo_type2(24),
|
||||
regulator_desc_s2mps11_ldo_type2(25),
|
||||
regulator_desc_s2mps11_ldo_type2(26),
|
||||
regulator_desc_s2mps11_ldo_type1(27),
|
||||
regulator_desc_s2mps11_ldo_type2(28),
|
||||
regulator_desc_s2mps11_ldo_type2(29),
|
||||
regulator_desc_s2mps11_ldo_type2(30),
|
||||
regulator_desc_s2mps11_ldo_type2(31),
|
||||
regulator_desc_s2mps11_ldo_type2(32),
|
||||
regulator_desc_s2mps11_ldo_type2(33),
|
||||
regulator_desc_s2mps11_ldo_type2(34),
|
||||
regulator_desc_s2mps11_ldo_type1(35),
|
||||
regulator_desc_s2mps11_ldo_type2(36),
|
||||
regulator_desc_s2mps11_ldo_type2(37),
|
||||
regulator_desc_s2mps11_ldo_type2(38),
|
||||
};
|
||||
|
||||
#define regulator_desc_s2mpu05_buck(num, which) \
|
||||
[num] = { \
|
||||
.mode_reg = S2MPU05_REG_B##num##CTRL1, \
|
||||
.mode_mask = S2MPS11_BUCK_MODE_MASK << S2MPS11_BUCK_MODE_SHIFT, \
|
||||
.volt_reg = S2MPU05_REG_B##num##CTRL2, \
|
||||
.volt_mask = S2MPS11_BUCK_VOLT_MASK, \
|
||||
.volt_min = S2MPU05_BUCK_MIN##which, \
|
||||
.volt_step = S2MPU05_BUCK_STEP##which, \
|
||||
.volt_max_hex = S2MPS11_BUCK_VOLT_MASK, \
|
||||
}
|
||||
|
||||
#define regulator_desc_s2mpu05_buck1_2_3(num) \
|
||||
regulator_desc_s2mpu05_buck(num, 1)
|
||||
|
||||
#define regulator_desc_s2mpu05_buck4_5(num) \
|
||||
regulator_desc_s2mpu05_buck(num, 2)
|
||||
|
||||
static const struct sec_regulator_desc s2mpu05_buck_desc[] = {
|
||||
regulator_desc_s2mpu05_buck1_2_3(1),
|
||||
regulator_desc_s2mpu05_buck1_2_3(2),
|
||||
regulator_desc_s2mpu05_buck1_2_3(3),
|
||||
regulator_desc_s2mpu05_buck4_5(4),
|
||||
regulator_desc_s2mpu05_buck4_5(5),
|
||||
};
|
||||
|
||||
#define regulator_desc_s2mpu05_ldo(num, reg, min, step) \
|
||||
[num] = { \
|
||||
.mode_reg = S2MPU05_REG_L##num##reg, \
|
||||
.mode_mask = S2MPS11_LDO_MODE_MASK << S2MPS11_LDO_MODE_SHIFT, \
|
||||
.volt_reg = S2MPU05_REG_L##num##reg, \
|
||||
.volt_mask = S2MPS11_LDO_VOLT_MASK, \
|
||||
.volt_min = min, \
|
||||
.volt_step = step, \
|
||||
.volt_max_hex = S2MPS11_LDO_VOLT_MAX_HEX, \
|
||||
}
|
||||
|
||||
#define regulator_desc_s2mpu05_ldo_type1(num) \
|
||||
regulator_desc_s2mpu05_ldo(num, CTRL, S2MPU05_LDO_MIN1, \
|
||||
S2MPU05_LDO_STEP1)
|
||||
|
||||
#define regulator_desc_s2mpu05_ldo_type2(num) \
|
||||
regulator_desc_s2mpu05_ldo(num, CTRL, S2MPU05_LDO_MIN1, \
|
||||
S2MPU05_LDO_STEP2)
|
||||
|
||||
#define regulator_desc_s2mpu05_ldo_type3(num) \
|
||||
regulator_desc_s2mpu05_ldo(num, CTRL, S2MPU05_LDO_MIN2, \
|
||||
S2MPU05_LDO_STEP2)
|
||||
|
||||
#define regulator_desc_s2mpu05_ldo_type4(num) \
|
||||
regulator_desc_s2mpu05_ldo(num, CTRL, S2MPU05_LDO_MIN3, \
|
||||
S2MPU05_LDO_STEP2)
|
||||
|
||||
#define regulator_desc_s2mpu05_ldo_type5(num) \
|
||||
regulator_desc_s2mpu05_ldo(num, CTRL1, S2MPU05_LDO_MIN3, \
|
||||
S2MPU05_LDO_STEP2)
|
||||
|
||||
static const struct sec_regulator_desc s2mpu05_ldo_desc[] = {
|
||||
regulator_desc_s2mpu05_ldo_type4(1),
|
||||
regulator_desc_s2mpu05_ldo_type3(2),
|
||||
regulator_desc_s2mpu05_ldo_type2(3),
|
||||
regulator_desc_s2mpu05_ldo_type1(4),
|
||||
regulator_desc_s2mpu05_ldo_type1(5),
|
||||
regulator_desc_s2mpu05_ldo_type1(6),
|
||||
regulator_desc_s2mpu05_ldo_type2(7),
|
||||
regulator_desc_s2mpu05_ldo_type3(8),
|
||||
regulator_desc_s2mpu05_ldo_type5(9),
|
||||
regulator_desc_s2mpu05_ldo_type4(10),
|
||||
/* LDOs 11-24 are used for CP. They aren't documented. */
|
||||
regulator_desc_s2mpu05_ldo_type2(25),
|
||||
regulator_desc_s2mpu05_ldo_type3(26),
|
||||
regulator_desc_s2mpu05_ldo_type2(27),
|
||||
regulator_desc_s2mpu05_ldo_type3(28),
|
||||
regulator_desc_s2mpu05_ldo_type3(29),
|
||||
regulator_desc_s2mpu05_ldo_type2(30),
|
||||
regulator_desc_s2mpu05_ldo_type3(31),
|
||||
regulator_desc_s2mpu05_ldo_type3(32),
|
||||
regulator_desc_s2mpu05_ldo_type3(33),
|
||||
regulator_desc_s2mpu05_ldo_type3(34),
|
||||
regulator_desc_s2mpu05_ldo_type3(35),
|
||||
};
|
||||
|
||||
#define MODE(_id, _val, _name) { \
|
||||
.id = _id, \
|
||||
.register_value = _val, \
|
||||
@@ -33,94 +220,46 @@ static struct dm_regulator_mode s2mps11_ldo_modes[] = {
|
||||
MODE(OP_ON, S2MPS11_LDO_MODE_ON, "ON"),
|
||||
};
|
||||
|
||||
static const char s2mps11_buck_ctrl[] = {
|
||||
0xff, 0x25, 0x27, 0x29, 0x2b, 0x2d, 0x33, 0x35, 0x37, 0x39, 0x3b
|
||||
static struct dm_regulator_mode s2mpu05_regulator_modes[] = {
|
||||
MODE(OP_OFF, S2MPS11_LDO_MODE_OFF, "OFF"),
|
||||
MODE(OP_ON, S2MPS11_LDO_MODE_ON, "ON"),
|
||||
};
|
||||
|
||||
static const char s2mps11_buck_out[] = {
|
||||
0xff, 0x26, 0x28, 0x2a, 0x2c, 0x2f, 0x34, 0x36, 0x38, 0x3a, 0x3c
|
||||
};
|
||||
|
||||
static int s2mps11_buck_hex2volt(int buck, int hex)
|
||||
static const ulong s2mps11_get_variant(struct udevice *dev)
|
||||
{
|
||||
unsigned int uV = 0;
|
||||
struct udevice *parent = dev_get_parent(dev);
|
||||
|
||||
if (hex < 0)
|
||||
goto bad;
|
||||
|
||||
switch (buck) {
|
||||
case 7:
|
||||
case 8:
|
||||
case 10:
|
||||
if (hex > S2MPS11_BUCK7_8_10_VOLT_MAX_HEX)
|
||||
goto bad;
|
||||
|
||||
uV = hex * S2MPS11_BUCK_HSTEP + S2MPS11_BUCK_UV_HMIN;
|
||||
break;
|
||||
case 9:
|
||||
if (hex > S2MPS11_BUCK9_VOLT_MAX_HEX)
|
||||
goto bad;
|
||||
uV = hex * S2MPS11_BUCK9_STEP * 2 + S2MPS11_BUCK9_UV_MIN;
|
||||
break;
|
||||
default:
|
||||
if (buck == 5 && hex > S2MPS11_BUCK5_VOLT_MAX_HEX)
|
||||
goto bad;
|
||||
else if (buck != 5 && hex > S2MPS11_BUCK_VOLT_MAX_HEX)
|
||||
goto bad;
|
||||
|
||||
uV = hex * S2MPS11_BUCK_LSTEP + S2MPS11_BUCK_UV_MIN;
|
||||
break;
|
||||
if (!parent) {
|
||||
pr_err("Parent is non-existent, this shouldn't happen!\n");
|
||||
return VARIANT_NONE;
|
||||
}
|
||||
|
||||
return uV;
|
||||
bad:
|
||||
pr_err("Value: %#x is wrong for BUCK%d", hex, buck);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int s2mps11_buck_volt2hex(int buck, int uV)
|
||||
{
|
||||
int hex;
|
||||
|
||||
switch (buck) {
|
||||
case 7:
|
||||
case 8:
|
||||
case 10:
|
||||
hex = (uV - S2MPS11_BUCK_UV_HMIN) / S2MPS11_BUCK_HSTEP;
|
||||
if (hex > S2MPS11_BUCK7_8_10_VOLT_MAX_HEX)
|
||||
goto bad;
|
||||
|
||||
break;
|
||||
case 9:
|
||||
hex = (uV - S2MPS11_BUCK9_UV_MIN) / S2MPS11_BUCK9_STEP;
|
||||
if (hex > S2MPS11_BUCK9_VOLT_MAX_HEX)
|
||||
goto bad;
|
||||
break;
|
||||
default:
|
||||
hex = (uV - S2MPS11_BUCK_UV_MIN) / S2MPS11_BUCK_LSTEP;
|
||||
if (buck == 5 && hex > S2MPS11_BUCK5_VOLT_MAX_HEX)
|
||||
goto bad;
|
||||
else if (buck != 5 && hex > S2MPS11_BUCK_VOLT_MAX_HEX)
|
||||
goto bad;
|
||||
break;
|
||||
};
|
||||
|
||||
if (hex >= 0)
|
||||
return hex;
|
||||
|
||||
bad:
|
||||
pr_err("Value: %d uV is wrong for BUCK%d", uV, buck);
|
||||
return -EINVAL;
|
||||
return dev_get_driver_data(parent);
|
||||
}
|
||||
|
||||
static int s2mps11_buck_val(struct udevice *dev, int op, int *uV)
|
||||
{
|
||||
int hex, buck, ret;
|
||||
u32 mask, addr;
|
||||
const struct sec_regulator_desc *buck_desc;
|
||||
int num_bucks, hex, buck, ret;
|
||||
u32 addr;
|
||||
u8 val;
|
||||
|
||||
switch (s2mps11_get_variant(dev)) {
|
||||
case VARIANT_S2MPS11:
|
||||
buck_desc = s2mps11_buck_desc;
|
||||
num_bucks = ARRAY_SIZE(s2mps11_buck_desc);
|
||||
break;
|
||||
case VARIANT_S2MPU05:
|
||||
buck_desc = s2mpu05_buck_desc;
|
||||
num_bucks = ARRAY_SIZE(s2mpu05_buck_desc);
|
||||
break;
|
||||
default:
|
||||
pr_err("Unknown device type\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
buck = dev->driver_data;
|
||||
if (buck < 1 || buck > S2MPS11_BUCK_NUM) {
|
||||
if (buck < 1 || buck > num_bucks) {
|
||||
pr_err("Wrong buck number: %d\n", buck);
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -128,35 +267,25 @@ static int s2mps11_buck_val(struct udevice *dev, int op, int *uV)
|
||||
if (op == PMIC_OP_GET)
|
||||
*uV = 0;
|
||||
|
||||
addr = s2mps11_buck_out[buck];
|
||||
|
||||
switch (buck) {
|
||||
case 9:
|
||||
mask = S2MPS11_BUCK9_VOLT_MASK;
|
||||
break;
|
||||
default:
|
||||
mask = S2MPS11_BUCK_VOLT_MASK;
|
||||
break;
|
||||
}
|
||||
addr = buck_desc[buck].volt_reg;
|
||||
|
||||
ret = pmic_read(dev->parent, addr, &val, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (op == PMIC_OP_GET) {
|
||||
val &= mask;
|
||||
ret = s2mps11_buck_hex2volt(buck, val);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
*uV = ret;
|
||||
val &= buck_desc[buck].volt_mask;
|
||||
*uV = val * buck_desc[buck].volt_step + buck_desc[buck].volt_min;
|
||||
return 0;
|
||||
}
|
||||
|
||||
hex = s2mps11_buck_volt2hex(buck, *uV);
|
||||
if (hex < 0)
|
||||
return hex;
|
||||
hex = (*uV - buck_desc[buck].volt_min) / buck_desc[buck].volt_step;
|
||||
if (hex > buck_desc[buck].volt_max_hex) {
|
||||
pr_err("Value: %d uV is wrong for LDO%d\n", *uV, buck);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
val &= ~mask;
|
||||
val &= ~buck_desc[buck].volt_mask;
|
||||
val |= hex;
|
||||
ret = pmic_write(dev->parent, addr, &val, 1);
|
||||
|
||||
@@ -165,60 +294,63 @@ static int s2mps11_buck_val(struct udevice *dev, int op, int *uV)
|
||||
|
||||
static int s2mps11_buck_mode(struct udevice *dev, int op, int *opmode)
|
||||
{
|
||||
struct dm_regulator_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
|
||||
const struct sec_regulator_desc *buck_desc;
|
||||
unsigned int addr, mode;
|
||||
unsigned char val;
|
||||
int buck, ret;
|
||||
int num_bucks, buck, ret, i;
|
||||
|
||||
switch (s2mps11_get_variant(dev)) {
|
||||
case VARIANT_S2MPS11:
|
||||
buck_desc = s2mps11_buck_desc;
|
||||
num_bucks = ARRAY_SIZE(s2mps11_buck_desc);
|
||||
break;
|
||||
case VARIANT_S2MPU05:
|
||||
buck_desc = s2mpu05_buck_desc;
|
||||
num_bucks = ARRAY_SIZE(s2mpu05_buck_desc);
|
||||
break;
|
||||
default:
|
||||
pr_err("Unknown device type\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
buck = dev->driver_data;
|
||||
if (buck < 1 || buck > S2MPS11_BUCK_NUM) {
|
||||
if (buck < 1 || buck > num_bucks) {
|
||||
pr_err("Wrong buck number: %d\n", buck);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
addr = s2mps11_buck_ctrl[buck];
|
||||
addr = buck_desc[buck].mode_reg;
|
||||
|
||||
ret = pmic_read(dev->parent, addr, &val, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (op == PMIC_OP_GET) {
|
||||
val &= (S2MPS11_BUCK_MODE_MASK << S2MPS11_BUCK_MODE_SHIFT);
|
||||
switch (val) {
|
||||
case S2MPS11_BUCK_MODE_OFF:
|
||||
*opmode = OP_OFF;
|
||||
break;
|
||||
case S2MPS11_BUCK_MODE_STANDBY:
|
||||
*opmode = OP_STANDBY;
|
||||
break;
|
||||
case S2MPS11_BUCK_MODE_ON:
|
||||
*opmode = OP_ON;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
val &= buck_desc[buck].mode_mask;
|
||||
for (i = 0; i < uc_pdata->mode_count; i++) {
|
||||
if (uc_pdata->mode[i].register_value != val)
|
||||
continue;
|
||||
|
||||
*opmode = uc_pdata->mode[i].id;
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (*opmode) {
|
||||
case OP_OFF:
|
||||
mode = S2MPS11_BUCK_MODE_OFF;
|
||||
break;
|
||||
case OP_STANDBY:
|
||||
mode = S2MPS11_BUCK_MODE_STANDBY;
|
||||
break;
|
||||
case OP_ON:
|
||||
mode = S2MPS11_BUCK_MODE_ON;
|
||||
break;
|
||||
default:
|
||||
pr_err("Wrong mode: %d for buck: %d\n", *opmode, buck);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
val &= ~(S2MPS11_BUCK_MODE_MASK << S2MPS11_BUCK_MODE_SHIFT);
|
||||
val |= mode;
|
||||
ret = pmic_write(dev->parent, addr, &val, 1);
|
||||
for (i = 0; i < uc_pdata->mode_count; i++) {
|
||||
if (uc_pdata->mode[i].id != *opmode)
|
||||
continue;
|
||||
|
||||
return ret;
|
||||
mode = uc_pdata->mode[i].register_value;
|
||||
val &= ~buck_desc[buck].mode_mask;
|
||||
val |= mode;
|
||||
return pmic_write(dev->parent, addr, &val, 1);
|
||||
}
|
||||
|
||||
pr_err("Wrong mode: %d for buck: %d\n", *opmode, buck);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int s2mps11_buck_enable(struct udevice *dev, int op, bool *enable)
|
||||
@@ -307,10 +439,21 @@ static int s2mps11_buck_probe(struct udevice *dev)
|
||||
struct dm_regulator_uclass_plat *uc_pdata;
|
||||
|
||||
uc_pdata = dev_get_uclass_plat(dev);
|
||||
|
||||
uc_pdata->type = REGULATOR_TYPE_BUCK;
|
||||
uc_pdata->mode = s2mps11_buck_modes;
|
||||
uc_pdata->mode_count = ARRAY_SIZE(s2mps11_buck_modes);
|
||||
|
||||
switch (s2mps11_get_variant(dev)) {
|
||||
case VARIANT_S2MPS11:
|
||||
uc_pdata->mode = s2mps11_buck_modes;
|
||||
uc_pdata->mode_count = ARRAY_SIZE(s2mps11_buck_modes);
|
||||
break;
|
||||
case VARIANT_S2MPU05:
|
||||
uc_pdata->mode = s2mpu05_regulator_modes;
|
||||
uc_pdata->mode_count = ARRAY_SIZE(s2mpu05_regulator_modes);
|
||||
break;
|
||||
default:
|
||||
pr_err("Unknown device type\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -331,95 +474,55 @@ U_BOOT_DRIVER(s2mps11_buck) = {
|
||||
.probe = s2mps11_buck_probe,
|
||||
};
|
||||
|
||||
static int s2mps11_ldo_hex2volt(int ldo, int hex)
|
||||
static int s2mps11_ldo_val(struct udevice *dev, int op, int *uV)
|
||||
{
|
||||
unsigned int uV = 0;
|
||||
const struct sec_regulator_desc *ldo_desc;
|
||||
unsigned int addr;
|
||||
unsigned char val;
|
||||
int num_ldos, hex, ldo, ret;
|
||||
|
||||
if (hex > S2MPS11_LDO_VOLT_MAX_HEX) {
|
||||
pr_err("Value: %#x is wrong for LDO%d", hex, ldo);
|
||||
switch (s2mps11_get_variant(dev)) {
|
||||
case VARIANT_S2MPS11:
|
||||
ldo_desc = s2mps11_ldo_desc;
|
||||
num_ldos = ARRAY_SIZE(s2mps11_ldo_desc);
|
||||
break;
|
||||
case VARIANT_S2MPU05:
|
||||
ldo_desc = s2mpu05_ldo_desc;
|
||||
num_ldos = ARRAY_SIZE(s2mpu05_ldo_desc);
|
||||
break;
|
||||
default:
|
||||
pr_err("Unknown device type\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (ldo) {
|
||||
case 1:
|
||||
case 6:
|
||||
case 11:
|
||||
case 22:
|
||||
case 23:
|
||||
case 27:
|
||||
case 35:
|
||||
uV = hex * S2MPS11_LDO_STEP + S2MPS11_LDO_UV_MIN;
|
||||
break;
|
||||
default:
|
||||
uV = hex * S2MPS11_LDO_STEP * 2 + S2MPS11_LDO_UV_MIN;
|
||||
break;
|
||||
}
|
||||
|
||||
return uV;
|
||||
}
|
||||
|
||||
static int s2mps11_ldo_volt2hex(int ldo, int uV)
|
||||
{
|
||||
int hex = 0;
|
||||
|
||||
switch (ldo) {
|
||||
case 1:
|
||||
case 6:
|
||||
case 11:
|
||||
case 22:
|
||||
case 23:
|
||||
case 27:
|
||||
case 35:
|
||||
hex = (uV - S2MPS11_LDO_UV_MIN) / S2MPS11_LDO_STEP;
|
||||
break;
|
||||
default:
|
||||
hex = (uV - S2MPS11_LDO_UV_MIN) / (S2MPS11_LDO_STEP * 2);
|
||||
break;
|
||||
}
|
||||
|
||||
if (hex >= 0 && hex <= S2MPS11_LDO_VOLT_MAX_HEX)
|
||||
return hex;
|
||||
|
||||
pr_err("Value: %d uV is wrong for LDO%d", uV, ldo);
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s2mps11_ldo_val(struct udevice *dev, int op, int *uV)
|
||||
{
|
||||
unsigned int addr;
|
||||
unsigned char val;
|
||||
int hex, ldo, ret;
|
||||
|
||||
ldo = dev->driver_data;
|
||||
if (ldo < 1 || ldo > S2MPS11_LDO_NUM) {
|
||||
if (ldo < 1 || ldo > num_ldos) {
|
||||
pr_err("Wrong ldo number: %d\n", ldo);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
addr = S2MPS11_REG_L1CTRL + ldo - 1;
|
||||
addr = ldo_desc[ldo].volt_reg;
|
||||
|
||||
if (op == PMIC_OP_GET)
|
||||
*uV = 0;
|
||||
|
||||
ret = pmic_read(dev->parent, addr, &val, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (op == PMIC_OP_GET) {
|
||||
*uV = 0;
|
||||
val &= S2MPS11_LDO_VOLT_MASK;
|
||||
ret = s2mps11_ldo_hex2volt(ldo, val);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
*uV = ret;
|
||||
val &= ldo_desc[ldo].volt_mask;
|
||||
*uV = val * ldo_desc[ldo].volt_step + ldo_desc[ldo].volt_min;
|
||||
return 0;
|
||||
}
|
||||
|
||||
hex = s2mps11_ldo_volt2hex(ldo, *uV);
|
||||
if (hex < 0)
|
||||
return hex;
|
||||
hex = (*uV - ldo_desc[ldo].volt_min) / ldo_desc[ldo].volt_step;
|
||||
if (hex > ldo_desc[ldo].volt_max_hex) {
|
||||
pr_err("Value: %d uV is wrong for LDO%d\n", *uV, ldo);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
val &= ~S2MPS11_LDO_VOLT_MASK;
|
||||
val &= ~ldo_desc[ldo].volt_mask;
|
||||
val |= hex;
|
||||
ret = pmic_write(dev->parent, addr, &val, 1);
|
||||
|
||||
@@ -428,65 +531,64 @@ static int s2mps11_ldo_val(struct udevice *dev, int op, int *uV)
|
||||
|
||||
static int s2mps11_ldo_mode(struct udevice *dev, int op, int *opmode)
|
||||
{
|
||||
struct dm_regulator_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
|
||||
const struct sec_regulator_desc *ldo_desc;
|
||||
unsigned int addr, mode;
|
||||
unsigned char val;
|
||||
int ldo, ret;
|
||||
int num_ldos, ldo, ret, i;
|
||||
|
||||
switch (s2mps11_get_variant(dev)) {
|
||||
case VARIANT_S2MPS11:
|
||||
ldo_desc = s2mps11_ldo_desc;
|
||||
num_ldos = ARRAY_SIZE(s2mps11_ldo_desc);
|
||||
break;
|
||||
case VARIANT_S2MPU05:
|
||||
ldo_desc = s2mpu05_ldo_desc;
|
||||
num_ldos = ARRAY_SIZE(s2mpu05_ldo_desc);
|
||||
break;
|
||||
default:
|
||||
pr_err("Unknown device type\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ldo = dev->driver_data;
|
||||
if (ldo < 1 || ldo > S2MPS11_LDO_NUM) {
|
||||
if (ldo < 1 || ldo > num_ldos) {
|
||||
pr_err("Wrong ldo number: %d\n", ldo);
|
||||
return -EINVAL;
|
||||
}
|
||||
addr = S2MPS11_REG_L1CTRL + ldo - 1;
|
||||
|
||||
addr = ldo_desc[ldo].mode_reg;
|
||||
|
||||
ret = pmic_read(dev->parent, addr, &val, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (op == PMIC_OP_GET) {
|
||||
val &= (S2MPS11_LDO_MODE_MASK << S2MPS11_LDO_MODE_SHIFT);
|
||||
switch (val) {
|
||||
case S2MPS11_LDO_MODE_OFF:
|
||||
*opmode = OP_OFF;
|
||||
break;
|
||||
case S2MPS11_LDO_MODE_STANDBY:
|
||||
*opmode = OP_STANDBY;
|
||||
break;
|
||||
case S2MPS11_LDO_MODE_STANDBY_LPM:
|
||||
*opmode = OP_STANDBY_LPM;
|
||||
break;
|
||||
case S2MPS11_LDO_MODE_ON:
|
||||
*opmode = OP_ON;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
val &= ldo_desc[ldo].mode_mask;
|
||||
|
||||
for (i = 0; i < uc_pdata->mode_count; i++) {
|
||||
if (uc_pdata->mode[i].register_value != val)
|
||||
continue;
|
||||
|
||||
*opmode = uc_pdata->mode[i].id;
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (*opmode) {
|
||||
case OP_OFF:
|
||||
mode = S2MPS11_LDO_MODE_OFF;
|
||||
break;
|
||||
case OP_STANDBY:
|
||||
mode = S2MPS11_LDO_MODE_STANDBY;
|
||||
break;
|
||||
case OP_STANDBY_LPM:
|
||||
mode = S2MPS11_LDO_MODE_STANDBY_LPM;
|
||||
break;
|
||||
case OP_ON:
|
||||
mode = S2MPS11_LDO_MODE_ON;
|
||||
break;
|
||||
default:
|
||||
pr_err("Wrong mode: %d for ldo: %d\n", *opmode, ldo);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
val &= ~(S2MPS11_LDO_MODE_MASK << S2MPS11_LDO_MODE_SHIFT);
|
||||
val |= mode;
|
||||
ret = pmic_write(dev->parent, addr, &val, 1);
|
||||
for (i = 0; i < uc_pdata->mode_count; i++) {
|
||||
if (uc_pdata->mode[i].id != *opmode)
|
||||
continue;
|
||||
|
||||
return ret;
|
||||
mode = uc_pdata->mode[i].register_value;
|
||||
val &= ~ldo_desc[ldo].mode_mask;
|
||||
val |= mode;
|
||||
return pmic_write(dev->parent, addr, &val, 1);
|
||||
}
|
||||
|
||||
pr_err("Wrong mode: %d for ldo: %d\n", *opmode, ldo);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int s2mps11_ldo_enable(struct udevice *dev, int op, bool *enable)
|
||||
@@ -584,8 +686,20 @@ static int s2mps11_ldo_probe(struct udevice *dev)
|
||||
|
||||
uc_pdata = dev_get_uclass_plat(dev);
|
||||
uc_pdata->type = REGULATOR_TYPE_LDO;
|
||||
uc_pdata->mode = s2mps11_ldo_modes;
|
||||
uc_pdata->mode_count = ARRAY_SIZE(s2mps11_ldo_modes);
|
||||
|
||||
switch (s2mps11_get_variant(dev)) {
|
||||
case VARIANT_S2MPS11:
|
||||
uc_pdata->mode = s2mps11_ldo_modes;
|
||||
uc_pdata->mode_count = ARRAY_SIZE(s2mps11_ldo_modes);
|
||||
break;
|
||||
case VARIANT_S2MPU05:
|
||||
uc_pdata->mode = s2mpu05_regulator_modes;
|
||||
uc_pdata->mode_count = ARRAY_SIZE(s2mpu05_regulator_modes);
|
||||
break;
|
||||
default:
|
||||
pr_err("Unknown device type\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
#define DWMCI_INTMSK_RTO BIT(8)
|
||||
#define DWMCI_INTMSK_DRTO BIT(9)
|
||||
#define DWMCI_INTMSK_HTO BIT(10)
|
||||
#define DWMCI_INTMSK_VOLTSW BIT(10) /* overlap! */
|
||||
#define DWMCI_INTMSK_FRUN BIT(11)
|
||||
#define DWMCI_INTMSK_HLE BIT(12)
|
||||
#define DWMCI_INTMSK_SBE BIT(13)
|
||||
@@ -104,6 +105,7 @@
|
||||
#define DWMCI_CMD_ABORT_STOP BIT(14)
|
||||
#define DWMCI_CMD_PRV_DAT_WAIT BIT(13)
|
||||
#define DWMCI_CMD_UPD_CLK BIT(21)
|
||||
#define DWMCI_CMD_VOLT_SWITCH BIT(28)
|
||||
#define DWMCI_CMD_USE_HOLD_REG BIT(29)
|
||||
#define DWMCI_CMD_START BIT(31)
|
||||
|
||||
@@ -190,6 +192,7 @@ struct dwmci_idmac_regs {
|
||||
* @cfg: Internal MMC configuration, for !CONFIG_BLK cases
|
||||
* @fifo_mode: Use FIFO mode (not DMA) to read and write data
|
||||
* @dma_64bit_address: Whether DMA supports 64-bit address mode or not
|
||||
* @volt_switching: Whether SD voltage switching is in process or not
|
||||
* @regs: Registers that can vary for different DW MMC block versions
|
||||
*/
|
||||
struct dwmci_host {
|
||||
@@ -229,6 +232,7 @@ struct dwmci_host {
|
||||
|
||||
bool fifo_mode;
|
||||
bool dma_64bit_address;
|
||||
bool volt_switching;
|
||||
const struct dwmci_idmac_regs *regs;
|
||||
};
|
||||
|
||||
@@ -334,6 +338,9 @@ int add_dwmci(struct dwmci_host *host, u32 max_clk, u32 min_clk);
|
||||
#ifdef CONFIG_DM_MMC
|
||||
/* Export the operations to drivers */
|
||||
int dwmci_probe(struct udevice *dev);
|
||||
int dwmci_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
|
||||
struct mmc_data *data);
|
||||
int dwmci_set_ios(struct udevice *dev);
|
||||
extern const struct dm_mmc_ops dm_dwmci_ops;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -759,6 +759,9 @@ struct mmc {
|
||||
#endif
|
||||
u8 *ext_csd;
|
||||
u32 cardtype; /* cardtype read from the MMC */
|
||||
#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
|
||||
u32 sd3_bus_mode; /* Supported UHS-I bus speed modes */
|
||||
#endif
|
||||
enum mmc_voltage current_voltage;
|
||||
enum bus_mode selected_mode; /* mode currently used */
|
||||
enum bus_mode best_mode; /* best mode is the supported mode with the
|
||||
|
||||
@@ -106,9 +106,6 @@ enum s2mps11_reg {
|
||||
|
||||
#define S2MPS11_LDO26_ENABLE 0xec
|
||||
|
||||
#define S2MPS11_LDO_NUM 26
|
||||
#define S2MPS11_BUCK_NUM 10
|
||||
|
||||
/* Driver name */
|
||||
#define S2MPS11_BUCK_DRIVER "s2mps11_buck"
|
||||
#define S2MPS11_OF_BUCK_PREFIX "BUCK"
|
||||
@@ -153,6 +150,131 @@ enum s2mps11_reg {
|
||||
#define S2MPS11_LDO_MODE_STANDBY_LPM (0x2 << 6)
|
||||
#define S2MPS11_LDO_MODE_ON (0x3 << 6)
|
||||
|
||||
enum s2mpu05_reg {
|
||||
S2MPU05_REG_ID,
|
||||
S2MPU05_REG_INT1,
|
||||
S2MPU05_REG_INT2,
|
||||
S2MPU05_REG_INT3,
|
||||
S2MPU05_REG_INT1M,
|
||||
S2MPU05_REG_INT2M,
|
||||
S2MPU05_REG_INT3M,
|
||||
S2MPU05_REG_ST1,
|
||||
S2MPU05_REG_ST2,
|
||||
S2MPU05_REG_PWRONSRC,
|
||||
S2MPU05_REG_OFFSRC,
|
||||
S2MPU05_REG_BU_CHG,
|
||||
S2MPU05_REG_RTC_BUF,
|
||||
S2MPU05_REG_CTRL1,
|
||||
S2MPU05_REG_CTRL2,
|
||||
S2MPU05_REG_ETC_TEST,
|
||||
S2MPU05_REG_OTP_ADRL,
|
||||
S2MPU05_REG_OTP_ADRH,
|
||||
S2MPU05_REG_OTP_DATA,
|
||||
S2MPU05_REG_MON1SEL,
|
||||
S2MPU05_REG_MON2SEL,
|
||||
S2MPU05_REG_CTRL3,
|
||||
S2MPU05_REG_ETC_OTP,
|
||||
S2MPU05_REG_UVLO,
|
||||
S2MPU05_REG_TIME_CTRL1,
|
||||
S2MPU05_REG_TIME_CTRL2,
|
||||
S2MPU05_REG_B1CTRL1,
|
||||
S2MPU05_REG_B1CTRL2,
|
||||
S2MPU05_REG_B2CTRL1,
|
||||
S2MPU05_REG_B2CTRL2,
|
||||
S2MPU05_REG_B2CTRL3,
|
||||
S2MPU05_REG_B2CTRL4,
|
||||
S2MPU05_REG_B3CTRL1,
|
||||
S2MPU05_REG_B3CTRL2,
|
||||
S2MPU05_REG_B3CTRL3,
|
||||
S2MPU05_REG_B4CTRL1,
|
||||
S2MPU05_REG_B4CTRL2,
|
||||
S2MPU05_REG_B5CTRL1,
|
||||
S2MPU05_REG_B5CTRL2,
|
||||
S2MPU05_REG_BUCK_RAMP,
|
||||
S2MPU05_REG_LDO_DVS1,
|
||||
S2MPU05_REG_LDO_DVS9,
|
||||
S2MPU05_REG_LDO_DVS10,
|
||||
S2MPU05_REG_L1CTRL,
|
||||
S2MPU05_REG_L2CTRL,
|
||||
S2MPU05_REG_L3CTRL,
|
||||
S2MPU05_REG_L4CTRL,
|
||||
S2MPU05_REG_L5CTRL,
|
||||
S2MPU05_REG_L6CTRL,
|
||||
S2MPU05_REG_L7CTRL,
|
||||
S2MPU05_REG_L8CTRL,
|
||||
S2MPU05_REG_L9CTRL1,
|
||||
S2MPU05_REG_L9CTRL2,
|
||||
S2MPU05_REG_L10CTRL,
|
||||
S2MPU05_REG_L11CTRL1,
|
||||
S2MPU05_REG_L11CTRL2,
|
||||
S2MPU05_REG_L12CTRL,
|
||||
S2MPU05_REG_L13CTRL,
|
||||
S2MPU05_REG_L14CTRL,
|
||||
S2MPU05_REG_L15CTRL,
|
||||
S2MPU05_REG_L16CTRL,
|
||||
S2MPU05_REG_L17CTRL1,
|
||||
S2MPU05_REG_L17CTRL2,
|
||||
S2MPU05_REG_L18CTRL1,
|
||||
S2MPU05_REG_L18CTRL2,
|
||||
S2MPU05_REG_L19CTRL,
|
||||
S2MPU05_REG_L20CTRL,
|
||||
S2MPU05_REG_L21CTRL,
|
||||
S2MPU05_REG_L22CTRL,
|
||||
S2MPU05_REG_L23CTRL,
|
||||
S2MPU05_REG_L24CTRL,
|
||||
S2MPU05_REG_L25CTRL,
|
||||
S2MPU05_REG_L26CTRL,
|
||||
S2MPU05_REG_L27CTRL,
|
||||
S2MPU05_REG_L28CTRL,
|
||||
S2MPU05_REG_L29CTRL,
|
||||
S2MPU05_REG_L30CTRL,
|
||||
S2MPU05_REG_L31CTRL,
|
||||
S2MPU05_REG_L32CTRL,
|
||||
S2MPU05_REG_L33CTRL,
|
||||
S2MPU05_REG_L34CTRL,
|
||||
S2MPU05_REG_L35CTRL,
|
||||
S2MPU05_REG_LDO_DSCH1,
|
||||
S2MPU05_REG_LDO_DSCH2,
|
||||
S2MPU05_REG_LDO_DSCH3,
|
||||
S2MPU05_REG_LDO_DSCH4,
|
||||
S2MPU05_REG_LDO_DSCH5,
|
||||
S2MPU05_REG_LDO_CTRL1,
|
||||
S2MPU05_REG_LDO_CTRL2,
|
||||
S2MPU05_REG_TCXO_CTRL,
|
||||
S2MPU05_REG_SELMIF,
|
||||
S2MPU05_REG_COUNT,
|
||||
};
|
||||
|
||||
#define S2MPU05_OF_BUCK_PREFIX "buck"
|
||||
#define S2MPU05_OF_LDO_PREFIX "ldo"
|
||||
|
||||
/* BUCK */
|
||||
#define S2MPU05_BUCK_MIN1 400000
|
||||
#define S2MPU05_BUCK_MIN2 600000
|
||||
#define S2MPU05_BUCK_STEP1 6250
|
||||
#define S2MPU05_BUCK_STEP2 12500
|
||||
|
||||
/* LDO */
|
||||
#define S2MPU05_LDO_MIN1 800000
|
||||
#define S2MPU05_LDO_MIN2 1800000
|
||||
#define S2MPU05_LDO_MIN3 400000
|
||||
#define S2MPU05_LDO_STEP1 12500
|
||||
#define S2MPU05_LDO_STEP2 25000
|
||||
|
||||
struct sec_regulator_desc {
|
||||
/* regulator mode control */
|
||||
unsigned int mode_reg;
|
||||
unsigned int mode_mask;
|
||||
|
||||
/* regulator voltage control */
|
||||
unsigned int volt_reg;
|
||||
unsigned int volt_mask;
|
||||
|
||||
unsigned int volt_min;
|
||||
unsigned int volt_step;
|
||||
unsigned int volt_max_hex;
|
||||
};
|
||||
|
||||
enum {
|
||||
OP_OFF = 0,
|
||||
OP_LPM,
|
||||
@@ -161,4 +283,10 @@ enum {
|
||||
OP_ON,
|
||||
};
|
||||
|
||||
enum {
|
||||
VARIANT_NONE,
|
||||
VARIANT_S2MPS11,
|
||||
VARIANT_S2MPU05,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -143,7 +143,7 @@
|
||||
#define SDHCI_INT_CMD_MASK (SDHCI_INT_RESPONSE | SDHCI_INT_TIMEOUT | \
|
||||
SDHCI_INT_CRC | SDHCI_INT_END_BIT | SDHCI_INT_INDEX)
|
||||
#define SDHCI_INT_DATA_MASK (SDHCI_INT_DATA_END | SDHCI_INT_DMA_END | \
|
||||
SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL | \
|
||||
SDHCI_INT_SPACE_AVAIL | SDHCI_INT_DATA_AVAIL | \
|
||||
SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_DATA_CRC | \
|
||||
SDHCI_INT_DATA_END_BIT | SDHCI_INT_ADMA_ERROR)
|
||||
#define SDHCI_INT_ALL_MASK ((unsigned int)-1)
|
||||
|
||||
Reference in New Issue
Block a user