static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { struct rk_i2s_dev *i2s = to_info(dai); unsigned int val = 0; switch (params_format(params)) { case SNDRV_PCM_FORMAT_S8: val |= I2S_TXCR_VDW(8); break; case SNDRV_PCM_FORMAT_S16_LE: val |= I2S_TXCR_VDW(16); break; case SNDRV_PCM_FORMAT_S20_3LE: val |= I2S_TXCR_VDW(20); break; case SNDRV_PCM_FORMAT_S24_LE: val |= I2S_TXCR_VDW(24); break; default: return -EINVAL; } regmap_update_bits(i2s->regmap, I2S_TXCR, I2S_TXCR_VDW_MASK, val); regmap_update_bits(i2s->regmap, I2S_RXCR, I2S_RXCR_VDW_MASK, val); regmap_update_bits(i2s->regmap, I2S_DMACR, I2S_DMACR_TDL_MASK, I2S_DMACR_TDL(16)); regmap_update_bits(i2s->regmap, I2S_DMACR, I2S_DMACR_RDL_MASK, I2S_DMACR_RDL(16)); return 0; }
static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { struct rk_i2s_dev *i2s = to_info(dai); unsigned int val = 0; switch (params_format(params)) { case SNDRV_PCM_FORMAT_S8: val |= I2S_TXCR_VDW(8); break; case SNDRV_PCM_FORMAT_S16_LE: val |= I2S_TXCR_VDW(16); break; case SNDRV_PCM_FORMAT_S20_3LE: val |= I2S_TXCR_VDW(20); break; case SNDRV_PCM_FORMAT_S24_LE: val |= I2S_TXCR_VDW(24); break; default: return -EINVAL; } regmap_update_bits(i2s->regmap, I2S_TXCR, I2S_TXCR_VDW_MASK, val); regmap_update_bits(i2s->regmap, I2S_RXCR, I2S_RXCR_VDW_MASK, val); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { dai->playback_dma_data = &i2s->playback_dma_data; regmap_update_bits(i2s->regmap, I2S_DMACR, I2S_DMACR_TDL_MASK, I2S_DMACR_TDL(1) | I2S_DMACR_TDE_ENABLE); } else { dai->capture_dma_data = &i2s->capture_dma_data; regmap_update_bits(i2s->regmap, I2S_DMACR, I2S_DMACR_RDL_MASK, I2S_DMACR_RDL(1) | I2S_DMACR_RDE_ENABLE); } return 0; }
static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { struct rk_i2s_dev *i2s = to_info(dai); struct snd_soc_pcm_runtime *rtd = substream->private_data; unsigned int val = 0; unsigned int mclk_rate, bclk_rate, div_bclk, div_lrck; if (i2s->is_master_mode) { mclk_rate = clk_get_rate(i2s->mclk); bclk_rate = 2 * 32 * params_rate(params); if (bclk_rate && mclk_rate % bclk_rate) return -EINVAL; div_bclk = mclk_rate / bclk_rate; div_lrck = bclk_rate / params_rate(params); regmap_update_bits(i2s->regmap, I2S_CKR, I2S_CKR_MDIV_MASK, I2S_CKR_MDIV(div_bclk)); regmap_update_bits(i2s->regmap, I2S_CKR, I2S_CKR_TSD_MASK | I2S_CKR_RSD_MASK, I2S_CKR_TSD(div_lrck) | I2S_CKR_RSD(div_lrck)); } switch (params_format(params)) { case SNDRV_PCM_FORMAT_S8: val |= I2S_TXCR_VDW(8); break; case SNDRV_PCM_FORMAT_S16_LE: val |= I2S_TXCR_VDW(16); break; case SNDRV_PCM_FORMAT_S20_3LE: val |= I2S_TXCR_VDW(20); break; case SNDRV_PCM_FORMAT_S24_LE: val |= I2S_TXCR_VDW(24); break; case SNDRV_PCM_FORMAT_S32_LE: val |= I2S_TXCR_VDW(32); break; default: return -EINVAL; } switch (params_channels(params)) { case 8: val |= I2S_CHN_8; break; case 6: val |= I2S_CHN_6; break; case 4: val |= I2S_CHN_4; break; case 2: val |= I2S_CHN_2; break; default: dev_err(i2s->dev, "invalid channel: %d\n", params_channels(params)); return -EINVAL; } if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) regmap_update_bits(i2s->regmap, I2S_RXCR, I2S_RXCR_VDW_MASK | I2S_RXCR_CSR_MASK, val); else regmap_update_bits(i2s->regmap, I2S_TXCR, I2S_TXCR_VDW_MASK | I2S_TXCR_CSR_MASK, val); regmap_update_bits(i2s->regmap, I2S_DMACR, I2S_DMACR_TDL_MASK, I2S_DMACR_TDL(16)); regmap_update_bits(i2s->regmap, I2S_DMACR, I2S_DMACR_RDL_MASK, I2S_DMACR_RDL(16)); val = I2S_CKR_TRCM_TXRX; if (dai->driver->symmetric_rates || rtd->dai_link->symmetric_rates) val = I2S_CKR_TRCM_TXSHARE; regmap_update_bits(i2s->regmap, I2S_CKR, I2S_CKR_TRCM_MASK, val); return 0; }