mcbsp.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044
  1. /*
  2. * linux/arch/arm/plat-omap/mcbsp.c
  3. *
  4. * Copyright (C) 2004 Nokia Corporation
  5. * Author: Samuel Ortiz <samuel.ortiz@nokia.com>
  6. *
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License version 2 as
  10. * published by the Free Software Foundation.
  11. *
  12. * Multichannel mode not supported.
  13. */
  14. #include <linux/module.h>
  15. #include <linux/init.h>
  16. #include <linux/device.h>
  17. #include <linux/wait.h>
  18. #include <linux/completion.h>
  19. #include <linux/interrupt.h>
  20. #include <linux/err.h>
  21. #include <linux/clk.h>
  22. #include <linux/delay.h>
  23. #include <asm/io.h>
  24. #include <asm/irq.h>
  25. #include <asm/arch/dma.h>
  26. #include <asm/arch/mux.h>
  27. #include <asm/arch/irqs.h>
  28. #include <asm/arch/dsp_common.h>
  29. #include <asm/arch/mcbsp.h>
  30. #ifdef CONFIG_MCBSP_DEBUG
  31. #define DBG(x...) printk(x)
  32. #else
  33. #define DBG(x...) do { } while (0)
  34. #endif
  35. struct omap_mcbsp {
  36. u32 io_base;
  37. u8 id;
  38. u8 free;
  39. omap_mcbsp_word_length rx_word_length;
  40. omap_mcbsp_word_length tx_word_length;
  41. omap_mcbsp_io_type_t io_type; /* IRQ or poll */
  42. /* IRQ based TX/RX */
  43. int rx_irq;
  44. int tx_irq;
  45. /* DMA stuff */
  46. u8 dma_rx_sync;
  47. short dma_rx_lch;
  48. u8 dma_tx_sync;
  49. short dma_tx_lch;
  50. /* Completion queues */
  51. struct completion tx_irq_completion;
  52. struct completion rx_irq_completion;
  53. struct completion tx_dma_completion;
  54. struct completion rx_dma_completion;
  55. spinlock_t lock;
  56. };
  57. static struct omap_mcbsp mcbsp[OMAP_MAX_MCBSP_COUNT];
  58. #ifdef CONFIG_ARCH_OMAP1
  59. static struct clk *mcbsp_dsp_ck = 0;
  60. static struct clk *mcbsp_api_ck = 0;
  61. static struct clk *mcbsp_dspxor_ck = 0;
  62. #endif
  63. #ifdef CONFIG_ARCH_OMAP2
  64. static struct clk *mcbsp1_ick = 0;
  65. static struct clk *mcbsp1_fck = 0;
  66. static struct clk *mcbsp2_ick = 0;
  67. static struct clk *mcbsp2_fck = 0;
  68. #endif
  69. static void omap_mcbsp_dump_reg(u8 id)
  70. {
  71. DBG("**** MCBSP%d regs ****\n", mcbsp[id].id);
  72. DBG("DRR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DRR2));
  73. DBG("DRR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DRR1));
  74. DBG("DXR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DXR2));
  75. DBG("DXR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DXR1));
  76. DBG("SPCR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR2));
  77. DBG("SPCR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR1));
  78. DBG("RCR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, RCR2));
  79. DBG("RCR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, RCR1));
  80. DBG("XCR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, XCR2));
  81. DBG("XCR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, XCR1));
  82. DBG("SRGR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR2));
  83. DBG("SRGR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR1));
  84. DBG("PCR0: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, PCR0));
  85. DBG("***********************\n");
  86. }
  87. static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id)
  88. {
  89. struct omap_mcbsp *mcbsp_tx = dev_id;
  90. DBG("TX IRQ callback : 0x%x\n",
  91. OMAP_MCBSP_READ(mcbsp_tx->io_base, SPCR2));
  92. complete(&mcbsp_tx->tx_irq_completion);
  93. return IRQ_HANDLED;
  94. }
  95. static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id)
  96. {
  97. struct omap_mcbsp *mcbsp_rx = dev_id;
  98. DBG("RX IRQ callback : 0x%x\n",
  99. OMAP_MCBSP_READ(mcbsp_rx->io_base, SPCR2));
  100. complete(&mcbsp_rx->rx_irq_completion);
  101. return IRQ_HANDLED;
  102. }
  103. static void omap_mcbsp_tx_dma_callback(int lch, u16 ch_status, void *data)
  104. {
  105. struct omap_mcbsp *mcbsp_dma_tx = data;
  106. DBG("TX DMA callback : 0x%x\n",
  107. OMAP_MCBSP_READ(mcbsp_dma_tx->io_base, SPCR2));
  108. /* We can free the channels */
  109. omap_free_dma(mcbsp_dma_tx->dma_tx_lch);
  110. mcbsp_dma_tx->dma_tx_lch = -1;
  111. complete(&mcbsp_dma_tx->tx_dma_completion);
  112. }
  113. static void omap_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data)
  114. {
  115. struct omap_mcbsp *mcbsp_dma_rx = data;
  116. DBG("RX DMA callback : 0x%x\n",
  117. OMAP_MCBSP_READ(mcbsp_dma_rx->io_base, SPCR2));
  118. /* We can free the channels */
  119. omap_free_dma(mcbsp_dma_rx->dma_rx_lch);
  120. mcbsp_dma_rx->dma_rx_lch = -1;
  121. complete(&mcbsp_dma_rx->rx_dma_completion);
  122. }
  123. /*
  124. * omap_mcbsp_config simply write a config to the
  125. * appropriate McBSP.
  126. * You either call this function or set the McBSP registers
  127. * by yourself before calling omap_mcbsp_start().
  128. */
  129. void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config)
  130. {
  131. u32 io_base = mcbsp[id].io_base;
  132. DBG("OMAP-McBSP: McBSP%d io_base: 0x%8x\n", id+1, io_base);
  133. /* We write the given config */
  134. OMAP_MCBSP_WRITE(io_base, SPCR2, config->spcr2);
  135. OMAP_MCBSP_WRITE(io_base, SPCR1, config->spcr1);
  136. OMAP_MCBSP_WRITE(io_base, RCR2, config->rcr2);
  137. OMAP_MCBSP_WRITE(io_base, RCR1, config->rcr1);
  138. OMAP_MCBSP_WRITE(io_base, XCR2, config->xcr2);
  139. OMAP_MCBSP_WRITE(io_base, XCR1, config->xcr1);
  140. OMAP_MCBSP_WRITE(io_base, SRGR2, config->srgr2);
  141. OMAP_MCBSP_WRITE(io_base, SRGR1, config->srgr1);
  142. OMAP_MCBSP_WRITE(io_base, MCR2, config->mcr2);
  143. OMAP_MCBSP_WRITE(io_base, MCR1, config->mcr1);
  144. OMAP_MCBSP_WRITE(io_base, PCR0, config->pcr0);
  145. }
  146. static int omap_mcbsp_check(unsigned int id)
  147. {
  148. if (cpu_is_omap730()) {
  149. if (id > OMAP_MAX_MCBSP_COUNT - 1) {
  150. printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1);
  151. return -1;
  152. }
  153. return 0;
  154. }
  155. if (cpu_is_omap15xx() || cpu_is_omap16xx() || cpu_is_omap24xx()) {
  156. if (id > OMAP_MAX_MCBSP_COUNT) {
  157. printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1);
  158. return -1;
  159. }
  160. return 0;
  161. }
  162. return -1;
  163. }
  164. #ifdef CONFIG_ARCH_OMAP1
  165. static void omap_mcbsp_dsp_request(void)
  166. {
  167. if (cpu_is_omap15xx() || cpu_is_omap16xx()) {
  168. int ret;
  169. ret = omap_dsp_request_mem();
  170. if (ret < 0) {
  171. printk(KERN_ERR "Could not get dsp memory: %i\n", ret);
  172. return;
  173. }
  174. clk_enable(mcbsp_dsp_ck);
  175. clk_enable(mcbsp_api_ck);
  176. /* enable 12MHz clock to mcbsp 1 & 3 */
  177. clk_enable(mcbsp_dspxor_ck);
  178. /*
  179. * DSP external peripheral reset
  180. * FIXME: This should be moved to dsp code
  181. */
  182. __raw_writew(__raw_readw(DSP_RSTCT2) | 1 | 1 << 1,
  183. DSP_RSTCT2);
  184. }
  185. }
  186. static void omap_mcbsp_dsp_free(void)
  187. {
  188. if (cpu_is_omap15xx() || cpu_is_omap16xx()) {
  189. omap_dsp_release_mem();
  190. clk_disable(mcbsp_dspxor_ck);
  191. clk_disable(mcbsp_dsp_ck);
  192. clk_disable(mcbsp_api_ck);
  193. }
  194. }
  195. #endif
  196. #ifdef CONFIG_ARCH_OMAP2
  197. static void omap2_mcbsp2_mux_setup(void)
  198. {
  199. if (cpu_is_omap2420()) {
  200. omap_cfg_reg(Y15_24XX_MCBSP2_CLKX);
  201. omap_cfg_reg(R14_24XX_MCBSP2_FSX);
  202. omap_cfg_reg(W15_24XX_MCBSP2_DR);
  203. omap_cfg_reg(V15_24XX_MCBSP2_DX);
  204. omap_cfg_reg(V14_24XX_GPIO117);
  205. }
  206. /*
  207. * Need to add MUX settings for OMAP 2430 SDP
  208. */
  209. }
  210. #endif
  211. /*
  212. * We can choose between IRQ based or polled IO.
  213. * This needs to be called before omap_mcbsp_request().
  214. */
  215. int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type)
  216. {
  217. if (omap_mcbsp_check(id) < 0)
  218. return -EINVAL;
  219. spin_lock(&mcbsp[id].lock);
  220. if (!mcbsp[id].free) {
  221. printk (KERN_ERR "OMAP-McBSP: McBSP%d is currently in use\n", id + 1);
  222. spin_unlock(&mcbsp[id].lock);
  223. return -EINVAL;
  224. }
  225. mcbsp[id].io_type = io_type;
  226. spin_unlock(&mcbsp[id].lock);
  227. return 0;
  228. }
  229. int omap_mcbsp_request(unsigned int id)
  230. {
  231. int err;
  232. if (omap_mcbsp_check(id) < 0)
  233. return -EINVAL;
  234. #ifdef CONFIG_ARCH_OMAP1
  235. /*
  236. * On 1510, 1610 and 1710, McBSP1 and McBSP3
  237. * are DSP public peripherals.
  238. */
  239. if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3)
  240. omap_mcbsp_dsp_request();
  241. #endif
  242. #ifdef CONFIG_ARCH_OMAP2
  243. if (cpu_is_omap24xx()) {
  244. if (id == OMAP_MCBSP1) {
  245. clk_enable(mcbsp1_ick);
  246. clk_enable(mcbsp1_fck);
  247. } else {
  248. clk_enable(mcbsp2_ick);
  249. clk_enable(mcbsp2_fck);
  250. }
  251. }
  252. #endif
  253. spin_lock(&mcbsp[id].lock);
  254. if (!mcbsp[id].free) {
  255. printk (KERN_ERR "OMAP-McBSP: McBSP%d is currently in use\n", id + 1);
  256. spin_unlock(&mcbsp[id].lock);
  257. return -1;
  258. }
  259. mcbsp[id].free = 0;
  260. spin_unlock(&mcbsp[id].lock);
  261. if (mcbsp[id].io_type == OMAP_MCBSP_IRQ_IO) {
  262. /* We need to get IRQs here */
  263. err = request_irq(mcbsp[id].tx_irq, omap_mcbsp_tx_irq_handler, 0,
  264. "McBSP",
  265. (void *) (&mcbsp[id]));
  266. if (err != 0) {
  267. printk(KERN_ERR "OMAP-McBSP: Unable to request TX IRQ %d for McBSP%d\n",
  268. mcbsp[id].tx_irq, mcbsp[id].id);
  269. return err;
  270. }
  271. init_completion(&(mcbsp[id].tx_irq_completion));
  272. err = request_irq(mcbsp[id].rx_irq, omap_mcbsp_rx_irq_handler, 0,
  273. "McBSP",
  274. (void *) (&mcbsp[id]));
  275. if (err != 0) {
  276. printk(KERN_ERR "OMAP-McBSP: Unable to request RX IRQ %d for McBSP%d\n",
  277. mcbsp[id].rx_irq, mcbsp[id].id);
  278. free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id]));
  279. return err;
  280. }
  281. init_completion(&(mcbsp[id].rx_irq_completion));
  282. }
  283. return 0;
  284. }
  285. void omap_mcbsp_free(unsigned int id)
  286. {
  287. if (omap_mcbsp_check(id) < 0)
  288. return;
  289. #ifdef CONFIG_ARCH_OMAP1
  290. if (cpu_class_is_omap1()) {
  291. if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3)
  292. omap_mcbsp_dsp_free();
  293. }
  294. #endif
  295. #ifdef CONFIG_ARCH_OMAP2
  296. if (cpu_is_omap24xx()) {
  297. if (id == OMAP_MCBSP1) {
  298. clk_disable(mcbsp1_ick);
  299. clk_disable(mcbsp1_fck);
  300. } else {
  301. clk_disable(mcbsp2_ick);
  302. clk_disable(mcbsp2_fck);
  303. }
  304. }
  305. #endif
  306. spin_lock(&mcbsp[id].lock);
  307. if (mcbsp[id].free) {
  308. printk (KERN_ERR "OMAP-McBSP: McBSP%d was not reserved\n", id + 1);
  309. spin_unlock(&mcbsp[id].lock);
  310. return;
  311. }
  312. mcbsp[id].free = 1;
  313. spin_unlock(&mcbsp[id].lock);
  314. if (mcbsp[id].io_type == OMAP_MCBSP_IRQ_IO) {
  315. /* Free IRQs */
  316. free_irq(mcbsp[id].rx_irq, (void *) (&mcbsp[id]));
  317. free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id]));
  318. }
  319. }
  320. /*
  321. * Here we start the McBSP, by enabling the sample
  322. * generator, both transmitter and receivers,
  323. * and the frame sync.
  324. */
  325. void omap_mcbsp_start(unsigned int id)
  326. {
  327. u32 io_base;
  328. u16 w;
  329. if (omap_mcbsp_check(id) < 0)
  330. return;
  331. io_base = mcbsp[id].io_base;
  332. mcbsp[id].rx_word_length = ((OMAP_MCBSP_READ(io_base, RCR1) >> 5) & 0x7);
  333. mcbsp[id].tx_word_length = ((OMAP_MCBSP_READ(io_base, XCR1) >> 5) & 0x7);
  334. /* Start the sample generator */
  335. w = OMAP_MCBSP_READ(io_base, SPCR2);
  336. OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 6));
  337. /* Enable transmitter and receiver */
  338. w = OMAP_MCBSP_READ(io_base, SPCR2);
  339. OMAP_MCBSP_WRITE(io_base, SPCR2, w | 1);
  340. w = OMAP_MCBSP_READ(io_base, SPCR1);
  341. OMAP_MCBSP_WRITE(io_base, SPCR1, w | 1);
  342. udelay(100);
  343. /* Start frame sync */
  344. w = OMAP_MCBSP_READ(io_base, SPCR2);
  345. OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 7));
  346. /* Dump McBSP Regs */
  347. omap_mcbsp_dump_reg(id);
  348. }
  349. void omap_mcbsp_stop(unsigned int id)
  350. {
  351. u32 io_base;
  352. u16 w;
  353. if (omap_mcbsp_check(id) < 0)
  354. return;
  355. io_base = mcbsp[id].io_base;
  356. /* Reset transmitter */
  357. w = OMAP_MCBSP_READ(io_base, SPCR2);
  358. OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1));
  359. /* Reset receiver */
  360. w = OMAP_MCBSP_READ(io_base, SPCR1);
  361. OMAP_MCBSP_WRITE(io_base, SPCR1, w & ~(1));
  362. /* Reset the sample rate generator */
  363. w = OMAP_MCBSP_READ(io_base, SPCR2);
  364. OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1 << 6));
  365. }
  366. /* polled mcbsp i/o operations */
  367. int omap_mcbsp_pollwrite(unsigned int id, u16 buf)
  368. {
  369. u32 base = mcbsp[id].io_base;
  370. writew(buf, base + OMAP_MCBSP_REG_DXR1);
  371. /* if frame sync error - clear the error */
  372. if (readw(base + OMAP_MCBSP_REG_SPCR2) & XSYNC_ERR) {
  373. /* clear error */
  374. writew(readw(base + OMAP_MCBSP_REG_SPCR2) & (~XSYNC_ERR),
  375. base + OMAP_MCBSP_REG_SPCR2);
  376. /* resend */
  377. return -1;
  378. } else {
  379. /* wait for transmit confirmation */
  380. int attemps = 0;
  381. while (!(readw(base + OMAP_MCBSP_REG_SPCR2) & XRDY)) {
  382. if (attemps++ > 1000) {
  383. writew(readw(base + OMAP_MCBSP_REG_SPCR2) &
  384. (~XRST),
  385. base + OMAP_MCBSP_REG_SPCR2);
  386. udelay(10);
  387. writew(readw(base + OMAP_MCBSP_REG_SPCR2) |
  388. (XRST),
  389. base + OMAP_MCBSP_REG_SPCR2);
  390. udelay(10);
  391. printk(KERN_ERR
  392. " Could not write to McBSP Register\n");
  393. return -2;
  394. }
  395. }
  396. }
  397. return 0;
  398. }
  399. int omap_mcbsp_pollread(unsigned int id, u16 * buf)
  400. {
  401. u32 base = mcbsp[id].io_base;
  402. /* if frame sync error - clear the error */
  403. if (readw(base + OMAP_MCBSP_REG_SPCR1) & RSYNC_ERR) {
  404. /* clear error */
  405. writew(readw(base + OMAP_MCBSP_REG_SPCR1) & (~RSYNC_ERR),
  406. base + OMAP_MCBSP_REG_SPCR1);
  407. /* resend */
  408. return -1;
  409. } else {
  410. /* wait for recieve confirmation */
  411. int attemps = 0;
  412. while (!(readw(base + OMAP_MCBSP_REG_SPCR1) & RRDY)) {
  413. if (attemps++ > 1000) {
  414. writew(readw(base + OMAP_MCBSP_REG_SPCR1) &
  415. (~RRST),
  416. base + OMAP_MCBSP_REG_SPCR1);
  417. udelay(10);
  418. writew(readw(base + OMAP_MCBSP_REG_SPCR1) |
  419. (RRST),
  420. base + OMAP_MCBSP_REG_SPCR1);
  421. udelay(10);
  422. printk(KERN_ERR
  423. " Could not read from McBSP Register\n");
  424. return -2;
  425. }
  426. }
  427. }
  428. *buf = readw(base + OMAP_MCBSP_REG_DRR1);
  429. return 0;
  430. }
  431. /*
  432. * IRQ based word transmission.
  433. */
  434. void omap_mcbsp_xmit_word(unsigned int id, u32 word)
  435. {
  436. u32 io_base;
  437. omap_mcbsp_word_length word_length = mcbsp[id].tx_word_length;
  438. if (omap_mcbsp_check(id) < 0)
  439. return;
  440. io_base = mcbsp[id].io_base;
  441. wait_for_completion(&(mcbsp[id].tx_irq_completion));
  442. if (word_length > OMAP_MCBSP_WORD_16)
  443. OMAP_MCBSP_WRITE(io_base, DXR2, word >> 16);
  444. OMAP_MCBSP_WRITE(io_base, DXR1, word & 0xffff);
  445. }
  446. u32 omap_mcbsp_recv_word(unsigned int id)
  447. {
  448. u32 io_base;
  449. u16 word_lsb, word_msb = 0;
  450. omap_mcbsp_word_length word_length = mcbsp[id].rx_word_length;
  451. if (omap_mcbsp_check(id) < 0)
  452. return -EINVAL;
  453. io_base = mcbsp[id].io_base;
  454. wait_for_completion(&(mcbsp[id].rx_irq_completion));
  455. if (word_length > OMAP_MCBSP_WORD_16)
  456. word_msb = OMAP_MCBSP_READ(io_base, DRR2);
  457. word_lsb = OMAP_MCBSP_READ(io_base, DRR1);
  458. return (word_lsb | (word_msb << 16));
  459. }
  460. int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word)
  461. {
  462. u32 io_base = mcbsp[id].io_base;
  463. omap_mcbsp_word_length tx_word_length = mcbsp[id].tx_word_length;
  464. omap_mcbsp_word_length rx_word_length = mcbsp[id].rx_word_length;
  465. u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0;
  466. if (tx_word_length != rx_word_length)
  467. return -EINVAL;
  468. /* First we wait for the transmitter to be ready */
  469. spcr2 = OMAP_MCBSP_READ(io_base, SPCR2);
  470. while (!(spcr2 & XRDY)) {
  471. spcr2 = OMAP_MCBSP_READ(io_base, SPCR2);
  472. if (attempts++ > 1000) {
  473. /* We must reset the transmitter */
  474. OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 & (~XRST));
  475. udelay(10);
  476. OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST);
  477. udelay(10);
  478. printk("McBSP transmitter not ready\n");
  479. return -EAGAIN;
  480. }
  481. }
  482. /* Now we can push the data */
  483. if (tx_word_length > OMAP_MCBSP_WORD_16)
  484. OMAP_MCBSP_WRITE(io_base, DXR2, word >> 16);
  485. OMAP_MCBSP_WRITE(io_base, DXR1, word & 0xffff);
  486. /* We wait for the receiver to be ready */
  487. spcr1 = OMAP_MCBSP_READ(io_base, SPCR1);
  488. while (!(spcr1 & RRDY)) {
  489. spcr1 = OMAP_MCBSP_READ(io_base, SPCR1);
  490. if (attempts++ > 1000) {
  491. /* We must reset the receiver */
  492. OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 & (~RRST));
  493. udelay(10);
  494. OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST);
  495. udelay(10);
  496. printk("McBSP receiver not ready\n");
  497. return -EAGAIN;
  498. }
  499. }
  500. /* Receiver is ready, let's read the dummy data */
  501. if (rx_word_length > OMAP_MCBSP_WORD_16)
  502. word_msb = OMAP_MCBSP_READ(io_base, DRR2);
  503. word_lsb = OMAP_MCBSP_READ(io_base, DRR1);
  504. return 0;
  505. }
  506. int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 * word)
  507. {
  508. u32 io_base = mcbsp[id].io_base, clock_word = 0;
  509. omap_mcbsp_word_length tx_word_length = mcbsp[id].tx_word_length;
  510. omap_mcbsp_word_length rx_word_length = mcbsp[id].rx_word_length;
  511. u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0;
  512. if (tx_word_length != rx_word_length)
  513. return -EINVAL;
  514. /* First we wait for the transmitter to be ready */
  515. spcr2 = OMAP_MCBSP_READ(io_base, SPCR2);
  516. while (!(spcr2 & XRDY)) {
  517. spcr2 = OMAP_MCBSP_READ(io_base, SPCR2);
  518. if (attempts++ > 1000) {
  519. /* We must reset the transmitter */
  520. OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 & (~XRST));
  521. udelay(10);
  522. OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST);
  523. udelay(10);
  524. printk("McBSP transmitter not ready\n");
  525. return -EAGAIN;
  526. }
  527. }
  528. /* We first need to enable the bus clock */
  529. if (tx_word_length > OMAP_MCBSP_WORD_16)
  530. OMAP_MCBSP_WRITE(io_base, DXR2, clock_word >> 16);
  531. OMAP_MCBSP_WRITE(io_base, DXR1, clock_word & 0xffff);
  532. /* We wait for the receiver to be ready */
  533. spcr1 = OMAP_MCBSP_READ(io_base, SPCR1);
  534. while (!(spcr1 & RRDY)) {
  535. spcr1 = OMAP_MCBSP_READ(io_base, SPCR1);
  536. if (attempts++ > 1000) {
  537. /* We must reset the receiver */
  538. OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 & (~RRST));
  539. udelay(10);
  540. OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST);
  541. udelay(10);
  542. printk("McBSP receiver not ready\n");
  543. return -EAGAIN;
  544. }
  545. }
  546. /* Receiver is ready, there is something for us */
  547. if (rx_word_length > OMAP_MCBSP_WORD_16)
  548. word_msb = OMAP_MCBSP_READ(io_base, DRR2);
  549. word_lsb = OMAP_MCBSP_READ(io_base, DRR1);
  550. word[0] = (word_lsb | (word_msb << 16));
  551. return 0;
  552. }
  553. /*
  554. * Simple DMA based buffer rx/tx routines.
  555. * Nothing fancy, just a single buffer tx/rx through DMA.
  556. * The DMA resources are released once the transfer is done.
  557. * For anything fancier, you should use your own customized DMA
  558. * routines and callbacks.
  559. */
  560. int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int length)
  561. {
  562. int dma_tx_ch;
  563. int src_port = 0;
  564. int dest_port = 0;
  565. int sync_dev = 0;
  566. if (omap_mcbsp_check(id) < 0)
  567. return -EINVAL;
  568. if (omap_request_dma(mcbsp[id].dma_tx_sync, "McBSP TX", omap_mcbsp_tx_dma_callback,
  569. &mcbsp[id],
  570. &dma_tx_ch)) {
  571. printk("OMAP-McBSP: Unable to request DMA channel for McBSP%d TX. Trying IRQ based TX\n", id+1);
  572. return -EAGAIN;
  573. }
  574. mcbsp[id].dma_tx_lch = dma_tx_ch;
  575. DBG("TX DMA on channel %d\n", dma_tx_ch);
  576. init_completion(&(mcbsp[id].tx_dma_completion));
  577. if (cpu_class_is_omap1()) {
  578. src_port = OMAP_DMA_PORT_TIPB;
  579. dest_port = OMAP_DMA_PORT_EMIFF;
  580. }
  581. if (cpu_is_omap24xx())
  582. sync_dev = mcbsp[id].dma_tx_sync;
  583. omap_set_dma_transfer_params(mcbsp[id].dma_tx_lch,
  584. OMAP_DMA_DATA_TYPE_S16,
  585. length >> 1, 1,
  586. OMAP_DMA_SYNC_ELEMENT,
  587. sync_dev, 0);
  588. omap_set_dma_dest_params(mcbsp[id].dma_tx_lch,
  589. src_port,
  590. OMAP_DMA_AMODE_CONSTANT,
  591. mcbsp[id].io_base + OMAP_MCBSP_REG_DXR1,
  592. 0, 0);
  593. omap_set_dma_src_params(mcbsp[id].dma_tx_lch,
  594. dest_port,
  595. OMAP_DMA_AMODE_POST_INC,
  596. buffer,
  597. 0, 0);
  598. omap_start_dma(mcbsp[id].dma_tx_lch);
  599. wait_for_completion(&(mcbsp[id].tx_dma_completion));
  600. return 0;
  601. }
  602. int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int length)
  603. {
  604. int dma_rx_ch;
  605. int src_port = 0;
  606. int dest_port = 0;
  607. int sync_dev = 0;
  608. if (omap_mcbsp_check(id) < 0)
  609. return -EINVAL;
  610. if (omap_request_dma(mcbsp[id].dma_rx_sync, "McBSP RX", omap_mcbsp_rx_dma_callback,
  611. &mcbsp[id],
  612. &dma_rx_ch)) {
  613. printk("Unable to request DMA channel for McBSP%d RX. Trying IRQ based RX\n", id+1);
  614. return -EAGAIN;
  615. }
  616. mcbsp[id].dma_rx_lch = dma_rx_ch;
  617. DBG("RX DMA on channel %d\n", dma_rx_ch);
  618. init_completion(&(mcbsp[id].rx_dma_completion));
  619. if (cpu_class_is_omap1()) {
  620. src_port = OMAP_DMA_PORT_TIPB;
  621. dest_port = OMAP_DMA_PORT_EMIFF;
  622. }
  623. if (cpu_is_omap24xx())
  624. sync_dev = mcbsp[id].dma_rx_sync;
  625. omap_set_dma_transfer_params(mcbsp[id].dma_rx_lch,
  626. OMAP_DMA_DATA_TYPE_S16,
  627. length >> 1, 1,
  628. OMAP_DMA_SYNC_ELEMENT,
  629. sync_dev, 0);
  630. omap_set_dma_src_params(mcbsp[id].dma_rx_lch,
  631. src_port,
  632. OMAP_DMA_AMODE_CONSTANT,
  633. mcbsp[id].io_base + OMAP_MCBSP_REG_DRR1,
  634. 0, 0);
  635. omap_set_dma_dest_params(mcbsp[id].dma_rx_lch,
  636. dest_port,
  637. OMAP_DMA_AMODE_POST_INC,
  638. buffer,
  639. 0, 0);
  640. omap_start_dma(mcbsp[id].dma_rx_lch);
  641. wait_for_completion(&(mcbsp[id].rx_dma_completion));
  642. return 0;
  643. }
  644. /*
  645. * SPI wrapper.
  646. * Since SPI setup is much simpler than the generic McBSP one,
  647. * this wrapper just need an omap_mcbsp_spi_cfg structure as an input.
  648. * Once this is done, you can call omap_mcbsp_start().
  649. */
  650. void omap_mcbsp_set_spi_mode(unsigned int id, const struct omap_mcbsp_spi_cfg * spi_cfg)
  651. {
  652. struct omap_mcbsp_reg_cfg mcbsp_cfg;
  653. if (omap_mcbsp_check(id) < 0)
  654. return;
  655. memset(&mcbsp_cfg, 0, sizeof(struct omap_mcbsp_reg_cfg));
  656. /* SPI has only one frame */
  657. mcbsp_cfg.rcr1 |= (RWDLEN1(spi_cfg->word_length) | RFRLEN1(0));
  658. mcbsp_cfg.xcr1 |= (XWDLEN1(spi_cfg->word_length) | XFRLEN1(0));
  659. /* Clock stop mode */
  660. if (spi_cfg->clk_stp_mode == OMAP_MCBSP_CLK_STP_MODE_NO_DELAY)
  661. mcbsp_cfg.spcr1 |= (1 << 12);
  662. else
  663. mcbsp_cfg.spcr1 |= (3 << 11);
  664. /* Set clock parities */
  665. if (spi_cfg->rx_clock_polarity == OMAP_MCBSP_CLK_RISING)
  666. mcbsp_cfg.pcr0 |= CLKRP;
  667. else
  668. mcbsp_cfg.pcr0 &= ~CLKRP;
  669. if (spi_cfg->tx_clock_polarity == OMAP_MCBSP_CLK_RISING)
  670. mcbsp_cfg.pcr0 &= ~CLKXP;
  671. else
  672. mcbsp_cfg.pcr0 |= CLKXP;
  673. /* Set SCLKME to 0 and CLKSM to 1 */
  674. mcbsp_cfg.pcr0 &= ~SCLKME;
  675. mcbsp_cfg.srgr2 |= CLKSM;
  676. /* Set FSXP */
  677. if (spi_cfg->fsx_polarity == OMAP_MCBSP_FS_ACTIVE_HIGH)
  678. mcbsp_cfg.pcr0 &= ~FSXP;
  679. else
  680. mcbsp_cfg.pcr0 |= FSXP;
  681. if (spi_cfg->spi_mode == OMAP_MCBSP_SPI_MASTER) {
  682. mcbsp_cfg.pcr0 |= CLKXM;
  683. mcbsp_cfg.srgr1 |= CLKGDV(spi_cfg->clk_div -1);
  684. mcbsp_cfg.pcr0 |= FSXM;
  685. mcbsp_cfg.srgr2 &= ~FSGM;
  686. mcbsp_cfg.xcr2 |= XDATDLY(1);
  687. mcbsp_cfg.rcr2 |= RDATDLY(1);
  688. }
  689. else {
  690. mcbsp_cfg.pcr0 &= ~CLKXM;
  691. mcbsp_cfg.srgr1 |= CLKGDV(1);
  692. mcbsp_cfg.pcr0 &= ~FSXM;
  693. mcbsp_cfg.xcr2 &= ~XDATDLY(3);
  694. mcbsp_cfg.rcr2 &= ~RDATDLY(3);
  695. }
  696. mcbsp_cfg.xcr2 &= ~XPHASE;
  697. mcbsp_cfg.rcr2 &= ~RPHASE;
  698. omap_mcbsp_config(id, &mcbsp_cfg);
  699. }
  700. /*
  701. * McBSP1 and McBSP3 are directly mapped on 1610 and 1510.
  702. * 730 has only 2 McBSP, and both of them are MPU peripherals.
  703. */
  704. struct omap_mcbsp_info {
  705. u32 virt_base;
  706. u8 dma_rx_sync, dma_tx_sync;
  707. u16 rx_irq, tx_irq;
  708. };
  709. #ifdef CONFIG_ARCH_OMAP730
  710. static const struct omap_mcbsp_info mcbsp_730[] = {
  711. [0] = { .virt_base = io_p2v(OMAP730_MCBSP1_BASE),
  712. .dma_rx_sync = OMAP_DMA_MCBSP1_RX,
  713. .dma_tx_sync = OMAP_DMA_MCBSP1_TX,
  714. .rx_irq = INT_730_McBSP1RX,
  715. .tx_irq = INT_730_McBSP1TX },
  716. [1] = { .virt_base = io_p2v(OMAP730_MCBSP2_BASE),
  717. .dma_rx_sync = OMAP_DMA_MCBSP3_RX,
  718. .dma_tx_sync = OMAP_DMA_MCBSP3_TX,
  719. .rx_irq = INT_730_McBSP2RX,
  720. .tx_irq = INT_730_McBSP2TX },
  721. };
  722. #endif
  723. #ifdef CONFIG_ARCH_OMAP15XX
  724. static const struct omap_mcbsp_info mcbsp_1510[] = {
  725. [0] = { .virt_base = OMAP1510_MCBSP1_BASE,
  726. .dma_rx_sync = OMAP_DMA_MCBSP1_RX,
  727. .dma_tx_sync = OMAP_DMA_MCBSP1_TX,
  728. .rx_irq = INT_McBSP1RX,
  729. .tx_irq = INT_McBSP1TX },
  730. [1] = { .virt_base = io_p2v(OMAP1510_MCBSP2_BASE),
  731. .dma_rx_sync = OMAP_DMA_MCBSP2_RX,
  732. .dma_tx_sync = OMAP_DMA_MCBSP2_TX,
  733. .rx_irq = INT_1510_SPI_RX,
  734. .tx_irq = INT_1510_SPI_TX },
  735. [2] = { .virt_base = OMAP1510_MCBSP3_BASE,
  736. .dma_rx_sync = OMAP_DMA_MCBSP3_RX,
  737. .dma_tx_sync = OMAP_DMA_MCBSP3_TX,
  738. .rx_irq = INT_McBSP3RX,
  739. .tx_irq = INT_McBSP3TX },
  740. };
  741. #endif
  742. #if defined(CONFIG_ARCH_OMAP16XX)
  743. static const struct omap_mcbsp_info mcbsp_1610[] = {
  744. [0] = { .virt_base = OMAP1610_MCBSP1_BASE,
  745. .dma_rx_sync = OMAP_DMA_MCBSP1_RX,
  746. .dma_tx_sync = OMAP_DMA_MCBSP1_TX,
  747. .rx_irq = INT_McBSP1RX,
  748. .tx_irq = INT_McBSP1TX },
  749. [1] = { .virt_base = io_p2v(OMAP1610_MCBSP2_BASE),
  750. .dma_rx_sync = OMAP_DMA_MCBSP2_RX,
  751. .dma_tx_sync = OMAP_DMA_MCBSP2_TX,
  752. .rx_irq = INT_1610_McBSP2_RX,
  753. .tx_irq = INT_1610_McBSP2_TX },
  754. [2] = { .virt_base = OMAP1610_MCBSP3_BASE,
  755. .dma_rx_sync = OMAP_DMA_MCBSP3_RX,
  756. .dma_tx_sync = OMAP_DMA_MCBSP3_TX,
  757. .rx_irq = INT_McBSP3RX,
  758. .tx_irq = INT_McBSP3TX },
  759. };
  760. #endif
  761. #if defined(CONFIG_ARCH_OMAP24XX)
  762. static const struct omap_mcbsp_info mcbsp_24xx[] = {
  763. [0] = { .virt_base = IO_ADDRESS(OMAP24XX_MCBSP1_BASE),
  764. .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX,
  765. .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX,
  766. .rx_irq = INT_24XX_MCBSP1_IRQ_RX,
  767. .tx_irq = INT_24XX_MCBSP1_IRQ_TX,
  768. },
  769. [1] = { .virt_base = IO_ADDRESS(OMAP24XX_MCBSP2_BASE),
  770. .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX,
  771. .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX,
  772. .rx_irq = INT_24XX_MCBSP2_IRQ_RX,
  773. .tx_irq = INT_24XX_MCBSP2_IRQ_TX,
  774. },
  775. };
  776. #endif
  777. static int __init omap_mcbsp_init(void)
  778. {
  779. int mcbsp_count = 0, i;
  780. static const struct omap_mcbsp_info *mcbsp_info;
  781. printk("Initializing OMAP McBSP system\n");
  782. #ifdef CONFIG_ARCH_OMAP1
  783. mcbsp_dsp_ck = clk_get(0, "dsp_ck");
  784. if (IS_ERR(mcbsp_dsp_ck)) {
  785. printk(KERN_ERR "mcbsp: could not acquire dsp_ck handle.\n");
  786. return PTR_ERR(mcbsp_dsp_ck);
  787. }
  788. mcbsp_api_ck = clk_get(0, "api_ck");
  789. if (IS_ERR(mcbsp_api_ck)) {
  790. printk(KERN_ERR "mcbsp: could not acquire api_ck handle.\n");
  791. return PTR_ERR(mcbsp_api_ck);
  792. }
  793. mcbsp_dspxor_ck = clk_get(0, "dspxor_ck");
  794. if (IS_ERR(mcbsp_dspxor_ck)) {
  795. printk(KERN_ERR "mcbsp: could not acquire dspxor_ck handle.\n");
  796. return PTR_ERR(mcbsp_dspxor_ck);
  797. }
  798. #endif
  799. #ifdef CONFIG_ARCH_OMAP2
  800. mcbsp1_ick = clk_get(0, "mcbsp1_ick");
  801. if (IS_ERR(mcbsp1_ick)) {
  802. printk(KERN_ERR "mcbsp: could not acquire mcbsp1_ick handle.\n");
  803. return PTR_ERR(mcbsp1_ick);
  804. }
  805. mcbsp1_fck = clk_get(0, "mcbsp1_fck");
  806. if (IS_ERR(mcbsp1_fck)) {
  807. printk(KERN_ERR "mcbsp: could not acquire mcbsp1_fck handle.\n");
  808. return PTR_ERR(mcbsp1_fck);
  809. }
  810. mcbsp2_ick = clk_get(0, "mcbsp2_ick");
  811. if (IS_ERR(mcbsp2_ick)) {
  812. printk(KERN_ERR "mcbsp: could not acquire mcbsp2_ick handle.\n");
  813. return PTR_ERR(mcbsp2_ick);
  814. }
  815. mcbsp2_fck = clk_get(0, "mcbsp2_fck");
  816. if (IS_ERR(mcbsp2_fck)) {
  817. printk(KERN_ERR "mcbsp: could not acquire mcbsp2_fck handle.\n");
  818. return PTR_ERR(mcbsp2_fck);
  819. }
  820. #endif
  821. #ifdef CONFIG_ARCH_OMAP730
  822. if (cpu_is_omap730()) {
  823. mcbsp_info = mcbsp_730;
  824. mcbsp_count = ARRAY_SIZE(mcbsp_730);
  825. }
  826. #endif
  827. #ifdef CONFIG_ARCH_OMAP15XX
  828. if (cpu_is_omap15xx()) {
  829. mcbsp_info = mcbsp_1510;
  830. mcbsp_count = ARRAY_SIZE(mcbsp_1510);
  831. }
  832. #endif
  833. #if defined(CONFIG_ARCH_OMAP16XX)
  834. if (cpu_is_omap16xx()) {
  835. mcbsp_info = mcbsp_1610;
  836. mcbsp_count = ARRAY_SIZE(mcbsp_1610);
  837. }
  838. #endif
  839. #if defined(CONFIG_ARCH_OMAP24XX)
  840. if (cpu_is_omap24xx()) {
  841. mcbsp_info = mcbsp_24xx;
  842. mcbsp_count = ARRAY_SIZE(mcbsp_24xx);
  843. omap2_mcbsp2_mux_setup();
  844. }
  845. #endif
  846. for (i = 0; i < OMAP_MAX_MCBSP_COUNT ; i++) {
  847. if (i >= mcbsp_count) {
  848. mcbsp[i].io_base = 0;
  849. mcbsp[i].free = 0;
  850. continue;
  851. }
  852. mcbsp[i].id = i + 1;
  853. mcbsp[i].free = 1;
  854. mcbsp[i].dma_tx_lch = -1;
  855. mcbsp[i].dma_rx_lch = -1;
  856. mcbsp[i].io_base = mcbsp_info[i].virt_base;
  857. mcbsp[i].io_type = OMAP_MCBSP_IRQ_IO; /* Default I/O is IRQ based */
  858. mcbsp[i].tx_irq = mcbsp_info[i].tx_irq;
  859. mcbsp[i].rx_irq = mcbsp_info[i].rx_irq;
  860. mcbsp[i].dma_rx_sync = mcbsp_info[i].dma_rx_sync;
  861. mcbsp[i].dma_tx_sync = mcbsp_info[i].dma_tx_sync;
  862. spin_lock_init(&mcbsp[i].lock);
  863. }
  864. return 0;
  865. }
  866. arch_initcall(omap_mcbsp_init);
  867. EXPORT_SYMBOL(omap_mcbsp_config);
  868. EXPORT_SYMBOL(omap_mcbsp_request);
  869. EXPORT_SYMBOL(omap_mcbsp_set_io_type);
  870. EXPORT_SYMBOL(omap_mcbsp_free);
  871. EXPORT_SYMBOL(omap_mcbsp_start);
  872. EXPORT_SYMBOL(omap_mcbsp_stop);
  873. EXPORT_SYMBOL(omap_mcbsp_pollread);
  874. EXPORT_SYMBOL(omap_mcbsp_pollwrite);
  875. EXPORT_SYMBOL(omap_mcbsp_xmit_word);
  876. EXPORT_SYMBOL(omap_mcbsp_recv_word);
  877. EXPORT_SYMBOL(omap_mcbsp_xmit_buffer);
  878. EXPORT_SYMBOL(omap_mcbsp_recv_buffer);
  879. EXPORT_SYMBOL(omap_mcbsp_spi_master_xmit_word_poll);
  880. EXPORT_SYMBOL(omap_mcbsp_spi_master_recv_word_poll);
  881. EXPORT_SYMBOL(omap_mcbsp_set_spi_mode);