From eb4089b259db40adc8384495ee20bdce6e9518f1 Mon Sep 17 00:00:00 2001 From: David Wu Date: Sat, 26 Mar 2016 22:26:16 +0800 Subject: [PATCH] pinctrl: rockchip: fix pull setting error for rk3399 Change-Id: Ie52226e751510373abc75754ab756a36ae4f3aaa Signed-off-by: David Wu --- drivers/pinctrl/pinctrl-rockchip.c | 176 ++++++++++++++++++++--------- 1 file changed, 124 insertions(+), 52 deletions(-) diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index f7648da15227..c6c04aca892f 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -101,6 +101,15 @@ enum rockchip_pin_drv_type { 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 +}; + /** * enum type of pin extra drive alignment. */ @@ -135,6 +144,7 @@ struct rockchip_drv { * @bank_num: number of the bank, to account for holes * @iomux: array describing the 4 iomux 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 * @of_node: dt node of this bank * @drvdata: common pinctrl basedata @@ -155,6 +165,7 @@ struct rockchip_pin_bank { u8 bank_num; struct rockchip_iomux iomux[4]; struct rockchip_drv drv[4]; + enum rockchip_pin_pull_type pull_type[4]; bool valid; struct device_node *of_node; struct rockchip_pinctrl *drvdata; @@ -210,6 +221,30 @@ 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(id, pins, label, iom0, iom1, iom2, \ iom3, drv0, drv1, drv2, drv3) \ { \ @@ -274,6 +309,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 { @@ -1354,12 +1417,27 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank, 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) { struct rockchip_pinctrl *info = bank->drvdata; struct rockchip_pin_ctrl *ctrl = info->ctrl; struct regmap *regmap; - int reg, ret; + int reg, ret, pull_type; u8 bit; u32 data; @@ -1383,22 +1461,11 @@ static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num) case RK3366: case RK3368: case RK3399: + pull_type = bank->pull_type[pin_num / 8]; data >>= bit; data &= (1 << RK3188_PULL_BITS_PER_PIN) - 1; - switch (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; + return rockchip_pull_list[pull_type][data]; default: dev_err(info->dev, "unsupported pinctrl type\n"); return -EINVAL; @@ -1411,7 +1478,7 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank, struct rockchip_pinctrl *info = bank->drvdata; struct rockchip_pin_ctrl *ctrl = info->ctrl; struct regmap *regmap; - int reg, ret; + int reg, ret, i, pull_type; unsigned long flags; u8 bit; u32 data, rmask; @@ -1441,30 +1508,27 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank, case RK3366: case RK3368: 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, "unknown pull setting %d\n", pull); + return ret; + } + spin_lock_irqsave(&bank->slock, flags); /* enable the write to the equivalent lower bits */ data = ((1 << RK3188_PULL_BITS_PER_PIN) - 1) << (bit + 16); rmask = data | (data >> 16); - - 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; - } + data |= (ret << bit); ret = regmap_update_bits(regmap, reg, rmask, data); @@ -2941,19 +3005,23 @@ static struct rockchip_pin_ctrl rk3368_pin_ctrl = { }; static struct rockchip_pin_bank rk3399_pin_banks[] = { - PIN_BANK_IOMUX_FLAGS_DRV_FLAGS_OFFSET(0, 32, "gpio0", IOMUX_SOURCE_PMU, - IOMUX_SOURCE_PMU, - IOMUX_SOURCE_PMU, - IOMUX_SOURCE_PMU, - DRV_TYPE_IO_1V8_ONLY, - DRV_TYPE_IO_1V8_ONLY, - DRV_TYPE_IO_DEFAULT, - DRV_TYPE_IO_DEFAULT, - 0x0, - 0x8, - -1, - -1 - ), + PIN_BANK_IOMUX_FLAGS_DRV_FLAGS_OFFSET_PULL_FLAGS(0, 32, "gpio0", + IOMUX_SOURCE_PMU, + IOMUX_SOURCE_PMU, + IOMUX_SOURCE_PMU, + IOMUX_SOURCE_PMU, + DRV_TYPE_IO_1V8_ONLY, + DRV_TYPE_IO_1V8_ONLY, + DRV_TYPE_IO_DEFAULT, + DRV_TYPE_IO_DEFAULT, + 0x0, + 0x8, + -1, + -1, + PULL_TYPE_IO_1V8_ONLY, + PULL_TYPE_IO_1V8_ONLY, + PULL_TYPE_IO_DEFAULT, + PULL_TYPE_IO_DEFAULT), PIN_BANK_IOMUX_FLAGS_DRV_FLAGS_OFFSET(1, 32, "gpio1", IOMUX_SOURCE_PMU, IOMUX_SOURCE_PMU, IOMUX_SOURCE_PMU, @@ -2967,11 +3035,15 @@ static struct rockchip_pin_bank rk3399_pin_banks[] = { 0x30, 0x38 ), - PIN_BANK_DRV_FLAGS(2, 32, "gpio2", DRV_TYPE_IO_1V8_OR_3V0, - DRV_TYPE_IO_1V8_OR_3V0, - DRV_TYPE_IO_1V8_ONLY, - DRV_TYPE_IO_1V8_ONLY - ), + 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_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, DRV_TYPE_IO_3V3_ONLY, DRV_TYPE_IO_3V3_ONLY, -- 2.34.1