Commit 6d3ea312 authored by Fabio Estevam's avatar Fabio Estevam Committed by Linus Walleij
Browse files

pinctrl: rockchip: Add RV1103B pinctrl support



Add pinctrl support for the RV1103B.

Based on the 5.10 Rockchip vendor kernel driver.

Signed-off-by: default avatarFabio Estevam <festevam@nabladev.com>
Signed-off-by: default avatarLinus Walleij <linusw@kernel.org>
parent 540e666a
Loading
Loading
Loading
Loading
+312 −1
Original line number Diff line number Diff line
@@ -467,6 +467,22 @@ static const struct pinctrl_ops rockchip_pctrl_ops = {
 * Hardware access
 */

static struct rockchip_mux_recalced_data rv1103b_mux_recalced_data[] = {
	{
		.num = 1,
		.pin = 6,
		.reg = 0x10024,
		.bit = 8,
		.mask = 0xf
	}, {
		.num = 1,
		.pin = 7,
		.reg = 0x10024,
		.bit = 12,
		.mask = 0xf
	},
};

static struct rockchip_mux_recalced_data rv1108_mux_recalced_data[] = {
	{
		.num = 1,
@@ -1172,6 +1188,9 @@ static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)
	else
		regmap = info->regmap_base;

	if (ctrl->type == RV1103B && bank->bank_num == 2 && pin >= 12)
		return 0;

	if (ctrl->type == RK3506) {
		if (bank->bank_num == 1)
			regmap = info->regmap_ioc1;
@@ -1298,6 +1317,9 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
	else
		regmap = info->regmap_base;

	if (ctrl->type == RV1103B && bank->bank_num == 2 && pin >= 12)
		return 0;

	if (ctrl->type == RK3506) {
		if (bank->bank_num == 1)
			regmap = info->regmap_ioc1;
@@ -1495,6 +1517,214 @@ static int px30_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
	return 0;
}

#define RV1103B_DRV_BITS_PER_PIN		8
#define RV1103B_DRV_PINS_PER_REG		2
#define RV1103B_DRV_GPIO0_A_OFFSET		0x40100
#define RV1103B_DRV_GPIO0_B_OFFSET		0x50110
#define RV1103B_DRV_GPIO1_A01_OFFSET		0x140
#define RV1103B_DRV_GPIO1_A67_OFFSET		0x1014C
#define RV1103B_DRV_GPIO2_OFFSET		0x30180
#define RV1103B_DRV_GPIO2_SARADC_OFFSET		0x3080C

static int rv1103b_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
				       int pin_num, struct regmap **regmap,
				       int *reg, u8 *bit)
{
	struct rockchip_pinctrl *info = bank->drvdata;
	int ret = 0;

	*regmap = info->regmap_base;
	switch (bank->bank_num) {
	case 0:
		if (pin_num < 7)
			*reg = RV1103B_DRV_GPIO0_A_OFFSET;
		else if (pin_num > 7 && pin_num < 14)
			*reg = RV1103B_DRV_GPIO0_B_OFFSET - 0x10;
		else
			ret = -EINVAL;
		break;

	case 1:
		if (pin_num < 6)
			*reg = RV1103B_DRV_GPIO1_A01_OFFSET;
		else if (pin_num >= 6 && pin_num < 23)
			*reg = RV1103B_DRV_GPIO1_A67_OFFSET - 0xc;
		else if (pin_num >= 24 && pin_num < 30)
			*reg = RV1103B_DRV_GPIO1_A67_OFFSET - 0xc;
		else
			ret = -EINVAL;
		break;

	case 2:
		if (pin_num < 12) {
			*reg = RV1103B_DRV_GPIO2_OFFSET;
		} else if (pin_num >= 16) {
			ret = -EINVAL;
		} else {
			*reg = RV1103B_DRV_GPIO2_SARADC_OFFSET;
			*bit = 10;

			return 0;
		}
		break;

	default:
		ret = -EINVAL;
		break;
	}

	if (ret) {
		dev_err(info->dev, "unsupported bank_num %d pin_num %d\n", bank->bank_num, pin_num);

		return ret;
	}

	*reg += ((pin_num / RV1103B_DRV_PINS_PER_REG) * 4);
	*bit = pin_num % RV1103B_DRV_PINS_PER_REG;
	*bit *= RV1103B_DRV_BITS_PER_PIN;

	return 0;
}

#define RV1103B_PULL_BITS_PER_PIN		2
#define RV1103B_PULL_PINS_PER_REG		8
#define RV1103B_PULL_GPIO0_A_OFFSET		0x40200
#define RV1103B_PULL_GPIO0_B_OFFSET		0x50204
#define RV1103B_PULL_GPIO1_A01_OFFSET		0x210
#define RV1103B_PULL_GPIO1_A67_OFFSET		0x10210
#define RV1103B_PULL_GPIO2_OFFSET		0x30220
#define RV1103B_PULL_GPIO2_SARADC_OFFSET	0x3080C

static int rv1103b_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
					int pin_num, struct regmap **regmap,
					int *reg, u8 *bit)
{
	struct rockchip_pinctrl *info = bank->drvdata;
	int ret = 0;

	*regmap = info->regmap_base;
	switch (bank->bank_num) {
	case 0:
		if (pin_num < 7)
			*reg = RV1103B_PULL_GPIO0_A_OFFSET;
		else if (pin_num > 7 && pin_num < 14)
			*reg = RV1103B_PULL_GPIO0_B_OFFSET - 0x4;
		else
			ret = -EINVAL;
		break;

	case 1:
		if (pin_num < 6)
			*reg = RV1103B_PULL_GPIO1_A01_OFFSET;
		else if (pin_num >= 6 && pin_num < 23)
			*reg = RV1103B_PULL_GPIO1_A67_OFFSET;
		else if (pin_num >= 24 && pin_num < 30)
			*reg = RV1103B_PULL_GPIO1_A67_OFFSET;
		else
			ret = -EINVAL;
		break;

	case 2:
		if (pin_num < 12) {
			*reg = RV1103B_PULL_GPIO2_OFFSET;
		} else if (pin_num >= 16) {
			ret = -EINVAL;
		} else {
			*reg = RV1103B_PULL_GPIO2_SARADC_OFFSET;
			*bit = 13;

			return 0;
		}
		break;

	default:
		ret = -EINVAL;
		break;
	}

	if (ret) {
		dev_err(info->dev, "unsupported bank_num %d pin_num %d\n", bank->bank_num, pin_num);

		return ret;
	}

	*reg += ((pin_num / RV1103B_PULL_PINS_PER_REG) * 4);
	*bit = pin_num % RV1103B_PULL_PINS_PER_REG;
	*bit *= RV1103B_PULL_BITS_PER_PIN;

	return 0;
}

#define RV1103B_SMT_BITS_PER_PIN		1
#define RV1103B_SMT_PINS_PER_REG		8
#define RV1103B_SMT_GPIO0_A_OFFSET		0x40400
#define RV1103B_SMT_GPIO0_B_OFFSET		0x50404
#define RV1103B_SMT_GPIO1_A01_OFFSET		0x410
#define RV1103B_SMT_GPIO1_A67_OFFSET		0x10410
#define RV1103B_SMT_GPIO2_OFFSET		0x30420
#define RV1103B_SMT_GPIO2_SARADC_OFFSET		0x3080C

static int rv1103b_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
					   int pin_num,
					   struct regmap **regmap,
					   int *reg, u8 *bit)
{
	struct rockchip_pinctrl *info = bank->drvdata;
	int ret = 0;

	*regmap = info->regmap_base;
	switch (bank->bank_num) {
	case 0:
		if (pin_num < 7)
			*reg = RV1103B_SMT_GPIO0_A_OFFSET;
		else if (pin_num > 7 && pin_num < 14)
			*reg = RV1103B_SMT_GPIO0_B_OFFSET - 0x4;
		else
			ret = -EINVAL;
		break;

	case 1:
		if (pin_num < 6)
			*reg = RV1103B_SMT_GPIO1_A01_OFFSET;
		else if (pin_num >= 6 && pin_num < 23)
			*reg = RV1103B_SMT_GPIO1_A67_OFFSET;
		else if (pin_num >= 24 && pin_num < 30)
			*reg = RV1103B_SMT_GPIO1_A67_OFFSET;
		else
			ret = -EINVAL;
		break;

	case 2:
		if (pin_num < 12) {
			*reg = RV1103B_SMT_GPIO2_OFFSET;
		} else if (pin_num >= 16) {
			ret = -EINVAL;
		} else {
			*reg = RV1103B_SMT_GPIO2_SARADC_OFFSET;
			*bit = 8;

			return 0;
		}
		break;

	default:
		ret = -EINVAL;
		break;
	}

	if (ret) {
		dev_err(info->dev, "unsupported bank_num %d pin_num %d\n", bank->bank_num, pin_num);

		return ret;
	}

	*reg += ((pin_num / RV1103B_SMT_PINS_PER_REG) * 4);
	*bit = pin_num % RV1103B_SMT_PINS_PER_REG;
	*bit *= RV1103B_SMT_BITS_PER_PIN;

	return 0;
}

#define RV1108_PULL_PMU_OFFSET		0x10
#define RV1108_PULL_OFFSET		0x110
#define RV1108_PULL_PINS_PER_REG	8
@@ -2982,6 +3212,9 @@ static int rockchip_get_drive_perpin(struct rockchip_pin_bank *bank,
	u8 bit;
	int drv_type = bank->drv[pin_num / 8].drv_type;

	if (ctrl->type == RV1103B && pin_num >= 12)
		drv_type = DRV_TYPE_IO_LEVEL_2_BIT;

	ret = ctrl->drv_calc_reg(bank, pin_num, &regmap, &reg, &bit);
	if (ret)
		return ret;
@@ -3043,6 +3276,11 @@ static int rockchip_get_drive_perpin(struct rockchip_pin_bank *bank,
	if (ret)
		return ret;

	if (ctrl->type == RV1103B && bank->bank_num == 2 && pin_num >= 12) {
		data = data >> 10;
		return data & 0x3;
	}

	data >>= bit;
	data &= (1 << rmask_bits) - 1;

@@ -3071,7 +3309,8 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
		rmask_bits = RK3588_DRV_BITS_PER_PIN;
		ret = strength;
		goto config;
	} else if (ctrl->type == RK3506 ||
	} else if (ctrl->type == RV1103B ||
		   ctrl->type == RK3506 ||
		   ctrl->type == RK3528 ||
		   ctrl->type == RK3562 ||
		   ctrl->type == RK3568) {
@@ -3182,6 +3421,12 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
			ret = strength;
		}
	}

	if (ctrl->type == RV1103B && bank->bank_num == 2 && pin_num >= 12) {
		rmask_bits = 2;
		ret = strength;
	}

	/* enable the write to the equivalent lower bits */
	data = ((1 << rmask_bits) - 1) << (bit + 16);
	rmask = data | (data >> 16);
@@ -3236,6 +3481,7 @@ static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num)
				? PIN_CONFIG_BIAS_PULL_PIN_DEFAULT
				: PIN_CONFIG_BIAS_DISABLE;
	case PX30:
	case RV1103B:
	case RV1108:
	case RK3188:
	case RK3288:
@@ -3251,6 +3497,9 @@ static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num)
		pull_type = bank->pull_type[pin_num / 8];
		data >>= bit;
		data &= (1 << RK3188_PULL_BITS_PER_PIN) - 1;

		if (ctrl->type == RV1103B && bank->bank_num == 2 && pin_num >= 12)
			pull_type = 1;
		/*
		 * In the TRM, pull-up being 1 for everything except the GPIO0_D3-D6,
		 * where that pull up value becomes 3.
@@ -3297,6 +3546,7 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
		ret = regmap_write(regmap, reg, data);
		break;
	case PX30:
	case RV1103B:
	case RV1108:
	case RV1126:
	case RK3188:
@@ -3312,6 +3562,8 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
	case RK3576:
	case RK3588:
		pull_type = bank->pull_type[pin_num / 8];
		if (ctrl->type == RV1103B && bank->bank_num == 2 && pin_num >= 12)
			pull_type = 1;
		ret = -EINVAL;
		for (i = 0; i < ARRAY_SIZE(rockchip_pull_list[pull_type]);
			i++) {
@@ -3417,6 +3669,11 @@ static int rockchip_get_schmitt(struct rockchip_pin_bank *bank, int pin_num)
	if (ret)
		return ret;

	if (ctrl->type == RV1103B && bank->bank_num == 2 && pin_num >= 12) {
		data >>= 8;
		return data & 0x3;
	}

	data >>= bit;
	switch (ctrl->type) {
	case RK3562:
@@ -3473,6 +3730,12 @@ static int rockchip_set_schmitt(struct rockchip_pin_bank *bank,
		}
	}

	if (ctrl->type == RV1103B && bank->bank_num == 2 && pin_num >= 12) {
		data = 0x3 << (bit + 16);
		rmask = data | (data >> 16);
		data |= ((enable ? 0x3 : 0) << bit);
	}

	return regmap_update_bits(regmap, reg, rmask, data);
}

@@ -3579,6 +3842,7 @@ static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl,
	case RK3066B:
		return pull ? false : true;
	case PX30:
	case RV1103B:
	case RV1108:
	case RV1126:
	case RK3188:
@@ -4318,6 +4582,51 @@ static struct rockchip_pin_ctrl px30_pin_ctrl = {
		.schmitt_calc_reg	= px30_calc_schmitt_reg_and_bit,
};

static struct rockchip_pin_bank rv1103b_pin_banks[] = {
	PIN_BANK_IOMUX_FLAGS_OFFSET_DRV_FLAGS(0, 32, "gpio0",
				    IOMUX_WIDTH_4BIT,
				    IOMUX_WIDTH_4BIT,
				    IOMUX_WIDTH_4BIT,
				    IOMUX_WIDTH_4BIT,
				    0x40000, 0x50008, 0x50010, 0x50018,
				    DRV_TYPE_IO_LEVEL_8_BIT,
				    DRV_TYPE_IO_LEVEL_8_BIT,
				    DRV_TYPE_IO_LEVEL_8_BIT,
				    DRV_TYPE_IO_LEVEL_8_BIT),
	PIN_BANK_IOMUX_FLAGS_OFFSET_DRV_FLAGS(1, 32, "gpio1",
				    IOMUX_WIDTH_4BIT,
				    IOMUX_WIDTH_4BIT,
				    IOMUX_WIDTH_4BIT,
				    IOMUX_WIDTH_4BIT,
				    0x20, 0x10028, 0x10030, 0x10038,
				    DRV_TYPE_IO_LEVEL_8_BIT,
				    DRV_TYPE_IO_LEVEL_8_BIT,
				    DRV_TYPE_IO_LEVEL_8_BIT,
				    DRV_TYPE_IO_LEVEL_8_BIT),
	PIN_BANK_IOMUX_FLAGS_OFFSET_DRV_FLAGS(2, 32, "gpio2",
				    IOMUX_WIDTH_4BIT,
				    IOMUX_WIDTH_4BIT,
				    IOMUX_WIDTH_4BIT,
				    IOMUX_WIDTH_4BIT,
				    0x30040, 0x30048, 0x30050, 0x30058,
				    DRV_TYPE_IO_LEVEL_8_BIT,
				    DRV_TYPE_IO_LEVEL_8_BIT,
				    DRV_TYPE_IO_LEVEL_8_BIT,
				    DRV_TYPE_IO_LEVEL_8_BIT),
};

static struct rockchip_pin_ctrl rv1103b_pin_ctrl __maybe_unused = {
	.pin_banks		= rv1103b_pin_banks,
	.nr_banks		= ARRAY_SIZE(rv1103b_pin_banks),
	.label			= "RV1103B-GPIO",
	.type			= RV1103B,
	.iomux_recalced		= rv1103b_mux_recalced_data,
	.niomux_recalced	= ARRAY_SIZE(rv1103b_mux_recalced_data),
	.pull_calc_reg		= rv1103b_calc_pull_reg_and_bit,
	.drv_calc_reg		= rv1103b_calc_drv_reg_and_bit,
	.schmitt_calc_reg	= rv1103b_calc_schmitt_reg_and_bit,
};

static struct rockchip_pin_bank rv1108_pin_banks[] = {
	PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU,
					     IOMUX_SOURCE_PMU,
@@ -4954,6 +5263,8 @@ static struct rockchip_pin_ctrl rk3588_pin_ctrl = {
static const struct of_device_id rockchip_pinctrl_dt_match[] = {
	{ .compatible = "rockchip,px30-pinctrl",
		.data = &px30_pin_ctrl },
	{ .compatible = "rockchip,rv1103b-pinctrl",
		.data = &rv1103b_pin_ctrl },
	{ .compatible = "rockchip,rv1108-pinctrl",
		.data = &rv1108_pin_ctrl },
	{ .compatible = "rockchip,rv1126-pinctrl",
+1 −0
Original line number Diff line number Diff line
@@ -185,6 +185,7 @@

enum rockchip_pinctrl_type {
	PX30,
	RV1103B,
	RV1108,
	RV1126,
	RK2928,