diff options
author | Tomasz Figa <tomasz.figa@gmail.com> | 2013-03-18 22:31:53 +0100 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2013-04-09 09:42:25 +0200 |
commit | 43fc9e7fab903ea3c525c693c5e9bf566d521380 (patch) | |
tree | 26f7d9ccb1e1ee260981e6382a9a6f772601b57a /drivers/pinctrl/pinctrl-samsung.c | |
parent | 499147c9dbceee27c63bf8e6b604aca1737e9e0c (diff) |
pinctrl: samsung: Remove hardcoded register offsets
This patch replaces statically hardcoded register offsets of Exynos SoCs
with an array of register offsets in samsung_pin_bank_type struct.
Thanks to this change, support for SoCs with other set and order of
registers can be added (e.g. S3C24xx and S3C64xx).
Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl/pinctrl-samsung.c')
-rw-r--r-- | drivers/pinctrl/pinctrl-samsung.c | 37 |
1 files changed, 9 insertions, 28 deletions
diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c index 97dd56024e33..b917ed36fb65 100644 --- a/drivers/pinctrl/pinctrl-samsung.c +++ b/drivers/pinctrl/pinctrl-samsung.c @@ -275,10 +275,6 @@ static void pin_to_reg_bank(struct samsung_pinctrl_drv_data *drvdata, *offset = pin - b->pin_base; if (bank) *bank = b; - - /* some banks have two config registers in a single bank */ - if (*offset * b->func_width > BITS_PER_LONG) - *reg += 4; } /* enable or disable a pinmux function */ @@ -310,11 +306,11 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector, spin_lock_irqsave(&bank->slock, flags); - data = readl(reg); + data = readl(reg + type->reg_offset[PINCFG_TYPE_FUNC]); data &= ~(mask << shift); if (enable) data |= drvdata->pin_groups[group].func << shift; - writel(data, reg); + writel(data, reg + type->reg_offset[PINCFG_TYPE_FUNC]); spin_unlock_irqrestore(&bank->slock, flags); } @@ -355,7 +351,8 @@ static int samsung_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev, drvdata = pinctrl_dev_get_drvdata(pctldev); pin_offset = offset - bank->pin_base; - reg = drvdata->virt_base + bank->pctl_offset; + reg = drvdata->virt_base + bank->pctl_offset + + type->reg_offset[PINCFG_TYPE_FUNC]; mask = (1 << type->fld_width[PINCFG_TYPE_FUNC]) - 1; shift = pin_offset * type->fld_width[PINCFG_TYPE_FUNC]; @@ -401,28 +398,11 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin, &pin_offset, &bank); type = bank->type; - switch (cfg_type) { - case PINCFG_TYPE_PUD: - cfg_reg = PUD_REG; - break; - case PINCFG_TYPE_DRV: - cfg_reg = DRV_REG; - break; - case PINCFG_TYPE_CON_PDN: - cfg_reg = CONPDN_REG; - break; - case PINCFG_TYPE_PUD_PDN: - cfg_reg = PUDPDN_REG; - break; - default: - WARN_ON(1); - return -EINVAL; - } - if (cfg_type >= PINCFG_TYPE_NUM || !type->fld_width[cfg_type]) return -EINVAL; width = type->fld_width[cfg_type]; + cfg_reg = type->reg_offset[cfg_type]; spin_lock_irqsave(&bank->slock, flags); @@ -511,11 +491,11 @@ static void samsung_gpio_set(struct gpio_chip *gc, unsigned offset, int value) spin_lock_irqsave(&bank->slock, flags); - data = readl(reg + DAT_REG); + data = readl(reg + type->reg_offset[PINCFG_TYPE_DAT]); data &= ~(1 << offset); if (value) data |= 1 << offset; - writel(data, reg + DAT_REG); + writel(data, reg + type->reg_offset[PINCFG_TYPE_DAT]); spin_unlock_irqrestore(&bank->slock, flags); } @@ -526,10 +506,11 @@ static int samsung_gpio_get(struct gpio_chip *gc, unsigned offset) void __iomem *reg; u32 data; struct samsung_pin_bank *bank = gc_to_pin_bank(gc); + struct samsung_pin_bank_type *type = bank->type; reg = bank->drvdata->virt_base + bank->pctl_offset; - data = readl(reg + DAT_REG); + data = readl(reg + type->reg_offset[PINCFG_TYPE_DAT]); data >>= offset; data &= 1; return data; |