This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Try to enable the 9022a for HDMI audio output

Other Parts Discussed in Thread: TVP5158

Hi,

    We are using DVRRDK 03.00.00.00. And use the DVR board for our reference design. The SoC is DM8168, PG2.0

    I followed this porting guide to attach my 9022a to McASP 1 as sound card0, port0, where the 5158 was.

   http://processors.wiki.ti.com/index.php/TI81xx_PSP_Porting_Guide#Audio_driver_.28McASP.29

   The only thing that I didn't do exactly what it said is the mux part, I am not sure what to do here. 

   According to the porting guide, "Note that McASP2 of TI816x/TI814x does not require any pin muxing."

   I may need do something here, since I am using McASP1. But after checking the SoC spec, 
http://www.ti.com/lit/ug/sprugx8/sprugx8.pdf    Page, 367 

    McASP[1] is dedicated port and needs no muxing.

   The boot log shows that I attach the audio device successfully to the mcasp I want.

[ 2.250000] Registered tvp5158 audio codec
[ 2.250000] Registered SiI9022a HDMI audio codec
[ 2.260000] asoc: sii9022a <-> davinci-mcasp.1 mapping ok
[ 2.270000] asoc: tlv320aic3x-hifi <-> davinci-mcasp.2 mapping ok
[ 2.270000] asoc: HDMI-DAI-CODEC <-> hdmi-dai mapping ok
[ 2.280000] ALSA device list:
[ 2.280000] #0: TI81XX DVR

and cat /proc/asound/pcm is 

00-00: hdmi-sii9022a sii9022a-0 : : playback 1
00-01: AIC3X tlv320aic3x-hifi-1 : : playback 1 : capture 1
00-02: hdmi HDMI-DAI-CODEC-2 : : playback 1

 However,  I cannot make the i2s output any signal, even the clock!

 I didn't initiate 9022a before pushing frames to McASP1, Should I initiate 9022a first?

when using snd_pcm_writei to output audio, the buffer can quickly overrun and this message occurs.

playback write error (DMA or IRQ trouble?)


   Interestingly, I switched tlv320 with 9022a and attached them to mcasp 1, mcasp2, respectively

[ 2.220000] Registered tvp5158 audio codec
[ 2.220000] Registered SiI9022a HDMI audio codec
[ 2.230000] asoc: sii9022a <-> davinci-mcasp.2 mapping ok
[ 2.230000] asoc: tlv320aic3x-hifi <-> davinci-mcasp.1 mapping ok
[ 2.240000] asoc: HDMI-DAI-CODEC <-> hdmi-dai mapping ok
[ 2.250000] ALSA device list:
[ 2.250000] #0: TI81XX DVR

   All of them cannot work and result in playback write error (DMA or IRQ trouble?)

    Here are my modifications, what else should I do?

  

diff --git a/arch/arm/mach-omap2/board-ti8168dvr.c b/arch/arm/mach-omap2/board-ti8168dvr.c
index d21eb96..3c2e6f2 100644
--- a/arch/arm/mach-omap2/board-ti8168dvr.c
+++ b/arch/arm/mach-omap2/board-ti8168dvr.c
@@ -454,6 +454,14 @@ static struct platform_device tvp5158_audio_device = {
};
#endif

+static struct platform_device sii9022a_audio_device = {
+ .name = "sii9022a-audio",
+ .id = -1,
+};
+
+
#define UART_REG_OFFSET(x) ((UART_##x) << 2)

@@ -495,6 +503,10 @@ static void __init ti8168_dvr_init(void)
platform_device_register(&tvp5158_audio_device);
#endif

+ platform_device_register(&sii9022a_audio_device);
+
ti81xx_register_mcasp(0, &ti8168_dvr_snd_data);
ti816x_spi_init();

--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -2642,7 +2642,60 @@ static struct platform_device ti81xx_mcasp0_device = {
.num_resources = ARRAY_SIZE(ti81xx_mcasp0_resource),
.resource = ti81xx_mcasp0_resource,
};
#endif
+
+static u8 sii9022a_iis_serializer_direction[] = {
+ TX_MODE, RX_MODE, INACTIVE_MODE, INACTIVE_MODE,
+ INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE,
+ INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE,
+ INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE,
+};
+
+static struct snd_platform_data sii9022a_snd_data = {
+ .tx_dma_offset = 0x46400000,
+ .rx_dma_offset = 0x46400000,
+ .asp_chan_q = EVENTQ_2,
+ .tdm_slots = 2, /* number of channels */
+ .op_mode = DAVINCI_MCASP_IIS_MODE,
+ .num_serializer = ARRAY_SIZE(sii9022a_iis_serializer_direction),
+ .serial_dir = sii9022a_iis_serializer_direction,
+ .version = MCASP_VERSION_2,
+ .txnumevt = 1,
+ .rxnumevt = 1,
+};
+
+static struct resource ti81xx_mcasp1_resource[] = {
+ {
+ .name = "mcasp1",
+ .start = TI81XX_ASP1_BASE,
+ .end = TI81XX_ASP1_BASE + (SZ_1K * 12) - 1,

+ .flags = IORESOURCE_MEM,
+ },
+ /* TX event */
+ {
+ .start = TI81XX_DMA_MCASP1_AXEVT,
+ .end = TI81XX_DMA_MCASP1_AXEVT,
+ .flags = IORESOURCE_DMA,
+ },
+ /* RX event */
+ {
+ .start = TI81XX_DMA_MCASP1_AREVT,
+ .end = TI81XX_DMA_MCASP1_AREVT,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device ti81xx_mcasp1_device = {
+ .name = "davinci-mcasp", /* driver name */
+ .id = 1,
+ .dev = {
+ .platform_data = &sii9022a_snd_data,
+ },
+ .num_resources = ARRAY_SIZE(ti81xx_mcasp1_resource),
+ .resource = ti81xx_mcasp1_resource,
+};

@@ -2654,6 +2707,9 @@ void __init ti81xx_register_mcasp(int id, struct snd_platform_data *pdata)

platform_device_register(&ti81xx_mcasp_device);
platform_device_register(&ti81xx_mcasp0_device);
+ platform_device_register(&ti81xx_mcasp1_device);
}
#else
void __init ti81xx_register_mcasp(int id, struct snd_platform_data *pdata)

 

diff --git a/sound/soc/codecs/syno_sii9022a_hdmi_audio.c b/sound/soc/codecs/syno_sii9022a_hdmi_audio.c
new file mode 100644
index 0000000..c8d5ea6
--- /dev/null
+++ b/sound/soc/codecs/syno_sii9022a_hdmi_audio.c
@@ -0,0 +1,108 @@
+/*
+ * ALSA SiI9022a HDMI audio driver
+ *
+ * This driver is used by TI81XX devices to config SiI9022a HDMI audio
+ * where no codec is needed. This file provides stub codec that can be used
+ * in these configurations.
+ * Based on OMAP4 HDMI audio codec driver
+ *
+ * Author: ChengYeh Yu <cyyu@synology.com>
+ * Copyright: (C) 2012 synology Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/slab.h>
+#include <sound/soc.h>
+#include <sound/pcm.h>
+#include <sound/initval.h>
+#include <linux/i2c.h>
+
+static struct snd_soc_codec_driver soc_codec_sii9022a;
+static struct i2c_client *client;
+
+/* null function */

+static int sii9022a_set_dai_sysclk(struct snd_soc_dai *codec_dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ return 0;
+}
+
+static int sii9022a_set_dai_fmt(struct snd_soc_dai *codec_dai,
+ unsigned int fmt)
+{
+ return 0;
+}
+
+static struct snd_soc_dai_ops sii9022a_dai_ops = {
+ .set_sysclk = sii9022a_set_dai_sysclk,
+ .set_fmt = sii9022a_set_dai_fmt,
+};
+
+/* Dummy dai driver for HDMI */
+static struct snd_soc_dai_driver sii9022a_dai = {
+ .name = "sii9022a",
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_48000
+ | SNDRV_PCM_RATE_32000
+ | SNDRV_PCM_RATE_44100
+ | SNDRV_PCM_RATE_96000
+ | SNDRV_PCM_RATE_192000 ,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE
+ | SNDRV_PCM_FMTBIT_S32_LE
+ | SNDRV_PCM_FMTBIT_S24_LE,
+ },
+ .ops = &sii9022a_dai_ops,
+};

+
+static int sii9022a_audio_codec_probe(struct platform_device *pdev)
+{
+ int ret;
+
+ ret = snd_soc_register_codec(&pdev->dev, &soc_codec_sii9022a,
+ &sii9022a_dai, 1);
+ if (ret < 0)
+ printk(KERN_INFO "SiI9022a HDMI Codec register Failed\n");
+ else
+ printk(KERN_INFO "Registered SiI9022a HDMI audio codec\n");
+
+ return ret;
+}
+
+static int sii9022a_audio_codec_remove(struct platform_device *pdev)
+{
+ snd_soc_unregister_codec(&pdev->dev);
+ return 0;
+}
+
+static struct platform_driver sii9022a_audio_codec_driver = {
+ .probe = sii9022a_audio_codec_probe,
+ .remove = sii9022a_audio_codec_remove,
+ .driver = {
+ .name = "sii9022a-audio",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init sii9022a_audio_init(void)
+{
+ return platform_driver_register(&sii9022a_audio_codec_driver);
+}

+
+static void __exit sii9022a_audio_exit(void)
+{
+ platform_driver_unregister(&sii9022a_audio_codec_driver);
+}
+
+module_init(sii9022a_audio_init);
+module_exit(sii9022a_audio_exit);
+
+MODULE_DESCRIPTION(" SiI9022a Audio Dummy codec Interface");
+MODULE_LICENSE("GPL");

--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -68,6 +68,7 @@ snd-soc-wm9713-objs := wm9713.o
snd-soc-wm-hubs-objs := wm_hubs.o
snd-soc-jz4740-codec-objs := jz4740.o
snd-soc-ti81xx-hdmi-objs := ti81xx_hdmi.o
+snd-soc-syno-sii9022a-hdmi-audio-objs := syno_sii9022a_hdmi_audio.o

# Amp
snd-soc-max9877-objs := max9877.o
@@ -145,6 +146,7 @@ obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o
obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o
obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o
obj-$(CONFIG_SND_SOC_TI81XX_HDMI) += snd-soc-ti81xx-hdmi.o
+obj-$(CONFIG_SYNO_TI816X_SII9022A_AUDIO) += snd-soc-syno-sii9022a-hdmi-audio.o

# Amp
obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o

diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index 81cade9..5c561fc 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -896,6 +896,29 @@ static struct snd_soc_dai_driver davinci_mcasp_dai[] = {
.ops = &davinci_mcasp_dai_ops,

},
+ {
+ .name = "davinci-mcasp.1",
+ .playback = {
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = DAVINCI_MCASP_RATES,
+ .formats = SNDRV_PCM_FMTBIT_S8 |
+ SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
+ },
+ .capture = {
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = DAVINCI_MCASP_RATES,
+ .formats = SNDRV_PCM_FMTBIT_S8 |
+ SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
+ },
+ .ops = &davinci_mcasp_dai_ops,
+
+ },

diff --git a/sound/soc/davinci/ti81xx-dvr.c b/sound/soc/davinci/ti81xx-dvr.c
index 3a8802b..b3de89d 100644
--- a/sound/soc/davinci/ti81xx-dvr.c
+++ b/sound/soc/davinci/ti81xx-dvr.c
@@ -40,6 +40,7 @@ static int ti81xx_dvr_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *codec_dai = rtd->codec_dai;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
unsigned sysclk, fmt = 0;
+ int ret;

/* default */
sysclk = 24576000;
@@ -50,6 +51,13 @@ static int ti81xx_dvr_hw_params(struct snd_pcm_substream *substream,
*/
fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM |
SND_SOC_DAIFMT_NB_IF;
+ } else if (!strcmp(rtd->dai_link->name,"SII9022AAUDIO")){
+ /*
+ * I2S Mode
+ */
+ printk (KERN_INFO "Preparing hardware parameters");
+ fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM |
+ SND_SOC_DAIFMT_IB_NF;
} else {
/*
* DSP_B Mode

@@ -129,6 +145,17 @@ static int ti81xx_dvr_aic3x_init(struct snd_soc_pcm_runtime *rtd)
}

static struct snd_soc_dai_link ti81xx_mcasp_dai[] = {
+#ifdef CONFIG_SYNO_TI816X_SII9022A_AUDIO
+ {
+ .name = "SII9022AAUDIO",
+ .stream_name = "hdmi-sii9022a",
+ .cpu_dai_name= "davinci-mcasp.1",
+ .platform_name = "davinci-pcm-audio",
+ .codec_dai_name = "sii9022a", /* DAI name */
+ .codec_name = "sii9022a-audio",
+ .ops = &ti81xx_dvr_ops,
+ },
+#else /* not CONFIG_SYNO_TI816X_SII9022A_AUDIO */
{
.name = "TVP5158AUDIO",
.stream_name = "TVP-PCM",
@@ -138,6 +165,7 @@ static struct snd_soc_dai_link ti81xx_mcasp_dai[] = {
.codec_name = "tvp5158-audio",
.ops = &ti81xx_dvr_ops,
},
+#endif /* not CONFIG_SYNO_TI816X_SII9022A_AUDIO */
{
.name = "TLV320AIC3X",
.stream_name = "AIC3X",