drivers/jtag_vpi: Group adapter commands
[fw/openocd] / src / jtag / drivers / sysfsgpio.c
index f9470a47b3c7b63d3ad3e6e8f4b129dea3d0b0d2..78a4c5b77e9928165adef0656be601463570ec48 100644 (file)
@@ -29,7 +29,7 @@
  *
  * A gpio is required for tck, tms, tdi and tdo. One or both of srst and trst
  * must be also be specified. The required jtag gpios are specified via the
- * sysfsgpio_jtag_nums command or the relevant sysfsgpio_XXX_num commang.
+ * sysfsgpio_jtag_nums command or the relevant sysfsgpio_XXX_num commands.
  * The srst and trst gpios are set via the sysfsgpio_srst_num and
  * sysfsgpio_trst_num respectively. GPIO numbering follows the kernel
  * convention of starting from 0.
@@ -54,6 +54,7 @@
 
 #include <helper/time_support.h>
 #include <jtag/interface.h>
+#include <transport/transport.h>
 #include "bitbang.h"
 
 /*
@@ -126,7 +127,7 @@ static int setup_sysfs_gpio(int gpio, int is_output, int init_high)
                        LOG_WARNING("gpio %d is already exported", gpio);
                } else {
                        LOG_ERROR("Couldn't export gpio %d", gpio);
-                       perror("sysfsgpio: ");
+                       LOG_ERROR("sysfsgpio: %s", strerror(errno));
                        return ERROR_FAIL;
                }
        }
@@ -146,7 +147,7 @@ static int setup_sysfs_gpio(int gpio, int is_output, int init_high)
        }
        if (ret < 0) {
                LOG_ERROR("Couldn't set direction for gpio %d", gpio);
-               perror("sysfsgpio: ");
+               LOG_ERROR("sysfsgpio: %s", strerror(errno));
                unexport_sysfs_gpio(gpio);
                return ERROR_FAIL;
        }
@@ -163,7 +164,7 @@ static int setup_sysfs_gpio(int gpio, int is_output, int init_high)
        }
        if (ret < 0) {
                LOG_ERROR("Couldn't open value for gpio %d", gpio);
-               perror("sysfsgpio: ");
+               LOG_ERROR("sysfsgpio: %s", strerror(errno));
                unexport_sysfs_gpio(gpio);
        }
 
@@ -207,7 +208,7 @@ static void sysfsgpio_swdio_drive(bool is_output)
        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: ");
+               LOG_ERROR("sysfsgpio: %s", strerror(errno));
        }
 
        last_stored = false;
@@ -230,7 +231,7 @@ static int sysfsgpio_swdio_read(void)
        return buf[0] != '0';
 }
 
-static void sysfsgpio_swdio_write(int swclk, int swdio)
+static int sysfsgpio_swd_write(int swclk, int swdio)
 {
        const char one[] = "1";
        const char zero[] = "0";
@@ -255,6 +256,8 @@ static void sysfsgpio_swdio_write(int swclk, int swdio)
        last_swdio = swdio;
        last_swclk = swclk;
        last_stored = true;
+
+       return ERROR_OK;
 }
 
 /*
@@ -287,11 +290,6 @@ static bb_value_t sysfsgpio_read(void)
  */
 static int sysfsgpio_write(int tck, int tms, int tdi)
 {
-       if (swd_mode) {
-               sysfsgpio_swdio_write(tck, tdi);
-               return ERROR_OK;
-       }
-
        const char one[] = "1";
        const char zero[] = "0";
 
@@ -572,6 +570,7 @@ static struct bitbang_interface sysfsgpio_bitbang = {
        .write = sysfsgpio_write,
        .swdio_read = sysfsgpio_swdio_read,
        .swdio_drive = sysfsgpio_swdio_drive,
+       .swd_write = sysfsgpio_swd_write,
        .blink = 0
 };
 
@@ -588,14 +587,18 @@ static void cleanup_fd(int fd, int gpio)
 
 static void cleanup_all_fds(void)
 {
-       cleanup_fd(tck_fd, tck_gpio);
-       cleanup_fd(tms_fd, tms_gpio);
-       cleanup_fd(tdi_fd, tdi_gpio);
-       cleanup_fd(tdo_fd, tdo_gpio);
-       cleanup_fd(trst_fd, trst_gpio);
+       if (transport_is_jtag()) {
+               cleanup_fd(tck_fd, tck_gpio);
+               cleanup_fd(tms_fd, tms_gpio);
+               cleanup_fd(tdi_fd, tdi_gpio);
+               cleanup_fd(tdo_fd, tdo_gpio);
+               cleanup_fd(trst_fd, trst_gpio);
+       }
+       if (transport_is_swd()) {
+               cleanup_fd(swclk_fd, swclk_gpio);
+               cleanup_fd(swdio_fd, swdio_gpio);
+       }
        cleanup_fd(srst_fd, srst_gpio);
-       cleanup_fd(swclk_fd, swclk_gpio);
-       cleanup_fd(swdio_fd, swdio_gpio);
 }
 
 static bool sysfsgpio_jtag_mode_possible(void)
@@ -626,74 +629,64 @@ static int sysfsgpio_init(void)
 
        LOG_INFO("SysfsGPIO JTAG/SWD bitbang driver");
 
-       if (sysfsgpio_jtag_mode_possible()) {
-               if (sysfsgpio_swd_mode_possible())
-                       LOG_INFO("JTAG and SWD modes enabled");
-               else
-                       LOG_INFO("JTAG only mode enabled (specify swclk and swdio gpio to add SWD mode)");
-       } else if (sysfsgpio_swd_mode_possible()) {
-               LOG_INFO("SWD only mode enabled (specify tck, tms, tdi and tdo gpios to add JTAG mode)");
-       } else {
-               LOG_ERROR("Require tck, tms, tdi and tdo gpios for JTAG mode and/or swclk and swdio gpio for SWD mode");
-               return ERROR_JTAG_INIT_FAILED;
-       }
-
-
        /*
         * Configure TDO as an input, and TDI, TCK, TMS, TRST, SRST
         * as outputs.  Drive TDI and TCK low, and TMS/TRST/SRST high.
         * For SWD, SWCLK and SWDIO are configures as output high.
         */
-       if (tck_gpio >= 0) {
+
+       if (transport_is_jtag()) {
+               if (!sysfsgpio_jtag_mode_possible()) {
+                       LOG_ERROR("Require tck, tms, tdi and tdo gpios for JTAG mode");
+                       return ERROR_JTAG_INIT_FAILED;
+               }
+
                tck_fd = setup_sysfs_gpio(tck_gpio, 1, 0);
                if (tck_fd < 0)
                        goto out_error;
-       }
 
-       if (tms_gpio >= 0) {
                tms_fd = setup_sysfs_gpio(tms_gpio, 1, 1);
                if (tms_fd < 0)
                        goto out_error;
-       }
 
-       if (tdi_gpio >= 0) {
                tdi_fd = setup_sysfs_gpio(tdi_gpio, 1, 0);
                if (tdi_fd < 0)
                        goto out_error;
-       }
 
-       if (tdo_gpio >= 0) {
                tdo_fd = setup_sysfs_gpio(tdo_gpio, 0, 0);
                if (tdo_fd < 0)
                        goto out_error;
-       }
 
-       /* assume active low*/
-       if (trst_gpio >= 0) {
-               trst_fd = setup_sysfs_gpio(trst_gpio, 1, 1);
-               if (trst_fd < 0)
-                       goto out_error;
+               /* assume active low*/
+               if (trst_gpio >= 0) {
+                       trst_fd = setup_sysfs_gpio(trst_gpio, 1, 1);
+                       if (trst_fd < 0)
+                               goto out_error;
+               }
        }
 
-       /* assume active low*/
-       if (srst_gpio >= 0) {
-               srst_fd = setup_sysfs_gpio(srst_gpio, 1, 1);
-               if (srst_fd < 0)
-                       goto out_error;
-       }
+       if (transport_is_swd()) {
+               if (!sysfsgpio_swd_mode_possible()) {
+                       LOG_ERROR("Require swclk and swdio gpio for SWD mode");
+                       return ERROR_JTAG_INIT_FAILED;
+               }
 
-       if (swclk_gpio >= 0) {
                swclk_fd = setup_sysfs_gpio(swclk_gpio, 1, 0);
                if (swclk_fd < 0)
                        goto out_error;
-       }
 
-       if (swdio_gpio >= 0) {
                swdio_fd = setup_sysfs_gpio(swdio_gpio, 1, 0);
                if (swdio_fd < 0)
                        goto out_error;
        }
 
+       /* assume active low*/
+       if (srst_gpio >= 0) {
+               srst_fd = setup_sysfs_gpio(srst_gpio, 1, 1);
+               if (srst_fd < 0)
+                       goto out_error;
+       }
+
        return ERROR_OK;
 
 out_error: