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>
This commit is contained in:
Steve Marple 2022-06-21 23:06:25 +01:00 committed by Antonio Borneo
parent 903f2e92a1
commit 290eac04b9
5 changed files with 382 additions and 588 deletions

View File

@ -3401,87 +3401,14 @@ See @file{interface/beaglebone-swd-native.cfg} for a sample configuration file.
@deffn {Interface Driver} {linuxgpiod} @deffn {Interface Driver} {linuxgpiod}
Linux provides userspace access to GPIO through libgpiod since Linux kernel version v4.6. Linux provides userspace access to GPIO through libgpiod since Linux kernel
The driver emulates either JTAG or SWD transport through bitbanging. version v4.6. The driver emulates either JTAG or SWD transport through
bitbanging. There are no driver-specific commands, all GPIO configuration is
See @file{interface/dln-2-gpiod.cfg} for a sample config. handled by the generic command @ref{adapter gpio, @command{adapter gpio}}. This
driver supports the resistor pull options provided by the @command{adapter gpio}
@deffn {Config Command} {linuxgpiod gpiochip} @var{chip} command but the underlying hardware may not be able to support them.
Set the GPIO chip number for all GPIOs used by linuxgpiod. If GPIOs use
different GPIO chips then the individual GPIO configuration commands (i.e., not
@command{linuxgpiod jtag_nums} or @command{linuxgpiod swd_nums}) can be used to
set chip numbers independently for each GPIO.
@end deffn
@deffn {Config Command} {linuxgpiod jtag_nums} @var{tck} @var{tms} @var{tdi} @var{tdo}
Set JTAG transport GPIO numbers for TCK, TMS, TDI, and TDO (in that order). Must
be specified to enable JTAG transport. These pins can also be specified
individually.
@end deffn
@deffn {Config Command} {linuxgpiod tck_num} [@var{chip}] @var{tck}
Set TCK GPIO number, and optionally TCK chip number. Must be specified to enable
JTAG transport. Can also be specified using the configuration command
@command{linuxgpiod jtag_nums}.
@end deffn
@deffn {Config Command} {linuxgpiod tms_num} [@var{chip}] @var{tms}
Set TMS GPIO number, and optionally TMS chip number. Must be specified to enable
JTAG transport. Can also be specified using the configuration command
@command{linuxgpiod jtag_nums}.
@end deffn
@deffn {Config Command} {linuxgpiod tdo_num} [@var{chip}] @var{tdo}
Set TDO GPIO number, and optionally TDO chip number. Must be specified to enable
JTAG transport. Can also be specified using the configuration command
@command{linuxgpiod jtag_nums}.
@end deffn
@deffn {Config Command} {linuxgpiod tdi_num} [@var{chip}] @var{tdi}
Set TDI GPIO number, and optionally TDI chip number. Must be specified to enable
JTAG transport. Can also be specified using the configuration command
@command{linuxgpiod jtag_nums}.
@end deffn
@deffn {Config Command} {linuxgpiod trst_num} [@var{chip}] @var{trst}
Set TRST GPIO number, and optionally TRST chip number. Must be specified to
enable TRST.
@end deffn
@deffn {Config Command} {linuxgpiod swd_nums} @var{swclk} @var{swdio}
Set SWD transport GPIO numbers for SWCLK and SWDIO (in that order). Must be
specified to enable SWD transport. These pins can also be specified
individually.
@end deffn
@deffn {Config Command} {linuxgpiod swclk_num} [@var{chip}] @var{swclk}
Set SWCLK GPIO number, and optionally SWCLK chip number. Must be specified to
enable SWD transport. Can also be specified using the configuration command
@command{linuxgpiod swd_nums}.
@end deffn
@deffn {Config Command} {linuxgpiod swdio_num} [@var{chip}] @var{swdio}
Set SWDIO GPIO number, and optionally SWDIO chip number. Must be specified to
enable SWD transport. Can also be specified using the configuration command
@command{linuxgpiod swd_nums}.
@end deffn
@deffn {Config Command} {linuxgpiod swdio_dir_num} [@var{chip}] @var{swdio_dir}
Set SWDIO direction control GPIO number, and optionally SWDIO direction control
chip number. If specified, this GPIO can be used to control the direction of an
external buffer connected to the SWDIO GPIO (set=output mode, clear=input mode).
@end deffn
@deffn {Config Command} {linuxgpiod srst_num} [@var{chip}] @var{srst}
Set SRST GPIO number, and optionally SRST chip number. Must be specified to
enable SRST.
@end deffn
@deffn {Config Command} {linuxgpiod led_num} [@var{chip}] @var{led}
Set activity LED GPIO number, and optionally activity LED chip number. If not
specified an activity LED is not enabled.
@end deffn
See @file{interface/dln-2-gpiod.cfg} for a sample configuration file.
@end deffn @end deffn

View File

@ -14,67 +14,41 @@
#endif #endif
#include <gpiod.h> #include <gpiod.h>
#include <jtag/adapter.h>
#include <jtag/interface.h> #include <jtag/interface.h>
#include <transport/transport.h> #include <transport/transport.h>
#include "bitbang.h" #include "bitbang.h"
/* gpio numbers for each gpio. Negative values are invalid */ static struct gpiod_chip *gpiod_chip[ADAPTER_GPIO_IDX_NUM] = {};
static int tck_gpio = -1; static struct gpiod_line *gpiod_line[ADAPTER_GPIO_IDX_NUM] = {};
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 int last_swclk; static int last_swclk;
static int last_swdio; static int last_swdio;
static bool last_stored; static bool last_stored;
static bool swdio_input; 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 */ /* Bitbang interface read of TDO */
static bb_value_t linuxgpiod_read(void) static bb_value_t linuxgpiod_read(void)
{ {
int retval; int retval;
retval = gpiod_line_get_value(gpiod_tdo); retval = gpiod_line_get_value(gpiod_line[ADAPTER_GPIO_IDX_TDO]);
if (retval < 0) { if (retval < 0) {
LOG_WARNING("reading tdo failed"); LOG_WARNING("reading tdo failed");
return 0; return 0;
@ -107,20 +81,20 @@ static int linuxgpiod_write(int tck, int tms, int tdi)
} }
if (tdi != last_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) if (retval < 0)
LOG_WARNING("writing tdi failed"); LOG_WARNING("writing tdi failed");
} }
if (tms != last_tms) { 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) if (retval < 0)
LOG_WARNING("writing tms failed"); LOG_WARNING("writing tms failed");
} }
/* write clk last */ /* write clk last */
if (tck != last_tck) { 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) if (retval < 0)
LOG_WARNING("writing tck failed"); LOG_WARNING("writing tck failed");
} }
@ -136,7 +110,7 @@ static int linuxgpiod_swdio_read(void)
{ {
int retval; int retval;
retval = gpiod_line_get_value(gpiod_swdio); retval = gpiod_line_get_value(gpiod_line[ADAPTER_GPIO_IDX_SWDIO]);
if (retval < 0) { if (retval < 0) {
LOG_WARNING("Fail read swdio"); LOG_WARNING("Fail read swdio");
return 0; return 0;
@ -154,23 +128,23 @@ static void linuxgpiod_swdio_drive(bool is_output)
* https://stackoverflow.com/questions/58735140/ * https://stackoverflow.com/questions/58735140/
* this would change in future libgpiod * this would change in future libgpiod
*/ */
gpiod_line_release(gpiod_swdio); gpiod_line_release(gpiod_line[ADAPTER_GPIO_IDX_SWDIO]);
if (is_output) { if (is_output) {
if (gpiod_swdio_dir) { if (gpiod_line[ADAPTER_GPIO_IDX_SWDIO_DIR]) {
retval = gpiod_line_set_value(gpiod_swdio_dir, swdio_dir_is_active_high ? 1 : 0); retval = gpiod_line_set_value(gpiod_line[ADAPTER_GPIO_IDX_SWDIO_DIR], 1);
if (retval < 0) if (retval < 0)
LOG_WARNING("Fail set swdio_dir"); 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) if (retval < 0)
LOG_WARNING("Fail request_output line swdio"); LOG_WARNING("Fail request_output line swdio");
} else { } else {
retval = gpiod_line_request_input(gpiod_swdio, "OpenOCD"); retval = gpiod_line_request_input(gpiod_line[ADAPTER_GPIO_IDX_SWDIO], "OpenOCD");
if (retval < 0) if (retval < 0)
LOG_WARNING("Fail request_input line swdio"); LOG_WARNING("Fail request_input line swdio");
if (gpiod_swdio_dir) { if (gpiod_line[ADAPTER_GPIO_IDX_SWDIO_DIR]) {
retval = gpiod_line_set_value(gpiod_swdio_dir, swdio_dir_is_active_high ? 0 : 1); retval = gpiod_line_set_value(gpiod_line[ADAPTER_GPIO_IDX_SWDIO_DIR], 0);
if (retval < 0) if (retval < 0)
LOG_WARNING("Fail set swdio_dir"); LOG_WARNING("Fail set swdio_dir");
} }
@ -186,7 +160,7 @@ static int linuxgpiod_swd_write(int swclk, int swdio)
if (!swdio_input) { if (!swdio_input) {
if (!last_stored || (swdio != last_swdio)) { 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) if (retval < 0)
LOG_WARNING("Fail set swdio"); LOG_WARNING("Fail set swdio");
} }
@ -194,7 +168,7 @@ static int linuxgpiod_swd_write(int swclk, int swdio)
/* write swclk last */ /* write swclk last */
if (!last_stored || (swclk != last_swclk)) { 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) if (retval < 0)
LOG_WARNING("Fail set swclk"); LOG_WARNING("Fail set swclk");
} }
@ -210,10 +184,10 @@ static int linuxgpiod_blink(int on)
{ {
int retval; int retval;
if (!gpiod_led) if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_LED))
return ERROR_OK; 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) if (retval < 0)
LOG_WARNING("Fail set led"); LOG_WARNING("Fail set led");
return retval; return retval;
@ -239,16 +213,18 @@ static int linuxgpiod_reset(int trst, int srst)
LOG_DEBUG("linuxgpiod_reset"); LOG_DEBUG("linuxgpiod_reset");
/* assume active low */ /*
if (gpiod_srst) { * active low behaviour handled by "adaptor gpio" command and
retval1 = gpiod_line_set_value(gpiod_srst, srst ? 0 : 1); * 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) if (retval1 < 0)
LOG_WARNING("set srst value failed"); LOG_WARNING("set srst value failed");
} }
/* assume active low */ if (gpiod_line[ADAPTER_GPIO_IDX_TRST]) {
if (gpiod_trst) { retval2 = gpiod_line_set_value(gpiod_line[ADAPTER_GPIO_IDX_TRST], trst);
retval2 = gpiod_line_set_value(gpiod_trst, trst ? 0 : 1);
if (retval2 < 0) if (retval2 < 0)
LOG_WARNING("set trst value failed"); 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; 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) static bool linuxgpiod_jtag_mode_possible(void)
{ {
if (!is_gpio_valid(tck_gpio)) if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_TCK))
return false; return false;
if (!is_gpio_valid(tms_gpio)) if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_TMS))
return false; return false;
if (!is_gpio_valid(tdi_gpio)) if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_TDI))
return false; return false;
if (!is_gpio_valid(tdo_gpio)) if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_TDO))
return false; return false;
return true; return true;
} }
static bool linuxgpiod_swd_mode_possible(void) static bool linuxgpiod_swd_mode_possible(void)
{ {
if (!is_gpio_valid(swclk_gpio)) if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_SWCLK))
return false; return false;
if (!is_gpio_valid(swdio_gpio)) if (!is_gpio_config_valid(ADAPTER_GPIO_IDX_SWDIO))
return false; return false;
return true; 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) if (gpiod_line[idx]) {
gpiod_line_release(line); gpiod_line_release(gpiod_line[idx]);
if (chip) gpiod_line[idx] = NULL;
gpiod_chip_close(chip); }
if (gpiod_chip[idx]) {
gpiod_chip_close(gpiod_chip[idx]);
gpiod_chip[idx] = NULL;
}
} }
static int linuxgpiod_quit(void) static int linuxgpiod_quit(void)
{ {
helper_release(gpiod_led, gpiod_chip_led); LOG_DEBUG("linuxgpiod_quit");
helper_release(gpiod_srst, gpiod_chip_srst); for (int i = 0; i < ADAPTER_GPIO_IDX_NUM; ++i)
helper_release(gpiod_swdio, gpiod_chip_swdio); helper_release(i);
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);
return ERROR_OK; return ERROR_OK;
} }
static struct gpiod_line *helper_get_line(const char *label, int helper_get_line(enum adapter_gpio_config_index idx)
struct gpiod_chip *gpiod_chip, unsigned int offset,
int val, int dir, int flags)
{ {
struct gpiod_line *line; if (!is_gpio_config_valid(idx))
int retval; return ERROR_OK;
line = gpiod_chip_get_line(gpiod_chip, offset); int dir = GPIOD_LINE_REQUEST_DIRECTION_INPUT, flags = 0, val = 0, retval;
if (!line) {
LOG_ERROR("Error get line %s", label); gpiod_chip[idx] = gpiod_chip_open_by_number(adapter_gpio_config[idx].chip_num);
return NULL; 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;
}
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 = { struct gpiod_line_request_config config = {
.consumer = "OpenOCD", .consumer = "OpenOCD",
.request_type = dir, .request_type = dir,
.flags = flags, .flags = flags,
}; };
retval = gpiod_line_request(line, &config, val); retval = gpiod_line_request(gpiod_line[idx], &config, val);
if (retval < 0) { if (retval < 0) {
LOG_ERROR("Error requesting gpio line %s", label); LOG_ERROR("Error requesting gpio line %s", adapter_gpio_get_name(idx));
return NULL; return ERROR_JTAG_INIT_FAILED;
} }
return line; return ERROR_OK;
}
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);
} }
static int linuxgpiod_init(void) static int linuxgpiod_init(void)
@ -366,11 +367,11 @@ static int linuxgpiod_init(void)
LOG_INFO("Linux GPIOD JTAG/SWD bitbang driver"); LOG_INFO("Linux GPIOD JTAG/SWD bitbang driver");
bitbang_interface = &linuxgpiod_bitbang; bitbang_interface = &linuxgpiod_bitbang;
adapter_gpio_config = adapter_gpio_get_config();
/* /*
* Configure TDO as an input, and TDI, TCK, TMS, TRST, SRST * Configure JTAG/SWD signals. Default directions and initial states are handled
* as outputs. Drive TDI and TCK low, and TMS/TRST/SRST high. * by adapter.c and "adapter gpio" command.
* For SWD, SWCLK and SWDIO are configures as output high.
*/ */
if (transport_is_jtag()) { if (transport_is_jtag()) {
@ -379,129 +380,44 @@ static int linuxgpiod_init(void)
goto out_error; goto out_error;
} }
gpiod_chip_tdo = gpiod_chip_open_by_number(tdo_gpiochip); if (helper_get_line(ADAPTER_GPIO_IDX_TDO) != ERROR_OK ||
if (!gpiod_chip_tdo) { helper_get_line(ADAPTER_GPIO_IDX_TDI) != ERROR_OK ||
LOG_ERROR("Cannot open LinuxGPIOD tdo_gpiochip %d", tdo_gpiochip); helper_get_line(ADAPTER_GPIO_IDX_TCK) != ERROR_OK ||
goto out_error; helper_get_line(ADAPTER_GPIO_IDX_TMS) != ERROR_OK ||
} helper_get_line(ADAPTER_GPIO_IDX_TRST) != ERROR_OK)
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);
goto out_error; 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()) { if (transport_is_swd()) {
int retval1, retval2;
if (!linuxgpiod_swd_mode_possible()) { if (!linuxgpiod_swd_mode_possible()) {
LOG_ERROR("Require swclk and swdio gpio for SWD mode"); LOG_ERROR("Require swclk and swdio gpio for SWD mode");
goto out_error; goto out_error;
} }
gpiod_chip_swclk = gpiod_chip_open_by_number(swclk_gpiochip); /*
if (!gpiod_chip_swclk) { * swdio and its buffer should be initialized in the order that prevents
LOG_ERROR("Cannot open LinuxGPIOD swclk_gpiochip %d", swclk_gpiochip); * two outputs from being connected together. This will occur if the
goto out_error; * 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 (retval1 != ERROR_OK || retval2 != ERROR_OK)
if (!gpiod_chip_swdio) {
LOG_ERROR("Cannot open LinuxGPIOD swdio_gpiochip %d", swdio_gpiochip);
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; goto out_error;
/* Set buffer direction before making SWDIO an output */ if (helper_get_line(ADAPTER_GPIO_IDX_SWCLK) != ERROR_OK)
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)
goto out_error; goto out_error;
} }
if (is_gpio_valid(srst_gpio)) { if (helper_get_line(ADAPTER_GPIO_IDX_SRST) != ERROR_OK ||
gpiod_chip_srst = gpiod_chip_open_by_number(srst_gpiochip); helper_get_line(ADAPTER_GPIO_IDX_LED) != ERROR_OK)
if (!gpiod_chip_srst) {
LOG_ERROR("Cannot open LinuxGPIOD srst_gpiochip %d", srst_gpiochip);
goto out_error; 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)
goto out_error;
}
return ERROR_OK; return ERROR_OK;
@ -511,241 +427,6 @@ out_error:
return ERROR_JTAG_INIT_FAILED; 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 const char *const linuxgpiod_transport[] = { "swd", "jtag", NULL };
static struct jtag_interface linuxgpiod_interface = { static struct jtag_interface linuxgpiod_interface = {
@ -756,7 +437,6 @@ static struct jtag_interface linuxgpiod_interface = {
struct adapter_driver linuxgpiod_adapter_driver = { struct adapter_driver linuxgpiod_adapter_driver = {
.name = "linuxgpiod", .name = "linuxgpiod",
.transports = linuxgpiod_transport, .transports = linuxgpiod_transport,
.commands = linuxgpiod_command_handlers,
.init = linuxgpiod_init, .init = linuxgpiod_init,
.quit = linuxgpiod_quit, .quit = linuxgpiod_quit,

View File

@ -535,74 +535,72 @@ proc bcm2835gpio_peripheral_base args {
lappend _telnet_autocomplete_skip linuxgpiod_jtag_nums lappend _telnet_autocomplete_skip linuxgpiod_jtag_nums
proc linuxgpiod_jtag_nums args { proc linuxgpiod_jtag_nums args {
echo "DEPRECATED! use 'linuxgpiod jtag_nums' not 'linuxgpiod_jtag_nums'" eval adapter_gpio_jtag_nums $args
eval linuxgpiod jtag_nums $args
} }
lappend _telnet_autocomplete_skip linuxgpiod_tck_num lappend _telnet_autocomplete_skip linuxgpiod_tck_num
proc linuxgpiod_tck_num args { proc linuxgpiod_tck_num args {
echo "DEPRECATED! use 'linuxgpiod tck_num' not 'linuxgpiod_tck_num'" eval adapter_gpio_helper tck $args
eval linuxgpiod tck_num $args
} }
lappend _telnet_autocomplete_skip linuxgpiod_tms_num lappend _telnet_autocomplete_skip linuxgpiod_tms_num
proc linuxgpiod_tms_num args { proc linuxgpiod_tms_num args {
echo "DEPRECATED! use 'linuxgpiod tms_num' not 'linuxgpiod_tms_num'" eval adapter_gpio_helper tms $args
eval linuxgpiod tms_num $args
} }
lappend _telnet_autocomplete_skip linuxgpiod_tdo_num lappend _telnet_autocomplete_skip linuxgpiod_tdo_num
proc linuxgpiod_tdo_num args { proc linuxgpiod_tdo_num args {
echo "DEPRECATED! use 'linuxgpiod tdo_num' not 'linuxgpiod_tdo_num'" eval adapter_gpio_helper tdo $args
eval linuxgpiod tdo_num $args
} }
lappend _telnet_autocomplete_skip linuxgpiod_tdi_num lappend _telnet_autocomplete_skip linuxgpiod_tdi_num
proc linuxgpiod_tdi_num args { proc linuxgpiod_tdi_num args {
echo "DEPRECATED! use 'linuxgpiod tdi_num' not 'linuxgpiod_tdi_num'" eval adapter_gpio_helper tdi $args
eval linuxgpiod tdi_num $args
} }
lappend _telnet_autocomplete_skip linuxgpiod_srst_num lappend _telnet_autocomplete_skip linuxgpiod_srst_num
proc linuxgpiod_srst_num args { proc linuxgpiod_srst_num args {
echo "DEPRECATED! use 'linuxgpiod srst_num' not 'linuxgpiod_srst_num'" eval adapter_gpio_helper srst $args
eval linuxgpiod srst_num $args
} }
lappend _telnet_autocomplete_skip linuxgpiod_trst_num lappend _telnet_autocomplete_skip linuxgpiod_trst_num
proc linuxgpiod_trst_num args { proc linuxgpiod_trst_num args {
echo "DEPRECATED! use 'linuxgpiod trst_num' not 'linuxgpiod_trst_num'" eval adapter_gpio_helper trst $args
eval linuxgpiod trst_num $args
} }
lappend _telnet_autocomplete_skip linuxgpiod_swd_nums lappend _telnet_autocomplete_skip linuxgpiod_swd_nums
proc linuxgpiod_swd_nums args { proc linuxgpiod_swd_nums args {
echo "DEPRECATED! use 'linuxgpiod swd_nums' not 'linuxgpiod_swd_nums'" eval adapter_gpio_swd_nums $args
eval linuxgpiod swd_nums $args
} }
lappend _telnet_autocomplete_skip linuxgpiod_swclk_num lappend _telnet_autocomplete_skip linuxgpiod_swclk_num
proc linuxgpiod_swclk_num args { proc linuxgpiod_swclk_num args {
echo "DEPRECATED! use 'linuxgpiod swclk_num' not 'linuxgpiod_swclk_num'" eval adapter_gpio_helper swclk $args
eval linuxgpiod swclk_num $args
} }
lappend _telnet_autocomplete_skip linuxgpiod_swdio_num lappend _telnet_autocomplete_skip linuxgpiod_swdio_num
proc linuxgpiod_swdio_num args { proc linuxgpiod_swdio_num args {
echo "DEPRECATED! use 'linuxgpiod swdio_num' not 'linuxgpiod_swdio_num'" eval adapter_gpio_helper swdio $args
eval linuxgpiod swdio_num $args
} }
lappend _telnet_autocomplete_skip linuxgpiod_led_num lappend _telnet_autocomplete_skip linuxgpiod_led_num
proc linuxgpiod_led_num args { proc linuxgpiod_led_num args {
echo "DEPRECATED! use 'linuxgpiod led_num' not 'linuxgpiod_led_num'" eval adapter_gpio_helper led $args
eval linuxgpiod led_num $args
} }
lappend _telnet_autocomplete_skip linuxgpiod_gpiochip lappend _telnet_autocomplete_skip linuxgpiod_gpiochip
proc linuxgpiod_gpiochip args { proc linuxgpiod_gpiochip args {
echo "DEPRECATED! use 'linuxgpiod gpiochip' not 'linuxgpiod_gpiochip'" echo "DEPRECATED! use 'adapter <signal_name> -chip' not 'linuxgpiod_gpiochip'"
eval linuxgpiod gpiochip $args 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 lappend _telnet_autocomplete_skip sysfsgpio_jtag_nums
@ -863,6 +861,87 @@ proc "xds110 serial" {args} {
eval adapter 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" lappend _telnet_autocomplete_skip "am335xgpio jtag_nums"
proc "am335xgpio jtag_nums" {tck_num tms_num tdi_num tdo_num} { 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'" echo "DEPRECATED! use 'adapter gpio tck; adapter gpio tms; adapter gpio tdi; adapter gpio tdo' not 'am335xgpio jtag_nums'"

View File

@ -17,11 +17,14 @@
adapter driver linuxgpiod adapter driver linuxgpiod
linuxgpiod gpiochip 0 adapter gpio srst 0 -chip 0
linuxgpiod jtag_nums 2 3 4 1 adapter gpio tdo 1 -chip 0
linuxgpiod trst_num 5 adapter gpio tck 2 -chip 0
linuxgpiod swd_nums 2 3 adapter gpio swclk 2 -chip 0
linuxgpiod srst_num 0 adapter gpio tms 3 -chip 0
linuxgpiod led_num 6 adapter gpio swdio 3 -chip 0
adapter gpio tdi 4 -chip 0
adapter gpio trst 5 -chip 0
adapter gpio led 6 -chip 0
reset_config trst_and_srst separate srst_push_pull reset_config trst_and_srst separate srst_push_pull

View File

@ -0,0 +1,105 @@
# SPDX-License-Identifier: GPL-2.0-or-later
# OpenOCD script to test that the deprecated "linuxgpiod *" and "linuxgpiod_*"
# commands produce the expected results. Run this command as:
# openocd -f <path>/test-linuxgpiod-deprecated-commands.cfg
# Raise an error if the "actual" value does not match the "expected" value. Trim
# whitespace (including newlines) from strings before comparing.
proc expected_value {expected actual} {
if {[string trim $expected] ne [string trim $actual]} {
error [puts "ERROR: '${actual}' != '${expected}'"]
}
}
adapter driver linuxgpiod
puts "Driver is '[adapter name]'"
expected_value "linuxgpiod" [adapter name]
echo [adapter gpio]
#####################################
# Test the "linuxgpiod *" commands
# Change the GPIO chip for all signals. Don't check directly here, do so when
# each signal command is tested.
linuxgpiod gpiochip 0
linuxgpiod jtag_nums 1 2 3 4
expected_value "adapter gpio tck (output): num 1, chip 0, active-high, push-pull, pull-none, init-state inactive" [eval adapter gpio tck]
expected_value "adapter gpio tms (output): num 2, chip 0, active-high, push-pull, pull-none, init-state active" [eval adapter gpio tms]
expected_value "adapter gpio tdi (output): num 3, chip 0, active-high, push-pull, pull-none, init-state inactive" [eval adapter gpio tdi]
expected_value "adapter gpio tdo (input): num 4, chip 0, active-high, pull-none, init-state input" [eval adapter gpio tdo]
linuxgpiod tck_num 5
expected_value "adapter gpio tck (output): num 5, chip 0, active-high, push-pull, pull-none, init-state inactive" [eval adapter gpio tck]
linuxgpiod tms_num 6
expected_value "adapter gpio tms (output): num 6, chip 0, active-high, push-pull, pull-none, init-state active" [eval adapter gpio tms]
linuxgpiod tdi_num 7
expected_value "adapter gpio tdi (output): num 7, chip 0, active-high, push-pull, pull-none, init-state inactive" [eval adapter gpio tdi]
linuxgpiod tdo_num 8
expected_value "adapter gpio tdo (input): num 8, chip 0, active-high, pull-none, init-state input" [eval adapter gpio tdo]
linuxgpiod swd_nums 9 10
expected_value "adapter gpio swclk (output): num 9, chip 0, active-high, push-pull, pull-none, init-state inactive" [eval adapter gpio swclk]
expected_value "adapter gpio swdio (bidirectional): num 10, chip 0, active-high, push-pull, pull-none, init-state inactive" [eval adapter gpio swdio]
linuxgpiod swclk_num 11
expected_value "adapter gpio swclk (output): num 11, chip 0, active-high, push-pull, pull-none, init-state inactive" [eval adapter gpio swclk]
linuxgpiod swdio_num 12
expected_value "adapter gpio swdio (bidirectional): num 12, chip 0, active-high, push-pull, pull-none, init-state inactive" [eval adapter gpio swdio]
linuxgpiod swdio_dir_num 13
expected_value "adapter gpio swdio_dir (output): num 13, chip 0, active-high, push-pull, pull-none" [eval adapter gpio swdio_dir]
linuxgpiod srst_num 14
expected_value "adapter gpio srst (output): num 14, chip 0, active-low, pull-none, init-state inactive" [eval adapter gpio srst]
linuxgpiod trst_num 15
expected_value "adapter gpio trst (output): num 15, chip 0, active-low, pull-none, init-state inactive" [eval adapter gpio trst]
linuxgpiod led_num 16
expected_value "adapter gpio led (output): num 16, chip 0, active-high, push-pull, pull-none, init-state inactive" [eval adapter gpio led]
#####################################
# Test the old linuxgpiod_* commands
# Change the GPIO chip for all signals. Don't check directly here, do so when
# each signal command is tested.
linuxgpiod_gpiochip 1
linuxgpiod_jtag_nums 17 18 19 20
expected_value "adapter gpio tck (output): num 17, chip 1, active-high, push-pull, pull-none, init-state inactive" [eval adapter gpio tck]
expected_value "adapter gpio tms (output): num 18, chip 1, active-high, push-pull, pull-none, init-state active" [eval adapter gpio tms]
expected_value "adapter gpio tdi (output): num 19, chip 1, active-high, push-pull, pull-none, init-state inactive" [eval adapter gpio tdi]
expected_value "adapter gpio tdo (input): num 20, chip 1, active-high, pull-none, init-state input" [eval adapter gpio tdo]
linuxgpiod_tck_num 21
expected_value "adapter gpio tck (output): num 21, chip 1, active-high, push-pull, pull-none, init-state inactive" [eval adapter gpio tck]
linuxgpiod_tms_num 22
expected_value "adapter gpio tms (output): num 22, chip 1, active-high, push-pull, pull-none, init-state active" [eval adapter gpio tms]
linuxgpiod_tdi_num 23
expected_value "adapter gpio tdi (output): num 23, chip 1, active-high, push-pull, pull-none, init-state inactive" [eval adapter gpio tdi]
linuxgpiod_tdo_num 24
expected_value "adapter gpio tdo (input): num 24, chip 1, active-high, pull-none, init-state input" [eval adapter gpio tdo]
linuxgpiod_swd_nums 25 26
expected_value "adapter gpio swclk (output): num 25, chip 1, active-high, push-pull, pull-none, init-state inactive" [eval adapter gpio swclk]
expected_value "adapter gpio swdio (bidirectional): num 26, chip 1, active-high, push-pull, pull-none, init-state inactive" [eval adapter gpio swdio]
linuxgpiod_swclk_num 27
expected_value "adapter gpio swclk (output): num 27, chip 1, active-high, push-pull, pull-none, init-state inactive" [eval adapter gpio swclk]
linuxgpiod_swdio_num 28
expected_value "adapter gpio swdio (bidirectional): num 28, chip 1, active-high, push-pull, pull-none, init-state inactive" [eval adapter gpio swdio]
linuxgpiod_led_num 29
expected_value "adapter gpio led (output): num 29, chip 1, active-high, push-pull, pull-none, init-state inactive" [eval adapter gpio led]
puts "SUCCESS"