From 05e59e5fb0064c97a1c10921ecd549f2d4a58565 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Wed, 09 Oct 2024 06:14:40 +0000
Subject: [PATCH] add REDIRECT
---
kernel/sound/soc/rockchip/rockchip_multi_dais.c | 108 ++++++++++++++++++++++++++++++++++++++++++++----------
1 files changed, 88 insertions(+), 20 deletions(-)
diff --git a/kernel/sound/soc/rockchip/rockchip_multi_dais.c b/kernel/sound/soc/rockchip/rockchip_multi_dais.c
index e52be21..4b9bb34 100644
--- a/kernel/sound/soc/rockchip/rockchip_multi_dais.c
+++ b/kernel/sound/soc/rockchip/rockchip_multi_dais.c
@@ -23,9 +23,18 @@
#define DAIS_DRV_NAME "rockchip-mdais"
#define RK3308_GRF_SOC_CON2 0x308
+#define SOUND_NAME_PREFIX "sound-name-prefix"
+
static inline struct rk_mdais_dev *to_info(struct snd_soc_dai *dai)
{
return snd_soc_dai_get_drvdata(dai);
+}
+
+static inline unsigned int *mdais_channel_maps(struct rk_mdais_dev *mdais,
+ struct snd_pcm_substream *substream)
+{
+ return substream->stream ? mdais->capture_channel_maps :
+ mdais->playback_channel_maps;
}
static void hw_refine_channels(struct snd_pcm_hw_params *params,
@@ -52,26 +61,51 @@
if (IS_ERR(cparams))
return PTR_ERR(cparams);
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- channel_maps = mdais->playback_channel_maps;
- else
- channel_maps = mdais->capture_channel_maps;
+ channel_maps = mdais_channel_maps(mdais, substream);
for (i = 0; i < mdais->num_dais; i++) {
child = mdais->dais[i].dai;
- if (channel_maps[i])
- hw_refine_channels(cparams, channel_maps[i]);
+ if (!channel_maps[i])
+ continue;
+
+ hw_refine_channels(cparams, channel_maps[i]);
if (child->driver->ops && child->driver->ops->hw_params) {
ret = child->driver->ops->hw_params(substream, cparams, child);
if (ret < 0) {
- dev_err(dai->dev, "ASoC: can't set %s hw params: %d\n",
+ dev_err(dai->dev, "Failed to set %s hw params: %d\n",
dai->name, ret);
- return ret;
+ break;
}
}
}
kfree(cparams);
+
+ return ret;
+}
+
+static int rockchip_mdais_hw_free(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct rk_mdais_dev *mdais = to_info(dai);
+ struct snd_soc_dai *child;
+ unsigned int *channel_maps;
+ int ret = 0, i = 0;
+
+ channel_maps = mdais_channel_maps(mdais, substream);
+
+ for (i = 0; i < mdais->num_dais; i++) {
+ child = mdais->dais[i].dai;
+ if (!channel_maps[i])
+ continue;
+
+ if (child->driver->ops && child->driver->ops->hw_free) {
+ ret = child->driver->ops->hw_free(substream, child);
+ if (ret < 0)
+ return ret;
+ }
+ }
+
return 0;
}
@@ -83,10 +117,7 @@
unsigned int *channel_maps;
int ret = 0, i = 0;
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- channel_maps = mdais->playback_channel_maps;
- else
- channel_maps = mdais->capture_channel_maps;
+ channel_maps = mdais_channel_maps(mdais, substream);
for (i = 0; i < mdais->num_dais; i++) {
/* skip DAIs which have no channel mapping */
@@ -110,9 +141,15 @@
{
struct rk_mdais_dev *mdais = to_info(dai);
struct snd_soc_dai *child;
+ unsigned int *channel_maps;
int ret = 0, i = 0;
+ channel_maps = mdais_channel_maps(mdais, substream);
+
for (i = 0; i < mdais->num_dais; i++) {
+ if (!channel_maps[i])
+ continue;
+
child = mdais->dais[i].dai;
if (child->driver->ops && child->driver->ops->startup) {
ret = child->driver->ops->startup(substream, child);
@@ -129,9 +166,15 @@
{
struct rk_mdais_dev *mdais = to_info(dai);
struct snd_soc_dai *child;
+ unsigned int *channel_maps;
int i = 0;
+ channel_maps = mdais_channel_maps(mdais, substream);
+
for (i = 0; i < mdais->num_dais; i++) {
+ if (!channel_maps[i])
+ continue;
+
child = mdais->dais[i].dai;
if (child->driver->ops && child->driver->ops->shutdown) {
child->driver->ops->shutdown(substream, child);
@@ -144,9 +187,15 @@
{
struct rk_mdais_dev *mdais = to_info(dai);
struct snd_soc_dai *child;
+ unsigned int *channel_maps;
int ret = 0, i = 0;
+ channel_maps = mdais_channel_maps(mdais, substream);
+
for (i = 0; i < mdais->num_dais; i++) {
+ if (!channel_maps[i])
+ continue;
+
child = mdais->dais[i].dai;
if (child->driver->ops && child->driver->ops->prepare) {
ret = child->driver->ops->prepare(substream, child);
@@ -220,20 +269,38 @@
static int rockchip_mdais_dai_probe(struct snd_soc_dai *dai)
{
struct rk_mdais_dev *mdais = to_info(dai);
+ struct snd_soc_component *comp;
struct snd_soc_dai *child;
+ const char *str;
int ret, i = 0;
for (i = 0; i < mdais->num_dais; i++) {
child = mdais->dais[i].dai;
+ comp = child->component;
if (!child->probed && child->driver->probe) {
- child->component->card = dai->component->card;
+ if (!comp->name_prefix) {
+ ret = device_property_read_string(child->dev,
+ SOUND_NAME_PREFIX, &str);
+ if (!ret)
+ comp->name_prefix = str;
+ }
+
+ comp->card = dai->component->card;
ret = child->driver->probe(child);
if (ret < 0) {
dev_err(child->dev,
- "ASoC: failed to probe DAI %s: %d\n",
+ "Failed to probe DAI %s: %d\n",
child->name, ret);
return ret;
}
+
+ ret = snd_soc_add_component_controls(comp,
+ comp->driver->controls,
+ comp->driver->num_controls);
+ if (ret)
+ dev_err(dai->dev, "%s: Failed to add controls, should add '%s' in DT\n",
+ dev_name(child->dev), SOUND_NAME_PREFIX);
+
dai->probed = 1;
}
}
@@ -243,6 +310,7 @@
static const struct snd_soc_dai_ops rockchip_mdais_dai_ops = {
.hw_params = rockchip_mdais_hw_params,
+ .hw_free = rockchip_mdais_hw_free,
.set_sysclk = rockchip_mdais_set_sysclk,
.set_fmt = rockchip_mdais_set_fmt,
.set_tdm_slot = rockchip_mdais_tdm_slot,
@@ -383,9 +451,9 @@
.probe = rockchip_mdais_dai_probe,
.playback = {
.stream_name = "Playback",
- .channels_min = 2,
- .channels_max = 32,
- .rates = SNDRV_PCM_RATE_8000_192000,
+ .channels_min = 1,
+ .channels_max = 512,
+ .rates = SNDRV_PCM_RATE_8000_384000,
.formats = (SNDRV_PCM_FMTBIT_S8 |
SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S20_3LE |
@@ -394,9 +462,9 @@
},
.capture = {
.stream_name = "Capture",
- .channels_min = 2,
- .channels_max = 32,
- .rates = SNDRV_PCM_RATE_8000_192000,
+ .channels_min = 1,
+ .channels_max = 512,
+ .rates = SNDRV_PCM_RATE_8000_384000,
.formats = (SNDRV_PCM_FMTBIT_S8 |
SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S20_3LE |
--
Gitblit v1.6.2