aml_mixer.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. #include <sound/core.h>
  2. #include <sound/control.h>
  3. #include <sound/pcm.h>
  4. #include <sound/initval.h>
  5. #include <linux/soundcard.h>
  6. #include "aml_pcm.h"
  7. #include "aml_alsa_common.h"
  8. #include "aml_audio_hw.h"
  9. extern audio_tone_control_t audio_tone_control;
  10. static int pcm_pb_volume_info(struct snd_kcontrol *kcontrol,
  11. struct snd_ctl_elem_info *uinfo)
  12. {
  13. uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  14. uinfo->count = 1;
  15. uinfo->value.integer.min = 0;
  16. uinfo->value.integer.max = 100;
  17. uinfo->value.integer.step = 1;
  18. return 0;
  19. }
  20. static int pcm_pb_volume_get(struct snd_kcontrol *kcontrol,
  21. struct snd_ctl_elem_value *uvalue)
  22. {
  23. int val;
  24. val = get_mixer_output_volume();
  25. val = val & 0xff;
  26. uvalue->value.integer.value[0] = val;
  27. return 0;
  28. }
  29. static int pcm_pb_volume_put(struct snd_kcontrol *kcontrol,
  30. struct snd_ctl_elem_value *uvalue)
  31. {
  32. int volume;
  33. volume = uvalue->value.integer.value[0];
  34. // volume = volume | (volume << 8);
  35. set_mixer_output_volume(volume);
  36. return 0;
  37. }
  38. static int pcm_pb_mute_info(struct snd_kcontrol *kcontrol,
  39. struct snd_ctl_elem_info *uinfo)
  40. {
  41. uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
  42. uinfo->count = 1;
  43. uinfo->value.integer.min = 0;
  44. uinfo->value.integer.max = 1;
  45. return 0;
  46. }
  47. static int pcm_pb_mute_get(struct snd_kcontrol *kcontrol,
  48. struct snd_ctl_elem_value *uvalue)
  49. {
  50. return 0;
  51. }
  52. static int pcm_pb_mute_put(struct snd_kcontrol *kcontrol,
  53. struct snd_ctl_elem_value *uvalue)
  54. {
  55. int flag;
  56. flag = uvalue->value.integer.value[0];
  57. if(flag)
  58. audio_i2s_unmute();
  59. else
  60. audio_i2s_mute();
  61. return 0;
  62. }
  63. static int pcm_left_mono_info(struct snd_kcontrol *kcontrol,
  64. struct snd_ctl_elem_info *uinfo)
  65. {
  66. uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
  67. uinfo->count = 1;
  68. uinfo->value.integer.min = 0;
  69. uinfo->value.integer.max = 1;
  70. return 0;
  71. }
  72. static int pcm_left_mono_get(struct snd_kcontrol *kcontrol,
  73. struct snd_ctl_elem_value *uvalue)
  74. {
  75. return 0;
  76. }
  77. static int pcm_left_mono_put(struct snd_kcontrol *kcontrol,
  78. struct snd_ctl_elem_value *uvalue)
  79. {
  80. int flag;
  81. flag = uvalue->value.integer.value[0];
  82. if(flag){
  83. audio_i2s_swap_left_right(1);
  84. }
  85. return 0;
  86. }
  87. static int pcm_right_mono_info(struct snd_kcontrol *kcontrol,
  88. struct snd_ctl_elem_info *uinfo)
  89. {
  90. uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
  91. uinfo->count = 1;
  92. uinfo->value.integer.min = 0;
  93. uinfo->value.integer.max = 1;
  94. return 0;
  95. }
  96. static int pcm_right_mono_get(struct snd_kcontrol *kcontrol,
  97. struct snd_ctl_elem_value *uvalue)
  98. {
  99. return 0;
  100. }
  101. static int pcm_right_mono_put(struct snd_kcontrol *kcontrol,
  102. struct snd_ctl_elem_value *uvalue)
  103. {
  104. int flag;
  105. flag = uvalue->value.integer.value[0];
  106. if(flag){
  107. audio_i2s_swap_left_right(2);
  108. }
  109. return 0;
  110. }
  111. static int pcm_stereo_info(struct snd_kcontrol *kcontrol,
  112. struct snd_ctl_elem_info *uinfo)
  113. {
  114. uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
  115. uinfo->count = 1;
  116. uinfo->value.integer.min = 0;
  117. uinfo->value.integer.max = 1;
  118. return 0;
  119. }
  120. static int pcm_stereo_get(struct snd_kcontrol *kcontrol,
  121. struct snd_ctl_elem_value *uvalue)
  122. {
  123. return 0;
  124. }
  125. static int pcm_stereo_put(struct snd_kcontrol *kcontrol,
  126. struct snd_ctl_elem_value *uvalue)
  127. {
  128. int flag;
  129. flag = uvalue->value.integer.value[0];
  130. if(flag){
  131. audio_i2s_swap_left_right(0);
  132. }
  133. return 0;
  134. }
  135. static int pcm_swap_info(struct snd_kcontrol *kcontrol,
  136. struct snd_ctl_elem_info *uinfo)
  137. {
  138. uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
  139. uinfo->count = 1;
  140. uinfo->value.integer.min = 0;
  141. uinfo->value.integer.max = 1;
  142. return 0;
  143. }
  144. static int pcm_swap_get(struct snd_kcontrol *kcontrol,
  145. struct snd_ctl_elem_value *uvalue)
  146. {
  147. return 0;
  148. }
  149. static int pcm_swap_put(struct snd_kcontrol *kcontrol,
  150. struct snd_ctl_elem_value *uvalue)
  151. {
  152. int flag;
  153. unsigned int reg;
  154. flag = uvalue->value.integer.value[0];
  155. if(flag){
  156. reg = read_i2s_mute_swap_reg();
  157. if((reg & 0x3))
  158. audio_i2s_swap_left_right(0);
  159. else
  160. audio_i2s_swap_left_right(3);
  161. }
  162. return 0;
  163. }
  164. static int pcm_pb_data_info(struct snd_kcontrol *kcontrol,
  165. struct snd_ctl_elem_info *uinfo)
  166. {
  167. uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
  168. uinfo->count = 128;
  169. return 0;
  170. }
  171. static int pcm_pb_data_get(struct snd_kcontrol *kcontrol,
  172. struct snd_ctl_elem_value *uvalue)
  173. {
  174. unsigned int rd_ptr;
  175. rd_ptr = read_i2s_rd_ptr();
  176. memcpy(uvalue->value.bytes.data, (unsigned char*)rd_ptr, 128);
  177. return 0;
  178. }
  179. static int pcm_pb_tone_info(struct snd_kcontrol *kcontrol,
  180. struct snd_ctl_elem_info *uinfo)
  181. {
  182. uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
  183. uinfo->count = 1;
  184. uinfo->value.integer.min = 0;
  185. uinfo->value.integer.max = 1;
  186. return 0;
  187. }
  188. static int pcm_pb_tone_put(struct snd_kcontrol *kcontrol,
  189. struct snd_ctl_elem_value *uvalue)
  190. {
  191. audio_tone_control.tone_flag = 1;
  192. return 0;
  193. }
  194. static int pcm_pb_tone_get(struct snd_kcontrol *kcontrol,
  195. struct snd_ctl_elem_value *uvalue)
  196. {
  197. return 0;
  198. }
  199. struct snd_kcontrol_new pcm_control_pb_vol = {
  200. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  201. .name = "Master Playback Volume",
  202. .index = 0x00,
  203. .info = pcm_pb_volume_info,
  204. .get = pcm_pb_volume_get,
  205. .put = pcm_pb_volume_put,
  206. .private_value = 0x0,
  207. };
  208. struct snd_kcontrol_new pcm_switch_pb_mute = {
  209. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  210. .name = "switch playback mute",
  211. .index = 0x00,
  212. .info = pcm_pb_mute_info,
  213. .get = pcm_pb_mute_get,
  214. .put = pcm_pb_mute_put,
  215. .private_value = 0xff,
  216. };
  217. struct snd_kcontrol_new pcm_pb_left_mono = {
  218. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  219. .name = "Playback Left Mono",
  220. .index = 0x00,
  221. .info = pcm_left_mono_info,
  222. .get = pcm_left_mono_get,
  223. .put = pcm_left_mono_put,
  224. .private_value = 0xff,
  225. };
  226. struct snd_kcontrol_new pcm_pb_right_mono = {
  227. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  228. .name = "Playback Right Mono",
  229. .index = 0x00,
  230. .info = pcm_right_mono_info,
  231. .get = pcm_right_mono_get,
  232. .put = pcm_right_mono_put,
  233. .private_value = 0xff,
  234. };
  235. struct snd_kcontrol_new pcm_pb_stereo = {
  236. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  237. .name = "Playback Stereo Out",
  238. .index = 0x00,
  239. .info = pcm_stereo_info,
  240. .get = pcm_stereo_get,
  241. .put = pcm_stereo_put,
  242. .private_value = 0xff,
  243. };
  244. struct snd_kcontrol_new pcm_pb_swap = {
  245. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  246. .name = "Playback Swap Left Right",
  247. .index = 0x00,
  248. .info = pcm_swap_info,
  249. .get = pcm_swap_get,
  250. .put = pcm_swap_put,
  251. .private_value = 0xff,
  252. };
  253. struct snd_kcontrol_new pcm_data_read = {
  254. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  255. .name = "Playback Data Get",
  256. .info = pcm_pb_data_info,
  257. .get = pcm_pb_data_get,
  258. .access = (SNDRV_CTL_ELEM_ACCESS_READ |
  259. SNDRV_CTL_ELEM_ACCESS_VOLATILE),
  260. };
  261. struct snd_kcontrol_new pcm_tone_play = {
  262. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  263. .name = "Playback Tone",
  264. .info = pcm_pb_tone_info,
  265. .put = pcm_pb_tone_put,
  266. .get = pcm_pb_tone_get,
  267. .access = (SNDRV_CTL_ELEM_ACCESS_WRITE |
  268. SNDRV_CTL_ELEM_ACCESS_READ),
  269. };
  270. int aml_alsa_create_ctrl(struct snd_card *card, void *p_value)
  271. {
  272. int err = 0;
  273. if ((err =
  274. snd_ctl_add(card,
  275. snd_ctl_new1(&pcm_control_pb_vol, p_value))) < 0)
  276. return err;
  277. if ((err =
  278. snd_ctl_add(card,
  279. snd_ctl_new1(&pcm_switch_pb_mute, p_value))) < 0)
  280. return err;
  281. if ((err =
  282. snd_ctl_add(card,
  283. snd_ctl_new1(&pcm_pb_left_mono, p_value))) < 0)
  284. return err;
  285. if ((err =
  286. snd_ctl_add(card,
  287. snd_ctl_new1(&pcm_pb_right_mono, p_value))) < 0)
  288. return err;
  289. if ((err =
  290. snd_ctl_add(card,
  291. snd_ctl_new1(&pcm_pb_stereo, p_value))) < 0)
  292. return err;
  293. if ((err =
  294. snd_ctl_add(card,
  295. snd_ctl_new1(&pcm_pb_swap, p_value))) < 0)
  296. return err;
  297. if ((err =
  298. snd_ctl_add(card,
  299. snd_ctl_new1(&pcm_data_read, p_value))) < 0)
  300. return err;
  301. if ((err =
  302. snd_ctl_add(card,
  303. snd_ctl_new1(&pcm_tone_play, p_value))) < 0)
  304. return err;
  305. return 0;
  306. }