···11+TPS65023 family of regulators22+33+Required properties:44+- compatible: Must be one of the following.55+ "ti,tps65020",66+ "ti,tps65021",77+ "ti,tps65023",88+- reg: I2C slave address99+- regulators: list of regulators provided by this controller, must be named1010+ after their hardware counterparts: VDCDC[1-3] and LDO[1-2]1111+- regulators: This is the list of child nodes that specify the regulator1212+ initialization data for defined regulators. The definition for each of1313+ these nodes is defined using the standard binding for regulators found at1414+ Documentation/devicetree/bindings/regulator/regulator.txt.1515+1616+Each regulator is defined using the standard binding for regulators.1717+1818+Example:1919+2020+ tps65023@48 {2121+ compatible = "ti,tps65023";2222+ reg = <0x48>;2323+2424+ regulators {2525+ VDCDC1 {2626+ regulator-name = "vdd_mpu";2727+ regulator-always-on;2828+ regulator-min-microvolt = <1200000>;2929+ regulator-max-microvolt = <1200000>;3030+ };3131+3232+ VDCDC2 {3333+ regulator-name = "vdd_core";3434+ regulator-always-on;3535+ regulator-min-microvolt = <3300000>;3636+ regulator-max-microvolt = <3300000>;3737+ };3838+3939+ VDCDC3 {4040+ regulator-name = "vdd_io";4141+ regulator-always-on;4242+ regulator-min-microvolt = <1800000>;4343+ regulator-max-microvolt = <1800000>;4444+ };4545+4646+ LDO1 {4747+ regulator-name = "vdd_usb18";4848+ regulator-always-on;4949+ regulator-min-microvolt = <1800000>;5050+ regulator-max-microvolt = <1800000>;5151+ };5252+5353+ LDO2 {5454+ regulator-name = "vdd_usb33";5555+ regulator-always-on;5656+ regulator-min-microvolt = <3300000>;5757+ regulator-max-microvolt = <3300000>;5858+ };5959+ };6060+ };
+13-65
drivers/mfd/tps6105x.c
···1616#include <linux/module.h>1717#include <linux/init.h>1818#include <linux/i2c.h>1919-#include <linux/mutex.h>1919+#include <linux/regmap.h>2020#include <linux/gpio.h>2121#include <linux/spinlock.h>2222#include <linux/slab.h>···2525#include <linux/mfd/core.h>2626#include <linux/mfd/tps6105x.h>27272828-int tps6105x_set(struct tps6105x *tps6105x, u8 reg, u8 value)2929-{3030- int ret;3131-3232- ret = mutex_lock_interruptible(&tps6105x->lock);3333- if (ret)3434- return ret;3535- ret = i2c_smbus_write_byte_data(tps6105x->client, reg, value);3636- mutex_unlock(&tps6105x->lock);3737- if (ret < 0)3838- return ret;3939-4040- return 0;4141-}4242-EXPORT_SYMBOL(tps6105x_set);4343-4444-int tps6105x_get(struct tps6105x *tps6105x, u8 reg, u8 *buf)4545-{4646- int ret;4747-4848- ret = mutex_lock_interruptible(&tps6105x->lock);4949- if (ret)5050- return ret;5151- ret = i2c_smbus_read_byte_data(tps6105x->client, reg);5252- mutex_unlock(&tps6105x->lock);5353- if (ret < 0)5454- return ret;5555-5656- *buf = ret;5757- return 0;5858-}5959-EXPORT_SYMBOL(tps6105x_get);6060-6161-/*6262- * Masks off the bits in the mask and sets the bits in the bitvalues6363- * parameter in one atomic operation6464- */6565-int tps6105x_mask_and_set(struct tps6105x *tps6105x, u8 reg,6666- u8 bitmask, u8 bitvalues)6767-{6868- int ret;6969- u8 regval;7070-7171- ret = mutex_lock_interruptible(&tps6105x->lock);7272- if (ret)7373- return ret;7474- ret = i2c_smbus_read_byte_data(tps6105x->client, reg);7575- if (ret < 0)7676- goto fail;7777- regval = ret;7878- regval = (~bitmask & regval) | (bitmask & bitvalues);7979- ret = i2c_smbus_write_byte_data(tps6105x->client, reg, regval);8080-fail:8181- mutex_unlock(&tps6105x->lock);8282- if (ret < 0)8383- return ret;8484-8585- return 0;8686-}8787-EXPORT_SYMBOL(tps6105x_mask_and_set);2828+static struct regmap_config tps6105x_regmap_config = {2929+ .reg_bits = 8,3030+ .val_bits = 8,3131+ .max_register = TPS6105X_REG_3,3232+};88338934static int tps6105x_startup(struct tps6105x *tps6105x)9035{9136 int ret;9292- u8 regval;3737+ unsigned int regval;93389494- ret = tps6105x_get(tps6105x, TPS6105X_REG_0, ®val);3939+ ret = regmap_read(tps6105x->regmap, TPS6105X_REG_0, ®val);9540 if (ret)9641 return ret;9742 switch (regval >> TPS6105X_REG0_MODE_SHIFT) {···90145 if (!tps6105x)91146 return -ENOMEM;92147148148+ tps6105x->regmap = devm_regmap_init_i2c(client, &tps6105x_regmap_config);149149+ if (IS_ERR(tps6105x->regmap))150150+ return PTR_ERR(tps6105x->regmap);151151+93152 i2c_set_clientdata(client, tps6105x);94153 tps6105x->client = client;95154 pdata = dev_get_platdata(&client->dev);96155 tps6105x->pdata = pdata;9797- mutex_init(&tps6105x->lock);9815699157 ret = tps6105x_startup(tps6105x);100158 if (ret) {···146198 mfd_remove_devices(&client->dev);147199148200 /* Put chip in shutdown mode */149149- tps6105x_mask_and_set(tps6105x, TPS6105X_REG_0,201201+ regmap_update_bits(tps6105x->regmap, TPS6105X_REG_0,150202 TPS6105X_REG0_MODE_MASK,151203 TPS6105X_MODE_SHUTDOWN << TPS6105X_REG0_MODE_SHIFT);152204
+179-70
drivers/regulator/core.c
···133133}134134135135/**136136+ * regulator_lock_supply - lock a regulator and its supplies137137+ * @rdev: regulator source138138+ */139139+static void regulator_lock_supply(struct regulator_dev *rdev)140140+{141141+ struct regulator *supply;142142+ int i = 0;143143+144144+ while (1) {145145+ mutex_lock_nested(&rdev->mutex, i++);146146+ supply = rdev->supply;147147+148148+ if (!rdev->supply)149149+ return;150150+151151+ rdev = supply->rdev;152152+ }153153+}154154+155155+/**156156+ * regulator_unlock_supply - unlock a regulator and its supplies157157+ * @rdev: regulator source158158+ */159159+static void regulator_unlock_supply(struct regulator_dev *rdev)160160+{161161+ struct regulator *supply;162162+163163+ while (1) {164164+ mutex_unlock(&rdev->mutex);165165+ supply = rdev->supply;166166+167167+ if (!rdev->supply)168168+ return;169169+170170+ rdev = supply->rdev;171171+ }172172+}173173+174174+/**136175 * of_get_regulator - get a regulator device node based on supply name137176 * @dev: Device pointer for the consumer (of regulator) device138177 * @supply: regulator supply name···24032364 return rdev->desc->ops->is_enabled(rdev);24042365}2405236623672367+static int _regulator_list_voltage(struct regulator *regulator,23682368+ unsigned selector, int lock)23692369+{23702370+ struct regulator_dev *rdev = regulator->rdev;23712371+ const struct regulator_ops *ops = rdev->desc->ops;23722372+ int ret;23732373+23742374+ if (rdev->desc->fixed_uV && rdev->desc->n_voltages == 1 && !selector)23752375+ return rdev->desc->fixed_uV;23762376+23772377+ if (ops->list_voltage) {23782378+ if (selector >= rdev->desc->n_voltages)23792379+ return -EINVAL;23802380+ if (lock)23812381+ mutex_lock(&rdev->mutex);23822382+ ret = ops->list_voltage(rdev, selector);23832383+ if (lock)23842384+ mutex_unlock(&rdev->mutex);23852385+ } else if (rdev->supply) {23862386+ ret = _regulator_list_voltage(rdev->supply, selector, lock);23872387+ } else {23882388+ return -EINVAL;23892389+ }23902390+23912391+ if (ret > 0) {23922392+ if (ret < rdev->constraints->min_uV)23932393+ ret = 0;23942394+ else if (ret > rdev->constraints->max_uV)23952395+ ret = 0;23962396+ }23972397+23982398+ return ret;23992399+}24002400+24062401/**24072402 * regulator_is_enabled - is the regulator output enabled24082403 * @regulator: regulator source···25262453 */25272454int regulator_list_voltage(struct regulator *regulator, unsigned selector)25282455{25292529- struct regulator_dev *rdev = regulator->rdev;25302530- const struct regulator_ops *ops = rdev->desc->ops;25312531- int ret;25322532-25332533- if (rdev->desc->fixed_uV && rdev->desc->n_voltages == 1 && !selector)25342534- return rdev->desc->fixed_uV;25352535-25362536- if (ops->list_voltage) {25372537- if (selector >= rdev->desc->n_voltages)25382538- return -EINVAL;25392539- mutex_lock(&rdev->mutex);25402540- ret = ops->list_voltage(rdev, selector);25412541- mutex_unlock(&rdev->mutex);25422542- } else if (rdev->supply) {25432543- ret = regulator_list_voltage(rdev->supply, selector);25442544- } else {25452545- return -EINVAL;25462546- }25472547-25482548- if (ret > 0) {25492549- if (ret < rdev->constraints->min_uV)25502550- ret = 0;25512551- else if (ret > rdev->constraints->max_uV)25522552- ret = 0;25532553- }25542554-25552555- return ret;24562456+ return _regulator_list_voltage(regulator, selector, 1);25562457}25572458EXPORT_SYMBOL_GPL(regulator_list_voltage);25582459···26612614}26622615EXPORT_SYMBOL_GPL(regulator_is_supported_voltage);2663261626172617+static int regulator_map_voltage(struct regulator_dev *rdev, int min_uV,26182618+ int max_uV)26192619+{26202620+ const struct regulator_desc *desc = rdev->desc;26212621+26222622+ if (desc->ops->map_voltage)26232623+ return desc->ops->map_voltage(rdev, min_uV, max_uV);26242624+26252625+ if (desc->ops->list_voltage == regulator_list_voltage_linear)26262626+ return regulator_map_voltage_linear(rdev, min_uV, max_uV);26272627+26282628+ if (desc->ops->list_voltage == regulator_list_voltage_linear_range)26292629+ return regulator_map_voltage_linear_range(rdev, min_uV, max_uV);26302630+26312631+ return regulator_map_voltage_iterate(rdev, min_uV, max_uV);26322632+}26332633+26642634static int _regulator_call_set_voltage(struct regulator_dev *rdev,26652635 int min_uV, int max_uV,26662636 unsigned *selector)···27662702 }2767270327682704 } else if (rdev->desc->ops->set_voltage_sel) {27692769- if (rdev->desc->ops->map_voltage) {27702770- ret = rdev->desc->ops->map_voltage(rdev, min_uV,27712771- max_uV);27722772- } else {27732773- if (rdev->desc->ops->list_voltage ==27742774- regulator_list_voltage_linear)27752775- ret = regulator_map_voltage_linear(rdev,27762776- min_uV, max_uV);27772777- else if (rdev->desc->ops->list_voltage ==27782778- regulator_list_voltage_linear_range)27792779- ret = regulator_map_voltage_linear_range(rdev,27802780- min_uV, max_uV);27812781- else27822782- ret = regulator_map_voltage_iterate(rdev,27832783- min_uV, max_uV);27842784- }27852785-27052705+ ret = regulator_map_voltage(rdev, min_uV, max_uV);27862706 if (ret >= 0) {27872707 best_val = rdev->desc->ops->list_voltage(rdev, ret);27882708 if (min_uV <= best_val && max_uV >= best_val) {···28172769 return ret;28182770}2819277128202820-/**28212821- * regulator_set_voltage - set regulator output voltage28222822- * @regulator: regulator source28232823- * @min_uV: Minimum required voltage in uV28242824- * @max_uV: Maximum acceptable voltage in uV28252825- *28262826- * Sets a voltage regulator to the desired output voltage. This can be set28272827- * during any regulator state. IOW, regulator can be disabled or enabled.28282828- *28292829- * If the regulator is enabled then the voltage will change to the new value28302830- * immediately otherwise if the regulator is disabled the regulator will28312831- * output at the new voltage when enabled.28322832- *28332833- * NOTE: If the regulator is shared between several devices then the lowest28342834- * request voltage that meets the system constraints will be used.28352835- * Regulator system constraints must be set for this regulator before28362836- * calling this function otherwise this call will fail.28372837- */28382838-int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV)27722772+static int regulator_set_voltage_unlocked(struct regulator *regulator,27732773+ int min_uV, int max_uV)28392774{28402775 struct regulator_dev *rdev = regulator->rdev;28412776 int ret = 0;28422777 int old_min_uV, old_max_uV;28432778 int current_uV;28442844-28452845- mutex_lock(&rdev->mutex);27792779+ int best_supply_uV = 0;27802780+ int supply_change_uV = 0;2846278128472782 /* If we're setting the same range as last time the change28482783 * should be a noop (some cpufreq implementations use the same···28692838 if (ret < 0)28702839 goto out2;2871284028412841+ if (rdev->supply && (rdev->desc->min_dropout_uV ||28422842+ !rdev->desc->ops->get_voltage)) {28432843+ int current_supply_uV;28442844+ int selector;28452845+28462846+ selector = regulator_map_voltage(rdev, min_uV, max_uV);28472847+ if (selector < 0) {28482848+ ret = selector;28492849+ goto out2;28502850+ }28512851+28522852+ best_supply_uV = _regulator_list_voltage(regulator, selector, 0);28532853+ if (best_supply_uV < 0) {28542854+ ret = best_supply_uV;28552855+ goto out2;28562856+ }28572857+28582858+ best_supply_uV += rdev->desc->min_dropout_uV;28592859+28602860+ current_supply_uV = _regulator_get_voltage(rdev->supply->rdev);28612861+ if (current_supply_uV < 0) {28622862+ ret = current_supply_uV;28632863+ goto out2;28642864+ }28652865+28662866+ supply_change_uV = best_supply_uV - current_supply_uV;28672867+ }28682868+28692869+ if (supply_change_uV > 0) {28702870+ ret = regulator_set_voltage_unlocked(rdev->supply,28712871+ best_supply_uV, INT_MAX);28722872+ if (ret) {28732873+ dev_err(&rdev->dev, "Failed to increase supply voltage: %d\n",28742874+ ret);28752875+ goto out2;28762876+ }28772877+ }28782878+28722879 ret = _regulator_do_set_voltage(rdev, min_uV, max_uV);28732880 if (ret < 0)28742881 goto out2;2875288228832883+ if (supply_change_uV < 0) {28842884+ ret = regulator_set_voltage_unlocked(rdev->supply,28852885+ best_supply_uV, INT_MAX);28862886+ if (ret)28872887+ dev_warn(&rdev->dev, "Failed to decrease supply voltage: %d\n",28882888+ ret);28892889+ /* No need to fail here */28902890+ ret = 0;28912891+ }28922892+28762893out:28772877- mutex_unlock(&rdev->mutex);28782894 return ret;28792895out2:28802896 regulator->min_uV = old_min_uV;28812897 regulator->max_uV = old_max_uV;28822882- mutex_unlock(&rdev->mutex);28982898+28992899+ return ret;29002900+}29012901+29022902+/**29032903+ * regulator_set_voltage - set regulator output voltage29042904+ * @regulator: regulator source29052905+ * @min_uV: Minimum required voltage in uV29062906+ * @max_uV: Maximum acceptable voltage in uV29072907+ *29082908+ * Sets a voltage regulator to the desired output voltage. This can be set29092909+ * during any regulator state. IOW, regulator can be disabled or enabled.29102910+ *29112911+ * If the regulator is enabled then the voltage will change to the new value29122912+ * immediately otherwise if the regulator is disabled the regulator will29132913+ * output at the new voltage when enabled.29142914+ *29152915+ * NOTE: If the regulator is shared between several devices then the lowest29162916+ * request voltage that meets the system constraints will be used.29172917+ * Regulator system constraints must be set for this regulator before29182918+ * calling this function otherwise this call will fail.29192919+ */29202920+int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV)29212921+{29222922+ int ret = 0;29232923+29242924+ regulator_lock_supply(regulator->rdev);29252925+29262926+ ret = regulator_set_voltage_unlocked(regulator, min_uV, max_uV);29272927+29282928+ regulator_unlock_supply(regulator->rdev);29292929+28832930 return ret;28842931}28852932EXPORT_SYMBOL_GPL(regulator_set_voltage);···31103001 } else if (rdev->desc->fixed_uV && (rdev->desc->n_voltages == 1)) {31113002 ret = rdev->desc->fixed_uV;31123003 } else if (rdev->supply) {31133113- ret = regulator_get_voltage(rdev->supply);30043004+ ret = _regulator_get_voltage(rdev->supply->rdev);31143005 } else {31153006 return -EINVAL;31163007 }···31333024{31343025 int ret;3135302631363136- mutex_lock(®ulator->rdev->mutex);30273027+ regulator_lock_supply(regulator->rdev);3137302831383029 ret = _regulator_get_voltage(regulator->rdev);3139303031403140- mutex_unlock(®ulator->rdev->mutex);30313031+ regulator_unlock_supply(regulator->rdev);3141303231423033 return ret;31433034}
+8-8
drivers/regulator/tps6105x-regulator.c
···1414#include <linux/kernel.h>1515#include <linux/init.h>1616#include <linux/err.h>1717-#include <linux/i2c.h>1717+#include <linux/regmap.h>1818#include <linux/platform_device.h>1919#include <linux/regulator/driver.h>2020#include <linux/mfd/core.h>···3333 int ret;34343535 /* Activate voltage mode */3636- ret = tps6105x_mask_and_set(tps6105x, TPS6105X_REG_0,3636+ ret = regmap_update_bits(tps6105x->regmap, TPS6105X_REG_0,3737 TPS6105X_REG0_MODE_MASK,3838 TPS6105X_REG0_MODE_VOLTAGE << TPS6105X_REG0_MODE_SHIFT);3939 if (ret)···4848 int ret;49495050 /* Set into shutdown mode */5151- ret = tps6105x_mask_and_set(tps6105x, TPS6105X_REG_0,5151+ ret = regmap_update_bits(tps6105x->regmap, TPS6105X_REG_0,5252 TPS6105X_REG0_MODE_MASK,5353 TPS6105X_REG0_MODE_SHUTDOWN << TPS6105X_REG0_MODE_SHIFT);5454 if (ret)···6060static int tps6105x_regulator_is_enabled(struct regulator_dev *rdev)6161{6262 struct tps6105x *tps6105x = rdev_get_drvdata(rdev);6363- u8 regval;6363+ unsigned int regval;6464 int ret;65656666- ret = tps6105x_get(tps6105x, TPS6105X_REG_0, ®val);6666+ ret = regmap_read(tps6105x->regmap, TPS6105X_REG_0, ®val);6767 if (ret)6868 return ret;6969 regval &= TPS6105X_REG0_MODE_MASK;···7878static int tps6105x_regulator_get_voltage_sel(struct regulator_dev *rdev)7979{8080 struct tps6105x *tps6105x = rdev_get_drvdata(rdev);8181- u8 regval;8181+ unsigned int regval;8282 int ret;83838484- ret = tps6105x_get(tps6105x, TPS6105X_REG_0, ®val);8484+ ret = regmap_read(tps6105x->regmap, TPS6105X_REG_0, ®val);8585 if (ret)8686 return ret;8787···9696 struct tps6105x *tps6105x = rdev_get_drvdata(rdev);9797 int ret;98989999- ret = tps6105x_mask_and_set(tps6105x, TPS6105X_REG_0,9999+ ret = regmap_update_bits(tps6105x->regmap, TPS6105X_REG_0,100100 TPS6105X_REG0_VOLTAGE_MASK,101101 selector << TPS6105X_REG0_VOLTAGE_SHIFT);102102 if (ret)