Re: [linux-sunxi] [PATCH 3.4] sunxi-hdmiaudio: Enable 32-bit audio
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
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
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/