]>
Commit | Line | Data |
---|---|---|
22e8f189 TK |
1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* | |
a94a4071 | 3 | * Copyright (C) 2019 Texas Instruments Incorporated - https://www.ti.com/ |
22e8f189 TK |
4 | * Tero Kristo <t-kristo@ti.com> |
5 | */ | |
6 | ||
d678a59d | 7 | #include <common.h> |
22e8f189 TK |
8 | #include <dm.h> |
9 | #include <i2c.h> | |
336d4615 | 10 | #include <dm/device_compat.h> |
22e8f189 TK |
11 | #include <power/regulator.h> |
12 | ||
13 | #define TPS62360_REG_SET0 0 | |
14 | ||
15 | #define TPS62360_I2C_CHIP 0x60 | |
16 | ||
17 | #define TPS62360_VSEL_STEPSIZE 10000 /* In uV */ | |
18 | ||
19 | struct tps62360_regulator_config { | |
20 | u32 vmin; | |
21 | u32 vmax; | |
22 | }; | |
23 | ||
24 | struct tps62360_regulator_pdata { | |
25 | u8 vsel_offset; | |
26 | struct udevice *i2c; | |
27 | struct tps62360_regulator_config *config; | |
28 | }; | |
29 | ||
30 | /* | |
31 | * TPS62362/TPS62363 are just re-using these values for now, their preset | |
32 | * voltage values are just different compared to TPS62360/TPS62361. | |
33 | */ | |
34 | static struct tps62360_regulator_config tps62360_data = { | |
35 | .vmin = 770000, | |
36 | .vmax = 1400000, | |
37 | }; | |
38 | ||
39 | static struct tps62360_regulator_config tps62361_data = { | |
40 | .vmin = 500000, | |
41 | .vmax = 1770000, | |
42 | }; | |
43 | ||
44 | static int tps62360_regulator_set_value(struct udevice *dev, int uV) | |
45 | { | |
c69cda25 | 46 | struct tps62360_regulator_pdata *pdata = dev_get_plat(dev); |
22e8f189 TK |
47 | u8 regval; |
48 | ||
49 | if (uV < pdata->config->vmin || uV > pdata->config->vmax) | |
50 | return -EINVAL; | |
51 | ||
52 | uV -= pdata->config->vmin; | |
53 | ||
54 | uV = DIV_ROUND_UP(uV, TPS62360_VSEL_STEPSIZE); | |
55 | ||
56 | if (uV > U8_MAX) | |
57 | return -EINVAL; | |
58 | ||
59 | regval = (u8)uV; | |
60 | ||
61 | return dm_i2c_write(pdata->i2c, TPS62360_REG_SET0 + pdata->vsel_offset, | |
62 | ®val, 1); | |
63 | } | |
64 | ||
65 | static int tps62360_regulator_get_value(struct udevice *dev) | |
66 | { | |
67 | u8 regval; | |
68 | int ret; | |
c69cda25 | 69 | struct tps62360_regulator_pdata *pdata = dev_get_plat(dev); |
22e8f189 TK |
70 | |
71 | ret = dm_i2c_read(pdata->i2c, TPS62360_REG_SET0 + pdata->vsel_offset, | |
72 | ®val, 1); | |
73 | if (ret) { | |
74 | dev_err(dev, "i2c read failed: %d\n", ret); | |
75 | return ret; | |
76 | } | |
77 | ||
78 | return (u32)regval * TPS62360_VSEL_STEPSIZE + pdata->config->vmin; | |
79 | } | |
80 | ||
17aaa42e | 81 | static int tps62360_regulator_probe(struct udevice *dev) |
22e8f189 | 82 | { |
c69cda25 | 83 | struct tps62360_regulator_pdata *pdata = dev_get_plat(dev); |
22e8f189 TK |
84 | u8 vsel0; |
85 | u8 vsel1; | |
86 | int ret; | |
87 | ||
88 | pdata->config = (void *)dev_get_driver_data(dev); | |
89 | ||
90 | vsel0 = dev_read_bool(dev, "ti,vsel0-state-high"); | |
91 | vsel1 = dev_read_bool(dev, "ti,vsel1-state-high"); | |
92 | ||
93 | pdata->vsel_offset = vsel0 + vsel1 * 2; | |
94 | ||
95 | ret = i2c_get_chip(dev->parent, TPS62360_I2C_CHIP, 1, &pdata->i2c); | |
96 | if (ret) { | |
97 | dev_err(dev, "i2c dev get failed.\n"); | |
98 | return ret; | |
99 | } | |
100 | ||
101 | return 0; | |
102 | } | |
103 | ||
104 | static const struct dm_regulator_ops tps62360_regulator_ops = { | |
105 | .get_value = tps62360_regulator_get_value, | |
106 | .set_value = tps62360_regulator_set_value, | |
107 | }; | |
108 | ||
109 | static const struct udevice_id tps62360_regulator_ids[] = { | |
110 | { .compatible = "ti,tps62360", .data = (ulong)&tps62360_data }, | |
111 | { .compatible = "ti,tps62361", .data = (ulong)&tps62361_data }, | |
112 | { .compatible = "ti,tps62362", .data = (ulong)&tps62360_data }, | |
113 | { .compatible = "ti,tps62363", .data = (ulong)&tps62361_data }, | |
114 | { }, | |
115 | }; | |
116 | ||
117 | U_BOOT_DRIVER(tps62360_regulator) = { | |
118 | .name = "tps62360_regulator", | |
119 | .id = UCLASS_REGULATOR, | |
120 | .ops = &tps62360_regulator_ops, | |
121 | .of_match = tps62360_regulator_ids, | |
caa4daa2 | 122 | .plat_auto = sizeof(struct tps62360_regulator_pdata), |
17aaa42e | 123 | .probe = tps62360_regulator_probe, |
22e8f189 | 124 | }; |