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; | |
a5bb73b3 | 304 | data->gc.can_sleep = true; |
d98dfad3 AT |
305 | data->gc.base = -1; |
306 | data->gc.names = data->gpio_names; | |
307 | data->gc.ngpio = ARRAY_SIZE(data->gpio_names); | |
308 | data->gc.get = adm1266_gpio_get; | |
309 | data->gc.get_multiple = adm1266_gpio_get_multiple; | |
310 | data->gc.dbg_show = adm1266_gpio_dbg_show; | |
311 | ||
312 | ret = devm_gpiochip_add_data(&data->client->dev, &data->gc, data); | |
313 | if (ret) | |
314 | dev_err(&data->client->dev, "GPIO registering failed (%d)\n", ret); | |
315 | ||
316 | return ret; | |
317 | } | |
318 | ||
ed1ff457 AT |
319 | static int adm1266_state_read(struct seq_file *s, void *pdata) |
320 | { | |
321 | struct device *dev = s->private; | |
322 | struct i2c_client *client = to_i2c_client(dev); | |
323 | int ret; | |
324 | ||
325 | ret = i2c_smbus_read_word_data(client, ADM1266_READ_STATE); | |
326 | if (ret < 0) | |
327 | return ret; | |
328 | ||
329 | seq_printf(s, "%d\n", ret); | |
330 | ||
331 | return 0; | |
332 | } | |
333 | ||
334 | static void adm1266_init_debugfs(struct adm1266_data *data) | |
335 | { | |
336 | struct dentry *root; | |
337 | ||
338 | root = pmbus_get_debugfs_dir(data->client); | |
339 | if (!root) | |
340 | return; | |
341 | ||
342 | data->debugfs_dir = debugfs_create_dir(data->client->name, root); | |
ed1ff457 AT |
343 | |
344 | debugfs_create_devm_seqfile(&data->client->dev, "sequencer_state", data->debugfs_dir, | |
345 | adm1266_state_read); | |
346 | } | |
347 | ||
15609d18 AT |
348 | static int adm1266_nvmem_read_blackbox(struct adm1266_data *data, u8 *read_buff) |
349 | { | |
350 | int record_count; | |
351 | char index; | |
352 | u8 buf[5]; | |
353 | int ret; | |
354 | ||
355 | ret = i2c_smbus_read_block_data(data->client, ADM1266_BLACKBOX_INFO, buf); | |
356 | if (ret < 0) | |
357 | return ret; | |
358 | ||
359 | if (ret != 4) | |
360 | return -EIO; | |
361 | ||
362 | record_count = buf[3]; | |
363 | ||
364 | for (index = 0; index < record_count; index++) { | |
365 | ret = adm1266_pmbus_block_xfer(data, ADM1266_READ_BLACKBOX, 1, &index, read_buff); | |
366 | if (ret < 0) | |
367 | return ret; | |
368 | ||
369 | if (ret != ADM1266_BLACKBOX_SIZE) | |
370 | return -EIO; | |
371 | ||
372 | read_buff += ADM1266_BLACKBOX_SIZE; | |
373 | } | |
374 | ||
375 | return 0; | |
376 | } | |
377 | ||
378 | static int adm1266_nvmem_read(void *priv, unsigned int offset, void *val, size_t bytes) | |
379 | { | |
380 | struct adm1266_data *data = priv; | |
381 | int ret; | |
382 | ||
383 | if (offset + bytes > data->nvmem_config.size) | |
384 | return -EINVAL; | |
385 | ||
386 | if (offset == 0) { | |
387 | memset(data->dev_mem, 0, data->nvmem_config.size); | |
388 | ||
389 | ret = adm1266_nvmem_read_blackbox(data, data->dev_mem); | |
390 | if (ret) { | |
391 | dev_err(&data->client->dev, "Could not read blackbox!"); | |
392 | return ret; | |
393 | } | |
394 | } | |
395 | ||
396 | memcpy(val, data->dev_mem + offset, bytes); | |
397 | ||
398 | return 0; | |
399 | } | |
400 | ||
401 | static int adm1266_config_nvmem(struct adm1266_data *data) | |
402 | { | |
403 | data->nvmem_config.name = dev_name(&data->client->dev); | |
404 | data->nvmem_config.dev = &data->client->dev; | |
405 | data->nvmem_config.root_only = true; | |
406 | data->nvmem_config.read_only = true; | |
407 | data->nvmem_config.owner = THIS_MODULE; | |
408 | data->nvmem_config.reg_read = adm1266_nvmem_read; | |
409 | data->nvmem_config.cells = adm1266_nvmem_cells; | |
410 | data->nvmem_config.ncells = ARRAY_SIZE(adm1266_nvmem_cells); | |
411 | data->nvmem_config.priv = data; | |
412 | data->nvmem_config.stride = 1; | |
413 | data->nvmem_config.word_size = 1; | |
414 | data->nvmem_config.size = adm1266_nvmem_cells[0].bytes; | |
415 | ||
416 | data->dev_mem = devm_kzalloc(&data->client->dev, data->nvmem_config.size, GFP_KERNEL); | |
417 | if (!data->dev_mem) | |
418 | return -ENOMEM; | |
419 | ||
420 | data->nvmem = devm_nvmem_register(&data->client->dev, &data->nvmem_config); | |
421 | if (IS_ERR(data->nvmem)) { | |
422 | dev_err(&data->client->dev, "Could not register nvmem!"); | |
423 | return PTR_ERR(data->nvmem); | |
424 | } | |
425 | ||
426 | return 0; | |
427 | } | |
428 | ||
429 | static int adm1266_set_rtc(struct adm1266_data *data) | |
430 | { | |
431 | time64_t kt; | |
432 | char write_buf[6]; | |
433 | int i; | |
434 | ||
435 | kt = ktime_get_seconds(); | |
436 | ||
437 | memset(write_buf, 0, sizeof(write_buf)); | |
438 | ||
439 | for (i = 0; i < 4; i++) | |
440 | write_buf[2 + i] = (kt >> (i * 8)) & 0xFF; | |
441 | ||
442 | return i2c_smbus_write_block_data(data->client, ADM1266_SET_RTC, sizeof(write_buf), | |
443 | write_buf); | |
444 | } | |
445 | ||
9514a228 AT |
446 | static int adm1266_probe(struct i2c_client *client) |
447 | { | |
448 | struct adm1266_data *data; | |
d98dfad3 | 449 | int ret; |
9514a228 AT |
450 | int i; |
451 | ||
452 | data = devm_kzalloc(&client->dev, sizeof(struct adm1266_data), GFP_KERNEL); | |
453 | if (!data) | |
454 | return -ENOMEM; | |
455 | ||
456 | data->client = client; | |
457 | data->info.pages = 17; | |
458 | data->info.format[PSC_VOLTAGE_OUT] = linear; | |
459 | for (i = 0; i < data->info.pages; i++) | |
460 | data->info.func[i] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT; | |
461 | ||
407dc802 AT |
462 | crc8_populate_msb(pmbus_crc_table, 0x7); |
463 | mutex_init(&data->buf_mutex); | |
464 | ||
d98dfad3 AT |
465 | ret = adm1266_config_gpio(data); |
466 | if (ret < 0) | |
467 | return ret; | |
468 | ||
15609d18 AT |
469 | ret = adm1266_set_rtc(data); |
470 | if (ret < 0) | |
471 | return ret; | |
472 | ||
473 | ret = adm1266_config_nvmem(data); | |
474 | if (ret < 0) | |
475 | return ret; | |
476 | ||
ed1ff457 AT |
477 | ret = pmbus_do_probe(client, &data->info); |
478 | if (ret) | |
479 | return ret; | |
480 | ||
481 | adm1266_init_debugfs(data); | |
482 | ||
483 | return 0; | |
9514a228 AT |
484 | } |
485 | ||
486 | static const struct of_device_id adm1266_of_match[] = { | |
487 | { .compatible = "adi,adm1266" }, | |
488 | { } | |
489 | }; | |
490 | MODULE_DEVICE_TABLE(of, adm1266_of_match); | |
491 | ||
492 | static const struct i2c_device_id adm1266_id[] = { | |
d8a66f36 | 493 | { "adm1266" }, |
9514a228 AT |
494 | { } |
495 | }; | |
496 | MODULE_DEVICE_TABLE(i2c, adm1266_id); | |
497 | ||
498 | static struct i2c_driver adm1266_driver = { | |
499 | .driver = { | |
500 | .name = "adm1266", | |
501 | .of_match_table = adm1266_of_match, | |
502 | }, | |
1975d167 | 503 | .probe = adm1266_probe, |
9514a228 AT |
504 | .id_table = adm1266_id, |
505 | }; | |
506 | ||
507 | module_i2c_driver(adm1266_driver); | |
508 | ||
509 | MODULE_AUTHOR("Alexandru Tachici <alexandru.tachici@analog.com>"); | |
510 | MODULE_DESCRIPTION("PMBus driver for Analog Devices ADM1266"); | |
511 | MODULE_LICENSE("GPL v2"); | |
b94ca77e | 512 | MODULE_IMPORT_NS(PMBUS); |