From: Maruthi Srinivas Bayyavarapu <maruthi.bayyavar...@amd.com>

DW i2s controller's master/slave config can be read from a
read-only register. Machine driver can try to set a master/slave
format on cpu-dai using 'set_fmt' of dai ops. A check is added to
verify codec is master when dwc is slave and vice-versa.

Signed-off-by: Maruthi Bayyavarapu <maruthi.bayyavarapu at amd.com>
Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
---
 sound/soc/dwc/designware_i2s.c | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/sound/soc/dwc/designware_i2s.c b/sound/soc/dwc/designware_i2s.c
index 3a52f82..f427325 100644
--- a/sound/soc/dwc/designware_i2s.c
+++ b/sound/soc/dwc/designware_i2s.c
@@ -341,12 +341,43 @@ static int dw_i2s_trigger(struct snd_pcm_substream 
*substream,
        return ret;
 }

+static int dw_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
+{
+       struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(cpu_dai);
+       int ret = 0;
+
+       switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+       case SND_SOC_DAIFMT_CBM_CFM:
+               if (dev->capability & DW_I2S_SLAVE)
+                       ret = 0;
+               else
+                       ret = -EINVAL;
+               break;
+       case SND_SOC_DAIFMT_CBS_CFS:
+               if (dev->capability & DW_I2S_MASTER)
+                       ret = 0;
+               else
+                       ret = -EINVAL;
+               break;
+       case SND_SOC_DAIFMT_CBM_CFS:
+       case SND_SOC_DAIFMT_CBS_CFM:
+               ret = -EINVAL;
+               break;
+       default:
+               dev_dbg(dev->dev, "dwc : Invalid master/slave format\n");
+               ret = -EINVAL;
+               break;
+       }
+       return ret;
+}
+
 static struct snd_soc_dai_ops dw_i2s_dai_ops = {
        .startup        = dw_i2s_startup,
        .shutdown       = dw_i2s_shutdown,
        .hw_params      = dw_i2s_hw_params,
        .prepare        = dw_i2s_prepare,
        .trigger        = dw_i2s_trigger,
+       .set_fmt        = dw_i2s_set_fmt,
 };

 static const struct snd_soc_component_driver dw_i2s_component = {
-- 
1.8.3.1

Reply via email to