26 #ifdef HAVE_LIBGPIOD_V1
28 #define GPIOD_LINE_DIRECTION_INPUT GPIOD_LINE_REQUEST_DIRECTION_INPUT
29 #define GPIOD_LINE_DIRECTION_OUTPUT GPIOD_LINE_REQUEST_DIRECTION_OUTPUT
31 #define GPIOD_LINE_VALUE_INACTIVE 0
32 #define GPIOD_LINE_VALUE_ACTIVE 1
34 #define GPIOD_LINE_DRIVE_PUSH_PULL 0
35 #define GPIOD_LINE_DRIVE_OPEN_DRAIN GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN
36 #define GPIOD_LINE_DRIVE_OPEN_SOURCE GPIOD_LINE_REQUEST_FLAG_OPEN_SOURCE
38 #define GPIOD_LINE_BIAS_DISABLED GPIOD_LINE_REQUEST_FLAG_BIAS_DISABLE
39 #define GPIOD_LINE_BIAS_PULL_UP GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_UP
40 #define GPIOD_LINE_BIAS_PULL_DOWN GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_DOWN
56 LOG_ERROR(
"No memory for gpiod line settings");
79 settings->value = value;
86 settings->drive = drive;
95 settings->active_low = GPIOD_LINE_REQUEST_FLAG_ACTIVE_LOW;
98 #ifdef HAVE_LIBGPIOD1_FLAGS_BIAS
102 settings->bias = bias;
111 if (bias == GPIOD_LINE_BIAS_DISABLED)
114 LOG_WARNING(
"linuxgpiod: ignoring request for pull-%s: not supported by libgpiod v%s",
115 (bias == GPIOD_LINE_BIAS_PULL_UP) ?
"up" :
"down",
116 gpiod_version_string());
124 unsigned int gpio_num;
134 LOG_ERROR(
"No memory for gpiod line config");
149 assert(num_offsets == 1);
151 config->gpio_num = *offsets;
152 config->line_settings = settings;
157 struct gpiod_request_config {
158 const char *consumer;
161 static struct gpiod_request_config *gpiod_request_config_new(
void)
163 struct gpiod_request_config *rv;
165 rv = calloc(
sizeof(
struct gpiod_request_config), 1);
167 LOG_ERROR(
"No memory for gpiod request config");
174 static void gpiod_request_config_free(
struct gpiod_request_config *
config)
179 static void gpiod_request_config_set_consumer(
struct gpiod_request_config *
config,
180 const char *consumer)
182 config->consumer = consumer;
185 struct gpiod_line_request {
186 struct gpiod_line *gpio_line;
188 struct gpiod_request_config *req_cfg;
192 static void gpiod_line_request_release(
struct gpiod_line_request *request);
194 static struct gpiod_line_request *gpiod_chip_request_lines(
struct gpiod_chip *chip,
197 struct gpiod_line_request *line_req;
202 line_req = calloc(
sizeof(
struct gpiod_line_request), 1);
204 LOG_ERROR(
"No memory for gpiod line request");
208 line_req->gpio_line = gpiod_chip_get_line(chip, line_cfg->gpio_num);
209 if (!line_req->gpio_line) {
215 line_req->chip = chip;
216 line_req->req_cfg = gpiod_request_config_new();
217 *line_req->req_cfg = *req_cfg;
218 line_req->line_cfg = line_cfg;
220 flags |= line_cfg->line_settings->drive;
221 flags |= line_cfg->line_settings->bias;
222 flags |= line_cfg->line_settings->active_low;
224 struct gpiod_line_request_config
config = {
225 .consumer = line_req->req_cfg->consumer,
226 .request_type = line_cfg->line_settings->direction,
230 rv = gpiod_line_request(line_req->gpio_line, &
config, line_cfg->line_settings->value);
232 gpiod_line_request_release(line_req);
239 static int gpiod_line_request_get_value(
struct gpiod_line_request *request,
242 return gpiod_line_get_value(request->gpio_line);
245 static int gpiod_line_request_set_value(
struct gpiod_line_request *request,
248 return gpiod_line_set_value(request->gpio_line, value);
251 static void gpiod_line_request_release(
struct gpiod_line_request *request)
253 gpiod_request_config_free(request->req_cfg);
254 gpiod_line_release(request->gpio_line);
258 static int gpiod_line_request_reconfigure_lines(
struct gpiod_line_request *request,
264 gpiod_line_release(request->gpio_line);
265 request->gpio_line = gpiod_chip_get_line(request->chip, request->line_cfg->gpio_num);
266 if (!request->gpio_line)
269 flags |= line_cfg->line_settings->drive;
270 flags |= line_cfg->line_settings->bias;
271 flags |= line_cfg->line_settings->active_low;
273 struct gpiod_line_request_config
config = {
274 .consumer = request->req_cfg->consumer,
275 .request_type = line_cfg->line_settings->direction,
279 rv = gpiod_line_request(request->gpio_line, &
config, line_cfg->line_settings->value);
284 request->line_cfg = line_cfg;
354 static int first_time;
365 if (tdi != last_tdi) {
378 if (tck != last_tck) {
416 GPIOD_LINE_DIRECTION_OUTPUT);
418 LOG_WARNING(
"Failed to set new direction of swdio");
421 GPIOD_LINE_VALUE_ACTIVE);
423 LOG_WARNING(
"Failed to set output value of swdio");
429 LOG_WARNING(
"Failed to apply output configuration to swdio");
437 GPIOD_LINE_DIRECTION_INPUT);
445 LOG_WARNING(
"Failed to apply input configuration to swdio");
518 int retval1 = 0, retval2 = 0;
594 struct gpiod_request_config *req_cfg =
NULL;
601 snprintf(chip_path,
sizeof(chip_path),
"/dev/gpiochip%u",
adapter_gpio_config[idx].chip_num);
612 req_cfg = gpiod_request_config_new();
616 gpiod_request_config_free(req_cfg);
620 gpiod_request_config_set_consumer(req_cfg,
"OpenOCD");
624 rv = gpiod_line_settings_set_direction(
gpiod_line_settings[idx], GPIOD_LINE_DIRECTION_INPUT);
627 rv = gpiod_line_settings_set_direction(
gpiod_line_settings[idx], GPIOD_LINE_DIRECTION_OUTPUT);
628 rv |= gpiod_line_settings_set_output_value(
gpiod_line_settings[idx], GPIOD_LINE_VALUE_INACTIVE);
631 rv = gpiod_line_settings_set_direction(
gpiod_line_settings[idx], GPIOD_LINE_DIRECTION_OUTPUT);
632 rv |= gpiod_line_settings_set_output_value(
gpiod_line_settings[idx], GPIOD_LINE_VALUE_ACTIVE);
637 gpiod_request_config_free(req_cfg);
649 rv = gpiod_line_settings_set_drive(
gpiod_line_settings[idx], GPIOD_LINE_DRIVE_OPEN_SOURCE);
654 gpiod_request_config_free(req_cfg);
671 gpiod_request_config_free(req_cfg);
682 gpiod_request_config_free(req_cfg);
688 gpiod_request_config_free(req_cfg);
700 LOG_INFO(
"Linux GPIOD JTAG/SWD bitbang driver");
712 LOG_ERROR(
"Require tck, tms, tdi and tdo gpios for JTAG mode");
725 int retval1, retval2;
727 LOG_ERROR(
"Require swclk and swdio gpio for SWD mode");
769 .
name =
"linuxgpiod",
const struct adapter_gpio_config * adapter_gpio_get_config(void)
Retrieves gpio configuration set with command "adapter gpio <signal_name>".
const char * adapter_gpio_get_name(enum adapter_gpio_config_index idx)
Retrieves gpio name.
@ ADAPTER_GPIO_INIT_STATE_ACTIVE
@ ADAPTER_GPIO_INIT_STATE_INPUT
@ ADAPTER_GPIO_INIT_STATE_INACTIVE
adapter_gpio_config_index
Adapter GPIO.
@ ADAPTER_GPIO_IDX_SWDIO_DIR
@ ADAPTER_GPIO_DRIVE_MODE_OPEN_SOURCE
@ ADAPTER_GPIO_DRIVE_MODE_OPEN_DRAIN
@ ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL
bool transport_is_swd(void)
Returns true if the current debug session is using SWD as its transport.
int bitbang_execute_queue(struct jtag_command *cmd_queue)
const struct swd_driver bitbang_swd
static uint16_t direction
#define DEBUG_CAP_TMS_SEQ
static struct device_config config
bool transport_is_jtag(void)
Returns true if the current debug session is using JTAG as its transport.
#define ERROR_JTAG_INIT_FAILED
static int linuxgpiod_quit(void)
static int linuxgpiod_blink(bool on)
struct adapter_driver linuxgpiod_adapter_driver
static void helper_release(enum adapter_gpio_config_index idx)
static bool linuxgpiod_jtag_mode_possible(void)
static bool is_gpio_config_valid(enum adapter_gpio_config_index idx)
static const struct bitbang_interface linuxgpiod_bitbang
static int linuxgpiod_line_set_value(enum adapter_gpio_config_index idx, int value)
static struct gpiod_line_settings * gpiod_line_settings[ADAPTER_GPIO_IDX_NUM]
static int linuxgpiod_line_get_value(enum adapter_gpio_config_index idx)
static struct jtag_interface linuxgpiod_interface
static int linuxgpiod_swdio_read(void)
static struct gpiod_line_request * gpiod_line_req[ADAPTER_GPIO_IDX_NUM]
static int helper_get_line(enum adapter_gpio_config_index idx)
static enum bb_value linuxgpiod_read(void)
static const struct adapter_gpio_config * adapter_gpio_config
static void linuxgpiod_swdio_drive(bool is_output)
static int linuxgpiod_write(int tck, int tms, int tdi)
static struct gpiod_chip * gpiod_chip[ADAPTER_GPIO_IDX_NUM]
static struct gpiod_line_config * gpiod_line_config[ADAPTER_GPIO_IDX_NUM]
static int linuxgpiod_swd_write(int swclk, int swdio)
static int linuxgpiod_reset(int trst, int srst)
static int linuxgpiod_init(void)
static bool linuxgpiod_swd_mode_possible(void)
#define LOG_WARNING(expr ...)
#define LOG_ERROR(expr ...)
#define LOG_INFO(expr ...)
#define LOG_DEBUG(expr ...)
struct qn908x_flash_bank __attribute__
Represents a driver for a debugging interface.
const char *const name
The name of the interface driver.
Configuration options for a single GPIO.
Low level callbacks (for bitbang).
enum bb_value(* read)(void)
Sample TDO and return the value.
Represents a driver for a debugging interface.
unsigned int supported
Bit vector listing capabilities exposed by this driver.