mcbsp.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  1. /*
  2. * linux/arch/arm/mach-omap1/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/ioport.h>
  14. #include <linux/module.h>
  15. #include <linux/init.h>
  16. #include <linux/clk.h>
  17. #include <linux/err.h>
  18. #include <linux/io.h>
  19. #include <linux/platform_device.h>
  20. #include <linux/slab.h>
  21. #include <mach/irqs.h>
  22. #include <plat/dma.h>
  23. #include <plat/mux.h>
  24. #include <plat/cpu.h>
  25. #include <plat/mcbsp.h>
  26. #define DPS_RSTCT2_PER_EN (1 << 0)
  27. #define DSP_RSTCT2_WD_PER_EN (1 << 1)
  28. static int dsp_use;
  29. static struct clk *api_clk;
  30. static struct clk *dsp_clk;
  31. static void omap1_mcbsp_request(unsigned int id)
  32. {
  33. /*
  34. * On 1510, 1610 and 1710, McBSP1 and McBSP3
  35. * are DSP public peripherals.
  36. */
  37. if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) {
  38. if (dsp_use++ == 0) {
  39. api_clk = clk_get(NULL, "api_ck");
  40. dsp_clk = clk_get(NULL, "dsp_ck");
  41. if (!IS_ERR(api_clk) && !IS_ERR(dsp_clk)) {
  42. clk_enable(api_clk);
  43. clk_enable(dsp_clk);
  44. /*
  45. * DSP external peripheral reset
  46. * FIXME: This should be moved to dsp code
  47. */
  48. __raw_writew(__raw_readw(DSP_RSTCT2) | DPS_RSTCT2_PER_EN |
  49. DSP_RSTCT2_WD_PER_EN, DSP_RSTCT2);
  50. }
  51. }
  52. }
  53. }
  54. static void omap1_mcbsp_free(unsigned int id)
  55. {
  56. if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) {
  57. if (--dsp_use == 0) {
  58. if (!IS_ERR(api_clk)) {
  59. clk_disable(api_clk);
  60. clk_put(api_clk);
  61. }
  62. if (!IS_ERR(dsp_clk)) {
  63. clk_disable(dsp_clk);
  64. clk_put(dsp_clk);
  65. }
  66. }
  67. }
  68. }
  69. static struct omap_mcbsp_ops omap1_mcbsp_ops = {
  70. .request = omap1_mcbsp_request,
  71. .free = omap1_mcbsp_free,
  72. };
  73. #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
  74. struct resource omap7xx_mcbsp_res[][6] = {
  75. {
  76. {
  77. .start = OMAP7XX_MCBSP1_BASE,
  78. .end = OMAP7XX_MCBSP1_BASE + SZ_256,
  79. .flags = IORESOURCE_MEM,
  80. },
  81. {
  82. .name = "rx",
  83. .start = INT_7XX_McBSP1RX,
  84. .flags = IORESOURCE_IRQ,
  85. },
  86. {
  87. .name = "tx",
  88. .start = INT_7XX_McBSP1TX,
  89. .flags = IORESOURCE_IRQ,
  90. },
  91. {
  92. .name = "rx",
  93. .start = OMAP_DMA_MCBSP1_RX,
  94. .flags = IORESOURCE_DMA,
  95. },
  96. {
  97. .name = "tx",
  98. .start = OMAP_DMA_MCBSP1_TX,
  99. .flags = IORESOURCE_DMA,
  100. },
  101. },
  102. {
  103. {
  104. .start = OMAP7XX_MCBSP2_BASE,
  105. .end = OMAP7XX_MCBSP2_BASE + SZ_256,
  106. .flags = IORESOURCE_MEM,
  107. },
  108. {
  109. .name = "rx",
  110. .start = INT_7XX_McBSP2RX,
  111. .flags = IORESOURCE_IRQ,
  112. },
  113. {
  114. .name = "tx",
  115. .start = INT_7XX_McBSP2TX,
  116. .flags = IORESOURCE_IRQ,
  117. },
  118. {
  119. .name = "rx",
  120. .start = OMAP_DMA_MCBSP3_RX,
  121. .flags = IORESOURCE_DMA,
  122. },
  123. {
  124. .name = "tx",
  125. .start = OMAP_DMA_MCBSP3_TX,
  126. .flags = IORESOURCE_DMA,
  127. },
  128. },
  129. };
  130. static struct omap_mcbsp_platform_data omap7xx_mcbsp_pdata[] = {
  131. {
  132. .ops = &omap1_mcbsp_ops,
  133. },
  134. {
  135. .ops = &omap1_mcbsp_ops,
  136. },
  137. };
  138. #define OMAP7XX_MCBSP_RES_SZ ARRAY_SIZE(omap7xx_mcbsp_res[1])
  139. #define OMAP7XX_MCBSP_COUNT ARRAY_SIZE(omap7xx_mcbsp_res)
  140. #else
  141. #define omap7xx_mcbsp_res NULL
  142. #define omap7xx_mcbsp_pdata NULL
  143. #define OMAP7XX_MCBSP_RES_SZ 0
  144. #define OMAP7XX_MCBSP_COUNT 0
  145. #endif
  146. #ifdef CONFIG_ARCH_OMAP15XX
  147. struct resource omap15xx_mcbsp_res[][6] = {
  148. {
  149. {
  150. .start = OMAP1510_MCBSP1_BASE,
  151. .end = OMAP1510_MCBSP1_BASE + SZ_256,
  152. .flags = IORESOURCE_MEM,
  153. },
  154. {
  155. .name = "rx",
  156. .start = INT_McBSP1RX,
  157. .flags = IORESOURCE_IRQ,
  158. },
  159. {
  160. .name = "tx",
  161. .start = INT_McBSP1TX,
  162. .flags = IORESOURCE_IRQ,
  163. },
  164. {
  165. .name = "rx",
  166. .start = OMAP_DMA_MCBSP1_RX,
  167. .flags = IORESOURCE_DMA,
  168. },
  169. {
  170. .name = "tx",
  171. .start = OMAP_DMA_MCBSP1_TX,
  172. .flags = IORESOURCE_DMA,
  173. },
  174. },
  175. {
  176. {
  177. .start = OMAP1510_MCBSP2_BASE,
  178. .end = OMAP1510_MCBSP2_BASE + SZ_256,
  179. .flags = IORESOURCE_MEM,
  180. },
  181. {
  182. .name = "rx",
  183. .start = INT_1510_SPI_RX,
  184. .flags = IORESOURCE_IRQ,
  185. },
  186. {
  187. .name = "tx",
  188. .start = INT_1510_SPI_TX,
  189. .flags = IORESOURCE_IRQ,
  190. },
  191. {
  192. .name = "rx",
  193. .start = OMAP_DMA_MCBSP2_RX,
  194. .flags = IORESOURCE_DMA,
  195. },
  196. {
  197. .name = "tx",
  198. .start = OMAP_DMA_MCBSP2_TX,
  199. .flags = IORESOURCE_DMA,
  200. },
  201. },
  202. {
  203. {
  204. .start = OMAP1510_MCBSP3_BASE,
  205. .end = OMAP1510_MCBSP3_BASE + SZ_256,
  206. .flags = IORESOURCE_MEM,
  207. },
  208. {
  209. .name = "rx",
  210. .start = INT_McBSP3RX,
  211. .flags = IORESOURCE_IRQ,
  212. },
  213. {
  214. .name = "tx",
  215. .start = INT_McBSP3TX,
  216. .flags = IORESOURCE_IRQ,
  217. },
  218. {
  219. .name = "rx",
  220. .start = OMAP_DMA_MCBSP3_RX,
  221. .flags = IORESOURCE_DMA,
  222. },
  223. {
  224. .name = "tx",
  225. .start = OMAP_DMA_MCBSP3_TX,
  226. .flags = IORESOURCE_DMA,
  227. },
  228. },
  229. };
  230. static struct omap_mcbsp_platform_data omap15xx_mcbsp_pdata[] = {
  231. {
  232. .ops = &omap1_mcbsp_ops,
  233. },
  234. {
  235. .ops = &omap1_mcbsp_ops,
  236. },
  237. {
  238. .ops = &omap1_mcbsp_ops,
  239. },
  240. };
  241. #define OMAP15XX_MCBSP_RES_SZ ARRAY_SIZE(omap15xx_mcbsp_res[1])
  242. #define OMAP15XX_MCBSP_COUNT ARRAY_SIZE(omap15xx_mcbsp_res)
  243. #else
  244. #define omap15xx_mcbsp_res NULL
  245. #define omap15xx_mcbsp_pdata NULL
  246. #define OMAP15XX_MCBSP_RES_SZ 0
  247. #define OMAP15XX_MCBSP_COUNT 0
  248. #endif
  249. #ifdef CONFIG_ARCH_OMAP16XX
  250. struct resource omap16xx_mcbsp_res[][6] = {
  251. {
  252. {
  253. .start = OMAP1610_MCBSP1_BASE,
  254. .end = OMAP1610_MCBSP1_BASE + SZ_256,
  255. .flags = IORESOURCE_MEM,
  256. },
  257. {
  258. .name = "rx",
  259. .start = INT_McBSP1RX,
  260. .flags = IORESOURCE_IRQ,
  261. },
  262. {
  263. .name = "tx",
  264. .start = INT_McBSP1TX,
  265. .flags = IORESOURCE_IRQ,
  266. },
  267. {
  268. .name = "rx",
  269. .start = OMAP_DMA_MCBSP1_RX,
  270. .flags = IORESOURCE_DMA,
  271. },
  272. {
  273. .name = "tx",
  274. .start = OMAP_DMA_MCBSP1_TX,
  275. .flags = IORESOURCE_DMA,
  276. },
  277. },
  278. {
  279. {
  280. .start = OMAP1610_MCBSP2_BASE,
  281. .end = OMAP1610_MCBSP2_BASE + SZ_256,
  282. .flags = IORESOURCE_MEM,
  283. },
  284. {
  285. .name = "rx",
  286. .start = INT_1610_McBSP2_RX,
  287. .flags = IORESOURCE_IRQ,
  288. },
  289. {
  290. .name = "tx",
  291. .start = INT_1610_McBSP2_TX,
  292. .flags = IORESOURCE_IRQ,
  293. },
  294. {
  295. .name = "rx",
  296. .start = OMAP_DMA_MCBSP2_RX,
  297. .flags = IORESOURCE_DMA,
  298. },
  299. {
  300. .name = "tx",
  301. .start = OMAP_DMA_MCBSP2_TX,
  302. .flags = IORESOURCE_DMA,
  303. },
  304. },
  305. {
  306. {
  307. .start = OMAP1610_MCBSP3_BASE,
  308. .end = OMAP1610_MCBSP3_BASE + SZ_256,
  309. .flags = IORESOURCE_MEM,
  310. },
  311. {
  312. .name = "rx",
  313. .start = INT_McBSP3RX,
  314. .flags = IORESOURCE_IRQ,
  315. },
  316. {
  317. .name = "tx",
  318. .start = INT_McBSP3TX,
  319. .flags = IORESOURCE_IRQ,
  320. },
  321. {
  322. .name = "rx",
  323. .start = OMAP_DMA_MCBSP3_RX,
  324. .flags = IORESOURCE_DMA,
  325. },
  326. {
  327. .name = "tx",
  328. .start = OMAP_DMA_MCBSP3_TX,
  329. .flags = IORESOURCE_DMA,
  330. },
  331. },
  332. };
  333. static struct omap_mcbsp_platform_data omap16xx_mcbsp_pdata[] = {
  334. {
  335. .ops = &omap1_mcbsp_ops,
  336. },
  337. {
  338. .ops = &omap1_mcbsp_ops,
  339. },
  340. {
  341. .ops = &omap1_mcbsp_ops,
  342. },
  343. };
  344. #define OMAP16XX_MCBSP_RES_SZ ARRAY_SIZE(omap16xx_mcbsp_res[1])
  345. #define OMAP16XX_MCBSP_COUNT ARRAY_SIZE(omap16xx_mcbsp_res)
  346. #else
  347. #define omap16xx_mcbsp_res NULL
  348. #define omap16xx_mcbsp_pdata NULL
  349. #define OMAP16XX_MCBSP_RES_SZ 0
  350. #define OMAP16XX_MCBSP_COUNT 0
  351. #endif
  352. static int __init omap1_mcbsp_init(void)
  353. {
  354. if (!cpu_class_is_omap1())
  355. return -ENODEV;
  356. if (cpu_is_omap7xx())
  357. omap_mcbsp_count = OMAP7XX_MCBSP_COUNT;
  358. else if (cpu_is_omap15xx())
  359. omap_mcbsp_count = OMAP15XX_MCBSP_COUNT;
  360. else if (cpu_is_omap16xx())
  361. omap_mcbsp_count = OMAP16XX_MCBSP_COUNT;
  362. mcbsp_ptr = kzalloc(omap_mcbsp_count * sizeof(struct omap_mcbsp *),
  363. GFP_KERNEL);
  364. if (!mcbsp_ptr)
  365. return -ENOMEM;
  366. if (cpu_is_omap7xx())
  367. omap_mcbsp_register_board_cfg(omap7xx_mcbsp_res[0],
  368. OMAP7XX_MCBSP_RES_SZ,
  369. omap7xx_mcbsp_pdata,
  370. OMAP7XX_MCBSP_COUNT);
  371. if (cpu_is_omap15xx())
  372. omap_mcbsp_register_board_cfg(omap15xx_mcbsp_res[0],
  373. OMAP15XX_MCBSP_RES_SZ,
  374. omap15xx_mcbsp_pdata,
  375. OMAP15XX_MCBSP_COUNT);
  376. if (cpu_is_omap16xx())
  377. omap_mcbsp_register_board_cfg(omap16xx_mcbsp_res[0],
  378. OMAP16XX_MCBSP_RES_SZ,
  379. omap16xx_mcbsp_pdata,
  380. OMAP16XX_MCBSP_COUNT);
  381. return omap_mcbsp_init();
  382. }
  383. arch_initcall(omap1_mcbsp_init);