fsl_esai.c 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216
  1. // SPDX-License-Identifier: GPL-2.0
  2. //
  3. // Freescale ESAI ALSA SoC Digital Audio Interface (DAI) driver
  4. //
  5. // Copyright (C) 2014 Freescale Semiconductor, Inc.
  6. #include <linux/clk.h>
  7. #include <linux/dmaengine.h>
  8. #include <linux/module.h>
  9. #include <linux/of_irq.h>
  10. #include <linux/of_platform.h>
  11. #include <linux/pm_runtime.h>
  12. #include <sound/dmaengine_pcm.h>
  13. #include <sound/pcm_params.h>
  14. #include "fsl_esai.h"
  15. #include "imx-pcm.h"
  16. #define FSL_ESAI_FORMATS (SNDRV_PCM_FMTBIT_S8 | \
  17. SNDRV_PCM_FMTBIT_S16_LE | \
  18. SNDRV_PCM_FMTBIT_S20_3LE | \
  19. SNDRV_PCM_FMTBIT_S24_LE)
  20. /**
  21. * struct fsl_esai_soc_data - soc specific data
  22. * @reset_at_xrun: flags for enable reset operaton
  23. */
  24. struct fsl_esai_soc_data {
  25. bool reset_at_xrun;
  26. };
  27. /**
  28. * struct fsl_esai - ESAI private data
  29. * @dma_params_rx: DMA parameters for receive channel
  30. * @dma_params_tx: DMA parameters for transmit channel
  31. * @pdev: platform device pointer
  32. * @regmap: regmap handler
  33. * @coreclk: clock source to access register
  34. * @extalclk: esai clock source to derive HCK, SCK and FS
  35. * @fsysclk: system clock source to derive HCK, SCK and FS
  36. * @spbaclk: SPBA clock (optional, depending on SoC design)
  37. * @work: work to handle the reset operation
  38. * @soc: soc specific data
  39. * @lock: spin lock between hw_reset() and trigger()
  40. * @fifo_depth: depth of tx/rx FIFO
  41. * @slot_width: width of each DAI slot
  42. * @slots: number of slots
  43. * @tx_mask: slot mask for TX
  44. * @rx_mask: slot mask for RX
  45. * @channels: channel num for tx or rx
  46. * @hck_rate: clock rate of desired HCKx clock
  47. * @sck_rate: clock rate of desired SCKx clock
  48. * @hck_dir: the direction of HCKx pads
  49. * @sck_div: if using PSR/PM dividers for SCKx clock
  50. * @consumer_mode: if fully using DAI clock consumer mode
  51. * @synchronous: if using tx/rx synchronous mode
  52. * @name: driver name
  53. */
  54. struct fsl_esai {
  55. struct snd_dmaengine_dai_dma_data dma_params_rx;
  56. struct snd_dmaengine_dai_dma_data dma_params_tx;
  57. struct platform_device *pdev;
  58. struct regmap *regmap;
  59. struct clk *coreclk;
  60. struct clk *extalclk;
  61. struct clk *fsysclk;
  62. struct clk *spbaclk;
  63. struct work_struct work;
  64. const struct fsl_esai_soc_data *soc;
  65. spinlock_t lock; /* Protect hw_reset and trigger */
  66. u32 fifo_depth;
  67. u32 slot_width;
  68. u32 slots;
  69. u32 tx_mask;
  70. u32 rx_mask;
  71. u32 channels[2];
  72. u32 hck_rate[2];
  73. u32 sck_rate[2];
  74. bool hck_dir[2];
  75. bool sck_div[2];
  76. bool consumer_mode;
  77. bool synchronous;
  78. char name[32];
  79. };
  80. static struct fsl_esai_soc_data fsl_esai_vf610 = {
  81. .reset_at_xrun = true,
  82. };
  83. static struct fsl_esai_soc_data fsl_esai_imx35 = {
  84. .reset_at_xrun = true,
  85. };
  86. static struct fsl_esai_soc_data fsl_esai_imx6ull = {
  87. .reset_at_xrun = false,
  88. };
  89. static irqreturn_t esai_isr(int irq, void *devid)
  90. {
  91. struct fsl_esai *esai_priv = (struct fsl_esai *)devid;
  92. struct platform_device *pdev = esai_priv->pdev;
  93. u32 esr;
  94. u32 saisr;
  95. regmap_read(esai_priv->regmap, REG_ESAI_ESR, &esr);
  96. regmap_read(esai_priv->regmap, REG_ESAI_SAISR, &saisr);
  97. if ((saisr & (ESAI_SAISR_TUE | ESAI_SAISR_ROE)) &&
  98. esai_priv->soc->reset_at_xrun) {
  99. dev_dbg(&pdev->dev, "reset module for xrun\n");
  100. regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR,
  101. ESAI_xCR_xEIE_MASK, 0);
  102. regmap_update_bits(esai_priv->regmap, REG_ESAI_RCR,
  103. ESAI_xCR_xEIE_MASK, 0);
  104. schedule_work(&esai_priv->work);
  105. }
  106. if (esr & ESAI_ESR_TINIT_MASK)
  107. dev_dbg(&pdev->dev, "isr: Transmission Initialized\n");
  108. if (esr & ESAI_ESR_RFF_MASK)
  109. dev_warn(&pdev->dev, "isr: Receiving overrun\n");
  110. if (esr & ESAI_ESR_TFE_MASK)
  111. dev_warn(&pdev->dev, "isr: Transmission underrun\n");
  112. if (esr & ESAI_ESR_TLS_MASK)
  113. dev_dbg(&pdev->dev, "isr: Just transmitted the last slot\n");
  114. if (esr & ESAI_ESR_TDE_MASK)
  115. dev_dbg(&pdev->dev, "isr: Transmission data exception\n");
  116. if (esr & ESAI_ESR_TED_MASK)
  117. dev_dbg(&pdev->dev, "isr: Transmitting even slots\n");
  118. if (esr & ESAI_ESR_TD_MASK)
  119. dev_dbg(&pdev->dev, "isr: Transmitting data\n");
  120. if (esr & ESAI_ESR_RLS_MASK)
  121. dev_dbg(&pdev->dev, "isr: Just received the last slot\n");
  122. if (esr & ESAI_ESR_RDE_MASK)
  123. dev_dbg(&pdev->dev, "isr: Receiving data exception\n");
  124. if (esr & ESAI_ESR_RED_MASK)
  125. dev_dbg(&pdev->dev, "isr: Receiving even slots\n");
  126. if (esr & ESAI_ESR_RD_MASK)
  127. dev_dbg(&pdev->dev, "isr: Receiving data\n");
  128. return IRQ_HANDLED;
  129. }
  130. /**
  131. * fsl_esai_divisor_cal - This function is used to calculate the
  132. * divisors of psr, pm, fp and it is supposed to be called in
  133. * set_dai_sysclk() and set_bclk().
  134. *
  135. * @dai: pointer to DAI
  136. * @tx: current setting is for playback or capture
  137. * @ratio: desired overall ratio for the paticipating dividers
  138. * @usefp: for HCK setting, there is no need to set fp divider
  139. * @fp: bypass other dividers by setting fp directly if fp != 0
  140. */
  141. static int fsl_esai_divisor_cal(struct snd_soc_dai *dai, bool tx, u32 ratio,
  142. bool usefp, u32 fp)
  143. {
  144. struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
  145. u32 psr, pm = 999, maxfp, prod, sub, savesub, i, j;
  146. maxfp = usefp ? 16 : 1;
  147. if (usefp && fp)
  148. goto out_fp;
  149. if (ratio > 2 * 8 * 256 * maxfp || ratio < 2) {
  150. dev_err(dai->dev, "the ratio is out of range (2 ~ %d)\n",
  151. 2 * 8 * 256 * maxfp);
  152. return -EINVAL;
  153. } else if (ratio % 2) {
  154. dev_err(dai->dev, "the raio must be even if using upper divider\n");
  155. return -EINVAL;
  156. }
  157. ratio /= 2;
  158. psr = ratio <= 256 * maxfp ? ESAI_xCCR_xPSR_BYPASS : ESAI_xCCR_xPSR_DIV8;
  159. /* Do not loop-search if PM (1 ~ 256) alone can serve the ratio */
  160. if (ratio <= 256) {
  161. pm = ratio;
  162. fp = 1;
  163. goto out;
  164. }
  165. /* Set the max fluctuation -- 0.1% of the max devisor */
  166. savesub = (psr ? 1 : 8) * 256 * maxfp / 1000;
  167. /* Find the best value for PM */
  168. for (i = 1; i <= 256; i++) {
  169. for (j = 1; j <= maxfp; j++) {
  170. /* PSR (1 or 8) * PM (1 ~ 256) * FP (1 ~ 16) */
  171. prod = (psr ? 1 : 8) * i * j;
  172. if (prod == ratio)
  173. sub = 0;
  174. else if (prod / ratio == 1)
  175. sub = prod - ratio;
  176. else if (ratio / prod == 1)
  177. sub = ratio - prod;
  178. else
  179. continue;
  180. /* Calculate the fraction */
  181. sub = sub * 1000 / ratio;
  182. if (sub < savesub) {
  183. savesub = sub;
  184. pm = i;
  185. fp = j;
  186. }
  187. /* We are lucky */
  188. if (savesub == 0)
  189. goto out;
  190. }
  191. }
  192. if (pm == 999) {
  193. dev_err(dai->dev, "failed to calculate proper divisors\n");
  194. return -EINVAL;
  195. }
  196. out:
  197. regmap_update_bits(esai_priv->regmap, REG_ESAI_xCCR(tx),
  198. ESAI_xCCR_xPSR_MASK | ESAI_xCCR_xPM_MASK,
  199. psr | ESAI_xCCR_xPM(pm));
  200. out_fp:
  201. /* Bypass fp if not being required */
  202. if (maxfp <= 1)
  203. return 0;
  204. regmap_update_bits(esai_priv->regmap, REG_ESAI_xCCR(tx),
  205. ESAI_xCCR_xFP_MASK, ESAI_xCCR_xFP(fp));
  206. return 0;
  207. }
  208. /**
  209. * fsl_esai_set_dai_sysclk - configure the clock frequency of MCLK (HCKT/HCKR)
  210. * @dai: pointer to DAI
  211. * @clk_id: The clock source of HCKT/HCKR
  212. * (Input from outside; output from inside, FSYS or EXTAL)
  213. * @freq: The required clock rate of HCKT/HCKR
  214. * @dir: The clock direction of HCKT/HCKR
  215. *
  216. * Note: If the direction is input, we do not care about clk_id.
  217. */
  218. static int fsl_esai_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
  219. unsigned int freq, int dir)
  220. {
  221. struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
  222. struct clk *clksrc = esai_priv->extalclk;
  223. bool tx = (clk_id <= ESAI_HCKT_EXTAL || esai_priv->synchronous);
  224. bool in = dir == SND_SOC_CLOCK_IN;
  225. u32 ratio, ecr = 0;
  226. unsigned long clk_rate;
  227. int ret;
  228. if (freq == 0) {
  229. dev_err(dai->dev, "%sput freq of HCK%c should not be 0Hz\n",
  230. in ? "in" : "out", tx ? 'T' : 'R');
  231. return -EINVAL;
  232. }
  233. /* Bypass divider settings if the requirement doesn't change */
  234. if (freq == esai_priv->hck_rate[tx] && dir == esai_priv->hck_dir[tx])
  235. return 0;
  236. /* sck_div can be only bypassed if ETO/ERO=0 and SNC_SOC_CLOCK_OUT */
  237. esai_priv->sck_div[tx] = true;
  238. /* Set the direction of HCKT/HCKR pins */
  239. regmap_update_bits(esai_priv->regmap, REG_ESAI_xCCR(tx),
  240. ESAI_xCCR_xHCKD, in ? 0 : ESAI_xCCR_xHCKD);
  241. if (in)
  242. goto out;
  243. switch (clk_id) {
  244. case ESAI_HCKT_FSYS:
  245. case ESAI_HCKR_FSYS:
  246. clksrc = esai_priv->fsysclk;
  247. break;
  248. case ESAI_HCKT_EXTAL:
  249. ecr |= ESAI_ECR_ETI;
  250. break;
  251. case ESAI_HCKR_EXTAL:
  252. ecr |= esai_priv->synchronous ? ESAI_ECR_ETI : ESAI_ECR_ERI;
  253. break;
  254. default:
  255. return -EINVAL;
  256. }
  257. if (IS_ERR(clksrc)) {
  258. dev_err(dai->dev, "no assigned %s clock\n",
  259. (clk_id % 2) ? "extal" : "fsys");
  260. return PTR_ERR(clksrc);
  261. }
  262. clk_rate = clk_get_rate(clksrc);
  263. ratio = clk_rate / freq;
  264. if (ratio * freq > clk_rate)
  265. ret = ratio * freq - clk_rate;
  266. else if (ratio * freq < clk_rate)
  267. ret = clk_rate - ratio * freq;
  268. else
  269. ret = 0;
  270. /* Block if clock source can not be divided into the required rate */
  271. if (ret != 0 && clk_rate / ret < 1000) {
  272. dev_err(dai->dev, "failed to derive required HCK%c rate\n",
  273. tx ? 'T' : 'R');
  274. return -EINVAL;
  275. }
  276. /* Only EXTAL source can be output directly without using PSR and PM */
  277. if (ratio == 1 && clksrc == esai_priv->extalclk) {
  278. /* Bypass all the dividers if not being needed */
  279. ecr |= tx ? ESAI_ECR_ETO : ESAI_ECR_ERO;
  280. goto out;
  281. } else if (ratio < 2) {
  282. /* The ratio should be no less than 2 if using other sources */
  283. dev_err(dai->dev, "failed to derive required HCK%c rate\n",
  284. tx ? 'T' : 'R');
  285. return -EINVAL;
  286. }
  287. ret = fsl_esai_divisor_cal(dai, tx, ratio, false, 0);
  288. if (ret)
  289. return ret;
  290. esai_priv->sck_div[tx] = false;
  291. out:
  292. esai_priv->hck_dir[tx] = dir;
  293. esai_priv->hck_rate[tx] = freq;
  294. regmap_update_bits(esai_priv->regmap, REG_ESAI_ECR,
  295. tx ? ESAI_ECR_ETI | ESAI_ECR_ETO :
  296. ESAI_ECR_ERI | ESAI_ECR_ERO, ecr);
  297. return 0;
  298. }
  299. /**
  300. * fsl_esai_set_bclk - configure the related dividers according to the bclk rate
  301. * @dai: pointer to DAI
  302. * @tx: direction boolean
  303. * @freq: bclk freq
  304. */
  305. static int fsl_esai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq)
  306. {
  307. struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
  308. u32 hck_rate = esai_priv->hck_rate[tx];
  309. u32 sub, ratio = hck_rate / freq;
  310. int ret;
  311. /* Don't apply for fully consumer mode or unchanged bclk */
  312. if (esai_priv->consumer_mode || esai_priv->sck_rate[tx] == freq)
  313. return 0;
  314. if (ratio * freq > hck_rate)
  315. sub = ratio * freq - hck_rate;
  316. else if (ratio * freq < hck_rate)
  317. sub = hck_rate - ratio * freq;
  318. else
  319. sub = 0;
  320. /* Block if clock source can not be divided into the required rate */
  321. if (sub != 0 && hck_rate / sub < 1000) {
  322. dev_err(dai->dev, "failed to derive required SCK%c rate\n",
  323. tx ? 'T' : 'R');
  324. return -EINVAL;
  325. }
  326. /* The ratio should be contented by FP alone if bypassing PM and PSR */
  327. if (!esai_priv->sck_div[tx] && (ratio > 16 || ratio == 0)) {
  328. dev_err(dai->dev, "the ratio is out of range (1 ~ 16)\n");
  329. return -EINVAL;
  330. }
  331. ret = fsl_esai_divisor_cal(dai, tx, ratio, true,
  332. esai_priv->sck_div[tx] ? 0 : ratio);
  333. if (ret)
  334. return ret;
  335. /* Save current bclk rate */
  336. esai_priv->sck_rate[tx] = freq;
  337. return 0;
  338. }
  339. static int fsl_esai_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask,
  340. u32 rx_mask, int slots, int slot_width)
  341. {
  342. struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
  343. regmap_update_bits(esai_priv->regmap, REG_ESAI_TCCR,
  344. ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(slots));
  345. regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR,
  346. ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(slots));
  347. esai_priv->slot_width = slot_width;
  348. esai_priv->slots = slots;
  349. esai_priv->tx_mask = tx_mask;
  350. esai_priv->rx_mask = rx_mask;
  351. return 0;
  352. }
  353. static int fsl_esai_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
  354. {
  355. struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
  356. u32 xcr = 0, xccr = 0, mask;
  357. /* DAI mode */
  358. switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
  359. case SND_SOC_DAIFMT_I2S:
  360. /* Data on rising edge of bclk, frame low, 1clk before data */
  361. xcr |= ESAI_xCR_xFSR;
  362. xccr |= ESAI_xCCR_xFSP | ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP;
  363. break;
  364. case SND_SOC_DAIFMT_LEFT_J:
  365. /* Data on rising edge of bclk, frame high */
  366. xccr |= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP;
  367. break;
  368. case SND_SOC_DAIFMT_RIGHT_J:
  369. /* Data on rising edge of bclk, frame high, right aligned */
  370. xccr |= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP;
  371. xcr |= ESAI_xCR_xWA;
  372. break;
  373. case SND_SOC_DAIFMT_DSP_A:
  374. /* Data on rising edge of bclk, frame high, 1clk before data */
  375. xcr |= ESAI_xCR_xFSL | ESAI_xCR_xFSR;
  376. xccr |= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP;
  377. break;
  378. case SND_SOC_DAIFMT_DSP_B:
  379. /* Data on rising edge of bclk, frame high */
  380. xcr |= ESAI_xCR_xFSL;
  381. xccr |= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP;
  382. break;
  383. default:
  384. return -EINVAL;
  385. }
  386. /* DAI clock inversion */
  387. switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
  388. case SND_SOC_DAIFMT_NB_NF:
  389. /* Nothing to do for both normal cases */
  390. break;
  391. case SND_SOC_DAIFMT_IB_NF:
  392. /* Invert bit clock */
  393. xccr ^= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP;
  394. break;
  395. case SND_SOC_DAIFMT_NB_IF:
  396. /* Invert frame clock */
  397. xccr ^= ESAI_xCCR_xFSP;
  398. break;
  399. case SND_SOC_DAIFMT_IB_IF:
  400. /* Invert both clocks */
  401. xccr ^= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP | ESAI_xCCR_xFSP;
  402. break;
  403. default:
  404. return -EINVAL;
  405. }
  406. esai_priv->consumer_mode = false;
  407. /* DAI clock provider masks */
  408. switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
  409. case SND_SOC_DAIFMT_BC_FC:
  410. esai_priv->consumer_mode = true;
  411. break;
  412. case SND_SOC_DAIFMT_BP_FC:
  413. xccr |= ESAI_xCCR_xCKD;
  414. break;
  415. case SND_SOC_DAIFMT_BC_FP:
  416. xccr |= ESAI_xCCR_xFSD;
  417. break;
  418. case SND_SOC_DAIFMT_BP_FP:
  419. xccr |= ESAI_xCCR_xFSD | ESAI_xCCR_xCKD;
  420. break;
  421. default:
  422. return -EINVAL;
  423. }
  424. mask = ESAI_xCR_xFSL | ESAI_xCR_xFSR | ESAI_xCR_xWA;
  425. regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR, mask, xcr);
  426. regmap_update_bits(esai_priv->regmap, REG_ESAI_RCR, mask, xcr);
  427. mask = ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP | ESAI_xCCR_xFSP |
  428. ESAI_xCCR_xFSD | ESAI_xCCR_xCKD;
  429. regmap_update_bits(esai_priv->regmap, REG_ESAI_TCCR, mask, xccr);
  430. regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR, mask, xccr);
  431. return 0;
  432. }
  433. static int fsl_esai_startup(struct snd_pcm_substream *substream,
  434. struct snd_soc_dai *dai)
  435. {
  436. struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
  437. if (!snd_soc_dai_active(dai)) {
  438. /* Set synchronous mode */
  439. regmap_update_bits(esai_priv->regmap, REG_ESAI_SAICR,
  440. ESAI_SAICR_SYNC, esai_priv->synchronous ?
  441. ESAI_SAICR_SYNC : 0);
  442. /* Set slots count */
  443. regmap_update_bits(esai_priv->regmap, REG_ESAI_TCCR,
  444. ESAI_xCCR_xDC_MASK,
  445. ESAI_xCCR_xDC(esai_priv->slots));
  446. regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR,
  447. ESAI_xCCR_xDC_MASK,
  448. ESAI_xCCR_xDC(esai_priv->slots));
  449. }
  450. return 0;
  451. }
  452. static int fsl_esai_hw_params(struct snd_pcm_substream *substream,
  453. struct snd_pcm_hw_params *params,
  454. struct snd_soc_dai *dai)
  455. {
  456. struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
  457. bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
  458. u32 width = params_width(params);
  459. u32 channels = params_channels(params);
  460. u32 pins = DIV_ROUND_UP(channels, esai_priv->slots);
  461. u32 slot_width = width;
  462. u32 bclk, mask, val;
  463. int ret;
  464. /* Override slot_width if being specifically set */
  465. if (esai_priv->slot_width)
  466. slot_width = esai_priv->slot_width;
  467. bclk = params_rate(params) * slot_width * esai_priv->slots;
  468. ret = fsl_esai_set_bclk(dai, esai_priv->synchronous || tx, bclk);
  469. if (ret)
  470. return ret;
  471. mask = ESAI_xCR_xSWS_MASK;
  472. val = ESAI_xCR_xSWS(slot_width, width);
  473. regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx), mask, val);
  474. /* Recording in synchronous mode needs to set TCR also */
  475. if (!tx && esai_priv->synchronous)
  476. regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR, mask, val);
  477. /* Use Normal mode to support monaural audio */
  478. regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
  479. ESAI_xCR_xMOD_MASK, params_channels(params) > 1 ?
  480. ESAI_xCR_xMOD_NETWORK : 0);
  481. regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx),
  482. ESAI_xFCR_xFR_MASK, ESAI_xFCR_xFR);
  483. mask = ESAI_xFCR_xFR_MASK | ESAI_xFCR_xWA_MASK | ESAI_xFCR_xFWM_MASK |
  484. (tx ? ESAI_xFCR_TE_MASK | ESAI_xFCR_TIEN : ESAI_xFCR_RE_MASK);
  485. val = ESAI_xFCR_xWA(width) | ESAI_xFCR_xFWM(esai_priv->fifo_depth) |
  486. (tx ? ESAI_xFCR_TE(pins) | ESAI_xFCR_TIEN : ESAI_xFCR_RE(pins));
  487. regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx), mask, val);
  488. if (tx)
  489. regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR,
  490. ESAI_xCR_PADC, ESAI_xCR_PADC);
  491. /* Remove ESAI personal reset by configuring ESAI_PCRC and ESAI_PRRC */
  492. regmap_update_bits(esai_priv->regmap, REG_ESAI_PRRC,
  493. ESAI_PRRC_PDC_MASK, ESAI_PRRC_PDC(ESAI_GPIO));
  494. regmap_update_bits(esai_priv->regmap, REG_ESAI_PCRC,
  495. ESAI_PCRC_PC_MASK, ESAI_PCRC_PC(ESAI_GPIO));
  496. return 0;
  497. }
  498. static int fsl_esai_hw_init(struct fsl_esai *esai_priv)
  499. {
  500. struct platform_device *pdev = esai_priv->pdev;
  501. int ret;
  502. /* Reset ESAI unit */
  503. ret = regmap_update_bits(esai_priv->regmap, REG_ESAI_ECR,
  504. ESAI_ECR_ESAIEN_MASK | ESAI_ECR_ERST_MASK,
  505. ESAI_ECR_ESAIEN | ESAI_ECR_ERST);
  506. if (ret) {
  507. dev_err(&pdev->dev, "failed to reset ESAI: %d\n", ret);
  508. return ret;
  509. }
  510. /*
  511. * We need to enable ESAI so as to access some of its registers.
  512. * Otherwise, we would fail to dump regmap from user space.
  513. */
  514. ret = regmap_update_bits(esai_priv->regmap, REG_ESAI_ECR,
  515. ESAI_ECR_ESAIEN_MASK | ESAI_ECR_ERST_MASK,
  516. ESAI_ECR_ESAIEN);
  517. if (ret) {
  518. dev_err(&pdev->dev, "failed to enable ESAI: %d\n", ret);
  519. return ret;
  520. }
  521. regmap_update_bits(esai_priv->regmap, REG_ESAI_PRRC,
  522. ESAI_PRRC_PDC_MASK, 0);
  523. regmap_update_bits(esai_priv->regmap, REG_ESAI_PCRC,
  524. ESAI_PCRC_PC_MASK, 0);
  525. return 0;
  526. }
  527. static int fsl_esai_register_restore(struct fsl_esai *esai_priv)
  528. {
  529. int ret;
  530. /* FIFO reset for safety */
  531. regmap_update_bits(esai_priv->regmap, REG_ESAI_TFCR,
  532. ESAI_xFCR_xFR, ESAI_xFCR_xFR);
  533. regmap_update_bits(esai_priv->regmap, REG_ESAI_RFCR,
  534. ESAI_xFCR_xFR, ESAI_xFCR_xFR);
  535. regcache_mark_dirty(esai_priv->regmap);
  536. ret = regcache_sync(esai_priv->regmap);
  537. if (ret)
  538. return ret;
  539. /* FIFO reset done */
  540. regmap_update_bits(esai_priv->regmap, REG_ESAI_TFCR, ESAI_xFCR_xFR, 0);
  541. regmap_update_bits(esai_priv->regmap, REG_ESAI_RFCR, ESAI_xFCR_xFR, 0);
  542. return 0;
  543. }
  544. static void fsl_esai_trigger_start(struct fsl_esai *esai_priv, bool tx)
  545. {
  546. u8 i, channels = esai_priv->channels[tx];
  547. u32 pins = DIV_ROUND_UP(channels, esai_priv->slots);
  548. u32 mask;
  549. regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx),
  550. ESAI_xFCR_xFEN_MASK, ESAI_xFCR_xFEN);
  551. /* Write initial words reqiured by ESAI as normal procedure */
  552. for (i = 0; tx && i < channels; i++)
  553. regmap_write(esai_priv->regmap, REG_ESAI_ETDR, 0x0);
  554. /*
  555. * When set the TE/RE in the end of enablement flow, there
  556. * will be channel swap issue for multi data line case.
  557. * In order to workaround this issue, we switch the bit
  558. * enablement sequence to below sequence
  559. * 1) clear the xSMB & xSMA: which is done in probe and
  560. * stop state.
  561. * 2) set TE/RE
  562. * 3) set xSMB
  563. * 4) set xSMA: xSMA is the last one in this flow, which
  564. * will trigger esai to start.
  565. */
  566. regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
  567. tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK,
  568. tx ? ESAI_xCR_TE(pins) : ESAI_xCR_RE(pins));
  569. mask = tx ? esai_priv->tx_mask : esai_priv->rx_mask;
  570. regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMB(tx),
  571. ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(mask));
  572. regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMA(tx),
  573. ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(mask));
  574. /* Enable Exception interrupt */
  575. regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
  576. ESAI_xCR_xEIE_MASK, ESAI_xCR_xEIE);
  577. }
  578. static void fsl_esai_trigger_stop(struct fsl_esai *esai_priv, bool tx)
  579. {
  580. regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
  581. ESAI_xCR_xEIE_MASK, 0);
  582. regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
  583. tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK, 0);
  584. regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMA(tx),
  585. ESAI_xSMA_xS_MASK, 0);
  586. regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMB(tx),
  587. ESAI_xSMB_xS_MASK, 0);
  588. /* Disable and reset FIFO */
  589. regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx),
  590. ESAI_xFCR_xFR | ESAI_xFCR_xFEN, ESAI_xFCR_xFR);
  591. regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx),
  592. ESAI_xFCR_xFR, 0);
  593. }
  594. static void fsl_esai_hw_reset(struct work_struct *work)
  595. {
  596. struct fsl_esai *esai_priv = container_of(work, struct fsl_esai, work);
  597. bool tx = true, rx = false, enabled[2];
  598. unsigned long lock_flags;
  599. u32 tfcr, rfcr;
  600. spin_lock_irqsave(&esai_priv->lock, lock_flags);
  601. /* Save the registers */
  602. regmap_read(esai_priv->regmap, REG_ESAI_TFCR, &tfcr);
  603. regmap_read(esai_priv->regmap, REG_ESAI_RFCR, &rfcr);
  604. enabled[tx] = tfcr & ESAI_xFCR_xFEN;
  605. enabled[rx] = rfcr & ESAI_xFCR_xFEN;
  606. /* Stop the tx & rx */
  607. fsl_esai_trigger_stop(esai_priv, tx);
  608. fsl_esai_trigger_stop(esai_priv, rx);
  609. /* Reset the esai, and ignore return value */
  610. fsl_esai_hw_init(esai_priv);
  611. /* Enforce ESAI personal resets for both TX and RX */
  612. regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR,
  613. ESAI_xCR_xPR_MASK, ESAI_xCR_xPR);
  614. regmap_update_bits(esai_priv->regmap, REG_ESAI_RCR,
  615. ESAI_xCR_xPR_MASK, ESAI_xCR_xPR);
  616. /* Restore registers by regcache_sync, and ignore return value */
  617. fsl_esai_register_restore(esai_priv);
  618. /* Remove ESAI personal resets by configuring PCRC and PRRC also */
  619. regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR,
  620. ESAI_xCR_xPR_MASK, 0);
  621. regmap_update_bits(esai_priv->regmap, REG_ESAI_RCR,
  622. ESAI_xCR_xPR_MASK, 0);
  623. regmap_update_bits(esai_priv->regmap, REG_ESAI_PRRC,
  624. ESAI_PRRC_PDC_MASK, ESAI_PRRC_PDC(ESAI_GPIO));
  625. regmap_update_bits(esai_priv->regmap, REG_ESAI_PCRC,
  626. ESAI_PCRC_PC_MASK, ESAI_PCRC_PC(ESAI_GPIO));
  627. /* Restart tx / rx, if they already enabled */
  628. if (enabled[tx])
  629. fsl_esai_trigger_start(esai_priv, tx);
  630. if (enabled[rx])
  631. fsl_esai_trigger_start(esai_priv, rx);
  632. spin_unlock_irqrestore(&esai_priv->lock, lock_flags);
  633. }
  634. static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd,
  635. struct snd_soc_dai *dai)
  636. {
  637. struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
  638. bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
  639. unsigned long lock_flags;
  640. esai_priv->channels[tx] = substream->runtime->channels;
  641. switch (cmd) {
  642. case SNDRV_PCM_TRIGGER_START:
  643. case SNDRV_PCM_TRIGGER_RESUME:
  644. case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
  645. spin_lock_irqsave(&esai_priv->lock, lock_flags);
  646. fsl_esai_trigger_start(esai_priv, tx);
  647. spin_unlock_irqrestore(&esai_priv->lock, lock_flags);
  648. break;
  649. case SNDRV_PCM_TRIGGER_SUSPEND:
  650. case SNDRV_PCM_TRIGGER_STOP:
  651. case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
  652. spin_lock_irqsave(&esai_priv->lock, lock_flags);
  653. fsl_esai_trigger_stop(esai_priv, tx);
  654. spin_unlock_irqrestore(&esai_priv->lock, lock_flags);
  655. break;
  656. default:
  657. return -EINVAL;
  658. }
  659. return 0;
  660. }
  661. static const struct snd_soc_dai_ops fsl_esai_dai_ops = {
  662. .startup = fsl_esai_startup,
  663. .trigger = fsl_esai_trigger,
  664. .hw_params = fsl_esai_hw_params,
  665. .set_sysclk = fsl_esai_set_dai_sysclk,
  666. .set_fmt = fsl_esai_set_dai_fmt,
  667. .set_tdm_slot = fsl_esai_set_dai_tdm_slot,
  668. };
  669. static int fsl_esai_dai_probe(struct snd_soc_dai *dai)
  670. {
  671. struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
  672. snd_soc_dai_init_dma_data(dai, &esai_priv->dma_params_tx,
  673. &esai_priv->dma_params_rx);
  674. return 0;
  675. }
  676. static struct snd_soc_dai_driver fsl_esai_dai = {
  677. .probe = fsl_esai_dai_probe,
  678. .playback = {
  679. .stream_name = "CPU-Playback",
  680. .channels_min = 1,
  681. .channels_max = 12,
  682. .rates = SNDRV_PCM_RATE_8000_192000,
  683. .formats = FSL_ESAI_FORMATS,
  684. },
  685. .capture = {
  686. .stream_name = "CPU-Capture",
  687. .channels_min = 1,
  688. .channels_max = 8,
  689. .rates = SNDRV_PCM_RATE_8000_192000,
  690. .formats = FSL_ESAI_FORMATS,
  691. },
  692. .ops = &fsl_esai_dai_ops,
  693. };
  694. static const struct snd_soc_component_driver fsl_esai_component = {
  695. .name = "fsl-esai",
  696. .legacy_dai_naming = 1,
  697. };
  698. static const struct reg_default fsl_esai_reg_defaults[] = {
  699. {REG_ESAI_ETDR, 0x00000000},
  700. {REG_ESAI_ECR, 0x00000000},
  701. {REG_ESAI_TFCR, 0x00000000},
  702. {REG_ESAI_RFCR, 0x00000000},
  703. {REG_ESAI_TX0, 0x00000000},
  704. {REG_ESAI_TX1, 0x00000000},
  705. {REG_ESAI_TX2, 0x00000000},
  706. {REG_ESAI_TX3, 0x00000000},
  707. {REG_ESAI_TX4, 0x00000000},
  708. {REG_ESAI_TX5, 0x00000000},
  709. {REG_ESAI_TSR, 0x00000000},
  710. {REG_ESAI_SAICR, 0x00000000},
  711. {REG_ESAI_TCR, 0x00000000},
  712. {REG_ESAI_TCCR, 0x00000000},
  713. {REG_ESAI_RCR, 0x00000000},
  714. {REG_ESAI_RCCR, 0x00000000},
  715. {REG_ESAI_TSMA, 0x0000ffff},
  716. {REG_ESAI_TSMB, 0x0000ffff},
  717. {REG_ESAI_RSMA, 0x0000ffff},
  718. {REG_ESAI_RSMB, 0x0000ffff},
  719. {REG_ESAI_PRRC, 0x00000000},
  720. {REG_ESAI_PCRC, 0x00000000},
  721. };
  722. static bool fsl_esai_readable_reg(struct device *dev, unsigned int reg)
  723. {
  724. switch (reg) {
  725. case REG_ESAI_ERDR:
  726. case REG_ESAI_ECR:
  727. case REG_ESAI_ESR:
  728. case REG_ESAI_TFCR:
  729. case REG_ESAI_TFSR:
  730. case REG_ESAI_RFCR:
  731. case REG_ESAI_RFSR:
  732. case REG_ESAI_RX0:
  733. case REG_ESAI_RX1:
  734. case REG_ESAI_RX2:
  735. case REG_ESAI_RX3:
  736. case REG_ESAI_SAISR:
  737. case REG_ESAI_SAICR:
  738. case REG_ESAI_TCR:
  739. case REG_ESAI_TCCR:
  740. case REG_ESAI_RCR:
  741. case REG_ESAI_RCCR:
  742. case REG_ESAI_TSMA:
  743. case REG_ESAI_TSMB:
  744. case REG_ESAI_RSMA:
  745. case REG_ESAI_RSMB:
  746. case REG_ESAI_PRRC:
  747. case REG_ESAI_PCRC:
  748. return true;
  749. default:
  750. return false;
  751. }
  752. }
  753. static bool fsl_esai_volatile_reg(struct device *dev, unsigned int reg)
  754. {
  755. switch (reg) {
  756. case REG_ESAI_ERDR:
  757. case REG_ESAI_ESR:
  758. case REG_ESAI_TFSR:
  759. case REG_ESAI_RFSR:
  760. case REG_ESAI_RX0:
  761. case REG_ESAI_RX1:
  762. case REG_ESAI_RX2:
  763. case REG_ESAI_RX3:
  764. case REG_ESAI_SAISR:
  765. return true;
  766. default:
  767. return false;
  768. }
  769. }
  770. static bool fsl_esai_writeable_reg(struct device *dev, unsigned int reg)
  771. {
  772. switch (reg) {
  773. case REG_ESAI_ETDR:
  774. case REG_ESAI_ECR:
  775. case REG_ESAI_TFCR:
  776. case REG_ESAI_RFCR:
  777. case REG_ESAI_TX0:
  778. case REG_ESAI_TX1:
  779. case REG_ESAI_TX2:
  780. case REG_ESAI_TX3:
  781. case REG_ESAI_TX4:
  782. case REG_ESAI_TX5:
  783. case REG_ESAI_TSR:
  784. case REG_ESAI_SAICR:
  785. case REG_ESAI_TCR:
  786. case REG_ESAI_TCCR:
  787. case REG_ESAI_RCR:
  788. case REG_ESAI_RCCR:
  789. case REG_ESAI_TSMA:
  790. case REG_ESAI_TSMB:
  791. case REG_ESAI_RSMA:
  792. case REG_ESAI_RSMB:
  793. case REG_ESAI_PRRC:
  794. case REG_ESAI_PCRC:
  795. return true;
  796. default:
  797. return false;
  798. }
  799. }
  800. static const struct regmap_config fsl_esai_regmap_config = {
  801. .reg_bits = 32,
  802. .reg_stride = 4,
  803. .val_bits = 32,
  804. .max_register = REG_ESAI_PCRC,
  805. .reg_defaults = fsl_esai_reg_defaults,
  806. .num_reg_defaults = ARRAY_SIZE(fsl_esai_reg_defaults),
  807. .readable_reg = fsl_esai_readable_reg,
  808. .volatile_reg = fsl_esai_volatile_reg,
  809. .writeable_reg = fsl_esai_writeable_reg,
  810. .cache_type = REGCACHE_FLAT,
  811. };
  812. static int fsl_esai_runtime_resume(struct device *dev);
  813. static int fsl_esai_runtime_suspend(struct device *dev);
  814. static int fsl_esai_probe(struct platform_device *pdev)
  815. {
  816. struct device_node *np = pdev->dev.of_node;
  817. struct fsl_esai *esai_priv;
  818. struct resource *res;
  819. const __be32 *iprop;
  820. void __iomem *regs;
  821. int irq, ret;
  822. esai_priv = devm_kzalloc(&pdev->dev, sizeof(*esai_priv), GFP_KERNEL);
  823. if (!esai_priv)
  824. return -ENOMEM;
  825. esai_priv->pdev = pdev;
  826. snprintf(esai_priv->name, sizeof(esai_priv->name), "%pOFn", np);
  827. esai_priv->soc = of_device_get_match_data(&pdev->dev);
  828. /* Get the addresses and IRQ */
  829. regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
  830. if (IS_ERR(regs))
  831. return PTR_ERR(regs);
  832. esai_priv->regmap = devm_regmap_init_mmio(&pdev->dev, regs, &fsl_esai_regmap_config);
  833. if (IS_ERR(esai_priv->regmap)) {
  834. dev_err(&pdev->dev, "failed to init regmap: %ld\n",
  835. PTR_ERR(esai_priv->regmap));
  836. return PTR_ERR(esai_priv->regmap);
  837. }
  838. esai_priv->coreclk = devm_clk_get(&pdev->dev, "core");
  839. if (IS_ERR(esai_priv->coreclk)) {
  840. dev_err(&pdev->dev, "failed to get core clock: %ld\n",
  841. PTR_ERR(esai_priv->coreclk));
  842. return PTR_ERR(esai_priv->coreclk);
  843. }
  844. esai_priv->extalclk = devm_clk_get(&pdev->dev, "extal");
  845. if (IS_ERR(esai_priv->extalclk))
  846. dev_warn(&pdev->dev, "failed to get extal clock: %ld\n",
  847. PTR_ERR(esai_priv->extalclk));
  848. esai_priv->fsysclk = devm_clk_get(&pdev->dev, "fsys");
  849. if (IS_ERR(esai_priv->fsysclk))
  850. dev_warn(&pdev->dev, "failed to get fsys clock: %ld\n",
  851. PTR_ERR(esai_priv->fsysclk));
  852. esai_priv->spbaclk = devm_clk_get(&pdev->dev, "spba");
  853. if (IS_ERR(esai_priv->spbaclk))
  854. dev_warn(&pdev->dev, "failed to get spba clock: %ld\n",
  855. PTR_ERR(esai_priv->spbaclk));
  856. irq = platform_get_irq(pdev, 0);
  857. if (irq < 0)
  858. return irq;
  859. ret = devm_request_irq(&pdev->dev, irq, esai_isr, IRQF_SHARED,
  860. esai_priv->name, esai_priv);
  861. if (ret) {
  862. dev_err(&pdev->dev, "failed to claim irq %u\n", irq);
  863. return ret;
  864. }
  865. /* Set a default slot number */
  866. esai_priv->slots = 2;
  867. /* Set a default clock provider state */
  868. esai_priv->consumer_mode = true;
  869. /* Determine the FIFO depth */
  870. iprop = of_get_property(np, "fsl,fifo-depth", NULL);
  871. if (iprop)
  872. esai_priv->fifo_depth = be32_to_cpup(iprop);
  873. else
  874. esai_priv->fifo_depth = 64;
  875. esai_priv->dma_params_tx.maxburst = 16;
  876. esai_priv->dma_params_rx.maxburst = 16;
  877. esai_priv->dma_params_tx.addr = res->start + REG_ESAI_ETDR;
  878. esai_priv->dma_params_rx.addr = res->start + REG_ESAI_ERDR;
  879. esai_priv->synchronous =
  880. of_property_read_bool(np, "fsl,esai-synchronous");
  881. /* Implement full symmetry for synchronous mode */
  882. if (esai_priv->synchronous) {
  883. fsl_esai_dai.symmetric_rate = 1;
  884. fsl_esai_dai.symmetric_channels = 1;
  885. fsl_esai_dai.symmetric_sample_bits = 1;
  886. }
  887. dev_set_drvdata(&pdev->dev, esai_priv);
  888. spin_lock_init(&esai_priv->lock);
  889. pm_runtime_enable(&pdev->dev);
  890. if (!pm_runtime_enabled(&pdev->dev)) {
  891. ret = fsl_esai_runtime_resume(&pdev->dev);
  892. if (ret)
  893. goto err_pm_disable;
  894. }
  895. ret = pm_runtime_resume_and_get(&pdev->dev);
  896. if (ret < 0)
  897. goto err_pm_get_sync;
  898. ret = fsl_esai_hw_init(esai_priv);
  899. if (ret)
  900. goto err_pm_get_sync;
  901. esai_priv->tx_mask = 0xFFFFFFFF;
  902. esai_priv->rx_mask = 0xFFFFFFFF;
  903. /* Clear the TSMA, TSMB, RSMA, RSMB */
  904. regmap_write(esai_priv->regmap, REG_ESAI_TSMA, 0);
  905. regmap_write(esai_priv->regmap, REG_ESAI_TSMB, 0);
  906. regmap_write(esai_priv->regmap, REG_ESAI_RSMA, 0);
  907. regmap_write(esai_priv->regmap, REG_ESAI_RSMB, 0);
  908. ret = pm_runtime_put_sync(&pdev->dev);
  909. if (ret < 0 && ret != -ENOSYS)
  910. goto err_pm_get_sync;
  911. /*
  912. * Register platform component before registering cpu dai for there
  913. * is not defer probe for platform component in snd_soc_add_pcm_runtime().
  914. */
  915. ret = imx_pcm_dma_init(pdev);
  916. if (ret) {
  917. dev_err(&pdev->dev, "failed to init imx pcm dma: %d\n", ret);
  918. goto err_pm_get_sync;
  919. }
  920. ret = devm_snd_soc_register_component(&pdev->dev, &fsl_esai_component,
  921. &fsl_esai_dai, 1);
  922. if (ret) {
  923. dev_err(&pdev->dev, "failed to register DAI: %d\n", ret);
  924. goto err_pm_get_sync;
  925. }
  926. INIT_WORK(&esai_priv->work, fsl_esai_hw_reset);
  927. return ret;
  928. err_pm_get_sync:
  929. if (!pm_runtime_status_suspended(&pdev->dev))
  930. fsl_esai_runtime_suspend(&pdev->dev);
  931. err_pm_disable:
  932. pm_runtime_disable(&pdev->dev);
  933. return ret;
  934. }
  935. static int fsl_esai_remove(struct platform_device *pdev)
  936. {
  937. struct fsl_esai *esai_priv = platform_get_drvdata(pdev);
  938. pm_runtime_disable(&pdev->dev);
  939. if (!pm_runtime_status_suspended(&pdev->dev))
  940. fsl_esai_runtime_suspend(&pdev->dev);
  941. cancel_work_sync(&esai_priv->work);
  942. return 0;
  943. }
  944. static const struct of_device_id fsl_esai_dt_ids[] = {
  945. { .compatible = "fsl,imx35-esai", .data = &fsl_esai_imx35 },
  946. { .compatible = "fsl,vf610-esai", .data = &fsl_esai_vf610 },
  947. { .compatible = "fsl,imx6ull-esai", .data = &fsl_esai_imx6ull },
  948. {}
  949. };
  950. MODULE_DEVICE_TABLE(of, fsl_esai_dt_ids);
  951. static int fsl_esai_runtime_resume(struct device *dev)
  952. {
  953. struct fsl_esai *esai = dev_get_drvdata(dev);
  954. int ret;
  955. /*
  956. * Some platforms might use the same bit to gate all three or two of
  957. * clocks, so keep all clocks open/close at the same time for safety
  958. */
  959. ret = clk_prepare_enable(esai->coreclk);
  960. if (ret)
  961. return ret;
  962. if (!IS_ERR(esai->spbaclk)) {
  963. ret = clk_prepare_enable(esai->spbaclk);
  964. if (ret)
  965. goto err_spbaclk;
  966. }
  967. if (!IS_ERR(esai->extalclk)) {
  968. ret = clk_prepare_enable(esai->extalclk);
  969. if (ret)
  970. goto err_extalclk;
  971. }
  972. if (!IS_ERR(esai->fsysclk)) {
  973. ret = clk_prepare_enable(esai->fsysclk);
  974. if (ret)
  975. goto err_fsysclk;
  976. }
  977. regcache_cache_only(esai->regmap, false);
  978. ret = fsl_esai_register_restore(esai);
  979. if (ret)
  980. goto err_regcache_sync;
  981. return 0;
  982. err_regcache_sync:
  983. if (!IS_ERR(esai->fsysclk))
  984. clk_disable_unprepare(esai->fsysclk);
  985. err_fsysclk:
  986. if (!IS_ERR(esai->extalclk))
  987. clk_disable_unprepare(esai->extalclk);
  988. err_extalclk:
  989. if (!IS_ERR(esai->spbaclk))
  990. clk_disable_unprepare(esai->spbaclk);
  991. err_spbaclk:
  992. clk_disable_unprepare(esai->coreclk);
  993. return ret;
  994. }
  995. static int fsl_esai_runtime_suspend(struct device *dev)
  996. {
  997. struct fsl_esai *esai = dev_get_drvdata(dev);
  998. regcache_cache_only(esai->regmap, true);
  999. if (!IS_ERR(esai->fsysclk))
  1000. clk_disable_unprepare(esai->fsysclk);
  1001. if (!IS_ERR(esai->extalclk))
  1002. clk_disable_unprepare(esai->extalclk);
  1003. if (!IS_ERR(esai->spbaclk))
  1004. clk_disable_unprepare(esai->spbaclk);
  1005. clk_disable_unprepare(esai->coreclk);
  1006. return 0;
  1007. }
  1008. static const struct dev_pm_ops fsl_esai_pm_ops = {
  1009. SET_RUNTIME_PM_OPS(fsl_esai_runtime_suspend,
  1010. fsl_esai_runtime_resume,
  1011. NULL)
  1012. SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
  1013. pm_runtime_force_resume)
  1014. };
  1015. static struct platform_driver fsl_esai_driver = {
  1016. .probe = fsl_esai_probe,
  1017. .remove = fsl_esai_remove,
  1018. .driver = {
  1019. .name = "fsl-esai-dai",
  1020. .pm = &fsl_esai_pm_ops,
  1021. .of_match_table = fsl_esai_dt_ids,
  1022. },
  1023. };
  1024. module_platform_driver(fsl_esai_driver);
  1025. MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  1026. MODULE_DESCRIPTION("Freescale ESAI CPU DAI driver");
  1027. MODULE_LICENSE("GPL v2");
  1028. MODULE_ALIAS("platform:fsl-esai-dai");