aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmmanuel Vadot <manu@FreeBSD.org>2021-05-16 14:18:46 +0000
committerEmmanuel Vadot <manu@FreeBSD.org>2021-07-22 17:09:41 +0000
commit19ccda09deb783cefcc06346ac7e1d34ebb8f8ec (patch)
tree72dacf9efd9b8f460c190f1d470daa24b8d09bb3
parentee2a2639749fd42de2b4bf19d4784948a6d1fca5 (diff)
downloadsrc-19ccda09deb783cefcc06346ac7e1d34ebb8f8ec.tar.gz
src-19ccda09deb783cefcc06346ac7e1d34ebb8f8ec.zip
mmc_fdt_helper: Add mmc_fdt_set_power
This helper can be used to enable/disable the regulator and starting the power sequence of sd/sdio/eMMC cards. Sponsored by: Diablotin Systems Differential Revision: https://reviews.freebsd.org/D30291 (cherry picked from commit 03d4e8bb6592fefab7b17f1d163adba4e35a12c2)
-rw-r--r--sys/dev/mmc/mmc_fdt_helpers.c42
-rw-r--r--sys/dev/mmc/mmc_fdt_helpers.h1
2 files changed, 43 insertions, 0 deletions
diff --git a/sys/dev/mmc/mmc_fdt_helpers.c b/sys/dev/mmc/mmc_fdt_helpers.c
index e544f3c4ac08..4e8a1730d240 100644
--- a/sys/dev/mmc/mmc_fdt_helpers.c
+++ b/sys/dev/mmc/mmc_fdt_helpers.c
@@ -45,6 +45,8 @@ __FBSDID("$FreeBSD$");
#include <dev/extres/regulator/regulator.h>
#endif
+#include "mmc_pwrseq_if.h"
+
static inline void
mmc_fdt_parse_sd_speed(phandle_t node, struct mmc_host *host)
{
@@ -423,3 +425,43 @@ mmc_fdt_gpio_get_readonly(struct mmc_fdt_helper *helper)
return (pinstate ^ (helper->props & MMC_PROP_WP_INVERTED));
}
+
+void
+mmc_fdt_set_power(struct mmc_fdt_helper *helper, enum mmc_power_mode power_mode)
+{
+ int reg_status;
+ int rv;
+
+ switch (power_mode) {
+ case power_on:
+ break;
+ case power_off:
+ if (helper->vmmc_supply) {
+ rv = regulator_status(helper->vmmc_supply, &reg_status);
+ if (rv == 0 && reg_status == REGULATOR_STATUS_ENABLED)
+ regulator_disable(helper->vmmc_supply);
+ }
+ if (helper->vqmmc_supply) {
+ rv = regulator_status(helper->vqmmc_supply, &reg_status);
+ if (rv == 0 && reg_status == REGULATOR_STATUS_ENABLED)
+ regulator_disable(helper->vqmmc_supply);
+ }
+ if (helper->mmc_pwrseq)
+ MMC_PWRSEQ_SET_POWER(helper->mmc_pwrseq, false);
+ break;
+ case power_up:
+ if (helper->vmmc_supply) {
+ rv = regulator_status(helper->vmmc_supply, &reg_status);
+ if (rv == 0 && reg_status != REGULATOR_STATUS_ENABLED)
+ regulator_enable(helper->vmmc_supply);
+ }
+ if (helper->vqmmc_supply) {
+ rv = regulator_status(helper->vqmmc_supply, &reg_status);
+ if (rv == 0 && reg_status != REGULATOR_STATUS_ENABLED)
+ regulator_enable(helper->vqmmc_supply);
+ }
+ if (helper->mmc_pwrseq)
+ MMC_PWRSEQ_SET_POWER(helper->mmc_pwrseq, true);
+ break;
+ }
+}
diff --git a/sys/dev/mmc/mmc_fdt_helpers.h b/sys/dev/mmc/mmc_fdt_helpers.h
index c6e2175690ee..e6d6f3fbfd84 100644
--- a/sys/dev/mmc/mmc_fdt_helpers.h
+++ b/sys/dev/mmc/mmc_fdt_helpers.h
@@ -74,5 +74,6 @@ int mmc_fdt_gpio_setup(device_t dev, phandle_t node, struct mmc_fdt_helper *help
void mmc_fdt_gpio_teardown(struct mmc_fdt_helper *helper);
bool mmc_fdt_gpio_get_present(struct mmc_fdt_helper *helper);
bool mmc_fdt_gpio_get_readonly(struct mmc_fdt_helper *helper);
+void mmc_fdt_set_power(struct mmc_fdt_helper *helper, enum mmc_power_mode power_mode);
#endif