Lines Matching +full:all +full:- +full:outputs +full:- +full:2
5 * SPDX-License-Identifier: Apache-2.0
106 typedef int (*pcal64xxa_outputs_write)(const struct i2c_dt_spec *i2c, pcal64xxa_data_t outputs);
131 struct pcal64xxa_drv_data *drv_data = dev->data; in pcal64xxa_pin_configure()
132 const struct pcal64xxa_drv_cfg *drv_cfg = dev->config; in pcal64xxa_pin_configure()
137 LOG_DBG("%s: configure pin %i with flags 0x%08X", dev->name, pin, flags); in pcal64xxa_pin_configure()
139 /* This device does not support open-source outputs, and open-drain in pcal64xxa_pin_configure()
140 * outputs can be only configured port-wise. in pcal64xxa_pin_configure()
143 return -ENOTSUP; in pcal64xxa_pin_configure()
146 /* Pins in this device can be either inputs or outputs and cannot be in pcal64xxa_pin_configure()
151 return -ENOTSUP; in pcal64xxa_pin_configure()
155 return -EWOULDBLOCK; in pcal64xxa_pin_configure()
158 k_sem_take(&drv_data->lock, K_FOREVER); in pcal64xxa_pin_configure()
160 pins_cfg = drv_data->pins_cfg; in pcal64xxa_pin_configure()
186 rc = drv_cfg->chip_api->pins_cfg_apply(&drv_cfg->i2c, &pins_cfg); in pcal64xxa_pin_configure()
188 drv_data->pins_cfg = pins_cfg; in pcal64xxa_pin_configure()
190 LOG_ERR("%s: failed to apply pin config", dev->name); in pcal64xxa_pin_configure()
193 k_sem_give(&drv_data->lock); in pcal64xxa_pin_configure()
200 const struct pcal64xxa_drv_cfg *drv_cfg = dev->config; in pcal64xxa_process_input()
201 struct pcal64xxa_drv_data *drv_data = dev->data; in pcal64xxa_process_input()
206 k_sem_take(&drv_data->lock, K_FOREVER); in pcal64xxa_process_input()
208 rc = drv_cfg->chip_api->inputs_read(&drv_cfg->i2c, &int_sources, &input_port); in pcal64xxa_process_input()
211 LOG_ERR("%s: failed to read inputs", dev->name); in pcal64xxa_process_input()
212 k_sem_give(&drv_data->lock); in pcal64xxa_process_input()
227 int_sources |= ((input_port ^ drv_data->input_port_last) & ~drv_data->triggers.masked); in pcal64xxa_process_input()
229 drv_data->input_port_last = input_port; in pcal64xxa_process_input()
232 pcal64xxa_data_t dual_edge_triggers = drv_data->triggers.dual_edge; in pcal64xxa_process_input()
234 ~dual_edge_triggers & drv_data->triggers.on_low; in pcal64xxa_process_input()
237 /* For dual edge triggers, react to all state changes. */ in pcal64xxa_process_input()
248 k_sem_give(&drv_data->lock); in pcal64xxa_process_input()
250 gpio_fire_callbacks(&drv_data->callbacks, dev, fired_triggers); in pcal64xxa_process_input()
252 k_sem_give(&drv_data->lock); in pcal64xxa_process_input()
262 (void)pcal64xxa_process_input(drv_data->dev, NULL); in pcal64xxa_work_handler()
274 k_work_submit(&drv_data->work); in pcal64xxa_int_gpio_handler()
282 return -EWOULDBLOCK; in pcal64xxa_port_get_raw()
296 const struct pcal64xxa_drv_cfg *drv_cfg = dev->config; in pcal64xxa_port_set_raw()
297 struct pcal64xxa_drv_data *drv_data = dev->data; in pcal64xxa_port_set_raw()
303 dev->name, mask, value, toggle); in pcal64xxa_port_set_raw()
306 return -EWOULDBLOCK; in pcal64xxa_port_set_raw()
309 k_sem_take(&drv_data->lock, K_FOREVER); in pcal64xxa_port_set_raw()
311 output = (drv_data->pins_cfg.outputs_high & ~mask); in pcal64xxa_port_set_raw()
315 * No need to limit `out` to only pins configured as outputs, in pcal64xxa_port_set_raw()
316 * as the chip anyway ignores all other bits in the register. in pcal64xxa_port_set_raw()
318 rc = drv_cfg->chip_api->outputs_write(&drv_cfg->i2c, output); in pcal64xxa_port_set_raw()
320 drv_data->pins_cfg.outputs_high = output; in pcal64xxa_port_set_raw()
323 k_sem_give(&drv_data->lock); in pcal64xxa_port_set_raw()
326 LOG_ERR("%s: failed to write output port: %d", dev->name, rc); in pcal64xxa_port_set_raw()
327 return -EIO; in pcal64xxa_port_set_raw()
357 const struct pcal64xxa_drv_cfg *drv_cfg = dev->config; in pcal64xxa_pin_interrupt_configure()
358 struct pcal64xxa_drv_data *drv_data = dev->data; in pcal64xxa_pin_interrupt_configure()
362 LOG_DBG("%s: configure interrupt for pin %i", dev->name, pin); in pcal64xxa_pin_interrupt_configure()
364 if (drv_cfg->gpio_interrupt.port == NULL) { in pcal64xxa_pin_interrupt_configure()
365 return -ENOTSUP; in pcal64xxa_pin_interrupt_configure()
368 /* This device supports only edge-triggered interrupts. */ in pcal64xxa_pin_interrupt_configure()
370 return -ENOTSUP; in pcal64xxa_pin_interrupt_configure()
374 return -EWOULDBLOCK; in pcal64xxa_pin_interrupt_configure()
377 k_sem_take(&drv_data->lock, K_FOREVER); in pcal64xxa_pin_interrupt_configure()
379 triggers = drv_data->triggers; in pcal64xxa_pin_interrupt_configure()
399 rc = drv_cfg->chip_api->triggers_apply(&drv_cfg->i2c, &triggers); in pcal64xxa_pin_interrupt_configure()
401 drv_data->triggers = triggers; in pcal64xxa_pin_interrupt_configure()
403 LOG_ERR("%s: failed to apply triggers", dev->name); in pcal64xxa_pin_interrupt_configure()
406 k_sem_give(&drv_data->lock); in pcal64xxa_pin_interrupt_configure()
414 struct pcal64xxa_drv_data *drv_data = dev->data; in pcal64xxa_manage_callback()
416 return gpio_manage_callback(&drv_data->callbacks, callback, set); in pcal64xxa_manage_callback()
456 (uint8_t)pins_cfg->pull_ups_selected); in pcal6408a_pins_cfg_apply()
458 return -EIO; in pcal6408a_pins_cfg_apply()
462 (uint8_t)pins_cfg->pulls_enabled); in pcal6408a_pins_cfg_apply()
464 return -EIO; in pcal6408a_pins_cfg_apply()
467 rc = pcal64xxa_i2c_write(i2c, PCAL6408A_REG_OUTPUT_PORT, (uint8_t)pins_cfg->outputs_high); in pcal6408a_pins_cfg_apply()
469 return -EIO; in pcal6408a_pins_cfg_apply()
473 (uint8_t)pins_cfg->configured_as_inputs); in pcal6408a_pins_cfg_apply()
475 return -EIO; in pcal6408a_pins_cfg_apply()
489 return -EIO; in pcal6408a_pins_cfg_read()
492 pins_cfg->pull_ups_selected = value; in pcal6408a_pins_cfg_read()
496 return -EIO; in pcal6408a_pins_cfg_read()
499 pins_cfg->pulls_enabled = value; in pcal6408a_pins_cfg_read()
503 return -EIO; in pcal6408a_pins_cfg_read()
506 pins_cfg->outputs_high = value; in pcal6408a_pins_cfg_read()
510 return -EIO; in pcal6408a_pins_cfg_read()
513 pins_cfg->configured_as_inputs = value; in pcal6408a_pins_cfg_read()
526 return -EIO; in pcal6408a_inputs_read()
534 return -EIO; in pcal6408a_inputs_read()
542 static int pcal6408a_outputs_write(const struct i2c_dt_spec *i2c, pcal64xxa_data_t outputs) in pcal6408a_outputs_write() argument
547 * No need to limit `out` to only pins configured as outputs, in pcal6408a_outputs_write()
548 * as the chip anyway ignores all other bits in the register. in pcal6408a_outputs_write()
550 rc = pcal64xxa_i2c_write(i2c, PCAL6408A_REG_OUTPUT_PORT, (uint8_t)outputs); in pcal6408a_outputs_write()
554 return -EIO; in pcal6408a_outputs_write()
564 uint8_t input_latch = ~triggers->masked; in pcal6408a_triggers_apply()
565 uint8_t interrupt_mask = triggers->masked; in pcal6408a_triggers_apply()
570 return -EIO; in pcal6408a_triggers_apply()
576 return -EIO; in pcal6408a_triggers_apply()
585 static const uint8_t reset_state[][2] = { in pcal6408a_reset_state_apply()
596 return -EIO; in pcal6408a_reset_state_apply()
620 (uint8_t)pins_cfg->pull_ups_selected); in pcal6416a_pins_cfg_apply()
622 return -EIO; in pcal6416a_pins_cfg_apply()
626 (uint8_t)(pins_cfg->pull_ups_selected >> 8)); in pcal6416a_pins_cfg_apply()
628 return -EIO; in pcal6416a_pins_cfg_apply()
632 (uint8_t)pins_cfg->pulls_enabled); in pcal6416a_pins_cfg_apply()
634 return -EIO; in pcal6416a_pins_cfg_apply()
638 (uint8_t)(pins_cfg->pulls_enabled >> 8)); in pcal6416a_pins_cfg_apply()
640 return -EIO; in pcal6416a_pins_cfg_apply()
643 rc = pcal64xxa_i2c_write(i2c, PCAL6416A_REG_OUTPUT_PORT_0, (uint8_t)pins_cfg->outputs_high); in pcal6416a_pins_cfg_apply()
645 return -EIO; in pcal6416a_pins_cfg_apply()
649 (uint8_t)(pins_cfg->outputs_high >> 8)); in pcal6416a_pins_cfg_apply()
651 return -EIO; in pcal6416a_pins_cfg_apply()
655 (uint8_t)pins_cfg->configured_as_inputs); in pcal6416a_pins_cfg_apply()
657 return -EIO; in pcal6416a_pins_cfg_apply()
661 (uint8_t)(pins_cfg->configured_as_inputs >> 8)); in pcal6416a_pins_cfg_apply()
663 return -EIO; in pcal6416a_pins_cfg_apply()
678 return -EIO; in pcal6416a_pins_cfg_read()
683 return -EIO; in pcal6416a_pins_cfg_read()
686 pins_cfg->pull_ups_selected = value_high << 8 | value_low; in pcal6416a_pins_cfg_read()
690 return -EIO; in pcal6416a_pins_cfg_read()
695 return -EIO; in pcal6416a_pins_cfg_read()
698 pins_cfg->pulls_enabled = value_high << 8 | value_low; in pcal6416a_pins_cfg_read()
702 return -EIO; in pcal6416a_pins_cfg_read()
707 return -EIO; in pcal6416a_pins_cfg_read()
710 pins_cfg->outputs_high = value_high << 8 | value_low; in pcal6416a_pins_cfg_read()
714 return -EIO; in pcal6416a_pins_cfg_read()
719 return -EIO; in pcal6416a_pins_cfg_read()
722 pins_cfg->configured_as_inputs = value_high << 8 | value_low; in pcal6416a_pins_cfg_read()
736 return -EIO; in pcal6416a_inputs_read()
741 return -EIO; in pcal6416a_inputs_read()
749 return -EIO; in pcal6416a_inputs_read()
755 return -EIO; in pcal6416a_inputs_read()
763 static int pcal6416a_outputs_write(const struct i2c_dt_spec *i2c, pcal64xxa_data_t outputs) in pcal6416a_outputs_write() argument
768 * No need to limit `out` to only pins configured as outputs, in pcal6416a_outputs_write()
769 * as the chip anyway ignores all other bits in the register. in pcal6416a_outputs_write()
771 rc = pcal64xxa_i2c_write(i2c, PCAL6416A_REG_OUTPUT_PORT_0, (uint8_t)outputs); in pcal6416a_outputs_write()
775 return -EIO; in pcal6416a_outputs_write()
778 rc = pcal64xxa_i2c_write(i2c, PCAL6416A_REG_OUTPUT_PORT_1, (uint8_t)(outputs >> 8)); in pcal6416a_outputs_write()
782 return -EIO; in pcal6416a_outputs_write()
792 pcal64xxa_data_t input_latch = ~triggers->masked; in pcal6416a_triggers_apply()
793 pcal64xxa_data_t interrupt_mask = triggers->masked; in pcal6416a_triggers_apply()
798 return -EIO; in pcal6416a_triggers_apply()
804 return -EIO; in pcal6416a_triggers_apply()
810 return -EIO; in pcal6416a_triggers_apply()
817 return -EIO; in pcal6416a_triggers_apply()
826 static const uint8_t reset_state[][2] = { in pcal6416a_reset_state_apply()
840 return -EIO; in pcal6416a_reset_state_apply()
859 const struct pcal64xxa_drv_cfg *drv_cfg = dev->config; in pcal64xxa_apply_initial_state()
860 struct pcal64xxa_drv_data *drv_data = dev->data; in pcal64xxa_apply_initial_state()
869 LOG_DBG("%s: apply initial state", dev->name); in pcal64xxa_apply_initial_state()
875 if (drv_cfg->gpio_reset.port != NULL) { in pcal64xxa_apply_initial_state()
876 if (!gpio_is_ready_dt(&drv_cfg->gpio_reset)) { in pcal64xxa_apply_initial_state()
877 LOG_ERR("%s: reset gpio device is not ready", dev->name); in pcal64xxa_apply_initial_state()
878 return -ENODEV; in pcal64xxa_apply_initial_state()
881 LOG_DBG("%s: trigger reset", dev->name); in pcal64xxa_apply_initial_state()
882 rc = gpio_pin_configure_dt(&drv_cfg->gpio_reset, GPIO_OUTPUT_ACTIVE); in pcal64xxa_apply_initial_state()
884 LOG_ERR("%s: failed to configure RESET line: %d", dev->name, rc); in pcal64xxa_apply_initial_state()
885 return -EIO; in pcal64xxa_apply_initial_state()
891 rc = gpio_pin_set_dt(&drv_cfg->gpio_reset, 0); in pcal64xxa_apply_initial_state()
893 LOG_ERR("%s: failed to deactivate RESET line: %d", dev->name, rc); in pcal64xxa_apply_initial_state()
894 return -EIO; in pcal64xxa_apply_initial_state()
900 rc = drv_cfg->chip_api->reset_state_apply(&drv_cfg->i2c); in pcal64xxa_apply_initial_state()
903 LOG_ERR("%s: failed to apply reset state", dev->name); in pcal64xxa_apply_initial_state()
909 rc = drv_cfg->chip_api->pins_cfg_apply(&drv_cfg->i2c, &initial_pins_cfg); in pcal64xxa_apply_initial_state()
911 LOG_ERR("%s: failed to apply pin config", dev->name); in pcal64xxa_apply_initial_state()
915 drv_data->pins_cfg = initial_pins_cfg; in pcal64xxa_apply_initial_state()
922 const struct pcal64xxa_drv_cfg *drv_cfg = dev->config; in pcal64xxa_read_state_from_registers()
923 struct pcal64xxa_drv_data *drv_data = dev->data; in pcal64xxa_read_state_from_registers()
926 LOG_DBG("%s: use retained state", dev->name); in pcal64xxa_read_state_from_registers()
929 rc = drv_cfg->chip_api->pins_cfg_read(&drv_cfg->i2c, &drv_data->pins_cfg); in pcal64xxa_read_state_from_registers()
931 LOG_ERR("%s: failed to apply pin config", dev->name); in pcal64xxa_read_state_from_registers()
940 const struct pcal64xxa_drv_cfg *drv_cfg = dev->config; in pcal64xxa_apply_initial_triggers()
941 struct pcal64xxa_drv_data *drv_data = dev->data; in pcal64xxa_apply_initial_triggers()
948 rc = drv_cfg->chip_api->triggers_apply(&drv_cfg->i2c, &initial_triggers); in pcal64xxa_apply_initial_triggers()
950 LOG_ERR("%s: failed to apply triggers", dev->name); in pcal64xxa_apply_initial_triggers()
954 drv_data->triggers = initial_triggers; in pcal64xxa_apply_initial_triggers()
961 const struct pcal64xxa_drv_cfg *drv_cfg = dev->config; in pcal64xxa_read_initial_inputs()
962 struct pcal64xxa_drv_data *drv_data = dev->data; in pcal64xxa_read_initial_inputs()
967 rc = drv_cfg->chip_api->inputs_read(&drv_cfg->i2c, &int_sources, in pcal64xxa_read_initial_inputs()
968 &drv_data->input_port_last); in pcal64xxa_read_initial_inputs()
970 LOG_ERR("%s: failed to read inputs", dev->name); in pcal64xxa_read_initial_inputs()
1001 struct pcal64xxa_drv_data *drv_data = dev->data; in pcal64xxa_reset()
1004 k_sem_take(&drv_data->lock, K_FOREVER); in pcal64xxa_reset()
1006 k_sem_give(&drv_data->lock); in pcal64xxa_reset()
1013 const struct pcal64xxa_drv_cfg *drv_cfg = dev->config; in pcal64xxa_init()
1014 struct pcal64xxa_drv_data *drv_data = dev->data; in pcal64xxa_init()
1017 LOG_DBG("%s: initializing PCAL64XXA", dev->name); in pcal64xxa_init()
1019 if (drv_cfg->ngpios != 8U && drv_cfg->ngpios != 16U) { in pcal64xxa_init()
1021 dev->name, drv_cfg->ngpios); in pcal64xxa_init()
1022 return -EINVAL; in pcal64xxa_init()
1029 if (!i2c_is_ready_dt(&drv_cfg->i2c)) { in pcal64xxa_init()
1030 LOG_ERR("%s: %s is not ready", dev->name, drv_cfg->i2c.bus->name); in pcal64xxa_init()
1031 return -ENODEV; in pcal64xxa_init()
1035 if (drv_cfg->gpio_interrupt.port != NULL) { in pcal64xxa_init()
1036 if (!gpio_is_ready_dt(&drv_cfg->gpio_interrupt)) { in pcal64xxa_init()
1037 LOG_ERR("%s: interrupt gpio device is not ready", dev->name); in pcal64xxa_init()
1038 return -ENODEV; in pcal64xxa_init()
1041 rc = gpio_pin_configure_dt(&drv_cfg->gpio_interrupt, GPIO_INPUT); in pcal64xxa_init()
1043 LOG_ERR("%s: failed to configure INT line: %d", dev->name, rc); in pcal64xxa_init()
1044 return -EIO; in pcal64xxa_init()
1047 rc = gpio_pin_interrupt_configure_dt(&drv_cfg->gpio_interrupt, in pcal64xxa_init()
1050 LOG_ERR("%s: failed to configure INT interrupt: %d", dev->name, rc); in pcal64xxa_init()
1051 return -EIO; in pcal64xxa_init()
1054 gpio_init_callback(&drv_data->int_gpio_cb, pcal64xxa_int_gpio_handler, in pcal64xxa_init()
1055 BIT(drv_cfg->gpio_interrupt.pin)); in pcal64xxa_init()
1056 rc = gpio_add_callback(drv_cfg->gpio_interrupt.port, &drv_data->int_gpio_cb); in pcal64xxa_init()
1058 LOG_ERR("%s: failed to add INT callback: %d", dev->name, rc); in pcal64xxa_init()
1059 return -EIO; in pcal64xxa_init()
1063 if (drv_cfg->automatic_reset) { in pcal64xxa_init()
1086 k_sem_give(&drv_data->lock); in pcal64xxa_init()