xref: /linux/drivers/hwmon/pmbus/q54sj108a2.c (revision 7b6e48df8892e1f128473e6971b3b8b24eb39f4b)
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