This is an automated email from Gerrit.

"Steve Marple <stevemar...@googlemail.com>" just uploaded a new patch set to 
Gerrit, which you can find at https://review.openocd.org/c/openocd/+/6984

-- gerrit

commit 9ad4a92d1276a912f4533581b34345f89f1e139e
Author: Steve Marple <stevemar...@googlemail.com>
Date:   Tue May 17 21:51:17 2022 +0100

    RFC: drivers/am335xgpio: Migrate to adapter gpio commands
    
    Use the new "adapter gpio" commands to configure the GPIOs used by the
    am335xgpio driver.
    
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Publishing early with fewer changes for easier review and rework. Only
    the LED GPIO has been migrated.
    
    TODO
    * Migrate all GPIOs to use the "adapter gpio" commands.
    * Rename x_NEW() functions to x() when all GPIOS have been migrated.
    * Add documentation when interface is stable.
    
    QUESTIONS
    * Should all GPIOs have a drive mode? The "reset_config" allows it to be
    defined for SRST and TRST. How would conflicts between "reset_config
    srst_open_drain" and "adapter gpio srst -open-drain" be resolved?
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    Change-Id: I7c63c0e4763657ea51790c43fc40d32b7c3580bb
    Signed-off-by: Steve Marple <stevemar...@googlemail.com>

diff --git a/src/jtag/drivers/am335xgpio.c b/src/jtag/drivers/am335xgpio.c
index e04c44c8e4..5f4808cf86 100644
--- a/src/jtag/drivers/am335xgpio.c
+++ b/src/jtag/drivers/am335xgpio.c
@@ -21,6 +21,7 @@
 #include "config.h"
 #endif
 
+#include <jtag/adapter.h>
 #include <jtag/interface.h>
 #include <transport/transport.h>
 #include "bitbang.h"
@@ -31,6 +32,7 @@
  * GPIO register base addresses. Values taken from "AM335x and AMIC110 Sitara
  * Processors Technical Reference Manual", Chapter 2 Memory Map.
  */
+#define AM335XGPIO_NUM_GPIO_PER_PORT 32
 #define AM335XGPIO_NUM_GPIO_PORTS 4
 #define AM335XGPIO_GPIO0_HW_ADDR 0x44E07000
 #define AM335XGPIO_GPIO1_HW_ADDR 0x4804C000
@@ -51,21 +53,21 @@
  * that module. GPIOs 0 to 31 map to GPIO0, 32 to 63 to GPIO1 etc. This scheme
  * matches that used by Linux on the BeagleBone.
  */
-#define AM335XGPIO_PORT_NUM(gpio_num) ((gpio_num) / 32)
-#define AM335XGPIO_BIT_NUM(gpio_num) ((gpio_num) % 32)
-#define AM335XGPIO_BIT_MASK(gpio_num) BIT(AM335XGPIO_BIT_NUM(gpio_num))
+#define AM335XGPIO_PORT_NUM(gpio_num) ((gpio_num) / 32) /* TODO: remove when 
all GPIOs ported to adapter commands */
+#define AM335XGPIO_BIT_NUM(gpio_num) ((gpio_num) % 32) /* TODO: remove when 
all GPIOs ported to adapter commands */
+#define AM335XGPIO_BIT_MASK(gpio_num) BIT(AM335XGPIO_BIT_NUM(gpio_num)) /* 
TODO: remove when ported to adapter cmds */
 
-#define AM335XGPIO_READ_REG(gpio_num, offset) \
-       (*(am335xgpio_gpio_port_mmap_addr[AM335XGPIO_PORT_NUM(gpio_num)] + 
(offset)))
+#define AM335XGPIO_READ_REG(chip_num, offset) \
+       (*(am335xgpio_gpio_port_mmap_addr[chip_num] + (offset)))
 
-#define AM335XGPIO_WRITE_REG(gpio_num, offset, value) \
-       (*(am335xgpio_gpio_port_mmap_addr[AM335XGPIO_PORT_NUM(gpio_num)] + 
(offset)) = (value))
+#define AM335XGPIO_WRITE_REG(chip_num, offset, value) \
+       (*(am335xgpio_gpio_port_mmap_addr[chip_num] + (offset)) = (value))
 
-#define AM335XGPIO_SET_REG_BITS(gpio_num, offset, bit_mask) \
-       (*(am335xgpio_gpio_port_mmap_addr[AM335XGPIO_PORT_NUM(gpio_num)] + 
(offset)) |= (bit_mask))
+#define AM335XGPIO_SET_REG_BITS(chip_num, offset, bit_mask) \
+       (*(am335xgpio_gpio_port_mmap_addr[chip_num] + (offset)) |= (bit_mask))
 
-#define AM335XGPIO_CLEAR_REG_BITS(gpio_num, offset, bit_mask) \
-       (*(am335xgpio_gpio_port_mmap_addr[AM335XGPIO_PORT_NUM(gpio_num)] + 
(offset)) &= ~(bit_mask))
+#define AM335XGPIO_CLEAR_REG_BITS(chip_num, offset, bit_mask) \
+       (*(am335xgpio_gpio_port_mmap_addr[chip_num] + (offset)) &= ~(bit_mask))
 
 enum amx335gpio_gpio_mode {
        AM335XGPIO_GPIO_MODE_INPUT,
@@ -105,43 +107,67 @@ static int swdio_gpio = -1;
 static enum amx335gpio_gpio_mode swdio_gpio_mode;
 static int swdio_dir_gpio = -1;
 static enum amx335gpio_gpio_mode swdio_dir_gpio_mode;
-static int led_gpio = -1;
-static enum amx335gpio_gpio_mode led_gpio_mode = -1;
+static enum amx335gpio_gpio_mode led_gpio_mode;
 
 static bool swdio_dir_is_active_high = true; /* Active state means output */
-static bool led_is_active_high = true;
 
 /* Transition delay coefficients */
 static int speed_coeff = 600000;
 static int speed_offset = 575;
 static unsigned int jtag_delay;
 
+static void set_gpio_value_NEW(const struct adapter_gpio_config *gpio_config, 
int value);
+
 static int is_gpio_valid(int gpio_num)
 {
        return gpio_num >= 0 && gpio_num < (32 * AM335XGPIO_NUM_GPIO_PORTS);
 }
 
+static bool is_gpio_config_valid(const struct adapter_gpio_config *gpio_config)
+{
+       return gpio_config->chip_num >= 0
+               && gpio_config->chip_num < AM335XGPIO_NUM_GPIO_PORTS
+               && gpio_config->gpio_num >= 0
+               && gpio_config->gpio_num < AM335XGPIO_NUM_GPIO_PER_PORT;
+}
+
 static int get_gpio_value(int gpio_num)
 {
        unsigned int shift = AM335XGPIO_BIT_NUM(gpio_num);
-       return (AM335XGPIO_READ_REG(gpio_num, AM335XGPIO_GPIO_DATAIN_OFFSET) >> 
shift) & 1;
+       return (AM335XGPIO_READ_REG(AM335XGPIO_PORT_NUM(gpio_num), 
AM335XGPIO_GPIO_DATAIN_OFFSET) >> shift) & 1;
 }
 
 static void set_gpio_value(int gpio_num, int value)
 {
        if (value)
-               AM335XGPIO_WRITE_REG(gpio_num, 
AM335XGPIO_GPIO_SETDATAOUT_OFFSET, AM335XGPIO_BIT_MASK(gpio_num));
+               AM335XGPIO_WRITE_REG(AM335XGPIO_PORT_NUM(gpio_num), 
AM335XGPIO_GPIO_SETDATAOUT_OFFSET,
+                               AM335XGPIO_BIT_MASK(gpio_num));
        else
-               AM335XGPIO_WRITE_REG(gpio_num, 
AM335XGPIO_GPIO_CLEARDATAOUT_OFFSET, AM335XGPIO_BIT_MASK(gpio_num));
+               AM335XGPIO_WRITE_REG(AM335XGPIO_PORT_NUM(gpio_num), 
AM335XGPIO_GPIO_CLEARDATAOUT_OFFSET,
+                               AM335XGPIO_BIT_MASK(gpio_num));
 }
 
 static enum amx335gpio_gpio_mode get_gpio_mode(int gpio_num)
 {
-       if (AM335XGPIO_READ_REG(gpio_num, AM335XGPIO_GPIO_OE_OFFSET) & 
AM335XGPIO_BIT_MASK(gpio_num)) {
+       if (AM335XGPIO_READ_REG(AM335XGPIO_PORT_NUM(gpio_num), 
AM335XGPIO_GPIO_OE_OFFSET) & AM335XGPIO_BIT_MASK(gpio_num)) {
+               return AM335XGPIO_GPIO_MODE_INPUT;
+       } else {
+               /* Return output level too so that pin mode can be fully 
restored */
+               if (AM335XGPIO_READ_REG(AM335XGPIO_PORT_NUM(gpio_num),
+                                       AM335XGPIO_GPIO_DATAOUT_OFFSET) & 
AM335XGPIO_BIT_MASK(gpio_num))
+                       return AM335XGPIO_GPIO_MODE_OUTPUT_HIGH;
+               else
+                       return AM335XGPIO_GPIO_MODE_OUTPUT_LOW;
+       }
+}
+
+static enum amx335gpio_gpio_mode get_gpio_mode_NEW(const struct 
adapter_gpio_config *gpio_config)
+{
+       if (AM335XGPIO_READ_REG(gpio_config->chip_num, 
AM335XGPIO_GPIO_OE_OFFSET) & BIT(gpio_config->gpio_num)) {
                return AM335XGPIO_GPIO_MODE_INPUT;
        } else {
                /* Return output level too so that pin mode can be fully 
restored */
-               if (AM335XGPIO_READ_REG(gpio_num, 
AM335XGPIO_GPIO_DATAOUT_OFFSET) & AM335XGPIO_BIT_MASK(gpio_num))
+               if (AM335XGPIO_READ_REG(gpio_config->chip_num, 
AM335XGPIO_GPIO_DATAOUT_OFFSET) & BIT(gpio_config->gpio_num))
                        return AM335XGPIO_GPIO_MODE_OUTPUT_HIGH;
                else
                        return AM335XGPIO_GPIO_MODE_OUTPUT_LOW;
@@ -151,7 +177,8 @@ static enum amx335gpio_gpio_mode get_gpio_mode(int gpio_num)
 static void set_gpio_mode(int gpio_num, enum amx335gpio_gpio_mode gpio_mode)
 {
        if (gpio_mode == AM335XGPIO_GPIO_MODE_INPUT) {
-               AM335XGPIO_SET_REG_BITS(gpio_num, AM335XGPIO_GPIO_OE_OFFSET, 
AM335XGPIO_BIT_MASK(gpio_num));
+               AM335XGPIO_SET_REG_BITS(AM335XGPIO_PORT_NUM(gpio_num),
+                               AM335XGPIO_GPIO_OE_OFFSET, 
AM335XGPIO_BIT_MASK(gpio_num));
                return;
        }
 
@@ -163,7 +190,27 @@ static void set_gpio_mode(int gpio_num, enum 
amx335gpio_gpio_mode gpio_mode)
        if (gpio_mode == AM335XGPIO_GPIO_MODE_OUTPUT ||
                gpio_mode == AM335XGPIO_GPIO_MODE_OUTPUT_LOW ||
                gpio_mode == AM335XGPIO_GPIO_MODE_OUTPUT_HIGH) {
-                       AM335XGPIO_CLEAR_REG_BITS(gpio_num, 
AM335XGPIO_GPIO_OE_OFFSET, AM335XGPIO_BIT_MASK(gpio_num));
+                       AM335XGPIO_CLEAR_REG_BITS(AM335XGPIO_PORT_NUM(gpio_num),
+                                       AM335XGPIO_GPIO_OE_OFFSET, 
AM335XGPIO_BIT_MASK(gpio_num));
+       }
+}
+
+static void set_gpio_mode_NEW(const struct adapter_gpio_config *gpio_config, 
enum amx335gpio_gpio_mode gpio_mode)
+{
+       if (gpio_mode == AM335XGPIO_GPIO_MODE_INPUT) {
+               AM335XGPIO_SET_REG_BITS(gpio_config->chip_num, 
AM335XGPIO_GPIO_OE_OFFSET, BIT(gpio_config->gpio_num));
+               return;
+       }
+
+       if (gpio_mode == AM335XGPIO_GPIO_MODE_OUTPUT_LOW)
+               set_gpio_value_NEW(gpio_config, 0);
+       if (gpio_mode == AM335XGPIO_GPIO_MODE_OUTPUT_HIGH)
+               set_gpio_value_NEW(gpio_config, 1);
+
+       if (gpio_mode == AM335XGPIO_GPIO_MODE_OUTPUT ||
+               gpio_mode == AM335XGPIO_GPIO_MODE_OUTPUT_LOW ||
+               gpio_mode == AM335XGPIO_GPIO_MODE_OUTPUT_HIGH) {
+                       AM335XGPIO_CLEAR_REG_BITS(gpio_config->chip_num, 
AM335XGPIO_GPIO_OE_OFFSET, BIT(gpio_config->gpio_num));
        }
 }
 
@@ -183,6 +230,35 @@ static const char *get_gpio_mode_name(enum 
amx335gpio_gpio_mode gpio_mode)
        }
 }
 
+static void set_gpio_value_NEW(const struct adapter_gpio_config *gpio_config, 
int value)
+{
+       value = value ^ gpio_config->active_low;
+       switch (gpio_config->drive) {
+       case ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL:
+               if (value)
+                       AM335XGPIO_WRITE_REG(gpio_config->chip_num, 
AM335XGPIO_GPIO_SETDATAOUT_OFFSET,
+                                       
AM335XGPIO_BIT_MASK(gpio_config->gpio_num));
+               else
+                       AM335XGPIO_WRITE_REG(gpio_config->chip_num, 
AM335XGPIO_GPIO_CLEARDATAOUT_OFFSET,
+                                       
AM335XGPIO_BIT_MASK(gpio_config->gpio_num));
+               break;
+       case ADAPTER_GPIO_DRIVE_MODE_OPEN_DRAIN:
+               if (value)
+                       set_gpio_mode_NEW(gpio_config, 
AM335XGPIO_GPIO_MODE_INPUT);
+               else
+                       AM335XGPIO_WRITE_REG(gpio_config->chip_num, 
AM335XGPIO_GPIO_CLEARDATAOUT_OFFSET,
+                                       
AM335XGPIO_BIT_MASK(gpio_config->gpio_num));
+               break;
+       case ADAPTER_GPIO_DRIVE_MODE_OPEN_SOURCE:
+               if (value)
+                       AM335XGPIO_WRITE_REG(gpio_config->chip_num, 
AM335XGPIO_GPIO_SETDATAOUT_OFFSET,
+                                       
AM335XGPIO_BIT_MASK(gpio_config->gpio_num));
+               else
+                       set_gpio_mode_NEW(gpio_config, 
AM335XGPIO_GPIO_MODE_INPUT);
+               break;
+       }
+}
+
 static bb_value_t am335xgpio_read(void)
 {
        return get_gpio_value(tdo_gpio) ? BB_HIGH : BB_LOW;
@@ -255,8 +331,9 @@ static int am335xgpio_swdio_read(void)
 
 static int am335xgpio_blink(int on)
 {
-       if (is_gpio_valid(led_gpio))
-               set_gpio_value(led_gpio, (!on ^ led_is_active_high) ? 1 : 0);
+       const struct adapter_gpio_config *led_gpio_config = 
adapter_get_gpio_config(ADAPTER_GPIO_IDX_LED);
+       if (is_gpio_config_valid(led_gpio_config))
+               set_gpio_value_NEW(led_gpio_config, (on ^ 
led_gpio_config->active_low) ? 1 : 0);
 
        return ERROR_OK;
 }
@@ -414,24 +491,6 @@ COMMAND_HANDLER(am335xgpio_handle_swd_dir_output_state)
        return ERROR_OK;
 }
 
-COMMAND_HANDLER(am335xgpio_handle_gpionum_led)
-{
-       if (CMD_ARGC == 1)
-               COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], led_gpio);
-
-       command_print(CMD, "AM335x GPIO config: led = %d", led_gpio);
-       return ERROR_OK;
-}
-
-COMMAND_HANDLER(am335xgpio_handle_led_on_state)
-{
-       if (CMD_ARGC == 1)
-               COMMAND_PARSE_BOOL(CMD_ARGV[0], led_is_active_high, "high", 
"low");
-
-       command_print(CMD, "AM335x GPIO config: led_on_state = %s", 
led_is_active_high ? "high" : "low");
-       return ERROR_OK;
-}
-
 COMMAND_HANDLER(am335xgpio_handle_speed_coeffs)
 {
        if (CMD_ARGC == 2) {
@@ -529,20 +588,6 @@ static const struct command_registration 
am335xgpio_subcommand_handlers[] = {
                .help = "gpio number for trst.",
                .usage = "[trst]",
        },
-       {
-               .name = "led_num",
-               .handler = am335xgpio_handle_gpionum_led,
-               .mode = COMMAND_CONFIG,
-               .help = "gpio number for led.",
-               .usage = "[led]",
-       },
-       {
-               .name = "led_on_state",
-               .handler = am335xgpio_handle_led_on_state,
-               .mode = COMMAND_CONFIG,
-               .help = "required state for led pin to turn on LED.",
-               .usage = "['off'|'on']",
-       },
        {
                .name = "speed_coeffs",
                .handler = am335xgpio_handle_speed_coeffs,
@@ -595,6 +640,7 @@ static bool am335xgpio_swd_mode_possible(void)
 
 static int am335xgpio_init(void)
 {
+       const struct adapter_gpio_config *led_gpio_config = 
adapter_get_gpio_config(ADAPTER_GPIO_IDX_LED);
        bitbang_interface = &am335xgpio_bitbang;
 
        LOG_INFO("AM335x GPIO JTAG/SWD bitbang driver");
@@ -677,11 +723,13 @@ static int am335xgpio_init(void)
                LOG_DEBUG("saved GPIO mode for srst (GPIO #%d): %s", srst_gpio, 
get_gpio_mode_name(srst_gpio_mode));
        }
 
-       if (is_gpio_valid(led_gpio)) {
-               led_gpio_mode = get_gpio_mode(led_gpio);
-               LOG_DEBUG("saved GPIO mode for led (GPIO #%d): %s", led_gpio, 
get_gpio_mode_name(led_gpio_mode));
-               set_gpio_mode(led_gpio,
-                               led_is_active_high ? 
AM335XGPIO_GPIO_MODE_OUTPUT_LOW : AM335XGPIO_GPIO_MODE_OUTPUT_HIGH);
+       if (is_gpio_config_valid(led_gpio_config)) {
+               led_gpio_mode = get_gpio_mode_NEW(led_gpio_config);
+               LOG_DEBUG("saved GPIO mode for led (GPIO %d %d): %s",
+                               led_gpio_config->chip_num, 
led_gpio_config->gpio_num, get_gpio_mode_name(led_gpio_mode));
+               set_gpio_mode_NEW(led_gpio_config,
+                               (led_gpio_config->active_low ^ 
led_gpio_config->init_active)
+                                       ? AM335XGPIO_GPIO_MODE_OUTPUT_HIGH : 
AM335XGPIO_GPIO_MODE_OUTPUT_LOW);
        }
 
        /* Set GPIO modes for TRST and SRST and make both inactive */
@@ -691,6 +739,8 @@ static int am335xgpio_init(void)
 
 static int am335xgpio_quit(void)
 {
+       const struct adapter_gpio_config *led_gpio_config = 
adapter_get_gpio_config(ADAPTER_GPIO_IDX_LED);
+
        if (transport_is_jtag()) {
                set_gpio_mode(tdo_gpio, tdo_gpio_mode);
                set_gpio_mode(tdi_gpio, tdi_gpio_mode);
@@ -710,8 +760,8 @@ static int am335xgpio_quit(void)
        if (is_gpio_valid(srst_gpio))
                set_gpio_mode(srst_gpio, srst_gpio_mode);
 
-       if (is_gpio_valid(led_gpio))
-               set_gpio_mode(led_gpio, led_gpio_mode);
+       if (is_gpio_config_valid(led_gpio_config))
+               set_gpio_mode_NEW(led_gpio_config, led_gpio_mode);
 
        return ERROR_OK;
 }

-- 

Reply via email to