Rework the Ti GPIO code to allow for both the OMAP4 and AM335X attachments

to be present. Thsi creates a new per-SoC driver that handles probe and
setting/getting the gpio flags.

Differential Revision:	https://reviews.freebsd.org/D943
Reviewed by:	loos, rpaulo
MFC after:	1 week
This commit is contained in:
Andrew Turner 2014-10-18 17:51:34 +00:00
parent daed8c66c5
commit b6c7dacfc9
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=273262
13 changed files with 554 additions and 233 deletions

View File

@ -0,0 +1,156 @@
/*-
* Copyright (c) 2012 Damjan Marion <dmarion@FreeBSD.org>
* Copyright (c) 2014 Andrew Turner <andrew@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/bus.h>
#include <sys/resource.h>
#include <sys/rman.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <machine/bus.h>
#include <machine/cpu.h>
#include <machine/cpufunc.h>
#include <machine/resource.h>
#include <machine/intr.h>
#include <sys/gpio.h>
#include <dev/fdt/fdt_common.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#include <arm/ti/ti_cpuid.h>
#include <arm/ti/ti_gpio.h>
#include <arm/ti/ti_scm.h>
#include <arm/ti/am335x/am335x_scm_padconf.h>
#include "ti_gpio_if.h"
static struct ofw_compat_data compat_data[] = {
{"ti,am335x-gpio", 1},
/* Linux uses ti,omap4-gpio on am335x so we need to support it */
{"ti,omap4-gpio", 1},
{"ti,gpio", 1},
{NULL, 0},
};
static int
am335x_gpio_probe(device_t dev)
{
if (ti_chip() != CHIP_AM335X)
return (ENXIO);
if (!ofw_bus_status_okay(dev))
return (ENXIO);
if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
return (ENXIO);
device_set_desc(dev, "Ti AM335x General Purpose I/O (GPIO)");
return (0);
}
static int
am335x_gpio_set_flags(device_t dev, uint32_t gpio, uint32_t flags)
{
unsigned int state = 0;
if (flags & GPIO_PIN_OUTPUT) {
if (flags & GPIO_PIN_PULLUP)
state = PADCONF_OUTPUT_PULLUP;
else
state = PADCONF_OUTPUT;
} else if (flags & GPIO_PIN_INPUT) {
if (flags & GPIO_PIN_PULLUP)
state = PADCONF_INPUT_PULLUP;
else if (flags & GPIO_PIN_PULLDOWN)
state = PADCONF_INPUT_PULLDOWN;
else
state = PADCONF_INPUT;
}
return ti_scm_padconf_set_gpiomode(gpio, state);
}
static int
am335x_gpio_get_flags(device_t dev, uint32_t gpio, uint32_t *flags)
{
unsigned int state;
if (ti_scm_padconf_get_gpiomode(gpio, &state) != 0) {
*flags = 0;
return (EINVAL);
} else {
switch (state) {
case PADCONF_OUTPUT:
*flags = GPIO_PIN_OUTPUT;
break;
case PADCONF_OUTPUT_PULLUP:
*flags = GPIO_PIN_OUTPUT | GPIO_PIN_PULLUP;
break;
case PADCONF_INPUT:
*flags = GPIO_PIN_INPUT;
break;
case PADCONF_INPUT_PULLUP:
*flags = GPIO_PIN_INPUT | GPIO_PIN_PULLUP;
break;
case PADCONF_INPUT_PULLDOWN:
*flags = GPIO_PIN_INPUT | GPIO_PIN_PULLDOWN;
break;
default:
*flags = 0;
break;
}
}
return (0);
}
static device_method_t am335x_gpio_methods[] = {
/* bus interface */
DEVMETHOD(device_probe, am335x_gpio_probe),
/* ti_gpio interface */
DEVMETHOD(ti_gpio_set_flags, am335x_gpio_set_flags),
DEVMETHOD(ti_gpio_get_flags, am335x_gpio_get_flags),
DEVMETHOD_END
};
extern driver_t ti_gpio_driver;
static devclass_t am335x_gpio_devclass;
DEFINE_CLASS_1(gpio, am335x_gpio_driver, am335x_gpio_methods,
sizeof(struct ti_gpio_softc), ti_gpio_driver);
DRIVER_MODULE(am335x_gpio, simplebus, am335x_gpio_driver, am335x_gpio_devclass,
0, 0);

View File

@ -47,6 +47,8 @@ __FBSDID("$FreeBSD$");
#include <arm/ti/tivar.h>
#include <arm/ti/ti_scm.h>
#include <arm/ti/am335x/am335x_scm_padconf.h>
#define _PIN(r, b, gp, gm, m0, m1, m2, m3, m4, m5, m6, m7) \
{ .reg_off = r, \
.gpio_pin = gp, \
@ -62,18 +64,6 @@ __FBSDID("$FreeBSD$");
.muxmodes[7] = m7, \
}
#define SLEWCTRL (0x01 << 6) /* faster(0) or slower(1) slew rate. */
#define RXACTIVE (0x01 << 5) /* Input enable value for the Pad */
#define PULLTYPESEL (0x01 << 4) /* Pad pullup/pulldown type selection */
#define PULLUDEN (0x01 << 3) /* Pullup/pulldown disabled */
#define PADCONF_OUTPUT (0)
#define PADCONF_OUTPUT_PULLUP (PULLTYPESEL)
#define PADCONF_INPUT (RXACTIVE | PULLUDEN)
#define PADCONF_INPUT_PULLUP (RXACTIVE | PULLTYPESEL)
#define PADCONF_INPUT_PULLDOWN (RXACTIVE)
#define PADCONF_INPUT_PULLUP_SLOW (PADCONF_INPUT_PULLUP | SLEWCTRL)
const static struct ti_scm_padstate ti_padstate_devmap[] = {
{"output", PADCONF_OUTPUT },
{"output_pullup", PADCONF_OUTPUT_PULLUP },
@ -311,54 +301,3 @@ const struct ti_scm_device ti_scm_dev = {
.padstate = (struct ti_scm_padstate *) &ti_padstate_devmap,
.padconf = (struct ti_scm_padconf *) &ti_padconf_devmap,
};
int
ti_scm_padconf_set_gpioflags(uint32_t gpio, uint32_t flags)
{
unsigned int state = 0;
if (flags & GPIO_PIN_OUTPUT) {
if (flags & GPIO_PIN_PULLUP)
state = PADCONF_OUTPUT_PULLUP;
else
state = PADCONF_OUTPUT;
} else if (flags & GPIO_PIN_INPUT) {
if (flags & GPIO_PIN_PULLUP)
state = PADCONF_INPUT_PULLUP;
else if (flags & GPIO_PIN_PULLDOWN)
state = PADCONF_INPUT_PULLDOWN;
else
state = PADCONF_INPUT;
}
return ti_scm_padconf_set_gpiomode(gpio, state);
}
void
ti_scm_padconf_get_gpioflags(uint32_t gpio, uint32_t *flags)
{
unsigned int state;
if (ti_scm_padconf_get_gpiomode(gpio, &state) != 0)
*flags = 0;
else {
switch (state) {
case PADCONF_OUTPUT:
*flags = GPIO_PIN_OUTPUT;
break;
case PADCONF_OUTPUT_PULLUP:
*flags = GPIO_PIN_OUTPUT | GPIO_PIN_PULLUP;
break;
case PADCONF_INPUT:
*flags = GPIO_PIN_INPUT;
break;
case PADCONF_INPUT_PULLUP:
*flags = GPIO_PIN_INPUT | GPIO_PIN_PULLUP;
break;
case PADCONF_INPUT_PULLDOWN:
*flags = GPIO_PIN_INPUT | GPIO_PIN_PULLDOWN;
break;
default:
*flags = 0;
break;
}
}
}

View File

@ -0,0 +1,44 @@
/*-
* Copyright (c) 2012 Damjan Marion <dmarion@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef AM335X_SCM_PADCONF_H
#define AM335X_SCM_PADCONF_H
#define SLEWCTRL (0x01 << 6) /* faster(0) or slower(1) slew rate. */
#define RXACTIVE (0x01 << 5) /* Input enable value for the Pad */
#define PULLTYPESEL (0x01 << 4) /* Pad pullup/pulldown type selection */
#define PULLUDEN (0x01 << 3) /* Pullup/pulldown disabled */
#define PADCONF_OUTPUT (0)
#define PADCONF_OUTPUT_PULLUP (PULLTYPESEL)
#define PADCONF_INPUT (RXACTIVE | PULLUDEN)
#define PADCONF_INPUT_PULLUP (RXACTIVE | PULLTYPESEL)
#define PADCONF_INPUT_PULLDOWN (RXACTIVE)
#define PADCONF_INPUT_PULLUP_SLOW (PADCONF_INPUT_PULLUP | SLEWCTRL)
#endif /* AM335X_SCM_PADCONF_H */

View File

@ -3,6 +3,7 @@
arm/ti/aintc.c standard
arm/ti/am335x/am335x_dmtimer.c standard
arm/ti/am335x/am335x_gpio.c optional gpio
arm/ti/am335x/am335x_lcd.c optional sc
arm/ti/am335x/am335x_lcd_syscons.c optional sc
arm/ti/am335x/am335x_pmic.c optional am335x_pmic

View File

@ -21,6 +21,7 @@ arm/ti/ti_pruss.c optional ti_pruss
arm/ti/ti_wdt.c optional ti_wdt
arm/ti/ti_adc.c optional ti_adc
arm/ti/ti_gpio.c optional gpio
arm/ti/ti_gpio_if.m optional gpio
arm/ti/ti_i2c.c optional ti_i2c
arm/ti/ti_sdhci.c optional sdhci

View File

@ -7,6 +7,7 @@ arm/ti/ti_smc.S standard
arm/ti/usb/omap_ehci.c optional usb ehci
arm/ti/ti_sdma.c optional ti_sdma
arm/ti/omap4/omap4_gpio.c optional gpio
arm/ti/omap4/omap4_l2cache.c optional pl310
arm/ti/omap4/omap4_prcm_clks.c standard
arm/ti/omap4/omap4_scm_padconf.c standard

View File

@ -0,0 +1,143 @@
/*-
* Copyright (c) 2011 Ben Gray <ben.r.gray@gmail.com>.
* Copyright (c) 2014 Andrew Turner <andrew@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY BEN GRAY ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL BEN GRAY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/bus.h>
#include <sys/gpio.h>
#include <machine/bus.h>
#include <dev/fdt/fdt_common.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#include <arm/ti/ti_cpuid.h>
#include <arm/ti/ti_gpio.h>
#include <arm/ti/ti_scm.h>
#include <arm/ti/omap4/omap4_scm_padconf.h>
#include "ti_gpio_if.h"
static struct ofw_compat_data compat_data[] = {
{"ti,omap4-gpio", 1},
{"ti,gpio", 1},
{NULL, 0},
};
static int
omap4_gpio_probe(device_t dev)
{
if (ti_chip() != CHIP_OMAP_4)
return (ENXIO);
if (!ofw_bus_status_okay(dev))
return (ENXIO);
if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
return (ENXIO);
device_set_desc(dev, "Ti OMAP4 General Purpose I/O (GPIO)");
return (0);
}
static int
omap4_gpio_set_flags(device_t dev, uint32_t gpio, uint32_t flags)
{
unsigned int state = 0;
/* First the SCM driver needs to be told to put the pad into GPIO mode */
if (flags & GPIO_PIN_OUTPUT)
state = PADCONF_PIN_OUTPUT;
else if (flags & GPIO_PIN_INPUT) {
if (flags & GPIO_PIN_PULLUP)
state = PADCONF_PIN_INPUT_PULLUP;
else if (flags & GPIO_PIN_PULLDOWN)
state = PADCONF_PIN_INPUT_PULLDOWN;
else
state = PADCONF_PIN_INPUT;
}
return ti_scm_padconf_set_gpiomode(gpio, state);
}
static int
omap4_gpio_get_flags(device_t dev, uint32_t gpio, uint32_t *flags)
{
unsigned int state;
/* Get the current pin state */
if (ti_scm_padconf_get_gpiomode(gpio, &state) != 0) {
*flags = 0;
return (EINVAL);
} else {
switch (state) {
case PADCONF_PIN_OUTPUT:
*flags = GPIO_PIN_OUTPUT;
break;
case PADCONF_PIN_INPUT:
*flags = GPIO_PIN_INPUT;
break;
case PADCONF_PIN_INPUT_PULLUP:
*flags = GPIO_PIN_INPUT | GPIO_PIN_PULLUP;
break;
case PADCONF_PIN_INPUT_PULLDOWN:
*flags = GPIO_PIN_INPUT | GPIO_PIN_PULLDOWN;
break;
default:
*flags = 0;
break;
}
}
return (0);
}
static device_method_t omap4_gpio_methods[] = {
/* bus interface */
DEVMETHOD(device_probe, omap4_gpio_probe),
/* ti_gpio interface */
DEVMETHOD(ti_gpio_set_flags, omap4_gpio_set_flags),
DEVMETHOD(ti_gpio_get_flags, omap4_gpio_get_flags),
DEVMETHOD_END
};
extern driver_t ti_gpio_driver;
static devclass_t omap4_gpio_devclass;
DEFINE_CLASS_1(gpio, omap4_gpio_driver, omap4_gpio_methods,
sizeof(struct ti_gpio_softc), ti_gpio_driver);
DRIVER_MODULE(omap4_gpio, simplebus, omap4_gpio_driver, omap4_gpio_devclass,
0, 0);

View File

@ -40,16 +40,9 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <machine/bus.h>
#include <machine/cpu.h>
#include <machine/cpufunc.h>
#include <machine/resource.h>
#include <machine/intr.h>
#include <sys/gpio.h>
#include <arm/ti/tivar.h>
#include <arm/ti/ti_scm.h>
#include <arm/ti/omap4/omap4var.h>
#include <arm/ti/omap4/omap4_reg.h>
#include <arm/ti/omap4/omap4_scm_padconf.h>
/*
@ -69,53 +62,6 @@ __FBSDID("$FreeBSD$");
*
*/
#define CONTROL_PADCONF_WAKEUP_EVENT (1UL << 15)
#define CONTROL_PADCONF_WAKEUP_ENABLE (1UL << 14)
#define CONTROL_PADCONF_OFF_PULL_UP (1UL << 13)
#define CONTROL_PADCONF_OFF_PULL_ENABLE (1UL << 12)
#define CONTROL_PADCONF_OFF_OUT_HIGH (1UL << 11)
#define CONTROL_PADCONF_OFF_OUT_ENABLE (1UL << 10)
#define CONTROL_PADCONF_OFF_ENABLE (1UL << 9)
#define CONTROL_PADCONF_INPUT_ENABLE (1UL << 8)
#define CONTROL_PADCONF_PULL_UP (1UL << 4)
#define CONTROL_PADCONF_PULL_ENABLE (1UL << 3)
#define CONTROL_PADCONF_MUXMODE_MASK (0x7)
#define CONTROL_PADCONF_SATE_MASK ( CONTROL_PADCONF_WAKEUP_EVENT \
| CONTROL_PADCONF_WAKEUP_ENABLE \
| CONTROL_PADCONF_OFF_PULL_UP \
| CONTROL_PADCONF_OFF_PULL_ENABLE \
| CONTROL_PADCONF_OFF_OUT_HIGH \
| CONTROL_PADCONF_OFF_OUT_ENABLE \
| CONTROL_PADCONF_OFF_ENABLE \
| CONTROL_PADCONF_INPUT_ENABLE \
| CONTROL_PADCONF_PULL_UP \
| CONTROL_PADCONF_PULL_ENABLE )
/* Active pin states */
#define PADCONF_PIN_OUTPUT 0
#define PADCONF_PIN_INPUT CONTROL_PADCONF_INPUT_ENABLE
#define PADCONF_PIN_INPUT_PULLUP ( CONTROL_PADCONF_INPUT_ENABLE \
| CONTROL_PADCONF_PULL_ENABLE \
| CONTROL_PADCONF_PULL_UP)
#define PADCONF_PIN_INPUT_PULLDOWN ( CONTROL_PADCONF_INPUT_ENABLE \
| CONTROL_PADCONF_PULL_ENABLE )
/* Off mode states */
#define PADCONF_PIN_OFF_NONE 0
#define PADCONF_PIN_OFF_OUTPUT_HIGH ( CONTROL_PADCONF_OFF_ENABLE \
| CONTROL_PADCONF_OFF_OUT_ENABLE \
| CONTROL_PADCONF_OFF_OUT_HIGH)
#define PADCONF_PIN_OFF_OUTPUT_LOW ( CONTROL_PADCONF_OFF_ENABLE \
| CONTROL_PADCONF_OFF_OUT_ENABLE)
#define PADCONF_PIN_OFF_INPUT_PULLUP ( CONTROL_PADCONF_OFF_ENABLE \
| CONTROL_PADCONF_OFF_PULL_ENABLE \
| CONTROL_PADCONF_OFF_PULL_UP)
#define PADCONF_PIN_OFF_INPUT_PULLDOWN ( CONTROL_PADCONF_OFF_ENABLE \
| CONTROL_PADCONF_OFF_PULL_ENABLE)
#define PADCONF_PIN_OFF_WAKEUPENABLE CONTROL_PADCONF_WAKEUP_ENABLE
#define _PINDEF(r, b, gp, gm, m0, m1, m2, m3, m4, m5, m6, m7) \
{ .reg_off = r, \
.gpio_pin = gp, \
@ -355,50 +301,3 @@ const struct ti_scm_device ti_scm_dev = {
.padstate = (struct ti_scm_padstate *) &ti_padstate_devmap,
.padconf = (struct ti_scm_padconf *) &ti_padconf_devmap,
};
int
ti_scm_padconf_set_gpioflags(uint32_t gpio, uint32_t flags)
{
unsigned int state = 0;
/* First the SCM driver needs to be told to put the pad into GPIO mode */
if (flags & GPIO_PIN_OUTPUT)
state = PADCONF_PIN_OUTPUT;
else if (flags & GPIO_PIN_INPUT) {
if (flags & GPIO_PIN_PULLUP)
state = PADCONF_PIN_INPUT_PULLUP;
else if (flags & GPIO_PIN_PULLDOWN)
state = PADCONF_PIN_INPUT_PULLDOWN;
else
state = PADCONF_PIN_INPUT;
}
return ti_scm_padconf_set_gpiomode(gpio, state);
}
void
ti_scm_padconf_get_gpioflags(uint32_t gpio, uint32_t *flags)
{
unsigned int state;
/* Get the current pin state */
if (ti_scm_padconf_get_gpiomode(gpio, &state) != 0)
*flags = 0;
else {
switch (state) {
case PADCONF_PIN_OUTPUT:
*flags = GPIO_PIN_OUTPUT;
break;
case PADCONF_PIN_INPUT:
*flags = GPIO_PIN_INPUT;
break;
case PADCONF_PIN_INPUT_PULLUP:
*flags = GPIO_PIN_INPUT | GPIO_PIN_PULLUP;
break;
case PADCONF_PIN_INPUT_PULLDOWN:
*flags = GPIO_PIN_INPUT | GPIO_PIN_PULLDOWN;
break;
default:
*flags = 0;
break;
}
}
}

View File

@ -0,0 +1,81 @@
/*-
* Copyright (c) 2011
* Ben Gray <ben.r.gray@gmail.com>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY BEN GRAY ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL BEN GRAY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef OMAP4_SCM_PADCONF_H
#define OMAP4_SCM_PADCONF_H
#define CONTROL_PADCONF_WAKEUP_EVENT (1UL << 15)
#define CONTROL_PADCONF_WAKEUP_ENABLE (1UL << 14)
#define CONTROL_PADCONF_OFF_PULL_UP (1UL << 13)
#define CONTROL_PADCONF_OFF_PULL_ENABLE (1UL << 12)
#define CONTROL_PADCONF_OFF_OUT_HIGH (1UL << 11)
#define CONTROL_PADCONF_OFF_OUT_ENABLE (1UL << 10)
#define CONTROL_PADCONF_OFF_ENABLE (1UL << 9)
#define CONTROL_PADCONF_INPUT_ENABLE (1UL << 8)
#define CONTROL_PADCONF_PULL_UP (1UL << 4)
#define CONTROL_PADCONF_PULL_ENABLE (1UL << 3)
#define CONTROL_PADCONF_MUXMODE_MASK (0x7)
#define CONTROL_PADCONF_SATE_MASK ( CONTROL_PADCONF_WAKEUP_EVENT \
| CONTROL_PADCONF_WAKEUP_ENABLE \
| CONTROL_PADCONF_OFF_PULL_UP \
| CONTROL_PADCONF_OFF_PULL_ENABLE \
| CONTROL_PADCONF_OFF_OUT_HIGH \
| CONTROL_PADCONF_OFF_OUT_ENABLE \
| CONTROL_PADCONF_OFF_ENABLE \
| CONTROL_PADCONF_INPUT_ENABLE \
| CONTROL_PADCONF_PULL_UP \
| CONTROL_PADCONF_PULL_ENABLE )
/* Active pin states */
#define PADCONF_PIN_OUTPUT 0
#define PADCONF_PIN_INPUT CONTROL_PADCONF_INPUT_ENABLE
#define PADCONF_PIN_INPUT_PULLUP ( CONTROL_PADCONF_INPUT_ENABLE \
| CONTROL_PADCONF_PULL_ENABLE \
| CONTROL_PADCONF_PULL_UP)
#define PADCONF_PIN_INPUT_PULLDOWN ( CONTROL_PADCONF_INPUT_ENABLE \
| CONTROL_PADCONF_PULL_ENABLE )
/* Off mode states */
#define PADCONF_PIN_OFF_NONE 0
#define PADCONF_PIN_OFF_OUTPUT_HIGH ( CONTROL_PADCONF_OFF_ENABLE \
| CONTROL_PADCONF_OFF_OUT_ENABLE \
| CONTROL_PADCONF_OFF_OUT_HIGH)
#define PADCONF_PIN_OFF_OUTPUT_LOW ( CONTROL_PADCONF_OFF_ENABLE \
| CONTROL_PADCONF_OFF_OUT_ENABLE)
#define PADCONF_PIN_OFF_INPUT_PULLUP ( CONTROL_PADCONF_OFF_ENABLE \
| CONTROL_PADCONF_OFF_PULL_ENABLE \
| CONTROL_PADCONF_OFF_PULL_UP)
#define PADCONF_PIN_OFF_INPUT_PULLDOWN ( CONTROL_PADCONF_OFF_ENABLE \
| CONTROL_PADCONF_OFF_PULL_ENABLE)
#define PADCONF_PIN_OFF_WAKEUPENABLE CONTROL_PADCONF_WAKEUP_ENABLE
#endif /* OMAP4_SCM_PADCONF_H */

View File

@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$");
#include <machine/resource.h>
#include <arm/ti/ti_cpuid.h>
#include <arm/ti/ti_gpio.h>
#include <arm/ti/ti_scm.h>
#include <arm/ti/ti_prcm.h>
@ -66,6 +67,7 @@ __FBSDID("$FreeBSD$");
#include <dev/ofw/ofw_bus_subr.h>
#include "gpio_if.h"
#include "ti_gpio_if.h"
/* Register definitions */
#define TI_GPIO_REVISION 0x0000
@ -115,9 +117,6 @@ __FBSDID("$FreeBSD$");
#define AM335X_INTR_PER_BANK 2
#define AM335X_GPIO_REV 0x50600801
#define PINS_PER_BANK 32
#define MAX_GPIO_BANKS 6
/* Maximum GPIOS possible, max of *_MAX_GPIO_BANKS * *_INTR_PER_BANK */
#define MAX_GPIO_INTRS 8
static u_int
ti_max_gpio_banks(void)
@ -224,33 +223,6 @@ static struct resource_spec ti_gpio_irq_spec[] = {
{ -1, 0, 0 }
};
/**
* Structure that stores the driver context.
*
* This structure is allocated during driver attach.
*/
struct ti_gpio_softc {
device_t sc_dev;
/*
* The memory resource(s) for the PRCM register set, when the device is
* created the caller can assign up to 6 memory regions depending on
* the SoC type.
*/
struct resource *sc_mem_res[MAX_GPIO_BANKS];
struct resource *sc_irq_res[MAX_GPIO_INTRS];
/* The handle for the register IRQ handlers. */
void *sc_irq_hdl[MAX_GPIO_INTRS];
/*
* The following describes the H/W revision of each of the GPIO banks.
*/
uint32_t sc_revision[MAX_GPIO_BANKS];
struct mtx sc_mtx;
};
/**
* Macros for driver mutex locking
*/
@ -418,7 +390,7 @@ ti_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
}
/* Get the current pin state */
ti_scm_padconf_get_gpioflags(pin, flags);
TI_GPIO_GET_FLAGS(dev, pin, flags);
TI_GPIO_UNLOCK(sc);
@ -509,7 +481,7 @@ ti_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
}
/* Set the GPIO mode and state */
if (ti_scm_padconf_set_gpioflags(pin, flags) != 0) {
if (TI_GPIO_SET_FLAGS(dev, pin, flags) != 0) {
TI_GPIO_UNLOCK(sc);
return (EINVAL);
}
@ -669,33 +641,6 @@ ti_gpio_intr(void *arg)
TI_GPIO_UNLOCK(sc);
}
/**
* ti_gpio_probe - probe function for the driver
* @dev: gpio device handle
*
* Simply sets the name of the driver
*
* LOCKING:
* None
*
* RETURNS:
* Always returns 0
*/
static int
ti_gpio_probe(device_t dev)
{
if (!ofw_bus_status_okay(dev))
return (ENXIO);
if (!ofw_bus_is_compatible(dev, "ti,gpio"))
return (ENXIO);
device_set_desc(dev, "TI General Purpose I/O (GPIO)");
return (0);
}
static int
ti_gpio_attach_intr(device_t dev)
{
@ -776,8 +721,7 @@ ti_gpio_bank_init(device_t dev, int bank)
/* Init OE register based on pads configuration. */
reg_oe = 0xffffffff;
for (pin = 0; pin < PINS_PER_BANK; pin++) {
ti_scm_padconf_get_gpioflags(PINS_PER_BANK * bank + pin,
&flags);
TI_GPIO_GET_FLAGS(dev, PINS_PER_BANK * bank + pin, &flags);
if (flags & GPIO_PIN_OUTPUT)
reg_oe &= ~(1UL << pin);
}
@ -910,7 +854,6 @@ ti_gpio_get_node(device_t bus, device_t dev)
}
static device_method_t ti_gpio_methods[] = {
DEVMETHOD(device_probe, ti_gpio_probe),
DEVMETHOD(device_attach, ti_gpio_attach),
DEVMETHOD(device_detach, ti_gpio_detach),
@ -930,11 +873,8 @@ static device_method_t ti_gpio_methods[] = {
{0, 0},
};
static driver_t ti_gpio_driver = {
driver_t ti_gpio_driver = {
"gpio",
ti_gpio_methods,
sizeof(struct ti_gpio_softc),
};
static devclass_t ti_gpio_devclass;
DRIVER_MODULE(ti_gpio, simplebus, ti_gpio_driver, ti_gpio_devclass, 0, 0);

69
sys/arm/ti/ti_gpio.h Normal file
View File

@ -0,0 +1,69 @@
/*-
* Copyright (c) 2011
* Ben Gray <ben.r.gray@gmail.com>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef TI_GPIO_H
#define TI_GPIO_H
/* The maximum number of banks for any SoC */
#define MAX_GPIO_BANKS 6
/*
* Maximum GPIOS possible, max of *_MAX_GPIO_BANKS * *_INTR_PER_BANK.
* These are defined in ti_gpio.c
*/
#define MAX_GPIO_INTRS 8
/**
* Structure that stores the driver context.
*
* This structure is allocated during driver attach.
*/
struct ti_gpio_softc {
device_t sc_dev;
/*
* The memory resource(s) for the PRCM register set, when the device is
* created the caller can assign up to 6 memory regions depending on
* the SoC type.
*/
struct resource *sc_mem_res[MAX_GPIO_BANKS];
struct resource *sc_irq_res[MAX_GPIO_INTRS];
/* The handle for the register IRQ handlers. */
void *sc_irq_hdl[MAX_GPIO_INTRS];
/*
* The following describes the H/W revision of each of the GPIO banks.
*/
uint32_t sc_revision[MAX_GPIO_BANKS];
struct mtx sc_mtx;
};
#endif /* TI_GPIO_H */

49
sys/arm/ti/ti_gpio_if.m Normal file
View File

@ -0,0 +1,49 @@
#-
# Copyright (c) 2014 Andrew Turner <andrew@FreeBSD.org>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# $FreeBSD$
#
#include <sys/bus.h>
INTERFACE ti_gpio;
/**
* Sets the Ti SoCs gpio flags
*/
METHOD int set_flags {
device_t dev;
uint32_t gpio;
uint32_t flags;
};
/**
* Gets the Ti SoCs gpio flags
*/
METHOD int get_flags {
device_t dev;
uint32_t gpio;
uint32_t *flags;
};

View File

@ -76,8 +76,6 @@ int ti_scm_padconf_get(const char *padname, const char **muxmode,
unsigned int *state);
int ti_scm_padconf_set_gpiomode(uint32_t gpio, unsigned int state);
int ti_scm_padconf_get_gpiomode(uint32_t gpio, unsigned int *state);
int ti_scm_padconf_set_gpioflags(uint32_t gpio, uint32_t flags);
void ti_scm_padconf_get_gpioflags(uint32_t gpio, uint32_t *flags);
int ti_scm_reg_read_4(uint32_t reg, uint32_t *val);
int ti_scm_reg_write_4(uint32_t reg, uint32_t val);