blob: a1dcdda41e08d6aaa2cffd915df511d845328e01 [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;
Meng Wangbd930242019-06-25 09:39:48 +0800908 int ret = 0;
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530909
Meng Wang15c825d2018-09-06 10:49:18 +0800910 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530911 return -EINVAL;
912
913 switch (event) {
914 case BOLERO_MACRO_EVT_SSR_DOWN:
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -0700915 if (wsa_priv->swr_ctrl_data) {
916 swrm_wcd_notify(
917 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
918 SWR_DEVICE_DOWN, NULL);
919 swrm_wcd_notify(
920 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
921 SWR_DEVICE_SSR_DOWN, NULL);
922 }
Aditya Bavanari50ef13e2019-08-09 15:14:43 +0530923 if ((!pm_runtime_enabled(wsa_dev) ||
924 !pm_runtime_suspended(wsa_dev))) {
925 ret = bolero_runtime_suspend(wsa_dev);
926 if (!ret) {
927 pm_runtime_disable(wsa_dev);
928 pm_runtime_set_suspended(wsa_dev);
929 pm_runtime_enable(wsa_dev);
930 }
931 }
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530932 break;
933 case BOLERO_MACRO_EVT_SSR_UP:
Ramprasad Katkama4c747b2018-12-11 19:15:53 +0530934 /* reset swr after ssr/pdr */
935 wsa_priv->reset_swr = true;
Meng Wangbd930242019-06-25 09:39:48 +0800936 /* enable&disable WSA_CORE_CLK to reset GFMUX reg */
937 ret = bolero_clk_rsc_request_clock(wsa_priv->dev,
938 wsa_priv->default_clk_id,
939 WSA_CORE_CLK, true);
940 if (ret < 0)
941 dev_err_ratelimited(wsa_priv->dev,
942 "%s, failed to enable clk, ret:%d\n",
943 __func__, ret);
944 else
945 bolero_clk_rsc_request_clock(wsa_priv->dev,
946 wsa_priv->default_clk_id,
947 WSA_CORE_CLK, false);
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -0700948 if (wsa_priv->swr_ctrl_data)
949 swrm_wcd_notify(
950 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
951 SWR_DEVICE_SSR_UP, NULL);
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530952 break;
Meng Wang8ef0cc22019-05-08 15:12:56 +0800953 case BOLERO_MACRO_EVT_CLK_RESET:
954 bolero_rsc_clk_reset(wsa_dev, WSA_CORE_CLK);
955 break;
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530956 }
957 return 0;
958}
959
Laxminath Kasam243e2752018-04-12 00:40:19 +0530960static int wsa_macro_enable_vi_feedback(struct snd_soc_dapm_widget *w,
961 struct snd_kcontrol *kcontrol,
962 int event)
963{
Meng Wang15c825d2018-09-06 10:49:18 +0800964 struct snd_soc_component *component =
965 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530966 struct device *wsa_dev = NULL;
967 struct wsa_macro_priv *wsa_priv = NULL;
968
Meng Wang15c825d2018-09-06 10:49:18 +0800969 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530970 return -EINVAL;
971
972 switch (event) {
973 case SND_SOC_DAPM_POST_PMU:
974 if (test_bit(WSA_MACRO_TX0,
975 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
976 dev_dbg(wsa_dev, "%s: spkr1 enabled\n", __func__);
977 /* Enable V&I sensing */
Meng Wang15c825d2018-09-06 10:49:18 +0800978 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530979 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
980 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +0800981 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530982 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
983 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +0800984 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530985 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
986 0x0F, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +0800987 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530988 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
989 0x0F, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +0800990 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530991 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
992 0x10, 0x10);
Meng Wang15c825d2018-09-06 10:49:18 +0800993 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530994 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
995 0x10, 0x10);
Meng Wang15c825d2018-09-06 10:49:18 +0800996 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530997 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
998 0x20, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +0800999 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301000 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
1001 0x20, 0x00);
1002 }
1003 if (test_bit(WSA_MACRO_TX1,
1004 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
1005 dev_dbg(wsa_dev, "%s: spkr2 enabled\n", __func__);
1006 /* Enable V&I sensing */
Meng Wang15c825d2018-09-06 10:49:18 +08001007 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301008 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
1009 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08001010 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301011 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
1012 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08001013 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301014 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
1015 0x0F, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001016 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301017 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
1018 0x0F, 0x00);
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_TX2_SPKR_PROT_PATH_CTL,
1021 0x10, 0x10);
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_TX3_SPKR_PROT_PATH_CTL,
1024 0x10, 0x10);
Meng Wang15c825d2018-09-06 10:49:18 +08001025 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301026 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
1027 0x20, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001028 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301029 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
1030 0x20, 0x00);
1031 }
1032 break;
1033 case SND_SOC_DAPM_POST_PMD:
1034 if (test_bit(WSA_MACRO_TX0,
1035 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
1036 /* Disable V&I sensing */
Meng Wang15c825d2018-09-06 10:49:18 +08001037 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301038 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
1039 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08001040 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301041 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
1042 0x20, 0x20);
1043 dev_dbg(wsa_dev, "%s: spkr1 disabled\n", __func__);
Meng Wang15c825d2018-09-06 10:49:18 +08001044 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301045 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
1046 0x10, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001047 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301048 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
1049 0x10, 0x00);
1050 }
1051 if (test_bit(WSA_MACRO_TX1,
1052 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
1053 /* Disable V&I sensing */
1054 dev_dbg(wsa_dev, "%s: spkr2 disabled\n", __func__);
Meng Wang15c825d2018-09-06 10:49:18 +08001055 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301056 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
1057 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08001058 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301059 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
1060 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08001061 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301062 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
1063 0x10, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001064 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301065 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
1066 0x10, 0x00);
1067 }
1068 break;
1069 }
1070
1071 return 0;
1072}
1073
1074static int wsa_macro_enable_mix_path(struct snd_soc_dapm_widget *w,
1075 struct snd_kcontrol *kcontrol, int event)
1076{
Meng Wang15c825d2018-09-06 10:49:18 +08001077 struct snd_soc_component *component =
1078 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301079 u16 gain_reg;
1080 int offset_val = 0;
1081 int val = 0;
1082
Meng Wang15c825d2018-09-06 10:49:18 +08001083 dev_dbg(component->dev, "%s %d %s\n", __func__, event, w->name);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301084
1085 switch (w->reg) {
1086 case BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL:
1087 gain_reg = BOLERO_CDC_WSA_RX0_RX_VOL_MIX_CTL;
1088 break;
1089 case BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL:
1090 gain_reg = BOLERO_CDC_WSA_RX1_RX_VOL_MIX_CTL;
1091 break;
1092 default:
Meng Wang15c825d2018-09-06 10:49:18 +08001093 dev_err(component->dev, "%s: No gain register avail for %s\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301094 __func__, w->name);
1095 return 0;
1096 }
1097
1098 switch (event) {
1099 case SND_SOC_DAPM_POST_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08001100 val = snd_soc_component_read32(component, gain_reg);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301101 val += offset_val;
Meng Wang15c825d2018-09-06 10:49:18 +08001102 snd_soc_component_write(component, gain_reg, val);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301103 break;
1104 case SND_SOC_DAPM_POST_PMD:
1105 break;
1106 }
1107
1108 return 0;
1109}
1110
Meng Wang15c825d2018-09-06 10:49:18 +08001111static void wsa_macro_hd2_control(struct snd_soc_component *component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301112 u16 reg, int event)
1113{
1114 u16 hd2_scale_reg;
1115 u16 hd2_enable_reg = 0;
1116
1117 if (reg == BOLERO_CDC_WSA_RX0_RX_PATH_CTL) {
1118 hd2_scale_reg = BOLERO_CDC_WSA_RX0_RX_PATH_SEC3;
1119 hd2_enable_reg = BOLERO_CDC_WSA_RX0_RX_PATH_CFG0;
1120 }
1121 if (reg == BOLERO_CDC_WSA_RX1_RX_PATH_CTL) {
1122 hd2_scale_reg = BOLERO_CDC_WSA_RX1_RX_PATH_SEC3;
1123 hd2_enable_reg = BOLERO_CDC_WSA_RX1_RX_PATH_CFG0;
1124 }
1125
1126 if (hd2_enable_reg && SND_SOC_DAPM_EVENT_ON(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001127 snd_soc_component_update_bits(component, hd2_scale_reg,
1128 0x3C, 0x10);
1129 snd_soc_component_update_bits(component, hd2_scale_reg,
1130 0x03, 0x01);
1131 snd_soc_component_update_bits(component, hd2_enable_reg,
1132 0x04, 0x04);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301133 }
1134
1135 if (hd2_enable_reg && SND_SOC_DAPM_EVENT_OFF(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001136 snd_soc_component_update_bits(component, hd2_enable_reg,
1137 0x04, 0x00);
1138 snd_soc_component_update_bits(component, hd2_scale_reg,
1139 0x03, 0x00);
1140 snd_soc_component_update_bits(component, hd2_scale_reg,
1141 0x3C, 0x00);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301142 }
1143}
1144
1145static int wsa_macro_enable_swr(struct snd_soc_dapm_widget *w,
1146 struct snd_kcontrol *kcontrol, int event)
1147{
Meng Wang15c825d2018-09-06 10:49:18 +08001148 struct snd_soc_component *component =
1149 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301150 int ch_cnt;
1151 struct device *wsa_dev = NULL;
1152 struct wsa_macro_priv *wsa_priv = NULL;
1153
Meng Wang15c825d2018-09-06 10:49:18 +08001154 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301155 return -EINVAL;
1156
1157 switch (event) {
1158 case SND_SOC_DAPM_PRE_PMU:
1159 if (!(strnstr(w->name, "RX0", sizeof("WSA_RX0"))) &&
1160 !wsa_priv->rx_0_count)
1161 wsa_priv->rx_0_count++;
1162 if (!(strnstr(w->name, "RX1", sizeof("WSA_RX1"))) &&
1163 !wsa_priv->rx_1_count)
1164 wsa_priv->rx_1_count++;
1165 ch_cnt = wsa_priv->rx_0_count + wsa_priv->rx_1_count;
1166
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07001167 if (wsa_priv->swr_ctrl_data) {
1168 swrm_wcd_notify(
1169 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
1170 SWR_DEVICE_UP, NULL);
1171 swrm_wcd_notify(
1172 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
1173 SWR_SET_NUM_RX_CH, &ch_cnt);
1174 }
Laxminath Kasam243e2752018-04-12 00:40:19 +05301175 break;
1176 case SND_SOC_DAPM_POST_PMD:
1177 if (!(strnstr(w->name, "RX0", sizeof("WSA_RX0"))) &&
1178 wsa_priv->rx_0_count)
1179 wsa_priv->rx_0_count--;
1180 if (!(strnstr(w->name, "RX1", sizeof("WSA_RX1"))) &&
1181 wsa_priv->rx_1_count)
1182 wsa_priv->rx_1_count--;
1183 ch_cnt = wsa_priv->rx_0_count + wsa_priv->rx_1_count;
1184
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07001185 if (wsa_priv->swr_ctrl_data)
1186 swrm_wcd_notify(
1187 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
1188 SWR_SET_NUM_RX_CH, &ch_cnt);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301189 break;
1190 }
1191 dev_dbg(wsa_priv->dev, "%s: current swr ch cnt: %d\n",
1192 __func__, wsa_priv->rx_0_count + wsa_priv->rx_1_count);
1193
1194 return 0;
1195}
1196
Meng Wang15c825d2018-09-06 10:49:18 +08001197static int wsa_macro_config_compander(struct snd_soc_component *component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301198 int comp, int event)
1199{
1200 u16 comp_ctl0_reg, rx_path_cfg0_reg;
1201 struct device *wsa_dev = NULL;
1202 struct wsa_macro_priv *wsa_priv = NULL;
1203
Meng Wang15c825d2018-09-06 10:49:18 +08001204 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301205 return -EINVAL;
1206
Meng Wang15c825d2018-09-06 10:49:18 +08001207 dev_dbg(component->dev, "%s: event %d compander %d, enabled %d\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301208 __func__, event, comp + 1, wsa_priv->comp_enabled[comp]);
1209
1210 if (!wsa_priv->comp_enabled[comp])
1211 return 0;
1212
1213 comp_ctl0_reg = BOLERO_CDC_WSA_COMPANDER0_CTL0 +
1214 (comp * WSA_MACRO_RX_COMP_OFFSET);
1215 rx_path_cfg0_reg = BOLERO_CDC_WSA_RX0_RX_PATH_CFG0 +
1216 (comp * WSA_MACRO_RX_PATH_OFFSET);
1217
1218 if (SND_SOC_DAPM_EVENT_ON(event)) {
1219 /* Enable Compander Clock */
Meng Wang15c825d2018-09-06 10:49:18 +08001220 snd_soc_component_update_bits(component, comp_ctl0_reg,
1221 0x01, 0x01);
1222 snd_soc_component_update_bits(component, comp_ctl0_reg,
1223 0x02, 0x02);
1224 snd_soc_component_update_bits(component, comp_ctl0_reg,
1225 0x02, 0x00);
1226 snd_soc_component_update_bits(component, rx_path_cfg0_reg,
1227 0x02, 0x02);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301228 }
1229
1230 if (SND_SOC_DAPM_EVENT_OFF(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001231 snd_soc_component_update_bits(component, comp_ctl0_reg,
1232 0x04, 0x04);
1233 snd_soc_component_update_bits(component, rx_path_cfg0_reg,
1234 0x02, 0x00);
1235 snd_soc_component_update_bits(component, comp_ctl0_reg,
1236 0x02, 0x02);
1237 snd_soc_component_update_bits(component, comp_ctl0_reg,
1238 0x02, 0x00);
1239 snd_soc_component_update_bits(component, comp_ctl0_reg,
1240 0x01, 0x00);
1241 snd_soc_component_update_bits(component, comp_ctl0_reg,
1242 0x04, 0x00);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301243 }
1244
1245 return 0;
1246}
1247
Meng Wang15c825d2018-09-06 10:49:18 +08001248static void wsa_macro_enable_softclip_clk(struct snd_soc_component *component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301249 struct wsa_macro_priv *wsa_priv,
1250 int path,
1251 bool enable)
1252{
1253 u16 softclip_clk_reg = BOLERO_CDC_WSA_SOFTCLIP0_CRC +
1254 (path * WSA_MACRO_RX_SOFTCLIP_OFFSET);
1255 u8 softclip_mux_mask = (1 << path);
1256 u8 softclip_mux_value = (1 << path);
1257
Meng Wang15c825d2018-09-06 10:49:18 +08001258 dev_dbg(component->dev, "%s: path %d, enable %d\n",
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301259 __func__, path, enable);
1260 if (enable) {
1261 if (wsa_priv->softclip_clk_users[path] == 0) {
Meng Wang15c825d2018-09-06 10:49:18 +08001262 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301263 softclip_clk_reg, 0x01, 0x01);
Meng Wang15c825d2018-09-06 10:49:18 +08001264 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301265 BOLERO_CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0,
1266 softclip_mux_mask, softclip_mux_value);
1267 }
1268 wsa_priv->softclip_clk_users[path]++;
1269 } else {
1270 wsa_priv->softclip_clk_users[path]--;
1271 if (wsa_priv->softclip_clk_users[path] == 0) {
Meng Wang15c825d2018-09-06 10:49:18 +08001272 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301273 softclip_clk_reg, 0x01, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001274 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301275 BOLERO_CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0,
1276 softclip_mux_mask, 0x00);
1277 }
1278 }
1279}
1280
Meng Wang15c825d2018-09-06 10:49:18 +08001281static int wsa_macro_config_softclip(struct snd_soc_component *component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301282 int path, int event)
1283{
1284 u16 softclip_ctrl_reg = 0;
1285 struct device *wsa_dev = NULL;
1286 struct wsa_macro_priv *wsa_priv = NULL;
1287 int softclip_path = 0;
1288
Meng Wang15c825d2018-09-06 10:49:18 +08001289 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301290 return -EINVAL;
1291
1292 if (path == WSA_MACRO_COMP1)
1293 softclip_path = WSA_MACRO_SOFTCLIP0;
1294 else if (path == WSA_MACRO_COMP2)
1295 softclip_path = WSA_MACRO_SOFTCLIP1;
1296
Meng Wang15c825d2018-09-06 10:49:18 +08001297 dev_dbg(component->dev, "%s: event %d path %d, enabled %d\n",
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301298 __func__, event, softclip_path,
1299 wsa_priv->is_softclip_on[softclip_path]);
1300
1301 if (!wsa_priv->is_softclip_on[softclip_path])
1302 return 0;
1303
1304 softclip_ctrl_reg = BOLERO_CDC_WSA_SOFTCLIP0_SOFTCLIP_CTRL +
1305 (softclip_path * WSA_MACRO_RX_SOFTCLIP_OFFSET);
1306
1307 if (SND_SOC_DAPM_EVENT_ON(event)) {
1308 /* Enable Softclip clock and mux */
Meng Wang15c825d2018-09-06 10:49:18 +08001309 wsa_macro_enable_softclip_clk(component, wsa_priv,
1310 softclip_path, true);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301311 /* Enable Softclip control */
Meng Wang15c825d2018-09-06 10:49:18 +08001312 snd_soc_component_update_bits(component, softclip_ctrl_reg,
1313 0x01, 0x01);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301314 }
1315
1316 if (SND_SOC_DAPM_EVENT_OFF(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001317 snd_soc_component_update_bits(component, softclip_ctrl_reg,
1318 0x01, 0x00);
1319 wsa_macro_enable_softclip_clk(component, wsa_priv,
1320 softclip_path, false);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301321 }
1322
1323 return 0;
1324}
1325
Laxminath Kasam243e2752018-04-12 00:40:19 +05301326static int wsa_macro_interp_get_primary_reg(u16 reg, u16 *ind)
1327{
1328 u16 prim_int_reg = 0;
1329
1330 switch (reg) {
1331 case BOLERO_CDC_WSA_RX0_RX_PATH_CTL:
1332 case BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL:
1333 prim_int_reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL;
1334 *ind = 0;
1335 break;
1336 case BOLERO_CDC_WSA_RX1_RX_PATH_CTL:
1337 case BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL:
1338 prim_int_reg = BOLERO_CDC_WSA_RX1_RX_PATH_CTL;
1339 *ind = 1;
1340 break;
1341 }
1342
1343 return prim_int_reg;
1344}
1345
1346static int wsa_macro_enable_prim_interpolator(
Meng Wang15c825d2018-09-06 10:49:18 +08001347 struct snd_soc_component *component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301348 u16 reg, int event)
1349{
1350 u16 prim_int_reg;
1351 u16 ind = 0;
1352 struct device *wsa_dev = NULL;
1353 struct wsa_macro_priv *wsa_priv = NULL;
1354
Meng Wang15c825d2018-09-06 10:49:18 +08001355 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301356 return -EINVAL;
1357
1358 prim_int_reg = wsa_macro_interp_get_primary_reg(reg, &ind);
1359
1360 switch (event) {
1361 case SND_SOC_DAPM_PRE_PMU:
1362 wsa_priv->prim_int_users[ind]++;
1363 if (wsa_priv->prim_int_users[ind] == 1) {
Meng Wang15c825d2018-09-06 10:49:18 +08001364 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301365 prim_int_reg + WSA_MACRO_RX_PATH_CFG3_OFFSET,
1366 0x03, 0x03);
Meng Wang15c825d2018-09-06 10:49:18 +08001367 snd_soc_component_update_bits(component, prim_int_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301368 0x10, 0x10);
Meng Wang15c825d2018-09-06 10:49:18 +08001369 wsa_macro_hd2_control(component, prim_int_reg, event);
1370 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301371 prim_int_reg + WSA_MACRO_RX_PATH_DSMDEM_OFFSET,
1372 0x1, 0x1);
Meng Wang15c825d2018-09-06 10:49:18 +08001373 snd_soc_component_update_bits(component, prim_int_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301374 1 << 0x5, 1 << 0x5);
1375 }
1376 if ((reg != prim_int_reg) &&
Meng Wang15c825d2018-09-06 10:49:18 +08001377 ((snd_soc_component_read32(
1378 component, prim_int_reg)) & 0x10))
1379 snd_soc_component_update_bits(component, reg,
1380 0x10, 0x10);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301381 break;
1382 case SND_SOC_DAPM_POST_PMD:
1383 wsa_priv->prim_int_users[ind]--;
1384 if (wsa_priv->prim_int_users[ind] == 0) {
Meng Wang15c825d2018-09-06 10:49:18 +08001385 snd_soc_component_update_bits(component, prim_int_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301386 1 << 0x5, 0 << 0x5);
Meng Wang15c825d2018-09-06 10:49:18 +08001387 snd_soc_component_update_bits(component, prim_int_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301388 0x40, 0x40);
Meng Wang15c825d2018-09-06 10:49:18 +08001389 snd_soc_component_update_bits(component, prim_int_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301390 0x40, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001391 wsa_macro_hd2_control(component, prim_int_reg, event);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301392 }
1393 break;
1394 }
1395
Meng Wang15c825d2018-09-06 10:49:18 +08001396 dev_dbg(component->dev, "%s: primary interpolator: INT%d, users: %d\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301397 __func__, ind, wsa_priv->prim_int_users[ind]);
1398 return 0;
1399}
1400
1401static int wsa_macro_enable_interpolator(struct snd_soc_dapm_widget *w,
1402 struct snd_kcontrol *kcontrol,
1403 int event)
1404{
Meng Wang15c825d2018-09-06 10:49:18 +08001405 struct snd_soc_component *component =
1406 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301407 u16 gain_reg;
1408 u16 reg;
1409 int val;
1410 int offset_val = 0;
1411 struct device *wsa_dev = NULL;
1412 struct wsa_macro_priv *wsa_priv = NULL;
1413
Meng Wang15c825d2018-09-06 10:49:18 +08001414 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301415 return -EINVAL;
1416
Meng Wang15c825d2018-09-06 10:49:18 +08001417 dev_dbg(component->dev, "%s %d %s\n", __func__, event, w->name);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301418
1419 if (!(strcmp(w->name, "WSA_RX INT0 INTERP"))) {
1420 reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL;
1421 gain_reg = BOLERO_CDC_WSA_RX0_RX_VOL_CTL;
1422 } else if (!(strcmp(w->name, "WSA_RX INT1 INTERP"))) {
1423 reg = BOLERO_CDC_WSA_RX1_RX_PATH_CTL;
1424 gain_reg = BOLERO_CDC_WSA_RX1_RX_VOL_CTL;
1425 } else {
Meng Wang15c825d2018-09-06 10:49:18 +08001426 dev_err(component->dev, "%s: Interpolator reg not found\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301427 __func__);
1428 return -EINVAL;
1429 }
1430
1431 switch (event) {
1432 case SND_SOC_DAPM_PRE_PMU:
1433 /* Reset if needed */
Meng Wang15c825d2018-09-06 10:49:18 +08001434 wsa_macro_enable_prim_interpolator(component, reg, event);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301435 break;
1436 case SND_SOC_DAPM_POST_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08001437 wsa_macro_config_compander(component, w->shift, event);
1438 wsa_macro_config_softclip(component, w->shift, event);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301439 /* apply gain after int clk is enabled */
Laxminath Kasam21c8b222018-06-21 18:47:22 +05301440 if ((wsa_priv->spkr_gain_offset ==
1441 WSA_MACRO_GAIN_OFFSET_M1P5_DB) &&
Laxminath Kasam243e2752018-04-12 00:40:19 +05301442 (wsa_priv->comp_enabled[WSA_MACRO_COMP1] ||
1443 wsa_priv->comp_enabled[WSA_MACRO_COMP2]) &&
1444 (gain_reg == BOLERO_CDC_WSA_RX0_RX_VOL_CTL ||
1445 gain_reg == BOLERO_CDC_WSA_RX1_RX_VOL_CTL)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001446 snd_soc_component_update_bits(component,
1447 BOLERO_CDC_WSA_RX0_RX_PATH_SEC1,
1448 0x01, 0x01);
1449 snd_soc_component_update_bits(component,
1450 BOLERO_CDC_WSA_RX0_RX_PATH_MIX_SEC0,
1451 0x01, 0x01);
1452 snd_soc_component_update_bits(component,
1453 BOLERO_CDC_WSA_RX1_RX_PATH_SEC1,
1454 0x01, 0x01);
1455 snd_soc_component_update_bits(component,
1456 BOLERO_CDC_WSA_RX1_RX_PATH_MIX_SEC0,
1457 0x01, 0x01);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301458 offset_val = -2;
1459 }
Meng Wang15c825d2018-09-06 10:49:18 +08001460 val = snd_soc_component_read32(component, gain_reg);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301461 val += offset_val;
Meng Wang15c825d2018-09-06 10:49:18 +08001462 snd_soc_component_write(component, gain_reg, val);
1463 wsa_macro_config_ear_spkr_gain(component, wsa_priv,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301464 event, gain_reg);
1465 break;
1466 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +08001467 wsa_macro_config_compander(component, w->shift, event);
1468 wsa_macro_config_softclip(component, w->shift, event);
1469 wsa_macro_enable_prim_interpolator(component, reg, event);
Laxminath Kasam21c8b222018-06-21 18:47:22 +05301470 if ((wsa_priv->spkr_gain_offset ==
1471 WSA_MACRO_GAIN_OFFSET_M1P5_DB) &&
Laxminath Kasam243e2752018-04-12 00:40:19 +05301472 (wsa_priv->comp_enabled[WSA_MACRO_COMP1] ||
1473 wsa_priv->comp_enabled[WSA_MACRO_COMP2]) &&
1474 (gain_reg == BOLERO_CDC_WSA_RX0_RX_VOL_CTL ||
1475 gain_reg == BOLERO_CDC_WSA_RX1_RX_VOL_CTL)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001476 snd_soc_component_update_bits(component,
1477 BOLERO_CDC_WSA_RX0_RX_PATH_SEC1,
1478 0x01, 0x00);
1479 snd_soc_component_update_bits(component,
1480 BOLERO_CDC_WSA_RX0_RX_PATH_MIX_SEC0,
1481 0x01, 0x00);
1482 snd_soc_component_update_bits(component,
1483 BOLERO_CDC_WSA_RX1_RX_PATH_SEC1,
1484 0x01, 0x00);
1485 snd_soc_component_update_bits(component,
1486 BOLERO_CDC_WSA_RX1_RX_PATH_MIX_SEC0,
1487 0x01, 0x00);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301488 offset_val = 2;
Meng Wang15c825d2018-09-06 10:49:18 +08001489 val = snd_soc_component_read32(component, gain_reg);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301490 val += offset_val;
Meng Wang15c825d2018-09-06 10:49:18 +08001491 snd_soc_component_write(component, gain_reg, val);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301492 }
Meng Wang15c825d2018-09-06 10:49:18 +08001493 wsa_macro_config_ear_spkr_gain(component, wsa_priv,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301494 event, gain_reg);
1495 break;
1496 }
1497
1498 return 0;
1499}
1500
Meng Wang15c825d2018-09-06 10:49:18 +08001501static int wsa_macro_config_ear_spkr_gain(struct snd_soc_component *component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301502 struct wsa_macro_priv *wsa_priv,
1503 int event, int gain_reg)
1504{
1505 int comp_gain_offset, val;
1506
1507 switch (wsa_priv->spkr_mode) {
Laxminath Kasam21c8b222018-06-21 18:47:22 +05301508 /* Compander gain in WSA_MACRO_SPKR_MODE1 case is 12 dB */
1509 case WSA_MACRO_SPKR_MODE_1:
Laxminath Kasam243e2752018-04-12 00:40:19 +05301510 comp_gain_offset = -12;
1511 break;
1512 /* Default case compander gain is 15 dB */
1513 default:
1514 comp_gain_offset = -15;
1515 break;
1516 }
1517
1518 switch (event) {
1519 case SND_SOC_DAPM_POST_PMU:
1520 /* Apply ear spkr gain only if compander is enabled */
1521 if (wsa_priv->comp_enabled[WSA_MACRO_COMP1] &&
1522 (gain_reg == BOLERO_CDC_WSA_RX0_RX_VOL_CTL) &&
1523 (wsa_priv->ear_spkr_gain != 0)) {
1524 /* For example, val is -8(-12+5-1) for 4dB of gain */
1525 val = comp_gain_offset + wsa_priv->ear_spkr_gain - 1;
Meng Wang15c825d2018-09-06 10:49:18 +08001526 snd_soc_component_write(component, gain_reg, val);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301527
1528 dev_dbg(wsa_priv->dev, "%s: RX0 Volume %d dB\n",
1529 __func__, val);
1530 }
1531 break;
1532 case SND_SOC_DAPM_POST_PMD:
1533 /*
1534 * Reset RX0 volume to 0 dB if compander is enabled and
1535 * ear_spkr_gain is non-zero.
1536 */
1537 if (wsa_priv->comp_enabled[WSA_MACRO_COMP1] &&
1538 (gain_reg == BOLERO_CDC_WSA_RX0_RX_VOL_CTL) &&
1539 (wsa_priv->ear_spkr_gain != 0)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001540 snd_soc_component_write(component, gain_reg, 0x0);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301541
1542 dev_dbg(wsa_priv->dev, "%s: Reset RX0 Volume to 0 dB\n",
1543 __func__);
1544 }
1545 break;
1546 }
1547
1548 return 0;
1549}
1550
1551static int wsa_macro_spk_boost_event(struct snd_soc_dapm_widget *w,
1552 struct snd_kcontrol *kcontrol,
1553 int event)
1554{
Meng Wang15c825d2018-09-06 10:49:18 +08001555 struct snd_soc_component *component =
1556 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301557 u16 boost_path_ctl, boost_path_cfg1;
1558 u16 reg, reg_mix;
1559
Meng Wang15c825d2018-09-06 10:49:18 +08001560 dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301561
1562 if (!strcmp(w->name, "WSA_RX INT0 CHAIN")) {
1563 boost_path_ctl = BOLERO_CDC_WSA_BOOST0_BOOST_PATH_CTL;
1564 boost_path_cfg1 = BOLERO_CDC_WSA_RX0_RX_PATH_CFG1;
1565 reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL;
1566 reg_mix = BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL;
1567 } else if (!strcmp(w->name, "WSA_RX INT1 CHAIN")) {
1568 boost_path_ctl = BOLERO_CDC_WSA_BOOST1_BOOST_PATH_CTL;
1569 boost_path_cfg1 = BOLERO_CDC_WSA_RX1_RX_PATH_CFG1;
1570 reg = BOLERO_CDC_WSA_RX1_RX_PATH_CTL;
1571 reg_mix = BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL;
1572 } else {
Meng Wang15c825d2018-09-06 10:49:18 +08001573 dev_err(component->dev, "%s: unknown widget: %s\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301574 __func__, w->name);
1575 return -EINVAL;
1576 }
1577
1578 switch (event) {
1579 case SND_SOC_DAPM_PRE_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08001580 snd_soc_component_update_bits(component, boost_path_cfg1,
1581 0x01, 0x01);
1582 snd_soc_component_update_bits(component, boost_path_ctl,
1583 0x10, 0x10);
1584 if ((snd_soc_component_read32(component, reg_mix)) & 0x10)
1585 snd_soc_component_update_bits(component, reg_mix,
1586 0x10, 0x00);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301587 break;
Laxminath Kasam0c857002018-07-17 23:47:17 +05301588 case SND_SOC_DAPM_POST_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08001589 snd_soc_component_update_bits(component, reg, 0x10, 0x00);
Laxminath Kasam0c857002018-07-17 23:47:17 +05301590 break;
Laxminath Kasam243e2752018-04-12 00:40:19 +05301591 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +08001592 snd_soc_component_update_bits(component, boost_path_ctl,
1593 0x10, 0x00);
1594 snd_soc_component_update_bits(component, boost_path_cfg1,
1595 0x01, 0x00);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301596 break;
1597 }
1598
1599 return 0;
1600}
1601
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301602
1603static int wsa_macro_enable_vbat(struct snd_soc_dapm_widget *w,
1604 struct snd_kcontrol *kcontrol,
1605 int event)
1606{
Meng Wang15c825d2018-09-06 10:49:18 +08001607 struct snd_soc_component *component =
1608 snd_soc_dapm_to_component(w->dapm);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301609 struct device *wsa_dev = NULL;
1610 struct wsa_macro_priv *wsa_priv = NULL;
1611 u16 vbat_path_cfg = 0;
1612 int softclip_path = 0;
1613
Meng Wang15c825d2018-09-06 10:49:18 +08001614 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301615 return -EINVAL;
1616
Meng Wang15c825d2018-09-06 10:49:18 +08001617 dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301618 if (!strcmp(w->name, "WSA_RX INT0 VBAT")) {
1619 vbat_path_cfg = BOLERO_CDC_WSA_RX0_RX_PATH_CFG1;
1620 softclip_path = WSA_MACRO_SOFTCLIP0;
1621 } else if (!strcmp(w->name, "WSA_RX INT1 VBAT")) {
1622 vbat_path_cfg = BOLERO_CDC_WSA_RX1_RX_PATH_CFG1;
1623 softclip_path = WSA_MACRO_SOFTCLIP1;
1624 }
1625
1626 switch (event) {
1627 case SND_SOC_DAPM_PRE_PMU:
1628 /* Enable clock for VBAT block */
Meng Wang15c825d2018-09-06 10:49:18 +08001629 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301630 BOLERO_CDC_WSA_VBAT_BCL_VBAT_PATH_CTL, 0x10, 0x10);
1631 /* Enable VBAT block */
Meng Wang15c825d2018-09-06 10:49:18 +08001632 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301633 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG, 0x01, 0x01);
1634 /* Update interpolator with 384K path */
Meng Wang15c825d2018-09-06 10:49:18 +08001635 snd_soc_component_update_bits(component, vbat_path_cfg,
1636 0x80, 0x80);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301637 /* Use attenuation mode */
Meng Wang15c825d2018-09-06 10:49:18 +08001638 snd_soc_component_update_bits(component,
1639 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG, 0x02, 0x00);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301640 /*
1641 * BCL block needs softclip clock and mux config to be enabled
1642 */
Meng Wang15c825d2018-09-06 10:49:18 +08001643 wsa_macro_enable_softclip_clk(component, wsa_priv,
1644 softclip_path, true);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301645 /* Enable VBAT at channel level */
Meng Wang15c825d2018-09-06 10:49:18 +08001646 snd_soc_component_update_bits(component, vbat_path_cfg,
1647 0x02, 0x02);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301648 /* Set the ATTK1 gain */
Meng Wang15c825d2018-09-06 10:49:18 +08001649 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301650 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD1,
1651 0xFF, 0xFF);
Meng Wang15c825d2018-09-06 10:49:18 +08001652 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301653 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD2,
1654 0xFF, 0x03);
Meng Wang15c825d2018-09-06 10:49:18 +08001655 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301656 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD3,
1657 0xFF, 0x00);
1658 /* Set the ATTK2 gain */
Meng Wang15c825d2018-09-06 10:49:18 +08001659 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301660 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD4,
1661 0xFF, 0xFF);
Meng Wang15c825d2018-09-06 10:49:18 +08001662 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301663 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD5,
1664 0xFF, 0x03);
Meng Wang15c825d2018-09-06 10:49:18 +08001665 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301666 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD6,
1667 0xFF, 0x00);
1668 /* Set the ATTK3 gain */
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_UPD7,
1671 0xFF, 0xFF);
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_UPD8,
1674 0xFF, 0x03);
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_UPD9,
1677 0xFF, 0x00);
1678 break;
1679
1680 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +08001681 snd_soc_component_update_bits(component, vbat_path_cfg,
1682 0x80, 0x00);
1683 snd_soc_component_update_bits(component,
1684 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG,
1685 0x02, 0x02);
1686 snd_soc_component_update_bits(component, vbat_path_cfg,
1687 0x02, 0x00);
1688 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301689 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD1,
1690 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001691 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301692 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD2,
1693 0xFF, 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_BCL_GAIN_UPD3,
1696 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001697 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301698 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD4,
1699 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001700 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301701 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD5,
1702 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001703 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301704 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD6,
1705 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001706 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301707 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD7,
1708 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001709 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301710 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD8,
1711 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001712 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301713 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD9,
1714 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001715 wsa_macro_enable_softclip_clk(component, wsa_priv,
1716 softclip_path, false);
1717 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301718 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG, 0x01, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001719 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301720 BOLERO_CDC_WSA_VBAT_BCL_VBAT_PATH_CTL, 0x10, 0x00);
1721 break;
1722 default:
1723 dev_err(wsa_dev, "%s: Invalid event %d\n", __func__, event);
1724 break;
1725 }
1726 return 0;
1727}
1728
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301729static int wsa_macro_enable_echo(struct snd_soc_dapm_widget *w,
1730 struct snd_kcontrol *kcontrol,
1731 int event)
1732{
Meng Wang15c825d2018-09-06 10:49:18 +08001733 struct snd_soc_component *component =
1734 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301735 struct device *wsa_dev = NULL;
1736 struct wsa_macro_priv *wsa_priv = NULL;
1737 u16 val, ec_tx = 0, ec_hq_reg;
1738
Meng Wang15c825d2018-09-06 10:49:18 +08001739 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301740 return -EINVAL;
1741
1742 dev_dbg(wsa_dev, "%s %d %s\n", __func__, event, w->name);
1743
Meng Wang15c825d2018-09-06 10:49:18 +08001744 val = snd_soc_component_read32(component,
1745 BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301746 if (!(strcmp(w->name, "WSA RX_MIX EC0_MUX")))
1747 ec_tx = (val & 0x07) - 1;
1748 else
1749 ec_tx = ((val & 0x38) >> 0x3) - 1;
1750
1751 if (ec_tx < 0 || ec_tx >= (WSA_MACRO_RX1 + 1)) {
1752 dev_err(wsa_dev, "%s: EC mix control not set correctly\n",
1753 __func__);
1754 return -EINVAL;
1755 }
1756 if (wsa_priv->ec_hq[ec_tx]) {
Meng Wang15c825d2018-09-06 10:49:18 +08001757 snd_soc_component_update_bits(component,
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301758 BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0,
1759 0x1 << ec_tx, 0x1 << ec_tx);
1760 ec_hq_reg = BOLERO_CDC_WSA_EC_HQ0_EC_REF_HQ_PATH_CTL +
Laxminath Kasam5d9ea8d2018-11-28 14:32:40 +05301761 0x40 * ec_tx;
Meng Wang15c825d2018-09-06 10:49:18 +08001762 snd_soc_component_update_bits(component, ec_hq_reg, 0x01, 0x01);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301763 ec_hq_reg = BOLERO_CDC_WSA_EC_HQ0_EC_REF_HQ_CFG0 +
Laxminath Kasam5d9ea8d2018-11-28 14:32:40 +05301764 0x40 * ec_tx;
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301765 /* default set to 48k */
Meng Wang15c825d2018-09-06 10:49:18 +08001766 snd_soc_component_update_bits(component, ec_hq_reg, 0x1E, 0x08);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301767 }
1768
1769 return 0;
1770}
1771
1772static int wsa_macro_get_ec_hq(struct snd_kcontrol *kcontrol,
1773 struct snd_ctl_elem_value *ucontrol)
1774{
1775
Meng Wang15c825d2018-09-06 10:49:18 +08001776 struct snd_soc_component *component =
1777 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301778 int ec_tx = ((struct soc_multi_mixer_control *)
1779 kcontrol->private_value)->shift;
1780 struct device *wsa_dev = NULL;
1781 struct wsa_macro_priv *wsa_priv = NULL;
1782
Meng Wang15c825d2018-09-06 10:49:18 +08001783 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301784 return -EINVAL;
1785
1786 ucontrol->value.integer.value[0] = wsa_priv->ec_hq[ec_tx];
1787 return 0;
1788}
1789
1790static int wsa_macro_set_ec_hq(struct snd_kcontrol *kcontrol,
1791 struct snd_ctl_elem_value *ucontrol)
1792{
Meng Wang15c825d2018-09-06 10:49:18 +08001793 struct snd_soc_component *component =
1794 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301795 int ec_tx = ((struct soc_multi_mixer_control *)
1796 kcontrol->private_value)->shift;
1797 int value = ucontrol->value.integer.value[0];
1798 struct device *wsa_dev = NULL;
1799 struct wsa_macro_priv *wsa_priv = NULL;
1800
Meng Wang15c825d2018-09-06 10:49:18 +08001801 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301802 return -EINVAL;
1803
1804 dev_dbg(wsa_dev, "%s: enable current %d, new %d\n",
1805 __func__, wsa_priv->ec_hq[ec_tx], value);
1806 wsa_priv->ec_hq[ec_tx] = value;
1807
1808 return 0;
1809}
1810
Vatsal Buchaf2a71b62019-03-26 16:14:40 +05301811static int wsa_macro_get_rx_mute_status(struct snd_kcontrol *kcontrol,
1812 struct snd_ctl_elem_value *ucontrol)
1813{
1814
1815 struct snd_soc_component *component =
1816 snd_soc_kcontrol_component(kcontrol);
1817 struct device *wsa_dev = NULL;
1818 struct wsa_macro_priv *wsa_priv = NULL;
1819 int wsa_rx_shift = ((struct soc_multi_mixer_control *)
1820 kcontrol->private_value)->shift;
1821
1822 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
1823 return -EINVAL;
1824
1825 ucontrol->value.integer.value[0] =
1826 wsa_priv->wsa_digital_mute_status[wsa_rx_shift];
1827 return 0;
1828}
1829
1830static int wsa_macro_set_rx_mute_status(struct snd_kcontrol *kcontrol,
1831 struct snd_ctl_elem_value *ucontrol)
1832{
1833 struct snd_soc_component *component =
1834 snd_soc_kcontrol_component(kcontrol);
1835 struct device *wsa_dev = NULL;
1836 struct wsa_macro_priv *wsa_priv = NULL;
1837 int value = ucontrol->value.integer.value[0];
1838 int wsa_rx_shift = ((struct soc_multi_mixer_control *)
1839 kcontrol->private_value)->shift;
1840
1841 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
1842 return -EINVAL;
1843
1844 switch (wsa_rx_shift) {
1845 case 0:
1846 snd_soc_component_update_bits(component,
1847 BOLERO_CDC_WSA_RX0_RX_PATH_CTL,
1848 0x10, value << 4);
1849 break;
1850 case 1:
1851 snd_soc_component_update_bits(component,
1852 BOLERO_CDC_WSA_RX1_RX_PATH_CTL,
1853 0x10, value << 4);
1854 break;
1855 case 2:
1856 snd_soc_component_update_bits(component,
1857 BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL,
1858 0x10, value << 4);
1859 break;
1860 case 3:
1861 snd_soc_component_update_bits(component,
1862 BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL,
1863 0x10, value << 4);
1864 break;
1865 default:
1866 pr_err("%s: invalid argument rx_shift = %d\n", __func__,
1867 wsa_rx_shift);
1868 return -EINVAL;
1869 }
1870
1871 dev_dbg(component->dev, "%s: WSA Digital Mute RX %d Enable %d\n",
1872 __func__, wsa_rx_shift, value);
1873 wsa_priv->wsa_digital_mute_status[wsa_rx_shift] = value;
1874 return 0;
1875}
1876
Laxminath Kasam243e2752018-04-12 00:40:19 +05301877static int wsa_macro_get_compander(struct snd_kcontrol *kcontrol,
1878 struct snd_ctl_elem_value *ucontrol)
1879{
1880
Meng Wang15c825d2018-09-06 10:49:18 +08001881 struct snd_soc_component *component =
1882 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301883 int comp = ((struct soc_multi_mixer_control *)
1884 kcontrol->private_value)->shift;
1885 struct device *wsa_dev = NULL;
1886 struct wsa_macro_priv *wsa_priv = NULL;
1887
Meng Wang15c825d2018-09-06 10:49:18 +08001888 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301889 return -EINVAL;
1890
1891 ucontrol->value.integer.value[0] = wsa_priv->comp_enabled[comp];
1892 return 0;
1893}
1894
1895static int wsa_macro_set_compander(struct snd_kcontrol *kcontrol,
1896 struct snd_ctl_elem_value *ucontrol)
1897{
Meng Wang15c825d2018-09-06 10:49:18 +08001898 struct snd_soc_component *component =
1899 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301900 int comp = ((struct soc_multi_mixer_control *)
1901 kcontrol->private_value)->shift;
1902 int value = ucontrol->value.integer.value[0];
1903 struct device *wsa_dev = NULL;
1904 struct wsa_macro_priv *wsa_priv = NULL;
1905
Meng Wang15c825d2018-09-06 10:49:18 +08001906 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301907 return -EINVAL;
1908
Meng Wang15c825d2018-09-06 10:49:18 +08001909 dev_dbg(component->dev, "%s: Compander %d enable current %d, new %d\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301910 __func__, comp + 1, wsa_priv->comp_enabled[comp], value);
1911 wsa_priv->comp_enabled[comp] = value;
1912
1913 return 0;
1914}
1915
1916static int wsa_macro_ear_spkr_pa_gain_get(struct snd_kcontrol *kcontrol,
1917 struct snd_ctl_elem_value *ucontrol)
1918{
Meng Wang15c825d2018-09-06 10:49:18 +08001919 struct snd_soc_component *component =
1920 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301921 struct device *wsa_dev = NULL;
1922 struct wsa_macro_priv *wsa_priv = NULL;
1923
Meng Wang15c825d2018-09-06 10:49:18 +08001924 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301925 return -EINVAL;
1926
1927 ucontrol->value.integer.value[0] = wsa_priv->ear_spkr_gain;
1928
Meng Wang15c825d2018-09-06 10:49:18 +08001929 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301930 __func__, ucontrol->value.integer.value[0]);
1931
1932 return 0;
1933}
1934
1935static int wsa_macro_ear_spkr_pa_gain_put(struct snd_kcontrol *kcontrol,
1936 struct snd_ctl_elem_value *ucontrol)
1937{
Meng Wang15c825d2018-09-06 10:49:18 +08001938 struct snd_soc_component *component =
1939 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301940 struct device *wsa_dev = NULL;
1941 struct wsa_macro_priv *wsa_priv = NULL;
1942
Meng Wang15c825d2018-09-06 10:49:18 +08001943 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301944 return -EINVAL;
1945
1946 wsa_priv->ear_spkr_gain = ucontrol->value.integer.value[0];
1947
Meng Wang15c825d2018-09-06 10:49:18 +08001948 dev_dbg(component->dev, "%s: gain = %d\n", __func__,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301949 wsa_priv->ear_spkr_gain);
1950
1951 return 0;
1952}
1953
1954static int wsa_macro_spkr_left_boost_stage_get(struct snd_kcontrol *kcontrol,
1955 struct snd_ctl_elem_value *ucontrol)
1956{
1957 u8 bst_state_max = 0;
Meng Wang15c825d2018-09-06 10:49:18 +08001958 struct snd_soc_component *component =
1959 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301960
Meng Wang15c825d2018-09-06 10:49:18 +08001961 bst_state_max = snd_soc_component_read32(component,
1962 BOLERO_CDC_WSA_BOOST0_BOOST_CTL);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301963 bst_state_max = (bst_state_max & 0x0c) >> 2;
1964 ucontrol->value.integer.value[0] = bst_state_max;
Meng Wang15c825d2018-09-06 10:49:18 +08001965 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301966 __func__, ucontrol->value.integer.value[0]);
1967
1968 return 0;
1969}
1970
1971static int wsa_macro_spkr_left_boost_stage_put(struct snd_kcontrol *kcontrol,
1972 struct snd_ctl_elem_value *ucontrol)
1973{
1974 u8 bst_state_max;
Meng Wang15c825d2018-09-06 10:49:18 +08001975 struct snd_soc_component *component =
1976 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301977
Meng Wang15c825d2018-09-06 10:49:18 +08001978 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301979 __func__, ucontrol->value.integer.value[0]);
1980 bst_state_max = ucontrol->value.integer.value[0] << 2;
Karthikeyan Mani10de3932019-04-15 11:46:57 -07001981 /* bolero does not need to limit the boost levels */
Laxminath Kasam243e2752018-04-12 00:40:19 +05301982
1983 return 0;
1984}
1985
1986static int wsa_macro_spkr_right_boost_stage_get(struct snd_kcontrol *kcontrol,
1987 struct snd_ctl_elem_value *ucontrol)
1988{
1989 u8 bst_state_max = 0;
Meng Wang15c825d2018-09-06 10:49:18 +08001990 struct snd_soc_component *component =
1991 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301992
Meng Wang15c825d2018-09-06 10:49:18 +08001993 bst_state_max = snd_soc_component_read32(component,
1994 BOLERO_CDC_WSA_BOOST1_BOOST_CTL);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301995 bst_state_max = (bst_state_max & 0x0c) >> 2;
1996 ucontrol->value.integer.value[0] = bst_state_max;
Meng Wang15c825d2018-09-06 10:49:18 +08001997 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301998 __func__, ucontrol->value.integer.value[0]);
1999
2000 return 0;
2001}
2002
2003static int wsa_macro_spkr_right_boost_stage_put(struct snd_kcontrol *kcontrol,
2004 struct snd_ctl_elem_value *ucontrol)
2005{
2006 u8 bst_state_max;
Meng Wang15c825d2018-09-06 10:49:18 +08002007 struct snd_soc_component *component =
2008 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302009
Meng Wang15c825d2018-09-06 10:49:18 +08002010 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05302011 __func__, ucontrol->value.integer.value[0]);
2012 bst_state_max = ucontrol->value.integer.value[0] << 2;
Karthikeyan Mani10de3932019-04-15 11:46:57 -07002013 /* bolero does not need to limit the boost levels */
Laxminath Kasam243e2752018-04-12 00:40:19 +05302014
2015 return 0;
2016}
2017
2018static int wsa_macro_rx_mux_get(struct snd_kcontrol *kcontrol,
2019 struct snd_ctl_elem_value *ucontrol)
2020{
2021 struct snd_soc_dapm_widget *widget =
2022 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +08002023 struct snd_soc_component *component =
2024 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302025 struct device *wsa_dev = NULL;
2026 struct wsa_macro_priv *wsa_priv = NULL;
2027
Meng Wang15c825d2018-09-06 10:49:18 +08002028 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302029 return -EINVAL;
2030
2031 ucontrol->value.integer.value[0] =
2032 wsa_priv->rx_port_value[widget->shift];
2033 return 0;
2034}
2035
2036static int wsa_macro_rx_mux_put(struct snd_kcontrol *kcontrol,
2037 struct snd_ctl_elem_value *ucontrol)
2038{
2039 struct snd_soc_dapm_widget *widget =
2040 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +08002041 struct snd_soc_component *component =
2042 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302043 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
2044 struct snd_soc_dapm_update *update = NULL;
2045 u32 rx_port_value = ucontrol->value.integer.value[0];
2046 u32 bit_input = 0;
2047 u32 aif_rst;
2048 struct device *wsa_dev = NULL;
2049 struct wsa_macro_priv *wsa_priv = NULL;
2050
Meng Wang15c825d2018-09-06 10:49:18 +08002051 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302052 return -EINVAL;
2053
2054 aif_rst = wsa_priv->rx_port_value[widget->shift];
2055 if (!rx_port_value) {
2056 if (aif_rst == 0) {
2057 dev_err(wsa_dev, "%s: AIF reset already\n", __func__);
2058 return 0;
2059 }
Sudheer Papothic0f75b72019-07-16 06:04:10 +05302060 if (aif_rst >= WSA_MACRO_RX_MAX) {
2061 dev_err(wsa_dev, "%s: Invalid AIF reset\n", __func__);
2062 return 0;
2063 }
Laxminath Kasam243e2752018-04-12 00:40:19 +05302064 }
2065 wsa_priv->rx_port_value[widget->shift] = rx_port_value;
2066
2067 bit_input = widget->shift;
2068 if (widget->shift >= WSA_MACRO_RX_MIX)
2069 bit_input %= WSA_MACRO_RX_MIX;
2070
Sudheer Papothic0f75b72019-07-16 06:04:10 +05302071 dev_dbg(wsa_dev,
2072 "%s: mux input: %d, mux output: %d, bit: %d\n",
2073 __func__, rx_port_value, widget->shift, bit_input);
2074
Laxminath Kasam243e2752018-04-12 00:40:19 +05302075 switch (rx_port_value) {
2076 case 0:
Sudheer Papothic0f75b72019-07-16 06:04:10 +05302077 if (wsa_priv->active_ch_cnt[aif_rst]) {
2078 clear_bit(bit_input,
2079 &wsa_priv->active_ch_mask[aif_rst]);
2080 wsa_priv->active_ch_cnt[aif_rst]--;
2081 }
Laxminath Kasam243e2752018-04-12 00:40:19 +05302082 break;
2083 case 1:
2084 case 2:
2085 set_bit(bit_input,
Laxminath Kasam59c7a1d2018-08-09 16:11:17 +05302086 &wsa_priv->active_ch_mask[rx_port_value]);
2087 wsa_priv->active_ch_cnt[rx_port_value]++;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302088 break;
2089 default:
2090 dev_err(wsa_dev,
Sudheer Papothic0f75b72019-07-16 06:04:10 +05302091 "%s: Invalid AIF_ID for WSA RX MUX %d\n",
2092 __func__, rx_port_value);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302093 return -EINVAL;
2094 }
2095
2096 snd_soc_dapm_mux_update_power(widget->dapm, kcontrol,
2097 rx_port_value, e, update);
2098 return 0;
2099}
2100
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302101static int wsa_macro_vbat_bcl_gsm_mode_func_get(struct snd_kcontrol *kcontrol,
2102 struct snd_ctl_elem_value *ucontrol)
2103{
Meng Wang15c825d2018-09-06 10:49:18 +08002104 struct snd_soc_component *component =
2105 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302106
2107 ucontrol->value.integer.value[0] =
Meng Wang15c825d2018-09-06 10:49:18 +08002108 ((snd_soc_component_read32(
2109 component, BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG) & 0x04) ?
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302110 1 : 0);
2111
Meng Wang15c825d2018-09-06 10:49:18 +08002112 dev_dbg(component->dev, "%s: value: %lu\n", __func__,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302113 ucontrol->value.integer.value[0]);
2114
2115 return 0;
2116}
2117
2118static int wsa_macro_vbat_bcl_gsm_mode_func_put(struct snd_kcontrol *kcontrol,
2119 struct snd_ctl_elem_value *ucontrol)
2120{
Meng Wang15c825d2018-09-06 10:49:18 +08002121 struct snd_soc_component *component =
2122 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302123
Meng Wang15c825d2018-09-06 10:49:18 +08002124 dev_dbg(component->dev, "%s: value: %lu\n", __func__,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302125 ucontrol->value.integer.value[0]);
2126
2127 /* Set Vbat register configuration for GSM mode bit based on value */
2128 if (ucontrol->value.integer.value[0])
Meng Wang15c825d2018-09-06 10:49:18 +08002129 snd_soc_component_update_bits(component,
2130 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG,
2131 0x04, 0x04);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302132 else
Meng Wang15c825d2018-09-06 10:49:18 +08002133 snd_soc_component_update_bits(component,
2134 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG,
2135 0x04, 0x00);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302136
2137 return 0;
2138}
2139
2140static int wsa_macro_soft_clip_enable_get(struct snd_kcontrol *kcontrol,
2141 struct snd_ctl_elem_value *ucontrol)
2142{
Meng Wang15c825d2018-09-06 10:49:18 +08002143 struct snd_soc_component *component =
2144 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302145 struct device *wsa_dev = NULL;
2146 struct wsa_macro_priv *wsa_priv = NULL;
2147 int path = ((struct soc_multi_mixer_control *)
2148 kcontrol->private_value)->shift;
2149
Meng Wang15c825d2018-09-06 10:49:18 +08002150 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302151 return -EINVAL;
2152
2153 ucontrol->value.integer.value[0] = wsa_priv->is_softclip_on[path];
2154
Meng Wang15c825d2018-09-06 10:49:18 +08002155 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302156 __func__, ucontrol->value.integer.value[0]);
2157
2158 return 0;
2159}
2160
2161static int wsa_macro_soft_clip_enable_put(struct snd_kcontrol *kcontrol,
2162 struct snd_ctl_elem_value *ucontrol)
2163{
Meng Wang15c825d2018-09-06 10:49:18 +08002164 struct snd_soc_component *component =
2165 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302166 struct device *wsa_dev = NULL;
2167 struct wsa_macro_priv *wsa_priv = NULL;
2168 int path = ((struct soc_multi_mixer_control *)
2169 kcontrol->private_value)->shift;
2170
Meng Wang15c825d2018-09-06 10:49:18 +08002171 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302172 return -EINVAL;
2173
2174 wsa_priv->is_softclip_on[path] = ucontrol->value.integer.value[0];
2175
Meng Wang15c825d2018-09-06 10:49:18 +08002176 dev_dbg(component->dev, "%s: soft clip enable for %d: %d\n", __func__,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302177 path, wsa_priv->is_softclip_on[path]);
2178
2179 return 0;
2180}
2181
Laxminath Kasam243e2752018-04-12 00:40:19 +05302182static const struct snd_kcontrol_new wsa_macro_snd_controls[] = {
2183 SOC_ENUM_EXT("EAR SPKR PA Gain", wsa_macro_ear_spkr_pa_gain_enum,
2184 wsa_macro_ear_spkr_pa_gain_get,
2185 wsa_macro_ear_spkr_pa_gain_put),
2186 SOC_ENUM_EXT("SPKR Left Boost Max State",
2187 wsa_macro_spkr_boost_stage_enum,
2188 wsa_macro_spkr_left_boost_stage_get,
2189 wsa_macro_spkr_left_boost_stage_put),
2190 SOC_ENUM_EXT("SPKR Right Boost Max State",
2191 wsa_macro_spkr_boost_stage_enum,
2192 wsa_macro_spkr_right_boost_stage_get,
2193 wsa_macro_spkr_right_boost_stage_put),
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302194 SOC_ENUM_EXT("GSM mode Enable", wsa_macro_vbat_bcl_gsm_mode_enum,
2195 wsa_macro_vbat_bcl_gsm_mode_func_get,
2196 wsa_macro_vbat_bcl_gsm_mode_func_put),
2197 SOC_SINGLE_EXT("WSA_Softclip0 Enable", SND_SOC_NOPM,
2198 WSA_MACRO_SOFTCLIP0, 1, 0,
2199 wsa_macro_soft_clip_enable_get,
2200 wsa_macro_soft_clip_enable_put),
2201 SOC_SINGLE_EXT("WSA_Softclip1 Enable", SND_SOC_NOPM,
2202 WSA_MACRO_SOFTCLIP1, 1, 0,
2203 wsa_macro_soft_clip_enable_get,
2204 wsa_macro_soft_clip_enable_put),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302205 SOC_SINGLE_SX_TLV("WSA_RX0 Digital Volume",
2206 BOLERO_CDC_WSA_RX0_RX_VOL_CTL,
2207 0, -84, 40, digital_gain),
2208 SOC_SINGLE_SX_TLV("WSA_RX1 Digital Volume",
2209 BOLERO_CDC_WSA_RX1_RX_VOL_CTL,
2210 0, -84, 40, digital_gain),
Vatsal Buchaf2a71b62019-03-26 16:14:40 +05302211 SOC_SINGLE_EXT("WSA_RX0 Digital Mute", SND_SOC_NOPM, WSA_MACRO_RX0, 1,
2212 0, wsa_macro_get_rx_mute_status,
2213 wsa_macro_set_rx_mute_status),
2214 SOC_SINGLE_EXT("WSA_RX1 Digital Mute", SND_SOC_NOPM, WSA_MACRO_RX1, 1,
2215 0, wsa_macro_get_rx_mute_status,
2216 wsa_macro_set_rx_mute_status),
2217 SOC_SINGLE_EXT("WSA_RX0_MIX Digital Mute", SND_SOC_NOPM,
2218 WSA_MACRO_RX_MIX0, 1, 0, wsa_macro_get_rx_mute_status,
2219 wsa_macro_set_rx_mute_status),
2220 SOC_SINGLE_EXT("WSA_RX1_MIX Digital Mute", SND_SOC_NOPM,
2221 WSA_MACRO_RX_MIX1, 1, 0, wsa_macro_get_rx_mute_status,
2222 wsa_macro_set_rx_mute_status),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302223 SOC_SINGLE_EXT("WSA_COMP1 Switch", SND_SOC_NOPM, WSA_MACRO_COMP1, 1, 0,
2224 wsa_macro_get_compander, wsa_macro_set_compander),
2225 SOC_SINGLE_EXT("WSA_COMP2 Switch", SND_SOC_NOPM, WSA_MACRO_COMP2, 1, 0,
2226 wsa_macro_get_compander, wsa_macro_set_compander),
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05302227 SOC_SINGLE_EXT("WSA_RX0 EC_HQ Switch", SND_SOC_NOPM, WSA_MACRO_RX0,
2228 1, 0, wsa_macro_get_ec_hq, wsa_macro_set_ec_hq),
2229 SOC_SINGLE_EXT("WSA_RX1 EC_HQ Switch", SND_SOC_NOPM, WSA_MACRO_RX1,
2230 1, 0, wsa_macro_get_ec_hq, wsa_macro_set_ec_hq),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302231};
2232
2233static const struct soc_enum rx_mux_enum =
2234 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_mux_text), rx_mux_text);
2235
2236static const struct snd_kcontrol_new rx_mux[WSA_MACRO_RX_MAX] = {
2237 SOC_DAPM_ENUM_EXT("WSA RX0 Mux", rx_mux_enum,
2238 wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),
2239 SOC_DAPM_ENUM_EXT("WSA RX1 Mux", rx_mux_enum,
2240 wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),
2241 SOC_DAPM_ENUM_EXT("WSA RX_MIX0 Mux", rx_mux_enum,
2242 wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),
2243 SOC_DAPM_ENUM_EXT("WSA RX_MIX1 Mux", rx_mux_enum,
2244 wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),
2245};
2246
2247static int wsa_macro_vi_feed_mixer_get(struct snd_kcontrol *kcontrol,
2248 struct snd_ctl_elem_value *ucontrol)
2249{
2250 struct snd_soc_dapm_widget *widget =
2251 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +08002252 struct snd_soc_component *component =
2253 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302254 struct soc_multi_mixer_control *mixer =
2255 ((struct soc_multi_mixer_control *)kcontrol->private_value);
2256 u32 dai_id = widget->shift;
2257 u32 spk_tx_id = mixer->shift;
2258 struct device *wsa_dev = NULL;
2259 struct wsa_macro_priv *wsa_priv = NULL;
2260
Meng Wang15c825d2018-09-06 10:49:18 +08002261 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302262 return -EINVAL;
2263
2264 if (test_bit(spk_tx_id, &wsa_priv->active_ch_mask[dai_id]))
2265 ucontrol->value.integer.value[0] = 1;
2266 else
2267 ucontrol->value.integer.value[0] = 0;
2268
2269 return 0;
2270}
2271
2272static int wsa_macro_vi_feed_mixer_put(struct snd_kcontrol *kcontrol,
2273 struct snd_ctl_elem_value *ucontrol)
2274{
2275 struct snd_soc_dapm_widget *widget =
2276 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +08002277 struct snd_soc_component *component =
2278 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302279 struct soc_multi_mixer_control *mixer =
2280 ((struct soc_multi_mixer_control *)kcontrol->private_value);
2281 u32 spk_tx_id = mixer->shift;
2282 u32 enable = ucontrol->value.integer.value[0];
2283 struct device *wsa_dev = NULL;
2284 struct wsa_macro_priv *wsa_priv = NULL;
2285
Meng Wang15c825d2018-09-06 10:49:18 +08002286 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302287 return -EINVAL;
2288
2289 wsa_priv->vi_feed_value = ucontrol->value.integer.value[0];
2290
2291 if (enable) {
2292 if (spk_tx_id == WSA_MACRO_TX0 &&
2293 !test_bit(WSA_MACRO_TX0,
2294 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
2295 set_bit(WSA_MACRO_TX0,
2296 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI]);
2297 wsa_priv->active_ch_cnt[WSA_MACRO_AIF_VI]++;
2298 }
2299 if (spk_tx_id == WSA_MACRO_TX1 &&
2300 !test_bit(WSA_MACRO_TX1,
2301 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
2302 set_bit(WSA_MACRO_TX1,
2303 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI]);
2304 wsa_priv->active_ch_cnt[WSA_MACRO_AIF_VI]++;
2305 }
2306 } else {
2307 if (spk_tx_id == WSA_MACRO_TX0 &&
2308 test_bit(WSA_MACRO_TX0,
2309 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
2310 clear_bit(WSA_MACRO_TX0,
2311 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI]);
2312 wsa_priv->active_ch_cnt[WSA_MACRO_AIF_VI]--;
2313 }
2314 if (spk_tx_id == WSA_MACRO_TX1 &&
2315 test_bit(WSA_MACRO_TX1,
2316 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
2317 clear_bit(WSA_MACRO_TX1,
2318 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI]);
2319 wsa_priv->active_ch_cnt[WSA_MACRO_AIF_VI]--;
2320 }
2321 }
2322 snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, NULL);
2323
2324 return 0;
2325}
2326
2327static const struct snd_kcontrol_new aif_vi_mixer[] = {
2328 SOC_SINGLE_EXT("WSA_SPKR_VI_1", SND_SOC_NOPM, WSA_MACRO_TX0, 1, 0,
2329 wsa_macro_vi_feed_mixer_get,
2330 wsa_macro_vi_feed_mixer_put),
2331 SOC_SINGLE_EXT("WSA_SPKR_VI_2", SND_SOC_NOPM, WSA_MACRO_TX1, 1, 0,
2332 wsa_macro_vi_feed_mixer_get,
2333 wsa_macro_vi_feed_mixer_put),
2334};
2335
2336static const struct snd_soc_dapm_widget wsa_macro_dapm_widgets[] = {
2337 SND_SOC_DAPM_AIF_IN("WSA AIF1 PB", "WSA_AIF1 Playback", 0,
2338 SND_SOC_NOPM, 0, 0),
2339
2340 SND_SOC_DAPM_AIF_IN("WSA AIF_MIX1 PB", "WSA_AIF_MIX1 Playback", 0,
2341 SND_SOC_NOPM, 0, 0),
2342
2343 SND_SOC_DAPM_AIF_OUT_E("WSA AIF_VI", "WSA_AIF_VI Capture", 0,
2344 SND_SOC_NOPM, WSA_MACRO_AIF_VI, 0,
2345 wsa_macro_enable_vi_feedback,
2346 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
2347
2348 SND_SOC_DAPM_AIF_OUT("WSA AIF_ECHO", "WSA_AIF_ECHO Capture", 0,
2349 SND_SOC_NOPM, 0, 0),
2350
2351 SND_SOC_DAPM_MIXER("WSA_AIF_VI Mixer", SND_SOC_NOPM, WSA_MACRO_AIF_VI,
2352 0, aif_vi_mixer, ARRAY_SIZE(aif_vi_mixer)),
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05302353 SND_SOC_DAPM_MUX_E("WSA RX_MIX EC0_MUX", SND_SOC_NOPM,
2354 WSA_MACRO_EC0_MUX, 0,
2355 &rx_mix_ec0_mux, wsa_macro_enable_echo,
2356 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2357 SND_SOC_DAPM_MUX_E("WSA RX_MIX EC1_MUX", SND_SOC_NOPM,
2358 WSA_MACRO_EC1_MUX, 0,
2359 &rx_mix_ec1_mux, wsa_macro_enable_echo,
2360 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302361
2362 SND_SOC_DAPM_MUX("WSA RX0 MUX", SND_SOC_NOPM, WSA_MACRO_RX0, 0,
2363 &rx_mux[WSA_MACRO_RX0]),
2364 SND_SOC_DAPM_MUX("WSA RX1 MUX", SND_SOC_NOPM, WSA_MACRO_RX1, 0,
2365 &rx_mux[WSA_MACRO_RX1]),
2366 SND_SOC_DAPM_MUX("WSA RX_MIX0 MUX", SND_SOC_NOPM, WSA_MACRO_RX_MIX0, 0,
2367 &rx_mux[WSA_MACRO_RX_MIX0]),
2368 SND_SOC_DAPM_MUX("WSA RX_MIX1 MUX", SND_SOC_NOPM, WSA_MACRO_RX_MIX1, 0,
2369 &rx_mux[WSA_MACRO_RX_MIX1]),
2370
2371 SND_SOC_DAPM_MIXER("WSA RX0", SND_SOC_NOPM, 0, 0, NULL, 0),
2372 SND_SOC_DAPM_MIXER("WSA RX1", SND_SOC_NOPM, 0, 0, NULL, 0),
2373 SND_SOC_DAPM_MIXER("WSA RX_MIX0", SND_SOC_NOPM, 0, 0, NULL, 0),
2374 SND_SOC_DAPM_MIXER("WSA RX_MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
2375
2376 SND_SOC_DAPM_MUX_E("WSA_RX0 INP0", SND_SOC_NOPM, 0, 0,
2377 &rx0_prim_inp0_mux, wsa_macro_enable_swr,
2378 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2379 SND_SOC_DAPM_MUX_E("WSA_RX0 INP1", SND_SOC_NOPM, 0, 0,
2380 &rx0_prim_inp1_mux, wsa_macro_enable_swr,
2381 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2382 SND_SOC_DAPM_MUX_E("WSA_RX0 INP2", SND_SOC_NOPM, 0, 0,
2383 &rx0_prim_inp2_mux, wsa_macro_enable_swr,
2384 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2385 SND_SOC_DAPM_MUX_E("WSA_RX0 MIX INP", SND_SOC_NOPM, 0, 0,
2386 &rx0_mix_mux, wsa_macro_enable_mix_path,
2387 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2388 SND_SOC_DAPM_MUX_E("WSA_RX1 INP0", SND_SOC_NOPM, 0, 0,
2389 &rx1_prim_inp0_mux, wsa_macro_enable_swr,
2390 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2391 SND_SOC_DAPM_MUX_E("WSA_RX1 INP1", SND_SOC_NOPM, 0, 0,
2392 &rx1_prim_inp1_mux, wsa_macro_enable_swr,
2393 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2394 SND_SOC_DAPM_MUX_E("WSA_RX1 INP2", SND_SOC_NOPM, 0, 0,
2395 &rx1_prim_inp2_mux, wsa_macro_enable_swr,
2396 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2397 SND_SOC_DAPM_MUX_E("WSA_RX1 MIX INP", SND_SOC_NOPM, 0, 0,
2398 &rx1_mix_mux, wsa_macro_enable_mix_path,
2399 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2400 SND_SOC_DAPM_MIXER("WSA_RX INT0 MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
2401 SND_SOC_DAPM_MIXER("WSA_RX INT1 MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
2402 SND_SOC_DAPM_MIXER("WSA_RX INT0 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
2403 SND_SOC_DAPM_MIXER("WSA_RX INT1 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
2404
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302405 SND_SOC_DAPM_MUX_E("WSA_RX0 INT0 SIDETONE MIX",
2406 BOLERO_CDC_WSA_RX0_RX_PATH_CFG1, 4, 0,
2407 &rx0_sidetone_mix_mux, wsa_macro_enable_swr,
2408 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2409 SND_SOC_DAPM_INPUT("WSA SRC0_INP"),
2410
2411 SND_SOC_DAPM_INPUT("WSA_TX DEC0_INP"),
2412 SND_SOC_DAPM_INPUT("WSA_TX DEC1_INP"),
2413
Laxminath Kasam243e2752018-04-12 00:40:19 +05302414 SND_SOC_DAPM_MIXER_E("WSA_RX INT0 INTERP", SND_SOC_NOPM,
2415 WSA_MACRO_COMP1, 0, NULL, 0, wsa_macro_enable_interpolator,
2416 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2417 SND_SOC_DAPM_POST_PMD),
2418 SND_SOC_DAPM_MIXER_E("WSA_RX INT1 INTERP", SND_SOC_NOPM,
2419 WSA_MACRO_COMP2, 0, NULL, 0, wsa_macro_enable_interpolator,
2420 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2421 SND_SOC_DAPM_POST_PMD),
2422
2423 SND_SOC_DAPM_MIXER_E("WSA_RX INT0 CHAIN", SND_SOC_NOPM, 0, 0,
2424 NULL, 0, wsa_macro_spk_boost_event,
Laxminath Kasam0c857002018-07-17 23:47:17 +05302425 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2426 SND_SOC_DAPM_POST_PMD),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302427 SND_SOC_DAPM_MIXER_E("WSA_RX INT1 CHAIN", SND_SOC_NOPM, 0, 0,
2428 NULL, 0, wsa_macro_spk_boost_event,
Laxminath Kasam0c857002018-07-17 23:47:17 +05302429 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2430 SND_SOC_DAPM_POST_PMD),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302431
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302432 SND_SOC_DAPM_MIXER_E("WSA_RX INT0 VBAT", SND_SOC_NOPM,
2433 0, 0, wsa_int0_vbat_mix_switch,
2434 ARRAY_SIZE(wsa_int0_vbat_mix_switch),
2435 wsa_macro_enable_vbat,
2436 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2437 SND_SOC_DAPM_MIXER_E("WSA_RX INT1 VBAT", SND_SOC_NOPM,
2438 0, 0, wsa_int1_vbat_mix_switch,
2439 ARRAY_SIZE(wsa_int1_vbat_mix_switch),
2440 wsa_macro_enable_vbat,
2441 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2442
Laxminath Kasam243e2752018-04-12 00:40:19 +05302443 SND_SOC_DAPM_INPUT("VIINPUT_WSA"),
2444
2445 SND_SOC_DAPM_OUTPUT("WSA_SPK1 OUT"),
2446 SND_SOC_DAPM_OUTPUT("WSA_SPK2 OUT"),
2447
2448 SND_SOC_DAPM_SUPPLY_S("WSA_MCLK", 0, SND_SOC_NOPM, 0, 0,
2449 wsa_macro_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2450};
2451
2452static const struct snd_soc_dapm_route wsa_audio_map[] = {
2453 /* VI Feedback */
2454 {"WSA_AIF_VI Mixer", "WSA_SPKR_VI_1", "VIINPUT_WSA"},
2455 {"WSA_AIF_VI Mixer", "WSA_SPKR_VI_2", "VIINPUT_WSA"},
2456 {"WSA AIF_VI", NULL, "WSA_AIF_VI Mixer"},
2457 {"WSA AIF_VI", NULL, "WSA_MCLK"},
2458
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05302459 {"WSA RX_MIX EC0_MUX", "RX_MIX_TX0", "WSA_RX INT0 SEC MIX"},
2460 {"WSA RX_MIX EC1_MUX", "RX_MIX_TX0", "WSA_RX INT0 SEC MIX"},
2461 {"WSA RX_MIX EC0_MUX", "RX_MIX_TX1", "WSA_RX INT1 SEC MIX"},
2462 {"WSA RX_MIX EC1_MUX", "RX_MIX_TX1", "WSA_RX INT1 SEC MIX"},
2463 {"WSA AIF_ECHO", NULL, "WSA RX_MIX EC0_MUX"},
2464 {"WSA AIF_ECHO", NULL, "WSA RX_MIX EC1_MUX"},
2465 {"WSA AIF_ECHO", NULL, "WSA_MCLK"},
2466
Laxminath Kasam243e2752018-04-12 00:40:19 +05302467 {"WSA AIF1 PB", NULL, "WSA_MCLK"},
2468 {"WSA AIF_MIX1 PB", NULL, "WSA_MCLK"},
2469
2470 {"WSA RX0 MUX", "AIF1_PB", "WSA AIF1 PB"},
2471 {"WSA RX1 MUX", "AIF1_PB", "WSA AIF1 PB"},
2472 {"WSA RX_MIX0 MUX", "AIF1_PB", "WSA AIF1 PB"},
2473 {"WSA RX_MIX1 MUX", "AIF1_PB", "WSA AIF1 PB"},
2474
2475 {"WSA RX0 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
2476 {"WSA RX1 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
2477 {"WSA RX_MIX0 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
2478 {"WSA RX_MIX1 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
2479
2480 {"WSA RX0", NULL, "WSA RX0 MUX"},
2481 {"WSA RX1", NULL, "WSA RX1 MUX"},
2482 {"WSA RX_MIX0", NULL, "WSA RX_MIX0 MUX"},
2483 {"WSA RX_MIX1", NULL, "WSA RX_MIX1 MUX"},
2484
2485 {"WSA_RX0 INP0", "RX0", "WSA RX0"},
2486 {"WSA_RX0 INP0", "RX1", "WSA RX1"},
2487 {"WSA_RX0 INP0", "RX_MIX0", "WSA RX_MIX0"},
2488 {"WSA_RX0 INP0", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302489 {"WSA_RX0 INP0", "DEC0", "WSA_TX DEC0_INP"},
2490 {"WSA_RX0 INP0", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302491 {"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP0"},
2492
2493 {"WSA_RX0 INP1", "RX0", "WSA RX0"},
2494 {"WSA_RX0 INP1", "RX1", "WSA RX1"},
2495 {"WSA_RX0 INP1", "RX_MIX0", "WSA RX_MIX0"},
2496 {"WSA_RX0 INP1", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302497 {"WSA_RX0 INP1", "DEC0", "WSA_TX DEC0_INP"},
2498 {"WSA_RX0 INP1", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302499 {"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP1"},
2500
2501 {"WSA_RX0 INP2", "RX0", "WSA RX0"},
2502 {"WSA_RX0 INP2", "RX1", "WSA RX1"},
2503 {"WSA_RX0 INP2", "RX_MIX0", "WSA RX_MIX0"},
2504 {"WSA_RX0 INP2", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302505 {"WSA_RX0 INP2", "DEC0", "WSA_TX DEC0_INP"},
2506 {"WSA_RX0 INP2", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302507 {"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP2"},
2508
2509 {"WSA_RX0 MIX INP", "RX0", "WSA RX0"},
2510 {"WSA_RX0 MIX INP", "RX1", "WSA RX1"},
2511 {"WSA_RX0 MIX INP", "RX_MIX0", "WSA RX_MIX0"},
2512 {"WSA_RX0 MIX INP", "RX_MIX1", "WSA RX_MIX1"},
2513 {"WSA_RX INT0 SEC MIX", NULL, "WSA_RX0 MIX INP"},
2514
2515 {"WSA_RX INT0 SEC MIX", NULL, "WSA_RX INT0 MIX"},
2516 {"WSA_RX INT0 INTERP", NULL, "WSA_RX INT0 SEC MIX"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302517 {"WSA_RX0 INT0 SIDETONE MIX", "SRC0", "WSA SRC0_INP"},
2518 {"WSA_RX INT0 INTERP", NULL, "WSA_RX0 INT0 SIDETONE MIX"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302519 {"WSA_RX INT0 CHAIN", NULL, "WSA_RX INT0 INTERP"},
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302520
2521 {"WSA_RX INT0 VBAT", "WSA RX0 VBAT Enable", "WSA_RX INT0 INTERP"},
2522 {"WSA_RX INT0 CHAIN", NULL, "WSA_RX INT0 VBAT"},
2523
Laxminath Kasam243e2752018-04-12 00:40:19 +05302524 {"WSA_SPK1 OUT", NULL, "WSA_RX INT0 CHAIN"},
Laxminath Kasamfc281ad2018-08-06 20:19:40 +05302525 {"WSA_SPK1 OUT", NULL, "WSA_MCLK"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302526
2527 {"WSA_RX1 INP0", "RX0", "WSA RX0"},
2528 {"WSA_RX1 INP0", "RX1", "WSA RX1"},
2529 {"WSA_RX1 INP0", "RX_MIX0", "WSA RX_MIX0"},
2530 {"WSA_RX1 INP0", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302531 {"WSA_RX1 INP0", "DEC0", "WSA_TX DEC0_INP"},
2532 {"WSA_RX1 INP0", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302533 {"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP0"},
2534
2535 {"WSA_RX1 INP1", "RX0", "WSA RX0"},
2536 {"WSA_RX1 INP1", "RX1", "WSA RX1"},
2537 {"WSA_RX1 INP1", "RX_MIX0", "WSA RX_MIX0"},
2538 {"WSA_RX1 INP1", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302539 {"WSA_RX1 INP1", "DEC0", "WSA_TX DEC0_INP"},
2540 {"WSA_RX1 INP1", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302541 {"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP1"},
2542
2543 {"WSA_RX1 INP2", "RX0", "WSA RX0"},
2544 {"WSA_RX1 INP2", "RX1", "WSA RX1"},
2545 {"WSA_RX1 INP2", "RX_MIX0", "WSA RX_MIX0"},
2546 {"WSA_RX1 INP2", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302547 {"WSA_RX1 INP2", "DEC0", "WSA_TX DEC0_INP"},
2548 {"WSA_RX1 INP2", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302549 {"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP2"},
2550
2551 {"WSA_RX1 MIX INP", "RX0", "WSA RX0"},
2552 {"WSA_RX1 MIX INP", "RX1", "WSA RX1"},
2553 {"WSA_RX1 MIX INP", "RX_MIX0", "WSA RX_MIX0"},
2554 {"WSA_RX1 MIX INP", "RX_MIX1", "WSA RX_MIX1"},
2555 {"WSA_RX INT1 SEC MIX", NULL, "WSA_RX1 MIX INP"},
2556
2557 {"WSA_RX INT1 SEC MIX", NULL, "WSA_RX INT1 MIX"},
2558 {"WSA_RX INT1 INTERP", NULL, "WSA_RX INT1 SEC MIX"},
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302559
2560 {"WSA_RX INT1 VBAT", "WSA RX1 VBAT Enable", "WSA_RX INT1 INTERP"},
2561 {"WSA_RX INT1 CHAIN", NULL, "WSA_RX INT1 VBAT"},
2562
Laxminath Kasam243e2752018-04-12 00:40:19 +05302563 {"WSA_RX INT1 CHAIN", NULL, "WSA_RX INT1 INTERP"},
2564 {"WSA_SPK2 OUT", NULL, "WSA_RX INT1 CHAIN"},
Laxminath Kasamfc281ad2018-08-06 20:19:40 +05302565 {"WSA_SPK2 OUT", NULL, "WSA_MCLK"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302566};
2567
2568static const struct wsa_macro_reg_mask_val wsa_macro_reg_init[] = {
2569 {BOLERO_CDC_WSA_BOOST0_BOOST_CFG1, 0x3F, 0x12},
2570 {BOLERO_CDC_WSA_BOOST0_BOOST_CFG2, 0x1C, 0x08},
2571 {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x1E, 0x18},
2572 {BOLERO_CDC_WSA_BOOST1_BOOST_CFG1, 0x3F, 0x12},
2573 {BOLERO_CDC_WSA_BOOST1_BOOST_CFG2, 0x1C, 0x08},
2574 {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x1E, 0x18},
2575 {BOLERO_CDC_WSA_BOOST0_BOOST_CTL, 0x70, 0x58},
2576 {BOLERO_CDC_WSA_BOOST1_BOOST_CTL, 0x70, 0x58},
2577 {BOLERO_CDC_WSA_RX0_RX_PATH_CFG1, 0x08, 0x08},
2578 {BOLERO_CDC_WSA_RX1_RX_PATH_CFG1, 0x08, 0x08},
2579 {BOLERO_CDC_WSA_TOP_TOP_CFG1, 0x02, 0x02},
2580 {BOLERO_CDC_WSA_TOP_TOP_CFG1, 0x01, 0x01},
2581 {BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
2582 {BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
2583 {BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
2584 {BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
2585 {BOLERO_CDC_WSA_COMPANDER0_CTL3, 0x80, 0x80},
2586 {BOLERO_CDC_WSA_COMPANDER1_CTL3, 0x80, 0x80},
2587 {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x01, 0x01},
2588 {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x01, 0x01},
2589 {BOLERO_CDC_WSA_RX0_RX_PATH_CFG0, 0x01, 0x01},
2590 {BOLERO_CDC_WSA_RX1_RX_PATH_CFG0, 0x01, 0x01},
2591 {BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CFG, 0x01, 0x01},
2592 {BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CFG, 0x01, 0x01},
2593};
2594
Meng Wang15c825d2018-09-06 10:49:18 +08002595static void wsa_macro_init_bcl_pmic_reg(struct snd_soc_component *component)
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302596{
2597 struct device *wsa_dev = NULL;
2598 struct wsa_macro_priv *wsa_priv = NULL;
2599
Meng Wang15c825d2018-09-06 10:49:18 +08002600 if (!component) {
2601 pr_err("%s: NULL component pointer!\n", __func__);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302602 return;
2603 }
2604
Meng Wang15c825d2018-09-06 10:49:18 +08002605 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302606 return;
2607
2608 switch (wsa_priv->bcl_pmic_params.id) {
2609 case 0:
2610 /* Enable ID0 to listen to respective PMIC group interrupts */
Meng Wang15c825d2018-09-06 10:49:18 +08002611 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302612 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CTL1, 0x02, 0x02);
2613 /* Update MC_SID0 */
Meng Wang15c825d2018-09-06 10:49:18 +08002614 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302615 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG1, 0x0F,
2616 wsa_priv->bcl_pmic_params.sid);
2617 /* Update MC_PPID0 */
Meng Wang15c825d2018-09-06 10:49:18 +08002618 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302619 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG2, 0xFF,
2620 wsa_priv->bcl_pmic_params.ppid);
2621 break;
2622 case 1:
2623 /* Enable ID1 to listen to respective PMIC group interrupts */
Meng Wang15c825d2018-09-06 10:49:18 +08002624 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302625 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CTL1, 0x01, 0x01);
2626 /* Update MC_SID1 */
Meng Wang15c825d2018-09-06 10:49:18 +08002627 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302628 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG3, 0x0F,
2629 wsa_priv->bcl_pmic_params.sid);
2630 /* Update MC_PPID1 */
Meng Wang15c825d2018-09-06 10:49:18 +08002631 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302632 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG4, 0xFF,
2633 wsa_priv->bcl_pmic_params.ppid);
2634 break;
2635 default:
2636 dev_err(wsa_dev, "%s: PMIC ID is invalid %d\n",
2637 __func__, wsa_priv->bcl_pmic_params.id);
2638 break;
2639 }
2640}
2641
Meng Wang15c825d2018-09-06 10:49:18 +08002642static void wsa_macro_init_reg(struct snd_soc_component *component)
Laxminath Kasam243e2752018-04-12 00:40:19 +05302643{
2644 int i;
2645
2646 for (i = 0; i < ARRAY_SIZE(wsa_macro_reg_init); i++)
Meng Wang15c825d2018-09-06 10:49:18 +08002647 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302648 wsa_macro_reg_init[i].reg,
2649 wsa_macro_reg_init[i].mask,
2650 wsa_macro_reg_init[i].val);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302651
Meng Wang15c825d2018-09-06 10:49:18 +08002652 wsa_macro_init_bcl_pmic_reg(component);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302653}
2654
2655static int wsa_swrm_clock(void *handle, bool enable)
2656{
2657 struct wsa_macro_priv *wsa_priv = (struct wsa_macro_priv *) handle;
2658 struct regmap *regmap = dev_get_regmap(wsa_priv->dev->parent, NULL);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302659 int ret = 0;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302660
Tanya Dixitab8eba82018-10-05 15:07:37 +05302661 if (regmap == NULL) {
2662 dev_err(wsa_priv->dev, "%s: regmap is NULL\n", __func__);
2663 return -EINVAL;
2664 }
2665
Laxminath Kasam243e2752018-04-12 00:40:19 +05302666 mutex_lock(&wsa_priv->swr_clk_lock);
2667
2668 dev_dbg(wsa_priv->dev, "%s: swrm clock %s\n",
2669 __func__, (enable ? "enable" : "disable"));
2670 if (enable) {
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302671 pm_runtime_get_sync(wsa_priv->dev);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302672 if (wsa_priv->swr_clk_users == 0) {
Karthikeyan Mani01f1ba42019-02-26 18:48:15 -08002673 msm_cdc_pinctrl_select_active_state(
2674 wsa_priv->wsa_swr_gpio_p);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302675 ret = wsa_macro_mclk_enable(wsa_priv, 1, true);
2676 if (ret < 0) {
Karthikeyan Mani01f1ba42019-02-26 18:48:15 -08002677 msm_cdc_pinctrl_select_sleep_state(
2678 wsa_priv->wsa_swr_gpio_p);
Ramprasad Katkam14efed62019-03-07 13:16:50 +05302679 dev_err_ratelimited(wsa_priv->dev,
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302680 "%s: wsa request clock enable failed\n",
2681 __func__);
2682 goto exit;
2683 }
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05302684 if (wsa_priv->reset_swr)
2685 regmap_update_bits(regmap,
2686 BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
2687 0x02, 0x02);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302688 regmap_update_bits(regmap,
2689 BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
2690 0x01, 0x01);
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05302691 if (wsa_priv->reset_swr)
2692 regmap_update_bits(regmap,
2693 BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
2694 0x02, 0x00);
2695 wsa_priv->reset_swr = false;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302696 }
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302697 pm_runtime_mark_last_busy(wsa_priv->dev);
2698 pm_runtime_put_autosuspend(wsa_priv->dev);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302699 wsa_priv->swr_clk_users++;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302700 } else {
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302701 if (wsa_priv->swr_clk_users <= 0) {
2702 dev_err(wsa_priv->dev, "%s: clock already disabled\n",
2703 __func__);
2704 wsa_priv->swr_clk_users = 0;
2705 goto exit;
2706 }
Laxminath Kasam243e2752018-04-12 00:40:19 +05302707 wsa_priv->swr_clk_users--;
2708 if (wsa_priv->swr_clk_users == 0) {
2709 regmap_update_bits(regmap,
2710 BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
2711 0x01, 0x00);
Karthikeyan Mani01f1ba42019-02-26 18:48:15 -08002712 wsa_macro_mclk_enable(wsa_priv, 0, true);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302713 msm_cdc_pinctrl_select_sleep_state(
2714 wsa_priv->wsa_swr_gpio_p);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302715 }
2716 }
2717 dev_dbg(wsa_priv->dev, "%s: swrm clock users %d\n",
2718 __func__, wsa_priv->swr_clk_users);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302719exit:
Laxminath Kasam243e2752018-04-12 00:40:19 +05302720 mutex_unlock(&wsa_priv->swr_clk_lock);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302721 return ret;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302722}
2723
Meng Wang15c825d2018-09-06 10:49:18 +08002724static int wsa_macro_init(struct snd_soc_component *component)
Laxminath Kasam243e2752018-04-12 00:40:19 +05302725{
Meng Wang15c825d2018-09-06 10:49:18 +08002726 struct snd_soc_dapm_context *dapm =
2727 snd_soc_component_get_dapm(component);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302728 int ret;
2729 struct device *wsa_dev = NULL;
2730 struct wsa_macro_priv *wsa_priv = NULL;
2731
Meng Wang15c825d2018-09-06 10:49:18 +08002732 wsa_dev = bolero_get_device_ptr(component->dev, WSA_MACRO);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302733 if (!wsa_dev) {
Meng Wang15c825d2018-09-06 10:49:18 +08002734 dev_err(component->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302735 "%s: null device for macro!\n", __func__);
2736 return -EINVAL;
2737 }
2738 wsa_priv = dev_get_drvdata(wsa_dev);
2739 if (!wsa_priv) {
Meng Wang15c825d2018-09-06 10:49:18 +08002740 dev_err(component->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302741 "%s: priv is null for macro!\n", __func__);
2742 return -EINVAL;
2743 }
2744
2745 ret = snd_soc_dapm_new_controls(dapm, wsa_macro_dapm_widgets,
2746 ARRAY_SIZE(wsa_macro_dapm_widgets));
2747 if (ret < 0) {
2748 dev_err(wsa_dev, "%s: Failed to add controls\n", __func__);
2749 return ret;
2750 }
2751
2752 ret = snd_soc_dapm_add_routes(dapm, wsa_audio_map,
2753 ARRAY_SIZE(wsa_audio_map));
2754 if (ret < 0) {
2755 dev_err(wsa_dev, "%s: Failed to add routes\n", __func__);
2756 return ret;
2757 }
2758
2759 ret = snd_soc_dapm_new_widgets(dapm->card);
2760 if (ret < 0) {
2761 dev_err(wsa_dev, "%s: Failed to add widgets\n", __func__);
2762 return ret;
2763 }
2764
Meng Wang15c825d2018-09-06 10:49:18 +08002765 ret = snd_soc_add_component_controls(component, wsa_macro_snd_controls,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302766 ARRAY_SIZE(wsa_macro_snd_controls));
2767 if (ret < 0) {
2768 dev_err(wsa_dev, "%s: Failed to add snd_ctls\n", __func__);
2769 return ret;
2770 }
Laxminath Kasam638b5602018-09-24 13:19:52 +05302771 snd_soc_dapm_ignore_suspend(dapm, "WSA_AIF1 Playback");
2772 snd_soc_dapm_ignore_suspend(dapm, "WSA_AIF_MIX1 Playback");
2773 snd_soc_dapm_ignore_suspend(dapm, "WSA_AIF_VI Capture");
2774 snd_soc_dapm_ignore_suspend(dapm, "WSA_AIF_ECHO Capture");
2775 snd_soc_dapm_ignore_suspend(dapm, "WSA_SPK1 OUT");
2776 snd_soc_dapm_ignore_suspend(dapm, "WSA_SPK2 OUT");
2777 snd_soc_dapm_ignore_suspend(dapm, "VIINPUT_WSA");
2778 snd_soc_dapm_ignore_suspend(dapm, "WSA SRC0_INP");
2779 snd_soc_dapm_ignore_suspend(dapm, "WSA_TX DEC0_INP");
2780 snd_soc_dapm_ignore_suspend(dapm, "WSA_TX DEC1_INP");
2781 snd_soc_dapm_sync(dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302782
Meng Wang15c825d2018-09-06 10:49:18 +08002783 wsa_priv->component = component;
Laxminath Kasam21c8b222018-06-21 18:47:22 +05302784 wsa_priv->spkr_gain_offset = WSA_MACRO_GAIN_OFFSET_0_DB;
Meng Wang15c825d2018-09-06 10:49:18 +08002785 wsa_macro_init_reg(component);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302786
2787 return 0;
2788}
2789
Meng Wang15c825d2018-09-06 10:49:18 +08002790static int wsa_macro_deinit(struct snd_soc_component *component)
Laxminath Kasam243e2752018-04-12 00:40:19 +05302791{
2792 struct device *wsa_dev = NULL;
2793 struct wsa_macro_priv *wsa_priv = NULL;
2794
Meng Wang15c825d2018-09-06 10:49:18 +08002795 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302796 return -EINVAL;
2797
Meng Wang15c825d2018-09-06 10:49:18 +08002798 wsa_priv->component = NULL;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302799
2800 return 0;
2801}
2802
2803static void wsa_macro_add_child_devices(struct work_struct *work)
2804{
2805 struct wsa_macro_priv *wsa_priv;
2806 struct platform_device *pdev;
2807 struct device_node *node;
2808 struct wsa_macro_swr_ctrl_data *swr_ctrl_data = NULL, *temp;
2809 int ret;
2810 u16 count = 0, ctrl_num = 0;
2811 struct wsa_macro_swr_ctrl_platform_data *platdata;
2812 char plat_dev_name[WSA_MACRO_SWR_STRING_LEN];
2813
2814 wsa_priv = container_of(work, struct wsa_macro_priv,
2815 wsa_macro_add_child_devices_work);
2816 if (!wsa_priv) {
2817 pr_err("%s: Memory for wsa_priv does not exist\n",
2818 __func__);
2819 return;
2820 }
Laxminath Kasam21c8b222018-06-21 18:47:22 +05302821 if (!wsa_priv->dev || !wsa_priv->dev->of_node) {
Laxminath Kasam243e2752018-04-12 00:40:19 +05302822 dev_err(wsa_priv->dev,
2823 "%s: DT node for wsa_priv does not exist\n", __func__);
2824 return;
2825 }
2826
2827 platdata = &wsa_priv->swr_plat_data;
2828 wsa_priv->child_count = 0;
2829
2830 for_each_available_child_of_node(wsa_priv->dev->of_node, node) {
2831 if (strnstr(node->name, "wsa_swr_master",
2832 strlen("wsa_swr_master")) != NULL)
2833 strlcpy(plat_dev_name, "wsa_swr_ctrl",
2834 (WSA_MACRO_SWR_STRING_LEN - 1));
2835 else if (strnstr(node->name, "msm_cdc_pinctrl",
2836 strlen("msm_cdc_pinctrl")) != NULL)
2837 strlcpy(plat_dev_name, node->name,
2838 (WSA_MACRO_SWR_STRING_LEN - 1));
2839 else
2840 continue;
2841
2842 pdev = platform_device_alloc(plat_dev_name, -1);
2843 if (!pdev) {
2844 dev_err(wsa_priv->dev, "%s: pdev memory alloc failed\n",
2845 __func__);
2846 ret = -ENOMEM;
2847 goto err;
2848 }
2849 pdev->dev.parent = wsa_priv->dev;
2850 pdev->dev.of_node = node;
2851
2852 if (strnstr(node->name, "wsa_swr_master",
2853 strlen("wsa_swr_master")) != NULL) {
2854 ret = platform_device_add_data(pdev, platdata,
2855 sizeof(*platdata));
2856 if (ret) {
2857 dev_err(&pdev->dev,
2858 "%s: cannot add plat data ctrl:%d\n",
2859 __func__, ctrl_num);
2860 goto fail_pdev_add;
2861 }
2862 }
2863
2864 ret = platform_device_add(pdev);
2865 if (ret) {
2866 dev_err(&pdev->dev,
2867 "%s: Cannot add platform device\n",
2868 __func__);
2869 goto fail_pdev_add;
2870 }
2871
2872 if (!strcmp(node->name, "wsa_swr_master")) {
2873 temp = krealloc(swr_ctrl_data,
2874 (ctrl_num + 1) * sizeof(
2875 struct wsa_macro_swr_ctrl_data),
2876 GFP_KERNEL);
2877 if (!temp) {
2878 dev_err(&pdev->dev, "out of memory\n");
2879 ret = -ENOMEM;
2880 goto err;
2881 }
2882 swr_ctrl_data = temp;
2883 swr_ctrl_data[ctrl_num].wsa_swr_pdev = pdev;
2884 ctrl_num++;
2885 dev_dbg(&pdev->dev,
2886 "%s: Added soundwire ctrl device(s)\n",
2887 __func__);
2888 wsa_priv->swr_ctrl_data = swr_ctrl_data;
2889 }
2890 if (wsa_priv->child_count < WSA_MACRO_CHILD_DEVICES_MAX)
2891 wsa_priv->pdev_child_devices[
2892 wsa_priv->child_count++] = pdev;
2893 else
2894 goto err;
2895 }
2896
2897 return;
2898fail_pdev_add:
2899 for (count = 0; count < wsa_priv->child_count; count++)
2900 platform_device_put(wsa_priv->pdev_child_devices[count]);
2901err:
2902 return;
2903}
2904
2905static void wsa_macro_init_ops(struct macro_ops *ops,
2906 char __iomem *wsa_io_base)
2907{
2908 memset(ops, 0, sizeof(struct macro_ops));
2909 ops->init = wsa_macro_init;
2910 ops->exit = wsa_macro_deinit;
2911 ops->io_base = wsa_io_base;
2912 ops->dai_ptr = wsa_macro_dai;
2913 ops->num_dais = ARRAY_SIZE(wsa_macro_dai);
Laxminath Kasamfb0d6832018-09-22 01:49:52 +05302914 ops->event_handler = wsa_macro_event_handler;
Sudheer Papothia3e969d2018-10-27 06:22:10 +05302915 ops->set_port_map = wsa_macro_set_port_map;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302916}
2917
2918static int wsa_macro_probe(struct platform_device *pdev)
2919{
2920 struct macro_ops ops;
2921 struct wsa_macro_priv *wsa_priv;
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07002922 u32 wsa_base_addr, default_clk_id;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302923 char __iomem *wsa_io_base;
2924 int ret = 0;
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302925 u8 bcl_pmic_params[3];
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07002926 u32 is_used_wsa_swr_gpio = 1;
2927 const char *is_used_wsa_swr_gpio_dt = "qcom,is-used-swr-gpio";
Laxminath Kasam243e2752018-04-12 00:40:19 +05302928
2929 wsa_priv = devm_kzalloc(&pdev->dev, sizeof(struct wsa_macro_priv),
2930 GFP_KERNEL);
2931 if (!wsa_priv)
2932 return -ENOMEM;
2933
2934 wsa_priv->dev = &pdev->dev;
2935 ret = of_property_read_u32(pdev->dev.of_node, "reg",
2936 &wsa_base_addr);
2937 if (ret) {
2938 dev_err(&pdev->dev, "%s: could not find %s entry in dt\n",
2939 __func__, "reg");
2940 return ret;
2941 }
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07002942 if (of_find_property(pdev->dev.of_node, is_used_wsa_swr_gpio_dt,
2943 NULL)) {
2944 ret = of_property_read_u32(pdev->dev.of_node,
2945 is_used_wsa_swr_gpio_dt,
2946 &is_used_wsa_swr_gpio);
2947 if (ret) {
2948 dev_err(&pdev->dev, "%s: error reading %s in dt\n",
2949 __func__, is_used_wsa_swr_gpio_dt);
2950 is_used_wsa_swr_gpio = 1;
2951 }
2952 }
Laxminath Kasam243e2752018-04-12 00:40:19 +05302953 wsa_priv->wsa_swr_gpio_p = of_parse_phandle(pdev->dev.of_node,
2954 "qcom,wsa-swr-gpios", 0);
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07002955 if (!wsa_priv->wsa_swr_gpio_p && is_used_wsa_swr_gpio) {
Laxminath Kasam243e2752018-04-12 00:40:19 +05302956 dev_err(&pdev->dev, "%s: swr_gpios handle not provided!\n",
2957 __func__);
2958 return -EINVAL;
2959 }
Karthikeyan Manib44e4552019-09-09 23:06:04 -07002960 if (msm_cdc_pinctrl_get_state(wsa_priv->wsa_swr_gpio_p) < 0 &&
2961 is_used_wsa_swr_gpio) {
Karthikeyan Mani326536d2019-06-03 13:29:43 -07002962 dev_err(&pdev->dev, "%s: failed to get swr pin state\n",
2963 __func__);
2964 return -EPROBE_DEFER;
2965 }
2966
Laxminath Kasam243e2752018-04-12 00:40:19 +05302967 wsa_io_base = devm_ioremap(&pdev->dev,
2968 wsa_base_addr, WSA_MACRO_MAX_OFFSET);
2969 if (!wsa_io_base) {
2970 dev_err(&pdev->dev, "%s: ioremap failed\n", __func__);
2971 return -EINVAL;
2972 }
2973 wsa_priv->wsa_io_base = wsa_io_base;
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05302974 wsa_priv->reset_swr = true;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302975 INIT_WORK(&wsa_priv->wsa_macro_add_child_devices_work,
2976 wsa_macro_add_child_devices);
2977 wsa_priv->swr_plat_data.handle = (void *) wsa_priv;
2978 wsa_priv->swr_plat_data.read = NULL;
2979 wsa_priv->swr_plat_data.write = NULL;
2980 wsa_priv->swr_plat_data.bulk_write = NULL;
2981 wsa_priv->swr_plat_data.clk = wsa_swrm_clock;
2982 wsa_priv->swr_plat_data.handle_irq = NULL;
2983
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07002984 ret = of_property_read_u32(pdev->dev.of_node, "qcom,default-clk-id",
2985 &default_clk_id);
2986 if (ret) {
2987 dev_err(&pdev->dev, "%s: could not find %s entry in dt\n",
2988 __func__, "qcom,mux0-clk-id");
2989 default_clk_id = WSA_CORE_CLK;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302990 }
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302991
2992 ret = of_property_read_u8_array(pdev->dev.of_node,
2993 "qcom,wsa-bcl-pmic-params", bcl_pmic_params,
2994 sizeof(bcl_pmic_params));
2995 if (ret) {
2996 dev_dbg(&pdev->dev, "%s: could not find %s entry in dt\n",
2997 __func__, "qcom,wsa-bcl-pmic-params");
2998 } else {
2999 wsa_priv->bcl_pmic_params.id = bcl_pmic_params[0];
3000 wsa_priv->bcl_pmic_params.sid = bcl_pmic_params[1];
3001 wsa_priv->bcl_pmic_params.ppid = bcl_pmic_params[2];
3002 }
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07003003 wsa_priv->default_clk_id = default_clk_id;
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303004
Laxminath Kasam243e2752018-04-12 00:40:19 +05303005 dev_set_drvdata(&pdev->dev, wsa_priv);
3006 mutex_init(&wsa_priv->mclk_lock);
3007 mutex_init(&wsa_priv->swr_clk_lock);
3008 wsa_macro_init_ops(&ops, wsa_io_base);
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07003009 ops.clk_id_req = wsa_priv->default_clk_id;
3010 ops.default_clk_id = wsa_priv->default_clk_id;
Laxminath Kasam243e2752018-04-12 00:40:19 +05303011 ret = bolero_register_macro(&pdev->dev, WSA_MACRO, &ops);
3012 if (ret < 0) {
3013 dev_err(&pdev->dev, "%s: register macro failed\n", __func__);
3014 goto reg_macro_fail;
3015 }
3016 schedule_work(&wsa_priv->wsa_macro_add_child_devices_work);
Sudheer Papothi7601cc62019-03-30 03:00:52 +05303017 pm_runtime_set_autosuspend_delay(&pdev->dev, AUTO_SUSPEND_DELAY);
3018 pm_runtime_use_autosuspend(&pdev->dev);
3019 pm_runtime_set_suspended(&pdev->dev);
3020 pm_runtime_enable(&pdev->dev);
3021
Laxminath Kasam243e2752018-04-12 00:40:19 +05303022 return ret;
3023reg_macro_fail:
3024 mutex_destroy(&wsa_priv->mclk_lock);
3025 mutex_destroy(&wsa_priv->swr_clk_lock);
3026 return ret;
3027}
3028
3029static int wsa_macro_remove(struct platform_device *pdev)
3030{
3031 struct wsa_macro_priv *wsa_priv;
3032 u16 count = 0;
3033
3034 wsa_priv = dev_get_drvdata(&pdev->dev);
3035
3036 if (!wsa_priv)
3037 return -EINVAL;
3038
3039 for (count = 0; count < wsa_priv->child_count &&
3040 count < WSA_MACRO_CHILD_DEVICES_MAX; count++)
3041 platform_device_unregister(wsa_priv->pdev_child_devices[count]);
3042
Sudheer Papothi7601cc62019-03-30 03:00:52 +05303043 pm_runtime_disable(&pdev->dev);
3044 pm_runtime_set_suspended(&pdev->dev);
Laxminath Kasam243e2752018-04-12 00:40:19 +05303045 bolero_unregister_macro(&pdev->dev, WSA_MACRO);
3046 mutex_destroy(&wsa_priv->mclk_lock);
3047 mutex_destroy(&wsa_priv->swr_clk_lock);
3048 return 0;
3049}
3050
3051static const struct of_device_id wsa_macro_dt_match[] = {
3052 {.compatible = "qcom,wsa-macro"},
3053 {}
3054};
3055
Sudheer Papothi7601cc62019-03-30 03:00:52 +05303056static const struct dev_pm_ops bolero_dev_pm_ops = {
3057 SET_RUNTIME_PM_OPS(
3058 bolero_runtime_suspend,
3059 bolero_runtime_resume,
3060 NULL
3061 )
3062};
3063
Laxminath Kasam243e2752018-04-12 00:40:19 +05303064static struct platform_driver wsa_macro_driver = {
3065 .driver = {
3066 .name = "wsa_macro",
3067 .owner = THIS_MODULE,
Sudheer Papothi7601cc62019-03-30 03:00:52 +05303068 .pm = &bolero_dev_pm_ops,
Laxminath Kasam243e2752018-04-12 00:40:19 +05303069 .of_match_table = wsa_macro_dt_match,
Xiaojun Sang53cd13a2018-06-29 15:14:37 +08003070 .suppress_bind_attrs = true,
Laxminath Kasam243e2752018-04-12 00:40:19 +05303071 },
3072 .probe = wsa_macro_probe,
3073 .remove = wsa_macro_remove,
3074};
3075
3076module_platform_driver(wsa_macro_driver);
3077
3078MODULE_DESCRIPTION("WSA macro driver");
3079MODULE_LICENSE("GPL v2");