aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHyeonki Hong <hhk7734@gmail.com>2020-06-18 11:59:22 +0900
committerLinus Walleij <linus.walleij@linaro.org>2020-07-07 13:15:11 +0200
commitf088ab6d4f4ce49d422c220074b7e605f54e2299 (patch)
tree5694e890218aa616f8168eef48b8fbbeb7beb6d8
parentpinctrl: single: fix function name in documentation (diff)
downloadlinux-dev-f088ab6d4f4ce49d422c220074b7e605f54e2299.tar.xz
linux-dev-f088ab6d4f4ce49d422c220074b7e605f54e2299.zip
pinctrl: meson: fix drive strength register and bit calculation
If a GPIO bank has greater than 16 pins, PAD_DS_REG is split into two or more registers. However, when register and bit were calculated, the first register defined in the bank was used, and the bit was calculated based on the first pin. This causes problems in setting the driving strength. The following method was used to solve this problem: A bit is calculated first using predefined strides. Then, If the bit is 32 or more, the register is changed by the quotient of the bit divided by 32. And the bit is set to the remainder. Signed-off-by: Hyeonki Hong <hhk7734@gmail.com> Link: https://lore.kernel.org/r/20200618025916.GA19368@home-desktop Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r--drivers/pinctrl/meson/pinctrl-meson.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/drivers/pinctrl/meson/pinctrl-meson.c b/drivers/pinctrl/meson/pinctrl-meson.c
index 079f8ee8d353..20683cd072bb 100644
--- a/drivers/pinctrl/meson/pinctrl-meson.c
+++ b/drivers/pinctrl/meson/pinctrl-meson.c
@@ -56,6 +56,10 @@
#include "../pinctrl-utils.h"
#include "pinctrl-meson.h"
+static const unsigned int meson_bit_strides[] = {
+ 1, 1, 1, 1, 1, 2, 1
+};
+
/**
* meson_get_bank() - find the bank containing a given pin
*
@@ -96,8 +100,9 @@ static void meson_calc_reg_and_bit(struct meson_bank *bank, unsigned int pin,
{
struct meson_reg_desc *desc = &bank->regs[reg_type];
- *reg = desc->reg * 4;
- *bit = desc->bit + pin - bank->first;
+ *bit = (desc->bit + pin - bank->first) * meson_bit_strides[reg_type];
+ *reg = (desc->reg + (*bit / 32)) * 4;
+ *bit &= 0x1f;
}
static int meson_get_groups_count(struct pinctrl_dev *pcdev)
@@ -314,7 +319,6 @@ static int meson_pinconf_set_drive_strength(struct meson_pinctrl *pc,
return ret;
meson_calc_reg_and_bit(bank, pin, REG_DS, &reg, &bit);
- bit = bit << 1;
if (drive_strength_ua <= 500) {
ds_val = MESON_PINCONF_DRV_500UA;
@@ -441,7 +445,6 @@ static int meson_pinconf_get_drive_strength(struct meson_pinctrl *pc,
return ret;
meson_calc_reg_and_bit(bank, pin, REG_DS, &reg, &bit);
- bit = bit << 1;
ret = regmap_read(pc->reg_ds, reg, &val);
if (ret)