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