blob: 09dd3b097b01469c78340c9aa84914aa095d587e [file] [log] [blame]
Laxminath Kasam989fccf2018-06-15 16:53:31 +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/clk.h>
16#include <linux/io.h>
17#include <linux/platform_device.h>
18#include <linux/regmap.h>
19#include <sound/soc.h>
20#include <sound/soc-dapm.h>
21#include <sound/tlv.h>
Laxminath Kasamfb0d6832018-09-22 01:49:52 +053022#include <soc/swr-wcd.h>
Laxminath Kasam989fccf2018-06-15 16:53:31 +053023#include "bolero-cdc.h"
24#include "bolero-cdc-registers.h"
25#include "../msm-cdc-pinctrl.h"
26
27#define TX_MACRO_MAX_OFFSET 0x1000
28
29#define NUM_DECIMATORS 8
30
31#define TX_MACRO_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
32 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
33 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
34#define TX_MACRO_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
35 SNDRV_PCM_FMTBIT_S24_LE |\
36 SNDRV_PCM_FMTBIT_S24_3LE)
37
38#define TX_HPF_CUT_OFF_FREQ_MASK 0x60
39#define CF_MIN_3DB_4HZ 0x0
40#define CF_MIN_3DB_75HZ 0x1
41#define CF_MIN_3DB_150HZ 0x2
42
43#define TX_MACRO_DMIC_SAMPLE_RATE_UNDEFINED 0
44#define TX_MACRO_MCLK_FREQ 9600000
45#define TX_MACRO_TX_PATH_OFFSET 0x80
Laxminath Kasam497a6512018-09-17 16:11:52 +053046#define TX_MACRO_SWR_MIC_MUX_SEL_MASK 0xF
47#define TX_MACRO_ADC_MUX_CFG_OFFSET 0x2
Laxminath Kasam989fccf2018-06-15 16:53:31 +053048
49#define TX_MACRO_TX_UNMUTE_DELAY_MS 40
50
51static int tx_unmute_delay = TX_MACRO_TX_UNMUTE_DELAY_MS;
52module_param(tx_unmute_delay, int, 0664);
53MODULE_PARM_DESC(tx_unmute_delay, "delay to unmute the tx path");
54
55static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0);
56
57static int tx_macro_hw_params(struct snd_pcm_substream *substream,
58 struct snd_pcm_hw_params *params,
59 struct snd_soc_dai *dai);
60static int tx_macro_get_channel_map(struct snd_soc_dai *dai,
61 unsigned int *tx_num, unsigned int *tx_slot,
62 unsigned int *rx_num, unsigned int *rx_slot);
63
64#define TX_MACRO_SWR_STRING_LEN 80
65#define TX_MACRO_CHILD_DEVICES_MAX 3
66
67/* Hold instance to soundwire platform device */
68struct tx_macro_swr_ctrl_data {
69 struct platform_device *tx_swr_pdev;
70};
71
72struct tx_macro_swr_ctrl_platform_data {
73 void *handle; /* holds codec private data */
74 int (*read)(void *handle, int reg);
75 int (*write)(void *handle, int reg, int val);
76 int (*bulk_write)(void *handle, u32 *reg, u32 *val, size_t len);
77 int (*clk)(void *handle, bool enable);
78 int (*handle_irq)(void *handle,
79 irqreturn_t (*swrm_irq_handler)(int irq,
80 void *data),
81 void *swrm_handle,
82 int action);
83};
84
85enum {
Laxminath Kasam59c7a1d2018-08-09 16:11:17 +053086 TX_MACRO_AIF_INVALID = 0,
87 TX_MACRO_AIF1_CAP,
Laxminath Kasam989fccf2018-06-15 16:53:31 +053088 TX_MACRO_AIF2_CAP,
89 TX_MACRO_MAX_DAIS
90};
91
92enum {
93 TX_MACRO_DEC0,
94 TX_MACRO_DEC1,
95 TX_MACRO_DEC2,
96 TX_MACRO_DEC3,
97 TX_MACRO_DEC4,
98 TX_MACRO_DEC5,
99 TX_MACRO_DEC6,
100 TX_MACRO_DEC7,
101 TX_MACRO_DEC_MAX,
102};
103
104enum {
105 TX_MACRO_CLK_DIV_2,
106 TX_MACRO_CLK_DIV_3,
107 TX_MACRO_CLK_DIV_4,
108 TX_MACRO_CLK_DIV_6,
109 TX_MACRO_CLK_DIV_8,
110 TX_MACRO_CLK_DIV_16,
111};
112
Laxminath Kasam497a6512018-09-17 16:11:52 +0530113enum {
114 MSM_DMIC,
115 SWR_MIC,
116 ANC_FB_TUNE1
117};
118
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530119struct tx_mute_work {
120 struct tx_macro_priv *tx_priv;
121 u32 decimator;
122 struct delayed_work dwork;
123};
124
125struct hpf_work {
126 struct tx_macro_priv *tx_priv;
127 u8 decimator;
128 u8 hpf_cut_off_freq;
129 struct delayed_work dwork;
130};
131
132struct tx_macro_priv {
133 struct device *dev;
134 bool dec_active[NUM_DECIMATORS];
135 int tx_mclk_users;
136 int swr_clk_users;
137 struct clk *tx_core_clk;
138 struct clk *tx_npl_clk;
139 struct mutex mclk_lock;
140 struct mutex swr_clk_lock;
141 struct snd_soc_codec *codec;
142 struct device_node *tx_swr_gpio_p;
143 struct tx_macro_swr_ctrl_data *swr_ctrl_data;
144 struct tx_macro_swr_ctrl_platform_data swr_plat_data;
145 struct work_struct tx_macro_add_child_devices_work;
146 struct hpf_work tx_hpf_work[NUM_DECIMATORS];
147 struct tx_mute_work tx_mute_dwork[NUM_DECIMATORS];
148 s32 dmic_0_1_clk_cnt;
149 s32 dmic_2_3_clk_cnt;
150 s32 dmic_4_5_clk_cnt;
151 s32 dmic_6_7_clk_cnt;
152 u16 dmic_clk_div;
153 unsigned long active_ch_mask[TX_MACRO_MAX_DAIS];
154 unsigned long active_ch_cnt[TX_MACRO_MAX_DAIS];
155 char __iomem *tx_io_base;
156 struct platform_device *pdev_child_devices
157 [TX_MACRO_CHILD_DEVICES_MAX];
158 int child_count;
159};
160
161static bool tx_macro_get_data(struct snd_soc_codec *codec,
162 struct device **tx_dev,
163 struct tx_macro_priv **tx_priv,
164 const char *func_name)
165{
166 *tx_dev = bolero_get_device_ptr(codec->dev, TX_MACRO);
167 if (!(*tx_dev)) {
168 dev_err(codec->dev,
169 "%s: null device for macro!\n", func_name);
170 return false;
171 }
172
173 *tx_priv = dev_get_drvdata((*tx_dev));
174 if (!(*tx_priv)) {
175 dev_err(codec->dev,
176 "%s: priv is null for macro!\n", func_name);
177 return false;
178 }
179
180 if (!(*tx_priv)->codec) {
181 dev_err(codec->dev,
182 "%s: tx_priv->codec not initialized!\n", func_name);
183 return false;
184 }
185
186 return true;
187}
188
189static int tx_macro_mclk_enable(struct tx_macro_priv *tx_priv,
190 bool mclk_enable)
191{
192 struct regmap *regmap = dev_get_regmap(tx_priv->dev->parent, NULL);
193 int ret = 0;
194
Tanya Dixit8530fb92018-09-14 16:01:25 +0530195 if (regmap == NULL) {
196 dev_err(tx_priv->dev, "%s: regmap is NULL\n", __func__);
197 return -EINVAL;
198 }
199
Laxminath Kasamb7f823c2018-08-02 13:23:11 +0530200 dev_dbg(tx_priv->dev, "%s: mclk_enable = %u,clk_users= %d\n",
201 __func__, mclk_enable, tx_priv->tx_mclk_users);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530202
203 mutex_lock(&tx_priv->mclk_lock);
204 if (mclk_enable) {
205 if (tx_priv->tx_mclk_users == 0) {
206 ret = bolero_request_clock(tx_priv->dev,
207 TX_MACRO, MCLK_MUX0, true);
208 if (ret < 0) {
209 dev_err(tx_priv->dev,
210 "%s: request clock enable failed\n",
211 __func__);
212 goto exit;
213 }
214 regcache_mark_dirty(regmap);
215 regcache_sync_region(regmap,
216 TX_START_OFFSET,
217 TX_MAX_OFFSET);
218 /* 9.6MHz MCLK, set value 0x00 if other frequency */
219 regmap_update_bits(regmap,
220 BOLERO_CDC_TX_TOP_CSR_FREQ_MCLK, 0x01, 0x01);
221 regmap_update_bits(regmap,
222 BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL,
223 0x01, 0x01);
224 regmap_update_bits(regmap,
225 BOLERO_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL,
226 0x01, 0x01);
227 }
228 tx_priv->tx_mclk_users++;
229 } else {
230 if (tx_priv->tx_mclk_users <= 0) {
231 dev_err(tx_priv->dev, "%s: clock already disabled\n",
232 __func__);
233 tx_priv->tx_mclk_users = 0;
234 goto exit;
235 }
236 tx_priv->tx_mclk_users--;
237 if (tx_priv->tx_mclk_users == 0) {
238 regmap_update_bits(regmap,
239 BOLERO_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL,
240 0x01, 0x00);
241 regmap_update_bits(regmap,
242 BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL,
243 0x01, 0x00);
244 bolero_request_clock(tx_priv->dev,
245 TX_MACRO, MCLK_MUX0, false);
246 }
247 }
248exit:
249 mutex_unlock(&tx_priv->mclk_lock);
250 return ret;
251}
252
253static int tx_macro_mclk_event(struct snd_soc_dapm_widget *w,
254 struct snd_kcontrol *kcontrol, int event)
255{
256 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
257 int ret = 0;
258 struct device *tx_dev = NULL;
259 struct tx_macro_priv *tx_priv = NULL;
260
261 if (!tx_macro_get_data(codec, &tx_dev, &tx_priv, __func__))
262 return -EINVAL;
263
264 dev_dbg(tx_dev, "%s: event = %d\n", __func__, event);
265 switch (event) {
266 case SND_SOC_DAPM_PRE_PMU:
267 ret = tx_macro_mclk_enable(tx_priv, 1);
268 break;
269 case SND_SOC_DAPM_POST_PMD:
270 ret = tx_macro_mclk_enable(tx_priv, 0);
271 break;
272 default:
273 dev_err(tx_priv->dev,
274 "%s: invalid DAPM event %d\n", __func__, event);
275 ret = -EINVAL;
276 }
277 return ret;
278}
279
280static int tx_macro_mclk_ctrl(struct device *dev, bool enable)
281{
282 struct tx_macro_priv *tx_priv = dev_get_drvdata(dev);
283 int ret = 0;
284
285 if (enable) {
286 ret = clk_prepare_enable(tx_priv->tx_core_clk);
287 if (ret < 0) {
288 dev_err(dev, "%s:tx mclk enable failed\n", __func__);
289 goto exit;
290 }
291 ret = clk_prepare_enable(tx_priv->tx_npl_clk);
292 if (ret < 0) {
293 dev_err(dev, "%s:tx npl_clk enable failed\n",
294 __func__);
295 clk_disable_unprepare(tx_priv->tx_core_clk);
296 goto exit;
297 }
298 } else {
299 clk_disable_unprepare(tx_priv->tx_npl_clk);
300 clk_disable_unprepare(tx_priv->tx_core_clk);
301 }
302
303exit:
304 return ret;
305}
306
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530307static int tx_macro_event_handler(struct snd_soc_codec *codec, u16 event,
308 u32 data)
309{
310 struct device *tx_dev = NULL;
311 struct tx_macro_priv *tx_priv = NULL;
312
313 if (!tx_macro_get_data(codec, &tx_dev, &tx_priv, __func__))
314 return -EINVAL;
315
316 switch (event) {
317 case BOLERO_MACRO_EVT_SSR_DOWN:
318 swrm_wcd_notify(
319 tx_priv->swr_ctrl_data[0].tx_swr_pdev,
320 SWR_DEVICE_SSR_DOWN, NULL);
321 swrm_wcd_notify(
322 tx_priv->swr_ctrl_data[0].tx_swr_pdev,
323 SWR_DEVICE_DOWN, NULL);
324 break;
325 case BOLERO_MACRO_EVT_SSR_UP:
326 swrm_wcd_notify(
327 tx_priv->swr_ctrl_data[0].tx_swr_pdev,
328 SWR_DEVICE_SSR_UP, NULL);
329 break;
330 }
331 return 0;
332}
333
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530334static void tx_macro_tx_hpf_corner_freq_callback(struct work_struct *work)
335{
336 struct delayed_work *hpf_delayed_work = NULL;
337 struct hpf_work *hpf_work = NULL;
338 struct tx_macro_priv *tx_priv = NULL;
339 struct snd_soc_codec *codec = NULL;
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530340 u16 dec_cfg_reg = 0, hpf_gate_reg = 0;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530341 u8 hpf_cut_off_freq = 0;
Laxminath Kasam497a6512018-09-17 16:11:52 +0530342 u16 adc_mux_reg = 0, adc_n = 0, adc_reg = 0;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530343
344 hpf_delayed_work = to_delayed_work(work);
345 hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork);
346 tx_priv = hpf_work->tx_priv;
347 codec = tx_priv->codec;
348 hpf_cut_off_freq = hpf_work->hpf_cut_off_freq;
349
350 dec_cfg_reg = BOLERO_CDC_TX0_TX_PATH_CFG0 +
351 TX_MACRO_TX_PATH_OFFSET * hpf_work->decimator;
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530352 hpf_gate_reg = BOLERO_CDC_TX0_TX_PATH_SEC2 +
353 TX_MACRO_TX_PATH_OFFSET * hpf_work->decimator;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530354
355 dev_dbg(codec->dev, "%s: decimator %u hpf_cut_of_freq 0x%x\n",
356 __func__, hpf_work->decimator, hpf_cut_off_freq);
357
Laxminath Kasam497a6512018-09-17 16:11:52 +0530358 adc_mux_reg = BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG1 +
359 TX_MACRO_ADC_MUX_CFG_OFFSET * hpf_work->decimator;
360 if (snd_soc_read(codec, adc_mux_reg) & SWR_MIC) {
361 adc_reg = BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0 +
362 TX_MACRO_ADC_MUX_CFG_OFFSET * hpf_work->decimator;
363 adc_n = snd_soc_read(codec, adc_reg) &
364 TX_MACRO_SWR_MIC_MUX_SEL_MASK;
365 if (adc_n >= BOLERO_ADC_MAX)
366 goto tx_hpf_set;
367 /* analog mic clear TX hold */
368 bolero_clear_amic_tx_hold(codec->dev, adc_n);
369 }
370tx_hpf_set:
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530371 snd_soc_update_bits(codec, dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK,
372 hpf_cut_off_freq << 5);
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530373 snd_soc_update_bits(codec, hpf_gate_reg, 0x02, 0x02);
374 /* Minimum 1 clk cycle delay is required as per HW spec */
375 usleep_range(1000, 1010);
376 snd_soc_update_bits(codec, hpf_gate_reg, 0x02, 0x00);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530377}
378
379static void tx_macro_mute_update_callback(struct work_struct *work)
380{
381 struct tx_mute_work *tx_mute_dwork = NULL;
382 struct snd_soc_codec *codec = NULL;
383 struct tx_macro_priv *tx_priv = NULL;
384 struct delayed_work *delayed_work = NULL;
385 u16 tx_vol_ctl_reg = 0, hpf_gate_reg = 0;
386 u8 decimator = 0;
387
388 delayed_work = to_delayed_work(work);
389 tx_mute_dwork = container_of(delayed_work, struct tx_mute_work, dwork);
390 tx_priv = tx_mute_dwork->tx_priv;
391 codec = tx_priv->codec;
392 decimator = tx_mute_dwork->decimator;
393
394 tx_vol_ctl_reg =
395 BOLERO_CDC_TX0_TX_PATH_CTL +
396 TX_MACRO_TX_PATH_OFFSET * decimator;
397 hpf_gate_reg = BOLERO_CDC_TX0_TX_PATH_SEC2 +
398 TX_MACRO_TX_PATH_OFFSET * decimator;
399 snd_soc_update_bits(codec, hpf_gate_reg, 0x01, 0x01);
Ramprasad Katkam9c2394a2018-08-23 13:13:48 +0530400 snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x00);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530401 dev_dbg(tx_priv->dev, "%s: decimator %u unmute\n",
402 __func__, decimator);
403}
404
405static int tx_macro_put_dec_enum(struct snd_kcontrol *kcontrol,
406 struct snd_ctl_elem_value *ucontrol)
407{
408 struct snd_soc_dapm_widget *widget =
409 snd_soc_dapm_kcontrol_widget(kcontrol);
410 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
411 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
412 unsigned int val = 0;
413 u16 mic_sel_reg = 0;
414
415 val = ucontrol->value.enumerated.item[0];
416 if (val > e->items - 1)
417 return -EINVAL;
418
419 dev_dbg(codec->dev, "%s: wname: %s, val: 0x%x\n", __func__,
420 widget->name, val);
421
422 switch (e->reg) {
423 case BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0:
424 mic_sel_reg = BOLERO_CDC_TX0_TX_PATH_CFG0;
425 break;
426 case BOLERO_CDC_TX_INP_MUX_ADC_MUX1_CFG0:
427 mic_sel_reg = BOLERO_CDC_TX1_TX_PATH_CFG0;
428 break;
429 case BOLERO_CDC_TX_INP_MUX_ADC_MUX2_CFG0:
430 mic_sel_reg = BOLERO_CDC_TX2_TX_PATH_CFG0;
431 break;
432 case BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG0:
433 mic_sel_reg = BOLERO_CDC_TX3_TX_PATH_CFG0;
434 break;
435 case BOLERO_CDC_TX_INP_MUX_ADC_MUX4_CFG0:
436 mic_sel_reg = BOLERO_CDC_TX4_TX_PATH_CFG0;
437 break;
438 case BOLERO_CDC_TX_INP_MUX_ADC_MUX5_CFG0:
439 mic_sel_reg = BOLERO_CDC_TX5_TX_PATH_CFG0;
440 break;
441 case BOLERO_CDC_TX_INP_MUX_ADC_MUX6_CFG0:
442 mic_sel_reg = BOLERO_CDC_TX6_TX_PATH_CFG0;
443 break;
444 case BOLERO_CDC_TX_INP_MUX_ADC_MUX7_CFG0:
445 mic_sel_reg = BOLERO_CDC_TX7_TX_PATH_CFG0;
446 break;
447 default:
448 dev_err(codec->dev, "%s: e->reg: 0x%x not expected\n",
449 __func__, e->reg);
450 return -EINVAL;
451 }
Laxminath Kasam497a6512018-09-17 16:11:52 +0530452 if (strnstr(widget->name, "SMIC", strlen(widget->name))) {
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530453 if (val != 0) {
454 if (val < 5)
455 snd_soc_update_bits(codec, mic_sel_reg,
456 1 << 7, 0x0 << 7);
457 else
458 snd_soc_update_bits(codec, mic_sel_reg,
459 1 << 7, 0x1 << 7);
460 }
461 } else {
462 /* DMIC selected */
463 if (val != 0)
464 snd_soc_update_bits(codec, mic_sel_reg, 1 << 7, 1 << 7);
465 }
466
467 return snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
468}
469
470static int tx_macro_tx_mixer_get(struct snd_kcontrol *kcontrol,
471 struct snd_ctl_elem_value *ucontrol)
472{
473 struct snd_soc_dapm_widget *widget =
474 snd_soc_dapm_kcontrol_widget(kcontrol);
475 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
476 struct soc_multi_mixer_control *mixer =
477 ((struct soc_multi_mixer_control *)kcontrol->private_value);
478 u32 dai_id = widget->shift;
479 u32 dec_id = mixer->shift;
480 struct device *tx_dev = NULL;
481 struct tx_macro_priv *tx_priv = NULL;
482
483 if (!tx_macro_get_data(codec, &tx_dev, &tx_priv, __func__))
484 return -EINVAL;
485
486 if (test_bit(dec_id, &tx_priv->active_ch_mask[dai_id]))
487 ucontrol->value.integer.value[0] = 1;
488 else
489 ucontrol->value.integer.value[0] = 0;
490 return 0;
491}
492
493static int tx_macro_tx_mixer_put(struct snd_kcontrol *kcontrol,
494 struct snd_ctl_elem_value *ucontrol)
495{
496 struct snd_soc_dapm_widget *widget =
497 snd_soc_dapm_kcontrol_widget(kcontrol);
498 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
499 struct snd_soc_dapm_update *update = NULL;
500 struct soc_multi_mixer_control *mixer =
501 ((struct soc_multi_mixer_control *)kcontrol->private_value);
502 u32 dai_id = widget->shift;
503 u32 dec_id = mixer->shift;
504 u32 enable = ucontrol->value.integer.value[0];
505 struct device *tx_dev = NULL;
506 struct tx_macro_priv *tx_priv = NULL;
507
508 if (!tx_macro_get_data(codec, &tx_dev, &tx_priv, __func__))
509 return -EINVAL;
510
511 if (enable) {
512 set_bit(dec_id, &tx_priv->active_ch_mask[dai_id]);
513 tx_priv->active_ch_cnt[dai_id]++;
514 } else {
515 tx_priv->active_ch_cnt[dai_id]--;
516 clear_bit(dec_id, &tx_priv->active_ch_mask[dai_id]);
517 }
518 snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, update);
519
520 return 0;
521}
522
523static int tx_macro_enable_dmic(struct snd_soc_dapm_widget *w,
524 struct snd_kcontrol *kcontrol, int event)
525{
526 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
527 u8 dmic_clk_en = 0x01;
528 u16 dmic_clk_reg = 0;
529 s32 *dmic_clk_cnt = NULL;
530 unsigned int dmic = 0;
531 int ret = 0;
532 char *wname = NULL;
533 struct device *tx_dev = NULL;
534 struct tx_macro_priv *tx_priv = NULL;
535
536 if (!tx_macro_get_data(codec, &tx_dev, &tx_priv, __func__))
537 return -EINVAL;
538
539 wname = strpbrk(w->name, "01234567");
540 if (!wname) {
541 dev_err(codec->dev, "%s: widget not found\n", __func__);
542 return -EINVAL;
543 }
544
545 ret = kstrtouint(wname, 10, &dmic);
546 if (ret < 0) {
547 dev_err(codec->dev, "%s: Invalid DMIC line on the codec\n",
548 __func__);
549 return -EINVAL;
550 }
551
552 switch (dmic) {
553 case 0:
554 case 1:
555 dmic_clk_cnt = &(tx_priv->dmic_0_1_clk_cnt);
556 dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC0_CTL;
557 break;
558 case 2:
559 case 3:
560 dmic_clk_cnt = &(tx_priv->dmic_2_3_clk_cnt);
561 dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC1_CTL;
562 break;
563 case 4:
564 case 5:
565 dmic_clk_cnt = &(tx_priv->dmic_4_5_clk_cnt);
566 dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC2_CTL;
567 break;
568 case 6:
569 case 7:
570 dmic_clk_cnt = &(tx_priv->dmic_6_7_clk_cnt);
571 dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC3_CTL;
572 break;
573 default:
574 dev_err(codec->dev, "%s: Invalid DMIC Selection\n",
575 __func__);
576 return -EINVAL;
577 }
578 dev_dbg(codec->dev, "%s: event %d DMIC%d dmic_clk_cnt %d\n",
579 __func__, event, dmic, *dmic_clk_cnt);
580
581 switch (event) {
582 case SND_SOC_DAPM_PRE_PMU:
583 (*dmic_clk_cnt)++;
584 if (*dmic_clk_cnt == 1) {
Ramprasad Katkam9c2394a2018-08-23 13:13:48 +0530585 snd_soc_update_bits(codec, BOLERO_CDC_VA_TOP_CSR_DMIC_CFG,
586 0x80, 0x00);
587
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530588 snd_soc_update_bits(codec, dmic_clk_reg,
589 0x0E, tx_priv->dmic_clk_div << 0x1);
590 snd_soc_update_bits(codec, dmic_clk_reg,
591 dmic_clk_en, dmic_clk_en);
592 }
593 break;
594 case SND_SOC_DAPM_POST_PMD:
595 (*dmic_clk_cnt)--;
596 if (*dmic_clk_cnt == 0)
597 snd_soc_update_bits(codec, dmic_clk_reg,
598 dmic_clk_en, 0);
599 break;
600 }
601
602 return 0;
603}
604
605static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w,
606 struct snd_kcontrol *kcontrol, int event)
607{
608 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
609 unsigned int decimator = 0;
610 u16 tx_vol_ctl_reg = 0;
611 u16 dec_cfg_reg = 0;
612 u16 hpf_gate_reg = 0;
613 u16 tx_gain_ctl_reg = 0;
614 u8 hpf_cut_off_freq = 0;
615 struct device *tx_dev = NULL;
616 struct tx_macro_priv *tx_priv = NULL;
617
618 if (!tx_macro_get_data(codec, &tx_dev, &tx_priv, __func__))
619 return -EINVAL;
620
621 decimator = w->shift;
622
623 dev_dbg(codec->dev, "%s(): widget = %s decimator = %u\n", __func__,
624 w->name, decimator);
625
626 tx_vol_ctl_reg = BOLERO_CDC_TX0_TX_PATH_CTL +
627 TX_MACRO_TX_PATH_OFFSET * decimator;
628 hpf_gate_reg = BOLERO_CDC_TX0_TX_PATH_SEC2 +
629 TX_MACRO_TX_PATH_OFFSET * decimator;
630 dec_cfg_reg = BOLERO_CDC_TX0_TX_PATH_CFG0 +
631 TX_MACRO_TX_PATH_OFFSET * decimator;
632 tx_gain_ctl_reg = BOLERO_CDC_TX0_TX_VOL_CTL +
633 TX_MACRO_TX_PATH_OFFSET * decimator;
634
635 switch (event) {
636 case SND_SOC_DAPM_PRE_PMU:
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530637 /* Enable TX PGA Mute */
638 snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x10);
639 break;
640 case SND_SOC_DAPM_POST_PMU:
641 snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x20, 0x20);
642 snd_soc_update_bits(codec, hpf_gate_reg, 0x01, 0x00);
643
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530644 hpf_cut_off_freq = (snd_soc_read(codec, dec_cfg_reg) &
645 TX_HPF_CUT_OFF_FREQ_MASK) >> 5;
646 tx_priv->tx_hpf_work[decimator].hpf_cut_off_freq =
647 hpf_cut_off_freq;
648
649 if (hpf_cut_off_freq != CF_MIN_3DB_150HZ)
650 snd_soc_update_bits(codec, dec_cfg_reg,
651 TX_HPF_CUT_OFF_FREQ_MASK,
652 CF_MIN_3DB_150HZ << 5);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530653 /* schedule work queue to Remove Mute */
654 schedule_delayed_work(&tx_priv->tx_mute_dwork[decimator].dwork,
655 msecs_to_jiffies(tx_unmute_delay));
656 if (tx_priv->tx_hpf_work[decimator].hpf_cut_off_freq !=
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530657 CF_MIN_3DB_150HZ) {
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530658 schedule_delayed_work(
659 &tx_priv->tx_hpf_work[decimator].dwork,
660 msecs_to_jiffies(300));
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530661 snd_soc_update_bits(codec, hpf_gate_reg, 0x02, 0x02);
662 /*
663 * Minimum 1 clk cycle delay is required as per HW spec
664 */
665 usleep_range(1000, 1010);
666 snd_soc_update_bits(codec, hpf_gate_reg, 0x02, 0x00);
667 }
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530668 /* apply gain after decimator is enabled */
669 snd_soc_write(codec, tx_gain_ctl_reg,
670 snd_soc_read(codec, tx_gain_ctl_reg));
671 break;
672 case SND_SOC_DAPM_PRE_PMD:
673 hpf_cut_off_freq =
674 tx_priv->tx_hpf_work[decimator].hpf_cut_off_freq;
675 snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x10);
676 if (cancel_delayed_work_sync(
677 &tx_priv->tx_hpf_work[decimator].dwork)) {
678 if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) {
679 snd_soc_update_bits(codec, dec_cfg_reg,
680 TX_HPF_CUT_OFF_FREQ_MASK,
681 hpf_cut_off_freq << 5);
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530682 snd_soc_update_bits(codec, hpf_gate_reg,
683 0x02, 0x02);
684 /*
685 * Minimum 1 clk cycle delay is required
686 * as per HW spec
687 */
688 usleep_range(1000, 1010);
689 snd_soc_update_bits(codec, hpf_gate_reg,
690 0x02, 0x00);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530691 }
692 }
693 cancel_delayed_work_sync(
694 &tx_priv->tx_mute_dwork[decimator].dwork);
695 break;
696 case SND_SOC_DAPM_POST_PMD:
Ramprasad Katkam9c2394a2018-08-23 13:13:48 +0530697 snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x20, 0x00);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530698 snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x00);
699 break;
700 }
701 return 0;
702}
703
704static int tx_macro_enable_micbias(struct snd_soc_dapm_widget *w,
705 struct snd_kcontrol *kcontrol, int event)
706{
707 return 0;
708}
709
710static int tx_macro_hw_params(struct snd_pcm_substream *substream,
711 struct snd_pcm_hw_params *params,
712 struct snd_soc_dai *dai)
713{
714 int tx_fs_rate = -EINVAL;
715 struct snd_soc_codec *codec = dai->codec;
716 u32 decimator = 0;
Laxminath Kasamb7f823c2018-08-02 13:23:11 +0530717 u32 sample_rate = 0;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530718 u16 tx_fs_reg = 0;
719 struct device *tx_dev = NULL;
720 struct tx_macro_priv *tx_priv = NULL;
721
722 if (!tx_macro_get_data(codec, &tx_dev, &tx_priv, __func__))
723 return -EINVAL;
724
725 pr_debug("%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__,
726 dai->name, dai->id, params_rate(params),
727 params_channels(params));
728
729 sample_rate = params_rate(params);
730 switch (sample_rate) {
731 case 8000:
732 tx_fs_rate = 0;
733 break;
734 case 16000:
735 tx_fs_rate = 1;
736 break;
737 case 32000:
738 tx_fs_rate = 3;
739 break;
740 case 48000:
741 tx_fs_rate = 4;
742 break;
743 case 96000:
744 tx_fs_rate = 5;
745 break;
746 case 192000:
747 tx_fs_rate = 6;
748 break;
749 case 384000:
750 tx_fs_rate = 7;
751 break;
752 default:
753 dev_err(codec->dev, "%s: Invalid TX sample rate: %d\n",
754 __func__, params_rate(params));
755 return -EINVAL;
756 }
757 for_each_set_bit(decimator, &tx_priv->active_ch_mask[dai->id],
758 TX_MACRO_DEC_MAX) {
759 if (decimator >= 0) {
760 tx_fs_reg = BOLERO_CDC_TX0_TX_PATH_CTL +
761 TX_MACRO_TX_PATH_OFFSET * decimator;
762 dev_dbg(codec->dev, "%s: set DEC%u rate to %u\n",
763 __func__, decimator, sample_rate);
764 snd_soc_update_bits(codec, tx_fs_reg, 0x0F,
765 tx_fs_rate);
766 } else {
767 dev_err(codec->dev,
768 "%s: ERROR: Invalid decimator: %d\n",
769 __func__, decimator);
770 return -EINVAL;
771 }
772 }
773 return 0;
774}
775
776static int tx_macro_get_channel_map(struct snd_soc_dai *dai,
777 unsigned int *tx_num, unsigned int *tx_slot,
778 unsigned int *rx_num, unsigned int *rx_slot)
779{
780 struct snd_soc_codec *codec = dai->codec;
781 struct device *tx_dev = NULL;
782 struct tx_macro_priv *tx_priv = NULL;
783
784 if (!tx_macro_get_data(codec, &tx_dev, &tx_priv, __func__))
785 return -EINVAL;
786
787 switch (dai->id) {
788 case TX_MACRO_AIF1_CAP:
789 case TX_MACRO_AIF2_CAP:
790 *tx_slot = tx_priv->active_ch_mask[dai->id];
791 *tx_num = tx_priv->active_ch_cnt[dai->id];
792 break;
793 default:
794 dev_err(tx_dev, "%s: Invalid AIF\n", __func__);
795 break;
796 }
797 return 0;
798}
799
800static struct snd_soc_dai_ops tx_macro_dai_ops = {
801 .hw_params = tx_macro_hw_params,
802 .get_channel_map = tx_macro_get_channel_map,
803};
804
805static struct snd_soc_dai_driver tx_macro_dai[] = {
806 {
807 .name = "tx_macro_tx1",
808 .id = TX_MACRO_AIF1_CAP,
809 .capture = {
810 .stream_name = "TX_AIF1 Capture",
811 .rates = TX_MACRO_RATES,
812 .formats = TX_MACRO_FORMATS,
813 .rate_max = 192000,
814 .rate_min = 8000,
815 .channels_min = 1,
816 .channels_max = 8,
817 },
818 .ops = &tx_macro_dai_ops,
819 },
820 {
821 .name = "tx_macro_tx2",
822 .id = TX_MACRO_AIF2_CAP,
823 .capture = {
824 .stream_name = "TX_AIF2 Capture",
825 .rates = TX_MACRO_RATES,
826 .formats = TX_MACRO_FORMATS,
827 .rate_max = 192000,
828 .rate_min = 8000,
829 .channels_min = 1,
830 .channels_max = 8,
831 },
832 .ops = &tx_macro_dai_ops,
833 },
834};
835
836#define STRING(name) #name
837#define TX_MACRO_DAPM_ENUM(name, reg, offset, text) \
838static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \
839static const struct snd_kcontrol_new name##_mux = \
840 SOC_DAPM_ENUM(STRING(name), name##_enum)
841
842#define TX_MACRO_DAPM_ENUM_EXT(name, reg, offset, text, getname, putname) \
843static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \
844static const struct snd_kcontrol_new name##_mux = \
845 SOC_DAPM_ENUM_EXT(STRING(name), name##_enum, getname, putname)
846
847#define TX_MACRO_DAPM_MUX(name, shift, kctl) \
848 SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, shift, 0, &kctl##_mux)
849
850static const char * const adc_mux_text[] = {
851 "MSM_DMIC", "SWR_MIC", "ANC_FB_TUNE1"
852};
853
854TX_MACRO_DAPM_ENUM(tx_dec0, BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG1,
855 0, adc_mux_text);
856TX_MACRO_DAPM_ENUM(tx_dec1, BOLERO_CDC_TX_INP_MUX_ADC_MUX1_CFG1,
857 0, adc_mux_text);
858TX_MACRO_DAPM_ENUM(tx_dec2, BOLERO_CDC_TX_INP_MUX_ADC_MUX2_CFG1,
859 0, adc_mux_text);
860TX_MACRO_DAPM_ENUM(tx_dec3, BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG1,
861 0, adc_mux_text);
862TX_MACRO_DAPM_ENUM(tx_dec4, BOLERO_CDC_TX_INP_MUX_ADC_MUX4_CFG1,
863 0, adc_mux_text);
864TX_MACRO_DAPM_ENUM(tx_dec5, BOLERO_CDC_TX_INP_MUX_ADC_MUX5_CFG1,
865 0, adc_mux_text);
866TX_MACRO_DAPM_ENUM(tx_dec6, BOLERO_CDC_TX_INP_MUX_ADC_MUX6_CFG1,
867 0, adc_mux_text);
868TX_MACRO_DAPM_ENUM(tx_dec7, BOLERO_CDC_TX_INP_MUX_ADC_MUX7_CFG1,
869 0, adc_mux_text);
870
871
872static const char * const dmic_mux_text[] = {
873 "ZERO", "DMIC0", "DMIC1", "DMIC2", "DMIC3",
874 "DMIC4", "DMIC5", "DMIC6", "DMIC7"
875};
876
877TX_MACRO_DAPM_ENUM_EXT(tx_dmic0, BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0,
878 4, dmic_mux_text, snd_soc_dapm_get_enum_double,
879 tx_macro_put_dec_enum);
880
881TX_MACRO_DAPM_ENUM_EXT(tx_dmic1, BOLERO_CDC_TX_INP_MUX_ADC_MUX1_CFG0,
882 4, dmic_mux_text, snd_soc_dapm_get_enum_double,
883 tx_macro_put_dec_enum);
884
885TX_MACRO_DAPM_ENUM_EXT(tx_dmic2, BOLERO_CDC_TX_INP_MUX_ADC_MUX2_CFG0,
886 4, dmic_mux_text, snd_soc_dapm_get_enum_double,
887 tx_macro_put_dec_enum);
888
889TX_MACRO_DAPM_ENUM_EXT(tx_dmic3, BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG0,
890 4, dmic_mux_text, snd_soc_dapm_get_enum_double,
891 tx_macro_put_dec_enum);
892
893TX_MACRO_DAPM_ENUM_EXT(tx_dmic4, BOLERO_CDC_TX_INP_MUX_ADC_MUX4_CFG0,
894 4, dmic_mux_text, snd_soc_dapm_get_enum_double,
895 tx_macro_put_dec_enum);
896
897TX_MACRO_DAPM_ENUM_EXT(tx_dmic5, BOLERO_CDC_TX_INP_MUX_ADC_MUX5_CFG0,
898 4, dmic_mux_text, snd_soc_dapm_get_enum_double,
899 tx_macro_put_dec_enum);
900
901TX_MACRO_DAPM_ENUM_EXT(tx_dmic6, BOLERO_CDC_TX_INP_MUX_ADC_MUX6_CFG0,
902 4, dmic_mux_text, snd_soc_dapm_get_enum_double,
903 tx_macro_put_dec_enum);
904
905TX_MACRO_DAPM_ENUM_EXT(tx_dmic7, BOLERO_CDC_TX_INP_MUX_ADC_MUX7_CFG0,
906 4, dmic_mux_text, snd_soc_dapm_get_enum_double,
907 tx_macro_put_dec_enum);
908
909static const char * const smic_mux_text[] = {
910 "ZERO", "ADC0", "ADC1", "ADC2", "ADC3",
911 "SWR_DMIC0", "SWR_DMIC1", "SWR_DMIC2", "SWR_DMIC3",
912 "SWR_DMIC4", "SWR_DMIC5", "SWR_DMIC6", "SWR_DMIC7"
913};
914
915TX_MACRO_DAPM_ENUM_EXT(tx_smic0, BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0,
916 0, smic_mux_text, snd_soc_dapm_get_enum_double,
917 tx_macro_put_dec_enum);
918
919TX_MACRO_DAPM_ENUM_EXT(tx_smic1, BOLERO_CDC_TX_INP_MUX_ADC_MUX1_CFG0,
920 0, smic_mux_text, snd_soc_dapm_get_enum_double,
921 tx_macro_put_dec_enum);
922
923TX_MACRO_DAPM_ENUM_EXT(tx_smic2, BOLERO_CDC_TX_INP_MUX_ADC_MUX2_CFG0,
924 0, smic_mux_text, snd_soc_dapm_get_enum_double,
925 tx_macro_put_dec_enum);
926
927TX_MACRO_DAPM_ENUM_EXT(tx_smic3, BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG0,
928 0, smic_mux_text, snd_soc_dapm_get_enum_double,
929 tx_macro_put_dec_enum);
930
931TX_MACRO_DAPM_ENUM_EXT(tx_smic4, BOLERO_CDC_TX_INP_MUX_ADC_MUX4_CFG0,
932 0, smic_mux_text, snd_soc_dapm_get_enum_double,
933 tx_macro_put_dec_enum);
934
935TX_MACRO_DAPM_ENUM_EXT(tx_smic5, BOLERO_CDC_TX_INP_MUX_ADC_MUX5_CFG0,
936 0, smic_mux_text, snd_soc_dapm_get_enum_double,
937 tx_macro_put_dec_enum);
938
939TX_MACRO_DAPM_ENUM_EXT(tx_smic6, BOLERO_CDC_TX_INP_MUX_ADC_MUX6_CFG0,
940 0, smic_mux_text, snd_soc_dapm_get_enum_double,
941 tx_macro_put_dec_enum);
942
943TX_MACRO_DAPM_ENUM_EXT(tx_smic7, BOLERO_CDC_TX_INP_MUX_ADC_MUX7_CFG0,
944 0, smic_mux_text, snd_soc_dapm_get_enum_double,
945 tx_macro_put_dec_enum);
946
947static const struct snd_kcontrol_new tx_aif1_cap_mixer[] = {
948 SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, TX_MACRO_DEC0, 1, 0,
949 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
950 SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, TX_MACRO_DEC1, 1, 0,
951 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
952 SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, TX_MACRO_DEC2, 1, 0,
953 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
954 SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, TX_MACRO_DEC3, 1, 0,
955 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
956 SOC_SINGLE_EXT("DEC4", SND_SOC_NOPM, TX_MACRO_DEC4, 1, 0,
957 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
958 SOC_SINGLE_EXT("DEC5", SND_SOC_NOPM, TX_MACRO_DEC5, 1, 0,
959 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
960 SOC_SINGLE_EXT("DEC6", SND_SOC_NOPM, TX_MACRO_DEC6, 1, 0,
961 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
962 SOC_SINGLE_EXT("DEC7", SND_SOC_NOPM, TX_MACRO_DEC7, 1, 0,
963 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
964};
965
966static const struct snd_kcontrol_new tx_aif2_cap_mixer[] = {
967 SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, TX_MACRO_DEC0, 1, 0,
968 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
969 SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, TX_MACRO_DEC1, 1, 0,
970 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
971 SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, TX_MACRO_DEC2, 1, 0,
972 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
973 SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, TX_MACRO_DEC3, 1, 0,
974 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
975 SOC_SINGLE_EXT("DEC4", SND_SOC_NOPM, TX_MACRO_DEC4, 1, 0,
976 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
977 SOC_SINGLE_EXT("DEC5", SND_SOC_NOPM, TX_MACRO_DEC5, 1, 0,
978 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
979 SOC_SINGLE_EXT("DEC6", SND_SOC_NOPM, TX_MACRO_DEC6, 1, 0,
980 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
981 SOC_SINGLE_EXT("DEC7", SND_SOC_NOPM, TX_MACRO_DEC7, 1, 0,
982 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
983};
984
985static const struct snd_soc_dapm_widget tx_macro_dapm_widgets[] = {
986 SND_SOC_DAPM_AIF_OUT("TX_AIF1 CAP", "TX_AIF1 Capture", 0,
987 SND_SOC_NOPM, TX_MACRO_AIF1_CAP, 0),
988
989 SND_SOC_DAPM_AIF_OUT("TX_AIF2 CAP", "TX_AIF2 Capture", 0,
990 SND_SOC_NOPM, TX_MACRO_AIF2_CAP, 0),
991
992 SND_SOC_DAPM_MIXER("TX_AIF1_CAP Mixer", SND_SOC_NOPM, TX_MACRO_AIF1_CAP, 0,
993 tx_aif1_cap_mixer, ARRAY_SIZE(tx_aif1_cap_mixer)),
994
995 SND_SOC_DAPM_MIXER("TX_AIF2_CAP Mixer", SND_SOC_NOPM, TX_MACRO_AIF2_CAP, 0,
996 tx_aif2_cap_mixer, ARRAY_SIZE(tx_aif2_cap_mixer)),
997
998
999 TX_MACRO_DAPM_MUX("TX DMIC MUX0", 0, tx_dmic0),
1000 TX_MACRO_DAPM_MUX("TX DMIC MUX1", 0, tx_dmic1),
1001 TX_MACRO_DAPM_MUX("TX DMIC MUX2", 0, tx_dmic2),
1002 TX_MACRO_DAPM_MUX("TX DMIC MUX3", 0, tx_dmic3),
1003 TX_MACRO_DAPM_MUX("TX DMIC MUX4", 0, tx_dmic4),
1004 TX_MACRO_DAPM_MUX("TX DMIC MUX5", 0, tx_dmic5),
1005 TX_MACRO_DAPM_MUX("TX DMIC MUX6", 0, tx_dmic6),
1006 TX_MACRO_DAPM_MUX("TX DMIC MUX7", 0, tx_dmic7),
1007
1008 TX_MACRO_DAPM_MUX("TX SMIC MUX0", 0, tx_smic0),
1009 TX_MACRO_DAPM_MUX("TX SMIC MUX1", 0, tx_smic1),
1010 TX_MACRO_DAPM_MUX("TX SMIC MUX2", 0, tx_smic2),
1011 TX_MACRO_DAPM_MUX("TX SMIC MUX3", 0, tx_smic3),
1012 TX_MACRO_DAPM_MUX("TX SMIC MUX4", 0, tx_smic4),
1013 TX_MACRO_DAPM_MUX("TX SMIC MUX5", 0, tx_smic5),
1014 TX_MACRO_DAPM_MUX("TX SMIC MUX6", 0, tx_smic6),
1015 TX_MACRO_DAPM_MUX("TX SMIC MUX7", 0, tx_smic7),
1016
1017 SND_SOC_DAPM_MICBIAS_E("TX MIC BIAS1", SND_SOC_NOPM, 0, 0,
1018 tx_macro_enable_micbias,
1019 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1020 SND_SOC_DAPM_ADC_E("TX DMIC0", NULL, SND_SOC_NOPM, 0, 0,
1021 tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
1022 SND_SOC_DAPM_POST_PMD),
1023
1024 SND_SOC_DAPM_ADC_E("TX DMIC1", NULL, SND_SOC_NOPM, 0, 0,
1025 tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
1026 SND_SOC_DAPM_POST_PMD),
1027
1028 SND_SOC_DAPM_ADC_E("TX DMIC2", NULL, SND_SOC_NOPM, 0, 0,
1029 tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
1030 SND_SOC_DAPM_POST_PMD),
1031
1032 SND_SOC_DAPM_ADC_E("TX DMIC3", NULL, SND_SOC_NOPM, 0, 0,
1033 tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
1034 SND_SOC_DAPM_POST_PMD),
1035
1036 SND_SOC_DAPM_ADC_E("TX DMIC4", NULL, SND_SOC_NOPM, 0, 0,
1037 tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
1038 SND_SOC_DAPM_POST_PMD),
1039
1040 SND_SOC_DAPM_ADC_E("TX DMIC5", NULL, SND_SOC_NOPM, 0, 0,
1041 tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
1042 SND_SOC_DAPM_POST_PMD),
1043
1044 SND_SOC_DAPM_ADC_E("TX DMIC6", NULL, SND_SOC_NOPM, 0, 0,
1045 tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
1046 SND_SOC_DAPM_POST_PMD),
1047
1048 SND_SOC_DAPM_ADC_E("TX DMIC7", NULL, SND_SOC_NOPM, 0, 0,
1049 tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
1050 SND_SOC_DAPM_POST_PMD),
1051
1052 SND_SOC_DAPM_INPUT("TX SWR_ADC0"),
1053 SND_SOC_DAPM_INPUT("TX SWR_ADC1"),
1054 SND_SOC_DAPM_INPUT("TX SWR_ADC2"),
1055 SND_SOC_DAPM_INPUT("TX SWR_ADC3"),
1056 SND_SOC_DAPM_INPUT("TX SWR_DMIC0"),
1057 SND_SOC_DAPM_INPUT("TX SWR_DMIC1"),
1058 SND_SOC_DAPM_INPUT("TX SWR_DMIC2"),
1059 SND_SOC_DAPM_INPUT("TX SWR_DMIC3"),
1060 SND_SOC_DAPM_INPUT("TX SWR_DMIC4"),
1061 SND_SOC_DAPM_INPUT("TX SWR_DMIC5"),
1062 SND_SOC_DAPM_INPUT("TX SWR_DMIC6"),
1063 SND_SOC_DAPM_INPUT("TX SWR_DMIC7"),
1064
Ramprasad Katkamf83acfb2018-08-11 23:28:57 +05301065 SND_SOC_DAPM_MUX_E("TX DEC0 MUX", SND_SOC_NOPM,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301066 TX_MACRO_DEC0, 0,
1067 &tx_dec0_mux, tx_macro_enable_dec,
1068 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1069 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1070
Ramprasad Katkamf83acfb2018-08-11 23:28:57 +05301071 SND_SOC_DAPM_MUX_E("TX DEC1 MUX", SND_SOC_NOPM,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301072 TX_MACRO_DEC1, 0,
1073 &tx_dec1_mux, tx_macro_enable_dec,
1074 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1075 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1076
Ramprasad Katkamf83acfb2018-08-11 23:28:57 +05301077 SND_SOC_DAPM_MUX_E("TX DEC2 MUX", SND_SOC_NOPM,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301078 TX_MACRO_DEC2, 0,
1079 &tx_dec2_mux, tx_macro_enable_dec,
1080 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1081 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1082
Ramprasad Katkamf83acfb2018-08-11 23:28:57 +05301083 SND_SOC_DAPM_MUX_E("TX DEC3 MUX", SND_SOC_NOPM,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301084 TX_MACRO_DEC3, 0,
1085 &tx_dec3_mux, tx_macro_enable_dec,
1086 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1087 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1088
Ramprasad Katkamf83acfb2018-08-11 23:28:57 +05301089 SND_SOC_DAPM_MUX_E("TX DEC4 MUX", SND_SOC_NOPM,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301090 TX_MACRO_DEC4, 0,
1091 &tx_dec4_mux, tx_macro_enable_dec,
1092 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1093 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1094
Ramprasad Katkamf83acfb2018-08-11 23:28:57 +05301095 SND_SOC_DAPM_MUX_E("TX DEC5 MUX", SND_SOC_NOPM,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301096 TX_MACRO_DEC5, 0,
1097 &tx_dec5_mux, tx_macro_enable_dec,
1098 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1099 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1100
Ramprasad Katkamf83acfb2018-08-11 23:28:57 +05301101 SND_SOC_DAPM_MUX_E("TX DEC6 MUX", SND_SOC_NOPM,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301102 TX_MACRO_DEC6, 0,
1103 &tx_dec6_mux, tx_macro_enable_dec,
1104 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1105 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1106
Ramprasad Katkamf83acfb2018-08-11 23:28:57 +05301107 SND_SOC_DAPM_MUX_E("TX DEC7 MUX", SND_SOC_NOPM,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301108 TX_MACRO_DEC7, 0,
1109 &tx_dec7_mux, tx_macro_enable_dec,
1110 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1111 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1112
1113 SND_SOC_DAPM_SUPPLY_S("TX_MCLK", 0, SND_SOC_NOPM, 0, 0,
1114 tx_macro_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1115};
1116
1117static const struct snd_soc_dapm_route tx_audio_map[] = {
1118 {"TX_AIF1 CAP", NULL, "TX_MCLK"},
1119 {"TX_AIF2 CAP", NULL, "TX_MCLK"},
1120
1121 {"TX_AIF1 CAP", NULL, "TX_AIF1_CAP Mixer"},
1122 {"TX_AIF2 CAP", NULL, "TX_AIF2_CAP Mixer"},
1123
1124 {"TX_AIF1_CAP Mixer", "DEC0", "TX DEC0 MUX"},
1125 {"TX_AIF1_CAP Mixer", "DEC1", "TX DEC1 MUX"},
1126 {"TX_AIF1_CAP Mixer", "DEC2", "TX DEC2 MUX"},
1127 {"TX_AIF1_CAP Mixer", "DEC3", "TX DEC3 MUX"},
1128 {"TX_AIF1_CAP Mixer", "DEC4", "TX DEC4 MUX"},
1129 {"TX_AIF1_CAP Mixer", "DEC5", "TX DEC5 MUX"},
1130 {"TX_AIF1_CAP Mixer", "DEC6", "TX DEC6 MUX"},
1131 {"TX_AIF1_CAP Mixer", "DEC7", "TX DEC7 MUX"},
1132
1133 {"TX_AIF2_CAP Mixer", "DEC0", "TX DEC0 MUX"},
1134 {"TX_AIF2_CAP Mixer", "DEC1", "TX DEC1 MUX"},
1135 {"TX_AIF2_CAP Mixer", "DEC2", "TX DEC2 MUX"},
1136 {"TX_AIF2_CAP Mixer", "DEC3", "TX DEC3 MUX"},
1137 {"TX_AIF2_CAP Mixer", "DEC4", "TX DEC4 MUX"},
1138 {"TX_AIF2_CAP Mixer", "DEC5", "TX DEC5 MUX"},
1139 {"TX_AIF2_CAP Mixer", "DEC6", "TX DEC6 MUX"},
1140 {"TX_AIF2_CAP Mixer", "DEC7", "TX DEC7 MUX"},
1141
Laxminath Kasamfc281ad2018-08-06 20:19:40 +05301142 {"TX DEC0 MUX", NULL, "TX_MCLK"},
1143 {"TX DEC1 MUX", NULL, "TX_MCLK"},
1144 {"TX DEC2 MUX", NULL, "TX_MCLK"},
1145 {"TX DEC3 MUX", NULL, "TX_MCLK"},
1146 {"TX DEC4 MUX", NULL, "TX_MCLK"},
1147 {"TX DEC5 MUX", NULL, "TX_MCLK"},
1148 {"TX DEC6 MUX", NULL, "TX_MCLK"},
1149 {"TX DEC7 MUX", NULL, "TX_MCLK"},
1150
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301151 {"TX DEC0 MUX", "MSM_DMIC", "TX DMIC MUX0"},
1152 {"TX DMIC MUX0", "DMIC0", "TX DMIC0"},
1153 {"TX DMIC MUX0", "DMIC1", "TX DMIC1"},
1154 {"TX DMIC MUX0", "DMIC2", "TX DMIC2"},
1155 {"TX DMIC MUX0", "DMIC3", "TX DMIC3"},
1156 {"TX DMIC MUX0", "DMIC4", "TX DMIC4"},
1157 {"TX DMIC MUX0", "DMIC5", "TX DMIC5"},
1158 {"TX DMIC MUX0", "DMIC6", "TX DMIC6"},
1159 {"TX DMIC MUX0", "DMIC7", "TX DMIC7"},
1160
1161 {"TX DEC0 MUX", "SWR_MIC", "TX SMIC MUX0"},
1162 {"TX SMIC MUX0", "ADC0", "TX SWR_ADC0"},
1163 {"TX SMIC MUX0", "ADC1", "TX SWR_ADC1"},
1164 {"TX SMIC MUX0", "ADC2", "TX SWR_ADC2"},
1165 {"TX SMIC MUX0", "ADC3", "TX SWR_ADC3"},
1166 {"TX SMIC MUX0", "SWR_DMIC0", "TX SWR_DMIC0"},
1167 {"TX SMIC MUX0", "SWR_DMIC1", "TX SWR_DMIC1"},
1168 {"TX SMIC MUX0", "SWR_DMIC2", "TX SWR_DMIC2"},
1169 {"TX SMIC MUX0", "SWR_DMIC3", "TX SWR_DMIC3"},
1170 {"TX SMIC MUX0", "SWR_DMIC4", "TX SWR_DMIC4"},
1171 {"TX SMIC MUX0", "SWR_DMIC5", "TX SWR_DMIC5"},
1172 {"TX SMIC MUX0", "SWR_DMIC6", "TX SWR_DMIC6"},
1173 {"TX SMIC MUX0", "SWR_DMIC7", "TX SWR_DMIC7"},
1174
1175 {"TX DEC1 MUX", "MSM_DMIC", "TX DMIC MUX1"},
1176 {"TX DMIC MUX1", "DMIC0", "TX DMIC0"},
1177 {"TX DMIC MUX1", "DMIC1", "TX DMIC1"},
1178 {"TX DMIC MUX1", "DMIC2", "TX DMIC2"},
1179 {"TX DMIC MUX1", "DMIC3", "TX DMIC3"},
1180 {"TX DMIC MUX1", "DMIC4", "TX DMIC4"},
1181 {"TX DMIC MUX1", "DMIC5", "TX DMIC5"},
1182 {"TX DMIC MUX1", "DMIC6", "TX DMIC6"},
1183 {"TX DMIC MUX1", "DMIC7", "TX DMIC7"},
1184
1185 {"TX DEC1 MUX", "SWR_MIC", "TX SMIC MUX1"},
1186 {"TX SMIC MUX1", "ADC0", "TX SWR_ADC0"},
1187 {"TX SMIC MUX1", "ADC1", "TX SWR_ADC1"},
1188 {"TX SMIC MUX1", "ADC2", "TX SWR_ADC2"},
1189 {"TX SMIC MUX1", "ADC3", "TX SWR_ADC3"},
1190 {"TX SMIC MUX1", "SWR_DMIC0", "TX SWR_DMIC0"},
1191 {"TX SMIC MUX1", "SWR_DMIC1", "TX SWR_DMIC1"},
1192 {"TX SMIC MUX1", "SWR_DMIC2", "TX SWR_DMIC2"},
1193 {"TX SMIC MUX1", "SWR_DMIC3", "TX SWR_DMIC3"},
1194 {"TX SMIC MUX1", "SWR_DMIC4", "TX SWR_DMIC4"},
1195 {"TX SMIC MUX1", "SWR_DMIC5", "TX SWR_DMIC5"},
1196 {"TX SMIC MUX1", "SWR_DMIC6", "TX SWR_DMIC6"},
1197 {"TX SMIC MUX1", "SWR_DMIC7", "TX SWR_DMIC7"},
1198
1199 {"TX DEC2 MUX", "MSM_DMIC", "TX DMIC MUX2"},
1200 {"TX DMIC MUX2", "DMIC0", "TX DMIC0"},
1201 {"TX DMIC MUX2", "DMIC1", "TX DMIC1"},
1202 {"TX DMIC MUX2", "DMIC2", "TX DMIC2"},
1203 {"TX DMIC MUX2", "DMIC3", "TX DMIC3"},
1204 {"TX DMIC MUX2", "DMIC4", "TX DMIC4"},
1205 {"TX DMIC MUX2", "DMIC5", "TX DMIC5"},
1206 {"TX DMIC MUX2", "DMIC6", "TX DMIC6"},
1207 {"TX DMIC MUX2", "DMIC7", "TX DMIC7"},
1208
1209 {"TX DEC2 MUX", "SWR_MIC", "TX SMIC MUX2"},
1210 {"TX SMIC MUX2", "ADC0", "TX SWR_ADC0"},
1211 {"TX SMIC MUX2", "ADC1", "TX SWR_ADC1"},
1212 {"TX SMIC MUX2", "ADC2", "TX SWR_ADC2"},
1213 {"TX SMIC MUX2", "ADC3", "TX SWR_ADC3"},
1214 {"TX SMIC MUX2", "SWR_DMIC0", "TX SWR_DMIC0"},
1215 {"TX SMIC MUX2", "SWR_DMIC1", "TX SWR_DMIC1"},
1216 {"TX SMIC MUX2", "SWR_DMIC2", "TX SWR_DMIC2"},
1217 {"TX SMIC MUX2", "SWR_DMIC3", "TX SWR_DMIC3"},
1218 {"TX SMIC MUX2", "SWR_DMIC4", "TX SWR_DMIC4"},
1219 {"TX SMIC MUX2", "SWR_DMIC5", "TX SWR_DMIC5"},
1220 {"TX SMIC MUX2", "SWR_DMIC6", "TX SWR_DMIC6"},
1221 {"TX SMIC MUX2", "SWR_DMIC7", "TX SWR_DMIC7"},
1222
1223 {"TX DEC3 MUX", "MSM_DMIC", "TX DMIC MUX3"},
1224 {"TX DMIC MUX3", "DMIC0", "TX DMIC0"},
1225 {"TX DMIC MUX3", "DMIC1", "TX DMIC1"},
1226 {"TX DMIC MUX3", "DMIC2", "TX DMIC2"},
1227 {"TX DMIC MUX3", "DMIC3", "TX DMIC3"},
1228 {"TX DMIC MUX3", "DMIC4", "TX DMIC4"},
1229 {"TX DMIC MUX3", "DMIC5", "TX DMIC5"},
1230 {"TX DMIC MUX3", "DMIC6", "TX DMIC6"},
1231 {"TX DMIC MUX3", "DMIC7", "TX DMIC7"},
1232
1233 {"TX DEC3 MUX", "SWR_MIC", "TX SMIC MUX3"},
1234 {"TX SMIC MUX3", "ADC0", "TX SWR_ADC0"},
1235 {"TX SMIC MUX3", "ADC1", "TX SWR_ADC1"},
1236 {"TX SMIC MUX3", "ADC2", "TX SWR_ADC2"},
1237 {"TX SMIC MUX3", "ADC3", "TX SWR_ADC3"},
1238 {"TX SMIC MUX3", "SWR_DMIC0", "TX SWR_DMIC0"},
1239 {"TX SMIC MUX3", "SWR_DMIC1", "TX SWR_DMIC1"},
1240 {"TX SMIC MUX3", "SWR_DMIC2", "TX SWR_DMIC2"},
1241 {"TX SMIC MUX3", "SWR_DMIC3", "TX SWR_DMIC3"},
1242 {"TX SMIC MUX3", "SWR_DMIC4", "TX SWR_DMIC4"},
1243 {"TX SMIC MUX3", "SWR_DMIC5", "TX SWR_DMIC5"},
1244 {"TX SMIC MUX3", "SWR_DMIC6", "TX SWR_DMIC6"},
1245 {"TX SMIC MUX3", "SWR_DMIC7", "TX SWR_DMIC7"},
1246
1247 {"TX DEC4 MUX", "MSM_DMIC", "TX DMIC MUX4"},
1248 {"TX DMIC MUX4", "DMIC0", "TX DMIC0"},
1249 {"TX DMIC MUX4", "DMIC1", "TX DMIC1"},
1250 {"TX DMIC MUX4", "DMIC2", "TX DMIC2"},
1251 {"TX DMIC MUX4", "DMIC3", "TX DMIC3"},
1252 {"TX DMIC MUX4", "DMIC4", "TX DMIC4"},
1253 {"TX DMIC MUX4", "DMIC5", "TX DMIC5"},
1254 {"TX DMIC MUX4", "DMIC6", "TX DMIC6"},
1255 {"TX DMIC MUX4", "DMIC7", "TX DMIC7"},
1256
1257 {"TX DEC4 MUX", "SWR_MIC", "TX SMIC MUX4"},
1258 {"TX SMIC MUX4", "ADC0", "TX SWR_ADC0"},
1259 {"TX SMIC MUX4", "ADC1", "TX SWR_ADC1"},
1260 {"TX SMIC MUX4", "ADC2", "TX SWR_ADC2"},
1261 {"TX SMIC MUX4", "ADC3", "TX SWR_ADC3"},
1262 {"TX SMIC MUX4", "SWR_DMIC0", "TX SWR_DMIC0"},
1263 {"TX SMIC MUX4", "SWR_DMIC1", "TX SWR_DMIC1"},
1264 {"TX SMIC MUX4", "SWR_DMIC2", "TX SWR_DMIC2"},
1265 {"TX SMIC MUX4", "SWR_DMIC3", "TX SWR_DMIC3"},
1266 {"TX SMIC MUX4", "SWR_DMIC4", "TX SWR_DMIC4"},
1267 {"TX SMIC MUX4", "SWR_DMIC5", "TX SWR_DMIC5"},
1268 {"TX SMIC MUX4", "SWR_DMIC6", "TX SWR_DMIC6"},
1269 {"TX SMIC MUX4", "SWR_DMIC7", "TX SWR_DMIC7"},
1270
1271 {"TX DEC5 MUX", "MSM_DMIC", "TX DMIC MUX5"},
1272 {"TX DMIC MUX5", "DMIC0", "TX DMIC0"},
1273 {"TX DMIC MUX5", "DMIC1", "TX DMIC1"},
1274 {"TX DMIC MUX5", "DMIC2", "TX DMIC2"},
1275 {"TX DMIC MUX5", "DMIC3", "TX DMIC3"},
1276 {"TX DMIC MUX5", "DMIC4", "TX DMIC4"},
1277 {"TX DMIC MUX5", "DMIC5", "TX DMIC5"},
1278 {"TX DMIC MUX5", "DMIC6", "TX DMIC6"},
1279 {"TX DMIC MUX5", "DMIC7", "TX DMIC7"},
1280
1281 {"TX DEC5 MUX", "SWR_MIC", "TX SMIC MUX5"},
1282 {"TX SMIC MUX5", "ADC0", "TX SWR_ADC0"},
1283 {"TX SMIC MUX5", "ADC1", "TX SWR_ADC1"},
1284 {"TX SMIC MUX5", "ADC2", "TX SWR_ADC2"},
1285 {"TX SMIC MUX5", "ADC3", "TX SWR_ADC3"},
1286 {"TX SMIC MUX5", "SWR_DMIC0", "TX SWR_DMIC0"},
1287 {"TX SMIC MUX5", "SWR_DMIC1", "TX SWR_DMIC1"},
1288 {"TX SMIC MUX5", "SWR_DMIC2", "TX SWR_DMIC2"},
1289 {"TX SMIC MUX5", "SWR_DMIC3", "TX SWR_DMIC3"},
1290 {"TX SMIC MUX5", "SWR_DMIC4", "TX SWR_DMIC4"},
1291 {"TX SMIC MUX5", "SWR_DMIC5", "TX SWR_DMIC5"},
1292 {"TX SMIC MUX5", "SWR_DMIC6", "TX SWR_DMIC6"},
1293 {"TX SMIC MUX5", "SWR_DMIC7", "TX SWR_DMIC7"},
1294
1295 {"TX DEC6 MUX", "MSM_DMIC", "TX DMIC MUX6"},
1296 {"TX DMIC MUX6", "DMIC0", "TX DMIC0"},
1297 {"TX DMIC MUX6", "DMIC1", "TX DMIC1"},
1298 {"TX DMIC MUX6", "DMIC2", "TX DMIC2"},
1299 {"TX DMIC MUX6", "DMIC3", "TX DMIC3"},
1300 {"TX DMIC MUX6", "DMIC4", "TX DMIC4"},
1301 {"TX DMIC MUX6", "DMIC5", "TX DMIC5"},
1302 {"TX DMIC MUX6", "DMIC6", "TX DMIC6"},
1303 {"TX DMIC MUX6", "DMIC7", "TX DMIC7"},
1304
1305 {"TX DEC6 MUX", "SWR_MIC", "TX SMIC MUX6"},
1306 {"TX SMIC MUX6", "ADC0", "TX SWR_ADC0"},
1307 {"TX SMIC MUX6", "ADC1", "TX SWR_ADC1"},
1308 {"TX SMIC MUX6", "ADC2", "TX SWR_ADC2"},
1309 {"TX SMIC MUX6", "ADC3", "TX SWR_ADC3"},
1310 {"TX SMIC MUX6", "SWR_DMIC0", "TX SWR_DMIC0"},
1311 {"TX SMIC MUX6", "SWR_DMIC1", "TX SWR_DMIC1"},
1312 {"TX SMIC MUX6", "SWR_DMIC2", "TX SWR_DMIC2"},
1313 {"TX SMIC MUX6", "SWR_DMIC3", "TX SWR_DMIC3"},
1314 {"TX SMIC MUX6", "SWR_DMIC4", "TX SWR_DMIC4"},
1315 {"TX SMIC MUX6", "SWR_DMIC5", "TX SWR_DMIC5"},
1316 {"TX SMIC MUX6", "SWR_DMIC6", "TX SWR_DMIC6"},
1317 {"TX SMIC MUX6", "SWR_DMIC7", "TX SWR_DMIC7"},
1318
1319 {"TX DEC7 MUX", "MSM_DMIC", "TX DMIC MUX7"},
1320 {"TX DMIC MUX7", "DMIC0", "TX DMIC0"},
1321 {"TX DMIC MUX7", "DMIC1", "TX DMIC1"},
1322 {"TX DMIC MUX7", "DMIC2", "TX DMIC2"},
1323 {"TX DMIC MUX7", "DMIC3", "TX DMIC3"},
1324 {"TX DMIC MUX7", "DMIC4", "TX DMIC4"},
1325 {"TX DMIC MUX7", "DMIC5", "TX DMIC5"},
1326 {"TX DMIC MUX7", "DMIC6", "TX DMIC6"},
1327 {"TX DMIC MUX7", "DMIC7", "TX DMIC7"},
1328
1329 {"TX DEC7 MUX", "SWR_MIC", "TX SMIC MUX7"},
1330 {"TX SMIC MUX7", "ADC0", "TX SWR_ADC0"},
1331 {"TX SMIC MUX7", "ADC1", "TX SWR_ADC1"},
1332 {"TX SMIC MUX7", "ADC2", "TX SWR_ADC2"},
1333 {"TX SMIC MUX7", "ADC3", "TX SWR_ADC3"},
1334 {"TX SMIC MUX7", "SWR_DMIC0", "TX SWR_DMIC0"},
1335 {"TX SMIC MUX7", "SWR_DMIC1", "TX SWR_DMIC1"},
1336 {"TX SMIC MUX7", "SWR_DMIC2", "TX SWR_DMIC2"},
1337 {"TX SMIC MUX7", "SWR_DMIC3", "TX SWR_DMIC3"},
1338 {"TX SMIC MUX7", "SWR_DMIC4", "TX SWR_DMIC4"},
1339 {"TX SMIC MUX7", "SWR_DMIC5", "TX SWR_DMIC5"},
1340 {"TX SMIC MUX7", "SWR_DMIC6", "TX SWR_DMIC6"},
1341 {"TX SMIC MUX7", "SWR_DMIC7", "TX SWR_DMIC7"},
1342};
1343
1344static const struct snd_kcontrol_new tx_macro_snd_controls[] = {
1345 SOC_SINGLE_SX_TLV("TX_DEC0 Volume",
1346 BOLERO_CDC_TX0_TX_VOL_CTL,
1347 0, -84, 40, digital_gain),
1348 SOC_SINGLE_SX_TLV("TX_DEC1 Volume",
1349 BOLERO_CDC_TX1_TX_VOL_CTL,
1350 0, -84, 40, digital_gain),
1351 SOC_SINGLE_SX_TLV("TX_DEC2 Volume",
1352 BOLERO_CDC_TX2_TX_VOL_CTL,
1353 0, -84, 40, digital_gain),
1354 SOC_SINGLE_SX_TLV("TX_DEC3 Volume",
1355 BOLERO_CDC_TX3_TX_VOL_CTL,
1356 0, -84, 40, digital_gain),
1357 SOC_SINGLE_SX_TLV("TX_DEC4 Volume",
1358 BOLERO_CDC_TX4_TX_VOL_CTL,
1359 0, -84, 40, digital_gain),
1360 SOC_SINGLE_SX_TLV("TX_DEC5 Volume",
1361 BOLERO_CDC_TX5_TX_VOL_CTL,
1362 0, -84, 40, digital_gain),
1363 SOC_SINGLE_SX_TLV("TX_DEC6 Volume",
1364 BOLERO_CDC_TX6_TX_VOL_CTL,
1365 0, -84, 40, digital_gain),
1366 SOC_SINGLE_SX_TLV("TX_DEC7 Volume",
1367 BOLERO_CDC_TX7_TX_VOL_CTL,
1368 0, -84, 40, digital_gain),
1369};
1370
1371static int tx_macro_swrm_clock(void *handle, bool enable)
1372{
1373 struct tx_macro_priv *tx_priv = (struct tx_macro_priv *) handle;
1374 struct regmap *regmap = dev_get_regmap(tx_priv->dev->parent, NULL);
1375 int ret = 0;
1376
Tanya Dixit8530fb92018-09-14 16:01:25 +05301377 if (regmap == NULL) {
1378 dev_err(tx_priv->dev, "%s: regmap is NULL\n", __func__);
1379 return -EINVAL;
1380 }
1381
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301382 mutex_lock(&tx_priv->swr_clk_lock);
1383
1384 dev_dbg(tx_priv->dev, "%s: swrm clock %s\n",
1385 __func__, (enable ? "enable" : "disable"));
1386 if (enable) {
1387 if (tx_priv->swr_clk_users == 0) {
1388 ret = tx_macro_mclk_enable(tx_priv, 1);
1389 if (ret < 0) {
1390 dev_err(tx_priv->dev,
1391 "%s: request clock enable failed\n",
1392 __func__);
1393 goto exit;
1394 }
1395 regmap_update_bits(regmap,
1396 BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL,
1397 0x01, 0x01);
1398 regmap_update_bits(regmap,
1399 BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL,
1400 0x1C, 0x0C);
1401 msm_cdc_pinctrl_select_active_state(
1402 tx_priv->tx_swr_gpio_p);
1403 }
1404 tx_priv->swr_clk_users++;
1405 } else {
1406 if (tx_priv->swr_clk_users <= 0) {
1407 dev_err(tx_priv->dev,
1408 "tx swrm clock users already 0\n");
1409 tx_priv->swr_clk_users = 0;
1410 goto exit;
1411 }
1412 tx_priv->swr_clk_users--;
1413 if (tx_priv->swr_clk_users == 0) {
1414 regmap_update_bits(regmap,
1415 BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL,
1416 0x01, 0x00);
1417 msm_cdc_pinctrl_select_sleep_state(
1418 tx_priv->tx_swr_gpio_p);
1419 tx_macro_mclk_enable(tx_priv, 0);
1420 }
1421 }
1422 dev_dbg(tx_priv->dev, "%s: swrm clock users %d\n",
1423 __func__, tx_priv->swr_clk_users);
1424exit:
1425 mutex_unlock(&tx_priv->swr_clk_lock);
1426 return ret;
1427}
1428
1429static int tx_macro_validate_dmic_sample_rate(u32 dmic_sample_rate,
1430 struct tx_macro_priv *tx_priv)
1431{
1432 u32 div_factor = TX_MACRO_CLK_DIV_2;
1433 u32 mclk_rate = TX_MACRO_MCLK_FREQ;
1434
1435 if (dmic_sample_rate == TX_MACRO_DMIC_SAMPLE_RATE_UNDEFINED ||
1436 mclk_rate % dmic_sample_rate != 0)
1437 goto undefined_rate;
1438
1439 div_factor = mclk_rate / dmic_sample_rate;
1440
1441 switch (div_factor) {
1442 case 2:
1443 tx_priv->dmic_clk_div = TX_MACRO_CLK_DIV_2;
1444 break;
1445 case 3:
1446 tx_priv->dmic_clk_div = TX_MACRO_CLK_DIV_3;
1447 break;
1448 case 4:
1449 tx_priv->dmic_clk_div = TX_MACRO_CLK_DIV_4;
1450 break;
1451 case 6:
1452 tx_priv->dmic_clk_div = TX_MACRO_CLK_DIV_6;
1453 break;
1454 case 8:
1455 tx_priv->dmic_clk_div = TX_MACRO_CLK_DIV_8;
1456 break;
1457 case 16:
1458 tx_priv->dmic_clk_div = TX_MACRO_CLK_DIV_16;
1459 break;
1460 default:
1461 /* Any other DIV factor is invalid */
1462 goto undefined_rate;
1463 }
1464
1465 /* Valid dmic DIV factors */
1466 dev_dbg(tx_priv->dev, "%s: DMIC_DIV = %u, mclk_rate = %u\n",
1467 __func__, div_factor, mclk_rate);
1468
1469 return dmic_sample_rate;
1470
1471undefined_rate:
1472 dev_dbg(tx_priv->dev, "%s: Invalid rate %d, for mclk %d\n",
1473 __func__, dmic_sample_rate, mclk_rate);
1474 dmic_sample_rate = TX_MACRO_DMIC_SAMPLE_RATE_UNDEFINED;
1475
1476 return dmic_sample_rate;
1477}
1478
1479static int tx_macro_init(struct snd_soc_codec *codec)
1480{
1481 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
1482 int ret = 0, i = 0;
1483 struct device *tx_dev = NULL;
1484 struct tx_macro_priv *tx_priv = NULL;
1485
1486 tx_dev = bolero_get_device_ptr(codec->dev, TX_MACRO);
1487 if (!tx_dev) {
1488 dev_err(codec->dev,
1489 "%s: null device for macro!\n", __func__);
1490 return -EINVAL;
1491 }
1492 tx_priv = dev_get_drvdata(tx_dev);
1493 if (!tx_priv) {
1494 dev_err(codec->dev,
1495 "%s: priv is null for macro!\n", __func__);
1496 return -EINVAL;
1497 }
1498 ret = snd_soc_dapm_new_controls(dapm, tx_macro_dapm_widgets,
1499 ARRAY_SIZE(tx_macro_dapm_widgets));
1500 if (ret < 0) {
1501 dev_err(tx_dev, "%s: Failed to add controls\n", __func__);
1502 return ret;
1503 }
1504
1505 ret = snd_soc_dapm_add_routes(dapm, tx_audio_map,
1506 ARRAY_SIZE(tx_audio_map));
1507 if (ret < 0) {
1508 dev_err(tx_dev, "%s: Failed to add routes\n", __func__);
1509 return ret;
1510 }
1511
1512 ret = snd_soc_dapm_new_widgets(dapm->card);
1513 if (ret < 0) {
1514 dev_err(tx_dev, "%s: Failed to add widgets\n", __func__);
1515 return ret;
1516 }
1517
1518 ret = snd_soc_add_codec_controls(codec, tx_macro_snd_controls,
1519 ARRAY_SIZE(tx_macro_snd_controls));
1520 if (ret < 0) {
1521 dev_err(tx_dev, "%s: Failed to add snd_ctls\n", __func__);
1522 return ret;
1523 }
Laxminath Kasam638b5602018-09-24 13:19:52 +05301524
1525 snd_soc_dapm_ignore_suspend(dapm, "TX_AIF1 Capture");
1526 snd_soc_dapm_ignore_suspend(dapm, "TX_AIF2 Capture");
1527 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC0");
1528 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC1");
1529 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC2");
1530 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC3");
1531 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC0");
1532 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC1");
1533 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC2");
1534 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC3");
1535 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC4");
1536 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC5");
1537 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC6");
1538 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC7");
1539 snd_soc_dapm_sync(dapm);
1540
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301541 for (i = 0; i < NUM_DECIMATORS; i++) {
1542 tx_priv->tx_hpf_work[i].tx_priv = tx_priv;
1543 tx_priv->tx_hpf_work[i].decimator = i;
1544 INIT_DELAYED_WORK(&tx_priv->tx_hpf_work[i].dwork,
1545 tx_macro_tx_hpf_corner_freq_callback);
1546 }
1547
1548 for (i = 0; i < NUM_DECIMATORS; i++) {
1549 tx_priv->tx_mute_dwork[i].tx_priv = tx_priv;
1550 tx_priv->tx_mute_dwork[i].decimator = i;
1551 INIT_DELAYED_WORK(&tx_priv->tx_mute_dwork[i].dwork,
1552 tx_macro_mute_update_callback);
1553 }
1554 tx_priv->codec = codec;
1555
1556 return 0;
1557}
1558
1559static int tx_macro_deinit(struct snd_soc_codec *codec)
1560{
1561 struct device *tx_dev = NULL;
1562 struct tx_macro_priv *tx_priv = NULL;
1563
1564 if (!tx_macro_get_data(codec, &tx_dev, &tx_priv, __func__))
1565 return -EINVAL;
1566
1567 tx_priv->codec = NULL;
1568 return 0;
1569}
1570
1571static void tx_macro_add_child_devices(struct work_struct *work)
1572{
1573 struct tx_macro_priv *tx_priv = NULL;
1574 struct platform_device *pdev = NULL;
1575 struct device_node *node = NULL;
1576 struct tx_macro_swr_ctrl_data *swr_ctrl_data = NULL, *temp = NULL;
1577 int ret = 0;
1578 u16 count = 0, ctrl_num = 0;
1579 struct tx_macro_swr_ctrl_platform_data *platdata = NULL;
1580 char plat_dev_name[TX_MACRO_SWR_STRING_LEN] = "";
1581 bool tx_swr_master_node = false;
1582
1583 tx_priv = container_of(work, struct tx_macro_priv,
1584 tx_macro_add_child_devices_work);
1585 if (!tx_priv) {
1586 pr_err("%s: Memory for tx_priv does not exist\n",
1587 __func__);
1588 return;
1589 }
1590
1591 if (!tx_priv->dev) {
1592 pr_err("%s: tx dev does not exist\n", __func__);
1593 return;
1594 }
1595
1596 if (!tx_priv->dev->of_node) {
1597 dev_err(tx_priv->dev,
1598 "%s: DT node for tx_priv does not exist\n", __func__);
1599 return;
1600 }
1601
1602 platdata = &tx_priv->swr_plat_data;
1603 tx_priv->child_count = 0;
1604
1605 for_each_available_child_of_node(tx_priv->dev->of_node, node) {
1606 tx_swr_master_node = false;
1607 if (strnstr(node->name, "tx_swr_master",
1608 strlen("tx_swr_master")) != NULL)
1609 tx_swr_master_node = true;
1610
1611 if (tx_swr_master_node)
1612 strlcpy(plat_dev_name, "tx_swr_ctrl",
1613 (TX_MACRO_SWR_STRING_LEN - 1));
1614 else
1615 strlcpy(plat_dev_name, node->name,
1616 (TX_MACRO_SWR_STRING_LEN - 1));
1617
1618 pdev = platform_device_alloc(plat_dev_name, -1);
1619 if (!pdev) {
1620 dev_err(tx_priv->dev, "%s: pdev memory alloc failed\n",
1621 __func__);
1622 ret = -ENOMEM;
1623 goto err;
1624 }
1625 pdev->dev.parent = tx_priv->dev;
1626 pdev->dev.of_node = node;
1627
1628 if (tx_swr_master_node) {
1629 ret = platform_device_add_data(pdev, platdata,
1630 sizeof(*platdata));
1631 if (ret) {
1632 dev_err(&pdev->dev,
1633 "%s: cannot add plat data ctrl:%d\n",
1634 __func__, ctrl_num);
1635 goto fail_pdev_add;
1636 }
1637 }
1638
1639 ret = platform_device_add(pdev);
1640 if (ret) {
1641 dev_err(&pdev->dev,
1642 "%s: Cannot add platform device\n",
1643 __func__);
1644 goto fail_pdev_add;
1645 }
1646
1647 if (tx_swr_master_node) {
1648 temp = krealloc(swr_ctrl_data,
1649 (ctrl_num + 1) * sizeof(
1650 struct tx_macro_swr_ctrl_data),
1651 GFP_KERNEL);
1652 if (!temp) {
1653 ret = -ENOMEM;
1654 goto fail_pdev_add;
1655 }
1656 swr_ctrl_data = temp;
1657 swr_ctrl_data[ctrl_num].tx_swr_pdev = pdev;
1658 ctrl_num++;
1659 dev_dbg(&pdev->dev,
1660 "%s: Added soundwire ctrl device(s)\n",
1661 __func__);
1662 tx_priv->swr_ctrl_data = swr_ctrl_data;
1663 }
1664 if (tx_priv->child_count < TX_MACRO_CHILD_DEVICES_MAX)
1665 tx_priv->pdev_child_devices[
1666 tx_priv->child_count++] = pdev;
1667 else
1668 goto err;
1669 }
1670 return;
1671fail_pdev_add:
1672 for (count = 0; count < tx_priv->child_count; count++)
1673 platform_device_put(tx_priv->pdev_child_devices[count]);
1674err:
1675 return;
1676}
1677
1678static void tx_macro_init_ops(struct macro_ops *ops,
1679 char __iomem *tx_io_base)
1680{
1681 memset(ops, 0, sizeof(struct macro_ops));
1682 ops->init = tx_macro_init;
1683 ops->exit = tx_macro_deinit;
1684 ops->io_base = tx_io_base;
1685 ops->dai_ptr = tx_macro_dai;
1686 ops->num_dais = ARRAY_SIZE(tx_macro_dai);
1687 ops->mclk_fn = tx_macro_mclk_ctrl;
Laxminath Kasamfb0d6832018-09-22 01:49:52 +05301688 ops->event_handler = tx_macro_event_handler;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301689}
1690
1691static int tx_macro_probe(struct platform_device *pdev)
1692{
1693 struct macro_ops ops = {0};
1694 struct tx_macro_priv *tx_priv = NULL;
1695 u32 tx_base_addr = 0, sample_rate = 0;
1696 char __iomem *tx_io_base = NULL;
1697 struct clk *tx_core_clk = NULL, *tx_npl_clk = NULL;
1698 int ret = 0;
1699 const char *dmic_sample_rate = "qcom,tx-dmic-sample-rate";
1700
1701 tx_priv = devm_kzalloc(&pdev->dev, sizeof(struct tx_macro_priv),
1702 GFP_KERNEL);
1703 if (!tx_priv)
1704 return -ENOMEM;
1705 platform_set_drvdata(pdev, tx_priv);
1706
1707 tx_priv->dev = &pdev->dev;
1708 ret = of_property_read_u32(pdev->dev.of_node, "reg",
1709 &tx_base_addr);
1710 if (ret) {
1711 dev_err(&pdev->dev, "%s: could not find %s entry in dt\n",
1712 __func__, "reg");
1713 return ret;
1714 }
1715 dev_set_drvdata(&pdev->dev, tx_priv);
1716 tx_priv->tx_swr_gpio_p = of_parse_phandle(pdev->dev.of_node,
1717 "qcom,tx-swr-gpios", 0);
1718 if (!tx_priv->tx_swr_gpio_p) {
1719 dev_err(&pdev->dev, "%s: swr_gpios handle not provided!\n",
1720 __func__);
1721 return -EINVAL;
1722 }
1723 tx_io_base = devm_ioremap(&pdev->dev,
1724 tx_base_addr, TX_MACRO_MAX_OFFSET);
1725 if (!tx_io_base) {
1726 dev_err(&pdev->dev, "%s: ioremap failed\n", __func__);
1727 return -ENOMEM;
1728 }
1729 tx_priv->tx_io_base = tx_io_base;
1730 ret = of_property_read_u32(pdev->dev.of_node, dmic_sample_rate,
1731 &sample_rate);
1732 if (ret) {
1733 dev_err(&pdev->dev,
1734 "%s: could not find sample_rate entry in dt\n",
1735 __func__);
1736 tx_priv->dmic_clk_div = TX_MACRO_CLK_DIV_2;
1737 } else {
1738 if (tx_macro_validate_dmic_sample_rate(
1739 sample_rate, tx_priv) == TX_MACRO_DMIC_SAMPLE_RATE_UNDEFINED)
1740 return -EINVAL;
1741 }
1742
1743 INIT_WORK(&tx_priv->tx_macro_add_child_devices_work,
1744 tx_macro_add_child_devices);
1745 tx_priv->swr_plat_data.handle = (void *) tx_priv;
1746 tx_priv->swr_plat_data.read = NULL;
1747 tx_priv->swr_plat_data.write = NULL;
1748 tx_priv->swr_plat_data.bulk_write = NULL;
1749 tx_priv->swr_plat_data.clk = tx_macro_swrm_clock;
1750 tx_priv->swr_plat_data.handle_irq = NULL;
1751 /* Register MCLK for tx macro */
1752 tx_core_clk = devm_clk_get(&pdev->dev, "tx_core_clk");
1753 if (IS_ERR(tx_core_clk)) {
1754 ret = PTR_ERR(tx_core_clk);
1755 dev_err(&pdev->dev, "%s: clk get %s failed %d\n",
1756 __func__, "tx_core_clk", ret);
1757 return ret;
1758 }
1759 tx_priv->tx_core_clk = tx_core_clk;
1760 /* Register npl clk for soundwire */
1761 tx_npl_clk = devm_clk_get(&pdev->dev, "tx_npl_clk");
1762 if (IS_ERR(tx_npl_clk)) {
1763 ret = PTR_ERR(tx_npl_clk);
1764 dev_err(&pdev->dev, "%s: clk get %s failed %d\n",
1765 __func__, "tx_npl_clk", ret);
1766 return ret;
1767 }
1768 tx_priv->tx_npl_clk = tx_npl_clk;
1769
1770 mutex_init(&tx_priv->mclk_lock);
1771 mutex_init(&tx_priv->swr_clk_lock);
1772 tx_macro_init_ops(&ops, tx_io_base);
1773 ret = bolero_register_macro(&pdev->dev, TX_MACRO, &ops);
1774 if (ret) {
1775 dev_err(&pdev->dev,
1776 "%s: register macro failed\n", __func__);
1777 goto err_reg_macro;
1778 }
1779 schedule_work(&tx_priv->tx_macro_add_child_devices_work);
1780 return 0;
1781err_reg_macro:
1782 mutex_destroy(&tx_priv->mclk_lock);
1783 mutex_destroy(&tx_priv->swr_clk_lock);
1784 return ret;
1785}
1786
1787static int tx_macro_remove(struct platform_device *pdev)
1788{
1789 struct tx_macro_priv *tx_priv = NULL;
1790 u16 count = 0;
1791
1792 tx_priv = platform_get_drvdata(pdev);
1793
1794 if (!tx_priv)
1795 return -EINVAL;
1796
1797 kfree(tx_priv->swr_ctrl_data);
1798 for (count = 0; count < tx_priv->child_count &&
1799 count < TX_MACRO_CHILD_DEVICES_MAX; count++)
1800 platform_device_unregister(tx_priv->pdev_child_devices[count]);
1801
1802 mutex_destroy(&tx_priv->mclk_lock);
1803 mutex_destroy(&tx_priv->swr_clk_lock);
1804 bolero_unregister_macro(&pdev->dev, TX_MACRO);
1805 return 0;
1806}
1807
1808
1809static const struct of_device_id tx_macro_dt_match[] = {
1810 {.compatible = "qcom,tx-macro"},
1811 {}
1812};
1813
1814static struct platform_driver tx_macro_driver = {
1815 .driver = {
1816 .name = "tx_macro",
1817 .owner = THIS_MODULE,
1818 .of_match_table = tx_macro_dt_match,
1819 },
1820 .probe = tx_macro_probe,
1821 .remove = tx_macro_remove,
1822};
1823
1824module_platform_driver(tx_macro_driver);
1825
1826MODULE_DESCRIPTION("TX macro driver");
1827MODULE_LICENSE("GPL v2");