+static int swclk_fd = -1;
+static int swdio_fd = -1;
+
+static int last_swclk;
+static int last_swdio;
+static bool last_stored;
+static bool swdio_input;
+
+static void sysfsgpio_swdio_drive(bool is_output)
+{
+ char buf[40];
+ int ret;
+
+ snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/direction", swdio_gpio);
+ ret = open_write_close(buf, is_output ? "high" : "in");
+ if (ret < 0) {
+ LOG_ERROR("Couldn't set direction for gpio %d", swdio_gpio);
+ perror("sysfsgpio: ");
+ }
+
+ last_stored = false;
+ swdio_input = !is_output;
+}
+
+static int sysfsgpio_swdio_read(void)
+{
+ char buf[1];
+
+ /* important to seek to signal sysfs of new read */
+ lseek(swdio_fd, 0, SEEK_SET);
+ int ret = read(swdio_fd, &buf, sizeof(buf));
+
+ if (ret < 0) {
+ LOG_WARNING("reading swdio failed");
+ return 0;
+ }
+
+ return buf[0] != '0';
+}
+
+static void sysfsgpio_swdio_write(int swclk, int swdio)
+{
+ const char one[] = "1";
+ const char zero[] = "0";
+
+ size_t bytes_written;
+
+ if (!swdio_input) {
+ if (!last_stored || (swdio != last_swdio)) {
+ bytes_written = write(swdio_fd, swdio ? &one : &zero, 1);
+ if (bytes_written != 1)
+ LOG_WARNING("writing swdio failed");
+ }
+ }
+
+ /* write swclk last */
+ if (!last_stored || (swclk != last_swclk)) {
+ bytes_written = write(swclk_fd, swclk ? &one : &zero, 1);
+ if (bytes_written != 1)
+ LOG_WARNING("writing swclk failed");
+ }
+
+ last_swdio = swdio;
+ last_swclk = swclk;
+ last_stored = true;
+}