mpc5200_psc_i2s.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. /*
  2. * Freescale MPC5200 PSC in I2S mode
  3. * ALSA SoC Digital Audio Interface (DAI) driver
  4. *
  5. * Copyright (C) 2008 Secret Lab Technologies Ltd.
  6. * Copyright (C) 2009 Jon Smirl, Digispeaker
  7. */
  8. #include <linux/module.h>
  9. #include <linux/of_device.h>
  10. #include <linux/of_platform.h>
  11. #include <sound/pcm.h>
  12. #include <sound/pcm_params.h>
  13. #include <sound/soc.h>
  14. #include <asm/mpc52xx_psc.h>
  15. #include "mpc5200_dma.h"
  16. /**
  17. * PSC_I2S_RATES: sample rates supported by the I2S
  18. *
  19. * This driver currently only supports the PSC running in I2S slave mode,
  20. * which means the codec determines the sample rate. Therefore, we tell
  21. * ALSA that we support all rates and let the codec driver decide what rates
  22. * are really supported.
  23. */
  24. #define PSC_I2S_RATES (SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_192000 | \
  25. SNDRV_PCM_RATE_CONTINUOUS)
  26. /**
  27. * PSC_I2S_FORMATS: audio formats supported by the PSC I2S mode
  28. */
  29. #define PSC_I2S_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_BE | \
  30. SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S32_BE)
  31. static int psc_i2s_hw_params(struct snd_pcm_substream *substream,
  32. struct snd_pcm_hw_params *params,
  33. struct snd_soc_dai *dai)
  34. {
  35. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  36. struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(rtd->cpu_dai);
  37. u32 mode;
  38. dev_dbg(psc_dma->dev, "%s(substream=%p) p_size=%i p_bytes=%i"
  39. " periods=%i buffer_size=%i buffer_bytes=%i\n",
  40. __func__, substream, params_period_size(params),
  41. params_period_bytes(params), params_periods(params),
  42. params_buffer_size(params), params_buffer_bytes(params));
  43. switch (params_format(params)) {
  44. case SNDRV_PCM_FORMAT_S8:
  45. mode = MPC52xx_PSC_SICR_SIM_CODEC_8;
  46. break;
  47. case SNDRV_PCM_FORMAT_S16_BE:
  48. mode = MPC52xx_PSC_SICR_SIM_CODEC_16;
  49. break;
  50. case SNDRV_PCM_FORMAT_S24_BE:
  51. mode = MPC52xx_PSC_SICR_SIM_CODEC_24;
  52. break;
  53. case SNDRV_PCM_FORMAT_S32_BE:
  54. mode = MPC52xx_PSC_SICR_SIM_CODEC_32;
  55. break;
  56. default:
  57. dev_dbg(psc_dma->dev, "invalid format\n");
  58. return -EINVAL;
  59. }
  60. out_be32(&psc_dma->psc_regs->sicr, psc_dma->sicr | mode);
  61. return 0;
  62. }
  63. /**
  64. * psc_i2s_set_sysclk: set the clock frequency and direction
  65. *
  66. * This function is called by the machine driver to tell us what the clock
  67. * frequency and direction are.
  68. *
  69. * Currently, we only support operating as a clock slave (SND_SOC_CLOCK_IN),
  70. * and we don't care about the frequency. Return an error if the direction
  71. * is not SND_SOC_CLOCK_IN.
  72. *
  73. * @clk_id: reserved, should be zero
  74. * @freq: the frequency of the given clock ID, currently ignored
  75. * @dir: SND_SOC_CLOCK_IN (clock slave) or SND_SOC_CLOCK_OUT (clock master)
  76. */
  77. static int psc_i2s_set_sysclk(struct snd_soc_dai *cpu_dai,
  78. int clk_id, unsigned int freq, int dir)
  79. {
  80. struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(cpu_dai);
  81. dev_dbg(psc_dma->dev, "psc_i2s_set_sysclk(cpu_dai=%p, dir=%i)\n",
  82. cpu_dai, dir);
  83. return (dir == SND_SOC_CLOCK_IN) ? 0 : -EINVAL;
  84. }
  85. /**
  86. * psc_i2s_set_fmt: set the serial format.
  87. *
  88. * This function is called by the machine driver to tell us what serial
  89. * format to use.
  90. *
  91. * This driver only supports I2S mode. Return an error if the format is
  92. * not SND_SOC_DAIFMT_I2S.
  93. *
  94. * @format: one of SND_SOC_DAIFMT_xxx
  95. */
  96. static int psc_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int format)
  97. {
  98. struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(cpu_dai);
  99. dev_dbg(psc_dma->dev, "psc_i2s_set_fmt(cpu_dai=%p, format=%i)\n",
  100. cpu_dai, format);
  101. return (format == SND_SOC_DAIFMT_I2S) ? 0 : -EINVAL;
  102. }
  103. /* ---------------------------------------------------------------------
  104. * ALSA SoC Bindings
  105. *
  106. * - Digital Audio Interface (DAI) template
  107. * - create/destroy dai hooks
  108. */
  109. /**
  110. * psc_i2s_dai_template: template CPU Digital Audio Interface
  111. */
  112. static struct snd_soc_dai_ops psc_i2s_dai_ops = {
  113. .hw_params = psc_i2s_hw_params,
  114. .set_sysclk = psc_i2s_set_sysclk,
  115. .set_fmt = psc_i2s_set_fmt,
  116. };
  117. static struct snd_soc_dai_driver psc_i2s_dai[] = {{
  118. .playback = {
  119. .channels_min = 2,
  120. .channels_max = 2,
  121. .rates = PSC_I2S_RATES,
  122. .formats = PSC_I2S_FORMATS,
  123. },
  124. .capture = {
  125. .channels_min = 2,
  126. .channels_max = 2,
  127. .rates = PSC_I2S_RATES,
  128. .formats = PSC_I2S_FORMATS,
  129. },
  130. .ops = &psc_i2s_dai_ops,
  131. } };
  132. /* ---------------------------------------------------------------------
  133. * OF platform bus binding code:
  134. * - Probe/remove operations
  135. * - OF device match table
  136. */
  137. static int __devinit psc_i2s_of_probe(struct platform_device *op)
  138. {
  139. int rc;
  140. struct psc_dma *psc_dma;
  141. struct mpc52xx_psc __iomem *regs;
  142. rc = snd_soc_register_dais(&op->dev, psc_i2s_dai, ARRAY_SIZE(psc_i2s_dai));
  143. if (rc != 0) {
  144. pr_err("Failed to register DAI\n");
  145. return rc;
  146. }
  147. psc_dma = dev_get_drvdata(&op->dev);
  148. regs = psc_dma->psc_regs;
  149. /* Configure the serial interface mode; defaulting to CODEC8 mode */
  150. psc_dma->sicr = MPC52xx_PSC_SICR_DTS1 | MPC52xx_PSC_SICR_I2S |
  151. MPC52xx_PSC_SICR_CLKPOL;
  152. out_be32(&psc_dma->psc_regs->sicr,
  153. psc_dma->sicr | MPC52xx_PSC_SICR_SIM_CODEC_8);
  154. /* Check for the codec handle. If it is not present then we
  155. * are done */
  156. if (!of_get_property(op->dev.of_node, "codec-handle", NULL))
  157. return 0;
  158. /* Due to errata in the dma mode; need to line up enabling
  159. * the transmitter with a transition on the frame sync
  160. * line */
  161. /* first make sure it is low */
  162. while ((in_8(&regs->ipcr_acr.ipcr) & 0x80) != 0)
  163. ;
  164. /* then wait for the transition to high */
  165. while ((in_8(&regs->ipcr_acr.ipcr) & 0x80) == 0)
  166. ;
  167. /* Finally, enable the PSC.
  168. * Receiver must always be enabled; even when we only want
  169. * transmit. (see 15.3.2.3 of MPC5200B User's Guide) */
  170. /* Go */
  171. out_8(&psc_dma->psc_regs->command,
  172. MPC52xx_PSC_TX_ENABLE | MPC52xx_PSC_RX_ENABLE);
  173. return 0;
  174. }
  175. static int __devexit psc_i2s_of_remove(struct platform_device *op)
  176. {
  177. snd_soc_unregister_dais(&op->dev, ARRAY_SIZE(psc_i2s_dai));
  178. return 0;
  179. }
  180. /* Match table for of_platform binding */
  181. static struct of_device_id psc_i2s_match[] __devinitdata = {
  182. { .compatible = "fsl,mpc5200-psc-i2s", },
  183. { .compatible = "fsl,mpc5200b-psc-i2s", },
  184. {}
  185. };
  186. MODULE_DEVICE_TABLE(of, psc_i2s_match);
  187. static struct platform_driver psc_i2s_driver = {
  188. .probe = psc_i2s_of_probe,
  189. .remove = __devexit_p(psc_i2s_of_remove),
  190. .driver = {
  191. .name = "mpc5200-psc-i2s",
  192. .owner = THIS_MODULE,
  193. .of_match_table = psc_i2s_match,
  194. },
  195. };
  196. /* ---------------------------------------------------------------------
  197. * Module setup and teardown; simply register the of_platform driver
  198. * for the PSC in I2S mode.
  199. */
  200. static int __init psc_i2s_init(void)
  201. {
  202. return platform_driver_register(&psc_i2s_driver);
  203. }
  204. module_init(psc_i2s_init);
  205. static void __exit psc_i2s_exit(void)
  206. {
  207. platform_driver_unregister(&psc_i2s_driver);
  208. }
  209. module_exit(psc_i2s_exit);
  210. MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
  211. MODULE_DESCRIPTION("Freescale MPC5200 PSC in I2S mode ASoC Driver");
  212. MODULE_LICENSE("GPL");