Example #1
0
static int
mv_gpio_map_gpios(device_t bus, phandle_t dev, phandle_t gparent, int gcells,
    pcell_t *gpios, uint32_t *pin, uint32_t *flags)
{
	struct mv_gpio_softc *sc = device_get_softc(bus);

	if (gpios[0] >= sc->pin_num)
		return (EINVAL);

	*pin = gpios[0];
	*flags = gpios[1];
	mv_gpio_configure(bus, *pin, *flags, ~0);

	return (0);
}
Example #2
0
static int
mv_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
{
	int ret;
	struct mv_gpio_softc *sc = device_get_softc(dev);
	if (pin >= sc->pin_num)
		return (EINVAL);

	/* Check for unwanted flags. */
	if ((flags & sc->gpio_setup[pin].gp_caps) != flags)
		return (EINVAL);

	ret = mv_gpio_configure(dev, pin, flags, ~0);

	return (ret);
}
Example #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);
}