Re: [PATCH v2 6/7] ASoC: samsung: Add support for HDMI audio on TM2 board

2018-02-12 Thread Krzysztof Kozlowski
On Mon, Feb 12, 2018 at 5:15 PM, Sylwester Nawrocki
 wrote:
> This patch defines I2S1 - HDMI DAI link and implements related
> hw_params callback. The AUD PLL frequency is configured through
> the CLK_SCLK_I2S1 leaf clock, the exynos5433 clock tree
> definitions are updated in a separate patch.
>
> The device tree parsing part is changed is a way it supports older
> DTBs with just a single CPU DAI specified, without the HDMI link.
>
> Signed-off-by: Sylwester Nawrocki 
> ---
> Changes since v1:
>  - dropped the AUD PLL frequency adjustments, only 48k, 96k,
>192k sample rates will be supported.
> ---
>  sound/soc/samsung/tm2_wm5110.c | 152 
> ++---
>  1 file changed, 129 insertions(+), 23 deletions(-)

Acked-by: Krzysztof Kozlowski 

Best regards,
Krzysztof


Re: [PATCH v2 6/7] ASoC: samsung: Add support for HDMI audio on TM2 board

2018-02-12 Thread Krzysztof Kozlowski
On Mon, Feb 12, 2018 at 5:15 PM, Sylwester Nawrocki
 wrote:
> This patch defines I2S1 - HDMI DAI link and implements related
> hw_params callback. The AUD PLL frequency is configured through
> the CLK_SCLK_I2S1 leaf clock, the exynos5433 clock tree
> definitions are updated in a separate patch.
>
> The device tree parsing part is changed is a way it supports older
> DTBs with just a single CPU DAI specified, without the HDMI link.
>
> Signed-off-by: Sylwester Nawrocki 
> ---
> Changes since v1:
>  - dropped the AUD PLL frequency adjustments, only 48k, 96k,
>192k sample rates will be supported.
> ---
>  sound/soc/samsung/tm2_wm5110.c | 152 
> ++---
>  1 file changed, 129 insertions(+), 23 deletions(-)

Acked-by: Krzysztof Kozlowski 

Best regards,
Krzysztof


[PATCH v2 6/7] ASoC: samsung: Add support for HDMI audio on TM2 board

2018-02-12 Thread Sylwester Nawrocki
This patch defines I2S1 - HDMI DAI link and implements related
hw_params callback. The AUD PLL frequency is configured through
the CLK_SCLK_I2S1 leaf clock, the exynos5433 clock tree
definitions are updated in a separate patch.

The device tree parsing part is changed is a way it supports older
DTBs with just a single CPU DAI specified, without the HDMI link.

Signed-off-by: Sylwester Nawrocki 
---
Changes since v1:
 - dropped the AUD PLL frequency adjustments, only 48k, 96k,
   192k sample rates will be supported.
---
 sound/soc/samsung/tm2_wm5110.c | 152 ++---
 1 file changed, 129 insertions(+), 23 deletions(-)

diff --git a/sound/soc/samsung/tm2_wm5110.c b/sound/soc/samsung/tm2_wm5110.c
index a55d18703fe7..b6a492f1ec02 100644
--- a/sound/soc/samsung/tm2_wm5110.c
+++ b/sound/soc/samsung/tm2_wm5110.c
@@ -210,6 +210,59 @@ static struct snd_soc_ops tm2_aif2_ops = {
.hw_free = tm2_aif2_hw_free,
 };
 
+static int tm2_hdmi_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+   struct snd_soc_pcm_runtime *rtd = substream->private_data;
+   struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+   unsigned int bfs;
+   int bitwidth, ret;
+
+   bitwidth = snd_pcm_format_width(params_format(params));
+   if (bitwidth < 0) {
+   dev_err(rtd->card->dev, "Invalid bit-width: %d\n", bitwidth);
+   return bitwidth;
+   }
+
+   switch (bitwidth) {
+   case 48:
+   bfs = 64;
+   break;
+   case 16:
+   bfs = 32;
+   break;
+   default:
+   dev_err(rtd->card->dev, "Unsupported bit-width: %d\n", 
bitwidth);
+   return -EINVAL;
+   }
+
+   switch (params_rate(params)) {
+   case 48000:
+   case 96000:
+   case 192000:
+   break;
+   default:
+   dev_err(rtd->card->dev, "Unsupported sample rate: %d\n",
+   params_rate(params));
+   return -EINVAL;
+   }
+
+   ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_OPCLK,
+   0, SAMSUNG_I2S_OPCLK_PCLK);
+   if (ret < 0)
+   return ret;
+
+   ret = snd_soc_dai_set_clkdiv(cpu_dai, SAMSUNG_I2S_DIV_BCLK, bfs);
+   if (ret < 0)
+   return ret;
+
+   return 0;
+}
+
+static struct snd_soc_ops tm2_hdmi_ops = {
+   .hw_params = tm2_hdmi_hw_params,
+};
+
 static int tm2_mic_bias(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
 {
@@ -405,6 +458,12 @@ static struct snd_soc_dai_link tm2_dai_links[] = {
.dai_fmt= SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
  SND_SOC_DAIFMT_CBM_CFM,
.ignore_suspend = 1,
+   }, {
+   .name   = "HDMI",
+   .stream_name= "i2s1",
+   .ops= _hdmi_ops,
+   .dai_fmt= SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBS_CFS,
}
 };
 
@@ -412,7 +471,6 @@ static struct snd_soc_card tm2_card = {
.owner  = THIS_MODULE,
 
.dai_link   = tm2_dai_links,
-   .num_links  = ARRAY_SIZE(tm2_dai_links),
.controls   = tm2_controls,
.num_controls   = ARRAY_SIZE(tm2_controls),
.dapm_widgets   = tm2_dapm_widgets,
@@ -426,11 +484,14 @@ static struct snd_soc_card tm2_card = {
 
 static int tm2_probe(struct platform_device *pdev)
 {
+   struct device_node *cpu_dai_node[2] = {};
+   struct device_node *codec_dai_node[2] = {};
+   const char *cells_name = NULL;
struct device *dev = >dev;
struct snd_soc_card *card = _card;
struct tm2_machine_priv *priv;
-   struct device_node *cpu_dai_node, *codec_dai_node;
-   int ret, i;
+   struct of_phandle_args args;
+   int num_codecs, ret, i;
 
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
@@ -464,47 +525,92 @@ static int tm2_probe(struct platform_device *pdev)
return -EINVAL;
}
 
-   cpu_dai_node = of_parse_phandle(dev->of_node, "i2s-controller", 0);
-   if (!cpu_dai_node) {
-   dev_err(dev, "i2s-controllers property invalid or missing\n");
-   ret = -EINVAL;
-   goto amp_node_put;
+   num_codecs = of_count_phandle_with_args(dev->of_node, "audio-codec",
+NULL);
+
+   /* Skip the HDMI link if not specified in DT */
+   if (num_codecs > 1) {
+   card->num_links = ARRAY_SIZE(tm2_dai_links);
+   cells_name = "#sound-dai-cells";
+   } else {
+   card->num_links = ARRAY_SIZE(tm2_dai_links) - 1;
}
 
-   

[PATCH v2 6/7] ASoC: samsung: Add support for HDMI audio on TM2 board

2018-02-12 Thread Sylwester Nawrocki
This patch defines I2S1 - HDMI DAI link and implements related
hw_params callback. The AUD PLL frequency is configured through
the CLK_SCLK_I2S1 leaf clock, the exynos5433 clock tree
definitions are updated in a separate patch.

The device tree parsing part is changed is a way it supports older
DTBs with just a single CPU DAI specified, without the HDMI link.

Signed-off-by: Sylwester Nawrocki 
---
Changes since v1:
 - dropped the AUD PLL frequency adjustments, only 48k, 96k,
   192k sample rates will be supported.
---
 sound/soc/samsung/tm2_wm5110.c | 152 ++---
 1 file changed, 129 insertions(+), 23 deletions(-)

diff --git a/sound/soc/samsung/tm2_wm5110.c b/sound/soc/samsung/tm2_wm5110.c
index a55d18703fe7..b6a492f1ec02 100644
--- a/sound/soc/samsung/tm2_wm5110.c
+++ b/sound/soc/samsung/tm2_wm5110.c
@@ -210,6 +210,59 @@ static struct snd_soc_ops tm2_aif2_ops = {
.hw_free = tm2_aif2_hw_free,
 };
 
+static int tm2_hdmi_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+   struct snd_soc_pcm_runtime *rtd = substream->private_data;
+   struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+   unsigned int bfs;
+   int bitwidth, ret;
+
+   bitwidth = snd_pcm_format_width(params_format(params));
+   if (bitwidth < 0) {
+   dev_err(rtd->card->dev, "Invalid bit-width: %d\n", bitwidth);
+   return bitwidth;
+   }
+
+   switch (bitwidth) {
+   case 48:
+   bfs = 64;
+   break;
+   case 16:
+   bfs = 32;
+   break;
+   default:
+   dev_err(rtd->card->dev, "Unsupported bit-width: %d\n", 
bitwidth);
+   return -EINVAL;
+   }
+
+   switch (params_rate(params)) {
+   case 48000:
+   case 96000:
+   case 192000:
+   break;
+   default:
+   dev_err(rtd->card->dev, "Unsupported sample rate: %d\n",
+   params_rate(params));
+   return -EINVAL;
+   }
+
+   ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_OPCLK,
+   0, SAMSUNG_I2S_OPCLK_PCLK);
+   if (ret < 0)
+   return ret;
+
+   ret = snd_soc_dai_set_clkdiv(cpu_dai, SAMSUNG_I2S_DIV_BCLK, bfs);
+   if (ret < 0)
+   return ret;
+
+   return 0;
+}
+
+static struct snd_soc_ops tm2_hdmi_ops = {
+   .hw_params = tm2_hdmi_hw_params,
+};
+
 static int tm2_mic_bias(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
 {
@@ -405,6 +458,12 @@ static struct snd_soc_dai_link tm2_dai_links[] = {
.dai_fmt= SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
  SND_SOC_DAIFMT_CBM_CFM,
.ignore_suspend = 1,
+   }, {
+   .name   = "HDMI",
+   .stream_name= "i2s1",
+   .ops= _hdmi_ops,
+   .dai_fmt= SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBS_CFS,
}
 };
 
@@ -412,7 +471,6 @@ static struct snd_soc_card tm2_card = {
.owner  = THIS_MODULE,
 
.dai_link   = tm2_dai_links,
-   .num_links  = ARRAY_SIZE(tm2_dai_links),
.controls   = tm2_controls,
.num_controls   = ARRAY_SIZE(tm2_controls),
.dapm_widgets   = tm2_dapm_widgets,
@@ -426,11 +484,14 @@ static struct snd_soc_card tm2_card = {
 
 static int tm2_probe(struct platform_device *pdev)
 {
+   struct device_node *cpu_dai_node[2] = {};
+   struct device_node *codec_dai_node[2] = {};
+   const char *cells_name = NULL;
struct device *dev = >dev;
struct snd_soc_card *card = _card;
struct tm2_machine_priv *priv;
-   struct device_node *cpu_dai_node, *codec_dai_node;
-   int ret, i;
+   struct of_phandle_args args;
+   int num_codecs, ret, i;
 
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
@@ -464,47 +525,92 @@ static int tm2_probe(struct platform_device *pdev)
return -EINVAL;
}
 
-   cpu_dai_node = of_parse_phandle(dev->of_node, "i2s-controller", 0);
-   if (!cpu_dai_node) {
-   dev_err(dev, "i2s-controllers property invalid or missing\n");
-   ret = -EINVAL;
-   goto amp_node_put;
+   num_codecs = of_count_phandle_with_args(dev->of_node, "audio-codec",
+NULL);
+
+   /* Skip the HDMI link if not specified in DT */
+   if (num_codecs > 1) {
+   card->num_links = ARRAY_SIZE(tm2_dai_links);
+   cells_name = "#sound-dai-cells";
+   } else {
+   card->num_links = ARRAY_SIZE(tm2_dai_links) - 1;
}
 
-   codec_dai_node =