From de13d5a44e61366ab5b75c111449ca284b6e3f5d Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Wed, 13 Feb 2019 18:10:37 +0100 Subject: mmc: core: Move regulator helpers to separate file The mmc regulator helper functions, are placed in the extensive core.c file. In a step towards trying to create a better structure of files, avoiding too many lines of code per file, let's move these helpers to a new file, regulator.c. Moreover, this within this context it makes sense to also drop the export of mmc_vddrange_to_ocrmask(), but instead let's make it internal to the mmc core. Signed-off-by: Ulf Hansson --- drivers/mmc/core/core.c | 242 ------------------------------------------------ 1 file changed, 242 deletions(-) (limited to 'drivers/mmc/core/core.c') diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index de0f1a1f0a63..f796a6afb19b 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include @@ -1112,7 +1111,6 @@ u32 mmc_vddrange_to_ocrmask(int vdd_min, int vdd_max) return mask; } -EXPORT_SYMBOL(mmc_vddrange_to_ocrmask); #ifdef CONFIG_OF @@ -1190,246 +1188,6 @@ struct device_node *mmc_of_find_child_device(struct mmc_host *host, return NULL; } -#ifdef CONFIG_REGULATOR - -/** - * mmc_ocrbitnum_to_vdd - Convert a OCR bit number to its voltage - * @vdd_bit: OCR bit number - * @min_uV: minimum voltage value (mV) - * @max_uV: maximum voltage value (mV) - * - * This function returns the voltage range according to the provided OCR - * bit number. If conversion is not possible a negative errno value returned. - */ -static int mmc_ocrbitnum_to_vdd(int vdd_bit, int *min_uV, int *max_uV) -{ - int tmp; - - if (!vdd_bit) - return -EINVAL; - - /* - * 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; - } - - return 0; -} - -/** - * 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; - int vdd_uV; - int vdd_mV; - - count = regulator_count_voltages(supply); - if (count < 0) - return count; - - for (i = 0; i < count; i++) { - 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); - } - - if (!result) { - vdd_uV = regulator_get_voltage(supply); - if (vdd_uV <= 0) - return vdd_uV; - - vdd_mV = vdd_uV / 1000; - result = mmc_vddrange_to_ocrmask(vdd_mV, vdd_mV); - } - - return result; -} -EXPORT_SYMBOL_GPL(mmc_regulator_get_ocrmask); - -/** - * mmc_regulator_set_ocr - set regulator to match host->ios voltage - * @mmc: the host to regulate - * @supply: regulator to use - * @vdd_bit: zero for power off, else a bit number (host->ios.vdd) - * - * 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 mmc_host *mmc, - struct regulator *supply, - unsigned short vdd_bit) -{ - int result = 0; - int min_uV, max_uV; - - if (vdd_bit) { - mmc_ocrbitnum_to_vdd(vdd_bit, &min_uV, &max_uV); - - result = regulator_set_voltage(supply, min_uV, max_uV); - if (result == 0 && !mmc->regulator_enabled) { - result = regulator_enable(supply); - if (!result) - mmc->regulator_enabled = true; - } - } else if (mmc->regulator_enabled) { - result = regulator_disable(supply); - if (result == 0) - mmc->regulator_enabled = false; - } - - if (result) - dev_err(mmc_dev(mmc), - "could not set regulator OCR (%d)\n", result); - return result; -} -EXPORT_SYMBOL_GPL(mmc_regulator_set_ocr); - -static int mmc_regulator_set_voltage_if_supported(struct regulator *regulator, - int min_uV, int target_uV, - int max_uV) -{ - /* - * Check if supported first to avoid errors since we may try several - * signal levels during power up and don't want to show errors. - */ - if (!regulator_is_supported_voltage(regulator, min_uV, max_uV)) - return -EINVAL; - - return regulator_set_voltage_triplet(regulator, min_uV, target_uV, - max_uV); -} - -/** - * mmc_regulator_set_vqmmc - Set VQMMC as per the ios - * - * For 3.3V signaling, we try to match VQMMC to VMMC as closely as possible. - * That will match the behavior of old boards where VQMMC and VMMC were supplied - * by the same supply. The Bus Operating conditions for 3.3V signaling in the - * SD card spec also define VQMMC in terms of VMMC. - * If this is not possible we'll try the full 2.7-3.6V of the spec. - * - * For 1.2V and 1.8V signaling we'll try to get as close as possible to the - * requested voltage. This is definitely a good idea for UHS where there's a - * separate regulator on the card that's trying to make 1.8V and it's best if - * we match. - * - * This function is expected to be used by a controller's - * start_signal_voltage_switch() function. - */ -int mmc_regulator_set_vqmmc(struct mmc_host *mmc, struct mmc_ios *ios) -{ - struct device *dev = mmc_dev(mmc); - int ret, volt, min_uV, max_uV; - - /* If no vqmmc supply then we can't change the voltage */ - if (IS_ERR(mmc->supply.vqmmc)) - return -EINVAL; - - switch (ios->signal_voltage) { - case MMC_SIGNAL_VOLTAGE_120: - return mmc_regulator_set_voltage_if_supported(mmc->supply.vqmmc, - 1100000, 1200000, 1300000); - case MMC_SIGNAL_VOLTAGE_180: - return mmc_regulator_set_voltage_if_supported(mmc->supply.vqmmc, - 1700000, 1800000, 1950000); - case MMC_SIGNAL_VOLTAGE_330: - ret = mmc_ocrbitnum_to_vdd(mmc->ios.vdd, &volt, &max_uV); - if (ret < 0) - return ret; - - dev_dbg(dev, "%s: found vmmc voltage range of %d-%duV\n", - __func__, volt, max_uV); - - min_uV = max(volt - 300000, 2700000); - max_uV = min(max_uV + 200000, 3600000); - - /* - * Due to a limitation in the current implementation of - * regulator_set_voltage_triplet() which is taking the lowest - * voltage possible if below the target, search for a suitable - * voltage in two steps and try to stay close to vmmc - * with a 0.3V tolerance at first. - */ - if (!mmc_regulator_set_voltage_if_supported(mmc->supply.vqmmc, - min_uV, volt, max_uV)) - return 0; - - return mmc_regulator_set_voltage_if_supported(mmc->supply.vqmmc, - 2700000, volt, 3600000); - default: - return -EINVAL; - } -} -EXPORT_SYMBOL_GPL(mmc_regulator_set_vqmmc); - -#endif /* CONFIG_REGULATOR */ - -/** - * mmc_regulator_get_supply - try to get VMMC and VQMMC regulators for a host - * @mmc: the host to regulate - * - * Returns 0 or errno. errno should be handled, it is either a critical error - * or -EPROBE_DEFER. 0 means no critical error but it does not mean all - * regulators have been found because they all are optional. If you require - * certain regulators, you need to check separately in your driver if they got - * populated after calling this function. - */ -int mmc_regulator_get_supply(struct mmc_host *mmc) -{ - struct device *dev = mmc_dev(mmc); - int ret; - - mmc->supply.vmmc = devm_regulator_get_optional(dev, "vmmc"); - mmc->supply.vqmmc = devm_regulator_get_optional(dev, "vqmmc"); - - if (IS_ERR(mmc->supply.vmmc)) { - if (PTR_ERR(mmc->supply.vmmc) == -EPROBE_DEFER) - return -EPROBE_DEFER; - dev_dbg(dev, "No vmmc regulator found\n"); - } else { - ret = mmc_regulator_get_ocrmask(mmc->supply.vmmc); - if (ret > 0) - mmc->ocr_avail = ret; - else - dev_warn(dev, "Failed getting OCR mask: %d\n", ret); - } - - if (IS_ERR(mmc->supply.vqmmc)) { - if (PTR_ERR(mmc->supply.vqmmc) == -EPROBE_DEFER) - return -EPROBE_DEFER; - dev_dbg(dev, "No vqmmc regulator found\n"); - } - - return 0; -} -EXPORT_SYMBOL_GPL(mmc_regulator_get_supply); - /* * Mask off any voltages we don't support and select * the lowest voltage -- cgit v1.2.3