Lines Matching +full:has +full:- +full:interrupt +full:- +full:mask +full:- +full:reg
4 * SPDX-License-Identifier: Apache-2.0
63 * @param reg Address of the first of 3 registers to be read.
70 static int read_port_regs(const struct device *dev, uint8_t reg, uint32_t *buf) in read_port_regs() argument
72 const struct tca6424a_drv_cfg *const config = dev->config; in read_port_regs()
76 ret = i2c_burst_read_dt(&config->i2c_spec, reg, (uint8_t *)&port_data, 3); in read_port_regs()
78 LOG_ERR("%s: error reading register 0x%X (%d)", dev->name, in read_port_regs()
79 reg, ret); in read_port_regs()
85 LOG_DBG("%s: Read: REG[0x%X] = 0x%X, REG[0x%X] = 0x%X, " in read_port_regs()
86 "REG[0x%X] = 0x%X", in read_port_regs()
87 dev->name, reg, (*buf & 0xFF), (reg + 1), ((*buf >> 8) & 0xFF), in read_port_regs()
88 (reg + 2), ((*buf >> 16) & 0xFF)); in read_port_regs()
98 * @param reg Address of the first of 3 registers to be written.
105 static int write_port_regs(const struct device *dev, uint8_t reg, uint32_t value) in write_port_regs() argument
107 const struct tca6424a_drv_cfg *const config = dev->config; in write_port_regs()
111 LOG_DBG("%s: Write: REG[0x%X] = 0x%X, REG[0x%X] = 0x%X, " in write_port_regs()
112 "REG[0x%X] = 0x%X", in write_port_regs()
113 dev->name, reg, (value & 0xFF), (reg + 1), ((value >> 8) & 0xFF), in write_port_regs()
114 (reg + 2), ((value >> 16) & 0xFF)); in write_port_regs()
116 buf[0] = reg; in write_port_regs()
118 ret = i2c_write_dt(&config->i2c_spec, buf, sizeof(buf)); in write_port_regs()
122 dev->name, reg, ret); in write_port_regs()
130 struct tca6424a_drv_data *const drv_data = dev->data; in update_input_regs()
134 drv_data->pins_state.input = *buf; in update_input_regs()
143 struct tca6424a_drv_data *const drv_data = dev->data; in update_output_regs()
147 drv_data->pins_state.output = value; in update_output_regs()
161 struct tca6424a_drv_data *const drv_data = dev->data; in update_config_regs()
165 drv_data->pins_state.config = value; in update_config_regs()
172 * @brief Handles interrupt triggered by the interrupt pin of TCA6424A.
176 * read in this function which clears the interrupt.
182 struct tca6424a_drv_data *drv_data = dev->data; in tca6424a_handle_interrupt()
183 struct tca6424a_irq_state *irq_state = &drv_data->irq_state; in tca6424a_handle_interrupt()
190 k_sem_take(&drv_data->lock, K_FOREVER); in tca6424a_handle_interrupt()
193 if (!irq_state->rising && !irq_state->falling) { in tca6424a_handle_interrupt()
194 k_sem_give(&drv_data->lock); in tca6424a_handle_interrupt()
199 previous_state = drv_data->pins_state.input; in tca6424a_handle_interrupt()
202 k_sem_give(&drv_data->lock); in tca6424a_handle_interrupt()
209 /* Mask gpio transactions with rising/falling edge interrupt config */ in tca6424a_handle_interrupt()
210 interrupt_status = (irq_state->rising & transitioned_pins & current_state); in tca6424a_handle_interrupt()
211 interrupt_status |= (irq_state->falling & transitioned_pins & previous_state); in tca6424a_handle_interrupt()
212 k_sem_give(&drv_data->lock); in tca6424a_handle_interrupt()
215 gpio_fire_callbacks(&drv_data->callbacks, dev, interrupt_status); in tca6424a_handle_interrupt()
220 * @brief Work handler for TCA6424A interrupt
222 * @param work Work struct that contains pointer to interrupt handler function
228 tca6424a_handle_interrupt(drv_data->dev); in tca6424a_work_handler()
232 * @brief ISR for interrupt pin of TCA6424A
236 * @param pins Bitmask of pins that triggered interrupt
247 k_work_submit(&drv_data->work); in tca6424a_int_gpio_handler()
252 struct tca6424a_drv_data *const drv_data = dev->data; in tca6424a_setup_pin()
253 uint32_t reg_cfg = drv_data->pins_state.config; in tca6424a_setup_pin()
254 uint32_t reg_out = drv_data->pins_state.output; in tca6424a_setup_pin()
281 struct tca6424a_drv_data *const drv_data = dev->data; in tca6424a_pin_config()
285 return -ENOTSUP; in tca6424a_pin_config()
290 return -ENOTSUP; in tca6424a_pin_config()
293 /* The TCA6424A has no internal pull up support */ in tca6424a_pin_config()
295 return -ENOTSUP; in tca6424a_pin_config()
300 return -ENOTSUP; in tca6424a_pin_config()
305 return -EWOULDBLOCK; in tca6424a_pin_config()
308 k_sem_take(&drv_data->lock, K_FOREVER); in tca6424a_pin_config()
312 LOG_ERR("%s: error setting pin direction (%d)", dev->name, ret); in tca6424a_pin_config()
315 k_sem_give(&drv_data->lock); in tca6424a_pin_config()
321 struct tca6424a_drv_data *const drv_data = dev->data; in tca6424a_port_get_raw()
327 return -EWOULDBLOCK; in tca6424a_port_get_raw()
330 k_sem_take(&drv_data->lock, K_FOREVER); in tca6424a_port_get_raw()
337 k_sem_give(&drv_data->lock); in tca6424a_port_get_raw()
341 static int tca6424a_port_set_masked_raw(const struct device *dev, gpio_port_pins_t mask, in tca6424a_port_set_masked_raw() argument
344 struct tca6424a_drv_data *const drv_data = dev->data; in tca6424a_port_set_masked_raw()
350 return -EWOULDBLOCK; in tca6424a_port_set_masked_raw()
353 k_sem_take(&drv_data->lock, K_FOREVER); in tca6424a_port_set_masked_raw()
355 reg_out = drv_data->pins_state.output; in tca6424a_port_set_masked_raw()
356 reg_out = (reg_out & ~mask) | (mask & value); in tca6424a_port_set_masked_raw()
360 k_sem_give(&drv_data->lock); in tca6424a_port_set_masked_raw()
365 static int tca6424a_port_set_bits_raw(const struct device *dev, gpio_port_pins_t mask) in tca6424a_port_set_bits_raw() argument
367 return tca6424a_port_set_masked_raw(dev, mask, mask); in tca6424a_port_set_bits_raw()
370 static int tca6424a_port_clear_bits_raw(const struct device *dev, gpio_port_pins_t mask) in tca6424a_port_clear_bits_raw() argument
372 return tca6424a_port_set_masked_raw(dev, mask, 0); in tca6424a_port_clear_bits_raw()
375 static int tca6424a_port_toggle_bits(const struct device *dev, gpio_port_pins_t mask) in tca6424a_port_toggle_bits() argument
377 struct tca6424a_drv_data *const drv_data = dev->data; in tca6424a_port_toggle_bits()
383 return -EWOULDBLOCK; in tca6424a_port_toggle_bits()
386 k_sem_take(&drv_data->lock, K_FOREVER); in tca6424a_port_toggle_bits()
388 reg_out = drv_data->pins_state.output; in tca6424a_port_toggle_bits()
389 reg_out ^= mask; in tca6424a_port_toggle_bits()
393 k_sem_give(&drv_data->lock); in tca6424a_port_toggle_bits()
401 struct tca6424a_drv_data *drv_data = dev->data; in tca6424a_pin_interrupt_configure()
402 struct tca6424a_irq_state *irq = &drv_data->irq_state; in tca6424a_pin_interrupt_configure()
404 /* Device does not support level-triggered interrupts. */ in tca6424a_pin_interrupt_configure()
406 return -ENOTSUP; in tca6424a_pin_interrupt_configure()
409 k_sem_take(&drv_data->lock, K_FOREVER); in tca6424a_pin_interrupt_configure()
412 irq->falling &= ~BIT(pin); in tca6424a_pin_interrupt_configure()
413 irq->rising &= ~BIT(pin); in tca6424a_pin_interrupt_configure()
416 irq->falling |= BIT(pin); in tca6424a_pin_interrupt_configure()
417 irq->rising |= BIT(pin); in tca6424a_pin_interrupt_configure()
419 irq->falling |= BIT(pin); in tca6424a_pin_interrupt_configure()
420 irq->rising &= ~BIT(pin); in tca6424a_pin_interrupt_configure()
422 irq->falling &= ~BIT(pin); in tca6424a_pin_interrupt_configure()
423 irq->rising |= BIT(pin); in tca6424a_pin_interrupt_configure()
427 k_sem_give(&drv_data->lock); in tca6424a_pin_interrupt_configure()
435 struct tca6424a_drv_data *drv_data = dev->data; in tca6424a_manage_callback()
437 return gpio_manage_callback(&drv_data->callbacks, callback, set); in tca6424a_manage_callback()
455 * The interrupt is configured if it is enabled.
464 const struct tca6424a_drv_cfg *drv_cfg = dev->config; in tca6424a_init()
465 struct tca6424a_drv_data *drv_data = dev->data; in tca6424a_init()
468 if (!device_is_ready(drv_cfg->i2c_spec.bus)) { in tca6424a_init()
470 return -ENODEV; in tca6424a_init()
476 if (drv_cfg->reset_gpio.port) { in tca6424a_init()
477 if (!gpio_is_ready_dt(&drv_cfg->reset_gpio)) { in tca6424a_init()
478 LOG_ERR("%s is not ready", drv_cfg->reset_gpio.port->name); in tca6424a_init()
479 return -ENODEV; in tca6424a_init()
481 ret = gpio_pin_configure_dt(&drv_cfg->reset_gpio, GPIO_OUTPUT_ACTIVE); in tca6424a_init()
483 LOG_ERR("%s: failed to configure RESET line: %d", dev->name, ret); in tca6424a_init()
489 ret = gpio_pin_set_dt(&drv_cfg->reset_gpio, 0); in tca6424a_init()
491 LOG_ERR("%s: failed to deactivate RESET line: %d", dev->name, ret); in tca6424a_init()
499 LOG_ERR("%s: failed to reset inversion register: %d", dev->name, ret); in tca6424a_init()
515 ret = update_input_regs(dev, &drv_data->pins_state.input); in tca6424a_init()
517 LOG_ERR("%s: failed to initially read input port: %d", dev->name, ret); in tca6424a_init()
522 if (drv_cfg->int_gpio.port) { in tca6424a_init()
523 if (!gpio_is_ready_dt(&drv_cfg->int_gpio)) { in tca6424a_init()
524 LOG_ERR("Cannot get pointer to gpio interrupt device " in tca6424a_init()
525 "%s init failed", dev->name); in tca6424a_init()
526 return -EINVAL; in tca6424a_init()
529 drv_data->dev = dev; in tca6424a_init()
531 k_work_init(&drv_data->work, tca6424a_work_handler); in tca6424a_init()
533 ret = gpio_pin_configure_dt(&drv_cfg->int_gpio, GPIO_INPUT); in tca6424a_init()
535 LOG_ERR("%s init failed: %d", dev->name, ret); in tca6424a_init()
539 ret = gpio_pin_interrupt_configure_dt(&drv_cfg->int_gpio, GPIO_INT_EDGE_TO_ACTIVE); in tca6424a_init()
541 LOG_ERR("%s init failed: %d", dev->name, ret); in tca6424a_init()
545 gpio_init_callback(&drv_data->int_gpio_cb, tca6424a_int_gpio_handler, in tca6424a_init()
546 BIT(drv_cfg->int_gpio.pin)); in tca6424a_init()
548 ret = gpio_add_callback(drv_cfg->int_gpio.port, &drv_data->int_gpio_cb); in tca6424a_init()
550 LOG_ERR("%s init failed: %d", dev->name, ret); in tca6424a_init()
555 LOG_DBG("%s init ok", dev->name); in tca6424a_init()