blob: b0a4b1e0f42df5c1aed262dbb5573758c64180df [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>
10#include <sound/soc.h>
11#include <sound/soc-dapm.h>
12#include <sound/tlv.h>
Sudheer Papothia3e969d2018-10-27 06:22:10 +053013#include <soc/swr-common.h>
Laxminath Kasam243e2752018-04-12 00:40:19 +053014#include <soc/swr-wcd.h>
15
Meng Wang11a25cf2018-10-31 14:11:26 +080016#include <asoc/msm-cdc-pinctrl.h>
Laxminath Kasam243e2752018-04-12 00:40:19 +053017#include "bolero-cdc.h"
18#include "bolero-cdc-registers.h"
19#include "wsa-macro.h"
Laxminath Kasam243e2752018-04-12 00:40:19 +053020
21#define WSA_MACRO_MAX_OFFSET 0x1000
22
23#define WSA_MACRO_RX_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
24 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
25 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
26#define WSA_MACRO_RX_MIX_RATES (SNDRV_PCM_RATE_48000 |\
27 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
28#define WSA_MACRO_RX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
29 SNDRV_PCM_FMTBIT_S24_LE |\
30 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
31
32#define WSA_MACRO_ECHO_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
33 SNDRV_PCM_RATE_48000)
34#define WSA_MACRO_ECHO_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
35 SNDRV_PCM_FMTBIT_S24_LE |\
36 SNDRV_PCM_FMTBIT_S24_3LE)
37
38#define NUM_INTERPOLATORS 2
39
40#define WSA_MACRO_MUX_INP_SHFT 0x3
41#define WSA_MACRO_MUX_INP_MASK1 0x38
42#define WSA_MACRO_MUX_INP_MASK2 0x38
43#define WSA_MACRO_MUX_CFG_OFFSET 0x8
44#define WSA_MACRO_MUX_CFG1_OFFSET 0x4
45#define WSA_MACRO_RX_COMP_OFFSET 0x40
Aditya Bavanari4f3d5642018-09-18 22:19:10 +053046#define WSA_MACRO_RX_SOFTCLIP_OFFSET 0x40
Laxminath Kasam243e2752018-04-12 00:40:19 +053047#define WSA_MACRO_RX_PATH_OFFSET 0x80
48#define WSA_MACRO_RX_PATH_CFG3_OFFSET 0x10
49#define WSA_MACRO_RX_PATH_DSMDEM_OFFSET 0x4C
50#define WSA_MACRO_FS_RATE_MASK 0x0F
Laxminath Kasam5d9ea8d2018-11-28 14:32:40 +053051#define WSA_MACRO_EC_MIX_TX0_MASK 0x03
52#define WSA_MACRO_EC_MIX_TX1_MASK 0x18
53
Laxminath Kasam243e2752018-04-12 00:40:19 +053054
55enum {
56 WSA_MACRO_RX0 = 0,
57 WSA_MACRO_RX1,
58 WSA_MACRO_RX_MIX,
59 WSA_MACRO_RX_MIX0 = WSA_MACRO_RX_MIX,
60 WSA_MACRO_RX_MIX1,
61 WSA_MACRO_RX_MAX,
62};
63
64enum {
65 WSA_MACRO_TX0 = 0,
66 WSA_MACRO_TX1,
67 WSA_MACRO_TX_MAX,
68};
69
70enum {
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +053071 WSA_MACRO_EC0_MUX = 0,
72 WSA_MACRO_EC1_MUX,
73 WSA_MACRO_EC_MUX_MAX,
74};
75
76enum {
Laxminath Kasam243e2752018-04-12 00:40:19 +053077 WSA_MACRO_COMP1, /* SPK_L */
78 WSA_MACRO_COMP2, /* SPK_R */
79 WSA_MACRO_COMP_MAX
80};
81
Aditya Bavanari4f3d5642018-09-18 22:19:10 +053082enum {
83 WSA_MACRO_SOFTCLIP0, /* RX0 */
84 WSA_MACRO_SOFTCLIP1, /* RX1 */
85 WSA_MACRO_SOFTCLIP_MAX
86};
87
Laxminath Kasam243e2752018-04-12 00:40:19 +053088struct interp_sample_rate {
89 int sample_rate;
90 int rate_val;
91};
92
93/*
94 * Structure used to update codec
95 * register defaults after reset
96 */
97struct wsa_macro_reg_mask_val {
98 u16 reg;
99 u8 mask;
100 u8 val;
101};
102
103static struct interp_sample_rate int_prim_sample_rate_val[] = {
104 {8000, 0x0}, /* 8K */
105 {16000, 0x1}, /* 16K */
106 {24000, -EINVAL},/* 24K */
107 {32000, 0x3}, /* 32K */
108 {48000, 0x4}, /* 48K */
109 {96000, 0x5}, /* 96K */
110 {192000, 0x6}, /* 192K */
111 {384000, 0x7}, /* 384K */
112 {44100, 0x8}, /* 44.1K */
113};
114
115static struct interp_sample_rate int_mix_sample_rate_val[] = {
116 {48000, 0x4}, /* 48K */
117 {96000, 0x5}, /* 96K */
118 {192000, 0x6}, /* 192K */
119};
120
121#define WSA_MACRO_SWR_STRING_LEN 80
122
123static int wsa_macro_hw_params(struct snd_pcm_substream *substream,
124 struct snd_pcm_hw_params *params,
125 struct snd_soc_dai *dai);
126static int wsa_macro_get_channel_map(struct snd_soc_dai *dai,
127 unsigned int *tx_num, unsigned int *tx_slot,
128 unsigned int *rx_num, unsigned int *rx_slot);
129/* Hold instance to soundwire platform device */
130struct wsa_macro_swr_ctrl_data {
131 struct platform_device *wsa_swr_pdev;
132};
133
134struct wsa_macro_swr_ctrl_platform_data {
135 void *handle; /* holds codec private data */
136 int (*read)(void *handle, int reg);
137 int (*write)(void *handle, int reg, int val);
138 int (*bulk_write)(void *handle, u32 *reg, u32 *val, size_t len);
139 int (*clk)(void *handle, bool enable);
140 int (*handle_irq)(void *handle,
141 irqreturn_t (*swrm_irq_handler)(int irq,
142 void *data),
143 void *swrm_handle,
144 int action);
145};
146
Aditya Bavanari4f3d5642018-09-18 22:19:10 +0530147struct wsa_macro_bcl_pmic_params {
148 u8 id;
149 u8 sid;
150 u8 ppid;
151};
152
Laxminath Kasam243e2752018-04-12 00:40:19 +0530153enum {
Laxminath Kasam59c7a1d2018-08-09 16:11:17 +0530154 WSA_MACRO_AIF_INVALID = 0,
155 WSA_MACRO_AIF1_PB,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530156 WSA_MACRO_AIF_MIX1_PB,
157 WSA_MACRO_AIF_VI,
158 WSA_MACRO_AIF_ECHO,
159 WSA_MACRO_MAX_DAIS,
160};
161
162#define WSA_MACRO_CHILD_DEVICES_MAX 3
163
164/*
165 * @dev: wsa macro device pointer
166 * @comp_enabled: compander enable mixer value set
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +0530167 * @ec_hq: echo HQ enable mixer value set
Laxminath Kasam243e2752018-04-12 00:40:19 +0530168 * @prim_int_users: Users of interpolator
169 * @wsa_mclk_users: WSA MCLK users count
170 * @swr_clk_users: SWR clk users count
171 * @vi_feed_value: VI sense mask
172 * @mclk_lock: to lock mclk operations
173 * @swr_clk_lock: to lock swr master clock operations
174 * @swr_ctrl_data: SoundWire data structure
175 * @swr_plat_data: Soundwire platform data
176 * @wsa_macro_add_child_devices_work: work for adding child devices
177 * @wsa_swr_gpio_p: used by pinctrl API
178 * @wsa_core_clk: MCLK for wsa macro
179 * @wsa_npl_clk: NPL clock for WSA soundwire
Meng Wang15c825d2018-09-06 10:49:18 +0800180 * @component: codec handle
Laxminath Kasam243e2752018-04-12 00:40:19 +0530181 * @rx_0_count: RX0 interpolation users
182 * @rx_1_count: RX1 interpolation users
183 * @active_ch_mask: channel mask for all AIF DAIs
184 * @active_ch_cnt: channel count of all AIF DAIs
185 * @rx_port_value: mixer ctl value of WSA RX MUXes
186 * @wsa_io_base: Base address of WSA macro addr space
187 */
188struct wsa_macro_priv {
189 struct device *dev;
190 int comp_enabled[WSA_MACRO_COMP_MAX];
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +0530191 int ec_hq[WSA_MACRO_RX1 + 1];
Laxminath Kasam243e2752018-04-12 00:40:19 +0530192 u16 prim_int_users[WSA_MACRO_RX1 + 1];
193 u16 wsa_mclk_users;
194 u16 swr_clk_users;
Ramprasad Katkam452772a2019-01-07 17:30:36 +0530195 bool dapm_mclk_enable;
Ramprasad Katkama4c747b2018-12-11 19:15:53 +0530196 bool reset_swr;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530197 unsigned int vi_feed_value;
198 struct mutex mclk_lock;
199 struct mutex swr_clk_lock;
200 struct wsa_macro_swr_ctrl_data *swr_ctrl_data;
201 struct wsa_macro_swr_ctrl_platform_data swr_plat_data;
202 struct work_struct wsa_macro_add_child_devices_work;
203 struct device_node *wsa_swr_gpio_p;
204 struct clk *wsa_core_clk;
205 struct clk *wsa_npl_clk;
Meng Wang15c825d2018-09-06 10:49:18 +0800206 struct snd_soc_component *component;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530207 int rx_0_count;
208 int rx_1_count;
209 unsigned long active_ch_mask[WSA_MACRO_MAX_DAIS];
210 unsigned long active_ch_cnt[WSA_MACRO_MAX_DAIS];
211 int rx_port_value[WSA_MACRO_RX_MAX];
212 char __iomem *wsa_io_base;
213 struct platform_device *pdev_child_devices
214 [WSA_MACRO_CHILD_DEVICES_MAX];
215 int child_count;
216 int ear_spkr_gain;
217 int spkr_gain_offset;
218 int spkr_mode;
Aditya Bavanari4f3d5642018-09-18 22:19:10 +0530219 int is_softclip_on[WSA_MACRO_SOFTCLIP_MAX];
220 int softclip_clk_users[WSA_MACRO_SOFTCLIP_MAX];
221 struct wsa_macro_bcl_pmic_params bcl_pmic_params;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530222};
223
Meng Wang15c825d2018-09-06 10:49:18 +0800224static int wsa_macro_config_ear_spkr_gain(struct snd_soc_component *component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530225 struct wsa_macro_priv *wsa_priv,
226 int event, int gain_reg);
227static struct snd_soc_dai_driver wsa_macro_dai[];
228static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0);
229
230static const char *const rx_text[] = {
231 "ZERO", "RX0", "RX1", "RX_MIX0", "RX_MIX1", "DEC0", "DEC1"
232};
233
234static const char *const rx_mix_text[] = {
235 "ZERO", "RX0", "RX1", "RX_MIX0", "RX_MIX1"
236};
237
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +0530238static const char *const rx_mix_ec_text[] = {
239 "ZERO", "RX_MIX_TX0", "RX_MIX_TX1"
240};
241
Laxminath Kasam243e2752018-04-12 00:40:19 +0530242static const char *const rx_mux_text[] = {
243 "ZERO", "AIF1_PB", "AIF_MIX1_PB"
244};
245
Laxminath Kasam6fc2e742018-08-26 23:32:57 +0530246static const char *const rx_sidetone_mix_text[] = {
247 "ZERO", "SRC0"
248};
249
Laxminath Kasam243e2752018-04-12 00:40:19 +0530250static const char * const wsa_macro_ear_spkr_pa_gain_text[] = {
251 "G_DEFAULT", "G_0_DB", "G_1_DB", "G_2_DB", "G_3_DB",
252 "G_4_DB", "G_5_DB", "G_6_DB"
253};
254
255static const char * const wsa_macro_speaker_boost_stage_text[] = {
256 "NO_MAX_STATE", "MAX_STATE_1", "MAX_STATE_2"
257};
258
Aditya Bavanari4f3d5642018-09-18 22:19:10 +0530259static const char * const wsa_macro_vbat_bcl_gsm_mode_text[] = {
260 "OFF", "ON"
261};
262
263static const struct snd_kcontrol_new wsa_int0_vbat_mix_switch[] = {
264 SOC_DAPM_SINGLE("WSA RX0 VBAT Enable", SND_SOC_NOPM, 0, 1, 0)
265};
266
267static const struct snd_kcontrol_new wsa_int1_vbat_mix_switch[] = {
268 SOC_DAPM_SINGLE("WSA RX1 VBAT Enable", SND_SOC_NOPM, 0, 1, 0)
269};
270
Laxminath Kasam243e2752018-04-12 00:40:19 +0530271static SOC_ENUM_SINGLE_EXT_DECL(wsa_macro_ear_spkr_pa_gain_enum,
272 wsa_macro_ear_spkr_pa_gain_text);
273static SOC_ENUM_SINGLE_EXT_DECL(wsa_macro_spkr_boost_stage_enum,
274 wsa_macro_speaker_boost_stage_text);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +0530275static SOC_ENUM_SINGLE_EXT_DECL(wsa_macro_vbat_bcl_gsm_mode_enum,
276 wsa_macro_vbat_bcl_gsm_mode_text);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530277
278/* RX INT0 */
279static const struct soc_enum rx0_prim_inp0_chain_enum =
280 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0,
281 0, 7, rx_text);
282
283static const struct soc_enum rx0_prim_inp1_chain_enum =
284 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0,
285 3, 7, rx_text);
286
287static const struct soc_enum rx0_prim_inp2_chain_enum =
288 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG1,
289 3, 7, rx_text);
290
291static const struct soc_enum rx0_mix_chain_enum =
292 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG1,
293 0, 5, rx_mix_text);
294
Laxminath Kasam6fc2e742018-08-26 23:32:57 +0530295static const struct soc_enum rx0_sidetone_mix_enum =
296 SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, 2, rx_sidetone_mix_text);
297
Laxminath Kasam243e2752018-04-12 00:40:19 +0530298static const struct snd_kcontrol_new rx0_prim_inp0_mux =
299 SOC_DAPM_ENUM("WSA_RX0 INP0 Mux", rx0_prim_inp0_chain_enum);
300
301static const struct snd_kcontrol_new rx0_prim_inp1_mux =
302 SOC_DAPM_ENUM("WSA_RX0 INP1 Mux", rx0_prim_inp1_chain_enum);
303
304static const struct snd_kcontrol_new rx0_prim_inp2_mux =
305 SOC_DAPM_ENUM("WSA_RX0 INP2 Mux", rx0_prim_inp2_chain_enum);
306
307static const struct snd_kcontrol_new rx0_mix_mux =
308 SOC_DAPM_ENUM("WSA_RX0 MIX Mux", rx0_mix_chain_enum);
309
Laxminath Kasam6fc2e742018-08-26 23:32:57 +0530310static const struct snd_kcontrol_new rx0_sidetone_mix_mux =
311 SOC_DAPM_ENUM("WSA_RX0 SIDETONE MIX Mux", rx0_sidetone_mix_enum);
312
Laxminath Kasam243e2752018-04-12 00:40:19 +0530313/* RX INT1 */
314static const struct soc_enum rx1_prim_inp0_chain_enum =
315 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT1_CFG0,
316 0, 7, rx_text);
317
318static const struct soc_enum rx1_prim_inp1_chain_enum =
319 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT1_CFG0,
320 3, 7, rx_text);
321
322static const struct soc_enum rx1_prim_inp2_chain_enum =
323 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT1_CFG1,
324 3, 7, rx_text);
325
326static const struct soc_enum rx1_mix_chain_enum =
327 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT1_CFG1,
328 0, 5, rx_mix_text);
329
330static const struct snd_kcontrol_new rx1_prim_inp0_mux =
331 SOC_DAPM_ENUM("WSA_RX1 INP0 Mux", rx1_prim_inp0_chain_enum);
332
333static const struct snd_kcontrol_new rx1_prim_inp1_mux =
334 SOC_DAPM_ENUM("WSA_RX1 INP1 Mux", rx1_prim_inp1_chain_enum);
335
336static const struct snd_kcontrol_new rx1_prim_inp2_mux =
337 SOC_DAPM_ENUM("WSA_RX1 INP2 Mux", rx1_prim_inp2_chain_enum);
338
339static const struct snd_kcontrol_new rx1_mix_mux =
340 SOC_DAPM_ENUM("WSA_RX1 MIX Mux", rx1_mix_chain_enum);
341
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +0530342static const struct soc_enum rx_mix_ec0_enum =
343 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0,
344 0, 3, rx_mix_ec_text);
345
346static const struct soc_enum rx_mix_ec1_enum =
347 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0,
348 3, 3, rx_mix_ec_text);
349
350static const struct snd_kcontrol_new rx_mix_ec0_mux =
351 SOC_DAPM_ENUM("WSA RX_MIX EC0_Mux", rx_mix_ec0_enum);
352
353static const struct snd_kcontrol_new rx_mix_ec1_mux =
354 SOC_DAPM_ENUM("WSA RX_MIX EC1_Mux", rx_mix_ec1_enum);
355
Laxminath Kasam243e2752018-04-12 00:40:19 +0530356static struct snd_soc_dai_ops wsa_macro_dai_ops = {
357 .hw_params = wsa_macro_hw_params,
358 .get_channel_map = wsa_macro_get_channel_map,
359};
360
361static struct snd_soc_dai_driver wsa_macro_dai[] = {
362 {
363 .name = "wsa_macro_rx1",
364 .id = WSA_MACRO_AIF1_PB,
365 .playback = {
366 .stream_name = "WSA_AIF1 Playback",
367 .rates = WSA_MACRO_RX_RATES,
368 .formats = WSA_MACRO_RX_FORMATS,
369 .rate_max = 384000,
370 .rate_min = 8000,
371 .channels_min = 1,
372 .channels_max = 2,
373 },
374 .ops = &wsa_macro_dai_ops,
375 },
376 {
377 .name = "wsa_macro_rx_mix",
378 .id = WSA_MACRO_AIF_MIX1_PB,
379 .playback = {
380 .stream_name = "WSA_AIF_MIX1 Playback",
381 .rates = WSA_MACRO_RX_MIX_RATES,
382 .formats = WSA_MACRO_RX_FORMATS,
383 .rate_max = 192000,
384 .rate_min = 48000,
385 .channels_min = 1,
386 .channels_max = 2,
387 },
388 .ops = &wsa_macro_dai_ops,
389 },
390 {
391 .name = "wsa_macro_vifeedback",
392 .id = WSA_MACRO_AIF_VI,
393 .capture = {
394 .stream_name = "WSA_AIF_VI Capture",
Vatsal Buchad1b694d2018-08-31 11:47:32 +0530395 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000,
396 .formats = WSA_MACRO_RX_FORMATS,
397 .rate_max = 48000,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530398 .rate_min = 8000,
399 .channels_min = 1,
Vatsal Buchad1b694d2018-08-31 11:47:32 +0530400 .channels_max = 4,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530401 },
402 .ops = &wsa_macro_dai_ops,
403 },
404 {
405 .name = "wsa_macro_echo",
406 .id = WSA_MACRO_AIF_ECHO,
407 .capture = {
408 .stream_name = "WSA_AIF_ECHO Capture",
409 .rates = WSA_MACRO_ECHO_RATES,
410 .formats = WSA_MACRO_ECHO_FORMATS,
411 .rate_max = 48000,
412 .rate_min = 8000,
413 .channels_min = 1,
414 .channels_max = 2,
415 },
416 .ops = &wsa_macro_dai_ops,
417 },
418};
419
420static const struct wsa_macro_reg_mask_val wsa_macro_spkr_default[] = {
421 {BOLERO_CDC_WSA_COMPANDER0_CTL3, 0x80, 0x80},
422 {BOLERO_CDC_WSA_COMPANDER1_CTL3, 0x80, 0x80},
423 {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x01, 0x01},
424 {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x01, 0x01},
425 {BOLERO_CDC_WSA_BOOST0_BOOST_CTL, 0x7C, 0x58},
426 {BOLERO_CDC_WSA_BOOST1_BOOST_CTL, 0x7C, 0x58},
427};
428
429static const struct wsa_macro_reg_mask_val wsa_macro_spkr_mode1[] = {
430 {BOLERO_CDC_WSA_COMPANDER0_CTL3, 0x80, 0x00},
431 {BOLERO_CDC_WSA_COMPANDER1_CTL3, 0x80, 0x00},
432 {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x01, 0x00},
433 {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x01, 0x00},
434 {BOLERO_CDC_WSA_BOOST0_BOOST_CTL, 0x7C, 0x44},
435 {BOLERO_CDC_WSA_BOOST1_BOOST_CTL, 0x7C, 0x44},
436};
437
Meng Wang15c825d2018-09-06 10:49:18 +0800438static bool wsa_macro_get_data(struct snd_soc_component *component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530439 struct device **wsa_dev,
440 struct wsa_macro_priv **wsa_priv,
441 const char *func_name)
442{
Meng Wang15c825d2018-09-06 10:49:18 +0800443 *wsa_dev = bolero_get_device_ptr(component->dev, WSA_MACRO);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530444 if (!(*wsa_dev)) {
Meng Wang15c825d2018-09-06 10:49:18 +0800445 dev_err(component->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530446 "%s: null device for macro!\n", func_name);
447 return false;
448 }
449 *wsa_priv = dev_get_drvdata((*wsa_dev));
Meng Wang15c825d2018-09-06 10:49:18 +0800450 if (!(*wsa_priv) || !(*wsa_priv)->component) {
451 dev_err(component->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530452 "%s: priv is null for macro!\n", func_name);
453 return false;
454 }
455 return true;
456}
457
Sudheer Papothia3e969d2018-10-27 06:22:10 +0530458static int wsa_macro_set_port_map(struct snd_soc_component *component,
459 u32 usecase, u32 size, void *data)
460{
461 struct device *wsa_dev = NULL;
462 struct wsa_macro_priv *wsa_priv = NULL;
463 struct swrm_port_config port_cfg;
464 int ret = 0;
465
466 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
467 return -EINVAL;
468
469 memset(&port_cfg, 0, sizeof(port_cfg));
470 port_cfg.uc = usecase;
471 port_cfg.size = size;
472 port_cfg.params = data;
473
474 ret = swrm_wcd_notify(
475 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
476 SWR_SET_PORT_MAP, &port_cfg);
477
478 return ret;
479}
480
Laxminath Kasam243e2752018-04-12 00:40:19 +0530481/**
482 * wsa_macro_set_spkr_gain_offset - offset the speaker path
483 * gain with the given offset value.
484 *
Meng Wang15c825d2018-09-06 10:49:18 +0800485 * @component: codec instance
Laxminath Kasam243e2752018-04-12 00:40:19 +0530486 * @offset: Indicates speaker path gain offset value.
487 *
488 * Returns 0 on success or -EINVAL on error.
489 */
Meng Wang15c825d2018-09-06 10:49:18 +0800490int wsa_macro_set_spkr_gain_offset(struct snd_soc_component *component,
491 int offset)
Laxminath Kasam243e2752018-04-12 00:40:19 +0530492{
493 struct device *wsa_dev = NULL;
494 struct wsa_macro_priv *wsa_priv = NULL;
495
Meng Wang15c825d2018-09-06 10:49:18 +0800496 if (!component) {
497 pr_err("%s: NULL component pointer!\n", __func__);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530498 return -EINVAL;
499 }
500
Meng Wang15c825d2018-09-06 10:49:18 +0800501 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530502 return -EINVAL;
503
504 wsa_priv->spkr_gain_offset = offset;
505 return 0;
506}
507EXPORT_SYMBOL(wsa_macro_set_spkr_gain_offset);
508
509/**
510 * wsa_macro_set_spkr_mode - Configures speaker compander and smartboost
511 * settings based on speaker mode.
512 *
Meng Wang15c825d2018-09-06 10:49:18 +0800513 * @component: codec instance
Laxminath Kasam243e2752018-04-12 00:40:19 +0530514 * @mode: Indicates speaker configuration mode.
515 *
516 * Returns 0 on success or -EINVAL on error.
517 */
Meng Wang15c825d2018-09-06 10:49:18 +0800518int wsa_macro_set_spkr_mode(struct snd_soc_component *component, int mode)
Laxminath Kasam243e2752018-04-12 00:40:19 +0530519{
520 int i;
521 const struct wsa_macro_reg_mask_val *regs;
522 int size;
523 struct device *wsa_dev = NULL;
524 struct wsa_macro_priv *wsa_priv = NULL;
525
Meng Wang15c825d2018-09-06 10:49:18 +0800526 if (!component) {
Laxminath Kasam243e2752018-04-12 00:40:19 +0530527 pr_err("%s: NULL codec pointer!\n", __func__);
528 return -EINVAL;
529 }
530
Meng Wang15c825d2018-09-06 10:49:18 +0800531 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530532 return -EINVAL;
533
534 switch (mode) {
Laxminath Kasam21c8b222018-06-21 18:47:22 +0530535 case WSA_MACRO_SPKR_MODE_1:
Laxminath Kasam243e2752018-04-12 00:40:19 +0530536 regs = wsa_macro_spkr_mode1;
537 size = ARRAY_SIZE(wsa_macro_spkr_mode1);
538 break;
539 default:
540 regs = wsa_macro_spkr_default;
541 size = ARRAY_SIZE(wsa_macro_spkr_default);
542 break;
543 }
544
545 wsa_priv->spkr_mode = mode;
546 for (i = 0; i < size; i++)
Meng Wang15c825d2018-09-06 10:49:18 +0800547 snd_soc_component_update_bits(component, regs[i].reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530548 regs[i].mask, regs[i].val);
549 return 0;
550}
551EXPORT_SYMBOL(wsa_macro_set_spkr_mode);
552
553static int wsa_macro_set_prim_interpolator_rate(struct snd_soc_dai *dai,
554 u8 int_prim_fs_rate_reg_val,
555 u32 sample_rate)
556{
557 u8 int_1_mix1_inp;
558 u32 j, port;
559 u16 int_mux_cfg0, int_mux_cfg1;
560 u16 int_fs_reg;
561 u8 int_mux_cfg0_val, int_mux_cfg1_val;
562 u8 inp0_sel, inp1_sel, inp2_sel;
Meng Wang15c825d2018-09-06 10:49:18 +0800563 struct snd_soc_component *component = dai->component;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530564 struct device *wsa_dev = NULL;
565 struct wsa_macro_priv *wsa_priv = NULL;
566
Meng Wang15c825d2018-09-06 10:49:18 +0800567 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530568 return -EINVAL;
569
570 for_each_set_bit(port, &wsa_priv->active_ch_mask[dai->id],
571 WSA_MACRO_RX_MAX) {
572 int_1_mix1_inp = port;
573 if ((int_1_mix1_inp < WSA_MACRO_RX0) ||
574 (int_1_mix1_inp > WSA_MACRO_RX_MIX1)) {
575 dev_err(wsa_dev,
576 "%s: Invalid RX port, Dai ID is %d\n",
577 __func__, dai->id);
578 return -EINVAL;
579 }
580
581 int_mux_cfg0 = BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0;
582
583 /*
584 * Loop through all interpolator MUX inputs and find out
585 * to which interpolator input, the cdc_dma rx port
586 * is connected
587 */
588 for (j = 0; j < NUM_INTERPOLATORS; j++) {
589 int_mux_cfg1 = int_mux_cfg0 + WSA_MACRO_MUX_CFG1_OFFSET;
590
Meng Wang15c825d2018-09-06 10:49:18 +0800591 int_mux_cfg0_val = snd_soc_component_read32(component,
592 int_mux_cfg0);
593 int_mux_cfg1_val = snd_soc_component_read32(component,
594 int_mux_cfg1);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530595 inp0_sel = int_mux_cfg0_val & WSA_MACRO_MUX_INP_MASK1;
596 inp1_sel = (int_mux_cfg0_val >>
597 WSA_MACRO_MUX_INP_SHFT) &
598 WSA_MACRO_MUX_INP_MASK2;
599 inp2_sel = (int_mux_cfg1_val >>
600 WSA_MACRO_MUX_INP_SHFT) &
601 WSA_MACRO_MUX_INP_MASK2;
602 if ((inp0_sel == int_1_mix1_inp) ||
603 (inp1_sel == int_1_mix1_inp) ||
604 (inp2_sel == int_1_mix1_inp)) {
605 int_fs_reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL +
606 WSA_MACRO_RX_PATH_OFFSET * j;
607 dev_dbg(wsa_dev,
608 "%s: AIF_PB DAI(%d) connected to INT%u_1\n",
609 __func__, dai->id, j);
610 dev_dbg(wsa_dev,
611 "%s: set INT%u_1 sample rate to %u\n",
612 __func__, j, sample_rate);
613 /* sample_rate is in Hz */
Meng Wang15c825d2018-09-06 10:49:18 +0800614 snd_soc_component_update_bits(component,
615 int_fs_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530616 WSA_MACRO_FS_RATE_MASK,
617 int_prim_fs_rate_reg_val);
618 }
619 int_mux_cfg0 += WSA_MACRO_MUX_CFG_OFFSET;
620 }
621 }
622
623 return 0;
624}
625
626static int wsa_macro_set_mix_interpolator_rate(struct snd_soc_dai *dai,
627 u8 int_mix_fs_rate_reg_val,
628 u32 sample_rate)
629{
630 u8 int_2_inp;
631 u32 j, port;
632 u16 int_mux_cfg1, int_fs_reg;
633 u8 int_mux_cfg1_val;
Meng Wang15c825d2018-09-06 10:49:18 +0800634 struct snd_soc_component *component = dai->component;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530635 struct device *wsa_dev = NULL;
636 struct wsa_macro_priv *wsa_priv = NULL;
637
Meng Wang15c825d2018-09-06 10:49:18 +0800638 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530639 return -EINVAL;
640
641
642 for_each_set_bit(port, &wsa_priv->active_ch_mask[dai->id],
643 WSA_MACRO_RX_MAX) {
644 int_2_inp = port;
645 if ((int_2_inp < WSA_MACRO_RX0) ||
646 (int_2_inp > WSA_MACRO_RX_MIX1)) {
647 dev_err(wsa_dev,
648 "%s: Invalid RX port, Dai ID is %d\n",
649 __func__, dai->id);
650 return -EINVAL;
651 }
652
653 int_mux_cfg1 = BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG1;
654 for (j = 0; j < NUM_INTERPOLATORS; j++) {
Meng Wang15c825d2018-09-06 10:49:18 +0800655 int_mux_cfg1_val = snd_soc_component_read32(component,
656 int_mux_cfg1) &
Laxminath Kasam243e2752018-04-12 00:40:19 +0530657 WSA_MACRO_MUX_INP_MASK1;
658 if (int_mux_cfg1_val == int_2_inp) {
659 int_fs_reg =
660 BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL +
661 WSA_MACRO_RX_PATH_OFFSET * j;
662
663 dev_dbg(wsa_dev,
664 "%s: AIF_PB DAI(%d) connected to INT%u_2\n",
665 __func__, dai->id, j);
666 dev_dbg(wsa_dev,
667 "%s: set INT%u_2 sample rate to %u\n",
668 __func__, j, sample_rate);
Meng Wang15c825d2018-09-06 10:49:18 +0800669 snd_soc_component_update_bits(component,
670 int_fs_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530671 WSA_MACRO_FS_RATE_MASK,
672 int_mix_fs_rate_reg_val);
673 }
674 int_mux_cfg1 += WSA_MACRO_MUX_CFG_OFFSET;
675 }
676 }
677 return 0;
678}
679
680static int wsa_macro_set_interpolator_rate(struct snd_soc_dai *dai,
681 u32 sample_rate)
682{
683 int rate_val = 0;
684 int i, ret;
685
686 /* set mixing path rate */
687 for (i = 0; i < ARRAY_SIZE(int_mix_sample_rate_val); i++) {
688 if (sample_rate ==
689 int_mix_sample_rate_val[i].sample_rate) {
690 rate_val =
691 int_mix_sample_rate_val[i].rate_val;
692 break;
693 }
694 }
695 if ((i == ARRAY_SIZE(int_mix_sample_rate_val)) ||
696 (rate_val < 0))
697 goto prim_rate;
698 ret = wsa_macro_set_mix_interpolator_rate(dai,
699 (u8) rate_val, sample_rate);
700prim_rate:
701 /* set primary path sample rate */
702 for (i = 0; i < ARRAY_SIZE(int_prim_sample_rate_val); i++) {
703 if (sample_rate ==
704 int_prim_sample_rate_val[i].sample_rate) {
705 rate_val =
706 int_prim_sample_rate_val[i].rate_val;
707 break;
708 }
709 }
710 if ((i == ARRAY_SIZE(int_prim_sample_rate_val)) ||
711 (rate_val < 0))
712 return -EINVAL;
713 ret = wsa_macro_set_prim_interpolator_rate(dai,
714 (u8) rate_val, sample_rate);
715 return ret;
716}
717
718static int wsa_macro_hw_params(struct snd_pcm_substream *substream,
719 struct snd_pcm_hw_params *params,
720 struct snd_soc_dai *dai)
721{
Meng Wang15c825d2018-09-06 10:49:18 +0800722 struct snd_soc_component *component = dai->component;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530723 int ret;
724
Meng Wang15c825d2018-09-06 10:49:18 +0800725 dev_dbg(component->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530726 "%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__,
727 dai->name, dai->id, params_rate(params),
728 params_channels(params));
729
730 switch (substream->stream) {
731 case SNDRV_PCM_STREAM_PLAYBACK:
732 ret = wsa_macro_set_interpolator_rate(dai, params_rate(params));
733 if (ret) {
Meng Wang15c825d2018-09-06 10:49:18 +0800734 dev_err(component->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530735 "%s: cannot set sample rate: %u\n",
736 __func__, params_rate(params));
737 return ret;
738 }
739 break;
740 case SNDRV_PCM_STREAM_CAPTURE:
741 default:
742 break;
743 }
744 return 0;
745}
746
747static int wsa_macro_get_channel_map(struct snd_soc_dai *dai,
748 unsigned int *tx_num, unsigned int *tx_slot,
749 unsigned int *rx_num, unsigned int *rx_slot)
750{
Meng Wang15c825d2018-09-06 10:49:18 +0800751 struct snd_soc_component *component = dai->component;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530752 struct device *wsa_dev = NULL;
753 struct wsa_macro_priv *wsa_priv = NULL;
Laxminath Kasam5d9ea8d2018-11-28 14:32:40 +0530754 u16 val = 0, mask = 0, cnt = 0;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530755
Meng Wang15c825d2018-09-06 10:49:18 +0800756 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530757 return -EINVAL;
758
759 wsa_priv = dev_get_drvdata(wsa_dev);
760 if (!wsa_priv)
761 return -EINVAL;
762
763 switch (dai->id) {
764 case WSA_MACRO_AIF_VI:
Laxminath Kasam243e2752018-04-12 00:40:19 +0530765 *tx_slot = wsa_priv->active_ch_mask[dai->id];
766 *tx_num = wsa_priv->active_ch_cnt[dai->id];
767 break;
768 case WSA_MACRO_AIF1_PB:
769 case WSA_MACRO_AIF_MIX1_PB:
770 *rx_slot = wsa_priv->active_ch_mask[dai->id];
771 *rx_num = wsa_priv->active_ch_cnt[dai->id];
772 break;
Laxminath Kasam5d9ea8d2018-11-28 14:32:40 +0530773 case WSA_MACRO_AIF_ECHO:
774 val = snd_soc_component_read32(component,
775 BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0);
776 if (val & WSA_MACRO_EC_MIX_TX1_MASK) {
777 mask |= 0x2;
778 cnt++;
779 }
780 if (val & WSA_MACRO_EC_MIX_TX0_MASK) {
781 mask |= 0x1;
782 cnt++;
783 }
784 *tx_slot = mask;
785 *tx_num = cnt;
786 break;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530787 default:
788 dev_err(wsa_dev, "%s: Invalid AIF\n", __func__);
789 break;
790 }
791 return 0;
792}
793
794static int wsa_macro_mclk_enable(struct wsa_macro_priv *wsa_priv,
795 bool mclk_enable, bool dapm)
796{
797 struct regmap *regmap = dev_get_regmap(wsa_priv->dev->parent, NULL);
798 int ret = 0;
799
Tanya Dixitab8eba82018-10-05 15:07:37 +0530800 if (regmap == NULL) {
801 dev_err(wsa_priv->dev, "%s: regmap is NULL\n", __func__);
802 return -EINVAL;
803 }
804
Laxminath Kasam243e2752018-04-12 00:40:19 +0530805 dev_dbg(wsa_priv->dev, "%s: mclk_enable = %u, dapm = %d clk_users= %d\n",
806 __func__, mclk_enable, dapm, wsa_priv->wsa_mclk_users);
807
808 mutex_lock(&wsa_priv->mclk_lock);
809 if (mclk_enable) {
Aditya Bavanaric496ed22018-11-16 15:50:40 +0530810 if (wsa_priv->wsa_mclk_users == 0) {
Laxminath Kasam243e2752018-04-12 00:40:19 +0530811 ret = bolero_request_clock(wsa_priv->dev,
812 WSA_MACRO, MCLK_MUX0, true);
813 if (ret < 0) {
814 dev_err(wsa_priv->dev,
815 "%s: wsa request clock enable failed\n",
816 __func__);
817 goto exit;
818 }
819 regcache_mark_dirty(regmap);
820 regcache_sync_region(regmap,
821 WSA_START_OFFSET,
822 WSA_MAX_OFFSET);
823 /* 9.6MHz MCLK, set value 0x00 if other frequency */
824 regmap_update_bits(regmap,
825 BOLERO_CDC_WSA_TOP_FREQ_MCLK, 0x01, 0x01);
826 regmap_update_bits(regmap,
827 BOLERO_CDC_WSA_CLK_RST_CTRL_MCLK_CONTROL,
828 0x01, 0x01);
829 regmap_update_bits(regmap,
830 BOLERO_CDC_WSA_CLK_RST_CTRL_FS_CNT_CONTROL,
831 0x01, 0x01);
832 }
Aditya Bavanaric496ed22018-11-16 15:50:40 +0530833 wsa_priv->wsa_mclk_users++;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530834 } else {
Aditya Bavanaric496ed22018-11-16 15:50:40 +0530835 if (wsa_priv->wsa_mclk_users <= 0) {
836 dev_err(wsa_priv->dev, "%s: clock already disabled\n",
837 __func__);
838 wsa_priv->wsa_mclk_users = 0;
839 goto exit;
840 }
Laxminath Kasam243e2752018-04-12 00:40:19 +0530841 wsa_priv->wsa_mclk_users--;
842 if (wsa_priv->wsa_mclk_users == 0) {
843 regmap_update_bits(regmap,
844 BOLERO_CDC_WSA_CLK_RST_CTRL_FS_CNT_CONTROL,
845 0x01, 0x00);
846 regmap_update_bits(regmap,
847 BOLERO_CDC_WSA_CLK_RST_CTRL_MCLK_CONTROL,
848 0x01, 0x00);
849 bolero_request_clock(wsa_priv->dev,
850 WSA_MACRO, MCLK_MUX0, false);
851 }
852 }
853exit:
854 mutex_unlock(&wsa_priv->mclk_lock);
855 return ret;
856}
857
858static int wsa_macro_mclk_event(struct snd_soc_dapm_widget *w,
859 struct snd_kcontrol *kcontrol, int event)
860{
Meng Wang15c825d2018-09-06 10:49:18 +0800861 struct snd_soc_component *component =
862 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530863 int ret = 0;
864 struct device *wsa_dev = NULL;
865 struct wsa_macro_priv *wsa_priv = NULL;
866
Meng Wang15c825d2018-09-06 10:49:18 +0800867 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530868 return -EINVAL;
869
870 dev_dbg(wsa_dev, "%s: event = %d\n", __func__, event);
871 switch (event) {
872 case SND_SOC_DAPM_PRE_PMU:
873 ret = wsa_macro_mclk_enable(wsa_priv, 1, true);
Ramprasad Katkam452772a2019-01-07 17:30:36 +0530874 if (ret)
875 wsa_priv->dapm_mclk_enable = false;
876 else
877 wsa_priv->dapm_mclk_enable = true;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530878 break;
879 case SND_SOC_DAPM_POST_PMD:
Ramprasad Katkam452772a2019-01-07 17:30:36 +0530880 if (wsa_priv->dapm_mclk_enable)
881 wsa_macro_mclk_enable(wsa_priv, 0, true);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530882 break;
883 default:
884 dev_err(wsa_priv->dev,
885 "%s: invalid DAPM event %d\n", __func__, event);
886 ret = -EINVAL;
887 }
888 return ret;
889}
890
891static int wsa_macro_mclk_ctrl(struct device *dev, bool enable)
892{
893 struct wsa_macro_priv *wsa_priv = dev_get_drvdata(dev);
894 int ret = 0;
895
896 if (!wsa_priv)
897 return -EINVAL;
898
899 if (enable) {
900 ret = clk_prepare_enable(wsa_priv->wsa_core_clk);
901 if (ret < 0) {
902 dev_err(dev, "%s:wsa mclk enable failed\n", __func__);
903 goto exit;
904 }
905 ret = clk_prepare_enable(wsa_priv->wsa_npl_clk);
906 if (ret < 0) {
907 dev_err(dev, "%s:wsa npl_clk enable failed\n",
908 __func__);
909 clk_disable_unprepare(wsa_priv->wsa_core_clk);
910 goto exit;
911 }
912 } else {
913 clk_disable_unprepare(wsa_priv->wsa_npl_clk);
914 clk_disable_unprepare(wsa_priv->wsa_core_clk);
915 }
916exit:
917 return ret;
918}
919
Meng Wang15c825d2018-09-06 10:49:18 +0800920static int wsa_macro_event_handler(struct snd_soc_component *component,
921 u16 event, u32 data)
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530922{
923 struct device *wsa_dev = NULL;
924 struct wsa_macro_priv *wsa_priv = NULL;
925
Meng Wang15c825d2018-09-06 10:49:18 +0800926 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530927 return -EINVAL;
928
929 switch (event) {
930 case BOLERO_MACRO_EVT_SSR_DOWN:
931 swrm_wcd_notify(
932 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
Ramprasad Katkam5ee54ae2018-12-19 18:56:00 +0530933 SWR_DEVICE_DOWN, NULL);
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530934 swrm_wcd_notify(
935 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
Ramprasad Katkam5ee54ae2018-12-19 18:56:00 +0530936 SWR_DEVICE_SSR_DOWN, NULL);
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530937 break;
938 case BOLERO_MACRO_EVT_SSR_UP:
Ramprasad Katkama4c747b2018-12-11 19:15:53 +0530939 /* reset swr after ssr/pdr */
940 wsa_priv->reset_swr = true;
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530941 swrm_wcd_notify(
942 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
943 SWR_DEVICE_SSR_UP, NULL);
944 break;
945 }
946 return 0;
947}
948
Laxminath Kasam243e2752018-04-12 00:40:19 +0530949static int wsa_macro_enable_vi_feedback(struct snd_soc_dapm_widget *w,
950 struct snd_kcontrol *kcontrol,
951 int event)
952{
Meng Wang15c825d2018-09-06 10:49:18 +0800953 struct snd_soc_component *component =
954 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530955 struct device *wsa_dev = NULL;
956 struct wsa_macro_priv *wsa_priv = NULL;
957
Meng Wang15c825d2018-09-06 10:49:18 +0800958 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530959 return -EINVAL;
960
961 switch (event) {
962 case SND_SOC_DAPM_POST_PMU:
963 if (test_bit(WSA_MACRO_TX0,
964 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
965 dev_dbg(wsa_dev, "%s: spkr1 enabled\n", __func__);
966 /* Enable V&I sensing */
Meng Wang15c825d2018-09-06 10:49:18 +0800967 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530968 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
969 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +0800970 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530971 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
972 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +0800973 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530974 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
975 0x0F, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +0800976 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530977 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
978 0x0F, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +0800979 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530980 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
981 0x10, 0x10);
Meng Wang15c825d2018-09-06 10:49:18 +0800982 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530983 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
984 0x10, 0x10);
Meng Wang15c825d2018-09-06 10:49:18 +0800985 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530986 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
987 0x20, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +0800988 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530989 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
990 0x20, 0x00);
991 }
992 if (test_bit(WSA_MACRO_TX1,
993 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
994 dev_dbg(wsa_dev, "%s: spkr2 enabled\n", __func__);
995 /* Enable V&I sensing */
Meng Wang15c825d2018-09-06 10:49:18 +0800996 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530997 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
998 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +0800999 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301000 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
1001 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08001002 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301003 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
1004 0x0F, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001005 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301006 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
1007 0x0F, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001008 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301009 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
1010 0x10, 0x10);
Meng Wang15c825d2018-09-06 10:49:18 +08001011 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301012 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
1013 0x10, 0x10);
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_TX2_SPKR_PROT_PATH_CTL,
1016 0x20, 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_TX3_SPKR_PROT_PATH_CTL,
1019 0x20, 0x00);
1020 }
1021 break;
1022 case SND_SOC_DAPM_POST_PMD:
1023 if (test_bit(WSA_MACRO_TX0,
1024 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
1025 /* Disable V&I sensing */
Meng Wang15c825d2018-09-06 10:49:18 +08001026 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301027 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
1028 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08001029 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301030 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
1031 0x20, 0x20);
1032 dev_dbg(wsa_dev, "%s: spkr1 disabled\n", __func__);
Meng Wang15c825d2018-09-06 10:49:18 +08001033 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301034 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
1035 0x10, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001036 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301037 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
1038 0x10, 0x00);
1039 }
1040 if (test_bit(WSA_MACRO_TX1,
1041 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
1042 /* Disable V&I sensing */
1043 dev_dbg(wsa_dev, "%s: spkr2 disabled\n", __func__);
Meng Wang15c825d2018-09-06 10:49:18 +08001044 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301045 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
1046 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08001047 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301048 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
1049 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08001050 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301051 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
1052 0x10, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001053 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301054 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
1055 0x10, 0x00);
1056 }
1057 break;
1058 }
1059
1060 return 0;
1061}
1062
1063static int wsa_macro_enable_mix_path(struct snd_soc_dapm_widget *w,
1064 struct snd_kcontrol *kcontrol, int event)
1065{
Meng Wang15c825d2018-09-06 10:49:18 +08001066 struct snd_soc_component *component =
1067 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301068 u16 gain_reg;
1069 int offset_val = 0;
1070 int val = 0;
1071
Meng Wang15c825d2018-09-06 10:49:18 +08001072 dev_dbg(component->dev, "%s %d %s\n", __func__, event, w->name);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301073
1074 switch (w->reg) {
1075 case BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL:
1076 gain_reg = BOLERO_CDC_WSA_RX0_RX_VOL_MIX_CTL;
1077 break;
1078 case BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL:
1079 gain_reg = BOLERO_CDC_WSA_RX1_RX_VOL_MIX_CTL;
1080 break;
1081 default:
Meng Wang15c825d2018-09-06 10:49:18 +08001082 dev_err(component->dev, "%s: No gain register avail for %s\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301083 __func__, w->name);
1084 return 0;
1085 }
1086
1087 switch (event) {
1088 case SND_SOC_DAPM_POST_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08001089 val = snd_soc_component_read32(component, gain_reg);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301090 val += offset_val;
Meng Wang15c825d2018-09-06 10:49:18 +08001091 snd_soc_component_write(component, gain_reg, val);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301092 break;
1093 case SND_SOC_DAPM_POST_PMD:
1094 break;
1095 }
1096
1097 return 0;
1098}
1099
Meng Wang15c825d2018-09-06 10:49:18 +08001100static void wsa_macro_hd2_control(struct snd_soc_component *component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301101 u16 reg, int event)
1102{
1103 u16 hd2_scale_reg;
1104 u16 hd2_enable_reg = 0;
1105
1106 if (reg == BOLERO_CDC_WSA_RX0_RX_PATH_CTL) {
1107 hd2_scale_reg = BOLERO_CDC_WSA_RX0_RX_PATH_SEC3;
1108 hd2_enable_reg = BOLERO_CDC_WSA_RX0_RX_PATH_CFG0;
1109 }
1110 if (reg == BOLERO_CDC_WSA_RX1_RX_PATH_CTL) {
1111 hd2_scale_reg = BOLERO_CDC_WSA_RX1_RX_PATH_SEC3;
1112 hd2_enable_reg = BOLERO_CDC_WSA_RX1_RX_PATH_CFG0;
1113 }
1114
1115 if (hd2_enable_reg && SND_SOC_DAPM_EVENT_ON(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001116 snd_soc_component_update_bits(component, hd2_scale_reg,
1117 0x3C, 0x10);
1118 snd_soc_component_update_bits(component, hd2_scale_reg,
1119 0x03, 0x01);
1120 snd_soc_component_update_bits(component, hd2_enable_reg,
1121 0x04, 0x04);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301122 }
1123
1124 if (hd2_enable_reg && SND_SOC_DAPM_EVENT_OFF(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001125 snd_soc_component_update_bits(component, hd2_enable_reg,
1126 0x04, 0x00);
1127 snd_soc_component_update_bits(component, hd2_scale_reg,
1128 0x03, 0x00);
1129 snd_soc_component_update_bits(component, hd2_scale_reg,
1130 0x3C, 0x00);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301131 }
1132}
1133
1134static int wsa_macro_enable_swr(struct snd_soc_dapm_widget *w,
1135 struct snd_kcontrol *kcontrol, int event)
1136{
Meng Wang15c825d2018-09-06 10:49:18 +08001137 struct snd_soc_component *component =
1138 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301139 int ch_cnt;
1140 struct device *wsa_dev = NULL;
1141 struct wsa_macro_priv *wsa_priv = NULL;
1142
Meng Wang15c825d2018-09-06 10:49:18 +08001143 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301144 return -EINVAL;
1145
1146 switch (event) {
1147 case SND_SOC_DAPM_PRE_PMU:
1148 if (!(strnstr(w->name, "RX0", sizeof("WSA_RX0"))) &&
1149 !wsa_priv->rx_0_count)
1150 wsa_priv->rx_0_count++;
1151 if (!(strnstr(w->name, "RX1", sizeof("WSA_RX1"))) &&
1152 !wsa_priv->rx_1_count)
1153 wsa_priv->rx_1_count++;
1154 ch_cnt = wsa_priv->rx_0_count + wsa_priv->rx_1_count;
1155
1156 swrm_wcd_notify(
1157 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
1158 SWR_DEVICE_UP, NULL);
1159 swrm_wcd_notify(
1160 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
1161 SWR_SET_NUM_RX_CH, &ch_cnt);
1162 break;
1163 case SND_SOC_DAPM_POST_PMD:
1164 if (!(strnstr(w->name, "RX0", sizeof("WSA_RX0"))) &&
1165 wsa_priv->rx_0_count)
1166 wsa_priv->rx_0_count--;
1167 if (!(strnstr(w->name, "RX1", sizeof("WSA_RX1"))) &&
1168 wsa_priv->rx_1_count)
1169 wsa_priv->rx_1_count--;
1170 ch_cnt = wsa_priv->rx_0_count + wsa_priv->rx_1_count;
1171
1172 swrm_wcd_notify(
1173 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
1174 SWR_SET_NUM_RX_CH, &ch_cnt);
1175 break;
1176 }
1177 dev_dbg(wsa_priv->dev, "%s: current swr ch cnt: %d\n",
1178 __func__, wsa_priv->rx_0_count + wsa_priv->rx_1_count);
1179
1180 return 0;
1181}
1182
Meng Wang15c825d2018-09-06 10:49:18 +08001183static int wsa_macro_config_compander(struct snd_soc_component *component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301184 int comp, int event)
1185{
1186 u16 comp_ctl0_reg, rx_path_cfg0_reg;
1187 struct device *wsa_dev = NULL;
1188 struct wsa_macro_priv *wsa_priv = NULL;
1189
Meng Wang15c825d2018-09-06 10:49:18 +08001190 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301191 return -EINVAL;
1192
Meng Wang15c825d2018-09-06 10:49:18 +08001193 dev_dbg(component->dev, "%s: event %d compander %d, enabled %d\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301194 __func__, event, comp + 1, wsa_priv->comp_enabled[comp]);
1195
1196 if (!wsa_priv->comp_enabled[comp])
1197 return 0;
1198
1199 comp_ctl0_reg = BOLERO_CDC_WSA_COMPANDER0_CTL0 +
1200 (comp * WSA_MACRO_RX_COMP_OFFSET);
1201 rx_path_cfg0_reg = BOLERO_CDC_WSA_RX0_RX_PATH_CFG0 +
1202 (comp * WSA_MACRO_RX_PATH_OFFSET);
1203
1204 if (SND_SOC_DAPM_EVENT_ON(event)) {
1205 /* Enable Compander Clock */
Meng Wang15c825d2018-09-06 10:49:18 +08001206 snd_soc_component_update_bits(component, comp_ctl0_reg,
1207 0x01, 0x01);
1208 snd_soc_component_update_bits(component, comp_ctl0_reg,
1209 0x02, 0x02);
1210 snd_soc_component_update_bits(component, comp_ctl0_reg,
1211 0x02, 0x00);
1212 snd_soc_component_update_bits(component, rx_path_cfg0_reg,
1213 0x02, 0x02);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301214 }
1215
1216 if (SND_SOC_DAPM_EVENT_OFF(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001217 snd_soc_component_update_bits(component, comp_ctl0_reg,
1218 0x04, 0x04);
1219 snd_soc_component_update_bits(component, rx_path_cfg0_reg,
1220 0x02, 0x00);
1221 snd_soc_component_update_bits(component, comp_ctl0_reg,
1222 0x02, 0x02);
1223 snd_soc_component_update_bits(component, comp_ctl0_reg,
1224 0x02, 0x00);
1225 snd_soc_component_update_bits(component, comp_ctl0_reg,
1226 0x01, 0x00);
1227 snd_soc_component_update_bits(component, comp_ctl0_reg,
1228 0x04, 0x00);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301229 }
1230
1231 return 0;
1232}
1233
Meng Wang15c825d2018-09-06 10:49:18 +08001234static void wsa_macro_enable_softclip_clk(struct snd_soc_component *component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301235 struct wsa_macro_priv *wsa_priv,
1236 int path,
1237 bool enable)
1238{
1239 u16 softclip_clk_reg = BOLERO_CDC_WSA_SOFTCLIP0_CRC +
1240 (path * WSA_MACRO_RX_SOFTCLIP_OFFSET);
1241 u8 softclip_mux_mask = (1 << path);
1242 u8 softclip_mux_value = (1 << path);
1243
Meng Wang15c825d2018-09-06 10:49:18 +08001244 dev_dbg(component->dev, "%s: path %d, enable %d\n",
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301245 __func__, path, enable);
1246 if (enable) {
1247 if (wsa_priv->softclip_clk_users[path] == 0) {
Meng Wang15c825d2018-09-06 10:49:18 +08001248 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301249 softclip_clk_reg, 0x01, 0x01);
Meng Wang15c825d2018-09-06 10:49:18 +08001250 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301251 BOLERO_CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0,
1252 softclip_mux_mask, softclip_mux_value);
1253 }
1254 wsa_priv->softclip_clk_users[path]++;
1255 } else {
1256 wsa_priv->softclip_clk_users[path]--;
1257 if (wsa_priv->softclip_clk_users[path] == 0) {
Meng Wang15c825d2018-09-06 10:49:18 +08001258 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301259 softclip_clk_reg, 0x01, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001260 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301261 BOLERO_CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0,
1262 softclip_mux_mask, 0x00);
1263 }
1264 }
1265}
1266
Meng Wang15c825d2018-09-06 10:49:18 +08001267static int wsa_macro_config_softclip(struct snd_soc_component *component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301268 int path, int event)
1269{
1270 u16 softclip_ctrl_reg = 0;
1271 struct device *wsa_dev = NULL;
1272 struct wsa_macro_priv *wsa_priv = NULL;
1273 int softclip_path = 0;
1274
Meng Wang15c825d2018-09-06 10:49:18 +08001275 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301276 return -EINVAL;
1277
1278 if (path == WSA_MACRO_COMP1)
1279 softclip_path = WSA_MACRO_SOFTCLIP0;
1280 else if (path == WSA_MACRO_COMP2)
1281 softclip_path = WSA_MACRO_SOFTCLIP1;
1282
Meng Wang15c825d2018-09-06 10:49:18 +08001283 dev_dbg(component->dev, "%s: event %d path %d, enabled %d\n",
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301284 __func__, event, softclip_path,
1285 wsa_priv->is_softclip_on[softclip_path]);
1286
1287 if (!wsa_priv->is_softclip_on[softclip_path])
1288 return 0;
1289
1290 softclip_ctrl_reg = BOLERO_CDC_WSA_SOFTCLIP0_SOFTCLIP_CTRL +
1291 (softclip_path * WSA_MACRO_RX_SOFTCLIP_OFFSET);
1292
1293 if (SND_SOC_DAPM_EVENT_ON(event)) {
1294 /* Enable Softclip clock and mux */
Meng Wang15c825d2018-09-06 10:49:18 +08001295 wsa_macro_enable_softclip_clk(component, wsa_priv,
1296 softclip_path, true);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301297 /* Enable Softclip control */
Meng Wang15c825d2018-09-06 10:49:18 +08001298 snd_soc_component_update_bits(component, softclip_ctrl_reg,
1299 0x01, 0x01);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301300 }
1301
1302 if (SND_SOC_DAPM_EVENT_OFF(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001303 snd_soc_component_update_bits(component, softclip_ctrl_reg,
1304 0x01, 0x00);
1305 wsa_macro_enable_softclip_clk(component, wsa_priv,
1306 softclip_path, false);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301307 }
1308
1309 return 0;
1310}
1311
Laxminath Kasam243e2752018-04-12 00:40:19 +05301312static int wsa_macro_interp_get_primary_reg(u16 reg, u16 *ind)
1313{
1314 u16 prim_int_reg = 0;
1315
1316 switch (reg) {
1317 case BOLERO_CDC_WSA_RX0_RX_PATH_CTL:
1318 case BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL:
1319 prim_int_reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL;
1320 *ind = 0;
1321 break;
1322 case BOLERO_CDC_WSA_RX1_RX_PATH_CTL:
1323 case BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL:
1324 prim_int_reg = BOLERO_CDC_WSA_RX1_RX_PATH_CTL;
1325 *ind = 1;
1326 break;
1327 }
1328
1329 return prim_int_reg;
1330}
1331
1332static int wsa_macro_enable_prim_interpolator(
Meng Wang15c825d2018-09-06 10:49:18 +08001333 struct snd_soc_component *component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301334 u16 reg, int event)
1335{
1336 u16 prim_int_reg;
1337 u16 ind = 0;
1338 struct device *wsa_dev = NULL;
1339 struct wsa_macro_priv *wsa_priv = NULL;
1340
Meng Wang15c825d2018-09-06 10:49:18 +08001341 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301342 return -EINVAL;
1343
1344 prim_int_reg = wsa_macro_interp_get_primary_reg(reg, &ind);
1345
1346 switch (event) {
1347 case SND_SOC_DAPM_PRE_PMU:
1348 wsa_priv->prim_int_users[ind]++;
1349 if (wsa_priv->prim_int_users[ind] == 1) {
Meng Wang15c825d2018-09-06 10:49:18 +08001350 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301351 prim_int_reg + WSA_MACRO_RX_PATH_CFG3_OFFSET,
1352 0x03, 0x03);
Meng Wang15c825d2018-09-06 10:49:18 +08001353 snd_soc_component_update_bits(component, prim_int_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301354 0x10, 0x10);
Meng Wang15c825d2018-09-06 10:49:18 +08001355 wsa_macro_hd2_control(component, prim_int_reg, event);
1356 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301357 prim_int_reg + WSA_MACRO_RX_PATH_DSMDEM_OFFSET,
1358 0x1, 0x1);
Meng Wang15c825d2018-09-06 10:49:18 +08001359 snd_soc_component_update_bits(component, prim_int_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301360 1 << 0x5, 1 << 0x5);
1361 }
1362 if ((reg != prim_int_reg) &&
Meng Wang15c825d2018-09-06 10:49:18 +08001363 ((snd_soc_component_read32(
1364 component, prim_int_reg)) & 0x10))
1365 snd_soc_component_update_bits(component, reg,
1366 0x10, 0x10);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301367 break;
1368 case SND_SOC_DAPM_POST_PMD:
1369 wsa_priv->prim_int_users[ind]--;
1370 if (wsa_priv->prim_int_users[ind] == 0) {
Meng Wang15c825d2018-09-06 10:49:18 +08001371 snd_soc_component_update_bits(component, prim_int_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301372 1 << 0x5, 0 << 0x5);
Meng Wang15c825d2018-09-06 10:49:18 +08001373 snd_soc_component_update_bits(component, prim_int_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301374 0x40, 0x40);
Meng Wang15c825d2018-09-06 10:49:18 +08001375 snd_soc_component_update_bits(component, prim_int_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301376 0x40, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001377 wsa_macro_hd2_control(component, prim_int_reg, event);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301378 }
1379 break;
1380 }
1381
Meng Wang15c825d2018-09-06 10:49:18 +08001382 dev_dbg(component->dev, "%s: primary interpolator: INT%d, users: %d\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301383 __func__, ind, wsa_priv->prim_int_users[ind]);
1384 return 0;
1385}
1386
1387static int wsa_macro_enable_interpolator(struct snd_soc_dapm_widget *w,
1388 struct snd_kcontrol *kcontrol,
1389 int event)
1390{
Meng Wang15c825d2018-09-06 10:49:18 +08001391 struct snd_soc_component *component =
1392 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301393 u16 gain_reg;
1394 u16 reg;
1395 int val;
1396 int offset_val = 0;
1397 struct device *wsa_dev = NULL;
1398 struct wsa_macro_priv *wsa_priv = NULL;
1399
Meng Wang15c825d2018-09-06 10:49:18 +08001400 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301401 return -EINVAL;
1402
Meng Wang15c825d2018-09-06 10:49:18 +08001403 dev_dbg(component->dev, "%s %d %s\n", __func__, event, w->name);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301404
1405 if (!(strcmp(w->name, "WSA_RX INT0 INTERP"))) {
1406 reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL;
1407 gain_reg = BOLERO_CDC_WSA_RX0_RX_VOL_CTL;
1408 } else if (!(strcmp(w->name, "WSA_RX INT1 INTERP"))) {
1409 reg = BOLERO_CDC_WSA_RX1_RX_PATH_CTL;
1410 gain_reg = BOLERO_CDC_WSA_RX1_RX_VOL_CTL;
1411 } else {
Meng Wang15c825d2018-09-06 10:49:18 +08001412 dev_err(component->dev, "%s: Interpolator reg not found\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301413 __func__);
1414 return -EINVAL;
1415 }
1416
1417 switch (event) {
1418 case SND_SOC_DAPM_PRE_PMU:
1419 /* Reset if needed */
Meng Wang15c825d2018-09-06 10:49:18 +08001420 wsa_macro_enable_prim_interpolator(component, reg, event);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301421 break;
1422 case SND_SOC_DAPM_POST_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08001423 wsa_macro_config_compander(component, w->shift, event);
1424 wsa_macro_config_softclip(component, w->shift, event);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301425 /* apply gain after int clk is enabled */
Laxminath Kasam21c8b222018-06-21 18:47:22 +05301426 if ((wsa_priv->spkr_gain_offset ==
1427 WSA_MACRO_GAIN_OFFSET_M1P5_DB) &&
Laxminath Kasam243e2752018-04-12 00:40:19 +05301428 (wsa_priv->comp_enabled[WSA_MACRO_COMP1] ||
1429 wsa_priv->comp_enabled[WSA_MACRO_COMP2]) &&
1430 (gain_reg == BOLERO_CDC_WSA_RX0_RX_VOL_CTL ||
1431 gain_reg == BOLERO_CDC_WSA_RX1_RX_VOL_CTL)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001432 snd_soc_component_update_bits(component,
1433 BOLERO_CDC_WSA_RX0_RX_PATH_SEC1,
1434 0x01, 0x01);
1435 snd_soc_component_update_bits(component,
1436 BOLERO_CDC_WSA_RX0_RX_PATH_MIX_SEC0,
1437 0x01, 0x01);
1438 snd_soc_component_update_bits(component,
1439 BOLERO_CDC_WSA_RX1_RX_PATH_SEC1,
1440 0x01, 0x01);
1441 snd_soc_component_update_bits(component,
1442 BOLERO_CDC_WSA_RX1_RX_PATH_MIX_SEC0,
1443 0x01, 0x01);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301444 offset_val = -2;
1445 }
Meng Wang15c825d2018-09-06 10:49:18 +08001446 val = snd_soc_component_read32(component, gain_reg);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301447 val += offset_val;
Meng Wang15c825d2018-09-06 10:49:18 +08001448 snd_soc_component_write(component, gain_reg, val);
1449 wsa_macro_config_ear_spkr_gain(component, wsa_priv,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301450 event, gain_reg);
1451 break;
1452 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +08001453 wsa_macro_config_compander(component, w->shift, event);
1454 wsa_macro_config_softclip(component, w->shift, event);
1455 wsa_macro_enable_prim_interpolator(component, reg, event);
Laxminath Kasam21c8b222018-06-21 18:47:22 +05301456 if ((wsa_priv->spkr_gain_offset ==
1457 WSA_MACRO_GAIN_OFFSET_M1P5_DB) &&
Laxminath Kasam243e2752018-04-12 00:40:19 +05301458 (wsa_priv->comp_enabled[WSA_MACRO_COMP1] ||
1459 wsa_priv->comp_enabled[WSA_MACRO_COMP2]) &&
1460 (gain_reg == BOLERO_CDC_WSA_RX0_RX_VOL_CTL ||
1461 gain_reg == BOLERO_CDC_WSA_RX1_RX_VOL_CTL)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001462 snd_soc_component_update_bits(component,
1463 BOLERO_CDC_WSA_RX0_RX_PATH_SEC1,
1464 0x01, 0x00);
1465 snd_soc_component_update_bits(component,
1466 BOLERO_CDC_WSA_RX0_RX_PATH_MIX_SEC0,
1467 0x01, 0x00);
1468 snd_soc_component_update_bits(component,
1469 BOLERO_CDC_WSA_RX1_RX_PATH_SEC1,
1470 0x01, 0x00);
1471 snd_soc_component_update_bits(component,
1472 BOLERO_CDC_WSA_RX1_RX_PATH_MIX_SEC0,
1473 0x01, 0x00);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301474 offset_val = 2;
Meng Wang15c825d2018-09-06 10:49:18 +08001475 val = snd_soc_component_read32(component, gain_reg);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301476 val += offset_val;
Meng Wang15c825d2018-09-06 10:49:18 +08001477 snd_soc_component_write(component, gain_reg, val);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301478 }
Meng Wang15c825d2018-09-06 10:49:18 +08001479 wsa_macro_config_ear_spkr_gain(component, wsa_priv,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301480 event, gain_reg);
1481 break;
1482 }
1483
1484 return 0;
1485}
1486
Meng Wang15c825d2018-09-06 10:49:18 +08001487static int wsa_macro_config_ear_spkr_gain(struct snd_soc_component *component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301488 struct wsa_macro_priv *wsa_priv,
1489 int event, int gain_reg)
1490{
1491 int comp_gain_offset, val;
1492
1493 switch (wsa_priv->spkr_mode) {
Laxminath Kasam21c8b222018-06-21 18:47:22 +05301494 /* Compander gain in WSA_MACRO_SPKR_MODE1 case is 12 dB */
1495 case WSA_MACRO_SPKR_MODE_1:
Laxminath Kasam243e2752018-04-12 00:40:19 +05301496 comp_gain_offset = -12;
1497 break;
1498 /* Default case compander gain is 15 dB */
1499 default:
1500 comp_gain_offset = -15;
1501 break;
1502 }
1503
1504 switch (event) {
1505 case SND_SOC_DAPM_POST_PMU:
1506 /* Apply ear spkr gain only if compander is enabled */
1507 if (wsa_priv->comp_enabled[WSA_MACRO_COMP1] &&
1508 (gain_reg == BOLERO_CDC_WSA_RX0_RX_VOL_CTL) &&
1509 (wsa_priv->ear_spkr_gain != 0)) {
1510 /* For example, val is -8(-12+5-1) for 4dB of gain */
1511 val = comp_gain_offset + wsa_priv->ear_spkr_gain - 1;
Meng Wang15c825d2018-09-06 10:49:18 +08001512 snd_soc_component_write(component, gain_reg, val);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301513
1514 dev_dbg(wsa_priv->dev, "%s: RX0 Volume %d dB\n",
1515 __func__, val);
1516 }
1517 break;
1518 case SND_SOC_DAPM_POST_PMD:
1519 /*
1520 * Reset RX0 volume to 0 dB if compander is enabled and
1521 * ear_spkr_gain is non-zero.
1522 */
1523 if (wsa_priv->comp_enabled[WSA_MACRO_COMP1] &&
1524 (gain_reg == BOLERO_CDC_WSA_RX0_RX_VOL_CTL) &&
1525 (wsa_priv->ear_spkr_gain != 0)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001526 snd_soc_component_write(component, gain_reg, 0x0);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301527
1528 dev_dbg(wsa_priv->dev, "%s: Reset RX0 Volume to 0 dB\n",
1529 __func__);
1530 }
1531 break;
1532 }
1533
1534 return 0;
1535}
1536
1537static int wsa_macro_spk_boost_event(struct snd_soc_dapm_widget *w,
1538 struct snd_kcontrol *kcontrol,
1539 int event)
1540{
Meng Wang15c825d2018-09-06 10:49:18 +08001541 struct snd_soc_component *component =
1542 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301543 u16 boost_path_ctl, boost_path_cfg1;
1544 u16 reg, reg_mix;
1545
Meng Wang15c825d2018-09-06 10:49:18 +08001546 dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301547
1548 if (!strcmp(w->name, "WSA_RX INT0 CHAIN")) {
1549 boost_path_ctl = BOLERO_CDC_WSA_BOOST0_BOOST_PATH_CTL;
1550 boost_path_cfg1 = BOLERO_CDC_WSA_RX0_RX_PATH_CFG1;
1551 reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL;
1552 reg_mix = BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL;
1553 } else if (!strcmp(w->name, "WSA_RX INT1 CHAIN")) {
1554 boost_path_ctl = BOLERO_CDC_WSA_BOOST1_BOOST_PATH_CTL;
1555 boost_path_cfg1 = BOLERO_CDC_WSA_RX1_RX_PATH_CFG1;
1556 reg = BOLERO_CDC_WSA_RX1_RX_PATH_CTL;
1557 reg_mix = BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL;
1558 } else {
Meng Wang15c825d2018-09-06 10:49:18 +08001559 dev_err(component->dev, "%s: unknown widget: %s\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301560 __func__, w->name);
1561 return -EINVAL;
1562 }
1563
1564 switch (event) {
1565 case SND_SOC_DAPM_PRE_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08001566 snd_soc_component_update_bits(component, boost_path_cfg1,
1567 0x01, 0x01);
1568 snd_soc_component_update_bits(component, boost_path_ctl,
1569 0x10, 0x10);
1570 if ((snd_soc_component_read32(component, reg_mix)) & 0x10)
1571 snd_soc_component_update_bits(component, reg_mix,
1572 0x10, 0x00);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301573 break;
Laxminath Kasam0c857002018-07-17 23:47:17 +05301574 case SND_SOC_DAPM_POST_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08001575 snd_soc_component_update_bits(component, reg, 0x10, 0x00);
Laxminath Kasam0c857002018-07-17 23:47:17 +05301576 break;
Laxminath Kasam243e2752018-04-12 00:40:19 +05301577 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +08001578 snd_soc_component_update_bits(component, boost_path_ctl,
1579 0x10, 0x00);
1580 snd_soc_component_update_bits(component, boost_path_cfg1,
1581 0x01, 0x00);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301582 break;
1583 }
1584
1585 return 0;
1586}
1587
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301588
1589static int wsa_macro_enable_vbat(struct snd_soc_dapm_widget *w,
1590 struct snd_kcontrol *kcontrol,
1591 int event)
1592{
Meng Wang15c825d2018-09-06 10:49:18 +08001593 struct snd_soc_component *component =
1594 snd_soc_dapm_to_component(w->dapm);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301595 struct device *wsa_dev = NULL;
1596 struct wsa_macro_priv *wsa_priv = NULL;
1597 u16 vbat_path_cfg = 0;
1598 int softclip_path = 0;
1599
Meng Wang15c825d2018-09-06 10:49:18 +08001600 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301601 return -EINVAL;
1602
Meng Wang15c825d2018-09-06 10:49:18 +08001603 dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301604 if (!strcmp(w->name, "WSA_RX INT0 VBAT")) {
1605 vbat_path_cfg = BOLERO_CDC_WSA_RX0_RX_PATH_CFG1;
1606 softclip_path = WSA_MACRO_SOFTCLIP0;
1607 } else if (!strcmp(w->name, "WSA_RX INT1 VBAT")) {
1608 vbat_path_cfg = BOLERO_CDC_WSA_RX1_RX_PATH_CFG1;
1609 softclip_path = WSA_MACRO_SOFTCLIP1;
1610 }
1611
1612 switch (event) {
1613 case SND_SOC_DAPM_PRE_PMU:
1614 /* Enable clock for VBAT block */
Meng Wang15c825d2018-09-06 10:49:18 +08001615 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301616 BOLERO_CDC_WSA_VBAT_BCL_VBAT_PATH_CTL, 0x10, 0x10);
1617 /* Enable VBAT block */
Meng Wang15c825d2018-09-06 10:49:18 +08001618 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301619 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG, 0x01, 0x01);
1620 /* Update interpolator with 384K path */
Meng Wang15c825d2018-09-06 10:49:18 +08001621 snd_soc_component_update_bits(component, vbat_path_cfg,
1622 0x80, 0x80);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301623 /* Use attenuation mode */
Meng Wang15c825d2018-09-06 10:49:18 +08001624 snd_soc_component_update_bits(component,
1625 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG, 0x02, 0x00);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301626 /*
1627 * BCL block needs softclip clock and mux config to be enabled
1628 */
Meng Wang15c825d2018-09-06 10:49:18 +08001629 wsa_macro_enable_softclip_clk(component, wsa_priv,
1630 softclip_path, true);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301631 /* Enable VBAT at channel level */
Meng Wang15c825d2018-09-06 10:49:18 +08001632 snd_soc_component_update_bits(component, vbat_path_cfg,
1633 0x02, 0x02);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301634 /* Set the ATTK1 gain */
Meng Wang15c825d2018-09-06 10:49:18 +08001635 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301636 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD1,
1637 0xFF, 0xFF);
Meng Wang15c825d2018-09-06 10:49:18 +08001638 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301639 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD2,
1640 0xFF, 0x03);
Meng Wang15c825d2018-09-06 10:49:18 +08001641 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301642 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD3,
1643 0xFF, 0x00);
1644 /* Set the ATTK2 gain */
Meng Wang15c825d2018-09-06 10:49:18 +08001645 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301646 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD4,
1647 0xFF, 0xFF);
Meng Wang15c825d2018-09-06 10:49:18 +08001648 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301649 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD5,
1650 0xFF, 0x03);
Meng Wang15c825d2018-09-06 10:49:18 +08001651 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301652 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD6,
1653 0xFF, 0x00);
1654 /* Set the ATTK3 gain */
Meng Wang15c825d2018-09-06 10:49:18 +08001655 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301656 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD7,
1657 0xFF, 0xFF);
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_UPD8,
1660 0xFF, 0x03);
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_UPD9,
1663 0xFF, 0x00);
1664 break;
1665
1666 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +08001667 snd_soc_component_update_bits(component, vbat_path_cfg,
1668 0x80, 0x00);
1669 snd_soc_component_update_bits(component,
1670 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG,
1671 0x02, 0x02);
1672 snd_soc_component_update_bits(component, vbat_path_cfg,
1673 0x02, 0x00);
1674 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301675 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD1,
1676 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001677 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301678 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD2,
1679 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001680 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301681 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD3,
1682 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001683 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301684 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD4,
1685 0xFF, 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_BCL_GAIN_UPD5,
1688 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001689 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301690 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD6,
1691 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001692 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301693 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD7,
1694 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001695 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301696 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD8,
1697 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001698 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301699 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD9,
1700 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001701 wsa_macro_enable_softclip_clk(component, wsa_priv,
1702 softclip_path, false);
1703 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301704 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG, 0x01, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001705 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301706 BOLERO_CDC_WSA_VBAT_BCL_VBAT_PATH_CTL, 0x10, 0x00);
1707 break;
1708 default:
1709 dev_err(wsa_dev, "%s: Invalid event %d\n", __func__, event);
1710 break;
1711 }
1712 return 0;
1713}
1714
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301715static int wsa_macro_enable_echo(struct snd_soc_dapm_widget *w,
1716 struct snd_kcontrol *kcontrol,
1717 int event)
1718{
Meng Wang15c825d2018-09-06 10:49:18 +08001719 struct snd_soc_component *component =
1720 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301721 struct device *wsa_dev = NULL;
1722 struct wsa_macro_priv *wsa_priv = NULL;
1723 u16 val, ec_tx = 0, ec_hq_reg;
1724
Meng Wang15c825d2018-09-06 10:49:18 +08001725 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301726 return -EINVAL;
1727
1728 dev_dbg(wsa_dev, "%s %d %s\n", __func__, event, w->name);
1729
Meng Wang15c825d2018-09-06 10:49:18 +08001730 val = snd_soc_component_read32(component,
1731 BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301732 if (!(strcmp(w->name, "WSA RX_MIX EC0_MUX")))
1733 ec_tx = (val & 0x07) - 1;
1734 else
1735 ec_tx = ((val & 0x38) >> 0x3) - 1;
1736
1737 if (ec_tx < 0 || ec_tx >= (WSA_MACRO_RX1 + 1)) {
1738 dev_err(wsa_dev, "%s: EC mix control not set correctly\n",
1739 __func__);
1740 return -EINVAL;
1741 }
1742 if (wsa_priv->ec_hq[ec_tx]) {
Meng Wang15c825d2018-09-06 10:49:18 +08001743 snd_soc_component_update_bits(component,
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301744 BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0,
1745 0x1 << ec_tx, 0x1 << ec_tx);
1746 ec_hq_reg = BOLERO_CDC_WSA_EC_HQ0_EC_REF_HQ_PATH_CTL +
Laxminath Kasam5d9ea8d2018-11-28 14:32:40 +05301747 0x40 * ec_tx;
Meng Wang15c825d2018-09-06 10:49:18 +08001748 snd_soc_component_update_bits(component, ec_hq_reg, 0x01, 0x01);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301749 ec_hq_reg = BOLERO_CDC_WSA_EC_HQ0_EC_REF_HQ_CFG0 +
Laxminath Kasam5d9ea8d2018-11-28 14:32:40 +05301750 0x40 * ec_tx;
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301751 /* default set to 48k */
Meng Wang15c825d2018-09-06 10:49:18 +08001752 snd_soc_component_update_bits(component, ec_hq_reg, 0x1E, 0x08);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301753 }
1754
1755 return 0;
1756}
1757
1758static int wsa_macro_get_ec_hq(struct snd_kcontrol *kcontrol,
1759 struct snd_ctl_elem_value *ucontrol)
1760{
1761
Meng Wang15c825d2018-09-06 10:49:18 +08001762 struct snd_soc_component *component =
1763 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301764 int ec_tx = ((struct soc_multi_mixer_control *)
1765 kcontrol->private_value)->shift;
1766 struct device *wsa_dev = NULL;
1767 struct wsa_macro_priv *wsa_priv = NULL;
1768
Meng Wang15c825d2018-09-06 10:49:18 +08001769 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301770 return -EINVAL;
1771
1772 ucontrol->value.integer.value[0] = wsa_priv->ec_hq[ec_tx];
1773 return 0;
1774}
1775
1776static int wsa_macro_set_ec_hq(struct snd_kcontrol *kcontrol,
1777 struct snd_ctl_elem_value *ucontrol)
1778{
Meng Wang15c825d2018-09-06 10:49:18 +08001779 struct snd_soc_component *component =
1780 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301781 int ec_tx = ((struct soc_multi_mixer_control *)
1782 kcontrol->private_value)->shift;
1783 int value = ucontrol->value.integer.value[0];
1784 struct device *wsa_dev = NULL;
1785 struct wsa_macro_priv *wsa_priv = NULL;
1786
Meng Wang15c825d2018-09-06 10:49:18 +08001787 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301788 return -EINVAL;
1789
1790 dev_dbg(wsa_dev, "%s: enable current %d, new %d\n",
1791 __func__, wsa_priv->ec_hq[ec_tx], value);
1792 wsa_priv->ec_hq[ec_tx] = value;
1793
1794 return 0;
1795}
1796
Laxminath Kasam243e2752018-04-12 00:40:19 +05301797static int wsa_macro_get_compander(struct snd_kcontrol *kcontrol,
1798 struct snd_ctl_elem_value *ucontrol)
1799{
1800
Meng Wang15c825d2018-09-06 10:49:18 +08001801 struct snd_soc_component *component =
1802 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301803 int comp = ((struct soc_multi_mixer_control *)
1804 kcontrol->private_value)->shift;
1805 struct device *wsa_dev = NULL;
1806 struct wsa_macro_priv *wsa_priv = NULL;
1807
Meng Wang15c825d2018-09-06 10:49:18 +08001808 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301809 return -EINVAL;
1810
1811 ucontrol->value.integer.value[0] = wsa_priv->comp_enabled[comp];
1812 return 0;
1813}
1814
1815static int wsa_macro_set_compander(struct snd_kcontrol *kcontrol,
1816 struct snd_ctl_elem_value *ucontrol)
1817{
Meng Wang15c825d2018-09-06 10:49:18 +08001818 struct snd_soc_component *component =
1819 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301820 int comp = ((struct soc_multi_mixer_control *)
1821 kcontrol->private_value)->shift;
1822 int value = ucontrol->value.integer.value[0];
1823 struct device *wsa_dev = NULL;
1824 struct wsa_macro_priv *wsa_priv = NULL;
1825
Meng Wang15c825d2018-09-06 10:49:18 +08001826 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301827 return -EINVAL;
1828
Meng Wang15c825d2018-09-06 10:49:18 +08001829 dev_dbg(component->dev, "%s: Compander %d enable current %d, new %d\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301830 __func__, comp + 1, wsa_priv->comp_enabled[comp], value);
1831 wsa_priv->comp_enabled[comp] = value;
1832
1833 return 0;
1834}
1835
1836static int wsa_macro_ear_spkr_pa_gain_get(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 ucontrol->value.integer.value[0] = wsa_priv->ear_spkr_gain;
1848
Meng Wang15c825d2018-09-06 10:49:18 +08001849 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301850 __func__, ucontrol->value.integer.value[0]);
1851
1852 return 0;
1853}
1854
1855static int wsa_macro_ear_spkr_pa_gain_put(struct snd_kcontrol *kcontrol,
1856 struct snd_ctl_elem_value *ucontrol)
1857{
Meng Wang15c825d2018-09-06 10:49:18 +08001858 struct snd_soc_component *component =
1859 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301860 struct device *wsa_dev = NULL;
1861 struct wsa_macro_priv *wsa_priv = NULL;
1862
Meng Wang15c825d2018-09-06 10:49:18 +08001863 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301864 return -EINVAL;
1865
1866 wsa_priv->ear_spkr_gain = ucontrol->value.integer.value[0];
1867
Meng Wang15c825d2018-09-06 10:49:18 +08001868 dev_dbg(component->dev, "%s: gain = %d\n", __func__,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301869 wsa_priv->ear_spkr_gain);
1870
1871 return 0;
1872}
1873
1874static int wsa_macro_spkr_left_boost_stage_get(struct snd_kcontrol *kcontrol,
1875 struct snd_ctl_elem_value *ucontrol)
1876{
1877 u8 bst_state_max = 0;
Meng Wang15c825d2018-09-06 10:49:18 +08001878 struct snd_soc_component *component =
1879 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301880
Meng Wang15c825d2018-09-06 10:49:18 +08001881 bst_state_max = snd_soc_component_read32(component,
1882 BOLERO_CDC_WSA_BOOST0_BOOST_CTL);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301883 bst_state_max = (bst_state_max & 0x0c) >> 2;
1884 ucontrol->value.integer.value[0] = bst_state_max;
Meng Wang15c825d2018-09-06 10:49:18 +08001885 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301886 __func__, ucontrol->value.integer.value[0]);
1887
1888 return 0;
1889}
1890
1891static int wsa_macro_spkr_left_boost_stage_put(struct snd_kcontrol *kcontrol,
1892 struct snd_ctl_elem_value *ucontrol)
1893{
1894 u8 bst_state_max;
Meng Wang15c825d2018-09-06 10:49:18 +08001895 struct snd_soc_component *component =
1896 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301897
Meng Wang15c825d2018-09-06 10:49:18 +08001898 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301899 __func__, ucontrol->value.integer.value[0]);
1900 bst_state_max = ucontrol->value.integer.value[0] << 2;
Meng Wang15c825d2018-09-06 10:49:18 +08001901 snd_soc_component_update_bits(component,
1902 BOLERO_CDC_WSA_BOOST0_BOOST_CTL,
1903 0x0c, bst_state_max);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301904
1905 return 0;
1906}
1907
1908static int wsa_macro_spkr_right_boost_stage_get(struct snd_kcontrol *kcontrol,
1909 struct snd_ctl_elem_value *ucontrol)
1910{
1911 u8 bst_state_max = 0;
Meng Wang15c825d2018-09-06 10:49:18 +08001912 struct snd_soc_component *component =
1913 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301914
Meng Wang15c825d2018-09-06 10:49:18 +08001915 bst_state_max = snd_soc_component_read32(component,
1916 BOLERO_CDC_WSA_BOOST1_BOOST_CTL);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301917 bst_state_max = (bst_state_max & 0x0c) >> 2;
1918 ucontrol->value.integer.value[0] = bst_state_max;
Meng Wang15c825d2018-09-06 10:49:18 +08001919 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301920 __func__, ucontrol->value.integer.value[0]);
1921
1922 return 0;
1923}
1924
1925static int wsa_macro_spkr_right_boost_stage_put(struct snd_kcontrol *kcontrol,
1926 struct snd_ctl_elem_value *ucontrol)
1927{
1928 u8 bst_state_max;
Meng Wang15c825d2018-09-06 10:49:18 +08001929 struct snd_soc_component *component =
1930 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301931
Meng Wang15c825d2018-09-06 10:49:18 +08001932 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301933 __func__, ucontrol->value.integer.value[0]);
1934 bst_state_max = ucontrol->value.integer.value[0] << 2;
Meng Wang15c825d2018-09-06 10:49:18 +08001935 snd_soc_component_update_bits(component,
1936 BOLERO_CDC_WSA_BOOST1_BOOST_CTL,
1937 0x0c, bst_state_max);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301938
1939 return 0;
1940}
1941
1942static int wsa_macro_rx_mux_get(struct snd_kcontrol *kcontrol,
1943 struct snd_ctl_elem_value *ucontrol)
1944{
1945 struct snd_soc_dapm_widget *widget =
1946 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +08001947 struct snd_soc_component *component =
1948 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301949 struct device *wsa_dev = NULL;
1950 struct wsa_macro_priv *wsa_priv = NULL;
1951
Meng Wang15c825d2018-09-06 10:49:18 +08001952 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301953 return -EINVAL;
1954
1955 ucontrol->value.integer.value[0] =
1956 wsa_priv->rx_port_value[widget->shift];
1957 return 0;
1958}
1959
1960static int wsa_macro_rx_mux_put(struct snd_kcontrol *kcontrol,
1961 struct snd_ctl_elem_value *ucontrol)
1962{
1963 struct snd_soc_dapm_widget *widget =
1964 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +08001965 struct snd_soc_component *component =
1966 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301967 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1968 struct snd_soc_dapm_update *update = NULL;
1969 u32 rx_port_value = ucontrol->value.integer.value[0];
1970 u32 bit_input = 0;
1971 u32 aif_rst;
1972 struct device *wsa_dev = NULL;
1973 struct wsa_macro_priv *wsa_priv = NULL;
1974
Meng Wang15c825d2018-09-06 10:49:18 +08001975 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301976 return -EINVAL;
1977
1978 aif_rst = wsa_priv->rx_port_value[widget->shift];
1979 if (!rx_port_value) {
1980 if (aif_rst == 0) {
1981 dev_err(wsa_dev, "%s: AIF reset already\n", __func__);
1982 return 0;
1983 }
1984 }
1985 wsa_priv->rx_port_value[widget->shift] = rx_port_value;
1986
1987 bit_input = widget->shift;
1988 if (widget->shift >= WSA_MACRO_RX_MIX)
1989 bit_input %= WSA_MACRO_RX_MIX;
1990
1991 switch (rx_port_value) {
1992 case 0:
1993 clear_bit(bit_input,
Laxminath Kasam59c7a1d2018-08-09 16:11:17 +05301994 &wsa_priv->active_ch_mask[aif_rst]);
1995 wsa_priv->active_ch_cnt[aif_rst]--;
Laxminath Kasam243e2752018-04-12 00:40:19 +05301996 break;
1997 case 1:
1998 case 2:
1999 set_bit(bit_input,
Laxminath Kasam59c7a1d2018-08-09 16:11:17 +05302000 &wsa_priv->active_ch_mask[rx_port_value]);
2001 wsa_priv->active_ch_cnt[rx_port_value]++;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302002 break;
2003 default:
2004 dev_err(wsa_dev,
2005 "%s: Invalid AIF_ID for WSA RX MUX\n", __func__);
2006 return -EINVAL;
2007 }
2008
2009 snd_soc_dapm_mux_update_power(widget->dapm, kcontrol,
2010 rx_port_value, e, update);
2011 return 0;
2012}
2013
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302014static int wsa_macro_vbat_bcl_gsm_mode_func_get(struct snd_kcontrol *kcontrol,
2015 struct snd_ctl_elem_value *ucontrol)
2016{
Meng Wang15c825d2018-09-06 10:49:18 +08002017 struct snd_soc_component *component =
2018 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302019
2020 ucontrol->value.integer.value[0] =
Meng Wang15c825d2018-09-06 10:49:18 +08002021 ((snd_soc_component_read32(
2022 component, BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG) & 0x04) ?
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302023 1 : 0);
2024
Meng Wang15c825d2018-09-06 10:49:18 +08002025 dev_dbg(component->dev, "%s: value: %lu\n", __func__,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302026 ucontrol->value.integer.value[0]);
2027
2028 return 0;
2029}
2030
2031static int wsa_macro_vbat_bcl_gsm_mode_func_put(struct snd_kcontrol *kcontrol,
2032 struct snd_ctl_elem_value *ucontrol)
2033{
Meng Wang15c825d2018-09-06 10:49:18 +08002034 struct snd_soc_component *component =
2035 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302036
Meng Wang15c825d2018-09-06 10:49:18 +08002037 dev_dbg(component->dev, "%s: value: %lu\n", __func__,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302038 ucontrol->value.integer.value[0]);
2039
2040 /* Set Vbat register configuration for GSM mode bit based on value */
2041 if (ucontrol->value.integer.value[0])
Meng Wang15c825d2018-09-06 10:49:18 +08002042 snd_soc_component_update_bits(component,
2043 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG,
2044 0x04, 0x04);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302045 else
Meng Wang15c825d2018-09-06 10:49:18 +08002046 snd_soc_component_update_bits(component,
2047 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG,
2048 0x04, 0x00);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302049
2050 return 0;
2051}
2052
2053static int wsa_macro_soft_clip_enable_get(struct snd_kcontrol *kcontrol,
2054 struct snd_ctl_elem_value *ucontrol)
2055{
Meng Wang15c825d2018-09-06 10:49:18 +08002056 struct snd_soc_component *component =
2057 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302058 struct device *wsa_dev = NULL;
2059 struct wsa_macro_priv *wsa_priv = NULL;
2060 int path = ((struct soc_multi_mixer_control *)
2061 kcontrol->private_value)->shift;
2062
Meng Wang15c825d2018-09-06 10:49:18 +08002063 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302064 return -EINVAL;
2065
2066 ucontrol->value.integer.value[0] = wsa_priv->is_softclip_on[path];
2067
Meng Wang15c825d2018-09-06 10:49:18 +08002068 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302069 __func__, ucontrol->value.integer.value[0]);
2070
2071 return 0;
2072}
2073
2074static int wsa_macro_soft_clip_enable_put(struct snd_kcontrol *kcontrol,
2075 struct snd_ctl_elem_value *ucontrol)
2076{
Meng Wang15c825d2018-09-06 10:49:18 +08002077 struct snd_soc_component *component =
2078 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302079 struct device *wsa_dev = NULL;
2080 struct wsa_macro_priv *wsa_priv = NULL;
2081 int path = ((struct soc_multi_mixer_control *)
2082 kcontrol->private_value)->shift;
2083
Meng Wang15c825d2018-09-06 10:49:18 +08002084 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302085 return -EINVAL;
2086
2087 wsa_priv->is_softclip_on[path] = ucontrol->value.integer.value[0];
2088
Meng Wang15c825d2018-09-06 10:49:18 +08002089 dev_dbg(component->dev, "%s: soft clip enable for %d: %d\n", __func__,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302090 path, wsa_priv->is_softclip_on[path]);
2091
2092 return 0;
2093}
2094
Laxminath Kasam243e2752018-04-12 00:40:19 +05302095static const struct snd_kcontrol_new wsa_macro_snd_controls[] = {
2096 SOC_ENUM_EXT("EAR SPKR PA Gain", wsa_macro_ear_spkr_pa_gain_enum,
2097 wsa_macro_ear_spkr_pa_gain_get,
2098 wsa_macro_ear_spkr_pa_gain_put),
2099 SOC_ENUM_EXT("SPKR Left Boost Max State",
2100 wsa_macro_spkr_boost_stage_enum,
2101 wsa_macro_spkr_left_boost_stage_get,
2102 wsa_macro_spkr_left_boost_stage_put),
2103 SOC_ENUM_EXT("SPKR Right Boost Max State",
2104 wsa_macro_spkr_boost_stage_enum,
2105 wsa_macro_spkr_right_boost_stage_get,
2106 wsa_macro_spkr_right_boost_stage_put),
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302107 SOC_ENUM_EXT("GSM mode Enable", wsa_macro_vbat_bcl_gsm_mode_enum,
2108 wsa_macro_vbat_bcl_gsm_mode_func_get,
2109 wsa_macro_vbat_bcl_gsm_mode_func_put),
2110 SOC_SINGLE_EXT("WSA_Softclip0 Enable", SND_SOC_NOPM,
2111 WSA_MACRO_SOFTCLIP0, 1, 0,
2112 wsa_macro_soft_clip_enable_get,
2113 wsa_macro_soft_clip_enable_put),
2114 SOC_SINGLE_EXT("WSA_Softclip1 Enable", SND_SOC_NOPM,
2115 WSA_MACRO_SOFTCLIP1, 1, 0,
2116 wsa_macro_soft_clip_enable_get,
2117 wsa_macro_soft_clip_enable_put),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302118 SOC_SINGLE_SX_TLV("WSA_RX0 Digital Volume",
2119 BOLERO_CDC_WSA_RX0_RX_VOL_CTL,
2120 0, -84, 40, digital_gain),
2121 SOC_SINGLE_SX_TLV("WSA_RX1 Digital Volume",
2122 BOLERO_CDC_WSA_RX1_RX_VOL_CTL,
2123 0, -84, 40, digital_gain),
2124 SOC_SINGLE_EXT("WSA_COMP1 Switch", SND_SOC_NOPM, WSA_MACRO_COMP1, 1, 0,
2125 wsa_macro_get_compander, wsa_macro_set_compander),
2126 SOC_SINGLE_EXT("WSA_COMP2 Switch", SND_SOC_NOPM, WSA_MACRO_COMP2, 1, 0,
2127 wsa_macro_get_compander, wsa_macro_set_compander),
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05302128 SOC_SINGLE_EXT("WSA_RX0 EC_HQ Switch", SND_SOC_NOPM, WSA_MACRO_RX0,
2129 1, 0, wsa_macro_get_ec_hq, wsa_macro_set_ec_hq),
2130 SOC_SINGLE_EXT("WSA_RX1 EC_HQ Switch", SND_SOC_NOPM, WSA_MACRO_RX1,
2131 1, 0, wsa_macro_get_ec_hq, wsa_macro_set_ec_hq),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302132};
2133
2134static const struct soc_enum rx_mux_enum =
2135 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_mux_text), rx_mux_text);
2136
2137static const struct snd_kcontrol_new rx_mux[WSA_MACRO_RX_MAX] = {
2138 SOC_DAPM_ENUM_EXT("WSA RX0 Mux", rx_mux_enum,
2139 wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),
2140 SOC_DAPM_ENUM_EXT("WSA RX1 Mux", rx_mux_enum,
2141 wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),
2142 SOC_DAPM_ENUM_EXT("WSA RX_MIX0 Mux", rx_mux_enum,
2143 wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),
2144 SOC_DAPM_ENUM_EXT("WSA RX_MIX1 Mux", rx_mux_enum,
2145 wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),
2146};
2147
2148static int wsa_macro_vi_feed_mixer_get(struct snd_kcontrol *kcontrol,
2149 struct snd_ctl_elem_value *ucontrol)
2150{
2151 struct snd_soc_dapm_widget *widget =
2152 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +08002153 struct snd_soc_component *component =
2154 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302155 struct soc_multi_mixer_control *mixer =
2156 ((struct soc_multi_mixer_control *)kcontrol->private_value);
2157 u32 dai_id = widget->shift;
2158 u32 spk_tx_id = mixer->shift;
2159 struct device *wsa_dev = NULL;
2160 struct wsa_macro_priv *wsa_priv = NULL;
2161
Meng Wang15c825d2018-09-06 10:49:18 +08002162 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302163 return -EINVAL;
2164
2165 if (test_bit(spk_tx_id, &wsa_priv->active_ch_mask[dai_id]))
2166 ucontrol->value.integer.value[0] = 1;
2167 else
2168 ucontrol->value.integer.value[0] = 0;
2169
2170 return 0;
2171}
2172
2173static int wsa_macro_vi_feed_mixer_put(struct snd_kcontrol *kcontrol,
2174 struct snd_ctl_elem_value *ucontrol)
2175{
2176 struct snd_soc_dapm_widget *widget =
2177 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +08002178 struct snd_soc_component *component =
2179 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302180 struct soc_multi_mixer_control *mixer =
2181 ((struct soc_multi_mixer_control *)kcontrol->private_value);
2182 u32 spk_tx_id = mixer->shift;
2183 u32 enable = ucontrol->value.integer.value[0];
2184 struct device *wsa_dev = NULL;
2185 struct wsa_macro_priv *wsa_priv = NULL;
2186
Meng Wang15c825d2018-09-06 10:49:18 +08002187 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302188 return -EINVAL;
2189
2190 wsa_priv->vi_feed_value = ucontrol->value.integer.value[0];
2191
2192 if (enable) {
2193 if (spk_tx_id == WSA_MACRO_TX0 &&
2194 !test_bit(WSA_MACRO_TX0,
2195 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
2196 set_bit(WSA_MACRO_TX0,
2197 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI]);
2198 wsa_priv->active_ch_cnt[WSA_MACRO_AIF_VI]++;
2199 }
2200 if (spk_tx_id == WSA_MACRO_TX1 &&
2201 !test_bit(WSA_MACRO_TX1,
2202 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
2203 set_bit(WSA_MACRO_TX1,
2204 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI]);
2205 wsa_priv->active_ch_cnt[WSA_MACRO_AIF_VI]++;
2206 }
2207 } else {
2208 if (spk_tx_id == WSA_MACRO_TX0 &&
2209 test_bit(WSA_MACRO_TX0,
2210 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
2211 clear_bit(WSA_MACRO_TX0,
2212 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI]);
2213 wsa_priv->active_ch_cnt[WSA_MACRO_AIF_VI]--;
2214 }
2215 if (spk_tx_id == WSA_MACRO_TX1 &&
2216 test_bit(WSA_MACRO_TX1,
2217 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
2218 clear_bit(WSA_MACRO_TX1,
2219 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI]);
2220 wsa_priv->active_ch_cnt[WSA_MACRO_AIF_VI]--;
2221 }
2222 }
2223 snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, NULL);
2224
2225 return 0;
2226}
2227
2228static const struct snd_kcontrol_new aif_vi_mixer[] = {
2229 SOC_SINGLE_EXT("WSA_SPKR_VI_1", SND_SOC_NOPM, WSA_MACRO_TX0, 1, 0,
2230 wsa_macro_vi_feed_mixer_get,
2231 wsa_macro_vi_feed_mixer_put),
2232 SOC_SINGLE_EXT("WSA_SPKR_VI_2", SND_SOC_NOPM, WSA_MACRO_TX1, 1, 0,
2233 wsa_macro_vi_feed_mixer_get,
2234 wsa_macro_vi_feed_mixer_put),
2235};
2236
2237static const struct snd_soc_dapm_widget wsa_macro_dapm_widgets[] = {
2238 SND_SOC_DAPM_AIF_IN("WSA AIF1 PB", "WSA_AIF1 Playback", 0,
2239 SND_SOC_NOPM, 0, 0),
2240
2241 SND_SOC_DAPM_AIF_IN("WSA AIF_MIX1 PB", "WSA_AIF_MIX1 Playback", 0,
2242 SND_SOC_NOPM, 0, 0),
2243
2244 SND_SOC_DAPM_AIF_OUT_E("WSA AIF_VI", "WSA_AIF_VI Capture", 0,
2245 SND_SOC_NOPM, WSA_MACRO_AIF_VI, 0,
2246 wsa_macro_enable_vi_feedback,
2247 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
2248
2249 SND_SOC_DAPM_AIF_OUT("WSA AIF_ECHO", "WSA_AIF_ECHO Capture", 0,
2250 SND_SOC_NOPM, 0, 0),
2251
2252 SND_SOC_DAPM_MIXER("WSA_AIF_VI Mixer", SND_SOC_NOPM, WSA_MACRO_AIF_VI,
2253 0, aif_vi_mixer, ARRAY_SIZE(aif_vi_mixer)),
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05302254 SND_SOC_DAPM_MUX_E("WSA RX_MIX EC0_MUX", SND_SOC_NOPM,
2255 WSA_MACRO_EC0_MUX, 0,
2256 &rx_mix_ec0_mux, wsa_macro_enable_echo,
2257 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2258 SND_SOC_DAPM_MUX_E("WSA RX_MIX EC1_MUX", SND_SOC_NOPM,
2259 WSA_MACRO_EC1_MUX, 0,
2260 &rx_mix_ec1_mux, wsa_macro_enable_echo,
2261 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302262
2263 SND_SOC_DAPM_MUX("WSA RX0 MUX", SND_SOC_NOPM, WSA_MACRO_RX0, 0,
2264 &rx_mux[WSA_MACRO_RX0]),
2265 SND_SOC_DAPM_MUX("WSA RX1 MUX", SND_SOC_NOPM, WSA_MACRO_RX1, 0,
2266 &rx_mux[WSA_MACRO_RX1]),
2267 SND_SOC_DAPM_MUX("WSA RX_MIX0 MUX", SND_SOC_NOPM, WSA_MACRO_RX_MIX0, 0,
2268 &rx_mux[WSA_MACRO_RX_MIX0]),
2269 SND_SOC_DAPM_MUX("WSA RX_MIX1 MUX", SND_SOC_NOPM, WSA_MACRO_RX_MIX1, 0,
2270 &rx_mux[WSA_MACRO_RX_MIX1]),
2271
2272 SND_SOC_DAPM_MIXER("WSA RX0", SND_SOC_NOPM, 0, 0, NULL, 0),
2273 SND_SOC_DAPM_MIXER("WSA RX1", SND_SOC_NOPM, 0, 0, NULL, 0),
2274 SND_SOC_DAPM_MIXER("WSA RX_MIX0", SND_SOC_NOPM, 0, 0, NULL, 0),
2275 SND_SOC_DAPM_MIXER("WSA RX_MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
2276
2277 SND_SOC_DAPM_MUX_E("WSA_RX0 INP0", SND_SOC_NOPM, 0, 0,
2278 &rx0_prim_inp0_mux, wsa_macro_enable_swr,
2279 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2280 SND_SOC_DAPM_MUX_E("WSA_RX0 INP1", SND_SOC_NOPM, 0, 0,
2281 &rx0_prim_inp1_mux, wsa_macro_enable_swr,
2282 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2283 SND_SOC_DAPM_MUX_E("WSA_RX0 INP2", SND_SOC_NOPM, 0, 0,
2284 &rx0_prim_inp2_mux, wsa_macro_enable_swr,
2285 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2286 SND_SOC_DAPM_MUX_E("WSA_RX0 MIX INP", SND_SOC_NOPM, 0, 0,
2287 &rx0_mix_mux, wsa_macro_enable_mix_path,
2288 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2289 SND_SOC_DAPM_MUX_E("WSA_RX1 INP0", SND_SOC_NOPM, 0, 0,
2290 &rx1_prim_inp0_mux, wsa_macro_enable_swr,
2291 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2292 SND_SOC_DAPM_MUX_E("WSA_RX1 INP1", SND_SOC_NOPM, 0, 0,
2293 &rx1_prim_inp1_mux, wsa_macro_enable_swr,
2294 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2295 SND_SOC_DAPM_MUX_E("WSA_RX1 INP2", SND_SOC_NOPM, 0, 0,
2296 &rx1_prim_inp2_mux, wsa_macro_enable_swr,
2297 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2298 SND_SOC_DAPM_MUX_E("WSA_RX1 MIX INP", SND_SOC_NOPM, 0, 0,
2299 &rx1_mix_mux, wsa_macro_enable_mix_path,
2300 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2301 SND_SOC_DAPM_MIXER("WSA_RX INT0 MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
2302 SND_SOC_DAPM_MIXER("WSA_RX INT1 MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
2303 SND_SOC_DAPM_MIXER("WSA_RX INT0 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
2304 SND_SOC_DAPM_MIXER("WSA_RX INT1 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
2305
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302306 SND_SOC_DAPM_MUX_E("WSA_RX0 INT0 SIDETONE MIX",
2307 BOLERO_CDC_WSA_RX0_RX_PATH_CFG1, 4, 0,
2308 &rx0_sidetone_mix_mux, wsa_macro_enable_swr,
2309 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2310 SND_SOC_DAPM_INPUT("WSA SRC0_INP"),
2311
2312 SND_SOC_DAPM_INPUT("WSA_TX DEC0_INP"),
2313 SND_SOC_DAPM_INPUT("WSA_TX DEC1_INP"),
2314
Laxminath Kasam243e2752018-04-12 00:40:19 +05302315 SND_SOC_DAPM_MIXER_E("WSA_RX INT0 INTERP", SND_SOC_NOPM,
2316 WSA_MACRO_COMP1, 0, NULL, 0, wsa_macro_enable_interpolator,
2317 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2318 SND_SOC_DAPM_POST_PMD),
2319 SND_SOC_DAPM_MIXER_E("WSA_RX INT1 INTERP", SND_SOC_NOPM,
2320 WSA_MACRO_COMP2, 0, NULL, 0, wsa_macro_enable_interpolator,
2321 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2322 SND_SOC_DAPM_POST_PMD),
2323
2324 SND_SOC_DAPM_MIXER_E("WSA_RX INT0 CHAIN", SND_SOC_NOPM, 0, 0,
2325 NULL, 0, wsa_macro_spk_boost_event,
Laxminath Kasam0c857002018-07-17 23:47:17 +05302326 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2327 SND_SOC_DAPM_POST_PMD),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302328 SND_SOC_DAPM_MIXER_E("WSA_RX INT1 CHAIN", SND_SOC_NOPM, 0, 0,
2329 NULL, 0, wsa_macro_spk_boost_event,
Laxminath Kasam0c857002018-07-17 23:47:17 +05302330 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2331 SND_SOC_DAPM_POST_PMD),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302332
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302333 SND_SOC_DAPM_MIXER_E("WSA_RX INT0 VBAT", SND_SOC_NOPM,
2334 0, 0, wsa_int0_vbat_mix_switch,
2335 ARRAY_SIZE(wsa_int0_vbat_mix_switch),
2336 wsa_macro_enable_vbat,
2337 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2338 SND_SOC_DAPM_MIXER_E("WSA_RX INT1 VBAT", SND_SOC_NOPM,
2339 0, 0, wsa_int1_vbat_mix_switch,
2340 ARRAY_SIZE(wsa_int1_vbat_mix_switch),
2341 wsa_macro_enable_vbat,
2342 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2343
Laxminath Kasam243e2752018-04-12 00:40:19 +05302344 SND_SOC_DAPM_INPUT("VIINPUT_WSA"),
2345
2346 SND_SOC_DAPM_OUTPUT("WSA_SPK1 OUT"),
2347 SND_SOC_DAPM_OUTPUT("WSA_SPK2 OUT"),
2348
2349 SND_SOC_DAPM_SUPPLY_S("WSA_MCLK", 0, SND_SOC_NOPM, 0, 0,
2350 wsa_macro_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2351};
2352
2353static const struct snd_soc_dapm_route wsa_audio_map[] = {
2354 /* VI Feedback */
2355 {"WSA_AIF_VI Mixer", "WSA_SPKR_VI_1", "VIINPUT_WSA"},
2356 {"WSA_AIF_VI Mixer", "WSA_SPKR_VI_2", "VIINPUT_WSA"},
2357 {"WSA AIF_VI", NULL, "WSA_AIF_VI Mixer"},
2358 {"WSA AIF_VI", NULL, "WSA_MCLK"},
2359
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05302360 {"WSA RX_MIX EC0_MUX", "RX_MIX_TX0", "WSA_RX INT0 SEC MIX"},
2361 {"WSA RX_MIX EC1_MUX", "RX_MIX_TX0", "WSA_RX INT0 SEC MIX"},
2362 {"WSA RX_MIX EC0_MUX", "RX_MIX_TX1", "WSA_RX INT1 SEC MIX"},
2363 {"WSA RX_MIX EC1_MUX", "RX_MIX_TX1", "WSA_RX INT1 SEC MIX"},
2364 {"WSA AIF_ECHO", NULL, "WSA RX_MIX EC0_MUX"},
2365 {"WSA AIF_ECHO", NULL, "WSA RX_MIX EC1_MUX"},
2366 {"WSA AIF_ECHO", NULL, "WSA_MCLK"},
2367
Laxminath Kasam243e2752018-04-12 00:40:19 +05302368 {"WSA AIF1 PB", NULL, "WSA_MCLK"},
2369 {"WSA AIF_MIX1 PB", NULL, "WSA_MCLK"},
2370
2371 {"WSA RX0 MUX", "AIF1_PB", "WSA AIF1 PB"},
2372 {"WSA RX1 MUX", "AIF1_PB", "WSA AIF1 PB"},
2373 {"WSA RX_MIX0 MUX", "AIF1_PB", "WSA AIF1 PB"},
2374 {"WSA RX_MIX1 MUX", "AIF1_PB", "WSA AIF1 PB"},
2375
2376 {"WSA RX0 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
2377 {"WSA RX1 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
2378 {"WSA RX_MIX0 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
2379 {"WSA RX_MIX1 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
2380
2381 {"WSA RX0", NULL, "WSA RX0 MUX"},
2382 {"WSA RX1", NULL, "WSA RX1 MUX"},
2383 {"WSA RX_MIX0", NULL, "WSA RX_MIX0 MUX"},
2384 {"WSA RX_MIX1", NULL, "WSA RX_MIX1 MUX"},
2385
2386 {"WSA_RX0 INP0", "RX0", "WSA RX0"},
2387 {"WSA_RX0 INP0", "RX1", "WSA RX1"},
2388 {"WSA_RX0 INP0", "RX_MIX0", "WSA RX_MIX0"},
2389 {"WSA_RX0 INP0", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302390 {"WSA_RX0 INP0", "DEC0", "WSA_TX DEC0_INP"},
2391 {"WSA_RX0 INP0", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302392 {"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP0"},
2393
2394 {"WSA_RX0 INP1", "RX0", "WSA RX0"},
2395 {"WSA_RX0 INP1", "RX1", "WSA RX1"},
2396 {"WSA_RX0 INP1", "RX_MIX0", "WSA RX_MIX0"},
2397 {"WSA_RX0 INP1", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302398 {"WSA_RX0 INP1", "DEC0", "WSA_TX DEC0_INP"},
2399 {"WSA_RX0 INP1", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302400 {"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP1"},
2401
2402 {"WSA_RX0 INP2", "RX0", "WSA RX0"},
2403 {"WSA_RX0 INP2", "RX1", "WSA RX1"},
2404 {"WSA_RX0 INP2", "RX_MIX0", "WSA RX_MIX0"},
2405 {"WSA_RX0 INP2", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302406 {"WSA_RX0 INP2", "DEC0", "WSA_TX DEC0_INP"},
2407 {"WSA_RX0 INP2", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302408 {"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP2"},
2409
2410 {"WSA_RX0 MIX INP", "RX0", "WSA RX0"},
2411 {"WSA_RX0 MIX INP", "RX1", "WSA RX1"},
2412 {"WSA_RX0 MIX INP", "RX_MIX0", "WSA RX_MIX0"},
2413 {"WSA_RX0 MIX INP", "RX_MIX1", "WSA RX_MIX1"},
2414 {"WSA_RX INT0 SEC MIX", NULL, "WSA_RX0 MIX INP"},
2415
2416 {"WSA_RX INT0 SEC MIX", NULL, "WSA_RX INT0 MIX"},
2417 {"WSA_RX INT0 INTERP", NULL, "WSA_RX INT0 SEC MIX"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302418 {"WSA_RX0 INT0 SIDETONE MIX", "SRC0", "WSA SRC0_INP"},
2419 {"WSA_RX INT0 INTERP", NULL, "WSA_RX0 INT0 SIDETONE MIX"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302420 {"WSA_RX INT0 CHAIN", NULL, "WSA_RX INT0 INTERP"},
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302421
2422 {"WSA_RX INT0 VBAT", "WSA RX0 VBAT Enable", "WSA_RX INT0 INTERP"},
2423 {"WSA_RX INT0 CHAIN", NULL, "WSA_RX INT0 VBAT"},
2424
Laxminath Kasam243e2752018-04-12 00:40:19 +05302425 {"WSA_SPK1 OUT", NULL, "WSA_RX INT0 CHAIN"},
Laxminath Kasamfc281ad2018-08-06 20:19:40 +05302426 {"WSA_SPK1 OUT", NULL, "WSA_MCLK"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302427
2428 {"WSA_RX1 INP0", "RX0", "WSA RX0"},
2429 {"WSA_RX1 INP0", "RX1", "WSA RX1"},
2430 {"WSA_RX1 INP0", "RX_MIX0", "WSA RX_MIX0"},
2431 {"WSA_RX1 INP0", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302432 {"WSA_RX1 INP0", "DEC0", "WSA_TX DEC0_INP"},
2433 {"WSA_RX1 INP0", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302434 {"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP0"},
2435
2436 {"WSA_RX1 INP1", "RX0", "WSA RX0"},
2437 {"WSA_RX1 INP1", "RX1", "WSA RX1"},
2438 {"WSA_RX1 INP1", "RX_MIX0", "WSA RX_MIX0"},
2439 {"WSA_RX1 INP1", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302440 {"WSA_RX1 INP1", "DEC0", "WSA_TX DEC0_INP"},
2441 {"WSA_RX1 INP1", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302442 {"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP1"},
2443
2444 {"WSA_RX1 INP2", "RX0", "WSA RX0"},
2445 {"WSA_RX1 INP2", "RX1", "WSA RX1"},
2446 {"WSA_RX1 INP2", "RX_MIX0", "WSA RX_MIX0"},
2447 {"WSA_RX1 INP2", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302448 {"WSA_RX1 INP2", "DEC0", "WSA_TX DEC0_INP"},
2449 {"WSA_RX1 INP2", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302450 {"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP2"},
2451
2452 {"WSA_RX1 MIX INP", "RX0", "WSA RX0"},
2453 {"WSA_RX1 MIX INP", "RX1", "WSA RX1"},
2454 {"WSA_RX1 MIX INP", "RX_MIX0", "WSA RX_MIX0"},
2455 {"WSA_RX1 MIX INP", "RX_MIX1", "WSA RX_MIX1"},
2456 {"WSA_RX INT1 SEC MIX", NULL, "WSA_RX1 MIX INP"},
2457
2458 {"WSA_RX INT1 SEC MIX", NULL, "WSA_RX INT1 MIX"},
2459 {"WSA_RX INT1 INTERP", NULL, "WSA_RX INT1 SEC MIX"},
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302460
2461 {"WSA_RX INT1 VBAT", "WSA RX1 VBAT Enable", "WSA_RX INT1 INTERP"},
2462 {"WSA_RX INT1 CHAIN", NULL, "WSA_RX INT1 VBAT"},
2463
Laxminath Kasam243e2752018-04-12 00:40:19 +05302464 {"WSA_RX INT1 CHAIN", NULL, "WSA_RX INT1 INTERP"},
2465 {"WSA_SPK2 OUT", NULL, "WSA_RX INT1 CHAIN"},
Laxminath Kasamfc281ad2018-08-06 20:19:40 +05302466 {"WSA_SPK2 OUT", NULL, "WSA_MCLK"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302467};
2468
2469static const struct wsa_macro_reg_mask_val wsa_macro_reg_init[] = {
2470 {BOLERO_CDC_WSA_BOOST0_BOOST_CFG1, 0x3F, 0x12},
2471 {BOLERO_CDC_WSA_BOOST0_BOOST_CFG2, 0x1C, 0x08},
2472 {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x1E, 0x18},
2473 {BOLERO_CDC_WSA_BOOST1_BOOST_CFG1, 0x3F, 0x12},
2474 {BOLERO_CDC_WSA_BOOST1_BOOST_CFG2, 0x1C, 0x08},
2475 {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x1E, 0x18},
2476 {BOLERO_CDC_WSA_BOOST0_BOOST_CTL, 0x70, 0x58},
2477 {BOLERO_CDC_WSA_BOOST1_BOOST_CTL, 0x70, 0x58},
2478 {BOLERO_CDC_WSA_RX0_RX_PATH_CFG1, 0x08, 0x08},
2479 {BOLERO_CDC_WSA_RX1_RX_PATH_CFG1, 0x08, 0x08},
2480 {BOLERO_CDC_WSA_TOP_TOP_CFG1, 0x02, 0x02},
2481 {BOLERO_CDC_WSA_TOP_TOP_CFG1, 0x01, 0x01},
2482 {BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
2483 {BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
2484 {BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
2485 {BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
2486 {BOLERO_CDC_WSA_COMPANDER0_CTL3, 0x80, 0x80},
2487 {BOLERO_CDC_WSA_COMPANDER1_CTL3, 0x80, 0x80},
2488 {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x01, 0x01},
2489 {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x01, 0x01},
2490 {BOLERO_CDC_WSA_RX0_RX_PATH_CFG0, 0x01, 0x01},
2491 {BOLERO_CDC_WSA_RX1_RX_PATH_CFG0, 0x01, 0x01},
2492 {BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CFG, 0x01, 0x01},
2493 {BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CFG, 0x01, 0x01},
2494};
2495
Meng Wang15c825d2018-09-06 10:49:18 +08002496static void wsa_macro_init_bcl_pmic_reg(struct snd_soc_component *component)
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302497{
2498 struct device *wsa_dev = NULL;
2499 struct wsa_macro_priv *wsa_priv = NULL;
2500
Meng Wang15c825d2018-09-06 10:49:18 +08002501 if (!component) {
2502 pr_err("%s: NULL component pointer!\n", __func__);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302503 return;
2504 }
2505
Meng Wang15c825d2018-09-06 10:49:18 +08002506 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302507 return;
2508
2509 switch (wsa_priv->bcl_pmic_params.id) {
2510 case 0:
2511 /* Enable ID0 to listen to respective PMIC group interrupts */
Meng Wang15c825d2018-09-06 10:49:18 +08002512 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302513 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CTL1, 0x02, 0x02);
2514 /* Update MC_SID0 */
Meng Wang15c825d2018-09-06 10:49:18 +08002515 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302516 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG1, 0x0F,
2517 wsa_priv->bcl_pmic_params.sid);
2518 /* Update MC_PPID0 */
Meng Wang15c825d2018-09-06 10:49:18 +08002519 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302520 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG2, 0xFF,
2521 wsa_priv->bcl_pmic_params.ppid);
2522 break;
2523 case 1:
2524 /* Enable ID1 to listen to respective PMIC group interrupts */
Meng Wang15c825d2018-09-06 10:49:18 +08002525 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302526 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CTL1, 0x01, 0x01);
2527 /* Update MC_SID1 */
Meng Wang15c825d2018-09-06 10:49:18 +08002528 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302529 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG3, 0x0F,
2530 wsa_priv->bcl_pmic_params.sid);
2531 /* Update MC_PPID1 */
Meng Wang15c825d2018-09-06 10:49:18 +08002532 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302533 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG4, 0xFF,
2534 wsa_priv->bcl_pmic_params.ppid);
2535 break;
2536 default:
2537 dev_err(wsa_dev, "%s: PMIC ID is invalid %d\n",
2538 __func__, wsa_priv->bcl_pmic_params.id);
2539 break;
2540 }
2541}
2542
Meng Wang15c825d2018-09-06 10:49:18 +08002543static void wsa_macro_init_reg(struct snd_soc_component *component)
Laxminath Kasam243e2752018-04-12 00:40:19 +05302544{
2545 int i;
2546
2547 for (i = 0; i < ARRAY_SIZE(wsa_macro_reg_init); i++)
Meng Wang15c825d2018-09-06 10:49:18 +08002548 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302549 wsa_macro_reg_init[i].reg,
2550 wsa_macro_reg_init[i].mask,
2551 wsa_macro_reg_init[i].val);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302552
Meng Wang15c825d2018-09-06 10:49:18 +08002553 wsa_macro_init_bcl_pmic_reg(component);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302554}
2555
2556static int wsa_swrm_clock(void *handle, bool enable)
2557{
2558 struct wsa_macro_priv *wsa_priv = (struct wsa_macro_priv *) handle;
2559 struct regmap *regmap = dev_get_regmap(wsa_priv->dev->parent, NULL);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302560 int ret = 0;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302561
Tanya Dixitab8eba82018-10-05 15:07:37 +05302562 if (regmap == NULL) {
2563 dev_err(wsa_priv->dev, "%s: regmap is NULL\n", __func__);
2564 return -EINVAL;
2565 }
2566
Laxminath Kasam243e2752018-04-12 00:40:19 +05302567 mutex_lock(&wsa_priv->swr_clk_lock);
2568
2569 dev_dbg(wsa_priv->dev, "%s: swrm clock %s\n",
2570 __func__, (enable ? "enable" : "disable"));
2571 if (enable) {
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302572 if (wsa_priv->swr_clk_users == 0) {
Karthikeyan Mani01f1ba42019-02-26 18:48:15 -08002573 msm_cdc_pinctrl_select_active_state(
2574 wsa_priv->wsa_swr_gpio_p);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302575 ret = wsa_macro_mclk_enable(wsa_priv, 1, true);
2576 if (ret < 0) {
Karthikeyan Mani01f1ba42019-02-26 18:48:15 -08002577 msm_cdc_pinctrl_select_sleep_state(
2578 wsa_priv->wsa_swr_gpio_p);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302579 dev_err(wsa_priv->dev,
2580 "%s: wsa request clock enable failed\n",
2581 __func__);
2582 goto exit;
2583 }
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05302584 if (wsa_priv->reset_swr)
2585 regmap_update_bits(regmap,
2586 BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
2587 0x02, 0x02);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302588 regmap_update_bits(regmap,
2589 BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
2590 0x01, 0x01);
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05302591 if (wsa_priv->reset_swr)
2592 regmap_update_bits(regmap,
2593 BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
2594 0x02, 0x00);
2595 wsa_priv->reset_swr = false;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302596 }
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302597 wsa_priv->swr_clk_users++;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302598 } else {
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302599 if (wsa_priv->swr_clk_users <= 0) {
2600 dev_err(wsa_priv->dev, "%s: clock already disabled\n",
2601 __func__);
2602 wsa_priv->swr_clk_users = 0;
2603 goto exit;
2604 }
Laxminath Kasam243e2752018-04-12 00:40:19 +05302605 wsa_priv->swr_clk_users--;
2606 if (wsa_priv->swr_clk_users == 0) {
2607 regmap_update_bits(regmap,
2608 BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
2609 0x01, 0x00);
Karthikeyan Mani01f1ba42019-02-26 18:48:15 -08002610 wsa_macro_mclk_enable(wsa_priv, 0, true);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302611 msm_cdc_pinctrl_select_sleep_state(
2612 wsa_priv->wsa_swr_gpio_p);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302613 }
2614 }
2615 dev_dbg(wsa_priv->dev, "%s: swrm clock users %d\n",
2616 __func__, wsa_priv->swr_clk_users);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302617exit:
Laxminath Kasam243e2752018-04-12 00:40:19 +05302618 mutex_unlock(&wsa_priv->swr_clk_lock);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302619 return ret;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302620}
2621
Meng Wang15c825d2018-09-06 10:49:18 +08002622static int wsa_macro_init(struct snd_soc_component *component)
Laxminath Kasam243e2752018-04-12 00:40:19 +05302623{
Meng Wang15c825d2018-09-06 10:49:18 +08002624 struct snd_soc_dapm_context *dapm =
2625 snd_soc_component_get_dapm(component);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302626 int ret;
2627 struct device *wsa_dev = NULL;
2628 struct wsa_macro_priv *wsa_priv = NULL;
2629
Meng Wang15c825d2018-09-06 10:49:18 +08002630 wsa_dev = bolero_get_device_ptr(component->dev, WSA_MACRO);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302631 if (!wsa_dev) {
Meng Wang15c825d2018-09-06 10:49:18 +08002632 dev_err(component->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302633 "%s: null device for macro!\n", __func__);
2634 return -EINVAL;
2635 }
2636 wsa_priv = dev_get_drvdata(wsa_dev);
2637 if (!wsa_priv) {
Meng Wang15c825d2018-09-06 10:49:18 +08002638 dev_err(component->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302639 "%s: priv is null for macro!\n", __func__);
2640 return -EINVAL;
2641 }
2642
2643 ret = snd_soc_dapm_new_controls(dapm, wsa_macro_dapm_widgets,
2644 ARRAY_SIZE(wsa_macro_dapm_widgets));
2645 if (ret < 0) {
2646 dev_err(wsa_dev, "%s: Failed to add controls\n", __func__);
2647 return ret;
2648 }
2649
2650 ret = snd_soc_dapm_add_routes(dapm, wsa_audio_map,
2651 ARRAY_SIZE(wsa_audio_map));
2652 if (ret < 0) {
2653 dev_err(wsa_dev, "%s: Failed to add routes\n", __func__);
2654 return ret;
2655 }
2656
2657 ret = snd_soc_dapm_new_widgets(dapm->card);
2658 if (ret < 0) {
2659 dev_err(wsa_dev, "%s: Failed to add widgets\n", __func__);
2660 return ret;
2661 }
2662
Meng Wang15c825d2018-09-06 10:49:18 +08002663 ret = snd_soc_add_component_controls(component, wsa_macro_snd_controls,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302664 ARRAY_SIZE(wsa_macro_snd_controls));
2665 if (ret < 0) {
2666 dev_err(wsa_dev, "%s: Failed to add snd_ctls\n", __func__);
2667 return ret;
2668 }
Laxminath Kasam638b5602018-09-24 13:19:52 +05302669 snd_soc_dapm_ignore_suspend(dapm, "WSA_AIF1 Playback");
2670 snd_soc_dapm_ignore_suspend(dapm, "WSA_AIF_MIX1 Playback");
2671 snd_soc_dapm_ignore_suspend(dapm, "WSA_AIF_VI Capture");
2672 snd_soc_dapm_ignore_suspend(dapm, "WSA_AIF_ECHO Capture");
2673 snd_soc_dapm_ignore_suspend(dapm, "WSA_SPK1 OUT");
2674 snd_soc_dapm_ignore_suspend(dapm, "WSA_SPK2 OUT");
2675 snd_soc_dapm_ignore_suspend(dapm, "VIINPUT_WSA");
2676 snd_soc_dapm_ignore_suspend(dapm, "WSA SRC0_INP");
2677 snd_soc_dapm_ignore_suspend(dapm, "WSA_TX DEC0_INP");
2678 snd_soc_dapm_ignore_suspend(dapm, "WSA_TX DEC1_INP");
2679 snd_soc_dapm_sync(dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302680
Meng Wang15c825d2018-09-06 10:49:18 +08002681 wsa_priv->component = component;
Laxminath Kasam21c8b222018-06-21 18:47:22 +05302682 wsa_priv->spkr_gain_offset = WSA_MACRO_GAIN_OFFSET_0_DB;
Meng Wang15c825d2018-09-06 10:49:18 +08002683 wsa_macro_init_reg(component);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302684
2685 return 0;
2686}
2687
Meng Wang15c825d2018-09-06 10:49:18 +08002688static int wsa_macro_deinit(struct snd_soc_component *component)
Laxminath Kasam243e2752018-04-12 00:40:19 +05302689{
2690 struct device *wsa_dev = NULL;
2691 struct wsa_macro_priv *wsa_priv = NULL;
2692
Meng Wang15c825d2018-09-06 10:49:18 +08002693 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302694 return -EINVAL;
2695
Meng Wang15c825d2018-09-06 10:49:18 +08002696 wsa_priv->component = NULL;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302697
2698 return 0;
2699}
2700
2701static void wsa_macro_add_child_devices(struct work_struct *work)
2702{
2703 struct wsa_macro_priv *wsa_priv;
2704 struct platform_device *pdev;
2705 struct device_node *node;
2706 struct wsa_macro_swr_ctrl_data *swr_ctrl_data = NULL, *temp;
2707 int ret;
2708 u16 count = 0, ctrl_num = 0;
2709 struct wsa_macro_swr_ctrl_platform_data *platdata;
2710 char plat_dev_name[WSA_MACRO_SWR_STRING_LEN];
2711
2712 wsa_priv = container_of(work, struct wsa_macro_priv,
2713 wsa_macro_add_child_devices_work);
2714 if (!wsa_priv) {
2715 pr_err("%s: Memory for wsa_priv does not exist\n",
2716 __func__);
2717 return;
2718 }
Laxminath Kasam21c8b222018-06-21 18:47:22 +05302719 if (!wsa_priv->dev || !wsa_priv->dev->of_node) {
Laxminath Kasam243e2752018-04-12 00:40:19 +05302720 dev_err(wsa_priv->dev,
2721 "%s: DT node for wsa_priv does not exist\n", __func__);
2722 return;
2723 }
2724
2725 platdata = &wsa_priv->swr_plat_data;
2726 wsa_priv->child_count = 0;
2727
2728 for_each_available_child_of_node(wsa_priv->dev->of_node, node) {
2729 if (strnstr(node->name, "wsa_swr_master",
2730 strlen("wsa_swr_master")) != NULL)
2731 strlcpy(plat_dev_name, "wsa_swr_ctrl",
2732 (WSA_MACRO_SWR_STRING_LEN - 1));
2733 else if (strnstr(node->name, "msm_cdc_pinctrl",
2734 strlen("msm_cdc_pinctrl")) != NULL)
2735 strlcpy(plat_dev_name, node->name,
2736 (WSA_MACRO_SWR_STRING_LEN - 1));
2737 else
2738 continue;
2739
2740 pdev = platform_device_alloc(plat_dev_name, -1);
2741 if (!pdev) {
2742 dev_err(wsa_priv->dev, "%s: pdev memory alloc failed\n",
2743 __func__);
2744 ret = -ENOMEM;
2745 goto err;
2746 }
2747 pdev->dev.parent = wsa_priv->dev;
2748 pdev->dev.of_node = node;
2749
2750 if (strnstr(node->name, "wsa_swr_master",
2751 strlen("wsa_swr_master")) != NULL) {
2752 ret = platform_device_add_data(pdev, platdata,
2753 sizeof(*platdata));
2754 if (ret) {
2755 dev_err(&pdev->dev,
2756 "%s: cannot add plat data ctrl:%d\n",
2757 __func__, ctrl_num);
2758 goto fail_pdev_add;
2759 }
2760 }
2761
2762 ret = platform_device_add(pdev);
2763 if (ret) {
2764 dev_err(&pdev->dev,
2765 "%s: Cannot add platform device\n",
2766 __func__);
2767 goto fail_pdev_add;
2768 }
2769
2770 if (!strcmp(node->name, "wsa_swr_master")) {
2771 temp = krealloc(swr_ctrl_data,
2772 (ctrl_num + 1) * sizeof(
2773 struct wsa_macro_swr_ctrl_data),
2774 GFP_KERNEL);
2775 if (!temp) {
2776 dev_err(&pdev->dev, "out of memory\n");
2777 ret = -ENOMEM;
2778 goto err;
2779 }
2780 swr_ctrl_data = temp;
2781 swr_ctrl_data[ctrl_num].wsa_swr_pdev = pdev;
2782 ctrl_num++;
2783 dev_dbg(&pdev->dev,
2784 "%s: Added soundwire ctrl device(s)\n",
2785 __func__);
2786 wsa_priv->swr_ctrl_data = swr_ctrl_data;
2787 }
2788 if (wsa_priv->child_count < WSA_MACRO_CHILD_DEVICES_MAX)
2789 wsa_priv->pdev_child_devices[
2790 wsa_priv->child_count++] = pdev;
2791 else
2792 goto err;
2793 }
2794
2795 return;
2796fail_pdev_add:
2797 for (count = 0; count < wsa_priv->child_count; count++)
2798 platform_device_put(wsa_priv->pdev_child_devices[count]);
2799err:
2800 return;
2801}
2802
2803static void wsa_macro_init_ops(struct macro_ops *ops,
2804 char __iomem *wsa_io_base)
2805{
2806 memset(ops, 0, sizeof(struct macro_ops));
2807 ops->init = wsa_macro_init;
2808 ops->exit = wsa_macro_deinit;
2809 ops->io_base = wsa_io_base;
2810 ops->dai_ptr = wsa_macro_dai;
2811 ops->num_dais = ARRAY_SIZE(wsa_macro_dai);
2812 ops->mclk_fn = wsa_macro_mclk_ctrl;
Laxminath Kasamfb0d6832018-09-22 01:49:52 +05302813 ops->event_handler = wsa_macro_event_handler;
Sudheer Papothia3e969d2018-10-27 06:22:10 +05302814 ops->set_port_map = wsa_macro_set_port_map;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302815}
2816
2817static int wsa_macro_probe(struct platform_device *pdev)
2818{
2819 struct macro_ops ops;
2820 struct wsa_macro_priv *wsa_priv;
2821 u32 wsa_base_addr;
2822 char __iomem *wsa_io_base;
2823 int ret = 0;
2824 struct clk *wsa_core_clk, *wsa_npl_clk;
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302825 u8 bcl_pmic_params[3];
Laxminath Kasam243e2752018-04-12 00:40:19 +05302826
2827 wsa_priv = devm_kzalloc(&pdev->dev, sizeof(struct wsa_macro_priv),
2828 GFP_KERNEL);
2829 if (!wsa_priv)
2830 return -ENOMEM;
2831
2832 wsa_priv->dev = &pdev->dev;
2833 ret = of_property_read_u32(pdev->dev.of_node, "reg",
2834 &wsa_base_addr);
2835 if (ret) {
2836 dev_err(&pdev->dev, "%s: could not find %s entry in dt\n",
2837 __func__, "reg");
2838 return ret;
2839 }
2840 wsa_priv->wsa_swr_gpio_p = of_parse_phandle(pdev->dev.of_node,
2841 "qcom,wsa-swr-gpios", 0);
2842 if (!wsa_priv->wsa_swr_gpio_p) {
2843 dev_err(&pdev->dev, "%s: swr_gpios handle not provided!\n",
2844 __func__);
2845 return -EINVAL;
2846 }
2847 wsa_io_base = devm_ioremap(&pdev->dev,
2848 wsa_base_addr, WSA_MACRO_MAX_OFFSET);
2849 if (!wsa_io_base) {
2850 dev_err(&pdev->dev, "%s: ioremap failed\n", __func__);
2851 return -EINVAL;
2852 }
2853 wsa_priv->wsa_io_base = wsa_io_base;
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05302854 wsa_priv->reset_swr = true;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302855 INIT_WORK(&wsa_priv->wsa_macro_add_child_devices_work,
2856 wsa_macro_add_child_devices);
2857 wsa_priv->swr_plat_data.handle = (void *) wsa_priv;
2858 wsa_priv->swr_plat_data.read = NULL;
2859 wsa_priv->swr_plat_data.write = NULL;
2860 wsa_priv->swr_plat_data.bulk_write = NULL;
2861 wsa_priv->swr_plat_data.clk = wsa_swrm_clock;
2862 wsa_priv->swr_plat_data.handle_irq = NULL;
2863
2864 /* Register MCLK for wsa macro */
2865 wsa_core_clk = devm_clk_get(&pdev->dev, "wsa_core_clk");
2866 if (IS_ERR(wsa_core_clk)) {
Ramprasad Katkamf83acfb2018-08-11 23:28:57 +05302867 ret = PTR_ERR(wsa_core_clk);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302868 dev_err(&pdev->dev, "%s: clk get %s failed\n",
2869 __func__, "wsa_core_clk");
Ramprasad Katkamf83acfb2018-08-11 23:28:57 +05302870 return ret;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302871 }
2872 wsa_priv->wsa_core_clk = wsa_core_clk;
2873 /* Register npl clk for soundwire */
2874 wsa_npl_clk = devm_clk_get(&pdev->dev, "wsa_npl_clk");
2875 if (IS_ERR(wsa_npl_clk)) {
Ramprasad Katkamf83acfb2018-08-11 23:28:57 +05302876 ret = PTR_ERR(wsa_npl_clk);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302877 dev_err(&pdev->dev, "%s: clk get %s failed\n",
2878 __func__, "wsa_npl_clk");
Ramprasad Katkamf83acfb2018-08-11 23:28:57 +05302879 return ret;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302880 }
2881 wsa_priv->wsa_npl_clk = wsa_npl_clk;
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302882
2883 ret = of_property_read_u8_array(pdev->dev.of_node,
2884 "qcom,wsa-bcl-pmic-params", bcl_pmic_params,
2885 sizeof(bcl_pmic_params));
2886 if (ret) {
2887 dev_dbg(&pdev->dev, "%s: could not find %s entry in dt\n",
2888 __func__, "qcom,wsa-bcl-pmic-params");
2889 } else {
2890 wsa_priv->bcl_pmic_params.id = bcl_pmic_params[0];
2891 wsa_priv->bcl_pmic_params.sid = bcl_pmic_params[1];
2892 wsa_priv->bcl_pmic_params.ppid = bcl_pmic_params[2];
2893 }
2894
Laxminath Kasam243e2752018-04-12 00:40:19 +05302895 dev_set_drvdata(&pdev->dev, wsa_priv);
2896 mutex_init(&wsa_priv->mclk_lock);
2897 mutex_init(&wsa_priv->swr_clk_lock);
2898 wsa_macro_init_ops(&ops, wsa_io_base);
2899 ret = bolero_register_macro(&pdev->dev, WSA_MACRO, &ops);
2900 if (ret < 0) {
2901 dev_err(&pdev->dev, "%s: register macro failed\n", __func__);
2902 goto reg_macro_fail;
2903 }
2904 schedule_work(&wsa_priv->wsa_macro_add_child_devices_work);
2905 return ret;
2906reg_macro_fail:
2907 mutex_destroy(&wsa_priv->mclk_lock);
2908 mutex_destroy(&wsa_priv->swr_clk_lock);
2909 return ret;
2910}
2911
2912static int wsa_macro_remove(struct platform_device *pdev)
2913{
2914 struct wsa_macro_priv *wsa_priv;
2915 u16 count = 0;
2916
2917 wsa_priv = dev_get_drvdata(&pdev->dev);
2918
2919 if (!wsa_priv)
2920 return -EINVAL;
2921
2922 for (count = 0; count < wsa_priv->child_count &&
2923 count < WSA_MACRO_CHILD_DEVICES_MAX; count++)
2924 platform_device_unregister(wsa_priv->pdev_child_devices[count]);
2925
2926 bolero_unregister_macro(&pdev->dev, WSA_MACRO);
2927 mutex_destroy(&wsa_priv->mclk_lock);
2928 mutex_destroy(&wsa_priv->swr_clk_lock);
2929 return 0;
2930}
2931
2932static const struct of_device_id wsa_macro_dt_match[] = {
2933 {.compatible = "qcom,wsa-macro"},
2934 {}
2935};
2936
2937static struct platform_driver wsa_macro_driver = {
2938 .driver = {
2939 .name = "wsa_macro",
2940 .owner = THIS_MODULE,
2941 .of_match_table = wsa_macro_dt_match,
2942 },
2943 .probe = wsa_macro_probe,
2944 .remove = wsa_macro_remove,
2945};
2946
2947module_platform_driver(wsa_macro_driver);
2948
2949MODULE_DESCRIPTION("WSA macro driver");
2950MODULE_LICENSE("GPL v2");