Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 140257
b: refs/heads/master
c: 5c13941
h: refs/heads/master
i:
  140255: 2f53ad9
v: v3
  • Loading branch information
David Brownell authored and Liam Girdwood committed Mar 31, 2009
1 parent efece4b commit 14a91f3
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 66b659e685bca1f2f6d6102bac74cafbc7eef5c2
refs/heads/master: 5c13941acc513669c7d07b28789c3f9ba66ddddf
100 changes: 100 additions & 0 deletions trunk/drivers/mmc/core/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -523,6 +524,105 @@ u32 mmc_vddrange_to_ocrmask(int vdd_min, int vdd_max)
}
EXPORT_SYMBOL(mmc_vddrange_to_ocrmask);

#ifdef CONFIG_REGULATOR

/**
* mmc_regulator_get_ocrmask - return mask of supported voltages
* @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 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
* @vdd_bit: zero for power off, else a bit number (host->ios.vdd)
* @supply: regulator to use
*
* Returns zero on success, else negative errno.
*
* 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 regulator *supply, unsigned short vdd_bit)
{
int result = 0;
int min_uV, max_uV;
int enabled;

enabled = regulator_is_enabled(supply);
if (enabled < 0)
return enabled;

if (vdd_bit) {
int tmp;
int voltage;

/* REVISIT mmc_vddrange_to_ocrmask() may have set some
* bits this regulator doesn't quite support ... don't
* be too picky, most cards and regulators are OK with
* a 0.1V range goof (it's a small error percentage).
*/
tmp = vdd_bit - ilog2(MMC_VDD_165_195);
if (tmp == 0) {
min_uV = 1650 * 1000;
max_uV = 1950 * 1000;
} else {
min_uV = 1900 * 1000 + tmp * 100 * 1000;
max_uV = min_uV + 100 * 1000;
}

/* avoid needless changes to this voltage; the regulator
* might not allow this operation
*/
voltage = regulator_get_voltage(supply);
if (voltage < 0)
result = voltage;
else if (voltage < min_uV || voltage > max_uV)
result = regulator_set_voltage(supply, min_uV, max_uV);
else
result = 0;

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
Expand Down
5 changes: 5 additions & 0 deletions trunk/include/linux/mmc/host.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,5 +192,10 @@ static inline void mmc_signal_sdio_irq(struct mmc_host *host)
wake_up_process(host->sdio_irq_thread);
}

struct regulator;

int mmc_regulator_get_ocrmask(struct regulator *supply);
int mmc_regulator_set_ocr(struct regulator *supply, unsigned short vdd_bit);

#endif

0 comments on commit 14a91f3

Please sign in to comment.