1 /*
2 * Copyright 2024 NXP
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /**
8 * @file Driver for PCA(L)xxxx SERIES I2C-based GPIO expander.
9 */
10
11 #include <errno.h>
12
13 #include <zephyr/kernel.h>
14 #include <zephyr/device.h>
15 #include <zephyr/init.h>
16 #include <zephyr/sys/byteorder.h>
17 #include <zephyr/sys/util.h>
18 #include <zephyr/drivers/gpio.h>
19 #include <zephyr/drivers/gpio/gpio_utils.h>
20 #include <zephyr/drivers/i2c.h>
21
22 #define LOG_LEVEL CONFIG_GPIO_LOG_LEVEL
23 #include <zephyr/logging/log.h>
24 LOG_MODULE_REGISTER(gpio_pca_series);
25
26 /** Private debug macro, enable more error checking and print more log. */
27 /* #define GPIO_NXP_PCA_SERIES_DEBUG */
28
29 /* Feature flags */
30 #define PCA_HAS_LATCH BIT(0) /** + output_drive_strength, + input_latch */
31 #define PCA_HAS_PULL BIT(1) /** + pull_enable, + pull_select */
32 #define PCA_HAS_INT_MASK BIT(2) /** + interrupt_mask, + int_status */
33 #define PCA_HAS_INT_EXTEND BIT(3) /** + interrupt_edge, + interrupt_clear */
34 #define PCA_HAS_OUT_CONFIG BIT(4) /** + input_status, + output_config */
35
36 /* get port and pin from gpio_pin_t */
37 #define PCA_PORT(gpio_pin) (gpio_pin >> 3)
38 #define PCA_PIN(gpio_pin) (gpio_pin & GENMASK(2, 0))
39
40 #define PCA_REG_INVALID (0xff)
41
42 /**
43 * @brief part number definition.
44 */
45 enum gpio_pca_series_part_no {
46 PCA_PART_NO_PCA9538,
47 PCA_PART_NO_PCA9539,
48 PCA_PART_NO_PCA9554,
49 PCA_PART_NO_PCA9555,
50 PCA_PART_NO_PCAL6524,
51 PCA_PART_NO_PCAL6534,
52 };
53
54 /**
55 * @brief part name definition for debug.
56 *
57 * @note must be consistent in order with @ref enum gpio_pca_series_part_no
58 */
59 const char *const gpio_pca_series_part_name[] = {
60 "pca9538",
61 "pca9539",
62 "pca9554",
63 "pca9555",
64 "pcal6524",
65 "pcal6534",
66 };
67
68 /**
69 * Device reg layout types:
70 * - Type 0: PCA953X, PCA955X
71 * - Type 1: PCAL953X, PCAL955X, PCAL64XXA
72 * - Type 2: PCA957X
73 * - Type 3: PCAL65XX
74 */
75
76 enum gpio_pca_series_reg_type { /** Type0 Type1 Type2 Type3 */
77 PCA_REG_TYPE_1B_INPUT_PORT = 0U, /** x x x x */
78 PCA_REG_TYPE_1B_OUTPUT_PORT, /** x x x x */
79 /* PCA_REG_TYPE_1B_POLARITY_INVERSION, x x x x * (unused, omitted) */
80 PCA_REG_TYPE_1B_CONFIGURATION, /** x x x x */
81 PCA_REG_TYPE_2B_OUTPUT_DRIVE_STRENGTH, /** x x */
82 PCA_REG_TYPE_1B_INPUT_LATCH, /** x x */
83 PCA_REG_TYPE_1B_PULL_ENABLE, /** x x*1 x */
84 PCA_REG_TYPE_1B_PULL_SELECT, /** x x x */
85 PCA_REG_TYPE_1B_INPUT_STATUS, /** x */
86 PCA_REG_TYPE_1B_OUTPUT_CONFIG, /** x*2 */
87 #ifdef CONFIG_GPIO_PCA_SERIES_INTERRUPT /** */
88 PCA_REG_TYPE_1B_INTERRUPT_MASK, /** x x x */
89 PCA_REG_TYPE_1B_INTERRUPT_STATUS, /** x x x */
90 PCA_REG_TYPE_2B_INTERRUPT_EDGE, /** x */
91 PCA_REG_TYPE_1B_INTERRUPT_CLEAR, /** x */
92 # ifdef CONFIG_GPIO_PCA_SERIES_CACHE_ALL
93 PCA_REG_TYPE_1B_INPUT_HISTORY, /** x x x * (cache registry) */
94 PCA_REG_TYPE_1B_INTERRUPT_RISE, /** x x x * (cache registry) */
95 PCA_REG_TYPE_1B_INTERRUPT_FALL, /** x x x * (cache registry) */
96 # endif /* CONFIG_GPIO_PCA_SERIES_CACHE_ALL */
97 #endif /* CONFIG_GPIO_PCA_SERIES_INTERRUPT */
98 PCA_REG_TYPE_COUNT, /** not a register */
99 };
100 /**
101 * #1: "pull_enable" register is named "bus_hold" in PCA957x datasheet.
102 * #2: this is for "individual pin output configuration register". We do not use
103 * port-level "pin output configuration" register.
104 */
105
106 const char *const gpio_pca_series_reg_name[] = {
107 "1b_input_port",
108 "1b_output_port",
109 /* "1b_polarity_inversion," */
110 "1b_configuration",
111 "2b_output_drive_strength",
112 "1b_input_latch",
113 "1b_pull_enable",
114 "1b_pull_select",
115 "1b_input_status",
116 "1b_output_config",
117 #ifdef CONFIG_GPIO_PCA_SERIES_INTERRUPT
118 "1b_interrupt_mask",
119 "1b_interrupt_status",
120 "2b_interrupt_edge",
121 "1b_interrupt_clear",
122 # ifdef CONFIG_GPIO_PCA_SERIES_CACHE_ALL
123 "1b_input_history",
124 "1b_interrupt_rise",
125 "ib_interrupt_fall",
126 # endif /* CONFIG_GPIO_PCA_SERIES_CACHE_ALL */
127 #endif /* CONFIG_GPIO_PCA_SERIES_INTERRUPT */
128 "reg_end",
129 };
130
131 /**
132 * @brief interrupt config for interrupt_edge register
133 *
134 * @note Only applies to part no with PCA_HAS_INT_EXTEND capability.
135 */
136 enum PCA_INTERRUPT_config_extended {
137 PCA_INTERRUPT_LEVEL_CHANGE = 0U, /* default */
138 PCA_INTERRUPT_RISING_EDGE,
139 PCA_INTERRUPT_FALLING_EDGE,
140 PCA_INTERRUPT_EITHER_EDGE,
141 };
142
143 struct gpio_pca_series_part_config {
144 uint8_t port_no; /* number of 8-pin ports on device */
145 uint8_t flags; /* capability flags */
146 const uint8_t *regs; /* pointer to register map */
147 #ifdef CONFIG_GPIO_PCA_SERIES_CACHE_ALL
148 # ifdef GPIO_NXP_PCA_SERIES_DEBUG
149 uint8_t cache_size;
150 # endif /* GPIO_NXP_PCA_SERIES_DEBUG */
151 const uint8_t *cache_map;
152 #endif /* CONFIG_GPIO_PCA_SERIES_CACHE_ALL */
153 };
154
155 /** Configuration data */
156 struct gpio_pca_series_config {
157 struct gpio_driver_config common; /* gpio_driver_config needs to be first */
158 struct i2c_dt_spec i2c; /* i2c bus dt spec */
159 const struct gpio_pca_series_part_config *part_cfg; /* config of part unmber */
160 struct gpio_dt_spec gpio_rst; /* device reset gpio */
161 #ifdef CONFIG_GPIO_PCA_SERIES_INTERRUPT
162 struct gpio_dt_spec gpio_int; /** device interrupt gpio */
163 #endif /* CONFIG_GPIO_PCA_SERIES_INTERRUPT */
164 };
165
166 /** Runtime driver data */
167 struct gpio_pca_series_data {
168 struct gpio_driver_data common; /** gpio_driver_data needs to be first */
169 struct k_sem lock;
170 void *cache; /** device spicific reg cache
171 * - if CONFIG_GPIO_PCA_SERIES_CACHE_ALL is set,
172 * it points to device specific cache memory.
173 * - if CONFIG_GPIO_PCA_SERIES_CACHE_ALL is not set,
174 * it point to a struct gpio_pca_series_reg_cache_mini
175 * instance.
176 */
177 #ifdef CONFIG_GPIO_PCA_SERIES_INTERRUPT
178 const struct device *self; /** Self-reference to the driver instance */
179 struct gpio_callback gpio_cb; /** gpio_int ISR callback */
180 sys_slist_t callbacks; /** port pin callbacks list */
181 struct k_work int_work; /** worker that fire callbacks */
182 #endif
183 };
184
185 /**
186 * gpio_pca_reg_access_api
187 * {
188 */
189
190 /**
191 * @brief get internal address of register from register type
192 *
193 * @param dev device struct
194 * @param reg_type value from enum gpio_pca_series_reg_type
195 * @return uint8_t PCA_REG_INVALID if reg is not used
196 * other internal address of register
197 */
gpio_pca_series_reg_get_addr(const struct device * dev,enum gpio_pca_series_reg_type reg_type)198 static inline uint8_t gpio_pca_series_reg_get_addr(const struct device *dev,
199 enum gpio_pca_series_reg_type reg_type)
200 {
201 const struct gpio_pca_series_config *cfg = dev->config;
202
203 #ifdef GPIO_NXP_PCA_SERIES_DEBUG
204 if (reg_type >= PCA_REG_TYPE_COUNT) {
205 LOG_ERR("reg_type %d out of range", reg_type);
206 return 0;
207 }
208 #endif /* GPIO_NXP_PCA_SERIES_DEBUG */
209
210 return cfg->part_cfg->regs[reg_type];
211 }
212
213 /**
214 * @brief get per-port size for register
215 *
216 * @param dev device struct
217 * @param reg_type value from enum gpio_pca_series_reg_type
218 * @return uint32_t size in bytes
219 * 0 if fail
220 */
gpio_pca_series_reg_size_per_port(const struct device * dev,enum gpio_pca_series_reg_type reg_type)221 static inline uint32_t gpio_pca_series_reg_size_per_port(const struct device *dev,
222 enum gpio_pca_series_reg_type reg_type)
223 {
224 #ifdef GPIO_NXP_PCA_SERIES_DEBUG
225 if (reg_type >= PCA_REG_TYPE_COUNT) {
226 LOG_ERR("reg_type %d out of range", reg_type);
227 return 0;
228 }
229 #endif /* GPIO_NXP_PCA_SERIES_DEBUG */
230
231 switch (reg_type) {
232 case PCA_REG_TYPE_1B_INPUT_PORT:
233 case PCA_REG_TYPE_1B_OUTPUT_PORT:
234 /* case PCA_REG_TYPE_1B_POLARITY_INVERSION: */
235 case PCA_REG_TYPE_1B_CONFIGURATION:
236 case PCA_REG_TYPE_1B_INPUT_LATCH:
237 case PCA_REG_TYPE_1B_PULL_ENABLE:
238 case PCA_REG_TYPE_1B_PULL_SELECT:
239 case PCA_REG_TYPE_1B_INPUT_STATUS:
240 case PCA_REG_TYPE_1B_OUTPUT_CONFIG:
241 #ifdef CONFIG_GPIO_PCA_SERIES_INTERRUPT
242 case PCA_REG_TYPE_1B_INTERRUPT_MASK:
243 case PCA_REG_TYPE_1B_INTERRUPT_STATUS:
244 case PCA_REG_TYPE_1B_INTERRUPT_CLEAR:
245 #ifdef CONFIG_GPIO_PCA_SERIES_CACHE_ALL
246 case PCA_REG_TYPE_1B_INPUT_HISTORY:
247 case PCA_REG_TYPE_1B_INTERRUPT_RISE:
248 case PCA_REG_TYPE_1B_INTERRUPT_FALL:
249 #endif /* CONFIG_GPIO_PCA_SERIES_CACHE_ALL */
250 #endif /* CONFIG_GPIO_PCA_SERIES_INTERRUPT */
251 return 1;
252 case PCA_REG_TYPE_2B_OUTPUT_DRIVE_STRENGTH:
253 #ifdef CONFIG_GPIO_PCA_SERIES_INTERRUPT
254 case PCA_REG_TYPE_2B_INTERRUPT_EDGE:
255 #endif /* CONFIG_GPIO_PCA_SERIES_INTERRUPT */
256 return 2;
257 default:
258 LOG_ERR("unsupported reg type %d", reg_type);
259 return 0; /** should never happen */
260 }
261 }
262
263 /**
264 * @brief get read size for register
265 *
266 * @param dev device struct
267 * @param reg_type value from enum gpio_pca_series_reg_type
268 * @return uint32_t size in bytes
269 * 0 if fail
270 */
gpio_pca_series_reg_size(const struct device * dev,enum gpio_pca_series_reg_type reg_type)271 static inline uint32_t gpio_pca_series_reg_size(const struct device *dev,
272 enum gpio_pca_series_reg_type reg_type)
273 {
274 const struct gpio_pca_series_config *cfg = dev->config;
275
276 return gpio_pca_series_reg_size_per_port(dev, reg_type) * cfg->part_cfg->port_no;
277 }
278
279 #ifdef CONFIG_GPIO_PCA_SERIES_CACHE_ALL
280 /** forward declarations */
281 static inline uint8_t gpio_pca_series_reg_cache_offset(const struct device *dev,
282 enum gpio_pca_series_reg_type reg_type);
283 static inline int gpio_pca_series_reg_cache_update(const struct device *dev,
284 enum gpio_pca_series_reg_type reg_type,
285 const uint8_t *buf);
286 #endif /* CONFIG_GPIO_PCA_SERIES_CACHE_ALL */
287
288 /**
289 * @brief read register with i2c interface.
290 *
291 * @note if CONFIG_GPIO_PCA_SERIES_CACHE_ALL is enabled, this will
292 * not update reg cache. Cache must be updated with
293 * @ref gpio_pca_series_reg_cache_update.
294 *
295 * @param dev device struct
296 * @param reg_type value from enum gpio_pca_series_reg_type
297 * @param buf pointer to data in little-endian byteorder
298 * @return int 0 if success
299 * -EFAULT if register is not supported
300 * -EIO if i2c failure
301 */
gpio_pca_series_reg_read(const struct device * dev,enum gpio_pca_series_reg_type reg_type,uint8_t * buf)302 static inline int gpio_pca_series_reg_read(const struct device *dev,
303 enum gpio_pca_series_reg_type reg_type, uint8_t *buf)
304 {
305 const struct gpio_pca_series_config *cfg = dev->config;
306 int ret = 0;
307 uint32_t size = gpio_pca_series_reg_size(dev, reg_type);
308 uint8_t addr = gpio_pca_series_reg_get_addr(dev, reg_type);
309
310 LOG_DBG("device read type %d addr 0x%x len %d", reg_type, addr, size);
311
312 #ifdef GPIO_NXP_PCA_SERIES_DEBUG
313 if (!buf) {
314 return -EFAULT;
315 }
316
317 if (addr == PCA_REG_INVALID) {
318 LOG_ERR("trying to read unsupported reg, reg type %d", reg_type);
319 return -EFAULT;
320 }
321 #endif /* GPIO_NXP_PCA_SERIES_DEBUG */
322
323 ret = i2c_write_read_dt(&cfg->i2c, (uint8_t *)&addr, 1, (uint8_t *)buf, size);
324 if (ret) {
325 LOG_ERR("i2c read error [%d]", ret);
326 }
327 return ret;
328 }
329
330 /**
331 * @brief write register with i2c interface.
332 *
333 * @note if CONFIG_GPIO_PCA_SERIES_CACHE_ALL is enabled, this will
334 * also update reg cache.
335 *
336 * @param dev device struct
337 * @param reg_type value from enum gpio_pca_series_reg_type
338 * @param buf pointer to data in little-endian byteorder
339 * @return int 0 if success
340 * -EFAULT if register is not supported
341 * -EIO if i2c failure
342 */
gpio_pca_series_reg_write(const struct device * dev,enum gpio_pca_series_reg_type reg_type,const uint8_t * buf)343 static inline int gpio_pca_series_reg_write(const struct device *dev,
344 enum gpio_pca_series_reg_type reg_type, const uint8_t *buf)
345 {
346 const struct gpio_pca_series_config *cfg = dev->config;
347 int ret = 0;
348 struct i2c_msg msg[2];
349 uint32_t size = gpio_pca_series_reg_size(dev, reg_type);
350 uint8_t addr = gpio_pca_series_reg_get_addr(dev, reg_type);
351
352 #ifdef GPIO_NXP_PCA_SERIES_DEBUG
353 if (!buf) {
354 return -EFAULT;
355 }
356
357 if (addr == PCA_REG_INVALID) {
358 LOG_ERR("trying to write unsupported reg type %d", reg_type);
359 return -EFAULT;
360 }
361 #endif /* GPIO_NXP_PCA_SERIES_DEBUG */
362
363 LOG_DBG("device write type %d addr 0x%x len %d", reg_type, addr, size);
364
365 msg[0].buf = (uint8_t *)&addr;
366 msg[0].len = 1;
367 msg[0].flags = I2C_MSG_WRITE;
368 msg[1].buf = (uint8_t *)buf;
369 msg[1].len = size;
370 msg[1].flags = I2C_MSG_WRITE | I2C_MSG_STOP;
371 ret = i2c_transfer_dt(&cfg->i2c, msg, 2);
372 if (ret) {
373 LOG_ERR("i2c write error [%d]", ret);
374 return ret;
375 }
376
377 #ifdef CONFIG_GPIO_PCA_SERIES_CACHE_ALL
378 if (gpio_pca_series_reg_cache_offset(dev, reg_type) != PCA_REG_INVALID) {
379 (void)gpio_pca_series_reg_cache_update(dev, reg_type, buf);
380 }
381 #endif /* CONFIG_GPIO_PCA_SERIES_CACHE_ALL */
382
383 return ret;
384 }
385
386 /**
387 * }
388 * gpio_pca_reg_access_api
389 */
390
391 /**
392 * gpio_pca_reg_cache_api
393 * {
394 * @note full cache is stored in le byteorder, consistent with reg layout.
395 * mini cache is stored in cpu byteorder
396 */
397
398 #ifdef CONFIG_GPIO_PCA_SERIES_CACHE_ALL
399
400 /**
401 * @brief get memory offset of register cache from register type
402 *
403 * @param dev device struct
404 * @param reg_type value from enum gpio_pca_series_reg_type
405 * @return uint8_t PCA_REG_INVALID if reg is not used or uncacheable
406 * other offset in bytes related to cache pointer
407 */
gpio_pca_series_reg_cache_offset(const struct device * dev,enum gpio_pca_series_reg_type reg_type)408 static inline uint8_t gpio_pca_series_reg_cache_offset(const struct device *dev,
409 enum gpio_pca_series_reg_type reg_type)
410 {
411 const struct gpio_pca_series_config *cfg = dev->config;
412
413 if (cfg->part_cfg->cache_map[reg_type] == PCA_REG_INVALID) {
414 return PCA_REG_INVALID;
415 } else {
416 return cfg->part_cfg->cache_map[reg_type] * cfg->part_cfg->port_no;
417 }
418 }
419
420 /**
421 * @brief read all cacheable physical registers from device and update them
422 * in cache
423 *
424 * @param dev device struct
425 * @param reg_type value from enum gpio_pca_series_reg_type
426 * @return uint8_t PCA_REG_INVALID if reg is not used or uncacheable
427 * other offset in bytes related to cache pointer
428 */
gpio_pca_series_reg_cache_reset(const struct device * dev)429 static inline int gpio_pca_series_reg_cache_reset(const struct device *dev)
430 {
431 struct gpio_pca_series_data *data = dev->data;
432 int ret = 0;
433
434 for (int reg_type = 0; reg_type < PCA_REG_TYPE_COUNT; ++reg_type) {
435 uint8_t cache_offset = gpio_pca_series_reg_cache_offset(dev, reg_type);
436
437 if (cache_offset == PCA_REG_INVALID) {
438 continue;
439 }
440
441 LOG_DBG("cache init type %d", reg_type);
442
443 #ifdef CONFIG_GPIO_PCA_SERIES_INTERRUPT
444 /**
445 * On devices without PCA_HAS_INT_EXTEND calabilitiy,
446 * PCA_REG_TYPE_2B_INTERRUPT_EDGE caches mask of rising and falling pins,
447 * while the actual register is not present. Account for that here:
448 */
449 uint8_t reg_addr = gpio_pca_series_reg_get_addr(dev, reg_type);
450
451 if (reg_addr == PCA_REG_INVALID) {
452 const uint8_t reset_value_0[] = {
453 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
454
455 switch (reg_type) {
456 case PCA_REG_TYPE_1B_INPUT_HISTORY:
457 ret = gpio_pca_series_reg_read(dev, PCA_REG_TYPE_1B_INPUT_PORT,
458 ((uint8_t *)data->cache) + cache_offset);
459 if (ret) {
460 LOG_ERR("cache initial input read failed %d", ret);
461 }
462 break;
463 case PCA_REG_TYPE_1B_INTERRUPT_RISE:
464 case PCA_REG_TYPE_1B_INTERRUPT_FALL:
465 ret = gpio_pca_series_reg_cache_update(dev, reg_type,
466 reset_value_0);
467 if (ret) {
468 LOG_ERR("init initial interrupt config failed %d", ret);
469 }
470 break;
471 default:
472 LOG_ERR("trying to cache reg that is not present");
473 break;
474 }
475 if (ret) {
476 break;
477 }
478 continue;
479 }
480 #endif /* CONFIG_GPIO_PCA_SERIES_INTERRUPT */
481
482 ret = gpio_pca_series_reg_read(dev, reg_type,
483 ((uint8_t *)data->cache) + cache_offset);
484 if (ret) {
485 LOG_ERR("reg type %d cache init fail %d", reg_type, ret);
486 break;
487 }
488 }
489 return ret;
490 }
491
492 /**
493 * @brief read register value from reg cache
494 *
495 * @param dev device struct
496 * @param reg_type value from enum gpio_pca_series_reg_type
497 * @param buf pointer to read data in little-endian byteorder
498 * @return int 0 if success
499 * -EINVAL if invalid arguments
500 * -EACCES if register is uncacheable
501 */
gpio_pca_series_reg_cache_read(const struct device * dev,enum gpio_pca_series_reg_type reg_type,uint8_t * buf)502 static inline int gpio_pca_series_reg_cache_read(const struct device *dev,
503 enum gpio_pca_series_reg_type reg_type,
504 uint8_t *buf)
505 {
506 struct gpio_pca_series_data *data = dev->data;
507 int ret = 0;
508 uint8_t offset = gpio_pca_series_reg_cache_offset(dev, reg_type);
509 uint32_t size = gpio_pca_series_reg_size(dev, reg_type);
510 uint8_t *src;
511
512 #ifdef GPIO_NXP_PCA_SERIES_DEBUG
513 if (!buf) {
514 return -EINVAL;
515 }
516
517 if (offset == PCA_REG_INVALID) {
518 LOG_ERR("can not get noncacheable reg %d");
519 return -EFAULT;
520 }
521 #endif /* GPIO_NXP_PCA_SERIES_DEBUG */
522
523 src = ((uint8_t *)data->cache) + offset;
524 LOG_DBG("cache read type %d len %d mem addr 0x%p", reg_type, size, src);
525 memcpy(buf, src, size);
526 return ret;
527 }
528
529 /**
530 * @brief update register cache from device or existing value.
531 *
532 * @param dev device struct
533 * @param reg_type value from enum gpio_pca_series_reg_type
534 * @param buf pointer to new data to update from, in little-endian byteorder
535 * @return int 0 if success
536 * -EINVAL if invalid arguments
537 * -EACCES if register is uncacheable
538 */
gpio_pca_series_reg_cache_update(const struct device * dev,enum gpio_pca_series_reg_type reg_type,const uint8_t * buf)539 static inline int gpio_pca_series_reg_cache_update(const struct device *dev,
540 enum gpio_pca_series_reg_type reg_type,
541 const uint8_t *buf)
542 {
543 struct gpio_pca_series_data *data = dev->data;
544 uint8_t offset = gpio_pca_series_reg_cache_offset(dev, reg_type);
545 uint32_t size = gpio_pca_series_reg_size(dev, reg_type);
546 uint8_t *dst;
547
548 #ifdef GPIO_NXP_PCA_SERIES_DEBUG
549 if (!buf) {
550 return -EINVAL;
551 }
552
553 if (offset == PCA_REG_INVALID) {
554 LOG_ERR("can not update non-cacheable reg type %d", reg_type);
555 return -EACCES;
556 }
557 #endif /* GPIO_NXP_PCA_SERIES_DEBUG */
558
559 LOG_DBG("cache update type %d len %d from %s", reg_type, size,
560 (buf ? "buffer" : "device"));
561
562 dst = ((uint8_t *)data->cache) + offset;
563 LOG_DBG("cache write mem addr 0x%p len %d", dst, size);
564
565 /** update cache from buf */
566 memcpy(dst, buf, size);
567
568 return 0;
569 }
570
571 #else /* CONFIG_GPIO_PCA_SERIES_CACHE_ALL */
572
573 #define gpio_pca_series_reg_cache_read gpio_pca_series_reg_read
574
575 struct gpio_pca_series_reg_cache_mini {
576 uint32_t output; /** cache output value for faster output */
577 #ifdef CONFIG_GPIO_PCA_SERIES_INTERRUPT
578 uint32_t input_old; /** only used when interrupt mask & edge config is not present */
579 uint32_t int_rise; /** only used if interrupt edge is software-compared */
580 uint32_t int_fall; /** only used if interrupt edge is software-compared */
581 #endif /* CONFIG_GPIO_PCA_SERIES_INTERRUPT */
582 };
583
gpio_pca_series_reg_cache_mini_get(const struct device * dev)584 static inline struct gpio_pca_series_reg_cache_mini *gpio_pca_series_reg_cache_mini_get(
585 const struct device *dev)
586 {
587 struct gpio_pca_series_data *data = dev->data;
588 struct gpio_pca_series_reg_cache_mini *cache =
589 (struct gpio_pca_series_reg_cache_mini *)(&data->cache);
590 LOG_DBG("mini cache addr 0x%p", cache);
591 return cache;
592 }
593
gpio_pca_series_reg_cache_mini_reset(const struct device * dev)594 static inline int gpio_pca_series_reg_cache_mini_reset(const struct device *dev)
595 {
596 const struct gpio_pca_series_config *cfg = dev->config;
597 struct gpio_pca_series_reg_cache_mini *cache =
598 gpio_pca_series_reg_cache_mini_get(dev);
599 int ret = 0;
600
601 ret = gpio_pca_series_reg_read(dev, PCA_REG_TYPE_1B_OUTPUT_PORT,
602 (uint8_t *)&cache->output);
603 if (ret) {
604 LOG_ERR("minimum cache failed to read initial output: %d", ret);
605 goto out;
606 }
607
608 cache->output = sys_le32_to_cpu(cache->output);
609
610 #ifdef CONFIG_GPIO_PCA_SERIES_INTERRUPT
611 cache->int_rise = 0;
612 cache->int_fall = 0;
613
614 /* Read initial input value */
615 enum gpio_pca_series_reg_type input_reg =
616 cfg->part_cfg->flags & PCA_HAS_OUT_CONFIG ?
617 PCA_REG_TYPE_1B_INPUT_STATUS : PCA_REG_TYPE_1B_INPUT_PORT;
618
619 ret = gpio_pca_series_reg_read(dev, input_reg, (uint8_t *)&cache->input_old);
620 if (ret) {
621 LOG_ERR("minimum cache failed to read initial input: %d", ret);
622 }
623
624 cache->input_old = sys_le32_to_cpu(cache->input_old);
625 #else
626 ARG_UNUSED(cfg);
627 #endif /* CONFIG_GPIO_PCA_SERIES_INTERRUPT */
628
629 out:
630 return ret;
631 }
632
633 #endif /* CONFIG_GPIO_PCA_SERIES_CACHE_ALL */
634
635 /**
636 * }
637 * gpio_pca_cache_api
638 */
639
640 /**
641 * gpio_pca_custom_api
642 * {
643 */
644
645 /**
646 * @brief Reset function of pca_series
647 *
648 * This function pulls reset pin to reset a pca_series
649 * device if reset_pin is present. Otherwise it write
650 * reset value to device registers.
651 */
gpio_pca_series_reset(const struct device * dev)652 static inline void gpio_pca_series_reset(const struct device *dev)
653 {
654 const struct gpio_pca_series_config *cfg = dev->config;
655 const uint8_t reset_value_0[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
656 const uint8_t reset_value_1[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
657 int ret = 0;
658
659 /** Reset pin connected, do hardware reset */
660 if (cfg->gpio_rst.port != NULL) {
661 if (!device_is_ready(cfg->gpio_rst.port)) {
662 goto sw_rst;
663 }
664 /* Reset gpio should be set to active LOW in dts */
665 ret = gpio_pin_configure_dt(&cfg->gpio_rst,
666 GPIO_OUTPUT_HIGH | GPIO_OUTPUT_INIT_LOGICAL);
667 if (ret) {
668 goto sw_rst;
669 }
670 k_sleep(K_USEC(1));
671 ret = gpio_pin_set_dt(&cfg->gpio_rst, 0U);
672 if (ret) {
673 goto sw_rst;
674 }
675 k_sleep(K_USEC(1));
676 return;
677 }
678
679 sw_rst:
680 /** Warn that gpio configured but failed */
681 if (cfg->gpio_rst.port != NULL) {
682 LOG_WRN("gpio reset failed, fallback to soft reset");
683 }
684 /**
685 * Reset pin not connected, write reset value to registers
686 * No need to check return, as unsupported reg will return early with error
687 */
688 gpio_pca_series_reg_write(dev, PCA_REG_TYPE_1B_OUTPUT_PORT, reset_value_1);
689 gpio_pca_series_reg_write(dev, PCA_REG_TYPE_1B_CONFIGURATION, reset_value_1);
690 if (cfg->part_cfg->flags & PCA_HAS_LATCH) {
691 gpio_pca_series_reg_write(dev, PCA_REG_TYPE_2B_OUTPUT_DRIVE_STRENGTH,
692 reset_value_1);
693 gpio_pca_series_reg_write(dev, PCA_REG_TYPE_1B_INPUT_LATCH, reset_value_0);
694 }
695 if (cfg->part_cfg->flags & PCA_HAS_PULL) {
696 gpio_pca_series_reg_write(dev, PCA_REG_TYPE_1B_PULL_ENABLE, reset_value_0);
697 gpio_pca_series_reg_write(dev, PCA_REG_TYPE_1B_PULL_SELECT, reset_value_1);
698 }
699 if (cfg->part_cfg->flags & PCA_HAS_OUT_CONFIG) {
700 gpio_pca_series_reg_write(dev, PCA_REG_TYPE_1B_OUTPUT_CONFIG, reset_value_0);
701 }
702 #ifdef CONFIG_GPIO_PCA_SERIES_INTERRUPT
703 if (cfg->part_cfg->flags & PCA_HAS_INT_MASK) {
704 gpio_pca_series_reg_write(dev, PCA_REG_TYPE_1B_INTERRUPT_MASK, reset_value_1);
705 }
706 if (cfg->part_cfg->flags & PCA_HAS_INT_EXTEND) {
707 gpio_pca_series_reg_write(dev, PCA_REG_TYPE_2B_INTERRUPT_EDGE, reset_value_0);
708 }
709 #endif /* CONFIG_GPIO_PCA_SERIES_INTERRUPT */
710 }
711
712 #ifdef GPIO_NXP_PCA_SERIES_DEBUG
713
714 /**
715 * @brief Dump all available register and cache for debug purpose.
716 *
717 * @note This function does not consider cpu byteorder.
718 */
gpio_pca_series_debug_dump(const struct device * dev)719 void gpio_pca_series_debug_dump(const struct device *dev)
720 {
721 const struct gpio_pca_series_config *cfg = dev->config;
722 struct gpio_pca_series_data *data = dev->data;
723 int ret = 0;
724
725 LOG_WRN("**** debug dump ****");
726 LOG_WRN("device: %s", dev->name);
727 #ifdef CONFIG_GPIO_PCA_SERIES_CACHE_ALL
728 LOG_WRN("cache base addr: 0x%p size: 0x%2.2x",
729 data->cache, cfg->part_cfg->cache_size);
730 #else
731 LOG_WRN("cache base addr: 0x%p", data->cache);
732 #endif /* CONFIG_GPIO_PCA_SERIES_CACHE_ALL */
733
734 LOG_WRN("register profile:");
735 LOG_WRN("type\t"
736 "name\t\t\t"
737 "addr\t"
738 "reg_value\t\t\t"
739 #ifdef CONFIG_GPIO_PCA_SERIES_CACHE_ALL
740 "cache\t"
741 "cache_value\t\t"
742 #endif /* CONFIG_GPIO_PCA_SERIES_CACHE_ALL */
743 );
744 for (int reg_type = 0; reg_type < PCA_REG_TYPE_COUNT; ++reg_type) {
745 uint8_t reg = cfg->part_cfg->regs[reg_type];
746 uint8_t reg_val[8];
747 uint64_t *reg_val_p = (uint64_t *)®_val;
748 uint32_t reg_size = gpio_pca_series_reg_size(dev, reg_type);
749 #ifdef CONFIG_GPIO_PCA_SERIES_CACHE_ALL
750 uint8_t cache = gpio_pca_series_reg_cache_offset(dev, reg_type);
751 uint8_t cache_val[8];
752 uint64_t *cache_val_p = (uint64_t *)&cache_val;
753
754 if (reg == PCA_REG_INVALID && cache == PCA_REG_INVALID)
755 #else
756 if (reg == PCA_REG_INVALID)
757 #endif /* CONFIG_GPIO_PCA_SERIES_CACHE_ALL */
758 {
759 continue;
760 }
761
762 if (reg != PCA_REG_INVALID) {
763 *reg_val_p = 0;
764 ret = gpio_pca_series_reg_read(dev, reg_type, reg_val);
765 if (ret) {
766 LOG_ERR("read reg error from reg type %d, invalidate this reg",
767 reg_type);
768 reg = PCA_REG_INVALID;
769 }
770 }
771 #ifdef CONFIG_GPIO_PCA_SERIES_CACHE_ALL
772 if (cache != PCA_REG_INVALID) {
773 *cache_val_p = 0;
774 ret = gpio_pca_series_reg_cache_read(dev, reg_type, cache_val);
775 if (ret) {
776 LOG_ERR("read reg cache error from reg type %d, invalidate this "
777 "reg cache",
778 reg_type);
779 reg = PCA_REG_INVALID;
780 }
781 }
782 #endif /* CONFIG_GPIO_PCA_SERIES_CACHE_ALL */
783
784 /** do_print */
785 #ifdef CONFIG_GPIO_PCA_SERIES_CACHE_ALL
786 if (reg != PCA_REG_INVALID && cache != PCA_REG_INVALID) {
787 LOG_WRN("%.2d\t%-24s\t0x%2.2x\t0x%16.16x\t0x%2.2x\t0x%16.16x\t"
788 , reg_type, gpio_pca_series_reg_name[reg_type]
789 , reg, *reg_val_p
790 , cache, *cache_val_p
791 );
792 if (memcmp(reg_val, cache_val, reg_size)) {
793 LOG_ERR("reg %d cache mismatch", reg_type);
794 }
795 } else if (reg == PCA_REG_INVALID && cache != PCA_REG_INVALID) {
796 /**
797 * On devices without PCA_HAS_INT_EXTEND calabilitiy,
798 * PCA_REG_TYPE_2B_INTERRUPT_EDGE caches mask of rising and falling pins,
799 * while the actual register is not present. Account for that here:
800 */
801 LOG_WRN("%.2d\t%-24s\tNone\tNone\t\t\t0x%2.2x\t0x%16.16x\t"
802 , reg_type, gpio_pca_series_reg_name[reg_type]
803 , cache, *cache_val_p
804 );
805 } else {
806 #endif /* CONFIG_GPIO_PCA_SERIES_CACHE_ALL */
807 LOG_WRN("%.2d\t%-24s\t0x%2.2x\t0x%16.16x\t"
808 #ifdef CONFIG_GPIO_PCA_SERIES_CACHE_ALL
809 "None\tNone\t\t\t"
810 #endif /* CONFIG_GPIO_PCA_SERIES_CACHE_ALL */
811 , reg_type, gpio_pca_series_reg_name[reg_type]
812 , reg, *reg_val_p
813 );
814 #ifdef CONFIG_GPIO_PCA_SERIES_CACHE_ALL
815 }
816 #endif /* CONFIG_GPIO_PCA_SERIES_CACHE_ALL */
817 }
818 LOG_WRN("**** dump finish ****");
819 }
820
821 #ifdef CONFIG_GPIO_PCA_SERIES_CACHE_ALL
822
823 /**
824 * @brief Validate the cache api by filling data to the cache.
825 */
gpio_pca_series_cache_test(const struct device * dev)826 void gpio_pca_series_cache_test(const struct device *dev)
827 {
828 const struct gpio_pca_series_config *cfg = dev->config;
829 const uint8_t reset_value_0[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
830 const uint8_t reset_value_1[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
831 uint8_t buffer[8];
832 uint8_t expected_offset = 0U;
833 uint64_t *buffer_p = (uint64_t *)buffer;
834
835 LOG_WRN("**** cache test ****");
836 LOG_WRN("device: %s", dev->name);
837
838 for (int reg_type = 0; reg_type < PCA_REG_TYPE_COUNT; ++reg_type) {
839 uint8_t cache_offset = gpio_pca_series_reg_cache_offset(dev, reg_type);
840 uint32_t cache_size = gpio_pca_series_reg_size(dev, reg_type);
841
842 if (cache_offset == PCA_REG_INVALID) {
843 LOG_WRN("skip reg %d: not present or non-cacheable", reg_type);
844 continue;
845 }
846
847 if (cache_offset != expected_offset) {
848 LOG_ERR("reg %d cache offset 0x%2.2x error, expected 0x%2.2x",
849 reg_type, cache_offset, expected_offset);
850 break;
851 }
852
853 expected_offset += cache_size;
854
855 LOG_WRN("testing reg %d size %d", reg_type, cache_size);
856 (void)gpio_pca_series_reg_cache_update(dev, reg_type, reset_value_0);
857 *buffer_p = 0;
858 gpio_pca_series_reg_cache_read(dev, reg_type, buffer);
859 LOG_WRN("fill 00, result: 0x%16.16x", *buffer_p);
860 (void)gpio_pca_series_reg_cache_update(dev, reg_type, reset_value_1);
861 *buffer_p = 0;
862 gpio_pca_series_reg_cache_read(dev, reg_type, buffer);
863 LOG_WRN("fill ff, result: 0x%16.16x", *buffer_p);
864 }
865 LOG_WRN("**** test finish ****");
866 }
867 #endif /* CONFIG_GPIO_PCA_SERIES_CACHE_ALL */
868
869 #endif /* GPIO_NXP_PCA_SERIES_DEBUG */
870
871 /**
872 * }
873 * gpio_pca_custom_api
874 */
875
876 /**
877 * gpio_pca_zephyr_gpio_api
878 * {
879 */
880
881 #ifdef CONFIG_GPIO_PCA_SERIES_INTERRUPT
882 /** Forward declaration */
883 static inline void gpio_pca_series_interrupt_handler_standard(
884 const struct device *dev, gpio_port_value_t *input_value);
885 #endif /* CONFIG_GPIO_PCA_SERIES_INTERRUPT */
886
887 /**
888 * @brief configure gpio port.
889 *
890 * @note This API applies to all supported part no. Capabilities (
891 * PCA_HAS_PULL and PCA_HAS_OUT_CONFIG) are evaluated and handled.
892 *
893 * @return int 0 if success
894 * -ENOTSUP if unsupported config flags are provided
895 */
gpio_pca_series_pin_configure(const struct device * dev,gpio_pin_t pin,gpio_flags_t flags)896 static int gpio_pca_series_pin_configure(const struct device *dev,
897 gpio_pin_t pin, gpio_flags_t flags)
898 {
899 const struct gpio_pca_series_config *cfg = dev->config;
900 struct gpio_pca_series_data *data = dev->data;
901 uint32_t reg_value;
902 int ret = 0;
903
904 if ((flags & GPIO_INPUT) && (flags & GPIO_OUTPUT)) {
905 return -ENOTSUP;
906 }
907
908 if ((flags & GPIO_SINGLE_ENDED) &&
909 (cfg->part_cfg->flags & PCA_HAS_OUT_CONFIG) == 0U) {
910 return -ENOTSUP;
911 }
912
913 if ((flags & GPIO_PULL_UP) || (flags & GPIO_PULL_DOWN)) {
914 if ((cfg->part_cfg->flags & PCA_HAS_PULL) == 0U) {
915 return -ENOTSUP;
916 }
917 } /* Can't do I2C bus operations from an ISR */
918 if (k_is_in_isr()) {
919 return -EWOULDBLOCK;
920 }
921
922 LOG_DBG("dev %s configure pin %d flag 0x%x", dev->name, pin, flags);
923
924 k_sem_take(&data->lock, K_FOREVER);
925
926 /**
927 * TODO: Only write 1 byte.
928 *
929 * The config api only configures 1 pin, so only need to write the
930 * modified byte. Need to create new register & cache api to provide
931 * single byte access.
932 * This applies to: pin_configure, pin_interrupt_configure
933 */
934 if (cfg->part_cfg->flags & PCA_HAS_OUT_CONFIG) {
935 /* configure PCA_REG_TYPE_1B_OUTPUT_CONFIG */
936 ret = gpio_pca_series_reg_cache_read(dev,
937 PCA_REG_TYPE_1B_OUTPUT_CONFIG, (uint8_t *)®_value);
938 reg_value = sys_le32_to_cpu(reg_value);
939 if (flags & GPIO_SINGLE_ENDED) {
940 reg_value |= (BIT(pin)); /* set bit to set open-drain */
941 } else {
942 reg_value &= (~BIT(pin)); /* clear bit to set push-pull */
943 }
944 reg_value = sys_cpu_to_le32(reg_value);
945 ret = gpio_pca_series_reg_write(dev,
946 PCA_REG_TYPE_1B_OUTPUT_CONFIG, (uint8_t *)®_value);
947 }
948
949 if ((cfg->part_cfg->flags & PCA_HAS_PULL)) {
950 if ((flags & GPIO_PULL_UP) || (flags & GPIO_PULL_DOWN)) {
951 /* configure PCA_REG_TYPE_1B_PULL_SELECT */
952 ret = gpio_pca_series_reg_cache_read(dev,
953 PCA_REG_TYPE_1B_PULL_SELECT, (uint8_t *)®_value);
954 reg_value = sys_le32_to_cpu(reg_value);
955 if (flags & GPIO_PULL_UP) {
956 reg_value |= (BIT(pin));
957 } else {
958 reg_value &= (~BIT(pin));
959 }
960 reg_value = sys_cpu_to_le32(reg_value);
961 ret = gpio_pca_series_reg_write(dev,
962 PCA_REG_TYPE_1B_PULL_SELECT, (uint8_t *)®_value);
963 }
964 /* configure PCA_REG_TYPE_1B_PULL_ENABLE */
965 ret = gpio_pca_series_reg_cache_read(dev,
966 PCA_REG_TYPE_1B_PULL_ENABLE, (uint8_t *)®_value);
967 reg_value = sys_le32_to_cpu(reg_value);
968 if ((flags & GPIO_PULL_UP) || (flags & GPIO_PULL_DOWN)) {
969 reg_value |= (BIT(pin)); /* set bit to enable pull */
970 } else {
971 reg_value &= (~BIT(pin)); /* clear bit to disable pull */
972 }
973 reg_value = sys_cpu_to_le32(reg_value);
974 ret = gpio_pca_series_reg_write(dev, PCA_REG_TYPE_1B_PULL_ENABLE,
975 (uint8_t *)®_value);
976 }
977
978 /* configure PCA_REG_TYPE_1B_OUTPUT */
979 if ((flags & GPIO_OUTPUT_INIT_HIGH) || (flags & GPIO_OUTPUT_INIT_LOW)) {
980 uint32_t out_old;
981 #ifdef CONFIG_GPIO_PCA_SERIES_CACHE_ALL
982 /* get output register old value from reg cache */
983 ret = gpio_pca_series_reg_cache_read(dev, PCA_REG_TYPE_1B_OUTPUT_PORT,
984 (uint8_t *)&out_old);
985 if (ret) {
986 ret = -EINVAL; /* should never fail */
987 goto out;
988 }
989 out_old = sys_le32_to_cpu(out_old);
990 #else /* CONFIG_GPIO_PCA_SERIES_CACHE_ALL */
991 out_old = gpio_pca_series_reg_cache_mini_get(dev)->output;
992 #endif /* CONFIG_GPIO_PCA_SERIES_CACHE_ALL */
993
994 if (flags & GPIO_OUTPUT_INIT_HIGH) {
995 reg_value = out_old | (BIT(pin));
996 }
997 if (flags & GPIO_OUTPUT_INIT_LOW) {
998 reg_value = out_old & (~BIT(pin));
999 }
1000 reg_value = sys_cpu_to_le32(reg_value);
1001 ret = gpio_pca_series_reg_write(dev, PCA_REG_TYPE_1B_OUTPUT_PORT,
1002 (uint8_t *)®_value);
1003 if (ret != 0) {
1004 goto out;
1005 }
1006 #ifndef CONFIG_GPIO_PCA_SERIES_CACHE_ALL
1007 /** update output register old value to void* cache raw value */
1008 gpio_pca_series_reg_cache_mini_get(dev)->output =
1009 sys_le32_to_cpu(reg_value);
1010 #endif /* CONFIG_GPIO_PCA_SERIES_CACHE_ALL */
1011 }
1012
1013 /* configure PCA_REG_TYPE_1B_CONFIGURATION */
1014 ret = gpio_pca_series_reg_cache_read(dev,
1015 PCA_REG_TYPE_1B_CONFIGURATION, (uint8_t *)®_value);
1016 reg_value = sys_le32_to_cpu(reg_value);
1017 if (flags & GPIO_INPUT) {
1018 reg_value |= (BIT(pin)); /* set bit to set input */
1019 } else {
1020 reg_value &= (~BIT(pin)); /* clear bit to set output */
1021 }
1022 reg_value = sys_cpu_to_le32(reg_value);
1023 ret = gpio_pca_series_reg_write(dev,
1024 PCA_REG_TYPE_1B_CONFIGURATION, (uint8_t *)®_value);
1025
1026 out:
1027 k_sem_give(&data->lock);
1028 LOG_DBG("dev %s configure return %d", dev->name, ret);
1029 return ret;
1030 }
1031
1032 /**
1033 * @brief read gpio port
1034 *
1035 * @note read input_port register will clear interrupt masks
1036 * on supported devices. This API is used for part no
1037 * without PCA_HAS_INT_EXTEND capability.
1038 *
1039 * @param dev
1040 * @param value
1041 * @return int 0 if success
1042 * -EWOULDBLOCK if called from ISR context
1043 */
gpio_pca_series_port_read_standard(const struct device * dev,gpio_port_value_t * value)1044 static int gpio_pca_series_port_read_standard(
1045 const struct device *dev, gpio_port_value_t *value)
1046 {
1047 struct gpio_pca_series_data *data = dev->data;
1048 uint32_t input_data;
1049 int ret = 0;
1050
1051 /* Can't do I2C bus operations from an ISR */
1052 if (k_is_in_isr()) {
1053 return -EWOULDBLOCK;
1054 }
1055
1056 LOG_DBG("dev %s standard_read", dev->name);
1057
1058 #ifdef CONFIG_GPIO_PCA_SERIES_INTERRUPT
1059 gpio_pca_series_interrupt_handler_standard(dev, value);
1060 ARG_UNUSED(data);
1061 ARG_UNUSED(input_data);
1062 #else
1063 k_sem_take(&data->lock, K_FOREVER);
1064
1065 /* Read Input Register */
1066 ret = gpio_pca_series_reg_read(dev,
1067 PCA_REG_TYPE_1B_INPUT_PORT, (uint8_t *)&input_data);
1068 if (ret) {
1069 LOG_ERR("port read error %d", ret);
1070 } else {
1071 value = sys_le32_to_cpu(input_data);
1072 }
1073 k_sem_give(&data->lock);
1074 #endif /* CONFIG_GPIO_PCA_SERIES_INTERRUPT */
1075
1076 LOG_DBG("dev %s standard_read return %d result 0x%8.8x",
1077 dev->name, ret, (uint32_t) *value);
1078 return ret;
1079 }
1080
1081 /**
1082 * @brief read gpio port
1083 *
1084 * @note This API is used for part no with PCA_HAS_INT_EXTEND capability.
1085 * It read input_status register, which will NOT clear interrupt masks.
1086 *
1087 * @return int 0 if success
1088 * -EWOULDBLOCK if called from ISR context
1089 */
gpio_pca_series_port_read_extended(const struct device * dev,gpio_port_value_t * value)1090 static int gpio_pca_series_port_read_extended(
1091 const struct device *dev, gpio_port_value_t *value)
1092 {
1093 const struct gpio_pca_series_config *cfg = dev->config;
1094 struct gpio_pca_series_data *data = dev->data;
1095 uint32_t input_data;
1096 int ret = 0;
1097
1098 #ifdef GPIO_NXP_PCA_SERIES_DEBUG
1099 /**
1100 * Check the flags during runtime.
1101 *
1102 * The purpose is to check api assignment for developer who is adding
1103 * new device support to this driver.
1104 */
1105 const uint8_t check_flags = (PCA_HAS_LATCH | PCA_HAS_INT_MASK | PCA_HAS_INT_EXTEND);
1106
1107 if ((cfg->part_cfg->flags & check_flags) != check_flags) {
1108 LOG_ERR("unsupported device trying to read gpio with extended api");
1109 return -ENOTSUP;
1110 }
1111 #else
1112 ARG_UNUSED(cfg);
1113 #endif /* GPIO_NXP_PCA_SERIES_DEBUG */
1114
1115 /* Can't do I2C bus operations from an ISR */
1116 if (k_is_in_isr()) {
1117 return -EWOULDBLOCK;
1118 }
1119
1120 LOG_DBG("dev %s extended_read", dev->name);
1121 k_sem_take(&data->lock, K_FOREVER);
1122
1123 /* Read Input Status Register */
1124 ret = gpio_pca_series_reg_read(dev, PCA_REG_TYPE_1B_INPUT_STATUS,
1125 (uint8_t *)&input_data);
1126 if (ret) {
1127 LOG_ERR("port read error %d", ret);
1128 } else {
1129 *value = sys_le32_to_cpu(input_data);
1130 }
1131
1132 k_sem_give(&data->lock);
1133 LOG_DBG("dev %s extended_read return %d result 0x%8.8x",
1134 dev->name, ret, (uint32_t) *value);
1135 return ret;
1136 }
1137
gpio_pca_series_port_write(const struct device * dev,gpio_port_pins_t mask,gpio_port_value_t value,gpio_port_value_t toggle)1138 static int gpio_pca_series_port_write(const struct device *dev,
1139 gpio_port_pins_t mask, gpio_port_value_t value, gpio_port_value_t toggle)
1140 {
1141 struct gpio_pca_series_data *data = dev->data;
1142 uint32_t out_old;
1143 uint32_t out;
1144 int ret = 0;
1145
1146 /* Can't do I2C bus operations from an ISR */
1147 if (k_is_in_isr()) {
1148 return -EWOULDBLOCK;
1149 }
1150
1151 LOG_DBG("dev %s write mask 0x%8.8x value 0x%8.8x toggle 0x%8.8x",
1152 dev->name, (uint32_t)mask, (uint32_t)value, (uint32_t)toggle);
1153 k_sem_take(&data->lock, K_FOREVER);
1154
1155 #ifdef CONFIG_GPIO_PCA_SERIES_CACHE_ALL
1156 /** get output register old value from reg cache */
1157 ret = gpio_pca_series_reg_cache_read(dev, PCA_REG_TYPE_1B_OUTPUT_PORT,
1158 (uint8_t *)&out_old);
1159 if (ret) {
1160 return -EINVAL; /** should never fail */
1161 }
1162 out_old = sys_le32_to_cpu(out_old);
1163 #else /* CONFIG_GPIO_PCA_SERIES_CACHE_ALL */
1164 LOG_DBG("access address 0x%8.8x", (uint32_t)data->cache);
1165 out_old = gpio_pca_series_reg_cache_mini_get(dev)->output;
1166 #endif /* CONFIG_GPIO_PCA_SERIES_CACHE_ALL */
1167
1168 out = ((out_old & ~mask) | (value & mask)) ^ toggle;
1169 out = sys_cpu_to_le32(out);
1170
1171 ret = gpio_pca_series_reg_write(dev, PCA_REG_TYPE_1B_OUTPUT_PORT, (uint8_t *)&out);
1172 if (ret == 0) {
1173 #ifndef CONFIG_GPIO_PCA_SERIES_CACHE_ALL
1174 /** update output register old value to void* cache raw value */
1175 gpio_pca_series_reg_cache_mini_get(dev)->output = sys_le32_to_cpu(out);
1176 #endif /* CONFIG_GPIO_PCA_SERIES_CACHE_ALL */
1177 }
1178
1179 k_sem_give(&data->lock);
1180
1181 LOG_DBG("dev %s write return %d result 0x%8.8x", dev->name, ret, out);
1182 return ret;
1183 }
1184
gpio_pca_series_port_set_masked(const struct device * dev,gpio_port_pins_t mask,gpio_port_value_t value)1185 static int gpio_pca_series_port_set_masked(const struct device *dev, gpio_port_pins_t mask,
1186 gpio_port_value_t value)
1187 {
1188 return gpio_pca_series_port_write(dev, mask, value, 0);
1189 }
1190
gpio_pca_series_port_set_bits(const struct device * dev,gpio_port_pins_t pins)1191 static int gpio_pca_series_port_set_bits(const struct device *dev, gpio_port_pins_t pins)
1192 {
1193 return gpio_pca_series_port_write(dev, pins, pins, 0);
1194 }
1195
gpio_pca_series_port_clear_bits(const struct device * dev,gpio_port_pins_t pins)1196 static int gpio_pca_series_port_clear_bits(const struct device *dev, gpio_port_pins_t pins)
1197 {
1198 return gpio_pca_series_port_write(dev, pins, 0, 0);
1199 }
1200
gpio_pca_series_port_toggle_bits(const struct device * dev,gpio_port_pins_t pins)1201 static int gpio_pca_series_port_toggle_bits(const struct device *dev, gpio_port_pins_t pins)
1202 {
1203 return gpio_pca_series_port_write(dev, 0, 0, pins);
1204 }
1205
1206 #ifdef CONFIG_GPIO_PCA_SERIES_INTERRUPT
1207 /**
1208 * @brief Configure interrupt for device with software-compared interrupt edge
1209 *
1210 * @note This version is used by devices that does not have interrupt edge config
1211 * (aka PCA_HAS_INT_EXTEND), and relies on software to check the edge.
1212 * This applies to all pca(l)9xxx and pcal64xxa devices.
1213 * This will also configure interrupt mask register if the device has it.
1214 *
1215 * @param dev
1216 * @param pin
1217 * @param mode
1218 * @param trig
1219 * @return int
1220 */
gpio_pca_series_pin_interrupt_configure_standard(const struct device * dev,gpio_pin_t pin,enum gpio_int_mode mode,enum gpio_int_trig trig)1221 static int gpio_pca_series_pin_interrupt_configure_standard(
1222 const struct device *dev, gpio_pin_t pin, enum gpio_int_mode mode,
1223 enum gpio_int_trig trig)
1224 {
1225 const struct gpio_pca_series_config *cfg = dev->config;
1226 struct gpio_pca_series_data *data = dev->data;
1227 uint32_t int_rise, int_fall;
1228 uint32_t int_mask, input_latch;
1229 int ret = 0;
1230
1231 if (cfg->gpio_int.port == NULL) {
1232 return -ENOTSUP;
1233 }
1234 /* Device does not support level-triggered interrupts. */
1235 if (mode == GPIO_INT_MODE_LEVEL) {
1236 return -ENOTSUP;
1237 }
1238 if (k_is_in_isr()) {
1239 return -EWOULDBLOCK;
1240 }
1241
1242 k_sem_take(&data->lock, K_FOREVER);
1243
1244 /**
1245 * TODO: Only write 1 byte.
1246 *
1247 * The config api only configures 1 pin, so only need to write the
1248 * modified byte. Need to create new register & cache api to provide
1249 * single byte access.
1250 * This applies to: pin_configure, pin_interrupt_configure
1251 */
1252
1253 /** get current interrupt config */
1254 #ifdef CONFIG_GPIO_PCA_SERIES_CACHE_ALL
1255 /** read from cache even if this register is not present on device */
1256 ret = gpio_pca_series_reg_cache_read(dev, PCA_REG_TYPE_1B_INTERRUPT_RISE,
1257 (uint8_t *)&int_rise);
1258 if (ret) {
1259 goto out;
1260 }
1261 int_rise = sys_le32_to_cpu(int_rise);
1262 /** read from cache even if this register is not present on device */
1263 ret = gpio_pca_series_reg_cache_read(dev, PCA_REG_TYPE_1B_INTERRUPT_FALL,
1264 (uint8_t *)&int_fall);
1265 if (ret) {
1266 goto out;
1267 }
1268 int_fall = sys_le32_to_cpu(int_fall);
1269 #else
1270 int_rise = gpio_pca_series_reg_cache_mini_get(dev)->int_rise;
1271 int_fall = gpio_pca_series_reg_cache_mini_get(dev)->int_fall;
1272 #endif /* CONFIG_GPIO_PCA_SERIES_CACHE_ALL */
1273
1274 if (mode == GPIO_INT_MODE_DISABLED) {
1275 int_fall &= ~BIT(pin);
1276 int_rise &= ~BIT(pin);
1277 } else {
1278 if (trig == GPIO_INT_TRIG_BOTH) {
1279 int_fall |= BIT(pin);
1280 int_rise |= BIT(pin);
1281 } else if (trig == GPIO_INT_TRIG_LOW) {
1282 int_fall |= BIT(pin);
1283 int_rise &= ~BIT(pin);
1284 } else if (trig == GPIO_INT_TRIG_HIGH) {
1285 int_fall &= ~BIT(pin);
1286 int_rise |= BIT(pin);
1287 }
1288 }
1289
1290 int_mask = int_fall | int_rise;
1291 input_latch = ~int_mask;
1292
1293 #ifdef CONFIG_GPIO_PCA_SERIES_CACHE_ALL
1294 /** read from cache even if this register is not present on device */
1295 int_rise = sys_cpu_to_le32(int_rise);
1296 ret = gpio_pca_series_reg_cache_update(dev, PCA_REG_TYPE_1B_INTERRUPT_RISE,
1297 (uint8_t *)&int_rise);
1298 if (ret) {
1299 goto out;
1300 }
1301 /** read from cache even if this register is not present on device */
1302 int_fall = sys_cpu_to_le32(int_fall);
1303 ret = gpio_pca_series_reg_cache_update(dev, PCA_REG_TYPE_1B_INTERRUPT_FALL,
1304 (uint8_t *)&int_fall);
1305 if (ret) {
1306 goto out;
1307 }
1308 #else
1309 gpio_pca_series_reg_cache_mini_get(dev)->int_rise = int_rise;
1310 gpio_pca_series_reg_cache_mini_get(dev)->int_fall = int_fall;
1311 #endif /* CONFIG_GPIO_PCA_SERIES_CACHE_ALL */
1312
1313 /** enable latch if available, so we do not lost interrupt */
1314 if (cfg->part_cfg->flags & PCA_HAS_LATCH) {
1315 input_latch = sys_cpu_to_le32(input_latch);
1316 ret = gpio_pca_series_reg_write(dev, PCA_REG_TYPE_1B_INPUT_LATCH,
1317 (uint8_t *)&input_latch);
1318 if (ret) {
1319 goto out;
1320 }
1321 }
1322 /** update interrupt mask register if available */
1323 if (cfg->part_cfg->flags & PCA_HAS_INT_MASK) {
1324 int_mask = sys_cpu_to_le32(int_mask);
1325 ret = gpio_pca_series_reg_write(dev, PCA_REG_TYPE_1B_INTERRUPT_MASK,
1326 (uint8_t *)&int_mask);
1327 if (ret) {
1328 goto out;
1329 }
1330 }
1331
1332 out:
1333 k_sem_give(&data->lock);
1334
1335 if (ret) {
1336 LOG_ERR("int config(s) error %d", ret);
1337 }
1338 return ret;
1339 }
1340
1341 /**
1342 * @brief Configure interrupt for device with hardware-selected interrupt edge
1343 *
1344 * @note This version is used by devices that have interrupt edge config
1345 * (aka PCA_HAS_INT_EXTEND), so interrupt only triggers on selected edge.
1346 * This applies to all pcal65xx devices.
1347 * This will configure interrupt mask register and interrupt edge register.
1348 * (All devices that have PCA_HAS_INT_EXTEND flag should have PCA_HAS_INT_MASK
1349 * flag. Otherwise, throw out error.)
1350 */
gpio_pca_series_pin_interrupt_configure_extended(const struct device * dev,gpio_pin_t pin,enum gpio_int_mode mode,enum gpio_int_trig trig)1351 static int gpio_pca_series_pin_interrupt_configure_extended(
1352 const struct device *dev,
1353 gpio_pin_t pin, enum gpio_int_mode mode,
1354 enum gpio_int_trig trig)
1355 {
1356 const struct gpio_pca_series_config *cfg = dev->config;
1357 struct gpio_pca_series_data *data = dev->data;
1358 uint64_t int_edge;
1359 uint32_t int_mask, input_latch;
1360 int ret = 0;
1361 uint32_t edge_cfg_shift = pin << 1U;
1362 uint64_t edge_cfg_mask = 0b11 << edge_cfg_shift;
1363
1364 if (cfg->gpio_int.port == NULL) {
1365 return -ENOTSUP;
1366 }
1367 /* Device does not support level-triggered interrupts. */
1368 if (mode == GPIO_INT_MODE_LEVEL) {
1369 return -ENOTSUP;
1370 }
1371
1372 #ifdef GPIO_NXP_PCA_SERIES_DEBUG
1373 /**
1374 * Check the flags during runtime.
1375 *
1376 * The purpose is to check api assignment for developer who is adding
1377 * new device support to this driver.
1378 */
1379 const uint8_t check_flags = (PCA_HAS_LATCH | PCA_HAS_INT_MASK | PCA_HAS_INT_EXTEND);
1380
1381 if ((cfg->part_cfg->flags & check_flags) != check_flags) {
1382 LOG_ERR("unsupported device trying to configure interrupt with extended api");
1383 return -ENOTSUP;
1384 }
1385 #endif /* GPIO_NXP_PCA_SERIES_DEBUG */
1386
1387 if (k_is_in_isr()) {
1388 return -EWOULDBLOCK;
1389 }
1390
1391 LOG_DBG("int cfg(e) pin %d mode %d trig %d", pin, mode, trig);
1392
1393 k_sem_take(&data->lock, K_FOREVER);
1394
1395 /**
1396 * TODO: Only write 1 byte.
1397 *
1398 * The config api only configures 1 pin, so only need to write the
1399 * modified byte. Need to create new register & cache api to provide
1400 * single byte access.
1401 * This applies to: pin_configure, pin_interrupt_configure
1402 */
1403
1404 /** get current interrupt edge config */
1405 ret = gpio_pca_series_reg_cache_read(dev, PCA_REG_TYPE_2B_INTERRUPT_EDGE,
1406 (uint8_t *)&int_edge);
1407 if (ret) {
1408 LOG_ERR("get current interrupt edge config fail [%d]", ret);
1409 goto out;
1410 }
1411 int_edge = sys_le64_to_cpu(int_edge);
1412
1413 ret = gpio_pca_series_reg_cache_read(dev, PCA_REG_TYPE_1B_INTERRUPT_MASK,
1414 (uint8_t *)&int_mask);
1415 if (ret) {
1416 goto out;
1417 }
1418 int_mask = sys_le32_to_cpu(int_mask);
1419
1420 if (mode == GPIO_INT_MODE_DISABLED) {
1421 int_mask |= BIT(pin); /** set 1 to disable interrupt */
1422 } else {
1423 if (trig == GPIO_INT_TRIG_BOTH) {
1424 int_edge = (int_edge & (~edge_cfg_mask)) |
1425 (PCA_INTERRUPT_EITHER_EDGE << edge_cfg_shift);
1426 } else if (trig == GPIO_INT_TRIG_LOW) {
1427 int_edge = (int_edge & (~edge_cfg_mask)) |
1428 (PCA_INTERRUPT_FALLING_EDGE << edge_cfg_shift);
1429 } else if (trig == GPIO_INT_TRIG_HIGH) {
1430 int_edge = (int_edge & (~edge_cfg_mask)) |
1431 (PCA_INTERRUPT_RISING_EDGE << edge_cfg_shift);
1432 }
1433 int_mask &= ~BIT(pin); /** set 0 to enable interrupt */
1434 }
1435
1436 /** update interrupt edge config */
1437 int_edge = sys_cpu_to_le64(int_edge);
1438 ret = gpio_pca_series_reg_write(dev, PCA_REG_TYPE_2B_INTERRUPT_EDGE,
1439 (uint8_t *)&int_edge);
1440 if (ret) {
1441 goto out;
1442 }
1443 /** enable latch, so we do not lost interrupt */
1444 input_latch = ~int_mask;
1445 input_latch = sys_cpu_to_le32(input_latch);
1446 ret = gpio_pca_series_reg_write(dev, PCA_REG_TYPE_1B_INPUT_LATCH,
1447 (uint8_t *)&input_latch);
1448 if (ret) {
1449 goto out;
1450 }
1451 /** update interrupt mask register */
1452 int_mask = sys_cpu_to_le32(int_mask);
1453 ret = gpio_pca_series_reg_write(dev, PCA_REG_TYPE_1B_INTERRUPT_MASK,
1454 (uint8_t *)&int_mask);
1455 if (ret) {
1456 goto out;
1457 }
1458
1459 out:
1460 k_sem_give(&data->lock);
1461 return ret;
1462 }
1463
gpio_pca_series_manage_callback(const struct device * dev,struct gpio_callback * callback,bool set)1464 static int gpio_pca_series_manage_callback(const struct device *dev,
1465 struct gpio_callback *callback, bool set)
1466 {
1467 struct gpio_pca_series_data *data = dev->data;
1468
1469 return gpio_manage_callback(&data->callbacks, callback, set);
1470 }
1471
gpio_pca_series_interrupt_handler_standard(const struct device * dev,gpio_port_value_t * input_value)1472 static void gpio_pca_series_interrupt_handler_standard(const struct device *dev,
1473 gpio_port_value_t *input_value)
1474 {
1475 struct gpio_pca_series_data *data = dev->data;
1476 int ret = 0;
1477 uint32_t input_old, int_rise, int_fall;
1478 uint32_t input;
1479 uint32_t transitioned_pins;
1480 uint32_t int_status = 0;
1481
1482 k_sem_take(&data->lock, K_FOREVER);
1483
1484 #ifdef CONFIG_GPIO_PCA_SERIES_CACHE_ALL
1485 /** read from cache even if this register is not present on device */
1486 ret = gpio_pca_series_reg_cache_read(dev, PCA_REG_TYPE_1B_INPUT_HISTORY,
1487 (uint8_t *)&input_old);
1488 if (ret) {
1489 goto out;
1490 }
1491 input_old = sys_le32_to_cpu(input_old);
1492 /** read from cache even if this register is not present on device */
1493 ret = gpio_pca_series_reg_cache_read(dev, PCA_REG_TYPE_1B_INTERRUPT_RISE,
1494 (uint8_t *)&int_rise);
1495 if (ret) {
1496 goto out;
1497 }
1498 int_rise = sys_le32_to_cpu(int_rise);
1499 /** read from cache even if this register is not present on device */
1500 ret = gpio_pca_series_reg_cache_read(dev, PCA_REG_TYPE_1B_INTERRUPT_FALL,
1501 (uint8_t *)&int_fall);
1502 if (ret) {
1503 goto out;
1504 }
1505 int_fall = sys_le32_to_cpu(int_fall);
1506 #else
1507 input_old = gpio_pca_series_reg_cache_mini_get(dev)->input_old;
1508 int_rise = gpio_pca_series_reg_cache_mini_get(dev)->int_rise;
1509 int_fall = gpio_pca_series_reg_cache_mini_get(dev)->int_fall;
1510 #endif /* CONFIG_GPIO_PCA_SERIES_CACHE_ALL */
1511
1512 /** check if any interrupt enabled */
1513 if ((!int_rise) && (!int_fall)) {
1514 goto out;
1515 }
1516
1517 /** read current input value, and clear status if reg is present */
1518 ret = gpio_pca_series_reg_read(dev, PCA_REG_TYPE_1B_INPUT_PORT, (uint8_t *)&input);
1519 if (ret) {
1520 goto out;
1521 }
1522 input = sys_le32_to_cpu(input);
1523 /** compare input to input_old to get transitioned_pins */
1524 transitioned_pins = input_old ^ input;
1525
1526 /** Mask gpio transactions with rising/falling edge interrupt config */
1527 int_status = (int_rise & transitioned_pins & input)
1528 | (int_fall & transitioned_pins & (~input));
1529
1530 /** update current input to cache */
1531 #ifdef CONFIG_GPIO_PCA_SERIES_CACHE_ALL
1532 uint32_t input_le = sys_cpu_to_le32(input);
1533
1534 ret = gpio_pca_series_reg_cache_update(dev, PCA_REG_TYPE_1B_INPUT_HISTORY,
1535 (uint8_t *)&input_le);
1536 #else
1537 gpio_pca_series_reg_cache_mini_get(dev)->input_old = input;
1538 #endif /* CONFIG_GPIO_PCA_SERIES_CACHE_ALL */
1539
1540 out:
1541 k_sem_give(&data->lock);
1542
1543 if (input_value) {
1544 *input_value = input;
1545 }
1546 if ((ret == 0) && (int_status)) {
1547 gpio_fire_callbacks(&data->callbacks, dev, int_status);
1548 }
1549 }
1550
gpio_pca_series_interrupt_handler_extended(const struct device * dev)1551 static void gpio_pca_series_interrupt_handler_extended(const struct device *dev)
1552 {
1553 const struct gpio_pca_series_config *cfg = dev->config;
1554 struct gpio_pca_series_data *data = dev->data;
1555
1556 int ret = 0;
1557 uint32_t int_status = 0;
1558
1559 #ifdef GPIO_NXP_PCA_SERIES_DEBUG
1560 /**
1561 * Check the flags during runtime.
1562 *
1563 * The purpose is to check api assignment for developer who is adding
1564 * new device support to this driver.
1565 */
1566 const uint8_t check_flags = (PCA_HAS_LATCH | PCA_HAS_INT_MASK | PCA_HAS_INT_EXTEND);
1567
1568 if ((cfg->part_cfg->flags & check_flags) != check_flags) {
1569 LOG_ERR("unsupported device trying to read gpio with extended api");
1570 return;
1571 }
1572 #else
1573 ARG_UNUSED(cfg);
1574 #endif /* GPIO_NXP_PCA_SERIES_DEBUG */
1575
1576 LOG_DBG("enter int handler(e)");
1577
1578 k_sem_take(&data->lock, K_FOREVER);
1579
1580 /** get transitioned_pins from interrupt_status register */
1581 ret = gpio_pca_series_reg_read(dev, PCA_REG_TYPE_1B_INTERRUPT_STATUS,
1582 (uint8_t *)&int_status);
1583 if (ret) {
1584 goto out;
1585 }
1586
1587 /** clear status */
1588 ret = gpio_pca_series_reg_write(dev, PCA_REG_TYPE_1B_INTERRUPT_CLEAR,
1589 (uint8_t *)&int_status);
1590 if (ret) {
1591 goto out;
1592 }
1593
1594 out:
1595 k_sem_give(&data->lock);
1596
1597 if ((ret == 0) && (int_status)) {
1598 int_status = sys_le32_to_cpu(int_status);
1599 gpio_fire_callbacks(&data->callbacks, dev, int_status);
1600 }
1601 }
1602
gpio_pca_series_interrupt_worker_standard(struct k_work * work)1603 static void gpio_pca_series_interrupt_worker_standard(struct k_work *work)
1604 {
1605 struct gpio_pca_series_data *data =
1606 CONTAINER_OF(work, struct gpio_pca_series_data, int_work);
1607 const struct device *dev = data->self;
1608
1609 gpio_pca_series_interrupt_handler_standard(dev, NULL);
1610 }
1611
gpio_pca_series_interrupt_worker_extended(struct k_work * work)1612 static void gpio_pca_series_interrupt_worker_extended(struct k_work *work)
1613 {
1614 struct gpio_pca_series_data *data =
1615 CONTAINER_OF(work, struct gpio_pca_series_data, int_work);
1616 const struct device *dev = data->self;
1617
1618 gpio_pca_series_interrupt_handler_extended(dev);
1619 }
1620
gpio_pca_series_gpio_int_handler(const struct device * dev,struct gpio_callback * gpio_cb,uint32_t pins)1621 static void gpio_pca_series_gpio_int_handler(const struct device *dev,
1622 struct gpio_callback *gpio_cb, uint32_t pins)
1623 {
1624 ARG_UNUSED(dev);
1625 ARG_UNUSED(pins);
1626
1627 LOG_DBG("gpio_int trigger");
1628
1629 struct gpio_pca_series_data *data =
1630 CONTAINER_OF(gpio_cb, struct gpio_pca_series_data, gpio_cb);
1631
1632 k_work_submit(&data->int_work);
1633 }
1634
1635 #endif /* CONFIG_GPIO_PCA_SERIES_INTERRUPT */
1636
1637 /**
1638 * }
1639 * gpio_pca_zephyr_gpio_api
1640 */
1641
1642 static DEVICE_API(gpio, gpio_pca_series_api_funcs_standard) = {
1643 .pin_configure = gpio_pca_series_pin_configure,
1644 .port_get_raw = gpio_pca_series_port_read_standard,
1645 .port_set_masked_raw = gpio_pca_series_port_set_masked,
1646 .port_set_bits_raw = gpio_pca_series_port_set_bits,
1647 .port_clear_bits_raw = gpio_pca_series_port_clear_bits,
1648 .port_toggle_bits = gpio_pca_series_port_toggle_bits,
1649 #ifdef CONFIG_GPIO_PCA_SERIES_INTERRUPT
1650 .pin_interrupt_configure = gpio_pca_series_pin_interrupt_configure_standard,
1651 .manage_callback = gpio_pca_series_manage_callback,
1652 #endif
1653 };
1654
1655 static DEVICE_API(gpio, gpio_pca_series_api_funcs_extended) = {
1656 .pin_configure = gpio_pca_series_pin_configure,
1657 .port_get_raw = gpio_pca_series_port_read_extended, /* special version used */
1658 .port_set_masked_raw = gpio_pca_series_port_set_masked,
1659 .port_set_bits_raw = gpio_pca_series_port_set_bits,
1660 .port_clear_bits_raw = gpio_pca_series_port_clear_bits,
1661 .port_toggle_bits = gpio_pca_series_port_toggle_bits,
1662 #ifdef CONFIG_GPIO_PCA_SERIES_INTERRUPT
1663 .pin_interrupt_configure = gpio_pca_series_pin_interrupt_configure_extended,
1664 .manage_callback = gpio_pca_series_manage_callback,
1665 #endif
1666 };
1667
1668 /**
1669 * @brief Initialization function of pca_series
1670 *
1671 * This sets initial input/ output configuration and output states.
1672 * The interrupt is configured if this is enabled.
1673 *
1674 * @param dev Device struct
1675 * @return 0 if successful, failed otherwise.
1676 */
gpio_pca_series_init(const struct device * dev)1677 static int gpio_pca_series_init(const struct device *dev)
1678 {
1679 const struct gpio_pca_series_config *cfg = dev->config;
1680 struct gpio_pca_series_data *data = dev->data;
1681 int ret = 0;
1682
1683 if (!device_is_ready(cfg->i2c.bus)) {
1684 LOG_ERR("i2c bus device not found");
1685 goto out_bus;
1686 }
1687 #ifdef GPIO_NXP_PCA_SERIES_DEBUG
1688 # ifdef CONFIG_GPIO_PCA_SERIES_CACHE_ALL
1689 gpio_pca_series_cache_test(dev);
1690 # endif /* CONFIG_GPIO_PCA_SERIES_CACHE_ALL */
1691 #endif /* GPIO_NXP_PCA_SERIES_DEBUG */
1692
1693 /** Set cache to initial state */
1694 #ifdef CONFIG_GPIO_PCA_SERIES_CACHE_ALL
1695 ret = gpio_pca_series_reg_cache_reset(dev);
1696 #else
1697 ret = gpio_pca_series_reg_cache_mini_reset(dev);
1698 #endif /* CONFIG_GPIO_PCA_SERIES_CACHE_ALL */
1699 if (ret) {
1700 LOG_ERR("cache init error %d", ret);
1701 goto out;
1702 }
1703 LOG_DBG("cache init done");
1704
1705 /** device reset */
1706 gpio_pca_series_reset(dev);
1707 LOG_DBG("device reset done");
1708
1709 /** configure interrupt */
1710 #ifdef CONFIG_GPIO_PCA_SERIES_INTERRUPT
1711 /** save dev pointer */
1712 data->self = dev;
1713
1714 /** check the flags and init work obj */
1715 const uint8_t check_flags = (PCA_HAS_LATCH | PCA_HAS_INT_MASK | PCA_HAS_INT_EXTEND);
1716
1717 if ((cfg->part_cfg->flags & check_flags) == check_flags) {
1718 k_work_init(&data->int_work, gpio_pca_series_interrupt_worker_extended);
1719 } else {
1720 k_work_init(&data->int_work, gpio_pca_series_interrupt_worker_standard);
1721 }
1722
1723 /** Interrupt pin connected, enable interrupt */
1724 if (cfg->gpio_int.port != NULL) {
1725 if (!device_is_ready(cfg->gpio_int.port)) {
1726 LOG_ERR("Cannot get pointer to gpio interrupt device");
1727 ret = -EINVAL;
1728 goto out;
1729 }
1730
1731 ret = gpio_pin_configure_dt(&cfg->gpio_int, GPIO_INPUT);
1732 if (ret) {
1733 goto out;
1734 }
1735
1736 ret = gpio_pin_interrupt_configure_dt(&cfg->gpio_int, GPIO_INT_EDGE_TO_ACTIVE);
1737 if (ret) {
1738 goto out;
1739 }
1740
1741 gpio_init_callback(&data->gpio_cb, gpio_pca_series_gpio_int_handler,
1742 BIT(cfg->gpio_int.pin));
1743
1744 ret = gpio_add_callback(cfg->gpio_int.port, &data->gpio_cb);
1745 } else {
1746 LOG_WRN("pca interrupt enabled w/o int-gpios configured in dts");
1747 }
1748 #else
1749 ARG_UNUSED(data);
1750 #endif /* CONFIG_GPIO_PCA_SERIES_INTERRUPT */
1751
1752 out:
1753 #ifdef GPIO_NXP_PCA_SERIES_DEBUG
1754 gpio_pca_series_debug_dump(dev);
1755 #endif /* GPIO_NXP_PCA_SERIES_DEBUG */
1756
1757 out_bus:
1758 if (ret) {
1759 LOG_ERR("%s init failed: %d", dev->name, ret);
1760 } else {
1761 LOG_INF("%s init ok", dev->name);
1762 }
1763 return ret;
1764 }
1765
1766 /**
1767 * @brief get device description by part_no
1768 */
1769 #define GPIO_PCA_GET_API_BY_PART_NO(part_no) ( \
1770 (part_no == PCA_PART_NO_PCAL6524) ? &gpio_pca_series_api_funcs_extended : \
1771 (part_no == PCA_PART_NO_PCAL6534) ? &gpio_pca_series_api_funcs_extended : \
1772 &gpio_pca_series_api_funcs_standard \
1773 )
1774 #define GPIO_PCA_GET_PORT_NO_CFG_BY_PART_NO(part_no) (GPIO_PCA_PORT_NO_##part_no)
1775 #define GPIO_PCA_GET_PART_FLAG_BY_PART_NO(part_no) (GPIO_PCA_FLAG_##part_no)
1776 #define GPIO_PCA_GET_PART_CFG_BY_PART_NO(part_no) (GPIO_PCA_PART_CFG_##part_no)
1777
1778 #ifdef CONFIG_GPIO_PCA_SERIES_CACHE_ALL
1779
1780 /** Cache size increment by feature flags */
1781 #define PCA_REG_HAS_LATCH (3U) /* +2b_drive_strength, +1b_input_latch */
1782 #define PCA_REG_HAS_PULL (2U) /* +1b_pull_enable, +1b_pull_select */
1783 #define PCA_REG_HAS_OUT_CONFIG (1U) /* +1b_output_config */
1784
1785 #define GPIO_PCA_GET_CACHE_SIZE_BY_PART_NO_NO_INT(part_no) (( \
1786 2U /* basic: +output_port, +configuration */ \
1787 + ((GPIO_PCA_GET_PART_FLAG_BY_PART_NO(part_no) & PCA_HAS_LATCH) ? \
1788 PCA_REG_HAS_LATCH : 0U) \
1789 + ((GPIO_PCA_GET_PART_FLAG_BY_PART_NO(part_no) & PCA_HAS_PULL) ? \
1790 PCA_REG_HAS_PULL : 0U) \
1791 + ((GPIO_PCA_GET_PART_FLAG_BY_PART_NO(part_no) & PCA_HAS_OUT_CONFIG) ? \
1792 PCA_REG_HAS_OUT_CONFIG : 0U) \
1793 ) * GPIO_PCA_GET_PORT_NO_CFG_BY_PART_NO(part_no) \
1794 )
1795
1796 #ifdef CONFIG_GPIO_PCA_SERIES_INTERRUPT
1797
1798 /** Cache size increment by feature flags (continued) */
1799 #define PCA_REG_HAS_INT_EXTEND (3U) /* true: +2b_interrupt_edge, +1b_interrupt_mask */
1800 #define PCA_REG_NO_INT_EXTEND (3U) /* false: +1b_input_history, +1b_interrupt_rise,
1801 * +1b_interrupt_fall
1802 */
1803
1804 /**
1805 * registers:
1806 * 1b_input_port
1807 * - present on all devices
1808 * - not used if PCA_HAS_OUT_CONFIG
1809 * - non-cacheable
1810 * 1b_output_port
1811 * - present on all devices
1812 * - cacheable
1813 * 1b_configuration
1814 * - present on all devices
1815 * - cacheable
1816 * 2b_output_drive_strength
1817 * - present if PCA_HAS_LATCH
1818 * - cacheable if present
1819 * 1b_input_latch
1820 * - present if PCA_HAS_LATCH
1821 * - non-cacheable
1822 * 1b_pull_enable
1823 * - present if PCA_HAS_PULL
1824 * - cacheable if present
1825 * 1b_pull_select
1826 * - present if PCA_HAS_PULL
1827 * - cacheable if present
1828 * 1b_input_status
1829 * - present if PCA_HAS_OUT_CONFIG
1830 * - replaces 1b_input_port if present
1831 * - non-cacheable
1832 * 1b_output_config
1833 * - present if PCA_HAS_OUT_CONFIG
1834 * - cacheable if present
1835 * 1b_interrupt_mask
1836 * - present if PCA_HAS_INT_MASK
1837 * - not present by default
1838 * - cacheable if PCA_HAS_INT_EXTEND
1839 * 1b_interrupt_status
1840 * - present if PCA_HAS_INT_MASK
1841 * - not used if not PCA_HAS_INT_EXTEND
1842 * - read only
1843 * - non-cacheable
1844 * 2b_interrupt_edge
1845 * - present if PCA_HAS_INT_EXTEND
1846 * - cacheable if present
1847 * 1b_interrupt_clear
1848 * - present if PCA_HAS_INT_EXTEND
1849 * - write only
1850 * - non-cacheable
1851 * 1b_input_history
1852 * - not present on all devices (fake cache)
1853 * - store last input value
1854 * - cacheable (present) if not PCA_HAS_INT_EXTEND
1855 * 1b_interrupt_rise
1856 * - not present on all devices (fake cache)
1857 * - store pins interrupt on rising edge
1858 * - cacheable (present) if not PCA_HAS_INT_EXTEND
1859 * 1b_interrupt_fall
1860 * - not present on all devices (fake cache)
1861 * - store pins interrupt on falling edge
1862 * - cacheable (present) if not PCA_HAS_INT_EXTEND
1863 */
1864
1865 #define GPIO_PCA_GET_CACHE_SIZE_BY_PART_NO(part_no) ( \
1866 GPIO_PCA_GET_CACHE_SIZE_BY_PART_NO_NO_INT(part_no) \
1867 + (((GPIO_PCA_GET_PART_FLAG_BY_PART_NO(part_no) & PCA_HAS_INT_EXTEND) ? \
1868 PCA_REG_HAS_INT_EXTEND : PCA_REG_NO_INT_EXTEND) \
1869 ) * GPIO_PCA_GET_PORT_NO_CFG_BY_PART_NO(part_no) \
1870 )
1871 #else /* CONFIG_GPIO_PCA_SERIES_INTERRUPT */
1872 #define GPIO_PCA_GET_CACHE_SIZE_BY_PART_NO(part_no) ( \
1873 GPIO_PCA_GET_CACHE_SIZE_BY_PART_NO_NO_INT(part_no) \
1874 )
1875 #endif /* CONFIG_GPIO_PCA_SERIES_INTERRUPT */
1876 #endif /* CONFIG_GPIO_PCA_SERIES_CACHE_ALL */
1877
1878 /**
1879 * @brief implement pca953x driver
1880 *
1881 * @note flags = 0U;
1882 *
1883 * api set : standard
1884 * ngpios : 8, 16
1885 * part_no : pca9534 pca9538 pca9535 pca9539
1886 */
1887 #define GPIO_PCA_SERIES_FLAG_TYPE_0 (0U)
1888
1889 #ifdef CONFIG_GPIO_PCA_SERIES_CACHE_ALL
1890 /**
1891 * cache map for flag = 0U
1892 */
1893 static const uint8_t gpio_pca_series_cache_map_pca953x[] = {
1894 PCA_REG_INVALID, /** input_port if not PCA_HAS_OUT_CONFIG, non-cacheable */
1895 0x00, /** output_port */
1896 /* 0x02, polarity_inversion (unused, omitted) */
1897 0x01, /** configuration */
1898 PCA_REG_INVALID, /** 2b_output_drive_strength if PCA_HAS_LATCH*/
1899 PCA_REG_INVALID, /** input_latch if PCA_HAS_LATCH*/
1900 PCA_REG_INVALID, /** pull_enable if PCA_HAS_PULL */
1901 PCA_REG_INVALID, /** pull_select if PCA_HAS_PULL */
1902 PCA_REG_INVALID, /** input_status if PCA_HAS_OUT_CONFIG, non-cacheable */
1903 PCA_REG_INVALID, /** output_config if PCA_HAS_OUT_CONFIG */
1904 #ifdef CONFIG_GPIO_PCA_SERIES_INTERRUPT
1905 PCA_REG_INVALID, /** interrupt_mask if PCA_HAS_INT_MASK,
1906 * non-cacheable if not PCA_HAS_INT_EXTEND
1907 */
1908 PCA_REG_INVALID, /** int_status if PCA_HAS_INT_MASK, non-cacheable */
1909 PCA_REG_INVALID, /** 2b_interrupt_edge if PCA_HAS_INT_EXTEND */
1910 PCA_REG_INVALID, /** interrupt_clear if PCA_HAS_INT_EXTEND, non-cacheable */
1911 # ifdef CONFIG_GPIO_PCA_SERIES_CACHE_ALL
1912 0x02, /** 1b_input_history if PCA_HAS_LATCH and not PCA_HAS_INT_EXTEND */
1913 0x03, /** 1b_interrupt_rise if PCA_HAS_LATCH and not PCA_HAS_INT_EXTEND */
1914 0x04, /** 1b_interrupt_fall if PCA_HAS_LATCH and not PCA_HAS_INT_EXTEND */
1915 # endif /* CONFIG_GPIO_PCA_SERIES_CACHE_ALL */
1916 #endif /* CONFIG_GPIO_PCA_SERIES_INTERRUPT */
1917 };
1918 #endif /* CONFIG_GPIO_PCA_SERIES_CACHE_ALL */
1919
1920 static const uint8_t gpio_pca_series_reg_pca9538[] = {
1921 0x00, /** input_port if not PCA_HAS_OUT_CONFIG, non-cacheable */
1922 0x01, /** output_port */
1923 /* 0x02, polarity_inversion (unused, omitted) */
1924 0x03, /** configuration */
1925 PCA_REG_INVALID, /** 2b_output_drive_strength if PCA_HAS_LATCH*/
1926 PCA_REG_INVALID, /** input_latch if PCA_HAS_LATCH*/
1927 PCA_REG_INVALID, /** pull_enable if PCA_HAS_PULL */
1928 PCA_REG_INVALID, /** pull_select if PCA_HAS_PULL */
1929 PCA_REG_INVALID, /** input_status if PCA_HAS_OUT_CONFIG, non-cacheable */
1930 PCA_REG_INVALID, /** output_config if PCA_HAS_OUT_CONFIG */
1931 #ifdef CONFIG_GPIO_PCA_SERIES_INTERRUPT
1932 PCA_REG_INVALID, /** interrupt_mask if PCA_HAS_INT_MASK,
1933 * non-cacheable if not PCA_HAS_INT_EXTEND
1934 */
1935 PCA_REG_INVALID, /** int_status if PCA_HAS_INT_MASK */
1936 PCA_REG_INVALID, /** 2b_interrupt_edge if PCA_HAS_INT_EXTEND */
1937 PCA_REG_INVALID, /** interrupt_clear if PCA_HAS_INT_EXTEND, non-cacheable */
1938 # ifdef CONFIG_GPIO_PCA_SERIES_CACHE_ALL
1939 PCA_REG_INVALID, /** 1b_input_history if PCA_HAS_LATCH and not PCA_HAS_INT_EXTEND */
1940 PCA_REG_INVALID, /** 1b_interrupt_rise if PCA_HAS_LATCH and not PCA_HAS_INT_EXTEND */
1941 PCA_REG_INVALID, /** 1b_interrupt_fall if PCA_HAS_LATCH and not PCA_HAS_INT_EXTEND */
1942 # endif /* CONFIG_GPIO_PCA_SERIES_CACHE_ALL */
1943 #endif /* CONFIG_GPIO_PCA_SERIES_INTERRUPT */
1944 };
1945
1946 #define GPIO_PCA_PORT_NO_PCA_PART_NO_PCA9538 (1U)
1947 #define GPIO_PCA_FLAG_PCA_PART_NO_PCA9538 GPIO_PCA_SERIES_FLAG_TYPE_0
1948 #define GPIO_PCA_PART_CFG_PCA_PART_NO_PCA9538 (&gpio_pca_series_part_cfg_pca9538)
1949
1950 const struct gpio_pca_series_part_config gpio_pca_series_part_cfg_pca9538 = {
1951 .port_no = GPIO_PCA_PORT_NO_PCA_PART_NO_PCA9538,
1952 .flags = GPIO_PCA_FLAG_PCA_PART_NO_PCA9538,
1953 .regs = gpio_pca_series_reg_pca9538,
1954 #ifdef CONFIG_GPIO_PCA_SERIES_CACHE_ALL
1955 # ifdef GPIO_NXP_PCA_SERIES_DEBUG
1956 .cache_size = GPIO_PCA_GET_CACHE_SIZE_BY_PART_NO(PCA_PART_NO_PCA9538),
1957 # endif /* GPIO_NXP_PCA_SERIES_DEBUG */
1958 .cache_map = gpio_pca_series_cache_map_pca953x,
1959 #endif /* CONFIG_GPIO_PCA_SERIES_CACHE_ALL */
1960 };
1961
1962 /**
1963 * pca9555 share the same register layout with pca9539, with
1964 * RESET pin repurposed to another address strapping pin.
1965 * no difference from driver perspective.
1966 */
1967
1968 #define GPIO_PCA_PORT_NO_PCA_PART_NO_PCA9554 GPIO_PCA_PORT_NO_PCA_PART_NO_PCA9538
1969 #define GPIO_PCA_FLAG_PCA_PART_NO_PCA9554 GPIO_PCA_FLAG_PCA_PART_NO_PCA9538
1970 #define GPIO_PCA_PART_CFG_PCA_PART_NO_PCA9554 (&gpio_pca_series_part_cfg_pca9554)
1971
1972 const struct gpio_pca_series_part_config gpio_pca_series_part_cfg_pca9554 = {
1973 .port_no = GPIO_PCA_PORT_NO_PCA_PART_NO_PCA9554,
1974 .flags = GPIO_PCA_FLAG_PCA_PART_NO_PCA9554,
1975 .regs = gpio_pca_series_reg_pca9538,
1976 #ifdef CONFIG_GPIO_PCA_SERIES_CACHE_ALL
1977 # ifdef GPIO_NXP_PCA_SERIES_DEBUG
1978 .cache_size = GPIO_PCA_GET_CACHE_SIZE_BY_PART_NO(PCA_PART_NO_PCA9554),
1979 # endif /* GPIO_NXP_PCA_SERIES_DEBUG */
1980 .cache_map = gpio_pca_series_cache_map_pca953x,
1981 #endif /* CONFIG_GPIO_PCA_SERIES_CACHE_ALL */
1982 };
1983
1984 static const uint8_t gpio_pca_series_reg_pca9539[] = {
1985 0x00, /** input_port if not PCA_HAS_OUT_CONFIG, non-cacheable */
1986 0x02, /** output_port */
1987 /* 0x04, polarity_inversion (unused, omitted) */
1988 0x06, /** configuration */
1989 PCA_REG_INVALID, /** 2b_output_drive_strength if PCA_HAS_LATCH*/
1990 PCA_REG_INVALID, /** input_latch if PCA_HAS_LATCH*/
1991 PCA_REG_INVALID, /** pull_enable if PCA_HAS_PULL */
1992 PCA_REG_INVALID, /** pull_select if PCA_HAS_PULL */
1993 PCA_REG_INVALID, /** input_status if PCA_HAS_OUT_CONFIG, non-cacheable */
1994 PCA_REG_INVALID, /** output_config if PCA_HAS_OUT_CONFIG */
1995 #ifdef CONFIG_GPIO_PCA_SERIES_INTERRUPT
1996 PCA_REG_INVALID, /** interrupt_mask if PCA_HAS_INT_MASK,
1997 * non-cacheable if not PCA_HAS_INT_EXTEND
1998 */
1999 PCA_REG_INVALID, /** int_status if PCA_HAS_INT_MASK */
2000 PCA_REG_INVALID, /** 2b_interrupt_edge if PCA_HAS_INT_EXTEND */
2001 PCA_REG_INVALID, /** interrupt_clear if PCA_HAS_INT_EXTEND, non-cacheable */
2002 # ifdef CONFIG_GPIO_PCA_SERIES_CACHE_ALL
2003 PCA_REG_INVALID, /** 1b_input_history if PCA_HAS_LATCH and not PCA_HAS_INT_EXTEND */
2004 PCA_REG_INVALID, /** 1b_interrupt_rise if PCA_HAS_LATCH and not PCA_HAS_INT_EXTEND */
2005 PCA_REG_INVALID, /** 1b_interrupt_fall if PCA_HAS_LATCH and not PCA_HAS_INT_EXTEND */
2006 # endif /* CONFIG_GPIO_PCA_SERIES_CACHE_ALL */
2007 #endif /* CONFIG_GPIO_PCA_SERIES_INTERRUPT */
2008 };
2009
2010 #define GPIO_PCA_PORT_NO_PCA_PART_NO_PCA9539 (2U)
2011 #define GPIO_PCA_FLAG_PCA_PART_NO_PCA9539 GPIO_PCA_SERIES_FLAG_TYPE_0
2012 #define GPIO_PCA_PART_CFG_PCA_PART_NO_PCA9539 (&gpio_pca_series_part_cfg_pca9539)
2013
2014 const struct gpio_pca_series_part_config gpio_pca_series_part_cfg_pca9539 = {
2015 .port_no = GPIO_PCA_PORT_NO_PCA_PART_NO_PCA9539,
2016 .flags = GPIO_PCA_FLAG_PCA_PART_NO_PCA9539,
2017 .regs = gpio_pca_series_reg_pca9539,
2018 #ifdef CONFIG_GPIO_PCA_SERIES_CACHE_ALL
2019 # ifdef GPIO_NXP_PCA_SERIES_DEBUG
2020 .cache_size = GPIO_PCA_GET_CACHE_SIZE_BY_PART_NO(PCA_PART_NO_PCA9539),
2021 # endif /* GPIO_NXP_PCA_SERIES_DEBUG */
2022 .cache_map = gpio_pca_series_cache_map_pca953x,
2023 #endif /* CONFIG_GPIO_PCA_SERIES_CACHE_ALL */
2024 };
2025
2026 /**
2027 * pca9555 share the same register layout with pca9539, with
2028 * RESET pin repurposed to another address strapping pin.
2029 * no difference from driver perspective.
2030 */
2031
2032 #define GPIO_PCA_PORT_NO_PCA_PART_NO_PCA9555 GPIO_PCA_PORT_NO_PCA_PART_NO_PCA9539
2033 #define GPIO_PCA_FLAG_PCA_PART_NO_PCA9555 GPIO_PCA_FLAG_PCA_PART_NO_PCA9539
2034 #define GPIO_PCA_PART_CFG_PCA_PART_NO_PCA9555 (&gpio_pca_series_part_cfg_pca9555)
2035
2036 const struct gpio_pca_series_part_config gpio_pca_series_part_cfg_pca9555 = {
2037 .port_no = GPIO_PCA_PORT_NO_PCA_PART_NO_PCA9555,
2038 .flags = GPIO_PCA_FLAG_PCA_PART_NO_PCA9555,
2039 .regs = gpio_pca_series_reg_pca9539,
2040 #ifdef CONFIG_GPIO_PCA_SERIES_CACHE_ALL
2041 # ifdef GPIO_NXP_PCA_SERIES_DEBUG
2042 .cache_size = GPIO_PCA_GET_CACHE_SIZE_BY_PART_NO(PCA_PART_NO_PCA9555),
2043 # endif /* GPIO_NXP_PCA_SERIES_DEBUG */
2044 .cache_map = gpio_pca_series_cache_map_pca953x,
2045 #endif /* CONFIG_GPIO_PCA_SERIES_CACHE_ALL */
2046 };
2047
2048 /**
2049 * @brief implement pcal65xx driver
2050 *
2051 * @note flags = PCA_HAS_LATCH
2052 * | PCA_HAS_PULL
2053 * | PCA_HAS_INT_MASK
2054 * | PCA_HAS_INT_EXTEND
2055 * | PCA_HAS_OUT_CONFIG
2056 *
2057 * api set : pcal65xx
2058 * ngpios : 24, 32
2059 * part_no : pcal6524 pcal6534
2060 */
2061 #define GPIO_PCA_SERIES_FLAG_TYPE_3 (PCA_HAS_LATCH | PCA_HAS_PULL | PCA_HAS_INT_MASK \
2062 | PCA_HAS_INT_EXTEND | PCA_HAS_OUT_CONFIG)
2063
2064 #ifdef CONFIG_GPIO_PCA_SERIES_CACHE_ALL
2065 /**
2066 * cache map for flag = PCA_HAS_LATCH
2067 * | PCA_HAS_PULL
2068 * | PCA_HAS_INT_MASK
2069 * | PCA_HAS_INT_EXTEND
2070 * | PCA_HAS_OUT_CONFIG
2071 */
2072 static const uint8_t gpio_pca_series_cache_map_pcal65xx[] = {
2073 PCA_REG_INVALID, /** input_port if not PCA_HAS_OUT_CONFIG, non-cacheable */
2074 0x00, /** output_port */
2075 /* 0x02, polarity_inversion (unused, omitted) */
2076 0x01, /** configuration */
2077 0x02, /** 2b_output_drive_strength if PCA_HAS_LATCH*/
2078 0x04, /** input_latch if PCA_HAS_LATCH*/
2079 0x05, /** pull_enable if PCA_HAS_PULL */
2080 0x06, /** pull_select if PCA_HAS_PULL */
2081 PCA_REG_INVALID, /** input_status if PCA_HAS_OUT_CONFIG, non-cacheable */
2082 0x07, /** output_config if PCA_HAS_OUT_CONFIG */
2083 #ifdef CONFIG_GPIO_PCA_SERIES_INTERRUPT
2084 0x08, /** interrupt_mask if PCA_HAS_INT_MASK,
2085 * non-cacheable if not PCA_HAS_INT_EXTEND
2086 */
2087 PCA_REG_INVALID, /** int_status if PCA_HAS_INT_MASK, non-cacheable */
2088 0x09, /** 2b_interrupt_edge if PCA_HAS_INT_EXTEND */
2089 PCA_REG_INVALID, /** interrupt_clear if PCA_HAS_INT_EXTEND, non-cacheable */
2090 # ifdef CONFIG_GPIO_PCA_SERIES_CACHE_ALL
2091 PCA_REG_INVALID, /** 1b_input_history if PCA_HAS_LATCH and not PCA_HAS_INT_EXTEND */
2092 PCA_REG_INVALID, /** 1b_interrupt_rise if PCA_HAS_LATCH and not PCA_HAS_INT_EXTEND */
2093 PCA_REG_INVALID, /** 1b_interrupt_fall if PCA_HAS_LATCH and not PCA_HAS_INT_EXTEND */
2094 # endif /* CONFIG_GPIO_PCA_SERIES_CACHE_ALL */
2095 #endif /* CONFIG_GPIO_PCA_SERIES_INTERRUPT */
2096 };
2097 #endif /* CONFIG_GPIO_PCA_SERIES_CACHE_ALL */
2098
2099 static const uint8_t gpio_pca_series_reg_pcal6524[] = {
2100 PCA_REG_INVALID, /** input_port if not PCA_HAS_OUT_CONFIG, non-cacheable */
2101 0x04, /** output_port */
2102 /* 0x08, polarity_inversion (unused, omitted) */
2103 0x0c, /** configuration */
2104 0x40, /** 2b_output_drive_strength if PCA_HAS_LATCH*/
2105 0x48, /** input_latch if PCA_HAS_LATCH*/
2106 0x4c, /** pull_enable if PCA_HAS_PULL */
2107 0x50, /** pull_select if PCA_HAS_PULL */
2108 0x6c, /** input_status if PCA_HAS_OUT_CONFIG, non-cacheable */
2109 0x70, /** output_config if PCA_HAS_OUT_CONFIG */
2110 #ifdef CONFIG_GPIO_PCA_SERIES_INTERRUPT
2111 0x54, /** interrupt_mask if PCA_HAS_INT_MASK,
2112 * non-cacheable if not PCA_HAS_INT_EXTEND
2113 */
2114 0x58, /** int_status if PCA_HAS_INT_MASK */
2115 0x60, /** 2b_interrupt_edge if PCA_HAS_INT_EXTEND */
2116 0x68, /** interrupt_clear if PCA_HAS_INT_EXTEND, non-cacheable */
2117 # ifdef CONFIG_GPIO_PCA_SERIES_CACHE_ALL
2118 PCA_REG_INVALID, /** 1b_input_history if PCA_HAS_LATCH and not PCA_HAS_INT_EXTEND */
2119 PCA_REG_INVALID, /** 1b_interrupt_rise if PCA_HAS_LATCH and not PCA_HAS_INT_EXTEND */
2120 PCA_REG_INVALID, /** 1b_interrupt_fall if PCA_HAS_LATCH and not PCA_HAS_INT_EXTEND */
2121 # endif /* CONFIG_GPIO_PCA_SERIES_CACHE_ALL */
2122 #endif /* CONFIG_GPIO_PCA_SERIES_INTERRUPT */
2123 };
2124
2125 #define GPIO_PCA_PORT_NO_PCA_PART_NO_PCAL6524 (3U)
2126 #define GPIO_PCA_FLAG_PCA_PART_NO_PCAL6524 GPIO_PCA_SERIES_FLAG_TYPE_3
2127 #define GPIO_PCA_PART_CFG_PCA_PART_NO_PCAL6524 (&gpio_pca_series_part_cfg_pcal6524)
2128
2129 const struct gpio_pca_series_part_config gpio_pca_series_part_cfg_pcal6524 = {
2130 .port_no = GPIO_PCA_PORT_NO_PCA_PART_NO_PCAL6524,
2131 .flags = GPIO_PCA_FLAG_PCA_PART_NO_PCAL6524,
2132 .regs = gpio_pca_series_reg_pcal6524,
2133 #ifdef CONFIG_GPIO_PCA_SERIES_CACHE_ALL
2134 # ifdef GPIO_NXP_PCA_SERIES_DEBUG
2135 .cache_size = GPIO_PCA_GET_CACHE_SIZE_BY_PART_NO(PCA_PART_NO_PCAL6524),
2136 # endif /* GPIO_NXP_PCA_SERIES_DEBUG */
2137 .cache_map = gpio_pca_series_cache_map_pcal65xx,
2138 #endif /* CONFIG_GPIO_PCA_SERIES_CACHE_ALL */
2139 };
2140
2141 static const uint8_t gpio_pca_series_reg_pcal6534[] = {
2142 PCA_REG_INVALID, /** input_port if not PCA_HAS_OUT_CONFIG, non-cacheable */
2143 0x04, /** output_port */
2144 /* 0x08, polarity_inversion (unused, omitted) */
2145 0x0c, /** configuration */
2146 0x40, /** 2b_output_drive_strength if PCA_HAS_LATCH*/
2147 0x48, /** input_latch if PCA_HAS_LATCH*/
2148 0x4c, /** pull_enable if PCA_HAS_PULL */
2149 0x50, /** pull_select if PCA_HAS_PULL */
2150 0x6c, /** input_status if PCA_HAS_OUT_CONFIG, non-cacheable */
2151 0x70, /** output_config if PCA_HAS_OUT_CONFIG */
2152 #ifdef CONFIG_GPIO_PCA_SERIES_INTERRUPT
2153 0x54, /** interrupt_mask if PCA_HAS_INT_MASK,
2154 * non-cacheable if not PCA_HAS_INT_EXTEND
2155 */
2156 0x58, /** int_status if PCA_HAS_INT_MASK */
2157 0x60, /** 2b_interrupt_edge if PCA_HAS_INT_EXTEND */
2158 0x68, /** interrupt_clear if PCA_HAS_INT_EXTEND, non-cacheable */
2159 # ifdef CONFIG_GPIO_PCA_SERIES_CACHE_ALL
2160 PCA_REG_INVALID, /** 1b_input_history if PCA_HAS_LATCH and not PCA_HAS_INT_EXTEND */
2161 PCA_REG_INVALID, /** 1b_interrupt_rise if PCA_HAS_LATCH and not PCA_HAS_INT_EXTEND */
2162 PCA_REG_INVALID, /** 1b_interrupt_fall if PCA_HAS_LATCH and not PCA_HAS_INT_EXTEND */
2163 # endif /* CONFIG_GPIO_PCA_SERIES_CACHE_ALL */
2164 #endif /* CONFIG_GPIO_PCA_SERIES_INTERRUPT */
2165 };
2166
2167 #define GPIO_PCA_PORT_NO_PCA_PART_NO_PCAL6534 (4U)
2168 #define GPIO_PCA_FLAG_PCA_PART_NO_PCAL6534 GPIO_PCA_SERIES_FLAG_TYPE_3
2169 #define GPIO_PCA_PART_CFG_PCA_PART_NO_PCAL6534 (&gpio_pca_series_part_cfg_pcal6534)
2170
2171 const struct gpio_pca_series_part_config gpio_pca_series_part_cfg_pcal6534 = {
2172 .port_no = GPIO_PCA_PORT_NO_PCA_PART_NO_PCAL6534,
2173 .flags = GPIO_PCA_FLAG_PCA_PART_NO_PCAL6534,
2174 .regs = gpio_pca_series_reg_pcal6534,
2175 #ifdef CONFIG_GPIO_PCA_SERIES_CACHE_ALL
2176 # ifdef GPIO_NXP_PCA_SERIES_DEBUG
2177 .cache_size = GPIO_PCA_GET_CACHE_SIZE_BY_PART_NO(PCA_PART_NO_PCAL6534),
2178 # endif /* GPIO_NXP_PCA_SERIES_DEBUG */
2179 .cache_map = gpio_pca_series_cache_map_pcal65xx,
2180 #endif /* CONFIG_GPIO_PCA_SERIES_CACHE_ALL */
2181 };
2182
2183 /**
2184 * @brief common device instance
2185 *
2186 */
2187 #define GPIO_PCA_SERIES_DEVICE_INSTANCE(inst, part_no) \
2188 static const struct gpio_pca_series_config gpio_##part_no##_##inst##_cfg = { \
2189 .common = { \
2190 .port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(inst), \
2191 }, \
2192 .i2c = I2C_DT_SPEC_INST_GET(inst), \
2193 .part_cfg = GPIO_PCA_GET_PART_CFG_BY_PART_NO(part_no), \
2194 .gpio_rst = GPIO_DT_SPEC_INST_GET_OR(inst, reset_gpios, {}), \
2195 IF_ENABLED(CONFIG_GPIO_PCA_SERIES_INTERRUPT, \
2196 (.gpio_int = GPIO_DT_SPEC_INST_GET_OR(inst, int_gpios, {}),)) \
2197 }; \
2198 static uint8_t gpio_##part_no##_##inst##_reg_cache[COND_CODE_1( \
2199 CONFIG_GPIO_PCA_SERIES_CACHE_ALL, \
2200 (GPIO_PCA_GET_CACHE_SIZE_BY_PART_NO(part_no) /** true */\
2201 ), \
2202 (sizeof(struct gpio_pca_series_reg_cache_mini) /** false */ \
2203 ))]; \
2204 static struct gpio_pca_series_data gpio_##part_no##_##inst##_data = { \
2205 .lock = Z_SEM_INITIALIZER(gpio_##part_no##_##inst##_data.lock, 1, 1), \
2206 .cache = (void *)gpio_##part_no##_##inst##_reg_cache, \
2207 }; \
2208 DEVICE_DT_INST_DEFINE(inst, gpio_pca_series_init, NULL, \
2209 &gpio_##part_no##_##inst##_data, \
2210 &gpio_##part_no##_##inst##_cfg, POST_KERNEL, \
2211 CONFIG_GPIO_PCA_SERIES_INIT_PRIORITY, \
2212 GPIO_PCA_GET_API_BY_PART_NO(part_no));
2213
2214
2215 #undef DT_DRV_COMPAT
2216 #define DT_DRV_COMPAT nxp_pca9538
2217 DT_INST_FOREACH_STATUS_OKAY_VARGS(GPIO_PCA_SERIES_DEVICE_INSTANCE, PCA_PART_NO_PCA9538)
2218
2219 #undef DT_DRV_COMPAT
2220 #define DT_DRV_COMPAT nxp_pca9539
2221 DT_INST_FOREACH_STATUS_OKAY_VARGS(GPIO_PCA_SERIES_DEVICE_INSTANCE, PCA_PART_NO_PCA9539)
2222
2223 #undef DT_DRV_COMPAT
2224 #define DT_DRV_COMPAT nxp_pca9554
2225 DT_INST_FOREACH_STATUS_OKAY_VARGS(GPIO_PCA_SERIES_DEVICE_INSTANCE, PCA_PART_NO_PCA9554)
2226
2227 #undef DT_DRV_COMPAT
2228 #define DT_DRV_COMPAT nxp_pca9555
2229 DT_INST_FOREACH_STATUS_OKAY_VARGS(GPIO_PCA_SERIES_DEVICE_INSTANCE, PCA_PART_NO_PCA9555)
2230
2231 #undef DT_DRV_COMPAT
2232 #define DT_DRV_COMPAT nxp_pcal6524
2233 DT_INST_FOREACH_STATUS_OKAY_VARGS(GPIO_PCA_SERIES_DEVICE_INSTANCE, PCA_PART_NO_PCAL6524)
2234
2235 #undef DT_DRV_COMPAT
2236 #define DT_DRV_COMPAT nxp_pcal6534
2237 DT_INST_FOREACH_STATUS_OKAY_VARGS(GPIO_PCA_SERIES_DEVICE_INSTANCE, PCA_PART_NO_PCAL6534)
2238