mirror of
https://github.com/torvalds/linux.git
synced 2026-09-25 09:41:03 +02:00
ASoC: meson: aiu: introduce I2S output formatter
Introduce aiu-formatter-i2s, a gx_formatter implementation for the AIU I2S playback path. This is going to replace data formatting tasks that are currently being implemented in aiu-encoder-i2s. This should ideally follow the same design pattern used on the AXG platform (see axg-tdmout), where basically the widget/formatter corresponds to a single audio component. This is not possible in the GX platform though because all the features are currently implemented in the AIU audio component and changing that would require backward incompatible device-tree changes. Therefore aiu-formatter-i2s is kept very simple and it only implements the bare minimum functionalities to provide I2S playback formatting. It's not a standalone component though because this is still belongs to AIU. Signed-off-by: Valerio Setti <vsetti@baylibre.com> Reviewed-by: Jerome Brunet <jbrunet@baylibre.com> Link: https://patch.msgid.link/20260610-reshape-aiu-as-axg-v2-3-cac3663a8b51@baylibre.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
9335117a22
commit
2cbb32d8dc
|
|
@ -5,6 +5,7 @@ snd-soc-meson-aiu-y += aiu-acodec-ctrl.o
|
|||
snd-soc-meson-aiu-y += aiu-codec-ctrl.o
|
||||
snd-soc-meson-aiu-y += aiu-encoder-i2s.o
|
||||
snd-soc-meson-aiu-y += gx-formatter.o
|
||||
snd-soc-meson-aiu-y += aiu-formatter-i2s.o
|
||||
snd-soc-meson-aiu-y += aiu-encoder-spdif.o
|
||||
snd-soc-meson-aiu-y += aiu-fifo.o
|
||||
snd-soc-meson-aiu-y += aiu-fifo-i2s.o
|
||||
|
|
|
|||
104
sound/soc/meson/aiu-formatter-i2s.c
Normal file
104
sound/soc/meson/aiu-formatter-i2s.c
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// Copyright (c) 2026 BayLibre, SAS.
|
||||
// Author: Valerio Setti <vsetti@baylibre.com>
|
||||
|
||||
#include <sound/pcm_params.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/soc-dai.h>
|
||||
|
||||
#include "aiu.h"
|
||||
#include "gx-formatter.h"
|
||||
|
||||
#define AIU_I2S_SOURCE_DESC_MODE_8CH BIT(0)
|
||||
#define AIU_I2S_SOURCE_DESC_MODE_24BIT BIT(5)
|
||||
#define AIU_I2S_SOURCE_DESC_MODE_32BIT BIT(9)
|
||||
#define AIU_RST_SOFT_I2S_FAST BIT(0)
|
||||
|
||||
#define AIU_I2S_DAC_CFG_MSB_FIRST BIT(2)
|
||||
|
||||
static struct snd_soc_dai *
|
||||
aiu_formatter_i2s_get_be(struct snd_soc_dapm_widget *w)
|
||||
{
|
||||
struct snd_soc_dapm_path *p;
|
||||
struct snd_soc_dai *be;
|
||||
|
||||
snd_soc_dapm_widget_for_each_sink_path(w, p) {
|
||||
if (!p->connect)
|
||||
continue;
|
||||
|
||||
if (p->sink->id == snd_soc_dapm_dai_in)
|
||||
return (struct snd_soc_dai *)p->sink->priv;
|
||||
|
||||
be = aiu_formatter_i2s_get_be(p->sink);
|
||||
if (be)
|
||||
return be;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct gx_stream *
|
||||
aiu_formatter_i2s_get_stream(struct snd_soc_dapm_widget *w)
|
||||
{
|
||||
struct snd_soc_dai *be = aiu_formatter_i2s_get_be(w);
|
||||
|
||||
if (!be)
|
||||
return NULL;
|
||||
|
||||
return snd_soc_dai_dma_data_get_playback(be);
|
||||
}
|
||||
|
||||
static int aiu_formatter_i2s_prepare(struct regmap *map,
|
||||
const struct gx_formatter_hw *quirks,
|
||||
struct gx_stream *ts)
|
||||
{
|
||||
/* Always operate in split (classic interleaved) mode */
|
||||
unsigned int desc = 0;
|
||||
unsigned int tmp;
|
||||
|
||||
/* Reset required to update the pipeline */
|
||||
regmap_write(map, AIU_RST_SOFT, AIU_RST_SOFT_I2S_FAST);
|
||||
regmap_read(map, AIU_I2S_SYNC, &tmp);
|
||||
|
||||
switch (ts->physical_width) {
|
||||
case 16: /* Nothing to do */
|
||||
break;
|
||||
|
||||
case 32:
|
||||
desc |= (AIU_I2S_SOURCE_DESC_MODE_24BIT |
|
||||
AIU_I2S_SOURCE_DESC_MODE_32BIT);
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (ts->channels) {
|
||||
case 2: /* Nothing to do */
|
||||
break;
|
||||
case 8:
|
||||
desc |= AIU_I2S_SOURCE_DESC_MODE_8CH;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
regmap_update_bits(map, AIU_I2S_SOURCE_DESC,
|
||||
AIU_I2S_SOURCE_DESC_MODE_8CH |
|
||||
AIU_I2S_SOURCE_DESC_MODE_24BIT |
|
||||
AIU_I2S_SOURCE_DESC_MODE_32BIT,
|
||||
desc);
|
||||
|
||||
/* Send data MSB first */
|
||||
regmap_update_bits(map, AIU_I2S_DAC_CFG,
|
||||
AIU_I2S_DAC_CFG_MSB_FIRST,
|
||||
AIU_I2S_DAC_CFG_MSB_FIRST);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct gx_formatter_ops aiu_formatter_i2s_ops = {
|
||||
.get_stream = aiu_formatter_i2s_get_stream,
|
||||
.prepare = aiu_formatter_i2s_prepare,
|
||||
};
|
||||
Loading…
Reference in New Issue
Block a user