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