xref: /openbmc/u-boot/board/freescale/common/zm7300.c (revision 3ebd892f)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2013 Freescale Semiconductor, Inc.
4  */
5 
6 /* Power-One ZM7300 DPM */
7 #include "zm7300.h"
8 
9 #define DPM_WP 0x96
10 #define WRP_OPCODE 0x01
11 #define WRM_OPCODE 0x02
12 #define RRP_OPCODE 0x11
13 
14 #define DPM_SUCCESS 0x01
15 #define DPM_EXEC_FAIL 0x00
16 
17 static const uint16_t hex_to_1_10mv[] = {
18 	5000,
19 	5125,
20 	5250,
21 	5375,
22 	5500,
23 	5625,
24 	5750,
25 	5875,
26 	6000,
27 	6125,
28 	6250,
29 	6375,
30 	6500,
31 	6625,
32 	6750,
33 	6875,
34 	7000,
35 	7125,
36 	7250,
37 	7375,
38 	7500,
39 	7625,
40 	7750,
41 	7875,
42 	8000,
43 	8125,
44 	8250,
45 	8375,
46 	8500,
47 	8625,
48 	8750,
49 	8875,
50 	9000,
51 	9125,
52 	9250,
53 	9375,
54 	9500,  /* 0.95mV */
55 	9625,
56 	9750,
57 	9875,
58 	10000,  /* 1.0V */
59 	10125,
60 	10250,
61 	10375,
62 	10500,
63 	10625,
64 	10750,
65 	10875,
66 	11000,
67 	11125,
68 	11250,
69 	11375,
70 	11500,
71 	11625,
72 	11750,
73 	11875,
74 	12000,
75 	12125,
76 	12250,
77 	12375,
78 	0,	/* reserved */
79 };
80 
81 
82 /* Read Data d from Register r of POL p */
83 u8 dpm_rrp(uchar r)
84 {
85 	u8 ret[5];
86 
87 	ret[0] = RRP_OPCODE;
88 	/* POL is 0 */
89 	ret[1] = 0;
90 	ret[2] = r;
91 	i2c_read(I2C_DPM_ADDR, 0, -3, ret, 2);
92 	if (ret[1] == DPM_SUCCESS) { /* the DPM returned success as status */
93 		debug("RRP_OPCODE returned success data is %x\n", ret[0]);
94 		return ret[0];
95 	} else {
96 		return -1;
97 	}
98 }
99 
100 /* Write Data d into DPM register r (RAM) */
101 int dpm_wrm(u8 r, u8 d)
102 {
103 	u8 ret[5];
104 
105 	ret[0] = WRM_OPCODE;
106 	ret[1] = r;
107 	ret[2] = d;
108 	i2c_read(I2C_DPM_ADDR, 0, -3, ret, 1);
109 	if (ret[0] == DPM_SUCCESS) { /* the DPM returned success as status */
110 		debug("WRM_OPCODE returned success data is %x\n", ret[0]);
111 		return ret[0];
112 	} else {
113 		return -1;
114 	}
115 }
116 
117 /* Write Data d into Register r of POL(s) a */
118 int dpm_wrp(u8 r, u8 d)
119 {
120 	u8 ret[7];
121 
122 	ret[0] = WRP_OPCODE;
123 	/* only POL0 is present */
124 	ret[1] = 0x01;
125 	ret[2] = 0x00;
126 	ret[3] = 0x00;
127 	ret[4] = 0x00;
128 	ret[5] = r;
129 	ret[6] = d;
130 	i2c_read(I2C_DPM_ADDR, 0, -7, ret, 1);
131 	if (ret[0] == DPM_SUCCESS) { /* the DPM returned success as status */
132 		debug("WRP_OPCODE returned success data is %x\n", ret[0]);
133 		return 0;
134 	} else {
135 		return -1;
136 	}
137 }
138 
139 /* Uses the DPM command RRP */
140 u8 zm_read(uchar reg)
141 {
142 	return dpm_rrp(reg);
143 }
144 
145 /* ZM_write --
146 	Steps:
147 	a. Write data to the register
148 	b. Read data from register and compare to written value
149 	c. Return return_code & voltage_read
150 */
151 u8 zm_write(u8 reg, u8 data)
152 {
153 	u8 d;
154 
155 	/* write data to register */
156 	dpm_wrp(reg, data);
157 
158 	/* read register and compare to written value */
159 	d = dpm_rrp(reg);
160 	if (d != data) {
161 		printf("zm_write : Comparison register data failed\n");
162 		return -1;
163 	}
164 
165 	return d;
166 }
167 
168 /* zm_write_out_voltage
169  * voltage in 1/10 mV
170  */
171 int zm_write_voltage(int voltage)
172 {
173 	u8 reg = 0x7, vid;
174 	uint16_t voltage_read;
175 	u8 ret;
176 
177 	vid =  (voltage - 5000) / ZM_STEP;
178 
179 	ret = zm_write(reg, vid);
180 	if (ret != -1) {
181 		voltage_read = hex_to_1_10mv[ret];
182 		debug("voltage set to %dmV\n", voltage_read/10);
183 		return voltage_read;
184 	}
185 	return -1;
186 }
187 
188 /* zm_read_out_voltage
189  * voltage in 1/10 mV
190  */
191 int zm_read_voltage(void)
192 {
193 	u8 reg = 0x7;
194 	u8 ret;
195 	int voltage;
196 
197 	ret = zm_read(reg);
198 	if (ret != -1) {
199 		voltage =  hex_to_1_10mv[ret];
200 		debug("Voltage read is %dmV\n", voltage/10);
201 		return voltage;
202 	} else {
203 		return -1;
204 	}
205 }
206 
207 int zm_disable_wp()
208 {
209 	u8 new_wp_value;
210 
211 	/* Disable using Write-Protect register 0x96 */
212 	new_wp_value = 0x8;
213 	if ((dpm_wrm(DPM_WP, new_wp_value)) < 0) {
214 		printf("Disable Write-Protect register failed\n");
215 		return -1;
216 	}
217 	return 0;
218 }
219 
220 int zm_enable_wp()
221 {
222 	u8 orig_wp_value;
223 	orig_wp_value = 0x0;
224 
225 	/* Enable using Write-Protect register 0x96 */
226 	if ((dpm_wrm(DPM_WP, orig_wp_value)) < 0) {
227 		printf("Enable Write-Protect register failed\n");
228 		return -1;
229 	}
230 	return 0;
231 }
232 
233