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, ®);
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