1 /*
2  * Copyright (c) 2015 Intel Corporation.
3  * Copyright (c) 2020 Norbit ODM AS
4  * Copyright 2022 NXP
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #define DT_DRV_COMPAT nxp_pca95xx
10 
11 /**
12  * @file Driver for PCA95XX and PCAL95XX I2C-based GPIO driver.
13  */
14 
15 #include <errno.h>
16 
17 #include <zephyr/kernel.h>
18 #include <zephyr/device.h>
19 #include <zephyr/init.h>
20 #include <zephyr/sys/byteorder.h>
21 #include <zephyr/sys/util.h>
22 #include <zephyr/drivers/gpio.h>
23 #include <zephyr/drivers/i2c.h>
24 
25 #include <zephyr/drivers/gpio/gpio_utils.h>
26 
27 #define LOG_LEVEL CONFIG_GPIO_LOG_LEVEL
28 #include <zephyr/logging/log.h>
29 LOG_MODULE_REGISTER(gpio_pca95xx);
30 
31 #if CONFIG_LITTLE_ENDIAN
32 #define LOW_BYTE_LE16_IDX	0
33 #define HIGH_BYTE_LE16_IDX	1
34 #else
35 #define LOW_BYTE_LE16_IDX	1
36 #define HIGH_BYTE_LE16_IDX	0
37 #endif
38 
39 /* Register definitions */
40 #define REG_INPUT_PORT0			0x00
41 #define REG_INPUT_PORT1			0x01
42 #define REG_OUTPUT_PORT0		0x02
43 #define REG_OUTPUT_PORT1		0x03
44 #define REG_POL_INV_PORT0		0x04
45 #define REG_POL_INV_PORT1		0x05
46 #define REG_CONF_PORT0			0x06
47 #define REG_CONF_PORT1			0x07
48 #define REG_OUT_DRV_STRENGTH_PORT0_L	0x40
49 #define REG_OUT_DRV_STRENGTH_PORT0_H	0x41
50 #define REG_OUT_DRV_STRENGTH_PORT1_L	0x42
51 #define REG_OUT_DRV_STRENGTH_PORT1_H	0x43
52 #define REG_INPUT_LATCH_PORT0		0x44
53 #define REG_INPUT_LATCH_PORT1		0x45
54 #define REG_PUD_EN_PORT0		0x46
55 #define REG_PUD_EN_PORT1		0x47
56 #define REG_PUD_SEL_PORT0		0x48
57 #define REG_PUD_SEL_PORT1		0x49
58 #define REG_INT_MASK_PORT0		0x4A
59 #define REG_INT_MASK_PORT1		0x4B
60 #define REG_INT_STATUS_PORT0		0x4C
61 #define REG_INT_STATUS_PORT1		0x4D
62 #define REG_OUTPUT_PORT_CONF		0x4F
63 
64 /* Driver flags */
65 #define PCA_HAS_PUD			BIT(0)
66 #define PCA_HAS_INTERRUPT		BIT(1)
67 #define PCA_HAS_INTERRUPT_MASK_REG	BIT(2)
68 
69 /** Configuration data */
70 struct gpio_pca95xx_config {
71 	/* gpio_driver_config needs to be first */
72 	struct gpio_driver_config common;
73 	struct i2c_dt_spec bus;
74 	uint8_t capabilities;
75 #ifdef CONFIG_GPIO_PCA95XX_INTERRUPT
76 	struct gpio_dt_spec int_gpio;
77 #endif
78 };
79 
80 /** Runtime driver data */
81 struct gpio_pca95xx_drv_data {
82 	/* gpio_driver_data needs to be first */
83 	struct gpio_driver_data common;
84 
85 	struct {
86 		uint16_t input;
87 		uint16_t output;
88 		uint16_t dir;
89 		uint16_t pud_en;
90 		uint16_t pud_sel;
91 		uint16_t int_mask;
92 		uint16_t input_latch;
93 	} reg_cache;
94 
95 	struct k_sem lock;
96 
97 #ifdef CONFIG_GPIO_PCA95XX_INTERRUPT
98 	/* Self-reference to the driver instance */
99 	const struct device *instance;
100 
101 	/* port ISR callback routine address */
102 	sys_slist_t callbacks;
103 
104 	/* interrupt triggering pin masks */
105 	struct {
106 		uint16_t edge_rising;
107 		uint16_t edge_falling;
108 		uint16_t level_high;
109 		uint16_t level_low;
110 	} interrupts;
111 
112 	struct gpio_callback gpio_callback;
113 
114 	struct k_work interrupt_worker;
115 
116 	bool interrupt_active;
117 #endif
118 };
119 
read_port_reg(const struct device * dev,uint8_t reg,uint8_t pin,uint16_t * cache,uint16_t * buf)120 static int read_port_reg(const struct device *dev, uint8_t reg, uint8_t pin,
121 			 uint16_t *cache, uint16_t *buf)
122 {
123 	const struct gpio_pca95xx_config * const config = dev->config;
124 	uint8_t b_buf;
125 	int ret;
126 
127 	if (pin >= 8)
128 		reg++;
129 
130 	ret = i2c_reg_read_byte_dt(&config->bus, reg, &b_buf);
131 	if (ret != 0) {
132 		LOG_ERR("PCA95XX[0x%X]: error reading register 0x%X (%d)",
133 			config->bus.addr, reg, ret);
134 		return ret;
135 	}
136 
137 	if (pin < 8) {
138 		((uint8_t *)cache)[LOW_BYTE_LE16_IDX] = b_buf;
139 	} else {
140 		((uint8_t *)cache)[HIGH_BYTE_LE16_IDX] = b_buf;
141 	}
142 
143 	*buf = *cache;
144 
145 	LOG_DBG("PCA95XX[0x%X]: Read: REG[0x%X] = 0x%X",
146 		config->bus.addr, reg, b_buf);
147 
148 	return 0;
149 }
150 
151 /**
152  * @brief Read both port 0 and port 1 registers of certain register function.
153  *
154  * Given the register in reg, read the pair of port 0 and port 1.
155  *
156  * @param dev Device struct of the PCA95XX.
157  * @param reg Register to read (the PORT0 of the pair of registers).
158  * @param cache Pointer to the cache to be updated after successful read.
159  * @param buf Buffer to read data into.
160  *
161  * @return 0 if successful, failed otherwise.
162  */
read_port_regs(const struct device * dev,uint8_t reg,uint16_t * cache,uint16_t * buf)163 static int read_port_regs(const struct device *dev, uint8_t reg,
164 			  uint16_t *cache, uint16_t *buf)
165 {
166 	const struct gpio_pca95xx_config * const config = dev->config;
167 	uint16_t port_data, value;
168 	int ret;
169 
170 	ret = i2c_burst_read_dt(&config->bus, reg, (uint8_t *)&port_data,
171 				sizeof(port_data));
172 	if (ret != 0) {
173 		LOG_ERR("PCA95XX[0x%X]: error reading register 0x%X (%d)",
174 			config->bus.addr, reg, ret);
175 		return ret;
176 	}
177 
178 	value = sys_le16_to_cpu(port_data);
179 	*cache = value;
180 	*buf = value;
181 
182 	LOG_DBG("PCA95XX[0x%X]: Read: REG[0x%X] = 0x%X, REG[0x%X] = 0x%X",
183 		config->bus.addr, reg, (*buf & 0xFF), (reg + 1), (*buf >> 8));
184 
185 	return 0;
186 }
187 
188 
write_port_reg(const struct device * dev,uint8_t reg,uint8_t pin,uint16_t * cache,uint16_t value)189 static int write_port_reg(const struct device *dev, uint8_t reg, uint8_t pin,
190 			  uint16_t *cache, uint16_t value)
191 {
192 	const struct gpio_pca95xx_config * const config = dev->config;
193 	uint8_t buf[2];
194 	int ret;
195 
196 	if (pin < 8) {
197 		buf[1] = value;
198 	} else {
199 		buf[1] = value >> 8;
200 		reg++;
201 	}
202 	buf[0] = reg;
203 
204 	LOG_DBG("PCA95XX[0x%X]: Write: REG[0x%X] = 0x%X", config->bus.addr,
205 			reg, buf[1]);
206 
207 	ret = i2c_write_dt(&config->bus, buf, sizeof(buf));
208 	if (ret == 0) {
209 		*cache = value;
210 	} else {
211 		LOG_ERR("PCA95XX[0x%X]: error writing to register 0x%X "
212 			"(%d)", config->bus.addr, reg, ret);
213 	}
214 
215 	return ret;
216 }
217 
218 /**
219  * @brief Write both port 0 and port 1 registers of certain register function.
220  *
221  * Given the register in reg, write the pair of port 0 and port 1.
222  *
223  * @param dev Device struct of the PCA95XX.
224  * @param reg Register to write into (the PORT0 of the pair of registers).
225  * @param cache Pointer to the cache to be updated after successful write.
226  * @param value New value to set.
227  *
228  * @return 0 if successful, failed otherwise.
229  */
write_port_regs(const struct device * dev,uint8_t reg,uint16_t * cache,uint16_t value)230 static int write_port_regs(const struct device *dev, uint8_t reg,
231 			   uint16_t *cache, uint16_t value)
232 {
233 	const struct gpio_pca95xx_config * const config = dev->config;
234 	uint8_t buf[3];
235 	int ret;
236 
237 	LOG_DBG("PCA95XX[0x%X]: Write: REG[0x%X] = 0x%X, REG[0x%X] = "
238 		"0x%X", config->bus.addr, reg, (value & 0xFF),
239 		(reg + 1), (value >> 8));
240 
241 	buf[0] = reg;
242 	sys_put_le16(value, &buf[1]);
243 
244 	ret = i2c_write_dt(&config->bus, buf, sizeof(buf));
245 	if (ret == 0) {
246 		*cache = value;
247 	} else {
248 		LOG_ERR("PCA95XX[0x%X]: error writing to register 0x%X "
249 			"(%d)", config->bus.addr, reg, ret);
250 	}
251 
252 	return ret;
253 }
254 
update_input_reg(const struct device * dev,uint8_t pin,uint16_t * buf)255 static inline int update_input_reg(const struct device *dev, uint8_t pin,
256 				   uint16_t *buf)
257 {
258 	struct gpio_pca95xx_drv_data * const drv_data =
259 		(struct gpio_pca95xx_drv_data * const)dev->data;
260 
261 	return read_port_reg(dev, REG_INPUT_PORT0, pin,
262 			     &drv_data->reg_cache.input, buf);
263 }
264 
update_input_regs(const struct device * dev,uint16_t * buf)265 static inline int update_input_regs(const struct device *dev, uint16_t *buf)
266 {
267 	struct gpio_pca95xx_drv_data * const drv_data =
268 		(struct gpio_pca95xx_drv_data * const)dev->data;
269 
270 	return read_port_regs(dev, REG_INPUT_PORT0,
271 			      &drv_data->reg_cache.input, buf);
272 }
273 
update_output_reg(const struct device * dev,uint8_t pin,uint16_t value)274 static inline int update_output_reg(const struct device *dev, uint8_t pin,
275 				    uint16_t value)
276 {
277 	struct gpio_pca95xx_drv_data * const drv_data =
278 		(struct gpio_pca95xx_drv_data * const)dev->data;
279 
280 	return write_port_reg(dev, REG_OUTPUT_PORT0, pin,
281 			      &drv_data->reg_cache.output, value);
282 }
283 
update_output_regs(const struct device * dev,uint16_t value)284 static inline int update_output_regs(const struct device *dev, uint16_t value)
285 {
286 	struct gpio_pca95xx_drv_data * const drv_data =
287 		(struct gpio_pca95xx_drv_data * const)dev->data;
288 
289 	return write_port_regs(dev, REG_OUTPUT_PORT0,
290 			       &drv_data->reg_cache.output, value);
291 }
292 
update_direction_reg(const struct device * dev,uint8_t pin,uint16_t value)293 static inline int update_direction_reg(const struct device *dev, uint8_t pin,
294 					uint16_t value)
295 {
296 	struct gpio_pca95xx_drv_data * const drv_data =
297 		(struct gpio_pca95xx_drv_data * const)dev->data;
298 
299 	return write_port_reg(dev, REG_CONF_PORT0, pin,
300 			      &drv_data->reg_cache.dir, value);
301 }
302 
update_pul_sel_reg(const struct device * dev,uint8_t pin,uint16_t value)303 static inline int update_pul_sel_reg(const struct device *dev, uint8_t pin,
304 					uint16_t value)
305 {
306 	struct gpio_pca95xx_drv_data * const drv_data =
307 		(struct gpio_pca95xx_drv_data * const)dev->data;
308 
309 	return write_port_reg(dev, REG_PUD_SEL_PORT0, pin,
310 			      &drv_data->reg_cache.pud_sel, value);
311 }
312 
update_pul_en_reg(const struct device * dev,uint8_t pin,uint8_t value)313 static inline int update_pul_en_reg(const struct device *dev, uint8_t pin,
314 					uint8_t value)
315 {
316 	struct gpio_pca95xx_drv_data * const drv_data =
317 		(struct gpio_pca95xx_drv_data * const)dev->data;
318 
319 	return write_port_reg(dev, REG_PUD_EN_PORT0, pin,
320 			      &drv_data->reg_cache.pud_en, value);
321 }
322 
323 #ifdef CONFIG_GPIO_PCA95XX_INTERRUPT
update_int_mask_reg(const struct device * dev,uint8_t pin,uint16_t value)324 static inline int update_int_mask_reg(const struct device *dev, uint8_t pin,
325 					uint16_t value)
326 {
327 	struct gpio_pca95xx_drv_data * const drv_data =
328 		(struct gpio_pca95xx_drv_data * const)dev->data;
329 
330 	/* If the interrupt mask is present, so is the input latch */
331 	write_port_reg(dev, REG_INPUT_LATCH_PORT0, pin, &drv_data->reg_cache.input_latch, ~value);
332 
333 	return write_port_reg(dev, REG_INT_MASK_PORT0, pin,
334 			      &drv_data->reg_cache.int_mask, value);
335 }
336 #endif /* CONFIG_GPIO_PCA95XX_INTERRUPT */
337 
338 /**
339  * @brief Setup the pin direction (input or output)
340  *
341  * @param dev Device struct of the PCA95XX
342  * @param pin The pin number
343  * @param flags Flags of pin or port
344  *
345  * @return 0 if successful, failed otherwise
346  */
setup_pin_dir(const struct device * dev,uint32_t pin,int flags)347 static int setup_pin_dir(const struct device *dev, uint32_t pin, int flags)
348 {
349 	struct gpio_pca95xx_drv_data * const drv_data =
350 		(struct gpio_pca95xx_drv_data * const)dev->data;
351 	uint16_t reg_dir = drv_data->reg_cache.dir;
352 	uint16_t reg_out = drv_data->reg_cache.output;
353 	int ret;
354 
355 	/* For each pin, 0 == output, 1 == input */
356 	if ((flags & GPIO_OUTPUT) != 0U) {
357 		if ((flags & GPIO_OUTPUT_INIT_HIGH) != 0U) {
358 			reg_out |= BIT(pin);
359 		} else if ((flags & GPIO_OUTPUT_INIT_LOW) != 0U) {
360 			reg_out &= ~BIT(pin);
361 		}
362 		ret = update_output_reg(dev, pin, reg_out);
363 		if (ret != 0) {
364 			return ret;
365 		}
366 		reg_dir &= ~BIT(pin);
367 	} else {
368 		reg_dir |= BIT(pin);
369 	}
370 
371 	ret = update_direction_reg(dev, pin, reg_dir);
372 
373 	return ret;
374 }
375 
376 /**
377  * @brief Setup the pin pull up/pull down status
378  *
379  * @param dev Device struct of the PCA95XX
380  * @param pin The pin number
381  * @param flags Flags of pin or port
382  *
383  * @return 0 if successful, failed otherwise
384  */
setup_pin_pullupdown(const struct device * dev,uint32_t pin,int flags)385 static int setup_pin_pullupdown(const struct device *dev, uint32_t pin,
386 				int flags)
387 {
388 	const struct gpio_pca95xx_config * const config = dev->config;
389 	struct gpio_pca95xx_drv_data * const drv_data =
390 		(struct gpio_pca95xx_drv_data * const)dev->data;
391 	uint16_t reg_pud;
392 	int ret;
393 
394 	if ((config->capabilities & PCA_HAS_PUD) == 0) {
395 		/* Chip does not support pull up/pull down */
396 		if ((flags & (GPIO_PULL_UP | GPIO_PULL_DOWN)) != 0U) {
397 			return -ENOTSUP;
398 		}
399 
400 		/* If both GPIO_PULL_UP and GPIO_PULL_DOWN are not set,
401 		 * we should disable them in hardware. But need to skip
402 		 * if the chip does not support pull up/pull down.
403 		 */
404 		return 0;
405 	}
406 
407 	/* If disabling pull up/down, there is no need to set the selection
408 	 * register. Just go straight to disabling.
409 	 */
410 	if ((flags & (GPIO_PULL_UP | GPIO_PULL_DOWN)) != 0U) {
411 		/* Setup pin pull up or pull down */
412 		reg_pud = drv_data->reg_cache.pud_sel;
413 
414 		/* pull down == 0, pull up == 1 */
415 		WRITE_BIT(reg_pud, pin, (flags & GPIO_PULL_UP) != 0U);
416 
417 		ret = update_pul_sel_reg(dev, pin, reg_pud);
418 		if (ret) {
419 			return ret;
420 		}
421 	}
422 
423 	/* enable/disable pull up/down */
424 	reg_pud = drv_data->reg_cache.pud_en;
425 
426 	WRITE_BIT(reg_pud, pin,
427 		  (flags & (GPIO_PULL_UP | GPIO_PULL_DOWN)) != 0U);
428 
429 	ret = update_pul_en_reg(dev, pin, reg_pud);
430 
431 	return ret;
432 }
433 
434 /**
435  * @brief Configure pin or port
436  *
437  * @param dev Device struct of the PCA95XX
438  * @param pin The pin number
439  * @param flags Flags of pin or port
440  *
441  * @return 0 if successful, failed otherwise
442  */
gpio_pca95xx_config(const struct device * dev,gpio_pin_t pin,gpio_flags_t flags)443 static int gpio_pca95xx_config(const struct device *dev,
444 			       gpio_pin_t pin, gpio_flags_t flags)
445 {
446 	int ret;
447 	struct gpio_pca95xx_drv_data * const drv_data =
448 		(struct gpio_pca95xx_drv_data * const)dev->data;
449 
450 #if (CONFIG_GPIO_LOG_LEVEL >= LOG_LEVEL_DEBUG)
451 	const struct gpio_pca95xx_config * const config = dev->config;
452 #endif
453 
454 	/* Does not support disconnected pin */
455 	if ((flags & (GPIO_INPUT | GPIO_OUTPUT)) == GPIO_DISCONNECTED) {
456 		return -ENOTSUP;
457 	}
458 
459 	/* Open-drain support is per port, not per pin.
460 	 * So can't really support the API as-is.
461 	 */
462 	if ((flags & GPIO_SINGLE_ENDED) != 0U) {
463 		return -ENOTSUP;
464 	}
465 
466 	/* Can't do I2C bus operations from an ISR */
467 	if (k_is_in_isr()) {
468 		return -EWOULDBLOCK;
469 	}
470 
471 	k_sem_take(&drv_data->lock, K_FOREVER);
472 
473 	ret = setup_pin_dir(dev, pin, flags);
474 	if (ret) {
475 		LOG_ERR("PCA95XX[0x%X]: error setting pin direction (%d)",
476 			config->bus.addr, ret);
477 		goto done;
478 	}
479 
480 	ret = setup_pin_pullupdown(dev, pin, flags);
481 	if (ret) {
482 		LOG_ERR("PCA95XX[0x%X]: error setting pin pull up/down "
483 			"(%d)", config->bus.addr, ret);
484 		goto done;
485 	}
486 
487 done:
488 	k_sem_give(&drv_data->lock);
489 	return ret;
490 }
491 
gpio_pca95xx_port_get_raw(const struct device * dev,uint32_t * value)492 static int gpio_pca95xx_port_get_raw(const struct device *dev, uint32_t *value)
493 {
494 	struct gpio_pca95xx_drv_data * const drv_data =
495 		(struct gpio_pca95xx_drv_data * const)dev->data;
496 	uint16_t buf;
497 	int ret;
498 
499 	/* Can't do I2C bus operations from an ISR */
500 	if (k_is_in_isr()) {
501 		return -EWOULDBLOCK;
502 	}
503 
504 	k_sem_take(&drv_data->lock, K_FOREVER);
505 
506 	ret = update_input_regs(dev, &buf);
507 	if (ret != 0) {
508 		goto done;
509 	}
510 
511 	*value = buf;
512 
513 done:
514 	k_sem_give(&drv_data->lock);
515 	return ret;
516 }
517 
gpio_pca95xx_port_set_masked_raw(const struct device * dev,uint32_t mask,uint32_t value)518 static int gpio_pca95xx_port_set_masked_raw(const struct device *dev,
519 					      uint32_t mask, uint32_t value)
520 {
521 	struct gpio_pca95xx_drv_data * const drv_data =
522 		(struct gpio_pca95xx_drv_data * const)dev->data;
523 	uint16_t reg_out;
524 	int ret;
525 
526 	/* Can't do I2C bus operations from an ISR */
527 	if (k_is_in_isr()) {
528 		return -EWOULDBLOCK;
529 	}
530 
531 	k_sem_take(&drv_data->lock, K_FOREVER);
532 
533 	reg_out = drv_data->reg_cache.output;
534 	reg_out = (reg_out & ~mask) | (mask & value);
535 
536 	ret = update_output_regs(dev, reg_out);
537 
538 	k_sem_give(&drv_data->lock);
539 
540 	return ret;
541 }
542 
gpio_pca95xx_port_set_bits_raw(const struct device * dev,uint32_t mask)543 static int gpio_pca95xx_port_set_bits_raw(const struct device *dev,
544 					  uint32_t mask)
545 {
546 	return gpio_pca95xx_port_set_masked_raw(dev, mask, mask);
547 }
548 
gpio_pca95xx_port_clear_bits_raw(const struct device * dev,uint32_t mask)549 static int gpio_pca95xx_port_clear_bits_raw(const struct device *dev,
550 					    uint32_t mask)
551 {
552 	return gpio_pca95xx_port_set_masked_raw(dev, mask, 0);
553 }
554 
gpio_pca95xx_port_toggle_bits(const struct device * dev,uint32_t mask)555 static int gpio_pca95xx_port_toggle_bits(const struct device *dev,
556 					 uint32_t mask)
557 {
558 	struct gpio_pca95xx_drv_data * const drv_data =
559 		(struct gpio_pca95xx_drv_data * const)dev->data;
560 	uint16_t reg_out;
561 	int ret;
562 
563 	/* Can't do I2C bus operations from an ISR */
564 	if (k_is_in_isr()) {
565 		return -EWOULDBLOCK;
566 	}
567 
568 	k_sem_take(&drv_data->lock, K_FOREVER);
569 
570 	reg_out = drv_data->reg_cache.output;
571 	reg_out ^= mask;
572 
573 	ret = update_output_regs(dev, reg_out);
574 
575 	k_sem_give(&drv_data->lock);
576 
577 	return ret;
578 }
579 
580 #ifdef CONFIG_GPIO_PCA95XX_INTERRUPT
get_triggered_it(struct gpio_pca95xx_drv_data * drv_data,uint16_t * trig_edge,uint16_t * trig_level)581 static void get_triggered_it(struct gpio_pca95xx_drv_data *drv_data,
582 		uint16_t *trig_edge, uint16_t *trig_level)
583 {
584 	uint16_t input_cache, changed_pins, input_new;
585 	int ret;
586 
587 	input_cache = drv_data->reg_cache.input;
588 	ret = update_input_regs(drv_data->instance, &input_new);
589 	if (ret == 0) {
590 		changed_pins = (input_cache ^ input_new);
591 
592 		*trig_edge |= (changed_pins & input_new &
593 			     drv_data->interrupts.edge_rising);
594 		*trig_edge |= (changed_pins & input_cache &
595 			      drv_data->interrupts.edge_falling);
596 		*trig_level |= (input_new & drv_data->interrupts.level_high);
597 		*trig_level |= (~input_new & drv_data->interrupts.level_low);
598 	}
599 }
600 
gpio_pca95xx_interrupt_worker(struct k_work * work)601 static void gpio_pca95xx_interrupt_worker(struct k_work *work)
602 {
603 	struct gpio_pca95xx_drv_data * const drv_data = CONTAINER_OF(
604 		work, struct gpio_pca95xx_drv_data, interrupt_worker);
605 	const struct gpio_pca95xx_config * const config = drv_data->instance->config;
606 	uint16_t trig_edge = 0, trig_level = 0;
607 	uint32_t triggered_int = 0;
608 
609 	k_sem_take(&drv_data->lock, K_FOREVER);
610 
611 	/* Note: PCA Interrupt status is cleared by reading inputs */
612 	if (config->capabilities & PCA_HAS_INTERRUPT_MASK_REG) {
613 		/* gpio latched read values, to be compared to cached ones */
614 		get_triggered_it(drv_data, &trig_edge, &trig_level);
615 	}
616 	/* gpio unlatched read values, in case signal has flipped again */
617 	get_triggered_it(drv_data, &trig_edge, &trig_level);
618 
619 	triggered_int = (trig_edge | trig_level);
620 
621 	k_sem_give(&drv_data->lock);
622 
623 	if (triggered_int != 0) {
624 		gpio_fire_callbacks(&drv_data->callbacks, drv_data->instance,
625 				    triggered_int);
626 	}
627 
628 	/* Emulate level triggering */
629 	if (trig_level != 0) {
630 		/* Reschedule worker */
631 		k_work_submit(&drv_data->interrupt_worker);
632 	}
633 }
634 
gpio_pca95xx_interrupt_callback(const struct device * dev,struct gpio_callback * cb,gpio_port_pins_t pins)635 static void gpio_pca95xx_interrupt_callback(const struct device *dev,
636 					    struct gpio_callback *cb,
637 					    gpio_port_pins_t pins)
638 {
639 	struct gpio_pca95xx_drv_data * const drv_data =
640 		CONTAINER_OF(cb, struct gpio_pca95xx_drv_data, gpio_callback);
641 
642 	ARG_UNUSED(pins);
643 
644 	/* Cannot read PCA95xx registers from ISR context, queue worker */
645 	k_work_submit(&drv_data->interrupt_worker);
646 }
647 
gpio_pca95xx_pin_interrupt_configure(const struct device * dev,gpio_pin_t pin,enum gpio_int_mode mode,enum gpio_int_trig trig)648 static int gpio_pca95xx_pin_interrupt_configure(const struct device *dev,
649 						  gpio_pin_t pin,
650 						  enum gpio_int_mode mode,
651 						  enum gpio_int_trig trig)
652 {
653 	int ret = 0;
654 	const struct gpio_pca95xx_config * const config = dev->config;
655 	struct gpio_pca95xx_drv_data * const drv_data =
656 		(struct gpio_pca95xx_drv_data * const)dev->data;
657 	uint16_t reg;
658 	bool enabled, edge, level, active;
659 
660 	/* Check if GPIO port supports interrupts */
661 	if ((config->capabilities & PCA_HAS_INTERRUPT) == 0U) {
662 		return -ENOTSUP;
663 	}
664 
665 	/* Check for an invalid pin number */
666 	if (BIT(pin) > config->common.port_pin_mask) {
667 		return -EINVAL;
668 	}
669 
670 	/* Check configured pin direction */
671 	if ((mode != GPIO_INT_MODE_DISABLED) &&
672 	    (BIT(pin) & drv_data->reg_cache.dir) != BIT(pin)) {
673 		LOG_ERR("PCA95XX[0x%X]: output pin cannot trigger interrupt",
674 			config->bus.addr);
675 		return -ENOTSUP;
676 	}
677 
678 	k_sem_take(&drv_data->lock, K_FOREVER);
679 
680 	/* Check if GPIO port has an interrupt mask register */
681 	if (config->capabilities & PCA_HAS_INTERRUPT_MASK_REG) {
682 		uint16_t reg_out;
683 
684 		reg_out = drv_data->reg_cache.int_mask;
685 		WRITE_BIT(reg_out, pin, (mode == GPIO_INT_MODE_DISABLED));
686 
687 		ret = update_int_mask_reg(dev, pin, reg_out);
688 		if (ret != 0) {
689 			LOG_ERR("PCA95XX[0x%X]: failed to update int mask (%d)",
690 				config->bus.addr, ret);
691 			goto err;
692 		}
693 	}
694 
695 	/* Update interrupt masks */
696 	enabled = ((mode & GPIO_INT_MODE_DISABLED) == 0U);
697 	edge = (mode == GPIO_INT_MODE_EDGE);
698 	level = (mode == GPIO_INT_MODE_LEVEL);
699 	WRITE_BIT(drv_data->interrupts.edge_rising, pin, (enabled &&
700 		edge && ((trig & GPIO_INT_TRIG_HIGH) == GPIO_INT_TRIG_HIGH)));
701 	WRITE_BIT(drv_data->interrupts.edge_falling, pin, (enabled &&
702 		edge && ((trig & GPIO_INT_TRIG_LOW) == GPIO_INT_TRIG_LOW)));
703 	WRITE_BIT(drv_data->interrupts.level_high, pin, (enabled &&
704 		level && ((trig & GPIO_INT_TRIG_HIGH) == GPIO_INT_TRIG_HIGH)));
705 	WRITE_BIT(drv_data->interrupts.level_low, pin, (enabled &&
706 		level && ((trig & GPIO_INT_TRIG_LOW) == GPIO_INT_TRIG_LOW)));
707 
708 	active = ((drv_data->interrupts.edge_rising ||
709 		   drv_data->interrupts.edge_falling ||
710 		   drv_data->interrupts.level_high ||
711 		   drv_data->interrupts.level_low) > 0);
712 
713 	/* Enable / disable interrupt as needed */
714 	if (active != drv_data->interrupt_active) {
715 		ret = gpio_pin_interrupt_configure_dt(
716 			&config->int_gpio, active ?
717 				   GPIO_INT_EDGE_TO_ACTIVE :
718 				   GPIO_INT_MODE_DISABLED);
719 		if (ret != 0) {
720 			LOG_ERR("PCA95XX[0x%X]: failed to configure interrupt "
721 				"on pin %d (%d)", config->bus.addr,
722 				config->int_gpio.pin, ret);
723 			goto err;
724 		}
725 		drv_data->interrupt_active = active;
726 
727 		if (active) {
728 			/* Read current status to reset any
729 			 * active signal on INT line
730 			 */
731 			update_input_regs(dev, &reg);
732 		}
733 	}
734 
735 err:
736 	k_sem_give(&drv_data->lock);
737 	return ret;
738 }
739 
gpio_pca95xx_manage_callback(const struct device * dev,struct gpio_callback * callback,bool set)740 static int gpio_pca95xx_manage_callback(const struct device *dev,
741 					struct gpio_callback *callback,
742 					bool set)
743 {
744 	const struct gpio_pca95xx_config * const config = dev->config;
745 	struct gpio_pca95xx_drv_data * const drv_data =
746 		(struct gpio_pca95xx_drv_data * const)dev->data;
747 
748 	if ((config->capabilities & PCA_HAS_INTERRUPT) == 0U) {
749 		return -ENOTSUP;
750 	}
751 
752 	k_sem_take(&drv_data->lock, K_FOREVER);
753 
754 	gpio_manage_callback(&drv_data->callbacks, callback, set);
755 
756 	k_sem_give(&drv_data->lock);
757 	return 0;
758 }
759 #endif /* CONFIG_GPIO_PCA95XX_INTERRUPT */
760 
761 static const struct gpio_driver_api gpio_pca95xx_drv_api_funcs = {
762 	.pin_configure = gpio_pca95xx_config,
763 	.port_get_raw = gpio_pca95xx_port_get_raw,
764 	.port_set_masked_raw = gpio_pca95xx_port_set_masked_raw,
765 	.port_set_bits_raw = gpio_pca95xx_port_set_bits_raw,
766 	.port_clear_bits_raw = gpio_pca95xx_port_clear_bits_raw,
767 	.port_toggle_bits = gpio_pca95xx_port_toggle_bits,
768 #ifdef CONFIG_GPIO_PCA95XX_INTERRUPT
769 	.pin_interrupt_configure = gpio_pca95xx_pin_interrupt_configure,
770 	.manage_callback = gpio_pca95xx_manage_callback,
771 #endif
772 };
773 
774 /**
775  * @brief Initialization function of PCA95XX
776  *
777  * @param dev Device struct
778  * @return 0 if successful, failed otherwise.
779  */
gpio_pca95xx_init(const struct device * dev)780 static int gpio_pca95xx_init(const struct device *dev)
781 {
782 	const struct gpio_pca95xx_config * const config = dev->config;
783 	struct gpio_pca95xx_drv_data * const drv_data =
784 		(struct gpio_pca95xx_drv_data * const)dev->data;
785 
786 	if (!device_is_ready(config->bus.bus)) {
787 		return -ENODEV;
788 	}
789 
790 	k_sem_init(&drv_data->lock, 1, 1);
791 
792 #ifdef CONFIG_GPIO_PCA95XX_INTERRUPT
793 	/* Check if GPIO port supports interrupts */
794 	if ((config->capabilities & PCA_HAS_INTERRUPT) != 0) {
795 		int ret;
796 
797 		/* Store self-reference for interrupt handling */
798 		drv_data->instance = dev;
799 
800 		/* Prepare interrupt worker */
801 		k_work_init(&drv_data->interrupt_worker,
802 			    gpio_pca95xx_interrupt_worker);
803 
804 		/* Configure GPIO interrupt pin */
805 		if (!gpio_is_ready_dt(&config->int_gpio)) {
806 			LOG_ERR("PCA95XX[0x%X]: interrupt GPIO not ready",
807 				config->bus.addr);
808 			return -ENODEV;
809 		}
810 
811 		ret = gpio_pin_configure_dt(&config->int_gpio, GPIO_INPUT);
812 		if (ret != 0) {
813 			LOG_ERR("PCA95XX[0x%X]: failed to configure interrupt"
814 				" pin %d (%d)", config->bus.addr,
815 				config->int_gpio.pin, ret);
816 			return ret;
817 		}
818 
819 		/* Prepare GPIO callback for interrupt pin */
820 		gpio_init_callback(&drv_data->gpio_callback,
821 				   gpio_pca95xx_interrupt_callback,
822 				   BIT(config->int_gpio.pin));
823 		ret = gpio_add_callback(config->int_gpio.port, &drv_data->gpio_callback);
824 		if (ret != 0) {
825 			LOG_ERR("PCA95XX[0x%X]: failed to add interrupt callback for"
826 				" pin %d (%d)", config->bus.addr,
827 				config->int_gpio.pin, ret);
828 			return ret;
829 		}
830 	}
831 #endif
832 
833 	return 0;
834 }
835 
836 #define GPIO_PCA95XX_DEVICE_INSTANCE(inst)				\
837 static const struct gpio_pca95xx_config gpio_pca95xx_##inst##_cfg = {	\
838 	.common = {							\
839 		.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(inst),	\
840 	},								\
841 	.bus = I2C_DT_SPEC_INST_GET(inst),				\
842 	.capabilities =							\
843 		(DT_INST_PROP(inst, has_pud) ? PCA_HAS_PUD : 0) |	\
844 		IF_ENABLED(CONFIG_GPIO_PCA95XX_INTERRUPT, (		\
845 		(DT_INST_NODE_HAS_PROP(inst, interrupt_gpios) ?		\
846 			PCA_HAS_INTERRUPT : 0) |			\
847 		(DT_INST_PROP(inst, has_interrupt_mask_reg) ?		\
848 			PCA_HAS_INTERRUPT_MASK_REG : 0) |		\
849 		))							\
850 		0,							\
851 	IF_ENABLED(CONFIG_GPIO_PCA95XX_INTERRUPT,			\
852 	(.int_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, interrupt_gpios, {}),)) \
853 };									\
854 									\
855 static struct gpio_pca95xx_drv_data gpio_pca95xx_##inst##_drvdata = {	\
856 	.reg_cache.input = 0x0,						\
857 	.reg_cache.output = 0xFFFF,					\
858 	.reg_cache.dir = 0xFFFF,					\
859 	.reg_cache.pud_en = 0x0,					\
860 	.reg_cache.pud_sel = 0xFFFF,					\
861 	.reg_cache.int_mask = 0xFFFF,					\
862 	.reg_cache.input_latch = 0x0,				\
863 	IF_ENABLED(CONFIG_GPIO_PCA95XX_INTERRUPT, (			\
864 	.interrupt_active = false,					\
865 	))								\
866 };									\
867 									\
868 DEVICE_DT_INST_DEFINE(inst,						\
869 	gpio_pca95xx_init,						\
870 	NULL,								\
871 	&gpio_pca95xx_##inst##_drvdata,					\
872 	&gpio_pca95xx_##inst##_cfg,					\
873 	POST_KERNEL, CONFIG_GPIO_PCA95XX_INIT_PRIORITY,			\
874 	&gpio_pca95xx_drv_api_funcs);
875 
876 DT_INST_FOREACH_STATUS_OKAY(GPIO_PCA95XX_DEVICE_INSTANCE)
877