blob: d1ba34620e5794c71b3ecb5d1f420a6ff5969cea [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
476 ret = swrm_wcd_notify(
477 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
478 SWR_SET_PORT_MAP, &port_cfg);
479
480 return ret;
481}
482
Laxminath Kasam243e2752018-04-12 00:40:19 +0530483/**
484 * wsa_macro_set_spkr_gain_offset - offset the speaker path
485 * gain with the given offset value.
486 *
Meng Wang15c825d2018-09-06 10:49:18 +0800487 * @component: codec instance
Laxminath Kasam243e2752018-04-12 00:40:19 +0530488 * @offset: Indicates speaker path gain offset value.
489 *
490 * Returns 0 on success or -EINVAL on error.
491 */
Meng Wang15c825d2018-09-06 10:49:18 +0800492int wsa_macro_set_spkr_gain_offset(struct snd_soc_component *component,
493 int offset)
Laxminath Kasam243e2752018-04-12 00:40:19 +0530494{
495 struct device *wsa_dev = NULL;
496 struct wsa_macro_priv *wsa_priv = NULL;
497
Meng Wang15c825d2018-09-06 10:49:18 +0800498 if (!component) {
499 pr_err("%s: NULL component pointer!\n", __func__);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530500 return -EINVAL;
501 }
502
Meng Wang15c825d2018-09-06 10:49:18 +0800503 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530504 return -EINVAL;
505
506 wsa_priv->spkr_gain_offset = offset;
507 return 0;
508}
509EXPORT_SYMBOL(wsa_macro_set_spkr_gain_offset);
510
511/**
512 * wsa_macro_set_spkr_mode - Configures speaker compander and smartboost
513 * settings based on speaker mode.
514 *
Meng Wang15c825d2018-09-06 10:49:18 +0800515 * @component: codec instance
Laxminath Kasam243e2752018-04-12 00:40:19 +0530516 * @mode: Indicates speaker configuration mode.
517 *
518 * Returns 0 on success or -EINVAL on error.
519 */
Meng Wang15c825d2018-09-06 10:49:18 +0800520int wsa_macro_set_spkr_mode(struct snd_soc_component *component, int mode)
Laxminath Kasam243e2752018-04-12 00:40:19 +0530521{
522 int i;
523 const struct wsa_macro_reg_mask_val *regs;
524 int size;
525 struct device *wsa_dev = NULL;
526 struct wsa_macro_priv *wsa_priv = NULL;
527
Meng Wang15c825d2018-09-06 10:49:18 +0800528 if (!component) {
Laxminath Kasam243e2752018-04-12 00:40:19 +0530529 pr_err("%s: NULL codec pointer!\n", __func__);
530 return -EINVAL;
531 }
532
Meng Wang15c825d2018-09-06 10:49:18 +0800533 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530534 return -EINVAL;
535
536 switch (mode) {
Laxminath Kasam21c8b222018-06-21 18:47:22 +0530537 case WSA_MACRO_SPKR_MODE_1:
Laxminath Kasam243e2752018-04-12 00:40:19 +0530538 regs = wsa_macro_spkr_mode1;
539 size = ARRAY_SIZE(wsa_macro_spkr_mode1);
540 break;
541 default:
542 regs = wsa_macro_spkr_default;
543 size = ARRAY_SIZE(wsa_macro_spkr_default);
544 break;
545 }
546
547 wsa_priv->spkr_mode = mode;
548 for (i = 0; i < size; i++)
Meng Wang15c825d2018-09-06 10:49:18 +0800549 snd_soc_component_update_bits(component, regs[i].reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530550 regs[i].mask, regs[i].val);
551 return 0;
552}
553EXPORT_SYMBOL(wsa_macro_set_spkr_mode);
554
555static int wsa_macro_set_prim_interpolator_rate(struct snd_soc_dai *dai,
556 u8 int_prim_fs_rate_reg_val,
557 u32 sample_rate)
558{
559 u8 int_1_mix1_inp;
560 u32 j, port;
561 u16 int_mux_cfg0, int_mux_cfg1;
562 u16 int_fs_reg;
563 u8 int_mux_cfg0_val, int_mux_cfg1_val;
564 u8 inp0_sel, inp1_sel, inp2_sel;
Meng Wang15c825d2018-09-06 10:49:18 +0800565 struct snd_soc_component *component = dai->component;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530566 struct device *wsa_dev = NULL;
567 struct wsa_macro_priv *wsa_priv = NULL;
568
Meng Wang15c825d2018-09-06 10:49:18 +0800569 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530570 return -EINVAL;
571
572 for_each_set_bit(port, &wsa_priv->active_ch_mask[dai->id],
573 WSA_MACRO_RX_MAX) {
574 int_1_mix1_inp = port;
575 if ((int_1_mix1_inp < WSA_MACRO_RX0) ||
576 (int_1_mix1_inp > WSA_MACRO_RX_MIX1)) {
577 dev_err(wsa_dev,
578 "%s: Invalid RX port, Dai ID is %d\n",
579 __func__, dai->id);
580 return -EINVAL;
581 }
582
583 int_mux_cfg0 = BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0;
584
585 /*
586 * Loop through all interpolator MUX inputs and find out
587 * to which interpolator input, the cdc_dma rx port
588 * is connected
589 */
590 for (j = 0; j < NUM_INTERPOLATORS; j++) {
591 int_mux_cfg1 = int_mux_cfg0 + WSA_MACRO_MUX_CFG1_OFFSET;
592
Meng Wang15c825d2018-09-06 10:49:18 +0800593 int_mux_cfg0_val = snd_soc_component_read32(component,
594 int_mux_cfg0);
595 int_mux_cfg1_val = snd_soc_component_read32(component,
596 int_mux_cfg1);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530597 inp0_sel = int_mux_cfg0_val & WSA_MACRO_MUX_INP_MASK1;
598 inp1_sel = (int_mux_cfg0_val >>
599 WSA_MACRO_MUX_INP_SHFT) &
600 WSA_MACRO_MUX_INP_MASK2;
601 inp2_sel = (int_mux_cfg1_val >>
602 WSA_MACRO_MUX_INP_SHFT) &
603 WSA_MACRO_MUX_INP_MASK2;
604 if ((inp0_sel == int_1_mix1_inp) ||
605 (inp1_sel == int_1_mix1_inp) ||
606 (inp2_sel == int_1_mix1_inp)) {
607 int_fs_reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL +
608 WSA_MACRO_RX_PATH_OFFSET * j;
609 dev_dbg(wsa_dev,
610 "%s: AIF_PB DAI(%d) connected to INT%u_1\n",
611 __func__, dai->id, j);
612 dev_dbg(wsa_dev,
613 "%s: set INT%u_1 sample rate to %u\n",
614 __func__, j, sample_rate);
615 /* sample_rate is in Hz */
Meng Wang15c825d2018-09-06 10:49:18 +0800616 snd_soc_component_update_bits(component,
617 int_fs_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530618 WSA_MACRO_FS_RATE_MASK,
619 int_prim_fs_rate_reg_val);
620 }
621 int_mux_cfg0 += WSA_MACRO_MUX_CFG_OFFSET;
622 }
623 }
624
625 return 0;
626}
627
628static int wsa_macro_set_mix_interpolator_rate(struct snd_soc_dai *dai,
629 u8 int_mix_fs_rate_reg_val,
630 u32 sample_rate)
631{
632 u8 int_2_inp;
633 u32 j, port;
634 u16 int_mux_cfg1, int_fs_reg;
635 u8 int_mux_cfg1_val;
Meng Wang15c825d2018-09-06 10:49:18 +0800636 struct snd_soc_component *component = dai->component;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530637 struct device *wsa_dev = NULL;
638 struct wsa_macro_priv *wsa_priv = NULL;
639
Meng Wang15c825d2018-09-06 10:49:18 +0800640 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530641 return -EINVAL;
642
643
644 for_each_set_bit(port, &wsa_priv->active_ch_mask[dai->id],
645 WSA_MACRO_RX_MAX) {
646 int_2_inp = port;
647 if ((int_2_inp < WSA_MACRO_RX0) ||
648 (int_2_inp > WSA_MACRO_RX_MIX1)) {
649 dev_err(wsa_dev,
650 "%s: Invalid RX port, Dai ID is %d\n",
651 __func__, dai->id);
652 return -EINVAL;
653 }
654
655 int_mux_cfg1 = BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG1;
656 for (j = 0; j < NUM_INTERPOLATORS; j++) {
Meng Wang15c825d2018-09-06 10:49:18 +0800657 int_mux_cfg1_val = snd_soc_component_read32(component,
658 int_mux_cfg1) &
Laxminath Kasam243e2752018-04-12 00:40:19 +0530659 WSA_MACRO_MUX_INP_MASK1;
660 if (int_mux_cfg1_val == int_2_inp) {
661 int_fs_reg =
662 BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL +
663 WSA_MACRO_RX_PATH_OFFSET * j;
664
665 dev_dbg(wsa_dev,
666 "%s: AIF_PB DAI(%d) connected to INT%u_2\n",
667 __func__, dai->id, j);
668 dev_dbg(wsa_dev,
669 "%s: set INT%u_2 sample rate to %u\n",
670 __func__, j, sample_rate);
Meng Wang15c825d2018-09-06 10:49:18 +0800671 snd_soc_component_update_bits(component,
672 int_fs_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530673 WSA_MACRO_FS_RATE_MASK,
674 int_mix_fs_rate_reg_val);
675 }
676 int_mux_cfg1 += WSA_MACRO_MUX_CFG_OFFSET;
677 }
678 }
679 return 0;
680}
681
682static int wsa_macro_set_interpolator_rate(struct snd_soc_dai *dai,
683 u32 sample_rate)
684{
685 int rate_val = 0;
686 int i, ret;
687
688 /* set mixing path rate */
689 for (i = 0; i < ARRAY_SIZE(int_mix_sample_rate_val); i++) {
690 if (sample_rate ==
691 int_mix_sample_rate_val[i].sample_rate) {
692 rate_val =
693 int_mix_sample_rate_val[i].rate_val;
694 break;
695 }
696 }
697 if ((i == ARRAY_SIZE(int_mix_sample_rate_val)) ||
698 (rate_val < 0))
699 goto prim_rate;
700 ret = wsa_macro_set_mix_interpolator_rate(dai,
701 (u8) rate_val, sample_rate);
702prim_rate:
703 /* set primary path sample rate */
704 for (i = 0; i < ARRAY_SIZE(int_prim_sample_rate_val); i++) {
705 if (sample_rate ==
706 int_prim_sample_rate_val[i].sample_rate) {
707 rate_val =
708 int_prim_sample_rate_val[i].rate_val;
709 break;
710 }
711 }
712 if ((i == ARRAY_SIZE(int_prim_sample_rate_val)) ||
713 (rate_val < 0))
714 return -EINVAL;
715 ret = wsa_macro_set_prim_interpolator_rate(dai,
716 (u8) rate_val, sample_rate);
717 return ret;
718}
719
720static int wsa_macro_hw_params(struct snd_pcm_substream *substream,
721 struct snd_pcm_hw_params *params,
722 struct snd_soc_dai *dai)
723{
Meng Wang15c825d2018-09-06 10:49:18 +0800724 struct snd_soc_component *component = dai->component;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530725 int ret;
726
Meng Wang15c825d2018-09-06 10:49:18 +0800727 dev_dbg(component->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530728 "%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__,
729 dai->name, dai->id, params_rate(params),
730 params_channels(params));
731
732 switch (substream->stream) {
733 case SNDRV_PCM_STREAM_PLAYBACK:
734 ret = wsa_macro_set_interpolator_rate(dai, params_rate(params));
735 if (ret) {
Meng Wang15c825d2018-09-06 10:49:18 +0800736 dev_err(component->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530737 "%s: cannot set sample rate: %u\n",
738 __func__, params_rate(params));
739 return ret;
740 }
741 break;
742 case SNDRV_PCM_STREAM_CAPTURE:
743 default:
744 break;
745 }
746 return 0;
747}
748
749static int wsa_macro_get_channel_map(struct snd_soc_dai *dai,
750 unsigned int *tx_num, unsigned int *tx_slot,
751 unsigned int *rx_num, unsigned int *rx_slot)
752{
Meng Wang15c825d2018-09-06 10:49:18 +0800753 struct snd_soc_component *component = dai->component;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530754 struct device *wsa_dev = NULL;
755 struct wsa_macro_priv *wsa_priv = NULL;
Laxminath Kasam5d9ea8d2018-11-28 14:32:40 +0530756 u16 val = 0, mask = 0, cnt = 0;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530757
Meng Wang15c825d2018-09-06 10:49:18 +0800758 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530759 return -EINVAL;
760
761 wsa_priv = dev_get_drvdata(wsa_dev);
762 if (!wsa_priv)
763 return -EINVAL;
764
765 switch (dai->id) {
766 case WSA_MACRO_AIF_VI:
Laxminath Kasam243e2752018-04-12 00:40:19 +0530767 *tx_slot = wsa_priv->active_ch_mask[dai->id];
768 *tx_num = wsa_priv->active_ch_cnt[dai->id];
769 break;
770 case WSA_MACRO_AIF1_PB:
771 case WSA_MACRO_AIF_MIX1_PB:
772 *rx_slot = wsa_priv->active_ch_mask[dai->id];
773 *rx_num = wsa_priv->active_ch_cnt[dai->id];
774 break;
Laxminath Kasam5d9ea8d2018-11-28 14:32:40 +0530775 case WSA_MACRO_AIF_ECHO:
776 val = snd_soc_component_read32(component,
777 BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0);
778 if (val & WSA_MACRO_EC_MIX_TX1_MASK) {
779 mask |= 0x2;
780 cnt++;
781 }
782 if (val & WSA_MACRO_EC_MIX_TX0_MASK) {
783 mask |= 0x1;
784 cnt++;
785 }
786 *tx_slot = mask;
787 *tx_num = cnt;
788 break;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530789 default:
790 dev_err(wsa_dev, "%s: Invalid AIF\n", __func__);
791 break;
792 }
793 return 0;
794}
795
796static int wsa_macro_mclk_enable(struct wsa_macro_priv *wsa_priv,
797 bool mclk_enable, bool dapm)
798{
799 struct regmap *regmap = dev_get_regmap(wsa_priv->dev->parent, NULL);
800 int ret = 0;
801
Tanya Dixitab8eba82018-10-05 15:07:37 +0530802 if (regmap == NULL) {
803 dev_err(wsa_priv->dev, "%s: regmap is NULL\n", __func__);
804 return -EINVAL;
805 }
806
Laxminath Kasam243e2752018-04-12 00:40:19 +0530807 dev_dbg(wsa_priv->dev, "%s: mclk_enable = %u, dapm = %d clk_users= %d\n",
808 __func__, mclk_enable, dapm, wsa_priv->wsa_mclk_users);
809
810 mutex_lock(&wsa_priv->mclk_lock);
811 if (mclk_enable) {
Aditya Bavanaric496ed22018-11-16 15:50:40 +0530812 if (wsa_priv->wsa_mclk_users == 0) {
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -0700813 ret = bolero_clk_rsc_request_clock(wsa_priv->dev,
814 wsa_priv->default_clk_id,
815 wsa_priv->default_clk_id,
816 true);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530817 if (ret < 0) {
818 dev_err(wsa_priv->dev,
819 "%s: wsa request clock enable failed\n",
820 __func__);
821 goto exit;
822 }
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -0700823 bolero_clk_rsc_fs_gen_request(wsa_priv->dev,
824 true);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530825 regcache_mark_dirty(regmap);
826 regcache_sync_region(regmap,
827 WSA_START_OFFSET,
828 WSA_MAX_OFFSET);
829 /* 9.6MHz MCLK, set value 0x00 if other frequency */
830 regmap_update_bits(regmap,
831 BOLERO_CDC_WSA_TOP_FREQ_MCLK, 0x01, 0x01);
832 regmap_update_bits(regmap,
833 BOLERO_CDC_WSA_CLK_RST_CTRL_MCLK_CONTROL,
834 0x01, 0x01);
835 regmap_update_bits(regmap,
836 BOLERO_CDC_WSA_CLK_RST_CTRL_FS_CNT_CONTROL,
837 0x01, 0x01);
838 }
Aditya Bavanaric496ed22018-11-16 15:50:40 +0530839 wsa_priv->wsa_mclk_users++;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530840 } else {
Aditya Bavanaric496ed22018-11-16 15:50:40 +0530841 if (wsa_priv->wsa_mclk_users <= 0) {
842 dev_err(wsa_priv->dev, "%s: clock already disabled\n",
843 __func__);
844 wsa_priv->wsa_mclk_users = 0;
845 goto exit;
846 }
Laxminath Kasam243e2752018-04-12 00:40:19 +0530847 wsa_priv->wsa_mclk_users--;
848 if (wsa_priv->wsa_mclk_users == 0) {
849 regmap_update_bits(regmap,
850 BOLERO_CDC_WSA_CLK_RST_CTRL_FS_CNT_CONTROL,
851 0x01, 0x00);
852 regmap_update_bits(regmap,
853 BOLERO_CDC_WSA_CLK_RST_CTRL_MCLK_CONTROL,
854 0x01, 0x00);
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -0700855 bolero_clk_rsc_fs_gen_request(wsa_priv->dev,
856 false);
857
858 bolero_clk_rsc_request_clock(wsa_priv->dev,
859 wsa_priv->default_clk_id,
860 wsa_priv->default_clk_id,
861 false);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530862 }
863 }
864exit:
865 mutex_unlock(&wsa_priv->mclk_lock);
866 return ret;
867}
868
869static int wsa_macro_mclk_event(struct snd_soc_dapm_widget *w,
870 struct snd_kcontrol *kcontrol, int event)
871{
Meng Wang15c825d2018-09-06 10:49:18 +0800872 struct snd_soc_component *component =
873 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530874 int ret = 0;
875 struct device *wsa_dev = NULL;
876 struct wsa_macro_priv *wsa_priv = NULL;
877
Meng Wang15c825d2018-09-06 10:49:18 +0800878 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530879 return -EINVAL;
880
881 dev_dbg(wsa_dev, "%s: event = %d\n", __func__, event);
882 switch (event) {
883 case SND_SOC_DAPM_PRE_PMU:
884 ret = wsa_macro_mclk_enable(wsa_priv, 1, true);
Ramprasad Katkam452772a2019-01-07 17:30:36 +0530885 if (ret)
886 wsa_priv->dapm_mclk_enable = false;
887 else
888 wsa_priv->dapm_mclk_enable = true;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530889 break;
890 case SND_SOC_DAPM_POST_PMD:
Ramprasad Katkam452772a2019-01-07 17:30:36 +0530891 if (wsa_priv->dapm_mclk_enable)
892 wsa_macro_mclk_enable(wsa_priv, 0, true);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530893 break;
894 default:
895 dev_err(wsa_priv->dev,
896 "%s: invalid DAPM event %d\n", __func__, event);
897 ret = -EINVAL;
898 }
899 return ret;
900}
901
Meng Wang15c825d2018-09-06 10:49:18 +0800902static int wsa_macro_event_handler(struct snd_soc_component *component,
903 u16 event, u32 data)
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530904{
905 struct device *wsa_dev = NULL;
906 struct wsa_macro_priv *wsa_priv = NULL;
907
Meng Wang15c825d2018-09-06 10:49:18 +0800908 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530909 return -EINVAL;
910
911 switch (event) {
912 case BOLERO_MACRO_EVT_SSR_DOWN:
913 swrm_wcd_notify(
914 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
Ramprasad Katkam5ee54ae2018-12-19 18:56:00 +0530915 SWR_DEVICE_DOWN, NULL);
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530916 swrm_wcd_notify(
917 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
Ramprasad Katkam5ee54ae2018-12-19 18:56:00 +0530918 SWR_DEVICE_SSR_DOWN, NULL);
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530919 break;
920 case BOLERO_MACRO_EVT_SSR_UP:
Ramprasad Katkama4c747b2018-12-11 19:15:53 +0530921 /* reset swr after ssr/pdr */
922 wsa_priv->reset_swr = true;
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530923 swrm_wcd_notify(
924 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
925 SWR_DEVICE_SSR_UP, NULL);
926 break;
927 }
928 return 0;
929}
930
Laxminath Kasam243e2752018-04-12 00:40:19 +0530931static int wsa_macro_enable_vi_feedback(struct snd_soc_dapm_widget *w,
932 struct snd_kcontrol *kcontrol,
933 int event)
934{
Meng Wang15c825d2018-09-06 10:49:18 +0800935 struct snd_soc_component *component =
936 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530937 struct device *wsa_dev = NULL;
938 struct wsa_macro_priv *wsa_priv = NULL;
939
Meng Wang15c825d2018-09-06 10:49:18 +0800940 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530941 return -EINVAL;
942
943 switch (event) {
944 case SND_SOC_DAPM_POST_PMU:
945 if (test_bit(WSA_MACRO_TX0,
946 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
947 dev_dbg(wsa_dev, "%s: spkr1 enabled\n", __func__);
948 /* Enable V&I sensing */
Meng Wang15c825d2018-09-06 10:49:18 +0800949 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530950 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
951 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +0800952 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530953 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
954 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +0800955 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530956 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
957 0x0F, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +0800958 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530959 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
960 0x0F, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +0800961 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530962 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
963 0x10, 0x10);
Meng Wang15c825d2018-09-06 10:49:18 +0800964 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530965 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
966 0x10, 0x10);
Meng Wang15c825d2018-09-06 10:49:18 +0800967 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530968 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
969 0x20, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +0800970 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530971 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
972 0x20, 0x00);
973 }
974 if (test_bit(WSA_MACRO_TX1,
975 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
976 dev_dbg(wsa_dev, "%s: spkr2 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_TX2_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_TX3_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_TX2_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_TX3_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_TX2_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_TX3_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_TX2_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_TX3_SPKR_PROT_PATH_CTL,
1001 0x20, 0x00);
1002 }
1003 break;
1004 case SND_SOC_DAPM_POST_PMD:
1005 if (test_bit(WSA_MACRO_TX0,
1006 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
1007 /* Disable V&I sensing */
Meng Wang15c825d2018-09-06 10:49:18 +08001008 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301009 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
1010 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08001011 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301012 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
1013 0x20, 0x20);
1014 dev_dbg(wsa_dev, "%s: spkr1 disabled\n", __func__);
Meng Wang15c825d2018-09-06 10:49:18 +08001015 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301016 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
1017 0x10, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001018 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301019 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
1020 0x10, 0x00);
1021 }
1022 if (test_bit(WSA_MACRO_TX1,
1023 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
1024 /* Disable V&I sensing */
1025 dev_dbg(wsa_dev, "%s: spkr2 disabled\n", __func__);
Meng Wang15c825d2018-09-06 10:49:18 +08001026 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301027 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
1028 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08001029 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301030 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
1031 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08001032 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301033 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
1034 0x10, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001035 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301036 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
1037 0x10, 0x00);
1038 }
1039 break;
1040 }
1041
1042 return 0;
1043}
1044
1045static int wsa_macro_enable_mix_path(struct snd_soc_dapm_widget *w,
1046 struct snd_kcontrol *kcontrol, int event)
1047{
Meng Wang15c825d2018-09-06 10:49:18 +08001048 struct snd_soc_component *component =
1049 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301050 u16 gain_reg;
1051 int offset_val = 0;
1052 int val = 0;
1053
Meng Wang15c825d2018-09-06 10:49:18 +08001054 dev_dbg(component->dev, "%s %d %s\n", __func__, event, w->name);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301055
1056 switch (w->reg) {
1057 case BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL:
1058 gain_reg = BOLERO_CDC_WSA_RX0_RX_VOL_MIX_CTL;
1059 break;
1060 case BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL:
1061 gain_reg = BOLERO_CDC_WSA_RX1_RX_VOL_MIX_CTL;
1062 break;
1063 default:
Meng Wang15c825d2018-09-06 10:49:18 +08001064 dev_err(component->dev, "%s: No gain register avail for %s\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301065 __func__, w->name);
1066 return 0;
1067 }
1068
1069 switch (event) {
1070 case SND_SOC_DAPM_POST_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08001071 val = snd_soc_component_read32(component, gain_reg);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301072 val += offset_val;
Meng Wang15c825d2018-09-06 10:49:18 +08001073 snd_soc_component_write(component, gain_reg, val);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301074 break;
1075 case SND_SOC_DAPM_POST_PMD:
1076 break;
1077 }
1078
1079 return 0;
1080}
1081
Meng Wang15c825d2018-09-06 10:49:18 +08001082static void wsa_macro_hd2_control(struct snd_soc_component *component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301083 u16 reg, int event)
1084{
1085 u16 hd2_scale_reg;
1086 u16 hd2_enable_reg = 0;
1087
1088 if (reg == BOLERO_CDC_WSA_RX0_RX_PATH_CTL) {
1089 hd2_scale_reg = BOLERO_CDC_WSA_RX0_RX_PATH_SEC3;
1090 hd2_enable_reg = BOLERO_CDC_WSA_RX0_RX_PATH_CFG0;
1091 }
1092 if (reg == BOLERO_CDC_WSA_RX1_RX_PATH_CTL) {
1093 hd2_scale_reg = BOLERO_CDC_WSA_RX1_RX_PATH_SEC3;
1094 hd2_enable_reg = BOLERO_CDC_WSA_RX1_RX_PATH_CFG0;
1095 }
1096
1097 if (hd2_enable_reg && SND_SOC_DAPM_EVENT_ON(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001098 snd_soc_component_update_bits(component, hd2_scale_reg,
1099 0x3C, 0x10);
1100 snd_soc_component_update_bits(component, hd2_scale_reg,
1101 0x03, 0x01);
1102 snd_soc_component_update_bits(component, hd2_enable_reg,
1103 0x04, 0x04);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301104 }
1105
1106 if (hd2_enable_reg && SND_SOC_DAPM_EVENT_OFF(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001107 snd_soc_component_update_bits(component, hd2_enable_reg,
1108 0x04, 0x00);
1109 snd_soc_component_update_bits(component, hd2_scale_reg,
1110 0x03, 0x00);
1111 snd_soc_component_update_bits(component, hd2_scale_reg,
1112 0x3C, 0x00);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301113 }
1114}
1115
1116static int wsa_macro_enable_swr(struct snd_soc_dapm_widget *w,
1117 struct snd_kcontrol *kcontrol, int event)
1118{
Meng Wang15c825d2018-09-06 10:49:18 +08001119 struct snd_soc_component *component =
1120 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301121 int ch_cnt;
1122 struct device *wsa_dev = NULL;
1123 struct wsa_macro_priv *wsa_priv = NULL;
1124
Meng Wang15c825d2018-09-06 10:49:18 +08001125 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301126 return -EINVAL;
1127
1128 switch (event) {
1129 case SND_SOC_DAPM_PRE_PMU:
1130 if (!(strnstr(w->name, "RX0", sizeof("WSA_RX0"))) &&
1131 !wsa_priv->rx_0_count)
1132 wsa_priv->rx_0_count++;
1133 if (!(strnstr(w->name, "RX1", sizeof("WSA_RX1"))) &&
1134 !wsa_priv->rx_1_count)
1135 wsa_priv->rx_1_count++;
1136 ch_cnt = wsa_priv->rx_0_count + wsa_priv->rx_1_count;
1137
1138 swrm_wcd_notify(
1139 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
1140 SWR_DEVICE_UP, NULL);
1141 swrm_wcd_notify(
1142 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
1143 SWR_SET_NUM_RX_CH, &ch_cnt);
1144 break;
1145 case SND_SOC_DAPM_POST_PMD:
1146 if (!(strnstr(w->name, "RX0", sizeof("WSA_RX0"))) &&
1147 wsa_priv->rx_0_count)
1148 wsa_priv->rx_0_count--;
1149 if (!(strnstr(w->name, "RX1", sizeof("WSA_RX1"))) &&
1150 wsa_priv->rx_1_count)
1151 wsa_priv->rx_1_count--;
1152 ch_cnt = wsa_priv->rx_0_count + wsa_priv->rx_1_count;
1153
1154 swrm_wcd_notify(
1155 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
1156 SWR_SET_NUM_RX_CH, &ch_cnt);
1157 break;
1158 }
1159 dev_dbg(wsa_priv->dev, "%s: current swr ch cnt: %d\n",
1160 __func__, wsa_priv->rx_0_count + wsa_priv->rx_1_count);
1161
1162 return 0;
1163}
1164
Meng Wang15c825d2018-09-06 10:49:18 +08001165static int wsa_macro_config_compander(struct snd_soc_component *component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301166 int comp, int event)
1167{
1168 u16 comp_ctl0_reg, rx_path_cfg0_reg;
1169 struct device *wsa_dev = NULL;
1170 struct wsa_macro_priv *wsa_priv = NULL;
1171
Meng Wang15c825d2018-09-06 10:49:18 +08001172 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301173 return -EINVAL;
1174
Meng Wang15c825d2018-09-06 10:49:18 +08001175 dev_dbg(component->dev, "%s: event %d compander %d, enabled %d\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301176 __func__, event, comp + 1, wsa_priv->comp_enabled[comp]);
1177
1178 if (!wsa_priv->comp_enabled[comp])
1179 return 0;
1180
1181 comp_ctl0_reg = BOLERO_CDC_WSA_COMPANDER0_CTL0 +
1182 (comp * WSA_MACRO_RX_COMP_OFFSET);
1183 rx_path_cfg0_reg = BOLERO_CDC_WSA_RX0_RX_PATH_CFG0 +
1184 (comp * WSA_MACRO_RX_PATH_OFFSET);
1185
1186 if (SND_SOC_DAPM_EVENT_ON(event)) {
1187 /* Enable Compander Clock */
Meng Wang15c825d2018-09-06 10:49:18 +08001188 snd_soc_component_update_bits(component, comp_ctl0_reg,
1189 0x01, 0x01);
1190 snd_soc_component_update_bits(component, comp_ctl0_reg,
1191 0x02, 0x02);
1192 snd_soc_component_update_bits(component, comp_ctl0_reg,
1193 0x02, 0x00);
1194 snd_soc_component_update_bits(component, rx_path_cfg0_reg,
1195 0x02, 0x02);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301196 }
1197
1198 if (SND_SOC_DAPM_EVENT_OFF(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001199 snd_soc_component_update_bits(component, comp_ctl0_reg,
1200 0x04, 0x04);
1201 snd_soc_component_update_bits(component, rx_path_cfg0_reg,
1202 0x02, 0x00);
1203 snd_soc_component_update_bits(component, comp_ctl0_reg,
1204 0x02, 0x02);
1205 snd_soc_component_update_bits(component, comp_ctl0_reg,
1206 0x02, 0x00);
1207 snd_soc_component_update_bits(component, comp_ctl0_reg,
1208 0x01, 0x00);
1209 snd_soc_component_update_bits(component, comp_ctl0_reg,
1210 0x04, 0x00);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301211 }
1212
1213 return 0;
1214}
1215
Meng Wang15c825d2018-09-06 10:49:18 +08001216static void wsa_macro_enable_softclip_clk(struct snd_soc_component *component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301217 struct wsa_macro_priv *wsa_priv,
1218 int path,
1219 bool enable)
1220{
1221 u16 softclip_clk_reg = BOLERO_CDC_WSA_SOFTCLIP0_CRC +
1222 (path * WSA_MACRO_RX_SOFTCLIP_OFFSET);
1223 u8 softclip_mux_mask = (1 << path);
1224 u8 softclip_mux_value = (1 << path);
1225
Meng Wang15c825d2018-09-06 10:49:18 +08001226 dev_dbg(component->dev, "%s: path %d, enable %d\n",
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301227 __func__, path, enable);
1228 if (enable) {
1229 if (wsa_priv->softclip_clk_users[path] == 0) {
Meng Wang15c825d2018-09-06 10:49:18 +08001230 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301231 softclip_clk_reg, 0x01, 0x01);
Meng Wang15c825d2018-09-06 10:49:18 +08001232 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301233 BOLERO_CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0,
1234 softclip_mux_mask, softclip_mux_value);
1235 }
1236 wsa_priv->softclip_clk_users[path]++;
1237 } else {
1238 wsa_priv->softclip_clk_users[path]--;
1239 if (wsa_priv->softclip_clk_users[path] == 0) {
Meng Wang15c825d2018-09-06 10:49:18 +08001240 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301241 softclip_clk_reg, 0x01, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001242 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301243 BOLERO_CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0,
1244 softclip_mux_mask, 0x00);
1245 }
1246 }
1247}
1248
Meng Wang15c825d2018-09-06 10:49:18 +08001249static int wsa_macro_config_softclip(struct snd_soc_component *component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301250 int path, int event)
1251{
1252 u16 softclip_ctrl_reg = 0;
1253 struct device *wsa_dev = NULL;
1254 struct wsa_macro_priv *wsa_priv = NULL;
1255 int softclip_path = 0;
1256
Meng Wang15c825d2018-09-06 10:49:18 +08001257 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301258 return -EINVAL;
1259
1260 if (path == WSA_MACRO_COMP1)
1261 softclip_path = WSA_MACRO_SOFTCLIP0;
1262 else if (path == WSA_MACRO_COMP2)
1263 softclip_path = WSA_MACRO_SOFTCLIP1;
1264
Meng Wang15c825d2018-09-06 10:49:18 +08001265 dev_dbg(component->dev, "%s: event %d path %d, enabled %d\n",
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301266 __func__, event, softclip_path,
1267 wsa_priv->is_softclip_on[softclip_path]);
1268
1269 if (!wsa_priv->is_softclip_on[softclip_path])
1270 return 0;
1271
1272 softclip_ctrl_reg = BOLERO_CDC_WSA_SOFTCLIP0_SOFTCLIP_CTRL +
1273 (softclip_path * WSA_MACRO_RX_SOFTCLIP_OFFSET);
1274
1275 if (SND_SOC_DAPM_EVENT_ON(event)) {
1276 /* Enable Softclip clock and mux */
Meng Wang15c825d2018-09-06 10:49:18 +08001277 wsa_macro_enable_softclip_clk(component, wsa_priv,
1278 softclip_path, true);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301279 /* Enable Softclip control */
Meng Wang15c825d2018-09-06 10:49:18 +08001280 snd_soc_component_update_bits(component, softclip_ctrl_reg,
1281 0x01, 0x01);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301282 }
1283
1284 if (SND_SOC_DAPM_EVENT_OFF(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001285 snd_soc_component_update_bits(component, softclip_ctrl_reg,
1286 0x01, 0x00);
1287 wsa_macro_enable_softclip_clk(component, wsa_priv,
1288 softclip_path, false);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301289 }
1290
1291 return 0;
1292}
1293
Laxminath Kasam243e2752018-04-12 00:40:19 +05301294static int wsa_macro_interp_get_primary_reg(u16 reg, u16 *ind)
1295{
1296 u16 prim_int_reg = 0;
1297
1298 switch (reg) {
1299 case BOLERO_CDC_WSA_RX0_RX_PATH_CTL:
1300 case BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL:
1301 prim_int_reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL;
1302 *ind = 0;
1303 break;
1304 case BOLERO_CDC_WSA_RX1_RX_PATH_CTL:
1305 case BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL:
1306 prim_int_reg = BOLERO_CDC_WSA_RX1_RX_PATH_CTL;
1307 *ind = 1;
1308 break;
1309 }
1310
1311 return prim_int_reg;
1312}
1313
1314static int wsa_macro_enable_prim_interpolator(
Meng Wang15c825d2018-09-06 10:49:18 +08001315 struct snd_soc_component *component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301316 u16 reg, int event)
1317{
1318 u16 prim_int_reg;
1319 u16 ind = 0;
1320 struct device *wsa_dev = NULL;
1321 struct wsa_macro_priv *wsa_priv = NULL;
1322
Meng Wang15c825d2018-09-06 10:49:18 +08001323 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301324 return -EINVAL;
1325
1326 prim_int_reg = wsa_macro_interp_get_primary_reg(reg, &ind);
1327
1328 switch (event) {
1329 case SND_SOC_DAPM_PRE_PMU:
1330 wsa_priv->prim_int_users[ind]++;
1331 if (wsa_priv->prim_int_users[ind] == 1) {
Meng Wang15c825d2018-09-06 10:49:18 +08001332 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301333 prim_int_reg + WSA_MACRO_RX_PATH_CFG3_OFFSET,
1334 0x03, 0x03);
Meng Wang15c825d2018-09-06 10:49:18 +08001335 snd_soc_component_update_bits(component, prim_int_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301336 0x10, 0x10);
Meng Wang15c825d2018-09-06 10:49:18 +08001337 wsa_macro_hd2_control(component, prim_int_reg, event);
1338 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301339 prim_int_reg + WSA_MACRO_RX_PATH_DSMDEM_OFFSET,
1340 0x1, 0x1);
Meng Wang15c825d2018-09-06 10:49:18 +08001341 snd_soc_component_update_bits(component, prim_int_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301342 1 << 0x5, 1 << 0x5);
1343 }
1344 if ((reg != prim_int_reg) &&
Meng Wang15c825d2018-09-06 10:49:18 +08001345 ((snd_soc_component_read32(
1346 component, prim_int_reg)) & 0x10))
1347 snd_soc_component_update_bits(component, reg,
1348 0x10, 0x10);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301349 break;
1350 case SND_SOC_DAPM_POST_PMD:
1351 wsa_priv->prim_int_users[ind]--;
1352 if (wsa_priv->prim_int_users[ind] == 0) {
Meng Wang15c825d2018-09-06 10:49:18 +08001353 snd_soc_component_update_bits(component, prim_int_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301354 1 << 0x5, 0 << 0x5);
Meng Wang15c825d2018-09-06 10:49:18 +08001355 snd_soc_component_update_bits(component, prim_int_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301356 0x40, 0x40);
Meng Wang15c825d2018-09-06 10:49:18 +08001357 snd_soc_component_update_bits(component, prim_int_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301358 0x40, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001359 wsa_macro_hd2_control(component, prim_int_reg, event);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301360 }
1361 break;
1362 }
1363
Meng Wang15c825d2018-09-06 10:49:18 +08001364 dev_dbg(component->dev, "%s: primary interpolator: INT%d, users: %d\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301365 __func__, ind, wsa_priv->prim_int_users[ind]);
1366 return 0;
1367}
1368
1369static int wsa_macro_enable_interpolator(struct snd_soc_dapm_widget *w,
1370 struct snd_kcontrol *kcontrol,
1371 int event)
1372{
Meng Wang15c825d2018-09-06 10:49:18 +08001373 struct snd_soc_component *component =
1374 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301375 u16 gain_reg;
1376 u16 reg;
1377 int val;
1378 int offset_val = 0;
1379 struct device *wsa_dev = NULL;
1380 struct wsa_macro_priv *wsa_priv = NULL;
1381
Meng Wang15c825d2018-09-06 10:49:18 +08001382 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301383 return -EINVAL;
1384
Meng Wang15c825d2018-09-06 10:49:18 +08001385 dev_dbg(component->dev, "%s %d %s\n", __func__, event, w->name);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301386
1387 if (!(strcmp(w->name, "WSA_RX INT0 INTERP"))) {
1388 reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL;
1389 gain_reg = BOLERO_CDC_WSA_RX0_RX_VOL_CTL;
1390 } else if (!(strcmp(w->name, "WSA_RX INT1 INTERP"))) {
1391 reg = BOLERO_CDC_WSA_RX1_RX_PATH_CTL;
1392 gain_reg = BOLERO_CDC_WSA_RX1_RX_VOL_CTL;
1393 } else {
Meng Wang15c825d2018-09-06 10:49:18 +08001394 dev_err(component->dev, "%s: Interpolator reg not found\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301395 __func__);
1396 return -EINVAL;
1397 }
1398
1399 switch (event) {
1400 case SND_SOC_DAPM_PRE_PMU:
1401 /* Reset if needed */
Meng Wang15c825d2018-09-06 10:49:18 +08001402 wsa_macro_enable_prim_interpolator(component, reg, event);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301403 break;
1404 case SND_SOC_DAPM_POST_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08001405 wsa_macro_config_compander(component, w->shift, event);
1406 wsa_macro_config_softclip(component, w->shift, event);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301407 /* apply gain after int clk is enabled */
Laxminath Kasam21c8b222018-06-21 18:47:22 +05301408 if ((wsa_priv->spkr_gain_offset ==
1409 WSA_MACRO_GAIN_OFFSET_M1P5_DB) &&
Laxminath Kasam243e2752018-04-12 00:40:19 +05301410 (wsa_priv->comp_enabled[WSA_MACRO_COMP1] ||
1411 wsa_priv->comp_enabled[WSA_MACRO_COMP2]) &&
1412 (gain_reg == BOLERO_CDC_WSA_RX0_RX_VOL_CTL ||
1413 gain_reg == BOLERO_CDC_WSA_RX1_RX_VOL_CTL)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001414 snd_soc_component_update_bits(component,
1415 BOLERO_CDC_WSA_RX0_RX_PATH_SEC1,
1416 0x01, 0x01);
1417 snd_soc_component_update_bits(component,
1418 BOLERO_CDC_WSA_RX0_RX_PATH_MIX_SEC0,
1419 0x01, 0x01);
1420 snd_soc_component_update_bits(component,
1421 BOLERO_CDC_WSA_RX1_RX_PATH_SEC1,
1422 0x01, 0x01);
1423 snd_soc_component_update_bits(component,
1424 BOLERO_CDC_WSA_RX1_RX_PATH_MIX_SEC0,
1425 0x01, 0x01);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301426 offset_val = -2;
1427 }
Meng Wang15c825d2018-09-06 10:49:18 +08001428 val = snd_soc_component_read32(component, gain_reg);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301429 val += offset_val;
Meng Wang15c825d2018-09-06 10:49:18 +08001430 snd_soc_component_write(component, gain_reg, val);
1431 wsa_macro_config_ear_spkr_gain(component, wsa_priv,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301432 event, gain_reg);
1433 break;
1434 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +08001435 wsa_macro_config_compander(component, w->shift, event);
1436 wsa_macro_config_softclip(component, w->shift, event);
1437 wsa_macro_enable_prim_interpolator(component, reg, event);
Laxminath Kasam21c8b222018-06-21 18:47:22 +05301438 if ((wsa_priv->spkr_gain_offset ==
1439 WSA_MACRO_GAIN_OFFSET_M1P5_DB) &&
Laxminath Kasam243e2752018-04-12 00:40:19 +05301440 (wsa_priv->comp_enabled[WSA_MACRO_COMP1] ||
1441 wsa_priv->comp_enabled[WSA_MACRO_COMP2]) &&
1442 (gain_reg == BOLERO_CDC_WSA_RX0_RX_VOL_CTL ||
1443 gain_reg == BOLERO_CDC_WSA_RX1_RX_VOL_CTL)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001444 snd_soc_component_update_bits(component,
1445 BOLERO_CDC_WSA_RX0_RX_PATH_SEC1,
1446 0x01, 0x00);
1447 snd_soc_component_update_bits(component,
1448 BOLERO_CDC_WSA_RX0_RX_PATH_MIX_SEC0,
1449 0x01, 0x00);
1450 snd_soc_component_update_bits(component,
1451 BOLERO_CDC_WSA_RX1_RX_PATH_SEC1,
1452 0x01, 0x00);
1453 snd_soc_component_update_bits(component,
1454 BOLERO_CDC_WSA_RX1_RX_PATH_MIX_SEC0,
1455 0x01, 0x00);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301456 offset_val = 2;
Meng Wang15c825d2018-09-06 10:49:18 +08001457 val = snd_soc_component_read32(component, gain_reg);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301458 val += offset_val;
Meng Wang15c825d2018-09-06 10:49:18 +08001459 snd_soc_component_write(component, gain_reg, val);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301460 }
Meng Wang15c825d2018-09-06 10:49:18 +08001461 wsa_macro_config_ear_spkr_gain(component, wsa_priv,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301462 event, gain_reg);
1463 break;
1464 }
1465
1466 return 0;
1467}
1468
Meng Wang15c825d2018-09-06 10:49:18 +08001469static int wsa_macro_config_ear_spkr_gain(struct snd_soc_component *component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301470 struct wsa_macro_priv *wsa_priv,
1471 int event, int gain_reg)
1472{
1473 int comp_gain_offset, val;
1474
1475 switch (wsa_priv->spkr_mode) {
Laxminath Kasam21c8b222018-06-21 18:47:22 +05301476 /* Compander gain in WSA_MACRO_SPKR_MODE1 case is 12 dB */
1477 case WSA_MACRO_SPKR_MODE_1:
Laxminath Kasam243e2752018-04-12 00:40:19 +05301478 comp_gain_offset = -12;
1479 break;
1480 /* Default case compander gain is 15 dB */
1481 default:
1482 comp_gain_offset = -15;
1483 break;
1484 }
1485
1486 switch (event) {
1487 case SND_SOC_DAPM_POST_PMU:
1488 /* Apply ear spkr gain only if compander is enabled */
1489 if (wsa_priv->comp_enabled[WSA_MACRO_COMP1] &&
1490 (gain_reg == BOLERO_CDC_WSA_RX0_RX_VOL_CTL) &&
1491 (wsa_priv->ear_spkr_gain != 0)) {
1492 /* For example, val is -8(-12+5-1) for 4dB of gain */
1493 val = comp_gain_offset + wsa_priv->ear_spkr_gain - 1;
Meng Wang15c825d2018-09-06 10:49:18 +08001494 snd_soc_component_write(component, gain_reg, val);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301495
1496 dev_dbg(wsa_priv->dev, "%s: RX0 Volume %d dB\n",
1497 __func__, val);
1498 }
1499 break;
1500 case SND_SOC_DAPM_POST_PMD:
1501 /*
1502 * Reset RX0 volume to 0 dB if compander is enabled and
1503 * ear_spkr_gain is non-zero.
1504 */
1505 if (wsa_priv->comp_enabled[WSA_MACRO_COMP1] &&
1506 (gain_reg == BOLERO_CDC_WSA_RX0_RX_VOL_CTL) &&
1507 (wsa_priv->ear_spkr_gain != 0)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001508 snd_soc_component_write(component, gain_reg, 0x0);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301509
1510 dev_dbg(wsa_priv->dev, "%s: Reset RX0 Volume to 0 dB\n",
1511 __func__);
1512 }
1513 break;
1514 }
1515
1516 return 0;
1517}
1518
1519static int wsa_macro_spk_boost_event(struct snd_soc_dapm_widget *w,
1520 struct snd_kcontrol *kcontrol,
1521 int event)
1522{
Meng Wang15c825d2018-09-06 10:49:18 +08001523 struct snd_soc_component *component =
1524 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301525 u16 boost_path_ctl, boost_path_cfg1;
1526 u16 reg, reg_mix;
1527
Meng Wang15c825d2018-09-06 10:49:18 +08001528 dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301529
1530 if (!strcmp(w->name, "WSA_RX INT0 CHAIN")) {
1531 boost_path_ctl = BOLERO_CDC_WSA_BOOST0_BOOST_PATH_CTL;
1532 boost_path_cfg1 = BOLERO_CDC_WSA_RX0_RX_PATH_CFG1;
1533 reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL;
1534 reg_mix = BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL;
1535 } else if (!strcmp(w->name, "WSA_RX INT1 CHAIN")) {
1536 boost_path_ctl = BOLERO_CDC_WSA_BOOST1_BOOST_PATH_CTL;
1537 boost_path_cfg1 = BOLERO_CDC_WSA_RX1_RX_PATH_CFG1;
1538 reg = BOLERO_CDC_WSA_RX1_RX_PATH_CTL;
1539 reg_mix = BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL;
1540 } else {
Meng Wang15c825d2018-09-06 10:49:18 +08001541 dev_err(component->dev, "%s: unknown widget: %s\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301542 __func__, w->name);
1543 return -EINVAL;
1544 }
1545
1546 switch (event) {
1547 case SND_SOC_DAPM_PRE_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08001548 snd_soc_component_update_bits(component, boost_path_cfg1,
1549 0x01, 0x01);
1550 snd_soc_component_update_bits(component, boost_path_ctl,
1551 0x10, 0x10);
1552 if ((snd_soc_component_read32(component, reg_mix)) & 0x10)
1553 snd_soc_component_update_bits(component, reg_mix,
1554 0x10, 0x00);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301555 break;
Laxminath Kasam0c857002018-07-17 23:47:17 +05301556 case SND_SOC_DAPM_POST_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08001557 snd_soc_component_update_bits(component, reg, 0x10, 0x00);
Laxminath Kasam0c857002018-07-17 23:47:17 +05301558 break;
Laxminath Kasam243e2752018-04-12 00:40:19 +05301559 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +08001560 snd_soc_component_update_bits(component, boost_path_ctl,
1561 0x10, 0x00);
1562 snd_soc_component_update_bits(component, boost_path_cfg1,
1563 0x01, 0x00);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301564 break;
1565 }
1566
1567 return 0;
1568}
1569
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301570
1571static int wsa_macro_enable_vbat(struct snd_soc_dapm_widget *w,
1572 struct snd_kcontrol *kcontrol,
1573 int event)
1574{
Meng Wang15c825d2018-09-06 10:49:18 +08001575 struct snd_soc_component *component =
1576 snd_soc_dapm_to_component(w->dapm);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301577 struct device *wsa_dev = NULL;
1578 struct wsa_macro_priv *wsa_priv = NULL;
1579 u16 vbat_path_cfg = 0;
1580 int softclip_path = 0;
1581
Meng Wang15c825d2018-09-06 10:49:18 +08001582 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301583 return -EINVAL;
1584
Meng Wang15c825d2018-09-06 10:49:18 +08001585 dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301586 if (!strcmp(w->name, "WSA_RX INT0 VBAT")) {
1587 vbat_path_cfg = BOLERO_CDC_WSA_RX0_RX_PATH_CFG1;
1588 softclip_path = WSA_MACRO_SOFTCLIP0;
1589 } else if (!strcmp(w->name, "WSA_RX INT1 VBAT")) {
1590 vbat_path_cfg = BOLERO_CDC_WSA_RX1_RX_PATH_CFG1;
1591 softclip_path = WSA_MACRO_SOFTCLIP1;
1592 }
1593
1594 switch (event) {
1595 case SND_SOC_DAPM_PRE_PMU:
1596 /* Enable clock for VBAT block */
Meng Wang15c825d2018-09-06 10:49:18 +08001597 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301598 BOLERO_CDC_WSA_VBAT_BCL_VBAT_PATH_CTL, 0x10, 0x10);
1599 /* Enable VBAT block */
Meng Wang15c825d2018-09-06 10:49:18 +08001600 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301601 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG, 0x01, 0x01);
1602 /* Update interpolator with 384K path */
Meng Wang15c825d2018-09-06 10:49:18 +08001603 snd_soc_component_update_bits(component, vbat_path_cfg,
1604 0x80, 0x80);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301605 /* Use attenuation mode */
Meng Wang15c825d2018-09-06 10:49:18 +08001606 snd_soc_component_update_bits(component,
1607 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG, 0x02, 0x00);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301608 /*
1609 * BCL block needs softclip clock and mux config to be enabled
1610 */
Meng Wang15c825d2018-09-06 10:49:18 +08001611 wsa_macro_enable_softclip_clk(component, wsa_priv,
1612 softclip_path, true);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301613 /* Enable VBAT at channel level */
Meng Wang15c825d2018-09-06 10:49:18 +08001614 snd_soc_component_update_bits(component, vbat_path_cfg,
1615 0x02, 0x02);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301616 /* Set the ATTK1 gain */
Meng Wang15c825d2018-09-06 10:49:18 +08001617 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301618 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD1,
1619 0xFF, 0xFF);
Meng Wang15c825d2018-09-06 10:49:18 +08001620 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301621 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD2,
1622 0xFF, 0x03);
Meng Wang15c825d2018-09-06 10:49:18 +08001623 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301624 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD3,
1625 0xFF, 0x00);
1626 /* Set the ATTK2 gain */
Meng Wang15c825d2018-09-06 10:49:18 +08001627 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301628 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD4,
1629 0xFF, 0xFF);
Meng Wang15c825d2018-09-06 10:49:18 +08001630 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301631 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD5,
1632 0xFF, 0x03);
Meng Wang15c825d2018-09-06 10:49:18 +08001633 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301634 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD6,
1635 0xFF, 0x00);
1636 /* Set the ATTK3 gain */
Meng Wang15c825d2018-09-06 10:49:18 +08001637 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301638 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD7,
1639 0xFF, 0xFF);
Meng Wang15c825d2018-09-06 10:49:18 +08001640 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301641 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD8,
1642 0xFF, 0x03);
Meng Wang15c825d2018-09-06 10:49:18 +08001643 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301644 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD9,
1645 0xFF, 0x00);
1646 break;
1647
1648 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +08001649 snd_soc_component_update_bits(component, vbat_path_cfg,
1650 0x80, 0x00);
1651 snd_soc_component_update_bits(component,
1652 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG,
1653 0x02, 0x02);
1654 snd_soc_component_update_bits(component, vbat_path_cfg,
1655 0x02, 0x00);
1656 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301657 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD1,
1658 0xFF, 0x00);
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_UPD2,
1661 0xFF, 0x00);
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_UPD3,
1664 0xFF, 0x00);
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_UPD4,
1667 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001668 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301669 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD5,
1670 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001671 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301672 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD6,
1673 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001674 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301675 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD7,
1676 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001677 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301678 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD8,
1679 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001680 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301681 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD9,
1682 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001683 wsa_macro_enable_softclip_clk(component, wsa_priv,
1684 softclip_path, false);
1685 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301686 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG, 0x01, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001687 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301688 BOLERO_CDC_WSA_VBAT_BCL_VBAT_PATH_CTL, 0x10, 0x00);
1689 break;
1690 default:
1691 dev_err(wsa_dev, "%s: Invalid event %d\n", __func__, event);
1692 break;
1693 }
1694 return 0;
1695}
1696
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301697static int wsa_macro_enable_echo(struct snd_soc_dapm_widget *w,
1698 struct snd_kcontrol *kcontrol,
1699 int event)
1700{
Meng Wang15c825d2018-09-06 10:49:18 +08001701 struct snd_soc_component *component =
1702 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301703 struct device *wsa_dev = NULL;
1704 struct wsa_macro_priv *wsa_priv = NULL;
1705 u16 val, ec_tx = 0, ec_hq_reg;
1706
Meng Wang15c825d2018-09-06 10:49:18 +08001707 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301708 return -EINVAL;
1709
1710 dev_dbg(wsa_dev, "%s %d %s\n", __func__, event, w->name);
1711
Meng Wang15c825d2018-09-06 10:49:18 +08001712 val = snd_soc_component_read32(component,
1713 BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301714 if (!(strcmp(w->name, "WSA RX_MIX EC0_MUX")))
1715 ec_tx = (val & 0x07) - 1;
1716 else
1717 ec_tx = ((val & 0x38) >> 0x3) - 1;
1718
1719 if (ec_tx < 0 || ec_tx >= (WSA_MACRO_RX1 + 1)) {
1720 dev_err(wsa_dev, "%s: EC mix control not set correctly\n",
1721 __func__);
1722 return -EINVAL;
1723 }
1724 if (wsa_priv->ec_hq[ec_tx]) {
Meng Wang15c825d2018-09-06 10:49:18 +08001725 snd_soc_component_update_bits(component,
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301726 BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0,
1727 0x1 << ec_tx, 0x1 << ec_tx);
1728 ec_hq_reg = BOLERO_CDC_WSA_EC_HQ0_EC_REF_HQ_PATH_CTL +
Laxminath Kasam5d9ea8d2018-11-28 14:32:40 +05301729 0x40 * ec_tx;
Meng Wang15c825d2018-09-06 10:49:18 +08001730 snd_soc_component_update_bits(component, ec_hq_reg, 0x01, 0x01);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301731 ec_hq_reg = BOLERO_CDC_WSA_EC_HQ0_EC_REF_HQ_CFG0 +
Laxminath Kasam5d9ea8d2018-11-28 14:32:40 +05301732 0x40 * ec_tx;
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301733 /* default set to 48k */
Meng Wang15c825d2018-09-06 10:49:18 +08001734 snd_soc_component_update_bits(component, ec_hq_reg, 0x1E, 0x08);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301735 }
1736
1737 return 0;
1738}
1739
1740static int wsa_macro_get_ec_hq(struct snd_kcontrol *kcontrol,
1741 struct snd_ctl_elem_value *ucontrol)
1742{
1743
Meng Wang15c825d2018-09-06 10:49:18 +08001744 struct snd_soc_component *component =
1745 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301746 int ec_tx = ((struct soc_multi_mixer_control *)
1747 kcontrol->private_value)->shift;
1748 struct device *wsa_dev = NULL;
1749 struct wsa_macro_priv *wsa_priv = NULL;
1750
Meng Wang15c825d2018-09-06 10:49:18 +08001751 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301752 return -EINVAL;
1753
1754 ucontrol->value.integer.value[0] = wsa_priv->ec_hq[ec_tx];
1755 return 0;
1756}
1757
1758static int wsa_macro_set_ec_hq(struct snd_kcontrol *kcontrol,
1759 struct snd_ctl_elem_value *ucontrol)
1760{
Meng Wang15c825d2018-09-06 10:49:18 +08001761 struct snd_soc_component *component =
1762 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301763 int ec_tx = ((struct soc_multi_mixer_control *)
1764 kcontrol->private_value)->shift;
1765 int value = ucontrol->value.integer.value[0];
1766 struct device *wsa_dev = NULL;
1767 struct wsa_macro_priv *wsa_priv = NULL;
1768
Meng Wang15c825d2018-09-06 10:49:18 +08001769 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301770 return -EINVAL;
1771
1772 dev_dbg(wsa_dev, "%s: enable current %d, new %d\n",
1773 __func__, wsa_priv->ec_hq[ec_tx], value);
1774 wsa_priv->ec_hq[ec_tx] = value;
1775
1776 return 0;
1777}
1778
Vatsal Buchaf2a71b62019-03-26 16:14:40 +05301779static int wsa_macro_get_rx_mute_status(struct snd_kcontrol *kcontrol,
1780 struct snd_ctl_elem_value *ucontrol)
1781{
1782
1783 struct snd_soc_component *component =
1784 snd_soc_kcontrol_component(kcontrol);
1785 struct device *wsa_dev = NULL;
1786 struct wsa_macro_priv *wsa_priv = NULL;
1787 int wsa_rx_shift = ((struct soc_multi_mixer_control *)
1788 kcontrol->private_value)->shift;
1789
1790 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
1791 return -EINVAL;
1792
1793 ucontrol->value.integer.value[0] =
1794 wsa_priv->wsa_digital_mute_status[wsa_rx_shift];
1795 return 0;
1796}
1797
1798static int wsa_macro_set_rx_mute_status(struct snd_kcontrol *kcontrol,
1799 struct snd_ctl_elem_value *ucontrol)
1800{
1801 struct snd_soc_component *component =
1802 snd_soc_kcontrol_component(kcontrol);
1803 struct device *wsa_dev = NULL;
1804 struct wsa_macro_priv *wsa_priv = NULL;
1805 int value = ucontrol->value.integer.value[0];
1806 int wsa_rx_shift = ((struct soc_multi_mixer_control *)
1807 kcontrol->private_value)->shift;
1808
1809 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
1810 return -EINVAL;
1811
1812 switch (wsa_rx_shift) {
1813 case 0:
1814 snd_soc_component_update_bits(component,
1815 BOLERO_CDC_WSA_RX0_RX_PATH_CTL,
1816 0x10, value << 4);
1817 break;
1818 case 1:
1819 snd_soc_component_update_bits(component,
1820 BOLERO_CDC_WSA_RX1_RX_PATH_CTL,
1821 0x10, value << 4);
1822 break;
1823 case 2:
1824 snd_soc_component_update_bits(component,
1825 BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL,
1826 0x10, value << 4);
1827 break;
1828 case 3:
1829 snd_soc_component_update_bits(component,
1830 BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL,
1831 0x10, value << 4);
1832 break;
1833 default:
1834 pr_err("%s: invalid argument rx_shift = %d\n", __func__,
1835 wsa_rx_shift);
1836 return -EINVAL;
1837 }
1838
1839 dev_dbg(component->dev, "%s: WSA Digital Mute RX %d Enable %d\n",
1840 __func__, wsa_rx_shift, value);
1841 wsa_priv->wsa_digital_mute_status[wsa_rx_shift] = value;
1842 return 0;
1843}
1844
Laxminath Kasam243e2752018-04-12 00:40:19 +05301845static int wsa_macro_get_compander(struct snd_kcontrol *kcontrol,
1846 struct snd_ctl_elem_value *ucontrol)
1847{
1848
Meng Wang15c825d2018-09-06 10:49:18 +08001849 struct snd_soc_component *component =
1850 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301851 int comp = ((struct soc_multi_mixer_control *)
1852 kcontrol->private_value)->shift;
1853 struct device *wsa_dev = NULL;
1854 struct wsa_macro_priv *wsa_priv = NULL;
1855
Meng Wang15c825d2018-09-06 10:49:18 +08001856 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301857 return -EINVAL;
1858
1859 ucontrol->value.integer.value[0] = wsa_priv->comp_enabled[comp];
1860 return 0;
1861}
1862
1863static int wsa_macro_set_compander(struct snd_kcontrol *kcontrol,
1864 struct snd_ctl_elem_value *ucontrol)
1865{
Meng Wang15c825d2018-09-06 10:49:18 +08001866 struct snd_soc_component *component =
1867 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301868 int comp = ((struct soc_multi_mixer_control *)
1869 kcontrol->private_value)->shift;
1870 int value = ucontrol->value.integer.value[0];
1871 struct device *wsa_dev = NULL;
1872 struct wsa_macro_priv *wsa_priv = NULL;
1873
Meng Wang15c825d2018-09-06 10:49:18 +08001874 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301875 return -EINVAL;
1876
Meng Wang15c825d2018-09-06 10:49:18 +08001877 dev_dbg(component->dev, "%s: Compander %d enable current %d, new %d\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301878 __func__, comp + 1, wsa_priv->comp_enabled[comp], value);
1879 wsa_priv->comp_enabled[comp] = value;
1880
1881 return 0;
1882}
1883
1884static int wsa_macro_ear_spkr_pa_gain_get(struct snd_kcontrol *kcontrol,
1885 struct snd_ctl_elem_value *ucontrol)
1886{
Meng Wang15c825d2018-09-06 10:49:18 +08001887 struct snd_soc_component *component =
1888 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301889 struct device *wsa_dev = NULL;
1890 struct wsa_macro_priv *wsa_priv = NULL;
1891
Meng Wang15c825d2018-09-06 10:49:18 +08001892 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301893 return -EINVAL;
1894
1895 ucontrol->value.integer.value[0] = wsa_priv->ear_spkr_gain;
1896
Meng Wang15c825d2018-09-06 10:49:18 +08001897 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301898 __func__, ucontrol->value.integer.value[0]);
1899
1900 return 0;
1901}
1902
1903static int wsa_macro_ear_spkr_pa_gain_put(struct snd_kcontrol *kcontrol,
1904 struct snd_ctl_elem_value *ucontrol)
1905{
Meng Wang15c825d2018-09-06 10:49:18 +08001906 struct snd_soc_component *component =
1907 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301908 struct device *wsa_dev = NULL;
1909 struct wsa_macro_priv *wsa_priv = NULL;
1910
Meng Wang15c825d2018-09-06 10:49:18 +08001911 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301912 return -EINVAL;
1913
1914 wsa_priv->ear_spkr_gain = ucontrol->value.integer.value[0];
1915
Meng Wang15c825d2018-09-06 10:49:18 +08001916 dev_dbg(component->dev, "%s: gain = %d\n", __func__,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301917 wsa_priv->ear_spkr_gain);
1918
1919 return 0;
1920}
1921
1922static int wsa_macro_spkr_left_boost_stage_get(struct snd_kcontrol *kcontrol,
1923 struct snd_ctl_elem_value *ucontrol)
1924{
1925 u8 bst_state_max = 0;
Meng Wang15c825d2018-09-06 10:49:18 +08001926 struct snd_soc_component *component =
1927 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301928
Meng Wang15c825d2018-09-06 10:49:18 +08001929 bst_state_max = snd_soc_component_read32(component,
1930 BOLERO_CDC_WSA_BOOST0_BOOST_CTL);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301931 bst_state_max = (bst_state_max & 0x0c) >> 2;
1932 ucontrol->value.integer.value[0] = bst_state_max;
Meng Wang15c825d2018-09-06 10:49:18 +08001933 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301934 __func__, ucontrol->value.integer.value[0]);
1935
1936 return 0;
1937}
1938
1939static int wsa_macro_spkr_left_boost_stage_put(struct snd_kcontrol *kcontrol,
1940 struct snd_ctl_elem_value *ucontrol)
1941{
1942 u8 bst_state_max;
Meng Wang15c825d2018-09-06 10:49:18 +08001943 struct snd_soc_component *component =
1944 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301945
Meng Wang15c825d2018-09-06 10:49:18 +08001946 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301947 __func__, ucontrol->value.integer.value[0]);
1948 bst_state_max = ucontrol->value.integer.value[0] << 2;
Meng Wang15c825d2018-09-06 10:49:18 +08001949 snd_soc_component_update_bits(component,
1950 BOLERO_CDC_WSA_BOOST0_BOOST_CTL,
1951 0x0c, bst_state_max);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301952
1953 return 0;
1954}
1955
1956static int wsa_macro_spkr_right_boost_stage_get(struct snd_kcontrol *kcontrol,
1957 struct snd_ctl_elem_value *ucontrol)
1958{
1959 u8 bst_state_max = 0;
Meng Wang15c825d2018-09-06 10:49:18 +08001960 struct snd_soc_component *component =
1961 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301962
Meng Wang15c825d2018-09-06 10:49:18 +08001963 bst_state_max = snd_soc_component_read32(component,
1964 BOLERO_CDC_WSA_BOOST1_BOOST_CTL);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301965 bst_state_max = (bst_state_max & 0x0c) >> 2;
1966 ucontrol->value.integer.value[0] = bst_state_max;
Meng Wang15c825d2018-09-06 10:49:18 +08001967 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301968 __func__, ucontrol->value.integer.value[0]);
1969
1970 return 0;
1971}
1972
1973static int wsa_macro_spkr_right_boost_stage_put(struct snd_kcontrol *kcontrol,
1974 struct snd_ctl_elem_value *ucontrol)
1975{
1976 u8 bst_state_max;
Meng Wang15c825d2018-09-06 10:49:18 +08001977 struct snd_soc_component *component =
1978 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301979
Meng Wang15c825d2018-09-06 10:49:18 +08001980 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301981 __func__, ucontrol->value.integer.value[0]);
1982 bst_state_max = ucontrol->value.integer.value[0] << 2;
Meng Wang15c825d2018-09-06 10:49:18 +08001983 snd_soc_component_update_bits(component,
1984 BOLERO_CDC_WSA_BOOST1_BOOST_CTL,
1985 0x0c, bst_state_max);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301986
1987 return 0;
1988}
1989
1990static int wsa_macro_rx_mux_get(struct snd_kcontrol *kcontrol,
1991 struct snd_ctl_elem_value *ucontrol)
1992{
1993 struct snd_soc_dapm_widget *widget =
1994 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +08001995 struct snd_soc_component *component =
1996 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301997 struct device *wsa_dev = NULL;
1998 struct wsa_macro_priv *wsa_priv = NULL;
1999
Meng Wang15c825d2018-09-06 10:49:18 +08002000 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302001 return -EINVAL;
2002
2003 ucontrol->value.integer.value[0] =
2004 wsa_priv->rx_port_value[widget->shift];
2005 return 0;
2006}
2007
2008static int wsa_macro_rx_mux_put(struct snd_kcontrol *kcontrol,
2009 struct snd_ctl_elem_value *ucontrol)
2010{
2011 struct snd_soc_dapm_widget *widget =
2012 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +08002013 struct snd_soc_component *component =
2014 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302015 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
2016 struct snd_soc_dapm_update *update = NULL;
2017 u32 rx_port_value = ucontrol->value.integer.value[0];
2018 u32 bit_input = 0;
2019 u32 aif_rst;
2020 struct device *wsa_dev = NULL;
2021 struct wsa_macro_priv *wsa_priv = NULL;
2022
Meng Wang15c825d2018-09-06 10:49:18 +08002023 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302024 return -EINVAL;
2025
2026 aif_rst = wsa_priv->rx_port_value[widget->shift];
2027 if (!rx_port_value) {
2028 if (aif_rst == 0) {
2029 dev_err(wsa_dev, "%s: AIF reset already\n", __func__);
2030 return 0;
2031 }
2032 }
2033 wsa_priv->rx_port_value[widget->shift] = rx_port_value;
2034
2035 bit_input = widget->shift;
2036 if (widget->shift >= WSA_MACRO_RX_MIX)
2037 bit_input %= WSA_MACRO_RX_MIX;
2038
2039 switch (rx_port_value) {
2040 case 0:
2041 clear_bit(bit_input,
Laxminath Kasam59c7a1d2018-08-09 16:11:17 +05302042 &wsa_priv->active_ch_mask[aif_rst]);
2043 wsa_priv->active_ch_cnt[aif_rst]--;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302044 break;
2045 case 1:
2046 case 2:
2047 set_bit(bit_input,
Laxminath Kasam59c7a1d2018-08-09 16:11:17 +05302048 &wsa_priv->active_ch_mask[rx_port_value]);
2049 wsa_priv->active_ch_cnt[rx_port_value]++;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302050 break;
2051 default:
2052 dev_err(wsa_dev,
2053 "%s: Invalid AIF_ID for WSA RX MUX\n", __func__);
2054 return -EINVAL;
2055 }
2056
2057 snd_soc_dapm_mux_update_power(widget->dapm, kcontrol,
2058 rx_port_value, e, update);
2059 return 0;
2060}
2061
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302062static int wsa_macro_vbat_bcl_gsm_mode_func_get(struct snd_kcontrol *kcontrol,
2063 struct snd_ctl_elem_value *ucontrol)
2064{
Meng Wang15c825d2018-09-06 10:49:18 +08002065 struct snd_soc_component *component =
2066 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302067
2068 ucontrol->value.integer.value[0] =
Meng Wang15c825d2018-09-06 10:49:18 +08002069 ((snd_soc_component_read32(
2070 component, BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG) & 0x04) ?
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302071 1 : 0);
2072
Meng Wang15c825d2018-09-06 10:49:18 +08002073 dev_dbg(component->dev, "%s: value: %lu\n", __func__,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302074 ucontrol->value.integer.value[0]);
2075
2076 return 0;
2077}
2078
2079static int wsa_macro_vbat_bcl_gsm_mode_func_put(struct snd_kcontrol *kcontrol,
2080 struct snd_ctl_elem_value *ucontrol)
2081{
Meng Wang15c825d2018-09-06 10:49:18 +08002082 struct snd_soc_component *component =
2083 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302084
Meng Wang15c825d2018-09-06 10:49:18 +08002085 dev_dbg(component->dev, "%s: value: %lu\n", __func__,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302086 ucontrol->value.integer.value[0]);
2087
2088 /* Set Vbat register configuration for GSM mode bit based on value */
2089 if (ucontrol->value.integer.value[0])
Meng Wang15c825d2018-09-06 10:49:18 +08002090 snd_soc_component_update_bits(component,
2091 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG,
2092 0x04, 0x04);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302093 else
Meng Wang15c825d2018-09-06 10:49:18 +08002094 snd_soc_component_update_bits(component,
2095 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG,
2096 0x04, 0x00);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302097
2098 return 0;
2099}
2100
2101static int wsa_macro_soft_clip_enable_get(struct snd_kcontrol *kcontrol,
2102 struct snd_ctl_elem_value *ucontrol)
2103{
Meng Wang15c825d2018-09-06 10:49:18 +08002104 struct snd_soc_component *component =
2105 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302106 struct device *wsa_dev = NULL;
2107 struct wsa_macro_priv *wsa_priv = NULL;
2108 int path = ((struct soc_multi_mixer_control *)
2109 kcontrol->private_value)->shift;
2110
Meng Wang15c825d2018-09-06 10:49:18 +08002111 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302112 return -EINVAL;
2113
2114 ucontrol->value.integer.value[0] = wsa_priv->is_softclip_on[path];
2115
Meng Wang15c825d2018-09-06 10:49:18 +08002116 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302117 __func__, ucontrol->value.integer.value[0]);
2118
2119 return 0;
2120}
2121
2122static int wsa_macro_soft_clip_enable_put(struct snd_kcontrol *kcontrol,
2123 struct snd_ctl_elem_value *ucontrol)
2124{
Meng Wang15c825d2018-09-06 10:49:18 +08002125 struct snd_soc_component *component =
2126 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302127 struct device *wsa_dev = NULL;
2128 struct wsa_macro_priv *wsa_priv = NULL;
2129 int path = ((struct soc_multi_mixer_control *)
2130 kcontrol->private_value)->shift;
2131
Meng Wang15c825d2018-09-06 10:49:18 +08002132 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302133 return -EINVAL;
2134
2135 wsa_priv->is_softclip_on[path] = ucontrol->value.integer.value[0];
2136
Meng Wang15c825d2018-09-06 10:49:18 +08002137 dev_dbg(component->dev, "%s: soft clip enable for %d: %d\n", __func__,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302138 path, wsa_priv->is_softclip_on[path]);
2139
2140 return 0;
2141}
2142
Laxminath Kasam243e2752018-04-12 00:40:19 +05302143static const struct snd_kcontrol_new wsa_macro_snd_controls[] = {
2144 SOC_ENUM_EXT("EAR SPKR PA Gain", wsa_macro_ear_spkr_pa_gain_enum,
2145 wsa_macro_ear_spkr_pa_gain_get,
2146 wsa_macro_ear_spkr_pa_gain_put),
2147 SOC_ENUM_EXT("SPKR Left Boost Max State",
2148 wsa_macro_spkr_boost_stage_enum,
2149 wsa_macro_spkr_left_boost_stage_get,
2150 wsa_macro_spkr_left_boost_stage_put),
2151 SOC_ENUM_EXT("SPKR Right Boost Max State",
2152 wsa_macro_spkr_boost_stage_enum,
2153 wsa_macro_spkr_right_boost_stage_get,
2154 wsa_macro_spkr_right_boost_stage_put),
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302155 SOC_ENUM_EXT("GSM mode Enable", wsa_macro_vbat_bcl_gsm_mode_enum,
2156 wsa_macro_vbat_bcl_gsm_mode_func_get,
2157 wsa_macro_vbat_bcl_gsm_mode_func_put),
2158 SOC_SINGLE_EXT("WSA_Softclip0 Enable", SND_SOC_NOPM,
2159 WSA_MACRO_SOFTCLIP0, 1, 0,
2160 wsa_macro_soft_clip_enable_get,
2161 wsa_macro_soft_clip_enable_put),
2162 SOC_SINGLE_EXT("WSA_Softclip1 Enable", SND_SOC_NOPM,
2163 WSA_MACRO_SOFTCLIP1, 1, 0,
2164 wsa_macro_soft_clip_enable_get,
2165 wsa_macro_soft_clip_enable_put),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302166 SOC_SINGLE_SX_TLV("WSA_RX0 Digital Volume",
2167 BOLERO_CDC_WSA_RX0_RX_VOL_CTL,
2168 0, -84, 40, digital_gain),
2169 SOC_SINGLE_SX_TLV("WSA_RX1 Digital Volume",
2170 BOLERO_CDC_WSA_RX1_RX_VOL_CTL,
2171 0, -84, 40, digital_gain),
Vatsal Buchaf2a71b62019-03-26 16:14:40 +05302172 SOC_SINGLE_EXT("WSA_RX0 Digital Mute", SND_SOC_NOPM, WSA_MACRO_RX0, 1,
2173 0, wsa_macro_get_rx_mute_status,
2174 wsa_macro_set_rx_mute_status),
2175 SOC_SINGLE_EXT("WSA_RX1 Digital Mute", SND_SOC_NOPM, WSA_MACRO_RX1, 1,
2176 0, wsa_macro_get_rx_mute_status,
2177 wsa_macro_set_rx_mute_status),
2178 SOC_SINGLE_EXT("WSA_RX0_MIX Digital Mute", SND_SOC_NOPM,
2179 WSA_MACRO_RX_MIX0, 1, 0, wsa_macro_get_rx_mute_status,
2180 wsa_macro_set_rx_mute_status),
2181 SOC_SINGLE_EXT("WSA_RX1_MIX Digital Mute", SND_SOC_NOPM,
2182 WSA_MACRO_RX_MIX1, 1, 0, wsa_macro_get_rx_mute_status,
2183 wsa_macro_set_rx_mute_status),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302184 SOC_SINGLE_EXT("WSA_COMP1 Switch", SND_SOC_NOPM, WSA_MACRO_COMP1, 1, 0,
2185 wsa_macro_get_compander, wsa_macro_set_compander),
2186 SOC_SINGLE_EXT("WSA_COMP2 Switch", SND_SOC_NOPM, WSA_MACRO_COMP2, 1, 0,
2187 wsa_macro_get_compander, wsa_macro_set_compander),
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05302188 SOC_SINGLE_EXT("WSA_RX0 EC_HQ Switch", SND_SOC_NOPM, WSA_MACRO_RX0,
2189 1, 0, wsa_macro_get_ec_hq, wsa_macro_set_ec_hq),
2190 SOC_SINGLE_EXT("WSA_RX1 EC_HQ Switch", SND_SOC_NOPM, WSA_MACRO_RX1,
2191 1, 0, wsa_macro_get_ec_hq, wsa_macro_set_ec_hq),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302192};
2193
2194static const struct soc_enum rx_mux_enum =
2195 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_mux_text), rx_mux_text);
2196
2197static const struct snd_kcontrol_new rx_mux[WSA_MACRO_RX_MAX] = {
2198 SOC_DAPM_ENUM_EXT("WSA RX0 Mux", rx_mux_enum,
2199 wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),
2200 SOC_DAPM_ENUM_EXT("WSA RX1 Mux", rx_mux_enum,
2201 wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),
2202 SOC_DAPM_ENUM_EXT("WSA RX_MIX0 Mux", rx_mux_enum,
2203 wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),
2204 SOC_DAPM_ENUM_EXT("WSA RX_MIX1 Mux", rx_mux_enum,
2205 wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),
2206};
2207
2208static int wsa_macro_vi_feed_mixer_get(struct snd_kcontrol *kcontrol,
2209 struct snd_ctl_elem_value *ucontrol)
2210{
2211 struct snd_soc_dapm_widget *widget =
2212 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +08002213 struct snd_soc_component *component =
2214 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302215 struct soc_multi_mixer_control *mixer =
2216 ((struct soc_multi_mixer_control *)kcontrol->private_value);
2217 u32 dai_id = widget->shift;
2218 u32 spk_tx_id = mixer->shift;
2219 struct device *wsa_dev = NULL;
2220 struct wsa_macro_priv *wsa_priv = NULL;
2221
Meng Wang15c825d2018-09-06 10:49:18 +08002222 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302223 return -EINVAL;
2224
2225 if (test_bit(spk_tx_id, &wsa_priv->active_ch_mask[dai_id]))
2226 ucontrol->value.integer.value[0] = 1;
2227 else
2228 ucontrol->value.integer.value[0] = 0;
2229
2230 return 0;
2231}
2232
2233static int wsa_macro_vi_feed_mixer_put(struct snd_kcontrol *kcontrol,
2234 struct snd_ctl_elem_value *ucontrol)
2235{
2236 struct snd_soc_dapm_widget *widget =
2237 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +08002238 struct snd_soc_component *component =
2239 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302240 struct soc_multi_mixer_control *mixer =
2241 ((struct soc_multi_mixer_control *)kcontrol->private_value);
2242 u32 spk_tx_id = mixer->shift;
2243 u32 enable = ucontrol->value.integer.value[0];
2244 struct device *wsa_dev = NULL;
2245 struct wsa_macro_priv *wsa_priv = NULL;
2246
Meng Wang15c825d2018-09-06 10:49:18 +08002247 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302248 return -EINVAL;
2249
2250 wsa_priv->vi_feed_value = ucontrol->value.integer.value[0];
2251
2252 if (enable) {
2253 if (spk_tx_id == WSA_MACRO_TX0 &&
2254 !test_bit(WSA_MACRO_TX0,
2255 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
2256 set_bit(WSA_MACRO_TX0,
2257 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI]);
2258 wsa_priv->active_ch_cnt[WSA_MACRO_AIF_VI]++;
2259 }
2260 if (spk_tx_id == WSA_MACRO_TX1 &&
2261 !test_bit(WSA_MACRO_TX1,
2262 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
2263 set_bit(WSA_MACRO_TX1,
2264 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI]);
2265 wsa_priv->active_ch_cnt[WSA_MACRO_AIF_VI]++;
2266 }
2267 } else {
2268 if (spk_tx_id == WSA_MACRO_TX0 &&
2269 test_bit(WSA_MACRO_TX0,
2270 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
2271 clear_bit(WSA_MACRO_TX0,
2272 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI]);
2273 wsa_priv->active_ch_cnt[WSA_MACRO_AIF_VI]--;
2274 }
2275 if (spk_tx_id == WSA_MACRO_TX1 &&
2276 test_bit(WSA_MACRO_TX1,
2277 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
2278 clear_bit(WSA_MACRO_TX1,
2279 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI]);
2280 wsa_priv->active_ch_cnt[WSA_MACRO_AIF_VI]--;
2281 }
2282 }
2283 snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, NULL);
2284
2285 return 0;
2286}
2287
2288static const struct snd_kcontrol_new aif_vi_mixer[] = {
2289 SOC_SINGLE_EXT("WSA_SPKR_VI_1", SND_SOC_NOPM, WSA_MACRO_TX0, 1, 0,
2290 wsa_macro_vi_feed_mixer_get,
2291 wsa_macro_vi_feed_mixer_put),
2292 SOC_SINGLE_EXT("WSA_SPKR_VI_2", SND_SOC_NOPM, WSA_MACRO_TX1, 1, 0,
2293 wsa_macro_vi_feed_mixer_get,
2294 wsa_macro_vi_feed_mixer_put),
2295};
2296
2297static const struct snd_soc_dapm_widget wsa_macro_dapm_widgets[] = {
2298 SND_SOC_DAPM_AIF_IN("WSA AIF1 PB", "WSA_AIF1 Playback", 0,
2299 SND_SOC_NOPM, 0, 0),
2300
2301 SND_SOC_DAPM_AIF_IN("WSA AIF_MIX1 PB", "WSA_AIF_MIX1 Playback", 0,
2302 SND_SOC_NOPM, 0, 0),
2303
2304 SND_SOC_DAPM_AIF_OUT_E("WSA AIF_VI", "WSA_AIF_VI Capture", 0,
2305 SND_SOC_NOPM, WSA_MACRO_AIF_VI, 0,
2306 wsa_macro_enable_vi_feedback,
2307 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
2308
2309 SND_SOC_DAPM_AIF_OUT("WSA AIF_ECHO", "WSA_AIF_ECHO Capture", 0,
2310 SND_SOC_NOPM, 0, 0),
2311
2312 SND_SOC_DAPM_MIXER("WSA_AIF_VI Mixer", SND_SOC_NOPM, WSA_MACRO_AIF_VI,
2313 0, aif_vi_mixer, ARRAY_SIZE(aif_vi_mixer)),
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05302314 SND_SOC_DAPM_MUX_E("WSA RX_MIX EC0_MUX", SND_SOC_NOPM,
2315 WSA_MACRO_EC0_MUX, 0,
2316 &rx_mix_ec0_mux, wsa_macro_enable_echo,
2317 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2318 SND_SOC_DAPM_MUX_E("WSA RX_MIX EC1_MUX", SND_SOC_NOPM,
2319 WSA_MACRO_EC1_MUX, 0,
2320 &rx_mix_ec1_mux, wsa_macro_enable_echo,
2321 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302322
2323 SND_SOC_DAPM_MUX("WSA RX0 MUX", SND_SOC_NOPM, WSA_MACRO_RX0, 0,
2324 &rx_mux[WSA_MACRO_RX0]),
2325 SND_SOC_DAPM_MUX("WSA RX1 MUX", SND_SOC_NOPM, WSA_MACRO_RX1, 0,
2326 &rx_mux[WSA_MACRO_RX1]),
2327 SND_SOC_DAPM_MUX("WSA RX_MIX0 MUX", SND_SOC_NOPM, WSA_MACRO_RX_MIX0, 0,
2328 &rx_mux[WSA_MACRO_RX_MIX0]),
2329 SND_SOC_DAPM_MUX("WSA RX_MIX1 MUX", SND_SOC_NOPM, WSA_MACRO_RX_MIX1, 0,
2330 &rx_mux[WSA_MACRO_RX_MIX1]),
2331
2332 SND_SOC_DAPM_MIXER("WSA RX0", SND_SOC_NOPM, 0, 0, NULL, 0),
2333 SND_SOC_DAPM_MIXER("WSA RX1", SND_SOC_NOPM, 0, 0, NULL, 0),
2334 SND_SOC_DAPM_MIXER("WSA RX_MIX0", SND_SOC_NOPM, 0, 0, NULL, 0),
2335 SND_SOC_DAPM_MIXER("WSA RX_MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
2336
2337 SND_SOC_DAPM_MUX_E("WSA_RX0 INP0", SND_SOC_NOPM, 0, 0,
2338 &rx0_prim_inp0_mux, wsa_macro_enable_swr,
2339 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2340 SND_SOC_DAPM_MUX_E("WSA_RX0 INP1", SND_SOC_NOPM, 0, 0,
2341 &rx0_prim_inp1_mux, wsa_macro_enable_swr,
2342 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2343 SND_SOC_DAPM_MUX_E("WSA_RX0 INP2", SND_SOC_NOPM, 0, 0,
2344 &rx0_prim_inp2_mux, wsa_macro_enable_swr,
2345 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2346 SND_SOC_DAPM_MUX_E("WSA_RX0 MIX INP", SND_SOC_NOPM, 0, 0,
2347 &rx0_mix_mux, wsa_macro_enable_mix_path,
2348 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2349 SND_SOC_DAPM_MUX_E("WSA_RX1 INP0", SND_SOC_NOPM, 0, 0,
2350 &rx1_prim_inp0_mux, wsa_macro_enable_swr,
2351 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2352 SND_SOC_DAPM_MUX_E("WSA_RX1 INP1", SND_SOC_NOPM, 0, 0,
2353 &rx1_prim_inp1_mux, wsa_macro_enable_swr,
2354 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2355 SND_SOC_DAPM_MUX_E("WSA_RX1 INP2", SND_SOC_NOPM, 0, 0,
2356 &rx1_prim_inp2_mux, wsa_macro_enable_swr,
2357 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2358 SND_SOC_DAPM_MUX_E("WSA_RX1 MIX INP", SND_SOC_NOPM, 0, 0,
2359 &rx1_mix_mux, wsa_macro_enable_mix_path,
2360 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2361 SND_SOC_DAPM_MIXER("WSA_RX INT0 MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
2362 SND_SOC_DAPM_MIXER("WSA_RX INT1 MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
2363 SND_SOC_DAPM_MIXER("WSA_RX INT0 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
2364 SND_SOC_DAPM_MIXER("WSA_RX INT1 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
2365
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302366 SND_SOC_DAPM_MUX_E("WSA_RX0 INT0 SIDETONE MIX",
2367 BOLERO_CDC_WSA_RX0_RX_PATH_CFG1, 4, 0,
2368 &rx0_sidetone_mix_mux, wsa_macro_enable_swr,
2369 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2370 SND_SOC_DAPM_INPUT("WSA SRC0_INP"),
2371
2372 SND_SOC_DAPM_INPUT("WSA_TX DEC0_INP"),
2373 SND_SOC_DAPM_INPUT("WSA_TX DEC1_INP"),
2374
Laxminath Kasam243e2752018-04-12 00:40:19 +05302375 SND_SOC_DAPM_MIXER_E("WSA_RX INT0 INTERP", SND_SOC_NOPM,
2376 WSA_MACRO_COMP1, 0, NULL, 0, wsa_macro_enable_interpolator,
2377 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2378 SND_SOC_DAPM_POST_PMD),
2379 SND_SOC_DAPM_MIXER_E("WSA_RX INT1 INTERP", SND_SOC_NOPM,
2380 WSA_MACRO_COMP2, 0, NULL, 0, wsa_macro_enable_interpolator,
2381 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2382 SND_SOC_DAPM_POST_PMD),
2383
2384 SND_SOC_DAPM_MIXER_E("WSA_RX INT0 CHAIN", SND_SOC_NOPM, 0, 0,
2385 NULL, 0, wsa_macro_spk_boost_event,
Laxminath Kasam0c857002018-07-17 23:47:17 +05302386 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2387 SND_SOC_DAPM_POST_PMD),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302388 SND_SOC_DAPM_MIXER_E("WSA_RX INT1 CHAIN", SND_SOC_NOPM, 0, 0,
2389 NULL, 0, wsa_macro_spk_boost_event,
Laxminath Kasam0c857002018-07-17 23:47:17 +05302390 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2391 SND_SOC_DAPM_POST_PMD),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302392
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302393 SND_SOC_DAPM_MIXER_E("WSA_RX INT0 VBAT", SND_SOC_NOPM,
2394 0, 0, wsa_int0_vbat_mix_switch,
2395 ARRAY_SIZE(wsa_int0_vbat_mix_switch),
2396 wsa_macro_enable_vbat,
2397 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2398 SND_SOC_DAPM_MIXER_E("WSA_RX INT1 VBAT", SND_SOC_NOPM,
2399 0, 0, wsa_int1_vbat_mix_switch,
2400 ARRAY_SIZE(wsa_int1_vbat_mix_switch),
2401 wsa_macro_enable_vbat,
2402 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2403
Laxminath Kasam243e2752018-04-12 00:40:19 +05302404 SND_SOC_DAPM_INPUT("VIINPUT_WSA"),
2405
2406 SND_SOC_DAPM_OUTPUT("WSA_SPK1 OUT"),
2407 SND_SOC_DAPM_OUTPUT("WSA_SPK2 OUT"),
2408
2409 SND_SOC_DAPM_SUPPLY_S("WSA_MCLK", 0, SND_SOC_NOPM, 0, 0,
2410 wsa_macro_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2411};
2412
2413static const struct snd_soc_dapm_route wsa_audio_map[] = {
2414 /* VI Feedback */
2415 {"WSA_AIF_VI Mixer", "WSA_SPKR_VI_1", "VIINPUT_WSA"},
2416 {"WSA_AIF_VI Mixer", "WSA_SPKR_VI_2", "VIINPUT_WSA"},
2417 {"WSA AIF_VI", NULL, "WSA_AIF_VI Mixer"},
2418 {"WSA AIF_VI", NULL, "WSA_MCLK"},
2419
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05302420 {"WSA RX_MIX EC0_MUX", "RX_MIX_TX0", "WSA_RX INT0 SEC MIX"},
2421 {"WSA RX_MIX EC1_MUX", "RX_MIX_TX0", "WSA_RX INT0 SEC MIX"},
2422 {"WSA RX_MIX EC0_MUX", "RX_MIX_TX1", "WSA_RX INT1 SEC MIX"},
2423 {"WSA RX_MIX EC1_MUX", "RX_MIX_TX1", "WSA_RX INT1 SEC MIX"},
2424 {"WSA AIF_ECHO", NULL, "WSA RX_MIX EC0_MUX"},
2425 {"WSA AIF_ECHO", NULL, "WSA RX_MIX EC1_MUX"},
2426 {"WSA AIF_ECHO", NULL, "WSA_MCLK"},
2427
Laxminath Kasam243e2752018-04-12 00:40:19 +05302428 {"WSA AIF1 PB", NULL, "WSA_MCLK"},
2429 {"WSA AIF_MIX1 PB", NULL, "WSA_MCLK"},
2430
2431 {"WSA RX0 MUX", "AIF1_PB", "WSA AIF1 PB"},
2432 {"WSA RX1 MUX", "AIF1_PB", "WSA AIF1 PB"},
2433 {"WSA RX_MIX0 MUX", "AIF1_PB", "WSA AIF1 PB"},
2434 {"WSA RX_MIX1 MUX", "AIF1_PB", "WSA AIF1 PB"},
2435
2436 {"WSA RX0 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
2437 {"WSA RX1 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
2438 {"WSA RX_MIX0 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
2439 {"WSA RX_MIX1 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
2440
2441 {"WSA RX0", NULL, "WSA RX0 MUX"},
2442 {"WSA RX1", NULL, "WSA RX1 MUX"},
2443 {"WSA RX_MIX0", NULL, "WSA RX_MIX0 MUX"},
2444 {"WSA RX_MIX1", NULL, "WSA RX_MIX1 MUX"},
2445
2446 {"WSA_RX0 INP0", "RX0", "WSA RX0"},
2447 {"WSA_RX0 INP0", "RX1", "WSA RX1"},
2448 {"WSA_RX0 INP0", "RX_MIX0", "WSA RX_MIX0"},
2449 {"WSA_RX0 INP0", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302450 {"WSA_RX0 INP0", "DEC0", "WSA_TX DEC0_INP"},
2451 {"WSA_RX0 INP0", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302452 {"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP0"},
2453
2454 {"WSA_RX0 INP1", "RX0", "WSA RX0"},
2455 {"WSA_RX0 INP1", "RX1", "WSA RX1"},
2456 {"WSA_RX0 INP1", "RX_MIX0", "WSA RX_MIX0"},
2457 {"WSA_RX0 INP1", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302458 {"WSA_RX0 INP1", "DEC0", "WSA_TX DEC0_INP"},
2459 {"WSA_RX0 INP1", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302460 {"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP1"},
2461
2462 {"WSA_RX0 INP2", "RX0", "WSA RX0"},
2463 {"WSA_RX0 INP2", "RX1", "WSA RX1"},
2464 {"WSA_RX0 INP2", "RX_MIX0", "WSA RX_MIX0"},
2465 {"WSA_RX0 INP2", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302466 {"WSA_RX0 INP2", "DEC0", "WSA_TX DEC0_INP"},
2467 {"WSA_RX0 INP2", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302468 {"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP2"},
2469
2470 {"WSA_RX0 MIX INP", "RX0", "WSA RX0"},
2471 {"WSA_RX0 MIX INP", "RX1", "WSA RX1"},
2472 {"WSA_RX0 MIX INP", "RX_MIX0", "WSA RX_MIX0"},
2473 {"WSA_RX0 MIX INP", "RX_MIX1", "WSA RX_MIX1"},
2474 {"WSA_RX INT0 SEC MIX", NULL, "WSA_RX0 MIX INP"},
2475
2476 {"WSA_RX INT0 SEC MIX", NULL, "WSA_RX INT0 MIX"},
2477 {"WSA_RX INT0 INTERP", NULL, "WSA_RX INT0 SEC MIX"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302478 {"WSA_RX0 INT0 SIDETONE MIX", "SRC0", "WSA SRC0_INP"},
2479 {"WSA_RX INT0 INTERP", NULL, "WSA_RX0 INT0 SIDETONE MIX"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302480 {"WSA_RX INT0 CHAIN", NULL, "WSA_RX INT0 INTERP"},
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302481
2482 {"WSA_RX INT0 VBAT", "WSA RX0 VBAT Enable", "WSA_RX INT0 INTERP"},
2483 {"WSA_RX INT0 CHAIN", NULL, "WSA_RX INT0 VBAT"},
2484
Laxminath Kasam243e2752018-04-12 00:40:19 +05302485 {"WSA_SPK1 OUT", NULL, "WSA_RX INT0 CHAIN"},
Laxminath Kasamfc281ad2018-08-06 20:19:40 +05302486 {"WSA_SPK1 OUT", NULL, "WSA_MCLK"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302487
2488 {"WSA_RX1 INP0", "RX0", "WSA RX0"},
2489 {"WSA_RX1 INP0", "RX1", "WSA RX1"},
2490 {"WSA_RX1 INP0", "RX_MIX0", "WSA RX_MIX0"},
2491 {"WSA_RX1 INP0", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302492 {"WSA_RX1 INP0", "DEC0", "WSA_TX DEC0_INP"},
2493 {"WSA_RX1 INP0", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302494 {"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP0"},
2495
2496 {"WSA_RX1 INP1", "RX0", "WSA RX0"},
2497 {"WSA_RX1 INP1", "RX1", "WSA RX1"},
2498 {"WSA_RX1 INP1", "RX_MIX0", "WSA RX_MIX0"},
2499 {"WSA_RX1 INP1", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302500 {"WSA_RX1 INP1", "DEC0", "WSA_TX DEC0_INP"},
2501 {"WSA_RX1 INP1", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302502 {"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP1"},
2503
2504 {"WSA_RX1 INP2", "RX0", "WSA RX0"},
2505 {"WSA_RX1 INP2", "RX1", "WSA RX1"},
2506 {"WSA_RX1 INP2", "RX_MIX0", "WSA RX_MIX0"},
2507 {"WSA_RX1 INP2", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302508 {"WSA_RX1 INP2", "DEC0", "WSA_TX DEC0_INP"},
2509 {"WSA_RX1 INP2", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302510 {"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP2"},
2511
2512 {"WSA_RX1 MIX INP", "RX0", "WSA RX0"},
2513 {"WSA_RX1 MIX INP", "RX1", "WSA RX1"},
2514 {"WSA_RX1 MIX INP", "RX_MIX0", "WSA RX_MIX0"},
2515 {"WSA_RX1 MIX INP", "RX_MIX1", "WSA RX_MIX1"},
2516 {"WSA_RX INT1 SEC MIX", NULL, "WSA_RX1 MIX INP"},
2517
2518 {"WSA_RX INT1 SEC MIX", NULL, "WSA_RX INT1 MIX"},
2519 {"WSA_RX INT1 INTERP", NULL, "WSA_RX INT1 SEC MIX"},
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302520
2521 {"WSA_RX INT1 VBAT", "WSA RX1 VBAT Enable", "WSA_RX INT1 INTERP"},
2522 {"WSA_RX INT1 CHAIN", NULL, "WSA_RX INT1 VBAT"},
2523
Laxminath Kasam243e2752018-04-12 00:40:19 +05302524 {"WSA_RX INT1 CHAIN", NULL, "WSA_RX INT1 INTERP"},
2525 {"WSA_SPK2 OUT", NULL, "WSA_RX INT1 CHAIN"},
Laxminath Kasamfc281ad2018-08-06 20:19:40 +05302526 {"WSA_SPK2 OUT", NULL, "WSA_MCLK"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302527};
2528
2529static const struct wsa_macro_reg_mask_val wsa_macro_reg_init[] = {
2530 {BOLERO_CDC_WSA_BOOST0_BOOST_CFG1, 0x3F, 0x12},
2531 {BOLERO_CDC_WSA_BOOST0_BOOST_CFG2, 0x1C, 0x08},
2532 {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x1E, 0x18},
2533 {BOLERO_CDC_WSA_BOOST1_BOOST_CFG1, 0x3F, 0x12},
2534 {BOLERO_CDC_WSA_BOOST1_BOOST_CFG2, 0x1C, 0x08},
2535 {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x1E, 0x18},
2536 {BOLERO_CDC_WSA_BOOST0_BOOST_CTL, 0x70, 0x58},
2537 {BOLERO_CDC_WSA_BOOST1_BOOST_CTL, 0x70, 0x58},
2538 {BOLERO_CDC_WSA_RX0_RX_PATH_CFG1, 0x08, 0x08},
2539 {BOLERO_CDC_WSA_RX1_RX_PATH_CFG1, 0x08, 0x08},
2540 {BOLERO_CDC_WSA_TOP_TOP_CFG1, 0x02, 0x02},
2541 {BOLERO_CDC_WSA_TOP_TOP_CFG1, 0x01, 0x01},
2542 {BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
2543 {BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
2544 {BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
2545 {BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
2546 {BOLERO_CDC_WSA_COMPANDER0_CTL3, 0x80, 0x80},
2547 {BOLERO_CDC_WSA_COMPANDER1_CTL3, 0x80, 0x80},
2548 {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x01, 0x01},
2549 {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x01, 0x01},
2550 {BOLERO_CDC_WSA_RX0_RX_PATH_CFG0, 0x01, 0x01},
2551 {BOLERO_CDC_WSA_RX1_RX_PATH_CFG0, 0x01, 0x01},
2552 {BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CFG, 0x01, 0x01},
2553 {BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CFG, 0x01, 0x01},
2554};
2555
Meng Wang15c825d2018-09-06 10:49:18 +08002556static void wsa_macro_init_bcl_pmic_reg(struct snd_soc_component *component)
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302557{
2558 struct device *wsa_dev = NULL;
2559 struct wsa_macro_priv *wsa_priv = NULL;
2560
Meng Wang15c825d2018-09-06 10:49:18 +08002561 if (!component) {
2562 pr_err("%s: NULL component pointer!\n", __func__);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302563 return;
2564 }
2565
Meng Wang15c825d2018-09-06 10:49:18 +08002566 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302567 return;
2568
2569 switch (wsa_priv->bcl_pmic_params.id) {
2570 case 0:
2571 /* Enable ID0 to listen to respective PMIC group interrupts */
Meng Wang15c825d2018-09-06 10:49:18 +08002572 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302573 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CTL1, 0x02, 0x02);
2574 /* Update MC_SID0 */
Meng Wang15c825d2018-09-06 10:49:18 +08002575 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302576 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG1, 0x0F,
2577 wsa_priv->bcl_pmic_params.sid);
2578 /* Update MC_PPID0 */
Meng Wang15c825d2018-09-06 10:49:18 +08002579 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302580 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG2, 0xFF,
2581 wsa_priv->bcl_pmic_params.ppid);
2582 break;
2583 case 1:
2584 /* Enable ID1 to listen to respective PMIC group interrupts */
Meng Wang15c825d2018-09-06 10:49:18 +08002585 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302586 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CTL1, 0x01, 0x01);
2587 /* Update MC_SID1 */
Meng Wang15c825d2018-09-06 10:49:18 +08002588 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302589 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG3, 0x0F,
2590 wsa_priv->bcl_pmic_params.sid);
2591 /* Update MC_PPID1 */
Meng Wang15c825d2018-09-06 10:49:18 +08002592 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302593 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG4, 0xFF,
2594 wsa_priv->bcl_pmic_params.ppid);
2595 break;
2596 default:
2597 dev_err(wsa_dev, "%s: PMIC ID is invalid %d\n",
2598 __func__, wsa_priv->bcl_pmic_params.id);
2599 break;
2600 }
2601}
2602
Meng Wang15c825d2018-09-06 10:49:18 +08002603static void wsa_macro_init_reg(struct snd_soc_component *component)
Laxminath Kasam243e2752018-04-12 00:40:19 +05302604{
2605 int i;
2606
2607 for (i = 0; i < ARRAY_SIZE(wsa_macro_reg_init); i++)
Meng Wang15c825d2018-09-06 10:49:18 +08002608 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302609 wsa_macro_reg_init[i].reg,
2610 wsa_macro_reg_init[i].mask,
2611 wsa_macro_reg_init[i].val);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302612
Meng Wang15c825d2018-09-06 10:49:18 +08002613 wsa_macro_init_bcl_pmic_reg(component);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302614}
2615
2616static int wsa_swrm_clock(void *handle, bool enable)
2617{
2618 struct wsa_macro_priv *wsa_priv = (struct wsa_macro_priv *) handle;
2619 struct regmap *regmap = dev_get_regmap(wsa_priv->dev->parent, NULL);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302620 int ret = 0;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302621
Tanya Dixitab8eba82018-10-05 15:07:37 +05302622 if (regmap == NULL) {
2623 dev_err(wsa_priv->dev, "%s: regmap is NULL\n", __func__);
2624 return -EINVAL;
2625 }
2626
Laxminath Kasam243e2752018-04-12 00:40:19 +05302627 mutex_lock(&wsa_priv->swr_clk_lock);
2628
2629 dev_dbg(wsa_priv->dev, "%s: swrm clock %s\n",
2630 __func__, (enable ? "enable" : "disable"));
2631 if (enable) {
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302632 pm_runtime_get_sync(wsa_priv->dev);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302633 if (wsa_priv->swr_clk_users == 0) {
Karthikeyan Mani01f1ba42019-02-26 18:48:15 -08002634 msm_cdc_pinctrl_select_active_state(
2635 wsa_priv->wsa_swr_gpio_p);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302636 ret = wsa_macro_mclk_enable(wsa_priv, 1, true);
2637 if (ret < 0) {
Karthikeyan Mani01f1ba42019-02-26 18:48:15 -08002638 msm_cdc_pinctrl_select_sleep_state(
2639 wsa_priv->wsa_swr_gpio_p);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302640 dev_err(wsa_priv->dev,
2641 "%s: wsa request clock enable failed\n",
2642 __func__);
2643 goto exit;
2644 }
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05302645 if (wsa_priv->reset_swr)
2646 regmap_update_bits(regmap,
2647 BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
2648 0x02, 0x02);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302649 regmap_update_bits(regmap,
2650 BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
2651 0x01, 0x01);
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05302652 if (wsa_priv->reset_swr)
2653 regmap_update_bits(regmap,
2654 BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
2655 0x02, 0x00);
2656 wsa_priv->reset_swr = false;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302657 }
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302658 pm_runtime_mark_last_busy(wsa_priv->dev);
2659 pm_runtime_put_autosuspend(wsa_priv->dev);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302660 wsa_priv->swr_clk_users++;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302661 } else {
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302662 if (wsa_priv->swr_clk_users <= 0) {
2663 dev_err(wsa_priv->dev, "%s: clock already disabled\n",
2664 __func__);
2665 wsa_priv->swr_clk_users = 0;
2666 goto exit;
2667 }
Laxminath Kasam243e2752018-04-12 00:40:19 +05302668 wsa_priv->swr_clk_users--;
2669 if (wsa_priv->swr_clk_users == 0) {
2670 regmap_update_bits(regmap,
2671 BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
2672 0x01, 0x00);
Karthikeyan Mani01f1ba42019-02-26 18:48:15 -08002673 wsa_macro_mclk_enable(wsa_priv, 0, true);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302674 msm_cdc_pinctrl_select_sleep_state(
2675 wsa_priv->wsa_swr_gpio_p);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302676 }
2677 }
2678 dev_dbg(wsa_priv->dev, "%s: swrm clock users %d\n",
2679 __func__, wsa_priv->swr_clk_users);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302680exit:
Laxminath Kasam243e2752018-04-12 00:40:19 +05302681 mutex_unlock(&wsa_priv->swr_clk_lock);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302682 return ret;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302683}
2684
Meng Wang15c825d2018-09-06 10:49:18 +08002685static int wsa_macro_init(struct snd_soc_component *component)
Laxminath Kasam243e2752018-04-12 00:40:19 +05302686{
Meng Wang15c825d2018-09-06 10:49:18 +08002687 struct snd_soc_dapm_context *dapm =
2688 snd_soc_component_get_dapm(component);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302689 int ret;
2690 struct device *wsa_dev = NULL;
2691 struct wsa_macro_priv *wsa_priv = NULL;
2692
Meng Wang15c825d2018-09-06 10:49:18 +08002693 wsa_dev = bolero_get_device_ptr(component->dev, WSA_MACRO);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302694 if (!wsa_dev) {
Meng Wang15c825d2018-09-06 10:49:18 +08002695 dev_err(component->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302696 "%s: null device for macro!\n", __func__);
2697 return -EINVAL;
2698 }
2699 wsa_priv = dev_get_drvdata(wsa_dev);
2700 if (!wsa_priv) {
Meng Wang15c825d2018-09-06 10:49:18 +08002701 dev_err(component->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302702 "%s: priv is null for macro!\n", __func__);
2703 return -EINVAL;
2704 }
2705
2706 ret = snd_soc_dapm_new_controls(dapm, wsa_macro_dapm_widgets,
2707 ARRAY_SIZE(wsa_macro_dapm_widgets));
2708 if (ret < 0) {
2709 dev_err(wsa_dev, "%s: Failed to add controls\n", __func__);
2710 return ret;
2711 }
2712
2713 ret = snd_soc_dapm_add_routes(dapm, wsa_audio_map,
2714 ARRAY_SIZE(wsa_audio_map));
2715 if (ret < 0) {
2716 dev_err(wsa_dev, "%s: Failed to add routes\n", __func__);
2717 return ret;
2718 }
2719
2720 ret = snd_soc_dapm_new_widgets(dapm->card);
2721 if (ret < 0) {
2722 dev_err(wsa_dev, "%s: Failed to add widgets\n", __func__);
2723 return ret;
2724 }
2725
Meng Wang15c825d2018-09-06 10:49:18 +08002726 ret = snd_soc_add_component_controls(component, wsa_macro_snd_controls,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302727 ARRAY_SIZE(wsa_macro_snd_controls));
2728 if (ret < 0) {
2729 dev_err(wsa_dev, "%s: Failed to add snd_ctls\n", __func__);
2730 return ret;
2731 }
Laxminath Kasam638b5602018-09-24 13:19:52 +05302732 snd_soc_dapm_ignore_suspend(dapm, "WSA_AIF1 Playback");
2733 snd_soc_dapm_ignore_suspend(dapm, "WSA_AIF_MIX1 Playback");
2734 snd_soc_dapm_ignore_suspend(dapm, "WSA_AIF_VI Capture");
2735 snd_soc_dapm_ignore_suspend(dapm, "WSA_AIF_ECHO Capture");
2736 snd_soc_dapm_ignore_suspend(dapm, "WSA_SPK1 OUT");
2737 snd_soc_dapm_ignore_suspend(dapm, "WSA_SPK2 OUT");
2738 snd_soc_dapm_ignore_suspend(dapm, "VIINPUT_WSA");
2739 snd_soc_dapm_ignore_suspend(dapm, "WSA SRC0_INP");
2740 snd_soc_dapm_ignore_suspend(dapm, "WSA_TX DEC0_INP");
2741 snd_soc_dapm_ignore_suspend(dapm, "WSA_TX DEC1_INP");
2742 snd_soc_dapm_sync(dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302743
Meng Wang15c825d2018-09-06 10:49:18 +08002744 wsa_priv->component = component;
Laxminath Kasam21c8b222018-06-21 18:47:22 +05302745 wsa_priv->spkr_gain_offset = WSA_MACRO_GAIN_OFFSET_0_DB;
Meng Wang15c825d2018-09-06 10:49:18 +08002746 wsa_macro_init_reg(component);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302747
2748 return 0;
2749}
2750
Meng Wang15c825d2018-09-06 10:49:18 +08002751static int wsa_macro_deinit(struct snd_soc_component *component)
Laxminath Kasam243e2752018-04-12 00:40:19 +05302752{
2753 struct device *wsa_dev = NULL;
2754 struct wsa_macro_priv *wsa_priv = NULL;
2755
Meng Wang15c825d2018-09-06 10:49:18 +08002756 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302757 return -EINVAL;
2758
Meng Wang15c825d2018-09-06 10:49:18 +08002759 wsa_priv->component = NULL;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302760
2761 return 0;
2762}
2763
2764static void wsa_macro_add_child_devices(struct work_struct *work)
2765{
2766 struct wsa_macro_priv *wsa_priv;
2767 struct platform_device *pdev;
2768 struct device_node *node;
2769 struct wsa_macro_swr_ctrl_data *swr_ctrl_data = NULL, *temp;
2770 int ret;
2771 u16 count = 0, ctrl_num = 0;
2772 struct wsa_macro_swr_ctrl_platform_data *platdata;
2773 char plat_dev_name[WSA_MACRO_SWR_STRING_LEN];
2774
2775 wsa_priv = container_of(work, struct wsa_macro_priv,
2776 wsa_macro_add_child_devices_work);
2777 if (!wsa_priv) {
2778 pr_err("%s: Memory for wsa_priv does not exist\n",
2779 __func__);
2780 return;
2781 }
Laxminath Kasam21c8b222018-06-21 18:47:22 +05302782 if (!wsa_priv->dev || !wsa_priv->dev->of_node) {
Laxminath Kasam243e2752018-04-12 00:40:19 +05302783 dev_err(wsa_priv->dev,
2784 "%s: DT node for wsa_priv does not exist\n", __func__);
2785 return;
2786 }
2787
2788 platdata = &wsa_priv->swr_plat_data;
2789 wsa_priv->child_count = 0;
2790
2791 for_each_available_child_of_node(wsa_priv->dev->of_node, node) {
2792 if (strnstr(node->name, "wsa_swr_master",
2793 strlen("wsa_swr_master")) != NULL)
2794 strlcpy(plat_dev_name, "wsa_swr_ctrl",
2795 (WSA_MACRO_SWR_STRING_LEN - 1));
2796 else if (strnstr(node->name, "msm_cdc_pinctrl",
2797 strlen("msm_cdc_pinctrl")) != NULL)
2798 strlcpy(plat_dev_name, node->name,
2799 (WSA_MACRO_SWR_STRING_LEN - 1));
2800 else
2801 continue;
2802
2803 pdev = platform_device_alloc(plat_dev_name, -1);
2804 if (!pdev) {
2805 dev_err(wsa_priv->dev, "%s: pdev memory alloc failed\n",
2806 __func__);
2807 ret = -ENOMEM;
2808 goto err;
2809 }
2810 pdev->dev.parent = wsa_priv->dev;
2811 pdev->dev.of_node = node;
2812
2813 if (strnstr(node->name, "wsa_swr_master",
2814 strlen("wsa_swr_master")) != NULL) {
2815 ret = platform_device_add_data(pdev, platdata,
2816 sizeof(*platdata));
2817 if (ret) {
2818 dev_err(&pdev->dev,
2819 "%s: cannot add plat data ctrl:%d\n",
2820 __func__, ctrl_num);
2821 goto fail_pdev_add;
2822 }
2823 }
2824
2825 ret = platform_device_add(pdev);
2826 if (ret) {
2827 dev_err(&pdev->dev,
2828 "%s: Cannot add platform device\n",
2829 __func__);
2830 goto fail_pdev_add;
2831 }
2832
2833 if (!strcmp(node->name, "wsa_swr_master")) {
2834 temp = krealloc(swr_ctrl_data,
2835 (ctrl_num + 1) * sizeof(
2836 struct wsa_macro_swr_ctrl_data),
2837 GFP_KERNEL);
2838 if (!temp) {
2839 dev_err(&pdev->dev, "out of memory\n");
2840 ret = -ENOMEM;
2841 goto err;
2842 }
2843 swr_ctrl_data = temp;
2844 swr_ctrl_data[ctrl_num].wsa_swr_pdev = pdev;
2845 ctrl_num++;
2846 dev_dbg(&pdev->dev,
2847 "%s: Added soundwire ctrl device(s)\n",
2848 __func__);
2849 wsa_priv->swr_ctrl_data = swr_ctrl_data;
2850 }
2851 if (wsa_priv->child_count < WSA_MACRO_CHILD_DEVICES_MAX)
2852 wsa_priv->pdev_child_devices[
2853 wsa_priv->child_count++] = pdev;
2854 else
2855 goto err;
2856 }
2857
2858 return;
2859fail_pdev_add:
2860 for (count = 0; count < wsa_priv->child_count; count++)
2861 platform_device_put(wsa_priv->pdev_child_devices[count]);
2862err:
2863 return;
2864}
2865
2866static void wsa_macro_init_ops(struct macro_ops *ops,
2867 char __iomem *wsa_io_base)
2868{
2869 memset(ops, 0, sizeof(struct macro_ops));
2870 ops->init = wsa_macro_init;
2871 ops->exit = wsa_macro_deinit;
2872 ops->io_base = wsa_io_base;
2873 ops->dai_ptr = wsa_macro_dai;
2874 ops->num_dais = ARRAY_SIZE(wsa_macro_dai);
Laxminath Kasamfb0d6832018-09-22 01:49:52 +05302875 ops->event_handler = wsa_macro_event_handler;
Sudheer Papothia3e969d2018-10-27 06:22:10 +05302876 ops->set_port_map = wsa_macro_set_port_map;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302877}
2878
2879static int wsa_macro_probe(struct platform_device *pdev)
2880{
2881 struct macro_ops ops;
2882 struct wsa_macro_priv *wsa_priv;
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07002883 u32 wsa_base_addr, default_clk_id;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302884 char __iomem *wsa_io_base;
2885 int ret = 0;
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302886 u8 bcl_pmic_params[3];
Laxminath Kasam243e2752018-04-12 00:40:19 +05302887
2888 wsa_priv = devm_kzalloc(&pdev->dev, sizeof(struct wsa_macro_priv),
2889 GFP_KERNEL);
2890 if (!wsa_priv)
2891 return -ENOMEM;
2892
2893 wsa_priv->dev = &pdev->dev;
2894 ret = of_property_read_u32(pdev->dev.of_node, "reg",
2895 &wsa_base_addr);
2896 if (ret) {
2897 dev_err(&pdev->dev, "%s: could not find %s entry in dt\n",
2898 __func__, "reg");
2899 return ret;
2900 }
2901 wsa_priv->wsa_swr_gpio_p = of_parse_phandle(pdev->dev.of_node,
2902 "qcom,wsa-swr-gpios", 0);
2903 if (!wsa_priv->wsa_swr_gpio_p) {
2904 dev_err(&pdev->dev, "%s: swr_gpios handle not provided!\n",
2905 __func__);
2906 return -EINVAL;
2907 }
2908 wsa_io_base = devm_ioremap(&pdev->dev,
2909 wsa_base_addr, WSA_MACRO_MAX_OFFSET);
2910 if (!wsa_io_base) {
2911 dev_err(&pdev->dev, "%s: ioremap failed\n", __func__);
2912 return -EINVAL;
2913 }
2914 wsa_priv->wsa_io_base = wsa_io_base;
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05302915 wsa_priv->reset_swr = true;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302916 INIT_WORK(&wsa_priv->wsa_macro_add_child_devices_work,
2917 wsa_macro_add_child_devices);
2918 wsa_priv->swr_plat_data.handle = (void *) wsa_priv;
2919 wsa_priv->swr_plat_data.read = NULL;
2920 wsa_priv->swr_plat_data.write = NULL;
2921 wsa_priv->swr_plat_data.bulk_write = NULL;
2922 wsa_priv->swr_plat_data.clk = wsa_swrm_clock;
2923 wsa_priv->swr_plat_data.handle_irq = NULL;
2924
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07002925 ret = of_property_read_u32(pdev->dev.of_node, "qcom,default-clk-id",
2926 &default_clk_id);
2927 if (ret) {
2928 dev_err(&pdev->dev, "%s: could not find %s entry in dt\n",
2929 __func__, "qcom,mux0-clk-id");
2930 default_clk_id = WSA_CORE_CLK;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302931 }
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302932
2933 ret = of_property_read_u8_array(pdev->dev.of_node,
2934 "qcom,wsa-bcl-pmic-params", bcl_pmic_params,
2935 sizeof(bcl_pmic_params));
2936 if (ret) {
2937 dev_dbg(&pdev->dev, "%s: could not find %s entry in dt\n",
2938 __func__, "qcom,wsa-bcl-pmic-params");
2939 } else {
2940 wsa_priv->bcl_pmic_params.id = bcl_pmic_params[0];
2941 wsa_priv->bcl_pmic_params.sid = bcl_pmic_params[1];
2942 wsa_priv->bcl_pmic_params.ppid = bcl_pmic_params[2];
2943 }
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07002944 wsa_priv->default_clk_id = default_clk_id;
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302945
Laxminath Kasam243e2752018-04-12 00:40:19 +05302946 dev_set_drvdata(&pdev->dev, wsa_priv);
2947 mutex_init(&wsa_priv->mclk_lock);
2948 mutex_init(&wsa_priv->swr_clk_lock);
2949 wsa_macro_init_ops(&ops, wsa_io_base);
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07002950 ops.clk_id_req = wsa_priv->default_clk_id;
2951 ops.default_clk_id = wsa_priv->default_clk_id;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302952 ret = bolero_register_macro(&pdev->dev, WSA_MACRO, &ops);
2953 if (ret < 0) {
2954 dev_err(&pdev->dev, "%s: register macro failed\n", __func__);
2955 goto reg_macro_fail;
2956 }
2957 schedule_work(&wsa_priv->wsa_macro_add_child_devices_work);
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302958 pm_runtime_set_autosuspend_delay(&pdev->dev, AUTO_SUSPEND_DELAY);
2959 pm_runtime_use_autosuspend(&pdev->dev);
2960 pm_runtime_set_suspended(&pdev->dev);
2961 pm_runtime_enable(&pdev->dev);
2962
Laxminath Kasam243e2752018-04-12 00:40:19 +05302963 return ret;
2964reg_macro_fail:
2965 mutex_destroy(&wsa_priv->mclk_lock);
2966 mutex_destroy(&wsa_priv->swr_clk_lock);
2967 return ret;
2968}
2969
2970static int wsa_macro_remove(struct platform_device *pdev)
2971{
2972 struct wsa_macro_priv *wsa_priv;
2973 u16 count = 0;
2974
2975 wsa_priv = dev_get_drvdata(&pdev->dev);
2976
2977 if (!wsa_priv)
2978 return -EINVAL;
2979
2980 for (count = 0; count < wsa_priv->child_count &&
2981 count < WSA_MACRO_CHILD_DEVICES_MAX; count++)
2982 platform_device_unregister(wsa_priv->pdev_child_devices[count]);
2983
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302984 pm_runtime_disable(&pdev->dev);
2985 pm_runtime_set_suspended(&pdev->dev);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302986 bolero_unregister_macro(&pdev->dev, WSA_MACRO);
2987 mutex_destroy(&wsa_priv->mclk_lock);
2988 mutex_destroy(&wsa_priv->swr_clk_lock);
2989 return 0;
2990}
2991
2992static const struct of_device_id wsa_macro_dt_match[] = {
2993 {.compatible = "qcom,wsa-macro"},
2994 {}
2995};
2996
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302997static const struct dev_pm_ops bolero_dev_pm_ops = {
2998 SET_RUNTIME_PM_OPS(
2999 bolero_runtime_suspend,
3000 bolero_runtime_resume,
3001 NULL
3002 )
3003};
3004
Laxminath Kasam243e2752018-04-12 00:40:19 +05303005static struct platform_driver wsa_macro_driver = {
3006 .driver = {
3007 .name = "wsa_macro",
3008 .owner = THIS_MODULE,
Sudheer Papothi7601cc62019-03-30 03:00:52 +05303009 .pm = &bolero_dev_pm_ops,
Laxminath Kasam243e2752018-04-12 00:40:19 +05303010 .of_match_table = wsa_macro_dt_match,
3011 },
3012 .probe = wsa_macro_probe,
3013 .remove = wsa_macro_remove,
3014};
3015
3016module_platform_driver(wsa_macro_driver);
3017
3018MODULE_DESCRIPTION("WSA macro driver");
3019MODULE_LICENSE("GPL v2");