Пример #1
0
/**
 * \brief Unlock the commit control of a special function pin
 *
 * Unlocks the commit control of the given pin or group of pins. If a pin is a
 * JTAG/SWD or NMI, the pin may then be reconfigured as a GPIO pin. If the pin
 * is not locked by default, this has no effect.
 *
 * @param[in] gpioport GPIO block register address base @ref gpio_reg_base
 * @param[in] gpios @ref gpio_pin_id. Any combination of pins may be specified
 *		    by OR'ing then together.
 */
void gpio_unlock_commit(uint32_t gpioport, uint8_t gpios)
{
	/* Unlock the GPIO_CR register */
	GPIO_LOCK(gpioport) = GPIO_LOCK_UNLOCK_CODE;
	/* Enable committing changes */
	GPIO_CR(gpioport) |= gpios;
	/* Lock the GPIO_CR register */
	GPIO_LOCK(gpioport) = ~GPIO_LOCK_UNLOCK_CODE;
}
Пример #2
0
/*!
    \brief      lock GPIO pin
    \param[in]  gpioport
      \arg        GPIOx(x = A,B,C,D,F)
    \param[in]  gpiopin
      \arg        GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
    \param[out] none
    \retval     none
*/
void gpio_pin_lock(uint32_t port, uint16_t pin)
{
    uint32_t lock = 0x00010000;
    lock |= pin;
    /* lock key writing sequence: write 1->write 0->write 1-> read 0-> read 1 */
    GPIO_LOCK(port) = lock;
    GPIO_LOCK(port) = pin;
    GPIO_LOCK(port) = lock;
    lock = GPIO_LOCK(port);
    lock = GPIO_LOCK(port);
}
Пример #3
0
/*!
    \brief      lock GPIO pin bit
    \param[in]  gpio_periph: GPIOx(x = A,B) 
                only one parameter can be selected which is shown as below:
      \arg        GPIOx(x = A,B) 
    \param[in]  pin: GPIO pin
                one or more parameters can be selected which are shown as below:
      \arg        GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
    \param[out] none
    \retval     none
*/
void gpio_pin_lock(uint32_t gpio_periph, uint32_t pin)
{
    uint32_t lock = 0x00010000U;
    lock |= pin;

    /* lock key writing sequence: write 1->write 0->write 1->read 0->read 1 */
    GPIO_LOCK(gpio_periph) = (uint32_t)lock;
    GPIO_LOCK(gpio_periph) = (uint32_t)pin;
    GPIO_LOCK(gpio_periph) = (uint32_t)lock;
    lock = GPIO_LOCK(gpio_periph);
    lock = GPIO_LOCK(gpio_periph);
}
Пример #4
0
static void
ar71xx_gpio_function_disable(struct ar71xx_gpio_softc *sc, uint32_t mask)
{
	GPIO_LOCK(sc);
	GPIO_CLEAR_BITS(sc, AR71XX_GPIO_FUNCTION, mask);
	GPIO_UNLOCK(sc);
}
Пример #5
0
static void
ar71xx_gpio_pin_configure(struct ar71xx_gpio_softc *sc, struct gpio_pin *pin,
    unsigned int flags)
{
	uint32_t mask;

	mask = 1 << pin->gp_pin;
	GPIO_LOCK(sc);

	/*
	 * Manage input/output
	 */
	if (flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) {
		pin->gp_flags &= ~(GPIO_PIN_INPUT|GPIO_PIN_OUTPUT);
		if (flags & GPIO_PIN_OUTPUT) {
			pin->gp_flags |= GPIO_PIN_OUTPUT;
			GPIO_SET_BITS(sc, AR71XX_GPIO_OE, mask);
		}
		else {
			pin->gp_flags |= GPIO_PIN_INPUT;
			GPIO_CLEAR_BITS(sc, AR71XX_GPIO_OE, mask);
		}
	}

	GPIO_UNLOCK(sc);
}
Пример #6
0
static int
cambria_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
{
	struct cambria_gpio_softc *sc = device_get_softc(dev);
	int error;
	uint8_t mask;

	mask = 1 << pin;

	if (pin >= GPIO_PINS)
		return (EINVAL);
	GPIO_LOCK(sc);
	if (value)
		sc->sc_val |= mask;
	else
		sc->sc_val &= ~mask;

	if (sc->sc_pins[pin].gp_flags != GPIO_PIN_OUTPUT) {
		/* just save, altering the latch will disable input */
		GPIO_UNLOCK(sc);
		return (0);
	}

	if (value)
		sc->sc_latch |= mask;
	else
		sc->sc_latch &= ~mask;
	error = cambria_gpio_write(sc);
	GPIO_UNLOCK(sc);

	return (error);
}
Пример #7
0
static int
octeon_gpio_pin_toggle(device_t dev, uint32_t pin)
{
    int i;
    uint64_t state;
    struct octeon_gpio_softc *sc = device_get_softc(dev);

    for (i = 0; i < sc->gpio_npins; i++) {
        if (sc->gpio_pins[i].gp_pin == pin)
            break;
    }

    if (i >= sc->gpio_npins)
        return (EINVAL);

    GPIO_LOCK(sc);
    /*
     * XXX: Need to check if read returns actual state of output
     * pins or we need to keep this information by ourself
     */
    state = cvmx_gpio_read();
    if (state & (1 << pin))
        cvmx_gpio_clear(1 << pin);
    else
        cvmx_gpio_set(1 << pin);
    GPIO_UNLOCK(sc);

    return (0);
}
Пример #8
0
static void
octeon_gpio_pin_configure(struct octeon_gpio_softc *sc, struct gpio_pin *pin,
                          unsigned int flags)
{
    uint32_t mask;
    cvmx_gpio_bit_cfgx_t gpio_cfgx;

    mask = 1 << pin->gp_pin;
    GPIO_LOCK(sc);

    /*
     * Manage input/output
     */
    if (flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) {
        gpio_cfgx.u64 = cvmx_read_csr(CVMX_GPIO_BIT_CFGX(pin->gp_pin));
        pin->gp_flags &= ~(GPIO_PIN_INPUT|GPIO_PIN_OUTPUT);
        if (flags & GPIO_PIN_OUTPUT) {
            pin->gp_flags |= GPIO_PIN_OUTPUT;
            gpio_cfgx.s.tx_oe = 1;
        }
        else {
            pin->gp_flags |= GPIO_PIN_INPUT;
            gpio_cfgx.s.tx_oe = 0;
        }
        if (flags & GPIO_PIN_INVIN)
            gpio_cfgx.s.rx_xor = 1;
        else
            gpio_cfgx.s.rx_xor = 0;
        cvmx_write_csr(CVMX_GPIO_BIT_CFGX(pin->gp_pin), gpio_cfgx.u64);
    }

    GPIO_UNLOCK(sc);
}
Пример #9
0
static int
pad_pin_get(device_t dev, uint32_t pin, unsigned int *val)
{
	struct gpio_bank bank;
	struct pad_softc *sc;
	int pin_shift;
	int i;

	sc = device_get_softc(dev);
	for (i = 0; i < sc->gpio_npins; i++) {
		if (sc->gpio_pins[i].gp_pin == pin)
			break;
	}

	if (i >= sc->gpio_npins)
		return (EINVAL);

	if (get_bank(sc, pin, &bank, &pin_shift) != 0)
		return (EINVAL);

	GPIO_LOCK(sc);
	if (READ4(sc, bank.port, bank.con + 0x4) & (1 << pin_shift))
		*val = 1;
	else
		*val = 0;
	GPIO_UNLOCK(sc);

	return (0);
}
Пример #10
0
static int
pad_pin_set(device_t dev, uint32_t pin, unsigned int value)
{
	struct pad_softc *sc;
	struct gpio_bank bank;
	int pin_shift;
	int reg;
	int i;

	sc = device_get_softc(dev);
	for (i = 0; i < sc->gpio_npins; i++) {
		if (sc->gpio_pins[i].gp_pin == pin)
			break;
	}

	if (i >= sc->gpio_npins)
		return (EINVAL);

	if (get_bank(sc, pin, &bank, &pin_shift) != 0)
		return (EINVAL);

	GPIO_LOCK(sc);
	reg = READ4(sc, bank.port, bank.con + 0x4);
	reg &= ~(PIN_OUT << pin_shift);
	if (value)
		reg |= (PIN_OUT << pin_shift);
	WRITE4(sc, bank.port, bank.con + 0x4, reg);
	GPIO_UNLOCK(sc);

	return (0);
}
Пример #11
0
/*
 * GPIO setup:
 * Enable the pins driving the RGB LED as outputs.
 */
static void gpio_setup(void)
{
	/*
	 * Configure GPIOF
	 * This port is used to control the RGB LED
	 */
	periph_clock_enable(RCC_GPIOF);
	const u32 outpins = (LED_R | LED_G | LED_B);

	GPIO_DIR(RGB_PORT) |= outpins; /* Configure outputs. */
	GPIO_DEN(RGB_PORT) |= outpins; /* Enable digital function on outputs. */

	/*
	 * Now take care of our buttons
	 */
	const u32 btnpins = USR_SW1 | USR_SW2;

	/*
	 * PF0 is locked by default. We need to unlock the GPIO_CR register,
	 * then enable PF0 commit. After we do this, we can setup PF0. If we
	 * don't do this, any configuration done to PF0 is lost, and we will not
	 * have a PF0 interrupt.
	 */
	GPIO_LOCK(GPIOF) = 0x4C4F434B;
	GPIO_CR(GPIOF) |= USR_SW2;

	/* Configure pins as inputs. */
	GPIO_DIR(GPIOF) &= ~btnpins;
	/* Enable digital function on the pins. */
	GPIO_DEN(GPIOF) |= btnpins;
	/* Pull-up the pins. We don't have an external pull-up */
	GPIO_PUR(GPIOF) |= btnpins;
}
Пример #12
0
static void
ar71xx_gpio_intr(void *arg)
{
	struct ar71xx_gpio_softc *sc = arg;
	GPIO_LOCK(sc);
	/* TODO: something useful */
	GPIO_UNLOCK(sc);
}
Пример #13
0
static int
tegra_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
{
	struct tegra_gpio_softc *sc;

	sc = device_get_softc(dev);
	if (pin >= sc->gpio_npins)
		return (EINVAL);
	GPIO_LOCK(sc);
	gpio_write_masked(sc, GPIO_MSK_OUT, &sc->gpio_pins[pin], value);
	GPIO_UNLOCK(sc);

	return (0);
}
Пример #14
0
static int
tegra_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
{
	struct tegra_gpio_softc *sc;

	sc = device_get_softc(dev);
	if (pin >= sc->gpio_npins)
		return (EINVAL);

	GPIO_LOCK(sc);
	*val = gpio_read(sc, GPIO_IN, &sc->gpio_pins[pin]);
	GPIO_UNLOCK(sc);

	return (0);
}
Пример #15
0
static int
tegra_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
{
	struct tegra_gpio_softc *sc;

	sc = device_get_softc(dev);
	if (pin >= sc->gpio_npins)
		return (EINVAL);

	GPIO_LOCK(sc);
	memcpy(name, sc->gpio_pins[pin].gp_name, GPIOMAXNAME);
	GPIO_UNLOCK(sc);

	return (0);
}
Пример #16
0
static int
tegra_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
{
	struct tegra_gpio_softc *sc;

	sc = device_get_softc(dev);
	if (pin >= sc->gpio_npins)
		return (EINVAL);

	GPIO_LOCK(sc);
	*caps = sc->gpio_pins[pin].gp_caps;
	GPIO_UNLOCK(sc);

	return (0);
}
Пример #17
0
static inline void
intr_write_modify(struct tegra_gpio_softc *sc, bus_addr_t reg,
    struct tegra_gpio_irqsrc *tgi, uint32_t val, uint32_t mask)
{
	uint32_t tmp;
	int bit;

	bit = GPIO_BIT(tgi->irq);
	GPIO_LOCK(sc);
	tmp = bus_read_4(sc->mem_res, reg + GPIO_REGNUM(tgi->irq));
	tmp &= ~(mask << bit);
	tmp |= val << bit;
	bus_write_4(sc->mem_res, reg + GPIO_REGNUM(tgi->irq), tmp);
	GPIO_UNLOCK(sc);
}
Пример #18
0
static int
tegra_gpio_pin_toggle(device_t dev, uint32_t pin)
{
	struct tegra_gpio_softc *sc;

	sc = device_get_softc(dev);
	if (pin >= sc->gpio_npins)
		return (EINVAL);

	GPIO_LOCK(sc);
	gpio_write_masked(sc, GPIO_MSK_OE, &sc->gpio_pins[pin],
	     gpio_read(sc, GPIO_IN, &sc->gpio_pins[pin]) ^ 1);
	GPIO_UNLOCK(sc);

	return (0);
}
Пример #19
0
static int
cambria_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
{
	struct cambria_gpio_softc *sc = device_get_softc(dev);
	int error = 0;

	if (pin >= GPIO_PINS)
		return (EINVAL);

	GPIO_LOCK(sc);
	if (sc->sc_pins[pin].gp_flags == GPIO_PIN_OUTPUT)
		*val = (sc->sc_latch & (1 << pin)) ? 1 : 0;
	else
		error = cambria_gpio_read(sc, pin, val);
	GPIO_UNLOCK(sc);

	return (error);
}
Пример #20
0
static int
cambria_gpio_pin_toggle(device_t dev, uint32_t pin)
{
	struct cambria_gpio_softc *sc = device_get_softc(dev);
	int error = 0;

	if (pin >= GPIO_PINS)
		return (EINVAL);

	GPIO_LOCK(sc);
	sc->sc_val ^= (1 << pin);
	if (sc->sc_pins[pin].gp_flags == GPIO_PIN_OUTPUT) {
		sc->sc_latch ^= (1 << pin);
		error = cambria_gpio_write(sc);
	}
	GPIO_UNLOCK(sc);

	return (error);
}
Пример #21
0
static int
octeon_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
{
    struct octeon_gpio_softc *sc = device_get_softc(dev);
    int i;

    for (i = 0; i < sc->gpio_npins; i++) {
        if (sc->gpio_pins[i].gp_pin == pin)
            break;
    }

    if (i >= sc->gpio_npins)
        return (EINVAL);

    GPIO_LOCK(sc);
    memcpy(name, sc->gpio_pins[i].gp_name, GPIOMAXNAME);
    GPIO_UNLOCK(sc);

    return (0);
}
Пример #22
0
static int
ar71xx_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
{
	struct ar71xx_gpio_softc *sc = device_get_softc(dev);
	int i;

	for (i = 0; i < sc->gpio_npins; i++) {
		if (sc->gpio_pins[i].gp_pin == pin)
			break;
	}

	if (i >= sc->gpio_npins)
		return (EINVAL);

	GPIO_LOCK(sc);
	*caps = sc->gpio_pins[i].gp_caps;
	GPIO_UNLOCK(sc);

	return (0);
}
Пример #23
0
static int
ar71xx_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
{
	struct ar71xx_gpio_softc *sc = device_get_softc(dev);
	int i;

	for (i = 0; i < sc->gpio_npins; i++) {
		if (sc->gpio_pins[i].gp_pin == pin)
			break;
	}

	if (i >= sc->gpio_npins)
		return (EINVAL);

	GPIO_LOCK(sc);
	*val = (GPIO_READ(sc, AR71XX_GPIO_IN) & (1 << pin)) ? 1 : 0;
	GPIO_UNLOCK(sc);

	return (0);
}
Пример #24
0
static int
octeon_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
{
    struct octeon_gpio_softc *sc = device_get_softc(dev);
    int i;

    for (i = 0; i < sc->gpio_npins; i++) {
        if (sc->gpio_pins[i].gp_pin == pin)
            break;
    }

    if (i >= sc->gpio_npins)
        return (EINVAL);

    GPIO_LOCK(sc);
    *flags = sc->gpio_pins[i].gp_flags;
    GPIO_UNLOCK(sc);

    return (0);
}
Пример #25
0
static void
pad_pin_configure(struct pad_softc *sc, struct gpio_pin *pin,
    unsigned int flags)
{
	struct gpio_bank bank;
	int pin_shift;
	int reg;

	GPIO_LOCK(sc);

	/*
	 * Manage input/output
	 */
	if (flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) {
		pin->gp_flags &= ~(GPIO_PIN_INPUT|GPIO_PIN_OUTPUT);

		if (get_bank(sc, pin->gp_pin, &bank, &pin_shift) != 0)
			return;

		pin_shift *= 4;

#if 0
		printf("bank is 0x%08x pin_shift %d\n", bank.con, pin_shift);
#endif

		if (flags & GPIO_PIN_OUTPUT) {
			pin->gp_flags |= GPIO_PIN_OUTPUT;
			reg = READ4(sc, bank.port, bank.con);
			reg &= ~(0xf << pin_shift);
			reg |= (PIN_OUT << pin_shift);
			WRITE4(sc, bank.port, bank.con, reg);
		} else {
			pin->gp_flags |= GPIO_PIN_INPUT;
			reg = READ4(sc, bank.port, bank.con);
			reg &= ~(0xf << pin_shift);
			WRITE4(sc, bank.port, bank.con, reg);
		}
	}

	GPIO_UNLOCK(sc);
}
Пример #26
0
static int
vf_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
{
	struct vf_gpio_softc *sc;
	int i;

	sc = device_get_softc(dev);
	for (i = 0; i < sc->gpio_npins; i++) {
		if (sc->gpio_pins[i].gp_pin == pin)
			break;
	}

	if (i >= sc->gpio_npins)
		return (EINVAL);

	GPIO_LOCK(sc);
	*val = (READ4(sc, GPIO_PDIR(i)) & (1 << (i % 32))) ? 1 : 0;
	GPIO_UNLOCK(sc);

	return (0);
}
Пример #27
0
static int
vf_gpio_pin_toggle(device_t dev, uint32_t pin)
{
	struct vf_gpio_softc *sc;
	int i;

	sc = device_get_softc(dev);
	for (i = 0; i < sc->gpio_npins; i++) {
		if (sc->gpio_pins[i].gp_pin == pin)
			break;
	}

	if (i >= sc->gpio_npins)
		return (EINVAL);

	GPIO_LOCK(sc);
	WRITE4(sc, GPIO_PTOR(i), (1 << (i % 32)));
	GPIO_UNLOCK(sc);

	return (0);
}
Пример #28
0
static int
tegra_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
{
	struct tegra_gpio_softc *sc;
	int cnf;

	sc = device_get_softc(dev);
	if (pin >= sc->gpio_npins)
		return (EINVAL);

	GPIO_LOCK(sc);
	cnf = gpio_read(sc, GPIO_CNF, &sc->gpio_pins[pin]);
	if (cnf == 0) {
		GPIO_UNLOCK(sc);
		return (ENXIO);
	}
	*flags = sc->gpio_pins[pin].gp_flags;
	GPIO_UNLOCK(sc);

	return (0);
}
Пример #29
0
static int
cambria_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
{
	struct cambria_gpio_softc *sc = device_get_softc(dev);
	int error;
	uint8_t mask;

	mask = 1 << pin;

	if (pin >= GPIO_PINS)
		return (EINVAL);

	/* Filter out unwanted flags */
	if ((flags &= sc->sc_pins[pin].gp_caps) != flags)
		return (EINVAL);

	/* Can't mix input/output together */
	if ((flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) ==
	    (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT))
		return (EINVAL);

	GPIO_LOCK(sc);
	sc->sc_pins[pin].gp_flags = flags;

	/*
	 * Writing a logical one sets the signal high and writing a logical
	 * zero sets the signal low. To configure a digital I/O signal as an
	 * input, a logical one must first be written to the data bit to
	 * three-state the associated output.
	 */
	if (flags & GPIO_PIN_INPUT || sc->sc_val & mask)
		sc->sc_latch |= mask; /* input or output & high */
	else
		sc->sc_latch &= ~mask;
	error = cambria_gpio_write(sc);
	GPIO_UNLOCK(sc);

	return (error);
}
Пример #30
0
static int
octeon_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
{
    struct octeon_gpio_softc *sc = device_get_softc(dev);
    int i;
    uint64_t state;

    for (i = 0; i < sc->gpio_npins; i++) {
        if (sc->gpio_pins[i].gp_pin == pin)
            break;
    }

    if (i >= sc->gpio_npins)
        return (EINVAL);

    GPIO_LOCK(sc);
    state = cvmx_gpio_read();
    *val = (state & (1 << pin)) ? 1 : 0;
    GPIO_UNLOCK(sc);

    return (0);
}