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

Commit ea262ad6 authored by david.wu's avatar david.wu Committed by Linus Walleij
Browse files

pinctrl: rockchip: Add mux recalculation support



Some pins are special at a bank so that add
IOMUX_RECALCED type to indicate which iomux source
of the bank need to be recalculated. If the mux
recalculateed callback and IOMUX_RECALCED type
were set, recalculate the pins' iomux by using
mux recalculated data struct.

Signed-off-by: default avatarDavid Wu <david.wu@rock-chips.com>
Reviewed-by: default avatarHeiko Stuebner <heiko@sntech.de>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent 8b6c6f93
Loading
Loading
Loading
Loading
+35 −6
Original line number Diff line number Diff line
@@ -76,6 +76,7 @@ enum rockchip_pinctrl_type {
#define IOMUX_SOURCE_PMU	BIT(2)
#define IOMUX_UNROUTED		BIT(3)
#define IOMUX_WIDTH_3BIT	BIT(4)
#define IOMUX_RECALCED		BIT(5)

/**
 * @type: iomux variant using IOMUX_* constants
@@ -305,6 +306,8 @@ struct rockchip_pin_ctrl {
	void	(*drv_calc_reg)(struct rockchip_pin_bank *bank,
				    int pin_num, struct regmap **regmap,
				    int *reg, u8 *bit);
	void	(*iomux_recalc)(u8 bank_num, int pin, int *reg,
				u8 *bit, int *mask);
};

struct rockchip_pin_config {
@@ -356,6 +359,22 @@ struct rockchip_pinctrl {
	unsigned int			nfunctions;
};

/**
 * struct rockchip_mux_recalced_data: represent a pin iomux data.
 * @num: bank number.
 * @pin: pin number.
 * @bit: index at register.
 * @reg: register offset.
 * @mask: mask bit
 */
struct rockchip_mux_recalced_data {
	u8 num;
	u8 pin;
	u8 reg;
	u8 bit;
	u8 mask;
};

static struct regmap_config rockchip_regmap_config = {
	.reg_bits = 32,
	.val_bits = 32,
@@ -518,10 +537,11 @@ static const struct pinctrl_ops rockchip_pctrl_ops = {
static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)
{
	struct rockchip_pinctrl *info = bank->drvdata;
	struct rockchip_pin_ctrl *ctrl = info->ctrl;
	int iomux_num = (pin / 8);
	struct regmap *regmap;
	unsigned int val;
	int reg, ret, mask;
	int reg, ret, mask, mux_type;
	u8 bit;

	if (iomux_num > 3)
@@ -539,13 +559,14 @@ static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)
				? info->regmap_pmu : info->regmap_base;

	/* get basic quadrupel of mux registers and the correct reg inside */
	mux_type = bank->iomux[iomux_num].type;
	reg = bank->iomux[iomux_num].offset;
	if (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) {
	if (mux_type & IOMUX_WIDTH_4BIT) {
		if ((pin % 8) >= 4)
			reg += 0x4;
		bit = (pin % 4) * 4;
		mask = 0xf;
	} else if (bank->iomux[iomux_num].type & IOMUX_WIDTH_3BIT) {
	} else if (mux_type & IOMUX_WIDTH_3BIT) {
		if ((pin % 8) >= 5)
			reg += 0x4;
		bit = (pin % 8 % 5) * 3;
@@ -555,6 +576,9 @@ static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)
		mask = 0x3;
	}

	if (ctrl->iomux_recalc && (mux_type & IOMUX_RECALCED))
		ctrl->iomux_recalc(bank->bank_num, pin, &reg, &bit, &mask);

	ret = regmap_read(regmap, reg, &val);
	if (ret)
		return ret;
@@ -578,9 +602,10 @@ static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)
static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
{
	struct rockchip_pinctrl *info = bank->drvdata;
	struct rockchip_pin_ctrl *ctrl = info->ctrl;
	int iomux_num = (pin / 8);
	struct regmap *regmap;
	int reg, ret, mask;
	int reg, ret, mask, mux_type;
	unsigned long flags;
	u8 bit;
	u32 data, rmask;
@@ -610,13 +635,14 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
				? info->regmap_pmu : info->regmap_base;

	/* get basic quadrupel of mux registers and the correct reg inside */
	mux_type = bank->iomux[iomux_num].type;
	reg = bank->iomux[iomux_num].offset;
	if (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) {
	if (mux_type & IOMUX_WIDTH_4BIT) {
		if ((pin % 8) >= 4)
			reg += 0x4;
		bit = (pin % 4) * 4;
		mask = 0xf;
	} else if (bank->iomux[iomux_num].type & IOMUX_WIDTH_3BIT) {
	} else if (mux_type & IOMUX_WIDTH_3BIT) {
		if ((pin % 8) >= 5)
			reg += 0x4;
		bit = (pin % 8 % 5) * 3;
@@ -626,6 +652,9 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
		mask = 0x3;
	}

	if (ctrl->iomux_recalc && (mux_type & IOMUX_RECALCED))
		ctrl->iomux_recalc(bank->bank_num, pin, &reg, &bit, &mask);

	spin_lock_irqsave(&bank->slock, flags);

	data = (mask << (bit + 16));