summaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/pinctrl-samsung.c
diff options
context:
space:
mode:
authorTomasz Figa <tomasz.figa@gmail.com>2013-03-18 22:31:53 +0100
committerLinus Walleij <linus.walleij@linaro.org>2013-04-09 09:42:25 +0200
commit43fc9e7fab903ea3c525c693c5e9bf566d521380 (patch)
tree26f7d9ccb1e1ee260981e6382a9a6f772601b57a /drivers/pinctrl/pinctrl-samsung.c
parent499147c9dbceee27c63bf8e6b604aca1737e9e0c (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.c37
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;