On 06/06/23 21:08, Pierre-Louis Bossart wrote: >> +static int acp63_sdw_dma_start(struct snd_pcm_substream *substream, void __iomem *acp_base) >> +{ >> + struct acp_sdw_dma_stream *stream; >> + u32 stream_id; >> + u32 sdw_dma_en_reg; >> + u32 sdw_dma_en_stat_reg; >> + u32 sdw_dma_stat; >> + >> + stream = substream->runtime->private_data; >> + stream_id = stream->stream_id; >> + switch (stream->instance) { >> + case ACP_SDW0: >> + sdw_dma_en_reg = sdw0_dma_enable_reg[stream_id]; >> + break; >> + case ACP_SDW1: >> + sdw_dma_en_reg = sdw1_dma_enable_reg[stream_id]; >> + break; >> + default: >> + return -EINVAL; >> + } >> + writel(0x01, acp_base + sdw_dma_en_reg); >> + sdw_dma_en_stat_reg = sdw_dma_en_reg + 4; >> + return readl_poll_timeout(acp_base + sdw_dma_en_stat_reg, sdw_dma_stat, >> + (sdw_dma_stat & BIT(0)), ACP_DELAY_US, ACP_COUNTER); >> +} >> + >> +static int acp63_sdw_dma_stop(struct snd_pcm_substream *substream, void __iomem *acp_base) >> +{ >> + struct acp_sdw_dma_stream *stream; >> + u32 stream_id; >> + u32 sdw_dma_en_reg; >> + u32 sdw_dma_en_stat_reg; >> + u32 sdw_dma_stat; >> + >> + stream = substream->runtime->private_data; >> + stream_id = stream->stream_id; >> + switch (stream->instance) { >> + case ACP_SDW0: >> + sdw_dma_en_reg = sdw0_dma_enable_reg[stream_id]; >> + break; >> + case ACP_SDW1: >> + sdw_dma_en_reg = sdw1_dma_enable_reg[stream_id]; >> + break; >> + default: >> + return -EINVAL; >> + } >> + >> + writel(0, acp_base + sdw_dma_en_reg); >> + sdw_dma_en_stat_reg = sdw_dma_en_reg + 4; >> + return readl_poll_timeout(acp_base + sdw_dma_en_stat_reg, sdw_dma_stat, !sdw_dma_stat, >> + ACP_DELAY_US, ACP_COUNTER); >> +} > these start/stop routines look mostly the same, except for the value to > be written in the register. Maybe they can be factored with a common > helper, e.g. acp63_sdw_dma_enable(true/false). Yes, it can be refactored. Will fix it. >> + >> +static int acp63_sdw_dma_trigger(struct snd_soc_component *comp, >> + struct snd_pcm_substream *substream, >> + int cmd) >> +{ >> + struct sdw_dma_dev_data *sdw_data; >> + int ret; >> + >> + sdw_data = dev_get_drvdata(comp->dev); >> + switch (cmd) { >> + case SNDRV_PCM_TRIGGER_START: >> + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: >> + case SNDRV_PCM_TRIGGER_RESUME: >> + ret = acp63_sdw_dma_start(substream, sdw_data->acp_base); >> + break; >> + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: >> + case SNDRV_PCM_TRIGGER_SUSPEND: >> + case SNDRV_PCM_TRIGGER_STOP: >> + ret = acp63_sdw_dma_stop(substream, sdw_data->acp_base); >> + break; >> + default: >> + ret = -EINVAL; >> + } >> + if (ret) >> + dev_err(comp->dev, "trigger %d failed: %d", cmd, ret); >> + return ret; >> +}