blob: f1fbce37942c8627579f659cd948d2d4ab45b67b [file] [log] [blame]
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001/* Copyright (c) 2015-2017, 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
13#include <linux/input.h>
14#include <linux/of_gpio.h>
15#include <linux/mfd/msm-cdc-pinctrl.h>
16#include <sound/pcm_params.h>
17#include <sound/q6afe-v2.h>
18#include "qdsp6v2/msm-pcm-routing-v2.h"
Neeraj Upadhyay49934422016-12-27 19:03:35 +053019#include "sdm660-common.h"
20#include "sdm660-internal.h"
21#include "sdm660-external.h"
22#include "../codecs/sdm660_cdc/msm-analog-cdc.h"
Banajit Goswami0530e2f2016-12-09 21:34:37 -080023#include "../codecs/wsa881x.h"
24
Neeraj Upadhyay49934422016-12-27 19:03:35 +053025#define DRV_NAME "sdm660-asoc-snd"
Banajit Goswami0530e2f2016-12-09 21:34:37 -080026
Laxminath Kasame68e94f2016-12-09 12:08:00 +053027#define MSM_INT_DIGITAL_CODEC "msm-dig-codec"
28#define PMIC_INT_ANALOG_CODEC "analog-codec"
29
Banajit Goswami0530e2f2016-12-09 21:34:37 -080030#define DEV_NAME_STR_LEN 32
31#define DEFAULT_MCLK_RATE 9600000
32
33struct dev_config {
34 u32 sample_rate;
35 u32 bit_format;
36 u32 channels;
37};
38
Rohit Kumar0bd27132016-12-06 14:48:58 +053039enum {
40 DP_RX_IDX,
41 EXT_DISP_RX_IDX_MAX,
42};
43
Banajit Goswami0530e2f2016-12-09 21:34:37 -080044/* TDM default config */
45static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = {
46 { /* PRI TDM */
47 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */
48 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */
49 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */
50 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */
51 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */
52 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */
53 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */
54 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */
55 },
56 { /* SEC TDM */
57 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */
58 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */
59 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */
60 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */
61 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */
62 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */
63 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */
64 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */
65 },
66 { /* TERT TDM */
67 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */
68 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */
69 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */
70 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */
71 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */
72 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */
73 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */
74 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */
75 },
76 { /* QUAT TDM */
77 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */
78 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */
79 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */
80 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */
81 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */
82 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */
83 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */
84 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */
85 }
86};
87
88/* TDM default config */
89static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = {
90 { /* PRI TDM */
91 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */
92 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */
93 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */
94 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */
95 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */
96 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */
97 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */
98 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */
99 },
100 { /* SEC TDM */
101 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */
102 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */
103 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */
104 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */
105 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */
106 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */
107 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */
108 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */
109 },
110 { /* TERT TDM */
111 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */
112 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */
113 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */
114 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */
115 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */
116 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */
117 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */
118 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */
119 },
120 { /* QUAT TDM */
121 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */
122 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */
123 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */
124 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */
125 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */
126 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */
127 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */
128 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */
129 }
130};
131
Rohit Kumar0bd27132016-12-06 14:48:58 +0530132/* Default configuration of external display BE */
133static struct dev_config ext_disp_rx_cfg[] = {
134 [DP_RX_IDX] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
135};
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800136static struct dev_config usb_rx_cfg = {
137 .sample_rate = SAMPLING_RATE_48KHZ,
138 .bit_format = SNDRV_PCM_FORMAT_S16_LE,
139 .channels = 2,
140};
141
142static struct dev_config usb_tx_cfg = {
143 .sample_rate = SAMPLING_RATE_48KHZ,
144 .bit_format = SNDRV_PCM_FORMAT_S16_LE,
145 .channels = 1,
146};
147
148enum {
149 PRIM_MI2S = 0,
150 SEC_MI2S,
151 TERT_MI2S,
152 QUAT_MI2S,
153 MI2S_MAX,
154};
155
156enum {
157 PRIM_AUX_PCM = 0,
158 SEC_AUX_PCM,
159 TERT_AUX_PCM,
160 QUAT_AUX_PCM,
161 AUX_PCM_MAX,
162};
163
164enum {
165 PCM_I2S_SEL_PRIM = 0,
166 PCM_I2S_SEL_SEC,
167 PCM_I2S_SEL_TERT,
168 PCM_I2S_SEL_QUAT,
169 PCM_I2S_SEL_MAX,
170};
171
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800172struct mi2s_conf {
173 struct mutex lock;
174 u32 ref_cnt;
175 u32 msm_is_mi2s_master;
Tanya Dixit73a3a262016-12-08 22:25:56 +0530176 u32 msm_is_ext_mclk;
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800177};
178
Tanya Dixit73a3a262016-12-08 22:25:56 +0530179static u32 mi2s_ebit_clk[MI2S_MAX] = {
180 Q6AFE_LPASS_CLK_ID_PRI_MI2S_EBIT,
181 Q6AFE_LPASS_CLK_ID_SEC_MI2S_EBIT,
182 Q6AFE_LPASS_CLK_ID_TER_MI2S_EBIT,
183 Q6AFE_LPASS_CLK_ID_QUAD_MI2S_EBIT
184};
185
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800186struct msm_wsa881x_dev_info {
187 struct device_node *of_node;
188 u32 index;
189};
190static struct snd_soc_aux_dev *msm_aux_dev;
191static struct snd_soc_codec_conf *msm_codec_conf;
192
193static bool msm_swap_gnd_mic(struct snd_soc_codec *codec);
194
195static struct wcd_mbhc_config mbhc_cfg = {
196 .read_fw_bin = false,
197 .calibration = NULL,
198 .detect_extn_cable = true,
199 .mono_stero_detection = false,
200 .swap_gnd_mic = NULL,
Laxminath Kasame68e94f2016-12-09 12:08:00 +0530201 .hs_ext_micbias = true,
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800202 .key_code[0] = KEY_MEDIA,
203 .key_code[1] = KEY_VOICECOMMAND,
204 .key_code[2] = KEY_VOLUMEUP,
205 .key_code[3] = KEY_VOLUMEDOWN,
206 .key_code[4] = 0,
207 .key_code[5] = 0,
208 .key_code[6] = 0,
209 .key_code[7] = 0,
210 .linein_th = 5000,
211 .moisture_en = false,
212 .mbhc_micbias = 0,
213 .anc_micbias = 0,
214 .enable_anc_mic_detect = false,
215};
216
217static struct dev_config proxy_rx_cfg = {
218 .sample_rate = SAMPLING_RATE_48KHZ,
219 .bit_format = SNDRV_PCM_FORMAT_S16_LE,
220 .channels = 2,
221};
222
223/* Default configuration of MI2S channels */
224static struct dev_config mi2s_rx_cfg[] = {
225 [PRIM_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
226 [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
227 [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
228 [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
229};
230
231static struct dev_config mi2s_tx_cfg[] = {
232 [PRIM_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
233 [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
234 [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
235 [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
236};
237
238static struct dev_config aux_pcm_rx_cfg[] = {
239 [PRIM_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
240 [SEC_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
241 [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
242 [QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
243};
244
245static struct dev_config aux_pcm_tx_cfg[] = {
246 [PRIM_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
247 [SEC_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
248 [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
249 [QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
250};
251
252static char const *ch_text[] = {"Two", "Three", "Four", "Five",
253 "Six", "Seven", "Eight"};
254static const char *const auxpcm_rate_text[] = {"KHZ_8", "KHZ_16"};
255static char const *mi2s_rate_text[] = {"KHZ_8", "KHZ_16",
256 "KHZ_32", "KHZ_44P1", "KHZ_48",
257 "KHZ_96", "KHZ_192"};
258static const char *const mi2s_ch_text[] = {"One", "Two", "Three", "Four",
259 "Five", "Six", "Seven",
260 "Eight"};
261static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE",
262 "S32_LE"};
Tanya Dixitc8ecc2e2017-02-17 17:57:44 +0530263static char const *mi2s_format_text[] = {"S16_LE", "S24_LE", "S24_3LE",
264 "S32_LE"};
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800265static char const *tdm_ch_text[] = {"One", "Two", "Three", "Four",
266 "Five", "Six", "Seven", "Eight"};
267static char const *tdm_bit_format_text[] = {"S16_LE", "S24_LE", "S32_LE"};
268static char const *tdm_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_32",
269 "KHZ_44P1", "KHZ_48", "KHZ_96",
270 "KHZ_192", "KHZ_352P8", "KHZ_384"};
271static const char *const usb_ch_text[] = {"One", "Two", "Three", "Four",
272 "Five", "Six", "Seven",
273 "Eight"};
274static char const *usb_sample_rate_text[] = {"KHZ_8", "KHZ_11P025",
275 "KHZ_16", "KHZ_22P05",
276 "KHZ_32", "KHZ_44P1", "KHZ_48",
277 "KHZ_96", "KHZ_192", "KHZ_384"};
Rohit Kumar0bd27132016-12-06 14:48:58 +0530278static char const *ext_disp_bit_format_text[] = {"S16_LE", "S24_LE"};
279static char const *ext_disp_sample_rate_text[] = {"KHZ_48", "KHZ_96",
280 "KHZ_192"};
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800281
Rohit Kumar0bd27132016-12-06 14:48:58 +0530282static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_chs, ch_text);
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800283static SOC_ENUM_SINGLE_EXT_DECL(proxy_rx_chs, ch_text);
284static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_rx_sample_rate, auxpcm_rate_text);
285static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_rx_sample_rate, auxpcm_rate_text);
286static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_rx_sample_rate, auxpcm_rate_text);
287static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_rx_sample_rate, auxpcm_rate_text);
288static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_tx_sample_rate, auxpcm_rate_text);
289static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_tx_sample_rate, auxpcm_rate_text);
290static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_tx_sample_rate, auxpcm_rate_text);
291static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_tx_sample_rate, auxpcm_rate_text);
292static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_sample_rate, mi2s_rate_text);
293static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_sample_rate, mi2s_rate_text);
294static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_sample_rate, mi2s_rate_text);
295static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_sample_rate, mi2s_rate_text);
296static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_sample_rate, mi2s_rate_text);
297static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_sample_rate, mi2s_rate_text);
298static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_sample_rate, mi2s_rate_text);
299static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_sample_rate, mi2s_rate_text);
Tanya Dixitc8ecc2e2017-02-17 17:57:44 +0530300static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_format, mi2s_format_text);
301static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_format, mi2s_format_text);
302static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_format, mi2s_format_text);
303static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_format, mi2s_format_text);
304static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_format, mi2s_format_text);
305static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_format, mi2s_format_text);
306static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_format, mi2s_format_text);
307static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_format, mi2s_format_text);
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800308static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_chs, mi2s_ch_text);
309static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_chs, mi2s_ch_text);
310static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_chs, mi2s_ch_text);
311static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_chs, mi2s_ch_text);
312static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_chs, mi2s_ch_text);
313static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_chs, mi2s_ch_text);
314static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_chs, mi2s_ch_text);
315static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_chs, mi2s_ch_text);
316static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_chs, usb_ch_text);
317static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_chs, usb_ch_text);
318static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_format, bit_format_text);
319static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_format, bit_format_text);
Rohit Kumar0bd27132016-12-06 14:48:58 +0530320static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_format, ext_disp_bit_format_text);
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800321static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_sample_rate, usb_sample_rate_text);
322static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_sample_rate, usb_sample_rate_text);
Rohit Kumar0bd27132016-12-06 14:48:58 +0530323static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_sample_rate,
324 ext_disp_sample_rate_text);
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800325static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_chs, tdm_ch_text);
326static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_format, tdm_bit_format_text);
327static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_sample_rate, tdm_sample_rate_text);
328static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_chs, tdm_ch_text);
329static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_format, tdm_bit_format_text);
330static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_sample_rate, tdm_sample_rate_text);
331
332static struct afe_clk_set mi2s_clk[MI2S_MAX] = {
333 {
334 AFE_API_VERSION_I2S_CONFIG,
335 Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT,
336 Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ,
337 Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
338 Q6AFE_LPASS_CLK_ROOT_DEFAULT,
339 0,
340 },
341 {
342 AFE_API_VERSION_I2S_CONFIG,
343 Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT,
344 Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ,
345 Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
346 Q6AFE_LPASS_CLK_ROOT_DEFAULT,
347 0,
348 },
349 {
350 AFE_API_VERSION_I2S_CONFIG,
351 Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT,
352 Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ,
353 Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
354 Q6AFE_LPASS_CLK_ROOT_DEFAULT,
355 0,
356 },
357 {
358 AFE_API_VERSION_I2S_CONFIG,
359 Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT,
360 Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ,
361 Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
362 Q6AFE_LPASS_CLK_ROOT_DEFAULT,
363 0,
364 }
365};
366
Tanya Dixit73a3a262016-12-08 22:25:56 +0530367static struct afe_clk_set mi2s_mclk[MI2S_MAX] = {
368 {
369 AFE_API_VERSION_I2S_CONFIG,
Tanya Dixit73a3a262016-12-08 22:25:56 +0530370 Q6AFE_LPASS_CLK_ID_MCLK_3,
371 Q6AFE_LPASS_OSR_CLK_9_P600_MHZ,
372 Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
373 Q6AFE_LPASS_CLK_ROOT_DEFAULT,
374 0,
375 },
376 {
377 AFE_API_VERSION_I2S_CONFIG,
378 Q6AFE_LPASS_CLK_ID_MCLK_4,
379 Q6AFE_LPASS_OSR_CLK_9_P600_MHZ,
380 Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
381 Q6AFE_LPASS_CLK_ROOT_DEFAULT,
382 0,
Laxminath Kasam4e444572017-01-15 20:00:11 +0530383 },
384 {
385 AFE_API_VERSION_I2S_CONFIG,
386 Q6AFE_LPASS_CLK_ID_MCLK_1,
387 Q6AFE_LPASS_OSR_CLK_9_P600_MHZ,
388 Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
389 Q6AFE_LPASS_CLK_ROOT_DEFAULT,
390 0,
391 },
392 {
393 AFE_API_VERSION_I2S_CONFIG,
394 Q6AFE_LPASS_CLK_ID_MCLK_2,
395 Q6AFE_LPASS_OSR_CLK_9_P600_MHZ,
396 Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
397 Q6AFE_LPASS_CLK_ROOT_DEFAULT,
398 0,
Tanya Dixit73a3a262016-12-08 22:25:56 +0530399 }
400};
401
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800402static struct mi2s_conf mi2s_intf_conf[MI2S_MAX];
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800403
404static int proxy_rx_ch_get(struct snd_kcontrol *kcontrol,
405 struct snd_ctl_elem_value *ucontrol)
406{
407 pr_debug("%s: proxy_rx channels = %d\n",
408 __func__, proxy_rx_cfg.channels);
409 ucontrol->value.integer.value[0] = proxy_rx_cfg.channels - 2;
410
411 return 0;
412}
413
414static int proxy_rx_ch_put(struct snd_kcontrol *kcontrol,
415 struct snd_ctl_elem_value *ucontrol)
416{
417 proxy_rx_cfg.channels = ucontrol->value.integer.value[0] + 2;
418 pr_debug("%s: proxy_rx channels = %d\n",
419 __func__, proxy_rx_cfg.channels);
420
421 return 1;
422}
423
424static int tdm_get_sample_rate(int value)
425{
426 int sample_rate = 0;
427
428 switch (value) {
429 case 0:
430 sample_rate = SAMPLING_RATE_8KHZ;
431 break;
432 case 1:
433 sample_rate = SAMPLING_RATE_16KHZ;
434 break;
435 case 2:
436 sample_rate = SAMPLING_RATE_32KHZ;
437 break;
438 case 3:
439 sample_rate = SAMPLING_RATE_44P1KHZ;
440 break;
441 case 4:
442 sample_rate = SAMPLING_RATE_48KHZ;
443 break;
444 case 5:
445 sample_rate = SAMPLING_RATE_96KHZ;
446 break;
447 case 6:
448 sample_rate = SAMPLING_RATE_192KHZ;
449 break;
450 case 7:
451 sample_rate = SAMPLING_RATE_352P8KHZ;
452 break;
453 case 8:
454 sample_rate = SAMPLING_RATE_384KHZ;
455 break;
456 default:
457 sample_rate = SAMPLING_RATE_48KHZ;
458 break;
459 }
460 return sample_rate;
461}
462
463static int tdm_get_sample_rate_val(int sample_rate)
464{
465 int sample_rate_val = 0;
466
467 switch (sample_rate) {
468 case SAMPLING_RATE_8KHZ:
469 sample_rate_val = 0;
470 break;
471 case SAMPLING_RATE_16KHZ:
472 sample_rate_val = 1;
473 break;
474 case SAMPLING_RATE_32KHZ:
475 sample_rate_val = 2;
476 break;
477 case SAMPLING_RATE_44P1KHZ:
478 sample_rate_val = 3;
479 break;
480 case SAMPLING_RATE_48KHZ:
481 sample_rate_val = 4;
482 break;
483 case SAMPLING_RATE_96KHZ:
484 sample_rate_val = 5;
485 break;
486 case SAMPLING_RATE_192KHZ:
487 sample_rate_val = 6;
488 break;
489 case SAMPLING_RATE_352P8KHZ:
490 sample_rate_val = 7;
491 break;
492 case SAMPLING_RATE_384KHZ:
493 sample_rate_val = 8;
494 break;
495 default:
496 sample_rate_val = 4;
497 break;
498 }
499 return sample_rate_val;
500}
501
502static int tdm_get_port_idx(struct snd_kcontrol *kcontrol,
503 struct tdm_port *port)
504{
505 if (port) {
506 if (strnstr(kcontrol->id.name, "PRI",
507 sizeof(kcontrol->id.name))) {
508 port->mode = TDM_PRI;
509 } else if (strnstr(kcontrol->id.name, "SEC",
510 sizeof(kcontrol->id.name))) {
511 port->mode = TDM_SEC;
512 } else if (strnstr(kcontrol->id.name, "TERT",
513 sizeof(kcontrol->id.name))) {
514 port->mode = TDM_TERT;
515 } else if (strnstr(kcontrol->id.name, "QUAT",
516 sizeof(kcontrol->id.name))) {
517 port->mode = TDM_QUAT;
518 } else {
519 pr_err("%s: unsupported mode in: %s",
520 __func__, kcontrol->id.name);
521 return -EINVAL;
522 }
523
524 if (strnstr(kcontrol->id.name, "RX_0",
525 sizeof(kcontrol->id.name)) ||
526 strnstr(kcontrol->id.name, "TX_0",
527 sizeof(kcontrol->id.name))) {
528 port->channel = TDM_0;
529 } else if (strnstr(kcontrol->id.name, "RX_1",
530 sizeof(kcontrol->id.name)) ||
531 strnstr(kcontrol->id.name, "TX_1",
532 sizeof(kcontrol->id.name))) {
533 port->channel = TDM_1;
534 } else if (strnstr(kcontrol->id.name, "RX_2",
535 sizeof(kcontrol->id.name)) ||
536 strnstr(kcontrol->id.name, "TX_2",
537 sizeof(kcontrol->id.name))) {
538 port->channel = TDM_2;
539 } else if (strnstr(kcontrol->id.name, "RX_3",
540 sizeof(kcontrol->id.name)) ||
541 strnstr(kcontrol->id.name, "TX_3",
542 sizeof(kcontrol->id.name))) {
543 port->channel = TDM_3;
544 } else if (strnstr(kcontrol->id.name, "RX_4",
545 sizeof(kcontrol->id.name)) ||
546 strnstr(kcontrol->id.name, "TX_4",
547 sizeof(kcontrol->id.name))) {
548 port->channel = TDM_4;
549 } else if (strnstr(kcontrol->id.name, "RX_5",
550 sizeof(kcontrol->id.name)) ||
551 strnstr(kcontrol->id.name, "TX_5",
552 sizeof(kcontrol->id.name))) {
553 port->channel = TDM_5;
554 } else if (strnstr(kcontrol->id.name, "RX_6",
555 sizeof(kcontrol->id.name)) ||
556 strnstr(kcontrol->id.name, "TX_6",
557 sizeof(kcontrol->id.name))) {
558 port->channel = TDM_6;
559 } else if (strnstr(kcontrol->id.name, "RX_7",
560 sizeof(kcontrol->id.name)) ||
561 strnstr(kcontrol->id.name, "TX_7",
562 sizeof(kcontrol->id.name))) {
563 port->channel = TDM_7;
564 } else {
565 pr_err("%s: unsupported channel in: %s",
566 __func__, kcontrol->id.name);
567 return -EINVAL;
568 }
569 } else
570 return -EINVAL;
571 return 0;
572}
573
574static int tdm_rx_sample_rate_get(struct snd_kcontrol *kcontrol,
575 struct snd_ctl_elem_value *ucontrol)
576{
577 struct tdm_port port;
578 int ret = tdm_get_port_idx(kcontrol, &port);
579
580 if (ret) {
581 pr_err("%s: unsupported control: %s",
582 __func__, kcontrol->id.name);
583 } else {
584 ucontrol->value.enumerated.item[0] = tdm_get_sample_rate_val(
585 tdm_rx_cfg[port.mode][port.channel].sample_rate);
586
587 pr_debug("%s: tdm_rx_sample_rate = %d, item = %d\n", __func__,
588 tdm_rx_cfg[port.mode][port.channel].sample_rate,
589 ucontrol->value.enumerated.item[0]);
590 }
591 return ret;
592}
593
594static int tdm_rx_sample_rate_put(struct snd_kcontrol *kcontrol,
595 struct snd_ctl_elem_value *ucontrol)
596{
597 struct tdm_port port;
598 int ret = tdm_get_port_idx(kcontrol, &port);
599
600 if (ret) {
601 pr_err("%s: unsupported control: %s",
602 __func__, kcontrol->id.name);
603 } else {
604 tdm_rx_cfg[port.mode][port.channel].sample_rate =
605 tdm_get_sample_rate(ucontrol->value.enumerated.item[0]);
606
607 pr_debug("%s: tdm_rx_sample_rate = %d, item = %d\n", __func__,
608 tdm_rx_cfg[port.mode][port.channel].sample_rate,
609 ucontrol->value.enumerated.item[0]);
610 }
611 return ret;
612}
613
614static int tdm_tx_sample_rate_get(struct snd_kcontrol *kcontrol,
615 struct snd_ctl_elem_value *ucontrol)
616{
617 struct tdm_port port;
618 int ret = tdm_get_port_idx(kcontrol, &port);
619
620 if (ret) {
621 pr_err("%s: unsupported control: %s",
622 __func__, kcontrol->id.name);
623 } else {
624 ucontrol->value.enumerated.item[0] = tdm_get_sample_rate_val(
625 tdm_tx_cfg[port.mode][port.channel].sample_rate);
626
627 pr_debug("%s: tdm_tx_sample_rate = %d, item = %d\n", __func__,
628 tdm_tx_cfg[port.mode][port.channel].sample_rate,
629 ucontrol->value.enumerated.item[0]);
630 }
631 return ret;
632}
633
634static int tdm_tx_sample_rate_put(struct snd_kcontrol *kcontrol,
635 struct snd_ctl_elem_value *ucontrol)
636{
637 struct tdm_port port;
638 int ret = tdm_get_port_idx(kcontrol, &port);
639
640 if (ret) {
641 pr_err("%s: unsupported control: %s",
642 __func__, kcontrol->id.name);
643 } else {
644 tdm_tx_cfg[port.mode][port.channel].sample_rate =
645 tdm_get_sample_rate(ucontrol->value.enumerated.item[0]);
646
647 pr_debug("%s: tdm_tx_sample_rate = %d, item = %d\n", __func__,
648 tdm_tx_cfg[port.mode][port.channel].sample_rate,
649 ucontrol->value.enumerated.item[0]);
650 }
651 return ret;
652}
653
654static int tdm_get_format(int value)
655{
656 int format = 0;
657
658 switch (value) {
659 case 0:
660 format = SNDRV_PCM_FORMAT_S16_LE;
661 break;
662 case 1:
663 format = SNDRV_PCM_FORMAT_S24_LE;
664 break;
665 case 2:
666 format = SNDRV_PCM_FORMAT_S32_LE;
667 break;
668 default:
669 format = SNDRV_PCM_FORMAT_S16_LE;
670 break;
671 }
672 return format;
673}
674
675static int tdm_get_format_val(int format)
676{
677 int value = 0;
678
679 switch (format) {
680 case SNDRV_PCM_FORMAT_S16_LE:
681 value = 0;
682 break;
683 case SNDRV_PCM_FORMAT_S24_LE:
684 value = 1;
685 break;
686 case SNDRV_PCM_FORMAT_S32_LE:
687 value = 2;
688 break;
689 default:
690 value = 0;
691 break;
692 }
693 return value;
694}
695
Tanya Dixitc8ecc2e2017-02-17 17:57:44 +0530696static int mi2s_get_format(int value)
697{
698 int format = 0;
699
700 switch (value) {
701 case 0:
702 format = SNDRV_PCM_FORMAT_S16_LE;
703 break;
704 case 1:
705 format = SNDRV_PCM_FORMAT_S24_LE;
706 break;
707 case 2:
708 format = SNDRV_PCM_FORMAT_S24_3LE;
709 break;
710 case 3:
711 format = SNDRV_PCM_FORMAT_S32_LE;
712 break;
713 default:
714 format = SNDRV_PCM_FORMAT_S16_LE;
715 break;
716 }
717 return format;
718}
719
720static int mi2s_get_format_value(int format)
721{
722 int value = 0;
723
724 switch (format) {
725 case SNDRV_PCM_FORMAT_S16_LE:
726 value = 0;
727 break;
728 case SNDRV_PCM_FORMAT_S24_LE:
729 value = 1;
730 break;
731 case SNDRV_PCM_FORMAT_S24_3LE:
732 value = 2;
733 break;
734 case SNDRV_PCM_FORMAT_S32_LE:
735 value = 3;
736 break;
737 default:
738 value = 0;
739 break;
740 }
741 return value;
742}
743
Banajit Goswami0530e2f2016-12-09 21:34:37 -0800744static int tdm_rx_format_get(struct snd_kcontrol *kcontrol,
745 struct snd_ctl_elem_value *ucontrol)
746{
747 struct tdm_port port;
748 int ret = tdm_get_port_idx(kcontrol, &port);
749
750 if (ret) {
751 pr_err("%s: unsupported control: %s",
752 __func__, kcontrol->id.name);
753 } else {
754 ucontrol->value.enumerated.item[0] = tdm_get_format_val(
755 tdm_rx_cfg[port.mode][port.channel].bit_format);
756
757 pr_debug("%s: tdm_rx_bit_format = %d, item = %d\n", __func__,
758 tdm_rx_cfg[port.mode][port.channel].bit_format,
759 ucontrol->value.enumerated.item[0]);
760 }
761 return ret;
762}
763
764static int tdm_rx_format_put(struct snd_kcontrol *kcontrol,
765 struct snd_ctl_elem_value *ucontrol)
766{
767 struct tdm_port port;
768 int ret = tdm_get_port_idx(kcontrol, &port);
769
770 if (ret) {
771 pr_err("%s: unsupported control: %s",
772 __func__, kcontrol->id.name);
773 } else {
774 tdm_rx_cfg[port.mode][port.channel].bit_format =
775 tdm_get_format(ucontrol->value.enumerated.item[0]);
776
777 pr_debug("%s: tdm_rx_bit_format = %d, item = %d\n", __func__,
778 tdm_rx_cfg[port.mode][port.channel].bit_format,
779 ucontrol->value.enumerated.item[0]);
780 }
781 return ret;
782}
783
784static int tdm_tx_format_get(struct snd_kcontrol *kcontrol,
785 struct snd_ctl_elem_value *ucontrol)
786{
787 struct tdm_port port;
788 int ret = tdm_get_port_idx(kcontrol, &port);
789
790 if (ret) {
791 pr_err("%s: unsupported control: %s",
792 __func__, kcontrol->id.name);
793 } else {
794 ucontrol->value.enumerated.item[0] = tdm_get_format_val(
795 tdm_tx_cfg[port.mode][port.channel].bit_format);
796
797 pr_debug("%s: tdm_tx_bit_format = %d, item = %d\n", __func__,
798 tdm_tx_cfg[port.mode][port.channel].bit_format,
799 ucontrol->value.enumerated.item[0]);
800 }
801 return ret;
802}
803
804static int tdm_tx_format_put(struct snd_kcontrol *kcontrol,
805 struct snd_ctl_elem_value *ucontrol)
806{
807 struct tdm_port port;
808 int ret = tdm_get_port_idx(kcontrol, &port);
809
810 if (ret) {
811 pr_err("%s: unsupported control: %s",
812 __func__, kcontrol->id.name);
813 } else {
814 tdm_tx_cfg[port.mode][port.channel].bit_format =
815 tdm_get_format(ucontrol->value.enumerated.item[0]);
816
817 pr_debug("%s: tdm_tx_bit_format = %d, item = %d\n", __func__,
818 tdm_tx_cfg[port.mode][port.channel].bit_format,
819 ucontrol->value.enumerated.item[0]);
820 }
821 return ret;
822}
823
824static int tdm_rx_ch_get(struct snd_kcontrol *kcontrol,
825 struct snd_ctl_elem_value *ucontrol)
826{
827 struct tdm_port port;
828 int ret = tdm_get_port_idx(kcontrol, &port);
829
830 if (ret) {
831 pr_err("%s: unsupported control: %s",
832 __func__, kcontrol->id.name);
833 } else {
834
835 ucontrol->value.enumerated.item[0] =
836 tdm_rx_cfg[port.mode][port.channel].channels - 1;
837
838 pr_debug("%s: tdm_rx_ch = %d, item = %d\n", __func__,
839 tdm_rx_cfg[port.mode][port.channel].channels - 1,
840 ucontrol->value.enumerated.item[0]);
841 }
842 return ret;
843}
844
845static int tdm_rx_ch_put(struct snd_kcontrol *kcontrol,
846 struct snd_ctl_elem_value *ucontrol)
847{
848 struct tdm_port port;
849 int ret = tdm_get_port_idx(kcontrol, &port);
850
851 if (ret) {
852 pr_err("%s: unsupported control: %s",
853 __func__, kcontrol->id.name);
854 } else {
855 tdm_rx_cfg[port.mode][port.channel].channels =
856 ucontrol->value.enumerated.item[0] + 1;
857
858 pr_debug("%s: tdm_rx_ch = %d, item = %d\n", __func__,
859 tdm_rx_cfg[port.mode][port.channel].channels,
860 ucontrol->value.enumerated.item[0] + 1);
861 }
862 return ret;
863}
864
865static int tdm_tx_ch_get(struct snd_kcontrol *kcontrol,
866 struct snd_ctl_elem_value *ucontrol)
867{
868 struct tdm_port port;
869 int ret = tdm_get_port_idx(kcontrol, &port);
870
871 if (ret) {
872 pr_err("%s: unsupported control: %s",
873 __func__, kcontrol->id.name);
874 } else {
875 ucontrol->value.enumerated.item[0] =
876 tdm_tx_cfg[port.mode][port.channel].channels - 1;
877
878 pr_debug("%s: tdm_tx_ch = %d, item = %d\n", __func__,
879 tdm_tx_cfg[port.mode][port.channel].channels - 1,
880 ucontrol->value.enumerated.item[0]);
881 }
882 return ret;
883}
884
885static int tdm_tx_ch_put(struct snd_kcontrol *kcontrol,
886 struct snd_ctl_elem_value *ucontrol)
887{
888 struct tdm_port port;
889 int ret = tdm_get_port_idx(kcontrol, &port);
890
891 if (ret) {
892 pr_err("%s: unsupported control: %s",
893 __func__, kcontrol->id.name);
894 } else {
895 tdm_tx_cfg[port.mode][port.channel].channels =
896 ucontrol->value.enumerated.item[0] + 1;
897
898 pr_debug("%s: tdm_tx_ch = %d, item = %d\n", __func__,
899 tdm_tx_cfg[port.mode][port.channel].channels,
900 ucontrol->value.enumerated.item[0] + 1);
901 }
902 return ret;
903}
904
905static int aux_pcm_get_sample_rate(int value)
906{
907 int sample_rate;
908
909 switch (value) {
910 case 1:
911 sample_rate = SAMPLING_RATE_16KHZ;
912 break;
913 case 0:
914 default:
915 sample_rate = SAMPLING_RATE_8KHZ;
916 break;
917 }
918 return sample_rate;
919}
920
921static int aux_pcm_get_sample_rate_val(int sample_rate)
922{
923 int sample_rate_val;
924
925 switch (sample_rate) {
926 case SAMPLING_RATE_16KHZ:
927 sample_rate_val = 1;
928 break;
929 case SAMPLING_RATE_8KHZ:
930 default:
931 sample_rate_val = 0;
932 break;
933 }
934 return sample_rate_val;
935}
936
937static int aux_pcm_get_port_idx(struct snd_kcontrol *kcontrol)
938{
939 int idx;
940
941 if (strnstr(kcontrol->id.name, "PRIM_AUX_PCM",
942 sizeof("PRIM_AUX_PCM")))
943 idx = PRIM_AUX_PCM;
944 else if (strnstr(kcontrol->id.name, "SEC_AUX_PCM",
945 sizeof("SEC_AUX_PCM")))
946 idx = SEC_AUX_PCM;
947 else if (strnstr(kcontrol->id.name, "TERT_AUX_PCM",
948 sizeof("TERT_AUX_PCM")))
949 idx = TERT_AUX_PCM;
950 else if (strnstr(kcontrol->id.name, "QUAT_AUX_PCM",
951 sizeof("QUAT_AUX_PCM")))
952 idx = QUAT_AUX_PCM;
953 else {
954 pr_err("%s: unsupported port: %s",
955 __func__, kcontrol->id.name);
956 idx = -EINVAL;
957 }
958
959 return idx;
960}
961
962static int aux_pcm_rx_sample_rate_put(struct snd_kcontrol *kcontrol,
963 struct snd_ctl_elem_value *ucontrol)
964{
965 int idx = aux_pcm_get_port_idx(kcontrol);
966
967 if (idx < 0)
968 return idx;
969
970 aux_pcm_rx_cfg[idx].sample_rate =
971 aux_pcm_get_sample_rate(ucontrol->value.enumerated.item[0]);
972
973 pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__,
974 idx, aux_pcm_rx_cfg[idx].sample_rate,
975 ucontrol->value.enumerated.item[0]);
976
977 return 0;
978}
979
980static int aux_pcm_rx_sample_rate_get(struct snd_kcontrol *kcontrol,
981 struct snd_ctl_elem_value *ucontrol)
982{
983 int idx = aux_pcm_get_port_idx(kcontrol);
984
985 if (idx < 0)
986 return idx;
987
988 ucontrol->value.enumerated.item[0] =
989 aux_pcm_get_sample_rate_val(aux_pcm_rx_cfg[idx].sample_rate);
990
991 pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__,
992 idx, aux_pcm_rx_cfg[idx].sample_rate,
993 ucontrol->value.enumerated.item[0]);
994
995 return 0;
996}
997
998static int aux_pcm_tx_sample_rate_put(struct snd_kcontrol *kcontrol,
999 struct snd_ctl_elem_value *ucontrol)
1000{
1001 int idx = aux_pcm_get_port_idx(kcontrol);
1002
1003 if (idx < 0)
1004 return idx;
1005
1006 aux_pcm_tx_cfg[idx].sample_rate =
1007 aux_pcm_get_sample_rate(ucontrol->value.enumerated.item[0]);
1008
1009 pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__,
1010 idx, aux_pcm_tx_cfg[idx].sample_rate,
1011 ucontrol->value.enumerated.item[0]);
1012
1013 return 0;
1014}
1015
1016static int aux_pcm_tx_sample_rate_get(struct snd_kcontrol *kcontrol,
1017 struct snd_ctl_elem_value *ucontrol)
1018{
1019 int idx = aux_pcm_get_port_idx(kcontrol);
1020
1021 if (idx < 0)
1022 return idx;
1023
1024 ucontrol->value.enumerated.item[0] =
1025 aux_pcm_get_sample_rate_val(aux_pcm_tx_cfg[idx].sample_rate);
1026
1027 pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__,
1028 idx, aux_pcm_tx_cfg[idx].sample_rate,
1029 ucontrol->value.enumerated.item[0]);
1030
1031 return 0;
1032}
1033
1034static int mi2s_get_port_idx(struct snd_kcontrol *kcontrol)
1035{
1036 int idx;
1037
1038 if (strnstr(kcontrol->id.name, "PRIM_MI2S_RX",
1039 sizeof("PRIM_MI2S_RX")))
1040 idx = PRIM_MI2S;
1041 else if (strnstr(kcontrol->id.name, "SEC_MI2S_RX",
1042 sizeof("SEC_MI2S_RX")))
1043 idx = SEC_MI2S;
1044 else if (strnstr(kcontrol->id.name, "TERT_MI2S_RX",
1045 sizeof("TERT_MI2S_RX")))
1046 idx = TERT_MI2S;
1047 else if (strnstr(kcontrol->id.name, "QUAT_MI2S_RX",
1048 sizeof("QUAT_MI2S_RX")))
1049 idx = QUAT_MI2S;
1050 else if (strnstr(kcontrol->id.name, "PRIM_MI2S_TX",
1051 sizeof("PRIM_MI2S_TX")))
1052 idx = PRIM_MI2S;
1053 else if (strnstr(kcontrol->id.name, "SEC_MI2S_TX",
1054 sizeof("SEC_MI2S_TX")))
1055 idx = SEC_MI2S;
1056 else if (strnstr(kcontrol->id.name, "TERT_MI2S_TX",
1057 sizeof("TERT_MI2S_TX")))
1058 idx = TERT_MI2S;
1059 else if (strnstr(kcontrol->id.name, "QUAT_MI2S_TX",
1060 sizeof("QUAT_MI2S_TX")))
1061 idx = QUAT_MI2S;
1062 else {
1063 pr_err("%s: unsupported channel: %s",
1064 __func__, kcontrol->id.name);
1065 idx = -EINVAL;
1066 }
1067
1068 return idx;
1069}
1070
1071static int mi2s_get_sample_rate_val(int sample_rate)
1072{
1073 int sample_rate_val;
1074
1075 switch (sample_rate) {
1076 case SAMPLING_RATE_8KHZ:
1077 sample_rate_val = 0;
1078 break;
1079 case SAMPLING_RATE_16KHZ:
1080 sample_rate_val = 1;
1081 break;
1082 case SAMPLING_RATE_32KHZ:
1083 sample_rate_val = 2;
1084 break;
1085 case SAMPLING_RATE_44P1KHZ:
1086 sample_rate_val = 3;
1087 break;
1088 case SAMPLING_RATE_48KHZ:
1089 sample_rate_val = 4;
1090 break;
1091 case SAMPLING_RATE_96KHZ:
1092 sample_rate_val = 5;
1093 break;
1094 case SAMPLING_RATE_192KHZ:
1095 sample_rate_val = 6;
1096 break;
1097 default:
1098 sample_rate_val = 4;
1099 break;
1100 }
1101 return sample_rate_val;
1102}
1103
1104static int mi2s_get_sample_rate(int value)
1105{
1106 int sample_rate;
1107
1108 switch (value) {
1109 case 0:
1110 sample_rate = SAMPLING_RATE_8KHZ;
1111 break;
1112 case 1:
1113 sample_rate = SAMPLING_RATE_16KHZ;
1114 break;
1115 case 2:
1116 sample_rate = SAMPLING_RATE_32KHZ;
1117 break;
1118 case 3:
1119 sample_rate = SAMPLING_RATE_44P1KHZ;
1120 break;
1121 case 4:
1122 sample_rate = SAMPLING_RATE_48KHZ;
1123 break;
1124 case 5:
1125 sample_rate = SAMPLING_RATE_96KHZ;
1126 break;
1127 case 6:
1128 sample_rate = SAMPLING_RATE_192KHZ;
1129 break;
1130 default:
1131 sample_rate = SAMPLING_RATE_48KHZ;
1132 break;
1133 }
1134 return sample_rate;
1135}
1136
1137static int mi2s_rx_sample_rate_put(struct snd_kcontrol *kcontrol,
1138 struct snd_ctl_elem_value *ucontrol)
1139{
1140 int idx = mi2s_get_port_idx(kcontrol);
1141
1142 if (idx < 0)
1143 return idx;
1144
1145 mi2s_rx_cfg[idx].sample_rate =
1146 mi2s_get_sample_rate(ucontrol->value.enumerated.item[0]);
1147
1148 pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__,
1149 idx, mi2s_rx_cfg[idx].sample_rate,
1150 ucontrol->value.enumerated.item[0]);
1151
1152 return 0;
1153}
1154
1155static int mi2s_rx_sample_rate_get(struct snd_kcontrol *kcontrol,
1156 struct snd_ctl_elem_value *ucontrol)
1157{
1158 int idx = mi2s_get_port_idx(kcontrol);
1159
1160 if (idx < 0)
1161 return idx;
1162
1163 ucontrol->value.enumerated.item[0] =
1164 mi2s_get_sample_rate_val(mi2s_rx_cfg[idx].sample_rate);
1165
1166 pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__,
1167 idx, mi2s_rx_cfg[idx].sample_rate,
1168 ucontrol->value.enumerated.item[0]);
1169
1170 return 0;
1171}
1172
1173static int mi2s_tx_sample_rate_put(struct snd_kcontrol *kcontrol,
1174 struct snd_ctl_elem_value *ucontrol)
1175{
1176 int idx = mi2s_get_port_idx(kcontrol);
1177
1178 if (idx < 0)
1179 return idx;
1180
1181 mi2s_tx_cfg[idx].sample_rate =
1182 mi2s_get_sample_rate(ucontrol->value.enumerated.item[0]);
1183
1184 pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__,
1185 idx, mi2s_tx_cfg[idx].sample_rate,
1186 ucontrol->value.enumerated.item[0]);
1187
1188 return 0;
1189}
1190
1191static int mi2s_tx_sample_rate_get(struct snd_kcontrol *kcontrol,
1192 struct snd_ctl_elem_value *ucontrol)
1193{
1194 int idx = mi2s_get_port_idx(kcontrol);
1195
1196 if (idx < 0)
1197 return idx;
1198
1199 ucontrol->value.enumerated.item[0] =
1200 mi2s_get_sample_rate_val(mi2s_tx_cfg[idx].sample_rate);
1201
1202 pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__,
1203 idx, mi2s_tx_cfg[idx].sample_rate,
1204 ucontrol->value.enumerated.item[0]);
1205
1206 return 0;
1207}
1208
Tanya Dixitc8ecc2e2017-02-17 17:57:44 +05301209static int mi2s_tx_format_put(struct snd_kcontrol *kcontrol,
1210 struct snd_ctl_elem_value *ucontrol)
1211{
1212 int idx = mi2s_get_port_idx(kcontrol);
1213
1214 if (idx < 0)
1215 return idx;
1216
1217 mi2s_tx_cfg[idx].bit_format =
1218 mi2s_get_format(ucontrol->value.enumerated.item[0]);
1219
1220 pr_debug("%s: idx[%d] _tx_format = %d, item = %d\n", __func__,
1221 idx, mi2s_tx_cfg[idx].bit_format,
1222 ucontrol->value.enumerated.item[0]);
1223
1224 return 0;
1225}
1226
1227static int mi2s_tx_format_get(struct snd_kcontrol *kcontrol,
1228 struct snd_ctl_elem_value *ucontrol)
1229{
1230 int idx = mi2s_get_port_idx(kcontrol);
1231
1232 if (idx < 0)
1233 return idx;
1234
1235 ucontrol->value.enumerated.item[0] =
1236 mi2s_get_format_value(mi2s_tx_cfg[idx].bit_format);
1237
1238 pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__,
1239 idx, mi2s_tx_cfg[idx].bit_format,
1240 ucontrol->value.enumerated.item[0]);
1241
1242 return 0;
1243}
1244
1245static int mi2s_rx_format_put(struct snd_kcontrol *kcontrol,
1246 struct snd_ctl_elem_value *ucontrol)
1247{
1248 int idx = mi2s_get_port_idx(kcontrol);
1249
1250 if (idx < 0)
1251 return idx;
1252
1253 mi2s_rx_cfg[idx].bit_format =
1254 mi2s_get_format(ucontrol->value.enumerated.item[0]);
1255
1256 pr_debug("%s: idx[%d] _rx_format = %d, item = %d\n", __func__,
1257 idx, mi2s_rx_cfg[idx].bit_format,
1258 ucontrol->value.enumerated.item[0]);
1259
1260 return 0;
1261}
1262
1263static int mi2s_rx_format_get(struct snd_kcontrol *kcontrol,
1264 struct snd_ctl_elem_value *ucontrol)
1265{
1266 int idx = mi2s_get_port_idx(kcontrol);
1267
1268 if (idx < 0)
1269 return idx;
1270
1271 ucontrol->value.enumerated.item[0] =
1272 mi2s_get_format_value(mi2s_rx_cfg[idx].bit_format);
1273
1274 pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__,
1275 idx, mi2s_rx_cfg[idx].bit_format,
1276 ucontrol->value.enumerated.item[0]);
1277
1278 return 0;
1279}
1280
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001281static int msm_mi2s_rx_ch_get(struct snd_kcontrol *kcontrol,
1282 struct snd_ctl_elem_value *ucontrol)
1283{
1284 int idx = mi2s_get_port_idx(kcontrol);
1285
1286 if (idx < 0)
1287 return idx;
1288
1289 pr_debug("%s: msm_mi2s_[%d]_rx_ch = %d\n", __func__,
1290 idx, mi2s_rx_cfg[idx].channels);
1291 ucontrol->value.enumerated.item[0] = mi2s_rx_cfg[idx].channels - 1;
1292
1293 return 0;
1294}
1295
1296static int msm_mi2s_rx_ch_put(struct snd_kcontrol *kcontrol,
1297 struct snd_ctl_elem_value *ucontrol)
1298{
1299 int idx = mi2s_get_port_idx(kcontrol);
1300
1301 if (idx < 0)
1302 return idx;
1303
1304 mi2s_rx_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1;
1305 pr_debug("%s: msm_mi2s_[%d]_rx_ch = %d\n", __func__,
1306 idx, mi2s_rx_cfg[idx].channels);
1307
1308 return 1;
1309}
1310
1311static int msm_mi2s_tx_ch_get(struct snd_kcontrol *kcontrol,
1312 struct snd_ctl_elem_value *ucontrol)
1313{
1314 int idx = mi2s_get_port_idx(kcontrol);
1315
1316 if (idx < 0)
1317 return idx;
1318
1319 pr_debug("%s: msm_mi2s_[%d]_tx_ch = %d\n", __func__,
1320 idx, mi2s_tx_cfg[idx].channels);
1321 ucontrol->value.enumerated.item[0] = mi2s_tx_cfg[idx].channels - 1;
1322
1323 return 0;
1324}
1325
1326static int msm_mi2s_tx_ch_put(struct snd_kcontrol *kcontrol,
1327 struct snd_ctl_elem_value *ucontrol)
1328{
1329 int idx = mi2s_get_port_idx(kcontrol);
1330
1331 if (idx < 0)
1332 return idx;
1333
1334 mi2s_tx_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1;
1335 pr_debug("%s: msm_mi2s_[%d]_tx_ch = %d\n", __func__,
1336 idx, mi2s_tx_cfg[idx].channels);
1337
1338 return 1;
1339}
1340
1341static int usb_audio_rx_ch_get(struct snd_kcontrol *kcontrol,
1342 struct snd_ctl_elem_value *ucontrol)
1343{
1344 pr_debug("%s: usb_audio_rx_ch = %d\n", __func__,
1345 usb_rx_cfg.channels);
1346 ucontrol->value.integer.value[0] = usb_rx_cfg.channels - 1;
1347 return 0;
1348}
1349
1350static int usb_audio_rx_ch_put(struct snd_kcontrol *kcontrol,
1351 struct snd_ctl_elem_value *ucontrol)
1352{
1353 usb_rx_cfg.channels = ucontrol->value.integer.value[0] + 1;
1354
1355 pr_debug("%s: usb_audio_rx_ch = %d\n", __func__, usb_rx_cfg.channels);
1356 return 1;
1357}
1358
1359static int usb_audio_rx_sample_rate_get(struct snd_kcontrol *kcontrol,
1360 struct snd_ctl_elem_value *ucontrol)
1361{
1362 int sample_rate_val;
1363
1364 switch (usb_rx_cfg.sample_rate) {
1365 case SAMPLING_RATE_384KHZ:
1366 sample_rate_val = 9;
1367 break;
1368 case SAMPLING_RATE_192KHZ:
1369 sample_rate_val = 8;
1370 break;
1371 case SAMPLING_RATE_96KHZ:
1372 sample_rate_val = 7;
1373 break;
1374 case SAMPLING_RATE_48KHZ:
1375 sample_rate_val = 6;
1376 break;
1377 case SAMPLING_RATE_44P1KHZ:
1378 sample_rate_val = 5;
1379 break;
1380 case SAMPLING_RATE_32KHZ:
1381 sample_rate_val = 4;
1382 break;
1383 case SAMPLING_RATE_22P05KHZ:
1384 sample_rate_val = 3;
1385 break;
1386 case SAMPLING_RATE_16KHZ:
1387 sample_rate_val = 2;
1388 break;
1389 case SAMPLING_RATE_11P025KHZ:
1390 sample_rate_val = 1;
1391 break;
1392 case SAMPLING_RATE_8KHZ:
1393 default:
1394 sample_rate_val = 0;
1395 break;
1396 }
1397
1398 ucontrol->value.integer.value[0] = sample_rate_val;
1399 pr_debug("%s: usb_audio_rx_sample_rate = %d\n", __func__,
1400 usb_rx_cfg.sample_rate);
1401 return 0;
1402}
1403
1404static int usb_audio_rx_sample_rate_put(struct snd_kcontrol *kcontrol,
1405 struct snd_ctl_elem_value *ucontrol)
1406{
1407 switch (ucontrol->value.integer.value[0]) {
1408 case 9:
1409 usb_rx_cfg.sample_rate = SAMPLING_RATE_384KHZ;
1410 break;
1411 case 8:
1412 usb_rx_cfg.sample_rate = SAMPLING_RATE_192KHZ;
1413 break;
1414 case 7:
1415 usb_rx_cfg.sample_rate = SAMPLING_RATE_96KHZ;
1416 break;
1417 case 6:
1418 usb_rx_cfg.sample_rate = SAMPLING_RATE_48KHZ;
1419 break;
1420 case 5:
1421 usb_rx_cfg.sample_rate = SAMPLING_RATE_44P1KHZ;
1422 break;
1423 case 4:
1424 usb_rx_cfg.sample_rate = SAMPLING_RATE_32KHZ;
1425 break;
1426 case 3:
1427 usb_rx_cfg.sample_rate = SAMPLING_RATE_22P05KHZ;
1428 break;
1429 case 2:
1430 usb_rx_cfg.sample_rate = SAMPLING_RATE_16KHZ;
1431 break;
1432 case 1:
1433 usb_rx_cfg.sample_rate = SAMPLING_RATE_11P025KHZ;
1434 break;
1435 case 0:
1436 usb_rx_cfg.sample_rate = SAMPLING_RATE_8KHZ;
1437 break;
1438 default:
1439 usb_rx_cfg.sample_rate = SAMPLING_RATE_48KHZ;
1440 break;
1441 }
1442
1443 pr_debug("%s: control value = %ld, usb_audio_rx_sample_rate = %d\n",
1444 __func__, ucontrol->value.integer.value[0],
1445 usb_rx_cfg.sample_rate);
1446 return 0;
1447}
1448
1449static int usb_audio_rx_format_get(struct snd_kcontrol *kcontrol,
1450 struct snd_ctl_elem_value *ucontrol)
1451{
1452 switch (usb_rx_cfg.bit_format) {
1453 case SNDRV_PCM_FORMAT_S32_LE:
1454 ucontrol->value.integer.value[0] = 3;
1455 break;
1456 case SNDRV_PCM_FORMAT_S24_3LE:
1457 ucontrol->value.integer.value[0] = 2;
1458 break;
1459 case SNDRV_PCM_FORMAT_S24_LE:
1460 ucontrol->value.integer.value[0] = 1;
1461 break;
1462 case SNDRV_PCM_FORMAT_S16_LE:
1463 default:
1464 ucontrol->value.integer.value[0] = 0;
1465 break;
1466 }
1467
1468 pr_debug("%s: usb_audio_rx_format = %d, ucontrol value = %ld\n",
1469 __func__, usb_rx_cfg.bit_format,
1470 ucontrol->value.integer.value[0]);
1471 return 0;
1472}
1473
1474static int usb_audio_rx_format_put(struct snd_kcontrol *kcontrol,
1475 struct snd_ctl_elem_value *ucontrol)
1476{
1477 int rc = 0;
1478
1479 switch (ucontrol->value.integer.value[0]) {
1480 case 3:
1481 usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S32_LE;
1482 break;
1483 case 2:
1484 usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_3LE;
1485 break;
1486 case 1:
1487 usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_LE;
1488 break;
1489 case 0:
1490 default:
1491 usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S16_LE;
1492 break;
1493 }
1494 pr_debug("%s: usb_audio_rx_format = %d, ucontrol value = %ld\n",
1495 __func__, usb_rx_cfg.bit_format,
1496 ucontrol->value.integer.value[0]);
1497
1498 return rc;
1499}
1500
1501static int usb_audio_tx_ch_get(struct snd_kcontrol *kcontrol,
1502 struct snd_ctl_elem_value *ucontrol)
1503{
1504 pr_debug("%s: usb_audio_tx_ch = %d\n", __func__,
1505 usb_tx_cfg.channels);
1506 ucontrol->value.integer.value[0] = usb_tx_cfg.channels - 1;
1507 return 0;
1508}
1509
1510static int usb_audio_tx_ch_put(struct snd_kcontrol *kcontrol,
1511 struct snd_ctl_elem_value *ucontrol)
1512{
1513 usb_tx_cfg.channels = ucontrol->value.integer.value[0] + 1;
1514
1515 pr_debug("%s: usb_audio_tx_ch = %d\n", __func__, usb_tx_cfg.channels);
1516 return 1;
1517}
1518
1519static int usb_audio_tx_sample_rate_get(struct snd_kcontrol *kcontrol,
1520 struct snd_ctl_elem_value *ucontrol)
1521{
1522 int sample_rate_val;
1523
1524 switch (usb_tx_cfg.sample_rate) {
1525 case SAMPLING_RATE_384KHZ:
1526 sample_rate_val = 9;
1527 break;
1528 case SAMPLING_RATE_192KHZ:
1529 sample_rate_val = 8;
1530 break;
1531 case SAMPLING_RATE_96KHZ:
1532 sample_rate_val = 7;
1533 break;
1534 case SAMPLING_RATE_48KHZ:
1535 sample_rate_val = 6;
1536 break;
1537 case SAMPLING_RATE_44P1KHZ:
1538 sample_rate_val = 5;
1539 break;
1540 case SAMPLING_RATE_32KHZ:
1541 sample_rate_val = 4;
1542 break;
1543 case SAMPLING_RATE_22P05KHZ:
1544 sample_rate_val = 3;
1545 break;
1546 case SAMPLING_RATE_16KHZ:
1547 sample_rate_val = 2;
1548 break;
1549 case SAMPLING_RATE_11P025KHZ:
1550 sample_rate_val = 1;
1551 break;
1552 case SAMPLING_RATE_8KHZ:
1553 sample_rate_val = 0;
1554 break;
1555 default:
1556 sample_rate_val = 6;
1557 break;
1558 }
1559
1560 ucontrol->value.integer.value[0] = sample_rate_val;
1561 pr_debug("%s: usb_audio_tx_sample_rate = %d\n", __func__,
1562 usb_tx_cfg.sample_rate);
1563 return 0;
1564}
1565
1566static int usb_audio_tx_sample_rate_put(struct snd_kcontrol *kcontrol,
1567 struct snd_ctl_elem_value *ucontrol)
1568{
1569 switch (ucontrol->value.integer.value[0]) {
1570 case 9:
1571 usb_tx_cfg.sample_rate = SAMPLING_RATE_384KHZ;
1572 break;
1573 case 8:
1574 usb_tx_cfg.sample_rate = SAMPLING_RATE_192KHZ;
1575 break;
1576 case 7:
1577 usb_tx_cfg.sample_rate = SAMPLING_RATE_96KHZ;
1578 break;
1579 case 6:
1580 usb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ;
1581 break;
1582 case 5:
1583 usb_tx_cfg.sample_rate = SAMPLING_RATE_44P1KHZ;
1584 break;
1585 case 4:
1586 usb_tx_cfg.sample_rate = SAMPLING_RATE_32KHZ;
1587 break;
1588 case 3:
1589 usb_tx_cfg.sample_rate = SAMPLING_RATE_22P05KHZ;
1590 break;
1591 case 2:
1592 usb_tx_cfg.sample_rate = SAMPLING_RATE_16KHZ;
1593 break;
1594 case 1:
1595 usb_tx_cfg.sample_rate = SAMPLING_RATE_11P025KHZ;
1596 break;
1597 case 0:
1598 usb_tx_cfg.sample_rate = SAMPLING_RATE_8KHZ;
1599 break;
1600 default:
1601 usb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ;
1602 break;
1603 }
1604
1605 pr_debug("%s: control value = %ld, usb_audio_tx_sample_rate = %d\n",
1606 __func__, ucontrol->value.integer.value[0],
1607 usb_tx_cfg.sample_rate);
1608 return 0;
1609}
1610
1611static int usb_audio_tx_format_get(struct snd_kcontrol *kcontrol,
1612 struct snd_ctl_elem_value *ucontrol)
1613{
1614 switch (usb_tx_cfg.bit_format) {
1615 case SNDRV_PCM_FORMAT_S32_LE:
1616 ucontrol->value.integer.value[0] = 3;
1617 break;
1618 case SNDRV_PCM_FORMAT_S24_3LE:
1619 ucontrol->value.integer.value[0] = 2;
1620 break;
1621 case SNDRV_PCM_FORMAT_S24_LE:
1622 ucontrol->value.integer.value[0] = 1;
1623 break;
1624 case SNDRV_PCM_FORMAT_S16_LE:
1625 default:
1626 ucontrol->value.integer.value[0] = 0;
1627 break;
1628 }
1629
1630 pr_debug("%s: usb_audio_tx_format = %d, ucontrol value = %ld\n",
1631 __func__, usb_tx_cfg.bit_format,
1632 ucontrol->value.integer.value[0]);
1633 return 0;
1634}
1635
1636static int usb_audio_tx_format_put(struct snd_kcontrol *kcontrol,
1637 struct snd_ctl_elem_value *ucontrol)
1638{
1639 int rc = 0;
1640
1641 switch (ucontrol->value.integer.value[0]) {
1642 case 3:
1643 usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S32_LE;
1644 break;
1645 case 2:
1646 usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_3LE;
1647 break;
1648 case 1:
1649 usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_LE;
1650 break;
1651 case 0:
1652 default:
1653 usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S16_LE;
1654 break;
1655 }
1656 pr_debug("%s: usb_audio_tx_format = %d, ucontrol value = %ld\n",
1657 __func__, usb_tx_cfg.bit_format,
1658 ucontrol->value.integer.value[0]);
1659
1660 return rc;
1661}
1662
Rohit Kumar0bd27132016-12-06 14:48:58 +05301663static int ext_disp_get_port_idx(struct snd_kcontrol *kcontrol)
1664{
1665 int idx;
1666
1667 if (strnstr(kcontrol->id.name, "Display Port RX",
1668 sizeof("Display Port RX")))
1669 idx = DP_RX_IDX;
1670 else {
1671 pr_err("%s: unsupported BE: %s",
1672 __func__, kcontrol->id.name);
1673 idx = -EINVAL;
1674 }
1675
1676 return idx;
1677}
1678
1679static int ext_disp_rx_format_get(struct snd_kcontrol *kcontrol,
1680 struct snd_ctl_elem_value *ucontrol)
1681{
1682 int idx = ext_disp_get_port_idx(kcontrol);
1683
1684 if (idx < 0)
1685 return idx;
1686
1687 switch (ext_disp_rx_cfg[idx].bit_format) {
1688 case SNDRV_PCM_FORMAT_S24_LE:
1689 ucontrol->value.integer.value[0] = 1;
1690 break;
1691
1692 case SNDRV_PCM_FORMAT_S16_LE:
1693 default:
1694 ucontrol->value.integer.value[0] = 0;
1695 break;
1696 }
1697
1698 pr_debug("%s: ext_disp_rx[%d].format = %d, ucontrol value = %ld\n",
1699 __func__, idx, ext_disp_rx_cfg[idx].bit_format,
1700 ucontrol->value.integer.value[0]);
1701 return 0;
1702}
1703
1704static int ext_disp_rx_format_put(struct snd_kcontrol *kcontrol,
1705 struct snd_ctl_elem_value *ucontrol)
1706{
1707 int idx = ext_disp_get_port_idx(kcontrol);
1708
1709 if (idx < 0)
1710 return idx;
1711
1712 switch (ucontrol->value.integer.value[0]) {
1713 case 1:
1714 ext_disp_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S24_LE;
1715 break;
1716 case 0:
1717 default:
1718 ext_disp_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S16_LE;
1719 break;
1720 }
1721 pr_debug("%s: ext_disp_rx[%d].format = %d, ucontrol value = %ld\n",
1722 __func__, idx, ext_disp_rx_cfg[idx].bit_format,
1723 ucontrol->value.integer.value[0]);
1724
1725 return 0;
1726}
1727
1728static int ext_disp_rx_ch_get(struct snd_kcontrol *kcontrol,
1729 struct snd_ctl_elem_value *ucontrol)
1730{
1731 int idx = ext_disp_get_port_idx(kcontrol);
1732
1733 if (idx < 0)
1734 return idx;
1735
1736 ucontrol->value.integer.value[0] =
1737 ext_disp_rx_cfg[idx].channels - 2;
1738
1739 pr_debug("%s: ext_disp_rx[%d].ch = %d\n", __func__,
1740 idx, ext_disp_rx_cfg[idx].channels);
1741
1742 return 0;
1743}
1744
1745static int ext_disp_rx_ch_put(struct snd_kcontrol *kcontrol,
1746 struct snd_ctl_elem_value *ucontrol)
1747{
1748 int idx = ext_disp_get_port_idx(kcontrol);
1749
1750 if (idx < 0)
1751 return idx;
1752
1753 ext_disp_rx_cfg[idx].channels =
1754 ucontrol->value.integer.value[0] + 2;
1755
1756 pr_debug("%s: ext_disp_rx[%d].ch = %d\n", __func__,
1757 idx, ext_disp_rx_cfg[idx].channels);
1758 return 1;
1759}
1760
1761static int ext_disp_rx_sample_rate_get(struct snd_kcontrol *kcontrol,
1762 struct snd_ctl_elem_value *ucontrol)
1763{
1764 int sample_rate_val;
1765 int idx = ext_disp_get_port_idx(kcontrol);
1766
1767 if (idx < 0)
1768 return idx;
1769
1770 switch (ext_disp_rx_cfg[idx].sample_rate) {
1771 case SAMPLING_RATE_192KHZ:
1772 sample_rate_val = 2;
1773 break;
1774
1775 case SAMPLING_RATE_96KHZ:
1776 sample_rate_val = 1;
1777 break;
1778
1779 case SAMPLING_RATE_48KHZ:
1780 default:
1781 sample_rate_val = 0;
1782 break;
1783 }
1784
1785 ucontrol->value.integer.value[0] = sample_rate_val;
1786 pr_debug("%s: ext_disp_rx[%d].sample_rate = %d\n", __func__,
1787 idx, ext_disp_rx_cfg[idx].sample_rate);
1788
1789 return 0;
1790}
1791
1792static int ext_disp_rx_sample_rate_put(struct snd_kcontrol *kcontrol,
1793 struct snd_ctl_elem_value *ucontrol)
1794{
1795 int idx = ext_disp_get_port_idx(kcontrol);
1796
1797 if (idx < 0)
1798 return idx;
1799
1800 switch (ucontrol->value.integer.value[0]) {
1801 case 2:
1802 ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_192KHZ;
1803 break;
1804 case 1:
1805 ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_96KHZ;
1806 break;
1807 case 0:
1808 default:
1809 ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_48KHZ;
1810 break;
1811 }
1812
1813 pr_debug("%s: control value = %ld, ext_disp_rx[%d].sample_rate = %d\n",
1814 __func__, ucontrol->value.integer.value[0], idx,
1815 ext_disp_rx_cfg[idx].sample_rate);
1816 return 0;
1817}
1818
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001819const struct snd_kcontrol_new msm_common_snd_controls[] = {
1820 SOC_ENUM_EXT("PROXY_RX Channels", proxy_rx_chs,
1821 proxy_rx_ch_get, proxy_rx_ch_put),
1822 SOC_ENUM_EXT("PRIM_AUX_PCM_RX SampleRate", prim_aux_pcm_rx_sample_rate,
1823 aux_pcm_rx_sample_rate_get,
1824 aux_pcm_rx_sample_rate_put),
1825 SOC_ENUM_EXT("SEC_AUX_PCM_RX SampleRate", sec_aux_pcm_rx_sample_rate,
1826 aux_pcm_rx_sample_rate_get,
1827 aux_pcm_rx_sample_rate_put),
1828 SOC_ENUM_EXT("TERT_AUX_PCM_RX SampleRate", tert_aux_pcm_rx_sample_rate,
1829 aux_pcm_rx_sample_rate_get,
1830 aux_pcm_rx_sample_rate_put),
1831 SOC_ENUM_EXT("QUAT_AUX_PCM_RX SampleRate", quat_aux_pcm_rx_sample_rate,
1832 aux_pcm_rx_sample_rate_get,
1833 aux_pcm_rx_sample_rate_put),
1834 SOC_ENUM_EXT("PRIM_AUX_PCM_TX SampleRate", prim_aux_pcm_tx_sample_rate,
1835 aux_pcm_tx_sample_rate_get,
1836 aux_pcm_tx_sample_rate_put),
1837 SOC_ENUM_EXT("SEC_AUX_PCM_TX SampleRate", sec_aux_pcm_tx_sample_rate,
1838 aux_pcm_tx_sample_rate_get,
1839 aux_pcm_tx_sample_rate_put),
1840 SOC_ENUM_EXT("TERT_AUX_PCM_TX SampleRate", tert_aux_pcm_tx_sample_rate,
1841 aux_pcm_tx_sample_rate_get,
1842 aux_pcm_tx_sample_rate_put),
1843 SOC_ENUM_EXT("QUAT_AUX_PCM_TX SampleRate", quat_aux_pcm_tx_sample_rate,
1844 aux_pcm_tx_sample_rate_get,
1845 aux_pcm_tx_sample_rate_put),
1846 SOC_ENUM_EXT("PRIM_MI2S_RX SampleRate", prim_mi2s_rx_sample_rate,
1847 mi2s_rx_sample_rate_get,
1848 mi2s_rx_sample_rate_put),
1849 SOC_ENUM_EXT("SEC_MI2S_RX SampleRate", sec_mi2s_rx_sample_rate,
1850 mi2s_rx_sample_rate_get,
1851 mi2s_rx_sample_rate_put),
1852 SOC_ENUM_EXT("TERT_MI2S_RX SampleRate", tert_mi2s_rx_sample_rate,
1853 mi2s_rx_sample_rate_get,
1854 mi2s_rx_sample_rate_put),
1855 SOC_ENUM_EXT("QUAT_MI2S_RX SampleRate", quat_mi2s_rx_sample_rate,
1856 mi2s_rx_sample_rate_get,
1857 mi2s_rx_sample_rate_put),
1858 SOC_ENUM_EXT("PRIM_MI2S_TX SampleRate", prim_mi2s_tx_sample_rate,
1859 mi2s_tx_sample_rate_get,
1860 mi2s_tx_sample_rate_put),
1861 SOC_ENUM_EXT("SEC_MI2S_TX SampleRate", sec_mi2s_tx_sample_rate,
1862 mi2s_tx_sample_rate_get,
1863 mi2s_tx_sample_rate_put),
1864 SOC_ENUM_EXT("TERT_MI2S_TX SampleRate", tert_mi2s_tx_sample_rate,
1865 mi2s_tx_sample_rate_get,
1866 mi2s_tx_sample_rate_put),
1867 SOC_ENUM_EXT("QUAT_MI2S_TX SampleRate", quat_mi2s_tx_sample_rate,
1868 mi2s_tx_sample_rate_get,
1869 mi2s_tx_sample_rate_put),
Tanya Dixitc8ecc2e2017-02-17 17:57:44 +05301870 SOC_ENUM_EXT("PRIM_MI2S_RX Format", prim_mi2s_rx_format,
1871 mi2s_rx_format_get,
1872 mi2s_rx_format_put),
1873 SOC_ENUM_EXT("SEC_MI2S_RX Format", sec_mi2s_rx_format,
1874 mi2s_rx_format_get,
1875 mi2s_rx_format_put),
1876 SOC_ENUM_EXT("TERT_MI2S_RX Format", tert_mi2s_rx_format,
1877 mi2s_rx_format_get,
1878 mi2s_rx_format_put),
1879 SOC_ENUM_EXT("QUAT_MI2S_RX Format", quat_mi2s_rx_format,
1880 mi2s_rx_format_get,
1881 mi2s_rx_format_put),
1882 SOC_ENUM_EXT("PRIM_MI2S_TX Format", prim_mi2s_tx_format,
1883 mi2s_tx_format_get,
1884 mi2s_tx_format_put),
1885 SOC_ENUM_EXT("SEC_MI2S_TX Format", sec_mi2s_tx_format,
1886 mi2s_tx_format_get,
1887 mi2s_tx_format_put),
1888 SOC_ENUM_EXT("TERT_MI2S_TX Format", tert_mi2s_tx_format,
1889 mi2s_tx_format_get,
1890 mi2s_tx_format_put),
1891 SOC_ENUM_EXT("QUAT_MI2S_TX Format", quat_mi2s_tx_format,
1892 mi2s_tx_format_get,
1893 mi2s_tx_format_put),
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001894 SOC_ENUM_EXT("PRIM_MI2S_RX Channels", prim_mi2s_rx_chs,
1895 msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put),
1896 SOC_ENUM_EXT("PRIM_MI2S_TX Channels", prim_mi2s_tx_chs,
1897 msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put),
1898 SOC_ENUM_EXT("SEC_MI2S_RX Channels", sec_mi2s_rx_chs,
1899 msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put),
1900 SOC_ENUM_EXT("SEC_MI2S_TX Channels", sec_mi2s_tx_chs,
1901 msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put),
1902 SOC_ENUM_EXT("TERT_MI2S_RX Channels", tert_mi2s_rx_chs,
1903 msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put),
1904 SOC_ENUM_EXT("TERT_MI2S_TX Channels", tert_mi2s_tx_chs,
1905 msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put),
1906 SOC_ENUM_EXT("QUAT_MI2S_RX Channels", quat_mi2s_rx_chs,
1907 msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put),
1908 SOC_ENUM_EXT("QUAT_MI2S_TX Channels", quat_mi2s_tx_chs,
1909 msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put),
1910 SOC_ENUM_EXT("USB_AUDIO_RX Channels", usb_rx_chs,
1911 usb_audio_rx_ch_get, usb_audio_rx_ch_put),
1912 SOC_ENUM_EXT("USB_AUDIO_TX Channels", usb_tx_chs,
1913 usb_audio_tx_ch_get, usb_audio_tx_ch_put),
Rohit Kumar0bd27132016-12-06 14:48:58 +05301914 SOC_ENUM_EXT("Display Port RX Channels", ext_disp_rx_chs,
1915 ext_disp_rx_ch_get, ext_disp_rx_ch_put),
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001916 SOC_ENUM_EXT("USB_AUDIO_RX Format", usb_rx_format,
1917 usb_audio_rx_format_get, usb_audio_rx_format_put),
1918 SOC_ENUM_EXT("USB_AUDIO_TX Format", usb_tx_format,
1919 usb_audio_tx_format_get, usb_audio_tx_format_put),
Rohit Kumar0bd27132016-12-06 14:48:58 +05301920 SOC_ENUM_EXT("Display Port RX Bit Format", ext_disp_rx_format,
1921 ext_disp_rx_format_get, ext_disp_rx_format_put),
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001922 SOC_ENUM_EXT("USB_AUDIO_RX SampleRate", usb_rx_sample_rate,
1923 usb_audio_rx_sample_rate_get,
1924 usb_audio_rx_sample_rate_put),
1925 SOC_ENUM_EXT("USB_AUDIO_TX SampleRate", usb_tx_sample_rate,
1926 usb_audio_tx_sample_rate_get,
1927 usb_audio_tx_sample_rate_put),
Rohit Kumar0bd27132016-12-06 14:48:58 +05301928 SOC_ENUM_EXT("Display Port RX SampleRate", ext_disp_rx_sample_rate,
1929 ext_disp_rx_sample_rate_get,
1930 ext_disp_rx_sample_rate_put),
Banajit Goswami0530e2f2016-12-09 21:34:37 -08001931 SOC_ENUM_EXT("PRI_TDM_RX_0 SampleRate", tdm_rx_sample_rate,
1932 tdm_rx_sample_rate_get,
1933 tdm_rx_sample_rate_put),
1934 SOC_ENUM_EXT("PRI_TDM_TX_0 SampleRate", tdm_tx_sample_rate,
1935 tdm_tx_sample_rate_get,
1936 tdm_tx_sample_rate_put),
1937 SOC_ENUM_EXT("PRI_TDM_RX_0 Format", tdm_rx_format,
1938 tdm_rx_format_get,
1939 tdm_rx_format_put),
1940 SOC_ENUM_EXT("PRI_TDM_TX_0 Format", tdm_tx_format,
1941 tdm_tx_format_get,
1942 tdm_tx_format_put),
1943 SOC_ENUM_EXT("PRI_TDM_RX_0 Channels", tdm_rx_chs,
1944 tdm_rx_ch_get,
1945 tdm_rx_ch_put),
1946 SOC_ENUM_EXT("PRI_TDM_TX_0 Channels", tdm_tx_chs,
1947 tdm_tx_ch_get,
1948 tdm_tx_ch_put),
1949 SOC_ENUM_EXT("SEC_TDM_RX_0 SampleRate", tdm_rx_sample_rate,
1950 tdm_rx_sample_rate_get,
1951 tdm_rx_sample_rate_put),
1952 SOC_ENUM_EXT("SEC_TDM_TX_0 SampleRate", tdm_tx_sample_rate,
1953 tdm_tx_sample_rate_get,
1954 tdm_tx_sample_rate_put),
1955 SOC_ENUM_EXT("SEC_TDM_RX_0 Format", tdm_rx_format,
1956 tdm_rx_format_get,
1957 tdm_rx_format_put),
1958 SOC_ENUM_EXT("SEC_TDM_TX_0 Format", tdm_tx_format,
1959 tdm_tx_format_get,
1960 tdm_tx_format_put),
1961 SOC_ENUM_EXT("SEC_TDM_RX_0 Channels", tdm_rx_chs,
1962 tdm_rx_ch_get,
1963 tdm_rx_ch_put),
1964 SOC_ENUM_EXT("SEC_TDM_TX_0 Channels", tdm_tx_chs,
1965 tdm_tx_ch_get,
1966 tdm_tx_ch_put),
1967 SOC_ENUM_EXT("TERT_TDM_RX_0 SampleRate", tdm_rx_sample_rate,
1968 tdm_rx_sample_rate_get,
1969 tdm_rx_sample_rate_put),
1970 SOC_ENUM_EXT("TERT_TDM_TX_0 SampleRate", tdm_tx_sample_rate,
1971 tdm_tx_sample_rate_get,
1972 tdm_tx_sample_rate_put),
1973 SOC_ENUM_EXT("TERT_TDM_RX_0 Format", tdm_rx_format,
1974 tdm_rx_format_get,
1975 tdm_rx_format_put),
1976 SOC_ENUM_EXT("TERT_TDM_TX_0 Format", tdm_tx_format,
1977 tdm_tx_format_get,
1978 tdm_tx_format_put),
1979 SOC_ENUM_EXT("TERT_TDM_RX_0 Channels", tdm_rx_chs,
1980 tdm_rx_ch_get,
1981 tdm_rx_ch_put),
1982 SOC_ENUM_EXT("TERT_TDM_TX_0 Channels", tdm_tx_chs,
1983 tdm_tx_ch_get,
1984 tdm_tx_ch_put),
1985 SOC_ENUM_EXT("QUAT_TDM_RX_0 SampleRate", tdm_rx_sample_rate,
1986 tdm_rx_sample_rate_get,
1987 tdm_rx_sample_rate_put),
1988 SOC_ENUM_EXT("QUAT_TDM_TX_0 SampleRate", tdm_tx_sample_rate,
1989 tdm_tx_sample_rate_get,
1990 tdm_tx_sample_rate_put),
1991 SOC_ENUM_EXT("QUAT_TDM_RX_0 Format", tdm_rx_format,
1992 tdm_rx_format_get,
1993 tdm_rx_format_put),
1994 SOC_ENUM_EXT("QUAT_TDM_TX_0 Format", tdm_tx_format,
1995 tdm_tx_format_get,
1996 tdm_tx_format_put),
1997 SOC_ENUM_EXT("QUAT_TDM_RX_0 Channels", tdm_rx_chs,
1998 tdm_rx_ch_get,
1999 tdm_rx_ch_put),
2000 SOC_ENUM_EXT("QUAT_TDM_TX_0 Channels", tdm_tx_chs,
2001 tdm_tx_ch_get,
2002 tdm_tx_ch_put),
2003};
2004
Laxminath Kasam35a610e2016-12-30 15:02:33 +05302005/**
2006 * msm_common_snd_controls_size - to return controls size
2007 *
2008 * Return: returns size of common controls array
2009 */
2010int msm_common_snd_controls_size(void)
2011{
2012 return ARRAY_SIZE(msm_common_snd_controls);
2013}
2014EXPORT_SYMBOL(msm_common_snd_controls_size);
2015
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002016static inline int param_is_mask(int p)
2017{
2018 return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) &&
2019 (p <= SNDRV_PCM_HW_PARAM_LAST_MASK);
2020}
2021
2022static inline struct snd_mask *param_to_mask(struct snd_pcm_hw_params *p,
2023 int n)
2024{
2025 return &(p->masks[n - SNDRV_PCM_HW_PARAM_FIRST_MASK]);
2026}
2027
2028static void param_set_mask(struct snd_pcm_hw_params *p, int n, unsigned int bit)
2029{
2030 if (bit >= SNDRV_MASK_MAX)
2031 return;
2032 if (param_is_mask(n)) {
2033 struct snd_mask *m = param_to_mask(p, n);
2034
2035 m->bits[0] = 0;
2036 m->bits[1] = 0;
2037 m->bits[bit >> 5] |= (1 << (bit & 31));
2038 }
2039}
2040
Rohit Kumar0bd27132016-12-06 14:48:58 +05302041static int msm_ext_disp_get_idx_from_beid(int32_t be_id)
2042{
2043 int idx;
2044
2045 switch (be_id) {
2046 case MSM_BACKEND_DAI_DISPLAY_PORT_RX:
2047 idx = DP_RX_IDX;
2048 break;
2049 default:
2050 pr_err("%s: Incorrect ext_disp be_id %d\n", __func__, be_id);
2051 idx = -EINVAL;
2052 break;
2053 }
2054
2055 return idx;
2056}
2057
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002058/**
2059 * msm_common_be_hw_params_fixup - updates settings of ALSA BE hw params.
2060 *
2061 * @rtd: runtime dailink instance
2062 * @params: HW params of associated backend dailink.
2063 *
2064 * Returns 0.
2065 */
2066int msm_common_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
2067 struct snd_pcm_hw_params *params)
2068{
2069 struct snd_soc_dai_link *dai_link = rtd->dai_link;
2070 struct snd_interval *rate = hw_param_interval(params,
2071 SNDRV_PCM_HW_PARAM_RATE);
2072 struct snd_interval *channels = hw_param_interval(params,
2073 SNDRV_PCM_HW_PARAM_CHANNELS);
2074 int rc = 0;
Rohit Kumar0bd27132016-12-06 14:48:58 +05302075 int idx;
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002076
2077 pr_debug("%s: format = %d, rate = %d\n",
2078 __func__, params_format(params), params_rate(params));
2079
2080 switch (dai_link->be_id) {
2081 case MSM_BACKEND_DAI_USB_RX:
2082 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2083 usb_rx_cfg.bit_format);
2084 rate->min = rate->max = usb_rx_cfg.sample_rate;
2085 channels->min = channels->max = usb_rx_cfg.channels;
2086 break;
2087
2088 case MSM_BACKEND_DAI_USB_TX:
2089 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2090 usb_tx_cfg.bit_format);
2091 rate->min = rate->max = usb_tx_cfg.sample_rate;
2092 channels->min = channels->max = usb_tx_cfg.channels;
2093 break;
2094
Rohit Kumar0bd27132016-12-06 14:48:58 +05302095 case MSM_BACKEND_DAI_DISPLAY_PORT_RX:
2096 idx = msm_ext_disp_get_idx_from_beid(dai_link->be_id);
2097 if (IS_ERR_VALUE(idx)) {
2098 pr_err("%s: Incorrect ext disp idx %d\n",
2099 __func__, idx);
2100 rc = idx;
2101 break;
2102 }
2103
2104 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2105 ext_disp_rx_cfg[idx].bit_format);
2106 rate->min = rate->max = ext_disp_rx_cfg[idx].sample_rate;
2107 channels->min = channels->max = ext_disp_rx_cfg[idx].channels;
2108 break;
2109
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002110 case MSM_BACKEND_DAI_AFE_PCM_RX:
2111 channels->min = channels->max = proxy_rx_cfg.channels;
2112 rate->min = rate->max = SAMPLING_RATE_48KHZ;
2113 break;
2114
2115 case MSM_BACKEND_DAI_PRI_TDM_RX_0:
2116 channels->min = channels->max =
2117 tdm_rx_cfg[TDM_PRI][TDM_0].channels;
2118 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2119 tdm_rx_cfg[TDM_PRI][TDM_0].bit_format);
2120 rate->min = rate->max = tdm_rx_cfg[TDM_PRI][TDM_0].sample_rate;
2121 break;
2122
2123 case MSM_BACKEND_DAI_PRI_TDM_TX_0:
2124 channels->min = channels->max =
2125 tdm_tx_cfg[TDM_PRI][TDM_0].channels;
2126 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2127 tdm_tx_cfg[TDM_PRI][TDM_0].bit_format);
2128 rate->min = rate->max = tdm_tx_cfg[TDM_PRI][TDM_0].sample_rate;
2129 break;
2130
2131 case MSM_BACKEND_DAI_SEC_TDM_RX_0:
2132 channels->min = channels->max =
2133 tdm_rx_cfg[TDM_SEC][TDM_0].channels;
2134 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2135 tdm_rx_cfg[TDM_SEC][TDM_0].bit_format);
2136 rate->min = rate->max = tdm_rx_cfg[TDM_SEC][TDM_0].sample_rate;
2137 break;
2138
2139 case MSM_BACKEND_DAI_SEC_TDM_TX_0:
2140 channels->min = channels->max =
2141 tdm_tx_cfg[TDM_SEC][TDM_0].channels;
2142 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2143 tdm_tx_cfg[TDM_SEC][TDM_0].bit_format);
2144 rate->min = rate->max = tdm_tx_cfg[TDM_SEC][TDM_0].sample_rate;
2145 break;
2146
2147 case MSM_BACKEND_DAI_TERT_TDM_RX_0:
2148 channels->min = channels->max =
2149 tdm_rx_cfg[TDM_TERT][TDM_0].channels;
2150 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2151 tdm_rx_cfg[TDM_TERT][TDM_0].bit_format);
2152 rate->min = rate->max = tdm_rx_cfg[TDM_TERT][TDM_0].sample_rate;
2153 break;
2154
2155 case MSM_BACKEND_DAI_TERT_TDM_TX_0:
2156 channels->min = channels->max =
2157 tdm_tx_cfg[TDM_TERT][TDM_0].channels;
2158 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2159 tdm_tx_cfg[TDM_TERT][TDM_0].bit_format);
2160 rate->min = rate->max = tdm_tx_cfg[TDM_TERT][TDM_0].sample_rate;
2161 break;
2162
2163 case MSM_BACKEND_DAI_QUAT_TDM_RX_0:
2164 channels->min = channels->max =
2165 tdm_rx_cfg[TDM_QUAT][TDM_0].channels;
2166 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2167 tdm_rx_cfg[TDM_QUAT][TDM_0].bit_format);
2168 rate->min = rate->max = tdm_rx_cfg[TDM_QUAT][TDM_0].sample_rate;
2169 break;
2170
2171 case MSM_BACKEND_DAI_QUAT_TDM_TX_0:
2172 channels->min = channels->max =
2173 tdm_tx_cfg[TDM_QUAT][TDM_0].channels;
2174 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2175 tdm_tx_cfg[TDM_QUAT][TDM_0].bit_format);
2176 rate->min = rate->max = tdm_tx_cfg[TDM_QUAT][TDM_0].sample_rate;
2177 break;
2178
2179 case MSM_BACKEND_DAI_AUXPCM_RX:
2180 rate->min = rate->max =
2181 aux_pcm_rx_cfg[PRIM_AUX_PCM].sample_rate;
2182 channels->min = channels->max =
2183 aux_pcm_rx_cfg[PRIM_AUX_PCM].channels;
2184 break;
2185
2186 case MSM_BACKEND_DAI_AUXPCM_TX:
2187 rate->min = rate->max =
2188 aux_pcm_tx_cfg[PRIM_AUX_PCM].sample_rate;
2189 channels->min = channels->max =
2190 aux_pcm_tx_cfg[PRIM_AUX_PCM].channels;
2191 break;
2192
2193 case MSM_BACKEND_DAI_SEC_AUXPCM_RX:
2194 rate->min = rate->max =
2195 aux_pcm_rx_cfg[SEC_AUX_PCM].sample_rate;
2196 channels->min = channels->max =
2197 aux_pcm_rx_cfg[SEC_AUX_PCM].channels;
2198 break;
2199
2200 case MSM_BACKEND_DAI_SEC_AUXPCM_TX:
2201 rate->min = rate->max =
2202 aux_pcm_tx_cfg[SEC_AUX_PCM].sample_rate;
2203 channels->min = channels->max =
2204 aux_pcm_tx_cfg[SEC_AUX_PCM].channels;
2205 break;
2206
2207 case MSM_BACKEND_DAI_TERT_AUXPCM_RX:
2208 rate->min = rate->max =
2209 aux_pcm_rx_cfg[TERT_AUX_PCM].sample_rate;
2210 channels->min = channels->max =
2211 aux_pcm_rx_cfg[TERT_AUX_PCM].channels;
2212 break;
2213
2214 case MSM_BACKEND_DAI_TERT_AUXPCM_TX:
2215 rate->min = rate->max =
2216 aux_pcm_tx_cfg[TERT_AUX_PCM].sample_rate;
2217 channels->min = channels->max =
2218 aux_pcm_tx_cfg[TERT_AUX_PCM].channels;
2219 break;
2220
2221 case MSM_BACKEND_DAI_QUAT_AUXPCM_RX:
2222 rate->min = rate->max =
2223 aux_pcm_rx_cfg[QUAT_AUX_PCM].sample_rate;
2224 channels->min = channels->max =
2225 aux_pcm_rx_cfg[QUAT_AUX_PCM].channels;
2226 break;
2227
2228 case MSM_BACKEND_DAI_QUAT_AUXPCM_TX:
2229 rate->min = rate->max =
2230 aux_pcm_tx_cfg[QUAT_AUX_PCM].sample_rate;
2231 channels->min = channels->max =
2232 aux_pcm_tx_cfg[QUAT_AUX_PCM].channels;
2233 break;
2234
2235 case MSM_BACKEND_DAI_PRI_MI2S_RX:
2236 rate->min = rate->max = mi2s_rx_cfg[PRIM_MI2S].sample_rate;
2237 channels->min = channels->max =
2238 mi2s_rx_cfg[PRIM_MI2S].channels;
Tanya Dixitc8ecc2e2017-02-17 17:57:44 +05302239 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2240 mi2s_rx_cfg[PRIM_MI2S].bit_format);
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002241 break;
2242
2243 case MSM_BACKEND_DAI_PRI_MI2S_TX:
2244 rate->min = rate->max = mi2s_tx_cfg[PRIM_MI2S].sample_rate;
2245 channels->min = channels->max =
2246 mi2s_tx_cfg[PRIM_MI2S].channels;
Tanya Dixitc8ecc2e2017-02-17 17:57:44 +05302247 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2248 mi2s_tx_cfg[PRIM_MI2S].bit_format);
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002249 break;
2250
2251 case MSM_BACKEND_DAI_SECONDARY_MI2S_RX:
2252 rate->min = rate->max = mi2s_rx_cfg[SEC_MI2S].sample_rate;
2253 channels->min = channels->max =
2254 mi2s_rx_cfg[SEC_MI2S].channels;
Tanya Dixitc8ecc2e2017-02-17 17:57:44 +05302255 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2256 mi2s_rx_cfg[SEC_MI2S].bit_format);
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002257 break;
2258
2259 case MSM_BACKEND_DAI_SECONDARY_MI2S_TX:
2260 rate->min = rate->max = mi2s_tx_cfg[SEC_MI2S].sample_rate;
2261 channels->min = channels->max =
2262 mi2s_tx_cfg[SEC_MI2S].channels;
Tanya Dixitc8ecc2e2017-02-17 17:57:44 +05302263 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2264 mi2s_tx_cfg[SEC_MI2S].bit_format);
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002265 break;
2266
2267 case MSM_BACKEND_DAI_TERTIARY_MI2S_RX:
2268 rate->min = rate->max = mi2s_rx_cfg[TERT_MI2S].sample_rate;
2269 channels->min = channels->max =
2270 mi2s_rx_cfg[TERT_MI2S].channels;
Tanya Dixitc8ecc2e2017-02-17 17:57:44 +05302271 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2272 mi2s_rx_cfg[TERT_MI2S].bit_format);
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002273 break;
2274
2275 case MSM_BACKEND_DAI_TERTIARY_MI2S_TX:
2276 rate->min = rate->max = mi2s_tx_cfg[TERT_MI2S].sample_rate;
2277 channels->min = channels->max =
2278 mi2s_tx_cfg[TERT_MI2S].channels;
Tanya Dixitc8ecc2e2017-02-17 17:57:44 +05302279 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2280 mi2s_tx_cfg[TERT_MI2S].bit_format);
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002281 break;
2282
2283 case MSM_BACKEND_DAI_QUATERNARY_MI2S_RX:
2284 rate->min = rate->max = mi2s_rx_cfg[QUAT_MI2S].sample_rate;
2285 channels->min = channels->max =
2286 mi2s_rx_cfg[QUAT_MI2S].channels;
Tanya Dixitc8ecc2e2017-02-17 17:57:44 +05302287 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2288 mi2s_rx_cfg[QUAT_MI2S].bit_format);
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002289 break;
2290
2291 case MSM_BACKEND_DAI_QUATERNARY_MI2S_TX:
2292 rate->min = rate->max = mi2s_tx_cfg[QUAT_MI2S].sample_rate;
2293 channels->min = channels->max =
2294 mi2s_tx_cfg[QUAT_MI2S].channels;
Tanya Dixitc8ecc2e2017-02-17 17:57:44 +05302295 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2296 mi2s_tx_cfg[QUAT_MI2S].bit_format);
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002297 break;
2298
2299 default:
2300 rate->min = rate->max = SAMPLING_RATE_48KHZ;
2301 break;
2302 }
2303 return rc;
2304}
2305EXPORT_SYMBOL(msm_common_be_hw_params_fixup);
2306
2307/**
2308 * msm_aux_pcm_snd_startup - startup ops of auxpcm.
2309 *
2310 * @substream: PCM stream pointer of associated backend dailink
2311 *
2312 * Returns 0 on success or -EINVAL on error.
2313 */
2314int msm_aux_pcm_snd_startup(struct snd_pcm_substream *substream)
2315{
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002316 struct snd_soc_pcm_runtime *rtd = substream->private_data;
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002317
2318 dev_dbg(rtd->card->dev,
2319 "%s: substream = %s stream = %d, dai name %s, dai ID %d\n",
2320 __func__, substream->name, substream->stream,
Laxminath Kasamaad2d182017-01-27 23:01:22 +05302321 rtd->cpu_dai->name, rtd->cpu_dai->id);
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002322
Laxminath Kasamaad2d182017-01-27 23:01:22 +05302323 return 0;
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002324}
2325EXPORT_SYMBOL(msm_aux_pcm_snd_startup);
2326
2327/**
2328 * msm_aux_pcm_snd_shutdown - shutdown ops of auxpcm.
2329 *
2330 * @substream: PCM stream pointer of associated backend dailink
2331 */
2332void msm_aux_pcm_snd_shutdown(struct snd_pcm_substream *substream)
2333{
2334 struct snd_soc_pcm_runtime *rtd = substream->private_data;
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002335
2336 dev_dbg(rtd->card->dev,
2337 "%s: substream = %s stream = %d, dai name %s, dai ID %d\n",
2338 __func__,
2339 substream->name, substream->stream,
2340 rtd->cpu_dai->name, rtd->cpu_dai->id);
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002341}
2342EXPORT_SYMBOL(msm_aux_pcm_snd_shutdown);
2343
2344static int msm_get_port_id(int be_id)
2345{
2346 int afe_port_id;
2347
2348 switch (be_id) {
2349 case MSM_BACKEND_DAI_PRI_MI2S_RX:
2350 afe_port_id = AFE_PORT_ID_PRIMARY_MI2S_RX;
2351 break;
2352 case MSM_BACKEND_DAI_PRI_MI2S_TX:
2353 afe_port_id = AFE_PORT_ID_PRIMARY_MI2S_TX;
2354 break;
2355 case MSM_BACKEND_DAI_SECONDARY_MI2S_RX:
2356 afe_port_id = AFE_PORT_ID_SECONDARY_MI2S_RX;
2357 break;
2358 case MSM_BACKEND_DAI_SECONDARY_MI2S_TX:
2359 afe_port_id = AFE_PORT_ID_SECONDARY_MI2S_TX;
2360 break;
2361 case MSM_BACKEND_DAI_TERTIARY_MI2S_RX:
2362 afe_port_id = AFE_PORT_ID_TERTIARY_MI2S_RX;
2363 break;
2364 case MSM_BACKEND_DAI_TERTIARY_MI2S_TX:
2365 afe_port_id = AFE_PORT_ID_TERTIARY_MI2S_TX;
2366 break;
2367 case MSM_BACKEND_DAI_QUATERNARY_MI2S_RX:
2368 afe_port_id = AFE_PORT_ID_QUATERNARY_MI2S_RX;
2369 break;
2370 case MSM_BACKEND_DAI_QUATERNARY_MI2S_TX:
2371 afe_port_id = AFE_PORT_ID_QUATERNARY_MI2S_TX;
2372 break;
2373 default:
2374 pr_err("%s: Invalid be_id: %d\n", __func__, be_id);
2375 afe_port_id = -EINVAL;
2376 }
2377
2378 return afe_port_id;
2379}
2380
2381static u32 get_mi2s_bits_per_sample(u32 bit_format)
2382{
2383 u32 bit_per_sample;
2384
2385 switch (bit_format) {
Tanya Dixitc8ecc2e2017-02-17 17:57:44 +05302386 case SNDRV_PCM_FORMAT_S32_LE:
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002387 case SNDRV_PCM_FORMAT_S24_3LE:
2388 case SNDRV_PCM_FORMAT_S24_LE:
2389 bit_per_sample = 32;
2390 break;
2391 case SNDRV_PCM_FORMAT_S16_LE:
2392 default:
2393 bit_per_sample = 16;
2394 break;
2395 }
2396
2397 return bit_per_sample;
2398}
2399
2400static void update_mi2s_clk_val(int dai_id, int stream)
2401{
2402 u32 bit_per_sample;
2403
2404 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
2405 bit_per_sample =
2406 get_mi2s_bits_per_sample(mi2s_rx_cfg[dai_id].bit_format);
2407 mi2s_clk[dai_id].clk_freq_in_hz =
2408 mi2s_rx_cfg[dai_id].sample_rate * 2 * bit_per_sample;
2409 } else {
2410 bit_per_sample =
2411 get_mi2s_bits_per_sample(mi2s_tx_cfg[dai_id].bit_format);
2412 mi2s_clk[dai_id].clk_freq_in_hz =
2413 mi2s_tx_cfg[dai_id].sample_rate * 2 * bit_per_sample;
2414 }
2415
2416 if (!mi2s_intf_conf[dai_id].msm_is_mi2s_master)
2417 mi2s_clk[dai_id].clk_freq_in_hz = 0;
2418}
2419
2420static int msm_mi2s_set_sclk(struct snd_pcm_substream *substream, bool enable)
2421{
2422 int ret = 0;
2423 struct snd_soc_pcm_runtime *rtd = substream->private_data;
2424 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
2425 int port_id = 0;
2426 int index = cpu_dai->id;
2427
2428 port_id = msm_get_port_id(rtd->dai_link->be_id);
Xiaoyu Ye1a2d8bd92017-01-31 18:54:15 -08002429 if (port_id < 0) {
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002430 dev_err(rtd->card->dev, "%s: Invalid port_id\n", __func__);
2431 ret = port_id;
2432 goto done;
2433 }
2434
2435 if (enable) {
2436 update_mi2s_clk_val(index, substream->stream);
2437 dev_dbg(rtd->card->dev, "%s: clock rate %ul\n", __func__,
2438 mi2s_clk[index].clk_freq_in_hz);
2439 }
2440
2441 mi2s_clk[index].enable = enable;
2442 ret = afe_set_lpass_clock_v2(port_id,
2443 &mi2s_clk[index]);
2444 if (ret < 0) {
2445 dev_err(rtd->card->dev,
2446 "%s: afe lpass clock failed for port 0x%x , err:%d\n",
2447 __func__, port_id, ret);
2448 goto done;
2449 }
2450
2451done:
2452 return ret;
2453}
2454
2455/**
2456 * msm_mi2s_snd_startup - startup ops of mi2s.
2457 *
2458 * @substream: PCM stream pointer of associated backend dailink
2459 *
2460 * Returns 0 on success or -EINVAL on error.
2461 */
2462int msm_mi2s_snd_startup(struct snd_pcm_substream *substream)
2463{
2464 int ret = 0;
2465 struct snd_soc_pcm_runtime *rtd = substream->private_data;
2466 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
Tanya Dixit73a3a262016-12-08 22:25:56 +05302467 int port_id = msm_get_port_id(rtd->dai_link->be_id);
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002468 int index = cpu_dai->id;
2469 unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS;
2470
2471 dev_dbg(rtd->card->dev,
2472 "%s: substream = %s stream = %d, dai name %s, dai ID %d\n",
2473 __func__, substream->name, substream->stream,
2474 cpu_dai->name, cpu_dai->id);
2475
2476 if (index < PRIM_MI2S || index > QUAT_MI2S) {
2477 ret = -EINVAL;
2478 dev_err(rtd->card->dev,
2479 "%s: CPU DAI id (%d) out of range\n",
2480 __func__, cpu_dai->id);
2481 goto done;
2482 }
2483 /*
2484 * Muxtex protection in case the same MI2S
2485 * interface using for both TX and RX so
2486 * that the same clock won't be enable twice.
2487 */
2488 mutex_lock(&mi2s_intf_conf[index].lock);
2489 if (++mi2s_intf_conf[index].ref_cnt == 1) {
Tanya Dixit73a3a262016-12-08 22:25:56 +05302490 /* Check if msm needs to provide the clock to the interface */
2491 if (!mi2s_intf_conf[index].msm_is_mi2s_master) {
2492 mi2s_clk[index].clk_id = mi2s_ebit_clk[index];
2493 fmt = SND_SOC_DAIFMT_CBM_CFM;
2494 }
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002495 ret = msm_mi2s_set_sclk(substream, true);
Xiaoyu Ye1a2d8bd92017-01-31 18:54:15 -08002496 if (ret < 0) {
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002497 dev_err(rtd->card->dev,
2498 "%s: afe lpass clock failed to enable MI2S clock, err:%d\n",
2499 __func__, ret);
2500 goto clean_up;
2501 }
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002502 ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
Xiaoyu Ye1a2d8bd92017-01-31 18:54:15 -08002503 if (ret < 0) {
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002504 dev_err(rtd->card->dev,
2505 "%s: set fmt cpu dai failed for MI2S (%d), err:%d\n",
2506 __func__, index, ret);
2507 goto clk_off;
2508 }
Tanya Dixit73a3a262016-12-08 22:25:56 +05302509 if (mi2s_intf_conf[index].msm_is_ext_mclk) {
2510 mi2s_mclk[index].enable = 1;
2511 pr_debug("%s: Enabling mclk, clk_freq_in_hz = %u\n",
2512 __func__, mi2s_mclk[index].clk_freq_in_hz);
2513 ret = afe_set_lpass_clock_v2(port_id,
2514 &mi2s_mclk[index]);
2515 if (ret < 0) {
2516 pr_err("%s: afe lpass mclk failed, err:%d\n",
2517 __func__, ret);
2518 goto clk_off;
2519 }
2520 }
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002521 }
Tanya Dixit73a3a262016-12-08 22:25:56 +05302522 mutex_unlock(&mi2s_intf_conf[index].lock);
2523 return 0;
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002524clk_off:
Xiaoyu Ye1a2d8bd92017-01-31 18:54:15 -08002525 if (ret < 0)
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002526 msm_mi2s_set_sclk(substream, false);
2527clean_up:
Xiaoyu Ye1a2d8bd92017-01-31 18:54:15 -08002528 if (ret < 0)
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002529 mi2s_intf_conf[index].ref_cnt--;
2530 mutex_unlock(&mi2s_intf_conf[index].lock);
2531done:
2532 return ret;
2533}
2534EXPORT_SYMBOL(msm_mi2s_snd_startup);
2535
2536/**
2537 * msm_mi2s_snd_shutdown - shutdown ops of mi2s.
2538 *
2539 * @substream: PCM stream pointer of associated backend dailink
2540 */
2541void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream)
2542{
2543 int ret;
2544 struct snd_soc_pcm_runtime *rtd = substream->private_data;
Tanya Dixit73a3a262016-12-08 22:25:56 +05302545 int port_id = msm_get_port_id(rtd->dai_link->be_id);
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002546 int index = rtd->cpu_dai->id;
2547
2548 pr_debug("%s(): substream = %s stream = %d\n", __func__,
2549 substream->name, substream->stream);
2550 if (index < PRIM_MI2S || index > QUAT_MI2S) {
2551 pr_err("%s:invalid MI2S DAI(%d)\n", __func__, index);
2552 return;
2553 }
2554
2555 mutex_lock(&mi2s_intf_conf[index].lock);
2556 if (--mi2s_intf_conf[index].ref_cnt == 0) {
2557 ret = msm_mi2s_set_sclk(substream, false);
2558 if (ret < 0) {
2559 pr_err("%s:clock disable failed for MI2S (%d); ret=%d\n",
2560 __func__, index, ret);
2561 mi2s_intf_conf[index].ref_cnt++;
2562 }
Tanya Dixit73a3a262016-12-08 22:25:56 +05302563 if (mi2s_intf_conf[index].msm_is_ext_mclk) {
2564 mi2s_mclk[index].enable = 0;
2565 pr_debug("%s: Disabling mclk, clk_freq_in_hz = %u\n",
2566 __func__, mi2s_mclk[index].clk_freq_in_hz);
2567 ret = afe_set_lpass_clock_v2(port_id,
2568 &mi2s_mclk[index]);
2569 if (ret < 0) {
2570 pr_err("%s: mclk disable failed for MCLK (%d); ret=%d\n",
2571 __func__, index, ret);
2572 }
2573 }
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002574 }
2575 mutex_unlock(&mi2s_intf_conf[index].lock);
2576}
2577EXPORT_SYMBOL(msm_mi2s_snd_shutdown);
2578
2579/* Validate whether US EU switch is present or not */
2580static int msm_prepare_us_euro(struct snd_soc_card *card)
2581{
2582 struct msm_asoc_mach_data *pdata =
2583 snd_soc_card_get_drvdata(card);
2584 int ret = 0;
2585
2586 if (pdata->us_euro_gpio >= 0) {
2587 dev_dbg(card->dev, "%s: us_euro gpio request %d", __func__,
2588 pdata->us_euro_gpio);
2589 ret = gpio_request(pdata->us_euro_gpio, "TASHA_CODEC_US_EURO");
2590 if (ret) {
2591 dev_err(card->dev,
2592 "%s: Failed to request codec US/EURO gpio %d error %d\n",
2593 __func__, pdata->us_euro_gpio, ret);
2594 }
2595 }
2596
2597 return ret;
2598}
2599
2600static bool msm_swap_gnd_mic(struct snd_soc_codec *codec)
2601{
2602 struct snd_soc_card *card = codec->component.card;
2603 struct msm_asoc_mach_data *pdata =
2604 snd_soc_card_get_drvdata(card);
2605 int value = 0;
2606
2607 if (pdata->us_euro_gpio_p) {
2608 value = msm_cdc_pinctrl_get_state(pdata->us_euro_gpio_p);
2609 if (value)
2610 msm_cdc_pinctrl_select_sleep_state(
2611 pdata->us_euro_gpio_p);
2612 else
2613 msm_cdc_pinctrl_select_active_state(
2614 pdata->us_euro_gpio_p);
2615 } else if (pdata->us_euro_gpio >= 0) {
2616 value = gpio_get_value_cansleep(pdata->us_euro_gpio);
2617 gpio_set_value_cansleep(pdata->us_euro_gpio, !value);
2618 }
2619 pr_debug("%s: swap select switch %d to %d\n", __func__, value, !value);
2620 return true;
2621}
2622
2623static int msm_populate_dai_link_component_of_node(
Laxminath Kasame68e94f2016-12-09 12:08:00 +05302624 struct msm_asoc_mach_data *pdata,
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002625 struct snd_soc_card *card)
2626{
2627 int i, index, ret = 0;
2628 struct device *cdev = card->dev;
2629 struct snd_soc_dai_link *dai_link = card->dai_link;
2630 struct device_node *phandle;
2631
2632 if (!cdev) {
2633 pr_err("%s: Sound card device memory NULL\n", __func__);
2634 return -ENODEV;
2635 }
2636
2637 for (i = 0; i < card->num_links; i++) {
2638 if (dai_link[i].platform_of_node && dai_link[i].cpu_of_node)
2639 continue;
2640
2641 /* populate platform_of_node for snd card dai links */
2642 if (dai_link[i].platform_name &&
2643 !dai_link[i].platform_of_node) {
2644 index = of_property_match_string(cdev->of_node,
2645 "asoc-platform-names",
2646 dai_link[i].platform_name);
2647 if (index < 0) {
2648 pr_err("%s: No match found for platform name: %s\n",
2649 __func__, dai_link[i].platform_name);
2650 ret = index;
2651 goto cpu_dai;
2652 }
2653 phandle = of_parse_phandle(cdev->of_node,
2654 "asoc-platform",
2655 index);
2656 if (!phandle) {
2657 pr_err("%s: retrieving phandle for platform %s, index %d failed\n",
2658 __func__, dai_link[i].platform_name,
2659 index);
2660 ret = -ENODEV;
2661 goto err;
2662 }
2663 dai_link[i].platform_of_node = phandle;
2664 dai_link[i].platform_name = NULL;
2665 }
2666cpu_dai:
2667 /* populate cpu_of_node for snd card dai links */
2668 if (dai_link[i].cpu_dai_name && !dai_link[i].cpu_of_node) {
2669 index = of_property_match_string(cdev->of_node,
2670 "asoc-cpu-names",
2671 dai_link[i].cpu_dai_name);
2672 if (index < 0)
2673 goto codec_dai;
2674 phandle = of_parse_phandle(cdev->of_node, "asoc-cpu",
2675 index);
2676 if (!phandle) {
2677 pr_err("%s: retrieving phandle for cpu dai %s failed\n",
2678 __func__, dai_link[i].cpu_dai_name);
2679 ret = -ENODEV;
2680 goto err;
2681 }
2682 dai_link[i].cpu_of_node = phandle;
2683 dai_link[i].cpu_dai_name = NULL;
2684 }
2685codec_dai:
2686 /* populate codec_of_node for snd card dai links */
2687 if (dai_link[i].codec_name && !dai_link[i].codec_of_node) {
2688 index = of_property_match_string(cdev->of_node,
2689 "asoc-codec-names",
2690 dai_link[i].codec_name);
2691 if (index < 0)
2692 continue;
2693 phandle = of_parse_phandle(cdev->of_node, "asoc-codec",
2694 index);
2695 if (!phandle) {
2696 pr_err("%s: retrieving phandle for codec dai %s failed\n",
2697 __func__, dai_link[i].codec_name);
2698 ret = -ENODEV;
2699 goto err;
2700 }
2701 dai_link[i].codec_of_node = phandle;
2702 dai_link[i].codec_name = NULL;
2703 }
Laxminath Kasamad0f6962016-12-14 20:00:35 +05302704 if (pdata->snd_card_val == INT_SND_CARD) {
Laxminath Kasame68e94f2016-12-09 12:08:00 +05302705 if ((dai_link[i].be_id ==
2706 MSM_BACKEND_DAI_INT0_MI2S_RX) ||
2707 (dai_link[i].be_id ==
2708 MSM_BACKEND_DAI_INT1_MI2S_RX) ||
2709 (dai_link[i].be_id ==
2710 MSM_BACKEND_DAI_INT2_MI2S_TX) ||
2711 (dai_link[i].be_id ==
2712 MSM_BACKEND_DAI_INT3_MI2S_TX)) {
2713 index = of_property_match_string(cdev->of_node,
2714 "asoc-codec-names",
2715 MSM_INT_DIGITAL_CODEC);
2716 phandle = of_parse_phandle(cdev->of_node,
2717 "asoc-codec",
2718 index);
2719 dai_link[i].codecs[DIG_CDC].of_node = phandle;
2720 index = of_property_match_string(cdev->of_node,
2721 "asoc-codec-names",
2722 PMIC_INT_ANALOG_CODEC);
2723 phandle = of_parse_phandle(cdev->of_node,
2724 "asoc-codec",
2725 index);
2726 dai_link[i].codecs[ANA_CDC].of_node = phandle;
2727 }
2728 }
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002729 }
2730err:
2731 return ret;
2732}
2733
2734static int msm_wsa881x_init(struct snd_soc_component *component)
2735{
2736 u8 spkleft_ports[WSA881X_MAX_SWR_PORTS] = {100, 101, 102, 106};
2737 u8 spkright_ports[WSA881X_MAX_SWR_PORTS] = {103, 104, 105, 107};
2738 unsigned int ch_rate[WSA881X_MAX_SWR_PORTS] = {2400, 600, 300, 1200};
2739 unsigned int ch_mask[WSA881X_MAX_SWR_PORTS] = {0x1, 0xF, 0x3, 0x3};
2740 struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
2741 struct msm_asoc_mach_data *pdata;
2742 struct snd_soc_dapm_context *dapm =
2743 snd_soc_codec_get_dapm(codec);
2744
2745 if (!codec) {
2746 pr_err("%s codec is NULL\n", __func__);
2747 return -EINVAL;
2748 }
2749
2750 if (!strcmp(component->name_prefix, "SpkrLeft")) {
2751 dev_dbg(codec->dev, "%s: setting left ch map to codec %s\n",
2752 __func__, codec->component.name);
2753 wsa881x_set_channel_map(codec, &spkleft_ports[0],
2754 WSA881X_MAX_SWR_PORTS, &ch_mask[0],
2755 &ch_rate[0]);
2756 if (dapm->component) {
2757 snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft IN");
2758 snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft SPKR");
2759 }
2760 } else if (!strcmp(component->name_prefix, "SpkrRight")) {
2761 dev_dbg(codec->dev, "%s: setting right ch map to codec %s\n",
2762 __func__, codec->component.name);
2763 wsa881x_set_channel_map(codec, &spkright_ports[0],
2764 WSA881X_MAX_SWR_PORTS, &ch_mask[0],
2765 &ch_rate[0]);
2766 if (dapm->component) {
2767 snd_soc_dapm_ignore_suspend(dapm, "SpkrRight IN");
2768 snd_soc_dapm_ignore_suspend(dapm, "SpkrRight SPKR");
2769 }
2770 } else {
2771 dev_err(codec->dev, "%s: wrong codec name %s\n", __func__,
2772 codec->component.name);
2773 return -EINVAL;
2774 }
2775
2776
2777 pdata = snd_soc_card_get_drvdata(component->card);
2778 if (pdata && pdata->codec_root)
2779 wsa881x_codec_info_create_codec_entry(pdata->codec_root,
2780 codec);
2781 return 0;
2782}
2783
2784
2785static int msm_init_wsa_dev(struct platform_device *pdev,
2786 struct snd_soc_card *card)
2787{
2788 struct device_node *wsa_of_node;
2789 u32 wsa_max_devs;
2790 u32 wsa_dev_cnt;
2791 char *dev_name_str = NULL;
2792 struct msm_wsa881x_dev_info *wsa881x_dev_info;
2793 const char *wsa_auxdev_name_prefix[1];
2794 int found = 0;
2795 int i;
2796 int ret;
2797
2798 /* Get maximum WSA device count for this platform */
2799 ret = of_property_read_u32(pdev->dev.of_node,
2800 "qcom,wsa-max-devs", &wsa_max_devs);
2801 if (ret) {
2802 dev_dbg(&pdev->dev,
2803 "%s: wsa-max-devs property missing in DT %s, ret = %d\n",
2804 __func__, pdev->dev.of_node->full_name, ret);
2805 goto err_dt;
2806 }
2807 if (wsa_max_devs == 0) {
2808 dev_warn(&pdev->dev,
2809 "%s: Max WSA devices is 0 for this target?\n",
2810 __func__);
2811 goto err_dt;
2812 }
2813
2814 /* Get count of WSA device phandles for this platform */
2815 wsa_dev_cnt = of_count_phandle_with_args(pdev->dev.of_node,
2816 "qcom,wsa-devs", NULL);
2817 if (wsa_dev_cnt == -ENOENT) {
2818 dev_warn(&pdev->dev, "%s: No wsa device defined in DT.\n",
2819 __func__);
2820 goto err_dt;
2821 } else if (wsa_dev_cnt <= 0) {
2822 dev_err(&pdev->dev,
2823 "%s: Error reading wsa device from DT. wsa_dev_cnt = %d\n",
2824 __func__, wsa_dev_cnt);
2825 ret = -EINVAL;
2826 goto err_dt;
2827 }
2828
2829 /*
2830 * Expect total phandles count to be NOT less than maximum possible
2831 * WSA count. However, if it is less, then assign same value to
2832 * max count as well.
2833 */
2834 if (wsa_dev_cnt < wsa_max_devs) {
2835 dev_dbg(&pdev->dev,
2836 "%s: wsa_max_devs = %d cannot exceed wsa_dev_cnt = %d\n",
2837 __func__, wsa_max_devs, wsa_dev_cnt);
2838 wsa_max_devs = wsa_dev_cnt;
2839 }
2840
2841 /* Make sure prefix string passed for each WSA device */
2842 ret = of_property_count_strings(pdev->dev.of_node,
2843 "qcom,wsa-aux-dev-prefix");
2844 if (ret != wsa_dev_cnt) {
2845 dev_err(&pdev->dev,
2846 "%s: expecting %d wsa prefix. Defined only %d in DT\n",
2847 __func__, wsa_dev_cnt, ret);
2848 ret = -EINVAL;
2849 goto err_dt;
2850 }
2851
2852 /*
2853 * Alloc mem to store phandle and index info of WSA device, if already
2854 * registered with ALSA core
2855 */
2856 wsa881x_dev_info = devm_kcalloc(&pdev->dev, wsa_max_devs,
2857 sizeof(struct msm_wsa881x_dev_info),
2858 GFP_KERNEL);
2859 if (!wsa881x_dev_info) {
2860 ret = -ENOMEM;
2861 goto err_mem;
2862 }
2863
2864 /*
2865 * search and check whether all WSA devices are already
2866 * registered with ALSA core or not. If found a node, store
2867 * the node and the index in a local array of struct for later
2868 * use.
2869 */
2870 for (i = 0; i < wsa_dev_cnt; i++) {
2871 wsa_of_node = of_parse_phandle(pdev->dev.of_node,
2872 "qcom,wsa-devs", i);
2873 if (unlikely(!wsa_of_node)) {
2874 /* we should not be here */
2875 dev_err(&pdev->dev,
2876 "%s: wsa dev node is not present\n",
2877 __func__);
2878 ret = -EINVAL;
2879 goto err_dev_node;
2880 }
2881 if (soc_find_component(wsa_of_node, NULL)) {
2882 /* WSA device registered with ALSA core */
2883 wsa881x_dev_info[found].of_node = wsa_of_node;
2884 wsa881x_dev_info[found].index = i;
2885 found++;
2886 if (found == wsa_max_devs)
2887 break;
2888 }
2889 }
2890
2891 if (found < wsa_max_devs) {
2892 dev_dbg(&pdev->dev,
2893 "%s: failed to find %d components. Found only %d\n",
2894 __func__, wsa_max_devs, found);
2895 return -EPROBE_DEFER;
2896 }
2897 dev_info(&pdev->dev,
2898 "%s: found %d wsa881x devices registered with ALSA core\n",
2899 __func__, found);
2900
2901 card->num_aux_devs = wsa_max_devs;
2902 card->num_configs = wsa_max_devs;
2903
2904 /* Alloc array of AUX devs struct */
2905 msm_aux_dev = devm_kcalloc(&pdev->dev, card->num_aux_devs,
2906 sizeof(struct snd_soc_aux_dev),
2907 GFP_KERNEL);
2908 if (!msm_aux_dev) {
2909 ret = -ENOMEM;
2910 goto err_auxdev_mem;
2911 }
2912
2913 /* Alloc array of codec conf struct */
2914 msm_codec_conf = devm_kcalloc(&pdev->dev, card->num_aux_devs,
2915 sizeof(struct snd_soc_codec_conf),
2916 GFP_KERNEL);
2917 if (!msm_codec_conf) {
2918 ret = -ENOMEM;
2919 goto err_codec_conf;
2920 }
2921
2922 for (i = 0; i < card->num_aux_devs; i++) {
2923 dev_name_str = devm_kzalloc(&pdev->dev, DEV_NAME_STR_LEN,
2924 GFP_KERNEL);
2925 if (!dev_name_str) {
2926 ret = -ENOMEM;
2927 goto err_dev_str;
2928 }
2929
2930 ret = of_property_read_string_index(pdev->dev.of_node,
2931 "qcom,wsa-aux-dev-prefix",
2932 wsa881x_dev_info[i].index,
2933 wsa_auxdev_name_prefix);
2934 if (ret) {
2935 dev_err(&pdev->dev,
2936 "%s: failed to read wsa aux dev prefix, ret = %d\n",
2937 __func__, ret);
2938 ret = -EINVAL;
2939 goto err_dt_prop;
2940 }
2941
2942 snprintf(dev_name_str, strlen("wsa881x.%d"), "wsa881x.%d", i);
2943 msm_aux_dev[i].name = dev_name_str;
2944 msm_aux_dev[i].codec_name = NULL;
2945 msm_aux_dev[i].codec_of_node =
2946 wsa881x_dev_info[i].of_node;
2947 msm_aux_dev[i].init = msm_wsa881x_init;
2948 msm_codec_conf[i].dev_name = NULL;
2949 msm_codec_conf[i].name_prefix = wsa_auxdev_name_prefix[0];
2950 msm_codec_conf[i].of_node = wsa881x_dev_info[i].of_node;
2951 }
2952 card->codec_conf = msm_codec_conf;
2953 card->aux_dev = msm_aux_dev;
2954
2955 return 0;
2956
2957err_dt_prop:
2958 devm_kfree(&pdev->dev, dev_name_str);
2959err_dev_str:
2960 devm_kfree(&pdev->dev, msm_codec_conf);
2961err_codec_conf:
2962 devm_kfree(&pdev->dev, msm_aux_dev);
2963err_auxdev_mem:
2964err_dev_node:
2965 devm_kfree(&pdev->dev, wsa881x_dev_info);
2966err_mem:
2967err_dt:
2968 return ret;
2969}
2970
2971static void msm_free_auxdev_mem(struct platform_device *pdev)
2972{
2973 struct snd_soc_card *card = platform_get_drvdata(pdev);
2974 int i;
2975
2976 if (card->num_aux_devs > 0) {
2977 for (i = 0; i < card->num_aux_devs; i++) {
2978 kfree(msm_aux_dev[i].codec_name);
2979 kfree(msm_codec_conf[i].dev_name);
2980 kfree(msm_codec_conf[i].name_prefix);
2981 }
2982 }
2983}
2984
2985static void i2s_auxpcm_init(struct platform_device *pdev)
2986{
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002987 int count;
2988 u32 mi2s_master_slave[MI2S_MAX];
Tanya Dixit73a3a262016-12-08 22:25:56 +05302989 u32 mi2s_ext_mclk[MI2S_MAX];
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002990 int ret;
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002991
2992 for (count = 0; count < MI2S_MAX; count++) {
2993 mutex_init(&mi2s_intf_conf[count].lock);
2994 mi2s_intf_conf[count].ref_cnt = 0;
2995 }
2996
Banajit Goswami0530e2f2016-12-09 21:34:37 -08002997 ret = of_property_read_u32_array(pdev->dev.of_node,
Tanya Dixit73a3a262016-12-08 22:25:56 +05302998 "qcom,msm-mi2s-master",
2999 mi2s_master_slave, MI2S_MAX);
Banajit Goswami0530e2f2016-12-09 21:34:37 -08003000 if (ret) {
3001 dev_dbg(&pdev->dev, "%s: no qcom,msm-mi2s-master in DT node\n",
3002 __func__);
3003 } else {
3004 for (count = 0; count < MI2S_MAX; count++) {
3005 mi2s_intf_conf[count].msm_is_mi2s_master =
3006 mi2s_master_slave[count];
3007 }
3008 }
Tanya Dixit73a3a262016-12-08 22:25:56 +05303009
3010 ret = of_property_read_u32_array(pdev->dev.of_node,
3011 "qcom,msm-mi2s-ext-mclk",
3012 mi2s_ext_mclk, MI2S_MAX);
3013 if (ret) {
3014 dev_dbg(&pdev->dev, "%s: no qcom,msm-mi2s-ext-mclk in DT node\n",
3015 __func__);
3016 } else {
3017 for (count = 0; count < MI2S_MAX; count++)
3018 mi2s_intf_conf[count].msm_is_ext_mclk =
3019 mi2s_ext_mclk[count];
3020 }
Banajit Goswami0530e2f2016-12-09 21:34:37 -08003021}
3022
Neeraj Upadhyay49934422016-12-27 19:03:35 +05303023static const struct of_device_id sdm660_asoc_machine_of_match[] = {
3024 { .compatible = "qcom,sdm660-asoc-snd",
Banajit Goswami0530e2f2016-12-09 21:34:37 -08003025 .data = "internal_codec"},
Neeraj Upadhyay49934422016-12-27 19:03:35 +05303026 { .compatible = "qcom,sdm660-asoc-snd-tasha",
Banajit Goswami0530e2f2016-12-09 21:34:37 -08003027 .data = "tasha_codec"},
Neeraj Upadhyay49934422016-12-27 19:03:35 +05303028 { .compatible = "qcom,sdm660-asoc-snd-tavil",
Banajit Goswami0530e2f2016-12-09 21:34:37 -08003029 .data = "tavil_codec"},
3030 {},
3031};
3032
3033static int msm_asoc_machine_probe(struct platform_device *pdev)
3034{
3035 struct snd_soc_card *card = NULL;
3036 struct msm_asoc_mach_data *pdata = NULL;
3037 const char *mclk = "qcom,msm-mclk-freq";
3038 int ret = -EINVAL, id;
3039 const struct of_device_id *match;
3040
3041 pdata = devm_kzalloc(&pdev->dev,
3042 sizeof(struct msm_asoc_mach_data),
3043 GFP_KERNEL);
3044 if (!pdata)
3045 return -ENOMEM;
3046
Neeraj Upadhyay49934422016-12-27 19:03:35 +05303047 match = of_match_node(sdm660_asoc_machine_of_match,
Banajit Goswami0530e2f2016-12-09 21:34:37 -08003048 pdev->dev.of_node);
3049 if (!match)
3050 goto err;
3051
3052 ret = of_property_read_u32(pdev->dev.of_node, mclk, &id);
3053 if (ret) {
3054 dev_err(&pdev->dev,
3055 "%s: missing %s in dt node\n", __func__, mclk);
3056 id = DEFAULT_MCLK_RATE;
3057 }
3058 pdata->mclk_freq = id;
3059
3060 if (!strcmp(match->data, "tasha_codec") ||
3061 !strcmp(match->data, "tavil_codec")) {
3062 if (!strcmp(match->data, "tasha_codec"))
3063 pdata->snd_card_val = EXT_SND_CARD_TASHA;
3064 else
3065 pdata->snd_card_val = EXT_SND_CARD_TAVIL;
3066 ret = msm_ext_cdc_init(pdev, pdata, &card, &mbhc_cfg);
3067 if (ret)
3068 goto err;
3069 } else if (!strcmp(match->data, "internal_codec")) {
3070 pdata->snd_card_val = INT_SND_CARD;
3071 ret = msm_int_cdc_init(pdev, pdata, &card, &mbhc_cfg);
3072 if (ret)
3073 goto err;
3074 } else {
3075 dev_err(&pdev->dev,
3076 "%s: Not a matching DT sound node\n", __func__);
3077 goto err;
3078 }
3079 if (!card)
3080 goto err;
3081
3082 if (pdata->snd_card_val == INT_SND_CARD) {
3083 /*reading the gpio configurations from dtsi file*/
Laxminath Kasamad0f6962016-12-14 20:00:35 +05303084 pdata->pdm_gpio_p = of_parse_phandle(pdev->dev.of_node,
3085 "qcom,cdc-pdm-gpios", 0);
3086 pdata->comp_gpio_p = of_parse_phandle(pdev->dev.of_node,
3087 "qcom,cdc-comp-gpios", 0);
Laxminath Kasamad0f6962016-12-14 20:00:35 +05303088 pdata->dmic_gpio_p = of_parse_phandle(pdev->dev.of_node,
3089 "qcom,cdc-dmic-gpios", 0);
3090 pdata->ext_spk_gpio_p = of_parse_phandle(pdev->dev.of_node,
3091 "qcom,cdc-ext-spk-gpios", 0);
Banajit Goswami0530e2f2016-12-09 21:34:37 -08003092 }
3093
3094 /*
3095 * Parse US-Euro gpio info from DT. Report no error if us-euro
3096 * entry is not found in DT file as some targets do not support
3097 * US-Euro detection
3098 */
3099 pdata->us_euro_gpio = of_get_named_gpio(pdev->dev.of_node,
3100 "qcom,us-euro-gpios", 0);
3101 if (!gpio_is_valid(pdata->us_euro_gpio))
3102 pdata->us_euro_gpio_p = of_parse_phandle(pdev->dev.of_node,
3103 "qcom,us-euro-gpios", 0);
3104 if (!gpio_is_valid(pdata->us_euro_gpio) && (!pdata->us_euro_gpio_p)) {
3105 dev_dbg(&pdev->dev, "property %s not detected in node %s",
3106 "qcom,us-euro-gpios", pdev->dev.of_node->full_name);
3107 } else {
3108 dev_dbg(&pdev->dev, "%s detected",
3109 "qcom,us-euro-gpios");
3110 mbhc_cfg.swap_gnd_mic = msm_swap_gnd_mic;
3111 }
3112
3113 ret = msm_prepare_us_euro(card);
3114 if (ret)
3115 dev_dbg(&pdev->dev, "msm_prepare_us_euro failed (%d)\n",
3116 ret);
3117
3118 i2s_auxpcm_init(pdev);
3119
3120 ret = snd_soc_of_parse_audio_routing(card, "qcom,audio-routing");
3121 if (ret)
3122 goto err;
3123
Laxminath Kasame68e94f2016-12-09 12:08:00 +05303124 ret = msm_populate_dai_link_component_of_node(pdata, card);
Banajit Goswami0530e2f2016-12-09 21:34:37 -08003125 if (ret) {
3126 ret = -EPROBE_DEFER;
3127 goto err;
3128 }
Banajit Goswami0530e2f2016-12-09 21:34:37 -08003129
Laxminath Kasam82f136f2017-01-24 00:52:55 +05303130 if (!of_property_read_bool(pdev->dev.of_node, "qcom,wsa-disable")) {
3131 ret = msm_init_wsa_dev(pdev, card);
3132 if (ret)
3133 goto err;
3134 }
Banajit Goswami0530e2f2016-12-09 21:34:37 -08003135
3136 ret = devm_snd_soc_register_card(&pdev->dev, card);
Laxminath Kasam54dc88a2016-12-22 19:44:52 +05303137 if (ret == -EPROBE_DEFER) {
3138 if (codec_reg_done) {
3139 /*
3140 * return failure as EINVAL since other codec
3141 * registered sound card successfully.
3142 * This avoids any further probe calls.
3143 */
3144 ret = -EINVAL;
3145 }
3146 goto err;
3147 } else if (ret) {
Banajit Goswami0530e2f2016-12-09 21:34:37 -08003148 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
3149 ret);
3150 goto err;
3151 }
Laxminath Kasam54dc88a2016-12-22 19:44:52 +05303152 if (pdata->snd_card_val != INT_SND_CARD)
3153 msm_ext_register_audio_notifier(pdev);
3154
Banajit Goswami0530e2f2016-12-09 21:34:37 -08003155 return 0;
3156err:
3157 if (pdata->us_euro_gpio > 0) {
3158 dev_dbg(&pdev->dev, "%s free us_euro gpio %d\n",
3159 __func__, pdata->us_euro_gpio);
3160 pdata->us_euro_gpio = 0;
3161 }
3162 if (pdata->hph_en1_gpio > 0) {
3163 dev_dbg(&pdev->dev, "%s free hph_en1_gpio %d\n",
3164 __func__, pdata->hph_en1_gpio);
3165 gpio_free(pdata->hph_en1_gpio);
3166 pdata->hph_en1_gpio = 0;
3167 }
3168 if (pdata->hph_en0_gpio > 0) {
3169 dev_dbg(&pdev->dev, "%s free hph_en0_gpio %d\n",
3170 __func__, pdata->hph_en0_gpio);
3171 gpio_free(pdata->hph_en0_gpio);
3172 pdata->hph_en0_gpio = 0;
3173 }
Laxminath Kasamfb36dc12016-11-28 23:04:47 +05303174 if (pdata->snd_card_val != INT_SND_CARD)
Laxminath Kasamc1a8f7c2017-01-23 13:33:31 +05303175 msm_ext_cdc_deinit(pdata);
Laxminath Kasam421cf77c2017-01-30 14:57:13 +05303176 devm_kfree(&pdev->dev, pdata);
Banajit Goswami0530e2f2016-12-09 21:34:37 -08003177 return ret;
3178}
3179
3180static int msm_asoc_machine_remove(struct platform_device *pdev)
3181{
3182 struct snd_soc_card *card = platform_get_drvdata(pdev);
3183 struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
3184
3185 if (pdata->snd_card_val == INT_SND_CARD)
3186 mutex_destroy(&pdata->cdc_int_mclk0_mutex);
Laxminath Kasamfb36dc12016-11-28 23:04:47 +05303187 else
Laxminath Kasamc1a8f7c2017-01-23 13:33:31 +05303188 msm_ext_cdc_deinit(pdata);
Banajit Goswami0530e2f2016-12-09 21:34:37 -08003189 msm_free_auxdev_mem(pdev);
3190
3191 gpio_free(pdata->us_euro_gpio);
3192 gpio_free(pdata->hph_en1_gpio);
3193 gpio_free(pdata->hph_en0_gpio);
Banajit Goswami0530e2f2016-12-09 21:34:37 -08003194 snd_soc_unregister_card(card);
3195 return 0;
3196}
3197
Neeraj Upadhyay49934422016-12-27 19:03:35 +05303198static struct platform_driver sdm660_asoc_machine_driver = {
Banajit Goswami0530e2f2016-12-09 21:34:37 -08003199 .driver = {
3200 .name = DRV_NAME,
3201 .owner = THIS_MODULE,
3202 .pm = &snd_soc_pm_ops,
Neeraj Upadhyay49934422016-12-27 19:03:35 +05303203 .of_match_table = sdm660_asoc_machine_of_match,
Banajit Goswami0530e2f2016-12-09 21:34:37 -08003204 },
3205 .probe = msm_asoc_machine_probe,
3206 .remove = msm_asoc_machine_remove,
3207};
Neeraj Upadhyay49934422016-12-27 19:03:35 +05303208module_platform_driver(sdm660_asoc_machine_driver);
Banajit Goswami0530e2f2016-12-09 21:34:37 -08003209
3210MODULE_DESCRIPTION("ALSA SoC msm");
3211MODULE_LICENSE("GPL v2");
3212MODULE_ALIAS("platform:" DRV_NAME);
Neeraj Upadhyay49934422016-12-27 19:03:35 +05303213MODULE_DEVICE_TABLE(of, sdm660_asoc_machine_of_match);