|
|
|
@ -494,6 +494,7 @@ static int mxs_saif_trigger(struct snd_pcm_substream *substream, int cmd, |
|
|
|
|
struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai); |
|
|
|
|
struct mxs_saif *master_saif; |
|
|
|
|
u32 delay; |
|
|
|
|
int ret; |
|
|
|
|
|
|
|
|
|
master_saif = mxs_saif_get_master(saif); |
|
|
|
|
if (!master_saif) |
|
|
|
@ -503,23 +504,37 @@ static int mxs_saif_trigger(struct snd_pcm_substream *substream, int cmd, |
|
|
|
|
case SNDRV_PCM_TRIGGER_START: |
|
|
|
|
case SNDRV_PCM_TRIGGER_RESUME: |
|
|
|
|
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
|
|
|
|
if (saif->state == MXS_SAIF_STATE_RUNNING) |
|
|
|
|
return 0; |
|
|
|
|
|
|
|
|
|
dev_dbg(cpu_dai->dev, "start\n"); |
|
|
|
|
|
|
|
|
|
clk_enable(master_saif->clk); |
|
|
|
|
if (!master_saif->mclk_in_use) |
|
|
|
|
__raw_writel(BM_SAIF_CTRL_RUN, |
|
|
|
|
master_saif->base + SAIF_CTRL + MXS_SET_ADDR); |
|
|
|
|
ret = clk_enable(master_saif->clk); |
|
|
|
|
if (ret) { |
|
|
|
|
dev_err(saif->dev, "Failed to enable master clock\n"); |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* If the saif's master is not himself, we also need to enable |
|
|
|
|
* itself clk for its internal basic logic to work. |
|
|
|
|
*/ |
|
|
|
|
if (saif != master_saif) { |
|
|
|
|
clk_enable(saif->clk); |
|
|
|
|
ret = clk_enable(saif->clk); |
|
|
|
|
if (ret) { |
|
|
|
|
dev_err(saif->dev, "Failed to enable master clock\n"); |
|
|
|
|
clk_disable(master_saif->clk); |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
__raw_writel(BM_SAIF_CTRL_RUN, |
|
|
|
|
saif->base + SAIF_CTRL + MXS_SET_ADDR); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!master_saif->mclk_in_use) |
|
|
|
|
__raw_writel(BM_SAIF_CTRL_RUN, |
|
|
|
|
master_saif->base + SAIF_CTRL + MXS_SET_ADDR); |
|
|
|
|
|
|
|
|
|
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
|
|
|
|
/*
|
|
|
|
|
* write data to saif data register to trigger |
|
|
|
@ -543,6 +558,7 @@ static int mxs_saif_trigger(struct snd_pcm_substream *substream, int cmd, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
master_saif->ongoing = 1; |
|
|
|
|
saif->state = MXS_SAIF_STATE_RUNNING; |
|
|
|
|
|
|
|
|
|
dev_dbg(saif->dev, "CTRL 0x%x STAT 0x%x\n", |
|
|
|
|
__raw_readl(saif->base + SAIF_CTRL), |
|
|
|
@ -555,6 +571,9 @@ static int mxs_saif_trigger(struct snd_pcm_substream *substream, int cmd, |
|
|
|
|
case SNDRV_PCM_TRIGGER_SUSPEND: |
|
|
|
|
case SNDRV_PCM_TRIGGER_STOP: |
|
|
|
|
case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
|
|
|
|
if (saif->state == MXS_SAIF_STATE_STOPPED) |
|
|
|
|
return 0; |
|
|
|
|
|
|
|
|
|
dev_dbg(cpu_dai->dev, "stop\n"); |
|
|
|
|
|
|
|
|
|
/* wait a while for the current sample to complete */ |
|
|
|
@ -575,6 +594,7 @@ static int mxs_saif_trigger(struct snd_pcm_substream *substream, int cmd, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
master_saif->ongoing = 0; |
|
|
|
|
saif->state = MXS_SAIF_STATE_STOPPED; |
|
|
|
|
|
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|