1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Driver for Delta modules, Q54SJ108A2 series 1/4 Brick DC/DC
4 * Regulated Power Module
5 *
6 * Copyright 2020 Delta LLC.
7 */
8
9 #include <linux/debugfs.h>
10 #include <linux/hex.h>
11 #include <linux/i2c.h>
12 #include <linux/kstrtox.h>
13 #include <linux/module.h>
14 #include <linux/of.h>
15 #include "pmbus.h"
16
17 #define STORE_DEFAULT_ALL 0x11
18 #define ERASE_BLACKBOX_DATA 0xD1
19 #define READ_HISTORY_EVENT_NUMBER 0xD2
20 #define READ_HISTORY_EVENTS 0xE0
21 #define SET_HISTORY_EVENT_OFFSET 0xE1
22 #define PMBUS_FLASH_KEY_WRITE 0xEC
23
24 enum chips {
25 q54sj108a2
26 };
27
28 enum {
29 Q54SJ108A2_DEBUGFS_OPERATION = 0,
30 Q54SJ108A2_DEBUGFS_CLEARFAULT,
31 Q54SJ108A2_DEBUGFS_WRITEPROTECT,
32 Q54SJ108A2_DEBUGFS_STOREDEFAULT,
33 Q54SJ108A2_DEBUGFS_VOOV_RESPONSE,
34 Q54SJ108A2_DEBUGFS_IOOC_RESPONSE,
35 Q54SJ108A2_DEBUGFS_PMBUS_VERSION,
36 Q54SJ108A2_DEBUGFS_MFR_ID,
37 Q54SJ108A2_DEBUGFS_MFR_MODEL,
38 Q54SJ108A2_DEBUGFS_MFR_REVISION,
39 Q54SJ108A2_DEBUGFS_MFR_LOCATION,
40 Q54SJ108A2_DEBUGFS_BLACKBOX_ERASE,
41 Q54SJ108A2_DEBUGFS_BLACKBOX_READ_OFFSET,
42 Q54SJ108A2_DEBUGFS_BLACKBOX_SET_OFFSET,
43 Q54SJ108A2_DEBUGFS_BLACKBOX_READ,
44 Q54SJ108A2_DEBUGFS_FLASH_KEY,
45 Q54SJ108A2_DEBUGFS_NUM_ENTRIES
46 };
47
48 struct q54sj108a2_data {
49 enum chips chip;
50 struct i2c_client *client;
51
52 int debugfs_entries[Q54SJ108A2_DEBUGFS_NUM_ENTRIES];
53 };
54
55 #define to_psu(x, y) container_of((x), struct q54sj108a2_data, debugfs_entries[(y)])
56
57 static struct pmbus_driver_info q54sj108a2_info[] = {
58 [q54sj108a2] = {
59 .pages = 1,
60
61 /* Source : Delta Q54SJ108A2 */
62 .format[PSC_TEMPERATURE] = linear,
63 .format[PSC_VOLTAGE_IN] = linear,
64 .format[PSC_CURRENT_OUT] = linear,
65
66 .func[0] = PMBUS_HAVE_VIN |
67 PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
68 PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT |
69 PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP |
70 PMBUS_HAVE_STATUS_INPUT,
71 },
72 };
73
q54sj108a2_debugfs_read(struct file * file,char __user * buf,size_t count,loff_t * ppos)74 static ssize_t q54sj108a2_debugfs_read(struct file *file, char __user *buf,
75 size_t count, loff_t *ppos)
76 {
77 int rc;
78 int *idxp = file->private_data;
79 int idx = *idxp;
80 struct q54sj108a2_data *psu = to_psu(idxp, idx);
81 char data[I2C_SMBUS_BLOCK_MAX + 2] = { 0 };
82 char data_char[I2C_SMBUS_BLOCK_MAX * 2 + 2] = { 0 };
83 char *out = data;
84 char *res;
85
86 switch (idx) {
87 case Q54SJ108A2_DEBUGFS_OPERATION:
88 rc = i2c_smbus_read_byte_data(psu->client, PMBUS_OPERATION);
89 if (rc < 0)
90 return rc;
91
92 rc = snprintf(data, 3, "%02x", rc);
93 break;
94 case Q54SJ108A2_DEBUGFS_WRITEPROTECT:
95 rc = i2c_smbus_read_byte_data(psu->client, PMBUS_WRITE_PROTECT);
96 if (rc < 0)
97 return rc;
98
99 rc = snprintf(data, 3, "%02x", rc);
100 break;
101 case Q54SJ108A2_DEBUGFS_VOOV_RESPONSE:
102 rc = i2c_smbus_read_byte_data(psu->client, PMBUS_VOUT_OV_FAULT_RESPONSE);
103 if (rc < 0)
104 return rc;
105
106 rc = snprintf(data, 3, "%02x", rc);
107 break;
108 case Q54SJ108A2_DEBUGFS_IOOC_RESPONSE:
109 rc = i2c_smbus_read_byte_data(psu->client, PMBUS_IOUT_OC_FAULT_RESPONSE);
110 if (rc < 0)
111 return rc;
112
113 rc = snprintf(data, 3, "%02x", rc);
114 break;
115 case Q54SJ108A2_DEBUGFS_PMBUS_VERSION:
116 rc = i2c_smbus_read_byte_data(psu->client, PMBUS_REVISION);
117 if (rc < 0)
118 return rc;
119
120 rc = snprintf(data, 3, "%02x", rc);
121 break;
122 case Q54SJ108A2_DEBUGFS_MFR_ID:
123 rc = i2c_smbus_read_block_data(psu->client, PMBUS_MFR_ID, data);
124 if (rc < 0)
125 return rc;
126 break;
127 case Q54SJ108A2_DEBUGFS_MFR_MODEL:
128 rc = i2c_smbus_read_block_data(psu->client, PMBUS_MFR_MODEL, data);
129 if (rc < 0)
130 return rc;
131 break;
132 case Q54SJ108A2_DEBUGFS_MFR_REVISION:
133 rc = i2c_smbus_read_block_data(psu->client, PMBUS_MFR_REVISION, data);
134 if (rc < 0)
135 return rc;
136 break;
137 case Q54SJ108A2_DEBUGFS_MFR_LOCATION:
138 rc = i2c_smbus_read_block_data(psu->client, PMBUS_MFR_LOCATION, data);
139 if (rc < 0)
140 return rc;
141 break;
142 case Q54SJ108A2_DEBUGFS_BLACKBOX_READ_OFFSET:
143 rc = i2c_smbus_read_byte_data(psu->client, READ_HISTORY_EVENT_NUMBER);
144 if (rc < 0)
145 return rc;
146
147 rc = snprintf(data, 3, "%02x", rc);
148 break;
149 case Q54SJ108A2_DEBUGFS_BLACKBOX_READ:
150 rc = i2c_smbus_read_block_data(psu->client, READ_HISTORY_EVENTS, data);
151 if (rc < 0)
152 return rc;
153
154 res = bin2hex(data_char, data, rc);
155 rc = res - data_char;
156 out = data_char;
157 break;
158 case Q54SJ108A2_DEBUGFS_FLASH_KEY:
159 rc = i2c_smbus_read_block_data(psu->client, PMBUS_FLASH_KEY_WRITE, data);
160 if (rc < 0)
161 return rc;
162
163 res = bin2hex(data_char, data, rc);
164 rc = res - data_char;
165 out = data_char;
166 break;
167 default:
168 return -EINVAL;
169 }
170
171 out[rc] = '\n';
172 rc += 2;
173
174 return simple_read_from_buffer(buf, count, ppos, out, rc);
175 }
176
q54sj108a2_debugfs_write(struct file * file,const char __user * buf,size_t count,loff_t * ppos)177 static ssize_t q54sj108a2_debugfs_write(struct file *file, const char __user *buf,
178 size_t count, loff_t *ppos)
179 {
180 u8 flash_key[4];
181 u8 dst_data;
182 ssize_t rc;
183 int *idxp = file->private_data;
184 int idx = *idxp;
185 struct q54sj108a2_data *psu = to_psu(idxp, idx);
186
187 rc = i2c_smbus_write_byte_data(psu->client, PMBUS_WRITE_PROTECT, 0);
188 if (rc)
189 return rc;
190
191 switch (idx) {
192 case Q54SJ108A2_DEBUGFS_OPERATION:
193 rc = kstrtou8_from_user(buf, count, 0, &dst_data);
194 if (rc < 0)
195 return rc;
196
197 rc = i2c_smbus_write_byte_data(psu->client, PMBUS_OPERATION, dst_data);
198 if (rc < 0)
199 return rc;
200
201 break;
202 case Q54SJ108A2_DEBUGFS_CLEARFAULT:
203 rc = i2c_smbus_write_byte(psu->client, PMBUS_CLEAR_FAULTS);
204 if (rc < 0)
205 return rc;
206
207 break;
208 case Q54SJ108A2_DEBUGFS_STOREDEFAULT:
209 flash_key[0] = 0x7E;
210 flash_key[1] = 0x15;
211 flash_key[2] = 0xDC;
212 flash_key[3] = 0x42;
213 rc = i2c_smbus_write_block_data(psu->client, PMBUS_FLASH_KEY_WRITE, 4, flash_key);
214 if (rc < 0)
215 return rc;
216
217 rc = i2c_smbus_write_byte(psu->client, STORE_DEFAULT_ALL);
218 if (rc < 0)
219 return rc;
220
221 break;
222 case Q54SJ108A2_DEBUGFS_VOOV_RESPONSE:
223 rc = kstrtou8_from_user(buf, count, 0, &dst_data);
224 if (rc < 0)
225 return rc;
226
227 rc = i2c_smbus_write_byte_data(psu->client, PMBUS_VOUT_OV_FAULT_RESPONSE, dst_data);
228 if (rc < 0)
229 return rc;
230
231 break;
232 case Q54SJ108A2_DEBUGFS_IOOC_RESPONSE:
233 rc = kstrtou8_from_user(buf, count, 0, &dst_data);
234 if (rc < 0)
235 return rc;
236
237 rc = i2c_smbus_write_byte_data(psu->client, PMBUS_IOUT_OC_FAULT_RESPONSE, dst_data);
238 if (rc < 0)
239 return rc;
240
241 break;
242 case Q54SJ108A2_DEBUGFS_BLACKBOX_ERASE:
243 rc = i2c_smbus_write_byte(psu->client, ERASE_BLACKBOX_DATA);
244 if (rc < 0)
245 return rc;
246
247 break;
248 case Q54SJ108A2_DEBUGFS_BLACKBOX_SET_OFFSET:
249 rc = kstrtou8_from_user(buf, count, 0, &dst_data);
250 if (rc < 0)
251 return rc;
252
253 rc = i2c_smbus_write_byte_data(psu->client, SET_HISTORY_EVENT_OFFSET, dst_data);
254 if (rc < 0)
255 return rc;
256
257 break;
258 default:
259 return -EINVAL;
260 }
261
262 return count;
263 }
264
265 static const struct file_operations q54sj108a2_fops = {
266 .llseek = noop_llseek,
267 .read = q54sj108a2_debugfs_read,
268 .write = q54sj108a2_debugfs_write,
269 .open = simple_open,
270 };
271
272 static const struct i2c_device_id q54sj108a2_id[] = {
273 { "q54sj108a2", q54sj108a2 },
274 { },
275 };
276
277 MODULE_DEVICE_TABLE(i2c, q54sj108a2_id);
278
q54sj108a2_probe(struct i2c_client * client)279 static int q54sj108a2_probe(struct i2c_client *client)
280 {
281 struct device *dev = &client->dev;
282 u8 buf[I2C_SMBUS_BLOCK_MAX + 1];
283 enum chips chip_id;
284 int ret, i;
285 struct dentry *debugfs;
286 struct dentry *q54sj108a2_dir;
287 struct q54sj108a2_data *psu;
288
289 if (!i2c_check_functionality(client->adapter,
290 I2C_FUNC_SMBUS_BYTE_DATA |
291 I2C_FUNC_SMBUS_WORD_DATA |
292 I2C_FUNC_SMBUS_BLOCK_DATA))
293 return -ENODEV;
294
295 if (client->dev.of_node)
296 chip_id = (enum chips)(unsigned long)of_device_get_match_data(dev);
297 else
298 chip_id = i2c_match_id(q54sj108a2_id, client)->driver_data;
299
300 ret = i2c_smbus_read_block_data(client, PMBUS_MFR_ID, buf);
301 if (ret < 0) {
302 dev_err(&client->dev, "Failed to read Manufacturer ID\n");
303 return ret;
304 }
305 if (ret != 6 || strncmp(buf, "DELTA", 5)) {
306 buf[ret] = '\0';
307 dev_err(dev, "Unsupported Manufacturer ID '%s'\n", buf);
308 return -ENODEV;
309 }
310
311 /*
312 * The chips support reading PMBUS_MFR_MODEL.
313 */
314 ret = i2c_smbus_read_block_data(client, PMBUS_MFR_MODEL, buf);
315 if (ret < 0) {
316 dev_err(dev, "Failed to read Manufacturer Model\n");
317 return ret;
318 }
319 if (ret != 14 || strncmp(buf, "Q54SJ108A2", 10)) {
320 buf[ret] = '\0';
321 dev_err(dev, "Unsupported Manufacturer Model '%s'\n", buf);
322 return -ENODEV;
323 }
324
325 ret = i2c_smbus_read_block_data(client, PMBUS_MFR_REVISION, buf);
326 if (ret < 0) {
327 dev_err(dev, "Failed to read Manufacturer Revision\n");
328 return ret;
329 }
330 if (ret != 4 || buf[0] != 'S') {
331 buf[ret] = '\0';
332 dev_err(dev, "Unsupported Manufacturer Revision '%s'\n", buf);
333 return -ENODEV;
334 }
335
336 ret = pmbus_do_probe(client, &q54sj108a2_info[chip_id]);
337 if (ret)
338 return ret;
339
340 psu = devm_kzalloc(&client->dev, sizeof(*psu), GFP_KERNEL);
341 if (!psu)
342 return 0;
343
344 psu->client = client;
345
346 debugfs = pmbus_get_debugfs_dir(client);
347
348 q54sj108a2_dir = debugfs_create_dir(client->name, debugfs);
349
350 for (i = 0; i < Q54SJ108A2_DEBUGFS_NUM_ENTRIES; ++i)
351 psu->debugfs_entries[i] = i;
352
353 debugfs_create_file("operation", 0644, q54sj108a2_dir,
354 &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_OPERATION],
355 &q54sj108a2_fops);
356 debugfs_create_file("clear_fault", 0200, q54sj108a2_dir,
357 &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_CLEARFAULT],
358 &q54sj108a2_fops);
359 debugfs_create_file("write_protect", 0444, q54sj108a2_dir,
360 &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_WRITEPROTECT],
361 &q54sj108a2_fops);
362 debugfs_create_file("store_default", 0200, q54sj108a2_dir,
363 &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_STOREDEFAULT],
364 &q54sj108a2_fops);
365 debugfs_create_file("vo_ov_response", 0644, q54sj108a2_dir,
366 &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_VOOV_RESPONSE],
367 &q54sj108a2_fops);
368 debugfs_create_file("io_oc_response", 0644, q54sj108a2_dir,
369 &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_IOOC_RESPONSE],
370 &q54sj108a2_fops);
371 debugfs_create_file("pmbus_revision", 0444, q54sj108a2_dir,
372 &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_PMBUS_VERSION],
373 &q54sj108a2_fops);
374 debugfs_create_file("mfr_id", 0444, q54sj108a2_dir,
375 &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_MFR_ID],
376 &q54sj108a2_fops);
377 debugfs_create_file("mfr_model", 0444, q54sj108a2_dir,
378 &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_MFR_MODEL],
379 &q54sj108a2_fops);
380 debugfs_create_file("mfr_revision", 0444, q54sj108a2_dir,
381 &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_MFR_REVISION],
382 &q54sj108a2_fops);
383 debugfs_create_file("mfr_location", 0444, q54sj108a2_dir,
384 &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_MFR_LOCATION],
385 &q54sj108a2_fops);
386 debugfs_create_file("blackbox_erase", 0200, q54sj108a2_dir,
387 &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_BLACKBOX_ERASE],
388 &q54sj108a2_fops);
389 debugfs_create_file("blackbox_read_offset", 0444, q54sj108a2_dir,
390 &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_BLACKBOX_READ_OFFSET],
391 &q54sj108a2_fops);
392 debugfs_create_file("blackbox_set_offset", 0200, q54sj108a2_dir,
393 &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_BLACKBOX_SET_OFFSET],
394 &q54sj108a2_fops);
395 debugfs_create_file("blackbox_read", 0444, q54sj108a2_dir,
396 &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_BLACKBOX_READ],
397 &q54sj108a2_fops);
398 debugfs_create_file("flash_key", 0444, q54sj108a2_dir,
399 &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_FLASH_KEY],
400 &q54sj108a2_fops);
401
402 return 0;
403 }
404
405 static const struct of_device_id q54sj108a2_of_match[] = {
406 { .compatible = "delta,q54sj108a2", .data = (void *)q54sj108a2 },
407 { },
408 };
409
410 MODULE_DEVICE_TABLE(of, q54sj108a2_of_match);
411
412 static struct i2c_driver q54sj108a2_driver = {
413 .driver = {
414 .name = "q54sj108a2",
415 .of_match_table = q54sj108a2_of_match,
416 },
417 .probe = q54sj108a2_probe,
418 .id_table = q54sj108a2_id,
419 };
420
421 module_i2c_driver(q54sj108a2_driver);
422
423 MODULE_AUTHOR("Xiao.Ma <xiao.mx.ma@deltaww.com>");
424 MODULE_DESCRIPTION("PMBus driver for Delta Q54SJ108A2 series modules");
425 MODULE_LICENSE("GPL");
426 MODULE_IMPORT_NS("PMBUS");
427