1 /*
2  * Copyright (c) 2024 Analog Devices Inc.
3  * Copyright (c) 2024 Baylibre SAS
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #define DT_DRV_COMPAT adi_max22017
9 
10 #include <zephyr/device.h>
11 #include <zephyr/drivers/gpio.h>
12 #include <zephyr/drivers/gpio/gpio_utils.h>
13 #include <zephyr/drivers/spi.h>
14 #include <zephyr/irq.h>
15 #include <zephyr/kernel.h>
16 #include <zephyr/logging/log.h>
17 #include <zephyr/sys/byteorder.h>
18 #include <zephyr/sys/crc.h>
19 
20 LOG_MODULE_REGISTER(mfd_max22017, CONFIG_MFD_LOG_LEVEL);
21 
22 #include <zephyr/drivers/mfd/max22017.h>
23 
24 struct max22017_config {
25 	struct spi_dt_spec spi;
26 	const struct gpio_dt_spec gpio_reset;
27 	const struct gpio_dt_spec gpio_int;
28 	bool crc_mode;
29 };
30 
max22017_reg_read(const struct device * dev,uint8_t addr,uint16_t * value)31 int max22017_reg_read(const struct device *dev, uint8_t addr, uint16_t *value)
32 {
33 	int ret;
34 	const struct max22017_config *config = dev->config;
35 	const struct max22017_data *data = dev->data;
36 	uint8_t rxbuffer[4] = {0};
37 	size_t recv_len = 3;
38 
39 	*value = 0;
40 	addr = FIELD_PREP(MAX22017_SPI_TRANS_ADDR, addr) | FIELD_PREP(MAX22017_SPI_TRANS_DIR, 1);
41 
42 	if (data->crc_enabled) {
43 		recv_len += 1;
44 	}
45 
46 	const struct spi_buf txb[] = {
47 		{
48 			.buf = &addr,
49 			.len = 1,
50 		},
51 	};
52 	const struct spi_buf rxb[] = {
53 		{
54 			.buf = rxbuffer,
55 			.len = recv_len,
56 		},
57 	};
58 
59 	struct spi_buf_set tx = {
60 		.buffers = txb,
61 		.count = ARRAY_SIZE(txb),
62 	};
63 
64 	struct spi_buf_set rx = {
65 		.buffers = rxb,
66 		.count = ARRAY_SIZE(rxb),
67 	};
68 
69 	ret = spi_transceive_dt(&config->spi, &tx, &rx);
70 
71 	if (ret) {
72 		return ret;
73 	}
74 
75 	if (!data->crc_enabled) {
76 		goto out_skip_crc;
77 	}
78 
79 	uint8_t crc_in[] = {addr, rxbuffer[1], rxbuffer[2]};
80 
81 	ret = crc8(crc_in, 3, MAX22017_CRC_POLY, 0, true);
82 
83 	if (ret != rxbuffer[3]) {
84 		LOG_ERR("Reg read: CRC Mismatch calculated / read: %x / %x", ret, rxbuffer[3]);
85 		return -EINVAL;
86 	}
87 
88 out_skip_crc:
89 	*value = rxbuffer[1] | rxbuffer[2] << 8;
90 	*value = sys_be16_to_cpu(*value);
91 
92 	return 0;
93 }
94 
max22017_reg_write(const struct device * dev,uint8_t addr,uint16_t value)95 int max22017_reg_write(const struct device *dev, uint8_t addr, uint16_t value)
96 {
97 	uint8_t crc;
98 	size_t crc_len = 0;
99 	const struct max22017_config *config = dev->config;
100 	const struct max22017_data *data = dev->data;
101 
102 	addr = FIELD_PREP(MAX22017_SPI_TRANS_ADDR, addr) | FIELD_PREP(MAX22017_SPI_TRANS_DIR, 0);
103 	value = sys_cpu_to_be16(value);
104 
105 	if (data->crc_enabled) {
106 		uint8_t crc_in[] = {addr, ((uint8_t *)&value)[0], ((uint8_t *)&value)[1]};
107 
108 		crc_len = 1;
109 		crc = crc8(crc_in, 3, MAX22017_CRC_POLY, 0, true);
110 	}
111 
112 	const struct spi_buf buf[] = {
113 		{
114 			.buf = &addr,
115 			.len = 1,
116 		},
117 		{
118 			.buf = &value,
119 			.len = 2,
120 		},
121 		{
122 			.buf = &crc,
123 			.len = crc_len,
124 		},
125 	};
126 
127 	struct spi_buf_set tx = {
128 		.buffers = buf,
129 		.count = ARRAY_SIZE(buf),
130 	};
131 
132 	return spi_write_dt(&config->spi, &tx);
133 }
134 
max22017_reset(const struct device * dev)135 static int max22017_reset(const struct device *dev)
136 {
137 	int ret = 0;
138 	uint16_t ao_sta;
139 	const struct max22017_config *config = dev->config;
140 
141 	if (config->gpio_reset.port != NULL) {
142 		ret = gpio_pin_set_dt(&config->gpio_reset, 0);
143 		if (ret) {
144 			return ret;
145 		}
146 		k_sleep(K_MSEC(100));
147 		ret = gpio_pin_set_dt(&config->gpio_reset, 1);
148 		k_sleep(K_MSEC(500));
149 	} else {
150 		ret = max22017_reg_write(dev, MAX22017_GEN_RST_CTRL_OFF,
151 					 FIELD_PREP(MAX22017_GEN_RST_CTRL_GEN_RST, 1));
152 		if (ret) {
153 			return ret;
154 		}
155 		k_sleep(K_MSEC(100));
156 		ret = max22017_reg_write(dev, MAX22017_GEN_RST_CTRL_OFF,
157 					 FIELD_PREP(MAX22017_GEN_RST_CTRL_GEN_RST, 0));
158 		if (ret) {
159 			return ret;
160 		}
161 		k_sleep(K_MSEC(500));
162 		ret = max22017_reg_read(dev, MAX22017_AO_STA_OFF, &ao_sta);
163 		if (ret) {
164 			return ret;
165 		}
166 		if (FIELD_GET(MAX22017_AO_STA_BUSY_STA, ao_sta)) {
167 			ret = -EBUSY;
168 		}
169 	}
170 	return ret;
171 }
172 
max22017_isr(const struct device * dev,struct gpio_callback * gpio_cb,uint32_t pins)173 static void max22017_isr(const struct device *dev, struct gpio_callback *gpio_cb, uint32_t pins)
174 {
175 	struct max22017_data *data = CONTAINER_OF(gpio_cb, struct max22017_data, callback_int);
176 	int ret;
177 
178 	k_mutex_lock(&data->lock, K_FOREVER);
179 
180 	ret = k_work_submit(&data->int_work);
181 	if (ret < 0) {
182 		LOG_WRN("Could not submit int work: %d", ret);
183 	}
184 
185 	k_mutex_unlock(&data->lock);
186 }
187 
max22017_int_worker(struct k_work * work)188 static void max22017_int_worker(struct k_work *work)
189 {
190 	struct max22017_data *data = CONTAINER_OF(work, struct max22017_data, int_work);
191 	const struct device *dev = data->dev;
192 	int ret;
193 	uint16_t gen_int;
194 
195 	k_mutex_lock(&data->lock, K_FOREVER);
196 
197 	ret = max22017_reg_read(dev, MAX22017_GEN_INT_OFF, &gen_int);
198 	if (ret) {
199 		LOG_ERR("Unable to read GEN_INT register");
200 		goto fail;
201 	}
202 
203 	if (FIELD_GET(MAX22017_GEN_INT_FAIL_INT, gen_int)) {
204 		LOG_ERR("Boot failure");
205 	}
206 
207 	ret = FIELD_GET(MAX22017_GEN_INT_CONV_OVF_INT, gen_int);
208 	if (ret) {
209 		LOG_ERR("Conversion failure on channels: %s %s", (ret & BIT(0)) ? "0" : "",
210 			(ret & BIT(1)) ? "1" : "");
211 	}
212 
213 	ret = FIELD_GET(MAX22017_GEN_INT_OPENWIRE_DTCT_INT, gen_int);
214 	if (ret) {
215 		LOG_ERR("Openwire detected on channels: %s %s", (ret & BIT(0)) ? "0" : "",
216 			(ret & BIT(1)) ? "1" : "");
217 	}
218 
219 	if (FIELD_GET(MAX22017_GEN_INT_HVDD_INT, gen_int)) {
220 		LOG_ERR("HVDD/HVSS voltage difference below 1.5V");
221 	}
222 
223 	if (FIELD_GET(MAX22017_GEN_INT_TMOUT_INT, gen_int)) {
224 		LOG_ERR("SPI transaction timeout");
225 	}
226 
227 	ret = FIELD_GET(MAX22017_GEN_INT_THSHDN_INT, gen_int);
228 	if (ret) {
229 		LOG_ERR("Thermal shutdown AO channels: %s %s", (ret & BIT(0)) ? "0" : "",
230 			(ret & BIT(1)) ? "1" : "");
231 	}
232 
233 	ret = FIELD_GET(MAX22017_GEN_INT_THWRNG_INT, gen_int);
234 	if (ret) {
235 		LOG_ERR("Thermal warning AO channels: %s %s", (ret & BIT(0)) ? "0" : "",
236 			(ret & BIT(1)) ? "1" : "");
237 	}
238 
239 	ret = FIELD_GET(MAX22017_GEN_INT_OVC_INT, gen_int);
240 	if (ret) {
241 		LOG_ERR("Over current on channels: %s %s", (ret & BIT(0)) ? "0" : "",
242 			(ret & BIT(1)) ? "1" : "");
243 	}
244 
245 	if (FIELD_GET(MAX22017_GEN_INT_CRC_INT, gen_int)) {
246 		LOG_ERR("CRC Error");
247 	}
248 
249 	ret = FIELD_GET(MAX22017_GEN_INT_GPI_INT, gen_int);
250 	if (ret) {
251 		LOG_INF("GPI Interrupt: %d", ret);
252 #ifdef CONFIG_GPIO_MAX22017
253 		uint16_t gpi_sta, lsb;
254 
255 		ret = max22017_reg_read(dev, MAX22017_GEN_GPI_INT_STA_OFF, &gpi_sta);
256 		if (ret) {
257 			goto fail;
258 		}
259 
260 		/* Aggregate both positive and negative edge together */
261 		gpi_sta = FIELD_GET(MAX22017_GEN_GPI_INT_GPI_NEG_EDGE_INT, gpi_sta) |
262 			  FIELD_GET(MAX22017_GEN_GPI_INT_GPI_POS_EDGE_INT, gpi_sta);
263 		while (gpi_sta) {
264 			lsb = LSB_GET(gpi_sta);
265 			gpio_fire_callbacks(&data->callbacks_gpi, dev, lsb);
266 			gpi_sta &= ~lsb;
267 		}
268 #endif
269 	}
270 fail:
271 	k_mutex_unlock(&data->lock);
272 }
273 
max22017_init(const struct device * dev)274 static int max22017_init(const struct device *dev)
275 {
276 	const struct max22017_config *config = dev->config;
277 	struct max22017_data *data = dev->data;
278 	uint16_t version;
279 	int ret;
280 	uint16_t gen_cnfg = 0, gen_int_en = 0;
281 
282 	if (!spi_is_ready_dt(&config->spi)) {
283 		LOG_ERR("SPI spi %s not ready", config->spi.bus->name);
284 		return -ENODEV;
285 	}
286 
287 	if (config->gpio_reset.port != NULL) {
288 		ret = gpio_pin_configure_dt(&config->gpio_reset, GPIO_OUTPUT_ACTIVE);
289 		if (ret) {
290 			LOG_ERR("failed to initialize GPIO reset pin");
291 			return ret;
292 		}
293 	}
294 
295 	ret = max22017_reset(dev);
296 	if (ret) {
297 		LOG_ERR("failed to reset MAX22017");
298 		return ret;
299 	}
300 
301 	data->dev = dev;
302 	k_work_init(&data->int_work, max22017_int_worker);
303 	k_mutex_init(&data->lock);
304 
305 	if (config->gpio_int.port) {
306 		ret = gpio_pin_configure_dt(&config->gpio_int, GPIO_INPUT);
307 		if (ret) {
308 			LOG_ERR("failed to initialize GPIO interrupt pin");
309 			goto fail;
310 		}
311 
312 		ret = gpio_pin_interrupt_configure_dt(&config->gpio_int, GPIO_INT_EDGE_TO_ACTIVE);
313 		if (ret) {
314 			LOG_ERR("failed to configure interrupt pin");
315 			goto fail;
316 		}
317 
318 		gpio_init_callback(&data->callback_int, max22017_isr, BIT(config->gpio_int.pin));
319 		ret = gpio_add_callback(config->gpio_int.port, &data->callback_int);
320 		if (ret) {
321 			LOG_ERR("failed to add data ready callback");
322 			goto fail;
323 		}
324 	}
325 
326 	k_mutex_lock(&data->lock, K_FOREVER);
327 
328 	ret = max22017_reg_write(dev, MAX22017_AO_CNFG_OFF, 0);
329 	if (ret) {
330 		return ret;
331 	}
332 
333 	ret = max22017_reg_write(dev, MAX22017_AO_DATA_CHn_OFF(0), 0);
334 	if (ret) {
335 		goto fail;
336 	}
337 
338 	ret = max22017_reg_write(dev, MAX22017_AO_DATA_CHn_OFF(1), 0);
339 	if (ret) {
340 		goto fail;
341 	}
342 
343 	if (config->crc_mode) {
344 		gen_cnfg |= FIELD_PREP(MAX22017_GEN_CNFG_CRC_EN, 1);
345 		gen_int_en |= FIELD_PREP(MAX22017_GEN_INTEN_CRC_INTEN, 1);
346 	}
347 
348 	ret = max22017_reg_write(dev, MAX22017_GEN_INTEN_OFF, gen_int_en);
349 	if (ret) {
350 		goto fail;
351 	}
352 
353 	ret = max22017_reg_write(dev, MAX22017_GEN_CNFG_OFF, gen_cnfg);
354 	if (ret) {
355 		goto fail;
356 	}
357 
358 	if (config->crc_mode) {
359 		data->crc_enabled = true;
360 	}
361 
362 	ret = max22017_reg_read(dev, MAX22017_GEN_ID_OFF, &version);
363 	if (ret) {
364 		LOG_ERR("Unable to read MAX22017 version over SPI: %d", ret);
365 		goto fail;
366 	}
367 
368 	LOG_INF("MAX22017 version: 0x%lx 0x%lx", FIELD_GET(MAX22017_GEN_ID_PROD_ID, version),
369 		FIELD_GET(MAX22017_GEN_ID_REV_ID, version));
370 
371 fail:
372 	k_mutex_unlock(&data->lock);
373 	return ret;
374 }
375 
376 #define INST_DT_MAX22017(index)                                                                    \
377 	static const struct max22017_config max22017_config_##index = {                            \
378 		.spi = SPI_DT_SPEC_INST_GET(index, SPI_OP_MODE_MASTER | SPI_WORD_SET(8U), 0U),     \
379 		.gpio_int = GPIO_DT_SPEC_INST_GET_OR(index, int_gpios, {0}),                       \
380 		.gpio_reset = GPIO_DT_SPEC_INST_GET_OR(index, rst_gpios, {0}),                     \
381 		.crc_mode = DT_INST_PROP_OR(index, crc_mode, 0),                                   \
382 	};                                                                                         \
383                                                                                                    \
384 	static struct max22017_data max22017_data_##index;                                         \
385                                                                                                    \
386 	DEVICE_DT_INST_DEFINE(index, max22017_init, NULL, &max22017_data_##index,                  \
387 			      &max22017_config_##index, POST_KERNEL, CONFIG_MFD_INIT_PRIORITY,     \
388 			      NULL);
389 
390 DT_INST_FOREACH_STATUS_OKAY(INST_DT_MAX22017);
391