svn commit: r326433 - head/sys/arm/allwinner
Kyle Evans
kevans at FreeBSD.org
Fri Dec 1 20:51:09 UTC 2017
Author: kevans
Date: Fri Dec 1 20:51:08 2017
New Revision: 326433
URL: https://svnweb.freebsd.org/changeset/base/326433
Log:
a10_gpio: Add support for more modern pin configuration
a10_gpio previously accepted only {allwinner,}drive and {allwinner,}pull for
drive/bias setting, while newer DTS is using drive-strength and
bias-{disable,pull-up,pull-down} properties. Accept these properties as
well.
Additionally make bias and drive strength optional rather than required; not
setting them should just indicate that we do not need to configure these
properties.
Tested on: BananaPi-M3 (a83t)
Reviewed by: manu
Approved by: emaste (implicit)
Obtained from: NetBSD (partially)
Differential Revision: https://reviews.freebsd.org/D13284
Modified:
head/sys/arm/allwinner/a10_gpio.c
Modified: head/sys/arm/allwinner/a10_gpio.c
==============================================================================
--- head/sys/arm/allwinner/a10_gpio.c Fri Dec 1 17:58:20 2017 (r326432)
+++ head/sys/arm/allwinner/a10_gpio.c Fri Dec 1 20:51:08 2017 (r326433)
@@ -203,6 +203,11 @@ struct a10_gpio_softc {
#define A10_GPIO_GP_INT_STA 0x214
#define A10_GPIO_GP_INT_DEB 0x218
+static char *a10_gpio_parse_function(phandle_t node);
+static const char **a10_gpio_parse_pins(phandle_t node, int *pins_nb);
+static uint32_t a10_gpio_parse_bias(phandle_t node);
+static int a10_gpio_parse_drive_strength(phandle_t node, uint32_t *drive);
+
static int a10_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *value);
static int a10_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value);
static int a10_gpio_pin_get_locked(struct a10_gpio_softc *sc, uint32_t pin, unsigned int *value);
@@ -278,6 +283,9 @@ a10_gpio_set_pud(struct a10_gpio_softc *sc, uint32_t p
{
uint32_t bank, offset, val;
+ if (a10_gpio_get_pud(sc, pin) == state)
+ return;
+
/* Must be called with lock held. */
A10_GPIO_LOCK_ASSERT(sc);
@@ -313,6 +321,9 @@ a10_gpio_set_drv(struct a10_gpio_softc *sc, uint32_t p
{
uint32_t bank, offset, val;
+ if (a10_gpio_get_drv(sc, pin) == drive)
+ return;
+
/* Must be called with lock held. */
A10_GPIO_LOCK_ASSERT(sc);
@@ -541,7 +552,76 @@ a10_gpio_pin_get_locked(struct a10_gpio_softc *sc,uint
return (0);
}
+static char *
+a10_gpio_parse_function(phandle_t node)
+{
+ char *function;
+
+ if (OF_getprop_alloc(node, "function", sizeof(*function),
+ (void **)&function) != -1)
+ return (function);
+ if (OF_getprop_alloc(node, "allwinner,function", sizeof(*function),
+ (void **)&function) != -1)
+ return (function);
+
+ return (NULL);
+}
+
+static const char **
+a10_gpio_parse_pins(phandle_t node, int *pins_nb)
+{
+ const char **pinlist;
+
+ *pins_nb = ofw_bus_string_list_to_array(node, "pins", &pinlist);
+ if (*pins_nb > 0)
+ return (pinlist);
+
+ *pins_nb = ofw_bus_string_list_to_array(node, "allwinner,pins",
+ &pinlist);
+ if (*pins_nb > 0)
+ return (pinlist);
+
+ return (NULL);
+}
+
+static uint32_t
+a10_gpio_parse_bias(phandle_t node)
+{
+ uint32_t bias;
+
+ if (OF_getencprop(node, "pull", &bias, sizeof(bias)) != -1)
+ return (bias);
+ if (OF_getencprop(node, "allwinner,pull", &bias, sizeof(bias)) != -1)
+ return (bias);
+ if (OF_hasprop(node, "bias-disable"))
+ return (A10_GPIO_NONE);
+ if (OF_hasprop(node, "bias-pull-up"))
+ return (A10_GPIO_PULLUP);
+ if (OF_hasprop(node, "bias-pull-down"))
+ return (A10_GPIO_PULLDOWN);
+
+ return (A10_GPIO_NONE);
+}
+
static int
+a10_gpio_parse_drive_strength(phandle_t node, uint32_t *drive)
+{
+ uint32_t drive_str;
+
+ if (OF_getencprop(node, "drive", drive, sizeof(*drive)) != -1)
+ return (0);
+ if (OF_getencprop(node, "allwinner,drive", drive, sizeof(*drive)) != -1)
+ return (0);
+ if (OF_getencprop(node, "drive-strength", &drive_str,
+ sizeof(drive_str)) != -1) {
+ *drive = (drive_str / 10) - 1;
+ return (0);
+ }
+
+ return (1);
+}
+
+static int
a10_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
{
struct a10_gpio_softc *sc;
@@ -682,46 +762,29 @@ aw_fdt_configure_pins(device_t dev, phandle_t cfgxref)
char *pin_function = NULL;
uint32_t pin_drive, pin_pull;
int pins_nb, pin_num, pin_func, i, ret;
+ bool set_drive;
sc = device_get_softc(dev);
node = OF_node_from_xref(cfgxref);
ret = 0;
+ set_drive = false;
/* Getting all prop for configuring pins */
- pins_nb = ofw_bus_string_list_to_array(node, "pins", &pinlist);
- if (pins_nb <= 0) {
- pins_nb = ofw_bus_string_list_to_array(node, "allwinner,pins",
- &pinlist);
- if (pins_nb <= 0)
- return (ENOENT);
+ pinlist = a10_gpio_parse_pins(node, &pins_nb);
+ if (pinlist == NULL)
+ return (ENOENT);
+
+ pin_function = a10_gpio_parse_function(node);
+ if (pin_function == NULL) {
+ ret = ENOENT;
+ goto out;
}
- if (OF_getprop_alloc(node, "function",
- sizeof(*pin_function),
- (void **)&pin_function) == -1) {
- if (OF_getprop_alloc(node, "allwinner,function",
- sizeof(*pin_function),
- (void **)&pin_function) == -1) {
- ret = ENOENT;
- goto out;
- }
- }
- if (OF_getencprop(node, "drive",
- &pin_drive, sizeof(pin_drive)) == -1) {
- if (OF_getencprop(node, "allwinner,drive",
- &pin_drive, sizeof(pin_drive)) == -1) {
- ret = ENOENT;
- goto out;
- }
- }
- if (OF_getencprop(node, "pull",
- &pin_pull, sizeof(pin_pull)) == -1) {
- if (OF_getencprop(node, "allwinner,pull",
- &pin_pull, sizeof(pin_pull)) == -1) {
- ret = ENOENT;
- goto out;
- }
- }
+ if (a10_gpio_parse_drive_strength(node, &pin_drive) == 0)
+ set_drive = true;
+
+ pin_pull = a10_gpio_parse_bias(node);
+
/* Configure each pin to the correct function, drive and pull */
for (i = 0; i < pins_nb; i++) {
pin_num = aw_find_pinnum_by_name(sc, pinlist[i]);
@@ -739,12 +802,11 @@ aw_fdt_configure_pins(device_t dev, phandle_t cfgxref)
if (a10_gpio_get_function(sc, pin_num) != pin_func)
a10_gpio_set_function(sc, pin_num, pin_func);
- if (a10_gpio_get_drv(sc, pin_num) != pin_drive)
+ if (set_drive)
a10_gpio_set_drv(sc, pin_num, pin_drive);
- if (a10_gpio_get_pud(sc, pin_num) != pin_pull &&
- (pin_pull == A10_GPIO_PULLUP ||
- pin_pull == A10_GPIO_PULLDOWN))
+ if (pin_pull != A10_GPIO_NONE)
a10_gpio_set_pud(sc, pin_num, pin_pull);
+
A10_GPIO_UNLOCK(sc);
}
More information about the svn-src-head
mailing list