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