ark1668_i2s.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572
  1. /*
  2. * ark_i2s.c -- ALSA SoC Audio Layer
  3. *
  4. * Jack Tang <jacktang@astri.org>
  5. *
  6. */
  7. #include <linux/init.h>
  8. #include <linux/module.h>
  9. #include <linux/io.h>
  10. #include <linux/slab.h>
  11. #include <linux/delay.h>
  12. #include <sound/core.h>
  13. #include <sound/pcm.h>
  14. #include <sound/pcm_params.h>
  15. #include <sound/soc.h>
  16. #include <linux/clk.h>
  17. #include <sound/dmaengine_pcm.h>
  18. //#include <mach/va_map.h>
  19. #include "ark1668_i2s.h"
  20. //#include "ark1668_pcm.h"
  21. #include "ark1668_i2s_sddac_regs.h"
  22. //#include <linux/ark/ark_i2s.h>
  23. #define DRV_NAME "ark1668-i2s"
  24. #define DMA_ENABLE
  25. #undef ARK_I2S_DEBUG
  26. #ifdef ARK_I2S_DEBUG
  27. #define DBG(f, a...) printk(KERN_DEBUG "ASOC %s-%d: "f, __FUNCTION__, __LINE__, ##a)
  28. #else
  29. #define DBG(...)
  30. #endif
  31. #define ERR(f, a...) printk(KERN_ERR "ASOC %s-%d: "f, __FUNCTION__, __LINE__, ##a)
  32. struct ark_i2s_dev {
  33. //struct platform_device *pdev;
  34. struct device *dev;
  35. void __iomem *base;
  36. struct clk *clk;
  37. u32 nco_reg;
  38. struct snd_dmaengine_dai_dma_data capture_dma_data;
  39. struct snd_dmaengine_dai_dma_data playback_dma_data;
  40. int master;
  41. u32 fmt;
  42. //struct ark_pcm_dma_params dma_params[2];
  43. };
  44. static void i2s_poweron(struct ark_i2s_dev *i2s)
  45. {
  46. uint32_t val;
  47. // void __iomem *Sys_base;
  48. // void __iomem *i2s_base;
  49. // Sys_base = ioremap(SYS_BASE, 0x1000);
  50. // if(!Sys_base)
  51. // goto unmap_sysreg;
  52. // i2s_base = ioremap(I2S_BASE, 0x1000);
  53. // if(!i2s_base)
  54. // goto unmap_i2sreg;
  55. // if(i2s->pdev->id == 0)
  56. // {
  57. val = readl(i2s->base + ARK_I2SSDDAC_SACR0);
  58. //val &= ~(ARK_I2SSDDAC_SACR0_VREF_PD | ARK_I2SSDDAC_SACR0_DAC_PD | ARK_I2SSDDAC_SACR0_SARADC_EN);
  59. val &= ~(ARK_I2SSDDAC_SACR0_VREF_PD | ARK_I2SSDDAC_SACR0_DAC_PD);
  60. val |= (ARK_I2SSDDAC_SACR0_SARADC_POW_EN | ARK_I2SSDDAC_SACR0_BCKD); // Bitclock output
  61. writel(val, i2s->base + ARK_I2SSDDAC_SACR0);
  62. // }
  63. // else if(i2s->pdev->id == 1)
  64. // {
  65. //#if 0 //set in ark_i2s_init_cfg()
  66. // val = readl(i2s->base + ARK_I2SSDDAC_SACR0);
  67. // val &= ~(ARK_I2SSDDAC_SACR0_BCKD); // Bitclock intput
  68. // val |= ARK_I2SSDDAC_SACR0_SARADC_POW_EN;
  69. // writel(val, i2s->base + ARK_I2SSDDAC_SACR0);
  70. //#endif
  71. // }
  72. //unmap_sysreg:
  73. // iounmap(Sys_base);
  74. //unmap_i2sreg:
  75. // iounmap(i2s_base);
  76. }
  77. static void setup_i2s2(int id)
  78. {
  79. }
  80. /*static void dump_i2s_registers(struct ark_i2s_dev *i2s)
  81. {
  82. printk("ARK_I2SSDDAC_SACR0 = 0x%08x\n", readl(i2s->base + ARK_I2SSDDAC_SACR0));
  83. printk("ARK_I2SSDDAC_SACR1 = 0x%08x\n", readl(i2s->base + ARK_I2SSDDAC_SACR1));
  84. printk("ARK_I2SSDDAC_SACR1 = 0x%08x\n", readl(i2s->base + ARK_I2SSDDAC_DACR0));
  85. printk("ARK_I2SSDDAC_SASR0 = 0x%08x\n", readl(i2s->base + ARK_I2SSDDAC_SASR0));
  86. printk("ARK_I2SSDDAC_DACR1 = 0x%08x\n", readl(i2s->base + ARK_I2SSDDAC_DACR1));
  87. printk("ARK_I2SSDDAC_SAIMR = 0x%08x\n", readl(i2s->base + ARK_I2SSDDAC_SAIMR));
  88. printk("ARK_I2SSDDAC_SAICR = 0x%08x\n", readl(i2s->base + ARK_I2SSDDAC_SAICR));
  89. printk("ARK_I2SSDDAC_ADCR0 = 0x%08x\n", readl(i2s->base + ARK_I2SSDDAC_ADCR0));
  90. printk("ARK_I2SSDDAC_SADR = 0x%08x\n", readl(i2s->base + ARK_I2SSDDAC_SADR));
  91. }*/
  92. static void ark_i2s_txctrl(struct ark_i2s_dev *i2s, int on)
  93. {
  94. }
  95. static void ark_i2s_rxctrl(struct ark_i2s_dev *i2s, int on)
  96. {
  97. }
  98. static void ark_i2s_init_cfg(struct ark_i2s_dev *i2s, int id)
  99. {
  100. }
  101. static int ark_i2s_startup(
  102. struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
  103. {//printk("==============[%s]:[ %d]\n", __FUNCTION__, __LINE__);
  104. struct ark_i2s_dev *i2s = snd_soc_dai_get_drvdata(dai);
  105. unsigned int val;
  106. void __iomem *Sys_base;
  107. void __iomem *i2s_base;
  108. Sys_base = ioremap(SYS_BASE, 0x1000);
  109. if(!Sys_base)
  110. goto unmap_sysreg;
  111. //printk("==============[sys_base = 0x%08x i2s->base = 0x%08x]\n",Sys_base,i2s->base);
  112. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  113. {printk("==============[%s]:[ %d]\n", __FUNCTION__, __LINE__);
  114. //val = readl(ARK1680_VA_SYS + ARK_SYS_PAD_CTRL06);
  115. //writel(val | ARK_SYS_I2S_DATA_DIR_OUT, ARK1680_VA_SYS + ARK_SYS_PAD_CTRL06);
  116. val = readl(Sys_base + ARK_SYS_PAD_CTRL0C);
  117. writel(val | ARK_SYS_I2S_MCLK_AUX, Sys_base + ARK_SYS_PAD_CTRL0C);
  118. val = readl(i2s->base + ARK_I2SSDDAC_SACR0);
  119. val |= ARK_I2SSDDAC_SACR0_I2SEN;//i2s enable
  120. // cancel pop noise
  121. //val |= ARK_I2SSDDAC_SACR0_BCKD;// Bitclock output
  122. val |= ARK_I2SSDDAC_SACR0_TFTH; // set tfth
  123. val |= ARK_I2SSDDAC_SACR0_SARADC_DATA; // set saradc data
  124. writel(val, i2s->base + ARK_I2SSDDAC_SACR0);
  125. val = readl(i2s->base + ARK_I2SSDDAC_SAIMR);
  126. val &= ~(ARK_I2SSDDAC_SAIMR_TFS
  127. |ARK_I2SSDDAC_SAIMR_TUR);
  128. writel(val, i2s->base + ARK_I2SSDDAC_SAIMR);
  129. val = readl(i2s->base + ARK_I2SSDDAC_SAICR);
  130. val |= (ARK_I2SSDDAC_SAICR_TXCR
  131. |ARK_I2SSDDAC_SAICR_TUR);
  132. writel(val, i2s->base + ARK_I2SSDDAC_SAICR);
  133. val = readl(i2s->base + ARK_I2SSDDAC_SAICR);
  134. val &= ~(ARK_I2SSDDAC_SAICR_TXCR
  135. |ARK_I2SSDDAC_SAICR_TUR);
  136. writel(val, i2s->base + ARK_I2SSDDAC_SAICR);
  137. // val = readl(i2s->base + ARK_I2SSDDAC_SACR0);
  138. // val |= ARK_I2SSDDAC_SACR0_TDMAENA; // enable tx dma
  139. // writel(val, i2s->base + ARK_I2SSDDAC_SACR0);
  140. val = readl(i2s->base + ARK_I2SSDDAC_SACR1);
  141. val &= ~ARK_I2SSDDAC_SACR1_DIS_PLAY; //enable play
  142. writel(val, i2s->base + ARK_I2SSDDAC_SACR1);
  143. writel(0, i2s->base + ARK_I2SSDDAC_DACR0);
  144. val = readl(i2s->base + ARK_I2SSDDAC_DACR1);
  145. val |= ARK_I2SSDDAC_DACR1_LRSW; // left/right audio play channel switch
  146. writel(val, i2s->base + ARK_I2SSDDAC_DACR1);
  147. }
  148. else if(substream->stream == SNDRV_PCM_STREAM_CAPTURE)
  149. {printk("==============[%s]:[ %d]\n", __FUNCTION__, __LINE__);
  150. //
  151. val = readl(Sys_base + ARK_SYS_PAD_CTRL09);
  152. val |= (ARK_SYS_I2S2_BCLK
  153. |ARK_SYS_I2S2_SADATA
  154. |ARK_SYS_I2S2_SYNC);
  155. writel(val, Sys_base + ARK_SYS_PAD_CTRL09);
  156. val = readl(Sys_base + ARK_SYS_PAD_CTRL0A);
  157. val |= (7<<8);
  158. writel(val, Sys_base + ARK_SYS_PAD_CTRL0A);
  159. val = readl(Sys_base + ARK_SYS_PAD_CTRL0C);
  160. val |= ARK_SYS_I2S_MCLK_AUX;
  161. writel(val, Sys_base + ARK_SYS_PAD_CTRL0C);
  162. //
  163. val = readl(Sys_base + ARK_SYS_PAD_CTRL06);
  164. val &= ~ARK_SYS_I2S_DATA_DIR_OUT;
  165. writel(val, Sys_base + ARK_SYS_PAD_CTRL06);
  166. val = readl(i2s->base + ARK_I2SSDDAC_SACR0);
  167. val &= ~(ARK_I2SSDDAC_SACR0_SARADC_VREF
  168. |ARK_I2SSDDAC_SACR0_SARADC_DATA
  169. |ARK_I2SSDDAC_SACR0_DACCLK_EDGE
  170. |ARK_I2SSDDAC_SACR0_RDMAENA
  171. |ARK_I2SSDDAC_SACR0_LOOPBACK
  172. |ARK_I2SSDDAC_SACR0_BCKD
  173. |ARK_I2SSDDAC_SACR0_SYNCD);
  174. val |= (ARK_I2SSDDAC_SACR0_MIC_LINE_SEL
  175. |ARK_I2SSDDAC_SACR0_SARADC_POW_EN
  176. |ARK_I2SSDDAC_SACR0_SARADC_EN
  177. |ARK_I2SSDDAC_SACR0_DAC_PD
  178. |ARK_I2SSDDAC_SACR0_VREF_PD
  179. |ARK_I2SSDDAC_SACR0_RFTH
  180. #if defined(CONFIG_FM1288_Driver)
  181. |ARK_I2SSDDAC_SACR0_BCKD //the module of fm1288 is weird, when capturing,
  182. |ARK_I2SSDDAC_SACR0_SYNCD //you must set the direction of the tow guys output as playback
  183. #endif
  184. |ARK_I2SSDDAC_SACR0_I2SEN);
  185. writel(val, i2s->base + ARK_I2SSDDAC_SACR0);
  186. val = readl(i2s->base + ARK_I2SSDDAC_SAIMR);
  187. val &= ~(ARK_I2SSDDAC_SAIMR_RFS
  188. |ARK_I2SSDDAC_SAIMR_ROR);
  189. writel(val, i2s->base + ARK_I2SSDDAC_SAIMR);
  190. val = readl(i2s->base + ARK_I2SSDDAC_SAICR);
  191. val |= (ARK_I2SSDDAC_SAICR_RXCR
  192. |ARK_I2SSDDAC_SAICR_ROR);
  193. writel(val, i2s->base + ARK_I2SSDDAC_SAICR);
  194. val = readl(i2s->base + ARK_I2SSDDAC_SAICR);
  195. val &= ~(ARK_I2SSDDAC_SAICR_RXCR
  196. |ARK_I2SSDDAC_SAICR_ROR);
  197. writel(val, i2s->base + ARK_I2SSDDAC_SAICR);
  198. // val = readl(i2s->base + ARK_I2SSDDAC_SACR0);
  199. // val |= ARK_I2SSDDAC_SACR0_RDMAENA; // enable rx dma
  200. // writel(val, i2s->base + ARK_I2SSDDAC_SACR0);
  201. val = readl(i2s->base + ARK_I2SSDDAC_SACR1);
  202. val &= ~ARK_I2SSDDAC_SACR1_DIS_REC; //enable record
  203. writel(val, i2s->base + ARK_I2SSDDAC_SACR1);
  204. }
  205. /* Tx/Rx Config */
  206. //snd_soc_dai_set_dma_data(dai, substream, &i2s->dma_params[substream->stream]);
  207. unmap_sysreg:
  208. iounmap(Sys_base);
  209. return 0;
  210. }
  211. static int ark_i2s_hw_params(
  212. struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params,
  213. struct snd_soc_dai *dai)
  214. { //printk("==============[%s]:[ %d]\n", __FUNCTION__, __LINE__);
  215. //struct ark_i2s_dev *i2s = snd_soc_dai_get_drvdata(dai);
  216. struct ark_i2s_dev *i2s = snd_soc_dai_get_drvdata(dai);
  217. u32 rate = params_rate(params);
  218. u32 step = 256 * 2, modulo;
  219. u32 val, freq;
  220. void *sysreg;
  221. if (!i2s->nco_reg)
  222. return 0;
  223. /* mclk = rate * 256, mclk = freq * step / (2 * modulo) */
  224. freq = clk_get_rate(i2s->clk);
  225. modulo = freq / rate;
  226. val = (step << 16) | modulo;
  227. sysreg = ioremap(i2s->nco_reg, 0x10);
  228. if (sysreg) {
  229. writel(val, sysreg);
  230. iounmap(sysreg);
  231. }
  232. return 0;
  233. }
  234. static int ark_i2s_trigger(
  235. struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai)
  236. {//printk("==============[%s]:[ %d]\n", __FUNCTION__, __LINE__);
  237. int ret = 0;
  238. struct ark_i2s_dev *i2s = snd_soc_dai_get_drvdata(dai);
  239. DBG("-->\n");
  240. switch (cmd) {
  241. case SNDRV_PCM_TRIGGER_START:
  242. case SNDRV_PCM_TRIGGER_RESUME:
  243. case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
  244. /* TODO: start i2s */
  245. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  246. ark_i2s_txctrl(i2s, 1);
  247. else
  248. ark_i2s_rxctrl(i2s, 1);
  249. /* TODO: Start DMA */
  250. break;
  251. case SNDRV_PCM_TRIGGER_STOP:
  252. case SNDRV_PCM_TRIGGER_SUSPEND:
  253. case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
  254. /* TODO: stop i2s */
  255. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  256. ark_i2s_txctrl(i2s, 0);
  257. else
  258. ark_i2s_rxctrl(i2s, 0);
  259. break;
  260. default:
  261. ret = -EINVAL;
  262. break;
  263. }
  264. return ret;
  265. }
  266. static int ark_i2s_set_fmt(
  267. struct snd_soc_dai *dai, unsigned int fmt)
  268. {//printk("==============[%s]:[ %d]\n", __FUNCTION__, __LINE__);
  269. struct ark_i2s_dev *i2s = snd_soc_dai_get_drvdata(dai);
  270. /* interface format */
  271. switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
  272. case SND_SOC_DAIFMT_I2S:
  273. i2s->fmt = 0;
  274. break;
  275. }
  276. switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
  277. case SND_SOC_DAIFMT_CBS_CFS:
  278. i2s->master = 1;
  279. break;
  280. case SND_SOC_DAIFMT_CBM_CFS:
  281. i2s->master = 0;
  282. break;
  283. default:
  284. break;
  285. }
  286. return 0;
  287. }
  288. static int ark_i2s_probe(struct snd_soc_dai *dai)
  289. {//printk("==============[%s]:[ %d]\n", __FUNCTION__, __LINE__);
  290. struct ark_i2s_dev *i2s = snd_soc_dai_get_drvdata(dai);
  291. int ret = 0;
  292. #ifdef DMA_ENABLE
  293. dai->capture_dma_data = &i2s->capture_dma_data;
  294. dai->playback_dma_data = &i2s->playback_dma_data;
  295. #endif
  296. return ret;
  297. }
  298. static int ark_i2s_remove(struct snd_soc_dai *dai)
  299. {//printk("==============[%s]:[ %d]\n", __FUNCTION__, __LINE__);
  300. struct ark_i2s_dev *i2s = snd_soc_dai_get_drvdata(dai);
  301. ark_i2s_txctrl(i2s, 0);
  302. ark_i2s_rxctrl(i2s, 0);
  303. return 0;
  304. }
  305. #ifdef CONFIG_PM
  306. static int ark_i2s_suspend(struct snd_soc_dai *cpu_dai)
  307. {//printk("==============[%s]:[ %d]\n", __FUNCTION__, __LINE__);
  308. /* TODO: suspend i2s, disable clock */
  309. return 0;
  310. }
  311. static int ark_i2s_resume(struct snd_soc_dai *cpu_dai)
  312. {
  313. //printk("==============[%s]:[ %d]\n", __FUNCTION__, __LINE__);
  314. /* TODO: enable clock and resume i2s */
  315. return 0;
  316. }
  317. #else
  318. #define ark_i2s_suspend NULL
  319. #define ark_i2s_resume NULL
  320. #endif
  321. /* I2S supported rate and format */
  322. #define ARK_I2S_RATES \
  323. (SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \
  324. SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | \
  325. SNDRV_PCM_RATE_64000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | \
  326. SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_8000)
  327. #define ARK_I2S_FORMAT (SNDRV_PCM_FMTBIT_S16_LE) /* TODO: 18 and 20bits width */
  328. static const struct snd_soc_dai_ops ark_i2s_dai_ops = {
  329. .startup = ark_i2s_startup,
  330. .trigger = ark_i2s_trigger,
  331. .hw_params = ark_i2s_hw_params,
  332. .set_fmt = ark_i2s_set_fmt,
  333. };
  334. static struct snd_soc_dai_driver ark_i2s_dai = {
  335. .probe = ark_i2s_probe,
  336. .playback = {
  337. .channels_min = 1,
  338. .channels_max = 2,
  339. .rates = ARK_I2S_RATES,
  340. .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
  341. SNDRV_PCM_FMTBIT_S32_LE,},
  342. .capture = {
  343. .channels_min = 2,
  344. .channels_max = 2,
  345. .rates = ARK_I2S_RATES,
  346. .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
  347. SNDRV_PCM_FMTBIT_S32_LE,},
  348. .ops = &ark_i2s_dai_ops,
  349. .symmetric_rates = 1,
  350. };
  351. static struct snd_pcm_hardware ark1668_pcm_hardware = {
  352. #if 0
  353. .info = (SNDRV_PCM_INFO_MMAP |
  354. SNDRV_PCM_INFO_MMAP_VALID |
  355. SNDRV_PCM_INFO_PAUSE |
  356. SNDRV_PCM_INFO_RESUME |
  357. SNDRV_PCM_INFO_INTERLEAVED |
  358. SNDRV_PCM_INFO_BLOCK_TRANSFER),
  359. .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
  360. SNDRV_PCM_FMTBIT_S32_LE,
  361. .rates = (SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 |
  362. SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 |
  363. SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
  364. SNDRV_PCM_RATE_64000 | SNDRV_PCM_RATE_88200 |
  365. SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |
  366. SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_8000),
  367. .rate_min = 8000,
  368. .rate_max = 192000,
  369. .channels_min = 1,
  370. .channels_max = 2,
  371. .buffer_bytes_max = 64 * 65536,//64 * 4096,
  372. .period_bytes_min = 64,
  373. .period_bytes_max = 65536,//4096,
  374. .periods_min = 1,
  375. .periods_max = 64,
  376. #else
  377. .info = (SNDRV_PCM_INFO_MMAP |
  378. SNDRV_PCM_INFO_MMAP_VALID |
  379. SNDRV_PCM_INFO_PAUSE |
  380. SNDRV_PCM_INFO_RESUME |
  381. SNDRV_PCM_INFO_INTERLEAVED |
  382. SNDRV_PCM_INFO_BLOCK_TRANSFER),
  383. .formats = SNDRV_PCM_FMTBIT_S16_LE,
  384. .rates = (SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 |
  385. SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 |
  386. SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
  387. SNDRV_PCM_RATE_64000 | SNDRV_PCM_RATE_88200 |
  388. SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |
  389. SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_8000),
  390. .rate_min = 8000,//11025
  391. .rate_max = 192000,
  392. .channels_min = 1,
  393. .channels_max = 2,
  394. .buffer_bytes_max = 64 * 4096,
  395. .period_bytes_min = 64,
  396. .period_bytes_max = 4096,
  397. .periods_min = 1,
  398. .periods_max = 64,
  399. // .fifo_size = 32,
  400. #endif
  401. };
  402. static const struct snd_dmaengine_pcm_config
  403. ark1668_i2s_dmaengine_pcm_config = {
  404. .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
  405. .pcm_hardware = &ark1668_pcm_hardware,
  406. };
  407. static const struct snd_soc_component_driver ark1668_i2s_component = {
  408. .name = DRV_NAME,
  409. };
  410. static int ark1668_i2s_drv_probe(struct platform_device *pdev)
  411. {
  412. struct ark_i2s_dev *i2s;
  413. struct resource *mem;
  414. u32 val;
  415. int ret = 0;
  416. printk("start:==============[%s]:[ %d]\n", __FUNCTION__, __LINE__);
  417. i2s = devm_kzalloc(&pdev->dev, sizeof(struct ark_i2s_dev), GFP_KERNEL);
  418. if (!i2s) {
  419. ERR("Failed to allocate ark_i2s_dev\n");
  420. return -ENOMEM;
  421. }
  422. i2s->dev = &pdev->dev;
  423. mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  424. i2s->base = devm_ioremap_resource(&pdev->dev, mem);
  425. if (IS_ERR(i2s->base)) {
  426. dev_err(&pdev->dev, "no mem resource\n");
  427. return PTR_ERR(i2s->base);
  428. }
  429. printk(KERN_ALERT "dev %s 0x%x.\n", dev_name(&pdev->dev), mem->start);
  430. if (!of_property_read_u32(pdev->dev.of_node, "nco-reg", &val))
  431. i2s->nco_reg = val;
  432. /* Get i2s clock */
  433. i2s->clk = of_clk_get(pdev->dev.of_node, 0);
  434. if (IS_ERR(i2s->clk)) {
  435. dev_err(&pdev->dev, "Cannot get the i2s clock\n");
  436. return PTR_ERR(i2s->clk);
  437. }
  438. /* DMA parameters */
  439. #ifdef DMA_ENABLE
  440. i2s->playback_dma_data.addr = mem->start + ARK_I2SSDDAC_SADR;
  441. i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
  442. i2s->playback_dma_data.maxburst = 16;
  443. i2s->capture_dma_data.addr = mem->start + ARK_I2SSDDAC_SADR;
  444. i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
  445. i2s->capture_dma_data.maxburst = 16;
  446. #endif
  447. /* Pre-assign snd_soc_dai_set_drvdata */
  448. dev_set_drvdata(&pdev->dev, i2s);
  449. ret = devm_snd_soc_register_component(&pdev->dev,
  450. &ark1668_i2s_component,
  451. &ark_i2s_dai, 1);
  452. if (ret !=0){
  453. dev_err(&pdev->dev, "Could not register DAI\n");
  454. return ret;
  455. }
  456. i2s_poweron(i2s);
  457. ret = devm_snd_dmaengine_pcm_register(&pdev->dev,
  458. &ark1668_i2s_dmaengine_pcm_config,
  459. 0);
  460. // ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
  461. if (ret) {
  462. dev_err(&pdev->dev, "Could not register PCM\n");
  463. return ret;
  464. }
  465. printk("end:==============[%s]:[ %d]\n", __FUNCTION__, __LINE__);
  466. return 0;
  467. }
  468. //static int ark1668_i2s_drv_remove(struct platform_device *pdev)
  469. //{
  470. // struct ark_i2s_dev *i2s = platform_get_drvdata(pdev);
  471. // struct resource *mem;
  472. // return 0;
  473. //}
  474. static const struct of_device_id ark1668_i2s_match[] = {
  475. { .compatible = "arkmicro,ark1668-i2s", },
  476. {},
  477. };
  478. static struct platform_driver ark1668_i2s_driver = {
  479. .probe = ark1668_i2s_drv_probe,
  480. .driver = {
  481. .name = DRV_NAME,
  482. .of_match_table = of_match_ptr(ark1668_i2s_match),
  483. },
  484. };
  485. module_platform_driver(ark1668_i2s_driver);
  486. MODULE_AUTHOR("Jack Tang, jacktang@astri.org");
  487. MODULE_DESCRIPTION("ARK I2S SoC Interface");
  488. MODULE_LICENSE("GPL");