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