diff options
| author | Guodong Xu <guodong.xu@linaro.org> | 2014-08-13 07:33:42 -0400 |
|---|---|---|
| committer | Mark Brown <broonie@linaro.org> | 2014-08-16 17:58:15 -0400 |
| commit | 87ca186f7eb663fc5e52b65452a91fe0fec170a0 (patch) | |
| tree | caeb09468cf072bd94f6a78e58c18f50e065e348 /drivers/regulator | |
| parent | 871f565055ed232e5751da18a331b73e8254adaf (diff) | |
regulator: add driver for hi6421 voltage regulator
Add driver support for HiSilicon Hi6421 voltage regulators.
Two rules for regulator enabling are defined in hi6421 spec:
1) Between disable and enable of each regulator (LDOs or BUCKs), there must
be a protection gap. Use @off_on_delay of regulator core to implement this.
2) No two regulators can be enabled at the same time. Use mutex in
hi6421_regulator_pdata to ensure this. A protection gap of 100us is added
into each LDO/BUCK's .enable_time.
Signed-off-by: Guodong Xu <guodong.xu@linaro.org>
Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'drivers/regulator')
| -rw-r--r-- | drivers/regulator/Kconfig | 10 | ||||
| -rw-r--r-- | drivers/regulator/Makefile | 1 | ||||
| -rw-r--r-- | drivers/regulator/hi6421-regulator.c | 657 |
3 files changed, 668 insertions, 0 deletions
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 2dc8289e5dba..e6b98ed4c12f 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig | |||
| @@ -240,6 +240,16 @@ config REGULATOR_GPIO | |||
| 240 | and the platform has to provide a mapping of GPIO-states | 240 | and the platform has to provide a mapping of GPIO-states |
| 241 | to target volts/amps. | 241 | to target volts/amps. |
| 242 | 242 | ||
| 243 | config REGULATOR_HI6421 | ||
| 244 | tristate "HiSilicon Hi6421 PMIC voltage regulator support" | ||
| 245 | depends on MFD_HI6421_PMIC && OF | ||
| 246 | help | ||
| 247 | This driver provides support for the voltage regulators on the | ||
| 248 | HiSilicon Hi6421 PMU / Codec IC. | ||
| 249 | Hi6421 is a multi-function device which, on regulator part, provides | ||
| 250 | 21 general purpose LDOs, 3 dedicated LDOs, and 5 BUCKs. All | ||
| 251 | of them come with support to either ECO (idle) or sleep mode. | ||
| 252 | |||
| 243 | config REGULATOR_ISL6271A | 253 | config REGULATOR_ISL6271A |
| 244 | tristate "Intersil ISL6271A Power regulator" | 254 | tristate "Intersil ISL6271A Power regulator" |
| 245 | depends on I2C | 255 | depends on I2C |
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index aa4a6aa7b558..5513e2c141b1 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile | |||
| @@ -32,6 +32,7 @@ obj-$(CONFIG_REGULATOR_DBX500_PRCMU) += dbx500-prcmu.o | |||
| 32 | obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o | 32 | obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o |
| 33 | obj-$(CONFIG_REGULATOR_FAN53555) += fan53555.o | 33 | obj-$(CONFIG_REGULATOR_FAN53555) += fan53555.o |
| 34 | obj-$(CONFIG_REGULATOR_GPIO) += gpio-regulator.o | 34 | obj-$(CONFIG_REGULATOR_GPIO) += gpio-regulator.o |
| 35 | obj-$(CONFIG_REGULATOR_HI6421) += hi6421-regulator.o | ||
| 35 | obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o | 36 | obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o |
| 36 | obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o | 37 | obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o |
| 37 | obj-$(CONFIG_REGULATOR_LP3972) += lp3972.o | 38 | obj-$(CONFIG_REGULATOR_LP3972) += lp3972.o |
diff --git a/drivers/regulator/hi6421-regulator.c b/drivers/regulator/hi6421-regulator.c new file mode 100644 index 000000000000..b40851eb5466 --- /dev/null +++ b/drivers/regulator/hi6421-regulator.c | |||
| @@ -0,0 +1,657 @@ | |||
| 1 | /* | ||
| 2 | * Device driver for regulators in Hi6421 IC | ||
| 3 | * | ||
| 4 | * Copyright (c) <2011-2014> HiSilicon Technologies Co., Ltd. | ||
| 5 | * http://www.hisilicon.com | ||
| 6 | * Copyright (c) <2013-2014> Linaro Ltd. | ||
| 7 | * http://www.linaro.org | ||
| 8 | * | ||
| 9 | * Author: Guodong Xu <guodong.xu@linaro.org> | ||
| 10 | * | ||
| 11 | * This program is free software; you can redistribute it and/or modify | ||
| 12 | * it under the terms of the GNU General Public License version 2 as | ||
| 13 | * published by the Free Software Foundation. | ||
| 14 | */ | ||
| 15 | |||
| 16 | #include <linux/slab.h> | ||
| 17 | #include <linux/device.h> | ||
| 18 | #include <linux/module.h> | ||
| 19 | #include <linux/err.h> | ||
| 20 | #include <linux/io.h> | ||
| 21 | #include <linux/jiffies.h> | ||
| 22 | #include <linux/platform_device.h> | ||
| 23 | #include <linux/of.h> | ||
| 24 | #include <linux/of_device.h> | ||
| 25 | #include <linux/of_address.h> | ||
| 26 | #include <linux/regmap.h> | ||
| 27 | #include <linux/regulator/driver.h> | ||
| 28 | #include <linux/regulator/machine.h> | ||
| 29 | #include <linux/regulator/of_regulator.h> | ||
| 30 | #include <linux/mfd/hi6421-pmic.h> | ||
| 31 | #include <linux/delay.h> | ||
| 32 | #include <linux/time.h> | ||
| 33 | |||
| 34 | /* | ||
| 35 | * struct hi6421_regulator_pdata - Hi6421 regulator data of platform device | ||
| 36 | * @lock: mutex to serialize regulator enable | ||
| 37 | */ | ||
| 38 | struct hi6421_regulator_pdata { | ||
| 39 | struct mutex lock; | ||
| 40 | }; | ||
| 41 | |||
| 42 | /* | ||
| 43 | * struct hi6421_regulator_info - hi6421 regulator information | ||
| 44 | * @dev: device pointer | ||
| 45 | * @desc: regulator description | ||
| 46 | * @regulator: regulator device | ||
| 47 | * @mode_mask: ECO mode bitmask of LDOs; for BUCKs, this masks sleep | ||
| 48 | * @eco_microamp: eco mode load upper limit (in mA), valid for LDOs only | ||
| 49 | * @valid_modes_mask: valid operating modes | ||
| 50 | */ | ||
| 51 | struct hi6421_regulator_info { | ||
| 52 | struct device *dev; | ||
| 53 | struct regulator_desc desc; | ||
| 54 | struct regulator_dev *regulator; | ||
| 55 | u8 mode_mask; | ||
| 56 | u32 eco_microamp; | ||
| 57 | unsigned int valid_modes_mask; | ||
| 58 | }; | ||
| 59 | |||
| 60 | /* HI6421 regulators */ | ||
| 61 | enum hi6421_regulator_id { | ||
| 62 | HI6421_LDO0, | ||
| 63 | HI6421_LDO1, | ||
| 64 | HI6421_LDO2, | ||
| 65 | HI6421_LDO3, | ||
| 66 | HI6421_LDO4, | ||
| 67 | HI6421_LDO5, | ||
| 68 | HI6421_LDO6, | ||
| 69 | HI6421_LDO7, | ||
| 70 | HI6421_LDO8, | ||
| 71 | HI6421_LDO9, | ||
| 72 | HI6421_LDO10, | ||
| 73 | HI6421_LDO11, | ||
| 74 | HI6421_LDO12, | ||
| 75 | HI6421_LDO13, | ||
| 76 | HI6421_LDO14, | ||
| 77 | HI6421_LDO15, | ||
| 78 | HI6421_LDO16, | ||
| 79 | HI6421_LDO17, | ||
| 80 | HI6421_LDO18, | ||
| 81 | HI6421_LDO19, | ||
| 82 | HI6421_LDO20, | ||
| 83 | HI6421_LDOAUDIO, | ||
| 84 | HI6421_BUCK0, | ||
| 85 | HI6421_BUCK1, | ||
| 86 | HI6421_BUCK2, | ||
| 87 | HI6421_BUCK3, | ||
| 88 | HI6421_BUCK4, | ||
| 89 | HI6421_BUCK5, | ||
| 90 | HI6421_NUM_REGULATORS, | ||
| 91 | }; | ||
| 92 | |||
| 93 | #define HI6421_REGULATOR_OF_MATCH(_name, id) \ | ||
| 94 | { \ | ||
| 95 | .name = #_name, \ | ||
| 96 | .driver_data = (void *) HI6421_##id, \ | ||
| 97 | } | ||
| 98 | |||
| 99 | static struct of_regulator_match hi6421_regulator_match[] = { | ||
| 100 | HI6421_REGULATOR_OF_MATCH(hi6421_vout0, LDO0), | ||
| 101 | HI6421_REGULATOR_OF_MATCH(hi6421_vout1, LDO1), | ||
| 102 | HI6421_REGULATOR_OF_MATCH(hi6421_vout2, LDO2), | ||
| 103 | HI6421_REGULATOR_OF_MATCH(hi6421_vout3, LDO3), | ||
| 104 | HI6421_REGULATOR_OF_MATCH(hi6421_vout4, LDO4), | ||
| 105 | HI6421_REGULATOR_OF_MATCH(hi6421_vout5, LDO5), | ||
| 106 | HI6421_REGULATOR_OF_MATCH(hi6421_vout6, LDO6), | ||
| 107 | HI6421_REGULATOR_OF_MATCH(hi6421_vout7, LDO7), | ||
| 108 | HI6421_REGULATOR_OF_MATCH(hi6421_vout8, LDO8), | ||
| 109 | HI6421_REGULATOR_OF_MATCH(hi6421_vout9, LDO9), | ||
| 110 | HI6421_REGULATOR_OF_MATCH(hi6421_vout10, LDO10), | ||
| 111 | HI6421_REGULATOR_OF_MATCH(hi6421_vout11, LDO11), | ||
| 112 | HI6421_REGULATOR_OF_MATCH(hi6421_vout12, LDO12), | ||
| 113 | HI6421_REGULATOR_OF_MATCH(hi6421_vout13, LDO13), | ||
| 114 | HI6421_REGULATOR_OF_MATCH(hi6421_vout14, LDO14), | ||
| 115 | HI6421_REGULATOR_OF_MATCH(hi6421_vout15, LDO15), | ||
| 116 | HI6421_REGULATOR_OF_MATCH(hi6421_vout16, LDO16), | ||
| 117 | HI6421_REGULATOR_OF_MATCH(hi6421_vout17, LDO17), | ||
| 118 | HI6421_REGULATOR_OF_MATCH(hi6421_vout18, LDO18), | ||
| 119 | HI6421_REGULATOR_OF_MATCH(hi6421_vout19, LDO19), | ||
| 120 | HI6421_REGULATOR_OF_MATCH(hi6421_vout20, LDO20), | ||
| 121 | HI6421_REGULATOR_OF_MATCH(hi6421_vout_audio, LDOAUDIO), | ||
| 122 | HI6421_REGULATOR_OF_MATCH(hi6421_buck0, BUCK0), | ||
| 123 | HI6421_REGULATOR_OF_MATCH(hi6421_buck1, BUCK1), | ||
| 124 | HI6421_REGULATOR_OF_MATCH(hi6421_buck2, BUCK2), | ||
| 125 | HI6421_REGULATOR_OF_MATCH(hi6421_buck3, BUCK3), | ||
| 126 | HI6421_REGULATOR_OF_MATCH(hi6421_buck4, BUCK4), | ||
| 127 | HI6421_REGULATOR_OF_MATCH(hi6421_buck5, BUCK5), | ||
| 128 | }; | ||
| 129 | |||
| 130 | /* LDO 0, 4~7, 9~14, 16~20 have same voltage table. */ | ||
| 131 | static const unsigned int ldo_0_voltages[] = { | ||
| 132 | 1500000, 1800000, 2400000, 2500000, | ||
| 133 | 2600000, 2700000, 2850000, 3000000, | ||
| 134 | }; | ||
| 135 | |||
| 136 | /* LDO 8, 15 have same voltage table. */ | ||
| 137 | static const unsigned int ldo_8_voltages[] = { | ||
| 138 | 1500000, 1800000, 2400000, 2600000, | ||
| 139 | 2700000, 2850000, 3000000, 3300000, | ||
| 140 | }; | ||
| 141 | |||
| 142 | /* Ranges are sorted in ascending order. */ | ||
| 143 | static const struct regulator_linear_range ldo_audio_volt_range[] = { | ||
| 144 | REGULATOR_LINEAR_RANGE(2800000, 0, 3, 50000), | ||
| 145 | REGULATOR_LINEAR_RANGE(3000000, 4, 7, 100000), | ||
| 146 | }; | ||
| 147 | |||
| 148 | static const unsigned int buck_3_voltages[] = { | ||
