Skip to content

Commit 4b63ef0

Browse files
vmyklebustkartben
authored andcommitted
drivers: gpio: Add support for cc23x0 GPIO
Add support for GPIO to cc23x0 SoC. Signed-off-by: Lars Thalian Morstad <l-morstad@ti.com> Signed-off-by: Vebjorn Myklebust <v.myklebust@ti.com> Signed-off-by: Stoyan Bogdanov <sbogdanov@baylibre.com> Signed-off-by: Julien Panis <jpanis@baylibre.com>
1 parent 10c35b8 commit 4b63ef0

File tree

5 files changed

+318
-0
lines changed

5 files changed

+318
-0
lines changed

drivers/gpio/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ zephyr_library_sources_ifdef(CONFIG_GPIO_BCM2711 gpio_bcm2711.c)
1717
zephyr_library_sources_ifdef(CONFIG_GPIO_BD8LB600FS gpio_bd8lb600fs.c)
1818
zephyr_library_sources_ifdef(CONFIG_GPIO_BRCMSTB gpio_brcmstb.c)
1919
zephyr_library_sources_ifdef(CONFIG_GPIO_CC13XX_CC26XX gpio_cc13xx_cc26xx.c)
20+
zephyr_library_sources_ifdef(CONFIG_GPIO_CC23X0 gpio_cc23x0.c)
2021
zephyr_library_sources_ifdef(CONFIG_GPIO_CC32XX gpio_cc32xx.c)
2122
zephyr_library_sources_ifdef(CONFIG_GPIO_CMSDK_AHB gpio_cmsdk_ahb.c)
2223
zephyr_library_sources_ifdef(CONFIG_GPIO_CY8C95XX gpio_cy8c95xx.c)

drivers/gpio/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ source "drivers/gpio/Kconfig.bcm2711"
107107
source "drivers/gpio/Kconfig.bd8lb600fs"
108108
source "drivers/gpio/Kconfig.brcmstb"
109109
source "drivers/gpio/Kconfig.cc13xx_cc26xx"
110+
source "drivers/gpio/Kconfig.cc23x0"
110111
source "drivers/gpio/Kconfig.cc32xx"
111112
source "drivers/gpio/Kconfig.cmsdk_ahb"
112113
source "drivers/gpio/Kconfig.creg_gpio"

drivers/gpio/Kconfig.cc23x0

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Copyright (c) 2024 Texas Instruments Incorporated
2+
# Copyright (c) 2024 BayLibre, SAS
3+
#
4+
# SPDX-License-Identifier: Apache-2.0
5+
6+
config GPIO_CC23X0
7+
bool "TI SimpleLink CC23X0 GPIO driver"
8+
default y
9+
depends on DT_HAS_TI_CC23X0_GPIO_ENABLED
10+
help
11+
Enable the TI SimpleLink CC23x0 GPIO driver.

drivers/gpio/gpio_cc23x0.c

Lines changed: 281 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,281 @@
1+
/*
2+
* Copyright (c) 2024 Texas Instruments Incorporated
3+
* Copyright (c) 2024 BayLibre, SAS
4+
*
5+
* SPDX-License-Identifier: Apache-2.0
6+
*/
7+
8+
#define DT_DRV_COMPAT ti_cc23x0_gpio
9+
10+
#include <zephyr/types.h>
11+
#include <zephyr/device.h>
12+
#include <zephyr/irq.h>
13+
#include <zephyr/drivers/gpio.h>
14+
#include <zephyr/drivers/gpio/gpio_utils.h>
15+
16+
#include <driverlib/clkctl.h>
17+
#include <driverlib/gpio.h>
18+
#include <inc/hw_ioc.h>
19+
20+
#define IOC_ADDR(index) (IOC_BASE + IOC_O_IOC0 + (sizeof(uint32_t) * (index)))
21+
22+
struct gpio_cc23x0_config {
23+
/* gpio_driver_config needs to be first */
24+
struct gpio_driver_config common;
25+
};
26+
27+
struct gpio_cc23x0_data {
28+
/* gpio_driver_data needs to be first */
29+
struct gpio_driver_data common;
30+
sys_slist_t callbacks;
31+
};
32+
33+
static void set_pin_mask_non_atomic(uint8_t index, uint32_t registerBaseAddress)
34+
{
35+
GPIOSetConfigDio(GPIO_BASE + registerBaseAddress, BIT(index));
36+
}
37+
38+
static int gpio_cc23x0_config(const struct device *port, gpio_pin_t pin, gpio_flags_t flags)
39+
{
40+
uint32_t config = 0;
41+
uint32_t iocfg_reg = IOC_ADDR(pin);
42+
gpio_flags_t direction = flags & GPIO_DIR_MASK;
43+
44+
if (flags & GPIO_PULL_UP) {
45+
config |= IOC_IOC0_PULLCTL_PULL_UP;
46+
} else if (flags & GPIO_PULL_DOWN) {
47+
config |= IOC_IOC0_PULLCTL_PULL_DOWN;
48+
} else {
49+
config |= IOC_IOC0_PULLCTL_PULL_DIS;
50+
}
51+
52+
if (!(flags & GPIO_SINGLE_ENDED)) {
53+
config |= IOC_IOC0_IOMODE_NORMAL;
54+
} else {
55+
if (flags & GPIO_LINE_OPEN_DRAIN) {
56+
config |= IOC_IOC0_IOMODE_OPEND;
57+
} else {
58+
config |= IOC_IOC0_IOMODE_OPENS;
59+
}
60+
}
61+
if (direction & GPIO_INPUT) {
62+
config |= IOC_IOC0_INPEN_EN | IOC_IOC0_HYSTEN_EN;
63+
}
64+
65+
GPIOSetConfigDio(iocfg_reg, config);
66+
67+
if (flags & GPIO_OUTPUT) {
68+
if (flags & GPIO_OUTPUT_INIT_HIGH) {
69+
GPIOSetDio(pin);
70+
} else if (flags & GPIO_OUTPUT_INIT_LOW) {
71+
GPIOClearDio(pin);
72+
}
73+
GPIOSetOutputEnableDio(pin, GPIO_OUTPUT_ENABLE);
74+
} else {
75+
GPIOSetOutputEnableDio(pin, GPIO_OUTPUT_DISABLE);
76+
}
77+
return 0;
78+
}
79+
80+
#ifdef CONFIG_GPIO_GET_CONFIG
81+
static int gpio_cc23x0_get_config(const struct device *port, gpio_pin_t pin, gpio_flags_t *flags)
82+
{
83+
uint32_t out_flag = 0;
84+
uint32_t iocfg_reg = IOC_ADDR(pin);
85+
uint32_t config = GPIOGetConfigDio(iocfg_reg);
86+
87+
/* GPIO input/output configuration flags */
88+
if (config & IOC_IOC0_INPEN_EN) {
89+
out_flag |= GPIO_INPUT;
90+
}
91+
92+
if (GPIOGetOutputEnableDio(pin)) {
93+
out_flag |= GPIO_OUTPUT;
94+
95+
if (GPIOReadDio(pin)) {
96+
out_flag |= GPIO_OUTPUT_INIT_HIGH;
97+
} else {
98+
/* This is the default value. If not explicitly set,
99+
* the returned config will not be symmetric
100+
*/
101+
out_flag |= GPIO_OUTPUT_INIT_LOW;
102+
}
103+
}
104+
105+
/* GPIO interrupt configuration flags */
106+
if ((config & IOC_IOC0_EDGEDET_M) != IOC_IOC0_EDGEDET_EDGE_DIS) {
107+
if (config & IOC_IOC0_EDGEDET_EDGE_POS) {
108+
out_flag |= GPIO_INT_EDGE_RISING;
109+
}
110+
111+
if (config & IOC_IOC0_EDGEDET_EDGE_NEG) {
112+
out_flag |= GPIO_INT_EDGE_FALLING;
113+
}
114+
} else {
115+
/* This is the default value. If not explicitly set,
116+
* the returned config will not be symmetric
117+
*/
118+
out_flag |= GPIO_INT_DISABLE;
119+
}
120+
121+
/* GPIO pin drive flags */
122+
if (config & IOC_IOC0_IOMODE_OPENS) {
123+
out_flag |= GPIO_OPEN_SOURCE;
124+
}
125+
126+
if (config & IOC_IOC0_IOMODE_OPEND) {
127+
out_flag |= IOC_IOC0_IOMODE_OPEND;
128+
}
129+
130+
if (config & IOC_IOC0_PULLCTL_PULL_UP) {
131+
out_flag |= GPIO_PULL_UP;
132+
}
133+
134+
if (config & IOC_IOC0_PULLCTL_PULL_DOWN) {
135+
out_flag |= GPIO_PULL_DOWN;
136+
}
137+
138+
*flags = out_flag;
139+
140+
return 0;
141+
}
142+
#endif
143+
144+
static int gpio_cc23x0_port_get_raw(const struct device *port, uint32_t *value)
145+
{
146+
*value = GPIOReadMultiDio(GPIO_DIO_ALL_MASK);
147+
148+
return 0;
149+
}
150+
151+
static int gpio_cc23x0_port_set_masked_raw(const struct device *port, uint32_t mask, uint32_t value)
152+
{
153+
GPIOWriteMultiDio(mask, value);
154+
155+
return 0;
156+
}
157+
158+
static int gpio_cc23x0_port_set_bits_raw(const struct device *port, uint32_t mask)
159+
{
160+
GPIOSetMultiDio(mask);
161+
162+
return 0;
163+
}
164+
165+
static int gpio_cc23x0_port_clear_bits_raw(const struct device *port, uint32_t mask)
166+
{
167+
GPIOClearMultiDio(mask);
168+
169+
return 0;
170+
}
171+
172+
static int gpio_cc23x0_port_toggle_bits(const struct device *port, uint32_t mask)
173+
{
174+
GPIOToggleMultiDio(mask);
175+
176+
return 0;
177+
}
178+
179+
static int gpio_cc23x0xx_pin_interrupt_configure(const struct device *port, gpio_pin_t pin,
180+
enum gpio_int_mode mode, enum gpio_int_trig trig)
181+
{
182+
if (mode == GPIO_INT_MODE_LEVEL) {
183+
return ENOTSUP;
184+
}
185+
186+
uint32_t config = GPIOGetConfigDio(IOC_ADDR(pin)) & ~IOC_IOC0_EDGEDET_M;
187+
188+
if (mode == GPIO_INT_MODE_DISABLED) {
189+
config |= IOC_IOC1_EDGEDET_EDGE_DIS;
190+
191+
GPIOSetConfigDio(IOC_ADDR(pin), config);
192+
193+
/* Disable interrupt mask */
194+
set_pin_mask_non_atomic(pin, GPIO_O_IMCLR);
195+
196+
} else if (mode == GPIO_INT_MODE_EDGE) {
197+
switch (trig) {
198+
case GPIO_INT_TRIG_LOW:
199+
config |= IOC_IOC1_EDGEDET_EDGE_NEG;
200+
break;
201+
case GPIO_INT_TRIG_HIGH:
202+
config |= IOC_IOC1_EDGEDET_EDGE_POS;
203+
break;
204+
case GPIO_INT_TRIG_BOTH:
205+
config |= IOC_IOC1_EDGEDET_EDGE_BOTH;
206+
break;
207+
default:
208+
return ENOTSUP;
209+
}
210+
211+
GPIOSetConfigDio(IOC_ADDR(pin), config);
212+
213+
/* Enable interrupt mask */
214+
set_pin_mask_non_atomic(pin, GPIO_O_ICLR);
215+
set_pin_mask_non_atomic(pin, GPIO_O_IMSET);
216+
}
217+
218+
return 0;
219+
}
220+
221+
static int gpio_cc23x0_manage_callback(const struct device *port, struct gpio_callback *callback,
222+
bool set)
223+
{
224+
struct gpio_cc23x0_data *data = port->data;
225+
226+
return gpio_manage_callback(&data->callbacks, callback, set);
227+
}
228+
229+
static uint32_t gpio_cc23x0_get_pending_int(const struct device *dev)
230+
{
231+
return GPIOGetEventMultiDio(GPIO_DIO_ALL_MASK);
232+
}
233+
234+
static void gpio_cc23x0_isr(const struct device *dev)
235+
{
236+
struct gpio_cc23x0_data *data = dev->data;
237+
238+
uint32_t status = GPIOGetEventMultiDio(GPIO_DIO_ALL_MASK);
239+
240+
GPIOClearEventMultiDio(status);
241+
242+
gpio_fire_callbacks(&data->callbacks, dev, status);
243+
}
244+
245+
static int gpio_cc23x0_init(const struct device *dev)
246+
{
247+
/* Enable GPIO domain clock */
248+
CLKCTLEnable(CLKCTL_BASE, CLKCTL_GPIO);
249+
250+
/* Enable IRQ */
251+
IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority), gpio_cc23x0_isr,
252+
DEVICE_DT_INST_GET(0), 0);
253+
254+
irq_enable(DT_INST_IRQN(0));
255+
256+
return 0;
257+
}
258+
259+
static const struct gpio_driver_api gpio_cc23x0_driver_api = {
260+
.pin_configure = gpio_cc23x0_config,
261+
#ifdef CONFIG_GPIO_GET_CONFIG
262+
.pin_get_config = gpio_cc23x0_get_config,
263+
#endif
264+
.port_get_raw = gpio_cc23x0_port_get_raw,
265+
.port_set_masked_raw = gpio_cc23x0_port_set_masked_raw,
266+
.port_set_bits_raw = gpio_cc23x0_port_set_bits_raw,
267+
.port_clear_bits_raw = gpio_cc23x0_port_clear_bits_raw,
268+
.port_toggle_bits = gpio_cc23x0_port_toggle_bits,
269+
.pin_interrupt_configure = gpio_cc23x0xx_pin_interrupt_configure,
270+
.manage_callback = gpio_cc23x0_manage_callback,
271+
.get_pending_int = gpio_cc23x0_get_pending_int,
272+
};
273+
274+
static const struct gpio_cc23x0_config gpio_cc23x0_config_0 = {
275+
.common = {/* Read ngpios from DT */
276+
.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(0)}};
277+
278+
static struct gpio_cc23x0_data gpio_cc23x0_data_0;
279+
280+
DEVICE_DT_INST_DEFINE(0, gpio_cc23x0_init, NULL, &gpio_cc23x0_data_0, &gpio_cc23x0_config_0,
281+
PRE_KERNEL_1, CONFIG_GPIO_INIT_PRIORITY, &gpio_cc23x0_driver_api);

dts/bindings/gpio/ti,cc23x0-gpio.yaml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Copyright (c) 2024 Texas Instruments Incorporated
2+
# Copyright (c) 2024 BayLibre, SAS
3+
#
4+
# SPDX-License-Identifier: Apache-2.0
5+
6+
description: TI SimpleLink CC23X0 GPIO node
7+
8+
compatible: "ti,cc23x0-gpio"
9+
10+
include: [gpio-controller.yaml, base.yaml]
11+
12+
properties:
13+
reg:
14+
required: true
15+
16+
interrupts:
17+
required: true
18+
19+
"#gpio-cells":
20+
const: 2
21+
22+
gpio-cells:
23+
- pin
24+
- flags

0 commit comments

Comments
 (0)