OpenOCD
linuxgpiod.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Bitbang driver for Linux GPIO descriptors through libgpiod
4  * Copyright (C) 2020 Antonio Borneo <borneo.antonio@gmail.com>
5  *
6  * Largely based on sysfsgpio driver
7  * Copyright (C) 2012 by Creative Product Design, marc @ cpdesign.com.au
8  * Copyright (C) 2014 by Jean-Christian de Rivaz <jc@eclis.ch>
9  * Copyright (C) 2014 by Paul Fertser <fercerpav@gmail.com>
10  */
11 
12 #ifdef HAVE_CONFIG_H
13 #include "config.h"
14 #endif
15 
16 #include <gpiod.h>
17 #include <jtag/adapter.h>
18 #include <jtag/interface.h>
19 #include <transport/transport.h>
20 #include "bitbang.h"
21 
22 /*
23  * In case of libgpiod v1, use as much as possible API from v2 plus
24  * the dummy wrappers below.
25  */
26 #ifdef HAVE_LIBGPIOD_V1
27 
28 #define GPIOD_LINE_DIRECTION_INPUT GPIOD_LINE_REQUEST_DIRECTION_INPUT
29 #define GPIOD_LINE_DIRECTION_OUTPUT GPIOD_LINE_REQUEST_DIRECTION_OUTPUT
30 
31 #define GPIOD_LINE_VALUE_INACTIVE 0
32 #define GPIOD_LINE_VALUE_ACTIVE 1
33 
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
37 
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
41 
42 struct gpiod_line_settings {
43  int direction;
44  int value;
45  int drive;
46  int bias;
47  int active_low;
48 };
49 
50 static struct gpiod_line_settings *gpiod_line_settings_new(void)
51 {
52  struct gpiod_line_settings *rv;
53 
54  rv = calloc(sizeof(struct gpiod_line_settings), 1);
55  if (!rv) {
56  LOG_ERROR("No memory for gpiod line settings");
57  return NULL;
58  }
59 
60  return rv;
61 }
62 
63 static void gpiod_line_settings_free(struct gpiod_line_settings *settings)
64 {
65  free(settings);
66 }
67 
68 static int gpiod_line_settings_set_direction(struct gpiod_line_settings *settings,
69  int direction)
70 {
71  settings->direction = direction;
72 
73  return 0;
74 }
75 
76 static int gpiod_line_settings_set_output_value(struct gpiod_line_settings *settings,
77  int value)
78 {
79  settings->value = value;
80 
81  return 0;
82 }
83 
84 static int gpiod_line_settings_set_drive(struct gpiod_line_settings *settings, int drive)
85 {
86  settings->drive = drive;
87 
88  return 0;
89 }
90 
91 static void gpiod_line_settings_set_active_low(struct gpiod_line_settings *settings,
92  bool active_low)
93 {
94  if (active_low)
95  settings->active_low = GPIOD_LINE_REQUEST_FLAG_ACTIVE_LOW;
96 }
97 
98 #ifdef HAVE_LIBGPIOD1_FLAGS_BIAS
99 
100 static int gpiod_line_settings_set_bias(struct gpiod_line_settings *settings, int bias)
101 {
102  settings->bias = bias;
103 
104  return 0;
105 }
106 
107 #else /* HAVE_LIBGPIOD1_FLAGS_BIAS */
108 
109 static int gpiod_line_settings_set_bias(struct gpiod_line_settings *settings, int bias)
110 {
111  if (bias == GPIOD_LINE_BIAS_DISABLED)
112  return 0;
113 
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());
117 
118  return 0;
119 }
120 
121 #endif /* HAVE_LIBGPIOD1_FLAGS_BIAS */
122 
123 struct gpiod_line_config {
124  unsigned int gpio_num;
125  struct gpiod_line_settings *line_settings;
126 };
127 
128 static struct gpiod_line_config *gpiod_line_config_new(void)
129 {
130  struct gpiod_line_config *rv;
131 
132  rv = calloc(sizeof(struct gpiod_line_config), 1);
133  if (!rv) {
134  LOG_ERROR("No memory for gpiod line config");
135  return NULL;
136  }
137 
138  return rv;
139 }
140 
141 static void gpiod_line_config_free(struct gpiod_line_config *config)
142 {
143  free(config);
144 }
145 
146 static int gpiod_line_config_add_line_settings(struct gpiod_line_config *config,
147  const unsigned int *offsets, size_t num_offsets, struct gpiod_line_settings *settings)
148 {
149  assert(num_offsets == 1);
150 
151  config->gpio_num = *offsets;
152  config->line_settings = settings;
153 
154  return 0;
155 }
156 
157 struct gpiod_request_config {
158  const char *consumer;
159 };
160 
161 static struct gpiod_request_config *gpiod_request_config_new(void)
162 {
163  struct gpiod_request_config *rv;
164 
165  rv = calloc(sizeof(struct gpiod_request_config), 1);
166  if (!rv) {
167  LOG_ERROR("No memory for gpiod request config");
168  return NULL;
169  }
170 
171  return rv;
172 }
173 
174 static void gpiod_request_config_free(struct gpiod_request_config *config)
175 {
176  free(config);
177 }
178 
179 static void gpiod_request_config_set_consumer(struct gpiod_request_config *config,
180  const char *consumer)
181 {
182  config->consumer = consumer;
183 }
184 
185 struct gpiod_line_request {
186  struct gpiod_line *gpio_line;
187  struct gpiod_chip *chip;
188  struct gpiod_request_config *req_cfg;
189  struct gpiod_line_config *line_cfg;
190 };
191 
192 static void gpiod_line_request_release(struct gpiod_line_request *request);
193 
194 static struct gpiod_line_request *gpiod_chip_request_lines(struct gpiod_chip *chip,
195  struct gpiod_request_config *req_cfg, struct gpiod_line_config *line_cfg)
196 {
197  struct gpiod_line_request *line_req;
198  int rv, flags = 0;
199 
200  assert(req_cfg);
201 
202  line_req = calloc(sizeof(struct gpiod_line_request), 1);
203  if (!line_req) {
204  LOG_ERROR("No memory for gpiod line request");
205  return NULL;
206  }
207 
208  line_req->gpio_line = gpiod_chip_get_line(chip, line_cfg->gpio_num);
209  if (!line_req->gpio_line) {
210  free(line_req);
211  return NULL;
212  }
213 
214  /* remember stuff in case we need to reconfigure later */
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;
219 
220  flags |= line_cfg->line_settings->drive;
221  flags |= line_cfg->line_settings->bias;
222  flags |= line_cfg->line_settings->active_low;
223 
224  struct gpiod_line_request_config config = {
225  .consumer = line_req->req_cfg->consumer,
226  .request_type = line_cfg->line_settings->direction,
227  .flags = flags,
228  };
229 
230  rv = gpiod_line_request(line_req->gpio_line, &config, line_cfg->line_settings->value);
231  if (rv < 0) {
232  gpiod_line_request_release(line_req);
233  return NULL;
234  }
235 
236  return line_req;
237 }
238 
239 static int gpiod_line_request_get_value(struct gpiod_line_request *request,
240  __attribute__((unused)) unsigned int offset)
241 {
242  return gpiod_line_get_value(request->gpio_line);
243 }
244 
245 static int gpiod_line_request_set_value(struct gpiod_line_request *request,
246  __attribute__((unused)) unsigned int offset, int value)
247 {
248  return gpiod_line_set_value(request->gpio_line, value);
249 }
250 
251 static void gpiod_line_request_release(struct gpiod_line_request *request)
252 {
253  gpiod_request_config_free(request->req_cfg);
254  gpiod_line_release(request->gpio_line);
255  free(request);
256 }
257 
258 static int gpiod_line_request_reconfigure_lines(struct gpiod_line_request *request,
259  struct gpiod_line_config *line_cfg)
260 {
261  int rv, flags = 0;
262 
263  /* in libgpiod v1 we have to release the line and re-aquire it */
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)
267  return -1;
268 
269  flags |= line_cfg->line_settings->drive;
270  flags |= line_cfg->line_settings->bias;
271  flags |= line_cfg->line_settings->active_low;
272 
273  struct gpiod_line_request_config config = {
274  .consumer = request->req_cfg->consumer,
275  .request_type = line_cfg->line_settings->direction,
276  .flags = flags,
277  };
278 
279  rv = gpiod_line_request(request->gpio_line, &config, line_cfg->line_settings->value);
280  if (rv < 0)
281  return -1;
282 
283  /* remember updated line_cfg */
284  request->line_cfg = line_cfg;
285  return 0;
286 }
287 
288 #endif /* HAVE_LIBGPIOD_V1 */
289 
293 static struct gpiod_line_request *gpiod_line_req[ADAPTER_GPIO_IDX_NUM] = {};
294 
295 static int last_swclk;
296 static int last_swdio;
297 static bool last_stored;
298 static bool swdio_input;
299 
301 
302 /* Helper to get/set a single line */
304 {
305  return gpiod_line_request_get_value(gpiod_line_req[idx],
307 }
308 
310 {
311  return gpiod_line_request_set_value(gpiod_line_req[idx],
313  value);
314 }
315 
316 /*
317  * Helper function to determine if gpio config is valid
318  *
319  * Assume here that there will be less than 10000 gpios per gpiochip, and less
320  * than 1000 gpiochips.
321  */
323 {
324  return adapter_gpio_config[idx].chip_num < 1000
325  && adapter_gpio_config[idx].gpio_num < 10000;
326 }
327 
328 /* Bitbang interface read of TDO */
329 static enum bb_value linuxgpiod_read(void)
330 {
331  int retval;
332 
334  if (retval < 0) {
335  LOG_WARNING("reading tdo failed");
336  return 0;
337  }
338 
339  return retval ? BB_HIGH : BB_LOW;
340 }
341 
342 /*
343  * Bitbang interface write of TCK, TMS, TDI
344  *
345  * Seeing as this is the only function where the outputs are changed,
346  * we can cache the old value to avoid needlessly writing it.
347  */
348 static int linuxgpiod_write(int tck, int tms, int tdi)
349 {
350  static int last_tck;
351  static int last_tms;
352  static int last_tdi;
353 
354  static int first_time;
355 
356  int retval;
357 
358  if (!first_time) {
359  last_tck = !tck;
360  last_tms = !tms;
361  last_tdi = !tdi;
362  first_time = 1;
363  }
364 
365  if (tdi != last_tdi) {
367  if (retval < 0)
368  LOG_WARNING("writing tdi failed");
369  }
370 
371  if (tms != last_tms) {
373  if (retval < 0)
374  LOG_WARNING("writing tms failed");
375  }
376 
377  /* write clk last */
378  if (tck != last_tck) {
380  if (retval < 0)
381  LOG_WARNING("writing tck failed");
382  }
383 
384  last_tdi = tdi;
385  last_tms = tms;
386  last_tck = tck;
387 
388  return ERROR_OK;
389 }
390 
391 static int linuxgpiod_swdio_read(void)
392 {
393  int retval;
394 
396  if (retval < 0) {
397  LOG_WARNING("Fail read swdio");
398  return 0;
399  }
400 
401  return retval;
402 }
403 
404 static void linuxgpiod_swdio_drive(bool is_output)
405 {
406  int retval;
407 
408  if (is_output) {
411  if (retval < 0)
412  LOG_WARNING("Failed to set swdio_dir=1");
413  }
414 
415  retval = gpiod_line_settings_set_direction(gpiod_line_settings[ADAPTER_GPIO_IDX_SWDIO],
416  GPIOD_LINE_DIRECTION_OUTPUT);
417  if (retval < 0)
418  LOG_WARNING("Failed to set new direction of swdio");
419 
420  retval = gpiod_line_settings_set_output_value(gpiod_line_settings[ADAPTER_GPIO_IDX_SWDIO],
421  GPIOD_LINE_VALUE_ACTIVE);
422  if (retval < 0)
423  LOG_WARNING("Failed to set output value of swdio");
424 
425  retval = gpiod_line_config_add_line_settings(gpiod_line_config[ADAPTER_GPIO_IDX_SWDIO],
428  if (retval < 0)
429  LOG_WARNING("Failed to apply output configuration to swdio");
430 
431  retval = gpiod_line_request_reconfigure_lines(gpiod_line_req[ADAPTER_GPIO_IDX_SWDIO],
433  if (retval < 0)
434  LOG_WARNING("Failed to switch swdio to output");
435  } else {
436  retval = gpiod_line_settings_set_direction(gpiod_line_settings[ADAPTER_GPIO_IDX_SWDIO],
437  GPIOD_LINE_DIRECTION_INPUT);
438  if (retval < 0)
439  LOG_WARNING("Failed to switch swdio to output");
440 
441  retval = gpiod_line_config_add_line_settings(gpiod_line_config[ADAPTER_GPIO_IDX_SWDIO],
444  if (retval < 0)
445  LOG_WARNING("Failed to apply input configuration to swdio");
446 
447  retval = gpiod_line_request_reconfigure_lines(gpiod_line_req[ADAPTER_GPIO_IDX_SWDIO],
449  if (retval < 0)
450  LOG_WARNING("Failed to switch swdio to input");
451 
454  if (retval < 0)
455  LOG_WARNING("Failed to set swdio_dir=0");
456  }
457  }
458 
459  last_stored = false;
460  swdio_input = !is_output;
461 }
462 
463 static int linuxgpiod_swd_write(int swclk, int swdio)
464 {
465  int retval;
466 
467  if (!swdio_input) {
468  if (!last_stored || swdio != last_swdio) {
470  if (retval < 0)
471  LOG_WARNING("Fail set swdio");
472  }
473  }
474 
475  /* write swclk last */
476  if (!last_stored || swclk != last_swclk) {
478  if (retval < 0)
479  LOG_WARNING("Fail set swclk");
480  }
481 
482  last_swdio = swdio;
483  last_swclk = swclk;
484  last_stored = true;
485 
486  return ERROR_OK;
487 }
488 
489 static int linuxgpiod_blink(bool on)
490 {
491  int retval;
492 
494  return ERROR_OK;
495 
497  if (retval < 0)
498  LOG_WARNING("Fail set led");
499  return retval;
500 }
501 
502 static const struct bitbang_interface linuxgpiod_bitbang = {
504  .write = linuxgpiod_write,
505  .swdio_read = linuxgpiod_swdio_read,
506  .swdio_drive = linuxgpiod_swdio_drive,
507  .swd_write = linuxgpiod_swd_write,
508  .blink = linuxgpiod_blink,
509 };
510 
511 /*
512  * Bitbang interface to manipulate reset lines SRST and TRST
513  *
514  * (1) assert or (0) deassert reset lines
515  */
516 static int linuxgpiod_reset(int trst, int srst)
517 {
518  int retval1 = 0, retval2 = 0;
519 
520  LOG_DEBUG("linuxgpiod_reset");
521 
522  /*
523  * active low behavior handled by "adaptor gpio" command and
524  * GPIOD_LINE_REQUEST_FLAG_ACTIVE_LOW flag when requesting the line.
525  */
528  if (retval1 < 0)
529  LOG_WARNING("set srst value failed");
530  }
531 
534  if (retval2 < 0)
535  LOG_WARNING("set trst value failed");
536  }
537 
538  return ((retval1 < 0) || (retval2 < 0)) ? ERROR_FAIL : ERROR_OK;
539 }
540 
542 {
544  return false;
546  return false;
548  return false;
550  return false;
551  return true;
552 }
553 
555 {
557  return false;
559  return false;
560  return true;
561 }
562 
563 static inline void helper_release(enum adapter_gpio_config_index idx)
564 {
565  if (gpiod_line_req[idx]) {
566  gpiod_line_request_release(gpiod_line_req[idx]);
567  gpiod_line_req[idx] = NULL;
568  }
569  if (gpiod_line_config[idx]) {
570  gpiod_line_config_free(gpiod_line_config[idx]);
571  gpiod_line_config[idx] = NULL;
572  }
573  if (gpiod_line_settings[idx]) {
574  gpiod_line_settings_free(gpiod_line_settings[idx]);
575  gpiod_line_settings[idx] = NULL;
576  }
577  if (gpiod_chip[idx]) {
578  gpiod_chip_close(gpiod_chip[idx]);
579  gpiod_chip[idx] = NULL;
580  }
581 }
582 
583 static int linuxgpiod_quit(void)
584 {
585  LOG_DEBUG("linuxgpiod_quit");
586  for (int i = 0; i < ADAPTER_GPIO_IDX_NUM; ++i)
587  helper_release(i);
588 
589  return ERROR_OK;
590 }
591 
593 {
594  struct gpiod_request_config *req_cfg = NULL;
595  char chip_path[24];
596  int rv = 0;
597 
598  if (!is_gpio_config_valid(idx))
599  return ERROR_OK;
600 
601  snprintf(chip_path, sizeof(chip_path), "/dev/gpiochip%u", adapter_gpio_config[idx].chip_num);
602  gpiod_chip[idx] = gpiod_chip_open(chip_path);
603 
604  if (!gpiod_chip[idx]) {
605  LOG_ERROR("Cannot open LinuxGPIOD chip %d for %s", adapter_gpio_config[idx].chip_num,
606  adapter_gpio_get_name(idx));
607  return ERROR_JTAG_INIT_FAILED;
608  }
609 
610  gpiod_line_settings[idx] = gpiod_line_settings_new();
611  gpiod_line_config[idx] = gpiod_line_config_new();
612  req_cfg = gpiod_request_config_new();
613 
614  if (!gpiod_line_settings[idx] || !gpiod_line_config[idx] || !req_cfg) {
615  LOG_ERROR("Cannot configure LinuxGPIOD line for %s", adapter_gpio_get_name(idx));
616  gpiod_request_config_free(req_cfg);
617  return ERROR_JTAG_INIT_FAILED;
618  }
619 
620  gpiod_request_config_set_consumer(req_cfg, "OpenOCD");
621 
622  switch (adapter_gpio_config[idx].init_state) {
624  rv = gpiod_line_settings_set_direction(gpiod_line_settings[idx], GPIOD_LINE_DIRECTION_INPUT);
625  break;
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);
629  break;
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);
633  break;
634  }
635  if (rv < 0) {
636  LOG_ERROR("Error while configuring LinuxGPIOD line init state for %s", adapter_gpio_get_name(idx));
637  gpiod_request_config_free(req_cfg);
638  return ERROR_JTAG_INIT_FAILED;
639  }
640 
641  switch (adapter_gpio_config[idx].drive) {
643  rv = gpiod_line_settings_set_drive(gpiod_line_settings[idx], GPIOD_LINE_DRIVE_PUSH_PULL);
644  break;
646  rv = gpiod_line_settings_set_drive(gpiod_line_settings[idx], GPIOD_LINE_DRIVE_OPEN_DRAIN);
647  break;
649  rv = gpiod_line_settings_set_drive(gpiod_line_settings[idx], GPIOD_LINE_DRIVE_OPEN_SOURCE);
650  break;
651  }
652  if (rv < 0) {
653  LOG_ERROR("Error while configuring LinuxGPIOD line driving for %s", adapter_gpio_get_name(idx));
654  gpiod_request_config_free(req_cfg);
655  return ERROR_JTAG_INIT_FAILED;
656  }
657 
658  switch (adapter_gpio_config[idx].pull) {
660  rv = gpiod_line_settings_set_bias(gpiod_line_settings[idx], GPIOD_LINE_BIAS_DISABLED);
661  break;
663  rv = gpiod_line_settings_set_bias(gpiod_line_settings[idx], GPIOD_LINE_BIAS_PULL_UP);
664  break;
666  rv = gpiod_line_settings_set_bias(gpiod_line_settings[idx], GPIOD_LINE_BIAS_PULL_DOWN);
667  break;
668  }
669  if (rv < 0) {
670  LOG_ERROR("Error while configuring LinuxGPIOD line biasing for %s", adapter_gpio_get_name(idx));
671  gpiod_request_config_free(req_cfg);
672  return ERROR_JTAG_INIT_FAILED;
673  }
674 
675  gpiod_line_settings_set_active_low(gpiod_line_settings[idx], adapter_gpio_config[idx].active_low);
676 
677  rv = gpiod_line_config_add_line_settings(gpiod_line_config[idx],
678  &adapter_gpio_config[idx].gpio_num, 1,
679  gpiod_line_settings[idx]);
680  if (rv < 0) {
681  LOG_ERROR("Error configuring gpio line %s", adapter_gpio_get_name(idx));
682  gpiod_request_config_free(req_cfg);
683  return ERROR_JTAG_INIT_FAILED;
684  }
685 
686  gpiod_line_req[idx] = gpiod_chip_request_lines(gpiod_chip[idx], req_cfg, gpiod_line_config[idx]);
687 
688  gpiod_request_config_free(req_cfg);
689 
690  if (!gpiod_line_req[idx]) {
691  LOG_ERROR("Error requesting gpio line %s", adapter_gpio_get_name(idx));
692  return ERROR_JTAG_INIT_FAILED;
693  }
694 
695  return ERROR_OK;
696 }
697 
698 static int linuxgpiod_init(void)
699 {
700  LOG_INFO("Linux GPIOD JTAG/SWD bitbang driver");
701 
704 
705  /*
706  * Configure JTAG/SWD signals. Default directions and initial states are handled
707  * by adapter.c and "adapter gpio" command.
708  */
709 
710  if (transport_is_jtag()) {
712  LOG_ERROR("Require tck, tms, tdi and tdo gpios for JTAG mode");
713  goto out_error;
714  }
715 
721  goto out_error;
722  }
723 
724  if (transport_is_swd()) {
725  int retval1, retval2;
727  LOG_ERROR("Require swclk and swdio gpio for SWD mode");
728  goto out_error;
729  }
730 
731  /*
732  * swdio and its buffer should be initialized in the order that prevents
733  * two outputs from being connected together. This will occur if the
734  * swdio GPIO is configured as an output while the external buffer is
735  * configured to send the swdio signal from the target to the GPIO.
736  */
740  } else {
743  }
744  if (retval1 != ERROR_OK || retval2 != ERROR_OK)
745  goto out_error;
746 
748  goto out_error;
749  }
750 
753  goto out_error;
754 
755  return ERROR_OK;
756 
757 out_error:
758  linuxgpiod_quit();
759 
760  return ERROR_JTAG_INIT_FAILED;
761 }
762 
763 static struct jtag_interface linuxgpiod_interface = {
765  .execute_queue = bitbang_execute_queue,
766 };
767 
769  .name = "linuxgpiod",
770  .transport_ids = TRANSPORT_SWD | TRANSPORT_JTAG,
771  .transport_preferred_id = TRANSPORT_SWD,
772 
773  .init = linuxgpiod_init,
774  .quit = linuxgpiod_quit,
775  .reset = linuxgpiod_reset,
776 
777  .jtag_ops = &linuxgpiod_interface,
778  .swd_ops = &bitbang_swd,
779 };
const struct adapter_gpio_config * adapter_gpio_get_config(void)
Retrieves gpio configuration set with command "adapter gpio <signal_name>".
Definition: adapter.c:1263
const char * adapter_gpio_get_name(enum adapter_gpio_config_index idx)
Retrieves gpio name.
Definition: adapter.c:1257
@ ADAPTER_GPIO_INIT_STATE_ACTIVE
Definition: adapter.h:32
@ ADAPTER_GPIO_INIT_STATE_INPUT
Definition: adapter.h:33
@ ADAPTER_GPIO_INIT_STATE_INACTIVE
Definition: adapter.h:31
adapter_gpio_config_index
Adapter GPIO.
Definition: adapter.h:52
@ ADAPTER_GPIO_IDX_LED
Definition: adapter.h:62
@ ADAPTER_GPIO_IDX_NUM
Definition: adapter.h:64
@ ADAPTER_GPIO_IDX_SWCLK
Definition: adapter.h:60
@ ADAPTER_GPIO_IDX_SWDIO_DIR
Definition: adapter.h:59
@ ADAPTER_GPIO_IDX_SRST
Definition: adapter.h:61
@ ADAPTER_GPIO_IDX_TRST
Definition: adapter.h:57
@ ADAPTER_GPIO_IDX_TDI
Definition: adapter.h:54
@ ADAPTER_GPIO_IDX_TMS
Definition: adapter.h:55
@ ADAPTER_GPIO_IDX_TCK
Definition: adapter.h:56
@ ADAPTER_GPIO_IDX_TDO
Definition: adapter.h:53
@ ADAPTER_GPIO_IDX_SWDIO
Definition: adapter.h:58
@ ADAPTER_GPIO_PULL_UP
Definition: adapter.h:47
@ ADAPTER_GPIO_PULL_DOWN
Definition: adapter.h:48
@ ADAPTER_GPIO_PULL_NONE
Definition: adapter.h:46
@ ADAPTER_GPIO_DRIVE_MODE_OPEN_SOURCE
Definition: adapter.h:19
@ ADAPTER_GPIO_DRIVE_MODE_OPEN_DRAIN
Definition: adapter.h:18
@ ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL
Definition: adapter.h:17
bool transport_is_swd(void)
Returns true if the current debug session is using SWD as its transport.
Definition: adi_v5_swd.c:773
static int last_tms
Definition: arm-jtag-ew.c:525
int bitbang_execute_queue(struct jtag_command *cmd_queue)
Definition: bitbang.c:293
const struct swd_driver bitbang_swd
Definition: bitbang.c:614
bb_value
Definition: bitbang.h:17
@ BB_LOW
Definition: bitbang.h:18
@ BB_HIGH
Definition: bitbang.h:19
static uint16_t direction
Definition: ftdi.c:120
#define DEBUG_CAP_TMS_SEQ
Definition: interface.h:188
bool transport_is_jtag(void)
Returns true if the current debug session is using JTAG as its transport.
Definition: jtag/core.c:1840
#define ERROR_JTAG_INIT_FAILED
Definition: jtag.h:552
static int linuxgpiod_quit(void)
Definition: linuxgpiod.c:583
static bool last_stored
Definition: linuxgpiod.c:297
static int linuxgpiod_blink(bool on)
Definition: linuxgpiod.c:489
struct adapter_driver linuxgpiod_adapter_driver
Definition: linuxgpiod.c:768
static void helper_release(enum adapter_gpio_config_index idx)
Definition: linuxgpiod.c:563
static int last_swclk
Definition: linuxgpiod.c:295
static bool linuxgpiod_jtag_mode_possible(void)
Definition: linuxgpiod.c:541
static bool is_gpio_config_valid(enum adapter_gpio_config_index idx)
Definition: linuxgpiod.c:322
static const struct bitbang_interface linuxgpiod_bitbang
Definition: linuxgpiod.c:502
static int linuxgpiod_line_set_value(enum adapter_gpio_config_index idx, int value)
Definition: linuxgpiod.c:309
static struct gpiod_line_settings * gpiod_line_settings[ADAPTER_GPIO_IDX_NUM]
Definition: linuxgpiod.c:291
static int linuxgpiod_line_get_value(enum adapter_gpio_config_index idx)
Definition: linuxgpiod.c:303
static struct jtag_interface linuxgpiod_interface
Definition: linuxgpiod.c:763
static int linuxgpiod_swdio_read(void)
Definition: linuxgpiod.c:391
static struct gpiod_line_request * gpiod_line_req[ADAPTER_GPIO_IDX_NUM]
Definition: linuxgpiod.c:293
static int helper_get_line(enum adapter_gpio_config_index idx)
Definition: linuxgpiod.c:592
static enum bb_value linuxgpiod_read(void)
Definition: linuxgpiod.c:329
static const struct adapter_gpio_config * adapter_gpio_config
Definition: linuxgpiod.c:300
static void linuxgpiod_swdio_drive(bool is_output)
Definition: linuxgpiod.c:404
static int linuxgpiod_write(int tck, int tms, int tdi)
Definition: linuxgpiod.c:348
static int last_swdio
Definition: linuxgpiod.c:296
static bool swdio_input
Definition: linuxgpiod.c:298
static struct gpiod_chip * gpiod_chip[ADAPTER_GPIO_IDX_NUM]
Definition: linuxgpiod.c:290
static struct gpiod_line_config * gpiod_line_config[ADAPTER_GPIO_IDX_NUM]
Definition: linuxgpiod.c:292
static int linuxgpiod_swd_write(int swclk, int swdio)
Definition: linuxgpiod.c:463
static int linuxgpiod_reset(int trst, int srst)
Definition: linuxgpiod.c:516
static int linuxgpiod_init(void)
Definition: linuxgpiod.c:698
static bool linuxgpiod_swd_mode_possible(void)
Definition: linuxgpiod.c:554
#define LOG_WARNING(expr ...)
Definition: log.h:130
#define ERROR_FAIL
Definition: log.h:174
#define LOG_ERROR(expr ...)
Definition: log.h:133
#define LOG_INFO(expr ...)
Definition: log.h:127
#define LOG_DEBUG(expr ...)
Definition: log.h:110
#define ERROR_OK
Definition: log.h:168
struct qn908x_flash_bank __attribute__
Definition: armv8.c:1054
Represents a driver for a debugging interface.
Definition: interface.h:208
const char *const name
The name of the interface driver.
Definition: interface.h:210
Configuration options for a single GPIO.
Definition: adapter.h:68
unsigned int gpio_num
Definition: adapter.h:69
unsigned int chip_num
Definition: adapter.h:70
Low level callbacks (for bitbang).
Definition: bitbang.h:30
enum bb_value(* read)(void)
Sample TDO and return the value.
Definition: bitbang.h:32
Represents a driver for a debugging interface.
Definition: interface.h:183
unsigned int supported
Bit vector listing capabilities exposed by this driver.
Definition: interface.h:187
#define TRANSPORT_SWD
Definition: transport.h:20
#define TRANSPORT_JTAG
Definition: transport.h:19
#define NULL
Definition: usb.h:16
uint8_t offset[4]
Definition: vdebug.c:9