From 483d2c91cb7f766dc7e0c154c30e192530582deb Mon Sep 17 00:00:00 2001 From: Tao Huang Date: Mon, 5 Mar 2018 18:27:20 +0800 Subject: [PATCH] pinctrl: remove unused pinctrl-rk Change-Id: I2420c01b80c56379f926f06d9070817a87a7c0eb Signed-off-by: Tao Huang --- drivers/pinctrl/pinctrl-rk.c | 2136 ------------------------------ include/dt-bindings/pinctrl/rk.h | 185 --- 2 files changed, 2321 deletions(-) delete mode 100755 drivers/pinctrl/pinctrl-rk.c delete mode 100644 include/dt-bindings/pinctrl/rk.h diff --git a/drivers/pinctrl/pinctrl-rk.c b/drivers/pinctrl/pinctrl-rk.c deleted file mode 100755 index 9712b1d12e72..000000000000 --- a/drivers/pinctrl/pinctrl-rk.c +++ /dev/null @@ -1,2136 +0,0 @@ -/* - * Pinctrl driver for Rockchip SoCs - * - * Copyright (c) 2013 MundoReader S.L. - * Author: Heiko Stuebner - * - * With some ideas taken from pinctrl-samsung: - * Copyright (c) 2012 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * Copyright (c) 2012 Linaro Ltd - * http://www.linaro.org - * - * and pinctrl-at91: - * Copyright (C) 2011-2012 Jean-Christophe PLAGNIOL-VILLARD - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "core.h" -#include "pinconf.h" - - -#if 0 -#define pinctrl_dbg(dev, format, arg...) \ - dev_printk(KERN_INFO , dev , format , ## arg) -#else - #define pinctrl_dbg(dev, format, arg...) -#endif - - -/* GPIO control registers */ -#define GPIO_SWPORT_DR 0x00 -#define GPIO_SWPORT_DDR 0x04 -#define GPIO_INTEN 0x30 -#define GPIO_INTMASK 0x34 -#define GPIO_INTTYPE_LEVEL 0x38 -#define GPIO_INT_POLARITY 0x3c -#define GPIO_INT_STATUS 0x40 -#define GPIO_INT_RAWSTATUS 0x44 -#define GPIO_DEBOUNCE 0x48 -#define GPIO_PORTS_EOI 0x4c -#define GPIO_EXT_PORT 0x50 -#define GPIO_LS_SYNC 0x60 - -enum rockchip_pinctrl_type { - RK2928, - RK3066B, - RK3188, - RK3228, - RK3288, - RK3368, -}; - -/** - * Encode variants of iomux registers into a type variable - */ -#define IOMUX_GPIO_ONLY BIT(0) -#define IOMUX_WIDTH_4BIT BIT(1) -#define IOMUX_SOURCE_PMU BIT(2) -#define IOMUX_UNROUTED BIT(3) - -/** - * @type: iomux variant using IOMUX_* constants - * @offset: if initialized to -1 it will be autocalculated, by specifying - * an initial offset value the relevant source offset can be reset - * to a new value for autocalculating the following iomux registers. - */ -struct rockchip_iomux { - int type; - int offset; -}; - -/** - * @reg_base: register base of the gpio bank - * @reg_pull: optional separate register for additional pull settings - * @clk: clock of the gpio bank - * @irq: interrupt of the gpio bank - * @pin_base: first pin number - * @nr_pins: number of pins in this bank - * @name: name of the bank - * @bank_num: number of the bank, to account for holes - * @iomux: array describing the 4 iomux sources of the bank - * @valid: are all necessary informations present - * @of_node: dt node of this bank - * @drvdata: common pinctrl basedata - * @domain: irqdomain of the gpio bank - * @gpio_chip: gpiolib chip - * @grange: gpio range - * @slock: spinlock for the gpio bank - */ -struct rockchip_pin_bank { - void __iomem *reg_base; - struct regmap *regmap_pull; - struct clk *clk; - int irq; - u32 pin_base; - u8 nr_pins; - char *name; - u8 bank_num; - struct rockchip_iomux iomux[4]; - bool valid; - struct device_node *of_node; - struct rockchip_pinctrl *drvdata; - struct irq_domain *domain; - struct gpio_chip gpio_chip; - struct pinctrl_gpio_range grange; - /*spinlock for the gpio bank*/ - spinlock_t slock; - u32 toggle_edge_mode; - u32 suspend_wakeup; - u32 saved_wakeup; -}; - -#define PIN_BANK(id, pins, label) \ - { \ - .bank_num = id, \ - .nr_pins = pins, \ - .name = label, \ - .iomux = { \ - { .offset = -1 }, \ - { .offset = -1 }, \ - { .offset = -1 }, \ - { .offset = -1 }, \ - }, \ - } - -#define PIN_BANK_IOMUX_FLAGS(id, pins, label, iom0, iom1, iom2, iom3) \ - { \ - .bank_num = id, \ - .nr_pins = pins, \ - .name = label, \ - .iomux = { \ - { .type = iom0, .offset = -1 }, \ - { .type = iom1, .offset = -1 }, \ - { .type = iom2, .offset = -1 }, \ - { .type = iom3, .offset = -1 }, \ - }, \ - } - -/** - */ -struct rockchip_pin_ctrl { - struct rockchip_pin_bank *pin_banks; - u32 nr_banks; - u32 nr_pins; - char *label; - enum rockchip_pinctrl_type type; - int grf_mux_offset; - int pmu_mux_offset; - - void (*pull_calc_reg)(struct rockchip_pin_bank *bank, - int pin_num, struct regmap **regmap, - int *reg, u8 *bit); -}; - -struct rockchip_pin_config { - unsigned int func; - unsigned long *configs; - unsigned int nconfigs; -}; - -/** - * struct rockchip_pin_group: represent group of pins of a pinmux function. - * @name: name of the pin group, used to lookup the group. - * @pins: the pins included in this group. - * @npins: number of pins included in this group. - * @func: the mux function number to be programmed when selected. - * @configs: the config values to be set for each pin - * @nconfigs: number of configs for each pin - */ -struct rockchip_pin_group { - const char *name; - unsigned int npins; - unsigned int *pins; - struct rockchip_pin_config *data; -}; - -/** - * struct rockchip_pmx_func: represent a pin function. - * @name: name of the pin function, used to lookup the function. - * @groups: one or more names of pin groups that provide this function. - * @num_groups: number of groups included in @groups. - */ -struct rockchip_pmx_func { - const char *name; - const char **groups; - u8 ngroups; -}; - -struct rockchip_pinctrl { - struct regmap *regmap_base; - int reg_size; - struct regmap *regmap_pull; - struct regmap *regmap_pmu; - struct device *dev; - struct rockchip_pin_ctrl *ctrl; - struct pinctrl_desc pctl; - struct pinctrl_dev *pctl_dev; - struct rockchip_pin_group *groups; - unsigned int ngroups; - struct rockchip_pmx_func *functions; - unsigned int nfunctions; -}; - -static struct regmap_config rockchip_regmap_config = { - .reg_bits = 32, - .val_bits = 32, - .reg_stride = 4, -}; -static struct rockchip_pinctrl *g_info; - -static inline struct rockchip_pin_bank *gc_to_pin_bank(struct gpio_chip *gc) -{ - return container_of(gc, struct rockchip_pin_bank, gpio_chip); -} - -static const inline struct rockchip_pin_group *pinctrl_name_to_group( - const struct rockchip_pinctrl *info, - const char *name) -{ - int i; - - for (i = 0; i < info->ngroups; i++) { - if (!strcmp(info->groups[i].name, name)) - return &info->groups[i]; - } - - return NULL; -} - -/* - * given a pin number that is local to a pin controller, find out the pin bank - * and the register base of the pin bank. - */ -static struct rockchip_pin_bank *pin_to_bank(struct rockchip_pinctrl *info, - unsigned pin) -{ - struct rockchip_pin_bank *b = info->ctrl->pin_banks; - - while (pin >= (b->pin_base + b->nr_pins)) - b++; - - return b; -} - -static struct rockchip_pin_bank *bank_num_to_bank( - struct rockchip_pinctrl *info, - unsigned num) -{ - struct rockchip_pin_bank *b = info->ctrl->pin_banks; - int i; - - for (i = 0; i < info->ctrl->nr_banks; i++, b++) { - if (b->bank_num == num) - return b; - } - - return ERR_PTR(-EINVAL); -} - -/* - * Pinctrl_ops handling - */ - -static int rockchip_get_groups_count(struct pinctrl_dev *pctldev) -{ - struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); - - return info->ngroups; -} - -static const char *rockchip_get_group_name(struct pinctrl_dev *pctldev, - unsigned selector) -{ - struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); - - return info->groups[selector].name; -} - -static int rockchip_get_group_pins(struct pinctrl_dev *pctldev, - unsigned selector, const unsigned **pins, - unsigned *npins) -{ - struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); - - if (selector >= info->ngroups) - return -EINVAL; - - *pins = info->groups[selector].pins; - *npins = info->groups[selector].npins; - - return 0; -} - -static int rockchip_dt_node_to_map(struct pinctrl_dev *pctldev, - struct device_node *np, - struct pinctrl_map **map, unsigned *num_maps) -{ - struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); - const struct rockchip_pin_group *grp; - struct pinctrl_map *new_map; - struct device_node *parent; - int map_num = 1; - int i; - - /* - * first find the group of this node and check if we need to create - * config maps for pins - */ - grp = pinctrl_name_to_group(info, np->name); - if (!grp) { - dev_err(info->dev, "unable to find group for node %s\n", - np->name); - return -EINVAL; - } - - map_num += grp->npins; - new_map = devm_kzalloc(pctldev->dev, sizeof(*new_map) * map_num, - GFP_KERNEL); - if (!new_map) - return -ENOMEM; - - *map = new_map; - *num_maps = map_num; - - /* create mux map */ - parent = of_get_parent(np); - if (!parent) { - devm_kfree(pctldev->dev, new_map); - return -EINVAL; - } - new_map[0].type = PIN_MAP_TYPE_MUX_GROUP; - new_map[0].data.mux.function = parent->name; - new_map[0].data.mux.group = np->name; - of_node_put(parent); - - /* create config map */ - new_map++; - for (i = 0; i < grp->npins; i++) { - new_map[i].type = PIN_MAP_TYPE_CONFIGS_PIN; - new_map[i].data.configs.group_or_pin = - pin_get_name(pctldev, grp->pins[i]); - new_map[i].data.configs.configs = grp->data[i].configs; - new_map[i].data.configs.num_configs = grp->data[i].nconfigs; - } - - pinctrl_dbg(pctldev->dev, "maps: function %s group %s num %d\n", - (*map)->data.mux.function, (*map)->data.mux.group, map_num); - - return 0; -} - -static void rockchip_dt_free_map(struct pinctrl_dev *pctldev, - struct pinctrl_map *map, unsigned num_maps) -{ -} - -static const struct pinctrl_ops rockchip_pctrl_ops = { - .get_groups_count = rockchip_get_groups_count, - .get_group_name = rockchip_get_group_name, - .get_group_pins = rockchip_get_group_pins, - .dt_node_to_map = rockchip_dt_node_to_map, - .dt_free_map = rockchip_dt_free_map, -}; - -/* - * Hardware access - */ - -static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin) -{ - struct rockchip_pinctrl *info = bank->drvdata; - int iomux_num = (pin / 8); - struct regmap *regmap; - unsigned int val; - int reg, ret, mask; - u8 bit; - - if (iomux_num > 3) - return -EINVAL; - - if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) { - dev_err(info->dev, "pin %d is unrouted\n", pin); - return -EINVAL; - } - - if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) - return RK_FUNC_GPIO; - - regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) - ? info->regmap_pmu : info->regmap_base; - - /* get basic quadrupel of mux registers and the correct reg inside */ - mask = (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) ? 0xf : 0x3; - reg = bank->iomux[iomux_num].offset; - if (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) { - if ((pin % 8) >= 4) - reg += 0x4; - bit = (pin % 4) * 4; - } else { - bit = (pin % 8) * 2; - } - - ret = regmap_read(regmap, reg, &val); - if (ret) - return ret; - - return ((val >> bit) & mask); -} - -/* - * Set a new mux function for a pin. - * - * The register is divided into the upper and lower 16 bit. When changing - * a value, the previous register value is not read and changed. Instead - * it seems the changed bits are marked in the upper 16 bit, while the - * changed value gets set in the same offset in the lower 16 bit. - * All pin settings seem to be 2 bit wide in both the upper and lower - * parts. - * @bank: pin bank to change - * @pin: pin to change - * @mux: new mux function to set - */ -static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) -{ - struct rockchip_pinctrl *info = bank->drvdata; - int iomux_num = (pin / 8); - struct regmap *regmap; - int reg, ret, mask; - unsigned long flags; - u8 bit; - u32 data, rmask; - - if (iomux_num > 3) - return -EINVAL; - - if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) { - dev_err(info->dev, "pin %d is unrouted\n", pin); - return -EINVAL; - } - - if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) { - if (mux != RK_FUNC_GPIO) { - dev_err(info->dev, - "pin %d only supports a gpio mux\n", pin); - return -ENOTSUPP; - } else { - return 0; - } - } - - pinctrl_dbg(info->dev, "setting mux of GPIO%d-%d to %d\n", - bank->bank_num, pin, mux); - - regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) - ? info->regmap_pmu : info->regmap_base; - - /* get basic quadrupel of mux registers and the correct reg inside */ - mask = (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) ? 0xf : 0x3; - reg = bank->iomux[iomux_num].offset; - if (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) { - if ((pin % 8) >= 4) - reg += 0x4; - bit = (pin % 4) * 4; - } else { - bit = (pin % 8) * 2; - } - - spin_lock_irqsave(&bank->slock, flags); - - data = (mask << (bit + 16)); - rmask = data | (data >> 16); - data |= (mux & mask) << bit; - ret = regmap_update_bits(regmap, reg, rmask, data); - - spin_unlock_irqrestore(&bank->slock, flags); - - return ret; -} - -#define RK3188_PULL_BITS_PER_PIN 2 -#define RK3188_PULL_PINS_PER_REG 8 -#define RK3188_PULL_BANK_STRIDE 16 -#define RK3188_PULL_PMU_OFFSET 0x64 - -#define RK3228_PULL_PMU_OFFSET 0x100 -#define RK3228_PULL_OFFSET 0x110 - -#define RK3288_PULL_OFFSET 0x140 -#define RK3368_PULL_PMU_OFFSET 0x10 -#define RK3368_PULL_OFFSET 0x100 - -static void rk3288_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, - int pin_num, struct regmap **regmap, - int *reg, u8 *bit) -{ - struct rockchip_pinctrl *info = bank->drvdata; - struct rockchip_pin_ctrl *ctrl = info->ctrl; - - /* The first 24 pins of the first bank are located in PMU */ - if (bank->bank_num == 0) { - if (ctrl->type == RK3228) { - *regmap = info->regmap_base; - *reg = RK3228_PULL_PMU_OFFSET; - } else if (ctrl->type == RK3288) { - *regmap = info->regmap_pmu; - *reg = RK3188_PULL_PMU_OFFSET; - } else if (ctrl->type == RK3368) { - *regmap = info->regmap_pmu; - *reg = RK3368_PULL_PMU_OFFSET; - } - - *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); - *bit = pin_num % RK3188_PULL_PINS_PER_REG; - *bit *= RK3188_PULL_BITS_PER_PIN; - } else { - *regmap = info->regmap_base; - if (ctrl->type == RK3228) - *reg = RK3228_PULL_OFFSET; - else if (ctrl->type == RK3288) - *reg = RK3288_PULL_OFFSET; - else if (ctrl->type == RK3368) - *reg = RK3368_PULL_OFFSET; - - /* correct the offset, as we're starting with the 2nd bank */ - *reg -= 0x10; - *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE; - *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); - - *bit = (pin_num % RK3188_PULL_PINS_PER_REG); - *bit *= RK3188_PULL_BITS_PER_PIN; - } -} - -#define RK3228_DRV_PMU_OFFSET 0x200 -#define RK3228_DRV_GRF_OFFSET 0x210 - -#define RK3288_DRV_PMU_OFFSET 0x70 -#define RK3288_DRV_GRF_OFFSET 0x1c0 -#define RK3288_DRV_BITS_PER_PIN 2 -#define RK3288_DRV_PINS_PER_REG 8 -#define RK3288_DRV_BANK_STRIDE 16 -static int rk3288_drv_list[] = { 2, 4, 8, 12 }; - -#define RK3368_DRV_PMU_OFFSET 0x20 -#define RK3368_DRV_GRF_OFFSET 0x200 - -static void rk3288_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, - int pin_num, struct regmap **regmap, - int *reg, u8 *bit) -{ - struct rockchip_pinctrl *info = bank->drvdata; - struct rockchip_pin_ctrl *ctrl = info->ctrl; - - /* The first 24 pins of the first bank are located in PMU */ - if (bank->bank_num == 0) { - if (ctrl->type == RK3228) { - *regmap = info->regmap_base; - *reg = RK3228_DRV_PMU_OFFSET; - } else if (ctrl->type == RK3288) { - *regmap = info->regmap_pmu; - *reg = RK3288_DRV_PMU_OFFSET; - } else if (ctrl->type == RK3368) { - *regmap = info->regmap_pmu; - *reg = RK3368_DRV_PMU_OFFSET; - } - - *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4); - *bit = pin_num % RK3288_DRV_PINS_PER_REG; - *bit *= RK3288_DRV_BITS_PER_PIN; - } else { - *regmap = info->regmap_base; - if (ctrl->type == RK3228) - *reg = RK3228_DRV_GRF_OFFSET; - else if (ctrl->type == RK3288) - *reg = RK3288_DRV_GRF_OFFSET; - else if (ctrl->type == RK3368) - *reg = RK3368_DRV_GRF_OFFSET; - - /* correct the offset, as we're starting with the 2nd bank */ - *reg -= 0x10; - *reg += bank->bank_num * RK3288_DRV_BANK_STRIDE; - *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4); - - *bit = (pin_num % RK3288_DRV_PINS_PER_REG); - *bit *= RK3288_DRV_BITS_PER_PIN; - } -} - -static int rk3288_get_drive(struct rockchip_pin_bank *bank, int pin_num) -{ - struct regmap *regmap; - int reg, ret; - u32 data; - u8 bit; - - rk3288_calc_drv_reg_and_bit(bank, pin_num, ®map, ®, &bit); - - ret = regmap_read(regmap, reg, &data); - if (ret) - return ret; - - data >>= bit; - data &= (1 << RK3288_DRV_BITS_PER_PIN) - 1; - - return rk3288_drv_list[data]; -} - -static int rk3288_set_drive(struct rockchip_pin_bank *bank, int pin_num, - int strength) -{ - struct rockchip_pinctrl *info = bank->drvdata; - struct regmap *regmap; - unsigned long flags; - int reg, ret, i; - u32 data, rmask; - u8 bit; - - rk3288_calc_drv_reg_and_bit(bank, pin_num, ®map, ®, &bit); - - ret = -EINVAL; - for (i = 0; i < ARRAY_SIZE(rk3288_drv_list); i++) { - if (rk3288_drv_list[i] == strength) { - ret = i; - break; - } - } - - if (ret < 0) { - dev_err(info->dev, "unsupported driver strength %d\n", - strength); - return ret; - } - - spin_lock_irqsave(&bank->slock, flags); - - /* enable the write to the equivalent lower bits */ - data = ((1 << RK3288_DRV_BITS_PER_PIN) - 1) << (bit + 16); - rmask = data | (data >> 16); - data |= (ret << bit); - - ret = regmap_update_bits(regmap, reg, rmask, data); - spin_unlock_irqrestore(&bank->slock, flags); - - return ret; -} - -static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num) -{ - struct rockchip_pinctrl *info = bank->drvdata; - struct rockchip_pin_ctrl *ctrl = info->ctrl; - struct regmap *regmap; - int reg, ret; - u8 bit; - u32 data; - - /* rk3066b does support any pulls */ - if (ctrl->type == RK3066B) - return PIN_CONFIG_BIAS_DISABLE; - - ctrl->pull_calc_reg(bank, pin_num, ®map, ®, &bit); - - ret = regmap_read(regmap, reg, &data); - if (ret) - return ret; - - switch (ctrl->type) { - case RK2928: - return !(data & BIT(bit)) - ? PIN_CONFIG_BIAS_PULL_PIN_DEFAULT - : PIN_CONFIG_BIAS_DISABLE; - case RK3188: - case RK3228: - case RK3288: - case RK3368: - data >>= bit; - data &= (1 << RK3188_PULL_BITS_PER_PIN) - 1; - - switch (data) { - case 0: - return PIN_CONFIG_BIAS_DISABLE; - case 1: - return PIN_CONFIG_BIAS_PULL_UP; - case 2: - return PIN_CONFIG_BIAS_PULL_DOWN; - case 3: - return PIN_CONFIG_BIAS_BUS_HOLD; - } - - dev_err(info->dev, "unknown pull setting\n"); - return -EIO; - default: - dev_err(info->dev, "unsupported pinctrl type\n"); - return -EINVAL; - }; -} - -static int rockchip_set_pull(struct rockchip_pin_bank *bank, - int pin_num, int pull) -{ - struct rockchip_pinctrl *info = bank->drvdata; - struct rockchip_pin_ctrl *ctrl = info->ctrl; - struct regmap *regmap; - int reg, ret; - unsigned long flags; - u8 bit; - u32 data, rmask; - - pinctrl_dbg(info->dev, "setting pull of GPIO%d-%d to %d\n", - bank->bank_num, pin_num, pull); - - /* rk3066b does support any pulls */ - if (ctrl->type == RK3066B) - return pull ? -EINVAL : 0; - - ctrl->pull_calc_reg(bank, pin_num, ®map, ®, &bit); - - switch (ctrl->type) { - case RK2928: - spin_lock_irqsave(&bank->slock, flags); - - data = BIT(bit + 16); - if (pull == PIN_CONFIG_BIAS_DISABLE) - data |= BIT(bit); - ret = regmap_write(regmap, reg, data); - - spin_unlock_irqrestore(&bank->slock, flags); - break; - case RK3188: - case RK3228: - case RK3288: - case RK3368: - spin_lock_irqsave(&bank->slock, flags); - - /* enable the write to the equivalent lower bits */ - data = ((1 << RK3188_PULL_BITS_PER_PIN) - 1) << (bit + 16); - rmask = data | (data >> 16); - - switch (pull) { - case PIN_CONFIG_BIAS_DISABLE: - break; - case PIN_CONFIG_BIAS_PULL_UP: - data |= (1 << bit); - break; - case PIN_CONFIG_BIAS_PULL_DOWN: - data |= (2 << bit); - break; - case PIN_CONFIG_BIAS_BUS_HOLD: - data |= (3 << bit); - break; - default: - spin_unlock_irqrestore(&bank->slock, flags); - dev_err(info->dev, "unsupported pull setting %d\n", - pull); - return -EINVAL; - } - - ret = regmap_update_bits(regmap, reg, rmask, data); - - spin_unlock_irqrestore(&bank->slock, flags); - break; - default: - dev_err(info->dev, "unsupported pinctrl type\n"); - return -EINVAL; - } - - return ret; -} - -/* - * Pinmux_ops handling - */ - -static int rockchip_pmx_get_funcs_count(struct pinctrl_dev *pctldev) -{ - struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); - - return info->nfunctions; -} - -static const char *rockchip_pmx_get_func_name(struct pinctrl_dev *pctldev, - unsigned selector) -{ - struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); - - return info->functions[selector].name; -} - -static int rockchip_pmx_get_groups(struct pinctrl_dev *pctldev, - unsigned selector, - const char * const **groups, - unsigned * const num_groups) -{ - struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); - - *groups = info->functions[selector].groups; - *num_groups = info->functions[selector].ngroups; - - return 0; -} - -static int rockchip_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector, - unsigned group) -{ - struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); - const unsigned int *pins = info->groups[group].pins; - const struct rockchip_pin_config *data = info->groups[group].data; - struct rockchip_pin_bank *bank; - int cnt, ret = 0; - - pinctrl_dbg(info->dev, "enable function %s group %s\n", - info->functions[selector].name, info->groups[group].name); - - /* - * for each pin in the pin group selected, program the correspoding pin - * pin function number in the config register. - */ - for (cnt = 0; cnt < info->groups[group].npins; cnt++) { - bank = pin_to_bank(info, pins[cnt]); - ret = rockchip_set_mux(bank, pins[cnt] - bank->pin_base, - data[cnt].func); - if (ret) - break; - } - - if (ret) { - /* revert the already done pin settings */ - for (cnt--; cnt >= 0; cnt--) - rockchip_set_mux(bank, pins[cnt] - bank->pin_base, 0); - - return ret; - } - - return 0; -} - -static void rockchip_pmx_disable(struct pinctrl_dev *pctldev, - unsigned selector, unsigned group) -{ - struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); - const unsigned int *pins = info->groups[group].pins; - struct rockchip_pin_bank *bank; - int cnt; - - pinctrl_dbg(info->dev, "disable function %s group %s\n", - info->functions[selector].name, info->groups[group].name); - - for (cnt = 0; cnt < info->groups[group].npins; cnt++) { - bank = pin_to_bank(info, pins[cnt]); - rockchip_set_mux(bank, pins[cnt] - bank->pin_base, 0); - } -} - -/* - * The calls to gpio_direction_output() and gpio_direction_input() - * leads to this function call (via the pinctrl_gpio_direction_{input|output}() - * function called from the gpiolib interface). - */ -static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, - struct pinctrl_gpio_range *range, - unsigned offset, bool input) -{ - struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); - struct rockchip_pin_bank *bank; - struct gpio_chip *chip; - int pin, ret; - u32 data; - - chip = range->gc; - bank = gc_to_pin_bank(chip); - pin = offset - chip->base; - - dev_dbg(info->dev, "gpio_direction for pin %u as %s-%d to %s\n", - offset, range->name, pin, input ? "input" : "output"); - - ret = rockchip_set_mux(bank, pin, RK_FUNC_GPIO); - if (ret < 0) - return ret; - - data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR); - /* set bit to 1 for output, 0 for input */ - if (!input) - data |= BIT(pin); - else - data &= ~BIT(pin); - writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR); - - return 0; -} - -static const struct pinmux_ops rockchip_pmx_ops = { - .get_functions_count = rockchip_pmx_get_funcs_count, - .get_function_name = rockchip_pmx_get_func_name, - .get_function_groups = rockchip_pmx_get_groups, - .enable = rockchip_pmx_enable, - .disable = rockchip_pmx_disable, - .gpio_set_direction = rockchip_pmx_gpio_set_direction, -}; - -/* - * Pinconf_ops handling - */ - -static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl, - enum pin_config_param pull) -{ - switch (ctrl->type) { - case RK2928: - return (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT || - pull == PIN_CONFIG_BIAS_DISABLE); - case RK3066B: - return pull ? false : true; - case RK3188: - case RK3228: - case RK3288: - case RK3368: - return (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT); - } - - return false; -} - -static int rockchip_gpio_direction_output( - struct gpio_chip *gc, unsigned offset, int value); -static int rockchip_gpio_direction_input( - struct gpio_chip *gc, unsigned offset); -static int rockchip_gpio_get(struct gpio_chip *gc, unsigned offset); - -/* set the pin config settings for a specified pin */ -static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, - unsigned long configs) -{ - struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); - struct rockchip_pin_bank *bank = pin_to_bank(info, pin); - enum pin_config_param param; - u16 arg; - int rc; - - param = pinconf_to_config_param(configs); - arg = pinconf_to_config_argument(configs); - - switch (param) { - case PIN_CONFIG_BIAS_DISABLE: - rc = rockchip_set_pull(bank, pin - bank->pin_base, - param); - if (rc) - return rc; - break; - case PIN_CONFIG_BIAS_PULL_UP: - case PIN_CONFIG_BIAS_PULL_DOWN: - case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: - case PIN_CONFIG_BIAS_BUS_HOLD: - if (!rockchip_pinconf_pull_valid(info->ctrl, param)) - return -ENOTSUPP; - - if (!arg) - return -EINVAL; - - rc = rockchip_set_pull(bank, pin - bank->pin_base, - param); - if (rc) - return rc; - break; - case PIN_CONFIG_OUTPUT: - rc = rockchip_gpio_direction_output( - &bank->gpio_chip, - pin - bank->pin_base, - arg); - if (rc) - return rc; - break; - - case PIN_CONFIG_INPUT_ENABLE: - if (arg == 1) { - rc = rockchip_gpio_direction_input( - &bank->gpio_chip, pin - bank->pin_base); - if (rc) - return rc; - } - break; - - case PIN_CONFIG_DRIVE_STRENGTH: - /* rk3228 rk3288 rk3368 is the first - with per-pin drive-strength */ - if ((RK3228 != info->ctrl->type) && - (RK3288 != info->ctrl->type) && - (RK3368 != info->ctrl->type)) - return -ENOTSUPP; - - rc = rk3288_set_drive(bank, pin - bank->pin_base, arg); - if (rc < 0) - return rc; - break; - default: - return -ENOTSUPP; - break; - } - - return 0; -} - -/* get the pin config settings for a specified pin */ -static int rockchip_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, - unsigned long *config) -{ - struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); - struct rockchip_pin_bank *bank = pin_to_bank(info, pin); - enum pin_config_param param = pinconf_to_config_param(*config); - u16 arg; - int rc; - - switch (param) { - case PIN_CONFIG_BIAS_DISABLE: - if (rockchip_get_pull(bank, pin - bank->pin_base) != param) - return -EINVAL; - - arg = 0; - break; - case PIN_CONFIG_BIAS_PULL_UP: - case PIN_CONFIG_BIAS_PULL_DOWN: - case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: - case PIN_CONFIG_BIAS_BUS_HOLD: - if (!rockchip_pinconf_pull_valid(info->ctrl, param)) - return -ENOTSUPP; - - if (rockchip_get_pull(bank, pin - bank->pin_base) != param) - return -EINVAL; - - arg = 1; - break; - case PIN_CONFIG_OUTPUT: - rc = rockchip_get_mux(bank, pin - bank->pin_base); - if (rc != RK_FUNC_GPIO) - return -EINVAL; - - rc = rockchip_gpio_get(&bank->gpio_chip, pin - bank->pin_base); - if (rc < 0) - return rc; - - arg = rc ? 1 : 0; - break; - case PIN_CONFIG_DRIVE_STRENGTH: - /* rk3228 rk3288 RK3368 is the first with per-pin - * drive-strength - */ - if ((RK3228 != info->ctrl->type) && - (RK3288 != info->ctrl->type) && - (RK3368 != info->ctrl->type)) - return -ENOTSUPP; - - rc = rk3288_get_drive(bank, pin - bank->pin_base); - if (rc < 0) - return rc; - - arg = rc; - break; - default: - return -ENOTSUPP; - break; - } - - *config = pinconf_to_config_packed(param, arg); - - return 0; -} - -static const struct pinconf_ops rockchip_pinconf_ops = { - .pin_config_get = rockchip_pinconf_get, - .pin_config_set = rockchip_pinconf_set, - .is_generic = true, -}; - -static const struct of_device_id rockchip_bank_match[] = { - { .compatible = "rockchip,gpio-bank" }, - { .compatible = "rockchip,rk3188-gpio-bank0" }, - {}, -}; - -static void rockchip_pinctrl_child_count(struct rockchip_pinctrl *info, - struct device_node *np) -{ - struct device_node *child; - - for_each_child_of_node(np, child) { - if (of_match_node(rockchip_bank_match, child)) - continue; - - info->nfunctions++; - info->ngroups += of_get_child_count(child); - } -} - -static int rockchip_pinctrl_parse_groups(struct device_node *np, - struct rockchip_pin_group *grp, - struct rockchip_pinctrl *info, - u32 index) -{ - struct rockchip_pin_bank *bank; - int size; - const __be32 *list; - int num; - int i, j; - int ret; - - dev_dbg(info->dev, "group(%d): %s\n", index, np->name); - - /* Initialise group */ - grp->name = np->name; - - /* - * the binding format is rockchip,pins = , - * do sanity check and calculate pins number - */ - list = of_get_property(np, "rockchip,pins", &size); - /* we do not check return since it's safe node passed down */ - size /= sizeof(*list); - if (!size || size % 4) { - dev_err(info->dev, - "wrong pins number or pins and configs should be by 4\n"); - return -EINVAL; - } - - grp->npins = size / 4; - - grp->pins = devm_kzalloc(info->dev, grp->npins * sizeof(unsigned int), - GFP_KERNEL); - grp->data = devm_kzalloc(info->dev, grp->npins * - sizeof(struct rockchip_pin_config), - GFP_KERNEL); - if (!grp->pins || !grp->data) - return -ENOMEM; - - for (i = 0, j = 0; i < size; i += 4, j++) { - const __be32 *phandle; - struct device_node *np_config; - - num = be32_to_cpu(*list++); - bank = bank_num_to_bank(info, num); - if (IS_ERR(bank)) - return PTR_ERR(bank); - - grp->pins[j] = bank->pin_base + be32_to_cpu(*list++); - grp->data[j].func = be32_to_cpu(*list++); - - phandle = list++; - if (!phandle) - return -EINVAL; - - np_config = of_find_node_by_phandle(be32_to_cpup(phandle)); - ret = pinconf_generic_parse_dt_config(np_config, - &grp->data[j].configs, - &grp->data[j].nconfigs); - if (ret) - return ret; - } - - return 0; -} - -static int rockchip_pinctrl_parse_functions(struct device_node *np, - struct rockchip_pinctrl *info, - u32 index) -{ - struct device_node *child; - struct rockchip_pmx_func *func; - struct rockchip_pin_group *grp; - int ret; - static u32 grp_index; - u32 i = 0; - - dev_dbg(info->dev, "parse function(%d): %s\n", index, np->name); - - func = &info->functions[index]; - - /* Initialise function */ - func->name = np->name; - func->ngroups = of_get_child_count(np); - if (func->ngroups <= 0) - return 0; - - func->groups = devm_kzalloc(info->dev, - func->ngroups * sizeof(char *), GFP_KERNEL); - if (!func->groups) - return -ENOMEM; - - for_each_child_of_node(np, child) { - func->groups[i] = child->name; - grp = &info->groups[grp_index++]; - ret = rockchip_pinctrl_parse_groups(child, grp, info, i++); - if (ret) - return ret; - } - - return 0; -} - -static int rockchip_pinctrl_parse_dt(struct platform_device *pdev, - struct rockchip_pinctrl *info) -{ - struct device *dev = &pdev->dev; - struct device_node *np = dev->of_node; - struct device_node *child; - int ret; - int i; - - rockchip_pinctrl_child_count(info, np); - - dev_dbg(&pdev->dev, "nfunctions = %d\n", info->nfunctions); - dev_dbg(&pdev->dev, "ngroups = %d\n", info->ngroups); - - info->functions = devm_kzalloc(dev, info->nfunctions * - sizeof(struct rockchip_pmx_func), - GFP_KERNEL); - if (!info->functions) { - dev_err(dev, "failed to allocate memory for function list\n"); - return -EINVAL; - } - - info->groups = devm_kzalloc(dev, info->ngroups * - sizeof(struct rockchip_pin_group), - GFP_KERNEL); - if (!info->groups) { - dev_err(dev, "failed allocate memory for ping group list\n"); - return -EINVAL; - } - - i = 0; - - for_each_child_of_node(np, child) { - if (of_match_node(rockchip_bank_match, child)) - continue; - - ret = rockchip_pinctrl_parse_functions(child, info, i++); - if (ret) { - dev_err(&pdev->dev, "failed to parse function\n"); - return ret; - } - } - - return 0; -} - -static int rockchip_pinctrl_register(struct platform_device *pdev, - struct rockchip_pinctrl *info) -{ - struct pinctrl_desc *ctrldesc = &info->pctl; - struct pinctrl_pin_desc *pindesc, *pdesc; - struct rockchip_pin_bank *pin_bank; - int pin, bank, ret; - int k; - - ctrldesc->name = "rockchip-pinctrl"; - ctrldesc->owner = THIS_MODULE; - ctrldesc->pctlops = &rockchip_pctrl_ops; - ctrldesc->pmxops = &rockchip_pmx_ops; - ctrldesc->confops = &rockchip_pinconf_ops; - - pindesc = devm_kzalloc(&pdev->dev, sizeof(*pindesc) * - info->ctrl->nr_pins, GFP_KERNEL); - if (!pindesc) { - dev_err(&pdev->dev, "mem alloc for pin descriptors failed\n"); - return -ENOMEM; - } - ctrldesc->pins = pindesc; - ctrldesc->npins = info->ctrl->nr_pins; - - pdesc = pindesc; - for (bank = 0 , k = 0; bank < info->ctrl->nr_banks; bank++) { - pin_bank = &info->ctrl->pin_banks[bank]; - for (pin = 0; pin < pin_bank->nr_pins; pin++, k++) { - pdesc->number = k; - pdesc->name = kasprintf(GFP_KERNEL, "%s-%d", - pin_bank->name, pin); - pdesc++; - } - } - - info->pctl_dev = pinctrl_register(ctrldesc, &pdev->dev, info); - if (!info->pctl_dev) { - dev_err(&pdev->dev, "could not register pinctrl driver\n"); - return -EINVAL; - } - - for (bank = 0; bank < info->ctrl->nr_banks; ++bank) { - pin_bank = &info->ctrl->pin_banks[bank]; - pin_bank->grange.name = pin_bank->name; - pin_bank->grange.id = bank; - pin_bank->grange.pin_base = pin_bank->pin_base; - pin_bank->grange.base = pin_bank->gpio_chip.base; - pin_bank->grange.npins = pin_bank->gpio_chip.ngpio; - pin_bank->grange.gc = &pin_bank->gpio_chip; - pinctrl_add_gpio_range(info->pctl_dev, &pin_bank->grange); - } - - ret = rockchip_pinctrl_parse_dt(pdev, info); - if (ret) { - pinctrl_unregister(info->pctl_dev); - return ret; - } - - return 0; -} - -/* - * GPIO handling - */ - -static int rockchip_gpio_request(struct gpio_chip *chip, unsigned offset) -{ - return pinctrl_request_gpio(chip->base + offset); -} - -static void rockchip_gpio_free(struct gpio_chip *chip, unsigned offset) -{ - pinctrl_free_gpio(chip->base + offset); -} - -static void rockchip_gpio_set(struct gpio_chip *gc, unsigned offset, int value) -{ - struct rockchip_pin_bank *bank = gc_to_pin_bank(gc); - void __iomem *reg = bank->reg_base + GPIO_SWPORT_DR; - unsigned long flags; - u32 data; - - spin_lock_irqsave(&bank->slock, flags); - - data = readl(reg); - data &= ~BIT(offset); - if (value) - data |= BIT(offset); - writel(data, reg); - - spin_unlock_irqrestore(&bank->slock, flags); -} - -/* - * Returns the level of the pin for input direction and setting of the DR - * register for output gpios. - */ -static int rockchip_gpio_get(struct gpio_chip *gc, unsigned offset) -{ - struct rockchip_pin_bank *bank = gc_to_pin_bank(gc); - u32 data; - - data = readl(bank->reg_base + GPIO_EXT_PORT); - data >>= offset; - data &= 1; - return data; -} - -/* - * gpiolib gpio_direction_input callback function. The setting of the pin - * mux function as 'gpio input' will be handled by the pinctrl susbsystem - * interface. - */ -static int rockchip_gpio_direction_input(struct gpio_chip *gc, unsigned offset) -{ - return pinctrl_gpio_direction_input(gc->base + offset); -} - -/* - * gpiolib gpio_direction_output callback function. The setting of the pin - * mux function as 'gpio output' will be handled by the pinctrl susbsystem - * interface. - */ -static int rockchip_gpio_direction_output(struct gpio_chip *gc, - unsigned offset, int value) -{ - rockchip_gpio_set(gc, offset, value); - return pinctrl_gpio_direction_output(gc->base + offset); -} - -/* - * gpiolib gpio_to_irq callback function. Creates a mapping between a GPIO pin - * and a virtual IRQ, if not already present. - */ -static int rockchip_gpio_to_irq(struct gpio_chip *gc, unsigned offset) -{ - struct rockchip_pin_bank *bank = gc_to_pin_bank(gc); - unsigned int virq; - - if (!bank->domain) - return -ENXIO; - - virq = irq_create_mapping(bank->domain, offset); - - return (virq) ? : -ENXIO; -} - -static const struct gpio_chip rockchip_gpiolib_chip = { - .request = rockchip_gpio_request, - .free = rockchip_gpio_free, - .set = rockchip_gpio_set, - .get = rockchip_gpio_get, - .direction_input = rockchip_gpio_direction_input, - .direction_output = rockchip_gpio_direction_output, - .to_irq = rockchip_gpio_to_irq, - .owner = THIS_MODULE, -}; - -/* - * Interrupt handling - */ - -static void rockchip_irq_demux(unsigned int irq, struct irq_desc *desc) -{ - struct irq_chip *chip = irq_get_chip(irq); - struct rockchip_pin_bank *bank = irq_get_handler_data(irq); - u32 polarity = 0, data = 0; - u32 pend; - bool edge_changed = false; - - pinctrl_dbg(bank->drvdata->dev, "got irq for bank %s\n", bank->name); - - chained_irq_enter(chip, desc); - - pend = readl_relaxed(bank->reg_base + GPIO_INT_STATUS); - - if (bank->toggle_edge_mode) { - polarity = readl_relaxed(bank->reg_base + - GPIO_INT_POLARITY); - data = readl_relaxed(bank->reg_base + GPIO_EXT_PORT); - } - - while (pend) { - unsigned int virq; - - irq = __ffs(pend); - pend &= ~BIT(irq); - virq = irq_linear_revmap(bank->domain, irq); - - if (!virq) { - dev_err(bank->drvdata->dev, "unmapped irq %d\n", irq); - continue; - } - - pinctrl_dbg(bank->drvdata->dev, "handling irq %d\n", irq); - - /* - * Triggering IRQ on both rising and falling edge - * needs manual intervention. - */ - if (bank->toggle_edge_mode & BIT(irq)) { - if (data & BIT(irq)) - polarity &= ~BIT(irq); - else - polarity |= BIT(irq); - - edge_changed = true; - } - - generic_handle_irq(virq); - } - - if (bank->toggle_edge_mode && edge_changed) { - /* Interrupt params should only be set with ints disabled */ - data = readl_relaxed(bank->reg_base + GPIO_INTEN); - writel_relaxed(0, bank->reg_base + GPIO_INTEN); - writel(polarity, bank->reg_base + GPIO_INT_POLARITY); - writel(data, bank->reg_base + GPIO_INTEN); - } - - chained_irq_exit(chip, desc); -} - -static int rockchip_gpio_irq_set_type(struct irq_data *d, unsigned int type) -{ - struct rockchip_pin_bank *bank = irq_data_get_irq_chip_data(d); - u32 mask = BIT(d->hwirq); - u32 polarity; - u32 level; - u32 data; - int ret; - unsigned long flags; - - /* make sure the pin is configured as gpio input */ - ret = rockchip_set_mux(bank, d->hwirq, RK_FUNC_GPIO); - if (ret < 0) - return ret; - - data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR); - data &= ~mask; - writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR); - - if (type & IRQ_TYPE_EDGE_BOTH) - __irq_set_handler_locked(d->irq, handle_edge_irq); - else - __irq_set_handler_locked(d->irq, handle_level_irq); - - spin_lock_irqsave(&bank->slock, flags); - - level = readl_relaxed(bank->reg_base + GPIO_INTTYPE_LEVEL); - polarity = readl_relaxed(bank->reg_base + GPIO_INT_POLARITY); - - switch (type) { - case IRQ_TYPE_EDGE_BOTH: - bank->toggle_edge_mode |= mask; - level |= mask; - - /* - * Determine gpio state. If 1 next interrupt should be falling - * otherwise rising. - */ - data = readl(bank->reg_base + GPIO_EXT_PORT); - if (data & mask) - polarity &= ~mask; - else - polarity |= mask; - break; - case IRQ_TYPE_EDGE_RISING: - bank->toggle_edge_mode &= ~mask; - level |= mask; - polarity |= mask; - break; - case IRQ_TYPE_EDGE_FALLING: - bank->toggle_edge_mode &= ~mask; - level |= mask; - polarity &= ~mask; - break; - case IRQ_TYPE_LEVEL_HIGH: - bank->toggle_edge_mode &= ~mask; - level &= ~mask; - polarity |= mask; - break; - case IRQ_TYPE_LEVEL_LOW: - bank->toggle_edge_mode &= ~mask; - level &= ~mask; - polarity &= ~mask; - break; - default: - return -EINVAL; - } - - writel_relaxed(level, bank->reg_base + GPIO_INTTYPE_LEVEL); - writel_relaxed(polarity, bank->reg_base + GPIO_INT_POLARITY); - - spin_unlock_irqrestore(&bank->slock, flags); - - return 0; -} - -static inline void rockchip_gpio_bit_op(void __iomem *reg_base - , unsigned int offset, u32 bit, unsigned char flag) -{ - u32 val = __raw_readl(reg_base + offset); - - if (flag) - val |= BIT(bit); - else - val &= ~BIT(bit); - - __raw_writel(val, reg_base + offset); -} - -static inline unsigned gpio_to_bit(struct rockchip_pin_bank *bank, - unsigned gpio) -{ - while (gpio >= (bank->pin_base + bank->nr_pins)) - bank++; - - return gpio - bank->pin_base; -} - -static inline unsigned offset_to_bit(unsigned offset) -{ - return 1u << offset; -} - -static void GPIOEnableIntr(void __iomem *reg_base, unsigned int bit) -{ - rockchip_gpio_bit_op(reg_base, GPIO_INTEN, bit, 1); -} - -static void GPIODisableIntr(void __iomem *reg_base, unsigned int bit) -{ - rockchip_gpio_bit_op(reg_base, GPIO_INTEN, bit, 0); -} - -static void GPIOAckIntr(void __iomem *reg_base, unsigned int bit) -{ - rockchip_gpio_bit_op(reg_base, GPIO_PORTS_EOI, bit, 1); -} - -static int rockchip_gpio_irq_set_wake(struct irq_data *d, unsigned int on) -{ - struct rockchip_pin_bank *bank = irq_data_get_irq_chip_data(d); - u32 bit = d->hwirq; - unsigned long flags; - - spin_lock_irqsave(&bank->slock, flags); - - if (on) - bank->suspend_wakeup |= BIT(bit); - else - bank->suspend_wakeup &= ~BIT(bit); - spin_unlock_irqrestore(&bank->slock, flags); - - return 0; -} - -static void rockchip_gpio_irq_unmask(struct irq_data *d) -{ - struct rockchip_pin_bank *bank = irq_data_get_irq_chip_data(d); - u32 bit = d->hwirq; - unsigned long flags; - - spin_lock_irqsave(&bank->slock, flags); - GPIOEnableIntr(bank->reg_base, bit); - spin_unlock_irqrestore(&bank->slock, flags); -} - -static void rockchip_gpio_irq_mask(struct irq_data *d) -{ - struct rockchip_pin_bank *bank = irq_data_get_irq_chip_data(d); - u32 bit = d->hwirq; - unsigned long flags; - - spin_lock_irqsave(&bank->slock, flags); - GPIODisableIntr(bank->reg_base, bit); - spin_unlock_irqrestore(&bank->slock, flags); -} - -static void rockchip_gpio_irq_ack(struct irq_data *d) -{ - struct rockchip_pin_bank *bank = irq_data_get_irq_chip_data(d); - u32 bit = d->hwirq; - - GPIOAckIntr(bank->reg_base, bit); -} - -static struct irq_chip rockchip_gpio_irq_chip = { - .name = "ROCKCHIP_GPIO_CHIP", - .irq_ack = rockchip_gpio_irq_ack, - .irq_disable = rockchip_gpio_irq_mask, - .irq_mask = rockchip_gpio_irq_mask, - .irq_unmask = rockchip_gpio_irq_unmask, - .irq_set_type = rockchip_gpio_irq_set_type, - .irq_set_wake = rockchip_gpio_irq_set_wake, -}; - -static int rockchip_gpio_irq_map(struct irq_domain *d, unsigned int irq, - irq_hw_number_t hwirq) -{ - struct rockchip_pin_bank *bank = d->host_data; - struct irq_data *irq_data = irq_get_irq_data(irq); - - if (!bank) { - dev_err(bank->drvdata->dev, "%s:bank=0x%p,irq=%d\n", - __func__, bank, irq); - return -EINVAL; - } - - irq_set_chip_and_handler(irq, &rockchip_gpio_irq_chip, - handle_level_irq); - irq_set_chip_data(irq, bank); - set_irq_flags(irq, IRQF_VALID); - - irq_data->hwirq = hwirq; - irq_data->irq = irq; - - pinctrl_dbg(bank->drvdata->dev, "%s:irq = %d, hwirq =%ld\n", - __func__, irq, hwirq); - return 0; -} - -static const struct irq_domain_ops rockchip_gpio_irq_ops = { - .map = rockchip_gpio_irq_map, - .xlate = irq_domain_xlate_twocell, -}; - -static int rockchip_interrupts_register(struct platform_device *pdev, - struct rockchip_pinctrl *info) -{ - struct rockchip_pin_ctrl *ctrl = info->ctrl; - struct rockchip_pin_bank *bank = ctrl->pin_banks; - int i; - - for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { - if (!bank->valid) { - dev_warn(&pdev->dev, "bank %s is not valid\n", - bank->name); - continue; - } - - __raw_writel(0, bank->reg_base + GPIO_INTEN); - - bank->drvdata = info; - bank->domain = irq_domain_add_linear(bank->of_node, 32, - &rockchip_gpio_irq_ops, bank); - if (!bank->domain) { - dev_warn(&pdev->dev, "could not initialize irq domain for bank %s\n", - bank->name); - continue; - } - - irq_set_handler_data(bank->irq, bank); - irq_set_chained_handler(bank->irq, rockchip_irq_demux); - } - - return 0; -} - -static int rockchip_gpiolib_register(struct platform_device *pdev, - struct rockchip_pinctrl *info) -{ - struct rockchip_pin_ctrl *ctrl = info->ctrl; - struct rockchip_pin_bank *bank = ctrl->pin_banks; - struct gpio_chip *gc; - int ret; - int i; - - for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { - if (!bank->valid) { - dev_warn(&pdev->dev, "bank %s is not valid\n", - bank->name); - continue; - } - - bank->gpio_chip = rockchip_gpiolib_chip; - - gc = &bank->gpio_chip; - gc->base = bank->pin_base; - gc->ngpio = bank->nr_pins; - gc->dev = &pdev->dev; - gc->of_node = bank->of_node; - gc->label = bank->name; - - ret = gpiochip_add(gc); - if (ret) { - dev_err(&pdev->dev, "failed to register gpio_chip %s, error code: %d\n", - gc->label, ret); - goto fail; - } - } - - rockchip_interrupts_register(pdev, info); - - return 0; - -fail: - for (--i, --bank; i >= 0; --i, --bank) { - if (!bank->valid) - continue; - - if (gpiochip_remove(&bank->gpio_chip)) - dev_err(&pdev->dev, "gpio chip %s remove failed\n", - bank->gpio_chip.label); - } - return ret; -} - -static int rockchip_gpiolib_unregister(struct platform_device *pdev, - struct rockchip_pinctrl *info) -{ - struct rockchip_pin_ctrl *ctrl = info->ctrl; - struct rockchip_pin_bank *bank = ctrl->pin_banks; - int ret = 0; - int i; - - for (i = 0; !ret && i < ctrl->nr_banks; ++i, ++bank) { - if (!bank->valid) - continue; - - ret = gpiochip_remove(&bank->gpio_chip); - } - - if (ret) - dev_err(&pdev->dev, "gpio chip remove failed\n"); - - return ret; -} - -static int rockchip_get_bank_data(struct rockchip_pin_bank *bank, - struct rockchip_pinctrl *info) -{ - struct resource res; - void __iomem *base; - - if (of_address_to_resource(bank->of_node, 0, &res)) { - dev_err(info->dev, "cannot find IO resource for bank\n"); - return -ENOENT; - } - - bank->reg_base = devm_ioremap_resource(info->dev, &res); - if (IS_ERR(bank->reg_base)) - return PTR_ERR(bank->reg_base); - - /* - * special case, where parts of the pull setting-registers are - * part of the PMU register space - */ - if (of_device_is_compatible(bank->of_node, - "rockchip,rk3188-gpio-bank0")) { - struct device_node *node; - - node = of_parse_phandle(bank->of_node->parent, - "rockchip,pmugrf", 0); - if (!node) { - if (of_address_to_resource(bank->of_node, 1, &res)) { - dev_err(info->dev, "cannot find IO resource for bank\n"); - return -ENOENT; - } - - base = devm_ioremap_resource(info->dev, &res); - if (IS_ERR(base)) - return PTR_ERR(base); - rockchip_regmap_config.max_register = - resource_size(&res) - 4; - rockchip_regmap_config.name = - "rockchip,rk3188-gpio-bank0-pull"; - bank->regmap_pull = devm_regmap_init_mmio(info->dev, - base, - &rockchip_regmap_config); - } - } - - bank->irq = irq_of_parse_and_map(bank->of_node, 0); - - bank->clk = of_clk_get(bank->of_node, 0); - if (IS_ERR(bank->clk)) - return PTR_ERR(bank->clk); - - return clk_prepare_enable(bank->clk); -} - -static const struct of_device_id rockchip_pinctrl_dt_match[]; - -/* retrieve the soc specific data */ -static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data( - struct rockchip_pinctrl *d, - struct platform_device *pdev) -{ - const struct of_device_id *match; - struct device_node *node = pdev->dev.of_node; - struct device_node *np; - struct rockchip_pin_ctrl *ctrl; - struct rockchip_pin_bank *bank; - int grf_offs, pmu_offs, i, j; - - match = of_match_node(rockchip_pinctrl_dt_match, node); - ctrl = (struct rockchip_pin_ctrl *)match->data; - - for_each_child_of_node(node, np) { - if (!of_find_property(np, "gpio-controller", NULL)) - continue; - - bank = ctrl->pin_banks; - for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { - if (!strcmp(bank->name, np->name)) { - bank->of_node = np; - - if (!rockchip_get_bank_data(bank, d)) - bank->valid = true; - - break; - } - } - } - - grf_offs = ctrl->grf_mux_offset; - pmu_offs = ctrl->pmu_mux_offset; - bank = ctrl->pin_banks; - for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { - int bank_pins = 0; - - spin_lock_init(&bank->slock); - bank->drvdata = d; - bank->pin_base = ctrl->nr_pins; - ctrl->nr_pins += bank->nr_pins; - - /* calculate iomux offsets */ - for (j = 0; j < 4; j++) { - struct rockchip_iomux *iom = &bank->iomux[j]; - int inc; - - if (bank_pins >= bank->nr_pins) - break; - - /* preset offset value, set new start value */ - if (iom->offset >= 0) { - if (iom->type & IOMUX_SOURCE_PMU) - pmu_offs = iom->offset; - else - grf_offs = iom->offset; - } else { /* set current offset */ - iom->offset = (iom->type & IOMUX_SOURCE_PMU) ? - pmu_offs : grf_offs; - } - - pinctrl_dbg(d->dev, "bank %d, iomux %d has offset 0x%x\n", - i, j, iom->offset); - - /* - * Increase offset according to iomux width. - * 4bit iomux'es are spread over two registers. - */ - inc = (iom->type & IOMUX_WIDTH_4BIT) ? 8 : 4; - if (iom->type & IOMUX_SOURCE_PMU) - pmu_offs += inc; - else - grf_offs += inc; - - bank_pins += 8; - } - } - - return ctrl; -} - -#ifdef CONFIG_PM -static int rockchip_pinctrl_suspend(void) -{ - struct rockchip_pinctrl *info = g_info; - struct rockchip_pin_ctrl *ctrl = info->ctrl; - struct rockchip_pin_bank *bank = ctrl->pin_banks; - int n; - - for (n = 0; n < ctrl->nr_banks; n++) { - bank->saved_wakeup = __raw_readl(bank->reg_base + GPIO_INTEN); - __raw_writel(bank->suspend_wakeup, bank->reg_base + GPIO_INTEN); - - if (!bank->suspend_wakeup) - clk_disable_unprepare(bank->clk); - bank++; - } - - return 0; -} - -static void rockchip_pinctrl_resume(void) -{ - struct rockchip_pinctrl *info = g_info; - struct rockchip_pin_ctrl *ctrl = info->ctrl; - struct rockchip_pin_bank *bank = ctrl->pin_banks; - int n; - u32 isr; - - for (n = 0; n < ctrl->nr_banks; n++) { - if (!bank->suspend_wakeup) - clk_prepare_enable(bank->clk); - - /* keep enable for resume irq */ - isr = __raw_readl(bank->reg_base + GPIO_INT_STATUS); - __raw_writel(bank->saved_wakeup - | (bank->suspend_wakeup & isr) - , bank->reg_base + GPIO_INTEN); - bank++; - } -} - -static struct syscore_ops rockchip_gpio_syscore_ops = { - .suspend = rockchip_pinctrl_suspend, - .resume = rockchip_pinctrl_resume, -}; -#endif - -static int rockchip_pinctrl_probe(struct platform_device *pdev) -{ - struct rockchip_pinctrl *info; - struct device *dev = &pdev->dev; - struct rockchip_pin_ctrl *ctrl; - struct device_node *np = pdev->dev.of_node, *node; - struct resource *res; - void __iomem *base; - int ret; - - if (!dev->of_node) { - dev_err(dev, "device tree node not found\n"); - return -ENODEV; - } - - info = devm_kzalloc(dev, sizeof(struct rockchip_pinctrl), GFP_KERNEL); - if (!info) - return -ENOMEM; - - info->dev = dev; - - ctrl = rockchip_pinctrl_get_soc_data(info, pdev); - if (!ctrl) { - dev_err(dev, "driver data not available\n"); - return -EINVAL; - } - info->ctrl = ctrl; - g_info = info; - - node = of_parse_phandle(np, "rockchip,grf", 0); - if (node) { - info->regmap_base = syscon_node_to_regmap(node); - if (IS_ERR(info->regmap_base)) - return PTR_ERR(info->regmap_base); - } else { - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(base)) - return PTR_ERR(base); - - rockchip_regmap_config.max_register = resource_size(res) - 4; - rockchip_regmap_config.name = "rockchip,pinctrl"; - info->regmap_base = devm_regmap_init_mmio(&pdev->dev, base, - &rockchip_regmap_config); - - /* to check for the old dt-bindings */ - info->reg_size = resource_size(res); - - /* Honor the old binding, with pull registers as 2nd resource */ - if (ctrl->type == RK3188 && info->reg_size < 0x200) { - res = platform_get_resource(pdev, IORESOURCE_MEM, 1); - base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(base)) - return PTR_ERR(base); - - rockchip_regmap_config.max_register = - resource_size(res) - 4; - rockchip_regmap_config.name = "rockchip,pinctrl-pull"; - info->regmap_pull = devm_regmap_init_mmio(&pdev->dev, - base, - &rockchip_regmap_config); - } - } - - /* try to find the optional reference to the pmu syscon */ - node = of_parse_phandle(np, "rockchip,pmugrf", 0); - if (node) { - info->regmap_pmu = syscon_node_to_regmap(node); - if (IS_ERR(info->regmap_pmu)) - return PTR_ERR(info->regmap_pmu); - } - - ret = rockchip_gpiolib_register(pdev, info); - if (ret) - return ret; - - ret = rockchip_pinctrl_register(pdev, info); - if (ret) { - rockchip_gpiolib_unregister(pdev, info); - return ret; - } - - platform_set_drvdata(pdev, info); -#ifdef CONFIG_PM - register_syscore_ops(&rockchip_gpio_syscore_ops); -#endif - - return 0; -} - -static struct rockchip_pin_bank rk3228_pin_banks[] = { - PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", 0, 0, 0, 0), - PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", 0, 0, 0, 0), - PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0, 0, 0, 0), - PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", 0, 0, 0, 0), -}; - -static struct rockchip_pin_ctrl rk3228_pin_ctrl = { - .pin_banks = rk3228_pin_banks, - .nr_banks = ARRAY_SIZE(rk3228_pin_banks), - .label = "RK3228-GPIO", - .type = RK3228, - .grf_mux_offset = 0x0, - .pmu_mux_offset = 0x0, - .pull_calc_reg = rk3288_calc_pull_reg_and_bit, -}; -static struct rockchip_pin_bank rk3368_pin_banks[] = { - PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU, - IOMUX_SOURCE_PMU, - IOMUX_SOURCE_PMU, - IOMUX_SOURCE_PMU), - PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", 0, 0, 0, 0), - PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0, 0, 0, 0), - PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", 0, 0, 0, 0), -}; - -static struct rockchip_pin_ctrl rk3368_pin_ctrl = { - .pin_banks = rk3368_pin_banks, - .nr_banks = ARRAY_SIZE(rk3368_pin_banks), - .label = "RK3368-GPIO", - .type = RK3368, - .grf_mux_offset = 0x0, - .pmu_mux_offset = 0x0, - .pull_calc_reg = rk3288_calc_pull_reg_and_bit, -}; - -static const struct of_device_id rockchip_pinctrl_dt_match[] = { - { .compatible = "rockchip,rk3228-pinctrl", - .data = (void *)&rk3228_pin_ctrl }, - { .compatible = "rockchip,rk3368-pinctrl", - .data = (void *)&rk3368_pin_ctrl }, - {}, -}; -MODULE_DEVICE_TABLE(of, rockchip_pinctrl_dt_match); - -static struct platform_driver rockchip_pinctrl_driver = { - .probe = rockchip_pinctrl_probe, - .driver = { - .name = "rk3368-pinctrl", - .owner = THIS_MODULE, - .of_match_table = rockchip_pinctrl_dt_match, - }, -}; - -static int __init rockchip_pinctrl_drv_register(void) -{ - return platform_driver_register(&rockchip_pinctrl_driver); -} -postcore_initcall(rockchip_pinctrl_drv_register); - -MODULE_AUTHOR("Heiko Stuebner "); -MODULE_DESCRIPTION("Rockchip pinctrl driver"); -MODULE_LICENSE("GPL v2"); diff --git a/include/dt-bindings/pinctrl/rk.h b/include/dt-bindings/pinctrl/rk.h deleted file mode 100644 index 976424b3fbdc..000000000000 --- a/include/dt-bindings/pinctrl/rk.h +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Header providing constants for Rockchip pinctrl bindings. - * - * Copyright (c) 2013 MundoReader S.L. - * Author: Heiko Stuebner - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef __DT_BINDINGS_ROCKCHIP_PINCTRL_H__ -#define __DT_BINDINGS_ROCKCHIP_PINCTRL_H__ - -#define RK_GPIO0 0 -#define RK_GPIO1 1 -#define RK_GPIO2 2 -#define RK_GPIO3 3 -#define RK_GPIO4 4 -#define RK_GPIO5 5 -#define RK_GPIO6 6 -#define RK_GPIO7 7 -#define RK_GPIO8 8 - - -#define RK_FUNC_GPIO 0 -#define RK_FUNC_1 1 -#define RK_FUNC_2 2 -#define RK_FUNC_3 3 -#define RK_FUNC_4 4 -#define RK_FUNC_5 5 -#define RK_FUNC_6 6 -#define RK_FUNC_7 7 - - - -/*special virtual pin for vcc domain setting*/ -#define VIRTUAL_PIN_FOR_AP0_VCC 0xfA00 -#define VIRTUAL_PIN_FOR_AP1_VCC 0xfA10 -#define VIRTUAL_PIN_FOR_CIF_VCC 0xfA20 -#define VIRTUAL_PIN_FOR_FLASH_VCC 0xfA30 -#define VIRTUAL_PIN_FOR_VCCIO0_VCC 0xfA40 -#define VIRTUAL_PIN_FOR_VCCIO1_VCC 0xfA50 -#define VIRTUAL_PIN_FOR_LCDC0_VCC 0xfA60 -#define VIRTUAL_PIN_FOR_LCDC1_VCC 0xfA70 - - -#define RK32_VIRTUAL_PIN_FOR_LCDC_VCC 0xfA00 -#define RK32_VIRTUAL_PIN_FOR_DVP_VCC 0xfA10 -#define RK32_VIRTUAL_PIN_FOR_FLASH0_VCC 0xfA20 -#define RK32_VIRTUAL_PIN_FOR_FLASH1_VCC 0xfA30 -#define RK32_VIRTUAL_PIN_FOR_WIFI_VCC 0xfA40 -#define RK32_VIRTUAL_PIN_FOR_BB_VCC 0xfA50 -#define RK32_VIRTUAL_PIN_FOR_AUDIO_VCC 0xfA60 -#define RK32_VIRTUAL_PIN_FOR_SDCARD_VCC 0xfA70 - -#define RK32_VIRTUAL_PIN_FOR_GPIO30_VCC 0xfB00 -#define RK32_VIRTUAL_PIN_FOR_GPIO1830_VCC 0xfB10 - - -#define TYPE_PULL_REG 0x01 -#define TYPE_VOL_REG 0x02 -#define TYPE_DRV_REG 0x03 -#define TYPE_TRI_REG 0x04 - -#define RK2928_PULL_OFFSET 0x118 -#define RK2928_PULL_PINS_PER_REG 16 -#define RK2928_PULL_BANK_STRIDE 8 - -#define RK3188_PULL_BITS_PER_PIN 2 -#define RK3188_PULL_PINS_PER_REG 8 -#define RK3188_PULL_BANK_STRIDE 16 - -#define RK3036_PULL_BITS_PER_PIN 1 -#define RK3036_PULL_PINS_PER_REG 16 -#define RK3036_PULL_BANK_STRIDE 8 - -#define RK312X_PULL_BITS_PER_PIN 1 -#define RK312X_PULL_PINS_PER_REG 16 -#define RK312X_PULL_BANK_STRIDE 8 - - -/*warning:don not chang the following value*/ -#define VALUE_PULL_NORMAL 0 -#define VALUE_PULL_UP 1 -#define VALUE_PULL_DOWN 2 -#define VALUE_PULL_KEEP 3 -#define VALUE_PULL_DISABLE 4 //don't set and keep pull default -#define VALUE_PULL_DEFAULT 4 //don't set and keep pull default - - -//for rk2928,rk3036 -#define VALUE_PULL_UPDOWN_DISABLE 0 -#define VALUE_PULL_UPDOWN_ENABLE 1 - -#define VALUE_VOL_DEFAULT 0 -#define VALUE_VOL_3V3 0 -#define VALUE_VOL_1V8 1 - -#define VALUE_DRV_DEFAULT 0 -#define VALUE_DRV_2MA 0 -#define VALUE_DRV_4MA 1 -#define VALUE_DRV_8MA 2 -#define VALUE_DRV_12MA 3 - -#define VALUE_TRI_DEFAULT 0 -#define VALUE_TRI_FALSE 0 -#define VALUE_TRI_TRUE 1 - - -/* - * pin config bit field definitions - * - * pull-up: 1..0 (2) - * voltage: 3..2 (2) - * drive: 5..4 (2) - * trisiate: 7..6 (2) - * - * MSB of each field is presence bit for the config. - */ -#define PULL_SHIFT 0 -#define PULL_PRESENT (1 << 2) -#define VOL_SHIFT 3 -#define VOL_PRESENT (1 << 5) -#define DRV_SHIFT 6 -#define DRV_PRESENT (1 << 8) -#define TRI_SHIFT 9 -#define TRI_PRESENT (1 << 11) - -#define CONFIG_TO_PULL(c) ((c) >> PULL_SHIFT & 0x3) -#define CONFIG_TO_VOL(c) ((c) >> VOL_SHIFT & 0x3) -#define CONFIG_TO_DRV(c) ((c) >> DRV_SHIFT & 0x3) -#define CONFIG_TO_TRI(c) ((c) >> TRI_SHIFT & 0x3) - - -#define MAX_NUM_CONFIGS 4 -#define POS_PULL 0 -#define POS_VOL 1 -#define POS_DRV 2 -#define POS_TRI 3 - - -#define GPIO_A0 0 -#define GPIO_A1 1 -#define GPIO_A2 2 -#define GPIO_A3 3 -#define GPIO_A4 4 -#define GPIO_A5 5 -#define GPIO_A6 6 -#define GPIO_A7 7 -#define GPIO_B0 8 -#define GPIO_B1 9 -#define GPIO_B2 10 -#define GPIO_B3 11 -#define GPIO_B4 12 -#define GPIO_B5 13 -#define GPIO_B6 14 -#define GPIO_B7 15 -#define GPIO_C0 16 -#define GPIO_C1 17 -#define GPIO_C2 18 -#define GPIO_C3 19 -#define GPIO_C4 20 -#define GPIO_C5 21 -#define GPIO_C6 22 -#define GPIO_C7 23 -#define GPIO_D0 24 -#define GPIO_D1 25 -#define GPIO_D2 26 -#define GPIO_D3 27 -#define GPIO_D4 28 -#define GPIO_D5 29 -#define GPIO_D6 30 -#define GPIO_D7 31 - -#define FUNC_TO_GPIO(m) ((m) & 0xfff0) - - -#endif