|
@@ -20,6 +20,7 @@
|
|
#include <linux/err.h>
|
|
#include <linux/err.h>
|
|
#include <linux/leds.h>
|
|
#include <linux/leds.h>
|
|
#include <linux/scatterlist.h>
|
|
#include <linux/scatterlist.h>
|
|
|
|
+#include <linux/log2.h>
|
|
|
|
|
|
#include <linux/mmc/card.h>
|
|
#include <linux/mmc/card.h>
|
|
#include <linux/mmc/host.h>
|
|
#include <linux/mmc/host.h>
|
|
@@ -448,6 +449,80 @@ void mmc_set_bus_width(struct mmc_host *host, unsigned int width)
|
|
mmc_set_ios(host);
|
|
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
|
|
* Mask off any voltages we don't support and select
|
|
* the lowest voltage
|
|
* the lowest voltage
|