summaryrefslogtreecommitdiff
path: root/sound/soc/intel/boards
diff options
context:
space:
mode:
authorBrent Lu <brent.lu@intel.com>2024-06-24 14:11:17 +0200
committerMark Brown <broonie@kernel.org>2024-06-24 13:40:07 +0100
commite364ffceab9252c06388727250d7583d6e0aea87 (patch)
tree9c22e93c5aad09879acb6e5fafd3f2fc1d49bbbc /sound/soc/intel/boards
parent65c90df918205bc84f5448550cde76a54dae5f52 (diff)
ASoC: Intel: maxim-common: add max_98373_get_tx_mask function
Add a helper function max_98373_get_tx_mask() to get tx mask from max98373 ACPI device properties at runtime. Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com> Signed-off-by: Brent Lu <brent.lu@intel.com> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Link: https://patch.msgid.link/20240624121119.91552-3-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/intel/boards')
-rw-r--r--sound/soc/intel/boards/sof_maxim_common.c56
1 files changed, 43 insertions, 13 deletions
diff --git a/sound/soc/intel/boards/sof_maxim_common.c b/sound/soc/intel/boards/sof_maxim_common.c
index f965b172fa36..fcc3b95e57a4 100644
--- a/sound/soc/intel/boards/sof_maxim_common.c
+++ b/sound/soc/intel/boards/sof_maxim_common.c
@@ -77,19 +77,36 @@ 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},
+ {.rx = 0x3},
+ {.rx = 0x3},
};
+/*
+ * The tx mask indicates which channel(s) contains output IV-sense data and
+ * others should set to Hi-Z. Here we get the channel number from codec's ACPI
+ * device property "maxim,vmon-slot-no" and "maxim,imon-slot-no" to generate the
+ * mask. Refer to the max98373_slot_config() function in max98373.c codec driver.
+ */
+static unsigned int max_98373_get_tx_mask(struct device *dev)
+{
+ int vmon_slot;
+ int imon_slot;
+
+ if (device_property_read_u32(dev, "maxim,vmon-slot-no", &vmon_slot))
+ vmon_slot = 0;
+
+ if (device_property_read_u32(dev, "maxim,imon-slot-no", &imon_slot))
+ imon_slot = 1;
+
+ dev_dbg(dev, "vmon_slot %d imon_slot %d\n", vmon_slot, imon_slot);
+
+ return (0x1 << vmon_slot) | (0x1 << imon_slot);
+}
+
static int max_98373_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
@@ -98,6 +115,8 @@ static int max_98373_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *codec_dai;
int i;
int tdm_slots;
+ unsigned int tx_mask;
+ unsigned int tx_mask_used = 0x0;
int ret = 0;
for_each_rtd_codec_dais(rtd, i, codec_dai) {
@@ -117,13 +136,26 @@ static int max_98373_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
}
+ /* get the tx mask from ACPI device properties */
+ tx_mask = max_98373_get_tx_mask(codec_dai->dev);
+ if (!tx_mask)
+ return -EINVAL;
+
+ if (tx_mask & tx_mask_used) {
+ dev_err(codec_dai->dev, "invalid tx mask 0x%x, used 0x%x\n",
+ tx_mask, tx_mask_used);
+ return -EINVAL;
+ }
+
+ tx_mask_used |= tx_mask;
+
/*
* check if tdm slot number is too small for channel
* allocation
*/
- if (fls(max_98373_tdm_mask[i].tx) > tdm_slots) {
+ if (fls(tx_mask) > tdm_slots) {
dev_err(codec_dai->dev, "slot mismatch, tx %d slots %d\n",
- fls(max_98373_tdm_mask[i].tx), tdm_slots);
+ fls(tx_mask), tdm_slots);
return -EINVAL;
}
@@ -134,12 +166,10 @@ static int max_98373_hw_params(struct snd_pcm_substream *substream,
}
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,
+ tx_mask, 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,
+ ret = snd_soc_dai_set_tdm_slot(codec_dai, tx_mask,
max_98373_tdm_mask[i].rx,
tdm_slots,
params_width(params));