aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSteve Marple <stevemarple@googlemail.com>2022-06-21 23:06:25 +0100
committerAntonio Borneo <borneo.antonio@gmail.com>2022-08-15 13:24:54 +0000
commit290eac04b93cd2f98e0a921e9dbf73b0822ae33b (patch)
treea5a9c0c06c3faaf7d954da0aec634450b41e15e1 /src
parent903f2e92a143acf66fcaa82e628c1672fdd0da9f (diff)
downloadriscv-openocd-290eac04b93cd2f98e0a921e9dbf73b0822ae33b.zip
riscv-openocd-290eac04b93cd2f98e0a921e9dbf73b0822ae33b.tar.gz
riscv-openocd-290eac04b93cd2f98e0a921e9dbf73b0822ae33b.tar.bz2
drivers/linuxgpiod: Migrate to adapter gpio commands
Use the new "adapter gpio" commands to configure the GPIOs used by the linuxgpiod driver. Adds support for drive mode and resistor pull options on all signals. Change-Id: Ic90cb4f06db82435294228b6793330107a9f3606 Signed-off-by: Steve Marple <stevemarple@googlemail.com> Reviewed-on: https://review.openocd.org/c/openocd/+/7048 Tested-by: jenkins Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/jtag/drivers/linuxgpiod.c636
-rw-r--r--src/jtag/startup.tcl127
2 files changed, 261 insertions, 502 deletions
diff --git a/src/jtag/drivers/linuxgpiod.c b/src/jtag/drivers/linuxgpiod.c
index 0e96d82..e8e93a5 100644
--- a/src/jtag/drivers/linuxgpiod.c
+++ b/src/jtag/drivers/linuxgpiod.c
@@ -14,67 +14,41 @@
#endif
#include <gpiod.h>
+#include <jtag/adapter.h>
#include <jtag/interface.h>
#include <transport/transport.h>
#include "bitbang.h"
-/* gpio numbers for each gpio. Negative values are invalid */
-static int tck_gpio = -1;
-static int tms_gpio = -1;
-static int tdi_gpio = -1;
-static int tdo_gpio = -1;
-static int trst_gpio = -1;
-static int srst_gpio = -1;
-static int swclk_gpio = -1;
-static int swdio_gpio = -1;
-static int swdio_dir_gpio = -1;
-static int led_gpio = -1;
-static int gpiochip = -1;
-static int tck_gpiochip = -1;
-static int tms_gpiochip = -1;
-static int tdi_gpiochip = -1;
-static int tdo_gpiochip = -1;
-static int trst_gpiochip = -1;
-static int srst_gpiochip = -1;
-static int swclk_gpiochip = -1;
-static int swdio_gpiochip = -1;
-static int swdio_dir_gpiochip = -1;
-static int led_gpiochip = -1;
-
-static struct gpiod_chip *gpiod_chip_tck;
-static struct gpiod_chip *gpiod_chip_tms;
-static struct gpiod_chip *gpiod_chip_tdi;
-static struct gpiod_chip *gpiod_chip_tdo;
-static struct gpiod_chip *gpiod_chip_trst;
-static struct gpiod_chip *gpiod_chip_srst;
-static struct gpiod_chip *gpiod_chip_swclk;
-static struct gpiod_chip *gpiod_chip_swdio;
-static struct gpiod_chip *gpiod_chip_swdio_dir;
-static struct gpiod_chip *gpiod_chip_led;
-
-static struct gpiod_line *gpiod_tck;
-static struct gpiod_line *gpiod_tms;
-static struct gpiod_line *gpiod_tdi;
-static struct gpiod_line *gpiod_tdo;
-static struct gpiod_line *gpiod_trst;
-static struct gpiod_line *gpiod_swclk;
-static struct gpiod_line *gpiod_swdio;
-static struct gpiod_line *gpiod_swdio_dir;
-static struct gpiod_line *gpiod_srst;
-static struct gpiod_line *gpiod_led;
+static struct gpiod_chip *gpiod_chip[ADAPTER_GPIO_IDX_NUM] = {};
+static struct gpiod_line *gpiod_line[ADAPTER_GPIO_IDX_NUM] = {};
static int last_swclk;
static int last_swdio;
static bool last_stored;
static bool swdio_input;
-static bool swdio_dir_is_active_high = true;
+
+static const struct adapter_gpio_config *adapter_gpio_config;
+
+/*
+ * Helper function to determine if gpio config is valid
+ *
+ * Assume here that there will be less than 10000 gpios per gpiochip, and less
+ * than 1000 gpiochips.
+ */
+static bool is_gpio_config_valid(enum adapter_gpio_config_index idx)
+{
+ return adapter_gpio_config[idx].chip_num >= 0
+ && adapter_gpio_config[idx].chip_num < 1000
+ && adapter_gpio_config[idx].gpio_num >= 0
+ && adapter_gpio_config[idx].gpio_num < 10000;
+}
/* Bitbang interface read of TDO */
static bb_value_t linuxgpiod_read(void)
{
int retval;
- retval = gpiod_line_get_value(gpiod_tdo);
+ retval = gpiod_line_get_value(gpiod_line[ADAPTER_GPIO_IDX_TDO]);
if (retval < 0) {
LOG_WARNING("reading tdo failed");
return 0;
@@ -107,20 +81,20 @@ static int linuxgpiod_write(int tck, int tms, int tdi)
}
if (tdi != last_tdi) {
- retval = gpiod_line_set_value(gpiod_tdi, tdi);
+ retval = gpiod_line_set_value(gpiod_line[ADAPTER_GPIO_IDX_TDI], tdi);
if (retval < 0)
LOG_WARNING("writing tdi failed");
}
if (tms != last_tms) {
- retval = gpiod_line_set_value(gpiod_tms, tms);
+ retval = gpiod_line_set_value(gpiod_line[ADAPTER_GPIO_IDX_TMS], tms);
if (retval < 0)
LOG_WARNING("writing tms failed");
}
/* write clk last */
if (tck != last_tck) {
- retval = gpiod_line_set_value(gpiod_tck, tck);
+ retval = gpiod_line_set_value(gpiod_line[ADAPTER_GPIO_IDX_TCK], tck);
if (retval < 0)
LOG_WARNING("writing tck failed");
}
@@ -136,7 +110,7 @@ static int linuxgpiod_swdio_read(void)
{
int retval;
- retval = gpiod_line_get_value(gpiod_swdio);
+ retval = gpiod_line_get_value(gpiod_line[ADAPTER_GPIO_IDX_SWDIO]);
if (retval < 0) {
LOG_WARNING("Fail read swdio");
return 0;
@@ -154,23 +128,23 @@ static void linuxgpiod_swdio_drive(bool is_output)
* https://stackoverflow.com/questions/58735140/
* this would change in future libgpiod
*/
- gpiod_line_release(gpiod_swdio);
+ gpiod_line_release(gpiod_line[ADAPTER_GPIO_IDX_SWDIO]);
if (is_output) {
- if (gpiod_swdio_dir) {
- retval = gpiod_line_set_value(gpiod_swdio_dir, swdio_dir_is_active_high ? 1 : 0);
+ if (gpiod_line[ADAPTER_GPIO_IDX_SWDIO_DIR]) {
+ retval = gpiod_line_set_value(gpiod_line[ADAPTER_GPIO_IDX_SWDIO_DIR], 1);
if (retval < 0)
LOG_WARNING("Fail set swdio_dir");
}
- retval = gpiod_line_request_output(gpiod_swdio, "OpenOCD", 1);
+ retval = gpiod_line_request_output(gpiod_line[ADAPTER_GPIO_IDX_SWDIO], "OpenOCD", 1);
if (retval < 0)
LOG_WARNING("Fail request_output line swdio");
} else {
- retval = gpiod_line_request_input(gpiod_swdio, "OpenOCD");
+ retval = gpiod_line_request_input(gpiod_line[ADAPTER_GPIO_IDX_SWDIO], "OpenOCD");
if (retval < 0)
LOG_WARNING("Fail request_input line swdio");
- if (gpiod_swdio_dir) {
- retval = gpiod_line_set_value(gpiod_swdio_dir, swdio_dir_is_active_high ? 0 : 1);
+ if (gpiod_line[ADAPTER_GPIO_IDX_SWDIO_DIR]) {
+ retval = gpiod_line_set_value(gpiod_line[ADAPTER_GPIO_IDX_SWDIO_DIR], 0);
if (retval < 0)
LOG_WARNING("Fail set swdio_dir");
}
@@ -186,7 +160,7 @@ static int linuxgpiod_swd_write(int swclk, int swdio)
if (!swdio_input) {
if (!last_stored || (swdio != last_swdio)) {
- retval = gpiod_line_set_value(gpiod_swdio, swdio);
+ retval = gpiod_line_set_value(gpiod_line[ADAPTER_GPIO_IDX_SWDIO], swdio);
if (retval < 0)
LOG_WARNING("Fail set swdio");
}
@@ -194,7 +168,7 @@ static int linuxgpiod_swd_write(int swclk, int swdio)
/* write swclk last */
if (!last_stored || (swclk != last_swclk)) {
- retval = gpiod_line_set_value(gpiod_swclk, swclk);
+ retval = gpiod_line_set_value(gpiod_line[ADAPTER_GPIO_IDX_SWCLK], swclk);
if (retval < 0)
LOG_WARNING("Fail set swclk");
}
@@ -210,10 +184,10 @@ static int linuxgpiod_blink(int on)
{
int retval;
- if (!gpiod_led)
+ if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_LED))
return ERROR_OK;
- retval = gpiod_line_set_value(gpiod_led, on);
+ retval = gpiod_line_set_value(gpiod_line[ADAPTER_GPIO_IDX_LED], on);
if (retval < 0)
LOG_WARNING("Fail set led");
return retval;
@@ -239,16 +213,18 @@ static int linuxgpiod_reset(int trst, int srst)
LOG_DEBUG("linuxgpiod_reset");
- /* assume active low */
- if (gpiod_srst) {
- retval1 = gpiod_line_set_value(gpiod_srst, srst ? 0 : 1);
+ /*
+ * active low behaviour handled by "adaptor gpio" command and
+ * GPIOD_LINE_REQUEST_FLAG_ACTIVE_LOW flag when requesting the line.
+ */
+ if (gpiod_line[ADAPTER_GPIO_IDX_SRST]) {
+ retval1 = gpiod_line_set_value(gpiod_line[ADAPTER_GPIO_IDX_SRST], srst);
if (retval1 < 0)
LOG_WARNING("set srst value failed");
}
- /* assume active low */
- if (gpiod_trst) {
- retval2 = gpiod_line_set_value(gpiod_trst, trst ? 0 : 1);
+ if (gpiod_line[ADAPTER_GPIO_IDX_TRST]) {
+ retval2 = gpiod_line_set_value(gpiod_line[ADAPTER_GPIO_IDX_TRST], trst);
if (retval2 < 0)
LOG_WARNING("set trst value failed");
}
@@ -256,109 +232,134 @@ static int linuxgpiod_reset(int trst, int srst)
return ((retval1 < 0) || (retval2 < 0)) ? ERROR_FAIL : ERROR_OK;
}
-/*
- * Helper function to determine if gpio number is valid
- *
- * Assume here that there will be less than 10000 gpios per gpiochip
- */
-static bool is_gpio_valid(int gpio)
-{
- return gpio >= 0 && gpio < 10000;
-}
-
static bool linuxgpiod_jtag_mode_possible(void)
{
- if (!is_gpio_valid(tck_gpio))
+ if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_TCK))
return false;
- if (!is_gpio_valid(tms_gpio))
+ if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_TMS))
return false;
- if (!is_gpio_valid(tdi_gpio))
+ if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_TDI))
return false;
- if (!is_gpio_valid(tdo_gpio))
+ if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_TDO))
return false;
return true;
}
static bool linuxgpiod_swd_mode_possible(void)
{
- if (!is_gpio_valid(swclk_gpio))
+ if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_SWCLK))
return false;
- if (!is_gpio_valid(swdio_gpio))
+ if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_SWDIO))
return false;
return true;
}
-static inline void helper_release(struct gpiod_line *line, struct gpiod_chip *chip)
+static inline void helper_release(enum adapter_gpio_config_index idx)
{
- if (line)
- gpiod_line_release(line);
- if (chip)
- gpiod_chip_close(chip);
+ if (gpiod_line[idx]) {
+ gpiod_line_release(gpiod_line[idx]);
+ gpiod_line[idx] = NULL;
+ }
+ if (gpiod_chip[idx]) {
+ gpiod_chip_close(gpiod_chip[idx]);
+ gpiod_chip[idx] = NULL;
+ }
}
static int linuxgpiod_quit(void)
{
- helper_release(gpiod_led, gpiod_chip_led);
- helper_release(gpiod_srst, gpiod_chip_srst);
- helper_release(gpiod_swdio, gpiod_chip_swdio);
- helper_release(gpiod_swdio_dir, gpiod_chip_swdio_dir);
- helper_release(gpiod_swclk, gpiod_chip_swclk);
- helper_release(gpiod_trst, gpiod_chip_trst);
- helper_release(gpiod_tms, gpiod_chip_tms);
- helper_release(gpiod_tck, gpiod_chip_tck);
- helper_release(gpiod_tdi, gpiod_chip_tdi);
- helper_release(gpiod_tdo, gpiod_chip_tdo);
+ LOG_DEBUG("linuxgpiod_quit");
+ for (int i = 0; i < ADAPTER_GPIO_IDX_NUM; ++i)
+ helper_release(i);
return ERROR_OK;
}
-static struct gpiod_line *helper_get_line(const char *label,
- struct gpiod_chip *gpiod_chip, unsigned int offset,
- int val, int dir, int flags)
+int helper_get_line(enum adapter_gpio_config_index idx)
{
- struct gpiod_line *line;
- int retval;
+ if (!is_gpio_config_valid(idx))
+ return ERROR_OK;
+
+ int dir = GPIOD_LINE_REQUEST_DIRECTION_INPUT, flags = 0, val = 0, retval;
+
+ gpiod_chip[idx] = gpiod_chip_open_by_number(adapter_gpio_config[idx].chip_num);
+ if (!gpiod_chip[idx]) {
+ LOG_ERROR("Cannot open LinuxGPIOD chip %d for %s", adapter_gpio_config[idx].chip_num,
+ adapter_gpio_get_name(idx));
+ return ERROR_JTAG_INIT_FAILED;
+ }
+
+ gpiod_line[idx] = gpiod_chip_get_line(gpiod_chip[idx], adapter_gpio_config[idx].gpio_num);
+ if (!gpiod_line[idx]) {
+ LOG_ERROR("Error get line %s", adapter_gpio_get_name(idx));
+ return ERROR_JTAG_INIT_FAILED;
+ }
+
+ switch (adapter_gpio_config[idx].init_state) {
+ case ADAPTER_GPIO_INIT_STATE_INPUT:
+ dir = GPIOD_LINE_REQUEST_DIRECTION_INPUT;
+ break;
+ case ADAPTER_GPIO_INIT_STATE_INACTIVE:
+ dir = GPIOD_LINE_REQUEST_DIRECTION_OUTPUT;
+ val = 0;
+ break;
+ case ADAPTER_GPIO_INIT_STATE_ACTIVE:
+ dir = GPIOD_LINE_REQUEST_DIRECTION_OUTPUT;
+ val = 1;
+ break;
+ }
+
+ switch (adapter_gpio_config[idx].drive) {
+ case ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL:
+ break;
+ case ADAPTER_GPIO_DRIVE_MODE_OPEN_DRAIN:
+ flags |= GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN;
+ break;
+ case ADAPTER_GPIO_DRIVE_MODE_OPEN_SOURCE:
+ flags |= GPIOD_LINE_REQUEST_FLAG_OPEN_SOURCE;
+ break;
+ }
- line = gpiod_chip_get_line(gpiod_chip, offset);
- if (!line) {
- LOG_ERROR("Error get line %s", label);
- return NULL;
+ switch (adapter_gpio_config[idx].pull) {
+ case ADAPTER_GPIO_PULL_NONE:
+#ifdef GPIOD_LINE_REQUEST_FLAG_BIAS_DISABLE
+ flags |= GPIOD_LINE_REQUEST_FLAG_BIAS_DISABLE;
+#endif
+ break;
+ case ADAPTER_GPIO_PULL_UP:
+#ifdef GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_UP
+ flags |= GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_UP;
+#else
+ LOG_WARNING("linuxgpiod: ignoring request for pull-up on %s: not supported by gpiod v%s",
+ adapter_gpio_get_name(idx), gpiod_version_string());
+#endif
+ break;
+ case ADAPTER_GPIO_PULL_DOWN:
+#ifdef GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_DOWN
+ flags |= GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_DOWN;
+#else
+ LOG_WARNING("linuxgpiod: ignoring request for pull-down on %s: not supported by gpiod v%s",
+ adapter_gpio_get_name(idx), gpiod_version_string());
+#endif
+ break;
}
+ if (adapter_gpio_config[idx].active_low)
+ flags |= GPIOD_LINE_REQUEST_FLAG_ACTIVE_LOW;
+
struct gpiod_line_request_config config = {
.consumer = "OpenOCD",
.request_type = dir,
.flags = flags,
};
- retval = gpiod_line_request(line, &config, val);
+ retval = gpiod_line_request(gpiod_line[idx], &config, val);
if (retval < 0) {
- LOG_ERROR("Error requesting gpio line %s", label);
- return NULL;
+ LOG_ERROR("Error requesting gpio line %s", adapter_gpio_get_name(idx));
+ return ERROR_JTAG_INIT_FAILED;
}
- return line;
-}
-
-static struct gpiod_line *helper_get_input_line(const char *label,
- struct gpiod_chip *gpiod_chip, unsigned int offset)
-{
- return helper_get_line(label, gpiod_chip, offset, 0,
- GPIOD_LINE_REQUEST_DIRECTION_INPUT, 0);
-}
-
-static struct gpiod_line *helper_get_output_line(const char *label,
- struct gpiod_chip *gpiod_chip, unsigned int offset, int val)
-{
- return helper_get_line(label, gpiod_chip, offset, val,
- GPIOD_LINE_REQUEST_DIRECTION_OUTPUT, 0);
-}
-
-static struct gpiod_line *helper_get_open_drain_output_line(const char *label,
- struct gpiod_chip *gpiod_chip, unsigned int offset, int val)
-{
- return helper_get_line(label, gpiod_chip, offset, val,
- GPIOD_LINE_REQUEST_DIRECTION_OUTPUT, GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN);
+ return ERROR_OK;
}
static int linuxgpiod_init(void)
@@ -366,11 +367,11 @@ static int linuxgpiod_init(void)
LOG_INFO("Linux GPIOD JTAG/SWD bitbang driver");
bitbang_interface = &linuxgpiod_bitbang;
+ adapter_gpio_config = adapter_gpio_get_config();
/*
- * 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.
+ * Configure JTAG/SWD signals. Default directions and initial states are handled
+ * by adapter.c and "adapter gpio" command.
*/
if (transport_is_jtag()) {
@@ -379,129 +380,44 @@ static int linuxgpiod_init(void)
goto out_error;
}
- gpiod_chip_tdo = gpiod_chip_open_by_number(tdo_gpiochip);
- if (!gpiod_chip_tdo) {
- LOG_ERROR("Cannot open LinuxGPIOD tdo_gpiochip %d", tdo_gpiochip);
- goto out_error;
- }
- gpiod_chip_tdi = gpiod_chip_open_by_number(tdi_gpiochip);
- if (!gpiod_chip_tdi) {
- LOG_ERROR("Cannot open LinuxGPIOD tdi_gpiochip %d", tdi_gpiochip);
- goto out_error;
- }
- gpiod_chip_tck = gpiod_chip_open_by_number(tck_gpiochip);
- if (!gpiod_chip_tck) {
- LOG_ERROR("Cannot open LinuxGPIOD tck_gpiochip %d", tck_gpiochip);
- goto out_error;
- }
- gpiod_chip_tms = gpiod_chip_open_by_number(tms_gpiochip);
- if (!gpiod_chip_tms) {
- LOG_ERROR("Cannot open LinuxGPIOD tms_gpiochip %d", tms_gpiochip);
- goto out_error;
- }
-
- gpiod_tdo = helper_get_input_line("tdo", gpiod_chip_tdo, tdo_gpio);
- if (!gpiod_tdo)
- goto out_error;
-
- gpiod_tdi = helper_get_output_line("tdi", gpiod_chip_tdi, tdi_gpio, 0);
- if (!gpiod_tdi)
- goto out_error;
-
- gpiod_tck = helper_get_output_line("tck", gpiod_chip_tck, tck_gpio, 0);
- if (!gpiod_tck)
- goto out_error;
-
- gpiod_tms = helper_get_output_line("tms", gpiod_chip_tms, tms_gpio, 1);
- if (!gpiod_tms)
- goto out_error;
-
- if (is_gpio_valid(trst_gpio)) {
- gpiod_chip_trst = gpiod_chip_open_by_number(trst_gpiochip);
- if (!gpiod_chip_trst) {
- LOG_ERROR("Cannot open LinuxGPIOD trst_gpiochip %d", trst_gpiochip);
+ if (helper_get_line(ADAPTER_GPIO_IDX_TDO) != ERROR_OK ||
+ helper_get_line(ADAPTER_GPIO_IDX_TDI) != ERROR_OK ||
+ helper_get_line(ADAPTER_GPIO_IDX_TCK) != ERROR_OK ||
+ helper_get_line(ADAPTER_GPIO_IDX_TMS) != ERROR_OK ||
+ helper_get_line(ADAPTER_GPIO_IDX_TRST) != ERROR_OK)
goto out_error;
- }
-
- if (jtag_get_reset_config() & RESET_TRST_OPEN_DRAIN)
- gpiod_trst = helper_get_open_drain_output_line("trst", gpiod_chip_trst, trst_gpio, 1);
- else
- gpiod_trst = helper_get_output_line("trst", gpiod_chip_trst, trst_gpio, 1);
-
- if (!gpiod_trst)
- goto out_error;
- }
}
if (transport_is_swd()) {
+ int retval1, retval2;
if (!linuxgpiod_swd_mode_possible()) {
LOG_ERROR("Require swclk and swdio gpio for SWD mode");
goto out_error;
}
- gpiod_chip_swclk = gpiod_chip_open_by_number(swclk_gpiochip);
- if (!gpiod_chip_swclk) {
- LOG_ERROR("Cannot open LinuxGPIOD swclk_gpiochip %d", swclk_gpiochip);
- goto out_error;
+ /*
+ * swdio and its buffer should be initialized in the order that prevents
+ * two outputs from being connected together. This will occur if the
+ * swdio GPIO is configured as an output while the external buffer is
+ * configured to send the swdio signal from the target to the GPIO.
+ */
+ if (adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].init_state == ADAPTER_GPIO_INIT_STATE_INPUT) {
+ retval1 = helper_get_line(ADAPTER_GPIO_IDX_SWDIO);
+ retval2 = helper_get_line(ADAPTER_GPIO_IDX_SWDIO_DIR);
+ } else {
+ retval1 = helper_get_line(ADAPTER_GPIO_IDX_SWDIO_DIR);
+ retval2 = helper_get_line(ADAPTER_GPIO_IDX_SWDIO);
}
- gpiod_chip_swdio = gpiod_chip_open_by_number(swdio_gpiochip);
- if (!gpiod_chip_swdio) {
- LOG_ERROR("Cannot open LinuxGPIOD swdio_gpiochip %d", swdio_gpiochip);
+ if (retval1 != ERROR_OK || retval2 != ERROR_OK)
goto out_error;
- }
-
- if (is_gpio_valid(swdio_dir_gpio)) {
- gpiod_chip_swdio_dir = gpiod_chip_open_by_number(swdio_dir_gpiochip);
- if (!gpiod_chip_swdio_dir) {
- LOG_ERROR("Cannot open LinuxGPIOD swdio_dir_gpiochip %d", swdio_dir_gpiochip);
- goto out_error;
- }
- }
- gpiod_swclk = helper_get_output_line("swclk", gpiod_chip_swclk, swclk_gpio, 1);
- if (!gpiod_swclk)
- goto out_error;
-
- /* Set buffer direction before making SWDIO an output */
- if (is_gpio_valid(swdio_dir_gpio)) {
- gpiod_swdio_dir = helper_get_output_line("swdio_dir", gpiod_chip_swdio_dir, swdio_dir_gpio,
- swdio_dir_is_active_high ? 1 : 0);
- if (!gpiod_swdio_dir)
- goto out_error;
- }
-
- gpiod_swdio = helper_get_output_line("swdio", gpiod_chip_swdio, swdio_gpio, 1);
- if (!gpiod_swdio)
+ if (helper_get_line(ADAPTER_GPIO_IDX_SWCLK) != ERROR_OK)
goto out_error;
}
- if (is_gpio_valid(srst_gpio)) {
- gpiod_chip_srst = gpiod_chip_open_by_number(srst_gpiochip);
- if (!gpiod_chip_srst) {
- LOG_ERROR("Cannot open LinuxGPIOD srst_gpiochip %d", srst_gpiochip);
- goto out_error;
- }
-
- if (jtag_get_reset_config() & RESET_SRST_PUSH_PULL)
- gpiod_srst = helper_get_output_line("srst", gpiod_chip_srst, srst_gpio, 1);
- else
- gpiod_srst = helper_get_open_drain_output_line("srst", gpiod_chip_srst, srst_gpio, 1);
-
- if (!gpiod_srst)
- goto out_error;
- }
-
- if (is_gpio_valid(led_gpio)) {
- gpiod_chip_led = gpiod_chip_open_by_number(led_gpiochip);
- if (!gpiod_chip_led) {
- LOG_ERROR("Cannot open LinuxGPIOD led_gpiochip %d", led_gpiochip);
- goto out_error;
- }
-
- gpiod_led = helper_get_output_line("led", gpiod_chip_led, led_gpio, 0);
- if (!gpiod_led)
+ if (helper_get_line(ADAPTER_GPIO_IDX_SRST) != ERROR_OK ||
+ helper_get_line(ADAPTER_GPIO_IDX_LED) != ERROR_OK)
goto out_error;
- }
return ERROR_OK;
@@ -511,241 +427,6 @@ out_error:
return ERROR_JTAG_INIT_FAILED;
}
-COMMAND_HELPER(linuxgpiod_helper_gpionum, const char *name, int *chip, int *line)
-{
- int i = 0;
- if (CMD_ARGC > 2)
- return ERROR_COMMAND_SYNTAX_ERROR;
- if (CMD_ARGC == 2) {
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], *chip);
- i = 1;
- }
- if (CMD_ARGC > 0)
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[i], *line);
- command_print(CMD, "LinuxGPIOD %s: chip = %d, num = %d", name, *chip, *line);
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(linuxgpiod_handle_jtag_gpionums)
-{
- if (CMD_ARGC == 4) {
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tck_gpio);
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], tms_gpio);
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[2], tdi_gpio);
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[3], tdo_gpio);
- } else if (CMD_ARGC != 0) {
- return ERROR_COMMAND_SYNTAX_ERROR;
- }
-
- command_print(CMD,
- "LinuxGPIOD nums: tck = %d, tms = %d, tdi = %d, tdo = %d",
- tck_gpio, tms_gpio, tdi_gpio, tdo_gpio);
-
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(linuxgpiod_handle_jtag_gpionum_tck)
-{
- return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "tck", &tck_gpiochip,
- &tck_gpio);
-}
-
-COMMAND_HANDLER(linuxgpiod_handle_jtag_gpionum_tms)
-{
- return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "tms", &tms_gpiochip,
- &tms_gpio);
-}
-
-COMMAND_HANDLER(linuxgpiod_handle_jtag_gpionum_tdo)
-{
- return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "tdo", &tdo_gpiochip,
- &tdo_gpio);
-}
-
-COMMAND_HANDLER(linuxgpiod_handle_jtag_gpionum_tdi)
-{
- return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "tdi", &tdi_gpiochip,
- &tdi_gpio);
-}
-
-COMMAND_HANDLER(linuxgpiod_handle_jtag_gpionum_srst)
-{
- return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "srst", &srst_gpiochip,
- &srst_gpio);
-}
-
-COMMAND_HANDLER(linuxgpiod_handle_jtag_gpionum_trst)
-{
- return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "trst", &trst_gpiochip,
- &trst_gpio);
-}
-
-COMMAND_HANDLER(linuxgpiod_handle_swd_gpionums)
-{
- if (CMD_ARGC == 2) {
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swclk_gpio);
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], swdio_gpio);
- } else if (CMD_ARGC != 0) {
- return ERROR_COMMAND_SYNTAX_ERROR;
- }
-
- command_print(CMD,
- "LinuxGPIOD nums: swclk = %d, swdio = %d",
- swclk_gpio, swdio_gpio);
-
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(linuxgpiod_handle_swd_gpionum_swclk)
-{
- return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "swclk", &swclk_gpiochip,
- &swclk_gpio);
-}
-
-COMMAND_HANDLER(linuxgpiod_handle_swd_gpionum_swdio)
-{
- return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "swdio", &swdio_gpiochip,
- &swdio_gpio);
-}
-
-COMMAND_HANDLER(linuxgpiod_handle_swd_gpionum_swdio_dir)
-{
- return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "swdio_dir", &swdio_dir_gpiochip,
- &swdio_dir_gpio);
-}
-
-COMMAND_HANDLER(linuxgpiod_handle_gpionum_led)
-{
- return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "led", &led_gpiochip,
- &led_gpio);
-}
-
-COMMAND_HANDLER(linuxgpiod_handle_gpiochip)
-{
- if (CMD_ARGC == 1) {
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], gpiochip);
- tck_gpiochip = gpiochip;
- tms_gpiochip = gpiochip;
- tdi_gpiochip = gpiochip;
- tdo_gpiochip = gpiochip;
- trst_gpiochip = gpiochip;
- srst_gpiochip = gpiochip;
- swclk_gpiochip = gpiochip;
- swdio_gpiochip = gpiochip;
- swdio_dir_gpiochip = gpiochip;
- led_gpiochip = gpiochip;
- }
-
- command_print(CMD, "LinuxGPIOD gpiochip = %d", gpiochip);
- return ERROR_OK;
-}
-
-static const struct command_registration linuxgpiod_subcommand_handlers[] = {
- {
- .name = "jtag_nums",
- .handler = linuxgpiod_handle_jtag_gpionums,
- .mode = COMMAND_CONFIG,
- .help = "gpio numbers for tck, tms, tdi, tdo. (in that order)",
- .usage = "tck tms tdi tdo",
- },
- {
- .name = "tck_num",
- .handler = linuxgpiod_handle_jtag_gpionum_tck,
- .mode = COMMAND_CONFIG,
- .help = "gpio chip number (optional) and gpio number for tck.",
- .usage = "[chip] tck",
- },
- {
- .name = "tms_num",
- .handler = linuxgpiod_handle_jtag_gpionum_tms,
- .mode = COMMAND_CONFIG,
- .help = "gpio chip number (optional) and gpio number for tms.",
- .usage = "[chip] tms",
- },
- {
- .name = "tdo_num",
- .handler = linuxgpiod_handle_jtag_gpionum_tdo,
- .mode = COMMAND_CONFIG,
- .help = "gpio chip number (optional) and gpio number for tdo.",
- .usage = "[chip] tdo",
- },
- {
- .name = "tdi_num",
- .handler = linuxgpiod_handle_jtag_gpionum_tdi,
- .mode = COMMAND_CONFIG,
- .help = "gpio chip number (optional) and gpio number for tdi.",
- .usage = "[chip] tdi",
- },
- {
- .name = "srst_num",
- .handler = linuxgpiod_handle_jtag_gpionum_srst,
- .mode = COMMAND_CONFIG,
- .help = "gpio chip number (optional) and gpio number for srst.",
- .usage = "[chip] srst",
- },
- {
- .name = "trst_num",
- .handler = linuxgpiod_handle_jtag_gpionum_trst,
- .mode = COMMAND_CONFIG,
- .help = "gpio chip number (optional) and gpio number for trst.",
- .usage = "[chip] trst",
- },
- {
- .name = "swd_nums",
- .handler = linuxgpiod_handle_swd_gpionums,
- .mode = COMMAND_CONFIG,
- .help = "gpio numbers for swclk, swdio. (in that order)",
- .usage = "swclk swdio",
- },
- {
- .name = "swclk_num",
- .handler = linuxgpiod_handle_swd_gpionum_swclk,
- .mode = COMMAND_CONFIG,
- .help = "gpio chip number (optional) and gpio number for swclk.",
- .usage = "[chip] swclk",
- },
- {
- .name = "swdio_num",
- .handler = linuxgpiod_handle_swd_gpionum_swdio,
- .mode = COMMAND_CONFIG,
- .help = "gpio chip number (optional) and gpio number for swdio.",
- .usage = "[chip] swdio",
- },
- {
- .name = "swdio_dir_num",
- .handler = linuxgpiod_handle_swd_gpionum_swdio_dir,
- .mode = COMMAND_CONFIG,
- .help = "gpio chip number (optional) and gpio number for swdio_dir.",
- .usage = "[chip] swdio_dir",
- },
- {
- .name = "led_num",
- .handler = linuxgpiod_handle_gpionum_led,
- .mode = COMMAND_CONFIG,
- .help = "gpio chip number (optional) and gpio number for LED.",
- .usage = "[chip] led",
- },
- {
- .name = "gpiochip",
- .handler = linuxgpiod_handle_gpiochip,
- .mode = COMMAND_CONFIG,
- .help = "number of the gpiochip.",
- .usage = "gpiochip",
- },
- COMMAND_REGISTRATION_DONE
-};
-
-static const struct command_registration linuxgpiod_command_handlers[] = {
- {
- .name = "linuxgpiod",
- .mode = COMMAND_ANY,
- .help = "perform linuxgpiod management",
- .chain = linuxgpiod_subcommand_handlers,
- .usage = "",
- },
- COMMAND_REGISTRATION_DONE
-};
-
static const char *const linuxgpiod_transport[] = { "swd", "jtag", NULL };
static struct jtag_interface linuxgpiod_interface = {
@@ -756,7 +437,6 @@ static struct jtag_interface linuxgpiod_interface = {
struct adapter_driver linuxgpiod_adapter_driver = {
.name = "linuxgpiod",
.transports = linuxgpiod_transport,
- .commands = linuxgpiod_command_handlers,
.init = linuxgpiod_init,
.quit = linuxgpiod_quit,
diff --git a/src/jtag/startup.tcl b/src/jtag/startup.tcl
index a72775e..1a638a3 100644
--- a/src/jtag/startup.tcl
+++ b/src/jtag/startup.tcl
@@ -535,74 +535,72 @@ proc bcm2835gpio_peripheral_base args {
lappend _telnet_autocomplete_skip linuxgpiod_jtag_nums
proc linuxgpiod_jtag_nums args {
- echo "DEPRECATED! use 'linuxgpiod jtag_nums' not 'linuxgpiod_jtag_nums'"
- eval linuxgpiod jtag_nums $args
+ eval adapter_gpio_jtag_nums $args
}
lappend _telnet_autocomplete_skip linuxgpiod_tck_num
proc linuxgpiod_tck_num args {
- echo "DEPRECATED! use 'linuxgpiod tck_num' not 'linuxgpiod_tck_num'"
- eval linuxgpiod tck_num $args
+ eval adapter_gpio_helper tck $args
}
lappend _telnet_autocomplete_skip linuxgpiod_tms_num
proc linuxgpiod_tms_num args {
- echo "DEPRECATED! use 'linuxgpiod tms_num' not 'linuxgpiod_tms_num'"
- eval linuxgpiod tms_num $args
+ eval adapter_gpio_helper tms $args
}
lappend _telnet_autocomplete_skip linuxgpiod_tdo_num
proc linuxgpiod_tdo_num args {
- echo "DEPRECATED! use 'linuxgpiod tdo_num' not 'linuxgpiod_tdo_num'"
- eval linuxgpiod tdo_num $args
+ eval adapter_gpio_helper tdo $args
}
lappend _telnet_autocomplete_skip linuxgpiod_tdi_num
proc linuxgpiod_tdi_num args {
- echo "DEPRECATED! use 'linuxgpiod tdi_num' not 'linuxgpiod_tdi_num'"
- eval linuxgpiod tdi_num $args
+ eval adapter_gpio_helper tdi $args
}
lappend _telnet_autocomplete_skip linuxgpiod_srst_num
proc linuxgpiod_srst_num args {
- echo "DEPRECATED! use 'linuxgpiod srst_num' not 'linuxgpiod_srst_num'"
- eval linuxgpiod srst_num $args
+ eval adapter_gpio_helper srst $args
}
lappend _telnet_autocomplete_skip linuxgpiod_trst_num
proc linuxgpiod_trst_num args {
- echo "DEPRECATED! use 'linuxgpiod trst_num' not 'linuxgpiod_trst_num'"
- eval linuxgpiod trst_num $args
+ eval adapter_gpio_helper trst $args
}
lappend _telnet_autocomplete_skip linuxgpiod_swd_nums
proc linuxgpiod_swd_nums args {
- echo "DEPRECATED! use 'linuxgpiod swd_nums' not 'linuxgpiod_swd_nums'"
- eval linuxgpiod swd_nums $args
+ eval adapter_gpio_swd_nums $args
}
lappend _telnet_autocomplete_skip linuxgpiod_swclk_num
proc linuxgpiod_swclk_num args {
- echo "DEPRECATED! use 'linuxgpiod swclk_num' not 'linuxgpiod_swclk_num'"
- eval linuxgpiod swclk_num $args
+ eval adapter_gpio_helper swclk $args
}
lappend _telnet_autocomplete_skip linuxgpiod_swdio_num
proc linuxgpiod_swdio_num args {
- echo "DEPRECATED! use 'linuxgpiod swdio_num' not 'linuxgpiod_swdio_num'"
- eval linuxgpiod swdio_num $args
+ eval adapter_gpio_helper swdio $args
}
lappend _telnet_autocomplete_skip linuxgpiod_led_num
proc linuxgpiod_led_num args {
- echo "DEPRECATED! use 'linuxgpiod led_num' not 'linuxgpiod_led_num'"
- eval linuxgpiod led_num $args
+ eval adapter_gpio_helper led $args
}
lappend _telnet_autocomplete_skip linuxgpiod_gpiochip
proc linuxgpiod_gpiochip args {
- echo "DEPRECATED! use 'linuxgpiod gpiochip' not 'linuxgpiod_gpiochip'"
- eval linuxgpiod gpiochip $args
+ echo "DEPRECATED! use 'adapter <signal_name> -chip' not 'linuxgpiod_gpiochip'"
+ switch [llength $args] {
+ 0 { }
+ 1 {
+ foreach sig_name {tck tms tdi tdo trst srst swclk swdio swdio_dir led} {
+ eval adapter gpio $sig_name -chip $args
+ }
+ }
+ default {return -code 1 -level 1 "linuxgpiod_gpiochip: syntax error"}
+ }
+ eval adapter gpio
}
lappend _telnet_autocomplete_skip sysfsgpio_jtag_nums
@@ -863,6 +861,87 @@ proc "xds110 serial" {args} {
eval adapter serial $args
}
+lappend _telnet_autocomplete_skip linuxgpiod
+# linuxgpiod command completely removed, this is required for the sub-commands to work
+proc linuxgpiod {subcommand args} {
+ eval {"linuxgpiod $subcommand"} $args
+}
+
+lappend _telnet_autocomplete_skip "linuxgpiod tck_num"
+proc "linuxgpiod tck_num" {args} {
+ eval adapter_gpio_helper tck $args
+}
+
+lappend _telnet_autocomplete_skip "linuxgpiod tms_num"
+proc "linuxgpiod tms_num" {args} {
+ eval adapter_gpio_helper tms $args
+}
+
+lappend _telnet_autocomplete_skip "linuxgpiod tdi_num"
+proc "linuxgpiod tdi_num" {args} {
+ eval adapter_gpio_helper tdi $args
+}
+
+lappend _telnet_autocomplete_skip "linuxgpiod tdo_num"
+proc "linuxgpiod tdo_num" {args} {
+ eval adapter_gpio_helper tdo $args
+}
+
+lappend _telnet_autocomplete_skip "linuxgpiod trst_num"
+proc "linuxgpiod trst_num" {args} {
+ eval adapter_gpio_helper trst $args
+}
+
+lappend _telnet_autocomplete_skip "linuxgpiod srst_num"
+proc "linuxgpiod srst_num" {args} {
+ eval adapter_gpio_helper srst $args
+}
+
+lappend _telnet_autocomplete_skip "linuxgpiod swclk_num"
+proc "linuxgpiod swclk_num" {args} {
+ eval adapter_gpio_helper swclk $args
+}
+
+lappend _telnet_autocomplete_skip "linuxgpiod swdio_num"
+proc "linuxgpiod swdio_num" {args} {
+ eval adapter_gpio_helper swdio $args
+}
+
+lappend _telnet_autocomplete_skip "linuxgpiod swdio_dir_num"
+proc "linuxgpiod swdio_dir_num" {args} {
+ eval adapter_gpio_helper swdio_dir $args
+}
+
+lappend _telnet_autocomplete_skip "linuxgpiod led_num"
+proc "linuxgpiod led_num" {args} {
+ eval adapter_gpio_helper led $args
+}
+
+lappend _telnet_autocomplete_skip "linuxgpiod gpiochip"
+proc "linuxgpiod gpiochip" {num} {
+ echo "DEPRECATED! use 'adapter <signal_name> -chip' not 'linuxgpiod gpiochip'"
+ foreach sig_name {tck tms tdi tdo trst srst swclk swdio swdio_dir led} {
+ eval adapter gpio $sig_name -chip $num
+ }
+ eval adapter gpio
+}
+
+lappend _telnet_autocomplete_skip "linuxgpiod jtag_nums"
+proc "linuxgpiod jtag_nums" {tck_num tms_num tdi_num tdo_num} {
+ echo "DEPRECATED! use 'adapter gpio tck; adapter gpio tms; adapter gpio tdi; adapter gpio tdo' not 'linuxgpiod jtag_nums'"
+ eval adapter gpio tck $tck_num
+ eval adapter gpio tms $tms_num
+ eval adapter gpio tdi $tdi_num
+ eval adapter gpio tdo $tdo_num
+}
+
+lappend _telnet_autocomplete_skip "linuxgpiod swd_nums"
+proc "linuxgpiod swd_nums" {swclk swdio} {
+ echo "DEPRECATED! use 'adapter gpio swclk; adapter gpio swdio' not 'linuxgpiod jtag_nums'"
+ eval adapter gpio swclk $swclk
+ eval adapter gpio swdio $swdio
+}
+
lappend _telnet_autocomplete_skip "am335xgpio jtag_nums"
proc "am335xgpio jtag_nums" {tck_num tms_num tdi_num tdo_num} {
echo "DEPRECATED! use 'adapter gpio tck; adapter gpio tms; adapter gpio tdi; adapter gpio tdo' not 'am335xgpio jtag_nums'"