Skip to content

Commit

Permalink
drivers: gpio: Add Davinci gpio controller support
Browse files Browse the repository at this point in the history
Davinci gpio controller support to add various soc gpio
support (J721E, AM654).

TRM for J721e https://www.ti.com/lit/zip/spruil1
File: spruil1c.pdf
GPIO: section 12.1.2

BeagleBone AI_64 https://beagleboard.org/ai-64

Signed-off-by: Prashanth S <slpp95prashanth@yahoo.com>
  • Loading branch information
slpp95prashanth committed Aug 24, 2023
1 parent a5895d6 commit 6226697
Show file tree
Hide file tree
Showing 6 changed files with 252 additions and 0 deletions.
1 change: 1 addition & 0 deletions drivers/gpio/CMakeLists.txt
Expand Up @@ -80,6 +80,7 @@ zephyr_library_sources_ifdef(CONFIG_GPIO_NUMICRO gpio_numicro.c)
zephyr_library_sources_ifdef(CONFIG_GPIO_HOGS gpio_hogs.c)
zephyr_library_sources_ifdef(CONFIG_GPIO_NUMAKER gpio_numaker.c)
zephyr_library_sources_ifdef(CONFIG_GPIO_EFINIX_SAPPHIRE gpio_efinix_sapphire.c)
zephyr_library_sources_ifdef(CONFIG_GPIO_DAVINCI gpio_davinci.c)

if (CONFIG_GPIO_EMUL_SDL)
zephyr_library_sources(gpio_emul_sdl.c)
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpio/Kconfig
Expand Up @@ -201,4 +201,6 @@ source "drivers/gpio/Kconfig.numaker"

source "drivers/gpio/Kconfig.efinix_sapphire"

source "drivers/gpio/Kconfig.davinci"

endif # GPIO
11 changes: 11 additions & 0 deletions drivers/gpio/Kconfig.davinci
@@ -0,0 +1,11 @@
# Copyright (C) 2023 BeagleBoard.org Foundation
# Copyright (C) 2023 S Prashanth
#
# SPDX-License-Identifier: Apache-2.0

config GPIO_DAVINCI
bool "Davinci GPIO Driver"
default y
depends on DT_HAS_TI_DAVINCI_GPIO_ENABLED
help
Enable the Davinci GPIO controller support.
199 changes: 199 additions & 0 deletions drivers/gpio/gpio_davinci.c
@@ -0,0 +1,199 @@
/*
* Copyright (C) 2023 BeagleBoard.org Foundation
* Copyright (C) 2023 S Prashanth
*
* SPDX-License-Identifier: Apache-2.0
*/

#define DT_DRV_COMPAT ti_davinci_gpio

#include <errno.h>

#include <zephyr/arch/common/sys_bitops.h>
#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/gpio/gpio_utils.h>
#include <zephyr/init.h>
#include <zephyr/kernel.h>
#include <zephyr/sys/sys_io.h>

/* Helper Macros for GPIO */
#define DEV_CFG(dev) \
((const struct gpio_davinci_config * const)((dev)->config))
#define DEV_DATA(dev) ((struct gpio_davinci_data *)(dev)->data)
#define DEV_GPIO_CFG_BASE(dev) \
((struct gpio_davinci_regs *)DEVICE_MMIO_NAMED_GET(dev, port_base))

#define GPIO_DAVINCI_DIR_RESET_VAL (0xFFFFFFFF)

struct gpio_davinci_regs {
uint32_t dir;
uint32_t out_data;
uint32_t set_data;
uint32_t clr_data;
uint32_t in_data;
uint32_t set_ris_trig;
uint32_t clr_ris_trig;
uint32_t set_fal_trig;
uint32_t clr_fal_trig;
uint32_t intstat;
};

struct gpio_davinci_data {
struct gpio_driver_data common;

DEVICE_MMIO_NAMED_RAM(port_base);

sys_slist_t cb;
};

struct gpio_davinci_config {
void (*bank_config)(const struct device *dev);
struct gpio_driver_config common;

DEVICE_MMIO_NAMED_ROM(port_base);

uint32_t port_num;
};

static int gpio_davinci_configure(const struct device *dev, gpio_pin_t pin,
gpio_flags_t flags)
{
volatile struct gpio_davinci_regs *regs = DEV_GPIO_CFG_BASE(dev);

if ((flags & GPIO_SINGLE_ENDED) != 0) {
return -ENOTSUP;
}

if ((flags & (GPIO_PULL_UP | GPIO_PULL_DOWN)) != 0) {
return -ENOTSUP;
}

if ((flags & GPIO_OUTPUT) != 0) {
if ((flags & GPIO_OUTPUT_INIT_HIGH) != 0) {
regs->set_data = BIT(pin);
} else {
regs->clr_data = BIT(pin);
}

regs->dir &= (~(BIT(pin)));

} else {
regs->dir |= (BIT(pin));
}

return 0;
}

static int gpio_davinci_port_get_raw(const struct device *dev,
gpio_port_value_t *value)
{
volatile struct gpio_davinci_regs *regs = DEV_GPIO_CFG_BASE(dev);

*value = regs->in_data;

return 0;
}

static int gpio_davinci_port_set_masked_raw(const struct device *dev,
gpio_port_pins_t mask, gpio_port_value_t value)
{
volatile struct gpio_davinci_regs *regs = DEV_GPIO_CFG_BASE(dev);

regs->out_data = (regs->out_data & (~mask)) | (mask & value);

return 0;
}

static int gpio_davinci_port_set_bits_raw(const struct device *dev,
gpio_port_pins_t mask)
{
volatile struct gpio_davinci_regs *regs = DEV_GPIO_CFG_BASE(dev);

regs->set_data |= mask;

return 0;
}

static int gpio_davinci_port_clear_bits_raw(const struct device *dev,
gpio_port_pins_t mask)
{
volatile struct gpio_davinci_regs *regs = DEV_GPIO_CFG_BASE(dev);

regs->clr_data |= mask;

return 0;
}

static int gpio_davinci_port_toggle_bits(const struct device *dev,
gpio_port_pins_t mask)
{
volatile struct gpio_davinci_regs *regs = DEV_GPIO_CFG_BASE(dev);

regs->out_data ^= mask;

return 0;
}

static const struct gpio_driver_api gpio_davinci_driver_api = {
.pin_configure = gpio_davinci_configure,
.port_get_raw = gpio_davinci_port_get_raw,
.port_set_masked_raw = gpio_davinci_port_set_masked_raw,
.port_set_bits_raw = gpio_davinci_port_set_bits_raw,
.port_clear_bits_raw = gpio_davinci_port_clear_bits_raw,
.port_toggle_bits = gpio_davinci_port_toggle_bits
};

static int gpio_davinci_init(const struct device *dev)
{
const struct gpio_davinci_config *config = DEV_CFG(dev);
volatile struct gpio_davinci_regs *regs = DEV_GPIO_CFG_BASE(dev);

DEVICE_MMIO_NAMED_MAP(dev, port_base, K_MEM_CACHE_NONE);

regs->dir = GPIO_DAVINCI_DIR_RESET_VAL;

config->bank_config(dev);

return 0;
}

#define GPIO_DAVINCI_INIT_FUNC(n) \
static void gpio_davinci_bank_##n##_config(const struct device *dev) \
{ \
volatile struct gpio_davinci_regs *regs = DEV_GPIO_CFG_BASE(dev); \
ARG_UNUSED(regs); \
}

#define GPIO_DAVINCI_DEVICE_INIT(n) \
DEVICE_DT_INST_DEFINE(n, &gpio_davinci_##n##_init, \
NULL, &gpio_davinci_##n##_data, \
&gpio_davinci_##n##_config, \
POST_KERNEL, CONFIG_GPIO_INIT_PRIORITY, \
&api_funcs)

#define GPIO_DAVINCI_INIT(n) \
\
GPIO_DAVINCI_INIT_FUNC(n) \
static const struct gpio_davinci_config gpio_davinci_##n##_config = { \
.bank_config = gpio_davinci_bank_##n##_config, \
.common = { \
.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(n), \
}, \
DEVICE_MMIO_NAMED_ROM_INIT(port_base, DT_DRV_INST(n)), \
.port_num = n \
}; \
\
static struct gpio_davinci_data gpio_davinci_##n##_data; \
\
DEVICE_DT_INST_DEFINE(n, \
&gpio_davinci_init, \
NULL, \
&gpio_davinci_##n##_data, \
&gpio_davinci_##n##_config, \
PRE_KERNEL_2, \
CONFIG_GPIO_INIT_PRIORITY, \
&gpio_davinci_driver_api);

DT_INST_FOREACH_STATUS_OKAY(GPIO_DAVINCI_INIT)
18 changes: 18 additions & 0 deletions dts/bindings/gpio/ti,davinci-gpio-nexus.yaml
@@ -0,0 +1,18 @@
# Copyright (C) 2023 BeagleBoard.org Foundation
# Copyright (C) 2023 S Prashanth
#
# SPDX-License-Identifier: Apache-2.0

description: GPIO controller for Davinci and Keystone devices

compatible: "ti,davinci-gpio-nexus"

include: [base.yaml, gpio-nexus.yaml]

properties:
"#gpio-cells":
const: 2

gpio-cells:
- pin
- flags
21 changes: 21 additions & 0 deletions dts/bindings/gpio/ti,davinci-gpio.yaml
@@ -0,0 +1,21 @@
# Copyright (C) 2023 BeagleBoard.org Foundation
# Copyright (C) 2023 S Prashanth
#
# SPDX-License-Identifier: Apache-2.0

description: GPIO controller for Davinci and Keystone devices.

compatible: "ti,davinci-gpio"

include: [gpio-controller.yaml, base.yaml]

properties:
reg:
required: true

"#gpio-cells":
const: 2

gpio-cells:
- pin
- flags

0 comments on commit 6226697

Please sign in to comment.