LCOV - code coverage report
Current view: top level - drivers/mmc/core - regulator.c (source / functions) Hit Total Coverage
Test: gcov_data_raspi2_real_modules_combined.info Lines: 0 62 0.0 %
Date: 2020-09-30 20:25:40 Functions: 0 5 0.0 %
Branches: 0 54 0.0 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0
       2                 :            : /*
       3                 :            :  * Helper functions for MMC regulators.
       4                 :            :  */
       5                 :            : 
       6                 :            : #include <linux/device.h>
       7                 :            : #include <linux/err.h>
       8                 :            : #include <linux/log2.h>
       9                 :            : #include <linux/regulator/consumer.h>
      10                 :            : 
      11                 :            : #include <linux/mmc/host.h>
      12                 :            : 
      13                 :            : #include "core.h"
      14                 :            : #include "host.h"
      15                 :            : 
      16                 :            : #ifdef CONFIG_REGULATOR
      17                 :            : 
      18                 :            : /**
      19                 :            :  * mmc_ocrbitnum_to_vdd - Convert a OCR bit number to its voltage
      20                 :            :  * @vdd_bit:    OCR bit number
      21                 :            :  * @min_uV:     minimum voltage value (mV)
      22                 :            :  * @max_uV:     maximum voltage value (mV)
      23                 :            :  *
      24                 :            :  * This function returns the voltage range according to the provided OCR
      25                 :            :  * bit number. If conversion is not possible a negative errno value returned.
      26                 :            :  */
      27                 :            : static int mmc_ocrbitnum_to_vdd(int vdd_bit, int *min_uV, int *max_uV)
      28                 :            : {
      29                 :            :         int             tmp;
      30                 :            : 
      31   [ #  #  #  # ]:          0 :         if (!vdd_bit)
      32                 :            :                 return -EINVAL;
      33                 :            : 
      34                 :            :         /*
      35                 :            :          * REVISIT mmc_vddrange_to_ocrmask() may have set some
      36                 :            :          * bits this regulator doesn't quite support ... don't
      37                 :            :          * be too picky, most cards and regulators are OK with
      38                 :            :          * a 0.1V range goof (it's a small error percentage).
      39                 :            :          */
      40                 :          0 :         tmp = vdd_bit - ilog2(MMC_VDD_165_195);
      41   [ #  #  #  # ]:          0 :         if (tmp == 0) {
      42                 :            :                 *min_uV = 1650 * 1000;
      43                 :            :                 *max_uV = 1950 * 1000;
      44                 :            :         } else {
      45                 :          0 :                 *min_uV = 1900 * 1000 + tmp * 100 * 1000;
      46                 :          0 :                 *max_uV = *min_uV + 100 * 1000;
      47                 :            :         }
      48                 :            : 
      49                 :            :         return 0;
      50                 :            : }
      51                 :            : 
      52                 :            : /**
      53                 :            :  * mmc_regulator_get_ocrmask - return mask of supported voltages
      54                 :            :  * @supply: regulator to use
      55                 :            :  *
      56                 :            :  * This returns either a negative errno, or a mask of voltages that
      57                 :            :  * can be provided to MMC/SD/SDIO devices using the specified voltage
      58                 :            :  * regulator.  This would normally be called before registering the
      59                 :            :  * MMC host adapter.
      60                 :            :  */
      61                 :          0 : static int mmc_regulator_get_ocrmask(struct regulator *supply)
      62                 :            : {
      63                 :            :         int                     result = 0;
      64                 :            :         int                     count;
      65                 :            :         int                     i;
      66                 :            :         int                     vdd_uV;
      67                 :            :         int                     vdd_mV;
      68                 :            : 
      69                 :          0 :         count = regulator_count_voltages(supply);
      70         [ #  # ]:          0 :         if (count < 0)
      71                 :            :                 return count;
      72                 :            : 
      73         [ #  # ]:          0 :         for (i = 0; i < count; i++) {
      74                 :          0 :                 vdd_uV = regulator_list_voltage(supply, i);
      75         [ #  # ]:          0 :                 if (vdd_uV <= 0)
      76                 :          0 :                         continue;
      77                 :            : 
      78                 :          0 :                 vdd_mV = vdd_uV / 1000;
      79                 :          0 :                 result |= mmc_vddrange_to_ocrmask(vdd_mV, vdd_mV);
      80                 :            :         }
      81                 :            : 
      82         [ #  # ]:          0 :         if (!result) {
      83                 :          0 :                 vdd_uV = regulator_get_voltage(supply);
      84         [ #  # ]:          0 :                 if (vdd_uV <= 0)
      85                 :            :                         return vdd_uV;
      86                 :            : 
      87                 :          0 :                 vdd_mV = vdd_uV / 1000;
      88                 :          0 :                 result = mmc_vddrange_to_ocrmask(vdd_mV, vdd_mV);
      89                 :            :         }
      90                 :            : 
      91                 :          0 :         return result;
      92                 :            : }
      93                 :            : 
      94                 :            : /**
      95                 :            :  * mmc_regulator_set_ocr - set regulator to match host->ios voltage
      96                 :            :  * @mmc: the host to regulate
      97                 :            :  * @supply: regulator to use
      98                 :            :  * @vdd_bit: zero for power off, else a bit number (host->ios.vdd)
      99                 :            :  *
     100                 :            :  * Returns zero on success, else negative errno.
     101                 :            :  *
     102                 :            :  * MMC host drivers may use this to enable or disable a regulator using
     103                 :            :  * a particular supply voltage.  This would normally be called from the
     104                 :            :  * set_ios() method.
     105                 :            :  */
     106                 :          0 : int mmc_regulator_set_ocr(struct mmc_host *mmc,
     107                 :            :                         struct regulator *supply,
     108                 :            :                         unsigned short vdd_bit)
     109                 :            : {
     110                 :            :         int                     result = 0;
     111                 :            :         int                     min_uV, max_uV;
     112                 :            : 
     113         [ #  # ]:          0 :         if (vdd_bit) {
     114                 :          0 :                 mmc_ocrbitnum_to_vdd(vdd_bit, &min_uV, &max_uV);
     115                 :            : 
     116                 :          0 :                 result = regulator_set_voltage(supply, min_uV, max_uV);
     117   [ #  #  #  # ]:          0 :                 if (result == 0 && !mmc->regulator_enabled) {
     118                 :          0 :                         result = regulator_enable(supply);
     119         [ #  # ]:          0 :                         if (!result)
     120                 :          0 :                                 mmc->regulator_enabled = true;
     121                 :            :                 }
     122         [ #  # ]:          0 :         } else if (mmc->regulator_enabled) {
     123                 :          0 :                 result = regulator_disable(supply);
     124         [ #  # ]:          0 :                 if (result == 0)
     125                 :          0 :                         mmc->regulator_enabled = false;
     126                 :            :         }
     127                 :            : 
     128         [ #  # ]:          0 :         if (result)
     129                 :          0 :                 dev_err(mmc_dev(mmc),
     130                 :            :                         "could not set regulator OCR (%d)\n", result);
     131                 :          0 :         return result;
     132                 :            : }
     133                 :            : EXPORT_SYMBOL_GPL(mmc_regulator_set_ocr);
     134                 :            : 
     135                 :          0 : static int mmc_regulator_set_voltage_if_supported(struct regulator *regulator,
     136                 :            :                                                   int min_uV, int target_uV,
     137                 :            :                                                   int max_uV)
     138                 :            : {
     139                 :            :         /*
     140                 :            :          * Check if supported first to avoid errors since we may try several
     141                 :            :          * signal levels during power up and don't want to show errors.
     142                 :            :          */
     143         [ #  # ]:          0 :         if (!regulator_is_supported_voltage(regulator, min_uV, max_uV))
     144                 :            :                 return -EINVAL;
     145                 :            : 
     146                 :          0 :         return regulator_set_voltage_triplet(regulator, min_uV, target_uV,
     147                 :            :                                              max_uV);
     148                 :            : }
     149                 :            : 
     150                 :            : /**
     151                 :            :  * mmc_regulator_set_vqmmc - Set VQMMC as per the ios
     152                 :            :  *
     153                 :            :  * For 3.3V signaling, we try to match VQMMC to VMMC as closely as possible.
     154                 :            :  * That will match the behavior of old boards where VQMMC and VMMC were supplied
     155                 :            :  * by the same supply.  The Bus Operating conditions for 3.3V signaling in the
     156                 :            :  * SD card spec also define VQMMC in terms of VMMC.
     157                 :            :  * If this is not possible we'll try the full 2.7-3.6V of the spec.
     158                 :            :  *
     159                 :            :  * For 1.2V and 1.8V signaling we'll try to get as close as possible to the
     160                 :            :  * requested voltage.  This is definitely a good idea for UHS where there's a
     161                 :            :  * separate regulator on the card that's trying to make 1.8V and it's best if
     162                 :            :  * we match.
     163                 :            :  *
     164                 :            :  * This function is expected to be used by a controller's
     165                 :            :  * start_signal_voltage_switch() function.
     166                 :            :  */
     167                 :          0 : int mmc_regulator_set_vqmmc(struct mmc_host *mmc, struct mmc_ios *ios)
     168                 :            : {
     169                 :            :         struct device *dev = mmc_dev(mmc);
     170                 :            :         int ret, volt, min_uV, max_uV;
     171                 :            : 
     172                 :            :         /* If no vqmmc supply then we can't change the voltage */
     173         [ #  # ]:          0 :         if (IS_ERR(mmc->supply.vqmmc))
     174                 :            :                 return -EINVAL;
     175                 :            : 
     176   [ #  #  #  # ]:          0 :         switch (ios->signal_voltage) {
     177                 :            :         case MMC_SIGNAL_VOLTAGE_120:
     178                 :          0 :                 return mmc_regulator_set_voltage_if_supported(mmc->supply.vqmmc,
     179                 :            :                                                 1100000, 1200000, 1300000);
     180                 :            :         case MMC_SIGNAL_VOLTAGE_180:
     181                 :          0 :                 return mmc_regulator_set_voltage_if_supported(mmc->supply.vqmmc,
     182                 :            :                                                 1700000, 1800000, 1950000);
     183                 :            :         case MMC_SIGNAL_VOLTAGE_330:
     184                 :          0 :                 ret = mmc_ocrbitnum_to_vdd(mmc->ios.vdd, &volt, &max_uV);
     185         [ #  # ]:          0 :                 if (ret < 0)
     186                 :            :                         return ret;
     187                 :            : 
     188                 :            :                 dev_dbg(dev, "%s: found vmmc voltage range of %d-%duV\n",
     189                 :            :                         __func__, volt, max_uV);
     190                 :            : 
     191                 :          0 :                 min_uV = max(volt - 300000, 2700000);
     192                 :          0 :                 max_uV = min(max_uV + 200000, 3600000);
     193                 :            : 
     194                 :            :                 /*
     195                 :            :                  * Due to a limitation in the current implementation of
     196                 :            :                  * regulator_set_voltage_triplet() which is taking the lowest
     197                 :            :                  * voltage possible if below the target, search for a suitable
     198                 :            :                  * voltage in two steps and try to stay close to vmmc
     199                 :            :                  * with a 0.3V tolerance at first.
     200                 :            :                  */
     201         [ #  # ]:          0 :                 if (!mmc_regulator_set_voltage_if_supported(mmc->supply.vqmmc,
     202                 :            :                                                 min_uV, volt, max_uV))
     203                 :            :                         return 0;
     204                 :            : 
     205                 :          0 :                 return mmc_regulator_set_voltage_if_supported(mmc->supply.vqmmc,
     206                 :            :                                                 2700000, volt, 3600000);
     207                 :            :         default:
     208                 :            :                 return -EINVAL;
     209                 :            :         }
     210                 :            : }
     211                 :            : EXPORT_SYMBOL_GPL(mmc_regulator_set_vqmmc);
     212                 :            : 
     213                 :            : #else
     214                 :            : 
     215                 :            : static inline int mmc_regulator_get_ocrmask(struct regulator *supply)
     216                 :            : {
     217                 :            :         return 0;
     218                 :            : }
     219                 :            : 
     220                 :            : #endif /* CONFIG_REGULATOR */
     221                 :            : 
     222                 :            : /**
     223                 :            :  * mmc_regulator_get_supply - try to get VMMC and VQMMC regulators for a host
     224                 :            :  * @mmc: the host to regulate
     225                 :            :  *
     226                 :            :  * Returns 0 or errno. errno should be handled, it is either a critical error
     227                 :            :  * or -EPROBE_DEFER. 0 means no critical error but it does not mean all
     228                 :            :  * regulators have been found because they all are optional. If you require
     229                 :            :  * certain regulators, you need to check separately in your driver if they got
     230                 :            :  * populated after calling this function.
     231                 :            :  */
     232                 :          0 : int mmc_regulator_get_supply(struct mmc_host *mmc)
     233                 :            : {
     234                 :          0 :         struct device *dev = mmc_dev(mmc);
     235                 :            :         int ret;
     236                 :            : 
     237                 :          0 :         mmc->supply.vmmc = devm_regulator_get_optional(dev, "vmmc");
     238                 :          0 :         mmc->supply.vqmmc = devm_regulator_get_optional(dev, "vqmmc");
     239                 :            : 
     240         [ #  # ]:          0 :         if (IS_ERR(mmc->supply.vmmc)) {
     241         [ #  # ]:          0 :                 if (PTR_ERR(mmc->supply.vmmc) == -EPROBE_DEFER)
     242                 :            :                         return -EPROBE_DEFER;
     243                 :            :                 dev_dbg(dev, "No vmmc regulator found\n");
     244                 :            :         } else {
     245                 :          0 :                 ret = mmc_regulator_get_ocrmask(mmc->supply.vmmc);
     246         [ #  # ]:          0 :                 if (ret > 0)
     247                 :          0 :                         mmc->ocr_avail = ret;
     248                 :            :                 else
     249                 :          0 :                         dev_warn(dev, "Failed getting OCR mask: %d\n", ret);
     250                 :            :         }
     251                 :            : 
     252         [ #  # ]:          0 :         if (IS_ERR(mmc->supply.vqmmc)) {
     253         [ #  # ]:          0 :                 if (PTR_ERR(mmc->supply.vqmmc) == -EPROBE_DEFER)
     254                 :            :                         return -EPROBE_DEFER;
     255                 :            :                 dev_dbg(dev, "No vqmmc regulator found\n");
     256                 :            :         }
     257                 :            : 
     258                 :          0 :         return 0;
     259                 :            : }
     260                 :            : EXPORT_SYMBOL_GPL(mmc_regulator_get_supply);

Generated by: LCOV version 1.14