From 4ee856e734dc7e6452cd8980b5d5cbd46e2ee964 Mon Sep 17 00:00:00 2001 From: Ivan Date: Thu, 16 Mar 2017 02:17:07 +0900 Subject: [PATCH] s5g/gpio: cleaned up gpio driver Driver code is cleaned and arranged in accordance with requirements. Change-Id: I1af335f6f82d9ce93290a4920d127c0209724cab Signed-off-by: Ivan --- os/arch/arm/src/s5j/s5j_gpio.c | 1377 ++++++++++++++++++++------------ os/arch/arm/src/s5j/s5j_gpio.h | 28 +- os/arch/arm/src/s5j/soc/s5jt200_gpio.h | 37 - 3 files changed, 853 insertions(+), 589 deletions(-) diff --git a/os/arch/arm/src/s5j/s5j_gpio.c b/os/arch/arm/src/s5j/s5j_gpio.c index 59c8903..3344a0f 100644 --- a/os/arch/arm/src/s5j/s5j_gpio.c +++ b/os/arch/arm/src/s5j/s5j_gpio.c @@ -86,13 +86,27 @@ struct s5j_gpio_priv { int idx; int isr_num; }; -CODE int s5j_gpio_open(FAR struct gpio_dev_s *dev); -CODE int s5j_gpio_close(FAR struct gpio_dev_s *dev); -CODE void s5j_gpio_set(FAR struct gpio_dev_s *dev, FAR unsigned int value); -CODE int s5j_gpio_get(FAR struct gpio_dev_s *dev); -CODE int s5j_gpio_ctrl(struct gpio_dev_s *dev, int cmd, unsigned long args); -static void s5j_gpio_disable_irq(struct gpio_dev_s *dev); + +/**************************************************************************** + * Private Functions prototypes + ****************************************************************************/ +static struct gpio_bank *gpio_to_bank(int gpio); +static void *__gpio_to_eint_base(int gpio); +static unsigned __gpio_to_eint_bank(int gpio); +static void *__gpio_eint_filter_get_addr(int gpio); +static void *__gpio_eint_get_addr(int gpio, unsigned offset); +static void s5j_gpio_callback_wqueue(FAR void *arg); +static void s5j_gpio_poll_expiry(int argc, uint32_t arg, ...); +static int s5j_gpio_irq_handler(int irq, void *context); static void s5j_gpio_enable_irq(struct gpio_dev_s *dev); +static void s5j_gpio_disable_irq(struct gpio_dev_s *dev); +static u32 gpio_get_irq_id(int gpio); +static const char *gpio_bank_name(int gpio); +static int s5j_gpio_open(FAR struct gpio_dev_s *dev); +static int s5j_gpio_close(FAR struct gpio_dev_s *dev); +static int s5j_gpio_get(FAR struct gpio_dev_s *dev); +static void s5j_gpio_set(FAR struct gpio_dev_s *dev, FAR unsigned int value); +static int s5j_gpio_ctrl(struct gpio_dev_s *dev, int cmd, unsigned long args); /**************************************************************************** * Private Data @@ -112,7 +126,6 @@ static struct gpio_dev_s s5j_gpio_all[NUM_GPIO]; ****************************************************************************/ #if defined(CONFIG_ARCH_CHIP_S5JT200) static struct gpio_bank s5jt200_gpio_bank[] = { - /* ALIVE */ [GPP0] = { .name = "GPP0", .base = (void *)(GPIO_CON_BASE), @@ -214,52 +227,26 @@ static struct gpio_bank s5jt200_gpio_bank[] = { }; #endif -#if defined(CONFIG_S5E_GPIO_LOG_DUMP) -static char *pull_str[] = { "none", "?", "down", "up" }; -static char *drv_str[] = { "1x", "3x", "2x", "4x" }; -#endif bool isinit = 0; + /**************************************************************************** * Private Functions ****************************************************************************/ -static u32 gpio_get_irq_id(int gpio); - -int up_create_gpio(int32_t idx) -{ -#ifdef CONFIG_GPIO - char path[20]; - struct s5j_gpio_priv *pgpio; - int bank = 0; - int port; - int idx_table[] = { 7, 15, 22, 28, 36, 44, 52, 56, 59, 63, 66 }; - pgpio = (struct s5j_gpio_priv *)kmm_malloc(sizeof(struct s5j_gpio_priv)); - s5j_gpio_all[idx].ops = &s5j_gpio_ops; - s5j_gpio_all[idx].priv = pgpio; - s5j_gpio_all[idx].wdog = NULL; - s5j_gpio_all[idx].callback = NULL; - for (bank = 0; bank < sizeof(idx_table) / sizeof(int); bank++) { - if (idx_table[bank] >= idx) { - break; - } - } - if (bank) { - port = idx - (idx_table[bank - 1] + 1); - } else { - port = idx; - } - pgpio->gpio = s5j_gpio(bank, port); - pgpio->idx = idx; - pgpio->isr_num = gpio_get_irq_id(pgpio->gpio); - snprintf(path, sizeof(path), "/dev/gpio%d", idx); - gpio_register(path, &s5j_gpio_all[idx]); - return 0; -#else - return 0; -#endif -} +/**************************************************************************** + * Name: gpio_to_bank + * + * Description: + * Converts gpio port index into gpio bank structure address + * + * Input Parameters: + * gpio - port id + * + * Returned Value: + * gpio bank structure address + ****************************************************************************/ static struct gpio_bank *gpio_to_bank(int gpio) { unsigned bank; @@ -273,6 +260,18 @@ static struct gpio_bank *gpio_to_bank(int gpio) return s5jt200_gpio_bank + bank; } +/**************************************************************************** + * Name: __gpio_to_eint_base + * + * Description: + * Converts gpio port index into eint base address + * + * Input Parameters: + * gpio - port id + * + * Returned Value: + * eint base address + ****************************************************************************/ static void *__gpio_to_eint_base(int gpio) { struct gpio_bank *gb; @@ -284,6 +283,19 @@ static void *__gpio_to_eint_base(int gpio) return gb->base; } + +/**************************************************************************** + * Name: __gpio_to_eint_bank + * + * Description: + * Converts gpio port index into eint bank + * + * Input Parameters: + * gpio - port id + * + * Returned Value: + * eint bank + ****************************************************************************/ static unsigned __gpio_to_eint_bank(int gpio) { int bank; @@ -297,6 +309,19 @@ static unsigned __gpio_to_eint_bank(int gpio) } } + +/**************************************************************************** + * Name: __gpio_eint_filter_get_addr + * + * Description: + * Returns EINT filter register address + * + * Input Parameters: + * gpio - port id + * + * Returned Value: + * Address + ****************************************************************************/ static void *__gpio_eint_filter_get_addr(int gpio) { void *gpio_filter_addr; @@ -307,6 +332,19 @@ static void *__gpio_eint_filter_get_addr(int gpio) return gpio_filter_addr; } +/**************************************************************************** + * Name: __gpio_eint_get_addr + * + * Description: + * Returns EINT CON/FLTCON/MASK/PEND register address + * + * Input Parameters: + * gpio - port id + * offset - EINT CON/FLTCON/MASK/PEND offset addr + * + * Returned Value: + * Address + ****************************************************************************/ static void *__gpio_eint_get_addr(int gpio, unsigned offset) { void *gpio_base; @@ -315,7 +353,6 @@ static void *__gpio_eint_get_addr(int gpio, unsigned offset) int port; gpio_base = __gpio_to_eint_base(gpio); - /* gpio_base = (void *)(((u64)gpio_base >> 16) << 16); TODO check this code correct or NOT */ bank_num = __gpio_to_eint_bank(gpio); port = s5j_gpio_port(gpio); @@ -331,6 +368,18 @@ static void *__gpio_eint_get_addr(int gpio, unsigned offset) return eint_addr; } +/**************************************************************************** + * Name: s5j_gpio_callback_wqueue + * + * Description: + * Callback function assigned by s5j_gpio_poll_expiry, to execute by work queue + * + * Input Parameters: + * arg - arguments + * + * Returned Value: + * None + ****************************************************************************/ static void s5j_gpio_callback_wqueue(FAR void *arg) { struct gpio_dev_s *dev; @@ -382,6 +431,21 @@ static void s5j_gpio_poll_expiry(int argc, uint32_t arg, ...) #endif } +/**************************************************************************** + * Name: s5j_gpio_irq_handler + * + * Description: + * IRQ handler to assign to handle IRQ and perform gpio notify, if configured + * + * Input Parameters: + * irq - IRQ number + * context - pointer to a dedicated context structure + * + * Returned Value: + * Ok + * -1, if Error + * + ****************************************************************************/ static int s5j_gpio_irq_handler(int irq, void *context) { int i; @@ -413,6 +477,20 @@ static int s5j_gpio_irq_handler(int irq, void *context) return OK; } +/**************************************************************************** + * Name: s5j_gpio_enable_irq + * + * Description: + * Enable IRQ + * + * Input Parameters: + * dev - GPIO device + * + * Returned Value: + * None + * + * + ****************************************************************************/ static void s5j_gpio_enable_irq(struct gpio_dev_s *dev) { int gpio; @@ -428,6 +506,20 @@ static void s5j_gpio_enable_irq(struct gpio_dev_s *dev) up_enable_irq(irq); } +/**************************************************************************** + * Name: s5j_gpio_disable_irq + * + * Description: + * Disable IRQ + * + * Input Parameters: + * dev - GPIO device + * + * Returned Value: + * None + * + * + ****************************************************************************/ static void s5j_gpio_disable_irq(struct gpio_dev_s *dev) { int gpio; @@ -439,6 +531,22 @@ static void s5j_gpio_disable_irq(struct gpio_dev_s *dev) up_disable_irq(irq); } + + +/**************************************************************************** + * Name: gpio_get_irq_id + * + * Description: + * Return IRQ ID + * + * Input Parameters: + * gpio - port id + * + * Returned Value: + * irq ID + * < 0, Error + * + ****************************************************************************/ static u32 gpio_get_irq_id(int gpio) { unsigned port; @@ -461,49 +569,20 @@ static u32 gpio_get_irq_id(int gpio) } /**************************************************************************** - * Public Functions - ****************************************************************************/ - -/** - * int gpio_valid(int gpio / Check if given gpio is in a valid range - * @param[in] gpio gpio id - * @return == 1: valid gpio - * == 0: invalid gpio + * Name: gpio_bank_name * - */ -int gpio_valid(int gpio) -{ - unsigned bank, port; - - if (gpio < 0) { - return 0; - } - - if ((gpio & 0xffff0000) != GPIO_MAGIC) { - return 0; - } - - bank = s5j_gpio_bank(gpio); - port = s5j_gpio_port(gpio); - - if (bank >= GPEND) { - return 0; - } - - if (port >= s5jt200_gpio_bank[bank].nr_port) { - return 0; - } - - return 1; -} - -/** - * const char *gpio_bank_name(int gpio) / Find and return a gpio bank name from a gpio id - * @param int gpio id - * @return gpio bank name + * Description: + * Find and return a gpio bank name from a gpio id + * + * Input Parameters: + * gpio - port id + * + * Returned Value: + * gpio bank name + * NULL in case of error * - */ -const char *gpio_bank_name(int gpio) + ****************************************************************************/ +static const char *gpio_bank_name(int gpio) { struct gpio_bank *gb = gpio_to_bank(gpio); @@ -514,118 +593,428 @@ const char *gpio_bank_name(int gpio) return gb->name; } -/** - * int gpio_cfg_pin(int gpio, int cfg) / Configure a gpio pin - * @param[in] gpio gpio id - * @param[in] cfg a mode of gpio pin(input/output/function/irq) - * @return == 0: success - * == -EINVAL: invalid gpio - */ -int gpio_cfg_pin(int gpio, int cfg) +/**************************************************************************** + * Name: s5j_gpio_open + * + * Description: + * Open GPIO port + * + * Input Parameters: + * dev - device + * + * Returned Value: + * == OK: Open success + * == -EINVAL: invalid gpio + ****************************************************************************/ +static int s5j_gpio_open(FAR struct gpio_dev_s *dev) { - struct gpio_bank *gb; - unsigned port, value; - - if (!(gb = gpio_to_bank(gpio))) { - return -EINVAL; + int idx = ((struct s5j_gpio_priv *)(dev->priv))->idx; + if (!isinit) { + up_create_gpio(idx); } - - port = s5j_gpio_port(gpio); - - value = __raw_readl(gb->base + GPIO_CON); - value &= ~CON_MASK(port); - value |= CON_SFR(port, cfg); - - __raw_writel(value, gb->base + GPIO_CON); - - return 0; + return OK; } -/** - * @brief int gpio_cfg_get_pin(int gpio) / Configure a gpio get pin - * @param[in] gpio gpio id - * @return == 0: input - * == 1: output - * == f: eint - * >= 2: function - * < 0: error - */ -int gpio_cfg_get_pin(int gpio) +/**************************************************************************** + * Name: s5j_gpio_close + * + * Description: + * Close GPIO port + * + * Input Parameters: + * dev - device + * + * Returned Value: + * == 0: close success + * == -EINVAL: invalid gpio + ****************************************************************************/ +static int s5j_gpio_close(FAR struct gpio_dev_s *dev) { - struct gpio_bank *gb; - unsigned int port; - unsigned int value; + struct s5j_gpio_priv *priv = (struct s5j_gpio_priv *)(dev->priv); + int idx = priv->idx; + s5j_gpio_disable_irq(&s5j_gpio_all[idx]); - if (!(gb = gpio_to_bank(gpio))) { - return -EINVAL; + if (NULL != dev->wdog) { + wd_cancel(dev->wdog); + dev->wdog = NULL; } - port = s5j_gpio_port(gpio); - - value = __raw_readl(gb->base + GPIO_CON); - - return ((value >> (port << 2)) & 0xF); + return OK; } -/** - * @brief int gpio_direction_output(int gpio, int high) / Configure a direction of gpio pin as output and set an initial data - * @param[in] gpio gpio id - * @param[in] high a value of gpio pin(low/high) - * @return == 0: success - * == -EINVAL: invalid gpio +/**************************************************************************** + * Name: s5j_gpio_get * - */ -int gpio_direction_output(int gpio, int high) + * Description: + * Get GPIO value + * + * Input Parameters: + * dev - device + * + * Returned Value: + * >= 0: gpio value + * == -EINVAL: invalid gpio + ****************************************************************************/ +static int s5j_gpio_get(FAR struct gpio_dev_s *dev) { - struct gpio_bank *gb; - unsigned int port; - unsigned int value; - - if (!(gb = gpio_to_bank(gpio))) { + int gpio = ((struct s5j_gpio_priv *)(dev->priv))->gpio; + if (!gpio_valid(gpio)) { return -EINVAL; } - - port = s5j_gpio_port(gpio); - - value = __raw_readl(gb->base + GPIO_DAT); - value &= ~(1 << port); - if (high) { - value |= (1 << port); - } - - __raw_writel(value, gb->base + GPIO_DAT); - - return gpio_cfg_pin(gpio, GPIO_OUTPUT); + return gpio_get_value(gpio); } -/** - * @brief int gpio_direction_input(int gpio) / Configure a direction of gpio pin as input - * @fn int gpio_direction_input(int gpio) - * @param[in] gpio gpio id - * @return == 0: success - * == -EINVAL: invalid gpio +/**************************************************************************** + * Name: s5j_gpio_set * - */ -int gpio_direction_input(int gpio) + * Description: + * Set GPIO value + * + * Input Parameters: + * dev - device + * value - value to set + * + * Returned Value: + * None + * + ****************************************************************************/ +static void s5j_gpio_set(FAR struct gpio_dev_s *dev, FAR unsigned int value) { - return gpio_cfg_pin(gpio, GPIO_INPUT); + int gpio = ((struct s5j_gpio_priv *)(dev->priv))->gpio; + gpio_set_value(gpio, value); } -/** - * @brief int gpio_set_value(int gpio, int high) / Set a data value of gpio pin - * @param[in] gpio gpio id - * @param[in] high a value of gpio pin(low/high) - * @return == 0: success - * == -EINVAL: invalid gpio +/**************************************************************************** + * Name: s5j_gpio_ctrl * - */ -int gpio_set_value(int gpio, int high) + * Description: + * GPIO IOCTRL function + * + * Input Parameters: + * dev - device + * cmd - ioctl command + * arg - ioctl argument + * + * Returned Value: + * >= 0: gpio ret value or OK + * == -EINVAL: invalid gpio + * + ****************************************************************************/ +static int s5j_gpio_ctrl(struct gpio_dev_s *dev, int cmd, unsigned long args) { - struct gpio_bank *gb; - unsigned int port; - unsigned int value; + int gpio = ((struct s5j_gpio_priv *)(dev->priv))->gpio; + bool isenable = true; + GPIO_CB_FUNC func = (GPIO_CB_FUNC)args; - if (!(gb = gpio_to_bank(gpio))) { + if (!gpio_valid(gpio)) { + return -EINVAL; + } + switch (cmd) { + case GPIO_CMD_SET_DIRECTION: + switch (args) { + case GPIO_DIRECTION_OUT: + gpio_cfg_pin(gpio, GPIO_OUTPUT); + break; + case GPIO_DIRECTION_IN: + gpio_cfg_pin(gpio, GPIO_INPUT); + break; + default: + return -EINVAL; + } + break; + case GPIO_CMD_GET_DIRECTION: + return gpio_cfg_get_pin(gpio); + break; + case GPIO_CMD_SET_EDGE: + gpio_eint_set_filter(gpio, EINT_FILTER_DELAY, 0); + switch (args) { + case GPIO_EDGE_NONE: + s5j_gpio_disable_irq(dev); + isenable = false; + break; + case GPIO_EDGE_BOTH: + gpio_eint_set_type(gpio, EINT_TYPE_EDGE_BOTH); + break; + case GPIO_EDGE_RISING: + gpio_eint_set_type(gpio, EINT_TYPE_EDGE_RISING); + break; + case GPIO_EDGE_FALLING: + gpio_eint_set_type(gpio, EINT_TYPE_EDGE_FALLING); + break; + case GPIO_LEVEL_LOW: + gpio_eint_set_type(gpio, EINT_TYPE_LEVEL_LOW); + break; + case GPIO_LEVEL_HIGH: + gpio_eint_set_type(gpio, EINT_TYPE_LEVEL_HIGH); + break; + default: + return -EINVAL; + } + if (isenable) { + s5j_gpio_enable_irq(dev); + } + break; + case GPIO_CMD_GET_EDGE: + switch (gpio_eint_get_type(gpio)) { + case EINT_TYPE_EDGE_BOTH: + return GPIO_EDGE_BOTH; + break; + case EINT_TYPE_EDGE_RISING: + return GPIO_EDGE_RISING; + break; + case EINT_TYPE_EDGE_FALLING: + return GPIO_EDGE_FALLING; + break; + case EINT_TYPE_LEVEL_LOW: + return GPIO_LEVEL_LOW; + break; + case EINT_TYPE_LEVEL_HIGH: + return GPIO_LEVEL_HIGH; + break; + default: + return -EINVAL; + } + break; + case GPIO_CMD_SET_DRIVE: + switch (args) { + case GPIO_DRIVE_NONE: + gpio_set_pull(gpio, GPIO_PULL_NONE); + break; + case GPIO_DRIVE_PULLUP: + gpio_set_pull(gpio, GPIO_PULL_UP); + break; + case GPIO_DRIVE_PULLDOWN: + gpio_set_pull(gpio, GPIO_PULL_DOWN); + break; + default: + return -EINVAL; + } + break; + case GPIO_CMD_GET_DRIVE: + switch (gpio_get_pull(gpio)) { + case GPIO_PULL_NONE: + return GPIO_DRIVE_NONE; + case GPIO_PULL_UP: + return GPIO_DRIVE_PULLUP; + case GPIO_PULL_DOWN: + return GPIO_DRIVE_PULLDOWN; + default: + return -EINVAL; + } + break; + + case GPIO_CMD_SET_CALLBACK: + /* if someone creates wdog, we don't need to create again */ + + if (dev->wdog == NULL) { + dev->wdog = wd_create(); + } + dev->callback = func; + break; + + default: + return -EINVAL; + break; + } + return OK; +} + + + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: gpio_valid + * + * Description: + * Check if given gpio is in a valid range + * + * Input Parameters: + * gpio - port id + * + * Returned Value: + * == 1: valid gpio + * == 0: invalid gpio + * + ****************************************************************************/ +int gpio_valid(int gpio) +{ + unsigned bank, port; + + if (gpio < 0) { + return 0; + } + + if ((gpio & 0xffff0000) != GPIO_MAGIC) { + return 0; + } + + bank = s5j_gpio_bank(gpio); + port = s5j_gpio_port(gpio); + + if (bank >= GPEND) { + return 0; + } + + if (port >= s5jt200_gpio_bank[bank].nr_port) { + return 0; + } + + return 1; +} + +/**************************************************************************** + * Name: gpio_cfg_pin + * + * Description: + * Set gpio pin configuration + * + * Input Parameters: + * gpio - port id + * cfg a mode of gpio pin(input/output/function/irq) + * + * Returned Value: + * == 0: success + * == -EINVAL: invalid gpio + * + ****************************************************************************/ +int gpio_cfg_pin(int gpio, int cfg) +{ + struct gpio_bank *gb; + unsigned port, value; + + if (!(gb = gpio_to_bank(gpio))) { + return -EINVAL; + } + + port = s5j_gpio_port(gpio); + + value = __raw_readl(gb->base + GPIO_CON); + value &= ~CON_MASK(port); + value |= CON_SFR(port, cfg); + + __raw_writel(value, gb->base + GPIO_CON); + + return 0; +} + + +/**************************************************************************** + * Name: gpio_cfg_get_pin + * + * Description: + * Get gpio pin configuration + * + * Input Parameters: + * gpio - port id + * + * Returned Value: + * == 0: input + * == 1: output + * == f: eint + * >= 2: function + * < 0: error + * + ****************************************************************************/ +int gpio_cfg_get_pin(int gpio) +{ + struct gpio_bank *gb; + unsigned int port; + unsigned int value; + + if (!(gb = gpio_to_bank(gpio))) { + return -EINVAL; + } + + port = s5j_gpio_port(gpio); + + value = __raw_readl(gb->base + GPIO_CON); + + return ((value >> (port << 2)) & 0xF); +} + + +/**************************************************************************** + * Name: gpio_direction_output + * + * Description: + * Configure a direction of gpio pin as output and set an initial data + * + * Input Parameters: + * gpio - port id + * high - a value of gpio pin(low/high) + * + * Returned Value: + * == 0: success + * == -EINVAL: invalid gpio + * + ****************************************************************************/ +int gpio_direction_output(int gpio, int high) +{ + struct gpio_bank *gb; + unsigned int port; + unsigned int value; + + if (!(gb = gpio_to_bank(gpio))) { + return -EINVAL; + } + + port = s5j_gpio_port(gpio); + + value = __raw_readl(gb->base + GPIO_DAT); + value &= ~(1 << port); + if (high) { + value |= (1 << port); + } + + __raw_writel(value, gb->base + GPIO_DAT); + + return gpio_cfg_pin(gpio, GPIO_OUTPUT); +} + +/**************************************************************************** + * Name: gpio_direction_input + * + * Description: + * Configure a direction of gpio pin as input + * + * Input Parameters: + * gpio - port id + * + * Returned Value: + * == 0: success + * == -EINVAL: invalid gpio + * + ****************************************************************************/ +int gpio_direction_input(int gpio) +{ + return gpio_cfg_pin(gpio, GPIO_INPUT); +} + +/**************************************************************************** + * Name: gpio_set_value + * + * Description: + * Set a data value of gpio pin + * + * Input Parameters: + * gpio - port id + * high - value of gpio pin(low/high) + * + * Returned Value: + * == 0: success + * == -EINVAL: invalid gpio + * + ****************************************************************************/ +int gpio_set_value(int gpio, int high) +{ + struct gpio_bank *gb; + unsigned int port; + unsigned int value; + + if (!(gb = gpio_to_bank(gpio))) { return -EINVAL; } @@ -642,15 +1031,22 @@ int gpio_set_value(int gpio, int high) return 0; } -/** - * @brief int gpio_get_value(int gpio) / Get a data value of gpio pin - * @fn int gpio_get_value(int gpio) - * @param[in] gpio gpio id - * @return == 1: gpio read as high - * == 0: gpio read as low - * < 0: error + +/**************************************************************************** + * Name: gpio_get_value + * + * Description: + * Get a data value of gpio pin + * + * Input Parameters: + * gpio - port id + * * - */ + * Returned Value: + * == 1: gpio read as high== 0: success + * == 0: gpio read as low == -EINVAL: invalid gpio + * < 0: error + ****************************************************************************/ int gpio_get_value(int gpio) { struct gpio_bank *gb; @@ -668,14 +1064,21 @@ int gpio_get_value(int gpio) return (value >> port) & 1; } -/** - * @brief int gpio_set_pull(int gpio, int mode) / Set a gpio pin as pull up or pull-down - * @param[in] gpio gpio id - * @param[in] mode gpio pin mode(pull up/pull down) - * @return == 0: success - * == -EINVAL: invalid gpio + +/**************************************************************************** + * Name: gpio_set_pull + * + * Description: + * Set a gpio pin as pull up or pull-down * - */ + * Input Parameters: + * gpio - port id + * mode - gpio pin mode(pull up/pull down) + * + * Returned Value: + * == 0: success + * == -EINVAL: invalid gpio + ****************************************************************************/ int gpio_set_pull(int gpio, int mode) { struct gpio_bank *gb; @@ -708,12 +1111,20 @@ int gpio_set_pull(int gpio, int mode) return 0; } -/** - * @brief int gpio_get_pull(int gpio) / Set a gpio pin as pull up or pull-down - * @param[in] gpio gpio id - * @return >= 0: pull up down data +/**************************************************************************** + * Name: gpio_get_pull + * + * Description: + * Get a gpio pin as pull up or pull-down + * + * Input Parameters: + * gpio - port id + * * - */ + * Returned Value: + * >= 0: pull up down data + * + ****************************************************************************/ int gpio_get_pull(int gpio) { struct gpio_bank *gb; @@ -732,15 +1143,20 @@ int gpio_get_pull(int gpio) return value; } -/** +/**************************************************************************** + * Name: gpio_set_drv + * + * Description: + * Set drive strength of gpio pin * - * @brief int gpio_set_drv(int gpio, int mode) / Set drive strength of gpio pin - * @param[in] gpio gpio id - * @param[in] mode strength of gpio pin mode - * @return == 0: success - * == -EINVAL: invalid gpio + * Input Parameters: + * gpio - port id + * mode - strength of gpio pin mode * - */ + * Returned Value: + * == 0: success + * == -EINVAL: invalid gpio + ****************************************************************************/ int gpio_set_drv(int gpio, int mode) { struct gpio_bank *gb; @@ -772,14 +1188,20 @@ int gpio_set_drv(int gpio, int mode) return 0; } -/** +/**************************************************************************** + * Name: gpio_get_drv + * + * Description: + * Get drive strength of gpio pin * - * @brief int gpio_get_drv(int gpio) / Get drive strength of gpio pin - * @param[in] gpio gpio id - * @return <= 0: strength of gpio pin mode - * == -EINVAL: invalid gpio + * Input Parameters: + * gpio - port id + * * - */ + * Returned Value: + * <= 0: strength of gpio pin mode + * == -EINVAL: invalid gpio + ****************************************************************************/ int gpio_get_drv(int gpio) { struct gpio_bank *gb; @@ -797,15 +1219,21 @@ int gpio_get_drv(int gpio) return value; } -/** + +/**************************************************************************** + * Name: gpio_set_rate + * + * Description: + * Set a slew rate of gpio pin * - * @brief int gpio_set_rate(int gpio, int mode) / Set a slew rate of gpio pin - * @param[in] gpio gpio id - * @param[in] mode slew rate of a gpio pin - * @return == 0: success - * == -EINVAL: invalid gpio + * Input Parameters: + * gpio - port id + * mode - slew rate of a gpio pin * - */ + * Returned Value: + * == 0: success + * == -EINVAL: invalid gpio + ****************************************************************************/ int gpio_set_rate(int gpio, int mode) { struct gpio_bank *gb; @@ -834,15 +1262,20 @@ int gpio_set_rate(int gpio, int mode) return 0; } -/** +/**************************************************************************** + * Name: gpio_cfg_pin_pdn + * + * Description: + * Configure a power down mode of gpio pin * - * @brief int gpio_cfg_pin_pdn(int gpio, int cfg) / Configure a power down mode of gpio pin - * @param[in] gpio gpio id - * @param[in] cfg configuration a power down mode of a gpio pin - * @return == 0: success - * == -EINVAL: invalid gpio + * Input Parameters: + * gpio - port id + * cfg - configuration a power down mode of a gpio pin * - */ + * Returned Value: + * == 0: success + * == -EINVAL: invalid gpio + ****************************************************************************/ int gpio_cfg_pin_pdn(int gpio, int cfg) { struct gpio_bank *gb; @@ -864,15 +1297,21 @@ int gpio_cfg_pin_pdn(int gpio, int cfg) return 0; } -/** + +/**************************************************************************** + * Name: gpio_set_pull_pdn + * + * Description: + * Configure a gpio pin as pull-up or pull-down for power down mode * - * @brief int gpio_set_pull_pdn(int gpio, int mode) / Configure a gpio pin as pull-up or pull-down for power down mode - * @param[in] gpio gpio id - * @param[in] mode gpio pin mode(pull up/pull down) - * @return == 0: success - * == -EINVAL: invalid gpio + * Input Parameters: + * gpio - port id + * mode - gpio pin mode(pull up/pull down) * - */ + * Returned Value: + * == 0: success + * == -EINVAL: invalid gpio + ****************************************************************************/ int gpio_set_pull_pdn(int gpio, int mode) { struct gpio_bank *gb; @@ -889,68 +1328,33 @@ int gpio_set_pull_pdn(int gpio, int mode) value &= ~PUDPDN_MASK(port); switch (mode) { - case GPIO_PULL_DOWN: - case GPIO_PULL_UP: - value |= PUDPDN_MODE(port, mode); - break; - default: - return -EINVAL; - } - - __raw_writel(value, gb->base + GPIO_PUDPDN); - - return 0; -} - -/** - * - * @brief void gpio_dump(int gpio) / Print a information of a gpio pin - * @param[in] gpio gpio id - * @return No return - * - */ -void gpio_dump(int gpio) -{ - struct gpio_bank *gb = gpio_to_bank(gpio); - int port = s5j_gpio_port(gpio); - unsigned int con; - unsigned int dat; - unsigned int pull; - unsigned int drv; - unsigned int conpdn; - unsigned int pudpdn; - - con = __raw_readl(gb->base + GPIO_CON) >> (port * 4); - con &= 0xf; - - dat = __raw_readl(gb->base + GPIO_DAT) >> port; - dat &= 1; - - pull = __raw_readl(gb->base + GPIO_PUD) >> (port * 2); - pull &= 0x3; - - drv = __raw_readl(gb->base + GPIO_DRVSR) >> (port * 2); - drv &= 0x3; - - conpdn = __raw_readl(gb->base + GPIO_CONPDN) >> (port * 2); - conpdn &= 0x3; + case GPIO_PULL_DOWN: + case GPIO_PULL_UP: + value |= PUDPDN_MODE(port, mode); + break; + default: + return -EINVAL; + } - pudpdn = __raw_readl(gb->base + GPIO_PUDPDN) >> (port * 2); - pudpdn &= 0x3; + __raw_writel(value, gb->base + GPIO_PUDPDN); -#if defined(CONFIG_S5J_GPIO_LOG_DUMP) - cprintf("%s.%d: con=%x (%s), dat=%s, pull=%s, drv=%s, conpdn=%x (%s), pudpdn=%s\n", gb->name, port, con, con == 0 ? "input" : (con == 1 ? "output" : "function"), dat ? "high" : "low", pull_str[pull], drv_str[drv], conpdn, conpdn == 0 ? "output0" : (conpdn == 1 ? "output1" : (conpdn == 2 ? "input" : "previous state")), pull_str[pudpdn]); -#endif + return 0; } -/** + +/**************************************************************************** + * Name: gpio_eint_mask * - * @brief int gpio_eint_mask(int gpio) / Mask a gpio external interrupt - * @param[in] gpio gpio id - * @return == 0: success - * == -EINVAL: invalid gpio + * Description: + * Mask a gpio external interrupt + * + * Input Parameters: + * gpio - port id * - */ + * Returned Value: + * == 0: success + * == -EINVAL: invalid gpio + ****************************************************************************/ int gpio_eint_mask(int gpio) { u32 mask; @@ -971,14 +1375,19 @@ int gpio_eint_mask(int gpio) return 0; } -/** +/**************************************************************************** + * Name: gpio_eint_unmask + * + * Description: + * Unmask a gpio external interrupt * - * @brief int gpio_eint_unmask(int gpio) / Unmask a gpio external interrupt - * @param[in] gpio gpio id - * @return == 0: success - * == -EINVAL: invalid gpio + * Input Parameters: + * gpio - port id * - */ + * Returned Value: + * == 0: success + * == -EINVAL: invalid gpio + ****************************************************************************/ int gpio_eint_unmask(int gpio) { u32 mask; @@ -999,14 +1408,19 @@ int gpio_eint_unmask(int gpio) return 0; } -/** +/**************************************************************************** + * Name: gpio_eint_ispending + * + * Description: + * Check if gpio external interrupt is pending * - * @brief bool gpio_eint_ispending(int gpio) / Check if a gpio external interrupt is pending - * @param[in] gpio gpio id - * @return == true: gpio external interrupt is pending - * == false: gpio external interrupt is not pending + * Input Parameters: + * gpio - port id * - */ + * Returned Value: + * == true: gpio external interrupt is pending + * == false: gpio external interrupt is not pending + ****************************************************************************/ bool gpio_eint_ispending(int gpio) { u32 pend; @@ -1021,14 +1435,20 @@ bool gpio_eint_ispending(int gpio) return (pend & (1 << port)) ? true : false; } -/** + +/**************************************************************************** + * Name: gpio_eint_clear_pending * - * @brief int gpio_eint_clear_pending(int gpio) / Clear a gpio external interrupt pending - * @param[in] gpio gpio id - * @return == 0: success - * == -EINVAL: invalid gpio + * Description: + * Clear gpio pending external interrupt + * + * Input Parameters: + * gpio - port id * - */ + * Returned Value: + * >= 0: success + * == -EINVAL: invalid gpio + ****************************************************************************/ int gpio_eint_clear_pending(int gpio) { u32 pend; @@ -1055,14 +1475,20 @@ int gpio_eint_clear_pending(int gpio) return 0; } -/** + +/**************************************************************************** + * Name: gpio_eint_enable_filter + * + * Description: + * Enable gpio external interrupt filter * - * @brief int gpio_eint_enable_filter(int gpio) / Enable a gpio external interrupt filter - * @param[in] gpio gpio id - * @return == 0: success - * == -EINVAL: invalid gpio + * Input Parameters: + * gpio - port id * - */ + * Returned Value: + * >= 0: success + * == -EINVAL: invalid gpio + ****************************************************************************/ int gpio_eint_enable_filter(int gpio) { u32 filter_con; @@ -1089,14 +1515,20 @@ int gpio_eint_enable_filter(int gpio) return 0; } -/** + +/**************************************************************************** + * Name: gpio_eint_disable_filter * - * @brief int gpio_eint_disable_filter(int gpio) / Disable a gpio external interrupt filter - * @param[in] gpio gpio id - * @return == 0: success - * == -EINVAL: invalid gpio + * Description: + * Disable a gpio external interrupt filter + * + * Input Parameters: + * gpio - port id * - */ + * Returned Value: + * >= 0: success + * == -EINVAL: invalid gpio + ****************************************************************************/ int gpio_eint_disable_filter(int gpio) { u32 filter_con; @@ -1123,16 +1555,21 @@ int gpio_eint_disable_filter(int gpio) return 0; } -/** +/**************************************************************************** + * Name: gpio_eint_set_filter + * + * Description: + * Configure type and width of a gpio external interrupt filter * - * @brief int gpio_eint_set_filter(int gpio, unsigned type, unsigned width) / Configure type and width of a gpio external interrupt filter - * @param[in] gpio gpio id - * @param[in] type filter type(delay/digital) - * @param[in] width filter width(it will be ignored when filter type is delay) - * @return == 0: success - * == -EINVAL: invalid gpio + * Input Parameters: + * gpio - port id + * type - filter type(delay/digital) + * width - filter width(it will be ignored when filter type is delay) * - */ + * Returned Value: + * >= 0: success + * == -EINVAL: invalid gpio + ****************************************************************************/ int gpio_eint_set_filter(int gpio, unsigned type, unsigned width) { u32 filter_con; @@ -1187,15 +1624,20 @@ int gpio_eint_set_filter(int gpio, unsigned type, unsigned width) return 0; } -/** +/**************************************************************************** + * Name: gpio_eint_set_type + * + * Description: + * Set edge/level type of a gpio external interrurt * - * @brief int gpio_eint_set_type(int gpio, unsigned type) / Configure type of a gpio external interrurt - * @param[in] gpio gpio id - * @param[in] type eint interrupt type (edge/level) - * @return == 0: success - * == -EINVAL: invalid gpio + * Input Parameters: + * gpio - port id + * type - eint interrupt type (edge/level) * - */ + * Returned Value: + * >= 0: success + * == -EINVAL: invalid gpio + ****************************************************************************/ int gpio_eint_set_type(int gpio, unsigned type) { u32 ctrl, mask; @@ -1234,14 +1676,19 @@ int gpio_eint_set_type(int gpio, unsigned type) return 0; } -/** +/**************************************************************************** + * Name: gpio_eint_get_type + * + * Description: + * Get edge/level type of a gpio external interrurt * - * @brief int gpio_eint_get_type(int gpio) / Get Eage type of a gpio external interrurt - * @param[in] gpio gpio id - * @return >= 0: eint interrupt type (edge/level) - * == -EINVAL: invalid gpio + * Input Parameters: + * gpio - port id * - */ + * Returned Value: + * >= 0: eint interrupt type (edge/level) + * == -EINVAL: invalid gpio + ****************************************************************************/ int gpio_eint_get_type(int gpio) { u32 ctrl, mask; @@ -1262,211 +1709,70 @@ int gpio_eint_get_type(int gpio) return ctrl; } -/** - * - * @brief int s5j_gpio_open(FAR struct gpio_dev_s *dev) / GPIO Driver Open - * @param[in] dev Device - * @return == 0: Open success - * == -EINVAL: invalid gpio - * - */ -int s5j_gpio_open(FAR struct gpio_dev_s *dev) -{ - int idx = ((struct s5j_gpio_priv *)(dev->priv))->idx; - if (!isinit) { - up_create_gpio(idx); - } - return OK; -} -/** - * - * @brief int s5j_gpio_close(FAR struct gpio_dev_s *dev) / GPIO Driver close - * @param[in] dev Device - * @return == 0: close success - * == -EINVAL: invalid gpio +/**************************************************************************** + * Name: up_create_gpio * - */ -int s5j_gpio_close(FAR struct gpio_dev_s *dev) -{ - struct s5j_gpio_priv *priv = (struct s5j_gpio_priv *)(dev->priv); - int idx = priv->idx; - s5j_gpio_disable_irq(&s5j_gpio_all[idx]); - - if (NULL != dev->wdog) { - wd_cancel(dev->wdog); - dev->wdog = NULL; - } - - return OK; -} - -/** + * Description: + * Creates GPIO port and expose it to file system: dev/gpioXX * - * @brief int s5j_gpio_get(FAR struct gpio_dev_s *dev) / Get GPIO Value - * @param[in] dev Device - * @return >= 0: gpio value - * == -EINVAL: invalid gpio + * Input Parameters: + * gpio - port id * - */ -int s5j_gpio_get(FAR struct gpio_dev_s *dev) -{ - int gpio = ((struct s5j_gpio_priv *)(dev->priv))->gpio; - if (!gpio_valid(gpio)) { - return -EINVAL; - } - return gpio_get_value(gpio); -} + * Returned Value: + * 0 + ****************************************************************************/ -/** - * - * @brief void s5j_gpio_set(FAR struct gpio_dev_s *dev) / Set GPIO Value - * @param[in] dev Device - * @return No return - * - */ -void s5j_gpio_set(FAR struct gpio_dev_s *dev, FAR unsigned int value) +int up_create_gpio(int32_t idx) { - int gpio = ((struct s5j_gpio_priv *)(dev->priv))->gpio; - gpio_set_value(gpio, value); -} - -/** - * - * @brief int s5j_gpio_ctrl(struct gpio_dev_s *dev, int cmd, unsigned long args) / GPIO IOCTL Control - * @param[in] dev Device - * @param[in] cmd ioctl command - * @param[in] arg ioctl arg - * @return >= 0: gpio eage value or OK - * == -EINVAL: invalid gpio - * - */ +#ifdef CONFIG_GPIO + char path[20]; + struct s5j_gpio_priv *pgpio; + int bank = 0; + int port; + int idx_table[] = { 7, 15, 22, 28, 36, 44, 52, 56, 59, 63, 66 }; -int s5j_gpio_ctrl(struct gpio_dev_s *dev, int cmd, unsigned long args) -{ - int gpio = ((struct s5j_gpio_priv *)(dev->priv))->gpio; - bool isenable = true; - GPIO_CB_FUNC func = (GPIO_CB_FUNC)args; + pgpio = (struct s5j_gpio_priv *)kmm_malloc(sizeof(struct s5j_gpio_priv)); + s5j_gpio_all[idx].ops = &s5j_gpio_ops; + s5j_gpio_all[idx].priv = pgpio; + s5j_gpio_all[idx].wdog = NULL; + s5j_gpio_all[idx].callback = NULL; - if (!gpio_valid(gpio)) { - return -EINVAL; - } - switch (cmd) { - case GPIO_CMD_SET_DIRECTION: - switch (args) { - case GPIO_DIRECTION_OUT: - gpio_cfg_pin(gpio, GPIO_OUTPUT); - break; - case GPIO_DIRECTION_IN: - gpio_cfg_pin(gpio, GPIO_INPUT); - break; - default: - return -EINVAL; - } - break; - case GPIO_CMD_GET_DIRECTION: - return gpio_cfg_get_pin(gpio); - break; - case GPIO_CMD_SET_EDGE: - gpio_eint_set_filter(gpio, EINT_FILTER_DELAY, 0); - switch (args) { - case GPIO_EDGE_NONE: - s5j_gpio_disable_irq(dev); - isenable = false; - break; - case GPIO_EDGE_BOTH: - gpio_eint_set_type(gpio, EINT_TYPE_EDGE_BOTH); - break; - case GPIO_EDGE_RISING: - gpio_eint_set_type(gpio, EINT_TYPE_EDGE_RISING); - break; - case GPIO_EDGE_FALLING: - gpio_eint_set_type(gpio, EINT_TYPE_EDGE_FALLING); - break; - case GPIO_LEVEL_LOW: - gpio_eint_set_type(gpio, EINT_TYPE_LEVEL_LOW); - break; - case GPIO_LEVEL_HIGH: - gpio_eint_set_type(gpio, EINT_TYPE_LEVEL_HIGH); - break; - default: - return -EINVAL; - } - if (isenable) { - s5j_gpio_enable_irq(dev); - } - break; - case GPIO_CMD_GET_EDGE: - switch (gpio_eint_get_type(gpio)) { - case EINT_TYPE_EDGE_BOTH: - return GPIO_EDGE_BOTH; - break; - case EINT_TYPE_EDGE_RISING: - return GPIO_EDGE_RISING; - break; - case EINT_TYPE_EDGE_FALLING: - return GPIO_EDGE_FALLING; - break; - case EINT_TYPE_LEVEL_LOW: - return GPIO_LEVEL_LOW; - break; - case EINT_TYPE_LEVEL_HIGH: - return GPIO_LEVEL_HIGH; - break; - default: - return -EINVAL; - } - break; - case GPIO_CMD_SET_DRIVE: - switch (args) { - case GPIO_DRIVE_NONE: - gpio_set_pull(gpio, GPIO_PULL_NONE); - break; - case GPIO_DRIVE_PULLUP: - gpio_set_pull(gpio, GPIO_PULL_UP); - break; - case GPIO_DRIVE_PULLDOWN: - gpio_set_pull(gpio, GPIO_PULL_DOWN); + for (bank = 0; bank < sizeof(idx_table) / sizeof(int); bank++) { + if (idx_table[bank] >= idx) { break; - default: - return -EINVAL; - } - break; - case GPIO_CMD_GET_DRIVE: - switch (gpio_get_pull(gpio)) { - case GPIO_PULL_NONE: - return GPIO_DRIVE_NONE; - case GPIO_PULL_UP: - return GPIO_DRIVE_PULLUP; - case GPIO_PULL_DOWN: - return GPIO_DRIVE_PULLDOWN; - default: - return -EINVAL; - } - break; - - case GPIO_CMD_SET_CALLBACK: - /* if someone creates wdog, we don't need to create again */ - - if (dev->wdog == NULL) { - dev->wdog = wd_create(); } - dev->callback = func; - break; - - default: - return -EINVAL; - break; } - return OK; + if (bank) { + port = idx - (idx_table[bank - 1] + 1); + } else { + port = idx; + } + pgpio->gpio = s5j_gpio(bank, port); + pgpio->idx = idx; + pgpio->isr_num = gpio_get_irq_id(pgpio->gpio); + snprintf(path, sizeof(path), "/dev/gpio%d", idx); + gpio_register(path, &s5j_gpio_all[idx]); + return 0; +#else + return 0; +#endif } -/** + +/**************************************************************************** + * Name: up_gpioinitialize + * + * Description: + * Init all available GPIO, exposing them to file system: dev/gpioXX + * + * Input Parameters: + * None * - * @brief void up_gpioinitialize(void) / GPIO initailize for Device Driver - * @return no return + * Returned Value: + * None * - */ + ****************************************************************************/ void up_gpioinitialize(void) { int i; @@ -1477,12 +1783,19 @@ void up_gpioinitialize(void) isinit = OK; } -/** +/**************************************************************************** + * Name: up_destroy_gpio + * + * Description: + * Destroy GPIO idx entry, release allocated priv memory. + * + * Input Parameters: + * idx - GPIO index * - * @brief int up_destroy_gpio(int32_t idx) / GPIO Destroy for Device Driver - * @return == 0 return OK + * Returned Value: + * OK * - */ + ****************************************************************************/ int up_destroy_gpio(int32_t idx) { struct s5j_gpio_priv *priv = (struct s5j_gpio_priv *)(s5j_gpio_all[idx].priv); diff --git a/os/arch/arm/src/s5j/s5j_gpio.h b/os/arch/arm/src/s5j/s5j_gpio.h index 8d9562a..6b8a91a 100644 --- a/os/arch/arm/src/s5j/s5j_gpio.h +++ b/os/arch/arm/src/s5j/s5j_gpio.h @@ -180,35 +180,22 @@ extern "C" { #endif /**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** * Public Functions ****************************************************************************/ +int gpio_valid(int gpio); int gpio_cfg_pin(int gpio, int cfg); -int gpio_set_pull(int gpio, int mode); - -int gpio_direction_output(int gpio, int value); +int gpio_cfg_get_pin(int gpio); +int gpio_direction_output(int gpio, int high); int gpio_direction_input(int gpio); -int gpio_set_value(int gpio, int value); +int gpio_set_value(int gpio, int high); int gpio_get_value(int gpio); - -int gpio_valid(int gpio); -const char *gpio_bank_name(int gpio); -int name_to_gpio(const char *name); -int periph_to_gpio(const char *name, char *port); - -int gpio_cfg_get_pin(int gpio); +int gpio_set_pull(int gpio, int mode); +int gpio_get_pull(int gpio); int gpio_set_drv(int gpio, int mode); +int gpio_get_drv(int gpio); int gpio_set_rate(int gpio, int mode); - int gpio_cfg_pin_pdn(int gpio, int cfg); int gpio_set_pull_pdn(int gpio, int mode); - -void gpio_dump(int gpio); -void gpio_status(void); - int gpio_eint_mask(int gpio); int gpio_eint_unmask(int gpio); bool gpio_eint_ispending(int gpio); @@ -217,6 +204,7 @@ int gpio_eint_enable_filter(int gpio); int gpio_eint_disable_filter(int gpio); int gpio_eint_set_filter(int gpio, unsigned type, unsigned width); int gpio_eint_set_type(int gpio, unsigned type); +int gpio_eint_get_type(int gpio); #if defined(__cplusplus) } diff --git a/os/arch/arm/src/s5j/soc/s5jt200_gpio.h b/os/arch/arm/src/s5j/soc/s5jt200_gpio.h index 453f5ba..c460462 100644 --- a/os/arch/arm/src/s5j/soc/s5jt200_gpio.h +++ b/os/arch/arm/src/s5j/soc/s5jt200_gpio.h @@ -34,43 +34,6 @@ enum { GPP4, ETC0, -#if 0 - GPA0 = 0, // ALIVE - GPA1, - GPA2, - GPA3, - GPP0, - GPP1, - GPP2, - GPP3, - GPP4, - GPG0, - GPG1, - GPG2, - GPG3, - ETC0, -#if 1 - ETC1, - GPQ0, - GPZ1, // DISP_AUD - GPC7, // ESE - GPC2, // NFC - GPR0, //FSYS - GPR1, - GPR4, - GPM0, // TOP - GPC0, - GPC1, - GPC4, - GPD1, - GPE0, - GPF0, - GPF1, - GPF3, - GPC3, // TOUCH - GPD2, -#endif -#endif GPEND, }; -- 2.7.4