Greetings,
I am working on DM816x evaluation board with EZSDK 5.05.02.00 and Linux PSP 4.04. I need to send PCM audio data through McASP0. The bit clock and frame sync for McASP0 (MCA0_ACLKX and MCA0_AFSX) will be provided by an external FPGA. I have applied all the modifications discussed in the following user's guides and e2e posts:
http://processors.wiki.ti.com/index.php/TI81XX_PSP_AUDIO_Driver_User_Guide
http://processors.wiki.ti.com/index.php/TI81XX_PSP_AUDIO_Driver_User_Guide
http://e2e.ti.com/support/dsp/davinci_digital_media_processors/f/716/p/149316/834765.aspx#834765
http://e2e.ti.com/support/dsp/davinci_digital_media_processors/f/717/p/219756/775182.aspx#775182
Namely, I took the following steps:
1. Rename ti8168_iis_serializer_direction to ti8168_iis_serializer_direction_mcasp2
2. Add ti8168_iis_serializer_direction_mcasp0 similar to ti8168_iis_serializer_direction_mcasp2
//<linux-psp>/arch/arm/mach-omap2/board-ti8146evm.c
static u8 ti8168_iis_serializer_direction_mcasp0[] = {
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 u8 ti8468_iis_serializer_direction_mcasp2[] = {
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,
};
3. Convert ti8168_evm_snd_data into an array and add info related to the other McASP
//<linux-psp>/arch/arm/mach-omap2/board-ti8168evm.c
static struct snd_platform_data ti8168_evm_snd_data[] = {
{
//McASP2
.tx_dma_offset = 0x46800000,
.rx_dma_offset = 0x46800000,
.op_mode = DAVINCI_MCASP_IIS_MODE,
.num_serializer = ARRAY_SIZE(ti8168_iis_serializer_direction_mcasp2),
.tdm_slots = 2,
.serial_dir = ti8168_iis_serializer_direction,
.asp_chan_q = EVENTQ_2,
.version = MCASP_VERSION_2,
.txnumevt = 1,
.rxnumevt = 1,
},
{
//McASP0
.tx_dma_offset = 0x46000000,
.rx_dma_offset = 0x46000000,
.op_mode = DAVINCI_MCASP_IIS_MODE,
.num_serializer = ARRAY_SIZE(ti8168_iis_serializer_direction_mcasp0),
.tdm_slots = 2,
.serial_dir = ti8168_iis_serializer_direction,
.asp_chan_q = EVENTQ_2,
.version = MCASP_VERSION_2,
.txnumevt = 1,
.rxnumevt = 1,
},
};
4. Rename ti81xx_mcasp_resource to ti81xx_mcasp2_resource
5. Add ti81xx_mcasp0_resource similar to ti81xx_mcasp2_resource
//<linux-psp>/arch/arm/mach-omap2/devices.c
static struct resource ti81xx_mcasp0_resource[] = {
{
.name = "mcasp0",
.start = TI81XX_ASP0_BASE,
.end = TI81XX_ASP0_BASE + (SZ_1K * 12) - 1,
.flags = IORESOURCE_MEM,
},
/* TX event */
{
.start = TI81XX_DMA_MCASP0_AXEVT,
.end = TI81XX_DMA_MCASP0_AXEVT,
.flags = IORESOURCE_DMA,
},
/* RX event */
{
.start = TI81XX_DMA_MCASP0_AREVT,
.end = TI81XX_DMA_MCASP0_AREVT,
.flags = IORESOURCE_DMA,
},
};
static struct resource ti81xx_mcasp2_resource[] = {
{
.name = "mcasp2",
.start = TI81XX_ASP2_BASE,
.end = TI81XX_ASP2_BASE + (SZ_1K * 12) - 1,
.flags = IORESOURCE_MEM,
},
/* TX event */
{
.start = TI81XX_DMA_MCASP2_AXEVT,
.end = TI81XX_DMA_MCASP2_AXEVT,
.flags = IORESOURCE_DMA,
},
/* RX event */
{
.start = TI81XX_DMA_MCASP2_AREVT,
.end = TI81XX_DMA_MCASP2_AREVT,
.flags = IORESOURCE_DMA,
},
};
6. Rename ti81xx_mcasp_device to ti81xx_mcasp2_device
7. Add ti81xx_mcasp0_device similar to ti81xx_mcasp2_device
//<linux-psp>/arch/arm/mach-omap2/devices.c
static struct platform_device ti81xx_mcasp2_device = {
.name = "davinci-mcasp2",
.id = 2,
.num_resources = ARRAY_SIZE(ti81xx_mcasp2_resource),
.resource = ti81xx_mcasp2_resource,
};
static struct platform_device ti81xx_mcasp0_device = {
.name = "davinci-mcasp0",
.id = 0,
.num_resources = ARRAY_SIZE(ti81xx_mcasp0_resource),
.resource = ti81xx_mcasp0_resource,
};
8. Register McASP0 device as a platform device
//<linux-psp>/arch/arm/mach-omap2/devices.c
void __init ti81xx_register_mcasp2(int id, struct snd_platform_data *pdata)
{
ti81xx_mcasp2_device.dev.platform_data = pdata;
platform_device_register(&ti81xx_mcasp2_device);
}
void __init ti81xx_register_mcasp0(int id, struct snd_platform_data *pdata)
{
ti81xx_mcasp0_device.dev.platform_data = pdata;
platform_device_register(&ti81xx_mcasp0_device);
}
//<linux-psp>/arch/arm/mach-omap2/board-ti8168evm.c
static void __init ti8168_evm_init(void)
{
[...]
ti81xx_register_mcasp2(0, &ti8168_evm_snd_data[0]);
ti81xx_register_mcasp0(0, &ti8168_evm_snd_data[1]);
[...]
}
9. Modify the machine driver and add a dummy driver for McASP0
//<linux-psp>/sound/soc/davinci/davinci-evm.c
static struct snd_soc_dai_link ti81xx_evm_dai[] = {
{
.name = "TLV320AIC3X",
.stream_name = "AIC3X",
.codec_dai_name = "tlv320aic3x-hifi",
.codec_name = "tlv320aic3x-codec.1-0018",
.cpu_dai_name = "davinci-mcasp.2",
.platform_name = "davinci-pcm-audio",
.init = evm_aic3x_init,
.ops = &evm_ops,
},
{
.name = "FPGA_SOC_LINK",
.stream_name = "FPGA",
.codec_dai_name = "FPGA-DAI-CODEC",
.codec_name = "fpga-dummy-codec",
.cpu_dai_name = "davinci-mcasp.0",
.platform_name = "davinci-pcm-audio",
.ops = &evm_ops,
},
};
The following lines show the outputs of printk traces inserted in <linux-psp>/sound/soc/soc-core.c after inserting the kernel modules:
dai_link->name = TLV320AIC3X
dai_link->cpu_dai_name = davinci-mcasp.2
rtd->codec = -953452672 rtd->codec_dai = -983255808 rtd->platform = -982357888
rtd->cpu_dai = -983254784
dai_link->name = FPGA_SOC_LINK
dai_link->cpu_dai_name = davinci-mcasp.0
rtd->codec = 0 rtd->codec_dai = 0 rtd->platform = -982357888 rtd->cpu_dai = 0
card->num_rtd = 1
card->num_links = 2
Please let me know how I should modify the glue layer and my dummy driver to hook it up with the board.
Regards,
Mohammad