Commit | Line | Data |
---|---|---|
6a1beee2 AL |
1 | // SPDX-License-Identifier: GPL-2.0 |
2 | // | |
3 | // FAN53555 Fairchild Digitally Programmable TinyBuck Regulator Driver. | |
4 | // | |
5 | // Supported Part Numbers: | |
6 | // FAN53555UC00X/01X/03X/04X/05X | |
7 | // | |
8 | // Copyright (c) 2012 Marvell Technology Ltd. | |
9 | // Yunfan Zhang <yfzhang@marvell.com> | |
10 | ||
49d8c599 YZ |
11 | #include <linux/module.h> |
12 | #include <linux/param.h> | |
13 | #include <linux/err.h> | |
14 | #include <linux/platform_device.h> | |
15 | #include <linux/regulator/driver.h> | |
16 | #include <linux/regulator/machine.h> | |
91f23d8f HS |
17 | #include <linux/regulator/of_regulator.h> |
18 | #include <linux/of_device.h> | |
49d8c599 YZ |
19 | #include <linux/i2c.h> |
20 | #include <linux/slab.h> | |
21 | #include <linux/regmap.h> | |
22 | #include <linux/regulator/fan53555.h> | |
23 | ||
24 | /* Voltage setting */ | |
25 | #define FAN53555_VSEL0 0x00 | |
26 | #define FAN53555_VSEL1 0x01 | |
27 | /* Control register */ | |
28 | #define FAN53555_CONTROL 0x02 | |
29 | /* IC Type */ | |
30 | #define FAN53555_ID1 0x03 | |
31 | /* IC mask version */ | |
32 | #define FAN53555_ID2 0x04 | |
33 | /* Monitor register */ | |
34 | #define FAN53555_MONITOR 0x05 | |
35 | ||
36 | /* VSEL bit definitions */ | |
37 | #define VSEL_BUCK_EN (1 << 7) | |
38 | #define VSEL_MODE (1 << 6) | |
49d8c599 YZ |
39 | /* Chip ID and Verison */ |
40 | #define DIE_ID 0x0F /* ID1 */ | |
41 | #define DIE_REV 0x0F /* ID2 */ | |
42 | /* Control bit definitions */ | |
43 | #define CTL_OUTPUT_DISCHG (1 << 7) | |
44 | #define CTL_SLEW_MASK (0x7 << 4) | |
45 | #define CTL_SLEW_SHIFT 4 | |
46 | #define CTL_RESET (1 << 2) | |
f2a9eb97 BA |
47 | #define CTL_MODE_VSEL0_MODE BIT(0) |
48 | #define CTL_MODE_VSEL1_MODE BIT(1) | |
49d8c599 YZ |
49 | |
50 | #define FAN53555_NVOLTAGES 64 /* Numbers of voltages */ | |
f2a9eb97 | 51 | #define FAN53526_NVOLTAGES 128 |
49d8c599 | 52 | |
ee30928a | 53 | enum fan53555_vendor { |
f2a9eb97 BA |
54 | FAN53526_VENDOR_FAIRCHILD = 0, |
55 | FAN53555_VENDOR_FAIRCHILD, | |
ee30928a HS |
56 | FAN53555_VENDOR_SILERGY, |
57 | }; | |
58 | ||
f2a9eb97 BA |
59 | enum { |
60 | FAN53526_CHIP_ID_01 = 1, | |
61 | }; | |
62 | ||
63 | enum { | |
64 | FAN53526_CHIP_REV_08 = 8, | |
65 | }; | |
66 | ||
49d8c599 YZ |
67 | /* IC Type */ |
68 | enum { | |
69 | FAN53555_CHIP_ID_00 = 0, | |
70 | FAN53555_CHIP_ID_01, | |
71 | FAN53555_CHIP_ID_02, | |
72 | FAN53555_CHIP_ID_03, | |
73 | FAN53555_CHIP_ID_04, | |
74 | FAN53555_CHIP_ID_05, | |
5e39cf49 | 75 | FAN53555_CHIP_ID_08 = 8, |
49d8c599 YZ |
76 | }; |
77 | ||
e57cbb70 WE |
78 | /* IC mask revision */ |
79 | enum { | |
80 | FAN53555_CHIP_REV_00 = 0x3, | |
81 | FAN53555_CHIP_REV_13 = 0xf, | |
82 | }; | |
83 | ||
ee30928a HS |
84 | enum { |
85 | SILERGY_SYR82X = 8, | |
86 | }; | |
87 | ||
49d8c599 | 88 | struct fan53555_device_info { |
ee30928a | 89 | enum fan53555_vendor vendor; |
49d8c599 YZ |
90 | struct device *dev; |
91 | struct regulator_desc desc; | |
49d8c599 YZ |
92 | struct regulator_init_data *regulator; |
93 | /* IC Type and Rev */ | |
94 | int chip_id; | |
95 | int chip_rev; | |
96 | /* Voltage setting register */ | |
97 | unsigned int vol_reg; | |
98 | unsigned int sleep_reg; | |
99 | /* Voltage range and step(linear) */ | |
100 | unsigned int vsel_min; | |
49d8c599 | 101 | unsigned int vsel_step; |
f2a9eb97 | 102 | unsigned int vsel_count; |
f2a9eb97 BA |
103 | /* Mode */ |
104 | unsigned int mode_reg; | |
105 | unsigned int mode_mask; | |
49d8c599 YZ |
106 | /* Sleep voltage cache */ |
107 | unsigned int sleep_vol_cache; | |
108 | }; | |
109 | ||
110 | static int fan53555_set_suspend_voltage(struct regulator_dev *rdev, int uV) | |
111 | { | |
112 | struct fan53555_device_info *di = rdev_get_drvdata(rdev); | |
113 | int ret; | |
114 | ||
115 | if (di->sleep_vol_cache == uV) | |
116 | return 0; | |
117 | ret = regulator_map_voltage_linear(rdev, uV, uV); | |
118 | if (ret < 0) | |
145fe1e1 | 119 | return ret; |
a69929c7 | 120 | ret = regmap_update_bits(rdev->regmap, di->sleep_reg, |
f2a9eb97 | 121 | di->desc.vsel_mask, ret); |
49d8c599 | 122 | if (ret < 0) |
145fe1e1 | 123 | return ret; |
49d8c599 YZ |
124 | /* Cache the sleep voltage setting. |
125 | * Might not be the real voltage which is rounded */ | |
126 | di->sleep_vol_cache = uV; | |
127 | ||
128 | return 0; | |
129 | } | |
130 | ||
ab7cad33 | 131 | static int fan53555_set_suspend_enable(struct regulator_dev *rdev) |
132 | { | |
133 | struct fan53555_device_info *di = rdev_get_drvdata(rdev); | |
134 | ||
a69929c7 | 135 | return regmap_update_bits(rdev->regmap, di->sleep_reg, |
ab7cad33 | 136 | VSEL_BUCK_EN, VSEL_BUCK_EN); |
137 | } | |
138 | ||
139 | static int fan53555_set_suspend_disable(struct regulator_dev *rdev) | |
140 | { | |
141 | struct fan53555_device_info *di = rdev_get_drvdata(rdev); | |
142 | ||
a69929c7 | 143 | return regmap_update_bits(rdev->regmap, di->sleep_reg, |
ab7cad33 | 144 | VSEL_BUCK_EN, 0); |
145 | } | |
146 | ||
49d8c599 YZ |
147 | static int fan53555_set_mode(struct regulator_dev *rdev, unsigned int mode) |
148 | { | |
149 | struct fan53555_device_info *di = rdev_get_drvdata(rdev); | |
150 | ||
151 | switch (mode) { | |
152 | case REGULATOR_MODE_FAST: | |
a69929c7 | 153 | regmap_update_bits(rdev->regmap, di->mode_reg, |
f2a9eb97 | 154 | di->mode_mask, di->mode_mask); |
49d8c599 YZ |
155 | break; |
156 | case REGULATOR_MODE_NORMAL: | |
a69929c7 | 157 | regmap_update_bits(rdev->regmap, di->vol_reg, di->mode_mask, 0); |
49d8c599 YZ |
158 | break; |
159 | default: | |
160 | return -EINVAL; | |
161 | } | |
162 | return 0; | |
163 | } | |
164 | ||
165 | static unsigned int fan53555_get_mode(struct regulator_dev *rdev) | |
166 | { | |
167 | struct fan53555_device_info *di = rdev_get_drvdata(rdev); | |
168 | unsigned int val; | |
169 | int ret = 0; | |
170 | ||
a69929c7 | 171 | ret = regmap_read(rdev->regmap, di->mode_reg, &val); |
49d8c599 YZ |
172 | if (ret < 0) |
173 | return ret; | |
f2a9eb97 | 174 | if (val & di->mode_mask) |
49d8c599 YZ |
175 | return REGULATOR_MODE_FAST; |
176 | else | |
177 | return REGULATOR_MODE_NORMAL; | |
178 | } | |
179 | ||
121b567d | 180 | static const int slew_rates[] = { |
dd7e71fb HS |
181 | 64000, |
182 | 32000, | |
183 | 16000, | |
184 | 8000, | |
185 | 4000, | |
186 | 2000, | |
187 | 1000, | |
188 | 500, | |
189 | }; | |
190 | ||
191 | static int fan53555_set_ramp(struct regulator_dev *rdev, int ramp) | |
192 | { | |
193 | struct fan53555_device_info *di = rdev_get_drvdata(rdev); | |
194 | int regval = -1, i; | |
195 | ||
196 | for (i = 0; i < ARRAY_SIZE(slew_rates); i++) { | |
197 | if (ramp <= slew_rates[i]) | |
198 | regval = i; | |
199 | else | |
200 | break; | |
201 | } | |
202 | ||
203 | if (regval < 0) { | |
204 | dev_err(di->dev, "unsupported ramp value %d\n", ramp); | |
205 | return -EINVAL; | |
206 | } | |
207 | ||
a69929c7 | 208 | return regmap_update_bits(rdev->regmap, FAN53555_CONTROL, |
dd7e71fb HS |
209 | CTL_SLEW_MASK, regval << CTL_SLEW_SHIFT); |
210 | } | |
211 | ||
71880ab2 | 212 | static const struct regulator_ops fan53555_regulator_ops = { |
49d8c599 YZ |
213 | .set_voltage_sel = regulator_set_voltage_sel_regmap, |
214 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | |
fda87a42 | 215 | .set_voltage_time_sel = regulator_set_voltage_time_sel, |
49d8c599 YZ |
216 | .map_voltage = regulator_map_voltage_linear, |
217 | .list_voltage = regulator_list_voltage_linear, | |
218 | .set_suspend_voltage = fan53555_set_suspend_voltage, | |
219 | .enable = regulator_enable_regmap, | |
220 | .disable = regulator_disable_regmap, | |
221 | .is_enabled = regulator_is_enabled_regmap, | |
222 | .set_mode = fan53555_set_mode, | |
223 | .get_mode = fan53555_get_mode, | |
dd7e71fb | 224 | .set_ramp_delay = fan53555_set_ramp, |
ab7cad33 | 225 | .set_suspend_enable = fan53555_set_suspend_enable, |
226 | .set_suspend_disable = fan53555_set_suspend_disable, | |
49d8c599 YZ |
227 | }; |
228 | ||
f2a9eb97 BA |
229 | static int fan53526_voltages_setup_fairchild(struct fan53555_device_info *di) |
230 | { | |
231 | /* Init voltage range and step */ | |
232 | switch (di->chip_id) { | |
233 | case FAN53526_CHIP_ID_01: | |
234 | switch (di->chip_rev) { | |
235 | case FAN53526_CHIP_REV_08: | |
236 | di->vsel_min = 600000; | |
237 | di->vsel_step = 6250; | |
238 | break; | |
239 | default: | |
240 | dev_err(di->dev, | |
241 | "Chip ID %d with rev %d not supported!\n", | |
242 | di->chip_id, di->chip_rev); | |
243 | return -EINVAL; | |
244 | } | |
245 | break; | |
246 | default: | |
247 | dev_err(di->dev, | |
248 | "Chip ID %d not supported!\n", di->chip_id); | |
249 | return -EINVAL; | |
250 | } | |
251 | ||
252 | di->vsel_count = FAN53526_NVOLTAGES; | |
253 | ||
254 | return 0; | |
255 | } | |
256 | ||
ee30928a HS |
257 | static int fan53555_voltages_setup_fairchild(struct fan53555_device_info *di) |
258 | { | |
259 | /* Init voltage range and step */ | |
260 | switch (di->chip_id) { | |
261 | case FAN53555_CHIP_ID_00: | |
e57cbb70 WE |
262 | switch (di->chip_rev) { |
263 | case FAN53555_CHIP_REV_00: | |
264 | di->vsel_min = 600000; | |
265 | di->vsel_step = 10000; | |
266 | break; | |
267 | case FAN53555_CHIP_REV_13: | |
268 | di->vsel_min = 800000; | |
269 | di->vsel_step = 10000; | |
270 | break; | |
271 | default: | |
272 | dev_err(di->dev, | |
273 | "Chip ID %d with rev %d not supported!\n", | |
274 | di->chip_id, di->chip_rev); | |
275 | return -EINVAL; | |
276 | } | |
277 | break; | |
ee30928a HS |
278 | case FAN53555_CHIP_ID_01: |
279 | case FAN53555_CHIP_ID_03: | |
280 | case FAN53555_CHIP_ID_05: | |
5e39cf49 | 281 | case FAN53555_CHIP_ID_08: |
ee30928a HS |
282 | di->vsel_min = 600000; |
283 | di->vsel_step = 10000; | |
284 | break; | |
285 | case FAN53555_CHIP_ID_04: | |
286 | di->vsel_min = 603000; | |
287 | di->vsel_step = 12826; | |
288 | break; | |
289 | default: | |
290 | dev_err(di->dev, | |
291 | "Chip ID %d not supported!\n", di->chip_id); | |
292 | return -EINVAL; | |
293 | } | |
294 | ||
f2a9eb97 BA |
295 | di->vsel_count = FAN53555_NVOLTAGES; |
296 | ||
ee30928a HS |
297 | return 0; |
298 | } | |
299 | ||
300 | static int fan53555_voltages_setup_silergy(struct fan53555_device_info *di) | |
301 | { | |
302 | /* Init voltage range and step */ | |
303 | switch (di->chip_id) { | |
304 | case SILERGY_SYR82X: | |
305 | di->vsel_min = 712500; | |
306 | di->vsel_step = 12500; | |
307 | break; | |
308 | default: | |
309 | dev_err(di->dev, | |
310 | "Chip ID %d not supported!\n", di->chip_id); | |
311 | return -EINVAL; | |
312 | } | |
313 | ||
f2a9eb97 BA |
314 | di->vsel_count = FAN53555_NVOLTAGES; |
315 | ||
ee30928a HS |
316 | return 0; |
317 | } | |
318 | ||
49d8c599 YZ |
319 | /* For 00,01,03,05 options: |
320 | * VOUT = 0.60V + NSELx * 10mV, from 0.60 to 1.23V. | |
321 | * For 04 option: | |
322 | * VOUT = 0.603V + NSELx * 12.826mV, from 0.603 to 1.411V. | |
323 | * */ | |
324 | static int fan53555_device_setup(struct fan53555_device_info *di, | |
325 | struct fan53555_platform_data *pdata) | |
326 | { | |
ee30928a HS |
327 | int ret = 0; |
328 | ||
49d8c599 YZ |
329 | /* Setup voltage control register */ |
330 | switch (pdata->sleep_vsel_id) { | |
331 | case FAN53555_VSEL_ID_0: | |
332 | di->sleep_reg = FAN53555_VSEL0; | |
333 | di->vol_reg = FAN53555_VSEL1; | |
334 | break; | |
335 | case FAN53555_VSEL_ID_1: | |
336 | di->sleep_reg = FAN53555_VSEL1; | |
337 | di->vol_reg = FAN53555_VSEL0; | |
338 | break; | |
339 | default: | |
340 | dev_err(di->dev, "Invalid VSEL ID!\n"); | |
341 | return -EINVAL; | |
342 | } | |
ee30928a | 343 | |
f2a9eb97 BA |
344 | /* Setup mode control register */ |
345 | switch (di->vendor) { | |
346 | case FAN53526_VENDOR_FAIRCHILD: | |
347 | di->mode_reg = FAN53555_CONTROL; | |
348 | ||
349 | switch (pdata->sleep_vsel_id) { | |
350 | case FAN53555_VSEL_ID_0: | |
351 | di->mode_mask = CTL_MODE_VSEL1_MODE; | |
352 | break; | |
353 | case FAN53555_VSEL_ID_1: | |
354 | di->mode_mask = CTL_MODE_VSEL0_MODE; | |
355 | break; | |
356 | } | |
357 | break; | |
358 | case FAN53555_VENDOR_FAIRCHILD: | |
359 | case FAN53555_VENDOR_SILERGY: | |
360 | di->mode_reg = di->vol_reg; | |
361 | di->mode_mask = VSEL_MODE; | |
362 | break; | |
363 | default: | |
364 | dev_err(di->dev, "vendor %d not supported!\n", di->vendor); | |
365 | return -EINVAL; | |
366 | } | |
367 | ||
368 | /* Setup voltage range */ | |
ee30928a | 369 | switch (di->vendor) { |
f2a9eb97 BA |
370 | case FAN53526_VENDOR_FAIRCHILD: |
371 | ret = fan53526_voltages_setup_fairchild(di); | |
372 | break; | |
ee30928a HS |
373 | case FAN53555_VENDOR_FAIRCHILD: |
374 | ret = fan53555_voltages_setup_fairchild(di); | |
49d8c599 | 375 | break; |
ee30928a HS |
376 | case FAN53555_VENDOR_SILERGY: |
377 | ret = fan53555_voltages_setup_silergy(di); | |
49d8c599 YZ |
378 | break; |
379 | default: | |
fe230531 | 380 | dev_err(di->dev, "vendor %d not supported!\n", di->vendor); |
49d8c599 YZ |
381 | return -EINVAL; |
382 | } | |
dd7e71fb | 383 | |
ee30928a | 384 | return ret; |
49d8c599 YZ |
385 | } |
386 | ||
387 | static int fan53555_regulator_register(struct fan53555_device_info *di, | |
388 | struct regulator_config *config) | |
389 | { | |
390 | struct regulator_desc *rdesc = &di->desc; | |
a69929c7 | 391 | struct regulator_dev *rdev; |
49d8c599 YZ |
392 | |
393 | rdesc->name = "fan53555-reg"; | |
3415d601 | 394 | rdesc->supply_name = "vin"; |
49d8c599 YZ |
395 | rdesc->ops = &fan53555_regulator_ops; |
396 | rdesc->type = REGULATOR_VOLTAGE; | |
f2a9eb97 | 397 | rdesc->n_voltages = di->vsel_count; |
49d8c599 YZ |
398 | rdesc->enable_reg = di->vol_reg; |
399 | rdesc->enable_mask = VSEL_BUCK_EN; | |
400 | rdesc->min_uV = di->vsel_min; | |
401 | rdesc->uV_step = di->vsel_step; | |
402 | rdesc->vsel_reg = di->vol_reg; | |
f2a9eb97 | 403 | rdesc->vsel_mask = di->vsel_count - 1; |
49d8c599 YZ |
404 | rdesc->owner = THIS_MODULE; |
405 | ||
a69929c7 AL |
406 | rdev = devm_regulator_register(di->dev, &di->desc, config); |
407 | return PTR_ERR_OR_ZERO(rdev); | |
49d8c599 YZ |
408 | } |
409 | ||
121b567d | 410 | static const struct regmap_config fan53555_regmap_config = { |
49d8c599 YZ |
411 | .reg_bits = 8, |
412 | .val_bits = 8, | |
413 | }; | |
414 | ||
91f23d8f | 415 | static struct fan53555_platform_data *fan53555_parse_dt(struct device *dev, |
072e78b1 JMC |
416 | struct device_node *np, |
417 | const struct regulator_desc *desc) | |
91f23d8f HS |
418 | { |
419 | struct fan53555_platform_data *pdata; | |
420 | int ret; | |
421 | u32 tmp; | |
422 | ||
423 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); | |
424 | if (!pdata) | |
425 | return NULL; | |
426 | ||
072e78b1 | 427 | pdata->regulator = of_get_regulator_init_data(dev, np, desc); |
91f23d8f HS |
428 | |
429 | ret = of_property_read_u32(np, "fcs,suspend-voltage-selector", | |
430 | &tmp); | |
431 | if (!ret) | |
432 | pdata->sleep_vsel_id = tmp; | |
433 | ||
434 | return pdata; | |
435 | } | |
436 | ||
437 | static const struct of_device_id fan53555_dt_ids[] = { | |
438 | { | |
f2a9eb97 BA |
439 | .compatible = "fcs,fan53526", |
440 | .data = (void *)FAN53526_VENDOR_FAIRCHILD, | |
441 | }, { | |
91f23d8f | 442 | .compatible = "fcs,fan53555", |
ee30928a HS |
443 | .data = (void *)FAN53555_VENDOR_FAIRCHILD |
444 | }, { | |
445 | .compatible = "silergy,syr827", | |
446 | .data = (void *)FAN53555_VENDOR_SILERGY, | |
447 | }, { | |
448 | .compatible = "silergy,syr828", | |
449 | .data = (void *)FAN53555_VENDOR_SILERGY, | |
91f23d8f HS |
450 | }, |
451 | { } | |
452 | }; | |
453 | MODULE_DEVICE_TABLE(of, fan53555_dt_ids); | |
454 | ||
a5023574 | 455 | static int fan53555_regulator_probe(struct i2c_client *client, |
49d8c599 YZ |
456 | const struct i2c_device_id *id) |
457 | { | |
91f23d8f | 458 | struct device_node *np = client->dev.of_node; |
49d8c599 YZ |
459 | struct fan53555_device_info *di; |
460 | struct fan53555_platform_data *pdata; | |
461 | struct regulator_config config = { }; | |
a69929c7 | 462 | struct regmap *regmap; |
49d8c599 YZ |
463 | unsigned int val; |
464 | int ret; | |
465 | ||
072e78b1 JMC |
466 | di = devm_kzalloc(&client->dev, sizeof(struct fan53555_device_info), |
467 | GFP_KERNEL); | |
468 | if (!di) | |
469 | return -ENOMEM; | |
470 | ||
dff91d0b | 471 | pdata = dev_get_platdata(&client->dev); |
91f23d8f | 472 | if (!pdata) |
072e78b1 | 473 | pdata = fan53555_parse_dt(&client->dev, np, &di->desc); |
91f23d8f | 474 | |
49d8c599 YZ |
475 | if (!pdata || !pdata->regulator) { |
476 | dev_err(&client->dev, "Platform data not found!\n"); | |
477 | return -ENODEV; | |
478 | } | |
479 | ||
e13426bf | 480 | di->regulator = pdata->regulator; |
ee30928a | 481 | if (client->dev.of_node) { |
d110e3e9 JZ |
482 | di->vendor = |
483 | (unsigned long)of_device_get_match_data(&client->dev); | |
ee30928a | 484 | } else { |
91f23d8f HS |
485 | /* if no ramp constraint set, get the pdata ramp_delay */ |
486 | if (!di->regulator->constraints.ramp_delay) { | |
87919e0c AL |
487 | if (pdata->slew_rate >= ARRAY_SIZE(slew_rates)) { |
488 | dev_err(&client->dev, "Invalid slew_rate\n"); | |
489 | return -EINVAL; | |
490 | } | |
dd7e71fb | 491 | |
91f23d8f | 492 | di->regulator->constraints.ramp_delay |
87919e0c | 493 | = slew_rates[pdata->slew_rate]; |
91f23d8f | 494 | } |
ee30928a HS |
495 | |
496 | di->vendor = id->driver_data; | |
dd7e71fb HS |
497 | } |
498 | ||
a69929c7 AL |
499 | regmap = devm_regmap_init_i2c(client, &fan53555_regmap_config); |
500 | if (IS_ERR(regmap)) { | |
49d8c599 | 501 | dev_err(&client->dev, "Failed to allocate regmap!\n"); |
a69929c7 | 502 | return PTR_ERR(regmap); |
49d8c599 YZ |
503 | } |
504 | di->dev = &client->dev; | |
49d8c599 YZ |
505 | i2c_set_clientdata(client, di); |
506 | /* Get chip ID */ | |
a69929c7 | 507 | ret = regmap_read(regmap, FAN53555_ID1, &val); |
49d8c599 YZ |
508 | if (ret < 0) { |
509 | dev_err(&client->dev, "Failed to get chip ID!\n"); | |
145fe1e1 | 510 | return ret; |
49d8c599 YZ |
511 | } |
512 | di->chip_id = val & DIE_ID; | |
513 | /* Get chip revision */ | |
a69929c7 | 514 | ret = regmap_read(regmap, FAN53555_ID2, &val); |
49d8c599 YZ |
515 | if (ret < 0) { |
516 | dev_err(&client->dev, "Failed to get chip Rev!\n"); | |
145fe1e1 | 517 | return ret; |
49d8c599 YZ |
518 | } |
519 | di->chip_rev = val & DIE_REV; | |
520 | dev_info(&client->dev, "FAN53555 Option[%d] Rev[%d] Detected!\n", | |
521 | di->chip_id, di->chip_rev); | |
522 | /* Device init */ | |
523 | ret = fan53555_device_setup(di, pdata); | |
524 | if (ret < 0) { | |
525 | dev_err(&client->dev, "Failed to setup device!\n"); | |
526 | return ret; | |
527 | } | |
528 | /* Register regulator */ | |
529 | config.dev = di->dev; | |
530 | config.init_data = di->regulator; | |
a69929c7 | 531 | config.regmap = regmap; |
49d8c599 | 532 | config.driver_data = di; |
91f23d8f HS |
533 | config.of_node = np; |
534 | ||
49d8c599 YZ |
535 | ret = fan53555_regulator_register(di, &config); |
536 | if (ret < 0) | |
537 | dev_err(&client->dev, "Failed to register regulator!\n"); | |
538 | return ret; | |
539 | ||
540 | } | |
541 | ||
49d8c599 | 542 | static const struct i2c_device_id fan53555_id[] = { |
ee30928a | 543 | { |
f2a9eb97 BA |
544 | .name = "fan53526", |
545 | .driver_data = FAN53526_VENDOR_FAIRCHILD | |
546 | }, { | |
ee30928a HS |
547 | .name = "fan53555", |
548 | .driver_data = FAN53555_VENDOR_FAIRCHILD | |
549 | }, { | |
fc1111b8 GT |
550 | .name = "syr827", |
551 | .driver_data = FAN53555_VENDOR_SILERGY | |
552 | }, { | |
553 | .name = "syr828", | |
ee30928a HS |
554 | .driver_data = FAN53555_VENDOR_SILERGY |
555 | }, | |
49d8c599 YZ |
556 | { }, |
557 | }; | |
e80c47bd | 558 | MODULE_DEVICE_TABLE(i2c, fan53555_id); |
49d8c599 YZ |
559 | |
560 | static struct i2c_driver fan53555_regulator_driver = { | |
561 | .driver = { | |
562 | .name = "fan53555-regulator", | |
91f23d8f | 563 | .of_match_table = of_match_ptr(fan53555_dt_ids), |
49d8c599 YZ |
564 | }, |
565 | .probe = fan53555_regulator_probe, | |
49d8c599 YZ |
566 | .id_table = fan53555_id, |
567 | }; | |
568 | ||
569 | module_i2c_driver(fan53555_regulator_driver); | |
570 | ||
571 | MODULE_AUTHOR("Yunfan Zhang <yfzhang@marvell.com>"); | |
572 | MODULE_DESCRIPTION("FAN53555 regulator driver"); | |
573 | MODULE_LICENSE("GPL v2"); |