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