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