mcbsp.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  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. #define omap7xx_mcbsp_res_0 omap7xx_mcbsp_res[0]
  131. static struct omap_mcbsp_platform_data omap7xx_mcbsp_pdata[] = {
  132. {
  133. .ops = &omap1_mcbsp_ops,
  134. },
  135. {
  136. .ops = &omap1_mcbsp_ops,
  137. },
  138. };
  139. #define OMAP7XX_MCBSP_RES_SZ ARRAY_SIZE(omap7xx_mcbsp_res[1])
  140. #define OMAP7XX_MCBSP_COUNT ARRAY_SIZE(omap7xx_mcbsp_res)
  141. #else
  142. #define omap7xx_mcbsp_res_0 NULL
  143. #define omap7xx_mcbsp_pdata NULL
  144. #define OMAP7XX_MCBSP_RES_SZ 0
  145. #define OMAP7XX_MCBSP_COUNT 0
  146. #endif
  147. #ifdef CONFIG_ARCH_OMAP15XX
  148. struct resource omap15xx_mcbsp_res[][6] = {
  149. {
  150. {
  151. .start = OMAP1510_MCBSP1_BASE,
  152. .end = OMAP1510_MCBSP1_BASE + SZ_256,
  153. .flags = IORESOURCE_MEM,
  154. },
  155. {
  156. .name = "rx",
  157. .start = INT_McBSP1RX,
  158. .flags = IORESOURCE_IRQ,
  159. },
  160. {
  161. .name = "tx",
  162. .start = INT_McBSP1TX,
  163. .flags = IORESOURCE_IRQ,
  164. },
  165. {
  166. .name = "rx",
  167. .start = OMAP_DMA_MCBSP1_RX,
  168. .flags = IORESOURCE_DMA,
  169. },
  170. {
  171. .name = "tx",
  172. .start = OMAP_DMA_MCBSP1_TX,
  173. .flags = IORESOURCE_DMA,
  174. },
  175. },
  176. {
  177. {
  178. .start = OMAP1510_MCBSP2_BASE,
  179. .end = OMAP1510_MCBSP2_BASE + SZ_256,
  180. .flags = IORESOURCE_MEM,
  181. },
  182. {
  183. .name = "rx",
  184. .start = INT_1510_SPI_RX,
  185. .flags = IORESOURCE_IRQ,
  186. },
  187. {
  188. .name = "tx",
  189. .start = INT_1510_SPI_TX,
  190. .flags = IORESOURCE_IRQ,
  191. },
  192. {
  193. .name = "rx",
  194. .start = OMAP_DMA_MCBSP2_RX,
  195. .flags = IORESOURCE_DMA,
  196. },
  197. {
  198. .name = "tx",
  199. .start = OMAP_DMA_MCBSP2_TX,
  200. .flags = IORESOURCE_DMA,
  201. },
  202. },
  203. {
  204. {
  205. .start = OMAP1510_MCBSP3_BASE,
  206. .end = OMAP1510_MCBSP3_BASE + SZ_256,
  207. .flags = IORESOURCE_MEM,
  208. },
  209. {
  210. .name = "rx",
  211. .start = INT_McBSP3RX,
  212. .flags = IORESOURCE_IRQ,
  213. },
  214. {
  215. .name = "tx",
  216. .start = INT_McBSP3TX,
  217. .flags = IORESOURCE_IRQ,
  218. },
  219. {
  220. .name = "rx",
  221. .start = OMAP_DMA_MCBSP3_RX,
  222. .flags = IORESOURCE_DMA,
  223. },
  224. {
  225. .name = "tx",
  226. .start = OMAP_DMA_MCBSP3_TX,
  227. .flags = IORESOURCE_DMA,
  228. },
  229. },
  230. };
  231. #define omap15xx_mcbsp_res_0 omap15xx_mcbsp_res[0]
  232. static struct omap_mcbsp_platform_data omap15xx_mcbsp_pdata[] = {
  233. {
  234. .ops = &omap1_mcbsp_ops,
  235. },
  236. {
  237. .ops = &omap1_mcbsp_ops,
  238. },
  239. {
  240. .ops = &omap1_mcbsp_ops,
  241. },
  242. };
  243. #define OMAP15XX_MCBSP_RES_SZ ARRAY_SIZE(omap15xx_mcbsp_res[1])
  244. #define OMAP15XX_MCBSP_COUNT ARRAY_SIZE(omap15xx_mcbsp_res)
  245. #else
  246. #define omap15xx_mcbsp_res_0 NULL
  247. #define omap15xx_mcbsp_pdata NULL
  248. #define OMAP15XX_MCBSP_RES_SZ 0
  249. #define OMAP15XX_MCBSP_COUNT 0
  250. #endif
  251. #ifdef CONFIG_ARCH_OMAP16XX
  252. struct resource omap16xx_mcbsp_res[][6] = {
  253. {
  254. {
  255. .start = OMAP1610_MCBSP1_BASE,
  256. .end = OMAP1610_MCBSP1_BASE + SZ_256,
  257. .flags = IORESOURCE_MEM,
  258. },
  259. {
  260. .name = "rx",
  261. .start = INT_McBSP1RX,
  262. .flags = IORESOURCE_IRQ,
  263. },
  264. {
  265. .name = "tx",
  266. .start = INT_McBSP1TX,
  267. .flags = IORESOURCE_IRQ,
  268. },
  269. {
  270. .name = "rx",
  271. .start = OMAP_DMA_MCBSP1_RX,
  272. .flags = IORESOURCE_DMA,
  273. },
  274. {
  275. .name = "tx",
  276. .start = OMAP_DMA_MCBSP1_TX,
  277. .flags = IORESOURCE_DMA,
  278. },
  279. },
  280. {
  281. {
  282. .start = OMAP1610_MCBSP2_BASE,
  283. .end = OMAP1610_MCBSP2_BASE + SZ_256,
  284. .flags = IORESOURCE_MEM,
  285. },
  286. {
  287. .name = "rx",
  288. .start = INT_1610_McBSP2_RX,
  289. .flags = IORESOURCE_IRQ,
  290. },
  291. {
  292. .name = "tx",
  293. .start = INT_1610_McBSP2_TX,
  294. .flags = IORESOURCE_IRQ,
  295. },
  296. {
  297. .name = "rx",
  298. .start = OMAP_DMA_MCBSP2_RX,
  299. .flags = IORESOURCE_DMA,
  300. },
  301. {
  302. .name = "tx",
  303. .start = OMAP_DMA_MCBSP2_TX,
  304. .flags = IORESOURCE_DMA,
  305. },
  306. },
  307. {
  308. {
  309. .start = OMAP1610_MCBSP3_BASE,
  310. .end = OMAP1610_MCBSP3_BASE + SZ_256,
  311. .flags = IORESOURCE_MEM,
  312. },
  313. {
  314. .name = "rx",
  315. .start = INT_McBSP3RX,
  316. .flags = IORESOURCE_IRQ,
  317. },
  318. {
  319. .name = "tx",
  320. .start = INT_McBSP3TX,
  321. .flags = IORESOURCE_IRQ,
  322. },
  323. {
  324. .name = "rx",
  325. .start = OMAP_DMA_MCBSP3_RX,
  326. .flags = IORESOURCE_DMA,
  327. },
  328. {
  329. .name = "tx",
  330. .start = OMAP_DMA_MCBSP3_TX,
  331. .flags = IORESOURCE_DMA,
  332. },
  333. },
  334. };
  335. #define omap16xx_mcbsp_res_0 omap16xx_mcbsp_res[0]
  336. static struct omap_mcbsp_platform_data omap16xx_mcbsp_pdata[] = {
  337. {
  338. .ops = &omap1_mcbsp_ops,
  339. },
  340. {
  341. .ops = &omap1_mcbsp_ops,
  342. },
  343. {
  344. .ops = &omap1_mcbsp_ops,
  345. },
  346. };
  347. #define OMAP16XX_MCBSP_RES_SZ ARRAY_SIZE(omap16xx_mcbsp_res[1])
  348. #define OMAP16XX_MCBSP_COUNT ARRAY_SIZE(omap16xx_mcbsp_res)
  349. #else
  350. #define omap16xx_mcbsp_res_0 NULL
  351. #define omap16xx_mcbsp_pdata NULL
  352. #define OMAP16XX_MCBSP_RES_SZ 0
  353. #define OMAP16XX_MCBSP_COUNT 0
  354. #endif
  355. static int __init omap1_mcbsp_init(void)
  356. {
  357. if (!cpu_class_is_omap1())
  358. return -ENODEV;
  359. if (cpu_is_omap7xx())
  360. omap_mcbsp_count = OMAP7XX_MCBSP_COUNT;
  361. else if (cpu_is_omap15xx())
  362. omap_mcbsp_count = OMAP15XX_MCBSP_COUNT;
  363. else if (cpu_is_omap16xx())
  364. omap_mcbsp_count = OMAP16XX_MCBSP_COUNT;
  365. mcbsp_ptr = kzalloc(omap_mcbsp_count * sizeof(struct omap_mcbsp *),
  366. GFP_KERNEL);
  367. if (!mcbsp_ptr)
  368. return -ENOMEM;
  369. if (cpu_is_omap7xx())
  370. omap_mcbsp_register_board_cfg(omap7xx_mcbsp_res_0,
  371. OMAP7XX_MCBSP_RES_SZ,
  372. omap7xx_mcbsp_pdata,
  373. OMAP7XX_MCBSP_COUNT);
  374. if (cpu_is_omap15xx())
  375. omap_mcbsp_register_board_cfg(omap15xx_mcbsp_res_0,
  376. OMAP15XX_MCBSP_RES_SZ,
  377. omap15xx_mcbsp_pdata,
  378. OMAP15XX_MCBSP_COUNT);
  379. if (cpu_is_omap16xx())
  380. omap_mcbsp_register_board_cfg(omap16xx_mcbsp_res_0,
  381. OMAP16XX_MCBSP_RES_SZ,
  382. omap16xx_mcbsp_pdata,
  383. OMAP16XX_MCBSP_COUNT);
  384. return omap_mcbsp_init();
  385. }
  386. arch_initcall(omap1_mcbsp_init);