diff options
author | Patrick Williams <patrick@stwcx.xyz> | 2016-08-24 14:23:45 -0500 |
---|---|---|
committer | Patrick Williams <patrick@stwcx.xyz> | 2016-08-24 14:24:40 -0500 |
commit | ed1368dab8568edabb6aa8baacfb90e661997cbd (patch) | |
tree | 853a996835889f1734b6972839837a4c16386133 /libopenbmc_intf/gpio.c | |
parent | d6baab92ca4fee70a55c81a009755637e7d595a5 (diff) | |
download | blackbird-skeleton-ed1368dab8568edabb6aa8baacfb90e661997cbd.tar.gz blackbird-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/gpio.c')
-rw-r--r-- | libopenbmc_intf/gpio.c | 24 |
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; } |