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