1 /*
2  *  Copyright (C) 2015 Linaro
3  *  Peter Griffin <peter.griffin@linaro.org>
4  *
5  * SPDX-License-Identifier:	GPL-2.0+
6  */
7 #include <asm/io.h>
8 #include <common.h>
9 #include <power/pmic.h>
10 #include <power/max8997_muic.h>
11 #include <power/hi6553_pmic.h>
12 #include <errno.h>
13 
14 u8 *pmussi_base;
15 
16 uint8_t hi6553_readb(u32 offset)
17 {
18 	return readb(pmussi_base + (offset << 2));
19 }
20 
21 void hi6553_writeb(u32 offset, uint8_t value)
22 {
23 	writeb(value, pmussi_base + (offset << 2));
24 }
25 
26 int pmic_reg_write(struct pmic *p, u32 reg, u32 val)
27 {
28 	if (check_reg(p, reg))
29 		return -EINVAL;
30 
31 	hi6553_writeb(reg, (uint8_t)val);
32 
33 	return 0;
34 }
35 
36 int pmic_reg_read(struct pmic *p, u32 reg, u32 *val)
37 {
38 	if (check_reg(p, reg))
39 		return -EINVAL;
40 
41 	*val = (u32)hi6553_readb(reg);
42 
43 	return 0;
44 }
45 
46 static void hi6553_init(void)
47 {
48 	int data;
49 
50 	hi6553_writeb(HI6553_PERI_EN_MARK, 0x1e);
51 	hi6553_writeb(HI6553_NP_REG_ADJ1, 0);
52 	data = HI6553_DISABLE6_XO_CLK_CONN | HI6553_DISABLE6_XO_CLK_NFC |
53 		HI6553_DISABLE6_XO_CLK_RF1 | HI6553_DISABLE6_XO_CLK_RF2;
54 	hi6553_writeb(HI6553_DISABLE6_XO_CLK, data);
55 
56 	/* configure BUCK0 & BUCK1 */
57 	hi6553_writeb(HI6553_BUCK01_CTRL2, 0x5e);
58 	hi6553_writeb(HI6553_BUCK0_CTRL7, 0x10);
59 	hi6553_writeb(HI6553_BUCK1_CTRL7, 0x10);
60 	hi6553_writeb(HI6553_BUCK0_CTRL5, 0x1e);
61 	hi6553_writeb(HI6553_BUCK1_CTRL5, 0x1e);
62 	hi6553_writeb(HI6553_BUCK0_CTRL1, 0xfc);
63 	hi6553_writeb(HI6553_BUCK1_CTRL1, 0xfc);
64 
65 	/* configure BUCK2 */
66 	hi6553_writeb(HI6553_BUCK2_REG1, 0x4f);
67 	hi6553_writeb(HI6553_BUCK2_REG5, 0x99);
68 	hi6553_writeb(HI6553_BUCK2_REG6, 0x45);
69 	mdelay(1);
70 	hi6553_writeb(HI6553_VSET_BUCK2_ADJ, 0x22);
71 	mdelay(1);
72 
73 	/* configure BUCK3 */
74 	hi6553_writeb(HI6553_BUCK3_REG3, 0x02);
75 	hi6553_writeb(HI6553_BUCK3_REG5, 0x99);
76 	hi6553_writeb(HI6553_BUCK3_REG6, 0x41);
77 	hi6553_writeb(HI6553_VSET_BUCK3_ADJ, 0x02);
78 	mdelay(1);
79 
80 	/* configure BUCK4 */
81 	hi6553_writeb(HI6553_BUCK4_REG2, 0x9a);
82 	hi6553_writeb(HI6553_BUCK4_REG5, 0x99);
83 	hi6553_writeb(HI6553_BUCK4_REG6, 0x45);
84 
85 	/* configure LDO20 */
86 	hi6553_writeb(HI6553_LDO20_REG_ADJ, 0x50);
87 
88 	hi6553_writeb(HI6553_NP_REG_CHG, 0x0f);
89 	hi6553_writeb(HI6553_CLK_TOP0, 0x06);
90 	hi6553_writeb(HI6553_CLK_TOP3, 0xc0);
91 	hi6553_writeb(HI6553_CLK_TOP4, 0x00);
92 
93 	/* configure LDO7 & LDO10 for SD slot */
94 	data = hi6553_readb(HI6553_LDO7_REG_ADJ);
95 	data = (data & 0xf8) | 0x2;
96 	hi6553_writeb(HI6553_LDO7_REG_ADJ, data);
97 	mdelay(5);
98 	/* enable LDO7 */
99 	hi6553_writeb(HI6553_ENABLE2_LDO1_8, 1 << 6);
100 	mdelay(5);
101 	data = hi6553_readb(HI6553_LDO10_REG_ADJ);
102 	data = (data & 0xf8) | 0x5;
103 	hi6553_writeb(HI6553_LDO10_REG_ADJ, data);
104 	mdelay(5);
105 	/* enable LDO10 */
106 	hi6553_writeb(HI6553_ENABLE3_LDO9_16, 1 << 1);
107 	mdelay(5);
108 
109 	/* select 32.764KHz */
110 	hi6553_writeb(HI6553_CLK19M2_600_586_EN, 0x01);
111 }
112 
113 int power_hi6553_init(u8 *base)
114 {
115 	static const char name[] = "HI6553 PMIC";
116 	struct pmic *p = pmic_alloc();
117 
118 	if (!p) {
119 		printf("%s: POWER allocation error!\n", __func__);
120 		return -ENOMEM;
121 	}
122 
123 	p->name = name;
124 	p->interface = PMIC_NONE;
125 	p->number_of_regs = 44;
126 	pmussi_base = base;
127 
128 	hi6553_init();
129 
130 	puts("HI6553 PMIC init\n");
131 
132 	return 0;
133 }
134