fsl_sai.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817
  1. /*
  2. * Freescale ALSA SoC Digital Audio Interface (SAI) driver.
  3. *
  4. * Copyright 2012-2015 Freescale Semiconductor, Inc.
  5. *
  6. * This program is free software, you can redistribute it and/or modify it
  7. * under the terms of the GNU General Public License as published by the
  8. * Free Software Foundation, either version 2 of the License, or(at your
  9. * option) any later version.
  10. *
  11. */
  12. #include <linux/clk.h>
  13. #include <linux/delay.h>
  14. #include <linux/dmaengine.h>
  15. #include <linux/module.h>
  16. #include <linux/of_address.h>
  17. #include <linux/regmap.h>
  18. #include <linux/slab.h>
  19. #include <sound/core.h>
  20. #include <sound/dmaengine_pcm.h>
  21. #include <sound/pcm_params.h>
  22. #include "fsl_sai.h"
  23. #include "imx-pcm.h"
  24. #define FSL_SAI_FLAGS (FSL_SAI_CSR_SEIE |\
  25. FSL_SAI_CSR_FEIE)
  26. static u32 fsl_sai_rates[] = {
  27. 8000, 11025, 12000, 16000, 22050,
  28. 24000, 32000, 44100, 48000, 64000,
  29. 88200, 96000, 176400, 192000
  30. };
  31. static struct snd_pcm_hw_constraint_list fsl_sai_rate_constraints = {
  32. .count = ARRAY_SIZE(fsl_sai_rates),
  33. .list = fsl_sai_rates,
  34. };
  35. static irqreturn_t fsl_sai_isr(int irq, void *devid)
  36. {
  37. struct fsl_sai *sai = (struct fsl_sai *)devid;
  38. struct device *dev = &sai->pdev->dev;
  39. u32 flags, xcsr, mask;
  40. bool irq_none = true;
  41. /*
  42. * Both IRQ status bits and IRQ mask bits are in the xCSR but
  43. * different shifts. And we here create a mask only for those
  44. * IRQs that we activated.
  45. */
  46. mask = (FSL_SAI_FLAGS >> FSL_SAI_CSR_xIE_SHIFT) << FSL_SAI_CSR_xF_SHIFT;
  47. /* Tx IRQ */
  48. regmap_read(sai->regmap, FSL_SAI_TCSR, &xcsr);
  49. flags = xcsr & mask;
  50. if (flags)
  51. irq_none = false;
  52. else
  53. goto irq_rx;
  54. if (flags & FSL_SAI_CSR_WSF)
  55. dev_dbg(dev, "isr: Start of Tx word detected\n");
  56. if (flags & FSL_SAI_CSR_SEF)
  57. dev_warn(dev, "isr: Tx Frame sync error detected\n");
  58. if (flags & FSL_SAI_CSR_FEF) {
  59. dev_warn(dev, "isr: Transmit underrun detected\n");
  60. /* FIFO reset for safety */
  61. xcsr |= FSL_SAI_CSR_FR;
  62. }
  63. if (flags & FSL_SAI_CSR_FWF)
  64. dev_dbg(dev, "isr: Enabled transmit FIFO is empty\n");
  65. if (flags & FSL_SAI_CSR_FRF)
  66. dev_dbg(dev, "isr: Transmit FIFO watermark has been reached\n");
  67. flags &= FSL_SAI_CSR_xF_W_MASK;
  68. xcsr &= ~FSL_SAI_CSR_xF_MASK;
  69. if (flags)
  70. regmap_write(sai->regmap, FSL_SAI_TCSR, flags | xcsr);
  71. irq_rx:
  72. /* Rx IRQ */
  73. regmap_read(sai->regmap, FSL_SAI_RCSR, &xcsr);
  74. flags = xcsr & mask;
  75. if (flags)
  76. irq_none = false;
  77. else
  78. goto out;
  79. if (flags & FSL_SAI_CSR_WSF)
  80. dev_dbg(dev, "isr: Start of Rx word detected\n");
  81. if (flags & FSL_SAI_CSR_SEF)
  82. dev_warn(dev, "isr: Rx Frame sync error detected\n");
  83. if (flags & FSL_SAI_CSR_FEF) {
  84. dev_warn(dev, "isr: Receive overflow detected\n");
  85. /* FIFO reset for safety */
  86. xcsr |= FSL_SAI_CSR_FR;
  87. }
  88. if (flags & FSL_SAI_CSR_FWF)
  89. dev_dbg(dev, "isr: Enabled receive FIFO is full\n");
  90. if (flags & FSL_SAI_CSR_FRF)
  91. dev_dbg(dev, "isr: Receive FIFO watermark has been reached\n");
  92. flags &= FSL_SAI_CSR_xF_W_MASK;
  93. xcsr &= ~FSL_SAI_CSR_xF_MASK;
  94. if (flags)
  95. regmap_write(sai->regmap, FSL_SAI_RCSR, flags | xcsr);
  96. out:
  97. if (irq_none)
  98. return IRQ_NONE;
  99. else
  100. return IRQ_HANDLED;
  101. }
  102. static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai,
  103. int clk_id, unsigned int freq, int fsl_dir)
  104. {
  105. struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
  106. bool tx = fsl_dir == FSL_FMT_TRANSMITTER;
  107. u32 val_cr2 = 0;
  108. switch (clk_id) {
  109. case FSL_SAI_CLK_BUS:
  110. val_cr2 |= FSL_SAI_CR2_MSEL_BUS;
  111. break;
  112. case FSL_SAI_CLK_MAST1:
  113. val_cr2 |= FSL_SAI_CR2_MSEL_MCLK1;
  114. break;
  115. case FSL_SAI_CLK_MAST2:
  116. val_cr2 |= FSL_SAI_CR2_MSEL_MCLK2;
  117. break;
  118. case FSL_SAI_CLK_MAST3:
  119. val_cr2 |= FSL_SAI_CR2_MSEL_MCLK3;
  120. break;
  121. default:
  122. return -EINVAL;
  123. }
  124. regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx),
  125. FSL_SAI_CR2_MSEL_MASK, val_cr2);
  126. return 0;
  127. }
  128. static int fsl_sai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
  129. int clk_id, unsigned int freq, int dir)
  130. {
  131. int ret;
  132. if (dir == SND_SOC_CLOCK_IN)
  133. return 0;
  134. ret = fsl_sai_set_dai_sysclk_tr(cpu_dai, clk_id, freq,
  135. FSL_FMT_TRANSMITTER);
  136. if (ret) {
  137. dev_err(cpu_dai->dev, "Cannot set tx sysclk: %d\n", ret);
  138. return ret;
  139. }
  140. ret = fsl_sai_set_dai_sysclk_tr(cpu_dai, clk_id, freq,
  141. FSL_FMT_RECEIVER);
  142. if (ret)
  143. dev_err(cpu_dai->dev, "Cannot set rx sysclk: %d\n", ret);
  144. return ret;
  145. }
  146. static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai,
  147. unsigned int fmt, int fsl_dir)
  148. {
  149. struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
  150. bool tx = fsl_dir == FSL_FMT_TRANSMITTER;
  151. u32 val_cr2 = 0, val_cr4 = 0;
  152. if (!sai->is_lsb_first)
  153. val_cr4 |= FSL_SAI_CR4_MF;
  154. /* DAI mode */
  155. switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
  156. case SND_SOC_DAIFMT_I2S:
  157. /*
  158. * Frame low, 1clk before data, one word length for frame sync,
  159. * frame sync starts one serial clock cycle earlier,
  160. * that is, together with the last bit of the previous
  161. * data word.
  162. */
  163. val_cr2 |= FSL_SAI_CR2_BCP;
  164. val_cr4 |= FSL_SAI_CR4_FSE | FSL_SAI_CR4_FSP;
  165. break;
  166. case SND_SOC_DAIFMT_LEFT_J:
  167. /*
  168. * Frame high, one word length for frame sync,
  169. * frame sync asserts with the first bit of the frame.
  170. */
  171. val_cr2 |= FSL_SAI_CR2_BCP;
  172. break;
  173. case SND_SOC_DAIFMT_DSP_A:
  174. /*
  175. * Frame high, 1clk before data, one bit for frame sync,
  176. * frame sync starts one serial clock cycle earlier,
  177. * that is, together with the last bit of the previous
  178. * data word.
  179. */
  180. val_cr2 |= FSL_SAI_CR2_BCP;
  181. val_cr4 |= FSL_SAI_CR4_FSE;
  182. sai->is_dsp_mode = true;
  183. break;
  184. case SND_SOC_DAIFMT_DSP_B:
  185. /*
  186. * Frame high, one bit for frame sync,
  187. * frame sync asserts with the first bit of the frame.
  188. */
  189. val_cr2 |= FSL_SAI_CR2_BCP;
  190. sai->is_dsp_mode = true;
  191. break;
  192. case SND_SOC_DAIFMT_RIGHT_J:
  193. /* To be done */
  194. default:
  195. return -EINVAL;
  196. }
  197. /* DAI clock inversion */
  198. switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
  199. case SND_SOC_DAIFMT_IB_IF:
  200. /* Invert both clocks */
  201. val_cr2 ^= FSL_SAI_CR2_BCP;
  202. val_cr4 ^= FSL_SAI_CR4_FSP;
  203. break;
  204. case SND_SOC_DAIFMT_IB_NF:
  205. /* Invert bit clock */
  206. val_cr2 ^= FSL_SAI_CR2_BCP;
  207. break;
  208. case SND_SOC_DAIFMT_NB_IF:
  209. /* Invert frame clock */
  210. val_cr4 ^= FSL_SAI_CR4_FSP;
  211. break;
  212. case SND_SOC_DAIFMT_NB_NF:
  213. /* Nothing to do for both normal cases */
  214. break;
  215. default:
  216. return -EINVAL;
  217. }
  218. /* DAI clock master masks */
  219. switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
  220. case SND_SOC_DAIFMT_CBS_CFS:
  221. val_cr2 |= FSL_SAI_CR2_BCD_MSTR;
  222. val_cr4 |= FSL_SAI_CR4_FSD_MSTR;
  223. break;
  224. case SND_SOC_DAIFMT_CBM_CFM:
  225. sai->is_slave_mode = true;
  226. break;
  227. case SND_SOC_DAIFMT_CBS_CFM:
  228. val_cr2 |= FSL_SAI_CR2_BCD_MSTR;
  229. break;
  230. case SND_SOC_DAIFMT_CBM_CFS:
  231. val_cr4 |= FSL_SAI_CR4_FSD_MSTR;
  232. sai->is_slave_mode = true;
  233. break;
  234. default:
  235. return -EINVAL;
  236. }
  237. regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx),
  238. FSL_SAI_CR2_BCP | FSL_SAI_CR2_BCD_MSTR, val_cr2);
  239. regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx),
  240. FSL_SAI_CR4_MF | FSL_SAI_CR4_FSE |
  241. FSL_SAI_CR4_FSP | FSL_SAI_CR4_FSD_MSTR, val_cr4);
  242. return 0;
  243. }
  244. static int fsl_sai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
  245. {
  246. int ret;
  247. ret = fsl_sai_set_dai_fmt_tr(cpu_dai, fmt, FSL_FMT_TRANSMITTER);
  248. if (ret) {
  249. dev_err(cpu_dai->dev, "Cannot set tx format: %d\n", ret);
  250. return ret;
  251. }
  252. ret = fsl_sai_set_dai_fmt_tr(cpu_dai, fmt, FSL_FMT_RECEIVER);
  253. if (ret)
  254. dev_err(cpu_dai->dev, "Cannot set rx format: %d\n", ret);
  255. return ret;
  256. }
  257. static int fsl_sai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq)
  258. {
  259. struct fsl_sai *sai = snd_soc_dai_get_drvdata(dai);
  260. unsigned long clk_rate;
  261. u32 savediv = 0, ratio, savesub = freq;
  262. u32 id;
  263. int ret = 0;
  264. /* Don't apply to slave mode */
  265. if (sai->is_slave_mode)
  266. return 0;
  267. for (id = 0; id < FSL_SAI_MCLK_MAX; id++) {
  268. clk_rate = clk_get_rate(sai->mclk_clk[id]);
  269. if (!clk_rate)
  270. continue;
  271. ratio = clk_rate / freq;
  272. ret = clk_rate - ratio * freq;
  273. /*
  274. * Drop the source that can not be
  275. * divided into the required rate.
  276. */
  277. if (ret != 0 && clk_rate / ret < 1000)
  278. continue;
  279. dev_dbg(dai->dev,
  280. "ratio %d for freq %dHz based on clock %ldHz\n",
  281. ratio, freq, clk_rate);
  282. if (ratio % 2 == 0 && ratio >= 2 && ratio <= 512)
  283. ratio /= 2;
  284. else
  285. continue;
  286. if (ret < savesub) {
  287. savediv = ratio;
  288. sai->mclk_id[tx] = id;
  289. savesub = ret;
  290. }
  291. if (ret == 0)
  292. break;
  293. }
  294. if (savediv == 0) {
  295. dev_err(dai->dev, "failed to derive required %cx rate: %d\n",
  296. tx ? 'T' : 'R', freq);
  297. return -EINVAL;
  298. }
  299. if ((tx && sai->synchronous[TX]) || (!tx && !sai->synchronous[RX])) {
  300. regmap_update_bits(sai->regmap, FSL_SAI_RCR2,
  301. FSL_SAI_CR2_MSEL_MASK,
  302. FSL_SAI_CR2_MSEL(sai->mclk_id[tx]));
  303. regmap_update_bits(sai->regmap, FSL_SAI_RCR2,
  304. FSL_SAI_CR2_DIV_MASK, savediv - 1);
  305. } else {
  306. regmap_update_bits(sai->regmap, FSL_SAI_TCR2,
  307. FSL_SAI_CR2_MSEL_MASK,
  308. FSL_SAI_CR2_MSEL(sai->mclk_id[tx]));
  309. regmap_update_bits(sai->regmap, FSL_SAI_TCR2,
  310. FSL_SAI_CR2_DIV_MASK, savediv - 1);
  311. }
  312. dev_dbg(dai->dev, "best fit: clock id=%d, div=%d, deviation =%d\n",
  313. sai->mclk_id[tx], savediv, savesub);
  314. return 0;
  315. }
  316. static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
  317. struct snd_pcm_hw_params *params,
  318. struct snd_soc_dai *cpu_dai)
  319. {
  320. struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
  321. bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
  322. unsigned int channels = params_channels(params);
  323. u32 word_width = snd_pcm_format_width(params_format(params));
  324. u32 val_cr4 = 0, val_cr5 = 0;
  325. int ret;
  326. if (!sai->is_slave_mode) {
  327. ret = fsl_sai_set_bclk(cpu_dai, tx,
  328. 2 * word_width * params_rate(params));
  329. if (ret)
  330. return ret;
  331. /* Do not enable the clock if it is already enabled */
  332. if (!(sai->mclk_streams & BIT(substream->stream))) {
  333. ret = clk_prepare_enable(sai->mclk_clk[sai->mclk_id[tx]]);
  334. if (ret)
  335. return ret;
  336. sai->mclk_streams |= BIT(substream->stream);
  337. }
  338. }
  339. if (!sai->is_dsp_mode)
  340. val_cr4 |= FSL_SAI_CR4_SYWD(word_width);
  341. val_cr5 |= FSL_SAI_CR5_WNW(word_width);
  342. val_cr5 |= FSL_SAI_CR5_W0W(word_width);
  343. if (sai->is_lsb_first)
  344. val_cr5 |= FSL_SAI_CR5_FBT(0);
  345. else
  346. val_cr5 |= FSL_SAI_CR5_FBT(word_width - 1);
  347. val_cr4 |= FSL_SAI_CR4_FRSZ(channels);
  348. regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx),
  349. FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK,
  350. val_cr4);
  351. regmap_update_bits(sai->regmap, FSL_SAI_xCR5(tx),
  352. FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK |
  353. FSL_SAI_CR5_FBT_MASK, val_cr5);
  354. regmap_write(sai->regmap, FSL_SAI_xMR(tx), ~0UL - ((1 << channels) - 1));
  355. return 0;
  356. }
  357. static int fsl_sai_hw_free(struct snd_pcm_substream *substream,
  358. struct snd_soc_dai *cpu_dai)
  359. {
  360. struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
  361. bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
  362. if (!sai->is_slave_mode &&
  363. sai->mclk_streams & BIT(substream->stream)) {
  364. clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[tx]]);
  365. sai->mclk_streams &= ~BIT(substream->stream);
  366. }
  367. return 0;
  368. }
  369. static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
  370. struct snd_soc_dai *cpu_dai)
  371. {
  372. struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
  373. bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
  374. u32 xcsr, count = 100;
  375. /*
  376. * Asynchronous mode: Clear SYNC for both Tx and Rx.
  377. * Rx sync with Tx clocks: Clear SYNC for Tx, set it for Rx.
  378. * Tx sync with Rx clocks: Clear SYNC for Rx, set it for Tx.
  379. */
  380. regmap_update_bits(sai->regmap, FSL_SAI_TCR2, FSL_SAI_CR2_SYNC, 0);
  381. regmap_update_bits(sai->regmap, FSL_SAI_RCR2, FSL_SAI_CR2_SYNC,
  382. sai->synchronous[RX] ? FSL_SAI_CR2_SYNC : 0);
  383. /*
  384. * It is recommended that the transmitter is the last enabled
  385. * and the first disabled.
  386. */
  387. switch (cmd) {
  388. case SNDRV_PCM_TRIGGER_START:
  389. case SNDRV_PCM_TRIGGER_RESUME:
  390. case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
  391. regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx),
  392. FSL_SAI_CSR_FRDE, FSL_SAI_CSR_FRDE);
  393. regmap_update_bits(sai->regmap, FSL_SAI_RCSR,
  394. FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE);
  395. regmap_update_bits(sai->regmap, FSL_SAI_TCSR,
  396. FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE);
  397. regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx),
  398. FSL_SAI_CSR_xIE_MASK, FSL_SAI_FLAGS);
  399. break;
  400. case SNDRV_PCM_TRIGGER_STOP:
  401. case SNDRV_PCM_TRIGGER_SUSPEND:
  402. case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
  403. regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx),
  404. FSL_SAI_CSR_FRDE, 0);
  405. regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx),
  406. FSL_SAI_CSR_xIE_MASK, 0);
  407. /* Check if the opposite FRDE is also disabled */
  408. regmap_read(sai->regmap, FSL_SAI_xCSR(!tx), &xcsr);
  409. if (!(xcsr & FSL_SAI_CSR_FRDE)) {
  410. /* Disable both directions and reset their FIFOs */
  411. regmap_update_bits(sai->regmap, FSL_SAI_TCSR,
  412. FSL_SAI_CSR_TERE, 0);
  413. regmap_update_bits(sai->regmap, FSL_SAI_RCSR,
  414. FSL_SAI_CSR_TERE, 0);
  415. /* TERE will remain set till the end of current frame */
  416. do {
  417. udelay(10);
  418. regmap_read(sai->regmap, FSL_SAI_xCSR(tx), &xcsr);
  419. } while (--count && xcsr & FSL_SAI_CSR_TERE);
  420. regmap_update_bits(sai->regmap, FSL_SAI_TCSR,
  421. FSL_SAI_CSR_FR, FSL_SAI_CSR_FR);
  422. regmap_update_bits(sai->regmap, FSL_SAI_RCSR,
  423. FSL_SAI_CSR_FR, FSL_SAI_CSR_FR);
  424. }
  425. break;
  426. default:
  427. return -EINVAL;
  428. }
  429. return 0;
  430. }
  431. static int fsl_sai_startup(struct snd_pcm_substream *substream,
  432. struct snd_soc_dai *cpu_dai)
  433. {
  434. struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
  435. bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
  436. struct device *dev = &sai->pdev->dev;
  437. int ret;
  438. ret = clk_prepare_enable(sai->bus_clk);
  439. if (ret) {
  440. dev_err(dev, "failed to enable bus clock: %d\n", ret);
  441. return ret;
  442. }
  443. regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE,
  444. FSL_SAI_CR3_TRCE);
  445. ret = snd_pcm_hw_constraint_list(substream->runtime, 0,
  446. SNDRV_PCM_HW_PARAM_RATE, &fsl_sai_rate_constraints);
  447. return ret;
  448. }
  449. static void fsl_sai_shutdown(struct snd_pcm_substream *substream,
  450. struct snd_soc_dai *cpu_dai)
  451. {
  452. struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
  453. bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
  454. regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE, 0);
  455. clk_disable_unprepare(sai->bus_clk);
  456. }
  457. static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = {
  458. .set_sysclk = fsl_sai_set_dai_sysclk,
  459. .set_fmt = fsl_sai_set_dai_fmt,
  460. .hw_params = fsl_sai_hw_params,
  461. .hw_free = fsl_sai_hw_free,
  462. .trigger = fsl_sai_trigger,
  463. .startup = fsl_sai_startup,
  464. .shutdown = fsl_sai_shutdown,
  465. };
  466. static int fsl_sai_dai_probe(struct snd_soc_dai *cpu_dai)
  467. {
  468. struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev);
  469. /* Software Reset for both Tx and Rx */
  470. regmap_write(sai->regmap, FSL_SAI_TCSR, FSL_SAI_CSR_SR);
  471. regmap_write(sai->regmap, FSL_SAI_RCSR, FSL_SAI_CSR_SR);
  472. /* Clear SR bit to finish the reset */
  473. regmap_write(sai->regmap, FSL_SAI_TCSR, 0);
  474. regmap_write(sai->regmap, FSL_SAI_RCSR, 0);
  475. regmap_update_bits(sai->regmap, FSL_SAI_TCR1, FSL_SAI_CR1_RFW_MASK,
  476. FSL_SAI_MAXBURST_TX * 2);
  477. regmap_update_bits(sai->regmap, FSL_SAI_RCR1, FSL_SAI_CR1_RFW_MASK,
  478. FSL_SAI_MAXBURST_RX - 1);
  479. snd_soc_dai_init_dma_data(cpu_dai, &sai->dma_params_tx,
  480. &sai->dma_params_rx);
  481. snd_soc_dai_set_drvdata(cpu_dai, sai);
  482. return 0;
  483. }
  484. static struct snd_soc_dai_driver fsl_sai_dai = {
  485. .probe = fsl_sai_dai_probe,
  486. .playback = {
  487. .stream_name = "CPU-Playback",
  488. .channels_min = 1,
  489. .channels_max = 2,
  490. .rate_min = 8000,
  491. .rate_max = 192000,
  492. .rates = SNDRV_PCM_RATE_KNOT,
  493. .formats = FSL_SAI_FORMATS,
  494. },
  495. .capture = {
  496. .stream_name = "CPU-Capture",
  497. .channels_min = 1,
  498. .channels_max = 2,
  499. .rate_min = 8000,
  500. .rate_max = 192000,
  501. .rates = SNDRV_PCM_RATE_KNOT,
  502. .formats = FSL_SAI_FORMATS,
  503. },
  504. .ops = &fsl_sai_pcm_dai_ops,
  505. };
  506. static const struct snd_soc_component_driver fsl_component = {
  507. .name = "fsl-sai",
  508. };
  509. static bool fsl_sai_readable_reg(struct device *dev, unsigned int reg)
  510. {
  511. switch (reg) {
  512. case FSL_SAI_TCSR:
  513. case FSL_SAI_TCR1:
  514. case FSL_SAI_TCR2:
  515. case FSL_SAI_TCR3:
  516. case FSL_SAI_TCR4:
  517. case FSL_SAI_TCR5:
  518. case FSL_SAI_TFR:
  519. case FSL_SAI_TMR:
  520. case FSL_SAI_RCSR:
  521. case FSL_SAI_RCR1:
  522. case FSL_SAI_RCR2:
  523. case FSL_SAI_RCR3:
  524. case FSL_SAI_RCR4:
  525. case FSL_SAI_RCR5:
  526. case FSL_SAI_RDR:
  527. case FSL_SAI_RFR:
  528. case FSL_SAI_RMR:
  529. return true;
  530. default:
  531. return false;
  532. }
  533. }
  534. static bool fsl_sai_volatile_reg(struct device *dev, unsigned int reg)
  535. {
  536. switch (reg) {
  537. case FSL_SAI_TFR:
  538. case FSL_SAI_RFR:
  539. case FSL_SAI_TDR:
  540. case FSL_SAI_RDR:
  541. return true;
  542. default:
  543. return false;
  544. }
  545. }
  546. static bool fsl_sai_writeable_reg(struct device *dev, unsigned int reg)
  547. {
  548. switch (reg) {
  549. case FSL_SAI_TCSR:
  550. case FSL_SAI_TCR1:
  551. case FSL_SAI_TCR2:
  552. case FSL_SAI_TCR3:
  553. case FSL_SAI_TCR4:
  554. case FSL_SAI_TCR5:
  555. case FSL_SAI_TDR:
  556. case FSL_SAI_TMR:
  557. case FSL_SAI_RCSR:
  558. case FSL_SAI_RCR1:
  559. case FSL_SAI_RCR2:
  560. case FSL_SAI_RCR3:
  561. case FSL_SAI_RCR4:
  562. case FSL_SAI_RCR5:
  563. case FSL_SAI_RMR:
  564. return true;
  565. default:
  566. return false;
  567. }
  568. }
  569. static const struct regmap_config fsl_sai_regmap_config = {
  570. .reg_bits = 32,
  571. .reg_stride = 4,
  572. .val_bits = 32,
  573. .max_register = FSL_SAI_RMR,
  574. .readable_reg = fsl_sai_readable_reg,
  575. .volatile_reg = fsl_sai_volatile_reg,
  576. .writeable_reg = fsl_sai_writeable_reg,
  577. };
  578. static int fsl_sai_probe(struct platform_device *pdev)
  579. {
  580. struct device_node *np = pdev->dev.of_node;
  581. struct fsl_sai *sai;
  582. struct resource *res;
  583. void __iomem *base;
  584. char tmp[8];
  585. int irq, ret, i;
  586. sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL);
  587. if (!sai)
  588. return -ENOMEM;
  589. sai->pdev = pdev;
  590. if (of_device_is_compatible(pdev->dev.of_node, "fsl,imx6sx-sai"))
  591. sai->sai_on_imx = true;
  592. sai->is_lsb_first = of_property_read_bool(np, "lsb-first");
  593. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  594. base = devm_ioremap_resource(&pdev->dev, res);
  595. if (IS_ERR(base))
  596. return PTR_ERR(base);
  597. sai->regmap = devm_regmap_init_mmio_clk(&pdev->dev,
  598. "bus", base, &fsl_sai_regmap_config);
  599. /* Compatible with old DTB cases */
  600. if (IS_ERR(sai->regmap))
  601. sai->regmap = devm_regmap_init_mmio_clk(&pdev->dev,
  602. "sai", base, &fsl_sai_regmap_config);
  603. if (IS_ERR(sai->regmap)) {
  604. dev_err(&pdev->dev, "regmap init failed\n");
  605. return PTR_ERR(sai->regmap);
  606. }
  607. /* No error out for old DTB cases but only mark the clock NULL */
  608. sai->bus_clk = devm_clk_get(&pdev->dev, "bus");
  609. if (IS_ERR(sai->bus_clk)) {
  610. dev_err(&pdev->dev, "failed to get bus clock: %ld\n",
  611. PTR_ERR(sai->bus_clk));
  612. sai->bus_clk = NULL;
  613. }
  614. sai->mclk_clk[0] = sai->bus_clk;
  615. for (i = 1; i < FSL_SAI_MCLK_MAX; i++) {
  616. sprintf(tmp, "mclk%d", i);
  617. sai->mclk_clk[i] = devm_clk_get(&pdev->dev, tmp);
  618. if (IS_ERR(sai->mclk_clk[i])) {
  619. dev_err(&pdev->dev, "failed to get mclk%d clock: %ld\n",
  620. i + 1, PTR_ERR(sai->mclk_clk[i]));
  621. sai->mclk_clk[i] = NULL;
  622. }
  623. }
  624. irq = platform_get_irq(pdev, 0);
  625. if (irq < 0) {
  626. dev_err(&pdev->dev, "no irq for node %s\n", pdev->name);
  627. return irq;
  628. }
  629. ret = devm_request_irq(&pdev->dev, irq, fsl_sai_isr, 0, np->name, sai);
  630. if (ret) {
  631. dev_err(&pdev->dev, "failed to claim irq %u\n", irq);
  632. return ret;
  633. }
  634. /* Sync Tx with Rx as default by following old DT binding */
  635. sai->synchronous[RX] = true;
  636. sai->synchronous[TX] = false;
  637. fsl_sai_dai.symmetric_rates = 1;
  638. fsl_sai_dai.symmetric_channels = 1;
  639. fsl_sai_dai.symmetric_samplebits = 1;
  640. if (of_find_property(np, "fsl,sai-synchronous-rx", NULL) &&
  641. of_find_property(np, "fsl,sai-asynchronous", NULL)) {
  642. /* error out if both synchronous and asynchronous are present */
  643. dev_err(&pdev->dev, "invalid binding for synchronous mode\n");
  644. return -EINVAL;
  645. }
  646. if (of_find_property(np, "fsl,sai-synchronous-rx", NULL)) {
  647. /* Sync Rx with Tx */
  648. sai->synchronous[RX] = false;
  649. sai->synchronous[TX] = true;
  650. } else if (of_find_property(np, "fsl,sai-asynchronous", NULL)) {
  651. /* Discard all settings for asynchronous mode */
  652. sai->synchronous[RX] = false;
  653. sai->synchronous[TX] = false;
  654. fsl_sai_dai.symmetric_rates = 0;
  655. fsl_sai_dai.symmetric_channels = 0;
  656. fsl_sai_dai.symmetric_samplebits = 0;
  657. }
  658. sai->dma_params_rx.addr = res->start + FSL_SAI_RDR;
  659. sai->dma_params_tx.addr = res->start + FSL_SAI_TDR;
  660. sai->dma_params_rx.maxburst = FSL_SAI_MAXBURST_RX;
  661. sai->dma_params_tx.maxburst = FSL_SAI_MAXBURST_TX;
  662. platform_set_drvdata(pdev, sai);
  663. ret = devm_snd_soc_register_component(&pdev->dev, &fsl_component,
  664. &fsl_sai_dai, 1);
  665. if (ret)
  666. return ret;
  667. if (sai->sai_on_imx)
  668. return imx_pcm_dma_init(pdev, IMX_SAI_DMABUF_SIZE);
  669. else
  670. return devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
  671. }
  672. static const struct of_device_id fsl_sai_ids[] = {
  673. { .compatible = "fsl,vf610-sai", },
  674. { .compatible = "fsl,imx6sx-sai", },
  675. { /* sentinel */ }
  676. };
  677. static struct platform_driver fsl_sai_driver = {
  678. .probe = fsl_sai_probe,
  679. .driver = {
  680. .name = "fsl-sai",
  681. .of_match_table = fsl_sai_ids,
  682. },
  683. };
  684. module_platform_driver(fsl_sai_driver);
  685. MODULE_DESCRIPTION("Freescale Soc SAI Interface");
  686. MODULE_AUTHOR("Xiubo Li, <Li.Xiubo@freescale.com>");
  687. MODULE_ALIAS("platform:fsl-sai");
  688. MODULE_LICENSE("GPL");