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 */
dpm_rrp(uchar r)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) */
dpm_wrm(u8 r,u8 d)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 */
dpm_wrp(u8 r,u8 d)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 */
zm_read(uchar reg)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 */
zm_write(u8 reg,u8 data)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 */
zm_write_voltage(int voltage)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 */
zm_read_voltage(void)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
zm_disable_wp()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
zm_enable_wp()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