blob: 08e2960bca1ebe788e0128a29dbc92bad06e00c8 [file] [log] [blame]
Meng Wang43bbb872018-12-10 12:32:05 +08001// SPDX-License-Identifier: GPL-2.0-only
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05302/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
Laxminath Kasam243e2752018-04-12 00:40:19 +05303 */
4
5#include <linux/module.h>
6#include <linux/init.h>
7#include <linux/io.h>
8#include <linux/platform_device.h>
9#include <linux/clk.h>
Sudheer Papothi7601cc62019-03-30 03:00:52 +053010#include <linux/pm_runtime.h>
Laxminath Kasam243e2752018-04-12 00:40:19 +053011#include <sound/soc.h>
12#include <sound/soc-dapm.h>
13#include <sound/tlv.h>
Sudheer Papothia3e969d2018-10-27 06:22:10 +053014#include <soc/swr-common.h>
Laxminath Kasam243e2752018-04-12 00:40:19 +053015#include <soc/swr-wcd.h>
16
Meng Wang11a25cf2018-10-31 14:11:26 +080017#include <asoc/msm-cdc-pinctrl.h>
Laxminath Kasam243e2752018-04-12 00:40:19 +053018#include "bolero-cdc.h"
19#include "bolero-cdc-registers.h"
20#include "wsa-macro.h"
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -070021#include "bolero-clk-rsc.h"
Laxminath Kasam243e2752018-04-12 00:40:19 +053022
Sudheer Papothi7601cc62019-03-30 03:00:52 +053023#define AUTO_SUSPEND_DELAY 50 /* delay in msec */
Laxminath Kasam243e2752018-04-12 00:40:19 +053024#define WSA_MACRO_MAX_OFFSET 0x1000
25
26#define WSA_MACRO_RX_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
27 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
28 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
29#define WSA_MACRO_RX_MIX_RATES (SNDRV_PCM_RATE_48000 |\
30 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
31#define WSA_MACRO_RX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
32 SNDRV_PCM_FMTBIT_S24_LE |\
33 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
34
35#define WSA_MACRO_ECHO_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
36 SNDRV_PCM_RATE_48000)
37#define WSA_MACRO_ECHO_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
38 SNDRV_PCM_FMTBIT_S24_LE |\
39 SNDRV_PCM_FMTBIT_S24_3LE)
40
41#define NUM_INTERPOLATORS 2
42
43#define WSA_MACRO_MUX_INP_SHFT 0x3
44#define WSA_MACRO_MUX_INP_MASK1 0x38
45#define WSA_MACRO_MUX_INP_MASK2 0x38
46#define WSA_MACRO_MUX_CFG_OFFSET 0x8
47#define WSA_MACRO_MUX_CFG1_OFFSET 0x4
48#define WSA_MACRO_RX_COMP_OFFSET 0x40
Aditya Bavanari4f3d5642018-09-18 22:19:10 +053049#define WSA_MACRO_RX_SOFTCLIP_OFFSET 0x40
Laxminath Kasam243e2752018-04-12 00:40:19 +053050#define WSA_MACRO_RX_PATH_OFFSET 0x80
51#define WSA_MACRO_RX_PATH_CFG3_OFFSET 0x10
52#define WSA_MACRO_RX_PATH_DSMDEM_OFFSET 0x4C
53#define WSA_MACRO_FS_RATE_MASK 0x0F
Laxminath Kasam5d9ea8d2018-11-28 14:32:40 +053054#define WSA_MACRO_EC_MIX_TX0_MASK 0x03
55#define WSA_MACRO_EC_MIX_TX1_MASK 0x18
56
Laxminath Kasam243e2752018-04-12 00:40:19 +053057
58enum {
59 WSA_MACRO_RX0 = 0,
60 WSA_MACRO_RX1,
61 WSA_MACRO_RX_MIX,
62 WSA_MACRO_RX_MIX0 = WSA_MACRO_RX_MIX,
63 WSA_MACRO_RX_MIX1,
64 WSA_MACRO_RX_MAX,
65};
66
67enum {
68 WSA_MACRO_TX0 = 0,
69 WSA_MACRO_TX1,
70 WSA_MACRO_TX_MAX,
71};
72
73enum {
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +053074 WSA_MACRO_EC0_MUX = 0,
75 WSA_MACRO_EC1_MUX,
76 WSA_MACRO_EC_MUX_MAX,
77};
78
79enum {
Laxminath Kasam243e2752018-04-12 00:40:19 +053080 WSA_MACRO_COMP1, /* SPK_L */
81 WSA_MACRO_COMP2, /* SPK_R */
82 WSA_MACRO_COMP_MAX
83};
84
Aditya Bavanari4f3d5642018-09-18 22:19:10 +053085enum {
86 WSA_MACRO_SOFTCLIP0, /* RX0 */
87 WSA_MACRO_SOFTCLIP1, /* RX1 */
88 WSA_MACRO_SOFTCLIP_MAX
89};
90
Laxminath Kasam243e2752018-04-12 00:40:19 +053091struct interp_sample_rate {
92 int sample_rate;
93 int rate_val;
94};
95
96/*
97 * Structure used to update codec
98 * register defaults after reset
99 */
100struct wsa_macro_reg_mask_val {
101 u16 reg;
102 u8 mask;
103 u8 val;
104};
105
106static struct interp_sample_rate int_prim_sample_rate_val[] = {
107 {8000, 0x0}, /* 8K */
108 {16000, 0x1}, /* 16K */
109 {24000, -EINVAL},/* 24K */
110 {32000, 0x3}, /* 32K */
111 {48000, 0x4}, /* 48K */
112 {96000, 0x5}, /* 96K */
113 {192000, 0x6}, /* 192K */
114 {384000, 0x7}, /* 384K */
115 {44100, 0x8}, /* 44.1K */
116};
117
118static struct interp_sample_rate int_mix_sample_rate_val[] = {
119 {48000, 0x4}, /* 48K */
120 {96000, 0x5}, /* 96K */
121 {192000, 0x6}, /* 192K */
122};
123
124#define WSA_MACRO_SWR_STRING_LEN 80
125
126static int wsa_macro_hw_params(struct snd_pcm_substream *substream,
127 struct snd_pcm_hw_params *params,
128 struct snd_soc_dai *dai);
129static int wsa_macro_get_channel_map(struct snd_soc_dai *dai,
130 unsigned int *tx_num, unsigned int *tx_slot,
131 unsigned int *rx_num, unsigned int *rx_slot);
132/* Hold instance to soundwire platform device */
133struct wsa_macro_swr_ctrl_data {
134 struct platform_device *wsa_swr_pdev;
135};
136
137struct wsa_macro_swr_ctrl_platform_data {
138 void *handle; /* holds codec private data */
139 int (*read)(void *handle, int reg);
140 int (*write)(void *handle, int reg, int val);
141 int (*bulk_write)(void *handle, u32 *reg, u32 *val, size_t len);
142 int (*clk)(void *handle, bool enable);
143 int (*handle_irq)(void *handle,
144 irqreturn_t (*swrm_irq_handler)(int irq,
145 void *data),
146 void *swrm_handle,
147 int action);
148};
149
Aditya Bavanari4f3d5642018-09-18 22:19:10 +0530150struct wsa_macro_bcl_pmic_params {
151 u8 id;
152 u8 sid;
153 u8 ppid;
154};
155
Laxminath Kasam243e2752018-04-12 00:40:19 +0530156enum {
Laxminath Kasam59c7a1d2018-08-09 16:11:17 +0530157 WSA_MACRO_AIF_INVALID = 0,
158 WSA_MACRO_AIF1_PB,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530159 WSA_MACRO_AIF_MIX1_PB,
160 WSA_MACRO_AIF_VI,
161 WSA_MACRO_AIF_ECHO,
162 WSA_MACRO_MAX_DAIS,
163};
164
165#define WSA_MACRO_CHILD_DEVICES_MAX 3
166
167/*
168 * @dev: wsa macro device pointer
169 * @comp_enabled: compander enable mixer value set
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +0530170 * @ec_hq: echo HQ enable mixer value set
Laxminath Kasam243e2752018-04-12 00:40:19 +0530171 * @prim_int_users: Users of interpolator
172 * @wsa_mclk_users: WSA MCLK users count
173 * @swr_clk_users: SWR clk users count
174 * @vi_feed_value: VI sense mask
175 * @mclk_lock: to lock mclk operations
176 * @swr_clk_lock: to lock swr master clock operations
177 * @swr_ctrl_data: SoundWire data structure
178 * @swr_plat_data: Soundwire platform data
179 * @wsa_macro_add_child_devices_work: work for adding child devices
180 * @wsa_swr_gpio_p: used by pinctrl API
Meng Wang15c825d2018-09-06 10:49:18 +0800181 * @component: codec handle
Laxminath Kasam243e2752018-04-12 00:40:19 +0530182 * @rx_0_count: RX0 interpolation users
183 * @rx_1_count: RX1 interpolation users
184 * @active_ch_mask: channel mask for all AIF DAIs
185 * @active_ch_cnt: channel count of all AIF DAIs
186 * @rx_port_value: mixer ctl value of WSA RX MUXes
187 * @wsa_io_base: Base address of WSA macro addr space
188 */
189struct wsa_macro_priv {
190 struct device *dev;
191 int comp_enabled[WSA_MACRO_COMP_MAX];
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +0530192 int ec_hq[WSA_MACRO_RX1 + 1];
Laxminath Kasam243e2752018-04-12 00:40:19 +0530193 u16 prim_int_users[WSA_MACRO_RX1 + 1];
194 u16 wsa_mclk_users;
195 u16 swr_clk_users;
Ramprasad Katkam452772a2019-01-07 17:30:36 +0530196 bool dapm_mclk_enable;
Ramprasad Katkama4c747b2018-12-11 19:15:53 +0530197 bool reset_swr;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530198 unsigned int vi_feed_value;
199 struct mutex mclk_lock;
200 struct mutex swr_clk_lock;
201 struct wsa_macro_swr_ctrl_data *swr_ctrl_data;
202 struct wsa_macro_swr_ctrl_platform_data swr_plat_data;
203 struct work_struct wsa_macro_add_child_devices_work;
204 struct device_node *wsa_swr_gpio_p;
Meng Wang15c825d2018-09-06 10:49:18 +0800205 struct snd_soc_component *component;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530206 int rx_0_count;
207 int rx_1_count;
208 unsigned long active_ch_mask[WSA_MACRO_MAX_DAIS];
209 unsigned long active_ch_cnt[WSA_MACRO_MAX_DAIS];
210 int rx_port_value[WSA_MACRO_RX_MAX];
211 char __iomem *wsa_io_base;
212 struct platform_device *pdev_child_devices
213 [WSA_MACRO_CHILD_DEVICES_MAX];
214 int child_count;
215 int ear_spkr_gain;
216 int spkr_gain_offset;
217 int spkr_mode;
Aditya Bavanari4f3d5642018-09-18 22:19:10 +0530218 int is_softclip_on[WSA_MACRO_SOFTCLIP_MAX];
219 int softclip_clk_users[WSA_MACRO_SOFTCLIP_MAX];
220 struct wsa_macro_bcl_pmic_params bcl_pmic_params;
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -0700221 char __iomem *mclk_mode_muxsel;
222 u16 default_clk_id;
Vatsal Buchaf2a71b62019-03-26 16:14:40 +0530223 int wsa_digital_mute_status[WSA_MACRO_RX_MAX];
Laxminath Kasam243e2752018-04-12 00:40:19 +0530224};
225
Meng Wang15c825d2018-09-06 10:49:18 +0800226static int wsa_macro_config_ear_spkr_gain(struct snd_soc_component *component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530227 struct wsa_macro_priv *wsa_priv,
228 int event, int gain_reg);
229static struct snd_soc_dai_driver wsa_macro_dai[];
230static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0);
231
232static const char *const rx_text[] = {
233 "ZERO", "RX0", "RX1", "RX_MIX0", "RX_MIX1", "DEC0", "DEC1"
234};
235
236static const char *const rx_mix_text[] = {
237 "ZERO", "RX0", "RX1", "RX_MIX0", "RX_MIX1"
238};
239
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +0530240static const char *const rx_mix_ec_text[] = {
241 "ZERO", "RX_MIX_TX0", "RX_MIX_TX1"
242};
243
Laxminath Kasam243e2752018-04-12 00:40:19 +0530244static const char *const rx_mux_text[] = {
245 "ZERO", "AIF1_PB", "AIF_MIX1_PB"
246};
247
Laxminath Kasam6fc2e742018-08-26 23:32:57 +0530248static const char *const rx_sidetone_mix_text[] = {
249 "ZERO", "SRC0"
250};
251
Laxminath Kasam243e2752018-04-12 00:40:19 +0530252static const char * const wsa_macro_ear_spkr_pa_gain_text[] = {
253 "G_DEFAULT", "G_0_DB", "G_1_DB", "G_2_DB", "G_3_DB",
254 "G_4_DB", "G_5_DB", "G_6_DB"
255};
256
257static const char * const wsa_macro_speaker_boost_stage_text[] = {
258 "NO_MAX_STATE", "MAX_STATE_1", "MAX_STATE_2"
259};
260
Aditya Bavanari4f3d5642018-09-18 22:19:10 +0530261static const char * const wsa_macro_vbat_bcl_gsm_mode_text[] = {
262 "OFF", "ON"
263};
264
265static const struct snd_kcontrol_new wsa_int0_vbat_mix_switch[] = {
266 SOC_DAPM_SINGLE("WSA RX0 VBAT Enable", SND_SOC_NOPM, 0, 1, 0)
267};
268
269static const struct snd_kcontrol_new wsa_int1_vbat_mix_switch[] = {
270 SOC_DAPM_SINGLE("WSA RX1 VBAT Enable", SND_SOC_NOPM, 0, 1, 0)
271};
272
Laxminath Kasam243e2752018-04-12 00:40:19 +0530273static SOC_ENUM_SINGLE_EXT_DECL(wsa_macro_ear_spkr_pa_gain_enum,
274 wsa_macro_ear_spkr_pa_gain_text);
275static SOC_ENUM_SINGLE_EXT_DECL(wsa_macro_spkr_boost_stage_enum,
276 wsa_macro_speaker_boost_stage_text);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +0530277static SOC_ENUM_SINGLE_EXT_DECL(wsa_macro_vbat_bcl_gsm_mode_enum,
278 wsa_macro_vbat_bcl_gsm_mode_text);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530279
280/* RX INT0 */
281static const struct soc_enum rx0_prim_inp0_chain_enum =
282 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0,
283 0, 7, rx_text);
284
285static const struct soc_enum rx0_prim_inp1_chain_enum =
286 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0,
287 3, 7, rx_text);
288
289static const struct soc_enum rx0_prim_inp2_chain_enum =
290 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG1,
291 3, 7, rx_text);
292
293static const struct soc_enum rx0_mix_chain_enum =
294 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG1,
295 0, 5, rx_mix_text);
296
Laxminath Kasam6fc2e742018-08-26 23:32:57 +0530297static const struct soc_enum rx0_sidetone_mix_enum =
298 SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, 2, rx_sidetone_mix_text);
299
Laxminath Kasam243e2752018-04-12 00:40:19 +0530300static const struct snd_kcontrol_new rx0_prim_inp0_mux =
301 SOC_DAPM_ENUM("WSA_RX0 INP0 Mux", rx0_prim_inp0_chain_enum);
302
303static const struct snd_kcontrol_new rx0_prim_inp1_mux =
304 SOC_DAPM_ENUM("WSA_RX0 INP1 Mux", rx0_prim_inp1_chain_enum);
305
306static const struct snd_kcontrol_new rx0_prim_inp2_mux =
307 SOC_DAPM_ENUM("WSA_RX0 INP2 Mux", rx0_prim_inp2_chain_enum);
308
309static const struct snd_kcontrol_new rx0_mix_mux =
310 SOC_DAPM_ENUM("WSA_RX0 MIX Mux", rx0_mix_chain_enum);
311
Laxminath Kasam6fc2e742018-08-26 23:32:57 +0530312static const struct snd_kcontrol_new rx0_sidetone_mix_mux =
313 SOC_DAPM_ENUM("WSA_RX0 SIDETONE MIX Mux", rx0_sidetone_mix_enum);
314
Laxminath Kasam243e2752018-04-12 00:40:19 +0530315/* RX INT1 */
316static const struct soc_enum rx1_prim_inp0_chain_enum =
317 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT1_CFG0,
318 0, 7, rx_text);
319
320static const struct soc_enum rx1_prim_inp1_chain_enum =
321 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT1_CFG0,
322 3, 7, rx_text);
323
324static const struct soc_enum rx1_prim_inp2_chain_enum =
325 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT1_CFG1,
326 3, 7, rx_text);
327
328static const struct soc_enum rx1_mix_chain_enum =
329 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT1_CFG1,
330 0, 5, rx_mix_text);
331
332static const struct snd_kcontrol_new rx1_prim_inp0_mux =
333 SOC_DAPM_ENUM("WSA_RX1 INP0 Mux", rx1_prim_inp0_chain_enum);
334
335static const struct snd_kcontrol_new rx1_prim_inp1_mux =
336 SOC_DAPM_ENUM("WSA_RX1 INP1 Mux", rx1_prim_inp1_chain_enum);
337
338static const struct snd_kcontrol_new rx1_prim_inp2_mux =
339 SOC_DAPM_ENUM("WSA_RX1 INP2 Mux", rx1_prim_inp2_chain_enum);
340
341static const struct snd_kcontrol_new rx1_mix_mux =
342 SOC_DAPM_ENUM("WSA_RX1 MIX Mux", rx1_mix_chain_enum);
343
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +0530344static const struct soc_enum rx_mix_ec0_enum =
345 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0,
346 0, 3, rx_mix_ec_text);
347
348static const struct soc_enum rx_mix_ec1_enum =
349 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0,
350 3, 3, rx_mix_ec_text);
351
352static const struct snd_kcontrol_new rx_mix_ec0_mux =
353 SOC_DAPM_ENUM("WSA RX_MIX EC0_Mux", rx_mix_ec0_enum);
354
355static const struct snd_kcontrol_new rx_mix_ec1_mux =
356 SOC_DAPM_ENUM("WSA RX_MIX EC1_Mux", rx_mix_ec1_enum);
357
Laxminath Kasam243e2752018-04-12 00:40:19 +0530358static struct snd_soc_dai_ops wsa_macro_dai_ops = {
359 .hw_params = wsa_macro_hw_params,
360 .get_channel_map = wsa_macro_get_channel_map,
361};
362
363static struct snd_soc_dai_driver wsa_macro_dai[] = {
364 {
365 .name = "wsa_macro_rx1",
366 .id = WSA_MACRO_AIF1_PB,
367 .playback = {
368 .stream_name = "WSA_AIF1 Playback",
369 .rates = WSA_MACRO_RX_RATES,
370 .formats = WSA_MACRO_RX_FORMATS,
371 .rate_max = 384000,
372 .rate_min = 8000,
373 .channels_min = 1,
374 .channels_max = 2,
375 },
376 .ops = &wsa_macro_dai_ops,
377 },
378 {
379 .name = "wsa_macro_rx_mix",
380 .id = WSA_MACRO_AIF_MIX1_PB,
381 .playback = {
382 .stream_name = "WSA_AIF_MIX1 Playback",
383 .rates = WSA_MACRO_RX_MIX_RATES,
384 .formats = WSA_MACRO_RX_FORMATS,
385 .rate_max = 192000,
386 .rate_min = 48000,
387 .channels_min = 1,
388 .channels_max = 2,
389 },
390 .ops = &wsa_macro_dai_ops,
391 },
392 {
393 .name = "wsa_macro_vifeedback",
394 .id = WSA_MACRO_AIF_VI,
395 .capture = {
396 .stream_name = "WSA_AIF_VI Capture",
Vatsal Buchad1b694d2018-08-31 11:47:32 +0530397 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000,
398 .formats = WSA_MACRO_RX_FORMATS,
399 .rate_max = 48000,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530400 .rate_min = 8000,
401 .channels_min = 1,
Vatsal Buchad1b694d2018-08-31 11:47:32 +0530402 .channels_max = 4,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530403 },
404 .ops = &wsa_macro_dai_ops,
405 },
406 {
407 .name = "wsa_macro_echo",
408 .id = WSA_MACRO_AIF_ECHO,
409 .capture = {
410 .stream_name = "WSA_AIF_ECHO Capture",
411 .rates = WSA_MACRO_ECHO_RATES,
412 .formats = WSA_MACRO_ECHO_FORMATS,
413 .rate_max = 48000,
414 .rate_min = 8000,
415 .channels_min = 1,
416 .channels_max = 2,
417 },
418 .ops = &wsa_macro_dai_ops,
419 },
420};
421
422static const struct wsa_macro_reg_mask_val wsa_macro_spkr_default[] = {
423 {BOLERO_CDC_WSA_COMPANDER0_CTL3, 0x80, 0x80},
424 {BOLERO_CDC_WSA_COMPANDER1_CTL3, 0x80, 0x80},
425 {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x01, 0x01},
426 {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x01, 0x01},
427 {BOLERO_CDC_WSA_BOOST0_BOOST_CTL, 0x7C, 0x58},
428 {BOLERO_CDC_WSA_BOOST1_BOOST_CTL, 0x7C, 0x58},
429};
430
431static const struct wsa_macro_reg_mask_val wsa_macro_spkr_mode1[] = {
432 {BOLERO_CDC_WSA_COMPANDER0_CTL3, 0x80, 0x00},
433 {BOLERO_CDC_WSA_COMPANDER1_CTL3, 0x80, 0x00},
434 {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x01, 0x00},
435 {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x01, 0x00},
436 {BOLERO_CDC_WSA_BOOST0_BOOST_CTL, 0x7C, 0x44},
437 {BOLERO_CDC_WSA_BOOST1_BOOST_CTL, 0x7C, 0x44},
438};
439
Meng Wang15c825d2018-09-06 10:49:18 +0800440static bool wsa_macro_get_data(struct snd_soc_component *component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530441 struct device **wsa_dev,
442 struct wsa_macro_priv **wsa_priv,
443 const char *func_name)
444{
Meng Wang15c825d2018-09-06 10:49:18 +0800445 *wsa_dev = bolero_get_device_ptr(component->dev, WSA_MACRO);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530446 if (!(*wsa_dev)) {
Meng Wang15c825d2018-09-06 10:49:18 +0800447 dev_err(component->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530448 "%s: null device for macro!\n", func_name);
449 return false;
450 }
451 *wsa_priv = dev_get_drvdata((*wsa_dev));
Meng Wang15c825d2018-09-06 10:49:18 +0800452 if (!(*wsa_priv) || !(*wsa_priv)->component) {
453 dev_err(component->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530454 "%s: priv is null for macro!\n", func_name);
455 return false;
456 }
457 return true;
458}
459
Sudheer Papothia3e969d2018-10-27 06:22:10 +0530460static int wsa_macro_set_port_map(struct snd_soc_component *component,
461 u32 usecase, u32 size, void *data)
462{
463 struct device *wsa_dev = NULL;
464 struct wsa_macro_priv *wsa_priv = NULL;
465 struct swrm_port_config port_cfg;
466 int ret = 0;
467
468 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
469 return -EINVAL;
470
471 memset(&port_cfg, 0, sizeof(port_cfg));
472 port_cfg.uc = usecase;
473 port_cfg.size = size;
474 port_cfg.params = data;
475
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -0700476 if (wsa_priv->swr_ctrl_data)
477 ret = swrm_wcd_notify(
478 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
479 SWR_SET_PORT_MAP, &port_cfg);
Sudheer Papothia3e969d2018-10-27 06:22:10 +0530480
481 return ret;
482}
483
Laxminath Kasam243e2752018-04-12 00:40:19 +0530484/**
485 * wsa_macro_set_spkr_gain_offset - offset the speaker path
486 * gain with the given offset value.
487 *
Meng Wang15c825d2018-09-06 10:49:18 +0800488 * @component: codec instance
Laxminath Kasam243e2752018-04-12 00:40:19 +0530489 * @offset: Indicates speaker path gain offset value.
490 *
491 * Returns 0 on success or -EINVAL on error.
492 */
Meng Wang15c825d2018-09-06 10:49:18 +0800493int wsa_macro_set_spkr_gain_offset(struct snd_soc_component *component,
494 int offset)
Laxminath Kasam243e2752018-04-12 00:40:19 +0530495{
496 struct device *wsa_dev = NULL;
497 struct wsa_macro_priv *wsa_priv = NULL;
498
Meng Wang15c825d2018-09-06 10:49:18 +0800499 if (!component) {
500 pr_err("%s: NULL component pointer!\n", __func__);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530501 return -EINVAL;
502 }
503
Meng Wang15c825d2018-09-06 10:49:18 +0800504 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530505 return -EINVAL;
506
507 wsa_priv->spkr_gain_offset = offset;
508 return 0;
509}
510EXPORT_SYMBOL(wsa_macro_set_spkr_gain_offset);
511
512/**
513 * wsa_macro_set_spkr_mode - Configures speaker compander and smartboost
514 * settings based on speaker mode.
515 *
Meng Wang15c825d2018-09-06 10:49:18 +0800516 * @component: codec instance
Laxminath Kasam243e2752018-04-12 00:40:19 +0530517 * @mode: Indicates speaker configuration mode.
518 *
519 * Returns 0 on success or -EINVAL on error.
520 */
Meng Wang15c825d2018-09-06 10:49:18 +0800521int wsa_macro_set_spkr_mode(struct snd_soc_component *component, int mode)
Laxminath Kasam243e2752018-04-12 00:40:19 +0530522{
523 int i;
524 const struct wsa_macro_reg_mask_val *regs;
525 int size;
526 struct device *wsa_dev = NULL;
527 struct wsa_macro_priv *wsa_priv = NULL;
528
Meng Wang15c825d2018-09-06 10:49:18 +0800529 if (!component) {
Laxminath Kasam243e2752018-04-12 00:40:19 +0530530 pr_err("%s: NULL codec pointer!\n", __func__);
531 return -EINVAL;
532 }
533
Meng Wang15c825d2018-09-06 10:49:18 +0800534 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530535 return -EINVAL;
536
537 switch (mode) {
Laxminath Kasam21c8b222018-06-21 18:47:22 +0530538 case WSA_MACRO_SPKR_MODE_1:
Laxminath Kasam243e2752018-04-12 00:40:19 +0530539 regs = wsa_macro_spkr_mode1;
540 size = ARRAY_SIZE(wsa_macro_spkr_mode1);
541 break;
542 default:
543 regs = wsa_macro_spkr_default;
544 size = ARRAY_SIZE(wsa_macro_spkr_default);
545 break;
546 }
547
548 wsa_priv->spkr_mode = mode;
549 for (i = 0; i < size; i++)
Meng Wang15c825d2018-09-06 10:49:18 +0800550 snd_soc_component_update_bits(component, regs[i].reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530551 regs[i].mask, regs[i].val);
552 return 0;
553}
554EXPORT_SYMBOL(wsa_macro_set_spkr_mode);
555
556static int wsa_macro_set_prim_interpolator_rate(struct snd_soc_dai *dai,
557 u8 int_prim_fs_rate_reg_val,
558 u32 sample_rate)
559{
560 u8 int_1_mix1_inp;
561 u32 j, port;
562 u16 int_mux_cfg0, int_mux_cfg1;
563 u16 int_fs_reg;
564 u8 int_mux_cfg0_val, int_mux_cfg1_val;
565 u8 inp0_sel, inp1_sel, inp2_sel;
Meng Wang15c825d2018-09-06 10:49:18 +0800566 struct snd_soc_component *component = dai->component;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530567 struct device *wsa_dev = NULL;
568 struct wsa_macro_priv *wsa_priv = NULL;
569
Meng Wang15c825d2018-09-06 10:49:18 +0800570 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530571 return -EINVAL;
572
573 for_each_set_bit(port, &wsa_priv->active_ch_mask[dai->id],
574 WSA_MACRO_RX_MAX) {
575 int_1_mix1_inp = port;
576 if ((int_1_mix1_inp < WSA_MACRO_RX0) ||
577 (int_1_mix1_inp > WSA_MACRO_RX_MIX1)) {
578 dev_err(wsa_dev,
579 "%s: Invalid RX port, Dai ID is %d\n",
580 __func__, dai->id);
581 return -EINVAL;
582 }
583
584 int_mux_cfg0 = BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0;
585
586 /*
587 * Loop through all interpolator MUX inputs and find out
588 * to which interpolator input, the cdc_dma rx port
589 * is connected
590 */
591 for (j = 0; j < NUM_INTERPOLATORS; j++) {
592 int_mux_cfg1 = int_mux_cfg0 + WSA_MACRO_MUX_CFG1_OFFSET;
593
Meng Wang15c825d2018-09-06 10:49:18 +0800594 int_mux_cfg0_val = snd_soc_component_read32(component,
595 int_mux_cfg0);
596 int_mux_cfg1_val = snd_soc_component_read32(component,
597 int_mux_cfg1);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530598 inp0_sel = int_mux_cfg0_val & WSA_MACRO_MUX_INP_MASK1;
599 inp1_sel = (int_mux_cfg0_val >>
600 WSA_MACRO_MUX_INP_SHFT) &
601 WSA_MACRO_MUX_INP_MASK2;
602 inp2_sel = (int_mux_cfg1_val >>
603 WSA_MACRO_MUX_INP_SHFT) &
604 WSA_MACRO_MUX_INP_MASK2;
605 if ((inp0_sel == int_1_mix1_inp) ||
606 (inp1_sel == int_1_mix1_inp) ||
607 (inp2_sel == int_1_mix1_inp)) {
608 int_fs_reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL +
609 WSA_MACRO_RX_PATH_OFFSET * j;
610 dev_dbg(wsa_dev,
611 "%s: AIF_PB DAI(%d) connected to INT%u_1\n",
612 __func__, dai->id, j);
613 dev_dbg(wsa_dev,
614 "%s: set INT%u_1 sample rate to %u\n",
615 __func__, j, sample_rate);
616 /* sample_rate is in Hz */
Meng Wang15c825d2018-09-06 10:49:18 +0800617 snd_soc_component_update_bits(component,
618 int_fs_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530619 WSA_MACRO_FS_RATE_MASK,
620 int_prim_fs_rate_reg_val);
621 }
622 int_mux_cfg0 += WSA_MACRO_MUX_CFG_OFFSET;
623 }
624 }
625
626 return 0;
627}
628
629static int wsa_macro_set_mix_interpolator_rate(struct snd_soc_dai *dai,
630 u8 int_mix_fs_rate_reg_val,
631 u32 sample_rate)
632{
633 u8 int_2_inp;
634 u32 j, port;
635 u16 int_mux_cfg1, int_fs_reg;
636 u8 int_mux_cfg1_val;
Meng Wang15c825d2018-09-06 10:49:18 +0800637 struct snd_soc_component *component = dai->component;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530638 struct device *wsa_dev = NULL;
639 struct wsa_macro_priv *wsa_priv = NULL;
640
Meng Wang15c825d2018-09-06 10:49:18 +0800641 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530642 return -EINVAL;
643
644
645 for_each_set_bit(port, &wsa_priv->active_ch_mask[dai->id],
646 WSA_MACRO_RX_MAX) {
647 int_2_inp = port;
648 if ((int_2_inp < WSA_MACRO_RX0) ||
649 (int_2_inp > WSA_MACRO_RX_MIX1)) {
650 dev_err(wsa_dev,
651 "%s: Invalid RX port, Dai ID is %d\n",
652 __func__, dai->id);
653 return -EINVAL;
654 }
655
656 int_mux_cfg1 = BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG1;
657 for (j = 0; j < NUM_INTERPOLATORS; j++) {
Meng Wang15c825d2018-09-06 10:49:18 +0800658 int_mux_cfg1_val = snd_soc_component_read32(component,
659 int_mux_cfg1) &
Laxminath Kasam243e2752018-04-12 00:40:19 +0530660 WSA_MACRO_MUX_INP_MASK1;
661 if (int_mux_cfg1_val == int_2_inp) {
662 int_fs_reg =
663 BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL +
664 WSA_MACRO_RX_PATH_OFFSET * j;
665
666 dev_dbg(wsa_dev,
667 "%s: AIF_PB DAI(%d) connected to INT%u_2\n",
668 __func__, dai->id, j);
669 dev_dbg(wsa_dev,
670 "%s: set INT%u_2 sample rate to %u\n",
671 __func__, j, sample_rate);
Meng Wang15c825d2018-09-06 10:49:18 +0800672 snd_soc_component_update_bits(component,
673 int_fs_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530674 WSA_MACRO_FS_RATE_MASK,
675 int_mix_fs_rate_reg_val);
676 }
677 int_mux_cfg1 += WSA_MACRO_MUX_CFG_OFFSET;
678 }
679 }
680 return 0;
681}
682
683static int wsa_macro_set_interpolator_rate(struct snd_soc_dai *dai,
684 u32 sample_rate)
685{
686 int rate_val = 0;
687 int i, ret;
688
689 /* set mixing path rate */
690 for (i = 0; i < ARRAY_SIZE(int_mix_sample_rate_val); i++) {
691 if (sample_rate ==
692 int_mix_sample_rate_val[i].sample_rate) {
693 rate_val =
694 int_mix_sample_rate_val[i].rate_val;
695 break;
696 }
697 }
698 if ((i == ARRAY_SIZE(int_mix_sample_rate_val)) ||
699 (rate_val < 0))
700 goto prim_rate;
701 ret = wsa_macro_set_mix_interpolator_rate(dai,
702 (u8) rate_val, sample_rate);
703prim_rate:
704 /* set primary path sample rate */
705 for (i = 0; i < ARRAY_SIZE(int_prim_sample_rate_val); i++) {
706 if (sample_rate ==
707 int_prim_sample_rate_val[i].sample_rate) {
708 rate_val =
709 int_prim_sample_rate_val[i].rate_val;
710 break;
711 }
712 }
713 if ((i == ARRAY_SIZE(int_prim_sample_rate_val)) ||
714 (rate_val < 0))
715 return -EINVAL;
716 ret = wsa_macro_set_prim_interpolator_rate(dai,
717 (u8) rate_val, sample_rate);
718 return ret;
719}
720
721static int wsa_macro_hw_params(struct snd_pcm_substream *substream,
722 struct snd_pcm_hw_params *params,
723 struct snd_soc_dai *dai)
724{
Meng Wang15c825d2018-09-06 10:49:18 +0800725 struct snd_soc_component *component = dai->component;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530726 int ret;
727
Meng Wang15c825d2018-09-06 10:49:18 +0800728 dev_dbg(component->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530729 "%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__,
730 dai->name, dai->id, params_rate(params),
731 params_channels(params));
732
733 switch (substream->stream) {
734 case SNDRV_PCM_STREAM_PLAYBACK:
735 ret = wsa_macro_set_interpolator_rate(dai, params_rate(params));
736 if (ret) {
Meng Wang15c825d2018-09-06 10:49:18 +0800737 dev_err(component->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530738 "%s: cannot set sample rate: %u\n",
739 __func__, params_rate(params));
740 return ret;
741 }
742 break;
743 case SNDRV_PCM_STREAM_CAPTURE:
744 default:
745 break;
746 }
747 return 0;
748}
749
750static int wsa_macro_get_channel_map(struct snd_soc_dai *dai,
751 unsigned int *tx_num, unsigned int *tx_slot,
752 unsigned int *rx_num, unsigned int *rx_slot)
753{
Meng Wang15c825d2018-09-06 10:49:18 +0800754 struct snd_soc_component *component = dai->component;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530755 struct device *wsa_dev = NULL;
756 struct wsa_macro_priv *wsa_priv = NULL;
Laxminath Kasam5d9ea8d2018-11-28 14:32:40 +0530757 u16 val = 0, mask = 0, cnt = 0;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530758
Meng Wang15c825d2018-09-06 10:49:18 +0800759 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530760 return -EINVAL;
761
762 wsa_priv = dev_get_drvdata(wsa_dev);
763 if (!wsa_priv)
764 return -EINVAL;
765
766 switch (dai->id) {
767 case WSA_MACRO_AIF_VI:
Laxminath Kasam243e2752018-04-12 00:40:19 +0530768 *tx_slot = wsa_priv->active_ch_mask[dai->id];
769 *tx_num = wsa_priv->active_ch_cnt[dai->id];
770 break;
771 case WSA_MACRO_AIF1_PB:
772 case WSA_MACRO_AIF_MIX1_PB:
773 *rx_slot = wsa_priv->active_ch_mask[dai->id];
774 *rx_num = wsa_priv->active_ch_cnt[dai->id];
775 break;
Laxminath Kasam5d9ea8d2018-11-28 14:32:40 +0530776 case WSA_MACRO_AIF_ECHO:
777 val = snd_soc_component_read32(component,
778 BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0);
779 if (val & WSA_MACRO_EC_MIX_TX1_MASK) {
780 mask |= 0x2;
781 cnt++;
782 }
783 if (val & WSA_MACRO_EC_MIX_TX0_MASK) {
784 mask |= 0x1;
785 cnt++;
786 }
787 *tx_slot = mask;
788 *tx_num = cnt;
789 break;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530790 default:
791 dev_err(wsa_dev, "%s: Invalid AIF\n", __func__);
792 break;
793 }
794 return 0;
795}
796
797static int wsa_macro_mclk_enable(struct wsa_macro_priv *wsa_priv,
798 bool mclk_enable, bool dapm)
799{
800 struct regmap *regmap = dev_get_regmap(wsa_priv->dev->parent, NULL);
801 int ret = 0;
802
Tanya Dixitab8eba82018-10-05 15:07:37 +0530803 if (regmap == NULL) {
804 dev_err(wsa_priv->dev, "%s: regmap is NULL\n", __func__);
805 return -EINVAL;
806 }
807
Laxminath Kasam243e2752018-04-12 00:40:19 +0530808 dev_dbg(wsa_priv->dev, "%s: mclk_enable = %u, dapm = %d clk_users= %d\n",
809 __func__, mclk_enable, dapm, wsa_priv->wsa_mclk_users);
810
811 mutex_lock(&wsa_priv->mclk_lock);
812 if (mclk_enable) {
Aditya Bavanaric496ed22018-11-16 15:50:40 +0530813 if (wsa_priv->wsa_mclk_users == 0) {
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -0700814 ret = bolero_clk_rsc_request_clock(wsa_priv->dev,
815 wsa_priv->default_clk_id,
816 wsa_priv->default_clk_id,
817 true);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530818 if (ret < 0) {
Ramprasad Katkam14efed62019-03-07 13:16:50 +0530819 dev_err_ratelimited(wsa_priv->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530820 "%s: wsa request clock enable failed\n",
821 __func__);
822 goto exit;
823 }
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -0700824 bolero_clk_rsc_fs_gen_request(wsa_priv->dev,
825 true);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530826 regcache_mark_dirty(regmap);
827 regcache_sync_region(regmap,
828 WSA_START_OFFSET,
829 WSA_MAX_OFFSET);
830 /* 9.6MHz MCLK, set value 0x00 if other frequency */
831 regmap_update_bits(regmap,
832 BOLERO_CDC_WSA_TOP_FREQ_MCLK, 0x01, 0x01);
833 regmap_update_bits(regmap,
834 BOLERO_CDC_WSA_CLK_RST_CTRL_MCLK_CONTROL,
835 0x01, 0x01);
836 regmap_update_bits(regmap,
837 BOLERO_CDC_WSA_CLK_RST_CTRL_FS_CNT_CONTROL,
838 0x01, 0x01);
839 }
Aditya Bavanaric496ed22018-11-16 15:50:40 +0530840 wsa_priv->wsa_mclk_users++;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530841 } else {
Aditya Bavanaric496ed22018-11-16 15:50:40 +0530842 if (wsa_priv->wsa_mclk_users <= 0) {
843 dev_err(wsa_priv->dev, "%s: clock already disabled\n",
844 __func__);
845 wsa_priv->wsa_mclk_users = 0;
846 goto exit;
847 }
Laxminath Kasam243e2752018-04-12 00:40:19 +0530848 wsa_priv->wsa_mclk_users--;
849 if (wsa_priv->wsa_mclk_users == 0) {
850 regmap_update_bits(regmap,
851 BOLERO_CDC_WSA_CLK_RST_CTRL_FS_CNT_CONTROL,
852 0x01, 0x00);
853 regmap_update_bits(regmap,
854 BOLERO_CDC_WSA_CLK_RST_CTRL_MCLK_CONTROL,
855 0x01, 0x00);
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -0700856 bolero_clk_rsc_fs_gen_request(wsa_priv->dev,
857 false);
858
859 bolero_clk_rsc_request_clock(wsa_priv->dev,
860 wsa_priv->default_clk_id,
861 wsa_priv->default_clk_id,
862 false);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530863 }
864 }
865exit:
866 mutex_unlock(&wsa_priv->mclk_lock);
867 return ret;
868}
869
870static int wsa_macro_mclk_event(struct snd_soc_dapm_widget *w,
871 struct snd_kcontrol *kcontrol, int event)
872{
Meng Wang15c825d2018-09-06 10:49:18 +0800873 struct snd_soc_component *component =
874 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530875 int ret = 0;
876 struct device *wsa_dev = NULL;
877 struct wsa_macro_priv *wsa_priv = NULL;
878
Meng Wang15c825d2018-09-06 10:49:18 +0800879 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530880 return -EINVAL;
881
882 dev_dbg(wsa_dev, "%s: event = %d\n", __func__, event);
883 switch (event) {
884 case SND_SOC_DAPM_PRE_PMU:
885 ret = wsa_macro_mclk_enable(wsa_priv, 1, true);
Ramprasad Katkam452772a2019-01-07 17:30:36 +0530886 if (ret)
887 wsa_priv->dapm_mclk_enable = false;
888 else
889 wsa_priv->dapm_mclk_enable = true;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530890 break;
891 case SND_SOC_DAPM_POST_PMD:
Ramprasad Katkam452772a2019-01-07 17:30:36 +0530892 if (wsa_priv->dapm_mclk_enable)
893 wsa_macro_mclk_enable(wsa_priv, 0, true);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530894 break;
895 default:
896 dev_err(wsa_priv->dev,
897 "%s: invalid DAPM event %d\n", __func__, event);
898 ret = -EINVAL;
899 }
900 return ret;
901}
902
Meng Wang15c825d2018-09-06 10:49:18 +0800903static int wsa_macro_event_handler(struct snd_soc_component *component,
904 u16 event, u32 data)
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530905{
906 struct device *wsa_dev = NULL;
907 struct wsa_macro_priv *wsa_priv = NULL;
908
Meng Wang15c825d2018-09-06 10:49:18 +0800909 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530910 return -EINVAL;
911
912 switch (event) {
913 case BOLERO_MACRO_EVT_SSR_DOWN:
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -0700914 if (wsa_priv->swr_ctrl_data) {
915 swrm_wcd_notify(
916 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
917 SWR_DEVICE_DOWN, NULL);
918 swrm_wcd_notify(
919 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
920 SWR_DEVICE_SSR_DOWN, NULL);
921 }
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530922 break;
923 case BOLERO_MACRO_EVT_SSR_UP:
Ramprasad Katkama4c747b2018-12-11 19:15:53 +0530924 /* reset swr after ssr/pdr */
925 wsa_priv->reset_swr = true;
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -0700926 if (wsa_priv->swr_ctrl_data)
927 swrm_wcd_notify(
928 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
929 SWR_DEVICE_SSR_UP, NULL);
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530930 break;
931 }
932 return 0;
933}
934
Laxminath Kasam243e2752018-04-12 00:40:19 +0530935static int wsa_macro_enable_vi_feedback(struct snd_soc_dapm_widget *w,
936 struct snd_kcontrol *kcontrol,
937 int event)
938{
Meng Wang15c825d2018-09-06 10:49:18 +0800939 struct snd_soc_component *component =
940 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530941 struct device *wsa_dev = NULL;
942 struct wsa_macro_priv *wsa_priv = NULL;
943
Meng Wang15c825d2018-09-06 10:49:18 +0800944 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530945 return -EINVAL;
946
947 switch (event) {
948 case SND_SOC_DAPM_POST_PMU:
949 if (test_bit(WSA_MACRO_TX0,
950 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
951 dev_dbg(wsa_dev, "%s: spkr1 enabled\n", __func__);
952 /* Enable V&I sensing */
Meng Wang15c825d2018-09-06 10:49:18 +0800953 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530954 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
955 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +0800956 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530957 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
958 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +0800959 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530960 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
961 0x0F, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +0800962 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530963 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
964 0x0F, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +0800965 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530966 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
967 0x10, 0x10);
Meng Wang15c825d2018-09-06 10:49:18 +0800968 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530969 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
970 0x10, 0x10);
Meng Wang15c825d2018-09-06 10:49:18 +0800971 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530972 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
973 0x20, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +0800974 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530975 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
976 0x20, 0x00);
977 }
978 if (test_bit(WSA_MACRO_TX1,
979 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
980 dev_dbg(wsa_dev, "%s: spkr2 enabled\n", __func__);
981 /* Enable V&I sensing */
Meng Wang15c825d2018-09-06 10:49:18 +0800982 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530983 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
984 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +0800985 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530986 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
987 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +0800988 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530989 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
990 0x0F, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +0800991 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530992 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
993 0x0F, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +0800994 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530995 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
996 0x10, 0x10);
Meng Wang15c825d2018-09-06 10:49:18 +0800997 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530998 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
999 0x10, 0x10);
Meng Wang15c825d2018-09-06 10:49:18 +08001000 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301001 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
1002 0x20, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001003 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301004 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
1005 0x20, 0x00);
1006 }
1007 break;
1008 case SND_SOC_DAPM_POST_PMD:
1009 if (test_bit(WSA_MACRO_TX0,
1010 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
1011 /* Disable V&I sensing */
Meng Wang15c825d2018-09-06 10:49:18 +08001012 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301013 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
1014 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08001015 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301016 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
1017 0x20, 0x20);
1018 dev_dbg(wsa_dev, "%s: spkr1 disabled\n", __func__);
Meng Wang15c825d2018-09-06 10:49:18 +08001019 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301020 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
1021 0x10, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001022 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301023 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
1024 0x10, 0x00);
1025 }
1026 if (test_bit(WSA_MACRO_TX1,
1027 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
1028 /* Disable V&I sensing */
1029 dev_dbg(wsa_dev, "%s: spkr2 disabled\n", __func__);
Meng Wang15c825d2018-09-06 10:49:18 +08001030 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301031 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
1032 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08001033 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301034 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
1035 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08001036 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301037 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
1038 0x10, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001039 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301040 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
1041 0x10, 0x00);
1042 }
1043 break;
1044 }
1045
1046 return 0;
1047}
1048
1049static int wsa_macro_enable_mix_path(struct snd_soc_dapm_widget *w,
1050 struct snd_kcontrol *kcontrol, int event)
1051{
Meng Wang15c825d2018-09-06 10:49:18 +08001052 struct snd_soc_component *component =
1053 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301054 u16 gain_reg;
1055 int offset_val = 0;
1056 int val = 0;
1057
Meng Wang15c825d2018-09-06 10:49:18 +08001058 dev_dbg(component->dev, "%s %d %s\n", __func__, event, w->name);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301059
1060 switch (w->reg) {
1061 case BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL:
1062 gain_reg = BOLERO_CDC_WSA_RX0_RX_VOL_MIX_CTL;
1063 break;
1064 case BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL:
1065 gain_reg = BOLERO_CDC_WSA_RX1_RX_VOL_MIX_CTL;
1066 break;
1067 default:
Meng Wang15c825d2018-09-06 10:49:18 +08001068 dev_err(component->dev, "%s: No gain register avail for %s\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301069 __func__, w->name);
1070 return 0;
1071 }
1072
1073 switch (event) {
1074 case SND_SOC_DAPM_POST_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08001075 val = snd_soc_component_read32(component, gain_reg);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301076 val += offset_val;
Meng Wang15c825d2018-09-06 10:49:18 +08001077 snd_soc_component_write(component, gain_reg, val);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301078 break;
1079 case SND_SOC_DAPM_POST_PMD:
1080 break;
1081 }
1082
1083 return 0;
1084}
1085
Meng Wang15c825d2018-09-06 10:49:18 +08001086static void wsa_macro_hd2_control(struct snd_soc_component *component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301087 u16 reg, int event)
1088{
1089 u16 hd2_scale_reg;
1090 u16 hd2_enable_reg = 0;
1091
1092 if (reg == BOLERO_CDC_WSA_RX0_RX_PATH_CTL) {
1093 hd2_scale_reg = BOLERO_CDC_WSA_RX0_RX_PATH_SEC3;
1094 hd2_enable_reg = BOLERO_CDC_WSA_RX0_RX_PATH_CFG0;
1095 }
1096 if (reg == BOLERO_CDC_WSA_RX1_RX_PATH_CTL) {
1097 hd2_scale_reg = BOLERO_CDC_WSA_RX1_RX_PATH_SEC3;
1098 hd2_enable_reg = BOLERO_CDC_WSA_RX1_RX_PATH_CFG0;
1099 }
1100
1101 if (hd2_enable_reg && SND_SOC_DAPM_EVENT_ON(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001102 snd_soc_component_update_bits(component, hd2_scale_reg,
1103 0x3C, 0x10);
1104 snd_soc_component_update_bits(component, hd2_scale_reg,
1105 0x03, 0x01);
1106 snd_soc_component_update_bits(component, hd2_enable_reg,
1107 0x04, 0x04);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301108 }
1109
1110 if (hd2_enable_reg && SND_SOC_DAPM_EVENT_OFF(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001111 snd_soc_component_update_bits(component, hd2_enable_reg,
1112 0x04, 0x00);
1113 snd_soc_component_update_bits(component, hd2_scale_reg,
1114 0x03, 0x00);
1115 snd_soc_component_update_bits(component, hd2_scale_reg,
1116 0x3C, 0x00);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301117 }
1118}
1119
1120static int wsa_macro_enable_swr(struct snd_soc_dapm_widget *w,
1121 struct snd_kcontrol *kcontrol, int event)
1122{
Meng Wang15c825d2018-09-06 10:49:18 +08001123 struct snd_soc_component *component =
1124 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301125 int ch_cnt;
1126 struct device *wsa_dev = NULL;
1127 struct wsa_macro_priv *wsa_priv = NULL;
1128
Meng Wang15c825d2018-09-06 10:49:18 +08001129 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301130 return -EINVAL;
1131
1132 switch (event) {
1133 case SND_SOC_DAPM_PRE_PMU:
1134 if (!(strnstr(w->name, "RX0", sizeof("WSA_RX0"))) &&
1135 !wsa_priv->rx_0_count)
1136 wsa_priv->rx_0_count++;
1137 if (!(strnstr(w->name, "RX1", sizeof("WSA_RX1"))) &&
1138 !wsa_priv->rx_1_count)
1139 wsa_priv->rx_1_count++;
1140 ch_cnt = wsa_priv->rx_0_count + wsa_priv->rx_1_count;
1141
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07001142 if (wsa_priv->swr_ctrl_data) {
1143 swrm_wcd_notify(
1144 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
1145 SWR_DEVICE_UP, NULL);
1146 swrm_wcd_notify(
1147 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
1148 SWR_SET_NUM_RX_CH, &ch_cnt);
1149 }
Laxminath Kasam243e2752018-04-12 00:40:19 +05301150 break;
1151 case SND_SOC_DAPM_POST_PMD:
1152 if (!(strnstr(w->name, "RX0", sizeof("WSA_RX0"))) &&
1153 wsa_priv->rx_0_count)
1154 wsa_priv->rx_0_count--;
1155 if (!(strnstr(w->name, "RX1", sizeof("WSA_RX1"))) &&
1156 wsa_priv->rx_1_count)
1157 wsa_priv->rx_1_count--;
1158 ch_cnt = wsa_priv->rx_0_count + wsa_priv->rx_1_count;
1159
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07001160 if (wsa_priv->swr_ctrl_data)
1161 swrm_wcd_notify(
1162 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
1163 SWR_SET_NUM_RX_CH, &ch_cnt);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301164 break;
1165 }
1166 dev_dbg(wsa_priv->dev, "%s: current swr ch cnt: %d\n",
1167 __func__, wsa_priv->rx_0_count + wsa_priv->rx_1_count);
1168
1169 return 0;
1170}
1171
Meng Wang15c825d2018-09-06 10:49:18 +08001172static int wsa_macro_config_compander(struct snd_soc_component *component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301173 int comp, int event)
1174{
1175 u16 comp_ctl0_reg, rx_path_cfg0_reg;
1176 struct device *wsa_dev = NULL;
1177 struct wsa_macro_priv *wsa_priv = NULL;
1178
Meng Wang15c825d2018-09-06 10:49:18 +08001179 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301180 return -EINVAL;
1181
Meng Wang15c825d2018-09-06 10:49:18 +08001182 dev_dbg(component->dev, "%s: event %d compander %d, enabled %d\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301183 __func__, event, comp + 1, wsa_priv->comp_enabled[comp]);
1184
1185 if (!wsa_priv->comp_enabled[comp])
1186 return 0;
1187
1188 comp_ctl0_reg = BOLERO_CDC_WSA_COMPANDER0_CTL0 +
1189 (comp * WSA_MACRO_RX_COMP_OFFSET);
1190 rx_path_cfg0_reg = BOLERO_CDC_WSA_RX0_RX_PATH_CFG0 +
1191 (comp * WSA_MACRO_RX_PATH_OFFSET);
1192
1193 if (SND_SOC_DAPM_EVENT_ON(event)) {
1194 /* Enable Compander Clock */
Meng Wang15c825d2018-09-06 10:49:18 +08001195 snd_soc_component_update_bits(component, comp_ctl0_reg,
1196 0x01, 0x01);
1197 snd_soc_component_update_bits(component, comp_ctl0_reg,
1198 0x02, 0x02);
1199 snd_soc_component_update_bits(component, comp_ctl0_reg,
1200 0x02, 0x00);
1201 snd_soc_component_update_bits(component, rx_path_cfg0_reg,
1202 0x02, 0x02);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301203 }
1204
1205 if (SND_SOC_DAPM_EVENT_OFF(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001206 snd_soc_component_update_bits(component, comp_ctl0_reg,
1207 0x04, 0x04);
1208 snd_soc_component_update_bits(component, rx_path_cfg0_reg,
1209 0x02, 0x00);
1210 snd_soc_component_update_bits(component, comp_ctl0_reg,
1211 0x02, 0x02);
1212 snd_soc_component_update_bits(component, comp_ctl0_reg,
1213 0x02, 0x00);
1214 snd_soc_component_update_bits(component, comp_ctl0_reg,
1215 0x01, 0x00);
1216 snd_soc_component_update_bits(component, comp_ctl0_reg,
1217 0x04, 0x00);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301218 }
1219
1220 return 0;
1221}
1222
Meng Wang15c825d2018-09-06 10:49:18 +08001223static void wsa_macro_enable_softclip_clk(struct snd_soc_component *component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301224 struct wsa_macro_priv *wsa_priv,
1225 int path,
1226 bool enable)
1227{
1228 u16 softclip_clk_reg = BOLERO_CDC_WSA_SOFTCLIP0_CRC +
1229 (path * WSA_MACRO_RX_SOFTCLIP_OFFSET);
1230 u8 softclip_mux_mask = (1 << path);
1231 u8 softclip_mux_value = (1 << path);
1232
Meng Wang15c825d2018-09-06 10:49:18 +08001233 dev_dbg(component->dev, "%s: path %d, enable %d\n",
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301234 __func__, path, enable);
1235 if (enable) {
1236 if (wsa_priv->softclip_clk_users[path] == 0) {
Meng Wang15c825d2018-09-06 10:49:18 +08001237 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301238 softclip_clk_reg, 0x01, 0x01);
Meng Wang15c825d2018-09-06 10:49:18 +08001239 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301240 BOLERO_CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0,
1241 softclip_mux_mask, softclip_mux_value);
1242 }
1243 wsa_priv->softclip_clk_users[path]++;
1244 } else {
1245 wsa_priv->softclip_clk_users[path]--;
1246 if (wsa_priv->softclip_clk_users[path] == 0) {
Meng Wang15c825d2018-09-06 10:49:18 +08001247 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301248 softclip_clk_reg, 0x01, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001249 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301250 BOLERO_CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0,
1251 softclip_mux_mask, 0x00);
1252 }
1253 }
1254}
1255
Meng Wang15c825d2018-09-06 10:49:18 +08001256static int wsa_macro_config_softclip(struct snd_soc_component *component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301257 int path, int event)
1258{
1259 u16 softclip_ctrl_reg = 0;
1260 struct device *wsa_dev = NULL;
1261 struct wsa_macro_priv *wsa_priv = NULL;
1262 int softclip_path = 0;
1263
Meng Wang15c825d2018-09-06 10:49:18 +08001264 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301265 return -EINVAL;
1266
1267 if (path == WSA_MACRO_COMP1)
1268 softclip_path = WSA_MACRO_SOFTCLIP0;
1269 else if (path == WSA_MACRO_COMP2)
1270 softclip_path = WSA_MACRO_SOFTCLIP1;
1271
Meng Wang15c825d2018-09-06 10:49:18 +08001272 dev_dbg(component->dev, "%s: event %d path %d, enabled %d\n",
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301273 __func__, event, softclip_path,
1274 wsa_priv->is_softclip_on[softclip_path]);
1275
1276 if (!wsa_priv->is_softclip_on[softclip_path])
1277 return 0;
1278
1279 softclip_ctrl_reg = BOLERO_CDC_WSA_SOFTCLIP0_SOFTCLIP_CTRL +
1280 (softclip_path * WSA_MACRO_RX_SOFTCLIP_OFFSET);
1281
1282 if (SND_SOC_DAPM_EVENT_ON(event)) {
1283 /* Enable Softclip clock and mux */
Meng Wang15c825d2018-09-06 10:49:18 +08001284 wsa_macro_enable_softclip_clk(component, wsa_priv,
1285 softclip_path, true);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301286 /* Enable Softclip control */
Meng Wang15c825d2018-09-06 10:49:18 +08001287 snd_soc_component_update_bits(component, softclip_ctrl_reg,
1288 0x01, 0x01);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301289 }
1290
1291 if (SND_SOC_DAPM_EVENT_OFF(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001292 snd_soc_component_update_bits(component, softclip_ctrl_reg,
1293 0x01, 0x00);
1294 wsa_macro_enable_softclip_clk(component, wsa_priv,
1295 softclip_path, false);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301296 }
1297
1298 return 0;
1299}
1300
Laxminath Kasam243e2752018-04-12 00:40:19 +05301301static int wsa_macro_interp_get_primary_reg(u16 reg, u16 *ind)
1302{
1303 u16 prim_int_reg = 0;
1304
1305 switch (reg) {
1306 case BOLERO_CDC_WSA_RX0_RX_PATH_CTL:
1307 case BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL:
1308 prim_int_reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL;
1309 *ind = 0;
1310 break;
1311 case BOLERO_CDC_WSA_RX1_RX_PATH_CTL:
1312 case BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL:
1313 prim_int_reg = BOLERO_CDC_WSA_RX1_RX_PATH_CTL;
1314 *ind = 1;
1315 break;
1316 }
1317
1318 return prim_int_reg;
1319}
1320
1321static int wsa_macro_enable_prim_interpolator(
Meng Wang15c825d2018-09-06 10:49:18 +08001322 struct snd_soc_component *component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301323 u16 reg, int event)
1324{
1325 u16 prim_int_reg;
1326 u16 ind = 0;
1327 struct device *wsa_dev = NULL;
1328 struct wsa_macro_priv *wsa_priv = NULL;
1329
Meng Wang15c825d2018-09-06 10:49:18 +08001330 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301331 return -EINVAL;
1332
1333 prim_int_reg = wsa_macro_interp_get_primary_reg(reg, &ind);
1334
1335 switch (event) {
1336 case SND_SOC_DAPM_PRE_PMU:
1337 wsa_priv->prim_int_users[ind]++;
1338 if (wsa_priv->prim_int_users[ind] == 1) {
Meng Wang15c825d2018-09-06 10:49:18 +08001339 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301340 prim_int_reg + WSA_MACRO_RX_PATH_CFG3_OFFSET,
1341 0x03, 0x03);
Meng Wang15c825d2018-09-06 10:49:18 +08001342 snd_soc_component_update_bits(component, prim_int_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301343 0x10, 0x10);
Meng Wang15c825d2018-09-06 10:49:18 +08001344 wsa_macro_hd2_control(component, prim_int_reg, event);
1345 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301346 prim_int_reg + WSA_MACRO_RX_PATH_DSMDEM_OFFSET,
1347 0x1, 0x1);
Meng Wang15c825d2018-09-06 10:49:18 +08001348 snd_soc_component_update_bits(component, prim_int_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301349 1 << 0x5, 1 << 0x5);
1350 }
1351 if ((reg != prim_int_reg) &&
Meng Wang15c825d2018-09-06 10:49:18 +08001352 ((snd_soc_component_read32(
1353 component, prim_int_reg)) & 0x10))
1354 snd_soc_component_update_bits(component, reg,
1355 0x10, 0x10);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301356 break;
1357 case SND_SOC_DAPM_POST_PMD:
1358 wsa_priv->prim_int_users[ind]--;
1359 if (wsa_priv->prim_int_users[ind] == 0) {
Meng Wang15c825d2018-09-06 10:49:18 +08001360 snd_soc_component_update_bits(component, prim_int_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301361 1 << 0x5, 0 << 0x5);
Meng Wang15c825d2018-09-06 10:49:18 +08001362 snd_soc_component_update_bits(component, prim_int_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301363 0x40, 0x40);
Meng Wang15c825d2018-09-06 10:49:18 +08001364 snd_soc_component_update_bits(component, prim_int_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301365 0x40, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001366 wsa_macro_hd2_control(component, prim_int_reg, event);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301367 }
1368 break;
1369 }
1370
Meng Wang15c825d2018-09-06 10:49:18 +08001371 dev_dbg(component->dev, "%s: primary interpolator: INT%d, users: %d\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301372 __func__, ind, wsa_priv->prim_int_users[ind]);
1373 return 0;
1374}
1375
1376static int wsa_macro_enable_interpolator(struct snd_soc_dapm_widget *w,
1377 struct snd_kcontrol *kcontrol,
1378 int event)
1379{
Meng Wang15c825d2018-09-06 10:49:18 +08001380 struct snd_soc_component *component =
1381 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301382 u16 gain_reg;
1383 u16 reg;
1384 int val;
1385 int offset_val = 0;
1386 struct device *wsa_dev = NULL;
1387 struct wsa_macro_priv *wsa_priv = NULL;
1388
Meng Wang15c825d2018-09-06 10:49:18 +08001389 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301390 return -EINVAL;
1391
Meng Wang15c825d2018-09-06 10:49:18 +08001392 dev_dbg(component->dev, "%s %d %s\n", __func__, event, w->name);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301393
1394 if (!(strcmp(w->name, "WSA_RX INT0 INTERP"))) {
1395 reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL;
1396 gain_reg = BOLERO_CDC_WSA_RX0_RX_VOL_CTL;
1397 } else if (!(strcmp(w->name, "WSA_RX INT1 INTERP"))) {
1398 reg = BOLERO_CDC_WSA_RX1_RX_PATH_CTL;
1399 gain_reg = BOLERO_CDC_WSA_RX1_RX_VOL_CTL;
1400 } else {
Meng Wang15c825d2018-09-06 10:49:18 +08001401 dev_err(component->dev, "%s: Interpolator reg not found\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301402 __func__);
1403 return -EINVAL;
1404 }
1405
1406 switch (event) {
1407 case SND_SOC_DAPM_PRE_PMU:
1408 /* Reset if needed */
Meng Wang15c825d2018-09-06 10:49:18 +08001409 wsa_macro_enable_prim_interpolator(component, reg, event);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301410 break;
1411 case SND_SOC_DAPM_POST_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08001412 wsa_macro_config_compander(component, w->shift, event);
1413 wsa_macro_config_softclip(component, w->shift, event);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301414 /* apply gain after int clk is enabled */
Laxminath Kasam21c8b222018-06-21 18:47:22 +05301415 if ((wsa_priv->spkr_gain_offset ==
1416 WSA_MACRO_GAIN_OFFSET_M1P5_DB) &&
Laxminath Kasam243e2752018-04-12 00:40:19 +05301417 (wsa_priv->comp_enabled[WSA_MACRO_COMP1] ||
1418 wsa_priv->comp_enabled[WSA_MACRO_COMP2]) &&
1419 (gain_reg == BOLERO_CDC_WSA_RX0_RX_VOL_CTL ||
1420 gain_reg == BOLERO_CDC_WSA_RX1_RX_VOL_CTL)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001421 snd_soc_component_update_bits(component,
1422 BOLERO_CDC_WSA_RX0_RX_PATH_SEC1,
1423 0x01, 0x01);
1424 snd_soc_component_update_bits(component,
1425 BOLERO_CDC_WSA_RX0_RX_PATH_MIX_SEC0,
1426 0x01, 0x01);
1427 snd_soc_component_update_bits(component,
1428 BOLERO_CDC_WSA_RX1_RX_PATH_SEC1,
1429 0x01, 0x01);
1430 snd_soc_component_update_bits(component,
1431 BOLERO_CDC_WSA_RX1_RX_PATH_MIX_SEC0,
1432 0x01, 0x01);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301433 offset_val = -2;
1434 }
Meng Wang15c825d2018-09-06 10:49:18 +08001435 val = snd_soc_component_read32(component, gain_reg);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301436 val += offset_val;
Meng Wang15c825d2018-09-06 10:49:18 +08001437 snd_soc_component_write(component, gain_reg, val);
1438 wsa_macro_config_ear_spkr_gain(component, wsa_priv,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301439 event, gain_reg);
1440 break;
1441 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +08001442 wsa_macro_config_compander(component, w->shift, event);
1443 wsa_macro_config_softclip(component, w->shift, event);
1444 wsa_macro_enable_prim_interpolator(component, reg, event);
Laxminath Kasam21c8b222018-06-21 18:47:22 +05301445 if ((wsa_priv->spkr_gain_offset ==
1446 WSA_MACRO_GAIN_OFFSET_M1P5_DB) &&
Laxminath Kasam243e2752018-04-12 00:40:19 +05301447 (wsa_priv->comp_enabled[WSA_MACRO_COMP1] ||
1448 wsa_priv->comp_enabled[WSA_MACRO_COMP2]) &&
1449 (gain_reg == BOLERO_CDC_WSA_RX0_RX_VOL_CTL ||
1450 gain_reg == BOLERO_CDC_WSA_RX1_RX_VOL_CTL)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001451 snd_soc_component_update_bits(component,
1452 BOLERO_CDC_WSA_RX0_RX_PATH_SEC1,
1453 0x01, 0x00);
1454 snd_soc_component_update_bits(component,
1455 BOLERO_CDC_WSA_RX0_RX_PATH_MIX_SEC0,
1456 0x01, 0x00);
1457 snd_soc_component_update_bits(component,
1458 BOLERO_CDC_WSA_RX1_RX_PATH_SEC1,
1459 0x01, 0x00);
1460 snd_soc_component_update_bits(component,
1461 BOLERO_CDC_WSA_RX1_RX_PATH_MIX_SEC0,
1462 0x01, 0x00);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301463 offset_val = 2;
Meng Wang15c825d2018-09-06 10:49:18 +08001464 val = snd_soc_component_read32(component, gain_reg);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301465 val += offset_val;
Meng Wang15c825d2018-09-06 10:49:18 +08001466 snd_soc_component_write(component, gain_reg, val);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301467 }
Meng Wang15c825d2018-09-06 10:49:18 +08001468 wsa_macro_config_ear_spkr_gain(component, wsa_priv,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301469 event, gain_reg);
1470 break;
1471 }
1472
1473 return 0;
1474}
1475
Meng Wang15c825d2018-09-06 10:49:18 +08001476static int wsa_macro_config_ear_spkr_gain(struct snd_soc_component *component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301477 struct wsa_macro_priv *wsa_priv,
1478 int event, int gain_reg)
1479{
1480 int comp_gain_offset, val;
1481
1482 switch (wsa_priv->spkr_mode) {
Laxminath Kasam21c8b222018-06-21 18:47:22 +05301483 /* Compander gain in WSA_MACRO_SPKR_MODE1 case is 12 dB */
1484 case WSA_MACRO_SPKR_MODE_1:
Laxminath Kasam243e2752018-04-12 00:40:19 +05301485 comp_gain_offset = -12;
1486 break;
1487 /* Default case compander gain is 15 dB */
1488 default:
1489 comp_gain_offset = -15;
1490 break;
1491 }
1492
1493 switch (event) {
1494 case SND_SOC_DAPM_POST_PMU:
1495 /* Apply ear spkr gain only if compander is enabled */
1496 if (wsa_priv->comp_enabled[WSA_MACRO_COMP1] &&
1497 (gain_reg == BOLERO_CDC_WSA_RX0_RX_VOL_CTL) &&
1498 (wsa_priv->ear_spkr_gain != 0)) {
1499 /* For example, val is -8(-12+5-1) for 4dB of gain */
1500 val = comp_gain_offset + wsa_priv->ear_spkr_gain - 1;
Meng Wang15c825d2018-09-06 10:49:18 +08001501 snd_soc_component_write(component, gain_reg, val);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301502
1503 dev_dbg(wsa_priv->dev, "%s: RX0 Volume %d dB\n",
1504 __func__, val);
1505 }
1506 break;
1507 case SND_SOC_DAPM_POST_PMD:
1508 /*
1509 * Reset RX0 volume to 0 dB if compander is enabled and
1510 * ear_spkr_gain is non-zero.
1511 */
1512 if (wsa_priv->comp_enabled[WSA_MACRO_COMP1] &&
1513 (gain_reg == BOLERO_CDC_WSA_RX0_RX_VOL_CTL) &&
1514 (wsa_priv->ear_spkr_gain != 0)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001515 snd_soc_component_write(component, gain_reg, 0x0);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301516
1517 dev_dbg(wsa_priv->dev, "%s: Reset RX0 Volume to 0 dB\n",
1518 __func__);
1519 }
1520 break;
1521 }
1522
1523 return 0;
1524}
1525
1526static int wsa_macro_spk_boost_event(struct snd_soc_dapm_widget *w,
1527 struct snd_kcontrol *kcontrol,
1528 int event)
1529{
Meng Wang15c825d2018-09-06 10:49:18 +08001530 struct snd_soc_component *component =
1531 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301532 u16 boost_path_ctl, boost_path_cfg1;
1533 u16 reg, reg_mix;
1534
Meng Wang15c825d2018-09-06 10:49:18 +08001535 dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301536
1537 if (!strcmp(w->name, "WSA_RX INT0 CHAIN")) {
1538 boost_path_ctl = BOLERO_CDC_WSA_BOOST0_BOOST_PATH_CTL;
1539 boost_path_cfg1 = BOLERO_CDC_WSA_RX0_RX_PATH_CFG1;
1540 reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL;
1541 reg_mix = BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL;
1542 } else if (!strcmp(w->name, "WSA_RX INT1 CHAIN")) {
1543 boost_path_ctl = BOLERO_CDC_WSA_BOOST1_BOOST_PATH_CTL;
1544 boost_path_cfg1 = BOLERO_CDC_WSA_RX1_RX_PATH_CFG1;
1545 reg = BOLERO_CDC_WSA_RX1_RX_PATH_CTL;
1546 reg_mix = BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL;
1547 } else {
Meng Wang15c825d2018-09-06 10:49:18 +08001548 dev_err(component->dev, "%s: unknown widget: %s\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301549 __func__, w->name);
1550 return -EINVAL;
1551 }
1552
1553 switch (event) {
1554 case SND_SOC_DAPM_PRE_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08001555 snd_soc_component_update_bits(component, boost_path_cfg1,
1556 0x01, 0x01);
1557 snd_soc_component_update_bits(component, boost_path_ctl,
1558 0x10, 0x10);
1559 if ((snd_soc_component_read32(component, reg_mix)) & 0x10)
1560 snd_soc_component_update_bits(component, reg_mix,
1561 0x10, 0x00);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301562 break;
Laxminath Kasam0c857002018-07-17 23:47:17 +05301563 case SND_SOC_DAPM_POST_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08001564 snd_soc_component_update_bits(component, reg, 0x10, 0x00);
Laxminath Kasam0c857002018-07-17 23:47:17 +05301565 break;
Laxminath Kasam243e2752018-04-12 00:40:19 +05301566 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +08001567 snd_soc_component_update_bits(component, boost_path_ctl,
1568 0x10, 0x00);
1569 snd_soc_component_update_bits(component, boost_path_cfg1,
1570 0x01, 0x00);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301571 break;
1572 }
1573
1574 return 0;
1575}
1576
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301577
1578static int wsa_macro_enable_vbat(struct snd_soc_dapm_widget *w,
1579 struct snd_kcontrol *kcontrol,
1580 int event)
1581{
Meng Wang15c825d2018-09-06 10:49:18 +08001582 struct snd_soc_component *component =
1583 snd_soc_dapm_to_component(w->dapm);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301584 struct device *wsa_dev = NULL;
1585 struct wsa_macro_priv *wsa_priv = NULL;
1586 u16 vbat_path_cfg = 0;
1587 int softclip_path = 0;
1588
Meng Wang15c825d2018-09-06 10:49:18 +08001589 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301590 return -EINVAL;
1591
Meng Wang15c825d2018-09-06 10:49:18 +08001592 dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301593 if (!strcmp(w->name, "WSA_RX INT0 VBAT")) {
1594 vbat_path_cfg = BOLERO_CDC_WSA_RX0_RX_PATH_CFG1;
1595 softclip_path = WSA_MACRO_SOFTCLIP0;
1596 } else if (!strcmp(w->name, "WSA_RX INT1 VBAT")) {
1597 vbat_path_cfg = BOLERO_CDC_WSA_RX1_RX_PATH_CFG1;
1598 softclip_path = WSA_MACRO_SOFTCLIP1;
1599 }
1600
1601 switch (event) {
1602 case SND_SOC_DAPM_PRE_PMU:
1603 /* Enable clock for VBAT block */
Meng Wang15c825d2018-09-06 10:49:18 +08001604 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301605 BOLERO_CDC_WSA_VBAT_BCL_VBAT_PATH_CTL, 0x10, 0x10);
1606 /* Enable VBAT block */
Meng Wang15c825d2018-09-06 10:49:18 +08001607 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301608 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG, 0x01, 0x01);
1609 /* Update interpolator with 384K path */
Meng Wang15c825d2018-09-06 10:49:18 +08001610 snd_soc_component_update_bits(component, vbat_path_cfg,
1611 0x80, 0x80);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301612 /* Use attenuation mode */
Meng Wang15c825d2018-09-06 10:49:18 +08001613 snd_soc_component_update_bits(component,
1614 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG, 0x02, 0x00);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301615 /*
1616 * BCL block needs softclip clock and mux config to be enabled
1617 */
Meng Wang15c825d2018-09-06 10:49:18 +08001618 wsa_macro_enable_softclip_clk(component, wsa_priv,
1619 softclip_path, true);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301620 /* Enable VBAT at channel level */
Meng Wang15c825d2018-09-06 10:49:18 +08001621 snd_soc_component_update_bits(component, vbat_path_cfg,
1622 0x02, 0x02);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301623 /* Set the ATTK1 gain */
Meng Wang15c825d2018-09-06 10:49:18 +08001624 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301625 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD1,
1626 0xFF, 0xFF);
Meng Wang15c825d2018-09-06 10:49:18 +08001627 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301628 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD2,
1629 0xFF, 0x03);
Meng Wang15c825d2018-09-06 10:49:18 +08001630 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301631 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD3,
1632 0xFF, 0x00);
1633 /* Set the ATTK2 gain */
Meng Wang15c825d2018-09-06 10:49:18 +08001634 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301635 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD4,
1636 0xFF, 0xFF);
Meng Wang15c825d2018-09-06 10:49:18 +08001637 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301638 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD5,
1639 0xFF, 0x03);
Meng Wang15c825d2018-09-06 10:49:18 +08001640 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301641 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD6,
1642 0xFF, 0x00);
1643 /* Set the ATTK3 gain */
Meng Wang15c825d2018-09-06 10:49:18 +08001644 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301645 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD7,
1646 0xFF, 0xFF);
Meng Wang15c825d2018-09-06 10:49:18 +08001647 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301648 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD8,
1649 0xFF, 0x03);
Meng Wang15c825d2018-09-06 10:49:18 +08001650 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301651 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD9,
1652 0xFF, 0x00);
1653 break;
1654
1655 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +08001656 snd_soc_component_update_bits(component, vbat_path_cfg,
1657 0x80, 0x00);
1658 snd_soc_component_update_bits(component,
1659 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG,
1660 0x02, 0x02);
1661 snd_soc_component_update_bits(component, vbat_path_cfg,
1662 0x02, 0x00);
1663 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301664 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD1,
1665 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001666 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301667 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD2,
1668 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001669 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301670 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD3,
1671 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001672 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301673 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD4,
1674 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001675 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301676 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD5,
1677 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001678 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301679 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD6,
1680 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001681 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301682 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD7,
1683 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001684 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301685 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD8,
1686 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001687 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301688 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD9,
1689 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001690 wsa_macro_enable_softclip_clk(component, wsa_priv,
1691 softclip_path, false);
1692 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301693 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG, 0x01, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001694 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301695 BOLERO_CDC_WSA_VBAT_BCL_VBAT_PATH_CTL, 0x10, 0x00);
1696 break;
1697 default:
1698 dev_err(wsa_dev, "%s: Invalid event %d\n", __func__, event);
1699 break;
1700 }
1701 return 0;
1702}
1703
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301704static int wsa_macro_enable_echo(struct snd_soc_dapm_widget *w,
1705 struct snd_kcontrol *kcontrol,
1706 int event)
1707{
Meng Wang15c825d2018-09-06 10:49:18 +08001708 struct snd_soc_component *component =
1709 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301710 struct device *wsa_dev = NULL;
1711 struct wsa_macro_priv *wsa_priv = NULL;
1712 u16 val, ec_tx = 0, ec_hq_reg;
1713
Meng Wang15c825d2018-09-06 10:49:18 +08001714 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301715 return -EINVAL;
1716
1717 dev_dbg(wsa_dev, "%s %d %s\n", __func__, event, w->name);
1718
Meng Wang15c825d2018-09-06 10:49:18 +08001719 val = snd_soc_component_read32(component,
1720 BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301721 if (!(strcmp(w->name, "WSA RX_MIX EC0_MUX")))
1722 ec_tx = (val & 0x07) - 1;
1723 else
1724 ec_tx = ((val & 0x38) >> 0x3) - 1;
1725
1726 if (ec_tx < 0 || ec_tx >= (WSA_MACRO_RX1 + 1)) {
1727 dev_err(wsa_dev, "%s: EC mix control not set correctly\n",
1728 __func__);
1729 return -EINVAL;
1730 }
1731 if (wsa_priv->ec_hq[ec_tx]) {
Meng Wang15c825d2018-09-06 10:49:18 +08001732 snd_soc_component_update_bits(component,
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301733 BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0,
1734 0x1 << ec_tx, 0x1 << ec_tx);
1735 ec_hq_reg = BOLERO_CDC_WSA_EC_HQ0_EC_REF_HQ_PATH_CTL +
Laxminath Kasam5d9ea8d2018-11-28 14:32:40 +05301736 0x40 * ec_tx;
Meng Wang15c825d2018-09-06 10:49:18 +08001737 snd_soc_component_update_bits(component, ec_hq_reg, 0x01, 0x01);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301738 ec_hq_reg = BOLERO_CDC_WSA_EC_HQ0_EC_REF_HQ_CFG0 +
Laxminath Kasam5d9ea8d2018-11-28 14:32:40 +05301739 0x40 * ec_tx;
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301740 /* default set to 48k */
Meng Wang15c825d2018-09-06 10:49:18 +08001741 snd_soc_component_update_bits(component, ec_hq_reg, 0x1E, 0x08);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301742 }
1743
1744 return 0;
1745}
1746
1747static int wsa_macro_get_ec_hq(struct snd_kcontrol *kcontrol,
1748 struct snd_ctl_elem_value *ucontrol)
1749{
1750
Meng Wang15c825d2018-09-06 10:49:18 +08001751 struct snd_soc_component *component =
1752 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301753 int ec_tx = ((struct soc_multi_mixer_control *)
1754 kcontrol->private_value)->shift;
1755 struct device *wsa_dev = NULL;
1756 struct wsa_macro_priv *wsa_priv = NULL;
1757
Meng Wang15c825d2018-09-06 10:49:18 +08001758 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301759 return -EINVAL;
1760
1761 ucontrol->value.integer.value[0] = wsa_priv->ec_hq[ec_tx];
1762 return 0;
1763}
1764
1765static int wsa_macro_set_ec_hq(struct snd_kcontrol *kcontrol,
1766 struct snd_ctl_elem_value *ucontrol)
1767{
Meng Wang15c825d2018-09-06 10:49:18 +08001768 struct snd_soc_component *component =
1769 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301770 int ec_tx = ((struct soc_multi_mixer_control *)
1771 kcontrol->private_value)->shift;
1772 int value = ucontrol->value.integer.value[0];
1773 struct device *wsa_dev = NULL;
1774 struct wsa_macro_priv *wsa_priv = NULL;
1775
Meng Wang15c825d2018-09-06 10:49:18 +08001776 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301777 return -EINVAL;
1778
1779 dev_dbg(wsa_dev, "%s: enable current %d, new %d\n",
1780 __func__, wsa_priv->ec_hq[ec_tx], value);
1781 wsa_priv->ec_hq[ec_tx] = value;
1782
1783 return 0;
1784}
1785
Vatsal Buchaf2a71b62019-03-26 16:14:40 +05301786static int wsa_macro_get_rx_mute_status(struct snd_kcontrol *kcontrol,
1787 struct snd_ctl_elem_value *ucontrol)
1788{
1789
1790 struct snd_soc_component *component =
1791 snd_soc_kcontrol_component(kcontrol);
1792 struct device *wsa_dev = NULL;
1793 struct wsa_macro_priv *wsa_priv = NULL;
1794 int wsa_rx_shift = ((struct soc_multi_mixer_control *)
1795 kcontrol->private_value)->shift;
1796
1797 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
1798 return -EINVAL;
1799
1800 ucontrol->value.integer.value[0] =
1801 wsa_priv->wsa_digital_mute_status[wsa_rx_shift];
1802 return 0;
1803}
1804
1805static int wsa_macro_set_rx_mute_status(struct snd_kcontrol *kcontrol,
1806 struct snd_ctl_elem_value *ucontrol)
1807{
1808 struct snd_soc_component *component =
1809 snd_soc_kcontrol_component(kcontrol);
1810 struct device *wsa_dev = NULL;
1811 struct wsa_macro_priv *wsa_priv = NULL;
1812 int value = ucontrol->value.integer.value[0];
1813 int wsa_rx_shift = ((struct soc_multi_mixer_control *)
1814 kcontrol->private_value)->shift;
1815
1816 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
1817 return -EINVAL;
1818
1819 switch (wsa_rx_shift) {
1820 case 0:
1821 snd_soc_component_update_bits(component,
1822 BOLERO_CDC_WSA_RX0_RX_PATH_CTL,
1823 0x10, value << 4);
1824 break;
1825 case 1:
1826 snd_soc_component_update_bits(component,
1827 BOLERO_CDC_WSA_RX1_RX_PATH_CTL,
1828 0x10, value << 4);
1829 break;
1830 case 2:
1831 snd_soc_component_update_bits(component,
1832 BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL,
1833 0x10, value << 4);
1834 break;
1835 case 3:
1836 snd_soc_component_update_bits(component,
1837 BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL,
1838 0x10, value << 4);
1839 break;
1840 default:
1841 pr_err("%s: invalid argument rx_shift = %d\n", __func__,
1842 wsa_rx_shift);
1843 return -EINVAL;
1844 }
1845
1846 dev_dbg(component->dev, "%s: WSA Digital Mute RX %d Enable %d\n",
1847 __func__, wsa_rx_shift, value);
1848 wsa_priv->wsa_digital_mute_status[wsa_rx_shift] = value;
1849 return 0;
1850}
1851
Laxminath Kasam243e2752018-04-12 00:40:19 +05301852static int wsa_macro_get_compander(struct snd_kcontrol *kcontrol,
1853 struct snd_ctl_elem_value *ucontrol)
1854{
1855
Meng Wang15c825d2018-09-06 10:49:18 +08001856 struct snd_soc_component *component =
1857 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301858 int comp = ((struct soc_multi_mixer_control *)
1859 kcontrol->private_value)->shift;
1860 struct device *wsa_dev = NULL;
1861 struct wsa_macro_priv *wsa_priv = NULL;
1862
Meng Wang15c825d2018-09-06 10:49:18 +08001863 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301864 return -EINVAL;
1865
1866 ucontrol->value.integer.value[0] = wsa_priv->comp_enabled[comp];
1867 return 0;
1868}
1869
1870static int wsa_macro_set_compander(struct snd_kcontrol *kcontrol,
1871 struct snd_ctl_elem_value *ucontrol)
1872{
Meng Wang15c825d2018-09-06 10:49:18 +08001873 struct snd_soc_component *component =
1874 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301875 int comp = ((struct soc_multi_mixer_control *)
1876 kcontrol->private_value)->shift;
1877 int value = ucontrol->value.integer.value[0];
1878 struct device *wsa_dev = NULL;
1879 struct wsa_macro_priv *wsa_priv = NULL;
1880
Meng Wang15c825d2018-09-06 10:49:18 +08001881 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301882 return -EINVAL;
1883
Meng Wang15c825d2018-09-06 10:49:18 +08001884 dev_dbg(component->dev, "%s: Compander %d enable current %d, new %d\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301885 __func__, comp + 1, wsa_priv->comp_enabled[comp], value);
1886 wsa_priv->comp_enabled[comp] = value;
1887
1888 return 0;
1889}
1890
1891static int wsa_macro_ear_spkr_pa_gain_get(struct snd_kcontrol *kcontrol,
1892 struct snd_ctl_elem_value *ucontrol)
1893{
Meng Wang15c825d2018-09-06 10:49:18 +08001894 struct snd_soc_component *component =
1895 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301896 struct device *wsa_dev = NULL;
1897 struct wsa_macro_priv *wsa_priv = NULL;
1898
Meng Wang15c825d2018-09-06 10:49:18 +08001899 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301900 return -EINVAL;
1901
1902 ucontrol->value.integer.value[0] = wsa_priv->ear_spkr_gain;
1903
Meng Wang15c825d2018-09-06 10:49:18 +08001904 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301905 __func__, ucontrol->value.integer.value[0]);
1906
1907 return 0;
1908}
1909
1910static int wsa_macro_ear_spkr_pa_gain_put(struct snd_kcontrol *kcontrol,
1911 struct snd_ctl_elem_value *ucontrol)
1912{
Meng Wang15c825d2018-09-06 10:49:18 +08001913 struct snd_soc_component *component =
1914 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301915 struct device *wsa_dev = NULL;
1916 struct wsa_macro_priv *wsa_priv = NULL;
1917
Meng Wang15c825d2018-09-06 10:49:18 +08001918 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301919 return -EINVAL;
1920
1921 wsa_priv->ear_spkr_gain = ucontrol->value.integer.value[0];
1922
Meng Wang15c825d2018-09-06 10:49:18 +08001923 dev_dbg(component->dev, "%s: gain = %d\n", __func__,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301924 wsa_priv->ear_spkr_gain);
1925
1926 return 0;
1927}
1928
1929static int wsa_macro_spkr_left_boost_stage_get(struct snd_kcontrol *kcontrol,
1930 struct snd_ctl_elem_value *ucontrol)
1931{
1932 u8 bst_state_max = 0;
Meng Wang15c825d2018-09-06 10:49:18 +08001933 struct snd_soc_component *component =
1934 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301935
Meng Wang15c825d2018-09-06 10:49:18 +08001936 bst_state_max = snd_soc_component_read32(component,
1937 BOLERO_CDC_WSA_BOOST0_BOOST_CTL);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301938 bst_state_max = (bst_state_max & 0x0c) >> 2;
1939 ucontrol->value.integer.value[0] = bst_state_max;
Meng Wang15c825d2018-09-06 10:49:18 +08001940 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301941 __func__, ucontrol->value.integer.value[0]);
1942
1943 return 0;
1944}
1945
1946static int wsa_macro_spkr_left_boost_stage_put(struct snd_kcontrol *kcontrol,
1947 struct snd_ctl_elem_value *ucontrol)
1948{
1949 u8 bst_state_max;
Meng Wang15c825d2018-09-06 10:49:18 +08001950 struct snd_soc_component *component =
1951 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301952
Meng Wang15c825d2018-09-06 10:49:18 +08001953 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301954 __func__, ucontrol->value.integer.value[0]);
1955 bst_state_max = ucontrol->value.integer.value[0] << 2;
Karthikeyan Mani10de3932019-04-15 11:46:57 -07001956 /* bolero does not need to limit the boost levels */
Laxminath Kasam243e2752018-04-12 00:40:19 +05301957
1958 return 0;
1959}
1960
1961static int wsa_macro_spkr_right_boost_stage_get(struct snd_kcontrol *kcontrol,
1962 struct snd_ctl_elem_value *ucontrol)
1963{
1964 u8 bst_state_max = 0;
Meng Wang15c825d2018-09-06 10:49:18 +08001965 struct snd_soc_component *component =
1966 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301967
Meng Wang15c825d2018-09-06 10:49:18 +08001968 bst_state_max = snd_soc_component_read32(component,
1969 BOLERO_CDC_WSA_BOOST1_BOOST_CTL);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301970 bst_state_max = (bst_state_max & 0x0c) >> 2;
1971 ucontrol->value.integer.value[0] = bst_state_max;
Meng Wang15c825d2018-09-06 10:49:18 +08001972 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301973 __func__, ucontrol->value.integer.value[0]);
1974
1975 return 0;
1976}
1977
1978static int wsa_macro_spkr_right_boost_stage_put(struct snd_kcontrol *kcontrol,
1979 struct snd_ctl_elem_value *ucontrol)
1980{
1981 u8 bst_state_max;
Meng Wang15c825d2018-09-06 10:49:18 +08001982 struct snd_soc_component *component =
1983 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301984
Meng Wang15c825d2018-09-06 10:49:18 +08001985 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301986 __func__, ucontrol->value.integer.value[0]);
1987 bst_state_max = ucontrol->value.integer.value[0] << 2;
Karthikeyan Mani10de3932019-04-15 11:46:57 -07001988 /* bolero does not need to limit the boost levels */
Laxminath Kasam243e2752018-04-12 00:40:19 +05301989
1990 return 0;
1991}
1992
1993static int wsa_macro_rx_mux_get(struct snd_kcontrol *kcontrol,
1994 struct snd_ctl_elem_value *ucontrol)
1995{
1996 struct snd_soc_dapm_widget *widget =
1997 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +08001998 struct snd_soc_component *component =
1999 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302000 struct device *wsa_dev = NULL;
2001 struct wsa_macro_priv *wsa_priv = NULL;
2002
Meng Wang15c825d2018-09-06 10:49:18 +08002003 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302004 return -EINVAL;
2005
2006 ucontrol->value.integer.value[0] =
2007 wsa_priv->rx_port_value[widget->shift];
2008 return 0;
2009}
2010
2011static int wsa_macro_rx_mux_put(struct snd_kcontrol *kcontrol,
2012 struct snd_ctl_elem_value *ucontrol)
2013{
2014 struct snd_soc_dapm_widget *widget =
2015 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +08002016 struct snd_soc_component *component =
2017 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302018 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
2019 struct snd_soc_dapm_update *update = NULL;
2020 u32 rx_port_value = ucontrol->value.integer.value[0];
2021 u32 bit_input = 0;
2022 u32 aif_rst;
2023 struct device *wsa_dev = NULL;
2024 struct wsa_macro_priv *wsa_priv = NULL;
2025
Meng Wang15c825d2018-09-06 10:49:18 +08002026 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302027 return -EINVAL;
2028
2029 aif_rst = wsa_priv->rx_port_value[widget->shift];
2030 if (!rx_port_value) {
2031 if (aif_rst == 0) {
2032 dev_err(wsa_dev, "%s: AIF reset already\n", __func__);
2033 return 0;
2034 }
2035 }
2036 wsa_priv->rx_port_value[widget->shift] = rx_port_value;
2037
2038 bit_input = widget->shift;
2039 if (widget->shift >= WSA_MACRO_RX_MIX)
2040 bit_input %= WSA_MACRO_RX_MIX;
2041
2042 switch (rx_port_value) {
2043 case 0:
2044 clear_bit(bit_input,
Laxminath Kasam59c7a1d2018-08-09 16:11:17 +05302045 &wsa_priv->active_ch_mask[aif_rst]);
2046 wsa_priv->active_ch_cnt[aif_rst]--;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302047 break;
2048 case 1:
2049 case 2:
2050 set_bit(bit_input,
Laxminath Kasam59c7a1d2018-08-09 16:11:17 +05302051 &wsa_priv->active_ch_mask[rx_port_value]);
2052 wsa_priv->active_ch_cnt[rx_port_value]++;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302053 break;
2054 default:
2055 dev_err(wsa_dev,
2056 "%s: Invalid AIF_ID for WSA RX MUX\n", __func__);
2057 return -EINVAL;
2058 }
2059
2060 snd_soc_dapm_mux_update_power(widget->dapm, kcontrol,
2061 rx_port_value, e, update);
2062 return 0;
2063}
2064
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302065static int wsa_macro_vbat_bcl_gsm_mode_func_get(struct snd_kcontrol *kcontrol,
2066 struct snd_ctl_elem_value *ucontrol)
2067{
Meng Wang15c825d2018-09-06 10:49:18 +08002068 struct snd_soc_component *component =
2069 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302070
2071 ucontrol->value.integer.value[0] =
Meng Wang15c825d2018-09-06 10:49:18 +08002072 ((snd_soc_component_read32(
2073 component, BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG) & 0x04) ?
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302074 1 : 0);
2075
Meng Wang15c825d2018-09-06 10:49:18 +08002076 dev_dbg(component->dev, "%s: value: %lu\n", __func__,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302077 ucontrol->value.integer.value[0]);
2078
2079 return 0;
2080}
2081
2082static int wsa_macro_vbat_bcl_gsm_mode_func_put(struct snd_kcontrol *kcontrol,
2083 struct snd_ctl_elem_value *ucontrol)
2084{
Meng Wang15c825d2018-09-06 10:49:18 +08002085 struct snd_soc_component *component =
2086 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302087
Meng Wang15c825d2018-09-06 10:49:18 +08002088 dev_dbg(component->dev, "%s: value: %lu\n", __func__,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302089 ucontrol->value.integer.value[0]);
2090
2091 /* Set Vbat register configuration for GSM mode bit based on value */
2092 if (ucontrol->value.integer.value[0])
Meng Wang15c825d2018-09-06 10:49:18 +08002093 snd_soc_component_update_bits(component,
2094 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG,
2095 0x04, 0x04);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302096 else
Meng Wang15c825d2018-09-06 10:49:18 +08002097 snd_soc_component_update_bits(component,
2098 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG,
2099 0x04, 0x00);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302100
2101 return 0;
2102}
2103
2104static int wsa_macro_soft_clip_enable_get(struct snd_kcontrol *kcontrol,
2105 struct snd_ctl_elem_value *ucontrol)
2106{
Meng Wang15c825d2018-09-06 10:49:18 +08002107 struct snd_soc_component *component =
2108 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302109 struct device *wsa_dev = NULL;
2110 struct wsa_macro_priv *wsa_priv = NULL;
2111 int path = ((struct soc_multi_mixer_control *)
2112 kcontrol->private_value)->shift;
2113
Meng Wang15c825d2018-09-06 10:49:18 +08002114 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302115 return -EINVAL;
2116
2117 ucontrol->value.integer.value[0] = wsa_priv->is_softclip_on[path];
2118
Meng Wang15c825d2018-09-06 10:49:18 +08002119 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302120 __func__, ucontrol->value.integer.value[0]);
2121
2122 return 0;
2123}
2124
2125static int wsa_macro_soft_clip_enable_put(struct snd_kcontrol *kcontrol,
2126 struct snd_ctl_elem_value *ucontrol)
2127{
Meng Wang15c825d2018-09-06 10:49:18 +08002128 struct snd_soc_component *component =
2129 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302130 struct device *wsa_dev = NULL;
2131 struct wsa_macro_priv *wsa_priv = NULL;
2132 int path = ((struct soc_multi_mixer_control *)
2133 kcontrol->private_value)->shift;
2134
Meng Wang15c825d2018-09-06 10:49:18 +08002135 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302136 return -EINVAL;
2137
2138 wsa_priv->is_softclip_on[path] = ucontrol->value.integer.value[0];
2139
Meng Wang15c825d2018-09-06 10:49:18 +08002140 dev_dbg(component->dev, "%s: soft clip enable for %d: %d\n", __func__,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302141 path, wsa_priv->is_softclip_on[path]);
2142
2143 return 0;
2144}
2145
Laxminath Kasam243e2752018-04-12 00:40:19 +05302146static const struct snd_kcontrol_new wsa_macro_snd_controls[] = {
2147 SOC_ENUM_EXT("EAR SPKR PA Gain", wsa_macro_ear_spkr_pa_gain_enum,
2148 wsa_macro_ear_spkr_pa_gain_get,
2149 wsa_macro_ear_spkr_pa_gain_put),
2150 SOC_ENUM_EXT("SPKR Left Boost Max State",
2151 wsa_macro_spkr_boost_stage_enum,
2152 wsa_macro_spkr_left_boost_stage_get,
2153 wsa_macro_spkr_left_boost_stage_put),
2154 SOC_ENUM_EXT("SPKR Right Boost Max State",
2155 wsa_macro_spkr_boost_stage_enum,
2156 wsa_macro_spkr_right_boost_stage_get,
2157 wsa_macro_spkr_right_boost_stage_put),
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302158 SOC_ENUM_EXT("GSM mode Enable", wsa_macro_vbat_bcl_gsm_mode_enum,
2159 wsa_macro_vbat_bcl_gsm_mode_func_get,
2160 wsa_macro_vbat_bcl_gsm_mode_func_put),
2161 SOC_SINGLE_EXT("WSA_Softclip0 Enable", SND_SOC_NOPM,
2162 WSA_MACRO_SOFTCLIP0, 1, 0,
2163 wsa_macro_soft_clip_enable_get,
2164 wsa_macro_soft_clip_enable_put),
2165 SOC_SINGLE_EXT("WSA_Softclip1 Enable", SND_SOC_NOPM,
2166 WSA_MACRO_SOFTCLIP1, 1, 0,
2167 wsa_macro_soft_clip_enable_get,
2168 wsa_macro_soft_clip_enable_put),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302169 SOC_SINGLE_SX_TLV("WSA_RX0 Digital Volume",
2170 BOLERO_CDC_WSA_RX0_RX_VOL_CTL,
2171 0, -84, 40, digital_gain),
2172 SOC_SINGLE_SX_TLV("WSA_RX1 Digital Volume",
2173 BOLERO_CDC_WSA_RX1_RX_VOL_CTL,
2174 0, -84, 40, digital_gain),
Vatsal Buchaf2a71b62019-03-26 16:14:40 +05302175 SOC_SINGLE_EXT("WSA_RX0 Digital Mute", SND_SOC_NOPM, WSA_MACRO_RX0, 1,
2176 0, wsa_macro_get_rx_mute_status,
2177 wsa_macro_set_rx_mute_status),
2178 SOC_SINGLE_EXT("WSA_RX1 Digital Mute", SND_SOC_NOPM, WSA_MACRO_RX1, 1,
2179 0, wsa_macro_get_rx_mute_status,
2180 wsa_macro_set_rx_mute_status),
2181 SOC_SINGLE_EXT("WSA_RX0_MIX Digital Mute", SND_SOC_NOPM,
2182 WSA_MACRO_RX_MIX0, 1, 0, wsa_macro_get_rx_mute_status,
2183 wsa_macro_set_rx_mute_status),
2184 SOC_SINGLE_EXT("WSA_RX1_MIX Digital Mute", SND_SOC_NOPM,
2185 WSA_MACRO_RX_MIX1, 1, 0, wsa_macro_get_rx_mute_status,
2186 wsa_macro_set_rx_mute_status),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302187 SOC_SINGLE_EXT("WSA_COMP1 Switch", SND_SOC_NOPM, WSA_MACRO_COMP1, 1, 0,
2188 wsa_macro_get_compander, wsa_macro_set_compander),
2189 SOC_SINGLE_EXT("WSA_COMP2 Switch", SND_SOC_NOPM, WSA_MACRO_COMP2, 1, 0,
2190 wsa_macro_get_compander, wsa_macro_set_compander),
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05302191 SOC_SINGLE_EXT("WSA_RX0 EC_HQ Switch", SND_SOC_NOPM, WSA_MACRO_RX0,
2192 1, 0, wsa_macro_get_ec_hq, wsa_macro_set_ec_hq),
2193 SOC_SINGLE_EXT("WSA_RX1 EC_HQ Switch", SND_SOC_NOPM, WSA_MACRO_RX1,
2194 1, 0, wsa_macro_get_ec_hq, wsa_macro_set_ec_hq),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302195};
2196
2197static const struct soc_enum rx_mux_enum =
2198 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_mux_text), rx_mux_text);
2199
2200static const struct snd_kcontrol_new rx_mux[WSA_MACRO_RX_MAX] = {
2201 SOC_DAPM_ENUM_EXT("WSA RX0 Mux", rx_mux_enum,
2202 wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),
2203 SOC_DAPM_ENUM_EXT("WSA RX1 Mux", rx_mux_enum,
2204 wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),
2205 SOC_DAPM_ENUM_EXT("WSA RX_MIX0 Mux", rx_mux_enum,
2206 wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),
2207 SOC_DAPM_ENUM_EXT("WSA RX_MIX1 Mux", rx_mux_enum,
2208 wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),
2209};
2210
2211static int wsa_macro_vi_feed_mixer_get(struct snd_kcontrol *kcontrol,
2212 struct snd_ctl_elem_value *ucontrol)
2213{
2214 struct snd_soc_dapm_widget *widget =
2215 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +08002216 struct snd_soc_component *component =
2217 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302218 struct soc_multi_mixer_control *mixer =
2219 ((struct soc_multi_mixer_control *)kcontrol->private_value);
2220 u32 dai_id = widget->shift;
2221 u32 spk_tx_id = mixer->shift;
2222 struct device *wsa_dev = NULL;
2223 struct wsa_macro_priv *wsa_priv = NULL;
2224
Meng Wang15c825d2018-09-06 10:49:18 +08002225 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302226 return -EINVAL;
2227
2228 if (test_bit(spk_tx_id, &wsa_priv->active_ch_mask[dai_id]))
2229 ucontrol->value.integer.value[0] = 1;
2230 else
2231 ucontrol->value.integer.value[0] = 0;
2232
2233 return 0;
2234}
2235
2236static int wsa_macro_vi_feed_mixer_put(struct snd_kcontrol *kcontrol,
2237 struct snd_ctl_elem_value *ucontrol)
2238{
2239 struct snd_soc_dapm_widget *widget =
2240 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +08002241 struct snd_soc_component *component =
2242 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302243 struct soc_multi_mixer_control *mixer =
2244 ((struct soc_multi_mixer_control *)kcontrol->private_value);
2245 u32 spk_tx_id = mixer->shift;
2246 u32 enable = ucontrol->value.integer.value[0];
2247 struct device *wsa_dev = NULL;
2248 struct wsa_macro_priv *wsa_priv = NULL;
2249
Meng Wang15c825d2018-09-06 10:49:18 +08002250 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302251 return -EINVAL;
2252
2253 wsa_priv->vi_feed_value = ucontrol->value.integer.value[0];
2254
2255 if (enable) {
2256 if (spk_tx_id == WSA_MACRO_TX0 &&
2257 !test_bit(WSA_MACRO_TX0,
2258 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
2259 set_bit(WSA_MACRO_TX0,
2260 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI]);
2261 wsa_priv->active_ch_cnt[WSA_MACRO_AIF_VI]++;
2262 }
2263 if (spk_tx_id == WSA_MACRO_TX1 &&
2264 !test_bit(WSA_MACRO_TX1,
2265 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
2266 set_bit(WSA_MACRO_TX1,
2267 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI]);
2268 wsa_priv->active_ch_cnt[WSA_MACRO_AIF_VI]++;
2269 }
2270 } else {
2271 if (spk_tx_id == WSA_MACRO_TX0 &&
2272 test_bit(WSA_MACRO_TX0,
2273 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
2274 clear_bit(WSA_MACRO_TX0,
2275 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI]);
2276 wsa_priv->active_ch_cnt[WSA_MACRO_AIF_VI]--;
2277 }
2278 if (spk_tx_id == WSA_MACRO_TX1 &&
2279 test_bit(WSA_MACRO_TX1,
2280 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
2281 clear_bit(WSA_MACRO_TX1,
2282 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI]);
2283 wsa_priv->active_ch_cnt[WSA_MACRO_AIF_VI]--;
2284 }
2285 }
2286 snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, NULL);
2287
2288 return 0;
2289}
2290
2291static const struct snd_kcontrol_new aif_vi_mixer[] = {
2292 SOC_SINGLE_EXT("WSA_SPKR_VI_1", SND_SOC_NOPM, WSA_MACRO_TX0, 1, 0,
2293 wsa_macro_vi_feed_mixer_get,
2294 wsa_macro_vi_feed_mixer_put),
2295 SOC_SINGLE_EXT("WSA_SPKR_VI_2", SND_SOC_NOPM, WSA_MACRO_TX1, 1, 0,
2296 wsa_macro_vi_feed_mixer_get,
2297 wsa_macro_vi_feed_mixer_put),
2298};
2299
2300static const struct snd_soc_dapm_widget wsa_macro_dapm_widgets[] = {
2301 SND_SOC_DAPM_AIF_IN("WSA AIF1 PB", "WSA_AIF1 Playback", 0,
2302 SND_SOC_NOPM, 0, 0),
2303
2304 SND_SOC_DAPM_AIF_IN("WSA AIF_MIX1 PB", "WSA_AIF_MIX1 Playback", 0,
2305 SND_SOC_NOPM, 0, 0),
2306
2307 SND_SOC_DAPM_AIF_OUT_E("WSA AIF_VI", "WSA_AIF_VI Capture", 0,
2308 SND_SOC_NOPM, WSA_MACRO_AIF_VI, 0,
2309 wsa_macro_enable_vi_feedback,
2310 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
2311
2312 SND_SOC_DAPM_AIF_OUT("WSA AIF_ECHO", "WSA_AIF_ECHO Capture", 0,
2313 SND_SOC_NOPM, 0, 0),
2314
2315 SND_SOC_DAPM_MIXER("WSA_AIF_VI Mixer", SND_SOC_NOPM, WSA_MACRO_AIF_VI,
2316 0, aif_vi_mixer, ARRAY_SIZE(aif_vi_mixer)),
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05302317 SND_SOC_DAPM_MUX_E("WSA RX_MIX EC0_MUX", SND_SOC_NOPM,
2318 WSA_MACRO_EC0_MUX, 0,
2319 &rx_mix_ec0_mux, wsa_macro_enable_echo,
2320 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2321 SND_SOC_DAPM_MUX_E("WSA RX_MIX EC1_MUX", SND_SOC_NOPM,
2322 WSA_MACRO_EC1_MUX, 0,
2323 &rx_mix_ec1_mux, wsa_macro_enable_echo,
2324 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302325
2326 SND_SOC_DAPM_MUX("WSA RX0 MUX", SND_SOC_NOPM, WSA_MACRO_RX0, 0,
2327 &rx_mux[WSA_MACRO_RX0]),
2328 SND_SOC_DAPM_MUX("WSA RX1 MUX", SND_SOC_NOPM, WSA_MACRO_RX1, 0,
2329 &rx_mux[WSA_MACRO_RX1]),
2330 SND_SOC_DAPM_MUX("WSA RX_MIX0 MUX", SND_SOC_NOPM, WSA_MACRO_RX_MIX0, 0,
2331 &rx_mux[WSA_MACRO_RX_MIX0]),
2332 SND_SOC_DAPM_MUX("WSA RX_MIX1 MUX", SND_SOC_NOPM, WSA_MACRO_RX_MIX1, 0,
2333 &rx_mux[WSA_MACRO_RX_MIX1]),
2334
2335 SND_SOC_DAPM_MIXER("WSA RX0", SND_SOC_NOPM, 0, 0, NULL, 0),
2336 SND_SOC_DAPM_MIXER("WSA RX1", SND_SOC_NOPM, 0, 0, NULL, 0),
2337 SND_SOC_DAPM_MIXER("WSA RX_MIX0", SND_SOC_NOPM, 0, 0, NULL, 0),
2338 SND_SOC_DAPM_MIXER("WSA RX_MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
2339
2340 SND_SOC_DAPM_MUX_E("WSA_RX0 INP0", SND_SOC_NOPM, 0, 0,
2341 &rx0_prim_inp0_mux, wsa_macro_enable_swr,
2342 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2343 SND_SOC_DAPM_MUX_E("WSA_RX0 INP1", SND_SOC_NOPM, 0, 0,
2344 &rx0_prim_inp1_mux, wsa_macro_enable_swr,
2345 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2346 SND_SOC_DAPM_MUX_E("WSA_RX0 INP2", SND_SOC_NOPM, 0, 0,
2347 &rx0_prim_inp2_mux, wsa_macro_enable_swr,
2348 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2349 SND_SOC_DAPM_MUX_E("WSA_RX0 MIX INP", SND_SOC_NOPM, 0, 0,
2350 &rx0_mix_mux, wsa_macro_enable_mix_path,
2351 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2352 SND_SOC_DAPM_MUX_E("WSA_RX1 INP0", SND_SOC_NOPM, 0, 0,
2353 &rx1_prim_inp0_mux, wsa_macro_enable_swr,
2354 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2355 SND_SOC_DAPM_MUX_E("WSA_RX1 INP1", SND_SOC_NOPM, 0, 0,
2356 &rx1_prim_inp1_mux, wsa_macro_enable_swr,
2357 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2358 SND_SOC_DAPM_MUX_E("WSA_RX1 INP2", SND_SOC_NOPM, 0, 0,
2359 &rx1_prim_inp2_mux, wsa_macro_enable_swr,
2360 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2361 SND_SOC_DAPM_MUX_E("WSA_RX1 MIX INP", SND_SOC_NOPM, 0, 0,
2362 &rx1_mix_mux, wsa_macro_enable_mix_path,
2363 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2364 SND_SOC_DAPM_MIXER("WSA_RX INT0 MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
2365 SND_SOC_DAPM_MIXER("WSA_RX INT1 MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
2366 SND_SOC_DAPM_MIXER("WSA_RX INT0 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
2367 SND_SOC_DAPM_MIXER("WSA_RX INT1 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
2368
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302369 SND_SOC_DAPM_MUX_E("WSA_RX0 INT0 SIDETONE MIX",
2370 BOLERO_CDC_WSA_RX0_RX_PATH_CFG1, 4, 0,
2371 &rx0_sidetone_mix_mux, wsa_macro_enable_swr,
2372 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2373 SND_SOC_DAPM_INPUT("WSA SRC0_INP"),
2374
2375 SND_SOC_DAPM_INPUT("WSA_TX DEC0_INP"),
2376 SND_SOC_DAPM_INPUT("WSA_TX DEC1_INP"),
2377
Laxminath Kasam243e2752018-04-12 00:40:19 +05302378 SND_SOC_DAPM_MIXER_E("WSA_RX INT0 INTERP", SND_SOC_NOPM,
2379 WSA_MACRO_COMP1, 0, NULL, 0, wsa_macro_enable_interpolator,
2380 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2381 SND_SOC_DAPM_POST_PMD),
2382 SND_SOC_DAPM_MIXER_E("WSA_RX INT1 INTERP", SND_SOC_NOPM,
2383 WSA_MACRO_COMP2, 0, NULL, 0, wsa_macro_enable_interpolator,
2384 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2385 SND_SOC_DAPM_POST_PMD),
2386
2387 SND_SOC_DAPM_MIXER_E("WSA_RX INT0 CHAIN", SND_SOC_NOPM, 0, 0,
2388 NULL, 0, wsa_macro_spk_boost_event,
Laxminath Kasam0c857002018-07-17 23:47:17 +05302389 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2390 SND_SOC_DAPM_POST_PMD),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302391 SND_SOC_DAPM_MIXER_E("WSA_RX INT1 CHAIN", SND_SOC_NOPM, 0, 0,
2392 NULL, 0, wsa_macro_spk_boost_event,
Laxminath Kasam0c857002018-07-17 23:47:17 +05302393 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2394 SND_SOC_DAPM_POST_PMD),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302395
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302396 SND_SOC_DAPM_MIXER_E("WSA_RX INT0 VBAT", SND_SOC_NOPM,
2397 0, 0, wsa_int0_vbat_mix_switch,
2398 ARRAY_SIZE(wsa_int0_vbat_mix_switch),
2399 wsa_macro_enable_vbat,
2400 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2401 SND_SOC_DAPM_MIXER_E("WSA_RX INT1 VBAT", SND_SOC_NOPM,
2402 0, 0, wsa_int1_vbat_mix_switch,
2403 ARRAY_SIZE(wsa_int1_vbat_mix_switch),
2404 wsa_macro_enable_vbat,
2405 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2406
Laxminath Kasam243e2752018-04-12 00:40:19 +05302407 SND_SOC_DAPM_INPUT("VIINPUT_WSA"),
2408
2409 SND_SOC_DAPM_OUTPUT("WSA_SPK1 OUT"),
2410 SND_SOC_DAPM_OUTPUT("WSA_SPK2 OUT"),
2411
2412 SND_SOC_DAPM_SUPPLY_S("WSA_MCLK", 0, SND_SOC_NOPM, 0, 0,
2413 wsa_macro_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2414};
2415
2416static const struct snd_soc_dapm_route wsa_audio_map[] = {
2417 /* VI Feedback */
2418 {"WSA_AIF_VI Mixer", "WSA_SPKR_VI_1", "VIINPUT_WSA"},
2419 {"WSA_AIF_VI Mixer", "WSA_SPKR_VI_2", "VIINPUT_WSA"},
2420 {"WSA AIF_VI", NULL, "WSA_AIF_VI Mixer"},
2421 {"WSA AIF_VI", NULL, "WSA_MCLK"},
2422
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05302423 {"WSA RX_MIX EC0_MUX", "RX_MIX_TX0", "WSA_RX INT0 SEC MIX"},
2424 {"WSA RX_MIX EC1_MUX", "RX_MIX_TX0", "WSA_RX INT0 SEC MIX"},
2425 {"WSA RX_MIX EC0_MUX", "RX_MIX_TX1", "WSA_RX INT1 SEC MIX"},
2426 {"WSA RX_MIX EC1_MUX", "RX_MIX_TX1", "WSA_RX INT1 SEC MIX"},
2427 {"WSA AIF_ECHO", NULL, "WSA RX_MIX EC0_MUX"},
2428 {"WSA AIF_ECHO", NULL, "WSA RX_MIX EC1_MUX"},
2429 {"WSA AIF_ECHO", NULL, "WSA_MCLK"},
2430
Laxminath Kasam243e2752018-04-12 00:40:19 +05302431 {"WSA AIF1 PB", NULL, "WSA_MCLK"},
2432 {"WSA AIF_MIX1 PB", NULL, "WSA_MCLK"},
2433
2434 {"WSA RX0 MUX", "AIF1_PB", "WSA AIF1 PB"},
2435 {"WSA RX1 MUX", "AIF1_PB", "WSA AIF1 PB"},
2436 {"WSA RX_MIX0 MUX", "AIF1_PB", "WSA AIF1 PB"},
2437 {"WSA RX_MIX1 MUX", "AIF1_PB", "WSA AIF1 PB"},
2438
2439 {"WSA RX0 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
2440 {"WSA RX1 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
2441 {"WSA RX_MIX0 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
2442 {"WSA RX_MIX1 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
2443
2444 {"WSA RX0", NULL, "WSA RX0 MUX"},
2445 {"WSA RX1", NULL, "WSA RX1 MUX"},
2446 {"WSA RX_MIX0", NULL, "WSA RX_MIX0 MUX"},
2447 {"WSA RX_MIX1", NULL, "WSA RX_MIX1 MUX"},
2448
2449 {"WSA_RX0 INP0", "RX0", "WSA RX0"},
2450 {"WSA_RX0 INP0", "RX1", "WSA RX1"},
2451 {"WSA_RX0 INP0", "RX_MIX0", "WSA RX_MIX0"},
2452 {"WSA_RX0 INP0", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302453 {"WSA_RX0 INP0", "DEC0", "WSA_TX DEC0_INP"},
2454 {"WSA_RX0 INP0", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302455 {"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP0"},
2456
2457 {"WSA_RX0 INP1", "RX0", "WSA RX0"},
2458 {"WSA_RX0 INP1", "RX1", "WSA RX1"},
2459 {"WSA_RX0 INP1", "RX_MIX0", "WSA RX_MIX0"},
2460 {"WSA_RX0 INP1", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302461 {"WSA_RX0 INP1", "DEC0", "WSA_TX DEC0_INP"},
2462 {"WSA_RX0 INP1", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302463 {"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP1"},
2464
2465 {"WSA_RX0 INP2", "RX0", "WSA RX0"},
2466 {"WSA_RX0 INP2", "RX1", "WSA RX1"},
2467 {"WSA_RX0 INP2", "RX_MIX0", "WSA RX_MIX0"},
2468 {"WSA_RX0 INP2", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302469 {"WSA_RX0 INP2", "DEC0", "WSA_TX DEC0_INP"},
2470 {"WSA_RX0 INP2", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302471 {"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP2"},
2472
2473 {"WSA_RX0 MIX INP", "RX0", "WSA RX0"},
2474 {"WSA_RX0 MIX INP", "RX1", "WSA RX1"},
2475 {"WSA_RX0 MIX INP", "RX_MIX0", "WSA RX_MIX0"},
2476 {"WSA_RX0 MIX INP", "RX_MIX1", "WSA RX_MIX1"},
2477 {"WSA_RX INT0 SEC MIX", NULL, "WSA_RX0 MIX INP"},
2478
2479 {"WSA_RX INT0 SEC MIX", NULL, "WSA_RX INT0 MIX"},
2480 {"WSA_RX INT0 INTERP", NULL, "WSA_RX INT0 SEC MIX"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302481 {"WSA_RX0 INT0 SIDETONE MIX", "SRC0", "WSA SRC0_INP"},
2482 {"WSA_RX INT0 INTERP", NULL, "WSA_RX0 INT0 SIDETONE MIX"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302483 {"WSA_RX INT0 CHAIN", NULL, "WSA_RX INT0 INTERP"},
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302484
2485 {"WSA_RX INT0 VBAT", "WSA RX0 VBAT Enable", "WSA_RX INT0 INTERP"},
2486 {"WSA_RX INT0 CHAIN", NULL, "WSA_RX INT0 VBAT"},
2487
Laxminath Kasam243e2752018-04-12 00:40:19 +05302488 {"WSA_SPK1 OUT", NULL, "WSA_RX INT0 CHAIN"},
Laxminath Kasamfc281ad2018-08-06 20:19:40 +05302489 {"WSA_SPK1 OUT", NULL, "WSA_MCLK"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302490
2491 {"WSA_RX1 INP0", "RX0", "WSA RX0"},
2492 {"WSA_RX1 INP0", "RX1", "WSA RX1"},
2493 {"WSA_RX1 INP0", "RX_MIX0", "WSA RX_MIX0"},
2494 {"WSA_RX1 INP0", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302495 {"WSA_RX1 INP0", "DEC0", "WSA_TX DEC0_INP"},
2496 {"WSA_RX1 INP0", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302497 {"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP0"},
2498
2499 {"WSA_RX1 INP1", "RX0", "WSA RX0"},
2500 {"WSA_RX1 INP1", "RX1", "WSA RX1"},
2501 {"WSA_RX1 INP1", "RX_MIX0", "WSA RX_MIX0"},
2502 {"WSA_RX1 INP1", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302503 {"WSA_RX1 INP1", "DEC0", "WSA_TX DEC0_INP"},
2504 {"WSA_RX1 INP1", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302505 {"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP1"},
2506
2507 {"WSA_RX1 INP2", "RX0", "WSA RX0"},
2508 {"WSA_RX1 INP2", "RX1", "WSA RX1"},
2509 {"WSA_RX1 INP2", "RX_MIX0", "WSA RX_MIX0"},
2510 {"WSA_RX1 INP2", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302511 {"WSA_RX1 INP2", "DEC0", "WSA_TX DEC0_INP"},
2512 {"WSA_RX1 INP2", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302513 {"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP2"},
2514
2515 {"WSA_RX1 MIX INP", "RX0", "WSA RX0"},
2516 {"WSA_RX1 MIX INP", "RX1", "WSA RX1"},
2517 {"WSA_RX1 MIX INP", "RX_MIX0", "WSA RX_MIX0"},
2518 {"WSA_RX1 MIX INP", "RX_MIX1", "WSA RX_MIX1"},
2519 {"WSA_RX INT1 SEC MIX", NULL, "WSA_RX1 MIX INP"},
2520
2521 {"WSA_RX INT1 SEC MIX", NULL, "WSA_RX INT1 MIX"},
2522 {"WSA_RX INT1 INTERP", NULL, "WSA_RX INT1 SEC MIX"},
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302523
2524 {"WSA_RX INT1 VBAT", "WSA RX1 VBAT Enable", "WSA_RX INT1 INTERP"},
2525 {"WSA_RX INT1 CHAIN", NULL, "WSA_RX INT1 VBAT"},
2526
Laxminath Kasam243e2752018-04-12 00:40:19 +05302527 {"WSA_RX INT1 CHAIN", NULL, "WSA_RX INT1 INTERP"},
2528 {"WSA_SPK2 OUT", NULL, "WSA_RX INT1 CHAIN"},
Laxminath Kasamfc281ad2018-08-06 20:19:40 +05302529 {"WSA_SPK2 OUT", NULL, "WSA_MCLK"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302530};
2531
2532static const struct wsa_macro_reg_mask_val wsa_macro_reg_init[] = {
2533 {BOLERO_CDC_WSA_BOOST0_BOOST_CFG1, 0x3F, 0x12},
2534 {BOLERO_CDC_WSA_BOOST0_BOOST_CFG2, 0x1C, 0x08},
2535 {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x1E, 0x18},
2536 {BOLERO_CDC_WSA_BOOST1_BOOST_CFG1, 0x3F, 0x12},
2537 {BOLERO_CDC_WSA_BOOST1_BOOST_CFG2, 0x1C, 0x08},
2538 {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x1E, 0x18},
2539 {BOLERO_CDC_WSA_BOOST0_BOOST_CTL, 0x70, 0x58},
2540 {BOLERO_CDC_WSA_BOOST1_BOOST_CTL, 0x70, 0x58},
2541 {BOLERO_CDC_WSA_RX0_RX_PATH_CFG1, 0x08, 0x08},
2542 {BOLERO_CDC_WSA_RX1_RX_PATH_CFG1, 0x08, 0x08},
2543 {BOLERO_CDC_WSA_TOP_TOP_CFG1, 0x02, 0x02},
2544 {BOLERO_CDC_WSA_TOP_TOP_CFG1, 0x01, 0x01},
2545 {BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
2546 {BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
2547 {BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
2548 {BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
2549 {BOLERO_CDC_WSA_COMPANDER0_CTL3, 0x80, 0x80},
2550 {BOLERO_CDC_WSA_COMPANDER1_CTL3, 0x80, 0x80},
2551 {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x01, 0x01},
2552 {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x01, 0x01},
2553 {BOLERO_CDC_WSA_RX0_RX_PATH_CFG0, 0x01, 0x01},
2554 {BOLERO_CDC_WSA_RX1_RX_PATH_CFG0, 0x01, 0x01},
2555 {BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CFG, 0x01, 0x01},
2556 {BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CFG, 0x01, 0x01},
2557};
2558
Meng Wang15c825d2018-09-06 10:49:18 +08002559static void wsa_macro_init_bcl_pmic_reg(struct snd_soc_component *component)
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302560{
2561 struct device *wsa_dev = NULL;
2562 struct wsa_macro_priv *wsa_priv = NULL;
2563
Meng Wang15c825d2018-09-06 10:49:18 +08002564 if (!component) {
2565 pr_err("%s: NULL component pointer!\n", __func__);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302566 return;
2567 }
2568
Meng Wang15c825d2018-09-06 10:49:18 +08002569 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302570 return;
2571
2572 switch (wsa_priv->bcl_pmic_params.id) {
2573 case 0:
2574 /* Enable ID0 to listen to respective PMIC group interrupts */
Meng Wang15c825d2018-09-06 10:49:18 +08002575 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302576 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CTL1, 0x02, 0x02);
2577 /* Update MC_SID0 */
Meng Wang15c825d2018-09-06 10:49:18 +08002578 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302579 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG1, 0x0F,
2580 wsa_priv->bcl_pmic_params.sid);
2581 /* Update MC_PPID0 */
Meng Wang15c825d2018-09-06 10:49:18 +08002582 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302583 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG2, 0xFF,
2584 wsa_priv->bcl_pmic_params.ppid);
2585 break;
2586 case 1:
2587 /* Enable ID1 to listen to respective PMIC group interrupts */
Meng Wang15c825d2018-09-06 10:49:18 +08002588 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302589 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CTL1, 0x01, 0x01);
2590 /* Update MC_SID1 */
Meng Wang15c825d2018-09-06 10:49:18 +08002591 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302592 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG3, 0x0F,
2593 wsa_priv->bcl_pmic_params.sid);
2594 /* Update MC_PPID1 */
Meng Wang15c825d2018-09-06 10:49:18 +08002595 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302596 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG4, 0xFF,
2597 wsa_priv->bcl_pmic_params.ppid);
2598 break;
2599 default:
2600 dev_err(wsa_dev, "%s: PMIC ID is invalid %d\n",
2601 __func__, wsa_priv->bcl_pmic_params.id);
2602 break;
2603 }
2604}
2605
Meng Wang15c825d2018-09-06 10:49:18 +08002606static void wsa_macro_init_reg(struct snd_soc_component *component)
Laxminath Kasam243e2752018-04-12 00:40:19 +05302607{
2608 int i;
2609
2610 for (i = 0; i < ARRAY_SIZE(wsa_macro_reg_init); i++)
Meng Wang15c825d2018-09-06 10:49:18 +08002611 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302612 wsa_macro_reg_init[i].reg,
2613 wsa_macro_reg_init[i].mask,
2614 wsa_macro_reg_init[i].val);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302615
Meng Wang15c825d2018-09-06 10:49:18 +08002616 wsa_macro_init_bcl_pmic_reg(component);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302617}
2618
2619static int wsa_swrm_clock(void *handle, bool enable)
2620{
2621 struct wsa_macro_priv *wsa_priv = (struct wsa_macro_priv *) handle;
2622 struct regmap *regmap = dev_get_regmap(wsa_priv->dev->parent, NULL);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302623 int ret = 0;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302624
Tanya Dixitab8eba82018-10-05 15:07:37 +05302625 if (regmap == NULL) {
2626 dev_err(wsa_priv->dev, "%s: regmap is NULL\n", __func__);
2627 return -EINVAL;
2628 }
2629
Laxminath Kasam243e2752018-04-12 00:40:19 +05302630 mutex_lock(&wsa_priv->swr_clk_lock);
2631
2632 dev_dbg(wsa_priv->dev, "%s: swrm clock %s\n",
2633 __func__, (enable ? "enable" : "disable"));
2634 if (enable) {
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302635 pm_runtime_get_sync(wsa_priv->dev);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302636 if (wsa_priv->swr_clk_users == 0) {
Karthikeyan Mani01f1ba42019-02-26 18:48:15 -08002637 msm_cdc_pinctrl_select_active_state(
2638 wsa_priv->wsa_swr_gpio_p);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302639 ret = wsa_macro_mclk_enable(wsa_priv, 1, true);
2640 if (ret < 0) {
Karthikeyan Mani01f1ba42019-02-26 18:48:15 -08002641 msm_cdc_pinctrl_select_sleep_state(
2642 wsa_priv->wsa_swr_gpio_p);
Ramprasad Katkam14efed62019-03-07 13:16:50 +05302643 dev_err_ratelimited(wsa_priv->dev,
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302644 "%s: wsa request clock enable failed\n",
2645 __func__);
2646 goto exit;
2647 }
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05302648 if (wsa_priv->reset_swr)
2649 regmap_update_bits(regmap,
2650 BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
2651 0x02, 0x02);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302652 regmap_update_bits(regmap,
2653 BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
2654 0x01, 0x01);
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05302655 if (wsa_priv->reset_swr)
2656 regmap_update_bits(regmap,
2657 BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
2658 0x02, 0x00);
2659 wsa_priv->reset_swr = false;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302660 }
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302661 pm_runtime_mark_last_busy(wsa_priv->dev);
2662 pm_runtime_put_autosuspend(wsa_priv->dev);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302663 wsa_priv->swr_clk_users++;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302664 } else {
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302665 if (wsa_priv->swr_clk_users <= 0) {
2666 dev_err(wsa_priv->dev, "%s: clock already disabled\n",
2667 __func__);
2668 wsa_priv->swr_clk_users = 0;
2669 goto exit;
2670 }
Laxminath Kasam243e2752018-04-12 00:40:19 +05302671 wsa_priv->swr_clk_users--;
2672 if (wsa_priv->swr_clk_users == 0) {
2673 regmap_update_bits(regmap,
2674 BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
2675 0x01, 0x00);
Karthikeyan Mani01f1ba42019-02-26 18:48:15 -08002676 wsa_macro_mclk_enable(wsa_priv, 0, true);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302677 msm_cdc_pinctrl_select_sleep_state(
2678 wsa_priv->wsa_swr_gpio_p);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302679 }
2680 }
2681 dev_dbg(wsa_priv->dev, "%s: swrm clock users %d\n",
2682 __func__, wsa_priv->swr_clk_users);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302683exit:
Laxminath Kasam243e2752018-04-12 00:40:19 +05302684 mutex_unlock(&wsa_priv->swr_clk_lock);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302685 return ret;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302686}
2687
Meng Wang15c825d2018-09-06 10:49:18 +08002688static int wsa_macro_init(struct snd_soc_component *component)
Laxminath Kasam243e2752018-04-12 00:40:19 +05302689{
Meng Wang15c825d2018-09-06 10:49:18 +08002690 struct snd_soc_dapm_context *dapm =
2691 snd_soc_component_get_dapm(component);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302692 int ret;
2693 struct device *wsa_dev = NULL;
2694 struct wsa_macro_priv *wsa_priv = NULL;
2695
Meng Wang15c825d2018-09-06 10:49:18 +08002696 wsa_dev = bolero_get_device_ptr(component->dev, WSA_MACRO);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302697 if (!wsa_dev) {
Meng Wang15c825d2018-09-06 10:49:18 +08002698 dev_err(component->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302699 "%s: null device for macro!\n", __func__);
2700 return -EINVAL;
2701 }
2702 wsa_priv = dev_get_drvdata(wsa_dev);
2703 if (!wsa_priv) {
Meng Wang15c825d2018-09-06 10:49:18 +08002704 dev_err(component->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302705 "%s: priv is null for macro!\n", __func__);
2706 return -EINVAL;
2707 }
2708
2709 ret = snd_soc_dapm_new_controls(dapm, wsa_macro_dapm_widgets,
2710 ARRAY_SIZE(wsa_macro_dapm_widgets));
2711 if (ret < 0) {
2712 dev_err(wsa_dev, "%s: Failed to add controls\n", __func__);
2713 return ret;
2714 }
2715
2716 ret = snd_soc_dapm_add_routes(dapm, wsa_audio_map,
2717 ARRAY_SIZE(wsa_audio_map));
2718 if (ret < 0) {
2719 dev_err(wsa_dev, "%s: Failed to add routes\n", __func__);
2720 return ret;
2721 }
2722
2723 ret = snd_soc_dapm_new_widgets(dapm->card);
2724 if (ret < 0) {
2725 dev_err(wsa_dev, "%s: Failed to add widgets\n", __func__);
2726 return ret;
2727 }
2728
Meng Wang15c825d2018-09-06 10:49:18 +08002729 ret = snd_soc_add_component_controls(component, wsa_macro_snd_controls,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302730 ARRAY_SIZE(wsa_macro_snd_controls));
2731 if (ret < 0) {
2732 dev_err(wsa_dev, "%s: Failed to add snd_ctls\n", __func__);
2733 return ret;
2734 }
Laxminath Kasam638b5602018-09-24 13:19:52 +05302735 snd_soc_dapm_ignore_suspend(dapm, "WSA_AIF1 Playback");
2736 snd_soc_dapm_ignore_suspend(dapm, "WSA_AIF_MIX1 Playback");
2737 snd_soc_dapm_ignore_suspend(dapm, "WSA_AIF_VI Capture");
2738 snd_soc_dapm_ignore_suspend(dapm, "WSA_AIF_ECHO Capture");
2739 snd_soc_dapm_ignore_suspend(dapm, "WSA_SPK1 OUT");
2740 snd_soc_dapm_ignore_suspend(dapm, "WSA_SPK2 OUT");
2741 snd_soc_dapm_ignore_suspend(dapm, "VIINPUT_WSA");
2742 snd_soc_dapm_ignore_suspend(dapm, "WSA SRC0_INP");
2743 snd_soc_dapm_ignore_suspend(dapm, "WSA_TX DEC0_INP");
2744 snd_soc_dapm_ignore_suspend(dapm, "WSA_TX DEC1_INP");
2745 snd_soc_dapm_sync(dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302746
Meng Wang15c825d2018-09-06 10:49:18 +08002747 wsa_priv->component = component;
Laxminath Kasam21c8b222018-06-21 18:47:22 +05302748 wsa_priv->spkr_gain_offset = WSA_MACRO_GAIN_OFFSET_0_DB;
Meng Wang15c825d2018-09-06 10:49:18 +08002749 wsa_macro_init_reg(component);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302750
2751 return 0;
2752}
2753
Meng Wang15c825d2018-09-06 10:49:18 +08002754static int wsa_macro_deinit(struct snd_soc_component *component)
Laxminath Kasam243e2752018-04-12 00:40:19 +05302755{
2756 struct device *wsa_dev = NULL;
2757 struct wsa_macro_priv *wsa_priv = NULL;
2758
Meng Wang15c825d2018-09-06 10:49:18 +08002759 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302760 return -EINVAL;
2761
Meng Wang15c825d2018-09-06 10:49:18 +08002762 wsa_priv->component = NULL;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302763
2764 return 0;
2765}
2766
2767static void wsa_macro_add_child_devices(struct work_struct *work)
2768{
2769 struct wsa_macro_priv *wsa_priv;
2770 struct platform_device *pdev;
2771 struct device_node *node;
2772 struct wsa_macro_swr_ctrl_data *swr_ctrl_data = NULL, *temp;
2773 int ret;
2774 u16 count = 0, ctrl_num = 0;
2775 struct wsa_macro_swr_ctrl_platform_data *platdata;
2776 char plat_dev_name[WSA_MACRO_SWR_STRING_LEN];
2777
2778 wsa_priv = container_of(work, struct wsa_macro_priv,
2779 wsa_macro_add_child_devices_work);
2780 if (!wsa_priv) {
2781 pr_err("%s: Memory for wsa_priv does not exist\n",
2782 __func__);
2783 return;
2784 }
Laxminath Kasam21c8b222018-06-21 18:47:22 +05302785 if (!wsa_priv->dev || !wsa_priv->dev->of_node) {
Laxminath Kasam243e2752018-04-12 00:40:19 +05302786 dev_err(wsa_priv->dev,
2787 "%s: DT node for wsa_priv does not exist\n", __func__);
2788 return;
2789 }
2790
2791 platdata = &wsa_priv->swr_plat_data;
2792 wsa_priv->child_count = 0;
2793
2794 for_each_available_child_of_node(wsa_priv->dev->of_node, node) {
2795 if (strnstr(node->name, "wsa_swr_master",
2796 strlen("wsa_swr_master")) != NULL)
2797 strlcpy(plat_dev_name, "wsa_swr_ctrl",
2798 (WSA_MACRO_SWR_STRING_LEN - 1));
2799 else if (strnstr(node->name, "msm_cdc_pinctrl",
2800 strlen("msm_cdc_pinctrl")) != NULL)
2801 strlcpy(plat_dev_name, node->name,
2802 (WSA_MACRO_SWR_STRING_LEN - 1));
2803 else
2804 continue;
2805
2806 pdev = platform_device_alloc(plat_dev_name, -1);
2807 if (!pdev) {
2808 dev_err(wsa_priv->dev, "%s: pdev memory alloc failed\n",
2809 __func__);
2810 ret = -ENOMEM;
2811 goto err;
2812 }
2813 pdev->dev.parent = wsa_priv->dev;
2814 pdev->dev.of_node = node;
2815
2816 if (strnstr(node->name, "wsa_swr_master",
2817 strlen("wsa_swr_master")) != NULL) {
2818 ret = platform_device_add_data(pdev, platdata,
2819 sizeof(*platdata));
2820 if (ret) {
2821 dev_err(&pdev->dev,
2822 "%s: cannot add plat data ctrl:%d\n",
2823 __func__, ctrl_num);
2824 goto fail_pdev_add;
2825 }
2826 }
2827
2828 ret = platform_device_add(pdev);
2829 if (ret) {
2830 dev_err(&pdev->dev,
2831 "%s: Cannot add platform device\n",
2832 __func__);
2833 goto fail_pdev_add;
2834 }
2835
2836 if (!strcmp(node->name, "wsa_swr_master")) {
2837 temp = krealloc(swr_ctrl_data,
2838 (ctrl_num + 1) * sizeof(
2839 struct wsa_macro_swr_ctrl_data),
2840 GFP_KERNEL);
2841 if (!temp) {
2842 dev_err(&pdev->dev, "out of memory\n");
2843 ret = -ENOMEM;
2844 goto err;
2845 }
2846 swr_ctrl_data = temp;
2847 swr_ctrl_data[ctrl_num].wsa_swr_pdev = pdev;
2848 ctrl_num++;
2849 dev_dbg(&pdev->dev,
2850 "%s: Added soundwire ctrl device(s)\n",
2851 __func__);
2852 wsa_priv->swr_ctrl_data = swr_ctrl_data;
2853 }
2854 if (wsa_priv->child_count < WSA_MACRO_CHILD_DEVICES_MAX)
2855 wsa_priv->pdev_child_devices[
2856 wsa_priv->child_count++] = pdev;
2857 else
2858 goto err;
2859 }
2860
2861 return;
2862fail_pdev_add:
2863 for (count = 0; count < wsa_priv->child_count; count++)
2864 platform_device_put(wsa_priv->pdev_child_devices[count]);
2865err:
2866 return;
2867}
2868
2869static void wsa_macro_init_ops(struct macro_ops *ops,
2870 char __iomem *wsa_io_base)
2871{
2872 memset(ops, 0, sizeof(struct macro_ops));
2873 ops->init = wsa_macro_init;
2874 ops->exit = wsa_macro_deinit;
2875 ops->io_base = wsa_io_base;
2876 ops->dai_ptr = wsa_macro_dai;
2877 ops->num_dais = ARRAY_SIZE(wsa_macro_dai);
Laxminath Kasamfb0d6832018-09-22 01:49:52 +05302878 ops->event_handler = wsa_macro_event_handler;
Sudheer Papothia3e969d2018-10-27 06:22:10 +05302879 ops->set_port_map = wsa_macro_set_port_map;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302880}
2881
2882static int wsa_macro_probe(struct platform_device *pdev)
2883{
2884 struct macro_ops ops;
2885 struct wsa_macro_priv *wsa_priv;
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07002886 u32 wsa_base_addr, default_clk_id;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302887 char __iomem *wsa_io_base;
2888 int ret = 0;
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302889 u8 bcl_pmic_params[3];
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07002890 u32 is_used_wsa_swr_gpio = 1;
2891 const char *is_used_wsa_swr_gpio_dt = "qcom,is-used-swr-gpio";
Laxminath Kasam243e2752018-04-12 00:40:19 +05302892
2893 wsa_priv = devm_kzalloc(&pdev->dev, sizeof(struct wsa_macro_priv),
2894 GFP_KERNEL);
2895 if (!wsa_priv)
2896 return -ENOMEM;
2897
2898 wsa_priv->dev = &pdev->dev;
2899 ret = of_property_read_u32(pdev->dev.of_node, "reg",
2900 &wsa_base_addr);
2901 if (ret) {
2902 dev_err(&pdev->dev, "%s: could not find %s entry in dt\n",
2903 __func__, "reg");
2904 return ret;
2905 }
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07002906 if (of_find_property(pdev->dev.of_node, is_used_wsa_swr_gpio_dt,
2907 NULL)) {
2908 ret = of_property_read_u32(pdev->dev.of_node,
2909 is_used_wsa_swr_gpio_dt,
2910 &is_used_wsa_swr_gpio);
2911 if (ret) {
2912 dev_err(&pdev->dev, "%s: error reading %s in dt\n",
2913 __func__, is_used_wsa_swr_gpio_dt);
2914 is_used_wsa_swr_gpio = 1;
2915 }
2916 }
Laxminath Kasam243e2752018-04-12 00:40:19 +05302917 wsa_priv->wsa_swr_gpio_p = of_parse_phandle(pdev->dev.of_node,
2918 "qcom,wsa-swr-gpios", 0);
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07002919 if (!wsa_priv->wsa_swr_gpio_p && is_used_wsa_swr_gpio) {
Laxminath Kasam243e2752018-04-12 00:40:19 +05302920 dev_err(&pdev->dev, "%s: swr_gpios handle not provided!\n",
2921 __func__);
2922 return -EINVAL;
2923 }
2924 wsa_io_base = devm_ioremap(&pdev->dev,
2925 wsa_base_addr, WSA_MACRO_MAX_OFFSET);
2926 if (!wsa_io_base) {
2927 dev_err(&pdev->dev, "%s: ioremap failed\n", __func__);
2928 return -EINVAL;
2929 }
2930 wsa_priv->wsa_io_base = wsa_io_base;
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05302931 wsa_priv->reset_swr = true;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302932 INIT_WORK(&wsa_priv->wsa_macro_add_child_devices_work,
2933 wsa_macro_add_child_devices);
2934 wsa_priv->swr_plat_data.handle = (void *) wsa_priv;
2935 wsa_priv->swr_plat_data.read = NULL;
2936 wsa_priv->swr_plat_data.write = NULL;
2937 wsa_priv->swr_plat_data.bulk_write = NULL;
2938 wsa_priv->swr_plat_data.clk = wsa_swrm_clock;
2939 wsa_priv->swr_plat_data.handle_irq = NULL;
2940
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07002941 ret = of_property_read_u32(pdev->dev.of_node, "qcom,default-clk-id",
2942 &default_clk_id);
2943 if (ret) {
2944 dev_err(&pdev->dev, "%s: could not find %s entry in dt\n",
2945 __func__, "qcom,mux0-clk-id");
2946 default_clk_id = WSA_CORE_CLK;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302947 }
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302948
2949 ret = of_property_read_u8_array(pdev->dev.of_node,
2950 "qcom,wsa-bcl-pmic-params", bcl_pmic_params,
2951 sizeof(bcl_pmic_params));
2952 if (ret) {
2953 dev_dbg(&pdev->dev, "%s: could not find %s entry in dt\n",
2954 __func__, "qcom,wsa-bcl-pmic-params");
2955 } else {
2956 wsa_priv->bcl_pmic_params.id = bcl_pmic_params[0];
2957 wsa_priv->bcl_pmic_params.sid = bcl_pmic_params[1];
2958 wsa_priv->bcl_pmic_params.ppid = bcl_pmic_params[2];
2959 }
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07002960 wsa_priv->default_clk_id = default_clk_id;
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302961
Laxminath Kasam243e2752018-04-12 00:40:19 +05302962 dev_set_drvdata(&pdev->dev, wsa_priv);
2963 mutex_init(&wsa_priv->mclk_lock);
2964 mutex_init(&wsa_priv->swr_clk_lock);
2965 wsa_macro_init_ops(&ops, wsa_io_base);
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07002966 ops.clk_id_req = wsa_priv->default_clk_id;
2967 ops.default_clk_id = wsa_priv->default_clk_id;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302968 ret = bolero_register_macro(&pdev->dev, WSA_MACRO, &ops);
2969 if (ret < 0) {
2970 dev_err(&pdev->dev, "%s: register macro failed\n", __func__);
2971 goto reg_macro_fail;
2972 }
2973 schedule_work(&wsa_priv->wsa_macro_add_child_devices_work);
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302974 pm_runtime_set_autosuspend_delay(&pdev->dev, AUTO_SUSPEND_DELAY);
2975 pm_runtime_use_autosuspend(&pdev->dev);
2976 pm_runtime_set_suspended(&pdev->dev);
2977 pm_runtime_enable(&pdev->dev);
2978
Laxminath Kasam243e2752018-04-12 00:40:19 +05302979 return ret;
2980reg_macro_fail:
2981 mutex_destroy(&wsa_priv->mclk_lock);
2982 mutex_destroy(&wsa_priv->swr_clk_lock);
2983 return ret;
2984}
2985
2986static int wsa_macro_remove(struct platform_device *pdev)
2987{
2988 struct wsa_macro_priv *wsa_priv;
2989 u16 count = 0;
2990
2991 wsa_priv = dev_get_drvdata(&pdev->dev);
2992
2993 if (!wsa_priv)
2994 return -EINVAL;
2995
2996 for (count = 0; count < wsa_priv->child_count &&
2997 count < WSA_MACRO_CHILD_DEVICES_MAX; count++)
2998 platform_device_unregister(wsa_priv->pdev_child_devices[count]);
2999
Sudheer Papothi7601cc62019-03-30 03:00:52 +05303000 pm_runtime_disable(&pdev->dev);
3001 pm_runtime_set_suspended(&pdev->dev);
Laxminath Kasam243e2752018-04-12 00:40:19 +05303002 bolero_unregister_macro(&pdev->dev, WSA_MACRO);
3003 mutex_destroy(&wsa_priv->mclk_lock);
3004 mutex_destroy(&wsa_priv->swr_clk_lock);
3005 return 0;
3006}
3007
3008static const struct of_device_id wsa_macro_dt_match[] = {
3009 {.compatible = "qcom,wsa-macro"},
3010 {}
3011};
3012
Sudheer Papothi7601cc62019-03-30 03:00:52 +05303013static const struct dev_pm_ops bolero_dev_pm_ops = {
3014 SET_RUNTIME_PM_OPS(
3015 bolero_runtime_suspend,
3016 bolero_runtime_resume,
3017 NULL
3018 )
3019};
3020
Laxminath Kasam243e2752018-04-12 00:40:19 +05303021static struct platform_driver wsa_macro_driver = {
3022 .driver = {
3023 .name = "wsa_macro",
3024 .owner = THIS_MODULE,
Sudheer Papothi7601cc62019-03-30 03:00:52 +05303025 .pm = &bolero_dev_pm_ops,
Laxminath Kasam243e2752018-04-12 00:40:19 +05303026 .of_match_table = wsa_macro_dt_match,
Xiaojun Sang53cd13a2018-06-29 15:14:37 +08003027 .suppress_bind_attrs = true,
Laxminath Kasam243e2752018-04-12 00:40:19 +05303028 },
3029 .probe = wsa_macro_probe,
3030 .remove = wsa_macro_remove,
3031};
3032
3033module_platform_driver(wsa_macro_driver);
3034
3035MODULE_DESCRIPTION("WSA macro driver");
3036MODULE_LICENSE("GPL v2");