Changeset View
Changeset View
Standalone View
Standalone View
sys/arm64/qoriq/ls1046_gpio.c
Show First 20 Lines • Show All 74 Lines • ▼ Show 20 Lines | |||||
}; | }; | ||||
#define QORIQ_GPIO_LOCK(_sc) mtx_lock_spin(&(_sc)->mutex) | #define QORIQ_GPIO_LOCK(_sc) mtx_lock_spin(&(_sc)->mutex) | ||||
#define QORIQ_GPIO_UNLOCK(_sc) mtx_unlock_spin(&(_sc)->mutex) | #define QORIQ_GPIO_UNLOCK(_sc) mtx_unlock_spin(&(_sc)->mutex) | ||||
#define QORIQ_GPIO_ASSERT_LOCKED(_sc) mtx_assert(&(_sc)->mutex, MA_OWNED) | #define QORIQ_GPIO_ASSERT_LOCKED(_sc) mtx_assert(&(_sc)->mutex, MA_OWNED) | ||||
/* prototypes */ | /* prototypes */ | ||||
/* helpers */ | /* helpers */ | ||||
static int qoriq_make_gpio_res(device_t, struct gpio_res*); | static bool qoriq_make_gpio_res(device_t, struct gpio_res*); | ||||
static uint32_t qoriq_gpio_reg_read(device_t, uint32_t); | static uint32_t qoriq_gpio_reg_read(device_t, uint32_t); | ||||
static void qoriq_gpio_reg_write(device_t, uint32_t, uint32_t); | static void qoriq_gpio_reg_write(device_t, uint32_t, uint32_t); | ||||
static void qoriq_gpio_reg_set(device_t, uint32_t, uint32_t); | static void qoriq_gpio_reg_set(device_t, uint32_t, uint32_t); | ||||
static void qoriq_gpio_reg_clear(device_t, uint32_t, uint32_t); | static void qoriq_gpio_reg_clear(device_t, uint32_t, uint32_t); | ||||
static void qoriq_gpio_out_en(device_t, uint32_t, uint8_t); | static void qoriq_gpio_out_en(device_t, uint32_t, uint8_t); | ||||
static void qoriq_gpio_value_set(device_t, uint32_t, uint8_t); | static void qoriq_gpio_value_set(device_t, uint32_t, uint8_t); | ||||
static uint32_t qoriq_gpio_value_get(device_t, uint32_t); | static uint32_t qoriq_gpio_value_get(device_t, uint32_t); | ||||
static void qoriq_gpio_open_drain_set(device_t, uint32_t, uint8_t); | static void qoriq_gpio_open_drain_set(device_t, uint32_t, uint8_t); | ||||
▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | |||||
static devclass_t gpio_devclass; | static devclass_t gpio_devclass; | ||||
DRIVER_MODULE(gpio, simplebus, gpio_driver, gpio_devclass, 0, 0); | DRIVER_MODULE(gpio, simplebus, gpio_driver, gpio_devclass, 0, 0); | ||||
MODULE_VERSION(gpio, 1); | MODULE_VERSION(gpio, 1); | ||||
/* | /* | ||||
* helpers | * helpers | ||||
*/ | */ | ||||
static int | static bool | ||||
emaste: Shall we make this `bool` while we're here? | |||||
qoriq_make_gpio_res(device_t dev, struct gpio_res *out) | qoriq_make_gpio_res(device_t dev, struct gpio_res *out) | ||||
{ | { | ||||
out->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, | out->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, | ||||
&out->mem_rid, RF_ACTIVE | RF_SHAREABLE); | &out->mem_rid, RF_ACTIVE | RF_SHAREABLE); | ||||
if(out->mem_res == NULL) { | return (out->mem_res == NULL); | ||||
return (1); | |||||
} else { | |||||
return (0); | |||||
} | } | ||||
} | |||||
static uint32_t | static uint32_t | ||||
qoriq_gpio_reg_read(device_t dev, uint32_t reg) | qoriq_gpio_reg_read(device_t dev, uint32_t reg) | ||||
{ | { | ||||
struct gpio_softc *sc = device_get_softc(dev); | struct gpio_softc *sc = device_get_softc(dev); | ||||
uint32_t result; | uint32_t result; | ||||
QORIQ_GPIO_ASSERT_LOCKED(sc); | QORIQ_GPIO_ASSERT_LOCKED(sc); | ||||
result = bus_read_4(sc->res.mem_res, reg); | result = bus_read_4(sc->res.mem_res, reg); | ||||
return be32toh(result); | return be32toh(result); | ||||
} | } | ||||
static void | static void | ||||
qoriq_gpio_reg_write(device_t dev, uint32_t reg, uint32_t val) | qoriq_gpio_reg_write(device_t dev, uint32_t reg, uint32_t val) | ||||
{ | { | ||||
struct gpio_softc *sc = device_get_softc(dev); | struct gpio_softc *sc = device_get_softc(dev); | ||||
QORIQ_GPIO_ASSERT_LOCKED(sc); | QORIQ_GPIO_ASSERT_LOCKED(sc); | ||||
val = htobe32(val); | val = htobe32(val); | ||||
bus_write_4(sc->res.mem_res, reg, val); | bus_write_4(sc->res.mem_res, reg, val); | ||||
bus_barrier(sc->res.mem_res, reg, 4, BUS_SPACE_BARRIER_READ | bus_barrier(sc->res.mem_res, reg, 4, BUS_SPACE_BARRIER_READ | | ||||
| BUS_SPACE_BARRIER_WRITE); | BUS_SPACE_BARRIER_WRITE); | ||||
} | } | ||||
static void | static void | ||||
qoriq_gpio_reg_set(device_t dev, uint32_t reg, uint32_t pin) | qoriq_gpio_reg_set(device_t dev, uint32_t reg, uint32_t pin) | ||||
{ | { | ||||
uint32_t reg_val; | uint32_t reg_val; | ||||
reg_val = qoriq_gpio_reg_read(dev, reg); | reg_val = qoriq_gpio_reg_read(dev, reg); | ||||
reg_val |= GPIO(pin); | reg_val |= GPIO(pin); | ||||
qoriq_gpio_reg_write(dev, reg, reg_val); | qoriq_gpio_reg_write(dev, reg, reg_val); | ||||
} | } | ||||
static void | static void | ||||
qoriq_gpio_reg_clear(device_t dev, uint32_t reg, uint32_t pin) | qoriq_gpio_reg_clear(device_t dev, uint32_t reg, uint32_t pin) | ||||
{ | { | ||||
uint32_t reg_val; | uint32_t reg_val; | ||||
reg_val = qoriq_gpio_reg_read(dev, reg); | reg_val = qoriq_gpio_reg_read(dev, reg); | ||||
reg_val &= ~(GPIO(pin)); | reg_val &= ~(GPIO(pin)); | ||||
qoriq_gpio_reg_write(dev, reg, reg_val); | qoriq_gpio_reg_write(dev, reg, reg_val); | ||||
} | } | ||||
static void | static void | ||||
qoriq_gpio_out_en(device_t dev, uint32_t pin, uint8_t enable) | qoriq_gpio_out_en(device_t dev, uint32_t pin, uint8_t enable) | ||||
Not Done Inline ActionsLooks like enable is a boolean; uint8_t seems a little odd. emaste: Looks like `enable` is a boolean; `uint8_t` seems a little odd. | |||||
Done Inline ActionsYes. I would have done that, but I am getting rid of his helper altogether in D26868. ar_semihalf.com: Yes. I would have done that, but I am getting rid of his helper altogether in D26868. | |||||
{ | { | ||||
if (pin >= PIN_COUNT) | if (pin >= PIN_COUNT) | ||||
return; | return; | ||||
if (enable) { | if (enable != 0) | ||||
qoriq_gpio_reg_set(dev, DIRECTION, pin); | qoriq_gpio_reg_set(dev, DIRECTION, pin); | ||||
} else { | else | ||||
qoriq_gpio_reg_clear(dev, DIRECTION, pin); | qoriq_gpio_reg_clear(dev, DIRECTION, pin); | ||||
} | } | ||||
} | |||||
static void | static void | ||||
qoriq_gpio_value_set(device_t dev, uint32_t pin, uint8_t val) | qoriq_gpio_value_set(device_t dev, uint32_t pin, uint8_t val) | ||||
{ | { | ||||
if (pin >= PIN_COUNT) | if (pin >= PIN_COUNT) | ||||
return; | return; | ||||
if (val) { | if (val != 0) | ||||
qoriq_gpio_reg_set(dev, DATA, pin); | qoriq_gpio_reg_set(dev, DATA, pin); | ||||
} else { | else | ||||
qoriq_gpio_reg_clear(dev, DATA, pin); | qoriq_gpio_reg_clear(dev, DATA, pin); | ||||
} | } | ||||
} | |||||
static uint32_t | static uint32_t | ||||
qoriq_gpio_value_get(device_t dev, uint32_t pin) | qoriq_gpio_value_get(device_t dev, uint32_t pin) | ||||
{ | { | ||||
uint32_t reg_val; | uint32_t reg_val; | ||||
if (pin >= PIN_COUNT) | if (pin >= PIN_COUNT) | ||||
return (0); | return (0); | ||||
reg_val = qoriq_gpio_reg_read(dev, DATA); | reg_val = qoriq_gpio_reg_read(dev, DATA); | ||||
return ((reg_val & GPIO(pin)) == 0 ? 0 : 1); | |||||
return ((reg_val & GPIO(pin)) != 0); | |||||
} | } | ||||
static void | static void | ||||
qoriq_gpio_open_drain_set(device_t dev, uint32_t pin, uint8_t val) | qoriq_gpio_open_drain_set(device_t dev, uint32_t pin, uint8_t val) | ||||
{ | { | ||||
if (pin >= PIN_COUNT) { | if (pin >= PIN_COUNT) | ||||
return; | return; | ||||
} | |||||
if (val) { | if (val != 0) | ||||
qoriq_gpio_reg_set(dev, OPEN_DRAIN, pin); | qoriq_gpio_reg_set(dev, OPEN_DRAIN, pin); | ||||
} else { | else | ||||
qoriq_gpio_reg_clear(dev, OPEN_DRAIN, pin); | qoriq_gpio_reg_clear(dev, OPEN_DRAIN, pin); | ||||
} | } | ||||
} | |||||
static int | static int | ||||
qoriq_gpio_configure(device_t dev, uint32_t pin, uint32_t flags) | qoriq_gpio_configure(device_t dev, uint32_t pin, uint32_t flags) | ||||
{ | { | ||||
struct gpio_softc *sc = device_get_softc(dev); | struct gpio_softc *sc = device_get_softc(dev); | ||||
uint32_t newflags; | uint32_t newflags; | ||||
if (pin >= PIN_COUNT) { | if (pin >= PIN_COUNT) | ||||
return (EINVAL); | return (EINVAL); | ||||
} | |||||
/* | /* | ||||
* Pin cannot function as input and output at the same time. | * Pin cannot function as input and output at the same time. | ||||
* The same applies to open-drain and push-pull functionality. | * The same applies to open-drain and push-pull functionality. | ||||
*/ | */ | ||||
if (((flags & GPIO_PIN_INPUT) && (flags & GPIO_PIN_OUTPUT)) | if (((flags & GPIO_PIN_INPUT) && (flags & GPIO_PIN_OUTPUT)) || | ||||
|| ((flags & GPIO_PIN_OPENDRAIN) && (flags & GPIO_PIN_PUSHPULL))) { | ((flags & GPIO_PIN_OPENDRAIN) && (flags & GPIO_PIN_PUSHPULL))) | ||||
return (EINVAL); | return (EINVAL); | ||||
} | |||||
QORIQ_GPIO_ASSERT_LOCKED(sc); | QORIQ_GPIO_ASSERT_LOCKED(sc); | ||||
if (flags & GPIO_PIN_INPUT) { | if (flags & GPIO_PIN_INPUT) { | ||||
newflags = GPIO_PIN_INPUT; | newflags = GPIO_PIN_INPUT; | ||||
qoriq_gpio_out_en(dev, pin, 0); | qoriq_gpio_out_en(dev, pin, 0); | ||||
} | } | ||||
Show All 15 Lines | qoriq_gpio_configure(device_t dev, uint32_t pin, uint32_t flags) | ||||
return (0); | return (0); | ||||
} | } | ||||
/* GPIO API */ | /* GPIO API */ | ||||
static int | static int | ||||
qoriq_gpio_probe(device_t dev) | qoriq_gpio_probe(device_t dev) | ||||
{ | { | ||||
if (!ofw_bus_status_okay(dev)) { | if (!ofw_bus_status_okay(dev)) | ||||
return (ENXIO); | return (ENXIO); | ||||
} | |||||
if (!ofw_bus_is_compatible(dev, "fsl,qoriq-gpio")) { | if (!ofw_bus_is_compatible(dev, "fsl,qoriq-gpio")) | ||||
return (ENXIO); | return (ENXIO); | ||||
} | |||||
device_set_desc(dev, "Integrated GPIO Controller"); | device_set_desc(dev, "Integrated GPIO Controller"); | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
qoriq_gpio_attach(device_t dev) | qoriq_gpio_attach(device_t dev) | ||||
{ | { | ||||
struct gpio_softc *sc = device_get_softc(dev); | struct gpio_softc *sc = device_get_softc(dev); | ||||
int i; | int i; | ||||
if(qoriq_make_gpio_res(dev, &sc->res) != 0) { | if (qoriq_make_gpio_res(dev, &sc->res)) | ||||
return (ENXIO); | return (ENXIO); | ||||
} | |||||
for(i = 0; i < PIN_COUNT; i++) { | for (i = 0; i < PIN_COUNT; i++) | ||||
sc->setup[i].gp_caps = DEFAULT_CAPS; | sc->setup[i].gp_caps = DEFAULT_CAPS; | ||||
} | |||||
sc->dev = dev; | sc->dev = dev; | ||||
sc->busdev = gpiobus_attach_bus(dev); | sc->busdev = gpiobus_attach_bus(dev); | ||||
if(sc->busdev == NULL) { | if (sc->busdev == NULL) | ||||
return (ENXIO); | return (ENXIO); | ||||
} | |||||
return (0); | return (0); | ||||
} | } | ||||
static device_t | static device_t | ||||
qoriq_gpio_get_bus(device_t dev) | qoriq_gpio_get_bus(device_t dev) | ||||
{ | { | ||||
struct gpio_softc *softc = device_get_softc(dev); | struct gpio_softc *softc = device_get_softc(dev); | ||||
return (softc->busdev); | return (softc->busdev); | ||||
} | } | ||||
static int | static int | ||||
qoriq_gpio_pin_max(device_t dev, int *maxpin) | qoriq_gpio_pin_max(device_t dev, int *maxpin) | ||||
{ | { | ||||
if(maxpin == NULL) { | if (maxpin == NULL) | ||||
return (EINVAL); | return (EINVAL); | ||||
} | |||||
*maxpin = PIN_COUNT - 1; | *maxpin = PIN_COUNT - 1; | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
qoriq_gpio_pin_getname(device_t dev, uint32_t pin, char *name) | qoriq_gpio_pin_getname(device_t dev, uint32_t pin, char *name) | ||||
{ | { | ||||
if(name == NULL || pin >= PIN_COUNT) { | if (name == NULL || pin >= PIN_COUNT) | ||||
return (EINVAL); | return (EINVAL); | ||||
} | |||||
snprintf(name, GPIOMAXNAME, "pin %d", pin); | snprintf(name, GPIOMAXNAME, "pin %d", pin); | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
qoriq_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *pflags) | qoriq_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *pflags) | ||||
{ | { | ||||
struct gpio_softc *sc = device_get_softc(dev); | struct gpio_softc *sc = device_get_softc(dev); | ||||
if (pflags == NULL || pin >= PIN_COUNT) { | if (pflags == NULL || pin >= PIN_COUNT) | ||||
return (EINVAL); | return (EINVAL); | ||||
} | |||||
QORIQ_GPIO_LOCK(sc); | QORIQ_GPIO_LOCK(sc); | ||||
*pflags = sc->setup[pin].gp_flags; | *pflags = sc->setup[pin].gp_flags; | ||||
QORIQ_GPIO_UNLOCK(sc); | QORIQ_GPIO_UNLOCK(sc); | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
qoriq_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) | qoriq_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) | ||||
{ | { | ||||
struct gpio_softc *sc = device_get_softc(dev); | struct gpio_softc *sc = device_get_softc(dev); | ||||
int ret; | int ret; | ||||
if (pin >= PIN_COUNT) | if (pin >= PIN_COUNT) | ||||
return (EINVAL); | return (EINVAL); | ||||
/* Check for unwanted flags. */ | /* Check for unwanted flags. */ | ||||
QORIQ_GPIO_LOCK(sc); | QORIQ_GPIO_LOCK(sc); | ||||
if ((flags & sc->setup[pin].gp_caps) != flags) { | if ((flags & sc->setup[pin].gp_caps) != flags) { | ||||
QORIQ_GPIO_UNLOCK(sc); | QORIQ_GPIO_UNLOCK(sc); | ||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
ret = qoriq_gpio_configure(dev, pin, flags); | ret = qoriq_gpio_configure(dev, pin, flags); | ||||
QORIQ_GPIO_UNLOCK(sc); | QORIQ_GPIO_UNLOCK(sc); | ||||
return (ret); | return (ret); | ||||
} | } | ||||
static int | static int | ||||
qoriq_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps) | qoriq_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps) | ||||
{ | { | ||||
struct gpio_softc *sc = device_get_softc(dev); | struct gpio_softc *sc = device_get_softc(dev); | ||||
if (caps == NULL || pin >= PIN_COUNT) { | if (caps == NULL || pin >= PIN_COUNT) | ||||
return (EINVAL); | return (EINVAL); | ||||
} | |||||
QORIQ_GPIO_LOCK(sc); | QORIQ_GPIO_LOCK(sc); | ||||
*caps = sc->setup[pin].gp_caps; | *caps = sc->setup[pin].gp_caps; | ||||
QORIQ_GPIO_UNLOCK(sc); | QORIQ_GPIO_UNLOCK(sc); | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
qoriq_gpio_pin_get(device_t dev, uint32_t pin, uint32_t *value) | qoriq_gpio_pin_get(device_t dev, uint32_t pin, uint32_t *value) | ||||
{ | { | ||||
struct gpio_softc *sc = device_get_softc(dev); | struct gpio_softc *sc = device_get_softc(dev); | ||||
if (value == NULL || pin >= PIN_COUNT) { | if (value == NULL || pin >= PIN_COUNT) | ||||
return (EINVAL); | return (EINVAL); | ||||
} | |||||
QORIQ_GPIO_LOCK(sc); | QORIQ_GPIO_LOCK(sc); | ||||
*value = qoriq_gpio_value_get(dev, pin); | *value = qoriq_gpio_value_get(dev, pin); | ||||
QORIQ_GPIO_UNLOCK(sc); | QORIQ_GPIO_UNLOCK(sc); | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
qoriq_gpio_pin_set(device_t dev, uint32_t pin, uint32_t value) | qoriq_gpio_pin_set(device_t dev, uint32_t pin, uint32_t value) | ||||
{ | { | ||||
struct gpio_softc *sc = device_get_softc(dev); | struct gpio_softc *sc = device_get_softc(dev); | ||||
if (pin >= PIN_COUNT) { | if (pin >= PIN_COUNT) | ||||
return (EINVAL); | return (EINVAL); | ||||
} | |||||
QORIQ_GPIO_LOCK(sc); | QORIQ_GPIO_LOCK(sc); | ||||
qoriq_gpio_value_set(dev, pin, value); | qoriq_gpio_value_set(dev, pin, value); | ||||
QORIQ_GPIO_UNLOCK(sc); | QORIQ_GPIO_UNLOCK(sc); | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
qoriq_gpio_pin_toggle(device_t dev, uint32_t pin) | qoriq_gpio_pin_toggle(device_t dev, uint32_t pin) | ||||
{ | { | ||||
struct gpio_softc *sc; | struct gpio_softc *sc; | ||||
uint32_t value; | uint32_t value; | ||||
if (pin >= PIN_COUNT) { | if (pin >= PIN_COUNT) | ||||
return (EINVAL); | return (EINVAL); | ||||
} | |||||
sc = device_get_softc(dev); | sc = device_get_softc(dev); | ||||
QORIQ_GPIO_LOCK(sc); | QORIQ_GPIO_LOCK(sc); | ||||
value = qoriq_gpio_reg_read(dev, DATA); | value = qoriq_gpio_reg_read(dev, DATA) ^ (1 << pin); | ||||
if (value & (1 << pin)) | |||||
value &= ~(1 << pin); | |||||
else | |||||
value |= (1 << pin); | |||||
qoriq_gpio_reg_write(dev, DATA, value); | qoriq_gpio_reg_write(dev, DATA, value); | ||||
QORIQ_GPIO_UNLOCK(sc); | QORIQ_GPIO_UNLOCK(sc); | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
qoriq_gpio_map_gpios(device_t bus, phandle_t dev, phandle_t gparent, int gcells, | qoriq_gpio_map_gpios(device_t bus, phandle_t dev, phandle_t gparent, int gcells, | ||||
pcell_t *gpios, uint32_t *pin, uint32_t *flags) | pcell_t *gpios, uint32_t *pin, uint32_t *flags) | ||||
{ | { | ||||
struct gpio_softc *sc = device_get_softc(bus); | struct gpio_softc *sc = device_get_softc(bus); | ||||
int err; | int err; | ||||
if (gpios[0] >= PIN_COUNT) | if (gpios[0] >= PIN_COUNT) | ||||
return (EINVAL); | return (EINVAL); | ||||
QORIQ_GPIO_LOCK(sc); | QORIQ_GPIO_LOCK(sc); | ||||
err = qoriq_gpio_configure(bus, gpios[0], gpios[1]); | err = qoriq_gpio_configure(bus, gpios[0], gpios[1]); | ||||
QORIQ_GPIO_UNLOCK(sc); | QORIQ_GPIO_UNLOCK(sc); | ||||
if(err == 0) { | if (err != 0) | ||||
return (err); | |||||
*pin = gpios[0]; | *pin = gpios[0]; | ||||
*flags = gpios[1]; | *flags = gpios[1]; | ||||
} | |||||
return (err); | return (0); | ||||
} | } | ||||
static int | static int | ||||
qoriq_gpio_pin_access_32(device_t dev, uint32_t first_pin, uint32_t clear_pins, | qoriq_gpio_pin_access_32(device_t dev, uint32_t first_pin, uint32_t clear_pins, | ||||
uint32_t change_pins, uint32_t *orig_pins) | uint32_t change_pins, uint32_t *orig_pins) | ||||
{ | { | ||||
struct gpio_softc *sc; | struct gpio_softc *sc; | ||||
uint32_t hwstate; | uint32_t hwstate; | ||||
Show All 23 Lines | qoriq_gpio_pin_config_32(device_t dev, uint32_t first_pin, uint32_t num_pins, | ||||
uint32_t newflags[32]; | uint32_t newflags[32]; | ||||
int i; | int i; | ||||
if (first_pin != 0 || num_pins > PIN_COUNT) | if (first_pin != 0 || num_pins > PIN_COUNT) | ||||
return (EINVAL); | return (EINVAL); | ||||
sc = device_get_softc(dev); | sc = device_get_softc(dev); | ||||
dir = 0; | dir = odr = mask = 0; | ||||
Not Done Inline ActionsIs not this slightly aggressive ? mmel: Is not this slightly aggressive ? | |||||
odr = 0; | |||||
mask = 0; | |||||
for (i = 0; i < num_pins; i++) { | for (i = 0; i < num_pins; i++) { | ||||
newflags[i] = 0; | newflags[i] = 0; | ||||
mask |= (1 << i); | mask |= (1 << i); | ||||
if (pin_flags[i] & GPIO_PIN_INPUT) { | if (pin_flags[i] & GPIO_PIN_INPUT) { | ||||
newflags[i] = GPIO_PIN_INPUT; | newflags[i] = GPIO_PIN_INPUT; | ||||
dir &= ~(1 << i); | dir &= ~(1 << i); | ||||
} else { | } else { | ||||
newflags[i] = GPIO_PIN_OUTPUT; | newflags[i] = GPIO_PIN_OUTPUT; | ||||
dir |= (1 << i); | dir |= (1 << i); | ||||
if (pin_flags[i] & GPIO_PIN_OPENDRAIN) { | if (pin_flags[i] & GPIO_PIN_OPENDRAIN) { | ||||
newflags[i] |= GPIO_PIN_OPENDRAIN; | newflags[i] |= GPIO_PIN_OPENDRAIN; | ||||
odr |= (1 << i); | odr |= (1 << i); | ||||
} else { | } else { | ||||
newflags[i] |= GPIO_PIN_PUSHPULL; | newflags[i] |= GPIO_PIN_PUSHPULL; | ||||
odr &= ~(1 << i); | odr &= ~(1 << i); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
QORIQ_GPIO_LOCK(sc); | QORIQ_GPIO_LOCK(sc); | ||||
reg = qoriq_gpio_reg_read(dev, DIRECTION); | |||||
reg &= ~mask; | reg = (qoriq_gpio_reg_read(dev, DIRECTION) & ~mask) | dir; | ||||
reg |= dir; | |||||
qoriq_gpio_reg_write(dev, DIRECTION, reg); | qoriq_gpio_reg_write(dev, DIRECTION, reg); | ||||
reg = qoriq_gpio_reg_read(dev, OPEN_DRAIN); | |||||
reg &= ~mask; | reg = (qoriq_gpio_reg_read(dev, OPEN_DRAIN) & ~mask) | odr; | ||||
reg |= odr; | |||||
qoriq_gpio_reg_write(dev, OPEN_DRAIN, reg); | qoriq_gpio_reg_write(dev, OPEN_DRAIN, reg); | ||||
for (i = 0; i < num_pins; i++) { | |||||
for (i = 0; i < num_pins; i++) | |||||
sc->setup[i].gp_flags = newflags[i]; | sc->setup[i].gp_flags = newflags[i]; | ||||
} | |||||
QORIQ_GPIO_UNLOCK(sc); | QORIQ_GPIO_UNLOCK(sc); | ||||
return (0); | return (0); | ||||
} | } |
Shall we make this bool while we're here?