Add 'gpio' command and enable it by default
authorPiotr Dymacz <pepe2k@gmail.com>
Fri, 11 Aug 2017 11:39:09 +0000 (13:39 +0200)
committerPiotr Dymacz <pepe2k@gmail.com>
Fri, 11 Aug 2017 11:49:40 +0000 (13:49 +0200)
This adds 'gpio' command, which allows to manipulate GPIO subsystem:
 - change direction
 - change output value
 - read input value (useful for scripts)
 - enable/disable JTAG
 - manage special/dedicated GPIO functions
 - list current configuration and available functions

For QCA95xx series, this allows full management of GPIO output and
input functionalities (mux). For AR933x, due to its capabilities,
function management is more simple and allows only enabling or
disabling selected bits in GPIO_FUNCTION_{1,2} registers.

Example commands:
 - list GPIO configuration:   gpio l
 - list available functions:  gpio l f
 - set GPIO10 output to high: gpio s 10
 - get GPIO10 input value:    gpio i 10

u-boot/common/Makefile
u-boot/common/cmd_qcagpio.c [new file with mode: 0644]
u-boot/include/cmd_qcagpio.h [new file with mode: 0644]
u-boot/include/configs/qca9k_common.h

index f22b1c4777ca530a260eaec67f36405f93391ef8..6df605b9c318f9ef39ddc215608ed361cad02c4b 100644 (file)
@@ -38,6 +38,7 @@ COBJS = main.o \
                  cmd_itest.o \
                  cmd_load.o \
                  cmd_qcaclk.o \
+                 cmd_qcagpio.o \
                  command.o \
                  console.o \
                  devices.o \
diff --git a/u-boot/common/cmd_qcagpio.c b/u-boot/common/cmd_qcagpio.c
new file mode 100644 (file)
index 0000000..460905e
--- /dev/null
@@ -0,0 +1,758 @@
+/*
+ * Copyright (C) 2017 Piotr Dymacz <piotr@dymacz.pl>
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <config.h>
+#include <common.h>
+#include <command.h>
+#include <cmd_qcagpio.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <linux/ctype.h>
+
+#if defined(CONFIG_CMD_GPIO)
+
+#define _GPIO_OUT_MUX_MAX      127
+#define _GPIO_NUM_MAX          (QCA_GPIO_COUNT - 1)
+
+#if (SOC_TYPE & QCA_AR933X_SOC)
+static void gpio_set_func(u32 func, u32 enable)
+{
+       u32 val;
+
+       if (func < gpio_funcs_1_cnt) {
+               val = qca_soc_reg_read(QCA_GPIO_FUNC_1_REG);
+
+               if (enable)
+                       val |= gpio_funcs_1[func].reg_mask;
+               else
+                       val &= ~gpio_funcs_1[func].reg_mask;
+
+               qca_soc_reg_write(QCA_GPIO_FUNC_1_REG, val);
+
+               return;
+       }
+
+       func -= gpio_funcs_1_cnt;
+       val = qca_soc_reg_read(QCA_GPIO_FUNC_2_REG);
+
+       if (enable)
+               val |= gpio_funcs_2[func].reg_mask;
+       else
+               val &= ~gpio_funcs_2[func].reg_mask;
+
+       qca_soc_reg_write(QCA_GPIO_FUNC_2_REG, val);
+}
+#else
+static void gpio_func_gate(u8 disable, u8 enable)
+{
+       u32 val;
+
+       switch (disable) {
+       case QCA_GPIO_OUT_MUX_CLK_OBS0_VAL:
+               val = QCA_GPIO_FUNC_CLK_OBS0_EN_MASK;
+               break;
+       case QCA_GPIO_OUT_MUX_CLK_OBS1_VAL:
+               val = QCA_GPIO_FUNC_CLK_OBS1_EN_MASK;
+               break;
+       case QCA_GPIO_OUT_MUX_CLK_OBS2_VAL:
+               val = QCA_GPIO_FUNC_CLK_OBS2_EN_MASK;
+               break;
+       case QCA_GPIO_OUT_MUX_CLK_OBS3_VAL:
+               val = QCA_GPIO_FUNC_CLK_OBS3_EN_MASK;
+               break;
+       case QCA_GPIO_OUT_MUX_CLK_OBS4_VAL:
+               val = QCA_GPIO_FUNC_CLK_OBS4_EN_MASK;
+               break;
+       case QCA_GPIO_OUT_MUX_CLK_OBS5_VAL:
+               val = QCA_GPIO_FUNC_CLK_OBS5_EN_MASK;
+               break;
+#if (SOC_TYPE & QCA_AR934X_SOC)  ||\
+    (SOC_TYPE & QCA_QCA953X_SOC) ||\
+    (SOC_TYPE & QCA_QCA956X_SOC)
+       case QCA_GPIO_OUT_MUX_CLK_OBS6_VAL:
+               val = QCA_GPIO_FUNC_CLK_OBS6_EN_MASK;
+               break;
+#endif
+#if (SOC_TYPE & QCA_AR934X_SOC)
+       case QCA_GPIO_OUT_MUX_CLK_OBS7_VAL:
+               val = QCA_GPIO_FUNC_CLK_OBS7_EN_MASK;
+               break;
+#endif
+#if (SOC_TYPE & QCA_QCA953X_SOC) ||\
+    (SOC_TYPE & QCA_QCA955X_SOC) ||\
+    (SOC_TYPE & QCA_QCA956X_SOC)
+       case QCA_GPIO_OUT_MUX_SRIF_OUT_VAL:
+               val = QCA_GPIO_FUNC_GPIO_SRIF_EN_MASK;
+               break;
+#endif
+       default:
+               val = 0;
+               break;
+       }
+
+       if (val)
+               qca_soc_reg_read_clear(QCA_GPIO_FUNC_REG, val);
+
+       switch (enable) {
+       case QCA_GPIO_OUT_MUX_CLK_OBS0_VAL:
+               val = QCA_GPIO_FUNC_CLK_OBS0_EN_MASK;
+               break;
+       case QCA_GPIO_OUT_MUX_CLK_OBS1_VAL:
+               val = QCA_GPIO_FUNC_CLK_OBS1_EN_MASK;
+               break;
+       case QCA_GPIO_OUT_MUX_CLK_OBS2_VAL:
+               val = QCA_GPIO_FUNC_CLK_OBS2_EN_MASK;
+               break;
+       case QCA_GPIO_OUT_MUX_CLK_OBS3_VAL:
+               val = QCA_GPIO_FUNC_CLK_OBS3_EN_MASK;
+               break;
+       case QCA_GPIO_OUT_MUX_CLK_OBS4_VAL:
+               val = QCA_GPIO_FUNC_CLK_OBS4_EN_MASK;
+               break;
+       case QCA_GPIO_OUT_MUX_CLK_OBS5_VAL:
+               val = QCA_GPIO_FUNC_CLK_OBS5_EN_MASK;
+               break;
+#if (SOC_TYPE & QCA_AR934X_SOC)  ||\
+    (SOC_TYPE & QCA_QCA953X_SOC) ||\
+    (SOC_TYPE & QCA_QCA956X_SOC)
+       case QCA_GPIO_OUT_MUX_CLK_OBS6_VAL:
+               val = QCA_GPIO_FUNC_CLK_OBS6_EN_MASK;
+               break;
+#endif
+#if (SOC_TYPE & QCA_AR934X_SOC)
+       case QCA_GPIO_OUT_MUX_CLK_OBS7_VAL:
+               val = QCA_GPIO_FUNC_CLK_OBS7_EN_MASK;
+               break;
+#endif
+#if (SOC_TYPE & QCA_QCA953X_SOC) ||\
+    (SOC_TYPE & QCA_QCA955X_SOC) ||\
+    (SOC_TYPE & QCA_QCA956X_SOC)
+       case QCA_GPIO_OUT_MUX_SRIF_OUT_VAL:
+               val = QCA_GPIO_FUNC_GPIO_SRIF_EN_MASK;
+               break;
+#endif
+       default:
+               val = 0;
+               break;
+       }
+
+       if (val)
+               qca_soc_reg_read_set(QCA_GPIO_FUNC_REG, val);
+}
+
+static u32 gpio_in_func_to_gpio(u8 func)
+{
+       u32 val, reg, shift;
+
+       if (func > (gpio_in_funcs_cnt - 1))
+               return _GPIO_OUT_MUX_MAX;
+
+       reg = QCA_GPIO_IN_EN0_REG + (4 * (gpio_in_funcs[func].offset / 4));
+       shift = 8 * (gpio_in_funcs[func].offset % 4);
+
+       val = qca_soc_reg_read(reg);
+       val &= (0xff << shift);
+       val = val >> shift;
+
+       return val;
+}
+
+static u8 gpio_get_out_func(u32 gpio_num)
+{
+       u32 val, reg, shift;
+
+       reg = QCA_GPIO_OUT_FUNC0_REG + (4 * (gpio_num / 4));
+       shift = 8 * (gpio_num % 4);
+
+       val = qca_soc_reg_read(reg);
+       val &= (0xff << shift);
+       val = val >> shift;
+
+       return (u8)val;
+}
+
+static void gpio_set_in_out_func(u32 gpio_num, u8 func, u32 output)
+{
+       u32 val, reg, shift;
+
+       if (output) {
+               reg = QCA_GPIO_OUT_FUNC0_REG + (4 * (gpio_num / 4));
+               shift = 8 * (gpio_num % 4);
+       } else {
+               if (func > (gpio_in_funcs_cnt - 1))
+                       return;
+
+               reg = QCA_GPIO_IN_EN0_REG + (4 * (gpio_in_funcs[func].offset / 4));
+               shift = 8 * (gpio_in_funcs[func].offset % 4);
+       }
+
+       val = qca_soc_reg_read(reg);
+       val &= ~(0xff << shift);
+
+       if (output)
+               val |= (func << shift);
+       else
+               val |= (gpio_num << shift);
+
+       qca_soc_reg_write(reg, val);
+}
+#endif /* SOC_TYPE & QCA_AR933X_SOC */
+
+static void gpio_set_jtag(u32 enable)
+{
+#if (SOC_TYPE & QCA_AR933X_SOC)
+       if (enable)
+               qca_soc_reg_read_clear(QCA_GPIO_FUNC_1_REG,
+                                      QCA_GPIO_FUNC_1_JTAG_DIS_MASK);
+       else
+               qca_soc_reg_read_set(QCA_GPIO_FUNC_1_REG,
+                                    QCA_GPIO_FUNC_1_JTAG_DIS_MASK);
+#else
+       if (enable)
+               qca_soc_reg_read_clear(QCA_GPIO_FUNC_REG,
+                                      QCA_GPIO_FUNC_JTAG_DIS_MASK);
+       else
+               qca_soc_reg_read_set(QCA_GPIO_FUNC_REG,
+                                    QCA_GPIO_FUNC_JTAG_DIS_MASK);
+#endif
+}
+
+static void gpio_set_val(u32 gpio_mask, u32 high)
+{
+       if (high)
+               qca_soc_reg_write(QCA_GPIO_SET_REG, gpio_mask);
+       else
+               qca_soc_reg_write(QCA_GPIO_CLEAR_REG, gpio_mask);
+}
+
+static void gpio_set_dir(u32 gpio_mask, u32 output)
+{
+       if (gpio_mask & QCA_GPIO_JTAG_MASK)
+               gpio_set_jtag(0);
+
+#if (SOC_TYPE & QCA_AR933X_SOC) ||\
+    (SOC_TYPE & QCA_QCA955X_SOC)
+       if (output)
+               qca_soc_reg_read_set(QCA_GPIO_OE_REG, gpio_mask);
+       else
+               qca_soc_reg_read_clear(QCA_GPIO_OE_REG, gpio_mask);
+#else
+       if (output)
+               qca_soc_reg_read_clear(QCA_GPIO_OE_REG, gpio_mask);
+       else
+               qca_soc_reg_read_set(QCA_GPIO_OE_REG, gpio_mask);
+#endif
+}
+
+static void gpio_list_cfg(void)
+{
+       u32 gpio_in_reg, gpio_out_reg, gpio_oe_reg;
+       u32 gpio_num, gpio_mask;
+       u32 output, val;
+       u32 jtag_en = 1;
+
+#if (SOC_TYPE & ~QCA_AR933X_SOC)
+       u8 func, i;
+#endif
+
+#if defined(CONFIG_QCA_GPIO_MASK_OUT_INIT_H) ||\
+    defined(CONFIG_QCA_GPIO_MASK_OUT_INIT_L) ||\
+    defined(CONFIG_QCA_GPIO_MASK_LED_ACT_H)  ||\
+    defined(CONFIG_QCA_GPIO_MASK_LED_ACT_L)
+       u32 mask_h = 0, mask_l = 0;
+#endif
+
+       puts("\n");
+#if (SOC_TYPE & ~QCA_AR933X_SOC)
+       puts("   # | DIR | VAL | DEF | LED | BTN | JTAG | FUNCTION\n"
+            " ----+-----+-----+-----+-----+-----+------+----------\n");
+#else
+       puts("   # | DIR | VAL | DEF | LED | BTN | JTAG\n"
+            " ----+-----+-----+-----+-----+-----+------\n");
+#endif
+
+       gpio_oe_reg  = qca_soc_reg_read(QCA_GPIO_OE_REG);
+       gpio_in_reg  = qca_soc_reg_read(QCA_GPIO_IN_REG);
+       gpio_out_reg = qca_soc_reg_read(QCA_GPIO_OUT_REG);
+
+#if (SOC_TYPE & QCA_AR933X_SOC)
+       val = qca_soc_reg_read(QCA_GPIO_FUNC_1_REG);
+       if (val & QCA_GPIO_FUNC_1_JTAG_DIS_MASK)
+               jtag_en = 0;
+#else
+       val = qca_soc_reg_read(QCA_GPIO_FUNC_REG);
+       if (val & QCA_GPIO_FUNC_JTAG_DIS_MASK)
+               jtag_en = 0;
+#endif
+
+       for (gpio_num = 0; gpio_num < QCA_GPIO_COUNT; gpio_num++) {
+               gpio_mask = (1 << gpio_num);
+
+               /* GPIO number */
+               printf("%4d", gpio_num);
+               puts(" | ");
+
+#if (SOC_TYPE & QCA_AR933X_SOC) ||\
+    (SOC_TYPE & QCA_QCA955X_SOC)
+               output = 0;
+               if (gpio_mask & gpio_oe_reg)
+                       output = 1;
+#else
+               output = 1;
+               if (gpio_mask & gpio_oe_reg)
+                       output = 0;
+#endif
+
+               /* GPIO direction */
+               if (output) {
+                       printf("%-3s", "out");
+                       val = gpio_mask & gpio_out_reg;
+               } else {
+                       printf("%-3s", "in");
+                       val = gpio_mask & gpio_in_reg;
+               }
+
+               puts(" | ");
+
+               /* GPIO value */
+               if (val)
+                       printf("%-3s", "hi");
+               else
+                       printf("%-3s", "lo");
+
+               puts(" | ");
+
+               /* GPIO default value */
+#if defined(CONFIG_QCA_GPIO_MASK_OUT_INIT_H) ||\
+    defined(CONFIG_QCA_GPIO_MASK_OUT_INIT_L)
+
+       #if defined(CONFIG_QCA_GPIO_MASK_OUT_INIT_H)
+               mask_h = CONFIG_QCA_GPIO_MASK_OUT_INIT_H;
+       #endif
+
+       #if defined(CONFIG_QCA_GPIO_MASK_OUT_INIT_L)
+               mask_l = CONFIG_QCA_GPIO_MASK_OUT_INIT_L;
+       #endif
+
+               if (output) {
+                       if (gpio_mask & mask_h)
+                               printf("%-3s", "hi");
+                       else if (gpio_mask & mask_l)
+                               printf("%-3s", "lo");
+                       else
+                               printf("%-3s", "-");
+               } else
+                       printf("%-3s", "-");
+#else
+               printf("%-3s", "-");
+#endif
+               puts(" | ");
+
+               /* GPIO in LED mask */
+#if defined(CONFIG_QCA_GPIO_MASK_LED_ACT_H) ||\
+    defined(CONFIG_QCA_GPIO_MASK_LED_ACT_L)
+       #if defined(CONFIG_QCA_GPIO_MASK_LED_ACT_H)
+               mask_h = CONFIG_QCA_GPIO_MASK_LED_ACT_H;
+       #endif
+
+       #if defined(CONFIG_QCA_GPIO_MASK_LED_ACT_L)
+               mask_l = CONFIG_QCA_GPIO_MASK_LED_ACT_L;
+       #endif
+
+               if (output) {
+                       if (gpio_mask & mask_h)
+                               printf("%-3s", "hi");
+                       else if (gpio_mask & mask_l)
+                               printf("%-3s", "lo");
+                       else
+                               printf("%-3s", "-");
+               } else
+                       printf("%-3s", "-");
+#else
+               printf("%-3s", "-");
+#endif
+               puts(" | ");
+
+               /* GPIO configured as RST button */
+#if defined(CONFIG_GPIO_RESET_BTN)
+               if (!output && (gpio_mask & (1 << CONFIG_GPIO_RESET_BTN)))
+       #if defined(CONFIG_GPIO_RESET_BTN_ACTIVE_LOW)
+                       printf("%-3s", "lo");
+       #else
+                       printf("%-3s", "hi");
+       #endif
+               else
+                       printf("%-3s", "-");
+#else
+               printf("%-3s", "-");
+#endif
+               puts(" | ");
+
+               /* JTAG enabled? */
+               if (jtag_en && (gpio_mask & QCA_GPIO_JTAG_MASK))
+                       printf("%-4s", "en");
+               else
+                       printf("%-4s", "-");
+
+#if (SOC_TYPE & ~QCA_AR933X_SOC)
+               puts(" | ");
+
+               /* GPIO input/output function */
+               val = 0;
+               if (output) {
+                       func = gpio_get_out_func(gpio_num);
+                       for (i = 0; i < gpio_out_funcs_cnt; i++)
+                               if (gpio_out_funcs[i].value == func) {
+                                       printf("%s (%d)",
+                                              gpio_out_funcs[i].name, func);
+
+                                       val = 1;
+                               }
+
+                       if (!val)
+                               printf("%s (%d)", "unknown", func);
+               } else {
+                       for (i = 0; i < gpio_in_funcs_cnt; i++) {
+                               if (gpio_num == gpio_in_func_to_gpio((u8)i)) {
+                                       if (val)
+                                               printf(",\n%43s %s (%d)", "|",
+                                                      gpio_in_funcs[i].name, i);
+                                       else
+                                               printf("%s (%d)",
+                                                      gpio_in_funcs[i].name, i);
+
+                                       val = 1;
+                               }
+                       }
+
+                       if (!val)
+                               puts("gpio (-)");
+               }
+#endif
+
+               puts("\n");
+       }
+
+       puts("\n");
+}
+
+#if (SOC_TYPE & QCA_AR933X_SOC)
+static void gpio_list_funcs(void)
+{
+       u32 i, j, n, val;
+       u32 found;
+
+       puts("\n");
+       puts("   # | EN | FUNCTION       | RELATED GPIOs\n"
+            " ----+----+----------------+---------------\n");
+
+       val = qca_soc_reg_read(QCA_GPIO_FUNC_1_REG);
+       for (i = 0; i < gpio_funcs_1_cnt; i++) {
+               printf("%4d", i);
+               puts(" | ");
+
+               if (val & gpio_funcs_1[i].reg_mask)
+                       puts("en");
+               else
+                       puts("  ");
+
+               puts(" | ");
+               printf("%-14s", gpio_funcs_1[i].name);
+               puts(" | ");
+
+               found = 0;
+               if (gpio_funcs_1[i].gpio_mask) {
+                       for (n = 0; n < _GPIO_NUM_MAX; n++) {
+                               if (gpio_funcs_1[i].gpio_mask & (1 << n)) {
+                                       if (found)
+                                               puts(", ");
+
+                                       printf("%2d", n);
+                                       found = 1;
+                               }
+                       }
+               }
+
+               if (found)
+                       puts("\n");
+               else
+                       puts("-\n");
+       }
+
+       j = gpio_funcs_1_cnt;
+       val = qca_soc_reg_read(QCA_GPIO_FUNC_2_REG);
+       for (i = 0; i < gpio_funcs_2_cnt; i++) {
+               printf("%4d", j);
+               puts(" | ");
+
+               if (val & gpio_funcs_2[i].reg_mask)
+                       puts("en");
+               else
+                       puts("  ");
+
+               puts(" | ");
+               printf("%-14s", gpio_funcs_2[i].name);
+               puts(" | ");
+
+               found = 0;
+               if (gpio_funcs_2[i].gpio_mask) {
+                       for (n = 0; n < _GPIO_NUM_MAX; n++) {
+                               if (gpio_funcs_2[i].gpio_mask & (1 << n)) {
+                                       if (found)
+                                               puts(", ");
+
+                                       printf("%2d", n);
+                                       found = 1;
+                               }
+                       }
+               }
+
+               if (found)
+                       puts("\n");
+               else
+                       puts("-\n");
+
+               j++;
+       }
+
+       puts("\n");
+}
+#else
+static void gpio_list_in_out_funcs(void)
+{
+       u32 i;
+
+       puts("\n");
+       puts("    # | DIR | FUNCTION\n"
+            " -----+-----+----------\n");
+
+       for (i = 0; i < gpio_in_funcs_cnt; i++) {
+               printf("%5d", i);
+               puts(" | ");
+               printf("%-3s", "in");
+               puts(" | ");
+               printf("%s\n", gpio_in_funcs[i].name);
+       }
+
+       puts(" -----+-----+---------\n");
+
+       for (i = 0; i < gpio_out_funcs_cnt; i++) {
+               printf("%5d", gpio_out_funcs[i].value);
+               puts(" | ");
+               printf("%-3s", "out");
+               puts(" | ");
+               printf("%s\n", gpio_out_funcs[i].name);
+       }
+
+       puts("\n");
+}
+#endif
+
+int do_gpio(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+       u32 gpio_mask, gpio_num = 0;
+       u32 output = 1;
+       u32 func = 0;
+       u32 val = 0;
+
+#if (SOC_TYPE & QCA_AR933X_SOC)
+       u32 func_max = gpio_funcs_1_cnt + gpio_funcs_2_cnt - 2;
+       u32 func_en;
+#else
+       u32 func_max = gpio_in_funcs_cnt - 1;
+       u32 func_old;
+#endif
+
+       /* We need at least one arg */
+       if (argc == 1) {
+usage:
+               print_cmd_help(cmdtp);
+               return 1;
+       }
+
+       switch (*argv[1]) {
+       case 'f':
+               if (argc < 4)
+                       goto usage;
+
+#if (SOC_TYPE & QCA_AR933X_SOC)
+               func = simple_strtoul(argv[2], NULL, 10);
+               if (func > func_max) {
+                       printf_err("GPIO function is out of range (0~%d)\n",
+                                  func_max);
+
+                       return 1;
+               }
+
+               switch (*argv[3]) {
+               case 'e':
+                       func_en = 1;
+                       break;
+               case 'd':
+                       func_en = 0;
+                       break;
+               default:
+                       goto usage;
+               }
+
+               gpio_set_func(func, func_en);
+
+               return 0;
+#else
+               if (strcmp(argv[1], "fin") == 0)
+                       output = 0;
+               else if (strcmp(argv[1], "fout") == 0)
+                       func_max = _GPIO_OUT_MUX_MAX;
+               else
+                       goto usage;
+
+               func = simple_strtoul(argv[3], NULL, 10);
+               if (func > func_max) {
+                       printf_err("GPIO function is out of range (0~%d)\n",
+                                  func_max);
+
+                       return 1;
+               }
+
+               break;
+#endif
+       case 'j':
+               if (argc < 2)
+                       goto usage;
+
+               switch (*argv[2]) {
+               case 'e':
+                       gpio_set_jtag(1);
+                       break;
+               case 'd':
+                       gpio_set_jtag(0);
+                       break;
+               default:
+                       goto usage;
+               }
+
+               return 0;
+       case 'l':
+               if (argc < 3)
+                       gpio_list_cfg();
+               else if (*argv[2] == 'f')
+#if (SOC_TYPE & QCA_AR933X_SOC)
+                       gpio_list_funcs();
+#else
+                       gpio_list_in_out_funcs();
+#endif
+               else
+                       goto usage;
+
+               return 0;
+       case 's':
+       case 'c':
+       case 't':
+       case 'i':
+               if (argc < 3)
+                       goto usage;
+
+               if (*argv[1] == 's')
+                       val = 1;
+
+               break;
+       default:
+               goto usage;
+       }
+
+       gpio_num = simple_strtoul(argv[2], NULL, 10);
+       if (gpio_num > _GPIO_NUM_MAX) {
+               printf_err("GPIO must be in range 0~%d\n", _GPIO_NUM_MAX);
+               return 1;
+       }
+
+       gpio_mask = (1 << gpio_num);
+
+       switch (*argv[1]) {
+       case 's':
+       case 'c':
+#if (SOC_TYPE & ~QCA_AR933X_SOC)
+       case 'f':
+               if (output)
+                       func_old = gpio_get_out_func(gpio_num);
+#endif
+
+               gpio_set_dir(gpio_mask, output);
+
+#if (SOC_TYPE & ~QCA_AR933X_SOC)
+               gpio_set_in_out_func(gpio_num, (u8)func, output);
+#endif
+
+               if ((*argv[1] == 's') || (*argv[1] == 'c'))
+                       gpio_set_val(gpio_mask, val);
+
+#if (SOC_TYPE & ~QCA_AR933X_SOC)
+               if (output && (func != func_old))
+                       gpio_func_gate(func_old, func);
+#endif
+
+               break;
+       case 't':
+               val = qca_soc_reg_read(QCA_GPIO_OE_REG);
+#if (SOC_TYPE & QCA_AR933X_SOC) ||\
+    (SOC_TYPE & QCA_QCA955X_SOC)
+               if (!(gpio_mask & val)) {
+#else
+               if (gpio_mask & val) {
+#endif
+                       printf_err("GPIO is not set as output\n");
+                       return 1;
+               }
+
+#if (SOC_TYPE & ~QCA_AR933X_SOC)
+               func = (u32)gpio_get_out_func(gpio_num);
+               if (func > 0) {
+                       printf_err("GPIO out function is not set to GPIO\n");
+                       return 1;
+               }
+#endif
+
+               val = qca_soc_reg_read(QCA_GPIO_OUT_REG);
+               if (gpio_mask & val)
+                       gpio_set_val(gpio_mask, 0);
+               else
+                       gpio_set_val(gpio_mask, 1);
+
+               break;
+       case 'i':
+               gpio_set_dir(gpio_mask, 0);
+
+               if (!(gpio_mask & qca_soc_reg_read(QCA_GPIO_IN_REG)))
+                       return 1;
+       }
+
+       return 0;
+}
+
+U_BOOT_CMD(gpio, 4, 0, do_gpio,
+          "control GPIO\n",
+          "<c>lear|<i>nput|<s>et|<t>oggle <gpio>\n"
+          "\t- setup <gpio> as in/out and change/get its value\n"
+#if (SOC_TYPE & QCA_AR933X_SOC)
+          "gpio <f>unction <func> <e>nable|<d>isable\n"
+          "\t- enable/disable function <func>\n"
+#else
+          "gpio <fin|fout> <gpio> <func>\n"
+          "\t- set <gpio> in/out function to <func>\n"
+#endif
+          "gpio <j>tag <e>nable|<d>isable\n"
+          "\t- enable/disable JTAG\n"
+          "gpio <l>ist\n"
+          "\t- show current GPIO configuration\n"
+          "gpio <l>ist <f>unctions\n"
+#if (SOC_TYPE & QCA_AR933X_SOC)
+          "\t- show all GPIO functions\n"
+#else
+          "\t- show all known GPIO in/out functions\n"
+#endif
+);
+
+#endif /* CONFIG_CMD_GPIO */
diff --git a/u-boot/include/cmd_qcagpio.h b/u-boot/include/cmd_qcagpio.h
new file mode 100644 (file)
index 0000000..ca75e66
--- /dev/null
@@ -0,0 +1,882 @@
+/*
+ * Copyright (C) 2017 Piotr Dymacz <piotr@dymacz.pl>
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <soc/qca_soc_common.h>
+
+#ifndef _CMD_QCAGPIO_H_
+#define _CMD_QCAGPIO_H_
+
+#if defined(CONFIG_CMD_GPIO)
+
+#if (SOC_TYPE & QCA_AR933X_SOC)
+
+typedef struct {
+       u32 reg_mask;
+       u32 gpio_mask;
+       char *name;
+} gpio_func;
+
+static const gpio_func gpio_funcs_1[] = {
+       {
+               .reg_mask  = QCA_GPIO_FUNC_1_UART_EN_MASK,
+               .gpio_mask = GPIO9 | GPIO10,
+               .name      = "uart"
+       }, {
+               .reg_mask  = QCA_GPIO_FUNC_1_UART_RTS_CTS_EN_MASK,
+               .gpio_mask = GPIO11 | GPIO12,
+               .name      = "uart_rts_cts"
+       }, {
+               .reg_mask  = QCA_GPIO_FUNC_1_ETH_SW_LED0_EN_MASK,
+               .gpio_mask = GPIO13,
+               .name      = "switch_led0"
+       }, {
+               .reg_mask  = QCA_GPIO_FUNC_1_ETH_SW_LED1_EN_MASK,
+               .gpio_mask = GPIO14,
+               .name      = "switch_led1"
+       }, {
+               .reg_mask  = QCA_GPIO_FUNC_1_ETH_SW_LED2_EN_MASK,
+               .gpio_mask = GPIO15,
+               .name      = "switch_led2"
+       }, {
+               .reg_mask  = QCA_GPIO_FUNC_1_ETH_SW_LED3_EN_MASK,
+               .gpio_mask = GPIO16,
+               .name      = "switch_led3"
+       }, {
+               .reg_mask  = QCA_GPIO_FUNC_1_ETH_SW_LED4_EN_MASK,
+               .gpio_mask = GPIO17,
+               .name      = "switch_led4"
+       }, {
+               .reg_mask  = QCA_GPIO_FUNC_1_SPI_CS_EN1_MASK,
+               .gpio_mask = GPIO9,
+               .name      = "spi_cs1"
+       }, {
+               .reg_mask  = QCA_GPIO_FUNC_1_SPI_CS_EN2_MASK,
+               .gpio_mask = GPIO10,
+               .name      = "spi_cs2"
+       }, {
+               .reg_mask  = QCA_GPIO_FUNC_1_SPI_EN_MASK,
+               .gpio_mask = GPIO2 | GPIO3 | GPIO4 | GPIO5,
+               .name      = "spi"
+       }, {
+               .reg_mask  = QCA_GPIO_FUNC_1_ETH_SW_LED_ACT_MASK,
+               .gpio_mask = 0,
+               .name      = "switch_led_act"
+       }, {
+               .reg_mask  = QCA_GPIO_FUNC_1_ETH_SW_LED_COLL_MASK,
+               .gpio_mask = 0,
+               .name      = "switch_led_col"
+       }, {
+               .reg_mask  = QCA_GPIO_FUNC_1_ETH_SW_LED_DUPL_MASK,
+               .gpio_mask = 0,
+               .name      = "switch_led_dup"
+       }, {
+               .reg_mask  = QCA_GPIO_FUNC_1_I2S_EN_MASK,
+               .gpio_mask = GPIO6 | GPIO7 | GPIO8 | GPIO11 | GPIO12,
+               .name      = "i2s"
+       }, {
+               .reg_mask  = QCA_GPIO_FUNC_1_I2S_MCLK_EN_MASK,
+               .gpio_mask = GPIO21,
+               .name      = "i2s_mck_on21"
+       }, {
+               .reg_mask  = QCA_GPIO_FUNC_1_I2S_22_18_EN_MASK,
+               .gpio_mask = GPIO18 | GPIO19 | GPIO20 | GPIO21 | GPIO22,
+               .name      = "i2s_on_18_22"
+       }, {
+               .reg_mask  = QCA_GPIO_FUNC_1_SPDIF_EN_MASK,
+               .gpio_mask = 0,
+               .name      = "spdif"
+       }, {
+               .reg_mask  = QCA_GPIO_FUNC_1_SPDIF_TCK_EN_MASK,
+               .gpio_mask = 0,
+               .name      = "spdif_on_tck"
+       },
+};
+
+static const gpio_func gpio_funcs_2[] = {
+       {
+               .reg_mask  = QCA_GPIO_FUNC_2_MIC_DIS_MASK,
+               .gpio_mask = 0,
+               .name      = "mic_dis"
+       }, {
+               .reg_mask  = QCA_GPIO_FUNC_2_I2S_ON_LED_MASK,
+               .gpio_mask = GPIO14 | GPIO15 | GPIO16,
+               .name      = "i2s_on_led"
+       }, {
+               .reg_mask  = QCA_GPIO_FUNC_2_SPDIF_ON23_MASK,
+               .gpio_mask = GPIO23,
+               .name      = "spdif_on_23"
+       }, {
+               .reg_mask  = QCA_GPIO_FUNC_2_I2SCK_ON1_MASK,
+               .gpio_mask = GPIO1,
+               .name      = "i2s_clk_on_1"
+       }, {
+               .reg_mask  = QCA_GPIO_FUNC_2_I2SWS_ON0_MASK,
+               .gpio_mask = GPIO0,
+               .name      = "i2s_ws_on_0"
+       }, {
+               .reg_mask  = QCA_GPIO_FUNC_2_I2SSD_ON12_MASK,
+               .gpio_mask = GPIO12,
+               .name      = "i2s_sd_on_12"
+       }, {
+               .reg_mask  = QCA_GPIO_FUNC_2_WPS_DIS_MASK,
+               .gpio_mask = GPIO12,
+               .name      = "wps_dis"
+       }, {
+               .reg_mask  = QCA_GPIO_FUNC_2_JUMPSTART_DIS_MASK,
+               .gpio_mask = GPIO11,
+               .name      = "jumpstart_dis"
+       }, {
+               .reg_mask  = QCA_GPIO_FUNC_2_WLAN_LED_ON0_MASK,
+               .gpio_mask = GPIO0,
+               .name      = "wlan_led1_on_0"
+       }, {
+               .reg_mask  = QCA_GPIO_FUNC_2_USB_LED_ON1_MASK,
+               .gpio_mask = GPIO1,
+               .name      = "wlan_led2_on_1"
+       }, {
+               .reg_mask  = QCA_GPIO_FUNC_2_LNA_ON28_MASK,
+               .gpio_mask = GPIO28,
+               .name      = "ext_lna_on_28"
+       }, {
+               .reg_mask  = QCA_GPIO_FUNC_2_SLIC_EN_MASK,
+               .gpio_mask = GPIO6 | GPIO7 | GPIO8 | GPIO11 | GPIO12,
+               .name      = "slic"
+       }, {
+               .reg_mask  = QCA_GPIO_FUNC_2_SLIC_ON18_22_MASK,
+               .gpio_mask = GPIO18 | GPIO19 | GPIO20 | GPIO21 | GPIO22,
+               .name      = "slic_on_18_22"
+       }, {
+               .reg_mask  = QCA_GPIO_FUNC_2_SLIC_DIO_MUX_EN_MASK,
+               .gpio_mask = 0,
+               .name      = "slic_dio_mux"
+       },
+};
+
+static u32 gpio_funcs_1_cnt = sizeof(gpio_funcs_1) / sizeof(gpio_func);
+static u32 gpio_funcs_2_cnt = sizeof(gpio_funcs_2) / sizeof(gpio_func);
+
+#else
+
+typedef struct {
+       u8 offset;
+       char *name;
+} gpio_in_func;
+
+typedef struct {
+       u8 value;
+       char *name;
+} gpio_out_func;
+
+/*
+ * TODO:
+ * split gpio input functions per SoC version, not just family
+ */
+static const gpio_in_func gpio_in_funcs[] = {
+#if (SOC_TYPE & QCA_AR934X_SOC) ||\
+    (SOC_TYPE & QCA_QCA955X_SOC)
+       /* QCA_GPIO_IN_EN0_REG (0x18040044) */
+       {
+               .offset = 0,
+               .name   = "spi_miso"
+       }, {
+               .offset = 1,
+               .name   = "uart0_rx"
+       },
+       /* QCA_GPIO_IN_EN1_REG (0x18040048) */
+       {
+               .offset = 4,
+               .name   = "i2s_mic_ws"
+       }, {
+               .offset = 5,
+               .name   = "i2s_mic_sd"
+       }, {
+               .offset = 6,
+               .name   = "i2s_ext_clk"
+       }, {
+               .offset = 7,
+               .name   = "i2s_ext_mck"
+       },
+       /* QCA_GPIO_IN_EN2_REG (0x1804004C) */
+       {
+               .offset = 8,
+               .name   = "eth_rx_err"
+       }, {
+               .offset = 9,
+               .name   = "eth_rx_col"
+       }, {
+               .offset = 10,
+               .name   = "eth_rx_crs"
+       },
+#if (SOC_TYPE & QCA_QCA955X_SOC)
+       {
+               .offset = 11,
+               .name   = "slic_ext_mclk"
+       },
+#endif
+       /* QCA_GPIO_IN_EN3_REG (0x18040050) */
+#if (SOC_TYPE & QCA_AR934X_SOC)
+       {
+               .offset = 14,
+               .name   = "boot_ext_mdo"
+       }, {
+               .offset = 15,
+               .name   = "boot_ext_mdc"
+       },
+#elif (SOC_TYPE & QCA_QCA955X_SOC)
+       {
+               .offset = 12,
+               .name   = "boot_ext_mdo"
+       }, {
+               .offset = 13,
+               .name   = "boot_ext_mdc"
+       }, {
+               .offset = 14,
+               .name   = "mii_ge1_mdi"
+       },
+#endif
+       /* QCA_GPIO_IN_EN4_REG (0x18040054) */
+       {
+               .offset = 16,
+               .name   = "slic_data_in"
+       }, {
+               .offset = 17,
+               .name   = "slic_pcm_fs_in"
+       },
+#if (SOC_TYPE & QCA_QCA955X_SOC)
+       {
+               .offset = 18,
+               .name   = "i2c_clk"
+       }, {
+               .offset = 19,
+               .name   = "i2c_sda"
+       },
+#endif
+       /* QCA_GPIO_IN_EN9_REG (0x18040068) */
+       {
+               .offset = 38,
+               .name   = "uart1_rx"
+       }, {
+               .offset = 39,
+               .name   = "uart1_cts"
+       },
+#elif (SOC_TYPE & QCA_QCA953X_SOC)
+       /* QCA_GPIO_IN_EN0_REG (0x18040044) */
+       {
+               .offset = 0,
+               .name   = "spi_miso"
+       }, {
+               .offset = 1,
+               .name   = "uart0_rx"
+       },
+#elif (SOC_TYPE & QCA_QCA956X_SOC)
+       /* QCA_GPIO_IN_EN0_REG (0x18040044) */
+       {
+               .offset = 1,
+               .name   = "uart0_rx"
+       },
+       /* QCA_GPIO_IN_EN3_REG (0x18040050) */
+       {
+               .offset = 14,
+               .name   = "mii_ge0_mdi"
+       },
+#endif
+};
+
+/*
+ * TODO:
+ * split gpio output functions per SoC version, not just family
+ */
+static const gpio_out_func gpio_out_funcs[] = {
+       {
+               .value = 0,
+               .name  = "gpio"
+       },
+#if (SOC_TYPE & QCA_AR934X_SOC)
+       {
+               .value = QCA_GPIO_OUT_MUX_NAND_CS0_VAL,                 /* 1 */
+               .name  = "nand_cs"
+       }, {
+               .value = 2,
+               .name  = "boot_rxt_mdi"
+       }, {
+               .value = 4,
+               .name  = "slic_data_out"
+       }, {
+               .value = 5,
+               .name  = "slic_pcm_fs"
+       }, {
+               .value = 6,
+               .name  = "slic_pcm_clk"
+       }, {
+               .value = 7,
+               .name  = "spi_cs1"
+       }, {
+               .value = 8,
+               .name  = "spi_cs2"
+       }, {
+               .value = 9,
+               .name  = "spi_cs0"
+       }, {
+               .value = QCA_GPIO_OUT_MUX_SPI_CLK_VAL,                  /* 10 */
+               .name  = "spi_clk"
+       }, {
+               .value = 11,
+               .name  = "spi_mosi"
+       }, {
+               .value = 12,
+               .name  = "i2s_clk"
+       }, {
+               .value = 13,
+               .name  = "i2s_ws"
+       }, {
+               .value = 14,
+               .name  = "i2s_sd"
+       }, {
+               .value = 15,
+               .name  = "i2s_mck"
+       }, {
+               .value = QCA_GPIO_OUT_MUX_CLK_OBS0_VAL,                 /* 16 */
+               .name  = "clk_obs0"
+       }, {
+               .value = QCA_GPIO_OUT_MUX_CLK_OBS1_VAL,                 /* 17 */
+               .name  = "clk_obs1"
+       }, {
+               .value = QCA_GPIO_OUT_MUX_CLK_OBS2_VAL,                 /* 18 */
+               .name  = "clk_obs2"
+       }, {
+               .value = QCA_GPIO_OUT_MUX_CLK_OBS3_VAL,                 /* 19 */
+               .name  = "clk_obs3"
+       }, {
+               .value = QCA_GPIO_OUT_MUX_CLK_OBS4_VAL,                 /* 20 */
+               .name  = "clk_obs4"
+       }, {
+               .value = QCA_GPIO_OUT_MUX_CLK_OBS5_VAL,                 /* 21 */
+               .name  = "clk_obs5"
+       }, {
+               .value = QCA_GPIO_OUT_MUX_CLK_OBS6_VAL,                 /* 22 */
+               .name  = "clk_obs6"
+       }, {
+               .value = QCA_GPIO_OUT_MUX_CLK_OBS7_VAL,                 /* 23 */
+               .name  = "clk_obs7"
+       }, {
+               .value = 24,
+               .name  = "uart0_tx"
+       }, {
+               .value = 25,
+               .name  = "spdif_out"
+       }, {
+               .value = 26,
+               .name  = "led_act0"
+       }, {
+               .value = 27,
+               .name  = "led_act1"
+       }, {
+               .value = 28,
+               .name  = "led_act2"
+       }, {
+               .value = 29,
+               .name  = "led_act3"
+       }, {
+               .value = 30,
+               .name  = "led_act4"
+       }, {
+               .value = 31,
+               .name  = "led_col0"
+       }, {
+               .value = 32,
+               .name  = "led_col1"
+       }, {
+               .value = 33,
+               .name  = "led_col2"
+       }, {
+               .value = 34,
+               .name  = "led_col3"
+       }, {
+               .value = 35,
+               .name  = "led_col4"
+       }, {
+               .value = 36,
+               .name  = "led_dup0"
+       }, {
+               .value = 37,
+               .name  = "led_dup1"
+       }, {
+               .value = 38,
+               .name  = "led_dup2"
+       }, {
+               .value = 39,
+               .name  = "led_dup3"
+       }, {
+               .value = 40,
+               .name  = "led_dup4"
+       }, {
+               .value = 41,
+               .name  = "led_link0"
+       }, {
+               .value = 42,
+               .name  = "led_link1"
+       }, {
+               .value = 43,
+               .name  = "led_link2"
+       }, {
+               .value = 44,
+               .name  = "led_link3"
+       }, {
+               .value = 45,
+               .name  = "led_link4"
+       }, {
+               .value = 46,
+               .name  = "ext_lna0"
+       }, {
+               .value = 47,
+               .name  = "ext_lna1"
+       }, {
+               .value = 48,
+               .name  = "tx_frame"
+       }, {
+               .value = 49,
+               .name  = "wlan_act"
+       }, {
+               .value = 50,
+               .name  = "led_net_en"
+       }, {
+               .value = 51,
+               .name  = "led_pwr_en"
+       }, {
+               .value = 72,
+               .name  = "wmac_glue_wow"
+       }, {
+               .value = 73,
+               .name  = "bt_act"
+       }, {
+               .value = 74,
+               .name  = "rx_clear_extension"
+       }, {
+               .value = 78,
+               .name  = "eth_tx_err"
+       }, {
+               .value = 79,
+               .name  = "uart1_tx"
+       }, {
+               .value = 80,
+               .name  = "uart1_rts"
+       }, {
+               .value = 84,
+               .name  = "ddr_dq_oe"
+       }, {
+               .value = 87,
+               .name  = "usb_suspend"
+       },
+#elif (SOC_TYPE & QCA_QCA953X_SOC)
+       {
+               .value = QCA_GPIO_OUT_MUX_SYS_RST_L_VAL,                /* 1 */
+               .name  = "sys_rst_l"
+       }, {
+               .value = QCA_GPIO_OUT_MUX_SPI_CLK_VAL,                  /* 8 */
+               .name  = "spi_clk"
+       }, {
+               .value = 9,
+               .name  = "spi_cs0"
+       }, {
+               .value = 10,
+               .name  = "spi_cs1"
+       }, {
+               .value = 11,
+               .name  = "spi_cs2"
+       }, {
+               .value = 12,
+               .name  = "spi_mosi"
+       }, {
+               .value = 22,
+               .name  = "uart0_tx"
+       }, {
+               .value = QCA_GPIO_OUT_MUX_SRIF_OUT_VAL,                 /* 23 */
+               .name  = "srif_out"
+       }, {
+               .value = 26,
+               .name  = "led_act0"
+       }, {
+               .value = 27,
+               .name  = "led_act1"
+       }, {
+               .value = 28,
+               .name  = "led_act2"
+       }, {
+               .value = 29,
+               .name  = "led_act3"
+       }, {
+               .value = 30,
+               .name  = "led_act4"
+       }, {
+               .value = 31,
+               .name  = "led_col0"
+       }, {
+               .value = 32,
+               .name  = "led_col1"
+       }, {
+               .value = 33,
+               .name  = "led_col2"
+       }, {
+               .value = 34,
+               .name  = "led_col3"
+       }, {
+               .value = 35,
+               .name  = "led_col4"
+       }, {
+               .value = 36,
+               .name  = "led_dup0"
+       }, {
+               .value = 37,
+               .name  = "led_dup1"
+       }, {
+               .value = 38,
+               .name  = "led_dup2"
+       }, {
+               .value = 39,
+               .name  = "led_dup3"
+       }, {
+               .value = 40,
+               .name  = "led_dup4"
+       }, {
+               .value = 41,
+               .name  = "led_link0"
+       }, {
+               .value = 42,
+               .name  = "led_link1"
+       }, {
+               .value = 43,
+               .name  = "led_link2"
+       }, {
+               .value = 44,
+               .name  = "led_link3"
+       }, {
+               .value = 45,
+               .name  = "led_link4"
+       }, {
+               .value = QCA_GPIO_OUT_MUX_SMART_ANT_CTRL_BIT2_VAL,      /* 48 */
+               .name  = "smart_ant_ctl_b2"
+       }, {
+               .value = QCA_GPIO_OUT_MUX_SMART_ANT_CTRL_BIT3_VAL,      /* 49 */
+               .name  = "smart_ant_ctl_b3"
+       }, {
+               .value = 50,
+               .name  = "ext_lna0"
+       }, {
+               .value = 51,
+               .name  = "ext_lna1"
+       }, {
+               .value = 52,
+               .name  = "tx_frame"
+       }, {
+               .value = 53,
+               .name  = "wlan_act"
+       }, {
+               .value = 54,
+               .name  = "led_net_en"
+       }, {
+               .value = 55,
+               .name  = "led_pwr_en"
+       }, {
+               .value = 78,
+               .name  = "rx_clear_extension"
+       }, {
+               .value = 86,
+               .name  = "usb_suspend"
+       }, {
+               .value = 88,
+               .name  = "ddr_dq_oe"
+       }, {
+               .value = 89,
+               .name  = "clk_req_rc_n"
+       }, {
+               .value = QCA_GPIO_OUT_MUX_CLK_OBS0_VAL,                 /* 90 */
+               .name  = "clk_obs0"
+       }, {
+               .value = QCA_GPIO_OUT_MUX_CLK_OBS1_VAL,                 /* 91 */
+               .name  = "clk_obs1"
+       }, {
+               .value = QCA_GPIO_OUT_MUX_CLK_OBS2_VAL,                 /* 92 */
+               .name  = "clk_obs2"
+       }, {
+               .value = QCA_GPIO_OUT_MUX_CLK_OBS3_VAL,                 /* 93 */
+               .name  = "clk_obs3"
+       }, {
+               .value = QCA_GPIO_OUT_MUX_CLK_OBS4_VAL,                 /* 94 */
+               .name  = "clk_obs4"
+       }, {
+               .value = QCA_GPIO_OUT_MUX_CLK_OBS5_VAL,                 /* 95 */
+               .name  = "clk_obs5"
+       }, {
+               .value = QCA_GPIO_OUT_MUX_CLK_OBS6_VAL,                 /* 96 */
+               .name  = "clk_obs6"
+       },
+#elif (SOC_TYPE & QCA_QCA955X_SOC)
+       {
+               .value = 1,
+               .name  = "mii_ext_mdi"
+       }, {
+               .value = 3,
+               .name  = "slic_data_out"
+       }, {
+               .value = 4,
+               .name  = "slic_pcm_fs"
+       }, {
+               .value = 5,
+               .name  = "slic_pcm_clk"
+       }, {
+               .value = QCA_GPIO_OUT_MUX_SPI_CLK_VAL,                  /* 8 */
+               .name  = "spi_clk"
+       }, {
+               .value = 9,
+               .name  = "spi_cs0"
+       }, {
+               .value = 10,
+               .name  = "spi_cs1"
+       }, {
+               .value = 11,
+               .name  = "spi_cs2"
+       }, {
+               .value = 12,
+               .name  = "spi_mosi"
+       }, {
+               .value = 13,
+               .name  = "i2s_clk"
+       }, {
+               .value = 14,
+               .name  = "i2s_ws"
+       }, {
+               .value = 15,
+               .name  = "i2s_sd"
+       }, {
+               .value = 16,
+               .name  = "i2s_mck"
+       }, {
+               .value = 17,
+               .name  = "spdif_out"
+       }, {
+               .value = 18,
+               .name  = "uart1_tx"
+       }, {
+               .value = 19,
+               .name  = "uart1_rts"
+       }, {
+               .value = 22,
+               .name  = "uart0_tx"
+       }, {
+               .value = QCA_GPIO_OUT_MUX_SRIF_OUT_VAL,                 /* 23 */
+               .name  = "srif_out"
+       }, {
+               .value = 24,
+               .name  = "led_sgmii_speed0"
+       }, {
+               .value = 25,
+               .name  = "led_sgmii_speed1"
+       }, {
+               .value = 26,
+               .name  = "led_sgmii_dup"
+       }, {
+               .value = 27,
+               .name  = "led_sgmii_link"
+       }, {
+               .value = 28,
+               .name  = "led_sgmii_speed0_inv"
+       }, {
+               .value = 29,
+               .name  = "led_sgmii_speed1_inv"
+       }, {
+               .value = 30,
+               .name  = "led_sgmii_dup_inv"
+       }, {
+               .value = 31,
+               .name  = "led_sgmii_link_inv"
+       }, {
+               .value = 32,
+               .name  = "ge1_mii_mdo"
+       }, {
+               .value = 33,
+               .name  = "ge1_mii_mdc"
+       }, {
+               .value = 38,
+               .name  = "swcom_b2"
+       }, {
+               .value = 39,
+               .name  = "swcom_b3"
+       }, {
+               .value = QCA_GPIO_OUT_MUX_SMART_ANT_CTRL_BIT2_VAL,      /* 40 */
+               .name  = "smart_ant_ctl_b2"
+       }, {
+               .value = QCA_GPIO_OUT_MUX_SMART_ANT_CTRL_BIT3_VAL,      /* 41 */
+               .name  = "smart_ant_ctl_b3"
+       }, {
+               .value = 42,
+               .name  = "ext_lna0"
+       }, {
+               .value = 43,
+               .name  = "ext_lna1"
+       }, {
+               .value = 44,
+               .name  = "tx_frame"
+       }, {
+               .value = 45,
+               .name  = "wlan_act"
+       }, {
+               .value = 46,
+               .name  = "led_net_en"
+       }, {
+               .value = 47,
+               .name  = "led_pwr_en"
+       }, {
+               .value = 68,
+               .name  = "wmac_glue_wow"
+       }, {
+               .value = 70,
+               .name  = "rx_clear_extension"
+       }, {
+               .value = 71,
+               .name  = "shift_strobe"
+       }, {
+               .value = 72,
+               .name  = "shift_data"
+       }, {
+               .value = 73,
+               .name  = "nand_cs1"
+       }, {
+               .value = 74,
+               .name  = "usb_suspend"
+       }, {
+               .value = 75,
+               .name  = "eth_tx_err"
+       }, {
+               .value = 76,
+               .name  = "ddr_dq_oe"
+       }, {
+               .value = 77,
+               .name  = "clk_req_ep_n"
+       }, {
+               .value = 78,
+               .name  = "clk_req_rc_n"
+       }, {
+               .value = QCA_GPIO_OUT_MUX_CLK_OBS0_VAL,                 /* 79 */
+               .name  = "clk_obs0"
+       }, {
+               .value = QCA_GPIO_OUT_MUX_CLK_OBS1_VAL,                 /* 80 */
+               .name  = "clk_obs1"
+       }, {
+               .value = QCA_GPIO_OUT_MUX_CLK_OBS2_VAL,                 /* 81 */
+               .name  = "clk_obs2"
+       }, {
+               .value = QCA_GPIO_OUT_MUX_CLK_OBS3_VAL,                 /* 82 */
+               .name  = "clk_obs3"
+       }, {
+               .value = QCA_GPIO_OUT_MUX_CLK_OBS4_VAL,                 /* 83 */
+               .name  = "clk_obs4"
+       }, {
+               .value = QCA_GPIO_OUT_MUX_CLK_OBS5_VAL,                 /* 84 */
+               .name  = "clk_obs5"
+       },
+#elif (SOC_TYPE & QCA_QCA956X_SOC)
+       {
+               .value = 18,
+               .name  = "uart1_tx"
+       }, {
+               .value = 19,
+               .name  = "uart1_rts"
+       }, {
+               .value = 22,
+               .name  = "uart0_tx"
+       }, {
+               .value = 23,
+               .name  = "srif_out"
+       }, {
+               .value = 24,
+               .name  = "led_sgmii_speed0"
+       }, {
+               .value = 25,
+               .name  = "led_sgmii_speed1"
+       }, {
+               .value = 26,
+               .name  = "led_sgmii_dup"
+       }, {
+               .value = 27,
+               .name  = "led_sgmii_link"
+       }, {
+               .value = 28,
+               .name  = "led_sgmii_speed0_inv"
+       }, {
+               .value = 29,
+               .name  = "led_sgmii_speed1_inv"
+       }, {
+               .value = 30,
+               .name  = "led_sgmii_dup_inv"
+       }, {
+               .value = 31,
+               .name  = "led_sgmii_link_inv"
+       }, {
+               .value = 37,
+               .name  = "spi_cs1"
+       }, {
+               .value = 38,
+               .name  = "swcom_b2"
+       }, {
+               .value = 39,
+               .name  = "swcom_b3"
+       }, {
+               .value = 40,
+               .name  = "smart_ant_ctl_b2"
+       }, {
+               .value = 41,
+               .name  = "smart_ant_ctl_b3"
+       }, {
+               .value = 42,
+               .name  = "ext_lna0"
+       }, {
+               .value = 43,
+               .name  = "ext_lna1"
+       }, {
+               .value = 44,
+               .name  = "tx_frame"
+       }, {
+               .value = 45,
+               .name  = "wlan_act"
+       }, {
+               .value = 46,
+               .name  = "led_net_en"
+       }, {
+               .value = 47,
+               .name  = "led_pwr_en"
+       }, {
+               .value = 69,
+               .name  = "bt_act"
+       }, {
+               .value = 70,
+               .name  = "rx_clear_extension"
+       }, {
+               .value = 73,
+               .name  = "i2c_clk"
+       }, {
+               .value = 77,
+               .name  = "i2c_sda"
+       }, {
+               .value = 78,
+               .name  = "clk_req_rc_n"
+       }, {
+               .value = 89,
+               .name  = "sgmii_lckdt"
+       }, {
+               .value = 115,
+               .name  = "pcie2_rst_l"
+       },
+#endif
+};
+
+static u32 gpio_in_funcs_cnt  = sizeof(gpio_in_funcs)  / sizeof(gpio_in_func);
+static u32 gpio_out_funcs_cnt = sizeof(gpio_out_funcs) / sizeof(gpio_out_func);
+
+#endif /* SOC_TYPE & QCA_AR933X_SOC */
+
+#endif /* CONFIG_CMD_GPIO */
+
+#endif /* _CMD_QCAGPIO_H_ */
index 4cd3505b0cbb75609d052e805938ad507ae0c0b5..80838d80449e4526b0a1842e43cba90b7987ea5f 100644 (file)
 #define CONFIG_CMD_ECHO
 #define CONFIG_CMD_ENV
 #define CONFIG_CMD_FLASH
+#define CONFIG_CMD_GPIO
 #define CONFIG_CMD_HTTPD
 #define CONFIG_CMD_IMI
 #define CONFIG_CMD_ITEST