Commit 459d71f1 authored by Brent Lu's avatar Brent Lu Committed by Mark Brown

ASoC: Intel: maxim-common: rewrite max_98373_hw_params function

Rewrite max_98373_hw_params() function to get tdm slot number from
topology in runtime because earlier platforms use 4-slot setting
instead of 8. Also check if the interface is configured in TDM mode
before calling snd_soc_dai_set_tdm_slot() function.
Reviewed-by: default avatarBard Liao <yung-chuan.liao@linux.intel.com>
Signed-off-by: default avatarBrent Lu <brent.lu@intel.com>
Signed-off-by: default avatarPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://msgid.link/r/20240527193552.165567-17-pierre-louis.bossart@linux.intel.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent 97a9e991
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <sound/soc-acpi.h> #include <sound/soc-acpi.h>
#include <sound/soc-dai.h> #include <sound/soc-dai.h>
#include <sound/soc-dapm.h> #include <sound/soc-dapm.h>
#include <sound/sof.h>
#include <uapi/sound/asound.h> #include <uapi/sound/asound.h>
#include "../common/soc-intel-quirks.h" #include "../common/soc-intel-quirks.h"
#include "sof_maxim_common.h" #include "sof_maxim_common.h"
...@@ -72,27 +73,86 @@ static struct snd_soc_dai_link_component max_98373_components[] = { ...@@ -72,27 +73,86 @@ static struct snd_soc_dai_link_component max_98373_components[] = {
}, },
}; };
/*
* According to the definition of 'DAI Sel Mux' mixer in max98373.c, rx mask
* should choose two channels from TDM slots, the LSB of rx mask is left channel
* and the other one is right channel.
*
* For tx mask, each codec requires two channels: one for V-sense and the other
* one for I-sense. Must match the device property "maxim,vmon-slot-no" and
* "maxim,imon-slot-no" in ACPI table.
*/
static const struct {
unsigned int tx;
unsigned int rx;
} max_98373_tdm_mask[] = {
{.tx = 0x03, .rx = 0x3},
{.tx = 0x0c, .rx = 0x3},
};
static int max_98373_hw_params(struct snd_pcm_substream *substream, static int max_98373_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params) struct snd_pcm_hw_params *params)
{ {
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_dai_link *dai_link = rtd->dai_link;
struct snd_soc_dai *codec_dai; struct snd_soc_dai *codec_dai;
int i;
int tdm_slots;
int ret = 0; int ret = 0;
int j;
for_each_rtd_codec_dais(rtd, j, codec_dai) { for_each_rtd_codec_dais(rtd, i, codec_dai) {
if (!strcmp(codec_dai->component->name, MAX_98373_DEV0_NAME)) { if (i >= ARRAY_SIZE(max_98373_tdm_mask)) {
/* DEV0 tdm slot configuration */ dev_err(codec_dai->dev, "only 2 amps are supported\n");
ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x03, 3, 8, 32); return -EINVAL;
} else if (!strcmp(codec_dai->component->name, MAX_98373_DEV1_NAME)) { }
/* DEV1 tdm slot configuration */
ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x0C, 3, 8, 32); switch (dai_link->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_DSP_A:
case SND_SOC_DAIFMT_DSP_B:
/* get the tplg configured tdm slot number */
tdm_slots = sof_dai_get_tdm_slots(rtd);
if (tdm_slots <= 0) {
dev_err(rtd->dev, "invalid tdm slots %d\n",
tdm_slots);
return -EINVAL;
}
/*
* check if tdm slot number is too small for channel
* allocation
*/
if (fls(max_98373_tdm_mask[i].tx) > tdm_slots) {
dev_err(codec_dai->dev, "slot mismatch, tx %d slots %d\n",
fls(max_98373_tdm_mask[i].tx), tdm_slots);
return -EINVAL;
} }
if (fls(max_98373_tdm_mask[i].rx) > tdm_slots) {
dev_err(codec_dai->dev, "slot mismatch, rx %d slots %d\n",
fls(max_98373_tdm_mask[i].rx), tdm_slots);
return -EINVAL;
}
dev_dbg(codec_dai->dev, "set tdm slot: tx 0x%x rx 0x%x slots %d width %d\n",
max_98373_tdm_mask[i].tx,
max_98373_tdm_mask[i].rx,
tdm_slots, params_width(params));
ret = snd_soc_dai_set_tdm_slot(codec_dai,
max_98373_tdm_mask[i].tx,
max_98373_tdm_mask[i].rx,
tdm_slots,
params_width(params));
if (ret < 0) { if (ret < 0) {
dev_err(codec_dai->dev, "fail to set tdm slot, ret %d\n", dev_err(codec_dai->dev, "fail to set tdm slot, ret %d\n",
ret); ret);
return ret; return ret;
} }
break;
default:
dev_dbg(codec_dai->dev, "codec is in I2S mode\n");
break;
}
} }
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment