提交 3ba6767a 编写于 作者: D David Wu 提交者: Linus Walleij

pinctrl: rockchip: fix pull setting error for rk3399

This patch fixes the pinctrl pull bias setting, since the pull up/down
setting is the contrary for gpio0(just the gpio0a and gpio0b) and
gpio2(just the gpio2c and gpio2d).

From the TRM said, the gpio0a pull polarity setting:
gpio0a_p
GPIO0A PE/PS programmation section, every
GPIO bit corresponding to 2bits[PS:PE]
2'b00: Z(Normal operation);
2'b11: weak 1(pull-up);
2'b01: weak 0(pull-down);
2'b10: Z(Normal operation);

Then, the other gpios setting as the following:
gpio1a_p (e.g.: gpio1, gpio2a, gpio2b, gpio3...)
GPIO1A PU/PD programmation section, every
GPIO bit corresponding to 2bits
2'b00: Z(Normal operation);
2'b01: weak 1(pull-up);
2'b10: weak 0(pull-down);
2'b11: Z(Normal operation);

For example,(rk3399evb board)
sdmmc_cd --->gpio0_a7
localhost / # io -r -4 0xff320040
ff320040: 00004d5f
In general,the value should be 0x0000cd5f since the pin has been set
in the dts.
Signed-off-by: NDavid Wu <david.wu@rock-chips.com>
Signed-off-by: NCaesar Wang <wxt@rock-chips.com>
Cc: linux-gpio@vger.kernel.org
Reviewed-by: NDouglas Anderson <dianders@chromium.org>
Reviewed-by: NHeiko Stuebner <heiko@sntech.de>
Signed-off-by: NLinus Walleij <linus.walleij@linaro.org>
上级 3beed93c
...@@ -98,6 +98,15 @@ enum rockchip_pin_drv_type { ...@@ -98,6 +98,15 @@ enum rockchip_pin_drv_type {
DRV_TYPE_MAX DRV_TYPE_MAX
}; };
/**
* enum type index corresponding to rockchip_pull_list arrays index.
*/
enum rockchip_pin_pull_type {
PULL_TYPE_IO_DEFAULT = 0,
PULL_TYPE_IO_1V8_ONLY,
PULL_TYPE_MAX
};
/** /**
* @drv_type: drive strength variant using rockchip_perpin_drv_type * @drv_type: drive strength variant using rockchip_perpin_drv_type
* @offset: if initialized to -1 it will be autocalculated, by specifying * @offset: if initialized to -1 it will be autocalculated, by specifying
...@@ -123,6 +132,7 @@ struct rockchip_drv { ...@@ -123,6 +132,7 @@ struct rockchip_drv {
* @bank_num: number of the bank, to account for holes * @bank_num: number of the bank, to account for holes
* @iomux: array describing the 4 iomux sources of the bank * @iomux: array describing the 4 iomux sources of the bank
* @drv: array describing the 4 drive strength sources of the bank * @drv: array describing the 4 drive strength sources of the bank
* @pull_type: array describing the 4 pull type sources of the bank
* @valid: are all necessary informations present * @valid: are all necessary informations present
* @of_node: dt node of this bank * @of_node: dt node of this bank
* @drvdata: common pinctrl basedata * @drvdata: common pinctrl basedata
...@@ -143,6 +153,7 @@ struct rockchip_pin_bank { ...@@ -143,6 +153,7 @@ struct rockchip_pin_bank {
u8 bank_num; u8 bank_num;
struct rockchip_iomux iomux[4]; struct rockchip_iomux iomux[4];
struct rockchip_drv drv[4]; struct rockchip_drv drv[4];
enum rockchip_pin_pull_type pull_type[4];
bool valid; bool valid;
struct device_node *of_node; struct device_node *of_node;
struct rockchip_pinctrl *drvdata; struct rockchip_pinctrl *drvdata;
...@@ -198,6 +209,31 @@ struct rockchip_pin_bank { ...@@ -198,6 +209,31 @@ struct rockchip_pin_bank {
}, \ }, \
} }
#define PIN_BANK_DRV_FLAGS_PULL_FLAGS(id, pins, label, drv0, drv1, \
drv2, drv3, pull0, pull1, \
pull2, pull3) \
{ \
.bank_num = id, \
.nr_pins = pins, \
.name = label, \
.iomux = { \
{ .offset = -1 }, \
{ .offset = -1 }, \
{ .offset = -1 }, \
{ .offset = -1 }, \
}, \
.drv = { \
{ .drv_type = drv0, .offset = -1 }, \
{ .drv_type = drv1, .offset = -1 }, \
{ .drv_type = drv2, .offset = -1 }, \
{ .drv_type = drv3, .offset = -1 }, \
}, \
.pull_type[0] = pull0, \
.pull_type[1] = pull1, \
.pull_type[2] = pull2, \
.pull_type[3] = pull3, \
}
#define PIN_BANK_IOMUX_DRV_FLAGS_OFFSET(id, pins, label, iom0, iom1, \ #define PIN_BANK_IOMUX_DRV_FLAGS_OFFSET(id, pins, label, iom0, iom1, \
iom2, iom3, drv0, drv1, drv2, \ iom2, iom3, drv0, drv1, drv2, \
drv3, offset0, offset1, \ drv3, offset0, offset1, \
...@@ -220,6 +256,34 @@ struct rockchip_pin_bank { ...@@ -220,6 +256,34 @@ struct rockchip_pin_bank {
}, \ }, \
} }
#define PIN_BANK_IOMUX_FLAGS_DRV_FLAGS_OFFSET_PULL_FLAGS(id, pins, \
label, iom0, iom1, iom2, \
iom3, drv0, drv1, drv2, \
drv3, offset0, offset1, \
offset2, offset3, pull0, \
pull1, pull2, pull3) \
{ \
.bank_num = id, \
.nr_pins = pins, \
.name = label, \
.iomux = { \
{ .type = iom0, .offset = -1 }, \
{ .type = iom1, .offset = -1 }, \
{ .type = iom2, .offset = -1 }, \
{ .type = iom3, .offset = -1 }, \
}, \
.drv = { \
{ .drv_type = drv0, .offset = offset0 }, \
{ .drv_type = drv1, .offset = offset1 }, \
{ .drv_type = drv2, .offset = offset2 }, \
{ .drv_type = drv3, .offset = offset3 }, \
}, \
.pull_type[0] = pull0, \
.pull_type[1] = pull1, \
.pull_type[2] = pull2, \
.pull_type[3] = pull3, \
}
/** /**
*/ */
struct rockchip_pin_ctrl { struct rockchip_pin_ctrl {
...@@ -1020,12 +1084,27 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank, ...@@ -1020,12 +1084,27 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
return ret; return ret;
} }
static int rockchip_pull_list[PULL_TYPE_MAX][4] = {
{
PIN_CONFIG_BIAS_DISABLE,
PIN_CONFIG_BIAS_PULL_UP,
PIN_CONFIG_BIAS_PULL_DOWN,
PIN_CONFIG_BIAS_BUS_HOLD
},
{
PIN_CONFIG_BIAS_DISABLE,
PIN_CONFIG_BIAS_PULL_DOWN,
PIN_CONFIG_BIAS_DISABLE,
PIN_CONFIG_BIAS_PULL_UP
},
};
static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num) static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num)
{ {
struct rockchip_pinctrl *info = bank->drvdata; struct rockchip_pinctrl *info = bank->drvdata;
struct rockchip_pin_ctrl *ctrl = info->ctrl; struct rockchip_pin_ctrl *ctrl = info->ctrl;
struct regmap *regmap; struct regmap *regmap;
int reg, ret; int reg, ret, pull_type;
u8 bit; u8 bit;
u32 data; u32 data;
...@@ -1048,22 +1127,11 @@ static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num) ...@@ -1048,22 +1127,11 @@ static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num)
case RK3288: case RK3288:
case RK3368: case RK3368:
case RK3399: case RK3399:
pull_type = bank->pull_type[pin_num / 8];
data >>= bit; data >>= bit;
data &= (1 << RK3188_PULL_BITS_PER_PIN) - 1; data &= (1 << RK3188_PULL_BITS_PER_PIN) - 1;
switch (data) { return rockchip_pull_list[pull_type][data];
case 0:
return PIN_CONFIG_BIAS_DISABLE;
case 1:
return PIN_CONFIG_BIAS_PULL_UP;
case 2:
return PIN_CONFIG_BIAS_PULL_DOWN;
case 3:
return PIN_CONFIG_BIAS_BUS_HOLD;
}
dev_err(info->dev, "unknown pull setting\n");
return -EIO;
default: default:
dev_err(info->dev, "unsupported pinctrl type\n"); dev_err(info->dev, "unsupported pinctrl type\n");
return -EINVAL; return -EINVAL;
...@@ -1076,7 +1144,7 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank, ...@@ -1076,7 +1144,7 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
struct rockchip_pinctrl *info = bank->drvdata; struct rockchip_pinctrl *info = bank->drvdata;
struct rockchip_pin_ctrl *ctrl = info->ctrl; struct rockchip_pin_ctrl *ctrl = info->ctrl;
struct regmap *regmap; struct regmap *regmap;
int reg, ret; int reg, ret, i, pull_type;
unsigned long flags; unsigned long flags;
u8 bit; u8 bit;
u32 data, rmask; u32 data, rmask;
...@@ -1105,30 +1173,28 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank, ...@@ -1105,30 +1173,28 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
case RK3288: case RK3288:
case RK3368: case RK3368:
case RK3399: case RK3399:
pull_type = bank->pull_type[pin_num / 8];
ret = -EINVAL;
for (i = 0; i < ARRAY_SIZE(rockchip_pull_list[pull_type]);
i++) {
if (rockchip_pull_list[pull_type][i] == pull) {
ret = i;
break;
}
}
if (ret < 0) {
dev_err(info->dev, "unsupported pull setting %d\n",
pull);
return ret;
}
spin_lock_irqsave(&bank->slock, flags); spin_lock_irqsave(&bank->slock, flags);
/* enable the write to the equivalent lower bits */ /* enable the write to the equivalent lower bits */
data = ((1 << RK3188_PULL_BITS_PER_PIN) - 1) << (bit + 16); data = ((1 << RK3188_PULL_BITS_PER_PIN) - 1) << (bit + 16);
rmask = data | (data >> 16); rmask = data | (data >> 16);
data |= (ret << bit);
switch (pull) {
case PIN_CONFIG_BIAS_DISABLE:
break;
case PIN_CONFIG_BIAS_PULL_UP:
data |= (1 << bit);
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
data |= (2 << bit);
break;
case PIN_CONFIG_BIAS_BUS_HOLD:
data |= (3 << bit);
break;
default:
spin_unlock_irqrestore(&bank->slock, flags);
dev_err(info->dev, "unsupported pull setting %d\n",
pull);
return -EINVAL;
}
ret = regmap_update_bits(regmap, reg, rmask, data); ret = regmap_update_bits(regmap, reg, rmask, data);
...@@ -2552,19 +2618,24 @@ static struct rockchip_pin_ctrl rk3368_pin_ctrl = { ...@@ -2552,19 +2618,24 @@ static struct rockchip_pin_ctrl rk3368_pin_ctrl = {
}; };
static struct rockchip_pin_bank rk3399_pin_banks[] = { static struct rockchip_pin_bank rk3399_pin_banks[] = {
PIN_BANK_IOMUX_DRV_FLAGS_OFFSET(0, 32, "gpio0", IOMUX_SOURCE_PMU, PIN_BANK_IOMUX_FLAGS_DRV_FLAGS_OFFSET_PULL_FLAGS(0, 32, "gpio0",
IOMUX_SOURCE_PMU, IOMUX_SOURCE_PMU,
IOMUX_SOURCE_PMU, IOMUX_SOURCE_PMU,
IOMUX_SOURCE_PMU, IOMUX_SOURCE_PMU,
DRV_TYPE_IO_1V8_ONLY, IOMUX_SOURCE_PMU,
DRV_TYPE_IO_1V8_ONLY, DRV_TYPE_IO_1V8_ONLY,
DRV_TYPE_IO_DEFAULT, DRV_TYPE_IO_1V8_ONLY,
DRV_TYPE_IO_DEFAULT, DRV_TYPE_IO_DEFAULT,
0x0, DRV_TYPE_IO_DEFAULT,
0x8, 0x0,
-1, 0x8,
-1 -1,
), -1,
PULL_TYPE_IO_1V8_ONLY,
PULL_TYPE_IO_1V8_ONLY,
PULL_TYPE_IO_DEFAULT,
PULL_TYPE_IO_DEFAULT
),
PIN_BANK_IOMUX_DRV_FLAGS_OFFSET(1, 32, "gpio1", IOMUX_SOURCE_PMU, PIN_BANK_IOMUX_DRV_FLAGS_OFFSET(1, 32, "gpio1", IOMUX_SOURCE_PMU,
IOMUX_SOURCE_PMU, IOMUX_SOURCE_PMU,
IOMUX_SOURCE_PMU, IOMUX_SOURCE_PMU,
...@@ -2578,11 +2649,15 @@ static struct rockchip_pin_bank rk3399_pin_banks[] = { ...@@ -2578,11 +2649,15 @@ static struct rockchip_pin_bank rk3399_pin_banks[] = {
0x30, 0x30,
0x38 0x38
), ),
PIN_BANK_DRV_FLAGS(2, 32, "gpio2", DRV_TYPE_IO_1V8_OR_3V0, PIN_BANK_DRV_FLAGS_PULL_FLAGS(2, 32, "gpio2", DRV_TYPE_IO_1V8_OR_3V0,
DRV_TYPE_IO_1V8_OR_3V0, DRV_TYPE_IO_1V8_OR_3V0,
DRV_TYPE_IO_1V8_ONLY, DRV_TYPE_IO_1V8_ONLY,
DRV_TYPE_IO_1V8_ONLY DRV_TYPE_IO_1V8_ONLY,
), PULL_TYPE_IO_DEFAULT,
PULL_TYPE_IO_DEFAULT,
PULL_TYPE_IO_1V8_ONLY,
PULL_TYPE_IO_1V8_ONLY
),
PIN_BANK_DRV_FLAGS(3, 32, "gpio3", DRV_TYPE_IO_3V3_ONLY, PIN_BANK_DRV_FLAGS(3, 32, "gpio3", DRV_TYPE_IO_3V3_ONLY,
DRV_TYPE_IO_3V3_ONLY, DRV_TYPE_IO_3V3_ONLY,
DRV_TYPE_IO_3V3_ONLY, DRV_TYPE_IO_3V3_ONLY,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册