Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3ba6767a authored by David Wu's avatar David Wu Committed by Linus Walleij
Browse files

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: default avatarDavid Wu <david.wu@rock-chips.com>
Signed-off-by: default avatarCaesar Wang <wxt@rock-chips.com>
Cc: linux-gpio@vger.kernel.org
Reviewed-by: default avatarDouglas Anderson <dianders@chromium.org>
Reviewed-by: default avatarHeiko Stuebner <heiko@sntech.de>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent 3beed93c
Loading
Loading
Loading
Loading
+127 −52
Original line number Diff line number Diff line
@@ -98,6 +98,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
};

/**
 * @drv_type: drive strength variant using rockchip_perpin_drv_type
 * @offset: if initialized to -1 it will be autocalculated, by specifying
@@ -123,6 +132,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
@@ -143,6 +153,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;
@@ -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,	\
					iom2, iom3, drv0, drv1, drv2,	\
					drv3, offset0, offset1,		\
@@ -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 {
@@ -1020,12 +1084,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;

@@ -1048,22 +1127,11 @@ static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num)
	case RK3288:
	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;
@@ -1076,7 +1144,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;
@@ -1105,30 +1173,28 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
	case RK3288:
	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, "unsupported 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);

@@ -2552,7 +2618,8 @@ static struct rockchip_pin_ctrl rk3368_pin_ctrl = {
};

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,
@@ -2563,7 +2630,11 @@ static struct rockchip_pin_bank rk3399_pin_banks[] = {
							 0x0,
							 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,
					IOMUX_SOURCE_PMU,
@@ -2578,10 +2649,14 @@ static struct rockchip_pin_bank rk3399_pin_banks[] = {
					0x30,
					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_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,
			   DRV_TYPE_IO_3V3_ONLY,