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

Commit 03716e1d authored by Heiko Stübner's avatar Heiko Stübner Committed by Linus Walleij
Browse files

pinctrl: rockchip: add support for 4bit wide iomux settings



In the upcoming rk3288 SoC some iomux settings are 4bit wide instead of
the regular 2bit. Therefore add a flag to mark iomuxes as such and adapt
the mux-access as well as the offset calculation accordingly.

Signed-off-by: default avatarHeiko Stuebner <heiko@sntech.de>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent 6bc0d121
Loading
Loading
Loading
Loading
+26 −8
Original line number Diff line number Diff line
@@ -68,6 +68,7 @@ enum rockchip_pinctrl_type {
 * Encode variants of iomux registers into a type variable
 */
#define IOMUX_GPIO_ONLY		BIT(0)
#define IOMUX_WIDTH_4BIT	BIT(1)

/**
 * @type: iomux variant using IOMUX_* constants
@@ -376,7 +377,7 @@ static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)
	struct rockchip_pinctrl *info = bank->drvdata;
	int iomux_num = (pin / 8);
	unsigned int val;
	int reg, ret;
	int reg, ret, mask;
	u8 bit;

	if (iomux_num > 3)
@@ -386,14 +387,21 @@ static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)
		return RK_FUNC_GPIO;

	/* get basic quadrupel of mux registers and the correct reg inside */
	mask = (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) ? 0xf : 0x3;
	reg = bank->iomux[iomux_num].offset;
	if (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) {
		if ((pin % 8) >= 4)
			reg += 0x4;
		bit = (pin % 4) * 4;
	} else {
		bit = (pin % 8) * 2;
	}

	ret = regmap_read(info->regmap_base, reg, &val);
	if (ret)
		return ret;

	return ((val >> bit) & 3);
	return ((val >> bit) & mask);
}

/*
@@ -413,7 +421,7 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
{
	struct rockchip_pinctrl *info = bank->drvdata;
	int iomux_num = (pin / 8);
	int reg, ret;
	int reg, ret, mask;
	unsigned long flags;
	u8 bit;
	u32 data;
@@ -435,13 +443,20 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
						bank->bank_num, pin, mux);

	/* get basic quadrupel of mux registers and the correct reg inside */
	mask = (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) ? 0xf : 0x3;
	reg = bank->iomux[iomux_num].offset;
	if (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) {
		if ((pin % 8) >= 4)
			reg += 0x4;
		bit = (pin % 4) * 4;
	} else {
		bit = (pin % 8) * 2;
	}

	spin_lock_irqsave(&bank->slock, flags);

	data = (3 << (bit + 16));
	data |= (mux & 3) << bit;
	data = (mask << (bit + 16));
	data |= (mux & mask) << bit;
	ret = regmap_write(info->regmap_base, reg, data);

	spin_unlock_irqrestore(&bank->slock, flags);
@@ -1556,6 +1571,7 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(
		/* calculate iomux offsets */
		for (j = 0; j < 4; j++) {
			struct rockchip_iomux *iom = &bank->iomux[j];
			int inc;

			if (bank_pins >= bank->nr_pins)
				break;
@@ -1572,8 +1588,10 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(

			/*
			 * Increase offset according to iomux width.
			 * 4bit iomux'es are spread over two registers.
			 */
			grf_offs += 4;
			inc = (iom->type & IOMUX_WIDTH_4BIT) ? 8 : 4;
			grf_offs += inc;

			bank_pins += 8;
		}