blob: 928aec0d5e0d57ec3a5bac50a25df21a1f38b63a [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 }
2060 }
2061 wsa_priv->rx_port_value[widget->shift] = rx_port_value;
2062
2063 bit_input = widget->shift;
2064 if (widget->shift >= WSA_MACRO_RX_MIX)
2065 bit_input %= WSA_MACRO_RX_MIX;
2066
2067 switch (rx_port_value) {
2068 case 0:
2069 clear_bit(bit_input,
Laxminath Kasam59c7a1d2018-08-09 16:11:17 +05302070 &wsa_priv->active_ch_mask[aif_rst]);
2071 wsa_priv->active_ch_cnt[aif_rst]--;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302072 break;
2073 case 1:
2074 case 2:
2075 set_bit(bit_input,
Laxminath Kasam59c7a1d2018-08-09 16:11:17 +05302076 &wsa_priv->active_ch_mask[rx_port_value]);
2077 wsa_priv->active_ch_cnt[rx_port_value]++;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302078 break;
2079 default:
2080 dev_err(wsa_dev,
2081 "%s: Invalid AIF_ID for WSA RX MUX\n", __func__);
2082 return -EINVAL;
2083 }
2084
2085 snd_soc_dapm_mux_update_power(widget->dapm, kcontrol,
2086 rx_port_value, e, update);
2087 return 0;
2088}
2089
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302090static int wsa_macro_vbat_bcl_gsm_mode_func_get(struct snd_kcontrol *kcontrol,
2091 struct snd_ctl_elem_value *ucontrol)
2092{
Meng Wang15c825d2018-09-06 10:49:18 +08002093 struct snd_soc_component *component =
2094 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302095
2096 ucontrol->value.integer.value[0] =
Meng Wang15c825d2018-09-06 10:49:18 +08002097 ((snd_soc_component_read32(
2098 component, BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG) & 0x04) ?
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302099 1 : 0);
2100
Meng Wang15c825d2018-09-06 10:49:18 +08002101 dev_dbg(component->dev, "%s: value: %lu\n", __func__,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302102 ucontrol->value.integer.value[0]);
2103
2104 return 0;
2105}
2106
2107static int wsa_macro_vbat_bcl_gsm_mode_func_put(struct snd_kcontrol *kcontrol,
2108 struct snd_ctl_elem_value *ucontrol)
2109{
Meng Wang15c825d2018-09-06 10:49:18 +08002110 struct snd_soc_component *component =
2111 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302112
Meng Wang15c825d2018-09-06 10:49:18 +08002113 dev_dbg(component->dev, "%s: value: %lu\n", __func__,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302114 ucontrol->value.integer.value[0]);
2115
2116 /* Set Vbat register configuration for GSM mode bit based on value */
2117 if (ucontrol->value.integer.value[0])
Meng Wang15c825d2018-09-06 10:49:18 +08002118 snd_soc_component_update_bits(component,
2119 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG,
2120 0x04, 0x04);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302121 else
Meng Wang15c825d2018-09-06 10:49:18 +08002122 snd_soc_component_update_bits(component,
2123 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG,
2124 0x04, 0x00);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302125
2126 return 0;
2127}
2128
2129static int wsa_macro_soft_clip_enable_get(struct snd_kcontrol *kcontrol,
2130 struct snd_ctl_elem_value *ucontrol)
2131{
Meng Wang15c825d2018-09-06 10:49:18 +08002132 struct snd_soc_component *component =
2133 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302134 struct device *wsa_dev = NULL;
2135 struct wsa_macro_priv *wsa_priv = NULL;
2136 int path = ((struct soc_multi_mixer_control *)
2137 kcontrol->private_value)->shift;
2138
Meng Wang15c825d2018-09-06 10:49:18 +08002139 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302140 return -EINVAL;
2141
2142 ucontrol->value.integer.value[0] = wsa_priv->is_softclip_on[path];
2143
Meng Wang15c825d2018-09-06 10:49:18 +08002144 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302145 __func__, ucontrol->value.integer.value[0]);
2146
2147 return 0;
2148}
2149
2150static int wsa_macro_soft_clip_enable_put(struct snd_kcontrol *kcontrol,
2151 struct snd_ctl_elem_value *ucontrol)
2152{
Meng Wang15c825d2018-09-06 10:49:18 +08002153 struct snd_soc_component *component =
2154 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302155 struct device *wsa_dev = NULL;
2156 struct wsa_macro_priv *wsa_priv = NULL;
2157 int path = ((struct soc_multi_mixer_control *)
2158 kcontrol->private_value)->shift;
2159
Meng Wang15c825d2018-09-06 10:49:18 +08002160 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302161 return -EINVAL;
2162
2163 wsa_priv->is_softclip_on[path] = ucontrol->value.integer.value[0];
2164
Meng Wang15c825d2018-09-06 10:49:18 +08002165 dev_dbg(component->dev, "%s: soft clip enable for %d: %d\n", __func__,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302166 path, wsa_priv->is_softclip_on[path]);
2167
2168 return 0;
2169}
2170
Laxminath Kasam243e2752018-04-12 00:40:19 +05302171static const struct snd_kcontrol_new wsa_macro_snd_controls[] = {
2172 SOC_ENUM_EXT("EAR SPKR PA Gain", wsa_macro_ear_spkr_pa_gain_enum,
2173 wsa_macro_ear_spkr_pa_gain_get,
2174 wsa_macro_ear_spkr_pa_gain_put),
2175 SOC_ENUM_EXT("SPKR Left Boost Max State",
2176 wsa_macro_spkr_boost_stage_enum,
2177 wsa_macro_spkr_left_boost_stage_get,
2178 wsa_macro_spkr_left_boost_stage_put),
2179 SOC_ENUM_EXT("SPKR Right Boost Max State",
2180 wsa_macro_spkr_boost_stage_enum,
2181 wsa_macro_spkr_right_boost_stage_get,
2182 wsa_macro_spkr_right_boost_stage_put),
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302183 SOC_ENUM_EXT("GSM mode Enable", wsa_macro_vbat_bcl_gsm_mode_enum,
2184 wsa_macro_vbat_bcl_gsm_mode_func_get,
2185 wsa_macro_vbat_bcl_gsm_mode_func_put),
2186 SOC_SINGLE_EXT("WSA_Softclip0 Enable", SND_SOC_NOPM,
2187 WSA_MACRO_SOFTCLIP0, 1, 0,
2188 wsa_macro_soft_clip_enable_get,
2189 wsa_macro_soft_clip_enable_put),
2190 SOC_SINGLE_EXT("WSA_Softclip1 Enable", SND_SOC_NOPM,
2191 WSA_MACRO_SOFTCLIP1, 1, 0,
2192 wsa_macro_soft_clip_enable_get,
2193 wsa_macro_soft_clip_enable_put),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302194 SOC_SINGLE_SX_TLV("WSA_RX0 Digital Volume",
2195 BOLERO_CDC_WSA_RX0_RX_VOL_CTL,
2196 0, -84, 40, digital_gain),
2197 SOC_SINGLE_SX_TLV("WSA_RX1 Digital Volume",
2198 BOLERO_CDC_WSA_RX1_RX_VOL_CTL,
2199 0, -84, 40, digital_gain),
Vatsal Buchaf2a71b62019-03-26 16:14:40 +05302200 SOC_SINGLE_EXT("WSA_RX0 Digital Mute", SND_SOC_NOPM, WSA_MACRO_RX0, 1,
2201 0, wsa_macro_get_rx_mute_status,
2202 wsa_macro_set_rx_mute_status),
2203 SOC_SINGLE_EXT("WSA_RX1 Digital Mute", SND_SOC_NOPM, WSA_MACRO_RX1, 1,
2204 0, wsa_macro_get_rx_mute_status,
2205 wsa_macro_set_rx_mute_status),
2206 SOC_SINGLE_EXT("WSA_RX0_MIX Digital Mute", SND_SOC_NOPM,
2207 WSA_MACRO_RX_MIX0, 1, 0, wsa_macro_get_rx_mute_status,
2208 wsa_macro_set_rx_mute_status),
2209 SOC_SINGLE_EXT("WSA_RX1_MIX Digital Mute", SND_SOC_NOPM,
2210 WSA_MACRO_RX_MIX1, 1, 0, wsa_macro_get_rx_mute_status,
2211 wsa_macro_set_rx_mute_status),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302212 SOC_SINGLE_EXT("WSA_COMP1 Switch", SND_SOC_NOPM, WSA_MACRO_COMP1, 1, 0,
2213 wsa_macro_get_compander, wsa_macro_set_compander),
2214 SOC_SINGLE_EXT("WSA_COMP2 Switch", SND_SOC_NOPM, WSA_MACRO_COMP2, 1, 0,
2215 wsa_macro_get_compander, wsa_macro_set_compander),
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05302216 SOC_SINGLE_EXT("WSA_RX0 EC_HQ Switch", SND_SOC_NOPM, WSA_MACRO_RX0,
2217 1, 0, wsa_macro_get_ec_hq, wsa_macro_set_ec_hq),
2218 SOC_SINGLE_EXT("WSA_RX1 EC_HQ Switch", SND_SOC_NOPM, WSA_MACRO_RX1,
2219 1, 0, wsa_macro_get_ec_hq, wsa_macro_set_ec_hq),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302220};
2221
2222static const struct soc_enum rx_mux_enum =
2223 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_mux_text), rx_mux_text);
2224
2225static const struct snd_kcontrol_new rx_mux[WSA_MACRO_RX_MAX] = {
2226 SOC_DAPM_ENUM_EXT("WSA RX0 Mux", rx_mux_enum,
2227 wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),
2228 SOC_DAPM_ENUM_EXT("WSA RX1 Mux", rx_mux_enum,
2229 wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),
2230 SOC_DAPM_ENUM_EXT("WSA RX_MIX0 Mux", rx_mux_enum,
2231 wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),
2232 SOC_DAPM_ENUM_EXT("WSA RX_MIX1 Mux", rx_mux_enum,
2233 wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),
2234};
2235
2236static int wsa_macro_vi_feed_mixer_get(struct snd_kcontrol *kcontrol,
2237 struct snd_ctl_elem_value *ucontrol)
2238{
2239 struct snd_soc_dapm_widget *widget =
2240 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +08002241 struct snd_soc_component *component =
2242 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302243 struct soc_multi_mixer_control *mixer =
2244 ((struct soc_multi_mixer_control *)kcontrol->private_value);
2245 u32 dai_id = widget->shift;
2246 u32 spk_tx_id = mixer->shift;
2247 struct device *wsa_dev = NULL;
2248 struct wsa_macro_priv *wsa_priv = NULL;
2249
Meng Wang15c825d2018-09-06 10:49:18 +08002250 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302251 return -EINVAL;
2252
2253 if (test_bit(spk_tx_id, &wsa_priv->active_ch_mask[dai_id]))
2254 ucontrol->value.integer.value[0] = 1;
2255 else
2256 ucontrol->value.integer.value[0] = 0;
2257
2258 return 0;
2259}
2260
2261static int wsa_macro_vi_feed_mixer_put(struct snd_kcontrol *kcontrol,
2262 struct snd_ctl_elem_value *ucontrol)
2263{
2264 struct snd_soc_dapm_widget *widget =
2265 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +08002266 struct snd_soc_component *component =
2267 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302268 struct soc_multi_mixer_control *mixer =
2269 ((struct soc_multi_mixer_control *)kcontrol->private_value);
2270 u32 spk_tx_id = mixer->shift;
2271 u32 enable = ucontrol->value.integer.value[0];
2272 struct device *wsa_dev = NULL;
2273 struct wsa_macro_priv *wsa_priv = NULL;
2274
Meng Wang15c825d2018-09-06 10:49:18 +08002275 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302276 return -EINVAL;
2277
2278 wsa_priv->vi_feed_value = ucontrol->value.integer.value[0];
2279
2280 if (enable) {
2281 if (spk_tx_id == WSA_MACRO_TX0 &&
2282 !test_bit(WSA_MACRO_TX0,
2283 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
2284 set_bit(WSA_MACRO_TX0,
2285 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI]);
2286 wsa_priv->active_ch_cnt[WSA_MACRO_AIF_VI]++;
2287 }
2288 if (spk_tx_id == WSA_MACRO_TX1 &&
2289 !test_bit(WSA_MACRO_TX1,
2290 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
2291 set_bit(WSA_MACRO_TX1,
2292 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI]);
2293 wsa_priv->active_ch_cnt[WSA_MACRO_AIF_VI]++;
2294 }
2295 } else {
2296 if (spk_tx_id == WSA_MACRO_TX0 &&
2297 test_bit(WSA_MACRO_TX0,
2298 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
2299 clear_bit(WSA_MACRO_TX0,
2300 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI]);
2301 wsa_priv->active_ch_cnt[WSA_MACRO_AIF_VI]--;
2302 }
2303 if (spk_tx_id == WSA_MACRO_TX1 &&
2304 test_bit(WSA_MACRO_TX1,
2305 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
2306 clear_bit(WSA_MACRO_TX1,
2307 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI]);
2308 wsa_priv->active_ch_cnt[WSA_MACRO_AIF_VI]--;
2309 }
2310 }
2311 snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, NULL);
2312
2313 return 0;
2314}
2315
2316static const struct snd_kcontrol_new aif_vi_mixer[] = {
2317 SOC_SINGLE_EXT("WSA_SPKR_VI_1", SND_SOC_NOPM, WSA_MACRO_TX0, 1, 0,
2318 wsa_macro_vi_feed_mixer_get,
2319 wsa_macro_vi_feed_mixer_put),
2320 SOC_SINGLE_EXT("WSA_SPKR_VI_2", SND_SOC_NOPM, WSA_MACRO_TX1, 1, 0,
2321 wsa_macro_vi_feed_mixer_get,
2322 wsa_macro_vi_feed_mixer_put),
2323};
2324
2325static const struct snd_soc_dapm_widget wsa_macro_dapm_widgets[] = {
2326 SND_SOC_DAPM_AIF_IN("WSA AIF1 PB", "WSA_AIF1 Playback", 0,
2327 SND_SOC_NOPM, 0, 0),
2328
2329 SND_SOC_DAPM_AIF_IN("WSA AIF_MIX1 PB", "WSA_AIF_MIX1 Playback", 0,
2330 SND_SOC_NOPM, 0, 0),
2331
2332 SND_SOC_DAPM_AIF_OUT_E("WSA AIF_VI", "WSA_AIF_VI Capture", 0,
2333 SND_SOC_NOPM, WSA_MACRO_AIF_VI, 0,
2334 wsa_macro_enable_vi_feedback,
2335 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
2336
2337 SND_SOC_DAPM_AIF_OUT("WSA AIF_ECHO", "WSA_AIF_ECHO Capture", 0,
2338 SND_SOC_NOPM, 0, 0),
2339
2340 SND_SOC_DAPM_MIXER("WSA_AIF_VI Mixer", SND_SOC_NOPM, WSA_MACRO_AIF_VI,
2341 0, aif_vi_mixer, ARRAY_SIZE(aif_vi_mixer)),
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05302342 SND_SOC_DAPM_MUX_E("WSA RX_MIX EC0_MUX", SND_SOC_NOPM,
2343 WSA_MACRO_EC0_MUX, 0,
2344 &rx_mix_ec0_mux, wsa_macro_enable_echo,
2345 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2346 SND_SOC_DAPM_MUX_E("WSA RX_MIX EC1_MUX", SND_SOC_NOPM,
2347 WSA_MACRO_EC1_MUX, 0,
2348 &rx_mix_ec1_mux, wsa_macro_enable_echo,
2349 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302350
2351 SND_SOC_DAPM_MUX("WSA RX0 MUX", SND_SOC_NOPM, WSA_MACRO_RX0, 0,
2352 &rx_mux[WSA_MACRO_RX0]),
2353 SND_SOC_DAPM_MUX("WSA RX1 MUX", SND_SOC_NOPM, WSA_MACRO_RX1, 0,
2354 &rx_mux[WSA_MACRO_RX1]),
2355 SND_SOC_DAPM_MUX("WSA RX_MIX0 MUX", SND_SOC_NOPM, WSA_MACRO_RX_MIX0, 0,
2356 &rx_mux[WSA_MACRO_RX_MIX0]),
2357 SND_SOC_DAPM_MUX("WSA RX_MIX1 MUX", SND_SOC_NOPM, WSA_MACRO_RX_MIX1, 0,
2358 &rx_mux[WSA_MACRO_RX_MIX1]),
2359
2360 SND_SOC_DAPM_MIXER("WSA RX0", SND_SOC_NOPM, 0, 0, NULL, 0),
2361 SND_SOC_DAPM_MIXER("WSA RX1", SND_SOC_NOPM, 0, 0, NULL, 0),
2362 SND_SOC_DAPM_MIXER("WSA RX_MIX0", SND_SOC_NOPM, 0, 0, NULL, 0),
2363 SND_SOC_DAPM_MIXER("WSA RX_MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
2364
2365 SND_SOC_DAPM_MUX_E("WSA_RX0 INP0", SND_SOC_NOPM, 0, 0,
2366 &rx0_prim_inp0_mux, wsa_macro_enable_swr,
2367 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2368 SND_SOC_DAPM_MUX_E("WSA_RX0 INP1", SND_SOC_NOPM, 0, 0,
2369 &rx0_prim_inp1_mux, wsa_macro_enable_swr,
2370 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2371 SND_SOC_DAPM_MUX_E("WSA_RX0 INP2", SND_SOC_NOPM, 0, 0,
2372 &rx0_prim_inp2_mux, wsa_macro_enable_swr,
2373 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2374 SND_SOC_DAPM_MUX_E("WSA_RX0 MIX INP", SND_SOC_NOPM, 0, 0,
2375 &rx0_mix_mux, wsa_macro_enable_mix_path,
2376 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2377 SND_SOC_DAPM_MUX_E("WSA_RX1 INP0", SND_SOC_NOPM, 0, 0,
2378 &rx1_prim_inp0_mux, wsa_macro_enable_swr,
2379 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2380 SND_SOC_DAPM_MUX_E("WSA_RX1 INP1", SND_SOC_NOPM, 0, 0,
2381 &rx1_prim_inp1_mux, wsa_macro_enable_swr,
2382 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2383 SND_SOC_DAPM_MUX_E("WSA_RX1 INP2", SND_SOC_NOPM, 0, 0,
2384 &rx1_prim_inp2_mux, wsa_macro_enable_swr,
2385 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2386 SND_SOC_DAPM_MUX_E("WSA_RX1 MIX INP", SND_SOC_NOPM, 0, 0,
2387 &rx1_mix_mux, wsa_macro_enable_mix_path,
2388 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2389 SND_SOC_DAPM_MIXER("WSA_RX INT0 MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
2390 SND_SOC_DAPM_MIXER("WSA_RX INT1 MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
2391 SND_SOC_DAPM_MIXER("WSA_RX INT0 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
2392 SND_SOC_DAPM_MIXER("WSA_RX INT1 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
2393
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302394 SND_SOC_DAPM_MUX_E("WSA_RX0 INT0 SIDETONE MIX",
2395 BOLERO_CDC_WSA_RX0_RX_PATH_CFG1, 4, 0,
2396 &rx0_sidetone_mix_mux, wsa_macro_enable_swr,
2397 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2398 SND_SOC_DAPM_INPUT("WSA SRC0_INP"),
2399
2400 SND_SOC_DAPM_INPUT("WSA_TX DEC0_INP"),
2401 SND_SOC_DAPM_INPUT("WSA_TX DEC1_INP"),
2402
Laxminath Kasam243e2752018-04-12 00:40:19 +05302403 SND_SOC_DAPM_MIXER_E("WSA_RX INT0 INTERP", SND_SOC_NOPM,
2404 WSA_MACRO_COMP1, 0, NULL, 0, wsa_macro_enable_interpolator,
2405 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2406 SND_SOC_DAPM_POST_PMD),
2407 SND_SOC_DAPM_MIXER_E("WSA_RX INT1 INTERP", SND_SOC_NOPM,
2408 WSA_MACRO_COMP2, 0, NULL, 0, wsa_macro_enable_interpolator,
2409 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2410 SND_SOC_DAPM_POST_PMD),
2411
2412 SND_SOC_DAPM_MIXER_E("WSA_RX INT0 CHAIN", SND_SOC_NOPM, 0, 0,
2413 NULL, 0, wsa_macro_spk_boost_event,
Laxminath Kasam0c857002018-07-17 23:47:17 +05302414 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2415 SND_SOC_DAPM_POST_PMD),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302416 SND_SOC_DAPM_MIXER_E("WSA_RX INT1 CHAIN", SND_SOC_NOPM, 0, 0,
2417 NULL, 0, wsa_macro_spk_boost_event,
Laxminath Kasam0c857002018-07-17 23:47:17 +05302418 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2419 SND_SOC_DAPM_POST_PMD),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302420
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302421 SND_SOC_DAPM_MIXER_E("WSA_RX INT0 VBAT", SND_SOC_NOPM,
2422 0, 0, wsa_int0_vbat_mix_switch,
2423 ARRAY_SIZE(wsa_int0_vbat_mix_switch),
2424 wsa_macro_enable_vbat,
2425 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2426 SND_SOC_DAPM_MIXER_E("WSA_RX INT1 VBAT", SND_SOC_NOPM,
2427 0, 0, wsa_int1_vbat_mix_switch,
2428 ARRAY_SIZE(wsa_int1_vbat_mix_switch),
2429 wsa_macro_enable_vbat,
2430 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2431
Laxminath Kasam243e2752018-04-12 00:40:19 +05302432 SND_SOC_DAPM_INPUT("VIINPUT_WSA"),
2433
2434 SND_SOC_DAPM_OUTPUT("WSA_SPK1 OUT"),
2435 SND_SOC_DAPM_OUTPUT("WSA_SPK2 OUT"),
2436
2437 SND_SOC_DAPM_SUPPLY_S("WSA_MCLK", 0, SND_SOC_NOPM, 0, 0,
2438 wsa_macro_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2439};
2440
2441static const struct snd_soc_dapm_route wsa_audio_map[] = {
2442 /* VI Feedback */
2443 {"WSA_AIF_VI Mixer", "WSA_SPKR_VI_1", "VIINPUT_WSA"},
2444 {"WSA_AIF_VI Mixer", "WSA_SPKR_VI_2", "VIINPUT_WSA"},
2445 {"WSA AIF_VI", NULL, "WSA_AIF_VI Mixer"},
2446 {"WSA AIF_VI", NULL, "WSA_MCLK"},
2447
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05302448 {"WSA RX_MIX EC0_MUX", "RX_MIX_TX0", "WSA_RX INT0 SEC MIX"},
2449 {"WSA RX_MIX EC1_MUX", "RX_MIX_TX0", "WSA_RX INT0 SEC MIX"},
2450 {"WSA RX_MIX EC0_MUX", "RX_MIX_TX1", "WSA_RX INT1 SEC MIX"},
2451 {"WSA RX_MIX EC1_MUX", "RX_MIX_TX1", "WSA_RX INT1 SEC MIX"},
2452 {"WSA AIF_ECHO", NULL, "WSA RX_MIX EC0_MUX"},
2453 {"WSA AIF_ECHO", NULL, "WSA RX_MIX EC1_MUX"},
2454 {"WSA AIF_ECHO", NULL, "WSA_MCLK"},
2455
Laxminath Kasam243e2752018-04-12 00:40:19 +05302456 {"WSA AIF1 PB", NULL, "WSA_MCLK"},
2457 {"WSA AIF_MIX1 PB", NULL, "WSA_MCLK"},
2458
2459 {"WSA RX0 MUX", "AIF1_PB", "WSA AIF1 PB"},
2460 {"WSA RX1 MUX", "AIF1_PB", "WSA AIF1 PB"},
2461 {"WSA RX_MIX0 MUX", "AIF1_PB", "WSA AIF1 PB"},
2462 {"WSA RX_MIX1 MUX", "AIF1_PB", "WSA AIF1 PB"},
2463
2464 {"WSA RX0 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
2465 {"WSA RX1 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
2466 {"WSA RX_MIX0 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
2467 {"WSA RX_MIX1 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
2468
2469 {"WSA RX0", NULL, "WSA RX0 MUX"},
2470 {"WSA RX1", NULL, "WSA RX1 MUX"},
2471 {"WSA RX_MIX0", NULL, "WSA RX_MIX0 MUX"},
2472 {"WSA RX_MIX1", NULL, "WSA RX_MIX1 MUX"},
2473
2474 {"WSA_RX0 INP0", "RX0", "WSA RX0"},
2475 {"WSA_RX0 INP0", "RX1", "WSA RX1"},
2476 {"WSA_RX0 INP0", "RX_MIX0", "WSA RX_MIX0"},
2477 {"WSA_RX0 INP0", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302478 {"WSA_RX0 INP0", "DEC0", "WSA_TX DEC0_INP"},
2479 {"WSA_RX0 INP0", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302480 {"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP0"},
2481
2482 {"WSA_RX0 INP1", "RX0", "WSA RX0"},
2483 {"WSA_RX0 INP1", "RX1", "WSA RX1"},
2484 {"WSA_RX0 INP1", "RX_MIX0", "WSA RX_MIX0"},
2485 {"WSA_RX0 INP1", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302486 {"WSA_RX0 INP1", "DEC0", "WSA_TX DEC0_INP"},
2487 {"WSA_RX0 INP1", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302488 {"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP1"},
2489
2490 {"WSA_RX0 INP2", "RX0", "WSA RX0"},
2491 {"WSA_RX0 INP2", "RX1", "WSA RX1"},
2492 {"WSA_RX0 INP2", "RX_MIX0", "WSA RX_MIX0"},
2493 {"WSA_RX0 INP2", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302494 {"WSA_RX0 INP2", "DEC0", "WSA_TX DEC0_INP"},
2495 {"WSA_RX0 INP2", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302496 {"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP2"},
2497
2498 {"WSA_RX0 MIX INP", "RX0", "WSA RX0"},
2499 {"WSA_RX0 MIX INP", "RX1", "WSA RX1"},
2500 {"WSA_RX0 MIX INP", "RX_MIX0", "WSA RX_MIX0"},
2501 {"WSA_RX0 MIX INP", "RX_MIX1", "WSA RX_MIX1"},
2502 {"WSA_RX INT0 SEC MIX", NULL, "WSA_RX0 MIX INP"},
2503
2504 {"WSA_RX INT0 SEC MIX", NULL, "WSA_RX INT0 MIX"},
2505 {"WSA_RX INT0 INTERP", NULL, "WSA_RX INT0 SEC MIX"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302506 {"WSA_RX0 INT0 SIDETONE MIX", "SRC0", "WSA SRC0_INP"},
2507 {"WSA_RX INT0 INTERP", NULL, "WSA_RX0 INT0 SIDETONE MIX"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302508 {"WSA_RX INT0 CHAIN", NULL, "WSA_RX INT0 INTERP"},
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302509
2510 {"WSA_RX INT0 VBAT", "WSA RX0 VBAT Enable", "WSA_RX INT0 INTERP"},
2511 {"WSA_RX INT0 CHAIN", NULL, "WSA_RX INT0 VBAT"},
2512
Laxminath Kasam243e2752018-04-12 00:40:19 +05302513 {"WSA_SPK1 OUT", NULL, "WSA_RX INT0 CHAIN"},
Laxminath Kasamfc281ad2018-08-06 20:19:40 +05302514 {"WSA_SPK1 OUT", NULL, "WSA_MCLK"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302515
2516 {"WSA_RX1 INP0", "RX0", "WSA RX0"},
2517 {"WSA_RX1 INP0", "RX1", "WSA RX1"},
2518 {"WSA_RX1 INP0", "RX_MIX0", "WSA RX_MIX0"},
2519 {"WSA_RX1 INP0", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302520 {"WSA_RX1 INP0", "DEC0", "WSA_TX DEC0_INP"},
2521 {"WSA_RX1 INP0", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302522 {"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP0"},
2523
2524 {"WSA_RX1 INP1", "RX0", "WSA RX0"},
2525 {"WSA_RX1 INP1", "RX1", "WSA RX1"},
2526 {"WSA_RX1 INP1", "RX_MIX0", "WSA RX_MIX0"},
2527 {"WSA_RX1 INP1", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302528 {"WSA_RX1 INP1", "DEC0", "WSA_TX DEC0_INP"},
2529 {"WSA_RX1 INP1", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302530 {"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP1"},
2531
2532 {"WSA_RX1 INP2", "RX0", "WSA RX0"},
2533 {"WSA_RX1 INP2", "RX1", "WSA RX1"},
2534 {"WSA_RX1 INP2", "RX_MIX0", "WSA RX_MIX0"},
2535 {"WSA_RX1 INP2", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302536 {"WSA_RX1 INP2", "DEC0", "WSA_TX DEC0_INP"},
2537 {"WSA_RX1 INP2", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302538 {"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP2"},
2539
2540 {"WSA_RX1 MIX INP", "RX0", "WSA RX0"},
2541 {"WSA_RX1 MIX INP", "RX1", "WSA RX1"},
2542 {"WSA_RX1 MIX INP", "RX_MIX0", "WSA RX_MIX0"},
2543 {"WSA_RX1 MIX INP", "RX_MIX1", "WSA RX_MIX1"},
2544 {"WSA_RX INT1 SEC MIX", NULL, "WSA_RX1 MIX INP"},
2545
2546 {"WSA_RX INT1 SEC MIX", NULL, "WSA_RX INT1 MIX"},
2547 {"WSA_RX INT1 INTERP", NULL, "WSA_RX INT1 SEC MIX"},
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302548
2549 {"WSA_RX INT1 VBAT", "WSA RX1 VBAT Enable", "WSA_RX INT1 INTERP"},
2550 {"WSA_RX INT1 CHAIN", NULL, "WSA_RX INT1 VBAT"},
2551
Laxminath Kasam243e2752018-04-12 00:40:19 +05302552 {"WSA_RX INT1 CHAIN", NULL, "WSA_RX INT1 INTERP"},
2553 {"WSA_SPK2 OUT", NULL, "WSA_RX INT1 CHAIN"},
Laxminath Kasamfc281ad2018-08-06 20:19:40 +05302554 {"WSA_SPK2 OUT", NULL, "WSA_MCLK"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302555};
2556
2557static const struct wsa_macro_reg_mask_val wsa_macro_reg_init[] = {
2558 {BOLERO_CDC_WSA_BOOST0_BOOST_CFG1, 0x3F, 0x12},
2559 {BOLERO_CDC_WSA_BOOST0_BOOST_CFG2, 0x1C, 0x08},
2560 {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x1E, 0x18},
2561 {BOLERO_CDC_WSA_BOOST1_BOOST_CFG1, 0x3F, 0x12},
2562 {BOLERO_CDC_WSA_BOOST1_BOOST_CFG2, 0x1C, 0x08},
2563 {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x1E, 0x18},
2564 {BOLERO_CDC_WSA_BOOST0_BOOST_CTL, 0x70, 0x58},
2565 {BOLERO_CDC_WSA_BOOST1_BOOST_CTL, 0x70, 0x58},
2566 {BOLERO_CDC_WSA_RX0_RX_PATH_CFG1, 0x08, 0x08},
2567 {BOLERO_CDC_WSA_RX1_RX_PATH_CFG1, 0x08, 0x08},
2568 {BOLERO_CDC_WSA_TOP_TOP_CFG1, 0x02, 0x02},
2569 {BOLERO_CDC_WSA_TOP_TOP_CFG1, 0x01, 0x01},
2570 {BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
2571 {BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
2572 {BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
2573 {BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
2574 {BOLERO_CDC_WSA_COMPANDER0_CTL3, 0x80, 0x80},
2575 {BOLERO_CDC_WSA_COMPANDER1_CTL3, 0x80, 0x80},
2576 {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x01, 0x01},
2577 {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x01, 0x01},
2578 {BOLERO_CDC_WSA_RX0_RX_PATH_CFG0, 0x01, 0x01},
2579 {BOLERO_CDC_WSA_RX1_RX_PATH_CFG0, 0x01, 0x01},
2580 {BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CFG, 0x01, 0x01},
2581 {BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CFG, 0x01, 0x01},
2582};
2583
Meng Wang15c825d2018-09-06 10:49:18 +08002584static void wsa_macro_init_bcl_pmic_reg(struct snd_soc_component *component)
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302585{
2586 struct device *wsa_dev = NULL;
2587 struct wsa_macro_priv *wsa_priv = NULL;
2588
Meng Wang15c825d2018-09-06 10:49:18 +08002589 if (!component) {
2590 pr_err("%s: NULL component pointer!\n", __func__);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302591 return;
2592 }
2593
Meng Wang15c825d2018-09-06 10:49:18 +08002594 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302595 return;
2596
2597 switch (wsa_priv->bcl_pmic_params.id) {
2598 case 0:
2599 /* Enable ID0 to listen to respective PMIC group interrupts */
Meng Wang15c825d2018-09-06 10:49:18 +08002600 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302601 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CTL1, 0x02, 0x02);
2602 /* Update MC_SID0 */
Meng Wang15c825d2018-09-06 10:49:18 +08002603 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302604 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG1, 0x0F,
2605 wsa_priv->bcl_pmic_params.sid);
2606 /* Update MC_PPID0 */
Meng Wang15c825d2018-09-06 10:49:18 +08002607 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302608 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG2, 0xFF,
2609 wsa_priv->bcl_pmic_params.ppid);
2610 break;
2611 case 1:
2612 /* Enable ID1 to listen to respective PMIC group interrupts */
Meng Wang15c825d2018-09-06 10:49:18 +08002613 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302614 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CTL1, 0x01, 0x01);
2615 /* Update MC_SID1 */
Meng Wang15c825d2018-09-06 10:49:18 +08002616 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302617 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG3, 0x0F,
2618 wsa_priv->bcl_pmic_params.sid);
2619 /* Update MC_PPID1 */
Meng Wang15c825d2018-09-06 10:49:18 +08002620 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302621 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG4, 0xFF,
2622 wsa_priv->bcl_pmic_params.ppid);
2623 break;
2624 default:
2625 dev_err(wsa_dev, "%s: PMIC ID is invalid %d\n",
2626 __func__, wsa_priv->bcl_pmic_params.id);
2627 break;
2628 }
2629}
2630
Meng Wang15c825d2018-09-06 10:49:18 +08002631static void wsa_macro_init_reg(struct snd_soc_component *component)
Laxminath Kasam243e2752018-04-12 00:40:19 +05302632{
2633 int i;
2634
2635 for (i = 0; i < ARRAY_SIZE(wsa_macro_reg_init); i++)
Meng Wang15c825d2018-09-06 10:49:18 +08002636 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302637 wsa_macro_reg_init[i].reg,
2638 wsa_macro_reg_init[i].mask,
2639 wsa_macro_reg_init[i].val);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302640
Meng Wang15c825d2018-09-06 10:49:18 +08002641 wsa_macro_init_bcl_pmic_reg(component);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302642}
2643
2644static int wsa_swrm_clock(void *handle, bool enable)
2645{
2646 struct wsa_macro_priv *wsa_priv = (struct wsa_macro_priv *) handle;
2647 struct regmap *regmap = dev_get_regmap(wsa_priv->dev->parent, NULL);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302648 int ret = 0;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302649
Tanya Dixitab8eba82018-10-05 15:07:37 +05302650 if (regmap == NULL) {
2651 dev_err(wsa_priv->dev, "%s: regmap is NULL\n", __func__);
2652 return -EINVAL;
2653 }
2654
Laxminath Kasam243e2752018-04-12 00:40:19 +05302655 mutex_lock(&wsa_priv->swr_clk_lock);
2656
2657 dev_dbg(wsa_priv->dev, "%s: swrm clock %s\n",
2658 __func__, (enable ? "enable" : "disable"));
2659 if (enable) {
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302660 pm_runtime_get_sync(wsa_priv->dev);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302661 if (wsa_priv->swr_clk_users == 0) {
Karthikeyan Mani01f1ba42019-02-26 18:48:15 -08002662 msm_cdc_pinctrl_select_active_state(
2663 wsa_priv->wsa_swr_gpio_p);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302664 ret = wsa_macro_mclk_enable(wsa_priv, 1, true);
2665 if (ret < 0) {
Karthikeyan Mani01f1ba42019-02-26 18:48:15 -08002666 msm_cdc_pinctrl_select_sleep_state(
2667 wsa_priv->wsa_swr_gpio_p);
Ramprasad Katkam14efed62019-03-07 13:16:50 +05302668 dev_err_ratelimited(wsa_priv->dev,
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302669 "%s: wsa request clock enable failed\n",
2670 __func__);
2671 goto exit;
2672 }
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05302673 if (wsa_priv->reset_swr)
2674 regmap_update_bits(regmap,
2675 BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
2676 0x02, 0x02);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302677 regmap_update_bits(regmap,
2678 BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
2679 0x01, 0x01);
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05302680 if (wsa_priv->reset_swr)
2681 regmap_update_bits(regmap,
2682 BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
2683 0x02, 0x00);
2684 wsa_priv->reset_swr = false;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302685 }
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302686 pm_runtime_mark_last_busy(wsa_priv->dev);
2687 pm_runtime_put_autosuspend(wsa_priv->dev);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302688 wsa_priv->swr_clk_users++;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302689 } else {
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302690 if (wsa_priv->swr_clk_users <= 0) {
2691 dev_err(wsa_priv->dev, "%s: clock already disabled\n",
2692 __func__);
2693 wsa_priv->swr_clk_users = 0;
2694 goto exit;
2695 }
Laxminath Kasam243e2752018-04-12 00:40:19 +05302696 wsa_priv->swr_clk_users--;
2697 if (wsa_priv->swr_clk_users == 0) {
2698 regmap_update_bits(regmap,
2699 BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
2700 0x01, 0x00);
Karthikeyan Mani01f1ba42019-02-26 18:48:15 -08002701 wsa_macro_mclk_enable(wsa_priv, 0, true);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302702 msm_cdc_pinctrl_select_sleep_state(
2703 wsa_priv->wsa_swr_gpio_p);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302704 }
2705 }
2706 dev_dbg(wsa_priv->dev, "%s: swrm clock users %d\n",
2707 __func__, wsa_priv->swr_clk_users);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302708exit:
Laxminath Kasam243e2752018-04-12 00:40:19 +05302709 mutex_unlock(&wsa_priv->swr_clk_lock);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302710 return ret;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302711}
2712
Meng Wang15c825d2018-09-06 10:49:18 +08002713static int wsa_macro_init(struct snd_soc_component *component)
Laxminath Kasam243e2752018-04-12 00:40:19 +05302714{
Meng Wang15c825d2018-09-06 10:49:18 +08002715 struct snd_soc_dapm_context *dapm =
2716 snd_soc_component_get_dapm(component);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302717 int ret;
2718 struct device *wsa_dev = NULL;
2719 struct wsa_macro_priv *wsa_priv = NULL;
2720
Meng Wang15c825d2018-09-06 10:49:18 +08002721 wsa_dev = bolero_get_device_ptr(component->dev, WSA_MACRO);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302722 if (!wsa_dev) {
Meng Wang15c825d2018-09-06 10:49:18 +08002723 dev_err(component->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302724 "%s: null device for macro!\n", __func__);
2725 return -EINVAL;
2726 }
2727 wsa_priv = dev_get_drvdata(wsa_dev);
2728 if (!wsa_priv) {
Meng Wang15c825d2018-09-06 10:49:18 +08002729 dev_err(component->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302730 "%s: priv is null for macro!\n", __func__);
2731 return -EINVAL;
2732 }
2733
2734 ret = snd_soc_dapm_new_controls(dapm, wsa_macro_dapm_widgets,
2735 ARRAY_SIZE(wsa_macro_dapm_widgets));
2736 if (ret < 0) {
2737 dev_err(wsa_dev, "%s: Failed to add controls\n", __func__);
2738 return ret;
2739 }
2740
2741 ret = snd_soc_dapm_add_routes(dapm, wsa_audio_map,
2742 ARRAY_SIZE(wsa_audio_map));
2743 if (ret < 0) {
2744 dev_err(wsa_dev, "%s: Failed to add routes\n", __func__);
2745 return ret;
2746 }
2747
2748 ret = snd_soc_dapm_new_widgets(dapm->card);
2749 if (ret < 0) {
2750 dev_err(wsa_dev, "%s: Failed to add widgets\n", __func__);
2751 return ret;
2752 }
2753
Meng Wang15c825d2018-09-06 10:49:18 +08002754 ret = snd_soc_add_component_controls(component, wsa_macro_snd_controls,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302755 ARRAY_SIZE(wsa_macro_snd_controls));
2756 if (ret < 0) {
2757 dev_err(wsa_dev, "%s: Failed to add snd_ctls\n", __func__);
2758 return ret;
2759 }
Laxminath Kasam638b5602018-09-24 13:19:52 +05302760 snd_soc_dapm_ignore_suspend(dapm, "WSA_AIF1 Playback");
2761 snd_soc_dapm_ignore_suspend(dapm, "WSA_AIF_MIX1 Playback");
2762 snd_soc_dapm_ignore_suspend(dapm, "WSA_AIF_VI Capture");
2763 snd_soc_dapm_ignore_suspend(dapm, "WSA_AIF_ECHO Capture");
2764 snd_soc_dapm_ignore_suspend(dapm, "WSA_SPK1 OUT");
2765 snd_soc_dapm_ignore_suspend(dapm, "WSA_SPK2 OUT");
2766 snd_soc_dapm_ignore_suspend(dapm, "VIINPUT_WSA");
2767 snd_soc_dapm_ignore_suspend(dapm, "WSA SRC0_INP");
2768 snd_soc_dapm_ignore_suspend(dapm, "WSA_TX DEC0_INP");
2769 snd_soc_dapm_ignore_suspend(dapm, "WSA_TX DEC1_INP");
2770 snd_soc_dapm_sync(dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302771
Meng Wang15c825d2018-09-06 10:49:18 +08002772 wsa_priv->component = component;
Laxminath Kasam21c8b222018-06-21 18:47:22 +05302773 wsa_priv->spkr_gain_offset = WSA_MACRO_GAIN_OFFSET_0_DB;
Meng Wang15c825d2018-09-06 10:49:18 +08002774 wsa_macro_init_reg(component);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302775
2776 return 0;
2777}
2778
Meng Wang15c825d2018-09-06 10:49:18 +08002779static int wsa_macro_deinit(struct snd_soc_component *component)
Laxminath Kasam243e2752018-04-12 00:40:19 +05302780{
2781 struct device *wsa_dev = NULL;
2782 struct wsa_macro_priv *wsa_priv = NULL;
2783
Meng Wang15c825d2018-09-06 10:49:18 +08002784 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302785 return -EINVAL;
2786
Meng Wang15c825d2018-09-06 10:49:18 +08002787 wsa_priv->component = NULL;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302788
2789 return 0;
2790}
2791
2792static void wsa_macro_add_child_devices(struct work_struct *work)
2793{
2794 struct wsa_macro_priv *wsa_priv;
2795 struct platform_device *pdev;
2796 struct device_node *node;
2797 struct wsa_macro_swr_ctrl_data *swr_ctrl_data = NULL, *temp;
2798 int ret;
2799 u16 count = 0, ctrl_num = 0;
2800 struct wsa_macro_swr_ctrl_platform_data *platdata;
2801 char plat_dev_name[WSA_MACRO_SWR_STRING_LEN];
2802
2803 wsa_priv = container_of(work, struct wsa_macro_priv,
2804 wsa_macro_add_child_devices_work);
2805 if (!wsa_priv) {
2806 pr_err("%s: Memory for wsa_priv does not exist\n",
2807 __func__);
2808 return;
2809 }
Laxminath Kasam21c8b222018-06-21 18:47:22 +05302810 if (!wsa_priv->dev || !wsa_priv->dev->of_node) {
Laxminath Kasam243e2752018-04-12 00:40:19 +05302811 dev_err(wsa_priv->dev,
2812 "%s: DT node for wsa_priv does not exist\n", __func__);
2813 return;
2814 }
2815
2816 platdata = &wsa_priv->swr_plat_data;
2817 wsa_priv->child_count = 0;
2818
2819 for_each_available_child_of_node(wsa_priv->dev->of_node, node) {
2820 if (strnstr(node->name, "wsa_swr_master",
2821 strlen("wsa_swr_master")) != NULL)
2822 strlcpy(plat_dev_name, "wsa_swr_ctrl",
2823 (WSA_MACRO_SWR_STRING_LEN - 1));
2824 else if (strnstr(node->name, "msm_cdc_pinctrl",
2825 strlen("msm_cdc_pinctrl")) != NULL)
2826 strlcpy(plat_dev_name, node->name,
2827 (WSA_MACRO_SWR_STRING_LEN - 1));
2828 else
2829 continue;
2830
2831 pdev = platform_device_alloc(plat_dev_name, -1);
2832 if (!pdev) {
2833 dev_err(wsa_priv->dev, "%s: pdev memory alloc failed\n",
2834 __func__);
2835 ret = -ENOMEM;
2836 goto err;
2837 }
2838 pdev->dev.parent = wsa_priv->dev;
2839 pdev->dev.of_node = node;
2840
2841 if (strnstr(node->name, "wsa_swr_master",
2842 strlen("wsa_swr_master")) != NULL) {
2843 ret = platform_device_add_data(pdev, platdata,
2844 sizeof(*platdata));
2845 if (ret) {
2846 dev_err(&pdev->dev,
2847 "%s: cannot add plat data ctrl:%d\n",
2848 __func__, ctrl_num);
2849 goto fail_pdev_add;
2850 }
2851 }
2852
2853 ret = platform_device_add(pdev);
2854 if (ret) {
2855 dev_err(&pdev->dev,
2856 "%s: Cannot add platform device\n",
2857 __func__);
2858 goto fail_pdev_add;
2859 }
2860
2861 if (!strcmp(node->name, "wsa_swr_master")) {
2862 temp = krealloc(swr_ctrl_data,
2863 (ctrl_num + 1) * sizeof(
2864 struct wsa_macro_swr_ctrl_data),
2865 GFP_KERNEL);
2866 if (!temp) {
2867 dev_err(&pdev->dev, "out of memory\n");
2868 ret = -ENOMEM;
2869 goto err;
2870 }
2871 swr_ctrl_data = temp;
2872 swr_ctrl_data[ctrl_num].wsa_swr_pdev = pdev;
2873 ctrl_num++;
2874 dev_dbg(&pdev->dev,
2875 "%s: Added soundwire ctrl device(s)\n",
2876 __func__);
2877 wsa_priv->swr_ctrl_data = swr_ctrl_data;
2878 }
2879 if (wsa_priv->child_count < WSA_MACRO_CHILD_DEVICES_MAX)
2880 wsa_priv->pdev_child_devices[
2881 wsa_priv->child_count++] = pdev;
2882 else
2883 goto err;
2884 }
2885
2886 return;
2887fail_pdev_add:
2888 for (count = 0; count < wsa_priv->child_count; count++)
2889 platform_device_put(wsa_priv->pdev_child_devices[count]);
2890err:
2891 return;
2892}
2893
2894static void wsa_macro_init_ops(struct macro_ops *ops,
2895 char __iomem *wsa_io_base)
2896{
2897 memset(ops, 0, sizeof(struct macro_ops));
2898 ops->init = wsa_macro_init;
2899 ops->exit = wsa_macro_deinit;
2900 ops->io_base = wsa_io_base;
2901 ops->dai_ptr = wsa_macro_dai;
2902 ops->num_dais = ARRAY_SIZE(wsa_macro_dai);
Laxminath Kasamfb0d6832018-09-22 01:49:52 +05302903 ops->event_handler = wsa_macro_event_handler;
Sudheer Papothia3e969d2018-10-27 06:22:10 +05302904 ops->set_port_map = wsa_macro_set_port_map;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302905}
2906
2907static int wsa_macro_probe(struct platform_device *pdev)
2908{
2909 struct macro_ops ops;
2910 struct wsa_macro_priv *wsa_priv;
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07002911 u32 wsa_base_addr, default_clk_id;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302912 char __iomem *wsa_io_base;
2913 int ret = 0;
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302914 u8 bcl_pmic_params[3];
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07002915 u32 is_used_wsa_swr_gpio = 1;
2916 const char *is_used_wsa_swr_gpio_dt = "qcom,is-used-swr-gpio";
Laxminath Kasam243e2752018-04-12 00:40:19 +05302917
2918 wsa_priv = devm_kzalloc(&pdev->dev, sizeof(struct wsa_macro_priv),
2919 GFP_KERNEL);
2920 if (!wsa_priv)
2921 return -ENOMEM;
2922
2923 wsa_priv->dev = &pdev->dev;
2924 ret = of_property_read_u32(pdev->dev.of_node, "reg",
2925 &wsa_base_addr);
2926 if (ret) {
2927 dev_err(&pdev->dev, "%s: could not find %s entry in dt\n",
2928 __func__, "reg");
2929 return ret;
2930 }
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07002931 if (of_find_property(pdev->dev.of_node, is_used_wsa_swr_gpio_dt,
2932 NULL)) {
2933 ret = of_property_read_u32(pdev->dev.of_node,
2934 is_used_wsa_swr_gpio_dt,
2935 &is_used_wsa_swr_gpio);
2936 if (ret) {
2937 dev_err(&pdev->dev, "%s: error reading %s in dt\n",
2938 __func__, is_used_wsa_swr_gpio_dt);
2939 is_used_wsa_swr_gpio = 1;
2940 }
2941 }
Laxminath Kasam243e2752018-04-12 00:40:19 +05302942 wsa_priv->wsa_swr_gpio_p = of_parse_phandle(pdev->dev.of_node,
2943 "qcom,wsa-swr-gpios", 0);
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07002944 if (!wsa_priv->wsa_swr_gpio_p && is_used_wsa_swr_gpio) {
Laxminath Kasam243e2752018-04-12 00:40:19 +05302945 dev_err(&pdev->dev, "%s: swr_gpios handle not provided!\n",
2946 __func__);
2947 return -EINVAL;
2948 }
Karthikeyan Mani326536d2019-06-03 13:29:43 -07002949 if (msm_cdc_pinctrl_get_state(wsa_priv->wsa_swr_gpio_p) < 0) {
2950 dev_err(&pdev->dev, "%s: failed to get swr pin state\n",
2951 __func__);
2952 return -EPROBE_DEFER;
2953 }
2954
Laxminath Kasam243e2752018-04-12 00:40:19 +05302955 wsa_io_base = devm_ioremap(&pdev->dev,
2956 wsa_base_addr, WSA_MACRO_MAX_OFFSET);
2957 if (!wsa_io_base) {
2958 dev_err(&pdev->dev, "%s: ioremap failed\n", __func__);
2959 return -EINVAL;
2960 }
2961 wsa_priv->wsa_io_base = wsa_io_base;
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05302962 wsa_priv->reset_swr = true;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302963 INIT_WORK(&wsa_priv->wsa_macro_add_child_devices_work,
2964 wsa_macro_add_child_devices);
2965 wsa_priv->swr_plat_data.handle = (void *) wsa_priv;
2966 wsa_priv->swr_plat_data.read = NULL;
2967 wsa_priv->swr_plat_data.write = NULL;
2968 wsa_priv->swr_plat_data.bulk_write = NULL;
2969 wsa_priv->swr_plat_data.clk = wsa_swrm_clock;
2970 wsa_priv->swr_plat_data.handle_irq = NULL;
2971
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07002972 ret = of_property_read_u32(pdev->dev.of_node, "qcom,default-clk-id",
2973 &default_clk_id);
2974 if (ret) {
2975 dev_err(&pdev->dev, "%s: could not find %s entry in dt\n",
2976 __func__, "qcom,mux0-clk-id");
2977 default_clk_id = WSA_CORE_CLK;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302978 }
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302979
2980 ret = of_property_read_u8_array(pdev->dev.of_node,
2981 "qcom,wsa-bcl-pmic-params", bcl_pmic_params,
2982 sizeof(bcl_pmic_params));
2983 if (ret) {
2984 dev_dbg(&pdev->dev, "%s: could not find %s entry in dt\n",
2985 __func__, "qcom,wsa-bcl-pmic-params");
2986 } else {
2987 wsa_priv->bcl_pmic_params.id = bcl_pmic_params[0];
2988 wsa_priv->bcl_pmic_params.sid = bcl_pmic_params[1];
2989 wsa_priv->bcl_pmic_params.ppid = bcl_pmic_params[2];
2990 }
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07002991 wsa_priv->default_clk_id = default_clk_id;
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302992
Laxminath Kasam243e2752018-04-12 00:40:19 +05302993 dev_set_drvdata(&pdev->dev, wsa_priv);
2994 mutex_init(&wsa_priv->mclk_lock);
2995 mutex_init(&wsa_priv->swr_clk_lock);
2996 wsa_macro_init_ops(&ops, wsa_io_base);
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07002997 ops.clk_id_req = wsa_priv->default_clk_id;
2998 ops.default_clk_id = wsa_priv->default_clk_id;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302999 ret = bolero_register_macro(&pdev->dev, WSA_MACRO, &ops);
3000 if (ret < 0) {
3001 dev_err(&pdev->dev, "%s: register macro failed\n", __func__);
3002 goto reg_macro_fail;
3003 }
3004 schedule_work(&wsa_priv->wsa_macro_add_child_devices_work);
Sudheer Papothi7601cc62019-03-30 03:00:52 +05303005 pm_runtime_set_autosuspend_delay(&pdev->dev, AUTO_SUSPEND_DELAY);
3006 pm_runtime_use_autosuspend(&pdev->dev);
3007 pm_runtime_set_suspended(&pdev->dev);
3008 pm_runtime_enable(&pdev->dev);
3009
Laxminath Kasam243e2752018-04-12 00:40:19 +05303010 return ret;
3011reg_macro_fail:
3012 mutex_destroy(&wsa_priv->mclk_lock);
3013 mutex_destroy(&wsa_priv->swr_clk_lock);
3014 return ret;
3015}
3016
3017static int wsa_macro_remove(struct platform_device *pdev)
3018{
3019 struct wsa_macro_priv *wsa_priv;
3020 u16 count = 0;
3021
3022 wsa_priv = dev_get_drvdata(&pdev->dev);
3023
3024 if (!wsa_priv)
3025 return -EINVAL;
3026
3027 for (count = 0; count < wsa_priv->child_count &&
3028 count < WSA_MACRO_CHILD_DEVICES_MAX; count++)
3029 platform_device_unregister(wsa_priv->pdev_child_devices[count]);
3030
Sudheer Papothi7601cc62019-03-30 03:00:52 +05303031 pm_runtime_disable(&pdev->dev);
3032 pm_runtime_set_suspended(&pdev->dev);
Laxminath Kasam243e2752018-04-12 00:40:19 +05303033 bolero_unregister_macro(&pdev->dev, WSA_MACRO);
3034 mutex_destroy(&wsa_priv->mclk_lock);
3035 mutex_destroy(&wsa_priv->swr_clk_lock);
3036 return 0;
3037}
3038
3039static const struct of_device_id wsa_macro_dt_match[] = {
3040 {.compatible = "qcom,wsa-macro"},
3041 {}
3042};
3043
Sudheer Papothi7601cc62019-03-30 03:00:52 +05303044static const struct dev_pm_ops bolero_dev_pm_ops = {
3045 SET_RUNTIME_PM_OPS(
3046 bolero_runtime_suspend,
3047 bolero_runtime_resume,
3048 NULL
3049 )
3050};
3051
Laxminath Kasam243e2752018-04-12 00:40:19 +05303052static struct platform_driver wsa_macro_driver = {
3053 .driver = {
3054 .name = "wsa_macro",
3055 .owner = THIS_MODULE,
Sudheer Papothi7601cc62019-03-30 03:00:52 +05303056 .pm = &bolero_dev_pm_ops,
Laxminath Kasam243e2752018-04-12 00:40:19 +05303057 .of_match_table = wsa_macro_dt_match,
Xiaojun Sang53cd13a2018-06-29 15:14:37 +08003058 .suppress_bind_attrs = true,
Laxminath Kasam243e2752018-04-12 00:40:19 +05303059 },
3060 .probe = wsa_macro_probe,
3061 .remove = wsa_macro_remove,
3062};
3063
3064module_platform_driver(wsa_macro_driver);
3065
3066MODULE_DESCRIPTION("WSA macro driver");
3067MODULE_LICENSE("GPL v2");