Message ID | 200902261348.30617.david-b@pacbell.net (mailing list archive) |
---|---|
State | Awaiting Upstream, archived |
Headers | show |
On Thu, 26 Feb 2009 13:48:30 -0800 David Brownell <david-b@pacbell.net> wrote: > From: David Brownell <dbrownell@users.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@users.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. > I have no insight into the regulator stuff, so I'm going to have to trust you on this. :) Some nitpicking though: > --- 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. > + Is there a need for a special Kconfig for this? Can't we just build these two whenever REGULATOR is defined? Or always, provided the regulator API is present even when the code isn't. > +/** > + * 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) > +{ Why not pass the vdd directly? Saves a few dereferences if nothing else. Rgds
On Monday 02 March 2009, Pierre Ossman wrote: > On Thu, 26 Feb 2009 13:48:30 -0800 > David Brownell <david-b@pacbell.net> wrote: > > > From: David Brownell <dbrownell@users.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@users.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. > > > > I have no insight into the regulator stuff, so I'm going to have to > trust you on this. :) Works for me. ;) > Some nitpicking though: > > > --- 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. > > + > > Is there a need for a special Kconfig for this? Can't we just build > these two whenever REGULATOR is defined? Or always, provided the > regulator API is present even when the code isn't. The first patch had a "default y" there, nobody commented. I'll simplify that, and use #ifdef CONFIG_REGULATOR instead. > > +/** > > + * 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) > > +{ > > Why not pass the vdd directly? Saves a few dereferences if nothing else. This call syntax is simpler, which is usually a win. Passing a third parameter would create fault paths of the "pass *wrong* parameter" flavor. In terms of object code, when I've looked at such things the dereferences generally cost the same as a ref to a parameter, but passing an extra parameter isn't free. - Dave -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Mon, 2 Mar 2009 13:27:13 -0800 David Brownell <david-b@pacbell.net> wrote: > On Monday 02 March 2009, Pierre Ossman wrote: > > On Thu, 26 Feb 2009 13:48:30 -0800 > > David Brownell <david-b@pacbell.net> wrote: > > > > > + */ > > > +int mmc_regulator_set_ocr(struct mmc_host *host, struct regulator *supply) > > > +{ > > > > Why not pass the vdd directly? Saves a few dereferences if nothing else. > > This call syntax is simpler, which is usually a win. > Passing a third parameter would create fault paths > of the "pass *wrong* parameter" flavor. > > In terms of object code, when I've looked at such things > the dereferences generally cost the same as a ref to a > parameter, but passing an extra parameter isn't free. > I couldn't see host being used in there, so I was thinking more of a replacement, not an addition. Rgds
On Monday 02 March 2009, Pierre Ossman wrote: > > > > +int mmc_regulator_set_ocr(struct mmc_host *host, struct regulator *supply) > > > > +{ > > > > > > Why not pass the vdd directly? Saves a few dereferences if nothing else. > > > > This call syntax is simpler, which is usually a win. > > Passing a third parameter would create fault paths > > of the "pass *wrong* parameter" flavor. > > > > In terms of object code, when I've looked at such things > > the dereferences generally cost the same as a ref to a > > parameter, but passing an extra parameter isn't free. > > > > I couldn't see host being used in there, so I was thinking more of a > replacement, not an addition. Oh, I see. That'd make sense. Just pass host->ios.vdd. -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
--- 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