1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * max8952.c - Voltage and current regulation for the Maxim 8952 |
4 | * |
5 | * Copyright (C) 2010 Samsung Electronics |
6 | * MyungJoo Ham <myungjoo.ham@samsung.com> |
7 | */ |
8 | |
9 | #include <linux/module.h> |
10 | #include <linux/init.h> |
11 | #include <linux/i2c.h> |
12 | #include <linux/err.h> |
13 | #include <linux/platform_device.h> |
14 | #include <linux/regulator/driver.h> |
15 | #include <linux/regulator/max8952.h> |
16 | #include <linux/gpio/consumer.h> |
17 | #include <linux/io.h> |
18 | #include <linux/of.h> |
19 | #include <linux/regulator/of_regulator.h> |
20 | #include <linux/slab.h> |
21 | |
22 | /* Registers */ |
23 | enum { |
24 | MAX8952_REG_MODE0, |
25 | MAX8952_REG_MODE1, |
26 | MAX8952_REG_MODE2, |
27 | MAX8952_REG_MODE3, |
28 | MAX8952_REG_CONTROL, |
29 | MAX8952_REG_SYNC, |
30 | MAX8952_REG_RAMP, |
31 | MAX8952_REG_CHIP_ID1, |
32 | MAX8952_REG_CHIP_ID2, |
33 | }; |
34 | |
35 | struct max8952_data { |
36 | struct i2c_client *client; |
37 | struct max8952_platform_data *pdata; |
38 | struct gpio_desc *vid0_gpiod; |
39 | struct gpio_desc *vid1_gpiod; |
40 | bool vid0; |
41 | bool vid1; |
42 | }; |
43 | |
44 | static int max8952_read_reg(struct max8952_data *max8952, u8 reg) |
45 | { |
46 | int ret = i2c_smbus_read_byte_data(client: max8952->client, command: reg); |
47 | |
48 | if (ret > 0) |
49 | ret &= 0xff; |
50 | |
51 | return ret; |
52 | } |
53 | |
54 | static int max8952_write_reg(struct max8952_data *max8952, |
55 | u8 reg, u8 value) |
56 | { |
57 | return i2c_smbus_write_byte_data(client: max8952->client, command: reg, value); |
58 | } |
59 | |
60 | static int max8952_list_voltage(struct regulator_dev *rdev, |
61 | unsigned int selector) |
62 | { |
63 | struct max8952_data *max8952 = rdev_get_drvdata(rdev); |
64 | |
65 | if (rdev_get_id(rdev) != 0) |
66 | return -EINVAL; |
67 | |
68 | return (max8952->pdata->dvs_mode[selector] * 10 + 770) * 1000; |
69 | } |
70 | |
71 | static int max8952_get_voltage_sel(struct regulator_dev *rdev) |
72 | { |
73 | struct max8952_data *max8952 = rdev_get_drvdata(rdev); |
74 | u8 vid = 0; |
75 | |
76 | if (max8952->vid0) |
77 | vid += 1; |
78 | if (max8952->vid1) |
79 | vid += 2; |
80 | |
81 | return vid; |
82 | } |
83 | |
84 | static int max8952_set_voltage_sel(struct regulator_dev *rdev, |
85 | unsigned selector) |
86 | { |
87 | struct max8952_data *max8952 = rdev_get_drvdata(rdev); |
88 | |
89 | if (!max8952->vid0_gpiod || !max8952->vid1_gpiod) { |
90 | /* DVS not supported */ |
91 | return -EPERM; |
92 | } |
93 | |
94 | max8952->vid0 = selector & 0x1; |
95 | max8952->vid1 = (selector >> 1) & 0x1; |
96 | gpiod_set_value(desc: max8952->vid0_gpiod, value: max8952->vid0); |
97 | gpiod_set_value(desc: max8952->vid1_gpiod, value: max8952->vid1); |
98 | |
99 | return 0; |
100 | } |
101 | |
102 | static const struct regulator_ops max8952_ops = { |
103 | .list_voltage = max8952_list_voltage, |
104 | .get_voltage_sel = max8952_get_voltage_sel, |
105 | .set_voltage_sel = max8952_set_voltage_sel, |
106 | }; |
107 | |
108 | static const struct regulator_desc regulator = { |
109 | .name = "MAX8952_VOUT" , |
110 | .id = 0, |
111 | .n_voltages = MAX8952_NUM_DVS_MODE, |
112 | .ops = &max8952_ops, |
113 | .type = REGULATOR_VOLTAGE, |
114 | .owner = THIS_MODULE, |
115 | }; |
116 | |
117 | #ifdef CONFIG_OF |
118 | static const struct of_device_id max8952_dt_match[] = { |
119 | { .compatible = "maxim,max8952" }, |
120 | {}, |
121 | }; |
122 | MODULE_DEVICE_TABLE(of, max8952_dt_match); |
123 | |
124 | static struct max8952_platform_data *max8952_parse_dt(struct device *dev) |
125 | { |
126 | struct max8952_platform_data *pd; |
127 | struct device_node *np = dev->of_node; |
128 | int ret; |
129 | int i; |
130 | |
131 | pd = devm_kzalloc(dev, size: sizeof(*pd), GFP_KERNEL); |
132 | if (!pd) |
133 | return NULL; |
134 | |
135 | if (of_property_read_u32(np, propname: "max8952,default-mode" , out_value: &pd->default_mode)) |
136 | dev_warn(dev, "Default mode not specified, assuming 0\n" ); |
137 | |
138 | ret = of_property_read_u32_array(np, propname: "max8952,dvs-mode-microvolt" , |
139 | out_values: pd->dvs_mode, ARRAY_SIZE(pd->dvs_mode)); |
140 | if (ret) { |
141 | dev_err(dev, "max8952,dvs-mode-microvolt property not specified" ); |
142 | return NULL; |
143 | } |
144 | |
145 | for (i = 0; i < ARRAY_SIZE(pd->dvs_mode); ++i) { |
146 | if (pd->dvs_mode[i] < 770000 || pd->dvs_mode[i] > 1400000) { |
147 | dev_err(dev, "DVS voltage %d out of range\n" , i); |
148 | return NULL; |
149 | } |
150 | pd->dvs_mode[i] = (pd->dvs_mode[i] - 770000) / 10000; |
151 | } |
152 | |
153 | if (of_property_read_u32(np, propname: "max8952,sync-freq" , out_value: &pd->sync_freq)) |
154 | dev_warn(dev, "max8952,sync-freq property not specified, defaulting to 26MHz\n" ); |
155 | |
156 | if (of_property_read_u32(np, propname: "max8952,ramp-speed" , out_value: &pd->ramp_speed)) |
157 | dev_warn(dev, "max8952,ramp-speed property not specified, defaulting to 32mV/us\n" ); |
158 | |
159 | pd->reg_data = of_get_regulator_init_data(dev, node: np, desc: ®ulator); |
160 | if (!pd->reg_data) { |
161 | dev_err(dev, "Failed to parse regulator init data\n" ); |
162 | return NULL; |
163 | } |
164 | |
165 | return pd; |
166 | } |
167 | #else |
168 | static struct max8952_platform_data *max8952_parse_dt(struct device *dev) |
169 | { |
170 | return NULL; |
171 | } |
172 | #endif |
173 | |
174 | static int max8952_pmic_probe(struct i2c_client *client) |
175 | { |
176 | struct i2c_adapter *adapter = client->adapter; |
177 | struct max8952_platform_data *pdata = dev_get_platdata(dev: &client->dev); |
178 | struct regulator_config config = { }; |
179 | struct max8952_data *max8952; |
180 | struct regulator_dev *rdev; |
181 | struct gpio_desc *gpiod; |
182 | enum gpiod_flags gflags; |
183 | |
184 | int ret = 0; |
185 | |
186 | if (client->dev.of_node) |
187 | pdata = max8952_parse_dt(dev: &client->dev); |
188 | |
189 | if (!pdata) { |
190 | dev_err(&client->dev, "Require the platform data\n" ); |
191 | return -EINVAL; |
192 | } |
193 | |
194 | if (!i2c_check_functionality(adap: adapter, I2C_FUNC_SMBUS_BYTE)) |
195 | return -EIO; |
196 | |
197 | max8952 = devm_kzalloc(dev: &client->dev, size: sizeof(struct max8952_data), |
198 | GFP_KERNEL); |
199 | if (!max8952) |
200 | return -ENOMEM; |
201 | |
202 | max8952->client = client; |
203 | max8952->pdata = pdata; |
204 | |
205 | config.dev = &client->dev; |
206 | config.init_data = pdata->reg_data; |
207 | config.driver_data = max8952; |
208 | config.of_node = client->dev.of_node; |
209 | |
210 | if (pdata->reg_data->constraints.boot_on) |
211 | gflags = GPIOD_OUT_HIGH; |
212 | else |
213 | gflags = GPIOD_OUT_LOW; |
214 | gflags |= GPIOD_FLAGS_BIT_NONEXCLUSIVE; |
215 | /* |
216 | * Do not use devm* here: the regulator core takes over the |
217 | * lifecycle management of the GPIO descriptor. |
218 | */ |
219 | gpiod = gpiod_get_optional(dev: &client->dev, |
220 | con_id: "max8952,en" , |
221 | flags: gflags); |
222 | if (IS_ERR(ptr: gpiod)) |
223 | return PTR_ERR(ptr: gpiod); |
224 | if (gpiod) |
225 | config.ena_gpiod = gpiod; |
226 | |
227 | rdev = devm_regulator_register(dev: &client->dev, regulator_desc: ®ulator, config: &config); |
228 | if (IS_ERR(ptr: rdev)) { |
229 | ret = PTR_ERR(ptr: rdev); |
230 | dev_err(&client->dev, "regulator init failed (%d)\n" , ret); |
231 | return ret; |
232 | } |
233 | |
234 | max8952->vid0 = pdata->default_mode & 0x1; |
235 | max8952->vid1 = (pdata->default_mode >> 1) & 0x1; |
236 | |
237 | /* Fetch vid0 and vid1 GPIOs if available */ |
238 | gflags = max8952->vid0 ? GPIOD_OUT_HIGH : GPIOD_OUT_LOW; |
239 | max8952->vid0_gpiod = devm_gpiod_get_index_optional(dev: &client->dev, |
240 | con_id: "max8952,vid" , |
241 | index: 0, flags: gflags); |
242 | if (IS_ERR(ptr: max8952->vid0_gpiod)) |
243 | return PTR_ERR(ptr: max8952->vid0_gpiod); |
244 | gflags = max8952->vid1 ? GPIOD_OUT_HIGH : GPIOD_OUT_LOW; |
245 | max8952->vid1_gpiod = devm_gpiod_get_index_optional(dev: &client->dev, |
246 | con_id: "max8952,vid" , |
247 | index: 1, flags: gflags); |
248 | if (IS_ERR(ptr: max8952->vid1_gpiod)) |
249 | return PTR_ERR(ptr: max8952->vid1_gpiod); |
250 | |
251 | /* If either VID GPIO is missing just disable this */ |
252 | if (!max8952->vid0_gpiod || !max8952->vid1_gpiod) { |
253 | dev_warn(&client->dev, "VID0/1 gpio invalid: " |
254 | "DVS not available.\n" ); |
255 | max8952->vid0 = 0; |
256 | max8952->vid1 = 0; |
257 | /* Make sure if we have any descriptors they get set to low */ |
258 | if (max8952->vid0_gpiod) |
259 | gpiod_set_value(desc: max8952->vid0_gpiod, value: 0); |
260 | if (max8952->vid1_gpiod) |
261 | gpiod_set_value(desc: max8952->vid1_gpiod, value: 0); |
262 | |
263 | /* Disable Pulldown of EN only */ |
264 | max8952_write_reg(max8952, reg: MAX8952_REG_CONTROL, value: 0x60); |
265 | |
266 | dev_err(&client->dev, "DVS modes disabled because VID0 and VID1" |
267 | " do not have proper controls.\n" ); |
268 | } else { |
269 | /* |
270 | * Disable Pulldown on EN, VID0, VID1 to reduce |
271 | * leakage current of MAX8952 assuming that MAX8952 |
272 | * is turned on (EN==1). Note that without having VID0/1 |
273 | * properly connected, turning pulldown off can be |
274 | * problematic. Thus, turn this off only when they are |
275 | * controllable by GPIO. |
276 | */ |
277 | max8952_write_reg(max8952, reg: MAX8952_REG_CONTROL, value: 0x0); |
278 | } |
279 | |
280 | max8952_write_reg(max8952, reg: MAX8952_REG_MODE0, |
281 | value: (max8952_read_reg(max8952, |
282 | reg: MAX8952_REG_MODE0) & 0xC0) | |
283 | (pdata->dvs_mode[0] & 0x3F)); |
284 | max8952_write_reg(max8952, reg: MAX8952_REG_MODE1, |
285 | value: (max8952_read_reg(max8952, |
286 | reg: MAX8952_REG_MODE1) & 0xC0) | |
287 | (pdata->dvs_mode[1] & 0x3F)); |
288 | max8952_write_reg(max8952, reg: MAX8952_REG_MODE2, |
289 | value: (max8952_read_reg(max8952, |
290 | reg: MAX8952_REG_MODE2) & 0xC0) | |
291 | (pdata->dvs_mode[2] & 0x3F)); |
292 | max8952_write_reg(max8952, reg: MAX8952_REG_MODE3, |
293 | value: (max8952_read_reg(max8952, |
294 | reg: MAX8952_REG_MODE3) & 0xC0) | |
295 | (pdata->dvs_mode[3] & 0x3F)); |
296 | |
297 | max8952_write_reg(max8952, reg: MAX8952_REG_SYNC, |
298 | value: (max8952_read_reg(max8952, reg: MAX8952_REG_SYNC) & 0x3F) | |
299 | ((pdata->sync_freq & 0x3) << 6)); |
300 | max8952_write_reg(max8952, reg: MAX8952_REG_RAMP, |
301 | value: (max8952_read_reg(max8952, reg: MAX8952_REG_RAMP) & 0x1F) | |
302 | ((pdata->ramp_speed & 0x7) << 5)); |
303 | |
304 | i2c_set_clientdata(client, data: max8952); |
305 | |
306 | return 0; |
307 | } |
308 | |
309 | static const struct i2c_device_id max8952_ids[] = { |
310 | { "max8952" , 0 }, |
311 | { }, |
312 | }; |
313 | MODULE_DEVICE_TABLE(i2c, max8952_ids); |
314 | |
315 | static struct i2c_driver max8952_pmic_driver = { |
316 | .probe = max8952_pmic_probe, |
317 | .driver = { |
318 | .name = "max8952" , |
319 | .probe_type = PROBE_PREFER_ASYNCHRONOUS, |
320 | .of_match_table = of_match_ptr(max8952_dt_match), |
321 | }, |
322 | .id_table = max8952_ids, |
323 | }; |
324 | |
325 | static int __init max8952_pmic_init(void) |
326 | { |
327 | return i2c_add_driver(&max8952_pmic_driver); |
328 | } |
329 | subsys_initcall(max8952_pmic_init); |
330 | |
331 | static void __exit max8952_pmic_exit(void) |
332 | { |
333 | i2c_del_driver(driver: &max8952_pmic_driver); |
334 | } |
335 | module_exit(max8952_pmic_exit); |
336 | |
337 | MODULE_DESCRIPTION("MAXIM 8952 voltage regulator driver" ); |
338 | MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>" ); |
339 | MODULE_LICENSE("GPL" ); |
340 | |