blob: e0cc3e81c2ea88400e2c922ce6ff92dca15d5a37 [file] [log] [blame]
Meng Wang43bbb872018-12-10 12:32:05 +08001// SPDX-License-Identifier: GPL-2.0-only
Prasad Kumpatla71fef462020-01-31 21:38:58 +05302/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
Laxminath Kasam243e2752018-04-12 00:40:19 +05303 */
4
5#include <linux/module.h>
6#include <linux/init.h>
7#include <linux/io.h>
8#include <linux/platform_device.h>
9#include <linux/clk.h>
Sudheer Papothi7601cc62019-03-30 03:00:52 +053010#include <linux/pm_runtime.h>
Laxminath Kasam243e2752018-04-12 00:40:19 +053011#include <sound/soc.h>
12#include <sound/soc-dapm.h>
13#include <sound/tlv.h>
Sudheer Papothia3e969d2018-10-27 06:22:10 +053014#include <soc/swr-common.h>
Laxminath Kasam243e2752018-04-12 00:40:19 +053015#include <soc/swr-wcd.h>
16
Meng Wang11a25cf2018-10-31 14:11:26 +080017#include <asoc/msm-cdc-pinctrl.h>
Laxminath Kasam243e2752018-04-12 00:40:19 +053018#include "bolero-cdc.h"
19#include "bolero-cdc-registers.h"
20#include "wsa-macro.h"
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -070021#include "bolero-clk-rsc.h"
Laxminath Kasam243e2752018-04-12 00:40:19 +053022
Sudheer Papothi7601cc62019-03-30 03:00:52 +053023#define AUTO_SUSPEND_DELAY 50 /* delay in msec */
Laxminath Kasam243e2752018-04-12 00:40:19 +053024#define WSA_MACRO_MAX_OFFSET 0x1000
25
26#define WSA_MACRO_RX_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
27 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
28 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
29#define WSA_MACRO_RX_MIX_RATES (SNDRV_PCM_RATE_48000 |\
30 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
31#define WSA_MACRO_RX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
32 SNDRV_PCM_FMTBIT_S24_LE |\
33 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
34
35#define WSA_MACRO_ECHO_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
36 SNDRV_PCM_RATE_48000)
37#define WSA_MACRO_ECHO_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
38 SNDRV_PCM_FMTBIT_S24_LE |\
39 SNDRV_PCM_FMTBIT_S24_3LE)
40
41#define NUM_INTERPOLATORS 2
42
43#define WSA_MACRO_MUX_INP_SHFT 0x3
Laxminath Kasam793902c2019-12-11 18:16:52 +053044#define WSA_MACRO_MUX_INP_MASK1 0x07
Laxminath Kasam243e2752018-04-12 00:40:19 +053045#define WSA_MACRO_MUX_INP_MASK2 0x38
46#define WSA_MACRO_MUX_CFG_OFFSET 0x8
47#define WSA_MACRO_MUX_CFG1_OFFSET 0x4
48#define WSA_MACRO_RX_COMP_OFFSET 0x40
Aditya Bavanari4f3d5642018-09-18 22:19:10 +053049#define WSA_MACRO_RX_SOFTCLIP_OFFSET 0x40
Laxminath Kasam243e2752018-04-12 00:40:19 +053050#define WSA_MACRO_RX_PATH_OFFSET 0x80
51#define WSA_MACRO_RX_PATH_CFG3_OFFSET 0x10
52#define WSA_MACRO_RX_PATH_DSMDEM_OFFSET 0x4C
53#define WSA_MACRO_FS_RATE_MASK 0x0F
Laxminath Kasam5d9ea8d2018-11-28 14:32:40 +053054#define WSA_MACRO_EC_MIX_TX0_MASK 0x03
55#define WSA_MACRO_EC_MIX_TX1_MASK 0x18
56
Laxminath Kasamf8adb5f2019-08-09 21:47:33 +053057#define WSA_MACRO_MAX_DMA_CH_PER_PORT 0x2
Laxminath Kasam243e2752018-04-12 00:40:19 +053058
59enum {
60 WSA_MACRO_RX0 = 0,
61 WSA_MACRO_RX1,
62 WSA_MACRO_RX_MIX,
63 WSA_MACRO_RX_MIX0 = WSA_MACRO_RX_MIX,
64 WSA_MACRO_RX_MIX1,
65 WSA_MACRO_RX_MAX,
66};
67
68enum {
69 WSA_MACRO_TX0 = 0,
70 WSA_MACRO_TX1,
71 WSA_MACRO_TX_MAX,
72};
73
74enum {
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +053075 WSA_MACRO_EC0_MUX = 0,
76 WSA_MACRO_EC1_MUX,
77 WSA_MACRO_EC_MUX_MAX,
78};
79
80enum {
Laxminath Kasam243e2752018-04-12 00:40:19 +053081 WSA_MACRO_COMP1, /* SPK_L */
82 WSA_MACRO_COMP2, /* SPK_R */
83 WSA_MACRO_COMP_MAX
84};
85
Aditya Bavanari4f3d5642018-09-18 22:19:10 +053086enum {
87 WSA_MACRO_SOFTCLIP0, /* RX0 */
88 WSA_MACRO_SOFTCLIP1, /* RX1 */
89 WSA_MACRO_SOFTCLIP_MAX
90};
91
Laxminath Kasam52ae6582019-08-08 18:00:35 +053092enum {
93 INTn_1_INP_SEL_ZERO = 0,
94 INTn_1_INP_SEL_RX0,
95 INTn_1_INP_SEL_RX1,
96 INTn_1_INP_SEL_RX2,
97 INTn_1_INP_SEL_RX3,
98 INTn_1_INP_SEL_DEC0,
99 INTn_1_INP_SEL_DEC1,
100};
101
Laxminath Kasamf8adb5f2019-08-09 21:47:33 +0530102enum {
103 INTn_2_INP_SEL_ZERO = 0,
104 INTn_2_INP_SEL_RX0,
105 INTn_2_INP_SEL_RX1,
106 INTn_2_INP_SEL_RX2,
107 INTn_2_INP_SEL_RX3,
108};
109
Laxminath Kasam243e2752018-04-12 00:40:19 +0530110struct interp_sample_rate {
111 int sample_rate;
112 int rate_val;
113};
114
115/*
116 * Structure used to update codec
117 * register defaults after reset
118 */
119struct wsa_macro_reg_mask_val {
120 u16 reg;
121 u8 mask;
122 u8 val;
123};
124
125static struct interp_sample_rate int_prim_sample_rate_val[] = {
126 {8000, 0x0}, /* 8K */
127 {16000, 0x1}, /* 16K */
128 {24000, -EINVAL},/* 24K */
129 {32000, 0x3}, /* 32K */
130 {48000, 0x4}, /* 48K */
131 {96000, 0x5}, /* 96K */
132 {192000, 0x6}, /* 192K */
133 {384000, 0x7}, /* 384K */
134 {44100, 0x8}, /* 44.1K */
135};
136
137static struct interp_sample_rate int_mix_sample_rate_val[] = {
138 {48000, 0x4}, /* 48K */
139 {96000, 0x5}, /* 96K */
140 {192000, 0x6}, /* 192K */
141};
142
143#define WSA_MACRO_SWR_STRING_LEN 80
144
145static int wsa_macro_hw_params(struct snd_pcm_substream *substream,
146 struct snd_pcm_hw_params *params,
147 struct snd_soc_dai *dai);
148static int wsa_macro_get_channel_map(struct snd_soc_dai *dai,
149 unsigned int *tx_num, unsigned int *tx_slot,
150 unsigned int *rx_num, unsigned int *rx_slot);
Laxminath Kasam52ae6582019-08-08 18:00:35 +0530151static int wsa_macro_digital_mute(struct snd_soc_dai *dai, int mute);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530152/* Hold instance to soundwire platform device */
153struct wsa_macro_swr_ctrl_data {
154 struct platform_device *wsa_swr_pdev;
155};
156
157struct wsa_macro_swr_ctrl_platform_data {
158 void *handle; /* holds codec private data */
159 int (*read)(void *handle, int reg);
160 int (*write)(void *handle, int reg, int val);
161 int (*bulk_write)(void *handle, u32 *reg, u32 *val, size_t len);
162 int (*clk)(void *handle, bool enable);
Karthikeyan Mani8d40a062019-09-05 16:44:49 -0700163 int (*core_vote)(void *handle, bool enable);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530164 int (*handle_irq)(void *handle,
165 irqreturn_t (*swrm_irq_handler)(int irq,
166 void *data),
167 void *swrm_handle,
168 int action);
Laxminath Kasamea6cbee2020-04-28 00:02:32 +0530169 int (*pinctrl_setup)(void *handle, bool enable);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530170};
171
Aditya Bavanari4f3d5642018-09-18 22:19:10 +0530172struct wsa_macro_bcl_pmic_params {
173 u8 id;
174 u8 sid;
175 u8 ppid;
176};
177
Laxminath Kasam243e2752018-04-12 00:40:19 +0530178enum {
Laxminath Kasam59c7a1d2018-08-09 16:11:17 +0530179 WSA_MACRO_AIF_INVALID = 0,
180 WSA_MACRO_AIF1_PB,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530181 WSA_MACRO_AIF_MIX1_PB,
182 WSA_MACRO_AIF_VI,
183 WSA_MACRO_AIF_ECHO,
184 WSA_MACRO_MAX_DAIS,
185};
186
187#define WSA_MACRO_CHILD_DEVICES_MAX 3
188
189/*
190 * @dev: wsa macro device pointer
191 * @comp_enabled: compander enable mixer value set
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +0530192 * @ec_hq: echo HQ enable mixer value set
Laxminath Kasam243e2752018-04-12 00:40:19 +0530193 * @prim_int_users: Users of interpolator
194 * @wsa_mclk_users: WSA MCLK users count
195 * @swr_clk_users: SWR clk users count
196 * @vi_feed_value: VI sense mask
197 * @mclk_lock: to lock mclk operations
198 * @swr_clk_lock: to lock swr master clock operations
199 * @swr_ctrl_data: SoundWire data structure
200 * @swr_plat_data: Soundwire platform data
201 * @wsa_macro_add_child_devices_work: work for adding child devices
202 * @wsa_swr_gpio_p: used by pinctrl API
Meng Wang15c825d2018-09-06 10:49:18 +0800203 * @component: codec handle
Laxminath Kasam243e2752018-04-12 00:40:19 +0530204 * @rx_0_count: RX0 interpolation users
205 * @rx_1_count: RX1 interpolation users
206 * @active_ch_mask: channel mask for all AIF DAIs
207 * @active_ch_cnt: channel count of all AIF DAIs
208 * @rx_port_value: mixer ctl value of WSA RX MUXes
209 * @wsa_io_base: Base address of WSA macro addr space
210 */
211struct wsa_macro_priv {
212 struct device *dev;
213 int comp_enabled[WSA_MACRO_COMP_MAX];
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +0530214 int ec_hq[WSA_MACRO_RX1 + 1];
Laxminath Kasam243e2752018-04-12 00:40:19 +0530215 u16 prim_int_users[WSA_MACRO_RX1 + 1];
216 u16 wsa_mclk_users;
217 u16 swr_clk_users;
Ramprasad Katkam452772a2019-01-07 17:30:36 +0530218 bool dapm_mclk_enable;
Ramprasad Katkama4c747b2018-12-11 19:15:53 +0530219 bool reset_swr;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530220 unsigned int vi_feed_value;
221 struct mutex mclk_lock;
222 struct mutex swr_clk_lock;
223 struct wsa_macro_swr_ctrl_data *swr_ctrl_data;
224 struct wsa_macro_swr_ctrl_platform_data swr_plat_data;
225 struct work_struct wsa_macro_add_child_devices_work;
226 struct device_node *wsa_swr_gpio_p;
Meng Wang15c825d2018-09-06 10:49:18 +0800227 struct snd_soc_component *component;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530228 int rx_0_count;
229 int rx_1_count;
230 unsigned long active_ch_mask[WSA_MACRO_MAX_DAIS];
231 unsigned long active_ch_cnt[WSA_MACRO_MAX_DAIS];
232 int rx_port_value[WSA_MACRO_RX_MAX];
233 char __iomem *wsa_io_base;
234 struct platform_device *pdev_child_devices
235 [WSA_MACRO_CHILD_DEVICES_MAX];
236 int child_count;
237 int ear_spkr_gain;
238 int spkr_gain_offset;
239 int spkr_mode;
Aditya Bavanari4f3d5642018-09-18 22:19:10 +0530240 int is_softclip_on[WSA_MACRO_SOFTCLIP_MAX];
241 int softclip_clk_users[WSA_MACRO_SOFTCLIP_MAX];
242 struct wsa_macro_bcl_pmic_params bcl_pmic_params;
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -0700243 char __iomem *mclk_mode_muxsel;
244 u16 default_clk_id;
Laxminath Kasam007d2522020-04-23 11:00:44 +0530245 u32 pcm_rate_vi;
Vatsal Buchaf2a71b62019-03-26 16:14:40 +0530246 int wsa_digital_mute_status[WSA_MACRO_RX_MAX];
Laxminath Kasam243e2752018-04-12 00:40:19 +0530247};
248
Meng Wang15c825d2018-09-06 10:49:18 +0800249static int wsa_macro_config_ear_spkr_gain(struct snd_soc_component *component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530250 struct wsa_macro_priv *wsa_priv,
251 int event, int gain_reg);
252static struct snd_soc_dai_driver wsa_macro_dai[];
253static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0);
254
255static const char *const rx_text[] = {
256 "ZERO", "RX0", "RX1", "RX_MIX0", "RX_MIX1", "DEC0", "DEC1"
257};
258
259static const char *const rx_mix_text[] = {
260 "ZERO", "RX0", "RX1", "RX_MIX0", "RX_MIX1"
261};
262
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +0530263static const char *const rx_mix_ec_text[] = {
264 "ZERO", "RX_MIX_TX0", "RX_MIX_TX1"
265};
266
Laxminath Kasam243e2752018-04-12 00:40:19 +0530267static const char *const rx_mux_text[] = {
268 "ZERO", "AIF1_PB", "AIF_MIX1_PB"
269};
270
Laxminath Kasam6fc2e742018-08-26 23:32:57 +0530271static const char *const rx_sidetone_mix_text[] = {
272 "ZERO", "SRC0"
273};
274
Laxminath Kasam243e2752018-04-12 00:40:19 +0530275static const char * const wsa_macro_ear_spkr_pa_gain_text[] = {
276 "G_DEFAULT", "G_0_DB", "G_1_DB", "G_2_DB", "G_3_DB",
277 "G_4_DB", "G_5_DB", "G_6_DB"
278};
279
280static const char * const wsa_macro_speaker_boost_stage_text[] = {
281 "NO_MAX_STATE", "MAX_STATE_1", "MAX_STATE_2"
282};
283
Aditya Bavanari4f3d5642018-09-18 22:19:10 +0530284static const char * const wsa_macro_vbat_bcl_gsm_mode_text[] = {
285 "OFF", "ON"
286};
287
288static const struct snd_kcontrol_new wsa_int0_vbat_mix_switch[] = {
289 SOC_DAPM_SINGLE("WSA RX0 VBAT Enable", SND_SOC_NOPM, 0, 1, 0)
290};
291
292static const struct snd_kcontrol_new wsa_int1_vbat_mix_switch[] = {
293 SOC_DAPM_SINGLE("WSA RX1 VBAT Enable", SND_SOC_NOPM, 0, 1, 0)
294};
295
Laxminath Kasam243e2752018-04-12 00:40:19 +0530296static SOC_ENUM_SINGLE_EXT_DECL(wsa_macro_ear_spkr_pa_gain_enum,
297 wsa_macro_ear_spkr_pa_gain_text);
298static SOC_ENUM_SINGLE_EXT_DECL(wsa_macro_spkr_boost_stage_enum,
299 wsa_macro_speaker_boost_stage_text);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +0530300static SOC_ENUM_SINGLE_EXT_DECL(wsa_macro_vbat_bcl_gsm_mode_enum,
301 wsa_macro_vbat_bcl_gsm_mode_text);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530302
303/* RX INT0 */
304static const struct soc_enum rx0_prim_inp0_chain_enum =
305 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0,
306 0, 7, rx_text);
307
308static const struct soc_enum rx0_prim_inp1_chain_enum =
309 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0,
310 3, 7, rx_text);
311
312static const struct soc_enum rx0_prim_inp2_chain_enum =
313 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG1,
314 3, 7, rx_text);
315
316static const struct soc_enum rx0_mix_chain_enum =
317 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG1,
318 0, 5, rx_mix_text);
319
Laxminath Kasam6fc2e742018-08-26 23:32:57 +0530320static const struct soc_enum rx0_sidetone_mix_enum =
321 SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, 2, rx_sidetone_mix_text);
322
Laxminath Kasam243e2752018-04-12 00:40:19 +0530323static const struct snd_kcontrol_new rx0_prim_inp0_mux =
324 SOC_DAPM_ENUM("WSA_RX0 INP0 Mux", rx0_prim_inp0_chain_enum);
325
326static const struct snd_kcontrol_new rx0_prim_inp1_mux =
327 SOC_DAPM_ENUM("WSA_RX0 INP1 Mux", rx0_prim_inp1_chain_enum);
328
329static const struct snd_kcontrol_new rx0_prim_inp2_mux =
330 SOC_DAPM_ENUM("WSA_RX0 INP2 Mux", rx0_prim_inp2_chain_enum);
331
332static const struct snd_kcontrol_new rx0_mix_mux =
333 SOC_DAPM_ENUM("WSA_RX0 MIX Mux", rx0_mix_chain_enum);
334
Laxminath Kasam6fc2e742018-08-26 23:32:57 +0530335static const struct snd_kcontrol_new rx0_sidetone_mix_mux =
336 SOC_DAPM_ENUM("WSA_RX0 SIDETONE MIX Mux", rx0_sidetone_mix_enum);
337
Laxminath Kasam243e2752018-04-12 00:40:19 +0530338/* RX INT1 */
339static const struct soc_enum rx1_prim_inp0_chain_enum =
340 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT1_CFG0,
341 0, 7, rx_text);
342
343static const struct soc_enum rx1_prim_inp1_chain_enum =
344 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT1_CFG0,
345 3, 7, rx_text);
346
347static const struct soc_enum rx1_prim_inp2_chain_enum =
348 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT1_CFG1,
349 3, 7, rx_text);
350
351static const struct soc_enum rx1_mix_chain_enum =
352 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT1_CFG1,
353 0, 5, rx_mix_text);
354
355static const struct snd_kcontrol_new rx1_prim_inp0_mux =
356 SOC_DAPM_ENUM("WSA_RX1 INP0 Mux", rx1_prim_inp0_chain_enum);
357
358static const struct snd_kcontrol_new rx1_prim_inp1_mux =
359 SOC_DAPM_ENUM("WSA_RX1 INP1 Mux", rx1_prim_inp1_chain_enum);
360
361static const struct snd_kcontrol_new rx1_prim_inp2_mux =
362 SOC_DAPM_ENUM("WSA_RX1 INP2 Mux", rx1_prim_inp2_chain_enum);
363
364static const struct snd_kcontrol_new rx1_mix_mux =
365 SOC_DAPM_ENUM("WSA_RX1 MIX Mux", rx1_mix_chain_enum);
366
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +0530367static const struct soc_enum rx_mix_ec0_enum =
368 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0,
369 0, 3, rx_mix_ec_text);
370
371static const struct soc_enum rx_mix_ec1_enum =
372 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0,
373 3, 3, rx_mix_ec_text);
374
375static const struct snd_kcontrol_new rx_mix_ec0_mux =
376 SOC_DAPM_ENUM("WSA RX_MIX EC0_Mux", rx_mix_ec0_enum);
377
378static const struct snd_kcontrol_new rx_mix_ec1_mux =
379 SOC_DAPM_ENUM("WSA RX_MIX EC1_Mux", rx_mix_ec1_enum);
380
Laxminath Kasam243e2752018-04-12 00:40:19 +0530381static struct snd_soc_dai_ops wsa_macro_dai_ops = {
382 .hw_params = wsa_macro_hw_params,
383 .get_channel_map = wsa_macro_get_channel_map,
Laxminath Kasam52ae6582019-08-08 18:00:35 +0530384 .digital_mute = wsa_macro_digital_mute,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530385};
386
387static struct snd_soc_dai_driver wsa_macro_dai[] = {
388 {
389 .name = "wsa_macro_rx1",
390 .id = WSA_MACRO_AIF1_PB,
391 .playback = {
392 .stream_name = "WSA_AIF1 Playback",
393 .rates = WSA_MACRO_RX_RATES,
394 .formats = WSA_MACRO_RX_FORMATS,
395 .rate_max = 384000,
396 .rate_min = 8000,
397 .channels_min = 1,
398 .channels_max = 2,
399 },
400 .ops = &wsa_macro_dai_ops,
401 },
402 {
403 .name = "wsa_macro_rx_mix",
404 .id = WSA_MACRO_AIF_MIX1_PB,
405 .playback = {
406 .stream_name = "WSA_AIF_MIX1 Playback",
407 .rates = WSA_MACRO_RX_MIX_RATES,
408 .formats = WSA_MACRO_RX_FORMATS,
409 .rate_max = 192000,
410 .rate_min = 48000,
411 .channels_min = 1,
412 .channels_max = 2,
413 },
414 .ops = &wsa_macro_dai_ops,
415 },
416 {
417 .name = "wsa_macro_vifeedback",
418 .id = WSA_MACRO_AIF_VI,
419 .capture = {
420 .stream_name = "WSA_AIF_VI Capture",
Vatsal Buchad1b694d2018-08-31 11:47:32 +0530421 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000,
422 .formats = WSA_MACRO_RX_FORMATS,
423 .rate_max = 48000,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530424 .rate_min = 8000,
425 .channels_min = 1,
Vatsal Buchad1b694d2018-08-31 11:47:32 +0530426 .channels_max = 4,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530427 },
428 .ops = &wsa_macro_dai_ops,
429 },
430 {
431 .name = "wsa_macro_echo",
432 .id = WSA_MACRO_AIF_ECHO,
433 .capture = {
434 .stream_name = "WSA_AIF_ECHO Capture",
435 .rates = WSA_MACRO_ECHO_RATES,
436 .formats = WSA_MACRO_ECHO_FORMATS,
437 .rate_max = 48000,
438 .rate_min = 8000,
439 .channels_min = 1,
440 .channels_max = 2,
441 },
442 .ops = &wsa_macro_dai_ops,
443 },
444};
445
446static const struct wsa_macro_reg_mask_val wsa_macro_spkr_default[] = {
447 {BOLERO_CDC_WSA_COMPANDER0_CTL3, 0x80, 0x80},
448 {BOLERO_CDC_WSA_COMPANDER1_CTL3, 0x80, 0x80},
449 {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x01, 0x01},
450 {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x01, 0x01},
451 {BOLERO_CDC_WSA_BOOST0_BOOST_CTL, 0x7C, 0x58},
452 {BOLERO_CDC_WSA_BOOST1_BOOST_CTL, 0x7C, 0x58},
453};
454
455static const struct wsa_macro_reg_mask_val wsa_macro_spkr_mode1[] = {
456 {BOLERO_CDC_WSA_COMPANDER0_CTL3, 0x80, 0x00},
457 {BOLERO_CDC_WSA_COMPANDER1_CTL3, 0x80, 0x00},
458 {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x01, 0x00},
459 {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x01, 0x00},
460 {BOLERO_CDC_WSA_BOOST0_BOOST_CTL, 0x7C, 0x44},
461 {BOLERO_CDC_WSA_BOOST1_BOOST_CTL, 0x7C, 0x44},
462};
463
Meng Wang15c825d2018-09-06 10:49:18 +0800464static bool wsa_macro_get_data(struct snd_soc_component *component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530465 struct device **wsa_dev,
466 struct wsa_macro_priv **wsa_priv,
467 const char *func_name)
468{
Meng Wang15c825d2018-09-06 10:49:18 +0800469 *wsa_dev = bolero_get_device_ptr(component->dev, WSA_MACRO);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530470 if (!(*wsa_dev)) {
Meng Wang15c825d2018-09-06 10:49:18 +0800471 dev_err(component->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530472 "%s: null device for macro!\n", func_name);
473 return false;
474 }
475 *wsa_priv = dev_get_drvdata((*wsa_dev));
Meng Wang15c825d2018-09-06 10:49:18 +0800476 if (!(*wsa_priv) || !(*wsa_priv)->component) {
477 dev_err(component->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530478 "%s: priv is null for macro!\n", func_name);
479 return false;
480 }
481 return true;
482}
483
Sudheer Papothia3e969d2018-10-27 06:22:10 +0530484static int wsa_macro_set_port_map(struct snd_soc_component *component,
485 u32 usecase, u32 size, void *data)
486{
487 struct device *wsa_dev = NULL;
488 struct wsa_macro_priv *wsa_priv = NULL;
489 struct swrm_port_config port_cfg;
490 int ret = 0;
491
492 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
493 return -EINVAL;
494
495 memset(&port_cfg, 0, sizeof(port_cfg));
496 port_cfg.uc = usecase;
497 port_cfg.size = size;
498 port_cfg.params = data;
499
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -0700500 if (wsa_priv->swr_ctrl_data)
501 ret = swrm_wcd_notify(
502 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
503 SWR_SET_PORT_MAP, &port_cfg);
Sudheer Papothia3e969d2018-10-27 06:22:10 +0530504
505 return ret;
506}
507
Laxminath Kasam243e2752018-04-12 00:40:19 +0530508/**
509 * wsa_macro_set_spkr_gain_offset - offset the speaker path
510 * gain with the given offset value.
511 *
Meng Wang15c825d2018-09-06 10:49:18 +0800512 * @component: codec instance
Laxminath Kasam243e2752018-04-12 00:40:19 +0530513 * @offset: Indicates speaker path gain offset value.
514 *
515 * Returns 0 on success or -EINVAL on error.
516 */
Meng Wang15c825d2018-09-06 10:49:18 +0800517int wsa_macro_set_spkr_gain_offset(struct snd_soc_component *component,
518 int offset)
Laxminath Kasam243e2752018-04-12 00:40:19 +0530519{
520 struct device *wsa_dev = NULL;
521 struct wsa_macro_priv *wsa_priv = NULL;
522
Meng Wang15c825d2018-09-06 10:49:18 +0800523 if (!component) {
524 pr_err("%s: NULL component pointer!\n", __func__);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530525 return -EINVAL;
526 }
527
Meng Wang15c825d2018-09-06 10:49:18 +0800528 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530529 return -EINVAL;
530
531 wsa_priv->spkr_gain_offset = offset;
532 return 0;
533}
534EXPORT_SYMBOL(wsa_macro_set_spkr_gain_offset);
535
536/**
537 * wsa_macro_set_spkr_mode - Configures speaker compander and smartboost
538 * settings based on speaker mode.
539 *
Meng Wang15c825d2018-09-06 10:49:18 +0800540 * @component: codec instance
Laxminath Kasam243e2752018-04-12 00:40:19 +0530541 * @mode: Indicates speaker configuration mode.
542 *
543 * Returns 0 on success or -EINVAL on error.
544 */
Meng Wang15c825d2018-09-06 10:49:18 +0800545int wsa_macro_set_spkr_mode(struct snd_soc_component *component, int mode)
Laxminath Kasam243e2752018-04-12 00:40:19 +0530546{
547 int i;
548 const struct wsa_macro_reg_mask_val *regs;
549 int size;
550 struct device *wsa_dev = NULL;
551 struct wsa_macro_priv *wsa_priv = NULL;
552
Meng Wang15c825d2018-09-06 10:49:18 +0800553 if (!component) {
Laxminath Kasam243e2752018-04-12 00:40:19 +0530554 pr_err("%s: NULL codec pointer!\n", __func__);
555 return -EINVAL;
556 }
557
Meng Wang15c825d2018-09-06 10:49:18 +0800558 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530559 return -EINVAL;
560
561 switch (mode) {
Laxminath Kasam21c8b222018-06-21 18:47:22 +0530562 case WSA_MACRO_SPKR_MODE_1:
Laxminath Kasam243e2752018-04-12 00:40:19 +0530563 regs = wsa_macro_spkr_mode1;
564 size = ARRAY_SIZE(wsa_macro_spkr_mode1);
565 break;
566 default:
567 regs = wsa_macro_spkr_default;
568 size = ARRAY_SIZE(wsa_macro_spkr_default);
569 break;
570 }
571
572 wsa_priv->spkr_mode = mode;
573 for (i = 0; i < size; i++)
Meng Wang15c825d2018-09-06 10:49:18 +0800574 snd_soc_component_update_bits(component, regs[i].reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530575 regs[i].mask, regs[i].val);
576 return 0;
577}
578EXPORT_SYMBOL(wsa_macro_set_spkr_mode);
579
580static int wsa_macro_set_prim_interpolator_rate(struct snd_soc_dai *dai,
581 u8 int_prim_fs_rate_reg_val,
582 u32 sample_rate)
583{
584 u8 int_1_mix1_inp;
585 u32 j, port;
586 u16 int_mux_cfg0, int_mux_cfg1;
587 u16 int_fs_reg;
588 u8 int_mux_cfg0_val, int_mux_cfg1_val;
589 u8 inp0_sel, inp1_sel, inp2_sel;
Meng Wang15c825d2018-09-06 10:49:18 +0800590 struct snd_soc_component *component = dai->component;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530591 struct device *wsa_dev = NULL;
592 struct wsa_macro_priv *wsa_priv = NULL;
593
Meng Wang15c825d2018-09-06 10:49:18 +0800594 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530595 return -EINVAL;
596
597 for_each_set_bit(port, &wsa_priv->active_ch_mask[dai->id],
598 WSA_MACRO_RX_MAX) {
599 int_1_mix1_inp = port;
600 if ((int_1_mix1_inp < WSA_MACRO_RX0) ||
601 (int_1_mix1_inp > WSA_MACRO_RX_MIX1)) {
602 dev_err(wsa_dev,
603 "%s: Invalid RX port, Dai ID is %d\n",
604 __func__, dai->id);
605 return -EINVAL;
606 }
607
608 int_mux_cfg0 = BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0;
609
610 /*
611 * Loop through all interpolator MUX inputs and find out
612 * to which interpolator input, the cdc_dma rx port
613 * is connected
614 */
615 for (j = 0; j < NUM_INTERPOLATORS; j++) {
616 int_mux_cfg1 = int_mux_cfg0 + WSA_MACRO_MUX_CFG1_OFFSET;
617
Meng Wang15c825d2018-09-06 10:49:18 +0800618 int_mux_cfg0_val = snd_soc_component_read32(component,
619 int_mux_cfg0);
620 int_mux_cfg1_val = snd_soc_component_read32(component,
621 int_mux_cfg1);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530622 inp0_sel = int_mux_cfg0_val & WSA_MACRO_MUX_INP_MASK1;
623 inp1_sel = (int_mux_cfg0_val >>
624 WSA_MACRO_MUX_INP_SHFT) &
Laxminath Kasam793902c2019-12-11 18:16:52 +0530625 WSA_MACRO_MUX_INP_MASK1;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530626 inp2_sel = (int_mux_cfg1_val >>
627 WSA_MACRO_MUX_INP_SHFT) &
Laxminath Kasam793902c2019-12-11 18:16:52 +0530628 WSA_MACRO_MUX_INP_MASK1;
Laxminath Kasamf8adb5f2019-08-09 21:47:33 +0530629 if ((inp0_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0) ||
630 (inp1_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0) ||
631 (inp2_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0)) {
Laxminath Kasam243e2752018-04-12 00:40:19 +0530632 int_fs_reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL +
633 WSA_MACRO_RX_PATH_OFFSET * j;
634 dev_dbg(wsa_dev,
635 "%s: AIF_PB DAI(%d) connected to INT%u_1\n",
636 __func__, dai->id, j);
637 dev_dbg(wsa_dev,
638 "%s: set INT%u_1 sample rate to %u\n",
639 __func__, j, sample_rate);
640 /* sample_rate is in Hz */
Meng Wang15c825d2018-09-06 10:49:18 +0800641 snd_soc_component_update_bits(component,
642 int_fs_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530643 WSA_MACRO_FS_RATE_MASK,
644 int_prim_fs_rate_reg_val);
645 }
646 int_mux_cfg0 += WSA_MACRO_MUX_CFG_OFFSET;
647 }
648 }
649
650 return 0;
651}
652
653static int wsa_macro_set_mix_interpolator_rate(struct snd_soc_dai *dai,
654 u8 int_mix_fs_rate_reg_val,
655 u32 sample_rate)
656{
657 u8 int_2_inp;
658 u32 j, port;
659 u16 int_mux_cfg1, int_fs_reg;
660 u8 int_mux_cfg1_val;
Meng Wang15c825d2018-09-06 10:49:18 +0800661 struct snd_soc_component *component = dai->component;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530662 struct device *wsa_dev = NULL;
663 struct wsa_macro_priv *wsa_priv = NULL;
664
Meng Wang15c825d2018-09-06 10:49:18 +0800665 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530666 return -EINVAL;
667
668
669 for_each_set_bit(port, &wsa_priv->active_ch_mask[dai->id],
670 WSA_MACRO_RX_MAX) {
671 int_2_inp = port;
672 if ((int_2_inp < WSA_MACRO_RX0) ||
673 (int_2_inp > WSA_MACRO_RX_MIX1)) {
674 dev_err(wsa_dev,
675 "%s: Invalid RX port, Dai ID is %d\n",
676 __func__, dai->id);
677 return -EINVAL;
678 }
679
680 int_mux_cfg1 = BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG1;
681 for (j = 0; j < NUM_INTERPOLATORS; j++) {
Meng Wang15c825d2018-09-06 10:49:18 +0800682 int_mux_cfg1_val = snd_soc_component_read32(component,
683 int_mux_cfg1) &
Laxminath Kasam243e2752018-04-12 00:40:19 +0530684 WSA_MACRO_MUX_INP_MASK1;
Laxminath Kasamf8adb5f2019-08-09 21:47:33 +0530685 if (int_mux_cfg1_val == int_2_inp +
686 INTn_2_INP_SEL_RX0) {
Laxminath Kasam243e2752018-04-12 00:40:19 +0530687 int_fs_reg =
688 BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL +
689 WSA_MACRO_RX_PATH_OFFSET * j;
690
691 dev_dbg(wsa_dev,
692 "%s: AIF_PB DAI(%d) connected to INT%u_2\n",
693 __func__, dai->id, j);
694 dev_dbg(wsa_dev,
695 "%s: set INT%u_2 sample rate to %u\n",
696 __func__, j, sample_rate);
Meng Wang15c825d2018-09-06 10:49:18 +0800697 snd_soc_component_update_bits(component,
698 int_fs_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530699 WSA_MACRO_FS_RATE_MASK,
700 int_mix_fs_rate_reg_val);
701 }
702 int_mux_cfg1 += WSA_MACRO_MUX_CFG_OFFSET;
703 }
704 }
705 return 0;
706}
707
708static int wsa_macro_set_interpolator_rate(struct snd_soc_dai *dai,
709 u32 sample_rate)
710{
711 int rate_val = 0;
712 int i, ret;
713
714 /* set mixing path rate */
715 for (i = 0; i < ARRAY_SIZE(int_mix_sample_rate_val); i++) {
716 if (sample_rate ==
717 int_mix_sample_rate_val[i].sample_rate) {
718 rate_val =
719 int_mix_sample_rate_val[i].rate_val;
720 break;
721 }
722 }
723 if ((i == ARRAY_SIZE(int_mix_sample_rate_val)) ||
724 (rate_val < 0))
725 goto prim_rate;
726 ret = wsa_macro_set_mix_interpolator_rate(dai,
727 (u8) rate_val, sample_rate);
728prim_rate:
729 /* set primary path sample rate */
730 for (i = 0; i < ARRAY_SIZE(int_prim_sample_rate_val); i++) {
731 if (sample_rate ==
732 int_prim_sample_rate_val[i].sample_rate) {
733 rate_val =
734 int_prim_sample_rate_val[i].rate_val;
735 break;
736 }
737 }
738 if ((i == ARRAY_SIZE(int_prim_sample_rate_val)) ||
739 (rate_val < 0))
740 return -EINVAL;
741 ret = wsa_macro_set_prim_interpolator_rate(dai,
742 (u8) rate_val, sample_rate);
743 return ret;
744}
745
746static int wsa_macro_hw_params(struct snd_pcm_substream *substream,
747 struct snd_pcm_hw_params *params,
748 struct snd_soc_dai *dai)
749{
Meng Wang15c825d2018-09-06 10:49:18 +0800750 struct snd_soc_component *component = dai->component;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530751 int ret;
Laxminath Kasam007d2522020-04-23 11:00:44 +0530752 struct device *wsa_dev = NULL;
753 struct wsa_macro_priv *wsa_priv = NULL;
754
755 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
756 return -EINVAL;
757
758 wsa_priv = dev_get_drvdata(wsa_dev);
759 if (!wsa_priv)
760 return -EINVAL;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530761
Meng Wang15c825d2018-09-06 10:49:18 +0800762 dev_dbg(component->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530763 "%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__,
764 dai->name, dai->id, params_rate(params),
765 params_channels(params));
766
767 switch (substream->stream) {
768 case SNDRV_PCM_STREAM_PLAYBACK:
769 ret = wsa_macro_set_interpolator_rate(dai, params_rate(params));
770 if (ret) {
Meng Wang15c825d2018-09-06 10:49:18 +0800771 dev_err(component->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530772 "%s: cannot set sample rate: %u\n",
773 __func__, params_rate(params));
774 return ret;
775 }
776 break;
777 case SNDRV_PCM_STREAM_CAPTURE:
Laxminath Kasam007d2522020-04-23 11:00:44 +0530778 if (dai->id == WSA_MACRO_AIF_VI)
779 wsa_priv->pcm_rate_vi = params_rate(params);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530780 default:
781 break;
782 }
783 return 0;
784}
785
786static int wsa_macro_get_channel_map(struct snd_soc_dai *dai,
787 unsigned int *tx_num, unsigned int *tx_slot,
788 unsigned int *rx_num, unsigned int *rx_slot)
789{
Meng Wang15c825d2018-09-06 10:49:18 +0800790 struct snd_soc_component *component = dai->component;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530791 struct device *wsa_dev = NULL;
792 struct wsa_macro_priv *wsa_priv = NULL;
Laxminath Kasamf8adb5f2019-08-09 21:47:33 +0530793 u16 val = 0, mask = 0, cnt = 0, temp = 0;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530794
Meng Wang15c825d2018-09-06 10:49:18 +0800795 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530796 return -EINVAL;
797
798 wsa_priv = dev_get_drvdata(wsa_dev);
799 if (!wsa_priv)
800 return -EINVAL;
801
802 switch (dai->id) {
803 case WSA_MACRO_AIF_VI:
Laxminath Kasam243e2752018-04-12 00:40:19 +0530804 *tx_slot = wsa_priv->active_ch_mask[dai->id];
805 *tx_num = wsa_priv->active_ch_cnt[dai->id];
806 break;
807 case WSA_MACRO_AIF1_PB:
808 case WSA_MACRO_AIF_MIX1_PB:
Laxminath Kasamf8adb5f2019-08-09 21:47:33 +0530809 for_each_set_bit(temp, &wsa_priv->active_ch_mask[dai->id],
810 WSA_MACRO_RX_MAX) {
811 mask |= (1 << temp);
812 if (++cnt == WSA_MACRO_MAX_DMA_CH_PER_PORT)
813 break;
814 }
815 if (mask & 0x0C)
816 mask = mask >> 0x2;
817 *rx_slot = mask;
818 *rx_num = cnt;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530819 break;
Laxminath Kasam5d9ea8d2018-11-28 14:32:40 +0530820 case WSA_MACRO_AIF_ECHO:
821 val = snd_soc_component_read32(component,
822 BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0);
823 if (val & WSA_MACRO_EC_MIX_TX1_MASK) {
824 mask |= 0x2;
825 cnt++;
826 }
827 if (val & WSA_MACRO_EC_MIX_TX0_MASK) {
828 mask |= 0x1;
829 cnt++;
830 }
831 *tx_slot = mask;
832 *tx_num = cnt;
833 break;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530834 default:
835 dev_err(wsa_dev, "%s: Invalid AIF\n", __func__);
836 break;
837 }
838 return 0;
839}
840
Laxminath Kasam52ae6582019-08-08 18:00:35 +0530841static int wsa_macro_digital_mute(struct snd_soc_dai *dai, int mute)
842{
843 struct snd_soc_component *component = dai->component;
844 struct device *wsa_dev = NULL;
845 struct wsa_macro_priv *wsa_priv = NULL;
846 uint16_t j = 0, reg = 0, mix_reg = 0, dsm_reg = 0;
847 u16 int_mux_cfg0 = 0, int_mux_cfg1 = 0;
848 u8 int_mux_cfg0_val = 0, int_mux_cfg1_val = 0;
849
850 if (mute)
851 return 0;
852
853 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
854 return -EINVAL;
855
856 switch (dai->id) {
857 case WSA_MACRO_AIF1_PB:
858 case WSA_MACRO_AIF_MIX1_PB:
859 for (j = 0; j < NUM_INTERPOLATORS; j++) {
860 reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL +
861 (j * WSA_MACRO_RX_PATH_OFFSET);
862 mix_reg = BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL +
863 (j * WSA_MACRO_RX_PATH_OFFSET);
864 dsm_reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL +
865 (j * WSA_MACRO_RX_PATH_OFFSET) +
866 WSA_MACRO_RX_PATH_DSMDEM_OFFSET;
867 int_mux_cfg0 = BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0 + j * 8;
868 int_mux_cfg1 = int_mux_cfg0 + 4;
869 int_mux_cfg0_val = snd_soc_component_read32(component,
870 int_mux_cfg0);
871 int_mux_cfg1_val = snd_soc_component_read32(component,
872 int_mux_cfg1);
873 if (snd_soc_component_read32(component, dsm_reg) & 0x01) {
874 if (int_mux_cfg0_val || (int_mux_cfg1_val & 0x38))
875 snd_soc_component_update_bits(component, reg,
876 0x20, 0x20);
Laxminath Kasamf8adb5f2019-08-09 21:47:33 +0530877 if (int_mux_cfg1_val & 0x07) {
878 snd_soc_component_update_bits(component, reg,
879 0x20, 0x20);
Laxminath Kasam52ae6582019-08-08 18:00:35 +0530880 snd_soc_component_update_bits(component,
881 mix_reg, 0x20, 0x20);
Laxminath Kasamf8adb5f2019-08-09 21:47:33 +0530882 }
Laxminath Kasam52ae6582019-08-08 18:00:35 +0530883 }
884 }
Laxminath Kasam069df142019-09-17 23:43:34 +0530885 bolero_wsa_pa_on(wsa_dev);
Laxminath Kasam52ae6582019-08-08 18:00:35 +0530886 break;
887 default:
888 break;
889 }
890 return 0;
891}
Laxminath Kasam243e2752018-04-12 00:40:19 +0530892static int wsa_macro_mclk_enable(struct wsa_macro_priv *wsa_priv,
893 bool mclk_enable, bool dapm)
894{
895 struct regmap *regmap = dev_get_regmap(wsa_priv->dev->parent, NULL);
896 int ret = 0;
897
Tanya Dixitab8eba82018-10-05 15:07:37 +0530898 if (regmap == NULL) {
899 dev_err(wsa_priv->dev, "%s: regmap is NULL\n", __func__);
900 return -EINVAL;
901 }
902
Laxminath Kasam243e2752018-04-12 00:40:19 +0530903 dev_dbg(wsa_priv->dev, "%s: mclk_enable = %u, dapm = %d clk_users= %d\n",
904 __func__, mclk_enable, dapm, wsa_priv->wsa_mclk_users);
905
906 mutex_lock(&wsa_priv->mclk_lock);
907 if (mclk_enable) {
Aditya Bavanaric496ed22018-11-16 15:50:40 +0530908 if (wsa_priv->wsa_mclk_users == 0) {
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -0700909 ret = bolero_clk_rsc_request_clock(wsa_priv->dev,
910 wsa_priv->default_clk_id,
911 wsa_priv->default_clk_id,
912 true);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530913 if (ret < 0) {
Ramprasad Katkam14efed62019-03-07 13:16:50 +0530914 dev_err_ratelimited(wsa_priv->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530915 "%s: wsa request clock enable failed\n",
916 __func__);
917 goto exit;
918 }
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -0700919 bolero_clk_rsc_fs_gen_request(wsa_priv->dev,
920 true);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530921 regcache_mark_dirty(regmap);
922 regcache_sync_region(regmap,
923 WSA_START_OFFSET,
924 WSA_MAX_OFFSET);
925 /* 9.6MHz MCLK, set value 0x00 if other frequency */
926 regmap_update_bits(regmap,
927 BOLERO_CDC_WSA_TOP_FREQ_MCLK, 0x01, 0x01);
928 regmap_update_bits(regmap,
929 BOLERO_CDC_WSA_CLK_RST_CTRL_MCLK_CONTROL,
930 0x01, 0x01);
931 regmap_update_bits(regmap,
932 BOLERO_CDC_WSA_CLK_RST_CTRL_FS_CNT_CONTROL,
933 0x01, 0x01);
934 }
Aditya Bavanaric496ed22018-11-16 15:50:40 +0530935 wsa_priv->wsa_mclk_users++;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530936 } else {
Aditya Bavanaric496ed22018-11-16 15:50:40 +0530937 if (wsa_priv->wsa_mclk_users <= 0) {
938 dev_err(wsa_priv->dev, "%s: clock already disabled\n",
939 __func__);
940 wsa_priv->wsa_mclk_users = 0;
941 goto exit;
942 }
Laxminath Kasam243e2752018-04-12 00:40:19 +0530943 wsa_priv->wsa_mclk_users--;
944 if (wsa_priv->wsa_mclk_users == 0) {
945 regmap_update_bits(regmap,
946 BOLERO_CDC_WSA_CLK_RST_CTRL_FS_CNT_CONTROL,
947 0x01, 0x00);
948 regmap_update_bits(regmap,
949 BOLERO_CDC_WSA_CLK_RST_CTRL_MCLK_CONTROL,
950 0x01, 0x00);
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -0700951 bolero_clk_rsc_fs_gen_request(wsa_priv->dev,
952 false);
953
954 bolero_clk_rsc_request_clock(wsa_priv->dev,
955 wsa_priv->default_clk_id,
956 wsa_priv->default_clk_id,
957 false);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530958 }
959 }
960exit:
961 mutex_unlock(&wsa_priv->mclk_lock);
962 return ret;
963}
964
965static int wsa_macro_mclk_event(struct snd_soc_dapm_widget *w,
966 struct snd_kcontrol *kcontrol, int event)
967{
Meng Wang15c825d2018-09-06 10:49:18 +0800968 struct snd_soc_component *component =
969 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530970 int ret = 0;
971 struct device *wsa_dev = NULL;
972 struct wsa_macro_priv *wsa_priv = NULL;
973
Meng Wang15c825d2018-09-06 10:49:18 +0800974 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530975 return -EINVAL;
976
977 dev_dbg(wsa_dev, "%s: event = %d\n", __func__, event);
978 switch (event) {
979 case SND_SOC_DAPM_PRE_PMU:
980 ret = wsa_macro_mclk_enable(wsa_priv, 1, true);
Ramprasad Katkam452772a2019-01-07 17:30:36 +0530981 if (ret)
982 wsa_priv->dapm_mclk_enable = false;
983 else
984 wsa_priv->dapm_mclk_enable = true;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530985 break;
986 case SND_SOC_DAPM_POST_PMD:
Ramprasad Katkam452772a2019-01-07 17:30:36 +0530987 if (wsa_priv->dapm_mclk_enable)
988 wsa_macro_mclk_enable(wsa_priv, 0, true);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530989 break;
990 default:
991 dev_err(wsa_priv->dev,
992 "%s: invalid DAPM event %d\n", __func__, event);
993 ret = -EINVAL;
994 }
995 return ret;
996}
997
Meng Wang15c825d2018-09-06 10:49:18 +0800998static int wsa_macro_event_handler(struct snd_soc_component *component,
999 u16 event, u32 data)
Laxminath Kasamfb0d6832018-09-22 01:49:52 +05301000{
1001 struct device *wsa_dev = NULL;
1002 struct wsa_macro_priv *wsa_priv = NULL;
Meng Wangbd930242019-06-25 09:39:48 +08001003 int ret = 0;
Laxminath Kasamfb0d6832018-09-22 01:49:52 +05301004
Meng Wang15c825d2018-09-06 10:49:18 +08001005 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasamfb0d6832018-09-22 01:49:52 +05301006 return -EINVAL;
1007
1008 switch (event) {
1009 case BOLERO_MACRO_EVT_SSR_DOWN:
Aditya Bavanarif500a1d2019-09-16 18:27:51 -07001010 trace_printk("%s, enter SSR down\n", __func__);
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07001011 if (wsa_priv->swr_ctrl_data) {
1012 swrm_wcd_notify(
1013 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07001014 SWR_DEVICE_SSR_DOWN, NULL);
1015 }
Aditya Bavanari50ef13e2019-08-09 15:14:43 +05301016 if ((!pm_runtime_enabled(wsa_dev) ||
1017 !pm_runtime_suspended(wsa_dev))) {
1018 ret = bolero_runtime_suspend(wsa_dev);
1019 if (!ret) {
1020 pm_runtime_disable(wsa_dev);
1021 pm_runtime_set_suspended(wsa_dev);
1022 pm_runtime_enable(wsa_dev);
1023 }
1024 }
Laxminath Kasamfb0d6832018-09-22 01:49:52 +05301025 break;
1026 case BOLERO_MACRO_EVT_SSR_UP:
Aditya Bavanarif500a1d2019-09-16 18:27:51 -07001027 trace_printk("%s, enter SSR up\n", __func__);
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05301028 /* reset swr after ssr/pdr */
1029 wsa_priv->reset_swr = true;
Meng Wangbd930242019-06-25 09:39:48 +08001030 /* enable&disable WSA_CORE_CLK to reset GFMUX reg */
1031 ret = bolero_clk_rsc_request_clock(wsa_priv->dev,
1032 wsa_priv->default_clk_id,
1033 WSA_CORE_CLK, true);
1034 if (ret < 0)
1035 dev_err_ratelimited(wsa_priv->dev,
1036 "%s, failed to enable clk, ret:%d\n",
1037 __func__, ret);
1038 else
1039 bolero_clk_rsc_request_clock(wsa_priv->dev,
1040 wsa_priv->default_clk_id,
1041 WSA_CORE_CLK, false);
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07001042 if (wsa_priv->swr_ctrl_data)
1043 swrm_wcd_notify(
1044 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
1045 SWR_DEVICE_SSR_UP, NULL);
Laxminath Kasamfb0d6832018-09-22 01:49:52 +05301046 break;
Meng Wang8ef0cc22019-05-08 15:12:56 +08001047 case BOLERO_MACRO_EVT_CLK_RESET:
1048 bolero_rsc_clk_reset(wsa_dev, WSA_CORE_CLK);
1049 break;
Laxminath Kasamfb0d6832018-09-22 01:49:52 +05301050 }
1051 return 0;
1052}
1053
Laxminath Kasam243e2752018-04-12 00:40:19 +05301054static int wsa_macro_enable_vi_feedback(struct snd_soc_dapm_widget *w,
1055 struct snd_kcontrol *kcontrol,
1056 int event)
1057{
Meng Wang15c825d2018-09-06 10:49:18 +08001058 struct snd_soc_component *component =
1059 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301060 struct device *wsa_dev = NULL;
1061 struct wsa_macro_priv *wsa_priv = NULL;
Laxminath Kasam007d2522020-04-23 11:00:44 +05301062 u8 val = 0x0;
Laxminath Kasam243e2752018-04-12 00:40:19 +05301063
Meng Wang15c825d2018-09-06 10:49:18 +08001064 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301065 return -EINVAL;
1066
Laxminath Kasam007d2522020-04-23 11:00:44 +05301067 switch (wsa_priv->pcm_rate_vi) {
1068 case 48000:
1069 val = 0x04;
1070 break;
1071 case 24000:
1072 val = 0x02;
1073 break;
1074 case 8000:
1075 default:
1076 val = 0x00;
1077 break;
1078 }
1079
Laxminath Kasam243e2752018-04-12 00:40:19 +05301080 switch (event) {
1081 case SND_SOC_DAPM_POST_PMU:
1082 if (test_bit(WSA_MACRO_TX0,
1083 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
1084 dev_dbg(wsa_dev, "%s: spkr1 enabled\n", __func__);
1085 /* Enable V&I sensing */
Meng Wang15c825d2018-09-06 10:49:18 +08001086 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301087 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
1088 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08001089 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301090 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
1091 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08001092 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301093 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
Laxminath Kasam007d2522020-04-23 11:00:44 +05301094 0x0F, val);
Meng Wang15c825d2018-09-06 10:49:18 +08001095 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301096 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
Laxminath Kasam007d2522020-04-23 11:00:44 +05301097 0x0F, val);
Meng Wang15c825d2018-09-06 10:49:18 +08001098 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301099 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
1100 0x10, 0x10);
Meng Wang15c825d2018-09-06 10:49:18 +08001101 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301102 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
1103 0x10, 0x10);
Meng Wang15c825d2018-09-06 10:49:18 +08001104 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301105 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
1106 0x20, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001107 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301108 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
1109 0x20, 0x00);
1110 }
1111 if (test_bit(WSA_MACRO_TX1,
1112 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
1113 dev_dbg(wsa_dev, "%s: spkr2 enabled\n", __func__);
1114 /* Enable V&I sensing */
Meng Wang15c825d2018-09-06 10:49:18 +08001115 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301116 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
1117 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08001118 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301119 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
1120 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08001121 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301122 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
Laxminath Kasam007d2522020-04-23 11:00:44 +05301123 0x0F, val);
Meng Wang15c825d2018-09-06 10:49:18 +08001124 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301125 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
Laxminath Kasam007d2522020-04-23 11:00:44 +05301126 0x0F, val);
Meng Wang15c825d2018-09-06 10:49:18 +08001127 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301128 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
1129 0x10, 0x10);
Meng Wang15c825d2018-09-06 10:49:18 +08001130 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301131 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
1132 0x10, 0x10);
Meng Wang15c825d2018-09-06 10:49:18 +08001133 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301134 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
1135 0x20, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001136 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301137 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
1138 0x20, 0x00);
1139 }
1140 break;
1141 case SND_SOC_DAPM_POST_PMD:
1142 if (test_bit(WSA_MACRO_TX0,
1143 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
1144 /* Disable V&I sensing */
Meng Wang15c825d2018-09-06 10:49:18 +08001145 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301146 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
1147 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08001148 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301149 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
1150 0x20, 0x20);
1151 dev_dbg(wsa_dev, "%s: spkr1 disabled\n", __func__);
Meng Wang15c825d2018-09-06 10:49:18 +08001152 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301153 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
1154 0x10, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001155 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301156 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
1157 0x10, 0x00);
1158 }
1159 if (test_bit(WSA_MACRO_TX1,
1160 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
1161 /* Disable V&I sensing */
1162 dev_dbg(wsa_dev, "%s: spkr2 disabled\n", __func__);
Meng Wang15c825d2018-09-06 10:49:18 +08001163 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301164 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
1165 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08001166 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301167 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
1168 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08001169 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301170 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
1171 0x10, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001172 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301173 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
1174 0x10, 0x00);
1175 }
1176 break;
1177 }
1178
1179 return 0;
1180}
1181
Meng Wang15c825d2018-09-06 10:49:18 +08001182static void wsa_macro_hd2_control(struct snd_soc_component *component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301183 u16 reg, int event)
1184{
1185 u16 hd2_scale_reg;
1186 u16 hd2_enable_reg = 0;
1187
1188 if (reg == BOLERO_CDC_WSA_RX0_RX_PATH_CTL) {
1189 hd2_scale_reg = BOLERO_CDC_WSA_RX0_RX_PATH_SEC3;
1190 hd2_enable_reg = BOLERO_CDC_WSA_RX0_RX_PATH_CFG0;
1191 }
1192 if (reg == BOLERO_CDC_WSA_RX1_RX_PATH_CTL) {
1193 hd2_scale_reg = BOLERO_CDC_WSA_RX1_RX_PATH_SEC3;
1194 hd2_enable_reg = BOLERO_CDC_WSA_RX1_RX_PATH_CFG0;
1195 }
1196
1197 if (hd2_enable_reg && SND_SOC_DAPM_EVENT_ON(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001198 snd_soc_component_update_bits(component, hd2_scale_reg,
1199 0x3C, 0x10);
1200 snd_soc_component_update_bits(component, hd2_scale_reg,
1201 0x03, 0x01);
1202 snd_soc_component_update_bits(component, hd2_enable_reg,
1203 0x04, 0x04);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301204 }
1205
1206 if (hd2_enable_reg && SND_SOC_DAPM_EVENT_OFF(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001207 snd_soc_component_update_bits(component, hd2_enable_reg,
1208 0x04, 0x00);
1209 snd_soc_component_update_bits(component, hd2_scale_reg,
1210 0x03, 0x00);
1211 snd_soc_component_update_bits(component, hd2_scale_reg,
1212 0x3C, 0x00);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301213 }
1214}
1215
1216static int wsa_macro_enable_swr(struct snd_soc_dapm_widget *w,
1217 struct snd_kcontrol *kcontrol, int event)
1218{
Meng Wang15c825d2018-09-06 10:49:18 +08001219 struct snd_soc_component *component =
1220 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301221 int ch_cnt;
1222 struct device *wsa_dev = NULL;
1223 struct wsa_macro_priv *wsa_priv = NULL;
1224
Meng Wang15c825d2018-09-06 10:49:18 +08001225 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301226 return -EINVAL;
1227
1228 switch (event) {
1229 case SND_SOC_DAPM_PRE_PMU:
1230 if (!(strnstr(w->name, "RX0", sizeof("WSA_RX0"))) &&
1231 !wsa_priv->rx_0_count)
1232 wsa_priv->rx_0_count++;
1233 if (!(strnstr(w->name, "RX1", sizeof("WSA_RX1"))) &&
1234 !wsa_priv->rx_1_count)
1235 wsa_priv->rx_1_count++;
1236 ch_cnt = wsa_priv->rx_0_count + wsa_priv->rx_1_count;
1237
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07001238 if (wsa_priv->swr_ctrl_data) {
1239 swrm_wcd_notify(
1240 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
1241 SWR_DEVICE_UP, NULL);
1242 swrm_wcd_notify(
1243 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
1244 SWR_SET_NUM_RX_CH, &ch_cnt);
1245 }
Laxminath Kasam243e2752018-04-12 00:40:19 +05301246 break;
1247 case SND_SOC_DAPM_POST_PMD:
1248 if (!(strnstr(w->name, "RX0", sizeof("WSA_RX0"))) &&
1249 wsa_priv->rx_0_count)
1250 wsa_priv->rx_0_count--;
1251 if (!(strnstr(w->name, "RX1", sizeof("WSA_RX1"))) &&
1252 wsa_priv->rx_1_count)
1253 wsa_priv->rx_1_count--;
1254 ch_cnt = wsa_priv->rx_0_count + wsa_priv->rx_1_count;
1255
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07001256 if (wsa_priv->swr_ctrl_data)
1257 swrm_wcd_notify(
1258 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
1259 SWR_SET_NUM_RX_CH, &ch_cnt);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301260 break;
1261 }
1262 dev_dbg(wsa_priv->dev, "%s: current swr ch cnt: %d\n",
1263 __func__, wsa_priv->rx_0_count + wsa_priv->rx_1_count);
1264
1265 return 0;
1266}
1267
Laxminath Kasam01d2eb22020-05-13 18:44:49 +05301268static int wsa_macro_enable_mix_path(struct snd_soc_dapm_widget *w,
1269 struct snd_kcontrol *kcontrol, int event)
1270{
1271 struct snd_soc_component *component =
1272 snd_soc_dapm_to_component(w->dapm);
1273 u16 gain_reg;
1274 int offset_val = 0;
1275 int val = 0;
1276
1277 dev_dbg(component->dev, "%s %d %s\n", __func__, event, w->name);
1278
1279 if (!(strcmp(w->name, "WSA_RX0 MIX INP"))) {
1280 gain_reg = BOLERO_CDC_WSA_RX0_RX_VOL_MIX_CTL;
1281 } else if (!(strcmp(w->name, "WSA_RX1 MIX INP"))) {
1282 gain_reg = BOLERO_CDC_WSA_RX1_RX_VOL_MIX_CTL;
1283 } else {
1284 dev_err(component->dev, "%s: No gain register avail for %s\n",
1285 __func__, w->name);
1286 return 0;
1287 }
1288
1289 switch (event) {
1290 case SND_SOC_DAPM_PRE_PMU:
1291 wsa_macro_enable_swr(w, kcontrol, event);
1292 val = snd_soc_component_read32(component, gain_reg);
1293 val += offset_val;
1294 snd_soc_component_write(component, gain_reg, val);
1295 break;
1296 case SND_SOC_DAPM_POST_PMD:
1297 snd_soc_component_update_bits(component,
1298 w->reg, 0x20, 0x00);
1299 wsa_macro_enable_swr(w, kcontrol, event);
1300 break;
1301 }
1302
1303 return 0;
1304}
1305
Meng Wang15c825d2018-09-06 10:49:18 +08001306static int wsa_macro_config_compander(struct snd_soc_component *component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301307 int comp, int event)
1308{
1309 u16 comp_ctl0_reg, rx_path_cfg0_reg;
1310 struct device *wsa_dev = NULL;
1311 struct wsa_macro_priv *wsa_priv = NULL;
1312
Meng Wang15c825d2018-09-06 10:49:18 +08001313 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301314 return -EINVAL;
1315
Meng Wang15c825d2018-09-06 10:49:18 +08001316 dev_dbg(component->dev, "%s: event %d compander %d, enabled %d\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301317 __func__, event, comp + 1, wsa_priv->comp_enabled[comp]);
1318
1319 if (!wsa_priv->comp_enabled[comp])
1320 return 0;
1321
1322 comp_ctl0_reg = BOLERO_CDC_WSA_COMPANDER0_CTL0 +
1323 (comp * WSA_MACRO_RX_COMP_OFFSET);
1324 rx_path_cfg0_reg = BOLERO_CDC_WSA_RX0_RX_PATH_CFG0 +
1325 (comp * WSA_MACRO_RX_PATH_OFFSET);
1326
1327 if (SND_SOC_DAPM_EVENT_ON(event)) {
1328 /* Enable Compander Clock */
Meng Wang15c825d2018-09-06 10:49:18 +08001329 snd_soc_component_update_bits(component, comp_ctl0_reg,
1330 0x01, 0x01);
1331 snd_soc_component_update_bits(component, comp_ctl0_reg,
1332 0x02, 0x02);
1333 snd_soc_component_update_bits(component, comp_ctl0_reg,
1334 0x02, 0x00);
1335 snd_soc_component_update_bits(component, rx_path_cfg0_reg,
1336 0x02, 0x02);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301337 }
1338
1339 if (SND_SOC_DAPM_EVENT_OFF(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001340 snd_soc_component_update_bits(component, comp_ctl0_reg,
1341 0x04, 0x04);
1342 snd_soc_component_update_bits(component, rx_path_cfg0_reg,
1343 0x02, 0x00);
1344 snd_soc_component_update_bits(component, comp_ctl0_reg,
1345 0x02, 0x02);
1346 snd_soc_component_update_bits(component, comp_ctl0_reg,
1347 0x02, 0x00);
1348 snd_soc_component_update_bits(component, comp_ctl0_reg,
1349 0x01, 0x00);
1350 snd_soc_component_update_bits(component, comp_ctl0_reg,
1351 0x04, 0x00);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301352 }
1353
1354 return 0;
1355}
1356
Meng Wang15c825d2018-09-06 10:49:18 +08001357static void wsa_macro_enable_softclip_clk(struct snd_soc_component *component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301358 struct wsa_macro_priv *wsa_priv,
1359 int path,
1360 bool enable)
1361{
1362 u16 softclip_clk_reg = BOLERO_CDC_WSA_SOFTCLIP0_CRC +
1363 (path * WSA_MACRO_RX_SOFTCLIP_OFFSET);
1364 u8 softclip_mux_mask = (1 << path);
1365 u8 softclip_mux_value = (1 << path);
1366
Meng Wang15c825d2018-09-06 10:49:18 +08001367 dev_dbg(component->dev, "%s: path %d, enable %d\n",
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301368 __func__, path, enable);
1369 if (enable) {
1370 if (wsa_priv->softclip_clk_users[path] == 0) {
Meng Wang15c825d2018-09-06 10:49:18 +08001371 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301372 softclip_clk_reg, 0x01, 0x01);
Meng Wang15c825d2018-09-06 10:49:18 +08001373 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301374 BOLERO_CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0,
1375 softclip_mux_mask, softclip_mux_value);
1376 }
1377 wsa_priv->softclip_clk_users[path]++;
1378 } else {
1379 wsa_priv->softclip_clk_users[path]--;
1380 if (wsa_priv->softclip_clk_users[path] == 0) {
Meng Wang15c825d2018-09-06 10:49:18 +08001381 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301382 softclip_clk_reg, 0x01, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001383 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301384 BOLERO_CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0,
1385 softclip_mux_mask, 0x00);
1386 }
1387 }
1388}
1389
Meng Wang15c825d2018-09-06 10:49:18 +08001390static int wsa_macro_config_softclip(struct snd_soc_component *component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301391 int path, int event)
1392{
1393 u16 softclip_ctrl_reg = 0;
1394 struct device *wsa_dev = NULL;
1395 struct wsa_macro_priv *wsa_priv = NULL;
1396 int softclip_path = 0;
1397
Meng Wang15c825d2018-09-06 10:49:18 +08001398 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301399 return -EINVAL;
1400
1401 if (path == WSA_MACRO_COMP1)
1402 softclip_path = WSA_MACRO_SOFTCLIP0;
1403 else if (path == WSA_MACRO_COMP2)
1404 softclip_path = WSA_MACRO_SOFTCLIP1;
1405
Meng Wang15c825d2018-09-06 10:49:18 +08001406 dev_dbg(component->dev, "%s: event %d path %d, enabled %d\n",
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301407 __func__, event, softclip_path,
1408 wsa_priv->is_softclip_on[softclip_path]);
1409
1410 if (!wsa_priv->is_softclip_on[softclip_path])
1411 return 0;
1412
1413 softclip_ctrl_reg = BOLERO_CDC_WSA_SOFTCLIP0_SOFTCLIP_CTRL +
1414 (softclip_path * WSA_MACRO_RX_SOFTCLIP_OFFSET);
1415
1416 if (SND_SOC_DAPM_EVENT_ON(event)) {
1417 /* Enable Softclip clock and mux */
Meng Wang15c825d2018-09-06 10:49:18 +08001418 wsa_macro_enable_softclip_clk(component, wsa_priv,
1419 softclip_path, true);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301420 /* Enable Softclip control */
Meng Wang15c825d2018-09-06 10:49:18 +08001421 snd_soc_component_update_bits(component, softclip_ctrl_reg,
1422 0x01, 0x01);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301423 }
1424
1425 if (SND_SOC_DAPM_EVENT_OFF(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001426 snd_soc_component_update_bits(component, softclip_ctrl_reg,
1427 0x01, 0x00);
1428 wsa_macro_enable_softclip_clk(component, wsa_priv,
1429 softclip_path, false);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301430 }
1431
1432 return 0;
1433}
1434
Laxminath Kasam52ae6582019-08-08 18:00:35 +05301435static bool wsa_macro_adie_lb(struct snd_soc_component *component,
1436 int interp_idx)
1437{
1438 u16 int_mux_cfg0 = 0, int_mux_cfg1 = 0;
1439 u8 int_mux_cfg0_val = 0, int_mux_cfg1_val = 0;
1440 u8 int_n_inp0 = 0, int_n_inp1 = 0, int_n_inp2 = 0;
1441
1442 int_mux_cfg0 = BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0 + interp_idx * 8;
1443 int_mux_cfg1 = int_mux_cfg0 + 4;
1444 int_mux_cfg0_val = snd_soc_component_read32(component, int_mux_cfg0);
1445 int_mux_cfg1_val = snd_soc_component_read32(component, int_mux_cfg1);
1446
1447 int_n_inp0 = int_mux_cfg0_val & 0x0F;
1448 if (int_n_inp0 == INTn_1_INP_SEL_DEC0 ||
1449 int_n_inp0 == INTn_1_INP_SEL_DEC1)
1450 return true;
1451
1452 int_n_inp1 = int_mux_cfg0_val >> 4;
1453 if (int_n_inp1 == INTn_1_INP_SEL_DEC0 ||
1454 int_n_inp1 == INTn_1_INP_SEL_DEC1)
1455 return true;
1456
1457 int_n_inp2 = int_mux_cfg1_val >> 4;
1458 if (int_n_inp2 == INTn_1_INP_SEL_DEC0 ||
1459 int_n_inp2 == INTn_1_INP_SEL_DEC1)
1460 return true;
1461
1462 return false;
1463}
1464
1465static int wsa_macro_enable_main_path(struct snd_soc_dapm_widget *w,
1466 struct snd_kcontrol *kcontrol,
1467 int event)
1468{
1469 struct snd_soc_component *component =
1470 snd_soc_dapm_to_component(w->dapm);
1471 u16 reg = 0;
Laxminath Kasam069df142019-09-17 23:43:34 +05301472 struct device *wsa_dev = NULL;
1473 struct wsa_macro_priv *wsa_priv = NULL;
1474
1475 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
1476 return -EINVAL;
1477
Laxminath Kasam52ae6582019-08-08 18:00:35 +05301478
1479 reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL +
1480 WSA_MACRO_RX_PATH_OFFSET * w->shift;
1481 switch (event) {
1482 case SND_SOC_DAPM_PRE_PMU:
Laxminath Kasam069df142019-09-17 23:43:34 +05301483 if (wsa_macro_adie_lb(component, w->shift)) {
Laxminath Kasam52ae6582019-08-08 18:00:35 +05301484 snd_soc_component_update_bits(component,
1485 reg, 0x20, 0x20);
Laxminath Kasam069df142019-09-17 23:43:34 +05301486 bolero_wsa_pa_on(wsa_dev);
1487 }
Laxminath Kasam52ae6582019-08-08 18:00:35 +05301488 break;
1489 default:
1490 break;
1491 }
1492 return 0;
1493}
1494
Laxminath Kasam243e2752018-04-12 00:40:19 +05301495static int wsa_macro_interp_get_primary_reg(u16 reg, u16 *ind)
1496{
1497 u16 prim_int_reg = 0;
1498
1499 switch (reg) {
1500 case BOLERO_CDC_WSA_RX0_RX_PATH_CTL:
1501 case BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL:
1502 prim_int_reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL;
1503 *ind = 0;
1504 break;
1505 case BOLERO_CDC_WSA_RX1_RX_PATH_CTL:
1506 case BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL:
1507 prim_int_reg = BOLERO_CDC_WSA_RX1_RX_PATH_CTL;
1508 *ind = 1;
1509 break;
1510 }
1511
1512 return prim_int_reg;
1513}
1514
1515static int wsa_macro_enable_prim_interpolator(
Meng Wang15c825d2018-09-06 10:49:18 +08001516 struct snd_soc_component *component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301517 u16 reg, int event)
1518{
1519 u16 prim_int_reg;
1520 u16 ind = 0;
1521 struct device *wsa_dev = NULL;
1522 struct wsa_macro_priv *wsa_priv = NULL;
1523
Meng Wang15c825d2018-09-06 10:49:18 +08001524 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301525 return -EINVAL;
1526
1527 prim_int_reg = wsa_macro_interp_get_primary_reg(reg, &ind);
1528
1529 switch (event) {
1530 case SND_SOC_DAPM_PRE_PMU:
1531 wsa_priv->prim_int_users[ind]++;
1532 if (wsa_priv->prim_int_users[ind] == 1) {
Meng Wang15c825d2018-09-06 10:49:18 +08001533 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301534 prim_int_reg + WSA_MACRO_RX_PATH_CFG3_OFFSET,
1535 0x03, 0x03);
Meng Wang15c825d2018-09-06 10:49:18 +08001536 snd_soc_component_update_bits(component, prim_int_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301537 0x10, 0x10);
Meng Wang15c825d2018-09-06 10:49:18 +08001538 wsa_macro_hd2_control(component, prim_int_reg, event);
1539 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301540 prim_int_reg + WSA_MACRO_RX_PATH_DSMDEM_OFFSET,
1541 0x1, 0x1);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301542 }
1543 if ((reg != prim_int_reg) &&
Meng Wang15c825d2018-09-06 10:49:18 +08001544 ((snd_soc_component_read32(
1545 component, prim_int_reg)) & 0x10))
1546 snd_soc_component_update_bits(component, reg,
1547 0x10, 0x10);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301548 break;
1549 case SND_SOC_DAPM_POST_PMD:
1550 wsa_priv->prim_int_users[ind]--;
1551 if (wsa_priv->prim_int_users[ind] == 0) {
Meng Wang15c825d2018-09-06 10:49:18 +08001552 snd_soc_component_update_bits(component, prim_int_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301553 1 << 0x5, 0 << 0x5);
Laxminath Kasam52ae6582019-08-08 18:00:35 +05301554 snd_soc_component_update_bits(component,
1555 prim_int_reg + WSA_MACRO_RX_PATH_DSMDEM_OFFSET,
1556 0x1, 0x0);
Meng Wang15c825d2018-09-06 10:49:18 +08001557 snd_soc_component_update_bits(component, prim_int_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301558 0x40, 0x40);
Meng Wang15c825d2018-09-06 10:49:18 +08001559 snd_soc_component_update_bits(component, prim_int_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301560 0x40, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001561 wsa_macro_hd2_control(component, prim_int_reg, event);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301562 }
1563 break;
1564 }
1565
Meng Wang15c825d2018-09-06 10:49:18 +08001566 dev_dbg(component->dev, "%s: primary interpolator: INT%d, users: %d\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301567 __func__, ind, wsa_priv->prim_int_users[ind]);
1568 return 0;
1569}
1570
1571static int wsa_macro_enable_interpolator(struct snd_soc_dapm_widget *w,
1572 struct snd_kcontrol *kcontrol,
1573 int event)
1574{
Meng Wang15c825d2018-09-06 10:49:18 +08001575 struct snd_soc_component *component =
1576 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301577 u16 gain_reg;
1578 u16 reg;
1579 int val;
1580 int offset_val = 0;
1581 struct device *wsa_dev = NULL;
1582 struct wsa_macro_priv *wsa_priv = NULL;
1583
Meng Wang15c825d2018-09-06 10:49:18 +08001584 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301585 return -EINVAL;
1586
Meng Wang15c825d2018-09-06 10:49:18 +08001587 dev_dbg(component->dev, "%s %d %s\n", __func__, event, w->name);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301588
1589 if (!(strcmp(w->name, "WSA_RX INT0 INTERP"))) {
1590 reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL;
1591 gain_reg = BOLERO_CDC_WSA_RX0_RX_VOL_CTL;
1592 } else if (!(strcmp(w->name, "WSA_RX INT1 INTERP"))) {
1593 reg = BOLERO_CDC_WSA_RX1_RX_PATH_CTL;
1594 gain_reg = BOLERO_CDC_WSA_RX1_RX_VOL_CTL;
1595 } else {
Meng Wang15c825d2018-09-06 10:49:18 +08001596 dev_err(component->dev, "%s: Interpolator reg not found\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301597 __func__);
1598 return -EINVAL;
1599 }
1600
1601 switch (event) {
1602 case SND_SOC_DAPM_PRE_PMU:
1603 /* Reset if needed */
Meng Wang15c825d2018-09-06 10:49:18 +08001604 wsa_macro_enable_prim_interpolator(component, reg, event);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301605 break;
1606 case SND_SOC_DAPM_POST_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08001607 wsa_macro_config_compander(component, w->shift, event);
1608 wsa_macro_config_softclip(component, w->shift, event);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301609 /* apply gain after int clk is enabled */
Laxminath Kasam21c8b222018-06-21 18:47:22 +05301610 if ((wsa_priv->spkr_gain_offset ==
1611 WSA_MACRO_GAIN_OFFSET_M1P5_DB) &&
Laxminath Kasam243e2752018-04-12 00:40:19 +05301612 (wsa_priv->comp_enabled[WSA_MACRO_COMP1] ||
1613 wsa_priv->comp_enabled[WSA_MACRO_COMP2]) &&
1614 (gain_reg == BOLERO_CDC_WSA_RX0_RX_VOL_CTL ||
1615 gain_reg == BOLERO_CDC_WSA_RX1_RX_VOL_CTL)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001616 snd_soc_component_update_bits(component,
1617 BOLERO_CDC_WSA_RX0_RX_PATH_SEC1,
1618 0x01, 0x01);
1619 snd_soc_component_update_bits(component,
1620 BOLERO_CDC_WSA_RX0_RX_PATH_MIX_SEC0,
1621 0x01, 0x01);
1622 snd_soc_component_update_bits(component,
1623 BOLERO_CDC_WSA_RX1_RX_PATH_SEC1,
1624 0x01, 0x01);
1625 snd_soc_component_update_bits(component,
1626 BOLERO_CDC_WSA_RX1_RX_PATH_MIX_SEC0,
1627 0x01, 0x01);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301628 offset_val = -2;
1629 }
Meng Wang15c825d2018-09-06 10:49:18 +08001630 val = snd_soc_component_read32(component, gain_reg);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301631 val += offset_val;
Meng Wang15c825d2018-09-06 10:49:18 +08001632 snd_soc_component_write(component, gain_reg, val);
1633 wsa_macro_config_ear_spkr_gain(component, wsa_priv,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301634 event, gain_reg);
1635 break;
1636 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +08001637 wsa_macro_config_compander(component, w->shift, event);
1638 wsa_macro_config_softclip(component, w->shift, event);
1639 wsa_macro_enable_prim_interpolator(component, reg, event);
Laxminath Kasam21c8b222018-06-21 18:47:22 +05301640 if ((wsa_priv->spkr_gain_offset ==
1641 WSA_MACRO_GAIN_OFFSET_M1P5_DB) &&
Laxminath Kasam243e2752018-04-12 00:40:19 +05301642 (wsa_priv->comp_enabled[WSA_MACRO_COMP1] ||
1643 wsa_priv->comp_enabled[WSA_MACRO_COMP2]) &&
1644 (gain_reg == BOLERO_CDC_WSA_RX0_RX_VOL_CTL ||
1645 gain_reg == BOLERO_CDC_WSA_RX1_RX_VOL_CTL)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001646 snd_soc_component_update_bits(component,
1647 BOLERO_CDC_WSA_RX0_RX_PATH_SEC1,
1648 0x01, 0x00);
1649 snd_soc_component_update_bits(component,
1650 BOLERO_CDC_WSA_RX0_RX_PATH_MIX_SEC0,
1651 0x01, 0x00);
1652 snd_soc_component_update_bits(component,
1653 BOLERO_CDC_WSA_RX1_RX_PATH_SEC1,
1654 0x01, 0x00);
1655 snd_soc_component_update_bits(component,
1656 BOLERO_CDC_WSA_RX1_RX_PATH_MIX_SEC0,
1657 0x01, 0x00);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301658 offset_val = 2;
Meng Wang15c825d2018-09-06 10:49:18 +08001659 val = snd_soc_component_read32(component, gain_reg);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301660 val += offset_val;
Meng Wang15c825d2018-09-06 10:49:18 +08001661 snd_soc_component_write(component, gain_reg, val);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301662 }
Meng Wang15c825d2018-09-06 10:49:18 +08001663 wsa_macro_config_ear_spkr_gain(component, wsa_priv,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301664 event, gain_reg);
1665 break;
1666 }
1667
1668 return 0;
1669}
1670
Meng Wang15c825d2018-09-06 10:49:18 +08001671static int wsa_macro_config_ear_spkr_gain(struct snd_soc_component *component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301672 struct wsa_macro_priv *wsa_priv,
1673 int event, int gain_reg)
1674{
1675 int comp_gain_offset, val;
1676
1677 switch (wsa_priv->spkr_mode) {
Laxminath Kasam21c8b222018-06-21 18:47:22 +05301678 /* Compander gain in WSA_MACRO_SPKR_MODE1 case is 12 dB */
1679 case WSA_MACRO_SPKR_MODE_1:
Laxminath Kasam243e2752018-04-12 00:40:19 +05301680 comp_gain_offset = -12;
1681 break;
1682 /* Default case compander gain is 15 dB */
1683 default:
1684 comp_gain_offset = -15;
1685 break;
1686 }
1687
1688 switch (event) {
1689 case SND_SOC_DAPM_POST_PMU:
1690 /* Apply ear spkr gain only if compander is enabled */
1691 if (wsa_priv->comp_enabled[WSA_MACRO_COMP1] &&
1692 (gain_reg == BOLERO_CDC_WSA_RX0_RX_VOL_CTL) &&
1693 (wsa_priv->ear_spkr_gain != 0)) {
1694 /* For example, val is -8(-12+5-1) for 4dB of gain */
1695 val = comp_gain_offset + wsa_priv->ear_spkr_gain - 1;
Meng Wang15c825d2018-09-06 10:49:18 +08001696 snd_soc_component_write(component, gain_reg, val);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301697
1698 dev_dbg(wsa_priv->dev, "%s: RX0 Volume %d dB\n",
1699 __func__, val);
1700 }
1701 break;
1702 case SND_SOC_DAPM_POST_PMD:
1703 /*
1704 * Reset RX0 volume to 0 dB if compander is enabled and
1705 * ear_spkr_gain is non-zero.
1706 */
1707 if (wsa_priv->comp_enabled[WSA_MACRO_COMP1] &&
1708 (gain_reg == BOLERO_CDC_WSA_RX0_RX_VOL_CTL) &&
1709 (wsa_priv->ear_spkr_gain != 0)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001710 snd_soc_component_write(component, gain_reg, 0x0);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301711
1712 dev_dbg(wsa_priv->dev, "%s: Reset RX0 Volume to 0 dB\n",
1713 __func__);
1714 }
1715 break;
1716 }
1717
1718 return 0;
1719}
1720
1721static int wsa_macro_spk_boost_event(struct snd_soc_dapm_widget *w,
1722 struct snd_kcontrol *kcontrol,
1723 int event)
1724{
Meng Wang15c825d2018-09-06 10:49:18 +08001725 struct snd_soc_component *component =
1726 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301727 u16 boost_path_ctl, boost_path_cfg1;
1728 u16 reg, reg_mix;
1729
Meng Wang15c825d2018-09-06 10:49:18 +08001730 dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301731
1732 if (!strcmp(w->name, "WSA_RX INT0 CHAIN")) {
1733 boost_path_ctl = BOLERO_CDC_WSA_BOOST0_BOOST_PATH_CTL;
1734 boost_path_cfg1 = BOLERO_CDC_WSA_RX0_RX_PATH_CFG1;
1735 reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL;
1736 reg_mix = BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL;
1737 } else if (!strcmp(w->name, "WSA_RX INT1 CHAIN")) {
1738 boost_path_ctl = BOLERO_CDC_WSA_BOOST1_BOOST_PATH_CTL;
1739 boost_path_cfg1 = BOLERO_CDC_WSA_RX1_RX_PATH_CFG1;
1740 reg = BOLERO_CDC_WSA_RX1_RX_PATH_CTL;
1741 reg_mix = BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL;
1742 } else {
Meng Wang15c825d2018-09-06 10:49:18 +08001743 dev_err(component->dev, "%s: unknown widget: %s\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301744 __func__, w->name);
1745 return -EINVAL;
1746 }
1747
1748 switch (event) {
1749 case SND_SOC_DAPM_PRE_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08001750 snd_soc_component_update_bits(component, boost_path_cfg1,
1751 0x01, 0x01);
1752 snd_soc_component_update_bits(component, boost_path_ctl,
1753 0x10, 0x10);
1754 if ((snd_soc_component_read32(component, reg_mix)) & 0x10)
1755 snd_soc_component_update_bits(component, reg_mix,
1756 0x10, 0x00);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301757 break;
Laxminath Kasam0c857002018-07-17 23:47:17 +05301758 case SND_SOC_DAPM_POST_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08001759 snd_soc_component_update_bits(component, reg, 0x10, 0x00);
Laxminath Kasam0c857002018-07-17 23:47:17 +05301760 break;
Laxminath Kasam243e2752018-04-12 00:40:19 +05301761 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +08001762 snd_soc_component_update_bits(component, boost_path_ctl,
1763 0x10, 0x00);
1764 snd_soc_component_update_bits(component, boost_path_cfg1,
1765 0x01, 0x00);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301766 break;
1767 }
1768
1769 return 0;
1770}
1771
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301772
1773static int wsa_macro_enable_vbat(struct snd_soc_dapm_widget *w,
1774 struct snd_kcontrol *kcontrol,
1775 int event)
1776{
Meng Wang15c825d2018-09-06 10:49:18 +08001777 struct snd_soc_component *component =
1778 snd_soc_dapm_to_component(w->dapm);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301779 struct device *wsa_dev = NULL;
1780 struct wsa_macro_priv *wsa_priv = NULL;
1781 u16 vbat_path_cfg = 0;
1782 int softclip_path = 0;
1783
Meng Wang15c825d2018-09-06 10:49:18 +08001784 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301785 return -EINVAL;
1786
Meng Wang15c825d2018-09-06 10:49:18 +08001787 dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301788 if (!strcmp(w->name, "WSA_RX INT0 VBAT")) {
1789 vbat_path_cfg = BOLERO_CDC_WSA_RX0_RX_PATH_CFG1;
1790 softclip_path = WSA_MACRO_SOFTCLIP0;
1791 } else if (!strcmp(w->name, "WSA_RX INT1 VBAT")) {
1792 vbat_path_cfg = BOLERO_CDC_WSA_RX1_RX_PATH_CFG1;
1793 softclip_path = WSA_MACRO_SOFTCLIP1;
1794 }
1795
1796 switch (event) {
1797 case SND_SOC_DAPM_PRE_PMU:
1798 /* Enable clock for VBAT block */
Meng Wang15c825d2018-09-06 10:49:18 +08001799 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301800 BOLERO_CDC_WSA_VBAT_BCL_VBAT_PATH_CTL, 0x10, 0x10);
1801 /* Enable VBAT block */
Meng Wang15c825d2018-09-06 10:49:18 +08001802 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301803 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG, 0x01, 0x01);
1804 /* Update interpolator with 384K path */
Meng Wang15c825d2018-09-06 10:49:18 +08001805 snd_soc_component_update_bits(component, vbat_path_cfg,
1806 0x80, 0x80);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301807 /* Use attenuation mode */
Meng Wang15c825d2018-09-06 10:49:18 +08001808 snd_soc_component_update_bits(component,
1809 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG, 0x02, 0x00);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301810 /*
1811 * BCL block needs softclip clock and mux config to be enabled
1812 */
Meng Wang15c825d2018-09-06 10:49:18 +08001813 wsa_macro_enable_softclip_clk(component, wsa_priv,
1814 softclip_path, true);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301815 /* Enable VBAT at channel level */
Meng Wang15c825d2018-09-06 10:49:18 +08001816 snd_soc_component_update_bits(component, vbat_path_cfg,
1817 0x02, 0x02);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301818 /* Set the ATTK1 gain */
Meng Wang15c825d2018-09-06 10:49:18 +08001819 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301820 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD1,
1821 0xFF, 0xFF);
Meng Wang15c825d2018-09-06 10:49:18 +08001822 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301823 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD2,
1824 0xFF, 0x03);
Meng Wang15c825d2018-09-06 10:49:18 +08001825 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301826 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD3,
1827 0xFF, 0x00);
1828 /* Set the ATTK2 gain */
Meng Wang15c825d2018-09-06 10:49:18 +08001829 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301830 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD4,
1831 0xFF, 0xFF);
Meng Wang15c825d2018-09-06 10:49:18 +08001832 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301833 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD5,
1834 0xFF, 0x03);
Meng Wang15c825d2018-09-06 10:49:18 +08001835 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301836 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD6,
1837 0xFF, 0x00);
1838 /* Set the ATTK3 gain */
Meng Wang15c825d2018-09-06 10:49:18 +08001839 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301840 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD7,
1841 0xFF, 0xFF);
Meng Wang15c825d2018-09-06 10:49:18 +08001842 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301843 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD8,
1844 0xFF, 0x03);
Meng Wang15c825d2018-09-06 10:49:18 +08001845 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301846 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD9,
1847 0xFF, 0x00);
1848 break;
1849
1850 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +08001851 snd_soc_component_update_bits(component, vbat_path_cfg,
1852 0x80, 0x00);
1853 snd_soc_component_update_bits(component,
1854 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG,
1855 0x02, 0x02);
1856 snd_soc_component_update_bits(component, vbat_path_cfg,
1857 0x02, 0x00);
1858 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301859 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD1,
1860 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001861 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301862 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD2,
1863 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001864 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301865 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD3,
1866 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001867 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301868 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD4,
1869 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001870 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301871 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD5,
1872 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001873 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301874 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD6,
1875 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001876 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301877 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD7,
1878 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001879 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301880 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD8,
1881 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001882 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301883 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD9,
1884 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001885 wsa_macro_enable_softclip_clk(component, wsa_priv,
1886 softclip_path, false);
1887 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301888 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG, 0x01, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001889 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301890 BOLERO_CDC_WSA_VBAT_BCL_VBAT_PATH_CTL, 0x10, 0x00);
1891 break;
1892 default:
1893 dev_err(wsa_dev, "%s: Invalid event %d\n", __func__, event);
1894 break;
1895 }
1896 return 0;
1897}
1898
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301899static int wsa_macro_enable_echo(struct snd_soc_dapm_widget *w,
1900 struct snd_kcontrol *kcontrol,
1901 int event)
1902{
Meng Wang15c825d2018-09-06 10:49:18 +08001903 struct snd_soc_component *component =
1904 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301905 struct device *wsa_dev = NULL;
1906 struct wsa_macro_priv *wsa_priv = NULL;
1907 u16 val, ec_tx = 0, ec_hq_reg;
1908
Meng Wang15c825d2018-09-06 10:49:18 +08001909 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301910 return -EINVAL;
1911
1912 dev_dbg(wsa_dev, "%s %d %s\n", __func__, event, w->name);
1913
Meng Wang15c825d2018-09-06 10:49:18 +08001914 val = snd_soc_component_read32(component,
1915 BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301916 if (!(strcmp(w->name, "WSA RX_MIX EC0_MUX")))
1917 ec_tx = (val & 0x07) - 1;
1918 else
1919 ec_tx = ((val & 0x38) >> 0x3) - 1;
1920
1921 if (ec_tx < 0 || ec_tx >= (WSA_MACRO_RX1 + 1)) {
1922 dev_err(wsa_dev, "%s: EC mix control not set correctly\n",
1923 __func__);
1924 return -EINVAL;
1925 }
1926 if (wsa_priv->ec_hq[ec_tx]) {
Meng Wang15c825d2018-09-06 10:49:18 +08001927 snd_soc_component_update_bits(component,
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301928 BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0,
1929 0x1 << ec_tx, 0x1 << ec_tx);
1930 ec_hq_reg = BOLERO_CDC_WSA_EC_HQ0_EC_REF_HQ_PATH_CTL +
Laxminath Kasam5d9ea8d2018-11-28 14:32:40 +05301931 0x40 * ec_tx;
Meng Wang15c825d2018-09-06 10:49:18 +08001932 snd_soc_component_update_bits(component, ec_hq_reg, 0x01, 0x01);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301933 ec_hq_reg = BOLERO_CDC_WSA_EC_HQ0_EC_REF_HQ_CFG0 +
Laxminath Kasam5d9ea8d2018-11-28 14:32:40 +05301934 0x40 * ec_tx;
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301935 /* default set to 48k */
Meng Wang15c825d2018-09-06 10:49:18 +08001936 snd_soc_component_update_bits(component, ec_hq_reg, 0x1E, 0x08);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301937 }
1938
1939 return 0;
1940}
1941
1942static int wsa_macro_get_ec_hq(struct snd_kcontrol *kcontrol,
1943 struct snd_ctl_elem_value *ucontrol)
1944{
1945
Meng Wang15c825d2018-09-06 10:49:18 +08001946 struct snd_soc_component *component =
1947 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301948 int ec_tx = ((struct soc_multi_mixer_control *)
1949 kcontrol->private_value)->shift;
1950 struct device *wsa_dev = NULL;
1951 struct wsa_macro_priv *wsa_priv = NULL;
1952
Meng Wang15c825d2018-09-06 10:49:18 +08001953 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301954 return -EINVAL;
1955
1956 ucontrol->value.integer.value[0] = wsa_priv->ec_hq[ec_tx];
1957 return 0;
1958}
1959
1960static int wsa_macro_set_ec_hq(struct snd_kcontrol *kcontrol,
1961 struct snd_ctl_elem_value *ucontrol)
1962{
Meng Wang15c825d2018-09-06 10:49:18 +08001963 struct snd_soc_component *component =
1964 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301965 int ec_tx = ((struct soc_multi_mixer_control *)
1966 kcontrol->private_value)->shift;
1967 int value = ucontrol->value.integer.value[0];
1968 struct device *wsa_dev = NULL;
1969 struct wsa_macro_priv *wsa_priv = NULL;
1970
Meng Wang15c825d2018-09-06 10:49:18 +08001971 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301972 return -EINVAL;
1973
1974 dev_dbg(wsa_dev, "%s: enable current %d, new %d\n",
1975 __func__, wsa_priv->ec_hq[ec_tx], value);
1976 wsa_priv->ec_hq[ec_tx] = value;
1977
1978 return 0;
1979}
1980
Vatsal Buchaf2a71b62019-03-26 16:14:40 +05301981static int wsa_macro_get_rx_mute_status(struct snd_kcontrol *kcontrol,
1982 struct snd_ctl_elem_value *ucontrol)
1983{
1984
1985 struct snd_soc_component *component =
1986 snd_soc_kcontrol_component(kcontrol);
1987 struct device *wsa_dev = NULL;
1988 struct wsa_macro_priv *wsa_priv = NULL;
1989 int wsa_rx_shift = ((struct soc_multi_mixer_control *)
1990 kcontrol->private_value)->shift;
1991
1992 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
1993 return -EINVAL;
1994
1995 ucontrol->value.integer.value[0] =
1996 wsa_priv->wsa_digital_mute_status[wsa_rx_shift];
1997 return 0;
1998}
1999
2000static int wsa_macro_set_rx_mute_status(struct snd_kcontrol *kcontrol,
2001 struct snd_ctl_elem_value *ucontrol)
2002{
2003 struct snd_soc_component *component =
2004 snd_soc_kcontrol_component(kcontrol);
2005 struct device *wsa_dev = NULL;
2006 struct wsa_macro_priv *wsa_priv = NULL;
2007 int value = ucontrol->value.integer.value[0];
2008 int wsa_rx_shift = ((struct soc_multi_mixer_control *)
2009 kcontrol->private_value)->shift;
2010
2011 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
2012 return -EINVAL;
2013
2014 switch (wsa_rx_shift) {
2015 case 0:
2016 snd_soc_component_update_bits(component,
2017 BOLERO_CDC_WSA_RX0_RX_PATH_CTL,
2018 0x10, value << 4);
2019 break;
2020 case 1:
2021 snd_soc_component_update_bits(component,
2022 BOLERO_CDC_WSA_RX1_RX_PATH_CTL,
2023 0x10, value << 4);
2024 break;
2025 case 2:
2026 snd_soc_component_update_bits(component,
2027 BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL,
2028 0x10, value << 4);
2029 break;
2030 case 3:
2031 snd_soc_component_update_bits(component,
2032 BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL,
2033 0x10, value << 4);
2034 break;
2035 default:
2036 pr_err("%s: invalid argument rx_shift = %d\n", __func__,
2037 wsa_rx_shift);
2038 return -EINVAL;
2039 }
2040
2041 dev_dbg(component->dev, "%s: WSA Digital Mute RX %d Enable %d\n",
2042 __func__, wsa_rx_shift, value);
2043 wsa_priv->wsa_digital_mute_status[wsa_rx_shift] = value;
2044 return 0;
2045}
2046
Laxminath Kasam243e2752018-04-12 00:40:19 +05302047static int wsa_macro_get_compander(struct snd_kcontrol *kcontrol,
2048 struct snd_ctl_elem_value *ucontrol)
2049{
2050
Meng Wang15c825d2018-09-06 10:49:18 +08002051 struct snd_soc_component *component =
2052 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302053 int comp = ((struct soc_multi_mixer_control *)
2054 kcontrol->private_value)->shift;
2055 struct device *wsa_dev = NULL;
2056 struct wsa_macro_priv *wsa_priv = NULL;
2057
Meng Wang15c825d2018-09-06 10:49:18 +08002058 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302059 return -EINVAL;
2060
2061 ucontrol->value.integer.value[0] = wsa_priv->comp_enabled[comp];
2062 return 0;
2063}
2064
2065static int wsa_macro_set_compander(struct snd_kcontrol *kcontrol,
2066 struct snd_ctl_elem_value *ucontrol)
2067{
Meng Wang15c825d2018-09-06 10:49:18 +08002068 struct snd_soc_component *component =
2069 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302070 int comp = ((struct soc_multi_mixer_control *)
2071 kcontrol->private_value)->shift;
2072 int value = ucontrol->value.integer.value[0];
2073 struct device *wsa_dev = NULL;
2074 struct wsa_macro_priv *wsa_priv = NULL;
2075
Meng Wang15c825d2018-09-06 10:49:18 +08002076 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302077 return -EINVAL;
2078
Meng Wang15c825d2018-09-06 10:49:18 +08002079 dev_dbg(component->dev, "%s: Compander %d enable current %d, new %d\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05302080 __func__, comp + 1, wsa_priv->comp_enabled[comp], value);
2081 wsa_priv->comp_enabled[comp] = value;
2082
2083 return 0;
2084}
2085
2086static int wsa_macro_ear_spkr_pa_gain_get(struct snd_kcontrol *kcontrol,
2087 struct snd_ctl_elem_value *ucontrol)
2088{
Meng Wang15c825d2018-09-06 10:49:18 +08002089 struct snd_soc_component *component =
2090 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302091 struct device *wsa_dev = NULL;
2092 struct wsa_macro_priv *wsa_priv = NULL;
2093
Meng Wang15c825d2018-09-06 10:49:18 +08002094 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302095 return -EINVAL;
2096
2097 ucontrol->value.integer.value[0] = wsa_priv->ear_spkr_gain;
2098
Meng Wang15c825d2018-09-06 10:49:18 +08002099 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05302100 __func__, ucontrol->value.integer.value[0]);
2101
2102 return 0;
2103}
2104
2105static int wsa_macro_ear_spkr_pa_gain_put(struct snd_kcontrol *kcontrol,
2106 struct snd_ctl_elem_value *ucontrol)
2107{
Meng Wang15c825d2018-09-06 10:49:18 +08002108 struct snd_soc_component *component =
2109 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302110 struct device *wsa_dev = NULL;
2111 struct wsa_macro_priv *wsa_priv = NULL;
2112
Meng Wang15c825d2018-09-06 10:49:18 +08002113 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302114 return -EINVAL;
2115
2116 wsa_priv->ear_spkr_gain = ucontrol->value.integer.value[0];
2117
Meng Wang15c825d2018-09-06 10:49:18 +08002118 dev_dbg(component->dev, "%s: gain = %d\n", __func__,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302119 wsa_priv->ear_spkr_gain);
2120
2121 return 0;
2122}
2123
2124static int wsa_macro_spkr_left_boost_stage_get(struct snd_kcontrol *kcontrol,
2125 struct snd_ctl_elem_value *ucontrol)
2126{
2127 u8 bst_state_max = 0;
Meng Wang15c825d2018-09-06 10:49:18 +08002128 struct snd_soc_component *component =
2129 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302130
Meng Wang15c825d2018-09-06 10:49:18 +08002131 bst_state_max = snd_soc_component_read32(component,
2132 BOLERO_CDC_WSA_BOOST0_BOOST_CTL);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302133 bst_state_max = (bst_state_max & 0x0c) >> 2;
2134 ucontrol->value.integer.value[0] = bst_state_max;
Meng Wang15c825d2018-09-06 10:49:18 +08002135 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05302136 __func__, ucontrol->value.integer.value[0]);
2137
2138 return 0;
2139}
2140
2141static int wsa_macro_spkr_left_boost_stage_put(struct snd_kcontrol *kcontrol,
2142 struct snd_ctl_elem_value *ucontrol)
2143{
2144 u8 bst_state_max;
Meng Wang15c825d2018-09-06 10:49:18 +08002145 struct snd_soc_component *component =
2146 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302147
Meng Wang15c825d2018-09-06 10:49:18 +08002148 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05302149 __func__, ucontrol->value.integer.value[0]);
2150 bst_state_max = ucontrol->value.integer.value[0] << 2;
Karthikeyan Mani10de3932019-04-15 11:46:57 -07002151 /* bolero does not need to limit the boost levels */
Laxminath Kasam243e2752018-04-12 00:40:19 +05302152
2153 return 0;
2154}
2155
2156static int wsa_macro_spkr_right_boost_stage_get(struct snd_kcontrol *kcontrol,
2157 struct snd_ctl_elem_value *ucontrol)
2158{
2159 u8 bst_state_max = 0;
Meng Wang15c825d2018-09-06 10:49:18 +08002160 struct snd_soc_component *component =
2161 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302162
Meng Wang15c825d2018-09-06 10:49:18 +08002163 bst_state_max = snd_soc_component_read32(component,
2164 BOLERO_CDC_WSA_BOOST1_BOOST_CTL);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302165 bst_state_max = (bst_state_max & 0x0c) >> 2;
2166 ucontrol->value.integer.value[0] = bst_state_max;
Meng Wang15c825d2018-09-06 10:49:18 +08002167 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05302168 __func__, ucontrol->value.integer.value[0]);
2169
2170 return 0;
2171}
2172
2173static int wsa_macro_spkr_right_boost_stage_put(struct snd_kcontrol *kcontrol,
2174 struct snd_ctl_elem_value *ucontrol)
2175{
2176 u8 bst_state_max;
Meng Wang15c825d2018-09-06 10:49:18 +08002177 struct snd_soc_component *component =
2178 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302179
Meng Wang15c825d2018-09-06 10:49:18 +08002180 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05302181 __func__, ucontrol->value.integer.value[0]);
2182 bst_state_max = ucontrol->value.integer.value[0] << 2;
Karthikeyan Mani10de3932019-04-15 11:46:57 -07002183 /* bolero does not need to limit the boost levels */
Laxminath Kasam243e2752018-04-12 00:40:19 +05302184
2185 return 0;
2186}
2187
2188static int wsa_macro_rx_mux_get(struct snd_kcontrol *kcontrol,
2189 struct snd_ctl_elem_value *ucontrol)
2190{
2191 struct snd_soc_dapm_widget *widget =
2192 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +08002193 struct snd_soc_component *component =
2194 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302195 struct device *wsa_dev = NULL;
2196 struct wsa_macro_priv *wsa_priv = NULL;
2197
Meng Wang15c825d2018-09-06 10:49:18 +08002198 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302199 return -EINVAL;
2200
2201 ucontrol->value.integer.value[0] =
2202 wsa_priv->rx_port_value[widget->shift];
2203 return 0;
2204}
2205
2206static int wsa_macro_rx_mux_put(struct snd_kcontrol *kcontrol,
2207 struct snd_ctl_elem_value *ucontrol)
2208{
2209 struct snd_soc_dapm_widget *widget =
2210 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +08002211 struct snd_soc_component *component =
2212 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302213 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
2214 struct snd_soc_dapm_update *update = NULL;
2215 u32 rx_port_value = ucontrol->value.integer.value[0];
2216 u32 bit_input = 0;
2217 u32 aif_rst;
2218 struct device *wsa_dev = NULL;
2219 struct wsa_macro_priv *wsa_priv = NULL;
2220
Meng Wang15c825d2018-09-06 10:49:18 +08002221 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302222 return -EINVAL;
2223
2224 aif_rst = wsa_priv->rx_port_value[widget->shift];
2225 if (!rx_port_value) {
2226 if (aif_rst == 0) {
2227 dev_err(wsa_dev, "%s: AIF reset already\n", __func__);
2228 return 0;
2229 }
Sudheer Papothic0f75b72019-07-16 06:04:10 +05302230 if (aif_rst >= WSA_MACRO_RX_MAX) {
2231 dev_err(wsa_dev, "%s: Invalid AIF reset\n", __func__);
2232 return 0;
2233 }
Laxminath Kasam243e2752018-04-12 00:40:19 +05302234 }
2235 wsa_priv->rx_port_value[widget->shift] = rx_port_value;
2236
2237 bit_input = widget->shift;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302238
Sudheer Papothic0f75b72019-07-16 06:04:10 +05302239 dev_dbg(wsa_dev,
2240 "%s: mux input: %d, mux output: %d, bit: %d\n",
2241 __func__, rx_port_value, widget->shift, bit_input);
2242
Laxminath Kasam243e2752018-04-12 00:40:19 +05302243 switch (rx_port_value) {
2244 case 0:
Sudheer Papothic0f75b72019-07-16 06:04:10 +05302245 if (wsa_priv->active_ch_cnt[aif_rst]) {
2246 clear_bit(bit_input,
2247 &wsa_priv->active_ch_mask[aif_rst]);
2248 wsa_priv->active_ch_cnt[aif_rst]--;
2249 }
Laxminath Kasam243e2752018-04-12 00:40:19 +05302250 break;
2251 case 1:
2252 case 2:
2253 set_bit(bit_input,
Laxminath Kasam59c7a1d2018-08-09 16:11:17 +05302254 &wsa_priv->active_ch_mask[rx_port_value]);
2255 wsa_priv->active_ch_cnt[rx_port_value]++;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302256 break;
2257 default:
2258 dev_err(wsa_dev,
Sudheer Papothic0f75b72019-07-16 06:04:10 +05302259 "%s: Invalid AIF_ID for WSA RX MUX %d\n",
2260 __func__, rx_port_value);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302261 return -EINVAL;
2262 }
2263
2264 snd_soc_dapm_mux_update_power(widget->dapm, kcontrol,
2265 rx_port_value, e, update);
2266 return 0;
2267}
2268
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302269static int wsa_macro_vbat_bcl_gsm_mode_func_get(struct snd_kcontrol *kcontrol,
2270 struct snd_ctl_elem_value *ucontrol)
2271{
Meng Wang15c825d2018-09-06 10:49:18 +08002272 struct snd_soc_component *component =
2273 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302274
2275 ucontrol->value.integer.value[0] =
Meng Wang15c825d2018-09-06 10:49:18 +08002276 ((snd_soc_component_read32(
2277 component, BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG) & 0x04) ?
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302278 1 : 0);
2279
Meng Wang15c825d2018-09-06 10:49:18 +08002280 dev_dbg(component->dev, "%s: value: %lu\n", __func__,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302281 ucontrol->value.integer.value[0]);
2282
2283 return 0;
2284}
2285
2286static int wsa_macro_vbat_bcl_gsm_mode_func_put(struct snd_kcontrol *kcontrol,
2287 struct snd_ctl_elem_value *ucontrol)
2288{
Meng Wang15c825d2018-09-06 10:49:18 +08002289 struct snd_soc_component *component =
2290 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302291
Meng Wang15c825d2018-09-06 10:49:18 +08002292 dev_dbg(component->dev, "%s: value: %lu\n", __func__,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302293 ucontrol->value.integer.value[0]);
2294
2295 /* Set Vbat register configuration for GSM mode bit based on value */
2296 if (ucontrol->value.integer.value[0])
Meng Wang15c825d2018-09-06 10:49:18 +08002297 snd_soc_component_update_bits(component,
2298 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG,
2299 0x04, 0x04);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302300 else
Meng Wang15c825d2018-09-06 10:49:18 +08002301 snd_soc_component_update_bits(component,
2302 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG,
2303 0x04, 0x00);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302304
2305 return 0;
2306}
2307
2308static int wsa_macro_soft_clip_enable_get(struct snd_kcontrol *kcontrol,
2309 struct snd_ctl_elem_value *ucontrol)
2310{
Meng Wang15c825d2018-09-06 10:49:18 +08002311 struct snd_soc_component *component =
2312 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302313 struct device *wsa_dev = NULL;
2314 struct wsa_macro_priv *wsa_priv = NULL;
2315 int path = ((struct soc_multi_mixer_control *)
2316 kcontrol->private_value)->shift;
2317
Meng Wang15c825d2018-09-06 10:49:18 +08002318 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302319 return -EINVAL;
2320
2321 ucontrol->value.integer.value[0] = wsa_priv->is_softclip_on[path];
2322
Meng Wang15c825d2018-09-06 10:49:18 +08002323 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302324 __func__, ucontrol->value.integer.value[0]);
2325
2326 return 0;
2327}
2328
2329static int wsa_macro_soft_clip_enable_put(struct snd_kcontrol *kcontrol,
2330 struct snd_ctl_elem_value *ucontrol)
2331{
Meng Wang15c825d2018-09-06 10:49:18 +08002332 struct snd_soc_component *component =
2333 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302334 struct device *wsa_dev = NULL;
2335 struct wsa_macro_priv *wsa_priv = NULL;
2336 int path = ((struct soc_multi_mixer_control *)
2337 kcontrol->private_value)->shift;
2338
Meng Wang15c825d2018-09-06 10:49:18 +08002339 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302340 return -EINVAL;
2341
2342 wsa_priv->is_softclip_on[path] = ucontrol->value.integer.value[0];
2343
Meng Wang15c825d2018-09-06 10:49:18 +08002344 dev_dbg(component->dev, "%s: soft clip enable for %d: %d\n", __func__,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302345 path, wsa_priv->is_softclip_on[path]);
2346
2347 return 0;
2348}
2349
Laxminath Kasam243e2752018-04-12 00:40:19 +05302350static const struct snd_kcontrol_new wsa_macro_snd_controls[] = {
2351 SOC_ENUM_EXT("EAR SPKR PA Gain", wsa_macro_ear_spkr_pa_gain_enum,
2352 wsa_macro_ear_spkr_pa_gain_get,
2353 wsa_macro_ear_spkr_pa_gain_put),
2354 SOC_ENUM_EXT("SPKR Left Boost Max State",
2355 wsa_macro_spkr_boost_stage_enum,
2356 wsa_macro_spkr_left_boost_stage_get,
2357 wsa_macro_spkr_left_boost_stage_put),
2358 SOC_ENUM_EXT("SPKR Right Boost Max State",
2359 wsa_macro_spkr_boost_stage_enum,
2360 wsa_macro_spkr_right_boost_stage_get,
2361 wsa_macro_spkr_right_boost_stage_put),
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302362 SOC_ENUM_EXT("GSM mode Enable", wsa_macro_vbat_bcl_gsm_mode_enum,
2363 wsa_macro_vbat_bcl_gsm_mode_func_get,
2364 wsa_macro_vbat_bcl_gsm_mode_func_put),
2365 SOC_SINGLE_EXT("WSA_Softclip0 Enable", SND_SOC_NOPM,
2366 WSA_MACRO_SOFTCLIP0, 1, 0,
2367 wsa_macro_soft_clip_enable_get,
2368 wsa_macro_soft_clip_enable_put),
2369 SOC_SINGLE_EXT("WSA_Softclip1 Enable", SND_SOC_NOPM,
2370 WSA_MACRO_SOFTCLIP1, 1, 0,
2371 wsa_macro_soft_clip_enable_get,
2372 wsa_macro_soft_clip_enable_put),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302373 SOC_SINGLE_SX_TLV("WSA_RX0 Digital Volume",
2374 BOLERO_CDC_WSA_RX0_RX_VOL_CTL,
2375 0, -84, 40, digital_gain),
2376 SOC_SINGLE_SX_TLV("WSA_RX1 Digital Volume",
2377 BOLERO_CDC_WSA_RX1_RX_VOL_CTL,
2378 0, -84, 40, digital_gain),
Vatsal Buchaf2a71b62019-03-26 16:14:40 +05302379 SOC_SINGLE_EXT("WSA_RX0 Digital Mute", SND_SOC_NOPM, WSA_MACRO_RX0, 1,
2380 0, wsa_macro_get_rx_mute_status,
2381 wsa_macro_set_rx_mute_status),
2382 SOC_SINGLE_EXT("WSA_RX1 Digital Mute", SND_SOC_NOPM, WSA_MACRO_RX1, 1,
2383 0, wsa_macro_get_rx_mute_status,
2384 wsa_macro_set_rx_mute_status),
2385 SOC_SINGLE_EXT("WSA_RX0_MIX Digital Mute", SND_SOC_NOPM,
2386 WSA_MACRO_RX_MIX0, 1, 0, wsa_macro_get_rx_mute_status,
2387 wsa_macro_set_rx_mute_status),
2388 SOC_SINGLE_EXT("WSA_RX1_MIX Digital Mute", SND_SOC_NOPM,
2389 WSA_MACRO_RX_MIX1, 1, 0, wsa_macro_get_rx_mute_status,
2390 wsa_macro_set_rx_mute_status),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302391 SOC_SINGLE_EXT("WSA_COMP1 Switch", SND_SOC_NOPM, WSA_MACRO_COMP1, 1, 0,
2392 wsa_macro_get_compander, wsa_macro_set_compander),
2393 SOC_SINGLE_EXT("WSA_COMP2 Switch", SND_SOC_NOPM, WSA_MACRO_COMP2, 1, 0,
2394 wsa_macro_get_compander, wsa_macro_set_compander),
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05302395 SOC_SINGLE_EXT("WSA_RX0 EC_HQ Switch", SND_SOC_NOPM, WSA_MACRO_RX0,
2396 1, 0, wsa_macro_get_ec_hq, wsa_macro_set_ec_hq),
2397 SOC_SINGLE_EXT("WSA_RX1 EC_HQ Switch", SND_SOC_NOPM, WSA_MACRO_RX1,
2398 1, 0, wsa_macro_get_ec_hq, wsa_macro_set_ec_hq),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302399};
2400
2401static const struct soc_enum rx_mux_enum =
2402 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_mux_text), rx_mux_text);
2403
2404static const struct snd_kcontrol_new rx_mux[WSA_MACRO_RX_MAX] = {
2405 SOC_DAPM_ENUM_EXT("WSA RX0 Mux", rx_mux_enum,
2406 wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),
2407 SOC_DAPM_ENUM_EXT("WSA RX1 Mux", rx_mux_enum,
2408 wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),
2409 SOC_DAPM_ENUM_EXT("WSA RX_MIX0 Mux", rx_mux_enum,
2410 wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),
2411 SOC_DAPM_ENUM_EXT("WSA RX_MIX1 Mux", rx_mux_enum,
2412 wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),
2413};
2414
2415static int wsa_macro_vi_feed_mixer_get(struct snd_kcontrol *kcontrol,
2416 struct snd_ctl_elem_value *ucontrol)
2417{
2418 struct snd_soc_dapm_widget *widget =
2419 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +08002420 struct snd_soc_component *component =
2421 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302422 struct soc_multi_mixer_control *mixer =
2423 ((struct soc_multi_mixer_control *)kcontrol->private_value);
2424 u32 dai_id = widget->shift;
2425 u32 spk_tx_id = mixer->shift;
2426 struct device *wsa_dev = NULL;
2427 struct wsa_macro_priv *wsa_priv = NULL;
2428
Meng Wang15c825d2018-09-06 10:49:18 +08002429 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302430 return -EINVAL;
2431
2432 if (test_bit(spk_tx_id, &wsa_priv->active_ch_mask[dai_id]))
2433 ucontrol->value.integer.value[0] = 1;
2434 else
2435 ucontrol->value.integer.value[0] = 0;
2436
2437 return 0;
2438}
2439
2440static int wsa_macro_vi_feed_mixer_put(struct snd_kcontrol *kcontrol,
2441 struct snd_ctl_elem_value *ucontrol)
2442{
2443 struct snd_soc_dapm_widget *widget =
2444 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +08002445 struct snd_soc_component *component =
2446 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302447 struct soc_multi_mixer_control *mixer =
2448 ((struct soc_multi_mixer_control *)kcontrol->private_value);
2449 u32 spk_tx_id = mixer->shift;
2450 u32 enable = ucontrol->value.integer.value[0];
2451 struct device *wsa_dev = NULL;
2452 struct wsa_macro_priv *wsa_priv = NULL;
2453
Meng Wang15c825d2018-09-06 10:49:18 +08002454 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302455 return -EINVAL;
2456
2457 wsa_priv->vi_feed_value = ucontrol->value.integer.value[0];
2458
2459 if (enable) {
2460 if (spk_tx_id == WSA_MACRO_TX0 &&
2461 !test_bit(WSA_MACRO_TX0,
2462 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
2463 set_bit(WSA_MACRO_TX0,
2464 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI]);
2465 wsa_priv->active_ch_cnt[WSA_MACRO_AIF_VI]++;
2466 }
2467 if (spk_tx_id == WSA_MACRO_TX1 &&
2468 !test_bit(WSA_MACRO_TX1,
2469 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
2470 set_bit(WSA_MACRO_TX1,
2471 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI]);
2472 wsa_priv->active_ch_cnt[WSA_MACRO_AIF_VI]++;
2473 }
2474 } else {
2475 if (spk_tx_id == WSA_MACRO_TX0 &&
2476 test_bit(WSA_MACRO_TX0,
2477 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
2478 clear_bit(WSA_MACRO_TX0,
2479 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI]);
2480 wsa_priv->active_ch_cnt[WSA_MACRO_AIF_VI]--;
2481 }
2482 if (spk_tx_id == WSA_MACRO_TX1 &&
2483 test_bit(WSA_MACRO_TX1,
2484 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
2485 clear_bit(WSA_MACRO_TX1,
2486 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI]);
2487 wsa_priv->active_ch_cnt[WSA_MACRO_AIF_VI]--;
2488 }
2489 }
2490 snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, NULL);
2491
2492 return 0;
2493}
2494
2495static const struct snd_kcontrol_new aif_vi_mixer[] = {
2496 SOC_SINGLE_EXT("WSA_SPKR_VI_1", SND_SOC_NOPM, WSA_MACRO_TX0, 1, 0,
2497 wsa_macro_vi_feed_mixer_get,
2498 wsa_macro_vi_feed_mixer_put),
2499 SOC_SINGLE_EXT("WSA_SPKR_VI_2", SND_SOC_NOPM, WSA_MACRO_TX1, 1, 0,
2500 wsa_macro_vi_feed_mixer_get,
2501 wsa_macro_vi_feed_mixer_put),
2502};
2503
2504static const struct snd_soc_dapm_widget wsa_macro_dapm_widgets[] = {
2505 SND_SOC_DAPM_AIF_IN("WSA AIF1 PB", "WSA_AIF1 Playback", 0,
2506 SND_SOC_NOPM, 0, 0),
2507
2508 SND_SOC_DAPM_AIF_IN("WSA AIF_MIX1 PB", "WSA_AIF_MIX1 Playback", 0,
2509 SND_SOC_NOPM, 0, 0),
2510
2511 SND_SOC_DAPM_AIF_OUT_E("WSA AIF_VI", "WSA_AIF_VI Capture", 0,
2512 SND_SOC_NOPM, WSA_MACRO_AIF_VI, 0,
2513 wsa_macro_enable_vi_feedback,
2514 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
2515
2516 SND_SOC_DAPM_AIF_OUT("WSA AIF_ECHO", "WSA_AIF_ECHO Capture", 0,
2517 SND_SOC_NOPM, 0, 0),
2518
2519 SND_SOC_DAPM_MIXER("WSA_AIF_VI Mixer", SND_SOC_NOPM, WSA_MACRO_AIF_VI,
2520 0, aif_vi_mixer, ARRAY_SIZE(aif_vi_mixer)),
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05302521 SND_SOC_DAPM_MUX_E("WSA RX_MIX EC0_MUX", SND_SOC_NOPM,
2522 WSA_MACRO_EC0_MUX, 0,
2523 &rx_mix_ec0_mux, wsa_macro_enable_echo,
2524 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2525 SND_SOC_DAPM_MUX_E("WSA RX_MIX EC1_MUX", SND_SOC_NOPM,
2526 WSA_MACRO_EC1_MUX, 0,
2527 &rx_mix_ec1_mux, wsa_macro_enable_echo,
2528 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302529
2530 SND_SOC_DAPM_MUX("WSA RX0 MUX", SND_SOC_NOPM, WSA_MACRO_RX0, 0,
2531 &rx_mux[WSA_MACRO_RX0]),
2532 SND_SOC_DAPM_MUX("WSA RX1 MUX", SND_SOC_NOPM, WSA_MACRO_RX1, 0,
2533 &rx_mux[WSA_MACRO_RX1]),
2534 SND_SOC_DAPM_MUX("WSA RX_MIX0 MUX", SND_SOC_NOPM, WSA_MACRO_RX_MIX0, 0,
2535 &rx_mux[WSA_MACRO_RX_MIX0]),
2536 SND_SOC_DAPM_MUX("WSA RX_MIX1 MUX", SND_SOC_NOPM, WSA_MACRO_RX_MIX1, 0,
2537 &rx_mux[WSA_MACRO_RX_MIX1]),
2538
2539 SND_SOC_DAPM_MIXER("WSA RX0", SND_SOC_NOPM, 0, 0, NULL, 0),
2540 SND_SOC_DAPM_MIXER("WSA RX1", SND_SOC_NOPM, 0, 0, NULL, 0),
2541 SND_SOC_DAPM_MIXER("WSA RX_MIX0", SND_SOC_NOPM, 0, 0, NULL, 0),
2542 SND_SOC_DAPM_MIXER("WSA RX_MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
2543
2544 SND_SOC_DAPM_MUX_E("WSA_RX0 INP0", SND_SOC_NOPM, 0, 0,
2545 &rx0_prim_inp0_mux, wsa_macro_enable_swr,
2546 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2547 SND_SOC_DAPM_MUX_E("WSA_RX0 INP1", SND_SOC_NOPM, 0, 0,
2548 &rx0_prim_inp1_mux, wsa_macro_enable_swr,
2549 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2550 SND_SOC_DAPM_MUX_E("WSA_RX0 INP2", SND_SOC_NOPM, 0, 0,
2551 &rx0_prim_inp2_mux, wsa_macro_enable_swr,
2552 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
Laxminath Kasam01d2eb22020-05-13 18:44:49 +05302553 SND_SOC_DAPM_MUX_E("WSA_RX0 MIX INP", SND_SOC_NOPM,
Laxminath Kasam52ae6582019-08-08 18:00:35 +05302554 0, 0, &rx0_mix_mux, wsa_macro_enable_mix_path,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302555 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2556 SND_SOC_DAPM_MUX_E("WSA_RX1 INP0", SND_SOC_NOPM, 0, 0,
2557 &rx1_prim_inp0_mux, wsa_macro_enable_swr,
2558 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2559 SND_SOC_DAPM_MUX_E("WSA_RX1 INP1", SND_SOC_NOPM, 0, 0,
2560 &rx1_prim_inp1_mux, wsa_macro_enable_swr,
2561 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2562 SND_SOC_DAPM_MUX_E("WSA_RX1 INP2", SND_SOC_NOPM, 0, 0,
2563 &rx1_prim_inp2_mux, wsa_macro_enable_swr,
2564 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
Laxminath Kasam01d2eb22020-05-13 18:44:49 +05302565 SND_SOC_DAPM_MUX_E("WSA_RX1 MIX INP", SND_SOC_NOPM,
Laxminath Kasam52ae6582019-08-08 18:00:35 +05302566 0, 0, &rx1_mix_mux, wsa_macro_enable_mix_path,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302567 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
Laxminath Kasam52ae6582019-08-08 18:00:35 +05302568 SND_SOC_DAPM_MIXER_E("WSA_RX INT0 MIX", SND_SOC_NOPM,
2569 0, 0, NULL, 0, wsa_macro_enable_main_path,
2570 SND_SOC_DAPM_PRE_PMU),
2571 SND_SOC_DAPM_MIXER_E("WSA_RX INT1 MIX", SND_SOC_NOPM,
2572 1, 0, NULL, 0, wsa_macro_enable_main_path,
2573 SND_SOC_DAPM_PRE_PMU),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302574 SND_SOC_DAPM_MIXER("WSA_RX INT0 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
2575 SND_SOC_DAPM_MIXER("WSA_RX INT1 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
2576
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302577 SND_SOC_DAPM_MUX_E("WSA_RX0 INT0 SIDETONE MIX",
2578 BOLERO_CDC_WSA_RX0_RX_PATH_CFG1, 4, 0,
2579 &rx0_sidetone_mix_mux, wsa_macro_enable_swr,
2580 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2581 SND_SOC_DAPM_INPUT("WSA SRC0_INP"),
2582
2583 SND_SOC_DAPM_INPUT("WSA_TX DEC0_INP"),
2584 SND_SOC_DAPM_INPUT("WSA_TX DEC1_INP"),
2585
Laxminath Kasam243e2752018-04-12 00:40:19 +05302586 SND_SOC_DAPM_MIXER_E("WSA_RX INT0 INTERP", SND_SOC_NOPM,
2587 WSA_MACRO_COMP1, 0, NULL, 0, wsa_macro_enable_interpolator,
2588 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2589 SND_SOC_DAPM_POST_PMD),
2590 SND_SOC_DAPM_MIXER_E("WSA_RX INT1 INTERP", SND_SOC_NOPM,
2591 WSA_MACRO_COMP2, 0, NULL, 0, wsa_macro_enable_interpolator,
2592 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2593 SND_SOC_DAPM_POST_PMD),
2594
2595 SND_SOC_DAPM_MIXER_E("WSA_RX INT0 CHAIN", SND_SOC_NOPM, 0, 0,
2596 NULL, 0, wsa_macro_spk_boost_event,
Laxminath Kasam0c857002018-07-17 23:47:17 +05302597 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2598 SND_SOC_DAPM_POST_PMD),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302599 SND_SOC_DAPM_MIXER_E("WSA_RX INT1 CHAIN", SND_SOC_NOPM, 0, 0,
2600 NULL, 0, wsa_macro_spk_boost_event,
Laxminath Kasam0c857002018-07-17 23:47:17 +05302601 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2602 SND_SOC_DAPM_POST_PMD),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302603
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302604 SND_SOC_DAPM_MIXER_E("WSA_RX INT0 VBAT", SND_SOC_NOPM,
2605 0, 0, wsa_int0_vbat_mix_switch,
2606 ARRAY_SIZE(wsa_int0_vbat_mix_switch),
2607 wsa_macro_enable_vbat,
2608 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2609 SND_SOC_DAPM_MIXER_E("WSA_RX INT1 VBAT", SND_SOC_NOPM,
2610 0, 0, wsa_int1_vbat_mix_switch,
2611 ARRAY_SIZE(wsa_int1_vbat_mix_switch),
2612 wsa_macro_enable_vbat,
2613 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2614
Laxminath Kasam243e2752018-04-12 00:40:19 +05302615 SND_SOC_DAPM_INPUT("VIINPUT_WSA"),
2616
2617 SND_SOC_DAPM_OUTPUT("WSA_SPK1 OUT"),
2618 SND_SOC_DAPM_OUTPUT("WSA_SPK2 OUT"),
2619
2620 SND_SOC_DAPM_SUPPLY_S("WSA_MCLK", 0, SND_SOC_NOPM, 0, 0,
2621 wsa_macro_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2622};
2623
2624static const struct snd_soc_dapm_route wsa_audio_map[] = {
2625 /* VI Feedback */
2626 {"WSA_AIF_VI Mixer", "WSA_SPKR_VI_1", "VIINPUT_WSA"},
2627 {"WSA_AIF_VI Mixer", "WSA_SPKR_VI_2", "VIINPUT_WSA"},
2628 {"WSA AIF_VI", NULL, "WSA_AIF_VI Mixer"},
2629 {"WSA AIF_VI", NULL, "WSA_MCLK"},
2630
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05302631 {"WSA RX_MIX EC0_MUX", "RX_MIX_TX0", "WSA_RX INT0 SEC MIX"},
2632 {"WSA RX_MIX EC1_MUX", "RX_MIX_TX0", "WSA_RX INT0 SEC MIX"},
2633 {"WSA RX_MIX EC0_MUX", "RX_MIX_TX1", "WSA_RX INT1 SEC MIX"},
2634 {"WSA RX_MIX EC1_MUX", "RX_MIX_TX1", "WSA_RX INT1 SEC MIX"},
2635 {"WSA AIF_ECHO", NULL, "WSA RX_MIX EC0_MUX"},
2636 {"WSA AIF_ECHO", NULL, "WSA RX_MIX EC1_MUX"},
2637 {"WSA AIF_ECHO", NULL, "WSA_MCLK"},
2638
Laxminath Kasam243e2752018-04-12 00:40:19 +05302639 {"WSA AIF1 PB", NULL, "WSA_MCLK"},
2640 {"WSA AIF_MIX1 PB", NULL, "WSA_MCLK"},
2641
2642 {"WSA RX0 MUX", "AIF1_PB", "WSA AIF1 PB"},
2643 {"WSA RX1 MUX", "AIF1_PB", "WSA AIF1 PB"},
2644 {"WSA RX_MIX0 MUX", "AIF1_PB", "WSA AIF1 PB"},
2645 {"WSA RX_MIX1 MUX", "AIF1_PB", "WSA AIF1 PB"},
2646
2647 {"WSA RX0 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
2648 {"WSA RX1 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
2649 {"WSA RX_MIX0 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
2650 {"WSA RX_MIX1 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
2651
2652 {"WSA RX0", NULL, "WSA RX0 MUX"},
2653 {"WSA RX1", NULL, "WSA RX1 MUX"},
2654 {"WSA RX_MIX0", NULL, "WSA RX_MIX0 MUX"},
2655 {"WSA RX_MIX1", NULL, "WSA RX_MIX1 MUX"},
2656
2657 {"WSA_RX0 INP0", "RX0", "WSA RX0"},
2658 {"WSA_RX0 INP0", "RX1", "WSA RX1"},
2659 {"WSA_RX0 INP0", "RX_MIX0", "WSA RX_MIX0"},
2660 {"WSA_RX0 INP0", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302661 {"WSA_RX0 INP0", "DEC0", "WSA_TX DEC0_INP"},
2662 {"WSA_RX0 INP0", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302663 {"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP0"},
2664
2665 {"WSA_RX0 INP1", "RX0", "WSA RX0"},
2666 {"WSA_RX0 INP1", "RX1", "WSA RX1"},
2667 {"WSA_RX0 INP1", "RX_MIX0", "WSA RX_MIX0"},
2668 {"WSA_RX0 INP1", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302669 {"WSA_RX0 INP1", "DEC0", "WSA_TX DEC0_INP"},
2670 {"WSA_RX0 INP1", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302671 {"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP1"},
2672
2673 {"WSA_RX0 INP2", "RX0", "WSA RX0"},
2674 {"WSA_RX0 INP2", "RX1", "WSA RX1"},
2675 {"WSA_RX0 INP2", "RX_MIX0", "WSA RX_MIX0"},
2676 {"WSA_RX0 INP2", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302677 {"WSA_RX0 INP2", "DEC0", "WSA_TX DEC0_INP"},
2678 {"WSA_RX0 INP2", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302679 {"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP2"},
2680
2681 {"WSA_RX0 MIX INP", "RX0", "WSA RX0"},
2682 {"WSA_RX0 MIX INP", "RX1", "WSA RX1"},
2683 {"WSA_RX0 MIX INP", "RX_MIX0", "WSA RX_MIX0"},
2684 {"WSA_RX0 MIX INP", "RX_MIX1", "WSA RX_MIX1"},
2685 {"WSA_RX INT0 SEC MIX", NULL, "WSA_RX0 MIX INP"},
2686
2687 {"WSA_RX INT0 SEC MIX", NULL, "WSA_RX INT0 MIX"},
2688 {"WSA_RX INT0 INTERP", NULL, "WSA_RX INT0 SEC MIX"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302689 {"WSA_RX0 INT0 SIDETONE MIX", "SRC0", "WSA SRC0_INP"},
2690 {"WSA_RX INT0 INTERP", NULL, "WSA_RX0 INT0 SIDETONE MIX"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302691 {"WSA_RX INT0 CHAIN", NULL, "WSA_RX INT0 INTERP"},
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302692
2693 {"WSA_RX INT0 VBAT", "WSA RX0 VBAT Enable", "WSA_RX INT0 INTERP"},
2694 {"WSA_RX INT0 CHAIN", NULL, "WSA_RX INT0 VBAT"},
2695
Laxminath Kasam243e2752018-04-12 00:40:19 +05302696 {"WSA_SPK1 OUT", NULL, "WSA_RX INT0 CHAIN"},
Laxminath Kasamfc281ad2018-08-06 20:19:40 +05302697 {"WSA_SPK1 OUT", NULL, "WSA_MCLK"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302698
2699 {"WSA_RX1 INP0", "RX0", "WSA RX0"},
2700 {"WSA_RX1 INP0", "RX1", "WSA RX1"},
2701 {"WSA_RX1 INP0", "RX_MIX0", "WSA RX_MIX0"},
2702 {"WSA_RX1 INP0", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302703 {"WSA_RX1 INP0", "DEC0", "WSA_TX DEC0_INP"},
2704 {"WSA_RX1 INP0", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302705 {"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP0"},
2706
2707 {"WSA_RX1 INP1", "RX0", "WSA RX0"},
2708 {"WSA_RX1 INP1", "RX1", "WSA RX1"},
2709 {"WSA_RX1 INP1", "RX_MIX0", "WSA RX_MIX0"},
2710 {"WSA_RX1 INP1", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302711 {"WSA_RX1 INP1", "DEC0", "WSA_TX DEC0_INP"},
2712 {"WSA_RX1 INP1", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302713 {"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP1"},
2714
2715 {"WSA_RX1 INP2", "RX0", "WSA RX0"},
2716 {"WSA_RX1 INP2", "RX1", "WSA RX1"},
2717 {"WSA_RX1 INP2", "RX_MIX0", "WSA RX_MIX0"},
2718 {"WSA_RX1 INP2", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302719 {"WSA_RX1 INP2", "DEC0", "WSA_TX DEC0_INP"},
2720 {"WSA_RX1 INP2", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302721 {"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP2"},
2722
2723 {"WSA_RX1 MIX INP", "RX0", "WSA RX0"},
2724 {"WSA_RX1 MIX INP", "RX1", "WSA RX1"},
2725 {"WSA_RX1 MIX INP", "RX_MIX0", "WSA RX_MIX0"},
2726 {"WSA_RX1 MIX INP", "RX_MIX1", "WSA RX_MIX1"},
2727 {"WSA_RX INT1 SEC MIX", NULL, "WSA_RX1 MIX INP"},
2728
2729 {"WSA_RX INT1 SEC MIX", NULL, "WSA_RX INT1 MIX"},
2730 {"WSA_RX INT1 INTERP", NULL, "WSA_RX INT1 SEC MIX"},
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302731
2732 {"WSA_RX INT1 VBAT", "WSA RX1 VBAT Enable", "WSA_RX INT1 INTERP"},
2733 {"WSA_RX INT1 CHAIN", NULL, "WSA_RX INT1 VBAT"},
2734
Laxminath Kasam243e2752018-04-12 00:40:19 +05302735 {"WSA_RX INT1 CHAIN", NULL, "WSA_RX INT1 INTERP"},
2736 {"WSA_SPK2 OUT", NULL, "WSA_RX INT1 CHAIN"},
Laxminath Kasamfc281ad2018-08-06 20:19:40 +05302737 {"WSA_SPK2 OUT", NULL, "WSA_MCLK"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302738};
2739
2740static const struct wsa_macro_reg_mask_val wsa_macro_reg_init[] = {
2741 {BOLERO_CDC_WSA_BOOST0_BOOST_CFG1, 0x3F, 0x12},
2742 {BOLERO_CDC_WSA_BOOST0_BOOST_CFG2, 0x1C, 0x08},
2743 {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x1E, 0x18},
2744 {BOLERO_CDC_WSA_BOOST1_BOOST_CFG1, 0x3F, 0x12},
2745 {BOLERO_CDC_WSA_BOOST1_BOOST_CFG2, 0x1C, 0x08},
2746 {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x1E, 0x18},
2747 {BOLERO_CDC_WSA_BOOST0_BOOST_CTL, 0x70, 0x58},
2748 {BOLERO_CDC_WSA_BOOST1_BOOST_CTL, 0x70, 0x58},
2749 {BOLERO_CDC_WSA_RX0_RX_PATH_CFG1, 0x08, 0x08},
2750 {BOLERO_CDC_WSA_RX1_RX_PATH_CFG1, 0x08, 0x08},
2751 {BOLERO_CDC_WSA_TOP_TOP_CFG1, 0x02, 0x02},
2752 {BOLERO_CDC_WSA_TOP_TOP_CFG1, 0x01, 0x01},
2753 {BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
2754 {BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
2755 {BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
2756 {BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
2757 {BOLERO_CDC_WSA_COMPANDER0_CTL3, 0x80, 0x80},
2758 {BOLERO_CDC_WSA_COMPANDER1_CTL3, 0x80, 0x80},
2759 {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x01, 0x01},
2760 {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x01, 0x01},
2761 {BOLERO_CDC_WSA_RX0_RX_PATH_CFG0, 0x01, 0x01},
2762 {BOLERO_CDC_WSA_RX1_RX_PATH_CFG0, 0x01, 0x01},
2763 {BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CFG, 0x01, 0x01},
2764 {BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CFG, 0x01, 0x01},
2765};
2766
Meng Wang15c825d2018-09-06 10:49:18 +08002767static void wsa_macro_init_bcl_pmic_reg(struct snd_soc_component *component)
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302768{
2769 struct device *wsa_dev = NULL;
2770 struct wsa_macro_priv *wsa_priv = NULL;
2771
Meng Wang15c825d2018-09-06 10:49:18 +08002772 if (!component) {
2773 pr_err("%s: NULL component pointer!\n", __func__);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302774 return;
2775 }
2776
Meng Wang15c825d2018-09-06 10:49:18 +08002777 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302778 return;
2779
2780 switch (wsa_priv->bcl_pmic_params.id) {
2781 case 0:
2782 /* Enable ID0 to listen to respective PMIC group interrupts */
Meng Wang15c825d2018-09-06 10:49:18 +08002783 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302784 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CTL1, 0x02, 0x02);
2785 /* Update MC_SID0 */
Meng Wang15c825d2018-09-06 10:49:18 +08002786 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302787 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG1, 0x0F,
2788 wsa_priv->bcl_pmic_params.sid);
2789 /* Update MC_PPID0 */
Meng Wang15c825d2018-09-06 10:49:18 +08002790 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302791 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG2, 0xFF,
2792 wsa_priv->bcl_pmic_params.ppid);
2793 break;
2794 case 1:
2795 /* Enable ID1 to listen to respective PMIC group interrupts */
Meng Wang15c825d2018-09-06 10:49:18 +08002796 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302797 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CTL1, 0x01, 0x01);
2798 /* Update MC_SID1 */
Meng Wang15c825d2018-09-06 10:49:18 +08002799 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302800 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG3, 0x0F,
2801 wsa_priv->bcl_pmic_params.sid);
2802 /* Update MC_PPID1 */
Meng Wang15c825d2018-09-06 10:49:18 +08002803 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302804 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG4, 0xFF,
2805 wsa_priv->bcl_pmic_params.ppid);
2806 break;
2807 default:
2808 dev_err(wsa_dev, "%s: PMIC ID is invalid %d\n",
2809 __func__, wsa_priv->bcl_pmic_params.id);
2810 break;
2811 }
2812}
2813
Meng Wang15c825d2018-09-06 10:49:18 +08002814static void wsa_macro_init_reg(struct snd_soc_component *component)
Laxminath Kasam243e2752018-04-12 00:40:19 +05302815{
2816 int i;
2817
2818 for (i = 0; i < ARRAY_SIZE(wsa_macro_reg_init); i++)
Meng Wang15c825d2018-09-06 10:49:18 +08002819 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302820 wsa_macro_reg_init[i].reg,
2821 wsa_macro_reg_init[i].mask,
2822 wsa_macro_reg_init[i].val);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302823
Meng Wang15c825d2018-09-06 10:49:18 +08002824 wsa_macro_init_bcl_pmic_reg(component);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302825}
2826
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07002827static int wsa_macro_core_vote(void *handle, bool enable)
2828{
2829 struct wsa_macro_priv *wsa_priv = (struct wsa_macro_priv *) handle;
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07002830
2831 if (wsa_priv == NULL) {
2832 pr_err("%s: wsa priv data is NULL\n", __func__);
2833 return -EINVAL;
2834 }
2835 if (enable) {
2836 pm_runtime_get_sync(wsa_priv->dev);
2837 pm_runtime_put_autosuspend(wsa_priv->dev);
2838 pm_runtime_mark_last_busy(wsa_priv->dev);
2839 }
2840
Aditya Bavanarid577af92019-10-03 21:09:19 +05302841 if (bolero_check_core_votes(wsa_priv->dev))
2842 return 0;
2843 else
2844 return -EINVAL;
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07002845}
2846
Laxminath Kasam243e2752018-04-12 00:40:19 +05302847static int wsa_swrm_clock(void *handle, bool enable)
2848{
2849 struct wsa_macro_priv *wsa_priv = (struct wsa_macro_priv *) handle;
2850 struct regmap *regmap = dev_get_regmap(wsa_priv->dev->parent, NULL);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302851 int ret = 0;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302852
Tanya Dixitab8eba82018-10-05 15:07:37 +05302853 if (regmap == NULL) {
2854 dev_err(wsa_priv->dev, "%s: regmap is NULL\n", __func__);
2855 return -EINVAL;
2856 }
2857
Laxminath Kasam243e2752018-04-12 00:40:19 +05302858 mutex_lock(&wsa_priv->swr_clk_lock);
2859
Aditya Bavanarif500a1d2019-09-16 18:27:51 -07002860 trace_printk("%s: %s swrm clock %s\n",
2861 dev_name(wsa_priv->dev), __func__,
2862 (enable ? "enable" : "disable"));
Laxminath Kasam243e2752018-04-12 00:40:19 +05302863 dev_dbg(wsa_priv->dev, "%s: swrm clock %s\n",
2864 __func__, (enable ? "enable" : "disable"));
2865 if (enable) {
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302866 pm_runtime_get_sync(wsa_priv->dev);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302867 if (wsa_priv->swr_clk_users == 0) {
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07002868 ret = msm_cdc_pinctrl_select_active_state(
Karthikeyan Mani01f1ba42019-02-26 18:48:15 -08002869 wsa_priv->wsa_swr_gpio_p);
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07002870 if (ret < 0) {
2871 dev_err_ratelimited(wsa_priv->dev,
2872 "%s: wsa swr pinctrl enable failed\n",
2873 __func__);
2874 pm_runtime_mark_last_busy(wsa_priv->dev);
2875 pm_runtime_put_autosuspend(wsa_priv->dev);
2876 goto exit;
2877 }
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302878 ret = wsa_macro_mclk_enable(wsa_priv, 1, true);
2879 if (ret < 0) {
Karthikeyan Mani01f1ba42019-02-26 18:48:15 -08002880 msm_cdc_pinctrl_select_sleep_state(
2881 wsa_priv->wsa_swr_gpio_p);
Ramprasad Katkam14efed62019-03-07 13:16:50 +05302882 dev_err_ratelimited(wsa_priv->dev,
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302883 "%s: wsa request clock enable failed\n",
2884 __func__);
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07002885 pm_runtime_mark_last_busy(wsa_priv->dev);
2886 pm_runtime_put_autosuspend(wsa_priv->dev);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302887 goto exit;
2888 }
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05302889 if (wsa_priv->reset_swr)
2890 regmap_update_bits(regmap,
2891 BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
2892 0x02, 0x02);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302893 regmap_update_bits(regmap,
2894 BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
2895 0x01, 0x01);
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05302896 if (wsa_priv->reset_swr)
2897 regmap_update_bits(regmap,
2898 BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
2899 0x02, 0x00);
2900 wsa_priv->reset_swr = false;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302901 }
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07002902 wsa_priv->swr_clk_users++;
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302903 pm_runtime_mark_last_busy(wsa_priv->dev);
2904 pm_runtime_put_autosuspend(wsa_priv->dev);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302905 } else {
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302906 if (wsa_priv->swr_clk_users <= 0) {
2907 dev_err(wsa_priv->dev, "%s: clock already disabled\n",
2908 __func__);
2909 wsa_priv->swr_clk_users = 0;
2910 goto exit;
2911 }
Laxminath Kasam243e2752018-04-12 00:40:19 +05302912 wsa_priv->swr_clk_users--;
2913 if (wsa_priv->swr_clk_users == 0) {
2914 regmap_update_bits(regmap,
2915 BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
2916 0x01, 0x00);
Karthikeyan Mani01f1ba42019-02-26 18:48:15 -08002917 wsa_macro_mclk_enable(wsa_priv, 0, true);
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07002918 ret = msm_cdc_pinctrl_select_sleep_state(
Laxminath Kasam243e2752018-04-12 00:40:19 +05302919 wsa_priv->wsa_swr_gpio_p);
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07002920 if (ret < 0) {
2921 dev_err_ratelimited(wsa_priv->dev,
2922 "%s: wsa swr pinctrl disable failed\n",
2923 __func__);
2924 goto exit;
2925 }
Laxminath Kasam243e2752018-04-12 00:40:19 +05302926 }
2927 }
Aditya Bavanarif500a1d2019-09-16 18:27:51 -07002928 trace_printk("%s: %s swrm clock users: %d\n",
2929 dev_name(wsa_priv->dev), __func__,
2930 wsa_priv->swr_clk_users);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302931 dev_dbg(wsa_priv->dev, "%s: swrm clock users %d\n",
2932 __func__, wsa_priv->swr_clk_users);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302933exit:
Laxminath Kasam243e2752018-04-12 00:40:19 +05302934 mutex_unlock(&wsa_priv->swr_clk_lock);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302935 return ret;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302936}
2937
Meng Wang15c825d2018-09-06 10:49:18 +08002938static int wsa_macro_init(struct snd_soc_component *component)
Laxminath Kasam243e2752018-04-12 00:40:19 +05302939{
Meng Wang15c825d2018-09-06 10:49:18 +08002940 struct snd_soc_dapm_context *dapm =
2941 snd_soc_component_get_dapm(component);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302942 int ret;
2943 struct device *wsa_dev = NULL;
2944 struct wsa_macro_priv *wsa_priv = NULL;
2945
Meng Wang15c825d2018-09-06 10:49:18 +08002946 wsa_dev = bolero_get_device_ptr(component->dev, WSA_MACRO);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302947 if (!wsa_dev) {
Meng Wang15c825d2018-09-06 10:49:18 +08002948 dev_err(component->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302949 "%s: null device for macro!\n", __func__);
2950 return -EINVAL;
2951 }
2952 wsa_priv = dev_get_drvdata(wsa_dev);
2953 if (!wsa_priv) {
Meng Wang15c825d2018-09-06 10:49:18 +08002954 dev_err(component->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302955 "%s: priv is null for macro!\n", __func__);
2956 return -EINVAL;
2957 }
2958
2959 ret = snd_soc_dapm_new_controls(dapm, wsa_macro_dapm_widgets,
2960 ARRAY_SIZE(wsa_macro_dapm_widgets));
2961 if (ret < 0) {
2962 dev_err(wsa_dev, "%s: Failed to add controls\n", __func__);
2963 return ret;
2964 }
2965
2966 ret = snd_soc_dapm_add_routes(dapm, wsa_audio_map,
2967 ARRAY_SIZE(wsa_audio_map));
2968 if (ret < 0) {
2969 dev_err(wsa_dev, "%s: Failed to add routes\n", __func__);
2970 return ret;
2971 }
2972
2973 ret = snd_soc_dapm_new_widgets(dapm->card);
2974 if (ret < 0) {
2975 dev_err(wsa_dev, "%s: Failed to add widgets\n", __func__);
2976 return ret;
2977 }
2978
Meng Wang15c825d2018-09-06 10:49:18 +08002979 ret = snd_soc_add_component_controls(component, wsa_macro_snd_controls,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302980 ARRAY_SIZE(wsa_macro_snd_controls));
2981 if (ret < 0) {
2982 dev_err(wsa_dev, "%s: Failed to add snd_ctls\n", __func__);
2983 return ret;
2984 }
Laxminath Kasam638b5602018-09-24 13:19:52 +05302985 snd_soc_dapm_ignore_suspend(dapm, "WSA_AIF1 Playback");
2986 snd_soc_dapm_ignore_suspend(dapm, "WSA_AIF_MIX1 Playback");
2987 snd_soc_dapm_ignore_suspend(dapm, "WSA_AIF_VI Capture");
2988 snd_soc_dapm_ignore_suspend(dapm, "WSA_AIF_ECHO Capture");
2989 snd_soc_dapm_ignore_suspend(dapm, "WSA_SPK1 OUT");
2990 snd_soc_dapm_ignore_suspend(dapm, "WSA_SPK2 OUT");
2991 snd_soc_dapm_ignore_suspend(dapm, "VIINPUT_WSA");
2992 snd_soc_dapm_ignore_suspend(dapm, "WSA SRC0_INP");
2993 snd_soc_dapm_ignore_suspend(dapm, "WSA_TX DEC0_INP");
2994 snd_soc_dapm_ignore_suspend(dapm, "WSA_TX DEC1_INP");
2995 snd_soc_dapm_sync(dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302996
Meng Wang15c825d2018-09-06 10:49:18 +08002997 wsa_priv->component = component;
Laxminath Kasam21c8b222018-06-21 18:47:22 +05302998 wsa_priv->spkr_gain_offset = WSA_MACRO_GAIN_OFFSET_0_DB;
Meng Wang15c825d2018-09-06 10:49:18 +08002999 wsa_macro_init_reg(component);
Laxminath Kasam243e2752018-04-12 00:40:19 +05303000
3001 return 0;
3002}
3003
Meng Wang15c825d2018-09-06 10:49:18 +08003004static int wsa_macro_deinit(struct snd_soc_component *component)
Laxminath Kasam243e2752018-04-12 00:40:19 +05303005{
3006 struct device *wsa_dev = NULL;
3007 struct wsa_macro_priv *wsa_priv = NULL;
3008
Meng Wang15c825d2018-09-06 10:49:18 +08003009 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05303010 return -EINVAL;
3011
Meng Wang15c825d2018-09-06 10:49:18 +08003012 wsa_priv->component = NULL;
Laxminath Kasam243e2752018-04-12 00:40:19 +05303013
3014 return 0;
3015}
3016
3017static void wsa_macro_add_child_devices(struct work_struct *work)
3018{
3019 struct wsa_macro_priv *wsa_priv;
3020 struct platform_device *pdev;
3021 struct device_node *node;
3022 struct wsa_macro_swr_ctrl_data *swr_ctrl_data = NULL, *temp;
3023 int ret;
3024 u16 count = 0, ctrl_num = 0;
3025 struct wsa_macro_swr_ctrl_platform_data *platdata;
3026 char plat_dev_name[WSA_MACRO_SWR_STRING_LEN];
3027
3028 wsa_priv = container_of(work, struct wsa_macro_priv,
3029 wsa_macro_add_child_devices_work);
3030 if (!wsa_priv) {
3031 pr_err("%s: Memory for wsa_priv does not exist\n",
3032 __func__);
3033 return;
3034 }
Laxminath Kasam21c8b222018-06-21 18:47:22 +05303035 if (!wsa_priv->dev || !wsa_priv->dev->of_node) {
Laxminath Kasam243e2752018-04-12 00:40:19 +05303036 dev_err(wsa_priv->dev,
3037 "%s: DT node for wsa_priv does not exist\n", __func__);
3038 return;
3039 }
3040
3041 platdata = &wsa_priv->swr_plat_data;
3042 wsa_priv->child_count = 0;
3043
3044 for_each_available_child_of_node(wsa_priv->dev->of_node, node) {
3045 if (strnstr(node->name, "wsa_swr_master",
3046 strlen("wsa_swr_master")) != NULL)
3047 strlcpy(plat_dev_name, "wsa_swr_ctrl",
3048 (WSA_MACRO_SWR_STRING_LEN - 1));
3049 else if (strnstr(node->name, "msm_cdc_pinctrl",
3050 strlen("msm_cdc_pinctrl")) != NULL)
3051 strlcpy(plat_dev_name, node->name,
3052 (WSA_MACRO_SWR_STRING_LEN - 1));
3053 else
3054 continue;
3055
3056 pdev = platform_device_alloc(plat_dev_name, -1);
3057 if (!pdev) {
3058 dev_err(wsa_priv->dev, "%s: pdev memory alloc failed\n",
3059 __func__);
3060 ret = -ENOMEM;
3061 goto err;
3062 }
3063 pdev->dev.parent = wsa_priv->dev;
3064 pdev->dev.of_node = node;
3065
3066 if (strnstr(node->name, "wsa_swr_master",
3067 strlen("wsa_swr_master")) != NULL) {
3068 ret = platform_device_add_data(pdev, platdata,
3069 sizeof(*platdata));
3070 if (ret) {
3071 dev_err(&pdev->dev,
3072 "%s: cannot add plat data ctrl:%d\n",
3073 __func__, ctrl_num);
3074 goto fail_pdev_add;
3075 }
3076 }
3077
3078 ret = platform_device_add(pdev);
3079 if (ret) {
3080 dev_err(&pdev->dev,
3081 "%s: Cannot add platform device\n",
3082 __func__);
3083 goto fail_pdev_add;
3084 }
3085
3086 if (!strcmp(node->name, "wsa_swr_master")) {
3087 temp = krealloc(swr_ctrl_data,
3088 (ctrl_num + 1) * sizeof(
3089 struct wsa_macro_swr_ctrl_data),
3090 GFP_KERNEL);
3091 if (!temp) {
3092 dev_err(&pdev->dev, "out of memory\n");
3093 ret = -ENOMEM;
3094 goto err;
3095 }
3096 swr_ctrl_data = temp;
3097 swr_ctrl_data[ctrl_num].wsa_swr_pdev = pdev;
3098 ctrl_num++;
3099 dev_dbg(&pdev->dev,
3100 "%s: Added soundwire ctrl device(s)\n",
3101 __func__);
3102 wsa_priv->swr_ctrl_data = swr_ctrl_data;
3103 }
3104 if (wsa_priv->child_count < WSA_MACRO_CHILD_DEVICES_MAX)
3105 wsa_priv->pdev_child_devices[
3106 wsa_priv->child_count++] = pdev;
3107 else
3108 goto err;
3109 }
3110
3111 return;
3112fail_pdev_add:
3113 for (count = 0; count < wsa_priv->child_count; count++)
3114 platform_device_put(wsa_priv->pdev_child_devices[count]);
3115err:
3116 return;
3117}
3118
3119static void wsa_macro_init_ops(struct macro_ops *ops,
3120 char __iomem *wsa_io_base)
3121{
3122 memset(ops, 0, sizeof(struct macro_ops));
3123 ops->init = wsa_macro_init;
3124 ops->exit = wsa_macro_deinit;
3125 ops->io_base = wsa_io_base;
3126 ops->dai_ptr = wsa_macro_dai;
3127 ops->num_dais = ARRAY_SIZE(wsa_macro_dai);
Laxminath Kasamfb0d6832018-09-22 01:49:52 +05303128 ops->event_handler = wsa_macro_event_handler;
Sudheer Papothia3e969d2018-10-27 06:22:10 +05303129 ops->set_port_map = wsa_macro_set_port_map;
Laxminath Kasam243e2752018-04-12 00:40:19 +05303130}
3131
3132static int wsa_macro_probe(struct platform_device *pdev)
3133{
3134 struct macro_ops ops;
3135 struct wsa_macro_priv *wsa_priv;
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07003136 u32 wsa_base_addr, default_clk_id;
Laxminath Kasam243e2752018-04-12 00:40:19 +05303137 char __iomem *wsa_io_base;
3138 int ret = 0;
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303139 u8 bcl_pmic_params[3];
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07003140 u32 is_used_wsa_swr_gpio = 1;
3141 const char *is_used_wsa_swr_gpio_dt = "qcom,is-used-swr-gpio";
Laxminath Kasam243e2752018-04-12 00:40:19 +05303142
3143 wsa_priv = devm_kzalloc(&pdev->dev, sizeof(struct wsa_macro_priv),
3144 GFP_KERNEL);
3145 if (!wsa_priv)
3146 return -ENOMEM;
3147
3148 wsa_priv->dev = &pdev->dev;
3149 ret = of_property_read_u32(pdev->dev.of_node, "reg",
3150 &wsa_base_addr);
3151 if (ret) {
3152 dev_err(&pdev->dev, "%s: could not find %s entry in dt\n",
3153 __func__, "reg");
3154 return ret;
3155 }
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07003156 if (of_find_property(pdev->dev.of_node, is_used_wsa_swr_gpio_dt,
3157 NULL)) {
3158 ret = of_property_read_u32(pdev->dev.of_node,
3159 is_used_wsa_swr_gpio_dt,
3160 &is_used_wsa_swr_gpio);
3161 if (ret) {
3162 dev_err(&pdev->dev, "%s: error reading %s in dt\n",
3163 __func__, is_used_wsa_swr_gpio_dt);
3164 is_used_wsa_swr_gpio = 1;
3165 }
3166 }
Laxminath Kasam243e2752018-04-12 00:40:19 +05303167 wsa_priv->wsa_swr_gpio_p = of_parse_phandle(pdev->dev.of_node,
3168 "qcom,wsa-swr-gpios", 0);
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07003169 if (!wsa_priv->wsa_swr_gpio_p && is_used_wsa_swr_gpio) {
Laxminath Kasam243e2752018-04-12 00:40:19 +05303170 dev_err(&pdev->dev, "%s: swr_gpios handle not provided!\n",
3171 __func__);
3172 return -EINVAL;
3173 }
Karthikeyan Manib44e4552019-09-09 23:06:04 -07003174 if (msm_cdc_pinctrl_get_state(wsa_priv->wsa_swr_gpio_p) < 0 &&
3175 is_used_wsa_swr_gpio) {
Karthikeyan Mani326536d2019-06-03 13:29:43 -07003176 dev_err(&pdev->dev, "%s: failed to get swr pin state\n",
3177 __func__);
3178 return -EPROBE_DEFER;
3179 }
3180
Laxminath Kasam243e2752018-04-12 00:40:19 +05303181 wsa_io_base = devm_ioremap(&pdev->dev,
3182 wsa_base_addr, WSA_MACRO_MAX_OFFSET);
3183 if (!wsa_io_base) {
3184 dev_err(&pdev->dev, "%s: ioremap failed\n", __func__);
3185 return -EINVAL;
3186 }
3187 wsa_priv->wsa_io_base = wsa_io_base;
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05303188 wsa_priv->reset_swr = true;
Laxminath Kasam243e2752018-04-12 00:40:19 +05303189 INIT_WORK(&wsa_priv->wsa_macro_add_child_devices_work,
3190 wsa_macro_add_child_devices);
3191 wsa_priv->swr_plat_data.handle = (void *) wsa_priv;
3192 wsa_priv->swr_plat_data.read = NULL;
3193 wsa_priv->swr_plat_data.write = NULL;
3194 wsa_priv->swr_plat_data.bulk_write = NULL;
3195 wsa_priv->swr_plat_data.clk = wsa_swrm_clock;
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07003196 wsa_priv->swr_plat_data.core_vote = wsa_macro_core_vote;
Laxminath Kasam243e2752018-04-12 00:40:19 +05303197 wsa_priv->swr_plat_data.handle_irq = NULL;
Laxminath Kasamea6cbee2020-04-28 00:02:32 +05303198 wsa_priv->swr_plat_data.pinctrl_setup = NULL;
Laxminath Kasam243e2752018-04-12 00:40:19 +05303199
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07003200 ret = of_property_read_u32(pdev->dev.of_node, "qcom,default-clk-id",
3201 &default_clk_id);
3202 if (ret) {
3203 dev_err(&pdev->dev, "%s: could not find %s entry in dt\n",
3204 __func__, "qcom,mux0-clk-id");
3205 default_clk_id = WSA_CORE_CLK;
Laxminath Kasam243e2752018-04-12 00:40:19 +05303206 }
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303207
3208 ret = of_property_read_u8_array(pdev->dev.of_node,
3209 "qcom,wsa-bcl-pmic-params", bcl_pmic_params,
3210 sizeof(bcl_pmic_params));
3211 if (ret) {
3212 dev_dbg(&pdev->dev, "%s: could not find %s entry in dt\n",
3213 __func__, "qcom,wsa-bcl-pmic-params");
3214 } else {
3215 wsa_priv->bcl_pmic_params.id = bcl_pmic_params[0];
3216 wsa_priv->bcl_pmic_params.sid = bcl_pmic_params[1];
3217 wsa_priv->bcl_pmic_params.ppid = bcl_pmic_params[2];
3218 }
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07003219 wsa_priv->default_clk_id = default_clk_id;
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303220
Laxminath Kasam243e2752018-04-12 00:40:19 +05303221 dev_set_drvdata(&pdev->dev, wsa_priv);
3222 mutex_init(&wsa_priv->mclk_lock);
3223 mutex_init(&wsa_priv->swr_clk_lock);
3224 wsa_macro_init_ops(&ops, wsa_io_base);
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07003225 ops.clk_id_req = wsa_priv->default_clk_id;
3226 ops.default_clk_id = wsa_priv->default_clk_id;
Laxminath Kasam243e2752018-04-12 00:40:19 +05303227 ret = bolero_register_macro(&pdev->dev, WSA_MACRO, &ops);
3228 if (ret < 0) {
3229 dev_err(&pdev->dev, "%s: register macro failed\n", __func__);
3230 goto reg_macro_fail;
3231 }
3232 schedule_work(&wsa_priv->wsa_macro_add_child_devices_work);
Sudheer Papothi7601cc62019-03-30 03:00:52 +05303233 pm_runtime_set_autosuspend_delay(&pdev->dev, AUTO_SUSPEND_DELAY);
3234 pm_runtime_use_autosuspend(&pdev->dev);
3235 pm_runtime_set_suspended(&pdev->dev);
Karthikeyan Mani3d209512019-10-03 13:51:53 -07003236 pm_suspend_ignore_children(&pdev->dev, true);
Sudheer Papothi7601cc62019-03-30 03:00:52 +05303237 pm_runtime_enable(&pdev->dev);
3238
Laxminath Kasam243e2752018-04-12 00:40:19 +05303239 return ret;
3240reg_macro_fail:
3241 mutex_destroy(&wsa_priv->mclk_lock);
3242 mutex_destroy(&wsa_priv->swr_clk_lock);
3243 return ret;
3244}
3245
3246static int wsa_macro_remove(struct platform_device *pdev)
3247{
3248 struct wsa_macro_priv *wsa_priv;
3249 u16 count = 0;
3250
3251 wsa_priv = dev_get_drvdata(&pdev->dev);
3252
3253 if (!wsa_priv)
3254 return -EINVAL;
3255
3256 for (count = 0; count < wsa_priv->child_count &&
3257 count < WSA_MACRO_CHILD_DEVICES_MAX; count++)
3258 platform_device_unregister(wsa_priv->pdev_child_devices[count]);
3259
Sudheer Papothi7601cc62019-03-30 03:00:52 +05303260 pm_runtime_disable(&pdev->dev);
3261 pm_runtime_set_suspended(&pdev->dev);
Laxminath Kasam243e2752018-04-12 00:40:19 +05303262 bolero_unregister_macro(&pdev->dev, WSA_MACRO);
3263 mutex_destroy(&wsa_priv->mclk_lock);
3264 mutex_destroy(&wsa_priv->swr_clk_lock);
3265 return 0;
3266}
3267
3268static const struct of_device_id wsa_macro_dt_match[] = {
3269 {.compatible = "qcom,wsa-macro"},
3270 {}
3271};
3272
Sudheer Papothi7601cc62019-03-30 03:00:52 +05303273static const struct dev_pm_ops bolero_dev_pm_ops = {
Aditya Bavanari4460ed22020-02-20 12:46:51 +05303274 SET_SYSTEM_SLEEP_PM_OPS(
3275 pm_runtime_force_suspend,
3276 pm_runtime_force_resume
3277 )
Sudheer Papothi7601cc62019-03-30 03:00:52 +05303278 SET_RUNTIME_PM_OPS(
3279 bolero_runtime_suspend,
3280 bolero_runtime_resume,
3281 NULL
3282 )
3283};
3284
Laxminath Kasam243e2752018-04-12 00:40:19 +05303285static struct platform_driver wsa_macro_driver = {
3286 .driver = {
3287 .name = "wsa_macro",
3288 .owner = THIS_MODULE,
Sudheer Papothi7601cc62019-03-30 03:00:52 +05303289 .pm = &bolero_dev_pm_ops,
Laxminath Kasam243e2752018-04-12 00:40:19 +05303290 .of_match_table = wsa_macro_dt_match,
Xiaojun Sang53cd13a2018-06-29 15:14:37 +08003291 .suppress_bind_attrs = true,
Laxminath Kasam243e2752018-04-12 00:40:19 +05303292 },
3293 .probe = wsa_macro_probe,
3294 .remove = wsa_macro_remove,
3295};
3296
3297module_platform_driver(wsa_macro_driver);
3298
3299MODULE_DESCRIPTION("WSA macro driver");
3300MODULE_LICENSE("GPL v2");