Ejemplo n.º 1
0
int
mv_gpio_configure(device_t dev, uint32_t pin, uint32_t flags, uint32_t mask)
{
	int error;
	struct mv_gpio_softc *sc;
	sc = (struct mv_gpio_softc *)device_get_softc(dev);
	error = 0;

	if (pin >= sc->pin_num)
		return (EINVAL);

	/* check flags consistency */
	if (((flags & mask) & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) ==
	    (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT))
		return (EINVAL);

	if (mask & MV_GPIO_IN_DEBOUNCE) {
		if (sc->irq_num == 0)
			return (EINVAL);
		error = mv_gpio_debounce_prepare(dev, pin);
		if (error != 0)
			return (error);
	}

	MV_GPIO_LOCK();

	if ((mask & flags) & GPIO_PIN_INPUT)
		mv_gpio_out_en(dev, pin, 0);
	if ((mask & flags) & GPIO_PIN_OUTPUT) {
		if ((flags & mask) & GPIO_PIN_OPENDRAIN)
			mv_gpio_value_set(dev, pin, 0);
		else
			mv_gpio_value_set(dev, pin, 1);
		mv_gpio_out_en(dev, pin, 1);
	}

	if (mask & MV_GPIO_OUT_BLINK)
		mv_gpio_blink(dev, pin, flags & MV_GPIO_OUT_BLINK);
	if (mask & MV_GPIO_IN_POL_LOW)
		mv_gpio_polarity(dev, pin, flags & MV_GPIO_IN_POL_LOW, 0);
	if (mask & MV_GPIO_IN_DEBOUNCE) {
		error = mv_gpio_debounce_setup(dev, pin);
		if (error) {
			MV_GPIO_UNLOCK();
			return (error);
		}
	}

	sc->gpio_setup[pin].gp_flags &= ~(mask);
	sc->gpio_setup[pin].gp_flags |= (flags & mask);

	MV_GPIO_UNLOCK();

	return (0);
}
Ejemplo n.º 2
0
void
mv_gpio_out(device_t dev, uint32_t pin, uint8_t val, uint8_t enable)
{
	struct mv_gpio_softc *sc;
	sc = (struct mv_gpio_softc *)device_get_softc(dev);

	MV_GPIO_LOCK();

	mv_gpio_value_set(dev, pin, val);
	mv_gpio_out_en(dev, pin, enable);

	MV_GPIO_UNLOCK();
}
Ejemplo n.º 3
0
static int
mv_gpio_attach(device_t dev)
{
	int error, i;
	struct mv_gpio_softc *sc;
	uint32_t dev_id, rev_id;

	sc = (struct mv_gpio_softc *)device_get_softc(dev);

	if (mv_gpio_softc != NULL)
		return (ENXIO);
	mv_gpio_softc = sc;

	/* Get chip id and revision */
	soc_id(&dev_id, &rev_id);

	if (dev_id == MV_DEV_88F5182 ||
	    dev_id == MV_DEV_88F5281 ||
	    dev_id == MV_DEV_MV78100 ||
	    dev_id == MV_DEV_MV78100_Z0 ) {
		sc->pin_num = 32;
		sc->irq_num = 4;
		sc->use_high = 0;

	} else if (dev_id == MV_DEV_88F6281) {
		sc->pin_num = 50;
		sc->irq_num = 7;
		sc->use_high = 1;

	} else {
		device_printf(dev, "unknown chip id=0x%x\n", dev_id);
		return (ENXIO);
	}

	error = bus_alloc_resources(dev, mv_gpio_res, sc->res);
	if (error) {
		device_printf(dev, "could not allocate resources\n");
		return (ENXIO);
	}

	sc->bst = rman_get_bustag(sc->res[0]);
	sc->bsh = rman_get_bushandle(sc->res[0]);

	/* Disable and clear all interrupts */
	bus_space_write_4(sc->bst, sc->bsh, GPIO_INT_EDGE_MASK, 0);
	bus_space_write_4(sc->bst, sc->bsh, GPIO_INT_LEV_MASK, 0);
	bus_space_write_4(sc->bst, sc->bsh, GPIO_INT_CAUSE, 0);

	if (sc->use_high) {
		bus_space_write_4(sc->bst, sc->bsh,
		    GPIO_HI_INT_EDGE_MASK, 0);
		bus_space_write_4(sc->bst, sc->bsh,
		    GPIO_HI_INT_LEV_MASK, 0);
		bus_space_write_4(sc->bst, sc->bsh,
		    GPIO_HI_INT_CAUSE, 0);
	}

	for (i = 0; i < sc->irq_num; i++) {
		if (bus_setup_intr(dev, sc->res[1 + i],
		    INTR_TYPE_MISC | INTR_FAST,
		    (driver_filter_t *)mv_gpio_intr, NULL,
		    sc, &sc->ih_cookie[i]) != 0) {
			bus_release_resources(dev, mv_gpio_res, sc->res);
			device_printf(dev, "could not set up intr %d\n", i);
			return (ENXIO);
		}
	}

	/* Setup GPIO lines */
	for (i = 0; mv_gpio_config[i].gc_gpio >= 0; i++) {
		mv_gpio_configure(mv_gpio_config[i].gc_gpio,
		    mv_gpio_config[i].gc_flags, ~0u);

		if (mv_gpio_config[i].gc_output < 0)
			mv_gpio_out_en(mv_gpio_config[i].gc_gpio, 0);
		else
			mv_gpio_out(mv_gpio_config[i].gc_gpio,
			    mv_gpio_config[i].gc_output, 1);
	}

	return (0);
}