escore-i2s.c 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. /*
  2. * escore-i2s.c -- Audience eScore I2S interface
  3. *
  4. * Copyright 2011 Audience, Inc.
  5. *
  6. * Author: Greg Clemson <gclemson@audience.com>
  7. *
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License version 2 as
  11. * published by the Free Software Foundation.
  12. */
  13. #include <linux/module.h>
  14. #include <linux/moduleparam.h>
  15. #include <linux/init.h>
  16. #include <linux/firmware.h>
  17. #include <linux/delay.h>
  18. #include <linux/pm.h>
  19. #include <linux/completion.h>
  20. #include <linux/gpio.h>
  21. #include <linux/platform_device.h>
  22. #include <linux/slab.h>
  23. #include <linux/err.h>
  24. #include <sound/core.h>
  25. #include <sound/pcm.h>
  26. #include <sound/pcm_params.h>
  27. #include <sound/soc.h>
  28. #include <sound/soc-dapm.h>
  29. #include <sound/initval.h>
  30. #include <sound/tlv.h>
  31. #include <linux/kthread.h>
  32. #include <linux/esxxx.h>
  33. #include "escore.h"
  34. #include "es515.h"
  35. #include "escore-list.h"
  36. static int escore_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id,
  37. unsigned int freq, int dir)
  38. {
  39. struct snd_soc_codec *codec = dai->codec;
  40. int rc = 0;
  41. dev_dbg(codec->dev, "%s()\n", __func__);
  42. return rc;
  43. }
  44. static int escore_i2s_set_pll(struct snd_soc_dai *dai, int pll_id,
  45. int source, unsigned int freq_in,
  46. unsigned int freq_out)
  47. {
  48. struct snd_soc_codec *codec = dai->codec;
  49. int rc = 0;
  50. dev_dbg(codec->dev, "%s()\n", __func__);
  51. return rc;
  52. }
  53. static int escore_i2s_set_clkdiv(struct snd_soc_dai *dai, int div_id,
  54. int div)
  55. {
  56. struct snd_soc_codec *codec = dai->codec;
  57. int rc = 0;
  58. dev_dbg(codec->dev, "%s()\n", __func__);
  59. return rc;
  60. }
  61. static int escore_i2s_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
  62. {
  63. struct snd_soc_codec *codec = dai->codec;
  64. int rc = 0;
  65. dev_dbg(codec->dev, "%s()\n", __func__);
  66. return rc;
  67. }
  68. static int escore_i2s_set_tdm_slot(struct snd_soc_dai *dai,
  69. unsigned int tx_mask, unsigned int rx_mask,
  70. int slots, int slot_width)
  71. {
  72. struct snd_soc_codec *codec = dai->codec;
  73. int rc = 0;
  74. dev_dbg(codec->dev, "%s()\n", __func__);
  75. return rc;
  76. }
  77. static int escore_i2s_set_channel_map(struct snd_soc_dai *dai,
  78. unsigned int tx_num, unsigned int *tx_slot,
  79. unsigned int rx_num, unsigned int *rx_slot)
  80. {
  81. struct snd_soc_codec *codec = dai->codec;
  82. int rc = 0;
  83. dev_dbg(codec->dev, "%s()\n", __func__);
  84. return rc;
  85. }
  86. static int escore_i2s_set_tristate(struct snd_soc_dai *dai, int tristate)
  87. {
  88. struct snd_soc_codec *codec = dai->codec;
  89. unsigned int paramid = 0;
  90. unsigned int val = 0;
  91. dev_dbg(codec->dev, "%s()\n", __func__);
  92. switch (dai->id) {
  93. case 0:
  94. break;
  95. case 1:
  96. break;
  97. default:
  98. return -EINVAL;
  99. }
  100. if (tristate)
  101. val = 0x0001;
  102. else
  103. val = 0x0000;
  104. return snd_soc_write(codec, paramid, val);
  105. }
  106. static int escore_i2s_port_mute(struct snd_soc_dai *dai, int mute)
  107. {
  108. struct snd_soc_codec *codec = dai->codec;
  109. unsigned int paramid = 0;
  110. unsigned int val = 0;
  111. dev_dbg(codec->dev, "%s()\n", __func__);
  112. /* Is this valid since DACs are not statically mapped to DAIs? */
  113. switch (dai->id) {
  114. case 0:
  115. break;
  116. case 1:
  117. break;
  118. default:
  119. return -EINVAL;
  120. }
  121. if (mute)
  122. val = 0x0000;
  123. else
  124. val = 0x0001;
  125. return snd_soc_write(codec, paramid, val);
  126. }
  127. static int escore_i2s_startup(struct snd_pcm_substream *substream,
  128. struct snd_soc_dai *dai)
  129. {
  130. struct snd_soc_codec *codec = dai->codec;
  131. struct escore_priv *escore = snd_soc_codec_get_drvdata(codec);
  132. int rc = 0;
  133. dev_dbg(codec->dev, "%s(): dai->name = %s, dai->id = %d\n", __func__,
  134. dai->name, dai->id);
  135. atomic_inc(&escore->active_streams);
  136. return rc;
  137. }
  138. static void escore_i2s_shutdown(struct snd_pcm_substream *substream,
  139. struct snd_soc_dai *dai)
  140. {
  141. struct snd_soc_codec *codec = dai->codec;
  142. struct escore_priv *escore = snd_soc_codec_get_drvdata(codec);
  143. dev_dbg(codec->dev, "%s(): dai->name = %s, dai->id = %d\n", __func__,
  144. dai->name, dai->id);
  145. atomic_dec(&escore->active_streams);
  146. if (!atomic_read(&escore->active_streams))
  147. escore_flush_msg_list(escore);
  148. }
  149. static int escore_i2s_hw_params(struct snd_pcm_substream *substream,
  150. struct snd_pcm_hw_params *params,
  151. struct snd_soc_dai *dai)
  152. {
  153. struct snd_soc_codec *codec = dai->codec;
  154. struct escore_priv *escore = snd_soc_codec_get_drvdata(codec);
  155. int bits_per_sample = 0;
  156. int rc = 0;
  157. dev_dbg(codec->dev, "%s(): dai->name = %s, dai->id = %d\n", __func__,
  158. dai->name, dai->id);
  159. switch (dai->id) {
  160. case ES_I2S_PORTA:
  161. dev_dbg(codec->dev, "%s(): ES_PORTA_PARAM_ID\n", __func__);
  162. break;
  163. case ES_I2S_PORTB:
  164. dev_dbg(codec->dev, "%s(): ES_PORTB_PARAM_ID\n", __func__);
  165. break;
  166. default:
  167. dev_dbg(codec->dev, "%s(): unknown port\n", __func__);
  168. return -EINVAL;
  169. }
  170. dev_dbg(codec->dev, "%s(): params_channels(params) = %d\n", __func__,
  171. params_channels(params));
  172. switch (params_channels(params)) {
  173. case 1:
  174. dev_dbg(codec->dev, "%s(): 1 channel\n", __func__);
  175. break;
  176. case 2:
  177. dev_dbg(codec->dev, "%s(): 2 channels\n", __func__);
  178. break;
  179. case 4:
  180. dev_dbg(codec->dev, "%s(): 4 channels\n", __func__);
  181. break;
  182. default:
  183. dev_dbg(codec->dev, "%s(): unsupported number of channels\n",
  184. __func__);
  185. return -EINVAL;
  186. }
  187. dev_dbg(codec->dev, "%s(): params_rate(params) = %d\n", __func__,
  188. params_rate(params));
  189. switch (params_rate(params)) {
  190. case 8000:
  191. dev_dbg(codec->dev, "%s(): 8000Hz\n", __func__);
  192. break;
  193. case 11025:
  194. dev_dbg(codec->dev, "%s(): 11025\n", __func__);
  195. break;
  196. case 16000:
  197. dev_dbg(codec->dev, "%s(): 16000\n", __func__);
  198. break;
  199. case 22050:
  200. dev_dbg(codec->dev, "%s(): 22050\n", __func__);
  201. break;
  202. case 32000:
  203. dev_dbg(codec->dev, "%s(): 32000\n", __func__);
  204. break;
  205. case 48000:
  206. dev_dbg(codec->dev, "%s(): 48000\n", __func__);
  207. break;
  208. case 96000:
  209. dev_dbg(codec->dev, "%s(): 96000\n", __func__);
  210. break;
  211. case 192000:
  212. dev_dbg(codec->dev, "%s(): 96000\n", __func__);
  213. break;
  214. default:
  215. dev_dbg(codec->dev, "%s(): unsupported rate = %d\n", __func__,
  216. params_rate(params));
  217. return -EINVAL;
  218. }
  219. switch (params_format(params)) {
  220. case SNDRV_PCM_FORMAT_S16_LE:
  221. dev_dbg(codec->dev, "%s(): S16_LE\n", __func__);
  222. bits_per_sample = 16;
  223. break;
  224. case SNDRV_PCM_FORMAT_S16_BE:
  225. dev_dbg(codec->dev, "%s(): S16_BE\n", __func__);
  226. bits_per_sample = 16;
  227. break;
  228. case SNDRV_PCM_FORMAT_S20_3LE:
  229. dev_dbg(codec->dev, "%s(): S20_3LE\n", __func__);
  230. bits_per_sample = 20;
  231. break;
  232. case SNDRV_PCM_FORMAT_S20_3BE:
  233. dev_dbg(codec->dev, "%s(): S20_3BE\n", __func__);
  234. bits_per_sample = 20;
  235. break;
  236. case SNDRV_PCM_FORMAT_S24_LE:
  237. dev_dbg(codec->dev, "%s(): S24_LE\n", __func__);
  238. bits_per_sample = 24;
  239. break;
  240. case SNDRV_PCM_FORMAT_S24_BE:
  241. dev_dbg(codec->dev, "%s(): S24_BE\n", __func__);
  242. bits_per_sample = 24;
  243. break;
  244. case SNDRV_PCM_FORMAT_S32_LE:
  245. dev_dbg(codec->dev, "%s(): S32_LE\n", __func__);
  246. bits_per_sample = 32;
  247. break;
  248. case SNDRV_PCM_FORMAT_S32_BE:
  249. dev_dbg(codec->dev, "%s(): S32_BE\n", __func__);
  250. bits_per_sample = 32;
  251. break;
  252. default:
  253. dev_dbg(codec->dev, "%s(): unknown format\n", __func__);
  254. return -EINVAL;
  255. }
  256. if (rc) {
  257. dev_dbg(codec->dev, "%s(): snd_soc_update_bits() failed\n",
  258. __func__);
  259. return rc;
  260. }
  261. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  262. dev_dbg(codec->dev, "%s(): PLAYBACK\n", __func__);
  263. else
  264. dev_dbg(codec->dev, "%s(): CAPTURE\n", __func__);
  265. escore_write_msg_list(escore);
  266. return rc;
  267. }
  268. static int escore_i2s_hw_free(struct snd_pcm_substream *substream,
  269. struct snd_soc_dai *dai)
  270. {
  271. struct snd_soc_codec *codec = dai->codec;
  272. int rc = 0;
  273. dev_dbg(codec->dev, "%s() dai->name = %s, dai->id = %d\n", __func__,
  274. dai->name, dai->id);
  275. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  276. dev_dbg(codec->dev, "%s(): PLAYBACK\n", __func__);
  277. else
  278. dev_dbg(codec->dev, "%s(): CAPTURE\n", __func__);
  279. return rc;
  280. }
  281. static int escore_i2s_prepare(struct snd_pcm_substream *substream,
  282. struct snd_soc_dai *dai)
  283. {
  284. struct snd_soc_codec *codec = dai->codec;
  285. int rc = 0;
  286. dev_dbg(codec->dev, "%s() dai->name = %s, dai->id = %d\n", __func__,
  287. dai->name, dai->id);
  288. return rc;
  289. }
  290. static int escore_i2s_trigger(struct snd_pcm_substream *substream,
  291. int cmd, struct snd_soc_dai *dai)
  292. {
  293. struct snd_soc_codec *codec = dai->codec;
  294. int rc = 0;
  295. dev_dbg(codec->dev, "%s() dai->name = %s, dai->id = %d\n", __func__,
  296. dai->name, dai->id);
  297. switch (cmd) {
  298. case SNDRV_PCM_TRIGGER_START:
  299. break;
  300. case SNDRV_PCM_TRIGGER_STOP:
  301. break;
  302. }
  303. return rc;
  304. }
  305. struct snd_soc_dai_ops escore_i2s_port_dai_ops = {
  306. .set_sysclk = escore_i2s_set_sysclk,
  307. .set_pll = escore_i2s_set_pll,
  308. .set_clkdiv = escore_i2s_set_clkdiv,
  309. .set_fmt = escore_i2s_set_dai_fmt,
  310. .set_tdm_slot = escore_i2s_set_tdm_slot,
  311. .set_channel_map = escore_i2s_set_channel_map,
  312. .set_tristate = escore_i2s_set_tristate,
  313. .digital_mute = escore_i2s_port_mute,
  314. .startup = escore_i2s_startup,
  315. .shutdown = escore_i2s_shutdown,
  316. .hw_params = escore_i2s_hw_params,
  317. .hw_free = escore_i2s_hw_free,
  318. .prepare = escore_i2s_prepare,
  319. .trigger = escore_i2s_trigger,
  320. };
  321. MODULE_DESCRIPTION("ASoC ES driver");
  322. MODULE_AUTHOR("Greg Clemson <gclemson@audience.com>");
  323. MODULE_LICENSE("GPL");