board-mop500-audio.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /*
  2. * Copyright (C) ST-Ericsson SA 2010
  3. *
  4. * License terms: GNU General Public License (GPL), version 2
  5. */
  6. #include <linux/platform_device.h>
  7. #include <linux/init.h>
  8. #include <linux/gpio.h>
  9. #include <linux/platform_data/pinctrl-nomadik.h>
  10. #include <linux/platform_data/dma-ste-dma40.h>
  11. #include "devices.h"
  12. #include "irqs.h"
  13. #include <linux/platform_data/asoc-ux500-msp.h>
  14. #include "ste-dma40-db8500.h"
  15. #include "board-mop500.h"
  16. #include "devices-db8500.h"
  17. #include "pins-db8500.h"
  18. static struct stedma40_chan_cfg msp0_dma_rx = {
  19. .high_priority = true,
  20. .dir = STEDMA40_PERIPH_TO_MEM,
  21. .src_dev_type = DB8500_DMA_DEV31_MSP0_RX_SLIM0_CH0_RX,
  22. .dst_dev_type = STEDMA40_DEV_DST_MEMORY,
  23. .src_info.psize = STEDMA40_PSIZE_LOG_4,
  24. .dst_info.psize = STEDMA40_PSIZE_LOG_4,
  25. /* data_width is set during configuration */
  26. };
  27. static struct stedma40_chan_cfg msp0_dma_tx = {
  28. .high_priority = true,
  29. .dir = STEDMA40_MEM_TO_PERIPH,
  30. .src_dev_type = STEDMA40_DEV_DST_MEMORY,
  31. .dst_dev_type = DB8500_DMA_DEV31_MSP0_TX_SLIM0_CH0_TX,
  32. .src_info.psize = STEDMA40_PSIZE_LOG_4,
  33. .dst_info.psize = STEDMA40_PSIZE_LOG_4,
  34. /* data_width is set during configuration */
  35. };
  36. struct msp_i2s_platform_data msp0_platform_data = {
  37. .id = MSP_I2S_0,
  38. .msp_i2s_dma_rx = &msp0_dma_rx,
  39. .msp_i2s_dma_tx = &msp0_dma_tx,
  40. };
  41. static struct stedma40_chan_cfg msp1_dma_rx = {
  42. .high_priority = true,
  43. .dir = STEDMA40_PERIPH_TO_MEM,
  44. .src_dev_type = DB8500_DMA_DEV30_MSP3_RX,
  45. .dst_dev_type = STEDMA40_DEV_DST_MEMORY,
  46. .src_info.psize = STEDMA40_PSIZE_LOG_4,
  47. .dst_info.psize = STEDMA40_PSIZE_LOG_4,
  48. /* data_width is set during configuration */
  49. };
  50. static struct stedma40_chan_cfg msp1_dma_tx = {
  51. .high_priority = true,
  52. .dir = STEDMA40_MEM_TO_PERIPH,
  53. .src_dev_type = STEDMA40_DEV_DST_MEMORY,
  54. .dst_dev_type = DB8500_DMA_DEV30_MSP1_TX,
  55. .src_info.psize = STEDMA40_PSIZE_LOG_4,
  56. .dst_info.psize = STEDMA40_PSIZE_LOG_4,
  57. /* data_width is set during configuration */
  58. };
  59. struct msp_i2s_platform_data msp1_platform_data = {
  60. .id = MSP_I2S_1,
  61. .msp_i2s_dma_rx = NULL,
  62. .msp_i2s_dma_tx = &msp1_dma_tx,
  63. };
  64. static struct stedma40_chan_cfg msp2_dma_rx = {
  65. .high_priority = true,
  66. .dir = STEDMA40_PERIPH_TO_MEM,
  67. .src_dev_type = DB8500_DMA_DEV14_MSP2_RX,
  68. .dst_dev_type = STEDMA40_DEV_DST_MEMORY,
  69. /* MSP2 DMA doesn't work with PSIZE == 4 on DB8500v2 */
  70. .src_info.psize = STEDMA40_PSIZE_LOG_1,
  71. .dst_info.psize = STEDMA40_PSIZE_LOG_1,
  72. /* data_width is set during configuration */
  73. };
  74. static struct stedma40_chan_cfg msp2_dma_tx = {
  75. .high_priority = true,
  76. .dir = STEDMA40_MEM_TO_PERIPH,
  77. .src_dev_type = STEDMA40_DEV_DST_MEMORY,
  78. .dst_dev_type = DB8500_DMA_DEV14_MSP2_TX,
  79. .src_info.psize = STEDMA40_PSIZE_LOG_4,
  80. .dst_info.psize = STEDMA40_PSIZE_LOG_4,
  81. .use_fixed_channel = true,
  82. .phy_channel = 1,
  83. /* data_width is set during configuration */
  84. };
  85. static struct platform_device *db8500_add_msp_i2s(struct device *parent,
  86. int id,
  87. resource_size_t base, int irq,
  88. struct msp_i2s_platform_data *pdata)
  89. {
  90. struct platform_device *pdev;
  91. struct resource res[] = {
  92. DEFINE_RES_MEM(base, SZ_4K),
  93. DEFINE_RES_IRQ(irq),
  94. };
  95. pr_info("Register platform-device 'ux500-msp-i2s', id %d, irq %d\n",
  96. id, irq);
  97. pdev = platform_device_register_resndata(parent, "ux500-msp-i2s", id,
  98. res, ARRAY_SIZE(res),
  99. pdata, sizeof(*pdata));
  100. if (!pdev) {
  101. pr_err("Failed to register platform-device 'ux500-msp-i2s.%d'!\n",
  102. id);
  103. return NULL;
  104. }
  105. return pdev;
  106. }
  107. /* Platform device for ASoC MOP500 machine */
  108. static struct platform_device snd_soc_mop500 = {
  109. .name = "snd-soc-mop500",
  110. .id = 0,
  111. .dev = {
  112. .platform_data = NULL,
  113. },
  114. };
  115. struct msp_i2s_platform_data msp2_platform_data = {
  116. .id = MSP_I2S_2,
  117. .msp_i2s_dma_rx = &msp2_dma_rx,
  118. .msp_i2s_dma_tx = &msp2_dma_tx,
  119. };
  120. struct msp_i2s_platform_data msp3_platform_data = {
  121. .id = MSP_I2S_3,
  122. .msp_i2s_dma_rx = &msp1_dma_rx,
  123. .msp_i2s_dma_tx = NULL,
  124. };
  125. void mop500_audio_init(struct device *parent)
  126. {
  127. pr_info("%s: Register platform-device 'snd-soc-mop500'.\n", __func__);
  128. platform_device_register(&snd_soc_mop500);
  129. pr_info("Initialize MSP I2S-devices.\n");
  130. db8500_add_msp_i2s(parent, 0, U8500_MSP0_BASE, IRQ_DB8500_MSP0,
  131. &msp0_platform_data);
  132. db8500_add_msp_i2s(parent, 1, U8500_MSP1_BASE, IRQ_DB8500_MSP1,
  133. &msp1_platform_data);
  134. db8500_add_msp_i2s(parent, 2, U8500_MSP2_BASE, IRQ_DB8500_MSP2,
  135. &msp2_platform_data);
  136. db8500_add_msp_i2s(parent, 3, U8500_MSP3_BASE, IRQ_DB8500_MSP1,
  137. &msp3_platform_data);
  138. }