blob: d73193c639f5814cfe0475117338318c07bc062b [file] [log] [blame]
Laxminath Kasam243e2752018-04-12 00:40:19 +05301/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/module.h>
14#include <linux/init.h>
15#include <linux/io.h>
16#include <linux/platform_device.h>
17#include <linux/clk.h>
18#include <sound/soc.h>
19#include <sound/soc-dapm.h>
20#include <sound/tlv.h>
21#include <soc/swr-wcd.h>
22
23#include "bolero-cdc.h"
24#include "bolero-cdc-registers.h"
25#include "wsa-macro.h"
26#include "../msm-cdc-pinctrl.h"
27
28#define WSA_MACRO_MAX_OFFSET 0x1000
29
30#define WSA_MACRO_RX_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
31 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
32 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
33#define WSA_MACRO_RX_MIX_RATES (SNDRV_PCM_RATE_48000 |\
34 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
35#define WSA_MACRO_RX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
36 SNDRV_PCM_FMTBIT_S24_LE |\
37 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
38
39#define WSA_MACRO_ECHO_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
40 SNDRV_PCM_RATE_48000)
41#define WSA_MACRO_ECHO_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
42 SNDRV_PCM_FMTBIT_S24_LE |\
43 SNDRV_PCM_FMTBIT_S24_3LE)
44
45#define NUM_INTERPOLATORS 2
46
47#define WSA_MACRO_MUX_INP_SHFT 0x3
48#define WSA_MACRO_MUX_INP_MASK1 0x38
49#define WSA_MACRO_MUX_INP_MASK2 0x38
50#define WSA_MACRO_MUX_CFG_OFFSET 0x8
51#define WSA_MACRO_MUX_CFG1_OFFSET 0x4
52#define WSA_MACRO_RX_COMP_OFFSET 0x40
53#define WSA_MACRO_RX_PATH_OFFSET 0x80
54#define WSA_MACRO_RX_PATH_CFG3_OFFSET 0x10
55#define WSA_MACRO_RX_PATH_DSMDEM_OFFSET 0x4C
56#define WSA_MACRO_FS_RATE_MASK 0x0F
57
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
85struct interp_sample_rate {
86 int sample_rate;
87 int rate_val;
88};
89
90/*
91 * Structure used to update codec
92 * register defaults after reset
93 */
94struct wsa_macro_reg_mask_val {
95 u16 reg;
96 u8 mask;
97 u8 val;
98};
99
100static struct interp_sample_rate int_prim_sample_rate_val[] = {
101 {8000, 0x0}, /* 8K */
102 {16000, 0x1}, /* 16K */
103 {24000, -EINVAL},/* 24K */
104 {32000, 0x3}, /* 32K */
105 {48000, 0x4}, /* 48K */
106 {96000, 0x5}, /* 96K */
107 {192000, 0x6}, /* 192K */
108 {384000, 0x7}, /* 384K */
109 {44100, 0x8}, /* 44.1K */
110};
111
112static struct interp_sample_rate int_mix_sample_rate_val[] = {
113 {48000, 0x4}, /* 48K */
114 {96000, 0x5}, /* 96K */
115 {192000, 0x6}, /* 192K */
116};
117
118#define WSA_MACRO_SWR_STRING_LEN 80
119
120static int wsa_macro_hw_params(struct snd_pcm_substream *substream,
121 struct snd_pcm_hw_params *params,
122 struct snd_soc_dai *dai);
123static int wsa_macro_get_channel_map(struct snd_soc_dai *dai,
124 unsigned int *tx_num, unsigned int *tx_slot,
125 unsigned int *rx_num, unsigned int *rx_slot);
126/* Hold instance to soundwire platform device */
127struct wsa_macro_swr_ctrl_data {
128 struct platform_device *wsa_swr_pdev;
129};
130
131struct wsa_macro_swr_ctrl_platform_data {
132 void *handle; /* holds codec private data */
133 int (*read)(void *handle, int reg);
134 int (*write)(void *handle, int reg, int val);
135 int (*bulk_write)(void *handle, u32 *reg, u32 *val, size_t len);
136 int (*clk)(void *handle, bool enable);
137 int (*handle_irq)(void *handle,
138 irqreturn_t (*swrm_irq_handler)(int irq,
139 void *data),
140 void *swrm_handle,
141 int action);
142};
143
144enum {
145 WSA_MACRO_AIF1_PB = 0,
146 WSA_MACRO_AIF_MIX1_PB,
147 WSA_MACRO_AIF_VI,
148 WSA_MACRO_AIF_ECHO,
149 WSA_MACRO_MAX_DAIS,
150};
151
152#define WSA_MACRO_CHILD_DEVICES_MAX 3
153
154/*
155 * @dev: wsa macro device pointer
156 * @comp_enabled: compander enable mixer value set
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +0530157 * @ec_hq: echo HQ enable mixer value set
Laxminath Kasam243e2752018-04-12 00:40:19 +0530158 * @prim_int_users: Users of interpolator
159 * @wsa_mclk_users: WSA MCLK users count
160 * @swr_clk_users: SWR clk users count
161 * @vi_feed_value: VI sense mask
162 * @mclk_lock: to lock mclk operations
163 * @swr_clk_lock: to lock swr master clock operations
164 * @swr_ctrl_data: SoundWire data structure
165 * @swr_plat_data: Soundwire platform data
166 * @wsa_macro_add_child_devices_work: work for adding child devices
167 * @wsa_swr_gpio_p: used by pinctrl API
168 * @wsa_core_clk: MCLK for wsa macro
169 * @wsa_npl_clk: NPL clock for WSA soundwire
170 * @codec: codec handle
171 * @rx_0_count: RX0 interpolation users
172 * @rx_1_count: RX1 interpolation users
173 * @active_ch_mask: channel mask for all AIF DAIs
174 * @active_ch_cnt: channel count of all AIF DAIs
175 * @rx_port_value: mixer ctl value of WSA RX MUXes
176 * @wsa_io_base: Base address of WSA macro addr space
177 */
178struct wsa_macro_priv {
179 struct device *dev;
180 int comp_enabled[WSA_MACRO_COMP_MAX];
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +0530181 int ec_hq[WSA_MACRO_RX1 + 1];
Laxminath Kasam243e2752018-04-12 00:40:19 +0530182 u16 prim_int_users[WSA_MACRO_RX1 + 1];
183 u16 wsa_mclk_users;
184 u16 swr_clk_users;
185 unsigned int vi_feed_value;
186 struct mutex mclk_lock;
187 struct mutex swr_clk_lock;
188 struct wsa_macro_swr_ctrl_data *swr_ctrl_data;
189 struct wsa_macro_swr_ctrl_platform_data swr_plat_data;
190 struct work_struct wsa_macro_add_child_devices_work;
191 struct device_node *wsa_swr_gpio_p;
192 struct clk *wsa_core_clk;
193 struct clk *wsa_npl_clk;
194 struct snd_soc_codec *codec;
195 int rx_0_count;
196 int rx_1_count;
197 unsigned long active_ch_mask[WSA_MACRO_MAX_DAIS];
198 unsigned long active_ch_cnt[WSA_MACRO_MAX_DAIS];
199 int rx_port_value[WSA_MACRO_RX_MAX];
200 char __iomem *wsa_io_base;
201 struct platform_device *pdev_child_devices
202 [WSA_MACRO_CHILD_DEVICES_MAX];
203 int child_count;
204 int ear_spkr_gain;
205 int spkr_gain_offset;
206 int spkr_mode;
207};
208
209static int wsa_macro_config_ear_spkr_gain(struct snd_soc_codec *codec,
210 struct wsa_macro_priv *wsa_priv,
211 int event, int gain_reg);
212static struct snd_soc_dai_driver wsa_macro_dai[];
213static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0);
214
215static const char *const rx_text[] = {
216 "ZERO", "RX0", "RX1", "RX_MIX0", "RX_MIX1", "DEC0", "DEC1"
217};
218
219static const char *const rx_mix_text[] = {
220 "ZERO", "RX0", "RX1", "RX_MIX0", "RX_MIX1"
221};
222
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +0530223static const char *const rx_mix_ec_text[] = {
224 "ZERO", "RX_MIX_TX0", "RX_MIX_TX1"
225};
226
Laxminath Kasam243e2752018-04-12 00:40:19 +0530227static const char *const rx_mux_text[] = {
228 "ZERO", "AIF1_PB", "AIF_MIX1_PB"
229};
230
231static const char * const wsa_macro_ear_spkr_pa_gain_text[] = {
232 "G_DEFAULT", "G_0_DB", "G_1_DB", "G_2_DB", "G_3_DB",
233 "G_4_DB", "G_5_DB", "G_6_DB"
234};
235
236static const char * const wsa_macro_speaker_boost_stage_text[] = {
237 "NO_MAX_STATE", "MAX_STATE_1", "MAX_STATE_2"
238};
239
240static SOC_ENUM_SINGLE_EXT_DECL(wsa_macro_ear_spkr_pa_gain_enum,
241 wsa_macro_ear_spkr_pa_gain_text);
242static SOC_ENUM_SINGLE_EXT_DECL(wsa_macro_spkr_boost_stage_enum,
243 wsa_macro_speaker_boost_stage_text);
244
245/* RX INT0 */
246static const struct soc_enum rx0_prim_inp0_chain_enum =
247 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0,
248 0, 7, rx_text);
249
250static const struct soc_enum rx0_prim_inp1_chain_enum =
251 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0,
252 3, 7, rx_text);
253
254static const struct soc_enum rx0_prim_inp2_chain_enum =
255 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG1,
256 3, 7, rx_text);
257
258static const struct soc_enum rx0_mix_chain_enum =
259 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG1,
260 0, 5, rx_mix_text);
261
262static const struct snd_kcontrol_new rx0_prim_inp0_mux =
263 SOC_DAPM_ENUM("WSA_RX0 INP0 Mux", rx0_prim_inp0_chain_enum);
264
265static const struct snd_kcontrol_new rx0_prim_inp1_mux =
266 SOC_DAPM_ENUM("WSA_RX0 INP1 Mux", rx0_prim_inp1_chain_enum);
267
268static const struct snd_kcontrol_new rx0_prim_inp2_mux =
269 SOC_DAPM_ENUM("WSA_RX0 INP2 Mux", rx0_prim_inp2_chain_enum);
270
271static const struct snd_kcontrol_new rx0_mix_mux =
272 SOC_DAPM_ENUM("WSA_RX0 MIX Mux", rx0_mix_chain_enum);
273
274/* RX INT1 */
275static const struct soc_enum rx1_prim_inp0_chain_enum =
276 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT1_CFG0,
277 0, 7, rx_text);
278
279static const struct soc_enum rx1_prim_inp1_chain_enum =
280 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT1_CFG0,
281 3, 7, rx_text);
282
283static const struct soc_enum rx1_prim_inp2_chain_enum =
284 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT1_CFG1,
285 3, 7, rx_text);
286
287static const struct soc_enum rx1_mix_chain_enum =
288 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT1_CFG1,
289 0, 5, rx_mix_text);
290
291static const struct snd_kcontrol_new rx1_prim_inp0_mux =
292 SOC_DAPM_ENUM("WSA_RX1 INP0 Mux", rx1_prim_inp0_chain_enum);
293
294static const struct snd_kcontrol_new rx1_prim_inp1_mux =
295 SOC_DAPM_ENUM("WSA_RX1 INP1 Mux", rx1_prim_inp1_chain_enum);
296
297static const struct snd_kcontrol_new rx1_prim_inp2_mux =
298 SOC_DAPM_ENUM("WSA_RX1 INP2 Mux", rx1_prim_inp2_chain_enum);
299
300static const struct snd_kcontrol_new rx1_mix_mux =
301 SOC_DAPM_ENUM("WSA_RX1 MIX Mux", rx1_mix_chain_enum);
302
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +0530303static const struct soc_enum rx_mix_ec0_enum =
304 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0,
305 0, 3, rx_mix_ec_text);
306
307static const struct soc_enum rx_mix_ec1_enum =
308 SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0,
309 3, 3, rx_mix_ec_text);
310
311static const struct snd_kcontrol_new rx_mix_ec0_mux =
312 SOC_DAPM_ENUM("WSA RX_MIX EC0_Mux", rx_mix_ec0_enum);
313
314static const struct snd_kcontrol_new rx_mix_ec1_mux =
315 SOC_DAPM_ENUM("WSA RX_MIX EC1_Mux", rx_mix_ec1_enum);
316
Laxminath Kasam243e2752018-04-12 00:40:19 +0530317static struct snd_soc_dai_ops wsa_macro_dai_ops = {
318 .hw_params = wsa_macro_hw_params,
319 .get_channel_map = wsa_macro_get_channel_map,
320};
321
322static struct snd_soc_dai_driver wsa_macro_dai[] = {
323 {
324 .name = "wsa_macro_rx1",
325 .id = WSA_MACRO_AIF1_PB,
326 .playback = {
327 .stream_name = "WSA_AIF1 Playback",
328 .rates = WSA_MACRO_RX_RATES,
329 .formats = WSA_MACRO_RX_FORMATS,
330 .rate_max = 384000,
331 .rate_min = 8000,
332 .channels_min = 1,
333 .channels_max = 2,
334 },
335 .ops = &wsa_macro_dai_ops,
336 },
337 {
338 .name = "wsa_macro_rx_mix",
339 .id = WSA_MACRO_AIF_MIX1_PB,
340 .playback = {
341 .stream_name = "WSA_AIF_MIX1 Playback",
342 .rates = WSA_MACRO_RX_MIX_RATES,
343 .formats = WSA_MACRO_RX_FORMATS,
344 .rate_max = 192000,
345 .rate_min = 48000,
346 .channels_min = 1,
347 .channels_max = 2,
348 },
349 .ops = &wsa_macro_dai_ops,
350 },
351 {
352 .name = "wsa_macro_vifeedback",
353 .id = WSA_MACRO_AIF_VI,
354 .capture = {
355 .stream_name = "WSA_AIF_VI Capture",
356 .rates = SNDRV_PCM_RATE_8000,
357 .formats = SNDRV_PCM_FMTBIT_S32_LE,
358 .rate_max = 8000,
359 .rate_min = 8000,
360 .channels_min = 1,
361 .channels_max = 2,
362 },
363 .ops = &wsa_macro_dai_ops,
364 },
365 {
366 .name = "wsa_macro_echo",
367 .id = WSA_MACRO_AIF_ECHO,
368 .capture = {
369 .stream_name = "WSA_AIF_ECHO Capture",
370 .rates = WSA_MACRO_ECHO_RATES,
371 .formats = WSA_MACRO_ECHO_FORMATS,
372 .rate_max = 48000,
373 .rate_min = 8000,
374 .channels_min = 1,
375 .channels_max = 2,
376 },
377 .ops = &wsa_macro_dai_ops,
378 },
379};
380
381static const struct wsa_macro_reg_mask_val wsa_macro_spkr_default[] = {
382 {BOLERO_CDC_WSA_COMPANDER0_CTL3, 0x80, 0x80},
383 {BOLERO_CDC_WSA_COMPANDER1_CTL3, 0x80, 0x80},
384 {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x01, 0x01},
385 {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x01, 0x01},
386 {BOLERO_CDC_WSA_BOOST0_BOOST_CTL, 0x7C, 0x58},
387 {BOLERO_CDC_WSA_BOOST1_BOOST_CTL, 0x7C, 0x58},
388};
389
390static const struct wsa_macro_reg_mask_val wsa_macro_spkr_mode1[] = {
391 {BOLERO_CDC_WSA_COMPANDER0_CTL3, 0x80, 0x00},
392 {BOLERO_CDC_WSA_COMPANDER1_CTL3, 0x80, 0x00},
393 {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x01, 0x00},
394 {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x01, 0x00},
395 {BOLERO_CDC_WSA_BOOST0_BOOST_CTL, 0x7C, 0x44},
396 {BOLERO_CDC_WSA_BOOST1_BOOST_CTL, 0x7C, 0x44},
397};
398
399static bool wsa_macro_get_data(struct snd_soc_codec *codec,
400 struct device **wsa_dev,
401 struct wsa_macro_priv **wsa_priv,
402 const char *func_name)
403{
404 *wsa_dev = bolero_get_device_ptr(codec->dev, WSA_MACRO);
405 if (!(*wsa_dev)) {
406 dev_err(codec->dev,
407 "%s: null device for macro!\n", func_name);
408 return false;
409 }
410 *wsa_priv = dev_get_drvdata((*wsa_dev));
411 if (!(*wsa_priv) || !(*wsa_priv)->codec) {
412 dev_err(codec->dev,
413 "%s: priv is null for macro!\n", func_name);
414 return false;
415 }
416 return true;
417}
418
419/**
420 * wsa_macro_set_spkr_gain_offset - offset the speaker path
421 * gain with the given offset value.
422 *
423 * @codec: codec instance
424 * @offset: Indicates speaker path gain offset value.
425 *
426 * Returns 0 on success or -EINVAL on error.
427 */
428int wsa_macro_set_spkr_gain_offset(struct snd_soc_codec *codec, int offset)
429{
430 struct device *wsa_dev = NULL;
431 struct wsa_macro_priv *wsa_priv = NULL;
432
433 if (!codec) {
434 pr_err("%s: NULL codec pointer!\n", __func__);
435 return -EINVAL;
436 }
437
438 if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__))
439 return -EINVAL;
440
441 wsa_priv->spkr_gain_offset = offset;
442 return 0;
443}
444EXPORT_SYMBOL(wsa_macro_set_spkr_gain_offset);
445
446/**
447 * wsa_macro_set_spkr_mode - Configures speaker compander and smartboost
448 * settings based on speaker mode.
449 *
450 * @codec: codec instance
451 * @mode: Indicates speaker configuration mode.
452 *
453 * Returns 0 on success or -EINVAL on error.
454 */
455int wsa_macro_set_spkr_mode(struct snd_soc_codec *codec, int mode)
456{
457 int i;
458 const struct wsa_macro_reg_mask_val *regs;
459 int size;
460 struct device *wsa_dev = NULL;
461 struct wsa_macro_priv *wsa_priv = NULL;
462
463 if (!codec) {
464 pr_err("%s: NULL codec pointer!\n", __func__);
465 return -EINVAL;
466 }
467
468 if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__))
469 return -EINVAL;
470
471 switch (mode) {
Laxminath Kasam21c8b222018-06-21 18:47:22 +0530472 case WSA_MACRO_SPKR_MODE_1:
Laxminath Kasam243e2752018-04-12 00:40:19 +0530473 regs = wsa_macro_spkr_mode1;
474 size = ARRAY_SIZE(wsa_macro_spkr_mode1);
475 break;
476 default:
477 regs = wsa_macro_spkr_default;
478 size = ARRAY_SIZE(wsa_macro_spkr_default);
479 break;
480 }
481
482 wsa_priv->spkr_mode = mode;
483 for (i = 0; i < size; i++)
484 snd_soc_update_bits(codec, regs[i].reg,
485 regs[i].mask, regs[i].val);
486 return 0;
487}
488EXPORT_SYMBOL(wsa_macro_set_spkr_mode);
489
490static int wsa_macro_set_prim_interpolator_rate(struct snd_soc_dai *dai,
491 u8 int_prim_fs_rate_reg_val,
492 u32 sample_rate)
493{
494 u8 int_1_mix1_inp;
495 u32 j, port;
496 u16 int_mux_cfg0, int_mux_cfg1;
497 u16 int_fs_reg;
498 u8 int_mux_cfg0_val, int_mux_cfg1_val;
499 u8 inp0_sel, inp1_sel, inp2_sel;
500 struct snd_soc_codec *codec = dai->codec;
501 struct device *wsa_dev = NULL;
502 struct wsa_macro_priv *wsa_priv = NULL;
503
504 if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__))
505 return -EINVAL;
506
507 for_each_set_bit(port, &wsa_priv->active_ch_mask[dai->id],
508 WSA_MACRO_RX_MAX) {
509 int_1_mix1_inp = port;
510 if ((int_1_mix1_inp < WSA_MACRO_RX0) ||
511 (int_1_mix1_inp > WSA_MACRO_RX_MIX1)) {
512 dev_err(wsa_dev,
513 "%s: Invalid RX port, Dai ID is %d\n",
514 __func__, dai->id);
515 return -EINVAL;
516 }
517
518 int_mux_cfg0 = BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0;
519
520 /*
521 * Loop through all interpolator MUX inputs and find out
522 * to which interpolator input, the cdc_dma rx port
523 * is connected
524 */
525 for (j = 0; j < NUM_INTERPOLATORS; j++) {
526 int_mux_cfg1 = int_mux_cfg0 + WSA_MACRO_MUX_CFG1_OFFSET;
527
528 int_mux_cfg0_val = snd_soc_read(codec, int_mux_cfg0);
529 int_mux_cfg1_val = snd_soc_read(codec, int_mux_cfg1);
530 inp0_sel = int_mux_cfg0_val & WSA_MACRO_MUX_INP_MASK1;
531 inp1_sel = (int_mux_cfg0_val >>
532 WSA_MACRO_MUX_INP_SHFT) &
533 WSA_MACRO_MUX_INP_MASK2;
534 inp2_sel = (int_mux_cfg1_val >>
535 WSA_MACRO_MUX_INP_SHFT) &
536 WSA_MACRO_MUX_INP_MASK2;
537 if ((inp0_sel == int_1_mix1_inp) ||
538 (inp1_sel == int_1_mix1_inp) ||
539 (inp2_sel == int_1_mix1_inp)) {
540 int_fs_reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL +
541 WSA_MACRO_RX_PATH_OFFSET * j;
542 dev_dbg(wsa_dev,
543 "%s: AIF_PB DAI(%d) connected to INT%u_1\n",
544 __func__, dai->id, j);
545 dev_dbg(wsa_dev,
546 "%s: set INT%u_1 sample rate to %u\n",
547 __func__, j, sample_rate);
548 /* sample_rate is in Hz */
549 snd_soc_update_bits(codec, int_fs_reg,
550 WSA_MACRO_FS_RATE_MASK,
551 int_prim_fs_rate_reg_val);
552 }
553 int_mux_cfg0 += WSA_MACRO_MUX_CFG_OFFSET;
554 }
555 }
556
557 return 0;
558}
559
560static int wsa_macro_set_mix_interpolator_rate(struct snd_soc_dai *dai,
561 u8 int_mix_fs_rate_reg_val,
562 u32 sample_rate)
563{
564 u8 int_2_inp;
565 u32 j, port;
566 u16 int_mux_cfg1, int_fs_reg;
567 u8 int_mux_cfg1_val;
568 struct snd_soc_codec *codec = dai->codec;
569 struct device *wsa_dev = NULL;
570 struct wsa_macro_priv *wsa_priv = NULL;
571
572 if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__))
573 return -EINVAL;
574
575
576 for_each_set_bit(port, &wsa_priv->active_ch_mask[dai->id],
577 WSA_MACRO_RX_MAX) {
578 int_2_inp = port;
579 if ((int_2_inp < WSA_MACRO_RX0) ||
580 (int_2_inp > WSA_MACRO_RX_MIX1)) {
581 dev_err(wsa_dev,
582 "%s: Invalid RX port, Dai ID is %d\n",
583 __func__, dai->id);
584 return -EINVAL;
585 }
586
587 int_mux_cfg1 = BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG1;
588 for (j = 0; j < NUM_INTERPOLATORS; j++) {
589 int_mux_cfg1_val = snd_soc_read(codec, int_mux_cfg1) &
590 WSA_MACRO_MUX_INP_MASK1;
591 if (int_mux_cfg1_val == int_2_inp) {
592 int_fs_reg =
593 BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL +
594 WSA_MACRO_RX_PATH_OFFSET * j;
595
596 dev_dbg(wsa_dev,
597 "%s: AIF_PB DAI(%d) connected to INT%u_2\n",
598 __func__, dai->id, j);
599 dev_dbg(wsa_dev,
600 "%s: set INT%u_2 sample rate to %u\n",
601 __func__, j, sample_rate);
602 snd_soc_update_bits(codec, int_fs_reg,
603 WSA_MACRO_FS_RATE_MASK,
604 int_mix_fs_rate_reg_val);
605 }
606 int_mux_cfg1 += WSA_MACRO_MUX_CFG_OFFSET;
607 }
608 }
609 return 0;
610}
611
612static int wsa_macro_set_interpolator_rate(struct snd_soc_dai *dai,
613 u32 sample_rate)
614{
615 int rate_val = 0;
616 int i, ret;
617
618 /* set mixing path rate */
619 for (i = 0; i < ARRAY_SIZE(int_mix_sample_rate_val); i++) {
620 if (sample_rate ==
621 int_mix_sample_rate_val[i].sample_rate) {
622 rate_val =
623 int_mix_sample_rate_val[i].rate_val;
624 break;
625 }
626 }
627 if ((i == ARRAY_SIZE(int_mix_sample_rate_val)) ||
628 (rate_val < 0))
629 goto prim_rate;
630 ret = wsa_macro_set_mix_interpolator_rate(dai,
631 (u8) rate_val, sample_rate);
632prim_rate:
633 /* set primary path sample rate */
634 for (i = 0; i < ARRAY_SIZE(int_prim_sample_rate_val); i++) {
635 if (sample_rate ==
636 int_prim_sample_rate_val[i].sample_rate) {
637 rate_val =
638 int_prim_sample_rate_val[i].rate_val;
639 break;
640 }
641 }
642 if ((i == ARRAY_SIZE(int_prim_sample_rate_val)) ||
643 (rate_val < 0))
644 return -EINVAL;
645 ret = wsa_macro_set_prim_interpolator_rate(dai,
646 (u8) rate_val, sample_rate);
647 return ret;
648}
649
650static int wsa_macro_hw_params(struct snd_pcm_substream *substream,
651 struct snd_pcm_hw_params *params,
652 struct snd_soc_dai *dai)
653{
654 struct snd_soc_codec *codec = dai->codec;
655 int ret;
656
657 dev_dbg(codec->dev,
658 "%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__,
659 dai->name, dai->id, params_rate(params),
660 params_channels(params));
661
662 switch (substream->stream) {
663 case SNDRV_PCM_STREAM_PLAYBACK:
664 ret = wsa_macro_set_interpolator_rate(dai, params_rate(params));
665 if (ret) {
666 dev_err(codec->dev,
667 "%s: cannot set sample rate: %u\n",
668 __func__, params_rate(params));
669 return ret;
670 }
671 break;
672 case SNDRV_PCM_STREAM_CAPTURE:
673 default:
674 break;
675 }
676 return 0;
677}
678
679static int wsa_macro_get_channel_map(struct snd_soc_dai *dai,
680 unsigned int *tx_num, unsigned int *tx_slot,
681 unsigned int *rx_num, unsigned int *rx_slot)
682{
683 struct snd_soc_codec *codec = dai->codec;
684 struct device *wsa_dev = NULL;
685 struct wsa_macro_priv *wsa_priv = NULL;
686
687 if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__))
688 return -EINVAL;
689
690 wsa_priv = dev_get_drvdata(wsa_dev);
691 if (!wsa_priv)
692 return -EINVAL;
693
694 switch (dai->id) {
695 case WSA_MACRO_AIF_VI:
696 case WSA_MACRO_AIF_ECHO:
697 *tx_slot = wsa_priv->active_ch_mask[dai->id];
698 *tx_num = wsa_priv->active_ch_cnt[dai->id];
699 break;
700 case WSA_MACRO_AIF1_PB:
701 case WSA_MACRO_AIF_MIX1_PB:
702 *rx_slot = wsa_priv->active_ch_mask[dai->id];
703 *rx_num = wsa_priv->active_ch_cnt[dai->id];
704 break;
705 default:
706 dev_err(wsa_dev, "%s: Invalid AIF\n", __func__);
707 break;
708 }
709 return 0;
710}
711
712static int wsa_macro_mclk_enable(struct wsa_macro_priv *wsa_priv,
713 bool mclk_enable, bool dapm)
714{
715 struct regmap *regmap = dev_get_regmap(wsa_priv->dev->parent, NULL);
716 int ret = 0;
717
718 dev_dbg(wsa_priv->dev, "%s: mclk_enable = %u, dapm = %d clk_users= %d\n",
719 __func__, mclk_enable, dapm, wsa_priv->wsa_mclk_users);
720
721 mutex_lock(&wsa_priv->mclk_lock);
722 if (mclk_enable) {
723 wsa_priv->wsa_mclk_users++;
724 if (wsa_priv->wsa_mclk_users == 1) {
725 ret = bolero_request_clock(wsa_priv->dev,
726 WSA_MACRO, MCLK_MUX0, true);
727 if (ret < 0) {
728 dev_err(wsa_priv->dev,
729 "%s: wsa request clock enable failed\n",
730 __func__);
731 goto exit;
732 }
733 regcache_mark_dirty(regmap);
734 regcache_sync_region(regmap,
735 WSA_START_OFFSET,
736 WSA_MAX_OFFSET);
737 /* 9.6MHz MCLK, set value 0x00 if other frequency */
738 regmap_update_bits(regmap,
739 BOLERO_CDC_WSA_TOP_FREQ_MCLK, 0x01, 0x01);
740 regmap_update_bits(regmap,
741 BOLERO_CDC_WSA_CLK_RST_CTRL_MCLK_CONTROL,
742 0x01, 0x01);
743 regmap_update_bits(regmap,
744 BOLERO_CDC_WSA_CLK_RST_CTRL_FS_CNT_CONTROL,
745 0x01, 0x01);
746 }
747 } else {
748 wsa_priv->wsa_mclk_users--;
749 if (wsa_priv->wsa_mclk_users == 0) {
750 regmap_update_bits(regmap,
751 BOLERO_CDC_WSA_CLK_RST_CTRL_FS_CNT_CONTROL,
752 0x01, 0x00);
753 regmap_update_bits(regmap,
754 BOLERO_CDC_WSA_CLK_RST_CTRL_MCLK_CONTROL,
755 0x01, 0x00);
756 bolero_request_clock(wsa_priv->dev,
757 WSA_MACRO, MCLK_MUX0, false);
758 }
759 }
760exit:
761 mutex_unlock(&wsa_priv->mclk_lock);
762 return ret;
763}
764
765static int wsa_macro_mclk_event(struct snd_soc_dapm_widget *w,
766 struct snd_kcontrol *kcontrol, int event)
767{
768 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
769 int ret = 0;
770 struct device *wsa_dev = NULL;
771 struct wsa_macro_priv *wsa_priv = NULL;
772
773 if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__))
774 return -EINVAL;
775
776 dev_dbg(wsa_dev, "%s: event = %d\n", __func__, event);
777 switch (event) {
778 case SND_SOC_DAPM_PRE_PMU:
779 ret = wsa_macro_mclk_enable(wsa_priv, 1, true);
780 break;
781 case SND_SOC_DAPM_POST_PMD:
782 wsa_macro_mclk_enable(wsa_priv, 0, true);
783 break;
784 default:
785 dev_err(wsa_priv->dev,
786 "%s: invalid DAPM event %d\n", __func__, event);
787 ret = -EINVAL;
788 }
789 return ret;
790}
791
792static int wsa_macro_mclk_ctrl(struct device *dev, bool enable)
793{
794 struct wsa_macro_priv *wsa_priv = dev_get_drvdata(dev);
795 int ret = 0;
796
797 if (!wsa_priv)
798 return -EINVAL;
799
800 if (enable) {
801 ret = clk_prepare_enable(wsa_priv->wsa_core_clk);
802 if (ret < 0) {
803 dev_err(dev, "%s:wsa mclk enable failed\n", __func__);
804 goto exit;
805 }
806 ret = clk_prepare_enable(wsa_priv->wsa_npl_clk);
807 if (ret < 0) {
808 dev_err(dev, "%s:wsa npl_clk enable failed\n",
809 __func__);
810 clk_disable_unprepare(wsa_priv->wsa_core_clk);
811 goto exit;
812 }
813 } else {
814 clk_disable_unprepare(wsa_priv->wsa_npl_clk);
815 clk_disable_unprepare(wsa_priv->wsa_core_clk);
816 }
817exit:
818 return ret;
819}
820
821static int wsa_macro_enable_vi_feedback(struct snd_soc_dapm_widget *w,
822 struct snd_kcontrol *kcontrol,
823 int event)
824{
825 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
826 struct device *wsa_dev = NULL;
827 struct wsa_macro_priv *wsa_priv = NULL;
828
829 if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__))
830 return -EINVAL;
831
832 switch (event) {
833 case SND_SOC_DAPM_POST_PMU:
834 if (test_bit(WSA_MACRO_TX0,
835 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
836 dev_dbg(wsa_dev, "%s: spkr1 enabled\n", __func__);
837 /* Enable V&I sensing */
838 snd_soc_update_bits(codec,
839 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
840 0x20, 0x20);
841 snd_soc_update_bits(codec,
842 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
843 0x20, 0x20);
844 snd_soc_update_bits(codec,
845 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
846 0x0F, 0x00);
847 snd_soc_update_bits(codec,
848 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
849 0x0F, 0x00);
850 snd_soc_update_bits(codec,
851 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
852 0x10, 0x10);
853 snd_soc_update_bits(codec,
854 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
855 0x10, 0x10);
856 snd_soc_update_bits(codec,
857 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
858 0x20, 0x00);
859 snd_soc_update_bits(codec,
860 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
861 0x20, 0x00);
862 }
863 if (test_bit(WSA_MACRO_TX1,
864 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
865 dev_dbg(wsa_dev, "%s: spkr2 enabled\n", __func__);
866 /* Enable V&I sensing */
867 snd_soc_update_bits(codec,
868 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
869 0x20, 0x20);
870 snd_soc_update_bits(codec,
871 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
872 0x20, 0x20);
873 snd_soc_update_bits(codec,
874 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
875 0x0F, 0x00);
876 snd_soc_update_bits(codec,
877 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
878 0x0F, 0x00);
879 snd_soc_update_bits(codec,
880 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
881 0x10, 0x10);
882 snd_soc_update_bits(codec,
883 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
884 0x10, 0x10);
885 snd_soc_update_bits(codec,
886 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
887 0x20, 0x00);
888 snd_soc_update_bits(codec,
889 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
890 0x20, 0x00);
891 }
892 break;
893 case SND_SOC_DAPM_POST_PMD:
894 if (test_bit(WSA_MACRO_TX0,
895 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
896 /* Disable V&I sensing */
897 snd_soc_update_bits(codec,
898 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
899 0x20, 0x20);
900 snd_soc_update_bits(codec,
901 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
902 0x20, 0x20);
903 dev_dbg(wsa_dev, "%s: spkr1 disabled\n", __func__);
904 snd_soc_update_bits(codec,
905 BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
906 0x10, 0x00);
907 snd_soc_update_bits(codec,
908 BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
909 0x10, 0x00);
910 }
911 if (test_bit(WSA_MACRO_TX1,
912 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
913 /* Disable V&I sensing */
914 dev_dbg(wsa_dev, "%s: spkr2 disabled\n", __func__);
915 snd_soc_update_bits(codec,
916 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
917 0x20, 0x20);
918 snd_soc_update_bits(codec,
919 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
920 0x20, 0x20);
921 snd_soc_update_bits(codec,
922 BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
923 0x10, 0x00);
924 snd_soc_update_bits(codec,
925 BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
926 0x10, 0x00);
927 }
928 break;
929 }
930
931 return 0;
932}
933
934static int wsa_macro_enable_mix_path(struct snd_soc_dapm_widget *w,
935 struct snd_kcontrol *kcontrol, int event)
936{
937 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
938 u16 gain_reg;
939 int offset_val = 0;
940 int val = 0;
941
942 dev_dbg(codec->dev, "%s %d %s\n", __func__, event, w->name);
943
944 switch (w->reg) {
945 case BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL:
946 gain_reg = BOLERO_CDC_WSA_RX0_RX_VOL_MIX_CTL;
947 break;
948 case BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL:
949 gain_reg = BOLERO_CDC_WSA_RX1_RX_VOL_MIX_CTL;
950 break;
951 default:
952 dev_err(codec->dev, "%s: No gain register avail for %s\n",
953 __func__, w->name);
954 return 0;
955 }
956
957 switch (event) {
958 case SND_SOC_DAPM_POST_PMU:
959 val = snd_soc_read(codec, gain_reg);
960 val += offset_val;
961 snd_soc_write(codec, gain_reg, val);
962 break;
963 case SND_SOC_DAPM_POST_PMD:
964 break;
965 }
966
967 return 0;
968}
969
970static void wsa_macro_hd2_control(struct snd_soc_codec *codec,
971 u16 reg, int event)
972{
973 u16 hd2_scale_reg;
974 u16 hd2_enable_reg = 0;
975
976 if (reg == BOLERO_CDC_WSA_RX0_RX_PATH_CTL) {
977 hd2_scale_reg = BOLERO_CDC_WSA_RX0_RX_PATH_SEC3;
978 hd2_enable_reg = BOLERO_CDC_WSA_RX0_RX_PATH_CFG0;
979 }
980 if (reg == BOLERO_CDC_WSA_RX1_RX_PATH_CTL) {
981 hd2_scale_reg = BOLERO_CDC_WSA_RX1_RX_PATH_SEC3;
982 hd2_enable_reg = BOLERO_CDC_WSA_RX1_RX_PATH_CFG0;
983 }
984
985 if (hd2_enable_reg && SND_SOC_DAPM_EVENT_ON(event)) {
986 snd_soc_update_bits(codec, hd2_scale_reg, 0x3C, 0x10);
987 snd_soc_update_bits(codec, hd2_scale_reg, 0x03, 0x01);
988 snd_soc_update_bits(codec, hd2_enable_reg, 0x04, 0x04);
989 }
990
991 if (hd2_enable_reg && SND_SOC_DAPM_EVENT_OFF(event)) {
992 snd_soc_update_bits(codec, hd2_enable_reg, 0x04, 0x00);
993 snd_soc_update_bits(codec, hd2_scale_reg, 0x03, 0x00);
994 snd_soc_update_bits(codec, hd2_scale_reg, 0x3C, 0x00);
995 }
996}
997
998static int wsa_macro_enable_swr(struct snd_soc_dapm_widget *w,
999 struct snd_kcontrol *kcontrol, int event)
1000{
1001 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1002 int ch_cnt;
1003 struct device *wsa_dev = NULL;
1004 struct wsa_macro_priv *wsa_priv = NULL;
1005
1006 if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__))
1007 return -EINVAL;
1008
1009 switch (event) {
1010 case SND_SOC_DAPM_PRE_PMU:
1011 if (!(strnstr(w->name, "RX0", sizeof("WSA_RX0"))) &&
1012 !wsa_priv->rx_0_count)
1013 wsa_priv->rx_0_count++;
1014 if (!(strnstr(w->name, "RX1", sizeof("WSA_RX1"))) &&
1015 !wsa_priv->rx_1_count)
1016 wsa_priv->rx_1_count++;
1017 ch_cnt = wsa_priv->rx_0_count + wsa_priv->rx_1_count;
1018
1019 swrm_wcd_notify(
1020 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
1021 SWR_DEVICE_UP, NULL);
1022 swrm_wcd_notify(
1023 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
1024 SWR_SET_NUM_RX_CH, &ch_cnt);
1025 break;
1026 case SND_SOC_DAPM_POST_PMD:
1027 if (!(strnstr(w->name, "RX0", sizeof("WSA_RX0"))) &&
1028 wsa_priv->rx_0_count)
1029 wsa_priv->rx_0_count--;
1030 if (!(strnstr(w->name, "RX1", sizeof("WSA_RX1"))) &&
1031 wsa_priv->rx_1_count)
1032 wsa_priv->rx_1_count--;
1033 ch_cnt = wsa_priv->rx_0_count + wsa_priv->rx_1_count;
1034
1035 swrm_wcd_notify(
1036 wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
1037 SWR_SET_NUM_RX_CH, &ch_cnt);
1038 break;
1039 }
1040 dev_dbg(wsa_priv->dev, "%s: current swr ch cnt: %d\n",
1041 __func__, wsa_priv->rx_0_count + wsa_priv->rx_1_count);
1042
1043 return 0;
1044}
1045
1046static int wsa_macro_config_compander(struct snd_soc_codec *codec,
1047 int comp, int event)
1048{
1049 u16 comp_ctl0_reg, rx_path_cfg0_reg;
1050 struct device *wsa_dev = NULL;
1051 struct wsa_macro_priv *wsa_priv = NULL;
1052
1053 if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__))
1054 return -EINVAL;
1055
1056 dev_dbg(codec->dev, "%s: event %d compander %d, enabled %d\n",
1057 __func__, event, comp + 1, wsa_priv->comp_enabled[comp]);
1058
1059 if (!wsa_priv->comp_enabled[comp])
1060 return 0;
1061
1062 comp_ctl0_reg = BOLERO_CDC_WSA_COMPANDER0_CTL0 +
1063 (comp * WSA_MACRO_RX_COMP_OFFSET);
1064 rx_path_cfg0_reg = BOLERO_CDC_WSA_RX0_RX_PATH_CFG0 +
1065 (comp * WSA_MACRO_RX_PATH_OFFSET);
1066
1067 if (SND_SOC_DAPM_EVENT_ON(event)) {
1068 /* Enable Compander Clock */
1069 snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x01);
1070 snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02);
1071 snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00);
1072 snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x02);
1073 }
1074
1075 if (SND_SOC_DAPM_EVENT_OFF(event)) {
1076 snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x04);
1077 snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x00);
1078 snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02);
1079 snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00);
1080 snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x00);
1081 snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x00);
1082 }
1083
1084 return 0;
1085}
1086
1087static int wsa_macro_interp_get_primary_reg(u16 reg, u16 *ind)
1088{
1089 u16 prim_int_reg = 0;
1090
1091 switch (reg) {
1092 case BOLERO_CDC_WSA_RX0_RX_PATH_CTL:
1093 case BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL:
1094 prim_int_reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL;
1095 *ind = 0;
1096 break;
1097 case BOLERO_CDC_WSA_RX1_RX_PATH_CTL:
1098 case BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL:
1099 prim_int_reg = BOLERO_CDC_WSA_RX1_RX_PATH_CTL;
1100 *ind = 1;
1101 break;
1102 }
1103
1104 return prim_int_reg;
1105}
1106
1107static int wsa_macro_enable_prim_interpolator(
1108 struct snd_soc_codec *codec,
1109 u16 reg, int event)
1110{
1111 u16 prim_int_reg;
1112 u16 ind = 0;
1113 struct device *wsa_dev = NULL;
1114 struct wsa_macro_priv *wsa_priv = NULL;
1115
1116 if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__))
1117 return -EINVAL;
1118
1119 prim_int_reg = wsa_macro_interp_get_primary_reg(reg, &ind);
1120
1121 switch (event) {
1122 case SND_SOC_DAPM_PRE_PMU:
1123 wsa_priv->prim_int_users[ind]++;
1124 if (wsa_priv->prim_int_users[ind] == 1) {
1125 snd_soc_update_bits(codec,
1126 prim_int_reg + WSA_MACRO_RX_PATH_CFG3_OFFSET,
1127 0x03, 0x03);
1128 snd_soc_update_bits(codec, prim_int_reg,
1129 0x10, 0x10);
1130 wsa_macro_hd2_control(codec, prim_int_reg, event);
1131 snd_soc_update_bits(codec,
1132 prim_int_reg + WSA_MACRO_RX_PATH_DSMDEM_OFFSET,
1133 0x1, 0x1);
1134 snd_soc_update_bits(codec, prim_int_reg,
1135 1 << 0x5, 1 << 0x5);
1136 }
1137 if ((reg != prim_int_reg) &&
1138 ((snd_soc_read(codec, prim_int_reg)) & 0x10))
1139 snd_soc_update_bits(codec, reg, 0x10, 0x10);
1140 break;
1141 case SND_SOC_DAPM_POST_PMD:
1142 wsa_priv->prim_int_users[ind]--;
1143 if (wsa_priv->prim_int_users[ind] == 0) {
1144 snd_soc_update_bits(codec, prim_int_reg,
1145 1 << 0x5, 0 << 0x5);
1146 snd_soc_update_bits(codec, prim_int_reg,
1147 0x40, 0x40);
1148 snd_soc_update_bits(codec, prim_int_reg,
1149 0x40, 0x00);
1150 wsa_macro_hd2_control(codec, prim_int_reg, event);
1151 }
1152 break;
1153 }
1154
1155 dev_dbg(codec->dev, "%s: primary interpolator: INT%d, users: %d\n",
1156 __func__, ind, wsa_priv->prim_int_users[ind]);
1157 return 0;
1158}
1159
1160static int wsa_macro_enable_interpolator(struct snd_soc_dapm_widget *w,
1161 struct snd_kcontrol *kcontrol,
1162 int event)
1163{
1164 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1165 u16 gain_reg;
1166 u16 reg;
1167 int val;
1168 int offset_val = 0;
1169 struct device *wsa_dev = NULL;
1170 struct wsa_macro_priv *wsa_priv = NULL;
1171
1172 if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__))
1173 return -EINVAL;
1174
1175 dev_dbg(codec->dev, "%s %d %s\n", __func__, event, w->name);
1176
1177 if (!(strcmp(w->name, "WSA_RX INT0 INTERP"))) {
1178 reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL;
1179 gain_reg = BOLERO_CDC_WSA_RX0_RX_VOL_CTL;
1180 } else if (!(strcmp(w->name, "WSA_RX INT1 INTERP"))) {
1181 reg = BOLERO_CDC_WSA_RX1_RX_PATH_CTL;
1182 gain_reg = BOLERO_CDC_WSA_RX1_RX_VOL_CTL;
1183 } else {
1184 dev_err(codec->dev, "%s: Interpolator reg not found\n",
1185 __func__);
1186 return -EINVAL;
1187 }
1188
1189 switch (event) {
1190 case SND_SOC_DAPM_PRE_PMU:
1191 /* Reset if needed */
1192 wsa_macro_enable_prim_interpolator(codec, reg, event);
1193 break;
1194 case SND_SOC_DAPM_POST_PMU:
1195 wsa_macro_config_compander(codec, w->shift, event);
1196 /* apply gain after int clk is enabled */
Laxminath Kasam21c8b222018-06-21 18:47:22 +05301197 if ((wsa_priv->spkr_gain_offset ==
1198 WSA_MACRO_GAIN_OFFSET_M1P5_DB) &&
Laxminath Kasam243e2752018-04-12 00:40:19 +05301199 (wsa_priv->comp_enabled[WSA_MACRO_COMP1] ||
1200 wsa_priv->comp_enabled[WSA_MACRO_COMP2]) &&
1201 (gain_reg == BOLERO_CDC_WSA_RX0_RX_VOL_CTL ||
1202 gain_reg == BOLERO_CDC_WSA_RX1_RX_VOL_CTL)) {
1203 snd_soc_update_bits(codec, BOLERO_CDC_WSA_RX0_RX_PATH_SEC1,
1204 0x01, 0x01);
1205 snd_soc_update_bits(codec,
1206 BOLERO_CDC_WSA_RX0_RX_PATH_MIX_SEC0,
1207 0x01, 0x01);
1208 snd_soc_update_bits(codec, BOLERO_CDC_WSA_RX1_RX_PATH_SEC1,
1209 0x01, 0x01);
1210 snd_soc_update_bits(codec,
1211 BOLERO_CDC_WSA_RX1_RX_PATH_MIX_SEC0,
1212 0x01, 0x01);
1213 offset_val = -2;
1214 }
1215 val = snd_soc_read(codec, gain_reg);
1216 val += offset_val;
1217 snd_soc_write(codec, gain_reg, val);
1218 wsa_macro_config_ear_spkr_gain(codec, wsa_priv,
1219 event, gain_reg);
1220 break;
1221 case SND_SOC_DAPM_POST_PMD:
1222 wsa_macro_config_compander(codec, w->shift, event);
1223 wsa_macro_enable_prim_interpolator(codec, reg, event);
Laxminath Kasam21c8b222018-06-21 18:47:22 +05301224 if ((wsa_priv->spkr_gain_offset ==
1225 WSA_MACRO_GAIN_OFFSET_M1P5_DB) &&
Laxminath Kasam243e2752018-04-12 00:40:19 +05301226 (wsa_priv->comp_enabled[WSA_MACRO_COMP1] ||
1227 wsa_priv->comp_enabled[WSA_MACRO_COMP2]) &&
1228 (gain_reg == BOLERO_CDC_WSA_RX0_RX_VOL_CTL ||
1229 gain_reg == BOLERO_CDC_WSA_RX1_RX_VOL_CTL)) {
1230 snd_soc_update_bits(codec, BOLERO_CDC_WSA_RX0_RX_PATH_SEC1,
1231 0x01, 0x00);
1232 snd_soc_update_bits(codec,
1233 BOLERO_CDC_WSA_RX0_RX_PATH_MIX_SEC0,
1234 0x01, 0x00);
1235 snd_soc_update_bits(codec, BOLERO_CDC_WSA_RX1_RX_PATH_SEC1,
1236 0x01, 0x00);
1237 snd_soc_update_bits(codec,
1238 BOLERO_CDC_WSA_RX1_RX_PATH_MIX_SEC0,
1239 0x01, 0x00);
1240 offset_val = 2;
1241 val = snd_soc_read(codec, gain_reg);
1242 val += offset_val;
1243 snd_soc_write(codec, gain_reg, val);
1244 }
1245 wsa_macro_config_ear_spkr_gain(codec, wsa_priv,
1246 event, gain_reg);
1247 break;
1248 }
1249
1250 return 0;
1251}
1252
1253static int wsa_macro_config_ear_spkr_gain(struct snd_soc_codec *codec,
1254 struct wsa_macro_priv *wsa_priv,
1255 int event, int gain_reg)
1256{
1257 int comp_gain_offset, val;
1258
1259 switch (wsa_priv->spkr_mode) {
Laxminath Kasam21c8b222018-06-21 18:47:22 +05301260 /* Compander gain in WSA_MACRO_SPKR_MODE1 case is 12 dB */
1261 case WSA_MACRO_SPKR_MODE_1:
Laxminath Kasam243e2752018-04-12 00:40:19 +05301262 comp_gain_offset = -12;
1263 break;
1264 /* Default case compander gain is 15 dB */
1265 default:
1266 comp_gain_offset = -15;
1267 break;
1268 }
1269
1270 switch (event) {
1271 case SND_SOC_DAPM_POST_PMU:
1272 /* Apply ear spkr gain only if compander is enabled */
1273 if (wsa_priv->comp_enabled[WSA_MACRO_COMP1] &&
1274 (gain_reg == BOLERO_CDC_WSA_RX0_RX_VOL_CTL) &&
1275 (wsa_priv->ear_spkr_gain != 0)) {
1276 /* For example, val is -8(-12+5-1) for 4dB of gain */
1277 val = comp_gain_offset + wsa_priv->ear_spkr_gain - 1;
1278 snd_soc_write(codec, gain_reg, val);
1279
1280 dev_dbg(wsa_priv->dev, "%s: RX0 Volume %d dB\n",
1281 __func__, val);
1282 }
1283 break;
1284 case SND_SOC_DAPM_POST_PMD:
1285 /*
1286 * Reset RX0 volume to 0 dB if compander is enabled and
1287 * ear_spkr_gain is non-zero.
1288 */
1289 if (wsa_priv->comp_enabled[WSA_MACRO_COMP1] &&
1290 (gain_reg == BOLERO_CDC_WSA_RX0_RX_VOL_CTL) &&
1291 (wsa_priv->ear_spkr_gain != 0)) {
1292 snd_soc_write(codec, gain_reg, 0x0);
1293
1294 dev_dbg(wsa_priv->dev, "%s: Reset RX0 Volume to 0 dB\n",
1295 __func__);
1296 }
1297 break;
1298 }
1299
1300 return 0;
1301}
1302
1303static int wsa_macro_spk_boost_event(struct snd_soc_dapm_widget *w,
1304 struct snd_kcontrol *kcontrol,
1305 int event)
1306{
1307 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1308 u16 boost_path_ctl, boost_path_cfg1;
1309 u16 reg, reg_mix;
1310
1311 dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
1312
1313 if (!strcmp(w->name, "WSA_RX INT0 CHAIN")) {
1314 boost_path_ctl = BOLERO_CDC_WSA_BOOST0_BOOST_PATH_CTL;
1315 boost_path_cfg1 = BOLERO_CDC_WSA_RX0_RX_PATH_CFG1;
1316 reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL;
1317 reg_mix = BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL;
1318 } else if (!strcmp(w->name, "WSA_RX INT1 CHAIN")) {
1319 boost_path_ctl = BOLERO_CDC_WSA_BOOST1_BOOST_PATH_CTL;
1320 boost_path_cfg1 = BOLERO_CDC_WSA_RX1_RX_PATH_CFG1;
1321 reg = BOLERO_CDC_WSA_RX1_RX_PATH_CTL;
1322 reg_mix = BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL;
1323 } else {
1324 dev_err(codec->dev, "%s: unknown widget: %s\n",
1325 __func__, w->name);
1326 return -EINVAL;
1327 }
1328
1329 switch (event) {
1330 case SND_SOC_DAPM_PRE_PMU:
1331 snd_soc_update_bits(codec, boost_path_cfg1, 0x01, 0x01);
1332 snd_soc_update_bits(codec, boost_path_ctl, 0x10, 0x10);
Laxminath Kasam243e2752018-04-12 00:40:19 +05301333 if ((snd_soc_read(codec, reg_mix)) & 0x10)
1334 snd_soc_update_bits(codec, reg_mix, 0x10, 0x00);
1335 break;
Laxminath Kasam0c857002018-07-17 23:47:17 +05301336 case SND_SOC_DAPM_POST_PMU:
1337 snd_soc_update_bits(codec, reg, 0x10, 0x00);
1338 break;
Laxminath Kasam243e2752018-04-12 00:40:19 +05301339 case SND_SOC_DAPM_POST_PMD:
1340 snd_soc_update_bits(codec, boost_path_ctl, 0x10, 0x00);
1341 snd_soc_update_bits(codec, boost_path_cfg1, 0x01, 0x00);
1342 break;
1343 }
1344
1345 return 0;
1346}
1347
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301348static int wsa_macro_enable_echo(struct snd_soc_dapm_widget *w,
1349 struct snd_kcontrol *kcontrol,
1350 int event)
1351{
1352 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1353 struct device *wsa_dev = NULL;
1354 struct wsa_macro_priv *wsa_priv = NULL;
1355 u16 val, ec_tx = 0, ec_hq_reg;
1356
1357 if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__))
1358 return -EINVAL;
1359
1360 dev_dbg(wsa_dev, "%s %d %s\n", __func__, event, w->name);
1361
1362 val = snd_soc_read(codec, BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0);
1363 if (!(strcmp(w->name, "WSA RX_MIX EC0_MUX")))
1364 ec_tx = (val & 0x07) - 1;
1365 else
1366 ec_tx = ((val & 0x38) >> 0x3) - 1;
1367
1368 if (ec_tx < 0 || ec_tx >= (WSA_MACRO_RX1 + 1)) {
1369 dev_err(wsa_dev, "%s: EC mix control not set correctly\n",
1370 __func__);
1371 return -EINVAL;
1372 }
1373 if (wsa_priv->ec_hq[ec_tx]) {
1374 snd_soc_update_bits(codec,
1375 BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0,
1376 0x1 << ec_tx, 0x1 << ec_tx);
1377 ec_hq_reg = BOLERO_CDC_WSA_EC_HQ0_EC_REF_HQ_PATH_CTL +
1378 0x20 * ec_tx;
1379 snd_soc_update_bits(codec, ec_hq_reg, 0x01, 0x01);
1380 ec_hq_reg = BOLERO_CDC_WSA_EC_HQ0_EC_REF_HQ_CFG0 +
1381 0x20 * ec_tx;
1382 /* default set to 48k */
1383 snd_soc_update_bits(codec, ec_hq_reg, 0x1E, 0x08);
1384 }
1385
1386 return 0;
1387}
1388
1389static int wsa_macro_get_ec_hq(struct snd_kcontrol *kcontrol,
1390 struct snd_ctl_elem_value *ucontrol)
1391{
1392
1393 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
1394 int ec_tx = ((struct soc_multi_mixer_control *)
1395 kcontrol->private_value)->shift;
1396 struct device *wsa_dev = NULL;
1397 struct wsa_macro_priv *wsa_priv = NULL;
1398
1399 if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__))
1400 return -EINVAL;
1401
1402 ucontrol->value.integer.value[0] = wsa_priv->ec_hq[ec_tx];
1403 return 0;
1404}
1405
1406static int wsa_macro_set_ec_hq(struct snd_kcontrol *kcontrol,
1407 struct snd_ctl_elem_value *ucontrol)
1408{
1409 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
1410 int ec_tx = ((struct soc_multi_mixer_control *)
1411 kcontrol->private_value)->shift;
1412 int value = ucontrol->value.integer.value[0];
1413 struct device *wsa_dev = NULL;
1414 struct wsa_macro_priv *wsa_priv = NULL;
1415
1416 if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__))
1417 return -EINVAL;
1418
1419 dev_dbg(wsa_dev, "%s: enable current %d, new %d\n",
1420 __func__, wsa_priv->ec_hq[ec_tx], value);
1421 wsa_priv->ec_hq[ec_tx] = value;
1422
1423 return 0;
1424}
1425
Laxminath Kasam243e2752018-04-12 00:40:19 +05301426static int wsa_macro_get_compander(struct snd_kcontrol *kcontrol,
1427 struct snd_ctl_elem_value *ucontrol)
1428{
1429
1430 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
1431 int comp = ((struct soc_multi_mixer_control *)
1432 kcontrol->private_value)->shift;
1433 struct device *wsa_dev = NULL;
1434 struct wsa_macro_priv *wsa_priv = NULL;
1435
1436 if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__))
1437 return -EINVAL;
1438
1439 ucontrol->value.integer.value[0] = wsa_priv->comp_enabled[comp];
1440 return 0;
1441}
1442
1443static int wsa_macro_set_compander(struct snd_kcontrol *kcontrol,
1444 struct snd_ctl_elem_value *ucontrol)
1445{
1446 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
1447 int comp = ((struct soc_multi_mixer_control *)
1448 kcontrol->private_value)->shift;
1449 int value = ucontrol->value.integer.value[0];
1450 struct device *wsa_dev = NULL;
1451 struct wsa_macro_priv *wsa_priv = NULL;
1452
1453 if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__))
1454 return -EINVAL;
1455
1456 dev_dbg(codec->dev, "%s: Compander %d enable current %d, new %d\n",
1457 __func__, comp + 1, wsa_priv->comp_enabled[comp], value);
1458 wsa_priv->comp_enabled[comp] = value;
1459
1460 return 0;
1461}
1462
1463static int wsa_macro_ear_spkr_pa_gain_get(struct snd_kcontrol *kcontrol,
1464 struct snd_ctl_elem_value *ucontrol)
1465{
1466 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
1467 struct device *wsa_dev = NULL;
1468 struct wsa_macro_priv *wsa_priv = NULL;
1469
1470 if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__))
1471 return -EINVAL;
1472
1473 ucontrol->value.integer.value[0] = wsa_priv->ear_spkr_gain;
1474
1475 dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
1476 __func__, ucontrol->value.integer.value[0]);
1477
1478 return 0;
1479}
1480
1481static int wsa_macro_ear_spkr_pa_gain_put(struct snd_kcontrol *kcontrol,
1482 struct snd_ctl_elem_value *ucontrol)
1483{
1484 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
1485 struct device *wsa_dev = NULL;
1486 struct wsa_macro_priv *wsa_priv = NULL;
1487
1488 if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__))
1489 return -EINVAL;
1490
1491 wsa_priv->ear_spkr_gain = ucontrol->value.integer.value[0];
1492
1493 dev_dbg(codec->dev, "%s: gain = %d\n", __func__,
1494 wsa_priv->ear_spkr_gain);
1495
1496 return 0;
1497}
1498
1499static int wsa_macro_spkr_left_boost_stage_get(struct snd_kcontrol *kcontrol,
1500 struct snd_ctl_elem_value *ucontrol)
1501{
1502 u8 bst_state_max = 0;
1503 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
1504
1505 bst_state_max = snd_soc_read(codec, BOLERO_CDC_WSA_BOOST0_BOOST_CTL);
1506 bst_state_max = (bst_state_max & 0x0c) >> 2;
1507 ucontrol->value.integer.value[0] = bst_state_max;
1508 dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
1509 __func__, ucontrol->value.integer.value[0]);
1510
1511 return 0;
1512}
1513
1514static int wsa_macro_spkr_left_boost_stage_put(struct snd_kcontrol *kcontrol,
1515 struct snd_ctl_elem_value *ucontrol)
1516{
1517 u8 bst_state_max;
1518 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
1519
1520 dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
1521 __func__, ucontrol->value.integer.value[0]);
1522 bst_state_max = ucontrol->value.integer.value[0] << 2;
1523 snd_soc_update_bits(codec, BOLERO_CDC_WSA_BOOST0_BOOST_CTL,
1524 0x0c, bst_state_max);
1525
1526 return 0;
1527}
1528
1529static int wsa_macro_spkr_right_boost_stage_get(struct snd_kcontrol *kcontrol,
1530 struct snd_ctl_elem_value *ucontrol)
1531{
1532 u8 bst_state_max = 0;
1533 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
1534
1535 bst_state_max = snd_soc_read(codec, BOLERO_CDC_WSA_BOOST1_BOOST_CTL);
1536 bst_state_max = (bst_state_max & 0x0c) >> 2;
1537 ucontrol->value.integer.value[0] = bst_state_max;
1538 dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
1539 __func__, ucontrol->value.integer.value[0]);
1540
1541 return 0;
1542}
1543
1544static int wsa_macro_spkr_right_boost_stage_put(struct snd_kcontrol *kcontrol,
1545 struct snd_ctl_elem_value *ucontrol)
1546{
1547 u8 bst_state_max;
1548 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
1549
1550 dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
1551 __func__, ucontrol->value.integer.value[0]);
1552 bst_state_max = ucontrol->value.integer.value[0] << 2;
1553 snd_soc_update_bits(codec, BOLERO_CDC_WSA_BOOST1_BOOST_CTL,
1554 0x0c, bst_state_max);
1555
1556 return 0;
1557}
1558
1559static int wsa_macro_rx_mux_get(struct snd_kcontrol *kcontrol,
1560 struct snd_ctl_elem_value *ucontrol)
1561{
1562 struct snd_soc_dapm_widget *widget =
1563 snd_soc_dapm_kcontrol_widget(kcontrol);
1564 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
1565 struct device *wsa_dev = NULL;
1566 struct wsa_macro_priv *wsa_priv = NULL;
1567
1568 if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__))
1569 return -EINVAL;
1570
1571 ucontrol->value.integer.value[0] =
1572 wsa_priv->rx_port_value[widget->shift];
1573 return 0;
1574}
1575
1576static int wsa_macro_rx_mux_put(struct snd_kcontrol *kcontrol,
1577 struct snd_ctl_elem_value *ucontrol)
1578{
1579 struct snd_soc_dapm_widget *widget =
1580 snd_soc_dapm_kcontrol_widget(kcontrol);
1581 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
1582 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1583 struct snd_soc_dapm_update *update = NULL;
1584 u32 rx_port_value = ucontrol->value.integer.value[0];
1585 u32 bit_input = 0;
1586 u32 aif_rst;
1587 struct device *wsa_dev = NULL;
1588 struct wsa_macro_priv *wsa_priv = NULL;
1589
1590 if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__))
1591 return -EINVAL;
1592
1593 aif_rst = wsa_priv->rx_port_value[widget->shift];
1594 if (!rx_port_value) {
1595 if (aif_rst == 0) {
1596 dev_err(wsa_dev, "%s: AIF reset already\n", __func__);
1597 return 0;
1598 }
1599 }
1600 wsa_priv->rx_port_value[widget->shift] = rx_port_value;
1601
1602 bit_input = widget->shift;
1603 if (widget->shift >= WSA_MACRO_RX_MIX)
1604 bit_input %= WSA_MACRO_RX_MIX;
1605
1606 switch (rx_port_value) {
1607 case 0:
1608 clear_bit(bit_input,
1609 &wsa_priv->active_ch_mask[aif_rst - 1]);
1610 wsa_priv->active_ch_cnt[aif_rst - 1]--;
1611 break;
1612 case 1:
1613 case 2:
1614 set_bit(bit_input,
1615 &wsa_priv->active_ch_mask[rx_port_value - 1]);
1616 wsa_priv->active_ch_cnt[rx_port_value - 1]++;
1617 break;
1618 default:
1619 dev_err(wsa_dev,
1620 "%s: Invalid AIF_ID for WSA RX MUX\n", __func__);
1621 return -EINVAL;
1622 }
1623
1624 snd_soc_dapm_mux_update_power(widget->dapm, kcontrol,
1625 rx_port_value, e, update);
1626 return 0;
1627}
1628
1629static const struct snd_kcontrol_new wsa_macro_snd_controls[] = {
1630 SOC_ENUM_EXT("EAR SPKR PA Gain", wsa_macro_ear_spkr_pa_gain_enum,
1631 wsa_macro_ear_spkr_pa_gain_get,
1632 wsa_macro_ear_spkr_pa_gain_put),
1633 SOC_ENUM_EXT("SPKR Left Boost Max State",
1634 wsa_macro_spkr_boost_stage_enum,
1635 wsa_macro_spkr_left_boost_stage_get,
1636 wsa_macro_spkr_left_boost_stage_put),
1637 SOC_ENUM_EXT("SPKR Right Boost Max State",
1638 wsa_macro_spkr_boost_stage_enum,
1639 wsa_macro_spkr_right_boost_stage_get,
1640 wsa_macro_spkr_right_boost_stage_put),
1641 SOC_SINGLE_SX_TLV("WSA_RX0 Digital Volume",
1642 BOLERO_CDC_WSA_RX0_RX_VOL_CTL,
1643 0, -84, 40, digital_gain),
1644 SOC_SINGLE_SX_TLV("WSA_RX1 Digital Volume",
1645 BOLERO_CDC_WSA_RX1_RX_VOL_CTL,
1646 0, -84, 40, digital_gain),
1647 SOC_SINGLE_EXT("WSA_COMP1 Switch", SND_SOC_NOPM, WSA_MACRO_COMP1, 1, 0,
1648 wsa_macro_get_compander, wsa_macro_set_compander),
1649 SOC_SINGLE_EXT("WSA_COMP2 Switch", SND_SOC_NOPM, WSA_MACRO_COMP2, 1, 0,
1650 wsa_macro_get_compander, wsa_macro_set_compander),
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301651 SOC_SINGLE_EXT("WSA_RX0 EC_HQ Switch", SND_SOC_NOPM, WSA_MACRO_RX0,
1652 1, 0, wsa_macro_get_ec_hq, wsa_macro_set_ec_hq),
1653 SOC_SINGLE_EXT("WSA_RX1 EC_HQ Switch", SND_SOC_NOPM, WSA_MACRO_RX1,
1654 1, 0, wsa_macro_get_ec_hq, wsa_macro_set_ec_hq),
Laxminath Kasam243e2752018-04-12 00:40:19 +05301655};
1656
1657static const struct soc_enum rx_mux_enum =
1658 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_mux_text), rx_mux_text);
1659
1660static const struct snd_kcontrol_new rx_mux[WSA_MACRO_RX_MAX] = {
1661 SOC_DAPM_ENUM_EXT("WSA RX0 Mux", rx_mux_enum,
1662 wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),
1663 SOC_DAPM_ENUM_EXT("WSA RX1 Mux", rx_mux_enum,
1664 wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),
1665 SOC_DAPM_ENUM_EXT("WSA RX_MIX0 Mux", rx_mux_enum,
1666 wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),
1667 SOC_DAPM_ENUM_EXT("WSA RX_MIX1 Mux", rx_mux_enum,
1668 wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),
1669};
1670
1671static int wsa_macro_vi_feed_mixer_get(struct snd_kcontrol *kcontrol,
1672 struct snd_ctl_elem_value *ucontrol)
1673{
1674 struct snd_soc_dapm_widget *widget =
1675 snd_soc_dapm_kcontrol_widget(kcontrol);
1676 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
1677 struct soc_multi_mixer_control *mixer =
1678 ((struct soc_multi_mixer_control *)kcontrol->private_value);
1679 u32 dai_id = widget->shift;
1680 u32 spk_tx_id = mixer->shift;
1681 struct device *wsa_dev = NULL;
1682 struct wsa_macro_priv *wsa_priv = NULL;
1683
1684 if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__))
1685 return -EINVAL;
1686
1687 if (test_bit(spk_tx_id, &wsa_priv->active_ch_mask[dai_id]))
1688 ucontrol->value.integer.value[0] = 1;
1689 else
1690 ucontrol->value.integer.value[0] = 0;
1691
1692 return 0;
1693}
1694
1695static int wsa_macro_vi_feed_mixer_put(struct snd_kcontrol *kcontrol,
1696 struct snd_ctl_elem_value *ucontrol)
1697{
1698 struct snd_soc_dapm_widget *widget =
1699 snd_soc_dapm_kcontrol_widget(kcontrol);
1700 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
1701 struct soc_multi_mixer_control *mixer =
1702 ((struct soc_multi_mixer_control *)kcontrol->private_value);
1703 u32 spk_tx_id = mixer->shift;
1704 u32 enable = ucontrol->value.integer.value[0];
1705 struct device *wsa_dev = NULL;
1706 struct wsa_macro_priv *wsa_priv = NULL;
1707
1708 if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__))
1709 return -EINVAL;
1710
1711 wsa_priv->vi_feed_value = ucontrol->value.integer.value[0];
1712
1713 if (enable) {
1714 if (spk_tx_id == WSA_MACRO_TX0 &&
1715 !test_bit(WSA_MACRO_TX0,
1716 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
1717 set_bit(WSA_MACRO_TX0,
1718 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI]);
1719 wsa_priv->active_ch_cnt[WSA_MACRO_AIF_VI]++;
1720 }
1721 if (spk_tx_id == WSA_MACRO_TX1 &&
1722 !test_bit(WSA_MACRO_TX1,
1723 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
1724 set_bit(WSA_MACRO_TX1,
1725 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI]);
1726 wsa_priv->active_ch_cnt[WSA_MACRO_AIF_VI]++;
1727 }
1728 } else {
1729 if (spk_tx_id == WSA_MACRO_TX0 &&
1730 test_bit(WSA_MACRO_TX0,
1731 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
1732 clear_bit(WSA_MACRO_TX0,
1733 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI]);
1734 wsa_priv->active_ch_cnt[WSA_MACRO_AIF_VI]--;
1735 }
1736 if (spk_tx_id == WSA_MACRO_TX1 &&
1737 test_bit(WSA_MACRO_TX1,
1738 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) {
1739 clear_bit(WSA_MACRO_TX1,
1740 &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI]);
1741 wsa_priv->active_ch_cnt[WSA_MACRO_AIF_VI]--;
1742 }
1743 }
1744 snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, NULL);
1745
1746 return 0;
1747}
1748
1749static const struct snd_kcontrol_new aif_vi_mixer[] = {
1750 SOC_SINGLE_EXT("WSA_SPKR_VI_1", SND_SOC_NOPM, WSA_MACRO_TX0, 1, 0,
1751 wsa_macro_vi_feed_mixer_get,
1752 wsa_macro_vi_feed_mixer_put),
1753 SOC_SINGLE_EXT("WSA_SPKR_VI_2", SND_SOC_NOPM, WSA_MACRO_TX1, 1, 0,
1754 wsa_macro_vi_feed_mixer_get,
1755 wsa_macro_vi_feed_mixer_put),
1756};
1757
1758static const struct snd_soc_dapm_widget wsa_macro_dapm_widgets[] = {
1759 SND_SOC_DAPM_AIF_IN("WSA AIF1 PB", "WSA_AIF1 Playback", 0,
1760 SND_SOC_NOPM, 0, 0),
1761
1762 SND_SOC_DAPM_AIF_IN("WSA AIF_MIX1 PB", "WSA_AIF_MIX1 Playback", 0,
1763 SND_SOC_NOPM, 0, 0),
1764
1765 SND_SOC_DAPM_AIF_OUT_E("WSA AIF_VI", "WSA_AIF_VI Capture", 0,
1766 SND_SOC_NOPM, WSA_MACRO_AIF_VI, 0,
1767 wsa_macro_enable_vi_feedback,
1768 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1769
1770 SND_SOC_DAPM_AIF_OUT("WSA AIF_ECHO", "WSA_AIF_ECHO Capture", 0,
1771 SND_SOC_NOPM, 0, 0),
1772
1773 SND_SOC_DAPM_MIXER("WSA_AIF_VI Mixer", SND_SOC_NOPM, WSA_MACRO_AIF_VI,
1774 0, aif_vi_mixer, ARRAY_SIZE(aif_vi_mixer)),
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301775 SND_SOC_DAPM_MUX_E("WSA RX_MIX EC0_MUX", SND_SOC_NOPM,
1776 WSA_MACRO_EC0_MUX, 0,
1777 &rx_mix_ec0_mux, wsa_macro_enable_echo,
1778 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1779 SND_SOC_DAPM_MUX_E("WSA RX_MIX EC1_MUX", SND_SOC_NOPM,
1780 WSA_MACRO_EC1_MUX, 0,
1781 &rx_mix_ec1_mux, wsa_macro_enable_echo,
1782 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
Laxminath Kasam243e2752018-04-12 00:40:19 +05301783
1784 SND_SOC_DAPM_MUX("WSA RX0 MUX", SND_SOC_NOPM, WSA_MACRO_RX0, 0,
1785 &rx_mux[WSA_MACRO_RX0]),
1786 SND_SOC_DAPM_MUX("WSA RX1 MUX", SND_SOC_NOPM, WSA_MACRO_RX1, 0,
1787 &rx_mux[WSA_MACRO_RX1]),
1788 SND_SOC_DAPM_MUX("WSA RX_MIX0 MUX", SND_SOC_NOPM, WSA_MACRO_RX_MIX0, 0,
1789 &rx_mux[WSA_MACRO_RX_MIX0]),
1790 SND_SOC_DAPM_MUX("WSA RX_MIX1 MUX", SND_SOC_NOPM, WSA_MACRO_RX_MIX1, 0,
1791 &rx_mux[WSA_MACRO_RX_MIX1]),
1792
1793 SND_SOC_DAPM_MIXER("WSA RX0", SND_SOC_NOPM, 0, 0, NULL, 0),
1794 SND_SOC_DAPM_MIXER("WSA RX1", SND_SOC_NOPM, 0, 0, NULL, 0),
1795 SND_SOC_DAPM_MIXER("WSA RX_MIX0", SND_SOC_NOPM, 0, 0, NULL, 0),
1796 SND_SOC_DAPM_MIXER("WSA RX_MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
1797
1798 SND_SOC_DAPM_MUX_E("WSA_RX0 INP0", SND_SOC_NOPM, 0, 0,
1799 &rx0_prim_inp0_mux, wsa_macro_enable_swr,
1800 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1801 SND_SOC_DAPM_MUX_E("WSA_RX0 INP1", SND_SOC_NOPM, 0, 0,
1802 &rx0_prim_inp1_mux, wsa_macro_enable_swr,
1803 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1804 SND_SOC_DAPM_MUX_E("WSA_RX0 INP2", SND_SOC_NOPM, 0, 0,
1805 &rx0_prim_inp2_mux, wsa_macro_enable_swr,
1806 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1807 SND_SOC_DAPM_MUX_E("WSA_RX0 MIX INP", SND_SOC_NOPM, 0, 0,
1808 &rx0_mix_mux, wsa_macro_enable_mix_path,
1809 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1810 SND_SOC_DAPM_MUX_E("WSA_RX1 INP0", SND_SOC_NOPM, 0, 0,
1811 &rx1_prim_inp0_mux, wsa_macro_enable_swr,
1812 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1813 SND_SOC_DAPM_MUX_E("WSA_RX1 INP1", SND_SOC_NOPM, 0, 0,
1814 &rx1_prim_inp1_mux, wsa_macro_enable_swr,
1815 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1816 SND_SOC_DAPM_MUX_E("WSA_RX1 INP2", SND_SOC_NOPM, 0, 0,
1817 &rx1_prim_inp2_mux, wsa_macro_enable_swr,
1818 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1819 SND_SOC_DAPM_MUX_E("WSA_RX1 MIX INP", SND_SOC_NOPM, 0, 0,
1820 &rx1_mix_mux, wsa_macro_enable_mix_path,
1821 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1822 SND_SOC_DAPM_MIXER("WSA_RX INT0 MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
1823 SND_SOC_DAPM_MIXER("WSA_RX INT1 MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
1824 SND_SOC_DAPM_MIXER("WSA_RX INT0 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
1825 SND_SOC_DAPM_MIXER("WSA_RX INT1 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
1826
1827 SND_SOC_DAPM_MIXER_E("WSA_RX INT0 INTERP", SND_SOC_NOPM,
1828 WSA_MACRO_COMP1, 0, NULL, 0, wsa_macro_enable_interpolator,
1829 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1830 SND_SOC_DAPM_POST_PMD),
1831 SND_SOC_DAPM_MIXER_E("WSA_RX INT1 INTERP", SND_SOC_NOPM,
1832 WSA_MACRO_COMP2, 0, NULL, 0, wsa_macro_enable_interpolator,
1833 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1834 SND_SOC_DAPM_POST_PMD),
1835
1836 SND_SOC_DAPM_MIXER_E("WSA_RX INT0 CHAIN", SND_SOC_NOPM, 0, 0,
1837 NULL, 0, wsa_macro_spk_boost_event,
Laxminath Kasam0c857002018-07-17 23:47:17 +05301838 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1839 SND_SOC_DAPM_POST_PMD),
Laxminath Kasam243e2752018-04-12 00:40:19 +05301840 SND_SOC_DAPM_MIXER_E("WSA_RX INT1 CHAIN", SND_SOC_NOPM, 0, 0,
1841 NULL, 0, wsa_macro_spk_boost_event,
Laxminath Kasam0c857002018-07-17 23:47:17 +05301842 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1843 SND_SOC_DAPM_POST_PMD),
Laxminath Kasam243e2752018-04-12 00:40:19 +05301844
1845 SND_SOC_DAPM_INPUT("VIINPUT_WSA"),
1846
1847 SND_SOC_DAPM_OUTPUT("WSA_SPK1 OUT"),
1848 SND_SOC_DAPM_OUTPUT("WSA_SPK2 OUT"),
1849
1850 SND_SOC_DAPM_SUPPLY_S("WSA_MCLK", 0, SND_SOC_NOPM, 0, 0,
1851 wsa_macro_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1852};
1853
1854static const struct snd_soc_dapm_route wsa_audio_map[] = {
1855 /* VI Feedback */
1856 {"WSA_AIF_VI Mixer", "WSA_SPKR_VI_1", "VIINPUT_WSA"},
1857 {"WSA_AIF_VI Mixer", "WSA_SPKR_VI_2", "VIINPUT_WSA"},
1858 {"WSA AIF_VI", NULL, "WSA_AIF_VI Mixer"},
1859 {"WSA AIF_VI", NULL, "WSA_MCLK"},
1860
Laxminath Kasam36ab7bb2018-06-18 18:43:46 +05301861 {"WSA RX_MIX EC0_MUX", "RX_MIX_TX0", "WSA_RX INT0 SEC MIX"},
1862 {"WSA RX_MIX EC1_MUX", "RX_MIX_TX0", "WSA_RX INT0 SEC MIX"},
1863 {"WSA RX_MIX EC0_MUX", "RX_MIX_TX1", "WSA_RX INT1 SEC MIX"},
1864 {"WSA RX_MIX EC1_MUX", "RX_MIX_TX1", "WSA_RX INT1 SEC MIX"},
1865 {"WSA AIF_ECHO", NULL, "WSA RX_MIX EC0_MUX"},
1866 {"WSA AIF_ECHO", NULL, "WSA RX_MIX EC1_MUX"},
1867 {"WSA AIF_ECHO", NULL, "WSA_MCLK"},
1868
Laxminath Kasam243e2752018-04-12 00:40:19 +05301869 {"WSA AIF1 PB", NULL, "WSA_MCLK"},
1870 {"WSA AIF_MIX1 PB", NULL, "WSA_MCLK"},
1871
1872 {"WSA RX0 MUX", "AIF1_PB", "WSA AIF1 PB"},
1873 {"WSA RX1 MUX", "AIF1_PB", "WSA AIF1 PB"},
1874 {"WSA RX_MIX0 MUX", "AIF1_PB", "WSA AIF1 PB"},
1875 {"WSA RX_MIX1 MUX", "AIF1_PB", "WSA AIF1 PB"},
1876
1877 {"WSA RX0 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
1878 {"WSA RX1 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
1879 {"WSA RX_MIX0 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
1880 {"WSA RX_MIX1 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
1881
1882 {"WSA RX0", NULL, "WSA RX0 MUX"},
1883 {"WSA RX1", NULL, "WSA RX1 MUX"},
1884 {"WSA RX_MIX0", NULL, "WSA RX_MIX0 MUX"},
1885 {"WSA RX_MIX1", NULL, "WSA RX_MIX1 MUX"},
1886
1887 {"WSA_RX0 INP0", "RX0", "WSA RX0"},
1888 {"WSA_RX0 INP0", "RX1", "WSA RX1"},
1889 {"WSA_RX0 INP0", "RX_MIX0", "WSA RX_MIX0"},
1890 {"WSA_RX0 INP0", "RX_MIX1", "WSA RX_MIX1"},
1891 {"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP0"},
1892
1893 {"WSA_RX0 INP1", "RX0", "WSA RX0"},
1894 {"WSA_RX0 INP1", "RX1", "WSA RX1"},
1895 {"WSA_RX0 INP1", "RX_MIX0", "WSA RX_MIX0"},
1896 {"WSA_RX0 INP1", "RX_MIX1", "WSA RX_MIX1"},
1897 {"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP1"},
1898
1899 {"WSA_RX0 INP2", "RX0", "WSA RX0"},
1900 {"WSA_RX0 INP2", "RX1", "WSA RX1"},
1901 {"WSA_RX0 INP2", "RX_MIX0", "WSA RX_MIX0"},
1902 {"WSA_RX0 INP2", "RX_MIX1", "WSA RX_MIX1"},
1903 {"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP2"},
1904
1905 {"WSA_RX0 MIX INP", "RX0", "WSA RX0"},
1906 {"WSA_RX0 MIX INP", "RX1", "WSA RX1"},
1907 {"WSA_RX0 MIX INP", "RX_MIX0", "WSA RX_MIX0"},
1908 {"WSA_RX0 MIX INP", "RX_MIX1", "WSA RX_MIX1"},
1909 {"WSA_RX INT0 SEC MIX", NULL, "WSA_RX0 MIX INP"},
1910
1911 {"WSA_RX INT0 SEC MIX", NULL, "WSA_RX INT0 MIX"},
1912 {"WSA_RX INT0 INTERP", NULL, "WSA_RX INT0 SEC MIX"},
1913 {"WSA_RX INT0 CHAIN", NULL, "WSA_RX INT0 INTERP"},
1914 {"WSA_SPK1 OUT", NULL, "WSA_RX INT0 CHAIN"},
1915
1916 {"WSA_RX1 INP0", "RX0", "WSA RX0"},
1917 {"WSA_RX1 INP0", "RX1", "WSA RX1"},
1918 {"WSA_RX1 INP0", "RX_MIX0", "WSA RX_MIX0"},
1919 {"WSA_RX1 INP0", "RX_MIX1", "WSA RX_MIX1"},
1920 {"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP0"},
1921
1922 {"WSA_RX1 INP1", "RX0", "WSA RX0"},
1923 {"WSA_RX1 INP1", "RX1", "WSA RX1"},
1924 {"WSA_RX1 INP1", "RX_MIX0", "WSA RX_MIX0"},
1925 {"WSA_RX1 INP1", "RX_MIX1", "WSA RX_MIX1"},
1926 {"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP1"},
1927
1928 {"WSA_RX1 INP2", "RX0", "WSA RX0"},
1929 {"WSA_RX1 INP2", "RX1", "WSA RX1"},
1930 {"WSA_RX1 INP2", "RX_MIX0", "WSA RX_MIX0"},
1931 {"WSA_RX1 INP2", "RX_MIX1", "WSA RX_MIX1"},
1932 {"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP2"},
1933
1934 {"WSA_RX1 MIX INP", "RX0", "WSA RX0"},
1935 {"WSA_RX1 MIX INP", "RX1", "WSA RX1"},
1936 {"WSA_RX1 MIX INP", "RX_MIX0", "WSA RX_MIX0"},
1937 {"WSA_RX1 MIX INP", "RX_MIX1", "WSA RX_MIX1"},
1938 {"WSA_RX INT1 SEC MIX", NULL, "WSA_RX1 MIX INP"},
1939
1940 {"WSA_RX INT1 SEC MIX", NULL, "WSA_RX INT1 MIX"},
1941 {"WSA_RX INT1 INTERP", NULL, "WSA_RX INT1 SEC MIX"},
1942 {"WSA_RX INT1 CHAIN", NULL, "WSA_RX INT1 INTERP"},
1943 {"WSA_SPK2 OUT", NULL, "WSA_RX INT1 CHAIN"},
1944};
1945
1946static const struct wsa_macro_reg_mask_val wsa_macro_reg_init[] = {
1947 {BOLERO_CDC_WSA_BOOST0_BOOST_CFG1, 0x3F, 0x12},
1948 {BOLERO_CDC_WSA_BOOST0_BOOST_CFG2, 0x1C, 0x08},
1949 {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x1E, 0x18},
1950 {BOLERO_CDC_WSA_BOOST1_BOOST_CFG1, 0x3F, 0x12},
1951 {BOLERO_CDC_WSA_BOOST1_BOOST_CFG2, 0x1C, 0x08},
1952 {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x1E, 0x18},
1953 {BOLERO_CDC_WSA_BOOST0_BOOST_CTL, 0x70, 0x58},
1954 {BOLERO_CDC_WSA_BOOST1_BOOST_CTL, 0x70, 0x58},
1955 {BOLERO_CDC_WSA_RX0_RX_PATH_CFG1, 0x08, 0x08},
1956 {BOLERO_CDC_WSA_RX1_RX_PATH_CFG1, 0x08, 0x08},
1957 {BOLERO_CDC_WSA_TOP_TOP_CFG1, 0x02, 0x02},
1958 {BOLERO_CDC_WSA_TOP_TOP_CFG1, 0x01, 0x01},
1959 {BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
1960 {BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
1961 {BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
1962 {BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
1963 {BOLERO_CDC_WSA_COMPANDER0_CTL3, 0x80, 0x80},
1964 {BOLERO_CDC_WSA_COMPANDER1_CTL3, 0x80, 0x80},
1965 {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x01, 0x01},
1966 {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x01, 0x01},
1967 {BOLERO_CDC_WSA_RX0_RX_PATH_CFG0, 0x01, 0x01},
1968 {BOLERO_CDC_WSA_RX1_RX_PATH_CFG0, 0x01, 0x01},
1969 {BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CFG, 0x01, 0x01},
1970 {BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CFG, 0x01, 0x01},
1971};
1972
1973static void wsa_macro_init_reg(struct snd_soc_codec *codec)
1974{
1975 int i;
1976
1977 for (i = 0; i < ARRAY_SIZE(wsa_macro_reg_init); i++)
1978 snd_soc_update_bits(codec,
1979 wsa_macro_reg_init[i].reg,
1980 wsa_macro_reg_init[i].mask,
1981 wsa_macro_reg_init[i].val);
1982}
1983
1984static int wsa_swrm_clock(void *handle, bool enable)
1985{
1986 struct wsa_macro_priv *wsa_priv = (struct wsa_macro_priv *) handle;
1987 struct regmap *regmap = dev_get_regmap(wsa_priv->dev->parent, NULL);
1988
1989 mutex_lock(&wsa_priv->swr_clk_lock);
1990
1991 dev_dbg(wsa_priv->dev, "%s: swrm clock %s\n",
1992 __func__, (enable ? "enable" : "disable"));
1993 if (enable) {
1994 wsa_priv->swr_clk_users++;
1995 if (wsa_priv->swr_clk_users == 1) {
1996 wsa_macro_mclk_enable(wsa_priv, 1, true);
1997 regmap_update_bits(regmap,
1998 BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
1999 0x01, 0x01);
2000 regmap_update_bits(regmap,
2001 BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
2002 0x1C, 0x0C);
2003 msm_cdc_pinctrl_select_active_state(
2004 wsa_priv->wsa_swr_gpio_p);
2005 }
2006 } else {
2007 wsa_priv->swr_clk_users--;
2008 if (wsa_priv->swr_clk_users == 0) {
2009 regmap_update_bits(regmap,
2010 BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
2011 0x01, 0x00);
2012 msm_cdc_pinctrl_select_sleep_state(
2013 wsa_priv->wsa_swr_gpio_p);
2014 wsa_macro_mclk_enable(wsa_priv, 0, true);
2015 }
2016 }
2017 dev_dbg(wsa_priv->dev, "%s: swrm clock users %d\n",
2018 __func__, wsa_priv->swr_clk_users);
2019 mutex_unlock(&wsa_priv->swr_clk_lock);
2020 return 0;
2021}
2022
2023static int wsa_macro_init(struct snd_soc_codec *codec)
2024{
2025 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
2026 int ret;
2027 struct device *wsa_dev = NULL;
2028 struct wsa_macro_priv *wsa_priv = NULL;
2029
2030 wsa_dev = bolero_get_device_ptr(codec->dev, WSA_MACRO);
2031 if (!wsa_dev) {
2032 dev_err(codec->dev,
2033 "%s: null device for macro!\n", __func__);
2034 return -EINVAL;
2035 }
2036 wsa_priv = dev_get_drvdata(wsa_dev);
2037 if (!wsa_priv) {
2038 dev_err(codec->dev,
2039 "%s: priv is null for macro!\n", __func__);
2040 return -EINVAL;
2041 }
2042
2043 ret = snd_soc_dapm_new_controls(dapm, wsa_macro_dapm_widgets,
2044 ARRAY_SIZE(wsa_macro_dapm_widgets));
2045 if (ret < 0) {
2046 dev_err(wsa_dev, "%s: Failed to add controls\n", __func__);
2047 return ret;
2048 }
2049
2050 ret = snd_soc_dapm_add_routes(dapm, wsa_audio_map,
2051 ARRAY_SIZE(wsa_audio_map));
2052 if (ret < 0) {
2053 dev_err(wsa_dev, "%s: Failed to add routes\n", __func__);
2054 return ret;
2055 }
2056
2057 ret = snd_soc_dapm_new_widgets(dapm->card);
2058 if (ret < 0) {
2059 dev_err(wsa_dev, "%s: Failed to add widgets\n", __func__);
2060 return ret;
2061 }
2062
2063 ret = snd_soc_add_codec_controls(codec, wsa_macro_snd_controls,
2064 ARRAY_SIZE(wsa_macro_snd_controls));
2065 if (ret < 0) {
2066 dev_err(wsa_dev, "%s: Failed to add snd_ctls\n", __func__);
2067 return ret;
2068 }
2069
2070 wsa_priv->codec = codec;
Laxminath Kasam21c8b222018-06-21 18:47:22 +05302071 wsa_priv->spkr_gain_offset = WSA_MACRO_GAIN_OFFSET_0_DB;
Laxminath Kasam243e2752018-04-12 00:40:19 +05302072 wsa_macro_init_reg(codec);
2073
2074 return 0;
2075}
2076
2077static int wsa_macro_deinit(struct snd_soc_codec *codec)
2078{
2079 struct device *wsa_dev = NULL;
2080 struct wsa_macro_priv *wsa_priv = NULL;
2081
2082 if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__))
2083 return -EINVAL;
2084
2085 wsa_priv->codec = NULL;
2086
2087 return 0;
2088}
2089
2090static void wsa_macro_add_child_devices(struct work_struct *work)
2091{
2092 struct wsa_macro_priv *wsa_priv;
2093 struct platform_device *pdev;
2094 struct device_node *node;
2095 struct wsa_macro_swr_ctrl_data *swr_ctrl_data = NULL, *temp;
2096 int ret;
2097 u16 count = 0, ctrl_num = 0;
2098 struct wsa_macro_swr_ctrl_platform_data *platdata;
2099 char plat_dev_name[WSA_MACRO_SWR_STRING_LEN];
2100
2101 wsa_priv = container_of(work, struct wsa_macro_priv,
2102 wsa_macro_add_child_devices_work);
2103 if (!wsa_priv) {
2104 pr_err("%s: Memory for wsa_priv does not exist\n",
2105 __func__);
2106 return;
2107 }
Laxminath Kasam21c8b222018-06-21 18:47:22 +05302108 if (!wsa_priv->dev || !wsa_priv->dev->of_node) {
Laxminath Kasam243e2752018-04-12 00:40:19 +05302109 dev_err(wsa_priv->dev,
2110 "%s: DT node for wsa_priv does not exist\n", __func__);
2111 return;
2112 }
2113
2114 platdata = &wsa_priv->swr_plat_data;
2115 wsa_priv->child_count = 0;
2116
2117 for_each_available_child_of_node(wsa_priv->dev->of_node, node) {
2118 if (strnstr(node->name, "wsa_swr_master",
2119 strlen("wsa_swr_master")) != NULL)
2120 strlcpy(plat_dev_name, "wsa_swr_ctrl",
2121 (WSA_MACRO_SWR_STRING_LEN - 1));
2122 else if (strnstr(node->name, "msm_cdc_pinctrl",
2123 strlen("msm_cdc_pinctrl")) != NULL)
2124 strlcpy(plat_dev_name, node->name,
2125 (WSA_MACRO_SWR_STRING_LEN - 1));
2126 else
2127 continue;
2128
2129 pdev = platform_device_alloc(plat_dev_name, -1);
2130 if (!pdev) {
2131 dev_err(wsa_priv->dev, "%s: pdev memory alloc failed\n",
2132 __func__);
2133 ret = -ENOMEM;
2134 goto err;
2135 }
2136 pdev->dev.parent = wsa_priv->dev;
2137 pdev->dev.of_node = node;
2138
2139 if (strnstr(node->name, "wsa_swr_master",
2140 strlen("wsa_swr_master")) != NULL) {
2141 ret = platform_device_add_data(pdev, platdata,
2142 sizeof(*platdata));
2143 if (ret) {
2144 dev_err(&pdev->dev,
2145 "%s: cannot add plat data ctrl:%d\n",
2146 __func__, ctrl_num);
2147 goto fail_pdev_add;
2148 }
2149 }
2150
2151 ret = platform_device_add(pdev);
2152 if (ret) {
2153 dev_err(&pdev->dev,
2154 "%s: Cannot add platform device\n",
2155 __func__);
2156 goto fail_pdev_add;
2157 }
2158
2159 if (!strcmp(node->name, "wsa_swr_master")) {
2160 temp = krealloc(swr_ctrl_data,
2161 (ctrl_num + 1) * sizeof(
2162 struct wsa_macro_swr_ctrl_data),
2163 GFP_KERNEL);
2164 if (!temp) {
2165 dev_err(&pdev->dev, "out of memory\n");
2166 ret = -ENOMEM;
2167 goto err;
2168 }
2169 swr_ctrl_data = temp;
2170 swr_ctrl_data[ctrl_num].wsa_swr_pdev = pdev;
2171 ctrl_num++;
2172 dev_dbg(&pdev->dev,
2173 "%s: Added soundwire ctrl device(s)\n",
2174 __func__);
2175 wsa_priv->swr_ctrl_data = swr_ctrl_data;
2176 }
2177 if (wsa_priv->child_count < WSA_MACRO_CHILD_DEVICES_MAX)
2178 wsa_priv->pdev_child_devices[
2179 wsa_priv->child_count++] = pdev;
2180 else
2181 goto err;
2182 }
2183
2184 return;
2185fail_pdev_add:
2186 for (count = 0; count < wsa_priv->child_count; count++)
2187 platform_device_put(wsa_priv->pdev_child_devices[count]);
2188err:
2189 return;
2190}
2191
2192static void wsa_macro_init_ops(struct macro_ops *ops,
2193 char __iomem *wsa_io_base)
2194{
2195 memset(ops, 0, sizeof(struct macro_ops));
2196 ops->init = wsa_macro_init;
2197 ops->exit = wsa_macro_deinit;
2198 ops->io_base = wsa_io_base;
2199 ops->dai_ptr = wsa_macro_dai;
2200 ops->num_dais = ARRAY_SIZE(wsa_macro_dai);
2201 ops->mclk_fn = wsa_macro_mclk_ctrl;
2202}
2203
2204static int wsa_macro_probe(struct platform_device *pdev)
2205{
2206 struct macro_ops ops;
2207 struct wsa_macro_priv *wsa_priv;
2208 u32 wsa_base_addr;
2209 char __iomem *wsa_io_base;
2210 int ret = 0;
2211 struct clk *wsa_core_clk, *wsa_npl_clk;
2212
2213 wsa_priv = devm_kzalloc(&pdev->dev, sizeof(struct wsa_macro_priv),
2214 GFP_KERNEL);
2215 if (!wsa_priv)
2216 return -ENOMEM;
2217
2218 wsa_priv->dev = &pdev->dev;
2219 ret = of_property_read_u32(pdev->dev.of_node, "reg",
2220 &wsa_base_addr);
2221 if (ret) {
2222 dev_err(&pdev->dev, "%s: could not find %s entry in dt\n",
2223 __func__, "reg");
2224 return ret;
2225 }
2226 wsa_priv->wsa_swr_gpio_p = of_parse_phandle(pdev->dev.of_node,
2227 "qcom,wsa-swr-gpios", 0);
2228 if (!wsa_priv->wsa_swr_gpio_p) {
2229 dev_err(&pdev->dev, "%s: swr_gpios handle not provided!\n",
2230 __func__);
2231 return -EINVAL;
2232 }
2233 wsa_io_base = devm_ioremap(&pdev->dev,
2234 wsa_base_addr, WSA_MACRO_MAX_OFFSET);
2235 if (!wsa_io_base) {
2236 dev_err(&pdev->dev, "%s: ioremap failed\n", __func__);
2237 return -EINVAL;
2238 }
2239 wsa_priv->wsa_io_base = wsa_io_base;
2240 INIT_WORK(&wsa_priv->wsa_macro_add_child_devices_work,
2241 wsa_macro_add_child_devices);
2242 wsa_priv->swr_plat_data.handle = (void *) wsa_priv;
2243 wsa_priv->swr_plat_data.read = NULL;
2244 wsa_priv->swr_plat_data.write = NULL;
2245 wsa_priv->swr_plat_data.bulk_write = NULL;
2246 wsa_priv->swr_plat_data.clk = wsa_swrm_clock;
2247 wsa_priv->swr_plat_data.handle_irq = NULL;
2248
2249 /* Register MCLK for wsa macro */
2250 wsa_core_clk = devm_clk_get(&pdev->dev, "wsa_core_clk");
2251 if (IS_ERR(wsa_core_clk)) {
2252 dev_err(&pdev->dev, "%s: clk get %s failed\n",
2253 __func__, "wsa_core_clk");
2254 return -EINVAL;
2255 }
2256 wsa_priv->wsa_core_clk = wsa_core_clk;
2257 /* Register npl clk for soundwire */
2258 wsa_npl_clk = devm_clk_get(&pdev->dev, "wsa_npl_clk");
2259 if (IS_ERR(wsa_npl_clk)) {
2260 dev_err(&pdev->dev, "%s: clk get %s failed\n",
2261 __func__, "wsa_npl_clk");
2262 return -EINVAL;
2263 }
2264 wsa_priv->wsa_npl_clk = wsa_npl_clk;
2265 dev_set_drvdata(&pdev->dev, wsa_priv);
2266 mutex_init(&wsa_priv->mclk_lock);
2267 mutex_init(&wsa_priv->swr_clk_lock);
2268 wsa_macro_init_ops(&ops, wsa_io_base);
2269 ret = bolero_register_macro(&pdev->dev, WSA_MACRO, &ops);
2270 if (ret < 0) {
2271 dev_err(&pdev->dev, "%s: register macro failed\n", __func__);
2272 goto reg_macro_fail;
2273 }
2274 schedule_work(&wsa_priv->wsa_macro_add_child_devices_work);
2275 return ret;
2276reg_macro_fail:
2277 mutex_destroy(&wsa_priv->mclk_lock);
2278 mutex_destroy(&wsa_priv->swr_clk_lock);
2279 return ret;
2280}
2281
2282static int wsa_macro_remove(struct platform_device *pdev)
2283{
2284 struct wsa_macro_priv *wsa_priv;
2285 u16 count = 0;
2286
2287 wsa_priv = dev_get_drvdata(&pdev->dev);
2288
2289 if (!wsa_priv)
2290 return -EINVAL;
2291
2292 for (count = 0; count < wsa_priv->child_count &&
2293 count < WSA_MACRO_CHILD_DEVICES_MAX; count++)
2294 platform_device_unregister(wsa_priv->pdev_child_devices[count]);
2295
2296 bolero_unregister_macro(&pdev->dev, WSA_MACRO);
2297 mutex_destroy(&wsa_priv->mclk_lock);
2298 mutex_destroy(&wsa_priv->swr_clk_lock);
2299 return 0;
2300}
2301
2302static const struct of_device_id wsa_macro_dt_match[] = {
2303 {.compatible = "qcom,wsa-macro"},
2304 {}
2305};
2306
2307static struct platform_driver wsa_macro_driver = {
2308 .driver = {
2309 .name = "wsa_macro",
2310 .owner = THIS_MODULE,
2311 .of_match_table = wsa_macro_dt_match,
2312 },
2313 .probe = wsa_macro_probe,
2314 .remove = wsa_macro_remove,
2315};
2316
2317module_platform_driver(wsa_macro_driver);
2318
2319MODULE_DESCRIPTION("WSA macro driver");
2320MODULE_LICENSE("GPL v2");