mdm9625.c 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209
  1. /* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  2. *
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License version 2 and
  5. * only version 2 as published by the Free Software Foundation.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. */
  12. #include <linux/clk.h>
  13. #include <linux/delay.h>
  14. #include <linux/gpio.h>
  15. #include <linux/of_gpio.h>
  16. #include <linux/platform_device.h>
  17. #include <linux/slab.h>
  18. #include <linux/qpnp/clkdiv.h>
  19. #include <sound/core.h>
  20. #include <sound/soc.h>
  21. #include <sound/soc-dapm.h>
  22. #include <sound/pcm.h>
  23. #include <sound/jack.h>
  24. #include <sound/q6afe-v2.h>
  25. #include <asm/mach-types.h>
  26. #include <mach/socinfo.h>
  27. #include <qdsp6v2/msm-pcm-routing-v2.h>
  28. #include "../codecs/wcd9320.h"
  29. #include <linux/io.h>
  30. /* Spk control */
  31. #define MDM9625_SPK_ON 1
  32. /* MDM9625 run Taiko at 12.288 Mhz.
  33. * At present MDM supports 12.288mhz
  34. * only. Taiko supports 9.6 MHz also.
  35. */
  36. #define MDM_MCLK_CLK_12P288MHZ 12288000
  37. #define MDM_MCLK_CLK_9P6HZ 9600000
  38. #define MDM_IBIT_CLK_DIV_1P56MHZ 7
  39. #define MDM_MI2S_AUXPCM_PRIM_INTF 0
  40. #define MDM_MI2S_AUXPCM_SEC_INTF 1
  41. #define LPAIF_OFFSET 0xFE000000
  42. #define LPAIF_PRI_MODE_MUXSEL (LPAIF_OFFSET + 0x2B000)
  43. #define LPAIF_SEC_MODE_MUXSEL (LPAIF_OFFSET + 0x2C000)
  44. #define I2S_SEL 0
  45. #define I2S_PCM_SEL 1
  46. #define I2S_PCM_SEL_OFFSET 1
  47. /* Machine driver Name*/
  48. #define MDM9625_MACHINE_DRV_NAME "mdm9625-asoc-taiko"
  49. /* I2S GPIO */
  50. struct msm_i2s_gpio {
  51. unsigned gpio_no;
  52. const char *gpio_name;
  53. };
  54. struct msm_i2s_ctrl {
  55. struct msm_i2s_gpio *pin_data;
  56. struct clk *cdc_bit_clk;
  57. u32 cnt;
  58. };
  59. struct mdm9625_machine_data {
  60. u32 mclk_freq;
  61. struct msm_i2s_gpio *mclk_pin;
  62. struct msm_i2s_ctrl *pri_ctrl;
  63. u32 prim_clk_usrs;
  64. };
  65. static const struct afe_clk_cfg lpass_default = {
  66. AFE_API_VERSION_I2S_CONFIG,
  67. Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ,
  68. Q6AFE_LPASS_OSR_CLK_12_P288_MHZ,
  69. Q6AFE_LPASS_CLK_SRC_INTERNAL,
  70. Q6AFE_LPASS_CLK_ROOT_DEFAULT,
  71. Q6AFE_LPASS_MODE_BOTH_VALID,
  72. 0,
  73. };
  74. #define GPIO_NAME_INDEX 0
  75. #define DT_PARSE_INDEX 1
  76. static int mdm9625_auxpcm_rate = 8000;
  77. void *lpaif_pri_muxsel_virt_addr;
  78. static char *mdm_i2s_gpio_name[][2] = {
  79. {"PRIM_MI2S_WS", "prim-i2s-gpio-ws"},
  80. {"PRIM_MI2S_DIN", "prim-i2s-gpio-din"},
  81. {"PRIM_MI2S_DOUT", "prim-i2s-gpio-dout"},
  82. {"PRIM_MI2S_SCLK", "prim-i2s-gpio-sclk"},
  83. };
  84. static char *mdm_mclk_gpio[][2] = {
  85. {"MI2S_MCLK", "prim-i2s-gpio-mclk"},
  86. };
  87. static struct mutex cdc_mclk_mutex;
  88. static int mdm9625_mi2s_rx_ch = 1;
  89. static int mdm9625_mi2s_tx_ch = 1;
  90. static int msm_spk_control;
  91. static atomic_t aux_ref_count;
  92. static atomic_t mi2s_ref_count;
  93. static int mdm9625_enable_codec_ext_clk(struct snd_soc_codec *codec,
  94. int enable, bool dapm);
  95. void *def_taiko_mbhc_cal(void);
  96. static struct wcd9xxx_mbhc_config mbhc_cfg = {
  97. .read_fw_bin = false,
  98. .calibration = NULL,
  99. .micbias = MBHC_MICBIAS2,
  100. .mclk_cb_fn = mdm9625_enable_codec_ext_clk,
  101. .mclk_rate = MDM_MCLK_CLK_12P288MHZ,
  102. .gpio = 0,
  103. .gpio_irq = 0,
  104. .gpio_level_insert = 1,
  105. .detect_extn_cable = true,
  106. .insert_detect = true,
  107. .swap_gnd_mic = NULL,
  108. };
  109. #define WCD9XXX_MBHC_DEF_BUTTONS 8
  110. #define WCD9XXX_MBHC_DEF_RLOADS 5
  111. static int mdm9625_set_gpio(struct snd_pcm_substream *substream,
  112. u32 intf)
  113. {
  114. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  115. struct snd_soc_card *card = rtd->card;
  116. struct mdm9625_machine_data *pdata = snd_soc_card_get_drvdata(card);
  117. struct msm_i2s_ctrl *i2s_ctrl = NULL;
  118. struct msm_i2s_gpio *pin_data = NULL;
  119. int rtn = 0;
  120. int i;
  121. int j;
  122. if (pdata == NULL) {
  123. pr_err("%s: pdata is NULL\n", __func__);
  124. rtn = -EINVAL;
  125. goto err;
  126. }
  127. if (intf == MDM_MI2S_AUXPCM_PRIM_INTF) {
  128. i2s_ctrl = pdata->pri_ctrl;
  129. }
  130. else {
  131. pr_err("%s: Wrong I2S Interface\n", __func__);
  132. rtn = -EINVAL;
  133. goto err;
  134. }
  135. if (i2s_ctrl == NULL || i2s_ctrl->pin_data == NULL) {
  136. pr_err("%s: Intf ptr NULL\n", __func__);
  137. rtn = -EINVAL;
  138. goto err;
  139. }
  140. pin_data = i2s_ctrl->pin_data;
  141. for (i = 0; i < i2s_ctrl->cnt; i++, pin_data++) {
  142. rtn = gpio_request(pin_data->gpio_no,
  143. pin_data->gpio_name);
  144. pr_debug("%s: gpio = %d, gpio name = %s\n"
  145. "rtn = %d\n", __func__,
  146. pin_data->gpio_no,
  147. pin_data->gpio_name,
  148. rtn);
  149. if (rtn) {
  150. pr_err("%s: Failed to request gpio %d\n",
  151. __func__, pin_data->gpio_no);
  152. /* Release all the GPIO on failure */
  153. for (j = i; j >= 0; j--)
  154. gpio_free(pin_data->gpio_no);
  155. goto err;
  156. }
  157. }
  158. err:
  159. return rtn;
  160. }
  161. static int mdm9625_mi2s_free_gpios(struct snd_pcm_substream *substream,
  162. u32 intf)
  163. {
  164. int i;
  165. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  166. struct snd_soc_card *card = rtd->card;
  167. struct mdm9625_machine_data *pdata = snd_soc_card_get_drvdata(card);
  168. struct msm_i2s_ctrl *i2s_ctrl = NULL;
  169. struct msm_i2s_gpio *pin_data = NULL;
  170. int rtn = 0;
  171. pr_debug("%s:", __func__);
  172. if (pdata == NULL) {
  173. pr_err("%s: pdata is NULL\n", __func__);
  174. rtn = -EINVAL;
  175. goto err;
  176. }
  177. if (intf == MDM_MI2S_AUXPCM_PRIM_INTF) {
  178. i2s_ctrl = pdata->pri_ctrl;
  179. }
  180. else {
  181. pr_debug("%s: Wrong Interface\n", __func__);
  182. rtn = -EINVAL;
  183. goto err;
  184. }
  185. if (i2s_ctrl == NULL || i2s_ctrl->pin_data == NULL) {
  186. pr_err("%s: Intf ptr NULL\n", __func__);
  187. rtn = -EINVAL;
  188. goto err;
  189. }
  190. pin_data = i2s_ctrl->pin_data;
  191. for (i = 0; i < i2s_ctrl->cnt; i++, pin_data++) {
  192. gpio_free(pin_data->gpio_no);
  193. pr_debug("%s: gpio = %d, gpio name = %s\n",
  194. __func__, pin_data->gpio_no,
  195. pin_data->gpio_name);
  196. }
  197. err:
  198. return rtn;
  199. }
  200. static int mdm9625_mi2s_clk_ctl(struct snd_soc_pcm_runtime *rtd, bool enable)
  201. {
  202. struct snd_soc_card *card = rtd->card;
  203. struct mdm9625_machine_data *pdata = snd_soc_card_get_drvdata(card);
  204. struct afe_clk_cfg *lpass_clk = NULL;
  205. int ret = 0;
  206. if (pdata == NULL) {
  207. pr_err("%s:platform data is null\n", __func__);
  208. return -ENOMEM;
  209. }
  210. lpass_clk = kzalloc(sizeof(struct afe_clk_cfg), GFP_KERNEL);
  211. if (lpass_clk == NULL) {
  212. pr_err("%s:Failed to allocate memory\n", __func__);
  213. return -ENOMEM;
  214. }
  215. memcpy(lpass_clk, &lpass_default, sizeof(struct afe_clk_cfg));
  216. pr_debug("%s:enable = %x\n", __func__, enable);
  217. if (enable) {
  218. if (pdata->prim_clk_usrs == 0) {
  219. lpass_clk->clk_val2 = pdata->mclk_freq;
  220. lpass_clk->clk_set_mode = Q6AFE_LPASS_MODE_BOTH_VALID;
  221. } else
  222. lpass_clk->clk_set_mode = Q6AFE_LPASS_MODE_CLK1_VALID;
  223. ret = afe_set_lpass_clock(MI2S_RX, lpass_clk);
  224. if (ret < 0)
  225. pr_err("%s:afe_set_lpass_clock failed\n", __func__);
  226. else
  227. pdata->prim_clk_usrs++;
  228. } else {
  229. if (pdata->prim_clk_usrs > 0)
  230. pdata->prim_clk_usrs--;
  231. if (pdata->prim_clk_usrs == 0) {
  232. lpass_clk->clk_val2 = Q6AFE_LPASS_OSR_CLK_DISABLE;
  233. lpass_clk->clk_set_mode = Q6AFE_LPASS_MODE_BOTH_VALID;
  234. } else
  235. lpass_clk->clk_set_mode = Q6AFE_LPASS_MODE_CLK1_VALID;
  236. lpass_clk->clk_val1 = Q6AFE_LPASS_IBIT_CLK_DISABLE;
  237. ret = afe_set_lpass_clock(MI2S_RX, lpass_clk);
  238. if (ret < 0)
  239. pr_err("%s:afe_set_lpass_clock failed\n", __func__);
  240. }
  241. pr_debug("%s: clk 1 = %x clk2 = %x mode = %x\n",
  242. __func__, lpass_clk->clk_val1,
  243. lpass_clk->clk_val2,
  244. lpass_clk->clk_set_mode);
  245. kfree(lpass_clk);
  246. return ret;
  247. }
  248. static void mdm9625_mi2s_snd_shutdown(struct snd_pcm_substream *substream)
  249. {
  250. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  251. int ret;
  252. if (atomic_dec_return(&mi2s_ref_count) == 0) {
  253. mdm9625_mi2s_free_gpios(substream, MDM_MI2S_AUXPCM_PRIM_INTF);
  254. ret = mdm9625_mi2s_clk_ctl(rtd, false);
  255. if (ret < 0)
  256. pr_err("%s:clock disable failed\n", __func__);
  257. }
  258. }
  259. static int mdm9625_mi2s_startup(struct snd_pcm_substream *substream)
  260. {
  261. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  262. struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
  263. struct snd_soc_dai *codec_dai = rtd->codec_dai;
  264. int ret = 0;
  265. if (atomic_inc_return(&mi2s_ref_count) == 1) {
  266. if (lpaif_pri_muxsel_virt_addr != NULL)
  267. iowrite32(I2S_SEL << I2S_PCM_SEL_OFFSET,
  268. lpaif_pri_muxsel_virt_addr);
  269. else
  270. pr_err("%s lpaif_pri_muxsel_virt_addr is NULL\n",
  271. __func__);
  272. ret = mdm9625_set_gpio(substream, MDM_MI2S_AUXPCM_PRIM_INTF);
  273. if (ret < 0) {
  274. pr_err("%s, GPIO setup failed\n", __func__);
  275. return ret;
  276. }
  277. ret = mdm9625_mi2s_clk_ctl(rtd, true);
  278. if (ret < 0) {
  279. pr_err("set format for codec dai failed\n");
  280. return ret;
  281. }
  282. /* This sets the CONFIG PARAMETER WS_SRC.
  283. * 1 means internal clock master mode.
  284. * 0 means external clock slave mode.
  285. */
  286. ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBS_CFS);
  287. if (ret < 0)
  288. pr_err("set fmt cpu dai failed\n");
  289. ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_CBS_CFS);
  290. if (ret < 0)
  291. pr_err("set fmt for codec dai failed\n");
  292. }
  293. return ret;
  294. }
  295. static int mdm9625_mi2s_rx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
  296. struct snd_pcm_hw_params *params)
  297. {
  298. struct snd_interval *rate = hw_param_interval(params,
  299. SNDRV_PCM_HW_PARAM_RATE);
  300. struct snd_interval *channels = hw_param_interval(params,
  301. SNDRV_PCM_HW_PARAM_CHANNELS);
  302. rate->min = rate->max = 48000;
  303. channels->min = channels->max = mdm9625_mi2s_rx_ch;
  304. return 0;
  305. }
  306. static int mdm9625_mi2s_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
  307. struct snd_pcm_hw_params *params)
  308. {
  309. struct snd_interval *rate = hw_param_interval(params,
  310. SNDRV_PCM_HW_PARAM_RATE);
  311. struct snd_interval *channels = hw_param_interval(params,
  312. SNDRV_PCM_HW_PARAM_CHANNELS);
  313. rate->min = rate->max = 48000;
  314. channels->min = channels->max = mdm9625_mi2s_tx_ch;
  315. return 0;
  316. }
  317. static int mdm9625_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
  318. struct snd_pcm_hw_params *params)
  319. {
  320. struct snd_interval *rate = hw_param_interval(params,
  321. SNDRV_PCM_HW_PARAM_RATE);
  322. rate->min = rate->max = 48000;
  323. return 0;
  324. }
  325. static int mdm9625_mi2s_rx_ch_get(struct snd_kcontrol *kcontrol,
  326. struct snd_ctl_elem_value *ucontrol)
  327. {
  328. pr_debug("%s: msm9615_i2s_rx_ch = %d\n", __func__,
  329. mdm9625_mi2s_rx_ch);
  330. ucontrol->value.integer.value[0] = mdm9625_mi2s_rx_ch - 1;
  331. return 0;
  332. }
  333. static int mdm9625_mi2s_rx_ch_put(struct snd_kcontrol *kcontrol,
  334. struct snd_ctl_elem_value *ucontrol)
  335. {
  336. mdm9625_mi2s_rx_ch = ucontrol->value.integer.value[0] + 1;
  337. pr_debug("%s: msm9615_i2s_rx_ch = %d\n", __func__,
  338. mdm9625_mi2s_rx_ch);
  339. return 1;
  340. }
  341. static int mdm9625_mi2s_tx_ch_get(struct snd_kcontrol *kcontrol,
  342. struct snd_ctl_elem_value *ucontrol)
  343. {
  344. pr_debug("%s: msm9615_i2s_tx_ch = %d\n", __func__,
  345. mdm9625_mi2s_tx_ch);
  346. ucontrol->value.integer.value[0] = mdm9625_mi2s_tx_ch - 1;
  347. return 0;
  348. }
  349. static int mdm9625_mi2s_tx_ch_put(struct snd_kcontrol *kcontrol,
  350. struct snd_ctl_elem_value *ucontrol)
  351. {
  352. mdm9625_mi2s_tx_ch = ucontrol->value.integer.value[0] + 1;
  353. pr_debug("%s: msm9615_i2s_tx_ch = %d\n", __func__,
  354. mdm9625_mi2s_tx_ch);
  355. return 1;
  356. }
  357. static int mdm9625_mi2s_get_spk(struct snd_kcontrol *kcontrol,
  358. struct snd_ctl_elem_value *ucontrol)
  359. {
  360. pr_debug("%s: msm_spk_control = %d", __func__, msm_spk_control);
  361. ucontrol->value.integer.value[0] = msm_spk_control;
  362. return 0;
  363. }
  364. static void mdm_ext_control(struct snd_soc_codec *codec)
  365. {
  366. struct snd_soc_dapm_context *dapm = &codec->dapm;
  367. pr_debug("%s: msm_spk_control = %d", __func__, msm_spk_control);
  368. mutex_lock(&dapm->codec->mutex);
  369. if (msm_spk_control == MDM9625_SPK_ON) {
  370. snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Pos");
  371. snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Neg");
  372. snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Pos");
  373. snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Neg");
  374. } else {
  375. snd_soc_dapm_disable_pin(dapm, "Ext Spk Bottom Pos");
  376. snd_soc_dapm_disable_pin(dapm, "Ext Spk Bottom Neg");
  377. snd_soc_dapm_disable_pin(dapm, "Ext Spk Top Pos");
  378. snd_soc_dapm_disable_pin(dapm, "Ext Spk Top Neg");
  379. }
  380. snd_soc_dapm_sync(dapm);
  381. mutex_unlock(&dapm->codec->mutex);
  382. }
  383. static int mdm9625_mi2s_set_spk(struct snd_kcontrol *kcontrol,
  384. struct snd_ctl_elem_value *ucontrol)
  385. {
  386. struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
  387. pr_debug("%s()\n", __func__);
  388. if (msm_spk_control == ucontrol->value.integer.value[0])
  389. return 0;
  390. msm_spk_control = ucontrol->value.integer.value[0];
  391. mdm_ext_control(codec);
  392. return 1;
  393. }
  394. static int mdm9625_enable_codec_ext_clk(struct snd_soc_codec *codec,
  395. int enable, bool dapm)
  396. {
  397. int ret = 0;
  398. struct mdm9625_machine_data *pdata =
  399. snd_soc_card_get_drvdata(codec->card);
  400. struct afe_clk_cfg *lpass_clk = NULL;
  401. pr_debug("%s: enable = %d codec name %s enable %x\n",
  402. __func__, enable, codec->name, enable);
  403. lpass_clk = kzalloc(sizeof(struct afe_clk_cfg), GFP_KERNEL);
  404. if (lpass_clk == NULL) {
  405. pr_err("%s:Failed to allocate memory\n", __func__);
  406. return -ENOMEM;
  407. }
  408. mutex_lock(&cdc_mclk_mutex);
  409. memcpy(lpass_clk, &lpass_default, sizeof(struct afe_clk_cfg));
  410. if (enable) {
  411. if (pdata->prim_clk_usrs == 0) {
  412. lpass_clk->clk_val2 = pdata->mclk_freq;
  413. lpass_clk->clk_set_mode = Q6AFE_LPASS_MODE_CLK2_VALID;
  414. ret = afe_set_lpass_clock(MI2S_RX, lpass_clk);
  415. if (ret < 0) {
  416. pr_err("%s:afe_set_lpass_clock failed\n",
  417. __func__);
  418. goto err;
  419. }
  420. }
  421. pdata->prim_clk_usrs++;
  422. taiko_mclk_enable(codec, 1, dapm);
  423. } else {
  424. if (pdata->prim_clk_usrs > 0)
  425. pdata->prim_clk_usrs--;
  426. if (pdata->prim_clk_usrs == 0) {
  427. lpass_clk->clk_set_mode = Q6AFE_LPASS_MODE_CLK2_VALID;
  428. lpass_clk->clk_val2 = Q6AFE_LPASS_OSR_CLK_DISABLE;
  429. ret = afe_set_lpass_clock(MI2S_RX, lpass_clk);
  430. if (ret < 0) {
  431. pr_err("%s:afe_set_lpass_clock failed\n",
  432. __func__);
  433. goto err;
  434. }
  435. }
  436. taiko_mclk_enable(codec, 0, dapm);
  437. }
  438. pr_debug("%s: clk2 = %x mode = %x\n",
  439. __func__, lpass_clk->clk_val2,
  440. lpass_clk->clk_set_mode);
  441. err:
  442. mutex_unlock(&cdc_mclk_mutex);
  443. kfree(lpass_clk);
  444. return ret;
  445. }
  446. static int mdm9625_mclk_event(struct snd_soc_dapm_widget *w,
  447. struct snd_kcontrol *kcontrol, int event)
  448. {
  449. pr_debug("%s: event = %d\n", __func__, event);
  450. switch (event) {
  451. case SND_SOC_DAPM_PRE_PMU:
  452. return mdm9625_enable_codec_ext_clk(w->codec, 1, true);
  453. case SND_SOC_DAPM_POST_PMD:
  454. return mdm9625_enable_codec_ext_clk(w->codec, 0, true);
  455. }
  456. return 0;
  457. }
  458. static int mdm9625_auxpcm_startup(struct snd_pcm_substream *substream)
  459. {
  460. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  461. int ret = 0;
  462. if (atomic_inc_return(&aux_ref_count) == 1) {
  463. if (lpaif_pri_muxsel_virt_addr != NULL)
  464. iowrite32(I2S_PCM_SEL << I2S_PCM_SEL_OFFSET,
  465. lpaif_pri_muxsel_virt_addr);
  466. else
  467. pr_err("%s lpaif_pri_muxsel_virt_addr is NULL\n",
  468. __func__);
  469. ret = mdm9625_set_gpio(substream, MDM_MI2S_AUXPCM_PRIM_INTF);
  470. if (ret < 0) {
  471. pr_err("%s, GPIO setup failed\n", __func__);
  472. return ret;
  473. }
  474. ret = mdm9625_mi2s_clk_ctl(rtd, true);
  475. if (ret < 0) {
  476. pr_err("set format for codec dai failed\n");
  477. return ret;
  478. }
  479. }
  480. return ret;
  481. }
  482. static void mdm9625_auxpcm_snd_shutdown(struct snd_pcm_substream *substream)
  483. {
  484. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  485. int ret;
  486. if (atomic_dec_return(&aux_ref_count) == 0) {
  487. mdm9625_mi2s_free_gpios(substream, MDM_MI2S_AUXPCM_PRIM_INTF);
  488. ret = mdm9625_mi2s_clk_ctl(rtd, false);
  489. if (ret < 0)
  490. pr_err("%s:clock disable failed\n", __func__);
  491. }
  492. }
  493. static int mdm9625_auxpcm_rate_get(struct snd_kcontrol *kcontrol,
  494. struct snd_ctl_elem_value *ucontrol)
  495. {
  496. ucontrol->value.integer.value[0] = mdm9625_auxpcm_rate;
  497. return 0;
  498. }
  499. static int mdm9625_auxpcm_rate_put(struct snd_kcontrol *kcontrol,
  500. struct snd_ctl_elem_value *ucontrol)
  501. {
  502. switch (ucontrol->value.integer.value[0]) {
  503. case 0:
  504. mdm9625_auxpcm_rate = 8000;
  505. break;
  506. case 1:
  507. mdm9625_auxpcm_rate = 16000;
  508. break;
  509. default:
  510. mdm9625_auxpcm_rate = 8000;
  511. break;
  512. }
  513. return 0;
  514. }
  515. static int mdm9625_auxpcm_be_params_fixup(struct snd_soc_pcm_runtime *rtd,
  516. struct snd_pcm_hw_params *params)
  517. {
  518. struct snd_interval *rate =
  519. hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
  520. struct snd_interval *channels =
  521. hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
  522. rate->min = rate->max = mdm9625_auxpcm_rate;
  523. channels->min = channels->max = 1;
  524. return 0;
  525. }
  526. static const struct snd_soc_dapm_widget mdm9625_dapm_widgets[] = {
  527. SND_SOC_DAPM_SUPPLY("MCLK", SND_SOC_NOPM, 0, 0,
  528. mdm9625_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  529. SND_SOC_DAPM_SPK("Ext Spk Bottom Pos", NULL),
  530. SND_SOC_DAPM_SPK("Ext Spk Bottom Neg", NULL),
  531. SND_SOC_DAPM_SPK("Ext Spk Top Pos", NULL),
  532. SND_SOC_DAPM_SPK("Ext Spk Top Neg", NULL),
  533. SND_SOC_DAPM_MIC("Handset Mic", NULL),
  534. SND_SOC_DAPM_MIC("Headset Mic", NULL),
  535. SND_SOC_DAPM_MIC("ANCRight Headset Mic", NULL),
  536. SND_SOC_DAPM_MIC("ANCLeft Headset Mic", NULL),
  537. SND_SOC_DAPM_MIC("Digital Mic1", NULL),
  538. SND_SOC_DAPM_MIC("Digital Mic2", NULL),
  539. SND_SOC_DAPM_MIC("Digital Mic3", NULL),
  540. SND_SOC_DAPM_MIC("Digital Mic4", NULL),
  541. SND_SOC_DAPM_MIC("Digital Mic5", NULL),
  542. SND_SOC_DAPM_MIC("Digital Mic6", NULL),
  543. };
  544. static const char *const spk_function[] = {"Off", "On"};
  545. static const char *const mi2s_rx_ch_text[] = {"One", "Two"};
  546. static const char *const mi2s_tx_ch_text[] = {"One", "Two"};
  547. static const char *const auxpcm_rate_text[] = {"rate_8000", "rate_16000"};
  548. static const struct soc_enum mdm9625_enum[] = {
  549. SOC_ENUM_SINGLE_EXT(2, spk_function),
  550. SOC_ENUM_SINGLE_EXT(2, mi2s_rx_ch_text),
  551. SOC_ENUM_SINGLE_EXT(2, mi2s_tx_ch_text),
  552. SOC_ENUM_SINGLE_EXT(2, auxpcm_rate_text),
  553. };
  554. static const struct snd_kcontrol_new mdm_snd_controls[] = {
  555. SOC_ENUM_EXT("Speaker Function", mdm9625_enum[0],
  556. mdm9625_mi2s_get_spk,
  557. mdm9625_mi2s_set_spk),
  558. SOC_ENUM_EXT("MI2S_RX Channels", mdm9625_enum[1],
  559. mdm9625_mi2s_rx_ch_get,
  560. mdm9625_mi2s_rx_ch_put),
  561. SOC_ENUM_EXT("MI2S_TX Channels", mdm9625_enum[2],
  562. mdm9625_mi2s_tx_ch_get,
  563. mdm9625_mi2s_tx_ch_put),
  564. SOC_ENUM_EXT("AUX PCM SampleRate", mdm9625_enum[3],
  565. mdm9625_auxpcm_rate_get,
  566. mdm9625_auxpcm_rate_put),
  567. };
  568. static int mdm9625_mi2s_audrx_init(struct snd_soc_pcm_runtime *rtd)
  569. {
  570. int err;
  571. struct snd_soc_codec *codec = rtd->codec;
  572. struct snd_soc_dapm_context *dapm = &codec->dapm;
  573. struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
  574. pr_debug("%s(), dev_name%s\n", __func__, dev_name(cpu_dai->dev));
  575. rtd->pmdown_time = 0;
  576. err = snd_soc_add_codec_controls(codec, mdm_snd_controls,
  577. ARRAY_SIZE(mdm_snd_controls));
  578. if (err < 0)
  579. return err;
  580. snd_soc_dapm_new_controls(dapm, mdm9625_dapm_widgets,
  581. ARRAY_SIZE(mdm9625_dapm_widgets));
  582. /* After DAPM Enable pins alawys
  583. * DAPM SYNC needs to be called.
  584. */
  585. snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Pos");
  586. snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Neg");
  587. snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Pos");
  588. snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Neg");
  589. snd_soc_dapm_sync(dapm);
  590. mbhc_cfg.calibration = def_taiko_mbhc_cal();
  591. if (mbhc_cfg.calibration)
  592. err = taiko_hs_detect(codec, &mbhc_cfg);
  593. else
  594. err = -ENOMEM;
  595. return err;
  596. }
  597. void *def_taiko_mbhc_cal(void)
  598. {
  599. void *taiko_cal;
  600. struct wcd9xxx_mbhc_btn_detect_cfg *btn_cfg;
  601. u16 *btn_low, *btn_high;
  602. u8 *n_ready, *n_cic, *gain;
  603. taiko_cal = kzalloc(WCD9XXX_MBHC_CAL_SIZE(WCD9XXX_MBHC_DEF_BUTTONS,
  604. WCD9XXX_MBHC_DEF_RLOADS),
  605. GFP_KERNEL);
  606. if (!taiko_cal) {
  607. pr_err("%s: out of memory\n", __func__);
  608. return NULL;
  609. }
  610. #define S(X, Y) ((WCD9XXX_MBHC_CAL_GENERAL_PTR(taiko_cal)->X) = (Y))
  611. S(t_ldoh, 100);
  612. S(t_bg_fast_settle, 100);
  613. S(t_shutdown_plug_rem, 255);
  614. S(mbhc_nsa, 4);
  615. S(mbhc_navg, 4);
  616. #undef S
  617. #define S(X, Y) ((WCD9XXX_MBHC_CAL_PLUG_DET_PTR(taiko_cal)->X) = (Y))
  618. S(mic_current, TAIKO_PID_MIC_5_UA);
  619. S(hph_current, TAIKO_PID_MIC_5_UA);
  620. S(t_mic_pid, 100);
  621. S(t_ins_complete, 250);
  622. S(t_ins_retry, 200);
  623. #undef S
  624. #define S(X, Y) ((WCD9XXX_MBHC_CAL_PLUG_TYPE_PTR(taiko_cal)->X) = (Y))
  625. S(v_no_mic, 30);
  626. S(v_hs_max, 2400);
  627. #undef S
  628. #define S(X, Y) ((WCD9XXX_MBHC_CAL_BTN_DET_PTR(taiko_cal)->X) = (Y))
  629. S(c[0], 62);
  630. S(c[1], 124);
  631. S(nc, 1);
  632. S(n_meas, 3);
  633. S(mbhc_nsc, 11);
  634. S(n_btn_meas, 1);
  635. S(n_btn_con, 2);
  636. S(num_btn, WCD9XXX_MBHC_DEF_BUTTONS);
  637. S(v_btn_press_delta_sta, 100);
  638. S(v_btn_press_delta_cic, 50);
  639. #undef S
  640. btn_cfg = WCD9XXX_MBHC_CAL_BTN_DET_PTR(taiko_cal);
  641. btn_low = wcd9xxx_mbhc_cal_btn_det_mp(btn_cfg, MBHC_BTN_DET_V_BTN_LOW);
  642. btn_high = wcd9xxx_mbhc_cal_btn_det_mp(btn_cfg,
  643. MBHC_BTN_DET_V_BTN_HIGH);
  644. btn_low[0] = -50;
  645. btn_high[0] = 10;
  646. btn_low[1] = 11;
  647. btn_high[1] = 52;
  648. btn_low[2] = 53;
  649. btn_high[2] = 94;
  650. btn_low[3] = 95;
  651. btn_high[3] = 133;
  652. btn_low[4] = 134;
  653. btn_high[4] = 171;
  654. btn_low[5] = 172;
  655. btn_high[5] = 208;
  656. btn_low[6] = 209;
  657. btn_high[6] = 244;
  658. btn_low[7] = 245;
  659. btn_high[7] = 330;
  660. n_ready = wcd9xxx_mbhc_cal_btn_det_mp(btn_cfg, MBHC_BTN_DET_N_READY);
  661. n_ready[0] = 80;
  662. n_ready[1] = 68;
  663. n_cic = wcd9xxx_mbhc_cal_btn_det_mp(btn_cfg, MBHC_BTN_DET_N_CIC);
  664. n_cic[0] = 60;
  665. n_cic[1] = 47;
  666. gain = wcd9xxx_mbhc_cal_btn_det_mp(btn_cfg, MBHC_BTN_DET_GAIN);
  667. gain[0] = 11;
  668. gain[1] = 9;
  669. return taiko_cal;
  670. }
  671. static struct snd_soc_ops mdm9625_mi2s_be_ops = {
  672. .startup = mdm9625_mi2s_startup,
  673. .shutdown = mdm9625_mi2s_snd_shutdown,
  674. };
  675. static struct snd_soc_ops mdm9625_auxpcm_be_ops = {
  676. .startup = mdm9625_auxpcm_startup,
  677. .shutdown = mdm9625_auxpcm_snd_shutdown,
  678. };
  679. /* Digital audio interface connects codec <---> CPU */
  680. static struct snd_soc_dai_link mdm9625_dai[] = {
  681. /* FrontEnd DAI Links */
  682. {
  683. .name = "MDM9625 Media1",
  684. .stream_name = "MultiMedia1",
  685. .cpu_dai_name = "MultiMedia1",
  686. .platform_name = "msm-pcm-dsp.0",
  687. .dynamic = 1,
  688. .trigger = {SND_SOC_DPCM_TRIGGER_POST,
  689. SND_SOC_DPCM_TRIGGER_POST},
  690. .codec_dai_name = "snd-soc-dummy-dai",
  691. .codec_name = "snd-soc-dummy",
  692. .ignore_suspend = 1,
  693. /* This dainlink has playback support */
  694. .ignore_pmdown_time = 1,
  695. .be_id = MSM_FRONTEND_DAI_MULTIMEDIA1
  696. },
  697. {
  698. .name = "MDM9625 Media2",
  699. .stream_name = "MultiMedia2",
  700. .cpu_dai_name = "MultiMedia2",
  701. .platform_name = "msm-pcm-dsp.0",
  702. .dynamic = 1,
  703. .codec_dai_name = "snd-soc-dummy-dai",
  704. .codec_name = "snd-soc-dummy",
  705. .trigger = {SND_SOC_DPCM_TRIGGER_POST,
  706. SND_SOC_DPCM_TRIGGER_POST},
  707. .ignore_suspend = 1,
  708. /* this dainlink has playback support */
  709. .ignore_pmdown_time = 1,
  710. .be_id = MSM_FRONTEND_DAI_MULTIMEDIA2,
  711. },
  712. {
  713. .name = "MSM VoIP",
  714. .stream_name = "VoIP",
  715. .cpu_dai_name = "VoIP",
  716. .platform_name = "msm-voip-dsp",
  717. .dynamic = 1,
  718. .trigger = {SND_SOC_DPCM_TRIGGER_POST,
  719. SND_SOC_DPCM_TRIGGER_POST},
  720. .codec_dai_name = "snd-soc-dummy-dai",
  721. .codec_name = "snd-soc-dummy",
  722. .ignore_suspend = 1,
  723. /* This dainlink has VOIP support */
  724. .ignore_pmdown_time = 1,
  725. .be_id = MSM_FRONTEND_DAI_VOIP,
  726. },
  727. {
  728. .name = "Circuit-Switch Voice",
  729. .stream_name = "CS-Voice",
  730. .cpu_dai_name = "CS-VOICE",
  731. .platform_name = "msm-pcm-voice",
  732. .dynamic = 1,
  733. .codec_dai_name = "snd-soc-dummy-dai",
  734. .codec_name = "snd-soc-dummy",
  735. .trigger = {SND_SOC_DPCM_TRIGGER_POST,
  736. SND_SOC_DPCM_TRIGGER_POST},
  737. .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
  738. .ignore_suspend = 1,
  739. /* This dainlink has Voice support */
  740. .ignore_pmdown_time = 1,
  741. .be_id = MSM_FRONTEND_DAI_CS_VOICE,
  742. },
  743. {
  744. .name = "MI2S Hostless",
  745. .stream_name = "MI2S Hostless",
  746. .cpu_dai_name = "MI2S_TX_HOSTLESS",
  747. .platform_name = "msm-pcm-hostless",
  748. .dynamic = 1,
  749. .trigger = {SND_SOC_DPCM_TRIGGER_POST,
  750. SND_SOC_DPCM_TRIGGER_POST},
  751. .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
  752. .ignore_suspend = 1,
  753. .ignore_pmdown_time = 1,
  754. /* This dainlink has MI2S support */
  755. .codec_dai_name = "snd-soc-dummy-dai",
  756. .codec_name = "snd-soc-dummy",
  757. },
  758. {
  759. .name = "VoLTE",
  760. .stream_name = "VoLTE",
  761. .cpu_dai_name = "VoLTE",
  762. .platform_name = "msm-pcm-voice",
  763. .dynamic = 1,
  764. .trigger = {SND_SOC_DPCM_TRIGGER_POST,
  765. SND_SOC_DPCM_TRIGGER_POST},
  766. .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
  767. .ignore_suspend = 1,
  768. /* this dainlink has playback support */
  769. .ignore_pmdown_time = 1,
  770. .codec_dai_name = "snd-soc-dummy-dai",
  771. .codec_name = "snd-soc-dummy",
  772. .be_id = MSM_FRONTEND_DAI_VOLTE,
  773. },
  774. { .name = "MSM AFE-PCM RX",
  775. .stream_name = "AFE-PROXY RX",
  776. .cpu_dai_name = "msm-dai-q6-dev.241",
  777. .codec_name = "msm-stub-codec.1",
  778. .codec_dai_name = "msm-stub-rx",
  779. .platform_name = "msm-pcm-afe",
  780. .ignore_suspend = 1,
  781. /* this dainlink has playback support */
  782. .ignore_pmdown_time = 1,
  783. },
  784. {
  785. .name = "MSM AFE-PCM TX",
  786. .stream_name = "AFE-PROXY TX",
  787. .cpu_dai_name = "msm-dai-q6-dev.240",
  788. .codec_name = "msm-stub-codec.1",
  789. .codec_dai_name = "msm-stub-tx",
  790. .platform_name = "msm-pcm-afe",
  791. .ignore_suspend = 1,
  792. },
  793. {
  794. .name = "DTMF RX Hostless",
  795. .stream_name = "DTMF RX Hostless",
  796. .cpu_dai_name = "DTMF_RX_HOSTLESS",
  797. .platform_name = "msm-pcm-dtmf",
  798. .dynamic = 1,
  799. .codec_dai_name = "snd-soc-dummy-dai",
  800. .codec_name = "snd-soc-dummy",
  801. .trigger = {SND_SOC_DPCM_TRIGGER_POST,
  802. SND_SOC_DPCM_TRIGGER_POST},
  803. .ignore_suspend = 1,
  804. .be_id = MSM_FRONTEND_DAI_DTMF_RX,
  805. .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
  806. },
  807. {
  808. .name = "DTMF TX",
  809. .stream_name = "DTMF TX",
  810. .cpu_dai_name = "msm-dai-stub",
  811. .platform_name = "msm-pcm-dtmf",
  812. .codec_name = "msm-stub-codec.1",
  813. .codec_dai_name = "msm-stub-tx",
  814. .ignore_suspend = 1,
  815. },
  816. /* Backend DAI Links */
  817. {
  818. .name = LPASS_BE_MI2S_RX,
  819. .stream_name = "MI2S Playback",
  820. .cpu_dai_name = "msm-dai-q6-mi2s.0",
  821. .platform_name = "msm-pcm-routing",
  822. .codec_name = "taiko_codec",
  823. .codec_dai_name = "taiko_i2s_rx1",
  824. .no_pcm = 1,
  825. .be_id = MSM_BACKEND_DAI_MI2S_RX,
  826. .init = &mdm9625_mi2s_audrx_init,
  827. .be_hw_params_fixup = &mdm9625_mi2s_rx_be_hw_params_fixup,
  828. .ops = &mdm9625_mi2s_be_ops,
  829. },
  830. {
  831. .name = LPASS_BE_MI2S_TX,
  832. .stream_name = "MI2S Capture",
  833. .cpu_dai_name = "msm-dai-q6-mi2s.0",
  834. .platform_name = "msm-pcm-routing",
  835. .codec_name = "taiko_codec",
  836. .codec_dai_name = "taiko_i2s_tx1",
  837. .no_pcm = 1,
  838. .be_id = MSM_BACKEND_DAI_MI2S_TX,
  839. .be_hw_params_fixup = &mdm9625_mi2s_tx_be_hw_params_fixup,
  840. .ops = &mdm9625_mi2s_be_ops,
  841. },
  842. {
  843. .name = LPASS_BE_AFE_PCM_RX,
  844. .stream_name = "AFE Playback",
  845. .cpu_dai_name = "msm-dai-q6-dev.224",
  846. .platform_name = "msm-pcm-routing",
  847. .codec_name = "msm-stub-codec.1",
  848. .codec_dai_name = "msm-stub-rx",
  849. .no_pcm = 1,
  850. .be_id = MSM_BACKEND_DAI_AFE_PCM_RX,
  851. },
  852. {
  853. .name = LPASS_BE_AFE_PCM_TX,
  854. .stream_name = "AFE Capture",
  855. .cpu_dai_name = "msm-dai-q6-dev.225",
  856. .platform_name = "msm-pcm-routing",
  857. .codec_name = "msm-stub-codec.1",
  858. .codec_dai_name = "msm-stub-tx",
  859. .no_pcm = 1,
  860. .be_id = MSM_BACKEND_DAI_AFE_PCM_TX,
  861. },
  862. {
  863. .name = LPASS_BE_AUXPCM_RX,
  864. .stream_name = "AUX PCM Playback",
  865. .cpu_dai_name = "msm-dai-q6-auxpcm.1",
  866. .platform_name = "msm-pcm-routing",
  867. .codec_name = "msm-stub-codec.1",
  868. .codec_dai_name = "msm-stub-rx",
  869. .no_pcm = 1,
  870. .be_id = MSM_BACKEND_DAI_AUXPCM_RX,
  871. .be_hw_params_fixup = mdm9625_auxpcm_be_params_fixup,
  872. .ops = &mdm9625_auxpcm_be_ops,
  873. .ignore_pmdown_time = 1,
  874. /* this dainlink has playback support */
  875. },
  876. {
  877. .name = LPASS_BE_AUXPCM_TX,
  878. .stream_name = "AUX PCM Capture",
  879. .cpu_dai_name = "msm-dai-q6-auxpcm.1",
  880. .platform_name = "msm-pcm-routing",
  881. .codec_name = "msm-stub-codec.1",
  882. .codec_dai_name = "msm-stub-tx",
  883. .no_pcm = 1,
  884. .be_id = MSM_BACKEND_DAI_AUXPCM_TX,
  885. .be_hw_params_fixup = mdm9625_auxpcm_be_params_fixup,
  886. .ops = &mdm9625_auxpcm_be_ops,
  887. },
  888. /* Incall Record Uplink BACK END DAI Link */
  889. {
  890. .name = LPASS_BE_INCALL_RECORD_TX,
  891. .stream_name = "Voice Uplink Capture",
  892. .cpu_dai_name = "msm-dai-q6-dev.32772",
  893. .platform_name = "msm-pcm-routing",
  894. .codec_name = "msm-stub-codec.1",
  895. .codec_dai_name = "msm-stub-tx",
  896. .no_pcm = 1,
  897. .be_id = MSM_BACKEND_DAI_INCALL_RECORD_TX,
  898. .be_hw_params_fixup = mdm9625_be_hw_params_fixup,
  899. .ignore_suspend = 1,
  900. },
  901. /* Incall Record Downlink BACK END DAI Link */
  902. {
  903. .name = LPASS_BE_INCALL_RECORD_RX,
  904. .stream_name = "Voice Downlink Capture",
  905. .cpu_dai_name = "msm-dai-q6-dev.32771",
  906. .platform_name = "msm-pcm-routing",
  907. .codec_name = "msm-stub-codec.1",
  908. .codec_dai_name = "msm-stub-tx",
  909. .no_pcm = 1,
  910. .be_id = MSM_BACKEND_DAI_INCALL_RECORD_RX,
  911. .be_hw_params_fixup = mdm9625_be_hw_params_fixup,
  912. .ignore_suspend = 1,
  913. },
  914. /* Incall Music BACK END DAI Link */
  915. {
  916. .name = LPASS_BE_VOICE_PLAYBACK_TX,
  917. .stream_name = "Voice Farend Playback",
  918. .cpu_dai_name = "msm-dai-q6-dev.32773",
  919. .platform_name = "msm-pcm-routing",
  920. .codec_name = "msm-stub-codec.1",
  921. .codec_dai_name = "msm-stub-rx",
  922. .no_pcm = 1,
  923. .be_id = MSM_BACKEND_DAI_VOICE_PLAYBACK_TX,
  924. .be_hw_params_fixup = mdm9625_be_hw_params_fixup,
  925. .ignore_suspend = 1,
  926. },
  927. };
  928. static struct snd_soc_card snd_soc_card_mdm9625 = {
  929. .name = "mdm9625-taiko-i2s-snd-card",
  930. .dai_link = mdm9625_dai,
  931. .num_links = ARRAY_SIZE(mdm9625_dai),
  932. };
  933. static int mdm9625_dtparse(struct platform_device *pdev,
  934. struct mdm9625_machine_data **pdata)
  935. {
  936. int ret = 0, i = 0;
  937. struct msm_i2s_gpio *pin_data = NULL;
  938. struct msm_i2s_ctrl *ctrl;
  939. struct msm_i2s_gpio *mclk_pin = NULL;
  940. unsigned int gpio_no[4];
  941. unsigned int dt_mclk = 0;
  942. enum of_gpio_flags flags = OF_GPIO_ACTIVE_LOW;
  943. int prim_cnt = 0;
  944. pin_data = devm_kzalloc(&pdev->dev, (4 *
  945. sizeof(struct msm_i2s_gpio)),
  946. GFP_KERNEL);
  947. mclk_pin = devm_kzalloc(&pdev->dev,
  948. sizeof(struct msm_i2s_gpio),
  949. GFP_KERNEL);
  950. if (!pin_data || !mclk_pin) {
  951. dev_err(&pdev->dev, "No memory for gpio\n");
  952. ret = -ENOMEM;
  953. goto err;
  954. }
  955. for (i = 0; i < ARRAY_SIZE(gpio_no); i++) {
  956. gpio_no[i] = of_get_named_gpio_flags(pdev->dev.of_node,
  957. mdm_i2s_gpio_name[i][DT_PARSE_INDEX],
  958. 0, &flags);
  959. if (gpio_no[i] > 0) {
  960. pin_data[i].gpio_name =
  961. mdm_i2s_gpio_name[prim_cnt][GPIO_NAME_INDEX];
  962. pin_data[i].gpio_no = gpio_no[i];
  963. dev_dbg(&pdev->dev, "%s:GPIO gpio[%s] =\n"
  964. "0x%x\n", __func__,
  965. pin_data[i].gpio_name,
  966. pin_data[i].gpio_no);
  967. prim_cnt++;
  968. } else {
  969. dev_err(&pdev->dev, "%s:Invalid I2S GPIO[%s] = %x\n",
  970. __func__,
  971. mdm_i2s_gpio_name[i][GPIO_NAME_INDEX],
  972. gpio_no[i]);
  973. ret = -ENODEV;
  974. goto err;
  975. }
  976. }
  977. for (i = 0; i < ARRAY_SIZE(mdm_mclk_gpio); i++) {
  978. dt_mclk = of_get_named_gpio_flags(pdev->dev.of_node,
  979. mdm_mclk_gpio[i][DT_PARSE_INDEX], 0,
  980. &flags);
  981. if (dt_mclk > 0) {
  982. mclk_pin->gpio_name =
  983. mdm_mclk_gpio[i][GPIO_NAME_INDEX];
  984. mclk_pin->gpio_no = dt_mclk;
  985. ret = gpio_request(mclk_pin->gpio_no,
  986. mclk_pin->gpio_name);
  987. dev_dbg(&pdev->dev, "%s:Request MCLK Gpio\n"
  988. "gpio[%s] = 0x%x\n", __func__,
  989. mclk_pin->gpio_name,
  990. dt_mclk);
  991. } else {
  992. dev_err(&pdev->dev, "%s:MCLK gpio is incorrect\n",
  993. __func__);
  994. ret = -ENODEV;
  995. goto err;
  996. }
  997. }
  998. ctrl = devm_kzalloc(&pdev->dev,
  999. sizeof(struct msm_i2s_ctrl), GFP_KERNEL);
  1000. if (!ctrl) {
  1001. dev_err(&pdev->dev, "No memory for gpio\n");
  1002. ret = -ENOMEM;
  1003. goto err;
  1004. }
  1005. ctrl->pin_data = pin_data;
  1006. ctrl->cnt = prim_cnt;
  1007. (*pdata)->pri_ctrl = ctrl;
  1008. (*pdata)->mclk_pin = mclk_pin;
  1009. return ret;
  1010. err:
  1011. if (mclk_pin)
  1012. devm_kfree(&pdev->dev, mclk_pin);
  1013. if (pin_data)
  1014. devm_kfree(&pdev->dev, pin_data);
  1015. return ret;
  1016. }
  1017. static __devinit int mdm9625_asoc_machine_probe(struct platform_device *pdev)
  1018. {
  1019. int ret;
  1020. struct snd_soc_card *card = &snd_soc_card_mdm9625;
  1021. struct mdm9625_machine_data *pdata;
  1022. enum apr_subsys_state q6_state;
  1023. q6_state = apr_get_q6_state();
  1024. if (q6_state != APR_SUBSYS_LOADED) {
  1025. dev_dbg(&pdev->dev, "defering %s, adsp_state %d\n",
  1026. __func__, q6_state);
  1027. return -EPROBE_DEFER;
  1028. }
  1029. mutex_init(&cdc_mclk_mutex);
  1030. if (!pdev->dev.of_node) {
  1031. dev_err(&pdev->dev, "No platform supplied from device tree\n");
  1032. return -EINVAL;
  1033. }
  1034. pdata = devm_kzalloc(&pdev->dev, sizeof(struct mdm9625_machine_data),
  1035. GFP_KERNEL);
  1036. if (!pdata) {
  1037. dev_err(&pdev->dev, "Can't allocate mdm9625_asoc_mach_data\n");
  1038. ret = -ENOMEM;
  1039. goto err;
  1040. }
  1041. ret = mdm9625_dtparse(pdev, &pdata);
  1042. if (ret) {
  1043. dev_err(&pdev->dev,
  1044. "%s: mi2s-aux Pin data parse failed",
  1045. __func__);
  1046. goto err;
  1047. }
  1048. ret = of_property_read_u32(pdev->dev.of_node,
  1049. "qcom,taiko-mclk-clk-freq",
  1050. &pdata->mclk_freq);
  1051. if (ret) {
  1052. dev_err(&pdev->dev,
  1053. "Looking up %s property in node %s failed",
  1054. "qcom,taiko-mclk-clk-freq",
  1055. pdev->dev.of_node->full_name);
  1056. goto err;
  1057. }
  1058. /* At present only 12.288MHz is supported on MDM. */
  1059. if (q6afe_check_osr_clk_freq(pdata->mclk_freq)) {
  1060. dev_err(&pdev->dev, "unsupported taiko mclk freq %u\n",
  1061. pdata->mclk_freq);
  1062. ret = -EINVAL;
  1063. goto err;
  1064. }
  1065. pdata->prim_clk_usrs = 0;
  1066. card->dev = &pdev->dev;
  1067. platform_set_drvdata(pdev, card);
  1068. snd_soc_card_set_drvdata(card, pdata);
  1069. ret = snd_soc_of_parse_card_name(card, "qcom,model");
  1070. if (ret)
  1071. goto err;
  1072. ret = snd_soc_of_parse_audio_routing(card, "qcom,audio-routing");
  1073. if (ret)
  1074. goto err;
  1075. ret = snd_soc_register_card(card);
  1076. if (ret) {
  1077. dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
  1078. ret);
  1079. goto err;
  1080. }
  1081. lpaif_pri_muxsel_virt_addr = ioremap(LPAIF_PRI_MODE_MUXSEL, 4);
  1082. if (lpaif_pri_muxsel_virt_addr == NULL) {
  1083. pr_err("%s Pri muxsel virt addr is null\n", __func__);
  1084. ret = -EINVAL;
  1085. goto err;
  1086. }
  1087. return 0;
  1088. err:
  1089. devm_kfree(&pdev->dev, pdata);
  1090. return ret;
  1091. }
  1092. static int __devexit mdm9625_asoc_machine_remove(struct platform_device *pdev)
  1093. {
  1094. struct snd_soc_card *card = platform_get_drvdata(pdev);
  1095. struct mdm9625_machine_data *pdata = snd_soc_card_get_drvdata(card);
  1096. pdata->mclk_freq = 0;
  1097. snd_soc_unregister_card(card);
  1098. return 0;
  1099. }
  1100. static const struct of_device_id msm9625_asoc_machine_of_match[] = {
  1101. { .compatible = "qcom,mdm9625-audio-taiko", },
  1102. {},
  1103. };
  1104. static struct platform_driver msm9625_asoc_machine_driver = {
  1105. .driver = {
  1106. .name = MDM9625_MACHINE_DRV_NAME,
  1107. .owner = THIS_MODULE,
  1108. .pm = &snd_soc_pm_ops,
  1109. .of_match_table = msm9625_asoc_machine_of_match,
  1110. },
  1111. .probe = mdm9625_asoc_machine_probe,
  1112. .remove = __devexit_p(mdm9625_asoc_machine_remove),
  1113. };
  1114. module_platform_driver(msm9625_asoc_machine_driver);
  1115. MODULE_DESCRIPTION("ALSA SoC msm");
  1116. MODULE_LICENSE("GPL v2");
  1117. MODULE_ALIAS("platform:" MDM9625_MACHINE_DRV_NAME);
  1118. MODULE_DEVICE_TABLE(of, msm9625_asoc_machine_of_match);