Re: [linux-sunxi] [PATCH 3.4] sunxi-hdmiaudio: Enable 32-bit audio

2014-03-09 Thread Alejandro Mery



On 09/03/14 13:08, Olliver Schinagl wrote:

Mnemoc, is this confirmed/merged?


oops, thanks for the reminder



On 01/27/14 18:54, Patrick Wood wrote:

The original modifications for this patch originate from some custom
changes made to the 3.3 Android kernel by huangxin at allwinnertech.com.

The A10/A20 DMA engine for HDMI audio only supports 16 or 32-bit
transfers. The documentation says 16, 20, and 24 bits, but I have not
been able to get 24-bit audio, ether 3-bytes (PCM_FMTBIT_24_3LE) or
4-bytes (PCM_FMTBIT_24_LE) to work.

This patch removes the non-working PCM formats, PCM_FMTBIT_S18_3LE
and PCM_FMTBIT_S20_3LE, and PCM_FMTBIT_S24_LE and adds suppor for
32-bit HDMI audio (PCM_FMTBIT_S32_LE).  It's possible that other 32-bit
formats, like PCM_FMTBIT_U32_LE or PCM_FMTBIT_FLOAT_LE might work, but
couldn't be tested.

This patch was tested with 24-bit and 32-bit .wav files and the ALSA
"plughw" plugin (for upconverting the 24-bit audio files to 23-bits)
with aplay -v to verify that the target format was S32_LE.

Signed-off-by: Patrick Wood 
---
  drivers/video/sunxi/hdmi/drv_hdmi.c |6 ++
  drivers/video/sunxi/hdmi/hdmi_core.c|   30
+--
  drivers/video/sunxi/hdmi/hdmi_core.h|1 +
  include/linux/drv_hdmi.h|1 +
  sound/soc/sunxi/hdmiaudio/sndhdmi.c |   16 +-
  sound/soc/sunxi/hdmiaudio/sunxi-hdmiaudio.c |6 --
  sound/soc/sunxi/hdmiaudio/sunxi-hdmipcm.c   |3 ++-
  7 files changed, 53 insertions(+), 10 deletions(-)

diff --git a/drivers/video/sunxi/hdmi/drv_hdmi.c
b/drivers/video/sunxi/hdmi/drv_hdmi.c
index a8d3cef..283d2ae 100644
--- a/drivers/video/sunxi/hdmi/drv_hdmi.c
+++ b/drivers/video/sunxi/hdmi/drv_hdmi.c
@@ -208,6 +208,12 @@ static __s32 Hdmi_Set_Audio_Para(hdmi_audio_t
*audio_para)
  if (!audio_para)
  return -1;

+if (audio_para->sample_bit != audio_info.sample_bit) {
+if (hdmi_state >= HDMI_State_Audio_config)
+hdmi_state = HDMI_State_Audio_config;
+audio_info.sample_bit = audio_para->sample_bit;
+}
+
  if (audio_para->sample_rate != audio_info.sample_rate) {
  audio_info.sample_rate = audio_para->sample_rate;
  change = audio_info.audio_en;
diff --git a/drivers/video/sunxi/hdmi/hdmi_core.c
b/drivers/video/sunxi/hdmi/hdmi_core.c
index c1c4c9c..a6dd01f 100644
--- a/drivers/video/sunxi/hdmi/hdmi_core.c
+++ b/drivers/video/sunxi/hdmi/hdmi_core.c
@@ -580,8 +580,14 @@ __s32 audio_config(void)
  return 0;

  if (audio_info.channel_num == 1) {
-/* audio fifo rst and select ddma, 2 ch 16bit pcm */
-writel(0x, HDMI_AUDIO_UNKNOWN_0);
+if (audio_info.sample_bit == 32) {
+/* audio fifo rst and select ddma, 2 ch 32bit pcm */
+writel(0x000e, HDMI_AUDIO_UNKNOWN_0);
+} else {
+/* audio fifo rst and select ddma, 2 ch 16bit pcm */
+writel(0x, HDMI_AUDIO_UNKNOWN_0);
+}
+
  /* ddma,pcm layout0 1ch */
  writel(0x, HDMI_AUDIO_LAYOUT);
  writel(0x76543200, HDMI_AUDIO_UNKNOWN_1);
@@ -592,8 +598,14 @@ __s32 audio_config(void)
  writel(0x, HDMI_AUDIO_INFOFRAME + 8);
  writel(0x, HDMI_AUDIO_INFOFRAME + 12);
  } else if (audio_info.channel_num == 2) {
-/* audio fifo rst and select ddma, 2 ch 16bit pcm */
-writel(0x, HDMI_AUDIO_UNKNOWN_0);
+if (audio_info.sample_bit == 32) {
+/* audio fifo rst and select ddma, 2 ch 32bit pcm */
+writel(0x000e, HDMI_AUDIO_UNKNOWN_0);
+} else {
+/* audio fifo rst and select ddma, 2 ch 16bit pcm */
+writel(0x, HDMI_AUDIO_UNKNOWN_0);
+}
+
  /* ddma,pcm layout0 2ch */
  writel(0x0001, HDMI_AUDIO_LAYOUT);
  writel(0x76543210, HDMI_AUDIO_UNKNOWN_1);
@@ -604,8 +616,14 @@ __s32 audio_config(void)
  writel(0x, HDMI_AUDIO_INFOFRAME + 8);
  writel(0x, HDMI_AUDIO_INFOFRAME + 12);
  } else if (audio_info.channel_num == 8) {
-/* audio fifo rst and select ddma, 2 ch 16bit pcm */
-writel(0x, HDMI_AUDIO_UNKNOWN_0);
+if (audio_info.sample_bit == 32) {
+/* audio fifo rst and select ddma, 2 ch 32bit pcm */
+writel(0x000e, HDMI_AUDIO_UNKNOWN_0);
+} else {
+/* audio fifo rst and select ddma, 2 ch 16bit pcm */
+writel(0x, HDMI_AUDIO_UNKNOWN_0);
+}
+
  /* ddma,pcm layout1 8ch */
  writel(0x000f, HDMI_AUDIO_LAYOUT);
  writel(0x76543210, HDMI_AUDIO_UNKNOWN_1);
diff --git a/drivers/video/sunxi/hdmi/hdmi_core.h
b/drivers/video/sunxi/hdmi/hdmi_core.h
index 50abbd1..7f11557 100644
--- a/drivers/video/sunxi/hdmi/hdmi_core.h
+++ b/drivers/video/sunxi/hdmi/hdmi_core.h
@@ -84,6 +84,7 @@ typedef struct audio_timing {
  __s32 ACR_N;
  __s32 CH_STATUS

Re: [linux-sunxi] [PATCH 3.4] sunxi-hdmiaudio: Enable 32-bit audio

2014-03-09 Thread Olliver Schinagl

Mnemoc, is this confirmed/merged?

Olliver

On 01/27/14 18:54, Patrick Wood wrote:

The original modifications for this patch originate from some custom
changes made to the 3.3 Android kernel by huangxin at allwinnertech.com.

The A10/A20 DMA engine for HDMI audio only supports 16 or 32-bit
transfers. The documentation says 16, 20, and 24 bits, but I have not
been able to get 24-bit audio, ether 3-bytes (PCM_FMTBIT_24_3LE) or
4-bytes (PCM_FMTBIT_24_LE) to work.

This patch removes the non-working PCM formats, PCM_FMTBIT_S18_3LE
and PCM_FMTBIT_S20_3LE, and PCM_FMTBIT_S24_LE and adds suppor for
32-bit HDMI audio (PCM_FMTBIT_S32_LE).  It's possible that other 32-bit
formats, like PCM_FMTBIT_U32_LE or PCM_FMTBIT_FLOAT_LE might work, but
couldn't be tested.

This patch was tested with 24-bit and 32-bit .wav files and the ALSA
"plughw" plugin (for upconverting the 24-bit audio files to 23-bits)
with aplay -v to verify that the target format was S32_LE.

Signed-off-by: Patrick Wood 
---
  drivers/video/sunxi/hdmi/drv_hdmi.c |6 ++
  drivers/video/sunxi/hdmi/hdmi_core.c|   30 +--
  drivers/video/sunxi/hdmi/hdmi_core.h|1 +
  include/linux/drv_hdmi.h|1 +
  sound/soc/sunxi/hdmiaudio/sndhdmi.c |   16 +-
  sound/soc/sunxi/hdmiaudio/sunxi-hdmiaudio.c |6 --
  sound/soc/sunxi/hdmiaudio/sunxi-hdmipcm.c   |3 ++-
  7 files changed, 53 insertions(+), 10 deletions(-)

diff --git a/drivers/video/sunxi/hdmi/drv_hdmi.c 
b/drivers/video/sunxi/hdmi/drv_hdmi.c
index a8d3cef..283d2ae 100644
--- a/drivers/video/sunxi/hdmi/drv_hdmi.c
+++ b/drivers/video/sunxi/hdmi/drv_hdmi.c
@@ -208,6 +208,12 @@ static __s32 Hdmi_Set_Audio_Para(hdmi_audio_t *audio_para)
if (!audio_para)
return -1;

+   if (audio_para->sample_bit != audio_info.sample_bit) {
+   if (hdmi_state >= HDMI_State_Audio_config)
+   hdmi_state = HDMI_State_Audio_config;
+   audio_info.sample_bit = audio_para->sample_bit;
+   }
+
if (audio_para->sample_rate != audio_info.sample_rate) {
audio_info.sample_rate = audio_para->sample_rate;
change = audio_info.audio_en;
diff --git a/drivers/video/sunxi/hdmi/hdmi_core.c 
b/drivers/video/sunxi/hdmi/hdmi_core.c
index c1c4c9c..a6dd01f 100644
--- a/drivers/video/sunxi/hdmi/hdmi_core.c
+++ b/drivers/video/sunxi/hdmi/hdmi_core.c
@@ -580,8 +580,14 @@ __s32 audio_config(void)
return 0;

if (audio_info.channel_num == 1) {
-   /* audio fifo rst and select ddma, 2 ch 16bit pcm */
-   writel(0x, HDMI_AUDIO_UNKNOWN_0);
+   if (audio_info.sample_bit == 32) {
+   /* audio fifo rst and select ddma, 2 ch 32bit pcm */
+   writel(0x000e, HDMI_AUDIO_UNKNOWN_0);
+   } else {
+   /* audio fifo rst and select ddma, 2 ch 16bit pcm */
+   writel(0x, HDMI_AUDIO_UNKNOWN_0);
+   }
+
/* ddma,pcm layout0 1ch */
writel(0x, HDMI_AUDIO_LAYOUT);
writel(0x76543200, HDMI_AUDIO_UNKNOWN_1);
@@ -592,8 +598,14 @@ __s32 audio_config(void)
writel(0x, HDMI_AUDIO_INFOFRAME + 8);
writel(0x, HDMI_AUDIO_INFOFRAME + 12);
} else if (audio_info.channel_num == 2) {
-   /* audio fifo rst and select ddma, 2 ch 16bit pcm */
-   writel(0x, HDMI_AUDIO_UNKNOWN_0);
+   if (audio_info.sample_bit == 32) {
+   /* audio fifo rst and select ddma, 2 ch 32bit pcm */
+   writel(0x000e, HDMI_AUDIO_UNKNOWN_0);
+   } else {
+   /* audio fifo rst and select ddma, 2 ch 16bit pcm */
+   writel(0x, HDMI_AUDIO_UNKNOWN_0);
+   }
+
/* ddma,pcm layout0 2ch */
writel(0x0001, HDMI_AUDIO_LAYOUT);
writel(0x76543210, HDMI_AUDIO_UNKNOWN_1);
@@ -604,8 +616,14 @@ __s32 audio_config(void)
writel(0x, HDMI_AUDIO_INFOFRAME + 8);
writel(0x, HDMI_AUDIO_INFOFRAME + 12);
} else if (audio_info.channel_num == 8) {
-   /* audio fifo rst and select ddma, 2 ch 16bit pcm */
-   writel(0x, HDMI_AUDIO_UNKNOWN_0);
+   if (audio_info.sample_bit == 32) {
+   /* audio fifo rst and select ddma, 2 ch 32bit pcm */
+   writel(0x000e, HDMI_AUDIO_UNKNOWN_0);
+   } else {
+   /* audio fifo rst and select ddma, 2 ch 16bit pcm */
+   writel(0x, HDMI_AUDIO_UNKNOWN_0);
+   }
+
/* ddma,pcm layout1 8ch */
writel(0x000f, HDMI_AUDIO_LAYOUT);
writel(0x76543210, HDMI_

[linux-sunxi] [PATCH 3.4] sunxi-hdmiaudio: Enable 32-bit audio

2014-01-27 Thread Patrick Wood
The original modifications for this patch originate from some custom
changes made to the 3.3 Android kernel by huangxin at allwinnertech.com.

The A10/A20 DMA engine for HDMI audio only supports 16 or 32-bit
transfers. The documentation says 16, 20, and 24 bits, but I have not
been able to get 24-bit audio, ether 3-bytes (PCM_FMTBIT_24_3LE) or
4-bytes (PCM_FMTBIT_24_LE) to work.

This patch removes the non-working PCM formats, PCM_FMTBIT_S18_3LE
and PCM_FMTBIT_S20_3LE, and PCM_FMTBIT_S24_LE and adds suppor for
32-bit HDMI audio (PCM_FMTBIT_S32_LE).  It's possible that other 32-bit
formats, like PCM_FMTBIT_U32_LE or PCM_FMTBIT_FLOAT_LE might work, but
couldn't be tested.

This patch was tested with 24-bit and 32-bit .wav files and the ALSA
"plughw" plugin (for upconverting the 24-bit audio files to 23-bits)
with aplay -v to verify that the target format was S32_LE.

Signed-off-by: Patrick Wood 
---
 drivers/video/sunxi/hdmi/drv_hdmi.c |6 ++
 drivers/video/sunxi/hdmi/hdmi_core.c|   30 +--
 drivers/video/sunxi/hdmi/hdmi_core.h|1 +
 include/linux/drv_hdmi.h|1 +
 sound/soc/sunxi/hdmiaudio/sndhdmi.c |   16 +-
 sound/soc/sunxi/hdmiaudio/sunxi-hdmiaudio.c |6 --
 sound/soc/sunxi/hdmiaudio/sunxi-hdmipcm.c   |3 ++-
 7 files changed, 53 insertions(+), 10 deletions(-)

diff --git a/drivers/video/sunxi/hdmi/drv_hdmi.c 
b/drivers/video/sunxi/hdmi/drv_hdmi.c
index a8d3cef..283d2ae 100644
--- a/drivers/video/sunxi/hdmi/drv_hdmi.c
+++ b/drivers/video/sunxi/hdmi/drv_hdmi.c
@@ -208,6 +208,12 @@ static __s32 Hdmi_Set_Audio_Para(hdmi_audio_t *audio_para)
if (!audio_para)
return -1;
 
+   if (audio_para->sample_bit != audio_info.sample_bit) {
+   if (hdmi_state >= HDMI_State_Audio_config)
+   hdmi_state = HDMI_State_Audio_config;
+   audio_info.sample_bit = audio_para->sample_bit;
+   }
+
if (audio_para->sample_rate != audio_info.sample_rate) {
audio_info.sample_rate = audio_para->sample_rate;
change = audio_info.audio_en;
diff --git a/drivers/video/sunxi/hdmi/hdmi_core.c 
b/drivers/video/sunxi/hdmi/hdmi_core.c
index c1c4c9c..a6dd01f 100644
--- a/drivers/video/sunxi/hdmi/hdmi_core.c
+++ b/drivers/video/sunxi/hdmi/hdmi_core.c
@@ -580,8 +580,14 @@ __s32 audio_config(void)
return 0;
 
if (audio_info.channel_num == 1) {
-   /* audio fifo rst and select ddma, 2 ch 16bit pcm */
-   writel(0x, HDMI_AUDIO_UNKNOWN_0);
+   if (audio_info.sample_bit == 32) {
+   /* audio fifo rst and select ddma, 2 ch 32bit pcm */
+   writel(0x000e, HDMI_AUDIO_UNKNOWN_0);
+   } else {
+   /* audio fifo rst and select ddma, 2 ch 16bit pcm */
+   writel(0x, HDMI_AUDIO_UNKNOWN_0);
+   }
+
/* ddma,pcm layout0 1ch */
writel(0x, HDMI_AUDIO_LAYOUT);
writel(0x76543200, HDMI_AUDIO_UNKNOWN_1);
@@ -592,8 +598,14 @@ __s32 audio_config(void)
writel(0x, HDMI_AUDIO_INFOFRAME + 8);
writel(0x, HDMI_AUDIO_INFOFRAME + 12);
} else if (audio_info.channel_num == 2) {
-   /* audio fifo rst and select ddma, 2 ch 16bit pcm */
-   writel(0x, HDMI_AUDIO_UNKNOWN_0);
+   if (audio_info.sample_bit == 32) {
+   /* audio fifo rst and select ddma, 2 ch 32bit pcm */
+   writel(0x000e, HDMI_AUDIO_UNKNOWN_0);
+   } else {
+   /* audio fifo rst and select ddma, 2 ch 16bit pcm */
+   writel(0x, HDMI_AUDIO_UNKNOWN_0);
+   }
+
/* ddma,pcm layout0 2ch */
writel(0x0001, HDMI_AUDIO_LAYOUT);
writel(0x76543210, HDMI_AUDIO_UNKNOWN_1);
@@ -604,8 +616,14 @@ __s32 audio_config(void)
writel(0x, HDMI_AUDIO_INFOFRAME + 8);
writel(0x, HDMI_AUDIO_INFOFRAME + 12);
} else if (audio_info.channel_num == 8) {
-   /* audio fifo rst and select ddma, 2 ch 16bit pcm */
-   writel(0x, HDMI_AUDIO_UNKNOWN_0);
+   if (audio_info.sample_bit == 32) {
+   /* audio fifo rst and select ddma, 2 ch 32bit pcm */
+   writel(0x000e, HDMI_AUDIO_UNKNOWN_0);
+   } else {
+   /* audio fifo rst and select ddma, 2 ch 16bit pcm */
+   writel(0x, HDMI_AUDIO_UNKNOWN_0);
+   }
+
/* ddma,pcm layout1 8ch */
writel(0x000f, HDMI_AUDIO_LAYOUT);
writel(0x76543210, HDMI_AUDIO_UNKNOWN_1);
diff --git a/drivers/video/sunxi/hdmi/hdmi_core.h 
b/drivers/video/sunxi/