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:
parent
903f2e92a1
commit
290eac04b9
|
@ -3401,87 +3401,14 @@ See @file{interface/beaglebone-swd-native.cfg} for a sample configuration file.
|
|||
|
||||
|
||||
@deffn {Interface Driver} {linuxgpiod}
|
||||
Linux provides userspace access to GPIO through libgpiod since Linux kernel version v4.6.
|
||||
The driver emulates either JTAG or SWD transport through bitbanging.
|
||||
|
||||
See @file{interface/dln-2-gpiod.cfg} for a sample config.
|
||||
|
||||
@deffn {Config Command} {linuxgpiod gpiochip} @var{chip}
|
||||
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
|
||||
Linux provides userspace access to GPIO through libgpiod since Linux kernel
|
||||
version v4.6. The driver emulates either JTAG or SWD transport through
|
||||
bitbanging. There are no driver-specific commands, all GPIO configuration is
|
||||
handled by the generic command @ref{adapter gpio, @command{adapter gpio}}. This
|
||||
driver supports the resistor pull options provided by the @command{adapter gpio}
|
||||
command but the underlying hardware may not be able to support them.
|
||||
|
||||
See @file{interface/dln-2-gpiod.cfg} for a sample configuration file.
|
||||
@end deffn
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
line = gpiod_chip_get_line(gpiod_chip, offset);
|
||||
if (!line) {
|
||||
LOG_ERROR("Error get line %s", label);
|
||||
return NULL;
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
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)
|
||||
if (retval1 != ERROR_OK || retval2 != ERROR_OK)
|
||||
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);
|
||||
if (helper_get_line(ADAPTER_GPIO_IDX_SRST) != ERROR_OK ||
|
||||
helper_get_line(ADAPTER_GPIO_IDX_LED) != ERROR_OK)
|
||||
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;
|
||||
|
||||
|
@ -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,
|
||||
|
|
|
@ -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'"
|
||||
|
|
|
@ -17,11 +17,14 @@
|
|||
|
||||
adapter driver linuxgpiod
|
||||
|
||||
linuxgpiod gpiochip 0
|
||||
linuxgpiod jtag_nums 2 3 4 1
|
||||
linuxgpiod trst_num 5
|
||||
linuxgpiod swd_nums 2 3
|
||||
linuxgpiod srst_num 0
|
||||
linuxgpiod led_num 6
|
||||
adapter gpio srst 0 -chip 0
|
||||
adapter gpio tdo 1 -chip 0
|
||||
adapter gpio tck 2 -chip 0
|
||||
adapter gpio swclk 2 -chip 0
|
||||
adapter gpio tms 3 -chip 0
|
||||
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
|
||||
|
|
|
@ -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"
|
Loading…
Reference in New Issue