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 *)&reg_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 *)&reg_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 *)&reg_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 *)&reg_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 *)&reg_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 *)&reg_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 *)&reg_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 *)&reg_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 *)&reg_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 *)&reg_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