ASoC: hdmi-codec: remove ops dependency on the dai id
authorJerome Brunet <jbrunet@baylibre.com>
Mon, 6 May 2019 09:58:15 +0000 (11:58 +0200)
committerMark Brown <broonie@kernel.org>
Wed, 8 May 2019 08:16:28 +0000 (17:16 +0900)
The dependency on the dai_id can be removed by setting different ops
for the i2s and spdif dai and storing the dai format information in
each dai structure. It simplies the code a bit.

Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/codecs/hdmi-codec.c

index 9408e6b..90a8927 100644 (file)
@@ -278,7 +278,6 @@ static const struct hdmi_codec_cea_spk_alloc hdmi_codec_channel_alloc[] = {
 
 struct hdmi_codec_priv {
        struct hdmi_codec_pdata hcd;
-       struct hdmi_codec_daifmt daifmt[2];
        uint8_t eld[MAX_ELD_BYTES];
        struct snd_pcm_chmap *chmap_info;
        unsigned int chmap_idx;
@@ -445,6 +444,7 @@ static int hdmi_codec_hw_params(struct snd_pcm_substream *substream,
                                struct snd_soc_dai *dai)
 {
        struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
+       struct hdmi_codec_daifmt *cf = dai->playback_dma_data;
        struct hdmi_codec_params hp = {
                .iec = {
                        .status = { 0 },
@@ -489,28 +489,27 @@ static int hdmi_codec_hw_params(struct snd_pcm_substream *substream,
        hp.channels = params_channels(params);
 
        return hcp->hcd.ops->hw_params(dai->dev->parent, hcp->hcd.data,
-                                      &hcp->daifmt[dai->id], &hp);
+                                      cf, &hp);
 }
 
-static int hdmi_codec_set_fmt(struct snd_soc_dai *dai,
-                             unsigned int fmt)
+static int hdmi_codec_i2s_set_fmt(struct snd_soc_dai *dai,
+                                 unsigned int fmt)
 {
-       struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
-       struct hdmi_codec_daifmt cf = { 0 };
+       struct hdmi_codec_daifmt *cf = dai->playback_dma_data;
 
-       if (dai->id == DAI_ID_SPDIF)
-               return 0;
+       /* Reset daifmt */
+       memset(cf, 0, sizeof(*cf));
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
        case SND_SOC_DAIFMT_CBM_CFM:
-               cf.bit_clk_master = 1;
-               cf.frame_clk_master = 1;
+               cf->bit_clk_master = 1;
+               cf->frame_clk_master = 1;
                break;
        case SND_SOC_DAIFMT_CBS_CFM:
-               cf.frame_clk_master = 1;
+               cf->frame_clk_master = 1;
                break;
        case SND_SOC_DAIFMT_CBM_CFS:
-               cf.bit_clk_master = 1;
+               cf->bit_clk_master = 1;
                break;
        case SND_SOC_DAIFMT_CBS_CFS:
                break;
@@ -522,43 +521,41 @@ static int hdmi_codec_set_fmt(struct snd_soc_dai *dai,
        case SND_SOC_DAIFMT_NB_NF:
                break;
        case SND_SOC_DAIFMT_NB_IF:
-               cf.frame_clk_inv = 1;
+               cf->frame_clk_inv = 1;
                break;
        case SND_SOC_DAIFMT_IB_NF:
-               cf.bit_clk_inv = 1;
+               cf->bit_clk_inv = 1;
                break;
        case SND_SOC_DAIFMT_IB_IF:
-               cf.frame_clk_inv = 1;
-               cf.bit_clk_inv = 1;
+               cf->frame_clk_inv = 1;
+               cf->bit_clk_inv = 1;
                break;
        }
 
        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
        case SND_SOC_DAIFMT_I2S:
-               cf.fmt = HDMI_I2S;
+               cf->fmt = HDMI_I2S;
                break;
        case SND_SOC_DAIFMT_DSP_A:
-               cf.fmt = HDMI_DSP_A;
+               cf->fmt = HDMI_DSP_A;
                break;
        case SND_SOC_DAIFMT_DSP_B:
-               cf.fmt = HDMI_DSP_B;
+               cf->fmt = HDMI_DSP_B;
                break;
        case SND_SOC_DAIFMT_RIGHT_J:
-               cf.fmt = HDMI_RIGHT_J;
+               cf->fmt = HDMI_RIGHT_J;
                break;
        case SND_SOC_DAIFMT_LEFT_J:
-               cf.fmt = HDMI_LEFT_J;
+               cf->fmt = HDMI_LEFT_J;
                break;
        case SND_SOC_DAIFMT_AC97:
-               cf.fmt = HDMI_AC97;
+               cf->fmt = HDMI_AC97;
                break;
        default:
                dev_err(dai->dev, "Invalid DAI interface format\n");
                return -EINVAL;
        }
 
-       hcp->daifmt[dai->id] = cf;
-
        return 0;
 }
 
@@ -573,14 +570,20 @@ static int hdmi_codec_digital_mute(struct snd_soc_dai *dai, int mute)
        return 0;
 }
 
-static const struct snd_soc_dai_ops hdmi_dai_ops = {
+static const struct snd_soc_dai_ops hdmi_codec_i2s_dai_ops = {
        .startup        = hdmi_codec_startup,
        .shutdown       = hdmi_codec_shutdown,
        .hw_params      = hdmi_codec_hw_params,
-       .set_fmt        = hdmi_codec_set_fmt,
+       .set_fmt        = hdmi_codec_i2s_set_fmt,
        .digital_mute   = hdmi_codec_digital_mute,
 };
 
+static const struct snd_soc_dai_ops hdmi_codec_spdif_dai_ops = {
+       .startup        = hdmi_codec_startup,
+       .shutdown       = hdmi_codec_shutdown,
+       .hw_params      = hdmi_codec_hw_params,
+       .digital_mute   = hdmi_codec_digital_mute,
+};
 
 #define HDMI_RATES     (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
                         SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
@@ -648,20 +651,52 @@ static int hdmi_codec_pcm_new(struct snd_soc_pcm_runtime *rtd,
 static int hdmi_dai_probe(struct snd_soc_dai *dai)
 {
        struct snd_soc_dapm_context *dapm;
+       struct hdmi_codec_daifmt *daifmt;
        struct snd_soc_dapm_route route = {
                .sink = "TX",
                .source = dai->driver->playback.stream_name,
        };
+       int ret;
 
        dapm = snd_soc_component_get_dapm(dai->component);
+       ret = snd_soc_dapm_add_routes(dapm, &route, 1);
+       if (ret)
+               return ret;
+
+       daifmt = kzalloc(sizeof(*daifmt), GFP_KERNEL);
+       if (!daifmt)
+               return -ENOMEM;
 
-       return snd_soc_dapm_add_routes(dapm, &route, 1);
+       dai->playback_dma_data = daifmt;
+       return 0;
+}
+
+static int hdmi_dai_spdif_probe(struct snd_soc_dai *dai)
+{
+       struct hdmi_codec_daifmt *cf = dai->playback_dma_data;
+       int ret;
+
+       ret = hdmi_dai_probe(dai);
+       if (ret)
+               return ret;
+
+       cf = dai->playback_dma_data;
+       cf->fmt = HDMI_SPDIF;
+
+       return 0;
+}
+
+static int hdmi_codec_dai_remove(struct snd_soc_dai *dai)
+{
+       kfree(dai->playback_dma_data);
+       return 0;
 }
 
 static const struct snd_soc_dai_driver hdmi_i2s_dai = {
        .name = "i2s-hifi",
        .id = DAI_ID_I2S,
        .probe = hdmi_dai_probe,
+       .remove = hdmi_codec_dai_remove,
        .playback = {
                .stream_name = "I2S Playback",
                .channels_min = 2,
@@ -670,14 +705,15 @@ static const struct snd_soc_dai_driver hdmi_i2s_dai = {
                .formats = I2S_FORMATS,
                .sig_bits = 24,
        },
-       .ops = &hdmi_dai_ops,
+       .ops = &hdmi_codec_i2s_dai_ops,
        .pcm_new = hdmi_codec_pcm_new,
 };
 
 static const struct snd_soc_dai_driver hdmi_spdif_dai = {
        .name = "spdif-hifi",
        .id = DAI_ID_SPDIF,
-       .probe = hdmi_dai_probe,
+       .probe = hdmi_dai_spdif_probe,
+       .remove = hdmi_codec_dai_remove,
        .playback = {
                .stream_name = "SPDIF Playback",
                .channels_min = 2,
@@ -685,7 +721,7 @@ static const struct snd_soc_dai_driver hdmi_spdif_dai = {
                .rates = HDMI_RATES,
                .formats = SPDIF_FORMATS,
        },
-       .ops = &hdmi_dai_ops,
+       .ops = &hdmi_codec_spdif_dai_ops,
        .pcm_new = hdmi_codec_pcm_new,
 };
 
@@ -747,10 +783,8 @@ static int hdmi_codec_probe(struct platform_device *pdev)
                i++;
        }
 
-       if (hcd->spdif) {
+       if (hcd->spdif)
                daidrv[i] = hdmi_spdif_dai;
-               hcp->daifmt[DAI_ID_SPDIF].fmt = HDMI_SPDIF;
-       }
 
        dev_set_drvdata(dev, hcp);