blob: c8a5e1d68291b1db15c8ee50180bbf505a9d2fbc [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;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530223};
224
Meng Wang15c825d2018-09-06 10:49:18 +0800225static int wsa_macro_config_ear_spkr_gain(struct snd_soc_component *component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530226 struct wsa_macro_priv *wsa_priv,
227 int event, int gain_reg);
228static struct snd_soc_dai_driver wsa_macro_dai[];
229static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0);
230
231static const char *const rx_text[] = {
232 "ZERO", "RX0", "RX1", "RX_MIX0", "RX_MIX1", "DEC0", "DEC1"
233};
234
235static const char *const rx_mix_text[] = {
236 "ZERO", "RX0", "RX1", "RX_MIX0", "RX_MIX1"
237};
238
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +0530239static const char *const rx_mix_ec_text[] = {
240 "ZERO", "RX_MIX_TX0", "RX_MIX_TX1"
241};
242
Laxminath Kasam243e2752018-04-12 00:40:19 +0530243static const char *const rx_mux_text[] = {
244 "ZERO", "AIF1_PB", "AIF_MIX1_PB"
245};
246
Laxminath Kasam6fc2e742018-08-26 23:32:57 +0530247static const char *const rx_sidetone_mix_text[] = {
248 "ZERO", "SRC0"
249};
250
Laxminath Kasam243e2752018-04-12 00:40:19 +0530251static const char * const wsa_macro_ear_spkr_pa_gain_text[] = {
252 "G_DEFAULT", "G_0_DB", "G_1_DB", "G_2_DB", "G_3_DB",
253 "G_4_DB", "G_5_DB", "G_6_DB"
254};
255
256static const char * const wsa_macro_speaker_boost_stage_text[] = {
257 "NO_MAX_STATE", "MAX_STATE_1", "MAX_STATE_2"
258};
259
Aditya Bavanari4f3d5642018-09-18 22:19:10 +0530260static const char * const wsa_macro_vbat_bcl_gsm_mode_text[] = {
261 "OFF", "ON"
262};
263
264static const struct snd_kcontrol_new wsa_int0_vbat_mix_switch[] = {
265 SOC_DAPM_SINGLE("WSA RX0 VBAT Enable", SND_SOC_NOPM, 0, 1, 0)
266};
267
268static const struct snd_kcontrol_new wsa_int1_vbat_mix_switch[] = {
269 SOC_DAPM_SINGLE("WSA RX1 VBAT Enable", SND_SOC_NOPM, 0, 1, 0)
270};
271
Laxminath Kasam243e2752018-04-12 00:40:19 +0530272static SOC_ENUM_SINGLE_EXT_DECL(wsa_macro_ear_spkr_pa_gain_enum,
273 wsa_macro_ear_spkr_pa_gain_text);
274static SOC_ENUM_SINGLE_EXT_DECL(wsa_macro_spkr_boost_stage_enum,
275 wsa_macro_speaker_boost_stage_text);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +0530276static SOC_ENUM_SINGLE_EXT_DECL(wsa_macro_vbat_bcl_gsm_mode_enum,
277 wsa_macro_vbat_bcl_gsm_mode_text);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530278
279/* RX INT0 */
280static const struct soc_enum rx0_prim_inp0_chain_enum =
281 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0,
282 0, 7, rx_text);
283
284static const struct soc_enum rx0_prim_inp1_chain_enum =
285 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0,
286 3, 7, rx_text);
287
288static const struct soc_enum rx0_prim_inp2_chain_enum =
289 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG1,
290 3, 7, rx_text);
291
292static const struct soc_enum rx0_mix_chain_enum =
293 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG1,
294 0, 5, rx_mix_text);
295
Laxminath Kasam6fc2e742018-08-26 23:32:57 +0530296static const struct soc_enum rx0_sidetone_mix_enum =
297 SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, 2, rx_sidetone_mix_text);
298
Laxminath Kasam243e2752018-04-12 00:40:19 +0530299static const struct snd_kcontrol_new rx0_prim_inp0_mux =
300 SOC_DAPM_ENUM("WSA_RX0 INP0 Mux", rx0_prim_inp0_chain_enum);
301
302static const struct snd_kcontrol_new rx0_prim_inp1_mux =
303 SOC_DAPM_ENUM("WSA_RX0 INP1 Mux", rx0_prim_inp1_chain_enum);
304
305static const struct snd_kcontrol_new rx0_prim_inp2_mux =
306 SOC_DAPM_ENUM("WSA_RX0 INP2 Mux", rx0_prim_inp2_chain_enum);
307
308static const struct snd_kcontrol_new rx0_mix_mux =
309 SOC_DAPM_ENUM("WSA_RX0 MIX Mux", rx0_mix_chain_enum);
310
Laxminath Kasam6fc2e742018-08-26 23:32:57 +0530311static const struct snd_kcontrol_new rx0_sidetone_mix_mux =
312 SOC_DAPM_ENUM("WSA_RX0 SIDETONE MIX Mux", rx0_sidetone_mix_enum);
313
Laxminath Kasam243e2752018-04-12 00:40:19 +0530314/* RX INT1 */
315static const struct soc_enum rx1_prim_inp0_chain_enum =
316 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT1_CFG0,
317 0, 7, rx_text);
318
319static const struct soc_enum rx1_prim_inp1_chain_enum =
320 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT1_CFG0,
321 3, 7, rx_text);
322
323static const struct soc_enum rx1_prim_inp2_chain_enum =
324 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT1_CFG1,
325 3, 7, rx_text);
326
327static const struct soc_enum rx1_mix_chain_enum =
328 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT1_CFG1,
329 0, 5, rx_mix_text);
330
331static const struct snd_kcontrol_new rx1_prim_inp0_mux =
332 SOC_DAPM_ENUM("WSA_RX1 INP0 Mux", rx1_prim_inp0_chain_enum);
333
334static const struct snd_kcontrol_new rx1_prim_inp1_mux =
335 SOC_DAPM_ENUM("WSA_RX1 INP1 Mux", rx1_prim_inp1_chain_enum);
336
337static const struct snd_kcontrol_new rx1_prim_inp2_mux =
338 SOC_DAPM_ENUM("WSA_RX1 INP2 Mux", rx1_prim_inp2_chain_enum);
339
340static const struct snd_kcontrol_new rx1_mix_mux =
341 SOC_DAPM_ENUM("WSA_RX1 MIX Mux", rx1_mix_chain_enum);
342
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +0530343static const struct soc_enum rx_mix_ec0_enum =
344 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0,
345 0, 3, rx_mix_ec_text);
346
347static const struct soc_enum rx_mix_ec1_enum =
348 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0,
349 3, 3, rx_mix_ec_text);
350
351static const struct snd_kcontrol_new rx_mix_ec0_mux =
352 SOC_DAPM_ENUM("WSA RX_MIX EC0_Mux", rx_mix_ec0_enum);
353
354static const struct snd_kcontrol_new rx_mix_ec1_mux =
355 SOC_DAPM_ENUM("WSA RX_MIX EC1_Mux", rx_mix_ec1_enum);
356
Laxminath Kasam243e2752018-04-12 00:40:19 +0530357static struct snd_soc_dai_ops wsa_macro_dai_ops = {
358 .hw_params = wsa_macro_hw_params,
359 .get_channel_map = wsa_macro_get_channel_map,
360};
361
362static struct snd_soc_dai_driver wsa_macro_dai[] = {
363 {
364 .name = "wsa_macro_rx1",
365 .id = WSA_MACRO_AIF1_PB,
366 .playback = {
367 .stream_name = "WSA_AIF1 Playback",
368 .rates = WSA_MACRO_RX_RATES,
369 .formats = WSA_MACRO_RX_FORMATS,
370 .rate_max = 384000,
371 .rate_min = 8000,
372 .channels_min = 1,
373 .channels_max = 2,
374 },
375 .ops = &wsa_macro_dai_ops,
376 },
377 {
378 .name = "wsa_macro_rx_mix",
379 .id = WSA_MACRO_AIF_MIX1_PB,
380 .playback = {
381 .stream_name = "WSA_AIF_MIX1 Playback",
382 .rates = WSA_MACRO_RX_MIX_RATES,
383 .formats = WSA_MACRO_RX_FORMATS,
384 .rate_max = 192000,
385 .rate_min = 48000,
386 .channels_min = 1,
387 .channels_max = 2,
388 },
389 .ops = &wsa_macro_dai_ops,
390 },
391 {
392 .name = "wsa_macro_vifeedback",
393 .id = WSA_MACRO_AIF_VI,
394 .capture = {
395 .stream_name = "WSA_AIF_VI Capture",
Vatsal Buchad1b694d2018-08-31 11:47:32 +0530396 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000,
397 .formats = WSA_MACRO_RX_FORMATS,
398 .rate_max = 48000,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530399 .rate_min = 8000,
400 .channels_min = 1,
Vatsal Buchad1b694d2018-08-31 11:47:32 +0530401 .channels_max = 4,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530402 },
403 .ops = &wsa_macro_dai_ops,
404 },
405 {
406 .name = "wsa_macro_echo",
407 .id = WSA_MACRO_AIF_ECHO,
408 .capture = {
409 .stream_name = "WSA_AIF_ECHO Capture",
410 .rates = WSA_MACRO_ECHO_RATES,
411 .formats = WSA_MACRO_ECHO_FORMATS,
412 .rate_max = 48000,
413 .rate_min = 8000,
414 .channels_min = 1,
415 .channels_max = 2,
416 },
417 .ops = &wsa_macro_dai_ops,
418 },
419};
420
421static const struct wsa_macro_reg_mask_val wsa_macro_spkr_default[] = {
422 {BOLERO_CDC_WSA_COMPANDER0_CTL3, 0x80, 0x80},
423 {BOLERO_CDC_WSA_COMPANDER1_CTL3, 0x80, 0x80},
424 {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x01, 0x01},
425 {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x01, 0x01},
426 {BOLERO_CDC_WSA_BOOST0_BOOST_CTL, 0x7C, 0x58},
427 {BOLERO_CDC_WSA_BOOST1_BOOST_CTL, 0x7C, 0x58},
428};
429
430static const struct wsa_macro_reg_mask_val wsa_macro_spkr_mode1[] = {
431 {BOLERO_CDC_WSA_COMPANDER0_CTL3, 0x80, 0x00},
432 {BOLERO_CDC_WSA_COMPANDER1_CTL3, 0x80, 0x00},
433 {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x01, 0x00},
434 {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x01, 0x00},
435 {BOLERO_CDC_WSA_BOOST0_BOOST_CTL, 0x7C, 0x44},
436 {BOLERO_CDC_WSA_BOOST1_BOOST_CTL, 0x7C, 0x44},
437};
438
Meng Wang15c825d2018-09-06 10:49:18 +0800439static bool wsa_macro_get_data(struct snd_soc_component *component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530440 struct device **wsa_dev,
441 struct wsa_macro_priv **wsa_priv,
442 const char *func_name)
443{
Meng Wang15c825d2018-09-06 10:49:18 +0800444 *wsa_dev = bolero_get_device_ptr(component->dev, WSA_MACRO);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530445 if (!(*wsa_dev)) {
Meng Wang15c825d2018-09-06 10:49:18 +0800446 dev_err(component->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530447 "%s: null device for macro!\n", func_name);
448 return false;
449 }
450 *wsa_priv = dev_get_drvdata((*wsa_dev));
Meng Wang15c825d2018-09-06 10:49:18 +0800451 if (!(*wsa_priv) || !(*wsa_priv)->component) {
452 dev_err(component->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530453 "%s: priv is null for macro!\n", func_name);
454 return false;
455 }
456 return true;
457}
458
Sudheer Papothia3e969d2018-10-27 06:22:10 +0530459static int wsa_macro_set_port_map(struct snd_soc_component *component,
460 u32 usecase, u32 size, void *data)
461{
462 struct device *wsa_dev = NULL;
463 struct wsa_macro_priv *wsa_priv = NULL;
464 struct swrm_port_config port_cfg;
465 int ret = 0;
466
467 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
468 return -EINVAL;
469
470 memset(&port_cfg, 0, sizeof(port_cfg));
471 port_cfg.uc = usecase;
472 port_cfg.size = size;
473 port_cfg.params = data;
474
475 ret = swrm_wcd_notify(
476 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
477 SWR_SET_PORT_MAP, &port_cfg);
478
479 return ret;
480}
481
Laxminath Kasam243e2752018-04-12 00:40:19 +0530482/**
483 * wsa_macro_set_spkr_gain_offset - offset the speaker path
484 * gain with the given offset value.
485 *
Meng Wang15c825d2018-09-06 10:49:18 +0800486 * @component: codec instance
Laxminath Kasam243e2752018-04-12 00:40:19 +0530487 * @offset: Indicates speaker path gain offset value.
488 *
489 * Returns 0 on success or -EINVAL on error.
490 */
Meng Wang15c825d2018-09-06 10:49:18 +0800491int wsa_macro_set_spkr_gain_offset(struct snd_soc_component *component,
492 int offset)
Laxminath Kasam243e2752018-04-12 00:40:19 +0530493{
494 struct device *wsa_dev = NULL;
495 struct wsa_macro_priv *wsa_priv = NULL;
496
Meng Wang15c825d2018-09-06 10:49:18 +0800497 if (!component) {
498 pr_err("%s: NULL component pointer!\n", __func__);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530499 return -EINVAL;
500 }
501
Meng Wang15c825d2018-09-06 10:49:18 +0800502 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530503 return -EINVAL;
504
505 wsa_priv->spkr_gain_offset = offset;
506 return 0;
507}
508EXPORT_SYMBOL(wsa_macro_set_spkr_gain_offset);
509
510/**
511 * wsa_macro_set_spkr_mode - Configures speaker compander and smartboost
512 * settings based on speaker mode.
513 *
Meng Wang15c825d2018-09-06 10:49:18 +0800514 * @component: codec instance
Laxminath Kasam243e2752018-04-12 00:40:19 +0530515 * @mode: Indicates speaker configuration mode.
516 *
517 * Returns 0 on success or -EINVAL on error.
518 */
Meng Wang15c825d2018-09-06 10:49:18 +0800519int wsa_macro_set_spkr_mode(struct snd_soc_component *component, int mode)
Laxminath Kasam243e2752018-04-12 00:40:19 +0530520{
521 int i;
522 const struct wsa_macro_reg_mask_val *regs;
523 int size;
524 struct device *wsa_dev = NULL;
525 struct wsa_macro_priv *wsa_priv = NULL;
526
Meng Wang15c825d2018-09-06 10:49:18 +0800527 if (!component) {
Laxminath Kasam243e2752018-04-12 00:40:19 +0530528 pr_err("%s: NULL codec pointer!\n", __func__);
529 return -EINVAL;
530 }
531
Meng Wang15c825d2018-09-06 10:49:18 +0800532 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530533 return -EINVAL;
534
535 switch (mode) {
Laxminath Kasam21c8b222018-06-21 18:47:22 +0530536 case WSA_MACRO_SPKR_MODE_1:
Laxminath Kasam243e2752018-04-12 00:40:19 +0530537 regs = wsa_macro_spkr_mode1;
538 size = ARRAY_SIZE(wsa_macro_spkr_mode1);
539 break;
540 default:
541 regs = wsa_macro_spkr_default;
542 size = ARRAY_SIZE(wsa_macro_spkr_default);
543 break;
544 }
545
546 wsa_priv->spkr_mode = mode;
547 for (i = 0; i < size; i++)
Meng Wang15c825d2018-09-06 10:49:18 +0800548 snd_soc_component_update_bits(component, regs[i].reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530549 regs[i].mask, regs[i].val);
550 return 0;
551}
552EXPORT_SYMBOL(wsa_macro_set_spkr_mode);
553
554static int wsa_macro_set_prim_interpolator_rate(struct snd_soc_dai *dai,
555 u8 int_prim_fs_rate_reg_val,
556 u32 sample_rate)
557{
558 u8 int_1_mix1_inp;
559 u32 j, port;
560 u16 int_mux_cfg0, int_mux_cfg1;
561 u16 int_fs_reg;
562 u8 int_mux_cfg0_val, int_mux_cfg1_val;
563 u8 inp0_sel, inp1_sel, inp2_sel;
Meng Wang15c825d2018-09-06 10:49:18 +0800564 struct snd_soc_component *component = dai->component;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530565 struct device *wsa_dev = NULL;
566 struct wsa_macro_priv *wsa_priv = NULL;
567
Meng Wang15c825d2018-09-06 10:49:18 +0800568 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530569 return -EINVAL;
570
571 for_each_set_bit(port, &wsa_priv->active_ch_mask[dai->id],
572 WSA_MACRO_RX_MAX) {
573 int_1_mix1_inp = port;
574 if ((int_1_mix1_inp < WSA_MACRO_RX0) ||
575 (int_1_mix1_inp > WSA_MACRO_RX_MIX1)) {
576 dev_err(wsa_dev,
577 "%s: Invalid RX port, Dai ID is %d\n",
578 __func__, dai->id);
579 return -EINVAL;
580 }
581
582 int_mux_cfg0 = BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0;
583
584 /*
585 * Loop through all interpolator MUX inputs and find out
586 * to which interpolator input, the cdc_dma rx port
587 * is connected
588 */
589 for (j = 0; j < NUM_INTERPOLATORS; j++) {
590 int_mux_cfg1 = int_mux_cfg0 + WSA_MACRO_MUX_CFG1_OFFSET;
591
Meng Wang15c825d2018-09-06 10:49:18 +0800592 int_mux_cfg0_val = snd_soc_component_read32(component,
593 int_mux_cfg0);
594 int_mux_cfg1_val = snd_soc_component_read32(component,
595 int_mux_cfg1);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530596 inp0_sel = int_mux_cfg0_val & WSA_MACRO_MUX_INP_MASK1;
597 inp1_sel = (int_mux_cfg0_val >>
598 WSA_MACRO_MUX_INP_SHFT) &
599 WSA_MACRO_MUX_INP_MASK2;
600 inp2_sel = (int_mux_cfg1_val >>
601 WSA_MACRO_MUX_INP_SHFT) &
602 WSA_MACRO_MUX_INP_MASK2;
603 if ((inp0_sel == int_1_mix1_inp) ||
604 (inp1_sel == int_1_mix1_inp) ||
605 (inp2_sel == int_1_mix1_inp)) {
606 int_fs_reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL +
607 WSA_MACRO_RX_PATH_OFFSET * j;
608 dev_dbg(wsa_dev,
609 "%s: AIF_PB DAI(%d) connected to INT%u_1\n",
610 __func__, dai->id, j);
611 dev_dbg(wsa_dev,
612 "%s: set INT%u_1 sample rate to %u\n",
613 __func__, j, sample_rate);
614 /* sample_rate is in Hz */
Meng Wang15c825d2018-09-06 10:49:18 +0800615 snd_soc_component_update_bits(component,
616 int_fs_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530617 WSA_MACRO_FS_RATE_MASK,
618 int_prim_fs_rate_reg_val);
619 }
620 int_mux_cfg0 += WSA_MACRO_MUX_CFG_OFFSET;
621 }
622 }
623
624 return 0;
625}
626
627static int wsa_macro_set_mix_interpolator_rate(struct snd_soc_dai *dai,
628 u8 int_mix_fs_rate_reg_val,
629 u32 sample_rate)
630{
631 u8 int_2_inp;
632 u32 j, port;
633 u16 int_mux_cfg1, int_fs_reg;
634 u8 int_mux_cfg1_val;
Meng Wang15c825d2018-09-06 10:49:18 +0800635 struct snd_soc_component *component = dai->component;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530636 struct device *wsa_dev = NULL;
637 struct wsa_macro_priv *wsa_priv = NULL;
638
Meng Wang15c825d2018-09-06 10:49:18 +0800639 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530640 return -EINVAL;
641
642
643 for_each_set_bit(port, &wsa_priv->active_ch_mask[dai->id],
644 WSA_MACRO_RX_MAX) {
645 int_2_inp = port;
646 if ((int_2_inp < WSA_MACRO_RX0) ||
647 (int_2_inp > WSA_MACRO_RX_MIX1)) {
648 dev_err(wsa_dev,
649 "%s: Invalid RX port, Dai ID is %d\n",
650 __func__, dai->id);
651 return -EINVAL;
652 }
653
654 int_mux_cfg1 = BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG1;
655 for (j = 0; j < NUM_INTERPOLATORS; j++) {
Meng Wang15c825d2018-09-06 10:49:18 +0800656 int_mux_cfg1_val = snd_soc_component_read32(component,
657 int_mux_cfg1) &
Laxminath Kasam243e2752018-04-12 00:40:19 +0530658 WSA_MACRO_MUX_INP_MASK1;
659 if (int_mux_cfg1_val == int_2_inp) {
660 int_fs_reg =
661 BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL +
662 WSA_MACRO_RX_PATH_OFFSET * j;
663
664 dev_dbg(wsa_dev,
665 "%s: AIF_PB DAI(%d) connected to INT%u_2\n",
666 __func__, dai->id, j);
667 dev_dbg(wsa_dev,
668 "%s: set INT%u_2 sample rate to %u\n",
669 __func__, j, sample_rate);
Meng Wang15c825d2018-09-06 10:49:18 +0800670 snd_soc_component_update_bits(component,
671 int_fs_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530672 WSA_MACRO_FS_RATE_MASK,
673 int_mix_fs_rate_reg_val);
674 }
675 int_mux_cfg1 += WSA_MACRO_MUX_CFG_OFFSET;
676 }
677 }
678 return 0;
679}
680
681static int wsa_macro_set_interpolator_rate(struct snd_soc_dai *dai,
682 u32 sample_rate)
683{
684 int rate_val = 0;
685 int i, ret;
686
687 /* set mixing path rate */
688 for (i = 0; i < ARRAY_SIZE(int_mix_sample_rate_val); i++) {
689 if (sample_rate ==
690 int_mix_sample_rate_val[i].sample_rate) {
691 rate_val =
692 int_mix_sample_rate_val[i].rate_val;
693 break;
694 }
695 }
696 if ((i == ARRAY_SIZE(int_mix_sample_rate_val)) ||
697 (rate_val < 0))
698 goto prim_rate;
699 ret = wsa_macro_set_mix_interpolator_rate(dai,
700 (u8) rate_val, sample_rate);
701prim_rate:
702 /* set primary path sample rate */
703 for (i = 0; i < ARRAY_SIZE(int_prim_sample_rate_val); i++) {
704 if (sample_rate ==
705 int_prim_sample_rate_val[i].sample_rate) {
706 rate_val =
707 int_prim_sample_rate_val[i].rate_val;
708 break;
709 }
710 }
711 if ((i == ARRAY_SIZE(int_prim_sample_rate_val)) ||
712 (rate_val < 0))
713 return -EINVAL;
714 ret = wsa_macro_set_prim_interpolator_rate(dai,
715 (u8) rate_val, sample_rate);
716 return ret;
717}
718
719static int wsa_macro_hw_params(struct snd_pcm_substream *substream,
720 struct snd_pcm_hw_params *params,
721 struct snd_soc_dai *dai)
722{
Meng Wang15c825d2018-09-06 10:49:18 +0800723 struct snd_soc_component *component = dai->component;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530724 int ret;
725
Meng Wang15c825d2018-09-06 10:49:18 +0800726 dev_dbg(component->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530727 "%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__,
728 dai->name, dai->id, params_rate(params),
729 params_channels(params));
730
731 switch (substream->stream) {
732 case SNDRV_PCM_STREAM_PLAYBACK:
733 ret = wsa_macro_set_interpolator_rate(dai, params_rate(params));
734 if (ret) {
Meng Wang15c825d2018-09-06 10:49:18 +0800735 dev_err(component->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530736 "%s: cannot set sample rate: %u\n",
737 __func__, params_rate(params));
738 return ret;
739 }
740 break;
741 case SNDRV_PCM_STREAM_CAPTURE:
742 default:
743 break;
744 }
745 return 0;
746}
747
748static int wsa_macro_get_channel_map(struct snd_soc_dai *dai,
749 unsigned int *tx_num, unsigned int *tx_slot,
750 unsigned int *rx_num, unsigned int *rx_slot)
751{
Meng Wang15c825d2018-09-06 10:49:18 +0800752 struct snd_soc_component *component = dai->component;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530753 struct device *wsa_dev = NULL;
754 struct wsa_macro_priv *wsa_priv = NULL;
Laxminath Kasam5d9ea8d2018-11-28 14:32:40 +0530755 u16 val = 0, mask = 0, cnt = 0;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530756
Meng Wang15c825d2018-09-06 10:49:18 +0800757 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530758 return -EINVAL;
759
760 wsa_priv = dev_get_drvdata(wsa_dev);
761 if (!wsa_priv)
762 return -EINVAL;
763
764 switch (dai->id) {
765 case WSA_MACRO_AIF_VI:
Laxminath Kasam243e2752018-04-12 00:40:19 +0530766 *tx_slot = wsa_priv->active_ch_mask[dai->id];
767 *tx_num = wsa_priv->active_ch_cnt[dai->id];
768 break;
769 case WSA_MACRO_AIF1_PB:
770 case WSA_MACRO_AIF_MIX1_PB:
771 *rx_slot = wsa_priv->active_ch_mask[dai->id];
772 *rx_num = wsa_priv->active_ch_cnt[dai->id];
773 break;
Laxminath Kasam5d9ea8d2018-11-28 14:32:40 +0530774 case WSA_MACRO_AIF_ECHO:
775 val = snd_soc_component_read32(component,
776 BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0);
777 if (val & WSA_MACRO_EC_MIX_TX1_MASK) {
778 mask |= 0x2;
779 cnt++;
780 }
781 if (val & WSA_MACRO_EC_MIX_TX0_MASK) {
782 mask |= 0x1;
783 cnt++;
784 }
785 *tx_slot = mask;
786 *tx_num = cnt;
787 break;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530788 default:
789 dev_err(wsa_dev, "%s: Invalid AIF\n", __func__);
790 break;
791 }
792 return 0;
793}
794
795static int wsa_macro_mclk_enable(struct wsa_macro_priv *wsa_priv,
796 bool mclk_enable, bool dapm)
797{
798 struct regmap *regmap = dev_get_regmap(wsa_priv->dev->parent, NULL);
799 int ret = 0;
800
Tanya Dixitab8eba82018-10-05 15:07:37 +0530801 if (regmap == NULL) {
802 dev_err(wsa_priv->dev, "%s: regmap is NULL\n", __func__);
803 return -EINVAL;
804 }
805
Laxminath Kasam243e2752018-04-12 00:40:19 +0530806 dev_dbg(wsa_priv->dev, "%s: mclk_enable = %u, dapm = %d clk_users= %d\n",
807 __func__, mclk_enable, dapm, wsa_priv->wsa_mclk_users);
808
809 mutex_lock(&wsa_priv->mclk_lock);
810 if (mclk_enable) {
Aditya Bavanaric496ed22018-11-16 15:50:40 +0530811 if (wsa_priv->wsa_mclk_users == 0) {
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -0700812 ret = bolero_clk_rsc_request_clock(wsa_priv->dev,
813 wsa_priv->default_clk_id,
814 wsa_priv->default_clk_id,
815 true);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530816 if (ret < 0) {
817 dev_err(wsa_priv->dev,
818 "%s: wsa request clock enable failed\n",
819 __func__);
820 goto exit;
821 }
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -0700822 bolero_clk_rsc_fs_gen_request(wsa_priv->dev,
823 true);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530824 regcache_mark_dirty(regmap);
825 regcache_sync_region(regmap,
826 WSA_START_OFFSET,
827 WSA_MAX_OFFSET);
828 /* 9.6MHz MCLK, set value 0x00 if other frequency */
829 regmap_update_bits(regmap,
830 BOLERO_CDC_WSA_TOP_FREQ_MCLK, 0x01, 0x01);
831 regmap_update_bits(regmap,
832 BOLERO_CDC_WSA_CLK_RST_CTRL_MCLK_CONTROL,
833 0x01, 0x01);
834 regmap_update_bits(regmap,
835 BOLERO_CDC_WSA_CLK_RST_CTRL_FS_CNT_CONTROL,
836 0x01, 0x01);
837 }
Aditya Bavanaric496ed22018-11-16 15:50:40 +0530838 wsa_priv->wsa_mclk_users++;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530839 } else {
Aditya Bavanaric496ed22018-11-16 15:50:40 +0530840 if (wsa_priv->wsa_mclk_users <= 0) {
841 dev_err(wsa_priv->dev, "%s: clock already disabled\n",
842 __func__);
843 wsa_priv->wsa_mclk_users = 0;
844 goto exit;
845 }
Laxminath Kasam243e2752018-04-12 00:40:19 +0530846 wsa_priv->wsa_mclk_users--;
847 if (wsa_priv->wsa_mclk_users == 0) {
848 regmap_update_bits(regmap,
849 BOLERO_CDC_WSA_CLK_RST_CTRL_FS_CNT_CONTROL,
850 0x01, 0x00);
851 regmap_update_bits(regmap,
852 BOLERO_CDC_WSA_CLK_RST_CTRL_MCLK_CONTROL,
853 0x01, 0x00);
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -0700854 bolero_clk_rsc_fs_gen_request(wsa_priv->dev,
855 false);
856
857 bolero_clk_rsc_request_clock(wsa_priv->dev,
858 wsa_priv->default_clk_id,
859 wsa_priv->default_clk_id,
860 false);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530861 }
862 }
863exit:
864 mutex_unlock(&wsa_priv->mclk_lock);
865 return ret;
866}
867
868static int wsa_macro_mclk_event(struct snd_soc_dapm_widget *w,
869 struct snd_kcontrol *kcontrol, int event)
870{
Meng Wang15c825d2018-09-06 10:49:18 +0800871 struct snd_soc_component *component =
872 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530873 int ret = 0;
874 struct device *wsa_dev = NULL;
875 struct wsa_macro_priv *wsa_priv = NULL;
876
Meng Wang15c825d2018-09-06 10:49:18 +0800877 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530878 return -EINVAL;
879
880 dev_dbg(wsa_dev, "%s: event = %d\n", __func__, event);
881 switch (event) {
882 case SND_SOC_DAPM_PRE_PMU:
883 ret = wsa_macro_mclk_enable(wsa_priv, 1, true);
Ramprasad Katkam452772a2019-01-07 17:30:36 +0530884 if (ret)
885 wsa_priv->dapm_mclk_enable = false;
886 else
887 wsa_priv->dapm_mclk_enable = true;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530888 break;
889 case SND_SOC_DAPM_POST_PMD:
Ramprasad Katkam452772a2019-01-07 17:30:36 +0530890 if (wsa_priv->dapm_mclk_enable)
891 wsa_macro_mclk_enable(wsa_priv, 0, true);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530892 break;
893 default:
894 dev_err(wsa_priv->dev,
895 "%s: invalid DAPM event %d\n", __func__, event);
896 ret = -EINVAL;
897 }
898 return ret;
899}
900
Meng Wang15c825d2018-09-06 10:49:18 +0800901static int wsa_macro_event_handler(struct snd_soc_component *component,
902 u16 event, u32 data)
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530903{
904 struct device *wsa_dev = NULL;
905 struct wsa_macro_priv *wsa_priv = NULL;
906
Meng Wang15c825d2018-09-06 10:49:18 +0800907 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530908 return -EINVAL;
909
910 switch (event) {
911 case BOLERO_MACRO_EVT_SSR_DOWN:
912 swrm_wcd_notify(
913 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
Ramprasad Katkam5ee54ae2018-12-19 18:56:00 +0530914 SWR_DEVICE_DOWN, NULL);
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530915 swrm_wcd_notify(
916 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
Ramprasad Katkam5ee54ae2018-12-19 18:56:00 +0530917 SWR_DEVICE_SSR_DOWN, NULL);
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530918 break;
919 case BOLERO_MACRO_EVT_SSR_UP:
Ramprasad Katkama4c747b2018-12-11 19:15:53 +0530920 /* reset swr after ssr/pdr */
921 wsa_priv->reset_swr = true;
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530922 swrm_wcd_notify(
923 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
924 SWR_DEVICE_SSR_UP, NULL);
925 break;
926 }
927 return 0;
928}
929
Laxminath Kasam243e2752018-04-12 00:40:19 +0530930static int wsa_macro_enable_vi_feedback(struct snd_soc_dapm_widget *w,
931 struct snd_kcontrol *kcontrol,
932 int event)
933{
Meng Wang15c825d2018-09-06 10:49:18 +0800934 struct snd_soc_component *component =
935 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530936 struct device *wsa_dev = NULL;
937 struct wsa_macro_priv *wsa_priv = NULL;
938
Meng Wang15c825d2018-09-06 10:49:18 +0800939 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530940 return -EINVAL;
941
942 switch (event) {
943 case SND_SOC_DAPM_POST_PMU:
944 if (test_bit(WSA_MACRO_TX0,
945 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
946 dev_dbg(wsa_dev, "%s: spkr1 enabled\n", __func__);
947 /* Enable V&I sensing */
Meng Wang15c825d2018-09-06 10:49:18 +0800948 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530949 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
950 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +0800951 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530952 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
953 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +0800954 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530955 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
956 0x0F, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +0800957 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530958 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
959 0x0F, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +0800960 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530961 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
962 0x10, 0x10);
Meng Wang15c825d2018-09-06 10:49:18 +0800963 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530964 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
965 0x10, 0x10);
Meng Wang15c825d2018-09-06 10:49:18 +0800966 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530967 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
968 0x20, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +0800969 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530970 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
971 0x20, 0x00);
972 }
973 if (test_bit(WSA_MACRO_TX1,
974 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
975 dev_dbg(wsa_dev, "%s: spkr2 enabled\n", __func__);
976 /* Enable V&I sensing */
Meng Wang15c825d2018-09-06 10:49:18 +0800977 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530978 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
979 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +0800980 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530981 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
982 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +0800983 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530984 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
985 0x0F, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +0800986 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530987 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
988 0x0F, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +0800989 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530990 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
991 0x10, 0x10);
Meng Wang15c825d2018-09-06 10:49:18 +0800992 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530993 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
994 0x10, 0x10);
Meng Wang15c825d2018-09-06 10:49:18 +0800995 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530996 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
997 0x20, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +0800998 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530999 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
1000 0x20, 0x00);
1001 }
1002 break;
1003 case SND_SOC_DAPM_POST_PMD:
1004 if (test_bit(WSA_MACRO_TX0,
1005 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
1006 /* Disable V&I sensing */
Meng Wang15c825d2018-09-06 10:49:18 +08001007 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301008 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
1009 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08001010 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301011 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
1012 0x20, 0x20);
1013 dev_dbg(wsa_dev, "%s: spkr1 disabled\n", __func__);
Meng Wang15c825d2018-09-06 10:49:18 +08001014 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301015 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
1016 0x10, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001017 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301018 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
1019 0x10, 0x00);
1020 }
1021 if (test_bit(WSA_MACRO_TX1,
1022 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
1023 /* Disable V&I sensing */
1024 dev_dbg(wsa_dev, "%s: spkr2 disabled\n", __func__);
Meng Wang15c825d2018-09-06 10:49:18 +08001025 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301026 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
1027 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08001028 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301029 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
1030 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08001031 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301032 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
1033 0x10, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001034 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301035 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
1036 0x10, 0x00);
1037 }
1038 break;
1039 }
1040
1041 return 0;
1042}
1043
1044static int wsa_macro_enable_mix_path(struct snd_soc_dapm_widget *w,
1045 struct snd_kcontrol *kcontrol, int event)
1046{
Meng Wang15c825d2018-09-06 10:49:18 +08001047 struct snd_soc_component *component =
1048 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301049 u16 gain_reg;
1050 int offset_val = 0;
1051 int val = 0;
1052
Meng Wang15c825d2018-09-06 10:49:18 +08001053 dev_dbg(component->dev, "%s %d %s\n", __func__, event, w->name);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301054
1055 switch (w->reg) {
1056 case BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL:
1057 gain_reg = BOLERO_CDC_WSA_RX0_RX_VOL_MIX_CTL;
1058 break;
1059 case BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL:
1060 gain_reg = BOLERO_CDC_WSA_RX1_RX_VOL_MIX_CTL;
1061 break;
1062 default:
Meng Wang15c825d2018-09-06 10:49:18 +08001063 dev_err(component->dev, "%s: No gain register avail for %s\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301064 __func__, w->name);
1065 return 0;
1066 }
1067
1068 switch (event) {
1069 case SND_SOC_DAPM_POST_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08001070 val = snd_soc_component_read32(component, gain_reg);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301071 val += offset_val;
Meng Wang15c825d2018-09-06 10:49:18 +08001072 snd_soc_component_write(component, gain_reg, val);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301073 break;
1074 case SND_SOC_DAPM_POST_PMD:
1075 break;
1076 }
1077
1078 return 0;
1079}
1080
Meng Wang15c825d2018-09-06 10:49:18 +08001081static void wsa_macro_hd2_control(struct snd_soc_component *component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301082 u16 reg, int event)
1083{
1084 u16 hd2_scale_reg;
1085 u16 hd2_enable_reg = 0;
1086
1087 if (reg == BOLERO_CDC_WSA_RX0_RX_PATH_CTL) {
1088 hd2_scale_reg = BOLERO_CDC_WSA_RX0_RX_PATH_SEC3;
1089 hd2_enable_reg = BOLERO_CDC_WSA_RX0_RX_PATH_CFG0;
1090 }
1091 if (reg == BOLERO_CDC_WSA_RX1_RX_PATH_CTL) {
1092 hd2_scale_reg = BOLERO_CDC_WSA_RX1_RX_PATH_SEC3;
1093 hd2_enable_reg = BOLERO_CDC_WSA_RX1_RX_PATH_CFG0;
1094 }
1095
1096 if (hd2_enable_reg && SND_SOC_DAPM_EVENT_ON(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001097 snd_soc_component_update_bits(component, hd2_scale_reg,
1098 0x3C, 0x10);
1099 snd_soc_component_update_bits(component, hd2_scale_reg,
1100 0x03, 0x01);
1101 snd_soc_component_update_bits(component, hd2_enable_reg,
1102 0x04, 0x04);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301103 }
1104
1105 if (hd2_enable_reg && SND_SOC_DAPM_EVENT_OFF(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001106 snd_soc_component_update_bits(component, hd2_enable_reg,
1107 0x04, 0x00);
1108 snd_soc_component_update_bits(component, hd2_scale_reg,
1109 0x03, 0x00);
1110 snd_soc_component_update_bits(component, hd2_scale_reg,
1111 0x3C, 0x00);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301112 }
1113}
1114
1115static int wsa_macro_enable_swr(struct snd_soc_dapm_widget *w,
1116 struct snd_kcontrol *kcontrol, int event)
1117{
Meng Wang15c825d2018-09-06 10:49:18 +08001118 struct snd_soc_component *component =
1119 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301120 int ch_cnt;
1121 struct device *wsa_dev = NULL;
1122 struct wsa_macro_priv *wsa_priv = NULL;
1123
Meng Wang15c825d2018-09-06 10:49:18 +08001124 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301125 return -EINVAL;
1126
1127 switch (event) {
1128 case SND_SOC_DAPM_PRE_PMU:
1129 if (!(strnstr(w->name, "RX0", sizeof("WSA_RX0"))) &&
1130 !wsa_priv->rx_0_count)
1131 wsa_priv->rx_0_count++;
1132 if (!(strnstr(w->name, "RX1", sizeof("WSA_RX1"))) &&
1133 !wsa_priv->rx_1_count)
1134 wsa_priv->rx_1_count++;
1135 ch_cnt = wsa_priv->rx_0_count + wsa_priv->rx_1_count;
1136
1137 swrm_wcd_notify(
1138 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
1139 SWR_DEVICE_UP, NULL);
1140 swrm_wcd_notify(
1141 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
1142 SWR_SET_NUM_RX_CH, &ch_cnt);
1143 break;
1144 case SND_SOC_DAPM_POST_PMD:
1145 if (!(strnstr(w->name, "RX0", sizeof("WSA_RX0"))) &&
1146 wsa_priv->rx_0_count)
1147 wsa_priv->rx_0_count--;
1148 if (!(strnstr(w->name, "RX1", sizeof("WSA_RX1"))) &&
1149 wsa_priv->rx_1_count)
1150 wsa_priv->rx_1_count--;
1151 ch_cnt = wsa_priv->rx_0_count + wsa_priv->rx_1_count;
1152
1153 swrm_wcd_notify(
1154 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
1155 SWR_SET_NUM_RX_CH, &ch_cnt);
1156 break;
1157 }
1158 dev_dbg(wsa_priv->dev, "%s: current swr ch cnt: %d\n",
1159 __func__, wsa_priv->rx_0_count + wsa_priv->rx_1_count);
1160
1161 return 0;
1162}
1163
Meng Wang15c825d2018-09-06 10:49:18 +08001164static int wsa_macro_config_compander(struct snd_soc_component *component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301165 int comp, int event)
1166{
1167 u16 comp_ctl0_reg, rx_path_cfg0_reg;
1168 struct device *wsa_dev = NULL;
1169 struct wsa_macro_priv *wsa_priv = NULL;
1170
Meng Wang15c825d2018-09-06 10:49:18 +08001171 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301172 return -EINVAL;
1173
Meng Wang15c825d2018-09-06 10:49:18 +08001174 dev_dbg(component->dev, "%s: event %d compander %d, enabled %d\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301175 __func__, event, comp + 1, wsa_priv->comp_enabled[comp]);
1176
1177 if (!wsa_priv->comp_enabled[comp])
1178 return 0;
1179
1180 comp_ctl0_reg = BOLERO_CDC_WSA_COMPANDER0_CTL0 +
1181 (comp * WSA_MACRO_RX_COMP_OFFSET);
1182 rx_path_cfg0_reg = BOLERO_CDC_WSA_RX0_RX_PATH_CFG0 +
1183 (comp * WSA_MACRO_RX_PATH_OFFSET);
1184
1185 if (SND_SOC_DAPM_EVENT_ON(event)) {
1186 /* Enable Compander Clock */
Meng Wang15c825d2018-09-06 10:49:18 +08001187 snd_soc_component_update_bits(component, comp_ctl0_reg,
1188 0x01, 0x01);
1189 snd_soc_component_update_bits(component, comp_ctl0_reg,
1190 0x02, 0x02);
1191 snd_soc_component_update_bits(component, comp_ctl0_reg,
1192 0x02, 0x00);
1193 snd_soc_component_update_bits(component, rx_path_cfg0_reg,
1194 0x02, 0x02);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301195 }
1196
1197 if (SND_SOC_DAPM_EVENT_OFF(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001198 snd_soc_component_update_bits(component, comp_ctl0_reg,
1199 0x04, 0x04);
1200 snd_soc_component_update_bits(component, rx_path_cfg0_reg,
1201 0x02, 0x00);
1202 snd_soc_component_update_bits(component, comp_ctl0_reg,
1203 0x02, 0x02);
1204 snd_soc_component_update_bits(component, comp_ctl0_reg,
1205 0x02, 0x00);
1206 snd_soc_component_update_bits(component, comp_ctl0_reg,
1207 0x01, 0x00);
1208 snd_soc_component_update_bits(component, comp_ctl0_reg,
1209 0x04, 0x00);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301210 }
1211
1212 return 0;
1213}
1214
Meng Wang15c825d2018-09-06 10:49:18 +08001215static void wsa_macro_enable_softclip_clk(struct snd_soc_component *component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301216 struct wsa_macro_priv *wsa_priv,
1217 int path,
1218 bool enable)
1219{
1220 u16 softclip_clk_reg = BOLERO_CDC_WSA_SOFTCLIP0_CRC +
1221 (path * WSA_MACRO_RX_SOFTCLIP_OFFSET);
1222 u8 softclip_mux_mask = (1 << path);
1223 u8 softclip_mux_value = (1 << path);
1224
Meng Wang15c825d2018-09-06 10:49:18 +08001225 dev_dbg(component->dev, "%s: path %d, enable %d\n",
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301226 __func__, path, enable);
1227 if (enable) {
1228 if (wsa_priv->softclip_clk_users[path] == 0) {
Meng Wang15c825d2018-09-06 10:49:18 +08001229 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301230 softclip_clk_reg, 0x01, 0x01);
Meng Wang15c825d2018-09-06 10:49:18 +08001231 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301232 BOLERO_CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0,
1233 softclip_mux_mask, softclip_mux_value);
1234 }
1235 wsa_priv->softclip_clk_users[path]++;
1236 } else {
1237 wsa_priv->softclip_clk_users[path]--;
1238 if (wsa_priv->softclip_clk_users[path] == 0) {
Meng Wang15c825d2018-09-06 10:49:18 +08001239 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301240 softclip_clk_reg, 0x01, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001241 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301242 BOLERO_CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0,
1243 softclip_mux_mask, 0x00);
1244 }
1245 }
1246}
1247
Meng Wang15c825d2018-09-06 10:49:18 +08001248static int wsa_macro_config_softclip(struct snd_soc_component *component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301249 int path, int event)
1250{
1251 u16 softclip_ctrl_reg = 0;
1252 struct device *wsa_dev = NULL;
1253 struct wsa_macro_priv *wsa_priv = NULL;
1254 int softclip_path = 0;
1255
Meng Wang15c825d2018-09-06 10:49:18 +08001256 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301257 return -EINVAL;
1258
1259 if (path == WSA_MACRO_COMP1)
1260 softclip_path = WSA_MACRO_SOFTCLIP0;
1261 else if (path == WSA_MACRO_COMP2)
1262 softclip_path = WSA_MACRO_SOFTCLIP1;
1263
Meng Wang15c825d2018-09-06 10:49:18 +08001264 dev_dbg(component->dev, "%s: event %d path %d, enabled %d\n",
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301265 __func__, event, softclip_path,
1266 wsa_priv->is_softclip_on[softclip_path]);
1267
1268 if (!wsa_priv->is_softclip_on[softclip_path])
1269 return 0;
1270
1271 softclip_ctrl_reg = BOLERO_CDC_WSA_SOFTCLIP0_SOFTCLIP_CTRL +
1272 (softclip_path * WSA_MACRO_RX_SOFTCLIP_OFFSET);
1273
1274 if (SND_SOC_DAPM_EVENT_ON(event)) {
1275 /* Enable Softclip clock and mux */
Meng Wang15c825d2018-09-06 10:49:18 +08001276 wsa_macro_enable_softclip_clk(component, wsa_priv,
1277 softclip_path, true);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301278 /* Enable Softclip control */
Meng Wang15c825d2018-09-06 10:49:18 +08001279 snd_soc_component_update_bits(component, softclip_ctrl_reg,
1280 0x01, 0x01);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301281 }
1282
1283 if (SND_SOC_DAPM_EVENT_OFF(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001284 snd_soc_component_update_bits(component, softclip_ctrl_reg,
1285 0x01, 0x00);
1286 wsa_macro_enable_softclip_clk(component, wsa_priv,
1287 softclip_path, false);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301288 }
1289
1290 return 0;
1291}
1292
Laxminath Kasam243e2752018-04-12 00:40:19 +05301293static int wsa_macro_interp_get_primary_reg(u16 reg, u16 *ind)
1294{
1295 u16 prim_int_reg = 0;
1296
1297 switch (reg) {
1298 case BOLERO_CDC_WSA_RX0_RX_PATH_CTL:
1299 case BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL:
1300 prim_int_reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL;
1301 *ind = 0;
1302 break;
1303 case BOLERO_CDC_WSA_RX1_RX_PATH_CTL:
1304 case BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL:
1305 prim_int_reg = BOLERO_CDC_WSA_RX1_RX_PATH_CTL;
1306 *ind = 1;
1307 break;
1308 }
1309
1310 return prim_int_reg;
1311}
1312
1313static int wsa_macro_enable_prim_interpolator(
Meng Wang15c825d2018-09-06 10:49:18 +08001314 struct snd_soc_component *component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301315 u16 reg, int event)
1316{
1317 u16 prim_int_reg;
1318 u16 ind = 0;
1319 struct device *wsa_dev = NULL;
1320 struct wsa_macro_priv *wsa_priv = NULL;
1321
Meng Wang15c825d2018-09-06 10:49:18 +08001322 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301323 return -EINVAL;
1324
1325 prim_int_reg = wsa_macro_interp_get_primary_reg(reg, &ind);
1326
1327 switch (event) {
1328 case SND_SOC_DAPM_PRE_PMU:
1329 wsa_priv->prim_int_users[ind]++;
1330 if (wsa_priv->prim_int_users[ind] == 1) {
Meng Wang15c825d2018-09-06 10:49:18 +08001331 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301332 prim_int_reg + WSA_MACRO_RX_PATH_CFG3_OFFSET,
1333 0x03, 0x03);
Meng Wang15c825d2018-09-06 10:49:18 +08001334 snd_soc_component_update_bits(component, prim_int_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301335 0x10, 0x10);
Meng Wang15c825d2018-09-06 10:49:18 +08001336 wsa_macro_hd2_control(component, prim_int_reg, event);
1337 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301338 prim_int_reg + WSA_MACRO_RX_PATH_DSMDEM_OFFSET,
1339 0x1, 0x1);
Meng Wang15c825d2018-09-06 10:49:18 +08001340 snd_soc_component_update_bits(component, prim_int_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301341 1 << 0x5, 1 << 0x5);
1342 }
1343 if ((reg != prim_int_reg) &&
Meng Wang15c825d2018-09-06 10:49:18 +08001344 ((snd_soc_component_read32(
1345 component, prim_int_reg)) & 0x10))
1346 snd_soc_component_update_bits(component, reg,
1347 0x10, 0x10);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301348 break;
1349 case SND_SOC_DAPM_POST_PMD:
1350 wsa_priv->prim_int_users[ind]--;
1351 if (wsa_priv->prim_int_users[ind] == 0) {
Meng Wang15c825d2018-09-06 10:49:18 +08001352 snd_soc_component_update_bits(component, prim_int_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301353 1 << 0x5, 0 << 0x5);
Meng Wang15c825d2018-09-06 10:49:18 +08001354 snd_soc_component_update_bits(component, prim_int_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301355 0x40, 0x40);
Meng Wang15c825d2018-09-06 10:49:18 +08001356 snd_soc_component_update_bits(component, prim_int_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301357 0x40, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001358 wsa_macro_hd2_control(component, prim_int_reg, event);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301359 }
1360 break;
1361 }
1362
Meng Wang15c825d2018-09-06 10:49:18 +08001363 dev_dbg(component->dev, "%s: primary interpolator: INT%d, users: %d\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301364 __func__, ind, wsa_priv->prim_int_users[ind]);
1365 return 0;
1366}
1367
1368static int wsa_macro_enable_interpolator(struct snd_soc_dapm_widget *w,
1369 struct snd_kcontrol *kcontrol,
1370 int event)
1371{
Meng Wang15c825d2018-09-06 10:49:18 +08001372 struct snd_soc_component *component =
1373 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301374 u16 gain_reg;
1375 u16 reg;
1376 int val;
1377 int offset_val = 0;
1378 struct device *wsa_dev = NULL;
1379 struct wsa_macro_priv *wsa_priv = NULL;
1380
Meng Wang15c825d2018-09-06 10:49:18 +08001381 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301382 return -EINVAL;
1383
Meng Wang15c825d2018-09-06 10:49:18 +08001384 dev_dbg(component->dev, "%s %d %s\n", __func__, event, w->name);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301385
1386 if (!(strcmp(w->name, "WSA_RX INT0 INTERP"))) {
1387 reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL;
1388 gain_reg = BOLERO_CDC_WSA_RX0_RX_VOL_CTL;
1389 } else if (!(strcmp(w->name, "WSA_RX INT1 INTERP"))) {
1390 reg = BOLERO_CDC_WSA_RX1_RX_PATH_CTL;
1391 gain_reg = BOLERO_CDC_WSA_RX1_RX_VOL_CTL;
1392 } else {
Meng Wang15c825d2018-09-06 10:49:18 +08001393 dev_err(component->dev, "%s: Interpolator reg not found\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301394 __func__);
1395 return -EINVAL;
1396 }
1397
1398 switch (event) {
1399 case SND_SOC_DAPM_PRE_PMU:
1400 /* Reset if needed */
Meng Wang15c825d2018-09-06 10:49:18 +08001401 wsa_macro_enable_prim_interpolator(component, reg, event);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301402 break;
1403 case SND_SOC_DAPM_POST_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08001404 wsa_macro_config_compander(component, w->shift, event);
1405 wsa_macro_config_softclip(component, w->shift, event);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301406 /* apply gain after int clk is enabled */
Laxminath Kasam21c8b222018-06-21 18:47:22 +05301407 if ((wsa_priv->spkr_gain_offset ==
1408 WSA_MACRO_GAIN_OFFSET_M1P5_DB) &&
Laxminath Kasam243e2752018-04-12 00:40:19 +05301409 (wsa_priv->comp_enabled[WSA_MACRO_COMP1] ||
1410 wsa_priv->comp_enabled[WSA_MACRO_COMP2]) &&
1411 (gain_reg == BOLERO_CDC_WSA_RX0_RX_VOL_CTL ||
1412 gain_reg == BOLERO_CDC_WSA_RX1_RX_VOL_CTL)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001413 snd_soc_component_update_bits(component,
1414 BOLERO_CDC_WSA_RX0_RX_PATH_SEC1,
1415 0x01, 0x01);
1416 snd_soc_component_update_bits(component,
1417 BOLERO_CDC_WSA_RX0_RX_PATH_MIX_SEC0,
1418 0x01, 0x01);
1419 snd_soc_component_update_bits(component,
1420 BOLERO_CDC_WSA_RX1_RX_PATH_SEC1,
1421 0x01, 0x01);
1422 snd_soc_component_update_bits(component,
1423 BOLERO_CDC_WSA_RX1_RX_PATH_MIX_SEC0,
1424 0x01, 0x01);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301425 offset_val = -2;
1426 }
Meng Wang15c825d2018-09-06 10:49:18 +08001427 val = snd_soc_component_read32(component, gain_reg);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301428 val += offset_val;
Meng Wang15c825d2018-09-06 10:49:18 +08001429 snd_soc_component_write(component, gain_reg, val);
1430 wsa_macro_config_ear_spkr_gain(component, wsa_priv,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301431 event, gain_reg);
1432 break;
1433 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +08001434 wsa_macro_config_compander(component, w->shift, event);
1435 wsa_macro_config_softclip(component, w->shift, event);
1436 wsa_macro_enable_prim_interpolator(component, reg, event);
Laxminath Kasam21c8b222018-06-21 18:47:22 +05301437 if ((wsa_priv->spkr_gain_offset ==
1438 WSA_MACRO_GAIN_OFFSET_M1P5_DB) &&
Laxminath Kasam243e2752018-04-12 00:40:19 +05301439 (wsa_priv->comp_enabled[WSA_MACRO_COMP1] ||
1440 wsa_priv->comp_enabled[WSA_MACRO_COMP2]) &&
1441 (gain_reg == BOLERO_CDC_WSA_RX0_RX_VOL_CTL ||
1442 gain_reg == BOLERO_CDC_WSA_RX1_RX_VOL_CTL)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001443 snd_soc_component_update_bits(component,
1444 BOLERO_CDC_WSA_RX0_RX_PATH_SEC1,
1445 0x01, 0x00);
1446 snd_soc_component_update_bits(component,
1447 BOLERO_CDC_WSA_RX0_RX_PATH_MIX_SEC0,
1448 0x01, 0x00);
1449 snd_soc_component_update_bits(component,
1450 BOLERO_CDC_WSA_RX1_RX_PATH_SEC1,
1451 0x01, 0x00);
1452 snd_soc_component_update_bits(component,
1453 BOLERO_CDC_WSA_RX1_RX_PATH_MIX_SEC0,
1454 0x01, 0x00);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301455 offset_val = 2;
Meng Wang15c825d2018-09-06 10:49:18 +08001456 val = snd_soc_component_read32(component, gain_reg);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301457 val += offset_val;
Meng Wang15c825d2018-09-06 10:49:18 +08001458 snd_soc_component_write(component, gain_reg, val);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301459 }
Meng Wang15c825d2018-09-06 10:49:18 +08001460 wsa_macro_config_ear_spkr_gain(component, wsa_priv,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301461 event, gain_reg);
1462 break;
1463 }
1464
1465 return 0;
1466}
1467
Meng Wang15c825d2018-09-06 10:49:18 +08001468static int wsa_macro_config_ear_spkr_gain(struct snd_soc_component *component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301469 struct wsa_macro_priv *wsa_priv,
1470 int event, int gain_reg)
1471{
1472 int comp_gain_offset, val;
1473
1474 switch (wsa_priv->spkr_mode) {
Laxminath Kasam21c8b222018-06-21 18:47:22 +05301475 /* Compander gain in WSA_MACRO_SPKR_MODE1 case is 12 dB */
1476 case WSA_MACRO_SPKR_MODE_1:
Laxminath Kasam243e2752018-04-12 00:40:19 +05301477 comp_gain_offset = -12;
1478 break;
1479 /* Default case compander gain is 15 dB */
1480 default:
1481 comp_gain_offset = -15;
1482 break;
1483 }
1484
1485 switch (event) {
1486 case SND_SOC_DAPM_POST_PMU:
1487 /* Apply ear spkr gain only if compander is enabled */
1488 if (wsa_priv->comp_enabled[WSA_MACRO_COMP1] &&
1489 (gain_reg == BOLERO_CDC_WSA_RX0_RX_VOL_CTL) &&
1490 (wsa_priv->ear_spkr_gain != 0)) {
1491 /* For example, val is -8(-12+5-1) for 4dB of gain */
1492 val = comp_gain_offset + wsa_priv->ear_spkr_gain - 1;
Meng Wang15c825d2018-09-06 10:49:18 +08001493 snd_soc_component_write(component, gain_reg, val);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301494
1495 dev_dbg(wsa_priv->dev, "%s: RX0 Volume %d dB\n",
1496 __func__, val);
1497 }
1498 break;
1499 case SND_SOC_DAPM_POST_PMD:
1500 /*
1501 * Reset RX0 volume to 0 dB if compander is enabled and
1502 * ear_spkr_gain is non-zero.
1503 */
1504 if (wsa_priv->comp_enabled[WSA_MACRO_COMP1] &&
1505 (gain_reg == BOLERO_CDC_WSA_RX0_RX_VOL_CTL) &&
1506 (wsa_priv->ear_spkr_gain != 0)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001507 snd_soc_component_write(component, gain_reg, 0x0);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301508
1509 dev_dbg(wsa_priv->dev, "%s: Reset RX0 Volume to 0 dB\n",
1510 __func__);
1511 }
1512 break;
1513 }
1514
1515 return 0;
1516}
1517
1518static int wsa_macro_spk_boost_event(struct snd_soc_dapm_widget *w,
1519 struct snd_kcontrol *kcontrol,
1520 int event)
1521{
Meng Wang15c825d2018-09-06 10:49:18 +08001522 struct snd_soc_component *component =
1523 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301524 u16 boost_path_ctl, boost_path_cfg1;
1525 u16 reg, reg_mix;
1526
Meng Wang15c825d2018-09-06 10:49:18 +08001527 dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301528
1529 if (!strcmp(w->name, "WSA_RX INT0 CHAIN")) {
1530 boost_path_ctl = BOLERO_CDC_WSA_BOOST0_BOOST_PATH_CTL;
1531 boost_path_cfg1 = BOLERO_CDC_WSA_RX0_RX_PATH_CFG1;
1532 reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL;
1533 reg_mix = BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL;
1534 } else if (!strcmp(w->name, "WSA_RX INT1 CHAIN")) {
1535 boost_path_ctl = BOLERO_CDC_WSA_BOOST1_BOOST_PATH_CTL;
1536 boost_path_cfg1 = BOLERO_CDC_WSA_RX1_RX_PATH_CFG1;
1537 reg = BOLERO_CDC_WSA_RX1_RX_PATH_CTL;
1538 reg_mix = BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL;
1539 } else {
Meng Wang15c825d2018-09-06 10:49:18 +08001540 dev_err(component->dev, "%s: unknown widget: %s\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301541 __func__, w->name);
1542 return -EINVAL;
1543 }
1544
1545 switch (event) {
1546 case SND_SOC_DAPM_PRE_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08001547 snd_soc_component_update_bits(component, boost_path_cfg1,
1548 0x01, 0x01);
1549 snd_soc_component_update_bits(component, boost_path_ctl,
1550 0x10, 0x10);
1551 if ((snd_soc_component_read32(component, reg_mix)) & 0x10)
1552 snd_soc_component_update_bits(component, reg_mix,
1553 0x10, 0x00);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301554 break;
Laxminath Kasam0c857002018-07-17 23:47:17 +05301555 case SND_SOC_DAPM_POST_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08001556 snd_soc_component_update_bits(component, reg, 0x10, 0x00);
Laxminath Kasam0c857002018-07-17 23:47:17 +05301557 break;
Laxminath Kasam243e2752018-04-12 00:40:19 +05301558 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +08001559 snd_soc_component_update_bits(component, boost_path_ctl,
1560 0x10, 0x00);
1561 snd_soc_component_update_bits(component, boost_path_cfg1,
1562 0x01, 0x00);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301563 break;
1564 }
1565
1566 return 0;
1567}
1568
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301569
1570static int wsa_macro_enable_vbat(struct snd_soc_dapm_widget *w,
1571 struct snd_kcontrol *kcontrol,
1572 int event)
1573{
Meng Wang15c825d2018-09-06 10:49:18 +08001574 struct snd_soc_component *component =
1575 snd_soc_dapm_to_component(w->dapm);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301576 struct device *wsa_dev = NULL;
1577 struct wsa_macro_priv *wsa_priv = NULL;
1578 u16 vbat_path_cfg = 0;
1579 int softclip_path = 0;
1580
Meng Wang15c825d2018-09-06 10:49:18 +08001581 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301582 return -EINVAL;
1583
Meng Wang15c825d2018-09-06 10:49:18 +08001584 dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301585 if (!strcmp(w->name, "WSA_RX INT0 VBAT")) {
1586 vbat_path_cfg = BOLERO_CDC_WSA_RX0_RX_PATH_CFG1;
1587 softclip_path = WSA_MACRO_SOFTCLIP0;
1588 } else if (!strcmp(w->name, "WSA_RX INT1 VBAT")) {
1589 vbat_path_cfg = BOLERO_CDC_WSA_RX1_RX_PATH_CFG1;
1590 softclip_path = WSA_MACRO_SOFTCLIP1;
1591 }
1592
1593 switch (event) {
1594 case SND_SOC_DAPM_PRE_PMU:
1595 /* Enable clock for VBAT block */
Meng Wang15c825d2018-09-06 10:49:18 +08001596 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301597 BOLERO_CDC_WSA_VBAT_BCL_VBAT_PATH_CTL, 0x10, 0x10);
1598 /* Enable VBAT block */
Meng Wang15c825d2018-09-06 10:49:18 +08001599 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301600 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG, 0x01, 0x01);
1601 /* Update interpolator with 384K path */
Meng Wang15c825d2018-09-06 10:49:18 +08001602 snd_soc_component_update_bits(component, vbat_path_cfg,
1603 0x80, 0x80);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301604 /* Use attenuation mode */
Meng Wang15c825d2018-09-06 10:49:18 +08001605 snd_soc_component_update_bits(component,
1606 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG, 0x02, 0x00);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301607 /*
1608 * BCL block needs softclip clock and mux config to be enabled
1609 */
Meng Wang15c825d2018-09-06 10:49:18 +08001610 wsa_macro_enable_softclip_clk(component, wsa_priv,
1611 softclip_path, true);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301612 /* Enable VBAT at channel level */
Meng Wang15c825d2018-09-06 10:49:18 +08001613 snd_soc_component_update_bits(component, vbat_path_cfg,
1614 0x02, 0x02);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301615 /* Set the ATTK1 gain */
Meng Wang15c825d2018-09-06 10:49:18 +08001616 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301617 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD1,
1618 0xFF, 0xFF);
Meng Wang15c825d2018-09-06 10:49:18 +08001619 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301620 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD2,
1621 0xFF, 0x03);
Meng Wang15c825d2018-09-06 10:49:18 +08001622 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301623 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD3,
1624 0xFF, 0x00);
1625 /* Set the ATTK2 gain */
Meng Wang15c825d2018-09-06 10:49:18 +08001626 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301627 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD4,
1628 0xFF, 0xFF);
Meng Wang15c825d2018-09-06 10:49:18 +08001629 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301630 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD5,
1631 0xFF, 0x03);
Meng Wang15c825d2018-09-06 10:49:18 +08001632 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301633 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD6,
1634 0xFF, 0x00);
1635 /* Set the ATTK3 gain */
Meng Wang15c825d2018-09-06 10:49:18 +08001636 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301637 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD7,
1638 0xFF, 0xFF);
Meng Wang15c825d2018-09-06 10:49:18 +08001639 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301640 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD8,
1641 0xFF, 0x03);
Meng Wang15c825d2018-09-06 10:49:18 +08001642 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301643 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD9,
1644 0xFF, 0x00);
1645 break;
1646
1647 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +08001648 snd_soc_component_update_bits(component, vbat_path_cfg,
1649 0x80, 0x00);
1650 snd_soc_component_update_bits(component,
1651 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG,
1652 0x02, 0x02);
1653 snd_soc_component_update_bits(component, vbat_path_cfg,
1654 0x02, 0x00);
1655 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301656 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD1,
1657 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001658 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301659 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD2,
1660 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001661 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301662 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD3,
1663 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001664 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301665 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD4,
1666 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001667 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301668 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD5,
1669 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001670 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301671 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD6,
1672 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001673 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301674 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD7,
1675 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001676 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301677 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD8,
1678 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001679 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301680 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD9,
1681 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001682 wsa_macro_enable_softclip_clk(component, wsa_priv,
1683 softclip_path, false);
1684 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301685 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG, 0x01, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001686 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301687 BOLERO_CDC_WSA_VBAT_BCL_VBAT_PATH_CTL, 0x10, 0x00);
1688 break;
1689 default:
1690 dev_err(wsa_dev, "%s: Invalid event %d\n", __func__, event);
1691 break;
1692 }
1693 return 0;
1694}
1695
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301696static int wsa_macro_enable_echo(struct snd_soc_dapm_widget *w,
1697 struct snd_kcontrol *kcontrol,
1698 int event)
1699{
Meng Wang15c825d2018-09-06 10:49:18 +08001700 struct snd_soc_component *component =
1701 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301702 struct device *wsa_dev = NULL;
1703 struct wsa_macro_priv *wsa_priv = NULL;
1704 u16 val, ec_tx = 0, ec_hq_reg;
1705
Meng Wang15c825d2018-09-06 10:49:18 +08001706 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301707 return -EINVAL;
1708
1709 dev_dbg(wsa_dev, "%s %d %s\n", __func__, event, w->name);
1710
Meng Wang15c825d2018-09-06 10:49:18 +08001711 val = snd_soc_component_read32(component,
1712 BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301713 if (!(strcmp(w->name, "WSA RX_MIX EC0_MUX")))
1714 ec_tx = (val & 0x07) - 1;
1715 else
1716 ec_tx = ((val & 0x38) >> 0x3) - 1;
1717
1718 if (ec_tx < 0 || ec_tx >= (WSA_MACRO_RX1 + 1)) {
1719 dev_err(wsa_dev, "%s: EC mix control not set correctly\n",
1720 __func__);
1721 return -EINVAL;
1722 }
1723 if (wsa_priv->ec_hq[ec_tx]) {
Meng Wang15c825d2018-09-06 10:49:18 +08001724 snd_soc_component_update_bits(component,
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301725 BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0,
1726 0x1 << ec_tx, 0x1 << ec_tx);
1727 ec_hq_reg = BOLERO_CDC_WSA_EC_HQ0_EC_REF_HQ_PATH_CTL +
Laxminath Kasam5d9ea8d2018-11-28 14:32:40 +05301728 0x40 * ec_tx;
Meng Wang15c825d2018-09-06 10:49:18 +08001729 snd_soc_component_update_bits(component, ec_hq_reg, 0x01, 0x01);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301730 ec_hq_reg = BOLERO_CDC_WSA_EC_HQ0_EC_REF_HQ_CFG0 +
Laxminath Kasam5d9ea8d2018-11-28 14:32:40 +05301731 0x40 * ec_tx;
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301732 /* default set to 48k */
Meng Wang15c825d2018-09-06 10:49:18 +08001733 snd_soc_component_update_bits(component, ec_hq_reg, 0x1E, 0x08);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301734 }
1735
1736 return 0;
1737}
1738
1739static int wsa_macro_get_ec_hq(struct snd_kcontrol *kcontrol,
1740 struct snd_ctl_elem_value *ucontrol)
1741{
1742
Meng Wang15c825d2018-09-06 10:49:18 +08001743 struct snd_soc_component *component =
1744 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301745 int ec_tx = ((struct soc_multi_mixer_control *)
1746 kcontrol->private_value)->shift;
1747 struct device *wsa_dev = NULL;
1748 struct wsa_macro_priv *wsa_priv = NULL;
1749
Meng Wang15c825d2018-09-06 10:49:18 +08001750 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301751 return -EINVAL;
1752
1753 ucontrol->value.integer.value[0] = wsa_priv->ec_hq[ec_tx];
1754 return 0;
1755}
1756
1757static int wsa_macro_set_ec_hq(struct snd_kcontrol *kcontrol,
1758 struct snd_ctl_elem_value *ucontrol)
1759{
Meng Wang15c825d2018-09-06 10:49:18 +08001760 struct snd_soc_component *component =
1761 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301762 int ec_tx = ((struct soc_multi_mixer_control *)
1763 kcontrol->private_value)->shift;
1764 int value = ucontrol->value.integer.value[0];
1765 struct device *wsa_dev = NULL;
1766 struct wsa_macro_priv *wsa_priv = NULL;
1767
Meng Wang15c825d2018-09-06 10:49:18 +08001768 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301769 return -EINVAL;
1770
1771 dev_dbg(wsa_dev, "%s: enable current %d, new %d\n",
1772 __func__, wsa_priv->ec_hq[ec_tx], value);
1773 wsa_priv->ec_hq[ec_tx] = value;
1774
1775 return 0;
1776}
1777
Laxminath Kasam243e2752018-04-12 00:40:19 +05301778static int wsa_macro_get_compander(struct snd_kcontrol *kcontrol,
1779 struct snd_ctl_elem_value *ucontrol)
1780{
1781
Meng Wang15c825d2018-09-06 10:49:18 +08001782 struct snd_soc_component *component =
1783 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301784 int comp = ((struct soc_multi_mixer_control *)
1785 kcontrol->private_value)->shift;
1786 struct device *wsa_dev = NULL;
1787 struct wsa_macro_priv *wsa_priv = NULL;
1788
Meng Wang15c825d2018-09-06 10:49:18 +08001789 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301790 return -EINVAL;
1791
1792 ucontrol->value.integer.value[0] = wsa_priv->comp_enabled[comp];
1793 return 0;
1794}
1795
1796static int wsa_macro_set_compander(struct snd_kcontrol *kcontrol,
1797 struct snd_ctl_elem_value *ucontrol)
1798{
Meng Wang15c825d2018-09-06 10:49:18 +08001799 struct snd_soc_component *component =
1800 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301801 int comp = ((struct soc_multi_mixer_control *)
1802 kcontrol->private_value)->shift;
1803 int value = ucontrol->value.integer.value[0];
1804 struct device *wsa_dev = NULL;
1805 struct wsa_macro_priv *wsa_priv = NULL;
1806
Meng Wang15c825d2018-09-06 10:49:18 +08001807 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301808 return -EINVAL;
1809
Meng Wang15c825d2018-09-06 10:49:18 +08001810 dev_dbg(component->dev, "%s: Compander %d enable current %d, new %d\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301811 __func__, comp + 1, wsa_priv->comp_enabled[comp], value);
1812 wsa_priv->comp_enabled[comp] = value;
1813
1814 return 0;
1815}
1816
1817static int wsa_macro_ear_spkr_pa_gain_get(struct snd_kcontrol *kcontrol,
1818 struct snd_ctl_elem_value *ucontrol)
1819{
Meng Wang15c825d2018-09-06 10:49:18 +08001820 struct snd_soc_component *component =
1821 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301822 struct device *wsa_dev = NULL;
1823 struct wsa_macro_priv *wsa_priv = NULL;
1824
Meng Wang15c825d2018-09-06 10:49:18 +08001825 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301826 return -EINVAL;
1827
1828 ucontrol->value.integer.value[0] = wsa_priv->ear_spkr_gain;
1829
Meng Wang15c825d2018-09-06 10:49:18 +08001830 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301831 __func__, ucontrol->value.integer.value[0]);
1832
1833 return 0;
1834}
1835
1836static int wsa_macro_ear_spkr_pa_gain_put(struct snd_kcontrol *kcontrol,
1837 struct snd_ctl_elem_value *ucontrol)
1838{
Meng Wang15c825d2018-09-06 10:49:18 +08001839 struct snd_soc_component *component =
1840 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301841 struct device *wsa_dev = NULL;
1842 struct wsa_macro_priv *wsa_priv = NULL;
1843
Meng Wang15c825d2018-09-06 10:49:18 +08001844 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301845 return -EINVAL;
1846
1847 wsa_priv->ear_spkr_gain = ucontrol->value.integer.value[0];
1848
Meng Wang15c825d2018-09-06 10:49:18 +08001849 dev_dbg(component->dev, "%s: gain = %d\n", __func__,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301850 wsa_priv->ear_spkr_gain);
1851
1852 return 0;
1853}
1854
1855static int wsa_macro_spkr_left_boost_stage_get(struct snd_kcontrol *kcontrol,
1856 struct snd_ctl_elem_value *ucontrol)
1857{
1858 u8 bst_state_max = 0;
Meng Wang15c825d2018-09-06 10:49:18 +08001859 struct snd_soc_component *component =
1860 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301861
Meng Wang15c825d2018-09-06 10:49:18 +08001862 bst_state_max = snd_soc_component_read32(component,
1863 BOLERO_CDC_WSA_BOOST0_BOOST_CTL);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301864 bst_state_max = (bst_state_max & 0x0c) >> 2;
1865 ucontrol->value.integer.value[0] = bst_state_max;
Meng Wang15c825d2018-09-06 10:49:18 +08001866 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301867 __func__, ucontrol->value.integer.value[0]);
1868
1869 return 0;
1870}
1871
1872static int wsa_macro_spkr_left_boost_stage_put(struct snd_kcontrol *kcontrol,
1873 struct snd_ctl_elem_value *ucontrol)
1874{
1875 u8 bst_state_max;
Meng Wang15c825d2018-09-06 10:49:18 +08001876 struct snd_soc_component *component =
1877 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301878
Meng Wang15c825d2018-09-06 10:49:18 +08001879 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301880 __func__, ucontrol->value.integer.value[0]);
1881 bst_state_max = ucontrol->value.integer.value[0] << 2;
Meng Wang15c825d2018-09-06 10:49:18 +08001882 snd_soc_component_update_bits(component,
1883 BOLERO_CDC_WSA_BOOST0_BOOST_CTL,
1884 0x0c, bst_state_max);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301885
1886 return 0;
1887}
1888
1889static int wsa_macro_spkr_right_boost_stage_get(struct snd_kcontrol *kcontrol,
1890 struct snd_ctl_elem_value *ucontrol)
1891{
1892 u8 bst_state_max = 0;
Meng Wang15c825d2018-09-06 10:49:18 +08001893 struct snd_soc_component *component =
1894 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301895
Meng Wang15c825d2018-09-06 10:49:18 +08001896 bst_state_max = snd_soc_component_read32(component,
1897 BOLERO_CDC_WSA_BOOST1_BOOST_CTL);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301898 bst_state_max = (bst_state_max & 0x0c) >> 2;
1899 ucontrol->value.integer.value[0] = bst_state_max;
Meng Wang15c825d2018-09-06 10:49:18 +08001900 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301901 __func__, ucontrol->value.integer.value[0]);
1902
1903 return 0;
1904}
1905
1906static int wsa_macro_spkr_right_boost_stage_put(struct snd_kcontrol *kcontrol,
1907 struct snd_ctl_elem_value *ucontrol)
1908{
1909 u8 bst_state_max;
Meng Wang15c825d2018-09-06 10:49:18 +08001910 struct snd_soc_component *component =
1911 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301912
Meng Wang15c825d2018-09-06 10:49:18 +08001913 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301914 __func__, ucontrol->value.integer.value[0]);
1915 bst_state_max = ucontrol->value.integer.value[0] << 2;
Meng Wang15c825d2018-09-06 10:49:18 +08001916 snd_soc_component_update_bits(component,
1917 BOLERO_CDC_WSA_BOOST1_BOOST_CTL,
1918 0x0c, bst_state_max);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301919
1920 return 0;
1921}
1922
1923static int wsa_macro_rx_mux_get(struct snd_kcontrol *kcontrol,
1924 struct snd_ctl_elem_value *ucontrol)
1925{
1926 struct snd_soc_dapm_widget *widget =
1927 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +08001928 struct snd_soc_component *component =
1929 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301930 struct device *wsa_dev = NULL;
1931 struct wsa_macro_priv *wsa_priv = NULL;
1932
Meng Wang15c825d2018-09-06 10:49:18 +08001933 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301934 return -EINVAL;
1935
1936 ucontrol->value.integer.value[0] =
1937 wsa_priv->rx_port_value[widget->shift];
1938 return 0;
1939}
1940
1941static int wsa_macro_rx_mux_put(struct snd_kcontrol *kcontrol,
1942 struct snd_ctl_elem_value *ucontrol)
1943{
1944 struct snd_soc_dapm_widget *widget =
1945 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +08001946 struct snd_soc_component *component =
1947 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301948 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1949 struct snd_soc_dapm_update *update = NULL;
1950 u32 rx_port_value = ucontrol->value.integer.value[0];
1951 u32 bit_input = 0;
1952 u32 aif_rst;
1953 struct device *wsa_dev = NULL;
1954 struct wsa_macro_priv *wsa_priv = NULL;
1955
Meng Wang15c825d2018-09-06 10:49:18 +08001956 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301957 return -EINVAL;
1958
1959 aif_rst = wsa_priv->rx_port_value[widget->shift];
1960 if (!rx_port_value) {
1961 if (aif_rst == 0) {
1962 dev_err(wsa_dev, "%s: AIF reset already\n", __func__);
1963 return 0;
1964 }
1965 }
1966 wsa_priv->rx_port_value[widget->shift] = rx_port_value;
1967
1968 bit_input = widget->shift;
1969 if (widget->shift >= WSA_MACRO_RX_MIX)
1970 bit_input %= WSA_MACRO_RX_MIX;
1971
1972 switch (rx_port_value) {
1973 case 0:
1974 clear_bit(bit_input,
Laxminath Kasam59c7a1d2018-08-09 16:11:17 +05301975 &wsa_priv->active_ch_mask[aif_rst]);
1976 wsa_priv->active_ch_cnt[aif_rst]--;
Laxminath Kasam243e2752018-04-12 00:40:19 +05301977 break;
1978 case 1:
1979 case 2:
1980 set_bit(bit_input,
Laxminath Kasam59c7a1d2018-08-09 16:11:17 +05301981 &wsa_priv->active_ch_mask[rx_port_value]);
1982 wsa_priv->active_ch_cnt[rx_port_value]++;
Laxminath Kasam243e2752018-04-12 00:40:19 +05301983 break;
1984 default:
1985 dev_err(wsa_dev,
1986 "%s: Invalid AIF_ID for WSA RX MUX\n", __func__);
1987 return -EINVAL;
1988 }
1989
1990 snd_soc_dapm_mux_update_power(widget->dapm, kcontrol,
1991 rx_port_value, e, update);
1992 return 0;
1993}
1994
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301995static int wsa_macro_vbat_bcl_gsm_mode_func_get(struct snd_kcontrol *kcontrol,
1996 struct snd_ctl_elem_value *ucontrol)
1997{
Meng Wang15c825d2018-09-06 10:49:18 +08001998 struct snd_soc_component *component =
1999 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302000
2001 ucontrol->value.integer.value[0] =
Meng Wang15c825d2018-09-06 10:49:18 +08002002 ((snd_soc_component_read32(
2003 component, BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG) & 0x04) ?
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302004 1 : 0);
2005
Meng Wang15c825d2018-09-06 10:49:18 +08002006 dev_dbg(component->dev, "%s: value: %lu\n", __func__,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302007 ucontrol->value.integer.value[0]);
2008
2009 return 0;
2010}
2011
2012static int wsa_macro_vbat_bcl_gsm_mode_func_put(struct snd_kcontrol *kcontrol,
2013 struct snd_ctl_elem_value *ucontrol)
2014{
Meng Wang15c825d2018-09-06 10:49:18 +08002015 struct snd_soc_component *component =
2016 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302017
Meng Wang15c825d2018-09-06 10:49:18 +08002018 dev_dbg(component->dev, "%s: value: %lu\n", __func__,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302019 ucontrol->value.integer.value[0]);
2020
2021 /* Set Vbat register configuration for GSM mode bit based on value */
2022 if (ucontrol->value.integer.value[0])
Meng Wang15c825d2018-09-06 10:49:18 +08002023 snd_soc_component_update_bits(component,
2024 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG,
2025 0x04, 0x04);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302026 else
Meng Wang15c825d2018-09-06 10:49:18 +08002027 snd_soc_component_update_bits(component,
2028 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG,
2029 0x04, 0x00);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302030
2031 return 0;
2032}
2033
2034static int wsa_macro_soft_clip_enable_get(struct snd_kcontrol *kcontrol,
2035 struct snd_ctl_elem_value *ucontrol)
2036{
Meng Wang15c825d2018-09-06 10:49:18 +08002037 struct snd_soc_component *component =
2038 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302039 struct device *wsa_dev = NULL;
2040 struct wsa_macro_priv *wsa_priv = NULL;
2041 int path = ((struct soc_multi_mixer_control *)
2042 kcontrol->private_value)->shift;
2043
Meng Wang15c825d2018-09-06 10:49:18 +08002044 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302045 return -EINVAL;
2046
2047 ucontrol->value.integer.value[0] = wsa_priv->is_softclip_on[path];
2048
Meng Wang15c825d2018-09-06 10:49:18 +08002049 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302050 __func__, ucontrol->value.integer.value[0]);
2051
2052 return 0;
2053}
2054
2055static int wsa_macro_soft_clip_enable_put(struct snd_kcontrol *kcontrol,
2056 struct snd_ctl_elem_value *ucontrol)
2057{
Meng Wang15c825d2018-09-06 10:49:18 +08002058 struct snd_soc_component *component =
2059 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302060 struct device *wsa_dev = NULL;
2061 struct wsa_macro_priv *wsa_priv = NULL;
2062 int path = ((struct soc_multi_mixer_control *)
2063 kcontrol->private_value)->shift;
2064
Meng Wang15c825d2018-09-06 10:49:18 +08002065 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302066 return -EINVAL;
2067
2068 wsa_priv->is_softclip_on[path] = ucontrol->value.integer.value[0];
2069
Meng Wang15c825d2018-09-06 10:49:18 +08002070 dev_dbg(component->dev, "%s: soft clip enable for %d: %d\n", __func__,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302071 path, wsa_priv->is_softclip_on[path]);
2072
2073 return 0;
2074}
2075
Laxminath Kasam243e2752018-04-12 00:40:19 +05302076static const struct snd_kcontrol_new wsa_macro_snd_controls[] = {
2077 SOC_ENUM_EXT("EAR SPKR PA Gain", wsa_macro_ear_spkr_pa_gain_enum,
2078 wsa_macro_ear_spkr_pa_gain_get,
2079 wsa_macro_ear_spkr_pa_gain_put),
2080 SOC_ENUM_EXT("SPKR Left Boost Max State",
2081 wsa_macro_spkr_boost_stage_enum,
2082 wsa_macro_spkr_left_boost_stage_get,
2083 wsa_macro_spkr_left_boost_stage_put),
2084 SOC_ENUM_EXT("SPKR Right Boost Max State",
2085 wsa_macro_spkr_boost_stage_enum,
2086 wsa_macro_spkr_right_boost_stage_get,
2087 wsa_macro_spkr_right_boost_stage_put),
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302088 SOC_ENUM_EXT("GSM mode Enable", wsa_macro_vbat_bcl_gsm_mode_enum,
2089 wsa_macro_vbat_bcl_gsm_mode_func_get,
2090 wsa_macro_vbat_bcl_gsm_mode_func_put),
2091 SOC_SINGLE_EXT("WSA_Softclip0 Enable", SND_SOC_NOPM,
2092 WSA_MACRO_SOFTCLIP0, 1, 0,
2093 wsa_macro_soft_clip_enable_get,
2094 wsa_macro_soft_clip_enable_put),
2095 SOC_SINGLE_EXT("WSA_Softclip1 Enable", SND_SOC_NOPM,
2096 WSA_MACRO_SOFTCLIP1, 1, 0,
2097 wsa_macro_soft_clip_enable_get,
2098 wsa_macro_soft_clip_enable_put),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302099 SOC_SINGLE_SX_TLV("WSA_RX0 Digital Volume",
2100 BOLERO_CDC_WSA_RX0_RX_VOL_CTL,
2101 0, -84, 40, digital_gain),
2102 SOC_SINGLE_SX_TLV("WSA_RX1 Digital Volume",
2103 BOLERO_CDC_WSA_RX1_RX_VOL_CTL,
2104 0, -84, 40, digital_gain),
2105 SOC_SINGLE_EXT("WSA_COMP1 Switch", SND_SOC_NOPM, WSA_MACRO_COMP1, 1, 0,
2106 wsa_macro_get_compander, wsa_macro_set_compander),
2107 SOC_SINGLE_EXT("WSA_COMP2 Switch", SND_SOC_NOPM, WSA_MACRO_COMP2, 1, 0,
2108 wsa_macro_get_compander, wsa_macro_set_compander),
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05302109 SOC_SINGLE_EXT("WSA_RX0 EC_HQ Switch", SND_SOC_NOPM, WSA_MACRO_RX0,
2110 1, 0, wsa_macro_get_ec_hq, wsa_macro_set_ec_hq),
2111 SOC_SINGLE_EXT("WSA_RX1 EC_HQ Switch", SND_SOC_NOPM, WSA_MACRO_RX1,
2112 1, 0, wsa_macro_get_ec_hq, wsa_macro_set_ec_hq),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302113};
2114
2115static const struct soc_enum rx_mux_enum =
2116 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_mux_text), rx_mux_text);
2117
2118static const struct snd_kcontrol_new rx_mux[WSA_MACRO_RX_MAX] = {
2119 SOC_DAPM_ENUM_EXT("WSA RX0 Mux", rx_mux_enum,
2120 wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),
2121 SOC_DAPM_ENUM_EXT("WSA RX1 Mux", rx_mux_enum,
2122 wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),
2123 SOC_DAPM_ENUM_EXT("WSA RX_MIX0 Mux", rx_mux_enum,
2124 wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),
2125 SOC_DAPM_ENUM_EXT("WSA RX_MIX1 Mux", rx_mux_enum,
2126 wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),
2127};
2128
2129static int wsa_macro_vi_feed_mixer_get(struct snd_kcontrol *kcontrol,
2130 struct snd_ctl_elem_value *ucontrol)
2131{
2132 struct snd_soc_dapm_widget *widget =
2133 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +08002134 struct snd_soc_component *component =
2135 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302136 struct soc_multi_mixer_control *mixer =
2137 ((struct soc_multi_mixer_control *)kcontrol->private_value);
2138 u32 dai_id = widget->shift;
2139 u32 spk_tx_id = mixer->shift;
2140 struct device *wsa_dev = NULL;
2141 struct wsa_macro_priv *wsa_priv = NULL;
2142
Meng Wang15c825d2018-09-06 10:49:18 +08002143 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302144 return -EINVAL;
2145
2146 if (test_bit(spk_tx_id, &wsa_priv->active_ch_mask[dai_id]))
2147 ucontrol->value.integer.value[0] = 1;
2148 else
2149 ucontrol->value.integer.value[0] = 0;
2150
2151 return 0;
2152}
2153
2154static int wsa_macro_vi_feed_mixer_put(struct snd_kcontrol *kcontrol,
2155 struct snd_ctl_elem_value *ucontrol)
2156{
2157 struct snd_soc_dapm_widget *widget =
2158 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +08002159 struct snd_soc_component *component =
2160 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302161 struct soc_multi_mixer_control *mixer =
2162 ((struct soc_multi_mixer_control *)kcontrol->private_value);
2163 u32 spk_tx_id = mixer->shift;
2164 u32 enable = ucontrol->value.integer.value[0];
2165 struct device *wsa_dev = NULL;
2166 struct wsa_macro_priv *wsa_priv = NULL;
2167
Meng Wang15c825d2018-09-06 10:49:18 +08002168 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302169 return -EINVAL;
2170
2171 wsa_priv->vi_feed_value = ucontrol->value.integer.value[0];
2172
2173 if (enable) {
2174 if (spk_tx_id == WSA_MACRO_TX0 &&
2175 !test_bit(WSA_MACRO_TX0,
2176 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
2177 set_bit(WSA_MACRO_TX0,
2178 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI]);
2179 wsa_priv->active_ch_cnt[WSA_MACRO_AIF_VI]++;
2180 }
2181 if (spk_tx_id == WSA_MACRO_TX1 &&
2182 !test_bit(WSA_MACRO_TX1,
2183 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
2184 set_bit(WSA_MACRO_TX1,
2185 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI]);
2186 wsa_priv->active_ch_cnt[WSA_MACRO_AIF_VI]++;
2187 }
2188 } else {
2189 if (spk_tx_id == WSA_MACRO_TX0 &&
2190 test_bit(WSA_MACRO_TX0,
2191 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
2192 clear_bit(WSA_MACRO_TX0,
2193 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI]);
2194 wsa_priv->active_ch_cnt[WSA_MACRO_AIF_VI]--;
2195 }
2196 if (spk_tx_id == WSA_MACRO_TX1 &&
2197 test_bit(WSA_MACRO_TX1,
2198 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
2199 clear_bit(WSA_MACRO_TX1,
2200 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI]);
2201 wsa_priv->active_ch_cnt[WSA_MACRO_AIF_VI]--;
2202 }
2203 }
2204 snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, NULL);
2205
2206 return 0;
2207}
2208
2209static const struct snd_kcontrol_new aif_vi_mixer[] = {
2210 SOC_SINGLE_EXT("WSA_SPKR_VI_1", SND_SOC_NOPM, WSA_MACRO_TX0, 1, 0,
2211 wsa_macro_vi_feed_mixer_get,
2212 wsa_macro_vi_feed_mixer_put),
2213 SOC_SINGLE_EXT("WSA_SPKR_VI_2", SND_SOC_NOPM, WSA_MACRO_TX1, 1, 0,
2214 wsa_macro_vi_feed_mixer_get,
2215 wsa_macro_vi_feed_mixer_put),
2216};
2217
2218static const struct snd_soc_dapm_widget wsa_macro_dapm_widgets[] = {
2219 SND_SOC_DAPM_AIF_IN("WSA AIF1 PB", "WSA_AIF1 Playback", 0,
2220 SND_SOC_NOPM, 0, 0),
2221
2222 SND_SOC_DAPM_AIF_IN("WSA AIF_MIX1 PB", "WSA_AIF_MIX1 Playback", 0,
2223 SND_SOC_NOPM, 0, 0),
2224
2225 SND_SOC_DAPM_AIF_OUT_E("WSA AIF_VI", "WSA_AIF_VI Capture", 0,
2226 SND_SOC_NOPM, WSA_MACRO_AIF_VI, 0,
2227 wsa_macro_enable_vi_feedback,
2228 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
2229
2230 SND_SOC_DAPM_AIF_OUT("WSA AIF_ECHO", "WSA_AIF_ECHO Capture", 0,
2231 SND_SOC_NOPM, 0, 0),
2232
2233 SND_SOC_DAPM_MIXER("WSA_AIF_VI Mixer", SND_SOC_NOPM, WSA_MACRO_AIF_VI,
2234 0, aif_vi_mixer, ARRAY_SIZE(aif_vi_mixer)),
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05302235 SND_SOC_DAPM_MUX_E("WSA RX_MIX EC0_MUX", SND_SOC_NOPM,
2236 WSA_MACRO_EC0_MUX, 0,
2237 &rx_mix_ec0_mux, wsa_macro_enable_echo,
2238 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2239 SND_SOC_DAPM_MUX_E("WSA RX_MIX EC1_MUX", SND_SOC_NOPM,
2240 WSA_MACRO_EC1_MUX, 0,
2241 &rx_mix_ec1_mux, wsa_macro_enable_echo,
2242 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302243
2244 SND_SOC_DAPM_MUX("WSA RX0 MUX", SND_SOC_NOPM, WSA_MACRO_RX0, 0,
2245 &rx_mux[WSA_MACRO_RX0]),
2246 SND_SOC_DAPM_MUX("WSA RX1 MUX", SND_SOC_NOPM, WSA_MACRO_RX1, 0,
2247 &rx_mux[WSA_MACRO_RX1]),
2248 SND_SOC_DAPM_MUX("WSA RX_MIX0 MUX", SND_SOC_NOPM, WSA_MACRO_RX_MIX0, 0,
2249 &rx_mux[WSA_MACRO_RX_MIX0]),
2250 SND_SOC_DAPM_MUX("WSA RX_MIX1 MUX", SND_SOC_NOPM, WSA_MACRO_RX_MIX1, 0,
2251 &rx_mux[WSA_MACRO_RX_MIX1]),
2252
2253 SND_SOC_DAPM_MIXER("WSA RX0", SND_SOC_NOPM, 0, 0, NULL, 0),
2254 SND_SOC_DAPM_MIXER("WSA RX1", SND_SOC_NOPM, 0, 0, NULL, 0),
2255 SND_SOC_DAPM_MIXER("WSA RX_MIX0", SND_SOC_NOPM, 0, 0, NULL, 0),
2256 SND_SOC_DAPM_MIXER("WSA RX_MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
2257
2258 SND_SOC_DAPM_MUX_E("WSA_RX0 INP0", SND_SOC_NOPM, 0, 0,
2259 &rx0_prim_inp0_mux, wsa_macro_enable_swr,
2260 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2261 SND_SOC_DAPM_MUX_E("WSA_RX0 INP1", SND_SOC_NOPM, 0, 0,
2262 &rx0_prim_inp1_mux, wsa_macro_enable_swr,
2263 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2264 SND_SOC_DAPM_MUX_E("WSA_RX0 INP2", SND_SOC_NOPM, 0, 0,
2265 &rx0_prim_inp2_mux, wsa_macro_enable_swr,
2266 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2267 SND_SOC_DAPM_MUX_E("WSA_RX0 MIX INP", SND_SOC_NOPM, 0, 0,
2268 &rx0_mix_mux, wsa_macro_enable_mix_path,
2269 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2270 SND_SOC_DAPM_MUX_E("WSA_RX1 INP0", SND_SOC_NOPM, 0, 0,
2271 &rx1_prim_inp0_mux, wsa_macro_enable_swr,
2272 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2273 SND_SOC_DAPM_MUX_E("WSA_RX1 INP1", SND_SOC_NOPM, 0, 0,
2274 &rx1_prim_inp1_mux, wsa_macro_enable_swr,
2275 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2276 SND_SOC_DAPM_MUX_E("WSA_RX1 INP2", SND_SOC_NOPM, 0, 0,
2277 &rx1_prim_inp2_mux, wsa_macro_enable_swr,
2278 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2279 SND_SOC_DAPM_MUX_E("WSA_RX1 MIX INP", SND_SOC_NOPM, 0, 0,
2280 &rx1_mix_mux, wsa_macro_enable_mix_path,
2281 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2282 SND_SOC_DAPM_MIXER("WSA_RX INT0 MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
2283 SND_SOC_DAPM_MIXER("WSA_RX INT1 MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
2284 SND_SOC_DAPM_MIXER("WSA_RX INT0 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
2285 SND_SOC_DAPM_MIXER("WSA_RX INT1 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
2286
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302287 SND_SOC_DAPM_MUX_E("WSA_RX0 INT0 SIDETONE MIX",
2288 BOLERO_CDC_WSA_RX0_RX_PATH_CFG1, 4, 0,
2289 &rx0_sidetone_mix_mux, wsa_macro_enable_swr,
2290 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2291 SND_SOC_DAPM_INPUT("WSA SRC0_INP"),
2292
2293 SND_SOC_DAPM_INPUT("WSA_TX DEC0_INP"),
2294 SND_SOC_DAPM_INPUT("WSA_TX DEC1_INP"),
2295
Laxminath Kasam243e2752018-04-12 00:40:19 +05302296 SND_SOC_DAPM_MIXER_E("WSA_RX INT0 INTERP", SND_SOC_NOPM,
2297 WSA_MACRO_COMP1, 0, NULL, 0, wsa_macro_enable_interpolator,
2298 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2299 SND_SOC_DAPM_POST_PMD),
2300 SND_SOC_DAPM_MIXER_E("WSA_RX INT1 INTERP", SND_SOC_NOPM,
2301 WSA_MACRO_COMP2, 0, NULL, 0, wsa_macro_enable_interpolator,
2302 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2303 SND_SOC_DAPM_POST_PMD),
2304
2305 SND_SOC_DAPM_MIXER_E("WSA_RX INT0 CHAIN", SND_SOC_NOPM, 0, 0,
2306 NULL, 0, wsa_macro_spk_boost_event,
Laxminath Kasam0c857002018-07-17 23:47:17 +05302307 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2308 SND_SOC_DAPM_POST_PMD),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302309 SND_SOC_DAPM_MIXER_E("WSA_RX INT1 CHAIN", SND_SOC_NOPM, 0, 0,
2310 NULL, 0, wsa_macro_spk_boost_event,
Laxminath Kasam0c857002018-07-17 23:47:17 +05302311 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2312 SND_SOC_DAPM_POST_PMD),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302313
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302314 SND_SOC_DAPM_MIXER_E("WSA_RX INT0 VBAT", SND_SOC_NOPM,
2315 0, 0, wsa_int0_vbat_mix_switch,
2316 ARRAY_SIZE(wsa_int0_vbat_mix_switch),
2317 wsa_macro_enable_vbat,
2318 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2319 SND_SOC_DAPM_MIXER_E("WSA_RX INT1 VBAT", SND_SOC_NOPM,
2320 0, 0, wsa_int1_vbat_mix_switch,
2321 ARRAY_SIZE(wsa_int1_vbat_mix_switch),
2322 wsa_macro_enable_vbat,
2323 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2324
Laxminath Kasam243e2752018-04-12 00:40:19 +05302325 SND_SOC_DAPM_INPUT("VIINPUT_WSA"),
2326
2327 SND_SOC_DAPM_OUTPUT("WSA_SPK1 OUT"),
2328 SND_SOC_DAPM_OUTPUT("WSA_SPK2 OUT"),
2329
2330 SND_SOC_DAPM_SUPPLY_S("WSA_MCLK", 0, SND_SOC_NOPM, 0, 0,
2331 wsa_macro_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2332};
2333
2334static const struct snd_soc_dapm_route wsa_audio_map[] = {
2335 /* VI Feedback */
2336 {"WSA_AIF_VI Mixer", "WSA_SPKR_VI_1", "VIINPUT_WSA"},
2337 {"WSA_AIF_VI Mixer", "WSA_SPKR_VI_2", "VIINPUT_WSA"},
2338 {"WSA AIF_VI", NULL, "WSA_AIF_VI Mixer"},
2339 {"WSA AIF_VI", NULL, "WSA_MCLK"},
2340
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05302341 {"WSA RX_MIX EC0_MUX", "RX_MIX_TX0", "WSA_RX INT0 SEC MIX"},
2342 {"WSA RX_MIX EC1_MUX", "RX_MIX_TX0", "WSA_RX INT0 SEC MIX"},
2343 {"WSA RX_MIX EC0_MUX", "RX_MIX_TX1", "WSA_RX INT1 SEC MIX"},
2344 {"WSA RX_MIX EC1_MUX", "RX_MIX_TX1", "WSA_RX INT1 SEC MIX"},
2345 {"WSA AIF_ECHO", NULL, "WSA RX_MIX EC0_MUX"},
2346 {"WSA AIF_ECHO", NULL, "WSA RX_MIX EC1_MUX"},
2347 {"WSA AIF_ECHO", NULL, "WSA_MCLK"},
2348
Laxminath Kasam243e2752018-04-12 00:40:19 +05302349 {"WSA AIF1 PB", NULL, "WSA_MCLK"},
2350 {"WSA AIF_MIX1 PB", NULL, "WSA_MCLK"},
2351
2352 {"WSA RX0 MUX", "AIF1_PB", "WSA AIF1 PB"},
2353 {"WSA RX1 MUX", "AIF1_PB", "WSA AIF1 PB"},
2354 {"WSA RX_MIX0 MUX", "AIF1_PB", "WSA AIF1 PB"},
2355 {"WSA RX_MIX1 MUX", "AIF1_PB", "WSA AIF1 PB"},
2356
2357 {"WSA RX0 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
2358 {"WSA RX1 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
2359 {"WSA RX_MIX0 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
2360 {"WSA RX_MIX1 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
2361
2362 {"WSA RX0", NULL, "WSA RX0 MUX"},
2363 {"WSA RX1", NULL, "WSA RX1 MUX"},
2364 {"WSA RX_MIX0", NULL, "WSA RX_MIX0 MUX"},
2365 {"WSA RX_MIX1", NULL, "WSA RX_MIX1 MUX"},
2366
2367 {"WSA_RX0 INP0", "RX0", "WSA RX0"},
2368 {"WSA_RX0 INP0", "RX1", "WSA RX1"},
2369 {"WSA_RX0 INP0", "RX_MIX0", "WSA RX_MIX0"},
2370 {"WSA_RX0 INP0", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302371 {"WSA_RX0 INP0", "DEC0", "WSA_TX DEC0_INP"},
2372 {"WSA_RX0 INP0", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302373 {"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP0"},
2374
2375 {"WSA_RX0 INP1", "RX0", "WSA RX0"},
2376 {"WSA_RX0 INP1", "RX1", "WSA RX1"},
2377 {"WSA_RX0 INP1", "RX_MIX0", "WSA RX_MIX0"},
2378 {"WSA_RX0 INP1", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302379 {"WSA_RX0 INP1", "DEC0", "WSA_TX DEC0_INP"},
2380 {"WSA_RX0 INP1", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302381 {"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP1"},
2382
2383 {"WSA_RX0 INP2", "RX0", "WSA RX0"},
2384 {"WSA_RX0 INP2", "RX1", "WSA RX1"},
2385 {"WSA_RX0 INP2", "RX_MIX0", "WSA RX_MIX0"},
2386 {"WSA_RX0 INP2", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302387 {"WSA_RX0 INP2", "DEC0", "WSA_TX DEC0_INP"},
2388 {"WSA_RX0 INP2", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302389 {"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP2"},
2390
2391 {"WSA_RX0 MIX INP", "RX0", "WSA RX0"},
2392 {"WSA_RX0 MIX INP", "RX1", "WSA RX1"},
2393 {"WSA_RX0 MIX INP", "RX_MIX0", "WSA RX_MIX0"},
2394 {"WSA_RX0 MIX INP", "RX_MIX1", "WSA RX_MIX1"},
2395 {"WSA_RX INT0 SEC MIX", NULL, "WSA_RX0 MIX INP"},
2396
2397 {"WSA_RX INT0 SEC MIX", NULL, "WSA_RX INT0 MIX"},
2398 {"WSA_RX INT0 INTERP", NULL, "WSA_RX INT0 SEC MIX"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302399 {"WSA_RX0 INT0 SIDETONE MIX", "SRC0", "WSA SRC0_INP"},
2400 {"WSA_RX INT0 INTERP", NULL, "WSA_RX0 INT0 SIDETONE MIX"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302401 {"WSA_RX INT0 CHAIN", NULL, "WSA_RX INT0 INTERP"},
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302402
2403 {"WSA_RX INT0 VBAT", "WSA RX0 VBAT Enable", "WSA_RX INT0 INTERP"},
2404 {"WSA_RX INT0 CHAIN", NULL, "WSA_RX INT0 VBAT"},
2405
Laxminath Kasam243e2752018-04-12 00:40:19 +05302406 {"WSA_SPK1 OUT", NULL, "WSA_RX INT0 CHAIN"},
Laxminath Kasamfc281ad2018-08-06 20:19:40 +05302407 {"WSA_SPK1 OUT", NULL, "WSA_MCLK"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302408
2409 {"WSA_RX1 INP0", "RX0", "WSA RX0"},
2410 {"WSA_RX1 INP0", "RX1", "WSA RX1"},
2411 {"WSA_RX1 INP0", "RX_MIX0", "WSA RX_MIX0"},
2412 {"WSA_RX1 INP0", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302413 {"WSA_RX1 INP0", "DEC0", "WSA_TX DEC0_INP"},
2414 {"WSA_RX1 INP0", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302415 {"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP0"},
2416
2417 {"WSA_RX1 INP1", "RX0", "WSA RX0"},
2418 {"WSA_RX1 INP1", "RX1", "WSA RX1"},
2419 {"WSA_RX1 INP1", "RX_MIX0", "WSA RX_MIX0"},
2420 {"WSA_RX1 INP1", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302421 {"WSA_RX1 INP1", "DEC0", "WSA_TX DEC0_INP"},
2422 {"WSA_RX1 INP1", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302423 {"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP1"},
2424
2425 {"WSA_RX1 INP2", "RX0", "WSA RX0"},
2426 {"WSA_RX1 INP2", "RX1", "WSA RX1"},
2427 {"WSA_RX1 INP2", "RX_MIX0", "WSA RX_MIX0"},
2428 {"WSA_RX1 INP2", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302429 {"WSA_RX1 INP2", "DEC0", "WSA_TX DEC0_INP"},
2430 {"WSA_RX1 INP2", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302431 {"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP2"},
2432
2433 {"WSA_RX1 MIX INP", "RX0", "WSA RX0"},
2434 {"WSA_RX1 MIX INP", "RX1", "WSA RX1"},
2435 {"WSA_RX1 MIX INP", "RX_MIX0", "WSA RX_MIX0"},
2436 {"WSA_RX1 MIX INP", "RX_MIX1", "WSA RX_MIX1"},
2437 {"WSA_RX INT1 SEC MIX", NULL, "WSA_RX1 MIX INP"},
2438
2439 {"WSA_RX INT1 SEC MIX", NULL, "WSA_RX INT1 MIX"},
2440 {"WSA_RX INT1 INTERP", NULL, "WSA_RX INT1 SEC MIX"},
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302441
2442 {"WSA_RX INT1 VBAT", "WSA RX1 VBAT Enable", "WSA_RX INT1 INTERP"},
2443 {"WSA_RX INT1 CHAIN", NULL, "WSA_RX INT1 VBAT"},
2444
Laxminath Kasam243e2752018-04-12 00:40:19 +05302445 {"WSA_RX INT1 CHAIN", NULL, "WSA_RX INT1 INTERP"},
2446 {"WSA_SPK2 OUT", NULL, "WSA_RX INT1 CHAIN"},
Laxminath Kasamfc281ad2018-08-06 20:19:40 +05302447 {"WSA_SPK2 OUT", NULL, "WSA_MCLK"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302448};
2449
2450static const struct wsa_macro_reg_mask_val wsa_macro_reg_init[] = {
2451 {BOLERO_CDC_WSA_BOOST0_BOOST_CFG1, 0x3F, 0x12},
2452 {BOLERO_CDC_WSA_BOOST0_BOOST_CFG2, 0x1C, 0x08},
2453 {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x1E, 0x18},
2454 {BOLERO_CDC_WSA_BOOST1_BOOST_CFG1, 0x3F, 0x12},
2455 {BOLERO_CDC_WSA_BOOST1_BOOST_CFG2, 0x1C, 0x08},
2456 {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x1E, 0x18},
2457 {BOLERO_CDC_WSA_BOOST0_BOOST_CTL, 0x70, 0x58},
2458 {BOLERO_CDC_WSA_BOOST1_BOOST_CTL, 0x70, 0x58},
2459 {BOLERO_CDC_WSA_RX0_RX_PATH_CFG1, 0x08, 0x08},
2460 {BOLERO_CDC_WSA_RX1_RX_PATH_CFG1, 0x08, 0x08},
2461 {BOLERO_CDC_WSA_TOP_TOP_CFG1, 0x02, 0x02},
2462 {BOLERO_CDC_WSA_TOP_TOP_CFG1, 0x01, 0x01},
2463 {BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
2464 {BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
2465 {BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
2466 {BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
2467 {BOLERO_CDC_WSA_COMPANDER0_CTL3, 0x80, 0x80},
2468 {BOLERO_CDC_WSA_COMPANDER1_CTL3, 0x80, 0x80},
2469 {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x01, 0x01},
2470 {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x01, 0x01},
2471 {BOLERO_CDC_WSA_RX0_RX_PATH_CFG0, 0x01, 0x01},
2472 {BOLERO_CDC_WSA_RX1_RX_PATH_CFG0, 0x01, 0x01},
2473 {BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CFG, 0x01, 0x01},
2474 {BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CFG, 0x01, 0x01},
2475};
2476
Meng Wang15c825d2018-09-06 10:49:18 +08002477static void wsa_macro_init_bcl_pmic_reg(struct snd_soc_component *component)
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302478{
2479 struct device *wsa_dev = NULL;
2480 struct wsa_macro_priv *wsa_priv = NULL;
2481
Meng Wang15c825d2018-09-06 10:49:18 +08002482 if (!component) {
2483 pr_err("%s: NULL component pointer!\n", __func__);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302484 return;
2485 }
2486
Meng Wang15c825d2018-09-06 10:49:18 +08002487 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302488 return;
2489
2490 switch (wsa_priv->bcl_pmic_params.id) {
2491 case 0:
2492 /* Enable ID0 to listen to respective PMIC group interrupts */
Meng Wang15c825d2018-09-06 10:49:18 +08002493 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302494 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CTL1, 0x02, 0x02);
2495 /* Update MC_SID0 */
Meng Wang15c825d2018-09-06 10:49:18 +08002496 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302497 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG1, 0x0F,
2498 wsa_priv->bcl_pmic_params.sid);
2499 /* Update MC_PPID0 */
Meng Wang15c825d2018-09-06 10:49:18 +08002500 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302501 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG2, 0xFF,
2502 wsa_priv->bcl_pmic_params.ppid);
2503 break;
2504 case 1:
2505 /* Enable ID1 to listen to respective PMIC group interrupts */
Meng Wang15c825d2018-09-06 10:49:18 +08002506 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302507 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CTL1, 0x01, 0x01);
2508 /* Update MC_SID1 */
Meng Wang15c825d2018-09-06 10:49:18 +08002509 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302510 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG3, 0x0F,
2511 wsa_priv->bcl_pmic_params.sid);
2512 /* Update MC_PPID1 */
Meng Wang15c825d2018-09-06 10:49:18 +08002513 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302514 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG4, 0xFF,
2515 wsa_priv->bcl_pmic_params.ppid);
2516 break;
2517 default:
2518 dev_err(wsa_dev, "%s: PMIC ID is invalid %d\n",
2519 __func__, wsa_priv->bcl_pmic_params.id);
2520 break;
2521 }
2522}
2523
Meng Wang15c825d2018-09-06 10:49:18 +08002524static void wsa_macro_init_reg(struct snd_soc_component *component)
Laxminath Kasam243e2752018-04-12 00:40:19 +05302525{
2526 int i;
2527
2528 for (i = 0; i < ARRAY_SIZE(wsa_macro_reg_init); i++)
Meng Wang15c825d2018-09-06 10:49:18 +08002529 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302530 wsa_macro_reg_init[i].reg,
2531 wsa_macro_reg_init[i].mask,
2532 wsa_macro_reg_init[i].val);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302533
Meng Wang15c825d2018-09-06 10:49:18 +08002534 wsa_macro_init_bcl_pmic_reg(component);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302535}
2536
2537static int wsa_swrm_clock(void *handle, bool enable)
2538{
2539 struct wsa_macro_priv *wsa_priv = (struct wsa_macro_priv *) handle;
2540 struct regmap *regmap = dev_get_regmap(wsa_priv->dev->parent, NULL);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302541 int ret = 0;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302542
Tanya Dixitab8eba82018-10-05 15:07:37 +05302543 if (regmap == NULL) {
2544 dev_err(wsa_priv->dev, "%s: regmap is NULL\n", __func__);
2545 return -EINVAL;
2546 }
2547
Laxminath Kasam243e2752018-04-12 00:40:19 +05302548 mutex_lock(&wsa_priv->swr_clk_lock);
2549
2550 dev_dbg(wsa_priv->dev, "%s: swrm clock %s\n",
2551 __func__, (enable ? "enable" : "disable"));
2552 if (enable) {
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302553 pm_runtime_get_sync(wsa_priv->dev);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302554 if (wsa_priv->swr_clk_users == 0) {
Karthikeyan Mani01f1ba42019-02-26 18:48:15 -08002555 msm_cdc_pinctrl_select_active_state(
2556 wsa_priv->wsa_swr_gpio_p);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302557 ret = wsa_macro_mclk_enable(wsa_priv, 1, true);
2558 if (ret < 0) {
Karthikeyan Mani01f1ba42019-02-26 18:48:15 -08002559 msm_cdc_pinctrl_select_sleep_state(
2560 wsa_priv->wsa_swr_gpio_p);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302561 dev_err(wsa_priv->dev,
2562 "%s: wsa request clock enable failed\n",
2563 __func__);
2564 goto exit;
2565 }
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05302566 if (wsa_priv->reset_swr)
2567 regmap_update_bits(regmap,
2568 BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
2569 0x02, 0x02);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302570 regmap_update_bits(regmap,
2571 BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
2572 0x01, 0x01);
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05302573 if (wsa_priv->reset_swr)
2574 regmap_update_bits(regmap,
2575 BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
2576 0x02, 0x00);
2577 wsa_priv->reset_swr = false;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302578 }
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302579 pm_runtime_mark_last_busy(wsa_priv->dev);
2580 pm_runtime_put_autosuspend(wsa_priv->dev);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302581 wsa_priv->swr_clk_users++;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302582 } else {
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302583 if (wsa_priv->swr_clk_users <= 0) {
2584 dev_err(wsa_priv->dev, "%s: clock already disabled\n",
2585 __func__);
2586 wsa_priv->swr_clk_users = 0;
2587 goto exit;
2588 }
Laxminath Kasam243e2752018-04-12 00:40:19 +05302589 wsa_priv->swr_clk_users--;
2590 if (wsa_priv->swr_clk_users == 0) {
2591 regmap_update_bits(regmap,
2592 BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
2593 0x01, 0x00);
Karthikeyan Mani01f1ba42019-02-26 18:48:15 -08002594 wsa_macro_mclk_enable(wsa_priv, 0, true);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302595 msm_cdc_pinctrl_select_sleep_state(
2596 wsa_priv->wsa_swr_gpio_p);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302597 }
2598 }
2599 dev_dbg(wsa_priv->dev, "%s: swrm clock users %d\n",
2600 __func__, wsa_priv->swr_clk_users);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302601exit:
Laxminath Kasam243e2752018-04-12 00:40:19 +05302602 mutex_unlock(&wsa_priv->swr_clk_lock);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302603 return ret;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302604}
2605
Meng Wang15c825d2018-09-06 10:49:18 +08002606static int wsa_macro_init(struct snd_soc_component *component)
Laxminath Kasam243e2752018-04-12 00:40:19 +05302607{
Meng Wang15c825d2018-09-06 10:49:18 +08002608 struct snd_soc_dapm_context *dapm =
2609 snd_soc_component_get_dapm(component);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302610 int ret;
2611 struct device *wsa_dev = NULL;
2612 struct wsa_macro_priv *wsa_priv = NULL;
2613
Meng Wang15c825d2018-09-06 10:49:18 +08002614 wsa_dev = bolero_get_device_ptr(component->dev, WSA_MACRO);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302615 if (!wsa_dev) {
Meng Wang15c825d2018-09-06 10:49:18 +08002616 dev_err(component->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302617 "%s: null device for macro!\n", __func__);
2618 return -EINVAL;
2619 }
2620 wsa_priv = dev_get_drvdata(wsa_dev);
2621 if (!wsa_priv) {
Meng Wang15c825d2018-09-06 10:49:18 +08002622 dev_err(component->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302623 "%s: priv is null for macro!\n", __func__);
2624 return -EINVAL;
2625 }
2626
2627 ret = snd_soc_dapm_new_controls(dapm, wsa_macro_dapm_widgets,
2628 ARRAY_SIZE(wsa_macro_dapm_widgets));
2629 if (ret < 0) {
2630 dev_err(wsa_dev, "%s: Failed to add controls\n", __func__);
2631 return ret;
2632 }
2633
2634 ret = snd_soc_dapm_add_routes(dapm, wsa_audio_map,
2635 ARRAY_SIZE(wsa_audio_map));
2636 if (ret < 0) {
2637 dev_err(wsa_dev, "%s: Failed to add routes\n", __func__);
2638 return ret;
2639 }
2640
2641 ret = snd_soc_dapm_new_widgets(dapm->card);
2642 if (ret < 0) {
2643 dev_err(wsa_dev, "%s: Failed to add widgets\n", __func__);
2644 return ret;
2645 }
2646
Meng Wang15c825d2018-09-06 10:49:18 +08002647 ret = snd_soc_add_component_controls(component, wsa_macro_snd_controls,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302648 ARRAY_SIZE(wsa_macro_snd_controls));
2649 if (ret < 0) {
2650 dev_err(wsa_dev, "%s: Failed to add snd_ctls\n", __func__);
2651 return ret;
2652 }
Laxminath Kasam638b5602018-09-24 13:19:52 +05302653 snd_soc_dapm_ignore_suspend(dapm, "WSA_AIF1 Playback");
2654 snd_soc_dapm_ignore_suspend(dapm, "WSA_AIF_MIX1 Playback");
2655 snd_soc_dapm_ignore_suspend(dapm, "WSA_AIF_VI Capture");
2656 snd_soc_dapm_ignore_suspend(dapm, "WSA_AIF_ECHO Capture");
2657 snd_soc_dapm_ignore_suspend(dapm, "WSA_SPK1 OUT");
2658 snd_soc_dapm_ignore_suspend(dapm, "WSA_SPK2 OUT");
2659 snd_soc_dapm_ignore_suspend(dapm, "VIINPUT_WSA");
2660 snd_soc_dapm_ignore_suspend(dapm, "WSA SRC0_INP");
2661 snd_soc_dapm_ignore_suspend(dapm, "WSA_TX DEC0_INP");
2662 snd_soc_dapm_ignore_suspend(dapm, "WSA_TX DEC1_INP");
2663 snd_soc_dapm_sync(dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302664
Meng Wang15c825d2018-09-06 10:49:18 +08002665 wsa_priv->component = component;
Laxminath Kasam21c8b222018-06-21 18:47:22 +05302666 wsa_priv->spkr_gain_offset = WSA_MACRO_GAIN_OFFSET_0_DB;
Meng Wang15c825d2018-09-06 10:49:18 +08002667 wsa_macro_init_reg(component);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302668
2669 return 0;
2670}
2671
Meng Wang15c825d2018-09-06 10:49:18 +08002672static int wsa_macro_deinit(struct snd_soc_component *component)
Laxminath Kasam243e2752018-04-12 00:40:19 +05302673{
2674 struct device *wsa_dev = NULL;
2675 struct wsa_macro_priv *wsa_priv = NULL;
2676
Meng Wang15c825d2018-09-06 10:49:18 +08002677 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302678 return -EINVAL;
2679
Meng Wang15c825d2018-09-06 10:49:18 +08002680 wsa_priv->component = NULL;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302681
2682 return 0;
2683}
2684
2685static void wsa_macro_add_child_devices(struct work_struct *work)
2686{
2687 struct wsa_macro_priv *wsa_priv;
2688 struct platform_device *pdev;
2689 struct device_node *node;
2690 struct wsa_macro_swr_ctrl_data *swr_ctrl_data = NULL, *temp;
2691 int ret;
2692 u16 count = 0, ctrl_num = 0;
2693 struct wsa_macro_swr_ctrl_platform_data *platdata;
2694 char plat_dev_name[WSA_MACRO_SWR_STRING_LEN];
2695
2696 wsa_priv = container_of(work, struct wsa_macro_priv,
2697 wsa_macro_add_child_devices_work);
2698 if (!wsa_priv) {
2699 pr_err("%s: Memory for wsa_priv does not exist\n",
2700 __func__);
2701 return;
2702 }
Laxminath Kasam21c8b222018-06-21 18:47:22 +05302703 if (!wsa_priv->dev || !wsa_priv->dev->of_node) {
Laxminath Kasam243e2752018-04-12 00:40:19 +05302704 dev_err(wsa_priv->dev,
2705 "%s: DT node for wsa_priv does not exist\n", __func__);
2706 return;
2707 }
2708
2709 platdata = &wsa_priv->swr_plat_data;
2710 wsa_priv->child_count = 0;
2711
2712 for_each_available_child_of_node(wsa_priv->dev->of_node, node) {
2713 if (strnstr(node->name, "wsa_swr_master",
2714 strlen("wsa_swr_master")) != NULL)
2715 strlcpy(plat_dev_name, "wsa_swr_ctrl",
2716 (WSA_MACRO_SWR_STRING_LEN - 1));
2717 else if (strnstr(node->name, "msm_cdc_pinctrl",
2718 strlen("msm_cdc_pinctrl")) != NULL)
2719 strlcpy(plat_dev_name, node->name,
2720 (WSA_MACRO_SWR_STRING_LEN - 1));
2721 else
2722 continue;
2723
2724 pdev = platform_device_alloc(plat_dev_name, -1);
2725 if (!pdev) {
2726 dev_err(wsa_priv->dev, "%s: pdev memory alloc failed\n",
2727 __func__);
2728 ret = -ENOMEM;
2729 goto err;
2730 }
2731 pdev->dev.parent = wsa_priv->dev;
2732 pdev->dev.of_node = node;
2733
2734 if (strnstr(node->name, "wsa_swr_master",
2735 strlen("wsa_swr_master")) != NULL) {
2736 ret = platform_device_add_data(pdev, platdata,
2737 sizeof(*platdata));
2738 if (ret) {
2739 dev_err(&pdev->dev,
2740 "%s: cannot add plat data ctrl:%d\n",
2741 __func__, ctrl_num);
2742 goto fail_pdev_add;
2743 }
2744 }
2745
2746 ret = platform_device_add(pdev);
2747 if (ret) {
2748 dev_err(&pdev->dev,
2749 "%s: Cannot add platform device\n",
2750 __func__);
2751 goto fail_pdev_add;
2752 }
2753
2754 if (!strcmp(node->name, "wsa_swr_master")) {
2755 temp = krealloc(swr_ctrl_data,
2756 (ctrl_num + 1) * sizeof(
2757 struct wsa_macro_swr_ctrl_data),
2758 GFP_KERNEL);
2759 if (!temp) {
2760 dev_err(&pdev->dev, "out of memory\n");
2761 ret = -ENOMEM;
2762 goto err;
2763 }
2764 swr_ctrl_data = temp;
2765 swr_ctrl_data[ctrl_num].wsa_swr_pdev = pdev;
2766 ctrl_num++;
2767 dev_dbg(&pdev->dev,
2768 "%s: Added soundwire ctrl device(s)\n",
2769 __func__);
2770 wsa_priv->swr_ctrl_data = swr_ctrl_data;
2771 }
2772 if (wsa_priv->child_count < WSA_MACRO_CHILD_DEVICES_MAX)
2773 wsa_priv->pdev_child_devices[
2774 wsa_priv->child_count++] = pdev;
2775 else
2776 goto err;
2777 }
2778
2779 return;
2780fail_pdev_add:
2781 for (count = 0; count < wsa_priv->child_count; count++)
2782 platform_device_put(wsa_priv->pdev_child_devices[count]);
2783err:
2784 return;
2785}
2786
2787static void wsa_macro_init_ops(struct macro_ops *ops,
2788 char __iomem *wsa_io_base)
2789{
2790 memset(ops, 0, sizeof(struct macro_ops));
2791 ops->init = wsa_macro_init;
2792 ops->exit = wsa_macro_deinit;
2793 ops->io_base = wsa_io_base;
2794 ops->dai_ptr = wsa_macro_dai;
2795 ops->num_dais = ARRAY_SIZE(wsa_macro_dai);
Laxminath Kasamfb0d6832018-09-22 01:49:52 +05302796 ops->event_handler = wsa_macro_event_handler;
Sudheer Papothia3e969d2018-10-27 06:22:10 +05302797 ops->set_port_map = wsa_macro_set_port_map;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302798}
2799
2800static int wsa_macro_probe(struct platform_device *pdev)
2801{
2802 struct macro_ops ops;
2803 struct wsa_macro_priv *wsa_priv;
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07002804 u32 wsa_base_addr, default_clk_id;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302805 char __iomem *wsa_io_base;
2806 int ret = 0;
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302807 u8 bcl_pmic_params[3];
Laxminath Kasam243e2752018-04-12 00:40:19 +05302808
2809 wsa_priv = devm_kzalloc(&pdev->dev, sizeof(struct wsa_macro_priv),
2810 GFP_KERNEL);
2811 if (!wsa_priv)
2812 return -ENOMEM;
2813
2814 wsa_priv->dev = &pdev->dev;
2815 ret = of_property_read_u32(pdev->dev.of_node, "reg",
2816 &wsa_base_addr);
2817 if (ret) {
2818 dev_err(&pdev->dev, "%s: could not find %s entry in dt\n",
2819 __func__, "reg");
2820 return ret;
2821 }
2822 wsa_priv->wsa_swr_gpio_p = of_parse_phandle(pdev->dev.of_node,
2823 "qcom,wsa-swr-gpios", 0);
2824 if (!wsa_priv->wsa_swr_gpio_p) {
2825 dev_err(&pdev->dev, "%s: swr_gpios handle not provided!\n",
2826 __func__);
2827 return -EINVAL;
2828 }
2829 wsa_io_base = devm_ioremap(&pdev->dev,
2830 wsa_base_addr, WSA_MACRO_MAX_OFFSET);
2831 if (!wsa_io_base) {
2832 dev_err(&pdev->dev, "%s: ioremap failed\n", __func__);
2833 return -EINVAL;
2834 }
2835 wsa_priv->wsa_io_base = wsa_io_base;
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05302836 wsa_priv->reset_swr = true;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302837 INIT_WORK(&wsa_priv->wsa_macro_add_child_devices_work,
2838 wsa_macro_add_child_devices);
2839 wsa_priv->swr_plat_data.handle = (void *) wsa_priv;
2840 wsa_priv->swr_plat_data.read = NULL;
2841 wsa_priv->swr_plat_data.write = NULL;
2842 wsa_priv->swr_plat_data.bulk_write = NULL;
2843 wsa_priv->swr_plat_data.clk = wsa_swrm_clock;
2844 wsa_priv->swr_plat_data.handle_irq = NULL;
2845
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07002846 ret = of_property_read_u32(pdev->dev.of_node, "qcom,default-clk-id",
2847 &default_clk_id);
2848 if (ret) {
2849 dev_err(&pdev->dev, "%s: could not find %s entry in dt\n",
2850 __func__, "qcom,mux0-clk-id");
2851 default_clk_id = WSA_CORE_CLK;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302852 }
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302853
2854 ret = of_property_read_u8_array(pdev->dev.of_node,
2855 "qcom,wsa-bcl-pmic-params", bcl_pmic_params,
2856 sizeof(bcl_pmic_params));
2857 if (ret) {
2858 dev_dbg(&pdev->dev, "%s: could not find %s entry in dt\n",
2859 __func__, "qcom,wsa-bcl-pmic-params");
2860 } else {
2861 wsa_priv->bcl_pmic_params.id = bcl_pmic_params[0];
2862 wsa_priv->bcl_pmic_params.sid = bcl_pmic_params[1];
2863 wsa_priv->bcl_pmic_params.ppid = bcl_pmic_params[2];
2864 }
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07002865 wsa_priv->default_clk_id = default_clk_id;
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302866
Laxminath Kasam243e2752018-04-12 00:40:19 +05302867 dev_set_drvdata(&pdev->dev, wsa_priv);
2868 mutex_init(&wsa_priv->mclk_lock);
2869 mutex_init(&wsa_priv->swr_clk_lock);
2870 wsa_macro_init_ops(&ops, wsa_io_base);
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07002871 ops.clk_id_req = wsa_priv->default_clk_id;
2872 ops.default_clk_id = wsa_priv->default_clk_id;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302873 ret = bolero_register_macro(&pdev->dev, WSA_MACRO, &ops);
2874 if (ret < 0) {
2875 dev_err(&pdev->dev, "%s: register macro failed\n", __func__);
2876 goto reg_macro_fail;
2877 }
2878 schedule_work(&wsa_priv->wsa_macro_add_child_devices_work);
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302879 pm_runtime_set_autosuspend_delay(&pdev->dev, AUTO_SUSPEND_DELAY);
2880 pm_runtime_use_autosuspend(&pdev->dev);
2881 pm_runtime_set_suspended(&pdev->dev);
2882 pm_runtime_enable(&pdev->dev);
2883
Laxminath Kasam243e2752018-04-12 00:40:19 +05302884 return ret;
2885reg_macro_fail:
2886 mutex_destroy(&wsa_priv->mclk_lock);
2887 mutex_destroy(&wsa_priv->swr_clk_lock);
2888 return ret;
2889}
2890
2891static int wsa_macro_remove(struct platform_device *pdev)
2892{
2893 struct wsa_macro_priv *wsa_priv;
2894 u16 count = 0;
2895
2896 wsa_priv = dev_get_drvdata(&pdev->dev);
2897
2898 if (!wsa_priv)
2899 return -EINVAL;
2900
2901 for (count = 0; count < wsa_priv->child_count &&
2902 count < WSA_MACRO_CHILD_DEVICES_MAX; count++)
2903 platform_device_unregister(wsa_priv->pdev_child_devices[count]);
2904
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302905 pm_runtime_disable(&pdev->dev);
2906 pm_runtime_set_suspended(&pdev->dev);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302907 bolero_unregister_macro(&pdev->dev, WSA_MACRO);
2908 mutex_destroy(&wsa_priv->mclk_lock);
2909 mutex_destroy(&wsa_priv->swr_clk_lock);
2910 return 0;
2911}
2912
2913static const struct of_device_id wsa_macro_dt_match[] = {
2914 {.compatible = "qcom,wsa-macro"},
2915 {}
2916};
2917
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302918static const struct dev_pm_ops bolero_dev_pm_ops = {
2919 SET_RUNTIME_PM_OPS(
2920 bolero_runtime_suspend,
2921 bolero_runtime_resume,
2922 NULL
2923 )
2924};
2925
Laxminath Kasam243e2752018-04-12 00:40:19 +05302926static struct platform_driver wsa_macro_driver = {
2927 .driver = {
2928 .name = "wsa_macro",
2929 .owner = THIS_MODULE,
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302930 .pm = &bolero_dev_pm_ops,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302931 .of_match_table = wsa_macro_dt_match,
2932 },
2933 .probe = wsa_macro_probe,
2934 .remove = wsa_macro_remove,
2935};
2936
2937module_platform_driver(wsa_macro_driver);
2938
2939MODULE_DESCRIPTION("WSA macro driver");
2940MODULE_LICENSE("GPL v2");