1 /*
2  * Copyright 2023 Grinn
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT maxim_max20335_charger
8 
9 #include <zephyr/device.h>
10 #include <zephyr/drivers/charger.h>
11 #include <zephyr/drivers/gpio.h>
12 #include <zephyr/drivers/i2c.h>
13 #include <zephyr/kernel.h>
14 #include <zephyr/sys/util.h>
15 #include <zephyr/sys/linear_range.h>
16 
17 #include "zephyr/logging/log.h"
18 LOG_MODULE_REGISTER(max20335_charger);
19 
20 #define MAX20335_REG_STATUSA 0x02
21 #define MAX20335_REG_STATUSB 0x03
22 #define MAX20335_REG_INTA 0x05
23 #define MAX20335_REG_INTB 0x06
24 #define MAX20335_REG_INTMASKA 0x07
25 #define MAX20335_REG_INTMASKB 0x08
26 #define MAX20335_REG_ILIMCNTL 0x09
27 #define MAX20335_REG_CHGCNTLA 0x0A
28 #define MAX20335_REG_THRMCFG 0x18
29 
30 #define MAX20335_INTA_USBOK_MASK BIT(3)
31 #define MAX20335_INTA_CHGSTAT_MASK BIT(6)
32 #define MAX20335_ILIMCNTL_ILIMCNTL_MASK GENMASK(1, 0)
33 #define MAX20335_ILIMCNTL_SYSMIN_MASK GENMASK(7, 5)
34 #define MAX20335_STATUSA_CHGSTAT_MASK GENMASK(2, 0)
35 #define MAX20335_STATUSB_USBOK_MASK BIT(3)
36 #define MAX20335_CHGCNTLA_BATRECHG_MASK GENMASK(6, 5)
37 #define MAX20335_CHGCNTLA_BATREG_MASK GENMASK(4, 1)
38 #define MAX20335_CHGCNTLA_CHRGEN_MASK BIT(0)
39 #define MAX20335_CHGCNTLA_CHRGEN BIT(0)
40 #define MAX20335_THRMCFG_THERMEN_MASK GENMASK(1, 0)
41 
42 #define MAX20335_REG_CVC_VREG_MIN_UV 4050000U
43 #define MAX20335_REG_CVC_VREG_STEP_UV 50000U
44 #define MAX20335_REG_CVC_VREG_MIN_IDX 0x0U
45 #define MAX20335_REG_CVC_VREG_MAX_IDX 0x0BU
46 
47 #define MAX20335_ILIMCNTL_SYSMIN_MIN_UV 3600000U
48 #define MAX20335_ILIMCNTL_SYSMIN_STEP_UV 100000U
49 #define MAX20335_ILIMCNTL_SYSMIN_MIN_IDX 0x0U
50 #define MAX20335_ILIMCNTL_SYSMIN_MAX_IDX 0x7U
51 
52 #define INT_ENABLE_DELAY K_MSEC(500)
53 
54 enum charger_max20335_therm_mode {
55 	MAX20335_THERM_MODE_DISABLED,
56 	MAX20335_THERM_MODE_THERMISTOR,
57 	MAX20335_THERM_MODE_JEITA_1,
58 	MAX20335_THERM_MODE_JEITA_2,
59 	MAX20335_THERM_MODE_UNKNOWN,
60 };
61 
62 struct charger_max20335_config {
63 	struct i2c_dt_spec bus;
64 	struct gpio_dt_spec int_gpio;
65 	uint32_t max_vreg_uv;
66 	uint32_t max_ichgin_to_sys_ua;
67 	uint32_t min_vsys_uv;
68 	uint32_t recharge_threshold_uv;
69 	char *therm_mon_mode;
70 };
71 
72 struct charger_max20335_data {
73 	const struct device *dev;
74 	struct gpio_callback gpio_cb;
75 	struct k_work int_routine_work;
76 	struct k_work_delayable int_enable_work;
77 	enum charger_status charger_status;
78 	enum charger_online charger_online;
79 	charger_status_notifier_t charger_status_notifier;
80 	charger_online_notifier_t charger_online_notifier;
81 	bool charger_enabled;
82 	uint32_t charge_voltage_uv;
83 };
84 
85 static const struct linear_range charger_uv_range =
86 	LINEAR_RANGE_INIT(MAX20335_REG_CVC_VREG_MIN_UV,
87 			  MAX20335_REG_CVC_VREG_STEP_UV,
88 			  MAX20335_REG_CVC_VREG_MIN_IDX,
89 			  MAX20335_REG_CVC_VREG_MAX_IDX);
90 
91 static const struct linear_range system_uv_range =
92 	LINEAR_RANGE_INIT(MAX20335_ILIMCNTL_SYSMIN_MIN_UV,
93 			  MAX20335_ILIMCNTL_SYSMIN_STEP_UV,
94 			  MAX20335_ILIMCNTL_SYSMIN_MIN_IDX,
95 			  MAX20335_ILIMCNTL_SYSMIN_MAX_IDX);
96 
max20335_get_charger_status(const struct device * dev,enum charger_status * status)97 static int max20335_get_charger_status(const struct device *dev, enum charger_status *status)
98 {
99 	enum {
100 		MAX20335_CHARGER_OFF,
101 		MAX20335_CHARGING_SUSPENDED_DUE_TO_TEMPERATURE,
102 		MAX20335_PRE_CHARGE_IN_PROGRESS,
103 		MAX20335_FAST_CHARGE_IN_PROGRESS_1,
104 		MAX20335_FAST_CHARGE_IN_PROGRESS_2,
105 		MAX20335_MAINTAIN_CHARGE_IN_PROGRESS,
106 		MAX20335_MAIN_CHARGER_TIMER_DONE,
107 		MAX20335_CHARGER_FAULT_CONDITION,
108 	};
109 	const struct charger_max20335_config *const config = dev->config;
110 	uint8_t val;
111 	int ret;
112 
113 	ret = i2c_reg_read_byte_dt(&config->bus, MAX20335_REG_STATUSA, &val);
114 	if (ret) {
115 		return ret;
116 	}
117 
118 	val = FIELD_GET(MAX20335_STATUSA_CHGSTAT_MASK, val);
119 
120 	switch (val) {
121 	case MAX20335_CHARGER_OFF:
122 		__fallthrough;
123 	case MAX20335_CHARGING_SUSPENDED_DUE_TO_TEMPERATURE:
124 		__fallthrough;
125 	case MAX20335_CHARGER_FAULT_CONDITION:
126 		*status = CHARGER_STATUS_NOT_CHARGING;
127 		break;
128 	case MAX20335_PRE_CHARGE_IN_PROGRESS:
129 		__fallthrough;
130 	case MAX20335_FAST_CHARGE_IN_PROGRESS_1:
131 		__fallthrough;
132 	case MAX20335_FAST_CHARGE_IN_PROGRESS_2:
133 		__fallthrough;
134 	case MAX20335_MAINTAIN_CHARGE_IN_PROGRESS:
135 		*status = CHARGER_STATUS_CHARGING;
136 		break;
137 	case MAX20335_MAIN_CHARGER_TIMER_DONE:
138 		*status = CHARGER_STATUS_FULL;
139 		break;
140 	default:
141 		*status = CHARGER_STATUS_UNKNOWN;
142 		break;
143 	};
144 
145 	return 0;
146 }
147 
max20335_get_charger_online(const struct device * dev,enum charger_online * online)148 static int max20335_get_charger_online(const struct device *dev, enum charger_online *online)
149 {
150 	enum {
151 		MAX20335_CHGIN_IN_NOT_PRESENT_OR_INVALID,
152 		MAX20335_CHGIN_IN_PRESENT_AND_VALID,
153 	};
154 	const struct charger_max20335_config *const config = dev->config;
155 	uint8_t val;
156 	int ret;
157 
158 	ret = i2c_reg_read_byte_dt(&config->bus, MAX20335_REG_STATUSB, &val);
159 	if (ret) {
160 		return ret;
161 	}
162 
163 	val = FIELD_GET(MAX20335_STATUSB_USBOK_MASK, val);
164 
165 	switch (val) {
166 	case MAX20335_CHGIN_IN_PRESENT_AND_VALID:
167 		*online = CHARGER_ONLINE_FIXED;
168 		break;
169 	default:
170 		*online = CHARGER_ONLINE_OFFLINE;
171 		break;
172 	};
173 
174 	return 0;
175 }
176 
max20335_set_recharge_threshold(const struct device * dev,uint32_t voltage_uv)177 static int max20335_set_recharge_threshold(const struct device *dev, uint32_t voltage_uv)
178 {
179 	const struct charger_max20335_config *const config = dev->config;
180 	uint8_t val;
181 
182 	switch (voltage_uv) {
183 	case 70000:
184 		val = 0x00;
185 		break;
186 	case 120000:
187 		val = 0x01;
188 		break;
189 	case 170000:
190 		val = 0x02;
191 		break;
192 	case 220000:
193 		val = 0x03;
194 		break;
195 	default:
196 		return -ENOTSUP;
197 	};
198 
199 	val = FIELD_PREP(MAX20335_CHGCNTLA_BATRECHG_MASK, val);
200 
201 	return i2c_reg_update_byte_dt(&config->bus,
202 				      MAX20335_REG_CHGCNTLA,
203 				      MAX20335_CHGCNTLA_BATRECHG_MASK,
204 				      val);
205 }
206 
max20335_set_constant_charge_voltage(const struct device * dev,uint32_t voltage_uv)207 static int max20335_set_constant_charge_voltage(const struct device *dev,
208 						uint32_t voltage_uv)
209 {
210 	const struct charger_max20335_config *const config = dev->config;
211 	uint16_t idx;
212 	uint8_t val;
213 	int ret;
214 
215 	ret = linear_range_get_index(&charger_uv_range, voltage_uv, &idx);
216 	if (ret < 0) {
217 		return ret;
218 	}
219 
220 	val = FIELD_PREP(MAX20335_CHGCNTLA_BATREG_MASK, idx);
221 
222 	return i2c_reg_update_byte_dt(&config->bus,
223 				      MAX20335_REG_CHGCNTLA,
224 				      MAX20335_CHGCNTLA_BATREG_MASK,
225 				      val);
226 }
227 
max20335_set_chgin_to_sys_current_limit(const struct device * dev,uint32_t current_ua)228 static int max20335_set_chgin_to_sys_current_limit(const struct device *dev, uint32_t current_ua)
229 {
230 	const struct charger_max20335_config *const config = dev->config;
231 	uint8_t val;
232 
233 	switch (current_ua) {
234 	case 0:
235 		val = 0x00;
236 		break;
237 	case 100000:
238 		val = 0x01;
239 		break;
240 	case 500000:
241 		val = 0x02;
242 		break;
243 	case 1000000:
244 		val = 0x03;
245 		break;
246 	default:
247 		return -ENOTSUP;
248 	};
249 
250 	val = FIELD_PREP(MAX20335_ILIMCNTL_ILIMCNTL_MASK, val);
251 
252 	return i2c_reg_update_byte_dt(&config->bus,
253 				      MAX20335_REG_ILIMCNTL,
254 				      MAX20335_ILIMCNTL_ILIMCNTL_MASK,
255 				      val);
256 }
257 
max20335_set_sys_voltage_min_threshold(const struct device * dev,uint32_t voltage_uv)258 static int max20335_set_sys_voltage_min_threshold(const struct device *dev, uint32_t voltage_uv)
259 {
260 	const struct charger_max20335_config *const config = dev->config;
261 	uint16_t idx;
262 	uint8_t val;
263 	int ret;
264 
265 	ret = linear_range_get_index(&system_uv_range, voltage_uv, &idx);
266 	if (ret < 0) {
267 		return ret;
268 	}
269 
270 	val = FIELD_PREP(MAX20335_ILIMCNTL_SYSMIN_MASK, idx);
271 
272 	return i2c_reg_update_byte_dt(&config->bus,
273 				      MAX20335_REG_ILIMCNTL,
274 				      MAX20335_ILIMCNTL_SYSMIN_MASK,
275 				      val);
276 }
277 
max20335_set_thermistor_mode(const struct device * dev,enum charger_max20335_therm_mode mode)278 static int max20335_set_thermistor_mode(const struct device *dev,
279 					enum charger_max20335_therm_mode mode)
280 {
281 	const struct charger_max20335_config *const config = dev->config;
282 	uint8_t val;
283 
284 	switch (mode) {
285 	case MAX20335_THERM_MODE_DISABLED:
286 		val = 0x00;
287 		break;
288 	case MAX20335_THERM_MODE_THERMISTOR:
289 		val = 0x01;
290 		break;
291 	case MAX20335_THERM_MODE_JEITA_1:
292 		val = 0x02;
293 		break;
294 	case MAX20335_THERM_MODE_JEITA_2:
295 		val = 0x03;
296 		break;
297 	default:
298 		return -ENOTSUP;
299 	};
300 
301 	val = FIELD_PREP(MAX20335_THRMCFG_THERMEN_MASK, val);
302 
303 	return i2c_reg_update_byte_dt(&config->bus,
304 				      MAX20335_REG_THRMCFG,
305 				      MAX20335_THRMCFG_THERMEN_MASK,
306 				      val);
307 }
308 
max20335_set_enabled(const struct device * dev,bool enable)309 static int max20335_set_enabled(const struct device *dev, bool enable)
310 {
311 	struct charger_max20335_data *data = dev->data;
312 	const struct charger_max20335_config *const config = dev->config;
313 
314 	data->charger_enabled = enable;
315 
316 	return i2c_reg_update_byte_dt(&config->bus,
317 				      MAX20335_REG_CHGCNTLA,
318 				      MAX20335_CHGCNTLA_CHRGEN_MASK,
319 				      enable ? MAX20335_CHGCNTLA_CHRGEN : 0);
320 }
321 
max20335_get_interrupt_source(const struct device * dev,uint8_t * int_a,uint8_t * int_b)322 static int max20335_get_interrupt_source(const struct device *dev, uint8_t *int_a, uint8_t *int_b)
323 {
324 	const struct charger_max20335_config *config = dev->config;
325 	uint8_t dummy;
326 	uint8_t *int_src;
327 	int ret;
328 
329 	/* Both INT_A and INT_B registers need to be read to clear all int flags */
330 
331 	int_src = (int_a != NULL) ? int_a : &dummy;
332 	ret = i2c_reg_read_byte_dt(&config->bus, MAX20335_REG_INTA, int_src);
333 	if (ret < 0) {
334 		return ret;
335 	}
336 
337 	int_src = (int_b != NULL) ? int_b : &dummy;
338 
339 	return i2c_reg_read_byte_dt(&config->bus, MAX20335_REG_INTB, int_src);
340 }
341 
max20335_enable_interrupts(const struct device * dev)342 static int max20335_enable_interrupts(const struct device *dev)
343 {
344 	enum {MASKA_VAL_ENABLE = 0xFF};
345 	const struct charger_max20335_config *config = dev->config;
346 	int ret;
347 
348 	ret = max20335_get_interrupt_source(dev, NULL, NULL);
349 	if (ret < 0) {
350 		LOG_WRN("Failed to clear pending interrupts: %d", ret);
351 		return ret;
352 	}
353 
354 	ret = i2c_reg_write_byte_dt(&config->bus, MAX20335_REG_INTMASKA, MASKA_VAL_ENABLE);
355 	if (ret < 0) {
356 		return ret;
357 	}
358 
359 	return i2c_reg_write_byte_dt(&config->bus, MAX20335_REG_INTMASKB, 0);
360 }
361 
max20335_init_properties(const struct device * dev)362 static int max20335_init_properties(const struct device *dev)
363 {
364 	struct charger_max20335_data *data = dev->data;
365 	const struct charger_max20335_config *config = dev->config;
366 	int ret;
367 
368 	data->charge_voltage_uv = config->max_vreg_uv;
369 	data->charger_enabled = true;
370 
371 	ret = max20335_get_charger_status(dev, &data->charger_status);
372 	if (ret < 0) {
373 		LOG_ERR("Failed to read charger status: %d", ret);
374 		return ret;
375 	}
376 
377 	ret = max20335_get_charger_online(dev, &data->charger_online);
378 	if (ret < 0) {
379 		LOG_ERR("Failed to read charger online: %d", ret);
380 		return ret;
381 	}
382 
383 	return 0;
384 }
385 
max20335_string_to_therm_mode(const char * mode_string)386 enum charger_max20335_therm_mode max20335_string_to_therm_mode(const char *mode_string)
387 {
388 	static const char * const modes[] = {
389 		[MAX20335_THERM_MODE_DISABLED] = "disabled",
390 		[MAX20335_THERM_MODE_THERMISTOR] = "thermistor",
391 		[MAX20335_THERM_MODE_JEITA_1] = "JEITA-1",
392 		[MAX20335_THERM_MODE_JEITA_2] = "JEITA-2",
393 	};
394 	enum charger_max20335_therm_mode i;
395 
396 	for (i = MAX20335_THERM_MODE_DISABLED; i < ARRAY_SIZE(modes); i++) {
397 		if (strncmp(mode_string, modes[i], strlen(modes[i])) == 0) {
398 			return i;
399 		}
400 	}
401 
402 	return MAX20335_THERM_MODE_UNKNOWN;
403 }
404 
max20335_update_properties(const struct device * dev)405 static int max20335_update_properties(const struct device *dev)
406 {
407 	struct charger_max20335_data *data = dev->data;
408 	const struct charger_max20335_config *config = dev->config;
409 	enum charger_max20335_therm_mode therm_mode;
410 	int ret;
411 
412 	ret = max20335_set_chgin_to_sys_current_limit(dev, config->max_ichgin_to_sys_ua);
413 	if (ret < 0) {
414 		LOG_ERR("Failed to set chgin-to-sys current limit: %d", ret);
415 		return ret;
416 	}
417 
418 	ret = max20335_set_sys_voltage_min_threshold(dev, config->min_vsys_uv);
419 	if (ret < 0) {
420 		LOG_ERR("Failed to set minimum system voltage threshold: %d", ret);
421 		return ret;
422 	}
423 
424 	ret = max20335_set_recharge_threshold(dev, config->recharge_threshold_uv);
425 	if (ret < 0) {
426 		LOG_ERR("Failed to set recharge threshold: %d", ret);
427 		return ret;
428 	}
429 
430 	therm_mode = max20335_string_to_therm_mode(config->therm_mon_mode);
431 	ret = max20335_set_thermistor_mode(dev, therm_mode);
432 	if (ret < 0) {
433 		LOG_ERR("Failed to set thermistor mode: %d", ret);
434 		return ret;
435 	}
436 
437 	ret = max20335_set_constant_charge_voltage(dev, data->charge_voltage_uv);
438 	if (ret < 0) {
439 		LOG_ERR("Failed to set charge voltage: %d", ret);
440 		return ret;
441 	}
442 
443 	ret = max20335_set_enabled(dev, data->charger_enabled);
444 	if (ret < 0) {
445 		LOG_ERR("Failed to set enabled: %d", ret);
446 		return ret;
447 	}
448 
449 	return 0;
450 }
451 
max20335_get_prop(const struct device * dev,charger_prop_t prop,union charger_propval * val)452 static int max20335_get_prop(const struct device *dev, charger_prop_t prop,
453 			     union charger_propval *val)
454 {
455 	struct charger_max20335_data *data = dev->data;
456 
457 	switch (prop) {
458 	case CHARGER_PROP_ONLINE:
459 		val->online = data->charger_online;
460 		return 0;
461 	case CHARGER_PROP_STATUS:
462 		val->status = data->charger_status;
463 		return 0;
464 	case CHARGER_PROP_CONSTANT_CHARGE_VOLTAGE_UV:
465 		val->const_charge_voltage_uv = data->charge_voltage_uv;
466 		return 0;
467 	default:
468 		return -ENOTSUP;
469 	}
470 }
471 
max20335_set_prop(const struct device * dev,charger_prop_t prop,const union charger_propval * val)472 static int max20335_set_prop(const struct device *dev, charger_prop_t prop,
473 			     const union charger_propval *val)
474 {
475 	struct charger_max20335_data *data = dev->data;
476 	int ret;
477 
478 	switch (prop) {
479 	case CHARGER_PROP_CONSTANT_CHARGE_VOLTAGE_UV:
480 		ret =  max20335_set_constant_charge_voltage(dev, val->const_charge_voltage_uv);
481 		if (ret == 0) {
482 			data->charge_voltage_uv = val->const_charge_voltage_uv;
483 		}
484 
485 		return ret;
486 	case CHARGER_PROP_STATUS_NOTIFICATION:
487 		data->charger_status_notifier = val->status_notification;
488 		return 0;
489 	case CHARGER_PROP_ONLINE_NOTIFICATION:
490 		data->charger_online_notifier = val->online_notification;
491 		return 0;
492 	default:
493 		return -ENOTSUP;
494 	}
495 }
496 
max20335_enable_interrupt_pin(const struct device * dev,bool enabled)497 static int max20335_enable_interrupt_pin(const struct device *dev, bool enabled)
498 {
499 	const struct charger_max20335_config *const config = dev->config;
500 	gpio_flags_t flags;
501 	int ret;
502 
503 	flags = enabled ? GPIO_INT_LEVEL_ACTIVE : GPIO_INT_DISABLE;
504 
505 	ret = gpio_pin_interrupt_configure_dt(&config->int_gpio, flags);
506 	if (ret < 0) {
507 		LOG_ERR("Could not %s interrupt GPIO callback: %d", enabled ? "enable" : "disable",
508 			ret);
509 	}
510 
511 	return ret;
512 }
513 
max20335_gpio_callback(const struct device * dev,struct gpio_callback * cb,uint32_t pins)514 static void max20335_gpio_callback(const struct device *dev, struct gpio_callback *cb,
515 				   uint32_t pins)
516 {
517 	struct charger_max20335_data *data = CONTAINER_OF(cb, struct charger_max20335_data,
518 							  gpio_cb);
519 	int ret;
520 
521 	(void) max20335_enable_interrupt_pin(data->dev, false);
522 
523 	ret = k_work_submit(&data->int_routine_work);
524 	if (ret < 0) {
525 		LOG_WRN("Could not submit int work: %d", ret);
526 	}
527 }
528 
max20335_int_routine_work_handler(struct k_work * work)529 static void max20335_int_routine_work_handler(struct k_work *work)
530 {
531 	struct charger_max20335_data *data = CONTAINER_OF(work, struct charger_max20335_data,
532 							  int_routine_work);
533 	uint8_t int_src_a;
534 	int ret;
535 
536 	ret = max20335_get_interrupt_source(data->dev, &int_src_a, NULL);
537 	if (ret < 0) {
538 		LOG_WRN("Failed to read interrupt source");
539 		return;
540 	}
541 
542 	if ((int_src_a & MAX20335_INTA_CHGSTAT_MASK) != 0) {
543 		ret = max20335_get_charger_status(data->dev, &data->charger_status);
544 		if (ret < 0) {
545 			LOG_WRN("Failed to read charger status: %d", ret);
546 		} else {
547 			if (data->charger_status_notifier != NULL) {
548 				data->charger_status_notifier(data->charger_status);
549 			}
550 		}
551 	}
552 
553 	if ((int_src_a & MAX20335_INTA_USBOK_MASK) != 0) {
554 		ret = max20335_get_charger_online(data->dev, &data->charger_online);
555 		if (ret < 0) {
556 			LOG_WRN("Failed to read charger online %d", ret);
557 		} else {
558 			if (data->charger_online_notifier != NULL) {
559 				data->charger_online_notifier(data->charger_online);
560 			}
561 		}
562 
563 		if (data->charger_online != CHARGER_ONLINE_OFFLINE) {
564 			(void) max20335_update_properties(data->dev);
565 		}
566 	}
567 
568 	ret = k_work_reschedule(&data->int_enable_work, INT_ENABLE_DELAY);
569 	if (ret < 0) {
570 		LOG_WRN("Could not reschedule int_enable_work: %d", ret);
571 	}
572 }
573 
max20335_int_enable_work_handler(struct k_work * work)574 static void max20335_int_enable_work_handler(struct k_work *work)
575 {
576 	struct k_work_delayable *dwork = k_work_delayable_from_work(work);
577 	struct charger_max20335_data *data = CONTAINER_OF(dwork, struct charger_max20335_data,
578 							  int_enable_work);
579 
580 	(void) max20335_enable_interrupt_pin(data->dev, true);
581 }
582 
max20335_configure_interrupt_pin(const struct device * dev)583 static int max20335_configure_interrupt_pin(const struct device *dev)
584 {
585 	struct charger_max20335_data *data = dev->data;
586 	const struct charger_max20335_config *config = dev->config;
587 	int ret;
588 
589 	if (!gpio_is_ready_dt(&config->int_gpio)) {
590 		LOG_ERR("Interrupt GPIO device not ready");
591 		return -ENODEV;
592 	}
593 
594 	ret = gpio_pin_configure_dt(&config->int_gpio, GPIO_INPUT);
595 	if (ret < 0) {
596 		LOG_ERR("Could not configure interrupt GPIO");
597 		return ret;
598 	}
599 
600 	gpio_init_callback(&data->gpio_cb, max20335_gpio_callback, BIT(config->int_gpio.pin));
601 	ret = gpio_add_callback_dt(&config->int_gpio, &data->gpio_cb);
602 	if (ret < 0) {
603 		LOG_ERR("Could not add interrupt GPIO callback");
604 		return ret;
605 	}
606 
607 	return 0;
608 }
609 
max20335_init(const struct device * dev)610 static int max20335_init(const struct device *dev)
611 {
612 	struct charger_max20335_data *data = dev->data;
613 	const struct charger_max20335_config *config = dev->config;
614 	int ret;
615 
616 	if (!i2c_is_ready_dt(&config->bus)) {
617 		return -ENODEV;
618 	}
619 
620 	data->dev = dev;
621 
622 	ret = max20335_init_properties(dev);
623 	if (ret < 0) {
624 		return ret;
625 	}
626 
627 	k_work_init(&data->int_routine_work, max20335_int_routine_work_handler);
628 	k_work_init_delayable(&data->int_enable_work, max20335_int_enable_work_handler);
629 
630 	ret = max20335_configure_interrupt_pin(dev);
631 	if (ret < 0) {
632 		return ret;
633 	}
634 
635 	ret = max20335_enable_interrupt_pin(dev, true);
636 	if (ret < 0) {
637 		return ret;
638 	}
639 
640 	ret = max20335_enable_interrupts(dev);
641 	if (ret < 0) {
642 		LOG_ERR("Failed to enable interrupts");
643 		return ret;
644 	}
645 
646 	return 0;
647 }
648 
649 static const struct charger_driver_api max20335_driver_api = {
650 	.get_property = max20335_get_prop,
651 	.set_property = max20335_set_prop,
652 	.charge_enable = max20335_set_enabled,
653 };
654 
655 #define MAX20335_DEFINE(inst)									\
656 	static struct charger_max20335_data charger_max20335_data_##inst;			\
657 	static const struct charger_max20335_config charger_max20335_config_##inst = {		\
658 		.bus = I2C_DT_SPEC_GET(DT_INST_PARENT(inst)),					\
659 		.int_gpio = GPIO_DT_SPEC_INST_GET(inst, int_gpios),				\
660 		.max_vreg_uv = DT_INST_PROP(inst, constant_charge_voltage_max_microvolt),	\
661 		.max_ichgin_to_sys_ua = DT_INST_PROP(inst, chgin_to_sys_current_limit_microamp),\
662 		.min_vsys_uv = DT_INST_PROP(inst, system_voltage_min_threshold_microvolt),	\
663 		.recharge_threshold_uv = DT_INST_PROP(inst, re_charge_threshold_microvolt),	\
664 		.therm_mon_mode = DT_INST_PROP(inst, thermistor_monitoring_mode),		\
665 	};											\
666 												\
667 	DEVICE_DT_INST_DEFINE(inst, &max20335_init, NULL, &charger_max20335_data_##inst,	\
668 			      &charger_max20335_config_##inst,					\
669 			      POST_KERNEL, CONFIG_MFD_INIT_PRIORITY,				\
670 			      &max20335_driver_api);
671 
672 DT_INST_FOREACH_STATUS_OKAY(MAX20335_DEFINE)
673