Module Name:    src
Committed By:   reinoud
Date:           Fri May 16 10:02:24 UTC 2014

Modified Files:
        src/sys/arch/arm/samsung: exynos_gpio.c

Log Message:
Fix issues with the gpio controller:
* the func get/put shift is 4 bits, not 16!
* redo available and inuse bits
* create a function to get a pindata from a pinset


To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/arm/samsung/exynos_gpio.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/arm/samsung/exynos_gpio.c
diff -u src/sys/arch/arm/samsung/exynos_gpio.c:1.4 src/sys/arch/arm/samsung/exynos_gpio.c:1.5
--- src/sys/arch/arm/samsung/exynos_gpio.c:1.4	Wed May 14 09:03:09 2014
+++ src/sys/arch/arm/samsung/exynos_gpio.c	Fri May 16 10:02:24 2014
@@ -32,7 +32,7 @@
 #include "gpio.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: exynos_gpio.c,v 1.4 2014/05/14 09:03:09 reinoud Exp $");
+__KERNEL_RCSID(1, "$NetBSD: exynos_gpio.c,v 1.5 2014/05/16 10:02:24 reinoud Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -334,8 +334,13 @@ exynos_gpio_attach(device_t parent, devi
 		snprintf(scrap, sizeof(scrap), "nc-%s", grp->grp_name);
 		if (prop_dictionary_get_uint32(dict, scrap, &nc)) {
 			KASSERT((~grp->grp_pin_mask & nc) == 0);
-			KASSERT((grp->grp_pin_inuse_mask & ~nc) == 0);
+			/* switch off the pins we have signalled NC */
 			grp->grp_pin_mask &= ~nc;
+#if 0
+			printf("%s: %-4s inuse_mask %02x, pin_mask %02x\n",
+			    __func__, grp->grp_name,
+			    grp->grp_pin_inuse_mask, grp->grp_pin_mask);
+#endif
 		}
 	}
 
@@ -349,7 +354,7 @@ exynos_gpio_attach(device_t parent, devi
 static u_int
 exynos_gpio_get_pin_func(const struct exynos_gpio_pin_cfg *cfg, int pin)
 {
-	const u_int shift = (pin & 7) << 4;
+	const u_int shift = (pin & 7) << 2;
 
 	return (cfg->cfg >> shift) & 0x0f;
 }
@@ -359,7 +364,7 @@ static void
 exynos_gpio_set_pin_func(struct exynos_gpio_pin_cfg *cfg,
 	int pin, int func)
 {
-	const u_int shift = (pin & 7) << 4;
+	const u_int shift = (pin & 7) << 2;
 
 	cfg->cfg &= ~(0x0f << shift);
 	cfg->cfg |= func << shift;
@@ -564,6 +569,32 @@ exynos_gpio_pinset_acquire(const struct 
 }
 
 
+/* get a pindata structure from a pinset structure */
+void
+exynos_gpio_pinset_to_pindata(const struct exynos_gpio_pinset *req, int pinnr,
+	struct exynos_gpio_pindata *pd)
+{
+	struct exynos_gpio_pin_group *grp;
+	int i;
+
+	KASSERT(req);
+	KASSERT(pd);
+	KASSERT(req->pinset_mask & __BIT(pinnr));
+
+	/* determine which group is requested */
+	grp = NULL;
+	for (i = 0; i < exynos_n_pin_groups; i++) {
+		grp = &exynos_pin_groups[i];
+		if (strcmp(req->pinset_group, grp->grp_name) == 0)
+			break;
+	}
+	KASSERT(grp);
+
+	pd->pd_gc = &grp->grp_gc_tag;
+	pd->pd_pin = pinnr;
+}
+
+
 /* XXXRPZ This release doesn't grock multiple usages! */
 void
 exynos_gpio_pinset_release(const struct exynos_gpio_pinset *req)
@@ -704,7 +735,8 @@ exynos_gpio_pin_reserve(const char *name
 	exynos_gpio_set_pin_pull(&ncfg, pinnr, pud);
 	exynos_gpio_update_cfg_regs(grp, &ncfg);
 
-	grp->grp_pin_inuse_mask &= ~__BIT(pinnr);
+	grp->grp_pin_inuse_mask |= __BIT(pinnr);
+	grp->grp_pin_mask &= ~__BIT(pinnr);
 
 	pd->pd_gc = &grp->grp_gc_tag;
 	pd->pd_pin = pinnr;
@@ -720,7 +752,7 @@ exynos_gpio_bootstrap(void)
 	bus_space_tag_t bst = &exynos_bs_tag;
 	struct exynos_gpio_pin_group *grp;
 	struct gpio_chipset_tag *gc_tag;
-	int i, j, func, mask;
+	int i;
 
 	/* determine what we're running on */
 #ifdef EXYNOS4
@@ -769,15 +801,24 @@ exynos_gpio_bootstrap(void)
 		grp->grp_cfg.pudpwd = bus_space_read_4(bst, grp->grp_bsh,
 			EXYNOS_GPIO_PUDPWD);
 
-		/* count number of busy pins */
-		for (j = 0, mask = 1;
+		/*
+		 * Normally we would count the busy pins.
+		 *
+		 * We can't check inuse here since uboot has used pins for its
+		 * own use and left them configured forbidding us to use pins
+		 * for our own sake.
+		 */
+#if 0
+		for (int j = 0, int mask = 1;
 		     (mask & grp->grp_pin_mask) != 0;
 		     j++, mask <<= 1) {
-			func = exynos_gpio_get_pin_func(&grp->grp_cfg, j);
+			int func = exynos_gpio_get_pin_func(&grp->grp_cfg, j);
 			if (func > EXYNOS_GPIO_FUNC_INPUT) {
-				grp->grp_pin_inuse_mask |= mask;
+				printf("%s: %s[%d] func %d\n", __func__,
+				    grp->grp_name, j, func);
 			}
 		}
+#endif
 	}
 #if 0
 	printf("\n");

Reply via email to