1 /*
2 * Copyright (c) 2019 Vestas Wind Systems A/S
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /**
8 * @file
9 * @brief GPIO driver for the LMP90xxx AFE.
10 */
11
12 #define DT_DRV_COMPAT ti_lmp90xxx_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_lmp90xxx);
20
21 #include <zephyr/drivers/adc/lmp90xxx.h>
22
23 #include <zephyr/drivers/gpio/gpio_utils.h>
24
25 struct gpio_lmp90xxx_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_lmp90xxx_data {
32 /* gpio_driver_data needs to be first */
33 struct gpio_driver_data common;
34 };
35
gpio_lmp90xxx_config(const struct device * dev,gpio_pin_t pin,gpio_flags_t flags)36 static int gpio_lmp90xxx_config(const struct device *dev,
37 gpio_pin_t pin, gpio_flags_t flags)
38 {
39 const struct gpio_lmp90xxx_config *config = dev->config;
40 int err = 0;
41
42 if (pin > LMP90XXX_GPIO_MAX) {
43 return -EINVAL;
44 }
45
46 if ((flags & GPIO_SINGLE_ENDED) != 0) {
47 return -ENOTSUP;
48 }
49
50 if ((flags & (GPIO_PULL_UP | GPIO_PULL_DOWN)) != 0) {
51 return -ENOTSUP;
52 }
53
54 if (flags & GPIO_INT_ENABLE) {
55 /* LMP90xxx GPIOs do not support interrupts */
56 return -ENOTSUP;
57 }
58
59 switch (flags & GPIO_DIR_MASK) {
60 case GPIO_INPUT:
61 err = lmp90xxx_gpio_set_input(config->parent, pin);
62 break;
63 case GPIO_OUTPUT:
64 if ((flags & GPIO_OUTPUT_INIT_HIGH) != 0) {
65 err = lmp90xxx_gpio_set_pin_value(config->parent, pin,
66 true);
67 } else if ((flags & GPIO_OUTPUT_INIT_LOW) != 0) {
68 err = lmp90xxx_gpio_set_pin_value(config->parent, pin,
69 false);
70 }
71
72 if (err) {
73 return err;
74 }
75 err = lmp90xxx_gpio_set_output(config->parent, pin);
76 break;
77 default:
78 return -ENOTSUP;
79 }
80
81 return err;
82 }
83
gpio_lmp90xxx_port_get_raw(const struct device * dev,gpio_port_value_t * value)84 static int gpio_lmp90xxx_port_get_raw(const struct device *dev,
85 gpio_port_value_t *value)
86 {
87 const struct gpio_lmp90xxx_config *config = dev->config;
88
89 return lmp90xxx_gpio_port_get_raw(config->parent, value);
90 }
91
gpio_lmp90xxx_port_set_masked_raw(const struct device * dev,gpio_port_pins_t mask,gpio_port_value_t value)92 static int gpio_lmp90xxx_port_set_masked_raw(const struct device *dev,
93 gpio_port_pins_t mask,
94 gpio_port_value_t value)
95 {
96 const struct gpio_lmp90xxx_config *config = dev->config;
97
98 return lmp90xxx_gpio_port_set_masked_raw(config->parent, mask, value);
99 }
100
gpio_lmp90xxx_port_set_bits_raw(const struct device * dev,gpio_port_pins_t pins)101 static int gpio_lmp90xxx_port_set_bits_raw(const struct device *dev,
102 gpio_port_pins_t pins)
103 {
104 const struct gpio_lmp90xxx_config *config = dev->config;
105
106 return lmp90xxx_gpio_port_set_bits_raw(config->parent, pins);
107 }
108
gpio_lmp90xxx_port_clear_bits_raw(const struct device * dev,gpio_port_pins_t pins)109 static int gpio_lmp90xxx_port_clear_bits_raw(const struct device *dev,
110 gpio_port_pins_t pins)
111 {
112 const struct gpio_lmp90xxx_config *config = dev->config;
113
114 return lmp90xxx_gpio_port_clear_bits_raw(config->parent, pins);
115 }
116
gpio_lmp90xxx_port_toggle_bits(const struct device * dev,gpio_port_pins_t pins)117 static int gpio_lmp90xxx_port_toggle_bits(const struct device *dev,
118 gpio_port_pins_t pins)
119 {
120 const struct gpio_lmp90xxx_config *config = dev->config;
121
122 return lmp90xxx_gpio_port_toggle_bits(config->parent, pins);
123 }
124
gpio_lmp90xxx_init(const struct device * dev)125 static int gpio_lmp90xxx_init(const struct device *dev)
126 {
127 const struct gpio_lmp90xxx_config *config = dev->config;
128
129 if (!device_is_ready(config->parent)) {
130 LOG_ERR("parent LMP90xxx device '%s' not ready",
131 config->parent->name);
132 return -EINVAL;
133 }
134
135 return 0;
136 }
137
138 static const struct gpio_driver_api gpio_lmp90xxx_api = {
139 .pin_configure = gpio_lmp90xxx_config,
140 .port_set_masked_raw = gpio_lmp90xxx_port_set_masked_raw,
141 .port_set_bits_raw = gpio_lmp90xxx_port_set_bits_raw,
142 .port_clear_bits_raw = gpio_lmp90xxx_port_clear_bits_raw,
143 .port_toggle_bits = gpio_lmp90xxx_port_toggle_bits,
144 .port_get_raw = gpio_lmp90xxx_port_get_raw,
145 };
146
147 BUILD_ASSERT(CONFIG_GPIO_LMP90XXX_INIT_PRIORITY >
148 CONFIG_ADC_INIT_PRIORITY,
149 "LMP90xxx GPIO driver must be initialized after LMP90xxx ADC "
150 "driver");
151
152 #define GPIO_LMP90XXX_DEVICE(id) \
153 static const struct gpio_lmp90xxx_config gpio_lmp90xxx_##id##_cfg = {\
154 .common = { \
155 .port_pin_mask = \
156 GPIO_PORT_PIN_MASK_FROM_DT_INST(id) \
157 }, \
158 .parent = DEVICE_DT_GET(DT_INST_BUS(id)), \
159 }; \
160 \
161 static struct gpio_lmp90xxx_data gpio_lmp90xxx_##id##_data; \
162 \
163 DEVICE_DT_INST_DEFINE(id, \
164 &gpio_lmp90xxx_init, \
165 NULL, \
166 &gpio_lmp90xxx_##id##_data, \
167 &gpio_lmp90xxx_##id##_cfg, POST_KERNEL, \
168 CONFIG_GPIO_LMP90XXX_INIT_PRIORITY, \
169 &gpio_lmp90xxx_api);
170
171 DT_INST_FOREACH_STATUS_OKAY(GPIO_LMP90XXX_DEVICE)
172