blob: 8c32043c479e889eb228f45029a61a2ba5b23d9d [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);
75 int (*handle_irq)(void *handle,
76 irqreturn_t (*swrm_irq_handler)(int irq,
77 void *data),
78 void *swrm_handle,
79 int action);
80};
81
82enum {
Laxminath Kasam59c7a1d2018-08-09 16:11:17 +053083 TX_MACRO_AIF_INVALID = 0,
84 TX_MACRO_AIF1_CAP,
Laxminath Kasam989fccf2018-06-15 16:53:31 +053085 TX_MACRO_AIF2_CAP,
Karthikeyan Manif3bb8182019-07-11 14:38:54 -070086 TX_MACRO_AIF3_CAP,
Laxminath Kasam989fccf2018-06-15 16:53:31 +053087 TX_MACRO_MAX_DAIS
88};
89
90enum {
91 TX_MACRO_DEC0,
92 TX_MACRO_DEC1,
93 TX_MACRO_DEC2,
94 TX_MACRO_DEC3,
95 TX_MACRO_DEC4,
96 TX_MACRO_DEC5,
97 TX_MACRO_DEC6,
98 TX_MACRO_DEC7,
99 TX_MACRO_DEC_MAX,
100};
101
102enum {
103 TX_MACRO_CLK_DIV_2,
104 TX_MACRO_CLK_DIV_3,
105 TX_MACRO_CLK_DIV_4,
106 TX_MACRO_CLK_DIV_6,
107 TX_MACRO_CLK_DIV_8,
108 TX_MACRO_CLK_DIV_16,
109};
110
Laxminath Kasam497a6512018-09-17 16:11:52 +0530111enum {
112 MSM_DMIC,
113 SWR_MIC,
114 ANC_FB_TUNE1
115};
116
Sudheer Papothia7397942019-03-19 03:14:23 +0530117enum {
118 TX_MCLK,
119 VA_MCLK,
120};
121
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530122struct tx_mute_work {
123 struct tx_macro_priv *tx_priv;
124 u32 decimator;
125 struct delayed_work dwork;
126};
127
128struct hpf_work {
129 struct tx_macro_priv *tx_priv;
130 u8 decimator;
131 u8 hpf_cut_off_freq;
132 struct delayed_work dwork;
133};
134
135struct tx_macro_priv {
136 struct device *dev;
137 bool dec_active[NUM_DECIMATORS];
138 int tx_mclk_users;
139 int swr_clk_users;
Ramprasad Katkam452772a2019-01-07 17:30:36 +0530140 bool dapm_mclk_enable;
Ramprasad Katkama4c747b2018-12-11 19:15:53 +0530141 bool reset_swr;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530142 struct mutex mclk_lock;
143 struct mutex swr_clk_lock;
Meng Wang15c825d2018-09-06 10:49:18 +0800144 struct snd_soc_component *component;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530145 struct device_node *tx_swr_gpio_p;
146 struct tx_macro_swr_ctrl_data *swr_ctrl_data;
147 struct tx_macro_swr_ctrl_platform_data swr_plat_data;
148 struct work_struct tx_macro_add_child_devices_work;
149 struct hpf_work tx_hpf_work[NUM_DECIMATORS];
150 struct tx_mute_work tx_mute_dwork[NUM_DECIMATORS];
151 s32 dmic_0_1_clk_cnt;
152 s32 dmic_2_3_clk_cnt;
153 s32 dmic_4_5_clk_cnt;
154 s32 dmic_6_7_clk_cnt;
155 u16 dmic_clk_div;
156 unsigned long active_ch_mask[TX_MACRO_MAX_DAIS];
157 unsigned long active_ch_cnt[TX_MACRO_MAX_DAIS];
158 char __iomem *tx_io_base;
159 struct platform_device *pdev_child_devices
160 [TX_MACRO_CHILD_DEVICES_MAX];
161 int child_count;
Sudheer Papothie456c2c2019-03-05 07:08:45 +0530162 int tx_swr_clk_cnt;
163 int va_swr_clk_cnt;
Sudheer Papothicf3b4062019-05-10 10:48:43 +0530164 int va_clk_status;
165 int tx_clk_status;
Karthikeyan Mani765eaab2019-07-18 16:27:01 -0700166 bool bcs_enable;
Karthikeyan Mani1dcd5a32019-08-22 14:37:13 -0700167 int dec_mode[NUM_DECIMATORS];
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530168};
169
Meng Wang15c825d2018-09-06 10:49:18 +0800170static bool tx_macro_get_data(struct snd_soc_component *component,
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530171 struct device **tx_dev,
172 struct tx_macro_priv **tx_priv,
173 const char *func_name)
174{
Meng Wang15c825d2018-09-06 10:49:18 +0800175 *tx_dev = bolero_get_device_ptr(component->dev, TX_MACRO);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530176 if (!(*tx_dev)) {
Meng Wang15c825d2018-09-06 10:49:18 +0800177 dev_err(component->dev,
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530178 "%s: null device for macro!\n", func_name);
179 return false;
180 }
181
182 *tx_priv = dev_get_drvdata((*tx_dev));
183 if (!(*tx_priv)) {
Meng Wang15c825d2018-09-06 10:49:18 +0800184 dev_err(component->dev,
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530185 "%s: priv is null for macro!\n", func_name);
186 return false;
187 }
188
Meng Wang15c825d2018-09-06 10:49:18 +0800189 if (!(*tx_priv)->component) {
190 dev_err(component->dev,
191 "%s: tx_priv->component not initialized!\n", func_name);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530192 return false;
193 }
194
195 return true;
196}
197
198static int tx_macro_mclk_enable(struct tx_macro_priv *tx_priv,
199 bool mclk_enable)
200{
201 struct regmap *regmap = dev_get_regmap(tx_priv->dev->parent, NULL);
202 int ret = 0;
203
Tanya Dixit8530fb92018-09-14 16:01:25 +0530204 if (regmap == NULL) {
205 dev_err(tx_priv->dev, "%s: regmap is NULL\n", __func__);
206 return -EINVAL;
207 }
208
Laxminath Kasamb7f823c2018-08-02 13:23:11 +0530209 dev_dbg(tx_priv->dev, "%s: mclk_enable = %u,clk_users= %d\n",
210 __func__, mclk_enable, tx_priv->tx_mclk_users);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530211
212 mutex_lock(&tx_priv->mclk_lock);
213 if (mclk_enable) {
214 if (tx_priv->tx_mclk_users == 0) {
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -0700215 ret = bolero_clk_rsc_request_clock(tx_priv->dev,
216 TX_CORE_CLK,
217 TX_CORE_CLK,
218 true);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530219 if (ret < 0) {
Ramprasad Katkam14efed62019-03-07 13:16:50 +0530220 dev_err_ratelimited(tx_priv->dev,
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530221 "%s: request clock enable failed\n",
222 __func__);
223 goto exit;
224 }
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -0700225 bolero_clk_rsc_fs_gen_request(tx_priv->dev,
226 true);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530227 regcache_mark_dirty(regmap);
228 regcache_sync_region(regmap,
229 TX_START_OFFSET,
230 TX_MAX_OFFSET);
231 /* 9.6MHz MCLK, set value 0x00 if other frequency */
232 regmap_update_bits(regmap,
233 BOLERO_CDC_TX_TOP_CSR_FREQ_MCLK, 0x01, 0x01);
234 regmap_update_bits(regmap,
235 BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL,
236 0x01, 0x01);
237 regmap_update_bits(regmap,
238 BOLERO_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL,
239 0x01, 0x01);
240 }
241 tx_priv->tx_mclk_users++;
242 } else {
243 if (tx_priv->tx_mclk_users <= 0) {
244 dev_err(tx_priv->dev, "%s: clock already disabled\n",
245 __func__);
246 tx_priv->tx_mclk_users = 0;
247 goto exit;
248 }
249 tx_priv->tx_mclk_users--;
250 if (tx_priv->tx_mclk_users == 0) {
251 regmap_update_bits(regmap,
252 BOLERO_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL,
253 0x01, 0x00);
254 regmap_update_bits(regmap,
255 BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL,
256 0x01, 0x00);
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -0700257 bolero_clk_rsc_fs_gen_request(tx_priv->dev,
258 false);
259
260 bolero_clk_rsc_request_clock(tx_priv->dev,
261 TX_CORE_CLK,
262 TX_CORE_CLK,
263 false);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530264 }
265 }
266exit:
267 mutex_unlock(&tx_priv->mclk_lock);
268 return ret;
269}
270
Sudheer Papothie456c2c2019-03-05 07:08:45 +0530271static int tx_macro_va_swr_clk_event(struct snd_soc_dapm_widget *w,
272 struct snd_kcontrol *kcontrol, int event)
273{
274 struct device *tx_dev = NULL;
275 struct tx_macro_priv *tx_priv = NULL;
276 struct snd_soc_component *component =
277 snd_soc_dapm_to_component(w->dapm);
278
279 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
280 return -EINVAL;
281
282 if (SND_SOC_DAPM_EVENT_ON(event))
283 ++tx_priv->va_swr_clk_cnt;
284 if (SND_SOC_DAPM_EVENT_OFF(event))
285 --tx_priv->va_swr_clk_cnt;
286
287 return 0;
288}
289
290static int tx_macro_tx_swr_clk_event(struct snd_soc_dapm_widget *w,
291 struct snd_kcontrol *kcontrol, int event)
292{
293 struct device *tx_dev = NULL;
294 struct tx_macro_priv *tx_priv = NULL;
295 struct snd_soc_component *component =
296 snd_soc_dapm_to_component(w->dapm);
297
298 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
299 return -EINVAL;
300
301 if (SND_SOC_DAPM_EVENT_ON(event))
302 ++tx_priv->tx_swr_clk_cnt;
303 if (SND_SOC_DAPM_EVENT_OFF(event))
304 --tx_priv->tx_swr_clk_cnt;
305
306 return 0;
307}
308
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530309static int tx_macro_mclk_event(struct snd_soc_dapm_widget *w,
310 struct snd_kcontrol *kcontrol, int event)
311{
Meng Wang15c825d2018-09-06 10:49:18 +0800312 struct snd_soc_component *component =
313 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530314 int ret = 0;
315 struct device *tx_dev = NULL;
316 struct tx_macro_priv *tx_priv = NULL;
317
Meng Wang15c825d2018-09-06 10:49:18 +0800318 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530319 return -EINVAL;
320
321 dev_dbg(tx_dev, "%s: event = %d\n", __func__, event);
322 switch (event) {
323 case SND_SOC_DAPM_PRE_PMU:
324 ret = tx_macro_mclk_enable(tx_priv, 1);
Ramprasad Katkam452772a2019-01-07 17:30:36 +0530325 if (ret)
326 tx_priv->dapm_mclk_enable = false;
327 else
328 tx_priv->dapm_mclk_enable = true;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530329 break;
330 case SND_SOC_DAPM_POST_PMD:
Ramprasad Katkam452772a2019-01-07 17:30:36 +0530331 if (tx_priv->dapm_mclk_enable)
332 ret = tx_macro_mclk_enable(tx_priv, 0);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530333 break;
334 default:
335 dev_err(tx_priv->dev,
336 "%s: invalid DAPM event %d\n", __func__, event);
337 ret = -EINVAL;
338 }
339 return ret;
340}
341
Meng Wang15c825d2018-09-06 10:49:18 +0800342static int tx_macro_event_handler(struct snd_soc_component *component,
343 u16 event, u32 data)
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530344{
345 struct device *tx_dev = NULL;
346 struct tx_macro_priv *tx_priv = NULL;
Aditya Bavanari50ef13e2019-08-09 15:14:43 +0530347 int ret = 0;
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530348
Meng Wang15c825d2018-09-06 10:49:18 +0800349 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530350 return -EINVAL;
351
352 switch (event) {
353 case BOLERO_MACRO_EVT_SSR_DOWN:
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -0700354 if (tx_priv->swr_ctrl_data) {
355 swrm_wcd_notify(
356 tx_priv->swr_ctrl_data[0].tx_swr_pdev,
357 SWR_DEVICE_DOWN, NULL);
358 swrm_wcd_notify(
359 tx_priv->swr_ctrl_data[0].tx_swr_pdev,
360 SWR_DEVICE_SSR_DOWN, NULL);
361 }
Aditya Bavanari50ef13e2019-08-09 15:14:43 +0530362 if ((!pm_runtime_enabled(tx_dev) ||
363 !pm_runtime_suspended(tx_dev))) {
364 ret = bolero_runtime_suspend(tx_dev);
365 if (!ret) {
366 pm_runtime_disable(tx_dev);
367 pm_runtime_set_suspended(tx_dev);
368 pm_runtime_enable(tx_dev);
369 }
370 }
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530371 break;
372 case BOLERO_MACRO_EVT_SSR_UP:
Ramprasad Katkama4c747b2018-12-11 19:15:53 +0530373 /* reset swr after ssr/pdr */
374 tx_priv->reset_swr = true;
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -0700375 if (tx_priv->swr_ctrl_data)
376 swrm_wcd_notify(
377 tx_priv->swr_ctrl_data[0].tx_swr_pdev,
378 SWR_DEVICE_SSR_UP, NULL);
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530379 break;
Meng Wang8ef0cc22019-05-08 15:12:56 +0800380 case BOLERO_MACRO_EVT_CLK_RESET:
381 bolero_rsc_clk_reset(tx_dev, TX_CORE_CLK);
382 break;
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530383 }
384 return 0;
385}
386
Meng Wang15c825d2018-09-06 10:49:18 +0800387static int tx_macro_reg_wake_irq(struct snd_soc_component *component,
Aditya Bavanaric4e96122018-11-14 14:46:38 +0530388 u32 data)
389{
390 struct device *tx_dev = NULL;
391 struct tx_macro_priv *tx_priv = NULL;
392 u32 ipc_wakeup = data;
393 int ret = 0;
394
Meng Wang15c825d2018-09-06 10:49:18 +0800395 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
Aditya Bavanaric4e96122018-11-14 14:46:38 +0530396 return -EINVAL;
397
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -0700398 if (tx_priv->swr_ctrl_data)
399 ret = swrm_wcd_notify(
400 tx_priv->swr_ctrl_data[0].tx_swr_pdev,
401 SWR_REGISTER_WAKE_IRQ, &ipc_wakeup);
Aditya Bavanaric4e96122018-11-14 14:46:38 +0530402
403 return ret;
404}
405
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530406static void tx_macro_tx_hpf_corner_freq_callback(struct work_struct *work)
407{
408 struct delayed_work *hpf_delayed_work = NULL;
409 struct hpf_work *hpf_work = NULL;
410 struct tx_macro_priv *tx_priv = NULL;
Meng Wang15c825d2018-09-06 10:49:18 +0800411 struct snd_soc_component *component = NULL;
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530412 u16 dec_cfg_reg = 0, hpf_gate_reg = 0;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530413 u8 hpf_cut_off_freq = 0;
Laxminath Kasam497a6512018-09-17 16:11:52 +0530414 u16 adc_mux_reg = 0, adc_n = 0, adc_reg = 0;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530415
416 hpf_delayed_work = to_delayed_work(work);
417 hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork);
418 tx_priv = hpf_work->tx_priv;
Meng Wang15c825d2018-09-06 10:49:18 +0800419 component = tx_priv->component;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530420 hpf_cut_off_freq = hpf_work->hpf_cut_off_freq;
421
422 dec_cfg_reg = BOLERO_CDC_TX0_TX_PATH_CFG0 +
423 TX_MACRO_TX_PATH_OFFSET * hpf_work->decimator;
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530424 hpf_gate_reg = BOLERO_CDC_TX0_TX_PATH_SEC2 +
425 TX_MACRO_TX_PATH_OFFSET * hpf_work->decimator;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530426
Meng Wang15c825d2018-09-06 10:49:18 +0800427 dev_dbg(component->dev, "%s: decimator %u hpf_cut_of_freq 0x%x\n",
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530428 __func__, hpf_work->decimator, hpf_cut_off_freq);
429
Laxminath Kasam497a6512018-09-17 16:11:52 +0530430 adc_mux_reg = BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG1 +
431 TX_MACRO_ADC_MUX_CFG_OFFSET * hpf_work->decimator;
Meng Wang15c825d2018-09-06 10:49:18 +0800432 if (snd_soc_component_read32(component, adc_mux_reg) & SWR_MIC) {
Laxminath Kasam497a6512018-09-17 16:11:52 +0530433 adc_reg = BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0 +
434 TX_MACRO_ADC_MUX_CFG_OFFSET * hpf_work->decimator;
Meng Wang15c825d2018-09-06 10:49:18 +0800435 adc_n = snd_soc_component_read32(component, adc_reg) &
Laxminath Kasam497a6512018-09-17 16:11:52 +0530436 TX_MACRO_SWR_MIC_MUX_SEL_MASK;
437 if (adc_n >= BOLERO_ADC_MAX)
438 goto tx_hpf_set;
439 /* analog mic clear TX hold */
Meng Wang15c825d2018-09-06 10:49:18 +0800440 bolero_clear_amic_tx_hold(component->dev, adc_n);
Laxminath Kasam497a6512018-09-17 16:11:52 +0530441 }
442tx_hpf_set:
Meng Wang15c825d2018-09-06 10:49:18 +0800443 snd_soc_component_update_bits(component,
444 dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK,
445 hpf_cut_off_freq << 5);
446 snd_soc_component_update_bits(component, hpf_gate_reg, 0x03, 0x02);
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530447 /* Minimum 1 clk cycle delay is required as per HW spec */
448 usleep_range(1000, 1010);
Meng Wang15c825d2018-09-06 10:49:18 +0800449 snd_soc_component_update_bits(component, hpf_gate_reg, 0x03, 0x01);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530450}
451
452static void tx_macro_mute_update_callback(struct work_struct *work)
453{
454 struct tx_mute_work *tx_mute_dwork = NULL;
Meng Wang15c825d2018-09-06 10:49:18 +0800455 struct snd_soc_component *component = NULL;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530456 struct tx_macro_priv *tx_priv = NULL;
457 struct delayed_work *delayed_work = NULL;
Xiaojun Sangd155fdc2018-10-11 15:11:59 +0800458 u16 tx_vol_ctl_reg = 0;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530459 u8 decimator = 0;
460
461 delayed_work = to_delayed_work(work);
462 tx_mute_dwork = container_of(delayed_work, struct tx_mute_work, dwork);
463 tx_priv = tx_mute_dwork->tx_priv;
Meng Wang15c825d2018-09-06 10:49:18 +0800464 component = tx_priv->component;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530465 decimator = tx_mute_dwork->decimator;
466
467 tx_vol_ctl_reg =
468 BOLERO_CDC_TX0_TX_PATH_CTL +
469 TX_MACRO_TX_PATH_OFFSET * decimator;
Meng Wang15c825d2018-09-06 10:49:18 +0800470 snd_soc_component_update_bits(component, tx_vol_ctl_reg, 0x10, 0x00);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530471 dev_dbg(tx_priv->dev, "%s: decimator %u unmute\n",
472 __func__, decimator);
473}
474
475static int tx_macro_put_dec_enum(struct snd_kcontrol *kcontrol,
476 struct snd_ctl_elem_value *ucontrol)
477{
478 struct snd_soc_dapm_widget *widget =
479 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +0800480 struct snd_soc_component *component =
481 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530482 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
483 unsigned int val = 0;
484 u16 mic_sel_reg = 0;
Laxminath Kasam549d11d2019-07-18 13:44:17 +0530485 u16 dmic_clk_reg = 0;
486 struct device *tx_dev = NULL;
487 struct tx_macro_priv *tx_priv = NULL;
488
489 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
490 return -EINVAL;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530491
492 val = ucontrol->value.enumerated.item[0];
493 if (val > e->items - 1)
494 return -EINVAL;
495
Meng Wang15c825d2018-09-06 10:49:18 +0800496 dev_dbg(component->dev, "%s: wname: %s, val: 0x%x\n", __func__,
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530497 widget->name, val);
498
499 switch (e->reg) {
500 case BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0:
501 mic_sel_reg = BOLERO_CDC_TX0_TX_PATH_CFG0;
502 break;
503 case BOLERO_CDC_TX_INP_MUX_ADC_MUX1_CFG0:
504 mic_sel_reg = BOLERO_CDC_TX1_TX_PATH_CFG0;
505 break;
506 case BOLERO_CDC_TX_INP_MUX_ADC_MUX2_CFG0:
507 mic_sel_reg = BOLERO_CDC_TX2_TX_PATH_CFG0;
508 break;
509 case BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG0:
510 mic_sel_reg = BOLERO_CDC_TX3_TX_PATH_CFG0;
511 break;
512 case BOLERO_CDC_TX_INP_MUX_ADC_MUX4_CFG0:
513 mic_sel_reg = BOLERO_CDC_TX4_TX_PATH_CFG0;
514 break;
515 case BOLERO_CDC_TX_INP_MUX_ADC_MUX5_CFG0:
516 mic_sel_reg = BOLERO_CDC_TX5_TX_PATH_CFG0;
517 break;
518 case BOLERO_CDC_TX_INP_MUX_ADC_MUX6_CFG0:
519 mic_sel_reg = BOLERO_CDC_TX6_TX_PATH_CFG0;
520 break;
521 case BOLERO_CDC_TX_INP_MUX_ADC_MUX7_CFG0:
522 mic_sel_reg = BOLERO_CDC_TX7_TX_PATH_CFG0;
523 break;
524 default:
Meng Wang15c825d2018-09-06 10:49:18 +0800525 dev_err(component->dev, "%s: e->reg: 0x%x not expected\n",
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530526 __func__, e->reg);
527 return -EINVAL;
528 }
Laxminath Kasam497a6512018-09-17 16:11:52 +0530529 if (strnstr(widget->name, "SMIC", strlen(widget->name))) {
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530530 if (val != 0) {
Laxminath Kasam549d11d2019-07-18 13:44:17 +0530531 if (val < 5) {
Meng Wang15c825d2018-09-06 10:49:18 +0800532 snd_soc_component_update_bits(component,
533 mic_sel_reg,
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530534 1 << 7, 0x0 << 7);
Laxminath Kasam549d11d2019-07-18 13:44:17 +0530535 } else {
Meng Wang15c825d2018-09-06 10:49:18 +0800536 snd_soc_component_update_bits(component,
537 mic_sel_reg,
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530538 1 << 7, 0x1 << 7);
Laxminath Kasam549d11d2019-07-18 13:44:17 +0530539 snd_soc_component_update_bits(component,
540 BOLERO_CDC_VA_TOP_CSR_DMIC_CFG,
541 0x80, 0x00);
542 dmic_clk_reg =
543 BOLERO_CDC_TX_TOP_CSR_SWR_DMIC0_CTL +
544 ((val - 5)/2) * 4;
545 snd_soc_component_update_bits(component,
546 dmic_clk_reg,
547 0x0E, tx_priv->dmic_clk_div << 0x1);
548 }
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530549 }
550 } else {
551 /* DMIC selected */
552 if (val != 0)
Meng Wang15c825d2018-09-06 10:49:18 +0800553 snd_soc_component_update_bits(component, mic_sel_reg,
554 1 << 7, 1 << 7);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530555 }
556
557 return snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
558}
559
560static int tx_macro_tx_mixer_get(struct snd_kcontrol *kcontrol,
561 struct snd_ctl_elem_value *ucontrol)
562{
563 struct snd_soc_dapm_widget *widget =
564 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +0800565 struct snd_soc_component *component =
566 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530567 struct soc_multi_mixer_control *mixer =
568 ((struct soc_multi_mixer_control *)kcontrol->private_value);
569 u32 dai_id = widget->shift;
570 u32 dec_id = mixer->shift;
571 struct device *tx_dev = NULL;
572 struct tx_macro_priv *tx_priv = NULL;
573
Meng Wang15c825d2018-09-06 10:49:18 +0800574 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530575 return -EINVAL;
576
577 if (test_bit(dec_id, &tx_priv->active_ch_mask[dai_id]))
578 ucontrol->value.integer.value[0] = 1;
579 else
580 ucontrol->value.integer.value[0] = 0;
581 return 0;
582}
583
584static int tx_macro_tx_mixer_put(struct snd_kcontrol *kcontrol,
585 struct snd_ctl_elem_value *ucontrol)
586{
587 struct snd_soc_dapm_widget *widget =
588 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +0800589 struct snd_soc_component *component =
590 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530591 struct snd_soc_dapm_update *update = NULL;
592 struct soc_multi_mixer_control *mixer =
593 ((struct soc_multi_mixer_control *)kcontrol->private_value);
594 u32 dai_id = widget->shift;
595 u32 dec_id = mixer->shift;
596 u32 enable = ucontrol->value.integer.value[0];
597 struct device *tx_dev = NULL;
598 struct tx_macro_priv *tx_priv = NULL;
599
Meng Wang15c825d2018-09-06 10:49:18 +0800600 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530601 return -EINVAL;
602
603 if (enable) {
604 set_bit(dec_id, &tx_priv->active_ch_mask[dai_id]);
605 tx_priv->active_ch_cnt[dai_id]++;
606 } else {
607 tx_priv->active_ch_cnt[dai_id]--;
608 clear_bit(dec_id, &tx_priv->active_ch_mask[dai_id]);
609 }
610 snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, update);
611
612 return 0;
613}
Karthikeyan Mani1dcd5a32019-08-22 14:37:13 -0700614
615static inline int tx_macro_path_get(const char *wname,
616 unsigned int *path_num)
617{
618 int ret = 0;
619 char *widget_name = NULL;
620 char *w_name = NULL;
621 char *path_num_char = NULL;
622 char *path_name = NULL;
623
624 widget_name = kstrndup(wname, 10, GFP_KERNEL);
625 if (!widget_name)
626 return -EINVAL;
627
628 w_name = widget_name;
629
630 path_name = strsep(&widget_name, " ");
631 if (!path_name) {
632 pr_err("%s: Invalid widget name = %s\n",
633 __func__, widget_name);
634 ret = -EINVAL;
635 goto err;
636 }
637 path_num_char = strpbrk(path_name, "01234567");
638 if (!path_num_char) {
639 pr_err("%s: tx path index not found\n",
640 __func__);
641 ret = -EINVAL;
642 goto err;
643 }
644 ret = kstrtouint(path_num_char, 10, path_num);
645 if (ret < 0)
646 pr_err("%s: Invalid tx path = %s\n",
647 __func__, w_name);
648
649err:
650 kfree(w_name);
651 return ret;
652}
653
654static int tx_macro_dec_mode_get(struct snd_kcontrol *kcontrol,
655 struct snd_ctl_elem_value *ucontrol)
656{
657 struct snd_soc_component *component =
658 snd_soc_kcontrol_component(kcontrol);
659 struct tx_macro_priv *tx_priv = NULL;
660 struct device *tx_dev = NULL;
661 int ret = 0;
662 int path = 0;
663
664 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
665 return -EINVAL;
666
667 ret = tx_macro_path_get(kcontrol->id.name, &path);
668 if (ret)
669 return ret;
670
671 ucontrol->value.integer.value[0] = tx_priv->dec_mode[path];
672
673 return 0;
674}
675
676static int tx_macro_dec_mode_put(struct snd_kcontrol *kcontrol,
677 struct snd_ctl_elem_value *ucontrol)
678{
679 struct snd_soc_component *component =
680 snd_soc_kcontrol_component(kcontrol);
681 struct tx_macro_priv *tx_priv = NULL;
682 struct device *tx_dev = NULL;
683 int value = ucontrol->value.integer.value[0];
684 int ret = 0;
685 int path = 0;
686
687 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
688 return -EINVAL;
689
690 ret = tx_macro_path_get(kcontrol->id.name, &path);
691 if (ret)
692 return ret;
693
694 tx_priv->dec_mode[path] = value;
695
696 return 0;
697}
698
Karthikeyan Mani765eaab2019-07-18 16:27:01 -0700699static int tx_macro_get_bcs(struct snd_kcontrol *kcontrol,
700 struct snd_ctl_elem_value *ucontrol)
701{
702 struct snd_soc_component *component =
703 snd_soc_kcontrol_component(kcontrol);
704 struct tx_macro_priv *tx_priv = NULL;
705 struct device *tx_dev = NULL;
706
707 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
708 return -EINVAL;
709
710 ucontrol->value.integer.value[0] = tx_priv->bcs_enable;
711
712 return 0;
713}
714
715static int tx_macro_set_bcs(struct snd_kcontrol *kcontrol,
716 struct snd_ctl_elem_value *ucontrol)
717{
718 struct snd_soc_component *component =
719 snd_soc_kcontrol_component(kcontrol);
720 struct tx_macro_priv *tx_priv = NULL;
721 struct device *tx_dev = NULL;
722 int value = ucontrol->value.integer.value[0];
723
724 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
725 return -EINVAL;
726
727 tx_priv->bcs_enable = value;
728
729 return 0;
730}
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530731
732static int tx_macro_enable_dmic(struct snd_soc_dapm_widget *w,
733 struct snd_kcontrol *kcontrol, int event)
734{
Meng Wang15c825d2018-09-06 10:49:18 +0800735 struct snd_soc_component *component =
736 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530737 u8 dmic_clk_en = 0x01;
738 u16 dmic_clk_reg = 0;
739 s32 *dmic_clk_cnt = NULL;
740 unsigned int dmic = 0;
741 int ret = 0;
742 char *wname = NULL;
743 struct device *tx_dev = NULL;
744 struct tx_macro_priv *tx_priv = NULL;
745
Meng Wang15c825d2018-09-06 10:49:18 +0800746 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530747 return -EINVAL;
748
749 wname = strpbrk(w->name, "01234567");
750 if (!wname) {
Meng Wang15c825d2018-09-06 10:49:18 +0800751 dev_err(component->dev, "%s: widget not found\n", __func__);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530752 return -EINVAL;
753 }
754
755 ret = kstrtouint(wname, 10, &dmic);
756 if (ret < 0) {
Meng Wang15c825d2018-09-06 10:49:18 +0800757 dev_err(component->dev, "%s: Invalid DMIC line on the codec\n",
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530758 __func__);
759 return -EINVAL;
760 }
761
762 switch (dmic) {
763 case 0:
764 case 1:
765 dmic_clk_cnt = &(tx_priv->dmic_0_1_clk_cnt);
766 dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC0_CTL;
767 break;
768 case 2:
769 case 3:
770 dmic_clk_cnt = &(tx_priv->dmic_2_3_clk_cnt);
771 dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC1_CTL;
772 break;
773 case 4:
774 case 5:
775 dmic_clk_cnt = &(tx_priv->dmic_4_5_clk_cnt);
776 dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC2_CTL;
777 break;
778 case 6:
779 case 7:
780 dmic_clk_cnt = &(tx_priv->dmic_6_7_clk_cnt);
781 dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC3_CTL;
782 break;
783 default:
Meng Wang15c825d2018-09-06 10:49:18 +0800784 dev_err(component->dev, "%s: Invalid DMIC Selection\n",
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530785 __func__);
786 return -EINVAL;
787 }
Meng Wang15c825d2018-09-06 10:49:18 +0800788 dev_dbg(component->dev, "%s: event %d DMIC%d dmic_clk_cnt %d\n",
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530789 __func__, event, dmic, *dmic_clk_cnt);
790
791 switch (event) {
792 case SND_SOC_DAPM_PRE_PMU:
793 (*dmic_clk_cnt)++;
794 if (*dmic_clk_cnt == 1) {
Meng Wang15c825d2018-09-06 10:49:18 +0800795 snd_soc_component_update_bits(component,
796 BOLERO_CDC_VA_TOP_CSR_DMIC_CFG,
Ramprasad Katkam9c2394a2018-08-23 13:13:48 +0530797 0x80, 0x00);
798
Meng Wang15c825d2018-09-06 10:49:18 +0800799 snd_soc_component_update_bits(component, dmic_clk_reg,
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530800 0x0E, tx_priv->dmic_clk_div << 0x1);
Meng Wang15c825d2018-09-06 10:49:18 +0800801 snd_soc_component_update_bits(component, dmic_clk_reg,
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530802 dmic_clk_en, dmic_clk_en);
803 }
804 break;
805 case SND_SOC_DAPM_POST_PMD:
806 (*dmic_clk_cnt)--;
807 if (*dmic_clk_cnt == 0)
Meng Wang15c825d2018-09-06 10:49:18 +0800808 snd_soc_component_update_bits(component, dmic_clk_reg,
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530809 dmic_clk_en, 0);
810 break;
811 }
812
813 return 0;
814}
815
816static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w,
817 struct snd_kcontrol *kcontrol, int event)
818{
Meng Wang15c825d2018-09-06 10:49:18 +0800819 struct snd_soc_component *component =
820 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530821 unsigned int decimator = 0;
822 u16 tx_vol_ctl_reg = 0;
823 u16 dec_cfg_reg = 0;
824 u16 hpf_gate_reg = 0;
825 u16 tx_gain_ctl_reg = 0;
826 u8 hpf_cut_off_freq = 0;
827 struct device *tx_dev = NULL;
828 struct tx_macro_priv *tx_priv = NULL;
829
Meng Wang15c825d2018-09-06 10:49:18 +0800830 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530831 return -EINVAL;
832
833 decimator = w->shift;
834
Meng Wang15c825d2018-09-06 10:49:18 +0800835 dev_dbg(component->dev, "%s(): widget = %s decimator = %u\n", __func__,
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530836 w->name, decimator);
837
838 tx_vol_ctl_reg = BOLERO_CDC_TX0_TX_PATH_CTL +
839 TX_MACRO_TX_PATH_OFFSET * decimator;
840 hpf_gate_reg = BOLERO_CDC_TX0_TX_PATH_SEC2 +
841 TX_MACRO_TX_PATH_OFFSET * decimator;
842 dec_cfg_reg = BOLERO_CDC_TX0_TX_PATH_CFG0 +
843 TX_MACRO_TX_PATH_OFFSET * decimator;
844 tx_gain_ctl_reg = BOLERO_CDC_TX0_TX_VOL_CTL +
845 TX_MACRO_TX_PATH_OFFSET * decimator;
846
847 switch (event) {
848 case SND_SOC_DAPM_PRE_PMU:
Karthikeyan Mani1dcd5a32019-08-22 14:37:13 -0700849 snd_soc_component_update_bits(component,
850 dec_cfg_reg, 0x06, tx_priv->dec_mode[decimator] <<
851 TX_MACRO_ADC_MODE_CFG0_SHIFT);
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530852 /* Enable TX PGA Mute */
Meng Wang15c825d2018-09-06 10:49:18 +0800853 snd_soc_component_update_bits(component,
854 tx_vol_ctl_reg, 0x10, 0x10);
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530855 break;
856 case SND_SOC_DAPM_POST_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +0800857 snd_soc_component_update_bits(component,
858 tx_vol_ctl_reg, 0x20, 0x20);
859 snd_soc_component_update_bits(component,
860 hpf_gate_reg, 0x01, 0x00);
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530861
Meng Wang15c825d2018-09-06 10:49:18 +0800862 hpf_cut_off_freq = (
863 snd_soc_component_read32(component, dec_cfg_reg) &
864 TX_HPF_CUT_OFF_FREQ_MASK) >> 5;
865
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530866 tx_priv->tx_hpf_work[decimator].hpf_cut_off_freq =
Meng Wang15c825d2018-09-06 10:49:18 +0800867 hpf_cut_off_freq;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530868
869 if (hpf_cut_off_freq != CF_MIN_3DB_150HZ)
Meng Wang15c825d2018-09-06 10:49:18 +0800870 snd_soc_component_update_bits(component, dec_cfg_reg,
871 TX_HPF_CUT_OFF_FREQ_MASK,
872 CF_MIN_3DB_150HZ << 5);
873
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530874 /* schedule work queue to Remove Mute */
875 schedule_delayed_work(&tx_priv->tx_mute_dwork[decimator].dwork,
876 msecs_to_jiffies(tx_unmute_delay));
877 if (tx_priv->tx_hpf_work[decimator].hpf_cut_off_freq !=
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530878 CF_MIN_3DB_150HZ) {
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530879 schedule_delayed_work(
880 &tx_priv->tx_hpf_work[decimator].dwork,
Karthikeyan Mani6bd895e2019-07-26 15:34:50 -0700881 msecs_to_jiffies(300));
Meng Wang15c825d2018-09-06 10:49:18 +0800882 snd_soc_component_update_bits(component,
883 hpf_gate_reg, 0x02, 0x02);
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530884 /*
885 * Minimum 1 clk cycle delay is required as per HW spec
886 */
887 usleep_range(1000, 1010);
Meng Wang15c825d2018-09-06 10:49:18 +0800888 snd_soc_component_update_bits(component,
889 hpf_gate_reg, 0x02, 0x00);
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530890 }
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530891 /* apply gain after decimator is enabled */
Meng Wang15c825d2018-09-06 10:49:18 +0800892 snd_soc_component_write(component, tx_gain_ctl_reg,
893 snd_soc_component_read32(component,
894 tx_gain_ctl_reg));
Karthikeyan Mani765eaab2019-07-18 16:27:01 -0700895 if (tx_priv->bcs_enable) {
896 snd_soc_component_update_bits(component, dec_cfg_reg,
897 0x01, 0x01);
898 snd_soc_component_update_bits(component,
899 BOLERO_CDC_TX0_TX_PATH_SEC7, 0x40, 0x40);
900 }
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530901 break;
902 case SND_SOC_DAPM_PRE_PMD:
903 hpf_cut_off_freq =
904 tx_priv->tx_hpf_work[decimator].hpf_cut_off_freq;
Meng Wang15c825d2018-09-06 10:49:18 +0800905 snd_soc_component_update_bits(component,
906 tx_vol_ctl_reg, 0x10, 0x10);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530907 if (cancel_delayed_work_sync(
908 &tx_priv->tx_hpf_work[decimator].dwork)) {
909 if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) {
Meng Wang15c825d2018-09-06 10:49:18 +0800910 snd_soc_component_update_bits(
911 component, dec_cfg_reg,
912 TX_HPF_CUT_OFF_FREQ_MASK,
913 hpf_cut_off_freq << 5);
914 snd_soc_component_update_bits(component,
915 hpf_gate_reg,
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530916 0x02, 0x02);
917 /*
918 * Minimum 1 clk cycle delay is required
919 * as per HW spec
920 */
921 usleep_range(1000, 1010);
Meng Wang15c825d2018-09-06 10:49:18 +0800922 snd_soc_component_update_bits(component,
923 hpf_gate_reg,
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530924 0x02, 0x00);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530925 }
926 }
927 cancel_delayed_work_sync(
928 &tx_priv->tx_mute_dwork[decimator].dwork);
929 break;
930 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +0800931 snd_soc_component_update_bits(component, tx_vol_ctl_reg,
932 0x20, 0x00);
Karthikeyan Mani1dcd5a32019-08-22 14:37:13 -0700933 snd_soc_component_update_bits(component,
934 dec_cfg_reg, 0x06, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +0800935 snd_soc_component_update_bits(component, tx_vol_ctl_reg,
936 0x10, 0x00);
Karthikeyan Mani765eaab2019-07-18 16:27:01 -0700937 if (tx_priv->bcs_enable) {
938 snd_soc_component_update_bits(component, dec_cfg_reg,
939 0x01, 0x00);
940 snd_soc_component_update_bits(component,
941 BOLERO_CDC_TX0_TX_PATH_SEC7, 0x40, 0x00);
942 }
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530943 break;
944 }
945 return 0;
946}
947
948static int tx_macro_enable_micbias(struct snd_soc_dapm_widget *w,
949 struct snd_kcontrol *kcontrol, int event)
950{
951 return 0;
952}
953
954static int tx_macro_hw_params(struct snd_pcm_substream *substream,
955 struct snd_pcm_hw_params *params,
956 struct snd_soc_dai *dai)
957{
958 int tx_fs_rate = -EINVAL;
Meng Wang15c825d2018-09-06 10:49:18 +0800959 struct snd_soc_component *component = dai->component;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530960 u32 decimator = 0;
Laxminath Kasamb7f823c2018-08-02 13:23:11 +0530961 u32 sample_rate = 0;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530962 u16 tx_fs_reg = 0;
963 struct device *tx_dev = NULL;
964 struct tx_macro_priv *tx_priv = NULL;
965
Meng Wang15c825d2018-09-06 10:49:18 +0800966 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530967 return -EINVAL;
968
969 pr_debug("%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__,
970 dai->name, dai->id, params_rate(params),
971 params_channels(params));
972
973 sample_rate = params_rate(params);
974 switch (sample_rate) {
975 case 8000:
976 tx_fs_rate = 0;
977 break;
978 case 16000:
979 tx_fs_rate = 1;
980 break;
981 case 32000:
982 tx_fs_rate = 3;
983 break;
984 case 48000:
985 tx_fs_rate = 4;
986 break;
987 case 96000:
988 tx_fs_rate = 5;
989 break;
990 case 192000:
991 tx_fs_rate = 6;
992 break;
993 case 384000:
994 tx_fs_rate = 7;
995 break;
996 default:
Meng Wang15c825d2018-09-06 10:49:18 +0800997 dev_err(component->dev, "%s: Invalid TX sample rate: %d\n",
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530998 __func__, params_rate(params));
999 return -EINVAL;
1000 }
1001 for_each_set_bit(decimator, &tx_priv->active_ch_mask[dai->id],
1002 TX_MACRO_DEC_MAX) {
1003 if (decimator >= 0) {
1004 tx_fs_reg = BOLERO_CDC_TX0_TX_PATH_CTL +
1005 TX_MACRO_TX_PATH_OFFSET * decimator;
Meng Wang15c825d2018-09-06 10:49:18 +08001006 dev_dbg(component->dev, "%s: set DEC%u rate to %u\n",
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301007 __func__, decimator, sample_rate);
Meng Wang15c825d2018-09-06 10:49:18 +08001008 snd_soc_component_update_bits(component, tx_fs_reg,
1009 0x0F, tx_fs_rate);
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301010 } else {
Meng Wang15c825d2018-09-06 10:49:18 +08001011 dev_err(component->dev,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301012 "%s: ERROR: Invalid decimator: %d\n",
1013 __func__, decimator);
1014 return -EINVAL;
1015 }
1016 }
1017 return 0;
1018}
1019
1020static int tx_macro_get_channel_map(struct snd_soc_dai *dai,
1021 unsigned int *tx_num, unsigned int *tx_slot,
1022 unsigned int *rx_num, unsigned int *rx_slot)
1023{
Meng Wang15c825d2018-09-06 10:49:18 +08001024 struct snd_soc_component *component = dai->component;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301025 struct device *tx_dev = NULL;
1026 struct tx_macro_priv *tx_priv = NULL;
1027
Meng Wang15c825d2018-09-06 10:49:18 +08001028 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301029 return -EINVAL;
1030
1031 switch (dai->id) {
1032 case TX_MACRO_AIF1_CAP:
1033 case TX_MACRO_AIF2_CAP:
Karthikeyan Manif3bb8182019-07-11 14:38:54 -07001034 case TX_MACRO_AIF3_CAP:
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301035 *tx_slot = tx_priv->active_ch_mask[dai->id];
1036 *tx_num = tx_priv->active_ch_cnt[dai->id];
1037 break;
1038 default:
1039 dev_err(tx_dev, "%s: Invalid AIF\n", __func__);
1040 break;
1041 }
1042 return 0;
1043}
1044
1045static struct snd_soc_dai_ops tx_macro_dai_ops = {
1046 .hw_params = tx_macro_hw_params,
1047 .get_channel_map = tx_macro_get_channel_map,
1048};
1049
1050static struct snd_soc_dai_driver tx_macro_dai[] = {
1051 {
1052 .name = "tx_macro_tx1",
1053 .id = TX_MACRO_AIF1_CAP,
1054 .capture = {
1055 .stream_name = "TX_AIF1 Capture",
1056 .rates = TX_MACRO_RATES,
1057 .formats = TX_MACRO_FORMATS,
1058 .rate_max = 192000,
1059 .rate_min = 8000,
1060 .channels_min = 1,
1061 .channels_max = 8,
1062 },
1063 .ops = &tx_macro_dai_ops,
1064 },
1065 {
1066 .name = "tx_macro_tx2",
1067 .id = TX_MACRO_AIF2_CAP,
1068 .capture = {
1069 .stream_name = "TX_AIF2 Capture",
1070 .rates = TX_MACRO_RATES,
1071 .formats = TX_MACRO_FORMATS,
1072 .rate_max = 192000,
1073 .rate_min = 8000,
1074 .channels_min = 1,
1075 .channels_max = 8,
1076 },
1077 .ops = &tx_macro_dai_ops,
1078 },
Karthikeyan Manif3bb8182019-07-11 14:38:54 -07001079 {
1080 .name = "tx_macro_tx3",
1081 .id = TX_MACRO_AIF3_CAP,
1082 .capture = {
1083 .stream_name = "TX_AIF3 Capture",
1084 .rates = TX_MACRO_RATES,
1085 .formats = TX_MACRO_FORMATS,
1086 .rate_max = 192000,
1087 .rate_min = 8000,
1088 .channels_min = 1,
1089 .channels_max = 8,
1090 },
1091 .ops = &tx_macro_dai_ops,
1092 },
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301093};
1094
1095#define STRING(name) #name
1096#define TX_MACRO_DAPM_ENUM(name, reg, offset, text) \
1097static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \
1098static const struct snd_kcontrol_new name##_mux = \
1099 SOC_DAPM_ENUM(STRING(name), name##_enum)
1100
1101#define TX_MACRO_DAPM_ENUM_EXT(name, reg, offset, text, getname, putname) \
1102static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \
1103static const struct snd_kcontrol_new name##_mux = \
1104 SOC_DAPM_ENUM_EXT(STRING(name), name##_enum, getname, putname)
1105
1106#define TX_MACRO_DAPM_MUX(name, shift, kctl) \
1107 SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, shift, 0, &kctl##_mux)
1108
1109static const char * const adc_mux_text[] = {
1110 "MSM_DMIC", "SWR_MIC", "ANC_FB_TUNE1"
1111};
1112
1113TX_MACRO_DAPM_ENUM(tx_dec0, BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG1,
1114 0, adc_mux_text);
1115TX_MACRO_DAPM_ENUM(tx_dec1, BOLERO_CDC_TX_INP_MUX_ADC_MUX1_CFG1,
1116 0, adc_mux_text);
1117TX_MACRO_DAPM_ENUM(tx_dec2, BOLERO_CDC_TX_INP_MUX_ADC_MUX2_CFG1,
1118 0, adc_mux_text);
1119TX_MACRO_DAPM_ENUM(tx_dec3, BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG1,
1120 0, adc_mux_text);
1121TX_MACRO_DAPM_ENUM(tx_dec4, BOLERO_CDC_TX_INP_MUX_ADC_MUX4_CFG1,
1122 0, adc_mux_text);
1123TX_MACRO_DAPM_ENUM(tx_dec5, BOLERO_CDC_TX_INP_MUX_ADC_MUX5_CFG1,
1124 0, adc_mux_text);
1125TX_MACRO_DAPM_ENUM(tx_dec6, BOLERO_CDC_TX_INP_MUX_ADC_MUX6_CFG1,
1126 0, adc_mux_text);
1127TX_MACRO_DAPM_ENUM(tx_dec7, BOLERO_CDC_TX_INP_MUX_ADC_MUX7_CFG1,
1128 0, adc_mux_text);
1129
1130
1131static const char * const dmic_mux_text[] = {
1132 "ZERO", "DMIC0", "DMIC1", "DMIC2", "DMIC3",
1133 "DMIC4", "DMIC5", "DMIC6", "DMIC7"
1134};
1135
1136TX_MACRO_DAPM_ENUM_EXT(tx_dmic0, BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0,
1137 4, dmic_mux_text, snd_soc_dapm_get_enum_double,
1138 tx_macro_put_dec_enum);
1139
1140TX_MACRO_DAPM_ENUM_EXT(tx_dmic1, BOLERO_CDC_TX_INP_MUX_ADC_MUX1_CFG0,
1141 4, dmic_mux_text, snd_soc_dapm_get_enum_double,
1142 tx_macro_put_dec_enum);
1143
1144TX_MACRO_DAPM_ENUM_EXT(tx_dmic2, BOLERO_CDC_TX_INP_MUX_ADC_MUX2_CFG0,
1145 4, dmic_mux_text, snd_soc_dapm_get_enum_double,
1146 tx_macro_put_dec_enum);
1147
1148TX_MACRO_DAPM_ENUM_EXT(tx_dmic3, BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG0,
1149 4, dmic_mux_text, snd_soc_dapm_get_enum_double,
1150 tx_macro_put_dec_enum);
1151
1152TX_MACRO_DAPM_ENUM_EXT(tx_dmic4, BOLERO_CDC_TX_INP_MUX_ADC_MUX4_CFG0,
1153 4, dmic_mux_text, snd_soc_dapm_get_enum_double,
1154 tx_macro_put_dec_enum);
1155
1156TX_MACRO_DAPM_ENUM_EXT(tx_dmic5, BOLERO_CDC_TX_INP_MUX_ADC_MUX5_CFG0,
1157 4, dmic_mux_text, snd_soc_dapm_get_enum_double,
1158 tx_macro_put_dec_enum);
1159
1160TX_MACRO_DAPM_ENUM_EXT(tx_dmic6, BOLERO_CDC_TX_INP_MUX_ADC_MUX6_CFG0,
1161 4, dmic_mux_text, snd_soc_dapm_get_enum_double,
1162 tx_macro_put_dec_enum);
1163
1164TX_MACRO_DAPM_ENUM_EXT(tx_dmic7, BOLERO_CDC_TX_INP_MUX_ADC_MUX7_CFG0,
1165 4, dmic_mux_text, snd_soc_dapm_get_enum_double,
1166 tx_macro_put_dec_enum);
1167
1168static const char * const smic_mux_text[] = {
Sudheer Papothi324b4952019-06-11 04:14:51 +05301169 "ZERO", "ADC0", "ADC1", "ADC2", "ADC3", "SWR_DMIC0",
1170 "SWR_DMIC1", "SWR_DMIC2", "SWR_DMIC3", "SWR_DMIC4",
1171 "SWR_DMIC5", "SWR_DMIC6", "SWR_DMIC7"
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301172};
1173
1174TX_MACRO_DAPM_ENUM_EXT(tx_smic0, BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0,
1175 0, smic_mux_text, snd_soc_dapm_get_enum_double,
1176 tx_macro_put_dec_enum);
1177
1178TX_MACRO_DAPM_ENUM_EXT(tx_smic1, BOLERO_CDC_TX_INP_MUX_ADC_MUX1_CFG0,
1179 0, smic_mux_text, snd_soc_dapm_get_enum_double,
1180 tx_macro_put_dec_enum);
1181
1182TX_MACRO_DAPM_ENUM_EXT(tx_smic2, BOLERO_CDC_TX_INP_MUX_ADC_MUX2_CFG0,
1183 0, smic_mux_text, snd_soc_dapm_get_enum_double,
1184 tx_macro_put_dec_enum);
1185
1186TX_MACRO_DAPM_ENUM_EXT(tx_smic3, BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG0,
1187 0, smic_mux_text, snd_soc_dapm_get_enum_double,
1188 tx_macro_put_dec_enum);
1189
1190TX_MACRO_DAPM_ENUM_EXT(tx_smic4, BOLERO_CDC_TX_INP_MUX_ADC_MUX4_CFG0,
1191 0, smic_mux_text, snd_soc_dapm_get_enum_double,
1192 tx_macro_put_dec_enum);
1193
1194TX_MACRO_DAPM_ENUM_EXT(tx_smic5, BOLERO_CDC_TX_INP_MUX_ADC_MUX5_CFG0,
1195 0, smic_mux_text, snd_soc_dapm_get_enum_double,
1196 tx_macro_put_dec_enum);
1197
1198TX_MACRO_DAPM_ENUM_EXT(tx_smic6, BOLERO_CDC_TX_INP_MUX_ADC_MUX6_CFG0,
1199 0, smic_mux_text, snd_soc_dapm_get_enum_double,
1200 tx_macro_put_dec_enum);
1201
1202TX_MACRO_DAPM_ENUM_EXT(tx_smic7, BOLERO_CDC_TX_INP_MUX_ADC_MUX7_CFG0,
1203 0, smic_mux_text, snd_soc_dapm_get_enum_double,
1204 tx_macro_put_dec_enum);
1205
Karthikeyan Mani1dcd5a32019-08-22 14:37:13 -07001206static const char * const dec_mode_mux_text[] = {
1207 "ADC_DEFAULT", "ADC_LOW_PWR", "ADC_HIGH_PERF",
1208};
1209
1210static const struct soc_enum dec_mode_mux_enum =
1211 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(dec_mode_mux_text),
1212 dec_mode_mux_text);
1213
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301214static const struct snd_kcontrol_new tx_aif1_cap_mixer[] = {
1215 SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, TX_MACRO_DEC0, 1, 0,
1216 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1217 SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, TX_MACRO_DEC1, 1, 0,
1218 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1219 SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, TX_MACRO_DEC2, 1, 0,
1220 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1221 SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, TX_MACRO_DEC3, 1, 0,
1222 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1223 SOC_SINGLE_EXT("DEC4", SND_SOC_NOPM, TX_MACRO_DEC4, 1, 0,
1224 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1225 SOC_SINGLE_EXT("DEC5", SND_SOC_NOPM, TX_MACRO_DEC5, 1, 0,
1226 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1227 SOC_SINGLE_EXT("DEC6", SND_SOC_NOPM, TX_MACRO_DEC6, 1, 0,
1228 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1229 SOC_SINGLE_EXT("DEC7", SND_SOC_NOPM, TX_MACRO_DEC7, 1, 0,
1230 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1231};
1232
1233static const struct snd_kcontrol_new tx_aif2_cap_mixer[] = {
1234 SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, TX_MACRO_DEC0, 1, 0,
1235 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1236 SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, TX_MACRO_DEC1, 1, 0,
1237 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1238 SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, TX_MACRO_DEC2, 1, 0,
1239 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1240 SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, TX_MACRO_DEC3, 1, 0,
1241 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1242 SOC_SINGLE_EXT("DEC4", SND_SOC_NOPM, TX_MACRO_DEC4, 1, 0,
1243 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1244 SOC_SINGLE_EXT("DEC5", SND_SOC_NOPM, TX_MACRO_DEC5, 1, 0,
1245 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1246 SOC_SINGLE_EXT("DEC6", SND_SOC_NOPM, TX_MACRO_DEC6, 1, 0,
1247 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1248 SOC_SINGLE_EXT("DEC7", SND_SOC_NOPM, TX_MACRO_DEC7, 1, 0,
1249 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1250};
1251
Karthikeyan Manif3bb8182019-07-11 14:38:54 -07001252static const struct snd_kcontrol_new tx_aif3_cap_mixer[] = {
1253 SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, TX_MACRO_DEC0, 1, 0,
1254 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1255 SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, TX_MACRO_DEC1, 1, 0,
1256 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1257 SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, TX_MACRO_DEC2, 1, 0,
1258 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1259 SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, TX_MACRO_DEC3, 1, 0,
1260 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1261 SOC_SINGLE_EXT("DEC4", SND_SOC_NOPM, TX_MACRO_DEC4, 1, 0,
1262 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1263 SOC_SINGLE_EXT("DEC5", SND_SOC_NOPM, TX_MACRO_DEC5, 1, 0,
1264 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1265 SOC_SINGLE_EXT("DEC6", SND_SOC_NOPM, TX_MACRO_DEC6, 1, 0,
1266 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1267 SOC_SINGLE_EXT("DEC7", SND_SOC_NOPM, TX_MACRO_DEC7, 1, 0,
1268 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1269};
1270
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301271static const struct snd_soc_dapm_widget tx_macro_dapm_widgets[] = {
1272 SND_SOC_DAPM_AIF_OUT("TX_AIF1 CAP", "TX_AIF1 Capture", 0,
1273 SND_SOC_NOPM, TX_MACRO_AIF1_CAP, 0),
1274
1275 SND_SOC_DAPM_AIF_OUT("TX_AIF2 CAP", "TX_AIF2 Capture", 0,
1276 SND_SOC_NOPM, TX_MACRO_AIF2_CAP, 0),
1277
Karthikeyan Manif3bb8182019-07-11 14:38:54 -07001278 SND_SOC_DAPM_AIF_OUT("TX_AIF3 CAP", "TX_AIF3 Capture", 0,
1279 SND_SOC_NOPM, TX_MACRO_AIF3_CAP, 0),
1280
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301281 SND_SOC_DAPM_MIXER("TX_AIF1_CAP Mixer", SND_SOC_NOPM, TX_MACRO_AIF1_CAP, 0,
1282 tx_aif1_cap_mixer, ARRAY_SIZE(tx_aif1_cap_mixer)),
1283
1284 SND_SOC_DAPM_MIXER("TX_AIF2_CAP Mixer", SND_SOC_NOPM, TX_MACRO_AIF2_CAP, 0,
1285 tx_aif2_cap_mixer, ARRAY_SIZE(tx_aif2_cap_mixer)),
1286
Karthikeyan Manif3bb8182019-07-11 14:38:54 -07001287 SND_SOC_DAPM_MIXER("TX_AIF3_CAP Mixer", SND_SOC_NOPM, TX_MACRO_AIF3_CAP, 0,
1288 tx_aif3_cap_mixer, ARRAY_SIZE(tx_aif3_cap_mixer)),
1289
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301290
1291 TX_MACRO_DAPM_MUX("TX DMIC MUX0", 0, tx_dmic0),
1292 TX_MACRO_DAPM_MUX("TX DMIC MUX1", 0, tx_dmic1),
1293 TX_MACRO_DAPM_MUX("TX DMIC MUX2", 0, tx_dmic2),
1294 TX_MACRO_DAPM_MUX("TX DMIC MUX3", 0, tx_dmic3),
1295 TX_MACRO_DAPM_MUX("TX DMIC MUX4", 0, tx_dmic4),
1296 TX_MACRO_DAPM_MUX("TX DMIC MUX5", 0, tx_dmic5),
1297 TX_MACRO_DAPM_MUX("TX DMIC MUX6", 0, tx_dmic6),
1298 TX_MACRO_DAPM_MUX("TX DMIC MUX7", 0, tx_dmic7),
1299
1300 TX_MACRO_DAPM_MUX("TX SMIC MUX0", 0, tx_smic0),
1301 TX_MACRO_DAPM_MUX("TX SMIC MUX1", 0, tx_smic1),
1302 TX_MACRO_DAPM_MUX("TX SMIC MUX2", 0, tx_smic2),
1303 TX_MACRO_DAPM_MUX("TX SMIC MUX3", 0, tx_smic3),
1304 TX_MACRO_DAPM_MUX("TX SMIC MUX4", 0, tx_smic4),
1305 TX_MACRO_DAPM_MUX("TX SMIC MUX5", 0, tx_smic5),
1306 TX_MACRO_DAPM_MUX("TX SMIC MUX6", 0, tx_smic6),
1307 TX_MACRO_DAPM_MUX("TX SMIC MUX7", 0, tx_smic7),
1308
1309 SND_SOC_DAPM_MICBIAS_E("TX MIC BIAS1", SND_SOC_NOPM, 0, 0,
1310 tx_macro_enable_micbias,
1311 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1312 SND_SOC_DAPM_ADC_E("TX DMIC0", NULL, SND_SOC_NOPM, 0, 0,
1313 tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
1314 SND_SOC_DAPM_POST_PMD),
1315
1316 SND_SOC_DAPM_ADC_E("TX DMIC1", NULL, SND_SOC_NOPM, 0, 0,
1317 tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
1318 SND_SOC_DAPM_POST_PMD),
1319
1320 SND_SOC_DAPM_ADC_E("TX DMIC2", NULL, SND_SOC_NOPM, 0, 0,
1321 tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
1322 SND_SOC_DAPM_POST_PMD),
1323
1324 SND_SOC_DAPM_ADC_E("TX DMIC3", NULL, SND_SOC_NOPM, 0, 0,
1325 tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
1326 SND_SOC_DAPM_POST_PMD),
1327
1328 SND_SOC_DAPM_ADC_E("TX DMIC4", NULL, SND_SOC_NOPM, 0, 0,
1329 tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
1330 SND_SOC_DAPM_POST_PMD),
1331
1332 SND_SOC_DAPM_ADC_E("TX DMIC5", NULL, SND_SOC_NOPM, 0, 0,
1333 tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
1334 SND_SOC_DAPM_POST_PMD),
1335
1336 SND_SOC_DAPM_ADC_E("TX DMIC6", NULL, SND_SOC_NOPM, 0, 0,
1337 tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
1338 SND_SOC_DAPM_POST_PMD),
1339
1340 SND_SOC_DAPM_ADC_E("TX DMIC7", NULL, SND_SOC_NOPM, 0, 0,
1341 tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
1342 SND_SOC_DAPM_POST_PMD),
1343
1344 SND_SOC_DAPM_INPUT("TX SWR_ADC0"),
1345 SND_SOC_DAPM_INPUT("TX SWR_ADC1"),
1346 SND_SOC_DAPM_INPUT("TX SWR_ADC2"),
1347 SND_SOC_DAPM_INPUT("TX SWR_ADC3"),
1348 SND_SOC_DAPM_INPUT("TX SWR_DMIC0"),
1349 SND_SOC_DAPM_INPUT("TX SWR_DMIC1"),
1350 SND_SOC_DAPM_INPUT("TX SWR_DMIC2"),
1351 SND_SOC_DAPM_INPUT("TX SWR_DMIC3"),
1352 SND_SOC_DAPM_INPUT("TX SWR_DMIC4"),
1353 SND_SOC_DAPM_INPUT("TX SWR_DMIC5"),
1354 SND_SOC_DAPM_INPUT("TX SWR_DMIC6"),
1355 SND_SOC_DAPM_INPUT("TX SWR_DMIC7"),
1356
Ramprasad Katkamf83acfb2018-08-11 23:28:57 +05301357 SND_SOC_DAPM_MUX_E("TX DEC0 MUX", SND_SOC_NOPM,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301358 TX_MACRO_DEC0, 0,
1359 &tx_dec0_mux, tx_macro_enable_dec,
1360 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1361 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1362
Ramprasad Katkamf83acfb2018-08-11 23:28:57 +05301363 SND_SOC_DAPM_MUX_E("TX DEC1 MUX", SND_SOC_NOPM,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301364 TX_MACRO_DEC1, 0,
1365 &tx_dec1_mux, tx_macro_enable_dec,
1366 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1367 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1368
Ramprasad Katkamf83acfb2018-08-11 23:28:57 +05301369 SND_SOC_DAPM_MUX_E("TX DEC2 MUX", SND_SOC_NOPM,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301370 TX_MACRO_DEC2, 0,
1371 &tx_dec2_mux, tx_macro_enable_dec,
1372 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1373 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1374
Ramprasad Katkamf83acfb2018-08-11 23:28:57 +05301375 SND_SOC_DAPM_MUX_E("TX DEC3 MUX", SND_SOC_NOPM,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301376 TX_MACRO_DEC3, 0,
1377 &tx_dec3_mux, tx_macro_enable_dec,
1378 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1379 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1380
Ramprasad Katkamf83acfb2018-08-11 23:28:57 +05301381 SND_SOC_DAPM_MUX_E("TX DEC4 MUX", SND_SOC_NOPM,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301382 TX_MACRO_DEC4, 0,
1383 &tx_dec4_mux, tx_macro_enable_dec,
1384 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1385 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1386
Ramprasad Katkamf83acfb2018-08-11 23:28:57 +05301387 SND_SOC_DAPM_MUX_E("TX DEC5 MUX", SND_SOC_NOPM,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301388 TX_MACRO_DEC5, 0,
1389 &tx_dec5_mux, tx_macro_enable_dec,
1390 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1391 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1392
Ramprasad Katkamf83acfb2018-08-11 23:28:57 +05301393 SND_SOC_DAPM_MUX_E("TX DEC6 MUX", SND_SOC_NOPM,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301394 TX_MACRO_DEC6, 0,
1395 &tx_dec6_mux, tx_macro_enable_dec,
1396 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1397 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1398
Ramprasad Katkamf83acfb2018-08-11 23:28:57 +05301399 SND_SOC_DAPM_MUX_E("TX DEC7 MUX", SND_SOC_NOPM,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301400 TX_MACRO_DEC7, 0,
1401 &tx_dec7_mux, tx_macro_enable_dec,
1402 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1403 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1404
1405 SND_SOC_DAPM_SUPPLY_S("TX_MCLK", 0, SND_SOC_NOPM, 0, 0,
1406 tx_macro_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
Sudheer Papothie456c2c2019-03-05 07:08:45 +05301407
1408 SND_SOC_DAPM_SUPPLY_S("TX_SWR_CLK", 0, SND_SOC_NOPM, 0, 0,
1409 tx_macro_tx_swr_clk_event,
1410 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1411
1412 SND_SOC_DAPM_SUPPLY_S("VA_SWR_CLK", 0, SND_SOC_NOPM, 0, 0,
1413 tx_macro_va_swr_clk_event,
1414 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301415};
1416
1417static const struct snd_soc_dapm_route tx_audio_map[] = {
1418 {"TX_AIF1 CAP", NULL, "TX_MCLK"},
1419 {"TX_AIF2 CAP", NULL, "TX_MCLK"},
Karthikeyan Manif3bb8182019-07-11 14:38:54 -07001420 {"TX_AIF3 CAP", NULL, "TX_MCLK"},
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301421
1422 {"TX_AIF1 CAP", NULL, "TX_AIF1_CAP Mixer"},
1423 {"TX_AIF2 CAP", NULL, "TX_AIF2_CAP Mixer"},
Karthikeyan Manif3bb8182019-07-11 14:38:54 -07001424 {"TX_AIF3 CAP", NULL, "TX_AIF3_CAP Mixer"},
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301425
1426 {"TX_AIF1_CAP Mixer", "DEC0", "TX DEC0 MUX"},
1427 {"TX_AIF1_CAP Mixer", "DEC1", "TX DEC1 MUX"},
1428 {"TX_AIF1_CAP Mixer", "DEC2", "TX DEC2 MUX"},
1429 {"TX_AIF1_CAP Mixer", "DEC3", "TX DEC3 MUX"},
1430 {"TX_AIF1_CAP Mixer", "DEC4", "TX DEC4 MUX"},
1431 {"TX_AIF1_CAP Mixer", "DEC5", "TX DEC5 MUX"},
1432 {"TX_AIF1_CAP Mixer", "DEC6", "TX DEC6 MUX"},
1433 {"TX_AIF1_CAP Mixer", "DEC7", "TX DEC7 MUX"},
1434
1435 {"TX_AIF2_CAP Mixer", "DEC0", "TX DEC0 MUX"},
1436 {"TX_AIF2_CAP Mixer", "DEC1", "TX DEC1 MUX"},
1437 {"TX_AIF2_CAP Mixer", "DEC2", "TX DEC2 MUX"},
1438 {"TX_AIF2_CAP Mixer", "DEC3", "TX DEC3 MUX"},
1439 {"TX_AIF2_CAP Mixer", "DEC4", "TX DEC4 MUX"},
1440 {"TX_AIF2_CAP Mixer", "DEC5", "TX DEC5 MUX"},
1441 {"TX_AIF2_CAP Mixer", "DEC6", "TX DEC6 MUX"},
1442 {"TX_AIF2_CAP Mixer", "DEC7", "TX DEC7 MUX"},
1443
Karthikeyan Manif3bb8182019-07-11 14:38:54 -07001444 {"TX_AIF3_CAP Mixer", "DEC0", "TX DEC0 MUX"},
1445 {"TX_AIF3_CAP Mixer", "DEC1", "TX DEC1 MUX"},
1446 {"TX_AIF3_CAP Mixer", "DEC2", "TX DEC2 MUX"},
1447 {"TX_AIF3_CAP Mixer", "DEC3", "TX DEC3 MUX"},
1448 {"TX_AIF3_CAP Mixer", "DEC4", "TX DEC4 MUX"},
1449 {"TX_AIF3_CAP Mixer", "DEC5", "TX DEC5 MUX"},
1450 {"TX_AIF3_CAP Mixer", "DEC6", "TX DEC6 MUX"},
1451 {"TX_AIF3_CAP Mixer", "DEC7", "TX DEC7 MUX"},
1452
Laxminath Kasamfc281ad2018-08-06 20:19:40 +05301453 {"TX DEC0 MUX", NULL, "TX_MCLK"},
1454 {"TX DEC1 MUX", NULL, "TX_MCLK"},
1455 {"TX DEC2 MUX", NULL, "TX_MCLK"},
1456 {"TX DEC3 MUX", NULL, "TX_MCLK"},
1457 {"TX DEC4 MUX", NULL, "TX_MCLK"},
1458 {"TX DEC5 MUX", NULL, "TX_MCLK"},
1459 {"TX DEC6 MUX", NULL, "TX_MCLK"},
1460 {"TX DEC7 MUX", NULL, "TX_MCLK"},
1461
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301462 {"TX DEC0 MUX", "MSM_DMIC", "TX DMIC MUX0"},
1463 {"TX DMIC MUX0", "DMIC0", "TX DMIC0"},
1464 {"TX DMIC MUX0", "DMIC1", "TX DMIC1"},
1465 {"TX DMIC MUX0", "DMIC2", "TX DMIC2"},
1466 {"TX DMIC MUX0", "DMIC3", "TX DMIC3"},
1467 {"TX DMIC MUX0", "DMIC4", "TX DMIC4"},
1468 {"TX DMIC MUX0", "DMIC5", "TX DMIC5"},
1469 {"TX DMIC MUX0", "DMIC6", "TX DMIC6"},
1470 {"TX DMIC MUX0", "DMIC7", "TX DMIC7"},
1471
1472 {"TX DEC0 MUX", "SWR_MIC", "TX SMIC MUX0"},
Sudheer Papothie456c2c2019-03-05 07:08:45 +05301473 {"TX SMIC MUX0", NULL, "TX_SWR_CLK"},
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301474 {"TX SMIC MUX0", "ADC0", "TX SWR_ADC0"},
1475 {"TX SMIC MUX0", "ADC1", "TX SWR_ADC1"},
1476 {"TX SMIC MUX0", "ADC2", "TX SWR_ADC2"},
1477 {"TX SMIC MUX0", "ADC3", "TX SWR_ADC3"},
1478 {"TX SMIC MUX0", "SWR_DMIC0", "TX SWR_DMIC0"},
1479 {"TX SMIC MUX0", "SWR_DMIC1", "TX SWR_DMIC1"},
1480 {"TX SMIC MUX0", "SWR_DMIC2", "TX SWR_DMIC2"},
1481 {"TX SMIC MUX0", "SWR_DMIC3", "TX SWR_DMIC3"},
1482 {"TX SMIC MUX0", "SWR_DMIC4", "TX SWR_DMIC4"},
1483 {"TX SMIC MUX0", "SWR_DMIC5", "TX SWR_DMIC5"},
1484 {"TX SMIC MUX0", "SWR_DMIC6", "TX SWR_DMIC6"},
1485 {"TX SMIC MUX0", "SWR_DMIC7", "TX SWR_DMIC7"},
1486
1487 {"TX DEC1 MUX", "MSM_DMIC", "TX DMIC MUX1"},
1488 {"TX DMIC MUX1", "DMIC0", "TX DMIC0"},
1489 {"TX DMIC MUX1", "DMIC1", "TX DMIC1"},
1490 {"TX DMIC MUX1", "DMIC2", "TX DMIC2"},
1491 {"TX DMIC MUX1", "DMIC3", "TX DMIC3"},
1492 {"TX DMIC MUX1", "DMIC4", "TX DMIC4"},
1493 {"TX DMIC MUX1", "DMIC5", "TX DMIC5"},
1494 {"TX DMIC MUX1", "DMIC6", "TX DMIC6"},
1495 {"TX DMIC MUX1", "DMIC7", "TX DMIC7"},
1496
1497 {"TX DEC1 MUX", "SWR_MIC", "TX SMIC MUX1"},
Sudheer Papothie456c2c2019-03-05 07:08:45 +05301498 {"TX SMIC MUX1", NULL, "TX_SWR_CLK"},
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301499 {"TX SMIC MUX1", "ADC0", "TX SWR_ADC0"},
1500 {"TX SMIC MUX1", "ADC1", "TX SWR_ADC1"},
1501 {"TX SMIC MUX1", "ADC2", "TX SWR_ADC2"},
1502 {"TX SMIC MUX1", "ADC3", "TX SWR_ADC3"},
1503 {"TX SMIC MUX1", "SWR_DMIC0", "TX SWR_DMIC0"},
1504 {"TX SMIC MUX1", "SWR_DMIC1", "TX SWR_DMIC1"},
1505 {"TX SMIC MUX1", "SWR_DMIC2", "TX SWR_DMIC2"},
1506 {"TX SMIC MUX1", "SWR_DMIC3", "TX SWR_DMIC3"},
1507 {"TX SMIC MUX1", "SWR_DMIC4", "TX SWR_DMIC4"},
1508 {"TX SMIC MUX1", "SWR_DMIC5", "TX SWR_DMIC5"},
1509 {"TX SMIC MUX1", "SWR_DMIC6", "TX SWR_DMIC6"},
1510 {"TX SMIC MUX1", "SWR_DMIC7", "TX SWR_DMIC7"},
1511
1512 {"TX DEC2 MUX", "MSM_DMIC", "TX DMIC MUX2"},
1513 {"TX DMIC MUX2", "DMIC0", "TX DMIC0"},
1514 {"TX DMIC MUX2", "DMIC1", "TX DMIC1"},
1515 {"TX DMIC MUX2", "DMIC2", "TX DMIC2"},
1516 {"TX DMIC MUX2", "DMIC3", "TX DMIC3"},
1517 {"TX DMIC MUX2", "DMIC4", "TX DMIC4"},
1518 {"TX DMIC MUX2", "DMIC5", "TX DMIC5"},
1519 {"TX DMIC MUX2", "DMIC6", "TX DMIC6"},
1520 {"TX DMIC MUX2", "DMIC7", "TX DMIC7"},
1521
1522 {"TX DEC2 MUX", "SWR_MIC", "TX SMIC MUX2"},
Sudheer Papothie456c2c2019-03-05 07:08:45 +05301523 {"TX SMIC MUX2", NULL, "TX_SWR_CLK"},
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301524 {"TX SMIC MUX2", "ADC0", "TX SWR_ADC0"},
1525 {"TX SMIC MUX2", "ADC1", "TX SWR_ADC1"},
1526 {"TX SMIC MUX2", "ADC2", "TX SWR_ADC2"},
1527 {"TX SMIC MUX2", "ADC3", "TX SWR_ADC3"},
1528 {"TX SMIC MUX2", "SWR_DMIC0", "TX SWR_DMIC0"},
1529 {"TX SMIC MUX2", "SWR_DMIC1", "TX SWR_DMIC1"},
1530 {"TX SMIC MUX2", "SWR_DMIC2", "TX SWR_DMIC2"},
1531 {"TX SMIC MUX2", "SWR_DMIC3", "TX SWR_DMIC3"},
1532 {"TX SMIC MUX2", "SWR_DMIC4", "TX SWR_DMIC4"},
1533 {"TX SMIC MUX2", "SWR_DMIC5", "TX SWR_DMIC5"},
1534 {"TX SMIC MUX2", "SWR_DMIC6", "TX SWR_DMIC6"},
1535 {"TX SMIC MUX2", "SWR_DMIC7", "TX SWR_DMIC7"},
1536
1537 {"TX DEC3 MUX", "MSM_DMIC", "TX DMIC MUX3"},
1538 {"TX DMIC MUX3", "DMIC0", "TX DMIC0"},
1539 {"TX DMIC MUX3", "DMIC1", "TX DMIC1"},
1540 {"TX DMIC MUX3", "DMIC2", "TX DMIC2"},
1541 {"TX DMIC MUX3", "DMIC3", "TX DMIC3"},
1542 {"TX DMIC MUX3", "DMIC4", "TX DMIC4"},
1543 {"TX DMIC MUX3", "DMIC5", "TX DMIC5"},
1544 {"TX DMIC MUX3", "DMIC6", "TX DMIC6"},
1545 {"TX DMIC MUX3", "DMIC7", "TX DMIC7"},
1546
1547 {"TX DEC3 MUX", "SWR_MIC", "TX SMIC MUX3"},
Sudheer Papothie456c2c2019-03-05 07:08:45 +05301548 {"TX SMIC MUX3", NULL, "TX_SWR_CLK"},
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301549 {"TX SMIC MUX3", "ADC0", "TX SWR_ADC0"},
1550 {"TX SMIC MUX3", "ADC1", "TX SWR_ADC1"},
1551 {"TX SMIC MUX3", "ADC2", "TX SWR_ADC2"},
1552 {"TX SMIC MUX3", "ADC3", "TX SWR_ADC3"},
1553 {"TX SMIC MUX3", "SWR_DMIC0", "TX SWR_DMIC0"},
1554 {"TX SMIC MUX3", "SWR_DMIC1", "TX SWR_DMIC1"},
1555 {"TX SMIC MUX3", "SWR_DMIC2", "TX SWR_DMIC2"},
1556 {"TX SMIC MUX3", "SWR_DMIC3", "TX SWR_DMIC3"},
1557 {"TX SMIC MUX3", "SWR_DMIC4", "TX SWR_DMIC4"},
1558 {"TX SMIC MUX3", "SWR_DMIC5", "TX SWR_DMIC5"},
1559 {"TX SMIC MUX3", "SWR_DMIC6", "TX SWR_DMIC6"},
1560 {"TX SMIC MUX3", "SWR_DMIC7", "TX SWR_DMIC7"},
1561
1562 {"TX DEC4 MUX", "MSM_DMIC", "TX DMIC MUX4"},
1563 {"TX DMIC MUX4", "DMIC0", "TX DMIC0"},
1564 {"TX DMIC MUX4", "DMIC1", "TX DMIC1"},
1565 {"TX DMIC MUX4", "DMIC2", "TX DMIC2"},
1566 {"TX DMIC MUX4", "DMIC3", "TX DMIC3"},
1567 {"TX DMIC MUX4", "DMIC4", "TX DMIC4"},
1568 {"TX DMIC MUX4", "DMIC5", "TX DMIC5"},
1569 {"TX DMIC MUX4", "DMIC6", "TX DMIC6"},
1570 {"TX DMIC MUX4", "DMIC7", "TX DMIC7"},
1571
1572 {"TX DEC4 MUX", "SWR_MIC", "TX SMIC MUX4"},
Sudheer Papothie456c2c2019-03-05 07:08:45 +05301573 {"TX SMIC MUX4", NULL, "TX_SWR_CLK"},
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301574 {"TX SMIC MUX4", "ADC0", "TX SWR_ADC0"},
1575 {"TX SMIC MUX4", "ADC1", "TX SWR_ADC1"},
1576 {"TX SMIC MUX4", "ADC2", "TX SWR_ADC2"},
1577 {"TX SMIC MUX4", "ADC3", "TX SWR_ADC3"},
1578 {"TX SMIC MUX4", "SWR_DMIC0", "TX SWR_DMIC0"},
1579 {"TX SMIC MUX4", "SWR_DMIC1", "TX SWR_DMIC1"},
1580 {"TX SMIC MUX4", "SWR_DMIC2", "TX SWR_DMIC2"},
1581 {"TX SMIC MUX4", "SWR_DMIC3", "TX SWR_DMIC3"},
1582 {"TX SMIC MUX4", "SWR_DMIC4", "TX SWR_DMIC4"},
1583 {"TX SMIC MUX4", "SWR_DMIC5", "TX SWR_DMIC5"},
1584 {"TX SMIC MUX4", "SWR_DMIC6", "TX SWR_DMIC6"},
1585 {"TX SMIC MUX4", "SWR_DMIC7", "TX SWR_DMIC7"},
1586
1587 {"TX DEC5 MUX", "MSM_DMIC", "TX DMIC MUX5"},
1588 {"TX DMIC MUX5", "DMIC0", "TX DMIC0"},
1589 {"TX DMIC MUX5", "DMIC1", "TX DMIC1"},
1590 {"TX DMIC MUX5", "DMIC2", "TX DMIC2"},
1591 {"TX DMIC MUX5", "DMIC3", "TX DMIC3"},
1592 {"TX DMIC MUX5", "DMIC4", "TX DMIC4"},
1593 {"TX DMIC MUX5", "DMIC5", "TX DMIC5"},
1594 {"TX DMIC MUX5", "DMIC6", "TX DMIC6"},
1595 {"TX DMIC MUX5", "DMIC7", "TX DMIC7"},
1596
1597 {"TX DEC5 MUX", "SWR_MIC", "TX SMIC MUX5"},
Sudheer Papothie456c2c2019-03-05 07:08:45 +05301598 {"TX SMIC MUX5", NULL, "TX_SWR_CLK"},
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301599 {"TX SMIC MUX5", "ADC0", "TX SWR_ADC0"},
1600 {"TX SMIC MUX5", "ADC1", "TX SWR_ADC1"},
1601 {"TX SMIC MUX5", "ADC2", "TX SWR_ADC2"},
1602 {"TX SMIC MUX5", "ADC3", "TX SWR_ADC3"},
1603 {"TX SMIC MUX5", "SWR_DMIC0", "TX SWR_DMIC0"},
1604 {"TX SMIC MUX5", "SWR_DMIC1", "TX SWR_DMIC1"},
1605 {"TX SMIC MUX5", "SWR_DMIC2", "TX SWR_DMIC2"},
1606 {"TX SMIC MUX5", "SWR_DMIC3", "TX SWR_DMIC3"},
1607 {"TX SMIC MUX5", "SWR_DMIC4", "TX SWR_DMIC4"},
1608 {"TX SMIC MUX5", "SWR_DMIC5", "TX SWR_DMIC5"},
1609 {"TX SMIC MUX5", "SWR_DMIC6", "TX SWR_DMIC6"},
1610 {"TX SMIC MUX5", "SWR_DMIC7", "TX SWR_DMIC7"},
1611
1612 {"TX DEC6 MUX", "MSM_DMIC", "TX DMIC MUX6"},
1613 {"TX DMIC MUX6", "DMIC0", "TX DMIC0"},
1614 {"TX DMIC MUX6", "DMIC1", "TX DMIC1"},
1615 {"TX DMIC MUX6", "DMIC2", "TX DMIC2"},
1616 {"TX DMIC MUX6", "DMIC3", "TX DMIC3"},
1617 {"TX DMIC MUX6", "DMIC4", "TX DMIC4"},
1618 {"TX DMIC MUX6", "DMIC5", "TX DMIC5"},
1619 {"TX DMIC MUX6", "DMIC6", "TX DMIC6"},
1620 {"TX DMIC MUX6", "DMIC7", "TX DMIC7"},
1621
1622 {"TX DEC6 MUX", "SWR_MIC", "TX SMIC MUX6"},
Sudheer Papothie456c2c2019-03-05 07:08:45 +05301623 {"TX SMIC MUX6", NULL, "TX_SWR_CLK"},
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301624 {"TX SMIC MUX6", "ADC0", "TX SWR_ADC0"},
1625 {"TX SMIC MUX6", "ADC1", "TX SWR_ADC1"},
1626 {"TX SMIC MUX6", "ADC2", "TX SWR_ADC2"},
1627 {"TX SMIC MUX6", "ADC3", "TX SWR_ADC3"},
1628 {"TX SMIC MUX6", "SWR_DMIC0", "TX SWR_DMIC0"},
1629 {"TX SMIC MUX6", "SWR_DMIC1", "TX SWR_DMIC1"},
1630 {"TX SMIC MUX6", "SWR_DMIC2", "TX SWR_DMIC2"},
1631 {"TX SMIC MUX6", "SWR_DMIC3", "TX SWR_DMIC3"},
1632 {"TX SMIC MUX6", "SWR_DMIC4", "TX SWR_DMIC4"},
1633 {"TX SMIC MUX6", "SWR_DMIC5", "TX SWR_DMIC5"},
1634 {"TX SMIC MUX6", "SWR_DMIC6", "TX SWR_DMIC6"},
1635 {"TX SMIC MUX6", "SWR_DMIC7", "TX SWR_DMIC7"},
1636
1637 {"TX DEC7 MUX", "MSM_DMIC", "TX DMIC MUX7"},
1638 {"TX DMIC MUX7", "DMIC0", "TX DMIC0"},
1639 {"TX DMIC MUX7", "DMIC1", "TX DMIC1"},
1640 {"TX DMIC MUX7", "DMIC2", "TX DMIC2"},
1641 {"TX DMIC MUX7", "DMIC3", "TX DMIC3"},
1642 {"TX DMIC MUX7", "DMIC4", "TX DMIC4"},
1643 {"TX DMIC MUX7", "DMIC5", "TX DMIC5"},
1644 {"TX DMIC MUX7", "DMIC6", "TX DMIC6"},
1645 {"TX DMIC MUX7", "DMIC7", "TX DMIC7"},
1646
1647 {"TX DEC7 MUX", "SWR_MIC", "TX SMIC MUX7"},
Sudheer Papothie456c2c2019-03-05 07:08:45 +05301648 {"TX SMIC MUX7", NULL, "TX_SWR_CLK"},
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301649 {"TX SMIC MUX7", "ADC0", "TX SWR_ADC0"},
1650 {"TX SMIC MUX7", "ADC1", "TX SWR_ADC1"},
1651 {"TX SMIC MUX7", "ADC2", "TX SWR_ADC2"},
1652 {"TX SMIC MUX7", "ADC3", "TX SWR_ADC3"},
1653 {"TX SMIC MUX7", "SWR_DMIC0", "TX SWR_DMIC0"},
1654 {"TX SMIC MUX7", "SWR_DMIC1", "TX SWR_DMIC1"},
1655 {"TX SMIC MUX7", "SWR_DMIC2", "TX SWR_DMIC2"},
1656 {"TX SMIC MUX7", "SWR_DMIC3", "TX SWR_DMIC3"},
1657 {"TX SMIC MUX7", "SWR_DMIC4", "TX SWR_DMIC4"},
1658 {"TX SMIC MUX7", "SWR_DMIC5", "TX SWR_DMIC5"},
1659 {"TX SMIC MUX7", "SWR_DMIC6", "TX SWR_DMIC6"},
1660 {"TX SMIC MUX7", "SWR_DMIC7", "TX SWR_DMIC7"},
1661};
1662
1663static const struct snd_kcontrol_new tx_macro_snd_controls[] = {
1664 SOC_SINGLE_SX_TLV("TX_DEC0 Volume",
1665 BOLERO_CDC_TX0_TX_VOL_CTL,
1666 0, -84, 40, digital_gain),
1667 SOC_SINGLE_SX_TLV("TX_DEC1 Volume",
1668 BOLERO_CDC_TX1_TX_VOL_CTL,
1669 0, -84, 40, digital_gain),
1670 SOC_SINGLE_SX_TLV("TX_DEC2 Volume",
1671 BOLERO_CDC_TX2_TX_VOL_CTL,
1672 0, -84, 40, digital_gain),
1673 SOC_SINGLE_SX_TLV("TX_DEC3 Volume",
1674 BOLERO_CDC_TX3_TX_VOL_CTL,
1675 0, -84, 40, digital_gain),
1676 SOC_SINGLE_SX_TLV("TX_DEC4 Volume",
1677 BOLERO_CDC_TX4_TX_VOL_CTL,
1678 0, -84, 40, digital_gain),
1679 SOC_SINGLE_SX_TLV("TX_DEC5 Volume",
1680 BOLERO_CDC_TX5_TX_VOL_CTL,
1681 0, -84, 40, digital_gain),
1682 SOC_SINGLE_SX_TLV("TX_DEC6 Volume",
1683 BOLERO_CDC_TX6_TX_VOL_CTL,
1684 0, -84, 40, digital_gain),
1685 SOC_SINGLE_SX_TLV("TX_DEC7 Volume",
1686 BOLERO_CDC_TX7_TX_VOL_CTL,
1687 0, -84, 40, digital_gain),
Karthikeyan Mani765eaab2019-07-18 16:27:01 -07001688
Karthikeyan Mani1dcd5a32019-08-22 14:37:13 -07001689 SOC_ENUM_EXT("DEC0 MODE", dec_mode_mux_enum,
1690 tx_macro_dec_mode_get, tx_macro_dec_mode_put),
1691
1692 SOC_ENUM_EXT("DEC1 MODE", dec_mode_mux_enum,
1693 tx_macro_dec_mode_get, tx_macro_dec_mode_put),
1694
1695 SOC_ENUM_EXT("DEC2 MODE", dec_mode_mux_enum,
1696 tx_macro_dec_mode_get, tx_macro_dec_mode_put),
1697
1698 SOC_ENUM_EXT("DEC3 MODE", dec_mode_mux_enum,
1699 tx_macro_dec_mode_get, tx_macro_dec_mode_put),
1700
1701 SOC_ENUM_EXT("DEC4 MODE", dec_mode_mux_enum,
1702 tx_macro_dec_mode_get, tx_macro_dec_mode_put),
1703
1704 SOC_ENUM_EXT("DEC5 MODE", dec_mode_mux_enum,
1705 tx_macro_dec_mode_get, tx_macro_dec_mode_put),
1706
1707 SOC_ENUM_EXT("DEC6 MODE", dec_mode_mux_enum,
1708 tx_macro_dec_mode_get, tx_macro_dec_mode_put),
1709
1710 SOC_ENUM_EXT("DEC7 MODE", dec_mode_mux_enum,
1711 tx_macro_dec_mode_get, tx_macro_dec_mode_put),
1712
Karthikeyan Mani765eaab2019-07-18 16:27:01 -07001713 SOC_SINGLE_EXT("DEC0_BCS Switch", SND_SOC_NOPM, 0, 1, 0,
1714 tx_macro_get_bcs, tx_macro_set_bcs),
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301715};
1716
Sudheer Papothia7397942019-03-19 03:14:23 +05301717static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv,
1718 struct regmap *regmap, int clk_type,
1719 bool enable)
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301720{
Meng Wang69b55c82019-05-29 11:04:29 +08001721 int ret = 0, clk_tx_ret = 0;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301722
Sudheer Papothi7601cc62019-03-30 03:00:52 +05301723 dev_dbg(tx_priv->dev,
1724 "%s: clock type %s, enable: %s tx_mclk_users: %d\n",
Sudheer Papothia7397942019-03-19 03:14:23 +05301725 __func__, (clk_type ? "VA_MCLK" : "TX_MCLK"),
Sudheer Papothi7601cc62019-03-30 03:00:52 +05301726 (enable ? "enable" : "disable"), tx_priv->tx_mclk_users);
Tanya Dixit8530fb92018-09-14 16:01:25 +05301727
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301728 if (enable) {
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301729 if (tx_priv->swr_clk_users == 0)
Karthikeyan Mani01f1ba42019-02-26 18:48:15 -08001730 msm_cdc_pinctrl_select_active_state(
1731 tx_priv->tx_swr_gpio_p);
Sudheer Papothia7397942019-03-19 03:14:23 +05301732
Meng Wang69b55c82019-05-29 11:04:29 +08001733 clk_tx_ret = bolero_clk_rsc_request_clock(tx_priv->dev,
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301734 TX_CORE_CLK,
1735 TX_CORE_CLK,
1736 true);
1737 if (clk_type == TX_MCLK) {
1738 ret = tx_macro_mclk_enable(tx_priv, 1);
1739 if (ret < 0) {
1740 if (tx_priv->swr_clk_users == 0)
1741 msm_cdc_pinctrl_select_sleep_state(
1742 tx_priv->tx_swr_gpio_p);
1743 dev_err_ratelimited(tx_priv->dev,
1744 "%s: request clock enable failed\n",
1745 __func__);
1746 goto done;
1747 }
1748 }
1749 if (clk_type == VA_MCLK) {
Sudheer Papothia7397942019-03-19 03:14:23 +05301750 ret = bolero_clk_rsc_request_clock(tx_priv->dev,
1751 TX_CORE_CLK,
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301752 VA_CORE_CLK,
Sudheer Papothia7397942019-03-19 03:14:23 +05301753 true);
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301754 if (ret < 0) {
1755 if (tx_priv->swr_clk_users == 0)
Sudheer Papothia7397942019-03-19 03:14:23 +05301756 msm_cdc_pinctrl_select_sleep_state(
1757 tx_priv->tx_swr_gpio_p);
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301758 dev_err_ratelimited(tx_priv->dev,
1759 "%s: swr request clk failed\n",
1760 __func__);
1761 goto done;
Sudheer Papothia7397942019-03-19 03:14:23 +05301762 }
Sudheer Papothi296867b2019-06-20 09:24:09 +05301763 bolero_clk_rsc_fs_gen_request(tx_priv->dev,
1764 true);
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301765 if (tx_priv->tx_mclk_users == 0) {
1766 regmap_update_bits(regmap,
1767 BOLERO_CDC_TX_TOP_CSR_FREQ_MCLK,
1768 0x01, 0x01);
1769 regmap_update_bits(regmap,
1770 BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL,
1771 0x01, 0x01);
1772 regmap_update_bits(regmap,
1773 BOLERO_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL,
1774 0x01, 0x01);
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301775 }
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301776 }
1777 if (tx_priv->swr_clk_users == 0) {
Sudheer Papothi7601cc62019-03-30 03:00:52 +05301778 dev_dbg(tx_priv->dev, "%s: reset_swr: %d\n",
1779 __func__, tx_priv->reset_swr);
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05301780 if (tx_priv->reset_swr)
1781 regmap_update_bits(regmap,
1782 BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL,
1783 0x02, 0x02);
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301784 regmap_update_bits(regmap,
1785 BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL,
1786 0x01, 0x01);
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05301787 if (tx_priv->reset_swr)
1788 regmap_update_bits(regmap,
1789 BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL,
1790 0x02, 0x00);
1791 tx_priv->reset_swr = false;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301792 }
Meng Wang69b55c82019-05-29 11:04:29 +08001793 if (!clk_tx_ret)
1794 ret = bolero_clk_rsc_request_clock(tx_priv->dev,
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301795 TX_CORE_CLK,
1796 TX_CORE_CLK,
1797 false);
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301798 tx_priv->swr_clk_users++;
1799 } else {
1800 if (tx_priv->swr_clk_users <= 0) {
Sudheer Papothia7397942019-03-19 03:14:23 +05301801 dev_err_ratelimited(tx_priv->dev,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301802 "tx swrm clock users already 0\n");
1803 tx_priv->swr_clk_users = 0;
Sudheer Papothia7397942019-03-19 03:14:23 +05301804 return 0;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301805 }
Meng Wang69b55c82019-05-29 11:04:29 +08001806 clk_tx_ret = bolero_clk_rsc_request_clock(tx_priv->dev,
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301807 TX_CORE_CLK,
1808 TX_CORE_CLK,
1809 true);
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301810 tx_priv->swr_clk_users--;
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301811 if (tx_priv->swr_clk_users == 0)
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301812 regmap_update_bits(regmap,
1813 BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL,
1814 0x01, 0x00);
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301815 if (clk_type == TX_MCLK)
1816 tx_macro_mclk_enable(tx_priv, 0);
1817 if (clk_type == VA_MCLK) {
1818 if (tx_priv->tx_mclk_users == 0) {
1819 regmap_update_bits(regmap,
1820 BOLERO_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL,
1821 0x01, 0x00);
1822 regmap_update_bits(regmap,
1823 BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL,
1824 0x01, 0x00);
Sudheer Papothia7397942019-03-19 03:14:23 +05301825 }
Sudheer Papothi296867b2019-06-20 09:24:09 +05301826 bolero_clk_rsc_fs_gen_request(tx_priv->dev,
1827 false);
Sudheer Papothia7397942019-03-19 03:14:23 +05301828 ret = bolero_clk_rsc_request_clock(tx_priv->dev,
1829 TX_CORE_CLK,
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301830 VA_CORE_CLK,
Sudheer Papothia7397942019-03-19 03:14:23 +05301831 false);
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301832 if (ret < 0) {
1833 dev_err_ratelimited(tx_priv->dev,
1834 "%s: swr request clk failed\n",
1835 __func__);
1836 goto done;
1837 }
1838 }
Meng Wang69b55c82019-05-29 11:04:29 +08001839 if (!clk_tx_ret)
1840 ret = bolero_clk_rsc_request_clock(tx_priv->dev,
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301841 TX_CORE_CLK,
1842 TX_CORE_CLK,
1843 false);
1844 if (tx_priv->swr_clk_users == 0)
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301845 msm_cdc_pinctrl_select_sleep_state(
1846 tx_priv->tx_swr_gpio_p);
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301847 }
Sudheer Papothia7397942019-03-19 03:14:23 +05301848 return 0;
1849
1850done:
Meng Wang69b55c82019-05-29 11:04:29 +08001851 if (!clk_tx_ret)
1852 bolero_clk_rsc_request_clock(tx_priv->dev,
Sudheer Papothia7397942019-03-19 03:14:23 +05301853 TX_CORE_CLK,
1854 TX_CORE_CLK,
1855 false);
1856 return ret;
1857}
1858
Sudheer Papothi6cc7f522019-06-28 11:04:03 +05301859static int tx_macro_clk_switch(struct snd_soc_component *component)
1860{
1861 struct device *tx_dev = NULL;
1862 struct tx_macro_priv *tx_priv = NULL;
1863 int ret = 0;
1864
1865 if (!component)
1866 return -EINVAL;
1867
1868 tx_dev = bolero_get_device_ptr(component->dev, TX_MACRO);
1869 if (!tx_dev) {
1870 dev_err(component->dev,
1871 "%s: null device for macro!\n", __func__);
1872 return -EINVAL;
1873 }
1874 tx_priv = dev_get_drvdata(tx_dev);
1875 if (!tx_priv) {
1876 dev_err(component->dev,
1877 "%s: priv is null for macro!\n", __func__);
1878 return -EINVAL;
1879 }
1880 if (tx_priv->swr_ctrl_data) {
1881 ret = swrm_wcd_notify(
1882 tx_priv->swr_ctrl_data[0].tx_swr_pdev,
1883 SWR_REQ_CLK_SWITCH, NULL);
1884 }
1885
1886 return ret;
1887}
1888
Sudheer Papothia7397942019-03-19 03:14:23 +05301889static int tx_macro_swrm_clock(void *handle, bool enable)
1890{
1891 struct tx_macro_priv *tx_priv = (struct tx_macro_priv *) handle;
1892 struct regmap *regmap = dev_get_regmap(tx_priv->dev->parent, NULL);
1893 int ret = 0;
1894
1895 if (regmap == NULL) {
1896 dev_err(tx_priv->dev, "%s: regmap is NULL\n", __func__);
1897 return -EINVAL;
1898 }
1899
1900 mutex_lock(&tx_priv->swr_clk_lock);
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301901 dev_dbg(tx_priv->dev,
1902 "%s: swrm clock %s tx_swr_clk_cnt: %d va_swr_clk_cnt: %d\n",
1903 __func__, (enable ? "enable" : "disable"),
1904 tx_priv->tx_swr_clk_cnt, tx_priv->va_swr_clk_cnt);
Sudheer Papothia7397942019-03-19 03:14:23 +05301905
1906 if (enable) {
Sudheer Papothi7601cc62019-03-30 03:00:52 +05301907 pm_runtime_get_sync(tx_priv->dev);
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301908 if (tx_priv->va_swr_clk_cnt && !tx_priv->tx_swr_clk_cnt) {
Sudheer Papothia7397942019-03-19 03:14:23 +05301909 ret = tx_macro_tx_va_mclk_enable(tx_priv, regmap,
1910 VA_MCLK, enable);
1911 if (ret)
1912 goto done;
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301913 tx_priv->va_clk_status++;
Sudheer Papothia7397942019-03-19 03:14:23 +05301914 } else {
Sudheer Papothia7397942019-03-19 03:14:23 +05301915 ret = tx_macro_tx_va_mclk_enable(tx_priv, regmap,
1916 TX_MCLK, enable);
1917 if (ret)
1918 goto done;
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301919 tx_priv->tx_clk_status++;
Sudheer Papothia7397942019-03-19 03:14:23 +05301920 }
Sudheer Papothi7601cc62019-03-30 03:00:52 +05301921 pm_runtime_mark_last_busy(tx_priv->dev);
1922 pm_runtime_put_autosuspend(tx_priv->dev);
Sudheer Papothia7397942019-03-19 03:14:23 +05301923 } else {
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301924 if (tx_priv->va_clk_status && !tx_priv->tx_clk_status) {
Sudheer Papothia7397942019-03-19 03:14:23 +05301925 ret = tx_macro_tx_va_mclk_enable(tx_priv, regmap,
1926 VA_MCLK, enable);
1927 if (ret)
1928 goto done;
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301929 --tx_priv->va_clk_status;
1930 } else if (!tx_priv->va_clk_status && tx_priv->tx_clk_status) {
Sudheer Papothia7397942019-03-19 03:14:23 +05301931 ret = tx_macro_tx_va_mclk_enable(tx_priv, regmap,
1932 TX_MCLK, enable);
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301933 if (ret)
1934 goto done;
1935 --tx_priv->tx_clk_status;
1936 } else if (tx_priv->va_clk_status && tx_priv->tx_clk_status) {
1937 if (!tx_priv->va_swr_clk_cnt && tx_priv->tx_swr_clk_cnt) {
1938 ret = tx_macro_tx_va_mclk_enable(tx_priv, regmap,
1939 VA_MCLK, enable);
Sudheer Papothia7397942019-03-19 03:14:23 +05301940 if (ret)
1941 goto done;
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301942 --tx_priv->va_clk_status;
1943 } else {
1944 ret = tx_macro_tx_va_mclk_enable(tx_priv, regmap,
1945 TX_MCLK, enable);
1946 if (ret)
1947 goto done;
1948 --tx_priv->tx_clk_status;
Sudheer Papothia7397942019-03-19 03:14:23 +05301949 }
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301950
1951 } else {
1952 dev_dbg(tx_priv->dev,
1953 "%s: Both clocks are disabled\n", __func__);
Sudheer Papothia7397942019-03-19 03:14:23 +05301954 }
1955 }
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301956
1957 dev_dbg(tx_priv->dev,
1958 "%s: swrm clock users %d tx_clk_sts_cnt: %d va_clk_sts_cnt: %d\n",
1959 __func__, tx_priv->swr_clk_users, tx_priv->tx_clk_status,
1960 tx_priv->va_clk_status);
Sudheer Papothia7397942019-03-19 03:14:23 +05301961done:
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301962 mutex_unlock(&tx_priv->swr_clk_lock);
1963 return ret;
1964}
1965
1966static int tx_macro_validate_dmic_sample_rate(u32 dmic_sample_rate,
1967 struct tx_macro_priv *tx_priv)
1968{
1969 u32 div_factor = TX_MACRO_CLK_DIV_2;
1970 u32 mclk_rate = TX_MACRO_MCLK_FREQ;
1971
1972 if (dmic_sample_rate == TX_MACRO_DMIC_SAMPLE_RATE_UNDEFINED ||
1973 mclk_rate % dmic_sample_rate != 0)
1974 goto undefined_rate;
1975
1976 div_factor = mclk_rate / dmic_sample_rate;
1977
1978 switch (div_factor) {
1979 case 2:
1980 tx_priv->dmic_clk_div = TX_MACRO_CLK_DIV_2;
1981 break;
1982 case 3:
1983 tx_priv->dmic_clk_div = TX_MACRO_CLK_DIV_3;
1984 break;
1985 case 4:
1986 tx_priv->dmic_clk_div = TX_MACRO_CLK_DIV_4;
1987 break;
1988 case 6:
1989 tx_priv->dmic_clk_div = TX_MACRO_CLK_DIV_6;
1990 break;
1991 case 8:
1992 tx_priv->dmic_clk_div = TX_MACRO_CLK_DIV_8;
1993 break;
1994 case 16:
1995 tx_priv->dmic_clk_div = TX_MACRO_CLK_DIV_16;
1996 break;
1997 default:
1998 /* Any other DIV factor is invalid */
1999 goto undefined_rate;
2000 }
2001
2002 /* Valid dmic DIV factors */
2003 dev_dbg(tx_priv->dev, "%s: DMIC_DIV = %u, mclk_rate = %u\n",
2004 __func__, div_factor, mclk_rate);
2005
2006 return dmic_sample_rate;
2007
2008undefined_rate:
2009 dev_dbg(tx_priv->dev, "%s: Invalid rate %d, for mclk %d\n",
2010 __func__, dmic_sample_rate, mclk_rate);
2011 dmic_sample_rate = TX_MACRO_DMIC_SAMPLE_RATE_UNDEFINED;
2012
2013 return dmic_sample_rate;
2014}
2015
Meng Wang15c825d2018-09-06 10:49:18 +08002016static int tx_macro_init(struct snd_soc_component *component)
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302017{
Meng Wang15c825d2018-09-06 10:49:18 +08002018 struct snd_soc_dapm_context *dapm =
2019 snd_soc_component_get_dapm(component);
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302020 int ret = 0, i = 0;
2021 struct device *tx_dev = NULL;
2022 struct tx_macro_priv *tx_priv = NULL;
2023
Meng Wang15c825d2018-09-06 10:49:18 +08002024 tx_dev = bolero_get_device_ptr(component->dev, TX_MACRO);
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302025 if (!tx_dev) {
Meng Wang15c825d2018-09-06 10:49:18 +08002026 dev_err(component->dev,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302027 "%s: null device for macro!\n", __func__);
2028 return -EINVAL;
2029 }
2030 tx_priv = dev_get_drvdata(tx_dev);
2031 if (!tx_priv) {
Meng Wang15c825d2018-09-06 10:49:18 +08002032 dev_err(component->dev,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302033 "%s: priv is null for macro!\n", __func__);
2034 return -EINVAL;
2035 }
2036 ret = snd_soc_dapm_new_controls(dapm, tx_macro_dapm_widgets,
2037 ARRAY_SIZE(tx_macro_dapm_widgets));
2038 if (ret < 0) {
2039 dev_err(tx_dev, "%s: Failed to add controls\n", __func__);
2040 return ret;
2041 }
2042
2043 ret = snd_soc_dapm_add_routes(dapm, tx_audio_map,
2044 ARRAY_SIZE(tx_audio_map));
2045 if (ret < 0) {
2046 dev_err(tx_dev, "%s: Failed to add routes\n", __func__);
2047 return ret;
2048 }
2049
2050 ret = snd_soc_dapm_new_widgets(dapm->card);
2051 if (ret < 0) {
2052 dev_err(tx_dev, "%s: Failed to add widgets\n", __func__);
2053 return ret;
2054 }
2055
Meng Wang15c825d2018-09-06 10:49:18 +08002056 ret = snd_soc_add_component_controls(component, tx_macro_snd_controls,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302057 ARRAY_SIZE(tx_macro_snd_controls));
2058 if (ret < 0) {
2059 dev_err(tx_dev, "%s: Failed to add snd_ctls\n", __func__);
2060 return ret;
2061 }
Laxminath Kasam638b5602018-09-24 13:19:52 +05302062
2063 snd_soc_dapm_ignore_suspend(dapm, "TX_AIF1 Capture");
2064 snd_soc_dapm_ignore_suspend(dapm, "TX_AIF2 Capture");
Karthikeyan Manif3bb8182019-07-11 14:38:54 -07002065 snd_soc_dapm_ignore_suspend(dapm, "TX_AIF3 Capture");
Laxminath Kasam638b5602018-09-24 13:19:52 +05302066 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC0");
2067 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC1");
2068 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC2");
2069 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC3");
Vatsal Bucha39ead2c2018-12-14 12:22:46 +05302070 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC0");
2071 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC1");
2072 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC2");
2073 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC3");
2074 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC4");
2075 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC5");
2076 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC6");
2077 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC7");
Laxminath Kasam638b5602018-09-24 13:19:52 +05302078 snd_soc_dapm_sync(dapm);
2079
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302080 for (i = 0; i < NUM_DECIMATORS; i++) {
2081 tx_priv->tx_hpf_work[i].tx_priv = tx_priv;
2082 tx_priv->tx_hpf_work[i].decimator = i;
2083 INIT_DELAYED_WORK(&tx_priv->tx_hpf_work[i].dwork,
2084 tx_macro_tx_hpf_corner_freq_callback);
2085 }
2086
2087 for (i = 0; i < NUM_DECIMATORS; i++) {
2088 tx_priv->tx_mute_dwork[i].tx_priv = tx_priv;
2089 tx_priv->tx_mute_dwork[i].decimator = i;
2090 INIT_DELAYED_WORK(&tx_priv->tx_mute_dwork[i].dwork,
2091 tx_macro_mute_update_callback);
2092 }
Meng Wang15c825d2018-09-06 10:49:18 +08002093 tx_priv->component = component;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302094
Karthikeyan Mani765eaab2019-07-18 16:27:01 -07002095 snd_soc_component_update_bits(component,
2096 BOLERO_CDC_TX0_TX_PATH_SEC7, 0x3F, 0x0E);
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302097 return 0;
2098}
2099
Meng Wang15c825d2018-09-06 10:49:18 +08002100static int tx_macro_deinit(struct snd_soc_component *component)
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302101{
2102 struct device *tx_dev = NULL;
2103 struct tx_macro_priv *tx_priv = NULL;
2104
Meng Wang15c825d2018-09-06 10:49:18 +08002105 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302106 return -EINVAL;
2107
Meng Wang15c825d2018-09-06 10:49:18 +08002108 tx_priv->component = NULL;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302109 return 0;
2110}
2111
2112static void tx_macro_add_child_devices(struct work_struct *work)
2113{
2114 struct tx_macro_priv *tx_priv = NULL;
2115 struct platform_device *pdev = NULL;
2116 struct device_node *node = NULL;
2117 struct tx_macro_swr_ctrl_data *swr_ctrl_data = NULL, *temp = NULL;
2118 int ret = 0;
2119 u16 count = 0, ctrl_num = 0;
2120 struct tx_macro_swr_ctrl_platform_data *platdata = NULL;
2121 char plat_dev_name[TX_MACRO_SWR_STRING_LEN] = "";
2122 bool tx_swr_master_node = false;
2123
2124 tx_priv = container_of(work, struct tx_macro_priv,
2125 tx_macro_add_child_devices_work);
2126 if (!tx_priv) {
2127 pr_err("%s: Memory for tx_priv does not exist\n",
2128 __func__);
2129 return;
2130 }
2131
2132 if (!tx_priv->dev) {
2133 pr_err("%s: tx dev does not exist\n", __func__);
2134 return;
2135 }
2136
2137 if (!tx_priv->dev->of_node) {
2138 dev_err(tx_priv->dev,
2139 "%s: DT node for tx_priv does not exist\n", __func__);
2140 return;
2141 }
2142
2143 platdata = &tx_priv->swr_plat_data;
2144 tx_priv->child_count = 0;
2145
2146 for_each_available_child_of_node(tx_priv->dev->of_node, node) {
2147 tx_swr_master_node = false;
2148 if (strnstr(node->name, "tx_swr_master",
2149 strlen("tx_swr_master")) != NULL)
2150 tx_swr_master_node = true;
2151
2152 if (tx_swr_master_node)
2153 strlcpy(plat_dev_name, "tx_swr_ctrl",
2154 (TX_MACRO_SWR_STRING_LEN - 1));
2155 else
2156 strlcpy(plat_dev_name, node->name,
2157 (TX_MACRO_SWR_STRING_LEN - 1));
2158
2159 pdev = platform_device_alloc(plat_dev_name, -1);
2160 if (!pdev) {
2161 dev_err(tx_priv->dev, "%s: pdev memory alloc failed\n",
2162 __func__);
2163 ret = -ENOMEM;
2164 goto err;
2165 }
2166 pdev->dev.parent = tx_priv->dev;
2167 pdev->dev.of_node = node;
2168
2169 if (tx_swr_master_node) {
2170 ret = platform_device_add_data(pdev, platdata,
2171 sizeof(*platdata));
2172 if (ret) {
2173 dev_err(&pdev->dev,
2174 "%s: cannot add plat data ctrl:%d\n",
2175 __func__, ctrl_num);
2176 goto fail_pdev_add;
2177 }
2178 }
2179
2180 ret = platform_device_add(pdev);
2181 if (ret) {
2182 dev_err(&pdev->dev,
2183 "%s: Cannot add platform device\n",
2184 __func__);
2185 goto fail_pdev_add;
2186 }
2187
2188 if (tx_swr_master_node) {
2189 temp = krealloc(swr_ctrl_data,
2190 (ctrl_num + 1) * sizeof(
2191 struct tx_macro_swr_ctrl_data),
2192 GFP_KERNEL);
2193 if (!temp) {
2194 ret = -ENOMEM;
2195 goto fail_pdev_add;
2196 }
2197 swr_ctrl_data = temp;
2198 swr_ctrl_data[ctrl_num].tx_swr_pdev = pdev;
2199 ctrl_num++;
2200 dev_dbg(&pdev->dev,
2201 "%s: Added soundwire ctrl device(s)\n",
2202 __func__);
2203 tx_priv->swr_ctrl_data = swr_ctrl_data;
2204 }
2205 if (tx_priv->child_count < TX_MACRO_CHILD_DEVICES_MAX)
2206 tx_priv->pdev_child_devices[
2207 tx_priv->child_count++] = pdev;
2208 else
2209 goto err;
2210 }
2211 return;
2212fail_pdev_add:
2213 for (count = 0; count < tx_priv->child_count; count++)
2214 platform_device_put(tx_priv->pdev_child_devices[count]);
2215err:
2216 return;
2217}
2218
Sudheer Papothia3e969d2018-10-27 06:22:10 +05302219static int tx_macro_set_port_map(struct snd_soc_component *component,
2220 u32 usecase, u32 size, void *data)
2221{
2222 struct device *tx_dev = NULL;
2223 struct tx_macro_priv *tx_priv = NULL;
2224 struct swrm_port_config port_cfg;
2225 int ret = 0;
2226
2227 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
2228 return -EINVAL;
2229
2230 memset(&port_cfg, 0, sizeof(port_cfg));
2231 port_cfg.uc = usecase;
2232 port_cfg.size = size;
2233 port_cfg.params = data;
2234
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07002235 if (tx_priv->swr_ctrl_data)
2236 ret = swrm_wcd_notify(
2237 tx_priv->swr_ctrl_data[0].tx_swr_pdev,
2238 SWR_SET_PORT_MAP, &port_cfg);
Sudheer Papothia3e969d2018-10-27 06:22:10 +05302239
2240 return ret;
2241}
2242
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302243static void tx_macro_init_ops(struct macro_ops *ops,
2244 char __iomem *tx_io_base)
2245{
2246 memset(ops, 0, sizeof(struct macro_ops));
2247 ops->init = tx_macro_init;
2248 ops->exit = tx_macro_deinit;
2249 ops->io_base = tx_io_base;
2250 ops->dai_ptr = tx_macro_dai;
2251 ops->num_dais = ARRAY_SIZE(tx_macro_dai);
Laxminath Kasamfb0d6832018-09-22 01:49:52 +05302252 ops->event_handler = tx_macro_event_handler;
Aditya Bavanaric4e96122018-11-14 14:46:38 +05302253 ops->reg_wake_irq = tx_macro_reg_wake_irq;
Sudheer Papothia3e969d2018-10-27 06:22:10 +05302254 ops->set_port_map = tx_macro_set_port_map;
Sudheer Papothi6cc7f522019-06-28 11:04:03 +05302255 ops->clk_switch = tx_macro_clk_switch;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302256}
2257
2258static int tx_macro_probe(struct platform_device *pdev)
2259{
2260 struct macro_ops ops = {0};
2261 struct tx_macro_priv *tx_priv = NULL;
2262 u32 tx_base_addr = 0, sample_rate = 0;
2263 char __iomem *tx_io_base = NULL;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302264 int ret = 0;
2265 const char *dmic_sample_rate = "qcom,tx-dmic-sample-rate";
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07002266 u32 is_used_tx_swr_gpio = 1;
2267 const char *is_used_tx_swr_gpio_dt = "qcom,is-used-swr-gpio";
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302268
2269 tx_priv = devm_kzalloc(&pdev->dev, sizeof(struct tx_macro_priv),
2270 GFP_KERNEL);
2271 if (!tx_priv)
2272 return -ENOMEM;
2273 platform_set_drvdata(pdev, tx_priv);
2274
2275 tx_priv->dev = &pdev->dev;
2276 ret = of_property_read_u32(pdev->dev.of_node, "reg",
2277 &tx_base_addr);
2278 if (ret) {
2279 dev_err(&pdev->dev, "%s: could not find %s entry in dt\n",
2280 __func__, "reg");
2281 return ret;
2282 }
2283 dev_set_drvdata(&pdev->dev, tx_priv);
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07002284 if (of_find_property(pdev->dev.of_node, is_used_tx_swr_gpio_dt,
2285 NULL)) {
2286 ret = of_property_read_u32(pdev->dev.of_node,
2287 is_used_tx_swr_gpio_dt,
2288 &is_used_tx_swr_gpio);
2289 if (ret) {
2290 dev_err(&pdev->dev, "%s: error reading %s in dt\n",
2291 __func__, is_used_tx_swr_gpio_dt);
2292 is_used_tx_swr_gpio = 1;
2293 }
2294 }
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302295 tx_priv->tx_swr_gpio_p = of_parse_phandle(pdev->dev.of_node,
2296 "qcom,tx-swr-gpios", 0);
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07002297 if (!tx_priv->tx_swr_gpio_p && is_used_tx_swr_gpio) {
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302298 dev_err(&pdev->dev, "%s: swr_gpios handle not provided!\n",
2299 __func__);
2300 return -EINVAL;
2301 }
Karthikeyan Mani326536d2019-06-03 13:29:43 -07002302 if (msm_cdc_pinctrl_get_state(tx_priv->tx_swr_gpio_p) < 0) {
2303 dev_err(&pdev->dev, "%s: failed to get swr pin state\n",
2304 __func__);
2305 return -EPROBE_DEFER;
2306 }
2307
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302308 tx_io_base = devm_ioremap(&pdev->dev,
2309 tx_base_addr, TX_MACRO_MAX_OFFSET);
2310 if (!tx_io_base) {
2311 dev_err(&pdev->dev, "%s: ioremap failed\n", __func__);
2312 return -ENOMEM;
2313 }
2314 tx_priv->tx_io_base = tx_io_base;
2315 ret = of_property_read_u32(pdev->dev.of_node, dmic_sample_rate,
2316 &sample_rate);
2317 if (ret) {
2318 dev_err(&pdev->dev,
2319 "%s: could not find sample_rate entry in dt\n",
2320 __func__);
2321 tx_priv->dmic_clk_div = TX_MACRO_CLK_DIV_2;
2322 } else {
2323 if (tx_macro_validate_dmic_sample_rate(
2324 sample_rate, tx_priv) == TX_MACRO_DMIC_SAMPLE_RATE_UNDEFINED)
2325 return -EINVAL;
2326 }
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05302327 tx_priv->reset_swr = true;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302328 INIT_WORK(&tx_priv->tx_macro_add_child_devices_work,
2329 tx_macro_add_child_devices);
2330 tx_priv->swr_plat_data.handle = (void *) tx_priv;
2331 tx_priv->swr_plat_data.read = NULL;
2332 tx_priv->swr_plat_data.write = NULL;
2333 tx_priv->swr_plat_data.bulk_write = NULL;
2334 tx_priv->swr_plat_data.clk = tx_macro_swrm_clock;
2335 tx_priv->swr_plat_data.handle_irq = NULL;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302336
2337 mutex_init(&tx_priv->mclk_lock);
2338 mutex_init(&tx_priv->swr_clk_lock);
2339 tx_macro_init_ops(&ops, tx_io_base);
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07002340 ops.clk_id_req = TX_CORE_CLK;
2341 ops.default_clk_id = TX_CORE_CLK;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302342 ret = bolero_register_macro(&pdev->dev, TX_MACRO, &ops);
2343 if (ret) {
2344 dev_err(&pdev->dev,
2345 "%s: register macro failed\n", __func__);
2346 goto err_reg_macro;
2347 }
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07002348
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302349 schedule_work(&tx_priv->tx_macro_add_child_devices_work);
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302350 pm_runtime_set_autosuspend_delay(&pdev->dev, AUTO_SUSPEND_DELAY);
2351 pm_runtime_use_autosuspend(&pdev->dev);
2352 pm_runtime_set_suspended(&pdev->dev);
Sudheer Papothi296867b2019-06-20 09:24:09 +05302353 pm_suspend_ignore_children(&pdev->dev, true);
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302354 pm_runtime_enable(&pdev->dev);
2355
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302356 return 0;
2357err_reg_macro:
2358 mutex_destroy(&tx_priv->mclk_lock);
2359 mutex_destroy(&tx_priv->swr_clk_lock);
2360 return ret;
2361}
2362
2363static int tx_macro_remove(struct platform_device *pdev)
2364{
2365 struct tx_macro_priv *tx_priv = NULL;
2366 u16 count = 0;
2367
2368 tx_priv = platform_get_drvdata(pdev);
2369
2370 if (!tx_priv)
2371 return -EINVAL;
2372
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07002373 if (tx_priv->swr_ctrl_data)
2374 kfree(tx_priv->swr_ctrl_data);
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302375 for (count = 0; count < tx_priv->child_count &&
2376 count < TX_MACRO_CHILD_DEVICES_MAX; count++)
2377 platform_device_unregister(tx_priv->pdev_child_devices[count]);
2378
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302379 pm_runtime_disable(&pdev->dev);
2380 pm_runtime_set_suspended(&pdev->dev);
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302381 mutex_destroy(&tx_priv->mclk_lock);
2382 mutex_destroy(&tx_priv->swr_clk_lock);
2383 bolero_unregister_macro(&pdev->dev, TX_MACRO);
2384 return 0;
2385}
2386
2387
2388static const struct of_device_id tx_macro_dt_match[] = {
2389 {.compatible = "qcom,tx-macro"},
2390 {}
2391};
2392
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302393static const struct dev_pm_ops bolero_dev_pm_ops = {
2394 SET_RUNTIME_PM_OPS(
2395 bolero_runtime_suspend,
2396 bolero_runtime_resume,
2397 NULL
2398 )
2399};
2400
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302401static struct platform_driver tx_macro_driver = {
2402 .driver = {
2403 .name = "tx_macro",
2404 .owner = THIS_MODULE,
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302405 .pm = &bolero_dev_pm_ops,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302406 .of_match_table = tx_macro_dt_match,
Xiaojun Sang53cd13a2018-06-29 15:14:37 +08002407 .suppress_bind_attrs = true,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302408 },
2409 .probe = tx_macro_probe,
2410 .remove = tx_macro_remove,
2411};
2412
2413module_platform_driver(tx_macro_driver);
2414
2415MODULE_DESCRIPTION("TX macro driver");
2416MODULE_LICENSE("GPL v2");