blob: 44966428730330090461a08db94f15dda3a80bb8 [file] [log] [blame]
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301/* 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>
Asish Bhattacharya84f7f732017-07-25 16:29:27 +053015#include <linux/module.h>
16#include <linux/platform_device.h>
17#include <linux/of_device.h>
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053018#include <sound/pcm_params.h>
Laxminath Kasam605b42f2017-08-01 22:02:15 +053019#include <dsp/q6afe-v2.h>
Meng Wangc444ff72017-10-18 10:52:07 +080020#include <dsp/audio_notifier.h>
Laxminath Kasam605b42f2017-08-01 22:02:15 +053021#include "msm-pcm-routing-v2.h"
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053022#include "sdm660-common.h"
23#include "sdm660-internal.h"
24#include "sdm660-external.h"
Laxminath Kasam605b42f2017-08-01 22:02:15 +053025#include "codecs/msm-cdc-pinctrl.h"
26#include "codecs/sdm660_cdc/msm-analog-cdc.h"
27#include "codecs/wsa881x.h"
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053028
Revathi Uddaraju30feb0d2017-11-21 15:30:19 +053029#define __CHIPSET__ "SDM660 "
30#define MSM_DAILINK_NAME(name) (__CHIPSET__#name)
31
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053032#define DRV_NAME "sdm660-asoc-snd"
33
34#define MSM_INT_DIGITAL_CODEC "msm-dig-codec"
35#define PMIC_INT_ANALOG_CODEC "analog-codec"
36
37#define DEV_NAME_STR_LEN 32
38#define DEFAULT_MCLK_RATE 9600000
Revathi Uddaraju30feb0d2017-11-21 15:30:19 +053039#define MSM_LL_QOS_VALUE 300 /* time in us to ensure LPM doesn't go in C3/C4 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053040
41struct dev_config {
42 u32 sample_rate;
43 u32 bit_format;
44 u32 channels;
45};
46
47enum {
48 DP_RX_IDX,
49 EXT_DISP_RX_IDX_MAX,
50};
51
Laxminath Kasam38070be2017-08-17 18:21:59 +053052bool codec_reg_done;
53
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053054/* TDM default config */
55static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = {
56 { /* PRI 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 { /* SEC 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 { /* TERT 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 { /* QUAT TDM */
87 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */
88 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */
89 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */
90 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */
91 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */
92 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */
93 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */
94 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */
Rohit Kumard1754482017-09-10 22:57:39 +053095 },
96 { /* QUIN TDM */
97 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */
98 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */
99 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */
100 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */
101 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */
102 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */
103 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */
104 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530105 }
106};
107
108/* TDM default config */
109static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = {
110 { /* PRI 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 { /* SEC 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 { /* TERT TDM */
131 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */
132 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */
133 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */
134 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */
135 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */
136 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */
137 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */
138 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */
139 },
140 { /* QUAT TDM */
141 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */
142 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */
143 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */
144 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */
145 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */
146 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */
147 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */
148 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */
Rohit Kumard1754482017-09-10 22:57:39 +0530149 },
150 { /* QUIN TDM */
151 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */
152 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */
153 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */
154 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */
155 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */
156 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */
157 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */
158 {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530159 }
160};
161
162/* Default configuration of external display BE */
163static struct dev_config ext_disp_rx_cfg[] = {
164 [DP_RX_IDX] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
165};
166static struct dev_config usb_rx_cfg = {
167 .sample_rate = SAMPLING_RATE_48KHZ,
168 .bit_format = SNDRV_PCM_FORMAT_S16_LE,
169 .channels = 2,
170};
171
172static struct dev_config usb_tx_cfg = {
173 .sample_rate = SAMPLING_RATE_48KHZ,
174 .bit_format = SNDRV_PCM_FORMAT_S16_LE,
175 .channels = 1,
176};
177
178enum {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530179 PRIM_AUX_PCM = 0,
180 SEC_AUX_PCM,
181 TERT_AUX_PCM,
182 QUAT_AUX_PCM,
Rohit Kumard1754482017-09-10 22:57:39 +0530183 QUIN_AUX_PCM,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530184 AUX_PCM_MAX,
185};
186
187enum {
188 PCM_I2S_SEL_PRIM = 0,
189 PCM_I2S_SEL_SEC,
190 PCM_I2S_SEL_TERT,
191 PCM_I2S_SEL_QUAT,
Rohit Kumard1754482017-09-10 22:57:39 +0530192 PCM_I2S_SEL_QUIN,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530193 PCM_I2S_SEL_MAX,
194};
195
196struct mi2s_conf {
197 struct mutex lock;
198 u32 ref_cnt;
199 u32 msm_is_mi2s_master;
200 u32 msm_is_ext_mclk;
201};
202
203static u32 mi2s_ebit_clk[MI2S_MAX] = {
204 Q6AFE_LPASS_CLK_ID_PRI_MI2S_EBIT,
205 Q6AFE_LPASS_CLK_ID_SEC_MI2S_EBIT,
206 Q6AFE_LPASS_CLK_ID_TER_MI2S_EBIT,
Rohit Kumar804f26b2017-10-02 10:35:21 +0530207 Q6AFE_LPASS_CLK_ID_QUAD_MI2S_EBIT,
208 Q6AFE_LPASS_CLK_ID_QUI_MI2S_EBIT
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530209};
210
211struct msm_wsa881x_dev_info {
212 struct device_node *of_node;
213 u32 index;
214};
215static struct snd_soc_aux_dev *msm_aux_dev;
216static struct snd_soc_codec_conf *msm_codec_conf;
217
Asish Bhattacharya84f7f732017-07-25 16:29:27 +0530218static bool msm_swap_gnd_mic(struct snd_soc_codec *codec, bool active);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530219
220static struct wcd_mbhc_config mbhc_cfg = {
221 .read_fw_bin = false,
222 .calibration = NULL,
223 .detect_extn_cable = true,
224 .mono_stero_detection = false,
225 .swap_gnd_mic = NULL,
226 .hs_ext_micbias = true,
227 .key_code[0] = KEY_MEDIA,
228 .key_code[1] = KEY_VOICECOMMAND,
229 .key_code[2] = KEY_VOLUMEUP,
230 .key_code[3] = KEY_VOLUMEDOWN,
231 .key_code[4] = 0,
232 .key_code[5] = 0,
233 .key_code[6] = 0,
234 .key_code[7] = 0,
235 .linein_th = 5000,
236 .moisture_en = false,
237 .mbhc_micbias = 0,
238 .anc_micbias = 0,
239 .enable_anc_mic_detect = false,
240};
241
242static struct dev_config proxy_rx_cfg = {
243 .sample_rate = SAMPLING_RATE_48KHZ,
244 .bit_format = SNDRV_PCM_FORMAT_S16_LE,
245 .channels = 2,
246};
247
248/* Default configuration of MI2S channels */
249static struct dev_config mi2s_rx_cfg[] = {
250 [PRIM_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
251 [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
252 [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
253 [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
Rohit Kumard1754482017-09-10 22:57:39 +0530254 [QUIN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530255};
256
257static struct dev_config mi2s_tx_cfg[] = {
258 [PRIM_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
259 [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
260 [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
261 [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
Rohit Kumard1754482017-09-10 22:57:39 +0530262 [QUIN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530263};
264
265static struct dev_config aux_pcm_rx_cfg[] = {
266 [PRIM_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
267 [SEC_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
268 [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
269 [QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
Rohit Kumard1754482017-09-10 22:57:39 +0530270 [QUIN_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530271};
272
273static struct dev_config aux_pcm_tx_cfg[] = {
274 [PRIM_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
275 [SEC_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
276 [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
277 [QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
Rohit Kumard1754482017-09-10 22:57:39 +0530278 [QUIN_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530279};
280
281static char const *ch_text[] = {"Two", "Three", "Four", "Five",
282 "Six", "Seven", "Eight"};
283static const char *const auxpcm_rate_text[] = {"KHZ_8", "KHZ_16"};
284static char const *mi2s_rate_text[] = {"KHZ_8", "KHZ_16",
285 "KHZ_32", "KHZ_44P1", "KHZ_48",
286 "KHZ_96", "KHZ_192"};
287static const char *const mi2s_ch_text[] = {"One", "Two", "Three", "Four",
288 "Five", "Six", "Seven",
289 "Eight"};
290static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE",
291 "S32_LE"};
292static char const *mi2s_format_text[] = {"S16_LE", "S24_LE", "S24_3LE",
293 "S32_LE"};
294static char const *tdm_ch_text[] = {"One", "Two", "Three", "Four",
295 "Five", "Six", "Seven", "Eight"};
296static char const *tdm_bit_format_text[] = {"S16_LE", "S24_LE", "S32_LE"};
297static char const *tdm_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_32",
298 "KHZ_44P1", "KHZ_48", "KHZ_96",
299 "KHZ_192", "KHZ_352P8", "KHZ_384"};
300static const char *const usb_ch_text[] = {"One", "Two", "Three", "Four",
301 "Five", "Six", "Seven",
302 "Eight"};
303static char const *usb_sample_rate_text[] = {"KHZ_8", "KHZ_11P025",
304 "KHZ_16", "KHZ_22P05",
305 "KHZ_32", "KHZ_44P1", "KHZ_48",
306 "KHZ_96", "KHZ_192", "KHZ_384"};
307static char const *ext_disp_bit_format_text[] = {"S16_LE", "S24_LE"};
308static char const *ext_disp_sample_rate_text[] = {"KHZ_48", "KHZ_96",
309 "KHZ_192"};
Revathi Uddaraju30feb0d2017-11-21 15:30:19 +0530310static const char *const qos_text[] = {"Disable", "Enable"};
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530311
312static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_chs, ch_text);
313static SOC_ENUM_SINGLE_EXT_DECL(proxy_rx_chs, ch_text);
314static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_rx_sample_rate, auxpcm_rate_text);
315static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_rx_sample_rate, auxpcm_rate_text);
316static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_rx_sample_rate, auxpcm_rate_text);
317static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_rx_sample_rate, auxpcm_rate_text);
Rohit Kumard1754482017-09-10 22:57:39 +0530318static SOC_ENUM_SINGLE_EXT_DECL(quin_aux_pcm_rx_sample_rate, auxpcm_rate_text);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530319static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_tx_sample_rate, auxpcm_rate_text);
320static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_tx_sample_rate, auxpcm_rate_text);
321static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_tx_sample_rate, auxpcm_rate_text);
322static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_tx_sample_rate, auxpcm_rate_text);
Rohit Kumard1754482017-09-10 22:57:39 +0530323static SOC_ENUM_SINGLE_EXT_DECL(quin_aux_pcm_tx_sample_rate, auxpcm_rate_text);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530324static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_sample_rate, mi2s_rate_text);
325static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_sample_rate, mi2s_rate_text);
326static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_sample_rate, mi2s_rate_text);
327static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_sample_rate, mi2s_rate_text);
Rohit Kumard1754482017-09-10 22:57:39 +0530328static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_rx_sample_rate, mi2s_rate_text);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530329static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_sample_rate, mi2s_rate_text);
330static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_sample_rate, mi2s_rate_text);
331static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_sample_rate, mi2s_rate_text);
332static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_sample_rate, mi2s_rate_text);
Rohit Kumard1754482017-09-10 22:57:39 +0530333static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_tx_sample_rate, mi2s_rate_text);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530334static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_format, mi2s_format_text);
335static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_format, mi2s_format_text);
336static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_format, mi2s_format_text);
337static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_format, mi2s_format_text);
Rohit Kumard1754482017-09-10 22:57:39 +0530338static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_rx_format, mi2s_format_text);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530339static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_format, mi2s_format_text);
340static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_format, mi2s_format_text);
341static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_format, mi2s_format_text);
342static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_format, mi2s_format_text);
Rohit Kumard1754482017-09-10 22:57:39 +0530343static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_tx_format, mi2s_format_text);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530344static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_chs, mi2s_ch_text);
345static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_chs, mi2s_ch_text);
346static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_chs, mi2s_ch_text);
347static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_chs, mi2s_ch_text);
348static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_chs, mi2s_ch_text);
349static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_chs, mi2s_ch_text);
350static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_chs, mi2s_ch_text);
351static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_chs, mi2s_ch_text);
Rohit Kumard1754482017-09-10 22:57:39 +0530352static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_rx_chs, mi2s_ch_text);
353static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_tx_chs, mi2s_ch_text);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530354static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_chs, usb_ch_text);
355static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_chs, usb_ch_text);
356static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_format, bit_format_text);
357static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_format, bit_format_text);
358static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_format, ext_disp_bit_format_text);
359static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_sample_rate, usb_sample_rate_text);
360static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_sample_rate, usb_sample_rate_text);
361static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_sample_rate,
362 ext_disp_sample_rate_text);
363static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_chs, tdm_ch_text);
364static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_format, tdm_bit_format_text);
365static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_sample_rate, tdm_sample_rate_text);
366static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_chs, tdm_ch_text);
367static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_format, tdm_bit_format_text);
368static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_sample_rate, tdm_sample_rate_text);
Revathi Uddaraju30feb0d2017-11-21 15:30:19 +0530369static SOC_ENUM_SINGLE_EXT_DECL(qos_vote, qos_text);
370
371static int qos_vote_status;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530372
373static struct afe_clk_set mi2s_clk[MI2S_MAX] = {
374 {
375 AFE_API_VERSION_I2S_CONFIG,
376 Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT,
377 Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ,
378 Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
379 Q6AFE_LPASS_CLK_ROOT_DEFAULT,
380 0,
381 },
382 {
383 AFE_API_VERSION_I2S_CONFIG,
384 Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT,
385 Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ,
386 Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
387 Q6AFE_LPASS_CLK_ROOT_DEFAULT,
388 0,
389 },
390 {
391 AFE_API_VERSION_I2S_CONFIG,
392 Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT,
393 Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ,
394 Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
395 Q6AFE_LPASS_CLK_ROOT_DEFAULT,
396 0,
397 },
398 {
399 AFE_API_VERSION_I2S_CONFIG,
400 Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT,
401 Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ,
402 Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
403 Q6AFE_LPASS_CLK_ROOT_DEFAULT,
404 0,
Rohit Kumar804f26b2017-10-02 10:35:21 +0530405 },
406 {
407 AFE_API_VERSION_I2S_CONFIG,
408 Q6AFE_LPASS_CLK_ID_QUI_MI2S_IBIT,
409 Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ,
410 Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
411 Q6AFE_LPASS_CLK_ROOT_DEFAULT,
412 0,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530413 }
414};
415
416static struct afe_clk_set mi2s_mclk[MI2S_MAX] = {
417 {
418 AFE_API_VERSION_I2S_CONFIG,
419 Q6AFE_LPASS_CLK_ID_MCLK_3,
420 Q6AFE_LPASS_OSR_CLK_9_P600_MHZ,
421 Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
422 Q6AFE_LPASS_CLK_ROOT_DEFAULT,
423 0,
424 },
425 {
426 AFE_API_VERSION_I2S_CONFIG,
Rohit Kumar804f26b2017-10-02 10:35:21 +0530427 Q6AFE_LPASS_CLK_ID_MCLK_2,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530428 Q6AFE_LPASS_OSR_CLK_9_P600_MHZ,
429 Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
430 Q6AFE_LPASS_CLK_ROOT_DEFAULT,
431 0,
432 },
433 {
434 AFE_API_VERSION_I2S_CONFIG,
435 Q6AFE_LPASS_CLK_ID_MCLK_1,
436 Q6AFE_LPASS_OSR_CLK_9_P600_MHZ,
437 Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
438 Q6AFE_LPASS_CLK_ROOT_DEFAULT,
439 0,
440 },
441 {
442 AFE_API_VERSION_I2S_CONFIG,
Rohit Kumar804f26b2017-10-02 10:35:21 +0530443 Q6AFE_LPASS_CLK_ID_MCLK_1,
444 Q6AFE_LPASS_OSR_CLK_9_P600_MHZ,
445 Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
446 Q6AFE_LPASS_CLK_ROOT_DEFAULT,
447 0,
448 },
449 {
450 AFE_API_VERSION_I2S_CONFIG,
451 Q6AFE_LPASS_CLK_ID_QUI_MI2S_OSR,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530452 Q6AFE_LPASS_OSR_CLK_9_P600_MHZ,
453 Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
454 Q6AFE_LPASS_CLK_ROOT_DEFAULT,
455 0,
456 }
457};
458
459static struct mi2s_conf mi2s_intf_conf[MI2S_MAX];
460
461static int proxy_rx_ch_get(struct snd_kcontrol *kcontrol,
462 struct snd_ctl_elem_value *ucontrol)
463{
464 pr_debug("%s: proxy_rx channels = %d\n",
465 __func__, proxy_rx_cfg.channels);
466 ucontrol->value.integer.value[0] = proxy_rx_cfg.channels - 2;
467
468 return 0;
469}
470
471static int proxy_rx_ch_put(struct snd_kcontrol *kcontrol,
472 struct snd_ctl_elem_value *ucontrol)
473{
474 proxy_rx_cfg.channels = ucontrol->value.integer.value[0] + 2;
475 pr_debug("%s: proxy_rx channels = %d\n",
476 __func__, proxy_rx_cfg.channels);
477
478 return 1;
479}
480
481static int tdm_get_sample_rate(int value)
482{
483 int sample_rate = 0;
484
485 switch (value) {
486 case 0:
487 sample_rate = SAMPLING_RATE_8KHZ;
488 break;
489 case 1:
490 sample_rate = SAMPLING_RATE_16KHZ;
491 break;
492 case 2:
493 sample_rate = SAMPLING_RATE_32KHZ;
494 break;
495 case 3:
496 sample_rate = SAMPLING_RATE_44P1KHZ;
497 break;
498 case 4:
499 sample_rate = SAMPLING_RATE_48KHZ;
500 break;
501 case 5:
502 sample_rate = SAMPLING_RATE_96KHZ;
503 break;
504 case 6:
505 sample_rate = SAMPLING_RATE_192KHZ;
506 break;
507 case 7:
508 sample_rate = SAMPLING_RATE_352P8KHZ;
509 break;
510 case 8:
511 sample_rate = SAMPLING_RATE_384KHZ;
512 break;
513 default:
514 sample_rate = SAMPLING_RATE_48KHZ;
515 break;
516 }
517 return sample_rate;
518}
519
520static int tdm_get_sample_rate_val(int sample_rate)
521{
522 int sample_rate_val = 0;
523
524 switch (sample_rate) {
525 case SAMPLING_RATE_8KHZ:
526 sample_rate_val = 0;
527 break;
528 case SAMPLING_RATE_16KHZ:
529 sample_rate_val = 1;
530 break;
531 case SAMPLING_RATE_32KHZ:
532 sample_rate_val = 2;
533 break;
534 case SAMPLING_RATE_44P1KHZ:
535 sample_rate_val = 3;
536 break;
537 case SAMPLING_RATE_48KHZ:
538 sample_rate_val = 4;
539 break;
540 case SAMPLING_RATE_96KHZ:
541 sample_rate_val = 5;
542 break;
543 case SAMPLING_RATE_192KHZ:
544 sample_rate_val = 6;
545 break;
546 case SAMPLING_RATE_352P8KHZ:
547 sample_rate_val = 7;
548 break;
549 case SAMPLING_RATE_384KHZ:
550 sample_rate_val = 8;
551 break;
552 default:
553 sample_rate_val = 4;
554 break;
555 }
556 return sample_rate_val;
557}
558
559static int tdm_get_port_idx(struct snd_kcontrol *kcontrol,
560 struct tdm_port *port)
561{
562 if (port) {
563 if (strnstr(kcontrol->id.name, "PRI",
564 sizeof(kcontrol->id.name))) {
565 port->mode = TDM_PRI;
566 } else if (strnstr(kcontrol->id.name, "SEC",
567 sizeof(kcontrol->id.name))) {
568 port->mode = TDM_SEC;
569 } else if (strnstr(kcontrol->id.name, "TERT",
570 sizeof(kcontrol->id.name))) {
571 port->mode = TDM_TERT;
572 } else if (strnstr(kcontrol->id.name, "QUAT",
573 sizeof(kcontrol->id.name))) {
574 port->mode = TDM_QUAT;
Rohit Kumard1754482017-09-10 22:57:39 +0530575 } else if (strnstr(kcontrol->id.name, "QUIN",
576 sizeof(kcontrol->id.name))) {
577 port->mode = TDM_QUIN;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530578 } else {
579 pr_err("%s: unsupported mode in: %s",
580 __func__, kcontrol->id.name);
581 return -EINVAL;
582 }
583
584 if (strnstr(kcontrol->id.name, "RX_0",
585 sizeof(kcontrol->id.name)) ||
586 strnstr(kcontrol->id.name, "TX_0",
587 sizeof(kcontrol->id.name))) {
588 port->channel = TDM_0;
589 } else if (strnstr(kcontrol->id.name, "RX_1",
590 sizeof(kcontrol->id.name)) ||
591 strnstr(kcontrol->id.name, "TX_1",
592 sizeof(kcontrol->id.name))) {
593 port->channel = TDM_1;
594 } else if (strnstr(kcontrol->id.name, "RX_2",
595 sizeof(kcontrol->id.name)) ||
596 strnstr(kcontrol->id.name, "TX_2",
597 sizeof(kcontrol->id.name))) {
598 port->channel = TDM_2;
599 } else if (strnstr(kcontrol->id.name, "RX_3",
600 sizeof(kcontrol->id.name)) ||
601 strnstr(kcontrol->id.name, "TX_3",
602 sizeof(kcontrol->id.name))) {
603 port->channel = TDM_3;
604 } else if (strnstr(kcontrol->id.name, "RX_4",
605 sizeof(kcontrol->id.name)) ||
606 strnstr(kcontrol->id.name, "TX_4",
607 sizeof(kcontrol->id.name))) {
608 port->channel = TDM_4;
609 } else if (strnstr(kcontrol->id.name, "RX_5",
610 sizeof(kcontrol->id.name)) ||
611 strnstr(kcontrol->id.name, "TX_5",
612 sizeof(kcontrol->id.name))) {
613 port->channel = TDM_5;
614 } else if (strnstr(kcontrol->id.name, "RX_6",
615 sizeof(kcontrol->id.name)) ||
616 strnstr(kcontrol->id.name, "TX_6",
617 sizeof(kcontrol->id.name))) {
618 port->channel = TDM_6;
619 } else if (strnstr(kcontrol->id.name, "RX_7",
620 sizeof(kcontrol->id.name)) ||
621 strnstr(kcontrol->id.name, "TX_7",
622 sizeof(kcontrol->id.name))) {
623 port->channel = TDM_7;
624 } else {
625 pr_err("%s: unsupported channel in: %s",
626 __func__, kcontrol->id.name);
627 return -EINVAL;
628 }
629 } else
630 return -EINVAL;
631 return 0;
632}
633
634static int tdm_rx_sample_rate_get(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 ucontrol->value.enumerated.item[0] = tdm_get_sample_rate_val(
645 tdm_rx_cfg[port.mode][port.channel].sample_rate);
646
647 pr_debug("%s: tdm_rx_sample_rate = %d, item = %d\n", __func__,
648 tdm_rx_cfg[port.mode][port.channel].sample_rate,
649 ucontrol->value.enumerated.item[0]);
650 }
651 return ret;
652}
653
654static int tdm_rx_sample_rate_put(struct snd_kcontrol *kcontrol,
655 struct snd_ctl_elem_value *ucontrol)
656{
657 struct tdm_port port;
658 int ret = tdm_get_port_idx(kcontrol, &port);
659
660 if (ret) {
661 pr_err("%s: unsupported control: %s",
662 __func__, kcontrol->id.name);
663 } else {
664 tdm_rx_cfg[port.mode][port.channel].sample_rate =
665 tdm_get_sample_rate(ucontrol->value.enumerated.item[0]);
666
667 pr_debug("%s: tdm_rx_sample_rate = %d, item = %d\n", __func__,
668 tdm_rx_cfg[port.mode][port.channel].sample_rate,
669 ucontrol->value.enumerated.item[0]);
670 }
671 return ret;
672}
673
674static int tdm_tx_sample_rate_get(struct snd_kcontrol *kcontrol,
675 struct snd_ctl_elem_value *ucontrol)
676{
677 struct tdm_port port;
678 int ret = tdm_get_port_idx(kcontrol, &port);
679
680 if (ret) {
681 pr_err("%s: unsupported control: %s",
682 __func__, kcontrol->id.name);
683 } else {
684 ucontrol->value.enumerated.item[0] = tdm_get_sample_rate_val(
685 tdm_tx_cfg[port.mode][port.channel].sample_rate);
686
687 pr_debug("%s: tdm_tx_sample_rate = %d, item = %d\n", __func__,
688 tdm_tx_cfg[port.mode][port.channel].sample_rate,
689 ucontrol->value.enumerated.item[0]);
690 }
691 return ret;
692}
693
694static int tdm_tx_sample_rate_put(struct snd_kcontrol *kcontrol,
695 struct snd_ctl_elem_value *ucontrol)
696{
697 struct tdm_port port;
698 int ret = tdm_get_port_idx(kcontrol, &port);
699
700 if (ret) {
701 pr_err("%s: unsupported control: %s",
702 __func__, kcontrol->id.name);
703 } else {
704 tdm_tx_cfg[port.mode][port.channel].sample_rate =
705 tdm_get_sample_rate(ucontrol->value.enumerated.item[0]);
706
707 pr_debug("%s: tdm_tx_sample_rate = %d, item = %d\n", __func__,
708 tdm_tx_cfg[port.mode][port.channel].sample_rate,
709 ucontrol->value.enumerated.item[0]);
710 }
711 return ret;
712}
713
714static int tdm_get_format(int value)
715{
716 int format = 0;
717
718 switch (value) {
719 case 0:
720 format = SNDRV_PCM_FORMAT_S16_LE;
721 break;
722 case 1:
723 format = SNDRV_PCM_FORMAT_S24_LE;
724 break;
725 case 2:
726 format = SNDRV_PCM_FORMAT_S32_LE;
727 break;
728 default:
729 format = SNDRV_PCM_FORMAT_S16_LE;
730 break;
731 }
732 return format;
733}
734
735static int tdm_get_format_val(int format)
736{
737 int value = 0;
738
739 switch (format) {
740 case SNDRV_PCM_FORMAT_S16_LE:
741 value = 0;
742 break;
743 case SNDRV_PCM_FORMAT_S24_LE:
744 value = 1;
745 break;
746 case SNDRV_PCM_FORMAT_S32_LE:
747 value = 2;
748 break;
749 default:
750 value = 0;
751 break;
752 }
753 return value;
754}
755
756static int mi2s_get_format(int value)
757{
758 int format = 0;
759
760 switch (value) {
761 case 0:
762 format = SNDRV_PCM_FORMAT_S16_LE;
763 break;
764 case 1:
765 format = SNDRV_PCM_FORMAT_S24_LE;
766 break;
767 case 2:
768 format = SNDRV_PCM_FORMAT_S24_3LE;
769 break;
770 case 3:
771 format = SNDRV_PCM_FORMAT_S32_LE;
772 break;
773 default:
774 format = SNDRV_PCM_FORMAT_S16_LE;
775 break;
776 }
777 return format;
778}
779
780static int mi2s_get_format_value(int format)
781{
782 int value = 0;
783
784 switch (format) {
785 case SNDRV_PCM_FORMAT_S16_LE:
786 value = 0;
787 break;
788 case SNDRV_PCM_FORMAT_S24_LE:
789 value = 1;
790 break;
791 case SNDRV_PCM_FORMAT_S24_3LE:
792 value = 2;
793 break;
794 case SNDRV_PCM_FORMAT_S32_LE:
795 value = 3;
796 break;
797 default:
798 value = 0;
799 break;
800 }
801 return value;
802}
803
804static int tdm_rx_format_get(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 ucontrol->value.enumerated.item[0] = tdm_get_format_val(
815 tdm_rx_cfg[port.mode][port.channel].bit_format);
816
817 pr_debug("%s: tdm_rx_bit_format = %d, item = %d\n", __func__,
818 tdm_rx_cfg[port.mode][port.channel].bit_format,
819 ucontrol->value.enumerated.item[0]);
820 }
821 return ret;
822}
823
824static int tdm_rx_format_put(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 tdm_rx_cfg[port.mode][port.channel].bit_format =
835 tdm_get_format(ucontrol->value.enumerated.item[0]);
836
837 pr_debug("%s: tdm_rx_bit_format = %d, item = %d\n", __func__,
838 tdm_rx_cfg[port.mode][port.channel].bit_format,
839 ucontrol->value.enumerated.item[0]);
840 }
841 return ret;
842}
843
844static int tdm_tx_format_get(struct snd_kcontrol *kcontrol,
845 struct snd_ctl_elem_value *ucontrol)
846{
847 struct tdm_port port;
848 int ret = tdm_get_port_idx(kcontrol, &port);
849
850 if (ret) {
851 pr_err("%s: unsupported control: %s",
852 __func__, kcontrol->id.name);
853 } else {
854 ucontrol->value.enumerated.item[0] = tdm_get_format_val(
855 tdm_tx_cfg[port.mode][port.channel].bit_format);
856
857 pr_debug("%s: tdm_tx_bit_format = %d, item = %d\n", __func__,
858 tdm_tx_cfg[port.mode][port.channel].bit_format,
859 ucontrol->value.enumerated.item[0]);
860 }
861 return ret;
862}
863
864static int tdm_tx_format_put(struct snd_kcontrol *kcontrol,
865 struct snd_ctl_elem_value *ucontrol)
866{
867 struct tdm_port port;
868 int ret = tdm_get_port_idx(kcontrol, &port);
869
870 if (ret) {
871 pr_err("%s: unsupported control: %s",
872 __func__, kcontrol->id.name);
873 } else {
874 tdm_tx_cfg[port.mode][port.channel].bit_format =
875 tdm_get_format(ucontrol->value.enumerated.item[0]);
876
877 pr_debug("%s: tdm_tx_bit_format = %d, item = %d\n", __func__,
878 tdm_tx_cfg[port.mode][port.channel].bit_format,
879 ucontrol->value.enumerated.item[0]);
880 }
881 return ret;
882}
883
884static int tdm_rx_ch_get(struct snd_kcontrol *kcontrol,
885 struct snd_ctl_elem_value *ucontrol)
886{
887 struct tdm_port port;
888 int ret = tdm_get_port_idx(kcontrol, &port);
889
890 if (ret) {
891 pr_err("%s: unsupported control: %s",
892 __func__, kcontrol->id.name);
893 } else {
894
895 ucontrol->value.enumerated.item[0] =
896 tdm_rx_cfg[port.mode][port.channel].channels - 1;
897
898 pr_debug("%s: tdm_rx_ch = %d, item = %d\n", __func__,
899 tdm_rx_cfg[port.mode][port.channel].channels - 1,
900 ucontrol->value.enumerated.item[0]);
901 }
902 return ret;
903}
904
905static int tdm_rx_ch_put(struct snd_kcontrol *kcontrol,
906 struct snd_ctl_elem_value *ucontrol)
907{
908 struct tdm_port port;
909 int ret = tdm_get_port_idx(kcontrol, &port);
910
911 if (ret) {
912 pr_err("%s: unsupported control: %s",
913 __func__, kcontrol->id.name);
914 } else {
915 tdm_rx_cfg[port.mode][port.channel].channels =
916 ucontrol->value.enumerated.item[0] + 1;
917
918 pr_debug("%s: tdm_rx_ch = %d, item = %d\n", __func__,
919 tdm_rx_cfg[port.mode][port.channel].channels,
920 ucontrol->value.enumerated.item[0] + 1);
921 }
922 return ret;
923}
924
925static int tdm_tx_ch_get(struct snd_kcontrol *kcontrol,
926 struct snd_ctl_elem_value *ucontrol)
927{
928 struct tdm_port port;
929 int ret = tdm_get_port_idx(kcontrol, &port);
930
931 if (ret) {
932 pr_err("%s: unsupported control: %s",
933 __func__, kcontrol->id.name);
934 } else {
935 ucontrol->value.enumerated.item[0] =
936 tdm_tx_cfg[port.mode][port.channel].channels - 1;
937
938 pr_debug("%s: tdm_tx_ch = %d, item = %d\n", __func__,
939 tdm_tx_cfg[port.mode][port.channel].channels - 1,
940 ucontrol->value.enumerated.item[0]);
941 }
942 return ret;
943}
944
945static int tdm_tx_ch_put(struct snd_kcontrol *kcontrol,
946 struct snd_ctl_elem_value *ucontrol)
947{
948 struct tdm_port port;
949 int ret = tdm_get_port_idx(kcontrol, &port);
950
951 if (ret) {
952 pr_err("%s: unsupported control: %s",
953 __func__, kcontrol->id.name);
954 } else {
955 tdm_tx_cfg[port.mode][port.channel].channels =
956 ucontrol->value.enumerated.item[0] + 1;
957
958 pr_debug("%s: tdm_tx_ch = %d, item = %d\n", __func__,
959 tdm_tx_cfg[port.mode][port.channel].channels,
960 ucontrol->value.enumerated.item[0] + 1);
961 }
962 return ret;
963}
964
965static int aux_pcm_get_sample_rate(int value)
966{
967 int sample_rate;
968
969 switch (value) {
970 case 1:
971 sample_rate = SAMPLING_RATE_16KHZ;
972 break;
973 case 0:
974 default:
975 sample_rate = SAMPLING_RATE_8KHZ;
976 break;
977 }
978 return sample_rate;
979}
980
981static int aux_pcm_get_sample_rate_val(int sample_rate)
982{
983 int sample_rate_val;
984
985 switch (sample_rate) {
986 case SAMPLING_RATE_16KHZ:
987 sample_rate_val = 1;
988 break;
989 case SAMPLING_RATE_8KHZ:
990 default:
991 sample_rate_val = 0;
992 break;
993 }
994 return sample_rate_val;
995}
996
997static int aux_pcm_get_port_idx(struct snd_kcontrol *kcontrol)
998{
999 int idx;
1000
1001 if (strnstr(kcontrol->id.name, "PRIM_AUX_PCM",
1002 sizeof("PRIM_AUX_PCM")))
1003 idx = PRIM_AUX_PCM;
1004 else if (strnstr(kcontrol->id.name, "SEC_AUX_PCM",
1005 sizeof("SEC_AUX_PCM")))
1006 idx = SEC_AUX_PCM;
1007 else if (strnstr(kcontrol->id.name, "TERT_AUX_PCM",
1008 sizeof("TERT_AUX_PCM")))
1009 idx = TERT_AUX_PCM;
1010 else if (strnstr(kcontrol->id.name, "QUAT_AUX_PCM",
1011 sizeof("QUAT_AUX_PCM")))
1012 idx = QUAT_AUX_PCM;
Rohit Kumard1754482017-09-10 22:57:39 +05301013 else if (strnstr(kcontrol->id.name, "QUIN_AUX_PCM",
1014 sizeof("QUIN_AUX_PCM")))
1015 idx = QUIN_AUX_PCM;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301016 else {
1017 pr_err("%s: unsupported port: %s",
1018 __func__, kcontrol->id.name);
1019 idx = -EINVAL;
1020 }
1021
1022 return idx;
1023}
1024
1025static int aux_pcm_rx_sample_rate_put(struct snd_kcontrol *kcontrol,
1026 struct snd_ctl_elem_value *ucontrol)
1027{
1028 int idx = aux_pcm_get_port_idx(kcontrol);
1029
1030 if (idx < 0)
1031 return idx;
1032
1033 aux_pcm_rx_cfg[idx].sample_rate =
1034 aux_pcm_get_sample_rate(ucontrol->value.enumerated.item[0]);
1035
1036 pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__,
1037 idx, aux_pcm_rx_cfg[idx].sample_rate,
1038 ucontrol->value.enumerated.item[0]);
1039
1040 return 0;
1041}
1042
1043static int aux_pcm_rx_sample_rate_get(struct snd_kcontrol *kcontrol,
1044 struct snd_ctl_elem_value *ucontrol)
1045{
1046 int idx = aux_pcm_get_port_idx(kcontrol);
1047
1048 if (idx < 0)
1049 return idx;
1050
1051 ucontrol->value.enumerated.item[0] =
1052 aux_pcm_get_sample_rate_val(aux_pcm_rx_cfg[idx].sample_rate);
1053
1054 pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__,
1055 idx, aux_pcm_rx_cfg[idx].sample_rate,
1056 ucontrol->value.enumerated.item[0]);
1057
1058 return 0;
1059}
1060
1061static int aux_pcm_tx_sample_rate_put(struct snd_kcontrol *kcontrol,
1062 struct snd_ctl_elem_value *ucontrol)
1063{
1064 int idx = aux_pcm_get_port_idx(kcontrol);
1065
1066 if (idx < 0)
1067 return idx;
1068
1069 aux_pcm_tx_cfg[idx].sample_rate =
1070 aux_pcm_get_sample_rate(ucontrol->value.enumerated.item[0]);
1071
1072 pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__,
1073 idx, aux_pcm_tx_cfg[idx].sample_rate,
1074 ucontrol->value.enumerated.item[0]);
1075
1076 return 0;
1077}
1078
1079static int aux_pcm_tx_sample_rate_get(struct snd_kcontrol *kcontrol,
1080 struct snd_ctl_elem_value *ucontrol)
1081{
1082 int idx = aux_pcm_get_port_idx(kcontrol);
1083
1084 if (idx < 0)
1085 return idx;
1086
1087 ucontrol->value.enumerated.item[0] =
1088 aux_pcm_get_sample_rate_val(aux_pcm_tx_cfg[idx].sample_rate);
1089
1090 pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__,
1091 idx, aux_pcm_tx_cfg[idx].sample_rate,
1092 ucontrol->value.enumerated.item[0]);
1093
1094 return 0;
1095}
1096
1097static int mi2s_get_port_idx(struct snd_kcontrol *kcontrol)
1098{
1099 int idx;
1100
1101 if (strnstr(kcontrol->id.name, "PRIM_MI2S_RX",
1102 sizeof("PRIM_MI2S_RX")))
1103 idx = PRIM_MI2S;
1104 else if (strnstr(kcontrol->id.name, "SEC_MI2S_RX",
1105 sizeof("SEC_MI2S_RX")))
1106 idx = SEC_MI2S;
1107 else if (strnstr(kcontrol->id.name, "TERT_MI2S_RX",
1108 sizeof("TERT_MI2S_RX")))
1109 idx = TERT_MI2S;
1110 else if (strnstr(kcontrol->id.name, "QUAT_MI2S_RX",
1111 sizeof("QUAT_MI2S_RX")))
1112 idx = QUAT_MI2S;
Rohit Kumard1754482017-09-10 22:57:39 +05301113 else if (strnstr(kcontrol->id.name, "QUIN_MI2S_RX",
1114 sizeof("QUIN_MI2S_RX")))
1115 idx = QUIN_MI2S;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301116 else if (strnstr(kcontrol->id.name, "PRIM_MI2S_TX",
1117 sizeof("PRIM_MI2S_TX")))
1118 idx = PRIM_MI2S;
1119 else if (strnstr(kcontrol->id.name, "SEC_MI2S_TX",
1120 sizeof("SEC_MI2S_TX")))
1121 idx = SEC_MI2S;
1122 else if (strnstr(kcontrol->id.name, "TERT_MI2S_TX",
1123 sizeof("TERT_MI2S_TX")))
1124 idx = TERT_MI2S;
1125 else if (strnstr(kcontrol->id.name, "QUAT_MI2S_TX",
1126 sizeof("QUAT_MI2S_TX")))
1127 idx = QUAT_MI2S;
Rohit Kumard1754482017-09-10 22:57:39 +05301128 else if (strnstr(kcontrol->id.name, "QUIN_MI2S_TX",
1129 sizeof("QUIN_MI2S_TX")))
1130 idx = QUIN_MI2S;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301131 else {
1132 pr_err("%s: unsupported channel: %s",
1133 __func__, kcontrol->id.name);
1134 idx = -EINVAL;
1135 }
1136
1137 return idx;
1138}
1139
1140static int mi2s_get_sample_rate_val(int sample_rate)
1141{
1142 int sample_rate_val;
1143
1144 switch (sample_rate) {
1145 case SAMPLING_RATE_8KHZ:
1146 sample_rate_val = 0;
1147 break;
1148 case SAMPLING_RATE_16KHZ:
1149 sample_rate_val = 1;
1150 break;
1151 case SAMPLING_RATE_32KHZ:
1152 sample_rate_val = 2;
1153 break;
1154 case SAMPLING_RATE_44P1KHZ:
1155 sample_rate_val = 3;
1156 break;
1157 case SAMPLING_RATE_48KHZ:
1158 sample_rate_val = 4;
1159 break;
1160 case SAMPLING_RATE_96KHZ:
1161 sample_rate_val = 5;
1162 break;
1163 case SAMPLING_RATE_192KHZ:
1164 sample_rate_val = 6;
1165 break;
1166 default:
1167 sample_rate_val = 4;
1168 break;
1169 }
1170 return sample_rate_val;
1171}
1172
1173static int mi2s_get_sample_rate(int value)
1174{
1175 int sample_rate;
1176
1177 switch (value) {
1178 case 0:
1179 sample_rate = SAMPLING_RATE_8KHZ;
1180 break;
1181 case 1:
1182 sample_rate = SAMPLING_RATE_16KHZ;
1183 break;
1184 case 2:
1185 sample_rate = SAMPLING_RATE_32KHZ;
1186 break;
1187 case 3:
1188 sample_rate = SAMPLING_RATE_44P1KHZ;
1189 break;
1190 case 4:
1191 sample_rate = SAMPLING_RATE_48KHZ;
1192 break;
1193 case 5:
1194 sample_rate = SAMPLING_RATE_96KHZ;
1195 break;
1196 case 6:
1197 sample_rate = SAMPLING_RATE_192KHZ;
1198 break;
1199 default:
1200 sample_rate = SAMPLING_RATE_48KHZ;
1201 break;
1202 }
1203 return sample_rate;
1204}
1205
1206static int mi2s_rx_sample_rate_put(struct snd_kcontrol *kcontrol,
1207 struct snd_ctl_elem_value *ucontrol)
1208{
1209 int idx = mi2s_get_port_idx(kcontrol);
1210
1211 if (idx < 0)
1212 return idx;
1213
1214 mi2s_rx_cfg[idx].sample_rate =
1215 mi2s_get_sample_rate(ucontrol->value.enumerated.item[0]);
1216
1217 pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__,
1218 idx, mi2s_rx_cfg[idx].sample_rate,
1219 ucontrol->value.enumerated.item[0]);
1220
1221 return 0;
1222}
1223
1224static int mi2s_rx_sample_rate_get(struct snd_kcontrol *kcontrol,
1225 struct snd_ctl_elem_value *ucontrol)
1226{
1227 int idx = mi2s_get_port_idx(kcontrol);
1228
1229 if (idx < 0)
1230 return idx;
1231
1232 ucontrol->value.enumerated.item[0] =
1233 mi2s_get_sample_rate_val(mi2s_rx_cfg[idx].sample_rate);
1234
1235 pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__,
1236 idx, mi2s_rx_cfg[idx].sample_rate,
1237 ucontrol->value.enumerated.item[0]);
1238
1239 return 0;
1240}
1241
1242static int mi2s_tx_sample_rate_put(struct snd_kcontrol *kcontrol,
1243 struct snd_ctl_elem_value *ucontrol)
1244{
1245 int idx = mi2s_get_port_idx(kcontrol);
1246
1247 if (idx < 0)
1248 return idx;
1249
1250 mi2s_tx_cfg[idx].sample_rate =
1251 mi2s_get_sample_rate(ucontrol->value.enumerated.item[0]);
1252
1253 pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__,
1254 idx, mi2s_tx_cfg[idx].sample_rate,
1255 ucontrol->value.enumerated.item[0]);
1256
1257 return 0;
1258}
1259
1260static int mi2s_tx_sample_rate_get(struct snd_kcontrol *kcontrol,
1261 struct snd_ctl_elem_value *ucontrol)
1262{
1263 int idx = mi2s_get_port_idx(kcontrol);
1264
1265 if (idx < 0)
1266 return idx;
1267
1268 ucontrol->value.enumerated.item[0] =
1269 mi2s_get_sample_rate_val(mi2s_tx_cfg[idx].sample_rate);
1270
1271 pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__,
1272 idx, mi2s_tx_cfg[idx].sample_rate,
1273 ucontrol->value.enumerated.item[0]);
1274
1275 return 0;
1276}
1277
1278static int mi2s_tx_format_put(struct snd_kcontrol *kcontrol,
1279 struct snd_ctl_elem_value *ucontrol)
1280{
1281 int idx = mi2s_get_port_idx(kcontrol);
1282
1283 if (idx < 0)
1284 return idx;
1285
1286 mi2s_tx_cfg[idx].bit_format =
1287 mi2s_get_format(ucontrol->value.enumerated.item[0]);
1288
1289 pr_debug("%s: idx[%d] _tx_format = %d, item = %d\n", __func__,
1290 idx, mi2s_tx_cfg[idx].bit_format,
1291 ucontrol->value.enumerated.item[0]);
1292
1293 return 0;
1294}
1295
1296static int mi2s_tx_format_get(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 ucontrol->value.enumerated.item[0] =
1305 mi2s_get_format_value(mi2s_tx_cfg[idx].bit_format);
1306
1307 pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__,
1308 idx, mi2s_tx_cfg[idx].bit_format,
1309 ucontrol->value.enumerated.item[0]);
1310
1311 return 0;
1312}
1313
1314static int mi2s_rx_format_put(struct snd_kcontrol *kcontrol,
1315 struct snd_ctl_elem_value *ucontrol)
1316{
1317 int idx = mi2s_get_port_idx(kcontrol);
1318
1319 if (idx < 0)
1320 return idx;
1321
1322 mi2s_rx_cfg[idx].bit_format =
1323 mi2s_get_format(ucontrol->value.enumerated.item[0]);
1324
1325 pr_debug("%s: idx[%d] _rx_format = %d, item = %d\n", __func__,
1326 idx, mi2s_rx_cfg[idx].bit_format,
1327 ucontrol->value.enumerated.item[0]);
1328
1329 return 0;
1330}
1331
1332static int mi2s_rx_format_get(struct snd_kcontrol *kcontrol,
1333 struct snd_ctl_elem_value *ucontrol)
1334{
1335 int idx = mi2s_get_port_idx(kcontrol);
1336
1337 if (idx < 0)
1338 return idx;
1339
1340 ucontrol->value.enumerated.item[0] =
1341 mi2s_get_format_value(mi2s_rx_cfg[idx].bit_format);
1342
1343 pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__,
1344 idx, mi2s_rx_cfg[idx].bit_format,
1345 ucontrol->value.enumerated.item[0]);
1346
1347 return 0;
1348}
1349
1350static int msm_mi2s_rx_ch_get(struct snd_kcontrol *kcontrol,
1351 struct snd_ctl_elem_value *ucontrol)
1352{
1353 int idx = mi2s_get_port_idx(kcontrol);
1354
1355 if (idx < 0)
1356 return idx;
1357
1358 pr_debug("%s: msm_mi2s_[%d]_rx_ch = %d\n", __func__,
1359 idx, mi2s_rx_cfg[idx].channels);
1360 ucontrol->value.enumerated.item[0] = mi2s_rx_cfg[idx].channels - 1;
1361
1362 return 0;
1363}
1364
1365static int msm_mi2s_rx_ch_put(struct snd_kcontrol *kcontrol,
1366 struct snd_ctl_elem_value *ucontrol)
1367{
1368 int idx = mi2s_get_port_idx(kcontrol);
1369
1370 if (idx < 0)
1371 return idx;
1372
1373 mi2s_rx_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1;
1374 pr_debug("%s: msm_mi2s_[%d]_rx_ch = %d\n", __func__,
1375 idx, mi2s_rx_cfg[idx].channels);
1376
1377 return 1;
1378}
1379
1380static int msm_mi2s_tx_ch_get(struct snd_kcontrol *kcontrol,
1381 struct snd_ctl_elem_value *ucontrol)
1382{
1383 int idx = mi2s_get_port_idx(kcontrol);
1384
1385 if (idx < 0)
1386 return idx;
1387
1388 pr_debug("%s: msm_mi2s_[%d]_tx_ch = %d\n", __func__,
1389 idx, mi2s_tx_cfg[idx].channels);
1390 ucontrol->value.enumerated.item[0] = mi2s_tx_cfg[idx].channels - 1;
1391
1392 return 0;
1393}
1394
1395static int msm_mi2s_tx_ch_put(struct snd_kcontrol *kcontrol,
1396 struct snd_ctl_elem_value *ucontrol)
1397{
1398 int idx = mi2s_get_port_idx(kcontrol);
1399
1400 if (idx < 0)
1401 return idx;
1402
1403 mi2s_tx_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1;
1404 pr_debug("%s: msm_mi2s_[%d]_tx_ch = %d\n", __func__,
1405 idx, mi2s_tx_cfg[idx].channels);
1406
1407 return 1;
1408}
1409
1410static int usb_audio_rx_ch_get(struct snd_kcontrol *kcontrol,
1411 struct snd_ctl_elem_value *ucontrol)
1412{
1413 pr_debug("%s: usb_audio_rx_ch = %d\n", __func__,
1414 usb_rx_cfg.channels);
1415 ucontrol->value.integer.value[0] = usb_rx_cfg.channels - 1;
1416 return 0;
1417}
1418
1419static int usb_audio_rx_ch_put(struct snd_kcontrol *kcontrol,
1420 struct snd_ctl_elem_value *ucontrol)
1421{
1422 usb_rx_cfg.channels = ucontrol->value.integer.value[0] + 1;
1423
1424 pr_debug("%s: usb_audio_rx_ch = %d\n", __func__, usb_rx_cfg.channels);
1425 return 1;
1426}
1427
1428static int usb_audio_rx_sample_rate_get(struct snd_kcontrol *kcontrol,
1429 struct snd_ctl_elem_value *ucontrol)
1430{
1431 int sample_rate_val;
1432
1433 switch (usb_rx_cfg.sample_rate) {
1434 case SAMPLING_RATE_384KHZ:
1435 sample_rate_val = 9;
1436 break;
1437 case SAMPLING_RATE_192KHZ:
1438 sample_rate_val = 8;
1439 break;
1440 case SAMPLING_RATE_96KHZ:
1441 sample_rate_val = 7;
1442 break;
1443 case SAMPLING_RATE_48KHZ:
1444 sample_rate_val = 6;
1445 break;
1446 case SAMPLING_RATE_44P1KHZ:
1447 sample_rate_val = 5;
1448 break;
1449 case SAMPLING_RATE_32KHZ:
1450 sample_rate_val = 4;
1451 break;
1452 case SAMPLING_RATE_22P05KHZ:
1453 sample_rate_val = 3;
1454 break;
1455 case SAMPLING_RATE_16KHZ:
1456 sample_rate_val = 2;
1457 break;
1458 case SAMPLING_RATE_11P025KHZ:
1459 sample_rate_val = 1;
1460 break;
1461 case SAMPLING_RATE_8KHZ:
1462 default:
1463 sample_rate_val = 0;
1464 break;
1465 }
1466
1467 ucontrol->value.integer.value[0] = sample_rate_val;
1468 pr_debug("%s: usb_audio_rx_sample_rate = %d\n", __func__,
1469 usb_rx_cfg.sample_rate);
1470 return 0;
1471}
1472
1473static int usb_audio_rx_sample_rate_put(struct snd_kcontrol *kcontrol,
1474 struct snd_ctl_elem_value *ucontrol)
1475{
1476 switch (ucontrol->value.integer.value[0]) {
1477 case 9:
1478 usb_rx_cfg.sample_rate = SAMPLING_RATE_384KHZ;
1479 break;
1480 case 8:
1481 usb_rx_cfg.sample_rate = SAMPLING_RATE_192KHZ;
1482 break;
1483 case 7:
1484 usb_rx_cfg.sample_rate = SAMPLING_RATE_96KHZ;
1485 break;
1486 case 6:
1487 usb_rx_cfg.sample_rate = SAMPLING_RATE_48KHZ;
1488 break;
1489 case 5:
1490 usb_rx_cfg.sample_rate = SAMPLING_RATE_44P1KHZ;
1491 break;
1492 case 4:
1493 usb_rx_cfg.sample_rate = SAMPLING_RATE_32KHZ;
1494 break;
1495 case 3:
1496 usb_rx_cfg.sample_rate = SAMPLING_RATE_22P05KHZ;
1497 break;
1498 case 2:
1499 usb_rx_cfg.sample_rate = SAMPLING_RATE_16KHZ;
1500 break;
1501 case 1:
1502 usb_rx_cfg.sample_rate = SAMPLING_RATE_11P025KHZ;
1503 break;
1504 case 0:
1505 usb_rx_cfg.sample_rate = SAMPLING_RATE_8KHZ;
1506 break;
1507 default:
1508 usb_rx_cfg.sample_rate = SAMPLING_RATE_48KHZ;
1509 break;
1510 }
1511
1512 pr_debug("%s: control value = %ld, usb_audio_rx_sample_rate = %d\n",
1513 __func__, ucontrol->value.integer.value[0],
1514 usb_rx_cfg.sample_rate);
1515 return 0;
1516}
1517
1518static int usb_audio_rx_format_get(struct snd_kcontrol *kcontrol,
1519 struct snd_ctl_elem_value *ucontrol)
1520{
1521 switch (usb_rx_cfg.bit_format) {
1522 case SNDRV_PCM_FORMAT_S32_LE:
1523 ucontrol->value.integer.value[0] = 3;
1524 break;
1525 case SNDRV_PCM_FORMAT_S24_3LE:
1526 ucontrol->value.integer.value[0] = 2;
1527 break;
1528 case SNDRV_PCM_FORMAT_S24_LE:
1529 ucontrol->value.integer.value[0] = 1;
1530 break;
1531 case SNDRV_PCM_FORMAT_S16_LE:
1532 default:
1533 ucontrol->value.integer.value[0] = 0;
1534 break;
1535 }
1536
1537 pr_debug("%s: usb_audio_rx_format = %d, ucontrol value = %ld\n",
1538 __func__, usb_rx_cfg.bit_format,
1539 ucontrol->value.integer.value[0]);
1540 return 0;
1541}
1542
1543static int usb_audio_rx_format_put(struct snd_kcontrol *kcontrol,
1544 struct snd_ctl_elem_value *ucontrol)
1545{
1546 int rc = 0;
1547
1548 switch (ucontrol->value.integer.value[0]) {
1549 case 3:
1550 usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S32_LE;
1551 break;
1552 case 2:
1553 usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_3LE;
1554 break;
1555 case 1:
1556 usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_LE;
1557 break;
1558 case 0:
1559 default:
1560 usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S16_LE;
1561 break;
1562 }
1563 pr_debug("%s: usb_audio_rx_format = %d, ucontrol value = %ld\n",
1564 __func__, usb_rx_cfg.bit_format,
1565 ucontrol->value.integer.value[0]);
1566
1567 return rc;
1568}
1569
1570static int usb_audio_tx_ch_get(struct snd_kcontrol *kcontrol,
1571 struct snd_ctl_elem_value *ucontrol)
1572{
1573 pr_debug("%s: usb_audio_tx_ch = %d\n", __func__,
1574 usb_tx_cfg.channels);
1575 ucontrol->value.integer.value[0] = usb_tx_cfg.channels - 1;
1576 return 0;
1577}
1578
1579static int usb_audio_tx_ch_put(struct snd_kcontrol *kcontrol,
1580 struct snd_ctl_elem_value *ucontrol)
1581{
1582 usb_tx_cfg.channels = ucontrol->value.integer.value[0] + 1;
1583
1584 pr_debug("%s: usb_audio_tx_ch = %d\n", __func__, usb_tx_cfg.channels);
1585 return 1;
1586}
1587
1588static int usb_audio_tx_sample_rate_get(struct snd_kcontrol *kcontrol,
1589 struct snd_ctl_elem_value *ucontrol)
1590{
1591 int sample_rate_val;
1592
1593 switch (usb_tx_cfg.sample_rate) {
1594 case SAMPLING_RATE_384KHZ:
1595 sample_rate_val = 9;
1596 break;
1597 case SAMPLING_RATE_192KHZ:
1598 sample_rate_val = 8;
1599 break;
1600 case SAMPLING_RATE_96KHZ:
1601 sample_rate_val = 7;
1602 break;
1603 case SAMPLING_RATE_48KHZ:
1604 sample_rate_val = 6;
1605 break;
1606 case SAMPLING_RATE_44P1KHZ:
1607 sample_rate_val = 5;
1608 break;
1609 case SAMPLING_RATE_32KHZ:
1610 sample_rate_val = 4;
1611 break;
1612 case SAMPLING_RATE_22P05KHZ:
1613 sample_rate_val = 3;
1614 break;
1615 case SAMPLING_RATE_16KHZ:
1616 sample_rate_val = 2;
1617 break;
1618 case SAMPLING_RATE_11P025KHZ:
1619 sample_rate_val = 1;
1620 break;
1621 case SAMPLING_RATE_8KHZ:
1622 sample_rate_val = 0;
1623 break;
1624 default:
1625 sample_rate_val = 6;
1626 break;
1627 }
1628
1629 ucontrol->value.integer.value[0] = sample_rate_val;
1630 pr_debug("%s: usb_audio_tx_sample_rate = %d\n", __func__,
1631 usb_tx_cfg.sample_rate);
1632 return 0;
1633}
1634
1635static int usb_audio_tx_sample_rate_put(struct snd_kcontrol *kcontrol,
1636 struct snd_ctl_elem_value *ucontrol)
1637{
1638 switch (ucontrol->value.integer.value[0]) {
1639 case 9:
1640 usb_tx_cfg.sample_rate = SAMPLING_RATE_384KHZ;
1641 break;
1642 case 8:
1643 usb_tx_cfg.sample_rate = SAMPLING_RATE_192KHZ;
1644 break;
1645 case 7:
1646 usb_tx_cfg.sample_rate = SAMPLING_RATE_96KHZ;
1647 break;
1648 case 6:
1649 usb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ;
1650 break;
1651 case 5:
1652 usb_tx_cfg.sample_rate = SAMPLING_RATE_44P1KHZ;
1653 break;
1654 case 4:
1655 usb_tx_cfg.sample_rate = SAMPLING_RATE_32KHZ;
1656 break;
1657 case 3:
1658 usb_tx_cfg.sample_rate = SAMPLING_RATE_22P05KHZ;
1659 break;
1660 case 2:
1661 usb_tx_cfg.sample_rate = SAMPLING_RATE_16KHZ;
1662 break;
1663 case 1:
1664 usb_tx_cfg.sample_rate = SAMPLING_RATE_11P025KHZ;
1665 break;
1666 case 0:
1667 usb_tx_cfg.sample_rate = SAMPLING_RATE_8KHZ;
1668 break;
1669 default:
1670 usb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ;
1671 break;
1672 }
1673
1674 pr_debug("%s: control value = %ld, usb_audio_tx_sample_rate = %d\n",
1675 __func__, ucontrol->value.integer.value[0],
1676 usb_tx_cfg.sample_rate);
1677 return 0;
1678}
1679
1680static int usb_audio_tx_format_get(struct snd_kcontrol *kcontrol,
1681 struct snd_ctl_elem_value *ucontrol)
1682{
1683 switch (usb_tx_cfg.bit_format) {
1684 case SNDRV_PCM_FORMAT_S32_LE:
1685 ucontrol->value.integer.value[0] = 3;
1686 break;
1687 case SNDRV_PCM_FORMAT_S24_3LE:
1688 ucontrol->value.integer.value[0] = 2;
1689 break;
1690 case SNDRV_PCM_FORMAT_S24_LE:
1691 ucontrol->value.integer.value[0] = 1;
1692 break;
1693 case SNDRV_PCM_FORMAT_S16_LE:
1694 default:
1695 ucontrol->value.integer.value[0] = 0;
1696 break;
1697 }
1698
1699 pr_debug("%s: usb_audio_tx_format = %d, ucontrol value = %ld\n",
1700 __func__, usb_tx_cfg.bit_format,
1701 ucontrol->value.integer.value[0]);
1702 return 0;
1703}
1704
1705static int usb_audio_tx_format_put(struct snd_kcontrol *kcontrol,
1706 struct snd_ctl_elem_value *ucontrol)
1707{
1708 int rc = 0;
1709
1710 switch (ucontrol->value.integer.value[0]) {
1711 case 3:
1712 usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S32_LE;
1713 break;
1714 case 2:
1715 usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_3LE;
1716 break;
1717 case 1:
1718 usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_LE;
1719 break;
1720 case 0:
1721 default:
1722 usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S16_LE;
1723 break;
1724 }
1725 pr_debug("%s: usb_audio_tx_format = %d, ucontrol value = %ld\n",
1726 __func__, usb_tx_cfg.bit_format,
1727 ucontrol->value.integer.value[0]);
1728
1729 return rc;
1730}
1731
1732static int ext_disp_get_port_idx(struct snd_kcontrol *kcontrol)
1733{
1734 int idx;
1735
1736 if (strnstr(kcontrol->id.name, "Display Port RX",
1737 sizeof("Display Port RX")))
1738 idx = DP_RX_IDX;
1739 else {
1740 pr_err("%s: unsupported BE: %s",
1741 __func__, kcontrol->id.name);
1742 idx = -EINVAL;
1743 }
1744
1745 return idx;
1746}
1747
1748static int ext_disp_rx_format_get(struct snd_kcontrol *kcontrol,
1749 struct snd_ctl_elem_value *ucontrol)
1750{
1751 int idx = ext_disp_get_port_idx(kcontrol);
1752
1753 if (idx < 0)
1754 return idx;
1755
1756 switch (ext_disp_rx_cfg[idx].bit_format) {
1757 case SNDRV_PCM_FORMAT_S24_LE:
1758 ucontrol->value.integer.value[0] = 1;
1759 break;
1760
1761 case SNDRV_PCM_FORMAT_S16_LE:
1762 default:
1763 ucontrol->value.integer.value[0] = 0;
1764 break;
1765 }
1766
1767 pr_debug("%s: ext_disp_rx[%d].format = %d, ucontrol value = %ld\n",
1768 __func__, idx, ext_disp_rx_cfg[idx].bit_format,
1769 ucontrol->value.integer.value[0]);
1770 return 0;
1771}
1772
1773static int ext_disp_rx_format_put(struct snd_kcontrol *kcontrol,
1774 struct snd_ctl_elem_value *ucontrol)
1775{
1776 int idx = ext_disp_get_port_idx(kcontrol);
1777
1778 if (idx < 0)
1779 return idx;
1780
1781 switch (ucontrol->value.integer.value[0]) {
1782 case 1:
1783 ext_disp_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S24_LE;
1784 break;
1785 case 0:
1786 default:
1787 ext_disp_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S16_LE;
1788 break;
1789 }
1790 pr_debug("%s: ext_disp_rx[%d].format = %d, ucontrol value = %ld\n",
1791 __func__, idx, ext_disp_rx_cfg[idx].bit_format,
1792 ucontrol->value.integer.value[0]);
1793
1794 return 0;
1795}
1796
1797static int ext_disp_rx_ch_get(struct snd_kcontrol *kcontrol,
1798 struct snd_ctl_elem_value *ucontrol)
1799{
1800 int idx = ext_disp_get_port_idx(kcontrol);
1801
1802 if (idx < 0)
1803 return idx;
1804
1805 ucontrol->value.integer.value[0] =
1806 ext_disp_rx_cfg[idx].channels - 2;
1807
1808 pr_debug("%s: ext_disp_rx[%d].ch = %d\n", __func__,
1809 idx, ext_disp_rx_cfg[idx].channels);
1810
1811 return 0;
1812}
1813
1814static int ext_disp_rx_ch_put(struct snd_kcontrol *kcontrol,
1815 struct snd_ctl_elem_value *ucontrol)
1816{
1817 int idx = ext_disp_get_port_idx(kcontrol);
1818
1819 if (idx < 0)
1820 return idx;
1821
1822 ext_disp_rx_cfg[idx].channels =
1823 ucontrol->value.integer.value[0] + 2;
1824
1825 pr_debug("%s: ext_disp_rx[%d].ch = %d\n", __func__,
1826 idx, ext_disp_rx_cfg[idx].channels);
1827 return 1;
1828}
1829
1830static int ext_disp_rx_sample_rate_get(struct snd_kcontrol *kcontrol,
1831 struct snd_ctl_elem_value *ucontrol)
1832{
1833 int sample_rate_val;
1834 int idx = ext_disp_get_port_idx(kcontrol);
1835
1836 if (idx < 0)
1837 return idx;
1838
1839 switch (ext_disp_rx_cfg[idx].sample_rate) {
1840 case SAMPLING_RATE_192KHZ:
1841 sample_rate_val = 2;
1842 break;
1843
1844 case SAMPLING_RATE_96KHZ:
1845 sample_rate_val = 1;
1846 break;
1847
1848 case SAMPLING_RATE_48KHZ:
1849 default:
1850 sample_rate_val = 0;
1851 break;
1852 }
1853
1854 ucontrol->value.integer.value[0] = sample_rate_val;
1855 pr_debug("%s: ext_disp_rx[%d].sample_rate = %d\n", __func__,
1856 idx, ext_disp_rx_cfg[idx].sample_rate);
1857
1858 return 0;
1859}
1860
1861static int ext_disp_rx_sample_rate_put(struct snd_kcontrol *kcontrol,
1862 struct snd_ctl_elem_value *ucontrol)
1863{
1864 int idx = ext_disp_get_port_idx(kcontrol);
1865
1866 if (idx < 0)
1867 return idx;
1868
1869 switch (ucontrol->value.integer.value[0]) {
1870 case 2:
1871 ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_192KHZ;
1872 break;
1873 case 1:
1874 ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_96KHZ;
1875 break;
1876 case 0:
1877 default:
1878 ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_48KHZ;
1879 break;
1880 }
1881
1882 pr_debug("%s: control value = %ld, ext_disp_rx[%d].sample_rate = %d\n",
1883 __func__, ucontrol->value.integer.value[0], idx,
1884 ext_disp_rx_cfg[idx].sample_rate);
1885 return 0;
1886}
1887
Revathi Uddaraju30feb0d2017-11-21 15:30:19 +05301888static int msm_qos_ctl_get(struct snd_kcontrol *kcontrol,
1889 struct snd_ctl_elem_value *ucontrol)
1890{
1891 ucontrol->value.enumerated.item[0] = qos_vote_status;
1892
1893 return 0;
1894}
1895
1896static int msm_qos_ctl_put(struct snd_kcontrol *kcontrol,
1897 struct snd_ctl_elem_value *ucontrol)
1898{
1899 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
1900 struct snd_soc_card *card = codec->component.card;
1901 const char *fe_name = MSM_DAILINK_NAME(LowLatency);
1902 struct snd_soc_pcm_runtime *rtd;
1903 struct snd_pcm_substream *substream;
1904 s32 usecs;
1905
1906 rtd = snd_soc_get_pcm_runtime(card, fe_name);
1907 if (!rtd) {
1908 pr_err("%s: fail to get pcm runtime for %s\n",
1909 __func__, fe_name);
1910 return -EINVAL;
1911 }
1912
1913 substream = rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
1914 if (!substream) {
1915 pr_err("%s: substream is null\n", __func__);
1916 return -EINVAL;
1917 }
1918
1919 qos_vote_status = ucontrol->value.enumerated.item[0];
1920 if (qos_vote_status) {
1921 if (pm_qos_request_active(&substream->latency_pm_qos_req))
1922 pm_qos_remove_request(&substream->latency_pm_qos_req);
1923 if (!substream->runtime) {
1924 pr_err("%s: runtime is null\n", __func__);
1925 return -EINVAL;
1926 }
1927 usecs = MSM_LL_QOS_VALUE;
1928 if (usecs >= 0)
1929 pm_qos_add_request(&substream->latency_pm_qos_req,
1930 PM_QOS_CPU_DMA_LATENCY, usecs);
1931 } else {
1932 if (pm_qos_request_active(&substream->latency_pm_qos_req))
1933 pm_qos_remove_request(&substream->latency_pm_qos_req);
1934 }
1935
1936 return 0;
1937}
1938
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301939const struct snd_kcontrol_new msm_common_snd_controls[] = {
1940 SOC_ENUM_EXT("PROXY_RX Channels", proxy_rx_chs,
1941 proxy_rx_ch_get, proxy_rx_ch_put),
1942 SOC_ENUM_EXT("PRIM_AUX_PCM_RX SampleRate", prim_aux_pcm_rx_sample_rate,
1943 aux_pcm_rx_sample_rate_get,
1944 aux_pcm_rx_sample_rate_put),
1945 SOC_ENUM_EXT("SEC_AUX_PCM_RX SampleRate", sec_aux_pcm_rx_sample_rate,
1946 aux_pcm_rx_sample_rate_get,
1947 aux_pcm_rx_sample_rate_put),
1948 SOC_ENUM_EXT("TERT_AUX_PCM_RX SampleRate", tert_aux_pcm_rx_sample_rate,
1949 aux_pcm_rx_sample_rate_get,
1950 aux_pcm_rx_sample_rate_put),
1951 SOC_ENUM_EXT("QUAT_AUX_PCM_RX SampleRate", quat_aux_pcm_rx_sample_rate,
1952 aux_pcm_rx_sample_rate_get,
1953 aux_pcm_rx_sample_rate_put),
Rohit Kumard1754482017-09-10 22:57:39 +05301954 SOC_ENUM_EXT("QUIN_AUX_PCM_RX SampleRate", quin_aux_pcm_rx_sample_rate,
1955 aux_pcm_rx_sample_rate_get,
1956 aux_pcm_rx_sample_rate_put),
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301957 SOC_ENUM_EXT("PRIM_AUX_PCM_TX SampleRate", prim_aux_pcm_tx_sample_rate,
1958 aux_pcm_tx_sample_rate_get,
1959 aux_pcm_tx_sample_rate_put),
1960 SOC_ENUM_EXT("SEC_AUX_PCM_TX SampleRate", sec_aux_pcm_tx_sample_rate,
1961 aux_pcm_tx_sample_rate_get,
1962 aux_pcm_tx_sample_rate_put),
1963 SOC_ENUM_EXT("TERT_AUX_PCM_TX SampleRate", tert_aux_pcm_tx_sample_rate,
1964 aux_pcm_tx_sample_rate_get,
1965 aux_pcm_tx_sample_rate_put),
1966 SOC_ENUM_EXT("QUAT_AUX_PCM_TX SampleRate", quat_aux_pcm_tx_sample_rate,
1967 aux_pcm_tx_sample_rate_get,
1968 aux_pcm_tx_sample_rate_put),
Rohit Kumard1754482017-09-10 22:57:39 +05301969 SOC_ENUM_EXT("QUIN_AUX_PCM_TX SampleRate", quin_aux_pcm_tx_sample_rate,
1970 aux_pcm_tx_sample_rate_get,
1971 aux_pcm_tx_sample_rate_put),
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301972 SOC_ENUM_EXT("PRIM_MI2S_RX SampleRate", prim_mi2s_rx_sample_rate,
1973 mi2s_rx_sample_rate_get,
1974 mi2s_rx_sample_rate_put),
1975 SOC_ENUM_EXT("SEC_MI2S_RX SampleRate", sec_mi2s_rx_sample_rate,
1976 mi2s_rx_sample_rate_get,
1977 mi2s_rx_sample_rate_put),
1978 SOC_ENUM_EXT("TERT_MI2S_RX SampleRate", tert_mi2s_rx_sample_rate,
1979 mi2s_rx_sample_rate_get,
1980 mi2s_rx_sample_rate_put),
1981 SOC_ENUM_EXT("QUAT_MI2S_RX SampleRate", quat_mi2s_rx_sample_rate,
1982 mi2s_rx_sample_rate_get,
1983 mi2s_rx_sample_rate_put),
Rohit Kumard1754482017-09-10 22:57:39 +05301984 SOC_ENUM_EXT("QUIN_MI2S_RX SampleRate", quin_mi2s_rx_sample_rate,
1985 mi2s_rx_sample_rate_get,
1986 mi2s_rx_sample_rate_put),
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301987 SOC_ENUM_EXT("PRIM_MI2S_TX SampleRate", prim_mi2s_tx_sample_rate,
1988 mi2s_tx_sample_rate_get,
1989 mi2s_tx_sample_rate_put),
1990 SOC_ENUM_EXT("SEC_MI2S_TX SampleRate", sec_mi2s_tx_sample_rate,
1991 mi2s_tx_sample_rate_get,
1992 mi2s_tx_sample_rate_put),
1993 SOC_ENUM_EXT("TERT_MI2S_TX SampleRate", tert_mi2s_tx_sample_rate,
1994 mi2s_tx_sample_rate_get,
1995 mi2s_tx_sample_rate_put),
1996 SOC_ENUM_EXT("QUAT_MI2S_TX SampleRate", quat_mi2s_tx_sample_rate,
1997 mi2s_tx_sample_rate_get,
1998 mi2s_tx_sample_rate_put),
Rohit Kumard1754482017-09-10 22:57:39 +05301999 SOC_ENUM_EXT("QUIN_MI2S_TX SampleRate", quin_mi2s_tx_sample_rate,
2000 mi2s_tx_sample_rate_get,
2001 mi2s_tx_sample_rate_put),
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302002 SOC_ENUM_EXT("PRIM_MI2S_RX Format", prim_mi2s_rx_format,
2003 mi2s_rx_format_get,
2004 mi2s_rx_format_put),
2005 SOC_ENUM_EXT("SEC_MI2S_RX Format", sec_mi2s_rx_format,
2006 mi2s_rx_format_get,
2007 mi2s_rx_format_put),
2008 SOC_ENUM_EXT("TERT_MI2S_RX Format", tert_mi2s_rx_format,
2009 mi2s_rx_format_get,
2010 mi2s_rx_format_put),
2011 SOC_ENUM_EXT("QUAT_MI2S_RX Format", quat_mi2s_rx_format,
2012 mi2s_rx_format_get,
2013 mi2s_rx_format_put),
Rohit Kumard1754482017-09-10 22:57:39 +05302014 SOC_ENUM_EXT("QUIN_MI2S_RX Format", quin_mi2s_rx_format,
2015 mi2s_rx_format_get,
2016 mi2s_rx_format_put),
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302017 SOC_ENUM_EXT("PRIM_MI2S_TX Format", prim_mi2s_tx_format,
2018 mi2s_tx_format_get,
2019 mi2s_tx_format_put),
2020 SOC_ENUM_EXT("SEC_MI2S_TX Format", sec_mi2s_tx_format,
2021 mi2s_tx_format_get,
2022 mi2s_tx_format_put),
2023 SOC_ENUM_EXT("TERT_MI2S_TX Format", tert_mi2s_tx_format,
2024 mi2s_tx_format_get,
2025 mi2s_tx_format_put),
2026 SOC_ENUM_EXT("QUAT_MI2S_TX Format", quat_mi2s_tx_format,
2027 mi2s_tx_format_get,
2028 mi2s_tx_format_put),
Rohit Kumard1754482017-09-10 22:57:39 +05302029 SOC_ENUM_EXT("QUIN_MI2S_TX Format", quin_mi2s_tx_format,
2030 mi2s_tx_format_get,
2031 mi2s_tx_format_put),
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302032 SOC_ENUM_EXT("PRIM_MI2S_RX Channels", prim_mi2s_rx_chs,
2033 msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put),
2034 SOC_ENUM_EXT("PRIM_MI2S_TX Channels", prim_mi2s_tx_chs,
2035 msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put),
2036 SOC_ENUM_EXT("SEC_MI2S_RX Channels", sec_mi2s_rx_chs,
2037 msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put),
2038 SOC_ENUM_EXT("SEC_MI2S_TX Channels", sec_mi2s_tx_chs,
2039 msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put),
2040 SOC_ENUM_EXT("TERT_MI2S_RX Channels", tert_mi2s_rx_chs,
2041 msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put),
2042 SOC_ENUM_EXT("TERT_MI2S_TX Channels", tert_mi2s_tx_chs,
2043 msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put),
2044 SOC_ENUM_EXT("QUAT_MI2S_RX Channels", quat_mi2s_rx_chs,
2045 msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put),
2046 SOC_ENUM_EXT("QUAT_MI2S_TX Channels", quat_mi2s_tx_chs,
2047 msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put),
Rohit Kumard1754482017-09-10 22:57:39 +05302048 SOC_ENUM_EXT("QUIN_MI2S_RX Channels", quin_mi2s_rx_chs,
2049 msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put),
2050 SOC_ENUM_EXT("QUIN_MI2S_TX Channels", quin_mi2s_tx_chs,
2051 msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put),
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302052 SOC_ENUM_EXT("USB_AUDIO_RX Channels", usb_rx_chs,
2053 usb_audio_rx_ch_get, usb_audio_rx_ch_put),
2054 SOC_ENUM_EXT("USB_AUDIO_TX Channels", usb_tx_chs,
2055 usb_audio_tx_ch_get, usb_audio_tx_ch_put),
2056 SOC_ENUM_EXT("Display Port RX Channels", ext_disp_rx_chs,
2057 ext_disp_rx_ch_get, ext_disp_rx_ch_put),
2058 SOC_ENUM_EXT("USB_AUDIO_RX Format", usb_rx_format,
2059 usb_audio_rx_format_get, usb_audio_rx_format_put),
2060 SOC_ENUM_EXT("USB_AUDIO_TX Format", usb_tx_format,
2061 usb_audio_tx_format_get, usb_audio_tx_format_put),
2062 SOC_ENUM_EXT("Display Port RX Bit Format", ext_disp_rx_format,
2063 ext_disp_rx_format_get, ext_disp_rx_format_put),
2064 SOC_ENUM_EXT("USB_AUDIO_RX SampleRate", usb_rx_sample_rate,
2065 usb_audio_rx_sample_rate_get,
2066 usb_audio_rx_sample_rate_put),
2067 SOC_ENUM_EXT("USB_AUDIO_TX SampleRate", usb_tx_sample_rate,
2068 usb_audio_tx_sample_rate_get,
2069 usb_audio_tx_sample_rate_put),
2070 SOC_ENUM_EXT("Display Port RX SampleRate", ext_disp_rx_sample_rate,
2071 ext_disp_rx_sample_rate_get,
2072 ext_disp_rx_sample_rate_put),
2073 SOC_ENUM_EXT("PRI_TDM_RX_0 SampleRate", tdm_rx_sample_rate,
2074 tdm_rx_sample_rate_get,
2075 tdm_rx_sample_rate_put),
2076 SOC_ENUM_EXT("PRI_TDM_TX_0 SampleRate", tdm_tx_sample_rate,
2077 tdm_tx_sample_rate_get,
2078 tdm_tx_sample_rate_put),
2079 SOC_ENUM_EXT("PRI_TDM_RX_0 Format", tdm_rx_format,
2080 tdm_rx_format_get,
2081 tdm_rx_format_put),
2082 SOC_ENUM_EXT("PRI_TDM_TX_0 Format", tdm_tx_format,
2083 tdm_tx_format_get,
2084 tdm_tx_format_put),
2085 SOC_ENUM_EXT("PRI_TDM_RX_0 Channels", tdm_rx_chs,
2086 tdm_rx_ch_get,
2087 tdm_rx_ch_put),
2088 SOC_ENUM_EXT("PRI_TDM_TX_0 Channels", tdm_tx_chs,
2089 tdm_tx_ch_get,
2090 tdm_tx_ch_put),
2091 SOC_ENUM_EXT("SEC_TDM_RX_0 SampleRate", tdm_rx_sample_rate,
2092 tdm_rx_sample_rate_get,
2093 tdm_rx_sample_rate_put),
2094 SOC_ENUM_EXT("SEC_TDM_TX_0 SampleRate", tdm_tx_sample_rate,
2095 tdm_tx_sample_rate_get,
2096 tdm_tx_sample_rate_put),
2097 SOC_ENUM_EXT("SEC_TDM_RX_0 Format", tdm_rx_format,
2098 tdm_rx_format_get,
2099 tdm_rx_format_put),
2100 SOC_ENUM_EXT("SEC_TDM_TX_0 Format", tdm_tx_format,
2101 tdm_tx_format_get,
2102 tdm_tx_format_put),
2103 SOC_ENUM_EXT("SEC_TDM_RX_0 Channels", tdm_rx_chs,
2104 tdm_rx_ch_get,
2105 tdm_rx_ch_put),
2106 SOC_ENUM_EXT("SEC_TDM_TX_0 Channels", tdm_tx_chs,
2107 tdm_tx_ch_get,
2108 tdm_tx_ch_put),
2109 SOC_ENUM_EXT("TERT_TDM_RX_0 SampleRate", tdm_rx_sample_rate,
2110 tdm_rx_sample_rate_get,
2111 tdm_rx_sample_rate_put),
2112 SOC_ENUM_EXT("TERT_TDM_TX_0 SampleRate", tdm_tx_sample_rate,
2113 tdm_tx_sample_rate_get,
2114 tdm_tx_sample_rate_put),
2115 SOC_ENUM_EXT("TERT_TDM_RX_0 Format", tdm_rx_format,
2116 tdm_rx_format_get,
2117 tdm_rx_format_put),
2118 SOC_ENUM_EXT("TERT_TDM_TX_0 Format", tdm_tx_format,
2119 tdm_tx_format_get,
2120 tdm_tx_format_put),
2121 SOC_ENUM_EXT("TERT_TDM_RX_0 Channels", tdm_rx_chs,
2122 tdm_rx_ch_get,
2123 tdm_rx_ch_put),
2124 SOC_ENUM_EXT("TERT_TDM_TX_0 Channels", tdm_tx_chs,
2125 tdm_tx_ch_get,
2126 tdm_tx_ch_put),
2127 SOC_ENUM_EXT("QUAT_TDM_RX_0 SampleRate", tdm_rx_sample_rate,
2128 tdm_rx_sample_rate_get,
2129 tdm_rx_sample_rate_put),
2130 SOC_ENUM_EXT("QUAT_TDM_TX_0 SampleRate", tdm_tx_sample_rate,
2131 tdm_tx_sample_rate_get,
2132 tdm_tx_sample_rate_put),
2133 SOC_ENUM_EXT("QUAT_TDM_RX_0 Format", tdm_rx_format,
2134 tdm_rx_format_get,
2135 tdm_rx_format_put),
2136 SOC_ENUM_EXT("QUAT_TDM_TX_0 Format", tdm_tx_format,
2137 tdm_tx_format_get,
2138 tdm_tx_format_put),
2139 SOC_ENUM_EXT("QUAT_TDM_RX_0 Channels", tdm_rx_chs,
2140 tdm_rx_ch_get,
2141 tdm_rx_ch_put),
2142 SOC_ENUM_EXT("QUAT_TDM_TX_0 Channels", tdm_tx_chs,
2143 tdm_tx_ch_get,
2144 tdm_tx_ch_put),
Rohit Kumard1754482017-09-10 22:57:39 +05302145 SOC_ENUM_EXT("QUIN_TDM_RX_0 SampleRate", tdm_rx_sample_rate,
2146 tdm_rx_sample_rate_get,
2147 tdm_rx_sample_rate_put),
2148 SOC_ENUM_EXT("QUIN_TDM_TX_0 SampleRate", tdm_tx_sample_rate,
2149 tdm_tx_sample_rate_get,
2150 tdm_tx_sample_rate_put),
2151 SOC_ENUM_EXT("QUIN_TDM_RX_0 Format", tdm_rx_format,
2152 tdm_rx_format_get,
2153 tdm_rx_format_put),
2154 SOC_ENUM_EXT("QUIN_TDM_TX_0 Format", tdm_tx_format,
2155 tdm_tx_format_get,
2156 tdm_tx_format_put),
2157 SOC_ENUM_EXT("QUIN_TDM_RX_0 Channels", tdm_rx_chs,
2158 tdm_rx_ch_get,
2159 tdm_rx_ch_put),
2160 SOC_ENUM_EXT("QUIN_TDM_TX_0 Channels", tdm_tx_chs,
2161 tdm_tx_ch_get,
2162 tdm_tx_ch_put),
Revathi Uddaraju30feb0d2017-11-21 15:30:19 +05302163 SOC_ENUM_EXT("MultiMedia5_RX QOS Vote", qos_vote, msm_qos_ctl_get,
2164 msm_qos_ctl_put),
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302165};
2166
2167/**
2168 * msm_common_snd_controls_size - to return controls size
2169 *
2170 * Return: returns size of common controls array
2171 */
2172int msm_common_snd_controls_size(void)
2173{
2174 return ARRAY_SIZE(msm_common_snd_controls);
2175}
2176EXPORT_SYMBOL(msm_common_snd_controls_size);
2177
Laxminath Kasam38070be2017-08-17 18:21:59 +05302178void msm_set_codec_reg_done(bool done)
2179{
2180 codec_reg_done = done;
2181}
2182EXPORT_SYMBOL(msm_set_codec_reg_done);
2183
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302184static inline int param_is_mask(int p)
2185{
2186 return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) &&
2187 (p <= SNDRV_PCM_HW_PARAM_LAST_MASK);
2188}
2189
2190static inline struct snd_mask *param_to_mask(struct snd_pcm_hw_params *p,
2191 int n)
2192{
2193 return &(p->masks[n - SNDRV_PCM_HW_PARAM_FIRST_MASK]);
2194}
2195
2196static void param_set_mask(struct snd_pcm_hw_params *p, int n, unsigned int bit)
2197{
2198 if (bit >= SNDRV_MASK_MAX)
2199 return;
2200 if (param_is_mask(n)) {
2201 struct snd_mask *m = param_to_mask(p, n);
2202
2203 m->bits[0] = 0;
2204 m->bits[1] = 0;
2205 m->bits[bit >> 5] |= (1 << (bit & 31));
2206 }
2207}
2208
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05302209static int msm_ext_disp_get_idx_from_beid(int32_t id)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302210{
2211 int idx;
2212
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05302213 switch (id) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302214 case MSM_BACKEND_DAI_DISPLAY_PORT_RX:
2215 idx = DP_RX_IDX;
2216 break;
2217 default:
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05302218 pr_err("%s: Incorrect ext_disp id %d\n", __func__, id);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302219 idx = -EINVAL;
2220 break;
2221 }
2222
2223 return idx;
2224}
2225
2226/**
2227 * msm_common_be_hw_params_fixup - updates settings of ALSA BE hw params.
2228 *
2229 * @rtd: runtime dailink instance
2230 * @params: HW params of associated backend dailink.
2231 *
2232 * Returns 0.
2233 */
2234int msm_common_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
2235 struct snd_pcm_hw_params *params)
2236{
2237 struct snd_soc_dai_link *dai_link = rtd->dai_link;
2238 struct snd_interval *rate = hw_param_interval(params,
2239 SNDRV_PCM_HW_PARAM_RATE);
2240 struct snd_interval *channels = hw_param_interval(params,
2241 SNDRV_PCM_HW_PARAM_CHANNELS);
2242 int rc = 0;
2243 int idx;
2244
2245 pr_debug("%s: format = %d, rate = %d\n",
2246 __func__, params_format(params), params_rate(params));
2247
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05302248 switch (dai_link->id) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302249 case MSM_BACKEND_DAI_USB_RX:
2250 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2251 usb_rx_cfg.bit_format);
2252 rate->min = rate->max = usb_rx_cfg.sample_rate;
2253 channels->min = channels->max = usb_rx_cfg.channels;
2254 break;
2255
2256 case MSM_BACKEND_DAI_USB_TX:
2257 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2258 usb_tx_cfg.bit_format);
2259 rate->min = rate->max = usb_tx_cfg.sample_rate;
2260 channels->min = channels->max = usb_tx_cfg.channels;
2261 break;
2262
2263 case MSM_BACKEND_DAI_DISPLAY_PORT_RX:
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05302264 idx = msm_ext_disp_get_idx_from_beid(dai_link->id);
2265 if (idx < 0) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302266 pr_err("%s: Incorrect ext disp idx %d\n",
2267 __func__, idx);
2268 rc = idx;
2269 break;
2270 }
2271
2272 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2273 ext_disp_rx_cfg[idx].bit_format);
2274 rate->min = rate->max = ext_disp_rx_cfg[idx].sample_rate;
2275 channels->min = channels->max = ext_disp_rx_cfg[idx].channels;
2276 break;
2277
2278 case MSM_BACKEND_DAI_AFE_PCM_RX:
2279 channels->min = channels->max = proxy_rx_cfg.channels;
2280 rate->min = rate->max = SAMPLING_RATE_48KHZ;
2281 break;
2282
2283 case MSM_BACKEND_DAI_PRI_TDM_RX_0:
2284 channels->min = channels->max =
2285 tdm_rx_cfg[TDM_PRI][TDM_0].channels;
2286 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2287 tdm_rx_cfg[TDM_PRI][TDM_0].bit_format);
2288 rate->min = rate->max = tdm_rx_cfg[TDM_PRI][TDM_0].sample_rate;
2289 break;
2290
2291 case MSM_BACKEND_DAI_PRI_TDM_TX_0:
2292 channels->min = channels->max =
2293 tdm_tx_cfg[TDM_PRI][TDM_0].channels;
2294 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2295 tdm_tx_cfg[TDM_PRI][TDM_0].bit_format);
2296 rate->min = rate->max = tdm_tx_cfg[TDM_PRI][TDM_0].sample_rate;
2297 break;
2298
2299 case MSM_BACKEND_DAI_SEC_TDM_RX_0:
2300 channels->min = channels->max =
2301 tdm_rx_cfg[TDM_SEC][TDM_0].channels;
2302 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2303 tdm_rx_cfg[TDM_SEC][TDM_0].bit_format);
2304 rate->min = rate->max = tdm_rx_cfg[TDM_SEC][TDM_0].sample_rate;
2305 break;
2306
2307 case MSM_BACKEND_DAI_SEC_TDM_TX_0:
2308 channels->min = channels->max =
2309 tdm_tx_cfg[TDM_SEC][TDM_0].channels;
2310 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2311 tdm_tx_cfg[TDM_SEC][TDM_0].bit_format);
2312 rate->min = rate->max = tdm_tx_cfg[TDM_SEC][TDM_0].sample_rate;
2313 break;
2314
2315 case MSM_BACKEND_DAI_TERT_TDM_RX_0:
2316 channels->min = channels->max =
2317 tdm_rx_cfg[TDM_TERT][TDM_0].channels;
2318 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2319 tdm_rx_cfg[TDM_TERT][TDM_0].bit_format);
2320 rate->min = rate->max = tdm_rx_cfg[TDM_TERT][TDM_0].sample_rate;
2321 break;
2322
2323 case MSM_BACKEND_DAI_TERT_TDM_TX_0:
2324 channels->min = channels->max =
2325 tdm_tx_cfg[TDM_TERT][TDM_0].channels;
2326 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2327 tdm_tx_cfg[TDM_TERT][TDM_0].bit_format);
2328 rate->min = rate->max = tdm_tx_cfg[TDM_TERT][TDM_0].sample_rate;
2329 break;
2330
2331 case MSM_BACKEND_DAI_QUAT_TDM_RX_0:
2332 channels->min = channels->max =
2333 tdm_rx_cfg[TDM_QUAT][TDM_0].channels;
2334 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2335 tdm_rx_cfg[TDM_QUAT][TDM_0].bit_format);
2336 rate->min = rate->max = tdm_rx_cfg[TDM_QUAT][TDM_0].sample_rate;
2337 break;
2338
2339 case MSM_BACKEND_DAI_QUAT_TDM_TX_0:
2340 channels->min = channels->max =
2341 tdm_tx_cfg[TDM_QUAT][TDM_0].channels;
2342 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2343 tdm_tx_cfg[TDM_QUAT][TDM_0].bit_format);
2344 rate->min = rate->max = tdm_tx_cfg[TDM_QUAT][TDM_0].sample_rate;
2345 break;
2346
Rohit Kumard1754482017-09-10 22:57:39 +05302347 case MSM_BACKEND_DAI_QUIN_TDM_RX_0:
2348 channels->min = channels->max =
2349 tdm_rx_cfg[TDM_QUIN][TDM_0].channels;
2350 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2351 tdm_rx_cfg[TDM_QUIN][TDM_0].bit_format);
2352 rate->min = rate->max = tdm_rx_cfg[TDM_QUIN][TDM_0].sample_rate;
2353 break;
2354
2355 case MSM_BACKEND_DAI_QUIN_TDM_TX_0:
2356 channels->min = channels->max =
2357 tdm_tx_cfg[TDM_QUIN][TDM_0].channels;
2358 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2359 tdm_tx_cfg[TDM_QUIN][TDM_0].bit_format);
2360 rate->min = rate->max = tdm_tx_cfg[TDM_QUIN][TDM_0].sample_rate;
2361 break;
2362
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302363 case MSM_BACKEND_DAI_AUXPCM_RX:
2364 rate->min = rate->max =
2365 aux_pcm_rx_cfg[PRIM_AUX_PCM].sample_rate;
2366 channels->min = channels->max =
2367 aux_pcm_rx_cfg[PRIM_AUX_PCM].channels;
2368 break;
2369
2370 case MSM_BACKEND_DAI_AUXPCM_TX:
2371 rate->min = rate->max =
2372 aux_pcm_tx_cfg[PRIM_AUX_PCM].sample_rate;
2373 channels->min = channels->max =
2374 aux_pcm_tx_cfg[PRIM_AUX_PCM].channels;
2375 break;
2376
2377 case MSM_BACKEND_DAI_SEC_AUXPCM_RX:
2378 rate->min = rate->max =
2379 aux_pcm_rx_cfg[SEC_AUX_PCM].sample_rate;
2380 channels->min = channels->max =
2381 aux_pcm_rx_cfg[SEC_AUX_PCM].channels;
2382 break;
2383
2384 case MSM_BACKEND_DAI_SEC_AUXPCM_TX:
2385 rate->min = rate->max =
2386 aux_pcm_tx_cfg[SEC_AUX_PCM].sample_rate;
2387 channels->min = channels->max =
2388 aux_pcm_tx_cfg[SEC_AUX_PCM].channels;
2389 break;
2390
2391 case MSM_BACKEND_DAI_TERT_AUXPCM_RX:
2392 rate->min = rate->max =
2393 aux_pcm_rx_cfg[TERT_AUX_PCM].sample_rate;
2394 channels->min = channels->max =
2395 aux_pcm_rx_cfg[TERT_AUX_PCM].channels;
2396 break;
2397
2398 case MSM_BACKEND_DAI_TERT_AUXPCM_TX:
2399 rate->min = rate->max =
2400 aux_pcm_tx_cfg[TERT_AUX_PCM].sample_rate;
2401 channels->min = channels->max =
2402 aux_pcm_tx_cfg[TERT_AUX_PCM].channels;
2403 break;
2404
2405 case MSM_BACKEND_DAI_QUAT_AUXPCM_RX:
2406 rate->min = rate->max =
2407 aux_pcm_rx_cfg[QUAT_AUX_PCM].sample_rate;
2408 channels->min = channels->max =
2409 aux_pcm_rx_cfg[QUAT_AUX_PCM].channels;
2410 break;
2411
2412 case MSM_BACKEND_DAI_QUAT_AUXPCM_TX:
2413 rate->min = rate->max =
2414 aux_pcm_tx_cfg[QUAT_AUX_PCM].sample_rate;
2415 channels->min = channels->max =
2416 aux_pcm_tx_cfg[QUAT_AUX_PCM].channels;
2417 break;
2418
Rohit Kumard1754482017-09-10 22:57:39 +05302419 case MSM_BACKEND_DAI_QUIN_AUXPCM_RX:
2420 rate->min = rate->max =
2421 aux_pcm_rx_cfg[QUIN_AUX_PCM].sample_rate;
2422 channels->min = channels->max =
2423 aux_pcm_rx_cfg[QUIN_AUX_PCM].channels;
2424 break;
2425
2426 case MSM_BACKEND_DAI_QUIN_AUXPCM_TX:
2427 rate->min = rate->max =
2428 aux_pcm_tx_cfg[QUIN_AUX_PCM].sample_rate;
2429 channels->min = channels->max =
2430 aux_pcm_tx_cfg[QUIN_AUX_PCM].channels;
2431 break;
2432
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302433 case MSM_BACKEND_DAI_PRI_MI2S_RX:
2434 rate->min = rate->max = mi2s_rx_cfg[PRIM_MI2S].sample_rate;
2435 channels->min = channels->max =
2436 mi2s_rx_cfg[PRIM_MI2S].channels;
2437 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2438 mi2s_rx_cfg[PRIM_MI2S].bit_format);
2439 break;
2440
2441 case MSM_BACKEND_DAI_PRI_MI2S_TX:
2442 rate->min = rate->max = mi2s_tx_cfg[PRIM_MI2S].sample_rate;
2443 channels->min = channels->max =
2444 mi2s_tx_cfg[PRIM_MI2S].channels;
2445 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2446 mi2s_tx_cfg[PRIM_MI2S].bit_format);
2447 break;
2448
2449 case MSM_BACKEND_DAI_SECONDARY_MI2S_RX:
2450 rate->min = rate->max = mi2s_rx_cfg[SEC_MI2S].sample_rate;
2451 channels->min = channels->max =
2452 mi2s_rx_cfg[SEC_MI2S].channels;
2453 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2454 mi2s_rx_cfg[SEC_MI2S].bit_format);
2455 break;
2456
2457 case MSM_BACKEND_DAI_SECONDARY_MI2S_TX:
2458 rate->min = rate->max = mi2s_tx_cfg[SEC_MI2S].sample_rate;
2459 channels->min = channels->max =
2460 mi2s_tx_cfg[SEC_MI2S].channels;
2461 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2462 mi2s_tx_cfg[SEC_MI2S].bit_format);
2463 break;
2464
2465 case MSM_BACKEND_DAI_TERTIARY_MI2S_RX:
2466 rate->min = rate->max = mi2s_rx_cfg[TERT_MI2S].sample_rate;
2467 channels->min = channels->max =
2468 mi2s_rx_cfg[TERT_MI2S].channels;
2469 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2470 mi2s_rx_cfg[TERT_MI2S].bit_format);
2471 break;
2472
2473 case MSM_BACKEND_DAI_TERTIARY_MI2S_TX:
2474 rate->min = rate->max = mi2s_tx_cfg[TERT_MI2S].sample_rate;
2475 channels->min = channels->max =
2476 mi2s_tx_cfg[TERT_MI2S].channels;
2477 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2478 mi2s_tx_cfg[TERT_MI2S].bit_format);
2479 break;
2480
2481 case MSM_BACKEND_DAI_QUATERNARY_MI2S_RX:
2482 rate->min = rate->max = mi2s_rx_cfg[QUAT_MI2S].sample_rate;
2483 channels->min = channels->max =
2484 mi2s_rx_cfg[QUAT_MI2S].channels;
2485 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2486 mi2s_rx_cfg[QUAT_MI2S].bit_format);
2487 break;
2488
2489 case MSM_BACKEND_DAI_QUATERNARY_MI2S_TX:
2490 rate->min = rate->max = mi2s_tx_cfg[QUAT_MI2S].sample_rate;
2491 channels->min = channels->max =
2492 mi2s_tx_cfg[QUAT_MI2S].channels;
2493 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2494 mi2s_tx_cfg[QUAT_MI2S].bit_format);
2495 break;
2496
Rohit Kumard1754482017-09-10 22:57:39 +05302497 case MSM_BACKEND_DAI_QUINARY_MI2S_RX:
2498 rate->min = rate->max = mi2s_rx_cfg[QUIN_MI2S].sample_rate;
2499 channels->min = channels->max =
2500 mi2s_rx_cfg[QUIN_MI2S].channels;
2501 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2502 mi2s_rx_cfg[QUIN_MI2S].bit_format);
2503 break;
2504
2505 case MSM_BACKEND_DAI_QUINARY_MI2S_TX:
2506 rate->min = rate->max = mi2s_tx_cfg[QUIN_MI2S].sample_rate;
2507 channels->min = channels->max =
2508 mi2s_tx_cfg[QUIN_MI2S].channels;
2509 param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
2510 mi2s_tx_cfg[QUIN_MI2S].bit_format);
2511 break;
2512
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302513 default:
2514 rate->min = rate->max = SAMPLING_RATE_48KHZ;
2515 break;
2516 }
2517 return rc;
2518}
2519EXPORT_SYMBOL(msm_common_be_hw_params_fixup);
2520
2521/**
2522 * msm_aux_pcm_snd_startup - startup ops of auxpcm.
2523 *
2524 * @substream: PCM stream pointer of associated backend dailink
2525 *
2526 * Returns 0 on success or -EINVAL on error.
2527 */
2528int msm_aux_pcm_snd_startup(struct snd_pcm_substream *substream)
2529{
2530 struct snd_soc_pcm_runtime *rtd = substream->private_data;
2531
2532 dev_dbg(rtd->card->dev,
2533 "%s: substream = %s stream = %d, dai name %s, dai ID %d\n",
2534 __func__, substream->name, substream->stream,
2535 rtd->cpu_dai->name, rtd->cpu_dai->id);
2536
2537 return 0;
2538}
2539EXPORT_SYMBOL(msm_aux_pcm_snd_startup);
2540
2541/**
2542 * msm_aux_pcm_snd_shutdown - shutdown ops of auxpcm.
2543 *
2544 * @substream: PCM stream pointer of associated backend dailink
2545 */
2546void msm_aux_pcm_snd_shutdown(struct snd_pcm_substream *substream)
2547{
2548 struct snd_soc_pcm_runtime *rtd = substream->private_data;
2549
2550 dev_dbg(rtd->card->dev,
2551 "%s: substream = %s stream = %d, dai name %s, dai ID %d\n",
2552 __func__,
2553 substream->name, substream->stream,
2554 rtd->cpu_dai->name, rtd->cpu_dai->id);
2555}
2556EXPORT_SYMBOL(msm_aux_pcm_snd_shutdown);
2557
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05302558static int msm_get_port_id(int id)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302559{
2560 int afe_port_id;
2561
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05302562 switch (id) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302563 case MSM_BACKEND_DAI_PRI_MI2S_RX:
2564 afe_port_id = AFE_PORT_ID_PRIMARY_MI2S_RX;
2565 break;
2566 case MSM_BACKEND_DAI_PRI_MI2S_TX:
2567 afe_port_id = AFE_PORT_ID_PRIMARY_MI2S_TX;
2568 break;
2569 case MSM_BACKEND_DAI_SECONDARY_MI2S_RX:
2570 afe_port_id = AFE_PORT_ID_SECONDARY_MI2S_RX;
2571 break;
2572 case MSM_BACKEND_DAI_SECONDARY_MI2S_TX:
2573 afe_port_id = AFE_PORT_ID_SECONDARY_MI2S_TX;
2574 break;
2575 case MSM_BACKEND_DAI_TERTIARY_MI2S_RX:
2576 afe_port_id = AFE_PORT_ID_TERTIARY_MI2S_RX;
2577 break;
2578 case MSM_BACKEND_DAI_TERTIARY_MI2S_TX:
2579 afe_port_id = AFE_PORT_ID_TERTIARY_MI2S_TX;
2580 break;
2581 case MSM_BACKEND_DAI_QUATERNARY_MI2S_RX:
2582 afe_port_id = AFE_PORT_ID_QUATERNARY_MI2S_RX;
2583 break;
2584 case MSM_BACKEND_DAI_QUATERNARY_MI2S_TX:
2585 afe_port_id = AFE_PORT_ID_QUATERNARY_MI2S_TX;
2586 break;
Rohit Kumard1754482017-09-10 22:57:39 +05302587 case MSM_BACKEND_DAI_QUINARY_MI2S_RX:
2588 afe_port_id = AFE_PORT_ID_QUINARY_MI2S_RX;
2589 break;
2590 case MSM_BACKEND_DAI_QUINARY_MI2S_TX:
2591 afe_port_id = AFE_PORT_ID_QUINARY_MI2S_TX;
2592 break;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302593 default:
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05302594 pr_err("%s: Invalid id: %d\n", __func__, id);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302595 afe_port_id = -EINVAL;
2596 }
2597
2598 return afe_port_id;
2599}
2600
2601static u32 get_mi2s_bits_per_sample(u32 bit_format)
2602{
2603 u32 bit_per_sample;
2604
2605 switch (bit_format) {
2606 case SNDRV_PCM_FORMAT_S32_LE:
2607 case SNDRV_PCM_FORMAT_S24_3LE:
2608 case SNDRV_PCM_FORMAT_S24_LE:
2609 bit_per_sample = 32;
2610 break;
2611 case SNDRV_PCM_FORMAT_S16_LE:
2612 default:
2613 bit_per_sample = 16;
2614 break;
2615 }
2616
2617 return bit_per_sample;
2618}
2619
2620static void update_mi2s_clk_val(int dai_id, int stream)
2621{
2622 u32 bit_per_sample;
2623
2624 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
2625 bit_per_sample =
2626 get_mi2s_bits_per_sample(mi2s_rx_cfg[dai_id].bit_format);
2627 mi2s_clk[dai_id].clk_freq_in_hz =
2628 mi2s_rx_cfg[dai_id].sample_rate * 2 * bit_per_sample;
2629 } else {
2630 bit_per_sample =
2631 get_mi2s_bits_per_sample(mi2s_tx_cfg[dai_id].bit_format);
2632 mi2s_clk[dai_id].clk_freq_in_hz =
2633 mi2s_tx_cfg[dai_id].sample_rate * 2 * bit_per_sample;
2634 }
2635}
2636
2637static int msm_mi2s_set_sclk(struct snd_pcm_substream *substream, bool enable)
2638{
2639 int ret = 0;
2640 struct snd_soc_pcm_runtime *rtd = substream->private_data;
2641 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
2642 int port_id = 0;
2643 int index = cpu_dai->id;
2644
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05302645 port_id = msm_get_port_id(rtd->dai_link->id);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302646 if (port_id < 0) {
2647 dev_err(rtd->card->dev, "%s: Invalid port_id\n", __func__);
2648 ret = port_id;
2649 goto done;
2650 }
2651
2652 if (enable) {
2653 update_mi2s_clk_val(index, substream->stream);
2654 dev_dbg(rtd->card->dev, "%s: clock rate %ul\n", __func__,
2655 mi2s_clk[index].clk_freq_in_hz);
2656 }
2657
2658 mi2s_clk[index].enable = enable;
2659 ret = afe_set_lpass_clock_v2(port_id,
2660 &mi2s_clk[index]);
2661 if (ret < 0) {
2662 dev_err(rtd->card->dev,
2663 "%s: afe lpass clock failed for port 0x%x , err:%d\n",
2664 __func__, port_id, ret);
2665 goto done;
2666 }
2667
2668done:
2669 return ret;
2670}
2671
2672/**
2673 * msm_mi2s_snd_startup - startup ops of mi2s.
2674 *
2675 * @substream: PCM stream pointer of associated backend dailink
2676 *
2677 * Returns 0 on success or -EINVAL on error.
2678 */
2679int msm_mi2s_snd_startup(struct snd_pcm_substream *substream)
2680{
2681 int ret = 0;
2682 struct snd_soc_pcm_runtime *rtd = substream->private_data;
2683 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05302684 int port_id = msm_get_port_id(rtd->dai_link->id);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302685 int index = cpu_dai->id;
2686 unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS;
Rohit Kumaraf88e4c2017-10-04 13:47:10 +05302687 struct msm_asoc_mach_data *pdata =
2688 snd_soc_card_get_drvdata(rtd->card);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302689
2690 dev_dbg(rtd->card->dev,
2691 "%s: substream = %s stream = %d, dai name %s, dai ID %d\n",
2692 __func__, substream->name, substream->stream,
2693 cpu_dai->name, cpu_dai->id);
2694
Rohit Kumard1754482017-09-10 22:57:39 +05302695 if (index < PRIM_MI2S || index >= MI2S_MAX) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302696 ret = -EINVAL;
2697 dev_err(rtd->card->dev,
2698 "%s: CPU DAI id (%d) out of range\n",
2699 __func__, cpu_dai->id);
2700 goto done;
2701 }
2702 /*
2703 * Muxtex protection in case the same MI2S
2704 * interface using for both TX and RX so
2705 * that the same clock won't be enable twice.
2706 */
2707 mutex_lock(&mi2s_intf_conf[index].lock);
2708 if (++mi2s_intf_conf[index].ref_cnt == 1) {
2709 /* Check if msm needs to provide the clock to the interface */
2710 if (!mi2s_intf_conf[index].msm_is_mi2s_master) {
2711 mi2s_clk[index].clk_id = mi2s_ebit_clk[index];
2712 fmt = SND_SOC_DAIFMT_CBM_CFM;
2713 }
2714 ret = msm_mi2s_set_sclk(substream, true);
2715 if (ret < 0) {
2716 dev_err(rtd->card->dev,
2717 "%s: afe lpass clock failed to enable MI2S clock, err:%d\n",
2718 __func__, ret);
2719 goto clean_up;
2720 }
2721 ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
2722 if (ret < 0) {
2723 dev_err(rtd->card->dev,
2724 "%s: set fmt cpu dai failed for MI2S (%d), err:%d\n",
2725 __func__, index, ret);
2726 goto clk_off;
2727 }
2728 if (mi2s_intf_conf[index].msm_is_ext_mclk) {
2729 mi2s_mclk[index].enable = 1;
2730 pr_debug("%s: Enabling mclk, clk_freq_in_hz = %u\n",
2731 __func__, mi2s_mclk[index].clk_freq_in_hz);
2732 ret = afe_set_lpass_clock_v2(port_id,
2733 &mi2s_mclk[index]);
2734 if (ret < 0) {
2735 pr_err("%s: afe lpass mclk failed, err:%d\n",
2736 __func__, ret);
2737 goto clk_off;
2738 }
2739 }
Rohit Kumaraf88e4c2017-10-04 13:47:10 +05302740 if (pdata->mi2s_gpio_p[index])
2741 msm_cdc_pinctrl_select_active_state(
2742 pdata->mi2s_gpio_p[index]);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302743 }
2744 mutex_unlock(&mi2s_intf_conf[index].lock);
2745 return 0;
2746clk_off:
2747 if (ret < 0)
2748 msm_mi2s_set_sclk(substream, false);
2749clean_up:
2750 if (ret < 0)
2751 mi2s_intf_conf[index].ref_cnt--;
2752 mutex_unlock(&mi2s_intf_conf[index].lock);
2753done:
2754 return ret;
2755}
2756EXPORT_SYMBOL(msm_mi2s_snd_startup);
2757
2758/**
2759 * msm_mi2s_snd_shutdown - shutdown ops of mi2s.
2760 *
2761 * @substream: PCM stream pointer of associated backend dailink
2762 */
2763void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream)
2764{
2765 int ret;
2766 struct snd_soc_pcm_runtime *rtd = substream->private_data;
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05302767 int port_id = msm_get_port_id(rtd->dai_link->id);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302768 int index = rtd->cpu_dai->id;
Rohit Kumaraf88e4c2017-10-04 13:47:10 +05302769 struct msm_asoc_mach_data *pdata =
2770 snd_soc_card_get_drvdata(rtd->card);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302771
2772 pr_debug("%s(): substream = %s stream = %d\n", __func__,
2773 substream->name, substream->stream);
Rohit Kumard1754482017-09-10 22:57:39 +05302774 if (index < PRIM_MI2S || index >= MI2S_MAX) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302775 pr_err("%s:invalid MI2S DAI(%d)\n", __func__, index);
2776 return;
2777 }
2778
2779 mutex_lock(&mi2s_intf_conf[index].lock);
2780 if (--mi2s_intf_conf[index].ref_cnt == 0) {
Rohit Kumaraf88e4c2017-10-04 13:47:10 +05302781 if (pdata->mi2s_gpio_p[index])
2782 msm_cdc_pinctrl_select_sleep_state(
2783 pdata->mi2s_gpio_p[index]);
2784
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302785 ret = msm_mi2s_set_sclk(substream, false);
2786 if (ret < 0) {
2787 pr_err("%s:clock disable failed for MI2S (%d); ret=%d\n",
2788 __func__, index, ret);
2789 mi2s_intf_conf[index].ref_cnt++;
2790 }
2791 if (mi2s_intf_conf[index].msm_is_ext_mclk) {
2792 mi2s_mclk[index].enable = 0;
2793 pr_debug("%s: Disabling mclk, clk_freq_in_hz = %u\n",
2794 __func__, mi2s_mclk[index].clk_freq_in_hz);
2795 ret = afe_set_lpass_clock_v2(port_id,
2796 &mi2s_mclk[index]);
2797 if (ret < 0) {
2798 pr_err("%s: mclk disable failed for MCLK (%d); ret=%d\n",
2799 __func__, index, ret);
2800 }
2801 }
2802 }
2803 mutex_unlock(&mi2s_intf_conf[index].lock);
2804}
2805EXPORT_SYMBOL(msm_mi2s_snd_shutdown);
2806
2807/* Validate whether US EU switch is present or not */
2808static int msm_prepare_us_euro(struct snd_soc_card *card)
2809{
2810 struct msm_asoc_mach_data *pdata =
2811 snd_soc_card_get_drvdata(card);
2812 int ret = 0;
2813
2814 if (pdata->us_euro_gpio >= 0) {
2815 dev_dbg(card->dev, "%s: us_euro gpio request %d", __func__,
2816 pdata->us_euro_gpio);
2817 ret = gpio_request(pdata->us_euro_gpio, "TASHA_CODEC_US_EURO");
2818 if (ret) {
2819 dev_err(card->dev,
2820 "%s: Failed to request codec US/EURO gpio %d error %d\n",
2821 __func__, pdata->us_euro_gpio, ret);
2822 }
2823 }
2824
2825 return ret;
2826}
2827
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05302828static bool msm_swap_gnd_mic(struct snd_soc_codec *codec, bool active)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302829{
2830 struct snd_soc_card *card = codec->component.card;
2831 struct msm_asoc_mach_data *pdata =
2832 snd_soc_card_get_drvdata(card);
2833 int value = 0;
2834
2835 if (pdata->us_euro_gpio_p) {
2836 value = msm_cdc_pinctrl_get_state(pdata->us_euro_gpio_p);
2837 if (value)
2838 msm_cdc_pinctrl_select_sleep_state(
2839 pdata->us_euro_gpio_p);
2840 else
2841 msm_cdc_pinctrl_select_active_state(
2842 pdata->us_euro_gpio_p);
2843 } else if (pdata->us_euro_gpio >= 0) {
2844 value = gpio_get_value_cansleep(pdata->us_euro_gpio);
2845 gpio_set_value_cansleep(pdata->us_euro_gpio, !value);
2846 }
2847 pr_debug("%s: swap select switch %d to %d\n", __func__, value, !value);
2848 return true;
2849}
2850
2851static int msm_populate_dai_link_component_of_node(
2852 struct msm_asoc_mach_data *pdata,
2853 struct snd_soc_card *card)
2854{
2855 int i, index, ret = 0;
2856 struct device *cdev = card->dev;
2857 struct snd_soc_dai_link *dai_link = card->dai_link;
2858 struct device_node *phandle;
2859
2860 if (!cdev) {
2861 pr_err("%s: Sound card device memory NULL\n", __func__);
2862 return -ENODEV;
2863 }
2864
2865 for (i = 0; i < card->num_links; i++) {
2866 if (dai_link[i].platform_of_node && dai_link[i].cpu_of_node)
2867 continue;
2868
2869 /* populate platform_of_node for snd card dai links */
2870 if (dai_link[i].platform_name &&
2871 !dai_link[i].platform_of_node) {
2872 index = of_property_match_string(cdev->of_node,
2873 "asoc-platform-names",
2874 dai_link[i].platform_name);
2875 if (index < 0) {
2876 pr_err("%s: No match found for platform name: %s\n",
2877 __func__, dai_link[i].platform_name);
2878 ret = index;
2879 goto cpu_dai;
2880 }
2881 phandle = of_parse_phandle(cdev->of_node,
2882 "asoc-platform",
2883 index);
2884 if (!phandle) {
2885 pr_err("%s: retrieving phandle for platform %s, index %d failed\n",
2886 __func__, dai_link[i].platform_name,
2887 index);
2888 ret = -ENODEV;
2889 goto err;
2890 }
2891 dai_link[i].platform_of_node = phandle;
2892 dai_link[i].platform_name = NULL;
2893 }
2894cpu_dai:
2895 /* populate cpu_of_node for snd card dai links */
2896 if (dai_link[i].cpu_dai_name && !dai_link[i].cpu_of_node) {
2897 index = of_property_match_string(cdev->of_node,
2898 "asoc-cpu-names",
2899 dai_link[i].cpu_dai_name);
2900 if (index < 0)
2901 goto codec_dai;
2902 phandle = of_parse_phandle(cdev->of_node, "asoc-cpu",
2903 index);
2904 if (!phandle) {
2905 pr_err("%s: retrieving phandle for cpu dai %s failed\n",
2906 __func__, dai_link[i].cpu_dai_name);
2907 ret = -ENODEV;
2908 goto err;
2909 }
2910 dai_link[i].cpu_of_node = phandle;
2911 dai_link[i].cpu_dai_name = NULL;
2912 }
2913codec_dai:
2914 /* populate codec_of_node for snd card dai links */
2915 if (dai_link[i].codec_name && !dai_link[i].codec_of_node) {
2916 index = of_property_match_string(cdev->of_node,
2917 "asoc-codec-names",
2918 dai_link[i].codec_name);
2919 if (index < 0)
2920 continue;
2921 phandle = of_parse_phandle(cdev->of_node, "asoc-codec",
2922 index);
2923 if (!phandle) {
2924 pr_err("%s: retrieving phandle for codec dai %s failed\n",
2925 __func__, dai_link[i].codec_name);
2926 ret = -ENODEV;
2927 goto err;
2928 }
2929 dai_link[i].codec_of_node = phandle;
2930 dai_link[i].codec_name = NULL;
2931 }
2932 if (pdata->snd_card_val == INT_SND_CARD) {
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05302933 if ((dai_link[i].id ==
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302934 MSM_BACKEND_DAI_INT0_MI2S_RX) ||
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05302935 (dai_link[i].id ==
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302936 MSM_BACKEND_DAI_INT1_MI2S_RX) ||
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05302937 (dai_link[i].id ==
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302938 MSM_BACKEND_DAI_INT2_MI2S_TX) ||
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05302939 (dai_link[i].id ==
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302940 MSM_BACKEND_DAI_INT3_MI2S_TX)) {
2941 index = of_property_match_string(cdev->of_node,
2942 "asoc-codec-names",
2943 MSM_INT_DIGITAL_CODEC);
2944 phandle = of_parse_phandle(cdev->of_node,
2945 "asoc-codec",
2946 index);
2947 dai_link[i].codecs[DIG_CDC].of_node = phandle;
2948 index = of_property_match_string(cdev->of_node,
2949 "asoc-codec-names",
2950 PMIC_INT_ANALOG_CODEC);
2951 phandle = of_parse_phandle(cdev->of_node,
2952 "asoc-codec",
2953 index);
2954 dai_link[i].codecs[ANA_CDC].of_node = phandle;
2955 }
2956 }
2957 }
2958err:
2959 return ret;
2960}
2961
2962static int msm_wsa881x_init(struct snd_soc_component *component)
2963{
2964 u8 spkleft_ports[WSA881X_MAX_SWR_PORTS] = {100, 101, 102, 106};
2965 u8 spkright_ports[WSA881X_MAX_SWR_PORTS] = {103, 104, 105, 107};
2966 unsigned int ch_rate[WSA881X_MAX_SWR_PORTS] = {2400, 600, 300, 1200};
2967 unsigned int ch_mask[WSA881X_MAX_SWR_PORTS] = {0x1, 0xF, 0x3, 0x3};
2968 struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
2969 struct msm_asoc_mach_data *pdata;
2970 struct snd_soc_dapm_context *dapm =
2971 snd_soc_codec_get_dapm(codec);
2972
2973 if (!codec) {
2974 pr_err("%s codec is NULL\n", __func__);
2975 return -EINVAL;
2976 }
2977
2978 if (!strcmp(component->name_prefix, "SpkrLeft")) {
2979 dev_dbg(codec->dev, "%s: setting left ch map to codec %s\n",
2980 __func__, codec->component.name);
2981 wsa881x_set_channel_map(codec, &spkleft_ports[0],
2982 WSA881X_MAX_SWR_PORTS, &ch_mask[0],
2983 &ch_rate[0]);
2984 if (dapm->component) {
2985 snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft IN");
2986 snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft SPKR");
2987 }
2988 } else if (!strcmp(component->name_prefix, "SpkrRight")) {
2989 dev_dbg(codec->dev, "%s: setting right ch map to codec %s\n",
2990 __func__, codec->component.name);
2991 wsa881x_set_channel_map(codec, &spkright_ports[0],
2992 WSA881X_MAX_SWR_PORTS, &ch_mask[0],
2993 &ch_rate[0]);
2994 if (dapm->component) {
2995 snd_soc_dapm_ignore_suspend(dapm, "SpkrRight IN");
2996 snd_soc_dapm_ignore_suspend(dapm, "SpkrRight SPKR");
2997 }
2998 } else {
2999 dev_err(codec->dev, "%s: wrong codec name %s\n", __func__,
3000 codec->component.name);
3001 return -EINVAL;
3002 }
3003
3004
3005 pdata = snd_soc_card_get_drvdata(component->card);
3006 if (pdata && pdata->codec_root)
3007 wsa881x_codec_info_create_codec_entry(pdata->codec_root,
3008 codec);
3009 return 0;
3010}
3011
3012
3013static int msm_init_wsa_dev(struct platform_device *pdev,
3014 struct snd_soc_card *card)
3015{
3016 struct device_node *wsa_of_node;
3017 u32 wsa_max_devs;
3018 u32 wsa_dev_cnt;
3019 char *dev_name_str = NULL;
3020 struct msm_wsa881x_dev_info *wsa881x_dev_info;
3021 const char *wsa_auxdev_name_prefix[1];
3022 int found = 0;
3023 int i;
3024 int ret;
3025
3026 /* Get maximum WSA device count for this platform */
3027 ret = of_property_read_u32(pdev->dev.of_node,
3028 "qcom,wsa-max-devs", &wsa_max_devs);
3029 if (ret) {
3030 dev_dbg(&pdev->dev,
3031 "%s: wsa-max-devs property missing in DT %s, ret = %d\n",
3032 __func__, pdev->dev.of_node->full_name, ret);
3033 goto err_dt;
3034 }
3035 if (wsa_max_devs == 0) {
3036 dev_warn(&pdev->dev,
3037 "%s: Max WSA devices is 0 for this target?\n",
3038 __func__);
3039 goto err_dt;
3040 }
3041
3042 /* Get count of WSA device phandles for this platform */
3043 wsa_dev_cnt = of_count_phandle_with_args(pdev->dev.of_node,
3044 "qcom,wsa-devs", NULL);
3045 if (wsa_dev_cnt == -ENOENT) {
3046 dev_warn(&pdev->dev, "%s: No wsa device defined in DT.\n",
3047 __func__);
3048 goto err_dt;
3049 } else if (wsa_dev_cnt <= 0) {
3050 dev_err(&pdev->dev,
3051 "%s: Error reading wsa device from DT. wsa_dev_cnt = %d\n",
3052 __func__, wsa_dev_cnt);
3053 ret = -EINVAL;
3054 goto err_dt;
3055 }
3056
3057 /*
3058 * Expect total phandles count to be NOT less than maximum possible
3059 * WSA count. However, if it is less, then assign same value to
3060 * max count as well.
3061 */
3062 if (wsa_dev_cnt < wsa_max_devs) {
3063 dev_dbg(&pdev->dev,
3064 "%s: wsa_max_devs = %d cannot exceed wsa_dev_cnt = %d\n",
3065 __func__, wsa_max_devs, wsa_dev_cnt);
3066 wsa_max_devs = wsa_dev_cnt;
3067 }
3068
3069 /* Make sure prefix string passed for each WSA device */
3070 ret = of_property_count_strings(pdev->dev.of_node,
3071 "qcom,wsa-aux-dev-prefix");
3072 if (ret != wsa_dev_cnt) {
3073 dev_err(&pdev->dev,
3074 "%s: expecting %d wsa prefix. Defined only %d in DT\n",
3075 __func__, wsa_dev_cnt, ret);
3076 ret = -EINVAL;
3077 goto err_dt;
3078 }
3079
3080 /*
3081 * Alloc mem to store phandle and index info of WSA device, if already
3082 * registered with ALSA core
3083 */
3084 wsa881x_dev_info = devm_kcalloc(&pdev->dev, wsa_max_devs,
3085 sizeof(struct msm_wsa881x_dev_info),
3086 GFP_KERNEL);
3087 if (!wsa881x_dev_info) {
3088 ret = -ENOMEM;
3089 goto err_mem;
3090 }
3091
3092 /*
3093 * search and check whether all WSA devices are already
3094 * registered with ALSA core or not. If found a node, store
3095 * the node and the index in a local array of struct for later
3096 * use.
3097 */
3098 for (i = 0; i < wsa_dev_cnt; i++) {
3099 wsa_of_node = of_parse_phandle(pdev->dev.of_node,
3100 "qcom,wsa-devs", i);
3101 if (unlikely(!wsa_of_node)) {
3102 /* we should not be here */
3103 dev_err(&pdev->dev,
3104 "%s: wsa dev node is not present\n",
3105 __func__);
3106 ret = -EINVAL;
3107 goto err_dev_node;
3108 }
3109 if (soc_find_component(wsa_of_node, NULL)) {
3110 /* WSA device registered with ALSA core */
3111 wsa881x_dev_info[found].of_node = wsa_of_node;
3112 wsa881x_dev_info[found].index = i;
3113 found++;
3114 if (found == wsa_max_devs)
3115 break;
3116 }
3117 }
3118
3119 if (found < wsa_max_devs) {
3120 dev_dbg(&pdev->dev,
3121 "%s: failed to find %d components. Found only %d\n",
3122 __func__, wsa_max_devs, found);
3123 return -EPROBE_DEFER;
3124 }
3125 dev_info(&pdev->dev,
3126 "%s: found %d wsa881x devices registered with ALSA core\n",
3127 __func__, found);
3128
3129 card->num_aux_devs = wsa_max_devs;
3130 card->num_configs = wsa_max_devs;
3131
3132 /* Alloc array of AUX devs struct */
3133 msm_aux_dev = devm_kcalloc(&pdev->dev, card->num_aux_devs,
3134 sizeof(struct snd_soc_aux_dev),
3135 GFP_KERNEL);
3136 if (!msm_aux_dev) {
3137 ret = -ENOMEM;
3138 goto err_auxdev_mem;
3139 }
3140
3141 /* Alloc array of codec conf struct */
3142 msm_codec_conf = devm_kcalloc(&pdev->dev, card->num_aux_devs,
3143 sizeof(struct snd_soc_codec_conf),
3144 GFP_KERNEL);
3145 if (!msm_codec_conf) {
3146 ret = -ENOMEM;
3147 goto err_codec_conf;
3148 }
3149
3150 for (i = 0; i < card->num_aux_devs; i++) {
3151 dev_name_str = devm_kzalloc(&pdev->dev, DEV_NAME_STR_LEN,
3152 GFP_KERNEL);
3153 if (!dev_name_str) {
3154 ret = -ENOMEM;
3155 goto err_dev_str;
3156 }
3157
3158 ret = of_property_read_string_index(pdev->dev.of_node,
3159 "qcom,wsa-aux-dev-prefix",
3160 wsa881x_dev_info[i].index,
3161 wsa_auxdev_name_prefix);
3162 if (ret) {
3163 dev_err(&pdev->dev,
3164 "%s: failed to read wsa aux dev prefix, ret = %d\n",
3165 __func__, ret);
3166 ret = -EINVAL;
3167 goto err_dt_prop;
3168 }
3169
3170 snprintf(dev_name_str, strlen("wsa881x.%d"), "wsa881x.%d", i);
3171 msm_aux_dev[i].name = dev_name_str;
3172 msm_aux_dev[i].codec_name = NULL;
3173 msm_aux_dev[i].codec_of_node =
3174 wsa881x_dev_info[i].of_node;
3175 msm_aux_dev[i].init = msm_wsa881x_init;
3176 msm_codec_conf[i].dev_name = NULL;
3177 msm_codec_conf[i].name_prefix = wsa_auxdev_name_prefix[0];
3178 msm_codec_conf[i].of_node = wsa881x_dev_info[i].of_node;
3179 }
3180 card->codec_conf = msm_codec_conf;
3181 card->aux_dev = msm_aux_dev;
3182
3183 return 0;
3184
3185err_dt_prop:
3186 devm_kfree(&pdev->dev, dev_name_str);
3187err_dev_str:
3188 devm_kfree(&pdev->dev, msm_codec_conf);
3189err_codec_conf:
3190 devm_kfree(&pdev->dev, msm_aux_dev);
3191err_auxdev_mem:
3192err_dev_node:
3193 devm_kfree(&pdev->dev, wsa881x_dev_info);
3194err_mem:
3195err_dt:
3196 return ret;
3197}
3198
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303199static void i2s_auxpcm_init(struct platform_device *pdev)
3200{
3201 int count;
3202 u32 mi2s_master_slave[MI2S_MAX];
3203 u32 mi2s_ext_mclk[MI2S_MAX];
3204 int ret;
3205
3206 for (count = 0; count < MI2S_MAX; count++) {
3207 mutex_init(&mi2s_intf_conf[count].lock);
3208 mi2s_intf_conf[count].ref_cnt = 0;
3209 }
3210
3211 ret = of_property_read_u32_array(pdev->dev.of_node,
3212 "qcom,msm-mi2s-master",
3213 mi2s_master_slave, MI2S_MAX);
3214 if (ret) {
3215 dev_dbg(&pdev->dev, "%s: no qcom,msm-mi2s-master in DT node\n",
3216 __func__);
3217 } else {
3218 for (count = 0; count < MI2S_MAX; count++) {
3219 mi2s_intf_conf[count].msm_is_mi2s_master =
3220 mi2s_master_slave[count];
3221 }
3222 }
3223
3224 ret = of_property_read_u32_array(pdev->dev.of_node,
3225 "qcom,msm-mi2s-ext-mclk",
3226 mi2s_ext_mclk, MI2S_MAX);
3227 if (ret) {
3228 dev_dbg(&pdev->dev, "%s: no qcom,msm-mi2s-ext-mclk in DT node\n",
3229 __func__);
3230 } else {
3231 for (count = 0; count < MI2S_MAX; count++)
3232 mi2s_intf_conf[count].msm_is_ext_mclk =
3233 mi2s_ext_mclk[count];
3234 }
3235}
3236
3237static const struct of_device_id sdm660_asoc_machine_of_match[] = {
3238 { .compatible = "qcom,sdm660-asoc-snd",
3239 .data = "internal_codec"},
3240 { .compatible = "qcom,sdm660-asoc-snd-tasha",
3241 .data = "tasha_codec"},
3242 { .compatible = "qcom,sdm660-asoc-snd-tavil",
3243 .data = "tavil_codec"},
Laxminath Kasam38070be2017-08-17 18:21:59 +05303244 { .compatible = "qcom,sdm670-asoc-snd",
3245 .data = "internal_codec"},
3246 { .compatible = "qcom,sdm670-asoc-snd-tasha",
3247 .data = "tasha_codec"},
3248 { .compatible = "qcom,sdm670-asoc-snd-tavil",
3249 .data = "tavil_codec"},
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303250 {},
3251};
3252
3253static int msm_asoc_machine_probe(struct platform_device *pdev)
3254{
3255 struct snd_soc_card *card = NULL;
3256 struct msm_asoc_mach_data *pdata = NULL;
3257 const char *mclk = "qcom,msm-mclk-freq";
3258 int ret = -EINVAL, id;
3259 const struct of_device_id *match;
3260
3261 pdata = devm_kzalloc(&pdev->dev,
3262 sizeof(struct msm_asoc_mach_data),
3263 GFP_KERNEL);
3264 if (!pdata)
3265 return -ENOMEM;
3266
Laxminath Kasam38070be2017-08-17 18:21:59 +05303267 msm_set_codec_reg_done(false);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303268 match = of_match_node(sdm660_asoc_machine_of_match,
3269 pdev->dev.of_node);
3270 if (!match)
3271 goto err;
3272
3273 ret = of_property_read_u32(pdev->dev.of_node, mclk, &id);
3274 if (ret) {
3275 dev_err(&pdev->dev,
3276 "%s: missing %s in dt node\n", __func__, mclk);
3277 id = DEFAULT_MCLK_RATE;
3278 }
3279 pdata->mclk_freq = id;
3280
3281 if (!strcmp(match->data, "tasha_codec") ||
3282 !strcmp(match->data, "tavil_codec")) {
3283 if (!strcmp(match->data, "tasha_codec"))
3284 pdata->snd_card_val = EXT_SND_CARD_TASHA;
3285 else
3286 pdata->snd_card_val = EXT_SND_CARD_TAVIL;
3287 ret = msm_ext_cdc_init(pdev, pdata, &card, &mbhc_cfg);
3288 if (ret)
3289 goto err;
3290 } else if (!strcmp(match->data, "internal_codec")) {
3291 pdata->snd_card_val = INT_SND_CARD;
3292 ret = msm_int_cdc_init(pdev, pdata, &card, &mbhc_cfg);
3293 if (ret)
3294 goto err;
3295 } else {
3296 dev_err(&pdev->dev,
3297 "%s: Not a matching DT sound node\n", __func__);
3298 goto err;
3299 }
3300 if (!card)
3301 goto err;
3302
3303 if (pdata->snd_card_val == INT_SND_CARD) {
3304 /*reading the gpio configurations from dtsi file*/
3305 pdata->pdm_gpio_p = of_parse_phandle(pdev->dev.of_node,
3306 "qcom,cdc-pdm-gpios", 0);
3307 pdata->comp_gpio_p = of_parse_phandle(pdev->dev.of_node,
3308 "qcom,cdc-comp-gpios", 0);
3309 pdata->dmic_gpio_p = of_parse_phandle(pdev->dev.of_node,
3310 "qcom,cdc-dmic-gpios", 0);
3311 pdata->ext_spk_gpio_p = of_parse_phandle(pdev->dev.of_node,
3312 "qcom,cdc-ext-spk-gpios", 0);
3313 }
3314
Rohit Kumaraf88e4c2017-10-04 13:47:10 +05303315 pdata->mi2s_gpio_p[PRIM_MI2S] = of_parse_phandle(pdev->dev.of_node,
3316 "qcom,pri-mi2s-gpios", 0);
3317 pdata->mi2s_gpio_p[SEC_MI2S] = of_parse_phandle(pdev->dev.of_node,
3318 "qcom,sec-mi2s-gpios", 0);
3319 pdata->mi2s_gpio_p[TERT_MI2S] = of_parse_phandle(pdev->dev.of_node,
3320 "qcom,tert-mi2s-gpios", 0);
3321 pdata->mi2s_gpio_p[QUAT_MI2S] = of_parse_phandle(pdev->dev.of_node,
3322 "qcom,quat-mi2s-gpios", 0);
3323 pdata->mi2s_gpio_p[QUIN_MI2S] = of_parse_phandle(pdev->dev.of_node,
3324 "qcom,quin-mi2s-gpios", 0);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303325 /*
3326 * Parse US-Euro gpio info from DT. Report no error if us-euro
3327 * entry is not found in DT file as some targets do not support
3328 * US-Euro detection
3329 */
3330 pdata->us_euro_gpio = of_get_named_gpio(pdev->dev.of_node,
3331 "qcom,us-euro-gpios", 0);
3332 if (!gpio_is_valid(pdata->us_euro_gpio))
3333 pdata->us_euro_gpio_p = of_parse_phandle(pdev->dev.of_node,
3334 "qcom,us-euro-gpios", 0);
3335 if (!gpio_is_valid(pdata->us_euro_gpio) && (!pdata->us_euro_gpio_p)) {
3336 dev_dbg(&pdev->dev, "property %s not detected in node %s",
3337 "qcom,us-euro-gpios", pdev->dev.of_node->full_name);
3338 } else {
3339 dev_dbg(&pdev->dev, "%s detected",
3340 "qcom,us-euro-gpios");
3341 mbhc_cfg.swap_gnd_mic = msm_swap_gnd_mic;
3342 }
3343
3344 ret = msm_prepare_us_euro(card);
3345 if (ret)
3346 dev_dbg(&pdev->dev, "msm_prepare_us_euro failed (%d)\n",
3347 ret);
3348
3349 i2s_auxpcm_init(pdev);
3350
3351 ret = snd_soc_of_parse_audio_routing(card, "qcom,audio-routing");
3352 if (ret)
3353 goto err;
3354
3355 ret = msm_populate_dai_link_component_of_node(pdata, card);
3356 if (ret) {
3357 ret = -EPROBE_DEFER;
3358 goto err;
3359 }
3360
3361 if (!of_property_read_bool(pdev->dev.of_node, "qcom,wsa-disable")) {
3362 ret = msm_init_wsa_dev(pdev, card);
3363 if (ret)
3364 goto err;
3365 }
3366
3367 ret = devm_snd_soc_register_card(&pdev->dev, card);
3368 if (ret == -EPROBE_DEFER) {
3369 if (codec_reg_done) {
3370 /*
3371 * return failure as EINVAL since other codec
3372 * registered sound card successfully.
3373 * This avoids any further probe calls.
3374 */
3375 ret = -EINVAL;
3376 }
3377 goto err;
3378 } else if (ret) {
3379 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
3380 ret);
3381 goto err;
3382 }
3383 if (pdata->snd_card_val != INT_SND_CARD)
3384 msm_ext_register_audio_notifier(pdev);
3385
3386 return 0;
3387err:
3388 if (pdata->us_euro_gpio > 0) {
3389 dev_dbg(&pdev->dev, "%s free us_euro gpio %d\n",
3390 __func__, pdata->us_euro_gpio);
3391 pdata->us_euro_gpio = 0;
3392 }
3393 if (pdata->hph_en1_gpio > 0) {
3394 dev_dbg(&pdev->dev, "%s free hph_en1_gpio %d\n",
3395 __func__, pdata->hph_en1_gpio);
3396 gpio_free(pdata->hph_en1_gpio);
3397 pdata->hph_en1_gpio = 0;
3398 }
3399 if (pdata->hph_en0_gpio > 0) {
3400 dev_dbg(&pdev->dev, "%s free hph_en0_gpio %d\n",
3401 __func__, pdata->hph_en0_gpio);
3402 gpio_free(pdata->hph_en0_gpio);
3403 pdata->hph_en0_gpio = 0;
3404 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303405 devm_kfree(&pdev->dev, pdata);
3406 return ret;
3407}
3408
3409static int msm_asoc_machine_remove(struct platform_device *pdev)
3410{
3411 struct snd_soc_card *card = platform_get_drvdata(pdev);
3412 struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
3413
3414 if (pdata->snd_card_val == INT_SND_CARD)
3415 mutex_destroy(&pdata->cdc_int_mclk0_mutex);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303416
Meng Wangc4ef3b52017-10-18 10:57:15 +08003417 if (gpio_is_valid(pdata->us_euro_gpio)) {
3418 gpio_free(pdata->us_euro_gpio);
3419 pdata->us_euro_gpio = 0;
3420 }
3421 if (gpio_is_valid(pdata->hph_en1_gpio)) {
3422 gpio_free(pdata->hph_en1_gpio);
3423 pdata->hph_en1_gpio = 0;
3424 }
3425 if (gpio_is_valid(pdata->hph_en0_gpio)) {
3426 gpio_free(pdata->hph_en0_gpio);
3427 pdata->hph_en0_gpio = 0;
3428 }
Meng Wangc444ff72017-10-18 10:52:07 +08003429
3430 if (pdata->snd_card_val != INT_SND_CARD)
3431 audio_notifier_deregister("sdm660");
3432
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303433 snd_soc_unregister_card(card);
3434 return 0;
3435}
3436
3437static struct platform_driver sdm660_asoc_machine_driver = {
3438 .driver = {
3439 .name = DRV_NAME,
3440 .owner = THIS_MODULE,
3441 .pm = &snd_soc_pm_ops,
3442 .of_match_table = sdm660_asoc_machine_of_match,
3443 },
3444 .probe = msm_asoc_machine_probe,
3445 .remove = msm_asoc_machine_remove,
3446};
3447module_platform_driver(sdm660_asoc_machine_driver);
3448
3449MODULE_DESCRIPTION("ALSA SoC msm");
3450MODULE_LICENSE("GPL v2");
3451MODULE_ALIAS("platform:" DRV_NAME);
3452MODULE_DEVICE_TABLE(of, sdm660_asoc_machine_of_match);