From 5ca032ee21cdabd08fb368ce3f02fa8906b0ef5f Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 14 Sep 2012 16:16:08 +0100 Subject: ASoC: Ux500: Move MSP pinctrl setup into the MSP driver In the initial submission of the MSP driver msp1 and msp3's associated pinctrl mechanism was passed back to platform code using a plat_init() call-back routine, but it has no place in platform code. The MSP driver should set this up for the appropriate ports. Instead we use a use_pinctrl identifier which is passed from platform_data/Device Tree which indicates which ports should use pinctrl. Acked-by: Ola Lilja Acked-by: Linus Walleij Signed-off-by: Lee Jones --- sound/soc/ux500/ux500_msp_i2s.c | 67 +++++++++++++++++++++++++++++++---------- 1 file changed, 51 insertions(+), 16 deletions(-) (limited to 'sound/soc/ux500/ux500_msp_i2s.c') diff --git a/sound/soc/ux500/ux500_msp_i2s.c b/sound/soc/ux500/ux500_msp_i2s.c index eb85113d472a..12d7f567420d 100644 --- a/sound/soc/ux500/ux500_msp_i2s.c +++ b/sound/soc/ux500/ux500_msp_i2s.c @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -25,6 +26,9 @@ #include "ux500_msp_i2s.h" +/* MSP1/3 Tx/Rx usage protection */ +static DEFINE_SPINLOCK(msp_rxtx_lock); + /* Protocol desciptors */ static const struct msp_protdesc prot_descs[] = { { /* I2S */ @@ -352,17 +356,23 @@ static int configure_multichannel(struct ux500_msp *msp, static int enable_msp(struct ux500_msp *msp, struct ux500_msp_config *config) { - int status = 0; + int status = 0, retval = 0; u32 reg_val_DMACR, reg_val_GCR; + unsigned long flags; /* Check msp state whether in RUN or CONFIGURED Mode */ - if ((msp->msp_state == MSP_STATE_IDLE) && (msp->plat_init)) { - status = msp->plat_init(); - if (status) { - dev_err(msp->dev, "%s: ERROR: Failed to init MSP (%d)!\n", - __func__, status); - return status; + if (msp->msp_state == MSP_STATE_IDLE) { + spin_lock_irqsave(&msp_rxtx_lock, flags); + if (msp->pinctrl_rxtx_ref == 0 && + !(IS_ERR(msp->pinctrl_p) || IS_ERR(msp->pinctrl_def))) { + retval = pinctrl_select_state(msp->pinctrl_p, + msp->pinctrl_def); + if (retval) + pr_err("could not set MSP defstate\n"); } + if (!retval) + msp->pinctrl_rxtx_ref++; + spin_unlock_irqrestore(&msp_rxtx_lock, flags); } /* Configure msp with protocol dependent settings */ @@ -620,7 +630,8 @@ int ux500_msp_i2s_trigger(struct ux500_msp *msp, int cmd, int direction) int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir) { - int status = 0; + int status = 0, retval = 0; + unsigned long flags; dev_dbg(msp->dev, "%s: Enter (dir = 0x%01x).\n", __func__, dir); @@ -631,12 +642,19 @@ int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir) writel((readl(msp->registers + MSP_GCR) & (~(FRAME_GEN_ENABLE | SRG_ENABLE))), msp->registers + MSP_GCR); - if (msp->plat_exit) - status = msp->plat_exit(); - if (status) - dev_warn(msp->dev, - "%s: WARN: ux500_msp_i2s_exit failed (%d)!\n", - __func__, status); + + spin_lock_irqsave(&msp_rxtx_lock, flags); + WARN_ON(!msp->pinctrl_rxtx_ref); + msp->pinctrl_rxtx_ref--; + if (msp->pinctrl_rxtx_ref == 0 && + !(IS_ERR(msp->pinctrl_p) || IS_ERR(msp->pinctrl_sleep))) { + retval = pinctrl_select_state(msp->pinctrl_p, + msp->pinctrl_sleep); + if (retval) + pr_err("could not set MSP sleepstate\n"); + } + spin_unlock_irqrestore(&msp_rxtx_lock, flags); + writel(0, msp->registers + MSP_GCR); writel(0, msp->registers + MSP_TCF); writel(0, msp->registers + MSP_RCF); @@ -675,8 +693,6 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev, msp->id = platform_data->id; msp->dev = &pdev->dev; - msp->plat_init = platform_data->msp_i2s_init; - msp->plat_exit = platform_data->msp_i2s_exit; msp->dma_cfg_rx = platform_data->msp_i2s_dma_rx; msp->dma_cfg_tx = platform_data->msp_i2s_dma_tx; @@ -713,6 +729,25 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev, dev_dbg(&pdev->dev, "I2S device-name: '%s'\n", i2s_cont->name); msp->i2s_cont = i2s_cont; + msp->pinctrl_p = pinctrl_get(msp->dev); + if (IS_ERR(msp->pinctrl_p)) + dev_err(&pdev->dev, "could not get MSP pinctrl\n"); + else { + msp->pinctrl_def = pinctrl_lookup_state(msp->pinctrl_p, + PINCTRL_STATE_DEFAULT); + if (IS_ERR(msp->pinctrl_def)) { + dev_err(&pdev->dev, + "could not get MSP defstate (%li)\n", + PTR_ERR(msp->pinctrl_def)); + } + msp->pinctrl_sleep = pinctrl_lookup_state(msp->pinctrl_p, + PINCTRL_STATE_SLEEP); + if (IS_ERR(msp->pinctrl_sleep)) + dev_err(&pdev->dev, + "could not get MSP idlestate (%li)\n", + PTR_ERR(msp->pinctrl_def)); + } + return 0; } -- cgit