Commit f088ab6d authored by Hyeonki Hong's avatar Hyeonki Hong Committed by Linus Walleij

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: default avatarHyeonki Hong <hhk7734@gmail.com>
Link: https://lore.kernel.org/r/20200618025916.GA19368@home-desktopSigned-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent bc6d2015
...@@ -56,6 +56,10 @@ ...@@ -56,6 +56,10 @@
#include "../pinctrl-utils.h" #include "../pinctrl-utils.h"
#include "pinctrl-meson.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 * 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, ...@@ -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]; struct meson_reg_desc *desc = &bank->regs[reg_type];
*reg = desc->reg * 4; *bit = (desc->bit + pin - bank->first) * meson_bit_strides[reg_type];
*bit = desc->bit + pin - bank->first; *reg = (desc->reg + (*bit / 32)) * 4;
*bit &= 0x1f;
} }
static int meson_get_groups_count(struct pinctrl_dev *pcdev) 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, ...@@ -314,7 +319,6 @@ static int meson_pinconf_set_drive_strength(struct meson_pinctrl *pc,
return ret; return ret;
meson_calc_reg_and_bit(bank, pin, REG_DS, &reg, &bit); meson_calc_reg_and_bit(bank, pin, REG_DS, &reg, &bit);
bit = bit << 1;
if (drive_strength_ua <= 500) { if (drive_strength_ua <= 500) {
ds_val = MESON_PINCONF_DRV_500UA; ds_val = MESON_PINCONF_DRV_500UA;
...@@ -441,7 +445,6 @@ static int meson_pinconf_get_drive_strength(struct meson_pinctrl *pc, ...@@ -441,7 +445,6 @@ static int meson_pinconf_get_drive_strength(struct meson_pinctrl *pc,
return ret; return ret;
meson_calc_reg_and_bit(bank, pin, REG_DS, &reg, &bit); meson_calc_reg_and_bit(bank, pin, REG_DS, &reg, &bit);
bit = bit << 1;
ret = regmap_read(pc->reg_ds, reg, &val); ret = regmap_read(pc->reg_ds, reg, &val);
if (ret) if (ret)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment