xref: /OK3568_Linux_fs/u-boot/drivers/power/pmic/rk8xx_spi.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  **Copyright (C) 2021 Rockchip Electronics Co., Ltd
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * SPDX-License-Identifier:	GPL-2.0+
5*4882a593Smuzhiyun  */
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun #include <common.h>
8*4882a593Smuzhiyun #include <dm.h>
9*4882a593Smuzhiyun #include <errno.h>
10*4882a593Smuzhiyun #include <irq-generic.h>
11*4882a593Smuzhiyun #include <power/rk8xx_pmic.h>
12*4882a593Smuzhiyun #include <power/pmic.h>
13*4882a593Smuzhiyun #include <spi.h>
14*4882a593Smuzhiyun 
15*4882a593Smuzhiyun DECLARE_GLOBAL_DATA_PTR;
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun #define RK806_CHIP_NAME			0x5A
18*4882a593Smuzhiyun #define RK806_CHIP_VER			0x5B
19*4882a593Smuzhiyun #define RK806_HW_VER			0x21
20*4882a593Smuzhiyun #define HW_DUAL_PMIC			0x28
21*4882a593Smuzhiyun #define HW_SINGLE_PMIC			0xe8
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun #define RK806_CMD_READ			0
24*4882a593Smuzhiyun #define RK806_CMD_WRITE			BIT(7)
25*4882a593Smuzhiyun #define RK806_CMD_CRC_EN		BIT(6)
26*4882a593Smuzhiyun #define RK806_CMD_CRC_DIS		0
27*4882a593Smuzhiyun #define RK806_CMD_LEN_MSK		0x0f
28*4882a593Smuzhiyun #define RK806_REG_H			0x00
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun #define RK806_SYS_CFG1			0x5f
31*4882a593Smuzhiyun #define RK806_PWRCTRL_CONFIG0		0x62
32*4882a593Smuzhiyun #define RK806_PWRCTRL_CONFIG1		0x63
33*4882a593Smuzhiyun #define RK806_VSEL_CTR_SEL0		0x64
34*4882a593Smuzhiyun #define RK806_DVS_CTR_SEL4		0x6e
35*4882a593Smuzhiyun #define RK806_SYS_CFG3			0x72
36*4882a593Smuzhiyun #define RK806_PWRON_KEY			0x76
37*4882a593Smuzhiyun #define RK806_INT_STS0			0x77
38*4882a593Smuzhiyun #define RK806_INT_MSK0			0x78
39*4882a593Smuzhiyun #define RK806_INT_STS1			0x79
40*4882a593Smuzhiyun #define RK806_INT_MSK1			0x7A
41*4882a593Smuzhiyun #define RK806_GPIO_INT_CONFIG		0x7B
42*4882a593Smuzhiyun #define RK806_ON_SOURCE			0xf4
43*4882a593Smuzhiyun #define RK806_OFF_SOURCE		0xf5
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun #define RK806_IRQ_PWRON_FALL_MSK	BIT(0)
46*4882a593Smuzhiyun #define RK806_IRQ_PWRON_RISE_MSK	BIT(1)
47*4882a593Smuzhiyun #define RK806_DEV_OFF			BIT(0)
48*4882a593Smuzhiyun #define RK806_RST_MODE1			0x01
49*4882a593Smuzhiyun #define RK806_RST_MODE2			0x02
50*4882a593Smuzhiyun #define RK806_PWRCTRL_FUN_MSK		0x88
51*4882a593Smuzhiyun #define RK806_VSEL_CTRL_MSK		0xcc
52*4882a593Smuzhiyun #define RK806_VSEL_PWRCTRL1		0x11
53*4882a593Smuzhiyun #define RK806_ENABLE_PWRCTRL		0x04
54*4882a593Smuzhiyun #define VERSION_AB			0x01
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun #if CONFIG_IS_ENABLED(IRQ)
57*4882a593Smuzhiyun /* RK805 */
58*4882a593Smuzhiyun static const struct virq_reg rk806_irqs[] = {
59*4882a593Smuzhiyun 	[RK8XX_IRQ_PWRON_FALL] = {
60*4882a593Smuzhiyun 		.mask = RK806_IRQ_PWRON_FALL_MSK,
61*4882a593Smuzhiyun 		.reg_offset = 0,
62*4882a593Smuzhiyun 	},
63*4882a593Smuzhiyun 	[RK8XX_IRQ_PWRON_RISE] = {
64*4882a593Smuzhiyun 		.mask = RK806_IRQ_PWRON_RISE_MSK,
65*4882a593Smuzhiyun 		.reg_offset = 0,
66*4882a593Smuzhiyun 	},
67*4882a593Smuzhiyun };
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun static struct virq_chip rk806_irq_chip = {
70*4882a593Smuzhiyun 	.status_base		= RK806_INT_STS0,
71*4882a593Smuzhiyun 	.mask_base		= RK806_INT_MSK0,
72*4882a593Smuzhiyun 	.num_regs		= 1,
73*4882a593Smuzhiyun 	.read			= pmic_reg_read,
74*4882a593Smuzhiyun 	.write			= pmic_reg_write,
75*4882a593Smuzhiyun 	.irqs			= rk806_irqs,
76*4882a593Smuzhiyun 	.num_irqs		= ARRAY_SIZE(rk806_irqs),
77*4882a593Smuzhiyun };
78*4882a593Smuzhiyun #endif
79*4882a593Smuzhiyun 
80*4882a593Smuzhiyun static const struct pmic_child_info pmic_children_info[] = {
81*4882a593Smuzhiyun 	{ .prefix = "DCDC", .driver = "rk8xx_spi_buck"},
82*4882a593Smuzhiyun 	{ .prefix = "NLDO", .driver = "rk8xx_spi_ldo"},
83*4882a593Smuzhiyun 	{ .prefix = "PLDO", .driver = "rk8xx_spi_pldo"},
84*4882a593Smuzhiyun 	{ },
85*4882a593Smuzhiyun };
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun static const struct pmic_child_info power_key_info[] = {
88*4882a593Smuzhiyun 	{ .prefix = "pwrkey", .driver = "rk8xx_pwrkey"},
89*4882a593Smuzhiyun 	{ },
90*4882a593Smuzhiyun };
91*4882a593Smuzhiyun 
_spi_read(struct udevice * dev,u32 reg,u8 * buffer,int len)92*4882a593Smuzhiyun static int _spi_read(struct udevice *dev, u32 reg, u8 *buffer, int len)
93*4882a593Smuzhiyun {
94*4882a593Smuzhiyun 	struct rk8xx_priv *priv = dev_get_priv(dev);
95*4882a593Smuzhiyun 	u8 txbuf[3];
96*4882a593Smuzhiyun 	int ret;
97*4882a593Smuzhiyun 
98*4882a593Smuzhiyun 	if (spi_claim_bus(priv->slave))
99*4882a593Smuzhiyun 		return -EBUSY;
100*4882a593Smuzhiyun 
101*4882a593Smuzhiyun 	txbuf[0] = RK806_CMD_READ;
102*4882a593Smuzhiyun 	txbuf[1] = reg;
103*4882a593Smuzhiyun 	txbuf[2] = RK806_REG_H;
104*4882a593Smuzhiyun 
105*4882a593Smuzhiyun 	ret = spi_write_then_read(priv->slave, txbuf, 3, NULL, buffer, 1);
106*4882a593Smuzhiyun 	spi_release_bus(priv->slave);
107*4882a593Smuzhiyun 
108*4882a593Smuzhiyun 	return ret;
109*4882a593Smuzhiyun }
110*4882a593Smuzhiyun 
_spi_write(struct udevice * dev,uint reg,const u8 * buffer,int len)111*4882a593Smuzhiyun static int _spi_write(struct udevice *dev, uint reg, const u8 *buffer, int len)
112*4882a593Smuzhiyun {
113*4882a593Smuzhiyun 	struct rk8xx_priv *priv = dev_get_priv(dev);
114*4882a593Smuzhiyun 	u8 txbuf[4];
115*4882a593Smuzhiyun 	int ret;
116*4882a593Smuzhiyun 
117*4882a593Smuzhiyun 	if (len < 1) {
118*4882a593Smuzhiyun 		dev_err(dev, "rk806 write error: len < 1\n");
119*4882a593Smuzhiyun 		return -EINVAL;
120*4882a593Smuzhiyun 	}
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun 	if (spi_claim_bus(priv->slave))
123*4882a593Smuzhiyun 		return -EBUSY;
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun 	txbuf[0] = RK806_CMD_WRITE;
126*4882a593Smuzhiyun 	txbuf[1] = reg;
127*4882a593Smuzhiyun 	txbuf[2] = RK806_REG_H;
128*4882a593Smuzhiyun 	txbuf[3] = *buffer;
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun 	ret = spi_write_then_read(priv->slave, txbuf, 4, NULL, NULL, 0);
131*4882a593Smuzhiyun 	spi_release_bus(priv->slave);
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun 	return ret;
134*4882a593Smuzhiyun }
135*4882a593Smuzhiyun 
rk806_spi_read(struct udevice * dev,uint reg,u8 * buffer,int len)136*4882a593Smuzhiyun static int rk806_spi_read(struct udevice *dev,
137*4882a593Smuzhiyun 			  uint reg,
138*4882a593Smuzhiyun 			  u8 *buffer,
139*4882a593Smuzhiyun 			  int len)
140*4882a593Smuzhiyun {
141*4882a593Smuzhiyun 	int ret;
142*4882a593Smuzhiyun 
143*4882a593Smuzhiyun 	ret = _spi_read(dev, reg, buffer, len);
144*4882a593Smuzhiyun 	if (ret)
145*4882a593Smuzhiyun 		dev_err(dev, "rk806 read reg(0x%x) error: %d\n", reg, ret);
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun 	return ret;
148*4882a593Smuzhiyun }
149*4882a593Smuzhiyun 
rk806_spi_write(struct udevice * dev,uint reg,const u8 * buffer,int len)150*4882a593Smuzhiyun static int rk806_spi_write(struct udevice *dev,
151*4882a593Smuzhiyun 			   uint reg,
152*4882a593Smuzhiyun 			   const u8 *buffer,
153*4882a593Smuzhiyun 			   int len)
154*4882a593Smuzhiyun {
155*4882a593Smuzhiyun 	int ret;
156*4882a593Smuzhiyun 
157*4882a593Smuzhiyun 	ret = _spi_write(dev, reg, buffer, len);
158*4882a593Smuzhiyun 	if (ret)
159*4882a593Smuzhiyun 		dev_err(dev, "rk806 write reg(0x%x) error: %d\n", reg, ret);
160*4882a593Smuzhiyun 
161*4882a593Smuzhiyun 	return ret;
162*4882a593Smuzhiyun }
163*4882a593Smuzhiyun 
rk8xx_spi_reg_count(struct udevice * dev)164*4882a593Smuzhiyun static int rk8xx_spi_reg_count(struct udevice *dev)
165*4882a593Smuzhiyun {
166*4882a593Smuzhiyun 	return 0xff;
167*4882a593Smuzhiyun }
168*4882a593Smuzhiyun 
169*4882a593Smuzhiyun #if CONFIG_IS_ENABLED(PMIC_CHILDREN)
rk8xx_spi_bind(struct udevice * dev)170*4882a593Smuzhiyun static int rk8xx_spi_bind(struct udevice *dev)
171*4882a593Smuzhiyun {
172*4882a593Smuzhiyun 	ofnode regulators_node;
173*4882a593Smuzhiyun 	int children;
174*4882a593Smuzhiyun 
175*4882a593Smuzhiyun 	regulators_node = dev_read_subnode(dev, "regulators");
176*4882a593Smuzhiyun 	if (!ofnode_valid(regulators_node)) {
177*4882a593Smuzhiyun 		debug("%s: %s regulators subnode not found!\n", __func__,
178*4882a593Smuzhiyun 		      dev->name);
179*4882a593Smuzhiyun 		return -ENXIO;
180*4882a593Smuzhiyun 	}
181*4882a593Smuzhiyun 
182*4882a593Smuzhiyun 	children = pmic_bind_children(dev, regulators_node, pmic_children_info);
183*4882a593Smuzhiyun 	if (!children)
184*4882a593Smuzhiyun 		debug("%s: %s - no child found\n", __func__, dev->name);
185*4882a593Smuzhiyun 
186*4882a593Smuzhiyun 	children = pmic_bind_children(dev, dev->node, power_key_info);
187*4882a593Smuzhiyun 	if (!children)
188*4882a593Smuzhiyun 		debug("%s: %s - no child found\n", __func__, dev->name);
189*4882a593Smuzhiyun 
190*4882a593Smuzhiyun 	return 0;
191*4882a593Smuzhiyun }
192*4882a593Smuzhiyun #endif
193*4882a593Smuzhiyun #if CONFIG_IS_ENABLED(IRQ)
rk8xx_spi_ofdata_to_platdata(struct udevice * dev)194*4882a593Smuzhiyun static int rk8xx_spi_ofdata_to_platdata(struct udevice *dev)
195*4882a593Smuzhiyun {
196*4882a593Smuzhiyun 	struct rk8xx_priv *rk8xx = dev_get_priv(dev);
197*4882a593Smuzhiyun 	u32 interrupt, phandle;
198*4882a593Smuzhiyun 	int ret;
199*4882a593Smuzhiyun 
200*4882a593Smuzhiyun 	rk8xx->rst_fun = dev_read_u32_default(dev, "pmic-reset-func", 0);
201*4882a593Smuzhiyun 
202*4882a593Smuzhiyun 	phandle = dev_read_u32_default(dev, "interrupt-parent", -ENODATA);
203*4882a593Smuzhiyun 	if (phandle == -ENODATA) {
204*4882a593Smuzhiyun 		printf("Read 'interrupt-parent' failed, ret=%d\n", phandle);
205*4882a593Smuzhiyun 		return phandle;
206*4882a593Smuzhiyun 	}
207*4882a593Smuzhiyun 
208*4882a593Smuzhiyun 	ret = dev_read_u32_array(dev, "interrupts", &interrupt, 1);
209*4882a593Smuzhiyun 	if (ret) {
210*4882a593Smuzhiyun 		printf("Read 'interrupts' failed, ret=%d\n", ret);
211*4882a593Smuzhiyun 		return ret;
212*4882a593Smuzhiyun 	}
213*4882a593Smuzhiyun 
214*4882a593Smuzhiyun 	rk8xx->irq = phandle_gpio_to_irq(phandle, interrupt);
215*4882a593Smuzhiyun 	if (rk8xx->irq < 0)
216*4882a593Smuzhiyun 		printf("Failed to request rk8xx irq, ret=%d\n", rk8xx->irq);
217*4882a593Smuzhiyun 
218*4882a593Smuzhiyun 	return 0;
219*4882a593Smuzhiyun }
220*4882a593Smuzhiyun 
rk8xx_spi_irq_chip_init(struct udevice * dev)221*4882a593Smuzhiyun static int rk8xx_spi_irq_chip_init(struct udevice *dev)
222*4882a593Smuzhiyun {
223*4882a593Smuzhiyun 	struct rk8xx_priv *priv = dev_get_priv(dev);
224*4882a593Smuzhiyun 	struct virq_chip *irq_chip = NULL;
225*4882a593Smuzhiyun 	u8 value;
226*4882a593Smuzhiyun 	int ret;
227*4882a593Smuzhiyun 
228*4882a593Smuzhiyun 	value = 0xff;
229*4882a593Smuzhiyun 	rk806_spi_write(dev, RK806_INT_STS0, &value, 1);
230*4882a593Smuzhiyun 	rk806_spi_write(dev, RK806_INT_STS1, &value, 1);
231*4882a593Smuzhiyun 	rk806_spi_write(dev, RK806_INT_MSK0, &value, 1);
232*4882a593Smuzhiyun 	rk806_spi_write(dev, RK806_INT_MSK1, &value, 1);
233*4882a593Smuzhiyun 	value = 0x00;
234*4882a593Smuzhiyun 	rk806_spi_write(dev, RK806_GPIO_INT_CONFIG, &value, 1);
235*4882a593Smuzhiyun 
236*4882a593Smuzhiyun 	irq_chip = &rk806_irq_chip;
237*4882a593Smuzhiyun 
238*4882a593Smuzhiyun 	if (irq_chip && priv->irq > 0) {
239*4882a593Smuzhiyun 		ret = virq_add_chip(dev, irq_chip, priv->irq);
240*4882a593Smuzhiyun 		if (ret) {
241*4882a593Smuzhiyun 			printf("Failed to add irqchip(irq=%d), ret=%d\n",
242*4882a593Smuzhiyun 			       priv->irq, ret);
243*4882a593Smuzhiyun 			return ret;
244*4882a593Smuzhiyun 		}
245*4882a593Smuzhiyun 		priv->irq_chip = irq_chip;
246*4882a593Smuzhiyun 	}
247*4882a593Smuzhiyun 
248*4882a593Smuzhiyun 	return 0;
249*4882a593Smuzhiyun }
250*4882a593Smuzhiyun #else
rk8xx_spi_ofdata_to_platdata(struct udevice * dev)251*4882a593Smuzhiyun static inline int rk8xx_spi_ofdata_to_platdata(struct udevice *dev)
252*4882a593Smuzhiyun {
253*4882a593Smuzhiyun 	return 0;
254*4882a593Smuzhiyun }
255*4882a593Smuzhiyun 
rk8xx_spi_irq_chip_init(struct udevice * dev)256*4882a593Smuzhiyun static inline int rk8xx_spi_irq_chip_init(struct udevice *dev)
257*4882a593Smuzhiyun {
258*4882a593Smuzhiyun 	return 0;
259*4882a593Smuzhiyun }
260*4882a593Smuzhiyun #endif
261*4882a593Smuzhiyun 
rk8xx_spi_probe(struct udevice * dev)262*4882a593Smuzhiyun static int rk8xx_spi_probe(struct udevice *dev)
263*4882a593Smuzhiyun {
264*4882a593Smuzhiyun 	struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev);
265*4882a593Smuzhiyun 	struct rk8xx_priv *priv = dev_get_priv(dev);
266*4882a593Smuzhiyun 	struct udevice *spi = dev_get_parent(dev);
267*4882a593Smuzhiyun 	struct spi_slave *slave = NULL;
268*4882a593Smuzhiyun 	u8 on_source, off_source;
269*4882a593Smuzhiyun 	u8 msb, lsb, value = 0;
270*4882a593Smuzhiyun 	int ret;
271*4882a593Smuzhiyun 
272*4882a593Smuzhiyun 	if (spi->seq < 0) {
273*4882a593Smuzhiyun 		dev_err(dev, "Failed to configure the spi num\n");
274*4882a593Smuzhiyun 		return -EINVAL;
275*4882a593Smuzhiyun 	}
276*4882a593Smuzhiyun 
277*4882a593Smuzhiyun 	slave = spi_setup_slave(spi->seq, plat->cs, plat->max_hz,
278*4882a593Smuzhiyun 				plat->mode);
279*4882a593Smuzhiyun 	if (!slave)
280*4882a593Smuzhiyun 		return -ENODEV;
281*4882a593Smuzhiyun 	priv->slave = slave;
282*4882a593Smuzhiyun 
283*4882a593Smuzhiyun 	/* read Chip variant */
284*4882a593Smuzhiyun 	ret = rk806_spi_read(dev, RK806_CHIP_NAME, &msb, 1);
285*4882a593Smuzhiyun 	if (ret) {
286*4882a593Smuzhiyun 		dev_err(dev, "rk806 name read error: %d\n", ret);
287*4882a593Smuzhiyun 		return ret;
288*4882a593Smuzhiyun 	}
289*4882a593Smuzhiyun 
290*4882a593Smuzhiyun 	ret = rk806_spi_read(dev, RK806_CHIP_VER, &lsb, 1);
291*4882a593Smuzhiyun 	if (ret) {
292*4882a593Smuzhiyun 		dev_err(dev, "rk806 version read error: %d\n", ret);
293*4882a593Smuzhiyun 		return ret;
294*4882a593Smuzhiyun 	}
295*4882a593Smuzhiyun 
296*4882a593Smuzhiyun 	priv->variant = ((msb << 8) | lsb) & RK8XX_ID_MSK;
297*4882a593Smuzhiyun 	printf("spi%d: RK%x%x: %d\n", spi->seq, msb, (lsb >> 4), lsb & 0x0f);
298*4882a593Smuzhiyun 
299*4882a593Smuzhiyun 	rk806_spi_read(dev, RK806_ON_SOURCE, &on_source, 1);
300*4882a593Smuzhiyun 	rk806_spi_read(dev, RK806_OFF_SOURCE, &off_source, 1);
301*4882a593Smuzhiyun 	printf("ON=0x%02x, OFF=0x%02x\n", on_source, off_source);
302*4882a593Smuzhiyun 
303*4882a593Smuzhiyun 	ret = rk806_spi_read(dev, RK806_HW_VER, &value, 1);
304*4882a593Smuzhiyun 	if (ret)
305*4882a593Smuzhiyun 		panic("RK806: read RK806_HW_VER error!\n");
306*4882a593Smuzhiyun 	/* dual rk806 dev name: "rk806master@0", "rk806slave@1"
307*4882a593Smuzhiyun 	 * single rk806 dev name: " rk806single@0"
308*4882a593Smuzhiyun 	 */
309*4882a593Smuzhiyun 	if ((!strcmp(dev->name, "rk806master@0")) || (!strcmp(dev->name, "rk806slave@1"))) {
310*4882a593Smuzhiyun 		if (value != HW_DUAL_PMIC) {
311*4882a593Smuzhiyun 			dev_err(dev, "HW single pmic, the firmware dual pmic(0x%x)!\n", value);
312*4882a593Smuzhiyun 			run_command("download", 0);
313*4882a593Smuzhiyun 		}
314*4882a593Smuzhiyun 	} else {
315*4882a593Smuzhiyun 		if (value != HW_SINGLE_PMIC) {
316*4882a593Smuzhiyun 			dev_err(dev, "HW dual pmic, the firmware single pmic(0x%x)!\n", value);
317*4882a593Smuzhiyun 			run_command("download", 0);
318*4882a593Smuzhiyun 		}
319*4882a593Smuzhiyun 	}
320*4882a593Smuzhiyun 
321*4882a593Smuzhiyun 	if ((lsb & 0x0f) == VERSION_AB) {
322*4882a593Smuzhiyun 		ret = rk806_spi_read(dev, RK806_SYS_CFG1, &value, 1);
323*4882a593Smuzhiyun 		if (ret) {
324*4882a593Smuzhiyun 			dev_err(dev, "rk806 RK806_SYS_CFG1 read error: %d\n", ret);
325*4882a593Smuzhiyun 			return ret;
326*4882a593Smuzhiyun 		}
327*4882a593Smuzhiyun 		value |= 0x80;
328*4882a593Smuzhiyun 		rk806_spi_write(dev, RK806_SYS_CFG1, &value, 1);
329*4882a593Smuzhiyun 	}
330*4882a593Smuzhiyun 
331*4882a593Smuzhiyun 	if (priv->rst_fun) {
332*4882a593Smuzhiyun 		rk806_spi_read(dev, RK806_SYS_CFG3, &value, 1);
333*4882a593Smuzhiyun 		value &= 0x3f;
334*4882a593Smuzhiyun 		if (priv->rst_fun == RK806_RST_MODE1) {
335*4882a593Smuzhiyun 			value |= (RK806_RST_MODE1 << 6);
336*4882a593Smuzhiyun 			rk806_spi_write(dev, RK806_SYS_CFG3, &value, 1);
337*4882a593Smuzhiyun 		} else if (priv->rst_fun == RK806_RST_MODE2) {
338*4882a593Smuzhiyun 			value |= (RK806_RST_MODE2 << 6);
339*4882a593Smuzhiyun 			rk806_spi_write(dev, RK806_SYS_CFG3, &value, 1);
340*4882a593Smuzhiyun 		}
341*4882a593Smuzhiyun 	}
342*4882a593Smuzhiyun 
343*4882a593Smuzhiyun 	rk8xx_spi_irq_chip_init(dev);
344*4882a593Smuzhiyun 
345*4882a593Smuzhiyun 	return 0;
346*4882a593Smuzhiyun }
347*4882a593Smuzhiyun 
rk8xx_spi_shutdown(struct udevice * dev)348*4882a593Smuzhiyun static int rk8xx_spi_shutdown(struct udevice *dev)
349*4882a593Smuzhiyun {
350*4882a593Smuzhiyun 	u8 dev_off;
351*4882a593Smuzhiyun 	int ret = 0;
352*4882a593Smuzhiyun 
353*4882a593Smuzhiyun 	ret = rk806_spi_read(dev, RK806_SYS_CFG3, &dev_off, 1);
354*4882a593Smuzhiyun 	if (ret)
355*4882a593Smuzhiyun 		return ret;
356*4882a593Smuzhiyun 
357*4882a593Smuzhiyun 	dev_off |= RK806_DEV_OFF;
358*4882a593Smuzhiyun 	ret = rk806_spi_write(dev, RK806_SYS_CFG3, &dev_off, 1);
359*4882a593Smuzhiyun 	if (ret) {
360*4882a593Smuzhiyun 		dev_err(dev, "rk806 shutdown error: %d\n", ret);
361*4882a593Smuzhiyun 		return ret;
362*4882a593Smuzhiyun 	}
363*4882a593Smuzhiyun 
364*4882a593Smuzhiyun 	while (1)
365*4882a593Smuzhiyun 		;
366*4882a593Smuzhiyun 
367*4882a593Smuzhiyun 	return 0;
368*4882a593Smuzhiyun }
369*4882a593Smuzhiyun 
rk806_suspend(struct udevice * dev)370*4882a593Smuzhiyun static int rk806_suspend(struct udevice *dev)
371*4882a593Smuzhiyun {
372*4882a593Smuzhiyun 	int ret = 0;
373*4882a593Smuzhiyun 	u8 i, val;
374*4882a593Smuzhiyun 
375*4882a593Smuzhiyun 	ret = rk806_spi_read(dev, RK806_PWRCTRL_CONFIG0, &val, 1);
376*4882a593Smuzhiyun 	if (ret)
377*4882a593Smuzhiyun 		return ret;
378*4882a593Smuzhiyun 	val &= RK806_PWRCTRL_FUN_MSK;
379*4882a593Smuzhiyun 	ret = rk806_spi_write(dev, RK806_PWRCTRL_CONFIG0, &val, 1);
380*4882a593Smuzhiyun 	if (ret)
381*4882a593Smuzhiyun 		return ret;
382*4882a593Smuzhiyun 
383*4882a593Smuzhiyun 	ret = rk806_spi_read(dev, RK806_PWRCTRL_CONFIG1, &val, 1);
384*4882a593Smuzhiyun 	if (ret)
385*4882a593Smuzhiyun 		return ret;
386*4882a593Smuzhiyun 	val &= RK806_PWRCTRL_FUN_MSK;
387*4882a593Smuzhiyun 	ret = rk806_spi_write(dev, RK806_PWRCTRL_CONFIG1, &val, 1);
388*4882a593Smuzhiyun 	if (ret)
389*4882a593Smuzhiyun 		return ret;
390*4882a593Smuzhiyun 
391*4882a593Smuzhiyun 	for (i = RK806_VSEL_CTR_SEL0; i <= 0x6e; i++) {
392*4882a593Smuzhiyun 		ret = rk806_spi_read(dev, i, &val, 1);
393*4882a593Smuzhiyun 		if (ret)
394*4882a593Smuzhiyun 			return ret;
395*4882a593Smuzhiyun 		val &= RK806_VSEL_CTRL_MSK;
396*4882a593Smuzhiyun 		ret = rk806_spi_write(dev, i, &val, 1);
397*4882a593Smuzhiyun 		if (ret)
398*4882a593Smuzhiyun 			return ret;
399*4882a593Smuzhiyun 	}
400*4882a593Smuzhiyun 
401*4882a593Smuzhiyun 	ret = rk806_spi_read(dev, RK806_PWRCTRL_CONFIG0, &val, 1);
402*4882a593Smuzhiyun 	if (ret)
403*4882a593Smuzhiyun 		return ret;
404*4882a593Smuzhiyun 	val &= RK806_PWRCTRL_FUN_MSK;
405*4882a593Smuzhiyun 	val |= RK806_ENABLE_PWRCTRL;
406*4882a593Smuzhiyun 	ret = rk806_spi_write(dev, RK806_PWRCTRL_CONFIG0, &val, 1);
407*4882a593Smuzhiyun 	if (ret)
408*4882a593Smuzhiyun 		return ret;
409*4882a593Smuzhiyun 
410*4882a593Smuzhiyun 	for (i = RK806_VSEL_CTR_SEL0; i <= RK806_DVS_CTR_SEL4; i++) {
411*4882a593Smuzhiyun 		ret = rk806_spi_read(dev, i, &val, 1);
412*4882a593Smuzhiyun 		if (ret)
413*4882a593Smuzhiyun 			return ret;
414*4882a593Smuzhiyun 		val &= RK806_VSEL_CTRL_MSK;
415*4882a593Smuzhiyun 		val |= RK806_VSEL_PWRCTRL1;
416*4882a593Smuzhiyun 		ret = rk806_spi_write(dev, i, &val, 1);
417*4882a593Smuzhiyun 		if (ret)
418*4882a593Smuzhiyun 			return ret;
419*4882a593Smuzhiyun 	}
420*4882a593Smuzhiyun 
421*4882a593Smuzhiyun 	return ret;
422*4882a593Smuzhiyun }
423*4882a593Smuzhiyun 
rk806_resume(struct udevice * dev)424*4882a593Smuzhiyun static int rk806_resume(struct udevice *dev)
425*4882a593Smuzhiyun {
426*4882a593Smuzhiyun 	int ret = 0;
427*4882a593Smuzhiyun 	u8 i, val;
428*4882a593Smuzhiyun 
429*4882a593Smuzhiyun 	for (i = RK806_VSEL_CTR_SEL0; i <= RK806_DVS_CTR_SEL4; i++) {
430*4882a593Smuzhiyun 		ret = rk806_spi_read(dev, i, &val, 1);
431*4882a593Smuzhiyun 		if (ret)
432*4882a593Smuzhiyun 			return ret;
433*4882a593Smuzhiyun 		val &= RK806_VSEL_CTRL_MSK;
434*4882a593Smuzhiyun 		ret = rk806_spi_write(dev, i, &val, 1);
435*4882a593Smuzhiyun 		if (ret)
436*4882a593Smuzhiyun 			return ret;
437*4882a593Smuzhiyun 	}
438*4882a593Smuzhiyun 
439*4882a593Smuzhiyun 	ret = rk806_spi_read(dev, RK806_PWRCTRL_CONFIG0, &val, 1);
440*4882a593Smuzhiyun 	if (ret)
441*4882a593Smuzhiyun 		return ret;
442*4882a593Smuzhiyun 	val &= RK806_PWRCTRL_FUN_MSK;
443*4882a593Smuzhiyun 	ret = rk806_spi_write(dev, RK806_PWRCTRL_CONFIG0, &val, 1);
444*4882a593Smuzhiyun 	if (ret)
445*4882a593Smuzhiyun 		return ret;
446*4882a593Smuzhiyun 
447*4882a593Smuzhiyun 	ret = rk806_spi_read(dev, RK806_PWRCTRL_CONFIG1, &val, 1);
448*4882a593Smuzhiyun 	if (ret)
449*4882a593Smuzhiyun 		return ret;
450*4882a593Smuzhiyun 	val &= RK806_PWRCTRL_FUN_MSK;
451*4882a593Smuzhiyun 	ret = rk806_spi_write(dev, RK806_PWRCTRL_CONFIG1, &val, 1);
452*4882a593Smuzhiyun 	if (ret)
453*4882a593Smuzhiyun 		return ret;
454*4882a593Smuzhiyun 
455*4882a593Smuzhiyun 	return ret;
456*4882a593Smuzhiyun }
457*4882a593Smuzhiyun 
458*4882a593Smuzhiyun static struct dm_pmic_ops rk8xx_spi_ops = {
459*4882a593Smuzhiyun 	.reg_count = rk8xx_spi_reg_count,
460*4882a593Smuzhiyun 	.read = rk806_spi_read,
461*4882a593Smuzhiyun 	.write = rk806_spi_write,
462*4882a593Smuzhiyun 	.shutdown = rk8xx_spi_shutdown,
463*4882a593Smuzhiyun 	.suspend = rk806_suspend,
464*4882a593Smuzhiyun 	.resume = rk806_resume,
465*4882a593Smuzhiyun };
466*4882a593Smuzhiyun 
467*4882a593Smuzhiyun static const struct udevice_id rk8xx_spi_ids[] = {
468*4882a593Smuzhiyun 	{ .compatible = "rockchip,rk806" },
469*4882a593Smuzhiyun 	{ }
470*4882a593Smuzhiyun };
471*4882a593Smuzhiyun 
472*4882a593Smuzhiyun U_BOOT_DRIVER(pmic_rk8xx_spi) = {
473*4882a593Smuzhiyun 	.name = "rk806-pmic",
474*4882a593Smuzhiyun 	.id = UCLASS_PMIC,
475*4882a593Smuzhiyun 	.of_match = rk8xx_spi_ids,
476*4882a593Smuzhiyun #if CONFIG_IS_ENABLED(PMIC_CHILDREN)
477*4882a593Smuzhiyun 	.bind = rk8xx_spi_bind,
478*4882a593Smuzhiyun #endif
479*4882a593Smuzhiyun 	.ofdata_to_platdata = rk8xx_spi_ofdata_to_platdata,
480*4882a593Smuzhiyun 	.priv_auto_alloc_size = sizeof(struct rk8xx_priv),
481*4882a593Smuzhiyun 	.probe = rk8xx_spi_probe,
482*4882a593Smuzhiyun 	.ops = &rk8xx_spi_ops,
483*4882a593Smuzhiyun };
484