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