arkn141_audio.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423
  1. /*
  2. * ark_sddac.c -- ALSA SoC audio for ark
  3. *
  4. */
  5. #include <linux/module.h>
  6. #include <linux/platform_device.h>
  7. #include <linux/io.h>
  8. #include <sound/core.h>
  9. #include <sound/pcm.h>
  10. #include <sound/soc.h>
  11. #include <sound/soc-dapm.h>
  12. #include <linux/clk.h>
  13. #define ARK_OUT_HP 0
  14. #define ARK_OUT_SPK 1
  15. #define ARK_STREAM_AVIN1 0
  16. #define ARK_STREAM_AVIN2 1
  17. #define ARK_STREAM_PLATFORM 2
  18. #define ARK_STREAM_BLUETOOTH 3
  19. static int ark_ir_ch_sel = 0;
  20. static int ark_ir_en_sel = 0;
  21. static int ark_out_sel = ARK_OUT_SPK;
  22. static int ark_stream_sel = ARK_STREAM_PLATFORM;
  23. static int ark_amp_volume = 80;
  24. static int ark_fm_freq = 765;
  25. static int ark_pa_mute = 0;
  26. static int ark_startup(struct snd_pcm_substream *substream)
  27. {
  28. int ret = 0;
  29. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  30. struct snd_soc_dai *codec_dai = rtd->codec_dai;
  31. /* variable MCLK */
  32. ret = snd_soc_dai_set_sysclk(codec_dai, 0, 0, SND_SOC_CLOCK_IN);
  33. return ret;
  34. }
  35. #define SYS_BASE 0x40408000
  36. #define DAC_I2S_NCO_CFG 0x16c
  37. #define ADC_I2S_NCO_CFG 0x15c
  38. #define I2S_CLK_FREQ 240000000
  39. static int ark_hw_params(
  40. struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params)
  41. {
  42. unsigned int val;
  43. void *sysreg;
  44. u32 rate = params_rate(params);
  45. u32 step, modulo = 18750;
  46. step = rate / (I2S_CLK_FREQ / 256 / 2 / modulo);
  47. val = (step << 16) | modulo;
  48. sysreg = ioremap(SYS_BASE, 0x1000);
  49. if (!sysreg) {
  50. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
  51. writel(val, sysreg + DAC_I2S_NCO_CFG);
  52. } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
  53. writel(val, sysreg + ADC_I2S_NCO_CFG);
  54. }
  55. iounmap(sysreg);
  56. }
  57. return 0;
  58. }
  59. static struct snd_soc_ops ark_ops = {
  60. .startup = ark_startup,
  61. .hw_params = ark_hw_params,
  62. };
  63. static int ark_get_output (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_value * ucontrol)
  64. {
  65. ucontrol->value.integer.value[0] = ark_out_sel;
  66. return 0;
  67. }
  68. static int ark_set_output (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_value * ucontrol)
  69. {
  70. //struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
  71. if (ark_out_sel == ucontrol->value.integer.value[0])
  72. return 0;
  73. ark_out_sel = ucontrol->value.integer.value[0];
  74. return 0;
  75. }
  76. static int ark_get_stream (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_value * ucontrol)
  77. {
  78. ucontrol->value.integer.value[0] = ark_stream_sel;
  79. return 0;
  80. }
  81. static int ark_set_stream (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_value * ucontrol)
  82. {
  83. //struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
  84. if (ark_stream_sel == ucontrol->value.integer.value[0])
  85. return 0;
  86. ark_stream_sel = ucontrol->value.integer.value[0];
  87. return 0;
  88. }
  89. static int ark_get_ir_status (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_value * ucontrol)
  90. {
  91. ucontrol->value.integer.value[0] = ark_ir_en_sel;
  92. return 0;
  93. }
  94. static int ark_set_ir_status (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_value * ucontrol)
  95. {
  96. //struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
  97. if (ark_ir_en_sel == ucontrol->value.integer.value[0])
  98. return 0;
  99. ark_ir_en_sel = ucontrol->value.integer.value[0];
  100. return 0;
  101. }
  102. static int ark_get_ir_channel (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_value * ucontrol)
  103. {
  104. ucontrol->value.integer.value[0] = ark_ir_ch_sel;
  105. return 0;
  106. }
  107. static int ark_set_ir_channel (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_value * ucontrol)
  108. {
  109. //struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
  110. if (ark_ir_en_sel == 0 || ark_ir_ch_sel == ucontrol->value.integer.value[0])
  111. return 0;
  112. ark_ir_ch_sel = ucontrol->value.integer.value[0];
  113. return 0;
  114. }
  115. static int ark_get_pa_mute_status (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_value * ucontrol)
  116. {
  117. ucontrol->value.integer.value[0] = ark_pa_mute;
  118. return 0;
  119. }
  120. static int ark_set_pa_mute_status (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_value * ucontrol)
  121. {
  122. //struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
  123. if (ark_pa_mute == ucontrol->value.integer.value[0])
  124. return 0;
  125. ark_pa_mute = ucontrol->value.integer.value[0];
  126. return 0;
  127. }
  128. static int ark_get_amp_volume (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_value * ucontrol)
  129. {
  130. ucontrol->value.integer.value[0] = ark_amp_volume;
  131. return 0;
  132. }
  133. static int ark_set_amp_volume (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_value * ucontrol)
  134. {
  135. //struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
  136. if (ark_amp_volume == ucontrol->value.integer.value[0])
  137. return 0;
  138. ark_amp_volume = ucontrol->value.integer.value[0];
  139. return 0;
  140. }
  141. static int ark_get_fm_freq (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_value * ucontrol)
  142. {
  143. ucontrol->value.integer.value[0] = ark_fm_freq;
  144. return 0;
  145. }
  146. extern void fm_set_transfer_rate(int freq);
  147. static int ark_set_fm_freq (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_value * ucontrol)
  148. {
  149. //struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
  150. if (ark_fm_freq == ucontrol->value.integer.value[0])
  151. return 0;
  152. ark_fm_freq = ucontrol->value.integer.value[0];
  153. return 0;
  154. }
  155. static const char *stream_select[] = {
  156. "AVIN1",
  157. "AVIN2",
  158. "Platform",
  159. "Bluetooth"
  160. };
  161. static const char *out_select[] = {
  162. "Headphone Jack",
  163. "Ext Spk",
  164. };
  165. static const char *ir_status_select[] = {
  166. "IR_Off",
  167. "IR_On",
  168. };
  169. static const char *ir_ch_select[] = {
  170. "IR_ch0",
  171. "IR_ch1",
  172. };
  173. static const char *pa_mute_switch[] = {
  174. "PA_Mute_Off",
  175. "PA_Mute_On",
  176. };
  177. static const struct soc_enum ark_stream_sel_enum =
  178. SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(stream_select), stream_select);
  179. static const struct soc_enum ark_out_sel_enum =
  180. SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(out_select), out_select);
  181. static const struct soc_enum ark_ir_status_sel_enum =
  182. SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ir_status_select), ir_status_select);
  183. static const struct soc_enum ark_ir_ch_sel_enum =
  184. SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ir_ch_select), ir_ch_select);
  185. static const struct soc_enum ark_pa_mute_switch_enum =
  186. SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(pa_mute_switch), pa_mute_switch);
  187. static const struct snd_soc_dapm_widget ark_dapm_widgets[] = {
  188. SND_SOC_DAPM_HP("Headphone Jack", NULL),
  189. SND_SOC_DAPM_SPK("Ext Spk", NULL),
  190. };
  191. static const struct snd_soc_dapm_route ark_audio_map[] = {
  192. {"Headphone Jack", NULL, "LOUT"},
  193. {"Headphone Jack", NULL, "ROUT"},
  194. {"Ext Spk", NULL, "ROUT"},
  195. {"Ext Spk", NULL, "LOUT"},
  196. };
  197. static const struct snd_kcontrol_new ark_controls[] = {
  198. SOC_ENUM_EXT("Stream Select", ark_stream_sel_enum,
  199. ark_get_stream, ark_set_stream),
  200. SOC_ENUM_EXT("Output Select", ark_out_sel_enum,
  201. ark_get_output, ark_set_output),
  202. SOC_SINGLE_EXT("AMP Volume", 0, 0, 99, 0,
  203. ark_get_amp_volume, ark_set_amp_volume),
  204. SOC_SINGLE_EXT("FM Freq", 0, 0, 1272, 0,
  205. ark_get_fm_freq, ark_set_fm_freq),
  206. SOC_ENUM_EXT("IR Status", ark_ir_status_sel_enum,
  207. ark_get_ir_status, ark_set_ir_status),
  208. SOC_ENUM_EXT("IR Channel", ark_ir_ch_sel_enum,
  209. ark_get_ir_channel, ark_set_ir_channel),
  210. SOC_ENUM_EXT("PA Mute", ark_pa_mute_switch_enum,
  211. ark_get_pa_mute_status, ark_set_pa_mute_status),
  212. };
  213. static struct snd_soc_dai_link ark_dai[] = {
  214. {
  215. .name = "sddac",
  216. .stream_name = "sddac",
  217. .codec_dai_name = "ark-sddac-codec",
  218. .cpu_dai_name = "ark-i2s-dac",
  219. .codec_name = "ark-sddac",
  220. .ops = &ark_ops,
  221. .dai_fmt = SND_SOC_DAIFMT_I2S,
  222. },
  223. {
  224. .name = "sdadc",
  225. .stream_name = "sdadc",
  226. .codec_dai_name = "ark-sdadc-codec",
  227. .cpu_dai_name = "ark-i2s-adc",
  228. .codec_name = "ark-sdadc",
  229. .ops = &ark_ops,
  230. .dai_fmt = SND_SOC_DAIFMT_I2S,
  231. },
  232. #if 0
  233. {
  234. .name = "es8156",
  235. .stream_name = "es8156 "
  236. .codec_dai_name = "es8156-hifi"//es8156 dai_driver
  237. //cpu_dai_name = "ark-i2s-dac",
  238. .codec_name = "es8156",//i2c_driver name
  239. .ops = &ark_ops,
  240. .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
  241. | SND_SOC_DAIFMT_CBS_CFS,
  242. },
  243. {
  244. .name = "es7243e ",
  245. .stream_name = "es7243e "
  246. .codec_dai_name = "es7243e-hifi",//es7243e dai_driver
  247. //cpu_dai_name = "ark-i2s-dac",
  248. .codec_name = "es7243e",//i2c_driver name
  249. .ops = &ark_ops,
  250. .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
  251. | SND_SOC_DAIFMT_CBS_CFS,
  252. },
  253. #endif
  254. };
  255. static struct snd_soc_dai_link ark_dai_es7243e[] = {
  256. .name = "es7243e ",
  257. .stream_name = "es7243e "
  258. .codec_dai_name = "es7243e-hifi",//es7243e dai_driver
  259. //cpu_dai_name = "ark-i2s-dac",
  260. .codec_name = "es7243e",//i2c_driver name
  261. .ops = &ark_ops,
  262. .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
  263. | SND_SOC_DAIFMT_CBS_CFS,
  264. };
  265. static struct snd_soc_dai_link ark_dai_es8156[] = {
  266. .name = "es8156",
  267. .stream_name = "es8156 "
  268. .codec_dai_name = "es8156-hifi"//es8156 dai_driver
  269. //cpu_dai_name = "ark-i2s-dac",
  270. .codec_name = "es8156",//i2c_driver name
  271. .ops = &ark_ops,
  272. .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
  273. | SND_SOC_DAIFMT_CBS_CFS,
  274. };
  275. static struct snd_soc_card arkn141_audio = {
  276. {
  277. .name = "arkn141-audio",
  278. .owner = THIS_MODULE,
  279. .dai_link = ark_dai,
  280. .num_links = ARRAY_SIZE(ark_dai),
  281. .controls = ark_controls,
  282. .num_controls = ARRAY_SIZE(ark_controls),
  283. .dapm_widgets = ark_dapm_widgets,
  284. .num_dapm_widgets = ARRAY_SIZE(ark_dapm_widgets),
  285. .dapm_routes = ark_audio_map,
  286. .num_dapm_routes = ARRAY_SIZE(ark_audio_map),
  287. }
  288. #if 1
  289. {
  290. .name = "es8156",/* proc/asound/cards */
  291. .owner = THIS_MODULE,
  292. .dai_link = ark_dai_es8156,
  293. .num_links = ARRAY_SIZE(ark_dai_es8156),
  294. .controls = ark_controls,
  295. .num_controls = ARRAY_SIZE(ark_controls),
  296. .dapm_widgets = ark_dapm_widgets,
  297. .num_dapm_widgets = ARRAY_SIZE(ark_dapm_widgets),
  298. .dapm_routes = ark_audio_map,
  299. .num_dapm_routes = ARRAY_SIZE(ark_audio_map),
  300. }
  301. {
  302. .name = "es7243e",/* proc/asound/cards */
  303. .owner = THIS_MODULE,
  304. .dai_link = ark_dai_es7243e,
  305. .num_links = ARRAY_SIZE(ark_dai_es7243e),
  306. .controls = ark_controls,
  307. .num_controls = ARRAY_SIZE(ark_controls),
  308. .dapm_widgets = ark_dapm_widgets,
  309. .num_dapm_widgets = ARRAY_SIZE(ark_dapm_widgets),
  310. .dapm_routes = ark_audio_map,
  311. .num_dapm_routes = ARRAY_SIZE(ark_audio_map),
  312. }
  313. #endif
  314. };
  315. static int arkn141_audio_probe(struct platform_device *pdev)
  316. {
  317. #if 0
  318. struct snd_soc_card *card = &arkn141_audio;
  319. int ret;
  320. card->dev = &pdev->dev;
  321. ret = devm_snd_soc_register_card(&pdev->dev, card);
  322. if (ret)
  323. dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
  324. ret);
  325. #else
  326. int ret;
  327. arkn141_audio[pdev->id].dev = &pdev->dev;
  328. ret = devm_snd_soc_register_card(&pdev->dev, &arkn141_audio[pdev->id]);
  329. if (ret)
  330. dev_err(&pdev->dev,
  331. "snd_soc_register_card(%s) failed: %d\n",
  332. arkn141_audio[pdev->id].name, ret);
  333. #endif
  334. return ret;
  335. }
  336. static const struct of_device_id arkn141_audio_of_match[] = {
  337. {
  338. .compatible = "arkmicro,arkn141-audio",
  339. }, {
  340. /* sentinel */
  341. }
  342. };
  343. MODULE_DEVICE_TABLE(of, arkn141_audio_of_match);
  344. static struct platform_driver arkn141_audio_driver = {
  345. .probe = arkn141_audio_probe,
  346. .driver = {
  347. .name = "arkn141-audio",
  348. .of_match_table = of_match_ptr(arkn141_audio_of_match),
  349. },
  350. };
  351. module_platform_driver(arkn141_audio_driver);
  352. MODULE_DESCRIPTION("Arkmicro audio driver under ALSA SoC architecture");
  353. MODULE_AUTHOR("Sim");
  354. MODULE_LICENSE("GPL v2");