msm7x30.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005
  1. /* Copyright (c) 2008-2011, The Linux Foundation. All rights reserved.
  2. *
  3. * All source code in this file is licensed under the following license except
  4. * where indicated.
  5. *
  6. * This program is free software; you can redistribute it and/or modify it
  7. * under the terms of the GNU General Public License version 2 as published
  8. * by the Free Software Foundation.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. *
  14. * See the GNU General Public License for more details.
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, you can find it at http://www.fsf.org.
  17. */
  18. #include <linux/init.h>
  19. #include <linux/err.h>
  20. #include <linux/module.h>
  21. #include <linux/moduleparam.h>
  22. #include <linux/time.h>
  23. #include <linux/wait.h>
  24. #include <linux/platform_device.h>
  25. #include <sound/core.h>
  26. #include <sound/soc.h>
  27. #include <sound/soc-dapm.h>
  28. #include <sound/pcm.h>
  29. #include <sound/tlv.h>
  30. #include <sound/initval.h>
  31. #include <sound/control.h>
  32. #include <asm/dma.h>
  33. #include <linux/dma-mapping.h>
  34. #include <linux/msm_audio.h>
  35. #include "msm7kv2-pcm.h"
  36. #include <asm/mach-types.h>
  37. #include <mach/qdsp5v2/audio_dev_ctl.h>
  38. #include <mach/debug_mm.h>
  39. #include <mach/qdsp5v2/afe.h>
  40. static struct platform_device *msm_audio_snd_device;
  41. struct audio_locks the_locks;
  42. EXPORT_SYMBOL(the_locks);
  43. struct msm_volume msm_vol_ctl;
  44. EXPORT_SYMBOL(msm_vol_ctl);
  45. static struct snd_kcontrol_new snd_msm_controls[];
  46. char snddev_name[AUDIO_DEV_CTL_MAX_DEV][44];
  47. #define MSM_MAX_VOLUME 0x2000
  48. #define MSM_VOLUME_STEP ((MSM_MAX_VOLUME+17)/100) /* 17 added to avoid
  49. more deviation */
  50. #define LOOPBACK_ENABLE 0x1
  51. #define LOOPBACK_DISABLE 0x0
  52. static int device_index; /* Count of Device controls */
  53. static int simple_control; /* Count of simple controls*/
  54. static int src_dev;
  55. static int dst_dev;
  56. static int loopback_status;
  57. static int msm_scontrol_count_info(struct snd_kcontrol *kcontrol,
  58. struct snd_ctl_elem_info *uinfo)
  59. {
  60. uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  61. uinfo->count = 1;
  62. return 0;
  63. }
  64. static int msm_scontrol_count_get(struct snd_kcontrol *kcontrol,
  65. struct snd_ctl_elem_value *ucontrol)
  66. {
  67. ucontrol->value.integer.value[0] = simple_control;
  68. return 0;
  69. }
  70. static int msm_v_call_info(struct snd_kcontrol *kcontrol,
  71. struct snd_ctl_elem_info *uinfo)
  72. {
  73. uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  74. uinfo->count = 1;
  75. uinfo->value.integer.min = 0;
  76. uinfo->value.integer.max = 1;
  77. return 0;
  78. }
  79. static int msm_v_call_get(struct snd_kcontrol *kcontrol,
  80. struct snd_ctl_elem_value *ucontrol)
  81. {
  82. ucontrol->value.integer.value[0] = 0;
  83. return 0;
  84. }
  85. static int msm_v_call_put(struct snd_kcontrol *kcontrol,
  86. struct snd_ctl_elem_value *ucontrol)
  87. {
  88. int start = ucontrol->value.integer.value[0];
  89. if (start)
  90. broadcast_event(AUDDEV_EVT_START_VOICE, DEVICE_IGNORE,
  91. SESSION_IGNORE);
  92. else
  93. broadcast_event(AUDDEV_EVT_END_VOICE, DEVICE_IGNORE,
  94. SESSION_IGNORE);
  95. return 0;
  96. }
  97. static int msm_v_mute_info(struct snd_kcontrol *kcontrol,
  98. struct snd_ctl_elem_info *uinfo)
  99. {
  100. uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  101. uinfo->count = 2;
  102. uinfo->value.integer.min = 0;
  103. uinfo->value.integer.max = 2;
  104. return 0;
  105. }
  106. static int msm_v_mute_get(struct snd_kcontrol *kcontrol,
  107. struct snd_ctl_elem_value *ucontrol)
  108. {
  109. ucontrol->value.integer.value[0] = 0;
  110. return 0;
  111. }
  112. static int msm_v_mute_put(struct snd_kcontrol *kcontrol,
  113. struct snd_ctl_elem_value *ucontrol)
  114. {
  115. int dir = ucontrol->value.integer.value[0];
  116. int mute = ucontrol->value.integer.value[1];
  117. return msm_set_voice_mute(dir, mute);
  118. }
  119. static int msm_v_volume_info(struct snd_kcontrol *kcontrol,
  120. struct snd_ctl_elem_info *uinfo)
  121. {
  122. uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  123. uinfo->count = 2; /* Volume */
  124. uinfo->value.integer.min = 0;
  125. uinfo->value.integer.max = 100;
  126. return 0;
  127. }
  128. static int msm_v_volume_get(struct snd_kcontrol *kcontrol,
  129. struct snd_ctl_elem_value *ucontrol)
  130. {
  131. ucontrol->value.integer.value[0] = 0;
  132. return 0;
  133. }
  134. static int msm_v_volume_put(struct snd_kcontrol *kcontrol,
  135. struct snd_ctl_elem_value *ucontrol)
  136. {
  137. int dir = ucontrol->value.integer.value[0];
  138. int volume = ucontrol->value.integer.value[1];
  139. return msm_set_voice_vol(dir, volume);
  140. }
  141. static int msm_volume_info(struct snd_kcontrol *kcontrol,
  142. struct snd_ctl_elem_info *uinfo)
  143. {
  144. uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  145. uinfo->count = 3; /* Volume and 10-base multiply factor*/
  146. uinfo->value.integer.min = 0;
  147. /* limit the muliply factor to 4 decimal digit */
  148. uinfo->value.integer.max = 1000000;
  149. return 0;
  150. }
  151. static int msm_volume_get(struct snd_kcontrol *kcontrol,
  152. struct snd_ctl_elem_value *ucontrol)
  153. {
  154. ucontrol->value.integer.value[0] = 0;
  155. return 0;
  156. }
  157. static int msm_volume_put(struct snd_kcontrol *kcontrol,
  158. struct snd_ctl_elem_value *ucontrol)
  159. {
  160. int ret = 0;
  161. int session_id = ucontrol->value.integer.value[0];
  162. int volume = ucontrol->value.integer.value[1];
  163. int factor = ucontrol->value.integer.value[2];
  164. u32 session_mask = 0;
  165. if (factor > 10000)
  166. return -EINVAL;
  167. if ((volume < 0) || (volume/factor > 100))
  168. return -EINVAL;
  169. volume = (MSM_VOLUME_STEP * volume);
  170. /* Convert back to original decimal point by removing the 10-base factor
  171. * and discard the fractional portion
  172. */
  173. volume = volume/factor;
  174. if (volume > MSM_MAX_VOLUME)
  175. volume = MSM_MAX_VOLUME;
  176. /* Only Decoder volume control supported */
  177. session_mask = (0x1 << (session_id) << (8 * ((int)AUDDEV_CLNT_DEC-1)));
  178. msm_vol_ctl.volume = volume;
  179. MM_DBG("session_id %d, volume %d", session_id, volume);
  180. broadcast_event(AUDDEV_EVT_STREAM_VOL_CHG, DEVICE_IGNORE,
  181. session_mask);
  182. return ret;
  183. }
  184. static int msm_voice_info(struct snd_kcontrol *kcontrol,
  185. struct snd_ctl_elem_info *uinfo)
  186. {
  187. uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  188. uinfo->count = 3; /* Device */
  189. uinfo->value.integer.min = 0;
  190. uinfo->value.integer.max = msm_snddev_devcount();
  191. return 0;
  192. }
  193. static int msm_voice_put(struct snd_kcontrol *kcontrol,
  194. struct snd_ctl_elem_value *ucontrol)
  195. {
  196. int rc = 0;
  197. uint32_t rx_dev_id;
  198. uint32_t tx_dev_id;
  199. struct msm_snddev_info *rx_dev_info;
  200. struct msm_snddev_info *tx_dev_info;
  201. int set = ucontrol->value.integer.value[2];
  202. u32 session_mask;
  203. if (!set)
  204. return -EPERM;
  205. /* Rx Device Routing */
  206. rx_dev_id = ucontrol->value.integer.value[0];
  207. rx_dev_info = audio_dev_ctrl_find_dev(rx_dev_id);
  208. if (IS_ERR(rx_dev_info)) {
  209. MM_ERR("pass invalid dev_id\n");
  210. rc = PTR_ERR(rx_dev_info);
  211. return rc;
  212. }
  213. if (!(rx_dev_info->capability & SNDDEV_CAP_RX)) {
  214. MM_ERR("First Dev is supposed to be RX\n");
  215. return -EFAULT;
  216. }
  217. MM_DBG("route cfg %d STREAM_VOICE_RX type\n",
  218. rx_dev_id);
  219. msm_set_voc_route(rx_dev_info, AUDIO_ROUTE_STREAM_VOICE_RX,
  220. rx_dev_id);
  221. session_mask = 0x1 << (8 * ((int)AUDDEV_CLNT_VOC-1));
  222. broadcast_event(AUDDEV_EVT_DEV_CHG_VOICE, rx_dev_id, session_mask);
  223. /* Tx Device Routing */
  224. tx_dev_id = ucontrol->value.integer.value[1];
  225. tx_dev_info = audio_dev_ctrl_find_dev(tx_dev_id);
  226. if (IS_ERR(tx_dev_info)) {
  227. MM_ERR("pass invalid dev_id\n");
  228. rc = PTR_ERR(tx_dev_info);
  229. return rc;
  230. }
  231. if (!(tx_dev_info->capability & SNDDEV_CAP_TX)) {
  232. MM_ERR("Second Dev is supposed to be Tx\n");
  233. return -EFAULT;
  234. }
  235. MM_DBG("route cfg %d %d type\n",
  236. tx_dev_id, AUDIO_ROUTE_STREAM_VOICE_TX);
  237. msm_set_voc_route(tx_dev_info, AUDIO_ROUTE_STREAM_VOICE_TX,
  238. tx_dev_id);
  239. broadcast_event(AUDDEV_EVT_DEV_CHG_VOICE, tx_dev_id, session_mask);
  240. if (rx_dev_info->opened)
  241. broadcast_event(AUDDEV_EVT_DEV_RDY, rx_dev_id, session_mask);
  242. if (tx_dev_info->opened)
  243. broadcast_event(AUDDEV_EVT_DEV_RDY, tx_dev_id, session_mask);
  244. return rc;
  245. }
  246. static int msm_voice_get(struct snd_kcontrol *kcontrol,
  247. struct snd_ctl_elem_value *ucontrol)
  248. {
  249. ucontrol->value.integer.value[0] = 0;
  250. /* TODO: query Device list */
  251. return 0;
  252. }
  253. static int msm_device_info(struct snd_kcontrol *kcontrol,
  254. struct snd_ctl_elem_info *uinfo)
  255. {
  256. uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  257. uinfo->count = 1; /* Device */
  258. uinfo->value.integer.min = 0;
  259. uinfo->value.integer.max = msm_snddev_devcount();
  260. return 0;
  261. }
  262. static int msm_device_put(struct snd_kcontrol *kcontrol,
  263. struct snd_ctl_elem_value *ucontrol)
  264. {
  265. int rc = 0;
  266. int set = 0;
  267. struct msm_audio_route_config route_cfg;
  268. struct msm_snddev_info *dev_info;
  269. struct msm_snddev_info *dst_dev_info;
  270. struct msm_snddev_info *src_dev_info;
  271. int tx_freq = 0;
  272. int rx_freq = 0;
  273. u32 set_freq = 0;
  274. set = ucontrol->value.integer.value[0];
  275. route_cfg.dev_id = ucontrol->id.numid - device_index;
  276. dev_info = audio_dev_ctrl_find_dev(route_cfg.dev_id);
  277. if (IS_ERR(dev_info)) {
  278. MM_ERR("pass invalid dev_id\n");
  279. rc = PTR_ERR(dev_info);
  280. return rc;
  281. }
  282. MM_INFO("device %s set %d\n", dev_info->name, set);
  283. if (set) {
  284. if (!dev_info->opened) {
  285. set_freq = dev_info->sample_rate;
  286. if (!msm_device_is_voice(route_cfg.dev_id)) {
  287. msm_get_voc_freq(&tx_freq, &rx_freq);
  288. if (dev_info->capability & SNDDEV_CAP_TX)
  289. set_freq = tx_freq;
  290. if (set_freq == 0)
  291. set_freq = dev_info->sample_rate;
  292. } else
  293. set_freq = dev_info->sample_rate;
  294. MM_ERR("device freq =%d\n", set_freq);
  295. rc = dev_info->dev_ops.set_freq(dev_info, set_freq);
  296. if (rc < 0) {
  297. MM_ERR("device freq failed!\n");
  298. return rc;
  299. }
  300. dev_info->set_sample_rate = rc;
  301. rc = 0;
  302. rc = dev_info->dev_ops.open(dev_info);
  303. if (rc < 0) {
  304. MM_ERR("Enabling %s failed", dev_info->name);
  305. return rc;
  306. }
  307. dev_info->opened = 1;
  308. broadcast_event(AUDDEV_EVT_DEV_RDY, route_cfg.dev_id,
  309. SESSION_IGNORE);
  310. /* Event to notify client for device info */
  311. broadcast_event(AUDDEV_EVT_DEVICE_INFO,
  312. route_cfg.dev_id, SESSION_IGNORE);
  313. if ((route_cfg.dev_id == src_dev) ||
  314. (route_cfg.dev_id == dst_dev)) {
  315. dst_dev_info = audio_dev_ctrl_find_dev(
  316. dst_dev);
  317. if (IS_ERR(dst_dev_info)) {
  318. pr_err("dst_dev:%s:pass invalid"
  319. "dev_id\n", __func__);
  320. rc = PTR_ERR(dst_dev_info);
  321. return rc;
  322. }
  323. src_dev_info = audio_dev_ctrl_find_dev(
  324. src_dev);
  325. if (IS_ERR(src_dev_info)) {
  326. pr_err("src_dev:%s:pass invalid"
  327. "dev_id\n", __func__);
  328. rc = PTR_ERR(src_dev_info);
  329. return rc;
  330. }
  331. if ((dst_dev_info->opened) &&
  332. (src_dev_info->opened)) {
  333. pr_debug("%d: Enable afe_loopback\n",
  334. __LINE__);
  335. afe_ext_loopback(LOOPBACK_ENABLE,
  336. dst_dev_info->copp_id,
  337. src_dev_info->copp_id);
  338. loopback_status = 1;
  339. }
  340. }
  341. }
  342. } else {
  343. if (dev_info->opened) {
  344. broadcast_event(AUDDEV_EVT_REL_PENDING,
  345. route_cfg.dev_id,
  346. SESSION_IGNORE);
  347. rc = dev_info->dev_ops.close(dev_info);
  348. if (rc < 0) {
  349. MM_ERR("Snd device failed close!\n");
  350. return rc;
  351. } else {
  352. dev_info->opened = 0;
  353. broadcast_event(AUDDEV_EVT_DEV_RLS,
  354. route_cfg.dev_id,
  355. SESSION_IGNORE);
  356. }
  357. if (loopback_status == 1) {
  358. if ((route_cfg.dev_id == src_dev) ||
  359. (route_cfg.dev_id == dst_dev)) {
  360. dst_dev_info = audio_dev_ctrl_find_dev(
  361. dst_dev);
  362. if (IS_ERR(dst_dev_info)) {
  363. pr_err("dst_dev:%s:pass invalid"
  364. "dev_id\n", __func__);
  365. rc = PTR_ERR(dst_dev_info);
  366. return rc;
  367. }
  368. src_dev_info = audio_dev_ctrl_find_dev(
  369. src_dev);
  370. if (IS_ERR(src_dev_info)) {
  371. pr_err("dst_dev:%s:pass invalid"
  372. "dev_id\n", __func__);
  373. rc = PTR_ERR(src_dev_info);
  374. return rc;
  375. }
  376. pr_debug("%d: Disable afe_loopback\n",
  377. __LINE__);
  378. afe_ext_loopback(LOOPBACK_DISABLE,
  379. dst_dev_info->copp_id,
  380. src_dev_info->copp_id);
  381. loopback_status = 0;
  382. }
  383. }
  384. }
  385. }
  386. return rc;
  387. }
  388. static int msm_device_get(struct snd_kcontrol *kcontrol,
  389. struct snd_ctl_elem_value *ucontrol)
  390. {
  391. int rc = 0;
  392. struct msm_audio_route_config route_cfg;
  393. struct msm_snddev_info *dev_info;
  394. route_cfg.dev_id = ucontrol->id.numid - device_index;
  395. dev_info = audio_dev_ctrl_find_dev(route_cfg.dev_id);
  396. if (IS_ERR(dev_info)) {
  397. MM_ERR("pass invalid dev_id\n");
  398. rc = PTR_ERR(dev_info);
  399. return rc;
  400. }
  401. ucontrol->value.integer.value[0] = dev_info->copp_id;
  402. ucontrol->value.integer.value[1] = dev_info->capability;
  403. return 0;
  404. }
  405. static int msm_route_info(struct snd_kcontrol *kcontrol,
  406. struct snd_ctl_elem_info *uinfo)
  407. {
  408. uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  409. uinfo->count = 3; /* Device */
  410. uinfo->value.integer.min = 0;
  411. uinfo->value.integer.max = msm_snddev_devcount();
  412. return 0;
  413. }
  414. static int msm_route_get(struct snd_kcontrol *kcontrol,
  415. struct snd_ctl_elem_value *ucontrol)
  416. {
  417. ucontrol->value.integer.value[0] = 0;
  418. /* TODO: query Device list */
  419. return 0;
  420. }
  421. static int msm_route_put(struct snd_kcontrol *kcontrol,
  422. struct snd_ctl_elem_value *ucontrol)
  423. {
  424. int rc = 0;
  425. int enc_freq = 0;
  426. int requested_freq = 0;
  427. struct msm_audio_route_config route_cfg;
  428. struct msm_snddev_info *dev_info;
  429. int session_id = ucontrol->value.integer.value[0];
  430. int set = ucontrol->value.integer.value[2];
  431. u32 session_mask = 0;
  432. route_cfg.dev_id = ucontrol->value.integer.value[1];
  433. if (ucontrol->id.numid == 2)
  434. route_cfg.stream_type = AUDIO_ROUTE_STREAM_PLAYBACK;
  435. else
  436. route_cfg.stream_type = AUDIO_ROUTE_STREAM_REC;
  437. MM_DBG("route cfg %d %d type for popp %d set value %d\n",
  438. route_cfg.dev_id, route_cfg.stream_type, session_id, set);
  439. dev_info = audio_dev_ctrl_find_dev(route_cfg.dev_id);
  440. if (IS_ERR(dev_info)) {
  441. MM_ERR("pass invalid dev_id\n");
  442. rc = PTR_ERR(dev_info);
  443. return rc;
  444. }
  445. if (route_cfg.stream_type == AUDIO_ROUTE_STREAM_PLAYBACK) {
  446. rc = msm_snddev_set_dec(session_id, dev_info->copp_id, set);
  447. session_mask =
  448. (0x1 << (session_id) << (8 * ((int)AUDDEV_CLNT_DEC-1)));
  449. if (!set) {
  450. if (dev_info->opened) {
  451. broadcast_event(AUDDEV_EVT_REL_PENDING,
  452. route_cfg.dev_id,
  453. session_mask);
  454. broadcast_event(AUDDEV_EVT_DEV_RLS,
  455. route_cfg.dev_id,
  456. session_mask);
  457. }
  458. dev_info->sessions &= ~(session_mask);
  459. } else {
  460. dev_info->sessions = dev_info->sessions | session_mask;
  461. if (dev_info->opened) {
  462. broadcast_event(AUDDEV_EVT_DEV_RDY,
  463. route_cfg.dev_id,
  464. session_mask);
  465. /* Event to notify client for device info */
  466. broadcast_event(AUDDEV_EVT_DEVICE_INFO,
  467. route_cfg.dev_id,
  468. session_mask);
  469. }
  470. }
  471. } else {
  472. rc = msm_snddev_set_enc(session_id, dev_info->copp_id, set);
  473. session_mask =
  474. (0x1 << (session_id)) << (8 * ((int)AUDDEV_CLNT_ENC-1));
  475. if (!set) {
  476. if (dev_info->opened)
  477. broadcast_event(AUDDEV_EVT_DEV_RLS,
  478. route_cfg.dev_id,
  479. session_mask);
  480. dev_info->sessions &= ~(session_mask);
  481. } else {
  482. dev_info->sessions = dev_info->sessions | session_mask;
  483. enc_freq = msm_snddev_get_enc_freq(session_id);
  484. requested_freq = enc_freq;
  485. if (enc_freq > 0) {
  486. rc = msm_snddev_request_freq(&enc_freq,
  487. session_id,
  488. SNDDEV_CAP_TX,
  489. AUDDEV_CLNT_ENC);
  490. MM_DBG("sample rate configured %d"
  491. "sample rate requested %d\n",
  492. enc_freq, requested_freq);
  493. if ((rc <= 0) || (enc_freq != requested_freq)) {
  494. MM_DBG("msm_snddev_withdraw_freq\n");
  495. rc = msm_snddev_withdraw_freq
  496. (session_id,
  497. SNDDEV_CAP_TX, AUDDEV_CLNT_ENC);
  498. broadcast_event(AUDDEV_EVT_FREQ_CHG,
  499. route_cfg.dev_id,
  500. SESSION_IGNORE);
  501. }
  502. }
  503. if (dev_info->opened) {
  504. broadcast_event(AUDDEV_EVT_DEV_RDY,
  505. route_cfg.dev_id,
  506. session_mask);
  507. /* Event to notify client for device info */
  508. broadcast_event(AUDDEV_EVT_DEVICE_INFO,
  509. route_cfg.dev_id,
  510. session_mask);
  511. }
  512. }
  513. }
  514. if (rc < 0) {
  515. MM_ERR("device could not be assigned!\n");
  516. return -EFAULT;
  517. }
  518. return rc;
  519. }
  520. static int msm_device_volume_info(struct snd_kcontrol *kcontrol,
  521. struct snd_ctl_elem_info *uinfo)
  522. {
  523. uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  524. uinfo->count = 2;
  525. uinfo->value.integer.min = 0;
  526. uinfo->value.integer.max = 100;
  527. return 0;
  528. }
  529. static int msm_device_volume_get(struct snd_kcontrol *kcontrol,
  530. struct snd_ctl_elem_value *ucontrol)
  531. {
  532. struct msm_snddev_info *dev_info;
  533. int dev_id = ucontrol->value.integer.value[0];
  534. dev_info = audio_dev_ctrl_find_dev(dev_id);
  535. ucontrol->value.integer.value[0] = dev_info->dev_volume;
  536. return 0;
  537. }
  538. static int msm_device_volume_put(struct snd_kcontrol *kcontrol,
  539. struct snd_ctl_elem_value *ucontrol)
  540. {
  541. int rc = -EPERM;
  542. struct msm_snddev_info *dev_info;
  543. int dev_id = ucontrol->value.integer.value[0];
  544. int volume = ucontrol->value.integer.value[1];
  545. MM_DBG("dev_id = %d, volume = %d\n", dev_id, volume);
  546. dev_info = audio_dev_ctrl_find_dev(dev_id);
  547. if (IS_ERR(dev_info)) {
  548. rc = PTR_ERR(dev_info);
  549. MM_ERR("audio_dev_ctrl_find_dev failed. %ld\n",
  550. PTR_ERR(dev_info));
  551. return rc;
  552. }
  553. MM_DBG("dev_name = %s dev_id = %d, volume = %d\n",
  554. dev_info->name, dev_id, volume);
  555. if (dev_info->dev_ops.set_device_volume)
  556. rc = dev_info->dev_ops.set_device_volume(dev_info, volume);
  557. else {
  558. MM_INFO("device %s does not support device volume "
  559. "control.", dev_info->name);
  560. return -EPERM;
  561. }
  562. return rc;
  563. }
  564. static int msm_reset_info(struct snd_kcontrol *kcontrol,
  565. struct snd_ctl_elem_info *uinfo)
  566. {
  567. uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  568. uinfo->count = 1;
  569. uinfo->value.integer.min = 0;
  570. uinfo->value.integer.max = 0;
  571. return 0;
  572. }
  573. static int msm_reset_get(struct snd_kcontrol *kcontrol,
  574. struct snd_ctl_elem_value *ucontrol)
  575. {
  576. ucontrol->value.integer.value[0] = 0;
  577. return 0;
  578. }
  579. static int msm_reset_put(struct snd_kcontrol *kcontrol,
  580. struct snd_ctl_elem_value *ucontrol)
  581. {
  582. MM_DBG("Resetting all devices\n");
  583. return msm_reset_all_device();
  584. }
  585. static int msm_dual_mic_info(struct snd_kcontrol *kcontrol,
  586. struct snd_ctl_elem_info *uinfo)
  587. {
  588. uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  589. uinfo->count = 2;
  590. uinfo->value.integer.min = 0;
  591. /*Max value is decided based on MAX ENC sessions*/
  592. uinfo->value.integer.max = MAX_AUDREC_SESSIONS - 1;
  593. return 0;
  594. }
  595. static int msm_dual_mic_get(struct snd_kcontrol *kcontrol,
  596. struct snd_ctl_elem_value *ucontrol)
  597. {
  598. int enc_session_id = ucontrol->value.integer.value[0];
  599. ucontrol->value.integer.value[1] =
  600. msm_get_dual_mic_config(enc_session_id);
  601. MM_DBG("session id = %d, config = %ld\n", enc_session_id,
  602. ucontrol->value.integer.value[1]);
  603. return 0;
  604. }
  605. static int msm_dual_mic_put(struct snd_kcontrol *kcontrol,
  606. struct snd_ctl_elem_value *ucontrol)
  607. {
  608. int enc_session_id = ucontrol->value.integer.value[0];
  609. int dual_mic_config = ucontrol->value.integer.value[1];
  610. MM_DBG("session id = %d, config = %d\n", enc_session_id,
  611. dual_mic_config);
  612. return msm_set_dual_mic_config(enc_session_id, dual_mic_config);
  613. }
  614. static int msm_device_mute_info(struct snd_kcontrol *kcontrol,
  615. struct snd_ctl_elem_info *uinfo)
  616. {
  617. uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  618. uinfo->count = 2;
  619. uinfo->value.integer.min = 0;
  620. uinfo->value.integer.max = msm_snddev_devcount();
  621. return 0;
  622. }
  623. static int msm_device_mute_get(struct snd_kcontrol *kcontrol,
  624. struct snd_ctl_elem_value *ucontrol)
  625. {
  626. return 0;
  627. }
  628. static int msm_device_mute_put(struct snd_kcontrol *kcontrol,
  629. struct snd_ctl_elem_value *ucontrol)
  630. {
  631. int dev_id = ucontrol->value.integer.value[0];
  632. int mute = ucontrol->value.integer.value[1];
  633. struct msm_snddev_info *dev_info;
  634. int afe_dev_id = 0;
  635. int volume = 0x4000;
  636. dev_info = audio_dev_ctrl_find_dev(dev_id);
  637. if (IS_ERR(dev_info)) {
  638. MM_ERR("pass invalid dev_id %d\n", dev_id);
  639. return PTR_ERR(dev_info);
  640. }
  641. if (dev_info->capability & SNDDEV_CAP_RX)
  642. return -EPERM;
  643. MM_DBG("Muting device id %d(%s)\n", dev_id, dev_info->name);
  644. if (dev_info->copp_id == 0)
  645. afe_dev_id = AFE_HW_PATH_CODEC_TX;
  646. if (dev_info->copp_id == 1)
  647. afe_dev_id = AFE_HW_PATH_AUXPCM_TX;
  648. if (dev_info->copp_id == 2)
  649. afe_dev_id = AFE_HW_PATH_MI2S_TX;
  650. if (mute)
  651. volume = 0;
  652. afe_device_volume_ctrl(afe_dev_id, volume);
  653. return 0;
  654. }
  655. static int msm_loopback_info(struct snd_kcontrol *kcontrol,
  656. struct snd_ctl_elem_info *uinfo)
  657. {
  658. uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  659. uinfo->count = 3;
  660. uinfo->value.integer.min = 0;
  661. uinfo->value.integer.max = msm_snddev_devcount();
  662. return 0;
  663. }
  664. static int msm_loopback_get(struct snd_kcontrol *kcontrol,
  665. struct snd_ctl_elem_value *ucontrol)
  666. {
  667. ucontrol->value.integer.value[0] = 0;
  668. return 0;
  669. }
  670. static int msm_loopback_put(struct snd_kcontrol *kcontrol,
  671. struct snd_ctl_elem_value *ucontrol)
  672. {
  673. int rc = 0;
  674. struct msm_snddev_info *src_dev_info = NULL; /* TX device */
  675. struct msm_snddev_info *dst_dev_info = NULL; /* RX device */
  676. int dst_dev_id = ucontrol->value.integer.value[0];
  677. int src_dev_id = ucontrol->value.integer.value[1];
  678. int set = ucontrol->value.integer.value[2];
  679. pr_debug("%s: set=%d\n", __func__, set);
  680. dst_dev_info = audio_dev_ctrl_find_dev(dst_dev_id);
  681. if (IS_ERR(dst_dev_info)) {
  682. pr_err("dst_dev:%s:pass invalid dev_id\n", __func__);
  683. rc = PTR_ERR(dst_dev_info);
  684. return rc;
  685. }
  686. if (!(dst_dev_info->capability & SNDDEV_CAP_RX)) {
  687. pr_err("Destination device %d is not RX device\n",
  688. dst_dev_id);
  689. return -EFAULT;
  690. }
  691. src_dev_info = audio_dev_ctrl_find_dev(src_dev_id);
  692. if (IS_ERR(src_dev_info)) {
  693. pr_err("src_dev:%s:pass invalid dev_id\n", __func__);
  694. rc = PTR_ERR(src_dev_info);
  695. return rc;
  696. }
  697. if (!(src_dev_info->capability & SNDDEV_CAP_TX)) {
  698. pr_err("Source device %d is not TX device\n", src_dev_id);
  699. return -EFAULT;
  700. }
  701. if (set) {
  702. pr_debug("%s:%d:Enabling AFE_Loopback\n", __func__, __LINE__);
  703. src_dev = src_dev_id;
  704. dst_dev = dst_dev_id;
  705. loopback_status = 1;
  706. if ((dst_dev_info->opened) && (src_dev_info->opened))
  707. afe_ext_loopback(LOOPBACK_ENABLE,
  708. dst_dev_info->copp_id,
  709. src_dev_info->copp_id);
  710. } else {
  711. pr_debug("%s:%d:Disabling AFE_Loopback\n", __func__, __LINE__);
  712. src_dev = DEVICE_IGNORE;
  713. dst_dev = DEVICE_IGNORE;
  714. loopback_status = 0;
  715. afe_ext_loopback(LOOPBACK_DISABLE,
  716. dst_dev_info->copp_id,
  717. src_dev_info->copp_id);
  718. }
  719. return 0;
  720. }
  721. static struct snd_kcontrol_new snd_dev_controls[AUDIO_DEV_CTL_MAX_DEV];
  722. static int snd_dev_ctl_index(int idx)
  723. {
  724. struct msm_snddev_info *dev_info;
  725. dev_info = audio_dev_ctrl_find_dev(idx);
  726. if (IS_ERR(dev_info)) {
  727. MM_ERR("pass invalid dev_id\n");
  728. return PTR_ERR(dev_info);
  729. }
  730. if (sizeof(dev_info->name) <= 44)
  731. sprintf(&snddev_name[idx][0] , "%s", dev_info->name);
  732. snd_dev_controls[idx].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
  733. snd_dev_controls[idx].access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
  734. snd_dev_controls[idx].name = &snddev_name[idx][0];
  735. snd_dev_controls[idx].index = idx;
  736. snd_dev_controls[idx].info = msm_device_info;
  737. snd_dev_controls[idx].get = msm_device_get;
  738. snd_dev_controls[idx].put = msm_device_put;
  739. snd_dev_controls[idx].private_value = 0;
  740. return 0;
  741. }
  742. #define MSM_EXT(xname, fp_info, fp_get, fp_put, addr) \
  743. { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
  744. .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
  745. .name = xname, \
  746. .info = fp_info,\
  747. .get = fp_get, .put = fp_put, \
  748. .private_value = addr, \
  749. }
  750. static struct snd_kcontrol_new snd_msm_controls[] = {
  751. MSM_EXT("Count", msm_scontrol_count_info, msm_scontrol_count_get, \
  752. NULL, 0),
  753. MSM_EXT("Stream", msm_route_info, msm_route_get, \
  754. msm_route_put, 0),
  755. MSM_EXT("Record", msm_route_info, msm_route_get, \
  756. msm_route_put, 0),
  757. MSM_EXT("Voice", msm_voice_info, msm_voice_get, \
  758. msm_voice_put, 0),
  759. MSM_EXT("Volume", msm_volume_info, msm_volume_get, \
  760. msm_volume_put, 0),
  761. MSM_EXT("VoiceVolume", msm_v_volume_info, msm_v_volume_get, \
  762. msm_v_volume_put, 0),
  763. MSM_EXT("VoiceMute", msm_v_mute_info, msm_v_mute_get, \
  764. msm_v_mute_put, 0),
  765. MSM_EXT("Voice Call", msm_v_call_info, msm_v_call_get, \
  766. msm_v_call_put, 0),
  767. MSM_EXT("Device_Volume", msm_device_volume_info,
  768. msm_device_volume_get, msm_device_volume_put, 0),
  769. MSM_EXT("Reset", msm_reset_info,
  770. msm_reset_get, msm_reset_put, 0),
  771. MSM_EXT("DualMic Switch", msm_dual_mic_info,
  772. msm_dual_mic_get, msm_dual_mic_put, 0),
  773. MSM_EXT("Device_Mute", msm_device_mute_info,
  774. msm_device_mute_get, msm_device_mute_put, 0),
  775. MSM_EXT("Sound Device Loopback", msm_loopback_info,
  776. msm_loopback_get, msm_loopback_put, 0),
  777. };
  778. static int msm_new_mixer(struct snd_soc_codec *codec)
  779. {
  780. unsigned int idx;
  781. int err;
  782. int dev_cnt;
  783. strcpy(codec->card->snd_card->mixername, "MSM Mixer");
  784. for (idx = 0; idx < ARRAY_SIZE(snd_msm_controls); idx++) {
  785. err = snd_ctl_add(codec->card->snd_card,
  786. snd_ctl_new1(&snd_msm_controls[idx], NULL));
  787. if (err < 0)
  788. MM_ERR("ERR adding ctl\n");
  789. }
  790. dev_cnt = msm_snddev_devcount();
  791. for (idx = 0; idx < dev_cnt; idx++) {
  792. if (!snd_dev_ctl_index(idx)) {
  793. err = snd_ctl_add(codec->card->snd_card,
  794. snd_ctl_new1(&snd_dev_controls[idx], NULL));
  795. if (err < 0)
  796. MM_ERR("ERR adding ctl\n");
  797. } else
  798. return 0;
  799. }
  800. simple_control = ARRAY_SIZE(snd_msm_controls);
  801. device_index = simple_control + 1;
  802. return 0;
  803. }
  804. static int msm_soc_dai_init(
  805. struct snd_soc_pcm_runtime *rtd)
  806. {
  807. int ret = 0;
  808. struct snd_soc_codec *codec = rtd->codec;
  809. ret = msm_new_mixer(codec);
  810. if (ret < 0)
  811. MM_ERR("msm_soc: ALSA MSM Mixer Fail\n");
  812. mutex_init(&the_locks.lock);
  813. mutex_init(&the_locks.write_lock);
  814. mutex_init(&the_locks.read_lock);
  815. spin_lock_init(&the_locks.read_dsp_lock);
  816. spin_lock_init(&the_locks.write_dsp_lock);
  817. spin_lock_init(&the_locks.mixer_lock);
  818. init_waitqueue_head(&the_locks.enable_wait);
  819. init_waitqueue_head(&the_locks.eos_wait);
  820. init_waitqueue_head(&the_locks.write_wait);
  821. init_waitqueue_head(&the_locks.read_wait);
  822. src_dev = DEVICE_IGNORE;
  823. dst_dev = DEVICE_IGNORE;
  824. return ret;
  825. }
  826. static struct snd_soc_dai_link msm_dai[] = {
  827. {
  828. .name = "MSM Primary I2S",
  829. .stream_name = "DSP 1",
  830. .cpu_dai_name = "msm-cpu-dai.0",
  831. .platform_name = "msm-dsp-audio.0",
  832. .codec_name = "msm-codec-dai.0",
  833. .codec_dai_name = "msm-codec-dai",
  834. .init = &msm_soc_dai_init,
  835. },
  836. #ifdef CONFIG_SND_MVS_SOC
  837. {
  838. .name = "MSM Primary Voip",
  839. .stream_name = "MVS",
  840. .cpu_dai_name = "mvs-cpu-dai.0",
  841. .platform_name = "msm-mvs-audio.0",
  842. .codec_name = "mvs-codec-dai.0",
  843. .codec_dai_name = "mvs-codec-dai",
  844. },
  845. #endif
  846. };
  847. static struct snd_soc_card snd_soc_card_msm = {
  848. .name = "msm-audio",
  849. .dai_link = msm_dai,
  850. .num_links = ARRAY_SIZE(msm_dai),
  851. };
  852. static int __init msm_audio_init(void)
  853. {
  854. int ret;
  855. msm_audio_snd_device = platform_device_alloc("soc-audio", -1);
  856. if (!msm_audio_snd_device)
  857. return -ENOMEM;
  858. platform_set_drvdata(msm_audio_snd_device, &snd_soc_card_msm);
  859. ret = platform_device_add(msm_audio_snd_device);
  860. if (ret) {
  861. platform_device_put(msm_audio_snd_device);
  862. return ret;
  863. }
  864. return ret;
  865. }
  866. static void __exit msm_audio_exit(void)
  867. {
  868. platform_device_unregister(msm_audio_snd_device);
  869. }
  870. module_init(msm_audio_init);
  871. module_exit(msm_audio_exit);
  872. MODULE_DESCRIPTION("PCM module");
  873. MODULE_LICENSE("GPL v2");