1*e54cf6dbSElaine Zhang // SPDX-License-Identifier: GPL-2.0
2*e54cf6dbSElaine Zhang /*
3*e54cf6dbSElaine Zhang * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd
4*e54cf6dbSElaine Zhang */
5*e54cf6dbSElaine Zhang #include <common.h>
6*e54cf6dbSElaine Zhang #include <dm.h>
7*e54cf6dbSElaine Zhang #include <errno.h>
8*e54cf6dbSElaine Zhang #include <asm/gpio.h>
9*e54cf6dbSElaine Zhang #include <power/regulator.h>
10*e54cf6dbSElaine Zhang #include <i2c.h>
11*e54cf6dbSElaine Zhang #include <asm/arch/clock.h>
12*e54cf6dbSElaine Zhang #include <asm/io.h>
13*e54cf6dbSElaine Zhang #include <syscon.h>
14*e54cf6dbSElaine Zhang
15*e54cf6dbSElaine Zhang DECLARE_GLOBAL_DATA_PTR;
16*e54cf6dbSElaine Zhang
17*e54cf6dbSElaine Zhang /* Voltage setting */
18*e54cf6dbSElaine Zhang #define FAN53555_VSEL0 0x00
19*e54cf6dbSElaine Zhang #define FAN53555_VSEL1 0x01
20*e54cf6dbSElaine Zhang
21*e54cf6dbSElaine Zhang #define TCS452X_VSEL0 0x11
22*e54cf6dbSElaine Zhang #define TCS452X_VSEL1 0x10
23*e54cf6dbSElaine Zhang #define TCS452X_TIME 0x13
24*e54cf6dbSElaine Zhang #define TCS452X_COMMAND 0x14
25*e54cf6dbSElaine Zhang
26*e54cf6dbSElaine Zhang /* Control register */
27*e54cf6dbSElaine Zhang #define FAN53555_CONTROL 0x02
28*e54cf6dbSElaine Zhang /* IC Type */
29*e54cf6dbSElaine Zhang #define FAN53555_ID1 0x03
30*e54cf6dbSElaine Zhang /* IC mask version */
31*e54cf6dbSElaine Zhang #define FAN53555_ID2 0x04
32*e54cf6dbSElaine Zhang /* Monitor register */
33*e54cf6dbSElaine Zhang #define FAN53555_MONITOR 0x05
34*e54cf6dbSElaine Zhang
35*e54cf6dbSElaine Zhang /* VSEL bit definitions */
36*e54cf6dbSElaine Zhang #define VSEL_BUCK_EN BIT(7)
37*e54cf6dbSElaine Zhang #define VSEL_MODE BIT(6)
38*e54cf6dbSElaine Zhang #define VSEL_NSEL_MASK 0x3F
39*e54cf6dbSElaine Zhang
40*e54cf6dbSElaine Zhang /* Chip ID and Version */
41*e54cf6dbSElaine Zhang #define DIE_ID 0x0F/* ID1 */
42*e54cf6dbSElaine Zhang #define DIE_REV 0x0F/* ID2 */
43*e54cf6dbSElaine Zhang /* Control bit definitions */
44*e54cf6dbSElaine Zhang #define CTL_OUTPUT_DISCHG BIT(7)
45*e54cf6dbSElaine Zhang #define CTL_SLEW_MASK (0x7 << 4)
46*e54cf6dbSElaine Zhang #define CTL_SLEW_SHIFT 4
47*e54cf6dbSElaine Zhang #define CTL_RESET BIT(2)
48*e54cf6dbSElaine Zhang
49*e54cf6dbSElaine Zhang #define TCS_VSEL_NSEL_MASK 0x7f
50*e54cf6dbSElaine Zhang #define TCS_VSEL0_MODE BIT(7)
51*e54cf6dbSElaine Zhang #define TCS_VSEL1_MODE BIT(6)
52*e54cf6dbSElaine Zhang
53*e54cf6dbSElaine Zhang #define TCS_SLEW_SHIFT 3
54*e54cf6dbSElaine Zhang #define TCS_SLEW_MASK (0x3 < 3)
55*e54cf6dbSElaine Zhang
56*e54cf6dbSElaine Zhang #define FAN53555_NVOLTAGES_64 64/* Numbers of voltages */
57*e54cf6dbSElaine Zhang #define FAN53555_NVOLTAGES_127 127/* Numbers of voltages */
58*e54cf6dbSElaine Zhang
59*e54cf6dbSElaine Zhang enum fan53555_vendor {
60*e54cf6dbSElaine Zhang FAN53555_VENDOR_FAIRCHILD = 0,
61*e54cf6dbSElaine Zhang FAN53555_VENDOR_SILERGY,
62*e54cf6dbSElaine Zhang FAN53555_VENDOR_TCS,
63*e54cf6dbSElaine Zhang };
64*e54cf6dbSElaine Zhang
65*e54cf6dbSElaine Zhang /* IC Type */
66*e54cf6dbSElaine Zhang enum {
67*e54cf6dbSElaine Zhang FAN53555_CHIP_ID_00 = 0,
68*e54cf6dbSElaine Zhang FAN53555_CHIP_ID_01,
69*e54cf6dbSElaine Zhang FAN53555_CHIP_ID_02,
70*e54cf6dbSElaine Zhang FAN53555_CHIP_ID_03,
71*e54cf6dbSElaine Zhang FAN53555_CHIP_ID_04,
72*e54cf6dbSElaine Zhang FAN53555_CHIP_ID_05,
73*e54cf6dbSElaine Zhang FAN53555_CHIP_ID_08 = 8,
74*e54cf6dbSElaine Zhang };
75*e54cf6dbSElaine Zhang
76*e54cf6dbSElaine Zhang /* IC mask revision */
77*e54cf6dbSElaine Zhang enum {
78*e54cf6dbSElaine Zhang FAN53555_CHIP_REV_00 = 0x3,
79*e54cf6dbSElaine Zhang FAN53555_CHIP_REV_13 = 0xf,
80*e54cf6dbSElaine Zhang };
81*e54cf6dbSElaine Zhang
82*e54cf6dbSElaine Zhang enum {
83*e54cf6dbSElaine Zhang SILERGY_SYR82X = 8,
84*e54cf6dbSElaine Zhang };
85*e54cf6dbSElaine Zhang
86*e54cf6dbSElaine Zhang enum {
87*e54cf6dbSElaine Zhang FAN53555_VSEL_ID_0 = 0,
88*e54cf6dbSElaine Zhang FAN53555_VSEL_ID_1,
89*e54cf6dbSElaine Zhang };
90*e54cf6dbSElaine Zhang
91*e54cf6dbSElaine Zhang struct fan53555_regulator_info {
92*e54cf6dbSElaine Zhang enum fan53555_vendor vendor;
93*e54cf6dbSElaine Zhang struct udevice *dev;
94*e54cf6dbSElaine Zhang /* IC Type and Rev */
95*e54cf6dbSElaine Zhang int chip_id;
96*e54cf6dbSElaine Zhang int chip_rev;
97*e54cf6dbSElaine Zhang /* Voltage setting register */
98*e54cf6dbSElaine Zhang unsigned int vol_reg;
99*e54cf6dbSElaine Zhang unsigned int sleep_reg;
100*e54cf6dbSElaine Zhang unsigned int mode_reg;
101*e54cf6dbSElaine Zhang unsigned int vol_mask;
102*e54cf6dbSElaine Zhang unsigned int mode_mask;
103*e54cf6dbSElaine Zhang /* Voltage range and step(linear) */
104*e54cf6dbSElaine Zhang unsigned int vsel_min;
105*e54cf6dbSElaine Zhang unsigned int vsel_step;
106*e54cf6dbSElaine Zhang struct gpio_desc vsel_gpio;
107*e54cf6dbSElaine Zhang unsigned int sleep_vsel_id;
108*e54cf6dbSElaine Zhang };
109*e54cf6dbSElaine Zhang
fan53555_write(struct udevice * dev,uint reg,const uint8_t * buff,int len)110*e54cf6dbSElaine Zhang static int fan53555_write(struct udevice *dev, uint reg, const uint8_t *buff,
111*e54cf6dbSElaine Zhang int len)
112*e54cf6dbSElaine Zhang {
113*e54cf6dbSElaine Zhang int ret;
114*e54cf6dbSElaine Zhang
115*e54cf6dbSElaine Zhang ret = dm_i2c_write(dev, reg, buff, len);
116*e54cf6dbSElaine Zhang if (ret) {
117*e54cf6dbSElaine Zhang debug("%s: write reg 0x%02x failed, ret=%d\n",
118*e54cf6dbSElaine Zhang __func__, reg, ret);
119*e54cf6dbSElaine Zhang return ret;
120*e54cf6dbSElaine Zhang }
121*e54cf6dbSElaine Zhang
122*e54cf6dbSElaine Zhang return 0;
123*e54cf6dbSElaine Zhang }
124*e54cf6dbSElaine Zhang
fan53555_read(struct udevice * dev,uint reg,uint8_t * buff,int len)125*e54cf6dbSElaine Zhang static int fan53555_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
126*e54cf6dbSElaine Zhang {
127*e54cf6dbSElaine Zhang int ret;
128*e54cf6dbSElaine Zhang
129*e54cf6dbSElaine Zhang ret = dm_i2c_read(dev, reg, buff, len);
130*e54cf6dbSElaine Zhang if (ret) {
131*e54cf6dbSElaine Zhang debug("%s: read reg 0x%02x failed, ret=%d\n",
132*e54cf6dbSElaine Zhang __func__, reg, ret);
133*e54cf6dbSElaine Zhang return ret;
134*e54cf6dbSElaine Zhang }
135*e54cf6dbSElaine Zhang
136*e54cf6dbSElaine Zhang return 0;
137*e54cf6dbSElaine Zhang }
138*e54cf6dbSElaine Zhang
fan53555_reg_read(struct udevice * dev,uint reg)139*e54cf6dbSElaine Zhang int fan53555_reg_read(struct udevice *dev, uint reg)
140*e54cf6dbSElaine Zhang {
141*e54cf6dbSElaine Zhang u8 byte;
142*e54cf6dbSElaine Zhang int ret;
143*e54cf6dbSElaine Zhang
144*e54cf6dbSElaine Zhang debug("%s: reg=%x", __func__, reg);
145*e54cf6dbSElaine Zhang ret = fan53555_read(dev, reg, &byte, 1);
146*e54cf6dbSElaine Zhang debug(", value=%x, ret=%d\n", byte, ret);
147*e54cf6dbSElaine Zhang
148*e54cf6dbSElaine Zhang return ret ? ret : byte;
149*e54cf6dbSElaine Zhang }
150*e54cf6dbSElaine Zhang
fan53555_reg_write(struct udevice * dev,uint reg,uint value)151*e54cf6dbSElaine Zhang int fan53555_reg_write(struct udevice *dev, uint reg, uint value)
152*e54cf6dbSElaine Zhang {
153*e54cf6dbSElaine Zhang u8 byte = value;
154*e54cf6dbSElaine Zhang int ret;
155*e54cf6dbSElaine Zhang
156*e54cf6dbSElaine Zhang debug("%s: reg=%x, value=%x", __func__, reg, value);
157*e54cf6dbSElaine Zhang ret = fan53555_write(dev, reg, &byte, 1);
158*e54cf6dbSElaine Zhang debug(", ret=%d\n", ret);
159*e54cf6dbSElaine Zhang
160*e54cf6dbSElaine Zhang return ret;
161*e54cf6dbSElaine Zhang }
162*e54cf6dbSElaine Zhang
fan53555_clrsetbits(struct udevice * dev,uint reg,uint clr,uint set)163*e54cf6dbSElaine Zhang int fan53555_clrsetbits(struct udevice *dev, uint reg, uint clr, uint set)
164*e54cf6dbSElaine Zhang {
165*e54cf6dbSElaine Zhang u8 byte;
166*e54cf6dbSElaine Zhang int ret;
167*e54cf6dbSElaine Zhang
168*e54cf6dbSElaine Zhang ret = fan53555_reg_read(dev, reg);
169*e54cf6dbSElaine Zhang if (ret < 0)
170*e54cf6dbSElaine Zhang return ret;
171*e54cf6dbSElaine Zhang byte = (ret & ~clr) | set;
172*e54cf6dbSElaine Zhang
173*e54cf6dbSElaine Zhang return fan53555_reg_write(dev, reg, byte);
174*e54cf6dbSElaine Zhang }
175*e54cf6dbSElaine Zhang
fan53555_regulator_set_enable(struct udevice * dev,bool enable)176*e54cf6dbSElaine Zhang static int fan53555_regulator_set_enable(struct udevice *dev, bool enable)
177*e54cf6dbSElaine Zhang {
178*e54cf6dbSElaine Zhang struct fan53555_regulator_info *priv = dev_get_priv(dev);
179*e54cf6dbSElaine Zhang int val, sleep_vsel_id;
180*e54cf6dbSElaine Zhang
181*e54cf6dbSElaine Zhang if (enable) {
182*e54cf6dbSElaine Zhang val = VSEL_BUCK_EN;
183*e54cf6dbSElaine Zhang sleep_vsel_id = !priv->sleep_vsel_id;
184*e54cf6dbSElaine Zhang } else {
185*e54cf6dbSElaine Zhang val = 0;
186*e54cf6dbSElaine Zhang sleep_vsel_id = priv->sleep_vsel_id;
187*e54cf6dbSElaine Zhang }
188*e54cf6dbSElaine Zhang
189*e54cf6dbSElaine Zhang if (dm_gpio_is_valid(&priv->vsel_gpio)) {
190*e54cf6dbSElaine Zhang dm_gpio_set_value(&priv->vsel_gpio, sleep_vsel_id);
191*e54cf6dbSElaine Zhang return 0;
192*e54cf6dbSElaine Zhang }
193*e54cf6dbSElaine Zhang fan53555_clrsetbits(dev, priv->vol_reg, VSEL_BUCK_EN, val);
194*e54cf6dbSElaine Zhang
195*e54cf6dbSElaine Zhang return 0;
196*e54cf6dbSElaine Zhang }
197*e54cf6dbSElaine Zhang
fan53555_regulator_get_enable(struct udevice * dev)198*e54cf6dbSElaine Zhang static int fan53555_regulator_get_enable(struct udevice *dev)
199*e54cf6dbSElaine Zhang {
200*e54cf6dbSElaine Zhang struct fan53555_regulator_info *priv = dev_get_priv(dev);
201*e54cf6dbSElaine Zhang int val;
202*e54cf6dbSElaine Zhang
203*e54cf6dbSElaine Zhang if (dm_gpio_is_valid(&priv->vsel_gpio)) {
204*e54cf6dbSElaine Zhang if (priv->sleep_vsel_id)
205*e54cf6dbSElaine Zhang return !dm_gpio_get_value(&priv->vsel_gpio);
206*e54cf6dbSElaine Zhang else
207*e54cf6dbSElaine Zhang return dm_gpio_get_value(&priv->vsel_gpio);
208*e54cf6dbSElaine Zhang }
209*e54cf6dbSElaine Zhang
210*e54cf6dbSElaine Zhang val = fan53555_reg_read(dev, priv->vol_reg);
211*e54cf6dbSElaine Zhang if (val & VSEL_BUCK_EN)
212*e54cf6dbSElaine Zhang return 1;
213*e54cf6dbSElaine Zhang else
214*e54cf6dbSElaine Zhang return 0;
215*e54cf6dbSElaine Zhang }
216*e54cf6dbSElaine Zhang
fan53555_regulator_set_suspend_enable(struct udevice * dev,bool enable)217*e54cf6dbSElaine Zhang static int fan53555_regulator_set_suspend_enable(struct udevice *dev,
218*e54cf6dbSElaine Zhang bool enable)
219*e54cf6dbSElaine Zhang {
220*e54cf6dbSElaine Zhang struct fan53555_regulator_info *priv = dev_get_priv(dev);
221*e54cf6dbSElaine Zhang int val;
222*e54cf6dbSElaine Zhang
223*e54cf6dbSElaine Zhang if (enable)
224*e54cf6dbSElaine Zhang val = VSEL_BUCK_EN;
225*e54cf6dbSElaine Zhang else
226*e54cf6dbSElaine Zhang val = 0;
227*e54cf6dbSElaine Zhang
228*e54cf6dbSElaine Zhang fan53555_clrsetbits(dev, priv->sleep_reg, VSEL_BUCK_EN, val);
229*e54cf6dbSElaine Zhang
230*e54cf6dbSElaine Zhang return 0;
231*e54cf6dbSElaine Zhang }
232*e54cf6dbSElaine Zhang
fan53555_regulator_get_suspend_enable(struct udevice * dev)233*e54cf6dbSElaine Zhang static int fan53555_regulator_get_suspend_enable(struct udevice *dev)
234*e54cf6dbSElaine Zhang {
235*e54cf6dbSElaine Zhang struct fan53555_regulator_info *priv = dev_get_priv(dev);
236*e54cf6dbSElaine Zhang int val;
237*e54cf6dbSElaine Zhang
238*e54cf6dbSElaine Zhang val = fan53555_reg_read(dev, priv->sleep_reg);
239*e54cf6dbSElaine Zhang if (val & VSEL_BUCK_EN)
240*e54cf6dbSElaine Zhang return 1;
241*e54cf6dbSElaine Zhang else
242*e54cf6dbSElaine Zhang return 0;
243*e54cf6dbSElaine Zhang }
244*e54cf6dbSElaine Zhang
fan53555_regulator_get_voltage(struct udevice * dev)245*e54cf6dbSElaine Zhang static int fan53555_regulator_get_voltage(struct udevice *dev)
246*e54cf6dbSElaine Zhang {
247*e54cf6dbSElaine Zhang struct fan53555_regulator_info *priv = dev_get_priv(dev);
248*e54cf6dbSElaine Zhang int uvolt = 0, val;
249*e54cf6dbSElaine Zhang
250*e54cf6dbSElaine Zhang val = fan53555_reg_read(dev, priv->vol_reg);
251*e54cf6dbSElaine Zhang val &= priv->vol_mask;
252*e54cf6dbSElaine Zhang uvolt = (val * priv->vsel_step) + priv->vsel_min;
253*e54cf6dbSElaine Zhang
254*e54cf6dbSElaine Zhang return uvolt;
255*e54cf6dbSElaine Zhang }
256*e54cf6dbSElaine Zhang
fan53555_regulator_set_voltage(struct udevice * dev,int uvolt)257*e54cf6dbSElaine Zhang static int fan53555_regulator_set_voltage(struct udevice *dev, int uvolt)
258*e54cf6dbSElaine Zhang {
259*e54cf6dbSElaine Zhang struct fan53555_regulator_info *priv = dev_get_priv(dev);
260*e54cf6dbSElaine Zhang int val;
261*e54cf6dbSElaine Zhang
262*e54cf6dbSElaine Zhang val = ((uvolt - priv->vsel_min) / priv->vsel_step);
263*e54cf6dbSElaine Zhang fan53555_clrsetbits(dev, priv->vol_reg, priv->vol_mask, val);
264*e54cf6dbSElaine Zhang
265*e54cf6dbSElaine Zhang return 0;
266*e54cf6dbSElaine Zhang }
267*e54cf6dbSElaine Zhang
fan53555_regulator_get_suspend_voltage(struct udevice * dev)268*e54cf6dbSElaine Zhang static int fan53555_regulator_get_suspend_voltage(struct udevice *dev)
269*e54cf6dbSElaine Zhang {
270*e54cf6dbSElaine Zhang struct fan53555_regulator_info *priv = dev_get_priv(dev);
271*e54cf6dbSElaine Zhang int uvolt = 0, val;
272*e54cf6dbSElaine Zhang
273*e54cf6dbSElaine Zhang val = fan53555_reg_read(dev, priv->sleep_reg);
274*e54cf6dbSElaine Zhang val &= priv->vol_mask;
275*e54cf6dbSElaine Zhang uvolt = (val * priv->vsel_step) + priv->vsel_min;
276*e54cf6dbSElaine Zhang
277*e54cf6dbSElaine Zhang return uvolt;
278*e54cf6dbSElaine Zhang }
279*e54cf6dbSElaine Zhang
fan53555_regulator_set_suspend_voltage(struct udevice * dev,int uvolt)280*e54cf6dbSElaine Zhang static int fan53555_regulator_set_suspend_voltage(struct udevice *dev,
281*e54cf6dbSElaine Zhang int uvolt)
282*e54cf6dbSElaine Zhang {
283*e54cf6dbSElaine Zhang struct fan53555_regulator_info *priv = dev_get_priv(dev);
284*e54cf6dbSElaine Zhang int val;
285*e54cf6dbSElaine Zhang
286*e54cf6dbSElaine Zhang val = ((uvolt - priv->vsel_min) / priv->vsel_step);
287*e54cf6dbSElaine Zhang fan53555_clrsetbits(dev, priv->sleep_reg, priv->vol_mask, val);
288*e54cf6dbSElaine Zhang
289*e54cf6dbSElaine Zhang return 0;
290*e54cf6dbSElaine Zhang }
291*e54cf6dbSElaine Zhang
fan53555_voltages_setup_fairchild(struct fan53555_regulator_info * di)292*e54cf6dbSElaine Zhang static int fan53555_voltages_setup_fairchild(struct fan53555_regulator_info *di)
293*e54cf6dbSElaine Zhang {
294*e54cf6dbSElaine Zhang /* Init voltage range and step */
295*e54cf6dbSElaine Zhang switch (di->chip_id) {
296*e54cf6dbSElaine Zhang case FAN53555_CHIP_ID_00:
297*e54cf6dbSElaine Zhang switch (di->chip_rev) {
298*e54cf6dbSElaine Zhang case FAN53555_CHIP_REV_00:
299*e54cf6dbSElaine Zhang di->vsel_min = 600000;
300*e54cf6dbSElaine Zhang di->vsel_step = 10000;
301*e54cf6dbSElaine Zhang break;
302*e54cf6dbSElaine Zhang case FAN53555_CHIP_REV_13:
303*e54cf6dbSElaine Zhang di->vsel_min = 800000;
304*e54cf6dbSElaine Zhang di->vsel_step = 10000;
305*e54cf6dbSElaine Zhang break;
306*e54cf6dbSElaine Zhang default:
307*e54cf6dbSElaine Zhang dev_err(di->dev,
308*e54cf6dbSElaine Zhang "Chip ID %d with rev %d not supported!\n",
309*e54cf6dbSElaine Zhang di->chip_id, di->chip_rev);
310*e54cf6dbSElaine Zhang return -EINVAL;
311*e54cf6dbSElaine Zhang }
312*e54cf6dbSElaine Zhang break;
313*e54cf6dbSElaine Zhang case FAN53555_CHIP_ID_01:
314*e54cf6dbSElaine Zhang case FAN53555_CHIP_ID_03:
315*e54cf6dbSElaine Zhang case FAN53555_CHIP_ID_05:
316*e54cf6dbSElaine Zhang case FAN53555_CHIP_ID_08:
317*e54cf6dbSElaine Zhang di->vsel_min = 600000;
318*e54cf6dbSElaine Zhang di->vsel_step = 10000;
319*e54cf6dbSElaine Zhang break;
320*e54cf6dbSElaine Zhang case FAN53555_CHIP_ID_04:
321*e54cf6dbSElaine Zhang di->vsel_min = 603000;
322*e54cf6dbSElaine Zhang di->vsel_step = 12826;
323*e54cf6dbSElaine Zhang break;
324*e54cf6dbSElaine Zhang default:
325*e54cf6dbSElaine Zhang dev_err(di->dev,
326*e54cf6dbSElaine Zhang "Chip ID %d not supported!\n", di->chip_id);
327*e54cf6dbSElaine Zhang return -EINVAL;
328*e54cf6dbSElaine Zhang }
329*e54cf6dbSElaine Zhang di->vol_mask = VSEL_NSEL_MASK;
330*e54cf6dbSElaine Zhang
331*e54cf6dbSElaine Zhang return 0;
332*e54cf6dbSElaine Zhang }
333*e54cf6dbSElaine Zhang
fan53555_voltages_setup_silergy(struct fan53555_regulator_info * di)334*e54cf6dbSElaine Zhang static int fan53555_voltages_setup_silergy(struct fan53555_regulator_info *di)
335*e54cf6dbSElaine Zhang {
336*e54cf6dbSElaine Zhang /* Init voltage range and step */
337*e54cf6dbSElaine Zhang di->vsel_min = 712500;
338*e54cf6dbSElaine Zhang di->vsel_step = 12500;
339*e54cf6dbSElaine Zhang di->vol_mask = VSEL_NSEL_MASK;
340*e54cf6dbSElaine Zhang
341*e54cf6dbSElaine Zhang return 0;
342*e54cf6dbSElaine Zhang }
343*e54cf6dbSElaine Zhang
fan53555_voltages_setup_tcs(struct fan53555_regulator_info * di)344*e54cf6dbSElaine Zhang static int fan53555_voltages_setup_tcs(struct fan53555_regulator_info *di)
345*e54cf6dbSElaine Zhang {
346*e54cf6dbSElaine Zhang if (di->sleep_vsel_id) {
347*e54cf6dbSElaine Zhang di->sleep_reg = TCS452X_VSEL1;
348*e54cf6dbSElaine Zhang di->vol_reg = TCS452X_VSEL0;
349*e54cf6dbSElaine Zhang } else {
350*e54cf6dbSElaine Zhang di->sleep_reg = TCS452X_VSEL0;
351*e54cf6dbSElaine Zhang di->vol_reg = TCS452X_VSEL1;
352*e54cf6dbSElaine Zhang }
353*e54cf6dbSElaine Zhang
354*e54cf6dbSElaine Zhang di->vol_mask = TCS_VSEL_NSEL_MASK;
355*e54cf6dbSElaine Zhang
356*e54cf6dbSElaine Zhang /* Init voltage range and step */
357*e54cf6dbSElaine Zhang di->vsel_min = 600000;
358*e54cf6dbSElaine Zhang di->vsel_step = 6250;
359*e54cf6dbSElaine Zhang
360*e54cf6dbSElaine Zhang return 0;
361*e54cf6dbSElaine Zhang }
362*e54cf6dbSElaine Zhang
363*e54cf6dbSElaine Zhang /* For 00,01,03,05 options:
364*e54cf6dbSElaine Zhang * VOUT = 0.60V + NSELx * 10mV, from 0.60 to 1.23V.
365*e54cf6dbSElaine Zhang * For 04 option:
366*e54cf6dbSElaine Zhang * VOUT = 0.603V + NSELx * 12.826mV, from 0.603 to 1.411V.
367*e54cf6dbSElaine Zhang *
368*e54cf6dbSElaine Zhang */
369*e54cf6dbSElaine Zhang
fan53555_device_setup(struct fan53555_regulator_info * di)370*e54cf6dbSElaine Zhang static int fan53555_device_setup(struct fan53555_regulator_info *di)
371*e54cf6dbSElaine Zhang {
372*e54cf6dbSElaine Zhang int ret = 0;
373*e54cf6dbSElaine Zhang
374*e54cf6dbSElaine Zhang /* Setup voltage control register */
375*e54cf6dbSElaine Zhang switch (di->sleep_vsel_id) {
376*e54cf6dbSElaine Zhang case FAN53555_VSEL_ID_0:
377*e54cf6dbSElaine Zhang di->sleep_reg = FAN53555_VSEL0;
378*e54cf6dbSElaine Zhang di->vol_reg = FAN53555_VSEL1;
379*e54cf6dbSElaine Zhang break;
380*e54cf6dbSElaine Zhang case FAN53555_VSEL_ID_1:
381*e54cf6dbSElaine Zhang di->sleep_reg = FAN53555_VSEL1;
382*e54cf6dbSElaine Zhang di->vol_reg = FAN53555_VSEL0;
383*e54cf6dbSElaine Zhang break;
384*e54cf6dbSElaine Zhang default:
385*e54cf6dbSElaine Zhang dev_err(di->dev, "Invalid VSEL ID!\n");
386*e54cf6dbSElaine Zhang return -EINVAL;
387*e54cf6dbSElaine Zhang }
388*e54cf6dbSElaine Zhang
389*e54cf6dbSElaine Zhang switch (di->vendor) {
390*e54cf6dbSElaine Zhang case FAN53555_VENDOR_FAIRCHILD:
391*e54cf6dbSElaine Zhang ret = fan53555_voltages_setup_fairchild(di);
392*e54cf6dbSElaine Zhang break;
393*e54cf6dbSElaine Zhang case FAN53555_VENDOR_SILERGY:
394*e54cf6dbSElaine Zhang ret = fan53555_voltages_setup_silergy(di);
395*e54cf6dbSElaine Zhang break;
396*e54cf6dbSElaine Zhang case FAN53555_VENDOR_TCS:
397*e54cf6dbSElaine Zhang ret = fan53555_voltages_setup_tcs(di);
398*e54cf6dbSElaine Zhang break;
399*e54cf6dbSElaine Zhang default:
400*e54cf6dbSElaine Zhang dev_err(di->dev, "vendor %d not supported!\n", di->vendor);
401*e54cf6dbSElaine Zhang return -EINVAL;
402*e54cf6dbSElaine Zhang }
403*e54cf6dbSElaine Zhang
404*e54cf6dbSElaine Zhang return ret;
405*e54cf6dbSElaine Zhang }
406*e54cf6dbSElaine Zhang
fan53555_regulator_ofdata_to_platdata(struct udevice * dev)407*e54cf6dbSElaine Zhang static int fan53555_regulator_ofdata_to_platdata(struct udevice *dev)
408*e54cf6dbSElaine Zhang {
409*e54cf6dbSElaine Zhang struct fan53555_regulator_info *priv = dev_get_priv(dev);
410*e54cf6dbSElaine Zhang int ret;
411*e54cf6dbSElaine Zhang
412*e54cf6dbSElaine Zhang priv->sleep_vsel_id = dev_read_u32_default(dev,
413*e54cf6dbSElaine Zhang "fcs,suspend-voltage-selector",
414*e54cf6dbSElaine Zhang 1);
415*e54cf6dbSElaine Zhang
416*e54cf6dbSElaine Zhang ret = gpio_request_by_name(dev, "vsel-gpios", 0,
417*e54cf6dbSElaine Zhang &priv->vsel_gpio, GPIOD_IS_OUT);
418*e54cf6dbSElaine Zhang if (ret)
419*e54cf6dbSElaine Zhang dev_err(dev, "vsel-gpios- not found! Error: %d\n", ret);
420*e54cf6dbSElaine Zhang
421*e54cf6dbSElaine Zhang if (dm_gpio_is_valid(&priv->vsel_gpio))
422*e54cf6dbSElaine Zhang dm_gpio_set_value(&priv->vsel_gpio, !priv->sleep_vsel_id);
423*e54cf6dbSElaine Zhang
424*e54cf6dbSElaine Zhang priv->vendor = dev_get_driver_data(dev);
425*e54cf6dbSElaine Zhang
426*e54cf6dbSElaine Zhang return 0;
427*e54cf6dbSElaine Zhang }
428*e54cf6dbSElaine Zhang
fan53555_regulator_probe(struct udevice * dev)429*e54cf6dbSElaine Zhang static int fan53555_regulator_probe(struct udevice *dev)
430*e54cf6dbSElaine Zhang {
431*e54cf6dbSElaine Zhang struct fan53555_regulator_info *di = dev_get_priv(dev);
432*e54cf6dbSElaine Zhang struct dm_regulator_uclass_platdata *uc_pdata;
433*e54cf6dbSElaine Zhang u8 val;
434*e54cf6dbSElaine Zhang int ret;
435*e54cf6dbSElaine Zhang
436*e54cf6dbSElaine Zhang uc_pdata = dev_get_uclass_platdata(dev);
437*e54cf6dbSElaine Zhang uc_pdata->type = REGULATOR_TYPE_BUCK;
438*e54cf6dbSElaine Zhang uc_pdata->mode_count = 0;
439*e54cf6dbSElaine Zhang
440*e54cf6dbSElaine Zhang /* Get chip ID */
441*e54cf6dbSElaine Zhang val = fan53555_reg_read(dev, FAN53555_ID1);
442*e54cf6dbSElaine Zhang if (val < 0) {
443*e54cf6dbSElaine Zhang dev_err(dev, "Failed to get chip ID!\n");
444*e54cf6dbSElaine Zhang return val;
445*e54cf6dbSElaine Zhang }
446*e54cf6dbSElaine Zhang di->chip_id = val & DIE_ID;
447*e54cf6dbSElaine Zhang
448*e54cf6dbSElaine Zhang /* Get chip revision */
449*e54cf6dbSElaine Zhang val = fan53555_reg_read(dev, FAN53555_ID2);
450*e54cf6dbSElaine Zhang if (val < 0) {
451*e54cf6dbSElaine Zhang dev_err(dev, "Failed to get chip Rev!\n");
452*e54cf6dbSElaine Zhang return val;
453*e54cf6dbSElaine Zhang }
454*e54cf6dbSElaine Zhang di->chip_rev = val & DIE_REV;
455*e54cf6dbSElaine Zhang
456*e54cf6dbSElaine Zhang debug("FAN53555 Option[%d] Rev[%d] Detected!\n",
457*e54cf6dbSElaine Zhang di->chip_id, di->chip_rev);
458*e54cf6dbSElaine Zhang
459*e54cf6dbSElaine Zhang /* Device init */
460*e54cf6dbSElaine Zhang ret = fan53555_device_setup(di);
461*e54cf6dbSElaine Zhang if (ret < 0) {
462*e54cf6dbSElaine Zhang dev_err(dev, "Failed to setup device!\n");
463*e54cf6dbSElaine Zhang return ret;
464*e54cf6dbSElaine Zhang }
465*e54cf6dbSElaine Zhang
466*e54cf6dbSElaine Zhang return 0;
467*e54cf6dbSElaine Zhang }
468*e54cf6dbSElaine Zhang
469*e54cf6dbSElaine Zhang static const struct udevice_id fan53555_id[] = {
470*e54cf6dbSElaine Zhang {
471*e54cf6dbSElaine Zhang .compatible = "fan53555",
472*e54cf6dbSElaine Zhang .data = FAN53555_VENDOR_FAIRCHILD,
473*e54cf6dbSElaine Zhang }, {
474*e54cf6dbSElaine Zhang .compatible = "silergy,syr827",
475*e54cf6dbSElaine Zhang .data = FAN53555_VENDOR_SILERGY,
476*e54cf6dbSElaine Zhang }, {
477*e54cf6dbSElaine Zhang .compatible = "silergy,syr828",
478*e54cf6dbSElaine Zhang .data = FAN53555_VENDOR_SILERGY,
479*e54cf6dbSElaine Zhang }, {
480*e54cf6dbSElaine Zhang .compatible = "tcs,tcs452x", /* tcs4525/4526 */
481*e54cf6dbSElaine Zhang .data = FAN53555_VENDOR_TCS,
482*e54cf6dbSElaine Zhang },
483*e54cf6dbSElaine Zhang { },
484*e54cf6dbSElaine Zhang };
485*e54cf6dbSElaine Zhang
486*e54cf6dbSElaine Zhang static const struct dm_regulator_ops fan53555_regulator_ops = {
487*e54cf6dbSElaine Zhang .get_value = fan53555_regulator_get_voltage,
488*e54cf6dbSElaine Zhang .set_value = fan53555_regulator_set_voltage,
489*e54cf6dbSElaine Zhang .set_suspend_value = fan53555_regulator_set_suspend_voltage,
490*e54cf6dbSElaine Zhang .get_suspend_value = fan53555_regulator_get_suspend_voltage,
491*e54cf6dbSElaine Zhang .set_enable = fan53555_regulator_set_enable,
492*e54cf6dbSElaine Zhang .get_enable = fan53555_regulator_get_enable,
493*e54cf6dbSElaine Zhang .set_suspend_enable = fan53555_regulator_set_suspend_enable,
494*e54cf6dbSElaine Zhang .get_suspend_enable = fan53555_regulator_get_suspend_enable,
495*e54cf6dbSElaine Zhang };
496*e54cf6dbSElaine Zhang
497*e54cf6dbSElaine Zhang U_BOOT_DRIVER(fan53555_regulator) = {
498*e54cf6dbSElaine Zhang .name = "fan53555_regulator",
499*e54cf6dbSElaine Zhang .id = UCLASS_REGULATOR,
500*e54cf6dbSElaine Zhang .ops = &fan53555_regulator_ops,
501*e54cf6dbSElaine Zhang .probe = fan53555_regulator_probe,
502*e54cf6dbSElaine Zhang .of_match = fan53555_id,
503*e54cf6dbSElaine Zhang .ofdata_to_platdata = fan53555_regulator_ofdata_to_platdata,
504*e54cf6dbSElaine Zhang .priv_auto_alloc_size = sizeof(struct fan53555_regulator_info),
505*e54cf6dbSElaine Zhang };
506*e54cf6dbSElaine Zhang
507