mcbsp.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. /*
  2. * linux/arch/arm/mach-omap2/mcbsp.c
  3. *
  4. * Copyright (C) 2008 Instituto Nokia de Tecnologia
  5. * Contact: Eduardo Valentin <eduardo.valentin@indt.org.br>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License version 2 as
  9. * published by the Free Software Foundation.
  10. *
  11. * Multichannel mode not supported.
  12. */
  13. #include <linux/module.h>
  14. #include <linux/init.h>
  15. #include <linux/clk.h>
  16. #include <linux/err.h>
  17. #include <linux/io.h>
  18. #include <linux/platform_device.h>
  19. #include <linux/slab.h>
  20. #include <mach/irqs.h>
  21. #include <plat/dma.h>
  22. #include <plat/cpu.h>
  23. #include <plat/mcbsp.h>
  24. #include "control.h"
  25. /* McBSP internal signal muxing functions */
  26. void omap2_mcbsp1_mux_clkr_src(u8 mux)
  27. {
  28. u32 v;
  29. v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
  30. if (mux == CLKR_SRC_CLKR)
  31. v &= ~OMAP2_MCBSP1_CLKR_MASK;
  32. else if (mux == CLKR_SRC_CLKX)
  33. v |= OMAP2_MCBSP1_CLKR_MASK;
  34. omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
  35. }
  36. EXPORT_SYMBOL(omap2_mcbsp1_mux_clkr_src);
  37. void omap2_mcbsp1_mux_fsr_src(u8 mux)
  38. {
  39. u32 v;
  40. v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
  41. if (mux == FSR_SRC_FSR)
  42. v &= ~OMAP2_MCBSP1_FSR_MASK;
  43. else if (mux == FSR_SRC_FSX)
  44. v |= OMAP2_MCBSP1_FSR_MASK;
  45. omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
  46. }
  47. EXPORT_SYMBOL(omap2_mcbsp1_mux_fsr_src);
  48. /* McBSP CLKS source switching function */
  49. int omap2_mcbsp_set_clks_src(u8 id, u8 fck_src_id)
  50. {
  51. struct omap_mcbsp *mcbsp;
  52. struct clk *fck_src;
  53. char *fck_src_name;
  54. int r;
  55. if (!omap_mcbsp_check_valid_id(id)) {
  56. pr_err("%s: Invalid id (%d)\n", __func__, id + 1);
  57. return -EINVAL;
  58. }
  59. mcbsp = id_to_mcbsp_ptr(id);
  60. if (fck_src_id == MCBSP_CLKS_PAD_SRC)
  61. fck_src_name = "pad_fck";
  62. else if (fck_src_id == MCBSP_CLKS_PRCM_SRC)
  63. fck_src_name = "prcm_fck";
  64. else
  65. return -EINVAL;
  66. fck_src = clk_get(mcbsp->dev, fck_src_name);
  67. if (IS_ERR_OR_NULL(fck_src)) {
  68. pr_err("omap-mcbsp: %s: could not clk_get() %s\n", "clks",
  69. fck_src_name);
  70. return -EINVAL;
  71. }
  72. clk_disable(mcbsp->fclk);
  73. r = clk_set_parent(mcbsp->fclk, fck_src);
  74. if (IS_ERR_VALUE(r)) {
  75. pr_err("omap-mcbsp: %s: could not clk_set_parent() to %s\n",
  76. "clks", fck_src_name);
  77. clk_put(fck_src);
  78. return -EINVAL;
  79. }
  80. clk_enable(mcbsp->fclk);
  81. clk_put(fck_src);
  82. return 0;
  83. }
  84. EXPORT_SYMBOL(omap2_mcbsp_set_clks_src);
  85. /* Platform data */
  86. #ifdef CONFIG_ARCH_OMAP2420
  87. static struct omap_mcbsp_platform_data omap2420_mcbsp_pdata[] = {
  88. {
  89. .phys_base = OMAP24XX_MCBSP1_BASE,
  90. .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX,
  91. .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX,
  92. .rx_irq = INT_24XX_MCBSP1_IRQ_RX,
  93. .tx_irq = INT_24XX_MCBSP1_IRQ_TX,
  94. },
  95. {
  96. .phys_base = OMAP24XX_MCBSP2_BASE,
  97. .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX,
  98. .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX,
  99. .rx_irq = INT_24XX_MCBSP2_IRQ_RX,
  100. .tx_irq = INT_24XX_MCBSP2_IRQ_TX,
  101. },
  102. };
  103. #define OMAP2420_MCBSP_PDATA_SZ ARRAY_SIZE(omap2420_mcbsp_pdata)
  104. #define OMAP2420_MCBSP_REG_NUM (OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1)
  105. #else
  106. #define omap2420_mcbsp_pdata NULL
  107. #define OMAP2420_MCBSP_PDATA_SZ 0
  108. #define OMAP2420_MCBSP_REG_NUM 0
  109. #endif
  110. #ifdef CONFIG_ARCH_OMAP2430
  111. static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = {
  112. {
  113. .phys_base = OMAP24XX_MCBSP1_BASE,
  114. .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX,
  115. .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX,
  116. .rx_irq = INT_24XX_MCBSP1_IRQ_RX,
  117. .tx_irq = INT_24XX_MCBSP1_IRQ_TX,
  118. },
  119. {
  120. .phys_base = OMAP24XX_MCBSP2_BASE,
  121. .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX,
  122. .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX,
  123. .rx_irq = INT_24XX_MCBSP2_IRQ_RX,
  124. .tx_irq = INT_24XX_MCBSP2_IRQ_TX,
  125. },
  126. {
  127. .phys_base = OMAP2430_MCBSP3_BASE,
  128. .dma_rx_sync = OMAP24XX_DMA_MCBSP3_RX,
  129. .dma_tx_sync = OMAP24XX_DMA_MCBSP3_TX,
  130. .rx_irq = INT_24XX_MCBSP3_IRQ_RX,
  131. .tx_irq = INT_24XX_MCBSP3_IRQ_TX,
  132. },
  133. {
  134. .phys_base = OMAP2430_MCBSP4_BASE,
  135. .dma_rx_sync = OMAP24XX_DMA_MCBSP4_RX,
  136. .dma_tx_sync = OMAP24XX_DMA_MCBSP4_TX,
  137. .rx_irq = INT_24XX_MCBSP4_IRQ_RX,
  138. .tx_irq = INT_24XX_MCBSP4_IRQ_TX,
  139. },
  140. {
  141. .phys_base = OMAP2430_MCBSP5_BASE,
  142. .dma_rx_sync = OMAP24XX_DMA_MCBSP5_RX,
  143. .dma_tx_sync = OMAP24XX_DMA_MCBSP5_TX,
  144. .rx_irq = INT_24XX_MCBSP5_IRQ_RX,
  145. .tx_irq = INT_24XX_MCBSP5_IRQ_TX,
  146. },
  147. };
  148. #define OMAP2430_MCBSP_PDATA_SZ ARRAY_SIZE(omap2430_mcbsp_pdata)
  149. #define OMAP2430_MCBSP_REG_NUM (OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1)
  150. #else
  151. #define omap2430_mcbsp_pdata NULL
  152. #define OMAP2430_MCBSP_PDATA_SZ 0
  153. #define OMAP2430_MCBSP_REG_NUM 0
  154. #endif
  155. #ifdef CONFIG_ARCH_OMAP3
  156. static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
  157. {
  158. .phys_base = OMAP34XX_MCBSP1_BASE,
  159. .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX,
  160. .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX,
  161. .rx_irq = INT_24XX_MCBSP1_IRQ_RX,
  162. .tx_irq = INT_24XX_MCBSP1_IRQ_TX,
  163. .buffer_size = 0x80, /* The FIFO has 128 locations */
  164. },
  165. {
  166. .phys_base = OMAP34XX_MCBSP2_BASE,
  167. .phys_base_st = OMAP34XX_MCBSP2_ST_BASE,
  168. .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX,
  169. .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX,
  170. .rx_irq = INT_24XX_MCBSP2_IRQ_RX,
  171. .tx_irq = INT_24XX_MCBSP2_IRQ_TX,
  172. .buffer_size = 0x500, /* The FIFO has 1024 + 256 locations */
  173. },
  174. {
  175. .phys_base = OMAP34XX_MCBSP3_BASE,
  176. .phys_base_st = OMAP34XX_MCBSP3_ST_BASE,
  177. .dma_rx_sync = OMAP24XX_DMA_MCBSP3_RX,
  178. .dma_tx_sync = OMAP24XX_DMA_MCBSP3_TX,
  179. .rx_irq = INT_24XX_MCBSP3_IRQ_RX,
  180. .tx_irq = INT_24XX_MCBSP3_IRQ_TX,
  181. .buffer_size = 0x80, /* The FIFO has 128 locations */
  182. },
  183. {
  184. .phys_base = OMAP34XX_MCBSP4_BASE,
  185. .dma_rx_sync = OMAP24XX_DMA_MCBSP4_RX,
  186. .dma_tx_sync = OMAP24XX_DMA_MCBSP4_TX,
  187. .rx_irq = INT_24XX_MCBSP4_IRQ_RX,
  188. .tx_irq = INT_24XX_MCBSP4_IRQ_TX,
  189. .buffer_size = 0x80, /* The FIFO has 128 locations */
  190. },
  191. {
  192. .phys_base = OMAP34XX_MCBSP5_BASE,
  193. .dma_rx_sync = OMAP24XX_DMA_MCBSP5_RX,
  194. .dma_tx_sync = OMAP24XX_DMA_MCBSP5_TX,
  195. .rx_irq = INT_24XX_MCBSP5_IRQ_RX,
  196. .tx_irq = INT_24XX_MCBSP5_IRQ_TX,
  197. .buffer_size = 0x80, /* The FIFO has 128 locations */
  198. },
  199. };
  200. #define OMAP34XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap34xx_mcbsp_pdata)
  201. #define OMAP34XX_MCBSP_REG_NUM (OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1)
  202. #else
  203. #define omap34xx_mcbsp_pdata NULL
  204. #define OMAP34XX_MCBSP_PDATA_SZ 0
  205. #define OMAP34XX_MCBSP_REG_NUM 0
  206. #endif
  207. static struct omap_mcbsp_platform_data omap44xx_mcbsp_pdata[] = {
  208. {
  209. .phys_base = OMAP44XX_MCBSP1_BASE,
  210. .dma_rx_sync = OMAP44XX_DMA_MCBSP1_RX,
  211. .dma_tx_sync = OMAP44XX_DMA_MCBSP1_TX,
  212. .tx_irq = OMAP44XX_IRQ_MCBSP1,
  213. },
  214. {
  215. .phys_base = OMAP44XX_MCBSP2_BASE,
  216. .dma_rx_sync = OMAP44XX_DMA_MCBSP2_RX,
  217. .dma_tx_sync = OMAP44XX_DMA_MCBSP2_TX,
  218. .tx_irq = OMAP44XX_IRQ_MCBSP2,
  219. },
  220. {
  221. .phys_base = OMAP44XX_MCBSP3_BASE,
  222. .dma_rx_sync = OMAP44XX_DMA_MCBSP3_RX,
  223. .dma_tx_sync = OMAP44XX_DMA_MCBSP3_TX,
  224. .tx_irq = OMAP44XX_IRQ_MCBSP3,
  225. },
  226. {
  227. .phys_base = OMAP44XX_MCBSP4_BASE,
  228. .dma_rx_sync = OMAP44XX_DMA_MCBSP4_RX,
  229. .dma_tx_sync = OMAP44XX_DMA_MCBSP4_TX,
  230. .tx_irq = OMAP44XX_IRQ_MCBSP4,
  231. },
  232. };
  233. #define OMAP44XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap44xx_mcbsp_pdata)
  234. #define OMAP44XX_MCBSP_REG_NUM (OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1)
  235. static int __init omap2_mcbsp_init(void)
  236. {
  237. if (cpu_is_omap2420()) {
  238. omap_mcbsp_count = OMAP2420_MCBSP_PDATA_SZ;
  239. omap_mcbsp_cache_size = OMAP2420_MCBSP_REG_NUM * sizeof(u16);
  240. } else if (cpu_is_omap2430()) {
  241. omap_mcbsp_count = OMAP2430_MCBSP_PDATA_SZ;
  242. omap_mcbsp_cache_size = OMAP2430_MCBSP_REG_NUM * sizeof(u32);
  243. } else if (cpu_is_omap34xx()) {
  244. omap_mcbsp_count = OMAP34XX_MCBSP_PDATA_SZ;
  245. omap_mcbsp_cache_size = OMAP34XX_MCBSP_REG_NUM * sizeof(u32);
  246. } else if (cpu_is_omap44xx()) {
  247. omap_mcbsp_count = OMAP44XX_MCBSP_PDATA_SZ;
  248. omap_mcbsp_cache_size = OMAP44XX_MCBSP_REG_NUM * sizeof(u32);
  249. }
  250. mcbsp_ptr = kzalloc(omap_mcbsp_count * sizeof(struct omap_mcbsp *),
  251. GFP_KERNEL);
  252. if (!mcbsp_ptr)
  253. return -ENOMEM;
  254. if (cpu_is_omap2420())
  255. omap_mcbsp_register_board_cfg(omap2420_mcbsp_pdata,
  256. OMAP2420_MCBSP_PDATA_SZ);
  257. if (cpu_is_omap2430())
  258. omap_mcbsp_register_board_cfg(omap2430_mcbsp_pdata,
  259. OMAP2430_MCBSP_PDATA_SZ);
  260. if (cpu_is_omap34xx())
  261. omap_mcbsp_register_board_cfg(omap34xx_mcbsp_pdata,
  262. OMAP34XX_MCBSP_PDATA_SZ);
  263. if (cpu_is_omap44xx())
  264. omap_mcbsp_register_board_cfg(omap44xx_mcbsp_pdata,
  265. OMAP44XX_MCBSP_PDATA_SZ);
  266. return omap_mcbsp_init();
  267. }
  268. arch_initcall(omap2_mcbsp_init);