Changeset View
Changeset View
Standalone View
Standalone View
head/sys/arm64/rockchip/rk_gpio.c
Show First 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | |||||
#include <dev/gpio/gpiobusvar.h> | #include <dev/gpio/gpiobusvar.h> | ||||
#include <dev/ofw/ofw_bus.h> | #include <dev/ofw/ofw_bus.h> | ||||
#include <dev/ofw/ofw_bus_subr.h> | #include <dev/ofw/ofw_bus_subr.h> | ||||
#include <dev/extres/clk/clk.h> | #include <dev/extres/clk/clk.h> | ||||
#include "gpio_if.h" | #include "gpio_if.h" | ||||
#include "fdt_pinctrl_if.h" | |||||
#define RK_GPIO_SWPORTA_DR 0x00 /* Data register */ | #define RK_GPIO_SWPORTA_DR 0x00 /* Data register */ | ||||
#define RK_GPIO_SWPORTA_DDR 0x04 /* Data direction register */ | #define RK_GPIO_SWPORTA_DDR 0x04 /* Data direction register */ | ||||
#define RK_GPIO_INTEN 0x30 /* Interrupt enable register */ | #define RK_GPIO_INTEN 0x30 /* Interrupt enable register */ | ||||
#define RK_GPIO_INTMASK 0x34 /* Interrupt mask register */ | #define RK_GPIO_INTMASK 0x34 /* Interrupt mask register */ | ||||
#define RK_GPIO_INTTYPE_LEVEL 0x38 /* Interrupt level register */ | #define RK_GPIO_INTTYPE_LEVEL 0x38 /* Interrupt level register */ | ||||
#define RK_GPIO_INT_POLARITY 0x3C /* Interrupt polarity register */ | #define RK_GPIO_INT_POLARITY 0x3C /* Interrupt polarity register */ | ||||
#define RK_GPIO_INT_STATUS 0x40 /* Interrupt status register */ | #define RK_GPIO_INT_STATUS 0x40 /* Interrupt status register */ | ||||
#define RK_GPIO_INT_RAWSTATUS 0x44 /* Raw Interrupt status register */ | #define RK_GPIO_INT_RAWSTATUS 0x44 /* Raw Interrupt status register */ | ||||
#define RK_GPIO_DEBOUNCE 0x48 /* Debounce enable register */ | #define RK_GPIO_DEBOUNCE 0x48 /* Debounce enable register */ | ||||
#define RK_GPIO_PORTA_EOI 0x4C /* Clear interrupt register */ | #define RK_GPIO_PORTA_EOI 0x4C /* Clear interrupt register */ | ||||
#define RK_GPIO_EXT_PORTA 0x50 /* External port register */ | #define RK_GPIO_EXT_PORTA 0x50 /* External port register */ | ||||
#define RK_GPIO_LS_SYNC 0x60 /* Level sensitive syncronization enable register */ | #define RK_GPIO_LS_SYNC 0x60 /* Level sensitive syncronization enable register */ | ||||
#define RK_GPIO_DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | \ | |||||
GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN) | |||||
struct rk_gpio_softc { | struct rk_gpio_softc { | ||||
device_t sc_dev; | device_t sc_dev; | ||||
device_t sc_busdev; | device_t sc_busdev; | ||||
struct mtx sc_mtx; | struct mtx sc_mtx; | ||||
struct resource *sc_res[2]; | struct resource *sc_res[2]; | ||||
bus_space_tag_t sc_bst; | bus_space_tag_t sc_bst; | ||||
bus_space_handle_t sc_bsh; | bus_space_handle_t sc_bsh; | ||||
clk_t clk; | clk_t clk; | ||||
device_t pinctrl; | |||||
}; | }; | ||||
static struct ofw_compat_data compat_data[] = { | static struct ofw_compat_data compat_data[] = { | ||||
{"rockchip,gpio-bank", 1}, | {"rockchip,gpio-bank", 1}, | ||||
{NULL, 0} | {NULL, 0} | ||||
}; | }; | ||||
static struct resource_spec rk_gpio_spec[] = { | static struct resource_spec rk_gpio_spec[] = { | ||||
Show All 31 Lines | |||||
rk_gpio_attach(device_t dev) | rk_gpio_attach(device_t dev) | ||||
{ | { | ||||
struct rk_gpio_softc *sc; | struct rk_gpio_softc *sc; | ||||
phandle_t node; | phandle_t node; | ||||
int err; | int err; | ||||
sc = device_get_softc(dev); | sc = device_get_softc(dev); | ||||
sc->sc_dev = dev; | sc->sc_dev = dev; | ||||
sc->pinctrl = device_get_parent(dev); | |||||
node = ofw_bus_get_node(sc->sc_dev); | node = ofw_bus_get_node(sc->sc_dev); | ||||
if (!OF_hasprop(node, "gpio-controller")) | if (!OF_hasprop(node, "gpio-controller")) | ||||
return (ENXIO); | return (ENXIO); | ||||
mtx_init(&sc->sc_mtx, "rk gpio", "gpio", MTX_SPIN); | mtx_init(&sc->sc_mtx, "rk gpio", "gpio", MTX_SPIN); | ||||
if (bus_alloc_resources(dev, rk_gpio_spec, sc->sc_res)) { | if (bus_alloc_resources(dev, rk_gpio_spec, sc->sc_res)) { | ||||
▲ Show 20 Lines • Show All 81 Lines • ▼ Show 20 Lines | rk_gpio_pin_getname(device_t dev, uint32_t pin, char *name) | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
rk_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags) | rk_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags) | ||||
{ | { | ||||
struct rk_gpio_softc *sc; | struct rk_gpio_softc *sc; | ||||
uint32_t reg; | uint32_t reg; | ||||
int rv; | |||||
bool is_gpio; | |||||
sc = device_get_softc(dev); | sc = device_get_softc(dev); | ||||
/* XXX Combine this with parent (pinctrl) */ | rv = FDT_PINCTRL_IS_GPIO(sc->pinctrl, dev, pin, &is_gpio); | ||||
if (rv != 0) | |||||
return (rv); | |||||
if (!is_gpio) | |||||
return (EINVAL); | |||||
*flags = 0; | |||||
rv = FDT_PINCTRL_GET_FLAGS(sc->pinctrl, dev, pin, flags); | |||||
if (rv != 0) | |||||
return (rv); | |||||
RK_GPIO_LOCK(sc); | RK_GPIO_LOCK(sc); | ||||
reg = RK_GPIO_READ(sc, RK_GPIO_SWPORTA_DDR); | reg = RK_GPIO_READ(sc, RK_GPIO_SWPORTA_DDR); | ||||
RK_GPIO_UNLOCK(sc); | RK_GPIO_UNLOCK(sc); | ||||
if (reg & (1 << pin)) | if (reg & (1 << pin)) | ||||
*flags = GPIO_PIN_OUTPUT; | *flags |= GPIO_PIN_OUTPUT; | ||||
else | else | ||||
*flags = GPIO_PIN_INPUT; | *flags |= GPIO_PIN_INPUT; | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
rk_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps) | rk_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps) | ||||
{ | { | ||||
/* Caps are managed by the pinctrl device */ | *caps = RK_GPIO_DEFAULT_CAPS; | ||||
/* XXX Pass this to parent (pinctrl) */ | |||||
*caps = 0; | |||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
rk_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) | rk_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) | ||||
{ | { | ||||
struct rk_gpio_softc *sc; | struct rk_gpio_softc *sc; | ||||
uint32_t reg; | uint32_t reg; | ||||
int rv; | |||||
bool is_gpio; | |||||
sc = device_get_softc(dev); | sc = device_get_softc(dev); | ||||
/* XXX Combine this with parent (pinctrl) */ | rv = FDT_PINCTRL_IS_GPIO(sc->pinctrl, dev, pin, &is_gpio); | ||||
if (rv != 0) | |||||
return (rv); | |||||
if (!is_gpio) | |||||
return (EINVAL); | |||||
rv = FDT_PINCTRL_SET_FLAGS(sc->pinctrl, dev, pin, flags); | |||||
if (rv != 0) | |||||
return (rv); | |||||
RK_GPIO_LOCK(sc); | RK_GPIO_LOCK(sc); | ||||
reg = RK_GPIO_READ(sc, RK_GPIO_SWPORTA_DDR); | reg = RK_GPIO_READ(sc, RK_GPIO_SWPORTA_DDR); | ||||
if (flags & GPIO_PIN_INPUT) | if (flags & GPIO_PIN_INPUT) | ||||
reg &= ~(1 << pin); | reg &= ~(1 << pin); | ||||
else if (flags & GPIO_PIN_OUTPUT) | else if (flags & GPIO_PIN_OUTPUT) | ||||
reg |= (1 << pin); | reg |= (1 << pin); | ||||
▲ Show 20 Lines • Show All 181 Lines • Show Last 20 Lines |