Skip to content

Commit 4300296

Browse files
author
Tavish Naruka
committed
drivers: gpio: add TMS570 gpio driver
Adds TI TMS570 SoC GPIO driver. Signed-off-by: Tavish Naruka <[email protected]>
1 parent 5a4ff1e commit 4300296

File tree

6 files changed

+269
-0
lines changed

6 files changed

+269
-0
lines changed

drivers/gpio/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ zephyr_library_sources_ifdef(CONFIG_GPIO_TCA6424A gpio_tca6424a.c)
113113
zephyr_library_sources_ifdef(CONFIG_GPIO_TELINK_B91 gpio_b91.c)
114114
zephyr_library_sources_ifdef(CONFIG_GPIO_TEST gpio_test.c)
115115
zephyr_library_sources_ifdef(CONFIG_GPIO_TLE9104 gpio_tle9104.c)
116+
zephyr_library_sources_ifdef(CONFIG_GPIO_TMS570 gpio_tms570.c)
116117
zephyr_library_sources_ifdef(CONFIG_GPIO_WCH_GPIO wch_gpio_ch32v00x.c)
117118
zephyr_library_sources_ifdef(CONFIG_GPIO_XEC gpio_mchp_xec.c)
118119
zephyr_library_sources_ifdef(CONFIG_GPIO_XEC_V2 gpio_mchp_xec_v2.c)

drivers/gpio/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ source "drivers/gpio/Kconfig.sy1xx"
195195
source "drivers/gpio/Kconfig.tca6424a"
196196
source "drivers/gpio/Kconfig.test"
197197
source "drivers/gpio/Kconfig.tle9104"
198+
source "drivers/gpio/Kconfig.tms570"
198199
source "drivers/gpio/Kconfig.wch_ch32v00x"
199200
source "drivers/gpio/Kconfig.xec"
200201
source "drivers/gpio/Kconfig.xlnx"

drivers/gpio/Kconfig.tms570

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Copyright (c) 2025 ispace, inc.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
config GPIO_TMS570
5+
bool "TMS570 GPIO driver"
6+
default y
7+
depends on DT_HAS_TI_TMS570_GPIO_ENABLED
8+
help
9+
Enable driver for the TI TMS570 GPIO controller.

drivers/gpio/gpio_tms570.c

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
/*
2+
* Copyright (c) 2025 ispace, inc.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#define DT_DRV_COMPAT ti_tms570_gpio
8+
9+
#include <zephyr/drivers/gpio.h>
10+
#include <zephyr/kernel.h>
11+
#include <zephyr/sys/sys_io.h>
12+
#include <zephyr/drivers/gpio/gpio_utils.h>
13+
#include <zephyr/irq.h>
14+
15+
/* port registers */
16+
#define REG_DIR 0x0000 /* Data Direction Register */
17+
#define REG_DIN 0x0004 /* Data Input Register */
18+
#define REG_DOUT 0x0008 /* Data Output Register */
19+
#define REG_DSET 0x000C /* Data Output Set Register */
20+
#define REG_DCLR 0x0010 /* Data Output Clear Register */
21+
#define REG_PDR 0x0014 /* Open Drain Register */
22+
#define REG_PULDIS 0x0018 /* Pullup Disable Register */
23+
#define REG_PSL 0x001C /* Pull Up/Down Selection Register */
24+
25+
/* GIO base registers */
26+
#define REG_GCR0 0x0000 /* Global Control Register */
27+
#define REG_INTDET 0x0008 /* Interrupt Detect Register*/
28+
#define REG_POL 0x000C /* Interrupt Polarity Register */
29+
#define REG_ENASET 0x0010 /* Interrupt Enable Set Register */
30+
#define REG_ENACLR 0x0014 /* Interrupt Enable Clear Register */
31+
#define REG_LVLSET 0x0018 /* Interrupt Priority Set Register */
32+
#define REG_LVLCLR 0x001C /* Interrupt Priority Clear Register */
33+
#define REG_FLG 0x0020 /* Interrupt Flag Register */
34+
#define REG_OFF1 0x0024 /* Interrupt Offset A Register */
35+
#define REG_OFF2 0x0028 /* Interrupt Offset B Register */
36+
#define REG_EMU1 0x002C /* Emulation 1 Register */
37+
#define REG_EMU2 0x0030 /* Emulation 2 Register */
38+
39+
struct gpio_tms570_config {
40+
/* gpio_driver_config needs to be first */
41+
struct gpio_driver_config common;
42+
uint32_t reg_gio;
43+
uint32_t reg_port;
44+
};
45+
46+
struct gpio_tms570_data {
47+
/* gpio_driver_data needs to be first */
48+
struct gpio_driver_data common;
49+
};
50+
51+
static int gpio_tms570_set_bits(const struct device *dev, gpio_port_pins_t pins)
52+
{
53+
const struct gpio_tms570_config *config = dev->config;
54+
55+
sys_write32(pins, config->reg_port + REG_DSET);
56+
57+
return 0;
58+
}
59+
60+
static int gpio_tms570_clear_bits(const struct device *dev, gpio_port_pins_t pins)
61+
{
62+
const struct gpio_tms570_config *config = dev->config;
63+
uint32_t val;
64+
65+
val = sys_read32(config->reg_port + REG_DIN);
66+
sys_write32(val & pins, config->reg_port + REG_DCLR);
67+
68+
return 0;
69+
}
70+
71+
static int gpio_tms570_port_set_masked_raw(const struct device *dev,
72+
gpio_port_pins_t mask,
73+
gpio_port_value_t value)
74+
{
75+
const struct gpio_tms570_config *config = dev->config;
76+
uint32_t cur_out;
77+
uint32_t cur_dir;
78+
uint32_t val_set;
79+
uint32_t val_clr;
80+
81+
cur_out = sys_read32(config->reg_port + REG_DIN);
82+
cur_dir = sys_read32(config->reg_port + REG_DIR);
83+
val_clr = cur_dir & cur_out & ~value & mask;
84+
val_set = cur_dir & ~cur_out & value & mask;
85+
86+
sys_write32(val_clr, config->reg_port + REG_DCLR);
87+
sys_write32(val_set, config->reg_port + REG_DSET);
88+
89+
return 0;
90+
}
91+
92+
static int gpio_tms570_port_toggle_bits(const struct device *dev,
93+
gpio_port_pins_t pins)
94+
{
95+
const struct gpio_tms570_config *config = dev->config;
96+
uint32_t cur_out;
97+
uint32_t cur_dir;
98+
uint32_t val_set;
99+
uint32_t val_clr;
100+
101+
cur_out = sys_read32(config->reg_port + REG_DIN);
102+
cur_dir = sys_read32(config->reg_port + REG_DIR);
103+
val_clr = cur_dir & cur_out & pins;
104+
val_set = cur_dir & ~cur_out & pins;
105+
sys_write32(val_clr, config->reg_port + REG_DCLR);
106+
sys_write32(val_set, config->reg_port + REG_DSET);
107+
108+
return 0;
109+
}
110+
111+
112+
static int gpio_tms570_get(const struct device *dev, gpio_port_value_t *value)
113+
{
114+
const struct gpio_tms570_config *config = dev->config;
115+
116+
*value = sys_read32(config->reg_port + REG_DIN);
117+
118+
return 0;
119+
}
120+
121+
static int gpio_tms570_configure(const struct device *dev, gpio_pin_t pin, gpio_flags_t flags)
122+
{
123+
const struct gpio_tms570_config *config = dev->config;
124+
uint32_t current_config;
125+
int ret;
126+
127+
/* Read the current configuration of the pins */
128+
current_config = sys_read32(config->reg_port + REG_DIR);
129+
130+
/* We only support changes in the direction of the pins */
131+
if ((flags & GPIO_INPUT) != 0U) {
132+
/* Pins specified as input will have their DIR register's bit set to 0 */
133+
sys_write32(current_config & ~BIT(pin), config->reg_port + REG_DIR);
134+
} else if ((flags & GPIO_OUTPUT) != 0U) {
135+
/* Pins specified as output will have their DIR register's bit set to 1 */
136+
sys_write32(current_config | BIT(pin), config->reg_port + REG_DIR);
137+
138+
if ((flags & GPIO_OUTPUT_INIT_HIGH) != 0U) {
139+
ret = gpio_tms570_set_bits(dev, (gpio_port_pins_t)BIT(pin));
140+
if (ret < 0) {
141+
return ret;
142+
}
143+
} else if ((flags & GPIO_OUTPUT_INIT_LOW) != 0U) {
144+
ret = gpio_tms570_clear_bits(dev, (gpio_port_pins_t)BIT(pin));
145+
if (ret < 0) {
146+
return ret;
147+
}
148+
}
149+
} else {
150+
return -EINVAL;
151+
}
152+
153+
return 0;
154+
}
155+
156+
static int gpio_tms570_pin_interrupt_configure(const struct device *dev, gpio_pin_t pin,
157+
enum gpio_int_mode mode, enum gpio_int_trig trig)
158+
{
159+
return -ENOTSUP;
160+
}
161+
162+
static int gpio_tms570_manage_callback(const struct device *dev, struct gpio_callback *callback,
163+
bool set)
164+
{
165+
return -ENOTSUP;
166+
}
167+
168+
static const struct gpio_driver_api gpio_tms570_api = {
169+
.port_get_raw = gpio_tms570_get,
170+
.port_set_masked_raw = gpio_tms570_port_set_masked_raw,
171+
.port_set_bits_raw = gpio_tms570_set_bits,
172+
.port_clear_bits_raw = gpio_tms570_clear_bits,
173+
.pin_configure = gpio_tms570_configure,
174+
.port_toggle_bits = gpio_tms570_port_toggle_bits,
175+
.pin_interrupt_configure = gpio_tms570_pin_interrupt_configure,
176+
.manage_callback = gpio_tms570_manage_callback,
177+
};
178+
179+
static int gpio_tms570_init(const struct device *dev)
180+
{
181+
const struct gpio_tms570_config *config = dev->config;
182+
static int gpio_tms570_init_done;
183+
184+
if (gpio_tms570_init_done == 0) {
185+
gpio_tms570_init_done = 1;
186+
sys_write32(1, config->reg_gio + REG_GCR0);
187+
sys_write32(0xFFU, config->reg_gio + REG_ENACLR);
188+
sys_write32(0xFFU, config->reg_gio + REG_LVLCLR);
189+
}
190+
191+
return 0;
192+
}
193+
194+
#define TMS570_GPIO_INIT(n) \
195+
static struct gpio_tms570_data gpio_tms570_data_##n = { \
196+
}; \
197+
static struct gpio_tms570_config gpio_tms570_config_##n = { \
198+
.common = { \
199+
.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(n), \
200+
}, \
201+
.reg_port = DT_INST_REG_ADDR_BY_IDX(n, 0), \
202+
.reg_gio = DT_INST_REG_ADDR_BY_IDX(n, 1), \
203+
}; \
204+
DEVICE_DT_INST_DEFINE(n, gpio_tms570_init, NULL, \
205+
&gpio_tms570_data_##n, &gpio_tms570_config_##n, \
206+
POST_KERNEL, CONFIG_GPIO_INIT_PRIORITY, \
207+
&gpio_tms570_api);
208+
209+
DT_INST_FOREACH_STATUS_OKAY(TMS570_GPIO_INIT)

dts/arm/ti/tms570.dtsi

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,5 +124,29 @@
124124
reg = <0xfff7e500 256>;
125125
status = "disabled";
126126
};
127+
128+
gpio_a: gpio@fff7bc34 {
129+
compatible = "ti,tms570-gpio";
130+
reg = <0xfff7bc34 0x34 /* GIO port base */
131+
0xfff7bc00 0x20>; /* GIO base */
132+
interrupts = <13 0>;
133+
interrupt-parent = <&vim>;
134+
gpio-controller;
135+
#gpio-cells = <2>;
136+
ngpios = <8>;
137+
status = "okay";
138+
};
139+
140+
gpio_b: gpio@fff7bc54 {
141+
compatible = "ti,tms570-gpio";
142+
reg = <0xfff7bc54 0x34 /* GIO port base */
143+
0xfff7bc00 0x20>; /* GIO base */
144+
interrupts = <13 0>;
145+
interrupt-parent = <&vim>;
146+
gpio-controller;
147+
#gpio-cells = <2>;
148+
ngpios = <8>;
149+
status = "okay";
150+
};
127151
};
128152
};
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Copyright (c) 2025 ispace, inc.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
description: TMS570 GPIO
5+
6+
compatible: "ti,tms570-gpio"
7+
8+
include: [gpio-controller.yaml, base.yaml]
9+
10+
properties:
11+
# NOTE: Register ranges:
12+
# - 0 : GIO port registers
13+
# - 1 : GIO base registers
14+
reg:
15+
required: true
16+
17+
interrupt-parent:
18+
required: true
19+
20+
ngpios:
21+
required: true
22+
23+
gpio-cells:
24+
- pin
25+
- flags

0 commit comments

Comments
 (0)