diff options
author | Tomasz Figa <tomasz.figa@gmail.com> | 2013-03-18 17:31:53 -0400 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2013-04-09 03:42:25 -0400 |
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, | |||
275 | *offset = pin - b->pin_base; | 275 | *offset = pin - b->pin_base; |
276 | if (bank) | 276 | if (bank) |
277 | *bank = b; | 277 | *bank = b; |
278 | |||
279 | /* some banks have two config registers in a single bank */ | ||
280 | if (*offset * b->func_width > BITS_PER_LONG) | ||
281 | *reg += 4; | ||
282 | } | 278 | } |
283 | 279 | ||
284 | /* enable or disable a pinmux function */ | 280 | /* enable or disable a pinmux function */ |
@@ -310,11 +306,11 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector, | |||
310 | 306 | ||
311 | spin_lock_irqsave(&bank->slock, flags); | 307 | spin_lock_irqsave(&bank->slock, flags); |
312 | 308 | ||
313 | data = readl(reg); | 309 | data = readl(reg + type->reg_offset[PINCFG_TYPE_FUNC]); |
314 | data &= ~(mask << shift); | 310 | data &= ~(mask << shift); |
315 | if (enable) | 311 | if (enable) |
316 | data |= drvdata->pin_groups[group].func << shift; | 312 | data |= drvdata->pin_groups[group].func << shift; |
317 | writel(data, reg); | 313 | writel(data, reg + type->reg_offset[PINCFG_TYPE_FUNC]); |
318 | 314 | ||
319 | spin_unlock_irqrestore(&bank->slock, flags); | 315 | spin_unlock_irqrestore(&bank->slock, flags); |
320 | } | 316 | } |
@@ -355,7 +351,8 @@ static int samsung_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev, | |||
355 | drvdata = pinctrl_dev_get_drvdata(pctldev); | 351 | drvdata = pinctrl_dev_get_drvdata(pctldev); |
356 | 352 | ||
357 | pin_offset = offset - bank->pin_base; | 353 | pin_offset = offset - bank->pin_base; |
358 | reg = drvdata->virt_base + bank->pctl_offset; | 354 | reg = drvdata->virt_base + bank->pctl_offset + |
355 | type->reg_offset[PINCFG_TYPE_FUNC]; | ||
359 | 356 | ||
360 | mask = (1 << type->fld_width[PINCFG_TYPE_FUNC]) - 1; | 357 | mask = (1 << type->fld_width[PINCFG_TYPE_FUNC]) - 1; |
361 | shift = pin_offset * type->fld_width[PINCFG_TYPE_FUNC]; | 358 | 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, | |||
401 | &pin_offset, &bank); | 398 | &pin_offset, &bank); |
402 | type = bank->type; | 399 | type = bank->type; |
403 | 400 | ||
404 | switch (cfg_type) { | ||
405 | case PINCFG_TYPE_PUD: | ||
406 | cfg_reg = PUD_REG; | ||
407 | break; | ||
408 | case PINCFG_TYPE_DRV: | ||
409 | cfg_reg = DRV_REG; | ||
410 | break; | ||
411 | case PINCFG_TYPE_CON_PDN: | ||
412 | cfg_reg = CONPDN_REG; | ||
413 | break; | ||
414 | case PINCFG_TYPE_PUD_PDN: | ||
415 | cfg_reg = PUDPDN_REG; | ||
416 | break; | ||
417 | default: | ||
418 | WARN_ON(1); | ||
419 | return -EINVAL; | ||
420 | } | ||
421 | |||
422 | if (cfg_type >= PINCFG_TYPE_NUM || !type->fld_width[cfg_type]) | 401 | if (cfg_type >= PINCFG_TYPE_NUM || !type->fld_width[cfg_type]) |
423 | return -EINVAL; | 402 | return -EINVAL; |
424 | 403 | ||
425 | width = type->fld_width[cfg_type]; | 404 | width = type->fld_width[cfg_type]; |
405 | cfg_reg = type->reg_offset[cfg_type]; | ||
426 | 406 | ||
427 | spin_lock_irqsave(&bank->slock, flags); | 407 | spin_lock_irqsave(&bank->slock, flags); |
428 | 408 | ||
@@ -511,11 +491,11 @@ static void samsung_gpio_set(struct gpio_chip *gc, unsigned offset, int value) | |||
511 | 491 | ||
512 | spin_lock_irqsave(&bank->slock, flags); | 492 | spin_lock_irqsave(&bank->slock, flags); |
513 | 493 | ||
514 | data = readl(reg + DAT_REG); | 494 | data = readl(reg + type->reg_offset[PINCFG_TYPE_DAT]); |
515 | data &= ~(1 << offset); | 495 | data &= ~(1 << offset); |
516 | if (value) | 496 | if (value) |
517 | data |= 1 << offset; | 497 | data |= 1 << offset; |
518 | writel(data, reg + DAT_REG); | 498 | writel(data, reg + type->reg_offset[PINCFG_TYPE_DAT]); |
519 | 499 | ||
520 | spin_unlock_irqrestore(&bank->slock, flags); | 500 | spin_unlock_irqrestore(&bank->slock, flags); |
521 | } | 501 | } |
@@ -526,10 +506,11 @@ static int samsung_gpio_get(struct gpio_chip *gc, unsigned offset) | |||
526 | void __iomem *reg; | 506 | void __iomem *reg; |
527 | u32 data; | 507 | u32 data; |
528 | struct samsung_pin_bank *bank = gc_to_pin_bank(gc); | 508 | struct samsung_pin_bank *bank = gc_to_pin_bank(gc); |
509 | struct samsung_pin_bank_type *type = bank->type; | ||
529 | 510 | ||
530 | reg = bank->drvdata->virt_base + bank->pctl_offset; | 511 | reg = bank->drvdata->virt_base + bank->pctl_offset; |
531 | 512 | ||
532 | data = readl(reg + DAT_REG); | 513 | data = readl(reg + type->reg_offset[PINCFG_TYPE_DAT]); |
533 | data >>= offset; | 514 | data >>= offset; |
534 | data &= 1; | 515 | data &= 1; |
535 | return data; | 516 | return data; |