1 /*
2 * Copyright (c) 2023 SILA Embedded Solutions GmbH
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /**
8 * @file
9 * @brief GPIO driver for the ADS114S0x AFE.
10 */
11
12 #define DT_DRV_COMPAT ti_ads114s0x_gpio
13
14 #include <zephyr/drivers/gpio.h>
15 #include <zephyr/kernel.h>
16
17 #define LOG_LEVEL CONFIG_GPIO_LOG_LEVEL
18 #include <zephyr/logging/log.h>
19 LOG_MODULE_REGISTER(gpio_ads114s0x);
20
21 #include <zephyr/drivers/adc/ads114s0x.h>
22
23 #include <zephyr/drivers/gpio/gpio_utils.h>
24
25 struct gpio_ads114s0x_config {
26 /* gpio_driver_config needs to be first */
27 struct gpio_driver_config common;
28 const struct device *parent;
29 };
30
31 struct gpio_ads114s0x_data {
32 /* gpio_driver_data needs to be first */
33 struct gpio_driver_data common;
34 };
35
gpio_ads114s0x_config(const struct device * dev,gpio_pin_t pin,gpio_flags_t flags)36 static int gpio_ads114s0x_config(const struct device *dev, gpio_pin_t pin, gpio_flags_t flags)
37 {
38 const struct gpio_ads114s0x_config *config = dev->config;
39 int err = 0;
40
41 if ((flags & (GPIO_INPUT | GPIO_OUTPUT)) == GPIO_DISCONNECTED) {
42 return ads114s0x_gpio_deconfigure(config->parent, pin);
43 }
44
45 if ((flags & GPIO_SINGLE_ENDED) != 0) {
46 return -ENOTSUP;
47 }
48
49 if ((flags & (GPIO_PULL_UP | GPIO_PULL_DOWN)) != 0) {
50 return -ENOTSUP;
51 }
52
53 if (flags & GPIO_INT_ENABLE) {
54 /* ads114s0x GPIOs do not support interrupts */
55 return -ENOTSUP;
56 }
57
58 switch (flags & GPIO_DIR_MASK) {
59 case GPIO_INPUT:
60 err = ads114s0x_gpio_set_input(config->parent, pin);
61 break;
62 case GPIO_OUTPUT:
63 err = ads114s0x_gpio_set_output(config->parent, pin,
64 (flags & GPIO_OUTPUT_INIT_HIGH) != 0);
65 break;
66 default:
67 return -ENOTSUP;
68 }
69
70 return err;
71 }
72
gpio_ads114s0x_port_get_raw(const struct device * dev,gpio_port_value_t * value)73 static int gpio_ads114s0x_port_get_raw(const struct device *dev, gpio_port_value_t *value)
74 {
75 const struct gpio_ads114s0x_config *config = dev->config;
76
77 return ads114s0x_gpio_port_get_raw(config->parent, value);
78 }
79
gpio_ads114s0x_port_set_masked_raw(const struct device * dev,gpio_port_pins_t mask,gpio_port_value_t value)80 static int gpio_ads114s0x_port_set_masked_raw(const struct device *dev, gpio_port_pins_t mask,
81 gpio_port_value_t value)
82 {
83 const struct gpio_ads114s0x_config *config = dev->config;
84
85 return ads114s0x_gpio_port_set_masked_raw(config->parent, mask, value);
86 }
87
gpio_ads114s0x_port_set_bits_raw(const struct device * dev,gpio_port_pins_t pins)88 static int gpio_ads114s0x_port_set_bits_raw(const struct device *dev, gpio_port_pins_t pins)
89 {
90 const struct gpio_ads114s0x_config *config = dev->config;
91
92 return ads114s0x_gpio_port_set_masked_raw(config->parent, pins, pins);
93 }
94
gpio_ads114s0x_port_clear_bits_raw(const struct device * dev,gpio_port_pins_t pins)95 static int gpio_ads114s0x_port_clear_bits_raw(const struct device *dev, gpio_port_pins_t pins)
96 {
97 const struct gpio_ads114s0x_config *config = dev->config;
98
99 return ads114s0x_gpio_port_set_masked_raw(config->parent, pins, 0);
100 }
101
gpio_ads114s0x_port_toggle_bits(const struct device * dev,gpio_port_pins_t pins)102 static int gpio_ads114s0x_port_toggle_bits(const struct device *dev, gpio_port_pins_t pins)
103 {
104 const struct gpio_ads114s0x_config *config = dev->config;
105
106 return ads114s0x_gpio_port_toggle_bits(config->parent, pins);
107 }
108
gpio_ads114s0x_init(const struct device * dev)109 static int gpio_ads114s0x_init(const struct device *dev)
110 {
111 const struct gpio_ads114s0x_config *config = dev->config;
112
113 if (!device_is_ready(config->parent)) {
114 LOG_ERR("parent ads114s0x device '%s' not ready", config->parent->name);
115 return -EINVAL;
116 }
117
118 return 0;
119 }
120
121 static const struct gpio_driver_api gpio_ads114s0x_api = {
122 .pin_configure = gpio_ads114s0x_config,
123 .port_set_masked_raw = gpio_ads114s0x_port_set_masked_raw,
124 .port_set_bits_raw = gpio_ads114s0x_port_set_bits_raw,
125 .port_clear_bits_raw = gpio_ads114s0x_port_clear_bits_raw,
126 .port_toggle_bits = gpio_ads114s0x_port_toggle_bits,
127 .port_get_raw = gpio_ads114s0x_port_get_raw,
128 };
129
130 BUILD_ASSERT(CONFIG_GPIO_ADS114S0X_INIT_PRIORITY > CONFIG_ADC_INIT_PRIORITY,
131 "ADS114S0X GPIO driver must be initialized after ADS114S0X ADC driver");
132
133 #define GPIO_ADS114S0X_DEVICE(id) \
134 static const struct gpio_ads114s0x_config gpio_ads114s0x_##id##_cfg = { \
135 .common = {.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(id)}, \
136 .parent = DEVICE_DT_GET(DT_INST_BUS(id)), \
137 }; \
138 \
139 static struct gpio_ads114s0x_data gpio_ads114s0x_##id##_data; \
140 \
141 DEVICE_DT_INST_DEFINE(id, &gpio_ads114s0x_init, NULL, &gpio_ads114s0x_##id##_data, \
142 &gpio_ads114s0x_##id##_cfg, POST_KERNEL, \
143 CONFIG_GPIO_ADS114S0X_INIT_PRIORITY, &gpio_ads114s0x_api);
144
145 DT_INST_FOREACH_STATUS_OKAY(GPIO_ADS114S0X_DEVICE)
146