Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

regulator: pcf50633: Use linear_min_sel and regulator_[map|list]_voltage_linear

This driver can be converted to use linear_min_sel and
regulator_[map|list]_voltage_linear.

Below shows the equation (from Datasheet) for each LDOs.

For AUTOOUT:
VO(prog) = 0.625 + auto_out x 0.025 V; e.g.
(00000000 to 00101110: reserved)
00101111: 1.8 V (min)
01010011: 2.7 V
01101010: 3.275 V
01101011: 3.300 V
01101100: 3.325 V
01111111 : 3.800 V (max)

The linear mapping start from 0x2f selector.

Thus we convert this equation to:
VO(prog) = 1.8 + (selector - linear_min_sel) x 0.025 V
(min_uV = 1800000, uV_step = 25000, linear_min_sel = 0x2f)

For DOWNxOUT:
VO(prog) = 0.625 + downx_out x 0.025 V; e.g.
00000000 : 0.625 V (min)
00010111 : 1.200 V
00101111 : 1.800 V
01011111 : 3.000 V (max)

For xLDOOUT:
VO(prog) = 0.9 + xldo_out x 0.1 V; e.g.
00000: 0.9 V
00001: 1.0 V
11000 : 3.3 V
11011 : 3.6 V

Signed-off-by: Axel Lin <axel.lin@ingics.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>

authored by

Axel Lin and committed by
Mark Brown
05cf34c1 6b1f8a45

+28 -148
+28 -148
drivers/regulator/pcf50633-regulator.c
··· 24 24 #include <linux/mfd/pcf50633/core.h> 25 25 #include <linux/mfd/pcf50633/pmic.h> 26 26 27 - #define PCF50633_REGULATOR(_name, _id, _n) \ 27 + #define PCF50633_REGULATOR(_name, _id, _min_uV, _uV_step, _min_sel, _n) \ 28 28 { \ 29 29 .name = _name, \ 30 30 .id = PCF50633_REGULATOR_##_id, \ 31 31 .ops = &pcf50633_regulator_ops, \ 32 32 .n_voltages = _n, \ 33 + .min_uV = _min_uV, \ 34 + .uV_step = _uV_step, \ 35 + .linear_min_sel = _min_sel, \ 33 36 .type = REGULATOR_VOLTAGE, \ 34 37 .owner = THIS_MODULE, \ 35 38 .vsel_reg = PCF50633_REG_##_id##OUT, \ ··· 41 38 .enable_mask = PCF50633_REGULATOR_ON, \ 42 39 } 43 40 44 - /* Bits from voltage value */ 45 - static u8 auto_voltage_bits(unsigned int millivolts) 46 - { 47 - if (millivolts < 1800) 48 - return 0x2f; 49 - if (millivolts > 3800) 50 - return 0xff; 51 - 52 - millivolts -= 625; 53 - 54 - return millivolts / 25; 55 - } 56 - 57 - static u8 down_voltage_bits(unsigned int millivolts) 58 - { 59 - if (millivolts < 625) 60 - return 0; 61 - else if (millivolts > 3000) 62 - return 0xff; 63 - 64 - millivolts -= 625; 65 - 66 - return millivolts / 25; 67 - } 68 - 69 - static u8 ldo_voltage_bits(unsigned int millivolts) 70 - { 71 - if (millivolts < 900) 72 - return 0; 73 - else if (millivolts > 3600) 74 - return 0x1f; 75 - 76 - millivolts -= 900; 77 - return millivolts / 100; 78 - } 79 - 80 - /* Obtain voltage value from bits */ 81 - static unsigned int auto_voltage_value(u8 bits) 82 - { 83 - /* AUTOOUT: 00000000 to 00101110 are reserved. 84 - * Return 0 for bits in reserved range, which means this selector code 85 - * can't be used on this system */ 86 - if (bits < 0x2f) 87 - return 0; 88 - 89 - return 625 + (bits * 25); 90 - } 91 - 92 - 93 - static unsigned int down_voltage_value(u8 bits) 94 - { 95 - return 625 + (bits * 25); 96 - } 97 - 98 - 99 - static unsigned int ldo_voltage_value(u8 bits) 100 - { 101 - bits &= 0x1f; 102 - 103 - return 900 + (bits * 100); 104 - } 105 - 106 - static int pcf50633_regulator_map_voltage(struct regulator_dev *rdev, 107 - int min_uV, int max_uV) 108 - { 109 - struct pcf50633 *pcf; 110 - int regulator_id, millivolts; 111 - u8 volt_bits; 112 - 113 - pcf = rdev_get_drvdata(rdev); 114 - 115 - regulator_id = rdev_get_id(rdev); 116 - if (regulator_id >= PCF50633_NUM_REGULATORS) 117 - return -EINVAL; 118 - 119 - millivolts = min_uV / 1000; 120 - 121 - switch (regulator_id) { 122 - case PCF50633_REGULATOR_AUTO: 123 - volt_bits = auto_voltage_bits(millivolts); 124 - break; 125 - case PCF50633_REGULATOR_DOWN1: 126 - case PCF50633_REGULATOR_DOWN2: 127 - volt_bits = down_voltage_bits(millivolts); 128 - break; 129 - case PCF50633_REGULATOR_LDO1: 130 - case PCF50633_REGULATOR_LDO2: 131 - case PCF50633_REGULATOR_LDO3: 132 - case PCF50633_REGULATOR_LDO4: 133 - case PCF50633_REGULATOR_LDO5: 134 - case PCF50633_REGULATOR_LDO6: 135 - case PCF50633_REGULATOR_HCLDO: 136 - case PCF50633_REGULATOR_MEMLDO: 137 - volt_bits = ldo_voltage_bits(millivolts); 138 - break; 139 - default: 140 - return -EINVAL; 141 - } 142 - 143 - return volt_bits; 144 - } 145 - 146 - static int pcf50633_regulator_list_voltage(struct regulator_dev *rdev, 147 - unsigned int index) 148 - { 149 - int regulator_id = rdev_get_id(rdev); 150 - 151 - int millivolts; 152 - 153 - switch (regulator_id) { 154 - case PCF50633_REGULATOR_AUTO: 155 - millivolts = auto_voltage_value(index); 156 - break; 157 - case PCF50633_REGULATOR_DOWN1: 158 - case PCF50633_REGULATOR_DOWN2: 159 - millivolts = down_voltage_value(index); 160 - break; 161 - case PCF50633_REGULATOR_LDO1: 162 - case PCF50633_REGULATOR_LDO2: 163 - case PCF50633_REGULATOR_LDO3: 164 - case PCF50633_REGULATOR_LDO4: 165 - case PCF50633_REGULATOR_LDO5: 166 - case PCF50633_REGULATOR_LDO6: 167 - case PCF50633_REGULATOR_HCLDO: 168 - case PCF50633_REGULATOR_MEMLDO: 169 - millivolts = ldo_voltage_value(index); 170 - break; 171 - default: 172 - return -EINVAL; 173 - } 174 - 175 - return millivolts * 1000; 176 - } 177 - 178 41 static struct regulator_ops pcf50633_regulator_ops = { 179 42 .set_voltage_sel = regulator_set_voltage_sel_regmap, 180 43 .get_voltage_sel = regulator_get_voltage_sel_regmap, 181 - .list_voltage = pcf50633_regulator_list_voltage, 182 - .map_voltage = pcf50633_regulator_map_voltage, 44 + .list_voltage = regulator_list_voltage_linear, 45 + .map_voltage = regulator_map_voltage_linear, 183 46 .enable = regulator_enable_regmap, 184 47 .disable = regulator_disable_regmap, 185 48 .is_enabled = regulator_is_enabled_regmap, 186 49 }; 187 50 188 51 static const struct regulator_desc regulators[] = { 189 - [PCF50633_REGULATOR_AUTO] = PCF50633_REGULATOR("auto", AUTO, 128), 190 - [PCF50633_REGULATOR_DOWN1] = PCF50633_REGULATOR("down1", DOWN1, 96), 191 - [PCF50633_REGULATOR_DOWN2] = PCF50633_REGULATOR("down2", DOWN2, 96), 192 - [PCF50633_REGULATOR_LDO1] = PCF50633_REGULATOR("ldo1", LDO1, 28), 193 - [PCF50633_REGULATOR_LDO2] = PCF50633_REGULATOR("ldo2", LDO2, 28), 194 - [PCF50633_REGULATOR_LDO3] = PCF50633_REGULATOR("ldo3", LDO3, 28), 195 - [PCF50633_REGULATOR_LDO4] = PCF50633_REGULATOR("ldo4", LDO4, 28), 196 - [PCF50633_REGULATOR_LDO5] = PCF50633_REGULATOR("ldo5", LDO5, 28), 197 - [PCF50633_REGULATOR_LDO6] = PCF50633_REGULATOR("ldo6", LDO6, 28), 198 - [PCF50633_REGULATOR_HCLDO] = PCF50633_REGULATOR("hcldo", HCLDO, 28), 199 - [PCF50633_REGULATOR_MEMLDO] = PCF50633_REGULATOR("memldo", MEMLDO, 28), 52 + [PCF50633_REGULATOR_AUTO] = 53 + PCF50633_REGULATOR("auto", AUTO, 1800000, 25000, 0x2f, 128), 54 + [PCF50633_REGULATOR_DOWN1] = 55 + PCF50633_REGULATOR("down1", DOWN1, 625000, 25000, 0, 96), 56 + [PCF50633_REGULATOR_DOWN2] = 57 + PCF50633_REGULATOR("down2", DOWN2, 625000, 25000, 0, 96), 58 + [PCF50633_REGULATOR_LDO1] = 59 + PCF50633_REGULATOR("ldo1", LDO1, 900000, 100000, 0, 28), 60 + [PCF50633_REGULATOR_LDO2] = 61 + PCF50633_REGULATOR("ldo2", LDO2, 900000, 100000, 0, 28), 62 + [PCF50633_REGULATOR_LDO3] = 63 + PCF50633_REGULATOR("ldo3", LDO3, 900000, 100000, 0, 28), 64 + [PCF50633_REGULATOR_LDO4] = 65 + PCF50633_REGULATOR("ldo4", LDO4, 900000, 100000, 0, 28), 66 + [PCF50633_REGULATOR_LDO5] = 67 + PCF50633_REGULATOR("ldo5", LDO5, 900000, 100000, 0, 28), 68 + [PCF50633_REGULATOR_LDO6] = 69 + PCF50633_REGULATOR("ldo6", LDO6, 900000, 100000, 0, 28), 70 + [PCF50633_REGULATOR_HCLDO] = 71 + PCF50633_REGULATOR("hcldo", HCLDO, 900000, 100000, 0, 28), 72 + [PCF50633_REGULATOR_MEMLDO] = 73 + PCF50633_REGULATOR("memldo", MEMLDO, 900000, 100000, 0, 28), 200 74 }; 201 75 202 76 static int __devinit pcf50633_regulator_probe(struct platform_device *pdev)