[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <200902261348.30617.david-b@pacbell.net>
Date: Thu, 26 Feb 2009 13:48:30 -0800
From: David Brownell <david-b@...bell.net>
To: Mark Brown <broonie@...ena.org.uk>,
Pierre Ossman <drzeus-mmc@...eus.cx>
Cc: Liam Girdwood <lrg@...mlogic.co.uk>,
lkml <linux-kernel@...r.kernel.org>,
OMAP <linux-omap@...r.kernel.org>
Subject: [patch 2.6.29-rc6+misc] MMC: regulator utilities
From: David Brownell <dbrownell@...rs.sourceforge.net>
Add optional glue between MMC and regulator stacks, using a new
regulator interface to learn what voltages are available.
This is intended to be selected and driven by MMC host adapters.
It only handles reusable parts of the regulator-to-MMC glue; the
adapter drivers will have access to details that affect how this
is used. Examples include when to use multiple voltage rails or
configure (internal or external) level shifters.
Signed-off-by: David Brownell <dbrownell@...rs.sourceforge.net>
---
Changes from previous version: adapter must select this, and
callers now pass in the regulator. mmc_regulator_set_ocr()
is still not tested, mmc_regulator_get_ocrmask() passed sanity
testing.
Pierre: Mark may have a need for this soonish. The omap_hsmmc
code will want it at some point.
drivers/mmc/core/Kconfig | 7 +++
drivers/mmc/core/core.c | 84 +++++++++++++++++++++++++++++++++++++++++++++
include/linux/mmc/host.h | 5 ++
3 files changed, 96 insertions(+)
--- a/drivers/mmc/core/Kconfig
+++ b/drivers/mmc/core/Kconfig
@@ -14,3 +14,10 @@ config MMC_UNSAFE_RESUME
This option is usually just for embedded systems which use
a MMC/SD card for rootfs. Most people should say N here.
+config MMC_REGULATOR
+ bool
+ depends on REGULATOR
+ help
+ Select this if your MMC host adapter driver wants helper
+ utilities for accessing power rails.
+
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -21,6 +21,7 @@
#include <linux/leds.h>
#include <linux/scatterlist.h>
#include <linux/log2.h>
+#include <linux/regulator/consumer.h>
#include <linux/mmc/card.h>
#include <linux/mmc/host.h>
@@ -523,6 +524,89 @@ u32 mmc_vddrange_to_ocrmask(int vdd_min,
}
EXPORT_SYMBOL(mmc_vddrange_to_ocrmask);
+#ifdef CONFIG_MMC_REGULATOR
+
+/**
+ * mmc_regulator_get_ocrmask - return mask of supported voltages
+ * @host: mmc host whose supply will be consulted
+ * @supply: regulator to use
+ *
+ * This returns either a negative errno, or a mask of voltages that
+ * can be provided to MMC/SD/SDIO devices using the specified voltage
+ * regulator. This would normally be called before registering the
+ * MMC host adapter.
+ */
+int mmc_regulator_get_ocrmask(struct mmc_host *host, struct regulator *supply)
+{
+ int result = 0;
+ int count;
+ int i;
+
+ count = regulator_count_voltages(supply);
+ if (count < 0)
+ return count;
+
+ for (i = 0; i < count; i++) {
+ int vdd_uV;
+ int vdd_mV;
+
+ vdd_uV = regulator_list_voltage(supply, i);
+ if (vdd_uV <= 0)
+ continue;
+
+ vdd_mV = vdd_uV / 1000;
+ result |= mmc_vddrange_to_ocrmask(vdd_mV, vdd_mV);
+ }
+
+ return result;
+}
+EXPORT_SYMBOL(mmc_regulator_get_ocrmask);
+
+/**
+ * mmc_regulator_set_ocr - set regulator to match host->ios voltage
+ * @host: mmc host whose supply voltage will be changed
+ * @supply: regulator to use
+ *
+ * MMC host drivers may use this to enable or disable a regulator using
+ * a particular supply voltage. This would normally be called from the
+ * set_ios() method.
+ */
+int mmc_regulator_set_ocr(struct mmc_host *host, struct regulator *supply)
+{
+ int result = 0;
+ int min_mV, max_mV;
+ int enabled;
+
+ enabled = regulator_is_enabled(supply);
+ if (enabled < 0)
+ return enabled;
+
+ if (host->ios.vdd) {
+ int tmp;
+
+ tmp = host->ios.vdd - ilog2(MMC_VDD_165_195);
+ if (tmp == 0) {
+ min_mV = 1650;
+ max_mV = 1950;
+ } else {
+ min_mV = 2000 + tmp * 100;
+ max_mV = min_mV + 100;
+ }
+
+ result = regulator_set_voltage(supply,
+ min_mV * 1000, max_mV * 1000);
+ if (result == 0 && !enabled)
+ result = regulator_enable(supply);
+ } else if (enabled) {
+ result = regulator_disable(supply);
+ }
+
+ return result;
+}
+EXPORT_SYMBOL(mmc_regulator_set_ocr);
+
+#endif
+
/*
* Mask off any voltages we don't support and select
* the lowest voltage
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -192,5 +192,10 @@ static inline void mmc_signal_sdio_irq(s
wake_up_process(host->sdio_irq_thread);
}
+struct regulator;
+
+int mmc_regulator_get_ocrmask(struct mmc_host *host, struct regulator *supply);
+int mmc_regulator_set_ocr(struct mmc_host *host, struct regulator *supply);
+
#endif
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists