ux500_msp_i2s.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737
  1. /*
  2. * Copyright (C) ST-Ericsson SA 2012
  3. *
  4. * Author: Ola Lilja <ola.o.lilja@stericsson.com>,
  5. * Roger Nilsson <roger.xr.nilsson@stericsson.com>,
  6. * Sandeep Kaushik <sandeep.kaushik@st.com>
  7. * for ST-Ericsson.
  8. *
  9. * License terms:
  10. *
  11. * This program is free software; you can redistribute it and/or modify
  12. * it under the terms of the GNU General Public License version 2 as published
  13. * by the Free Software Foundation.
  14. */
  15. #include <linux/module.h>
  16. #include <linux/platform_device.h>
  17. #include <linux/delay.h>
  18. #include <linux/slab.h>
  19. #include <linux/io.h>
  20. #include <linux/of.h>
  21. #include <linux/platform_data/asoc-ux500-msp.h>
  22. #include <sound/soc.h>
  23. #include "ux500_msp_i2s.h"
  24. /* Protocol desciptors */
  25. static const struct msp_protdesc prot_descs[] = {
  26. { /* I2S */
  27. MSP_SINGLE_PHASE,
  28. MSP_SINGLE_PHASE,
  29. MSP_PHASE2_START_MODE_IMEDIATE,
  30. MSP_PHASE2_START_MODE_IMEDIATE,
  31. MSP_BTF_MS_BIT_FIRST,
  32. MSP_BTF_MS_BIT_FIRST,
  33. MSP_FRAME_LEN_1,
  34. MSP_FRAME_LEN_1,
  35. MSP_FRAME_LEN_1,
  36. MSP_FRAME_LEN_1,
  37. MSP_ELEM_LEN_32,
  38. MSP_ELEM_LEN_32,
  39. MSP_ELEM_LEN_32,
  40. MSP_ELEM_LEN_32,
  41. MSP_DELAY_1,
  42. MSP_DELAY_1,
  43. MSP_RISING_EDGE,
  44. MSP_FALLING_EDGE,
  45. MSP_FSYNC_POL_ACT_LO,
  46. MSP_FSYNC_POL_ACT_LO,
  47. MSP_SWAP_NONE,
  48. MSP_SWAP_NONE,
  49. MSP_COMPRESS_MODE_LINEAR,
  50. MSP_EXPAND_MODE_LINEAR,
  51. MSP_FSYNC_IGNORE,
  52. 31,
  53. 15,
  54. 32,
  55. }, { /* PCM */
  56. MSP_DUAL_PHASE,
  57. MSP_DUAL_PHASE,
  58. MSP_PHASE2_START_MODE_FSYNC,
  59. MSP_PHASE2_START_MODE_FSYNC,
  60. MSP_BTF_MS_BIT_FIRST,
  61. MSP_BTF_MS_BIT_FIRST,
  62. MSP_FRAME_LEN_1,
  63. MSP_FRAME_LEN_1,
  64. MSP_FRAME_LEN_1,
  65. MSP_FRAME_LEN_1,
  66. MSP_ELEM_LEN_16,
  67. MSP_ELEM_LEN_16,
  68. MSP_ELEM_LEN_16,
  69. MSP_ELEM_LEN_16,
  70. MSP_DELAY_0,
  71. MSP_DELAY_0,
  72. MSP_RISING_EDGE,
  73. MSP_FALLING_EDGE,
  74. MSP_FSYNC_POL_ACT_HI,
  75. MSP_FSYNC_POL_ACT_HI,
  76. MSP_SWAP_NONE,
  77. MSP_SWAP_NONE,
  78. MSP_COMPRESS_MODE_LINEAR,
  79. MSP_EXPAND_MODE_LINEAR,
  80. MSP_FSYNC_IGNORE,
  81. 255,
  82. 0,
  83. 256,
  84. }, { /* Companded PCM */
  85. MSP_SINGLE_PHASE,
  86. MSP_SINGLE_PHASE,
  87. MSP_PHASE2_START_MODE_FSYNC,
  88. MSP_PHASE2_START_MODE_FSYNC,
  89. MSP_BTF_MS_BIT_FIRST,
  90. MSP_BTF_MS_BIT_FIRST,
  91. MSP_FRAME_LEN_1,
  92. MSP_FRAME_LEN_1,
  93. MSP_FRAME_LEN_1,
  94. MSP_FRAME_LEN_1,
  95. MSP_ELEM_LEN_8,
  96. MSP_ELEM_LEN_8,
  97. MSP_ELEM_LEN_8,
  98. MSP_ELEM_LEN_8,
  99. MSP_DELAY_0,
  100. MSP_DELAY_0,
  101. MSP_RISING_EDGE,
  102. MSP_RISING_EDGE,
  103. MSP_FSYNC_POL_ACT_HI,
  104. MSP_FSYNC_POL_ACT_HI,
  105. MSP_SWAP_NONE,
  106. MSP_SWAP_NONE,
  107. MSP_COMPRESS_MODE_LINEAR,
  108. MSP_EXPAND_MODE_LINEAR,
  109. MSP_FSYNC_IGNORE,
  110. 255,
  111. 0,
  112. 256,
  113. },
  114. };
  115. static void set_prot_desc_tx(struct ux500_msp *msp,
  116. struct msp_protdesc *protdesc,
  117. enum msp_data_size data_size)
  118. {
  119. u32 temp_reg = 0;
  120. temp_reg |= MSP_P2_ENABLE_BIT(protdesc->tx_phase_mode);
  121. temp_reg |= MSP_P2_START_MODE_BIT(protdesc->tx_phase2_start_mode);
  122. temp_reg |= MSP_P1_FRAME_LEN_BITS(protdesc->tx_frame_len_1);
  123. temp_reg |= MSP_P2_FRAME_LEN_BITS(protdesc->tx_frame_len_2);
  124. if (msp->def_elem_len) {
  125. temp_reg |= MSP_P1_ELEM_LEN_BITS(protdesc->tx_elem_len_1);
  126. temp_reg |= MSP_P2_ELEM_LEN_BITS(protdesc->tx_elem_len_2);
  127. } else {
  128. temp_reg |= MSP_P1_ELEM_LEN_BITS(data_size);
  129. temp_reg |= MSP_P2_ELEM_LEN_BITS(data_size);
  130. }
  131. temp_reg |= MSP_DATA_DELAY_BITS(protdesc->tx_data_delay);
  132. temp_reg |= MSP_SET_ENDIANNES_BIT(protdesc->tx_byte_order);
  133. temp_reg |= MSP_FSYNC_POL(protdesc->tx_fsync_pol);
  134. temp_reg |= MSP_DATA_WORD_SWAP(protdesc->tx_half_word_swap);
  135. temp_reg |= MSP_SET_COMPANDING_MODE(protdesc->compression_mode);
  136. temp_reg |= MSP_SET_FSYNC_IGNORE(protdesc->frame_sync_ignore);
  137. writel(temp_reg, msp->registers + MSP_TCF);
  138. }
  139. static void set_prot_desc_rx(struct ux500_msp *msp,
  140. struct msp_protdesc *protdesc,
  141. enum msp_data_size data_size)
  142. {
  143. u32 temp_reg = 0;
  144. temp_reg |= MSP_P2_ENABLE_BIT(protdesc->rx_phase_mode);
  145. temp_reg |= MSP_P2_START_MODE_BIT(protdesc->rx_phase2_start_mode);
  146. temp_reg |= MSP_P1_FRAME_LEN_BITS(protdesc->rx_frame_len_1);
  147. temp_reg |= MSP_P2_FRAME_LEN_BITS(protdesc->rx_frame_len_2);
  148. if (msp->def_elem_len) {
  149. temp_reg |= MSP_P1_ELEM_LEN_BITS(protdesc->rx_elem_len_1);
  150. temp_reg |= MSP_P2_ELEM_LEN_BITS(protdesc->rx_elem_len_2);
  151. } else {
  152. temp_reg |= MSP_P1_ELEM_LEN_BITS(data_size);
  153. temp_reg |= MSP_P2_ELEM_LEN_BITS(data_size);
  154. }
  155. temp_reg |= MSP_DATA_DELAY_BITS(protdesc->rx_data_delay);
  156. temp_reg |= MSP_SET_ENDIANNES_BIT(protdesc->rx_byte_order);
  157. temp_reg |= MSP_FSYNC_POL(protdesc->rx_fsync_pol);
  158. temp_reg |= MSP_DATA_WORD_SWAP(protdesc->rx_half_word_swap);
  159. temp_reg |= MSP_SET_COMPANDING_MODE(protdesc->expansion_mode);
  160. temp_reg |= MSP_SET_FSYNC_IGNORE(protdesc->frame_sync_ignore);
  161. writel(temp_reg, msp->registers + MSP_RCF);
  162. }
  163. static int configure_protocol(struct ux500_msp *msp,
  164. struct ux500_msp_config *config)
  165. {
  166. struct msp_protdesc *protdesc;
  167. enum msp_data_size data_size;
  168. u32 temp_reg = 0;
  169. data_size = config->data_size;
  170. msp->def_elem_len = config->def_elem_len;
  171. if (config->default_protdesc == 1) {
  172. if (config->protocol >= MSP_INVALID_PROTOCOL) {
  173. dev_err(msp->dev, "%s: ERROR: Invalid protocol!\n",
  174. __func__);
  175. return -EINVAL;
  176. }
  177. protdesc =
  178. (struct msp_protdesc *)&prot_descs[config->protocol];
  179. } else {
  180. protdesc = (struct msp_protdesc *)&config->protdesc;
  181. }
  182. if (data_size < MSP_DATA_BITS_DEFAULT || data_size > MSP_DATA_BITS_32) {
  183. dev_err(msp->dev,
  184. "%s: ERROR: Invalid data-size requested (data_size = %d)!\n",
  185. __func__, data_size);
  186. return -EINVAL;
  187. }
  188. if (config->direction & MSP_DIR_TX)
  189. set_prot_desc_tx(msp, protdesc, data_size);
  190. if (config->direction & MSP_DIR_RX)
  191. set_prot_desc_rx(msp, protdesc, data_size);
  192. /* The code below should not be separated. */
  193. temp_reg = readl(msp->registers + MSP_GCR) & ~TX_CLK_POL_RISING;
  194. temp_reg |= MSP_TX_CLKPOL_BIT(~protdesc->tx_clk_pol);
  195. writel(temp_reg, msp->registers + MSP_GCR);
  196. temp_reg = readl(msp->registers + MSP_GCR) & ~RX_CLK_POL_RISING;
  197. temp_reg |= MSP_RX_CLKPOL_BIT(protdesc->rx_clk_pol);
  198. writel(temp_reg, msp->registers + MSP_GCR);
  199. return 0;
  200. }
  201. static int setup_bitclk(struct ux500_msp *msp, struct ux500_msp_config *config)
  202. {
  203. u32 reg_val_GCR;
  204. u32 frame_per = 0;
  205. u32 sck_div = 0;
  206. u32 frame_width = 0;
  207. u32 temp_reg = 0;
  208. struct msp_protdesc *protdesc = NULL;
  209. reg_val_GCR = readl(msp->registers + MSP_GCR);
  210. writel(reg_val_GCR & ~SRG_ENABLE, msp->registers + MSP_GCR);
  211. if (config->default_protdesc)
  212. protdesc =
  213. (struct msp_protdesc *)&prot_descs[config->protocol];
  214. else
  215. protdesc = (struct msp_protdesc *)&config->protdesc;
  216. switch (config->protocol) {
  217. case MSP_PCM_PROTOCOL:
  218. case MSP_PCM_COMPAND_PROTOCOL:
  219. frame_width = protdesc->frame_width;
  220. sck_div = config->f_inputclk / (config->frame_freq *
  221. (protdesc->clocks_per_frame));
  222. frame_per = protdesc->frame_period;
  223. break;
  224. case MSP_I2S_PROTOCOL:
  225. frame_width = protdesc->frame_width;
  226. sck_div = config->f_inputclk / (config->frame_freq *
  227. (protdesc->clocks_per_frame));
  228. frame_per = protdesc->frame_period;
  229. break;
  230. default:
  231. dev_err(msp->dev, "%s: ERROR: Unknown protocol (%d)!\n",
  232. __func__,
  233. config->protocol);
  234. return -EINVAL;
  235. }
  236. temp_reg = (sck_div - 1) & SCK_DIV_MASK;
  237. temp_reg |= FRAME_WIDTH_BITS(frame_width);
  238. temp_reg |= FRAME_PERIOD_BITS(frame_per);
  239. writel(temp_reg, msp->registers + MSP_SRG);
  240. msp->f_bitclk = (config->f_inputclk)/(sck_div + 1);
  241. /* Enable bit-clock */
  242. udelay(100);
  243. reg_val_GCR = readl(msp->registers + MSP_GCR);
  244. writel(reg_val_GCR | SRG_ENABLE, msp->registers + MSP_GCR);
  245. udelay(100);
  246. return 0;
  247. }
  248. static int configure_multichannel(struct ux500_msp *msp,
  249. struct ux500_msp_config *config)
  250. {
  251. struct msp_protdesc *protdesc;
  252. struct msp_multichannel_config *mcfg;
  253. u32 reg_val_MCR;
  254. if (config->default_protdesc == 1) {
  255. if (config->protocol >= MSP_INVALID_PROTOCOL) {
  256. dev_err(msp->dev,
  257. "%s: ERROR: Invalid protocol (%d)!\n",
  258. __func__, config->protocol);
  259. return -EINVAL;
  260. }
  261. protdesc = (struct msp_protdesc *)
  262. &prot_descs[config->protocol];
  263. } else {
  264. protdesc = (struct msp_protdesc *)&config->protdesc;
  265. }
  266. mcfg = &config->multichannel_config;
  267. if (mcfg->tx_multichannel_enable) {
  268. if (protdesc->tx_phase_mode == MSP_SINGLE_PHASE) {
  269. reg_val_MCR = readl(msp->registers + MSP_MCR);
  270. writel(reg_val_MCR | (mcfg->tx_multichannel_enable ?
  271. 1 << TMCEN_BIT : 0),
  272. msp->registers + MSP_MCR);
  273. writel(mcfg->tx_channel_0_enable,
  274. msp->registers + MSP_TCE0);
  275. writel(mcfg->tx_channel_1_enable,
  276. msp->registers + MSP_TCE1);
  277. writel(mcfg->tx_channel_2_enable,
  278. msp->registers + MSP_TCE2);
  279. writel(mcfg->tx_channel_3_enable,
  280. msp->registers + MSP_TCE3);
  281. } else {
  282. dev_err(msp->dev,
  283. "%s: ERROR: Only single-phase supported (TX-mode: %d)!\n",
  284. __func__, protdesc->tx_phase_mode);
  285. return -EINVAL;
  286. }
  287. }
  288. if (mcfg->rx_multichannel_enable) {
  289. if (protdesc->rx_phase_mode == MSP_SINGLE_PHASE) {
  290. reg_val_MCR = readl(msp->registers + MSP_MCR);
  291. writel(reg_val_MCR | (mcfg->rx_multichannel_enable ?
  292. 1 << RMCEN_BIT : 0),
  293. msp->registers + MSP_MCR);
  294. writel(mcfg->rx_channel_0_enable,
  295. msp->registers + MSP_RCE0);
  296. writel(mcfg->rx_channel_1_enable,
  297. msp->registers + MSP_RCE1);
  298. writel(mcfg->rx_channel_2_enable,
  299. msp->registers + MSP_RCE2);
  300. writel(mcfg->rx_channel_3_enable,
  301. msp->registers + MSP_RCE3);
  302. } else {
  303. dev_err(msp->dev,
  304. "%s: ERROR: Only single-phase supported (RX-mode: %d)!\n",
  305. __func__, protdesc->rx_phase_mode);
  306. return -EINVAL;
  307. }
  308. if (mcfg->rx_comparison_enable_mode) {
  309. reg_val_MCR = readl(msp->registers + MSP_MCR);
  310. writel(reg_val_MCR |
  311. (mcfg->rx_comparison_enable_mode << RCMPM_BIT),
  312. msp->registers + MSP_MCR);
  313. writel(mcfg->comparison_mask,
  314. msp->registers + MSP_RCM);
  315. writel(mcfg->comparison_value,
  316. msp->registers + MSP_RCV);
  317. }
  318. }
  319. return 0;
  320. }
  321. static int enable_msp(struct ux500_msp *msp, struct ux500_msp_config *config)
  322. {
  323. int status = 0;
  324. u32 reg_val_DMACR, reg_val_GCR;
  325. /* Configure msp with protocol dependent settings */
  326. configure_protocol(msp, config);
  327. setup_bitclk(msp, config);
  328. if (config->multichannel_configured == 1) {
  329. status = configure_multichannel(msp, config);
  330. if (status)
  331. dev_warn(msp->dev,
  332. "%s: WARN: configure_multichannel failed (%d)!\n",
  333. __func__, status);
  334. }
  335. /* Make sure the correct DMA-directions are configured */
  336. if ((config->direction & MSP_DIR_RX) &&
  337. !msp->capture_dma_data.dma_cfg) {
  338. dev_err(msp->dev, "%s: ERROR: MSP RX-mode is not configured!",
  339. __func__);
  340. return -EINVAL;
  341. }
  342. if ((config->direction == MSP_DIR_TX) &&
  343. !msp->playback_dma_data.dma_cfg) {
  344. dev_err(msp->dev, "%s: ERROR: MSP TX-mode is not configured!",
  345. __func__);
  346. return -EINVAL;
  347. }
  348. reg_val_DMACR = readl(msp->registers + MSP_DMACR);
  349. if (config->direction & MSP_DIR_RX)
  350. reg_val_DMACR |= RX_DMA_ENABLE;
  351. if (config->direction & MSP_DIR_TX)
  352. reg_val_DMACR |= TX_DMA_ENABLE;
  353. writel(reg_val_DMACR, msp->registers + MSP_DMACR);
  354. writel(config->iodelay, msp->registers + MSP_IODLY);
  355. /* Enable frame generation logic */
  356. reg_val_GCR = readl(msp->registers + MSP_GCR);
  357. writel(reg_val_GCR | FRAME_GEN_ENABLE, msp->registers + MSP_GCR);
  358. return status;
  359. }
  360. static void flush_fifo_rx(struct ux500_msp *msp)
  361. {
  362. u32 reg_val_DR, reg_val_GCR, reg_val_FLR;
  363. u32 limit = 32;
  364. reg_val_GCR = readl(msp->registers + MSP_GCR);
  365. writel(reg_val_GCR | RX_ENABLE, msp->registers + MSP_GCR);
  366. reg_val_FLR = readl(msp->registers + MSP_FLR);
  367. while (!(reg_val_FLR & RX_FIFO_EMPTY) && limit--) {
  368. reg_val_DR = readl(msp->registers + MSP_DR);
  369. reg_val_FLR = readl(msp->registers + MSP_FLR);
  370. }
  371. writel(reg_val_GCR, msp->registers + MSP_GCR);
  372. }
  373. static void flush_fifo_tx(struct ux500_msp *msp)
  374. {
  375. u32 reg_val_TSTDR, reg_val_GCR, reg_val_FLR;
  376. u32 limit = 32;
  377. reg_val_GCR = readl(msp->registers + MSP_GCR);
  378. writel(reg_val_GCR | TX_ENABLE, msp->registers + MSP_GCR);
  379. writel(MSP_ITCR_ITEN | MSP_ITCR_TESTFIFO, msp->registers + MSP_ITCR);
  380. reg_val_FLR = readl(msp->registers + MSP_FLR);
  381. while (!(reg_val_FLR & TX_FIFO_EMPTY) && limit--) {
  382. reg_val_TSTDR = readl(msp->registers + MSP_TSTDR);
  383. reg_val_FLR = readl(msp->registers + MSP_FLR);
  384. }
  385. writel(0x0, msp->registers + MSP_ITCR);
  386. writel(reg_val_GCR, msp->registers + MSP_GCR);
  387. }
  388. int ux500_msp_i2s_open(struct ux500_msp *msp,
  389. struct ux500_msp_config *config)
  390. {
  391. u32 old_reg, new_reg, mask;
  392. int res;
  393. unsigned int tx_sel, rx_sel, tx_busy, rx_busy;
  394. if (in_interrupt()) {
  395. dev_err(msp->dev,
  396. "%s: ERROR: Open called in interrupt context!\n",
  397. __func__);
  398. return -1;
  399. }
  400. tx_sel = (config->direction & MSP_DIR_TX) > 0;
  401. rx_sel = (config->direction & MSP_DIR_RX) > 0;
  402. if (!tx_sel && !rx_sel) {
  403. dev_err(msp->dev, "%s: Error: No direction selected!\n",
  404. __func__);
  405. return -EINVAL;
  406. }
  407. tx_busy = (msp->dir_busy & MSP_DIR_TX) > 0;
  408. rx_busy = (msp->dir_busy & MSP_DIR_RX) > 0;
  409. if (tx_busy && tx_sel) {
  410. dev_err(msp->dev, "%s: Error: TX is in use!\n", __func__);
  411. return -EBUSY;
  412. }
  413. if (rx_busy && rx_sel) {
  414. dev_err(msp->dev, "%s: Error: RX is in use!\n", __func__);
  415. return -EBUSY;
  416. }
  417. msp->dir_busy |= (tx_sel ? MSP_DIR_TX : 0) | (rx_sel ? MSP_DIR_RX : 0);
  418. /* First do the global config register */
  419. mask = RX_CLK_SEL_MASK | TX_CLK_SEL_MASK | RX_FSYNC_MASK |
  420. TX_FSYNC_MASK | RX_SYNC_SEL_MASK | TX_SYNC_SEL_MASK |
  421. RX_FIFO_ENABLE_MASK | TX_FIFO_ENABLE_MASK | SRG_CLK_SEL_MASK |
  422. LOOPBACK_MASK | TX_EXTRA_DELAY_MASK;
  423. new_reg = (config->tx_clk_sel | config->rx_clk_sel |
  424. config->rx_fsync_pol | config->tx_fsync_pol |
  425. config->rx_fsync_sel | config->tx_fsync_sel |
  426. config->rx_fifo_config | config->tx_fifo_config |
  427. config->srg_clk_sel | config->loopback_enable |
  428. config->tx_data_enable);
  429. old_reg = readl(msp->registers + MSP_GCR);
  430. old_reg &= ~mask;
  431. new_reg |= old_reg;
  432. writel(new_reg, msp->registers + MSP_GCR);
  433. res = enable_msp(msp, config);
  434. if (res < 0) {
  435. dev_err(msp->dev, "%s: ERROR: enable_msp failed (%d)!\n",
  436. __func__, res);
  437. return -EBUSY;
  438. }
  439. if (config->loopback_enable & 0x80)
  440. msp->loopback_enable = 1;
  441. /* Flush FIFOs */
  442. flush_fifo_tx(msp);
  443. flush_fifo_rx(msp);
  444. msp->msp_state = MSP_STATE_CONFIGURED;
  445. return 0;
  446. }
  447. static void disable_msp_rx(struct ux500_msp *msp)
  448. {
  449. u32 reg_val_GCR, reg_val_DMACR, reg_val_IMSC;
  450. reg_val_GCR = readl(msp->registers + MSP_GCR);
  451. writel(reg_val_GCR & ~RX_ENABLE, msp->registers + MSP_GCR);
  452. reg_val_DMACR = readl(msp->registers + MSP_DMACR);
  453. writel(reg_val_DMACR & ~RX_DMA_ENABLE, msp->registers + MSP_DMACR);
  454. reg_val_IMSC = readl(msp->registers + MSP_IMSC);
  455. writel(reg_val_IMSC &
  456. ~(RX_SERVICE_INT | RX_OVERRUN_ERROR_INT),
  457. msp->registers + MSP_IMSC);
  458. msp->dir_busy &= ~MSP_DIR_RX;
  459. }
  460. static void disable_msp_tx(struct ux500_msp *msp)
  461. {
  462. u32 reg_val_GCR, reg_val_DMACR, reg_val_IMSC;
  463. reg_val_GCR = readl(msp->registers + MSP_GCR);
  464. writel(reg_val_GCR & ~TX_ENABLE, msp->registers + MSP_GCR);
  465. reg_val_DMACR = readl(msp->registers + MSP_DMACR);
  466. writel(reg_val_DMACR & ~TX_DMA_ENABLE, msp->registers + MSP_DMACR);
  467. reg_val_IMSC = readl(msp->registers + MSP_IMSC);
  468. writel(reg_val_IMSC &
  469. ~(TX_SERVICE_INT | TX_UNDERRUN_ERR_INT),
  470. msp->registers + MSP_IMSC);
  471. msp->dir_busy &= ~MSP_DIR_TX;
  472. }
  473. static int disable_msp(struct ux500_msp *msp, unsigned int dir)
  474. {
  475. u32 reg_val_GCR;
  476. int status = 0;
  477. unsigned int disable_tx, disable_rx;
  478. reg_val_GCR = readl(msp->registers + MSP_GCR);
  479. disable_tx = dir & MSP_DIR_TX;
  480. disable_rx = dir & MSP_DIR_TX;
  481. if (disable_tx && disable_rx) {
  482. reg_val_GCR = readl(msp->registers + MSP_GCR);
  483. writel(reg_val_GCR | LOOPBACK_MASK,
  484. msp->registers + MSP_GCR);
  485. /* Flush TX-FIFO */
  486. flush_fifo_tx(msp);
  487. /* Disable TX-channel */
  488. writel((readl(msp->registers + MSP_GCR) &
  489. (~TX_ENABLE)), msp->registers + MSP_GCR);
  490. /* Flush RX-FIFO */
  491. flush_fifo_rx(msp);
  492. /* Disable Loopback and Receive channel */
  493. writel((readl(msp->registers + MSP_GCR) &
  494. (~(RX_ENABLE | LOOPBACK_MASK))),
  495. msp->registers + MSP_GCR);
  496. disable_msp_tx(msp);
  497. disable_msp_rx(msp);
  498. } else if (disable_tx)
  499. disable_msp_tx(msp);
  500. else if (disable_rx)
  501. disable_msp_rx(msp);
  502. return status;
  503. }
  504. int ux500_msp_i2s_trigger(struct ux500_msp *msp, int cmd, int direction)
  505. {
  506. u32 reg_val_GCR, enable_bit;
  507. if (msp->msp_state == MSP_STATE_IDLE) {
  508. dev_err(msp->dev, "%s: ERROR: MSP is not configured!\n",
  509. __func__);
  510. return -EINVAL;
  511. }
  512. switch (cmd) {
  513. case SNDRV_PCM_TRIGGER_START:
  514. case SNDRV_PCM_TRIGGER_RESUME:
  515. case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
  516. if (direction == SNDRV_PCM_STREAM_PLAYBACK)
  517. enable_bit = TX_ENABLE;
  518. else
  519. enable_bit = RX_ENABLE;
  520. reg_val_GCR = readl(msp->registers + MSP_GCR);
  521. writel(reg_val_GCR | enable_bit, msp->registers + MSP_GCR);
  522. break;
  523. case SNDRV_PCM_TRIGGER_STOP:
  524. case SNDRV_PCM_TRIGGER_SUSPEND:
  525. case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
  526. if (direction == SNDRV_PCM_STREAM_PLAYBACK)
  527. disable_msp_tx(msp);
  528. else
  529. disable_msp_rx(msp);
  530. break;
  531. default:
  532. return -EINVAL;
  533. break;
  534. }
  535. return 0;
  536. }
  537. int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir)
  538. {
  539. int status = 0;
  540. dev_dbg(msp->dev, "%s: Enter (dir = 0x%01x).\n", __func__, dir);
  541. status = disable_msp(msp, dir);
  542. if (msp->dir_busy == 0) {
  543. /* disable sample rate and frame generators */
  544. msp->msp_state = MSP_STATE_IDLE;
  545. writel((readl(msp->registers + MSP_GCR) &
  546. (~(FRAME_GEN_ENABLE | SRG_ENABLE))),
  547. msp->registers + MSP_GCR);
  548. writel(0, msp->registers + MSP_GCR);
  549. writel(0, msp->registers + MSP_TCF);
  550. writel(0, msp->registers + MSP_RCF);
  551. writel(0, msp->registers + MSP_DMACR);
  552. writel(0, msp->registers + MSP_SRG);
  553. writel(0, msp->registers + MSP_MCR);
  554. writel(0, msp->registers + MSP_RCM);
  555. writel(0, msp->registers + MSP_RCV);
  556. writel(0, msp->registers + MSP_TCE0);
  557. writel(0, msp->registers + MSP_TCE1);
  558. writel(0, msp->registers + MSP_TCE2);
  559. writel(0, msp->registers + MSP_TCE3);
  560. writel(0, msp->registers + MSP_RCE0);
  561. writel(0, msp->registers + MSP_RCE1);
  562. writel(0, msp->registers + MSP_RCE2);
  563. writel(0, msp->registers + MSP_RCE3);
  564. }
  565. return status;
  566. }
  567. static int ux500_msp_i2s_of_init_msp(struct platform_device *pdev,
  568. struct ux500_msp *msp,
  569. struct msp_i2s_platform_data **platform_data)
  570. {
  571. struct msp_i2s_platform_data *pdata;
  572. *platform_data = devm_kzalloc(&pdev->dev,
  573. sizeof(struct msp_i2s_platform_data),
  574. GFP_KERNEL);
  575. pdata = *platform_data;
  576. if (!pdata)
  577. return -ENOMEM;
  578. msp->playback_dma_data.dma_cfg = devm_kzalloc(&pdev->dev,
  579. sizeof(struct stedma40_chan_cfg),
  580. GFP_KERNEL);
  581. if (!msp->playback_dma_data.dma_cfg)
  582. return -ENOMEM;
  583. msp->capture_dma_data.dma_cfg = devm_kzalloc(&pdev->dev,
  584. sizeof(struct stedma40_chan_cfg),
  585. GFP_KERNEL);
  586. if (!msp->capture_dma_data.dma_cfg)
  587. return -ENOMEM;
  588. return 0;
  589. }
  590. int ux500_msp_i2s_init_msp(struct platform_device *pdev,
  591. struct ux500_msp **msp_p,
  592. struct msp_i2s_platform_data *platform_data)
  593. {
  594. struct resource *res = NULL;
  595. struct device_node *np = pdev->dev.of_node;
  596. struct ux500_msp *msp;
  597. int ret;
  598. *msp_p = devm_kzalloc(&pdev->dev, sizeof(struct ux500_msp), GFP_KERNEL);
  599. msp = *msp_p;
  600. if (!msp)
  601. return -ENOMEM;
  602. if (!platform_data) {
  603. if (np) {
  604. ret = ux500_msp_i2s_of_init_msp(pdev, msp,
  605. &platform_data);
  606. if (ret)
  607. return ret;
  608. } else
  609. return -EINVAL;
  610. } else {
  611. msp->playback_dma_data.dma_cfg = platform_data->msp_i2s_dma_tx;
  612. msp->capture_dma_data.dma_cfg = platform_data->msp_i2s_dma_rx;
  613. msp->id = platform_data->id;
  614. }
  615. msp->dev = &pdev->dev;
  616. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  617. if (res == NULL) {
  618. dev_err(&pdev->dev, "%s: ERROR: Unable to get resource!\n",
  619. __func__);
  620. return -ENOMEM;
  621. }
  622. msp->playback_dma_data.tx_rx_addr = res->start + MSP_DR;
  623. msp->capture_dma_data.tx_rx_addr = res->start + MSP_DR;
  624. msp->registers = devm_ioremap(&pdev->dev, res->start,
  625. resource_size(res));
  626. if (msp->registers == NULL) {
  627. dev_err(&pdev->dev, "%s: ERROR: ioremap failed!\n", __func__);
  628. return -ENOMEM;
  629. }
  630. msp->msp_state = MSP_STATE_IDLE;
  631. msp->loopback_enable = 0;
  632. return 0;
  633. }
  634. void ux500_msp_i2s_cleanup_msp(struct platform_device *pdev,
  635. struct ux500_msp *msp)
  636. {
  637. dev_dbg(msp->dev, "%s: Enter (id = %d).\n", __func__, msp->id);
  638. }
  639. MODULE_LICENSE("GPL v2");