diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-22 10:38:37 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-22 10:38:37 -0500 |
commit | fcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch) | |
tree | a57612d1888735a2ec7972891b68c1ac5ec8faea /drivers/regulator | |
parent | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff) |
Diffstat (limited to 'drivers/regulator')
-rw-r--r-- | drivers/regulator/bq24022.c | 161 | ||||
-rw-r--r-- | drivers/regulator/fan53555-regulator.c | 567 | ||||
-rw-r--r-- | drivers/regulator/gpio-switch-regulator.c | 412 | ||||
-rw-r--r-- | drivers/regulator/max77663-regulator.c | 928 | ||||
-rw-r--r-- | drivers/regulator/max8907c-regulator.c | 421 | ||||
-rw-r--r-- | drivers/regulator/ricoh583-regulator.c | 412 | ||||
-rw-r--r-- | drivers/regulator/tps6591x-regulator.c | 955 |
7 files changed, 3856 insertions, 0 deletions
diff --git a/drivers/regulator/bq24022.c b/drivers/regulator/bq24022.c new file mode 100644 index 00000000000..068d488a4f7 --- /dev/null +++ b/drivers/regulator/bq24022.c | |||
@@ -0,0 +1,161 @@ | |||
1 | /* | ||
2 | * Support for TI bq24022 (bqTINY-II) Dual Input (USB/AC Adpater) | ||
3 | * 1-Cell Li-Ion Charger connected via GPIOs. | ||
4 | * | ||
5 | * Copyright (c) 2008 Philipp Zabel | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | */ | ||
12 | |||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/err.h> | ||
17 | #include <linux/gpio.h> | ||
18 | #include <linux/regulator/bq24022.h> | ||
19 | #include <linux/regulator/driver.h> | ||
20 | |||
21 | |||
22 | static int bq24022_set_current_limit(struct regulator_dev *rdev, | ||
23 | int min_uA, int max_uA) | ||
24 | { | ||
25 | struct bq24022_mach_info *pdata = rdev_get_drvdata(rdev); | ||
26 | |||
27 | dev_dbg(rdev_get_dev(rdev), "setting current limit to %s mA\n", | ||
28 | max_uA >= 500000 ? "500" : "100"); | ||
29 | |||
30 | /* REVISIT: maybe return error if min_uA != 0 ? */ | ||
31 | gpio_set_value(pdata->gpio_iset2, max_uA >= 500000); | ||
32 | return 0; | ||
33 | } | ||
34 | |||
35 | static int bq24022_get_current_limit(struct regulator_dev *rdev) | ||
36 | { | ||
37 | struct bq24022_mach_info *pdata = rdev_get_drvdata(rdev); | ||
38 | |||
39 | return gpio_get_value(pdata->gpio_iset2) ? 500000 : 100000; | ||
40 | } | ||
41 | |||
42 | static int bq24022_enable(struct regulator_dev *rdev) | ||
43 | { | ||
44 | struct bq24022_mach_info *pdata = rdev_get_drvdata(rdev); | ||
45 | |||
46 | dev_dbg(rdev_get_dev(rdev), "enabling charger\n"); | ||
47 | |||
48 | gpio_set_value(pdata->gpio_nce, 0); | ||
49 | return 0; | ||
50 | } | ||
51 | |||
52 | static int bq24022_disable(struct regulator_dev *rdev) | ||
53 | { | ||
54 | struct bq24022_mach_info *pdata = rdev_get_drvdata(rdev); | ||
55 | |||
56 | dev_dbg(rdev_get_dev(rdev), "disabling charger\n"); | ||
57 | |||
58 | gpio_set_value(pdata->gpio_nce, 1); | ||
59 | return 0; | ||
60 | } | ||
61 | |||
62 | static int bq24022_is_enabled(struct regulator_dev *rdev) | ||
63 | { | ||
64 | struct bq24022_mach_info *pdata = rdev_get_drvdata(rdev); | ||
65 | |||
66 | return !gpio_get_value(pdata->gpio_nce); | ||
67 | } | ||
68 | |||
69 | static struct regulator_ops bq24022_ops = { | ||
70 | .set_current_limit = bq24022_set_current_limit, | ||
71 | .get_current_limit = bq24022_get_current_limit, | ||
72 | .enable = bq24022_enable, | ||
73 | .disable = bq24022_disable, | ||
74 | .is_enabled = bq24022_is_enabled, | ||
75 | }; | ||
76 | |||
77 | static struct regulator_desc bq24022_desc = { | ||
78 | .name = "bq24022", | ||
79 | .ops = &bq24022_ops, | ||
80 | .type = REGULATOR_CURRENT, | ||
81 | .owner = THIS_MODULE, | ||
82 | }; | ||
83 | |||
84 | static int __init bq24022_probe(struct platform_device *pdev) | ||
85 | { | ||
86 | struct bq24022_mach_info *pdata = pdev->dev.platform_data; | ||
87 | struct regulator_dev *bq24022; | ||
88 | int ret; | ||
89 | |||
90 | if (!pdata || !pdata->gpio_nce || !pdata->gpio_iset2) | ||
91 | return -EINVAL; | ||
92 | |||
93 | ret = gpio_request(pdata->gpio_nce, "ncharge_en"); | ||
94 | if (ret) { | ||
95 | dev_dbg(&pdev->dev, "couldn't request nCE GPIO: %d\n", | ||
96 | pdata->gpio_nce); | ||
97 | goto err_ce; | ||
98 | } | ||
99 | ret = gpio_request(pdata->gpio_iset2, "charge_mode"); | ||
100 | if (ret) { | ||
101 | dev_dbg(&pdev->dev, "couldn't request ISET2 GPIO: %d\n", | ||
102 | pdata->gpio_iset2); | ||
103 | goto err_iset2; | ||
104 | } | ||
105 | ret = gpio_direction_output(pdata->gpio_iset2, 0); | ||
106 | ret = gpio_direction_output(pdata->gpio_nce, 1); | ||
107 | |||
108 | bq24022 = regulator_register(&bq24022_desc, &pdev->dev, | ||
109 | pdata->init_data, pdata); | ||
110 | if (IS_ERR(bq24022)) { | ||
111 | dev_dbg(&pdev->dev, "couldn't register regulator\n"); | ||
112 | ret = PTR_ERR(bq24022); | ||
113 | goto err_reg; | ||
114 | } | ||
115 | platform_set_drvdata(pdev, bq24022); | ||
116 | dev_dbg(&pdev->dev, "registered regulator\n"); | ||
117 | |||
118 | return 0; | ||
119 | err_reg: | ||
120 | gpio_free(pdata->gpio_iset2); | ||
121 | err_iset2: | ||
122 | gpio_free(pdata->gpio_nce); | ||
123 | err_ce: | ||
124 | return ret; | ||
125 | } | ||
126 | |||
127 | static int __devexit bq24022_remove(struct platform_device *pdev) | ||
128 | { | ||
129 | struct bq24022_mach_info *pdata = pdev->dev.platform_data; | ||
130 | struct regulator_dev *bq24022 = platform_get_drvdata(pdev); | ||
131 | |||
132 | regulator_unregister(bq24022); | ||
133 | gpio_free(pdata->gpio_iset2); | ||
134 | gpio_free(pdata->gpio_nce); | ||
135 | |||
136 | return 0; | ||
137 | } | ||
138 | |||
139 | static struct platform_driver bq24022_driver = { | ||
140 | .driver = { | ||
141 | .name = "bq24022", | ||
142 | }, | ||
143 | .remove = __devexit_p(bq24022_remove), | ||
144 | }; | ||
145 | |||
146 | static int __init bq24022_init(void) | ||
147 | { | ||
148 | return platform_driver_probe(&bq24022_driver, bq24022_probe); | ||
149 | } | ||
150 | |||
151 | static void __exit bq24022_exit(void) | ||
152 | { | ||
153 | platform_driver_unregister(&bq24022_driver); | ||
154 | } | ||
155 | |||
156 | module_init(bq24022_init); | ||
157 | module_exit(bq24022_exit); | ||
158 | |||
159 | MODULE_AUTHOR("Philipp Zabel"); | ||
160 | MODULE_DESCRIPTION("TI bq24022 Li-Ion Charger driver"); | ||
161 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/regulator/fan53555-regulator.c b/drivers/regulator/fan53555-regulator.c new file mode 100644 index 00000000000..13fa79c4ba3 --- /dev/null +++ b/drivers/regulator/fan53555-regulator.c | |||
@@ -0,0 +1,567 @@ | |||
1 | /* | ||
2 | * driver/regultor/fan53555-regulator.c | ||
3 | * | ||
4 | * Driver for FAN53555UC00X, FAN53555UC01X, FAN53555UC03X, | ||
5 | * FAN53555UC04X, FAN53555UC05X | ||
6 | * | ||
7 | * Copyright (c) 2011, NVIDIA Corporation. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License as | ||
11 | * published by the Free Software Foundation version 2. | ||
12 | * | ||
13 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind, | ||
14 | * whether express or implied; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16 | * General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||
21 | * 02111-1307, USA | ||
22 | */ | ||
23 | |||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/init.h> | ||
27 | #include <linux/err.h> | ||
28 | #include <linux/platform_device.h> | ||
29 | #include <linux/regulator/driver.h> | ||
30 | #include <linux/regulator/machine.h> | ||
31 | #include <linux/regulator/fan53555-regulator.h> | ||
32 | #include <linux/i2c.h> | ||
33 | #include <linux/delay.h> | ||
34 | #include <linux/slab.h> | ||
35 | |||
36 | /* Register definitions */ | ||
37 | #define FAN53555_REG_VSEL0 0 | ||
38 | #define FAN53555_REG_VSEL1 1 | ||
39 | #define FAN53555_REG_CONTROL 2 | ||
40 | #define FAN53555_REG_ID1 3 | ||
41 | #define FAN53555_REG_ID2 4 | ||
42 | #define FAN53555_REG_MONITOR 5 | ||
43 | |||
44 | #define FAN53555_VSEL_BUCK_EN BIT(7) | ||
45 | #define FAN53555_VSEL_MODE BIT(6) | ||
46 | #define FAN53555_VSEL_NSEL_SHIFT 0 | ||
47 | #define FAN53555_VSEL_NSEL_MASK 0x3F | ||
48 | |||
49 | #define FAN53555_CONTROL_DISCHARGE BIT(7) | ||
50 | #define FAN53555_CONTROL_SLEW_SHIFT 4 | ||
51 | #define FAN53555_CONTROL_SLEW_MASK 0x70 | ||
52 | #define FAN53555_CONTROL_RESET BIT(2) | ||
53 | |||
54 | #define FAN53555_ID1_VENDOR_SHIFT 4 | ||
55 | #define FAN53555_ID1_VENDOR_MASK 0xF0 | ||
56 | #define FAN53555_ID1_DIE_ID_SHIFT 0 | ||
57 | #define FAN53555_ID1_DIE_ID_MASK 0x0F | ||
58 | |||
59 | #define FAN53555_ID2_REV_SHIFT 0 | ||
60 | #define FAN53555_ID2_REV_MASK 0x0F | ||
61 | |||
62 | #define FAN53555_MONITOR_ILIM BIT(7) | ||
63 | #define FAN53555_MONITOR_UVLO BIT(6) | ||
64 | #define FAN53555_MONITOR_OVP BIT(5) | ||
65 | #define FAN53555_MONITOR_POS BIT(4) | ||
66 | #define FAN53555_MONITOR_NEG BIT(3) | ||
67 | #define FAN53555_MONITOR_RESET_STAT BIT(2) | ||
68 | #define FAN53555_MONITOR_OT BIT(1) | ||
69 | #define FAN53555_MONITOR_BUCK_STATUS BIT(0) | ||
70 | |||
71 | #define FAN53555_VSEL0_ID 0 | ||
72 | #define FAN53555_VSEL1_ID 1 | ||
73 | |||
74 | #define FAN53555UC00X_ID 0x80 | ||
75 | #define FAN53555UC01X_ID 0x81 | ||
76 | #define FAN53555UC03X_ID 0x83 | ||
77 | #define FAN53555UC04X_ID 0x84 | ||
78 | #define FAN53555UC05X_ID 0x85 | ||
79 | |||
80 | #define FAN53555_N_VOLTAGES 64 | ||
81 | |||
82 | /* FAN53555 chip information */ | ||
83 | struct fan53555_chip { | ||
84 | const char *name; | ||
85 | struct device *dev; | ||
86 | struct regulator_desc desc; | ||
87 | struct i2c_client *client; | ||
88 | struct regulator_dev *rdev; | ||
89 | struct mutex io_lock; | ||
90 | int chip_id; | ||
91 | int vsel_id; | ||
92 | u8 shadow[6]; | ||
93 | }; | ||
94 | |||
95 | #define FAN53555_VOLTAGE(chip_id, vsel) \ | ||
96 | (((chip_id) == FAN53555UC04X_ID) ? \ | ||
97 | ((vsel) * 12826 + 600000) : ((vsel) * 10000 + 600000)) | ||
98 | |||
99 | static int fan53555_read(struct fan53555_chip *fan, u8 reg) | ||
100 | { | ||
101 | u8 data; | ||
102 | u8 val; | ||
103 | int ret; | ||
104 | |||
105 | data = reg; | ||
106 | |||
107 | ret = i2c_master_send(fan->client, &data, 1); | ||
108 | if (ret < 0) | ||
109 | goto out; | ||
110 | |||
111 | ret = i2c_master_recv(fan->client, &val, 1); | ||
112 | if (ret < 0) | ||
113 | goto out; | ||
114 | |||
115 | ret = val; | ||
116 | out: | ||
117 | return ret; | ||
118 | } | ||
119 | |||
120 | static inline int fan53555_write(struct fan53555_chip *fan, u8 reg, u8 val) | ||
121 | { | ||
122 | u8 msg[2]; | ||
123 | int ret; | ||
124 | |||
125 | msg[0] = reg; | ||
126 | msg[1] = val; | ||
127 | |||
128 | ret = i2c_master_send(fan->client, msg, 2); | ||
129 | if (ret < 0) | ||
130 | return ret; | ||
131 | if (ret != 2) | ||
132 | return -EIO; | ||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | static int fan53555_read_reg(struct fan53555_chip *fan, u8 reg) | ||
137 | { | ||
138 | int data; | ||
139 | |||
140 | mutex_lock(&fan->io_lock); | ||
141 | data = fan53555_read(fan, reg); | ||
142 | if (data < 0) | ||
143 | dev_err(fan->dev, "Read from reg 0x%x failed\n", reg); | ||
144 | mutex_unlock(&fan->io_lock); | ||
145 | |||
146 | return data; | ||
147 | } | ||
148 | |||
149 | static int fan53555_set_bits(struct fan53555_chip *fan, u8 reg, u8 mask, u8 val) | ||
150 | { | ||
151 | int err; | ||
152 | u8 data; | ||
153 | |||
154 | mutex_lock(&fan->io_lock); | ||
155 | data = fan->shadow[reg]; | ||
156 | data &= ~mask; | ||
157 | val &= mask; | ||
158 | data |= val; | ||
159 | err = fan53555_write(fan, reg, data); | ||
160 | if (err) | ||
161 | dev_err(fan->dev, "write for reg 0x%x failed\n", reg); | ||
162 | else | ||
163 | fan->shadow[reg] = data; | ||
164 | mutex_unlock(&fan->io_lock); | ||
165 | |||
166 | return err; | ||
167 | } | ||
168 | |||
169 | static int __fan53555_dcdc_set_voltage(struct fan53555_chip *fan, | ||
170 | int vsel_id, int min_uV, int max_uV, | ||
171 | unsigned *selector) | ||
172 | { | ||
173 | int nsel; | ||
174 | int uV; | ||
175 | int chip_id; | ||
176 | int n_voltages; | ||
177 | |||
178 | chip_id = fan->chip_id; | ||
179 | n_voltages = fan->desc.n_voltages; | ||
180 | |||
181 | if (max_uV < min_uV) { | ||
182 | dev_err(fan->dev, "max_uV(%d) < min_uV(%d)\n", max_uV, min_uV); | ||
183 | return -EINVAL; | ||
184 | } | ||
185 | if (min_uV > FAN53555_VOLTAGE(chip_id, n_voltages - 1)) { | ||
186 | dev_err(fan->dev, "min_uV(%d) > %d[uV]\n", | ||
187 | min_uV, FAN53555_VOLTAGE(chip_id, n_voltages - 1)); | ||
188 | return -EINVAL; | ||
189 | } | ||
190 | if (max_uV < FAN53555_VOLTAGE(chip_id, 0)) { | ||
191 | dev_err(fan->dev, "max_uV(%d) < %d[uV]\n", | ||
192 | max_uV, FAN53555_VOLTAGE(chip_id, 0)); | ||
193 | return -EINVAL; | ||
194 | } | ||
195 | if ((vsel_id != FAN53555_VSEL0_ID) && (vsel_id != FAN53555_VSEL1_ID)) { | ||
196 | dev_err(fan->dev, | ||
197 | "%d is not valid VSEL register ID\n", vsel_id); | ||
198 | return -EINVAL; | ||
199 | } | ||
200 | for (nsel = 0; nsel < n_voltages; nsel++) { | ||
201 | uV = FAN53555_VOLTAGE(chip_id, nsel); | ||
202 | if (min_uV <= uV && uV <= max_uV) { | ||
203 | if (selector) | ||
204 | *selector = nsel; | ||
205 | return fan53555_set_bits(fan, | ||
206 | FAN53555_REG_VSEL0 + vsel_id, | ||
207 | FAN53555_VSEL_NSEL_MASK, | ||
208 | nsel << | ||
209 | FAN53555_VSEL_NSEL_SHIFT); | ||
210 | } | ||
211 | } | ||
212 | |||
213 | return -EINVAL; | ||
214 | } | ||
215 | |||
216 | #ifdef CONFIG_DEBUG_FS | ||
217 | |||
218 | #include <linux/debugfs.h> | ||
219 | #include <linux/seq_file.h> | ||
220 | |||
221 | static int dbg_fan_show(struct seq_file *s, void *unused) | ||
222 | { | ||
223 | struct fan53555_chip *fan = s->private; | ||
224 | int val; | ||
225 | |||
226 | seq_printf(s, "FAN53555 Registers\n"); | ||
227 | seq_printf(s, "------------------\n"); | ||
228 | |||
229 | val = fan53555_read_reg(fan, FAN53555_REG_VSEL0); | ||
230 | if (val >= 0) | ||
231 | seq_printf(s, "Reg VSEL0 Value 0x%02x\n", val); | ||
232 | |||
233 | val = fan53555_read_reg(fan, FAN53555_REG_VSEL1); | ||
234 | if (val >= 0) | ||
235 | seq_printf(s, "Reg VSEL1 Value 0x%02x\n", val); | ||
236 | |||
237 | val = fan53555_read_reg(fan, FAN53555_REG_CONTROL); | ||
238 | if (val >= 0) | ||
239 | seq_printf(s, "Reg CONTROL Value 0x%02x\n", val); | ||
240 | |||
241 | val = fan53555_read_reg(fan, FAN53555_REG_ID1); | ||
242 | if (val >= 0) | ||
243 | seq_printf(s, "Reg ID1 Value 0x%02x\n", val); | ||
244 | |||
245 | val = fan53555_read_reg(fan, FAN53555_REG_ID2); | ||
246 | if (val >= 0) | ||
247 | seq_printf(s, "Reg ID2 Value 0x%02x\n", val); | ||
248 | |||
249 | val = fan53555_read_reg(fan, FAN53555_REG_MONITOR); | ||
250 | if (val >= 0) | ||
251 | seq_printf(s, "Reg MONITOR Value 0x%02x\n", val); | ||
252 | |||
253 | return 0; | ||
254 | } | ||
255 | |||
256 | static int dbg_fan_open(struct inode *inode, struct file *file) | ||
257 | { | ||
258 | return single_open(file, dbg_fan_show, inode->i_private); | ||
259 | } | ||
260 | |||
261 | static const struct file_operations debug_fops = { | ||
262 | .open = dbg_fan_open, | ||
263 | .read = seq_read, | ||
264 | .llseek = seq_lseek, | ||
265 | .release = single_release, | ||
266 | }; | ||
267 | |||
268 | static void __init fan53555_debuginit(struct fan53555_chip *fan) | ||
269 | { | ||
270 | (void)debugfs_create_file("fan53555", S_IRUGO, NULL, fan, &debug_fops); | ||
271 | } | ||
272 | #else | ||
273 | static void __init fan53555_debuginit(struct fan53555_chip *fan) | ||
274 | { | ||
275 | } | ||
276 | #endif | ||
277 | |||
278 | static int fan53555_dcdc_init(struct fan53555_chip *fan, | ||
279 | struct i2c_client *client, | ||
280 | struct fan53555_regulator_platform_data *pdata) | ||
281 | { | ||
282 | int err; | ||
283 | int val; | ||
284 | |||
285 | err = fan53555_read_reg(fan, FAN53555_REG_VSEL0); | ||
286 | if (err < 0) | ||
287 | return err; | ||
288 | fan->shadow[FAN53555_REG_VSEL0] = (u8)err; | ||
289 | |||
290 | err = fan53555_read_reg(fan, FAN53555_REG_VSEL1); | ||
291 | if (err < 0) | ||
292 | return err; | ||
293 | fan->shadow[FAN53555_REG_VSEL1] = (u8)err; | ||
294 | |||
295 | err = fan53555_read_reg(fan, FAN53555_REG_CONTROL); | ||
296 | if (err < 0) | ||
297 | return err; | ||
298 | fan->shadow[FAN53555_REG_CONTROL] = (u8)err; | ||
299 | |||
300 | err = __fan53555_dcdc_set_voltage(fan, | ||
301 | FAN53555_VSEL0_ID, | ||
302 | pdata->init_vsel0_min_uV, | ||
303 | pdata->init_vsel0_max_uV, | ||
304 | NULL); | ||
305 | if (err < 0) | ||
306 | return err; | ||
307 | |||
308 | val = pdata->vsel0_buck_en ? FAN53555_VSEL_BUCK_EN : 0; | ||
309 | val |= pdata->vsel0_mode ? FAN53555_VSEL_MODE : 0; | ||
310 | err = fan53555_set_bits(fan, | ||
311 | FAN53555_REG_VSEL0, | ||
312 | FAN53555_VSEL_BUCK_EN | FAN53555_VSEL_MODE, | ||
313 | val); | ||
314 | if (err < 0) | ||
315 | return err; | ||
316 | |||
317 | err = __fan53555_dcdc_set_voltage(fan, | ||
318 | FAN53555_VSEL1_ID, | ||
319 | pdata->init_vsel1_min_uV, | ||
320 | pdata->init_vsel1_max_uV, | ||
321 | NULL); | ||
322 | if (err < 0) | ||
323 | return err; | ||
324 | |||
325 | val = pdata->vsel1_buck_en ? FAN53555_VSEL_BUCK_EN : 0; | ||
326 | val |= pdata->vsel1_mode ? FAN53555_VSEL_MODE : 0; | ||
327 | err = fan53555_set_bits(fan, | ||
328 | FAN53555_REG_VSEL1, | ||
329 | FAN53555_VSEL_BUCK_EN | FAN53555_VSEL_MODE, | ||
330 | val); | ||
331 | if (err < 0) | ||
332 | return err; | ||
333 | |||
334 | val = pdata->slew_rate; | ||
335 | val <<= FAN53555_CONTROL_SLEW_SHIFT; | ||
336 | val |= pdata->output_discharge ? FAN53555_CONTROL_DISCHARGE : 0; | ||
337 | err = fan53555_set_bits(fan, | ||
338 | FAN53555_REG_CONTROL, | ||
339 | FAN53555_CONTROL_DISCHARGE | | ||
340 | FAN53555_CONTROL_SLEW_MASK, val); | ||
341 | return err; | ||
342 | } | ||
343 | |||
344 | static int fan53555_dcdc_list_voltage(struct regulator_dev *dev, | ||
345 | unsigned selector) | ||
346 | { | ||
347 | struct fan53555_chip *fan = rdev_get_drvdata(dev); | ||
348 | |||
349 | if ((selector < 0) || (selector >= fan->desc.n_voltages)) | ||
350 | return -EINVAL; | ||
351 | |||
352 | return FAN53555_VOLTAGE(fan->chip_id, selector); | ||
353 | } | ||
354 | |||
355 | static int fan53555_dcdc_set_voltage(struct regulator_dev *dev, | ||
356 | int min_uV, int max_uV, | ||
357 | unsigned *selector) | ||
358 | { | ||
359 | struct fan53555_chip *fan = rdev_get_drvdata(dev); | ||
360 | |||
361 | return __fan53555_dcdc_set_voltage(fan, fan->vsel_id, min_uV, max_uV, | ||
362 | selector); | ||
363 | } | ||
364 | |||
365 | static int fan53555_dcdc_get_voltage(struct regulator_dev *dev) | ||
366 | { | ||
367 | struct fan53555_chip *fan = rdev_get_drvdata(dev); | ||
368 | u8 data; | ||
369 | |||
370 | if ((fan->vsel_id != FAN53555_VSEL0_ID) && | ||
371 | (fan->vsel_id != FAN53555_VSEL1_ID)) { | ||
372 | dev_err(fan->dev, | ||
373 | "%d is not valid VSEL register ID\n", fan->vsel_id); | ||
374 | return -EINVAL; | ||
375 | } | ||
376 | data = fan->shadow[FAN53555_REG_VSEL0 + fan->vsel_id]; | ||
377 | data &= FAN53555_VSEL_NSEL_MASK; | ||
378 | data >>= FAN53555_VSEL_NSEL_SHIFT; | ||
379 | |||
380 | return FAN53555_VOLTAGE(fan->chip_id, data); | ||
381 | } | ||
382 | |||
383 | static int fan53555_dcdc_enable(struct regulator_dev *dev) | ||
384 | { | ||
385 | struct fan53555_chip *fan = rdev_get_drvdata(dev); | ||
386 | |||
387 | if ((fan->vsel_id != FAN53555_VSEL0_ID) && | ||
388 | (fan->vsel_id != FAN53555_VSEL1_ID)) { | ||
389 | dev_err(fan->dev, | ||
390 | "%d is not valid VSEL register ID\n", fan->vsel_id); | ||
391 | return -EINVAL; | ||
392 | } | ||
393 | |||
394 | return fan53555_set_bits(fan, | ||
395 | FAN53555_REG_VSEL0 + fan->vsel_id, | ||
396 | FAN53555_VSEL_BUCK_EN, FAN53555_VSEL_BUCK_EN); | ||
397 | } | ||
398 | |||
399 | static int fan53555_dcdc_disable(struct regulator_dev *dev) | ||
400 | { | ||
401 | struct fan53555_chip *fan = rdev_get_drvdata(dev); | ||
402 | |||
403 | if ((fan->vsel_id != FAN53555_VSEL0_ID) && | ||
404 | (fan->vsel_id != FAN53555_VSEL1_ID)) { | ||
405 | dev_err(fan->dev, | ||
406 | "%d is not valid VSEL register ID\n", fan->vsel_id); | ||
407 | return -EINVAL; | ||
408 | } | ||
409 | |||
410 | return fan53555_set_bits(fan, | ||
411 | FAN53555_REG_VSEL0 + fan->vsel_id, | ||
412 | FAN53555_VSEL_BUCK_EN, 0); | ||
413 | } | ||
414 | |||
415 | static int fan53555_dcdc_is_enabled(struct regulator_dev *dev) | ||
416 | { | ||
417 | struct fan53555_chip *fan = rdev_get_drvdata(dev); | ||
418 | u8 data; | ||
419 | |||
420 | if ((fan->vsel_id != FAN53555_VSEL0_ID) && | ||
421 | (fan->vsel_id != FAN53555_VSEL1_ID)) { | ||
422 | dev_err(fan->dev, | ||
423 | "%d is not valid VSEL register ID\n", fan->vsel_id); | ||
424 | return -EINVAL; | ||
425 | } | ||
426 | data = fan->shadow[FAN53555_REG_VSEL0 + fan->vsel_id]; | ||
427 | |||
428 | return (data & FAN53555_VSEL_BUCK_EN) ? 1 : 0; | ||
429 | } | ||
430 | |||
431 | static struct regulator_ops fan53555_dcdc_ops = { | ||
432 | .list_voltage = fan53555_dcdc_list_voltage, | ||
433 | .set_voltage = fan53555_dcdc_set_voltage, | ||
434 | .get_voltage = fan53555_dcdc_get_voltage, | ||
435 | .enable = fan53555_dcdc_enable, | ||
436 | .disable = fan53555_dcdc_disable, | ||
437 | .is_enabled = fan53555_dcdc_is_enabled, | ||
438 | }; | ||
439 | |||
440 | static int __devinit fan53555_probe(struct i2c_client *client, | ||
441 | const struct i2c_device_id *id) | ||
442 | { | ||
443 | struct fan53555_regulator_platform_data *pdata; | ||
444 | struct regulator_init_data *init_data; | ||
445 | struct regulator_dev *rdev; | ||
446 | struct fan53555_chip *fan; | ||
447 | int chip_id; | ||
448 | int err; | ||
449 | |||
450 | pdata = client->dev.platform_data; | ||
451 | if (!pdata) { | ||
452 | dev_err(&client->dev, "Err: Platform data not found\n"); | ||
453 | return -EIO; | ||
454 | } | ||
455 | init_data = &pdata->reg_init_data; | ||
456 | fan = kzalloc(sizeof(*fan), GFP_KERNEL); | ||
457 | if (!fan) { | ||
458 | dev_err(&client->dev, "Err: Memory allocation fails\n"); | ||
459 | return -ENOMEM; | ||
460 | } | ||
461 | mutex_init(&fan->io_lock); | ||
462 | fan->client = client; | ||
463 | fan->dev = &client->dev; | ||
464 | fan->vsel_id = pdata->vsel_id; | ||
465 | fan->name = id->name; | ||
466 | fan->desc.name = id->name; | ||
467 | fan->desc.id = 0; | ||
468 | fan->desc.irq = 0; | ||
469 | fan->desc.ops = &fan53555_dcdc_ops; | ||
470 | fan->desc.type = REGULATOR_VOLTAGE; | ||
471 | fan->desc.owner = THIS_MODULE; | ||
472 | fan->desc.n_voltages = FAN53555_N_VOLTAGES; | ||
473 | i2c_set_clientdata(client, fan); | ||
474 | |||
475 | chip_id = fan53555_read_reg(fan, FAN53555_REG_ID1); | ||
476 | if (chip_id < 0) { | ||
477 | err = chip_id; | ||
478 | dev_err(fan->dev, "Error in reading device %d\n", err); | ||
479 | goto fail; | ||
480 | } | ||
481 | |||
482 | switch (chip_id) { | ||
483 | case FAN53555UC00X_ID: | ||
484 | case FAN53555UC01X_ID: | ||
485 | case FAN53555UC03X_ID: | ||
486 | case FAN53555UC04X_ID: | ||
487 | case FAN53555UC05X_ID: | ||
488 | fan->chip_id = chip_id; | ||
489 | break; | ||
490 | default: | ||
491 | dev_err(fan->dev, "Err: not supported device chip id 0x%x", | ||
492 | chip_id); | ||
493 | err = -ENODEV; | ||
494 | goto fail; | ||
495 | } | ||
496 | |||
497 | err = fan53555_dcdc_init(fan, client, pdata); | ||
498 | if (err < 0) { | ||
499 | dev_err(fan->dev, "FAN53555 init fails with %d\n", err); | ||
500 | goto fail; | ||
501 | } | ||
502 | |||
503 | rdev = regulator_register(&fan->desc, &client->dev, init_data, fan); | ||
504 | if (IS_ERR(rdev)) { | ||
505 | dev_err(fan->dev, "Failed to register %s\n", id->name); | ||
506 | err = PTR_ERR(rdev); | ||
507 | goto fail; | ||
508 | } | ||
509 | fan->rdev = rdev; | ||
510 | |||
511 | fan53555_debuginit(fan); | ||
512 | return 0; | ||
513 | |||
514 | fail: | ||
515 | kfree(fan); | ||
516 | return err; | ||
517 | } | ||
518 | |||
519 | /** | ||
520 | * fan53555_remove - fan53555 driver i2c remove handler | ||
521 | * @client: i2c driver client device structure | ||
522 | * | ||
523 | * Unregister fan53555 driver as an i2c client device driver | ||
524 | */ | ||
525 | static int __devexit fan53555_remove(struct i2c_client *client) | ||
526 | { | ||
527 | struct fan53555_chip *chip = i2c_get_clientdata(client); | ||
528 | |||
529 | regulator_unregister(chip->rdev); | ||
530 | kfree(chip); | ||
531 | return 0; | ||
532 | } | ||
533 | |||
534 | static const struct i2c_device_id fan53555_id[] = { | ||
535 | {.name = "fan53555", .driver_data = 0 }, | ||
536 | {}, | ||
537 | }; | ||
538 | MODULE_DEVICE_TABLE(i2c, fan53555_id); | ||
539 | |||
540 | static struct i2c_driver fan53555_i2c_driver = { | ||
541 | .driver = { | ||
542 | .name = "fan53555", | ||
543 | .owner = THIS_MODULE, | ||
544 | }, | ||
545 | .probe = fan53555_probe, | ||
546 | .remove = __devexit_p(fan53555_remove), | ||
547 | .id_table = fan53555_id, | ||
548 | }; | ||
549 | |||
550 | /* Module init function */ | ||
551 | static int __init fan53555_init(void) | ||
552 | { | ||
553 | return i2c_add_driver(&fan53555_i2c_driver); | ||
554 | } | ||
555 | subsys_initcall_sync(fan53555_init); | ||
556 | |||
557 | /* Module exit function */ | ||
558 | static void __exit fan53555_cleanup(void) | ||
559 | { | ||
560 | i2c_del_driver(&fan53555_i2c_driver); | ||
561 | } | ||
562 | module_exit(fan53555_cleanup); | ||
563 | |||
564 | MODULE_LICENSE("GPL"); | ||
565 | MODULE_AUTHOR("Jake Park<jakep@nvidia.com>"); | ||
566 | MODULE_DESCRIPTION("Regulator Driver for Fairchild FAN53555 Regulator"); | ||
567 | MODULE_ALIAS("platform:fan53555-regulator"); | ||
diff --git a/drivers/regulator/gpio-switch-regulator.c b/drivers/regulator/gpio-switch-regulator.c new file mode 100644 index 00000000000..55dd63675a0 --- /dev/null +++ b/drivers/regulator/gpio-switch-regulator.c | |||
@@ -0,0 +1,412 @@ | |||
1 | /* | ||
2 | * driver/regulator/gpio-switch-regulator.c | ||
3 | * GPIO based switch regulator to enable/disable power rails. | ||
4 | * | ||
5 | * Copyright (c) 2011, NVIDIA Corporation. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
15 | * more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License along | ||
18 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
19 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
20 | */ | ||
21 | |||
22 | /*#define DEBUG 1*/ | ||
23 | /*#define VERBOSE_DEBUG 1*/ | ||
24 | |||
25 | #include <linux/kernel.h> | ||
26 | #include <linux/init.h> | ||
27 | #include <linux/err.h> | ||
28 | #include <linux/slab.h> | ||
29 | #include <linux/platform_device.h> | ||
30 | #include <linux/regulator/driver.h> | ||
31 | #include <linux/regulator/machine.h> | ||
32 | #include <linux/gpio.h> | ||
33 | #include <linux/regulator/gpio-switch-regulator.h> | ||
34 | |||
35 | struct gpio_switch_regulator { | ||
36 | struct regulator_desc reg_desc; | ||
37 | struct regulator_init_data reg_init_data; | ||
38 | struct regulator *input_regulator; | ||
39 | struct regulator_dev *rdev; | ||
40 | struct device *dev; | ||
41 | int gpio_nr; | ||
42 | int pin_group; | ||
43 | bool is_gpio_init; | ||
44 | bool is_enable; | ||
45 | bool active_low; | ||
46 | bool is_init_success; | ||
47 | int *voltages; | ||
48 | unsigned curr_vol_sel; | ||
49 | struct gpio_switch_regulator_subdev_data *psubdev_data; | ||
50 | int (*enable_rail)(struct gpio_switch_regulator_subdev_data *sdata); | ||
51 | int (*disable_rail)(struct gpio_switch_regulator_subdev_data *sdata); | ||
52 | }; | ||
53 | |||
54 | static int _gpio_regulator_enable(struct device *dev, | ||
55 | struct gpio_switch_regulator *ri) | ||
56 | { | ||
57 | int init_val; | ||
58 | int ret; | ||
59 | |||
60 | if (ri->enable_rail) { | ||
61 | ret = ri->enable_rail(ri->psubdev_data); | ||
62 | if (ret < 0) | ||
63 | dev_err(dev, "Unable to enable rail through board api" | ||
64 | " error %d\n", ret); | ||
65 | } else { | ||
66 | init_val = (ri->active_low) ? 0 : 1; | ||
67 | ret = gpio_direction_output(ri->gpio_nr, init_val); | ||
68 | if (ret < 0) | ||
69 | dev_err(dev, "Unable to set direction %d\n", | ||
70 | ri->gpio_nr); | ||
71 | } | ||
72 | return ret; | ||
73 | } | ||
74 | |||
75 | static int _gpio_regulator_disable(struct device *dev, | ||
76 | struct gpio_switch_regulator *ri) | ||
77 | { | ||
78 | int init_val; | ||
79 | int ret; | ||
80 | |||
81 | if (ri->disable_rail) { | ||
82 | ret = ri->disable_rail(ri->psubdev_data); | ||
83 | if (ret < 0) | ||
84 | dev_err(dev, "Unable to disable rail through " | ||
85 | "board api %d\n", ret); | ||
86 | } else { | ||
87 | init_val = (ri->active_low) ? 1 : 0; | ||
88 | ret = gpio_direction_output(ri->gpio_nr, init_val); | ||
89 | if (ret < 0) | ||
90 | dev_err(dev, "Unable to set direction %d\n", | ||
91 | ri->gpio_nr); | ||
92 | } | ||
93 | return ret; | ||
94 | } | ||
95 | |||
96 | static int gpio_switch_list_voltage(struct regulator_dev *rdev, | ||
97 | unsigned selector) | ||
98 | { | ||
99 | struct gpio_switch_regulator *ri = rdev_get_drvdata(rdev); | ||
100 | |||
101 | if (selector < ri->reg_desc.n_voltages) | ||
102 | return ri->voltages[selector] * 1000; | ||
103 | else | ||
104 | return 0; | ||
105 | } | ||
106 | |||
107 | static int gpio_switch_set_voltage(struct regulator_dev *rdev, | ||
108 | int min_uV, int max_uV, unsigned *selector) | ||
109 | { | ||
110 | struct gpio_switch_regulator *ri = rdev_get_drvdata(rdev); | ||
111 | int uV; | ||
112 | bool found = false; | ||
113 | unsigned val; | ||
114 | |||
115 | for (val = 0; val < ri->reg_desc.n_voltages; val++) { | ||
116 | uV = ri->voltages[val] * 1000; | ||
117 | if (min_uV <= uV && uV <= max_uV) { | ||
118 | found = true; | ||
119 | *selector = ri->curr_vol_sel = val; | ||
120 | break; | ||
121 | } | ||
122 | } | ||
123 | if (found && ri->input_regulator) | ||
124 | return regulator_set_voltage(ri->input_regulator, min_uV, | ||
125 | max_uV); | ||
126 | ri->curr_vol_sel = 0; | ||
127 | return -EINVAL; | ||
128 | } | ||
129 | |||
130 | static int gpio_switch_get_voltage(struct regulator_dev *rdev) | ||
131 | { | ||
132 | struct gpio_switch_regulator *ri = rdev_get_drvdata(rdev); | ||
133 | if (ri->input_regulator) | ||
134 | return regulator_get_voltage(ri->input_regulator); | ||
135 | |||
136 | if (ri->curr_vol_sel < ri->reg_desc.n_voltages) | ||
137 | return ri->voltages[ri->curr_vol_sel] * 1000; | ||
138 | return 0; | ||
139 | } | ||
140 | |||
141 | static int gpio_switch_regulator_enable(struct regulator_dev *rdev) | ||
142 | { | ||
143 | struct gpio_switch_regulator *ri = rdev_get_drvdata(rdev); | ||
144 | int ret = 0; | ||
145 | if (ri->is_enable) | ||
146 | return 0; | ||
147 | |||
148 | if (ri->input_regulator) { | ||
149 | ret = regulator_enable(ri->input_regulator); | ||
150 | if (ret < 0) { | ||
151 | dev_err(&rdev->dev, "%s:Failed to enable regulator" | ||
152 | " Error %d\n", __func__, ret); | ||
153 | return ret; | ||
154 | } | ||
155 | } | ||
156 | |||
157 | ret = _gpio_regulator_enable(&rdev->dev, ri); | ||
158 | if (ret < 0) | ||
159 | return ret; | ||
160 | ri->is_enable = true; | ||
161 | return 0; | ||
162 | } | ||
163 | |||
164 | static int gpio_switch_regulator_disable(struct regulator_dev *rdev) | ||
165 | { | ||
166 | struct gpio_switch_regulator *ri = rdev_get_drvdata(rdev); | ||
167 | int ret = 0; | ||
168 | |||
169 | if (!ri->is_enable) | ||
170 | return 0; | ||
171 | |||
172 | ret = _gpio_regulator_disable(&rdev->dev, ri); | ||
173 | if (ret < 0) | ||
174 | return ret; | ||
175 | |||
176 | if (ri->input_regulator) { | ||
177 | ret = regulator_disable(ri->input_regulator); | ||
178 | if (ret < 0) { | ||
179 | dev_err(&rdev->dev, "%s:Failed to disable regulator" | ||
180 | " Error %d\n", __func__, ret); | ||
181 | return ret; | ||
182 | } | ||
183 | } | ||
184 | |||
185 | ri->is_enable = false; | ||
186 | return 0; | ||
187 | } | ||
188 | |||
189 | static int gpio_switch_regulator_is_enabled(struct regulator_dev *rdev) | ||
190 | { | ||
191 | struct gpio_switch_regulator *ri = rdev_get_drvdata(rdev); | ||
192 | int ret = 0; | ||
193 | if (ri->input_regulator) { | ||
194 | ret = regulator_is_enabled(ri->input_regulator); | ||
195 | if (!ret) | ||
196 | return ret; | ||
197 | } | ||
198 | return (ri->is_enable) ? 1 : 0; | ||
199 | } | ||
200 | |||
201 | static struct regulator_ops gpio_switch_regulator_ops = { | ||
202 | .list_voltage = gpio_switch_list_voltage, | ||
203 | .get_voltage = gpio_switch_get_voltage, | ||
204 | .set_voltage = gpio_switch_set_voltage, | ||
205 | .is_enabled = gpio_switch_regulator_is_enabled, | ||
206 | .enable = gpio_switch_regulator_enable, | ||
207 | .disable = gpio_switch_regulator_disable, | ||
208 | }; | ||
209 | |||
210 | static int __devinit gpio_switch_regulator_probe(struct platform_device *pdev) | ||
211 | { | ||
212 | struct gpio_switch_regulator *ri = NULL; | ||
213 | struct gpio_switch_regulator *gswitch_reg = NULL; | ||
214 | struct gpio_switch_regulator_platform_data *pdata; | ||
215 | struct gpio_switch_regulator_subdev_data *sdata = NULL; | ||
216 | int id = pdev->id; | ||
217 | int ret = 0; | ||
218 | int rcount; | ||
219 | |||
220 | dev_dbg(&pdev->dev, "Probing regulator %d\n", id); | ||
221 | |||
222 | pdata = pdev->dev.platform_data; | ||
223 | if (!pdata) { | ||
224 | dev_err(&pdev->dev, "%s:No platform data Exiting\n", __func__); | ||
225 | return -ENODEV; | ||
226 | } | ||
227 | |||
228 | BUG_ON(!pdata->num_subdevs); | ||
229 | |||
230 | gswitch_reg = kzalloc(sizeof(struct gpio_switch_regulator) * | ||
231 | pdata->num_subdevs, GFP_KERNEL); | ||
232 | if (!gswitch_reg) { | ||
233 | dev_err(&pdev->dev, "%s:Failed to allocate memory\n", __func__); | ||
234 | return -ENOMEM; | ||
235 | } | ||
236 | |||
237 | for (rcount = 0; rcount < pdata->num_subdevs; ++rcount) { | ||
238 | ri = &gswitch_reg[rcount]; | ||
239 | sdata = pdata->subdevs[rcount]; | ||
240 | |||
241 | /* Initialize the regulator parameter */ | ||
242 | ri->reg_desc.name = sdata->regulator_name; | ||
243 | ri->reg_desc.ops = &gpio_switch_regulator_ops; | ||
244 | ri->reg_desc.type = REGULATOR_VOLTAGE; | ||
245 | ri->reg_desc.id = sdata->id; | ||
246 | ri->reg_desc.n_voltages = sdata->n_voltages; | ||
247 | ri->reg_desc.owner = THIS_MODULE; | ||
248 | ri->is_init_success = false; | ||
249 | |||
250 | memcpy(&ri->reg_init_data.constraints, &sdata->constraints, | ||
251 | sizeof(struct regulation_constraints)); | ||
252 | |||
253 | /* Initialize min and maximum contraint voltage if it is not | ||
254 | * define in platform device */ | ||
255 | if (!sdata->constraints.min_uV) | ||
256 | ri->reg_init_data.constraints.min_uV = 1000 * | ||
257 | sdata->voltages[0]; | ||
258 | |||
259 | if (!sdata->constraints.max_uV) | ||
260 | ri->reg_init_data.constraints.max_uV = 1000 * | ||
261 | sdata->voltages[sdata->n_voltages - 1]; | ||
262 | |||
263 | ri->reg_init_data.num_consumer_supplies = | ||
264 | sdata->num_consumer_supplies; | ||
265 | ri->reg_init_data.consumer_supplies = sdata->consumer_supplies; | ||
266 | |||
267 | ri->input_regulator = NULL; | ||
268 | ri->is_gpio_init = false; | ||
269 | ri->is_enable = (sdata->init_state) ? true : false; | ||
270 | ri->voltages = sdata->voltages; | ||
271 | ri->psubdev_data = sdata; | ||
272 | ri->gpio_nr = sdata->gpio_nr; | ||
273 | ri->active_low = sdata->active_low; | ||
274 | ri->dev = &pdev->dev; | ||
275 | ri->enable_rail = sdata->enable_rail; | ||
276 | ri->disable_rail = sdata->disable_rail; | ||
277 | ri->pin_group = sdata->pin_group; | ||
278 | |||
279 | /* Checking for board APIs enable/disable rail */ | ||
280 | if (ri->enable_rail || ri->disable_rail) | ||
281 | BUG_ON(!(ri->enable_rail && ri->disable_rail)); | ||
282 | |||
283 | /* Get the regulator structure if input supply is available */ | ||
284 | if (sdata->input_supply) { | ||
285 | ri->input_regulator = regulator_get(NULL, | ||
286 | sdata->input_supply); | ||
287 | if (IS_ERR_OR_NULL(ri->input_regulator)) { | ||
288 | dev_err(&pdev->dev, "Unable to get regu" | ||
289 | "lator %s\n", sdata->input_supply); | ||
290 | ret = -ENODEV; | ||
291 | goto reg_get_fail; | ||
292 | } | ||
293 | if (ri->is_enable) { | ||
294 | ret = regulator_enable(ri->input_regulator); | ||
295 | if (ret < 0) { | ||
296 | dev_err(&pdev->dev, "Unable to enable " | ||
297 | "regulator %s\n", | ||
298 | sdata->input_supply); | ||
299 | goto reg_en_fail; | ||
300 | } | ||
301 | } | ||
302 | } | ||
303 | |||
304 | /* Initialize gpios */ | ||
305 | ret = gpio_request(ri->gpio_nr, sdata->regulator_name); | ||
306 | if (ret < 0) { | ||
307 | dev_err(&pdev->dev, "Unable to request gpio %d\n", | ||
308 | ri->gpio_nr); | ||
309 | goto gpio_req_fail; | ||
310 | } | ||
311 | |||
312 | if (ri->is_enable) | ||
313 | ret = _gpio_regulator_enable(&pdev->dev, ri); | ||
314 | else | ||
315 | ret = _gpio_regulator_disable(&pdev->dev, ri); | ||
316 | if (ret < 0) | ||
317 | goto reg_cont_fail; | ||
318 | |||
319 | ri->is_gpio_init = true; | ||
320 | |||
321 | ri->rdev = regulator_register(&ri->reg_desc, &pdev->dev, | ||
322 | &ri->reg_init_data, ri); | ||
323 | if (IS_ERR_OR_NULL(ri->rdev)) { | ||
324 | dev_err(&pdev->dev, "Failed to register regulator %s\n", | ||
325 | ri->reg_desc.name); | ||
326 | ret = PTR_ERR(ri->rdev); | ||
327 | goto reg_reg_fail; | ||
328 | } | ||
329 | |||
330 | /* If everything success then continue for next registration */ | ||
331 | ri->is_init_success = true; | ||
332 | continue; | ||
333 | |||
334 | /* Cleanup the current registration and continue for next | ||
335 | * registration*/ | ||
336 | reg_reg_fail: | ||
337 | if (ri->is_enable) | ||
338 | _gpio_regulator_disable(&pdev->dev, ri); | ||
339 | reg_cont_fail: | ||
340 | gpio_free(ri->gpio_nr); | ||
341 | gpio_req_fail: | ||
342 | if (ri->is_enable && ri->input_regulator) | ||
343 | regulator_disable(ri->input_regulator); | ||
344 | reg_en_fail: | ||
345 | if (ri->input_regulator) { | ||
346 | regulator_put(ri->input_regulator); | ||
347 | ri->input_regulator = NULL; | ||
348 | } | ||
349 | reg_get_fail: | ||
350 | dev_err(&pdev->dev, "Unable to register regulator %s\n", | ||
351 | sdata->regulator_name); | ||
352 | } | ||
353 | |||
354 | platform_set_drvdata(pdev, gswitch_reg); | ||
355 | return 0; | ||
356 | } | ||
357 | |||
358 | static int __devexit gpio_switch_regulator_remove(struct platform_device *pdev) | ||
359 | { | ||
360 | struct gpio_switch_regulator *ri = NULL; | ||
361 | struct gpio_switch_regulator *gswitch_reg = platform_get_drvdata(pdev); | ||
362 | int i; | ||
363 | struct gpio_switch_regulator_platform_data *pdata; | ||
364 | |||
365 | pdata = pdev->dev.platform_data; | ||
366 | |||
367 | /* Unregister devices in reverse order */ | ||
368 | for (i = pdata->num_subdevs; i; --i) { | ||
369 | ri = &gswitch_reg[i - 1]; | ||
370 | /* If registration was not success, then do not release */ | ||
371 | if (!ri->is_init_success) | ||
372 | continue; | ||
373 | |||
374 | if (ri->is_enable) | ||
375 | _gpio_regulator_disable(&pdev->dev, ri); | ||
376 | |||
377 | if (ri->input_regulator) { | ||
378 | if (ri->is_enable) | ||
379 | regulator_disable(ri->input_regulator); | ||
380 | regulator_put(ri->input_regulator); | ||
381 | } | ||
382 | |||
383 | regulator_unregister(ri->rdev); | ||
384 | gpio_free(ri->gpio_nr); | ||
385 | } | ||
386 | |||
387 | kfree(gswitch_reg); | ||
388 | platform_set_drvdata(pdev, NULL); | ||
389 | return 0; | ||
390 | } | ||
391 | |||
392 | static struct platform_driver gpio_switch_regulator_driver = { | ||
393 | .driver = { | ||
394 | .name = "gpio-switch-regulator", | ||
395 | .owner = THIS_MODULE, | ||
396 | }, | ||
397 | .probe = gpio_switch_regulator_probe, | ||
398 | .remove = __devexit_p(gpio_switch_regulator_remove), | ||
399 | }; | ||
400 | |||
401 | static int __init gpio_switch_regulator_init(void) | ||
402 | { | ||
403 | return platform_driver_register(&gpio_switch_regulator_driver); | ||
404 | } | ||
405 | |||
406 | static void __exit gpio_switch_regulator_exit(void) | ||
407 | { | ||
408 | platform_driver_unregister(&gpio_switch_regulator_driver); | ||
409 | } | ||
410 | |||
411 | subsys_initcall_sync(gpio_switch_regulator_init); | ||
412 | module_exit(gpio_switch_regulator_exit); | ||
diff --git a/drivers/regulator/max77663-regulator.c b/drivers/regulator/max77663-regulator.c new file mode 100644 index 00000000000..dca8ece4c43 --- /dev/null +++ b/drivers/regulator/max77663-regulator.c | |||
@@ -0,0 +1,928 @@ | |||
1 | /* | ||
2 | * drivers/regulator/max77663-regulator.c | ||
3 | * Maxim LDO and Buck regulators driver | ||
4 | * | ||
5 | * Copyright 2011-2012 Maxim Integrated Products, Inc. | ||
6 | * Copyright (C) 2011-2012 NVIDIA Corporation | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License as | ||
10 | * published by the Free Software Foundation; either version 2 of the | ||
11 | * License, or (at your option) any later version. | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | #include <linux/err.h> | ||
16 | #include <linux/string.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/slab.h> | ||
21 | #include <linux/debugfs.h> | ||
22 | #include <linux/uaccess.h> | ||
23 | #include <linux/i2c.h> | ||
24 | #include <linux/mfd/core.h> | ||
25 | #include <linux/mfd/max77663-core.h> | ||
26 | #include <linux/regulator/driver.h> | ||
27 | #include <linux/regulator/machine.h> | ||
28 | #include <linux/regulator/max77663-regulator.h> | ||
29 | |||
30 | /* Regulator types */ | ||
31 | #define REGULATOR_TYPE_SD 0 | ||
32 | #define REGULATOR_TYPE_LDO_N 1 | ||
33 | #define REGULATOR_TYPE_LDO_P 2 | ||
34 | |||
35 | /* SD and LDO Registers */ | ||
36 | #define MAX77663_REG_SD0 0x16 | ||
37 | #define MAX77663_REG_SD1 0x17 | ||
38 | #define MAX77663_REG_SD2 0x18 | ||
39 | #define MAX77663_REG_SD3 0x19 | ||
40 | #define MAX77663_REG_SD4 0x1A | ||
41 | #define MAX77663_REG_DVSSD0 0x1B | ||
42 | #define MAX77663_REG_DVSSD1 0x1C | ||
43 | #define MAX77663_REG_SD0_CFG 0x1D | ||
44 | #define MAX77663_REG_DVSSD0_CFG MAX77663_REG_SD0_CFG | ||
45 | #define MAX77663_REG_SD1_CFG 0x1E | ||
46 | #define MAX77663_REG_DVSSD1_CFG MAX77663_REG_SD1_CFG | ||
47 | #define MAX77663_REG_SD2_CFG 0x1F | ||
48 | #define MAX77663_REG_SD3_CFG 0x20 | ||
49 | #define MAX77663_REG_SD4_CFG 0x21 | ||
50 | #define MAX77663_REG_LDO0_CFG 0x23 | ||
51 | #define MAX77663_REG_LDO0_CFG2 0x24 | ||
52 | #define MAX77663_REG_LDO1_CFG 0x25 | ||
53 | #define MAX77663_REG_LDO1_CFG2 0x26 | ||
54 | #define MAX77663_REG_LDO2_CFG 0x27 | ||
55 | #define MAX77663_REG_LDO2_CFG2 0x28 | ||
56 | #define MAX77663_REG_LDO3_CFG 0x29 | ||
57 | #define MAX77663_REG_LDO3_CFG2 0x2A | ||
58 | #define MAX77663_REG_LDO4_CFG 0x2B | ||
59 | #define MAX77663_REG_LDO4_CFG2 0x2C | ||
60 | #define MAX77663_REG_LDO5_CFG 0x2D | ||
61 | #define MAX77663_REG_LDO5_CFG2 0x2E | ||
62 | #define MAX77663_REG_LDO6_CFG 0x2F | ||
63 | #define MAX77663_REG_LDO6_CFG2 0x30 | ||
64 | #define MAX77663_REG_LDO7_CFG 0x31 | ||
65 | #define MAX77663_REG_LDO7_CFG2 0x32 | ||
66 | #define MAX77663_REG_LDO8_CFG 0x33 | ||
67 | #define MAX77663_REG_LDO8_CFG2 0x34 | ||
68 | #define MAX77663_REG_LDO_CFG3 0x35 | ||
69 | |||
70 | /* Power Mode */ | ||
71 | #define POWER_MODE_NORMAL 3 | ||
72 | #define POWER_MODE_LPM 2 | ||
73 | #define POWER_MODE_GLPM 1 | ||
74 | #define POWER_MODE_DISABLE 0 | ||
75 | #define SD_POWER_MODE_MASK 0x30 | ||
76 | #define SD_POWER_MODE_SHIFT 4 | ||
77 | #define LDO_POWER_MODE_MASK 0xC0 | ||
78 | #define LDO_POWER_MODE_SHIFT 6 | ||
79 | |||
80 | /* SD Slew Rate */ | ||
81 | #define SD_SR_13_75 0 | ||
82 | #define SD_SR_27_5 1 | ||
83 | #define SD_SR_55 2 | ||
84 | #define SD_SR_100 3 | ||
85 | #define SD_SR_MASK 0xC0 | ||
86 | #define SD_SR_SHIFT 6 | ||
87 | |||
88 | /* SD Forced PWM Mode */ | ||
89 | #define SD_FPWM_MASK 0x04 | ||
90 | #define SD_FPWM_SHIFT 2 | ||
91 | |||
92 | /* SD Failling slew rate Active-Discharge Mode */ | ||
93 | #define SD_FSRADE_MASK 0x01 | ||
94 | #define SD_FSRADE_SHIFT 0 | ||
95 | |||
96 | /* LDO Configuration 3 */ | ||
97 | #define TRACK4_MASK 0x20 | ||
98 | #define TRACK4_SHIFT 5 | ||
99 | |||
100 | /* Voltage */ | ||
101 | #define SDX_VOLT_MASK 0xFF | ||
102 | #define SD1_VOLT_MASK 0x3F | ||
103 | #define LDO_VOLT_MASK 0x3F | ||
104 | |||
105 | /* FPS Registers */ | ||
106 | #define MAX77663_REG_FPS_CFG0 0x43 | ||
107 | #define MAX77663_REG_FPS_CFG1 0x44 | ||
108 | #define MAX77663_REG_FPS_CFG2 0x45 | ||
109 | #define MAX77663_REG_FPS_LDO0 0x46 | ||
110 | #define MAX77663_REG_FPS_LDO1 0x47 | ||
111 | #define MAX77663_REG_FPS_LDO2 0x48 | ||
112 | #define MAX77663_REG_FPS_LDO3 0x49 | ||
113 | #define MAX77663_REG_FPS_LDO4 0x4A | ||
114 | #define MAX77663_REG_FPS_LDO5 0x4B | ||
115 | #define MAX77663_REG_FPS_LDO6 0x4C | ||
116 | #define MAX77663_REG_FPS_LDO7 0x4D | ||
117 | #define MAX77663_REG_FPS_LDO8 0x4E | ||
118 | #define MAX77663_REG_FPS_SD0 0x4F | ||
119 | #define MAX77663_REG_FPS_SD1 0x50 | ||
120 | #define MAX77663_REG_FPS_SD2 0x51 | ||
121 | #define MAX77663_REG_FPS_SD3 0x52 | ||
122 | #define MAX77663_REG_FPS_SD4 0x53 | ||
123 | #define MAX77663_REG_FPS_NONE 0 | ||
124 | |||
125 | #define FPS_TIME_PERIOD_MASK 0x38 | ||
126 | #define FPS_TIME_PERIOD_SHIFT 3 | ||
127 | #define FPS_EN_SRC_MASK 0x06 | ||
128 | #define FPS_EN_SRC_SHIFT 1 | ||
129 | #define FPS_SW_EN_MASK 0x01 | ||
130 | #define FPS_SW_EN_SHIFT 0 | ||
131 | #define FPS_SRC_MASK 0xC0 | ||
132 | #define FPS_SRC_SHIFT 6 | ||
133 | #define FPS_PU_PERIOD_MASK 0x38 | ||
134 | #define FPS_PU_PERIOD_SHIFT 3 | ||
135 | #define FPS_PD_PERIOD_MASK 0x07 | ||
136 | #define FPS_PD_PERIOD_SHIFT 0 | ||
137 | |||
138 | /* Chip Identification Register */ | ||
139 | #define MAX77663_REG_CID5 0x5D | ||
140 | |||
141 | #define CID_DIDM_MASK 0xF0 | ||
142 | #define CID_DIDM_SHIFT 4 | ||
143 | |||
144 | #define SD_SAFE_DOWN_UV 50000 /* 50mV */ | ||
145 | |||
146 | enum { | ||
147 | VOLT_REG = 0, | ||
148 | CFG_REG, | ||
149 | FPS_REG, | ||
150 | }; | ||
151 | |||
152 | struct max77663_register { | ||
153 | u8 addr; | ||
154 | u8 val; | ||
155 | }; | ||
156 | |||
157 | struct max77663_regulator { | ||
158 | struct regulator_dev *rdev; | ||
159 | struct device *dev; | ||
160 | struct max77663_regulator_platform_data *pdata; | ||
161 | |||
162 | u8 id; | ||
163 | u8 type; | ||
164 | u32 min_uV; | ||
165 | u32 max_uV; | ||
166 | u32 step_uV; | ||
167 | int safe_down_uV; /* for stable down scaling */ | ||
168 | u32 regulator_mode; | ||
169 | |||
170 | struct max77663_register regs[3]; /* volt, cfg, fps */ | ||
171 | enum max77663_regulator_fps_src fps_src; | ||
172 | |||
173 | u8 volt_mask; | ||
174 | |||
175 | u8 power_mode; | ||
176 | u8 power_mode_mask; | ||
177 | u8 power_mode_shift; | ||
178 | }; | ||
179 | |||
180 | #define fps_src_name(fps_src) \ | ||
181 | (fps_src == FPS_SRC_0 ? "FPS_SRC_0" : \ | ||
182 | fps_src == FPS_SRC_1 ? "FPS_SRC_1" : \ | ||
183 | fps_src == FPS_SRC_2 ? "FPS_SRC_2" : "FPS_SRC_NONE") | ||
184 | |||
185 | static int fps_cfg_init; | ||
186 | static struct max77663_register fps_cfg_regs[] = { | ||
187 | { | ||
188 | .addr = MAX77663_REG_FPS_CFG0, | ||
189 | }, | ||
190 | { | ||
191 | .addr = MAX77663_REG_FPS_CFG1, | ||
192 | }, | ||
193 | { | ||
194 | .addr = MAX77663_REG_FPS_CFG2, | ||
195 | }, | ||
196 | }; | ||
197 | |||
198 | static inline struct max77663_regulator_platform_data | ||
199 | *_to_pdata(struct max77663_regulator *reg) | ||
200 | { | ||
201 | return reg->pdata; | ||
202 | } | ||
203 | |||
204 | static inline struct device *_to_parent(struct max77663_regulator *reg) | ||
205 | { | ||
206 | return reg->dev->parent; | ||
207 | } | ||
208 | |||
209 | static inline int max77663_regulator_cache_write(struct max77663_regulator *reg, | ||
210 | u8 addr, u8 mask, u8 val, u8 *cache) | ||
211 | { | ||
212 | struct device *parent = _to_parent(reg); | ||
213 | u8 new_val; | ||
214 | int ret; | ||
215 | |||
216 | new_val = (*cache & ~mask) | (val & mask); | ||
217 | if (*cache != new_val) { | ||
218 | ret = max77663_write(parent, addr, &new_val, 1, 0); | ||
219 | if (ret < 0) | ||
220 | return ret; | ||
221 | |||
222 | *cache = new_val; | ||
223 | } | ||
224 | return 0; | ||
225 | } | ||
226 | |||
227 | static int | ||
228 | max77663_regulator_set_fps_src(struct max77663_regulator *reg, | ||
229 | enum max77663_regulator_fps_src fps_src) | ||
230 | { | ||
231 | int ret; | ||
232 | |||
233 | if ((reg->regs[FPS_REG].addr == MAX77663_REG_FPS_NONE) || | ||
234 | (reg->fps_src == fps_src)) | ||
235 | return 0; | ||
236 | |||
237 | switch (fps_src) { | ||
238 | case FPS_SRC_0: | ||
239 | case FPS_SRC_1: | ||
240 | case FPS_SRC_2: | ||
241 | case FPS_SRC_NONE: | ||
242 | break; | ||
243 | case FPS_SRC_DEF: | ||
244 | return 0; | ||
245 | default: | ||
246 | return -EINVAL; | ||
247 | } | ||
248 | |||
249 | ret = max77663_regulator_cache_write(reg, reg->regs[FPS_REG].addr, | ||
250 | FPS_SRC_MASK, fps_src << FPS_SRC_SHIFT, | ||
251 | ®->regs[FPS_REG].val); | ||
252 | if (ret < 0) | ||
253 | return ret; | ||
254 | |||
255 | reg->fps_src = fps_src; | ||
256 | return 0; | ||
257 | } | ||
258 | |||
259 | static int max77663_regulator_set_fps(struct max77663_regulator *reg) | ||
260 | { | ||
261 | struct max77663_regulator_platform_data *pdata = _to_pdata(reg); | ||
262 | u8 fps_val = 0, fps_mask = 0; | ||
263 | int ret = 0; | ||
264 | |||
265 | if (reg->regs[FPS_REG].addr == MAX77663_REG_FPS_NONE) | ||
266 | return 0; | ||
267 | |||
268 | if (reg->fps_src == FPS_SRC_NONE) | ||
269 | return 0; | ||
270 | |||
271 | /* FPS power up period setting */ | ||
272 | if (pdata->fps_pu_period != FPS_POWER_PERIOD_DEF) { | ||
273 | fps_val |= (pdata->fps_pu_period << FPS_PU_PERIOD_SHIFT); | ||
274 | fps_mask |= FPS_PU_PERIOD_MASK; | ||
275 | } | ||
276 | |||
277 | /* FPS power down period setting */ | ||
278 | if (pdata->fps_pd_period != FPS_POWER_PERIOD_DEF) { | ||
279 | fps_val |= (pdata->fps_pd_period << FPS_PD_PERIOD_SHIFT); | ||
280 | fps_mask |= FPS_PD_PERIOD_MASK; | ||
281 | } | ||
282 | |||
283 | if (fps_val) | ||
284 | ret = max77663_regulator_cache_write(reg, | ||
285 | reg->regs[FPS_REG].addr, fps_mask, | ||
286 | fps_val, ®->regs[FPS_REG].val); | ||
287 | |||
288 | return ret; | ||
289 | } | ||
290 | |||
291 | static int | ||
292 | max77663_regulator_set_fps_cfg(struct max77663_regulator *reg, | ||
293 | struct max77663_regulator_fps_cfg *fps_cfg) | ||
294 | { | ||
295 | u8 val, mask; | ||
296 | |||
297 | if ((fps_cfg->src < FPS_SRC_0) || (fps_cfg->src > FPS_SRC_2)) | ||
298 | return -EINVAL; | ||
299 | |||
300 | val = (fps_cfg->en_src << FPS_EN_SRC_SHIFT); | ||
301 | mask = FPS_EN_SRC_MASK; | ||
302 | |||
303 | if (fps_cfg->time_period != FPS_TIME_PERIOD_DEF) { | ||
304 | val |= (fps_cfg->time_period << FPS_TIME_PERIOD_SHIFT); | ||
305 | mask |= FPS_TIME_PERIOD_MASK; | ||
306 | } | ||
307 | |||
308 | return max77663_regulator_cache_write(reg, | ||
309 | fps_cfg_regs[fps_cfg->src].addr, mask, | ||
310 | val, &fps_cfg_regs[fps_cfg->src].val); | ||
311 | } | ||
312 | |||
313 | static int | ||
314 | max77663_regulator_set_fps_cfgs(struct max77663_regulator *reg, | ||
315 | struct max77663_regulator_fps_cfg *fps_cfgs, | ||
316 | int num_fps_cfgs) | ||
317 | { | ||
318 | struct device *parent = _to_parent(reg); | ||
319 | int i, ret; | ||
320 | |||
321 | if (fps_cfg_init) | ||
322 | return 0; | ||
323 | |||
324 | for (i = 0; i <= FPS_SRC_2; i++) { | ||
325 | ret = max77663_read(parent, fps_cfg_regs[i].addr, | ||
326 | &fps_cfg_regs[i].val, 1, 0); | ||
327 | if (ret < 0) | ||
328 | return ret; | ||
329 | } | ||
330 | |||
331 | for (i = 0; i < num_fps_cfgs; i++) { | ||
332 | ret = max77663_regulator_set_fps_cfg(reg, &fps_cfgs[i]); | ||
333 | if (ret < 0) | ||
334 | return ret; | ||
335 | } | ||
336 | fps_cfg_init = 1; | ||
337 | |||
338 | return 0; | ||
339 | } | ||
340 | |||
341 | static int | ||
342 | max77663_regulator_set_power_mode(struct max77663_regulator *reg, u8 power_mode) | ||
343 | { | ||
344 | u8 mask = reg->power_mode_mask; | ||
345 | u8 shift = reg->power_mode_shift; | ||
346 | int ret; | ||
347 | |||
348 | if (reg->type == REGULATOR_TYPE_SD) | ||
349 | ret = max77663_regulator_cache_write(reg, | ||
350 | reg->regs[CFG_REG].addr, | ||
351 | mask, power_mode << shift, | ||
352 | ®->regs[CFG_REG].val); | ||
353 | else | ||
354 | ret = max77663_regulator_cache_write(reg, | ||
355 | reg->regs[VOLT_REG].addr, | ||
356 | mask, power_mode << shift, | ||
357 | ®->regs[VOLT_REG].val); | ||
358 | |||
359 | if (ret < 0) | ||
360 | return ret; | ||
361 | |||
362 | reg->power_mode = power_mode; | ||
363 | return ret; | ||
364 | } | ||
365 | |||
366 | static u8 max77663_regulator_get_power_mode(struct max77663_regulator *reg) | ||
367 | { | ||
368 | u8 mask = reg->power_mode_mask; | ||
369 | u8 shift = reg->power_mode_shift; | ||
370 | |||
371 | if (reg->type == REGULATOR_TYPE_SD) | ||
372 | reg->power_mode = (reg->regs[CFG_REG].val & mask) >> shift; | ||
373 | else | ||
374 | reg->power_mode = (reg->regs[VOLT_REG].val & mask) >> shift; | ||
375 | |||
376 | return reg->power_mode; | ||
377 | } | ||
378 | |||
379 | static int max77663_regulator_do_set_voltage(struct max77663_regulator *reg, | ||
380 | int min_uV, int max_uV) | ||
381 | { | ||
382 | u8 addr = reg->regs[VOLT_REG].addr; | ||
383 | u8 mask = reg->volt_mask; | ||
384 | u8 *cache = ®->regs[VOLT_REG].val; | ||
385 | u8 val; | ||
386 | int old_uV, new_uV, safe_uV; | ||
387 | int i, steps = 1; | ||
388 | int ret = 0; | ||
389 | |||
390 | if (min_uV < reg->min_uV || max_uV > reg->max_uV) | ||
391 | return -EDOM; | ||
392 | |||
393 | old_uV = (*cache & mask) * reg->step_uV + reg->min_uV; | ||
394 | |||
395 | if ((old_uV > min_uV) && (reg->safe_down_uV >= reg->step_uV)) { | ||
396 | steps = DIV_ROUND_UP(old_uV - min_uV, reg->safe_down_uV); | ||
397 | safe_uV = -reg->safe_down_uV; | ||
398 | } | ||
399 | |||
400 | if (steps == 1) { | ||
401 | val = (min_uV - reg->min_uV) / reg->step_uV; | ||
402 | ret = max77663_regulator_cache_write(reg, addr, mask, val, | ||
403 | cache); | ||
404 | } else { | ||
405 | for (i = 0; i < steps; i++) { | ||
406 | if (abs(min_uV - old_uV) > abs(safe_uV)) | ||
407 | new_uV = old_uV + safe_uV; | ||
408 | else | ||
409 | new_uV = min_uV; | ||
410 | |||
411 | dev_dbg(®->rdev->dev, "do_set_voltage: name=%s, " | ||
412 | "%d/%d, old_uV=%d, new_uV=%d\n", | ||
413 | reg->rdev->desc->name, i + 1, steps, old_uV, | ||
414 | new_uV); | ||
415 | |||
416 | val = (new_uV - reg->min_uV) / reg->step_uV; | ||
417 | ret = max77663_regulator_cache_write(reg, addr, mask, | ||
418 | val, cache); | ||
419 | if (ret < 0) | ||
420 | return ret; | ||
421 | |||
422 | old_uV = new_uV; | ||
423 | } | ||
424 | } | ||
425 | |||
426 | return ret; | ||
427 | } | ||
428 | |||
429 | static int max77663_regulator_set_voltage(struct regulator_dev *rdev, | ||
430 | int min_uV, int max_uV, | ||
431 | unsigned *selector) | ||
432 | { | ||
433 | struct max77663_regulator *reg = rdev_get_drvdata(rdev); | ||
434 | |||
435 | dev_dbg(&rdev->dev, "set_voltage: name=%s, min_uV=%d, max_uV=%d\n", | ||
436 | rdev->desc->name, min_uV, max_uV); | ||
437 | return max77663_regulator_do_set_voltage(reg, min_uV, max_uV); | ||
438 | } | ||
439 | |||
440 | static int max77663_regulator_get_voltage(struct regulator_dev *rdev) | ||
441 | { | ||
442 | struct max77663_regulator *reg = rdev_get_drvdata(rdev); | ||
443 | int volt; | ||
444 | |||
445 | volt = (reg->regs[VOLT_REG].val & reg->volt_mask) | ||
446 | * reg->step_uV + reg->min_uV; | ||
447 | |||
448 | dev_dbg(&rdev->dev, "get_voltage: name=%s, volt=%d, val=0x%02x\n", | ||
449 | rdev->desc->name, volt, reg->regs[VOLT_REG].val); | ||
450 | return volt; | ||
451 | } | ||
452 | |||
453 | static int max77663_regulator_enable(struct regulator_dev *rdev) | ||
454 | { | ||
455 | struct max77663_regulator *reg = rdev_get_drvdata(rdev); | ||
456 | struct max77663_regulator_platform_data *pdata = _to_pdata(reg); | ||
457 | int power_mode = (pdata->flags & GLPM_ENABLE) ? | ||
458 | POWER_MODE_GLPM : POWER_MODE_NORMAL; | ||
459 | |||
460 | if (reg->fps_src != FPS_SRC_NONE) { | ||
461 | dev_dbg(&rdev->dev, "enable: Regulator %s using %s\n", | ||
462 | rdev->desc->name, fps_src_name(reg->fps_src)); | ||
463 | return 0; | ||
464 | } | ||
465 | |||
466 | if ((reg->id == MAX77663_REGULATOR_ID_SD0) | ||
467 | && (pdata->flags & EN2_CTRL_SD0)) { | ||
468 | dev_dbg(&rdev->dev, | ||
469 | "enable: Regulator %s is controlled by EN2\n", | ||
470 | rdev->desc->name); | ||
471 | return 0; | ||
472 | } | ||
473 | |||
474 | /* N-Channel LDOs don't support Low-Power mode. */ | ||
475 | if ((reg->type != REGULATOR_TYPE_LDO_N) && | ||
476 | (reg->regulator_mode == REGULATOR_MODE_STANDBY)) | ||
477 | power_mode = POWER_MODE_LPM; | ||
478 | |||
479 | return max77663_regulator_set_power_mode(reg, power_mode); | ||
480 | } | ||
481 | |||
482 | static int max77663_regulator_disable(struct regulator_dev *rdev) | ||
483 | { | ||
484 | struct max77663_regulator *reg = rdev_get_drvdata(rdev); | ||
485 | struct max77663_regulator_platform_data *pdata = _to_pdata(reg); | ||
486 | int power_mode = POWER_MODE_DISABLE; | ||
487 | |||
488 | if (reg->fps_src != FPS_SRC_NONE) { | ||
489 | dev_dbg(&rdev->dev, "disable: Regulator %s using %s\n", | ||
490 | rdev->desc->name, fps_src_name(reg->fps_src)); | ||
491 | return 0; | ||
492 | } | ||
493 | |||
494 | if ((reg->id == MAX77663_REGULATOR_ID_SD0) | ||
495 | && (pdata->flags & EN2_CTRL_SD0)) { | ||
496 | dev_dbg(&rdev->dev, | ||
497 | "disable: Regulator %s is controlled by EN2\n", | ||
498 | rdev->desc->name); | ||
499 | return 0; | ||
500 | } | ||
501 | |||
502 | return max77663_regulator_set_power_mode(reg, power_mode); | ||
503 | } | ||
504 | |||
505 | static int max77663_regulator_is_enabled(struct regulator_dev *rdev) | ||
506 | { | ||
507 | struct max77663_regulator *reg = rdev_get_drvdata(rdev); | ||
508 | struct max77663_regulator_platform_data *pdata = _to_pdata(reg); | ||
509 | int ret = 1; | ||
510 | |||
511 | if (reg->fps_src != FPS_SRC_NONE) { | ||
512 | dev_dbg(&rdev->dev, "is_enable: Regulator %s using %s\n", | ||
513 | rdev->desc->name, fps_src_name(reg->fps_src)); | ||
514 | return 1; | ||
515 | } | ||
516 | |||
517 | if ((reg->id == MAX77663_REGULATOR_ID_SD0) | ||
518 | && (pdata->flags & EN2_CTRL_SD0)) { | ||
519 | dev_dbg(&rdev->dev, | ||
520 | "is_enable: Regulator %s is controlled by EN2\n", | ||
521 | rdev->desc->name); | ||
522 | return 1; | ||
523 | } | ||
524 | |||
525 | if (max77663_regulator_get_power_mode(reg) == POWER_MODE_DISABLE) | ||
526 | ret = 0; | ||
527 | |||
528 | return ret; | ||
529 | } | ||
530 | |||
531 | static int max77663_regulator_set_mode(struct regulator_dev *rdev, | ||
532 | unsigned int mode) | ||
533 | { | ||
534 | struct max77663_regulator *reg = rdev_get_drvdata(rdev); | ||
535 | struct max77663_regulator_platform_data *pdata = _to_pdata(reg); | ||
536 | u8 power_mode; | ||
537 | int ret; | ||
538 | |||
539 | if (mode == REGULATOR_MODE_NORMAL) | ||
540 | power_mode = (pdata->flags & GLPM_ENABLE) ? | ||
541 | POWER_MODE_GLPM : POWER_MODE_NORMAL; | ||
542 | else if (mode == REGULATOR_MODE_STANDBY) { | ||
543 | /* N-Channel LDOs don't support Low-Power mode. */ | ||
544 | power_mode = (reg->type != REGULATOR_TYPE_LDO_N) ? | ||
545 | POWER_MODE_LPM : POWER_MODE_NORMAL; | ||
546 | } else | ||
547 | return -EINVAL; | ||
548 | |||
549 | ret = max77663_regulator_set_power_mode(reg, power_mode); | ||
550 | if (!ret) | ||
551 | reg->regulator_mode = mode; | ||
552 | |||
553 | return ret; | ||
554 | } | ||
555 | |||
556 | static unsigned int max77663_regulator_get_mode(struct regulator_dev *rdev) | ||
557 | { | ||
558 | struct max77663_regulator *reg = rdev_get_drvdata(rdev); | ||
559 | |||
560 | return reg->regulator_mode; | ||
561 | } | ||
562 | |||
563 | static struct regulator_ops max77663_ldo_ops = { | ||
564 | .set_voltage = max77663_regulator_set_voltage, | ||
565 | .get_voltage = max77663_regulator_get_voltage, | ||
566 | .enable = max77663_regulator_enable, | ||
567 | .disable = max77663_regulator_disable, | ||
568 | .is_enabled = max77663_regulator_is_enabled, | ||
569 | .set_mode = max77663_regulator_set_mode, | ||
570 | .get_mode = max77663_regulator_get_mode, | ||
571 | }; | ||
572 | |||
573 | static int max77663_regulator_preinit(struct max77663_regulator *reg) | ||
574 | { | ||
575 | struct max77663_regulator_platform_data *pdata = _to_pdata(reg); | ||
576 | struct device *parent = _to_parent(reg); | ||
577 | int i; | ||
578 | u8 val, mask; | ||
579 | int ret; | ||
580 | |||
581 | /* Update registers */ | ||
582 | for (i = 0; i <= FPS_REG; i++) { | ||
583 | ret = max77663_read(parent, reg->regs[i].addr, | ||
584 | ®->regs[i].val, 1, 0); | ||
585 | if (ret < 0) { | ||
586 | dev_err(reg->dev, | ||
587 | "preinit: Failed to get register 0x%x\n", | ||
588 | reg->regs[i].addr); | ||
589 | return ret; | ||
590 | } | ||
591 | } | ||
592 | |||
593 | /* Update FPS source */ | ||
594 | if (reg->regs[FPS_REG].addr == MAX77663_REG_FPS_NONE) | ||
595 | reg->fps_src = FPS_SRC_NONE; | ||
596 | else | ||
597 | reg->fps_src = (reg->regs[FPS_REG].val & FPS_SRC_MASK) | ||
598 | >> FPS_SRC_SHIFT; | ||
599 | |||
600 | dev_dbg(reg->dev, "preinit: initial fps_src=%s\n", | ||
601 | fps_src_name(reg->fps_src)); | ||
602 | |||
603 | /* Update power mode */ | ||
604 | max77663_regulator_get_power_mode(reg); | ||
605 | |||
606 | /* Check Chip Identification */ | ||
607 | ret = max77663_read(parent, MAX77663_REG_CID5, &val, 1, 0); | ||
608 | if (ret < 0) { | ||
609 | dev_err(reg->dev, "preinit: Failed to get register 0x%x\n", | ||
610 | MAX77663_REG_CID5); | ||
611 | return ret; | ||
612 | } | ||
613 | |||
614 | /* If metal revision is less than rev.3, | ||
615 | * set safe_down_uV for stable down scaling. */ | ||
616 | if ((reg->type == REGULATOR_TYPE_SD) && | ||
617 | ((val & CID_DIDM_MASK) >> CID_DIDM_SHIFT) <= 2) | ||
618 | reg->safe_down_uV = SD_SAFE_DOWN_UV; | ||
619 | else | ||
620 | reg->safe_down_uV = 0; | ||
621 | |||
622 | /* Set FPS */ | ||
623 | ret = max77663_regulator_set_fps_cfgs(reg, pdata->fps_cfgs, | ||
624 | pdata->num_fps_cfgs); | ||
625 | if (ret < 0) { | ||
626 | dev_err(reg->dev, "preinit: Failed to set FPSCFG\n"); | ||
627 | return ret; | ||
628 | } | ||
629 | |||
630 | /* N-Channel LDOs don't support Low-Power mode. */ | ||
631 | if ((reg->type == REGULATOR_TYPE_LDO_N) && | ||
632 | (pdata->flags & GLPM_ENABLE)) | ||
633 | pdata->flags &= ~GLPM_ENABLE; | ||
634 | |||
635 | /* To prevent power rail turn-off when change FPS source, | ||
636 | * it must set power mode to NORMAL before change FPS source to NONE | ||
637 | * from SRC_0, SRC_1 and SRC_2. */ | ||
638 | if ((reg->fps_src != FPS_SRC_NONE) && (pdata->fps_src == FPS_SRC_NONE) | ||
639 | && (reg->power_mode != POWER_MODE_NORMAL)) { | ||
640 | val = (pdata->flags & GLPM_ENABLE) ? | ||
641 | POWER_MODE_GLPM : POWER_MODE_NORMAL; | ||
642 | ret = max77663_regulator_set_power_mode(reg, val); | ||
643 | if (ret < 0) { | ||
644 | dev_err(reg->dev, "preinit: Failed to " | ||
645 | "set power mode to POWER_MODE_NORMAL\n"); | ||
646 | return ret; | ||
647 | } | ||
648 | } | ||
649 | |||
650 | ret = max77663_regulator_set_fps_src(reg, pdata->fps_src); | ||
651 | if (ret < 0) { | ||
652 | dev_err(reg->dev, "preinit: Failed to set FPSSRC to %d\n", | ||
653 | pdata->fps_src); | ||
654 | return ret; | ||
655 | } | ||
656 | |||
657 | ret = max77663_regulator_set_fps(reg); | ||
658 | if (ret < 0) { | ||
659 | dev_err(reg->dev, "preinit: Failed to set FPS\n"); | ||
660 | return ret; | ||
661 | } | ||
662 | |||
663 | /* Set initial state */ | ||
664 | if (!pdata->init_apply) | ||
665 | goto skip_init_apply; | ||
666 | |||
667 | if (pdata->init_uV >= 0) { | ||
668 | ret = max77663_regulator_do_set_voltage(reg, pdata->init_uV, | ||
669 | pdata->init_uV); | ||
670 | if (ret < 0) { | ||
671 | dev_err(reg->dev, "preinit: Failed to set voltage to " | ||
672 | "%d\n", pdata->init_uV); | ||
673 | return ret; | ||
674 | } | ||
675 | } | ||
676 | |||
677 | if (pdata->init_enable) | ||
678 | val = (pdata->flags & GLPM_ENABLE) ? | ||
679 | POWER_MODE_GLPM : POWER_MODE_NORMAL; | ||
680 | else | ||
681 | val = POWER_MODE_DISABLE; | ||
682 | |||
683 | ret = max77663_regulator_set_power_mode(reg, val); | ||
684 | if (ret < 0) { | ||
685 | dev_err(reg->dev, | ||
686 | "preinit: Failed to set power mode to %d\n", val); | ||
687 | return ret; | ||
688 | } | ||
689 | |||
690 | skip_init_apply: | ||
691 | if (reg->type == REGULATOR_TYPE_SD) { | ||
692 | val = 0; | ||
693 | mask = 0; | ||
694 | |||
695 | if (pdata->flags & SD_SLEW_RATE_MASK) { | ||
696 | mask |= SD_SR_MASK; | ||
697 | if (pdata->flags & SD_SLEW_RATE_SLOWEST) | ||
698 | val |= (SD_SR_13_75 << SD_SR_SHIFT); | ||
699 | else if (pdata->flags & SD_SLEW_RATE_SLOW) | ||
700 | val |= (SD_SR_27_5 << SD_SR_SHIFT); | ||
701 | else if (pdata->flags & SD_SLEW_RATE_FAST) | ||
702 | val |= (SD_SR_55 << SD_SR_SHIFT); | ||
703 | else | ||
704 | val |= (SD_SR_100 << SD_SR_SHIFT); | ||
705 | } | ||
706 | |||
707 | if (pdata->flags & SD_FORCED_PWM_MODE) { | ||
708 | mask |= SD_FPWM_MASK; | ||
709 | val |= SD_FPWM_MASK; | ||
710 | } | ||
711 | |||
712 | if (pdata->flags & SD_FSRADE_DISABLE) { | ||
713 | mask |= SD_FSRADE_MASK; | ||
714 | val |= SD_FSRADE_MASK; | ||
715 | } | ||
716 | |||
717 | ret = max77663_regulator_cache_write(reg, | ||
718 | reg->regs[CFG_REG].addr, mask, val, | ||
719 | ®->regs[CFG_REG].val); | ||
720 | if (ret < 0) { | ||
721 | dev_err(reg->dev, "preinit: " | ||
722 | "Failed to set register 0x%x\n", | ||
723 | reg->regs[CFG_REG].addr); | ||
724 | return ret; | ||
725 | } | ||
726 | |||
727 | if ((reg->id == MAX77663_REGULATOR_ID_SD0) | ||
728 | && (pdata->flags & EN2_CTRL_SD0)) { | ||
729 | val = POWER_MODE_DISABLE; | ||
730 | ret = max77663_regulator_set_power_mode(reg, val); | ||
731 | if (ret < 0) { | ||
732 | dev_err(reg->dev, "preinit: " | ||
733 | "Failed to set power mode to %d for " | ||
734 | "EN2_CTRL_SD0\n", val); | ||
735 | return ret; | ||
736 | } | ||
737 | |||
738 | ret = max77663_regulator_set_fps_src(reg, FPS_SRC_NONE); | ||
739 | if (ret < 0) { | ||
740 | dev_err(reg->dev, "preinit: " | ||
741 | "Failed to set FPSSRC to FPS_SRC_NONE " | ||
742 | "for EN2_CTRL_SD0\n"); | ||
743 | return ret; | ||
744 | } | ||
745 | } | ||
746 | } | ||
747 | |||
748 | if ((reg->id == MAX77663_REGULATOR_ID_LDO4) | ||
749 | && (pdata->flags & LDO4_EN_TRACKING)) { | ||
750 | val = TRACK4_MASK; | ||
751 | ret = max77663_write(parent, MAX77663_REG_LDO_CFG3, &val, 1, 0); | ||
752 | if (ret < 0) { | ||
753 | dev_err(reg->dev, "preinit: " | ||
754 | "Failed to set register 0x%x\n", | ||
755 | MAX77663_REG_LDO_CFG3); | ||
756 | return ret; | ||
757 | } | ||
758 | } | ||
759 | |||
760 | return 0; | ||
761 | } | ||
762 | |||
763 | #define REGULATOR_SD(_id, _volt_mask, _fps_reg, _min_uV, _max_uV, _step_uV) \ | ||
764 | [MAX77663_REGULATOR_ID_##_id] = { \ | ||
765 | .id = MAX77663_REGULATOR_ID_##_id, \ | ||
766 | .type = REGULATOR_TYPE_SD, \ | ||
767 | .volt_mask = _volt_mask##_VOLT_MASK, \ | ||
768 | .regs = { \ | ||
769 | [VOLT_REG] = { \ | ||
770 | .addr = MAX77663_REG_##_id, \ | ||
771 | }, \ | ||
772 | [CFG_REG] = { \ | ||
773 | .addr = MAX77663_REG_##_id##_CFG, \ | ||
774 | }, \ | ||
775 | [FPS_REG] = { \ | ||
776 | .addr = MAX77663_REG_FPS_##_fps_reg, \ | ||
777 | }, \ | ||
778 | }, \ | ||
779 | .min_uV = _min_uV, \ | ||
780 | .max_uV = _max_uV, \ | ||
781 | .step_uV = _step_uV, \ | ||
782 | .regulator_mode = REGULATOR_MODE_NORMAL, \ | ||
783 | .power_mode = POWER_MODE_NORMAL, \ | ||
784 | .power_mode_mask = SD_POWER_MODE_MASK, \ | ||
785 | .power_mode_shift = SD_POWER_MODE_SHIFT, \ | ||
786 | } | ||
787 | |||
788 | #define REGULATOR_LDO(_id, _type, _min_uV, _max_uV, _step_uV) \ | ||
789 | [MAX77663_REGULATOR_ID_##_id] = { \ | ||
790 | .id = MAX77663_REGULATOR_ID_##_id, \ | ||
791 | .type = REGULATOR_TYPE_LDO_##_type, \ | ||
792 | .volt_mask = LDO_VOLT_MASK, \ | ||
793 | .regs = { \ | ||
794 | [VOLT_REG] = { \ | ||
795 | .addr = MAX77663_REG_##_id##_CFG, \ | ||
796 | }, \ | ||
797 | [CFG_REG] = { \ | ||
798 | .addr = MAX77663_REG_##_id##_CFG2, \ | ||
799 | }, \ | ||
800 | [FPS_REG] = { \ | ||
801 | .addr = MAX77663_REG_FPS_##_id, \ | ||
802 | }, \ | ||
803 | }, \ | ||
804 | .min_uV = _min_uV, \ | ||
805 | .max_uV = _max_uV, \ | ||
806 | .step_uV = _step_uV, \ | ||
807 | .regulator_mode = REGULATOR_MODE_NORMAL, \ | ||
808 | .power_mode = POWER_MODE_NORMAL, \ | ||
809 | .power_mode_mask = LDO_POWER_MODE_MASK, \ | ||
810 | .power_mode_shift = LDO_POWER_MODE_SHIFT, \ | ||
811 | } | ||
812 | |||
813 | static struct max77663_regulator max77663_regs[MAX77663_REGULATOR_ID_NR] = { | ||
814 | REGULATOR_SD(SD0, SDX, SD0, 600000, 3387500, 12500), | ||
815 | REGULATOR_SD(DVSSD0, SDX, NONE, 600000, 3387500, 12500), | ||
816 | REGULATOR_SD(SD1, SD1, SD1, 800000, 1587500, 12500), | ||
817 | REGULATOR_SD(DVSSD1, SD1, NONE, 800000, 1587500, 12500), | ||
818 | REGULATOR_SD(SD2, SDX, SD2, 600000, 3387500, 12500), | ||
819 | REGULATOR_SD(SD3, SDX, SD3, 600000, 3387500, 12500), | ||
820 | REGULATOR_SD(SD4, SDX, SD4, 600000, 3387500, 12500), | ||
821 | |||
822 | REGULATOR_LDO(LDO0, N, 800000, 2350000, 25000), | ||
823 | REGULATOR_LDO(LDO1, N, 800000, 2350000, 25000), | ||
824 | REGULATOR_LDO(LDO2, P, 800000, 3950000, 50000), | ||
825 | REGULATOR_LDO(LDO3, P, 800000, 3950000, 50000), | ||
826 | REGULATOR_LDO(LDO4, P, 800000, 1587500, 12500), | ||
827 | REGULATOR_LDO(LDO5, P, 800000, 3950000, 50000), | ||
828 | REGULATOR_LDO(LDO6, P, 800000, 3950000, 50000), | ||
829 | REGULATOR_LDO(LDO7, N, 800000, 3950000, 50000), | ||
830 | REGULATOR_LDO(LDO8, N, 800000, 3950000, 50000), | ||
831 | }; | ||
832 | |||
833 | #define REGULATOR_DESC(_id, _name) \ | ||
834 | [MAX77663_REGULATOR_ID_##_id] = { \ | ||
835 | .name = max77663_rails(_name), \ | ||
836 | .id = MAX77663_REGULATOR_ID_##_id, \ | ||
837 | .ops = &max77663_ldo_ops, \ | ||
838 | .type = REGULATOR_VOLTAGE, \ | ||
839 | .owner = THIS_MODULE, \ | ||
840 | } | ||
841 | |||
842 | static struct regulator_desc max77663_rdesc[MAX77663_REGULATOR_ID_NR] = { | ||
843 | REGULATOR_DESC(SD0, sd0), | ||
844 | REGULATOR_DESC(DVSSD0, dvssd0), | ||
845 | REGULATOR_DESC(SD1, sd1), | ||
846 | REGULATOR_DESC(DVSSD1, dvssd1), | ||
847 | REGULATOR_DESC(SD2, sd2), | ||
848 | REGULATOR_DESC(SD3, sd3), | ||
849 | REGULATOR_DESC(SD4, sd4), | ||
850 | REGULATOR_DESC(LDO0, ldo0), | ||
851 | REGULATOR_DESC(LDO1, ldo1), | ||
852 | REGULATOR_DESC(LDO2, ldo2), | ||
853 | REGULATOR_DESC(LDO3, ldo3), | ||
854 | REGULATOR_DESC(LDO4, ldo4), | ||
855 | REGULATOR_DESC(LDO5, ldo5), | ||
856 | REGULATOR_DESC(LDO6, ldo6), | ||
857 | REGULATOR_DESC(LDO7, ldo7), | ||
858 | REGULATOR_DESC(LDO8, ldo8), | ||
859 | }; | ||
860 | |||
861 | static int max77663_regulator_probe(struct platform_device *pdev) | ||
862 | { | ||
863 | struct regulator_desc *rdesc; | ||
864 | struct max77663_regulator *reg; | ||
865 | int ret = 0; | ||
866 | |||
867 | if ((pdev->id < 0) || (pdev->id >= MAX77663_REGULATOR_ID_NR)) { | ||
868 | dev_err(&pdev->dev, "Invalid device id %d\n", pdev->id); | ||
869 | return -ENODEV; | ||
870 | } | ||
871 | |||
872 | rdesc = &max77663_rdesc[pdev->id]; | ||
873 | reg = &max77663_regs[pdev->id]; | ||
874 | reg->dev = &pdev->dev; | ||
875 | reg->pdata = dev_get_platdata(&pdev->dev); | ||
876 | |||
877 | dev_dbg(&pdev->dev, "probe: name=%s\n", rdesc->name); | ||
878 | |||
879 | ret = max77663_regulator_preinit(reg); | ||
880 | if (ret) { | ||
881 | dev_err(&pdev->dev, "probe: Failed to preinit regulator %s\n", | ||
882 | rdesc->name); | ||
883 | return ret; | ||
884 | } | ||
885 | |||
886 | reg->rdev = regulator_register(rdesc, &pdev->dev, | ||
887 | ®->pdata->init_data, reg); | ||
888 | if (IS_ERR(reg->rdev)) { | ||
889 | dev_err(&pdev->dev, "probe: Failed to register regulator %s\n", | ||
890 | rdesc->name); | ||
891 | return PTR_ERR(reg->rdev); | ||
892 | } | ||
893 | |||
894 | return 0; | ||
895 | } | ||
896 | |||
897 | static int max77663_regulator_remove(struct platform_device *pdev) | ||
898 | { | ||
899 | struct regulator_dev *rdev = platform_get_drvdata(pdev); | ||
900 | |||
901 | regulator_unregister(rdev); | ||
902 | return 0; | ||
903 | } | ||
904 | |||
905 | static struct platform_driver max77663_regulator_driver = { | ||
906 | .probe = max77663_regulator_probe, | ||
907 | .remove = __devexit_p(max77663_regulator_remove), | ||
908 | .driver = { | ||
909 | .name = "max77663-regulator", | ||
910 | .owner = THIS_MODULE, | ||
911 | }, | ||
912 | }; | ||
913 | |||
914 | static int __init max77663_regulator_init(void) | ||
915 | { | ||
916 | return platform_driver_register(&max77663_regulator_driver); | ||
917 | } | ||
918 | subsys_initcall(max77663_regulator_init); | ||
919 | |||
920 | static void __exit max77663_reg_exit(void) | ||
921 | { | ||
922 | platform_driver_unregister(&max77663_regulator_driver); | ||
923 | } | ||
924 | module_exit(max77663_reg_exit); | ||
925 | |||
926 | MODULE_LICENSE("GPL v2"); | ||
927 | MODULE_DESCRIPTION("max77663 regulator driver"); | ||
928 | MODULE_VERSION("1.0"); | ||
diff --git a/drivers/regulator/max8907c-regulator.c b/drivers/regulator/max8907c-regulator.c new file mode 100644 index 00000000000..925f161d992 --- /dev/null +++ b/drivers/regulator/max8907c-regulator.c | |||
@@ -0,0 +1,421 @@ | |||
1 | /* | ||
2 | * max8907c-regulator.c -- support regulators in max8907c | ||
3 | * | ||
4 | * Copyright (C) 2010 Gyungoh Yoo <jack.yoo@maxim-ic.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/module.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/slab.h> | ||
14 | #include <linux/err.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/regulator/driver.h> | ||
17 | #include <linux/mfd/max8907c.h> | ||
18 | #include <linux/regulator/max8907c-regulator.h> | ||
19 | |||
20 | #define MAX8907C_II2RR_VERSION_MASK 0xF0 | ||
21 | #define MAX8907C_II2RR_VERSION_REV_A 0x00 | ||
22 | #define MAX8907C_II2RR_VERSION_REV_B 0x10 | ||
23 | #define MAX8907C_II2RR_VERSION_REV_C 0x30 | ||
24 | |||
25 | #define MAX8907C_REGULATOR_CNT (ARRAY_SIZE(max8907c_regulators)) | ||
26 | |||
27 | struct max8907c_regulator_info { | ||
28 | u32 min_uV; | ||
29 | u32 max_uV; | ||
30 | u32 step_uV; | ||
31 | u8 reg_base; | ||
32 | struct regulator_desc desc; | ||
33 | struct i2c_client *i2c; | ||
34 | }; | ||
35 | |||
36 | #define REG_LDO(ids, base, min, max, step) \ | ||
37 | { \ | ||
38 | .min_uV = (min), \ | ||
39 | .max_uV = (max), \ | ||
40 | .step_uV = (step), \ | ||
41 | .reg_base = (base), \ | ||
42 | .desc = { \ | ||
43 | .name = #ids, \ | ||
44 | .id = MAX8907C_##ids, \ | ||
45 | .n_voltages = ((max) - (min)) / (step) + 1, \ | ||
46 | .ops = &max8907c_ldo_ops, \ | ||
47 | .type = REGULATOR_VOLTAGE, \ | ||
48 | .owner = THIS_MODULE, \ | ||
49 | }, \ | ||
50 | } | ||
51 | |||
52 | #define REG_FIXED(ids, voltage) \ | ||
53 | { \ | ||
54 | .min_uV = (voltage), \ | ||
55 | .max_uV = (voltage), \ | ||
56 | .desc = { \ | ||
57 | .name = #ids, \ | ||
58 | .id = MAX8907C_##ids, \ | ||
59 | .n_voltages = 1, \ | ||
60 | .ops = &max8907c_fixed_ops, \ | ||
61 | .type = REGULATOR_VOLTAGE, \ | ||
62 | .owner = THIS_MODULE, \ | ||
63 | }, \ | ||
64 | } | ||
65 | |||
66 | #define REG_OUT5V(ids, base, voltage) \ | ||
67 | { \ | ||
68 | .min_uV = (voltage), \ | ||
69 | .max_uV = (voltage), \ | ||
70 | .reg_base = (base), \ | ||
71 | .desc = { \ | ||
72 | .name = #ids, \ | ||
73 | .id = MAX8907C_##ids, \ | ||
74 | .n_voltages = 1, \ | ||
75 | .ops = &max8907c_out5v_ops, \ | ||
76 | .type = REGULATOR_VOLTAGE, \ | ||
77 | .owner = THIS_MODULE, \ | ||
78 | }, \ | ||
79 | } | ||
80 | |||
81 | #define REG_BBAT(ids, base, min, max, step) \ | ||
82 | { \ | ||
83 | .min_uV = (min), \ | ||
84 | .max_uV = (max), \ | ||
85 | .step_uV = (step), \ | ||
86 | .reg_base = (base), \ | ||
87 | .desc = { \ | ||
88 | .name = #ids, \ | ||
89 | .id = MAX8907C_##ids, \ | ||
90 | .n_voltages = ((max) - (min)) / (step) + 1, \ | ||
91 | .ops = &max8907c_bbat_ops, \ | ||
92 | .type = REGULATOR_VOLTAGE, \ | ||
93 | .owner = THIS_MODULE, \ | ||
94 | }, \ | ||
95 | } | ||
96 | |||
97 | #define REG_WLED(ids, base, voltage) \ | ||
98 | { \ | ||
99 | .min_uV = (voltage), \ | ||
100 | .max_uV = (voltage), \ | ||
101 | .reg_base = (base), \ | ||
102 | .desc = { \ | ||
103 | .name = #ids, \ | ||
104 | .id = MAX8907C_##ids, \ | ||
105 | .n_voltages = 1, \ | ||
106 | .ops = &max8907c_wled_ops, \ | ||
107 | .type = REGULATOR_CURRENT, \ | ||
108 | .owner = THIS_MODULE, \ | ||
109 | }, \ | ||
110 | } | ||
111 | |||
112 | #define LDO_750_50(id, base) REG_LDO(id, (base), 750000, 3900000, 50000) | ||
113 | #define LDO_650_25(id, base) REG_LDO(id, (base), 650000, 2225000, 25000) | ||
114 | |||
115 | static int max8907c_regulator_list_voltage(struct regulator_dev *dev, | ||
116 | unsigned index); | ||
117 | static int max8907c_regulator_ldo_set_voltage(struct regulator_dev *dev, | ||
118 | int min_uV, int max_uV); | ||
119 | static int max8907c_regulator_bbat_set_voltage(struct regulator_dev *dev, | ||
120 | int min_uV, int max_uV); | ||
121 | static int max8907c_regulator_ldo_get_voltage(struct regulator_dev *dev); | ||
122 | static int max8907c_regulator_fixed_get_voltage(struct regulator_dev *dev); | ||
123 | static int max8907c_regulator_bbat_get_voltage(struct regulator_dev *dev); | ||
124 | static int max8907c_regulator_wled_set_current_limit(struct regulator_dev *dev, | ||
125 | int min_uA, int max_uA); | ||
126 | static int max8907c_regulator_wled_get_current_limit(struct regulator_dev *dev); | ||
127 | static int max8907c_regulator_ldo_enable(struct regulator_dev *dev); | ||
128 | static int max8907c_regulator_out5v_enable(struct regulator_dev *dev); | ||
129 | static int max8907c_regulator_ldo_disable(struct regulator_dev *dev); | ||
130 | static int max8907c_regulator_out5v_disable(struct regulator_dev *dev); | ||
131 | static int max8907c_regulator_ldo_is_enabled(struct regulator_dev *dev); | ||
132 | static int max8907c_regulator_out5v_is_enabled(struct regulator_dev *dev); | ||
133 | |||
134 | static struct regulator_ops max8907c_ldo_ops = { | ||
135 | .list_voltage = max8907c_regulator_list_voltage, | ||
136 | .set_voltage = max8907c_regulator_ldo_set_voltage, | ||
137 | .get_voltage = max8907c_regulator_ldo_get_voltage, | ||
138 | .enable = max8907c_regulator_ldo_enable, | ||
139 | .disable = max8907c_regulator_ldo_disable, | ||
140 | .is_enabled = max8907c_regulator_ldo_is_enabled, | ||
141 | }; | ||
142 | |||
143 | static struct regulator_ops max8907c_fixed_ops = { | ||
144 | .list_voltage = max8907c_regulator_list_voltage, | ||
145 | .get_voltage = max8907c_regulator_fixed_get_voltage, | ||
146 | }; | ||
147 | |||
148 | static struct regulator_ops max8907c_out5v_ops = { | ||
149 | .list_voltage = max8907c_regulator_list_voltage, | ||
150 | .get_voltage = max8907c_regulator_fixed_get_voltage, | ||
151 | .enable = max8907c_regulator_out5v_enable, | ||
152 | .disable = max8907c_regulator_out5v_disable, | ||
153 | .is_enabled = max8907c_regulator_out5v_is_enabled, | ||
154 | }; | ||
155 | |||
156 | static struct regulator_ops max8907c_bbat_ops = { | ||
157 | .list_voltage = max8907c_regulator_list_voltage, | ||
158 | .set_voltage = max8907c_regulator_bbat_set_voltage, | ||
159 | .get_voltage = max8907c_regulator_bbat_get_voltage, | ||
160 | }; | ||
161 | |||
162 | static struct regulator_ops max8907c_wled_ops = { | ||
163 | .list_voltage = max8907c_regulator_list_voltage, | ||
164 | .set_current_limit = max8907c_regulator_wled_set_current_limit, | ||
165 | .get_current_limit = max8907c_regulator_wled_get_current_limit, | ||
166 | .get_voltage = max8907c_regulator_fixed_get_voltage, | ||
167 | }; | ||
168 | |||
169 | static struct max8907c_regulator_info max8907c_regulators[] = { | ||
170 | REG_LDO(SD1, MAX8907C_REG_SDCTL1, 650000, 2225000, 25000), | ||
171 | REG_LDO(SD2, MAX8907C_REG_SDCTL2, 637500, 1425000, 12500), | ||
172 | REG_LDO(SD3, MAX8907C_REG_SDCTL3, 750000, 3900000, 50000), | ||
173 | LDO_750_50(LDO1, MAX8907C_REG_LDOCTL1), | ||
174 | LDO_650_25(LDO2, MAX8907C_REG_LDOCTL2), | ||
175 | LDO_650_25(LDO3, MAX8907C_REG_LDOCTL3), | ||
176 | LDO_750_50(LDO4, MAX8907C_REG_LDOCTL4), | ||
177 | LDO_750_50(LDO5, MAX8907C_REG_LDOCTL5), | ||
178 | LDO_750_50(LDO6, MAX8907C_REG_LDOCTL6), | ||
179 | LDO_750_50(LDO7, MAX8907C_REG_LDOCTL7), | ||
180 | LDO_750_50(LDO8, MAX8907C_REG_LDOCTL8), | ||
181 | LDO_750_50(LDO9, MAX8907C_REG_LDOCTL9), | ||
182 | LDO_750_50(LDO10, MAX8907C_REG_LDOCTL10), | ||
183 | LDO_750_50(LDO11, MAX8907C_REG_LDOCTL11), | ||
184 | LDO_750_50(LDO12, MAX8907C_REG_LDOCTL12), | ||
185 | LDO_750_50(LDO13, MAX8907C_REG_LDOCTL13), | ||
186 | LDO_750_50(LDO14, MAX8907C_REG_LDOCTL14), | ||
187 | LDO_750_50(LDO15, MAX8907C_REG_LDOCTL15), | ||
188 | LDO_750_50(LDO16, MAX8907C_REG_LDOCTL16), | ||
189 | LDO_650_25(LDO17, MAX8907C_REG_LDOCTL17), | ||
190 | LDO_650_25(LDO18, MAX8907C_REG_LDOCTL18), | ||
191 | LDO_750_50(LDO19, MAX8907C_REG_LDOCTL19), | ||
192 | LDO_750_50(LDO20, MAX8907C_REG_LDOCTL20), | ||
193 | REG_OUT5V(OUT5V, MAX8907C_REG_OUT5VEN, 5000000), | ||
194 | REG_OUT5V(OUT33V, MAX8907C_REG_OUT33VEN, 3300000), | ||
195 | REG_BBAT(BBAT, MAX8907C_REG_BBAT_CNFG, 2400000, 3000000, 200000), | ||
196 | REG_FIXED(SDBY, 1200000), | ||
197 | REG_FIXED(VRTC, 3300000), | ||
198 | REG_WLED(WLED, MAX8907C_REG_ILED_CNTL, 0), | ||
199 | }; | ||
200 | |||
201 | static int max8907c_regulator_list_voltage(struct regulator_dev *rdev, | ||
202 | unsigned index) | ||
203 | { | ||
204 | const struct max8907c_regulator_info *info = rdev_get_drvdata(rdev); | ||
205 | |||
206 | return info->min_uV + info->step_uV * index; | ||
207 | } | ||
208 | |||
209 | static int max8907c_regulator_ldo_set_voltage(struct regulator_dev *rdev, | ||
210 | int min_uV, int max_uV) | ||
211 | { | ||
212 | const struct max8907c_regulator_info *info = rdev_get_drvdata(rdev); | ||
213 | int val; | ||
214 | |||
215 | if (min_uV < info->min_uV || max_uV > info->max_uV) | ||
216 | return -EDOM; | ||
217 | |||
218 | val = (min_uV - info->min_uV) / info->step_uV; | ||
219 | |||
220 | return max8907c_reg_write(info->i2c, info->reg_base + MAX8907C_VOUT, val); | ||
221 | } | ||
222 | |||
223 | static int max8907c_regulator_bbat_set_voltage(struct regulator_dev *rdev, | ||
224 | int min_uV, int max_uV) | ||
225 | { | ||
226 | const struct max8907c_regulator_info *info = rdev_get_drvdata(rdev); | ||
227 | int val; | ||
228 | |||
229 | if (min_uV < info->min_uV || max_uV > info->max_uV) | ||
230 | return -EDOM; | ||
231 | |||
232 | val = (min_uV - info->min_uV) / info->step_uV; | ||
233 | |||
234 | return max8907c_set_bits(info->i2c, info->reg_base, MAX8907C_MASK_VBBATTCV, | ||
235 | val); | ||
236 | } | ||
237 | |||
238 | static int max8907c_regulator_ldo_get_voltage(struct regulator_dev *rdev) | ||
239 | { | ||
240 | const struct max8907c_regulator_info *info = rdev_get_drvdata(rdev); | ||
241 | int val; | ||
242 | |||
243 | val = max8907c_reg_read(info->i2c, info->reg_base + MAX8907C_VOUT); | ||
244 | return val * info->step_uV + info->min_uV; | ||
245 | } | ||
246 | |||
247 | static int max8907c_regulator_fixed_get_voltage(struct regulator_dev *rdev) | ||
248 | { | ||
249 | const struct max8907c_regulator_info *info = rdev_get_drvdata(rdev); | ||
250 | |||
251 | return info->min_uV; | ||
252 | } | ||
253 | |||
254 | static int max8907c_regulator_bbat_get_voltage(struct regulator_dev *rdev) | ||
255 | { | ||
256 | const struct max8907c_regulator_info *info = rdev_get_drvdata(rdev); | ||
257 | int val; | ||
258 | |||
259 | val = | ||
260 | max8907c_reg_read(info->i2c, info->reg_base) & MAX8907C_MASK_VBBATTCV; | ||
261 | return val * info->step_uV + info->min_uV; | ||
262 | } | ||
263 | |||
264 | static int max8907c_regulator_wled_set_current_limit(struct regulator_dev *rdev, | ||
265 | int min_uA, int max_uA) | ||
266 | { | ||
267 | const struct max8907c_regulator_info *info = rdev_get_drvdata(rdev); | ||
268 | |||
269 | if (min_uA > 25500) | ||
270 | return -EDOM; | ||
271 | |||
272 | return max8907c_reg_write(info->i2c, info->reg_base, min_uA / 100); | ||
273 | } | ||
274 | |||
275 | static int max8907c_regulator_wled_get_current_limit(struct regulator_dev *rdev) | ||
276 | { | ||
277 | const struct max8907c_regulator_info *info = rdev_get_drvdata(rdev); | ||
278 | int val; | ||
279 | |||
280 | val = max8907c_reg_read(info->i2c, info->reg_base); | ||
281 | return val * 100; | ||
282 | } | ||
283 | |||
284 | static int max8907c_regulator_ldo_enable(struct regulator_dev *rdev) | ||
285 | { | ||
286 | const struct max8907c_regulator_info *info = rdev_get_drvdata(rdev); | ||
287 | |||
288 | return max8907c_set_bits(info->i2c, info->reg_base + MAX8907C_CTL, | ||
289 | MAX8907C_MASK_LDO_EN | MAX8907C_MASK_LDO_SEQ, | ||
290 | MAX8907C_MASK_LDO_EN | MAX8907C_MASK_LDO_SEQ); | ||
291 | } | ||
292 | |||
293 | static int max8907c_regulator_out5v_enable(struct regulator_dev *rdev) | ||
294 | { | ||
295 | const struct max8907c_regulator_info *info = rdev_get_drvdata(rdev); | ||
296 | |||
297 | return max8907c_set_bits(info->i2c, info->reg_base, | ||
298 | MAX8907C_MASK_OUT5V_VINEN | | ||
299 | MAX8907C_MASK_OUT5V_ENSRC | | ||
300 | MAX8907C_MASK_OUT5V_EN, | ||
301 | MAX8907C_MASK_OUT5V_ENSRC | | ||
302 | MAX8907C_MASK_OUT5V_EN); | ||
303 | } | ||
304 | |||
305 | static int max8907c_regulator_ldo_disable(struct regulator_dev *rdev) | ||
306 | { | ||
307 | const struct max8907c_regulator_info *info = rdev_get_drvdata(rdev); | ||
308 | |||
309 | return max8907c_set_bits(info->i2c, info->reg_base + MAX8907C_CTL, | ||
310 | MAX8907C_MASK_LDO_EN | MAX8907C_MASK_LDO_SEQ, | ||
311 | MAX8907C_MASK_LDO_SEQ); | ||
312 | } | ||
313 | |||
314 | static int max8907c_regulator_out5v_disable(struct regulator_dev *rdev) | ||
315 | { | ||
316 | const struct max8907c_regulator_info *info = rdev_get_drvdata(rdev); | ||
317 | |||
318 | return max8907c_set_bits(info->i2c, info->reg_base, | ||
319 | MAX8907C_MASK_OUT5V_VINEN | | ||
320 | MAX8907C_MASK_OUT5V_ENSRC | | ||
321 | MAX8907C_MASK_OUT5V_EN, | ||
322 | MAX8907C_MASK_OUT5V_ENSRC); | ||
323 | } | ||
324 | |||
325 | static int max8907c_regulator_ldo_is_enabled(struct regulator_dev *rdev) | ||
326 | { | ||
327 | const struct max8907c_regulator_info *info = rdev_get_drvdata(rdev); | ||
328 | int val; | ||
329 | |||
330 | val = max8907c_reg_read(info->i2c, info->reg_base + MAX8907C_CTL); | ||
331 | if (val < 0) | ||
332 | return -EDOM; | ||
333 | |||
334 | return (val & MAX8907C_MASK_LDO_EN) || !(val & MAX8907C_MASK_LDO_SEQ); | ||
335 | } | ||
336 | |||
337 | static int max8907c_regulator_out5v_is_enabled(struct regulator_dev *rdev) | ||
338 | { | ||
339 | const struct max8907c_regulator_info *info = rdev_get_drvdata(rdev); | ||
340 | int val; | ||
341 | |||
342 | val = max8907c_reg_read(info->i2c, info->reg_base); | ||
343 | if (val < 0) | ||
344 | return -EDOM; | ||
345 | |||
346 | if ((val & | ||
347 | (MAX8907C_MASK_OUT5V_VINEN | MAX8907C_MASK_OUT5V_ENSRC | | ||
348 | MAX8907C_MASK_OUT5V_EN)) | ||
349 | == MAX8907C_MASK_OUT5V_ENSRC) | ||
350 | return 1; | ||
351 | |||
352 | return 0; | ||
353 | } | ||
354 | |||
355 | static int max8907c_regulator_probe(struct platform_device *pdev) | ||
356 | { | ||
357 | struct max8907c *max8907c = dev_get_drvdata(pdev->dev.parent); | ||
358 | struct max8907c_regulator_info *info; | ||
359 | struct regulator_dev *rdev; | ||
360 | u8 version; | ||
361 | |||
362 | /* Backwards compatibility with max8907b, SD1 uses different voltages */ | ||
363 | version = max8907c_reg_read(max8907c->i2c_power, MAX8907C_REG_II2RR); | ||
364 | if ((version & MAX8907C_II2RR_VERSION_MASK) == MAX8907C_II2RR_VERSION_REV_B) { | ||
365 | max8907c_regulators[MAX8907C_SD1].min_uV = 637500; | ||
366 | max8907c_regulators[MAX8907C_SD1].max_uV = 1425000; | ||
367 | max8907c_regulators[MAX8907C_SD1].step_uV = 12500; | ||
368 | } | ||
369 | |||
370 | info = &max8907c_regulators[pdev->id]; | ||
371 | info->i2c = max8907c->i2c_power; | ||
372 | |||
373 | rdev = regulator_register(&info->desc, | ||
374 | &pdev->dev, pdev->dev.platform_data, info); | ||
375 | if (IS_ERR(rdev)) { | ||
376 | dev_err(&pdev->dev, "Cannot register regulator \"%s\", %ld\n", | ||
377 | info->desc.name, PTR_ERR(rdev)); | ||
378 | goto error; | ||
379 | } | ||
380 | |||
381 | platform_set_drvdata(pdev, rdev); | ||
382 | return 0; | ||
383 | |||
384 | error: | ||
385 | return PTR_ERR(rdev); | ||
386 | } | ||
387 | |||
388 | static int max8907c_regulator_remove(struct platform_device *pdev) | ||
389 | { | ||
390 | struct regulator_dev *rdev = platform_get_drvdata(pdev); | ||
391 | |||
392 | regulator_unregister(rdev); | ||
393 | return 0; | ||
394 | } | ||
395 | |||
396 | static struct platform_driver max8907c_regulator_driver = { | ||
397 | .driver = { | ||
398 | .name = "max8907c-regulator", | ||
399 | .owner = THIS_MODULE, | ||
400 | }, | ||
401 | .probe = max8907c_regulator_probe, | ||
402 | .remove = __devexit_p(max8907c_regulator_remove), | ||
403 | }; | ||
404 | |||
405 | static int __init max8907c_regulator_init(void) | ||
406 | { | ||
407 | return platform_driver_register(&max8907c_regulator_driver); | ||
408 | } | ||
409 | |||
410 | subsys_initcall(max8907c_regulator_init); | ||
411 | |||
412 | static void __exit max8907c_reg_exit(void) | ||
413 | { | ||
414 | platform_driver_unregister(&max8907c_regulator_driver); | ||
415 | } | ||
416 | |||
417 | module_exit(max8907c_reg_exit); | ||
418 | |||
419 | MODULE_DESCRIPTION("MAX8907C regulator driver"); | ||
420 | MODULE_AUTHOR("Gyungoh Yoo <jack.yoo@maxim-ic.com>"); | ||
421 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/regulator/ricoh583-regulator.c b/drivers/regulator/ricoh583-regulator.c new file mode 100644 index 00000000000..867ffe629ed --- /dev/null +++ b/drivers/regulator/ricoh583-regulator.c | |||
@@ -0,0 +1,412 @@ | |||
1 | /* | ||
2 | * drivers/regulator/ricoh583-regulator.c | ||
3 | * | ||
4 | * Regulator driver for RICOH583 power management chip. | ||
5 | * | ||
6 | * Copyright (C) 2011 NVIDIA Corporation | ||
7 | * | ||
8 | * Copyright (C) 2011 RICOH COMPANY,LTD | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
16 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
17 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
18 | * more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License along | ||
21 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
22 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
23 | * | ||
24 | */ | ||
25 | |||
26 | /*#define DEBUG 1*/ | ||
27 | /*#define VERBOSE_DEBUG 1*/ | ||
28 | #include <linux/module.h> | ||
29 | #include <linux/delay.h> | ||
30 | #include <linux/init.h> | ||
31 | #include <linux/slab.h> | ||
32 | #include <linux/err.h> | ||
33 | #include <linux/platform_device.h> | ||
34 | #include <linux/regulator/driver.h> | ||
35 | #include <linux/regulator/machine.h> | ||
36 | #include <linux/mfd/ricoh583.h> | ||
37 | #include <linux/regulator/ricoh583-regulator.h> | ||
38 | |||
39 | struct ricoh583_regulator { | ||
40 | int id; | ||
41 | int deepsleep_id; | ||
42 | /* Regulator register address.*/ | ||
43 | u8 reg_en_reg; | ||
44 | u8 en_bit; | ||
45 | u8 reg_disc_reg; | ||
46 | u8 disc_bit; | ||
47 | u8 vout_reg; | ||
48 | u8 vout_mask; | ||
49 | u8 vout_reg_cache; | ||
50 | u8 deepsleep_reg; | ||
51 | |||
52 | /* chip constraints on regulator behavior */ | ||
53 | int min_uV; | ||
54 | int max_uV; | ||
55 | int step_uV; | ||
56 | int nsteps; | ||
57 | |||
58 | /* regulator specific turn-on delay */ | ||
59 | u16 delay; | ||
60 | |||
61 | /* used by regulator core */ | ||
62 | struct regulator_desc desc; | ||
63 | |||
64 | /* Device */ | ||
65 | struct device *dev; | ||
66 | }; | ||
67 | |||
68 | |||
69 | static inline struct device *to_ricoh583_dev(struct regulator_dev *rdev) | ||
70 | { | ||
71 | return rdev_get_dev(rdev)->parent->parent; | ||
72 | } | ||
73 | |||
74 | static int ricoh583_regulator_enable_time(struct regulator_dev *rdev) | ||
75 | { | ||
76 | struct ricoh583_regulator *ri = rdev_get_drvdata(rdev); | ||
77 | |||
78 | return ri->delay; | ||
79 | } | ||
80 | |||
81 | static int ricoh583_reg_is_enabled(struct regulator_dev *rdev) | ||
82 | { | ||
83 | struct ricoh583_regulator *ri = rdev_get_drvdata(rdev); | ||
84 | struct device *parent = to_ricoh583_dev(rdev); | ||
85 | uint8_t control; | ||
86 | int ret; | ||
87 | |||
88 | ret = ricoh583_read(parent, ri->reg_en_reg, &control); | ||
89 | if (ret < 0) { | ||
90 | dev_err(&rdev->dev, "Error in reading the control register\n"); | ||
91 | return ret; | ||
92 | } | ||
93 | return (((control >> ri->en_bit) & 1) == 1); | ||
94 | } | ||
95 | |||
96 | static int ricoh583_reg_enable(struct regulator_dev *rdev) | ||
97 | { | ||
98 | struct ricoh583_regulator *ri = rdev_get_drvdata(rdev); | ||
99 | struct device *parent = to_ricoh583_dev(rdev); | ||
100 | int ret; | ||
101 | |||
102 | ret = ricoh583_set_bits(parent, ri->reg_en_reg, (1 << ri->en_bit)); | ||
103 | if (ret < 0) { | ||
104 | dev_err(&rdev->dev, "Error in updating the STATE register\n"); | ||
105 | return ret; | ||
106 | } | ||
107 | udelay(ri->delay); | ||
108 | return ret; | ||
109 | } | ||
110 | |||
111 | static int ricoh583_reg_disable(struct regulator_dev *rdev) | ||
112 | { | ||
113 | struct ricoh583_regulator *ri = rdev_get_drvdata(rdev); | ||
114 | struct device *parent = to_ricoh583_dev(rdev); | ||
115 | int ret; | ||
116 | |||
117 | ret = ricoh583_clr_bits(parent, ri->reg_en_reg, (1 << ri->en_bit)); | ||
118 | if (ret < 0) | ||
119 | dev_err(&rdev->dev, "Error in updating the STATE register\n"); | ||
120 | |||
121 | return ret; | ||
122 | } | ||
123 | |||
124 | static int ricoh583_list_voltage(struct regulator_dev *rdev, unsigned index) | ||
125 | { | ||
126 | struct ricoh583_regulator *ri = rdev_get_drvdata(rdev); | ||
127 | |||
128 | return ri->min_uV + (ri->step_uV * index); | ||
129 | } | ||
130 | |||
131 | static int __ricoh583_set_ds_voltage(struct device *parent, | ||
132 | struct ricoh583_regulator *ri, int min_uV, int max_uV) | ||
133 | { | ||
134 | int vsel; | ||
135 | int ret; | ||
136 | |||
137 | if ((min_uV < ri->min_uV) || (max_uV > ri->max_uV)) | ||
138 | return -EDOM; | ||
139 | |||
140 | vsel = (min_uV - ri->min_uV + ri->step_uV - 1)/ri->step_uV; | ||
141 | if (vsel > ri->nsteps) | ||
142 | return -EDOM; | ||
143 | |||
144 | ret = ricoh583_update(parent, ri->deepsleep_reg, vsel, ri->vout_mask); | ||
145 | if (ret < 0) | ||
146 | dev_err(ri->dev, "Error in writing the deepsleep register\n"); | ||
147 | return ret; | ||
148 | } | ||
149 | |||
150 | static int __ricoh583_set_voltage(struct device *parent, | ||
151 | struct ricoh583_regulator *ri, int min_uV, int max_uV, | ||
152 | unsigned *selector) | ||
153 | { | ||
154 | int vsel; | ||
155 | int ret; | ||
156 | uint8_t vout_val; | ||
157 | |||
158 | if ((min_uV < ri->min_uV) || (max_uV > ri->max_uV)) | ||
159 | return -EDOM; | ||
160 | |||
161 | vsel = (min_uV - ri->min_uV + ri->step_uV - 1)/ri->step_uV; | ||
162 | if (vsel > ri->nsteps) | ||
163 | return -EDOM; | ||
164 | |||
165 | if (selector) | ||
166 | *selector = vsel; | ||
167 | |||
168 | vout_val = (ri->vout_reg_cache & ~ri->vout_mask) | | ||
169 | (vsel & ri->vout_mask); | ||
170 | ret = ricoh583_write(parent, ri->vout_reg, vout_val); | ||
171 | if (ret < 0) | ||
172 | dev_err(ri->dev, "Error in writing the Voltage register\n"); | ||
173 | else | ||
174 | ri->vout_reg_cache = vout_val; | ||
175 | |||
176 | return ret; | ||
177 | } | ||
178 | |||
179 | static int ricoh583_set_voltage(struct regulator_dev *rdev, | ||
180 | int min_uV, int max_uV, unsigned *selector) | ||
181 | { | ||
182 | struct ricoh583_regulator *ri = rdev_get_drvdata(rdev); | ||
183 | struct device *parent = to_ricoh583_dev(rdev); | ||
184 | |||
185 | return __ricoh583_set_voltage(parent, ri, min_uV, max_uV, selector); | ||
186 | } | ||
187 | |||
188 | static int ricoh583_get_voltage(struct regulator_dev *rdev) | ||
189 | { | ||
190 | struct ricoh583_regulator *ri = rdev_get_drvdata(rdev); | ||
191 | uint8_t vsel; | ||
192 | |||
193 | vsel = ri->vout_reg_cache & ri->vout_mask; | ||
194 | return ri->min_uV + vsel * ri->step_uV; | ||
195 | } | ||
196 | |||
197 | static struct regulator_ops ricoh583_ops = { | ||
198 | .list_voltage = ricoh583_list_voltage, | ||
199 | .set_voltage = ricoh583_set_voltage, | ||
200 | .get_voltage = ricoh583_get_voltage, | ||
201 | .enable = ricoh583_reg_enable, | ||
202 | .disable = ricoh583_reg_disable, | ||
203 | .is_enabled = ricoh583_reg_is_enabled, | ||
204 | .enable_time = ricoh583_regulator_enable_time, | ||
205 | }; | ||
206 | |||
207 | #define RICOH583_REG(_id, _en_reg, _en_bit, _disc_reg, _disc_bit, _vout_reg, \ | ||
208 | _vout_mask, _ds_reg, _min_mv, _max_mv, _step_uV, _nsteps, \ | ||
209 | _ops, _delay) \ | ||
210 | { \ | ||
211 | .reg_en_reg = _en_reg, \ | ||
212 | .en_bit = _en_bit, \ | ||
213 | .reg_disc_reg = _disc_reg, \ | ||
214 | .disc_bit = _disc_bit, \ | ||
215 | .vout_reg = _vout_reg, \ | ||
216 | .vout_mask = _vout_mask, \ | ||
217 | .deepsleep_reg = _ds_reg, \ | ||
218 | .min_uV = _min_mv * 1000, \ | ||
219 | .max_uV = _max_mv * 1000, \ | ||
220 | .step_uV = _step_uV, \ | ||
221 | .nsteps = _nsteps, \ | ||
222 | .delay = _delay, \ | ||
223 | .id = RICOH583_ID_##_id, \ | ||
224 | .deepsleep_id = RICOH583_DS_##_id, \ | ||
225 | .desc = { \ | ||
226 | .name = ricoh583_rails(_id), \ | ||
227 | .id = RICOH583_ID_##_id, \ | ||
228 | .n_voltages = _nsteps, \ | ||
229 | .ops = &_ops, \ | ||
230 | .type = REGULATOR_VOLTAGE, \ | ||
231 | .owner = THIS_MODULE, \ | ||
232 | }, \ | ||
233 | } | ||
234 | |||
235 | static struct ricoh583_regulator ricoh583_regulator[] = { | ||
236 | RICOH583_REG(DC0, 0x30, 0, 0x30, 1, 0x31, 0x7F, 0x60, | ||
237 | 700, 1500, 12500, 0x41, ricoh583_ops, 500), | ||
238 | RICOH583_REG(DC1, 0x34, 0, 0x34, 1, 0x35, 0x7F, 0x61, | ||
239 | 700, 1500, 12500, 0x41, ricoh583_ops, 500), | ||
240 | RICOH583_REG(DC2, 0x38, 0, 0x38, 1, 0x39, 0x7F, 0x62, | ||
241 | 900, 2400, 12500, 0x79, ricoh583_ops, 500), | ||
242 | RICOH583_REG(DC3, 0x3C, 0, 0x3C, 1, 0x3D, 0x7F, 0x63, | ||
243 | 900, 2400, 12500, 0x79, ricoh583_ops, 500), | ||
244 | RICOH583_REG(LDO0, 0x51, 0, 0x53, 0, 0x54, 0x7F, 0x64, | ||
245 | 900, 3400, 25000, 0x65, ricoh583_ops, 500), | ||
246 | RICOH583_REG(LDO1, 0x51, 1, 0x53, 1, 0x55, 0x7F, 0x65, | ||
247 | 900, 3400, 25000, 0x65, ricoh583_ops, 500), | ||
248 | RICOH583_REG(LDO2, 0x51, 2, 0x53, 2, 0x56, 0x7F, 0x66, | ||
249 | 900, 3400, 25000, 0x65, ricoh583_ops, 500), | ||
250 | RICOH583_REG(LDO3, 0x51, 3, 0x53, 3, 0x57, 0x7F, 0x67, | ||
251 | 900, 3400, 25000, 0x65, ricoh583_ops, 500), | ||
252 | RICOH583_REG(LDO4, 0x51, 4, 0x53, 4, 0x58, 0x3F, 0x68, | ||
253 | 750, 1500, 12500, 0x3D, ricoh583_ops, 500), | ||
254 | RICOH583_REG(LDO5, 0x51, 5, 0x53, 5, 0x59, 0x7F, 0x69, | ||
255 | 900, 3400, 25000, 0x65, ricoh583_ops, 500), | ||
256 | RICOH583_REG(LDO6, 0x51, 6, 0x53, 6, 0x5A, 0x7F, 0x6A, | ||
257 | 900, 3400, 25000, 0x65, ricoh583_ops, 500), | ||
258 | RICOH583_REG(LDO7, 0x51, 7, 0x53, 7, 0x5B, 0x7F, 0x6B, | ||
259 | 900, 3400, 25000, 0x65, ricoh583_ops, 500), | ||
260 | RICOH583_REG(LDO8, 0x50, 0, 0x52, 0, 0x5C, 0x7F, 0x6C, | ||
261 | 900, 3400, 25000, 0x65, ricoh583_ops, 500), | ||
262 | RICOH583_REG(LDO9, 0x50, 1, 0x52, 1, 0x5D, 0x7F, 0x6D, | ||
263 | 900, 3400, 25000, 0x65, ricoh583_ops, 500), | ||
264 | }; | ||
265 | static inline struct ricoh583_regulator *find_regulator_info(int id) | ||
266 | { | ||
267 | struct ricoh583_regulator *ri; | ||
268 | int i; | ||
269 | |||
270 | for (i = 0; i < ARRAY_SIZE(ricoh583_regulator); i++) { | ||
271 | ri = &ricoh583_regulator[i]; | ||
272 | if (ri->desc.id == id) | ||
273 | return ri; | ||
274 | } | ||
275 | return NULL; | ||
276 | } | ||
277 | |||
278 | static int ricoh583_regulator_preinit(struct device *parent, | ||
279 | struct ricoh583_regulator *ri, | ||
280 | struct ricoh583_regulator_platform_data *ricoh583_pdata) | ||
281 | { | ||
282 | int ret = 0; | ||
283 | |||
284 | if (ri->deepsleep_id != RICOH583_DS_NONE) { | ||
285 | ret = ricoh583_ext_power_req_config(parent, ri->deepsleep_id, | ||
286 | ricoh583_pdata->ext_pwr_req, | ||
287 | ricoh583_pdata->deepsleep_slots); | ||
288 | if (ret < 0) | ||
289 | return ret; | ||
290 | } | ||
291 | |||
292 | if (!ricoh583_pdata->init_apply) | ||
293 | return 0; | ||
294 | |||
295 | if (ricoh583_pdata->deepsleep_uV) { | ||
296 | ret = __ricoh583_set_ds_voltage(parent, ri, | ||
297 | ricoh583_pdata->deepsleep_uV, | ||
298 | ricoh583_pdata->deepsleep_uV); | ||
299 | if (ret < 0) { | ||
300 | dev_err(ri->dev, "Not able to initialize ds voltage %d" | ||
301 | " for rail %d err %d\n", | ||
302 | ricoh583_pdata->deepsleep_uV, ri->desc.id, ret); | ||
303 | return ret; | ||
304 | } | ||
305 | } | ||
306 | |||
307 | if (ricoh583_pdata->init_uV >= 0) { | ||
308 | ret = __ricoh583_set_voltage(parent, ri, | ||
309 | ricoh583_pdata->init_uV, | ||
310 | ricoh583_pdata->init_uV, 0); | ||
311 | if (ret < 0) { | ||
312 | dev_err(ri->dev, "Not able to initialize voltage %d " | ||
313 | "for rail %d err %d\n", ricoh583_pdata->init_uV, | ||
314 | ri->desc.id, ret); | ||
315 | return ret; | ||
316 | } | ||
317 | } | ||
318 | |||
319 | if (ricoh583_pdata->init_enable) | ||
320 | ret = ricoh583_set_bits(parent, ri->reg_en_reg, | ||
321 | (1 << ri->en_bit)); | ||
322 | else | ||
323 | ret = ricoh583_clr_bits(parent, ri->reg_en_reg, | ||
324 | (1 << ri->en_bit)); | ||
325 | if (ret < 0) | ||
326 | dev_err(ri->dev, "Not able to %s rail %d err %d\n", | ||
327 | (ricoh583_pdata->init_enable) ? "enable" : "disable", | ||
328 | ri->desc.id, ret); | ||
329 | |||
330 | return ret; | ||
331 | } | ||
332 | |||
333 | static inline int ricoh583_cache_regulator_register(struct device *parent, | ||
334 | struct ricoh583_regulator *ri) | ||
335 | { | ||
336 | ri->vout_reg_cache = 0; | ||
337 | return ricoh583_read(parent, ri->vout_reg, &ri->vout_reg_cache); | ||
338 | } | ||
339 | |||
340 | static int __devinit ricoh583_regulator_probe(struct platform_device *pdev) | ||
341 | { | ||
342 | struct ricoh583_regulator *ri = NULL; | ||
343 | struct regulator_dev *rdev; | ||
344 | struct ricoh583_regulator_platform_data *tps_pdata; | ||
345 | int id = pdev->id; | ||
346 | int err; | ||
347 | |||
348 | dev_dbg(&pdev->dev, "Probing reulator %d\n", id); | ||
349 | |||
350 | ri = find_regulator_info(id); | ||
351 | if (ri == NULL) { | ||
352 | dev_err(&pdev->dev, "invalid regulator ID specified\n"); | ||
353 | return -EINVAL; | ||
354 | } | ||
355 | tps_pdata = pdev->dev.platform_data; | ||
356 | ri->dev = &pdev->dev; | ||
357 | |||
358 | err = ricoh583_cache_regulator_register(pdev->dev.parent, ri); | ||
359 | if (err) { | ||
360 | dev_err(&pdev->dev, "Fail in caching register\n"); | ||
361 | return err; | ||
362 | } | ||
363 | |||
364 | err = ricoh583_regulator_preinit(pdev->dev.parent, ri, tps_pdata); | ||
365 | if (err) { | ||
366 | dev_err(&pdev->dev, "Fail in pre-initialisation\n"); | ||
367 | return err; | ||
368 | } | ||
369 | rdev = regulator_register(&ri->desc, &pdev->dev, | ||
370 | &tps_pdata->regulator, ri); | ||
371 | if (IS_ERR_OR_NULL(rdev)) { | ||
372 | dev_err(&pdev->dev, "failed to register regulator %s\n", | ||
373 | ri->desc.name); | ||
374 | return PTR_ERR(rdev); | ||
375 | } | ||
376 | |||
377 | platform_set_drvdata(pdev, rdev); | ||
378 | return 0; | ||
379 | } | ||
380 | |||
381 | static int __devexit ricoh583_regulator_remove(struct platform_device *pdev) | ||
382 | { | ||
383 | struct regulator_dev *rdev = platform_get_drvdata(pdev); | ||
384 | |||
385 | regulator_unregister(rdev); | ||
386 | return 0; | ||
387 | } | ||
388 | |||
389 | static struct platform_driver ricoh583_regulator_driver = { | ||
390 | .driver = { | ||
391 | .name = "ricoh583-regulator", | ||
392 | .owner = THIS_MODULE, | ||
393 | }, | ||
394 | .probe = ricoh583_regulator_probe, | ||
395 | .remove = __devexit_p(ricoh583_regulator_remove), | ||
396 | }; | ||
397 | |||
398 | static int __init ricoh583_regulator_init(void) | ||
399 | { | ||
400 | return platform_driver_register(&ricoh583_regulator_driver); | ||
401 | } | ||
402 | subsys_initcall(ricoh583_regulator_init); | ||
403 | |||
404 | static void __exit ricoh583_regulator_exit(void) | ||
405 | { | ||
406 | platform_driver_unregister(&ricoh583_regulator_driver); | ||
407 | } | ||
408 | module_exit(ricoh583_regulator_exit); | ||
409 | |||
410 | MODULE_DESCRIPTION("RICOH583 regulator driver"); | ||
411 | MODULE_ALIAS("platform:ricoh583-regulator"); | ||
412 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/regulator/tps6591x-regulator.c b/drivers/regulator/tps6591x-regulator.c new file mode 100644 index 00000000000..5336f3d8257 --- /dev/null +++ b/drivers/regulator/tps6591x-regulator.c | |||
@@ -0,0 +1,955 @@ | |||
1 | /* | ||
2 | * driver/regulator/tps6591x-regulator.c | ||
3 | * | ||
4 | * Regulator driver for TI TPS6591x PMIC family | ||
5 | * | ||
6 | * Copyright (C) 2011 NVIDIA Corporation | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
15 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
16 | * more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License along | ||
19 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
20 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/delay.h> | ||
26 | #include <linux/init.h> | ||
27 | #include <linux/err.h> | ||
28 | #include <linux/slab.h> | ||
29 | #include <linux/platform_device.h> | ||
30 | #include <linux/regulator/driver.h> | ||
31 | #include <linux/regulator/machine.h> | ||
32 | #include <linux/regulator/tps6591x-regulator.h> | ||
33 | #include <linux/mfd/tps6591x.h> | ||
34 | |||
35 | /* supply control and voltage setting */ | ||
36 | #define TPS6591X_VIO_ADD 0x20 | ||
37 | #define TPS6591X_VDD1_ADD 0x21 | ||
38 | #define TPS6591X_VDD1_OP_ADD 0x22 | ||
39 | #define TPS6591X_VDD1_SR_ADD 0x23 | ||
40 | #define TPS6591X_VDD2_ADD 0x24 | ||
41 | #define TPS6591X_VDD2_OP_ADD 0x25 | ||
42 | #define TPS6591X_VDD2_SR_ADD 0x26 | ||
43 | #define TPS6591X_VDDCTRL_ADD 0x27 | ||
44 | #define TPS6591X_VDDCTRL_OP_ADD 0x28 | ||
45 | #define TPS6591X_VDDCTRL_SR_ADD 0x29 | ||
46 | #define TPS6591X_LDO1_ADD 0x30 | ||
47 | #define TPS6591X_LDO2_ADD 0x31 | ||
48 | #define TPS6591X_LDO3_ADD 0x37 | ||
49 | #define TPS6591X_LDO4_ADD 0x36 | ||
50 | #define TPS6591X_LDO5_ADD 0x32 | ||
51 | #define TPS6591X_LDO6_ADD 0x35 | ||
52 | #define TPS6591X_LDO7_ADD 0x34 | ||
53 | #define TPS6591X_LDO8_ADD 0x33 | ||
54 | #define TPS6591X_SLEEP_SET_LDO_OFF_ADD 0x43 | ||
55 | #define TPS6591X_SLEEP_SET_RES_OFF_ADD 0x44 | ||
56 | #define TPS6591X_EN1_LDO_ADD 0x45 | ||
57 | #define TPS6591X_EN1_SMPS_ADD 0x46 | ||
58 | #define TPS6591X_EN2_LDO_ADD 0x47 | ||
59 | #define TPS6591X_EN2_SMPS_ADD 0x48 | ||
60 | #define TPS6591X_INVALID_ADD 0xFF | ||
61 | |||
62 | #define EN1_EN2_OFFSET 2 | ||
63 | |||
64 | struct tps6591x_register_info { | ||
65 | unsigned char addr; | ||
66 | unsigned char nbits; | ||
67 | unsigned char shift_bits; | ||
68 | uint8_t cache_val; | ||
69 | }; | ||
70 | |||
71 | enum { | ||
72 | supply_type_none = 0x0, | ||
73 | supply_type_single_reg, | ||
74 | supply_type_sr_op_reg | ||
75 | }; | ||
76 | |||
77 | struct tps6591x_regulator { | ||
78 | struct regulator_desc desc; | ||
79 | int supply_type; | ||
80 | |||
81 | struct tps6591x_register_info supply_reg; | ||
82 | struct tps6591x_register_info op_reg; | ||
83 | struct tps6591x_register_info sr_reg; | ||
84 | struct tps6591x_register_info en1_reg; | ||
85 | struct tps6591x_register_info slp_off_reg; | ||
86 | |||
87 | int *voltages; | ||
88 | |||
89 | int enable_delay; /* delay in us for regulator to stabilize */ | ||
90 | enum tps6591x_ext_control ectrl; | ||
91 | int current_volt_uv; | ||
92 | |||
93 | /* Time (micro sec) taken for 1uV change */ | ||
94 | int voltage_change_uv_per_us; | ||
95 | unsigned int config_flags; | ||
96 | }; | ||
97 | |||
98 | static inline struct device *to_tps6591x_dev(struct regulator_dev *rdev) | ||
99 | { | ||
100 | return rdev_get_dev(rdev)->parent->parent; | ||
101 | } | ||
102 | |||
103 | static int tps6591x_regulator_enable_time(struct regulator_dev *rdev) | ||
104 | { | ||
105 | struct tps6591x_regulator *ri = rdev_get_drvdata(rdev); | ||
106 | |||
107 | return ri->enable_delay; | ||
108 | } | ||
109 | |||
110 | static int __tps6591x_ext_control_set(struct device *parent, | ||
111 | struct tps6591x_regulator *ri, | ||
112 | enum tps6591x_ext_control ectrl) | ||
113 | { | ||
114 | int ret; | ||
115 | uint8_t mask, reg_val, addr, offset; | ||
116 | struct tps6591x_register_info *ext_reg; | ||
117 | |||
118 | /* For regulator that has separate operational and sleep register make | ||
119 | sure that operational is used and clear sleep register to turn | ||
120 | regulator off when external control is inactive */ | ||
121 | if (ri->supply_type == supply_type_sr_op_reg) { | ||
122 | reg_val = ri->op_reg.cache_val; | ||
123 | if (reg_val & 0x80) { /* boot has used sr - switch to op */ | ||
124 | reg_val = ri->sr_reg.cache_val; | ||
125 | mask = ((1 << ri->sr_reg.nbits) - 1) | ||
126 | << ri->sr_reg.shift_bits; | ||
127 | reg_val &= mask; | ||
128 | ret = tps6591x_write(parent, ri->op_reg.addr, reg_val); | ||
129 | if (ret) | ||
130 | return ret; | ||
131 | ri->op_reg.cache_val = reg_val; | ||
132 | } | ||
133 | ret = tps6591x_write(parent, ri->sr_reg.addr, 0); | ||
134 | if (ret) | ||
135 | return ret; | ||
136 | ri->sr_reg.cache_val = 0; | ||
137 | } | ||
138 | |||
139 | offset = 0; | ||
140 | switch (ectrl) { | ||
141 | case EXT_CTRL_EN2: | ||
142 | offset = EN1_EN2_OFFSET; | ||
143 | /* fall through to EXT_CTRL_EN1 */ | ||
144 | case EXT_CTRL_EN1: | ||
145 | ext_reg = &(ri->en1_reg); | ||
146 | break; | ||
147 | case EXT_CTRL_SLEEP_OFF: | ||
148 | ext_reg = &(ri->slp_off_reg); | ||
149 | break; | ||
150 | default: | ||
151 | return -EINVAL; | ||
152 | } | ||
153 | |||
154 | addr = ext_reg->addr + offset; | ||
155 | mask = ((1 << ext_reg->nbits) - 1) << ext_reg->shift_bits; | ||
156 | |||
157 | return tps6591x_update(parent, addr, mask, mask); | ||
158 | } | ||
159 | |||
160 | static void wait_for_voltage_change(struct tps6591x_regulator *ri, int uV) | ||
161 | { | ||
162 | int change_uv; | ||
163 | int change_us; | ||
164 | |||
165 | change_uv = abs(uV - ri->current_volt_uv); | ||
166 | change_us = change_uv/ri->voltage_change_uv_per_us + 1; | ||
167 | if (change_us >= 1000) { | ||
168 | mdelay(change_us/1000); | ||
169 | change_us -= (change_us/1000); | ||
170 | } | ||
171 | if (change_us) | ||
172 | udelay(change_us); | ||
173 | ri->current_volt_uv = uV; | ||
174 | } | ||
175 | |||
176 | static int __tps6591x_vio_set_voltage(struct device *parent, | ||
177 | struct tps6591x_regulator *ri, | ||
178 | int min_uV, int max_uV, | ||
179 | unsigned *selector) | ||
180 | { | ||
181 | int uV; | ||
182 | uint8_t mask; | ||
183 | uint8_t val; | ||
184 | int ret; | ||
185 | uint8_t reg_val; | ||
186 | |||
187 | for (val = 0; val < ri->desc.n_voltages; val++) { | ||
188 | uV = ri->voltages[val] * 1000; | ||
189 | |||
190 | /* use the first in-range value */ | ||
191 | if (min_uV <= uV && uV <= max_uV) { | ||
192 | if (selector) | ||
193 | *selector = val; | ||
194 | |||
195 | reg_val = ri->supply_reg.cache_val; | ||
196 | val <<= ri->supply_reg.shift_bits; | ||
197 | |||
198 | mask = ((1 << ri->supply_reg.nbits) - 1) << | ||
199 | ri->supply_reg.shift_bits; | ||
200 | reg_val = (reg_val & ~mask) | (val & mask); | ||
201 | |||
202 | ret = tps6591x_write(parent, ri->supply_reg.addr, | ||
203 | reg_val); | ||
204 | if (ret >= 0) { | ||
205 | wait_for_voltage_change(ri, uV); | ||
206 | ri->supply_reg.cache_val = reg_val; | ||
207 | } | ||
208 | return ret; | ||
209 | } | ||
210 | } | ||
211 | |||
212 | return -EINVAL; | ||
213 | } | ||
214 | |||
215 | static int tps6591x_vio_set_voltage(struct regulator_dev *rdev, | ||
216 | int min_uV, int max_uV, | ||
217 | unsigned *selector) | ||
218 | { | ||
219 | struct tps6591x_regulator *ri = rdev_get_drvdata(rdev); | ||
220 | struct device *parent = to_tps6591x_dev(rdev); | ||
221 | |||
222 | return __tps6591x_vio_set_voltage(parent, ri, min_uV, max_uV, | ||
223 | selector); | ||
224 | } | ||
225 | |||
226 | static int tps6591x_vio_get_voltage(struct regulator_dev *rdev) | ||
227 | { | ||
228 | struct tps6591x_regulator *ri = rdev_get_drvdata(rdev); | ||
229 | uint8_t val, mask; | ||
230 | |||
231 | val = ri->supply_reg.cache_val; | ||
232 | |||
233 | mask = ((1 << ri->supply_reg.nbits) - 1) << ri->supply_reg.shift_bits; | ||
234 | val = (val & mask) >> ri->supply_reg.shift_bits; | ||
235 | |||
236 | if (val >= ri->desc.n_voltages) | ||
237 | BUG(); | ||
238 | |||
239 | return ri->voltages[val] * 1000; | ||
240 | } | ||
241 | |||
242 | |||
243 | static int tps6591x_ldo_list_voltage(struct regulator_dev *rdev, | ||
244 | unsigned selector) | ||
245 | { | ||
246 | struct tps6591x_regulator *info = rdev_get_drvdata(rdev); | ||
247 | |||
248 | return info->voltages[selector] * 1000; | ||
249 | } | ||
250 | |||
251 | static int __tps6591x_ldo1_set_voltage(struct device *parent, | ||
252 | struct tps6591x_regulator *ri, | ||
253 | int min_uV, int max_uV, | ||
254 | unsigned *selector) | ||
255 | { | ||
256 | int val, uV; | ||
257 | uint8_t mask; | ||
258 | uint8_t reg_val; | ||
259 | int ret; | ||
260 | |||
261 | for (val = 0; val < ri->desc.n_voltages; val++) { | ||
262 | uV = ri->voltages[val] * 1000; | ||
263 | |||
264 | /* use the first in-range value */ | ||
265 | if (min_uV <= uV && uV <= max_uV) { | ||
266 | if (selector) | ||
267 | *selector = val; | ||
268 | reg_val = ri->supply_reg.cache_val; | ||
269 | val += 4; | ||
270 | val <<= ri->supply_reg.shift_bits; | ||
271 | mask = ((1 << ri->supply_reg.nbits) - 1) << | ||
272 | ri->supply_reg.shift_bits; | ||
273 | |||
274 | reg_val = (reg_val & ~mask) | (val & mask); | ||
275 | ret = tps6591x_write(parent, ri->supply_reg.addr, | ||
276 | reg_val); | ||
277 | if (ret >= 0) { | ||
278 | wait_for_voltage_change(ri, uV); | ||
279 | ri->supply_reg.cache_val = reg_val; | ||
280 | } | ||
281 | return ret; | ||
282 | } | ||
283 | } | ||
284 | |||
285 | return -EINVAL; | ||
286 | } | ||
287 | |||
288 | static int tps6591x_ldo1_set_voltage(struct regulator_dev *rdev, | ||
289 | int min_uV, int max_uV, | ||
290 | unsigned *selector) | ||
291 | { | ||
292 | struct tps6591x_regulator *ri = rdev_get_drvdata(rdev); | ||
293 | struct device *parent = to_tps6591x_dev(rdev); | ||
294 | |||
295 | return __tps6591x_ldo1_set_voltage(parent, ri, min_uV, max_uV, | ||
296 | selector); | ||
297 | } | ||
298 | |||
299 | static int tps6591x_ldo1_get_voltage(struct regulator_dev *rdev) | ||
300 | { | ||
301 | struct tps6591x_regulator *ri = rdev_get_drvdata(rdev); | ||
302 | uint8_t val, mask; | ||
303 | |||
304 | val = ri->supply_reg.cache_val; | ||
305 | mask = ((1 << ri->supply_reg.nbits) - 1) << ri->supply_reg.shift_bits; | ||
306 | val = (val & mask) >> ri->supply_reg.shift_bits; | ||
307 | |||
308 | if (val < 4) | ||
309 | return 1000 * 1000; | ||
310 | else if (val > 0x32) | ||
311 | return 3300 * 1000; | ||
312 | else | ||
313 | val -= 4; | ||
314 | if (val >= ri->desc.n_voltages) | ||
315 | BUG(); | ||
316 | |||
317 | return ri->voltages[val] * 1000; | ||
318 | } | ||
319 | |||
320 | static int __tps6591x_ldo3_set_voltage(struct device *parent, | ||
321 | struct tps6591x_regulator *ri, | ||
322 | int min_uV, int max_uV, | ||
323 | unsigned *selector) | ||
324 | { | ||
325 | int val, uV; | ||
326 | uint8_t mask; | ||
327 | int ret; | ||
328 | uint8_t reg_val; | ||
329 | |||
330 | for (val = 0; val < ri->desc.n_voltages; val++) { | ||
331 | uV = ri->voltages[val] * 1000; | ||
332 | |||
333 | /* use the first in-range value */ | ||
334 | if (min_uV <= uV && uV <= max_uV) { | ||
335 | if (selector) | ||
336 | *selector = val; | ||
337 | reg_val = ri->supply_reg.cache_val; | ||
338 | val += 2; | ||
339 | val <<= ri->supply_reg.shift_bits; | ||
340 | mask = ((1 << ri->supply_reg.nbits) - 1) << | ||
341 | ri->supply_reg.shift_bits; | ||
342 | |||
343 | reg_val = (reg_val & ~mask) | (val & mask); | ||
344 | |||
345 | ret = tps6591x_write(parent, ri->supply_reg.addr, | ||
346 | reg_val); | ||
347 | if (ret >= 0) { | ||
348 | wait_for_voltage_change(ri, uV); | ||
349 | ri->supply_reg.cache_val = reg_val; | ||
350 | } | ||
351 | return ret; | ||
352 | } | ||
353 | } | ||
354 | |||
355 | return -EINVAL; | ||
356 | } | ||
357 | |||
358 | static int tps6591x_ldo3_set_voltage(struct regulator_dev *rdev, | ||
359 | int min_uV, int max_uV, | ||
360 | unsigned *selector) | ||
361 | { | ||
362 | struct tps6591x_regulator *ri = rdev_get_drvdata(rdev); | ||
363 | struct device *parent = to_tps6591x_dev(rdev); | ||
364 | |||
365 | return __tps6591x_ldo3_set_voltage(parent, ri, min_uV, max_uV, | ||
366 | selector); | ||
367 | } | ||
368 | |||
369 | static int tps6591x_ldo3_get_voltage(struct regulator_dev *rdev) | ||
370 | { | ||
371 | struct tps6591x_regulator *ri = rdev_get_drvdata(rdev); | ||
372 | uint8_t val, mask; | ||
373 | |||
374 | val = ri->supply_reg.cache_val; | ||
375 | mask = ((1 << ri->supply_reg.nbits) - 1) << ri->supply_reg.shift_bits; | ||
376 | val = (val & mask) >> ri->supply_reg.shift_bits; | ||
377 | |||
378 | if (val < 2) | ||
379 | return 1000 * 1000; | ||
380 | else if (val > 0x19) | ||
381 | return 3300 * 1000; | ||
382 | else | ||
383 | val -= 2; | ||
384 | if (val >= ri->desc.n_voltages) | ||
385 | BUG(); | ||
386 | |||
387 | return ri->voltages[val] * 1000; | ||
388 | } | ||
389 | |||
390 | static int __tps6591x_vdd_set_voltage(struct device *parent, | ||
391 | struct tps6591x_regulator *ri, | ||
392 | int min_uV, int max_uV, | ||
393 | unsigned *selector) | ||
394 | { | ||
395 | int val, uV, ret; | ||
396 | uint8_t mask; | ||
397 | uint8_t op_reg_val; | ||
398 | uint8_t sr_reg_val; | ||
399 | |||
400 | for (val = 0; val < ri->desc.n_voltages; val++) { | ||
401 | uV = ri->voltages[val] * 1000; | ||
402 | |||
403 | /* use the first in-range value */ | ||
404 | if (min_uV <= uV && uV <= max_uV) { | ||
405 | if (selector) | ||
406 | *selector = val; | ||
407 | op_reg_val = ri->op_reg.cache_val; | ||
408 | val += 3; | ||
409 | if (op_reg_val & 0x80) { | ||
410 | sr_reg_val = ri->sr_reg.cache_val; | ||
411 | val <<= ri->sr_reg.shift_bits; | ||
412 | mask = ((1 << ri->sr_reg.nbits) - 1) | ||
413 | << ri->sr_reg.shift_bits; | ||
414 | sr_reg_val = (sr_reg_val & ~mask) | | ||
415 | (val & mask); | ||
416 | ret = tps6591x_write(parent, | ||
417 | ri->sr_reg.addr, sr_reg_val); | ||
418 | if (!ret) | ||
419 | ri->sr_reg.cache_val = sr_reg_val; | ||
420 | } else { | ||
421 | val <<= ri->op_reg.shift_bits; | ||
422 | mask = ((1 << ri->op_reg.nbits) - 1) | ||
423 | << ri->op_reg.shift_bits; | ||
424 | op_reg_val = (op_reg_val & ~mask) | | ||
425 | (val & mask); | ||
426 | ret = tps6591x_write(parent, | ||
427 | ri->op_reg.addr, op_reg_val); | ||
428 | if (!ret) | ||
429 | ri->op_reg.cache_val = op_reg_val; | ||
430 | } | ||
431 | if (ret >= 0) | ||
432 | wait_for_voltage_change(ri, uV); | ||
433 | return ret; | ||
434 | } | ||
435 | } | ||
436 | |||
437 | return -EINVAL; | ||
438 | } | ||
439 | |||
440 | static int tps6591x_vdd_set_voltage(struct regulator_dev *rdev, | ||
441 | int min_uV, int max_uV, | ||
442 | unsigned *selector) | ||
443 | { | ||
444 | struct tps6591x_regulator *ri = rdev_get_drvdata(rdev); | ||
445 | struct device *parent = to_tps6591x_dev(rdev); | ||
446 | |||
447 | return __tps6591x_vdd_set_voltage(parent, ri, min_uV, max_uV, | ||
448 | selector); | ||
449 | } | ||
450 | |||
451 | static int tps6591x_vdd_get_voltage(struct regulator_dev *rdev) | ||
452 | { | ||
453 | struct tps6591x_regulator *ri = rdev_get_drvdata(rdev); | ||
454 | uint8_t op_val, sr_val, val; | ||
455 | |||
456 | op_val = ri->op_reg.cache_val; | ||
457 | sr_val = ri->sr_reg.cache_val; | ||
458 | |||
459 | val = (op_val & 0x80) ? (sr_val & 0x7F) : (op_val & 0x7F); | ||
460 | |||
461 | if (!val) | ||
462 | return 0; | ||
463 | else if (val < 0x3) | ||
464 | return 600 * 1000; | ||
465 | else if (val > 0x4B) | ||
466 | return 1500 * 1000; | ||
467 | else | ||
468 | val -= 3; | ||
469 | |||
470 | if (val >= ri->desc.n_voltages) | ||
471 | BUG(); | ||
472 | |||
473 | return ri->voltages[val] * 1000; | ||
474 | } | ||
475 | |||
476 | static int tps6591x_regulator_enable(struct regulator_dev *rdev) | ||
477 | { | ||
478 | struct tps6591x_regulator *ri = rdev_get_drvdata(rdev); | ||
479 | struct device *parent = to_tps6591x_dev(rdev); | ||
480 | uint8_t reg_val; | ||
481 | int ret; | ||
482 | |||
483 | reg_val = ri->supply_reg.cache_val; | ||
484 | reg_val |= 0x1; | ||
485 | |||
486 | ret = tps6591x_write(parent, ri->supply_reg.addr, reg_val); | ||
487 | if (!ret) | ||
488 | ri->supply_reg.cache_val = reg_val; | ||
489 | return ret; | ||
490 | } | ||
491 | |||
492 | static int tps6591x_regulator_disable(struct regulator_dev *rdev) | ||
493 | { | ||
494 | struct tps6591x_regulator *ri = rdev_get_drvdata(rdev); | ||
495 | struct device *parent = to_tps6591x_dev(rdev); | ||
496 | uint8_t reg_val; | ||
497 | int ret; | ||
498 | |||
499 | reg_val = ri->supply_reg.cache_val; | ||
500 | reg_val &= ~0x1; | ||
501 | ret = tps6591x_write(parent, ri->supply_reg.addr, reg_val); | ||
502 | if (!ret) | ||
503 | ri->supply_reg.cache_val = reg_val; | ||
504 | return ret; | ||
505 | } | ||
506 | |||
507 | static int tps6591x_regulator_is_enabled(struct regulator_dev *rdev) | ||
508 | { | ||
509 | struct tps6591x_regulator *ri = rdev_get_drvdata(rdev); | ||
510 | uint8_t reg_val; | ||
511 | |||
512 | reg_val = ri->supply_reg.cache_val; | ||
513 | reg_val &= 0x1; | ||
514 | return reg_val & 0x1; | ||
515 | } | ||
516 | |||
517 | static struct regulator_ops tps6591x_regulator_vio_ops = { | ||
518 | .list_voltage = tps6591x_ldo_list_voltage, | ||
519 | .get_voltage = tps6591x_vio_get_voltage, | ||
520 | .set_voltage = tps6591x_vio_set_voltage, | ||
521 | |||
522 | .enable_time = tps6591x_regulator_enable_time, | ||
523 | .is_enabled = tps6591x_regulator_is_enabled, | ||
524 | .enable = tps6591x_regulator_enable, | ||
525 | .disable = tps6591x_regulator_disable, | ||
526 | }; | ||
527 | |||
528 | static struct regulator_ops tps6591x_regulator_ldo1_ops = { | ||
529 | .list_voltage = tps6591x_ldo_list_voltage, | ||
530 | .get_voltage = tps6591x_ldo1_get_voltage, | ||
531 | .set_voltage = tps6591x_ldo1_set_voltage, | ||
532 | |||
533 | .enable_time = tps6591x_regulator_enable_time, | ||
534 | .is_enabled = tps6591x_regulator_is_enabled, | ||
535 | .enable = tps6591x_regulator_enable, | ||
536 | .disable = tps6591x_regulator_disable, | ||
537 | }; | ||
538 | |||
539 | static struct regulator_ops tps6591x_regulator_ldo3_ops = { | ||
540 | .list_voltage = tps6591x_ldo_list_voltage, | ||
541 | .get_voltage = tps6591x_ldo3_get_voltage, | ||
542 | .set_voltage = tps6591x_ldo3_set_voltage, | ||
543 | |||
544 | .enable_time = tps6591x_regulator_enable_time, | ||
545 | .is_enabled = tps6591x_regulator_is_enabled, | ||
546 | .enable = tps6591x_regulator_enable, | ||
547 | .disable = tps6591x_regulator_disable, | ||
548 | }; | ||
549 | |||
550 | static struct regulator_ops tps6591x_regulator_vdd_ops = { | ||
551 | .list_voltage = tps6591x_ldo_list_voltage, | ||
552 | .get_voltage = tps6591x_vdd_get_voltage, | ||
553 | .set_voltage = tps6591x_vdd_set_voltage, | ||
554 | |||
555 | .enable_time = tps6591x_regulator_enable_time, | ||
556 | .is_enabled = tps6591x_regulator_is_enabled, | ||
557 | .enable = tps6591x_regulator_enable, | ||
558 | .disable = tps6591x_regulator_disable, | ||
559 | }; | ||
560 | |||
561 | static int tps6591x_vio_voltages[] = { | ||
562 | 1500, 1800, 2500, 3300, | ||
563 | }; | ||
564 | |||
565 | /* SEL[7:2]=000100:1000mV --> 110010:3300mV */ | ||
566 | static int tps6591x_ldo124_voltages[] = { | ||
567 | 1000, 1050, 1100, 1150, 1200, 1250, 1300, 1350, 1400, 1450, | ||
568 | 1500, 1550, 1600, 1650, 1700, 1750, 1800, 1850, 1900, 1950, | ||
569 | 2000, 2050, 2100, 2150, 2200, 2250, 2300, 2350, 2400, 2450, | ||
570 | 2500, 2550, 2600, 2650, 2700, 2750, 2800, 2850, 2900, 2950, | ||
571 | 3000, 3050, 3100, 3150, 3200, 3250, 3300, | ||
572 | }; | ||
573 | |||
574 | /* SEL[6:2]=00010:1000mv --> 11001:3300mV */ | ||
575 | static int tps6591x_ldo35678_voltages[] = { | ||
576 | 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800, 1900, | ||
577 | 2000, 2100, 2200, 2300, 2400, 2500, 2600, 2700, 2800, 2900, | ||
578 | 3000, 3100, 3200, 3300, | ||
579 | }; | ||
580 | |||
581 | static int tps6591x_vdd_voltages[] = { | ||
582 | 600, 612, 625, 637, 650, 662, 675, 687, 700, 712, 725, 737, | ||
583 | 750, 762, 775, 787, 800, 812, 825, 837, 850, 862, 875, 887, | ||
584 | 900, 912, 925, 937, 950, 962, 975, 987, 1000, 1012, 1025, | ||
585 | 1037, 1050, 1062, 1075, 1087, 1100, 1112, 1125, 1137, 1150, | ||
586 | 1162, 1175, 1187, 1200, 1212, 1225, 1237, 1250, 1262, 1275, | ||
587 | 1287, 1300, 1312, 1325, 1337, 1350, 1362, 1375, 1387, 1400, | ||
588 | 1412, 1425, 1437, 1450, 1462, 1475, 1487, 1500, | ||
589 | }; | ||
590 | |||
591 | static int tps6591x_vddctrl_voltages[] = { | ||
592 | 600, 612, 625, 637, 650, 662, 675, 687, 700, 712, 725, 737, | ||
593 | 750, 762, 775, 787, 800, 812, 825, 837, 850, 862, 875, 887, | ||
594 | 900, 912, 925, 937, 950, 962, 975, 987, 1000, 1012, 1025, | ||
595 | 1037, 1050, 1062, 1075, 1087, 1100, 1112, 1125, 1137, 1150, | ||
596 | 1162, 1175, 1187, 1200, 1212, 1225, 1237, 1250, 1262, 1275, | ||
597 | 1287, 1300, 1312, 1325, 1337, 1350, 1362, 1375, 1387, 1400, | ||
598 | }; | ||
599 | |||
600 | #define TPS6591X_REGULATOR(_id, vdata, _ops, s_addr, s_nbits, s_shift, \ | ||
601 | s_type, op_addr, op_nbits, op_shift, sr_addr, \ | ||
602 | sr_nbits, sr_shift, en1_addr, en1_shift, \ | ||
603 | slp_off_addr, slp_off_shift, en_time, \ | ||
604 | change_rate) \ | ||
605 | .desc = { \ | ||
606 | .name = tps6591x_rails(_id), \ | ||
607 | .ops = &tps6591x_regulator_##_ops, \ | ||
608 | .type = REGULATOR_VOLTAGE, \ | ||
609 | .id = TPS6591X_ID_##_id, \ | ||
610 | .n_voltages = ARRAY_SIZE(tps6591x_##vdata##_voltages), \ | ||
611 | .owner = THIS_MODULE, \ | ||
612 | }, \ | ||
613 | .supply_type = supply_type_##s_type, \ | ||
614 | .supply_reg = { \ | ||
615 | .addr = TPS6591X_##s_addr##_ADD, \ | ||
616 | .nbits = s_nbits, \ | ||
617 | .shift_bits = s_shift, \ | ||
618 | }, \ | ||
619 | .op_reg = { \ | ||
620 | .addr = TPS6591X_##op_addr##_ADD, \ | ||
621 | .nbits = op_nbits, \ | ||
622 | .shift_bits = op_shift, \ | ||
623 | }, \ | ||
624 | .sr_reg = { \ | ||
625 | .addr = TPS6591X_##sr_addr##_ADD, \ | ||
626 | .nbits = sr_nbits, \ | ||
627 | .shift_bits = sr_shift, \ | ||
628 | }, \ | ||
629 | .en1_reg = { \ | ||
630 | .addr = TPS6591X_##en1_addr##_ADD, \ | ||
631 | .nbits = 1, \ | ||
632 | .shift_bits = en1_shift, \ | ||
633 | }, \ | ||
634 | .slp_off_reg = { \ | ||
635 | .addr = TPS6591X_SLEEP_SET_##slp_off_addr##_ADD, \ | ||
636 | .nbits = 1, \ | ||
637 | .shift_bits = slp_off_shift, \ | ||
638 | }, \ | ||
639 | .voltages = tps6591x_##vdata##_voltages, \ | ||
640 | .enable_delay = en_time, \ | ||
641 | .voltage_change_uv_per_us = change_rate, | ||
642 | |||
643 | #define TPS6591X_VIO(_id, vdata, s_addr, s_nbits, s_shift, s_type, \ | ||
644 | en1_shift, slp_off_shift, en_time) \ | ||
645 | { \ | ||
646 | TPS6591X_REGULATOR(_id, vdata, vio_ops, s_addr, s_nbits, \ | ||
647 | s_shift, s_type, INVALID, 0, 0, INVALID, 0, 0, \ | ||
648 | EN1_SMPS, en1_shift, RES_OFF, slp_off_shift, \ | ||
649 | en_time, 10000) \ | ||
650 | } | ||
651 | |||
652 | #define TPS6591X_LDO1(_id, vdata, s_addr, s_nbits, s_shift, s_type, \ | ||
653 | en1_shift, slp_off_shift, en_time) \ | ||
654 | { \ | ||
655 | TPS6591X_REGULATOR(_id, vdata, ldo1_ops, s_addr, s_nbits, \ | ||
656 | s_shift, s_type, INVALID, 0, 0, INVALID, 0, 0, \ | ||
657 | EN1_LDO, en1_shift, LDO_OFF, slp_off_shift, \ | ||
658 | en_time, 6000) \ | ||
659 | } | ||
660 | |||
661 | #define TPS6591X_LDO3(_id, vdata, s_addr, s_nbits, s_shift, s_type, \ | ||
662 | en1_shift, slp_off_shift, en_time) \ | ||
663 | { \ | ||
664 | TPS6591X_REGULATOR(_id, vdata, ldo3_ops, s_addr, s_nbits, \ | ||
665 | s_shift, s_type, INVALID, 0, 0, INVALID, 0, 0, \ | ||
666 | EN1_LDO, en1_shift, LDO_OFF, slp_off_shift, \ | ||
667 | en_time, 11000) \ | ||
668 | } | ||
669 | |||
670 | #define TPS6591X_VDD(_id, vdata, s_addr, s_nbits, s_shift, s_type, \ | ||
671 | op_addr, op_nbits, op_shift, sr_addr, sr_nbits, \ | ||
672 | sr_shift, en1_shift, slp_off_shift, en_time) \ | ||
673 | { \ | ||
674 | TPS6591X_REGULATOR(_id, vdata, vdd_ops, s_addr, s_nbits, \ | ||
675 | s_shift, s_type, op_addr, op_nbits, op_shift, \ | ||
676 | sr_addr, sr_nbits, sr_shift, EN1_SMPS, \ | ||
677 | en1_shift, RES_OFF, slp_off_shift, en_time, \ | ||
678 | 5000) \ | ||
679 | } | ||
680 | |||
681 | static struct tps6591x_regulator tps6591x_regulator[] = { | ||
682 | TPS6591X_VIO(VIO, vio, VIO, 2, 2, single_reg, 0, 0, 350), | ||
683 | TPS6591X_LDO1(LDO_1, ldo124, LDO1, 6, 2, single_reg, 1, 1, 420), | ||
684 | TPS6591X_LDO1(LDO_2, ldo124, LDO2, 6, 2, single_reg, 2, 2, 420), | ||
685 | TPS6591X_LDO3(LDO_3, ldo35678, LDO3, 5, 2, single_reg, 7, 7, 230), | ||
686 | TPS6591X_LDO1(LDO_4, ldo124, LDO4, 6, 2, single_reg, 6, 6, 230), | ||
687 | TPS6591X_LDO3(LDO_5, ldo35678, LDO5, 5, 2, single_reg, 3, 3, 230), | ||
688 | TPS6591X_LDO3(LDO_6, ldo35678, LDO6, 5, 2, single_reg, 0, 0, 230), | ||
689 | TPS6591X_LDO3(LDO_7, ldo35678, LDO7, 5, 2, single_reg, 5, 5, 230), | ||
690 | TPS6591X_LDO3(LDO_8, ldo35678, LDO8, 5, 2, single_reg, 4, 4, 230), | ||
691 | TPS6591X_VDD(VDD_1, vdd, VDD1, 2, 0, sr_op_reg, VDD1_OP, | ||
692 | 7, 0, VDD1_SR, 7, 0, 1, 1, 350), | ||
693 | TPS6591X_VDD(VDD_2, vdd, VDD2, 2, 0, sr_op_reg, VDD2_OP, | ||
694 | 7, 0, VDD2_SR, 7, 0, 2, 2, 350), | ||
695 | TPS6591X_VDD(VDDCTRL, vddctrl, VDDCTRL, 2, 0, sr_op_reg, | ||
696 | VDDCTRL_OP, 7, 0, VDDCTRL_SR, 7, 0, 3, 3, 900), | ||
697 | }; | ||
698 | |||
699 | static inline int tps6591x_regulator_preinit(struct device *parent, | ||
700 | struct tps6591x_regulator *ri, | ||
701 | struct tps6591x_regulator_platform_data *tps6591x_pdata) | ||
702 | { | ||
703 | int ret; | ||
704 | uint8_t reg_val; | ||
705 | |||
706 | if (tps6591x_pdata->ectrl != EXT_CTRL_NONE) { | ||
707 | ret = __tps6591x_ext_control_set( | ||
708 | parent, ri, tps6591x_pdata->ectrl); | ||
709 | if (ret < 0) { | ||
710 | pr_err("Not able to configure external control %d" | ||
711 | " for rail %d err %d\n", tps6591x_pdata->ectrl, | ||
712 | ri->desc.id, ret); | ||
713 | return ret; | ||
714 | } | ||
715 | } | ||
716 | |||
717 | if (!tps6591x_pdata->init_apply) | ||
718 | return 0; | ||
719 | |||
720 | if (tps6591x_pdata->init_uV >= 0) { | ||
721 | switch (ri->desc.id) { | ||
722 | case TPS6591X_ID_VIO: | ||
723 | ret = __tps6591x_vio_set_voltage(parent, ri, | ||
724 | tps6591x_pdata->init_uV, | ||
725 | tps6591x_pdata->init_uV, 0); | ||
726 | break; | ||
727 | |||
728 | case TPS6591X_ID_LDO_1: | ||
729 | case TPS6591X_ID_LDO_2: | ||
730 | case TPS6591X_ID_LDO_4: | ||
731 | ret = __tps6591x_ldo1_set_voltage(parent, ri, | ||
732 | tps6591x_pdata->init_uV, | ||
733 | tps6591x_pdata->init_uV, 0); | ||
734 | break; | ||
735 | |||
736 | case TPS6591X_ID_LDO_3: | ||
737 | case TPS6591X_ID_LDO_5: | ||
738 | case TPS6591X_ID_LDO_6: | ||
739 | case TPS6591X_ID_LDO_7: | ||
740 | case TPS6591X_ID_LDO_8: | ||
741 | ret = __tps6591x_ldo3_set_voltage(parent, ri, | ||
742 | tps6591x_pdata->init_uV, | ||
743 | tps6591x_pdata->init_uV, 0); | ||
744 | break; | ||
745 | |||
746 | case TPS6591X_ID_VDD_1: | ||
747 | case TPS6591X_ID_VDD_2: | ||
748 | case TPS6591X_ID_VDDCTRL: | ||
749 | ret = __tps6591x_vdd_set_voltage(parent, ri, | ||
750 | tps6591x_pdata->init_uV, | ||
751 | tps6591x_pdata->init_uV, 0); | ||
752 | break; | ||
753 | |||
754 | default: | ||
755 | ret = -EINVAL; | ||
756 | break; | ||
757 | } | ||
758 | if (ret < 0) { | ||
759 | pr_err("Not able to initialize voltage %d for rail " | ||
760 | "%d err %d\n", tps6591x_pdata->init_uV, | ||
761 | ri->desc.id, ret); | ||
762 | return ret; | ||
763 | } | ||
764 | } | ||
765 | |||
766 | reg_val = ri->supply_reg.cache_val; | ||
767 | if (tps6591x_pdata->init_enable) | ||
768 | reg_val |= 0x1; | ||
769 | else | ||
770 | reg_val &= ~0x1; | ||
771 | ret = tps6591x_write(parent, ri->supply_reg.addr, reg_val); | ||
772 | |||
773 | if (ret < 0) | ||
774 | pr_err("Not able to %s rail %d err %d\n", | ||
775 | (tps6591x_pdata->init_enable) ? "enable" : "disable", | ||
776 | ri->desc.id, ret); | ||
777 | else | ||
778 | ri->supply_reg.cache_val = reg_val; | ||
779 | return ret; | ||
780 | } | ||
781 | |||
782 | static inline int tps6591x_cache_regulator_register(struct device *parent, | ||
783 | struct tps6591x_regulator *ri) | ||
784 | { | ||
785 | int ret; | ||
786 | ret = tps6591x_read(parent, ri->supply_reg.addr, | ||
787 | &ri->supply_reg.cache_val); | ||
788 | if (!ret && (ri->supply_type == supply_type_sr_op_reg)) { | ||
789 | ret = tps6591x_read(parent, ri->op_reg.addr, | ||
790 | &ri->op_reg.cache_val); | ||
791 | if (!ret) | ||
792 | ret = tps6591x_read(parent, ri->sr_reg.addr, | ||
793 | &ri->sr_reg.cache_val); | ||
794 | } | ||
795 | return ret; | ||
796 | } | ||
797 | |||
798 | static inline struct tps6591x_regulator *find_regulator_info(int id) | ||
799 | { | ||
800 | struct tps6591x_regulator *ri; | ||
801 | int i; | ||
802 | |||
803 | for (i = 0; i < ARRAY_SIZE(tps6591x_regulator); i++) { | ||
804 | ri = &tps6591x_regulator[i]; | ||
805 | if (ri->desc.id == id) | ||
806 | return ri; | ||
807 | } | ||
808 | return NULL; | ||
809 | } | ||
810 | |||
811 | |||
812 | static int __devinit tps6591x_regulator_probe(struct platform_device *pdev) | ||
813 | { | ||
814 | struct tps6591x_regulator *ri = NULL; | ||
815 | struct regulator_dev *rdev; | ||
816 | struct tps6591x_regulator_platform_data *tps_pdata; | ||
817 | int id = pdev->id; | ||
818 | int err; | ||
819 | |||
820 | dev_dbg(&pdev->dev, "Probing reulator %d\n", id); | ||
821 | |||
822 | ri = find_regulator_info(id); | ||
823 | if (ri == NULL) { | ||
824 | dev_err(&pdev->dev, "invalid regulator ID specified\n"); | ||
825 | return -EINVAL; | ||
826 | } | ||
827 | tps_pdata = pdev->dev.platform_data; | ||
828 | ri->ectrl = tps_pdata->ectrl; | ||
829 | ri->config_flags = tps_pdata->flags; | ||
830 | |||
831 | if (tps_pdata->slew_rate_uV_per_us) | ||
832 | ri->voltage_change_uv_per_us = tps_pdata->slew_rate_uV_per_us; | ||
833 | |||
834 | err = tps6591x_cache_regulator_register(pdev->dev.parent, ri); | ||
835 | if (err) { | ||
836 | dev_err(&pdev->dev, "Error in caching registers error %d\n", | ||
837 | err); | ||
838 | return err; | ||
839 | } | ||
840 | |||
841 | err = tps6591x_regulator_preinit(pdev->dev.parent, ri, tps_pdata); | ||
842 | if (err) { | ||
843 | dev_err(&pdev->dev, "Error in pre-initialization of regulator " | ||
844 | "error %d\n", err); | ||
845 | return err; | ||
846 | } | ||
847 | |||
848 | rdev = regulator_register(&ri->desc, &pdev->dev, | ||
849 | &tps_pdata->regulator, ri); | ||
850 | if (IS_ERR_OR_NULL(rdev)) { | ||
851 | dev_err(&pdev->dev, "failed to register regulator %s\n", | ||
852 | ri->desc.name); | ||
853 | return PTR_ERR(rdev); | ||
854 | } | ||
855 | ri->current_volt_uv = ri->desc.ops->get_voltage(rdev); | ||
856 | |||
857 | platform_set_drvdata(pdev, rdev); | ||
858 | |||
859 | return 0; | ||
860 | } | ||
861 | |||
862 | static int __devexit tps6591x_regulator_remove(struct platform_device *pdev) | ||
863 | { | ||
864 | struct regulator_dev *rdev = platform_get_drvdata(pdev); | ||
865 | |||
866 | regulator_unregister(rdev); | ||
867 | return 0; | ||
868 | } | ||
869 | |||
870 | static void tps6591x_regulator_shutdown(struct platform_device *pdev) | ||
871 | { | ||
872 | struct regulator_dev *rdev = platform_get_drvdata(pdev); | ||
873 | struct tps6591x_regulator *ri = rdev_get_drvdata(rdev); | ||
874 | struct device *parent = to_tps6591x_dev(rdev); | ||
875 | int ret; | ||
876 | |||
877 | if (ri->ectrl == EXT_CTRL_EN1) { | ||
878 | ret = tps6591x_clr_bits(parent, ri->en1_reg.addr, | ||
879 | (1 << ri->en1_reg.shift_bits)); | ||
880 | if (ret < 0) | ||
881 | dev_err(&pdev->dev, "Error in clearing external control\n"); | ||
882 | } | ||
883 | } | ||
884 | |||
885 | static int tps6591x_suspend(struct platform_device *pdev, pm_message_t state) | ||
886 | { | ||
887 | struct regulator_dev *rdev = platform_get_drvdata(pdev); | ||
888 | struct tps6591x_regulator *ri = rdev_get_drvdata(rdev); | ||
889 | struct device *parent = to_tps6591x_dev(rdev); | ||
890 | int ret = 0; | ||
891 | uint8_t reg_val; | ||
892 | |||
893 | if (ri->config_flags & LDO_LOW_POWER_ON_SUSPEND) { | ||
894 | ret = tps6591x_clr_bits(parent, ri->en1_reg.addr, | ||
895 | (1 << ri->en1_reg.shift_bits)); | ||
896 | reg_val = ri->supply_reg.cache_val; | ||
897 | reg_val = (reg_val & ~0x3) | (0x3); | ||
898 | ret = tps6591x_write(parent, ri->supply_reg.addr, reg_val); | ||
899 | if (ret >= 0) | ||
900 | ri->supply_reg.cache_val = reg_val; | ||
901 | else | ||
902 | dev_err(&pdev->dev, "Error in updating the supply state\n"); | ||
903 | } | ||
904 | return ret; | ||
905 | } | ||
906 | |||
907 | static int tps6591x_resume(struct platform_device *pdev) | ||
908 | { | ||
909 | struct regulator_dev *rdev = platform_get_drvdata(pdev); | ||
910 | struct tps6591x_regulator *ri = rdev_get_drvdata(rdev); | ||
911 | struct device *parent = to_tps6591x_dev(rdev); | ||
912 | int ret = 0; | ||
913 | uint8_t reg_val; | ||
914 | |||
915 | if (ri->config_flags & LDO_LOW_POWER_ON_SUSPEND) { | ||
916 | ret = tps6591x_clr_bits(parent, ri->en1_reg.addr, | ||
917 | (1 << ri->en1_reg.shift_bits)); | ||
918 | reg_val = ri->supply_reg.cache_val; | ||
919 | reg_val = (reg_val & ~0x3) | (0x1); | ||
920 | ret = tps6591x_write(parent, ri->supply_reg.addr, reg_val); | ||
921 | if (ret >= 0) | ||
922 | ri->supply_reg.cache_val = reg_val; | ||
923 | else | ||
924 | dev_err(&pdev->dev, "Error in updating the supply state\n"); | ||
925 | } | ||
926 | return ret; | ||
927 | } | ||
928 | |||
929 | static struct platform_driver tps6591x_regulator_driver = { | ||
930 | .driver = { | ||
931 | .name = "tps6591x-regulator", | ||
932 | .owner = THIS_MODULE, | ||
933 | }, | ||
934 | .probe = tps6591x_regulator_probe, | ||
935 | .remove = __devexit_p(tps6591x_regulator_remove), | ||
936 | .shutdown = tps6591x_regulator_shutdown, | ||
937 | .suspend = tps6591x_suspend, | ||
938 | .resume = tps6591x_resume, | ||
939 | }; | ||
940 | |||
941 | static int __init tps6591x_regulator_init(void) | ||
942 | { | ||
943 | return platform_driver_register(&tps6591x_regulator_driver); | ||
944 | } | ||
945 | subsys_initcall(tps6591x_regulator_init); | ||
946 | |||
947 | static void __exit tps6591x_regulator_exit(void) | ||
948 | { | ||
949 | platform_driver_unregister(&tps6591x_regulator_driver); | ||
950 | } | ||
951 | module_exit(tps6591x_regulator_exit); | ||
952 | |||
953 | MODULE_LICENSE("GPL"); | ||
954 | MODULE_DESCRIPTION("Regulator Driver for TI TPS6591X PMIC"); | ||
955 | MODULE_ALIAS("platform:tps6591x-regulator"); | ||