summaryrefslogtreecommitdiffstats
path: root/libopenbmc_intf
diff options
context:
space:
mode:
authorPatrick Williams <patrick@stwcx.xyz>2016-08-24 14:23:45 -0500
committerPatrick Williams <patrick@stwcx.xyz>2016-08-24 14:24:40 -0500
commited1368dab8568edabb6aa8baacfb90e661997cbd (patch)
tree853a996835889f1734b6972839837a4c16386133 /libopenbmc_intf
parentd6baab92ca4fee70a55c81a009755637e7d595a5 (diff)
downloadtalos-skeleton-ed1368dab8568edabb6aa8baacfb90e661997cbd.tar.gz
talos-skeleton-ed1368dab8568edabb6aa8baacfb90e661997cbd.zip
gpio: Avoid glitching 'out'-direction GPIOs
Change-Id: I42dafd3235d13ec57f7b15e043bc3fe82fdb4665 Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
Diffstat (limited to 'libopenbmc_intf')
-rw-r--r--libopenbmc_intf/gpio.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/libopenbmc_intf/gpio.c b/libopenbmc_intf/gpio.c
index e48eff4..0dfb260 100644
--- a/libopenbmc_intf/gpio.c
+++ b/libopenbmc_intf/gpio.c
@@ -149,18 +149,36 @@ int gpio_init(GDBusConnection *connection, GPIO* gpio)
}
}
const char* file = "edge";
- if (strcmp(gpio->direction,"in")==0 || strcmp(gpio->direction,"out")==0)
+ const char* direction = gpio->direction;
+ if (strcmp(direction, "in") == 0)
{
file = "direction";
}
+ else if (strcmp(direction, "out") == 0)
+ {
+ file = "direction";
+
+ // Read current value, so we can set 'high' or 'low'.
+ // Setting direction directly to 'out' is the same as
+ // setting to 'low' which can change the value in the
+ // GPIO.
+ uint8_t value = 0;
+ rc = gpio_open(gpio);
+ if (rc) break;
+ rc = gpio_read(gpio, &value);
+ if (rc) break;
+ gpio_close(gpio);
+
+ direction = (value ? "high" : "low");
+ }
sprintf(dev,"%s/gpio%d/%s",gpio->dev,gpio->num,file);
fd = open(dev,O_WRONLY);
if (fd == GPIO_ERROR) {
rc = GPIO_WRITE_ERROR;
break;
}
- rc = write(fd,gpio->direction,strlen(gpio->direction));
- if (rc != strlen(gpio->direction)) {
+ rc = write(fd,direction,strlen(direction));
+ if (rc != strlen(direction)) {
rc = GPIO_WRITE_ERROR;
break;
}
OpenPOWER on IntegriCloud