mirror of
https://github.com/torvalds/linux.git
synced 2026-06-01 19:13:47 +02:00
ASoC: renesas: rz-ssi: Add support for 24 bits sample width
Add support for 24 bits sample format width for RZ/G2L SoCs. Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com> Link: https://patch.msgid.link/20251114075856.4751-5-biju.das.jz@bp.renesas.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
b541cb0a27
commit
9e10709f83
|
|
@ -38,6 +38,7 @@
|
|||
#define SSICR_MST BIT(14)
|
||||
#define SSICR_BCKP BIT(13)
|
||||
#define SSICR_LRCKP BIT(12)
|
||||
#define SSICR_PDTA BIT(9)
|
||||
#define SSICR_CKDV(x) (((x) & 0xf) << 4)
|
||||
#define SSICR_TEN BIT(1)
|
||||
#define SSICR_REN BIT(0)
|
||||
|
|
@ -74,7 +75,7 @@
|
|||
#define PREALLOC_BUFFER_MAX (SZ_32K)
|
||||
|
||||
#define SSI_RATES SNDRV_PCM_RATE_8000_48000 /* 8k-48kHz */
|
||||
#define SSI_FMTS SNDRV_PCM_FMTBIT_S16_LE
|
||||
#define SSI_FMTS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE)
|
||||
#define SSI_CHAN_MIN 2
|
||||
#define SSI_CHAN_MAX 2
|
||||
#define SSI_FIFO_DEPTH 32
|
||||
|
|
@ -294,11 +295,24 @@ static int rz_ssi_clk_setup(struct rz_ssi_priv *ssi, unsigned int rate,
|
|||
}
|
||||
|
||||
/*
|
||||
* DWL: Data Word Length = 16 bits
|
||||
* DWL: Data Word Length = {16, 24} bits
|
||||
* SWL: System Word Length = 32 bits
|
||||
*/
|
||||
ssicr |= SSICR_CKDV(clk_ckdv);
|
||||
ssicr |= SSICR_DWL(1) | SSICR_SWL(3);
|
||||
switch (ssi->hw_params_cache.sample_width) {
|
||||
case 16:
|
||||
ssicr |= SSICR_DWL(1);
|
||||
break;
|
||||
case 24:
|
||||
ssicr |= SSICR_DWL(5) | SSICR_PDTA;
|
||||
break;
|
||||
default:
|
||||
dev_err(ssi->dev, "Not support %u data width",
|
||||
ssi->hw_params_cache.sample_width);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ssicr |= SSICR_SWL(3);
|
||||
rz_ssi_reg_writel(ssi, SSICR, ssicr);
|
||||
rz_ssi_reg_writel(ssi, SSIFCR, SSIFCR_AUCKE | SSIFCR_FIFO_RST);
|
||||
|
||||
|
|
@ -455,7 +469,6 @@ static int rz_ssi_pio_recv(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm)
|
|||
{
|
||||
struct snd_pcm_substream *substream = strm->substream;
|
||||
struct snd_pcm_runtime *runtime;
|
||||
u16 *buf;
|
||||
int fifo_samples;
|
||||
int frames_left;
|
||||
int samples;
|
||||
|
|
@ -490,12 +503,23 @@ static int rz_ssi_pio_recv(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm)
|
|||
break;
|
||||
|
||||
/* calculate new buffer index */
|
||||
buf = (u16 *)runtime->dma_area;
|
||||
buf += strm->buffer_pos * runtime->channels;
|
||||
if (ssi->hw_params_cache.sample_width == 16) {
|
||||
u16 *buf;
|
||||
|
||||
/* Note, only supports 16-bit samples */
|
||||
for (i = 0; i < samples; i++)
|
||||
*buf++ = (u16)(rz_ssi_reg_readl(ssi, SSIFRDR) >> 16);
|
||||
buf = (u16 *)runtime->dma_area;
|
||||
buf += strm->buffer_pos * runtime->channels;
|
||||
|
||||
for (i = 0; i < samples; i++)
|
||||
*buf++ = (u16)(rz_ssi_reg_readl(ssi, SSIFRDR) >> 16);
|
||||
} else {
|
||||
u32 *buf;
|
||||
|
||||
buf = (u32 *)runtime->dma_area;
|
||||
buf += strm->buffer_pos * runtime->channels;
|
||||
|
||||
for (i = 0; i < samples; i++)
|
||||
*buf++ = rz_ssi_reg_readl(ssi, SSIFRDR);
|
||||
}
|
||||
|
||||
rz_ssi_reg_mask_setl(ssi, SSIFSR, SSIFSR_RDF, 0);
|
||||
rz_ssi_pointer_update(strm, samples / runtime->channels);
|
||||
|
|
@ -513,7 +537,6 @@ static int rz_ssi_pio_send(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm)
|
|||
int frames_left;
|
||||
int i;
|
||||
u32 ssifsr;
|
||||
u16 *buf;
|
||||
|
||||
if (!rz_ssi_stream_is_valid(ssi, strm))
|
||||
return -EINVAL;
|
||||
|
|
@ -542,12 +565,23 @@ static int rz_ssi_pio_send(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm)
|
|||
return 0;
|
||||
|
||||
/* calculate new buffer index */
|
||||
buf = (u16 *)(runtime->dma_area);
|
||||
buf += strm->buffer_pos * runtime->channels;
|
||||
if (ssi->hw_params_cache.sample_width == 16) {
|
||||
u16 *buf;
|
||||
|
||||
/* Note, only supports 16-bit samples */
|
||||
for (i = 0; i < samples; i++)
|
||||
rz_ssi_reg_writel(ssi, SSIFTDR, ((u32)(*buf++) << 16));
|
||||
buf = (u16 *)(runtime->dma_area);
|
||||
buf += strm->buffer_pos * runtime->channels;
|
||||
|
||||
for (i = 0; i < samples; i++)
|
||||
rz_ssi_reg_writel(ssi, SSIFTDR, ((u32)(*buf++) << 16));
|
||||
} else {
|
||||
u32 *buf;
|
||||
|
||||
buf = (u32 *)(runtime->dma_area);
|
||||
buf += strm->buffer_pos * runtime->channels;
|
||||
|
||||
for (i = 0; i < samples; i++)
|
||||
rz_ssi_reg_writel(ssi, SSIFTDR, *buf++);
|
||||
}
|
||||
|
||||
rz_ssi_reg_mask_setl(ssi, SSIFSR, SSIFSR_TDE, 0);
|
||||
rz_ssi_pointer_update(strm, samples / runtime->channels);
|
||||
|
|
@ -658,8 +692,13 @@ static int rz_ssi_dma_slave_config(struct rz_ssi_priv *ssi,
|
|||
cfg.direction = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;
|
||||
cfg.dst_addr = ssi->phys + SSIFTDR;
|
||||
cfg.src_addr = ssi->phys + SSIFRDR;
|
||||
cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
|
||||
cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
|
||||
if (ssi->hw_params_cache.sample_width == 16) {
|
||||
cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
|
||||
cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
|
||||
} else {
|
||||
cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
||||
cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
||||
}
|
||||
|
||||
return dmaengine_slave_config(dma_ch, &cfg);
|
||||
}
|
||||
|
|
@ -977,7 +1016,7 @@ static int rz_ssi_dai_hw_params(struct snd_pcm_substream *substream,
|
|||
unsigned int rate = params_rate(params);
|
||||
int ret;
|
||||
|
||||
if (sample_bits != 16) {
|
||||
if (!(sample_bits == 16 || sample_bits == 24)) {
|
||||
dev_err(ssi->dev, "Unsupported sample width: %d\n",
|
||||
sample_bits);
|
||||
return -EINVAL;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user