blob: 45afd304dc813623015fdcb6a0a319163f6e265b [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
Sudheer Papothi72fef482019-08-30 11:00:20 +0530122struct tx_macro_reg_mask_val {
123 u16 reg;
124 u8 mask;
125 u8 val;
126};
127
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530128struct tx_mute_work {
129 struct tx_macro_priv *tx_priv;
130 u32 decimator;
131 struct delayed_work dwork;
132};
133
134struct hpf_work {
135 struct tx_macro_priv *tx_priv;
136 u8 decimator;
137 u8 hpf_cut_off_freq;
138 struct delayed_work dwork;
139};
140
141struct tx_macro_priv {
142 struct device *dev;
143 bool dec_active[NUM_DECIMATORS];
144 int tx_mclk_users;
145 int swr_clk_users;
Ramprasad Katkam452772a2019-01-07 17:30:36 +0530146 bool dapm_mclk_enable;
Ramprasad Katkama4c747b2018-12-11 19:15:53 +0530147 bool reset_swr;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530148 struct mutex mclk_lock;
149 struct mutex swr_clk_lock;
Meng Wang15c825d2018-09-06 10:49:18 +0800150 struct snd_soc_component *component;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530151 struct device_node *tx_swr_gpio_p;
152 struct tx_macro_swr_ctrl_data *swr_ctrl_data;
153 struct tx_macro_swr_ctrl_platform_data swr_plat_data;
154 struct work_struct tx_macro_add_child_devices_work;
155 struct hpf_work tx_hpf_work[NUM_DECIMATORS];
156 struct tx_mute_work tx_mute_dwork[NUM_DECIMATORS];
157 s32 dmic_0_1_clk_cnt;
158 s32 dmic_2_3_clk_cnt;
159 s32 dmic_4_5_clk_cnt;
160 s32 dmic_6_7_clk_cnt;
161 u16 dmic_clk_div;
162 unsigned long active_ch_mask[TX_MACRO_MAX_DAIS];
163 unsigned long active_ch_cnt[TX_MACRO_MAX_DAIS];
164 char __iomem *tx_io_base;
165 struct platform_device *pdev_child_devices
166 [TX_MACRO_CHILD_DEVICES_MAX];
167 int child_count;
Sudheer Papothie456c2c2019-03-05 07:08:45 +0530168 int tx_swr_clk_cnt;
169 int va_swr_clk_cnt;
Sudheer Papothicf3b4062019-05-10 10:48:43 +0530170 int va_clk_status;
171 int tx_clk_status;
Karthikeyan Mani765eaab2019-07-18 16:27:01 -0700172 bool bcs_enable;
Karthikeyan Mani1dcd5a32019-08-22 14:37:13 -0700173 int dec_mode[NUM_DECIMATORS];
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530174};
175
Meng Wang15c825d2018-09-06 10:49:18 +0800176static bool tx_macro_get_data(struct snd_soc_component *component,
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530177 struct device **tx_dev,
178 struct tx_macro_priv **tx_priv,
179 const char *func_name)
180{
Meng Wang15c825d2018-09-06 10:49:18 +0800181 *tx_dev = bolero_get_device_ptr(component->dev, TX_MACRO);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530182 if (!(*tx_dev)) {
Meng Wang15c825d2018-09-06 10:49:18 +0800183 dev_err(component->dev,
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530184 "%s: null device for macro!\n", func_name);
185 return false;
186 }
187
188 *tx_priv = dev_get_drvdata((*tx_dev));
189 if (!(*tx_priv)) {
Meng Wang15c825d2018-09-06 10:49:18 +0800190 dev_err(component->dev,
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530191 "%s: priv is null for macro!\n", func_name);
192 return false;
193 }
194
Meng Wang15c825d2018-09-06 10:49:18 +0800195 if (!(*tx_priv)->component) {
196 dev_err(component->dev,
197 "%s: tx_priv->component not initialized!\n", func_name);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530198 return false;
199 }
200
201 return true;
202}
203
204static int tx_macro_mclk_enable(struct tx_macro_priv *tx_priv,
205 bool mclk_enable)
206{
207 struct regmap *regmap = dev_get_regmap(tx_priv->dev->parent, NULL);
208 int ret = 0;
209
Tanya Dixit8530fb92018-09-14 16:01:25 +0530210 if (regmap == NULL) {
211 dev_err(tx_priv->dev, "%s: regmap is NULL\n", __func__);
212 return -EINVAL;
213 }
214
Laxminath Kasamb7f823c2018-08-02 13:23:11 +0530215 dev_dbg(tx_priv->dev, "%s: mclk_enable = %u,clk_users= %d\n",
216 __func__, mclk_enable, tx_priv->tx_mclk_users);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530217
218 mutex_lock(&tx_priv->mclk_lock);
219 if (mclk_enable) {
220 if (tx_priv->tx_mclk_users == 0) {
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -0700221 ret = bolero_clk_rsc_request_clock(tx_priv->dev,
222 TX_CORE_CLK,
223 TX_CORE_CLK,
224 true);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530225 if (ret < 0) {
Ramprasad Katkam14efed62019-03-07 13:16:50 +0530226 dev_err_ratelimited(tx_priv->dev,
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530227 "%s: request clock enable failed\n",
228 __func__);
229 goto exit;
230 }
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -0700231 bolero_clk_rsc_fs_gen_request(tx_priv->dev,
232 true);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530233 regcache_mark_dirty(regmap);
234 regcache_sync_region(regmap,
235 TX_START_OFFSET,
236 TX_MAX_OFFSET);
237 /* 9.6MHz MCLK, set value 0x00 if other frequency */
238 regmap_update_bits(regmap,
239 BOLERO_CDC_TX_TOP_CSR_FREQ_MCLK, 0x01, 0x01);
240 regmap_update_bits(regmap,
241 BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL,
242 0x01, 0x01);
243 regmap_update_bits(regmap,
244 BOLERO_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL,
245 0x01, 0x01);
246 }
247 tx_priv->tx_mclk_users++;
248 } else {
249 if (tx_priv->tx_mclk_users <= 0) {
250 dev_err(tx_priv->dev, "%s: clock already disabled\n",
251 __func__);
252 tx_priv->tx_mclk_users = 0;
253 goto exit;
254 }
255 tx_priv->tx_mclk_users--;
256 if (tx_priv->tx_mclk_users == 0) {
257 regmap_update_bits(regmap,
258 BOLERO_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL,
259 0x01, 0x00);
260 regmap_update_bits(regmap,
261 BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL,
262 0x01, 0x00);
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -0700263 bolero_clk_rsc_fs_gen_request(tx_priv->dev,
264 false);
265
266 bolero_clk_rsc_request_clock(tx_priv->dev,
267 TX_CORE_CLK,
268 TX_CORE_CLK,
269 false);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530270 }
271 }
272exit:
273 mutex_unlock(&tx_priv->mclk_lock);
274 return ret;
275}
276
Sudheer Papothie456c2c2019-03-05 07:08:45 +0530277static int tx_macro_va_swr_clk_event(struct snd_soc_dapm_widget *w,
278 struct snd_kcontrol *kcontrol, int event)
279{
280 struct device *tx_dev = NULL;
281 struct tx_macro_priv *tx_priv = NULL;
282 struct snd_soc_component *component =
283 snd_soc_dapm_to_component(w->dapm);
284
285 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
286 return -EINVAL;
287
288 if (SND_SOC_DAPM_EVENT_ON(event))
289 ++tx_priv->va_swr_clk_cnt;
290 if (SND_SOC_DAPM_EVENT_OFF(event))
291 --tx_priv->va_swr_clk_cnt;
292
293 return 0;
294}
295
296static int tx_macro_tx_swr_clk_event(struct snd_soc_dapm_widget *w,
297 struct snd_kcontrol *kcontrol, int event)
298{
299 struct device *tx_dev = NULL;
300 struct tx_macro_priv *tx_priv = NULL;
301 struct snd_soc_component *component =
302 snd_soc_dapm_to_component(w->dapm);
303
304 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
305 return -EINVAL;
306
307 if (SND_SOC_DAPM_EVENT_ON(event))
308 ++tx_priv->tx_swr_clk_cnt;
309 if (SND_SOC_DAPM_EVENT_OFF(event))
310 --tx_priv->tx_swr_clk_cnt;
311
312 return 0;
313}
314
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530315static int tx_macro_mclk_event(struct snd_soc_dapm_widget *w,
316 struct snd_kcontrol *kcontrol, int event)
317{
Meng Wang15c825d2018-09-06 10:49:18 +0800318 struct snd_soc_component *component =
319 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530320 int ret = 0;
321 struct device *tx_dev = NULL;
322 struct tx_macro_priv *tx_priv = NULL;
323
Meng Wang15c825d2018-09-06 10:49:18 +0800324 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530325 return -EINVAL;
326
327 dev_dbg(tx_dev, "%s: event = %d\n", __func__, event);
328 switch (event) {
329 case SND_SOC_DAPM_PRE_PMU:
330 ret = tx_macro_mclk_enable(tx_priv, 1);
Ramprasad Katkam452772a2019-01-07 17:30:36 +0530331 if (ret)
332 tx_priv->dapm_mclk_enable = false;
333 else
334 tx_priv->dapm_mclk_enable = true;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530335 break;
336 case SND_SOC_DAPM_POST_PMD:
Ramprasad Katkam452772a2019-01-07 17:30:36 +0530337 if (tx_priv->dapm_mclk_enable)
338 ret = tx_macro_mclk_enable(tx_priv, 0);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530339 break;
340 default:
341 dev_err(tx_priv->dev,
342 "%s: invalid DAPM event %d\n", __func__, event);
343 ret = -EINVAL;
344 }
345 return ret;
346}
347
Meng Wang15c825d2018-09-06 10:49:18 +0800348static int tx_macro_event_handler(struct snd_soc_component *component,
349 u16 event, u32 data)
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530350{
351 struct device *tx_dev = NULL;
352 struct tx_macro_priv *tx_priv = NULL;
Aditya Bavanari50ef13e2019-08-09 15:14:43 +0530353 int ret = 0;
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530354
Meng Wang15c825d2018-09-06 10:49:18 +0800355 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530356 return -EINVAL;
357
358 switch (event) {
359 case BOLERO_MACRO_EVT_SSR_DOWN:
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -0700360 if (tx_priv->swr_ctrl_data) {
361 swrm_wcd_notify(
362 tx_priv->swr_ctrl_data[0].tx_swr_pdev,
363 SWR_DEVICE_DOWN, NULL);
364 swrm_wcd_notify(
365 tx_priv->swr_ctrl_data[0].tx_swr_pdev,
366 SWR_DEVICE_SSR_DOWN, NULL);
367 }
Aditya Bavanari50ef13e2019-08-09 15:14:43 +0530368 if ((!pm_runtime_enabled(tx_dev) ||
369 !pm_runtime_suspended(tx_dev))) {
370 ret = bolero_runtime_suspend(tx_dev);
371 if (!ret) {
372 pm_runtime_disable(tx_dev);
373 pm_runtime_set_suspended(tx_dev);
374 pm_runtime_enable(tx_dev);
375 }
376 }
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530377 break;
378 case BOLERO_MACRO_EVT_SSR_UP:
Ramprasad Katkama4c747b2018-12-11 19:15:53 +0530379 /* reset swr after ssr/pdr */
380 tx_priv->reset_swr = true;
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -0700381 if (tx_priv->swr_ctrl_data)
382 swrm_wcd_notify(
383 tx_priv->swr_ctrl_data[0].tx_swr_pdev,
384 SWR_DEVICE_SSR_UP, NULL);
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530385 break;
Meng Wang8ef0cc22019-05-08 15:12:56 +0800386 case BOLERO_MACRO_EVT_CLK_RESET:
387 bolero_rsc_clk_reset(tx_dev, TX_CORE_CLK);
388 break;
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530389 }
390 return 0;
391}
392
Meng Wang15c825d2018-09-06 10:49:18 +0800393static int tx_macro_reg_wake_irq(struct snd_soc_component *component,
Aditya Bavanaric4e96122018-11-14 14:46:38 +0530394 u32 data)
395{
396 struct device *tx_dev = NULL;
397 struct tx_macro_priv *tx_priv = NULL;
398 u32 ipc_wakeup = data;
399 int ret = 0;
400
Meng Wang15c825d2018-09-06 10:49:18 +0800401 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
Aditya Bavanaric4e96122018-11-14 14:46:38 +0530402 return -EINVAL;
403
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -0700404 if (tx_priv->swr_ctrl_data)
405 ret = swrm_wcd_notify(
406 tx_priv->swr_ctrl_data[0].tx_swr_pdev,
407 SWR_REGISTER_WAKE_IRQ, &ipc_wakeup);
Aditya Bavanaric4e96122018-11-14 14:46:38 +0530408
409 return ret;
410}
411
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530412static void tx_macro_tx_hpf_corner_freq_callback(struct work_struct *work)
413{
414 struct delayed_work *hpf_delayed_work = NULL;
415 struct hpf_work *hpf_work = NULL;
416 struct tx_macro_priv *tx_priv = NULL;
Meng Wang15c825d2018-09-06 10:49:18 +0800417 struct snd_soc_component *component = NULL;
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530418 u16 dec_cfg_reg = 0, hpf_gate_reg = 0;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530419 u8 hpf_cut_off_freq = 0;
Laxminath Kasam497a6512018-09-17 16:11:52 +0530420 u16 adc_mux_reg = 0, adc_n = 0, adc_reg = 0;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530421
422 hpf_delayed_work = to_delayed_work(work);
423 hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork);
424 tx_priv = hpf_work->tx_priv;
Meng Wang15c825d2018-09-06 10:49:18 +0800425 component = tx_priv->component;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530426 hpf_cut_off_freq = hpf_work->hpf_cut_off_freq;
427
428 dec_cfg_reg = BOLERO_CDC_TX0_TX_PATH_CFG0 +
429 TX_MACRO_TX_PATH_OFFSET * hpf_work->decimator;
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530430 hpf_gate_reg = BOLERO_CDC_TX0_TX_PATH_SEC2 +
431 TX_MACRO_TX_PATH_OFFSET * hpf_work->decimator;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530432
Meng Wang15c825d2018-09-06 10:49:18 +0800433 dev_dbg(component->dev, "%s: decimator %u hpf_cut_of_freq 0x%x\n",
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530434 __func__, hpf_work->decimator, hpf_cut_off_freq);
435
Laxminath Kasam497a6512018-09-17 16:11:52 +0530436 adc_mux_reg = BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG1 +
437 TX_MACRO_ADC_MUX_CFG_OFFSET * hpf_work->decimator;
Meng Wang15c825d2018-09-06 10:49:18 +0800438 if (snd_soc_component_read32(component, adc_mux_reg) & SWR_MIC) {
Laxminath Kasam497a6512018-09-17 16:11:52 +0530439 adc_reg = BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0 +
440 TX_MACRO_ADC_MUX_CFG_OFFSET * hpf_work->decimator;
Meng Wang15c825d2018-09-06 10:49:18 +0800441 adc_n = snd_soc_component_read32(component, adc_reg) &
Laxminath Kasam497a6512018-09-17 16:11:52 +0530442 TX_MACRO_SWR_MIC_MUX_SEL_MASK;
443 if (adc_n >= BOLERO_ADC_MAX)
444 goto tx_hpf_set;
445 /* analog mic clear TX hold */
Meng Wang15c825d2018-09-06 10:49:18 +0800446 bolero_clear_amic_tx_hold(component->dev, adc_n);
Laxminath Kasam497a6512018-09-17 16:11:52 +0530447 }
448tx_hpf_set:
Meng Wang15c825d2018-09-06 10:49:18 +0800449 snd_soc_component_update_bits(component,
450 dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK,
451 hpf_cut_off_freq << 5);
452 snd_soc_component_update_bits(component, hpf_gate_reg, 0x03, 0x02);
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530453 /* Minimum 1 clk cycle delay is required as per HW spec */
454 usleep_range(1000, 1010);
Meng Wang15c825d2018-09-06 10:49:18 +0800455 snd_soc_component_update_bits(component, hpf_gate_reg, 0x03, 0x01);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530456}
457
458static void tx_macro_mute_update_callback(struct work_struct *work)
459{
460 struct tx_mute_work *tx_mute_dwork = NULL;
Meng Wang15c825d2018-09-06 10:49:18 +0800461 struct snd_soc_component *component = NULL;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530462 struct tx_macro_priv *tx_priv = NULL;
463 struct delayed_work *delayed_work = NULL;
Xiaojun Sangd155fdc2018-10-11 15:11:59 +0800464 u16 tx_vol_ctl_reg = 0;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530465 u8 decimator = 0;
466
467 delayed_work = to_delayed_work(work);
468 tx_mute_dwork = container_of(delayed_work, struct tx_mute_work, dwork);
469 tx_priv = tx_mute_dwork->tx_priv;
Meng Wang15c825d2018-09-06 10:49:18 +0800470 component = tx_priv->component;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530471 decimator = tx_mute_dwork->decimator;
472
473 tx_vol_ctl_reg =
474 BOLERO_CDC_TX0_TX_PATH_CTL +
475 TX_MACRO_TX_PATH_OFFSET * decimator;
Meng Wang15c825d2018-09-06 10:49:18 +0800476 snd_soc_component_update_bits(component, tx_vol_ctl_reg, 0x10, 0x00);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530477 dev_dbg(tx_priv->dev, "%s: decimator %u unmute\n",
478 __func__, decimator);
479}
480
481static int tx_macro_put_dec_enum(struct snd_kcontrol *kcontrol,
482 struct snd_ctl_elem_value *ucontrol)
483{
484 struct snd_soc_dapm_widget *widget =
485 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +0800486 struct snd_soc_component *component =
487 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530488 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
489 unsigned int val = 0;
490 u16 mic_sel_reg = 0;
Laxminath Kasam549d11d2019-07-18 13:44:17 +0530491 u16 dmic_clk_reg = 0;
492 struct device *tx_dev = NULL;
493 struct tx_macro_priv *tx_priv = NULL;
494
495 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
496 return -EINVAL;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530497
498 val = ucontrol->value.enumerated.item[0];
499 if (val > e->items - 1)
500 return -EINVAL;
501
Meng Wang15c825d2018-09-06 10:49:18 +0800502 dev_dbg(component->dev, "%s: wname: %s, val: 0x%x\n", __func__,
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530503 widget->name, val);
504
505 switch (e->reg) {
506 case BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0:
507 mic_sel_reg = BOLERO_CDC_TX0_TX_PATH_CFG0;
508 break;
509 case BOLERO_CDC_TX_INP_MUX_ADC_MUX1_CFG0:
510 mic_sel_reg = BOLERO_CDC_TX1_TX_PATH_CFG0;
511 break;
512 case BOLERO_CDC_TX_INP_MUX_ADC_MUX2_CFG0:
513 mic_sel_reg = BOLERO_CDC_TX2_TX_PATH_CFG0;
514 break;
515 case BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG0:
516 mic_sel_reg = BOLERO_CDC_TX3_TX_PATH_CFG0;
517 break;
518 case BOLERO_CDC_TX_INP_MUX_ADC_MUX4_CFG0:
519 mic_sel_reg = BOLERO_CDC_TX4_TX_PATH_CFG0;
520 break;
521 case BOLERO_CDC_TX_INP_MUX_ADC_MUX5_CFG0:
522 mic_sel_reg = BOLERO_CDC_TX5_TX_PATH_CFG0;
523 break;
524 case BOLERO_CDC_TX_INP_MUX_ADC_MUX6_CFG0:
525 mic_sel_reg = BOLERO_CDC_TX6_TX_PATH_CFG0;
526 break;
527 case BOLERO_CDC_TX_INP_MUX_ADC_MUX7_CFG0:
528 mic_sel_reg = BOLERO_CDC_TX7_TX_PATH_CFG0;
529 break;
530 default:
Meng Wang15c825d2018-09-06 10:49:18 +0800531 dev_err(component->dev, "%s: e->reg: 0x%x not expected\n",
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530532 __func__, e->reg);
533 return -EINVAL;
534 }
Laxminath Kasam497a6512018-09-17 16:11:52 +0530535 if (strnstr(widget->name, "SMIC", strlen(widget->name))) {
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530536 if (val != 0) {
Laxminath Kasam549d11d2019-07-18 13:44:17 +0530537 if (val < 5) {
Meng Wang15c825d2018-09-06 10:49:18 +0800538 snd_soc_component_update_bits(component,
539 mic_sel_reg,
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530540 1 << 7, 0x0 << 7);
Laxminath Kasam549d11d2019-07-18 13:44:17 +0530541 } else {
Meng Wang15c825d2018-09-06 10:49:18 +0800542 snd_soc_component_update_bits(component,
543 mic_sel_reg,
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530544 1 << 7, 0x1 << 7);
Laxminath Kasam549d11d2019-07-18 13:44:17 +0530545 snd_soc_component_update_bits(component,
546 BOLERO_CDC_VA_TOP_CSR_DMIC_CFG,
547 0x80, 0x00);
548 dmic_clk_reg =
549 BOLERO_CDC_TX_TOP_CSR_SWR_DMIC0_CTL +
550 ((val - 5)/2) * 4;
551 snd_soc_component_update_bits(component,
552 dmic_clk_reg,
553 0x0E, tx_priv->dmic_clk_div << 0x1);
554 }
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530555 }
556 } else {
557 /* DMIC selected */
558 if (val != 0)
Meng Wang15c825d2018-09-06 10:49:18 +0800559 snd_soc_component_update_bits(component, mic_sel_reg,
560 1 << 7, 1 << 7);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530561 }
562
563 return snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
564}
565
566static int tx_macro_tx_mixer_get(struct snd_kcontrol *kcontrol,
567 struct snd_ctl_elem_value *ucontrol)
568{
569 struct snd_soc_dapm_widget *widget =
570 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +0800571 struct snd_soc_component *component =
572 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530573 struct soc_multi_mixer_control *mixer =
574 ((struct soc_multi_mixer_control *)kcontrol->private_value);
575 u32 dai_id = widget->shift;
576 u32 dec_id = mixer->shift;
577 struct device *tx_dev = NULL;
578 struct tx_macro_priv *tx_priv = NULL;
579
Meng Wang15c825d2018-09-06 10:49:18 +0800580 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530581 return -EINVAL;
582
583 if (test_bit(dec_id, &tx_priv->active_ch_mask[dai_id]))
584 ucontrol->value.integer.value[0] = 1;
585 else
586 ucontrol->value.integer.value[0] = 0;
587 return 0;
588}
589
590static int tx_macro_tx_mixer_put(struct snd_kcontrol *kcontrol,
591 struct snd_ctl_elem_value *ucontrol)
592{
593 struct snd_soc_dapm_widget *widget =
594 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +0800595 struct snd_soc_component *component =
596 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530597 struct snd_soc_dapm_update *update = NULL;
598 struct soc_multi_mixer_control *mixer =
599 ((struct soc_multi_mixer_control *)kcontrol->private_value);
600 u32 dai_id = widget->shift;
601 u32 dec_id = mixer->shift;
602 u32 enable = ucontrol->value.integer.value[0];
603 struct device *tx_dev = NULL;
604 struct tx_macro_priv *tx_priv = NULL;
605
Meng Wang15c825d2018-09-06 10:49:18 +0800606 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530607 return -EINVAL;
608
609 if (enable) {
610 set_bit(dec_id, &tx_priv->active_ch_mask[dai_id]);
611 tx_priv->active_ch_cnt[dai_id]++;
612 } else {
613 tx_priv->active_ch_cnt[dai_id]--;
614 clear_bit(dec_id, &tx_priv->active_ch_mask[dai_id]);
615 }
616 snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, update);
617
618 return 0;
619}
Karthikeyan Mani1dcd5a32019-08-22 14:37:13 -0700620
621static inline int tx_macro_path_get(const char *wname,
622 unsigned int *path_num)
623{
624 int ret = 0;
625 char *widget_name = NULL;
626 char *w_name = NULL;
627 char *path_num_char = NULL;
628 char *path_name = NULL;
629
630 widget_name = kstrndup(wname, 10, GFP_KERNEL);
631 if (!widget_name)
632 return -EINVAL;
633
634 w_name = widget_name;
635
636 path_name = strsep(&widget_name, " ");
637 if (!path_name) {
638 pr_err("%s: Invalid widget name = %s\n",
639 __func__, widget_name);
640 ret = -EINVAL;
641 goto err;
642 }
643 path_num_char = strpbrk(path_name, "01234567");
644 if (!path_num_char) {
645 pr_err("%s: tx path index not found\n",
646 __func__);
647 ret = -EINVAL;
648 goto err;
649 }
650 ret = kstrtouint(path_num_char, 10, path_num);
651 if (ret < 0)
652 pr_err("%s: Invalid tx path = %s\n",
653 __func__, w_name);
654
655err:
656 kfree(w_name);
657 return ret;
658}
659
660static int tx_macro_dec_mode_get(struct snd_kcontrol *kcontrol,
661 struct snd_ctl_elem_value *ucontrol)
662{
663 struct snd_soc_component *component =
664 snd_soc_kcontrol_component(kcontrol);
665 struct tx_macro_priv *tx_priv = NULL;
666 struct device *tx_dev = NULL;
667 int ret = 0;
668 int path = 0;
669
670 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
671 return -EINVAL;
672
673 ret = tx_macro_path_get(kcontrol->id.name, &path);
674 if (ret)
675 return ret;
676
677 ucontrol->value.integer.value[0] = tx_priv->dec_mode[path];
678
679 return 0;
680}
681
682static int tx_macro_dec_mode_put(struct snd_kcontrol *kcontrol,
683 struct snd_ctl_elem_value *ucontrol)
684{
685 struct snd_soc_component *component =
686 snd_soc_kcontrol_component(kcontrol);
687 struct tx_macro_priv *tx_priv = NULL;
688 struct device *tx_dev = NULL;
689 int value = ucontrol->value.integer.value[0];
690 int ret = 0;
691 int path = 0;
692
693 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
694 return -EINVAL;
695
696 ret = tx_macro_path_get(kcontrol->id.name, &path);
697 if (ret)
698 return ret;
699
700 tx_priv->dec_mode[path] = value;
701
702 return 0;
703}
704
Karthikeyan Mani765eaab2019-07-18 16:27:01 -0700705static int tx_macro_get_bcs(struct snd_kcontrol *kcontrol,
706 struct snd_ctl_elem_value *ucontrol)
707{
708 struct snd_soc_component *component =
709 snd_soc_kcontrol_component(kcontrol);
710 struct tx_macro_priv *tx_priv = NULL;
711 struct device *tx_dev = NULL;
712
713 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
714 return -EINVAL;
715
716 ucontrol->value.integer.value[0] = tx_priv->bcs_enable;
717
718 return 0;
719}
720
721static int tx_macro_set_bcs(struct snd_kcontrol *kcontrol,
722 struct snd_ctl_elem_value *ucontrol)
723{
724 struct snd_soc_component *component =
725 snd_soc_kcontrol_component(kcontrol);
726 struct tx_macro_priv *tx_priv = NULL;
727 struct device *tx_dev = NULL;
728 int value = ucontrol->value.integer.value[0];
729
730 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
731 return -EINVAL;
732
733 tx_priv->bcs_enable = value;
734
735 return 0;
736}
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530737
738static int tx_macro_enable_dmic(struct snd_soc_dapm_widget *w,
739 struct snd_kcontrol *kcontrol, int event)
740{
Meng Wang15c825d2018-09-06 10:49:18 +0800741 struct snd_soc_component *component =
742 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530743 u8 dmic_clk_en = 0x01;
744 u16 dmic_clk_reg = 0;
745 s32 *dmic_clk_cnt = NULL;
746 unsigned int dmic = 0;
747 int ret = 0;
748 char *wname = NULL;
749 struct device *tx_dev = NULL;
750 struct tx_macro_priv *tx_priv = NULL;
751
Meng Wang15c825d2018-09-06 10:49:18 +0800752 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530753 return -EINVAL;
754
755 wname = strpbrk(w->name, "01234567");
756 if (!wname) {
Meng Wang15c825d2018-09-06 10:49:18 +0800757 dev_err(component->dev, "%s: widget not found\n", __func__);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530758 return -EINVAL;
759 }
760
761 ret = kstrtouint(wname, 10, &dmic);
762 if (ret < 0) {
Meng Wang15c825d2018-09-06 10:49:18 +0800763 dev_err(component->dev, "%s: Invalid DMIC line on the codec\n",
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530764 __func__);
765 return -EINVAL;
766 }
767
768 switch (dmic) {
769 case 0:
770 case 1:
771 dmic_clk_cnt = &(tx_priv->dmic_0_1_clk_cnt);
772 dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC0_CTL;
773 break;
774 case 2:
775 case 3:
776 dmic_clk_cnt = &(tx_priv->dmic_2_3_clk_cnt);
777 dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC1_CTL;
778 break;
779 case 4:
780 case 5:
781 dmic_clk_cnt = &(tx_priv->dmic_4_5_clk_cnt);
782 dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC2_CTL;
783 break;
784 case 6:
785 case 7:
786 dmic_clk_cnt = &(tx_priv->dmic_6_7_clk_cnt);
787 dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC3_CTL;
788 break;
789 default:
Meng Wang15c825d2018-09-06 10:49:18 +0800790 dev_err(component->dev, "%s: Invalid DMIC Selection\n",
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530791 __func__);
792 return -EINVAL;
793 }
Meng Wang15c825d2018-09-06 10:49:18 +0800794 dev_dbg(component->dev, "%s: event %d DMIC%d dmic_clk_cnt %d\n",
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530795 __func__, event, dmic, *dmic_clk_cnt);
796
797 switch (event) {
798 case SND_SOC_DAPM_PRE_PMU:
799 (*dmic_clk_cnt)++;
800 if (*dmic_clk_cnt == 1) {
Meng Wang15c825d2018-09-06 10:49:18 +0800801 snd_soc_component_update_bits(component,
802 BOLERO_CDC_VA_TOP_CSR_DMIC_CFG,
Ramprasad Katkam9c2394a2018-08-23 13:13:48 +0530803 0x80, 0x00);
804
Meng Wang15c825d2018-09-06 10:49:18 +0800805 snd_soc_component_update_bits(component, dmic_clk_reg,
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530806 0x0E, tx_priv->dmic_clk_div << 0x1);
Meng Wang15c825d2018-09-06 10:49:18 +0800807 snd_soc_component_update_bits(component, dmic_clk_reg,
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530808 dmic_clk_en, dmic_clk_en);
809 }
810 break;
811 case SND_SOC_DAPM_POST_PMD:
812 (*dmic_clk_cnt)--;
813 if (*dmic_clk_cnt == 0)
Meng Wang15c825d2018-09-06 10:49:18 +0800814 snd_soc_component_update_bits(component, dmic_clk_reg,
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530815 dmic_clk_en, 0);
816 break;
817 }
818
819 return 0;
820}
821
822static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w,
823 struct snd_kcontrol *kcontrol, int event)
824{
Meng Wang15c825d2018-09-06 10:49:18 +0800825 struct snd_soc_component *component =
826 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530827 unsigned int decimator = 0;
828 u16 tx_vol_ctl_reg = 0;
829 u16 dec_cfg_reg = 0;
830 u16 hpf_gate_reg = 0;
831 u16 tx_gain_ctl_reg = 0;
832 u8 hpf_cut_off_freq = 0;
833 struct device *tx_dev = NULL;
834 struct tx_macro_priv *tx_priv = NULL;
835
Meng Wang15c825d2018-09-06 10:49:18 +0800836 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530837 return -EINVAL;
838
839 decimator = w->shift;
840
Meng Wang15c825d2018-09-06 10:49:18 +0800841 dev_dbg(component->dev, "%s(): widget = %s decimator = %u\n", __func__,
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530842 w->name, decimator);
843
844 tx_vol_ctl_reg = BOLERO_CDC_TX0_TX_PATH_CTL +
845 TX_MACRO_TX_PATH_OFFSET * decimator;
846 hpf_gate_reg = BOLERO_CDC_TX0_TX_PATH_SEC2 +
847 TX_MACRO_TX_PATH_OFFSET * decimator;
848 dec_cfg_reg = BOLERO_CDC_TX0_TX_PATH_CFG0 +
849 TX_MACRO_TX_PATH_OFFSET * decimator;
850 tx_gain_ctl_reg = BOLERO_CDC_TX0_TX_VOL_CTL +
851 TX_MACRO_TX_PATH_OFFSET * decimator;
852
853 switch (event) {
854 case SND_SOC_DAPM_PRE_PMU:
Karthikeyan Mani1dcd5a32019-08-22 14:37:13 -0700855 snd_soc_component_update_bits(component,
856 dec_cfg_reg, 0x06, tx_priv->dec_mode[decimator] <<
857 TX_MACRO_ADC_MODE_CFG0_SHIFT);
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530858 /* Enable TX PGA Mute */
Meng Wang15c825d2018-09-06 10:49:18 +0800859 snd_soc_component_update_bits(component,
860 tx_vol_ctl_reg, 0x10, 0x10);
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530861 break;
862 case SND_SOC_DAPM_POST_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +0800863 snd_soc_component_update_bits(component,
864 tx_vol_ctl_reg, 0x20, 0x20);
865 snd_soc_component_update_bits(component,
866 hpf_gate_reg, 0x01, 0x00);
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530867
Meng Wang15c825d2018-09-06 10:49:18 +0800868 hpf_cut_off_freq = (
869 snd_soc_component_read32(component, dec_cfg_reg) &
870 TX_HPF_CUT_OFF_FREQ_MASK) >> 5;
871
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530872 tx_priv->tx_hpf_work[decimator].hpf_cut_off_freq =
Meng Wang15c825d2018-09-06 10:49:18 +0800873 hpf_cut_off_freq;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530874
875 if (hpf_cut_off_freq != CF_MIN_3DB_150HZ)
Meng Wang15c825d2018-09-06 10:49:18 +0800876 snd_soc_component_update_bits(component, dec_cfg_reg,
877 TX_HPF_CUT_OFF_FREQ_MASK,
878 CF_MIN_3DB_150HZ << 5);
879
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530880 /* schedule work queue to Remove Mute */
881 schedule_delayed_work(&tx_priv->tx_mute_dwork[decimator].dwork,
882 msecs_to_jiffies(tx_unmute_delay));
883 if (tx_priv->tx_hpf_work[decimator].hpf_cut_off_freq !=
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530884 CF_MIN_3DB_150HZ) {
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530885 schedule_delayed_work(
886 &tx_priv->tx_hpf_work[decimator].dwork,
Karthikeyan Mani6bd895e2019-07-26 15:34:50 -0700887 msecs_to_jiffies(300));
Meng Wang15c825d2018-09-06 10:49:18 +0800888 snd_soc_component_update_bits(component,
889 hpf_gate_reg, 0x02, 0x02);
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530890 /*
891 * Minimum 1 clk cycle delay is required as per HW spec
892 */
893 usleep_range(1000, 1010);
Meng Wang15c825d2018-09-06 10:49:18 +0800894 snd_soc_component_update_bits(component,
895 hpf_gate_reg, 0x02, 0x00);
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530896 }
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530897 /* apply gain after decimator is enabled */
Meng Wang15c825d2018-09-06 10:49:18 +0800898 snd_soc_component_write(component, tx_gain_ctl_reg,
899 snd_soc_component_read32(component,
900 tx_gain_ctl_reg));
Karthikeyan Mani765eaab2019-07-18 16:27:01 -0700901 if (tx_priv->bcs_enable) {
902 snd_soc_component_update_bits(component, dec_cfg_reg,
903 0x01, 0x01);
904 snd_soc_component_update_bits(component,
905 BOLERO_CDC_TX0_TX_PATH_SEC7, 0x40, 0x40);
906 }
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530907 break;
908 case SND_SOC_DAPM_PRE_PMD:
909 hpf_cut_off_freq =
910 tx_priv->tx_hpf_work[decimator].hpf_cut_off_freq;
Meng Wang15c825d2018-09-06 10:49:18 +0800911 snd_soc_component_update_bits(component,
912 tx_vol_ctl_reg, 0x10, 0x10);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530913 if (cancel_delayed_work_sync(
914 &tx_priv->tx_hpf_work[decimator].dwork)) {
915 if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) {
Meng Wang15c825d2018-09-06 10:49:18 +0800916 snd_soc_component_update_bits(
917 component, dec_cfg_reg,
918 TX_HPF_CUT_OFF_FREQ_MASK,
919 hpf_cut_off_freq << 5);
920 snd_soc_component_update_bits(component,
921 hpf_gate_reg,
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530922 0x02, 0x02);
923 /*
924 * Minimum 1 clk cycle delay is required
925 * as per HW spec
926 */
927 usleep_range(1000, 1010);
Meng Wang15c825d2018-09-06 10:49:18 +0800928 snd_soc_component_update_bits(component,
929 hpf_gate_reg,
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530930 0x02, 0x00);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530931 }
932 }
933 cancel_delayed_work_sync(
934 &tx_priv->tx_mute_dwork[decimator].dwork);
935 break;
936 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +0800937 snd_soc_component_update_bits(component, tx_vol_ctl_reg,
938 0x20, 0x00);
Karthikeyan Mani1dcd5a32019-08-22 14:37:13 -0700939 snd_soc_component_update_bits(component,
940 dec_cfg_reg, 0x06, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +0800941 snd_soc_component_update_bits(component, tx_vol_ctl_reg,
942 0x10, 0x00);
Karthikeyan Mani765eaab2019-07-18 16:27:01 -0700943 if (tx_priv->bcs_enable) {
944 snd_soc_component_update_bits(component, dec_cfg_reg,
945 0x01, 0x00);
946 snd_soc_component_update_bits(component,
947 BOLERO_CDC_TX0_TX_PATH_SEC7, 0x40, 0x00);
948 }
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530949 break;
950 }
951 return 0;
952}
953
954static int tx_macro_enable_micbias(struct snd_soc_dapm_widget *w,
955 struct snd_kcontrol *kcontrol, int event)
956{
957 return 0;
958}
959
960static int tx_macro_hw_params(struct snd_pcm_substream *substream,
961 struct snd_pcm_hw_params *params,
962 struct snd_soc_dai *dai)
963{
964 int tx_fs_rate = -EINVAL;
Meng Wang15c825d2018-09-06 10:49:18 +0800965 struct snd_soc_component *component = dai->component;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530966 u32 decimator = 0;
Laxminath Kasamb7f823c2018-08-02 13:23:11 +0530967 u32 sample_rate = 0;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530968 u16 tx_fs_reg = 0;
969 struct device *tx_dev = NULL;
970 struct tx_macro_priv *tx_priv = NULL;
971
Meng Wang15c825d2018-09-06 10:49:18 +0800972 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530973 return -EINVAL;
974
975 pr_debug("%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__,
976 dai->name, dai->id, params_rate(params),
977 params_channels(params));
978
979 sample_rate = params_rate(params);
980 switch (sample_rate) {
981 case 8000:
982 tx_fs_rate = 0;
983 break;
984 case 16000:
985 tx_fs_rate = 1;
986 break;
987 case 32000:
988 tx_fs_rate = 3;
989 break;
990 case 48000:
991 tx_fs_rate = 4;
992 break;
993 case 96000:
994 tx_fs_rate = 5;
995 break;
996 case 192000:
997 tx_fs_rate = 6;
998 break;
999 case 384000:
1000 tx_fs_rate = 7;
1001 break;
1002 default:
Meng Wang15c825d2018-09-06 10:49:18 +08001003 dev_err(component->dev, "%s: Invalid TX sample rate: %d\n",
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301004 __func__, params_rate(params));
1005 return -EINVAL;
1006 }
1007 for_each_set_bit(decimator, &tx_priv->active_ch_mask[dai->id],
1008 TX_MACRO_DEC_MAX) {
1009 if (decimator >= 0) {
1010 tx_fs_reg = BOLERO_CDC_TX0_TX_PATH_CTL +
1011 TX_MACRO_TX_PATH_OFFSET * decimator;
Meng Wang15c825d2018-09-06 10:49:18 +08001012 dev_dbg(component->dev, "%s: set DEC%u rate to %u\n",
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301013 __func__, decimator, sample_rate);
Meng Wang15c825d2018-09-06 10:49:18 +08001014 snd_soc_component_update_bits(component, tx_fs_reg,
1015 0x0F, tx_fs_rate);
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301016 } else {
Meng Wang15c825d2018-09-06 10:49:18 +08001017 dev_err(component->dev,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301018 "%s: ERROR: Invalid decimator: %d\n",
1019 __func__, decimator);
1020 return -EINVAL;
1021 }
1022 }
1023 return 0;
1024}
1025
1026static int tx_macro_get_channel_map(struct snd_soc_dai *dai,
1027 unsigned int *tx_num, unsigned int *tx_slot,
1028 unsigned int *rx_num, unsigned int *rx_slot)
1029{
Meng Wang15c825d2018-09-06 10:49:18 +08001030 struct snd_soc_component *component = dai->component;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301031 struct device *tx_dev = NULL;
1032 struct tx_macro_priv *tx_priv = NULL;
1033
Meng Wang15c825d2018-09-06 10:49:18 +08001034 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301035 return -EINVAL;
1036
1037 switch (dai->id) {
1038 case TX_MACRO_AIF1_CAP:
1039 case TX_MACRO_AIF2_CAP:
Karthikeyan Manif3bb8182019-07-11 14:38:54 -07001040 case TX_MACRO_AIF3_CAP:
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301041 *tx_slot = tx_priv->active_ch_mask[dai->id];
1042 *tx_num = tx_priv->active_ch_cnt[dai->id];
1043 break;
1044 default:
1045 dev_err(tx_dev, "%s: Invalid AIF\n", __func__);
1046 break;
1047 }
1048 return 0;
1049}
1050
1051static struct snd_soc_dai_ops tx_macro_dai_ops = {
1052 .hw_params = tx_macro_hw_params,
1053 .get_channel_map = tx_macro_get_channel_map,
1054};
1055
1056static struct snd_soc_dai_driver tx_macro_dai[] = {
1057 {
1058 .name = "tx_macro_tx1",
1059 .id = TX_MACRO_AIF1_CAP,
1060 .capture = {
1061 .stream_name = "TX_AIF1 Capture",
1062 .rates = TX_MACRO_RATES,
1063 .formats = TX_MACRO_FORMATS,
1064 .rate_max = 192000,
1065 .rate_min = 8000,
1066 .channels_min = 1,
1067 .channels_max = 8,
1068 },
1069 .ops = &tx_macro_dai_ops,
1070 },
1071 {
1072 .name = "tx_macro_tx2",
1073 .id = TX_MACRO_AIF2_CAP,
1074 .capture = {
1075 .stream_name = "TX_AIF2 Capture",
1076 .rates = TX_MACRO_RATES,
1077 .formats = TX_MACRO_FORMATS,
1078 .rate_max = 192000,
1079 .rate_min = 8000,
1080 .channels_min = 1,
1081 .channels_max = 8,
1082 },
1083 .ops = &tx_macro_dai_ops,
1084 },
Karthikeyan Manif3bb8182019-07-11 14:38:54 -07001085 {
1086 .name = "tx_macro_tx3",
1087 .id = TX_MACRO_AIF3_CAP,
1088 .capture = {
1089 .stream_name = "TX_AIF3 Capture",
1090 .rates = TX_MACRO_RATES,
1091 .formats = TX_MACRO_FORMATS,
1092 .rate_max = 192000,
1093 .rate_min = 8000,
1094 .channels_min = 1,
1095 .channels_max = 8,
1096 },
1097 .ops = &tx_macro_dai_ops,
1098 },
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301099};
1100
1101#define STRING(name) #name
1102#define TX_MACRO_DAPM_ENUM(name, reg, offset, text) \
1103static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \
1104static const struct snd_kcontrol_new name##_mux = \
1105 SOC_DAPM_ENUM(STRING(name), name##_enum)
1106
1107#define TX_MACRO_DAPM_ENUM_EXT(name, reg, offset, text, getname, putname) \
1108static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \
1109static const struct snd_kcontrol_new name##_mux = \
1110 SOC_DAPM_ENUM_EXT(STRING(name), name##_enum, getname, putname)
1111
1112#define TX_MACRO_DAPM_MUX(name, shift, kctl) \
1113 SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, shift, 0, &kctl##_mux)
1114
1115static const char * const adc_mux_text[] = {
1116 "MSM_DMIC", "SWR_MIC", "ANC_FB_TUNE1"
1117};
1118
1119TX_MACRO_DAPM_ENUM(tx_dec0, BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG1,
1120 0, adc_mux_text);
1121TX_MACRO_DAPM_ENUM(tx_dec1, BOLERO_CDC_TX_INP_MUX_ADC_MUX1_CFG1,
1122 0, adc_mux_text);
1123TX_MACRO_DAPM_ENUM(tx_dec2, BOLERO_CDC_TX_INP_MUX_ADC_MUX2_CFG1,
1124 0, adc_mux_text);
1125TX_MACRO_DAPM_ENUM(tx_dec3, BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG1,
1126 0, adc_mux_text);
1127TX_MACRO_DAPM_ENUM(tx_dec4, BOLERO_CDC_TX_INP_MUX_ADC_MUX4_CFG1,
1128 0, adc_mux_text);
1129TX_MACRO_DAPM_ENUM(tx_dec5, BOLERO_CDC_TX_INP_MUX_ADC_MUX5_CFG1,
1130 0, adc_mux_text);
1131TX_MACRO_DAPM_ENUM(tx_dec6, BOLERO_CDC_TX_INP_MUX_ADC_MUX6_CFG1,
1132 0, adc_mux_text);
1133TX_MACRO_DAPM_ENUM(tx_dec7, BOLERO_CDC_TX_INP_MUX_ADC_MUX7_CFG1,
1134 0, adc_mux_text);
1135
1136
1137static const char * const dmic_mux_text[] = {
1138 "ZERO", "DMIC0", "DMIC1", "DMIC2", "DMIC3",
1139 "DMIC4", "DMIC5", "DMIC6", "DMIC7"
1140};
1141
1142TX_MACRO_DAPM_ENUM_EXT(tx_dmic0, BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0,
1143 4, dmic_mux_text, snd_soc_dapm_get_enum_double,
1144 tx_macro_put_dec_enum);
1145
1146TX_MACRO_DAPM_ENUM_EXT(tx_dmic1, BOLERO_CDC_TX_INP_MUX_ADC_MUX1_CFG0,
1147 4, dmic_mux_text, snd_soc_dapm_get_enum_double,
1148 tx_macro_put_dec_enum);
1149
1150TX_MACRO_DAPM_ENUM_EXT(tx_dmic2, BOLERO_CDC_TX_INP_MUX_ADC_MUX2_CFG0,
1151 4, dmic_mux_text, snd_soc_dapm_get_enum_double,
1152 tx_macro_put_dec_enum);
1153
1154TX_MACRO_DAPM_ENUM_EXT(tx_dmic3, BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG0,
1155 4, dmic_mux_text, snd_soc_dapm_get_enum_double,
1156 tx_macro_put_dec_enum);
1157
1158TX_MACRO_DAPM_ENUM_EXT(tx_dmic4, BOLERO_CDC_TX_INP_MUX_ADC_MUX4_CFG0,
1159 4, dmic_mux_text, snd_soc_dapm_get_enum_double,
1160 tx_macro_put_dec_enum);
1161
1162TX_MACRO_DAPM_ENUM_EXT(tx_dmic5, BOLERO_CDC_TX_INP_MUX_ADC_MUX5_CFG0,
1163 4, dmic_mux_text, snd_soc_dapm_get_enum_double,
1164 tx_macro_put_dec_enum);
1165
1166TX_MACRO_DAPM_ENUM_EXT(tx_dmic6, BOLERO_CDC_TX_INP_MUX_ADC_MUX6_CFG0,
1167 4, dmic_mux_text, snd_soc_dapm_get_enum_double,
1168 tx_macro_put_dec_enum);
1169
1170TX_MACRO_DAPM_ENUM_EXT(tx_dmic7, BOLERO_CDC_TX_INP_MUX_ADC_MUX7_CFG0,
1171 4, dmic_mux_text, snd_soc_dapm_get_enum_double,
1172 tx_macro_put_dec_enum);
1173
1174static const char * const smic_mux_text[] = {
Sudheer Papothi324b4952019-06-11 04:14:51 +05301175 "ZERO", "ADC0", "ADC1", "ADC2", "ADC3", "SWR_DMIC0",
1176 "SWR_DMIC1", "SWR_DMIC2", "SWR_DMIC3", "SWR_DMIC4",
1177 "SWR_DMIC5", "SWR_DMIC6", "SWR_DMIC7"
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301178};
1179
1180TX_MACRO_DAPM_ENUM_EXT(tx_smic0, BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0,
1181 0, smic_mux_text, snd_soc_dapm_get_enum_double,
1182 tx_macro_put_dec_enum);
1183
1184TX_MACRO_DAPM_ENUM_EXT(tx_smic1, BOLERO_CDC_TX_INP_MUX_ADC_MUX1_CFG0,
1185 0, smic_mux_text, snd_soc_dapm_get_enum_double,
1186 tx_macro_put_dec_enum);
1187
1188TX_MACRO_DAPM_ENUM_EXT(tx_smic2, BOLERO_CDC_TX_INP_MUX_ADC_MUX2_CFG0,
1189 0, smic_mux_text, snd_soc_dapm_get_enum_double,
1190 tx_macro_put_dec_enum);
1191
1192TX_MACRO_DAPM_ENUM_EXT(tx_smic3, BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG0,
1193 0, smic_mux_text, snd_soc_dapm_get_enum_double,
1194 tx_macro_put_dec_enum);
1195
1196TX_MACRO_DAPM_ENUM_EXT(tx_smic4, BOLERO_CDC_TX_INP_MUX_ADC_MUX4_CFG0,
1197 0, smic_mux_text, snd_soc_dapm_get_enum_double,
1198 tx_macro_put_dec_enum);
1199
1200TX_MACRO_DAPM_ENUM_EXT(tx_smic5, BOLERO_CDC_TX_INP_MUX_ADC_MUX5_CFG0,
1201 0, smic_mux_text, snd_soc_dapm_get_enum_double,
1202 tx_macro_put_dec_enum);
1203
1204TX_MACRO_DAPM_ENUM_EXT(tx_smic6, BOLERO_CDC_TX_INP_MUX_ADC_MUX6_CFG0,
1205 0, smic_mux_text, snd_soc_dapm_get_enum_double,
1206 tx_macro_put_dec_enum);
1207
1208TX_MACRO_DAPM_ENUM_EXT(tx_smic7, BOLERO_CDC_TX_INP_MUX_ADC_MUX7_CFG0,
1209 0, smic_mux_text, snd_soc_dapm_get_enum_double,
1210 tx_macro_put_dec_enum);
1211
Karthikeyan Mani1dcd5a32019-08-22 14:37:13 -07001212static const char * const dec_mode_mux_text[] = {
1213 "ADC_DEFAULT", "ADC_LOW_PWR", "ADC_HIGH_PERF",
1214};
1215
1216static const struct soc_enum dec_mode_mux_enum =
1217 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(dec_mode_mux_text),
1218 dec_mode_mux_text);
1219
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301220static const struct snd_kcontrol_new tx_aif1_cap_mixer[] = {
1221 SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, TX_MACRO_DEC0, 1, 0,
1222 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1223 SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, TX_MACRO_DEC1, 1, 0,
1224 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1225 SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, TX_MACRO_DEC2, 1, 0,
1226 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1227 SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, TX_MACRO_DEC3, 1, 0,
1228 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1229 SOC_SINGLE_EXT("DEC4", SND_SOC_NOPM, TX_MACRO_DEC4, 1, 0,
1230 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1231 SOC_SINGLE_EXT("DEC5", SND_SOC_NOPM, TX_MACRO_DEC5, 1, 0,
1232 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1233 SOC_SINGLE_EXT("DEC6", SND_SOC_NOPM, TX_MACRO_DEC6, 1, 0,
1234 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1235 SOC_SINGLE_EXT("DEC7", SND_SOC_NOPM, TX_MACRO_DEC7, 1, 0,
1236 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1237};
1238
1239static const struct snd_kcontrol_new tx_aif2_cap_mixer[] = {
1240 SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, TX_MACRO_DEC0, 1, 0,
1241 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1242 SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, TX_MACRO_DEC1, 1, 0,
1243 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1244 SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, TX_MACRO_DEC2, 1, 0,
1245 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1246 SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, TX_MACRO_DEC3, 1, 0,
1247 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1248 SOC_SINGLE_EXT("DEC4", SND_SOC_NOPM, TX_MACRO_DEC4, 1, 0,
1249 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1250 SOC_SINGLE_EXT("DEC5", SND_SOC_NOPM, TX_MACRO_DEC5, 1, 0,
1251 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1252 SOC_SINGLE_EXT("DEC6", SND_SOC_NOPM, TX_MACRO_DEC6, 1, 0,
1253 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1254 SOC_SINGLE_EXT("DEC7", SND_SOC_NOPM, TX_MACRO_DEC7, 1, 0,
1255 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1256};
1257
Karthikeyan Manif3bb8182019-07-11 14:38:54 -07001258static const struct snd_kcontrol_new tx_aif3_cap_mixer[] = {
1259 SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, TX_MACRO_DEC0, 1, 0,
1260 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1261 SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, TX_MACRO_DEC1, 1, 0,
1262 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1263 SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, TX_MACRO_DEC2, 1, 0,
1264 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1265 SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, TX_MACRO_DEC3, 1, 0,
1266 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1267 SOC_SINGLE_EXT("DEC4", SND_SOC_NOPM, TX_MACRO_DEC4, 1, 0,
1268 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1269 SOC_SINGLE_EXT("DEC5", SND_SOC_NOPM, TX_MACRO_DEC5, 1, 0,
1270 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1271 SOC_SINGLE_EXT("DEC6", SND_SOC_NOPM, TX_MACRO_DEC6, 1, 0,
1272 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1273 SOC_SINGLE_EXT("DEC7", SND_SOC_NOPM, TX_MACRO_DEC7, 1, 0,
1274 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1275};
1276
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301277static const struct snd_soc_dapm_widget tx_macro_dapm_widgets[] = {
1278 SND_SOC_DAPM_AIF_OUT("TX_AIF1 CAP", "TX_AIF1 Capture", 0,
1279 SND_SOC_NOPM, TX_MACRO_AIF1_CAP, 0),
1280
1281 SND_SOC_DAPM_AIF_OUT("TX_AIF2 CAP", "TX_AIF2 Capture", 0,
1282 SND_SOC_NOPM, TX_MACRO_AIF2_CAP, 0),
1283
Karthikeyan Manif3bb8182019-07-11 14:38:54 -07001284 SND_SOC_DAPM_AIF_OUT("TX_AIF3 CAP", "TX_AIF3 Capture", 0,
1285 SND_SOC_NOPM, TX_MACRO_AIF3_CAP, 0),
1286
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301287 SND_SOC_DAPM_MIXER("TX_AIF1_CAP Mixer", SND_SOC_NOPM, TX_MACRO_AIF1_CAP, 0,
1288 tx_aif1_cap_mixer, ARRAY_SIZE(tx_aif1_cap_mixer)),
1289
1290 SND_SOC_DAPM_MIXER("TX_AIF2_CAP Mixer", SND_SOC_NOPM, TX_MACRO_AIF2_CAP, 0,
1291 tx_aif2_cap_mixer, ARRAY_SIZE(tx_aif2_cap_mixer)),
1292
Karthikeyan Manif3bb8182019-07-11 14:38:54 -07001293 SND_SOC_DAPM_MIXER("TX_AIF3_CAP Mixer", SND_SOC_NOPM, TX_MACRO_AIF3_CAP, 0,
1294 tx_aif3_cap_mixer, ARRAY_SIZE(tx_aif3_cap_mixer)),
1295
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301296
1297 TX_MACRO_DAPM_MUX("TX DMIC MUX0", 0, tx_dmic0),
1298 TX_MACRO_DAPM_MUX("TX DMIC MUX1", 0, tx_dmic1),
1299 TX_MACRO_DAPM_MUX("TX DMIC MUX2", 0, tx_dmic2),
1300 TX_MACRO_DAPM_MUX("TX DMIC MUX3", 0, tx_dmic3),
1301 TX_MACRO_DAPM_MUX("TX DMIC MUX4", 0, tx_dmic4),
1302 TX_MACRO_DAPM_MUX("TX DMIC MUX5", 0, tx_dmic5),
1303 TX_MACRO_DAPM_MUX("TX DMIC MUX6", 0, tx_dmic6),
1304 TX_MACRO_DAPM_MUX("TX DMIC MUX7", 0, tx_dmic7),
1305
1306 TX_MACRO_DAPM_MUX("TX SMIC MUX0", 0, tx_smic0),
1307 TX_MACRO_DAPM_MUX("TX SMIC MUX1", 0, tx_smic1),
1308 TX_MACRO_DAPM_MUX("TX SMIC MUX2", 0, tx_smic2),
1309 TX_MACRO_DAPM_MUX("TX SMIC MUX3", 0, tx_smic3),
1310 TX_MACRO_DAPM_MUX("TX SMIC MUX4", 0, tx_smic4),
1311 TX_MACRO_DAPM_MUX("TX SMIC MUX5", 0, tx_smic5),
1312 TX_MACRO_DAPM_MUX("TX SMIC MUX6", 0, tx_smic6),
1313 TX_MACRO_DAPM_MUX("TX SMIC MUX7", 0, tx_smic7),
1314
1315 SND_SOC_DAPM_MICBIAS_E("TX MIC BIAS1", SND_SOC_NOPM, 0, 0,
1316 tx_macro_enable_micbias,
1317 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1318 SND_SOC_DAPM_ADC_E("TX DMIC0", NULL, SND_SOC_NOPM, 0, 0,
1319 tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
1320 SND_SOC_DAPM_POST_PMD),
1321
1322 SND_SOC_DAPM_ADC_E("TX DMIC1", NULL, SND_SOC_NOPM, 0, 0,
1323 tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
1324 SND_SOC_DAPM_POST_PMD),
1325
1326 SND_SOC_DAPM_ADC_E("TX DMIC2", NULL, SND_SOC_NOPM, 0, 0,
1327 tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
1328 SND_SOC_DAPM_POST_PMD),
1329
1330 SND_SOC_DAPM_ADC_E("TX DMIC3", NULL, SND_SOC_NOPM, 0, 0,
1331 tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
1332 SND_SOC_DAPM_POST_PMD),
1333
1334 SND_SOC_DAPM_ADC_E("TX DMIC4", NULL, SND_SOC_NOPM, 0, 0,
1335 tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
1336 SND_SOC_DAPM_POST_PMD),
1337
1338 SND_SOC_DAPM_ADC_E("TX DMIC5", NULL, SND_SOC_NOPM, 0, 0,
1339 tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
1340 SND_SOC_DAPM_POST_PMD),
1341
1342 SND_SOC_DAPM_ADC_E("TX DMIC6", NULL, SND_SOC_NOPM, 0, 0,
1343 tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
1344 SND_SOC_DAPM_POST_PMD),
1345
1346 SND_SOC_DAPM_ADC_E("TX DMIC7", NULL, SND_SOC_NOPM, 0, 0,
1347 tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
1348 SND_SOC_DAPM_POST_PMD),
1349
1350 SND_SOC_DAPM_INPUT("TX SWR_ADC0"),
1351 SND_SOC_DAPM_INPUT("TX SWR_ADC1"),
1352 SND_SOC_DAPM_INPUT("TX SWR_ADC2"),
1353 SND_SOC_DAPM_INPUT("TX SWR_ADC3"),
1354 SND_SOC_DAPM_INPUT("TX SWR_DMIC0"),
1355 SND_SOC_DAPM_INPUT("TX SWR_DMIC1"),
1356 SND_SOC_DAPM_INPUT("TX SWR_DMIC2"),
1357 SND_SOC_DAPM_INPUT("TX SWR_DMIC3"),
1358 SND_SOC_DAPM_INPUT("TX SWR_DMIC4"),
1359 SND_SOC_DAPM_INPUT("TX SWR_DMIC5"),
1360 SND_SOC_DAPM_INPUT("TX SWR_DMIC6"),
1361 SND_SOC_DAPM_INPUT("TX SWR_DMIC7"),
1362
Ramprasad Katkamf83acfb2018-08-11 23:28:57 +05301363 SND_SOC_DAPM_MUX_E("TX DEC0 MUX", SND_SOC_NOPM,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301364 TX_MACRO_DEC0, 0,
1365 &tx_dec0_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 DEC1 MUX", SND_SOC_NOPM,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301370 TX_MACRO_DEC1, 0,
1371 &tx_dec1_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 DEC2 MUX", SND_SOC_NOPM,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301376 TX_MACRO_DEC2, 0,
1377 &tx_dec2_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 DEC3 MUX", SND_SOC_NOPM,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301382 TX_MACRO_DEC3, 0,
1383 &tx_dec3_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 DEC4 MUX", SND_SOC_NOPM,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301388 TX_MACRO_DEC4, 0,
1389 &tx_dec4_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 DEC5 MUX", SND_SOC_NOPM,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301394 TX_MACRO_DEC5, 0,
1395 &tx_dec5_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 DEC6 MUX", SND_SOC_NOPM,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301400 TX_MACRO_DEC6, 0,
1401 &tx_dec6_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
Ramprasad Katkamf83acfb2018-08-11 23:28:57 +05301405 SND_SOC_DAPM_MUX_E("TX DEC7 MUX", SND_SOC_NOPM,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301406 TX_MACRO_DEC7, 0,
1407 &tx_dec7_mux, tx_macro_enable_dec,
1408 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1409 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1410
1411 SND_SOC_DAPM_SUPPLY_S("TX_MCLK", 0, SND_SOC_NOPM, 0, 0,
1412 tx_macro_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
Sudheer Papothie456c2c2019-03-05 07:08:45 +05301413
1414 SND_SOC_DAPM_SUPPLY_S("TX_SWR_CLK", 0, SND_SOC_NOPM, 0, 0,
1415 tx_macro_tx_swr_clk_event,
1416 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1417
1418 SND_SOC_DAPM_SUPPLY_S("VA_SWR_CLK", 0, SND_SOC_NOPM, 0, 0,
1419 tx_macro_va_swr_clk_event,
1420 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301421};
1422
1423static const struct snd_soc_dapm_route tx_audio_map[] = {
1424 {"TX_AIF1 CAP", NULL, "TX_MCLK"},
1425 {"TX_AIF2 CAP", NULL, "TX_MCLK"},
Karthikeyan Manif3bb8182019-07-11 14:38:54 -07001426 {"TX_AIF3 CAP", NULL, "TX_MCLK"},
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301427
1428 {"TX_AIF1 CAP", NULL, "TX_AIF1_CAP Mixer"},
1429 {"TX_AIF2 CAP", NULL, "TX_AIF2_CAP Mixer"},
Karthikeyan Manif3bb8182019-07-11 14:38:54 -07001430 {"TX_AIF3 CAP", NULL, "TX_AIF3_CAP Mixer"},
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301431
1432 {"TX_AIF1_CAP Mixer", "DEC0", "TX DEC0 MUX"},
1433 {"TX_AIF1_CAP Mixer", "DEC1", "TX DEC1 MUX"},
1434 {"TX_AIF1_CAP Mixer", "DEC2", "TX DEC2 MUX"},
1435 {"TX_AIF1_CAP Mixer", "DEC3", "TX DEC3 MUX"},
1436 {"TX_AIF1_CAP Mixer", "DEC4", "TX DEC4 MUX"},
1437 {"TX_AIF1_CAP Mixer", "DEC5", "TX DEC5 MUX"},
1438 {"TX_AIF1_CAP Mixer", "DEC6", "TX DEC6 MUX"},
1439 {"TX_AIF1_CAP Mixer", "DEC7", "TX DEC7 MUX"},
1440
1441 {"TX_AIF2_CAP Mixer", "DEC0", "TX DEC0 MUX"},
1442 {"TX_AIF2_CAP Mixer", "DEC1", "TX DEC1 MUX"},
1443 {"TX_AIF2_CAP Mixer", "DEC2", "TX DEC2 MUX"},
1444 {"TX_AIF2_CAP Mixer", "DEC3", "TX DEC3 MUX"},
1445 {"TX_AIF2_CAP Mixer", "DEC4", "TX DEC4 MUX"},
1446 {"TX_AIF2_CAP Mixer", "DEC5", "TX DEC5 MUX"},
1447 {"TX_AIF2_CAP Mixer", "DEC6", "TX DEC6 MUX"},
1448 {"TX_AIF2_CAP Mixer", "DEC7", "TX DEC7 MUX"},
1449
Karthikeyan Manif3bb8182019-07-11 14:38:54 -07001450 {"TX_AIF3_CAP Mixer", "DEC0", "TX DEC0 MUX"},
1451 {"TX_AIF3_CAP Mixer", "DEC1", "TX DEC1 MUX"},
1452 {"TX_AIF3_CAP Mixer", "DEC2", "TX DEC2 MUX"},
1453 {"TX_AIF3_CAP Mixer", "DEC3", "TX DEC3 MUX"},
1454 {"TX_AIF3_CAP Mixer", "DEC4", "TX DEC4 MUX"},
1455 {"TX_AIF3_CAP Mixer", "DEC5", "TX DEC5 MUX"},
1456 {"TX_AIF3_CAP Mixer", "DEC6", "TX DEC6 MUX"},
1457 {"TX_AIF3_CAP Mixer", "DEC7", "TX DEC7 MUX"},
1458
Laxminath Kasamfc281ad2018-08-06 20:19:40 +05301459 {"TX DEC0 MUX", NULL, "TX_MCLK"},
1460 {"TX DEC1 MUX", NULL, "TX_MCLK"},
1461 {"TX DEC2 MUX", NULL, "TX_MCLK"},
1462 {"TX DEC3 MUX", NULL, "TX_MCLK"},
1463 {"TX DEC4 MUX", NULL, "TX_MCLK"},
1464 {"TX DEC5 MUX", NULL, "TX_MCLK"},
1465 {"TX DEC6 MUX", NULL, "TX_MCLK"},
1466 {"TX DEC7 MUX", NULL, "TX_MCLK"},
1467
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301468 {"TX DEC0 MUX", "MSM_DMIC", "TX DMIC MUX0"},
1469 {"TX DMIC MUX0", "DMIC0", "TX DMIC0"},
1470 {"TX DMIC MUX0", "DMIC1", "TX DMIC1"},
1471 {"TX DMIC MUX0", "DMIC2", "TX DMIC2"},
1472 {"TX DMIC MUX0", "DMIC3", "TX DMIC3"},
1473 {"TX DMIC MUX0", "DMIC4", "TX DMIC4"},
1474 {"TX DMIC MUX0", "DMIC5", "TX DMIC5"},
1475 {"TX DMIC MUX0", "DMIC6", "TX DMIC6"},
1476 {"TX DMIC MUX0", "DMIC7", "TX DMIC7"},
1477
1478 {"TX DEC0 MUX", "SWR_MIC", "TX SMIC MUX0"},
Sudheer Papothie456c2c2019-03-05 07:08:45 +05301479 {"TX SMIC MUX0", NULL, "TX_SWR_CLK"},
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301480 {"TX SMIC MUX0", "ADC0", "TX SWR_ADC0"},
1481 {"TX SMIC MUX0", "ADC1", "TX SWR_ADC1"},
1482 {"TX SMIC MUX0", "ADC2", "TX SWR_ADC2"},
1483 {"TX SMIC MUX0", "ADC3", "TX SWR_ADC3"},
1484 {"TX SMIC MUX0", "SWR_DMIC0", "TX SWR_DMIC0"},
1485 {"TX SMIC MUX0", "SWR_DMIC1", "TX SWR_DMIC1"},
1486 {"TX SMIC MUX0", "SWR_DMIC2", "TX SWR_DMIC2"},
1487 {"TX SMIC MUX0", "SWR_DMIC3", "TX SWR_DMIC3"},
1488 {"TX SMIC MUX0", "SWR_DMIC4", "TX SWR_DMIC4"},
1489 {"TX SMIC MUX0", "SWR_DMIC5", "TX SWR_DMIC5"},
1490 {"TX SMIC MUX0", "SWR_DMIC6", "TX SWR_DMIC6"},
1491 {"TX SMIC MUX0", "SWR_DMIC7", "TX SWR_DMIC7"},
1492
1493 {"TX DEC1 MUX", "MSM_DMIC", "TX DMIC MUX1"},
1494 {"TX DMIC MUX1", "DMIC0", "TX DMIC0"},
1495 {"TX DMIC MUX1", "DMIC1", "TX DMIC1"},
1496 {"TX DMIC MUX1", "DMIC2", "TX DMIC2"},
1497 {"TX DMIC MUX1", "DMIC3", "TX DMIC3"},
1498 {"TX DMIC MUX1", "DMIC4", "TX DMIC4"},
1499 {"TX DMIC MUX1", "DMIC5", "TX DMIC5"},
1500 {"TX DMIC MUX1", "DMIC6", "TX DMIC6"},
1501 {"TX DMIC MUX1", "DMIC7", "TX DMIC7"},
1502
1503 {"TX DEC1 MUX", "SWR_MIC", "TX SMIC MUX1"},
Sudheer Papothie456c2c2019-03-05 07:08:45 +05301504 {"TX SMIC MUX1", NULL, "TX_SWR_CLK"},
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301505 {"TX SMIC MUX1", "ADC0", "TX SWR_ADC0"},
1506 {"TX SMIC MUX1", "ADC1", "TX SWR_ADC1"},
1507 {"TX SMIC MUX1", "ADC2", "TX SWR_ADC2"},
1508 {"TX SMIC MUX1", "ADC3", "TX SWR_ADC3"},
1509 {"TX SMIC MUX1", "SWR_DMIC0", "TX SWR_DMIC0"},
1510 {"TX SMIC MUX1", "SWR_DMIC1", "TX SWR_DMIC1"},
1511 {"TX SMIC MUX1", "SWR_DMIC2", "TX SWR_DMIC2"},
1512 {"TX SMIC MUX1", "SWR_DMIC3", "TX SWR_DMIC3"},
1513 {"TX SMIC MUX1", "SWR_DMIC4", "TX SWR_DMIC4"},
1514 {"TX SMIC MUX1", "SWR_DMIC5", "TX SWR_DMIC5"},
1515 {"TX SMIC MUX1", "SWR_DMIC6", "TX SWR_DMIC6"},
1516 {"TX SMIC MUX1", "SWR_DMIC7", "TX SWR_DMIC7"},
1517
1518 {"TX DEC2 MUX", "MSM_DMIC", "TX DMIC MUX2"},
1519 {"TX DMIC MUX2", "DMIC0", "TX DMIC0"},
1520 {"TX DMIC MUX2", "DMIC1", "TX DMIC1"},
1521 {"TX DMIC MUX2", "DMIC2", "TX DMIC2"},
1522 {"TX DMIC MUX2", "DMIC3", "TX DMIC3"},
1523 {"TX DMIC MUX2", "DMIC4", "TX DMIC4"},
1524 {"TX DMIC MUX2", "DMIC5", "TX DMIC5"},
1525 {"TX DMIC MUX2", "DMIC6", "TX DMIC6"},
1526 {"TX DMIC MUX2", "DMIC7", "TX DMIC7"},
1527
1528 {"TX DEC2 MUX", "SWR_MIC", "TX SMIC MUX2"},
Sudheer Papothie456c2c2019-03-05 07:08:45 +05301529 {"TX SMIC MUX2", NULL, "TX_SWR_CLK"},
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301530 {"TX SMIC MUX2", "ADC0", "TX SWR_ADC0"},
1531 {"TX SMIC MUX2", "ADC1", "TX SWR_ADC1"},
1532 {"TX SMIC MUX2", "ADC2", "TX SWR_ADC2"},
1533 {"TX SMIC MUX2", "ADC3", "TX SWR_ADC3"},
1534 {"TX SMIC MUX2", "SWR_DMIC0", "TX SWR_DMIC0"},
1535 {"TX SMIC MUX2", "SWR_DMIC1", "TX SWR_DMIC1"},
1536 {"TX SMIC MUX2", "SWR_DMIC2", "TX SWR_DMIC2"},
1537 {"TX SMIC MUX2", "SWR_DMIC3", "TX SWR_DMIC3"},
1538 {"TX SMIC MUX2", "SWR_DMIC4", "TX SWR_DMIC4"},
1539 {"TX SMIC MUX2", "SWR_DMIC5", "TX SWR_DMIC5"},
1540 {"TX SMIC MUX2", "SWR_DMIC6", "TX SWR_DMIC6"},
1541 {"TX SMIC MUX2", "SWR_DMIC7", "TX SWR_DMIC7"},
1542
1543 {"TX DEC3 MUX", "MSM_DMIC", "TX DMIC MUX3"},
1544 {"TX DMIC MUX3", "DMIC0", "TX DMIC0"},
1545 {"TX DMIC MUX3", "DMIC1", "TX DMIC1"},
1546 {"TX DMIC MUX3", "DMIC2", "TX DMIC2"},
1547 {"TX DMIC MUX3", "DMIC3", "TX DMIC3"},
1548 {"TX DMIC MUX3", "DMIC4", "TX DMIC4"},
1549 {"TX DMIC MUX3", "DMIC5", "TX DMIC5"},
1550 {"TX DMIC MUX3", "DMIC6", "TX DMIC6"},
1551 {"TX DMIC MUX3", "DMIC7", "TX DMIC7"},
1552
1553 {"TX DEC3 MUX", "SWR_MIC", "TX SMIC MUX3"},
Sudheer Papothie456c2c2019-03-05 07:08:45 +05301554 {"TX SMIC MUX3", NULL, "TX_SWR_CLK"},
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301555 {"TX SMIC MUX3", "ADC0", "TX SWR_ADC0"},
1556 {"TX SMIC MUX3", "ADC1", "TX SWR_ADC1"},
1557 {"TX SMIC MUX3", "ADC2", "TX SWR_ADC2"},
1558 {"TX SMIC MUX3", "ADC3", "TX SWR_ADC3"},
1559 {"TX SMIC MUX3", "SWR_DMIC0", "TX SWR_DMIC0"},
1560 {"TX SMIC MUX3", "SWR_DMIC1", "TX SWR_DMIC1"},
1561 {"TX SMIC MUX3", "SWR_DMIC2", "TX SWR_DMIC2"},
1562 {"TX SMIC MUX3", "SWR_DMIC3", "TX SWR_DMIC3"},
1563 {"TX SMIC MUX3", "SWR_DMIC4", "TX SWR_DMIC4"},
1564 {"TX SMIC MUX3", "SWR_DMIC5", "TX SWR_DMIC5"},
1565 {"TX SMIC MUX3", "SWR_DMIC6", "TX SWR_DMIC6"},
1566 {"TX SMIC MUX3", "SWR_DMIC7", "TX SWR_DMIC7"},
1567
1568 {"TX DEC4 MUX", "MSM_DMIC", "TX DMIC MUX4"},
1569 {"TX DMIC MUX4", "DMIC0", "TX DMIC0"},
1570 {"TX DMIC MUX4", "DMIC1", "TX DMIC1"},
1571 {"TX DMIC MUX4", "DMIC2", "TX DMIC2"},
1572 {"TX DMIC MUX4", "DMIC3", "TX DMIC3"},
1573 {"TX DMIC MUX4", "DMIC4", "TX DMIC4"},
1574 {"TX DMIC MUX4", "DMIC5", "TX DMIC5"},
1575 {"TX DMIC MUX4", "DMIC6", "TX DMIC6"},
1576 {"TX DMIC MUX4", "DMIC7", "TX DMIC7"},
1577
1578 {"TX DEC4 MUX", "SWR_MIC", "TX SMIC MUX4"},
Sudheer Papothie456c2c2019-03-05 07:08:45 +05301579 {"TX SMIC MUX4", NULL, "TX_SWR_CLK"},
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301580 {"TX SMIC MUX4", "ADC0", "TX SWR_ADC0"},
1581 {"TX SMIC MUX4", "ADC1", "TX SWR_ADC1"},
1582 {"TX SMIC MUX4", "ADC2", "TX SWR_ADC2"},
1583 {"TX SMIC MUX4", "ADC3", "TX SWR_ADC3"},
1584 {"TX SMIC MUX4", "SWR_DMIC0", "TX SWR_DMIC0"},
1585 {"TX SMIC MUX4", "SWR_DMIC1", "TX SWR_DMIC1"},
1586 {"TX SMIC MUX4", "SWR_DMIC2", "TX SWR_DMIC2"},
1587 {"TX SMIC MUX4", "SWR_DMIC3", "TX SWR_DMIC3"},
1588 {"TX SMIC MUX4", "SWR_DMIC4", "TX SWR_DMIC4"},
1589 {"TX SMIC MUX4", "SWR_DMIC5", "TX SWR_DMIC5"},
1590 {"TX SMIC MUX4", "SWR_DMIC6", "TX SWR_DMIC6"},
1591 {"TX SMIC MUX4", "SWR_DMIC7", "TX SWR_DMIC7"},
1592
1593 {"TX DEC5 MUX", "MSM_DMIC", "TX DMIC MUX5"},
1594 {"TX DMIC MUX5", "DMIC0", "TX DMIC0"},
1595 {"TX DMIC MUX5", "DMIC1", "TX DMIC1"},
1596 {"TX DMIC MUX5", "DMIC2", "TX DMIC2"},
1597 {"TX DMIC MUX5", "DMIC3", "TX DMIC3"},
1598 {"TX DMIC MUX5", "DMIC4", "TX DMIC4"},
1599 {"TX DMIC MUX5", "DMIC5", "TX DMIC5"},
1600 {"TX DMIC MUX5", "DMIC6", "TX DMIC6"},
1601 {"TX DMIC MUX5", "DMIC7", "TX DMIC7"},
1602
1603 {"TX DEC5 MUX", "SWR_MIC", "TX SMIC MUX5"},
Sudheer Papothie456c2c2019-03-05 07:08:45 +05301604 {"TX SMIC MUX5", NULL, "TX_SWR_CLK"},
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301605 {"TX SMIC MUX5", "ADC0", "TX SWR_ADC0"},
1606 {"TX SMIC MUX5", "ADC1", "TX SWR_ADC1"},
1607 {"TX SMIC MUX5", "ADC2", "TX SWR_ADC2"},
1608 {"TX SMIC MUX5", "ADC3", "TX SWR_ADC3"},
1609 {"TX SMIC MUX5", "SWR_DMIC0", "TX SWR_DMIC0"},
1610 {"TX SMIC MUX5", "SWR_DMIC1", "TX SWR_DMIC1"},
1611 {"TX SMIC MUX5", "SWR_DMIC2", "TX SWR_DMIC2"},
1612 {"TX SMIC MUX5", "SWR_DMIC3", "TX SWR_DMIC3"},
1613 {"TX SMIC MUX5", "SWR_DMIC4", "TX SWR_DMIC4"},
1614 {"TX SMIC MUX5", "SWR_DMIC5", "TX SWR_DMIC5"},
1615 {"TX SMIC MUX5", "SWR_DMIC6", "TX SWR_DMIC6"},
1616 {"TX SMIC MUX5", "SWR_DMIC7", "TX SWR_DMIC7"},
1617
1618 {"TX DEC6 MUX", "MSM_DMIC", "TX DMIC MUX6"},
1619 {"TX DMIC MUX6", "DMIC0", "TX DMIC0"},
1620 {"TX DMIC MUX6", "DMIC1", "TX DMIC1"},
1621 {"TX DMIC MUX6", "DMIC2", "TX DMIC2"},
1622 {"TX DMIC MUX6", "DMIC3", "TX DMIC3"},
1623 {"TX DMIC MUX6", "DMIC4", "TX DMIC4"},
1624 {"TX DMIC MUX6", "DMIC5", "TX DMIC5"},
1625 {"TX DMIC MUX6", "DMIC6", "TX DMIC6"},
1626 {"TX DMIC MUX6", "DMIC7", "TX DMIC7"},
1627
1628 {"TX DEC6 MUX", "SWR_MIC", "TX SMIC MUX6"},
Sudheer Papothie456c2c2019-03-05 07:08:45 +05301629 {"TX SMIC MUX6", NULL, "TX_SWR_CLK"},
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301630 {"TX SMIC MUX6", "ADC0", "TX SWR_ADC0"},
1631 {"TX SMIC MUX6", "ADC1", "TX SWR_ADC1"},
1632 {"TX SMIC MUX6", "ADC2", "TX SWR_ADC2"},
1633 {"TX SMIC MUX6", "ADC3", "TX SWR_ADC3"},
1634 {"TX SMIC MUX6", "SWR_DMIC0", "TX SWR_DMIC0"},
1635 {"TX SMIC MUX6", "SWR_DMIC1", "TX SWR_DMIC1"},
1636 {"TX SMIC MUX6", "SWR_DMIC2", "TX SWR_DMIC2"},
1637 {"TX SMIC MUX6", "SWR_DMIC3", "TX SWR_DMIC3"},
1638 {"TX SMIC MUX6", "SWR_DMIC4", "TX SWR_DMIC4"},
1639 {"TX SMIC MUX6", "SWR_DMIC5", "TX SWR_DMIC5"},
1640 {"TX SMIC MUX6", "SWR_DMIC6", "TX SWR_DMIC6"},
1641 {"TX SMIC MUX6", "SWR_DMIC7", "TX SWR_DMIC7"},
1642
1643 {"TX DEC7 MUX", "MSM_DMIC", "TX DMIC MUX7"},
1644 {"TX DMIC MUX7", "DMIC0", "TX DMIC0"},
1645 {"TX DMIC MUX7", "DMIC1", "TX DMIC1"},
1646 {"TX DMIC MUX7", "DMIC2", "TX DMIC2"},
1647 {"TX DMIC MUX7", "DMIC3", "TX DMIC3"},
1648 {"TX DMIC MUX7", "DMIC4", "TX DMIC4"},
1649 {"TX DMIC MUX7", "DMIC5", "TX DMIC5"},
1650 {"TX DMIC MUX7", "DMIC6", "TX DMIC6"},
1651 {"TX DMIC MUX7", "DMIC7", "TX DMIC7"},
1652
1653 {"TX DEC7 MUX", "SWR_MIC", "TX SMIC MUX7"},
Sudheer Papothie456c2c2019-03-05 07:08:45 +05301654 {"TX SMIC MUX7", NULL, "TX_SWR_CLK"},
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301655 {"TX SMIC MUX7", "ADC0", "TX SWR_ADC0"},
1656 {"TX SMIC MUX7", "ADC1", "TX SWR_ADC1"},
1657 {"TX SMIC MUX7", "ADC2", "TX SWR_ADC2"},
1658 {"TX SMIC MUX7", "ADC3", "TX SWR_ADC3"},
1659 {"TX SMIC MUX7", "SWR_DMIC0", "TX SWR_DMIC0"},
1660 {"TX SMIC MUX7", "SWR_DMIC1", "TX SWR_DMIC1"},
1661 {"TX SMIC MUX7", "SWR_DMIC2", "TX SWR_DMIC2"},
1662 {"TX SMIC MUX7", "SWR_DMIC3", "TX SWR_DMIC3"},
1663 {"TX SMIC MUX7", "SWR_DMIC4", "TX SWR_DMIC4"},
1664 {"TX SMIC MUX7", "SWR_DMIC5", "TX SWR_DMIC5"},
1665 {"TX SMIC MUX7", "SWR_DMIC6", "TX SWR_DMIC6"},
1666 {"TX SMIC MUX7", "SWR_DMIC7", "TX SWR_DMIC7"},
1667};
1668
1669static const struct snd_kcontrol_new tx_macro_snd_controls[] = {
1670 SOC_SINGLE_SX_TLV("TX_DEC0 Volume",
1671 BOLERO_CDC_TX0_TX_VOL_CTL,
1672 0, -84, 40, digital_gain),
1673 SOC_SINGLE_SX_TLV("TX_DEC1 Volume",
1674 BOLERO_CDC_TX1_TX_VOL_CTL,
1675 0, -84, 40, digital_gain),
1676 SOC_SINGLE_SX_TLV("TX_DEC2 Volume",
1677 BOLERO_CDC_TX2_TX_VOL_CTL,
1678 0, -84, 40, digital_gain),
1679 SOC_SINGLE_SX_TLV("TX_DEC3 Volume",
1680 BOLERO_CDC_TX3_TX_VOL_CTL,
1681 0, -84, 40, digital_gain),
1682 SOC_SINGLE_SX_TLV("TX_DEC4 Volume",
1683 BOLERO_CDC_TX4_TX_VOL_CTL,
1684 0, -84, 40, digital_gain),
1685 SOC_SINGLE_SX_TLV("TX_DEC5 Volume",
1686 BOLERO_CDC_TX5_TX_VOL_CTL,
1687 0, -84, 40, digital_gain),
1688 SOC_SINGLE_SX_TLV("TX_DEC6 Volume",
1689 BOLERO_CDC_TX6_TX_VOL_CTL,
1690 0, -84, 40, digital_gain),
1691 SOC_SINGLE_SX_TLV("TX_DEC7 Volume",
1692 BOLERO_CDC_TX7_TX_VOL_CTL,
1693 0, -84, 40, digital_gain),
Karthikeyan Mani765eaab2019-07-18 16:27:01 -07001694
Karthikeyan Mani1dcd5a32019-08-22 14:37:13 -07001695 SOC_ENUM_EXT("DEC0 MODE", dec_mode_mux_enum,
1696 tx_macro_dec_mode_get, tx_macro_dec_mode_put),
1697
1698 SOC_ENUM_EXT("DEC1 MODE", dec_mode_mux_enum,
1699 tx_macro_dec_mode_get, tx_macro_dec_mode_put),
1700
1701 SOC_ENUM_EXT("DEC2 MODE", dec_mode_mux_enum,
1702 tx_macro_dec_mode_get, tx_macro_dec_mode_put),
1703
1704 SOC_ENUM_EXT("DEC3 MODE", dec_mode_mux_enum,
1705 tx_macro_dec_mode_get, tx_macro_dec_mode_put),
1706
1707 SOC_ENUM_EXT("DEC4 MODE", dec_mode_mux_enum,
1708 tx_macro_dec_mode_get, tx_macro_dec_mode_put),
1709
1710 SOC_ENUM_EXT("DEC5 MODE", dec_mode_mux_enum,
1711 tx_macro_dec_mode_get, tx_macro_dec_mode_put),
1712
1713 SOC_ENUM_EXT("DEC6 MODE", dec_mode_mux_enum,
1714 tx_macro_dec_mode_get, tx_macro_dec_mode_put),
1715
1716 SOC_ENUM_EXT("DEC7 MODE", dec_mode_mux_enum,
1717 tx_macro_dec_mode_get, tx_macro_dec_mode_put),
1718
Karthikeyan Mani765eaab2019-07-18 16:27:01 -07001719 SOC_SINGLE_EXT("DEC0_BCS Switch", SND_SOC_NOPM, 0, 1, 0,
1720 tx_macro_get_bcs, tx_macro_set_bcs),
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301721};
1722
Sudheer Papothia7397942019-03-19 03:14:23 +05301723static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv,
1724 struct regmap *regmap, int clk_type,
1725 bool enable)
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301726{
Meng Wang69b55c82019-05-29 11:04:29 +08001727 int ret = 0, clk_tx_ret = 0;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301728
Sudheer Papothi7601cc62019-03-30 03:00:52 +05301729 dev_dbg(tx_priv->dev,
1730 "%s: clock type %s, enable: %s tx_mclk_users: %d\n",
Sudheer Papothia7397942019-03-19 03:14:23 +05301731 __func__, (clk_type ? "VA_MCLK" : "TX_MCLK"),
Sudheer Papothi7601cc62019-03-30 03:00:52 +05301732 (enable ? "enable" : "disable"), tx_priv->tx_mclk_users);
Tanya Dixit8530fb92018-09-14 16:01:25 +05301733
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301734 if (enable) {
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301735 if (tx_priv->swr_clk_users == 0)
Karthikeyan Mani01f1ba42019-02-26 18:48:15 -08001736 msm_cdc_pinctrl_select_active_state(
1737 tx_priv->tx_swr_gpio_p);
Sudheer Papothia7397942019-03-19 03:14:23 +05301738
Meng Wang69b55c82019-05-29 11:04:29 +08001739 clk_tx_ret = bolero_clk_rsc_request_clock(tx_priv->dev,
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301740 TX_CORE_CLK,
1741 TX_CORE_CLK,
1742 true);
1743 if (clk_type == TX_MCLK) {
1744 ret = tx_macro_mclk_enable(tx_priv, 1);
1745 if (ret < 0) {
1746 if (tx_priv->swr_clk_users == 0)
1747 msm_cdc_pinctrl_select_sleep_state(
1748 tx_priv->tx_swr_gpio_p);
1749 dev_err_ratelimited(tx_priv->dev,
1750 "%s: request clock enable failed\n",
1751 __func__);
1752 goto done;
1753 }
1754 }
1755 if (clk_type == VA_MCLK) {
Sudheer Papothia7397942019-03-19 03:14:23 +05301756 ret = bolero_clk_rsc_request_clock(tx_priv->dev,
1757 TX_CORE_CLK,
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301758 VA_CORE_CLK,
Sudheer Papothia7397942019-03-19 03:14:23 +05301759 true);
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301760 if (ret < 0) {
1761 if (tx_priv->swr_clk_users == 0)
Sudheer Papothia7397942019-03-19 03:14:23 +05301762 msm_cdc_pinctrl_select_sleep_state(
1763 tx_priv->tx_swr_gpio_p);
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301764 dev_err_ratelimited(tx_priv->dev,
1765 "%s: swr request clk failed\n",
1766 __func__);
1767 goto done;
Sudheer Papothia7397942019-03-19 03:14:23 +05301768 }
Sudheer Papothi296867b2019-06-20 09:24:09 +05301769 bolero_clk_rsc_fs_gen_request(tx_priv->dev,
1770 true);
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301771 if (tx_priv->tx_mclk_users == 0) {
1772 regmap_update_bits(regmap,
1773 BOLERO_CDC_TX_TOP_CSR_FREQ_MCLK,
1774 0x01, 0x01);
1775 regmap_update_bits(regmap,
1776 BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL,
1777 0x01, 0x01);
1778 regmap_update_bits(regmap,
1779 BOLERO_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL,
1780 0x01, 0x01);
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301781 }
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301782 }
1783 if (tx_priv->swr_clk_users == 0) {
Sudheer Papothi7601cc62019-03-30 03:00:52 +05301784 dev_dbg(tx_priv->dev, "%s: reset_swr: %d\n",
1785 __func__, tx_priv->reset_swr);
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05301786 if (tx_priv->reset_swr)
1787 regmap_update_bits(regmap,
1788 BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL,
1789 0x02, 0x02);
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301790 regmap_update_bits(regmap,
1791 BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL,
1792 0x01, 0x01);
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05301793 if (tx_priv->reset_swr)
1794 regmap_update_bits(regmap,
1795 BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL,
1796 0x02, 0x00);
1797 tx_priv->reset_swr = false;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301798 }
Meng Wang69b55c82019-05-29 11:04:29 +08001799 if (!clk_tx_ret)
1800 ret = bolero_clk_rsc_request_clock(tx_priv->dev,
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301801 TX_CORE_CLK,
1802 TX_CORE_CLK,
1803 false);
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301804 tx_priv->swr_clk_users++;
1805 } else {
1806 if (tx_priv->swr_clk_users <= 0) {
Sudheer Papothia7397942019-03-19 03:14:23 +05301807 dev_err_ratelimited(tx_priv->dev,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301808 "tx swrm clock users already 0\n");
1809 tx_priv->swr_clk_users = 0;
Sudheer Papothia7397942019-03-19 03:14:23 +05301810 return 0;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301811 }
Meng Wang69b55c82019-05-29 11:04:29 +08001812 clk_tx_ret = bolero_clk_rsc_request_clock(tx_priv->dev,
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301813 TX_CORE_CLK,
1814 TX_CORE_CLK,
1815 true);
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301816 tx_priv->swr_clk_users--;
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301817 if (tx_priv->swr_clk_users == 0)
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301818 regmap_update_bits(regmap,
1819 BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL,
1820 0x01, 0x00);
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301821 if (clk_type == TX_MCLK)
1822 tx_macro_mclk_enable(tx_priv, 0);
1823 if (clk_type == VA_MCLK) {
1824 if (tx_priv->tx_mclk_users == 0) {
1825 regmap_update_bits(regmap,
1826 BOLERO_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL,
1827 0x01, 0x00);
1828 regmap_update_bits(regmap,
1829 BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL,
1830 0x01, 0x00);
Sudheer Papothia7397942019-03-19 03:14:23 +05301831 }
Sudheer Papothi296867b2019-06-20 09:24:09 +05301832 bolero_clk_rsc_fs_gen_request(tx_priv->dev,
1833 false);
Sudheer Papothia7397942019-03-19 03:14:23 +05301834 ret = bolero_clk_rsc_request_clock(tx_priv->dev,
1835 TX_CORE_CLK,
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301836 VA_CORE_CLK,
Sudheer Papothia7397942019-03-19 03:14:23 +05301837 false);
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301838 if (ret < 0) {
1839 dev_err_ratelimited(tx_priv->dev,
1840 "%s: swr request clk failed\n",
1841 __func__);
1842 goto done;
1843 }
1844 }
Meng Wang69b55c82019-05-29 11:04:29 +08001845 if (!clk_tx_ret)
1846 ret = bolero_clk_rsc_request_clock(tx_priv->dev,
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301847 TX_CORE_CLK,
1848 TX_CORE_CLK,
1849 false);
1850 if (tx_priv->swr_clk_users == 0)
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301851 msm_cdc_pinctrl_select_sleep_state(
1852 tx_priv->tx_swr_gpio_p);
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301853 }
Sudheer Papothia7397942019-03-19 03:14:23 +05301854 return 0;
1855
1856done:
Meng Wang69b55c82019-05-29 11:04:29 +08001857 if (!clk_tx_ret)
1858 bolero_clk_rsc_request_clock(tx_priv->dev,
Sudheer Papothia7397942019-03-19 03:14:23 +05301859 TX_CORE_CLK,
1860 TX_CORE_CLK,
1861 false);
1862 return ret;
1863}
1864
Sudheer Papothi6cc7f522019-06-28 11:04:03 +05301865static int tx_macro_clk_switch(struct snd_soc_component *component)
1866{
1867 struct device *tx_dev = NULL;
1868 struct tx_macro_priv *tx_priv = NULL;
1869 int ret = 0;
1870
1871 if (!component)
1872 return -EINVAL;
1873
1874 tx_dev = bolero_get_device_ptr(component->dev, TX_MACRO);
1875 if (!tx_dev) {
1876 dev_err(component->dev,
1877 "%s: null device for macro!\n", __func__);
1878 return -EINVAL;
1879 }
1880 tx_priv = dev_get_drvdata(tx_dev);
1881 if (!tx_priv) {
1882 dev_err(component->dev,
1883 "%s: priv is null for macro!\n", __func__);
1884 return -EINVAL;
1885 }
1886 if (tx_priv->swr_ctrl_data) {
1887 ret = swrm_wcd_notify(
1888 tx_priv->swr_ctrl_data[0].tx_swr_pdev,
1889 SWR_REQ_CLK_SWITCH, NULL);
1890 }
1891
1892 return ret;
1893}
1894
Sudheer Papothia7397942019-03-19 03:14:23 +05301895static int tx_macro_swrm_clock(void *handle, bool enable)
1896{
1897 struct tx_macro_priv *tx_priv = (struct tx_macro_priv *) handle;
1898 struct regmap *regmap = dev_get_regmap(tx_priv->dev->parent, NULL);
1899 int ret = 0;
1900
1901 if (regmap == NULL) {
1902 dev_err(tx_priv->dev, "%s: regmap is NULL\n", __func__);
1903 return -EINVAL;
1904 }
1905
1906 mutex_lock(&tx_priv->swr_clk_lock);
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301907 dev_dbg(tx_priv->dev,
1908 "%s: swrm clock %s tx_swr_clk_cnt: %d va_swr_clk_cnt: %d\n",
1909 __func__, (enable ? "enable" : "disable"),
1910 tx_priv->tx_swr_clk_cnt, tx_priv->va_swr_clk_cnt);
Sudheer Papothia7397942019-03-19 03:14:23 +05301911
1912 if (enable) {
Sudheer Papothi7601cc62019-03-30 03:00:52 +05301913 pm_runtime_get_sync(tx_priv->dev);
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301914 if (tx_priv->va_swr_clk_cnt && !tx_priv->tx_swr_clk_cnt) {
Sudheer Papothia7397942019-03-19 03:14:23 +05301915 ret = tx_macro_tx_va_mclk_enable(tx_priv, regmap,
1916 VA_MCLK, enable);
1917 if (ret)
1918 goto done;
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301919 tx_priv->va_clk_status++;
Sudheer Papothia7397942019-03-19 03:14:23 +05301920 } else {
Sudheer Papothia7397942019-03-19 03:14:23 +05301921 ret = tx_macro_tx_va_mclk_enable(tx_priv, regmap,
1922 TX_MCLK, enable);
1923 if (ret)
1924 goto done;
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301925 tx_priv->tx_clk_status++;
Sudheer Papothia7397942019-03-19 03:14:23 +05301926 }
Sudheer Papothi7601cc62019-03-30 03:00:52 +05301927 pm_runtime_mark_last_busy(tx_priv->dev);
1928 pm_runtime_put_autosuspend(tx_priv->dev);
Sudheer Papothia7397942019-03-19 03:14:23 +05301929 } else {
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301930 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 VA_MCLK, enable);
1933 if (ret)
1934 goto done;
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301935 --tx_priv->va_clk_status;
1936 } else if (!tx_priv->va_clk_status && tx_priv->tx_clk_status) {
Sudheer Papothia7397942019-03-19 03:14:23 +05301937 ret = tx_macro_tx_va_mclk_enable(tx_priv, regmap,
1938 TX_MCLK, enable);
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301939 if (ret)
1940 goto done;
1941 --tx_priv->tx_clk_status;
1942 } else if (tx_priv->va_clk_status && tx_priv->tx_clk_status) {
1943 if (!tx_priv->va_swr_clk_cnt && tx_priv->tx_swr_clk_cnt) {
1944 ret = tx_macro_tx_va_mclk_enable(tx_priv, regmap,
1945 VA_MCLK, enable);
Sudheer Papothia7397942019-03-19 03:14:23 +05301946 if (ret)
1947 goto done;
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301948 --tx_priv->va_clk_status;
1949 } else {
1950 ret = tx_macro_tx_va_mclk_enable(tx_priv, regmap,
1951 TX_MCLK, enable);
1952 if (ret)
1953 goto done;
1954 --tx_priv->tx_clk_status;
Sudheer Papothia7397942019-03-19 03:14:23 +05301955 }
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301956
1957 } else {
1958 dev_dbg(tx_priv->dev,
1959 "%s: Both clocks are disabled\n", __func__);
Sudheer Papothia7397942019-03-19 03:14:23 +05301960 }
1961 }
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301962
1963 dev_dbg(tx_priv->dev,
1964 "%s: swrm clock users %d tx_clk_sts_cnt: %d va_clk_sts_cnt: %d\n",
1965 __func__, tx_priv->swr_clk_users, tx_priv->tx_clk_status,
1966 tx_priv->va_clk_status);
Sudheer Papothia7397942019-03-19 03:14:23 +05301967done:
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301968 mutex_unlock(&tx_priv->swr_clk_lock);
1969 return ret;
1970}
1971
1972static int tx_macro_validate_dmic_sample_rate(u32 dmic_sample_rate,
1973 struct tx_macro_priv *tx_priv)
1974{
1975 u32 div_factor = TX_MACRO_CLK_DIV_2;
1976 u32 mclk_rate = TX_MACRO_MCLK_FREQ;
1977
1978 if (dmic_sample_rate == TX_MACRO_DMIC_SAMPLE_RATE_UNDEFINED ||
1979 mclk_rate % dmic_sample_rate != 0)
1980 goto undefined_rate;
1981
1982 div_factor = mclk_rate / dmic_sample_rate;
1983
1984 switch (div_factor) {
1985 case 2:
1986 tx_priv->dmic_clk_div = TX_MACRO_CLK_DIV_2;
1987 break;
1988 case 3:
1989 tx_priv->dmic_clk_div = TX_MACRO_CLK_DIV_3;
1990 break;
1991 case 4:
1992 tx_priv->dmic_clk_div = TX_MACRO_CLK_DIV_4;
1993 break;
1994 case 6:
1995 tx_priv->dmic_clk_div = TX_MACRO_CLK_DIV_6;
1996 break;
1997 case 8:
1998 tx_priv->dmic_clk_div = TX_MACRO_CLK_DIV_8;
1999 break;
2000 case 16:
2001 tx_priv->dmic_clk_div = TX_MACRO_CLK_DIV_16;
2002 break;
2003 default:
2004 /* Any other DIV factor is invalid */
2005 goto undefined_rate;
2006 }
2007
2008 /* Valid dmic DIV factors */
2009 dev_dbg(tx_priv->dev, "%s: DMIC_DIV = %u, mclk_rate = %u\n",
2010 __func__, div_factor, mclk_rate);
2011
2012 return dmic_sample_rate;
2013
2014undefined_rate:
2015 dev_dbg(tx_priv->dev, "%s: Invalid rate %d, for mclk %d\n",
2016 __func__, dmic_sample_rate, mclk_rate);
2017 dmic_sample_rate = TX_MACRO_DMIC_SAMPLE_RATE_UNDEFINED;
2018
2019 return dmic_sample_rate;
2020}
2021
Sudheer Papothi72fef482019-08-30 11:00:20 +05302022static const struct tx_macro_reg_mask_val tx_macro_reg_init[] = {
2023 {BOLERO_CDC_TX0_TX_PATH_SEC7, 0x3F, 0x0E},
2024};
2025
Meng Wang15c825d2018-09-06 10:49:18 +08002026static int tx_macro_init(struct snd_soc_component *component)
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302027{
Meng Wang15c825d2018-09-06 10:49:18 +08002028 struct snd_soc_dapm_context *dapm =
2029 snd_soc_component_get_dapm(component);
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302030 int ret = 0, i = 0;
2031 struct device *tx_dev = NULL;
2032 struct tx_macro_priv *tx_priv = NULL;
2033
Meng Wang15c825d2018-09-06 10:49:18 +08002034 tx_dev = bolero_get_device_ptr(component->dev, TX_MACRO);
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302035 if (!tx_dev) {
Meng Wang15c825d2018-09-06 10:49:18 +08002036 dev_err(component->dev,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302037 "%s: null device for macro!\n", __func__);
2038 return -EINVAL;
2039 }
2040 tx_priv = dev_get_drvdata(tx_dev);
2041 if (!tx_priv) {
Meng Wang15c825d2018-09-06 10:49:18 +08002042 dev_err(component->dev,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302043 "%s: priv is null for macro!\n", __func__);
2044 return -EINVAL;
2045 }
2046 ret = snd_soc_dapm_new_controls(dapm, tx_macro_dapm_widgets,
2047 ARRAY_SIZE(tx_macro_dapm_widgets));
2048 if (ret < 0) {
2049 dev_err(tx_dev, "%s: Failed to add controls\n", __func__);
2050 return ret;
2051 }
2052
2053 ret = snd_soc_dapm_add_routes(dapm, tx_audio_map,
2054 ARRAY_SIZE(tx_audio_map));
2055 if (ret < 0) {
2056 dev_err(tx_dev, "%s: Failed to add routes\n", __func__);
2057 return ret;
2058 }
2059
2060 ret = snd_soc_dapm_new_widgets(dapm->card);
2061 if (ret < 0) {
2062 dev_err(tx_dev, "%s: Failed to add widgets\n", __func__);
2063 return ret;
2064 }
2065
Meng Wang15c825d2018-09-06 10:49:18 +08002066 ret = snd_soc_add_component_controls(component, tx_macro_snd_controls,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302067 ARRAY_SIZE(tx_macro_snd_controls));
2068 if (ret < 0) {
2069 dev_err(tx_dev, "%s: Failed to add snd_ctls\n", __func__);
2070 return ret;
2071 }
Laxminath Kasam638b5602018-09-24 13:19:52 +05302072
2073 snd_soc_dapm_ignore_suspend(dapm, "TX_AIF1 Capture");
2074 snd_soc_dapm_ignore_suspend(dapm, "TX_AIF2 Capture");
Karthikeyan Manif3bb8182019-07-11 14:38:54 -07002075 snd_soc_dapm_ignore_suspend(dapm, "TX_AIF3 Capture");
Laxminath Kasam638b5602018-09-24 13:19:52 +05302076 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC0");
2077 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC1");
2078 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC2");
2079 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC3");
Vatsal Bucha39ead2c2018-12-14 12:22:46 +05302080 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC0");
2081 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC1");
2082 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC2");
2083 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC3");
2084 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC4");
2085 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC5");
2086 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC6");
2087 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC7");
Laxminath Kasam638b5602018-09-24 13:19:52 +05302088 snd_soc_dapm_sync(dapm);
2089
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302090 for (i = 0; i < NUM_DECIMATORS; i++) {
2091 tx_priv->tx_hpf_work[i].tx_priv = tx_priv;
2092 tx_priv->tx_hpf_work[i].decimator = i;
2093 INIT_DELAYED_WORK(&tx_priv->tx_hpf_work[i].dwork,
2094 tx_macro_tx_hpf_corner_freq_callback);
2095 }
2096
2097 for (i = 0; i < NUM_DECIMATORS; i++) {
2098 tx_priv->tx_mute_dwork[i].tx_priv = tx_priv;
2099 tx_priv->tx_mute_dwork[i].decimator = i;
2100 INIT_DELAYED_WORK(&tx_priv->tx_mute_dwork[i].dwork,
2101 tx_macro_mute_update_callback);
2102 }
Meng Wang15c825d2018-09-06 10:49:18 +08002103 tx_priv->component = component;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302104
Sudheer Papothi72fef482019-08-30 11:00:20 +05302105 for (i = 0; i < ARRAY_SIZE(tx_macro_reg_init); i++)
2106 snd_soc_component_update_bits(component,
2107 tx_macro_reg_init[i].reg,
2108 tx_macro_reg_init[i].mask,
2109 tx_macro_reg_init[i].val);
2110
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302111 return 0;
2112}
2113
Meng Wang15c825d2018-09-06 10:49:18 +08002114static int tx_macro_deinit(struct snd_soc_component *component)
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302115{
2116 struct device *tx_dev = NULL;
2117 struct tx_macro_priv *tx_priv = NULL;
2118
Meng Wang15c825d2018-09-06 10:49:18 +08002119 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302120 return -EINVAL;
2121
Meng Wang15c825d2018-09-06 10:49:18 +08002122 tx_priv->component = NULL;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302123 return 0;
2124}
2125
2126static void tx_macro_add_child_devices(struct work_struct *work)
2127{
2128 struct tx_macro_priv *tx_priv = NULL;
2129 struct platform_device *pdev = NULL;
2130 struct device_node *node = NULL;
2131 struct tx_macro_swr_ctrl_data *swr_ctrl_data = NULL, *temp = NULL;
2132 int ret = 0;
2133 u16 count = 0, ctrl_num = 0;
2134 struct tx_macro_swr_ctrl_platform_data *platdata = NULL;
2135 char plat_dev_name[TX_MACRO_SWR_STRING_LEN] = "";
2136 bool tx_swr_master_node = false;
2137
2138 tx_priv = container_of(work, struct tx_macro_priv,
2139 tx_macro_add_child_devices_work);
2140 if (!tx_priv) {
2141 pr_err("%s: Memory for tx_priv does not exist\n",
2142 __func__);
2143 return;
2144 }
2145
2146 if (!tx_priv->dev) {
2147 pr_err("%s: tx dev does not exist\n", __func__);
2148 return;
2149 }
2150
2151 if (!tx_priv->dev->of_node) {
2152 dev_err(tx_priv->dev,
2153 "%s: DT node for tx_priv does not exist\n", __func__);
2154 return;
2155 }
2156
2157 platdata = &tx_priv->swr_plat_data;
2158 tx_priv->child_count = 0;
2159
2160 for_each_available_child_of_node(tx_priv->dev->of_node, node) {
2161 tx_swr_master_node = false;
2162 if (strnstr(node->name, "tx_swr_master",
2163 strlen("tx_swr_master")) != NULL)
2164 tx_swr_master_node = true;
2165
2166 if (tx_swr_master_node)
2167 strlcpy(plat_dev_name, "tx_swr_ctrl",
2168 (TX_MACRO_SWR_STRING_LEN - 1));
2169 else
2170 strlcpy(plat_dev_name, node->name,
2171 (TX_MACRO_SWR_STRING_LEN - 1));
2172
2173 pdev = platform_device_alloc(plat_dev_name, -1);
2174 if (!pdev) {
2175 dev_err(tx_priv->dev, "%s: pdev memory alloc failed\n",
2176 __func__);
2177 ret = -ENOMEM;
2178 goto err;
2179 }
2180 pdev->dev.parent = tx_priv->dev;
2181 pdev->dev.of_node = node;
2182
2183 if (tx_swr_master_node) {
2184 ret = platform_device_add_data(pdev, platdata,
2185 sizeof(*platdata));
2186 if (ret) {
2187 dev_err(&pdev->dev,
2188 "%s: cannot add plat data ctrl:%d\n",
2189 __func__, ctrl_num);
2190 goto fail_pdev_add;
2191 }
2192 }
2193
2194 ret = platform_device_add(pdev);
2195 if (ret) {
2196 dev_err(&pdev->dev,
2197 "%s: Cannot add platform device\n",
2198 __func__);
2199 goto fail_pdev_add;
2200 }
2201
2202 if (tx_swr_master_node) {
2203 temp = krealloc(swr_ctrl_data,
2204 (ctrl_num + 1) * sizeof(
2205 struct tx_macro_swr_ctrl_data),
2206 GFP_KERNEL);
2207 if (!temp) {
2208 ret = -ENOMEM;
2209 goto fail_pdev_add;
2210 }
2211 swr_ctrl_data = temp;
2212 swr_ctrl_data[ctrl_num].tx_swr_pdev = pdev;
2213 ctrl_num++;
2214 dev_dbg(&pdev->dev,
2215 "%s: Added soundwire ctrl device(s)\n",
2216 __func__);
2217 tx_priv->swr_ctrl_data = swr_ctrl_data;
2218 }
2219 if (tx_priv->child_count < TX_MACRO_CHILD_DEVICES_MAX)
2220 tx_priv->pdev_child_devices[
2221 tx_priv->child_count++] = pdev;
2222 else
2223 goto err;
2224 }
2225 return;
2226fail_pdev_add:
2227 for (count = 0; count < tx_priv->child_count; count++)
2228 platform_device_put(tx_priv->pdev_child_devices[count]);
2229err:
2230 return;
2231}
2232
Sudheer Papothia3e969d2018-10-27 06:22:10 +05302233static int tx_macro_set_port_map(struct snd_soc_component *component,
2234 u32 usecase, u32 size, void *data)
2235{
2236 struct device *tx_dev = NULL;
2237 struct tx_macro_priv *tx_priv = NULL;
2238 struct swrm_port_config port_cfg;
2239 int ret = 0;
2240
2241 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
2242 return -EINVAL;
2243
2244 memset(&port_cfg, 0, sizeof(port_cfg));
2245 port_cfg.uc = usecase;
2246 port_cfg.size = size;
2247 port_cfg.params = data;
2248
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07002249 if (tx_priv->swr_ctrl_data)
2250 ret = swrm_wcd_notify(
2251 tx_priv->swr_ctrl_data[0].tx_swr_pdev,
2252 SWR_SET_PORT_MAP, &port_cfg);
Sudheer Papothia3e969d2018-10-27 06:22:10 +05302253
2254 return ret;
2255}
2256
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302257static void tx_macro_init_ops(struct macro_ops *ops,
2258 char __iomem *tx_io_base)
2259{
2260 memset(ops, 0, sizeof(struct macro_ops));
2261 ops->init = tx_macro_init;
2262 ops->exit = tx_macro_deinit;
2263 ops->io_base = tx_io_base;
2264 ops->dai_ptr = tx_macro_dai;
2265 ops->num_dais = ARRAY_SIZE(tx_macro_dai);
Laxminath Kasamfb0d6832018-09-22 01:49:52 +05302266 ops->event_handler = tx_macro_event_handler;
Aditya Bavanaric4e96122018-11-14 14:46:38 +05302267 ops->reg_wake_irq = tx_macro_reg_wake_irq;
Sudheer Papothia3e969d2018-10-27 06:22:10 +05302268 ops->set_port_map = tx_macro_set_port_map;
Sudheer Papothi6cc7f522019-06-28 11:04:03 +05302269 ops->clk_switch = tx_macro_clk_switch;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302270}
2271
2272static int tx_macro_probe(struct platform_device *pdev)
2273{
2274 struct macro_ops ops = {0};
2275 struct tx_macro_priv *tx_priv = NULL;
2276 u32 tx_base_addr = 0, sample_rate = 0;
2277 char __iomem *tx_io_base = NULL;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302278 int ret = 0;
2279 const char *dmic_sample_rate = "qcom,tx-dmic-sample-rate";
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07002280 u32 is_used_tx_swr_gpio = 1;
2281 const char *is_used_tx_swr_gpio_dt = "qcom,is-used-swr-gpio";
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302282
2283 tx_priv = devm_kzalloc(&pdev->dev, sizeof(struct tx_macro_priv),
2284 GFP_KERNEL);
2285 if (!tx_priv)
2286 return -ENOMEM;
2287 platform_set_drvdata(pdev, tx_priv);
2288
2289 tx_priv->dev = &pdev->dev;
2290 ret = of_property_read_u32(pdev->dev.of_node, "reg",
2291 &tx_base_addr);
2292 if (ret) {
2293 dev_err(&pdev->dev, "%s: could not find %s entry in dt\n",
2294 __func__, "reg");
2295 return ret;
2296 }
2297 dev_set_drvdata(&pdev->dev, tx_priv);
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07002298 if (of_find_property(pdev->dev.of_node, is_used_tx_swr_gpio_dt,
2299 NULL)) {
2300 ret = of_property_read_u32(pdev->dev.of_node,
2301 is_used_tx_swr_gpio_dt,
2302 &is_used_tx_swr_gpio);
2303 if (ret) {
2304 dev_err(&pdev->dev, "%s: error reading %s in dt\n",
2305 __func__, is_used_tx_swr_gpio_dt);
2306 is_used_tx_swr_gpio = 1;
2307 }
2308 }
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302309 tx_priv->tx_swr_gpio_p = of_parse_phandle(pdev->dev.of_node,
2310 "qcom,tx-swr-gpios", 0);
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07002311 if (!tx_priv->tx_swr_gpio_p && is_used_tx_swr_gpio) {
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302312 dev_err(&pdev->dev, "%s: swr_gpios handle not provided!\n",
2313 __func__);
2314 return -EINVAL;
2315 }
Karthikeyan Mani326536d2019-06-03 13:29:43 -07002316 if (msm_cdc_pinctrl_get_state(tx_priv->tx_swr_gpio_p) < 0) {
2317 dev_err(&pdev->dev, "%s: failed to get swr pin state\n",
2318 __func__);
2319 return -EPROBE_DEFER;
2320 }
2321
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302322 tx_io_base = devm_ioremap(&pdev->dev,
2323 tx_base_addr, TX_MACRO_MAX_OFFSET);
2324 if (!tx_io_base) {
2325 dev_err(&pdev->dev, "%s: ioremap failed\n", __func__);
2326 return -ENOMEM;
2327 }
2328 tx_priv->tx_io_base = tx_io_base;
2329 ret = of_property_read_u32(pdev->dev.of_node, dmic_sample_rate,
2330 &sample_rate);
2331 if (ret) {
2332 dev_err(&pdev->dev,
2333 "%s: could not find sample_rate entry in dt\n",
2334 __func__);
2335 tx_priv->dmic_clk_div = TX_MACRO_CLK_DIV_2;
2336 } else {
2337 if (tx_macro_validate_dmic_sample_rate(
2338 sample_rate, tx_priv) == TX_MACRO_DMIC_SAMPLE_RATE_UNDEFINED)
2339 return -EINVAL;
2340 }
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05302341 tx_priv->reset_swr = true;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302342 INIT_WORK(&tx_priv->tx_macro_add_child_devices_work,
2343 tx_macro_add_child_devices);
2344 tx_priv->swr_plat_data.handle = (void *) tx_priv;
2345 tx_priv->swr_plat_data.read = NULL;
2346 tx_priv->swr_plat_data.write = NULL;
2347 tx_priv->swr_plat_data.bulk_write = NULL;
2348 tx_priv->swr_plat_data.clk = tx_macro_swrm_clock;
2349 tx_priv->swr_plat_data.handle_irq = NULL;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302350
2351 mutex_init(&tx_priv->mclk_lock);
2352 mutex_init(&tx_priv->swr_clk_lock);
2353 tx_macro_init_ops(&ops, tx_io_base);
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07002354 ops.clk_id_req = TX_CORE_CLK;
2355 ops.default_clk_id = TX_CORE_CLK;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302356 ret = bolero_register_macro(&pdev->dev, TX_MACRO, &ops);
2357 if (ret) {
2358 dev_err(&pdev->dev,
2359 "%s: register macro failed\n", __func__);
2360 goto err_reg_macro;
2361 }
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07002362
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302363 schedule_work(&tx_priv->tx_macro_add_child_devices_work);
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302364 pm_runtime_set_autosuspend_delay(&pdev->dev, AUTO_SUSPEND_DELAY);
2365 pm_runtime_use_autosuspend(&pdev->dev);
2366 pm_runtime_set_suspended(&pdev->dev);
Sudheer Papothi296867b2019-06-20 09:24:09 +05302367 pm_suspend_ignore_children(&pdev->dev, true);
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302368 pm_runtime_enable(&pdev->dev);
2369
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302370 return 0;
2371err_reg_macro:
2372 mutex_destroy(&tx_priv->mclk_lock);
2373 mutex_destroy(&tx_priv->swr_clk_lock);
2374 return ret;
2375}
2376
2377static int tx_macro_remove(struct platform_device *pdev)
2378{
2379 struct tx_macro_priv *tx_priv = NULL;
2380 u16 count = 0;
2381
2382 tx_priv = platform_get_drvdata(pdev);
2383
2384 if (!tx_priv)
2385 return -EINVAL;
2386
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07002387 if (tx_priv->swr_ctrl_data)
2388 kfree(tx_priv->swr_ctrl_data);
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302389 for (count = 0; count < tx_priv->child_count &&
2390 count < TX_MACRO_CHILD_DEVICES_MAX; count++)
2391 platform_device_unregister(tx_priv->pdev_child_devices[count]);
2392
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302393 pm_runtime_disable(&pdev->dev);
2394 pm_runtime_set_suspended(&pdev->dev);
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302395 mutex_destroy(&tx_priv->mclk_lock);
2396 mutex_destroy(&tx_priv->swr_clk_lock);
2397 bolero_unregister_macro(&pdev->dev, TX_MACRO);
2398 return 0;
2399}
2400
2401
2402static const struct of_device_id tx_macro_dt_match[] = {
2403 {.compatible = "qcom,tx-macro"},
2404 {}
2405};
2406
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302407static const struct dev_pm_ops bolero_dev_pm_ops = {
2408 SET_RUNTIME_PM_OPS(
2409 bolero_runtime_suspend,
2410 bolero_runtime_resume,
2411 NULL
2412 )
2413};
2414
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302415static struct platform_driver tx_macro_driver = {
2416 .driver = {
2417 .name = "tx_macro",
2418 .owner = THIS_MODULE,
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302419 .pm = &bolero_dev_pm_ops,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302420 .of_match_table = tx_macro_dt_match,
Xiaojun Sang53cd13a2018-06-29 15:14:37 +08002421 .suppress_bind_attrs = true,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302422 },
2423 .probe = tx_macro_probe,
2424 .remove = tx_macro_remove,
2425};
2426
2427module_platform_driver(tx_macro_driver);
2428
2429MODULE_DESCRIPTION("TX macro driver");
2430MODULE_LICENSE("GPL v2");