reset: imx8mp-audiomix: Introduce active_low configuration option

For EARC and EARC PHY the reset happens when clearing the reset bits.
Refactor assert/deassert function in order to take into account the
active_low configuration option.

Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
Reviewed-by: Peng Fan <peng.fan@nxp.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com>
Link: https://lore.kernel.org/r/20250311085812.1296243-7-daniel.baluta@nxp.com
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
This commit is contained in:
Daniel Baluta 2025-03-11 10:58:09 +02:00 committed by Mathieu Poirier
parent a83bc87cd3
commit 9fba66374d

View File

@ -20,16 +20,19 @@
struct imx8mp_reset_map {
unsigned int offset;
unsigned int mask;
bool active_low;
};
static const struct imx8mp_reset_map reset_map[] = {
[IMX8MP_AUDIOMIX_EARC_RESET] = {
.offset = IMX8MP_AUDIOMIX_EARC_RESET_OFFSET,
.mask = IMX8MP_AUDIOMIX_EARC_RESET_MASK,
.active_low = true,
},
[IMX8MP_AUDIOMIX_EARC_PHY_RESET] = {
.offset = IMX8MP_AUDIOMIX_EARC_RESET_OFFSET,
.mask = IMX8MP_AUDIOMIX_EARC_PHY_RESET_MASK,
.active_low = true,
},
};
@ -44,42 +47,42 @@ static struct imx8mp_audiomix_reset *to_imx8mp_audiomix_reset(struct reset_contr
return container_of(rcdev, struct imx8mp_audiomix_reset, rcdev);
}
static int imx8mp_audiomix_reset_assert(struct reset_controller_dev *rcdev,
unsigned long id)
static int imx8mp_audiomix_update(struct reset_controller_dev *rcdev,
unsigned long id, bool assert)
{
struct imx8mp_audiomix_reset *priv = to_imx8mp_audiomix_reset(rcdev);
void __iomem *reg_addr = priv->base;
unsigned int mask, offset, reg;
unsigned long flags;
unsigned int mask, offset, active_low;
unsigned long reg, flags;
mask = reset_map[id].mask;
offset = reset_map[id].offset;
active_low = reset_map[id].active_low;
spin_lock_irqsave(&priv->lock, flags);
reg = readl(reg_addr + offset);
writel(reg & ~mask, reg_addr + offset);
if (active_low ^ assert)
reg |= mask;
else
reg &= ~mask;
writel(reg, reg_addr + offset);
spin_unlock_irqrestore(&priv->lock, flags);
return 0;
}
static int imx8mp_audiomix_reset_assert(struct reset_controller_dev *rcdev,
unsigned long id)
{
return imx8mp_audiomix_update(rcdev, id, true);
}
static int imx8mp_audiomix_reset_deassert(struct reset_controller_dev *rcdev,
unsigned long id)
{
struct imx8mp_audiomix_reset *priv = to_imx8mp_audiomix_reset(rcdev);
void __iomem *reg_addr = priv->base;
unsigned int mask, offset, reg;
unsigned long flags;
mask = reset_map[id].mask;
offset = reset_map[id].offset;
spin_lock_irqsave(&priv->lock, flags);
reg = readl(reg_addr + offset);
writel(reg | mask, reg_addr + offset);
spin_unlock_irqrestore(&priv->lock, flags);
return 0;
return imx8mp_audiomix_update(rcdev, id, false);
}
static const struct reset_control_ops imx8mp_audiomix_reset_ops = {