]>
Commit | Line | Data |
---|---|---|
9514a228 AT |
1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* | |
3 | * ADM1266 - Cascadable Super Sequencer with Margin | |
4 | * Control and Fault Recording | |
5 | * | |
6 | * Copyright 2020 Analog Devices Inc. | |
7 | */ | |
8 | ||
d98dfad3 | 9 | #include <linux/bitfield.h> |
407dc802 | 10 | #include <linux/crc8.h> |
d98dfad3 AT |
11 | #include <linux/debugfs.h> |
12 | #include <linux/gpio/driver.h> | |
9514a228 | 13 | #include <linux/i2c.h> |
d98dfad3 | 14 | #include <linux/i2c-smbus.h> |
9514a228 AT |
15 | #include <linux/init.h> |
16 | #include <linux/kernel.h> | |
17 | #include <linux/module.h> | |
15609d18 AT |
18 | #include <linux/nvmem-consumer.h> |
19 | #include <linux/nvmem-provider.h> | |
9514a228 AT |
20 | #include "pmbus.h" |
21 | #include <linux/slab.h> | |
15609d18 | 22 | #include <linux/timekeeping.h> |
9514a228 | 23 | |
15609d18 | 24 | #define ADM1266_BLACKBOX_CONFIG 0xD3 |
d98dfad3 | 25 | #define ADM1266_PDIO_CONFIG 0xD4 |
ed1ff457 | 26 | #define ADM1266_READ_STATE 0xD9 |
15609d18 AT |
27 | #define ADM1266_READ_BLACKBOX 0xDE |
28 | #define ADM1266_SET_RTC 0xDF | |
d98dfad3 | 29 | #define ADM1266_GPIO_CONFIG 0xE1 |
15609d18 | 30 | #define ADM1266_BLACKBOX_INFO 0xE6 |
d98dfad3 AT |
31 | #define ADM1266_PDIO_STATUS 0xE9 |
32 | #define ADM1266_GPIO_STATUS 0xEA | |
33 | ||
34 | /* ADM1266 GPIO defines */ | |
35 | #define ADM1266_GPIO_NR 9 | |
36 | #define ADM1266_GPIO_FUNCTIONS(x) FIELD_GET(BIT(0), x) | |
37 | #define ADM1266_GPIO_INPUT_EN(x) FIELD_GET(BIT(2), x) | |
38 | #define ADM1266_GPIO_OUTPUT_EN(x) FIELD_GET(BIT(3), x) | |
39 | #define ADM1266_GPIO_OPEN_DRAIN(x) FIELD_GET(BIT(4), x) | |
40 | ||
41 | /* ADM1266 PDIO defines */ | |
42 | #define ADM1266_PDIO_NR 16 | |
43 | #define ADM1266_PDIO_PIN_CFG(x) FIELD_GET(GENMASK(15, 13), x) | |
44 | #define ADM1266_PDIO_GLITCH_FILT(x) FIELD_GET(GENMASK(12, 9), x) | |
45 | #define ADM1266_PDIO_OUT_CFG(x) FIELD_GET(GENMASK(2, 0), x) | |
46 | ||
15609d18 AT |
47 | #define ADM1266_BLACKBOX_OFFSET 0 |
48 | #define ADM1266_BLACKBOX_SIZE 64 | |
49 | ||
407dc802 AT |
50 | #define ADM1266_PMBUS_BLOCK_MAX 255 |
51 | ||
9514a228 AT |
52 | struct adm1266_data { |
53 | struct pmbus_driver_info info; | |
d98dfad3 AT |
54 | struct gpio_chip gc; |
55 | const char *gpio_names[ADM1266_GPIO_NR + ADM1266_PDIO_NR]; | |
9514a228 | 56 | struct i2c_client *client; |
ed1ff457 | 57 | struct dentry *debugfs_dir; |
15609d18 AT |
58 | struct nvmem_config nvmem_config; |
59 | struct nvmem_device *nvmem; | |
60 | u8 *dev_mem; | |
407dc802 AT |
61 | struct mutex buf_mutex; |
62 | u8 write_buf[ADM1266_PMBUS_BLOCK_MAX + 1] ____cacheline_aligned; | |
63 | u8 read_buf[ADM1266_PMBUS_BLOCK_MAX + 1] ____cacheline_aligned; | |
9514a228 AT |
64 | }; |
65 | ||
15609d18 AT |
66 | static const struct nvmem_cell_info adm1266_nvmem_cells[] = { |
67 | { | |
68 | .name = "blackbox", | |
69 | .offset = ADM1266_BLACKBOX_OFFSET, | |
70 | .bytes = 2048, | |
71 | }, | |
72 | }; | |
73 | ||
407dc802 AT |
74 | DECLARE_CRC8_TABLE(pmbus_crc_table); |
75 | ||
76 | /* | |
77 | * Different from Block Read as it sends data and waits for the slave to | |
78 | * return a value dependent on that data. The protocol is simply a Write Block | |
79 | * followed by a Read Block without the Read-Block command field and the | |
80 | * Write-Block STOP bit. | |
81 | */ | |
82 | static int adm1266_pmbus_block_xfer(struct adm1266_data *data, u8 cmd, u8 w_len, u8 *data_w, | |
83 | u8 *data_r) | |
84 | { | |
85 | struct i2c_client *client = data->client; | |
86 | struct i2c_msg msgs[2] = { | |
87 | { | |
88 | .addr = client->addr, | |
89 | .flags = I2C_M_DMA_SAFE, | |
90 | .buf = data->write_buf, | |
91 | .len = w_len + 2, | |
92 | }, | |
93 | { | |
94 | .addr = client->addr, | |
95 | .flags = I2C_M_RD | I2C_M_DMA_SAFE, | |
96 | .buf = data->read_buf, | |
97 | .len = ADM1266_PMBUS_BLOCK_MAX + 2, | |
98 | } | |
99 | }; | |
100 | u8 addr; | |
101 | u8 crc; | |
102 | int ret; | |
103 | ||
104 | mutex_lock(&data->buf_mutex); | |
105 | ||
106 | msgs[0].buf[0] = cmd; | |
107 | msgs[0].buf[1] = w_len; | |
108 | memcpy(&msgs[0].buf[2], data_w, w_len); | |
109 | ||
110 | ret = i2c_transfer(client->adapter, msgs, 2); | |
111 | if (ret != 2) { | |
112 | if (ret >= 0) | |
113 | ret = -EPROTO; | |
114 | ||
115 | mutex_unlock(&data->buf_mutex); | |
116 | ||
117 | return ret; | |
118 | } | |
119 | ||
120 | if (client->flags & I2C_CLIENT_PEC) { | |
121 | addr = i2c_8bit_addr_from_msg(&msgs[0]); | |
122 | crc = crc8(pmbus_crc_table, &addr, 1, 0); | |
123 | crc = crc8(pmbus_crc_table, msgs[0].buf, msgs[0].len, crc); | |
124 | ||
125 | addr = i2c_8bit_addr_from_msg(&msgs[1]); | |
126 | crc = crc8(pmbus_crc_table, &addr, 1, crc); | |
127 | crc = crc8(pmbus_crc_table, msgs[1].buf, msgs[1].buf[0] + 1, crc); | |
128 | ||
129 | if (crc != msgs[1].buf[msgs[1].buf[0] + 1]) { | |
130 | mutex_unlock(&data->buf_mutex); | |
131 | return -EBADMSG; | |
132 | } | |
133 | } | |
134 | ||
135 | memcpy(data_r, &msgs[1].buf[1], msgs[1].buf[0]); | |
136 | ||
137 | ret = msgs[1].buf[0]; | |
138 | mutex_unlock(&data->buf_mutex); | |
139 | ||
140 | return ret; | |
141 | } | |
142 | ||
d98dfad3 AT |
143 | static const unsigned int adm1266_gpio_mapping[ADM1266_GPIO_NR][2] = { |
144 | {1, 0}, | |
145 | {2, 1}, | |
146 | {3, 2}, | |
147 | {4, 8}, | |
148 | {5, 9}, | |
149 | {6, 10}, | |
150 | {7, 11}, | |
151 | {8, 6}, | |
152 | {9, 7}, | |
153 | }; | |
154 | ||
155 | static const char *adm1266_names[ADM1266_GPIO_NR + ADM1266_PDIO_NR] = { | |
156 | "GPIO1", "GPIO2", "GPIO3", "GPIO4", "GPIO5", "GPIO6", "GPIO7", "GPIO8", | |
157 | "GPIO9", "PDIO1", "PDIO2", "PDIO3", "PDIO4", "PDIO5", "PDIO6", | |
158 | "PDIO7", "PDIO8", "PDIO9", "PDIO10", "PDIO11", "PDIO12", "PDIO13", | |
159 | "PDIO14", "PDIO15", "PDIO16", | |
160 | }; | |
161 | ||
162 | static int adm1266_gpio_get(struct gpio_chip *chip, unsigned int offset) | |
163 | { | |
164 | struct adm1266_data *data = gpiochip_get_data(chip); | |
165 | u8 read_buf[I2C_SMBUS_BLOCK_MAX + 1]; | |
166 | unsigned long pins_status; | |
167 | unsigned int pmbus_cmd; | |
168 | int ret; | |
169 | ||
170 | if (offset < ADM1266_GPIO_NR) | |
171 | pmbus_cmd = ADM1266_GPIO_STATUS; | |
172 | else | |
173 | pmbus_cmd = ADM1266_PDIO_STATUS; | |
174 | ||
175 | ret = i2c_smbus_read_block_data(data->client, pmbus_cmd, read_buf); | |
176 | if (ret < 0) | |
177 | return ret; | |
178 | ||
179 | pins_status = read_buf[0] + (read_buf[1] << 8); | |
180 | if (offset < ADM1266_GPIO_NR) | |
181 | return test_bit(adm1266_gpio_mapping[offset][1], &pins_status); | |
182 | ||
183 | return test_bit(offset - ADM1266_GPIO_NR, &pins_status); | |
184 | } | |
185 | ||
186 | static int adm1266_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask, | |
187 | unsigned long *bits) | |
188 | { | |
189 | struct adm1266_data *data = gpiochip_get_data(chip); | |
190 | u8 read_buf[ADM1266_PMBUS_BLOCK_MAX + 1]; | |
191 | unsigned long status; | |
192 | unsigned int gpio_nr; | |
193 | int ret; | |
194 | ||
195 | ret = i2c_smbus_read_block_data(data->client, ADM1266_GPIO_STATUS, read_buf); | |
196 | if (ret < 0) | |
197 | return ret; | |
198 | ||
199 | status = read_buf[0] + (read_buf[1] << 8); | |
200 | ||
201 | *bits = 0; | |
202 | for_each_set_bit(gpio_nr, mask, ADM1266_GPIO_NR) { | |
203 | if (test_bit(adm1266_gpio_mapping[gpio_nr][1], &status)) | |
204 | set_bit(gpio_nr, bits); | |
205 | } | |
206 | ||
207 | ret = i2c_smbus_read_block_data(data->client, ADM1266_PDIO_STATUS, read_buf); | |
208 | if (ret < 0) | |
209 | return ret; | |
210 | ||
211 | status = read_buf[0] + (read_buf[1] << 8); | |
212 | ||
213 | *bits = 0; | |
214 | for_each_set_bit_from(gpio_nr, mask, ADM1266_GPIO_NR + ADM1266_PDIO_STATUS) { | |
215 | if (test_bit(gpio_nr - ADM1266_GPIO_NR, &status)) | |
216 | set_bit(gpio_nr, bits); | |
217 | } | |
218 | ||
219 | return 0; | |
220 | } | |
221 | ||
222 | static void adm1266_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) | |
223 | { | |
224 | struct adm1266_data *data = gpiochip_get_data(chip); | |
225 | u8 read_buf[ADM1266_PMBUS_BLOCK_MAX + 1]; | |
226 | unsigned long gpio_config; | |
227 | unsigned long pdio_config; | |
228 | unsigned long pin_cfg; | |
229 | u8 write_cmd; | |
230 | int ret; | |
231 | int i; | |
232 | ||
233 | for (i = 0; i < ADM1266_GPIO_NR; i++) { | |
234 | write_cmd = adm1266_gpio_mapping[i][1]; | |
235 | ret = adm1266_pmbus_block_xfer(data, ADM1266_GPIO_CONFIG, 1, &write_cmd, read_buf); | |
236 | if (ret != 2) | |
237 | return; | |
238 | ||
239 | gpio_config = read_buf[0]; | |
240 | seq_puts(s, adm1266_names[i]); | |
241 | ||
242 | seq_puts(s, " ( "); | |
243 | if (!ADM1266_GPIO_FUNCTIONS(gpio_config)) { | |
244 | seq_puts(s, "high-Z )\n"); | |
245 | continue; | |
246 | } | |
247 | if (ADM1266_GPIO_INPUT_EN(gpio_config)) | |
248 | seq_puts(s, "input "); | |
249 | if (ADM1266_GPIO_OUTPUT_EN(gpio_config)) | |
250 | seq_puts(s, "output "); | |
251 | if (ADM1266_GPIO_OPEN_DRAIN(gpio_config)) | |
252 | seq_puts(s, "open-drain )\n"); | |
253 | else | |
254 | seq_puts(s, "push-pull )\n"); | |
255 | } | |
256 | ||
257 | write_cmd = 0xFF; | |
258 | ret = adm1266_pmbus_block_xfer(data, ADM1266_PDIO_CONFIG, 1, &write_cmd, read_buf); | |
259 | if (ret != 32) | |
260 | return; | |
261 | ||
262 | for (i = 0; i < ADM1266_PDIO_NR; i++) { | |
263 | seq_puts(s, adm1266_names[ADM1266_GPIO_NR + i]); | |
264 | ||
265 | pdio_config = read_buf[2 * i]; | |
266 | pdio_config += (read_buf[2 * i + 1] << 8); | |
267 | pin_cfg = ADM1266_PDIO_PIN_CFG(pdio_config); | |
268 | ||
269 | seq_puts(s, " ( "); | |
270 | if (!pin_cfg || pin_cfg > 5) { | |
271 | seq_puts(s, "high-Z )\n"); | |
272 | continue; | |
273 | } | |
274 | ||
275 | if (pin_cfg & BIT(0)) | |
276 | seq_puts(s, "output "); | |
277 | ||
278 | if (pin_cfg & BIT(1)) | |
279 | seq_puts(s, "input "); | |
280 | ||
281 | seq_puts(s, ")\n"); | |
282 | } | |
283 | } | |
284 | ||
285 | static int adm1266_config_gpio(struct adm1266_data *data) | |
286 | { | |
287 | const char *name = dev_name(&data->client->dev); | |
288 | char *gpio_name; | |
289 | int ret; | |
290 | int i; | |
291 | ||
292 | for (i = 0; i < ARRAY_SIZE(data->gpio_names); i++) { | |
293 | gpio_name = devm_kasprintf(&data->client->dev, GFP_KERNEL, "adm1266-%x-%s", | |
294 | data->client->addr, adm1266_names[i]); | |
295 | if (!gpio_name) | |
296 | return -ENOMEM; | |
297 | ||
298 | data->gpio_names[i] = gpio_name; | |
299 | } | |
300 | ||
301 | data->gc.label = name; | |
302 | data->gc.parent = &data->client->dev; | |
303 | data->gc.owner = THIS_MODULE; | |
304 | data->gc.base = -1; | |
305 | data->gc.names = data->gpio_names; | |
306 | data->gc.ngpio = ARRAY_SIZE(data->gpio_names); | |
307 | data->gc.get = adm1266_gpio_get; | |
308 | data->gc.get_multiple = adm1266_gpio_get_multiple; | |
309 | data->gc.dbg_show = adm1266_gpio_dbg_show; | |
310 | ||
311 | ret = devm_gpiochip_add_data(&data->client->dev, &data->gc, data); | |
312 | if (ret) | |
313 | dev_err(&data->client->dev, "GPIO registering failed (%d)\n", ret); | |
314 | ||
315 | return ret; | |
316 | } | |
317 | ||
ed1ff457 AT |
318 | static int adm1266_state_read(struct seq_file *s, void *pdata) |
319 | { | |
320 | struct device *dev = s->private; | |
321 | struct i2c_client *client = to_i2c_client(dev); | |
322 | int ret; | |
323 | ||
324 | ret = i2c_smbus_read_word_data(client, ADM1266_READ_STATE); | |
325 | if (ret < 0) | |
326 | return ret; | |
327 | ||
328 | seq_printf(s, "%d\n", ret); | |
329 | ||
330 | return 0; | |
331 | } | |
332 | ||
333 | static void adm1266_init_debugfs(struct adm1266_data *data) | |
334 | { | |
335 | struct dentry *root; | |
336 | ||
337 | root = pmbus_get_debugfs_dir(data->client); | |
338 | if (!root) | |
339 | return; | |
340 | ||
341 | data->debugfs_dir = debugfs_create_dir(data->client->name, root); | |
342 | if (!data->debugfs_dir) | |
343 | return; | |
344 | ||
345 | debugfs_create_devm_seqfile(&data->client->dev, "sequencer_state", data->debugfs_dir, | |
346 | adm1266_state_read); | |
347 | } | |
348 | ||
15609d18 AT |
349 | static int adm1266_nvmem_read_blackbox(struct adm1266_data *data, u8 *read_buff) |
350 | { | |
351 | int record_count; | |
352 | char index; | |
353 | u8 buf[5]; | |
354 | int ret; | |
355 | ||
356 | ret = i2c_smbus_read_block_data(data->client, ADM1266_BLACKBOX_INFO, buf); | |
357 | if (ret < 0) | |
358 | return ret; | |
359 | ||
360 | if (ret != 4) | |
361 | return -EIO; | |
362 | ||
363 | record_count = buf[3]; | |
364 | ||
365 | for (index = 0; index < record_count; index++) { | |
366 | ret = adm1266_pmbus_block_xfer(data, ADM1266_READ_BLACKBOX, 1, &index, read_buff); | |
367 | if (ret < 0) | |
368 | return ret; | |
369 | ||
370 | if (ret != ADM1266_BLACKBOX_SIZE) | |
371 | return -EIO; | |
372 | ||
373 | read_buff += ADM1266_BLACKBOX_SIZE; | |
374 | } | |
375 | ||
376 | return 0; | |
377 | } | |
378 | ||
379 | static int adm1266_nvmem_read(void *priv, unsigned int offset, void *val, size_t bytes) | |
380 | { | |
381 | struct adm1266_data *data = priv; | |
382 | int ret; | |
383 | ||
384 | if (offset + bytes > data->nvmem_config.size) | |
385 | return -EINVAL; | |
386 | ||
387 | if (offset == 0) { | |
388 | memset(data->dev_mem, 0, data->nvmem_config.size); | |
389 | ||
390 | ret = adm1266_nvmem_read_blackbox(data, data->dev_mem); | |
391 | if (ret) { | |
392 | dev_err(&data->client->dev, "Could not read blackbox!"); | |
393 | return ret; | |
394 | } | |
395 | } | |
396 | ||
397 | memcpy(val, data->dev_mem + offset, bytes); | |
398 | ||
399 | return 0; | |
400 | } | |
401 | ||
402 | static int adm1266_config_nvmem(struct adm1266_data *data) | |
403 | { | |
404 | data->nvmem_config.name = dev_name(&data->client->dev); | |
405 | data->nvmem_config.dev = &data->client->dev; | |
406 | data->nvmem_config.root_only = true; | |
407 | data->nvmem_config.read_only = true; | |
408 | data->nvmem_config.owner = THIS_MODULE; | |
409 | data->nvmem_config.reg_read = adm1266_nvmem_read; | |
410 | data->nvmem_config.cells = adm1266_nvmem_cells; | |
411 | data->nvmem_config.ncells = ARRAY_SIZE(adm1266_nvmem_cells); | |
412 | data->nvmem_config.priv = data; | |
413 | data->nvmem_config.stride = 1; | |
414 | data->nvmem_config.word_size = 1; | |
415 | data->nvmem_config.size = adm1266_nvmem_cells[0].bytes; | |
416 | ||
417 | data->dev_mem = devm_kzalloc(&data->client->dev, data->nvmem_config.size, GFP_KERNEL); | |
418 | if (!data->dev_mem) | |
419 | return -ENOMEM; | |
420 | ||
421 | data->nvmem = devm_nvmem_register(&data->client->dev, &data->nvmem_config); | |
422 | if (IS_ERR(data->nvmem)) { | |
423 | dev_err(&data->client->dev, "Could not register nvmem!"); | |
424 | return PTR_ERR(data->nvmem); | |
425 | } | |
426 | ||
427 | return 0; | |
428 | } | |
429 | ||
430 | static int adm1266_set_rtc(struct adm1266_data *data) | |
431 | { | |
432 | time64_t kt; | |
433 | char write_buf[6]; | |
434 | int i; | |
435 | ||
436 | kt = ktime_get_seconds(); | |
437 | ||
438 | memset(write_buf, 0, sizeof(write_buf)); | |
439 | ||
440 | for (i = 0; i < 4; i++) | |
441 | write_buf[2 + i] = (kt >> (i * 8)) & 0xFF; | |
442 | ||
443 | return i2c_smbus_write_block_data(data->client, ADM1266_SET_RTC, sizeof(write_buf), | |
444 | write_buf); | |
445 | } | |
446 | ||
9514a228 AT |
447 | static int adm1266_probe(struct i2c_client *client) |
448 | { | |
449 | struct adm1266_data *data; | |
d98dfad3 | 450 | int ret; |
9514a228 AT |
451 | int i; |
452 | ||
453 | data = devm_kzalloc(&client->dev, sizeof(struct adm1266_data), GFP_KERNEL); | |
454 | if (!data) | |
455 | return -ENOMEM; | |
456 | ||
457 | data->client = client; | |
458 | data->info.pages = 17; | |
459 | data->info.format[PSC_VOLTAGE_OUT] = linear; | |
460 | for (i = 0; i < data->info.pages; i++) | |
461 | data->info.func[i] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT; | |
462 | ||
407dc802 AT |
463 | crc8_populate_msb(pmbus_crc_table, 0x7); |
464 | mutex_init(&data->buf_mutex); | |
465 | ||
d98dfad3 AT |
466 | ret = adm1266_config_gpio(data); |
467 | if (ret < 0) | |
468 | return ret; | |
469 | ||
15609d18 AT |
470 | ret = adm1266_set_rtc(data); |
471 | if (ret < 0) | |
472 | return ret; | |
473 | ||
474 | ret = adm1266_config_nvmem(data); | |
475 | if (ret < 0) | |
476 | return ret; | |
477 | ||
ed1ff457 AT |
478 | ret = pmbus_do_probe(client, &data->info); |
479 | if (ret) | |
480 | return ret; | |
481 | ||
482 | adm1266_init_debugfs(data); | |
483 | ||
484 | return 0; | |
9514a228 AT |
485 | } |
486 | ||
487 | static const struct of_device_id adm1266_of_match[] = { | |
488 | { .compatible = "adi,adm1266" }, | |
489 | { } | |
490 | }; | |
491 | MODULE_DEVICE_TABLE(of, adm1266_of_match); | |
492 | ||
493 | static const struct i2c_device_id adm1266_id[] = { | |
494 | { "adm1266", 0 }, | |
495 | { } | |
496 | }; | |
497 | MODULE_DEVICE_TABLE(i2c, adm1266_id); | |
498 | ||
499 | static struct i2c_driver adm1266_driver = { | |
500 | .driver = { | |
501 | .name = "adm1266", | |
502 | .of_match_table = adm1266_of_match, | |
503 | }, | |
504 | .probe_new = adm1266_probe, | |
9514a228 AT |
505 | .id_table = adm1266_id, |
506 | }; | |
507 | ||
508 | module_i2c_driver(adm1266_driver); | |
509 | ||
510 | MODULE_AUTHOR("Alexandru Tachici <alexandru.tachici@analog.com>"); | |
511 | MODULE_DESCRIPTION("PMBus driver for Analog Devices ADM1266"); | |
512 | MODULE_LICENSE("GPL v2"); | |
b94ca77e | 513 | MODULE_IMPORT_NS(PMBUS); |