xref: /rk3399_rockchip-uboot/drivers/power/regulator/sy7636a_regulator.c (revision 12e25d6dabb5a12529baaa09009184622210b9bb)
1*12e25d6dSChaoyi Chen // SPDX-License-Identifier: GPL-2.0
2*12e25d6dSChaoyi Chen /*
3*12e25d6dSChaoyi Chen  * Copyright (c) 2024 Rockchip Electronics Co., Ltd.
4*12e25d6dSChaoyi Chen  */
5*12e25d6dSChaoyi Chen 
6*12e25d6dSChaoyi Chen #include <common.h>
7*12e25d6dSChaoyi Chen #include <dm.h>
8*12e25d6dSChaoyi Chen #include <power/pmic.h>
9*12e25d6dSChaoyi Chen #include <power/regulator.h>
10*12e25d6dSChaoyi Chen #include <power/sy7636a.h>
11*12e25d6dSChaoyi Chen 
12*12e25d6dSChaoyi Chen DECLARE_GLOBAL_DATA_PTR;
13*12e25d6dSChaoyi Chen 
sy7636a_get_enable(struct udevice * dev)14*12e25d6dSChaoyi Chen static int sy7636a_get_enable(struct udevice *dev)
15*12e25d6dSChaoyi Chen {
16*12e25d6dSChaoyi Chen         struct udevice *pmic = dev_get_parent(dev);
17*12e25d6dSChaoyi Chen         int ret;
18*12e25d6dSChaoyi Chen 
19*12e25d6dSChaoyi Chen         ret = pmic_reg_read(pmic, SY7636A_REG_OPERATION_MODE_CRL);
20*12e25d6dSChaoyi Chen         if (ret < 0)
21*12e25d6dSChaoyi Chen                 return ret;
22*12e25d6dSChaoyi Chen 
23*12e25d6dSChaoyi Chen         return !!(ret & SY7636A_OPERATION_MODE_CRL_VCOMCTL);
24*12e25d6dSChaoyi Chen }
25*12e25d6dSChaoyi Chen 
sy7636a_set_enable(struct udevice * dev,bool enable)26*12e25d6dSChaoyi Chen static int sy7636a_set_enable(struct udevice *dev, bool enable)
27*12e25d6dSChaoyi Chen {
28*12e25d6dSChaoyi Chen         struct udevice *pmic = dev_get_parent(dev);
29*12e25d6dSChaoyi Chen         int ret;
30*12e25d6dSChaoyi Chen 
31*12e25d6dSChaoyi Chen         if (enable)
32*12e25d6dSChaoyi Chen                 ret = pmic_clrsetbits(pmic, SY7636A_REG_OPERATION_MODE_CRL,
33*12e25d6dSChaoyi Chen                                       0, SY7636A_OPERATION_MODE_CRL_ONOFF);
34*12e25d6dSChaoyi Chen         else
35*12e25d6dSChaoyi Chen                 ret = pmic_clrsetbits(pmic, SY7636A_REG_OPERATION_MODE_CRL,
36*12e25d6dSChaoyi Chen                                       SY7636A_OPERATION_MODE_CRL_ONOFF, 0);
37*12e25d6dSChaoyi Chen 
38*12e25d6dSChaoyi Chen         return ret;
39*12e25d6dSChaoyi Chen }
40*12e25d6dSChaoyi Chen 
sy7636a_set_value(struct udevice * dev,int uV)41*12e25d6dSChaoyi Chen static int sy7636a_set_value(struct udevice *dev, int uV)
42*12e25d6dSChaoyi Chen {
43*12e25d6dSChaoyi Chen         struct udevice *pmic = dev_get_parent(dev);
44*12e25d6dSChaoyi Chen         int mV;
45*12e25d6dSChaoyi Chen         u32 val, origin_val;
46*12e25d6dSChaoyi Chen         int ret;
47*12e25d6dSChaoyi Chen 
48*12e25d6dSChaoyi Chen         mV = uV / 1000;
49*12e25d6dSChaoyi Chen 	val = mV / 10;
50*12e25d6dSChaoyi Chen 
51*12e25d6dSChaoyi Chen         /* VCOM[7:0] */
52*12e25d6dSChaoyi Chen         ret = pmic_reg_read(pmic, SY7636A_REG_VCOM_ADJUST_CTRL_L);
53*12e25d6dSChaoyi Chen         if (ret < 0)
54*12e25d6dSChaoyi Chen                 return ret;
55*12e25d6dSChaoyi Chen 
56*12e25d6dSChaoyi Chen         origin_val = ret & 0xFF;
57*12e25d6dSChaoyi Chen 
58*12e25d6dSChaoyi Chen         /* VCOM[8] */
59*12e25d6dSChaoyi Chen         ret = pmic_reg_read(pmic, SY7636A_REG_VCOM_ADJUST_CTRL_H);
60*12e25d6dSChaoyi Chen         if (ret < 0)
61*12e25d6dSChaoyi Chen                 return ret;
62*12e25d6dSChaoyi Chen 
63*12e25d6dSChaoyi Chen         origin_val |= (ret & VCOM_ADJUST_BIT_8) << 1;
64*12e25d6dSChaoyi Chen         if (val == origin_val)
65*12e25d6dSChaoyi Chen                 return 0;
66*12e25d6dSChaoyi Chen 
67*12e25d6dSChaoyi Chen         /* turn off power rails */
68*12e25d6dSChaoyi Chen         ret = pmic_clrsetbits(pmic, SY7636A_REG_OPERATION_MODE_CRL,
69*12e25d6dSChaoyi Chen                               SY7636A_OPERATION_MODE_CRL_ONOFF, 0);
70*12e25d6dSChaoyi Chen         if (ret < 0)
71*12e25d6dSChaoyi Chen                 return ret;
72*12e25d6dSChaoyi Chen 
73*12e25d6dSChaoyi Chen 	ret = pmic_reg_write(pmic, SY7636A_REG_VCOM_ADJUST_CTRL_L, val & 0xFF);
74*12e25d6dSChaoyi Chen 	if (ret < 0)
75*12e25d6dSChaoyi Chen 		return ret;
76*12e25d6dSChaoyi Chen 
77*12e25d6dSChaoyi Chen 	ret = pmic_reg_write(pmic, SY7636A_REG_VCOM_ADJUST_CTRL_H, (val >> 1) & 0x80);
78*12e25d6dSChaoyi Chen 	if (ret < 0)
79*12e25d6dSChaoyi Chen 		return ret;
80*12e25d6dSChaoyi Chen 
81*12e25d6dSChaoyi Chen         /* SY7636A has 50ms protection mask for power rails */
82*12e25d6dSChaoyi Chen         udelay(50 * 1000);
83*12e25d6dSChaoyi Chen 
84*12e25d6dSChaoyi Chen         /* turn on power rails */
85*12e25d6dSChaoyi Chen         ret = pmic_clrsetbits(pmic, SY7636A_REG_OPERATION_MODE_CRL, 0,
86*12e25d6dSChaoyi Chen                               SY7636A_OPERATION_MODE_CRL_ONOFF);
87*12e25d6dSChaoyi Chen 
88*12e25d6dSChaoyi Chen         return ret;
89*12e25d6dSChaoyi Chen }
90*12e25d6dSChaoyi Chen 
sy7636a_regulator_probe(struct udevice * dev)91*12e25d6dSChaoyi Chen static int sy7636a_regulator_probe(struct udevice *dev)
92*12e25d6dSChaoyi Chen {
93*12e25d6dSChaoyi Chen         struct udevice *pmic = dev_get_parent(dev);
94*12e25d6dSChaoyi Chen         int ret;
95*12e25d6dSChaoyi Chen 
96*12e25d6dSChaoyi Chen         ret = pmic_reg_write(pmic, SY7636A_REG_POWER_ON_DELAY_TIME, 0x0);
97*12e25d6dSChaoyi Chen 	if (ret) {
98*12e25d6dSChaoyi Chen 		dev_err(dev, "Failed to initialize regulator: %d\n", ret);
99*12e25d6dSChaoyi Chen 		return ret;
100*12e25d6dSChaoyi Chen 	}
101*12e25d6dSChaoyi Chen 
102*12e25d6dSChaoyi Chen         return 0;
103*12e25d6dSChaoyi Chen }
104*12e25d6dSChaoyi Chen 
105*12e25d6dSChaoyi Chen static const struct dm_regulator_ops sy7636a_ops = {
106*12e25d6dSChaoyi Chen         .get_enable = sy7636a_get_enable,
107*12e25d6dSChaoyi Chen         .set_enable = sy7636a_set_enable,
108*12e25d6dSChaoyi Chen         .set_value  = sy7636a_set_value,
109*12e25d6dSChaoyi Chen };
110*12e25d6dSChaoyi Chen 
111*12e25d6dSChaoyi Chen U_BOOT_DRIVER(sy7636a_regulator) = {
112*12e25d6dSChaoyi Chen 	.name = SY7636A_REGULATOR_DRIVER_NAME,
113*12e25d6dSChaoyi Chen 	.id = UCLASS_REGULATOR,
114*12e25d6dSChaoyi Chen 	.ops = &sy7636a_ops,
115*12e25d6dSChaoyi Chen 	.probe = sy7636a_regulator_probe,
116*12e25d6dSChaoyi Chen };
117