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