xref: /OK3568_Linux_fs/kernel/drivers/regulator/rk806-regulator.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Regulator driver for Rockchip RK806
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  * Author: Xu Shengfei <xsf@rock-chips.com>
8*4882a593Smuzhiyun  */
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #include <linux/delay.h>
11*4882a593Smuzhiyun #include <linux/gpio.h>
12*4882a593Smuzhiyun #include <linux/gpio/consumer.h>
13*4882a593Smuzhiyun #include <linux/mfd/rk806.h>
14*4882a593Smuzhiyun #include <linux/mod_devicetable.h>
15*4882a593Smuzhiyun #include <linux/module.h>
16*4882a593Smuzhiyun #include <linux/of_device.h>
17*4882a593Smuzhiyun #include <linux/platform_device.h>
18*4882a593Smuzhiyun #include <linux/regulator/driver.h>
19*4882a593Smuzhiyun #include "internal.h"
20*4882a593Smuzhiyun 
21*4882a593Smuzhiyun static int dbg_enable;
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun module_param_named(dbg_level, dbg_enable, int, 0644);
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun #define REG_DBG(args...) \
26*4882a593Smuzhiyun 	do { \
27*4882a593Smuzhiyun 		if (dbg_enable) { \
28*4882a593Smuzhiyun 			pr_info(args); \
29*4882a593Smuzhiyun 		} \
30*4882a593Smuzhiyun 	} while (0)
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun #define RK806_BUCK_MIN0		500000
33*4882a593Smuzhiyun #define RK806_BUCK_MAX0		1500000
34*4882a593Smuzhiyun #define RK806_BUCK_MIN1		1500000
35*4882a593Smuzhiyun #define RK806_BUCK_MAX1		3400000
36*4882a593Smuzhiyun #define RK806_BUCK_STP0		6250
37*4882a593Smuzhiyun #define RK806_BUCK_STP1		25000
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun #define RK806_NLDO_MIN		500000
40*4882a593Smuzhiyun #define RK806_NLDO_MAX		3400000
41*4882a593Smuzhiyun #define RK806_NLDO_STP0		1250
42*4882a593Smuzhiyun #define RK806_NLDO_SEL		((RK806_NLDO_MAX - RK806_NLDO_MIN) / RK806_NLDO_STP0 + 1)
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun #define ENABLE_MASK(id)		(BIT(id) | BIT(4 + (id)))
45*4882a593Smuzhiyun #define DISABLE_VAL(id)		(BIT(4 + (id)))
46*4882a593Smuzhiyun #define PWM_MODE_MSK		BIT(0)
47*4882a593Smuzhiyun #define FPWM_MODE		BIT(0)
48*4882a593Smuzhiyun #define AUTO_PWM_MODE		0
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun #define RK806_DCDC_SLP_REG_OFFSET	0x0A
51*4882a593Smuzhiyun #define RK806_NLDO_SLP_REG_OFFSET	0x05
52*4882a593Smuzhiyun #define RK806_PLDO_SLP_REG_OFFSET	0x06
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun #define RK806_BUCK_SEL_CNT		0xff
55*4882a593Smuzhiyun #define RK806_LDO_SEL_CNT		0xff
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun #define RK806_RAMP_RATE_4LSB_PER_1CLK	0x00/* LDO 100mV/uS buck 50mV/us */
58*4882a593Smuzhiyun #define RK806_RAMP_RATE_2LSB_PER_1CLK	0x01/* LDO 50mV/uS buck 25mV/us */
59*4882a593Smuzhiyun #define RK806_RAMP_RATE_1LSB_PER_1CLK	0x02/* LDO 25mV/uS buck 12.5mV/us */
60*4882a593Smuzhiyun #define RK806_RAMP_RATE_1LSB_PER_2CLK	0x03/* LDO 12.5mV/uS buck 6.25mV/us */
61*4882a593Smuzhiyun 
62*4882a593Smuzhiyun #define RK806_RAMP_RATE_1LSB_PER_4CLK	0x04/* LDO 6.28/2mV/uS buck 3.125mV/us */
63*4882a593Smuzhiyun #define RK806_RAMP_RATE_1LSB_PER_8CLK	0x05/* LDO 3.12mV/uS buck 1.56mV/us */
64*4882a593Smuzhiyun #define RK806_RAMP_RATE_1LSB_PER_13CLK	0x06/* LDO 1.9mV/uS buck 961mV/us */
65*4882a593Smuzhiyun #define RK806_RAMP_RATE_1LSB_PER_32CLK	0x07/* LDO 0.78mV/uS buck 0.39mV/us */
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun static int vsel_ctr_sel_id[RK806_ID_END] = {
68*4882a593Smuzhiyun 	BUCK1_VSEL_CTR_SEL,
69*4882a593Smuzhiyun 	BUCK2_VSEL_CTR_SEL,
70*4882a593Smuzhiyun 	BUCK3_VSEL_CTR_SEL,
71*4882a593Smuzhiyun 	BUCK4_VSEL_CTR_SEL,
72*4882a593Smuzhiyun 	BUCK5_VSEL_CTR_SEL,
73*4882a593Smuzhiyun 	BUCK6_VSEL_CTR_SEL,
74*4882a593Smuzhiyun 	BUCK7_VSEL_CTR_SEL,
75*4882a593Smuzhiyun 	BUCK8_VSEL_CTR_SEL,
76*4882a593Smuzhiyun 	BUCK9_VSEL_CTR_SEL,
77*4882a593Smuzhiyun 	BUCK10_VSEL_CTR_SEL,
78*4882a593Smuzhiyun 	NLDO1_VSEL_CTR_SEL,
79*4882a593Smuzhiyun 	NLDO2_VSEL_CTR_SEL,
80*4882a593Smuzhiyun 	NLDO3_VSEL_CTR_SEL,
81*4882a593Smuzhiyun 	NLDO4_VSEL_CTR_SEL,
82*4882a593Smuzhiyun 	NLDO5_VSEL_CTR_SEL,
83*4882a593Smuzhiyun 	PLDO1_VSEL_CTR_SEL,
84*4882a593Smuzhiyun 	PLDO2_VSEL_CTR_SEL,
85*4882a593Smuzhiyun 	PLDO3_VSEL_CTR_SEL,
86*4882a593Smuzhiyun 	PLDO4_VSEL_CTR_SEL,
87*4882a593Smuzhiyun 	PLDO5_VSEL_CTR_SEL,
88*4882a593Smuzhiyun 	PLDO6_VSEL_CTR_SEL,
89*4882a593Smuzhiyun };
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun static int start_dvs_id[RK806_ID_END] = {
92*4882a593Smuzhiyun 	BUCK1_DVS_CTR_SEL,
93*4882a593Smuzhiyun 	BUCK2_DVS_CTR_SEL,
94*4882a593Smuzhiyun 	BUCK3_DVS_CTR_SEL,
95*4882a593Smuzhiyun 	BUCK4_DVS_CTR_SEL,
96*4882a593Smuzhiyun 	BUCK5_DVS_CTR_SEL,
97*4882a593Smuzhiyun 	BUCK6_DVS_CTR_SEL,
98*4882a593Smuzhiyun 	BUCK7_DVS_CTR_SEL,
99*4882a593Smuzhiyun 	BUCK8_DVS_CTR_SEL,
100*4882a593Smuzhiyun 	BUCK9_DVS_CTR_SEL,
101*4882a593Smuzhiyun 	BUCK10_DVS_CTR_SEL,
102*4882a593Smuzhiyun 	NLDO1_DVS_CTR_SEL,
103*4882a593Smuzhiyun 	NLDO2_DVS_CTR_SEL,
104*4882a593Smuzhiyun 	NLDO3_DVS_CTR_SEL,
105*4882a593Smuzhiyun 	NLDO4_DVS_CTR_SEL,
106*4882a593Smuzhiyun 	NLDO5_DVS_CTR_SEL,
107*4882a593Smuzhiyun 	PLDO1_DVS_CTR_SEL,
108*4882a593Smuzhiyun 	PLDO2_DVS_CTR_SEL,
109*4882a593Smuzhiyun 	PLDO3_DVS_CTR_SEL,
110*4882a593Smuzhiyun 	PLDO4_DVS_CTR_SEL,
111*4882a593Smuzhiyun 	PLDO5_DVS_CTR_SEL,
112*4882a593Smuzhiyun 	PLDO6_DVS_CTR_SEL,
113*4882a593Smuzhiyun };
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun static const int rk806_buck_rate_config_field[10][2] = {
116*4882a593Smuzhiyun 	{ BUCK1_RATE, BUCK1_RATE2 },
117*4882a593Smuzhiyun 	{ BUCK2_RATE, BUCK2_RATE2 },
118*4882a593Smuzhiyun 	{ BUCK3_RATE, BUCK3_RATE2 },
119*4882a593Smuzhiyun 	{ BUCK4_RATE, BUCK4_RATE2 },
120*4882a593Smuzhiyun 	{ BUCK5_RATE, BUCK5_RATE2 },
121*4882a593Smuzhiyun 	{ BUCK6_RATE, BUCK6_RATE2 },
122*4882a593Smuzhiyun 	{ BUCK7_RATE, BUCK7_RATE2 },
123*4882a593Smuzhiyun 	{ BUCK8_RATE, BUCK8_RATE2 },
124*4882a593Smuzhiyun 	{ BUCK9_RATE, BUCK9_RATE2 },
125*4882a593Smuzhiyun 	{ BUCK10_RATE, BUCK10_RATE2 },
126*4882a593Smuzhiyun };
127*4882a593Smuzhiyun 
128*4882a593Smuzhiyun struct rk806_dvs_field {
129*4882a593Smuzhiyun 	int en_reg;
130*4882a593Smuzhiyun 	int en_bit;
131*4882a593Smuzhiyun 	int sleep_en;
132*4882a593Smuzhiyun 	int on_vsel;
133*4882a593Smuzhiyun 	int sleep_vsel;
134*4882a593Smuzhiyun 	int vsel_ctrl_sel;
135*4882a593Smuzhiyun };
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun struct rk806_dvs_status {
138*4882a593Smuzhiyun 	int en_reg_val;
139*4882a593Smuzhiyun 	int en_bit_val;
140*4882a593Smuzhiyun 	int sleep_en_val;
141*4882a593Smuzhiyun 	int on_vsel_val;
142*4882a593Smuzhiyun 	int sleep_vsel_val;
143*4882a593Smuzhiyun 	int vsel_ctrl_sel_val;
144*4882a593Smuzhiyun 	int dvs_gpio_level[3];
145*4882a593Smuzhiyun };
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun struct rk806_regulator_data {
148*4882a593Smuzhiyun 	struct device_node *dvs_dn[RK806_DVS_END][RK806_ID_END];
149*4882a593Smuzhiyun 	struct rk806_dvs_field dvs_field[RK806_ID_END];
150*4882a593Smuzhiyun 	struct rk806_dvs_status dvs_mode[RK806_ID_END];
151*4882a593Smuzhiyun 	struct rk806_dvs_status sleep_mode[RK806_ID_END];
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun 	int dvs_ctrl_mode_init[RK806_ID_END];
154*4882a593Smuzhiyun 	int dvs_ctrl_mode[RK806_ID_END];
155*4882a593Smuzhiyun 	int dvs_ctrl_id[RK806_ID_END];
156*4882a593Smuzhiyun 	int vsel_ctrl_id[RK806_ID_END];
157*4882a593Smuzhiyun 
158*4882a593Smuzhiyun 	int dvs_flag[RK806_DVS_END];
159*4882a593Smuzhiyun 	int dvs_used[RK806_DVS_END];
160*4882a593Smuzhiyun 	int dvs_count[RK806_DVS_END];
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun 	int regulator_init;
163*4882a593Smuzhiyun 	int support_dvs;
164*4882a593Smuzhiyun 	struct gpio_desc *dvs_gpios[3];
165*4882a593Smuzhiyun 	struct rk806 *rk806;
166*4882a593Smuzhiyun };
167*4882a593Smuzhiyun 
168*4882a593Smuzhiyun #define INIT_DVS_FIELD(_en_reg, _en_bit, _sleep_en, _on_vsel,	\
169*4882a593Smuzhiyun 			_sleep_vsel, _vsel_ctrl_sel)	\
170*4882a593Smuzhiyun {	\
171*4882a593Smuzhiyun 	.en_reg = _en_reg,	\
172*4882a593Smuzhiyun 	.en_bit = _en_bit,	\
173*4882a593Smuzhiyun 	.sleep_en = _sleep_en,	\
174*4882a593Smuzhiyun 	.on_vsel = _on_vsel,	\
175*4882a593Smuzhiyun 	.sleep_vsel = _sleep_vsel,	\
176*4882a593Smuzhiyun 	.vsel_ctrl_sel = _vsel_ctrl_sel,	\
177*4882a593Smuzhiyun }
178*4882a593Smuzhiyun 
179*4882a593Smuzhiyun static const struct rk806_dvs_field rk806_dvs_fields[RK806_ID_END] = {
180*4882a593Smuzhiyun 	INIT_DVS_FIELD(POWER_EN0, BIT(0), BUCK1_SLP_EN,
181*4882a593Smuzhiyun 		       BUCK1_ON_VSEL, BUCK1_SLP_VSEL, BUCK1_VSEL_CTR_SEL),
182*4882a593Smuzhiyun 	INIT_DVS_FIELD(POWER_EN0, BIT(1), BUCK2_SLP_EN,
183*4882a593Smuzhiyun 		       BUCK2_ON_VSEL, BUCK2_SLP_VSEL, BUCK2_VSEL_CTR_SEL),
184*4882a593Smuzhiyun 	INIT_DVS_FIELD(POWER_EN0, BIT(2), BUCK3_SLP_EN,
185*4882a593Smuzhiyun 		       BUCK3_ON_VSEL, BUCK3_SLP_VSEL, BUCK3_VSEL_CTR_SEL),
186*4882a593Smuzhiyun 	INIT_DVS_FIELD(POWER_EN0, BIT(3), BUCK4_SLP_EN,
187*4882a593Smuzhiyun 		       BUCK4_ON_VSEL, BUCK4_SLP_VSEL, BUCK4_VSEL_CTR_SEL),
188*4882a593Smuzhiyun 
189*4882a593Smuzhiyun 	INIT_DVS_FIELD(POWER_EN1, BIT(0), BUCK5_SLP_EN,
190*4882a593Smuzhiyun 		       BUCK5_ON_VSEL, BUCK5_SLP_VSEL, BUCK5_VSEL_CTR_SEL),
191*4882a593Smuzhiyun 	INIT_DVS_FIELD(POWER_EN1, BIT(1), BUCK6_SLP_EN,
192*4882a593Smuzhiyun 		       BUCK6_ON_VSEL, BUCK6_SLP_VSEL, BUCK6_VSEL_CTR_SEL),
193*4882a593Smuzhiyun 	INIT_DVS_FIELD(POWER_EN1, BIT(2), BUCK7_SLP_EN,
194*4882a593Smuzhiyun 		       BUCK7_ON_VSEL, BUCK7_SLP_VSEL, BUCK7_VSEL_CTR_SEL),
195*4882a593Smuzhiyun 	INIT_DVS_FIELD(POWER_EN1, BIT(3), BUCK8_SLP_EN,
196*4882a593Smuzhiyun 		       BUCK8_ON_VSEL, BUCK8_SLP_VSEL, BUCK8_VSEL_CTR_SEL),
197*4882a593Smuzhiyun 
198*4882a593Smuzhiyun 	INIT_DVS_FIELD(POWER_EN2, BIT(0), BUCK9_SLP_EN,
199*4882a593Smuzhiyun 		       BUCK9_ON_VSEL, BUCK9_SLP_VSEL, BUCK9_VSEL_CTR_SEL),
200*4882a593Smuzhiyun 	INIT_DVS_FIELD(POWER_EN2, BIT(1), BUCK10_SLP_EN,
201*4882a593Smuzhiyun 		       BUCK10_ON_VSEL, BUCK10_SLP_VSEL, BUCK10_VSEL_CTR_SEL),
202*4882a593Smuzhiyun 
203*4882a593Smuzhiyun 	INIT_DVS_FIELD(POWER_EN3, BIT(0), NLDO1_SLP_EN,
204*4882a593Smuzhiyun 		       NLDO1_ON_VSEL, NLDO1_SLP_VSEL, NLDO1_VSEL_CTR_SEL),
205*4882a593Smuzhiyun 	INIT_DVS_FIELD(POWER_EN3, BIT(1), NLDO2_SLP_EN,
206*4882a593Smuzhiyun 		       NLDO2_ON_VSEL, NLDO2_SLP_VSEL, NLDO2_VSEL_CTR_SEL),
207*4882a593Smuzhiyun 	INIT_DVS_FIELD(POWER_EN3, BIT(2), NLDO3_SLP_EN,
208*4882a593Smuzhiyun 		       NLDO3_ON_VSEL, NLDO3_SLP_VSEL, NLDO3_VSEL_CTR_SEL),
209*4882a593Smuzhiyun 	INIT_DVS_FIELD(POWER_EN3, BIT(3), NLDO4_SLP_EN,
210*4882a593Smuzhiyun 		       NLDO4_ON_VSEL, NLDO4_SLP_VSEL, NLDO4_VSEL_CTR_SEL),
211*4882a593Smuzhiyun 
212*4882a593Smuzhiyun 	INIT_DVS_FIELD(POWER_EN5, BIT(2), NLDO5_SLP_EN,
213*4882a593Smuzhiyun 		       NLDO5_ON_VSEL, NLDO5_SLP_VSEL, NLDO5_VSEL_CTR_SEL),
214*4882a593Smuzhiyun 
215*4882a593Smuzhiyun 	INIT_DVS_FIELD(POWER_EN4, BIT(1), PLDO1_SLP_EN,
216*4882a593Smuzhiyun 		       PLDO1_ON_VSEL, PLDO1_SLP_VSEL, PLDO1_VSEL_CTR_SEL),
217*4882a593Smuzhiyun 	INIT_DVS_FIELD(POWER_EN4, BIT(2), PLDO2_SLP_EN,
218*4882a593Smuzhiyun 		       PLDO2_ON_VSEL, PLDO2_SLP_VSEL, PLDO2_VSEL_CTR_SEL),
219*4882a593Smuzhiyun 	INIT_DVS_FIELD(POWER_EN4, BIT(3), PLDO3_SLP_EN,
220*4882a593Smuzhiyun 		       PLDO3_ON_VSEL, PLDO3_SLP_VSEL, PLDO3_VSEL_CTR_SEL),
221*4882a593Smuzhiyun 	INIT_DVS_FIELD(POWER_EN5, BIT(0), PLDO4_SLP_EN,
222*4882a593Smuzhiyun 		       PLDO4_ON_VSEL, PLDO4_SLP_VSEL, PLDO4_VSEL_CTR_SEL),
223*4882a593Smuzhiyun 
224*4882a593Smuzhiyun 	INIT_DVS_FIELD(POWER_EN5, BIT(1), PLDO5_SLP_EN,
225*4882a593Smuzhiyun 		       PLDO5_ON_VSEL, PLDO5_SLP_VSEL, PLDO5_VSEL_CTR_SEL),
226*4882a593Smuzhiyun 	INIT_DVS_FIELD(POWER_EN4, BIT(0), PLDO6_SLP_EN,
227*4882a593Smuzhiyun 		       PLDO6_ON_VSEL, PLDO6_SLP_VSEL, PLDO6_VSEL_CTR_SEL),
228*4882a593Smuzhiyun };
229*4882a593Smuzhiyun 
230*4882a593Smuzhiyun static const struct linear_range rk806_buck_voltage_ranges[] = {
231*4882a593Smuzhiyun 	REGULATOR_LINEAR_RANGE(500000, 0, 159, 6250), /* 500mV ~ 1500mV */
232*4882a593Smuzhiyun 	REGULATOR_LINEAR_RANGE(1500000, 160, 236, 25000), /* 1500mV ~ 3400mV */
233*4882a593Smuzhiyun 	REGULATOR_LINEAR_RANGE(3400000, 237, 255, 0),
234*4882a593Smuzhiyun };
235*4882a593Smuzhiyun 
236*4882a593Smuzhiyun static const struct linear_range rk806_ldo_voltage_ranges[] = {
237*4882a593Smuzhiyun 	REGULATOR_LINEAR_RANGE(500000, 0, 232, 12500), /* 500mV ~ 3400mV */
238*4882a593Smuzhiyun 	REGULATOR_LINEAR_RANGE(3400000, 233, 255, 0), /* 500mV ~ 3400mV */
239*4882a593Smuzhiyun };
240*4882a593Smuzhiyun 
get_count(int value)241*4882a593Smuzhiyun static int get_count(int value)
242*4882a593Smuzhiyun {
243*4882a593Smuzhiyun 	int count = 0;
244*4882a593Smuzhiyun 
245*4882a593Smuzhiyun 	while (value != 0) {
246*4882a593Smuzhiyun 		if (value % 2 == 1)
247*4882a593Smuzhiyun 			count++;
248*4882a593Smuzhiyun 		value >>= 1;
249*4882a593Smuzhiyun 	}
250*4882a593Smuzhiyun 
251*4882a593Smuzhiyun 	return count;
252*4882a593Smuzhiyun }
253*4882a593Smuzhiyun 
rk806_dvs_start_fun_init(struct regulator_dev * rdev)254*4882a593Smuzhiyun static void rk806_dvs_start_fun_init(struct regulator_dev *rdev)
255*4882a593Smuzhiyun {
256*4882a593Smuzhiyun 	struct rk806_regulator_data *pdata = rdev_get_drvdata(rdev);
257*4882a593Smuzhiyun 	struct rk806 *rk806 = pdata->rk806;
258*4882a593Smuzhiyun 	int rid = rdev_get_id(rdev);
259*4882a593Smuzhiyun 
260*4882a593Smuzhiyun 	rk806_field_write(rk806,
261*4882a593Smuzhiyun 			  pdata->dvs_ctrl_id[rid],
262*4882a593Smuzhiyun 			  pdata->dvs_ctrl_mode[rid]);
263*4882a593Smuzhiyun }
264*4882a593Smuzhiyun 
rk806_dvs_pwrctrl_fun_init(struct regulator_dev * rdev)265*4882a593Smuzhiyun static void rk806_dvs_pwrctrl_fun_init(struct regulator_dev *rdev)
266*4882a593Smuzhiyun {
267*4882a593Smuzhiyun 	struct rk806_regulator_data *pdata = rdev_get_drvdata(rdev);
268*4882a593Smuzhiyun 	struct rk806 *rk806 = pdata->rk806;
269*4882a593Smuzhiyun 	int rid = rdev_get_id(rdev);
270*4882a593Smuzhiyun 	int offset;
271*4882a593Smuzhiyun 
272*4882a593Smuzhiyun 	/* init dvs pin function */
273*4882a593Smuzhiyun 	offset = pdata->dvs_ctrl_mode[rid] - RK806_DVS_PWRCTRL1;
274*4882a593Smuzhiyun 	rk806_field_write(rk806, PWRCTRL1_FUN + offset, PWRCTRL_DVS_FUN);
275*4882a593Smuzhiyun 
276*4882a593Smuzhiyun 	rk806_field_write(rk806,
277*4882a593Smuzhiyun 			  pdata->dvs_ctrl_id[rid],
278*4882a593Smuzhiyun 			  pdata->dvs_ctrl_mode[rid] - RK806_DVS_START3);
279*4882a593Smuzhiyun }
280*4882a593Smuzhiyun 
rk806_dvs_start_pwrctrl_fun_init(struct regulator_dev * rdev)281*4882a593Smuzhiyun static void rk806_dvs_start_pwrctrl_fun_init(struct regulator_dev *rdev)
282*4882a593Smuzhiyun {
283*4882a593Smuzhiyun 	struct rk806_regulator_data *pdata = rdev_get_drvdata(rdev);
284*4882a593Smuzhiyun 	struct rk806 *rk806 = pdata->rk806;
285*4882a593Smuzhiyun 	int rid = rdev_get_id(rdev);
286*4882a593Smuzhiyun 	int offset;
287*4882a593Smuzhiyun 
288*4882a593Smuzhiyun 	/* init dvs pin function */
289*4882a593Smuzhiyun 	offset = pdata->dvs_ctrl_mode[rid] - RK806_DVS_START_PWRCTR1;
290*4882a593Smuzhiyun 	/*set pin polarity, active high */
291*4882a593Smuzhiyun 	rk806_field_write(rk806, PWRCTRL1_POL + offset, POL_HIGH);
292*4882a593Smuzhiyun 	rk806_field_write(rk806, PWRCTRL1_FUN + offset, PWRCTRL_DVS_FUN);
293*4882a593Smuzhiyun 
294*4882a593Smuzhiyun 	/* enable start bit dvs  function */
295*4882a593Smuzhiyun 	rk806_field_write(rk806,
296*4882a593Smuzhiyun 			  pdata->dvs_ctrl_id[rid],
297*4882a593Smuzhiyun 			  pdata->dvs_ctrl_mode[rid] - RK806_DVS_PWRCTRL3);
298*4882a593Smuzhiyun 	rk806_field_write(rk806,
299*4882a593Smuzhiyun 			  pdata->vsel_ctrl_id[rid],
300*4882a593Smuzhiyun 			  pdata->dvs_ctrl_mode[rid] - RK806_DVS_PWRCTRL3);
301*4882a593Smuzhiyun 
302*4882a593Smuzhiyun }
303*4882a593Smuzhiyun 
rk806_dvs_mode_init(struct regulator_dev * rdev)304*4882a593Smuzhiyun static int rk806_dvs_mode_init(struct regulator_dev *rdev)
305*4882a593Smuzhiyun {
306*4882a593Smuzhiyun 	struct rk806_regulator_data *pdata = rdev_get_drvdata(rdev);
307*4882a593Smuzhiyun 	int rid = rdev_get_id(rdev);
308*4882a593Smuzhiyun 	int mode, j;
309*4882a593Smuzhiyun 
310*4882a593Smuzhiyun 	for (mode = RK806_DVS_START1; mode < RK806_DVS_END; mode++) {
311*4882a593Smuzhiyun 		for (j = 0; j < RK806_ID_END; j++) {
312*4882a593Smuzhiyun 			if ((pdata->dvs_dn[mode][j] == NULL) ||
313*4882a593Smuzhiyun 			    (strcmp(pdata->dvs_dn[mode][j]->name, rdev->desc->name)))
314*4882a593Smuzhiyun 				continue;
315*4882a593Smuzhiyun 
316*4882a593Smuzhiyun 			pdata->dvs_ctrl_mode[rid] = mode;
317*4882a593Smuzhiyun 			pdata->dvs_ctrl_mode_init[rid] = 1;
318*4882a593Smuzhiyun 			pdata->dvs_flag[mode] |= BIT(rid);
319*4882a593Smuzhiyun 
320*4882a593Smuzhiyun 			/* init dvs function, dvs-pin or start bit */
321*4882a593Smuzhiyun 			if (mode <= RK806_DVS_START3)
322*4882a593Smuzhiyun 				rk806_dvs_start_fun_init(rdev);
323*4882a593Smuzhiyun 			else if (mode <= RK806_DVS_PWRCTRL3)
324*4882a593Smuzhiyun 				rk806_dvs_pwrctrl_fun_init(rdev);
325*4882a593Smuzhiyun 			else if (mode <= RK806_DVS_START_PWRCTR3)
326*4882a593Smuzhiyun 				rk806_dvs_start_pwrctrl_fun_init(rdev);
327*4882a593Smuzhiyun 			return pdata->dvs_ctrl_mode[rid];
328*4882a593Smuzhiyun 		}
329*4882a593Smuzhiyun 	}
330*4882a593Smuzhiyun 
331*4882a593Smuzhiyun 	return pdata->dvs_ctrl_mode[rid];
332*4882a593Smuzhiyun }
333*4882a593Smuzhiyun 
get_dvs_mode(struct regulator_dev * rdev)334*4882a593Smuzhiyun static int get_dvs_mode(struct regulator_dev *rdev)
335*4882a593Smuzhiyun {
336*4882a593Smuzhiyun 	struct rk806_regulator_data *pdata = rdev_get_drvdata(rdev);
337*4882a593Smuzhiyun 	int rid = rdev_get_id(rdev);
338*4882a593Smuzhiyun 
339*4882a593Smuzhiyun 	if (!pdata->support_dvs)
340*4882a593Smuzhiyun 		return RK806_DVS_NOT_SUPPORT;
341*4882a593Smuzhiyun 
342*4882a593Smuzhiyun 	if (pdata->dvs_ctrl_mode_init[rid] || pdata->regulator_init)
343*4882a593Smuzhiyun 		return pdata->dvs_ctrl_mode[rid];
344*4882a593Smuzhiyun 
345*4882a593Smuzhiyun 	return rk806_dvs_mode_init(rdev);
346*4882a593Smuzhiyun }
347*4882a593Smuzhiyun 
get_gpio_id(int mode)348*4882a593Smuzhiyun static int get_gpio_id(int mode)
349*4882a593Smuzhiyun {
350*4882a593Smuzhiyun 	int pid = -1;
351*4882a593Smuzhiyun 
352*4882a593Smuzhiyun 	if ((mode >= RK806_DVS_PWRCTRL1) && (mode <= RK806_DVS_PWRCTRL3))
353*4882a593Smuzhiyun 		pid = mode - RK806_DVS_PWRCTRL1;
354*4882a593Smuzhiyun 
355*4882a593Smuzhiyun 	return pid;
356*4882a593Smuzhiyun }
357*4882a593Smuzhiyun 
rk806_get_reg_offset(int id)358*4882a593Smuzhiyun static int rk806_get_reg_offset(int id)
359*4882a593Smuzhiyun {
360*4882a593Smuzhiyun 	int reg_offset = 0;
361*4882a593Smuzhiyun 
362*4882a593Smuzhiyun 	if (id >= RK806_ID_DCDC1 && id <= RK806_ID_DCDC10)
363*4882a593Smuzhiyun 		reg_offset = RK806_DCDC_SLP_REG_OFFSET;
364*4882a593Smuzhiyun 	else if ((id >= RK806_ID_NLDO1 && id <= RK806_ID_NLDO4) ||
365*4882a593Smuzhiyun 		 (id == RK806_ID_NLDO5))
366*4882a593Smuzhiyun 		reg_offset = RK806_NLDO_SLP_REG_OFFSET;
367*4882a593Smuzhiyun 	else if (id >= RK806_ID_PLDO1 && id <= RK806_ID_PLDO6)
368*4882a593Smuzhiyun 		reg_offset = RK806_PLDO_SLP_REG_OFFSET;
369*4882a593Smuzhiyun 
370*4882a593Smuzhiyun 	return reg_offset;
371*4882a593Smuzhiyun }
372*4882a593Smuzhiyun 
rk806_get_read_vsel_register(struct regulator_dev * rdev)373*4882a593Smuzhiyun static int rk806_get_read_vsel_register(struct regulator_dev *rdev)
374*4882a593Smuzhiyun {
375*4882a593Smuzhiyun 	struct rk806_regulator_data *pdata = rdev_get_drvdata(rdev);
376*4882a593Smuzhiyun 	int level, vsel_reg, pid;
377*4882a593Smuzhiyun 	int rid = rdev_get_id(rdev);
378*4882a593Smuzhiyun 	int mode;
379*4882a593Smuzhiyun 
380*4882a593Smuzhiyun 	vsel_reg = rdev->desc->vsel_reg;
381*4882a593Smuzhiyun 	if (!pdata->support_dvs)
382*4882a593Smuzhiyun 		return vsel_reg;
383*4882a593Smuzhiyun 
384*4882a593Smuzhiyun 	mode = get_dvs_mode(rdev);
385*4882a593Smuzhiyun 	pid = get_gpio_id(mode);
386*4882a593Smuzhiyun 	if ((pid >= 0) && (pdata->dvs_gpios[pid] != NULL)) {
387*4882a593Smuzhiyun 		level = gpiod_get_value(pdata->dvs_gpios[pid]);
388*4882a593Smuzhiyun 		/* level == 0, the Output high level, the SLP_VSEL output */
389*4882a593Smuzhiyun 		if (level == 0)
390*4882a593Smuzhiyun 			vsel_reg = rdev->desc->vsel_reg + rk806_get_reg_offset(rid);
391*4882a593Smuzhiyun 	}
392*4882a593Smuzhiyun 
393*4882a593Smuzhiyun 	return vsel_reg;
394*4882a593Smuzhiyun }
395*4882a593Smuzhiyun 
rk806_get_write_vsel_register(struct regulator_dev * rdev)396*4882a593Smuzhiyun static int rk806_get_write_vsel_register(struct regulator_dev *rdev)
397*4882a593Smuzhiyun {
398*4882a593Smuzhiyun 	struct rk806_regulator_data *pdata = rdev_get_drvdata(rdev);
399*4882a593Smuzhiyun 	int level, vsel_reg, pid;
400*4882a593Smuzhiyun 	int rid = rdev_get_id(rdev);
401*4882a593Smuzhiyun 	int mode;
402*4882a593Smuzhiyun 
403*4882a593Smuzhiyun 	vsel_reg = rdev->desc->vsel_reg;
404*4882a593Smuzhiyun 	if (!pdata->support_dvs)
405*4882a593Smuzhiyun 		return vsel_reg;
406*4882a593Smuzhiyun 
407*4882a593Smuzhiyun 	mode = get_dvs_mode(rdev);
408*4882a593Smuzhiyun 	pid = get_gpio_id(mode);
409*4882a593Smuzhiyun 	if ((pid >= 0) && (pdata->dvs_gpios[pid] != NULL)) {
410*4882a593Smuzhiyun 		level = gpiod_get_value(pdata->dvs_gpios[pid]);
411*4882a593Smuzhiyun 		/* level == 1, output low level, the ON_VSEL output, next SLP_VSEL */
412*4882a593Smuzhiyun 		if (level == 1)
413*4882a593Smuzhiyun 			vsel_reg = rdev->desc->vsel_reg + rk806_get_reg_offset(rid);
414*4882a593Smuzhiyun 	}
415*4882a593Smuzhiyun 
416*4882a593Smuzhiyun 	return vsel_reg;
417*4882a593Smuzhiyun }
418*4882a593Smuzhiyun 
rk806_do_gpio_dvs(struct regulator_dev * rdev)419*4882a593Smuzhiyun static void rk806_do_gpio_dvs(struct regulator_dev *rdev)
420*4882a593Smuzhiyun {
421*4882a593Smuzhiyun 	struct rk806_regulator_data *pdata = rdev_get_drvdata(rdev);
422*4882a593Smuzhiyun 	char dvs_ctrl_name[10][32] = {
423*4882a593Smuzhiyun 					"dvs_default",
424*4882a593Smuzhiyun 					"start_dvs1_ctrl",
425*4882a593Smuzhiyun 					"start_dvs2_ctrl",
426*4882a593Smuzhiyun 					"start_dvs3_ctrl",
427*4882a593Smuzhiyun 					"dvs_pin1_ctrl",
428*4882a593Smuzhiyun 					"dvs_pin2_ctrl",
429*4882a593Smuzhiyun 					"dvs_pin3_ctrl",
430*4882a593Smuzhiyun 					"start_and_pwrctrl1",
431*4882a593Smuzhiyun 					"start_and_pwrctrl2",
432*4882a593Smuzhiyun 					"start_and_pwrctrl3"};
433*4882a593Smuzhiyun 	int rid = rdev_get_id(rdev);
434*4882a593Smuzhiyun 	int gpio_level, pid;
435*4882a593Smuzhiyun 	int mode, count;
436*4882a593Smuzhiyun 
437*4882a593Smuzhiyun 	mode = get_dvs_mode(rdev);
438*4882a593Smuzhiyun 	pdata->dvs_used[mode] |= BIT(rid);
439*4882a593Smuzhiyun 	count = get_count(pdata->dvs_used[mode]);
440*4882a593Smuzhiyun 
441*4882a593Smuzhiyun 	if ((pdata->dvs_used[mode] != pdata->dvs_flag[mode]) ||
442*4882a593Smuzhiyun 	    (count != pdata->dvs_count[mode]))
443*4882a593Smuzhiyun 		return;
444*4882a593Smuzhiyun 
445*4882a593Smuzhiyun 	pdata->dvs_used[mode] = 0;
446*4882a593Smuzhiyun 
447*4882a593Smuzhiyun 	pid = get_gpio_id(mode);
448*4882a593Smuzhiyun 	if ((pid >= 0) && (pdata->dvs_gpios[pid] != NULL)) {
449*4882a593Smuzhiyun 		gpio_level = gpiod_get_value(pdata->dvs_gpios[pid]);
450*4882a593Smuzhiyun 		if (gpio_level == 1)
451*4882a593Smuzhiyun 			gpiod_set_value(pdata->dvs_gpios[pid], 0);
452*4882a593Smuzhiyun 		else
453*4882a593Smuzhiyun 			gpiod_set_value(pdata->dvs_gpios[pid], 1);
454*4882a593Smuzhiyun 	}
455*4882a593Smuzhiyun 	REG_DBG("pin: name: %s, %s\n", dvs_ctrl_name[mode], rdev->desc->name);
456*4882a593Smuzhiyun }
457*4882a593Smuzhiyun 
rk806_do_soft_dvs(struct regulator_dev * rdev)458*4882a593Smuzhiyun static void rk806_do_soft_dvs(struct regulator_dev *rdev)
459*4882a593Smuzhiyun {
460*4882a593Smuzhiyun 	struct rk806_regulator_data *pdata = rdev_get_drvdata(rdev);
461*4882a593Smuzhiyun 	char dvs_ctrl_name[10][32] = {
462*4882a593Smuzhiyun 					"dvs_default",
463*4882a593Smuzhiyun 					"start_dvs1_ctrl",
464*4882a593Smuzhiyun 					"start_dvs2_ctrl",
465*4882a593Smuzhiyun 					"start_dvs3_ctrl",
466*4882a593Smuzhiyun 					"dvs_pin1_ctrl",
467*4882a593Smuzhiyun 					"dvs_pin2_ctrl",
468*4882a593Smuzhiyun 					"dvs_pin3_ctrl",
469*4882a593Smuzhiyun 					"start_and_pwrctrl1",
470*4882a593Smuzhiyun 					"start_and_pwrctrl2",
471*4882a593Smuzhiyun 					"start_and_pwrctrl3"};
472*4882a593Smuzhiyun 	struct rk806 *rk806 = pdata->rk806;
473*4882a593Smuzhiyun 	int rid = rdev_get_id(rdev);
474*4882a593Smuzhiyun 	int soft_mode, count;
475*4882a593Smuzhiyun 	int offset;
476*4882a593Smuzhiyun 
477*4882a593Smuzhiyun 	soft_mode = get_dvs_mode(rdev);
478*4882a593Smuzhiyun 	pdata->dvs_used[soft_mode] |= BIT(rid);
479*4882a593Smuzhiyun 	count = get_count(pdata->dvs_used[soft_mode]);
480*4882a593Smuzhiyun 
481*4882a593Smuzhiyun 	if ((pdata->dvs_used[soft_mode] != pdata->dvs_flag[soft_mode]) ||
482*4882a593Smuzhiyun 	    (count != pdata->dvs_count[soft_mode]))
483*4882a593Smuzhiyun 		return;
484*4882a593Smuzhiyun 
485*4882a593Smuzhiyun 	pdata->dvs_used[soft_mode] = 0;
486*4882a593Smuzhiyun 
487*4882a593Smuzhiyun 	if (soft_mode < RK806_DVS_START_PWRCTR1)
488*4882a593Smuzhiyun 		offset = soft_mode - RK806_DVS_START1;
489*4882a593Smuzhiyun 	else
490*4882a593Smuzhiyun 		offset = soft_mode - RK806_DVS_START_PWRCTR1;
491*4882a593Smuzhiyun 
492*4882a593Smuzhiyun 	rk806_field_write(rk806, DVS_START1 + offset, 0x01);
493*4882a593Smuzhiyun 	REG_DBG("soft:%s, %s\n", dvs_ctrl_name[soft_mode], rdev->desc->name);
494*4882a593Smuzhiyun }
495*4882a593Smuzhiyun 
rk806_regulator_sync_voltage(struct regulator_dev * rdev)496*4882a593Smuzhiyun static void rk806_regulator_sync_voltage(struct regulator_dev *rdev)
497*4882a593Smuzhiyun {
498*4882a593Smuzhiyun 	int mode;
499*4882a593Smuzhiyun 
500*4882a593Smuzhiyun 	mode = get_dvs_mode(rdev);
501*4882a593Smuzhiyun 	if (mode == RK806_DVS_NOT_SUPPORT)
502*4882a593Smuzhiyun 		return;
503*4882a593Smuzhiyun 
504*4882a593Smuzhiyun 	if ((mode >= RK806_DVS_PWRCTRL1) && (mode <= RK806_DVS_PWRCTRL3))
505*4882a593Smuzhiyun 		rk806_do_gpio_dvs(rdev);
506*4882a593Smuzhiyun 	else
507*4882a593Smuzhiyun 		rk806_do_soft_dvs(rdev);
508*4882a593Smuzhiyun }
509*4882a593Smuzhiyun 
rk806_regulator_of_map_mode(unsigned int mode)510*4882a593Smuzhiyun static unsigned int rk806_regulator_of_map_mode(unsigned int mode)
511*4882a593Smuzhiyun {
512*4882a593Smuzhiyun 	switch (mode) {
513*4882a593Smuzhiyun 	case 1:
514*4882a593Smuzhiyun 		return REGULATOR_MODE_FAST;
515*4882a593Smuzhiyun 	case 2:
516*4882a593Smuzhiyun 		return REGULATOR_MODE_NORMAL;
517*4882a593Smuzhiyun 	default:
518*4882a593Smuzhiyun 		return -EINVAL;
519*4882a593Smuzhiyun 	}
520*4882a593Smuzhiyun }
521*4882a593Smuzhiyun 
rk806_set_suspend_enable_ctrl(struct regulator_dev * rdev,unsigned int en)522*4882a593Smuzhiyun static int rk806_set_suspend_enable_ctrl(struct regulator_dev *rdev,
523*4882a593Smuzhiyun 					 unsigned int en)
524*4882a593Smuzhiyun {
525*4882a593Smuzhiyun 	struct rk806_regulator_data *pdata = rdev_get_drvdata(rdev);
526*4882a593Smuzhiyun 	struct rk806 *rk806 = pdata->rk806;
527*4882a593Smuzhiyun 	int rid = rdev_get_id(rdev);
528*4882a593Smuzhiyun 	unsigned int val;
529*4882a593Smuzhiyun 
530*4882a593Smuzhiyun 	if (en)
531*4882a593Smuzhiyun 		val = 1;
532*4882a593Smuzhiyun 	else
533*4882a593Smuzhiyun 		val = 0;
534*4882a593Smuzhiyun 
535*4882a593Smuzhiyun 	if ((get_dvs_mode(rdev) < RK806_DVS_PWRCTRL1) ||
536*4882a593Smuzhiyun 	    (get_dvs_mode(rdev) > RK806_DVS_PWRCTRL3))
537*4882a593Smuzhiyun 		return rk806_field_write(rk806, pdata->dvs_field[rid].sleep_en, val);
538*4882a593Smuzhiyun 
539*4882a593Smuzhiyun 	pdata->sleep_mode[rid].sleep_en_val = val;
540*4882a593Smuzhiyun 
541*4882a593Smuzhiyun 	return 0;
542*4882a593Smuzhiyun }
543*4882a593Smuzhiyun 
rk806_set_suspend_enable(struct regulator_dev * rdev)544*4882a593Smuzhiyun static int rk806_set_suspend_enable(struct regulator_dev *rdev)
545*4882a593Smuzhiyun {
546*4882a593Smuzhiyun 	return rk806_set_suspend_enable_ctrl(rdev, 1);
547*4882a593Smuzhiyun }
548*4882a593Smuzhiyun 
rk806_set_suspend_disable(struct regulator_dev * rdev)549*4882a593Smuzhiyun static int rk806_set_suspend_disable(struct regulator_dev *rdev)
550*4882a593Smuzhiyun {
551*4882a593Smuzhiyun 	return rk806_set_suspend_enable_ctrl(rdev, 0);
552*4882a593Smuzhiyun }
553*4882a593Smuzhiyun 
rk806_set_mode(struct regulator_dev * rdev,unsigned int mode)554*4882a593Smuzhiyun static int rk806_set_mode(struct regulator_dev *rdev, unsigned int mode)
555*4882a593Smuzhiyun {
556*4882a593Smuzhiyun 	int rid = rdev_get_id(rdev);
557*4882a593Smuzhiyun 	int ctr_bit, reg;
558*4882a593Smuzhiyun 
559*4882a593Smuzhiyun 	if (rid > RK806_ID_DCDC10)
560*4882a593Smuzhiyun 		return 0;
561*4882a593Smuzhiyun 
562*4882a593Smuzhiyun 	reg = RK806_POWER_FPWM_EN0 + rid / 8;
563*4882a593Smuzhiyun 	ctr_bit = rid % 8;
564*4882a593Smuzhiyun 
565*4882a593Smuzhiyun 	switch (mode) {
566*4882a593Smuzhiyun 	case REGULATOR_MODE_FAST:
567*4882a593Smuzhiyun 		return regmap_update_bits(rdev->regmap, reg,
568*4882a593Smuzhiyun 					  PWM_MODE_MSK << ctr_bit,
569*4882a593Smuzhiyun 					  FPWM_MODE << ctr_bit);
570*4882a593Smuzhiyun 	case REGULATOR_MODE_NORMAL:
571*4882a593Smuzhiyun 		return regmap_update_bits(rdev->regmap, reg,
572*4882a593Smuzhiyun 					  PWM_MODE_MSK << ctr_bit,
573*4882a593Smuzhiyun 					  AUTO_PWM_MODE << ctr_bit);
574*4882a593Smuzhiyun 	default:
575*4882a593Smuzhiyun 		dev_err(&rdev->dev, "do not support this mode\n");
576*4882a593Smuzhiyun 		return -EINVAL;
577*4882a593Smuzhiyun 	}
578*4882a593Smuzhiyun 
579*4882a593Smuzhiyun 	return 0;
580*4882a593Smuzhiyun }
581*4882a593Smuzhiyun 
rk806_get_mode(struct regulator_dev * rdev)582*4882a593Smuzhiyun static unsigned int rk806_get_mode(struct regulator_dev *rdev)
583*4882a593Smuzhiyun {
584*4882a593Smuzhiyun 	int rid = rdev_get_id(rdev);
585*4882a593Smuzhiyun 	int ctr_bit, reg;
586*4882a593Smuzhiyun 	unsigned int val;
587*4882a593Smuzhiyun 	int err;
588*4882a593Smuzhiyun 
589*4882a593Smuzhiyun 	if (rid > RK806_ID_DCDC10)
590*4882a593Smuzhiyun 		return 0;
591*4882a593Smuzhiyun 
592*4882a593Smuzhiyun 	reg = RK806_POWER_FPWM_EN0 + rid / 8;
593*4882a593Smuzhiyun 	ctr_bit = rid % 8;
594*4882a593Smuzhiyun 
595*4882a593Smuzhiyun 	err = regmap_read(rdev->regmap, reg, &val);
596*4882a593Smuzhiyun 	if (err)
597*4882a593Smuzhiyun 		return err;
598*4882a593Smuzhiyun 
599*4882a593Smuzhiyun 	if ((val >> ctr_bit) & FPWM_MODE)
600*4882a593Smuzhiyun 		return REGULATOR_MODE_FAST;
601*4882a593Smuzhiyun 	else
602*4882a593Smuzhiyun 		return REGULATOR_MODE_NORMAL;
603*4882a593Smuzhiyun }
604*4882a593Smuzhiyun 
rk806_regulator_sleep2dvs_mode(struct regulator_dev * rdev)605*4882a593Smuzhiyun static int rk806_regulator_sleep2dvs_mode(struct regulator_dev *rdev)
606*4882a593Smuzhiyun {
607*4882a593Smuzhiyun 	struct rk806_regulator_data *pdata = rdev_get_drvdata(rdev);
608*4882a593Smuzhiyun 	struct rk806 *rk806 = pdata->rk806;
609*4882a593Smuzhiyun 	int mode = get_dvs_mode(rdev);
610*4882a593Smuzhiyun 	int rid = rdev_get_id(rdev);
611*4882a593Smuzhiyun 	int pid = get_gpio_id(mode);
612*4882a593Smuzhiyun 	int gpio_level, j;
613*4882a593Smuzhiyun 
614*4882a593Smuzhiyun 	/* set slp_fun NULL*/
615*4882a593Smuzhiyun 	if (pdata->dvs_ctrl_mode[rid] == RK806_DVS_PWRCTRL1)
616*4882a593Smuzhiyun 		rk806_field_write(rk806, PWRCTRL1_FUN, PWRCTRL_DVS_FUN);
617*4882a593Smuzhiyun 	else if (pdata->dvs_ctrl_mode[rid] == RK806_DVS_PWRCTRL2)
618*4882a593Smuzhiyun 		rk806_field_write(rk806, PWRCTRL2_FUN, PWRCTRL_DVS_FUN);
619*4882a593Smuzhiyun 	else if (pdata->dvs_ctrl_mode[rid] == RK806_DVS_PWRCTRL3)
620*4882a593Smuzhiyun 		rk806_field_write(rk806, PWRCTRL3_FUN, PWRCTRL_DVS_FUN);
621*4882a593Smuzhiyun 
622*4882a593Smuzhiyun 
623*4882a593Smuzhiyun 	/* 3.check the used count 1*/
624*4882a593Smuzhiyun 	pdata->dvs_used[mode] |= BIT(rid);
625*4882a593Smuzhiyun 	if (pdata->dvs_used[mode] != pdata->dvs_flag[mode])
626*4882a593Smuzhiyun 		return 0;
627*4882a593Smuzhiyun 
628*4882a593Smuzhiyun 	pdata->dvs_used[mode] = 0;
629*4882a593Smuzhiyun 	/* 5.clear the SLP_CTRL_SEL */
630*4882a593Smuzhiyun 	for (j = 0; j < RK806_ID_END; j++)
631*4882a593Smuzhiyun 		if (pdata->dvs_ctrl_mode[j] == mode)
632*4882a593Smuzhiyun 			rk806_field_write(rk806,
633*4882a593Smuzhiyun 					  pdata->dvs_field[j].vsel_ctrl_sel,
634*4882a593Smuzhiyun 					  pdata->dvs_ctrl_mode[j]);
635*4882a593Smuzhiyun 
636*4882a593Smuzhiyun 	if ((pid >= 0) && (pdata->dvs_gpios[pid] != NULL)) {
637*4882a593Smuzhiyun 		gpio_level = pdata->dvs_mode[rid].dvs_gpio_level[pid];
638*4882a593Smuzhiyun 		if (gpio_level == 1) {
639*4882a593Smuzhiyun 			gpiod_set_value(pdata->dvs_gpios[pid], 0);
640*4882a593Smuzhiyun 			rk806_field_write(rk806,
641*4882a593Smuzhiyun 					  pdata->dvs_field[rid].on_vsel,
642*4882a593Smuzhiyun 					  pdata->dvs_mode[rid].on_vsel_val);
643*4882a593Smuzhiyun 			rk806_field_write(rk806,
644*4882a593Smuzhiyun 					  pdata->dvs_field[rid].en_reg,
645*4882a593Smuzhiyun 					  pdata->dvs_mode[rid].en_reg_val | (pdata->dvs_field[rid].en_bit << 4));
646*4882a593Smuzhiyun 		}
647*4882a593Smuzhiyun 	}
648*4882a593Smuzhiyun 	return 0;
649*4882a593Smuzhiyun }
650*4882a593Smuzhiyun 
rk806_regulator_resume(struct regulator_dev * rdev)651*4882a593Smuzhiyun static int rk806_regulator_resume(struct regulator_dev *rdev)
652*4882a593Smuzhiyun {
653*4882a593Smuzhiyun 	struct rk806_regulator_data *pdata = rdev_get_drvdata(rdev);
654*4882a593Smuzhiyun 	struct rk806 *rk806 = pdata->rk806;
655*4882a593Smuzhiyun 	int rid = rdev_get_id(rdev);
656*4882a593Smuzhiyun 	int j;
657*4882a593Smuzhiyun 
658*4882a593Smuzhiyun 	if (!pdata->support_dvs)
659*4882a593Smuzhiyun 		return 0;
660*4882a593Smuzhiyun 
661*4882a593Smuzhiyun 	if (rid == RK806_ID_DCDC1) {
662*4882a593Smuzhiyun 		for (j = 0; j < RK806_ID_END; j++) {
663*4882a593Smuzhiyun 			rk806_field_write(rk806,
664*4882a593Smuzhiyun 					  pdata->dvs_field[j].vsel_ctrl_sel,
665*4882a593Smuzhiyun 					  0x00);
666*4882a593Smuzhiyun 			rk806_field_write(rk806,
667*4882a593Smuzhiyun 					  pdata->dvs_field[j].sleep_vsel,
668*4882a593Smuzhiyun 					  pdata->dvs_mode[j].sleep_vsel_val);
669*4882a593Smuzhiyun 			rk806_field_write(rk806,
670*4882a593Smuzhiyun 					  pdata->dvs_field[j].sleep_en,
671*4882a593Smuzhiyun 					  pdata->dvs_mode[j].sleep_en_val);
672*4882a593Smuzhiyun 		}
673*4882a593Smuzhiyun 	}
674*4882a593Smuzhiyun 
675*4882a593Smuzhiyun 	if ((get_dvs_mode(rdev) >= RK806_DVS_PWRCTRL1) &&
676*4882a593Smuzhiyun 	    (get_dvs_mode(rdev) <= RK806_DVS_PWRCTRL3))
677*4882a593Smuzhiyun 		rk806_regulator_sleep2dvs_mode(rdev);
678*4882a593Smuzhiyun 	return 0;
679*4882a593Smuzhiyun }
680*4882a593Smuzhiyun 
rk806_set_suspend_voltage_range(struct regulator_dev * rdev,int uv)681*4882a593Smuzhiyun static int rk806_set_suspend_voltage_range(struct regulator_dev *rdev, int uv)
682*4882a593Smuzhiyun {
683*4882a593Smuzhiyun 	struct rk806_regulator_data *pdata = rdev_get_drvdata(rdev);
684*4882a593Smuzhiyun 	int sel = regulator_map_voltage_linear_range(rdev, uv, uv);
685*4882a593Smuzhiyun 	struct rk806 *rk806 = pdata->rk806;
686*4882a593Smuzhiyun 	int rid = rdev_get_id(rdev);
687*4882a593Smuzhiyun 	int reg_offset;
688*4882a593Smuzhiyun 	unsigned int reg;
689*4882a593Smuzhiyun 
690*4882a593Smuzhiyun 	if (sel < 0)
691*4882a593Smuzhiyun 		return -EINVAL;
692*4882a593Smuzhiyun 
693*4882a593Smuzhiyun 	reg_offset = rk806_get_reg_offset(rid);
694*4882a593Smuzhiyun 	reg = rdev->desc->vsel_reg + reg_offset;
695*4882a593Smuzhiyun 
696*4882a593Smuzhiyun 	return regmap_update_bits(rk806->regmap, reg,
697*4882a593Smuzhiyun 				  rdev->desc->vsel_mask,
698*4882a593Smuzhiyun 				  sel);
699*4882a593Smuzhiyun }
700*4882a593Smuzhiyun 
rk806_get_voltage_sel_regmap(struct regulator_dev * rdev)701*4882a593Smuzhiyun static int rk806_get_voltage_sel_regmap(struct regulator_dev *rdev)
702*4882a593Smuzhiyun {
703*4882a593Smuzhiyun 	unsigned int val;
704*4882a593Smuzhiyun 	int vsel_reg;
705*4882a593Smuzhiyun 	int ret;
706*4882a593Smuzhiyun 
707*4882a593Smuzhiyun 	vsel_reg = rk806_get_read_vsel_register(rdev);
708*4882a593Smuzhiyun 
709*4882a593Smuzhiyun 	ret = regmap_read(rdev->regmap, vsel_reg, &val);
710*4882a593Smuzhiyun 	if (ret != 0)
711*4882a593Smuzhiyun 		return ret;
712*4882a593Smuzhiyun 
713*4882a593Smuzhiyun 	val &= rdev->desc->vsel_mask;
714*4882a593Smuzhiyun 	val >>= ffs(rdev->desc->vsel_mask) - 1;
715*4882a593Smuzhiyun 
716*4882a593Smuzhiyun 	return val;
717*4882a593Smuzhiyun }
718*4882a593Smuzhiyun 
rk806_set_voltage(struct regulator_dev * rdev,int req_min_uV,int req_max_uV,unsigned int * selector)719*4882a593Smuzhiyun static int rk806_set_voltage(struct regulator_dev *rdev,
720*4882a593Smuzhiyun 			     int req_min_uV, int req_max_uV,
721*4882a593Smuzhiyun 			     unsigned int *selector)
722*4882a593Smuzhiyun {
723*4882a593Smuzhiyun 	int vsel_reg;
724*4882a593Smuzhiyun 	int mode;
725*4882a593Smuzhiyun 	int ret;
726*4882a593Smuzhiyun 	int sel;
727*4882a593Smuzhiyun 
728*4882a593Smuzhiyun 	ret = regulator_map_voltage_linear_range(rdev, req_min_uV, req_max_uV);
729*4882a593Smuzhiyun 	if (ret >= 0) {
730*4882a593Smuzhiyun 		*selector = ret;
731*4882a593Smuzhiyun 		sel = ret;
732*4882a593Smuzhiyun 	} else {
733*4882a593Smuzhiyun 		return -EINVAL;
734*4882a593Smuzhiyun 	}
735*4882a593Smuzhiyun 
736*4882a593Smuzhiyun 	vsel_reg = rk806_get_write_vsel_register(rdev);
737*4882a593Smuzhiyun 
738*4882a593Smuzhiyun 	sel <<= ffs(rdev->desc->vsel_mask) - 1;
739*4882a593Smuzhiyun 
740*4882a593Smuzhiyun 	ret = regmap_update_bits(rdev->regmap, vsel_reg,
741*4882a593Smuzhiyun 				 rdev->desc->vsel_mask, sel);
742*4882a593Smuzhiyun 
743*4882a593Smuzhiyun 	mode = get_dvs_mode(rdev);
744*4882a593Smuzhiyun 	if (mode == RK806_DVS_NOT_SUPPORT)
745*4882a593Smuzhiyun 		return ret;
746*4882a593Smuzhiyun 
747*4882a593Smuzhiyun 	if ((mode >= RK806_DVS_PWRCTRL1) &&
748*4882a593Smuzhiyun 	    (mode <= RK806_DVS_PWRCTRL3))
749*4882a593Smuzhiyun 		rk806_do_gpio_dvs(rdev);
750*4882a593Smuzhiyun 	else
751*4882a593Smuzhiyun 		rk806_do_soft_dvs(rdev);
752*4882a593Smuzhiyun 
753*4882a593Smuzhiyun 	return ret;
754*4882a593Smuzhiyun }
755*4882a593Smuzhiyun 
rk806_regulator_is_enabled_regmap(struct regulator_dev * rdev)756*4882a593Smuzhiyun static int rk806_regulator_is_enabled_regmap(struct regulator_dev *rdev)
757*4882a593Smuzhiyun {
758*4882a593Smuzhiyun 	struct rk806_regulator_data *pdata = rdev_get_drvdata(rdev);
759*4882a593Smuzhiyun 	struct rk806 *rk806 = pdata->rk806;
760*4882a593Smuzhiyun 	int rid = rdev_get_id(rdev);
761*4882a593Smuzhiyun 	int gpio_level, pid;
762*4882a593Smuzhiyun 	unsigned int val;
763*4882a593Smuzhiyun 	int mode;
764*4882a593Smuzhiyun 
765*4882a593Smuzhiyun 	mode = get_dvs_mode(rdev);
766*4882a593Smuzhiyun 	pid = get_gpio_id(mode);
767*4882a593Smuzhiyun 	if ((pid >= 0) && (pdata->dvs_gpios[pid] != NULL)) {
768*4882a593Smuzhiyun 		gpio_level = gpiod_get_value(pdata->dvs_gpios[pid]);
769*4882a593Smuzhiyun 		if (gpio_level == 0)
770*4882a593Smuzhiyun 			return rk806_field_read(rk806, pdata->dvs_field[rid].sleep_en);
771*4882a593Smuzhiyun 	}
772*4882a593Smuzhiyun 
773*4882a593Smuzhiyun 	val = rk806_field_read(rk806, pdata->dvs_field[rid].en_reg);
774*4882a593Smuzhiyun 	return (val & rdev->desc->enable_val) != 0;
775*4882a593Smuzhiyun }
776*4882a593Smuzhiyun 
rk806_regulator_enable_regmap(struct regulator_dev * rdev)777*4882a593Smuzhiyun static int rk806_regulator_enable_regmap(struct regulator_dev *rdev)
778*4882a593Smuzhiyun {
779*4882a593Smuzhiyun 	struct rk806_regulator_data *pdata = rdev_get_drvdata(rdev);
780*4882a593Smuzhiyun 	struct rk806 *rk806 = pdata->rk806;
781*4882a593Smuzhiyun 	int rid = rdev_get_id(rdev);
782*4882a593Smuzhiyun 	int gpio_level, pid;
783*4882a593Smuzhiyun 	int mode;
784*4882a593Smuzhiyun 
785*4882a593Smuzhiyun 	mode = get_dvs_mode(rdev);
786*4882a593Smuzhiyun 	pid = get_gpio_id(mode);
787*4882a593Smuzhiyun 	if ((pid >= 0) && (pdata->dvs_gpios[pid] != NULL)) {
788*4882a593Smuzhiyun 		gpio_level = gpiod_get_value(pdata->dvs_gpios[pid]);
789*4882a593Smuzhiyun 		if (gpio_level == 0)
790*4882a593Smuzhiyun 			return rk806_field_write(rk806,
791*4882a593Smuzhiyun 						 pdata->dvs_field[rid].sleep_en,
792*4882a593Smuzhiyun 						 0x01);
793*4882a593Smuzhiyun 	}
794*4882a593Smuzhiyun 
795*4882a593Smuzhiyun 	return rk806_field_write(rk806,
796*4882a593Smuzhiyun 				 pdata->dvs_field[rid].en_reg,
797*4882a593Smuzhiyun 				 rdev->desc->enable_val);
798*4882a593Smuzhiyun }
799*4882a593Smuzhiyun 
rk806_regulator_disable_regmap(struct regulator_dev * rdev)800*4882a593Smuzhiyun static int rk806_regulator_disable_regmap(struct regulator_dev *rdev)
801*4882a593Smuzhiyun {
802*4882a593Smuzhiyun 	struct rk806_regulator_data *pdata = rdev_get_drvdata(rdev);
803*4882a593Smuzhiyun 	struct rk806 *rk806 = pdata->rk806;
804*4882a593Smuzhiyun 	int rid = rdev_get_id(rdev);
805*4882a593Smuzhiyun 	int gpio_level, pid;
806*4882a593Smuzhiyun 	int mode;
807*4882a593Smuzhiyun 
808*4882a593Smuzhiyun 	mode = get_dvs_mode(rdev);
809*4882a593Smuzhiyun 	pid = get_gpio_id(mode);
810*4882a593Smuzhiyun 	if ((pid >= 0) && (pdata->dvs_gpios[pid] != NULL)) {
811*4882a593Smuzhiyun 		gpio_level = gpiod_get_value(pdata->dvs_gpios[pid]);
812*4882a593Smuzhiyun 		if (gpio_level == 0)
813*4882a593Smuzhiyun 			return rk806_field_write(rk806,
814*4882a593Smuzhiyun 						 pdata->dvs_field[rid].sleep_en,
815*4882a593Smuzhiyun 						 0x00);
816*4882a593Smuzhiyun 	}
817*4882a593Smuzhiyun 
818*4882a593Smuzhiyun 	return rk806_field_write(rk806,
819*4882a593Smuzhiyun 				 pdata->dvs_field[rid].en_reg,
820*4882a593Smuzhiyun 				 rdev->desc->disable_val);
821*4882a593Smuzhiyun }
822*4882a593Smuzhiyun 
rk806_set_ramp_delay(struct regulator_dev * rdev,int ramp_delay)823*4882a593Smuzhiyun static int rk806_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
824*4882a593Smuzhiyun {
825*4882a593Smuzhiyun 	unsigned int ramp_value = RK806_RAMP_RATE_2LSB_PER_1CLK;
826*4882a593Smuzhiyun 	struct rk806_regulator_data *pdata = rdev_get_drvdata(rdev);
827*4882a593Smuzhiyun 	struct rk806 *rk806 = pdata->rk806;
828*4882a593Smuzhiyun 	int rid = rdev_get_id(rdev);
829*4882a593Smuzhiyun 
830*4882a593Smuzhiyun 	if (rid <= RK806_ID_DCDC10) {
831*4882a593Smuzhiyun 		switch (ramp_delay) {
832*4882a593Smuzhiyun 		case 1 ... 390:
833*4882a593Smuzhiyun 			ramp_value = RK806_RAMP_RATE_1LSB_PER_32CLK;
834*4882a593Smuzhiyun 			break;
835*4882a593Smuzhiyun 		case 391 ... 961:
836*4882a593Smuzhiyun 			ramp_value = RK806_RAMP_RATE_1LSB_PER_13CLK;
837*4882a593Smuzhiyun 			break;
838*4882a593Smuzhiyun 		case 962 ... 1560:
839*4882a593Smuzhiyun 			ramp_value = RK806_RAMP_RATE_1LSB_PER_8CLK;
840*4882a593Smuzhiyun 			break;
841*4882a593Smuzhiyun 		case 1561 ... 3125:
842*4882a593Smuzhiyun 			ramp_value = RK806_RAMP_RATE_1LSB_PER_4CLK;
843*4882a593Smuzhiyun 			break;
844*4882a593Smuzhiyun 		case 3126 ... 6250:
845*4882a593Smuzhiyun 			ramp_value = RK806_RAMP_RATE_1LSB_PER_2CLK;
846*4882a593Smuzhiyun 			break;
847*4882a593Smuzhiyun 		case 6251 ... 12500:
848*4882a593Smuzhiyun 			ramp_value = RK806_RAMP_RATE_1LSB_PER_1CLK;
849*4882a593Smuzhiyun 			break;
850*4882a593Smuzhiyun 		case 12501 ... 25000:
851*4882a593Smuzhiyun 			ramp_value = RK806_RAMP_RATE_2LSB_PER_1CLK;
852*4882a593Smuzhiyun 			break;
853*4882a593Smuzhiyun 		case 25001 ... 50000: /* 50mV/us */
854*4882a593Smuzhiyun 			ramp_value = RK806_RAMP_RATE_4LSB_PER_1CLK;
855*4882a593Smuzhiyun 			break;
856*4882a593Smuzhiyun 		default:
857*4882a593Smuzhiyun 			pr_warn("%s ramp_delay: %d not supported, setting 10000\n",
858*4882a593Smuzhiyun 				rdev->desc->name, ramp_delay);
859*4882a593Smuzhiyun 		}
860*4882a593Smuzhiyun 
861*4882a593Smuzhiyun 		rk806_field_write(rk806,
862*4882a593Smuzhiyun 				  rk806_buck_rate_config_field[rid][0],
863*4882a593Smuzhiyun 				  ramp_value & 0x03);
864*4882a593Smuzhiyun 		return rk806_field_write(rk806,
865*4882a593Smuzhiyun 					 rk806_buck_rate_config_field[rid][1],
866*4882a593Smuzhiyun 					 (ramp_value & 0x4) >> 2);
867*4882a593Smuzhiyun 	} else {
868*4882a593Smuzhiyun 		switch (ramp_delay) {
869*4882a593Smuzhiyun 		case 1 ... 780:
870*4882a593Smuzhiyun 			ramp_value = RK806_RAMP_RATE_1LSB_PER_32CLK;
871*4882a593Smuzhiyun 			break;
872*4882a593Smuzhiyun 		case 781 ... 1900:
873*4882a593Smuzhiyun 			ramp_value = RK806_RAMP_RATE_1LSB_PER_13CLK;
874*4882a593Smuzhiyun 			break;
875*4882a593Smuzhiyun 		case 1901 ... 3120:
876*4882a593Smuzhiyun 			ramp_value = RK806_RAMP_RATE_1LSB_PER_8CLK;
877*4882a593Smuzhiyun 			break;
878*4882a593Smuzhiyun 		case 3121 ... 6280:
879*4882a593Smuzhiyun 			ramp_value = RK806_RAMP_RATE_1LSB_PER_4CLK;
880*4882a593Smuzhiyun 			break;
881*4882a593Smuzhiyun 		case 6281 ... 12500:
882*4882a593Smuzhiyun 			ramp_value = RK806_RAMP_RATE_1LSB_PER_2CLK;
883*4882a593Smuzhiyun 			break;
884*4882a593Smuzhiyun 		case 12501 ... 25000:
885*4882a593Smuzhiyun 			ramp_value = RK806_RAMP_RATE_1LSB_PER_1CLK;
886*4882a593Smuzhiyun 			break;
887*4882a593Smuzhiyun 		case 25001 ... 50000:
888*4882a593Smuzhiyun 			ramp_value = RK806_RAMP_RATE_2LSB_PER_1CLK;
889*4882a593Smuzhiyun 			break;
890*4882a593Smuzhiyun 		case 50001 ... 100000:
891*4882a593Smuzhiyun 			ramp_value = RK806_RAMP_RATE_4LSB_PER_1CLK;
892*4882a593Smuzhiyun 			break;
893*4882a593Smuzhiyun 		default:
894*4882a593Smuzhiyun 			pr_warn("%s ramp_delay: %d not supported, setting 10000\n",
895*4882a593Smuzhiyun 				rdev->desc->name, ramp_delay);
896*4882a593Smuzhiyun 		}
897*4882a593Smuzhiyun 		return rk806_field_write(rk806, LDO_RATE, ramp_value);
898*4882a593Smuzhiyun 	}
899*4882a593Smuzhiyun }
900*4882a593Smuzhiyun 
901*4882a593Smuzhiyun static const struct regulator_ops rk806_ops_dcdc = {
902*4882a593Smuzhiyun 	.list_voltage		= regulator_list_voltage_linear_range,
903*4882a593Smuzhiyun 	.map_voltage		= regulator_map_voltage_linear_range,
904*4882a593Smuzhiyun 
905*4882a593Smuzhiyun 	.get_voltage_sel	= rk806_get_voltage_sel_regmap,
906*4882a593Smuzhiyun 	.set_voltage		= rk806_set_voltage,
907*4882a593Smuzhiyun 	.set_voltage_time_sel	= regulator_set_voltage_time_sel,
908*4882a593Smuzhiyun 	.set_mode		= rk806_set_mode,
909*4882a593Smuzhiyun 	.get_mode		= rk806_get_mode,
910*4882a593Smuzhiyun 
911*4882a593Smuzhiyun 	.enable			= rk806_regulator_enable_regmap,
912*4882a593Smuzhiyun 	.disable		= rk806_regulator_disable_regmap,
913*4882a593Smuzhiyun 	.is_enabled		= rk806_regulator_is_enabled_regmap,
914*4882a593Smuzhiyun 
915*4882a593Smuzhiyun 	.set_suspend_mode	= rk806_set_mode,
916*4882a593Smuzhiyun 	.set_ramp_delay		= rk806_set_ramp_delay,
917*4882a593Smuzhiyun 
918*4882a593Smuzhiyun 	.set_suspend_voltage	= rk806_set_suspend_voltage_range,
919*4882a593Smuzhiyun 	.resume			= rk806_regulator_resume,
920*4882a593Smuzhiyun 	.set_suspend_enable	= rk806_set_suspend_enable,
921*4882a593Smuzhiyun 	.set_suspend_disable	= rk806_set_suspend_disable,
922*4882a593Smuzhiyun };
923*4882a593Smuzhiyun 
924*4882a593Smuzhiyun static const struct regulator_ops rk806_ops_ldo = {
925*4882a593Smuzhiyun 	.list_voltage		= regulator_list_voltage_linear_range,
926*4882a593Smuzhiyun 	.map_voltage		= regulator_map_voltage_linear_range,
927*4882a593Smuzhiyun 
928*4882a593Smuzhiyun 	.get_voltage_sel	= rk806_get_voltage_sel_regmap,
929*4882a593Smuzhiyun 	.set_voltage		= rk806_set_voltage,
930*4882a593Smuzhiyun 	.set_voltage_time_sel	= regulator_set_voltage_time_sel,
931*4882a593Smuzhiyun 
932*4882a593Smuzhiyun 	.enable			= rk806_regulator_enable_regmap,
933*4882a593Smuzhiyun 	.disable		= rk806_regulator_disable_regmap,
934*4882a593Smuzhiyun 	.is_enabled		= rk806_regulator_is_enabled_regmap,
935*4882a593Smuzhiyun 
936*4882a593Smuzhiyun 	.set_suspend_mode	= rk806_set_mode,
937*4882a593Smuzhiyun 	.set_ramp_delay		= rk806_set_ramp_delay,
938*4882a593Smuzhiyun 
939*4882a593Smuzhiyun 	.set_suspend_voltage	= rk806_set_suspend_voltage_range,
940*4882a593Smuzhiyun 	.resume			= rk806_regulator_resume,
941*4882a593Smuzhiyun 	.set_suspend_enable	= rk806_set_suspend_enable,
942*4882a593Smuzhiyun 	.set_suspend_disable	= rk806_set_suspend_disable,
943*4882a593Smuzhiyun };
944*4882a593Smuzhiyun 
945*4882a593Smuzhiyun #define RK806_REGULATOR(_name, _supply_name, _id, _ops,\
946*4882a593Smuzhiyun 			_n_voltages, _vr, _er, _lr, ctrl_bit)\
947*4882a593Smuzhiyun [_id] = {\
948*4882a593Smuzhiyun 		.name = _name,\
949*4882a593Smuzhiyun 		.supply_name = _supply_name,\
950*4882a593Smuzhiyun 		.of_match = of_match_ptr(_name),\
951*4882a593Smuzhiyun 		.regulators_node = of_match_ptr("regulators"),\
952*4882a593Smuzhiyun 		.id = _id,\
953*4882a593Smuzhiyun 		.ops = &_ops,\
954*4882a593Smuzhiyun 		.type = REGULATOR_VOLTAGE,\
955*4882a593Smuzhiyun 		.n_voltages = _n_voltages,\
956*4882a593Smuzhiyun 		.linear_ranges = _lr,\
957*4882a593Smuzhiyun 		.n_linear_ranges = ARRAY_SIZE(_lr),\
958*4882a593Smuzhiyun 		.vsel_reg = _vr,\
959*4882a593Smuzhiyun 		.vsel_mask = 0xff,\
960*4882a593Smuzhiyun 		.enable_reg = _er,\
961*4882a593Smuzhiyun 		.enable_mask = ENABLE_MASK(ctrl_bit),\
962*4882a593Smuzhiyun 		.enable_val = ENABLE_MASK(ctrl_bit),\
963*4882a593Smuzhiyun 		.disable_val = DISABLE_VAL(ctrl_bit),\
964*4882a593Smuzhiyun 		.of_map_mode = rk806_regulator_of_map_mode,\
965*4882a593Smuzhiyun 		.owner = THIS_MODULE,\
966*4882a593Smuzhiyun 	}
967*4882a593Smuzhiyun 
968*4882a593Smuzhiyun static const struct regulator_desc rk806_regulators[] = {
969*4882a593Smuzhiyun 	RK806_REGULATOR("DCDC_REG1", "vcc1", RK806_ID_DCDC1, rk806_ops_dcdc,
970*4882a593Smuzhiyun 			RK806_BUCK_SEL_CNT, RK806_BUCK1_ON_VSEL,
971*4882a593Smuzhiyun 			RK806_POWER_EN0, rk806_buck_voltage_ranges, 0),
972*4882a593Smuzhiyun 	RK806_REGULATOR("DCDC_REG2", "vcc2", RK806_ID_DCDC2, rk806_ops_dcdc,
973*4882a593Smuzhiyun 			RK806_BUCK_SEL_CNT, RK806_BUCK2_ON_VSEL,
974*4882a593Smuzhiyun 			RK806_POWER_EN0, rk806_buck_voltage_ranges, 1),
975*4882a593Smuzhiyun 	RK806_REGULATOR("DCDC_REG3", "vcc3", RK806_ID_DCDC3, rk806_ops_dcdc,
976*4882a593Smuzhiyun 			RK806_BUCK_SEL_CNT, RK806_BUCK3_ON_VSEL,
977*4882a593Smuzhiyun 			RK806_POWER_EN0, rk806_buck_voltage_ranges, 2),
978*4882a593Smuzhiyun 	RK806_REGULATOR("DCDC_REG4", "vcc4", RK806_ID_DCDC4, rk806_ops_dcdc,
979*4882a593Smuzhiyun 			RK806_BUCK_SEL_CNT, RK806_BUCK4_ON_VSEL,
980*4882a593Smuzhiyun 			RK806_POWER_EN0, rk806_buck_voltage_ranges, 3),
981*4882a593Smuzhiyun 
982*4882a593Smuzhiyun 	RK806_REGULATOR("DCDC_REG5", "vcc5", RK806_ID_DCDC5, rk806_ops_dcdc,
983*4882a593Smuzhiyun 			RK806_BUCK_SEL_CNT, RK806_BUCK5_ON_VSEL,
984*4882a593Smuzhiyun 			RK806_POWER_EN1, rk806_buck_voltage_ranges, 0),
985*4882a593Smuzhiyun 	RK806_REGULATOR("DCDC_REG6", "vcc6", RK806_ID_DCDC6, rk806_ops_dcdc,
986*4882a593Smuzhiyun 			RK806_BUCK_SEL_CNT, RK806_BUCK6_ON_VSEL,
987*4882a593Smuzhiyun 			RK806_POWER_EN1, rk806_buck_voltage_ranges, 1),
988*4882a593Smuzhiyun 	RK806_REGULATOR("DCDC_REG7", "vcc7", RK806_ID_DCDC7, rk806_ops_dcdc,
989*4882a593Smuzhiyun 			RK806_BUCK_SEL_CNT, RK806_BUCK7_ON_VSEL,
990*4882a593Smuzhiyun 			RK806_POWER_EN1, rk806_buck_voltage_ranges, 2),
991*4882a593Smuzhiyun 	RK806_REGULATOR("DCDC_REG8", "vcc8", RK806_ID_DCDC8, rk806_ops_dcdc,
992*4882a593Smuzhiyun 			RK806_BUCK_SEL_CNT, RK806_BUCK8_ON_VSEL,
993*4882a593Smuzhiyun 			RK806_POWER_EN1, rk806_buck_voltage_ranges, 3),
994*4882a593Smuzhiyun 
995*4882a593Smuzhiyun 	RK806_REGULATOR("DCDC_REG9", "vcc9", RK806_ID_DCDC9, rk806_ops_dcdc,
996*4882a593Smuzhiyun 			RK806_BUCK_SEL_CNT, RK806_BUCK9_ON_VSEL,
997*4882a593Smuzhiyun 			RK806_POWER_EN2, rk806_buck_voltage_ranges, 0),
998*4882a593Smuzhiyun 	RK806_REGULATOR("DCDC_REG10", "vcc10", RK806_ID_DCDC10, rk806_ops_dcdc,
999*4882a593Smuzhiyun 			RK806_BUCK_SEL_CNT, RK806_BUCK10_ON_VSEL,
1000*4882a593Smuzhiyun 			RK806_POWER_EN2, rk806_buck_voltage_ranges, 1),
1001*4882a593Smuzhiyun 
1002*4882a593Smuzhiyun 	RK806_REGULATOR("NLDO_REG1", "vcc13", RK806_ID_NLDO1, rk806_ops_ldo,
1003*4882a593Smuzhiyun 			RK806_LDO_SEL_CNT, RK806_NLDO1_ON_VSEL,
1004*4882a593Smuzhiyun 			RK806_POWER_EN3, rk806_ldo_voltage_ranges, 0),
1005*4882a593Smuzhiyun 	RK806_REGULATOR("NLDO_REG2", "vcc13", RK806_ID_NLDO2, rk806_ops_ldo,
1006*4882a593Smuzhiyun 			RK806_LDO_SEL_CNT, RK806_NLDO2_ON_VSEL,
1007*4882a593Smuzhiyun 			RK806_POWER_EN3, rk806_ldo_voltage_ranges, 1),
1008*4882a593Smuzhiyun 	RK806_REGULATOR("NLDO_REG3", "vcc13", RK806_ID_NLDO3, rk806_ops_ldo,
1009*4882a593Smuzhiyun 			RK806_LDO_SEL_CNT, RK806_NLDO3_ON_VSEL,
1010*4882a593Smuzhiyun 			RK806_POWER_EN3, rk806_ldo_voltage_ranges, 2),
1011*4882a593Smuzhiyun 	RK806_REGULATOR("NLDO_REG4", "vcc14", RK806_ID_NLDO4, rk806_ops_ldo,
1012*4882a593Smuzhiyun 			RK806_LDO_SEL_CNT, RK806_NLDO4_ON_VSEL,
1013*4882a593Smuzhiyun 			RK806_POWER_EN3, rk806_ldo_voltage_ranges, 3),
1014*4882a593Smuzhiyun 
1015*4882a593Smuzhiyun 	RK806_REGULATOR("NLDO_REG5", "vcc14", RK806_ID_NLDO5, rk806_ops_ldo,
1016*4882a593Smuzhiyun 			RK806_LDO_SEL_CNT, RK806_NLDO5_ON_VSEL,
1017*4882a593Smuzhiyun 			RK806_POWER_EN5, rk806_ldo_voltage_ranges, 2),
1018*4882a593Smuzhiyun 
1019*4882a593Smuzhiyun 	RK806_REGULATOR("PLDO_REG1", "vcc11", RK806_ID_PLDO1, rk806_ops_ldo,
1020*4882a593Smuzhiyun 			RK806_LDO_SEL_CNT, RK806_PLDO1_ON_VSEL,
1021*4882a593Smuzhiyun 			RK806_POWER_EN4, rk806_ldo_voltage_ranges, 1),
1022*4882a593Smuzhiyun 	RK806_REGULATOR("PLDO_REG2", "vcc11", RK806_ID_PLDO2, rk806_ops_ldo,
1023*4882a593Smuzhiyun 			RK806_LDO_SEL_CNT, RK806_PLDO2_ON_VSEL,
1024*4882a593Smuzhiyun 			RK806_POWER_EN4, rk806_ldo_voltage_ranges, 2),
1025*4882a593Smuzhiyun 	RK806_REGULATOR("PLDO_REG3", "vcc11", RK806_ID_PLDO3, rk806_ops_ldo,
1026*4882a593Smuzhiyun 			RK806_LDO_SEL_CNT, RK806_PLDO3_ON_VSEL,
1027*4882a593Smuzhiyun 			RK806_POWER_EN4, rk806_ldo_voltage_ranges, 3),
1028*4882a593Smuzhiyun 
1029*4882a593Smuzhiyun 	RK806_REGULATOR("PLDO_REG4", "vcc12", RK806_ID_PLDO4, rk806_ops_ldo,
1030*4882a593Smuzhiyun 			RK806_LDO_SEL_CNT, RK806_PLDO4_ON_VSEL,
1031*4882a593Smuzhiyun 			RK806_POWER_EN5, rk806_ldo_voltage_ranges, 0),
1032*4882a593Smuzhiyun 	RK806_REGULATOR("PLDO_REG5", "vcc12", RK806_ID_PLDO5, rk806_ops_ldo,
1033*4882a593Smuzhiyun 			RK806_LDO_SEL_CNT, RK806_PLDO5_ON_VSEL,
1034*4882a593Smuzhiyun 			RK806_POWER_EN5, rk806_ldo_voltage_ranges, 1),
1035*4882a593Smuzhiyun 
1036*4882a593Smuzhiyun 	RK806_REGULATOR("PLDO_REG6", "vcca", RK806_ID_PLDO6, rk806_ops_ldo,
1037*4882a593Smuzhiyun 			RK806_LDO_SEL_CNT, RK806_PLDO6_ON_VSEL,
1038*4882a593Smuzhiyun 			RK806_POWER_EN4, rk806_ldo_voltage_ranges, 0),
1039*4882a593Smuzhiyun };
1040*4882a593Smuzhiyun 
rk806_regulator_dt_parse_pdata(struct rk806 * rk806,struct regmap * map,struct rk806_regulator_data * pdata)1041*4882a593Smuzhiyun static void rk806_regulator_dt_parse_pdata(struct rk806 *rk806,
1042*4882a593Smuzhiyun 					   struct regmap *map,
1043*4882a593Smuzhiyun 					   struct rk806_regulator_data *pdata)
1044*4882a593Smuzhiyun 
1045*4882a593Smuzhiyun {
1046*4882a593Smuzhiyun 	char dvs_ctrl_name[10][32] = {
1047*4882a593Smuzhiyun 					"dvs_default",
1048*4882a593Smuzhiyun 					"start_dvs1_ctrl",
1049*4882a593Smuzhiyun 					"start_dvs2_ctrl",
1050*4882a593Smuzhiyun 					"start_dvs3_ctrl",
1051*4882a593Smuzhiyun 					"dvs_pin1_ctrl",
1052*4882a593Smuzhiyun 					"dvs_pin2_ctrl",
1053*4882a593Smuzhiyun 					"dvs_pin3_ctrl",
1054*4882a593Smuzhiyun 					"start_and_pwrctrl1",
1055*4882a593Smuzhiyun 					"start_and_pwrctrl2",
1056*4882a593Smuzhiyun 					"start_and_pwrctrl3"};
1057*4882a593Smuzhiyun 	char dvs_pin_name[3][30] = { "rk806,pmic-dvs-gpio1",
1058*4882a593Smuzhiyun 				     "rk806,pmic-dvs-gpio2",
1059*4882a593Smuzhiyun 				     "rk806,pmic-dvs-gpio3" };
1060*4882a593Smuzhiyun 	struct device_node *np = rk806->dev->of_node;
1061*4882a593Smuzhiyun 	struct device_node *dn;
1062*4882a593Smuzhiyun 	int i, j;
1063*4882a593Smuzhiyun 
1064*4882a593Smuzhiyun 	pdata->support_dvs = 0;
1065*4882a593Smuzhiyun 
1066*4882a593Smuzhiyun 	for (i = 0; i < RK806_ID_END; i++) {
1067*4882a593Smuzhiyun 		pdata->dvs_field[i] = rk806_dvs_fields[i];
1068*4882a593Smuzhiyun 		pdata->dvs_ctrl_id[i] = start_dvs_id[i];
1069*4882a593Smuzhiyun 		pdata->vsel_ctrl_id[i] = vsel_ctr_sel_id[i];
1070*4882a593Smuzhiyun 	}
1071*4882a593Smuzhiyun 
1072*4882a593Smuzhiyun 	for (j = 1; j < RK806_DVS_END; j++) {
1073*4882a593Smuzhiyun 		if (device_property_present(rk806->dev, dvs_ctrl_name[j])) {
1074*4882a593Smuzhiyun 			REG_DBG("%s:\n", dvs_ctrl_name[j]);
1075*4882a593Smuzhiyun 			for (i = 0;
1076*4882a593Smuzhiyun 			     (dn = of_parse_phandle(np, dvs_ctrl_name[j], i));
1077*4882a593Smuzhiyun 			     i++) {
1078*4882a593Smuzhiyun 				REG_DBG("\t%s\n", dn->name);
1079*4882a593Smuzhiyun 				pdata->support_dvs = 1;
1080*4882a593Smuzhiyun 				pdata->dvs_dn[j][i] = dn;
1081*4882a593Smuzhiyun 				pdata->dvs_count[j]++;
1082*4882a593Smuzhiyun 
1083*4882a593Smuzhiyun 				of_node_put(dn);
1084*4882a593Smuzhiyun 				if (i >= RK806_ID_END)
1085*4882a593Smuzhiyun 					break;
1086*4882a593Smuzhiyun 			}
1087*4882a593Smuzhiyun 		}
1088*4882a593Smuzhiyun 	}
1089*4882a593Smuzhiyun 	if (!pdata->support_dvs)
1090*4882a593Smuzhiyun 		return;
1091*4882a593Smuzhiyun 
1092*4882a593Smuzhiyun 	for (i = 0; i < 3; i++) {
1093*4882a593Smuzhiyun 		pdata->dvs_gpios[i] = devm_gpiod_get_optional(rk806->dev,
1094*4882a593Smuzhiyun 							      dvs_pin_name[i],
1095*4882a593Smuzhiyun 							      GPIOD_OUT_HIGH);
1096*4882a593Smuzhiyun 		if (IS_ERR(pdata->dvs_gpios[i])) {
1097*4882a593Smuzhiyun 			pdata->dvs_gpios[i] = NULL;
1098*4882a593Smuzhiyun 			dev_info(rk806->dev, "Failed to get %s\n", dvs_pin_name[i]);
1099*4882a593Smuzhiyun 		}
1100*4882a593Smuzhiyun 	}
1101*4882a593Smuzhiyun }
1102*4882a593Smuzhiyun 
rk806_regulator_probe(struct platform_device * pdev)1103*4882a593Smuzhiyun static int rk806_regulator_probe(struct platform_device *pdev)
1104*4882a593Smuzhiyun {
1105*4882a593Smuzhiyun 	struct rk806 *rk806 = dev_get_drvdata(pdev->dev.parent);
1106*4882a593Smuzhiyun 	struct rk806_regulator_data *pdata;
1107*4882a593Smuzhiyun 	struct regulator_config config = { };
1108*4882a593Smuzhiyun 	struct regulator_dev *rdev;
1109*4882a593Smuzhiyun 	int i;
1110*4882a593Smuzhiyun 
1111*4882a593Smuzhiyun 	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
1112*4882a593Smuzhiyun 	if (!pdata)
1113*4882a593Smuzhiyun 		return -ENOMEM;
1114*4882a593Smuzhiyun 
1115*4882a593Smuzhiyun 	rk806_regulator_dt_parse_pdata(rk806, rk806->regmap, pdata);
1116*4882a593Smuzhiyun 
1117*4882a593Smuzhiyun 	pdata->rk806 = rk806;
1118*4882a593Smuzhiyun 	platform_set_drvdata(pdev, pdata);
1119*4882a593Smuzhiyun 
1120*4882a593Smuzhiyun 	config.dev = &pdev->dev;
1121*4882a593Smuzhiyun 	config.driver_data = pdata;
1122*4882a593Smuzhiyun 	config.dev->of_node = rk806->dev->of_node;
1123*4882a593Smuzhiyun 	config.regmap = rk806->regmap;
1124*4882a593Smuzhiyun 
1125*4882a593Smuzhiyun 	for (i = 0; i < ARRAY_SIZE(rk806_regulators); i++) {
1126*4882a593Smuzhiyun 		rdev = devm_regulator_register(&pdev->dev,
1127*4882a593Smuzhiyun 					       &rk806_regulators[i],
1128*4882a593Smuzhiyun 					       &config);
1129*4882a593Smuzhiyun 		if (IS_ERR(rdev)) {
1130*4882a593Smuzhiyun 			dev_err(rk806->dev, "failed to register %s regulator\n",
1131*4882a593Smuzhiyun 				pdev->name);
1132*4882a593Smuzhiyun 			return PTR_ERR(rdev);
1133*4882a593Smuzhiyun 		}
1134*4882a593Smuzhiyun 
1135*4882a593Smuzhiyun 		rk806_regulator_sync_voltage(rdev);
1136*4882a593Smuzhiyun 	}
1137*4882a593Smuzhiyun 
1138*4882a593Smuzhiyun 	pdata->regulator_init = 1;
1139*4882a593Smuzhiyun 
1140*4882a593Smuzhiyun 	return 0;
1141*4882a593Smuzhiyun }
1142*4882a593Smuzhiyun 
rk806_suspend(struct device * dev)1143*4882a593Smuzhiyun static int __maybe_unused rk806_suspend(struct device *dev)
1144*4882a593Smuzhiyun {
1145*4882a593Smuzhiyun 	struct rk806 *rk806 = dev_get_drvdata(dev->parent);
1146*4882a593Smuzhiyun 	int i;
1147*4882a593Smuzhiyun 
1148*4882a593Smuzhiyun 	rk806_field_write(rk806, PWRCTRL1_FUN, PWRCTRL_NULL_FUN);
1149*4882a593Smuzhiyun 	rk806_field_write(rk806, PWRCTRL2_FUN, PWRCTRL_NULL_FUN);
1150*4882a593Smuzhiyun 	rk806_field_write(rk806, PWRCTRL3_FUN, PWRCTRL_NULL_FUN);
1151*4882a593Smuzhiyun 
1152*4882a593Smuzhiyun 	for (i = RK806_ID_DCDC1; i < RK806_ID_END; i++)
1153*4882a593Smuzhiyun 		rk806_field_write(rk806, BUCK1_VSEL_CTR_SEL + i, CTR_BY_NO_EFFECT);
1154*4882a593Smuzhiyun 
1155*4882a593Smuzhiyun 	rk806_field_write(rk806, PWRCTRL1_FUN, PWRCTRL_DVS_FUN);
1156*4882a593Smuzhiyun 
1157*4882a593Smuzhiyun 	for (i = RK806_ID_DCDC1; i < RK806_ID_END; i++)
1158*4882a593Smuzhiyun 		rk806_field_write(rk806, BUCK1_VSEL_CTR_SEL + i, CTR_BY_PWRCTRL1);
1159*4882a593Smuzhiyun 
1160*4882a593Smuzhiyun 	return 0;
1161*4882a593Smuzhiyun }
1162*4882a593Smuzhiyun 
rk806_resume(struct device * dev)1163*4882a593Smuzhiyun static int __maybe_unused rk806_resume(struct device *dev)
1164*4882a593Smuzhiyun {
1165*4882a593Smuzhiyun 	struct rk806 *rk806 = dev_get_drvdata(dev->parent);
1166*4882a593Smuzhiyun 	int i;
1167*4882a593Smuzhiyun 
1168*4882a593Smuzhiyun 	for (i = RK806_ID_DCDC1; i < RK806_ID_END; i++)
1169*4882a593Smuzhiyun 		rk806_field_write(rk806, BUCK1_VSEL_CTR_SEL + i, CTR_BY_NO_EFFECT);
1170*4882a593Smuzhiyun 
1171*4882a593Smuzhiyun 	rk806_field_write(rk806, PWRCTRL1_FUN, PWRCTRL_NULL_FUN);
1172*4882a593Smuzhiyun 
1173*4882a593Smuzhiyun 	return 0;
1174*4882a593Smuzhiyun }
1175*4882a593Smuzhiyun SIMPLE_DEV_PM_OPS(rk806_pm_ops, rk806_suspend, rk806_resume);
1176*4882a593Smuzhiyun 
rk806_regulator_shutdown(struct platform_device * pdev)1177*4882a593Smuzhiyun static void rk806_regulator_shutdown(struct platform_device *pdev)
1178*4882a593Smuzhiyun {
1179*4882a593Smuzhiyun 	struct rk806 *rk806 = dev_get_drvdata(pdev->dev.parent);
1180*4882a593Smuzhiyun 
1181*4882a593Smuzhiyun 	if (system_state == SYSTEM_POWER_OFF)
1182*4882a593Smuzhiyun 		if ((rk806->pins->p) && (rk806->pins->power_off))
1183*4882a593Smuzhiyun 			pinctrl_select_state(rk806->pins->p, rk806->pins->power_off);
1184*4882a593Smuzhiyun 
1185*4882a593Smuzhiyun 	if (system_state == SYSTEM_RESTART)
1186*4882a593Smuzhiyun 		if ((rk806->pins->p) && (rk806->pins->reset))
1187*4882a593Smuzhiyun 			pinctrl_select_state(rk806->pins->p, rk806->pins->reset);
1188*4882a593Smuzhiyun 
1189*4882a593Smuzhiyun }
1190*4882a593Smuzhiyun 
1191*4882a593Smuzhiyun static const struct platform_device_id rk806_regulator_id_table[] = {
1192*4882a593Smuzhiyun 	{ "rk806-regulator", },
1193*4882a593Smuzhiyun 	{ /* sentinel */ }
1194*4882a593Smuzhiyun };
1195*4882a593Smuzhiyun MODULE_DEVICE_TABLE(platform, rk806_regulator_id_table);
1196*4882a593Smuzhiyun 
1197*4882a593Smuzhiyun static struct platform_driver rk806_regulator_driver = {
1198*4882a593Smuzhiyun 	.driver = {
1199*4882a593Smuzhiyun 		.name = "rk806-regulator",
1200*4882a593Smuzhiyun 		.pm = &rk806_pm_ops,
1201*4882a593Smuzhiyun 	},
1202*4882a593Smuzhiyun 	.probe = rk806_regulator_probe,
1203*4882a593Smuzhiyun 	.id_table = rk806_regulator_id_table,
1204*4882a593Smuzhiyun 	.shutdown = rk806_regulator_shutdown,
1205*4882a593Smuzhiyun };
1206*4882a593Smuzhiyun module_platform_driver(rk806_regulator_driver);
1207*4882a593Smuzhiyun 
1208*4882a593Smuzhiyun MODULE_AUTHOR("Xu Shengfei <xsf@rock-chips.com>");
1209*4882a593Smuzhiyun MODULE_DESCRIPTION("rk806 voltage regulator driver");
1210*4882a593Smuzhiyun MODULE_LICENSE("GPL v2");
1211