Changeset View
Changeset View
Standalone View
Standalone View
sys/arm/mv/mvebu_gpio.c
Show First 20 Lines • Show All 118 Lines • ▼ Show 20 Lines | |||||
}; | }; | ||||
/* -------------------------------------------------------------------------- | /* -------------------------------------------------------------------------- | ||||
* | * | ||||
* GPIO | * GPIO | ||||
* | * | ||||
*/ | */ | ||||
static inline void | static inline void | ||||
gpio_modify(struct mvebu_gpio_softc *sc, bus_size_t reg, | |||||
struct gpio_pin *pin, uint32_t val) | |||||
{ | |||||
int bit; | |||||
bit = GPIO_BIT(pin->gp_pin); | |||||
SYSCON_MODIFY_4(sc->syscon, sc->offset + GPIO_REGNUM(pin->gp_pin) + reg, | |||||
0x1 << bit, (val & 1) << bit); | |||||
} | |||||
static inline void | |||||
gpio_write(struct mvebu_gpio_softc *sc, bus_size_t reg, | gpio_write(struct mvebu_gpio_softc *sc, bus_size_t reg, | ||||
struct gpio_pin *pin, uint32_t val) | struct gpio_pin *pin, uint32_t val) | ||||
{ | { | ||||
uint32_t tmp; | |||||
int bit; | int bit; | ||||
bit = GPIO_BIT(pin->gp_pin); | bit = GPIO_BIT(pin->gp_pin); | ||||
tmp = 0x100 << bit; /* mask */ | |||||
tmp |= (val & 1) << bit; /* value */ | |||||
SYSCON_WRITE_4(sc->syscon, sc->offset + GPIO_REGNUM(pin->gp_pin) + reg, | SYSCON_WRITE_4(sc->syscon, sc->offset + GPIO_REGNUM(pin->gp_pin) + reg, | ||||
tmp); | (val & 1) << bit); | ||||
} | } | ||||
static inline uint32_t | static inline uint32_t | ||||
gpio_read(struct mvebu_gpio_softc *sc, bus_size_t reg, struct gpio_pin *pin) | gpio_read(struct mvebu_gpio_softc *sc, bus_size_t reg, struct gpio_pin *pin) | ||||
{ | { | ||||
int bit; | int bit; | ||||
uint32_t val; | uint32_t val; | ||||
Show All 10 Lines | mvebu_gpio_pin_configure(struct mvebu_gpio_softc *sc, struct gpio_pin *pin, | ||||
if ((flags & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) == 0) | if ((flags & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) == 0) | ||||
return; | return; | ||||
/* Manage input/output */ | /* Manage input/output */ | ||||
pin->gp_flags &= ~(GPIO_PIN_INPUT | GPIO_PIN_OUTPUT); | pin->gp_flags &= ~(GPIO_PIN_INPUT | GPIO_PIN_OUTPUT); | ||||
if (flags & GPIO_PIN_OUTPUT) { | if (flags & GPIO_PIN_OUTPUT) { | ||||
pin->gp_flags |= GPIO_PIN_OUTPUT; | pin->gp_flags |= GPIO_PIN_OUTPUT; | ||||
gpio_write(sc, GPIO_CONTROL_SET, pin, 1); | gpio_write(sc, GPIO_CONTROL_SET, pin, 1); | ||||
mmel: No, this change is wrong. GPIO have their own register for setting or clearing pin direction. | |||||
} else { | } else { | ||||
pin->gp_flags |= GPIO_PIN_INPUT; | pin->gp_flags |= GPIO_PIN_INPUT; | ||||
gpio_write(sc, GPIO_CONTROL_CLR, pin, 1); | gpio_write(sc, GPIO_CONTROL_CLR, pin, 1); | ||||
} | } | ||||
} | } | ||||
static device_t | static device_t | ||||
mvebu_gpio_get_bus(device_t dev) | mvebu_gpio_get_bus(device_t dev) | ||||
▲ Show 20 Lines • Show All 75 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
struct mvebu_gpio_softc *sc; | struct mvebu_gpio_softc *sc; | ||||
sc = device_get_softc(dev); | sc = device_get_softc(dev); | ||||
if (pin >= sc->gpio_npins) | if (pin >= sc->gpio_npins) | ||||
return (EINVAL); | return (EINVAL); | ||||
if (value != 0) | if (value != 0) | ||||
gpio_write(sc, GPIO_DATA_SET, &sc->gpio_pins[pin], 1); | gpio_write(sc, GPIO_DATA_SET, &sc->gpio_pins[pin], 1); | ||||
Done Inline Actionsditto. mmel: ditto. | |||||
else | else | ||||
gpio_write(sc, GPIO_DATA_CLR, &sc->gpio_pins[pin], 1); | gpio_write(sc, GPIO_DATA_CLR, &sc->gpio_pins[pin], 1); | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
mvebu_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val) | mvebu_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val) | ||||
Show All 20 Lines | mvebu_gpio_pin_toggle(device_t dev, uint32_t pin) | ||||
sc = device_get_softc(dev); | sc = device_get_softc(dev); | ||||
if (pin >= sc->gpio_npins) | if (pin >= sc->gpio_npins) | ||||
return (EINVAL); | return (EINVAL); | ||||
GPIO_LOCK(sc); | GPIO_LOCK(sc); | ||||
mvebu_gpio_pin_get(sc->dev, pin, &val); | mvebu_gpio_pin_get(sc->dev, pin, &val); | ||||
if (val != 0) | if (val != 0) | ||||
gpio_write(sc, GPIO_DATA_CLR, &sc->gpio_pins[pin], 1); | gpio_write(sc, GPIO_DATA_CLR, &sc->gpio_pins[pin], 1); | ||||
Done Inline Actionsditto mmel: ditto | |||||
else | else | ||||
gpio_write(sc, GPIO_DATA_SET, &sc->gpio_pins[pin], 1); | gpio_write(sc, GPIO_DATA_SET, &sc->gpio_pins[pin], 1); | ||||
GPIO_UNLOCK(sc); | GPIO_UNLOCK(sc); | ||||
return (0); | return (0); | ||||
} | } | ||||
/* -------------------------------------------------------------------------- | /* -------------------------------------------------------------------------- | ||||
▲ Show 20 Lines • Show All 469 Lines • ▼ Show 20 Lines | for (i = 0; i < sc->gpio_npins; i++) { | ||||
else | else | ||||
pin->gp_caps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT; | pin->gp_caps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT; | ||||
pin->gp_flags = | pin->gp_flags = | ||||
gpio_read(sc, GPIO_CONTROL, &sc->gpio_pins[i]) != 0 ? | gpio_read(sc, GPIO_CONTROL, &sc->gpio_pins[i]) != 0 ? | ||||
GPIO_PIN_OUTPUT : GPIO_PIN_INPUT; | GPIO_PIN_OUTPUT : GPIO_PIN_INPUT; | ||||
snprintf(pin->gp_name, GPIOMAXNAME, "gpio%d", i); | snprintf(pin->gp_name, GPIOMAXNAME, "gpio%d", i); | ||||
/* Init HW */ | /* Init HW */ | ||||
gpio_write(sc, GPIO_INT_MASK, pin, 0); | gpio_modify(sc, GPIO_INT_MASK, pin, 0); | ||||
gpio_write(sc, GPIO_INT_LEVEL_MASK, pin, 0); | gpio_modify(sc, GPIO_INT_LEVEL_MASK, pin, 0); | ||||
gpio_write(sc, GPIO_INT_CAUSE, pin, 0); | gpio_modify(sc, GPIO_INT_CAUSE, pin, 0); | ||||
gpio_write(sc, GPIO_DATA_IN_POL, pin, 1); | gpio_modify(sc, GPIO_DATA_IN_POL, pin, 1); | ||||
gpio_write(sc, GPIO_BLINK_ENA, pin, 0); | gpio_modify(sc, GPIO_BLINK_ENA, pin, 0); | ||||
} | } | ||||
if (sc->irq_res[0] != NULL) { | if (sc->irq_res[0] != NULL) { | ||||
rv = mvebu_gpio_pic_attach(sc); | rv = mvebu_gpio_pic_attach(sc); | ||||
if (rv != 0) { | if (rv != 0) { | ||||
device_printf(dev, "WARNING: unable to attach PIC\n"); | device_printf(dev, "WARNING: unable to attach PIC\n"); | ||||
mvebu_gpio_detach(dev); | mvebu_gpio_detach(dev); | ||||
return (rv); | return (rv); | ||||
▲ Show 20 Lines • Show All 71 Lines • Show Last 20 Lines |
No, this change is wrong. GPIO have their own register for setting or clearing pin direction. Full register write is right at this place.