blob: 9dcb7f082df5e5340747f278a93ba87576387bd2 [file] [log] [blame]
Meng Wang43bbb872018-12-10 12:32:05 +08001// SPDX-License-Identifier: GPL-2.0-only
Vatsal Bucha39ead2c2018-12-14 12:22:46 +05302/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
Laxminath Kasam989fccf2018-06-15 16:53:31 +05303 */
4
5#include <linux/module.h>
6#include <linux/init.h>
7#include <linux/clk.h>
8#include <linux/io.h>
9#include <linux/platform_device.h>
10#include <linux/regmap.h>
Sudheer Papothi7601cc62019-03-30 03:00:52 +053011#include <linux/pm_runtime.h>
Laxminath Kasam989fccf2018-06-15 16:53:31 +053012#include <sound/soc.h>
13#include <sound/soc-dapm.h>
14#include <sound/tlv.h>
Sudheer Papothia3e969d2018-10-27 06:22:10 +053015#include <soc/swr-common.h>
Laxminath Kasamfb0d6832018-09-22 01:49:52 +053016#include <soc/swr-wcd.h>
Meng Wang11a25cf2018-10-31 14:11:26 +080017#include <asoc/msm-cdc-pinctrl.h>
Laxminath Kasam989fccf2018-06-15 16:53:31 +053018#include "bolero-cdc.h"
19#include "bolero-cdc-registers.h"
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -070020#include "bolero-clk-rsc.h"
Laxminath Kasam989fccf2018-06-15 16:53:31 +053021
Sudheer Papothi7601cc62019-03-30 03:00:52 +053022#define AUTO_SUSPEND_DELAY 50 /* delay in msec */
Laxminath Kasam989fccf2018-06-15 16:53:31 +053023#define TX_MACRO_MAX_OFFSET 0x1000
24
25#define NUM_DECIMATORS 8
26
27#define TX_MACRO_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
28 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
29 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
30#define TX_MACRO_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
31 SNDRV_PCM_FMTBIT_S24_LE |\
32 SNDRV_PCM_FMTBIT_S24_3LE)
33
34#define TX_HPF_CUT_OFF_FREQ_MASK 0x60
35#define CF_MIN_3DB_4HZ 0x0
36#define CF_MIN_3DB_75HZ 0x1
37#define CF_MIN_3DB_150HZ 0x2
38
39#define TX_MACRO_DMIC_SAMPLE_RATE_UNDEFINED 0
40#define TX_MACRO_MCLK_FREQ 9600000
41#define TX_MACRO_TX_PATH_OFFSET 0x80
Laxminath Kasam497a6512018-09-17 16:11:52 +053042#define TX_MACRO_SWR_MIC_MUX_SEL_MASK 0xF
43#define TX_MACRO_ADC_MUX_CFG_OFFSET 0x2
Karthikeyan Mani1dcd5a32019-08-22 14:37:13 -070044#define TX_MACRO_ADC_MODE_CFG0_SHIFT 1
Laxminath Kasam989fccf2018-06-15 16:53:31 +053045
46#define TX_MACRO_TX_UNMUTE_DELAY_MS 40
47
48static int tx_unmute_delay = TX_MACRO_TX_UNMUTE_DELAY_MS;
49module_param(tx_unmute_delay, int, 0664);
50MODULE_PARM_DESC(tx_unmute_delay, "delay to unmute the tx path");
51
52static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0);
53
54static int tx_macro_hw_params(struct snd_pcm_substream *substream,
55 struct snd_pcm_hw_params *params,
56 struct snd_soc_dai *dai);
57static int tx_macro_get_channel_map(struct snd_soc_dai *dai,
58 unsigned int *tx_num, unsigned int *tx_slot,
59 unsigned int *rx_num, unsigned int *rx_slot);
60
61#define TX_MACRO_SWR_STRING_LEN 80
62#define TX_MACRO_CHILD_DEVICES_MAX 3
63
64/* Hold instance to soundwire platform device */
65struct tx_macro_swr_ctrl_data {
66 struct platform_device *tx_swr_pdev;
67};
68
69struct tx_macro_swr_ctrl_platform_data {
70 void *handle; /* holds codec private data */
71 int (*read)(void *handle, int reg);
72 int (*write)(void *handle, int reg, int val);
73 int (*bulk_write)(void *handle, u32 *reg, u32 *val, size_t len);
74 int (*clk)(void *handle, bool enable);
Karthikeyan Mani8d40a062019-09-05 16:44:49 -070075 int (*core_vote)(void *handle, bool enable);
Laxminath Kasam989fccf2018-06-15 16:53:31 +053076 int (*handle_irq)(void *handle,
77 irqreturn_t (*swrm_irq_handler)(int irq,
78 void *data),
79 void *swrm_handle,
80 int action);
81};
82
83enum {
Laxminath Kasam59c7a1d2018-08-09 16:11:17 +053084 TX_MACRO_AIF_INVALID = 0,
85 TX_MACRO_AIF1_CAP,
Laxminath Kasam989fccf2018-06-15 16:53:31 +053086 TX_MACRO_AIF2_CAP,
Karthikeyan Manif3bb8182019-07-11 14:38:54 -070087 TX_MACRO_AIF3_CAP,
Laxminath Kasam989fccf2018-06-15 16:53:31 +053088 TX_MACRO_MAX_DAIS
89};
90
91enum {
92 TX_MACRO_DEC0,
93 TX_MACRO_DEC1,
94 TX_MACRO_DEC2,
95 TX_MACRO_DEC3,
96 TX_MACRO_DEC4,
97 TX_MACRO_DEC5,
98 TX_MACRO_DEC6,
99 TX_MACRO_DEC7,
100 TX_MACRO_DEC_MAX,
101};
102
103enum {
104 TX_MACRO_CLK_DIV_2,
105 TX_MACRO_CLK_DIV_3,
106 TX_MACRO_CLK_DIV_4,
107 TX_MACRO_CLK_DIV_6,
108 TX_MACRO_CLK_DIV_8,
109 TX_MACRO_CLK_DIV_16,
110};
111
Laxminath Kasam497a6512018-09-17 16:11:52 +0530112enum {
113 MSM_DMIC,
114 SWR_MIC,
115 ANC_FB_TUNE1
116};
117
Sudheer Papothia7397942019-03-19 03:14:23 +0530118enum {
119 TX_MCLK,
120 VA_MCLK,
121};
122
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530123struct tx_mute_work {
124 struct tx_macro_priv *tx_priv;
125 u32 decimator;
126 struct delayed_work dwork;
127};
128
129struct hpf_work {
130 struct tx_macro_priv *tx_priv;
131 u8 decimator;
132 u8 hpf_cut_off_freq;
133 struct delayed_work dwork;
134};
135
136struct tx_macro_priv {
137 struct device *dev;
138 bool dec_active[NUM_DECIMATORS];
139 int tx_mclk_users;
140 int swr_clk_users;
Ramprasad Katkam452772a2019-01-07 17:30:36 +0530141 bool dapm_mclk_enable;
Ramprasad Katkama4c747b2018-12-11 19:15:53 +0530142 bool reset_swr;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530143 struct mutex mclk_lock;
144 struct mutex swr_clk_lock;
Meng Wang15c825d2018-09-06 10:49:18 +0800145 struct snd_soc_component *component;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530146 struct device_node *tx_swr_gpio_p;
147 struct tx_macro_swr_ctrl_data *swr_ctrl_data;
148 struct tx_macro_swr_ctrl_platform_data swr_plat_data;
149 struct work_struct tx_macro_add_child_devices_work;
150 struct hpf_work tx_hpf_work[NUM_DECIMATORS];
151 struct tx_mute_work tx_mute_dwork[NUM_DECIMATORS];
152 s32 dmic_0_1_clk_cnt;
153 s32 dmic_2_3_clk_cnt;
154 s32 dmic_4_5_clk_cnt;
155 s32 dmic_6_7_clk_cnt;
156 u16 dmic_clk_div;
157 unsigned long active_ch_mask[TX_MACRO_MAX_DAIS];
158 unsigned long active_ch_cnt[TX_MACRO_MAX_DAIS];
159 char __iomem *tx_io_base;
160 struct platform_device *pdev_child_devices
161 [TX_MACRO_CHILD_DEVICES_MAX];
162 int child_count;
Sudheer Papothie456c2c2019-03-05 07:08:45 +0530163 int tx_swr_clk_cnt;
164 int va_swr_clk_cnt;
Sudheer Papothicf3b4062019-05-10 10:48:43 +0530165 int va_clk_status;
166 int tx_clk_status;
Karthikeyan Mani765eaab2019-07-18 16:27:01 -0700167 bool bcs_enable;
Karthikeyan Mani1dcd5a32019-08-22 14:37:13 -0700168 int dec_mode[NUM_DECIMATORS];
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530169};
170
Meng Wang15c825d2018-09-06 10:49:18 +0800171static bool tx_macro_get_data(struct snd_soc_component *component,
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530172 struct device **tx_dev,
173 struct tx_macro_priv **tx_priv,
174 const char *func_name)
175{
Meng Wang15c825d2018-09-06 10:49:18 +0800176 *tx_dev = bolero_get_device_ptr(component->dev, TX_MACRO);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530177 if (!(*tx_dev)) {
Meng Wang15c825d2018-09-06 10:49:18 +0800178 dev_err(component->dev,
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530179 "%s: null device for macro!\n", func_name);
180 return false;
181 }
182
183 *tx_priv = dev_get_drvdata((*tx_dev));
184 if (!(*tx_priv)) {
Meng Wang15c825d2018-09-06 10:49:18 +0800185 dev_err(component->dev,
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530186 "%s: priv is null for macro!\n", func_name);
187 return false;
188 }
189
Meng Wang15c825d2018-09-06 10:49:18 +0800190 if (!(*tx_priv)->component) {
191 dev_err(component->dev,
192 "%s: tx_priv->component not initialized!\n", func_name);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530193 return false;
194 }
195
196 return true;
197}
198
199static int tx_macro_mclk_enable(struct tx_macro_priv *tx_priv,
200 bool mclk_enable)
201{
202 struct regmap *regmap = dev_get_regmap(tx_priv->dev->parent, NULL);
203 int ret = 0;
204
Tanya Dixit8530fb92018-09-14 16:01:25 +0530205 if (regmap == NULL) {
206 dev_err(tx_priv->dev, "%s: regmap is NULL\n", __func__);
207 return -EINVAL;
208 }
209
Laxminath Kasamb7f823c2018-08-02 13:23:11 +0530210 dev_dbg(tx_priv->dev, "%s: mclk_enable = %u,clk_users= %d\n",
211 __func__, mclk_enable, tx_priv->tx_mclk_users);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530212
213 mutex_lock(&tx_priv->mclk_lock);
214 if (mclk_enable) {
215 if (tx_priv->tx_mclk_users == 0) {
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -0700216 ret = bolero_clk_rsc_request_clock(tx_priv->dev,
217 TX_CORE_CLK,
218 TX_CORE_CLK,
219 true);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530220 if (ret < 0) {
Ramprasad Katkam14efed62019-03-07 13:16:50 +0530221 dev_err_ratelimited(tx_priv->dev,
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530222 "%s: request clock enable failed\n",
223 __func__);
224 goto exit;
225 }
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -0700226 bolero_clk_rsc_fs_gen_request(tx_priv->dev,
227 true);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530228 regcache_mark_dirty(regmap);
229 regcache_sync_region(regmap,
230 TX_START_OFFSET,
231 TX_MAX_OFFSET);
232 /* 9.6MHz MCLK, set value 0x00 if other frequency */
233 regmap_update_bits(regmap,
234 BOLERO_CDC_TX_TOP_CSR_FREQ_MCLK, 0x01, 0x01);
235 regmap_update_bits(regmap,
236 BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL,
237 0x01, 0x01);
238 regmap_update_bits(regmap,
239 BOLERO_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL,
240 0x01, 0x01);
241 }
242 tx_priv->tx_mclk_users++;
243 } else {
244 if (tx_priv->tx_mclk_users <= 0) {
245 dev_err(tx_priv->dev, "%s: clock already disabled\n",
246 __func__);
247 tx_priv->tx_mclk_users = 0;
248 goto exit;
249 }
250 tx_priv->tx_mclk_users--;
251 if (tx_priv->tx_mclk_users == 0) {
252 regmap_update_bits(regmap,
253 BOLERO_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL,
254 0x01, 0x00);
255 regmap_update_bits(regmap,
256 BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL,
257 0x01, 0x00);
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -0700258 bolero_clk_rsc_fs_gen_request(tx_priv->dev,
259 false);
260
261 bolero_clk_rsc_request_clock(tx_priv->dev,
262 TX_CORE_CLK,
263 TX_CORE_CLK,
264 false);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530265 }
266 }
267exit:
268 mutex_unlock(&tx_priv->mclk_lock);
269 return ret;
270}
271
Sudheer Papothie456c2c2019-03-05 07:08:45 +0530272static int tx_macro_va_swr_clk_event(struct snd_soc_dapm_widget *w,
273 struct snd_kcontrol *kcontrol, int event)
274{
275 struct device *tx_dev = NULL;
276 struct tx_macro_priv *tx_priv = NULL;
277 struct snd_soc_component *component =
278 snd_soc_dapm_to_component(w->dapm);
279
280 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
281 return -EINVAL;
282
283 if (SND_SOC_DAPM_EVENT_ON(event))
284 ++tx_priv->va_swr_clk_cnt;
285 if (SND_SOC_DAPM_EVENT_OFF(event))
286 --tx_priv->va_swr_clk_cnt;
287
288 return 0;
289}
290
291static int tx_macro_tx_swr_clk_event(struct snd_soc_dapm_widget *w,
292 struct snd_kcontrol *kcontrol, int event)
293{
294 struct device *tx_dev = NULL;
295 struct tx_macro_priv *tx_priv = NULL;
296 struct snd_soc_component *component =
297 snd_soc_dapm_to_component(w->dapm);
298
299 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
300 return -EINVAL;
301
302 if (SND_SOC_DAPM_EVENT_ON(event))
303 ++tx_priv->tx_swr_clk_cnt;
304 if (SND_SOC_DAPM_EVENT_OFF(event))
305 --tx_priv->tx_swr_clk_cnt;
306
307 return 0;
308}
309
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530310static int tx_macro_mclk_event(struct snd_soc_dapm_widget *w,
311 struct snd_kcontrol *kcontrol, int event)
312{
Meng Wang15c825d2018-09-06 10:49:18 +0800313 struct snd_soc_component *component =
314 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530315 int ret = 0;
316 struct device *tx_dev = NULL;
317 struct tx_macro_priv *tx_priv = NULL;
318
Meng Wang15c825d2018-09-06 10:49:18 +0800319 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530320 return -EINVAL;
321
322 dev_dbg(tx_dev, "%s: event = %d\n", __func__, event);
323 switch (event) {
324 case SND_SOC_DAPM_PRE_PMU:
325 ret = tx_macro_mclk_enable(tx_priv, 1);
Ramprasad Katkam452772a2019-01-07 17:30:36 +0530326 if (ret)
327 tx_priv->dapm_mclk_enable = false;
328 else
329 tx_priv->dapm_mclk_enable = true;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530330 break;
331 case SND_SOC_DAPM_POST_PMD:
Ramprasad Katkam452772a2019-01-07 17:30:36 +0530332 if (tx_priv->dapm_mclk_enable)
333 ret = tx_macro_mclk_enable(tx_priv, 0);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530334 break;
335 default:
336 dev_err(tx_priv->dev,
337 "%s: invalid DAPM event %d\n", __func__, event);
338 ret = -EINVAL;
339 }
340 return ret;
341}
342
Meng Wang15c825d2018-09-06 10:49:18 +0800343static int tx_macro_event_handler(struct snd_soc_component *component,
344 u16 event, u32 data)
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530345{
346 struct device *tx_dev = NULL;
347 struct tx_macro_priv *tx_priv = NULL;
Aditya Bavanari50ef13e2019-08-09 15:14:43 +0530348 int ret = 0;
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530349
Meng Wang15c825d2018-09-06 10:49:18 +0800350 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530351 return -EINVAL;
352
353 switch (event) {
354 case BOLERO_MACRO_EVT_SSR_DOWN:
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -0700355 if (tx_priv->swr_ctrl_data) {
356 swrm_wcd_notify(
357 tx_priv->swr_ctrl_data[0].tx_swr_pdev,
358 SWR_DEVICE_DOWN, NULL);
359 swrm_wcd_notify(
360 tx_priv->swr_ctrl_data[0].tx_swr_pdev,
361 SWR_DEVICE_SSR_DOWN, NULL);
362 }
Aditya Bavanari50ef13e2019-08-09 15:14:43 +0530363 if ((!pm_runtime_enabled(tx_dev) ||
364 !pm_runtime_suspended(tx_dev))) {
365 ret = bolero_runtime_suspend(tx_dev);
366 if (!ret) {
367 pm_runtime_disable(tx_dev);
368 pm_runtime_set_suspended(tx_dev);
369 pm_runtime_enable(tx_dev);
370 }
371 }
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530372 break;
373 case BOLERO_MACRO_EVT_SSR_UP:
Ramprasad Katkama4c747b2018-12-11 19:15:53 +0530374 /* reset swr after ssr/pdr */
375 tx_priv->reset_swr = true;
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -0700376 if (tx_priv->swr_ctrl_data)
377 swrm_wcd_notify(
378 tx_priv->swr_ctrl_data[0].tx_swr_pdev,
379 SWR_DEVICE_SSR_UP, NULL);
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530380 break;
Meng Wang8ef0cc22019-05-08 15:12:56 +0800381 case BOLERO_MACRO_EVT_CLK_RESET:
382 bolero_rsc_clk_reset(tx_dev, TX_CORE_CLK);
383 break;
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530384 }
385 return 0;
386}
387
Meng Wang15c825d2018-09-06 10:49:18 +0800388static int tx_macro_reg_wake_irq(struct snd_soc_component *component,
Aditya Bavanaric4e96122018-11-14 14:46:38 +0530389 u32 data)
390{
391 struct device *tx_dev = NULL;
392 struct tx_macro_priv *tx_priv = NULL;
393 u32 ipc_wakeup = data;
394 int ret = 0;
395
Meng Wang15c825d2018-09-06 10:49:18 +0800396 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
Aditya Bavanaric4e96122018-11-14 14:46:38 +0530397 return -EINVAL;
398
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -0700399 if (tx_priv->swr_ctrl_data)
400 ret = swrm_wcd_notify(
401 tx_priv->swr_ctrl_data[0].tx_swr_pdev,
402 SWR_REGISTER_WAKE_IRQ, &ipc_wakeup);
Aditya Bavanaric4e96122018-11-14 14:46:38 +0530403
404 return ret;
405}
406
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530407static void tx_macro_tx_hpf_corner_freq_callback(struct work_struct *work)
408{
409 struct delayed_work *hpf_delayed_work = NULL;
410 struct hpf_work *hpf_work = NULL;
411 struct tx_macro_priv *tx_priv = NULL;
Meng Wang15c825d2018-09-06 10:49:18 +0800412 struct snd_soc_component *component = NULL;
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530413 u16 dec_cfg_reg = 0, hpf_gate_reg = 0;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530414 u8 hpf_cut_off_freq = 0;
Laxminath Kasam497a6512018-09-17 16:11:52 +0530415 u16 adc_mux_reg = 0, adc_n = 0, adc_reg = 0;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530416
417 hpf_delayed_work = to_delayed_work(work);
418 hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork);
419 tx_priv = hpf_work->tx_priv;
Meng Wang15c825d2018-09-06 10:49:18 +0800420 component = tx_priv->component;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530421 hpf_cut_off_freq = hpf_work->hpf_cut_off_freq;
422
423 dec_cfg_reg = BOLERO_CDC_TX0_TX_PATH_CFG0 +
424 TX_MACRO_TX_PATH_OFFSET * hpf_work->decimator;
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530425 hpf_gate_reg = BOLERO_CDC_TX0_TX_PATH_SEC2 +
426 TX_MACRO_TX_PATH_OFFSET * hpf_work->decimator;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530427
Meng Wang15c825d2018-09-06 10:49:18 +0800428 dev_dbg(component->dev, "%s: decimator %u hpf_cut_of_freq 0x%x\n",
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530429 __func__, hpf_work->decimator, hpf_cut_off_freq);
430
Laxminath Kasam497a6512018-09-17 16:11:52 +0530431 adc_mux_reg = BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG1 +
432 TX_MACRO_ADC_MUX_CFG_OFFSET * hpf_work->decimator;
Meng Wang15c825d2018-09-06 10:49:18 +0800433 if (snd_soc_component_read32(component, adc_mux_reg) & SWR_MIC) {
Laxminath Kasam497a6512018-09-17 16:11:52 +0530434 adc_reg = BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0 +
435 TX_MACRO_ADC_MUX_CFG_OFFSET * hpf_work->decimator;
Meng Wang15c825d2018-09-06 10:49:18 +0800436 adc_n = snd_soc_component_read32(component, adc_reg) &
Laxminath Kasam497a6512018-09-17 16:11:52 +0530437 TX_MACRO_SWR_MIC_MUX_SEL_MASK;
438 if (adc_n >= BOLERO_ADC_MAX)
439 goto tx_hpf_set;
440 /* analog mic clear TX hold */
Meng Wang15c825d2018-09-06 10:49:18 +0800441 bolero_clear_amic_tx_hold(component->dev, adc_n);
Laxminath Kasam497a6512018-09-17 16:11:52 +0530442 }
443tx_hpf_set:
Meng Wang15c825d2018-09-06 10:49:18 +0800444 snd_soc_component_update_bits(component,
445 dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK,
446 hpf_cut_off_freq << 5);
447 snd_soc_component_update_bits(component, hpf_gate_reg, 0x03, 0x02);
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530448 /* Minimum 1 clk cycle delay is required as per HW spec */
449 usleep_range(1000, 1010);
Meng Wang15c825d2018-09-06 10:49:18 +0800450 snd_soc_component_update_bits(component, hpf_gate_reg, 0x03, 0x01);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530451}
452
453static void tx_macro_mute_update_callback(struct work_struct *work)
454{
455 struct tx_mute_work *tx_mute_dwork = NULL;
Meng Wang15c825d2018-09-06 10:49:18 +0800456 struct snd_soc_component *component = NULL;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530457 struct tx_macro_priv *tx_priv = NULL;
458 struct delayed_work *delayed_work = NULL;
Xiaojun Sangd155fdc2018-10-11 15:11:59 +0800459 u16 tx_vol_ctl_reg = 0;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530460 u8 decimator = 0;
461
462 delayed_work = to_delayed_work(work);
463 tx_mute_dwork = container_of(delayed_work, struct tx_mute_work, dwork);
464 tx_priv = tx_mute_dwork->tx_priv;
Meng Wang15c825d2018-09-06 10:49:18 +0800465 component = tx_priv->component;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530466 decimator = tx_mute_dwork->decimator;
467
468 tx_vol_ctl_reg =
469 BOLERO_CDC_TX0_TX_PATH_CTL +
470 TX_MACRO_TX_PATH_OFFSET * decimator;
Meng Wang15c825d2018-09-06 10:49:18 +0800471 snd_soc_component_update_bits(component, tx_vol_ctl_reg, 0x10, 0x00);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530472 dev_dbg(tx_priv->dev, "%s: decimator %u unmute\n",
473 __func__, decimator);
474}
475
476static int tx_macro_put_dec_enum(struct snd_kcontrol *kcontrol,
477 struct snd_ctl_elem_value *ucontrol)
478{
479 struct snd_soc_dapm_widget *widget =
480 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +0800481 struct snd_soc_component *component =
482 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530483 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
484 unsigned int val = 0;
485 u16 mic_sel_reg = 0;
Laxminath Kasam549d11d2019-07-18 13:44:17 +0530486 u16 dmic_clk_reg = 0;
487 struct device *tx_dev = NULL;
488 struct tx_macro_priv *tx_priv = NULL;
489
490 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
491 return -EINVAL;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530492
493 val = ucontrol->value.enumerated.item[0];
494 if (val > e->items - 1)
495 return -EINVAL;
496
Meng Wang15c825d2018-09-06 10:49:18 +0800497 dev_dbg(component->dev, "%s: wname: %s, val: 0x%x\n", __func__,
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530498 widget->name, val);
499
500 switch (e->reg) {
501 case BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0:
502 mic_sel_reg = BOLERO_CDC_TX0_TX_PATH_CFG0;
503 break;
504 case BOLERO_CDC_TX_INP_MUX_ADC_MUX1_CFG0:
505 mic_sel_reg = BOLERO_CDC_TX1_TX_PATH_CFG0;
506 break;
507 case BOLERO_CDC_TX_INP_MUX_ADC_MUX2_CFG0:
508 mic_sel_reg = BOLERO_CDC_TX2_TX_PATH_CFG0;
509 break;
510 case BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG0:
511 mic_sel_reg = BOLERO_CDC_TX3_TX_PATH_CFG0;
512 break;
513 case BOLERO_CDC_TX_INP_MUX_ADC_MUX4_CFG0:
514 mic_sel_reg = BOLERO_CDC_TX4_TX_PATH_CFG0;
515 break;
516 case BOLERO_CDC_TX_INP_MUX_ADC_MUX5_CFG0:
517 mic_sel_reg = BOLERO_CDC_TX5_TX_PATH_CFG0;
518 break;
519 case BOLERO_CDC_TX_INP_MUX_ADC_MUX6_CFG0:
520 mic_sel_reg = BOLERO_CDC_TX6_TX_PATH_CFG0;
521 break;
522 case BOLERO_CDC_TX_INP_MUX_ADC_MUX7_CFG0:
523 mic_sel_reg = BOLERO_CDC_TX7_TX_PATH_CFG0;
524 break;
525 default:
Meng Wang15c825d2018-09-06 10:49:18 +0800526 dev_err(component->dev, "%s: e->reg: 0x%x not expected\n",
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530527 __func__, e->reg);
528 return -EINVAL;
529 }
Laxminath Kasam497a6512018-09-17 16:11:52 +0530530 if (strnstr(widget->name, "SMIC", strlen(widget->name))) {
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530531 if (val != 0) {
Laxminath Kasam549d11d2019-07-18 13:44:17 +0530532 if (val < 5) {
Meng Wang15c825d2018-09-06 10:49:18 +0800533 snd_soc_component_update_bits(component,
534 mic_sel_reg,
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530535 1 << 7, 0x0 << 7);
Laxminath Kasam549d11d2019-07-18 13:44:17 +0530536 } else {
Meng Wang15c825d2018-09-06 10:49:18 +0800537 snd_soc_component_update_bits(component,
538 mic_sel_reg,
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530539 1 << 7, 0x1 << 7);
Laxminath Kasam549d11d2019-07-18 13:44:17 +0530540 snd_soc_component_update_bits(component,
541 BOLERO_CDC_VA_TOP_CSR_DMIC_CFG,
542 0x80, 0x00);
543 dmic_clk_reg =
544 BOLERO_CDC_TX_TOP_CSR_SWR_DMIC0_CTL +
545 ((val - 5)/2) * 4;
546 snd_soc_component_update_bits(component,
547 dmic_clk_reg,
548 0x0E, tx_priv->dmic_clk_div << 0x1);
549 }
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530550 }
551 } else {
552 /* DMIC selected */
553 if (val != 0)
Meng Wang15c825d2018-09-06 10:49:18 +0800554 snd_soc_component_update_bits(component, mic_sel_reg,
555 1 << 7, 1 << 7);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530556 }
557
558 return snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
559}
560
561static int tx_macro_tx_mixer_get(struct snd_kcontrol *kcontrol,
562 struct snd_ctl_elem_value *ucontrol)
563{
564 struct snd_soc_dapm_widget *widget =
565 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +0800566 struct snd_soc_component *component =
567 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530568 struct soc_multi_mixer_control *mixer =
569 ((struct soc_multi_mixer_control *)kcontrol->private_value);
570 u32 dai_id = widget->shift;
571 u32 dec_id = mixer->shift;
572 struct device *tx_dev = NULL;
573 struct tx_macro_priv *tx_priv = NULL;
574
Meng Wang15c825d2018-09-06 10:49:18 +0800575 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530576 return -EINVAL;
577
578 if (test_bit(dec_id, &tx_priv->active_ch_mask[dai_id]))
579 ucontrol->value.integer.value[0] = 1;
580 else
581 ucontrol->value.integer.value[0] = 0;
582 return 0;
583}
584
585static int tx_macro_tx_mixer_put(struct snd_kcontrol *kcontrol,
586 struct snd_ctl_elem_value *ucontrol)
587{
588 struct snd_soc_dapm_widget *widget =
589 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +0800590 struct snd_soc_component *component =
591 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530592 struct snd_soc_dapm_update *update = NULL;
593 struct soc_multi_mixer_control *mixer =
594 ((struct soc_multi_mixer_control *)kcontrol->private_value);
595 u32 dai_id = widget->shift;
596 u32 dec_id = mixer->shift;
597 u32 enable = ucontrol->value.integer.value[0];
598 struct device *tx_dev = NULL;
599 struct tx_macro_priv *tx_priv = NULL;
600
Meng Wang15c825d2018-09-06 10:49:18 +0800601 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530602 return -EINVAL;
603
604 if (enable) {
605 set_bit(dec_id, &tx_priv->active_ch_mask[dai_id]);
606 tx_priv->active_ch_cnt[dai_id]++;
607 } else {
608 tx_priv->active_ch_cnt[dai_id]--;
609 clear_bit(dec_id, &tx_priv->active_ch_mask[dai_id]);
610 }
611 snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, update);
612
613 return 0;
614}
Karthikeyan Mani1dcd5a32019-08-22 14:37:13 -0700615
616static inline int tx_macro_path_get(const char *wname,
617 unsigned int *path_num)
618{
619 int ret = 0;
620 char *widget_name = NULL;
621 char *w_name = NULL;
622 char *path_num_char = NULL;
623 char *path_name = NULL;
624
625 widget_name = kstrndup(wname, 10, GFP_KERNEL);
626 if (!widget_name)
627 return -EINVAL;
628
629 w_name = widget_name;
630
631 path_name = strsep(&widget_name, " ");
632 if (!path_name) {
633 pr_err("%s: Invalid widget name = %s\n",
634 __func__, widget_name);
635 ret = -EINVAL;
636 goto err;
637 }
638 path_num_char = strpbrk(path_name, "01234567");
639 if (!path_num_char) {
640 pr_err("%s: tx path index not found\n",
641 __func__);
642 ret = -EINVAL;
643 goto err;
644 }
645 ret = kstrtouint(path_num_char, 10, path_num);
646 if (ret < 0)
647 pr_err("%s: Invalid tx path = %s\n",
648 __func__, w_name);
649
650err:
651 kfree(w_name);
652 return ret;
653}
654
655static int tx_macro_dec_mode_get(struct snd_kcontrol *kcontrol,
656 struct snd_ctl_elem_value *ucontrol)
657{
658 struct snd_soc_component *component =
659 snd_soc_kcontrol_component(kcontrol);
660 struct tx_macro_priv *tx_priv = NULL;
661 struct device *tx_dev = NULL;
662 int ret = 0;
663 int path = 0;
664
665 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
666 return -EINVAL;
667
668 ret = tx_macro_path_get(kcontrol->id.name, &path);
669 if (ret)
670 return ret;
671
672 ucontrol->value.integer.value[0] = tx_priv->dec_mode[path];
673
674 return 0;
675}
676
677static int tx_macro_dec_mode_put(struct snd_kcontrol *kcontrol,
678 struct snd_ctl_elem_value *ucontrol)
679{
680 struct snd_soc_component *component =
681 snd_soc_kcontrol_component(kcontrol);
682 struct tx_macro_priv *tx_priv = NULL;
683 struct device *tx_dev = NULL;
684 int value = ucontrol->value.integer.value[0];
685 int ret = 0;
686 int path = 0;
687
688 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
689 return -EINVAL;
690
691 ret = tx_macro_path_get(kcontrol->id.name, &path);
692 if (ret)
693 return ret;
694
695 tx_priv->dec_mode[path] = value;
696
697 return 0;
698}
699
Karthikeyan Mani765eaab2019-07-18 16:27:01 -0700700static int tx_macro_get_bcs(struct snd_kcontrol *kcontrol,
701 struct snd_ctl_elem_value *ucontrol)
702{
703 struct snd_soc_component *component =
704 snd_soc_kcontrol_component(kcontrol);
705 struct tx_macro_priv *tx_priv = NULL;
706 struct device *tx_dev = NULL;
707
708 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
709 return -EINVAL;
710
711 ucontrol->value.integer.value[0] = tx_priv->bcs_enable;
712
713 return 0;
714}
715
716static int tx_macro_set_bcs(struct snd_kcontrol *kcontrol,
717 struct snd_ctl_elem_value *ucontrol)
718{
719 struct snd_soc_component *component =
720 snd_soc_kcontrol_component(kcontrol);
721 struct tx_macro_priv *tx_priv = NULL;
722 struct device *tx_dev = NULL;
723 int value = ucontrol->value.integer.value[0];
724
725 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
726 return -EINVAL;
727
728 tx_priv->bcs_enable = value;
729
730 return 0;
731}
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530732
733static int tx_macro_enable_dmic(struct snd_soc_dapm_widget *w,
734 struct snd_kcontrol *kcontrol, int event)
735{
Meng Wang15c825d2018-09-06 10:49:18 +0800736 struct snd_soc_component *component =
737 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530738 u8 dmic_clk_en = 0x01;
739 u16 dmic_clk_reg = 0;
740 s32 *dmic_clk_cnt = NULL;
741 unsigned int dmic = 0;
742 int ret = 0;
743 char *wname = NULL;
744 struct device *tx_dev = NULL;
745 struct tx_macro_priv *tx_priv = NULL;
746
Meng Wang15c825d2018-09-06 10:49:18 +0800747 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530748 return -EINVAL;
749
750 wname = strpbrk(w->name, "01234567");
751 if (!wname) {
Meng Wang15c825d2018-09-06 10:49:18 +0800752 dev_err(component->dev, "%s: widget not found\n", __func__);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530753 return -EINVAL;
754 }
755
756 ret = kstrtouint(wname, 10, &dmic);
757 if (ret < 0) {
Meng Wang15c825d2018-09-06 10:49:18 +0800758 dev_err(component->dev, "%s: Invalid DMIC line on the codec\n",
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530759 __func__);
760 return -EINVAL;
761 }
762
763 switch (dmic) {
764 case 0:
765 case 1:
766 dmic_clk_cnt = &(tx_priv->dmic_0_1_clk_cnt);
767 dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC0_CTL;
768 break;
769 case 2:
770 case 3:
771 dmic_clk_cnt = &(tx_priv->dmic_2_3_clk_cnt);
772 dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC1_CTL;
773 break;
774 case 4:
775 case 5:
776 dmic_clk_cnt = &(tx_priv->dmic_4_5_clk_cnt);
777 dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC2_CTL;
778 break;
779 case 6:
780 case 7:
781 dmic_clk_cnt = &(tx_priv->dmic_6_7_clk_cnt);
782 dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC3_CTL;
783 break;
784 default:
Meng Wang15c825d2018-09-06 10:49:18 +0800785 dev_err(component->dev, "%s: Invalid DMIC Selection\n",
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530786 __func__);
787 return -EINVAL;
788 }
Meng Wang15c825d2018-09-06 10:49:18 +0800789 dev_dbg(component->dev, "%s: event %d DMIC%d dmic_clk_cnt %d\n",
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530790 __func__, event, dmic, *dmic_clk_cnt);
791
792 switch (event) {
793 case SND_SOC_DAPM_PRE_PMU:
794 (*dmic_clk_cnt)++;
795 if (*dmic_clk_cnt == 1) {
Meng Wang15c825d2018-09-06 10:49:18 +0800796 snd_soc_component_update_bits(component,
797 BOLERO_CDC_VA_TOP_CSR_DMIC_CFG,
Ramprasad Katkam9c2394a2018-08-23 13:13:48 +0530798 0x80, 0x00);
799
Meng Wang15c825d2018-09-06 10:49:18 +0800800 snd_soc_component_update_bits(component, dmic_clk_reg,
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530801 0x0E, tx_priv->dmic_clk_div << 0x1);
Meng Wang15c825d2018-09-06 10:49:18 +0800802 snd_soc_component_update_bits(component, dmic_clk_reg,
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530803 dmic_clk_en, dmic_clk_en);
804 }
805 break;
806 case SND_SOC_DAPM_POST_PMD:
807 (*dmic_clk_cnt)--;
808 if (*dmic_clk_cnt == 0)
Meng Wang15c825d2018-09-06 10:49:18 +0800809 snd_soc_component_update_bits(component, dmic_clk_reg,
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530810 dmic_clk_en, 0);
811 break;
812 }
813
814 return 0;
815}
816
817static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w,
818 struct snd_kcontrol *kcontrol, int event)
819{
Meng Wang15c825d2018-09-06 10:49:18 +0800820 struct snd_soc_component *component =
821 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530822 unsigned int decimator = 0;
823 u16 tx_vol_ctl_reg = 0;
824 u16 dec_cfg_reg = 0;
825 u16 hpf_gate_reg = 0;
826 u16 tx_gain_ctl_reg = 0;
827 u8 hpf_cut_off_freq = 0;
828 struct device *tx_dev = NULL;
829 struct tx_macro_priv *tx_priv = NULL;
830
Meng Wang15c825d2018-09-06 10:49:18 +0800831 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530832 return -EINVAL;
833
834 decimator = w->shift;
835
Meng Wang15c825d2018-09-06 10:49:18 +0800836 dev_dbg(component->dev, "%s(): widget = %s decimator = %u\n", __func__,
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530837 w->name, decimator);
838
839 tx_vol_ctl_reg = BOLERO_CDC_TX0_TX_PATH_CTL +
840 TX_MACRO_TX_PATH_OFFSET * decimator;
841 hpf_gate_reg = BOLERO_CDC_TX0_TX_PATH_SEC2 +
842 TX_MACRO_TX_PATH_OFFSET * decimator;
843 dec_cfg_reg = BOLERO_CDC_TX0_TX_PATH_CFG0 +
844 TX_MACRO_TX_PATH_OFFSET * decimator;
845 tx_gain_ctl_reg = BOLERO_CDC_TX0_TX_VOL_CTL +
846 TX_MACRO_TX_PATH_OFFSET * decimator;
847
848 switch (event) {
849 case SND_SOC_DAPM_PRE_PMU:
Karthikeyan Mani1dcd5a32019-08-22 14:37:13 -0700850 snd_soc_component_update_bits(component,
851 dec_cfg_reg, 0x06, tx_priv->dec_mode[decimator] <<
852 TX_MACRO_ADC_MODE_CFG0_SHIFT);
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530853 /* Enable TX PGA Mute */
Meng Wang15c825d2018-09-06 10:49:18 +0800854 snd_soc_component_update_bits(component,
855 tx_vol_ctl_reg, 0x10, 0x10);
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530856 break;
857 case SND_SOC_DAPM_POST_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +0800858 snd_soc_component_update_bits(component,
859 tx_vol_ctl_reg, 0x20, 0x20);
860 snd_soc_component_update_bits(component,
861 hpf_gate_reg, 0x01, 0x00);
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530862
Meng Wang15c825d2018-09-06 10:49:18 +0800863 hpf_cut_off_freq = (
864 snd_soc_component_read32(component, dec_cfg_reg) &
865 TX_HPF_CUT_OFF_FREQ_MASK) >> 5;
866
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530867 tx_priv->tx_hpf_work[decimator].hpf_cut_off_freq =
Meng Wang15c825d2018-09-06 10:49:18 +0800868 hpf_cut_off_freq;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530869
870 if (hpf_cut_off_freq != CF_MIN_3DB_150HZ)
Meng Wang15c825d2018-09-06 10:49:18 +0800871 snd_soc_component_update_bits(component, dec_cfg_reg,
872 TX_HPF_CUT_OFF_FREQ_MASK,
873 CF_MIN_3DB_150HZ << 5);
874
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530875 /* schedule work queue to Remove Mute */
876 schedule_delayed_work(&tx_priv->tx_mute_dwork[decimator].dwork,
877 msecs_to_jiffies(tx_unmute_delay));
878 if (tx_priv->tx_hpf_work[decimator].hpf_cut_off_freq !=
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530879 CF_MIN_3DB_150HZ) {
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530880 schedule_delayed_work(
881 &tx_priv->tx_hpf_work[decimator].dwork,
Karthikeyan Mani6bd895e2019-07-26 15:34:50 -0700882 msecs_to_jiffies(300));
Meng Wang15c825d2018-09-06 10:49:18 +0800883 snd_soc_component_update_bits(component,
884 hpf_gate_reg, 0x02, 0x02);
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530885 /*
886 * Minimum 1 clk cycle delay is required as per HW spec
887 */
888 usleep_range(1000, 1010);
Meng Wang15c825d2018-09-06 10:49:18 +0800889 snd_soc_component_update_bits(component,
890 hpf_gate_reg, 0x02, 0x00);
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530891 }
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530892 /* apply gain after decimator is enabled */
Meng Wang15c825d2018-09-06 10:49:18 +0800893 snd_soc_component_write(component, tx_gain_ctl_reg,
894 snd_soc_component_read32(component,
895 tx_gain_ctl_reg));
Karthikeyan Mani765eaab2019-07-18 16:27:01 -0700896 if (tx_priv->bcs_enable) {
897 snd_soc_component_update_bits(component, dec_cfg_reg,
898 0x01, 0x01);
899 snd_soc_component_update_bits(component,
900 BOLERO_CDC_TX0_TX_PATH_SEC7, 0x40, 0x40);
901 }
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530902 break;
903 case SND_SOC_DAPM_PRE_PMD:
904 hpf_cut_off_freq =
905 tx_priv->tx_hpf_work[decimator].hpf_cut_off_freq;
Meng Wang15c825d2018-09-06 10:49:18 +0800906 snd_soc_component_update_bits(component,
907 tx_vol_ctl_reg, 0x10, 0x10);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530908 if (cancel_delayed_work_sync(
909 &tx_priv->tx_hpf_work[decimator].dwork)) {
910 if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) {
Meng Wang15c825d2018-09-06 10:49:18 +0800911 snd_soc_component_update_bits(
912 component, dec_cfg_reg,
913 TX_HPF_CUT_OFF_FREQ_MASK,
914 hpf_cut_off_freq << 5);
915 snd_soc_component_update_bits(component,
916 hpf_gate_reg,
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530917 0x02, 0x02);
918 /*
919 * Minimum 1 clk cycle delay is required
920 * as per HW spec
921 */
922 usleep_range(1000, 1010);
Meng Wang15c825d2018-09-06 10:49:18 +0800923 snd_soc_component_update_bits(component,
924 hpf_gate_reg,
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530925 0x02, 0x00);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530926 }
927 }
928 cancel_delayed_work_sync(
929 &tx_priv->tx_mute_dwork[decimator].dwork);
930 break;
931 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +0800932 snd_soc_component_update_bits(component, tx_vol_ctl_reg,
933 0x20, 0x00);
Karthikeyan Mani1dcd5a32019-08-22 14:37:13 -0700934 snd_soc_component_update_bits(component,
935 dec_cfg_reg, 0x06, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +0800936 snd_soc_component_update_bits(component, tx_vol_ctl_reg,
937 0x10, 0x00);
Karthikeyan Mani765eaab2019-07-18 16:27:01 -0700938 if (tx_priv->bcs_enable) {
939 snd_soc_component_update_bits(component, dec_cfg_reg,
940 0x01, 0x00);
941 snd_soc_component_update_bits(component,
942 BOLERO_CDC_TX0_TX_PATH_SEC7, 0x40, 0x00);
943 }
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530944 break;
945 }
946 return 0;
947}
948
949static int tx_macro_enable_micbias(struct snd_soc_dapm_widget *w,
950 struct snd_kcontrol *kcontrol, int event)
951{
952 return 0;
953}
954
955static int tx_macro_hw_params(struct snd_pcm_substream *substream,
956 struct snd_pcm_hw_params *params,
957 struct snd_soc_dai *dai)
958{
959 int tx_fs_rate = -EINVAL;
Meng Wang15c825d2018-09-06 10:49:18 +0800960 struct snd_soc_component *component = dai->component;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530961 u32 decimator = 0;
Laxminath Kasamb7f823c2018-08-02 13:23:11 +0530962 u32 sample_rate = 0;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530963 u16 tx_fs_reg = 0;
964 struct device *tx_dev = NULL;
965 struct tx_macro_priv *tx_priv = NULL;
966
Meng Wang15c825d2018-09-06 10:49:18 +0800967 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530968 return -EINVAL;
969
970 pr_debug("%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__,
971 dai->name, dai->id, params_rate(params),
972 params_channels(params));
973
974 sample_rate = params_rate(params);
975 switch (sample_rate) {
976 case 8000:
977 tx_fs_rate = 0;
978 break;
979 case 16000:
980 tx_fs_rate = 1;
981 break;
982 case 32000:
983 tx_fs_rate = 3;
984 break;
985 case 48000:
986 tx_fs_rate = 4;
987 break;
988 case 96000:
989 tx_fs_rate = 5;
990 break;
991 case 192000:
992 tx_fs_rate = 6;
993 break;
994 case 384000:
995 tx_fs_rate = 7;
996 break;
997 default:
Meng Wang15c825d2018-09-06 10:49:18 +0800998 dev_err(component->dev, "%s: Invalid TX sample rate: %d\n",
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530999 __func__, params_rate(params));
1000 return -EINVAL;
1001 }
1002 for_each_set_bit(decimator, &tx_priv->active_ch_mask[dai->id],
1003 TX_MACRO_DEC_MAX) {
1004 if (decimator >= 0) {
1005 tx_fs_reg = BOLERO_CDC_TX0_TX_PATH_CTL +
1006 TX_MACRO_TX_PATH_OFFSET * decimator;
Meng Wang15c825d2018-09-06 10:49:18 +08001007 dev_dbg(component->dev, "%s: set DEC%u rate to %u\n",
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301008 __func__, decimator, sample_rate);
Meng Wang15c825d2018-09-06 10:49:18 +08001009 snd_soc_component_update_bits(component, tx_fs_reg,
1010 0x0F, tx_fs_rate);
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301011 } else {
Meng Wang15c825d2018-09-06 10:49:18 +08001012 dev_err(component->dev,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301013 "%s: ERROR: Invalid decimator: %d\n",
1014 __func__, decimator);
1015 return -EINVAL;
1016 }
1017 }
1018 return 0;
1019}
1020
1021static int tx_macro_get_channel_map(struct snd_soc_dai *dai,
1022 unsigned int *tx_num, unsigned int *tx_slot,
1023 unsigned int *rx_num, unsigned int *rx_slot)
1024{
Meng Wang15c825d2018-09-06 10:49:18 +08001025 struct snd_soc_component *component = dai->component;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301026 struct device *tx_dev = NULL;
1027 struct tx_macro_priv *tx_priv = NULL;
1028
Meng Wang15c825d2018-09-06 10:49:18 +08001029 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301030 return -EINVAL;
1031
1032 switch (dai->id) {
1033 case TX_MACRO_AIF1_CAP:
1034 case TX_MACRO_AIF2_CAP:
Karthikeyan Manif3bb8182019-07-11 14:38:54 -07001035 case TX_MACRO_AIF3_CAP:
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301036 *tx_slot = tx_priv->active_ch_mask[dai->id];
1037 *tx_num = tx_priv->active_ch_cnt[dai->id];
1038 break;
1039 default:
1040 dev_err(tx_dev, "%s: Invalid AIF\n", __func__);
1041 break;
1042 }
1043 return 0;
1044}
1045
1046static struct snd_soc_dai_ops tx_macro_dai_ops = {
1047 .hw_params = tx_macro_hw_params,
1048 .get_channel_map = tx_macro_get_channel_map,
1049};
1050
1051static struct snd_soc_dai_driver tx_macro_dai[] = {
1052 {
1053 .name = "tx_macro_tx1",
1054 .id = TX_MACRO_AIF1_CAP,
1055 .capture = {
1056 .stream_name = "TX_AIF1 Capture",
1057 .rates = TX_MACRO_RATES,
1058 .formats = TX_MACRO_FORMATS,
1059 .rate_max = 192000,
1060 .rate_min = 8000,
1061 .channels_min = 1,
1062 .channels_max = 8,
1063 },
1064 .ops = &tx_macro_dai_ops,
1065 },
1066 {
1067 .name = "tx_macro_tx2",
1068 .id = TX_MACRO_AIF2_CAP,
1069 .capture = {
1070 .stream_name = "TX_AIF2 Capture",
1071 .rates = TX_MACRO_RATES,
1072 .formats = TX_MACRO_FORMATS,
1073 .rate_max = 192000,
1074 .rate_min = 8000,
1075 .channels_min = 1,
1076 .channels_max = 8,
1077 },
1078 .ops = &tx_macro_dai_ops,
1079 },
Karthikeyan Manif3bb8182019-07-11 14:38:54 -07001080 {
1081 .name = "tx_macro_tx3",
1082 .id = TX_MACRO_AIF3_CAP,
1083 .capture = {
1084 .stream_name = "TX_AIF3 Capture",
1085 .rates = TX_MACRO_RATES,
1086 .formats = TX_MACRO_FORMATS,
1087 .rate_max = 192000,
1088 .rate_min = 8000,
1089 .channels_min = 1,
1090 .channels_max = 8,
1091 },
1092 .ops = &tx_macro_dai_ops,
1093 },
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301094};
1095
1096#define STRING(name) #name
1097#define TX_MACRO_DAPM_ENUM(name, reg, offset, text) \
1098static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \
1099static const struct snd_kcontrol_new name##_mux = \
1100 SOC_DAPM_ENUM(STRING(name), name##_enum)
1101
1102#define TX_MACRO_DAPM_ENUM_EXT(name, reg, offset, text, getname, putname) \
1103static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \
1104static const struct snd_kcontrol_new name##_mux = \
1105 SOC_DAPM_ENUM_EXT(STRING(name), name##_enum, getname, putname)
1106
1107#define TX_MACRO_DAPM_MUX(name, shift, kctl) \
1108 SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, shift, 0, &kctl##_mux)
1109
1110static const char * const adc_mux_text[] = {
1111 "MSM_DMIC", "SWR_MIC", "ANC_FB_TUNE1"
1112};
1113
1114TX_MACRO_DAPM_ENUM(tx_dec0, BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG1,
1115 0, adc_mux_text);
1116TX_MACRO_DAPM_ENUM(tx_dec1, BOLERO_CDC_TX_INP_MUX_ADC_MUX1_CFG1,
1117 0, adc_mux_text);
1118TX_MACRO_DAPM_ENUM(tx_dec2, BOLERO_CDC_TX_INP_MUX_ADC_MUX2_CFG1,
1119 0, adc_mux_text);
1120TX_MACRO_DAPM_ENUM(tx_dec3, BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG1,
1121 0, adc_mux_text);
1122TX_MACRO_DAPM_ENUM(tx_dec4, BOLERO_CDC_TX_INP_MUX_ADC_MUX4_CFG1,
1123 0, adc_mux_text);
1124TX_MACRO_DAPM_ENUM(tx_dec5, BOLERO_CDC_TX_INP_MUX_ADC_MUX5_CFG1,
1125 0, adc_mux_text);
1126TX_MACRO_DAPM_ENUM(tx_dec6, BOLERO_CDC_TX_INP_MUX_ADC_MUX6_CFG1,
1127 0, adc_mux_text);
1128TX_MACRO_DAPM_ENUM(tx_dec7, BOLERO_CDC_TX_INP_MUX_ADC_MUX7_CFG1,
1129 0, adc_mux_text);
1130
1131
1132static const char * const dmic_mux_text[] = {
1133 "ZERO", "DMIC0", "DMIC1", "DMIC2", "DMIC3",
1134 "DMIC4", "DMIC5", "DMIC6", "DMIC7"
1135};
1136
1137TX_MACRO_DAPM_ENUM_EXT(tx_dmic0, BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0,
1138 4, dmic_mux_text, snd_soc_dapm_get_enum_double,
1139 tx_macro_put_dec_enum);
1140
1141TX_MACRO_DAPM_ENUM_EXT(tx_dmic1, BOLERO_CDC_TX_INP_MUX_ADC_MUX1_CFG0,
1142 4, dmic_mux_text, snd_soc_dapm_get_enum_double,
1143 tx_macro_put_dec_enum);
1144
1145TX_MACRO_DAPM_ENUM_EXT(tx_dmic2, BOLERO_CDC_TX_INP_MUX_ADC_MUX2_CFG0,
1146 4, dmic_mux_text, snd_soc_dapm_get_enum_double,
1147 tx_macro_put_dec_enum);
1148
1149TX_MACRO_DAPM_ENUM_EXT(tx_dmic3, BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG0,
1150 4, dmic_mux_text, snd_soc_dapm_get_enum_double,
1151 tx_macro_put_dec_enum);
1152
1153TX_MACRO_DAPM_ENUM_EXT(tx_dmic4, BOLERO_CDC_TX_INP_MUX_ADC_MUX4_CFG0,
1154 4, dmic_mux_text, snd_soc_dapm_get_enum_double,
1155 tx_macro_put_dec_enum);
1156
1157TX_MACRO_DAPM_ENUM_EXT(tx_dmic5, BOLERO_CDC_TX_INP_MUX_ADC_MUX5_CFG0,
1158 4, dmic_mux_text, snd_soc_dapm_get_enum_double,
1159 tx_macro_put_dec_enum);
1160
1161TX_MACRO_DAPM_ENUM_EXT(tx_dmic6, BOLERO_CDC_TX_INP_MUX_ADC_MUX6_CFG0,
1162 4, dmic_mux_text, snd_soc_dapm_get_enum_double,
1163 tx_macro_put_dec_enum);
1164
1165TX_MACRO_DAPM_ENUM_EXT(tx_dmic7, BOLERO_CDC_TX_INP_MUX_ADC_MUX7_CFG0,
1166 4, dmic_mux_text, snd_soc_dapm_get_enum_double,
1167 tx_macro_put_dec_enum);
1168
1169static const char * const smic_mux_text[] = {
Sudheer Papothi324b4952019-06-11 04:14:51 +05301170 "ZERO", "ADC0", "ADC1", "ADC2", "ADC3", "SWR_DMIC0",
1171 "SWR_DMIC1", "SWR_DMIC2", "SWR_DMIC3", "SWR_DMIC4",
1172 "SWR_DMIC5", "SWR_DMIC6", "SWR_DMIC7"
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301173};
1174
1175TX_MACRO_DAPM_ENUM_EXT(tx_smic0, BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0,
1176 0, smic_mux_text, snd_soc_dapm_get_enum_double,
1177 tx_macro_put_dec_enum);
1178
1179TX_MACRO_DAPM_ENUM_EXT(tx_smic1, BOLERO_CDC_TX_INP_MUX_ADC_MUX1_CFG0,
1180 0, smic_mux_text, snd_soc_dapm_get_enum_double,
1181 tx_macro_put_dec_enum);
1182
1183TX_MACRO_DAPM_ENUM_EXT(tx_smic2, BOLERO_CDC_TX_INP_MUX_ADC_MUX2_CFG0,
1184 0, smic_mux_text, snd_soc_dapm_get_enum_double,
1185 tx_macro_put_dec_enum);
1186
1187TX_MACRO_DAPM_ENUM_EXT(tx_smic3, BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG0,
1188 0, smic_mux_text, snd_soc_dapm_get_enum_double,
1189 tx_macro_put_dec_enum);
1190
1191TX_MACRO_DAPM_ENUM_EXT(tx_smic4, BOLERO_CDC_TX_INP_MUX_ADC_MUX4_CFG0,
1192 0, smic_mux_text, snd_soc_dapm_get_enum_double,
1193 tx_macro_put_dec_enum);
1194
1195TX_MACRO_DAPM_ENUM_EXT(tx_smic5, BOLERO_CDC_TX_INP_MUX_ADC_MUX5_CFG0,
1196 0, smic_mux_text, snd_soc_dapm_get_enum_double,
1197 tx_macro_put_dec_enum);
1198
1199TX_MACRO_DAPM_ENUM_EXT(tx_smic6, BOLERO_CDC_TX_INP_MUX_ADC_MUX6_CFG0,
1200 0, smic_mux_text, snd_soc_dapm_get_enum_double,
1201 tx_macro_put_dec_enum);
1202
1203TX_MACRO_DAPM_ENUM_EXT(tx_smic7, BOLERO_CDC_TX_INP_MUX_ADC_MUX7_CFG0,
1204 0, smic_mux_text, snd_soc_dapm_get_enum_double,
1205 tx_macro_put_dec_enum);
1206
Karthikeyan Mani1dcd5a32019-08-22 14:37:13 -07001207static const char * const dec_mode_mux_text[] = {
1208 "ADC_DEFAULT", "ADC_LOW_PWR", "ADC_HIGH_PERF",
1209};
1210
1211static const struct soc_enum dec_mode_mux_enum =
1212 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(dec_mode_mux_text),
1213 dec_mode_mux_text);
1214
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301215static const struct snd_kcontrol_new tx_aif1_cap_mixer[] = {
1216 SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, TX_MACRO_DEC0, 1, 0,
1217 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1218 SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, TX_MACRO_DEC1, 1, 0,
1219 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1220 SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, TX_MACRO_DEC2, 1, 0,
1221 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1222 SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, TX_MACRO_DEC3, 1, 0,
1223 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1224 SOC_SINGLE_EXT("DEC4", SND_SOC_NOPM, TX_MACRO_DEC4, 1, 0,
1225 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1226 SOC_SINGLE_EXT("DEC5", SND_SOC_NOPM, TX_MACRO_DEC5, 1, 0,
1227 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1228 SOC_SINGLE_EXT("DEC6", SND_SOC_NOPM, TX_MACRO_DEC6, 1, 0,
1229 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1230 SOC_SINGLE_EXT("DEC7", SND_SOC_NOPM, TX_MACRO_DEC7, 1, 0,
1231 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1232};
1233
1234static const struct snd_kcontrol_new tx_aif2_cap_mixer[] = {
1235 SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, TX_MACRO_DEC0, 1, 0,
1236 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1237 SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, TX_MACRO_DEC1, 1, 0,
1238 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1239 SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, TX_MACRO_DEC2, 1, 0,
1240 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1241 SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, TX_MACRO_DEC3, 1, 0,
1242 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1243 SOC_SINGLE_EXT("DEC4", SND_SOC_NOPM, TX_MACRO_DEC4, 1, 0,
1244 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1245 SOC_SINGLE_EXT("DEC5", SND_SOC_NOPM, TX_MACRO_DEC5, 1, 0,
1246 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1247 SOC_SINGLE_EXT("DEC6", SND_SOC_NOPM, TX_MACRO_DEC6, 1, 0,
1248 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1249 SOC_SINGLE_EXT("DEC7", SND_SOC_NOPM, TX_MACRO_DEC7, 1, 0,
1250 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1251};
1252
Karthikeyan Manif3bb8182019-07-11 14:38:54 -07001253static const struct snd_kcontrol_new tx_aif3_cap_mixer[] = {
1254 SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, TX_MACRO_DEC0, 1, 0,
1255 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1256 SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, TX_MACRO_DEC1, 1, 0,
1257 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1258 SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, TX_MACRO_DEC2, 1, 0,
1259 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1260 SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, TX_MACRO_DEC3, 1, 0,
1261 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1262 SOC_SINGLE_EXT("DEC4", SND_SOC_NOPM, TX_MACRO_DEC4, 1, 0,
1263 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1264 SOC_SINGLE_EXT("DEC5", SND_SOC_NOPM, TX_MACRO_DEC5, 1, 0,
1265 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1266 SOC_SINGLE_EXT("DEC6", SND_SOC_NOPM, TX_MACRO_DEC6, 1, 0,
1267 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1268 SOC_SINGLE_EXT("DEC7", SND_SOC_NOPM, TX_MACRO_DEC7, 1, 0,
1269 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1270};
1271
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301272static const struct snd_soc_dapm_widget tx_macro_dapm_widgets[] = {
1273 SND_SOC_DAPM_AIF_OUT("TX_AIF1 CAP", "TX_AIF1 Capture", 0,
1274 SND_SOC_NOPM, TX_MACRO_AIF1_CAP, 0),
1275
1276 SND_SOC_DAPM_AIF_OUT("TX_AIF2 CAP", "TX_AIF2 Capture", 0,
1277 SND_SOC_NOPM, TX_MACRO_AIF2_CAP, 0),
1278
Karthikeyan Manif3bb8182019-07-11 14:38:54 -07001279 SND_SOC_DAPM_AIF_OUT("TX_AIF3 CAP", "TX_AIF3 Capture", 0,
1280 SND_SOC_NOPM, TX_MACRO_AIF3_CAP, 0),
1281
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301282 SND_SOC_DAPM_MIXER("TX_AIF1_CAP Mixer", SND_SOC_NOPM, TX_MACRO_AIF1_CAP, 0,
1283 tx_aif1_cap_mixer, ARRAY_SIZE(tx_aif1_cap_mixer)),
1284
1285 SND_SOC_DAPM_MIXER("TX_AIF2_CAP Mixer", SND_SOC_NOPM, TX_MACRO_AIF2_CAP, 0,
1286 tx_aif2_cap_mixer, ARRAY_SIZE(tx_aif2_cap_mixer)),
1287
Karthikeyan Manif3bb8182019-07-11 14:38:54 -07001288 SND_SOC_DAPM_MIXER("TX_AIF3_CAP Mixer", SND_SOC_NOPM, TX_MACRO_AIF3_CAP, 0,
1289 tx_aif3_cap_mixer, ARRAY_SIZE(tx_aif3_cap_mixer)),
1290
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301291
1292 TX_MACRO_DAPM_MUX("TX DMIC MUX0", 0, tx_dmic0),
1293 TX_MACRO_DAPM_MUX("TX DMIC MUX1", 0, tx_dmic1),
1294 TX_MACRO_DAPM_MUX("TX DMIC MUX2", 0, tx_dmic2),
1295 TX_MACRO_DAPM_MUX("TX DMIC MUX3", 0, tx_dmic3),
1296 TX_MACRO_DAPM_MUX("TX DMIC MUX4", 0, tx_dmic4),
1297 TX_MACRO_DAPM_MUX("TX DMIC MUX5", 0, tx_dmic5),
1298 TX_MACRO_DAPM_MUX("TX DMIC MUX6", 0, tx_dmic6),
1299 TX_MACRO_DAPM_MUX("TX DMIC MUX7", 0, tx_dmic7),
1300
1301 TX_MACRO_DAPM_MUX("TX SMIC MUX0", 0, tx_smic0),
1302 TX_MACRO_DAPM_MUX("TX SMIC MUX1", 0, tx_smic1),
1303 TX_MACRO_DAPM_MUX("TX SMIC MUX2", 0, tx_smic2),
1304 TX_MACRO_DAPM_MUX("TX SMIC MUX3", 0, tx_smic3),
1305 TX_MACRO_DAPM_MUX("TX SMIC MUX4", 0, tx_smic4),
1306 TX_MACRO_DAPM_MUX("TX SMIC MUX5", 0, tx_smic5),
1307 TX_MACRO_DAPM_MUX("TX SMIC MUX6", 0, tx_smic6),
1308 TX_MACRO_DAPM_MUX("TX SMIC MUX7", 0, tx_smic7),
1309
1310 SND_SOC_DAPM_MICBIAS_E("TX MIC BIAS1", SND_SOC_NOPM, 0, 0,
1311 tx_macro_enable_micbias,
1312 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1313 SND_SOC_DAPM_ADC_E("TX DMIC0", NULL, SND_SOC_NOPM, 0, 0,
1314 tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
1315 SND_SOC_DAPM_POST_PMD),
1316
1317 SND_SOC_DAPM_ADC_E("TX DMIC1", NULL, SND_SOC_NOPM, 0, 0,
1318 tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
1319 SND_SOC_DAPM_POST_PMD),
1320
1321 SND_SOC_DAPM_ADC_E("TX DMIC2", NULL, SND_SOC_NOPM, 0, 0,
1322 tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
1323 SND_SOC_DAPM_POST_PMD),
1324
1325 SND_SOC_DAPM_ADC_E("TX DMIC3", NULL, SND_SOC_NOPM, 0, 0,
1326 tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
1327 SND_SOC_DAPM_POST_PMD),
1328
1329 SND_SOC_DAPM_ADC_E("TX DMIC4", NULL, SND_SOC_NOPM, 0, 0,
1330 tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
1331 SND_SOC_DAPM_POST_PMD),
1332
1333 SND_SOC_DAPM_ADC_E("TX DMIC5", NULL, SND_SOC_NOPM, 0, 0,
1334 tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
1335 SND_SOC_DAPM_POST_PMD),
1336
1337 SND_SOC_DAPM_ADC_E("TX DMIC6", NULL, SND_SOC_NOPM, 0, 0,
1338 tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
1339 SND_SOC_DAPM_POST_PMD),
1340
1341 SND_SOC_DAPM_ADC_E("TX DMIC7", NULL, SND_SOC_NOPM, 0, 0,
1342 tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
1343 SND_SOC_DAPM_POST_PMD),
1344
1345 SND_SOC_DAPM_INPUT("TX SWR_ADC0"),
1346 SND_SOC_DAPM_INPUT("TX SWR_ADC1"),
1347 SND_SOC_DAPM_INPUT("TX SWR_ADC2"),
1348 SND_SOC_DAPM_INPUT("TX SWR_ADC3"),
1349 SND_SOC_DAPM_INPUT("TX SWR_DMIC0"),
1350 SND_SOC_DAPM_INPUT("TX SWR_DMIC1"),
1351 SND_SOC_DAPM_INPUT("TX SWR_DMIC2"),
1352 SND_SOC_DAPM_INPUT("TX SWR_DMIC3"),
1353 SND_SOC_DAPM_INPUT("TX SWR_DMIC4"),
1354 SND_SOC_DAPM_INPUT("TX SWR_DMIC5"),
1355 SND_SOC_DAPM_INPUT("TX SWR_DMIC6"),
1356 SND_SOC_DAPM_INPUT("TX SWR_DMIC7"),
1357
Ramprasad Katkamf83acfb2018-08-11 23:28:57 +05301358 SND_SOC_DAPM_MUX_E("TX DEC0 MUX", SND_SOC_NOPM,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301359 TX_MACRO_DEC0, 0,
1360 &tx_dec0_mux, tx_macro_enable_dec,
1361 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1362 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1363
Ramprasad Katkamf83acfb2018-08-11 23:28:57 +05301364 SND_SOC_DAPM_MUX_E("TX DEC1 MUX", SND_SOC_NOPM,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301365 TX_MACRO_DEC1, 0,
1366 &tx_dec1_mux, tx_macro_enable_dec,
1367 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1368 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1369
Ramprasad Katkamf83acfb2018-08-11 23:28:57 +05301370 SND_SOC_DAPM_MUX_E("TX DEC2 MUX", SND_SOC_NOPM,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301371 TX_MACRO_DEC2, 0,
1372 &tx_dec2_mux, tx_macro_enable_dec,
1373 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1374 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1375
Ramprasad Katkamf83acfb2018-08-11 23:28:57 +05301376 SND_SOC_DAPM_MUX_E("TX DEC3 MUX", SND_SOC_NOPM,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301377 TX_MACRO_DEC3, 0,
1378 &tx_dec3_mux, tx_macro_enable_dec,
1379 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1380 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1381
Ramprasad Katkamf83acfb2018-08-11 23:28:57 +05301382 SND_SOC_DAPM_MUX_E("TX DEC4 MUX", SND_SOC_NOPM,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301383 TX_MACRO_DEC4, 0,
1384 &tx_dec4_mux, tx_macro_enable_dec,
1385 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1386 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1387
Ramprasad Katkamf83acfb2018-08-11 23:28:57 +05301388 SND_SOC_DAPM_MUX_E("TX DEC5 MUX", SND_SOC_NOPM,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301389 TX_MACRO_DEC5, 0,
1390 &tx_dec5_mux, tx_macro_enable_dec,
1391 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1392 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1393
Ramprasad Katkamf83acfb2018-08-11 23:28:57 +05301394 SND_SOC_DAPM_MUX_E("TX DEC6 MUX", SND_SOC_NOPM,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301395 TX_MACRO_DEC6, 0,
1396 &tx_dec6_mux, tx_macro_enable_dec,
1397 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1398 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1399
Ramprasad Katkamf83acfb2018-08-11 23:28:57 +05301400 SND_SOC_DAPM_MUX_E("TX DEC7 MUX", SND_SOC_NOPM,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301401 TX_MACRO_DEC7, 0,
1402 &tx_dec7_mux, tx_macro_enable_dec,
1403 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1404 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1405
1406 SND_SOC_DAPM_SUPPLY_S("TX_MCLK", 0, SND_SOC_NOPM, 0, 0,
1407 tx_macro_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
Sudheer Papothie456c2c2019-03-05 07:08:45 +05301408
1409 SND_SOC_DAPM_SUPPLY_S("TX_SWR_CLK", 0, SND_SOC_NOPM, 0, 0,
1410 tx_macro_tx_swr_clk_event,
1411 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1412
1413 SND_SOC_DAPM_SUPPLY_S("VA_SWR_CLK", 0, SND_SOC_NOPM, 0, 0,
1414 tx_macro_va_swr_clk_event,
1415 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301416};
1417
1418static const struct snd_soc_dapm_route tx_audio_map[] = {
1419 {"TX_AIF1 CAP", NULL, "TX_MCLK"},
1420 {"TX_AIF2 CAP", NULL, "TX_MCLK"},
Karthikeyan Manif3bb8182019-07-11 14:38:54 -07001421 {"TX_AIF3 CAP", NULL, "TX_MCLK"},
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301422
1423 {"TX_AIF1 CAP", NULL, "TX_AIF1_CAP Mixer"},
1424 {"TX_AIF2 CAP", NULL, "TX_AIF2_CAP Mixer"},
Karthikeyan Manif3bb8182019-07-11 14:38:54 -07001425 {"TX_AIF3 CAP", NULL, "TX_AIF3_CAP Mixer"},
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301426
1427 {"TX_AIF1_CAP Mixer", "DEC0", "TX DEC0 MUX"},
1428 {"TX_AIF1_CAP Mixer", "DEC1", "TX DEC1 MUX"},
1429 {"TX_AIF1_CAP Mixer", "DEC2", "TX DEC2 MUX"},
1430 {"TX_AIF1_CAP Mixer", "DEC3", "TX DEC3 MUX"},
1431 {"TX_AIF1_CAP Mixer", "DEC4", "TX DEC4 MUX"},
1432 {"TX_AIF1_CAP Mixer", "DEC5", "TX DEC5 MUX"},
1433 {"TX_AIF1_CAP Mixer", "DEC6", "TX DEC6 MUX"},
1434 {"TX_AIF1_CAP Mixer", "DEC7", "TX DEC7 MUX"},
1435
1436 {"TX_AIF2_CAP Mixer", "DEC0", "TX DEC0 MUX"},
1437 {"TX_AIF2_CAP Mixer", "DEC1", "TX DEC1 MUX"},
1438 {"TX_AIF2_CAP Mixer", "DEC2", "TX DEC2 MUX"},
1439 {"TX_AIF2_CAP Mixer", "DEC3", "TX DEC3 MUX"},
1440 {"TX_AIF2_CAP Mixer", "DEC4", "TX DEC4 MUX"},
1441 {"TX_AIF2_CAP Mixer", "DEC5", "TX DEC5 MUX"},
1442 {"TX_AIF2_CAP Mixer", "DEC6", "TX DEC6 MUX"},
1443 {"TX_AIF2_CAP Mixer", "DEC7", "TX DEC7 MUX"},
1444
Karthikeyan Manif3bb8182019-07-11 14:38:54 -07001445 {"TX_AIF3_CAP Mixer", "DEC0", "TX DEC0 MUX"},
1446 {"TX_AIF3_CAP Mixer", "DEC1", "TX DEC1 MUX"},
1447 {"TX_AIF3_CAP Mixer", "DEC2", "TX DEC2 MUX"},
1448 {"TX_AIF3_CAP Mixer", "DEC3", "TX DEC3 MUX"},
1449 {"TX_AIF3_CAP Mixer", "DEC4", "TX DEC4 MUX"},
1450 {"TX_AIF3_CAP Mixer", "DEC5", "TX DEC5 MUX"},
1451 {"TX_AIF3_CAP Mixer", "DEC6", "TX DEC6 MUX"},
1452 {"TX_AIF3_CAP Mixer", "DEC7", "TX DEC7 MUX"},
1453
Laxminath Kasamfc281ad2018-08-06 20:19:40 +05301454 {"TX DEC0 MUX", NULL, "TX_MCLK"},
1455 {"TX DEC1 MUX", NULL, "TX_MCLK"},
1456 {"TX DEC2 MUX", NULL, "TX_MCLK"},
1457 {"TX DEC3 MUX", NULL, "TX_MCLK"},
1458 {"TX DEC4 MUX", NULL, "TX_MCLK"},
1459 {"TX DEC5 MUX", NULL, "TX_MCLK"},
1460 {"TX DEC6 MUX", NULL, "TX_MCLK"},
1461 {"TX DEC7 MUX", NULL, "TX_MCLK"},
1462
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301463 {"TX DEC0 MUX", "MSM_DMIC", "TX DMIC MUX0"},
1464 {"TX DMIC MUX0", "DMIC0", "TX DMIC0"},
1465 {"TX DMIC MUX0", "DMIC1", "TX DMIC1"},
1466 {"TX DMIC MUX0", "DMIC2", "TX DMIC2"},
1467 {"TX DMIC MUX0", "DMIC3", "TX DMIC3"},
1468 {"TX DMIC MUX0", "DMIC4", "TX DMIC4"},
1469 {"TX DMIC MUX0", "DMIC5", "TX DMIC5"},
1470 {"TX DMIC MUX0", "DMIC6", "TX DMIC6"},
1471 {"TX DMIC MUX0", "DMIC7", "TX DMIC7"},
1472
1473 {"TX DEC0 MUX", "SWR_MIC", "TX SMIC MUX0"},
Sudheer Papothie456c2c2019-03-05 07:08:45 +05301474 {"TX SMIC MUX0", NULL, "TX_SWR_CLK"},
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301475 {"TX SMIC MUX0", "ADC0", "TX SWR_ADC0"},
1476 {"TX SMIC MUX0", "ADC1", "TX SWR_ADC1"},
1477 {"TX SMIC MUX0", "ADC2", "TX SWR_ADC2"},
1478 {"TX SMIC MUX0", "ADC3", "TX SWR_ADC3"},
1479 {"TX SMIC MUX0", "SWR_DMIC0", "TX SWR_DMIC0"},
1480 {"TX SMIC MUX0", "SWR_DMIC1", "TX SWR_DMIC1"},
1481 {"TX SMIC MUX0", "SWR_DMIC2", "TX SWR_DMIC2"},
1482 {"TX SMIC MUX0", "SWR_DMIC3", "TX SWR_DMIC3"},
1483 {"TX SMIC MUX0", "SWR_DMIC4", "TX SWR_DMIC4"},
1484 {"TX SMIC MUX0", "SWR_DMIC5", "TX SWR_DMIC5"},
1485 {"TX SMIC MUX0", "SWR_DMIC6", "TX SWR_DMIC6"},
1486 {"TX SMIC MUX0", "SWR_DMIC7", "TX SWR_DMIC7"},
1487
1488 {"TX DEC1 MUX", "MSM_DMIC", "TX DMIC MUX1"},
1489 {"TX DMIC MUX1", "DMIC0", "TX DMIC0"},
1490 {"TX DMIC MUX1", "DMIC1", "TX DMIC1"},
1491 {"TX DMIC MUX1", "DMIC2", "TX DMIC2"},
1492 {"TX DMIC MUX1", "DMIC3", "TX DMIC3"},
1493 {"TX DMIC MUX1", "DMIC4", "TX DMIC4"},
1494 {"TX DMIC MUX1", "DMIC5", "TX DMIC5"},
1495 {"TX DMIC MUX1", "DMIC6", "TX DMIC6"},
1496 {"TX DMIC MUX1", "DMIC7", "TX DMIC7"},
1497
1498 {"TX DEC1 MUX", "SWR_MIC", "TX SMIC MUX1"},
Sudheer Papothie456c2c2019-03-05 07:08:45 +05301499 {"TX SMIC MUX1", NULL, "TX_SWR_CLK"},
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301500 {"TX SMIC MUX1", "ADC0", "TX SWR_ADC0"},
1501 {"TX SMIC MUX1", "ADC1", "TX SWR_ADC1"},
1502 {"TX SMIC MUX1", "ADC2", "TX SWR_ADC2"},
1503 {"TX SMIC MUX1", "ADC3", "TX SWR_ADC3"},
1504 {"TX SMIC MUX1", "SWR_DMIC0", "TX SWR_DMIC0"},
1505 {"TX SMIC MUX1", "SWR_DMIC1", "TX SWR_DMIC1"},
1506 {"TX SMIC MUX1", "SWR_DMIC2", "TX SWR_DMIC2"},
1507 {"TX SMIC MUX1", "SWR_DMIC3", "TX SWR_DMIC3"},
1508 {"TX SMIC MUX1", "SWR_DMIC4", "TX SWR_DMIC4"},
1509 {"TX SMIC MUX1", "SWR_DMIC5", "TX SWR_DMIC5"},
1510 {"TX SMIC MUX1", "SWR_DMIC6", "TX SWR_DMIC6"},
1511 {"TX SMIC MUX1", "SWR_DMIC7", "TX SWR_DMIC7"},
1512
1513 {"TX DEC2 MUX", "MSM_DMIC", "TX DMIC MUX2"},
1514 {"TX DMIC MUX2", "DMIC0", "TX DMIC0"},
1515 {"TX DMIC MUX2", "DMIC1", "TX DMIC1"},
1516 {"TX DMIC MUX2", "DMIC2", "TX DMIC2"},
1517 {"TX DMIC MUX2", "DMIC3", "TX DMIC3"},
1518 {"TX DMIC MUX2", "DMIC4", "TX DMIC4"},
1519 {"TX DMIC MUX2", "DMIC5", "TX DMIC5"},
1520 {"TX DMIC MUX2", "DMIC6", "TX DMIC6"},
1521 {"TX DMIC MUX2", "DMIC7", "TX DMIC7"},
1522
1523 {"TX DEC2 MUX", "SWR_MIC", "TX SMIC MUX2"},
Sudheer Papothie456c2c2019-03-05 07:08:45 +05301524 {"TX SMIC MUX2", NULL, "TX_SWR_CLK"},
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301525 {"TX SMIC MUX2", "ADC0", "TX SWR_ADC0"},
1526 {"TX SMIC MUX2", "ADC1", "TX SWR_ADC1"},
1527 {"TX SMIC MUX2", "ADC2", "TX SWR_ADC2"},
1528 {"TX SMIC MUX2", "ADC3", "TX SWR_ADC3"},
1529 {"TX SMIC MUX2", "SWR_DMIC0", "TX SWR_DMIC0"},
1530 {"TX SMIC MUX2", "SWR_DMIC1", "TX SWR_DMIC1"},
1531 {"TX SMIC MUX2", "SWR_DMIC2", "TX SWR_DMIC2"},
1532 {"TX SMIC MUX2", "SWR_DMIC3", "TX SWR_DMIC3"},
1533 {"TX SMIC MUX2", "SWR_DMIC4", "TX SWR_DMIC4"},
1534 {"TX SMIC MUX2", "SWR_DMIC5", "TX SWR_DMIC5"},
1535 {"TX SMIC MUX2", "SWR_DMIC6", "TX SWR_DMIC6"},
1536 {"TX SMIC MUX2", "SWR_DMIC7", "TX SWR_DMIC7"},
1537
1538 {"TX DEC3 MUX", "MSM_DMIC", "TX DMIC MUX3"},
1539 {"TX DMIC MUX3", "DMIC0", "TX DMIC0"},
1540 {"TX DMIC MUX3", "DMIC1", "TX DMIC1"},
1541 {"TX DMIC MUX3", "DMIC2", "TX DMIC2"},
1542 {"TX DMIC MUX3", "DMIC3", "TX DMIC3"},
1543 {"TX DMIC MUX3", "DMIC4", "TX DMIC4"},
1544 {"TX DMIC MUX3", "DMIC5", "TX DMIC5"},
1545 {"TX DMIC MUX3", "DMIC6", "TX DMIC6"},
1546 {"TX DMIC MUX3", "DMIC7", "TX DMIC7"},
1547
1548 {"TX DEC3 MUX", "SWR_MIC", "TX SMIC MUX3"},
Sudheer Papothie456c2c2019-03-05 07:08:45 +05301549 {"TX SMIC MUX3", NULL, "TX_SWR_CLK"},
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301550 {"TX SMIC MUX3", "ADC0", "TX SWR_ADC0"},
1551 {"TX SMIC MUX3", "ADC1", "TX SWR_ADC1"},
1552 {"TX SMIC MUX3", "ADC2", "TX SWR_ADC2"},
1553 {"TX SMIC MUX3", "ADC3", "TX SWR_ADC3"},
1554 {"TX SMIC MUX3", "SWR_DMIC0", "TX SWR_DMIC0"},
1555 {"TX SMIC MUX3", "SWR_DMIC1", "TX SWR_DMIC1"},
1556 {"TX SMIC MUX3", "SWR_DMIC2", "TX SWR_DMIC2"},
1557 {"TX SMIC MUX3", "SWR_DMIC3", "TX SWR_DMIC3"},
1558 {"TX SMIC MUX3", "SWR_DMIC4", "TX SWR_DMIC4"},
1559 {"TX SMIC MUX3", "SWR_DMIC5", "TX SWR_DMIC5"},
1560 {"TX SMIC MUX3", "SWR_DMIC6", "TX SWR_DMIC6"},
1561 {"TX SMIC MUX3", "SWR_DMIC7", "TX SWR_DMIC7"},
1562
1563 {"TX DEC4 MUX", "MSM_DMIC", "TX DMIC MUX4"},
1564 {"TX DMIC MUX4", "DMIC0", "TX DMIC0"},
1565 {"TX DMIC MUX4", "DMIC1", "TX DMIC1"},
1566 {"TX DMIC MUX4", "DMIC2", "TX DMIC2"},
1567 {"TX DMIC MUX4", "DMIC3", "TX DMIC3"},
1568 {"TX DMIC MUX4", "DMIC4", "TX DMIC4"},
1569 {"TX DMIC MUX4", "DMIC5", "TX DMIC5"},
1570 {"TX DMIC MUX4", "DMIC6", "TX DMIC6"},
1571 {"TX DMIC MUX4", "DMIC7", "TX DMIC7"},
1572
1573 {"TX DEC4 MUX", "SWR_MIC", "TX SMIC MUX4"},
Sudheer Papothie456c2c2019-03-05 07:08:45 +05301574 {"TX SMIC MUX4", NULL, "TX_SWR_CLK"},
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301575 {"TX SMIC MUX4", "ADC0", "TX SWR_ADC0"},
1576 {"TX SMIC MUX4", "ADC1", "TX SWR_ADC1"},
1577 {"TX SMIC MUX4", "ADC2", "TX SWR_ADC2"},
1578 {"TX SMIC MUX4", "ADC3", "TX SWR_ADC3"},
1579 {"TX SMIC MUX4", "SWR_DMIC0", "TX SWR_DMIC0"},
1580 {"TX SMIC MUX4", "SWR_DMIC1", "TX SWR_DMIC1"},
1581 {"TX SMIC MUX4", "SWR_DMIC2", "TX SWR_DMIC2"},
1582 {"TX SMIC MUX4", "SWR_DMIC3", "TX SWR_DMIC3"},
1583 {"TX SMIC MUX4", "SWR_DMIC4", "TX SWR_DMIC4"},
1584 {"TX SMIC MUX4", "SWR_DMIC5", "TX SWR_DMIC5"},
1585 {"TX SMIC MUX4", "SWR_DMIC6", "TX SWR_DMIC6"},
1586 {"TX SMIC MUX4", "SWR_DMIC7", "TX SWR_DMIC7"},
1587
1588 {"TX DEC5 MUX", "MSM_DMIC", "TX DMIC MUX5"},
1589 {"TX DMIC MUX5", "DMIC0", "TX DMIC0"},
1590 {"TX DMIC MUX5", "DMIC1", "TX DMIC1"},
1591 {"TX DMIC MUX5", "DMIC2", "TX DMIC2"},
1592 {"TX DMIC MUX5", "DMIC3", "TX DMIC3"},
1593 {"TX DMIC MUX5", "DMIC4", "TX DMIC4"},
1594 {"TX DMIC MUX5", "DMIC5", "TX DMIC5"},
1595 {"TX DMIC MUX5", "DMIC6", "TX DMIC6"},
1596 {"TX DMIC MUX5", "DMIC7", "TX DMIC7"},
1597
1598 {"TX DEC5 MUX", "SWR_MIC", "TX SMIC MUX5"},
Sudheer Papothie456c2c2019-03-05 07:08:45 +05301599 {"TX SMIC MUX5", NULL, "TX_SWR_CLK"},
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301600 {"TX SMIC MUX5", "ADC0", "TX SWR_ADC0"},
1601 {"TX SMIC MUX5", "ADC1", "TX SWR_ADC1"},
1602 {"TX SMIC MUX5", "ADC2", "TX SWR_ADC2"},
1603 {"TX SMIC MUX5", "ADC3", "TX SWR_ADC3"},
1604 {"TX SMIC MUX5", "SWR_DMIC0", "TX SWR_DMIC0"},
1605 {"TX SMIC MUX5", "SWR_DMIC1", "TX SWR_DMIC1"},
1606 {"TX SMIC MUX5", "SWR_DMIC2", "TX SWR_DMIC2"},
1607 {"TX SMIC MUX5", "SWR_DMIC3", "TX SWR_DMIC3"},
1608 {"TX SMIC MUX5", "SWR_DMIC4", "TX SWR_DMIC4"},
1609 {"TX SMIC MUX5", "SWR_DMIC5", "TX SWR_DMIC5"},
1610 {"TX SMIC MUX5", "SWR_DMIC6", "TX SWR_DMIC6"},
1611 {"TX SMIC MUX5", "SWR_DMIC7", "TX SWR_DMIC7"},
1612
1613 {"TX DEC6 MUX", "MSM_DMIC", "TX DMIC MUX6"},
1614 {"TX DMIC MUX6", "DMIC0", "TX DMIC0"},
1615 {"TX DMIC MUX6", "DMIC1", "TX DMIC1"},
1616 {"TX DMIC MUX6", "DMIC2", "TX DMIC2"},
1617 {"TX DMIC MUX6", "DMIC3", "TX DMIC3"},
1618 {"TX DMIC MUX6", "DMIC4", "TX DMIC4"},
1619 {"TX DMIC MUX6", "DMIC5", "TX DMIC5"},
1620 {"TX DMIC MUX6", "DMIC6", "TX DMIC6"},
1621 {"TX DMIC MUX6", "DMIC7", "TX DMIC7"},
1622
1623 {"TX DEC6 MUX", "SWR_MIC", "TX SMIC MUX6"},
Sudheer Papothie456c2c2019-03-05 07:08:45 +05301624 {"TX SMIC MUX6", NULL, "TX_SWR_CLK"},
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301625 {"TX SMIC MUX6", "ADC0", "TX SWR_ADC0"},
1626 {"TX SMIC MUX6", "ADC1", "TX SWR_ADC1"},
1627 {"TX SMIC MUX6", "ADC2", "TX SWR_ADC2"},
1628 {"TX SMIC MUX6", "ADC3", "TX SWR_ADC3"},
1629 {"TX SMIC MUX6", "SWR_DMIC0", "TX SWR_DMIC0"},
1630 {"TX SMIC MUX6", "SWR_DMIC1", "TX SWR_DMIC1"},
1631 {"TX SMIC MUX6", "SWR_DMIC2", "TX SWR_DMIC2"},
1632 {"TX SMIC MUX6", "SWR_DMIC3", "TX SWR_DMIC3"},
1633 {"TX SMIC MUX6", "SWR_DMIC4", "TX SWR_DMIC4"},
1634 {"TX SMIC MUX6", "SWR_DMIC5", "TX SWR_DMIC5"},
1635 {"TX SMIC MUX6", "SWR_DMIC6", "TX SWR_DMIC6"},
1636 {"TX SMIC MUX6", "SWR_DMIC7", "TX SWR_DMIC7"},
1637
1638 {"TX DEC7 MUX", "MSM_DMIC", "TX DMIC MUX7"},
1639 {"TX DMIC MUX7", "DMIC0", "TX DMIC0"},
1640 {"TX DMIC MUX7", "DMIC1", "TX DMIC1"},
1641 {"TX DMIC MUX7", "DMIC2", "TX DMIC2"},
1642 {"TX DMIC MUX7", "DMIC3", "TX DMIC3"},
1643 {"TX DMIC MUX7", "DMIC4", "TX DMIC4"},
1644 {"TX DMIC MUX7", "DMIC5", "TX DMIC5"},
1645 {"TX DMIC MUX7", "DMIC6", "TX DMIC6"},
1646 {"TX DMIC MUX7", "DMIC7", "TX DMIC7"},
1647
1648 {"TX DEC7 MUX", "SWR_MIC", "TX SMIC MUX7"},
Sudheer Papothie456c2c2019-03-05 07:08:45 +05301649 {"TX SMIC MUX7", NULL, "TX_SWR_CLK"},
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301650 {"TX SMIC MUX7", "ADC0", "TX SWR_ADC0"},
1651 {"TX SMIC MUX7", "ADC1", "TX SWR_ADC1"},
1652 {"TX SMIC MUX7", "ADC2", "TX SWR_ADC2"},
1653 {"TX SMIC MUX7", "ADC3", "TX SWR_ADC3"},
1654 {"TX SMIC MUX7", "SWR_DMIC0", "TX SWR_DMIC0"},
1655 {"TX SMIC MUX7", "SWR_DMIC1", "TX SWR_DMIC1"},
1656 {"TX SMIC MUX7", "SWR_DMIC2", "TX SWR_DMIC2"},
1657 {"TX SMIC MUX7", "SWR_DMIC3", "TX SWR_DMIC3"},
1658 {"TX SMIC MUX7", "SWR_DMIC4", "TX SWR_DMIC4"},
1659 {"TX SMIC MUX7", "SWR_DMIC5", "TX SWR_DMIC5"},
1660 {"TX SMIC MUX7", "SWR_DMIC6", "TX SWR_DMIC6"},
1661 {"TX SMIC MUX7", "SWR_DMIC7", "TX SWR_DMIC7"},
1662};
1663
1664static const struct snd_kcontrol_new tx_macro_snd_controls[] = {
1665 SOC_SINGLE_SX_TLV("TX_DEC0 Volume",
1666 BOLERO_CDC_TX0_TX_VOL_CTL,
1667 0, -84, 40, digital_gain),
1668 SOC_SINGLE_SX_TLV("TX_DEC1 Volume",
1669 BOLERO_CDC_TX1_TX_VOL_CTL,
1670 0, -84, 40, digital_gain),
1671 SOC_SINGLE_SX_TLV("TX_DEC2 Volume",
1672 BOLERO_CDC_TX2_TX_VOL_CTL,
1673 0, -84, 40, digital_gain),
1674 SOC_SINGLE_SX_TLV("TX_DEC3 Volume",
1675 BOLERO_CDC_TX3_TX_VOL_CTL,
1676 0, -84, 40, digital_gain),
1677 SOC_SINGLE_SX_TLV("TX_DEC4 Volume",
1678 BOLERO_CDC_TX4_TX_VOL_CTL,
1679 0, -84, 40, digital_gain),
1680 SOC_SINGLE_SX_TLV("TX_DEC5 Volume",
1681 BOLERO_CDC_TX5_TX_VOL_CTL,
1682 0, -84, 40, digital_gain),
1683 SOC_SINGLE_SX_TLV("TX_DEC6 Volume",
1684 BOLERO_CDC_TX6_TX_VOL_CTL,
1685 0, -84, 40, digital_gain),
1686 SOC_SINGLE_SX_TLV("TX_DEC7 Volume",
1687 BOLERO_CDC_TX7_TX_VOL_CTL,
1688 0, -84, 40, digital_gain),
Karthikeyan Mani765eaab2019-07-18 16:27:01 -07001689
Karthikeyan Mani1dcd5a32019-08-22 14:37:13 -07001690 SOC_ENUM_EXT("DEC0 MODE", dec_mode_mux_enum,
1691 tx_macro_dec_mode_get, tx_macro_dec_mode_put),
1692
1693 SOC_ENUM_EXT("DEC1 MODE", dec_mode_mux_enum,
1694 tx_macro_dec_mode_get, tx_macro_dec_mode_put),
1695
1696 SOC_ENUM_EXT("DEC2 MODE", dec_mode_mux_enum,
1697 tx_macro_dec_mode_get, tx_macro_dec_mode_put),
1698
1699 SOC_ENUM_EXT("DEC3 MODE", dec_mode_mux_enum,
1700 tx_macro_dec_mode_get, tx_macro_dec_mode_put),
1701
1702 SOC_ENUM_EXT("DEC4 MODE", dec_mode_mux_enum,
1703 tx_macro_dec_mode_get, tx_macro_dec_mode_put),
1704
1705 SOC_ENUM_EXT("DEC5 MODE", dec_mode_mux_enum,
1706 tx_macro_dec_mode_get, tx_macro_dec_mode_put),
1707
1708 SOC_ENUM_EXT("DEC6 MODE", dec_mode_mux_enum,
1709 tx_macro_dec_mode_get, tx_macro_dec_mode_put),
1710
1711 SOC_ENUM_EXT("DEC7 MODE", dec_mode_mux_enum,
1712 tx_macro_dec_mode_get, tx_macro_dec_mode_put),
1713
Karthikeyan Mani765eaab2019-07-18 16:27:01 -07001714 SOC_SINGLE_EXT("DEC0_BCS Switch", SND_SOC_NOPM, 0, 1, 0,
1715 tx_macro_get_bcs, tx_macro_set_bcs),
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301716};
1717
Sudheer Papothia7397942019-03-19 03:14:23 +05301718static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv,
1719 struct regmap *regmap, int clk_type,
1720 bool enable)
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301721{
Meng Wang69b55c82019-05-29 11:04:29 +08001722 int ret = 0, clk_tx_ret = 0;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301723
Sudheer Papothi7601cc62019-03-30 03:00:52 +05301724 dev_dbg(tx_priv->dev,
1725 "%s: clock type %s, enable: %s tx_mclk_users: %d\n",
Sudheer Papothia7397942019-03-19 03:14:23 +05301726 __func__, (clk_type ? "VA_MCLK" : "TX_MCLK"),
Sudheer Papothi7601cc62019-03-30 03:00:52 +05301727 (enable ? "enable" : "disable"), tx_priv->tx_mclk_users);
Tanya Dixit8530fb92018-09-14 16:01:25 +05301728
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301729 if (enable) {
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07001730 if (tx_priv->swr_clk_users == 0) {
1731 ret = msm_cdc_pinctrl_select_active_state(
Karthikeyan Mani01f1ba42019-02-26 18:48:15 -08001732 tx_priv->tx_swr_gpio_p);
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07001733 if (ret < 0) {
1734 dev_err_ratelimited(tx_priv->dev,
1735 "%s: tx swr pinctrl enable failed\n",
1736 __func__);
1737 goto exit;
1738 }
1739 }
Sudheer Papothia7397942019-03-19 03:14:23 +05301740
Meng Wang69b55c82019-05-29 11:04:29 +08001741 clk_tx_ret = bolero_clk_rsc_request_clock(tx_priv->dev,
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301742 TX_CORE_CLK,
1743 TX_CORE_CLK,
1744 true);
1745 if (clk_type == TX_MCLK) {
1746 ret = tx_macro_mclk_enable(tx_priv, 1);
1747 if (ret < 0) {
1748 if (tx_priv->swr_clk_users == 0)
1749 msm_cdc_pinctrl_select_sleep_state(
1750 tx_priv->tx_swr_gpio_p);
1751 dev_err_ratelimited(tx_priv->dev,
1752 "%s: request clock enable failed\n",
1753 __func__);
1754 goto done;
1755 }
1756 }
1757 if (clk_type == VA_MCLK) {
Sudheer Papothia7397942019-03-19 03:14:23 +05301758 ret = bolero_clk_rsc_request_clock(tx_priv->dev,
1759 TX_CORE_CLK,
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301760 VA_CORE_CLK,
Sudheer Papothia7397942019-03-19 03:14:23 +05301761 true);
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301762 if (ret < 0) {
1763 if (tx_priv->swr_clk_users == 0)
Sudheer Papothia7397942019-03-19 03:14:23 +05301764 msm_cdc_pinctrl_select_sleep_state(
1765 tx_priv->tx_swr_gpio_p);
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301766 dev_err_ratelimited(tx_priv->dev,
1767 "%s: swr request clk failed\n",
1768 __func__);
1769 goto done;
Sudheer Papothia7397942019-03-19 03:14:23 +05301770 }
Sudheer Papothi296867b2019-06-20 09:24:09 +05301771 bolero_clk_rsc_fs_gen_request(tx_priv->dev,
1772 true);
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301773 if (tx_priv->tx_mclk_users == 0) {
1774 regmap_update_bits(regmap,
1775 BOLERO_CDC_TX_TOP_CSR_FREQ_MCLK,
1776 0x01, 0x01);
1777 regmap_update_bits(regmap,
1778 BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL,
1779 0x01, 0x01);
1780 regmap_update_bits(regmap,
1781 BOLERO_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL,
1782 0x01, 0x01);
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301783 }
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301784 }
1785 if (tx_priv->swr_clk_users == 0) {
Sudheer Papothi7601cc62019-03-30 03:00:52 +05301786 dev_dbg(tx_priv->dev, "%s: reset_swr: %d\n",
1787 __func__, tx_priv->reset_swr);
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05301788 if (tx_priv->reset_swr)
1789 regmap_update_bits(regmap,
1790 BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL,
1791 0x02, 0x02);
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301792 regmap_update_bits(regmap,
1793 BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL,
1794 0x01, 0x01);
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05301795 if (tx_priv->reset_swr)
1796 regmap_update_bits(regmap,
1797 BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL,
1798 0x02, 0x00);
1799 tx_priv->reset_swr = false;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301800 }
Meng Wang69b55c82019-05-29 11:04:29 +08001801 if (!clk_tx_ret)
1802 ret = bolero_clk_rsc_request_clock(tx_priv->dev,
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301803 TX_CORE_CLK,
1804 TX_CORE_CLK,
1805 false);
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301806 tx_priv->swr_clk_users++;
1807 } else {
1808 if (tx_priv->swr_clk_users <= 0) {
Sudheer Papothia7397942019-03-19 03:14:23 +05301809 dev_err_ratelimited(tx_priv->dev,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301810 "tx swrm clock users already 0\n");
1811 tx_priv->swr_clk_users = 0;
Sudheer Papothia7397942019-03-19 03:14:23 +05301812 return 0;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301813 }
Meng Wang69b55c82019-05-29 11:04:29 +08001814 clk_tx_ret = bolero_clk_rsc_request_clock(tx_priv->dev,
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301815 TX_CORE_CLK,
1816 TX_CORE_CLK,
1817 true);
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301818 tx_priv->swr_clk_users--;
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301819 if (tx_priv->swr_clk_users == 0)
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301820 regmap_update_bits(regmap,
1821 BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL,
1822 0x01, 0x00);
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301823 if (clk_type == TX_MCLK)
1824 tx_macro_mclk_enable(tx_priv, 0);
1825 if (clk_type == VA_MCLK) {
1826 if (tx_priv->tx_mclk_users == 0) {
1827 regmap_update_bits(regmap,
1828 BOLERO_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL,
1829 0x01, 0x00);
1830 regmap_update_bits(regmap,
1831 BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL,
1832 0x01, 0x00);
Sudheer Papothia7397942019-03-19 03:14:23 +05301833 }
Sudheer Papothi296867b2019-06-20 09:24:09 +05301834 bolero_clk_rsc_fs_gen_request(tx_priv->dev,
1835 false);
Sudheer Papothia7397942019-03-19 03:14:23 +05301836 ret = bolero_clk_rsc_request_clock(tx_priv->dev,
1837 TX_CORE_CLK,
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301838 VA_CORE_CLK,
Sudheer Papothia7397942019-03-19 03:14:23 +05301839 false);
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301840 if (ret < 0) {
1841 dev_err_ratelimited(tx_priv->dev,
1842 "%s: swr request clk failed\n",
1843 __func__);
1844 goto done;
1845 }
1846 }
Meng Wang69b55c82019-05-29 11:04:29 +08001847 if (!clk_tx_ret)
1848 ret = bolero_clk_rsc_request_clock(tx_priv->dev,
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301849 TX_CORE_CLK,
1850 TX_CORE_CLK,
1851 false);
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07001852 if (tx_priv->swr_clk_users == 0) {
1853 ret = msm_cdc_pinctrl_select_sleep_state(
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301854 tx_priv->tx_swr_gpio_p);
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07001855 if (ret < 0) {
1856 dev_err_ratelimited(tx_priv->dev,
1857 "%s: tx swr pinctrl disable failed\n",
1858 __func__);
1859 goto exit;
1860 }
1861 }
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301862 }
Sudheer Papothia7397942019-03-19 03:14:23 +05301863 return 0;
1864
1865done:
Meng Wang69b55c82019-05-29 11:04:29 +08001866 if (!clk_tx_ret)
1867 bolero_clk_rsc_request_clock(tx_priv->dev,
Sudheer Papothia7397942019-03-19 03:14:23 +05301868 TX_CORE_CLK,
1869 TX_CORE_CLK,
1870 false);
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07001871exit:
Sudheer Papothia7397942019-03-19 03:14:23 +05301872 return ret;
1873}
1874
Sudheer Papothi6cc7f522019-06-28 11:04:03 +05301875static int tx_macro_clk_switch(struct snd_soc_component *component)
1876{
1877 struct device *tx_dev = NULL;
1878 struct tx_macro_priv *tx_priv = NULL;
1879 int ret = 0;
1880
1881 if (!component)
1882 return -EINVAL;
1883
1884 tx_dev = bolero_get_device_ptr(component->dev, TX_MACRO);
1885 if (!tx_dev) {
1886 dev_err(component->dev,
1887 "%s: null device for macro!\n", __func__);
1888 return -EINVAL;
1889 }
1890 tx_priv = dev_get_drvdata(tx_dev);
1891 if (!tx_priv) {
1892 dev_err(component->dev,
1893 "%s: priv is null for macro!\n", __func__);
1894 return -EINVAL;
1895 }
1896 if (tx_priv->swr_ctrl_data) {
1897 ret = swrm_wcd_notify(
1898 tx_priv->swr_ctrl_data[0].tx_swr_pdev,
1899 SWR_REQ_CLK_SWITCH, NULL);
1900 }
1901
1902 return ret;
1903}
1904
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07001905static int tx_macro_core_vote(void *handle, bool enable)
1906{
1907 struct tx_macro_priv *tx_priv = (struct tx_macro_priv *) handle;
1908 int ret = 0;
1909
1910 if (tx_priv == NULL) {
1911 pr_err("%s: tx priv data is NULL\n", __func__);
1912 return -EINVAL;
1913 }
1914 if (enable) {
1915 pm_runtime_get_sync(tx_priv->dev);
1916 pm_runtime_put_autosuspend(tx_priv->dev);
1917 pm_runtime_mark_last_busy(tx_priv->dev);
1918 }
1919
1920 return ret;
1921}
1922
Sudheer Papothia7397942019-03-19 03:14:23 +05301923static int tx_macro_swrm_clock(void *handle, bool enable)
1924{
1925 struct tx_macro_priv *tx_priv = (struct tx_macro_priv *) handle;
1926 struct regmap *regmap = dev_get_regmap(tx_priv->dev->parent, NULL);
1927 int ret = 0;
1928
1929 if (regmap == NULL) {
1930 dev_err(tx_priv->dev, "%s: regmap is NULL\n", __func__);
1931 return -EINVAL;
1932 }
1933
1934 mutex_lock(&tx_priv->swr_clk_lock);
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301935 dev_dbg(tx_priv->dev,
1936 "%s: swrm clock %s tx_swr_clk_cnt: %d va_swr_clk_cnt: %d\n",
1937 __func__, (enable ? "enable" : "disable"),
1938 tx_priv->tx_swr_clk_cnt, tx_priv->va_swr_clk_cnt);
Sudheer Papothia7397942019-03-19 03:14:23 +05301939
1940 if (enable) {
Sudheer Papothi7601cc62019-03-30 03:00:52 +05301941 pm_runtime_get_sync(tx_priv->dev);
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301942 if (tx_priv->va_swr_clk_cnt && !tx_priv->tx_swr_clk_cnt) {
Sudheer Papothia7397942019-03-19 03:14:23 +05301943 ret = tx_macro_tx_va_mclk_enable(tx_priv, regmap,
1944 VA_MCLK, enable);
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07001945 if (ret) {
1946 pm_runtime_mark_last_busy(tx_priv->dev);
1947 pm_runtime_put_autosuspend(tx_priv->dev);
Sudheer Papothia7397942019-03-19 03:14:23 +05301948 goto done;
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07001949 }
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301950 tx_priv->va_clk_status++;
Sudheer Papothia7397942019-03-19 03:14:23 +05301951 } else {
Sudheer Papothia7397942019-03-19 03:14:23 +05301952 ret = tx_macro_tx_va_mclk_enable(tx_priv, regmap,
1953 TX_MCLK, enable);
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07001954 if (ret) {
1955 pm_runtime_mark_last_busy(tx_priv->dev);
1956 pm_runtime_put_autosuspend(tx_priv->dev);
Sudheer Papothia7397942019-03-19 03:14:23 +05301957 goto done;
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07001958 }
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301959 tx_priv->tx_clk_status++;
Sudheer Papothia7397942019-03-19 03:14:23 +05301960 }
Sudheer Papothi7601cc62019-03-30 03:00:52 +05301961 pm_runtime_mark_last_busy(tx_priv->dev);
1962 pm_runtime_put_autosuspend(tx_priv->dev);
Sudheer Papothia7397942019-03-19 03:14:23 +05301963 } else {
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301964 if (tx_priv->va_clk_status && !tx_priv->tx_clk_status) {
Sudheer Papothia7397942019-03-19 03:14:23 +05301965 ret = tx_macro_tx_va_mclk_enable(tx_priv, regmap,
1966 VA_MCLK, enable);
1967 if (ret)
1968 goto done;
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301969 --tx_priv->va_clk_status;
1970 } else if (!tx_priv->va_clk_status && tx_priv->tx_clk_status) {
Sudheer Papothia7397942019-03-19 03:14:23 +05301971 ret = tx_macro_tx_va_mclk_enable(tx_priv, regmap,
1972 TX_MCLK, enable);
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301973 if (ret)
1974 goto done;
1975 --tx_priv->tx_clk_status;
1976 } else if (tx_priv->va_clk_status && tx_priv->tx_clk_status) {
1977 if (!tx_priv->va_swr_clk_cnt && tx_priv->tx_swr_clk_cnt) {
1978 ret = tx_macro_tx_va_mclk_enable(tx_priv, regmap,
1979 VA_MCLK, enable);
Sudheer Papothia7397942019-03-19 03:14:23 +05301980 if (ret)
1981 goto done;
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301982 --tx_priv->va_clk_status;
1983 } else {
1984 ret = tx_macro_tx_va_mclk_enable(tx_priv, regmap,
1985 TX_MCLK, enable);
1986 if (ret)
1987 goto done;
1988 --tx_priv->tx_clk_status;
Sudheer Papothia7397942019-03-19 03:14:23 +05301989 }
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301990
1991 } else {
1992 dev_dbg(tx_priv->dev,
1993 "%s: Both clocks are disabled\n", __func__);
Sudheer Papothia7397942019-03-19 03:14:23 +05301994 }
1995 }
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301996
1997 dev_dbg(tx_priv->dev,
1998 "%s: swrm clock users %d tx_clk_sts_cnt: %d va_clk_sts_cnt: %d\n",
1999 __func__, tx_priv->swr_clk_users, tx_priv->tx_clk_status,
2000 tx_priv->va_clk_status);
Sudheer Papothia7397942019-03-19 03:14:23 +05302001done:
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302002 mutex_unlock(&tx_priv->swr_clk_lock);
2003 return ret;
2004}
2005
2006static int tx_macro_validate_dmic_sample_rate(u32 dmic_sample_rate,
2007 struct tx_macro_priv *tx_priv)
2008{
2009 u32 div_factor = TX_MACRO_CLK_DIV_2;
2010 u32 mclk_rate = TX_MACRO_MCLK_FREQ;
2011
2012 if (dmic_sample_rate == TX_MACRO_DMIC_SAMPLE_RATE_UNDEFINED ||
2013 mclk_rate % dmic_sample_rate != 0)
2014 goto undefined_rate;
2015
2016 div_factor = mclk_rate / dmic_sample_rate;
2017
2018 switch (div_factor) {
2019 case 2:
2020 tx_priv->dmic_clk_div = TX_MACRO_CLK_DIV_2;
2021 break;
2022 case 3:
2023 tx_priv->dmic_clk_div = TX_MACRO_CLK_DIV_3;
2024 break;
2025 case 4:
2026 tx_priv->dmic_clk_div = TX_MACRO_CLK_DIV_4;
2027 break;
2028 case 6:
2029 tx_priv->dmic_clk_div = TX_MACRO_CLK_DIV_6;
2030 break;
2031 case 8:
2032 tx_priv->dmic_clk_div = TX_MACRO_CLK_DIV_8;
2033 break;
2034 case 16:
2035 tx_priv->dmic_clk_div = TX_MACRO_CLK_DIV_16;
2036 break;
2037 default:
2038 /* Any other DIV factor is invalid */
2039 goto undefined_rate;
2040 }
2041
2042 /* Valid dmic DIV factors */
2043 dev_dbg(tx_priv->dev, "%s: DMIC_DIV = %u, mclk_rate = %u\n",
2044 __func__, div_factor, mclk_rate);
2045
2046 return dmic_sample_rate;
2047
2048undefined_rate:
2049 dev_dbg(tx_priv->dev, "%s: Invalid rate %d, for mclk %d\n",
2050 __func__, dmic_sample_rate, mclk_rate);
2051 dmic_sample_rate = TX_MACRO_DMIC_SAMPLE_RATE_UNDEFINED;
2052
2053 return dmic_sample_rate;
2054}
2055
Meng Wang15c825d2018-09-06 10:49:18 +08002056static int tx_macro_init(struct snd_soc_component *component)
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302057{
Meng Wang15c825d2018-09-06 10:49:18 +08002058 struct snd_soc_dapm_context *dapm =
2059 snd_soc_component_get_dapm(component);
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302060 int ret = 0, i = 0;
2061 struct device *tx_dev = NULL;
2062 struct tx_macro_priv *tx_priv = NULL;
2063
Meng Wang15c825d2018-09-06 10:49:18 +08002064 tx_dev = bolero_get_device_ptr(component->dev, TX_MACRO);
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302065 if (!tx_dev) {
Meng Wang15c825d2018-09-06 10:49:18 +08002066 dev_err(component->dev,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302067 "%s: null device for macro!\n", __func__);
2068 return -EINVAL;
2069 }
2070 tx_priv = dev_get_drvdata(tx_dev);
2071 if (!tx_priv) {
Meng Wang15c825d2018-09-06 10:49:18 +08002072 dev_err(component->dev,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302073 "%s: priv is null for macro!\n", __func__);
2074 return -EINVAL;
2075 }
2076 ret = snd_soc_dapm_new_controls(dapm, tx_macro_dapm_widgets,
2077 ARRAY_SIZE(tx_macro_dapm_widgets));
2078 if (ret < 0) {
2079 dev_err(tx_dev, "%s: Failed to add controls\n", __func__);
2080 return ret;
2081 }
2082
2083 ret = snd_soc_dapm_add_routes(dapm, tx_audio_map,
2084 ARRAY_SIZE(tx_audio_map));
2085 if (ret < 0) {
2086 dev_err(tx_dev, "%s: Failed to add routes\n", __func__);
2087 return ret;
2088 }
2089
2090 ret = snd_soc_dapm_new_widgets(dapm->card);
2091 if (ret < 0) {
2092 dev_err(tx_dev, "%s: Failed to add widgets\n", __func__);
2093 return ret;
2094 }
2095
Meng Wang15c825d2018-09-06 10:49:18 +08002096 ret = snd_soc_add_component_controls(component, tx_macro_snd_controls,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302097 ARRAY_SIZE(tx_macro_snd_controls));
2098 if (ret < 0) {
2099 dev_err(tx_dev, "%s: Failed to add snd_ctls\n", __func__);
2100 return ret;
2101 }
Laxminath Kasam638b5602018-09-24 13:19:52 +05302102
2103 snd_soc_dapm_ignore_suspend(dapm, "TX_AIF1 Capture");
2104 snd_soc_dapm_ignore_suspend(dapm, "TX_AIF2 Capture");
Karthikeyan Manif3bb8182019-07-11 14:38:54 -07002105 snd_soc_dapm_ignore_suspend(dapm, "TX_AIF3 Capture");
Laxminath Kasam638b5602018-09-24 13:19:52 +05302106 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC0");
2107 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC1");
2108 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC2");
2109 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC3");
Vatsal Bucha39ead2c2018-12-14 12:22:46 +05302110 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC0");
2111 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC1");
2112 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC2");
2113 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC3");
2114 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC4");
2115 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC5");
2116 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC6");
2117 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC7");
Laxminath Kasam638b5602018-09-24 13:19:52 +05302118 snd_soc_dapm_sync(dapm);
2119
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302120 for (i = 0; i < NUM_DECIMATORS; i++) {
2121 tx_priv->tx_hpf_work[i].tx_priv = tx_priv;
2122 tx_priv->tx_hpf_work[i].decimator = i;
2123 INIT_DELAYED_WORK(&tx_priv->tx_hpf_work[i].dwork,
2124 tx_macro_tx_hpf_corner_freq_callback);
2125 }
2126
2127 for (i = 0; i < NUM_DECIMATORS; i++) {
2128 tx_priv->tx_mute_dwork[i].tx_priv = tx_priv;
2129 tx_priv->tx_mute_dwork[i].decimator = i;
2130 INIT_DELAYED_WORK(&tx_priv->tx_mute_dwork[i].dwork,
2131 tx_macro_mute_update_callback);
2132 }
Meng Wang15c825d2018-09-06 10:49:18 +08002133 tx_priv->component = component;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302134
Karthikeyan Mani765eaab2019-07-18 16:27:01 -07002135 snd_soc_component_update_bits(component,
2136 BOLERO_CDC_TX0_TX_PATH_SEC7, 0x3F, 0x0E);
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302137 return 0;
2138}
2139
Meng Wang15c825d2018-09-06 10:49:18 +08002140static int tx_macro_deinit(struct snd_soc_component *component)
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302141{
2142 struct device *tx_dev = NULL;
2143 struct tx_macro_priv *tx_priv = NULL;
2144
Meng Wang15c825d2018-09-06 10:49:18 +08002145 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302146 return -EINVAL;
2147
Meng Wang15c825d2018-09-06 10:49:18 +08002148 tx_priv->component = NULL;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302149 return 0;
2150}
2151
2152static void tx_macro_add_child_devices(struct work_struct *work)
2153{
2154 struct tx_macro_priv *tx_priv = NULL;
2155 struct platform_device *pdev = NULL;
2156 struct device_node *node = NULL;
2157 struct tx_macro_swr_ctrl_data *swr_ctrl_data = NULL, *temp = NULL;
2158 int ret = 0;
2159 u16 count = 0, ctrl_num = 0;
2160 struct tx_macro_swr_ctrl_platform_data *platdata = NULL;
2161 char plat_dev_name[TX_MACRO_SWR_STRING_LEN] = "";
2162 bool tx_swr_master_node = false;
2163
2164 tx_priv = container_of(work, struct tx_macro_priv,
2165 tx_macro_add_child_devices_work);
2166 if (!tx_priv) {
2167 pr_err("%s: Memory for tx_priv does not exist\n",
2168 __func__);
2169 return;
2170 }
2171
2172 if (!tx_priv->dev) {
2173 pr_err("%s: tx dev does not exist\n", __func__);
2174 return;
2175 }
2176
2177 if (!tx_priv->dev->of_node) {
2178 dev_err(tx_priv->dev,
2179 "%s: DT node for tx_priv does not exist\n", __func__);
2180 return;
2181 }
2182
2183 platdata = &tx_priv->swr_plat_data;
2184 tx_priv->child_count = 0;
2185
2186 for_each_available_child_of_node(tx_priv->dev->of_node, node) {
2187 tx_swr_master_node = false;
2188 if (strnstr(node->name, "tx_swr_master",
2189 strlen("tx_swr_master")) != NULL)
2190 tx_swr_master_node = true;
2191
2192 if (tx_swr_master_node)
2193 strlcpy(plat_dev_name, "tx_swr_ctrl",
2194 (TX_MACRO_SWR_STRING_LEN - 1));
2195 else
2196 strlcpy(plat_dev_name, node->name,
2197 (TX_MACRO_SWR_STRING_LEN - 1));
2198
2199 pdev = platform_device_alloc(plat_dev_name, -1);
2200 if (!pdev) {
2201 dev_err(tx_priv->dev, "%s: pdev memory alloc failed\n",
2202 __func__);
2203 ret = -ENOMEM;
2204 goto err;
2205 }
2206 pdev->dev.parent = tx_priv->dev;
2207 pdev->dev.of_node = node;
2208
2209 if (tx_swr_master_node) {
2210 ret = platform_device_add_data(pdev, platdata,
2211 sizeof(*platdata));
2212 if (ret) {
2213 dev_err(&pdev->dev,
2214 "%s: cannot add plat data ctrl:%d\n",
2215 __func__, ctrl_num);
2216 goto fail_pdev_add;
2217 }
2218 }
2219
2220 ret = platform_device_add(pdev);
2221 if (ret) {
2222 dev_err(&pdev->dev,
2223 "%s: Cannot add platform device\n",
2224 __func__);
2225 goto fail_pdev_add;
2226 }
2227
2228 if (tx_swr_master_node) {
2229 temp = krealloc(swr_ctrl_data,
2230 (ctrl_num + 1) * sizeof(
2231 struct tx_macro_swr_ctrl_data),
2232 GFP_KERNEL);
2233 if (!temp) {
2234 ret = -ENOMEM;
2235 goto fail_pdev_add;
2236 }
2237 swr_ctrl_data = temp;
2238 swr_ctrl_data[ctrl_num].tx_swr_pdev = pdev;
2239 ctrl_num++;
2240 dev_dbg(&pdev->dev,
2241 "%s: Added soundwire ctrl device(s)\n",
2242 __func__);
2243 tx_priv->swr_ctrl_data = swr_ctrl_data;
2244 }
2245 if (tx_priv->child_count < TX_MACRO_CHILD_DEVICES_MAX)
2246 tx_priv->pdev_child_devices[
2247 tx_priv->child_count++] = pdev;
2248 else
2249 goto err;
2250 }
2251 return;
2252fail_pdev_add:
2253 for (count = 0; count < tx_priv->child_count; count++)
2254 platform_device_put(tx_priv->pdev_child_devices[count]);
2255err:
2256 return;
2257}
2258
Sudheer Papothia3e969d2018-10-27 06:22:10 +05302259static int tx_macro_set_port_map(struct snd_soc_component *component,
2260 u32 usecase, u32 size, void *data)
2261{
2262 struct device *tx_dev = NULL;
2263 struct tx_macro_priv *tx_priv = NULL;
2264 struct swrm_port_config port_cfg;
2265 int ret = 0;
2266
2267 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
2268 return -EINVAL;
2269
2270 memset(&port_cfg, 0, sizeof(port_cfg));
2271 port_cfg.uc = usecase;
2272 port_cfg.size = size;
2273 port_cfg.params = data;
2274
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07002275 if (tx_priv->swr_ctrl_data)
2276 ret = swrm_wcd_notify(
2277 tx_priv->swr_ctrl_data[0].tx_swr_pdev,
2278 SWR_SET_PORT_MAP, &port_cfg);
Sudheer Papothia3e969d2018-10-27 06:22:10 +05302279
2280 return ret;
2281}
2282
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302283static void tx_macro_init_ops(struct macro_ops *ops,
2284 char __iomem *tx_io_base)
2285{
2286 memset(ops, 0, sizeof(struct macro_ops));
2287 ops->init = tx_macro_init;
2288 ops->exit = tx_macro_deinit;
2289 ops->io_base = tx_io_base;
2290 ops->dai_ptr = tx_macro_dai;
2291 ops->num_dais = ARRAY_SIZE(tx_macro_dai);
Laxminath Kasamfb0d6832018-09-22 01:49:52 +05302292 ops->event_handler = tx_macro_event_handler;
Aditya Bavanaric4e96122018-11-14 14:46:38 +05302293 ops->reg_wake_irq = tx_macro_reg_wake_irq;
Sudheer Papothia3e969d2018-10-27 06:22:10 +05302294 ops->set_port_map = tx_macro_set_port_map;
Sudheer Papothi6cc7f522019-06-28 11:04:03 +05302295 ops->clk_switch = tx_macro_clk_switch;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302296}
2297
2298static int tx_macro_probe(struct platform_device *pdev)
2299{
2300 struct macro_ops ops = {0};
2301 struct tx_macro_priv *tx_priv = NULL;
2302 u32 tx_base_addr = 0, sample_rate = 0;
2303 char __iomem *tx_io_base = NULL;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302304 int ret = 0;
2305 const char *dmic_sample_rate = "qcom,tx-dmic-sample-rate";
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07002306 u32 is_used_tx_swr_gpio = 1;
2307 const char *is_used_tx_swr_gpio_dt = "qcom,is-used-swr-gpio";
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302308
2309 tx_priv = devm_kzalloc(&pdev->dev, sizeof(struct tx_macro_priv),
2310 GFP_KERNEL);
2311 if (!tx_priv)
2312 return -ENOMEM;
2313 platform_set_drvdata(pdev, tx_priv);
2314
2315 tx_priv->dev = &pdev->dev;
2316 ret = of_property_read_u32(pdev->dev.of_node, "reg",
2317 &tx_base_addr);
2318 if (ret) {
2319 dev_err(&pdev->dev, "%s: could not find %s entry in dt\n",
2320 __func__, "reg");
2321 return ret;
2322 }
2323 dev_set_drvdata(&pdev->dev, tx_priv);
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07002324 if (of_find_property(pdev->dev.of_node, is_used_tx_swr_gpio_dt,
2325 NULL)) {
2326 ret = of_property_read_u32(pdev->dev.of_node,
2327 is_used_tx_swr_gpio_dt,
2328 &is_used_tx_swr_gpio);
2329 if (ret) {
2330 dev_err(&pdev->dev, "%s: error reading %s in dt\n",
2331 __func__, is_used_tx_swr_gpio_dt);
2332 is_used_tx_swr_gpio = 1;
2333 }
2334 }
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302335 tx_priv->tx_swr_gpio_p = of_parse_phandle(pdev->dev.of_node,
2336 "qcom,tx-swr-gpios", 0);
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07002337 if (!tx_priv->tx_swr_gpio_p && is_used_tx_swr_gpio) {
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302338 dev_err(&pdev->dev, "%s: swr_gpios handle not provided!\n",
2339 __func__);
2340 return -EINVAL;
2341 }
Karthikeyan Mani326536d2019-06-03 13:29:43 -07002342 if (msm_cdc_pinctrl_get_state(tx_priv->tx_swr_gpio_p) < 0) {
2343 dev_err(&pdev->dev, "%s: failed to get swr pin state\n",
2344 __func__);
2345 return -EPROBE_DEFER;
2346 }
2347
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302348 tx_io_base = devm_ioremap(&pdev->dev,
2349 tx_base_addr, TX_MACRO_MAX_OFFSET);
2350 if (!tx_io_base) {
2351 dev_err(&pdev->dev, "%s: ioremap failed\n", __func__);
2352 return -ENOMEM;
2353 }
2354 tx_priv->tx_io_base = tx_io_base;
2355 ret = of_property_read_u32(pdev->dev.of_node, dmic_sample_rate,
2356 &sample_rate);
2357 if (ret) {
2358 dev_err(&pdev->dev,
2359 "%s: could not find sample_rate entry in dt\n",
2360 __func__);
2361 tx_priv->dmic_clk_div = TX_MACRO_CLK_DIV_2;
2362 } else {
2363 if (tx_macro_validate_dmic_sample_rate(
2364 sample_rate, tx_priv) == TX_MACRO_DMIC_SAMPLE_RATE_UNDEFINED)
2365 return -EINVAL;
2366 }
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05302367 tx_priv->reset_swr = true;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302368 INIT_WORK(&tx_priv->tx_macro_add_child_devices_work,
2369 tx_macro_add_child_devices);
2370 tx_priv->swr_plat_data.handle = (void *) tx_priv;
2371 tx_priv->swr_plat_data.read = NULL;
2372 tx_priv->swr_plat_data.write = NULL;
2373 tx_priv->swr_plat_data.bulk_write = NULL;
2374 tx_priv->swr_plat_data.clk = tx_macro_swrm_clock;
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07002375 tx_priv->swr_plat_data.core_vote = tx_macro_core_vote;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302376 tx_priv->swr_plat_data.handle_irq = NULL;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302377
2378 mutex_init(&tx_priv->mclk_lock);
2379 mutex_init(&tx_priv->swr_clk_lock);
2380 tx_macro_init_ops(&ops, tx_io_base);
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07002381 ops.clk_id_req = TX_CORE_CLK;
2382 ops.default_clk_id = TX_CORE_CLK;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302383 ret = bolero_register_macro(&pdev->dev, TX_MACRO, &ops);
2384 if (ret) {
2385 dev_err(&pdev->dev,
2386 "%s: register macro failed\n", __func__);
2387 goto err_reg_macro;
2388 }
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07002389
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302390 schedule_work(&tx_priv->tx_macro_add_child_devices_work);
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302391 pm_runtime_set_autosuspend_delay(&pdev->dev, AUTO_SUSPEND_DELAY);
2392 pm_runtime_use_autosuspend(&pdev->dev);
2393 pm_runtime_set_suspended(&pdev->dev);
Sudheer Papothi296867b2019-06-20 09:24:09 +05302394 pm_suspend_ignore_children(&pdev->dev, true);
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302395 pm_runtime_enable(&pdev->dev);
2396
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302397 return 0;
2398err_reg_macro:
2399 mutex_destroy(&tx_priv->mclk_lock);
2400 mutex_destroy(&tx_priv->swr_clk_lock);
2401 return ret;
2402}
2403
2404static int tx_macro_remove(struct platform_device *pdev)
2405{
2406 struct tx_macro_priv *tx_priv = NULL;
2407 u16 count = 0;
2408
2409 tx_priv = platform_get_drvdata(pdev);
2410
2411 if (!tx_priv)
2412 return -EINVAL;
2413
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07002414 if (tx_priv->swr_ctrl_data)
2415 kfree(tx_priv->swr_ctrl_data);
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302416 for (count = 0; count < tx_priv->child_count &&
2417 count < TX_MACRO_CHILD_DEVICES_MAX; count++)
2418 platform_device_unregister(tx_priv->pdev_child_devices[count]);
2419
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302420 pm_runtime_disable(&pdev->dev);
2421 pm_runtime_set_suspended(&pdev->dev);
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302422 mutex_destroy(&tx_priv->mclk_lock);
2423 mutex_destroy(&tx_priv->swr_clk_lock);
2424 bolero_unregister_macro(&pdev->dev, TX_MACRO);
2425 return 0;
2426}
2427
2428
2429static const struct of_device_id tx_macro_dt_match[] = {
2430 {.compatible = "qcom,tx-macro"},
2431 {}
2432};
2433
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302434static const struct dev_pm_ops bolero_dev_pm_ops = {
2435 SET_RUNTIME_PM_OPS(
2436 bolero_runtime_suspend,
2437 bolero_runtime_resume,
2438 NULL
2439 )
2440};
2441
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302442static struct platform_driver tx_macro_driver = {
2443 .driver = {
2444 .name = "tx_macro",
2445 .owner = THIS_MODULE,
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302446 .pm = &bolero_dev_pm_ops,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302447 .of_match_table = tx_macro_dt_match,
Xiaojun Sang53cd13a2018-06-29 15:14:37 +08002448 .suppress_bind_attrs = true,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302449 },
2450 .probe = tx_macro_probe,
2451 .remove = tx_macro_remove,
2452};
2453
2454module_platform_driver(tx_macro_driver);
2455
2456MODULE_DESCRIPTION("TX macro driver");
2457MODULE_LICENSE("GPL v2");