mcbsp.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896
  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/platform_device.h>
  18. #include <linux/wait.h>
  19. #include <linux/completion.h>
  20. #include <linux/interrupt.h>
  21. #include <linux/err.h>
  22. #include <linux/clk.h>
  23. #include <linux/delay.h>
  24. #include <linux/io.h>
  25. #include <mach/dma.h>
  26. #include <mach/mcbsp.h>
  27. static struct omap_mcbsp mcbsp[OMAP_MAX_MCBSP_COUNT];
  28. #define omap_mcbsp_check_valid_id(id) (mcbsp[id].pdata && \
  29. mcbsp[id].pdata->ops && \
  30. mcbsp[id].pdata->ops->check && \
  31. (mcbsp[id].pdata->ops->check(id) == 0))
  32. static void omap_mcbsp_dump_reg(u8 id)
  33. {
  34. dev_dbg(mcbsp[id].dev, "**** McBSP%d regs ****\n", mcbsp[id].id);
  35. dev_dbg(mcbsp[id].dev, "DRR2: 0x%04x\n",
  36. OMAP_MCBSP_READ(mcbsp[id].io_base, DRR2));
  37. dev_dbg(mcbsp[id].dev, "DRR1: 0x%04x\n",
  38. OMAP_MCBSP_READ(mcbsp[id].io_base, DRR1));
  39. dev_dbg(mcbsp[id].dev, "DXR2: 0x%04x\n",
  40. OMAP_MCBSP_READ(mcbsp[id].io_base, DXR2));
  41. dev_dbg(mcbsp[id].dev, "DXR1: 0x%04x\n",
  42. OMAP_MCBSP_READ(mcbsp[id].io_base, DXR1));
  43. dev_dbg(mcbsp[id].dev, "SPCR2: 0x%04x\n",
  44. OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR2));
  45. dev_dbg(mcbsp[id].dev, "SPCR1: 0x%04x\n",
  46. OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR1));
  47. dev_dbg(mcbsp[id].dev, "RCR2: 0x%04x\n",
  48. OMAP_MCBSP_READ(mcbsp[id].io_base, RCR2));
  49. dev_dbg(mcbsp[id].dev, "RCR1: 0x%04x\n",
  50. OMAP_MCBSP_READ(mcbsp[id].io_base, RCR1));
  51. dev_dbg(mcbsp[id].dev, "XCR2: 0x%04x\n",
  52. OMAP_MCBSP_READ(mcbsp[id].io_base, XCR2));
  53. dev_dbg(mcbsp[id].dev, "XCR1: 0x%04x\n",
  54. OMAP_MCBSP_READ(mcbsp[id].io_base, XCR1));
  55. dev_dbg(mcbsp[id].dev, "SRGR2: 0x%04x\n",
  56. OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR2));
  57. dev_dbg(mcbsp[id].dev, "SRGR1: 0x%04x\n",
  58. OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR1));
  59. dev_dbg(mcbsp[id].dev, "PCR0: 0x%04x\n",
  60. OMAP_MCBSP_READ(mcbsp[id].io_base, PCR0));
  61. dev_dbg(mcbsp[id].dev, "***********************\n");
  62. }
  63. static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id)
  64. {
  65. struct omap_mcbsp *mcbsp_tx = dev_id;
  66. dev_dbg(mcbsp_tx->dev, "TX IRQ callback : 0x%x\n",
  67. OMAP_MCBSP_READ(mcbsp_tx->io_base, SPCR2));
  68. complete(&mcbsp_tx->tx_irq_completion);
  69. return IRQ_HANDLED;
  70. }
  71. static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id)
  72. {
  73. struct omap_mcbsp *mcbsp_rx = dev_id;
  74. dev_dbg(mcbsp_rx->dev, "RX IRQ callback : 0x%x\n",
  75. OMAP_MCBSP_READ(mcbsp_rx->io_base, SPCR2));
  76. complete(&mcbsp_rx->rx_irq_completion);
  77. return IRQ_HANDLED;
  78. }
  79. static void omap_mcbsp_tx_dma_callback(int lch, u16 ch_status, void *data)
  80. {
  81. struct omap_mcbsp *mcbsp_dma_tx = data;
  82. dev_dbg(mcbsp_dma_tx->dev, "TX DMA callback : 0x%x\n",
  83. OMAP_MCBSP_READ(mcbsp_dma_tx->io_base, SPCR2));
  84. /* We can free the channels */
  85. omap_free_dma(mcbsp_dma_tx->dma_tx_lch);
  86. mcbsp_dma_tx->dma_tx_lch = -1;
  87. complete(&mcbsp_dma_tx->tx_dma_completion);
  88. }
  89. static void omap_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data)
  90. {
  91. struct omap_mcbsp *mcbsp_dma_rx = data;
  92. dev_dbg(mcbsp_dma_rx->dev, "RX DMA callback : 0x%x\n",
  93. OMAP_MCBSP_READ(mcbsp_dma_rx->io_base, SPCR2));
  94. /* We can free the channels */
  95. omap_free_dma(mcbsp_dma_rx->dma_rx_lch);
  96. mcbsp_dma_rx->dma_rx_lch = -1;
  97. complete(&mcbsp_dma_rx->rx_dma_completion);
  98. }
  99. /*
  100. * omap_mcbsp_config simply write a config to the
  101. * appropriate McBSP.
  102. * You either call this function or set the McBSP registers
  103. * by yourself before calling omap_mcbsp_start().
  104. */
  105. void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config)
  106. {
  107. u32 io_base;
  108. if (!omap_mcbsp_check_valid_id(id)) {
  109. printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
  110. return;
  111. }
  112. io_base = mcbsp[id].io_base;
  113. dev_dbg(mcbsp[id].dev, "Configuring McBSP%d io_base: 0x%8x\n",
  114. mcbsp[id].id, io_base);
  115. /* We write the given config */
  116. OMAP_MCBSP_WRITE(io_base, SPCR2, config->spcr2);
  117. OMAP_MCBSP_WRITE(io_base, SPCR1, config->spcr1);
  118. OMAP_MCBSP_WRITE(io_base, RCR2, config->rcr2);
  119. OMAP_MCBSP_WRITE(io_base, RCR1, config->rcr1);
  120. OMAP_MCBSP_WRITE(io_base, XCR2, config->xcr2);
  121. OMAP_MCBSP_WRITE(io_base, XCR1, config->xcr1);
  122. OMAP_MCBSP_WRITE(io_base, SRGR2, config->srgr2);
  123. OMAP_MCBSP_WRITE(io_base, SRGR1, config->srgr1);
  124. OMAP_MCBSP_WRITE(io_base, MCR2, config->mcr2);
  125. OMAP_MCBSP_WRITE(io_base, MCR1, config->mcr1);
  126. OMAP_MCBSP_WRITE(io_base, PCR0, config->pcr0);
  127. }
  128. EXPORT_SYMBOL(omap_mcbsp_config);
  129. /*
  130. * We can choose between IRQ based or polled IO.
  131. * This needs to be called before omap_mcbsp_request().
  132. */
  133. int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type)
  134. {
  135. if (!omap_mcbsp_check_valid_id(id)) {
  136. printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
  137. return -ENODEV;
  138. }
  139. spin_lock(&mcbsp[id].lock);
  140. if (!mcbsp[id].free) {
  141. dev_err(mcbsp[id].dev, "McBSP%d is currently in use\n",
  142. mcbsp[id].id);
  143. spin_unlock(&mcbsp[id].lock);
  144. return -EINVAL;
  145. }
  146. mcbsp[id].io_type = io_type;
  147. spin_unlock(&mcbsp[id].lock);
  148. return 0;
  149. }
  150. EXPORT_SYMBOL(omap_mcbsp_set_io_type);
  151. int omap_mcbsp_request(unsigned int id)
  152. {
  153. int err;
  154. if (!omap_mcbsp_check_valid_id(id)) {
  155. printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
  156. return -ENODEV;
  157. }
  158. if (mcbsp[id].pdata->ops->request)
  159. mcbsp[id].pdata->ops->request(id);
  160. clk_enable(mcbsp[id].clk);
  161. spin_lock(&mcbsp[id].lock);
  162. if (!mcbsp[id].free) {
  163. dev_err(mcbsp[id].dev, "McBSP%d is currently in use\n",
  164. mcbsp[id].id);
  165. spin_unlock(&mcbsp[id].lock);
  166. return -1;
  167. }
  168. mcbsp[id].free = 0;
  169. spin_unlock(&mcbsp[id].lock);
  170. if (mcbsp[id].io_type == OMAP_MCBSP_IRQ_IO) {
  171. /* We need to get IRQs here */
  172. err = request_irq(mcbsp[id].tx_irq, omap_mcbsp_tx_irq_handler,
  173. 0, "McBSP", (void *) (&mcbsp[id]));
  174. if (err != 0) {
  175. dev_err(mcbsp[id].dev, "Unable to request TX IRQ %d "
  176. "for McBSP%d\n", mcbsp[id].tx_irq,
  177. mcbsp[id].id);
  178. return err;
  179. }
  180. init_completion(&(mcbsp[id].tx_irq_completion));
  181. err = request_irq(mcbsp[id].rx_irq, omap_mcbsp_rx_irq_handler,
  182. 0, "McBSP", (void *) (&mcbsp[id]));
  183. if (err != 0) {
  184. dev_err(mcbsp[id].dev, "Unable to request RX IRQ %d "
  185. "for McBSP%d\n", mcbsp[id].rx_irq,
  186. mcbsp[id].id);
  187. free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id]));
  188. return err;
  189. }
  190. init_completion(&(mcbsp[id].rx_irq_completion));
  191. }
  192. return 0;
  193. }
  194. EXPORT_SYMBOL(omap_mcbsp_request);
  195. void omap_mcbsp_free(unsigned int id)
  196. {
  197. if (!omap_mcbsp_check_valid_id(id)) {
  198. printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
  199. return;
  200. }
  201. if (mcbsp[id].pdata->ops->free)
  202. mcbsp[id].pdata->ops->free(id);
  203. clk_disable(mcbsp[id].clk);
  204. spin_lock(&mcbsp[id].lock);
  205. if (mcbsp[id].free) {
  206. dev_err(mcbsp[id].dev, "McBSP%d was not reserved\n",
  207. mcbsp[id].id);
  208. spin_unlock(&mcbsp[id].lock);
  209. return;
  210. }
  211. mcbsp[id].free = 1;
  212. spin_unlock(&mcbsp[id].lock);
  213. if (mcbsp[id].io_type == OMAP_MCBSP_IRQ_IO) {
  214. /* Free IRQs */
  215. free_irq(mcbsp[id].rx_irq, (void *) (&mcbsp[id]));
  216. free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id]));
  217. }
  218. }
  219. EXPORT_SYMBOL(omap_mcbsp_free);
  220. /*
  221. * Here we start the McBSP, by enabling the sample
  222. * generator, both transmitter and receivers,
  223. * and the frame sync.
  224. */
  225. void omap_mcbsp_start(unsigned int id)
  226. {
  227. u32 io_base;
  228. u16 w;
  229. if (!omap_mcbsp_check_valid_id(id)) {
  230. printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
  231. return;
  232. }
  233. io_base = mcbsp[id].io_base;
  234. mcbsp[id].rx_word_length = (OMAP_MCBSP_READ(io_base, RCR1) >> 5) & 0x7;
  235. mcbsp[id].tx_word_length = (OMAP_MCBSP_READ(io_base, XCR1) >> 5) & 0x7;
  236. /* Start the sample generator */
  237. w = OMAP_MCBSP_READ(io_base, SPCR2);
  238. OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 6));
  239. /* Enable transmitter and receiver */
  240. w = OMAP_MCBSP_READ(io_base, SPCR2);
  241. OMAP_MCBSP_WRITE(io_base, SPCR2, w | 1);
  242. w = OMAP_MCBSP_READ(io_base, SPCR1);
  243. OMAP_MCBSP_WRITE(io_base, SPCR1, w | 1);
  244. udelay(100);
  245. /* Start frame sync */
  246. w = OMAP_MCBSP_READ(io_base, SPCR2);
  247. OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 7));
  248. /* Dump McBSP Regs */
  249. omap_mcbsp_dump_reg(id);
  250. }
  251. EXPORT_SYMBOL(omap_mcbsp_start);
  252. void omap_mcbsp_stop(unsigned int id)
  253. {
  254. u32 io_base;
  255. u16 w;
  256. if (!omap_mcbsp_check_valid_id(id)) {
  257. printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
  258. return;
  259. }
  260. io_base = mcbsp[id].io_base;
  261. /* Reset transmitter */
  262. w = OMAP_MCBSP_READ(io_base, SPCR2);
  263. OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1));
  264. /* Reset receiver */
  265. w = OMAP_MCBSP_READ(io_base, SPCR1);
  266. OMAP_MCBSP_WRITE(io_base, SPCR1, w & ~(1));
  267. /* Reset the sample rate generator */
  268. w = OMAP_MCBSP_READ(io_base, SPCR2);
  269. OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1 << 6));
  270. }
  271. EXPORT_SYMBOL(omap_mcbsp_stop);
  272. /* polled mcbsp i/o operations */
  273. int omap_mcbsp_pollwrite(unsigned int id, u16 buf)
  274. {
  275. u32 base;
  276. if (!omap_mcbsp_check_valid_id(id)) {
  277. printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
  278. return -ENODEV;
  279. }
  280. base = mcbsp[id].io_base;
  281. writew(buf, base + OMAP_MCBSP_REG_DXR1);
  282. /* if frame sync error - clear the error */
  283. if (readw(base + OMAP_MCBSP_REG_SPCR2) & XSYNC_ERR) {
  284. /* clear error */
  285. writew(readw(base + OMAP_MCBSP_REG_SPCR2) & (~XSYNC_ERR),
  286. base + OMAP_MCBSP_REG_SPCR2);
  287. /* resend */
  288. return -1;
  289. } else {
  290. /* wait for transmit confirmation */
  291. int attemps = 0;
  292. while (!(readw(base + OMAP_MCBSP_REG_SPCR2) & XRDY)) {
  293. if (attemps++ > 1000) {
  294. writew(readw(base + OMAP_MCBSP_REG_SPCR2) &
  295. (~XRST),
  296. base + OMAP_MCBSP_REG_SPCR2);
  297. udelay(10);
  298. writew(readw(base + OMAP_MCBSP_REG_SPCR2) |
  299. (XRST),
  300. base + OMAP_MCBSP_REG_SPCR2);
  301. udelay(10);
  302. dev_err(mcbsp[id].dev, "Could not write to"
  303. " McBSP%d Register\n", mcbsp[id].id);
  304. return -2;
  305. }
  306. }
  307. }
  308. return 0;
  309. }
  310. EXPORT_SYMBOL(omap_mcbsp_pollwrite);
  311. int omap_mcbsp_pollread(unsigned int id, u16 *buf)
  312. {
  313. u32 base;
  314. if (!omap_mcbsp_check_valid_id(id)) {
  315. printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
  316. return -ENODEV;
  317. }
  318. base = mcbsp[id].io_base;
  319. /* if frame sync error - clear the error */
  320. if (readw(base + OMAP_MCBSP_REG_SPCR1) & RSYNC_ERR) {
  321. /* clear error */
  322. writew(readw(base + OMAP_MCBSP_REG_SPCR1) & (~RSYNC_ERR),
  323. base + OMAP_MCBSP_REG_SPCR1);
  324. /* resend */
  325. return -1;
  326. } else {
  327. /* wait for recieve confirmation */
  328. int attemps = 0;
  329. while (!(readw(base + OMAP_MCBSP_REG_SPCR1) & RRDY)) {
  330. if (attemps++ > 1000) {
  331. writew(readw(base + OMAP_MCBSP_REG_SPCR1) &
  332. (~RRST),
  333. base + OMAP_MCBSP_REG_SPCR1);
  334. udelay(10);
  335. writew(readw(base + OMAP_MCBSP_REG_SPCR1) |
  336. (RRST),
  337. base + OMAP_MCBSP_REG_SPCR1);
  338. udelay(10);
  339. dev_err(mcbsp[id].dev, "Could not read from"
  340. " McBSP%d Register\n", mcbsp[id].id);
  341. return -2;
  342. }
  343. }
  344. }
  345. *buf = readw(base + OMAP_MCBSP_REG_DRR1);
  346. return 0;
  347. }
  348. EXPORT_SYMBOL(omap_mcbsp_pollread);
  349. /*
  350. * IRQ based word transmission.
  351. */
  352. void omap_mcbsp_xmit_word(unsigned int id, u32 word)
  353. {
  354. u32 io_base;
  355. omap_mcbsp_word_length word_length;
  356. if (!omap_mcbsp_check_valid_id(id)) {
  357. printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
  358. return;
  359. }
  360. io_base = mcbsp[id].io_base;
  361. word_length = mcbsp[id].tx_word_length;
  362. wait_for_completion(&(mcbsp[id].tx_irq_completion));
  363. if (word_length > OMAP_MCBSP_WORD_16)
  364. OMAP_MCBSP_WRITE(io_base, DXR2, word >> 16);
  365. OMAP_MCBSP_WRITE(io_base, DXR1, word & 0xffff);
  366. }
  367. EXPORT_SYMBOL(omap_mcbsp_xmit_word);
  368. u32 omap_mcbsp_recv_word(unsigned int id)
  369. {
  370. u32 io_base;
  371. u16 word_lsb, word_msb = 0;
  372. omap_mcbsp_word_length word_length;
  373. if (!omap_mcbsp_check_valid_id(id)) {
  374. printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
  375. return -ENODEV;
  376. }
  377. word_length = mcbsp[id].rx_word_length;
  378. io_base = mcbsp[id].io_base;
  379. wait_for_completion(&(mcbsp[id].rx_irq_completion));
  380. if (word_length > OMAP_MCBSP_WORD_16)
  381. word_msb = OMAP_MCBSP_READ(io_base, DRR2);
  382. word_lsb = OMAP_MCBSP_READ(io_base, DRR1);
  383. return (word_lsb | (word_msb << 16));
  384. }
  385. EXPORT_SYMBOL(omap_mcbsp_recv_word);
  386. int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word)
  387. {
  388. u32 io_base;
  389. omap_mcbsp_word_length tx_word_length;
  390. omap_mcbsp_word_length rx_word_length;
  391. u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0;
  392. if (!omap_mcbsp_check_valid_id(id)) {
  393. printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
  394. return -ENODEV;
  395. }
  396. io_base = mcbsp[id].io_base;
  397. tx_word_length = mcbsp[id].tx_word_length;
  398. rx_word_length = mcbsp[id].rx_word_length;
  399. if (tx_word_length != rx_word_length)
  400. return -EINVAL;
  401. /* First we wait for the transmitter to be ready */
  402. spcr2 = OMAP_MCBSP_READ(io_base, SPCR2);
  403. while (!(spcr2 & XRDY)) {
  404. spcr2 = OMAP_MCBSP_READ(io_base, SPCR2);
  405. if (attempts++ > 1000) {
  406. /* We must reset the transmitter */
  407. OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 & (~XRST));
  408. udelay(10);
  409. OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST);
  410. udelay(10);
  411. dev_err(mcbsp[id].dev, "McBSP%d transmitter not "
  412. "ready\n", mcbsp[id].id);
  413. return -EAGAIN;
  414. }
  415. }
  416. /* Now we can push the data */
  417. if (tx_word_length > OMAP_MCBSP_WORD_16)
  418. OMAP_MCBSP_WRITE(io_base, DXR2, word >> 16);
  419. OMAP_MCBSP_WRITE(io_base, DXR1, word & 0xffff);
  420. /* We wait for the receiver to be ready */
  421. spcr1 = OMAP_MCBSP_READ(io_base, SPCR1);
  422. while (!(spcr1 & RRDY)) {
  423. spcr1 = OMAP_MCBSP_READ(io_base, SPCR1);
  424. if (attempts++ > 1000) {
  425. /* We must reset the receiver */
  426. OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 & (~RRST));
  427. udelay(10);
  428. OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST);
  429. udelay(10);
  430. dev_err(mcbsp[id].dev, "McBSP%d receiver not "
  431. "ready\n", mcbsp[id].id);
  432. return -EAGAIN;
  433. }
  434. }
  435. /* Receiver is ready, let's read the dummy data */
  436. if (rx_word_length > OMAP_MCBSP_WORD_16)
  437. word_msb = OMAP_MCBSP_READ(io_base, DRR2);
  438. word_lsb = OMAP_MCBSP_READ(io_base, DRR1);
  439. return 0;
  440. }
  441. EXPORT_SYMBOL(omap_mcbsp_spi_master_xmit_word_poll);
  442. int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word)
  443. {
  444. u32 io_base, clock_word = 0;
  445. omap_mcbsp_word_length tx_word_length;
  446. omap_mcbsp_word_length rx_word_length;
  447. u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0;
  448. if (!omap_mcbsp_check_valid_id(id)) {
  449. printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
  450. return -ENODEV;
  451. }
  452. io_base = mcbsp[id].io_base;
  453. tx_word_length = mcbsp[id].tx_word_length;
  454. rx_word_length = mcbsp[id].rx_word_length;
  455. if (tx_word_length != rx_word_length)
  456. return -EINVAL;
  457. /* First we wait for the transmitter to be ready */
  458. spcr2 = OMAP_MCBSP_READ(io_base, SPCR2);
  459. while (!(spcr2 & XRDY)) {
  460. spcr2 = OMAP_MCBSP_READ(io_base, SPCR2);
  461. if (attempts++ > 1000) {
  462. /* We must reset the transmitter */
  463. OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 & (~XRST));
  464. udelay(10);
  465. OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST);
  466. udelay(10);
  467. dev_err(mcbsp[id].dev, "McBSP%d transmitter not "
  468. "ready\n", mcbsp[id].id);
  469. return -EAGAIN;
  470. }
  471. }
  472. /* We first need to enable the bus clock */
  473. if (tx_word_length > OMAP_MCBSP_WORD_16)
  474. OMAP_MCBSP_WRITE(io_base, DXR2, clock_word >> 16);
  475. OMAP_MCBSP_WRITE(io_base, DXR1, clock_word & 0xffff);
  476. /* We wait for the receiver to be ready */
  477. spcr1 = OMAP_MCBSP_READ(io_base, SPCR1);
  478. while (!(spcr1 & RRDY)) {
  479. spcr1 = OMAP_MCBSP_READ(io_base, SPCR1);
  480. if (attempts++ > 1000) {
  481. /* We must reset the receiver */
  482. OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 & (~RRST));
  483. udelay(10);
  484. OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST);
  485. udelay(10);
  486. dev_err(mcbsp[id].dev, "McBSP%d receiver not "
  487. "ready\n", mcbsp[id].id);
  488. return -EAGAIN;
  489. }
  490. }
  491. /* Receiver is ready, there is something for us */
  492. if (rx_word_length > OMAP_MCBSP_WORD_16)
  493. word_msb = OMAP_MCBSP_READ(io_base, DRR2);
  494. word_lsb = OMAP_MCBSP_READ(io_base, DRR1);
  495. word[0] = (word_lsb | (word_msb << 16));
  496. return 0;
  497. }
  498. EXPORT_SYMBOL(omap_mcbsp_spi_master_recv_word_poll);
  499. /*
  500. * Simple DMA based buffer rx/tx routines.
  501. * Nothing fancy, just a single buffer tx/rx through DMA.
  502. * The DMA resources are released once the transfer is done.
  503. * For anything fancier, you should use your own customized DMA
  504. * routines and callbacks.
  505. */
  506. int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer,
  507. unsigned int length)
  508. {
  509. int dma_tx_ch;
  510. int src_port = 0;
  511. int dest_port = 0;
  512. int sync_dev = 0;
  513. if (!omap_mcbsp_check_valid_id(id)) {
  514. printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
  515. return -ENODEV;
  516. }
  517. if (omap_request_dma(mcbsp[id].dma_tx_sync, "McBSP TX",
  518. omap_mcbsp_tx_dma_callback,
  519. &mcbsp[id],
  520. &dma_tx_ch)) {
  521. dev_err(mcbsp[id].dev, " Unable to request DMA channel for "
  522. "McBSP%d TX. Trying IRQ based TX\n",
  523. mcbsp[id].id);
  524. return -EAGAIN;
  525. }
  526. mcbsp[id].dma_tx_lch = dma_tx_ch;
  527. dev_err(mcbsp[id].dev, "McBSP%d TX DMA on channel %d\n", mcbsp[id].id,
  528. dma_tx_ch);
  529. init_completion(&(mcbsp[id].tx_dma_completion));
  530. if (cpu_class_is_omap1()) {
  531. src_port = OMAP_DMA_PORT_TIPB;
  532. dest_port = OMAP_DMA_PORT_EMIFF;
  533. }
  534. if (cpu_class_is_omap2())
  535. sync_dev = mcbsp[id].dma_tx_sync;
  536. omap_set_dma_transfer_params(mcbsp[id].dma_tx_lch,
  537. OMAP_DMA_DATA_TYPE_S16,
  538. length >> 1, 1,
  539. OMAP_DMA_SYNC_ELEMENT,
  540. sync_dev, 0);
  541. omap_set_dma_dest_params(mcbsp[id].dma_tx_lch,
  542. src_port,
  543. OMAP_DMA_AMODE_CONSTANT,
  544. mcbsp[id].phys_base + OMAP_MCBSP_REG_DXR1,
  545. 0, 0);
  546. omap_set_dma_src_params(mcbsp[id].dma_tx_lch,
  547. dest_port,
  548. OMAP_DMA_AMODE_POST_INC,
  549. buffer,
  550. 0, 0);
  551. omap_start_dma(mcbsp[id].dma_tx_lch);
  552. wait_for_completion(&(mcbsp[id].tx_dma_completion));
  553. return 0;
  554. }
  555. EXPORT_SYMBOL(omap_mcbsp_xmit_buffer);
  556. int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer,
  557. unsigned int length)
  558. {
  559. int dma_rx_ch;
  560. int src_port = 0;
  561. int dest_port = 0;
  562. int sync_dev = 0;
  563. if (!omap_mcbsp_check_valid_id(id)) {
  564. printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
  565. return -ENODEV;
  566. }
  567. if (omap_request_dma(mcbsp[id].dma_rx_sync, "McBSP RX",
  568. omap_mcbsp_rx_dma_callback,
  569. &mcbsp[id],
  570. &dma_rx_ch)) {
  571. dev_err(mcbsp[id].dev, "Unable to request DMA channel for "
  572. "McBSP%d RX. Trying IRQ based RX\n",
  573. mcbsp[id].id);
  574. return -EAGAIN;
  575. }
  576. mcbsp[id].dma_rx_lch = dma_rx_ch;
  577. dev_err(mcbsp[id].dev, "McBSP%d RX DMA on channel %d\n", mcbsp[id].id,
  578. dma_rx_ch);
  579. init_completion(&(mcbsp[id].rx_dma_completion));
  580. if (cpu_class_is_omap1()) {
  581. src_port = OMAP_DMA_PORT_TIPB;
  582. dest_port = OMAP_DMA_PORT_EMIFF;
  583. }
  584. if (cpu_class_is_omap2())
  585. sync_dev = mcbsp[id].dma_rx_sync;
  586. omap_set_dma_transfer_params(mcbsp[id].dma_rx_lch,
  587. OMAP_DMA_DATA_TYPE_S16,
  588. length >> 1, 1,
  589. OMAP_DMA_SYNC_ELEMENT,
  590. sync_dev, 0);
  591. omap_set_dma_src_params(mcbsp[id].dma_rx_lch,
  592. src_port,
  593. OMAP_DMA_AMODE_CONSTANT,
  594. mcbsp[id].phys_base + OMAP_MCBSP_REG_DRR1,
  595. 0, 0);
  596. omap_set_dma_dest_params(mcbsp[id].dma_rx_lch,
  597. dest_port,
  598. OMAP_DMA_AMODE_POST_INC,
  599. buffer,
  600. 0, 0);
  601. omap_start_dma(mcbsp[id].dma_rx_lch);
  602. wait_for_completion(&(mcbsp[id].rx_dma_completion));
  603. return 0;
  604. }
  605. EXPORT_SYMBOL(omap_mcbsp_recv_buffer);
  606. /*
  607. * SPI wrapper.
  608. * Since SPI setup is much simpler than the generic McBSP one,
  609. * this wrapper just need an omap_mcbsp_spi_cfg structure as an input.
  610. * Once this is done, you can call omap_mcbsp_start().
  611. */
  612. void omap_mcbsp_set_spi_mode(unsigned int id,
  613. const struct omap_mcbsp_spi_cfg *spi_cfg)
  614. {
  615. struct omap_mcbsp_reg_cfg mcbsp_cfg;
  616. if (!omap_mcbsp_check_valid_id(id)) {
  617. printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
  618. return;
  619. }
  620. memset(&mcbsp_cfg, 0, sizeof(struct omap_mcbsp_reg_cfg));
  621. /* SPI has only one frame */
  622. mcbsp_cfg.rcr1 |= (RWDLEN1(spi_cfg->word_length) | RFRLEN1(0));
  623. mcbsp_cfg.xcr1 |= (XWDLEN1(spi_cfg->word_length) | XFRLEN1(0));
  624. /* Clock stop mode */
  625. if (spi_cfg->clk_stp_mode == OMAP_MCBSP_CLK_STP_MODE_NO_DELAY)
  626. mcbsp_cfg.spcr1 |= (1 << 12);
  627. else
  628. mcbsp_cfg.spcr1 |= (3 << 11);
  629. /* Set clock parities */
  630. if (spi_cfg->rx_clock_polarity == OMAP_MCBSP_CLK_RISING)
  631. mcbsp_cfg.pcr0 |= CLKRP;
  632. else
  633. mcbsp_cfg.pcr0 &= ~CLKRP;
  634. if (spi_cfg->tx_clock_polarity == OMAP_MCBSP_CLK_RISING)
  635. mcbsp_cfg.pcr0 &= ~CLKXP;
  636. else
  637. mcbsp_cfg.pcr0 |= CLKXP;
  638. /* Set SCLKME to 0 and CLKSM to 1 */
  639. mcbsp_cfg.pcr0 &= ~SCLKME;
  640. mcbsp_cfg.srgr2 |= CLKSM;
  641. /* Set FSXP */
  642. if (spi_cfg->fsx_polarity == OMAP_MCBSP_FS_ACTIVE_HIGH)
  643. mcbsp_cfg.pcr0 &= ~FSXP;
  644. else
  645. mcbsp_cfg.pcr0 |= FSXP;
  646. if (spi_cfg->spi_mode == OMAP_MCBSP_SPI_MASTER) {
  647. mcbsp_cfg.pcr0 |= CLKXM;
  648. mcbsp_cfg.srgr1 |= CLKGDV(spi_cfg->clk_div - 1);
  649. mcbsp_cfg.pcr0 |= FSXM;
  650. mcbsp_cfg.srgr2 &= ~FSGM;
  651. mcbsp_cfg.xcr2 |= XDATDLY(1);
  652. mcbsp_cfg.rcr2 |= RDATDLY(1);
  653. } else {
  654. mcbsp_cfg.pcr0 &= ~CLKXM;
  655. mcbsp_cfg.srgr1 |= CLKGDV(1);
  656. mcbsp_cfg.pcr0 &= ~FSXM;
  657. mcbsp_cfg.xcr2 &= ~XDATDLY(3);
  658. mcbsp_cfg.rcr2 &= ~RDATDLY(3);
  659. }
  660. mcbsp_cfg.xcr2 &= ~XPHASE;
  661. mcbsp_cfg.rcr2 &= ~RPHASE;
  662. omap_mcbsp_config(id, &mcbsp_cfg);
  663. }
  664. EXPORT_SYMBOL(omap_mcbsp_set_spi_mode);
  665. /*
  666. * McBSP1 and McBSP3 are directly mapped on 1610 and 1510.
  667. * 730 has only 2 McBSP, and both of them are MPU peripherals.
  668. */
  669. static int __init omap_mcbsp_probe(struct platform_device *pdev)
  670. {
  671. struct omap_mcbsp_platform_data *pdata = pdev->dev.platform_data;
  672. int id = pdev->id - 1;
  673. int ret = 0;
  674. if (!pdata) {
  675. dev_err(&pdev->dev, "McBSP device initialized without"
  676. "platform data\n");
  677. ret = -EINVAL;
  678. goto exit;
  679. }
  680. dev_dbg(&pdev->dev, "Initializing OMAP McBSP (%d).\n", pdev->id);
  681. if (id >= OMAP_MAX_MCBSP_COUNT) {
  682. dev_err(&pdev->dev, "Invalid McBSP device id (%d)\n", id);
  683. ret = -EINVAL;
  684. goto exit;
  685. }
  686. spin_lock_init(&mcbsp[id].lock);
  687. mcbsp[id].id = id + 1;
  688. mcbsp[id].free = 1;
  689. mcbsp[id].dma_tx_lch = -1;
  690. mcbsp[id].dma_rx_lch = -1;
  691. mcbsp[id].phys_base = pdata->phys_base;
  692. mcbsp[id].io_base = pdata->virt_base;
  693. /* Default I/O is IRQ based */
  694. mcbsp[id].io_type = OMAP_MCBSP_IRQ_IO;
  695. mcbsp[id].tx_irq = pdata->tx_irq;
  696. mcbsp[id].rx_irq = pdata->rx_irq;
  697. mcbsp[id].dma_rx_sync = pdata->dma_rx_sync;
  698. mcbsp[id].dma_tx_sync = pdata->dma_tx_sync;
  699. if (pdata->clk_name)
  700. mcbsp[id].clk = clk_get(&pdev->dev, pdata->clk_name);
  701. if (IS_ERR(mcbsp[id].clk)) {
  702. mcbsp[id].free = 0;
  703. dev_err(&pdev->dev,
  704. "Invalid clock configuration for McBSP%d.\n",
  705. mcbsp[id].id);
  706. ret = -EINVAL;
  707. goto exit;
  708. }
  709. mcbsp[id].pdata = pdata;
  710. mcbsp[id].dev = &pdev->dev;
  711. platform_set_drvdata(pdev, &mcbsp[id]);
  712. exit:
  713. return ret;
  714. }
  715. static int omap_mcbsp_remove(struct platform_device *pdev)
  716. {
  717. struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev);
  718. platform_set_drvdata(pdev, NULL);
  719. if (mcbsp) {
  720. if (mcbsp->pdata && mcbsp->pdata->ops &&
  721. mcbsp->pdata->ops->free)
  722. mcbsp->pdata->ops->free(mcbsp->id);
  723. clk_disable(mcbsp->clk);
  724. clk_put(mcbsp->clk);
  725. mcbsp->clk = NULL;
  726. mcbsp->free = 0;
  727. mcbsp->dev = NULL;
  728. }
  729. return 0;
  730. }
  731. static struct platform_driver omap_mcbsp_driver = {
  732. .probe = omap_mcbsp_probe,
  733. .remove = omap_mcbsp_remove,
  734. .driver = {
  735. .name = "omap-mcbsp",
  736. },
  737. };
  738. int __init omap_mcbsp_init(void)
  739. {
  740. /* Register the McBSP driver */
  741. return platform_driver_register(&omap_mcbsp_driver);
  742. }