Lines Matching +full:io +full:- +full:low +full:- +full:port

4  * 2023 Amrith Venkat Kesavamoorthi <amrith@mr-beam.org>
7 * SPDX-License-Identifier: Apache-2.0
9 * @see https://www.nxp.com/docs/en/data-sheet/PCF8575.pdf
10 * @see https://www.nxp.com/docs/en/data-sheet/PCF8574_PCF8574A.pdf
64 const struct pcf857x_drv_cfg *drv_cfg = dev->config; in pcf857x_process_input()
65 struct pcf857x_drv_data *drv_data = dev->data; in pcf857x_process_input()
69 rc = i2c_read_dt(&drv_cfg->i2c, rx_buf, drv_data->num_bytes); in pcf857x_process_input()
71 LOG_ERR("%s: failed to read from device: %d", dev->name, rc); in pcf857x_process_input()
72 return -EIO; in pcf857x_process_input()
76 *value = sys_get_le16(rx_buf); /*format P17-P10..P07-P00 (bit15-bit8..bit7-bit0)*/ in pcf857x_process_input()
79 drv_data->input_port_last = sys_get_le16(rx_buf); in pcf857x_process_input()
84 /** Register the read-task as work*/
89 k_sem_take(&drv_data->lock, K_FOREVER); in pcf857x_work_handler()
92 uint16_t input_port_last_temp = drv_data->input_port_last; in pcf857x_work_handler()
93 int rc = pcf857x_process_input(drv_data->dev, &changed_pins); in pcf857x_work_handler()
98 k_sem_give(&drv_data->lock); in pcf857x_work_handler()
103 gpio_fire_callbacks(&drv_data->callbacks, drv_data->dev, changed_pins); in pcf857x_work_handler()
117 k_work_submit(&drv_data->work); in pcf857x_int_gpio_handler()
123 * @param dev Pointer to the device structure of a port.
131 struct pcf857x_drv_data *drv_data = dev->data; in pcf857x_port_get_raw()
135 return -EWOULDBLOCK; in pcf857x_port_get_raw()
138 if ((~drv_data->pins_cfg.configured_as_outputs & (uint16_t)*value) != (uint16_t)*value) { in pcf857x_port_get_raw()
140 return -EOPNOTSUPP; in pcf857x_port_get_raw()
143 k_sem_take(&drv_data->lock, K_FOREVER); in pcf857x_port_get_raw()
146 * Reading of the input port also clears the generated interrupt, in pcf857x_port_get_raw()
151 k_sem_give(&drv_data->lock); in pcf857x_port_get_raw()
160 * @param mask A mask of bits to set some bits to LOW or HIGH
170 const struct pcf857x_drv_cfg *drv_cfg = dev->config; in pcf857x_port_set_raw()
171 struct pcf857x_drv_data *drv_data = dev->data; in pcf857x_port_set_raw()
177 return -EWOULDBLOCK; in pcf857x_port_set_raw()
180 if ((drv_data->pins_cfg.configured_as_outputs & value) != value) { in pcf857x_port_set_raw()
182 return -EOPNOTSUPP; in pcf857x_port_set_raw()
185 tx_buf = (drv_data->pins_cfg.outputs_state & ~mask); in pcf857x_port_set_raw()
190 rc = i2c_write_dt(&drv_cfg->i2c, tx_buf_p, drv_data->num_bytes); in pcf857x_port_set_raw()
192 LOG_ERR("%s: failed to write output port: %d", dev->name, rc); in pcf857x_port_set_raw()
193 return -EIO; in pcf857x_port_set_raw()
195 k_sem_take(&drv_data->lock, K_FOREVER); in pcf857x_port_set_raw()
196 drv_data->pins_cfg.outputs_state = tx_buf; in pcf857x_port_set_raw()
197 k_sem_give(&drv_data->lock); in pcf857x_port_set_raw()
204 * You can use it to set some pins permanent to HIGH or LOW until reset. It uses the port_set_raw
208 * @param pin The bit in the io register which is set to high
216 struct pcf857x_drv_data *drv_data = dev->data; in pcf857x_pin_configure()
218 uint16_t temp_pins = drv_data->pins_cfg.outputs_state; in pcf857x_pin_configure()
219 uint16_t temp_outputs = drv_data->pins_cfg.configured_as_outputs; in pcf857x_pin_configure()
222 return -ENOTSUP; in pcf857x_pin_configure()
228 drv_data->pins_cfg.configured_as_outputs |= BIT(pin); in pcf857x_pin_configure()
229 temp_outputs = drv_data->pins_cfg.configured_as_outputs; in pcf857x_pin_configure()
238 ret = pcf857x_port_set_raw(dev, drv_data->pins_cfg.configured_as_outputs, temp_pins, 0); in pcf857x_pin_configure()
241 k_sem_take(&drv_data->lock, K_FOREVER); in pcf857x_pin_configure()
242 drv_data->pins_cfg.outputs_state = temp_pins; in pcf857x_pin_configure()
243 drv_data->pins_cfg.configured_as_outputs = temp_outputs; in pcf857x_pin_configure()
244 k_sem_give(&drv_data->lock); in pcf857x_pin_configure()
270 * @param pins The pin(s) which will be set in a range from P17-P10..P07-P00
312 const struct pcf857x_drv_cfg *drv_cfg = dev->config; in pcf857x_pin_interrupt_configure()
314 if (!drv_cfg->gpio_int.port) { in pcf857x_pin_interrupt_configure()
315 return -ENOTSUP; in pcf857x_pin_interrupt_configure()
318 /* This device supports only edge-triggered interrupts. */ in pcf857x_pin_interrupt_configure()
320 return -ENOTSUP; in pcf857x_pin_interrupt_configure()
330 struct pcf857x_drv_data *drv_data = dev->data; in pcf857x_manage_callback()
332 return gpio_manage_callback(&drv_data->callbacks, callback, set); in pcf857x_manage_callback()
338 const struct pcf857x_drv_cfg *drv_cfg = dev->config; in pcf857x_init()
339 struct pcf857x_drv_data *drv_data = dev->data; in pcf857x_init()
342 if (!device_is_ready(drv_cfg->i2c.bus)) { in pcf857x_init()
343 LOG_ERR("%s is not ready", drv_cfg->i2c.bus->name); in pcf857x_init()
344 return -ENODEV; in pcf857x_init()
348 if (drv_cfg->gpio_int.port) { in pcf857x_init()
349 if (!gpio_is_ready_dt(&drv_cfg->gpio_int)) { in pcf857x_init()
350 LOG_ERR("Port is not ready"); in pcf857x_init()
351 return -ENODEV; in pcf857x_init()
354 rc = gpio_pin_configure_dt(&drv_cfg->gpio_int, GPIO_INPUT); in pcf857x_init()
356 LOG_ERR("%s: failed to configure INT line: %d", dev->name, rc); in pcf857x_init()
357 return -EIO; in pcf857x_init()
360 rc = gpio_pin_interrupt_configure_dt(&drv_cfg->gpio_int, GPIO_INT_EDGE_TO_ACTIVE); in pcf857x_init()
362 LOG_ERR("%s: failed to configure INT interrupt: %d", dev->name, rc); in pcf857x_init()
363 return -EIO; in pcf857x_init()
366 gpio_init_callback(&drv_data->int_gpio_cb, pcf857x_int_gpio_handler, in pcf857x_init()
367 BIT(drv_cfg->gpio_int.pin)); in pcf857x_init()
368 rc = gpio_add_callback(drv_cfg->gpio_int.port, &drv_data->int_gpio_cb); in pcf857x_init()
370 LOG_ERR("%s: failed to add INT callback: %d", dev->name, rc); in pcf857x_init()
371 return -EIO; in pcf857x_init()