blob: 3c145b0ead472b7872f7410cd4c32c04914473cf [file] [log] [blame]
Meng Wang43bbb872018-12-10 12:32:05 +08001// SPDX-License-Identifier: GPL-2.0-only
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05302/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
Laxminath Kasam243e2752018-04-12 00:40:19 +05303 */
4
5#include <linux/module.h>
6#include <linux/init.h>
7#include <linux/io.h>
8#include <linux/platform_device.h>
9#include <linux/clk.h>
Sudheer Papothi7601cc62019-03-30 03:00:52 +053010#include <linux/pm_runtime.h>
Laxminath Kasam243e2752018-04-12 00:40:19 +053011#include <sound/soc.h>
12#include <sound/soc-dapm.h>
13#include <sound/tlv.h>
Sudheer Papothia3e969d2018-10-27 06:22:10 +053014#include <soc/swr-common.h>
Laxminath Kasam243e2752018-04-12 00:40:19 +053015#include <soc/swr-wcd.h>
16
Meng Wang11a25cf2018-10-31 14:11:26 +080017#include <asoc/msm-cdc-pinctrl.h>
Laxminath Kasam243e2752018-04-12 00:40:19 +053018#include "bolero-cdc.h"
19#include "bolero-cdc-registers.h"
20#include "wsa-macro.h"
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -070021#include "bolero-clk-rsc.h"
Laxminath Kasam243e2752018-04-12 00:40:19 +053022
Sudheer Papothi7601cc62019-03-30 03:00:52 +053023#define AUTO_SUSPEND_DELAY 50 /* delay in msec */
Laxminath Kasam243e2752018-04-12 00:40:19 +053024#define WSA_MACRO_MAX_OFFSET 0x1000
25
26#define WSA_MACRO_RX_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
27 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
28 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
29#define WSA_MACRO_RX_MIX_RATES (SNDRV_PCM_RATE_48000 |\
30 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
31#define WSA_MACRO_RX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
32 SNDRV_PCM_FMTBIT_S24_LE |\
33 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
34
35#define WSA_MACRO_ECHO_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
36 SNDRV_PCM_RATE_48000)
37#define WSA_MACRO_ECHO_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
38 SNDRV_PCM_FMTBIT_S24_LE |\
39 SNDRV_PCM_FMTBIT_S24_3LE)
40
41#define NUM_INTERPOLATORS 2
42
43#define WSA_MACRO_MUX_INP_SHFT 0x3
44#define WSA_MACRO_MUX_INP_MASK1 0x38
45#define WSA_MACRO_MUX_INP_MASK2 0x38
46#define WSA_MACRO_MUX_CFG_OFFSET 0x8
47#define WSA_MACRO_MUX_CFG1_OFFSET 0x4
48#define WSA_MACRO_RX_COMP_OFFSET 0x40
Aditya Bavanari4f3d5642018-09-18 22:19:10 +053049#define WSA_MACRO_RX_SOFTCLIP_OFFSET 0x40
Laxminath Kasam243e2752018-04-12 00:40:19 +053050#define WSA_MACRO_RX_PATH_OFFSET 0x80
51#define WSA_MACRO_RX_PATH_CFG3_OFFSET 0x10
52#define WSA_MACRO_RX_PATH_DSMDEM_OFFSET 0x4C
53#define WSA_MACRO_FS_RATE_MASK 0x0F
Laxminath Kasam5d9ea8d2018-11-28 14:32:40 +053054#define WSA_MACRO_EC_MIX_TX0_MASK 0x03
55#define WSA_MACRO_EC_MIX_TX1_MASK 0x18
56
Laxminath Kasam243e2752018-04-12 00:40:19 +053057
58enum {
59 WSA_MACRO_RX0 = 0,
60 WSA_MACRO_RX1,
61 WSA_MACRO_RX_MIX,
62 WSA_MACRO_RX_MIX0 = WSA_MACRO_RX_MIX,
63 WSA_MACRO_RX_MIX1,
64 WSA_MACRO_RX_MAX,
65};
66
67enum {
68 WSA_MACRO_TX0 = 0,
69 WSA_MACRO_TX1,
70 WSA_MACRO_TX_MAX,
71};
72
73enum {
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +053074 WSA_MACRO_EC0_MUX = 0,
75 WSA_MACRO_EC1_MUX,
76 WSA_MACRO_EC_MUX_MAX,
77};
78
79enum {
Laxminath Kasam243e2752018-04-12 00:40:19 +053080 WSA_MACRO_COMP1, /* SPK_L */
81 WSA_MACRO_COMP2, /* SPK_R */
82 WSA_MACRO_COMP_MAX
83};
84
Aditya Bavanari4f3d5642018-09-18 22:19:10 +053085enum {
86 WSA_MACRO_SOFTCLIP0, /* RX0 */
87 WSA_MACRO_SOFTCLIP1, /* RX1 */
88 WSA_MACRO_SOFTCLIP_MAX
89};
90
Laxminath Kasam52ae6582019-08-08 18:00:35 +053091enum {
92 INTn_1_INP_SEL_ZERO = 0,
93 INTn_1_INP_SEL_RX0,
94 INTn_1_INP_SEL_RX1,
95 INTn_1_INP_SEL_RX2,
96 INTn_1_INP_SEL_RX3,
97 INTn_1_INP_SEL_DEC0,
98 INTn_1_INP_SEL_DEC1,
99};
100
Laxminath Kasam243e2752018-04-12 00:40:19 +0530101struct interp_sample_rate {
102 int sample_rate;
103 int rate_val;
104};
105
106/*
107 * Structure used to update codec
108 * register defaults after reset
109 */
110struct wsa_macro_reg_mask_val {
111 u16 reg;
112 u8 mask;
113 u8 val;
114};
115
116static struct interp_sample_rate int_prim_sample_rate_val[] = {
117 {8000, 0x0}, /* 8K */
118 {16000, 0x1}, /* 16K */
119 {24000, -EINVAL},/* 24K */
120 {32000, 0x3}, /* 32K */
121 {48000, 0x4}, /* 48K */
122 {96000, 0x5}, /* 96K */
123 {192000, 0x6}, /* 192K */
124 {384000, 0x7}, /* 384K */
125 {44100, 0x8}, /* 44.1K */
126};
127
128static struct interp_sample_rate int_mix_sample_rate_val[] = {
129 {48000, 0x4}, /* 48K */
130 {96000, 0x5}, /* 96K */
131 {192000, 0x6}, /* 192K */
132};
133
134#define WSA_MACRO_SWR_STRING_LEN 80
135
136static int wsa_macro_hw_params(struct snd_pcm_substream *substream,
137 struct snd_pcm_hw_params *params,
138 struct snd_soc_dai *dai);
139static int wsa_macro_get_channel_map(struct snd_soc_dai *dai,
140 unsigned int *tx_num, unsigned int *tx_slot,
141 unsigned int *rx_num, unsigned int *rx_slot);
Laxminath Kasam52ae6582019-08-08 18:00:35 +0530142static int wsa_macro_digital_mute(struct snd_soc_dai *dai, int mute);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530143/* Hold instance to soundwire platform device */
144struct wsa_macro_swr_ctrl_data {
145 struct platform_device *wsa_swr_pdev;
146};
147
148struct wsa_macro_swr_ctrl_platform_data {
149 void *handle; /* holds codec private data */
150 int (*read)(void *handle, int reg);
151 int (*write)(void *handle, int reg, int val);
152 int (*bulk_write)(void *handle, u32 *reg, u32 *val, size_t len);
153 int (*clk)(void *handle, bool enable);
Karthikeyan Mani8d40a062019-09-05 16:44:49 -0700154 int (*core_vote)(void *handle, bool enable);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530155 int (*handle_irq)(void *handle,
156 irqreturn_t (*swrm_irq_handler)(int irq,
157 void *data),
158 void *swrm_handle,
159 int action);
160};
161
Aditya Bavanari4f3d5642018-09-18 22:19:10 +0530162struct wsa_macro_bcl_pmic_params {
163 u8 id;
164 u8 sid;
165 u8 ppid;
166};
167
Laxminath Kasam243e2752018-04-12 00:40:19 +0530168enum {
Laxminath Kasam59c7a1d2018-08-09 16:11:17 +0530169 WSA_MACRO_AIF_INVALID = 0,
170 WSA_MACRO_AIF1_PB,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530171 WSA_MACRO_AIF_MIX1_PB,
172 WSA_MACRO_AIF_VI,
173 WSA_MACRO_AIF_ECHO,
174 WSA_MACRO_MAX_DAIS,
175};
176
177#define WSA_MACRO_CHILD_DEVICES_MAX 3
178
179/*
180 * @dev: wsa macro device pointer
181 * @comp_enabled: compander enable mixer value set
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +0530182 * @ec_hq: echo HQ enable mixer value set
Laxminath Kasam243e2752018-04-12 00:40:19 +0530183 * @prim_int_users: Users of interpolator
184 * @wsa_mclk_users: WSA MCLK users count
185 * @swr_clk_users: SWR clk users count
186 * @vi_feed_value: VI sense mask
187 * @mclk_lock: to lock mclk operations
188 * @swr_clk_lock: to lock swr master clock operations
189 * @swr_ctrl_data: SoundWire data structure
190 * @swr_plat_data: Soundwire platform data
191 * @wsa_macro_add_child_devices_work: work for adding child devices
192 * @wsa_swr_gpio_p: used by pinctrl API
Meng Wang15c825d2018-09-06 10:49:18 +0800193 * @component: codec handle
Laxminath Kasam243e2752018-04-12 00:40:19 +0530194 * @rx_0_count: RX0 interpolation users
195 * @rx_1_count: RX1 interpolation users
196 * @active_ch_mask: channel mask for all AIF DAIs
197 * @active_ch_cnt: channel count of all AIF DAIs
198 * @rx_port_value: mixer ctl value of WSA RX MUXes
199 * @wsa_io_base: Base address of WSA macro addr space
200 */
201struct wsa_macro_priv {
202 struct device *dev;
203 int comp_enabled[WSA_MACRO_COMP_MAX];
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +0530204 int ec_hq[WSA_MACRO_RX1 + 1];
Laxminath Kasam243e2752018-04-12 00:40:19 +0530205 u16 prim_int_users[WSA_MACRO_RX1 + 1];
206 u16 wsa_mclk_users;
207 u16 swr_clk_users;
Ramprasad Katkam452772a2019-01-07 17:30:36 +0530208 bool dapm_mclk_enable;
Ramprasad Katkama4c747b2018-12-11 19:15:53 +0530209 bool reset_swr;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530210 unsigned int vi_feed_value;
211 struct mutex mclk_lock;
212 struct mutex swr_clk_lock;
213 struct wsa_macro_swr_ctrl_data *swr_ctrl_data;
214 struct wsa_macro_swr_ctrl_platform_data swr_plat_data;
215 struct work_struct wsa_macro_add_child_devices_work;
216 struct device_node *wsa_swr_gpio_p;
Meng Wang15c825d2018-09-06 10:49:18 +0800217 struct snd_soc_component *component;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530218 int rx_0_count;
219 int rx_1_count;
220 unsigned long active_ch_mask[WSA_MACRO_MAX_DAIS];
221 unsigned long active_ch_cnt[WSA_MACRO_MAX_DAIS];
222 int rx_port_value[WSA_MACRO_RX_MAX];
223 char __iomem *wsa_io_base;
224 struct platform_device *pdev_child_devices
225 [WSA_MACRO_CHILD_DEVICES_MAX];
226 int child_count;
227 int ear_spkr_gain;
228 int spkr_gain_offset;
229 int spkr_mode;
Aditya Bavanari4f3d5642018-09-18 22:19:10 +0530230 int is_softclip_on[WSA_MACRO_SOFTCLIP_MAX];
231 int softclip_clk_users[WSA_MACRO_SOFTCLIP_MAX];
232 struct wsa_macro_bcl_pmic_params bcl_pmic_params;
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -0700233 char __iomem *mclk_mode_muxsel;
234 u16 default_clk_id;
Vatsal Buchaf2a71b62019-03-26 16:14:40 +0530235 int wsa_digital_mute_status[WSA_MACRO_RX_MAX];
Laxminath Kasam243e2752018-04-12 00:40:19 +0530236};
237
Meng Wang15c825d2018-09-06 10:49:18 +0800238static int wsa_macro_config_ear_spkr_gain(struct snd_soc_component *component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530239 struct wsa_macro_priv *wsa_priv,
240 int event, int gain_reg);
241static struct snd_soc_dai_driver wsa_macro_dai[];
242static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0);
243
244static const char *const rx_text[] = {
245 "ZERO", "RX0", "RX1", "RX_MIX0", "RX_MIX1", "DEC0", "DEC1"
246};
247
248static const char *const rx_mix_text[] = {
249 "ZERO", "RX0", "RX1", "RX_MIX0", "RX_MIX1"
250};
251
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +0530252static const char *const rx_mix_ec_text[] = {
253 "ZERO", "RX_MIX_TX0", "RX_MIX_TX1"
254};
255
Laxminath Kasam243e2752018-04-12 00:40:19 +0530256static const char *const rx_mux_text[] = {
257 "ZERO", "AIF1_PB", "AIF_MIX1_PB"
258};
259
Laxminath Kasam6fc2e742018-08-26 23:32:57 +0530260static const char *const rx_sidetone_mix_text[] = {
261 "ZERO", "SRC0"
262};
263
Laxminath Kasam243e2752018-04-12 00:40:19 +0530264static const char * const wsa_macro_ear_spkr_pa_gain_text[] = {
265 "G_DEFAULT", "G_0_DB", "G_1_DB", "G_2_DB", "G_3_DB",
266 "G_4_DB", "G_5_DB", "G_6_DB"
267};
268
269static const char * const wsa_macro_speaker_boost_stage_text[] = {
270 "NO_MAX_STATE", "MAX_STATE_1", "MAX_STATE_2"
271};
272
Aditya Bavanari4f3d5642018-09-18 22:19:10 +0530273static const char * const wsa_macro_vbat_bcl_gsm_mode_text[] = {
274 "OFF", "ON"
275};
276
277static const struct snd_kcontrol_new wsa_int0_vbat_mix_switch[] = {
278 SOC_DAPM_SINGLE("WSA RX0 VBAT Enable", SND_SOC_NOPM, 0, 1, 0)
279};
280
281static const struct snd_kcontrol_new wsa_int1_vbat_mix_switch[] = {
282 SOC_DAPM_SINGLE("WSA RX1 VBAT Enable", SND_SOC_NOPM, 0, 1, 0)
283};
284
Laxminath Kasam243e2752018-04-12 00:40:19 +0530285static SOC_ENUM_SINGLE_EXT_DECL(wsa_macro_ear_spkr_pa_gain_enum,
286 wsa_macro_ear_spkr_pa_gain_text);
287static SOC_ENUM_SINGLE_EXT_DECL(wsa_macro_spkr_boost_stage_enum,
288 wsa_macro_speaker_boost_stage_text);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +0530289static SOC_ENUM_SINGLE_EXT_DECL(wsa_macro_vbat_bcl_gsm_mode_enum,
290 wsa_macro_vbat_bcl_gsm_mode_text);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530291
292/* RX INT0 */
293static const struct soc_enum rx0_prim_inp0_chain_enum =
294 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0,
295 0, 7, rx_text);
296
297static const struct soc_enum rx0_prim_inp1_chain_enum =
298 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0,
299 3, 7, rx_text);
300
301static const struct soc_enum rx0_prim_inp2_chain_enum =
302 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG1,
303 3, 7, rx_text);
304
305static const struct soc_enum rx0_mix_chain_enum =
306 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG1,
307 0, 5, rx_mix_text);
308
Laxminath Kasam6fc2e742018-08-26 23:32:57 +0530309static const struct soc_enum rx0_sidetone_mix_enum =
310 SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, 2, rx_sidetone_mix_text);
311
Laxminath Kasam243e2752018-04-12 00:40:19 +0530312static const struct snd_kcontrol_new rx0_prim_inp0_mux =
313 SOC_DAPM_ENUM("WSA_RX0 INP0 Mux", rx0_prim_inp0_chain_enum);
314
315static const struct snd_kcontrol_new rx0_prim_inp1_mux =
316 SOC_DAPM_ENUM("WSA_RX0 INP1 Mux", rx0_prim_inp1_chain_enum);
317
318static const struct snd_kcontrol_new rx0_prim_inp2_mux =
319 SOC_DAPM_ENUM("WSA_RX0 INP2 Mux", rx0_prim_inp2_chain_enum);
320
321static const struct snd_kcontrol_new rx0_mix_mux =
322 SOC_DAPM_ENUM("WSA_RX0 MIX Mux", rx0_mix_chain_enum);
323
Laxminath Kasam6fc2e742018-08-26 23:32:57 +0530324static const struct snd_kcontrol_new rx0_sidetone_mix_mux =
325 SOC_DAPM_ENUM("WSA_RX0 SIDETONE MIX Mux", rx0_sidetone_mix_enum);
326
Laxminath Kasam243e2752018-04-12 00:40:19 +0530327/* RX INT1 */
328static const struct soc_enum rx1_prim_inp0_chain_enum =
329 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT1_CFG0,
330 0, 7, rx_text);
331
332static const struct soc_enum rx1_prim_inp1_chain_enum =
333 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT1_CFG0,
334 3, 7, rx_text);
335
336static const struct soc_enum rx1_prim_inp2_chain_enum =
337 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT1_CFG1,
338 3, 7, rx_text);
339
340static const struct soc_enum rx1_mix_chain_enum =
341 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT1_CFG1,
342 0, 5, rx_mix_text);
343
344static const struct snd_kcontrol_new rx1_prim_inp0_mux =
345 SOC_DAPM_ENUM("WSA_RX1 INP0 Mux", rx1_prim_inp0_chain_enum);
346
347static const struct snd_kcontrol_new rx1_prim_inp1_mux =
348 SOC_DAPM_ENUM("WSA_RX1 INP1 Mux", rx1_prim_inp1_chain_enum);
349
350static const struct snd_kcontrol_new rx1_prim_inp2_mux =
351 SOC_DAPM_ENUM("WSA_RX1 INP2 Mux", rx1_prim_inp2_chain_enum);
352
353static const struct snd_kcontrol_new rx1_mix_mux =
354 SOC_DAPM_ENUM("WSA_RX1 MIX Mux", rx1_mix_chain_enum);
355
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +0530356static const struct soc_enum rx_mix_ec0_enum =
357 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0,
358 0, 3, rx_mix_ec_text);
359
360static const struct soc_enum rx_mix_ec1_enum =
361 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0,
362 3, 3, rx_mix_ec_text);
363
364static const struct snd_kcontrol_new rx_mix_ec0_mux =
365 SOC_DAPM_ENUM("WSA RX_MIX EC0_Mux", rx_mix_ec0_enum);
366
367static const struct snd_kcontrol_new rx_mix_ec1_mux =
368 SOC_DAPM_ENUM("WSA RX_MIX EC1_Mux", rx_mix_ec1_enum);
369
Laxminath Kasam243e2752018-04-12 00:40:19 +0530370static struct snd_soc_dai_ops wsa_macro_dai_ops = {
371 .hw_params = wsa_macro_hw_params,
372 .get_channel_map = wsa_macro_get_channel_map,
Laxminath Kasam52ae6582019-08-08 18:00:35 +0530373 .digital_mute = wsa_macro_digital_mute,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530374};
375
376static struct snd_soc_dai_driver wsa_macro_dai[] = {
377 {
378 .name = "wsa_macro_rx1",
379 .id = WSA_MACRO_AIF1_PB,
380 .playback = {
381 .stream_name = "WSA_AIF1 Playback",
382 .rates = WSA_MACRO_RX_RATES,
383 .formats = WSA_MACRO_RX_FORMATS,
384 .rate_max = 384000,
385 .rate_min = 8000,
386 .channels_min = 1,
387 .channels_max = 2,
388 },
389 .ops = &wsa_macro_dai_ops,
390 },
391 {
392 .name = "wsa_macro_rx_mix",
393 .id = WSA_MACRO_AIF_MIX1_PB,
394 .playback = {
395 .stream_name = "WSA_AIF_MIX1 Playback",
396 .rates = WSA_MACRO_RX_MIX_RATES,
397 .formats = WSA_MACRO_RX_FORMATS,
398 .rate_max = 192000,
399 .rate_min = 48000,
400 .channels_min = 1,
401 .channels_max = 2,
402 },
403 .ops = &wsa_macro_dai_ops,
404 },
405 {
406 .name = "wsa_macro_vifeedback",
407 .id = WSA_MACRO_AIF_VI,
408 .capture = {
409 .stream_name = "WSA_AIF_VI Capture",
Vatsal Buchad1b694d2018-08-31 11:47:32 +0530410 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000,
411 .formats = WSA_MACRO_RX_FORMATS,
412 .rate_max = 48000,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530413 .rate_min = 8000,
414 .channels_min = 1,
Vatsal Buchad1b694d2018-08-31 11:47:32 +0530415 .channels_max = 4,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530416 },
417 .ops = &wsa_macro_dai_ops,
418 },
419 {
420 .name = "wsa_macro_echo",
421 .id = WSA_MACRO_AIF_ECHO,
422 .capture = {
423 .stream_name = "WSA_AIF_ECHO Capture",
424 .rates = WSA_MACRO_ECHO_RATES,
425 .formats = WSA_MACRO_ECHO_FORMATS,
426 .rate_max = 48000,
427 .rate_min = 8000,
428 .channels_min = 1,
429 .channels_max = 2,
430 },
431 .ops = &wsa_macro_dai_ops,
432 },
433};
434
435static const struct wsa_macro_reg_mask_val wsa_macro_spkr_default[] = {
436 {BOLERO_CDC_WSA_COMPANDER0_CTL3, 0x80, 0x80},
437 {BOLERO_CDC_WSA_COMPANDER1_CTL3, 0x80, 0x80},
438 {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x01, 0x01},
439 {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x01, 0x01},
440 {BOLERO_CDC_WSA_BOOST0_BOOST_CTL, 0x7C, 0x58},
441 {BOLERO_CDC_WSA_BOOST1_BOOST_CTL, 0x7C, 0x58},
442};
443
444static const struct wsa_macro_reg_mask_val wsa_macro_spkr_mode1[] = {
445 {BOLERO_CDC_WSA_COMPANDER0_CTL3, 0x80, 0x00},
446 {BOLERO_CDC_WSA_COMPANDER1_CTL3, 0x80, 0x00},
447 {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x01, 0x00},
448 {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x01, 0x00},
449 {BOLERO_CDC_WSA_BOOST0_BOOST_CTL, 0x7C, 0x44},
450 {BOLERO_CDC_WSA_BOOST1_BOOST_CTL, 0x7C, 0x44},
451};
452
Meng Wang15c825d2018-09-06 10:49:18 +0800453static bool wsa_macro_get_data(struct snd_soc_component *component,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530454 struct device **wsa_dev,
455 struct wsa_macro_priv **wsa_priv,
456 const char *func_name)
457{
Meng Wang15c825d2018-09-06 10:49:18 +0800458 *wsa_dev = bolero_get_device_ptr(component->dev, WSA_MACRO);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530459 if (!(*wsa_dev)) {
Meng Wang15c825d2018-09-06 10:49:18 +0800460 dev_err(component->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530461 "%s: null device for macro!\n", func_name);
462 return false;
463 }
464 *wsa_priv = dev_get_drvdata((*wsa_dev));
Meng Wang15c825d2018-09-06 10:49:18 +0800465 if (!(*wsa_priv) || !(*wsa_priv)->component) {
466 dev_err(component->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530467 "%s: priv is null for macro!\n", func_name);
468 return false;
469 }
470 return true;
471}
472
Sudheer Papothia3e969d2018-10-27 06:22:10 +0530473static int wsa_macro_set_port_map(struct snd_soc_component *component,
474 u32 usecase, u32 size, void *data)
475{
476 struct device *wsa_dev = NULL;
477 struct wsa_macro_priv *wsa_priv = NULL;
478 struct swrm_port_config port_cfg;
479 int ret = 0;
480
481 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
482 return -EINVAL;
483
484 memset(&port_cfg, 0, sizeof(port_cfg));
485 port_cfg.uc = usecase;
486 port_cfg.size = size;
487 port_cfg.params = data;
488
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -0700489 if (wsa_priv->swr_ctrl_data)
490 ret = swrm_wcd_notify(
491 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
492 SWR_SET_PORT_MAP, &port_cfg);
Sudheer Papothia3e969d2018-10-27 06:22:10 +0530493
494 return ret;
495}
496
Laxminath Kasam243e2752018-04-12 00:40:19 +0530497/**
498 * wsa_macro_set_spkr_gain_offset - offset the speaker path
499 * gain with the given offset value.
500 *
Meng Wang15c825d2018-09-06 10:49:18 +0800501 * @component: codec instance
Laxminath Kasam243e2752018-04-12 00:40:19 +0530502 * @offset: Indicates speaker path gain offset value.
503 *
504 * Returns 0 on success or -EINVAL on error.
505 */
Meng Wang15c825d2018-09-06 10:49:18 +0800506int wsa_macro_set_spkr_gain_offset(struct snd_soc_component *component,
507 int offset)
Laxminath Kasam243e2752018-04-12 00:40:19 +0530508{
509 struct device *wsa_dev = NULL;
510 struct wsa_macro_priv *wsa_priv = NULL;
511
Meng Wang15c825d2018-09-06 10:49:18 +0800512 if (!component) {
513 pr_err("%s: NULL component pointer!\n", __func__);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530514 return -EINVAL;
515 }
516
Meng Wang15c825d2018-09-06 10:49:18 +0800517 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530518 return -EINVAL;
519
520 wsa_priv->spkr_gain_offset = offset;
521 return 0;
522}
523EXPORT_SYMBOL(wsa_macro_set_spkr_gain_offset);
524
525/**
526 * wsa_macro_set_spkr_mode - Configures speaker compander and smartboost
527 * settings based on speaker mode.
528 *
Meng Wang15c825d2018-09-06 10:49:18 +0800529 * @component: codec instance
Laxminath Kasam243e2752018-04-12 00:40:19 +0530530 * @mode: Indicates speaker configuration mode.
531 *
532 * Returns 0 on success or -EINVAL on error.
533 */
Meng Wang15c825d2018-09-06 10:49:18 +0800534int wsa_macro_set_spkr_mode(struct snd_soc_component *component, int mode)
Laxminath Kasam243e2752018-04-12 00:40:19 +0530535{
536 int i;
537 const struct wsa_macro_reg_mask_val *regs;
538 int size;
539 struct device *wsa_dev = NULL;
540 struct wsa_macro_priv *wsa_priv = NULL;
541
Meng Wang15c825d2018-09-06 10:49:18 +0800542 if (!component) {
Laxminath Kasam243e2752018-04-12 00:40:19 +0530543 pr_err("%s: NULL codec pointer!\n", __func__);
544 return -EINVAL;
545 }
546
Meng Wang15c825d2018-09-06 10:49:18 +0800547 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530548 return -EINVAL;
549
550 switch (mode) {
Laxminath Kasam21c8b222018-06-21 18:47:22 +0530551 case WSA_MACRO_SPKR_MODE_1:
Laxminath Kasam243e2752018-04-12 00:40:19 +0530552 regs = wsa_macro_spkr_mode1;
553 size = ARRAY_SIZE(wsa_macro_spkr_mode1);
554 break;
555 default:
556 regs = wsa_macro_spkr_default;
557 size = ARRAY_SIZE(wsa_macro_spkr_default);
558 break;
559 }
560
561 wsa_priv->spkr_mode = mode;
562 for (i = 0; i < size; i++)
Meng Wang15c825d2018-09-06 10:49:18 +0800563 snd_soc_component_update_bits(component, regs[i].reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530564 regs[i].mask, regs[i].val);
565 return 0;
566}
567EXPORT_SYMBOL(wsa_macro_set_spkr_mode);
568
569static int wsa_macro_set_prim_interpolator_rate(struct snd_soc_dai *dai,
570 u8 int_prim_fs_rate_reg_val,
571 u32 sample_rate)
572{
573 u8 int_1_mix1_inp;
574 u32 j, port;
575 u16 int_mux_cfg0, int_mux_cfg1;
576 u16 int_fs_reg;
577 u8 int_mux_cfg0_val, int_mux_cfg1_val;
578 u8 inp0_sel, inp1_sel, inp2_sel;
Meng Wang15c825d2018-09-06 10:49:18 +0800579 struct snd_soc_component *component = dai->component;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530580 struct device *wsa_dev = NULL;
581 struct wsa_macro_priv *wsa_priv = NULL;
582
Meng Wang15c825d2018-09-06 10:49:18 +0800583 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530584 return -EINVAL;
585
586 for_each_set_bit(port, &wsa_priv->active_ch_mask[dai->id],
587 WSA_MACRO_RX_MAX) {
588 int_1_mix1_inp = port;
589 if ((int_1_mix1_inp < WSA_MACRO_RX0) ||
590 (int_1_mix1_inp > WSA_MACRO_RX_MIX1)) {
591 dev_err(wsa_dev,
592 "%s: Invalid RX port, Dai ID is %d\n",
593 __func__, dai->id);
594 return -EINVAL;
595 }
596
597 int_mux_cfg0 = BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0;
598
599 /*
600 * Loop through all interpolator MUX inputs and find out
601 * to which interpolator input, the cdc_dma rx port
602 * is connected
603 */
604 for (j = 0; j < NUM_INTERPOLATORS; j++) {
605 int_mux_cfg1 = int_mux_cfg0 + WSA_MACRO_MUX_CFG1_OFFSET;
606
Meng Wang15c825d2018-09-06 10:49:18 +0800607 int_mux_cfg0_val = snd_soc_component_read32(component,
608 int_mux_cfg0);
609 int_mux_cfg1_val = snd_soc_component_read32(component,
610 int_mux_cfg1);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530611 inp0_sel = int_mux_cfg0_val & WSA_MACRO_MUX_INP_MASK1;
612 inp1_sel = (int_mux_cfg0_val >>
613 WSA_MACRO_MUX_INP_SHFT) &
614 WSA_MACRO_MUX_INP_MASK2;
615 inp2_sel = (int_mux_cfg1_val >>
616 WSA_MACRO_MUX_INP_SHFT) &
617 WSA_MACRO_MUX_INP_MASK2;
618 if ((inp0_sel == int_1_mix1_inp) ||
619 (inp1_sel == int_1_mix1_inp) ||
620 (inp2_sel == int_1_mix1_inp)) {
621 int_fs_reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL +
622 WSA_MACRO_RX_PATH_OFFSET * j;
623 dev_dbg(wsa_dev,
624 "%s: AIF_PB DAI(%d) connected to INT%u_1\n",
625 __func__, dai->id, j);
626 dev_dbg(wsa_dev,
627 "%s: set INT%u_1 sample rate to %u\n",
628 __func__, j, sample_rate);
629 /* sample_rate is in Hz */
Meng Wang15c825d2018-09-06 10:49:18 +0800630 snd_soc_component_update_bits(component,
631 int_fs_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530632 WSA_MACRO_FS_RATE_MASK,
633 int_prim_fs_rate_reg_val);
634 }
635 int_mux_cfg0 += WSA_MACRO_MUX_CFG_OFFSET;
636 }
637 }
638
639 return 0;
640}
641
642static int wsa_macro_set_mix_interpolator_rate(struct snd_soc_dai *dai,
643 u8 int_mix_fs_rate_reg_val,
644 u32 sample_rate)
645{
646 u8 int_2_inp;
647 u32 j, port;
648 u16 int_mux_cfg1, int_fs_reg;
649 u8 int_mux_cfg1_val;
Meng Wang15c825d2018-09-06 10:49:18 +0800650 struct snd_soc_component *component = dai->component;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530651 struct device *wsa_dev = NULL;
652 struct wsa_macro_priv *wsa_priv = NULL;
653
Meng Wang15c825d2018-09-06 10:49:18 +0800654 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530655 return -EINVAL;
656
657
658 for_each_set_bit(port, &wsa_priv->active_ch_mask[dai->id],
659 WSA_MACRO_RX_MAX) {
660 int_2_inp = port;
661 if ((int_2_inp < WSA_MACRO_RX0) ||
662 (int_2_inp > WSA_MACRO_RX_MIX1)) {
663 dev_err(wsa_dev,
664 "%s: Invalid RX port, Dai ID is %d\n",
665 __func__, dai->id);
666 return -EINVAL;
667 }
668
669 int_mux_cfg1 = BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG1;
670 for (j = 0; j < NUM_INTERPOLATORS; j++) {
Meng Wang15c825d2018-09-06 10:49:18 +0800671 int_mux_cfg1_val = snd_soc_component_read32(component,
672 int_mux_cfg1) &
Laxminath Kasam243e2752018-04-12 00:40:19 +0530673 WSA_MACRO_MUX_INP_MASK1;
674 if (int_mux_cfg1_val == int_2_inp) {
675 int_fs_reg =
676 BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL +
677 WSA_MACRO_RX_PATH_OFFSET * j;
678
679 dev_dbg(wsa_dev,
680 "%s: AIF_PB DAI(%d) connected to INT%u_2\n",
681 __func__, dai->id, j);
682 dev_dbg(wsa_dev,
683 "%s: set INT%u_2 sample rate to %u\n",
684 __func__, j, sample_rate);
Meng Wang15c825d2018-09-06 10:49:18 +0800685 snd_soc_component_update_bits(component,
686 int_fs_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530687 WSA_MACRO_FS_RATE_MASK,
688 int_mix_fs_rate_reg_val);
689 }
690 int_mux_cfg1 += WSA_MACRO_MUX_CFG_OFFSET;
691 }
692 }
693 return 0;
694}
695
696static int wsa_macro_set_interpolator_rate(struct snd_soc_dai *dai,
697 u32 sample_rate)
698{
699 int rate_val = 0;
700 int i, ret;
701
702 /* set mixing path rate */
703 for (i = 0; i < ARRAY_SIZE(int_mix_sample_rate_val); i++) {
704 if (sample_rate ==
705 int_mix_sample_rate_val[i].sample_rate) {
706 rate_val =
707 int_mix_sample_rate_val[i].rate_val;
708 break;
709 }
710 }
711 if ((i == ARRAY_SIZE(int_mix_sample_rate_val)) ||
712 (rate_val < 0))
713 goto prim_rate;
714 ret = wsa_macro_set_mix_interpolator_rate(dai,
715 (u8) rate_val, sample_rate);
716prim_rate:
717 /* set primary path sample rate */
718 for (i = 0; i < ARRAY_SIZE(int_prim_sample_rate_val); i++) {
719 if (sample_rate ==
720 int_prim_sample_rate_val[i].sample_rate) {
721 rate_val =
722 int_prim_sample_rate_val[i].rate_val;
723 break;
724 }
725 }
726 if ((i == ARRAY_SIZE(int_prim_sample_rate_val)) ||
727 (rate_val < 0))
728 return -EINVAL;
729 ret = wsa_macro_set_prim_interpolator_rate(dai,
730 (u8) rate_val, sample_rate);
731 return ret;
732}
733
734static int wsa_macro_hw_params(struct snd_pcm_substream *substream,
735 struct snd_pcm_hw_params *params,
736 struct snd_soc_dai *dai)
737{
Meng Wang15c825d2018-09-06 10:49:18 +0800738 struct snd_soc_component *component = dai->component;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530739 int ret;
740
Meng Wang15c825d2018-09-06 10:49:18 +0800741 dev_dbg(component->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530742 "%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__,
743 dai->name, dai->id, params_rate(params),
744 params_channels(params));
745
746 switch (substream->stream) {
747 case SNDRV_PCM_STREAM_PLAYBACK:
748 ret = wsa_macro_set_interpolator_rate(dai, params_rate(params));
749 if (ret) {
Meng Wang15c825d2018-09-06 10:49:18 +0800750 dev_err(component->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530751 "%s: cannot set sample rate: %u\n",
752 __func__, params_rate(params));
753 return ret;
754 }
755 break;
756 case SNDRV_PCM_STREAM_CAPTURE:
757 default:
758 break;
759 }
760 return 0;
761}
762
763static int wsa_macro_get_channel_map(struct snd_soc_dai *dai,
764 unsigned int *tx_num, unsigned int *tx_slot,
765 unsigned int *rx_num, unsigned int *rx_slot)
766{
Meng Wang15c825d2018-09-06 10:49:18 +0800767 struct snd_soc_component *component = dai->component;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530768 struct device *wsa_dev = NULL;
769 struct wsa_macro_priv *wsa_priv = NULL;
Laxminath Kasam5d9ea8d2018-11-28 14:32:40 +0530770 u16 val = 0, mask = 0, cnt = 0;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530771
Meng Wang15c825d2018-09-06 10:49:18 +0800772 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530773 return -EINVAL;
774
775 wsa_priv = dev_get_drvdata(wsa_dev);
776 if (!wsa_priv)
777 return -EINVAL;
778
779 switch (dai->id) {
780 case WSA_MACRO_AIF_VI:
Laxminath Kasam243e2752018-04-12 00:40:19 +0530781 *tx_slot = wsa_priv->active_ch_mask[dai->id];
782 *tx_num = wsa_priv->active_ch_cnt[dai->id];
783 break;
784 case WSA_MACRO_AIF1_PB:
785 case WSA_MACRO_AIF_MIX1_PB:
786 *rx_slot = wsa_priv->active_ch_mask[dai->id];
787 *rx_num = wsa_priv->active_ch_cnt[dai->id];
788 break;
Laxminath Kasam5d9ea8d2018-11-28 14:32:40 +0530789 case WSA_MACRO_AIF_ECHO:
790 val = snd_soc_component_read32(component,
791 BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0);
792 if (val & WSA_MACRO_EC_MIX_TX1_MASK) {
793 mask |= 0x2;
794 cnt++;
795 }
796 if (val & WSA_MACRO_EC_MIX_TX0_MASK) {
797 mask |= 0x1;
798 cnt++;
799 }
800 *tx_slot = mask;
801 *tx_num = cnt;
802 break;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530803 default:
804 dev_err(wsa_dev, "%s: Invalid AIF\n", __func__);
805 break;
806 }
807 return 0;
808}
809
Laxminath Kasam52ae6582019-08-08 18:00:35 +0530810static int wsa_macro_digital_mute(struct snd_soc_dai *dai, int mute)
811{
812 struct snd_soc_component *component = dai->component;
813 struct device *wsa_dev = NULL;
814 struct wsa_macro_priv *wsa_priv = NULL;
815 uint16_t j = 0, reg = 0, mix_reg = 0, dsm_reg = 0;
816 u16 int_mux_cfg0 = 0, int_mux_cfg1 = 0;
817 u8 int_mux_cfg0_val = 0, int_mux_cfg1_val = 0;
818
819 if (mute)
820 return 0;
821
822 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
823 return -EINVAL;
824
825 switch (dai->id) {
826 case WSA_MACRO_AIF1_PB:
827 case WSA_MACRO_AIF_MIX1_PB:
828 for (j = 0; j < NUM_INTERPOLATORS; j++) {
829 reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL +
830 (j * WSA_MACRO_RX_PATH_OFFSET);
831 mix_reg = BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL +
832 (j * WSA_MACRO_RX_PATH_OFFSET);
833 dsm_reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL +
834 (j * WSA_MACRO_RX_PATH_OFFSET) +
835 WSA_MACRO_RX_PATH_DSMDEM_OFFSET;
836 int_mux_cfg0 = BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0 + j * 8;
837 int_mux_cfg1 = int_mux_cfg0 + 4;
838 int_mux_cfg0_val = snd_soc_component_read32(component,
839 int_mux_cfg0);
840 int_mux_cfg1_val = snd_soc_component_read32(component,
841 int_mux_cfg1);
842 if (snd_soc_component_read32(component, dsm_reg) & 0x01) {
843 if (int_mux_cfg0_val || (int_mux_cfg1_val & 0x38))
844 snd_soc_component_update_bits(component, reg,
845 0x20, 0x20);
846 if (int_mux_cfg1_val & 0x07)
847 snd_soc_component_update_bits(component,
848 mix_reg, 0x20, 0x20);
849 }
850 }
Laxminath Kasam069df142019-09-17 23:43:34 +0530851 bolero_wsa_pa_on(wsa_dev);
Laxminath Kasam52ae6582019-08-08 18:00:35 +0530852 break;
853 default:
854 break;
855 }
856 return 0;
857}
Laxminath Kasam243e2752018-04-12 00:40:19 +0530858static int wsa_macro_mclk_enable(struct wsa_macro_priv *wsa_priv,
859 bool mclk_enable, bool dapm)
860{
861 struct regmap *regmap = dev_get_regmap(wsa_priv->dev->parent, NULL);
862 int ret = 0;
863
Tanya Dixitab8eba82018-10-05 15:07:37 +0530864 if (regmap == NULL) {
865 dev_err(wsa_priv->dev, "%s: regmap is NULL\n", __func__);
866 return -EINVAL;
867 }
868
Laxminath Kasam243e2752018-04-12 00:40:19 +0530869 dev_dbg(wsa_priv->dev, "%s: mclk_enable = %u, dapm = %d clk_users= %d\n",
870 __func__, mclk_enable, dapm, wsa_priv->wsa_mclk_users);
871
872 mutex_lock(&wsa_priv->mclk_lock);
873 if (mclk_enable) {
Aditya Bavanaric496ed22018-11-16 15:50:40 +0530874 if (wsa_priv->wsa_mclk_users == 0) {
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -0700875 ret = bolero_clk_rsc_request_clock(wsa_priv->dev,
876 wsa_priv->default_clk_id,
877 wsa_priv->default_clk_id,
878 true);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530879 if (ret < 0) {
Ramprasad Katkam14efed62019-03-07 13:16:50 +0530880 dev_err_ratelimited(wsa_priv->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +0530881 "%s: wsa request clock enable failed\n",
882 __func__);
883 goto exit;
884 }
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -0700885 bolero_clk_rsc_fs_gen_request(wsa_priv->dev,
886 true);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530887 regcache_mark_dirty(regmap);
888 regcache_sync_region(regmap,
889 WSA_START_OFFSET,
890 WSA_MAX_OFFSET);
891 /* 9.6MHz MCLK, set value 0x00 if other frequency */
892 regmap_update_bits(regmap,
893 BOLERO_CDC_WSA_TOP_FREQ_MCLK, 0x01, 0x01);
894 regmap_update_bits(regmap,
895 BOLERO_CDC_WSA_CLK_RST_CTRL_MCLK_CONTROL,
896 0x01, 0x01);
897 regmap_update_bits(regmap,
898 BOLERO_CDC_WSA_CLK_RST_CTRL_FS_CNT_CONTROL,
899 0x01, 0x01);
900 }
Aditya Bavanaric496ed22018-11-16 15:50:40 +0530901 wsa_priv->wsa_mclk_users++;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530902 } else {
Aditya Bavanaric496ed22018-11-16 15:50:40 +0530903 if (wsa_priv->wsa_mclk_users <= 0) {
904 dev_err(wsa_priv->dev, "%s: clock already disabled\n",
905 __func__);
906 wsa_priv->wsa_mclk_users = 0;
907 goto exit;
908 }
Laxminath Kasam243e2752018-04-12 00:40:19 +0530909 wsa_priv->wsa_mclk_users--;
910 if (wsa_priv->wsa_mclk_users == 0) {
911 regmap_update_bits(regmap,
912 BOLERO_CDC_WSA_CLK_RST_CTRL_FS_CNT_CONTROL,
913 0x01, 0x00);
914 regmap_update_bits(regmap,
915 BOLERO_CDC_WSA_CLK_RST_CTRL_MCLK_CONTROL,
916 0x01, 0x00);
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -0700917 bolero_clk_rsc_fs_gen_request(wsa_priv->dev,
918 false);
919
920 bolero_clk_rsc_request_clock(wsa_priv->dev,
921 wsa_priv->default_clk_id,
922 wsa_priv->default_clk_id,
923 false);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530924 }
925 }
926exit:
927 mutex_unlock(&wsa_priv->mclk_lock);
928 return ret;
929}
930
931static int wsa_macro_mclk_event(struct snd_soc_dapm_widget *w,
932 struct snd_kcontrol *kcontrol, int event)
933{
Meng Wang15c825d2018-09-06 10:49:18 +0800934 struct snd_soc_component *component =
935 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530936 int ret = 0;
937 struct device *wsa_dev = NULL;
938 struct wsa_macro_priv *wsa_priv = NULL;
939
Meng Wang15c825d2018-09-06 10:49:18 +0800940 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +0530941 return -EINVAL;
942
943 dev_dbg(wsa_dev, "%s: event = %d\n", __func__, event);
944 switch (event) {
945 case SND_SOC_DAPM_PRE_PMU:
946 ret = wsa_macro_mclk_enable(wsa_priv, 1, true);
Ramprasad Katkam452772a2019-01-07 17:30:36 +0530947 if (ret)
948 wsa_priv->dapm_mclk_enable = false;
949 else
950 wsa_priv->dapm_mclk_enable = true;
Laxminath Kasam243e2752018-04-12 00:40:19 +0530951 break;
952 case SND_SOC_DAPM_POST_PMD:
Ramprasad Katkam452772a2019-01-07 17:30:36 +0530953 if (wsa_priv->dapm_mclk_enable)
954 wsa_macro_mclk_enable(wsa_priv, 0, true);
Laxminath Kasam243e2752018-04-12 00:40:19 +0530955 break;
956 default:
957 dev_err(wsa_priv->dev,
958 "%s: invalid DAPM event %d\n", __func__, event);
959 ret = -EINVAL;
960 }
961 return ret;
962}
963
Meng Wang15c825d2018-09-06 10:49:18 +0800964static int wsa_macro_event_handler(struct snd_soc_component *component,
965 u16 event, u32 data)
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530966{
967 struct device *wsa_dev = NULL;
968 struct wsa_macro_priv *wsa_priv = NULL;
Meng Wangbd930242019-06-25 09:39:48 +0800969 int ret = 0;
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530970
Meng Wang15c825d2018-09-06 10:49:18 +0800971 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530972 return -EINVAL;
973
974 switch (event) {
975 case BOLERO_MACRO_EVT_SSR_DOWN:
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -0700976 if (wsa_priv->swr_ctrl_data) {
977 swrm_wcd_notify(
978 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
979 SWR_DEVICE_DOWN, NULL);
980 swrm_wcd_notify(
981 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
982 SWR_DEVICE_SSR_DOWN, NULL);
983 }
Aditya Bavanari50ef13e2019-08-09 15:14:43 +0530984 if ((!pm_runtime_enabled(wsa_dev) ||
985 !pm_runtime_suspended(wsa_dev))) {
986 ret = bolero_runtime_suspend(wsa_dev);
987 if (!ret) {
988 pm_runtime_disable(wsa_dev);
989 pm_runtime_set_suspended(wsa_dev);
990 pm_runtime_enable(wsa_dev);
991 }
992 }
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530993 break;
994 case BOLERO_MACRO_EVT_SSR_UP:
Ramprasad Katkama4c747b2018-12-11 19:15:53 +0530995 /* reset swr after ssr/pdr */
996 wsa_priv->reset_swr = true;
Meng Wangbd930242019-06-25 09:39:48 +0800997 /* enable&disable WSA_CORE_CLK to reset GFMUX reg */
998 ret = bolero_clk_rsc_request_clock(wsa_priv->dev,
999 wsa_priv->default_clk_id,
1000 WSA_CORE_CLK, true);
1001 if (ret < 0)
1002 dev_err_ratelimited(wsa_priv->dev,
1003 "%s, failed to enable clk, ret:%d\n",
1004 __func__, ret);
1005 else
1006 bolero_clk_rsc_request_clock(wsa_priv->dev,
1007 wsa_priv->default_clk_id,
1008 WSA_CORE_CLK, false);
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07001009 if (wsa_priv->swr_ctrl_data)
1010 swrm_wcd_notify(
1011 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
1012 SWR_DEVICE_SSR_UP, NULL);
Laxminath Kasamfb0d6832018-09-22 01:49:52 +05301013 break;
Meng Wang8ef0cc22019-05-08 15:12:56 +08001014 case BOLERO_MACRO_EVT_CLK_RESET:
1015 bolero_rsc_clk_reset(wsa_dev, WSA_CORE_CLK);
1016 break;
Laxminath Kasamfb0d6832018-09-22 01:49:52 +05301017 }
1018 return 0;
1019}
1020
Laxminath Kasam243e2752018-04-12 00:40:19 +05301021static int wsa_macro_enable_vi_feedback(struct snd_soc_dapm_widget *w,
1022 struct snd_kcontrol *kcontrol,
1023 int event)
1024{
Meng Wang15c825d2018-09-06 10:49:18 +08001025 struct snd_soc_component *component =
1026 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301027 struct device *wsa_dev = NULL;
1028 struct wsa_macro_priv *wsa_priv = NULL;
1029
Meng Wang15c825d2018-09-06 10:49:18 +08001030 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301031 return -EINVAL;
1032
1033 switch (event) {
1034 case SND_SOC_DAPM_POST_PMU:
1035 if (test_bit(WSA_MACRO_TX0,
1036 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
1037 dev_dbg(wsa_dev, "%s: spkr1 enabled\n", __func__);
1038 /* Enable V&I sensing */
Meng Wang15c825d2018-09-06 10:49:18 +08001039 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301040 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
1041 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08001042 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301043 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
1044 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08001045 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301046 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
1047 0x0F, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001048 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301049 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
1050 0x0F, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001051 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301052 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
1053 0x10, 0x10);
Meng Wang15c825d2018-09-06 10:49:18 +08001054 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301055 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
1056 0x10, 0x10);
Meng Wang15c825d2018-09-06 10:49:18 +08001057 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301058 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
1059 0x20, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001060 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301061 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
1062 0x20, 0x00);
1063 }
1064 if (test_bit(WSA_MACRO_TX1,
1065 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
1066 dev_dbg(wsa_dev, "%s: spkr2 enabled\n", __func__);
1067 /* Enable V&I sensing */
Meng Wang15c825d2018-09-06 10:49:18 +08001068 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301069 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
1070 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08001071 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301072 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
1073 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08001074 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301075 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
1076 0x0F, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001077 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301078 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
1079 0x0F, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001080 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301081 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
1082 0x10, 0x10);
Meng Wang15c825d2018-09-06 10:49:18 +08001083 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301084 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
1085 0x10, 0x10);
Meng Wang15c825d2018-09-06 10:49:18 +08001086 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301087 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
1088 0x20, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001089 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301090 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
1091 0x20, 0x00);
1092 }
1093 break;
1094 case SND_SOC_DAPM_POST_PMD:
1095 if (test_bit(WSA_MACRO_TX0,
1096 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
1097 /* Disable V&I sensing */
Meng Wang15c825d2018-09-06 10:49:18 +08001098 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301099 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
1100 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08001101 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301102 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
1103 0x20, 0x20);
1104 dev_dbg(wsa_dev, "%s: spkr1 disabled\n", __func__);
Meng Wang15c825d2018-09-06 10:49:18 +08001105 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301106 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
1107 0x10, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001108 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301109 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
1110 0x10, 0x00);
1111 }
1112 if (test_bit(WSA_MACRO_TX1,
1113 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
1114 /* Disable V&I sensing */
1115 dev_dbg(wsa_dev, "%s: spkr2 disabled\n", __func__);
Meng Wang15c825d2018-09-06 10:49:18 +08001116 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301117 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
1118 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08001119 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301120 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
1121 0x20, 0x20);
Meng Wang15c825d2018-09-06 10:49:18 +08001122 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301123 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
1124 0x10, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001125 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301126 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
1127 0x10, 0x00);
1128 }
1129 break;
1130 }
1131
1132 return 0;
1133}
1134
1135static int wsa_macro_enable_mix_path(struct snd_soc_dapm_widget *w,
1136 struct snd_kcontrol *kcontrol, int event)
1137{
Meng Wang15c825d2018-09-06 10:49:18 +08001138 struct snd_soc_component *component =
1139 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301140 u16 gain_reg;
1141 int offset_val = 0;
1142 int val = 0;
1143
Meng Wang15c825d2018-09-06 10:49:18 +08001144 dev_dbg(component->dev, "%s %d %s\n", __func__, event, w->name);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301145
1146 switch (w->reg) {
1147 case BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL:
1148 gain_reg = BOLERO_CDC_WSA_RX0_RX_VOL_MIX_CTL;
1149 break;
1150 case BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL:
1151 gain_reg = BOLERO_CDC_WSA_RX1_RX_VOL_MIX_CTL;
1152 break;
1153 default:
Meng Wang15c825d2018-09-06 10:49:18 +08001154 dev_err(component->dev, "%s: No gain register avail for %s\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301155 __func__, w->name);
1156 return 0;
1157 }
1158
1159 switch (event) {
1160 case SND_SOC_DAPM_POST_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08001161 val = snd_soc_component_read32(component, gain_reg);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301162 val += offset_val;
Meng Wang15c825d2018-09-06 10:49:18 +08001163 snd_soc_component_write(component, gain_reg, val);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301164 break;
1165 case SND_SOC_DAPM_POST_PMD:
Laxminath Kasam52ae6582019-08-08 18:00:35 +05301166 snd_soc_component_update_bits(component,
1167 w->reg, 0x20, 0x00);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301168 break;
1169 }
1170
1171 return 0;
1172}
1173
Meng Wang15c825d2018-09-06 10:49:18 +08001174static void wsa_macro_hd2_control(struct snd_soc_component *component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301175 u16 reg, int event)
1176{
1177 u16 hd2_scale_reg;
1178 u16 hd2_enable_reg = 0;
1179
1180 if (reg == BOLERO_CDC_WSA_RX0_RX_PATH_CTL) {
1181 hd2_scale_reg = BOLERO_CDC_WSA_RX0_RX_PATH_SEC3;
1182 hd2_enable_reg = BOLERO_CDC_WSA_RX0_RX_PATH_CFG0;
1183 }
1184 if (reg == BOLERO_CDC_WSA_RX1_RX_PATH_CTL) {
1185 hd2_scale_reg = BOLERO_CDC_WSA_RX1_RX_PATH_SEC3;
1186 hd2_enable_reg = BOLERO_CDC_WSA_RX1_RX_PATH_CFG0;
1187 }
1188
1189 if (hd2_enable_reg && SND_SOC_DAPM_EVENT_ON(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001190 snd_soc_component_update_bits(component, hd2_scale_reg,
1191 0x3C, 0x10);
1192 snd_soc_component_update_bits(component, hd2_scale_reg,
1193 0x03, 0x01);
1194 snd_soc_component_update_bits(component, hd2_enable_reg,
1195 0x04, 0x04);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301196 }
1197
1198 if (hd2_enable_reg && SND_SOC_DAPM_EVENT_OFF(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001199 snd_soc_component_update_bits(component, hd2_enable_reg,
1200 0x04, 0x00);
1201 snd_soc_component_update_bits(component, hd2_scale_reg,
1202 0x03, 0x00);
1203 snd_soc_component_update_bits(component, hd2_scale_reg,
1204 0x3C, 0x00);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301205 }
1206}
1207
1208static int wsa_macro_enable_swr(struct snd_soc_dapm_widget *w,
1209 struct snd_kcontrol *kcontrol, int event)
1210{
Meng Wang15c825d2018-09-06 10:49:18 +08001211 struct snd_soc_component *component =
1212 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301213 int ch_cnt;
1214 struct device *wsa_dev = NULL;
1215 struct wsa_macro_priv *wsa_priv = NULL;
1216
Meng Wang15c825d2018-09-06 10:49:18 +08001217 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301218 return -EINVAL;
1219
1220 switch (event) {
1221 case SND_SOC_DAPM_PRE_PMU:
1222 if (!(strnstr(w->name, "RX0", sizeof("WSA_RX0"))) &&
1223 !wsa_priv->rx_0_count)
1224 wsa_priv->rx_0_count++;
1225 if (!(strnstr(w->name, "RX1", sizeof("WSA_RX1"))) &&
1226 !wsa_priv->rx_1_count)
1227 wsa_priv->rx_1_count++;
1228 ch_cnt = wsa_priv->rx_0_count + wsa_priv->rx_1_count;
1229
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07001230 if (wsa_priv->swr_ctrl_data) {
1231 swrm_wcd_notify(
1232 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
1233 SWR_DEVICE_UP, NULL);
1234 swrm_wcd_notify(
1235 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
1236 SWR_SET_NUM_RX_CH, &ch_cnt);
1237 }
Laxminath Kasam243e2752018-04-12 00:40:19 +05301238 break;
1239 case SND_SOC_DAPM_POST_PMD:
1240 if (!(strnstr(w->name, "RX0", sizeof("WSA_RX0"))) &&
1241 wsa_priv->rx_0_count)
1242 wsa_priv->rx_0_count--;
1243 if (!(strnstr(w->name, "RX1", sizeof("WSA_RX1"))) &&
1244 wsa_priv->rx_1_count)
1245 wsa_priv->rx_1_count--;
1246 ch_cnt = wsa_priv->rx_0_count + wsa_priv->rx_1_count;
1247
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07001248 if (wsa_priv->swr_ctrl_data)
1249 swrm_wcd_notify(
1250 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
1251 SWR_SET_NUM_RX_CH, &ch_cnt);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301252 break;
1253 }
1254 dev_dbg(wsa_priv->dev, "%s: current swr ch cnt: %d\n",
1255 __func__, wsa_priv->rx_0_count + wsa_priv->rx_1_count);
1256
1257 return 0;
1258}
1259
Meng Wang15c825d2018-09-06 10:49:18 +08001260static int wsa_macro_config_compander(struct snd_soc_component *component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301261 int comp, int event)
1262{
1263 u16 comp_ctl0_reg, rx_path_cfg0_reg;
1264 struct device *wsa_dev = NULL;
1265 struct wsa_macro_priv *wsa_priv = NULL;
1266
Meng Wang15c825d2018-09-06 10:49:18 +08001267 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301268 return -EINVAL;
1269
Meng Wang15c825d2018-09-06 10:49:18 +08001270 dev_dbg(component->dev, "%s: event %d compander %d, enabled %d\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301271 __func__, event, comp + 1, wsa_priv->comp_enabled[comp]);
1272
1273 if (!wsa_priv->comp_enabled[comp])
1274 return 0;
1275
1276 comp_ctl0_reg = BOLERO_CDC_WSA_COMPANDER0_CTL0 +
1277 (comp * WSA_MACRO_RX_COMP_OFFSET);
1278 rx_path_cfg0_reg = BOLERO_CDC_WSA_RX0_RX_PATH_CFG0 +
1279 (comp * WSA_MACRO_RX_PATH_OFFSET);
1280
1281 if (SND_SOC_DAPM_EVENT_ON(event)) {
1282 /* Enable Compander Clock */
Meng Wang15c825d2018-09-06 10:49:18 +08001283 snd_soc_component_update_bits(component, comp_ctl0_reg,
1284 0x01, 0x01);
1285 snd_soc_component_update_bits(component, comp_ctl0_reg,
1286 0x02, 0x02);
1287 snd_soc_component_update_bits(component, comp_ctl0_reg,
1288 0x02, 0x00);
1289 snd_soc_component_update_bits(component, rx_path_cfg0_reg,
1290 0x02, 0x02);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301291 }
1292
1293 if (SND_SOC_DAPM_EVENT_OFF(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001294 snd_soc_component_update_bits(component, comp_ctl0_reg,
1295 0x04, 0x04);
1296 snd_soc_component_update_bits(component, rx_path_cfg0_reg,
1297 0x02, 0x00);
1298 snd_soc_component_update_bits(component, comp_ctl0_reg,
1299 0x02, 0x02);
1300 snd_soc_component_update_bits(component, comp_ctl0_reg,
1301 0x02, 0x00);
1302 snd_soc_component_update_bits(component, comp_ctl0_reg,
1303 0x01, 0x00);
1304 snd_soc_component_update_bits(component, comp_ctl0_reg,
1305 0x04, 0x00);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301306 }
1307
1308 return 0;
1309}
1310
Meng Wang15c825d2018-09-06 10:49:18 +08001311static void wsa_macro_enable_softclip_clk(struct snd_soc_component *component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301312 struct wsa_macro_priv *wsa_priv,
1313 int path,
1314 bool enable)
1315{
1316 u16 softclip_clk_reg = BOLERO_CDC_WSA_SOFTCLIP0_CRC +
1317 (path * WSA_MACRO_RX_SOFTCLIP_OFFSET);
1318 u8 softclip_mux_mask = (1 << path);
1319 u8 softclip_mux_value = (1 << path);
1320
Meng Wang15c825d2018-09-06 10:49:18 +08001321 dev_dbg(component->dev, "%s: path %d, enable %d\n",
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301322 __func__, path, enable);
1323 if (enable) {
1324 if (wsa_priv->softclip_clk_users[path] == 0) {
Meng Wang15c825d2018-09-06 10:49:18 +08001325 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301326 softclip_clk_reg, 0x01, 0x01);
Meng Wang15c825d2018-09-06 10:49:18 +08001327 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301328 BOLERO_CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0,
1329 softclip_mux_mask, softclip_mux_value);
1330 }
1331 wsa_priv->softclip_clk_users[path]++;
1332 } else {
1333 wsa_priv->softclip_clk_users[path]--;
1334 if (wsa_priv->softclip_clk_users[path] == 0) {
Meng Wang15c825d2018-09-06 10:49:18 +08001335 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301336 softclip_clk_reg, 0x01, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001337 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301338 BOLERO_CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0,
1339 softclip_mux_mask, 0x00);
1340 }
1341 }
1342}
1343
Meng Wang15c825d2018-09-06 10:49:18 +08001344static int wsa_macro_config_softclip(struct snd_soc_component *component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301345 int path, int event)
1346{
1347 u16 softclip_ctrl_reg = 0;
1348 struct device *wsa_dev = NULL;
1349 struct wsa_macro_priv *wsa_priv = NULL;
1350 int softclip_path = 0;
1351
Meng Wang15c825d2018-09-06 10:49:18 +08001352 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301353 return -EINVAL;
1354
1355 if (path == WSA_MACRO_COMP1)
1356 softclip_path = WSA_MACRO_SOFTCLIP0;
1357 else if (path == WSA_MACRO_COMP2)
1358 softclip_path = WSA_MACRO_SOFTCLIP1;
1359
Meng Wang15c825d2018-09-06 10:49:18 +08001360 dev_dbg(component->dev, "%s: event %d path %d, enabled %d\n",
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301361 __func__, event, softclip_path,
1362 wsa_priv->is_softclip_on[softclip_path]);
1363
1364 if (!wsa_priv->is_softclip_on[softclip_path])
1365 return 0;
1366
1367 softclip_ctrl_reg = BOLERO_CDC_WSA_SOFTCLIP0_SOFTCLIP_CTRL +
1368 (softclip_path * WSA_MACRO_RX_SOFTCLIP_OFFSET);
1369
1370 if (SND_SOC_DAPM_EVENT_ON(event)) {
1371 /* Enable Softclip clock and mux */
Meng Wang15c825d2018-09-06 10:49:18 +08001372 wsa_macro_enable_softclip_clk(component, wsa_priv,
1373 softclip_path, true);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301374 /* Enable Softclip control */
Meng Wang15c825d2018-09-06 10:49:18 +08001375 snd_soc_component_update_bits(component, softclip_ctrl_reg,
1376 0x01, 0x01);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301377 }
1378
1379 if (SND_SOC_DAPM_EVENT_OFF(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001380 snd_soc_component_update_bits(component, softclip_ctrl_reg,
1381 0x01, 0x00);
1382 wsa_macro_enable_softclip_clk(component, wsa_priv,
1383 softclip_path, false);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301384 }
1385
1386 return 0;
1387}
1388
Laxminath Kasam52ae6582019-08-08 18:00:35 +05301389static bool wsa_macro_adie_lb(struct snd_soc_component *component,
1390 int interp_idx)
1391{
1392 u16 int_mux_cfg0 = 0, int_mux_cfg1 = 0;
1393 u8 int_mux_cfg0_val = 0, int_mux_cfg1_val = 0;
1394 u8 int_n_inp0 = 0, int_n_inp1 = 0, int_n_inp2 = 0;
1395
1396 int_mux_cfg0 = BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0 + interp_idx * 8;
1397 int_mux_cfg1 = int_mux_cfg0 + 4;
1398 int_mux_cfg0_val = snd_soc_component_read32(component, int_mux_cfg0);
1399 int_mux_cfg1_val = snd_soc_component_read32(component, int_mux_cfg1);
1400
1401 int_n_inp0 = int_mux_cfg0_val & 0x0F;
1402 if (int_n_inp0 == INTn_1_INP_SEL_DEC0 ||
1403 int_n_inp0 == INTn_1_INP_SEL_DEC1)
1404 return true;
1405
1406 int_n_inp1 = int_mux_cfg0_val >> 4;
1407 if (int_n_inp1 == INTn_1_INP_SEL_DEC0 ||
1408 int_n_inp1 == INTn_1_INP_SEL_DEC1)
1409 return true;
1410
1411 int_n_inp2 = int_mux_cfg1_val >> 4;
1412 if (int_n_inp2 == INTn_1_INP_SEL_DEC0 ||
1413 int_n_inp2 == INTn_1_INP_SEL_DEC1)
1414 return true;
1415
1416 return false;
1417}
1418
1419static int wsa_macro_enable_main_path(struct snd_soc_dapm_widget *w,
1420 struct snd_kcontrol *kcontrol,
1421 int event)
1422{
1423 struct snd_soc_component *component =
1424 snd_soc_dapm_to_component(w->dapm);
1425 u16 reg = 0;
Laxminath Kasam069df142019-09-17 23:43:34 +05301426 struct device *wsa_dev = NULL;
1427 struct wsa_macro_priv *wsa_priv = NULL;
1428
1429 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
1430 return -EINVAL;
1431
Laxminath Kasam52ae6582019-08-08 18:00:35 +05301432
1433 reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL +
1434 WSA_MACRO_RX_PATH_OFFSET * w->shift;
1435 switch (event) {
1436 case SND_SOC_DAPM_PRE_PMU:
Laxminath Kasam069df142019-09-17 23:43:34 +05301437 if (wsa_macro_adie_lb(component, w->shift)) {
Laxminath Kasam52ae6582019-08-08 18:00:35 +05301438 snd_soc_component_update_bits(component,
1439 reg, 0x20, 0x20);
Laxminath Kasam069df142019-09-17 23:43:34 +05301440 bolero_wsa_pa_on(wsa_dev);
1441 }
Laxminath Kasam52ae6582019-08-08 18:00:35 +05301442 break;
1443 default:
1444 break;
1445 }
1446 return 0;
1447}
1448
Laxminath Kasam243e2752018-04-12 00:40:19 +05301449static int wsa_macro_interp_get_primary_reg(u16 reg, u16 *ind)
1450{
1451 u16 prim_int_reg = 0;
1452
1453 switch (reg) {
1454 case BOLERO_CDC_WSA_RX0_RX_PATH_CTL:
1455 case BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL:
1456 prim_int_reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL;
1457 *ind = 0;
1458 break;
1459 case BOLERO_CDC_WSA_RX1_RX_PATH_CTL:
1460 case BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL:
1461 prim_int_reg = BOLERO_CDC_WSA_RX1_RX_PATH_CTL;
1462 *ind = 1;
1463 break;
1464 }
1465
1466 return prim_int_reg;
1467}
1468
1469static int wsa_macro_enable_prim_interpolator(
Meng Wang15c825d2018-09-06 10:49:18 +08001470 struct snd_soc_component *component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301471 u16 reg, int event)
1472{
1473 u16 prim_int_reg;
1474 u16 ind = 0;
1475 struct device *wsa_dev = NULL;
1476 struct wsa_macro_priv *wsa_priv = NULL;
1477
Meng Wang15c825d2018-09-06 10:49:18 +08001478 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301479 return -EINVAL;
1480
1481 prim_int_reg = wsa_macro_interp_get_primary_reg(reg, &ind);
1482
1483 switch (event) {
1484 case SND_SOC_DAPM_PRE_PMU:
1485 wsa_priv->prim_int_users[ind]++;
1486 if (wsa_priv->prim_int_users[ind] == 1) {
Meng Wang15c825d2018-09-06 10:49:18 +08001487 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301488 prim_int_reg + WSA_MACRO_RX_PATH_CFG3_OFFSET,
1489 0x03, 0x03);
Meng Wang15c825d2018-09-06 10:49:18 +08001490 snd_soc_component_update_bits(component, prim_int_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301491 0x10, 0x10);
Meng Wang15c825d2018-09-06 10:49:18 +08001492 wsa_macro_hd2_control(component, prim_int_reg, event);
1493 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301494 prim_int_reg + WSA_MACRO_RX_PATH_DSMDEM_OFFSET,
1495 0x1, 0x1);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301496 }
1497 if ((reg != prim_int_reg) &&
Meng Wang15c825d2018-09-06 10:49:18 +08001498 ((snd_soc_component_read32(
1499 component, prim_int_reg)) & 0x10))
1500 snd_soc_component_update_bits(component, reg,
1501 0x10, 0x10);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301502 break;
1503 case SND_SOC_DAPM_POST_PMD:
1504 wsa_priv->prim_int_users[ind]--;
1505 if (wsa_priv->prim_int_users[ind] == 0) {
Meng Wang15c825d2018-09-06 10:49:18 +08001506 snd_soc_component_update_bits(component, prim_int_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301507 1 << 0x5, 0 << 0x5);
Laxminath Kasam52ae6582019-08-08 18:00:35 +05301508 snd_soc_component_update_bits(component,
1509 prim_int_reg + WSA_MACRO_RX_PATH_DSMDEM_OFFSET,
1510 0x1, 0x0);
Meng Wang15c825d2018-09-06 10:49:18 +08001511 snd_soc_component_update_bits(component, prim_int_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301512 0x40, 0x40);
Meng Wang15c825d2018-09-06 10:49:18 +08001513 snd_soc_component_update_bits(component, prim_int_reg,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301514 0x40, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001515 wsa_macro_hd2_control(component, prim_int_reg, event);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301516 }
1517 break;
1518 }
1519
Meng Wang15c825d2018-09-06 10:49:18 +08001520 dev_dbg(component->dev, "%s: primary interpolator: INT%d, users: %d\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301521 __func__, ind, wsa_priv->prim_int_users[ind]);
1522 return 0;
1523}
1524
1525static int wsa_macro_enable_interpolator(struct snd_soc_dapm_widget *w,
1526 struct snd_kcontrol *kcontrol,
1527 int event)
1528{
Meng Wang15c825d2018-09-06 10:49:18 +08001529 struct snd_soc_component *component =
1530 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301531 u16 gain_reg;
1532 u16 reg;
1533 int val;
1534 int offset_val = 0;
1535 struct device *wsa_dev = NULL;
1536 struct wsa_macro_priv *wsa_priv = NULL;
1537
Meng Wang15c825d2018-09-06 10:49:18 +08001538 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05301539 return -EINVAL;
1540
Meng Wang15c825d2018-09-06 10:49:18 +08001541 dev_dbg(component->dev, "%s %d %s\n", __func__, event, w->name);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301542
1543 if (!(strcmp(w->name, "WSA_RX INT0 INTERP"))) {
1544 reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL;
1545 gain_reg = BOLERO_CDC_WSA_RX0_RX_VOL_CTL;
1546 } else if (!(strcmp(w->name, "WSA_RX INT1 INTERP"))) {
1547 reg = BOLERO_CDC_WSA_RX1_RX_PATH_CTL;
1548 gain_reg = BOLERO_CDC_WSA_RX1_RX_VOL_CTL;
1549 } else {
Meng Wang15c825d2018-09-06 10:49:18 +08001550 dev_err(component->dev, "%s: Interpolator reg not found\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301551 __func__);
1552 return -EINVAL;
1553 }
1554
1555 switch (event) {
1556 case SND_SOC_DAPM_PRE_PMU:
1557 /* Reset if needed */
Meng Wang15c825d2018-09-06 10:49:18 +08001558 wsa_macro_enable_prim_interpolator(component, reg, event);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301559 break;
1560 case SND_SOC_DAPM_POST_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08001561 wsa_macro_config_compander(component, w->shift, event);
1562 wsa_macro_config_softclip(component, w->shift, event);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301563 /* apply gain after int clk is enabled */
Laxminath Kasam21c8b222018-06-21 18:47:22 +05301564 if ((wsa_priv->spkr_gain_offset ==
1565 WSA_MACRO_GAIN_OFFSET_M1P5_DB) &&
Laxminath Kasam243e2752018-04-12 00:40:19 +05301566 (wsa_priv->comp_enabled[WSA_MACRO_COMP1] ||
1567 wsa_priv->comp_enabled[WSA_MACRO_COMP2]) &&
1568 (gain_reg == BOLERO_CDC_WSA_RX0_RX_VOL_CTL ||
1569 gain_reg == BOLERO_CDC_WSA_RX1_RX_VOL_CTL)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001570 snd_soc_component_update_bits(component,
1571 BOLERO_CDC_WSA_RX0_RX_PATH_SEC1,
1572 0x01, 0x01);
1573 snd_soc_component_update_bits(component,
1574 BOLERO_CDC_WSA_RX0_RX_PATH_MIX_SEC0,
1575 0x01, 0x01);
1576 snd_soc_component_update_bits(component,
1577 BOLERO_CDC_WSA_RX1_RX_PATH_SEC1,
1578 0x01, 0x01);
1579 snd_soc_component_update_bits(component,
1580 BOLERO_CDC_WSA_RX1_RX_PATH_MIX_SEC0,
1581 0x01, 0x01);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301582 offset_val = -2;
1583 }
Meng Wang15c825d2018-09-06 10:49:18 +08001584 val = snd_soc_component_read32(component, gain_reg);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301585 val += offset_val;
Meng Wang15c825d2018-09-06 10:49:18 +08001586 snd_soc_component_write(component, gain_reg, val);
1587 wsa_macro_config_ear_spkr_gain(component, wsa_priv,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301588 event, gain_reg);
1589 break;
1590 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +08001591 wsa_macro_config_compander(component, w->shift, event);
1592 wsa_macro_config_softclip(component, w->shift, event);
1593 wsa_macro_enable_prim_interpolator(component, reg, event);
Laxminath Kasam21c8b222018-06-21 18:47:22 +05301594 if ((wsa_priv->spkr_gain_offset ==
1595 WSA_MACRO_GAIN_OFFSET_M1P5_DB) &&
Laxminath Kasam243e2752018-04-12 00:40:19 +05301596 (wsa_priv->comp_enabled[WSA_MACRO_COMP1] ||
1597 wsa_priv->comp_enabled[WSA_MACRO_COMP2]) &&
1598 (gain_reg == BOLERO_CDC_WSA_RX0_RX_VOL_CTL ||
1599 gain_reg == BOLERO_CDC_WSA_RX1_RX_VOL_CTL)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001600 snd_soc_component_update_bits(component,
1601 BOLERO_CDC_WSA_RX0_RX_PATH_SEC1,
1602 0x01, 0x00);
1603 snd_soc_component_update_bits(component,
1604 BOLERO_CDC_WSA_RX0_RX_PATH_MIX_SEC0,
1605 0x01, 0x00);
1606 snd_soc_component_update_bits(component,
1607 BOLERO_CDC_WSA_RX1_RX_PATH_SEC1,
1608 0x01, 0x00);
1609 snd_soc_component_update_bits(component,
1610 BOLERO_CDC_WSA_RX1_RX_PATH_MIX_SEC0,
1611 0x01, 0x00);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301612 offset_val = 2;
Meng Wang15c825d2018-09-06 10:49:18 +08001613 val = snd_soc_component_read32(component, gain_reg);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301614 val += offset_val;
Meng Wang15c825d2018-09-06 10:49:18 +08001615 snd_soc_component_write(component, gain_reg, val);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301616 }
Meng Wang15c825d2018-09-06 10:49:18 +08001617 wsa_macro_config_ear_spkr_gain(component, wsa_priv,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301618 event, gain_reg);
1619 break;
1620 }
1621
1622 return 0;
1623}
1624
Meng Wang15c825d2018-09-06 10:49:18 +08001625static int wsa_macro_config_ear_spkr_gain(struct snd_soc_component *component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05301626 struct wsa_macro_priv *wsa_priv,
1627 int event, int gain_reg)
1628{
1629 int comp_gain_offset, val;
1630
1631 switch (wsa_priv->spkr_mode) {
Laxminath Kasam21c8b222018-06-21 18:47:22 +05301632 /* Compander gain in WSA_MACRO_SPKR_MODE1 case is 12 dB */
1633 case WSA_MACRO_SPKR_MODE_1:
Laxminath Kasam243e2752018-04-12 00:40:19 +05301634 comp_gain_offset = -12;
1635 break;
1636 /* Default case compander gain is 15 dB */
1637 default:
1638 comp_gain_offset = -15;
1639 break;
1640 }
1641
1642 switch (event) {
1643 case SND_SOC_DAPM_POST_PMU:
1644 /* Apply ear spkr gain only if compander is enabled */
1645 if (wsa_priv->comp_enabled[WSA_MACRO_COMP1] &&
1646 (gain_reg == BOLERO_CDC_WSA_RX0_RX_VOL_CTL) &&
1647 (wsa_priv->ear_spkr_gain != 0)) {
1648 /* For example, val is -8(-12+5-1) for 4dB of gain */
1649 val = comp_gain_offset + wsa_priv->ear_spkr_gain - 1;
Meng Wang15c825d2018-09-06 10:49:18 +08001650 snd_soc_component_write(component, gain_reg, val);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301651
1652 dev_dbg(wsa_priv->dev, "%s: RX0 Volume %d dB\n",
1653 __func__, val);
1654 }
1655 break;
1656 case SND_SOC_DAPM_POST_PMD:
1657 /*
1658 * Reset RX0 volume to 0 dB if compander is enabled and
1659 * ear_spkr_gain is non-zero.
1660 */
1661 if (wsa_priv->comp_enabled[WSA_MACRO_COMP1] &&
1662 (gain_reg == BOLERO_CDC_WSA_RX0_RX_VOL_CTL) &&
1663 (wsa_priv->ear_spkr_gain != 0)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001664 snd_soc_component_write(component, gain_reg, 0x0);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301665
1666 dev_dbg(wsa_priv->dev, "%s: Reset RX0 Volume to 0 dB\n",
1667 __func__);
1668 }
1669 break;
1670 }
1671
1672 return 0;
1673}
1674
1675static int wsa_macro_spk_boost_event(struct snd_soc_dapm_widget *w,
1676 struct snd_kcontrol *kcontrol,
1677 int event)
1678{
Meng Wang15c825d2018-09-06 10:49:18 +08001679 struct snd_soc_component *component =
1680 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301681 u16 boost_path_ctl, boost_path_cfg1;
1682 u16 reg, reg_mix;
1683
Meng Wang15c825d2018-09-06 10:49:18 +08001684 dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301685
1686 if (!strcmp(w->name, "WSA_RX INT0 CHAIN")) {
1687 boost_path_ctl = BOLERO_CDC_WSA_BOOST0_BOOST_PATH_CTL;
1688 boost_path_cfg1 = BOLERO_CDC_WSA_RX0_RX_PATH_CFG1;
1689 reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL;
1690 reg_mix = BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL;
1691 } else if (!strcmp(w->name, "WSA_RX INT1 CHAIN")) {
1692 boost_path_ctl = BOLERO_CDC_WSA_BOOST1_BOOST_PATH_CTL;
1693 boost_path_cfg1 = BOLERO_CDC_WSA_RX1_RX_PATH_CFG1;
1694 reg = BOLERO_CDC_WSA_RX1_RX_PATH_CTL;
1695 reg_mix = BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL;
1696 } else {
Meng Wang15c825d2018-09-06 10:49:18 +08001697 dev_err(component->dev, "%s: unknown widget: %s\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05301698 __func__, w->name);
1699 return -EINVAL;
1700 }
1701
1702 switch (event) {
1703 case SND_SOC_DAPM_PRE_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08001704 snd_soc_component_update_bits(component, boost_path_cfg1,
1705 0x01, 0x01);
1706 snd_soc_component_update_bits(component, boost_path_ctl,
1707 0x10, 0x10);
1708 if ((snd_soc_component_read32(component, reg_mix)) & 0x10)
1709 snd_soc_component_update_bits(component, reg_mix,
1710 0x10, 0x00);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301711 break;
Laxminath Kasam0c857002018-07-17 23:47:17 +05301712 case SND_SOC_DAPM_POST_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08001713 snd_soc_component_update_bits(component, reg, 0x10, 0x00);
Laxminath Kasam0c857002018-07-17 23:47:17 +05301714 break;
Laxminath Kasam243e2752018-04-12 00:40:19 +05301715 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +08001716 snd_soc_component_update_bits(component, boost_path_ctl,
1717 0x10, 0x00);
1718 snd_soc_component_update_bits(component, boost_path_cfg1,
1719 0x01, 0x00);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301720 break;
1721 }
1722
1723 return 0;
1724}
1725
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301726
1727static int wsa_macro_enable_vbat(struct snd_soc_dapm_widget *w,
1728 struct snd_kcontrol *kcontrol,
1729 int event)
1730{
Meng Wang15c825d2018-09-06 10:49:18 +08001731 struct snd_soc_component *component =
1732 snd_soc_dapm_to_component(w->dapm);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301733 struct device *wsa_dev = NULL;
1734 struct wsa_macro_priv *wsa_priv = NULL;
1735 u16 vbat_path_cfg = 0;
1736 int softclip_path = 0;
1737
Meng Wang15c825d2018-09-06 10:49:18 +08001738 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301739 return -EINVAL;
1740
Meng Wang15c825d2018-09-06 10:49:18 +08001741 dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301742 if (!strcmp(w->name, "WSA_RX INT0 VBAT")) {
1743 vbat_path_cfg = BOLERO_CDC_WSA_RX0_RX_PATH_CFG1;
1744 softclip_path = WSA_MACRO_SOFTCLIP0;
1745 } else if (!strcmp(w->name, "WSA_RX INT1 VBAT")) {
1746 vbat_path_cfg = BOLERO_CDC_WSA_RX1_RX_PATH_CFG1;
1747 softclip_path = WSA_MACRO_SOFTCLIP1;
1748 }
1749
1750 switch (event) {
1751 case SND_SOC_DAPM_PRE_PMU:
1752 /* Enable clock for VBAT block */
Meng Wang15c825d2018-09-06 10:49:18 +08001753 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301754 BOLERO_CDC_WSA_VBAT_BCL_VBAT_PATH_CTL, 0x10, 0x10);
1755 /* Enable VBAT block */
Meng Wang15c825d2018-09-06 10:49:18 +08001756 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301757 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG, 0x01, 0x01);
1758 /* Update interpolator with 384K path */
Meng Wang15c825d2018-09-06 10:49:18 +08001759 snd_soc_component_update_bits(component, vbat_path_cfg,
1760 0x80, 0x80);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301761 /* Use attenuation mode */
Meng Wang15c825d2018-09-06 10:49:18 +08001762 snd_soc_component_update_bits(component,
1763 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG, 0x02, 0x00);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301764 /*
1765 * BCL block needs softclip clock and mux config to be enabled
1766 */
Meng Wang15c825d2018-09-06 10:49:18 +08001767 wsa_macro_enable_softclip_clk(component, wsa_priv,
1768 softclip_path, true);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301769 /* Enable VBAT at channel level */
Meng Wang15c825d2018-09-06 10:49:18 +08001770 snd_soc_component_update_bits(component, vbat_path_cfg,
1771 0x02, 0x02);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301772 /* Set the ATTK1 gain */
Meng Wang15c825d2018-09-06 10:49:18 +08001773 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301774 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD1,
1775 0xFF, 0xFF);
Meng Wang15c825d2018-09-06 10:49:18 +08001776 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301777 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD2,
1778 0xFF, 0x03);
Meng Wang15c825d2018-09-06 10:49:18 +08001779 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301780 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD3,
1781 0xFF, 0x00);
1782 /* Set the ATTK2 gain */
Meng Wang15c825d2018-09-06 10:49:18 +08001783 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301784 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD4,
1785 0xFF, 0xFF);
Meng Wang15c825d2018-09-06 10:49:18 +08001786 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301787 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD5,
1788 0xFF, 0x03);
Meng Wang15c825d2018-09-06 10:49:18 +08001789 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301790 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD6,
1791 0xFF, 0x00);
1792 /* Set the ATTK3 gain */
Meng Wang15c825d2018-09-06 10:49:18 +08001793 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301794 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD7,
1795 0xFF, 0xFF);
Meng Wang15c825d2018-09-06 10:49:18 +08001796 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301797 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD8,
1798 0xFF, 0x03);
Meng Wang15c825d2018-09-06 10:49:18 +08001799 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301800 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD9,
1801 0xFF, 0x00);
1802 break;
1803
1804 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +08001805 snd_soc_component_update_bits(component, vbat_path_cfg,
1806 0x80, 0x00);
1807 snd_soc_component_update_bits(component,
1808 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG,
1809 0x02, 0x02);
1810 snd_soc_component_update_bits(component, vbat_path_cfg,
1811 0x02, 0x00);
1812 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301813 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD1,
1814 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001815 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301816 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD2,
1817 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001818 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301819 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD3,
1820 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001821 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301822 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD4,
1823 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001824 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301825 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD5,
1826 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001827 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301828 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD6,
1829 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001830 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301831 BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD7,
1832 0xFF, 0x00);
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_UPD8,
1835 0xFF, 0x00);
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_UPD9,
1838 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001839 wsa_macro_enable_softclip_clk(component, wsa_priv,
1840 softclip_path, false);
1841 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301842 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG, 0x01, 0x00);
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_PATH_CTL, 0x10, 0x00);
1845 break;
1846 default:
1847 dev_err(wsa_dev, "%s: Invalid event %d\n", __func__, event);
1848 break;
1849 }
1850 return 0;
1851}
1852
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301853static int wsa_macro_enable_echo(struct snd_soc_dapm_widget *w,
1854 struct snd_kcontrol *kcontrol,
1855 int event)
1856{
Meng Wang15c825d2018-09-06 10:49:18 +08001857 struct snd_soc_component *component =
1858 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301859 struct device *wsa_dev = NULL;
1860 struct wsa_macro_priv *wsa_priv = NULL;
1861 u16 val, ec_tx = 0, ec_hq_reg;
1862
Meng Wang15c825d2018-09-06 10:49:18 +08001863 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301864 return -EINVAL;
1865
1866 dev_dbg(wsa_dev, "%s %d %s\n", __func__, event, w->name);
1867
Meng Wang15c825d2018-09-06 10:49:18 +08001868 val = snd_soc_component_read32(component,
1869 BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301870 if (!(strcmp(w->name, "WSA RX_MIX EC0_MUX")))
1871 ec_tx = (val & 0x07) - 1;
1872 else
1873 ec_tx = ((val & 0x38) >> 0x3) - 1;
1874
1875 if (ec_tx < 0 || ec_tx >= (WSA_MACRO_RX1 + 1)) {
1876 dev_err(wsa_dev, "%s: EC mix control not set correctly\n",
1877 __func__);
1878 return -EINVAL;
1879 }
1880 if (wsa_priv->ec_hq[ec_tx]) {
Meng Wang15c825d2018-09-06 10:49:18 +08001881 snd_soc_component_update_bits(component,
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301882 BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0,
1883 0x1 << ec_tx, 0x1 << ec_tx);
1884 ec_hq_reg = BOLERO_CDC_WSA_EC_HQ0_EC_REF_HQ_PATH_CTL +
Laxminath Kasam5d9ea8d2018-11-28 14:32:40 +05301885 0x40 * ec_tx;
Meng Wang15c825d2018-09-06 10:49:18 +08001886 snd_soc_component_update_bits(component, ec_hq_reg, 0x01, 0x01);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301887 ec_hq_reg = BOLERO_CDC_WSA_EC_HQ0_EC_REF_HQ_CFG0 +
Laxminath Kasam5d9ea8d2018-11-28 14:32:40 +05301888 0x40 * ec_tx;
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301889 /* default set to 48k */
Meng Wang15c825d2018-09-06 10:49:18 +08001890 snd_soc_component_update_bits(component, ec_hq_reg, 0x1E, 0x08);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301891 }
1892
1893 return 0;
1894}
1895
1896static int wsa_macro_get_ec_hq(struct snd_kcontrol *kcontrol,
1897 struct snd_ctl_elem_value *ucontrol)
1898{
1899
Meng Wang15c825d2018-09-06 10:49:18 +08001900 struct snd_soc_component *component =
1901 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301902 int ec_tx = ((struct soc_multi_mixer_control *)
1903 kcontrol->private_value)->shift;
1904 struct device *wsa_dev = NULL;
1905 struct wsa_macro_priv *wsa_priv = NULL;
1906
Meng Wang15c825d2018-09-06 10:49:18 +08001907 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301908 return -EINVAL;
1909
1910 ucontrol->value.integer.value[0] = wsa_priv->ec_hq[ec_tx];
1911 return 0;
1912}
1913
1914static int wsa_macro_set_ec_hq(struct snd_kcontrol *kcontrol,
1915 struct snd_ctl_elem_value *ucontrol)
1916{
Meng Wang15c825d2018-09-06 10:49:18 +08001917 struct snd_soc_component *component =
1918 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301919 int ec_tx = ((struct soc_multi_mixer_control *)
1920 kcontrol->private_value)->shift;
1921 int value = ucontrol->value.integer.value[0];
1922 struct device *wsa_dev = NULL;
1923 struct wsa_macro_priv *wsa_priv = NULL;
1924
Meng Wang15c825d2018-09-06 10:49:18 +08001925 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301926 return -EINVAL;
1927
1928 dev_dbg(wsa_dev, "%s: enable current %d, new %d\n",
1929 __func__, wsa_priv->ec_hq[ec_tx], value);
1930 wsa_priv->ec_hq[ec_tx] = value;
1931
1932 return 0;
1933}
1934
Vatsal Buchaf2a71b62019-03-26 16:14:40 +05301935static int wsa_macro_get_rx_mute_status(struct snd_kcontrol *kcontrol,
1936 struct snd_ctl_elem_value *ucontrol)
1937{
1938
1939 struct snd_soc_component *component =
1940 snd_soc_kcontrol_component(kcontrol);
1941 struct device *wsa_dev = NULL;
1942 struct wsa_macro_priv *wsa_priv = NULL;
1943 int wsa_rx_shift = ((struct soc_multi_mixer_control *)
1944 kcontrol->private_value)->shift;
1945
1946 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
1947 return -EINVAL;
1948
1949 ucontrol->value.integer.value[0] =
1950 wsa_priv->wsa_digital_mute_status[wsa_rx_shift];
1951 return 0;
1952}
1953
1954static int wsa_macro_set_rx_mute_status(struct snd_kcontrol *kcontrol,
1955 struct snd_ctl_elem_value *ucontrol)
1956{
1957 struct snd_soc_component *component =
1958 snd_soc_kcontrol_component(kcontrol);
1959 struct device *wsa_dev = NULL;
1960 struct wsa_macro_priv *wsa_priv = NULL;
1961 int value = ucontrol->value.integer.value[0];
1962 int wsa_rx_shift = ((struct soc_multi_mixer_control *)
1963 kcontrol->private_value)->shift;
1964
1965 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
1966 return -EINVAL;
1967
1968 switch (wsa_rx_shift) {
1969 case 0:
1970 snd_soc_component_update_bits(component,
1971 BOLERO_CDC_WSA_RX0_RX_PATH_CTL,
1972 0x10, value << 4);
1973 break;
1974 case 1:
1975 snd_soc_component_update_bits(component,
1976 BOLERO_CDC_WSA_RX1_RX_PATH_CTL,
1977 0x10, value << 4);
1978 break;
1979 case 2:
1980 snd_soc_component_update_bits(component,
1981 BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL,
1982 0x10, value << 4);
1983 break;
1984 case 3:
1985 snd_soc_component_update_bits(component,
1986 BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL,
1987 0x10, value << 4);
1988 break;
1989 default:
1990 pr_err("%s: invalid argument rx_shift = %d\n", __func__,
1991 wsa_rx_shift);
1992 return -EINVAL;
1993 }
1994
1995 dev_dbg(component->dev, "%s: WSA Digital Mute RX %d Enable %d\n",
1996 __func__, wsa_rx_shift, value);
1997 wsa_priv->wsa_digital_mute_status[wsa_rx_shift] = value;
1998 return 0;
1999}
2000
Laxminath Kasam243e2752018-04-12 00:40:19 +05302001static int wsa_macro_get_compander(struct snd_kcontrol *kcontrol,
2002 struct snd_ctl_elem_value *ucontrol)
2003{
2004
Meng Wang15c825d2018-09-06 10:49:18 +08002005 struct snd_soc_component *component =
2006 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302007 int comp = ((struct soc_multi_mixer_control *)
2008 kcontrol->private_value)->shift;
2009 struct device *wsa_dev = NULL;
2010 struct wsa_macro_priv *wsa_priv = NULL;
2011
Meng Wang15c825d2018-09-06 10:49:18 +08002012 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302013 return -EINVAL;
2014
2015 ucontrol->value.integer.value[0] = wsa_priv->comp_enabled[comp];
2016 return 0;
2017}
2018
2019static int wsa_macro_set_compander(struct snd_kcontrol *kcontrol,
2020 struct snd_ctl_elem_value *ucontrol)
2021{
Meng Wang15c825d2018-09-06 10:49:18 +08002022 struct snd_soc_component *component =
2023 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302024 int comp = ((struct soc_multi_mixer_control *)
2025 kcontrol->private_value)->shift;
2026 int value = ucontrol->value.integer.value[0];
2027 struct device *wsa_dev = NULL;
2028 struct wsa_macro_priv *wsa_priv = NULL;
2029
Meng Wang15c825d2018-09-06 10:49:18 +08002030 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302031 return -EINVAL;
2032
Meng Wang15c825d2018-09-06 10:49:18 +08002033 dev_dbg(component->dev, "%s: Compander %d enable current %d, new %d\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05302034 __func__, comp + 1, wsa_priv->comp_enabled[comp], value);
2035 wsa_priv->comp_enabled[comp] = value;
2036
2037 return 0;
2038}
2039
2040static int wsa_macro_ear_spkr_pa_gain_get(struct snd_kcontrol *kcontrol,
2041 struct snd_ctl_elem_value *ucontrol)
2042{
Meng Wang15c825d2018-09-06 10:49:18 +08002043 struct snd_soc_component *component =
2044 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302045 struct device *wsa_dev = NULL;
2046 struct wsa_macro_priv *wsa_priv = NULL;
2047
Meng Wang15c825d2018-09-06 10:49:18 +08002048 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302049 return -EINVAL;
2050
2051 ucontrol->value.integer.value[0] = wsa_priv->ear_spkr_gain;
2052
Meng Wang15c825d2018-09-06 10:49:18 +08002053 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05302054 __func__, ucontrol->value.integer.value[0]);
2055
2056 return 0;
2057}
2058
2059static int wsa_macro_ear_spkr_pa_gain_put(struct snd_kcontrol *kcontrol,
2060 struct snd_ctl_elem_value *ucontrol)
2061{
Meng Wang15c825d2018-09-06 10:49:18 +08002062 struct snd_soc_component *component =
2063 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302064 struct device *wsa_dev = NULL;
2065 struct wsa_macro_priv *wsa_priv = NULL;
2066
Meng Wang15c825d2018-09-06 10:49:18 +08002067 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302068 return -EINVAL;
2069
2070 wsa_priv->ear_spkr_gain = ucontrol->value.integer.value[0];
2071
Meng Wang15c825d2018-09-06 10:49:18 +08002072 dev_dbg(component->dev, "%s: gain = %d\n", __func__,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302073 wsa_priv->ear_spkr_gain);
2074
2075 return 0;
2076}
2077
2078static int wsa_macro_spkr_left_boost_stage_get(struct snd_kcontrol *kcontrol,
2079 struct snd_ctl_elem_value *ucontrol)
2080{
2081 u8 bst_state_max = 0;
Meng Wang15c825d2018-09-06 10:49:18 +08002082 struct snd_soc_component *component =
2083 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302084
Meng Wang15c825d2018-09-06 10:49:18 +08002085 bst_state_max = snd_soc_component_read32(component,
2086 BOLERO_CDC_WSA_BOOST0_BOOST_CTL);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302087 bst_state_max = (bst_state_max & 0x0c) >> 2;
2088 ucontrol->value.integer.value[0] = bst_state_max;
Meng Wang15c825d2018-09-06 10:49:18 +08002089 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05302090 __func__, ucontrol->value.integer.value[0]);
2091
2092 return 0;
2093}
2094
2095static int wsa_macro_spkr_left_boost_stage_put(struct snd_kcontrol *kcontrol,
2096 struct snd_ctl_elem_value *ucontrol)
2097{
2098 u8 bst_state_max;
Meng Wang15c825d2018-09-06 10:49:18 +08002099 struct snd_soc_component *component =
2100 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302101
Meng Wang15c825d2018-09-06 10:49:18 +08002102 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05302103 __func__, ucontrol->value.integer.value[0]);
2104 bst_state_max = ucontrol->value.integer.value[0] << 2;
Karthikeyan Mani10de3932019-04-15 11:46:57 -07002105 /* bolero does not need to limit the boost levels */
Laxminath Kasam243e2752018-04-12 00:40:19 +05302106
2107 return 0;
2108}
2109
2110static int wsa_macro_spkr_right_boost_stage_get(struct snd_kcontrol *kcontrol,
2111 struct snd_ctl_elem_value *ucontrol)
2112{
2113 u8 bst_state_max = 0;
Meng Wang15c825d2018-09-06 10:49:18 +08002114 struct snd_soc_component *component =
2115 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302116
Meng Wang15c825d2018-09-06 10:49:18 +08002117 bst_state_max = snd_soc_component_read32(component,
2118 BOLERO_CDC_WSA_BOOST1_BOOST_CTL);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302119 bst_state_max = (bst_state_max & 0x0c) >> 2;
2120 ucontrol->value.integer.value[0] = bst_state_max;
Meng Wang15c825d2018-09-06 10:49:18 +08002121 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05302122 __func__, ucontrol->value.integer.value[0]);
2123
2124 return 0;
2125}
2126
2127static int wsa_macro_spkr_right_boost_stage_put(struct snd_kcontrol *kcontrol,
2128 struct snd_ctl_elem_value *ucontrol)
2129{
2130 u8 bst_state_max;
Meng Wang15c825d2018-09-06 10:49:18 +08002131 struct snd_soc_component *component =
2132 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302133
Meng Wang15c825d2018-09-06 10:49:18 +08002134 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Laxminath Kasam243e2752018-04-12 00:40:19 +05302135 __func__, ucontrol->value.integer.value[0]);
2136 bst_state_max = ucontrol->value.integer.value[0] << 2;
Karthikeyan Mani10de3932019-04-15 11:46:57 -07002137 /* bolero does not need to limit the boost levels */
Laxminath Kasam243e2752018-04-12 00:40:19 +05302138
2139 return 0;
2140}
2141
2142static int wsa_macro_rx_mux_get(struct snd_kcontrol *kcontrol,
2143 struct snd_ctl_elem_value *ucontrol)
2144{
2145 struct snd_soc_dapm_widget *widget =
2146 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +08002147 struct snd_soc_component *component =
2148 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302149 struct device *wsa_dev = NULL;
2150 struct wsa_macro_priv *wsa_priv = NULL;
2151
Meng Wang15c825d2018-09-06 10:49:18 +08002152 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302153 return -EINVAL;
2154
2155 ucontrol->value.integer.value[0] =
2156 wsa_priv->rx_port_value[widget->shift];
2157 return 0;
2158}
2159
2160static int wsa_macro_rx_mux_put(struct snd_kcontrol *kcontrol,
2161 struct snd_ctl_elem_value *ucontrol)
2162{
2163 struct snd_soc_dapm_widget *widget =
2164 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +08002165 struct snd_soc_component *component =
2166 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302167 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
2168 struct snd_soc_dapm_update *update = NULL;
2169 u32 rx_port_value = ucontrol->value.integer.value[0];
2170 u32 bit_input = 0;
2171 u32 aif_rst;
2172 struct device *wsa_dev = NULL;
2173 struct wsa_macro_priv *wsa_priv = NULL;
2174
Meng Wang15c825d2018-09-06 10:49:18 +08002175 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302176 return -EINVAL;
2177
2178 aif_rst = wsa_priv->rx_port_value[widget->shift];
2179 if (!rx_port_value) {
2180 if (aif_rst == 0) {
2181 dev_err(wsa_dev, "%s: AIF reset already\n", __func__);
2182 return 0;
2183 }
Sudheer Papothic0f75b72019-07-16 06:04:10 +05302184 if (aif_rst >= WSA_MACRO_RX_MAX) {
2185 dev_err(wsa_dev, "%s: Invalid AIF reset\n", __func__);
2186 return 0;
2187 }
Laxminath Kasam243e2752018-04-12 00:40:19 +05302188 }
2189 wsa_priv->rx_port_value[widget->shift] = rx_port_value;
2190
2191 bit_input = widget->shift;
2192 if (widget->shift >= WSA_MACRO_RX_MIX)
2193 bit_input %= WSA_MACRO_RX_MIX;
2194
Sudheer Papothic0f75b72019-07-16 06:04:10 +05302195 dev_dbg(wsa_dev,
2196 "%s: mux input: %d, mux output: %d, bit: %d\n",
2197 __func__, rx_port_value, widget->shift, bit_input);
2198
Laxminath Kasam243e2752018-04-12 00:40:19 +05302199 switch (rx_port_value) {
2200 case 0:
Sudheer Papothic0f75b72019-07-16 06:04:10 +05302201 if (wsa_priv->active_ch_cnt[aif_rst]) {
2202 clear_bit(bit_input,
2203 &wsa_priv->active_ch_mask[aif_rst]);
2204 wsa_priv->active_ch_cnt[aif_rst]--;
2205 }
Laxminath Kasam243e2752018-04-12 00:40:19 +05302206 break;
2207 case 1:
2208 case 2:
2209 set_bit(bit_input,
Laxminath Kasam59c7a1d2018-08-09 16:11:17 +05302210 &wsa_priv->active_ch_mask[rx_port_value]);
2211 wsa_priv->active_ch_cnt[rx_port_value]++;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302212 break;
2213 default:
2214 dev_err(wsa_dev,
Sudheer Papothic0f75b72019-07-16 06:04:10 +05302215 "%s: Invalid AIF_ID for WSA RX MUX %d\n",
2216 __func__, rx_port_value);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302217 return -EINVAL;
2218 }
2219
2220 snd_soc_dapm_mux_update_power(widget->dapm, kcontrol,
2221 rx_port_value, e, update);
2222 return 0;
2223}
2224
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302225static int wsa_macro_vbat_bcl_gsm_mode_func_get(struct snd_kcontrol *kcontrol,
2226 struct snd_ctl_elem_value *ucontrol)
2227{
Meng Wang15c825d2018-09-06 10:49:18 +08002228 struct snd_soc_component *component =
2229 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302230
2231 ucontrol->value.integer.value[0] =
Meng Wang15c825d2018-09-06 10:49:18 +08002232 ((snd_soc_component_read32(
2233 component, BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG) & 0x04) ?
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302234 1 : 0);
2235
Meng Wang15c825d2018-09-06 10:49:18 +08002236 dev_dbg(component->dev, "%s: value: %lu\n", __func__,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302237 ucontrol->value.integer.value[0]);
2238
2239 return 0;
2240}
2241
2242static int wsa_macro_vbat_bcl_gsm_mode_func_put(struct snd_kcontrol *kcontrol,
2243 struct snd_ctl_elem_value *ucontrol)
2244{
Meng Wang15c825d2018-09-06 10:49:18 +08002245 struct snd_soc_component *component =
2246 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302247
Meng Wang15c825d2018-09-06 10:49:18 +08002248 dev_dbg(component->dev, "%s: value: %lu\n", __func__,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302249 ucontrol->value.integer.value[0]);
2250
2251 /* Set Vbat register configuration for GSM mode bit based on value */
2252 if (ucontrol->value.integer.value[0])
Meng Wang15c825d2018-09-06 10:49:18 +08002253 snd_soc_component_update_bits(component,
2254 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG,
2255 0x04, 0x04);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302256 else
Meng Wang15c825d2018-09-06 10:49:18 +08002257 snd_soc_component_update_bits(component,
2258 BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG,
2259 0x04, 0x00);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302260
2261 return 0;
2262}
2263
2264static int wsa_macro_soft_clip_enable_get(struct snd_kcontrol *kcontrol,
2265 struct snd_ctl_elem_value *ucontrol)
2266{
Meng Wang15c825d2018-09-06 10:49:18 +08002267 struct snd_soc_component *component =
2268 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302269 struct device *wsa_dev = NULL;
2270 struct wsa_macro_priv *wsa_priv = NULL;
2271 int path = ((struct soc_multi_mixer_control *)
2272 kcontrol->private_value)->shift;
2273
Meng Wang15c825d2018-09-06 10:49:18 +08002274 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302275 return -EINVAL;
2276
2277 ucontrol->value.integer.value[0] = wsa_priv->is_softclip_on[path];
2278
Meng Wang15c825d2018-09-06 10:49:18 +08002279 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302280 __func__, ucontrol->value.integer.value[0]);
2281
2282 return 0;
2283}
2284
2285static int wsa_macro_soft_clip_enable_put(struct snd_kcontrol *kcontrol,
2286 struct snd_ctl_elem_value *ucontrol)
2287{
Meng Wang15c825d2018-09-06 10:49:18 +08002288 struct snd_soc_component *component =
2289 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302290 struct device *wsa_dev = NULL;
2291 struct wsa_macro_priv *wsa_priv = NULL;
2292 int path = ((struct soc_multi_mixer_control *)
2293 kcontrol->private_value)->shift;
2294
Meng Wang15c825d2018-09-06 10:49:18 +08002295 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302296 return -EINVAL;
2297
2298 wsa_priv->is_softclip_on[path] = ucontrol->value.integer.value[0];
2299
Meng Wang15c825d2018-09-06 10:49:18 +08002300 dev_dbg(component->dev, "%s: soft clip enable for %d: %d\n", __func__,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302301 path, wsa_priv->is_softclip_on[path]);
2302
2303 return 0;
2304}
2305
Laxminath Kasam243e2752018-04-12 00:40:19 +05302306static const struct snd_kcontrol_new wsa_macro_snd_controls[] = {
2307 SOC_ENUM_EXT("EAR SPKR PA Gain", wsa_macro_ear_spkr_pa_gain_enum,
2308 wsa_macro_ear_spkr_pa_gain_get,
2309 wsa_macro_ear_spkr_pa_gain_put),
2310 SOC_ENUM_EXT("SPKR Left Boost Max State",
2311 wsa_macro_spkr_boost_stage_enum,
2312 wsa_macro_spkr_left_boost_stage_get,
2313 wsa_macro_spkr_left_boost_stage_put),
2314 SOC_ENUM_EXT("SPKR Right Boost Max State",
2315 wsa_macro_spkr_boost_stage_enum,
2316 wsa_macro_spkr_right_boost_stage_get,
2317 wsa_macro_spkr_right_boost_stage_put),
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302318 SOC_ENUM_EXT("GSM mode Enable", wsa_macro_vbat_bcl_gsm_mode_enum,
2319 wsa_macro_vbat_bcl_gsm_mode_func_get,
2320 wsa_macro_vbat_bcl_gsm_mode_func_put),
2321 SOC_SINGLE_EXT("WSA_Softclip0 Enable", SND_SOC_NOPM,
2322 WSA_MACRO_SOFTCLIP0, 1, 0,
2323 wsa_macro_soft_clip_enable_get,
2324 wsa_macro_soft_clip_enable_put),
2325 SOC_SINGLE_EXT("WSA_Softclip1 Enable", SND_SOC_NOPM,
2326 WSA_MACRO_SOFTCLIP1, 1, 0,
2327 wsa_macro_soft_clip_enable_get,
2328 wsa_macro_soft_clip_enable_put),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302329 SOC_SINGLE_SX_TLV("WSA_RX0 Digital Volume",
2330 BOLERO_CDC_WSA_RX0_RX_VOL_CTL,
2331 0, -84, 40, digital_gain),
2332 SOC_SINGLE_SX_TLV("WSA_RX1 Digital Volume",
2333 BOLERO_CDC_WSA_RX1_RX_VOL_CTL,
2334 0, -84, 40, digital_gain),
Vatsal Buchaf2a71b62019-03-26 16:14:40 +05302335 SOC_SINGLE_EXT("WSA_RX0 Digital Mute", SND_SOC_NOPM, WSA_MACRO_RX0, 1,
2336 0, wsa_macro_get_rx_mute_status,
2337 wsa_macro_set_rx_mute_status),
2338 SOC_SINGLE_EXT("WSA_RX1 Digital Mute", SND_SOC_NOPM, WSA_MACRO_RX1, 1,
2339 0, wsa_macro_get_rx_mute_status,
2340 wsa_macro_set_rx_mute_status),
2341 SOC_SINGLE_EXT("WSA_RX0_MIX Digital Mute", SND_SOC_NOPM,
2342 WSA_MACRO_RX_MIX0, 1, 0, wsa_macro_get_rx_mute_status,
2343 wsa_macro_set_rx_mute_status),
2344 SOC_SINGLE_EXT("WSA_RX1_MIX Digital Mute", SND_SOC_NOPM,
2345 WSA_MACRO_RX_MIX1, 1, 0, wsa_macro_get_rx_mute_status,
2346 wsa_macro_set_rx_mute_status),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302347 SOC_SINGLE_EXT("WSA_COMP1 Switch", SND_SOC_NOPM, WSA_MACRO_COMP1, 1, 0,
2348 wsa_macro_get_compander, wsa_macro_set_compander),
2349 SOC_SINGLE_EXT("WSA_COMP2 Switch", SND_SOC_NOPM, WSA_MACRO_COMP2, 1, 0,
2350 wsa_macro_get_compander, wsa_macro_set_compander),
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05302351 SOC_SINGLE_EXT("WSA_RX0 EC_HQ Switch", SND_SOC_NOPM, WSA_MACRO_RX0,
2352 1, 0, wsa_macro_get_ec_hq, wsa_macro_set_ec_hq),
2353 SOC_SINGLE_EXT("WSA_RX1 EC_HQ Switch", SND_SOC_NOPM, WSA_MACRO_RX1,
2354 1, 0, wsa_macro_get_ec_hq, wsa_macro_set_ec_hq),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302355};
2356
2357static const struct soc_enum rx_mux_enum =
2358 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_mux_text), rx_mux_text);
2359
2360static const struct snd_kcontrol_new rx_mux[WSA_MACRO_RX_MAX] = {
2361 SOC_DAPM_ENUM_EXT("WSA RX0 Mux", rx_mux_enum,
2362 wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),
2363 SOC_DAPM_ENUM_EXT("WSA RX1 Mux", rx_mux_enum,
2364 wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),
2365 SOC_DAPM_ENUM_EXT("WSA RX_MIX0 Mux", rx_mux_enum,
2366 wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),
2367 SOC_DAPM_ENUM_EXT("WSA RX_MIX1 Mux", rx_mux_enum,
2368 wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),
2369};
2370
2371static int wsa_macro_vi_feed_mixer_get(struct snd_kcontrol *kcontrol,
2372 struct snd_ctl_elem_value *ucontrol)
2373{
2374 struct snd_soc_dapm_widget *widget =
2375 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +08002376 struct snd_soc_component *component =
2377 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302378 struct soc_multi_mixer_control *mixer =
2379 ((struct soc_multi_mixer_control *)kcontrol->private_value);
2380 u32 dai_id = widget->shift;
2381 u32 spk_tx_id = mixer->shift;
2382 struct device *wsa_dev = NULL;
2383 struct wsa_macro_priv *wsa_priv = NULL;
2384
Meng Wang15c825d2018-09-06 10:49:18 +08002385 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302386 return -EINVAL;
2387
2388 if (test_bit(spk_tx_id, &wsa_priv->active_ch_mask[dai_id]))
2389 ucontrol->value.integer.value[0] = 1;
2390 else
2391 ucontrol->value.integer.value[0] = 0;
2392
2393 return 0;
2394}
2395
2396static int wsa_macro_vi_feed_mixer_put(struct snd_kcontrol *kcontrol,
2397 struct snd_ctl_elem_value *ucontrol)
2398{
2399 struct snd_soc_dapm_widget *widget =
2400 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +08002401 struct snd_soc_component *component =
2402 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302403 struct soc_multi_mixer_control *mixer =
2404 ((struct soc_multi_mixer_control *)kcontrol->private_value);
2405 u32 spk_tx_id = mixer->shift;
2406 u32 enable = ucontrol->value.integer.value[0];
2407 struct device *wsa_dev = NULL;
2408 struct wsa_macro_priv *wsa_priv = NULL;
2409
Meng Wang15c825d2018-09-06 10:49:18 +08002410 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302411 return -EINVAL;
2412
2413 wsa_priv->vi_feed_value = ucontrol->value.integer.value[0];
2414
2415 if (enable) {
2416 if (spk_tx_id == WSA_MACRO_TX0 &&
2417 !test_bit(WSA_MACRO_TX0,
2418 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
2419 set_bit(WSA_MACRO_TX0,
2420 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI]);
2421 wsa_priv->active_ch_cnt[WSA_MACRO_AIF_VI]++;
2422 }
2423 if (spk_tx_id == WSA_MACRO_TX1 &&
2424 !test_bit(WSA_MACRO_TX1,
2425 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
2426 set_bit(WSA_MACRO_TX1,
2427 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI]);
2428 wsa_priv->active_ch_cnt[WSA_MACRO_AIF_VI]++;
2429 }
2430 } else {
2431 if (spk_tx_id == WSA_MACRO_TX0 &&
2432 test_bit(WSA_MACRO_TX0,
2433 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
2434 clear_bit(WSA_MACRO_TX0,
2435 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI]);
2436 wsa_priv->active_ch_cnt[WSA_MACRO_AIF_VI]--;
2437 }
2438 if (spk_tx_id == WSA_MACRO_TX1 &&
2439 test_bit(WSA_MACRO_TX1,
2440 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
2441 clear_bit(WSA_MACRO_TX1,
2442 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI]);
2443 wsa_priv->active_ch_cnt[WSA_MACRO_AIF_VI]--;
2444 }
2445 }
2446 snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, NULL);
2447
2448 return 0;
2449}
2450
2451static const struct snd_kcontrol_new aif_vi_mixer[] = {
2452 SOC_SINGLE_EXT("WSA_SPKR_VI_1", SND_SOC_NOPM, WSA_MACRO_TX0, 1, 0,
2453 wsa_macro_vi_feed_mixer_get,
2454 wsa_macro_vi_feed_mixer_put),
2455 SOC_SINGLE_EXT("WSA_SPKR_VI_2", SND_SOC_NOPM, WSA_MACRO_TX1, 1, 0,
2456 wsa_macro_vi_feed_mixer_get,
2457 wsa_macro_vi_feed_mixer_put),
2458};
2459
2460static const struct snd_soc_dapm_widget wsa_macro_dapm_widgets[] = {
2461 SND_SOC_DAPM_AIF_IN("WSA AIF1 PB", "WSA_AIF1 Playback", 0,
2462 SND_SOC_NOPM, 0, 0),
2463
2464 SND_SOC_DAPM_AIF_IN("WSA AIF_MIX1 PB", "WSA_AIF_MIX1 Playback", 0,
2465 SND_SOC_NOPM, 0, 0),
2466
2467 SND_SOC_DAPM_AIF_OUT_E("WSA AIF_VI", "WSA_AIF_VI Capture", 0,
2468 SND_SOC_NOPM, WSA_MACRO_AIF_VI, 0,
2469 wsa_macro_enable_vi_feedback,
2470 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
2471
2472 SND_SOC_DAPM_AIF_OUT("WSA AIF_ECHO", "WSA_AIF_ECHO Capture", 0,
2473 SND_SOC_NOPM, 0, 0),
2474
2475 SND_SOC_DAPM_MIXER("WSA_AIF_VI Mixer", SND_SOC_NOPM, WSA_MACRO_AIF_VI,
2476 0, aif_vi_mixer, ARRAY_SIZE(aif_vi_mixer)),
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05302477 SND_SOC_DAPM_MUX_E("WSA RX_MIX EC0_MUX", SND_SOC_NOPM,
2478 WSA_MACRO_EC0_MUX, 0,
2479 &rx_mix_ec0_mux, wsa_macro_enable_echo,
2480 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2481 SND_SOC_DAPM_MUX_E("WSA RX_MIX EC1_MUX", SND_SOC_NOPM,
2482 WSA_MACRO_EC1_MUX, 0,
2483 &rx_mix_ec1_mux, wsa_macro_enable_echo,
2484 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302485
2486 SND_SOC_DAPM_MUX("WSA RX0 MUX", SND_SOC_NOPM, WSA_MACRO_RX0, 0,
2487 &rx_mux[WSA_MACRO_RX0]),
2488 SND_SOC_DAPM_MUX("WSA RX1 MUX", SND_SOC_NOPM, WSA_MACRO_RX1, 0,
2489 &rx_mux[WSA_MACRO_RX1]),
2490 SND_SOC_DAPM_MUX("WSA RX_MIX0 MUX", SND_SOC_NOPM, WSA_MACRO_RX_MIX0, 0,
2491 &rx_mux[WSA_MACRO_RX_MIX0]),
2492 SND_SOC_DAPM_MUX("WSA RX_MIX1 MUX", SND_SOC_NOPM, WSA_MACRO_RX_MIX1, 0,
2493 &rx_mux[WSA_MACRO_RX_MIX1]),
2494
2495 SND_SOC_DAPM_MIXER("WSA RX0", SND_SOC_NOPM, 0, 0, NULL, 0),
2496 SND_SOC_DAPM_MIXER("WSA RX1", SND_SOC_NOPM, 0, 0, NULL, 0),
2497 SND_SOC_DAPM_MIXER("WSA RX_MIX0", SND_SOC_NOPM, 0, 0, NULL, 0),
2498 SND_SOC_DAPM_MIXER("WSA RX_MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
2499
2500 SND_SOC_DAPM_MUX_E("WSA_RX0 INP0", SND_SOC_NOPM, 0, 0,
2501 &rx0_prim_inp0_mux, wsa_macro_enable_swr,
2502 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2503 SND_SOC_DAPM_MUX_E("WSA_RX0 INP1", SND_SOC_NOPM, 0, 0,
2504 &rx0_prim_inp1_mux, wsa_macro_enable_swr,
2505 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2506 SND_SOC_DAPM_MUX_E("WSA_RX0 INP2", SND_SOC_NOPM, 0, 0,
2507 &rx0_prim_inp2_mux, wsa_macro_enable_swr,
2508 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
Laxminath Kasam52ae6582019-08-08 18:00:35 +05302509 SND_SOC_DAPM_MUX_E("WSA_RX0 MIX INP", BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL,
2510 0, 0, &rx0_mix_mux, wsa_macro_enable_mix_path,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302511 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2512 SND_SOC_DAPM_MUX_E("WSA_RX1 INP0", SND_SOC_NOPM, 0, 0,
2513 &rx1_prim_inp0_mux, wsa_macro_enable_swr,
2514 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2515 SND_SOC_DAPM_MUX_E("WSA_RX1 INP1", SND_SOC_NOPM, 0, 0,
2516 &rx1_prim_inp1_mux, wsa_macro_enable_swr,
2517 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2518 SND_SOC_DAPM_MUX_E("WSA_RX1 INP2", SND_SOC_NOPM, 0, 0,
2519 &rx1_prim_inp2_mux, wsa_macro_enable_swr,
2520 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
Laxminath Kasam52ae6582019-08-08 18:00:35 +05302521 SND_SOC_DAPM_MUX_E("WSA_RX1 MIX INP", BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL,
2522 0, 0, &rx1_mix_mux, wsa_macro_enable_mix_path,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302523 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
Laxminath Kasam52ae6582019-08-08 18:00:35 +05302524 SND_SOC_DAPM_MIXER_E("WSA_RX INT0 MIX", SND_SOC_NOPM,
2525 0, 0, NULL, 0, wsa_macro_enable_main_path,
2526 SND_SOC_DAPM_PRE_PMU),
2527 SND_SOC_DAPM_MIXER_E("WSA_RX INT1 MIX", SND_SOC_NOPM,
2528 1, 0, NULL, 0, wsa_macro_enable_main_path,
2529 SND_SOC_DAPM_PRE_PMU),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302530 SND_SOC_DAPM_MIXER("WSA_RX INT0 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
2531 SND_SOC_DAPM_MIXER("WSA_RX INT1 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
2532
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302533 SND_SOC_DAPM_MUX_E("WSA_RX0 INT0 SIDETONE MIX",
2534 BOLERO_CDC_WSA_RX0_RX_PATH_CFG1, 4, 0,
2535 &rx0_sidetone_mix_mux, wsa_macro_enable_swr,
2536 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2537 SND_SOC_DAPM_INPUT("WSA SRC0_INP"),
2538
2539 SND_SOC_DAPM_INPUT("WSA_TX DEC0_INP"),
2540 SND_SOC_DAPM_INPUT("WSA_TX DEC1_INP"),
2541
Laxminath Kasam243e2752018-04-12 00:40:19 +05302542 SND_SOC_DAPM_MIXER_E("WSA_RX INT0 INTERP", SND_SOC_NOPM,
2543 WSA_MACRO_COMP1, 0, NULL, 0, wsa_macro_enable_interpolator,
2544 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2545 SND_SOC_DAPM_POST_PMD),
2546 SND_SOC_DAPM_MIXER_E("WSA_RX INT1 INTERP", SND_SOC_NOPM,
2547 WSA_MACRO_COMP2, 0, NULL, 0, wsa_macro_enable_interpolator,
2548 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2549 SND_SOC_DAPM_POST_PMD),
2550
2551 SND_SOC_DAPM_MIXER_E("WSA_RX INT0 CHAIN", SND_SOC_NOPM, 0, 0,
2552 NULL, 0, wsa_macro_spk_boost_event,
Laxminath Kasam0c857002018-07-17 23:47:17 +05302553 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2554 SND_SOC_DAPM_POST_PMD),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302555 SND_SOC_DAPM_MIXER_E("WSA_RX INT1 CHAIN", SND_SOC_NOPM, 0, 0,
2556 NULL, 0, wsa_macro_spk_boost_event,
Laxminath Kasam0c857002018-07-17 23:47:17 +05302557 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2558 SND_SOC_DAPM_POST_PMD),
Laxminath Kasam243e2752018-04-12 00:40:19 +05302559
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302560 SND_SOC_DAPM_MIXER_E("WSA_RX INT0 VBAT", SND_SOC_NOPM,
2561 0, 0, wsa_int0_vbat_mix_switch,
2562 ARRAY_SIZE(wsa_int0_vbat_mix_switch),
2563 wsa_macro_enable_vbat,
2564 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2565 SND_SOC_DAPM_MIXER_E("WSA_RX INT1 VBAT", SND_SOC_NOPM,
2566 0, 0, wsa_int1_vbat_mix_switch,
2567 ARRAY_SIZE(wsa_int1_vbat_mix_switch),
2568 wsa_macro_enable_vbat,
2569 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2570
Laxminath Kasam243e2752018-04-12 00:40:19 +05302571 SND_SOC_DAPM_INPUT("VIINPUT_WSA"),
2572
2573 SND_SOC_DAPM_OUTPUT("WSA_SPK1 OUT"),
2574 SND_SOC_DAPM_OUTPUT("WSA_SPK2 OUT"),
2575
2576 SND_SOC_DAPM_SUPPLY_S("WSA_MCLK", 0, SND_SOC_NOPM, 0, 0,
2577 wsa_macro_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2578};
2579
2580static const struct snd_soc_dapm_route wsa_audio_map[] = {
2581 /* VI Feedback */
2582 {"WSA_AIF_VI Mixer", "WSA_SPKR_VI_1", "VIINPUT_WSA"},
2583 {"WSA_AIF_VI Mixer", "WSA_SPKR_VI_2", "VIINPUT_WSA"},
2584 {"WSA AIF_VI", NULL, "WSA_AIF_VI Mixer"},
2585 {"WSA AIF_VI", NULL, "WSA_MCLK"},
2586
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05302587 {"WSA RX_MIX EC0_MUX", "RX_MIX_TX0", "WSA_RX INT0 SEC MIX"},
2588 {"WSA RX_MIX EC1_MUX", "RX_MIX_TX0", "WSA_RX INT0 SEC MIX"},
2589 {"WSA RX_MIX EC0_MUX", "RX_MIX_TX1", "WSA_RX INT1 SEC MIX"},
2590 {"WSA RX_MIX EC1_MUX", "RX_MIX_TX1", "WSA_RX INT1 SEC MIX"},
2591 {"WSA AIF_ECHO", NULL, "WSA RX_MIX EC0_MUX"},
2592 {"WSA AIF_ECHO", NULL, "WSA RX_MIX EC1_MUX"},
2593 {"WSA AIF_ECHO", NULL, "WSA_MCLK"},
2594
Laxminath Kasam243e2752018-04-12 00:40:19 +05302595 {"WSA AIF1 PB", NULL, "WSA_MCLK"},
2596 {"WSA AIF_MIX1 PB", NULL, "WSA_MCLK"},
2597
2598 {"WSA RX0 MUX", "AIF1_PB", "WSA AIF1 PB"},
2599 {"WSA RX1 MUX", "AIF1_PB", "WSA AIF1 PB"},
2600 {"WSA RX_MIX0 MUX", "AIF1_PB", "WSA AIF1 PB"},
2601 {"WSA RX_MIX1 MUX", "AIF1_PB", "WSA AIF1 PB"},
2602
2603 {"WSA RX0 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
2604 {"WSA RX1 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
2605 {"WSA RX_MIX0 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
2606 {"WSA RX_MIX1 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
2607
2608 {"WSA RX0", NULL, "WSA RX0 MUX"},
2609 {"WSA RX1", NULL, "WSA RX1 MUX"},
2610 {"WSA RX_MIX0", NULL, "WSA RX_MIX0 MUX"},
2611 {"WSA RX_MIX1", NULL, "WSA RX_MIX1 MUX"},
2612
2613 {"WSA_RX0 INP0", "RX0", "WSA RX0"},
2614 {"WSA_RX0 INP0", "RX1", "WSA RX1"},
2615 {"WSA_RX0 INP0", "RX_MIX0", "WSA RX_MIX0"},
2616 {"WSA_RX0 INP0", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302617 {"WSA_RX0 INP0", "DEC0", "WSA_TX DEC0_INP"},
2618 {"WSA_RX0 INP0", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302619 {"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP0"},
2620
2621 {"WSA_RX0 INP1", "RX0", "WSA RX0"},
2622 {"WSA_RX0 INP1", "RX1", "WSA RX1"},
2623 {"WSA_RX0 INP1", "RX_MIX0", "WSA RX_MIX0"},
2624 {"WSA_RX0 INP1", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302625 {"WSA_RX0 INP1", "DEC0", "WSA_TX DEC0_INP"},
2626 {"WSA_RX0 INP1", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302627 {"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP1"},
2628
2629 {"WSA_RX0 INP2", "RX0", "WSA RX0"},
2630 {"WSA_RX0 INP2", "RX1", "WSA RX1"},
2631 {"WSA_RX0 INP2", "RX_MIX0", "WSA RX_MIX0"},
2632 {"WSA_RX0 INP2", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302633 {"WSA_RX0 INP2", "DEC0", "WSA_TX DEC0_INP"},
2634 {"WSA_RX0 INP2", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302635 {"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP2"},
2636
2637 {"WSA_RX0 MIX INP", "RX0", "WSA RX0"},
2638 {"WSA_RX0 MIX INP", "RX1", "WSA RX1"},
2639 {"WSA_RX0 MIX INP", "RX_MIX0", "WSA RX_MIX0"},
2640 {"WSA_RX0 MIX INP", "RX_MIX1", "WSA RX_MIX1"},
2641 {"WSA_RX INT0 SEC MIX", NULL, "WSA_RX0 MIX INP"},
2642
2643 {"WSA_RX INT0 SEC MIX", NULL, "WSA_RX INT0 MIX"},
2644 {"WSA_RX INT0 INTERP", NULL, "WSA_RX INT0 SEC MIX"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302645 {"WSA_RX0 INT0 SIDETONE MIX", "SRC0", "WSA SRC0_INP"},
2646 {"WSA_RX INT0 INTERP", NULL, "WSA_RX0 INT0 SIDETONE MIX"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302647 {"WSA_RX INT0 CHAIN", NULL, "WSA_RX INT0 INTERP"},
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302648
2649 {"WSA_RX INT0 VBAT", "WSA RX0 VBAT Enable", "WSA_RX INT0 INTERP"},
2650 {"WSA_RX INT0 CHAIN", NULL, "WSA_RX INT0 VBAT"},
2651
Laxminath Kasam243e2752018-04-12 00:40:19 +05302652 {"WSA_SPK1 OUT", NULL, "WSA_RX INT0 CHAIN"},
Laxminath Kasamfc281ad2018-08-06 20:19:40 +05302653 {"WSA_SPK1 OUT", NULL, "WSA_MCLK"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302654
2655 {"WSA_RX1 INP0", "RX0", "WSA RX0"},
2656 {"WSA_RX1 INP0", "RX1", "WSA RX1"},
2657 {"WSA_RX1 INP0", "RX_MIX0", "WSA RX_MIX0"},
2658 {"WSA_RX1 INP0", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302659 {"WSA_RX1 INP0", "DEC0", "WSA_TX DEC0_INP"},
2660 {"WSA_RX1 INP0", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302661 {"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP0"},
2662
2663 {"WSA_RX1 INP1", "RX0", "WSA RX0"},
2664 {"WSA_RX1 INP1", "RX1", "WSA RX1"},
2665 {"WSA_RX1 INP1", "RX_MIX0", "WSA RX_MIX0"},
2666 {"WSA_RX1 INP1", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302667 {"WSA_RX1 INP1", "DEC0", "WSA_TX DEC0_INP"},
2668 {"WSA_RX1 INP1", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302669 {"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP1"},
2670
2671 {"WSA_RX1 INP2", "RX0", "WSA RX0"},
2672 {"WSA_RX1 INP2", "RX1", "WSA RX1"},
2673 {"WSA_RX1 INP2", "RX_MIX0", "WSA RX_MIX0"},
2674 {"WSA_RX1 INP2", "RX_MIX1", "WSA RX_MIX1"},
Laxminath Kasam6fc2e742018-08-26 23:32:57 +05302675 {"WSA_RX1 INP2", "DEC0", "WSA_TX DEC0_INP"},
2676 {"WSA_RX1 INP2", "DEC1", "WSA_TX DEC1_INP"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302677 {"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP2"},
2678
2679 {"WSA_RX1 MIX INP", "RX0", "WSA RX0"},
2680 {"WSA_RX1 MIX INP", "RX1", "WSA RX1"},
2681 {"WSA_RX1 MIX INP", "RX_MIX0", "WSA RX_MIX0"},
2682 {"WSA_RX1 MIX INP", "RX_MIX1", "WSA RX_MIX1"},
2683 {"WSA_RX INT1 SEC MIX", NULL, "WSA_RX1 MIX INP"},
2684
2685 {"WSA_RX INT1 SEC MIX", NULL, "WSA_RX INT1 MIX"},
2686 {"WSA_RX INT1 INTERP", NULL, "WSA_RX INT1 SEC MIX"},
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302687
2688 {"WSA_RX INT1 VBAT", "WSA RX1 VBAT Enable", "WSA_RX INT1 INTERP"},
2689 {"WSA_RX INT1 CHAIN", NULL, "WSA_RX INT1 VBAT"},
2690
Laxminath Kasam243e2752018-04-12 00:40:19 +05302691 {"WSA_RX INT1 CHAIN", NULL, "WSA_RX INT1 INTERP"},
2692 {"WSA_SPK2 OUT", NULL, "WSA_RX INT1 CHAIN"},
Laxminath Kasamfc281ad2018-08-06 20:19:40 +05302693 {"WSA_SPK2 OUT", NULL, "WSA_MCLK"},
Laxminath Kasam243e2752018-04-12 00:40:19 +05302694};
2695
2696static const struct wsa_macro_reg_mask_val wsa_macro_reg_init[] = {
2697 {BOLERO_CDC_WSA_BOOST0_BOOST_CFG1, 0x3F, 0x12},
2698 {BOLERO_CDC_WSA_BOOST0_BOOST_CFG2, 0x1C, 0x08},
2699 {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x1E, 0x18},
2700 {BOLERO_CDC_WSA_BOOST1_BOOST_CFG1, 0x3F, 0x12},
2701 {BOLERO_CDC_WSA_BOOST1_BOOST_CFG2, 0x1C, 0x08},
2702 {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x1E, 0x18},
2703 {BOLERO_CDC_WSA_BOOST0_BOOST_CTL, 0x70, 0x58},
2704 {BOLERO_CDC_WSA_BOOST1_BOOST_CTL, 0x70, 0x58},
2705 {BOLERO_CDC_WSA_RX0_RX_PATH_CFG1, 0x08, 0x08},
2706 {BOLERO_CDC_WSA_RX1_RX_PATH_CFG1, 0x08, 0x08},
2707 {BOLERO_CDC_WSA_TOP_TOP_CFG1, 0x02, 0x02},
2708 {BOLERO_CDC_WSA_TOP_TOP_CFG1, 0x01, 0x01},
2709 {BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
2710 {BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
2711 {BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
2712 {BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
2713 {BOLERO_CDC_WSA_COMPANDER0_CTL3, 0x80, 0x80},
2714 {BOLERO_CDC_WSA_COMPANDER1_CTL3, 0x80, 0x80},
2715 {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x01, 0x01},
2716 {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x01, 0x01},
2717 {BOLERO_CDC_WSA_RX0_RX_PATH_CFG0, 0x01, 0x01},
2718 {BOLERO_CDC_WSA_RX1_RX_PATH_CFG0, 0x01, 0x01},
2719 {BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CFG, 0x01, 0x01},
2720 {BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CFG, 0x01, 0x01},
2721};
2722
Meng Wang15c825d2018-09-06 10:49:18 +08002723static void wsa_macro_init_bcl_pmic_reg(struct snd_soc_component *component)
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302724{
2725 struct device *wsa_dev = NULL;
2726 struct wsa_macro_priv *wsa_priv = NULL;
2727
Meng Wang15c825d2018-09-06 10:49:18 +08002728 if (!component) {
2729 pr_err("%s: NULL component pointer!\n", __func__);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302730 return;
2731 }
2732
Meng Wang15c825d2018-09-06 10:49:18 +08002733 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302734 return;
2735
2736 switch (wsa_priv->bcl_pmic_params.id) {
2737 case 0:
2738 /* Enable ID0 to listen to respective PMIC group interrupts */
Meng Wang15c825d2018-09-06 10:49:18 +08002739 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302740 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CTL1, 0x02, 0x02);
2741 /* Update MC_SID0 */
Meng Wang15c825d2018-09-06 10:49:18 +08002742 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302743 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG1, 0x0F,
2744 wsa_priv->bcl_pmic_params.sid);
2745 /* Update MC_PPID0 */
Meng Wang15c825d2018-09-06 10:49:18 +08002746 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302747 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG2, 0xFF,
2748 wsa_priv->bcl_pmic_params.ppid);
2749 break;
2750 case 1:
2751 /* Enable ID1 to listen to respective PMIC group interrupts */
Meng Wang15c825d2018-09-06 10:49:18 +08002752 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302753 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CTL1, 0x01, 0x01);
2754 /* Update MC_SID1 */
Meng Wang15c825d2018-09-06 10:49:18 +08002755 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302756 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG3, 0x0F,
2757 wsa_priv->bcl_pmic_params.sid);
2758 /* Update MC_PPID1 */
Meng Wang15c825d2018-09-06 10:49:18 +08002759 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302760 BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG4, 0xFF,
2761 wsa_priv->bcl_pmic_params.ppid);
2762 break;
2763 default:
2764 dev_err(wsa_dev, "%s: PMIC ID is invalid %d\n",
2765 __func__, wsa_priv->bcl_pmic_params.id);
2766 break;
2767 }
2768}
2769
Meng Wang15c825d2018-09-06 10:49:18 +08002770static void wsa_macro_init_reg(struct snd_soc_component *component)
Laxminath Kasam243e2752018-04-12 00:40:19 +05302771{
2772 int i;
2773
2774 for (i = 0; i < ARRAY_SIZE(wsa_macro_reg_init); i++)
Meng Wang15c825d2018-09-06 10:49:18 +08002775 snd_soc_component_update_bits(component,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302776 wsa_macro_reg_init[i].reg,
2777 wsa_macro_reg_init[i].mask,
2778 wsa_macro_reg_init[i].val);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302779
Meng Wang15c825d2018-09-06 10:49:18 +08002780 wsa_macro_init_bcl_pmic_reg(component);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302781}
2782
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07002783static int wsa_macro_core_vote(void *handle, bool enable)
2784{
2785 struct wsa_macro_priv *wsa_priv = (struct wsa_macro_priv *) handle;
2786 int ret = 0;
2787
2788 if (wsa_priv == NULL) {
2789 pr_err("%s: wsa priv data is NULL\n", __func__);
2790 return -EINVAL;
2791 }
2792 if (enable) {
2793 pm_runtime_get_sync(wsa_priv->dev);
2794 pm_runtime_put_autosuspend(wsa_priv->dev);
2795 pm_runtime_mark_last_busy(wsa_priv->dev);
2796 }
2797
2798 return ret;
2799}
2800
Laxminath Kasam243e2752018-04-12 00:40:19 +05302801static int wsa_swrm_clock(void *handle, bool enable)
2802{
2803 struct wsa_macro_priv *wsa_priv = (struct wsa_macro_priv *) handle;
2804 struct regmap *regmap = dev_get_regmap(wsa_priv->dev->parent, NULL);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302805 int ret = 0;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302806
Tanya Dixitab8eba82018-10-05 15:07:37 +05302807 if (regmap == NULL) {
2808 dev_err(wsa_priv->dev, "%s: regmap is NULL\n", __func__);
2809 return -EINVAL;
2810 }
2811
Laxminath Kasam243e2752018-04-12 00:40:19 +05302812 mutex_lock(&wsa_priv->swr_clk_lock);
2813
2814 dev_dbg(wsa_priv->dev, "%s: swrm clock %s\n",
2815 __func__, (enable ? "enable" : "disable"));
2816 if (enable) {
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302817 pm_runtime_get_sync(wsa_priv->dev);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302818 if (wsa_priv->swr_clk_users == 0) {
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07002819 ret = msm_cdc_pinctrl_select_active_state(
Karthikeyan Mani01f1ba42019-02-26 18:48:15 -08002820 wsa_priv->wsa_swr_gpio_p);
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07002821 if (ret < 0) {
2822 dev_err_ratelimited(wsa_priv->dev,
2823 "%s: wsa swr pinctrl enable failed\n",
2824 __func__);
2825 pm_runtime_mark_last_busy(wsa_priv->dev);
2826 pm_runtime_put_autosuspend(wsa_priv->dev);
2827 goto exit;
2828 }
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302829 ret = wsa_macro_mclk_enable(wsa_priv, 1, true);
2830 if (ret < 0) {
Karthikeyan Mani01f1ba42019-02-26 18:48:15 -08002831 msm_cdc_pinctrl_select_sleep_state(
2832 wsa_priv->wsa_swr_gpio_p);
Ramprasad Katkam14efed62019-03-07 13:16:50 +05302833 dev_err_ratelimited(wsa_priv->dev,
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302834 "%s: wsa request clock enable failed\n",
2835 __func__);
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07002836 pm_runtime_mark_last_busy(wsa_priv->dev);
2837 pm_runtime_put_autosuspend(wsa_priv->dev);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302838 goto exit;
2839 }
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05302840 if (wsa_priv->reset_swr)
2841 regmap_update_bits(regmap,
2842 BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
2843 0x02, 0x02);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302844 regmap_update_bits(regmap,
2845 BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
2846 0x01, 0x01);
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05302847 if (wsa_priv->reset_swr)
2848 regmap_update_bits(regmap,
2849 BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
2850 0x02, 0x00);
2851 wsa_priv->reset_swr = false;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302852 }
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07002853 wsa_priv->swr_clk_users++;
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302854 pm_runtime_mark_last_busy(wsa_priv->dev);
2855 pm_runtime_put_autosuspend(wsa_priv->dev);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302856 } else {
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302857 if (wsa_priv->swr_clk_users <= 0) {
2858 dev_err(wsa_priv->dev, "%s: clock already disabled\n",
2859 __func__);
2860 wsa_priv->swr_clk_users = 0;
2861 goto exit;
2862 }
Laxminath Kasam243e2752018-04-12 00:40:19 +05302863 wsa_priv->swr_clk_users--;
2864 if (wsa_priv->swr_clk_users == 0) {
2865 regmap_update_bits(regmap,
2866 BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
2867 0x01, 0x00);
Karthikeyan Mani01f1ba42019-02-26 18:48:15 -08002868 wsa_macro_mclk_enable(wsa_priv, 0, true);
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07002869 ret = msm_cdc_pinctrl_select_sleep_state(
Laxminath Kasam243e2752018-04-12 00:40:19 +05302870 wsa_priv->wsa_swr_gpio_p);
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07002871 if (ret < 0) {
2872 dev_err_ratelimited(wsa_priv->dev,
2873 "%s: wsa swr pinctrl disable failed\n",
2874 __func__);
2875 goto exit;
2876 }
Laxminath Kasam243e2752018-04-12 00:40:19 +05302877 }
2878 }
2879 dev_dbg(wsa_priv->dev, "%s: swrm clock users %d\n",
2880 __func__, wsa_priv->swr_clk_users);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302881exit:
Laxminath Kasam243e2752018-04-12 00:40:19 +05302882 mutex_unlock(&wsa_priv->swr_clk_lock);
Aditya Bavanaric496ed22018-11-16 15:50:40 +05302883 return ret;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302884}
2885
Meng Wang15c825d2018-09-06 10:49:18 +08002886static int wsa_macro_init(struct snd_soc_component *component)
Laxminath Kasam243e2752018-04-12 00:40:19 +05302887{
Meng Wang15c825d2018-09-06 10:49:18 +08002888 struct snd_soc_dapm_context *dapm =
2889 snd_soc_component_get_dapm(component);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302890 int ret;
2891 struct device *wsa_dev = NULL;
2892 struct wsa_macro_priv *wsa_priv = NULL;
2893
Meng Wang15c825d2018-09-06 10:49:18 +08002894 wsa_dev = bolero_get_device_ptr(component->dev, WSA_MACRO);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302895 if (!wsa_dev) {
Meng Wang15c825d2018-09-06 10:49:18 +08002896 dev_err(component->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302897 "%s: null device for macro!\n", __func__);
2898 return -EINVAL;
2899 }
2900 wsa_priv = dev_get_drvdata(wsa_dev);
2901 if (!wsa_priv) {
Meng Wang15c825d2018-09-06 10:49:18 +08002902 dev_err(component->dev,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302903 "%s: priv is null for macro!\n", __func__);
2904 return -EINVAL;
2905 }
2906
2907 ret = snd_soc_dapm_new_controls(dapm, wsa_macro_dapm_widgets,
2908 ARRAY_SIZE(wsa_macro_dapm_widgets));
2909 if (ret < 0) {
2910 dev_err(wsa_dev, "%s: Failed to add controls\n", __func__);
2911 return ret;
2912 }
2913
2914 ret = snd_soc_dapm_add_routes(dapm, wsa_audio_map,
2915 ARRAY_SIZE(wsa_audio_map));
2916 if (ret < 0) {
2917 dev_err(wsa_dev, "%s: Failed to add routes\n", __func__);
2918 return ret;
2919 }
2920
2921 ret = snd_soc_dapm_new_widgets(dapm->card);
2922 if (ret < 0) {
2923 dev_err(wsa_dev, "%s: Failed to add widgets\n", __func__);
2924 return ret;
2925 }
2926
Meng Wang15c825d2018-09-06 10:49:18 +08002927 ret = snd_soc_add_component_controls(component, wsa_macro_snd_controls,
Laxminath Kasam243e2752018-04-12 00:40:19 +05302928 ARRAY_SIZE(wsa_macro_snd_controls));
2929 if (ret < 0) {
2930 dev_err(wsa_dev, "%s: Failed to add snd_ctls\n", __func__);
2931 return ret;
2932 }
Laxminath Kasam638b5602018-09-24 13:19:52 +05302933 snd_soc_dapm_ignore_suspend(dapm, "WSA_AIF1 Playback");
2934 snd_soc_dapm_ignore_suspend(dapm, "WSA_AIF_MIX1 Playback");
2935 snd_soc_dapm_ignore_suspend(dapm, "WSA_AIF_VI Capture");
2936 snd_soc_dapm_ignore_suspend(dapm, "WSA_AIF_ECHO Capture");
2937 snd_soc_dapm_ignore_suspend(dapm, "WSA_SPK1 OUT");
2938 snd_soc_dapm_ignore_suspend(dapm, "WSA_SPK2 OUT");
2939 snd_soc_dapm_ignore_suspend(dapm, "VIINPUT_WSA");
2940 snd_soc_dapm_ignore_suspend(dapm, "WSA SRC0_INP");
2941 snd_soc_dapm_ignore_suspend(dapm, "WSA_TX DEC0_INP");
2942 snd_soc_dapm_ignore_suspend(dapm, "WSA_TX DEC1_INP");
2943 snd_soc_dapm_sync(dapm);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302944
Meng Wang15c825d2018-09-06 10:49:18 +08002945 wsa_priv->component = component;
Laxminath Kasam21c8b222018-06-21 18:47:22 +05302946 wsa_priv->spkr_gain_offset = WSA_MACRO_GAIN_OFFSET_0_DB;
Meng Wang15c825d2018-09-06 10:49:18 +08002947 wsa_macro_init_reg(component);
Laxminath Kasam243e2752018-04-12 00:40:19 +05302948
2949 return 0;
2950}
2951
Meng Wang15c825d2018-09-06 10:49:18 +08002952static int wsa_macro_deinit(struct snd_soc_component *component)
Laxminath Kasam243e2752018-04-12 00:40:19 +05302953{
2954 struct device *wsa_dev = NULL;
2955 struct wsa_macro_priv *wsa_priv = NULL;
2956
Meng Wang15c825d2018-09-06 10:49:18 +08002957 if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
Laxminath Kasam243e2752018-04-12 00:40:19 +05302958 return -EINVAL;
2959
Meng Wang15c825d2018-09-06 10:49:18 +08002960 wsa_priv->component = NULL;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302961
2962 return 0;
2963}
2964
2965static void wsa_macro_add_child_devices(struct work_struct *work)
2966{
2967 struct wsa_macro_priv *wsa_priv;
2968 struct platform_device *pdev;
2969 struct device_node *node;
2970 struct wsa_macro_swr_ctrl_data *swr_ctrl_data = NULL, *temp;
2971 int ret;
2972 u16 count = 0, ctrl_num = 0;
2973 struct wsa_macro_swr_ctrl_platform_data *platdata;
2974 char plat_dev_name[WSA_MACRO_SWR_STRING_LEN];
2975
2976 wsa_priv = container_of(work, struct wsa_macro_priv,
2977 wsa_macro_add_child_devices_work);
2978 if (!wsa_priv) {
2979 pr_err("%s: Memory for wsa_priv does not exist\n",
2980 __func__);
2981 return;
2982 }
Laxminath Kasam21c8b222018-06-21 18:47:22 +05302983 if (!wsa_priv->dev || !wsa_priv->dev->of_node) {
Laxminath Kasam243e2752018-04-12 00:40:19 +05302984 dev_err(wsa_priv->dev,
2985 "%s: DT node for wsa_priv does not exist\n", __func__);
2986 return;
2987 }
2988
2989 platdata = &wsa_priv->swr_plat_data;
2990 wsa_priv->child_count = 0;
2991
2992 for_each_available_child_of_node(wsa_priv->dev->of_node, node) {
2993 if (strnstr(node->name, "wsa_swr_master",
2994 strlen("wsa_swr_master")) != NULL)
2995 strlcpy(plat_dev_name, "wsa_swr_ctrl",
2996 (WSA_MACRO_SWR_STRING_LEN - 1));
2997 else if (strnstr(node->name, "msm_cdc_pinctrl",
2998 strlen("msm_cdc_pinctrl")) != NULL)
2999 strlcpy(plat_dev_name, node->name,
3000 (WSA_MACRO_SWR_STRING_LEN - 1));
3001 else
3002 continue;
3003
3004 pdev = platform_device_alloc(plat_dev_name, -1);
3005 if (!pdev) {
3006 dev_err(wsa_priv->dev, "%s: pdev memory alloc failed\n",
3007 __func__);
3008 ret = -ENOMEM;
3009 goto err;
3010 }
3011 pdev->dev.parent = wsa_priv->dev;
3012 pdev->dev.of_node = node;
3013
3014 if (strnstr(node->name, "wsa_swr_master",
3015 strlen("wsa_swr_master")) != NULL) {
3016 ret = platform_device_add_data(pdev, platdata,
3017 sizeof(*platdata));
3018 if (ret) {
3019 dev_err(&pdev->dev,
3020 "%s: cannot add plat data ctrl:%d\n",
3021 __func__, ctrl_num);
3022 goto fail_pdev_add;
3023 }
3024 }
3025
3026 ret = platform_device_add(pdev);
3027 if (ret) {
3028 dev_err(&pdev->dev,
3029 "%s: Cannot add platform device\n",
3030 __func__);
3031 goto fail_pdev_add;
3032 }
3033
3034 if (!strcmp(node->name, "wsa_swr_master")) {
3035 temp = krealloc(swr_ctrl_data,
3036 (ctrl_num + 1) * sizeof(
3037 struct wsa_macro_swr_ctrl_data),
3038 GFP_KERNEL);
3039 if (!temp) {
3040 dev_err(&pdev->dev, "out of memory\n");
3041 ret = -ENOMEM;
3042 goto err;
3043 }
3044 swr_ctrl_data = temp;
3045 swr_ctrl_data[ctrl_num].wsa_swr_pdev = pdev;
3046 ctrl_num++;
3047 dev_dbg(&pdev->dev,
3048 "%s: Added soundwire ctrl device(s)\n",
3049 __func__);
3050 wsa_priv->swr_ctrl_data = swr_ctrl_data;
3051 }
3052 if (wsa_priv->child_count < WSA_MACRO_CHILD_DEVICES_MAX)
3053 wsa_priv->pdev_child_devices[
3054 wsa_priv->child_count++] = pdev;
3055 else
3056 goto err;
3057 }
3058
3059 return;
3060fail_pdev_add:
3061 for (count = 0; count < wsa_priv->child_count; count++)
3062 platform_device_put(wsa_priv->pdev_child_devices[count]);
3063err:
3064 return;
3065}
3066
3067static void wsa_macro_init_ops(struct macro_ops *ops,
3068 char __iomem *wsa_io_base)
3069{
3070 memset(ops, 0, sizeof(struct macro_ops));
3071 ops->init = wsa_macro_init;
3072 ops->exit = wsa_macro_deinit;
3073 ops->io_base = wsa_io_base;
3074 ops->dai_ptr = wsa_macro_dai;
3075 ops->num_dais = ARRAY_SIZE(wsa_macro_dai);
Laxminath Kasamfb0d6832018-09-22 01:49:52 +05303076 ops->event_handler = wsa_macro_event_handler;
Sudheer Papothia3e969d2018-10-27 06:22:10 +05303077 ops->set_port_map = wsa_macro_set_port_map;
Laxminath Kasam243e2752018-04-12 00:40:19 +05303078}
3079
3080static int wsa_macro_probe(struct platform_device *pdev)
3081{
3082 struct macro_ops ops;
3083 struct wsa_macro_priv *wsa_priv;
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07003084 u32 wsa_base_addr, default_clk_id;
Laxminath Kasam243e2752018-04-12 00:40:19 +05303085 char __iomem *wsa_io_base;
3086 int ret = 0;
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303087 u8 bcl_pmic_params[3];
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07003088 u32 is_used_wsa_swr_gpio = 1;
3089 const char *is_used_wsa_swr_gpio_dt = "qcom,is-used-swr-gpio";
Laxminath Kasam243e2752018-04-12 00:40:19 +05303090
3091 wsa_priv = devm_kzalloc(&pdev->dev, sizeof(struct wsa_macro_priv),
3092 GFP_KERNEL);
3093 if (!wsa_priv)
3094 return -ENOMEM;
3095
3096 wsa_priv->dev = &pdev->dev;
3097 ret = of_property_read_u32(pdev->dev.of_node, "reg",
3098 &wsa_base_addr);
3099 if (ret) {
3100 dev_err(&pdev->dev, "%s: could not find %s entry in dt\n",
3101 __func__, "reg");
3102 return ret;
3103 }
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07003104 if (of_find_property(pdev->dev.of_node, is_used_wsa_swr_gpio_dt,
3105 NULL)) {
3106 ret = of_property_read_u32(pdev->dev.of_node,
3107 is_used_wsa_swr_gpio_dt,
3108 &is_used_wsa_swr_gpio);
3109 if (ret) {
3110 dev_err(&pdev->dev, "%s: error reading %s in dt\n",
3111 __func__, is_used_wsa_swr_gpio_dt);
3112 is_used_wsa_swr_gpio = 1;
3113 }
3114 }
Laxminath Kasam243e2752018-04-12 00:40:19 +05303115 wsa_priv->wsa_swr_gpio_p = of_parse_phandle(pdev->dev.of_node,
3116 "qcom,wsa-swr-gpios", 0);
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07003117 if (!wsa_priv->wsa_swr_gpio_p && is_used_wsa_swr_gpio) {
Laxminath Kasam243e2752018-04-12 00:40:19 +05303118 dev_err(&pdev->dev, "%s: swr_gpios handle not provided!\n",
3119 __func__);
3120 return -EINVAL;
3121 }
Karthikeyan Mani326536d2019-06-03 13:29:43 -07003122 if (msm_cdc_pinctrl_get_state(wsa_priv->wsa_swr_gpio_p) < 0) {
3123 dev_err(&pdev->dev, "%s: failed to get swr pin state\n",
3124 __func__);
3125 return -EPROBE_DEFER;
3126 }
3127
Laxminath Kasam243e2752018-04-12 00:40:19 +05303128 wsa_io_base = devm_ioremap(&pdev->dev,
3129 wsa_base_addr, WSA_MACRO_MAX_OFFSET);
3130 if (!wsa_io_base) {
3131 dev_err(&pdev->dev, "%s: ioremap failed\n", __func__);
3132 return -EINVAL;
3133 }
3134 wsa_priv->wsa_io_base = wsa_io_base;
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05303135 wsa_priv->reset_swr = true;
Laxminath Kasam243e2752018-04-12 00:40:19 +05303136 INIT_WORK(&wsa_priv->wsa_macro_add_child_devices_work,
3137 wsa_macro_add_child_devices);
3138 wsa_priv->swr_plat_data.handle = (void *) wsa_priv;
3139 wsa_priv->swr_plat_data.read = NULL;
3140 wsa_priv->swr_plat_data.write = NULL;
3141 wsa_priv->swr_plat_data.bulk_write = NULL;
3142 wsa_priv->swr_plat_data.clk = wsa_swrm_clock;
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07003143 wsa_priv->swr_plat_data.core_vote = wsa_macro_core_vote;
Laxminath Kasam243e2752018-04-12 00:40:19 +05303144 wsa_priv->swr_plat_data.handle_irq = NULL;
3145
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07003146 ret = of_property_read_u32(pdev->dev.of_node, "qcom,default-clk-id",
3147 &default_clk_id);
3148 if (ret) {
3149 dev_err(&pdev->dev, "%s: could not find %s entry in dt\n",
3150 __func__, "qcom,mux0-clk-id");
3151 default_clk_id = WSA_CORE_CLK;
Laxminath Kasam243e2752018-04-12 00:40:19 +05303152 }
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303153
3154 ret = of_property_read_u8_array(pdev->dev.of_node,
3155 "qcom,wsa-bcl-pmic-params", bcl_pmic_params,
3156 sizeof(bcl_pmic_params));
3157 if (ret) {
3158 dev_dbg(&pdev->dev, "%s: could not find %s entry in dt\n",
3159 __func__, "qcom,wsa-bcl-pmic-params");
3160 } else {
3161 wsa_priv->bcl_pmic_params.id = bcl_pmic_params[0];
3162 wsa_priv->bcl_pmic_params.sid = bcl_pmic_params[1];
3163 wsa_priv->bcl_pmic_params.ppid = bcl_pmic_params[2];
3164 }
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07003165 wsa_priv->default_clk_id = default_clk_id;
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303166
Laxminath Kasam243e2752018-04-12 00:40:19 +05303167 dev_set_drvdata(&pdev->dev, wsa_priv);
3168 mutex_init(&wsa_priv->mclk_lock);
3169 mutex_init(&wsa_priv->swr_clk_lock);
3170 wsa_macro_init_ops(&ops, wsa_io_base);
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07003171 ops.clk_id_req = wsa_priv->default_clk_id;
3172 ops.default_clk_id = wsa_priv->default_clk_id;
Laxminath Kasam243e2752018-04-12 00:40:19 +05303173 ret = bolero_register_macro(&pdev->dev, WSA_MACRO, &ops);
3174 if (ret < 0) {
3175 dev_err(&pdev->dev, "%s: register macro failed\n", __func__);
3176 goto reg_macro_fail;
3177 }
3178 schedule_work(&wsa_priv->wsa_macro_add_child_devices_work);
Sudheer Papothi7601cc62019-03-30 03:00:52 +05303179 pm_runtime_set_autosuspend_delay(&pdev->dev, AUTO_SUSPEND_DELAY);
3180 pm_runtime_use_autosuspend(&pdev->dev);
3181 pm_runtime_set_suspended(&pdev->dev);
3182 pm_runtime_enable(&pdev->dev);
3183
Laxminath Kasam243e2752018-04-12 00:40:19 +05303184 return ret;
3185reg_macro_fail:
3186 mutex_destroy(&wsa_priv->mclk_lock);
3187 mutex_destroy(&wsa_priv->swr_clk_lock);
3188 return ret;
3189}
3190
3191static int wsa_macro_remove(struct platform_device *pdev)
3192{
3193 struct wsa_macro_priv *wsa_priv;
3194 u16 count = 0;
3195
3196 wsa_priv = dev_get_drvdata(&pdev->dev);
3197
3198 if (!wsa_priv)
3199 return -EINVAL;
3200
3201 for (count = 0; count < wsa_priv->child_count &&
3202 count < WSA_MACRO_CHILD_DEVICES_MAX; count++)
3203 platform_device_unregister(wsa_priv->pdev_child_devices[count]);
3204
Sudheer Papothi7601cc62019-03-30 03:00:52 +05303205 pm_runtime_disable(&pdev->dev);
3206 pm_runtime_set_suspended(&pdev->dev);
Laxminath Kasam243e2752018-04-12 00:40:19 +05303207 bolero_unregister_macro(&pdev->dev, WSA_MACRO);
3208 mutex_destroy(&wsa_priv->mclk_lock);
3209 mutex_destroy(&wsa_priv->swr_clk_lock);
3210 return 0;
3211}
3212
3213static const struct of_device_id wsa_macro_dt_match[] = {
3214 {.compatible = "qcom,wsa-macro"},
3215 {}
3216};
3217
Sudheer Papothi7601cc62019-03-30 03:00:52 +05303218static const struct dev_pm_ops bolero_dev_pm_ops = {
3219 SET_RUNTIME_PM_OPS(
3220 bolero_runtime_suspend,
3221 bolero_runtime_resume,
3222 NULL
3223 )
3224};
3225
Laxminath Kasam243e2752018-04-12 00:40:19 +05303226static struct platform_driver wsa_macro_driver = {
3227 .driver = {
3228 .name = "wsa_macro",
3229 .owner = THIS_MODULE,
Sudheer Papothi7601cc62019-03-30 03:00:52 +05303230 .pm = &bolero_dev_pm_ops,
Laxminath Kasam243e2752018-04-12 00:40:19 +05303231 .of_match_table = wsa_macro_dt_match,
Xiaojun Sang53cd13a2018-06-29 15:14:37 +08003232 .suppress_bind_attrs = true,
Laxminath Kasam243e2752018-04-12 00:40:19 +05303233 },
3234 .probe = wsa_macro_probe,
3235 .remove = wsa_macro_remove,
3236};
3237
3238module_platform_driver(wsa_macro_driver);
3239
3240MODULE_DESCRIPTION("WSA macro driver");
3241MODULE_LICENSE("GPL v2");