blob: 4e06d12bea90ef38a423f80da59ddf8ea0537b82 [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);
169};
170
Aditya Bavanari4f3d5642018-09-18 22:19:10 +0530171struct wsa_macro_bcl_pmic_params {
172 u8 id;
173 u8 sid;
174 u8 ppid;
175};
176
Laxminath Kasam243e2752018-04-12 00:40:19 +0530177enum {
Laxminath Kasam59c7a1d2018-08-09 16:11:17 +0530178 WSA_MACRO_AIF_INVALID = 0,
179 WSA_MACRO_AIF1_PB,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530180 WSA_MACRO_AIF_MIX1_PB,
181 WSA_MACRO_AIF_VI,
182 WSA_MACRO_AIF_ECHO,
183 WSA_MACRO_MAX_DAIS,
184};
185
186#define WSA_MACRO_CHILD_DEVICES_MAX 3
187
188/*
189 * @dev: wsa macro device pointer
190 * @comp_enabled: compander enable mixer value set
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +0530191 * @ec_hq: echo HQ enable mixer value set
Laxminath Kasam243e2752018-04-12 00:40:19 +0530192 * @prim_int_users: Users of interpolator
193 * @wsa_mclk_users: WSA MCLK users count
194 * @swr_clk_users: SWR clk users count
195 * @vi_feed_value: VI sense mask
196 * @mclk_lock: to lock mclk operations
197 * @swr_clk_lock: to lock swr master clock operations
198 * @swr_ctrl_data: SoundWire data structure
199 * @swr_plat_data: Soundwire platform data
200 * @wsa_macro_add_child_devices_work: work for adding child devices
201 * @wsa_swr_gpio_p: used by pinctrl API
Meng Wang15c825d2018-09-06 10:49:18 +0800202 * @component: codec handle
Laxminath Kasam243e2752018-04-12 00:40:19 +0530203 * @rx_0_count: RX0 interpolation users
204 * @rx_1_count: RX1 interpolation users
205 * @active_ch_mask: channel mask for all AIF DAIs
206 * @active_ch_cnt: channel count of all AIF DAIs
207 * @rx_port_value: mixer ctl value of WSA RX MUXes
208 * @wsa_io_base: Base address of WSA macro addr space
209 */
210struct wsa_macro_priv {
211 struct device *dev;
212 int comp_enabled[WSA_MACRO_COMP_MAX];
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +0530213 int ec_hq[WSA_MACRO_RX1 + 1];
Laxminath Kasam243e2752018-04-12 00:40:19 +0530214 u16 prim_int_users[WSA_MACRO_RX1 + 1];
215 u16 wsa_mclk_users;
216 u16 swr_clk_users;
Ramprasad Katkam452772a2019-01-07 17:30:36 +0530217 bool dapm_mclk_enable;
Ramprasad Katkama4c747b2018-12-11 19:15:53 +0530218 bool reset_swr;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530219 unsigned int vi_feed_value;
220 struct mutex mclk_lock;
221 struct mutex swr_clk_lock;
222 struct wsa_macro_swr_ctrl_data *swr_ctrl_data;
223 struct wsa_macro_swr_ctrl_platform_data swr_plat_data;
224 struct work_struct wsa_macro_add_child_devices_work;
225 struct device_node *wsa_swr_gpio_p;
Meng Wang15c825d2018-09-06 10:49:18 +0800226 struct snd_soc_component *component;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530227 int rx_0_count;
228 int rx_1_count;
229 unsigned long active_ch_mask[WSA_MACRO_MAX_DAIS];
230 unsigned long active_ch_cnt[WSA_MACRO_MAX_DAIS];
231 int rx_port_value[WSA_MACRO_RX_MAX];
232 char __iomem *wsa_io_base;
233 struct platform_device *pdev_child_devices
234 [WSA_MACRO_CHILD_DEVICES_MAX];
235 int child_count;
236 int ear_spkr_gain;
237 int spkr_gain_offset;
238 int spkr_mode;
Aditya Bavanari4f3d5642018-09-18 22:19:10 +0530239 int is_softclip_on[WSA_MACRO_SOFTCLIP_MAX];
240 int softclip_clk_users[WSA_MACRO_SOFTCLIP_MAX];
241 struct wsa_macro_bcl_pmic_params bcl_pmic_params;
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -0700242 char __iomem *mclk_mode_muxsel;
243 u16 default_clk_id;
Laxminath Kasam007d2522020-04-23 11:00:44 +0530244 u32 pcm_rate_vi;
Vatsal Buchaf2a71b62019-03-26 16:14:40 +0530245 int wsa_digital_mute_status[WSA_MACRO_RX_MAX];
Laxminath Kasam243e2752018-04-12 00:40:19 +0530246};
247
Meng Wang15c825d2018-09-06 10:49:18 +0800248static int wsa_macro_config_ear_spkr_gain(struct snd_soc_component *component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530249 struct wsa_macro_priv *wsa_priv,
250 int event, int gain_reg);
251static struct snd_soc_dai_driver wsa_macro_dai[];
252static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0);
253
254static const char *const rx_text[] = {
255 "ZERO", "RX0", "RX1", "RX_MIX0", "RX_MIX1", "DEC0", "DEC1"
256};
257
258static const char *const rx_mix_text[] = {
259 "ZERO", "RX0", "RX1", "RX_MIX0", "RX_MIX1"
260};
261
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +0530262static const char *const rx_mix_ec_text[] = {
263 "ZERO", "RX_MIX_TX0", "RX_MIX_TX1"
264};
265
Laxminath Kasam243e2752018-04-12 00:40:19 +0530266static const char *const rx_mux_text[] = {
267 "ZERO", "AIF1_PB", "AIF_MIX1_PB"
268};
269
Laxminath Kasam6fc2e742018-08-26 23:32:57 +0530270static const char *const rx_sidetone_mix_text[] = {
271 "ZERO", "SRC0"
272};
273
Laxminath Kasam243e2752018-04-12 00:40:19 +0530274static const char * const wsa_macro_ear_spkr_pa_gain_text[] = {
275 "G_DEFAULT", "G_0_DB", "G_1_DB", "G_2_DB", "G_3_DB",
276 "G_4_DB", "G_5_DB", "G_6_DB"
277};
278
279static const char * const wsa_macro_speaker_boost_stage_text[] = {
280 "NO_MAX_STATE", "MAX_STATE_1", "MAX_STATE_2"
281};
282
Aditya Bavanari4f3d5642018-09-18 22:19:10 +0530283static const char * const wsa_macro_vbat_bcl_gsm_mode_text[] = {
284 "OFF", "ON"
285};
286
287static const struct snd_kcontrol_new wsa_int0_vbat_mix_switch[] = {
288 SOC_DAPM_SINGLE("WSA RX0 VBAT Enable", SND_SOC_NOPM, 0, 1, 0)
289};
290
291static const struct snd_kcontrol_new wsa_int1_vbat_mix_switch[] = {
292 SOC_DAPM_SINGLE("WSA RX1 VBAT Enable", SND_SOC_NOPM, 0, 1, 0)
293};
294
Laxminath Kasam243e2752018-04-12 00:40:19 +0530295static SOC_ENUM_SINGLE_EXT_DECL(wsa_macro_ear_spkr_pa_gain_enum,
296 wsa_macro_ear_spkr_pa_gain_text);
297static SOC_ENUM_SINGLE_EXT_DECL(wsa_macro_spkr_boost_stage_enum,
298 wsa_macro_speaker_boost_stage_text);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +0530299static SOC_ENUM_SINGLE_EXT_DECL(wsa_macro_vbat_bcl_gsm_mode_enum,
300 wsa_macro_vbat_bcl_gsm_mode_text);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530301
302/* RX INT0 */
303static const struct soc_enum rx0_prim_inp0_chain_enum =
304 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0,
305 0, 7, rx_text);
306
307static const struct soc_enum rx0_prim_inp1_chain_enum =
308 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0,
309 3, 7, rx_text);
310
311static const struct soc_enum rx0_prim_inp2_chain_enum =
312 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG1,
313 3, 7, rx_text);
314
315static const struct soc_enum rx0_mix_chain_enum =
316 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG1,
317 0, 5, rx_mix_text);
318
Laxminath Kasam6fc2e742018-08-26 23:32:57 +0530319static const struct soc_enum rx0_sidetone_mix_enum =
320 SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, 2, rx_sidetone_mix_text);
321
Laxminath Kasam243e2752018-04-12 00:40:19 +0530322static const struct snd_kcontrol_new rx0_prim_inp0_mux =
323 SOC_DAPM_ENUM("WSA_RX0 INP0 Mux", rx0_prim_inp0_chain_enum);
324
325static const struct snd_kcontrol_new rx0_prim_inp1_mux =
326 SOC_DAPM_ENUM("WSA_RX0 INP1 Mux", rx0_prim_inp1_chain_enum);
327
328static const struct snd_kcontrol_new rx0_prim_inp2_mux =
329 SOC_DAPM_ENUM("WSA_RX0 INP2 Mux", rx0_prim_inp2_chain_enum);
330
331static const struct snd_kcontrol_new rx0_mix_mux =
332 SOC_DAPM_ENUM("WSA_RX0 MIX Mux", rx0_mix_chain_enum);
333
Laxminath Kasam6fc2e742018-08-26 23:32:57 +0530334static const struct snd_kcontrol_new rx0_sidetone_mix_mux =
335 SOC_DAPM_ENUM("WSA_RX0 SIDETONE MIX Mux", rx0_sidetone_mix_enum);
336
Laxminath Kasam243e2752018-04-12 00:40:19 +0530337/* RX INT1 */
338static const struct soc_enum rx1_prim_inp0_chain_enum =
339 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT1_CFG0,
340 0, 7, rx_text);
341
342static const struct soc_enum rx1_prim_inp1_chain_enum =
343 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT1_CFG0,
344 3, 7, rx_text);
345
346static const struct soc_enum rx1_prim_inp2_chain_enum =
347 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT1_CFG1,
348 3, 7, rx_text);
349
350static const struct soc_enum rx1_mix_chain_enum =
351 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT1_CFG1,
352 0, 5, rx_mix_text);
353
354static const struct snd_kcontrol_new rx1_prim_inp0_mux =
355 SOC_DAPM_ENUM("WSA_RX1 INP0 Mux", rx1_prim_inp0_chain_enum);
356
357static const struct snd_kcontrol_new rx1_prim_inp1_mux =
358 SOC_DAPM_ENUM("WSA_RX1 INP1 Mux", rx1_prim_inp1_chain_enum);
359
360static const struct snd_kcontrol_new rx1_prim_inp2_mux =
361 SOC_DAPM_ENUM("WSA_RX1 INP2 Mux", rx1_prim_inp2_chain_enum);
362
363static const struct snd_kcontrol_new rx1_mix_mux =
364 SOC_DAPM_ENUM("WSA_RX1 MIX Mux", rx1_mix_chain_enum);
365
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +0530366static const struct soc_enum rx_mix_ec0_enum =
367 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0,
368 0, 3, rx_mix_ec_text);
369
370static const struct soc_enum rx_mix_ec1_enum =
371 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0,
372 3, 3, rx_mix_ec_text);
373
374static const struct snd_kcontrol_new rx_mix_ec0_mux =
375 SOC_DAPM_ENUM("WSA RX_MIX EC0_Mux", rx_mix_ec0_enum);
376
377static const struct snd_kcontrol_new rx_mix_ec1_mux =
378 SOC_DAPM_ENUM("WSA RX_MIX EC1_Mux", rx_mix_ec1_enum);
379
Laxminath Kasam243e2752018-04-12 00:40:19 +0530380static struct snd_soc_dai_ops wsa_macro_dai_ops = {
381 .hw_params = wsa_macro_hw_params,
382 .get_channel_map = wsa_macro_get_channel_map,
Laxminath Kasam52ae6582019-08-08 18:00:35 +0530383 .digital_mute = wsa_macro_digital_mute,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530384};
385
386static struct snd_soc_dai_driver wsa_macro_dai[] = {
387 {
388 .name = "wsa_macro_rx1",
389 .id = WSA_MACRO_AIF1_PB,
390 .playback = {
391 .stream_name = "WSA_AIF1 Playback",
392 .rates = WSA_MACRO_RX_RATES,
393 .formats = WSA_MACRO_RX_FORMATS,
394 .rate_max = 384000,
395 .rate_min = 8000,
396 .channels_min = 1,
397 .channels_max = 2,
398 },
399 .ops = &wsa_macro_dai_ops,
400 },
401 {
402 .name = "wsa_macro_rx_mix",
403 .id = WSA_MACRO_AIF_MIX1_PB,
404 .playback = {
405 .stream_name = "WSA_AIF_MIX1 Playback",
406 .rates = WSA_MACRO_RX_MIX_RATES,
407 .formats = WSA_MACRO_RX_FORMATS,
408 .rate_max = 192000,
409 .rate_min = 48000,
410 .channels_min = 1,
411 .channels_max = 2,
412 },
413 .ops = &wsa_macro_dai_ops,
414 },
415 {
416 .name = "wsa_macro_vifeedback",
417 .id = WSA_MACRO_AIF_VI,
418 .capture = {
419 .stream_name = "WSA_AIF_VI Capture",
Vatsal Buchad1b694d2018-08-31 11:47:32 +0530420 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000,
421 .formats = WSA_MACRO_RX_FORMATS,
422 .rate_max = 48000,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530423 .rate_min = 8000,
424 .channels_min = 1,
Vatsal Buchad1b694d2018-08-31 11:47:32 +0530425 .channels_max = 4,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530426 },
427 .ops = &wsa_macro_dai_ops,
428 },
429 {
430 .name = "wsa_macro_echo",
431 .id = WSA_MACRO_AIF_ECHO,
432 .capture = {
433 .stream_name = "WSA_AIF_ECHO Capture",
434 .rates = WSA_MACRO_ECHO_RATES,
435 .formats = WSA_MACRO_ECHO_FORMATS,
436 .rate_max = 48000,
437 .rate_min = 8000,
438 .channels_min = 1,
439 .channels_max = 2,
440 },
441 .ops = &wsa_macro_dai_ops,
442 },
443};
444
445static const struct wsa_macro_reg_mask_val wsa_macro_spkr_default[] = {
446 {BOLERO_CDC_WSA_COMPANDER0_CTL3, 0x80, 0x80},
447 {BOLERO_CDC_WSA_COMPANDER1_CTL3, 0x80, 0x80},
Sudheer Papothi44f2b862020-03-28 10:03:21 +0530448 {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x1F, 0x19},
449 {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x1F, 0x19},
Laxminath Kasam243e2752018-04-12 00:40:19 +0530450 {BOLERO_CDC_WSA_BOOST0_BOOST_CTL, 0x7C, 0x58},
451 {BOLERO_CDC_WSA_BOOST1_BOOST_CTL, 0x7C, 0x58},
452};
453
454static const struct wsa_macro_reg_mask_val wsa_macro_spkr_mode1[] = {
455 {BOLERO_CDC_WSA_COMPANDER0_CTL3, 0x80, 0x00},
456 {BOLERO_CDC_WSA_COMPANDER1_CTL3, 0x80, 0x00},
Sudheer Papothi44f2b862020-03-28 10:03:21 +0530457 {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x1F, 0x18},
458 {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x1F, 0x18},
Laxminath Kasam243e2752018-04-12 00:40:19 +0530459 {BOLERO_CDC_WSA_BOOST0_BOOST_CTL, 0x7C, 0x44},
460 {BOLERO_CDC_WSA_BOOST1_BOOST_CTL, 0x7C, 0x44},
461};
462
Meng Wang15c825d2018-09-06 10:49:18 +0800463static bool wsa_macro_get_data(struct snd_soc_component *component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530464 struct device **wsa_dev,
465 struct wsa_macro_priv **wsa_priv,
466 const char *func_name)
467{
Meng Wang15c825d2018-09-06 10:49:18 +0800468 *wsa_dev = bolero_get_device_ptr(component->dev, WSA_MACRO);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530469 if (!(*wsa_dev)) {
Meng Wang15c825d2018-09-06 10:49:18 +0800470 dev_err(component->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530471 "%s: null device for macro!\n", func_name);
472 return false;
473 }
474 *wsa_priv = dev_get_drvdata((*wsa_dev));
Meng Wang15c825d2018-09-06 10:49:18 +0800475 if (!(*wsa_priv) || !(*wsa_priv)->component) {
476 dev_err(component->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530477 "%s: priv is null for macro!\n", func_name);
478 return false;
479 }
480 return true;
481}
482
Sudheer Papothia3e969d2018-10-27 06:22:10 +0530483static int wsa_macro_set_port_map(struct snd_soc_component *component,
484 u32 usecase, u32 size, void *data)
485{
486 struct device *wsa_dev = NULL;
487 struct wsa_macro_priv *wsa_priv = NULL;
488 struct swrm_port_config port_cfg;
489 int ret = 0;
490
491 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
492 return -EINVAL;
493
494 memset(&port_cfg, 0, sizeof(port_cfg));
495 port_cfg.uc = usecase;
496 port_cfg.size = size;
497 port_cfg.params = data;
498
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -0700499 if (wsa_priv->swr_ctrl_data)
500 ret = swrm_wcd_notify(
501 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
502 SWR_SET_PORT_MAP, &port_cfg);
Sudheer Papothia3e969d2018-10-27 06:22:10 +0530503
504 return ret;
505}
506
Laxminath Kasam243e2752018-04-12 00:40:19 +0530507/**
508 * wsa_macro_set_spkr_gain_offset - offset the speaker path
509 * gain with the given offset value.
510 *
Meng Wang15c825d2018-09-06 10:49:18 +0800511 * @component: codec instance
Laxminath Kasam243e2752018-04-12 00:40:19 +0530512 * @offset: Indicates speaker path gain offset value.
513 *
514 * Returns 0 on success or -EINVAL on error.
515 */
Meng Wang15c825d2018-09-06 10:49:18 +0800516int wsa_macro_set_spkr_gain_offset(struct snd_soc_component *component,
517 int offset)
Laxminath Kasam243e2752018-04-12 00:40:19 +0530518{
519 struct device *wsa_dev = NULL;
520 struct wsa_macro_priv *wsa_priv = NULL;
521
Meng Wang15c825d2018-09-06 10:49:18 +0800522 if (!component) {
523 pr_err("%s: NULL component pointer!\n", __func__);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530524 return -EINVAL;
525 }
526
Meng Wang15c825d2018-09-06 10:49:18 +0800527 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530528 return -EINVAL;
529
530 wsa_priv->spkr_gain_offset = offset;
531 return 0;
532}
533EXPORT_SYMBOL(wsa_macro_set_spkr_gain_offset);
534
535/**
536 * wsa_macro_set_spkr_mode - Configures speaker compander and smartboost
537 * settings based on speaker mode.
538 *
Meng Wang15c825d2018-09-06 10:49:18 +0800539 * @component: codec instance
Laxminath Kasam243e2752018-04-12 00:40:19 +0530540 * @mode: Indicates speaker configuration mode.
541 *
542 * Returns 0 on success or -EINVAL on error.
543 */
Meng Wang15c825d2018-09-06 10:49:18 +0800544int wsa_macro_set_spkr_mode(struct snd_soc_component *component, int mode)
Laxminath Kasam243e2752018-04-12 00:40:19 +0530545{
546 int i;
547 const struct wsa_macro_reg_mask_val *regs;
548 int size;
549 struct device *wsa_dev = NULL;
550 struct wsa_macro_priv *wsa_priv = NULL;
551
Meng Wang15c825d2018-09-06 10:49:18 +0800552 if (!component) {
Laxminath Kasam243e2752018-04-12 00:40:19 +0530553 pr_err("%s: NULL codec pointer!\n", __func__);
554 return -EINVAL;
555 }
556
Meng Wang15c825d2018-09-06 10:49:18 +0800557 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530558 return -EINVAL;
559
560 switch (mode) {
Laxminath Kasam21c8b222018-06-21 18:47:22 +0530561 case WSA_MACRO_SPKR_MODE_1:
Laxminath Kasam243e2752018-04-12 00:40:19 +0530562 regs = wsa_macro_spkr_mode1;
563 size = ARRAY_SIZE(wsa_macro_spkr_mode1);
564 break;
565 default:
566 regs = wsa_macro_spkr_default;
567 size = ARRAY_SIZE(wsa_macro_spkr_default);
568 break;
569 }
570
571 wsa_priv->spkr_mode = mode;
572 for (i = 0; i < size; i++)
Meng Wang15c825d2018-09-06 10:49:18 +0800573 snd_soc_component_update_bits(component, regs[i].reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530574 regs[i].mask, regs[i].val);
575 return 0;
576}
577EXPORT_SYMBOL(wsa_macro_set_spkr_mode);
578
579static int wsa_macro_set_prim_interpolator_rate(struct snd_soc_dai *dai,
580 u8 int_prim_fs_rate_reg_val,
581 u32 sample_rate)
582{
583 u8 int_1_mix1_inp;
584 u32 j, port;
585 u16 int_mux_cfg0, int_mux_cfg1;
586 u16 int_fs_reg;
587 u8 int_mux_cfg0_val, int_mux_cfg1_val;
588 u8 inp0_sel, inp1_sel, inp2_sel;
Meng Wang15c825d2018-09-06 10:49:18 +0800589 struct snd_soc_component *component = dai->component;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530590 struct device *wsa_dev = NULL;
591 struct wsa_macro_priv *wsa_priv = NULL;
592
Meng Wang15c825d2018-09-06 10:49:18 +0800593 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530594 return -EINVAL;
595
596 for_each_set_bit(port, &wsa_priv->active_ch_mask[dai->id],
597 WSA_MACRO_RX_MAX) {
598 int_1_mix1_inp = port;
599 if ((int_1_mix1_inp < WSA_MACRO_RX0) ||
600 (int_1_mix1_inp > WSA_MACRO_RX_MIX1)) {
601 dev_err(wsa_dev,
602 "%s: Invalid RX port, Dai ID is %d\n",
603 __func__, dai->id);
604 return -EINVAL;
605 }
606
607 int_mux_cfg0 = BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0;
608
609 /*
610 * Loop through all interpolator MUX inputs and find out
611 * to which interpolator input, the cdc_dma rx port
612 * is connected
613 */
614 for (j = 0; j < NUM_INTERPOLATORS; j++) {
615 int_mux_cfg1 = int_mux_cfg0 + WSA_MACRO_MUX_CFG1_OFFSET;
616
Meng Wang15c825d2018-09-06 10:49:18 +0800617 int_mux_cfg0_val = snd_soc_component_read32(component,
618 int_mux_cfg0);
619 int_mux_cfg1_val = snd_soc_component_read32(component,
620 int_mux_cfg1);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530621 inp0_sel = int_mux_cfg0_val & WSA_MACRO_MUX_INP_MASK1;
622 inp1_sel = (int_mux_cfg0_val >>
623 WSA_MACRO_MUX_INP_SHFT) &
Laxminath Kasam793902c2019-12-11 18:16:52 +0530624 WSA_MACRO_MUX_INP_MASK1;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530625 inp2_sel = (int_mux_cfg1_val >>
626 WSA_MACRO_MUX_INP_SHFT) &
Laxminath Kasam793902c2019-12-11 18:16:52 +0530627 WSA_MACRO_MUX_INP_MASK1;
Laxminath Kasamf8adb5f2019-08-09 21:47:33 +0530628 if ((inp0_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0) ||
629 (inp1_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0) ||
630 (inp2_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0)) {
Laxminath Kasam243e2752018-04-12 00:40:19 +0530631 int_fs_reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL +
632 WSA_MACRO_RX_PATH_OFFSET * j;
633 dev_dbg(wsa_dev,
634 "%s: AIF_PB DAI(%d) connected to INT%u_1\n",
635 __func__, dai->id, j);
636 dev_dbg(wsa_dev,
637 "%s: set INT%u_1 sample rate to %u\n",
638 __func__, j, sample_rate);
639 /* sample_rate is in Hz */
Meng Wang15c825d2018-09-06 10:49:18 +0800640 snd_soc_component_update_bits(component,
641 int_fs_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530642 WSA_MACRO_FS_RATE_MASK,
643 int_prim_fs_rate_reg_val);
644 }
645 int_mux_cfg0 += WSA_MACRO_MUX_CFG_OFFSET;
646 }
647 }
648
649 return 0;
650}
651
652static int wsa_macro_set_mix_interpolator_rate(struct snd_soc_dai *dai,
653 u8 int_mix_fs_rate_reg_val,
654 u32 sample_rate)
655{
656 u8 int_2_inp;
657 u32 j, port;
658 u16 int_mux_cfg1, int_fs_reg;
659 u8 int_mux_cfg1_val;
Meng Wang15c825d2018-09-06 10:49:18 +0800660 struct snd_soc_component *component = dai->component;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530661 struct device *wsa_dev = NULL;
662 struct wsa_macro_priv *wsa_priv = NULL;
663
Meng Wang15c825d2018-09-06 10:49:18 +0800664 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530665 return -EINVAL;
666
667
668 for_each_set_bit(port, &wsa_priv->active_ch_mask[dai->id],
669 WSA_MACRO_RX_MAX) {
670 int_2_inp = port;
671 if ((int_2_inp < WSA_MACRO_RX0) ||
672 (int_2_inp > WSA_MACRO_RX_MIX1)) {
673 dev_err(wsa_dev,
674 "%s: Invalid RX port, Dai ID is %d\n",
675 __func__, dai->id);
676 return -EINVAL;
677 }
678
679 int_mux_cfg1 = BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG1;
680 for (j = 0; j < NUM_INTERPOLATORS; j++) {
Meng Wang15c825d2018-09-06 10:49:18 +0800681 int_mux_cfg1_val = snd_soc_component_read32(component,
682 int_mux_cfg1) &
Laxminath Kasam243e2752018-04-12 00:40:19 +0530683 WSA_MACRO_MUX_INP_MASK1;
Laxminath Kasamf8adb5f2019-08-09 21:47:33 +0530684 if (int_mux_cfg1_val == int_2_inp +
685 INTn_2_INP_SEL_RX0) {
Laxminath Kasam243e2752018-04-12 00:40:19 +0530686 int_fs_reg =
687 BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL +
688 WSA_MACRO_RX_PATH_OFFSET * j;
689
690 dev_dbg(wsa_dev,
691 "%s: AIF_PB DAI(%d) connected to INT%u_2\n",
692 __func__, dai->id, j);
693 dev_dbg(wsa_dev,
694 "%s: set INT%u_2 sample rate to %u\n",
695 __func__, j, sample_rate);
Meng Wang15c825d2018-09-06 10:49:18 +0800696 snd_soc_component_update_bits(component,
697 int_fs_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530698 WSA_MACRO_FS_RATE_MASK,
699 int_mix_fs_rate_reg_val);
700 }
701 int_mux_cfg1 += WSA_MACRO_MUX_CFG_OFFSET;
702 }
703 }
704 return 0;
705}
706
707static int wsa_macro_set_interpolator_rate(struct snd_soc_dai *dai,
708 u32 sample_rate)
709{
710 int rate_val = 0;
711 int i, ret;
712
713 /* set mixing path rate */
714 for (i = 0; i < ARRAY_SIZE(int_mix_sample_rate_val); i++) {
715 if (sample_rate ==
716 int_mix_sample_rate_val[i].sample_rate) {
717 rate_val =
718 int_mix_sample_rate_val[i].rate_val;
719 break;
720 }
721 }
722 if ((i == ARRAY_SIZE(int_mix_sample_rate_val)) ||
723 (rate_val < 0))
724 goto prim_rate;
725 ret = wsa_macro_set_mix_interpolator_rate(dai,
726 (u8) rate_val, sample_rate);
727prim_rate:
728 /* set primary path sample rate */
729 for (i = 0; i < ARRAY_SIZE(int_prim_sample_rate_val); i++) {
730 if (sample_rate ==
731 int_prim_sample_rate_val[i].sample_rate) {
732 rate_val =
733 int_prim_sample_rate_val[i].rate_val;
734 break;
735 }
736 }
737 if ((i == ARRAY_SIZE(int_prim_sample_rate_val)) ||
738 (rate_val < 0))
739 return -EINVAL;
740 ret = wsa_macro_set_prim_interpolator_rate(dai,
741 (u8) rate_val, sample_rate);
742 return ret;
743}
744
745static int wsa_macro_hw_params(struct snd_pcm_substream *substream,
746 struct snd_pcm_hw_params *params,
747 struct snd_soc_dai *dai)
748{
Meng Wang15c825d2018-09-06 10:49:18 +0800749 struct snd_soc_component *component = dai->component;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530750 int ret;
Laxminath Kasam007d2522020-04-23 11:00:44 +0530751 struct device *wsa_dev = NULL;
752 struct wsa_macro_priv *wsa_priv = NULL;
753
754 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
755 return -EINVAL;
756
757 wsa_priv = dev_get_drvdata(wsa_dev);
758 if (!wsa_priv)
759 return -EINVAL;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530760
Meng Wang15c825d2018-09-06 10:49:18 +0800761 dev_dbg(component->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530762 "%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__,
763 dai->name, dai->id, params_rate(params),
764 params_channels(params));
765
766 switch (substream->stream) {
767 case SNDRV_PCM_STREAM_PLAYBACK:
768 ret = wsa_macro_set_interpolator_rate(dai, params_rate(params));
769 if (ret) {
Meng Wang15c825d2018-09-06 10:49:18 +0800770 dev_err(component->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530771 "%s: cannot set sample rate: %u\n",
772 __func__, params_rate(params));
773 return ret;
774 }
775 break;
776 case SNDRV_PCM_STREAM_CAPTURE:
Laxminath Kasam007d2522020-04-23 11:00:44 +0530777 if (dai->id == WSA_MACRO_AIF_VI)
778 wsa_priv->pcm_rate_vi = params_rate(params);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530779 default:
780 break;
781 }
782 return 0;
783}
784
785static int wsa_macro_get_channel_map(struct snd_soc_dai *dai,
786 unsigned int *tx_num, unsigned int *tx_slot,
787 unsigned int *rx_num, unsigned int *rx_slot)
788{
Meng Wang15c825d2018-09-06 10:49:18 +0800789 struct snd_soc_component *component = dai->component;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530790 struct device *wsa_dev = NULL;
791 struct wsa_macro_priv *wsa_priv = NULL;
Laxminath Kasamf8adb5f2019-08-09 21:47:33 +0530792 u16 val = 0, mask = 0, cnt = 0, temp = 0;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530793
Meng Wang15c825d2018-09-06 10:49:18 +0800794 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530795 return -EINVAL;
796
797 wsa_priv = dev_get_drvdata(wsa_dev);
798 if (!wsa_priv)
799 return -EINVAL;
800
801 switch (dai->id) {
802 case WSA_MACRO_AIF_VI:
Laxminath Kasam243e2752018-04-12 00:40:19 +0530803 *tx_slot = wsa_priv->active_ch_mask[dai->id];
804 *tx_num = wsa_priv->active_ch_cnt[dai->id];
805 break;
806 case WSA_MACRO_AIF1_PB:
807 case WSA_MACRO_AIF_MIX1_PB:
Laxminath Kasamf8adb5f2019-08-09 21:47:33 +0530808 for_each_set_bit(temp, &wsa_priv->active_ch_mask[dai->id],
809 WSA_MACRO_RX_MAX) {
810 mask |= (1 << temp);
811 if (++cnt == WSA_MACRO_MAX_DMA_CH_PER_PORT)
812 break;
813 }
814 if (mask & 0x0C)
815 mask = mask >> 0x2;
816 *rx_slot = mask;
817 *rx_num = cnt;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530818 break;
Laxminath Kasam5d9ea8d2018-11-28 14:32:40 +0530819 case WSA_MACRO_AIF_ECHO:
820 val = snd_soc_component_read32(component,
821 BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0);
822 if (val & WSA_MACRO_EC_MIX_TX1_MASK) {
823 mask |= 0x2;
824 cnt++;
825 }
826 if (val & WSA_MACRO_EC_MIX_TX0_MASK) {
827 mask |= 0x1;
828 cnt++;
829 }
830 *tx_slot = mask;
831 *tx_num = cnt;
832 break;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530833 default:
834 dev_err(wsa_dev, "%s: Invalid AIF\n", __func__);
835 break;
836 }
837 return 0;
838}
839
Laxminath Kasam52ae6582019-08-08 18:00:35 +0530840static int wsa_macro_digital_mute(struct snd_soc_dai *dai, int mute)
841{
842 struct snd_soc_component *component = dai->component;
843 struct device *wsa_dev = NULL;
844 struct wsa_macro_priv *wsa_priv = NULL;
845 uint16_t j = 0, reg = 0, mix_reg = 0, dsm_reg = 0;
846 u16 int_mux_cfg0 = 0, int_mux_cfg1 = 0;
847 u8 int_mux_cfg0_val = 0, int_mux_cfg1_val = 0;
Laxminath Kasam2fe71f52020-05-15 00:39:51 +0530848 bool adie_lb = false;
Laxminath Kasam52ae6582019-08-08 18:00:35 +0530849
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 Kasam2fe71f52020-05-15 00:39:51 +0530885 bolero_wsa_pa_on(wsa_dev, adie_lb);
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;
Prasad Kumpatlaefdb3932020-05-13 18:55:32 +05301026 case BOLERO_MACRO_EVT_PRE_SSR_UP:
Meng Wangbd930242019-06-25 09:39:48 +08001027 /* enable&disable WSA_CORE_CLK to reset GFMUX reg */
1028 ret = bolero_clk_rsc_request_clock(wsa_priv->dev,
1029 wsa_priv->default_clk_id,
1030 WSA_CORE_CLK, true);
1031 if (ret < 0)
1032 dev_err_ratelimited(wsa_priv->dev,
1033 "%s, failed to enable clk, ret:%d\n",
1034 __func__, ret);
1035 else
1036 bolero_clk_rsc_request_clock(wsa_priv->dev,
1037 wsa_priv->default_clk_id,
1038 WSA_CORE_CLK, false);
Prasad Kumpatlaefdb3932020-05-13 18:55:32 +05301039 break;
1040 case BOLERO_MACRO_EVT_SSR_UP:
1041 trace_printk("%s, enter SSR up\n", __func__);
1042 /* reset swr after ssr/pdr */
1043 wsa_priv->reset_swr = true;
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07001044 if (wsa_priv->swr_ctrl_data)
1045 swrm_wcd_notify(
1046 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
1047 SWR_DEVICE_SSR_UP, NULL);
Laxminath Kasamfb0d6832018-09-22 01:49:52 +05301048 break;
Meng Wang8ef0cc22019-05-08 15:12:56 +08001049 case BOLERO_MACRO_EVT_CLK_RESET:
1050 bolero_rsc_clk_reset(wsa_dev, WSA_CORE_CLK);
1051 break;
Laxminath Kasamfb0d6832018-09-22 01:49:52 +05301052 }
1053 return 0;
1054}
1055
Laxminath Kasam243e2752018-04-12 00:40:19 +05301056static int wsa_macro_enable_vi_feedback(struct snd_soc_dapm_widget *w,
1057 struct snd_kcontrol *kcontrol,
1058 int event)
1059{
Meng Wang15c825d2018-09-06 10:49:18 +08001060 struct snd_soc_component *component =
1061 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301062 struct device *wsa_dev = NULL;
1063 struct wsa_macro_priv *wsa_priv = NULL;
Laxminath Kasam007d2522020-04-23 11:00:44 +05301064 u8 val = 0x0;
Laxminath Kasam243e2752018-04-12 00:40:19 +05301065
Meng Wang15c825d2018-09-06 10:49:18 +08001066 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301067 return -EINVAL;
1068
Laxminath Kasam007d2522020-04-23 11:00:44 +05301069 switch (wsa_priv->pcm_rate_vi) {
1070 case 48000:
1071 val = 0x04;
1072 break;
1073 case 24000:
1074 val = 0x02;
1075 break;
1076 case 8000:
1077 default:
1078 val = 0x00;
1079 break;
1080 }
1081
Laxminath Kasam243e2752018-04-12 00:40:19 +05301082 switch (event) {
1083 case SND_SOC_DAPM_POST_PMU:
1084 if (test_bit(WSA_MACRO_TX0,
1085 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
1086 dev_dbg(wsa_dev, "%s: spkr1 enabled\n", __func__);
1087 /* Enable V&I sensing */
Meng Wang15c825d2018-09-06 10:49:18 +08001088 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301089 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
1090 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08001091 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301092 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
1093 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08001094 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301095 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
Laxminath Kasam007d2522020-04-23 11:00:44 +05301096 0x0F, val);
Meng Wang15c825d2018-09-06 10:49:18 +08001097 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301098 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
Laxminath Kasam007d2522020-04-23 11:00:44 +05301099 0x0F, val);
Meng Wang15c825d2018-09-06 10:49:18 +08001100 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301101 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
1102 0x10, 0x10);
Meng Wang15c825d2018-09-06 10:49:18 +08001103 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301104 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
1105 0x10, 0x10);
Meng Wang15c825d2018-09-06 10:49:18 +08001106 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301107 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
1108 0x20, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001109 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301110 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
1111 0x20, 0x00);
1112 }
1113 if (test_bit(WSA_MACRO_TX1,
1114 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
1115 dev_dbg(wsa_dev, "%s: spkr2 enabled\n", __func__);
1116 /* Enable V&I sensing */
Meng Wang15c825d2018-09-06 10:49:18 +08001117 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301118 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
1119 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08001120 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301121 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
1122 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08001123 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301124 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
Laxminath Kasam007d2522020-04-23 11:00:44 +05301125 0x0F, val);
Meng Wang15c825d2018-09-06 10:49:18 +08001126 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301127 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
Laxminath Kasam007d2522020-04-23 11:00:44 +05301128 0x0F, val);
Meng Wang15c825d2018-09-06 10:49:18 +08001129 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301130 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
1131 0x10, 0x10);
Meng Wang15c825d2018-09-06 10:49:18 +08001132 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301133 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
1134 0x10, 0x10);
Meng Wang15c825d2018-09-06 10:49:18 +08001135 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301136 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
1137 0x20, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001138 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301139 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
1140 0x20, 0x00);
1141 }
1142 break;
1143 case SND_SOC_DAPM_POST_PMD:
1144 if (test_bit(WSA_MACRO_TX0,
1145 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
1146 /* Disable V&I sensing */
Meng Wang15c825d2018-09-06 10:49:18 +08001147 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301148 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
1149 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08001150 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301151 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
1152 0x20, 0x20);
1153 dev_dbg(wsa_dev, "%s: spkr1 disabled\n", __func__);
Meng Wang15c825d2018-09-06 10:49:18 +08001154 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301155 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
1156 0x10, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001157 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301158 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
1159 0x10, 0x00);
1160 }
1161 if (test_bit(WSA_MACRO_TX1,
1162 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
1163 /* Disable V&I sensing */
1164 dev_dbg(wsa_dev, "%s: spkr2 disabled\n", __func__);
Meng Wang15c825d2018-09-06 10:49:18 +08001165 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301166 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
1167 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08001168 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301169 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
1170 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08001171 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301172 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
1173 0x10, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001174 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301175 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
1176 0x10, 0x00);
1177 }
1178 break;
1179 }
1180
1181 return 0;
1182}
1183
Meng Wang15c825d2018-09-06 10:49:18 +08001184static void wsa_macro_hd2_control(struct snd_soc_component *component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301185 u16 reg, int event)
1186{
1187 u16 hd2_scale_reg;
1188 u16 hd2_enable_reg = 0;
1189
1190 if (reg == BOLERO_CDC_WSA_RX0_RX_PATH_CTL) {
1191 hd2_scale_reg = BOLERO_CDC_WSA_RX0_RX_PATH_SEC3;
1192 hd2_enable_reg = BOLERO_CDC_WSA_RX0_RX_PATH_CFG0;
1193 }
1194 if (reg == BOLERO_CDC_WSA_RX1_RX_PATH_CTL) {
1195 hd2_scale_reg = BOLERO_CDC_WSA_RX1_RX_PATH_SEC3;
1196 hd2_enable_reg = BOLERO_CDC_WSA_RX1_RX_PATH_CFG0;
1197 }
1198
1199 if (hd2_enable_reg && SND_SOC_DAPM_EVENT_ON(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001200 snd_soc_component_update_bits(component, hd2_scale_reg,
1201 0x3C, 0x10);
1202 snd_soc_component_update_bits(component, hd2_scale_reg,
1203 0x03, 0x01);
1204 snd_soc_component_update_bits(component, hd2_enable_reg,
1205 0x04, 0x04);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301206 }
1207
1208 if (hd2_enable_reg && SND_SOC_DAPM_EVENT_OFF(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001209 snd_soc_component_update_bits(component, hd2_enable_reg,
1210 0x04, 0x00);
1211 snd_soc_component_update_bits(component, hd2_scale_reg,
1212 0x03, 0x00);
1213 snd_soc_component_update_bits(component, hd2_scale_reg,
1214 0x3C, 0x00);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301215 }
1216}
1217
1218static int wsa_macro_enable_swr(struct snd_soc_dapm_widget *w,
1219 struct snd_kcontrol *kcontrol, int event)
1220{
Meng Wang15c825d2018-09-06 10:49:18 +08001221 struct snd_soc_component *component =
1222 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301223 int ch_cnt;
1224 struct device *wsa_dev = NULL;
1225 struct wsa_macro_priv *wsa_priv = NULL;
1226
Meng Wang15c825d2018-09-06 10:49:18 +08001227 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301228 return -EINVAL;
1229
1230 switch (event) {
1231 case SND_SOC_DAPM_PRE_PMU:
1232 if (!(strnstr(w->name, "RX0", sizeof("WSA_RX0"))) &&
1233 !wsa_priv->rx_0_count)
1234 wsa_priv->rx_0_count++;
1235 if (!(strnstr(w->name, "RX1", sizeof("WSA_RX1"))) &&
1236 !wsa_priv->rx_1_count)
1237 wsa_priv->rx_1_count++;
1238 ch_cnt = wsa_priv->rx_0_count + wsa_priv->rx_1_count;
1239
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07001240 if (wsa_priv->swr_ctrl_data) {
1241 swrm_wcd_notify(
1242 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
1243 SWR_DEVICE_UP, NULL);
1244 swrm_wcd_notify(
1245 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
1246 SWR_SET_NUM_RX_CH, &ch_cnt);
1247 }
Laxminath Kasam243e2752018-04-12 00:40:19 +05301248 break;
1249 case SND_SOC_DAPM_POST_PMD:
1250 if (!(strnstr(w->name, "RX0", sizeof("WSA_RX0"))) &&
1251 wsa_priv->rx_0_count)
1252 wsa_priv->rx_0_count--;
1253 if (!(strnstr(w->name, "RX1", sizeof("WSA_RX1"))) &&
1254 wsa_priv->rx_1_count)
1255 wsa_priv->rx_1_count--;
1256 ch_cnt = wsa_priv->rx_0_count + wsa_priv->rx_1_count;
1257
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07001258 if (wsa_priv->swr_ctrl_data)
1259 swrm_wcd_notify(
1260 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
1261 SWR_SET_NUM_RX_CH, &ch_cnt);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301262 break;
1263 }
1264 dev_dbg(wsa_priv->dev, "%s: current swr ch cnt: %d\n",
1265 __func__, wsa_priv->rx_0_count + wsa_priv->rx_1_count);
1266
1267 return 0;
1268}
1269
Laxminath Kasam01d2eb22020-05-13 18:44:49 +05301270static int wsa_macro_enable_mix_path(struct snd_soc_dapm_widget *w,
1271 struct snd_kcontrol *kcontrol, int event)
1272{
1273 struct snd_soc_component *component =
1274 snd_soc_dapm_to_component(w->dapm);
1275 u16 gain_reg;
1276 int offset_val = 0;
1277 int val = 0;
1278
1279 dev_dbg(component->dev, "%s %d %s\n", __func__, event, w->name);
1280
1281 if (!(strcmp(w->name, "WSA_RX0 MIX INP"))) {
1282 gain_reg = BOLERO_CDC_WSA_RX0_RX_VOL_MIX_CTL;
1283 } else if (!(strcmp(w->name, "WSA_RX1 MIX INP"))) {
1284 gain_reg = BOLERO_CDC_WSA_RX1_RX_VOL_MIX_CTL;
1285 } else {
1286 dev_err(component->dev, "%s: No gain register avail for %s\n",
1287 __func__, w->name);
1288 return 0;
1289 }
1290
1291 switch (event) {
1292 case SND_SOC_DAPM_PRE_PMU:
1293 wsa_macro_enable_swr(w, kcontrol, event);
1294 val = snd_soc_component_read32(component, gain_reg);
1295 val += offset_val;
1296 snd_soc_component_write(component, gain_reg, val);
1297 break;
1298 case SND_SOC_DAPM_POST_PMD:
1299 snd_soc_component_update_bits(component,
1300 w->reg, 0x20, 0x00);
1301 wsa_macro_enable_swr(w, kcontrol, event);
1302 break;
1303 }
1304
1305 return 0;
1306}
1307
Meng Wang15c825d2018-09-06 10:49:18 +08001308static int wsa_macro_config_compander(struct snd_soc_component *component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301309 int comp, int event)
1310{
1311 u16 comp_ctl0_reg, rx_path_cfg0_reg;
1312 struct device *wsa_dev = NULL;
1313 struct wsa_macro_priv *wsa_priv = NULL;
1314
Meng Wang15c825d2018-09-06 10:49:18 +08001315 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301316 return -EINVAL;
1317
Meng Wang15c825d2018-09-06 10:49:18 +08001318 dev_dbg(component->dev, "%s: event %d compander %d, enabled %d\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301319 __func__, event, comp + 1, wsa_priv->comp_enabled[comp]);
1320
1321 if (!wsa_priv->comp_enabled[comp])
1322 return 0;
1323
1324 comp_ctl0_reg = BOLERO_CDC_WSA_COMPANDER0_CTL0 +
1325 (comp * WSA_MACRO_RX_COMP_OFFSET);
1326 rx_path_cfg0_reg = BOLERO_CDC_WSA_RX0_RX_PATH_CFG0 +
1327 (comp * WSA_MACRO_RX_PATH_OFFSET);
1328
1329 if (SND_SOC_DAPM_EVENT_ON(event)) {
1330 /* Enable Compander Clock */
Meng Wang15c825d2018-09-06 10:49:18 +08001331 snd_soc_component_update_bits(component, comp_ctl0_reg,
1332 0x01, 0x01);
1333 snd_soc_component_update_bits(component, comp_ctl0_reg,
1334 0x02, 0x02);
1335 snd_soc_component_update_bits(component, comp_ctl0_reg,
1336 0x02, 0x00);
1337 snd_soc_component_update_bits(component, rx_path_cfg0_reg,
1338 0x02, 0x02);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301339 }
1340
1341 if (SND_SOC_DAPM_EVENT_OFF(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001342 snd_soc_component_update_bits(component, comp_ctl0_reg,
1343 0x04, 0x04);
1344 snd_soc_component_update_bits(component, rx_path_cfg0_reg,
1345 0x02, 0x00);
1346 snd_soc_component_update_bits(component, comp_ctl0_reg,
1347 0x02, 0x02);
1348 snd_soc_component_update_bits(component, comp_ctl0_reg,
1349 0x02, 0x00);
1350 snd_soc_component_update_bits(component, comp_ctl0_reg,
1351 0x01, 0x00);
1352 snd_soc_component_update_bits(component, comp_ctl0_reg,
1353 0x04, 0x00);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301354 }
1355
1356 return 0;
1357}
1358
Meng Wang15c825d2018-09-06 10:49:18 +08001359static void wsa_macro_enable_softclip_clk(struct snd_soc_component *component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301360 struct wsa_macro_priv *wsa_priv,
1361 int path,
1362 bool enable)
1363{
1364 u16 softclip_clk_reg = BOLERO_CDC_WSA_SOFTCLIP0_CRC +
1365 (path * WSA_MACRO_RX_SOFTCLIP_OFFSET);
1366 u8 softclip_mux_mask = (1 << path);
1367 u8 softclip_mux_value = (1 << path);
1368
Meng Wang15c825d2018-09-06 10:49:18 +08001369 dev_dbg(component->dev, "%s: path %d, enable %d\n",
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301370 __func__, path, enable);
1371 if (enable) {
1372 if (wsa_priv->softclip_clk_users[path] == 0) {
Meng Wang15c825d2018-09-06 10:49:18 +08001373 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301374 softclip_clk_reg, 0x01, 0x01);
Meng Wang15c825d2018-09-06 10:49:18 +08001375 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301376 BOLERO_CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0,
1377 softclip_mux_mask, softclip_mux_value);
1378 }
1379 wsa_priv->softclip_clk_users[path]++;
1380 } else {
1381 wsa_priv->softclip_clk_users[path]--;
1382 if (wsa_priv->softclip_clk_users[path] == 0) {
Meng Wang15c825d2018-09-06 10:49:18 +08001383 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301384 softclip_clk_reg, 0x01, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001385 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301386 BOLERO_CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0,
1387 softclip_mux_mask, 0x00);
1388 }
1389 }
1390}
1391
Meng Wang15c825d2018-09-06 10:49:18 +08001392static int wsa_macro_config_softclip(struct snd_soc_component *component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301393 int path, int event)
1394{
1395 u16 softclip_ctrl_reg = 0;
1396 struct device *wsa_dev = NULL;
1397 struct wsa_macro_priv *wsa_priv = NULL;
1398 int softclip_path = 0;
1399
Meng Wang15c825d2018-09-06 10:49:18 +08001400 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301401 return -EINVAL;
1402
1403 if (path == WSA_MACRO_COMP1)
1404 softclip_path = WSA_MACRO_SOFTCLIP0;
1405 else if (path == WSA_MACRO_COMP2)
1406 softclip_path = WSA_MACRO_SOFTCLIP1;
1407
Meng Wang15c825d2018-09-06 10:49:18 +08001408 dev_dbg(component->dev, "%s: event %d path %d, enabled %d\n",
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301409 __func__, event, softclip_path,
1410 wsa_priv->is_softclip_on[softclip_path]);
1411
1412 if (!wsa_priv->is_softclip_on[softclip_path])
1413 return 0;
1414
1415 softclip_ctrl_reg = BOLERO_CDC_WSA_SOFTCLIP0_SOFTCLIP_CTRL +
1416 (softclip_path * WSA_MACRO_RX_SOFTCLIP_OFFSET);
1417
1418 if (SND_SOC_DAPM_EVENT_ON(event)) {
1419 /* Enable Softclip clock and mux */
Meng Wang15c825d2018-09-06 10:49:18 +08001420 wsa_macro_enable_softclip_clk(component, wsa_priv,
1421 softclip_path, true);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301422 /* Enable Softclip control */
Meng Wang15c825d2018-09-06 10:49:18 +08001423 snd_soc_component_update_bits(component, softclip_ctrl_reg,
1424 0x01, 0x01);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301425 }
1426
1427 if (SND_SOC_DAPM_EVENT_OFF(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001428 snd_soc_component_update_bits(component, softclip_ctrl_reg,
1429 0x01, 0x00);
1430 wsa_macro_enable_softclip_clk(component, wsa_priv,
1431 softclip_path, false);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301432 }
1433
1434 return 0;
1435}
1436
Laxminath Kasam52ae6582019-08-08 18:00:35 +05301437static bool wsa_macro_adie_lb(struct snd_soc_component *component,
1438 int interp_idx)
1439{
1440 u16 int_mux_cfg0 = 0, int_mux_cfg1 = 0;
1441 u8 int_mux_cfg0_val = 0, int_mux_cfg1_val = 0;
1442 u8 int_n_inp0 = 0, int_n_inp1 = 0, int_n_inp2 = 0;
1443
1444 int_mux_cfg0 = BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0 + interp_idx * 8;
1445 int_mux_cfg1 = int_mux_cfg0 + 4;
1446 int_mux_cfg0_val = snd_soc_component_read32(component, int_mux_cfg0);
1447 int_mux_cfg1_val = snd_soc_component_read32(component, int_mux_cfg1);
1448
1449 int_n_inp0 = int_mux_cfg0_val & 0x0F;
1450 if (int_n_inp0 == INTn_1_INP_SEL_DEC0 ||
1451 int_n_inp0 == INTn_1_INP_SEL_DEC1)
1452 return true;
1453
1454 int_n_inp1 = int_mux_cfg0_val >> 4;
1455 if (int_n_inp1 == INTn_1_INP_SEL_DEC0 ||
1456 int_n_inp1 == INTn_1_INP_SEL_DEC1)
1457 return true;
1458
1459 int_n_inp2 = int_mux_cfg1_val >> 4;
1460 if (int_n_inp2 == INTn_1_INP_SEL_DEC0 ||
1461 int_n_inp2 == INTn_1_INP_SEL_DEC1)
1462 return true;
1463
1464 return false;
1465}
1466
1467static int wsa_macro_enable_main_path(struct snd_soc_dapm_widget *w,
1468 struct snd_kcontrol *kcontrol,
1469 int event)
1470{
1471 struct snd_soc_component *component =
1472 snd_soc_dapm_to_component(w->dapm);
1473 u16 reg = 0;
Laxminath Kasam069df142019-09-17 23:43:34 +05301474 struct device *wsa_dev = NULL;
1475 struct wsa_macro_priv *wsa_priv = NULL;
Laxminath Kasam2fe71f52020-05-15 00:39:51 +05301476 bool adie_lb = false;
Laxminath Kasam069df142019-09-17 23:43:34 +05301477
1478 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
1479 return -EINVAL;
1480
Laxminath Kasam52ae6582019-08-08 18:00:35 +05301481
1482 reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL +
1483 WSA_MACRO_RX_PATH_OFFSET * w->shift;
1484 switch (event) {
1485 case SND_SOC_DAPM_PRE_PMU:
Laxminath Kasam069df142019-09-17 23:43:34 +05301486 if (wsa_macro_adie_lb(component, w->shift)) {
Laxminath Kasam2fe71f52020-05-15 00:39:51 +05301487 adie_lb = true;
Laxminath Kasam52ae6582019-08-08 18:00:35 +05301488 snd_soc_component_update_bits(component,
1489 reg, 0x20, 0x20);
Laxminath Kasam2fe71f52020-05-15 00:39:51 +05301490 bolero_wsa_pa_on(wsa_dev, adie_lb);
Laxminath Kasam069df142019-09-17 23:43:34 +05301491 }
Laxminath Kasam52ae6582019-08-08 18:00:35 +05301492 break;
1493 default:
1494 break;
1495 }
1496 return 0;
1497}
1498
Laxminath Kasam243e2752018-04-12 00:40:19 +05301499static int wsa_macro_interp_get_primary_reg(u16 reg, u16 *ind)
1500{
1501 u16 prim_int_reg = 0;
1502
1503 switch (reg) {
1504 case BOLERO_CDC_WSA_RX0_RX_PATH_CTL:
1505 case BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL:
1506 prim_int_reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL;
1507 *ind = 0;
1508 break;
1509 case BOLERO_CDC_WSA_RX1_RX_PATH_CTL:
1510 case BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL:
1511 prim_int_reg = BOLERO_CDC_WSA_RX1_RX_PATH_CTL;
1512 *ind = 1;
1513 break;
1514 }
1515
1516 return prim_int_reg;
1517}
1518
1519static int wsa_macro_enable_prim_interpolator(
Meng Wang15c825d2018-09-06 10:49:18 +08001520 struct snd_soc_component *component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301521 u16 reg, int event)
1522{
1523 u16 prim_int_reg;
1524 u16 ind = 0;
1525 struct device *wsa_dev = NULL;
1526 struct wsa_macro_priv *wsa_priv = NULL;
1527
Meng Wang15c825d2018-09-06 10:49:18 +08001528 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301529 return -EINVAL;
1530
1531 prim_int_reg = wsa_macro_interp_get_primary_reg(reg, &ind);
1532
1533 switch (event) {
1534 case SND_SOC_DAPM_PRE_PMU:
1535 wsa_priv->prim_int_users[ind]++;
1536 if (wsa_priv->prim_int_users[ind] == 1) {
Meng Wang15c825d2018-09-06 10:49:18 +08001537 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301538 prim_int_reg + WSA_MACRO_RX_PATH_CFG3_OFFSET,
1539 0x03, 0x03);
Meng Wang15c825d2018-09-06 10:49:18 +08001540 snd_soc_component_update_bits(component, prim_int_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301541 0x10, 0x10);
Meng Wang15c825d2018-09-06 10:49:18 +08001542 wsa_macro_hd2_control(component, prim_int_reg, event);
1543 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301544 prim_int_reg + WSA_MACRO_RX_PATH_DSMDEM_OFFSET,
1545 0x1, 0x1);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301546 }
1547 if ((reg != prim_int_reg) &&
Meng Wang15c825d2018-09-06 10:49:18 +08001548 ((snd_soc_component_read32(
1549 component, prim_int_reg)) & 0x10))
1550 snd_soc_component_update_bits(component, reg,
1551 0x10, 0x10);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301552 break;
1553 case SND_SOC_DAPM_POST_PMD:
1554 wsa_priv->prim_int_users[ind]--;
1555 if (wsa_priv->prim_int_users[ind] == 0) {
Meng Wang15c825d2018-09-06 10:49:18 +08001556 snd_soc_component_update_bits(component, prim_int_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301557 1 << 0x5, 0 << 0x5);
Laxminath Kasam52ae6582019-08-08 18:00:35 +05301558 snd_soc_component_update_bits(component,
1559 prim_int_reg + WSA_MACRO_RX_PATH_DSMDEM_OFFSET,
1560 0x1, 0x0);
Meng Wang15c825d2018-09-06 10:49:18 +08001561 snd_soc_component_update_bits(component, prim_int_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301562 0x40, 0x40);
Meng Wang15c825d2018-09-06 10:49:18 +08001563 snd_soc_component_update_bits(component, prim_int_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301564 0x40, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001565 wsa_macro_hd2_control(component, prim_int_reg, event);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301566 }
1567 break;
1568 }
1569
Meng Wang15c825d2018-09-06 10:49:18 +08001570 dev_dbg(component->dev, "%s: primary interpolator: INT%d, users: %d\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301571 __func__, ind, wsa_priv->prim_int_users[ind]);
1572 return 0;
1573}
1574
1575static int wsa_macro_enable_interpolator(struct snd_soc_dapm_widget *w,
1576 struct snd_kcontrol *kcontrol,
1577 int event)
1578{
Meng Wang15c825d2018-09-06 10:49:18 +08001579 struct snd_soc_component *component =
1580 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301581 u16 gain_reg;
1582 u16 reg;
1583 int val;
1584 int offset_val = 0;
1585 struct device *wsa_dev = NULL;
1586 struct wsa_macro_priv *wsa_priv = NULL;
1587
Meng Wang15c825d2018-09-06 10:49:18 +08001588 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301589 return -EINVAL;
1590
Meng Wang15c825d2018-09-06 10:49:18 +08001591 dev_dbg(component->dev, "%s %d %s\n", __func__, event, w->name);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301592
1593 if (!(strcmp(w->name, "WSA_RX INT0 INTERP"))) {
1594 reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL;
1595 gain_reg = BOLERO_CDC_WSA_RX0_RX_VOL_CTL;
1596 } else if (!(strcmp(w->name, "WSA_RX INT1 INTERP"))) {
1597 reg = BOLERO_CDC_WSA_RX1_RX_PATH_CTL;
1598 gain_reg = BOLERO_CDC_WSA_RX1_RX_VOL_CTL;
1599 } else {
Meng Wang15c825d2018-09-06 10:49:18 +08001600 dev_err(component->dev, "%s: Interpolator reg not found\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301601 __func__);
1602 return -EINVAL;
1603 }
1604
1605 switch (event) {
1606 case SND_SOC_DAPM_PRE_PMU:
1607 /* Reset if needed */
Meng Wang15c825d2018-09-06 10:49:18 +08001608 wsa_macro_enable_prim_interpolator(component, reg, event);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301609 break;
1610 case SND_SOC_DAPM_POST_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08001611 wsa_macro_config_compander(component, w->shift, event);
1612 wsa_macro_config_softclip(component, w->shift, event);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301613 /* apply gain after int clk is enabled */
Laxminath Kasam21c8b222018-06-21 18:47:22 +05301614 if ((wsa_priv->spkr_gain_offset ==
1615 WSA_MACRO_GAIN_OFFSET_M1P5_DB) &&
Laxminath Kasam243e2752018-04-12 00:40:19 +05301616 (wsa_priv->comp_enabled[WSA_MACRO_COMP1] ||
1617 wsa_priv->comp_enabled[WSA_MACRO_COMP2]) &&
1618 (gain_reg == BOLERO_CDC_WSA_RX0_RX_VOL_CTL ||
1619 gain_reg == BOLERO_CDC_WSA_RX1_RX_VOL_CTL)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001620 snd_soc_component_update_bits(component,
1621 BOLERO_CDC_WSA_RX0_RX_PATH_SEC1,
1622 0x01, 0x01);
1623 snd_soc_component_update_bits(component,
1624 BOLERO_CDC_WSA_RX0_RX_PATH_MIX_SEC0,
1625 0x01, 0x01);
1626 snd_soc_component_update_bits(component,
1627 BOLERO_CDC_WSA_RX1_RX_PATH_SEC1,
1628 0x01, 0x01);
1629 snd_soc_component_update_bits(component,
1630 BOLERO_CDC_WSA_RX1_RX_PATH_MIX_SEC0,
1631 0x01, 0x01);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301632 offset_val = -2;
1633 }
Meng Wang15c825d2018-09-06 10:49:18 +08001634 val = snd_soc_component_read32(component, gain_reg);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301635 val += offset_val;
Meng Wang15c825d2018-09-06 10:49:18 +08001636 snd_soc_component_write(component, gain_reg, val);
1637 wsa_macro_config_ear_spkr_gain(component, wsa_priv,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301638 event, gain_reg);
1639 break;
1640 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +08001641 wsa_macro_config_compander(component, w->shift, event);
1642 wsa_macro_config_softclip(component, w->shift, event);
1643 wsa_macro_enable_prim_interpolator(component, reg, event);
Laxminath Kasam21c8b222018-06-21 18:47:22 +05301644 if ((wsa_priv->spkr_gain_offset ==
1645 WSA_MACRO_GAIN_OFFSET_M1P5_DB) &&
Laxminath Kasam243e2752018-04-12 00:40:19 +05301646 (wsa_priv->comp_enabled[WSA_MACRO_COMP1] ||
1647 wsa_priv->comp_enabled[WSA_MACRO_COMP2]) &&
1648 (gain_reg == BOLERO_CDC_WSA_RX0_RX_VOL_CTL ||
1649 gain_reg == BOLERO_CDC_WSA_RX1_RX_VOL_CTL)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001650 snd_soc_component_update_bits(component,
1651 BOLERO_CDC_WSA_RX0_RX_PATH_SEC1,
1652 0x01, 0x00);
1653 snd_soc_component_update_bits(component,
1654 BOLERO_CDC_WSA_RX0_RX_PATH_MIX_SEC0,
1655 0x01, 0x00);
1656 snd_soc_component_update_bits(component,
1657 BOLERO_CDC_WSA_RX1_RX_PATH_SEC1,
1658 0x01, 0x00);
1659 snd_soc_component_update_bits(component,
1660 BOLERO_CDC_WSA_RX1_RX_PATH_MIX_SEC0,
1661 0x01, 0x00);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301662 offset_val = 2;
Meng Wang15c825d2018-09-06 10:49:18 +08001663 val = snd_soc_component_read32(component, gain_reg);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301664 val += offset_val;
Meng Wang15c825d2018-09-06 10:49:18 +08001665 snd_soc_component_write(component, gain_reg, val);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301666 }
Meng Wang15c825d2018-09-06 10:49:18 +08001667 wsa_macro_config_ear_spkr_gain(component, wsa_priv,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301668 event, gain_reg);
1669 break;
1670 }
1671
1672 return 0;
1673}
1674
Meng Wang15c825d2018-09-06 10:49:18 +08001675static int wsa_macro_config_ear_spkr_gain(struct snd_soc_component *component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301676 struct wsa_macro_priv *wsa_priv,
1677 int event, int gain_reg)
1678{
1679 int comp_gain_offset, val;
1680
1681 switch (wsa_priv->spkr_mode) {
Laxminath Kasam21c8b222018-06-21 18:47:22 +05301682 /* Compander gain in WSA_MACRO_SPKR_MODE1 case is 12 dB */
1683 case WSA_MACRO_SPKR_MODE_1:
Laxminath Kasam243e2752018-04-12 00:40:19 +05301684 comp_gain_offset = -12;
1685 break;
1686 /* Default case compander gain is 15 dB */
1687 default:
1688 comp_gain_offset = -15;
1689 break;
1690 }
1691
1692 switch (event) {
1693 case SND_SOC_DAPM_POST_PMU:
1694 /* Apply ear spkr gain only if compander is enabled */
1695 if (wsa_priv->comp_enabled[WSA_MACRO_COMP1] &&
1696 (gain_reg == BOLERO_CDC_WSA_RX0_RX_VOL_CTL) &&
1697 (wsa_priv->ear_spkr_gain != 0)) {
1698 /* For example, val is -8(-12+5-1) for 4dB of gain */
1699 val = comp_gain_offset + wsa_priv->ear_spkr_gain - 1;
Meng Wang15c825d2018-09-06 10:49:18 +08001700 snd_soc_component_write(component, gain_reg, val);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301701
1702 dev_dbg(wsa_priv->dev, "%s: RX0 Volume %d dB\n",
1703 __func__, val);
1704 }
1705 break;
1706 case SND_SOC_DAPM_POST_PMD:
1707 /*
1708 * Reset RX0 volume to 0 dB if compander is enabled and
1709 * ear_spkr_gain is non-zero.
1710 */
1711 if (wsa_priv->comp_enabled[WSA_MACRO_COMP1] &&
1712 (gain_reg == BOLERO_CDC_WSA_RX0_RX_VOL_CTL) &&
1713 (wsa_priv->ear_spkr_gain != 0)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001714 snd_soc_component_write(component, gain_reg, 0x0);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301715
1716 dev_dbg(wsa_priv->dev, "%s: Reset RX0 Volume to 0 dB\n",
1717 __func__);
1718 }
1719 break;
1720 }
1721
1722 return 0;
1723}
1724
1725static int wsa_macro_spk_boost_event(struct snd_soc_dapm_widget *w,
1726 struct snd_kcontrol *kcontrol,
1727 int event)
1728{
Meng Wang15c825d2018-09-06 10:49:18 +08001729 struct snd_soc_component *component =
1730 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301731 u16 boost_path_ctl, boost_path_cfg1;
1732 u16 reg, reg_mix;
1733
Meng Wang15c825d2018-09-06 10:49:18 +08001734 dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301735
1736 if (!strcmp(w->name, "WSA_RX INT0 CHAIN")) {
1737 boost_path_ctl = BOLERO_CDC_WSA_BOOST0_BOOST_PATH_CTL;
1738 boost_path_cfg1 = BOLERO_CDC_WSA_RX0_RX_PATH_CFG1;
1739 reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL;
1740 reg_mix = BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL;
1741 } else if (!strcmp(w->name, "WSA_RX INT1 CHAIN")) {
1742 boost_path_ctl = BOLERO_CDC_WSA_BOOST1_BOOST_PATH_CTL;
1743 boost_path_cfg1 = BOLERO_CDC_WSA_RX1_RX_PATH_CFG1;
1744 reg = BOLERO_CDC_WSA_RX1_RX_PATH_CTL;
1745 reg_mix = BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL;
1746 } else {
Meng Wang15c825d2018-09-06 10:49:18 +08001747 dev_err(component->dev, "%s: unknown widget: %s\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301748 __func__, w->name);
1749 return -EINVAL;
1750 }
1751
1752 switch (event) {
1753 case SND_SOC_DAPM_PRE_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08001754 snd_soc_component_update_bits(component, boost_path_cfg1,
1755 0x01, 0x01);
1756 snd_soc_component_update_bits(component, boost_path_ctl,
1757 0x10, 0x10);
1758 if ((snd_soc_component_read32(component, reg_mix)) & 0x10)
1759 snd_soc_component_update_bits(component, reg_mix,
1760 0x10, 0x00);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301761 break;
Laxminath Kasam0c857002018-07-17 23:47:17 +05301762 case SND_SOC_DAPM_POST_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08001763 snd_soc_component_update_bits(component, reg, 0x10, 0x00);
Laxminath Kasam0c857002018-07-17 23:47:17 +05301764 break;
Laxminath Kasam243e2752018-04-12 00:40:19 +05301765 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +08001766 snd_soc_component_update_bits(component, boost_path_ctl,
1767 0x10, 0x00);
1768 snd_soc_component_update_bits(component, boost_path_cfg1,
1769 0x01, 0x00);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301770 break;
1771 }
1772
1773 return 0;
1774}
1775
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301776
1777static int wsa_macro_enable_vbat(struct snd_soc_dapm_widget *w,
1778 struct snd_kcontrol *kcontrol,
1779 int event)
1780{
Meng Wang15c825d2018-09-06 10:49:18 +08001781 struct snd_soc_component *component =
1782 snd_soc_dapm_to_component(w->dapm);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301783 struct device *wsa_dev = NULL;
1784 struct wsa_macro_priv *wsa_priv = NULL;
1785 u16 vbat_path_cfg = 0;
1786 int softclip_path = 0;
1787
Meng Wang15c825d2018-09-06 10:49:18 +08001788 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301789 return -EINVAL;
1790
Meng Wang15c825d2018-09-06 10:49:18 +08001791 dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301792 if (!strcmp(w->name, "WSA_RX INT0 VBAT")) {
1793 vbat_path_cfg = BOLERO_CDC_WSA_RX0_RX_PATH_CFG1;
1794 softclip_path = WSA_MACRO_SOFTCLIP0;
1795 } else if (!strcmp(w->name, "WSA_RX INT1 VBAT")) {
1796 vbat_path_cfg = BOLERO_CDC_WSA_RX1_RX_PATH_CFG1;
1797 softclip_path = WSA_MACRO_SOFTCLIP1;
1798 }
1799
1800 switch (event) {
1801 case SND_SOC_DAPM_PRE_PMU:
1802 /* Enable clock for VBAT block */
Meng Wang15c825d2018-09-06 10:49:18 +08001803 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301804 BOLERO_CDC_WSA_VBAT_BCL_VBAT_PATH_CTL, 0x10, 0x10);
1805 /* Enable VBAT block */
Meng Wang15c825d2018-09-06 10:49:18 +08001806 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301807 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG, 0x01, 0x01);
1808 /* Update interpolator with 384K path */
Meng Wang15c825d2018-09-06 10:49:18 +08001809 snd_soc_component_update_bits(component, vbat_path_cfg,
1810 0x80, 0x80);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301811 /* Use attenuation mode */
Meng Wang15c825d2018-09-06 10:49:18 +08001812 snd_soc_component_update_bits(component,
1813 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG, 0x02, 0x00);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301814 /*
1815 * BCL block needs softclip clock and mux config to be enabled
1816 */
Meng Wang15c825d2018-09-06 10:49:18 +08001817 wsa_macro_enable_softclip_clk(component, wsa_priv,
1818 softclip_path, true);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301819 /* Enable VBAT at channel level */
Meng Wang15c825d2018-09-06 10:49:18 +08001820 snd_soc_component_update_bits(component, vbat_path_cfg,
1821 0x02, 0x02);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301822 /* Set the ATTK1 gain */
Meng Wang15c825d2018-09-06 10:49:18 +08001823 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301824 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD1,
1825 0xFF, 0xFF);
Meng Wang15c825d2018-09-06 10:49:18 +08001826 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301827 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD2,
1828 0xFF, 0x03);
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_UPD3,
1831 0xFF, 0x00);
1832 /* Set the ATTK2 gain */
Meng Wang15c825d2018-09-06 10:49:18 +08001833 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301834 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD4,
1835 0xFF, 0xFF);
Meng Wang15c825d2018-09-06 10:49:18 +08001836 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301837 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD5,
1838 0xFF, 0x03);
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_UPD6,
1841 0xFF, 0x00);
1842 /* Set the ATTK3 gain */
Meng Wang15c825d2018-09-06 10:49:18 +08001843 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301844 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD7,
1845 0xFF, 0xFF);
Meng Wang15c825d2018-09-06 10:49:18 +08001846 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301847 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD8,
1848 0xFF, 0x03);
Meng Wang15c825d2018-09-06 10:49:18 +08001849 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301850 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD9,
1851 0xFF, 0x00);
1852 break;
1853
1854 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +08001855 snd_soc_component_update_bits(component, vbat_path_cfg,
1856 0x80, 0x00);
1857 snd_soc_component_update_bits(component,
1858 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG,
1859 0x02, 0x02);
1860 snd_soc_component_update_bits(component, vbat_path_cfg,
1861 0x02, 0x00);
1862 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301863 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD1,
1864 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001865 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301866 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD2,
1867 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001868 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301869 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD3,
1870 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001871 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301872 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD4,
1873 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001874 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301875 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD5,
1876 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001877 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301878 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD6,
1879 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001880 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301881 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD7,
1882 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001883 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301884 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD8,
1885 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001886 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301887 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD9,
1888 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001889 wsa_macro_enable_softclip_clk(component, wsa_priv,
1890 softclip_path, false);
1891 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301892 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG, 0x01, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001893 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301894 BOLERO_CDC_WSA_VBAT_BCL_VBAT_PATH_CTL, 0x10, 0x00);
1895 break;
1896 default:
1897 dev_err(wsa_dev, "%s: Invalid event %d\n", __func__, event);
1898 break;
1899 }
1900 return 0;
1901}
1902
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301903static int wsa_macro_enable_echo(struct snd_soc_dapm_widget *w,
1904 struct snd_kcontrol *kcontrol,
1905 int event)
1906{
Meng Wang15c825d2018-09-06 10:49:18 +08001907 struct snd_soc_component *component =
1908 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301909 struct device *wsa_dev = NULL;
1910 struct wsa_macro_priv *wsa_priv = NULL;
1911 u16 val, ec_tx = 0, ec_hq_reg;
1912
Meng Wang15c825d2018-09-06 10:49:18 +08001913 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301914 return -EINVAL;
1915
1916 dev_dbg(wsa_dev, "%s %d %s\n", __func__, event, w->name);
1917
Meng Wang15c825d2018-09-06 10:49:18 +08001918 val = snd_soc_component_read32(component,
1919 BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301920 if (!(strcmp(w->name, "WSA RX_MIX EC0_MUX")))
1921 ec_tx = (val & 0x07) - 1;
1922 else
1923 ec_tx = ((val & 0x38) >> 0x3) - 1;
1924
1925 if (ec_tx < 0 || ec_tx >= (WSA_MACRO_RX1 + 1)) {
1926 dev_err(wsa_dev, "%s: EC mix control not set correctly\n",
1927 __func__);
1928 return -EINVAL;
1929 }
1930 if (wsa_priv->ec_hq[ec_tx]) {
Meng Wang15c825d2018-09-06 10:49:18 +08001931 snd_soc_component_update_bits(component,
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301932 BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0,
1933 0x1 << ec_tx, 0x1 << ec_tx);
1934 ec_hq_reg = BOLERO_CDC_WSA_EC_HQ0_EC_REF_HQ_PATH_CTL +
Laxminath Kasam5d9ea8d2018-11-28 14:32:40 +05301935 0x40 * ec_tx;
Meng Wang15c825d2018-09-06 10:49:18 +08001936 snd_soc_component_update_bits(component, ec_hq_reg, 0x01, 0x01);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301937 ec_hq_reg = BOLERO_CDC_WSA_EC_HQ0_EC_REF_HQ_CFG0 +
Laxminath Kasam5d9ea8d2018-11-28 14:32:40 +05301938 0x40 * ec_tx;
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301939 /* default set to 48k */
Meng Wang15c825d2018-09-06 10:49:18 +08001940 snd_soc_component_update_bits(component, ec_hq_reg, 0x1E, 0x08);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301941 }
1942
1943 return 0;
1944}
1945
1946static int wsa_macro_get_ec_hq(struct snd_kcontrol *kcontrol,
1947 struct snd_ctl_elem_value *ucontrol)
1948{
1949
Meng Wang15c825d2018-09-06 10:49:18 +08001950 struct snd_soc_component *component =
1951 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301952 int ec_tx = ((struct soc_multi_mixer_control *)
1953 kcontrol->private_value)->shift;
1954 struct device *wsa_dev = NULL;
1955 struct wsa_macro_priv *wsa_priv = NULL;
1956
Meng Wang15c825d2018-09-06 10:49:18 +08001957 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301958 return -EINVAL;
1959
1960 ucontrol->value.integer.value[0] = wsa_priv->ec_hq[ec_tx];
1961 return 0;
1962}
1963
1964static int wsa_macro_set_ec_hq(struct snd_kcontrol *kcontrol,
1965 struct snd_ctl_elem_value *ucontrol)
1966{
Meng Wang15c825d2018-09-06 10:49:18 +08001967 struct snd_soc_component *component =
1968 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301969 int ec_tx = ((struct soc_multi_mixer_control *)
1970 kcontrol->private_value)->shift;
1971 int value = ucontrol->value.integer.value[0];
1972 struct device *wsa_dev = NULL;
1973 struct wsa_macro_priv *wsa_priv = NULL;
1974
Meng Wang15c825d2018-09-06 10:49:18 +08001975 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301976 return -EINVAL;
1977
1978 dev_dbg(wsa_dev, "%s: enable current %d, new %d\n",
1979 __func__, wsa_priv->ec_hq[ec_tx], value);
1980 wsa_priv->ec_hq[ec_tx] = value;
1981
1982 return 0;
1983}
1984
Vatsal Buchaf2a71b62019-03-26 16:14:40 +05301985static int wsa_macro_get_rx_mute_status(struct snd_kcontrol *kcontrol,
1986 struct snd_ctl_elem_value *ucontrol)
1987{
1988
1989 struct snd_soc_component *component =
1990 snd_soc_kcontrol_component(kcontrol);
1991 struct device *wsa_dev = NULL;
1992 struct wsa_macro_priv *wsa_priv = NULL;
1993 int wsa_rx_shift = ((struct soc_multi_mixer_control *)
1994 kcontrol->private_value)->shift;
1995
1996 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
1997 return -EINVAL;
1998
1999 ucontrol->value.integer.value[0] =
2000 wsa_priv->wsa_digital_mute_status[wsa_rx_shift];
2001 return 0;
2002}
2003
2004static int wsa_macro_set_rx_mute_status(struct snd_kcontrol *kcontrol,
2005 struct snd_ctl_elem_value *ucontrol)
2006{
2007 struct snd_soc_component *component =
2008 snd_soc_kcontrol_component(kcontrol);
2009 struct device *wsa_dev = NULL;
2010 struct wsa_macro_priv *wsa_priv = NULL;
2011 int value = ucontrol->value.integer.value[0];
2012 int wsa_rx_shift = ((struct soc_multi_mixer_control *)
2013 kcontrol->private_value)->shift;
2014
2015 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
2016 return -EINVAL;
2017
2018 switch (wsa_rx_shift) {
2019 case 0:
2020 snd_soc_component_update_bits(component,
2021 BOLERO_CDC_WSA_RX0_RX_PATH_CTL,
2022 0x10, value << 4);
2023 break;
2024 case 1:
2025 snd_soc_component_update_bits(component,
2026 BOLERO_CDC_WSA_RX1_RX_PATH_CTL,
2027 0x10, value << 4);
2028 break;
2029 case 2:
2030 snd_soc_component_update_bits(component,
2031 BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL,
2032 0x10, value << 4);
2033 break;
2034 case 3:
2035 snd_soc_component_update_bits(component,
2036 BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL,
2037 0x10, value << 4);
2038 break;
2039 default:
2040 pr_err("%s: invalid argument rx_shift = %d\n", __func__,
2041 wsa_rx_shift);
2042 return -EINVAL;
2043 }
2044
2045 dev_dbg(component->dev, "%s: WSA Digital Mute RX %d Enable %d\n",
2046 __func__, wsa_rx_shift, value);
2047 wsa_priv->wsa_digital_mute_status[wsa_rx_shift] = value;
2048 return 0;
2049}
2050
Laxminath Kasam243e2752018-04-12 00:40:19 +05302051static int wsa_macro_get_compander(struct snd_kcontrol *kcontrol,
2052 struct snd_ctl_elem_value *ucontrol)
2053{
2054
Meng Wang15c825d2018-09-06 10:49:18 +08002055 struct snd_soc_component *component =
2056 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302057 int comp = ((struct soc_multi_mixer_control *)
2058 kcontrol->private_value)->shift;
2059 struct device *wsa_dev = NULL;
2060 struct wsa_macro_priv *wsa_priv = NULL;
2061
Meng Wang15c825d2018-09-06 10:49:18 +08002062 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302063 return -EINVAL;
2064
2065 ucontrol->value.integer.value[0] = wsa_priv->comp_enabled[comp];
2066 return 0;
2067}
2068
2069static int wsa_macro_set_compander(struct snd_kcontrol *kcontrol,
2070 struct snd_ctl_elem_value *ucontrol)
2071{
Meng Wang15c825d2018-09-06 10:49:18 +08002072 struct snd_soc_component *component =
2073 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302074 int comp = ((struct soc_multi_mixer_control *)
2075 kcontrol->private_value)->shift;
2076 int value = ucontrol->value.integer.value[0];
2077 struct device *wsa_dev = NULL;
2078 struct wsa_macro_priv *wsa_priv = NULL;
2079
Meng Wang15c825d2018-09-06 10:49:18 +08002080 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302081 return -EINVAL;
2082
Meng Wang15c825d2018-09-06 10:49:18 +08002083 dev_dbg(component->dev, "%s: Compander %d enable current %d, new %d\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05302084 __func__, comp + 1, wsa_priv->comp_enabled[comp], value);
2085 wsa_priv->comp_enabled[comp] = value;
2086
2087 return 0;
2088}
2089
2090static int wsa_macro_ear_spkr_pa_gain_get(struct snd_kcontrol *kcontrol,
2091 struct snd_ctl_elem_value *ucontrol)
2092{
Meng Wang15c825d2018-09-06 10:49:18 +08002093 struct snd_soc_component *component =
2094 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302095 struct device *wsa_dev = NULL;
2096 struct wsa_macro_priv *wsa_priv = NULL;
2097
Meng Wang15c825d2018-09-06 10:49:18 +08002098 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302099 return -EINVAL;
2100
2101 ucontrol->value.integer.value[0] = wsa_priv->ear_spkr_gain;
2102
Meng Wang15c825d2018-09-06 10:49:18 +08002103 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05302104 __func__, ucontrol->value.integer.value[0]);
2105
2106 return 0;
2107}
2108
2109static int wsa_macro_ear_spkr_pa_gain_put(struct snd_kcontrol *kcontrol,
2110 struct snd_ctl_elem_value *ucontrol)
2111{
Meng Wang15c825d2018-09-06 10:49:18 +08002112 struct snd_soc_component *component =
2113 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302114 struct device *wsa_dev = NULL;
2115 struct wsa_macro_priv *wsa_priv = NULL;
2116
Meng Wang15c825d2018-09-06 10:49:18 +08002117 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302118 return -EINVAL;
2119
2120 wsa_priv->ear_spkr_gain = ucontrol->value.integer.value[0];
2121
Meng Wang15c825d2018-09-06 10:49:18 +08002122 dev_dbg(component->dev, "%s: gain = %d\n", __func__,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302123 wsa_priv->ear_spkr_gain);
2124
2125 return 0;
2126}
2127
2128static int wsa_macro_spkr_left_boost_stage_get(struct snd_kcontrol *kcontrol,
2129 struct snd_ctl_elem_value *ucontrol)
2130{
2131 u8 bst_state_max = 0;
Meng Wang15c825d2018-09-06 10:49:18 +08002132 struct snd_soc_component *component =
2133 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302134
Meng Wang15c825d2018-09-06 10:49:18 +08002135 bst_state_max = snd_soc_component_read32(component,
2136 BOLERO_CDC_WSA_BOOST0_BOOST_CTL);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302137 bst_state_max = (bst_state_max & 0x0c) >> 2;
2138 ucontrol->value.integer.value[0] = bst_state_max;
Meng Wang15c825d2018-09-06 10:49:18 +08002139 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05302140 __func__, ucontrol->value.integer.value[0]);
2141
2142 return 0;
2143}
2144
2145static int wsa_macro_spkr_left_boost_stage_put(struct snd_kcontrol *kcontrol,
2146 struct snd_ctl_elem_value *ucontrol)
2147{
2148 u8 bst_state_max;
Meng Wang15c825d2018-09-06 10:49:18 +08002149 struct snd_soc_component *component =
2150 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302151
Meng Wang15c825d2018-09-06 10:49:18 +08002152 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05302153 __func__, ucontrol->value.integer.value[0]);
2154 bst_state_max = ucontrol->value.integer.value[0] << 2;
Karthikeyan Mani10de3932019-04-15 11:46:57 -07002155 /* bolero does not need to limit the boost levels */
Laxminath Kasam243e2752018-04-12 00:40:19 +05302156
2157 return 0;
2158}
2159
2160static int wsa_macro_spkr_right_boost_stage_get(struct snd_kcontrol *kcontrol,
2161 struct snd_ctl_elem_value *ucontrol)
2162{
2163 u8 bst_state_max = 0;
Meng Wang15c825d2018-09-06 10:49:18 +08002164 struct snd_soc_component *component =
2165 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302166
Meng Wang15c825d2018-09-06 10:49:18 +08002167 bst_state_max = snd_soc_component_read32(component,
2168 BOLERO_CDC_WSA_BOOST1_BOOST_CTL);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302169 bst_state_max = (bst_state_max & 0x0c) >> 2;
2170 ucontrol->value.integer.value[0] = bst_state_max;
Meng Wang15c825d2018-09-06 10:49:18 +08002171 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05302172 __func__, ucontrol->value.integer.value[0]);
2173
2174 return 0;
2175}
2176
2177static int wsa_macro_spkr_right_boost_stage_put(struct snd_kcontrol *kcontrol,
2178 struct snd_ctl_elem_value *ucontrol)
2179{
2180 u8 bst_state_max;
Meng Wang15c825d2018-09-06 10:49:18 +08002181 struct snd_soc_component *component =
2182 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302183
Meng Wang15c825d2018-09-06 10:49:18 +08002184 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05302185 __func__, ucontrol->value.integer.value[0]);
2186 bst_state_max = ucontrol->value.integer.value[0] << 2;
Karthikeyan Mani10de3932019-04-15 11:46:57 -07002187 /* bolero does not need to limit the boost levels */
Laxminath Kasam243e2752018-04-12 00:40:19 +05302188
2189 return 0;
2190}
2191
2192static int wsa_macro_rx_mux_get(struct snd_kcontrol *kcontrol,
2193 struct snd_ctl_elem_value *ucontrol)
2194{
2195 struct snd_soc_dapm_widget *widget =
2196 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +08002197 struct snd_soc_component *component =
2198 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302199 struct device *wsa_dev = NULL;
2200 struct wsa_macro_priv *wsa_priv = NULL;
2201
Meng Wang15c825d2018-09-06 10:49:18 +08002202 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302203 return -EINVAL;
2204
2205 ucontrol->value.integer.value[0] =
2206 wsa_priv->rx_port_value[widget->shift];
2207 return 0;
2208}
2209
2210static int wsa_macro_rx_mux_put(struct snd_kcontrol *kcontrol,
2211 struct snd_ctl_elem_value *ucontrol)
2212{
2213 struct snd_soc_dapm_widget *widget =
2214 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +08002215 struct snd_soc_component *component =
2216 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302217 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
2218 struct snd_soc_dapm_update *update = NULL;
2219 u32 rx_port_value = ucontrol->value.integer.value[0];
2220 u32 bit_input = 0;
2221 u32 aif_rst;
2222 struct device *wsa_dev = NULL;
2223 struct wsa_macro_priv *wsa_priv = NULL;
2224
Meng Wang15c825d2018-09-06 10:49:18 +08002225 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302226 return -EINVAL;
2227
2228 aif_rst = wsa_priv->rx_port_value[widget->shift];
2229 if (!rx_port_value) {
2230 if (aif_rst == 0) {
2231 dev_err(wsa_dev, "%s: AIF reset already\n", __func__);
2232 return 0;
2233 }
Sudheer Papothic0f75b72019-07-16 06:04:10 +05302234 if (aif_rst >= WSA_MACRO_RX_MAX) {
2235 dev_err(wsa_dev, "%s: Invalid AIF reset\n", __func__);
2236 return 0;
2237 }
Laxminath Kasam243e2752018-04-12 00:40:19 +05302238 }
2239 wsa_priv->rx_port_value[widget->shift] = rx_port_value;
2240
2241 bit_input = widget->shift;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302242
Sudheer Papothic0f75b72019-07-16 06:04:10 +05302243 dev_dbg(wsa_dev,
2244 "%s: mux input: %d, mux output: %d, bit: %d\n",
2245 __func__, rx_port_value, widget->shift, bit_input);
2246
Laxminath Kasam243e2752018-04-12 00:40:19 +05302247 switch (rx_port_value) {
2248 case 0:
Sudheer Papothic0f75b72019-07-16 06:04:10 +05302249 if (wsa_priv->active_ch_cnt[aif_rst]) {
2250 clear_bit(bit_input,
2251 &wsa_priv->active_ch_mask[aif_rst]);
2252 wsa_priv->active_ch_cnt[aif_rst]--;
2253 }
Laxminath Kasam243e2752018-04-12 00:40:19 +05302254 break;
2255 case 1:
2256 case 2:
2257 set_bit(bit_input,
Laxminath Kasam59c7a1d2018-08-09 16:11:17 +05302258 &wsa_priv->active_ch_mask[rx_port_value]);
2259 wsa_priv->active_ch_cnt[rx_port_value]++;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302260 break;
2261 default:
2262 dev_err(wsa_dev,
Sudheer Papothic0f75b72019-07-16 06:04:10 +05302263 "%s: Invalid AIF_ID for WSA RX MUX %d\n",
2264 __func__, rx_port_value);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302265 return -EINVAL;
2266 }
2267
2268 snd_soc_dapm_mux_update_power(widget->dapm, kcontrol,
2269 rx_port_value, e, update);
2270 return 0;
2271}
2272
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302273static int wsa_macro_vbat_bcl_gsm_mode_func_get(struct snd_kcontrol *kcontrol,
2274 struct snd_ctl_elem_value *ucontrol)
2275{
Meng Wang15c825d2018-09-06 10:49:18 +08002276 struct snd_soc_component *component =
2277 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302278
2279 ucontrol->value.integer.value[0] =
Meng Wang15c825d2018-09-06 10:49:18 +08002280 ((snd_soc_component_read32(
2281 component, BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG) & 0x04) ?
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302282 1 : 0);
2283
Meng Wang15c825d2018-09-06 10:49:18 +08002284 dev_dbg(component->dev, "%s: value: %lu\n", __func__,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302285 ucontrol->value.integer.value[0]);
2286
2287 return 0;
2288}
2289
2290static int wsa_macro_vbat_bcl_gsm_mode_func_put(struct snd_kcontrol *kcontrol,
2291 struct snd_ctl_elem_value *ucontrol)
2292{
Meng Wang15c825d2018-09-06 10:49:18 +08002293 struct snd_soc_component *component =
2294 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302295
Meng Wang15c825d2018-09-06 10:49:18 +08002296 dev_dbg(component->dev, "%s: value: %lu\n", __func__,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302297 ucontrol->value.integer.value[0]);
2298
2299 /* Set Vbat register configuration for GSM mode bit based on value */
2300 if (ucontrol->value.integer.value[0])
Meng Wang15c825d2018-09-06 10:49:18 +08002301 snd_soc_component_update_bits(component,
2302 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG,
2303 0x04, 0x04);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302304 else
Meng Wang15c825d2018-09-06 10:49:18 +08002305 snd_soc_component_update_bits(component,
2306 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG,
2307 0x04, 0x00);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302308
2309 return 0;
2310}
2311
2312static int wsa_macro_soft_clip_enable_get(struct snd_kcontrol *kcontrol,
2313 struct snd_ctl_elem_value *ucontrol)
2314{
Meng Wang15c825d2018-09-06 10:49:18 +08002315 struct snd_soc_component *component =
2316 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302317 struct device *wsa_dev = NULL;
2318 struct wsa_macro_priv *wsa_priv = NULL;
2319 int path = ((struct soc_multi_mixer_control *)
2320 kcontrol->private_value)->shift;
2321
Meng Wang15c825d2018-09-06 10:49:18 +08002322 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302323 return -EINVAL;
2324
2325 ucontrol->value.integer.value[0] = wsa_priv->is_softclip_on[path];
2326
Meng Wang15c825d2018-09-06 10:49:18 +08002327 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302328 __func__, ucontrol->value.integer.value[0]);
2329
2330 return 0;
2331}
2332
2333static int wsa_macro_soft_clip_enable_put(struct snd_kcontrol *kcontrol,
2334 struct snd_ctl_elem_value *ucontrol)
2335{
Meng Wang15c825d2018-09-06 10:49:18 +08002336 struct snd_soc_component *component =
2337 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302338 struct device *wsa_dev = NULL;
2339 struct wsa_macro_priv *wsa_priv = NULL;
2340 int path = ((struct soc_multi_mixer_control *)
2341 kcontrol->private_value)->shift;
2342
Meng Wang15c825d2018-09-06 10:49:18 +08002343 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302344 return -EINVAL;
2345
2346 wsa_priv->is_softclip_on[path] = ucontrol->value.integer.value[0];
2347
Meng Wang15c825d2018-09-06 10:49:18 +08002348 dev_dbg(component->dev, "%s: soft clip enable for %d: %d\n", __func__,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302349 path, wsa_priv->is_softclip_on[path]);
2350
2351 return 0;
2352}
2353
Laxminath Kasam243e2752018-04-12 00:40:19 +05302354static const struct snd_kcontrol_new wsa_macro_snd_controls[] = {
2355 SOC_ENUM_EXT("EAR SPKR PA Gain", wsa_macro_ear_spkr_pa_gain_enum,
2356 wsa_macro_ear_spkr_pa_gain_get,
2357 wsa_macro_ear_spkr_pa_gain_put),
2358 SOC_ENUM_EXT("SPKR Left Boost Max State",
2359 wsa_macro_spkr_boost_stage_enum,
2360 wsa_macro_spkr_left_boost_stage_get,
2361 wsa_macro_spkr_left_boost_stage_put),
2362 SOC_ENUM_EXT("SPKR Right Boost Max State",
2363 wsa_macro_spkr_boost_stage_enum,
2364 wsa_macro_spkr_right_boost_stage_get,
2365 wsa_macro_spkr_right_boost_stage_put),
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302366 SOC_ENUM_EXT("GSM mode Enable", wsa_macro_vbat_bcl_gsm_mode_enum,
2367 wsa_macro_vbat_bcl_gsm_mode_func_get,
2368 wsa_macro_vbat_bcl_gsm_mode_func_put),
2369 SOC_SINGLE_EXT("WSA_Softclip0 Enable", SND_SOC_NOPM,
2370 WSA_MACRO_SOFTCLIP0, 1, 0,
2371 wsa_macro_soft_clip_enable_get,
2372 wsa_macro_soft_clip_enable_put),
2373 SOC_SINGLE_EXT("WSA_Softclip1 Enable", SND_SOC_NOPM,
2374 WSA_MACRO_SOFTCLIP1, 1, 0,
2375 wsa_macro_soft_clip_enable_get,
2376 wsa_macro_soft_clip_enable_put),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302377 SOC_SINGLE_SX_TLV("WSA_RX0 Digital Volume",
2378 BOLERO_CDC_WSA_RX0_RX_VOL_CTL,
2379 0, -84, 40, digital_gain),
2380 SOC_SINGLE_SX_TLV("WSA_RX1 Digital Volume",
2381 BOLERO_CDC_WSA_RX1_RX_VOL_CTL,
2382 0, -84, 40, digital_gain),
Vatsal Buchaf2a71b62019-03-26 16:14:40 +05302383 SOC_SINGLE_EXT("WSA_RX0 Digital Mute", SND_SOC_NOPM, WSA_MACRO_RX0, 1,
2384 0, wsa_macro_get_rx_mute_status,
2385 wsa_macro_set_rx_mute_status),
2386 SOC_SINGLE_EXT("WSA_RX1 Digital Mute", SND_SOC_NOPM, WSA_MACRO_RX1, 1,
2387 0, wsa_macro_get_rx_mute_status,
2388 wsa_macro_set_rx_mute_status),
2389 SOC_SINGLE_EXT("WSA_RX0_MIX Digital Mute", SND_SOC_NOPM,
2390 WSA_MACRO_RX_MIX0, 1, 0, wsa_macro_get_rx_mute_status,
2391 wsa_macro_set_rx_mute_status),
2392 SOC_SINGLE_EXT("WSA_RX1_MIX Digital Mute", SND_SOC_NOPM,
2393 WSA_MACRO_RX_MIX1, 1, 0, wsa_macro_get_rx_mute_status,
2394 wsa_macro_set_rx_mute_status),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302395 SOC_SINGLE_EXT("WSA_COMP1 Switch", SND_SOC_NOPM, WSA_MACRO_COMP1, 1, 0,
2396 wsa_macro_get_compander, wsa_macro_set_compander),
2397 SOC_SINGLE_EXT("WSA_COMP2 Switch", SND_SOC_NOPM, WSA_MACRO_COMP2, 1, 0,
2398 wsa_macro_get_compander, wsa_macro_set_compander),
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05302399 SOC_SINGLE_EXT("WSA_RX0 EC_HQ Switch", SND_SOC_NOPM, WSA_MACRO_RX0,
2400 1, 0, wsa_macro_get_ec_hq, wsa_macro_set_ec_hq),
2401 SOC_SINGLE_EXT("WSA_RX1 EC_HQ Switch", SND_SOC_NOPM, WSA_MACRO_RX1,
2402 1, 0, wsa_macro_get_ec_hq, wsa_macro_set_ec_hq),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302403};
2404
2405static const struct soc_enum rx_mux_enum =
2406 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_mux_text), rx_mux_text);
2407
2408static const struct snd_kcontrol_new rx_mux[WSA_MACRO_RX_MAX] = {
2409 SOC_DAPM_ENUM_EXT("WSA RX0 Mux", rx_mux_enum,
2410 wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),
2411 SOC_DAPM_ENUM_EXT("WSA RX1 Mux", rx_mux_enum,
2412 wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),
2413 SOC_DAPM_ENUM_EXT("WSA RX_MIX0 Mux", rx_mux_enum,
2414 wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),
2415 SOC_DAPM_ENUM_EXT("WSA RX_MIX1 Mux", rx_mux_enum,
2416 wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),
2417};
2418
2419static int wsa_macro_vi_feed_mixer_get(struct snd_kcontrol *kcontrol,
2420 struct snd_ctl_elem_value *ucontrol)
2421{
2422 struct snd_soc_dapm_widget *widget =
2423 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +08002424 struct snd_soc_component *component =
2425 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302426 struct soc_multi_mixer_control *mixer =
2427 ((struct soc_multi_mixer_control *)kcontrol->private_value);
2428 u32 dai_id = widget->shift;
2429 u32 spk_tx_id = mixer->shift;
2430 struct device *wsa_dev = NULL;
2431 struct wsa_macro_priv *wsa_priv = NULL;
2432
Meng Wang15c825d2018-09-06 10:49:18 +08002433 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302434 return -EINVAL;
2435
2436 if (test_bit(spk_tx_id, &wsa_priv->active_ch_mask[dai_id]))
2437 ucontrol->value.integer.value[0] = 1;
2438 else
2439 ucontrol->value.integer.value[0] = 0;
2440
2441 return 0;
2442}
2443
2444static int wsa_macro_vi_feed_mixer_put(struct snd_kcontrol *kcontrol,
2445 struct snd_ctl_elem_value *ucontrol)
2446{
2447 struct snd_soc_dapm_widget *widget =
2448 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +08002449 struct snd_soc_component *component =
2450 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302451 struct soc_multi_mixer_control *mixer =
2452 ((struct soc_multi_mixer_control *)kcontrol->private_value);
2453 u32 spk_tx_id = mixer->shift;
2454 u32 enable = ucontrol->value.integer.value[0];
2455 struct device *wsa_dev = NULL;
2456 struct wsa_macro_priv *wsa_priv = NULL;
2457
Meng Wang15c825d2018-09-06 10:49:18 +08002458 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302459 return -EINVAL;
2460
2461 wsa_priv->vi_feed_value = ucontrol->value.integer.value[0];
2462
2463 if (enable) {
2464 if (spk_tx_id == WSA_MACRO_TX0 &&
2465 !test_bit(WSA_MACRO_TX0,
2466 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
2467 set_bit(WSA_MACRO_TX0,
2468 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI]);
2469 wsa_priv->active_ch_cnt[WSA_MACRO_AIF_VI]++;
2470 }
2471 if (spk_tx_id == WSA_MACRO_TX1 &&
2472 !test_bit(WSA_MACRO_TX1,
2473 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
2474 set_bit(WSA_MACRO_TX1,
2475 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI]);
2476 wsa_priv->active_ch_cnt[WSA_MACRO_AIF_VI]++;
2477 }
2478 } else {
2479 if (spk_tx_id == WSA_MACRO_TX0 &&
2480 test_bit(WSA_MACRO_TX0,
2481 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
2482 clear_bit(WSA_MACRO_TX0,
2483 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI]);
2484 wsa_priv->active_ch_cnt[WSA_MACRO_AIF_VI]--;
2485 }
2486 if (spk_tx_id == WSA_MACRO_TX1 &&
2487 test_bit(WSA_MACRO_TX1,
2488 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
2489 clear_bit(WSA_MACRO_TX1,
2490 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI]);
2491 wsa_priv->active_ch_cnt[WSA_MACRO_AIF_VI]--;
2492 }
2493 }
2494 snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, NULL);
2495
2496 return 0;
2497}
2498
2499static const struct snd_kcontrol_new aif_vi_mixer[] = {
2500 SOC_SINGLE_EXT("WSA_SPKR_VI_1", SND_SOC_NOPM, WSA_MACRO_TX0, 1, 0,
2501 wsa_macro_vi_feed_mixer_get,
2502 wsa_macro_vi_feed_mixer_put),
2503 SOC_SINGLE_EXT("WSA_SPKR_VI_2", SND_SOC_NOPM, WSA_MACRO_TX1, 1, 0,
2504 wsa_macro_vi_feed_mixer_get,
2505 wsa_macro_vi_feed_mixer_put),
2506};
2507
2508static const struct snd_soc_dapm_widget wsa_macro_dapm_widgets[] = {
2509 SND_SOC_DAPM_AIF_IN("WSA AIF1 PB", "WSA_AIF1 Playback", 0,
2510 SND_SOC_NOPM, 0, 0),
2511
2512 SND_SOC_DAPM_AIF_IN("WSA AIF_MIX1 PB", "WSA_AIF_MIX1 Playback", 0,
2513 SND_SOC_NOPM, 0, 0),
2514
2515 SND_SOC_DAPM_AIF_OUT_E("WSA AIF_VI", "WSA_AIF_VI Capture", 0,
2516 SND_SOC_NOPM, WSA_MACRO_AIF_VI, 0,
2517 wsa_macro_enable_vi_feedback,
2518 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
2519
2520 SND_SOC_DAPM_AIF_OUT("WSA AIF_ECHO", "WSA_AIF_ECHO Capture", 0,
2521 SND_SOC_NOPM, 0, 0),
2522
2523 SND_SOC_DAPM_MIXER("WSA_AIF_VI Mixer", SND_SOC_NOPM, WSA_MACRO_AIF_VI,
2524 0, aif_vi_mixer, ARRAY_SIZE(aif_vi_mixer)),
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05302525 SND_SOC_DAPM_MUX_E("WSA RX_MIX EC0_MUX", SND_SOC_NOPM,
2526 WSA_MACRO_EC0_MUX, 0,
2527 &rx_mix_ec0_mux, wsa_macro_enable_echo,
2528 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2529 SND_SOC_DAPM_MUX_E("WSA RX_MIX EC1_MUX", SND_SOC_NOPM,
2530 WSA_MACRO_EC1_MUX, 0,
2531 &rx_mix_ec1_mux, wsa_macro_enable_echo,
2532 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302533
2534 SND_SOC_DAPM_MUX("WSA RX0 MUX", SND_SOC_NOPM, WSA_MACRO_RX0, 0,
2535 &rx_mux[WSA_MACRO_RX0]),
2536 SND_SOC_DAPM_MUX("WSA RX1 MUX", SND_SOC_NOPM, WSA_MACRO_RX1, 0,
2537 &rx_mux[WSA_MACRO_RX1]),
2538 SND_SOC_DAPM_MUX("WSA RX_MIX0 MUX", SND_SOC_NOPM, WSA_MACRO_RX_MIX0, 0,
2539 &rx_mux[WSA_MACRO_RX_MIX0]),
2540 SND_SOC_DAPM_MUX("WSA RX_MIX1 MUX", SND_SOC_NOPM, WSA_MACRO_RX_MIX1, 0,
2541 &rx_mux[WSA_MACRO_RX_MIX1]),
2542
2543 SND_SOC_DAPM_MIXER("WSA RX0", SND_SOC_NOPM, 0, 0, NULL, 0),
2544 SND_SOC_DAPM_MIXER("WSA RX1", SND_SOC_NOPM, 0, 0, NULL, 0),
2545 SND_SOC_DAPM_MIXER("WSA RX_MIX0", SND_SOC_NOPM, 0, 0, NULL, 0),
2546 SND_SOC_DAPM_MIXER("WSA RX_MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
2547
2548 SND_SOC_DAPM_MUX_E("WSA_RX0 INP0", SND_SOC_NOPM, 0, 0,
2549 &rx0_prim_inp0_mux, wsa_macro_enable_swr,
2550 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2551 SND_SOC_DAPM_MUX_E("WSA_RX0 INP1", SND_SOC_NOPM, 0, 0,
2552 &rx0_prim_inp1_mux, wsa_macro_enable_swr,
2553 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2554 SND_SOC_DAPM_MUX_E("WSA_RX0 INP2", SND_SOC_NOPM, 0, 0,
2555 &rx0_prim_inp2_mux, wsa_macro_enable_swr,
2556 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
Laxminath Kasam01d2eb22020-05-13 18:44:49 +05302557 SND_SOC_DAPM_MUX_E("WSA_RX0 MIX INP", SND_SOC_NOPM,
Laxminath Kasam52ae6582019-08-08 18:00:35 +05302558 0, 0, &rx0_mix_mux, wsa_macro_enable_mix_path,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302559 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2560 SND_SOC_DAPM_MUX_E("WSA_RX1 INP0", SND_SOC_NOPM, 0, 0,
2561 &rx1_prim_inp0_mux, wsa_macro_enable_swr,
2562 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2563 SND_SOC_DAPM_MUX_E("WSA_RX1 INP1", SND_SOC_NOPM, 0, 0,
2564 &rx1_prim_inp1_mux, wsa_macro_enable_swr,
2565 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2566 SND_SOC_DAPM_MUX_E("WSA_RX1 INP2", SND_SOC_NOPM, 0, 0,
2567 &rx1_prim_inp2_mux, wsa_macro_enable_swr,
2568 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
Laxminath Kasam01d2eb22020-05-13 18:44:49 +05302569 SND_SOC_DAPM_MUX_E("WSA_RX1 MIX INP", SND_SOC_NOPM,
Laxminath Kasam52ae6582019-08-08 18:00:35 +05302570 0, 0, &rx1_mix_mux, wsa_macro_enable_mix_path,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302571 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
Laxminath Kasam2fe71f52020-05-15 00:39:51 +05302572 SND_SOC_DAPM_PGA_E("WSA_RX INT0 MIX", SND_SOC_NOPM,
Laxminath Kasam52ae6582019-08-08 18:00:35 +05302573 0, 0, NULL, 0, wsa_macro_enable_main_path,
2574 SND_SOC_DAPM_PRE_PMU),
Laxminath Kasam2fe71f52020-05-15 00:39:51 +05302575 SND_SOC_DAPM_PGA_E("WSA_RX INT1 MIX", SND_SOC_NOPM,
Laxminath Kasam52ae6582019-08-08 18:00:35 +05302576 1, 0, NULL, 0, wsa_macro_enable_main_path,
2577 SND_SOC_DAPM_PRE_PMU),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302578 SND_SOC_DAPM_MIXER("WSA_RX INT0 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
2579 SND_SOC_DAPM_MIXER("WSA_RX INT1 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
2580
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302581 SND_SOC_DAPM_MUX_E("WSA_RX0 INT0 SIDETONE MIX",
2582 BOLERO_CDC_WSA_RX0_RX_PATH_CFG1, 4, 0,
2583 &rx0_sidetone_mix_mux, wsa_macro_enable_swr,
2584 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2585 SND_SOC_DAPM_INPUT("WSA SRC0_INP"),
2586
2587 SND_SOC_DAPM_INPUT("WSA_TX DEC0_INP"),
2588 SND_SOC_DAPM_INPUT("WSA_TX DEC1_INP"),
2589
Laxminath Kasam243e2752018-04-12 00:40:19 +05302590 SND_SOC_DAPM_MIXER_E("WSA_RX INT0 INTERP", SND_SOC_NOPM,
2591 WSA_MACRO_COMP1, 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 SND_SOC_DAPM_MIXER_E("WSA_RX INT1 INTERP", SND_SOC_NOPM,
2595 WSA_MACRO_COMP2, 0, NULL, 0, wsa_macro_enable_interpolator,
2596 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2597 SND_SOC_DAPM_POST_PMD),
2598
2599 SND_SOC_DAPM_MIXER_E("WSA_RX INT0 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 SND_SOC_DAPM_MIXER_E("WSA_RX INT1 CHAIN", SND_SOC_NOPM, 0, 0,
2604 NULL, 0, wsa_macro_spk_boost_event,
Laxminath Kasam0c857002018-07-17 23:47:17 +05302605 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2606 SND_SOC_DAPM_POST_PMD),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302607
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302608 SND_SOC_DAPM_MIXER_E("WSA_RX INT0 VBAT", SND_SOC_NOPM,
2609 0, 0, wsa_int0_vbat_mix_switch,
2610 ARRAY_SIZE(wsa_int0_vbat_mix_switch),
2611 wsa_macro_enable_vbat,
2612 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2613 SND_SOC_DAPM_MIXER_E("WSA_RX INT1 VBAT", SND_SOC_NOPM,
2614 0, 0, wsa_int1_vbat_mix_switch,
2615 ARRAY_SIZE(wsa_int1_vbat_mix_switch),
2616 wsa_macro_enable_vbat,
2617 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2618
Laxminath Kasam243e2752018-04-12 00:40:19 +05302619 SND_SOC_DAPM_INPUT("VIINPUT_WSA"),
2620
2621 SND_SOC_DAPM_OUTPUT("WSA_SPK1 OUT"),
2622 SND_SOC_DAPM_OUTPUT("WSA_SPK2 OUT"),
2623
2624 SND_SOC_DAPM_SUPPLY_S("WSA_MCLK", 0, SND_SOC_NOPM, 0, 0,
2625 wsa_macro_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2626};
2627
2628static const struct snd_soc_dapm_route wsa_audio_map[] = {
2629 /* VI Feedback */
2630 {"WSA_AIF_VI Mixer", "WSA_SPKR_VI_1", "VIINPUT_WSA"},
2631 {"WSA_AIF_VI Mixer", "WSA_SPKR_VI_2", "VIINPUT_WSA"},
2632 {"WSA AIF_VI", NULL, "WSA_AIF_VI Mixer"},
2633 {"WSA AIF_VI", NULL, "WSA_MCLK"},
2634
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05302635 {"WSA RX_MIX EC0_MUX", "RX_MIX_TX0", "WSA_RX INT0 SEC MIX"},
2636 {"WSA RX_MIX EC1_MUX", "RX_MIX_TX0", "WSA_RX INT0 SEC MIX"},
2637 {"WSA RX_MIX EC0_MUX", "RX_MIX_TX1", "WSA_RX INT1 SEC MIX"},
2638 {"WSA RX_MIX EC1_MUX", "RX_MIX_TX1", "WSA_RX INT1 SEC MIX"},
2639 {"WSA AIF_ECHO", NULL, "WSA RX_MIX EC0_MUX"},
2640 {"WSA AIF_ECHO", NULL, "WSA RX_MIX EC1_MUX"},
2641 {"WSA AIF_ECHO", NULL, "WSA_MCLK"},
2642
Laxminath Kasam243e2752018-04-12 00:40:19 +05302643 {"WSA AIF1 PB", NULL, "WSA_MCLK"},
2644 {"WSA AIF_MIX1 PB", NULL, "WSA_MCLK"},
2645
2646 {"WSA RX0 MUX", "AIF1_PB", "WSA AIF1 PB"},
2647 {"WSA RX1 MUX", "AIF1_PB", "WSA AIF1 PB"},
2648 {"WSA RX_MIX0 MUX", "AIF1_PB", "WSA AIF1 PB"},
2649 {"WSA RX_MIX1 MUX", "AIF1_PB", "WSA AIF1 PB"},
2650
2651 {"WSA RX0 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
2652 {"WSA RX1 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
2653 {"WSA RX_MIX0 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
2654 {"WSA RX_MIX1 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
2655
2656 {"WSA RX0", NULL, "WSA RX0 MUX"},
2657 {"WSA RX1", NULL, "WSA RX1 MUX"},
2658 {"WSA RX_MIX0", NULL, "WSA RX_MIX0 MUX"},
2659 {"WSA RX_MIX1", NULL, "WSA RX_MIX1 MUX"},
2660
2661 {"WSA_RX0 INP0", "RX0", "WSA RX0"},
2662 {"WSA_RX0 INP0", "RX1", "WSA RX1"},
2663 {"WSA_RX0 INP0", "RX_MIX0", "WSA RX_MIX0"},
2664 {"WSA_RX0 INP0", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302665 {"WSA_RX0 INP0", "DEC0", "WSA_TX DEC0_INP"},
2666 {"WSA_RX0 INP0", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302667 {"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP0"},
2668
2669 {"WSA_RX0 INP1", "RX0", "WSA RX0"},
2670 {"WSA_RX0 INP1", "RX1", "WSA RX1"},
2671 {"WSA_RX0 INP1", "RX_MIX0", "WSA RX_MIX0"},
2672 {"WSA_RX0 INP1", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302673 {"WSA_RX0 INP1", "DEC0", "WSA_TX DEC0_INP"},
2674 {"WSA_RX0 INP1", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302675 {"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP1"},
2676
2677 {"WSA_RX0 INP2", "RX0", "WSA RX0"},
2678 {"WSA_RX0 INP2", "RX1", "WSA RX1"},
2679 {"WSA_RX0 INP2", "RX_MIX0", "WSA RX_MIX0"},
2680 {"WSA_RX0 INP2", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302681 {"WSA_RX0 INP2", "DEC0", "WSA_TX DEC0_INP"},
2682 {"WSA_RX0 INP2", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302683 {"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP2"},
2684
2685 {"WSA_RX0 MIX INP", "RX0", "WSA RX0"},
2686 {"WSA_RX0 MIX INP", "RX1", "WSA RX1"},
2687 {"WSA_RX0 MIX INP", "RX_MIX0", "WSA RX_MIX0"},
2688 {"WSA_RX0 MIX INP", "RX_MIX1", "WSA RX_MIX1"},
2689 {"WSA_RX INT0 SEC MIX", NULL, "WSA_RX0 MIX INP"},
2690
2691 {"WSA_RX INT0 SEC MIX", NULL, "WSA_RX INT0 MIX"},
2692 {"WSA_RX INT0 INTERP", NULL, "WSA_RX INT0 SEC MIX"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302693 {"WSA_RX0 INT0 SIDETONE MIX", "SRC0", "WSA SRC0_INP"},
2694 {"WSA_RX INT0 INTERP", NULL, "WSA_RX0 INT0 SIDETONE MIX"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302695 {"WSA_RX INT0 CHAIN", NULL, "WSA_RX INT0 INTERP"},
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302696
2697 {"WSA_RX INT0 VBAT", "WSA RX0 VBAT Enable", "WSA_RX INT0 INTERP"},
2698 {"WSA_RX INT0 CHAIN", NULL, "WSA_RX INT0 VBAT"},
2699
Laxminath Kasam243e2752018-04-12 00:40:19 +05302700 {"WSA_SPK1 OUT", NULL, "WSA_RX INT0 CHAIN"},
Laxminath Kasamfc281ad2018-08-06 20:19:40 +05302701 {"WSA_SPK1 OUT", NULL, "WSA_MCLK"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302702
2703 {"WSA_RX1 INP0", "RX0", "WSA RX0"},
2704 {"WSA_RX1 INP0", "RX1", "WSA RX1"},
2705 {"WSA_RX1 INP0", "RX_MIX0", "WSA RX_MIX0"},
2706 {"WSA_RX1 INP0", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302707 {"WSA_RX1 INP0", "DEC0", "WSA_TX DEC0_INP"},
2708 {"WSA_RX1 INP0", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302709 {"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP0"},
2710
2711 {"WSA_RX1 INP1", "RX0", "WSA RX0"},
2712 {"WSA_RX1 INP1", "RX1", "WSA RX1"},
2713 {"WSA_RX1 INP1", "RX_MIX0", "WSA RX_MIX0"},
2714 {"WSA_RX1 INP1", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302715 {"WSA_RX1 INP1", "DEC0", "WSA_TX DEC0_INP"},
2716 {"WSA_RX1 INP1", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302717 {"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP1"},
2718
2719 {"WSA_RX1 INP2", "RX0", "WSA RX0"},
2720 {"WSA_RX1 INP2", "RX1", "WSA RX1"},
2721 {"WSA_RX1 INP2", "RX_MIX0", "WSA RX_MIX0"},
2722 {"WSA_RX1 INP2", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302723 {"WSA_RX1 INP2", "DEC0", "WSA_TX DEC0_INP"},
2724 {"WSA_RX1 INP2", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302725 {"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP2"},
2726
2727 {"WSA_RX1 MIX INP", "RX0", "WSA RX0"},
2728 {"WSA_RX1 MIX INP", "RX1", "WSA RX1"},
2729 {"WSA_RX1 MIX INP", "RX_MIX0", "WSA RX_MIX0"},
2730 {"WSA_RX1 MIX INP", "RX_MIX1", "WSA RX_MIX1"},
2731 {"WSA_RX INT1 SEC MIX", NULL, "WSA_RX1 MIX INP"},
2732
2733 {"WSA_RX INT1 SEC MIX", NULL, "WSA_RX INT1 MIX"},
2734 {"WSA_RX INT1 INTERP", NULL, "WSA_RX INT1 SEC MIX"},
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302735
2736 {"WSA_RX INT1 VBAT", "WSA RX1 VBAT Enable", "WSA_RX INT1 INTERP"},
2737 {"WSA_RX INT1 CHAIN", NULL, "WSA_RX INT1 VBAT"},
2738
Laxminath Kasam243e2752018-04-12 00:40:19 +05302739 {"WSA_RX INT1 CHAIN", NULL, "WSA_RX INT1 INTERP"},
2740 {"WSA_SPK2 OUT", NULL, "WSA_RX INT1 CHAIN"},
Laxminath Kasamfc281ad2018-08-06 20:19:40 +05302741 {"WSA_SPK2 OUT", NULL, "WSA_MCLK"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302742};
2743
2744static const struct wsa_macro_reg_mask_val wsa_macro_reg_init[] = {
2745 {BOLERO_CDC_WSA_BOOST0_BOOST_CFG1, 0x3F, 0x12},
2746 {BOLERO_CDC_WSA_BOOST0_BOOST_CFG2, 0x1C, 0x08},
Sudheer Papothi44f2b862020-03-28 10:03:21 +05302747 {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x1E, 0x0C},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302748 {BOLERO_CDC_WSA_BOOST1_BOOST_CFG1, 0x3F, 0x12},
2749 {BOLERO_CDC_WSA_BOOST1_BOOST_CFG2, 0x1C, 0x08},
Sudheer Papothi44f2b862020-03-28 10:03:21 +05302750 {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x1E, 0x0C},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302751 {BOLERO_CDC_WSA_BOOST0_BOOST_CTL, 0x70, 0x58},
2752 {BOLERO_CDC_WSA_BOOST1_BOOST_CTL, 0x70, 0x58},
2753 {BOLERO_CDC_WSA_RX0_RX_PATH_CFG1, 0x08, 0x08},
2754 {BOLERO_CDC_WSA_RX1_RX_PATH_CFG1, 0x08, 0x08},
2755 {BOLERO_CDC_WSA_TOP_TOP_CFG1, 0x02, 0x02},
2756 {BOLERO_CDC_WSA_TOP_TOP_CFG1, 0x01, 0x01},
2757 {BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
2758 {BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
2759 {BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
2760 {BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302761 {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x01, 0x01},
2762 {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x01, 0x01},
2763 {BOLERO_CDC_WSA_RX0_RX_PATH_CFG0, 0x01, 0x01},
2764 {BOLERO_CDC_WSA_RX1_RX_PATH_CFG0, 0x01, 0x01},
2765 {BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CFG, 0x01, 0x01},
2766 {BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CFG, 0x01, 0x01},
2767};
2768
Meng Wang15c825d2018-09-06 10:49:18 +08002769static void wsa_macro_init_bcl_pmic_reg(struct snd_soc_component *component)
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302770{
2771 struct device *wsa_dev = NULL;
2772 struct wsa_macro_priv *wsa_priv = NULL;
2773
Meng Wang15c825d2018-09-06 10:49:18 +08002774 if (!component) {
2775 pr_err("%s: NULL component pointer!\n", __func__);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302776 return;
2777 }
2778
Meng Wang15c825d2018-09-06 10:49:18 +08002779 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302780 return;
2781
2782 switch (wsa_priv->bcl_pmic_params.id) {
2783 case 0:
2784 /* Enable ID0 to listen to respective PMIC group interrupts */
Meng Wang15c825d2018-09-06 10:49:18 +08002785 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302786 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CTL1, 0x02, 0x02);
2787 /* Update MC_SID0 */
Meng Wang15c825d2018-09-06 10:49:18 +08002788 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302789 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG1, 0x0F,
2790 wsa_priv->bcl_pmic_params.sid);
2791 /* Update MC_PPID0 */
Meng Wang15c825d2018-09-06 10:49:18 +08002792 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302793 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG2, 0xFF,
2794 wsa_priv->bcl_pmic_params.ppid);
2795 break;
2796 case 1:
2797 /* Enable ID1 to listen to respective PMIC group interrupts */
Meng Wang15c825d2018-09-06 10:49:18 +08002798 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302799 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CTL1, 0x01, 0x01);
2800 /* Update MC_SID1 */
Meng Wang15c825d2018-09-06 10:49:18 +08002801 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302802 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG3, 0x0F,
2803 wsa_priv->bcl_pmic_params.sid);
2804 /* Update MC_PPID1 */
Meng Wang15c825d2018-09-06 10:49:18 +08002805 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302806 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG4, 0xFF,
2807 wsa_priv->bcl_pmic_params.ppid);
2808 break;
2809 default:
2810 dev_err(wsa_dev, "%s: PMIC ID is invalid %d\n",
2811 __func__, wsa_priv->bcl_pmic_params.id);
2812 break;
2813 }
2814}
2815
Meng Wang15c825d2018-09-06 10:49:18 +08002816static void wsa_macro_init_reg(struct snd_soc_component *component)
Laxminath Kasam243e2752018-04-12 00:40:19 +05302817{
2818 int i;
2819
2820 for (i = 0; i < ARRAY_SIZE(wsa_macro_reg_init); i++)
Meng Wang15c825d2018-09-06 10:49:18 +08002821 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302822 wsa_macro_reg_init[i].reg,
2823 wsa_macro_reg_init[i].mask,
2824 wsa_macro_reg_init[i].val);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302825
Meng Wang15c825d2018-09-06 10:49:18 +08002826 wsa_macro_init_bcl_pmic_reg(component);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302827}
2828
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07002829static int wsa_macro_core_vote(void *handle, bool enable)
2830{
Vangala, Amarnath258d2932020-10-27 23:53:04 +05302831 int rc = 0;
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07002832 struct wsa_macro_priv *wsa_priv = (struct wsa_macro_priv *) handle;
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07002833
2834 if (wsa_priv == NULL) {
2835 pr_err("%s: wsa priv data is NULL\n", __func__);
2836 return -EINVAL;
2837 }
Vangala, Amarnath258d2932020-10-27 23:53:04 +05302838
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07002839 if (enable) {
2840 pm_runtime_get_sync(wsa_priv->dev);
Vangala, Amarnath258d2932020-10-27 23:53:04 +05302841 if (bolero_check_core_votes(wsa_priv->dev))
2842 rc = 0;
2843 else
2844 rc = -ENOTSYNC;
2845 } else {
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07002846 pm_runtime_put_autosuspend(wsa_priv->dev);
2847 pm_runtime_mark_last_busy(wsa_priv->dev);
2848 }
Vangala, Amarnath258d2932020-10-27 23:53:04 +05302849 return rc;
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07002850}
2851
Laxminath Kasam243e2752018-04-12 00:40:19 +05302852static int wsa_swrm_clock(void *handle, bool enable)
2853{
2854 struct wsa_macro_priv *wsa_priv = (struct wsa_macro_priv *) handle;
2855 struct regmap *regmap = dev_get_regmap(wsa_priv->dev->parent, NULL);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302856 int ret = 0;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302857
Tanya Dixitab8eba82018-10-05 15:07:37 +05302858 if (regmap == NULL) {
2859 dev_err(wsa_priv->dev, "%s: regmap is NULL\n", __func__);
2860 return -EINVAL;
2861 }
2862
Laxminath Kasam243e2752018-04-12 00:40:19 +05302863 mutex_lock(&wsa_priv->swr_clk_lock);
2864
Aditya Bavanarif500a1d2019-09-16 18:27:51 -07002865 trace_printk("%s: %s swrm clock %s\n",
2866 dev_name(wsa_priv->dev), __func__,
2867 (enable ? "enable" : "disable"));
Laxminath Kasam243e2752018-04-12 00:40:19 +05302868 dev_dbg(wsa_priv->dev, "%s: swrm clock %s\n",
2869 __func__, (enable ? "enable" : "disable"));
2870 if (enable) {
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302871 pm_runtime_get_sync(wsa_priv->dev);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302872 if (wsa_priv->swr_clk_users == 0) {
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07002873 ret = msm_cdc_pinctrl_select_active_state(
Karthikeyan Mani01f1ba42019-02-26 18:48:15 -08002874 wsa_priv->wsa_swr_gpio_p);
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07002875 if (ret < 0) {
2876 dev_err_ratelimited(wsa_priv->dev,
2877 "%s: wsa swr pinctrl enable failed\n",
2878 __func__);
2879 pm_runtime_mark_last_busy(wsa_priv->dev);
2880 pm_runtime_put_autosuspend(wsa_priv->dev);
2881 goto exit;
2882 }
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302883 ret = wsa_macro_mclk_enable(wsa_priv, 1, true);
2884 if (ret < 0) {
Karthikeyan Mani01f1ba42019-02-26 18:48:15 -08002885 msm_cdc_pinctrl_select_sleep_state(
2886 wsa_priv->wsa_swr_gpio_p);
Ramprasad Katkam14efed62019-03-07 13:16:50 +05302887 dev_err_ratelimited(wsa_priv->dev,
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302888 "%s: wsa request clock enable failed\n",
2889 __func__);
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07002890 pm_runtime_mark_last_busy(wsa_priv->dev);
2891 pm_runtime_put_autosuspend(wsa_priv->dev);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302892 goto exit;
2893 }
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05302894 if (wsa_priv->reset_swr)
2895 regmap_update_bits(regmap,
2896 BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
2897 0x02, 0x02);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302898 regmap_update_bits(regmap,
2899 BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
2900 0x01, 0x01);
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05302901 if (wsa_priv->reset_swr)
2902 regmap_update_bits(regmap,
2903 BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
2904 0x02, 0x00);
2905 wsa_priv->reset_swr = false;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302906 }
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07002907 wsa_priv->swr_clk_users++;
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302908 pm_runtime_mark_last_busy(wsa_priv->dev);
2909 pm_runtime_put_autosuspend(wsa_priv->dev);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302910 } else {
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302911 if (wsa_priv->swr_clk_users <= 0) {
2912 dev_err(wsa_priv->dev, "%s: clock already disabled\n",
2913 __func__);
2914 wsa_priv->swr_clk_users = 0;
2915 goto exit;
2916 }
Laxminath Kasam243e2752018-04-12 00:40:19 +05302917 wsa_priv->swr_clk_users--;
2918 if (wsa_priv->swr_clk_users == 0) {
2919 regmap_update_bits(regmap,
2920 BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
2921 0x01, 0x00);
Karthikeyan Mani01f1ba42019-02-26 18:48:15 -08002922 wsa_macro_mclk_enable(wsa_priv, 0, true);
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07002923 ret = msm_cdc_pinctrl_select_sleep_state(
Laxminath Kasam243e2752018-04-12 00:40:19 +05302924 wsa_priv->wsa_swr_gpio_p);
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07002925 if (ret < 0) {
2926 dev_err_ratelimited(wsa_priv->dev,
2927 "%s: wsa swr pinctrl disable failed\n",
2928 __func__);
2929 goto exit;
2930 }
Laxminath Kasam243e2752018-04-12 00:40:19 +05302931 }
2932 }
Aditya Bavanarif500a1d2019-09-16 18:27:51 -07002933 trace_printk("%s: %s swrm clock users: %d\n",
2934 dev_name(wsa_priv->dev), __func__,
2935 wsa_priv->swr_clk_users);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302936 dev_dbg(wsa_priv->dev, "%s: swrm clock users %d\n",
2937 __func__, wsa_priv->swr_clk_users);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302938exit:
Laxminath Kasam243e2752018-04-12 00:40:19 +05302939 mutex_unlock(&wsa_priv->swr_clk_lock);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302940 return ret;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302941}
2942
Meng Wang15c825d2018-09-06 10:49:18 +08002943static int wsa_macro_init(struct snd_soc_component *component)
Laxminath Kasam243e2752018-04-12 00:40:19 +05302944{
Meng Wang15c825d2018-09-06 10:49:18 +08002945 struct snd_soc_dapm_context *dapm =
2946 snd_soc_component_get_dapm(component);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302947 int ret;
2948 struct device *wsa_dev = NULL;
2949 struct wsa_macro_priv *wsa_priv = NULL;
2950
Meng Wang15c825d2018-09-06 10:49:18 +08002951 wsa_dev = bolero_get_device_ptr(component->dev, WSA_MACRO);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302952 if (!wsa_dev) {
Meng Wang15c825d2018-09-06 10:49:18 +08002953 dev_err(component->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302954 "%s: null device for macro!\n", __func__);
2955 return -EINVAL;
2956 }
2957 wsa_priv = dev_get_drvdata(wsa_dev);
2958 if (!wsa_priv) {
Meng Wang15c825d2018-09-06 10:49:18 +08002959 dev_err(component->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302960 "%s: priv is null for macro!\n", __func__);
2961 return -EINVAL;
2962 }
2963
2964 ret = snd_soc_dapm_new_controls(dapm, wsa_macro_dapm_widgets,
2965 ARRAY_SIZE(wsa_macro_dapm_widgets));
2966 if (ret < 0) {
2967 dev_err(wsa_dev, "%s: Failed to add controls\n", __func__);
2968 return ret;
2969 }
2970
2971 ret = snd_soc_dapm_add_routes(dapm, wsa_audio_map,
2972 ARRAY_SIZE(wsa_audio_map));
2973 if (ret < 0) {
2974 dev_err(wsa_dev, "%s: Failed to add routes\n", __func__);
2975 return ret;
2976 }
2977
2978 ret = snd_soc_dapm_new_widgets(dapm->card);
2979 if (ret < 0) {
2980 dev_err(wsa_dev, "%s: Failed to add widgets\n", __func__);
2981 return ret;
2982 }
2983
Meng Wang15c825d2018-09-06 10:49:18 +08002984 ret = snd_soc_add_component_controls(component, wsa_macro_snd_controls,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302985 ARRAY_SIZE(wsa_macro_snd_controls));
2986 if (ret < 0) {
2987 dev_err(wsa_dev, "%s: Failed to add snd_ctls\n", __func__);
2988 return ret;
2989 }
Laxminath Kasam638b5602018-09-24 13:19:52 +05302990 snd_soc_dapm_ignore_suspend(dapm, "WSA_AIF1 Playback");
2991 snd_soc_dapm_ignore_suspend(dapm, "WSA_AIF_MIX1 Playback");
2992 snd_soc_dapm_ignore_suspend(dapm, "WSA_AIF_VI Capture");
2993 snd_soc_dapm_ignore_suspend(dapm, "WSA_AIF_ECHO Capture");
2994 snd_soc_dapm_ignore_suspend(dapm, "WSA_SPK1 OUT");
2995 snd_soc_dapm_ignore_suspend(dapm, "WSA_SPK2 OUT");
2996 snd_soc_dapm_ignore_suspend(dapm, "VIINPUT_WSA");
2997 snd_soc_dapm_ignore_suspend(dapm, "WSA SRC0_INP");
2998 snd_soc_dapm_ignore_suspend(dapm, "WSA_TX DEC0_INP");
2999 snd_soc_dapm_ignore_suspend(dapm, "WSA_TX DEC1_INP");
3000 snd_soc_dapm_sync(dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05303001
Meng Wang15c825d2018-09-06 10:49:18 +08003002 wsa_priv->component = component;
Laxminath Kasam21c8b222018-06-21 18:47:22 +05303003 wsa_priv->spkr_gain_offset = WSA_MACRO_GAIN_OFFSET_0_DB;
Meng Wang15c825d2018-09-06 10:49:18 +08003004 wsa_macro_init_reg(component);
Laxminath Kasam243e2752018-04-12 00:40:19 +05303005
3006 return 0;
3007}
3008
Meng Wang15c825d2018-09-06 10:49:18 +08003009static int wsa_macro_deinit(struct snd_soc_component *component)
Laxminath Kasam243e2752018-04-12 00:40:19 +05303010{
3011 struct device *wsa_dev = NULL;
3012 struct wsa_macro_priv *wsa_priv = NULL;
3013
Meng Wang15c825d2018-09-06 10:49:18 +08003014 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05303015 return -EINVAL;
3016
Meng Wang15c825d2018-09-06 10:49:18 +08003017 wsa_priv->component = NULL;
Laxminath Kasam243e2752018-04-12 00:40:19 +05303018
3019 return 0;
3020}
3021
3022static void wsa_macro_add_child_devices(struct work_struct *work)
3023{
3024 struct wsa_macro_priv *wsa_priv;
3025 struct platform_device *pdev;
3026 struct device_node *node;
3027 struct wsa_macro_swr_ctrl_data *swr_ctrl_data = NULL, *temp;
3028 int ret;
3029 u16 count = 0, ctrl_num = 0;
3030 struct wsa_macro_swr_ctrl_platform_data *platdata;
3031 char plat_dev_name[WSA_MACRO_SWR_STRING_LEN];
3032
3033 wsa_priv = container_of(work, struct wsa_macro_priv,
3034 wsa_macro_add_child_devices_work);
3035 if (!wsa_priv) {
3036 pr_err("%s: Memory for wsa_priv does not exist\n",
3037 __func__);
3038 return;
3039 }
Laxminath Kasam21c8b222018-06-21 18:47:22 +05303040 if (!wsa_priv->dev || !wsa_priv->dev->of_node) {
Laxminath Kasam243e2752018-04-12 00:40:19 +05303041 dev_err(wsa_priv->dev,
3042 "%s: DT node for wsa_priv does not exist\n", __func__);
3043 return;
3044 }
3045
3046 platdata = &wsa_priv->swr_plat_data;
3047 wsa_priv->child_count = 0;
3048
3049 for_each_available_child_of_node(wsa_priv->dev->of_node, node) {
3050 if (strnstr(node->name, "wsa_swr_master",
3051 strlen("wsa_swr_master")) != NULL)
3052 strlcpy(plat_dev_name, "wsa_swr_ctrl",
3053 (WSA_MACRO_SWR_STRING_LEN - 1));
3054 else if (strnstr(node->name, "msm_cdc_pinctrl",
3055 strlen("msm_cdc_pinctrl")) != NULL)
3056 strlcpy(plat_dev_name, node->name,
3057 (WSA_MACRO_SWR_STRING_LEN - 1));
3058 else
3059 continue;
3060
3061 pdev = platform_device_alloc(plat_dev_name, -1);
3062 if (!pdev) {
3063 dev_err(wsa_priv->dev, "%s: pdev memory alloc failed\n",
3064 __func__);
3065 ret = -ENOMEM;
3066 goto err;
3067 }
3068 pdev->dev.parent = wsa_priv->dev;
3069 pdev->dev.of_node = node;
3070
3071 if (strnstr(node->name, "wsa_swr_master",
3072 strlen("wsa_swr_master")) != NULL) {
3073 ret = platform_device_add_data(pdev, platdata,
3074 sizeof(*platdata));
3075 if (ret) {
3076 dev_err(&pdev->dev,
3077 "%s: cannot add plat data ctrl:%d\n",
3078 __func__, ctrl_num);
3079 goto fail_pdev_add;
3080 }
3081 }
3082
3083 ret = platform_device_add(pdev);
3084 if (ret) {
3085 dev_err(&pdev->dev,
3086 "%s: Cannot add platform device\n",
3087 __func__);
3088 goto fail_pdev_add;
3089 }
3090
3091 if (!strcmp(node->name, "wsa_swr_master")) {
3092 temp = krealloc(swr_ctrl_data,
3093 (ctrl_num + 1) * sizeof(
3094 struct wsa_macro_swr_ctrl_data),
3095 GFP_KERNEL);
3096 if (!temp) {
3097 dev_err(&pdev->dev, "out of memory\n");
3098 ret = -ENOMEM;
3099 goto err;
3100 }
3101 swr_ctrl_data = temp;
3102 swr_ctrl_data[ctrl_num].wsa_swr_pdev = pdev;
3103 ctrl_num++;
3104 dev_dbg(&pdev->dev,
3105 "%s: Added soundwire ctrl device(s)\n",
3106 __func__);
3107 wsa_priv->swr_ctrl_data = swr_ctrl_data;
3108 }
3109 if (wsa_priv->child_count < WSA_MACRO_CHILD_DEVICES_MAX)
3110 wsa_priv->pdev_child_devices[
3111 wsa_priv->child_count++] = pdev;
3112 else
3113 goto err;
3114 }
3115
3116 return;
3117fail_pdev_add:
3118 for (count = 0; count < wsa_priv->child_count; count++)
3119 platform_device_put(wsa_priv->pdev_child_devices[count]);
3120err:
3121 return;
3122}
3123
3124static void wsa_macro_init_ops(struct macro_ops *ops,
3125 char __iomem *wsa_io_base)
3126{
3127 memset(ops, 0, sizeof(struct macro_ops));
3128 ops->init = wsa_macro_init;
3129 ops->exit = wsa_macro_deinit;
3130 ops->io_base = wsa_io_base;
3131 ops->dai_ptr = wsa_macro_dai;
3132 ops->num_dais = ARRAY_SIZE(wsa_macro_dai);
Laxminath Kasamfb0d6832018-09-22 01:49:52 +05303133 ops->event_handler = wsa_macro_event_handler;
Sudheer Papothia3e969d2018-10-27 06:22:10 +05303134 ops->set_port_map = wsa_macro_set_port_map;
Laxminath Kasam243e2752018-04-12 00:40:19 +05303135}
3136
3137static int wsa_macro_probe(struct platform_device *pdev)
3138{
3139 struct macro_ops ops;
3140 struct wsa_macro_priv *wsa_priv;
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07003141 u32 wsa_base_addr, default_clk_id;
Laxminath Kasam243e2752018-04-12 00:40:19 +05303142 char __iomem *wsa_io_base;
3143 int ret = 0;
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303144 u8 bcl_pmic_params[3];
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07003145 u32 is_used_wsa_swr_gpio = 1;
3146 const char *is_used_wsa_swr_gpio_dt = "qcom,is-used-swr-gpio";
Laxminath Kasam243e2752018-04-12 00:40:19 +05303147
Laxminath Kasam251ce992020-07-01 23:37:33 +05303148 if (!bolero_is_va_macro_registered(&pdev->dev)) {
3149 dev_err(&pdev->dev,
3150 "%s: va-macro not registered yet, defer\n", __func__);
3151 return -EPROBE_DEFER;
3152 }
3153
Laxminath Kasam243e2752018-04-12 00:40:19 +05303154 wsa_priv = devm_kzalloc(&pdev->dev, sizeof(struct wsa_macro_priv),
3155 GFP_KERNEL);
3156 if (!wsa_priv)
3157 return -ENOMEM;
3158
3159 wsa_priv->dev = &pdev->dev;
3160 ret = of_property_read_u32(pdev->dev.of_node, "reg",
3161 &wsa_base_addr);
3162 if (ret) {
3163 dev_err(&pdev->dev, "%s: could not find %s entry in dt\n",
3164 __func__, "reg");
3165 return ret;
3166 }
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07003167 if (of_find_property(pdev->dev.of_node, is_used_wsa_swr_gpio_dt,
3168 NULL)) {
3169 ret = of_property_read_u32(pdev->dev.of_node,
3170 is_used_wsa_swr_gpio_dt,
3171 &is_used_wsa_swr_gpio);
3172 if (ret) {
3173 dev_err(&pdev->dev, "%s: error reading %s in dt\n",
3174 __func__, is_used_wsa_swr_gpio_dt);
3175 is_used_wsa_swr_gpio = 1;
3176 }
3177 }
Laxminath Kasam243e2752018-04-12 00:40:19 +05303178 wsa_priv->wsa_swr_gpio_p = of_parse_phandle(pdev->dev.of_node,
3179 "qcom,wsa-swr-gpios", 0);
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07003180 if (!wsa_priv->wsa_swr_gpio_p && is_used_wsa_swr_gpio) {
Laxminath Kasam243e2752018-04-12 00:40:19 +05303181 dev_err(&pdev->dev, "%s: swr_gpios handle not provided!\n",
3182 __func__);
3183 return -EINVAL;
3184 }
Karthikeyan Manib44e4552019-09-09 23:06:04 -07003185 if (msm_cdc_pinctrl_get_state(wsa_priv->wsa_swr_gpio_p) < 0 &&
3186 is_used_wsa_swr_gpio) {
Karthikeyan Mani326536d2019-06-03 13:29:43 -07003187 dev_err(&pdev->dev, "%s: failed to get swr pin state\n",
3188 __func__);
3189 return -EPROBE_DEFER;
3190 }
3191
Laxminath Kasam243e2752018-04-12 00:40:19 +05303192 wsa_io_base = devm_ioremap(&pdev->dev,
3193 wsa_base_addr, WSA_MACRO_MAX_OFFSET);
3194 if (!wsa_io_base) {
3195 dev_err(&pdev->dev, "%s: ioremap failed\n", __func__);
3196 return -EINVAL;
3197 }
3198 wsa_priv->wsa_io_base = wsa_io_base;
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05303199 wsa_priv->reset_swr = true;
Laxminath Kasam243e2752018-04-12 00:40:19 +05303200 INIT_WORK(&wsa_priv->wsa_macro_add_child_devices_work,
3201 wsa_macro_add_child_devices);
3202 wsa_priv->swr_plat_data.handle = (void *) wsa_priv;
3203 wsa_priv->swr_plat_data.read = NULL;
3204 wsa_priv->swr_plat_data.write = NULL;
3205 wsa_priv->swr_plat_data.bulk_write = NULL;
3206 wsa_priv->swr_plat_data.clk = wsa_swrm_clock;
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07003207 wsa_priv->swr_plat_data.core_vote = wsa_macro_core_vote;
Laxminath Kasam243e2752018-04-12 00:40:19 +05303208 wsa_priv->swr_plat_data.handle_irq = NULL;
3209
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07003210 ret = of_property_read_u32(pdev->dev.of_node, "qcom,default-clk-id",
3211 &default_clk_id);
3212 if (ret) {
3213 dev_err(&pdev->dev, "%s: could not find %s entry in dt\n",
3214 __func__, "qcom,mux0-clk-id");
3215 default_clk_id = WSA_CORE_CLK;
Laxminath Kasam243e2752018-04-12 00:40:19 +05303216 }
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303217
3218 ret = of_property_read_u8_array(pdev->dev.of_node,
3219 "qcom,wsa-bcl-pmic-params", bcl_pmic_params,
3220 sizeof(bcl_pmic_params));
3221 if (ret) {
3222 dev_dbg(&pdev->dev, "%s: could not find %s entry in dt\n",
3223 __func__, "qcom,wsa-bcl-pmic-params");
3224 } else {
3225 wsa_priv->bcl_pmic_params.id = bcl_pmic_params[0];
3226 wsa_priv->bcl_pmic_params.sid = bcl_pmic_params[1];
3227 wsa_priv->bcl_pmic_params.ppid = bcl_pmic_params[2];
3228 }
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07003229 wsa_priv->default_clk_id = default_clk_id;
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303230
Laxminath Kasam243e2752018-04-12 00:40:19 +05303231 dev_set_drvdata(&pdev->dev, wsa_priv);
3232 mutex_init(&wsa_priv->mclk_lock);
3233 mutex_init(&wsa_priv->swr_clk_lock);
3234 wsa_macro_init_ops(&ops, wsa_io_base);
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07003235 ops.clk_id_req = wsa_priv->default_clk_id;
3236 ops.default_clk_id = wsa_priv->default_clk_id;
Laxminath Kasam251ce992020-07-01 23:37:33 +05303237
Laxminath Kasam243e2752018-04-12 00:40:19 +05303238 ret = bolero_register_macro(&pdev->dev, WSA_MACRO, &ops);
3239 if (ret < 0) {
3240 dev_err(&pdev->dev, "%s: register macro failed\n", __func__);
3241 goto reg_macro_fail;
3242 }
Sudheer Papothi7601cc62019-03-30 03:00:52 +05303243 pm_runtime_set_autosuspend_delay(&pdev->dev, AUTO_SUSPEND_DELAY);
3244 pm_runtime_use_autosuspend(&pdev->dev);
3245 pm_runtime_set_suspended(&pdev->dev);
Karthikeyan Mani3d209512019-10-03 13:51:53 -07003246 pm_suspend_ignore_children(&pdev->dev, true);
Sudheer Papothi7601cc62019-03-30 03:00:52 +05303247 pm_runtime_enable(&pdev->dev);
Vangala, Amarnath0a0c7182020-12-03 14:14:56 +05303248 schedule_work(&wsa_priv->wsa_macro_add_child_devices_work);
Sudheer Papothi7601cc62019-03-30 03:00:52 +05303249
Laxminath Kasam243e2752018-04-12 00:40:19 +05303250 return ret;
3251reg_macro_fail:
3252 mutex_destroy(&wsa_priv->mclk_lock);
3253 mutex_destroy(&wsa_priv->swr_clk_lock);
3254 return ret;
3255}
3256
3257static int wsa_macro_remove(struct platform_device *pdev)
3258{
3259 struct wsa_macro_priv *wsa_priv;
3260 u16 count = 0;
3261
3262 wsa_priv = dev_get_drvdata(&pdev->dev);
3263
3264 if (!wsa_priv)
3265 return -EINVAL;
3266
3267 for (count = 0; count < wsa_priv->child_count &&
3268 count < WSA_MACRO_CHILD_DEVICES_MAX; count++)
3269 platform_device_unregister(wsa_priv->pdev_child_devices[count]);
3270
Sudheer Papothi7601cc62019-03-30 03:00:52 +05303271 pm_runtime_disable(&pdev->dev);
3272 pm_runtime_set_suspended(&pdev->dev);
Laxminath Kasam243e2752018-04-12 00:40:19 +05303273 bolero_unregister_macro(&pdev->dev, WSA_MACRO);
3274 mutex_destroy(&wsa_priv->mclk_lock);
3275 mutex_destroy(&wsa_priv->swr_clk_lock);
3276 return 0;
3277}
3278
3279static const struct of_device_id wsa_macro_dt_match[] = {
3280 {.compatible = "qcom,wsa-macro"},
3281 {}
3282};
3283
Sudheer Papothi7601cc62019-03-30 03:00:52 +05303284static const struct dev_pm_ops bolero_dev_pm_ops = {
Aditya Bavanari4460ed22020-02-20 12:46:51 +05303285 SET_SYSTEM_SLEEP_PM_OPS(
3286 pm_runtime_force_suspend,
3287 pm_runtime_force_resume
3288 )
Sudheer Papothi7601cc62019-03-30 03:00:52 +05303289 SET_RUNTIME_PM_OPS(
3290 bolero_runtime_suspend,
3291 bolero_runtime_resume,
3292 NULL
3293 )
3294};
3295
Laxminath Kasam243e2752018-04-12 00:40:19 +05303296static struct platform_driver wsa_macro_driver = {
3297 .driver = {
3298 .name = "wsa_macro",
3299 .owner = THIS_MODULE,
Sudheer Papothi7601cc62019-03-30 03:00:52 +05303300 .pm = &bolero_dev_pm_ops,
Laxminath Kasam243e2752018-04-12 00:40:19 +05303301 .of_match_table = wsa_macro_dt_match,
Xiaojun Sang53cd13a2018-06-29 15:14:37 +08003302 .suppress_bind_attrs = true,
Laxminath Kasam243e2752018-04-12 00:40:19 +05303303 },
3304 .probe = wsa_macro_probe,
3305 .remove = wsa_macro_remove,
3306};
3307
3308module_platform_driver(wsa_macro_driver);
3309
3310MODULE_DESCRIPTION("WSA macro driver");
3311MODULE_LICENSE("GPL v2");