From b30f8af3358b5c66be223e3a9f3d11b3d02b4a8f Mon Sep 17 00:00:00 2001 From: Jarkko Lavinen Date: Mon, 17 Nov 2008 14:35:21 +0200 Subject: mmc: Add 8-bit bus width support Signed-off-by: Jarkko Lavinen Signed-off-by: Pierre Ossman --- include/linux/mmc/host.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux/mmc') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index f842f234e44f..4e457256bd33 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -41,6 +41,7 @@ struct mmc_ios { #define MMC_BUS_WIDTH_1 0 #define MMC_BUS_WIDTH_4 2 +#define MMC_BUS_WIDTH_8 3 unsigned char timing; /* timing specification used */ @@ -116,6 +117,7 @@ struct mmc_host { #define MMC_CAP_SDIO_IRQ (1 << 3) /* Can signal pending SDIO IRQs */ #define MMC_CAP_SPI (1 << 4) /* Talks only SPI protocols */ #define MMC_CAP_NEEDS_POLL (1 << 5) /* Needs polling for card-detection */ +#define MMC_CAP_8_BIT_DATA (1 << 6) /* Can the host do 8 bit transfers */ /* host specific block data */ unsigned int max_seg_size; /* see blk_queue_max_segment_size */ -- cgit v1.2.3 From 86e8286a0e48663e1e86a5884b30a6d05de2993a Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Wed, 26 Nov 2008 22:54:17 +0300 Subject: mmc: Add mmc_vddrange_to_ocrmask() helper function This function sets the OCR mask bits according to provided voltage ranges. Will be used by the mmc_spi OpenFirmware bindings. Signed-off-by: Anton Vorontsov Signed-off-by: Pierre Ossman --- drivers/mmc/core/core.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/mmc/core.h | 2 ++ 2 files changed, 77 insertions(+) (limited to 'include/linux/mmc') diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index f7284b905eb3..5f288aeeb721 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -448,6 +449,80 @@ void mmc_set_bus_width(struct mmc_host *host, unsigned int width) mmc_set_ios(host); } +/** + * mmc_vdd_to_ocrbitnum - Convert a voltage to the OCR bit number + * @vdd: voltage (mV) + * @low_bits: prefer low bits in boundary cases + * + * This function returns the OCR bit number according to the provided @vdd + * value. If conversion is not possible a negative errno value returned. + * + * Depending on the @low_bits flag the function prefers low or high OCR bits + * on boundary voltages. For example, + * with @low_bits = true, 3300 mV translates to ilog2(MMC_VDD_32_33); + * with @low_bits = false, 3300 mV translates to ilog2(MMC_VDD_33_34); + * + * Any value in the [1951:1999] range translates to the ilog2(MMC_VDD_20_21). + */ +static int mmc_vdd_to_ocrbitnum(int vdd, bool low_bits) +{ + const int max_bit = ilog2(MMC_VDD_35_36); + int bit; + + if (vdd < 1650 || vdd > 3600) + return -EINVAL; + + if (vdd >= 1650 && vdd <= 1950) + return ilog2(MMC_VDD_165_195); + + if (low_bits) + vdd -= 1; + + /* Base 2000 mV, step 100 mV, bit's base 8. */ + bit = (vdd - 2000) / 100 + 8; + if (bit > max_bit) + return max_bit; + return bit; +} + +/** + * mmc_vddrange_to_ocrmask - Convert a voltage range to the OCR mask + * @vdd_min: minimum voltage value (mV) + * @vdd_max: maximum voltage value (mV) + * + * This function returns the OCR mask bits according to the provided @vdd_min + * and @vdd_max values. If conversion is not possible the function returns 0. + * + * Notes wrt boundary cases: + * This function sets the OCR bits for all boundary voltages, for example + * [3300:3400] range is translated to MMC_VDD_32_33 | MMC_VDD_33_34 | + * MMC_VDD_34_35 mask. + */ +u32 mmc_vddrange_to_ocrmask(int vdd_min, int vdd_max) +{ + u32 mask = 0; + + if (vdd_max < vdd_min) + return 0; + + /* Prefer high bits for the boundary vdd_max values. */ + vdd_max = mmc_vdd_to_ocrbitnum(vdd_max, false); + if (vdd_max < 0) + return 0; + + /* Prefer low bits for the boundary vdd_min values. */ + vdd_min = mmc_vdd_to_ocrbitnum(vdd_min, true); + if (vdd_min < 0) + return 0; + + /* Fill the mask, from max bit to min bit. */ + while (vdd_max >= vdd_min) + mask |= 1 << vdd_max--; + + return mask; +} +EXPORT_SYMBOL(mmc_vddrange_to_ocrmask); + /* * Mask off any voltages we don't support and select * the lowest voltage diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index 143cebf0586f..7ac8b500d55c 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h @@ -151,4 +151,6 @@ static inline void mmc_claim_host(struct mmc_host *host) __mmc_claim_host(host, NULL); } +extern u32 mmc_vddrange_to_ocrmask(int vdd_min, int vdd_max); + #endif -- cgit v1.2.3