blob: 73ce9d254aee76b7231e131bd0c4f8da61039b67 [file] [log] [blame]
Meng Wang43bbb872018-12-10 12:32:05 +08001// SPDX-License-Identifier: GPL-2.0-only
Vatsal Bucha39ead2c2018-12-14 12:22:46 +05302/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
Laxminath Kasam989fccf2018-06-15 16:53:31 +05303 */
4
5#include <linux/module.h>
6#include <linux/init.h>
7#include <linux/clk.h>
8#include <linux/io.h>
9#include <linux/platform_device.h>
10#include <linux/regmap.h>
Sudheer Papothi7601cc62019-03-30 03:00:52 +053011#include <linux/pm_runtime.h>
Laxminath Kasam989fccf2018-06-15 16:53:31 +053012#include <sound/soc.h>
13#include <sound/soc-dapm.h>
14#include <sound/tlv.h>
Sudheer Papothia3e969d2018-10-27 06:22:10 +053015#include <soc/swr-common.h>
Laxminath Kasamfb0d6832018-09-22 01:49:52 +053016#include <soc/swr-wcd.h>
Meng Wang11a25cf2018-10-31 14:11:26 +080017#include <asoc/msm-cdc-pinctrl.h>
Laxminath Kasam989fccf2018-06-15 16:53:31 +053018#include "bolero-cdc.h"
19#include "bolero-cdc-registers.h"
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -070020#include "bolero-clk-rsc.h"
Laxminath Kasam989fccf2018-06-15 16:53:31 +053021
Sudheer Papothi7601cc62019-03-30 03:00:52 +053022#define AUTO_SUSPEND_DELAY 50 /* delay in msec */
Laxminath Kasam989fccf2018-06-15 16:53:31 +053023#define TX_MACRO_MAX_OFFSET 0x1000
24
25#define NUM_DECIMATORS 8
26
27#define TX_MACRO_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
28 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
29 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
30#define TX_MACRO_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
31 SNDRV_PCM_FMTBIT_S24_LE |\
32 SNDRV_PCM_FMTBIT_S24_3LE)
33
34#define TX_HPF_CUT_OFF_FREQ_MASK 0x60
35#define CF_MIN_3DB_4HZ 0x0
36#define CF_MIN_3DB_75HZ 0x1
37#define CF_MIN_3DB_150HZ 0x2
38
39#define TX_MACRO_DMIC_SAMPLE_RATE_UNDEFINED 0
40#define TX_MACRO_MCLK_FREQ 9600000
41#define TX_MACRO_TX_PATH_OFFSET 0x80
Laxminath Kasam497a6512018-09-17 16:11:52 +053042#define TX_MACRO_SWR_MIC_MUX_SEL_MASK 0xF
43#define TX_MACRO_ADC_MUX_CFG_OFFSET 0x2
Karthikeyan Mani1dcd5a32019-08-22 14:37:13 -070044#define TX_MACRO_ADC_MODE_CFG0_SHIFT 1
Laxminath Kasam989fccf2018-06-15 16:53:31 +053045
46#define TX_MACRO_TX_UNMUTE_DELAY_MS 40
47
48static int tx_unmute_delay = TX_MACRO_TX_UNMUTE_DELAY_MS;
49module_param(tx_unmute_delay, int, 0664);
50MODULE_PARM_DESC(tx_unmute_delay, "delay to unmute the tx path");
51
52static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0);
53
54static int tx_macro_hw_params(struct snd_pcm_substream *substream,
55 struct snd_pcm_hw_params *params,
56 struct snd_soc_dai *dai);
57static int tx_macro_get_channel_map(struct snd_soc_dai *dai,
58 unsigned int *tx_num, unsigned int *tx_slot,
59 unsigned int *rx_num, unsigned int *rx_slot);
60
61#define TX_MACRO_SWR_STRING_LEN 80
62#define TX_MACRO_CHILD_DEVICES_MAX 3
63
64/* Hold instance to soundwire platform device */
65struct tx_macro_swr_ctrl_data {
66 struct platform_device *tx_swr_pdev;
67};
68
69struct tx_macro_swr_ctrl_platform_data {
70 void *handle; /* holds codec private data */
71 int (*read)(void *handle, int reg);
72 int (*write)(void *handle, int reg, int val);
73 int (*bulk_write)(void *handle, u32 *reg, u32 *val, size_t len);
74 int (*clk)(void *handle, bool enable);
Karthikeyan Mani8d40a062019-09-05 16:44:49 -070075 int (*core_vote)(void *handle, bool enable);
Laxminath Kasam989fccf2018-06-15 16:53:31 +053076 int (*handle_irq)(void *handle,
77 irqreturn_t (*swrm_irq_handler)(int irq,
78 void *data),
79 void *swrm_handle,
80 int action);
81};
82
83enum {
Laxminath Kasam59c7a1d2018-08-09 16:11:17 +053084 TX_MACRO_AIF_INVALID = 0,
85 TX_MACRO_AIF1_CAP,
Laxminath Kasam989fccf2018-06-15 16:53:31 +053086 TX_MACRO_AIF2_CAP,
Karthikeyan Manif3bb8182019-07-11 14:38:54 -070087 TX_MACRO_AIF3_CAP,
Laxminath Kasam989fccf2018-06-15 16:53:31 +053088 TX_MACRO_MAX_DAIS
89};
90
91enum {
92 TX_MACRO_DEC0,
93 TX_MACRO_DEC1,
94 TX_MACRO_DEC2,
95 TX_MACRO_DEC3,
96 TX_MACRO_DEC4,
97 TX_MACRO_DEC5,
98 TX_MACRO_DEC6,
99 TX_MACRO_DEC7,
100 TX_MACRO_DEC_MAX,
101};
102
103enum {
104 TX_MACRO_CLK_DIV_2,
105 TX_MACRO_CLK_DIV_3,
106 TX_MACRO_CLK_DIV_4,
107 TX_MACRO_CLK_DIV_6,
108 TX_MACRO_CLK_DIV_8,
109 TX_MACRO_CLK_DIV_16,
110};
111
Laxminath Kasam497a6512018-09-17 16:11:52 +0530112enum {
113 MSM_DMIC,
114 SWR_MIC,
115 ANC_FB_TUNE1
116};
117
Sudheer Papothia7397942019-03-19 03:14:23 +0530118enum {
119 TX_MCLK,
120 VA_MCLK,
121};
122
Sudheer Papothi72fef482019-08-30 11:00:20 +0530123struct tx_macro_reg_mask_val {
124 u16 reg;
125 u8 mask;
126 u8 val;
127};
128
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530129struct tx_mute_work {
130 struct tx_macro_priv *tx_priv;
131 u32 decimator;
132 struct delayed_work dwork;
133};
134
135struct hpf_work {
136 struct tx_macro_priv *tx_priv;
137 u8 decimator;
138 u8 hpf_cut_off_freq;
139 struct delayed_work dwork;
140};
141
142struct tx_macro_priv {
143 struct device *dev;
144 bool dec_active[NUM_DECIMATORS];
145 int tx_mclk_users;
146 int swr_clk_users;
Ramprasad Katkam452772a2019-01-07 17:30:36 +0530147 bool dapm_mclk_enable;
Ramprasad Katkama4c747b2018-12-11 19:15:53 +0530148 bool reset_swr;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530149 struct mutex mclk_lock;
150 struct mutex swr_clk_lock;
Meng Wang15c825d2018-09-06 10:49:18 +0800151 struct snd_soc_component *component;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530152 struct device_node *tx_swr_gpio_p;
153 struct tx_macro_swr_ctrl_data *swr_ctrl_data;
154 struct tx_macro_swr_ctrl_platform_data swr_plat_data;
155 struct work_struct tx_macro_add_child_devices_work;
156 struct hpf_work tx_hpf_work[NUM_DECIMATORS];
157 struct tx_mute_work tx_mute_dwork[NUM_DECIMATORS];
158 s32 dmic_0_1_clk_cnt;
159 s32 dmic_2_3_clk_cnt;
160 s32 dmic_4_5_clk_cnt;
161 s32 dmic_6_7_clk_cnt;
162 u16 dmic_clk_div;
163 unsigned long active_ch_mask[TX_MACRO_MAX_DAIS];
164 unsigned long active_ch_cnt[TX_MACRO_MAX_DAIS];
165 char __iomem *tx_io_base;
166 struct platform_device *pdev_child_devices
167 [TX_MACRO_CHILD_DEVICES_MAX];
168 int child_count;
Sudheer Papothie456c2c2019-03-05 07:08:45 +0530169 int tx_swr_clk_cnt;
170 int va_swr_clk_cnt;
Sudheer Papothicf3b4062019-05-10 10:48:43 +0530171 int va_clk_status;
172 int tx_clk_status;
Karthikeyan Mani765eaab2019-07-18 16:27:01 -0700173 bool bcs_enable;
Karthikeyan Mani1dcd5a32019-08-22 14:37:13 -0700174 int dec_mode[NUM_DECIMATORS];
Vatsal Buchad06525f2019-10-14 23:14:12 +0530175 bool bcs_clk_en;
176 bool hs_slow_insert_complete;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530177};
178
Meng Wang15c825d2018-09-06 10:49:18 +0800179static bool tx_macro_get_data(struct snd_soc_component *component,
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530180 struct device **tx_dev,
181 struct tx_macro_priv **tx_priv,
182 const char *func_name)
183{
Meng Wang15c825d2018-09-06 10:49:18 +0800184 *tx_dev = bolero_get_device_ptr(component->dev, TX_MACRO);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530185 if (!(*tx_dev)) {
Meng Wang15c825d2018-09-06 10:49:18 +0800186 dev_err(component->dev,
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530187 "%s: null device for macro!\n", func_name);
188 return false;
189 }
190
191 *tx_priv = dev_get_drvdata((*tx_dev));
192 if (!(*tx_priv)) {
Meng Wang15c825d2018-09-06 10:49:18 +0800193 dev_err(component->dev,
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530194 "%s: priv is null for macro!\n", func_name);
195 return false;
196 }
197
Meng Wang15c825d2018-09-06 10:49:18 +0800198 if (!(*tx_priv)->component) {
199 dev_err(component->dev,
200 "%s: tx_priv->component not initialized!\n", func_name);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530201 return false;
202 }
203
204 return true;
205}
206
207static int tx_macro_mclk_enable(struct tx_macro_priv *tx_priv,
208 bool mclk_enable)
209{
210 struct regmap *regmap = dev_get_regmap(tx_priv->dev->parent, NULL);
211 int ret = 0;
212
Tanya Dixit8530fb92018-09-14 16:01:25 +0530213 if (regmap == NULL) {
214 dev_err(tx_priv->dev, "%s: regmap is NULL\n", __func__);
215 return -EINVAL;
216 }
217
Laxminath Kasamb7f823c2018-08-02 13:23:11 +0530218 dev_dbg(tx_priv->dev, "%s: mclk_enable = %u,clk_users= %d\n",
219 __func__, mclk_enable, tx_priv->tx_mclk_users);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530220
221 mutex_lock(&tx_priv->mclk_lock);
222 if (mclk_enable) {
223 if (tx_priv->tx_mclk_users == 0) {
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -0700224 ret = bolero_clk_rsc_request_clock(tx_priv->dev,
225 TX_CORE_CLK,
226 TX_CORE_CLK,
227 true);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530228 if (ret < 0) {
Ramprasad Katkam14efed62019-03-07 13:16:50 +0530229 dev_err_ratelimited(tx_priv->dev,
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530230 "%s: request clock enable failed\n",
231 __func__);
232 goto exit;
233 }
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -0700234 bolero_clk_rsc_fs_gen_request(tx_priv->dev,
235 true);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530236 regcache_mark_dirty(regmap);
237 regcache_sync_region(regmap,
238 TX_START_OFFSET,
239 TX_MAX_OFFSET);
240 /* 9.6MHz MCLK, set value 0x00 if other frequency */
241 regmap_update_bits(regmap,
242 BOLERO_CDC_TX_TOP_CSR_FREQ_MCLK, 0x01, 0x01);
243 regmap_update_bits(regmap,
244 BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL,
245 0x01, 0x01);
246 regmap_update_bits(regmap,
247 BOLERO_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL,
248 0x01, 0x01);
249 }
250 tx_priv->tx_mclk_users++;
251 } else {
252 if (tx_priv->tx_mclk_users <= 0) {
253 dev_err(tx_priv->dev, "%s: clock already disabled\n",
254 __func__);
255 tx_priv->tx_mclk_users = 0;
256 goto exit;
257 }
258 tx_priv->tx_mclk_users--;
259 if (tx_priv->tx_mclk_users == 0) {
260 regmap_update_bits(regmap,
261 BOLERO_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL,
262 0x01, 0x00);
263 regmap_update_bits(regmap,
264 BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL,
265 0x01, 0x00);
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -0700266 bolero_clk_rsc_fs_gen_request(tx_priv->dev,
267 false);
268
269 bolero_clk_rsc_request_clock(tx_priv->dev,
270 TX_CORE_CLK,
271 TX_CORE_CLK,
272 false);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530273 }
274 }
275exit:
276 mutex_unlock(&tx_priv->mclk_lock);
277 return ret;
278}
279
Sudheer Papothie456c2c2019-03-05 07:08:45 +0530280static int tx_macro_va_swr_clk_event(struct snd_soc_dapm_widget *w,
281 struct snd_kcontrol *kcontrol, int event)
282{
283 struct device *tx_dev = NULL;
284 struct tx_macro_priv *tx_priv = NULL;
285 struct snd_soc_component *component =
286 snd_soc_dapm_to_component(w->dapm);
287
288 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
289 return -EINVAL;
290
291 if (SND_SOC_DAPM_EVENT_ON(event))
292 ++tx_priv->va_swr_clk_cnt;
293 if (SND_SOC_DAPM_EVENT_OFF(event))
294 --tx_priv->va_swr_clk_cnt;
295
296 return 0;
297}
298
299static int tx_macro_tx_swr_clk_event(struct snd_soc_dapm_widget *w,
300 struct snd_kcontrol *kcontrol, int event)
301{
302 struct device *tx_dev = NULL;
303 struct tx_macro_priv *tx_priv = NULL;
304 struct snd_soc_component *component =
305 snd_soc_dapm_to_component(w->dapm);
306
307 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
308 return -EINVAL;
309
310 if (SND_SOC_DAPM_EVENT_ON(event))
311 ++tx_priv->tx_swr_clk_cnt;
312 if (SND_SOC_DAPM_EVENT_OFF(event))
313 --tx_priv->tx_swr_clk_cnt;
314
315 return 0;
316}
317
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530318static int tx_macro_mclk_event(struct snd_soc_dapm_widget *w,
319 struct snd_kcontrol *kcontrol, int event)
320{
Meng Wang15c825d2018-09-06 10:49:18 +0800321 struct snd_soc_component *component =
322 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530323 int ret = 0;
324 struct device *tx_dev = NULL;
325 struct tx_macro_priv *tx_priv = NULL;
326
Meng Wang15c825d2018-09-06 10:49:18 +0800327 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530328 return -EINVAL;
329
330 dev_dbg(tx_dev, "%s: event = %d\n", __func__, event);
331 switch (event) {
332 case SND_SOC_DAPM_PRE_PMU:
333 ret = tx_macro_mclk_enable(tx_priv, 1);
Ramprasad Katkam452772a2019-01-07 17:30:36 +0530334 if (ret)
335 tx_priv->dapm_mclk_enable = false;
336 else
337 tx_priv->dapm_mclk_enable = true;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530338 break;
339 case SND_SOC_DAPM_POST_PMD:
Ramprasad Katkam452772a2019-01-07 17:30:36 +0530340 if (tx_priv->dapm_mclk_enable)
341 ret = tx_macro_mclk_enable(tx_priv, 0);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530342 break;
343 default:
344 dev_err(tx_priv->dev,
345 "%s: invalid DAPM event %d\n", __func__, event);
346 ret = -EINVAL;
347 }
348 return ret;
349}
350
Meng Wang15c825d2018-09-06 10:49:18 +0800351static int tx_macro_event_handler(struct snd_soc_component *component,
352 u16 event, u32 data)
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530353{
354 struct device *tx_dev = NULL;
355 struct tx_macro_priv *tx_priv = NULL;
Aditya Bavanari50ef13e2019-08-09 15:14:43 +0530356 int ret = 0;
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530357
Meng Wang15c825d2018-09-06 10:49:18 +0800358 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530359 return -EINVAL;
360
361 switch (event) {
362 case BOLERO_MACRO_EVT_SSR_DOWN:
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -0700363 if (tx_priv->swr_ctrl_data) {
364 swrm_wcd_notify(
365 tx_priv->swr_ctrl_data[0].tx_swr_pdev,
366 SWR_DEVICE_DOWN, NULL);
367 swrm_wcd_notify(
368 tx_priv->swr_ctrl_data[0].tx_swr_pdev,
369 SWR_DEVICE_SSR_DOWN, NULL);
370 }
Aditya Bavanari50ef13e2019-08-09 15:14:43 +0530371 if ((!pm_runtime_enabled(tx_dev) ||
372 !pm_runtime_suspended(tx_dev))) {
373 ret = bolero_runtime_suspend(tx_dev);
374 if (!ret) {
375 pm_runtime_disable(tx_dev);
376 pm_runtime_set_suspended(tx_dev);
377 pm_runtime_enable(tx_dev);
378 }
379 }
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530380 break;
381 case BOLERO_MACRO_EVT_SSR_UP:
Ramprasad Katkama4c747b2018-12-11 19:15:53 +0530382 /* reset swr after ssr/pdr */
383 tx_priv->reset_swr = true;
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -0700384 if (tx_priv->swr_ctrl_data)
385 swrm_wcd_notify(
386 tx_priv->swr_ctrl_data[0].tx_swr_pdev,
387 SWR_DEVICE_SSR_UP, NULL);
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530388 break;
Meng Wang8ef0cc22019-05-08 15:12:56 +0800389 case BOLERO_MACRO_EVT_CLK_RESET:
390 bolero_rsc_clk_reset(tx_dev, TX_CORE_CLK);
391 break;
Vatsal Buchad06525f2019-10-14 23:14:12 +0530392 case BOLERO_MACRO_EVT_BCS_CLK_OFF:
393 if (tx_priv->bcs_clk_en)
394 snd_soc_component_update_bits(component,
395 BOLERO_CDC_TX0_TX_PATH_SEC7, 0x40, data << 6);
396 if (data)
397 tx_priv->hs_slow_insert_complete = true;
398 else
399 tx_priv->hs_slow_insert_complete = false;
400 break;
Laxminath Kasamfb0d6832018-09-22 01:49:52 +0530401 }
402 return 0;
403}
404
Meng Wang15c825d2018-09-06 10:49:18 +0800405static int tx_macro_reg_wake_irq(struct snd_soc_component *component,
Aditya Bavanaric4e96122018-11-14 14:46:38 +0530406 u32 data)
407{
408 struct device *tx_dev = NULL;
409 struct tx_macro_priv *tx_priv = NULL;
410 u32 ipc_wakeup = data;
411 int ret = 0;
412
Meng Wang15c825d2018-09-06 10:49:18 +0800413 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
Aditya Bavanaric4e96122018-11-14 14:46:38 +0530414 return -EINVAL;
415
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -0700416 if (tx_priv->swr_ctrl_data)
417 ret = swrm_wcd_notify(
418 tx_priv->swr_ctrl_data[0].tx_swr_pdev,
419 SWR_REGISTER_WAKE_IRQ, &ipc_wakeup);
Aditya Bavanaric4e96122018-11-14 14:46:38 +0530420
421 return ret;
422}
423
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530424static void tx_macro_tx_hpf_corner_freq_callback(struct work_struct *work)
425{
426 struct delayed_work *hpf_delayed_work = NULL;
427 struct hpf_work *hpf_work = NULL;
428 struct tx_macro_priv *tx_priv = NULL;
Meng Wang15c825d2018-09-06 10:49:18 +0800429 struct snd_soc_component *component = NULL;
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530430 u16 dec_cfg_reg = 0, hpf_gate_reg = 0;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530431 u8 hpf_cut_off_freq = 0;
Laxminath Kasam497a6512018-09-17 16:11:52 +0530432 u16 adc_mux_reg = 0, adc_n = 0, adc_reg = 0;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530433
434 hpf_delayed_work = to_delayed_work(work);
435 hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork);
436 tx_priv = hpf_work->tx_priv;
Meng Wang15c825d2018-09-06 10:49:18 +0800437 component = tx_priv->component;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530438 hpf_cut_off_freq = hpf_work->hpf_cut_off_freq;
439
440 dec_cfg_reg = BOLERO_CDC_TX0_TX_PATH_CFG0 +
441 TX_MACRO_TX_PATH_OFFSET * hpf_work->decimator;
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530442 hpf_gate_reg = BOLERO_CDC_TX0_TX_PATH_SEC2 +
443 TX_MACRO_TX_PATH_OFFSET * hpf_work->decimator;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530444
Meng Wang15c825d2018-09-06 10:49:18 +0800445 dev_dbg(component->dev, "%s: decimator %u hpf_cut_of_freq 0x%x\n",
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530446 __func__, hpf_work->decimator, hpf_cut_off_freq);
447
Laxminath Kasam497a6512018-09-17 16:11:52 +0530448 adc_mux_reg = BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG1 +
449 TX_MACRO_ADC_MUX_CFG_OFFSET * hpf_work->decimator;
Meng Wang15c825d2018-09-06 10:49:18 +0800450 if (snd_soc_component_read32(component, adc_mux_reg) & SWR_MIC) {
Laxminath Kasam497a6512018-09-17 16:11:52 +0530451 adc_reg = BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0 +
452 TX_MACRO_ADC_MUX_CFG_OFFSET * hpf_work->decimator;
Meng Wang15c825d2018-09-06 10:49:18 +0800453 adc_n = snd_soc_component_read32(component, adc_reg) &
Laxminath Kasam497a6512018-09-17 16:11:52 +0530454 TX_MACRO_SWR_MIC_MUX_SEL_MASK;
455 if (adc_n >= BOLERO_ADC_MAX)
456 goto tx_hpf_set;
457 /* analog mic clear TX hold */
Meng Wang15c825d2018-09-06 10:49:18 +0800458 bolero_clear_amic_tx_hold(component->dev, adc_n);
Laxminath Kasam497a6512018-09-17 16:11:52 +0530459 }
460tx_hpf_set:
Meng Wang15c825d2018-09-06 10:49:18 +0800461 snd_soc_component_update_bits(component,
462 dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK,
463 hpf_cut_off_freq << 5);
464 snd_soc_component_update_bits(component, hpf_gate_reg, 0x03, 0x02);
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530465 /* Minimum 1 clk cycle delay is required as per HW spec */
466 usleep_range(1000, 1010);
Meng Wang15c825d2018-09-06 10:49:18 +0800467 snd_soc_component_update_bits(component, hpf_gate_reg, 0x03, 0x01);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530468}
469
470static void tx_macro_mute_update_callback(struct work_struct *work)
471{
472 struct tx_mute_work *tx_mute_dwork = NULL;
Meng Wang15c825d2018-09-06 10:49:18 +0800473 struct snd_soc_component *component = NULL;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530474 struct tx_macro_priv *tx_priv = NULL;
475 struct delayed_work *delayed_work = NULL;
Xiaojun Sangd155fdc2018-10-11 15:11:59 +0800476 u16 tx_vol_ctl_reg = 0;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530477 u8 decimator = 0;
478
479 delayed_work = to_delayed_work(work);
480 tx_mute_dwork = container_of(delayed_work, struct tx_mute_work, dwork);
481 tx_priv = tx_mute_dwork->tx_priv;
Meng Wang15c825d2018-09-06 10:49:18 +0800482 component = tx_priv->component;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530483 decimator = tx_mute_dwork->decimator;
484
485 tx_vol_ctl_reg =
486 BOLERO_CDC_TX0_TX_PATH_CTL +
487 TX_MACRO_TX_PATH_OFFSET * decimator;
Meng Wang15c825d2018-09-06 10:49:18 +0800488 snd_soc_component_update_bits(component, tx_vol_ctl_reg, 0x10, 0x00);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530489 dev_dbg(tx_priv->dev, "%s: decimator %u unmute\n",
490 __func__, decimator);
491}
492
493static int tx_macro_put_dec_enum(struct snd_kcontrol *kcontrol,
494 struct snd_ctl_elem_value *ucontrol)
495{
496 struct snd_soc_dapm_widget *widget =
497 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +0800498 struct snd_soc_component *component =
499 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530500 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
501 unsigned int val = 0;
502 u16 mic_sel_reg = 0;
Laxminath Kasam549d11d2019-07-18 13:44:17 +0530503 u16 dmic_clk_reg = 0;
504 struct device *tx_dev = NULL;
505 struct tx_macro_priv *tx_priv = NULL;
506
507 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
508 return -EINVAL;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530509
510 val = ucontrol->value.enumerated.item[0];
511 if (val > e->items - 1)
512 return -EINVAL;
513
Meng Wang15c825d2018-09-06 10:49:18 +0800514 dev_dbg(component->dev, "%s: wname: %s, val: 0x%x\n", __func__,
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530515 widget->name, val);
516
517 switch (e->reg) {
518 case BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0:
519 mic_sel_reg = BOLERO_CDC_TX0_TX_PATH_CFG0;
520 break;
521 case BOLERO_CDC_TX_INP_MUX_ADC_MUX1_CFG0:
522 mic_sel_reg = BOLERO_CDC_TX1_TX_PATH_CFG0;
523 break;
524 case BOLERO_CDC_TX_INP_MUX_ADC_MUX2_CFG0:
525 mic_sel_reg = BOLERO_CDC_TX2_TX_PATH_CFG0;
526 break;
527 case BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG0:
528 mic_sel_reg = BOLERO_CDC_TX3_TX_PATH_CFG0;
529 break;
530 case BOLERO_CDC_TX_INP_MUX_ADC_MUX4_CFG0:
531 mic_sel_reg = BOLERO_CDC_TX4_TX_PATH_CFG0;
532 break;
533 case BOLERO_CDC_TX_INP_MUX_ADC_MUX5_CFG0:
534 mic_sel_reg = BOLERO_CDC_TX5_TX_PATH_CFG0;
535 break;
536 case BOLERO_CDC_TX_INP_MUX_ADC_MUX6_CFG0:
537 mic_sel_reg = BOLERO_CDC_TX6_TX_PATH_CFG0;
538 break;
539 case BOLERO_CDC_TX_INP_MUX_ADC_MUX7_CFG0:
540 mic_sel_reg = BOLERO_CDC_TX7_TX_PATH_CFG0;
541 break;
542 default:
Meng Wang15c825d2018-09-06 10:49:18 +0800543 dev_err(component->dev, "%s: e->reg: 0x%x not expected\n",
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530544 __func__, e->reg);
545 return -EINVAL;
546 }
Laxminath Kasam497a6512018-09-17 16:11:52 +0530547 if (strnstr(widget->name, "SMIC", strlen(widget->name))) {
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530548 if (val != 0) {
Laxminath Kasam549d11d2019-07-18 13:44:17 +0530549 if (val < 5) {
Meng Wang15c825d2018-09-06 10:49:18 +0800550 snd_soc_component_update_bits(component,
551 mic_sel_reg,
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530552 1 << 7, 0x0 << 7);
Laxminath Kasam549d11d2019-07-18 13:44:17 +0530553 } else {
Meng Wang15c825d2018-09-06 10:49:18 +0800554 snd_soc_component_update_bits(component,
555 mic_sel_reg,
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530556 1 << 7, 0x1 << 7);
Laxminath Kasam549d11d2019-07-18 13:44:17 +0530557 snd_soc_component_update_bits(component,
558 BOLERO_CDC_VA_TOP_CSR_DMIC_CFG,
559 0x80, 0x00);
560 dmic_clk_reg =
561 BOLERO_CDC_TX_TOP_CSR_SWR_DMIC0_CTL +
562 ((val - 5)/2) * 4;
563 snd_soc_component_update_bits(component,
564 dmic_clk_reg,
565 0x0E, tx_priv->dmic_clk_div << 0x1);
566 }
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530567 }
568 } else {
569 /* DMIC selected */
570 if (val != 0)
Meng Wang15c825d2018-09-06 10:49:18 +0800571 snd_soc_component_update_bits(component, mic_sel_reg,
572 1 << 7, 1 << 7);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530573 }
574
575 return snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
576}
577
578static int tx_macro_tx_mixer_get(struct snd_kcontrol *kcontrol,
579 struct snd_ctl_elem_value *ucontrol)
580{
581 struct snd_soc_dapm_widget *widget =
582 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +0800583 struct snd_soc_component *component =
584 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530585 struct soc_multi_mixer_control *mixer =
586 ((struct soc_multi_mixer_control *)kcontrol->private_value);
587 u32 dai_id = widget->shift;
588 u32 dec_id = mixer->shift;
589 struct device *tx_dev = NULL;
590 struct tx_macro_priv *tx_priv = NULL;
591
Meng Wang15c825d2018-09-06 10:49:18 +0800592 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530593 return -EINVAL;
594
595 if (test_bit(dec_id, &tx_priv->active_ch_mask[dai_id]))
596 ucontrol->value.integer.value[0] = 1;
597 else
598 ucontrol->value.integer.value[0] = 0;
599 return 0;
600}
601
602static int tx_macro_tx_mixer_put(struct snd_kcontrol *kcontrol,
603 struct snd_ctl_elem_value *ucontrol)
604{
605 struct snd_soc_dapm_widget *widget =
606 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +0800607 struct snd_soc_component *component =
608 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530609 struct snd_soc_dapm_update *update = NULL;
610 struct soc_multi_mixer_control *mixer =
611 ((struct soc_multi_mixer_control *)kcontrol->private_value);
612 u32 dai_id = widget->shift;
613 u32 dec_id = mixer->shift;
614 u32 enable = ucontrol->value.integer.value[0];
615 struct device *tx_dev = NULL;
616 struct tx_macro_priv *tx_priv = NULL;
617
Meng Wang15c825d2018-09-06 10:49:18 +0800618 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530619 return -EINVAL;
620
621 if (enable) {
622 set_bit(dec_id, &tx_priv->active_ch_mask[dai_id]);
623 tx_priv->active_ch_cnt[dai_id]++;
624 } else {
625 tx_priv->active_ch_cnt[dai_id]--;
626 clear_bit(dec_id, &tx_priv->active_ch_mask[dai_id]);
627 }
628 snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, update);
629
630 return 0;
631}
Karthikeyan Mani1dcd5a32019-08-22 14:37:13 -0700632
633static inline int tx_macro_path_get(const char *wname,
634 unsigned int *path_num)
635{
636 int ret = 0;
637 char *widget_name = NULL;
638 char *w_name = NULL;
639 char *path_num_char = NULL;
640 char *path_name = NULL;
641
642 widget_name = kstrndup(wname, 10, GFP_KERNEL);
643 if (!widget_name)
644 return -EINVAL;
645
646 w_name = widget_name;
647
648 path_name = strsep(&widget_name, " ");
649 if (!path_name) {
650 pr_err("%s: Invalid widget name = %s\n",
651 __func__, widget_name);
652 ret = -EINVAL;
653 goto err;
654 }
655 path_num_char = strpbrk(path_name, "01234567");
656 if (!path_num_char) {
657 pr_err("%s: tx path index not found\n",
658 __func__);
659 ret = -EINVAL;
660 goto err;
661 }
662 ret = kstrtouint(path_num_char, 10, path_num);
663 if (ret < 0)
664 pr_err("%s: Invalid tx path = %s\n",
665 __func__, w_name);
666
667err:
668 kfree(w_name);
669 return ret;
670}
671
672static int tx_macro_dec_mode_get(struct snd_kcontrol *kcontrol,
673 struct snd_ctl_elem_value *ucontrol)
674{
675 struct snd_soc_component *component =
676 snd_soc_kcontrol_component(kcontrol);
677 struct tx_macro_priv *tx_priv = NULL;
678 struct device *tx_dev = NULL;
679 int ret = 0;
680 int path = 0;
681
682 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
683 return -EINVAL;
684
685 ret = tx_macro_path_get(kcontrol->id.name, &path);
686 if (ret)
687 return ret;
688
689 ucontrol->value.integer.value[0] = tx_priv->dec_mode[path];
690
691 return 0;
692}
693
694static int tx_macro_dec_mode_put(struct snd_kcontrol *kcontrol,
695 struct snd_ctl_elem_value *ucontrol)
696{
697 struct snd_soc_component *component =
698 snd_soc_kcontrol_component(kcontrol);
699 struct tx_macro_priv *tx_priv = NULL;
700 struct device *tx_dev = NULL;
701 int value = ucontrol->value.integer.value[0];
702 int ret = 0;
703 int path = 0;
704
705 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
706 return -EINVAL;
707
708 ret = tx_macro_path_get(kcontrol->id.name, &path);
709 if (ret)
710 return ret;
711
712 tx_priv->dec_mode[path] = value;
713
714 return 0;
715}
716
Karthikeyan Mani765eaab2019-07-18 16:27:01 -0700717static int tx_macro_get_bcs(struct snd_kcontrol *kcontrol,
718 struct snd_ctl_elem_value *ucontrol)
719{
720 struct snd_soc_component *component =
721 snd_soc_kcontrol_component(kcontrol);
722 struct tx_macro_priv *tx_priv = NULL;
723 struct device *tx_dev = NULL;
724
725 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
726 return -EINVAL;
727
728 ucontrol->value.integer.value[0] = tx_priv->bcs_enable;
729
730 return 0;
731}
732
733static int tx_macro_set_bcs(struct snd_kcontrol *kcontrol,
734 struct snd_ctl_elem_value *ucontrol)
735{
736 struct snd_soc_component *component =
737 snd_soc_kcontrol_component(kcontrol);
738 struct tx_macro_priv *tx_priv = NULL;
739 struct device *tx_dev = NULL;
740 int value = ucontrol->value.integer.value[0];
741
742 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
743 return -EINVAL;
744
745 tx_priv->bcs_enable = value;
746
747 return 0;
748}
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530749
750static int tx_macro_enable_dmic(struct snd_soc_dapm_widget *w,
751 struct snd_kcontrol *kcontrol, int event)
752{
Meng Wang15c825d2018-09-06 10:49:18 +0800753 struct snd_soc_component *component =
754 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530755 u8 dmic_clk_en = 0x01;
756 u16 dmic_clk_reg = 0;
757 s32 *dmic_clk_cnt = NULL;
758 unsigned int dmic = 0;
759 int ret = 0;
760 char *wname = NULL;
761 struct device *tx_dev = NULL;
762 struct tx_macro_priv *tx_priv = NULL;
763
Meng Wang15c825d2018-09-06 10:49:18 +0800764 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530765 return -EINVAL;
766
767 wname = strpbrk(w->name, "01234567");
768 if (!wname) {
Meng Wang15c825d2018-09-06 10:49:18 +0800769 dev_err(component->dev, "%s: widget not found\n", __func__);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530770 return -EINVAL;
771 }
772
773 ret = kstrtouint(wname, 10, &dmic);
774 if (ret < 0) {
Meng Wang15c825d2018-09-06 10:49:18 +0800775 dev_err(component->dev, "%s: Invalid DMIC line on the codec\n",
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530776 __func__);
777 return -EINVAL;
778 }
779
780 switch (dmic) {
781 case 0:
782 case 1:
783 dmic_clk_cnt = &(tx_priv->dmic_0_1_clk_cnt);
784 dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC0_CTL;
785 break;
786 case 2:
787 case 3:
788 dmic_clk_cnt = &(tx_priv->dmic_2_3_clk_cnt);
789 dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC1_CTL;
790 break;
791 case 4:
792 case 5:
793 dmic_clk_cnt = &(tx_priv->dmic_4_5_clk_cnt);
794 dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC2_CTL;
795 break;
796 case 6:
797 case 7:
798 dmic_clk_cnt = &(tx_priv->dmic_6_7_clk_cnt);
799 dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC3_CTL;
800 break;
801 default:
Meng Wang15c825d2018-09-06 10:49:18 +0800802 dev_err(component->dev, "%s: Invalid DMIC Selection\n",
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530803 __func__);
804 return -EINVAL;
805 }
Meng Wang15c825d2018-09-06 10:49:18 +0800806 dev_dbg(component->dev, "%s: event %d DMIC%d dmic_clk_cnt %d\n",
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530807 __func__, event, dmic, *dmic_clk_cnt);
808
809 switch (event) {
810 case SND_SOC_DAPM_PRE_PMU:
811 (*dmic_clk_cnt)++;
812 if (*dmic_clk_cnt == 1) {
Meng Wang15c825d2018-09-06 10:49:18 +0800813 snd_soc_component_update_bits(component,
814 BOLERO_CDC_VA_TOP_CSR_DMIC_CFG,
Ramprasad Katkam9c2394a2018-08-23 13:13:48 +0530815 0x80, 0x00);
816
Meng Wang15c825d2018-09-06 10:49:18 +0800817 snd_soc_component_update_bits(component, dmic_clk_reg,
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530818 0x0E, tx_priv->dmic_clk_div << 0x1);
Meng Wang15c825d2018-09-06 10:49:18 +0800819 snd_soc_component_update_bits(component, dmic_clk_reg,
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530820 dmic_clk_en, dmic_clk_en);
821 }
822 break;
823 case SND_SOC_DAPM_POST_PMD:
824 (*dmic_clk_cnt)--;
825 if (*dmic_clk_cnt == 0)
Meng Wang15c825d2018-09-06 10:49:18 +0800826 snd_soc_component_update_bits(component, dmic_clk_reg,
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530827 dmic_clk_en, 0);
828 break;
829 }
830
831 return 0;
832}
833
834static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w,
835 struct snd_kcontrol *kcontrol, int event)
836{
Meng Wang15c825d2018-09-06 10:49:18 +0800837 struct snd_soc_component *component =
838 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530839 unsigned int decimator = 0;
840 u16 tx_vol_ctl_reg = 0;
841 u16 dec_cfg_reg = 0;
842 u16 hpf_gate_reg = 0;
843 u16 tx_gain_ctl_reg = 0;
844 u8 hpf_cut_off_freq = 0;
845 struct device *tx_dev = NULL;
846 struct tx_macro_priv *tx_priv = NULL;
847
Meng Wang15c825d2018-09-06 10:49:18 +0800848 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530849 return -EINVAL;
850
851 decimator = w->shift;
852
Meng Wang15c825d2018-09-06 10:49:18 +0800853 dev_dbg(component->dev, "%s(): widget = %s decimator = %u\n", __func__,
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530854 w->name, decimator);
855
856 tx_vol_ctl_reg = BOLERO_CDC_TX0_TX_PATH_CTL +
857 TX_MACRO_TX_PATH_OFFSET * decimator;
858 hpf_gate_reg = BOLERO_CDC_TX0_TX_PATH_SEC2 +
859 TX_MACRO_TX_PATH_OFFSET * decimator;
860 dec_cfg_reg = BOLERO_CDC_TX0_TX_PATH_CFG0 +
861 TX_MACRO_TX_PATH_OFFSET * decimator;
862 tx_gain_ctl_reg = BOLERO_CDC_TX0_TX_VOL_CTL +
863 TX_MACRO_TX_PATH_OFFSET * decimator;
864
865 switch (event) {
866 case SND_SOC_DAPM_PRE_PMU:
Karthikeyan Mani1dcd5a32019-08-22 14:37:13 -0700867 snd_soc_component_update_bits(component,
868 dec_cfg_reg, 0x06, tx_priv->dec_mode[decimator] <<
869 TX_MACRO_ADC_MODE_CFG0_SHIFT);
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530870 /* Enable TX PGA Mute */
Meng Wang15c825d2018-09-06 10:49:18 +0800871 snd_soc_component_update_bits(component,
872 tx_vol_ctl_reg, 0x10, 0x10);
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530873 break;
874 case SND_SOC_DAPM_POST_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +0800875 snd_soc_component_update_bits(component,
876 tx_vol_ctl_reg, 0x20, 0x20);
877 snd_soc_component_update_bits(component,
878 hpf_gate_reg, 0x01, 0x00);
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530879
Meng Wang15c825d2018-09-06 10:49:18 +0800880 hpf_cut_off_freq = (
881 snd_soc_component_read32(component, dec_cfg_reg) &
882 TX_HPF_CUT_OFF_FREQ_MASK) >> 5;
883
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530884 tx_priv->tx_hpf_work[decimator].hpf_cut_off_freq =
Meng Wang15c825d2018-09-06 10:49:18 +0800885 hpf_cut_off_freq;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530886
887 if (hpf_cut_off_freq != CF_MIN_3DB_150HZ)
Meng Wang15c825d2018-09-06 10:49:18 +0800888 snd_soc_component_update_bits(component, dec_cfg_reg,
889 TX_HPF_CUT_OFF_FREQ_MASK,
890 CF_MIN_3DB_150HZ << 5);
891
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530892 /* schedule work queue to Remove Mute */
893 schedule_delayed_work(&tx_priv->tx_mute_dwork[decimator].dwork,
894 msecs_to_jiffies(tx_unmute_delay));
895 if (tx_priv->tx_hpf_work[decimator].hpf_cut_off_freq !=
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530896 CF_MIN_3DB_150HZ) {
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530897 schedule_delayed_work(
898 &tx_priv->tx_hpf_work[decimator].dwork,
Karthikeyan Mani6bd895e2019-07-26 15:34:50 -0700899 msecs_to_jiffies(300));
Meng Wang15c825d2018-09-06 10:49:18 +0800900 snd_soc_component_update_bits(component,
901 hpf_gate_reg, 0x02, 0x02);
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530902 /*
903 * Minimum 1 clk cycle delay is required as per HW spec
904 */
905 usleep_range(1000, 1010);
Meng Wang15c825d2018-09-06 10:49:18 +0800906 snd_soc_component_update_bits(component,
907 hpf_gate_reg, 0x02, 0x00);
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530908 }
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530909 /* apply gain after decimator is enabled */
Meng Wang15c825d2018-09-06 10:49:18 +0800910 snd_soc_component_write(component, tx_gain_ctl_reg,
911 snd_soc_component_read32(component,
912 tx_gain_ctl_reg));
Karthikeyan Mani765eaab2019-07-18 16:27:01 -0700913 if (tx_priv->bcs_enable) {
914 snd_soc_component_update_bits(component, dec_cfg_reg,
915 0x01, 0x01);
Vatsal Buchad06525f2019-10-14 23:14:12 +0530916 tx_priv->bcs_clk_en = true;
917 if (tx_priv->hs_slow_insert_complete)
918 snd_soc_component_update_bits(component,
919 BOLERO_CDC_TX0_TX_PATH_SEC7, 0x40,
920 0x40);
Karthikeyan Mani765eaab2019-07-18 16:27:01 -0700921 }
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530922 break;
923 case SND_SOC_DAPM_PRE_PMD:
924 hpf_cut_off_freq =
925 tx_priv->tx_hpf_work[decimator].hpf_cut_off_freq;
Meng Wang15c825d2018-09-06 10:49:18 +0800926 snd_soc_component_update_bits(component,
927 tx_vol_ctl_reg, 0x10, 0x10);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530928 if (cancel_delayed_work_sync(
929 &tx_priv->tx_hpf_work[decimator].dwork)) {
930 if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) {
Meng Wang15c825d2018-09-06 10:49:18 +0800931 snd_soc_component_update_bits(
932 component, dec_cfg_reg,
933 TX_HPF_CUT_OFF_FREQ_MASK,
934 hpf_cut_off_freq << 5);
935 snd_soc_component_update_bits(component,
936 hpf_gate_reg,
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530937 0x02, 0x02);
938 /*
939 * Minimum 1 clk cycle delay is required
940 * as per HW spec
941 */
942 usleep_range(1000, 1010);
Meng Wang15c825d2018-09-06 10:49:18 +0800943 snd_soc_component_update_bits(component,
944 hpf_gate_reg,
Laxminath Kasam9eb80222018-08-29 21:53:14 +0530945 0x02, 0x00);
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530946 }
947 }
948 cancel_delayed_work_sync(
949 &tx_priv->tx_mute_dwork[decimator].dwork);
950 break;
951 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +0800952 snd_soc_component_update_bits(component, tx_vol_ctl_reg,
953 0x20, 0x00);
Karthikeyan Mani1dcd5a32019-08-22 14:37:13 -0700954 snd_soc_component_update_bits(component,
955 dec_cfg_reg, 0x06, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +0800956 snd_soc_component_update_bits(component, tx_vol_ctl_reg,
957 0x10, 0x00);
Karthikeyan Mani765eaab2019-07-18 16:27:01 -0700958 if (tx_priv->bcs_enable) {
959 snd_soc_component_update_bits(component, dec_cfg_reg,
960 0x01, 0x00);
961 snd_soc_component_update_bits(component,
962 BOLERO_CDC_TX0_TX_PATH_SEC7, 0x40, 0x00);
Vatsal Buchad06525f2019-10-14 23:14:12 +0530963 tx_priv->bcs_clk_en = false;
Karthikeyan Mani765eaab2019-07-18 16:27:01 -0700964 }
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530965 break;
966 }
967 return 0;
968}
969
970static int tx_macro_enable_micbias(struct snd_soc_dapm_widget *w,
971 struct snd_kcontrol *kcontrol, int event)
972{
973 return 0;
974}
975
976static int tx_macro_hw_params(struct snd_pcm_substream *substream,
977 struct snd_pcm_hw_params *params,
978 struct snd_soc_dai *dai)
979{
980 int tx_fs_rate = -EINVAL;
Meng Wang15c825d2018-09-06 10:49:18 +0800981 struct snd_soc_component *component = dai->component;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530982 u32 decimator = 0;
Laxminath Kasamb7f823c2018-08-02 13:23:11 +0530983 u32 sample_rate = 0;
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530984 u16 tx_fs_reg = 0;
985 struct device *tx_dev = NULL;
986 struct tx_macro_priv *tx_priv = NULL;
987
Meng Wang15c825d2018-09-06 10:49:18 +0800988 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
Laxminath Kasam989fccf2018-06-15 16:53:31 +0530989 return -EINVAL;
990
991 pr_debug("%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__,
992 dai->name, dai->id, params_rate(params),
993 params_channels(params));
994
995 sample_rate = params_rate(params);
996 switch (sample_rate) {
997 case 8000:
998 tx_fs_rate = 0;
999 break;
1000 case 16000:
1001 tx_fs_rate = 1;
1002 break;
1003 case 32000:
1004 tx_fs_rate = 3;
1005 break;
1006 case 48000:
1007 tx_fs_rate = 4;
1008 break;
1009 case 96000:
1010 tx_fs_rate = 5;
1011 break;
1012 case 192000:
1013 tx_fs_rate = 6;
1014 break;
1015 case 384000:
1016 tx_fs_rate = 7;
1017 break;
1018 default:
Meng Wang15c825d2018-09-06 10:49:18 +08001019 dev_err(component->dev, "%s: Invalid TX sample rate: %d\n",
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301020 __func__, params_rate(params));
1021 return -EINVAL;
1022 }
1023 for_each_set_bit(decimator, &tx_priv->active_ch_mask[dai->id],
1024 TX_MACRO_DEC_MAX) {
1025 if (decimator >= 0) {
1026 tx_fs_reg = BOLERO_CDC_TX0_TX_PATH_CTL +
1027 TX_MACRO_TX_PATH_OFFSET * decimator;
Meng Wang15c825d2018-09-06 10:49:18 +08001028 dev_dbg(component->dev, "%s: set DEC%u rate to %u\n",
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301029 __func__, decimator, sample_rate);
Meng Wang15c825d2018-09-06 10:49:18 +08001030 snd_soc_component_update_bits(component, tx_fs_reg,
1031 0x0F, tx_fs_rate);
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301032 } else {
Meng Wang15c825d2018-09-06 10:49:18 +08001033 dev_err(component->dev,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301034 "%s: ERROR: Invalid decimator: %d\n",
1035 __func__, decimator);
1036 return -EINVAL;
1037 }
1038 }
1039 return 0;
1040}
1041
1042static int tx_macro_get_channel_map(struct snd_soc_dai *dai,
1043 unsigned int *tx_num, unsigned int *tx_slot,
1044 unsigned int *rx_num, unsigned int *rx_slot)
1045{
Meng Wang15c825d2018-09-06 10:49:18 +08001046 struct snd_soc_component *component = dai->component;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301047 struct device *tx_dev = NULL;
1048 struct tx_macro_priv *tx_priv = NULL;
1049
Meng Wang15c825d2018-09-06 10:49:18 +08001050 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301051 return -EINVAL;
1052
1053 switch (dai->id) {
1054 case TX_MACRO_AIF1_CAP:
1055 case TX_MACRO_AIF2_CAP:
Karthikeyan Manif3bb8182019-07-11 14:38:54 -07001056 case TX_MACRO_AIF3_CAP:
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301057 *tx_slot = tx_priv->active_ch_mask[dai->id];
1058 *tx_num = tx_priv->active_ch_cnt[dai->id];
1059 break;
1060 default:
1061 dev_err(tx_dev, "%s: Invalid AIF\n", __func__);
1062 break;
1063 }
1064 return 0;
1065}
1066
1067static struct snd_soc_dai_ops tx_macro_dai_ops = {
1068 .hw_params = tx_macro_hw_params,
1069 .get_channel_map = tx_macro_get_channel_map,
1070};
1071
1072static struct snd_soc_dai_driver tx_macro_dai[] = {
1073 {
1074 .name = "tx_macro_tx1",
1075 .id = TX_MACRO_AIF1_CAP,
1076 .capture = {
1077 .stream_name = "TX_AIF1 Capture",
1078 .rates = TX_MACRO_RATES,
1079 .formats = TX_MACRO_FORMATS,
1080 .rate_max = 192000,
1081 .rate_min = 8000,
1082 .channels_min = 1,
1083 .channels_max = 8,
1084 },
1085 .ops = &tx_macro_dai_ops,
1086 },
1087 {
1088 .name = "tx_macro_tx2",
1089 .id = TX_MACRO_AIF2_CAP,
1090 .capture = {
1091 .stream_name = "TX_AIF2 Capture",
1092 .rates = TX_MACRO_RATES,
1093 .formats = TX_MACRO_FORMATS,
1094 .rate_max = 192000,
1095 .rate_min = 8000,
1096 .channels_min = 1,
1097 .channels_max = 8,
1098 },
1099 .ops = &tx_macro_dai_ops,
1100 },
Karthikeyan Manif3bb8182019-07-11 14:38:54 -07001101 {
1102 .name = "tx_macro_tx3",
1103 .id = TX_MACRO_AIF3_CAP,
1104 .capture = {
1105 .stream_name = "TX_AIF3 Capture",
1106 .rates = TX_MACRO_RATES,
1107 .formats = TX_MACRO_FORMATS,
1108 .rate_max = 192000,
1109 .rate_min = 8000,
1110 .channels_min = 1,
1111 .channels_max = 8,
1112 },
1113 .ops = &tx_macro_dai_ops,
1114 },
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301115};
1116
1117#define STRING(name) #name
1118#define TX_MACRO_DAPM_ENUM(name, reg, offset, text) \
1119static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \
1120static const struct snd_kcontrol_new name##_mux = \
1121 SOC_DAPM_ENUM(STRING(name), name##_enum)
1122
1123#define TX_MACRO_DAPM_ENUM_EXT(name, reg, offset, text, getname, putname) \
1124static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \
1125static const struct snd_kcontrol_new name##_mux = \
1126 SOC_DAPM_ENUM_EXT(STRING(name), name##_enum, getname, putname)
1127
1128#define TX_MACRO_DAPM_MUX(name, shift, kctl) \
1129 SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, shift, 0, &kctl##_mux)
1130
1131static const char * const adc_mux_text[] = {
1132 "MSM_DMIC", "SWR_MIC", "ANC_FB_TUNE1"
1133};
1134
1135TX_MACRO_DAPM_ENUM(tx_dec0, BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG1,
1136 0, adc_mux_text);
1137TX_MACRO_DAPM_ENUM(tx_dec1, BOLERO_CDC_TX_INP_MUX_ADC_MUX1_CFG1,
1138 0, adc_mux_text);
1139TX_MACRO_DAPM_ENUM(tx_dec2, BOLERO_CDC_TX_INP_MUX_ADC_MUX2_CFG1,
1140 0, adc_mux_text);
1141TX_MACRO_DAPM_ENUM(tx_dec3, BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG1,
1142 0, adc_mux_text);
1143TX_MACRO_DAPM_ENUM(tx_dec4, BOLERO_CDC_TX_INP_MUX_ADC_MUX4_CFG1,
1144 0, adc_mux_text);
1145TX_MACRO_DAPM_ENUM(tx_dec5, BOLERO_CDC_TX_INP_MUX_ADC_MUX5_CFG1,
1146 0, adc_mux_text);
1147TX_MACRO_DAPM_ENUM(tx_dec6, BOLERO_CDC_TX_INP_MUX_ADC_MUX6_CFG1,
1148 0, adc_mux_text);
1149TX_MACRO_DAPM_ENUM(tx_dec7, BOLERO_CDC_TX_INP_MUX_ADC_MUX7_CFG1,
1150 0, adc_mux_text);
1151
1152
1153static const char * const dmic_mux_text[] = {
1154 "ZERO", "DMIC0", "DMIC1", "DMIC2", "DMIC3",
1155 "DMIC4", "DMIC5", "DMIC6", "DMIC7"
1156};
1157
1158TX_MACRO_DAPM_ENUM_EXT(tx_dmic0, BOLERO_CDC_TX_INP_MUX_ADC_MUX0_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_dmic1, BOLERO_CDC_TX_INP_MUX_ADC_MUX1_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_dmic2, BOLERO_CDC_TX_INP_MUX_ADC_MUX2_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_dmic3, BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG0,
1171 4, dmic_mux_text, snd_soc_dapm_get_enum_double,
1172 tx_macro_put_dec_enum);
1173
1174TX_MACRO_DAPM_ENUM_EXT(tx_dmic4, BOLERO_CDC_TX_INP_MUX_ADC_MUX4_CFG0,
1175 4, dmic_mux_text, snd_soc_dapm_get_enum_double,
1176 tx_macro_put_dec_enum);
1177
1178TX_MACRO_DAPM_ENUM_EXT(tx_dmic5, BOLERO_CDC_TX_INP_MUX_ADC_MUX5_CFG0,
1179 4, dmic_mux_text, snd_soc_dapm_get_enum_double,
1180 tx_macro_put_dec_enum);
1181
1182TX_MACRO_DAPM_ENUM_EXT(tx_dmic6, BOLERO_CDC_TX_INP_MUX_ADC_MUX6_CFG0,
1183 4, dmic_mux_text, snd_soc_dapm_get_enum_double,
1184 tx_macro_put_dec_enum);
1185
1186TX_MACRO_DAPM_ENUM_EXT(tx_dmic7, BOLERO_CDC_TX_INP_MUX_ADC_MUX7_CFG0,
1187 4, dmic_mux_text, snd_soc_dapm_get_enum_double,
1188 tx_macro_put_dec_enum);
1189
1190static const char * const smic_mux_text[] = {
Sudheer Papothi324b4952019-06-11 04:14:51 +05301191 "ZERO", "ADC0", "ADC1", "ADC2", "ADC3", "SWR_DMIC0",
1192 "SWR_DMIC1", "SWR_DMIC2", "SWR_DMIC3", "SWR_DMIC4",
1193 "SWR_DMIC5", "SWR_DMIC6", "SWR_DMIC7"
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301194};
1195
1196TX_MACRO_DAPM_ENUM_EXT(tx_smic0, BOLERO_CDC_TX_INP_MUX_ADC_MUX0_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_smic1, BOLERO_CDC_TX_INP_MUX_ADC_MUX1_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_smic2, BOLERO_CDC_TX_INP_MUX_ADC_MUX2_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_smic3, BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG0,
1209 0, smic_mux_text, snd_soc_dapm_get_enum_double,
1210 tx_macro_put_dec_enum);
1211
1212TX_MACRO_DAPM_ENUM_EXT(tx_smic4, BOLERO_CDC_TX_INP_MUX_ADC_MUX4_CFG0,
1213 0, smic_mux_text, snd_soc_dapm_get_enum_double,
1214 tx_macro_put_dec_enum);
1215
1216TX_MACRO_DAPM_ENUM_EXT(tx_smic5, BOLERO_CDC_TX_INP_MUX_ADC_MUX5_CFG0,
1217 0, smic_mux_text, snd_soc_dapm_get_enum_double,
1218 tx_macro_put_dec_enum);
1219
1220TX_MACRO_DAPM_ENUM_EXT(tx_smic6, BOLERO_CDC_TX_INP_MUX_ADC_MUX6_CFG0,
1221 0, smic_mux_text, snd_soc_dapm_get_enum_double,
1222 tx_macro_put_dec_enum);
1223
1224TX_MACRO_DAPM_ENUM_EXT(tx_smic7, BOLERO_CDC_TX_INP_MUX_ADC_MUX7_CFG0,
1225 0, smic_mux_text, snd_soc_dapm_get_enum_double,
1226 tx_macro_put_dec_enum);
1227
Karthikeyan Mani1dcd5a32019-08-22 14:37:13 -07001228static const char * const dec_mode_mux_text[] = {
1229 "ADC_DEFAULT", "ADC_LOW_PWR", "ADC_HIGH_PERF",
1230};
1231
1232static const struct soc_enum dec_mode_mux_enum =
1233 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(dec_mode_mux_text),
1234 dec_mode_mux_text);
1235
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301236static const struct snd_kcontrol_new tx_aif1_cap_mixer[] = {
1237 SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, TX_MACRO_DEC0, 1, 0,
1238 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1239 SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, TX_MACRO_DEC1, 1, 0,
1240 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1241 SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, TX_MACRO_DEC2, 1, 0,
1242 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1243 SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, TX_MACRO_DEC3, 1, 0,
1244 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1245 SOC_SINGLE_EXT("DEC4", SND_SOC_NOPM, TX_MACRO_DEC4, 1, 0,
1246 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1247 SOC_SINGLE_EXT("DEC5", SND_SOC_NOPM, TX_MACRO_DEC5, 1, 0,
1248 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1249 SOC_SINGLE_EXT("DEC6", SND_SOC_NOPM, TX_MACRO_DEC6, 1, 0,
1250 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1251 SOC_SINGLE_EXT("DEC7", SND_SOC_NOPM, TX_MACRO_DEC7, 1, 0,
1252 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1253};
1254
1255static const struct snd_kcontrol_new tx_aif2_cap_mixer[] = {
1256 SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, TX_MACRO_DEC0, 1, 0,
1257 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1258 SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, TX_MACRO_DEC1, 1, 0,
1259 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1260 SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, TX_MACRO_DEC2, 1, 0,
1261 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1262 SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, TX_MACRO_DEC3, 1, 0,
1263 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1264 SOC_SINGLE_EXT("DEC4", SND_SOC_NOPM, TX_MACRO_DEC4, 1, 0,
1265 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1266 SOC_SINGLE_EXT("DEC5", SND_SOC_NOPM, TX_MACRO_DEC5, 1, 0,
1267 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1268 SOC_SINGLE_EXT("DEC6", SND_SOC_NOPM, TX_MACRO_DEC6, 1, 0,
1269 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1270 SOC_SINGLE_EXT("DEC7", SND_SOC_NOPM, TX_MACRO_DEC7, 1, 0,
1271 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1272};
1273
Karthikeyan Manif3bb8182019-07-11 14:38:54 -07001274static const struct snd_kcontrol_new tx_aif3_cap_mixer[] = {
1275 SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, TX_MACRO_DEC0, 1, 0,
1276 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1277 SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, TX_MACRO_DEC1, 1, 0,
1278 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1279 SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, TX_MACRO_DEC2, 1, 0,
1280 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1281 SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, TX_MACRO_DEC3, 1, 0,
1282 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1283 SOC_SINGLE_EXT("DEC4", SND_SOC_NOPM, TX_MACRO_DEC4, 1, 0,
1284 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1285 SOC_SINGLE_EXT("DEC5", SND_SOC_NOPM, TX_MACRO_DEC5, 1, 0,
1286 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1287 SOC_SINGLE_EXT("DEC6", SND_SOC_NOPM, TX_MACRO_DEC6, 1, 0,
1288 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1289 SOC_SINGLE_EXT("DEC7", SND_SOC_NOPM, TX_MACRO_DEC7, 1, 0,
1290 tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
1291};
1292
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301293static const struct snd_soc_dapm_widget tx_macro_dapm_widgets[] = {
1294 SND_SOC_DAPM_AIF_OUT("TX_AIF1 CAP", "TX_AIF1 Capture", 0,
1295 SND_SOC_NOPM, TX_MACRO_AIF1_CAP, 0),
1296
1297 SND_SOC_DAPM_AIF_OUT("TX_AIF2 CAP", "TX_AIF2 Capture", 0,
1298 SND_SOC_NOPM, TX_MACRO_AIF2_CAP, 0),
1299
Karthikeyan Manif3bb8182019-07-11 14:38:54 -07001300 SND_SOC_DAPM_AIF_OUT("TX_AIF3 CAP", "TX_AIF3 Capture", 0,
1301 SND_SOC_NOPM, TX_MACRO_AIF3_CAP, 0),
1302
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301303 SND_SOC_DAPM_MIXER("TX_AIF1_CAP Mixer", SND_SOC_NOPM, TX_MACRO_AIF1_CAP, 0,
1304 tx_aif1_cap_mixer, ARRAY_SIZE(tx_aif1_cap_mixer)),
1305
1306 SND_SOC_DAPM_MIXER("TX_AIF2_CAP Mixer", SND_SOC_NOPM, TX_MACRO_AIF2_CAP, 0,
1307 tx_aif2_cap_mixer, ARRAY_SIZE(tx_aif2_cap_mixer)),
1308
Karthikeyan Manif3bb8182019-07-11 14:38:54 -07001309 SND_SOC_DAPM_MIXER("TX_AIF3_CAP Mixer", SND_SOC_NOPM, TX_MACRO_AIF3_CAP, 0,
1310 tx_aif3_cap_mixer, ARRAY_SIZE(tx_aif3_cap_mixer)),
1311
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301312
1313 TX_MACRO_DAPM_MUX("TX DMIC MUX0", 0, tx_dmic0),
1314 TX_MACRO_DAPM_MUX("TX DMIC MUX1", 0, tx_dmic1),
1315 TX_MACRO_DAPM_MUX("TX DMIC MUX2", 0, tx_dmic2),
1316 TX_MACRO_DAPM_MUX("TX DMIC MUX3", 0, tx_dmic3),
1317 TX_MACRO_DAPM_MUX("TX DMIC MUX4", 0, tx_dmic4),
1318 TX_MACRO_DAPM_MUX("TX DMIC MUX5", 0, tx_dmic5),
1319 TX_MACRO_DAPM_MUX("TX DMIC MUX6", 0, tx_dmic6),
1320 TX_MACRO_DAPM_MUX("TX DMIC MUX7", 0, tx_dmic7),
1321
1322 TX_MACRO_DAPM_MUX("TX SMIC MUX0", 0, tx_smic0),
1323 TX_MACRO_DAPM_MUX("TX SMIC MUX1", 0, tx_smic1),
1324 TX_MACRO_DAPM_MUX("TX SMIC MUX2", 0, tx_smic2),
1325 TX_MACRO_DAPM_MUX("TX SMIC MUX3", 0, tx_smic3),
1326 TX_MACRO_DAPM_MUX("TX SMIC MUX4", 0, tx_smic4),
1327 TX_MACRO_DAPM_MUX("TX SMIC MUX5", 0, tx_smic5),
1328 TX_MACRO_DAPM_MUX("TX SMIC MUX6", 0, tx_smic6),
1329 TX_MACRO_DAPM_MUX("TX SMIC MUX7", 0, tx_smic7),
1330
1331 SND_SOC_DAPM_MICBIAS_E("TX MIC BIAS1", SND_SOC_NOPM, 0, 0,
1332 tx_macro_enable_micbias,
1333 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1334 SND_SOC_DAPM_ADC_E("TX DMIC0", 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 DMIC1", 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 DMIC2", 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 DMIC3", 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_ADC_E("TX DMIC4", NULL, SND_SOC_NOPM, 0, 0,
1351 tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
1352 SND_SOC_DAPM_POST_PMD),
1353
1354 SND_SOC_DAPM_ADC_E("TX DMIC5", NULL, SND_SOC_NOPM, 0, 0,
1355 tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
1356 SND_SOC_DAPM_POST_PMD),
1357
1358 SND_SOC_DAPM_ADC_E("TX DMIC6", NULL, SND_SOC_NOPM, 0, 0,
1359 tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
1360 SND_SOC_DAPM_POST_PMD),
1361
1362 SND_SOC_DAPM_ADC_E("TX DMIC7", NULL, SND_SOC_NOPM, 0, 0,
1363 tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
1364 SND_SOC_DAPM_POST_PMD),
1365
1366 SND_SOC_DAPM_INPUT("TX SWR_ADC0"),
1367 SND_SOC_DAPM_INPUT("TX SWR_ADC1"),
1368 SND_SOC_DAPM_INPUT("TX SWR_ADC2"),
1369 SND_SOC_DAPM_INPUT("TX SWR_ADC3"),
1370 SND_SOC_DAPM_INPUT("TX SWR_DMIC0"),
1371 SND_SOC_DAPM_INPUT("TX SWR_DMIC1"),
1372 SND_SOC_DAPM_INPUT("TX SWR_DMIC2"),
1373 SND_SOC_DAPM_INPUT("TX SWR_DMIC3"),
1374 SND_SOC_DAPM_INPUT("TX SWR_DMIC4"),
1375 SND_SOC_DAPM_INPUT("TX SWR_DMIC5"),
1376 SND_SOC_DAPM_INPUT("TX SWR_DMIC6"),
1377 SND_SOC_DAPM_INPUT("TX SWR_DMIC7"),
1378
Ramprasad Katkamf83acfb2018-08-11 23:28:57 +05301379 SND_SOC_DAPM_MUX_E("TX DEC0 MUX", SND_SOC_NOPM,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301380 TX_MACRO_DEC0, 0,
1381 &tx_dec0_mux, tx_macro_enable_dec,
1382 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1383 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1384
Ramprasad Katkamf83acfb2018-08-11 23:28:57 +05301385 SND_SOC_DAPM_MUX_E("TX DEC1 MUX", SND_SOC_NOPM,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301386 TX_MACRO_DEC1, 0,
1387 &tx_dec1_mux, tx_macro_enable_dec,
1388 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1389 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1390
Ramprasad Katkamf83acfb2018-08-11 23:28:57 +05301391 SND_SOC_DAPM_MUX_E("TX DEC2 MUX", SND_SOC_NOPM,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301392 TX_MACRO_DEC2, 0,
1393 &tx_dec2_mux, tx_macro_enable_dec,
1394 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1395 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1396
Ramprasad Katkamf83acfb2018-08-11 23:28:57 +05301397 SND_SOC_DAPM_MUX_E("TX DEC3 MUX", SND_SOC_NOPM,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301398 TX_MACRO_DEC3, 0,
1399 &tx_dec3_mux, tx_macro_enable_dec,
1400 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1401 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1402
Ramprasad Katkamf83acfb2018-08-11 23:28:57 +05301403 SND_SOC_DAPM_MUX_E("TX DEC4 MUX", SND_SOC_NOPM,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301404 TX_MACRO_DEC4, 0,
1405 &tx_dec4_mux, tx_macro_enable_dec,
1406 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1407 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1408
Ramprasad Katkamf83acfb2018-08-11 23:28:57 +05301409 SND_SOC_DAPM_MUX_E("TX DEC5 MUX", SND_SOC_NOPM,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301410 TX_MACRO_DEC5, 0,
1411 &tx_dec5_mux, tx_macro_enable_dec,
1412 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1413 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1414
Ramprasad Katkamf83acfb2018-08-11 23:28:57 +05301415 SND_SOC_DAPM_MUX_E("TX DEC6 MUX", SND_SOC_NOPM,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301416 TX_MACRO_DEC6, 0,
1417 &tx_dec6_mux, tx_macro_enable_dec,
1418 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1419 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1420
Ramprasad Katkamf83acfb2018-08-11 23:28:57 +05301421 SND_SOC_DAPM_MUX_E("TX DEC7 MUX", SND_SOC_NOPM,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301422 TX_MACRO_DEC7, 0,
1423 &tx_dec7_mux, tx_macro_enable_dec,
1424 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1425 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1426
1427 SND_SOC_DAPM_SUPPLY_S("TX_MCLK", 0, SND_SOC_NOPM, 0, 0,
1428 tx_macro_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
Sudheer Papothie456c2c2019-03-05 07:08:45 +05301429
1430 SND_SOC_DAPM_SUPPLY_S("TX_SWR_CLK", 0, SND_SOC_NOPM, 0, 0,
1431 tx_macro_tx_swr_clk_event,
1432 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1433
1434 SND_SOC_DAPM_SUPPLY_S("VA_SWR_CLK", 0, SND_SOC_NOPM, 0, 0,
1435 tx_macro_va_swr_clk_event,
1436 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301437};
1438
1439static const struct snd_soc_dapm_route tx_audio_map[] = {
1440 {"TX_AIF1 CAP", NULL, "TX_MCLK"},
1441 {"TX_AIF2 CAP", NULL, "TX_MCLK"},
Karthikeyan Manif3bb8182019-07-11 14:38:54 -07001442 {"TX_AIF3 CAP", NULL, "TX_MCLK"},
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301443
1444 {"TX_AIF1 CAP", NULL, "TX_AIF1_CAP Mixer"},
1445 {"TX_AIF2 CAP", NULL, "TX_AIF2_CAP Mixer"},
Karthikeyan Manif3bb8182019-07-11 14:38:54 -07001446 {"TX_AIF3 CAP", NULL, "TX_AIF3_CAP Mixer"},
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301447
1448 {"TX_AIF1_CAP Mixer", "DEC0", "TX DEC0 MUX"},
1449 {"TX_AIF1_CAP Mixer", "DEC1", "TX DEC1 MUX"},
1450 {"TX_AIF1_CAP Mixer", "DEC2", "TX DEC2 MUX"},
1451 {"TX_AIF1_CAP Mixer", "DEC3", "TX DEC3 MUX"},
1452 {"TX_AIF1_CAP Mixer", "DEC4", "TX DEC4 MUX"},
1453 {"TX_AIF1_CAP Mixer", "DEC5", "TX DEC5 MUX"},
1454 {"TX_AIF1_CAP Mixer", "DEC6", "TX DEC6 MUX"},
1455 {"TX_AIF1_CAP Mixer", "DEC7", "TX DEC7 MUX"},
1456
1457 {"TX_AIF2_CAP Mixer", "DEC0", "TX DEC0 MUX"},
1458 {"TX_AIF2_CAP Mixer", "DEC1", "TX DEC1 MUX"},
1459 {"TX_AIF2_CAP Mixer", "DEC2", "TX DEC2 MUX"},
1460 {"TX_AIF2_CAP Mixer", "DEC3", "TX DEC3 MUX"},
1461 {"TX_AIF2_CAP Mixer", "DEC4", "TX DEC4 MUX"},
1462 {"TX_AIF2_CAP Mixer", "DEC5", "TX DEC5 MUX"},
1463 {"TX_AIF2_CAP Mixer", "DEC6", "TX DEC6 MUX"},
1464 {"TX_AIF2_CAP Mixer", "DEC7", "TX DEC7 MUX"},
1465
Karthikeyan Manif3bb8182019-07-11 14:38:54 -07001466 {"TX_AIF3_CAP Mixer", "DEC0", "TX DEC0 MUX"},
1467 {"TX_AIF3_CAP Mixer", "DEC1", "TX DEC1 MUX"},
1468 {"TX_AIF3_CAP Mixer", "DEC2", "TX DEC2 MUX"},
1469 {"TX_AIF3_CAP Mixer", "DEC3", "TX DEC3 MUX"},
1470 {"TX_AIF3_CAP Mixer", "DEC4", "TX DEC4 MUX"},
1471 {"TX_AIF3_CAP Mixer", "DEC5", "TX DEC5 MUX"},
1472 {"TX_AIF3_CAP Mixer", "DEC6", "TX DEC6 MUX"},
1473 {"TX_AIF3_CAP Mixer", "DEC7", "TX DEC7 MUX"},
1474
Laxminath Kasamfc281ad2018-08-06 20:19:40 +05301475 {"TX DEC0 MUX", NULL, "TX_MCLK"},
1476 {"TX DEC1 MUX", NULL, "TX_MCLK"},
1477 {"TX DEC2 MUX", NULL, "TX_MCLK"},
1478 {"TX DEC3 MUX", NULL, "TX_MCLK"},
1479 {"TX DEC4 MUX", NULL, "TX_MCLK"},
1480 {"TX DEC5 MUX", NULL, "TX_MCLK"},
1481 {"TX DEC6 MUX", NULL, "TX_MCLK"},
1482 {"TX DEC7 MUX", NULL, "TX_MCLK"},
1483
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301484 {"TX DEC0 MUX", "MSM_DMIC", "TX DMIC MUX0"},
1485 {"TX DMIC MUX0", "DMIC0", "TX DMIC0"},
1486 {"TX DMIC MUX0", "DMIC1", "TX DMIC1"},
1487 {"TX DMIC MUX0", "DMIC2", "TX DMIC2"},
1488 {"TX DMIC MUX0", "DMIC3", "TX DMIC3"},
1489 {"TX DMIC MUX0", "DMIC4", "TX DMIC4"},
1490 {"TX DMIC MUX0", "DMIC5", "TX DMIC5"},
1491 {"TX DMIC MUX0", "DMIC6", "TX DMIC6"},
1492 {"TX DMIC MUX0", "DMIC7", "TX DMIC7"},
1493
1494 {"TX DEC0 MUX", "SWR_MIC", "TX SMIC MUX0"},
Sudheer Papothie456c2c2019-03-05 07:08:45 +05301495 {"TX SMIC MUX0", NULL, "TX_SWR_CLK"},
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301496 {"TX SMIC MUX0", "ADC0", "TX SWR_ADC0"},
1497 {"TX SMIC MUX0", "ADC1", "TX SWR_ADC1"},
1498 {"TX SMIC MUX0", "ADC2", "TX SWR_ADC2"},
1499 {"TX SMIC MUX0", "ADC3", "TX SWR_ADC3"},
1500 {"TX SMIC MUX0", "SWR_DMIC0", "TX SWR_DMIC0"},
1501 {"TX SMIC MUX0", "SWR_DMIC1", "TX SWR_DMIC1"},
1502 {"TX SMIC MUX0", "SWR_DMIC2", "TX SWR_DMIC2"},
1503 {"TX SMIC MUX0", "SWR_DMIC3", "TX SWR_DMIC3"},
1504 {"TX SMIC MUX0", "SWR_DMIC4", "TX SWR_DMIC4"},
1505 {"TX SMIC MUX0", "SWR_DMIC5", "TX SWR_DMIC5"},
1506 {"TX SMIC MUX0", "SWR_DMIC6", "TX SWR_DMIC6"},
1507 {"TX SMIC MUX0", "SWR_DMIC7", "TX SWR_DMIC7"},
1508
1509 {"TX DEC1 MUX", "MSM_DMIC", "TX DMIC MUX1"},
1510 {"TX DMIC MUX1", "DMIC0", "TX DMIC0"},
1511 {"TX DMIC MUX1", "DMIC1", "TX DMIC1"},
1512 {"TX DMIC MUX1", "DMIC2", "TX DMIC2"},
1513 {"TX DMIC MUX1", "DMIC3", "TX DMIC3"},
1514 {"TX DMIC MUX1", "DMIC4", "TX DMIC4"},
1515 {"TX DMIC MUX1", "DMIC5", "TX DMIC5"},
1516 {"TX DMIC MUX1", "DMIC6", "TX DMIC6"},
1517 {"TX DMIC MUX1", "DMIC7", "TX DMIC7"},
1518
1519 {"TX DEC1 MUX", "SWR_MIC", "TX SMIC MUX1"},
Sudheer Papothie456c2c2019-03-05 07:08:45 +05301520 {"TX SMIC MUX1", NULL, "TX_SWR_CLK"},
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301521 {"TX SMIC MUX1", "ADC0", "TX SWR_ADC0"},
1522 {"TX SMIC MUX1", "ADC1", "TX SWR_ADC1"},
1523 {"TX SMIC MUX1", "ADC2", "TX SWR_ADC2"},
1524 {"TX SMIC MUX1", "ADC3", "TX SWR_ADC3"},
1525 {"TX SMIC MUX1", "SWR_DMIC0", "TX SWR_DMIC0"},
1526 {"TX SMIC MUX1", "SWR_DMIC1", "TX SWR_DMIC1"},
1527 {"TX SMIC MUX1", "SWR_DMIC2", "TX SWR_DMIC2"},
1528 {"TX SMIC MUX1", "SWR_DMIC3", "TX SWR_DMIC3"},
1529 {"TX SMIC MUX1", "SWR_DMIC4", "TX SWR_DMIC4"},
1530 {"TX SMIC MUX1", "SWR_DMIC5", "TX SWR_DMIC5"},
1531 {"TX SMIC MUX1", "SWR_DMIC6", "TX SWR_DMIC6"},
1532 {"TX SMIC MUX1", "SWR_DMIC7", "TX SWR_DMIC7"},
1533
1534 {"TX DEC2 MUX", "MSM_DMIC", "TX DMIC MUX2"},
1535 {"TX DMIC MUX2", "DMIC0", "TX DMIC0"},
1536 {"TX DMIC MUX2", "DMIC1", "TX DMIC1"},
1537 {"TX DMIC MUX2", "DMIC2", "TX DMIC2"},
1538 {"TX DMIC MUX2", "DMIC3", "TX DMIC3"},
1539 {"TX DMIC MUX2", "DMIC4", "TX DMIC4"},
1540 {"TX DMIC MUX2", "DMIC5", "TX DMIC5"},
1541 {"TX DMIC MUX2", "DMIC6", "TX DMIC6"},
1542 {"TX DMIC MUX2", "DMIC7", "TX DMIC7"},
1543
1544 {"TX DEC2 MUX", "SWR_MIC", "TX SMIC MUX2"},
Sudheer Papothie456c2c2019-03-05 07:08:45 +05301545 {"TX SMIC MUX2", NULL, "TX_SWR_CLK"},
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301546 {"TX SMIC MUX2", "ADC0", "TX SWR_ADC0"},
1547 {"TX SMIC MUX2", "ADC1", "TX SWR_ADC1"},
1548 {"TX SMIC MUX2", "ADC2", "TX SWR_ADC2"},
1549 {"TX SMIC MUX2", "ADC3", "TX SWR_ADC3"},
1550 {"TX SMIC MUX2", "SWR_DMIC0", "TX SWR_DMIC0"},
1551 {"TX SMIC MUX2", "SWR_DMIC1", "TX SWR_DMIC1"},
1552 {"TX SMIC MUX2", "SWR_DMIC2", "TX SWR_DMIC2"},
1553 {"TX SMIC MUX2", "SWR_DMIC3", "TX SWR_DMIC3"},
1554 {"TX SMIC MUX2", "SWR_DMIC4", "TX SWR_DMIC4"},
1555 {"TX SMIC MUX2", "SWR_DMIC5", "TX SWR_DMIC5"},
1556 {"TX SMIC MUX2", "SWR_DMIC6", "TX SWR_DMIC6"},
1557 {"TX SMIC MUX2", "SWR_DMIC7", "TX SWR_DMIC7"},
1558
1559 {"TX DEC3 MUX", "MSM_DMIC", "TX DMIC MUX3"},
1560 {"TX DMIC MUX3", "DMIC0", "TX DMIC0"},
1561 {"TX DMIC MUX3", "DMIC1", "TX DMIC1"},
1562 {"TX DMIC MUX3", "DMIC2", "TX DMIC2"},
1563 {"TX DMIC MUX3", "DMIC3", "TX DMIC3"},
1564 {"TX DMIC MUX3", "DMIC4", "TX DMIC4"},
1565 {"TX DMIC MUX3", "DMIC5", "TX DMIC5"},
1566 {"TX DMIC MUX3", "DMIC6", "TX DMIC6"},
1567 {"TX DMIC MUX3", "DMIC7", "TX DMIC7"},
1568
1569 {"TX DEC3 MUX", "SWR_MIC", "TX SMIC MUX3"},
Sudheer Papothie456c2c2019-03-05 07:08:45 +05301570 {"TX SMIC MUX3", NULL, "TX_SWR_CLK"},
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301571 {"TX SMIC MUX3", "ADC0", "TX SWR_ADC0"},
1572 {"TX SMIC MUX3", "ADC1", "TX SWR_ADC1"},
1573 {"TX SMIC MUX3", "ADC2", "TX SWR_ADC2"},
1574 {"TX SMIC MUX3", "ADC3", "TX SWR_ADC3"},
1575 {"TX SMIC MUX3", "SWR_DMIC0", "TX SWR_DMIC0"},
1576 {"TX SMIC MUX3", "SWR_DMIC1", "TX SWR_DMIC1"},
1577 {"TX SMIC MUX3", "SWR_DMIC2", "TX SWR_DMIC2"},
1578 {"TX SMIC MUX3", "SWR_DMIC3", "TX SWR_DMIC3"},
1579 {"TX SMIC MUX3", "SWR_DMIC4", "TX SWR_DMIC4"},
1580 {"TX SMIC MUX3", "SWR_DMIC5", "TX SWR_DMIC5"},
1581 {"TX SMIC MUX3", "SWR_DMIC6", "TX SWR_DMIC6"},
1582 {"TX SMIC MUX3", "SWR_DMIC7", "TX SWR_DMIC7"},
1583
1584 {"TX DEC4 MUX", "MSM_DMIC", "TX DMIC MUX4"},
1585 {"TX DMIC MUX4", "DMIC0", "TX DMIC0"},
1586 {"TX DMIC MUX4", "DMIC1", "TX DMIC1"},
1587 {"TX DMIC MUX4", "DMIC2", "TX DMIC2"},
1588 {"TX DMIC MUX4", "DMIC3", "TX DMIC3"},
1589 {"TX DMIC MUX4", "DMIC4", "TX DMIC4"},
1590 {"TX DMIC MUX4", "DMIC5", "TX DMIC5"},
1591 {"TX DMIC MUX4", "DMIC6", "TX DMIC6"},
1592 {"TX DMIC MUX4", "DMIC7", "TX DMIC7"},
1593
1594 {"TX DEC4 MUX", "SWR_MIC", "TX SMIC MUX4"},
Sudheer Papothie456c2c2019-03-05 07:08:45 +05301595 {"TX SMIC MUX4", NULL, "TX_SWR_CLK"},
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301596 {"TX SMIC MUX4", "ADC0", "TX SWR_ADC0"},
1597 {"TX SMIC MUX4", "ADC1", "TX SWR_ADC1"},
1598 {"TX SMIC MUX4", "ADC2", "TX SWR_ADC2"},
1599 {"TX SMIC MUX4", "ADC3", "TX SWR_ADC3"},
1600 {"TX SMIC MUX4", "SWR_DMIC0", "TX SWR_DMIC0"},
1601 {"TX SMIC MUX4", "SWR_DMIC1", "TX SWR_DMIC1"},
1602 {"TX SMIC MUX4", "SWR_DMIC2", "TX SWR_DMIC2"},
1603 {"TX SMIC MUX4", "SWR_DMIC3", "TX SWR_DMIC3"},
1604 {"TX SMIC MUX4", "SWR_DMIC4", "TX SWR_DMIC4"},
1605 {"TX SMIC MUX4", "SWR_DMIC5", "TX SWR_DMIC5"},
1606 {"TX SMIC MUX4", "SWR_DMIC6", "TX SWR_DMIC6"},
1607 {"TX SMIC MUX4", "SWR_DMIC7", "TX SWR_DMIC7"},
1608
1609 {"TX DEC5 MUX", "MSM_DMIC", "TX DMIC MUX5"},
1610 {"TX DMIC MUX5", "DMIC0", "TX DMIC0"},
1611 {"TX DMIC MUX5", "DMIC1", "TX DMIC1"},
1612 {"TX DMIC MUX5", "DMIC2", "TX DMIC2"},
1613 {"TX DMIC MUX5", "DMIC3", "TX DMIC3"},
1614 {"TX DMIC MUX5", "DMIC4", "TX DMIC4"},
1615 {"TX DMIC MUX5", "DMIC5", "TX DMIC5"},
1616 {"TX DMIC MUX5", "DMIC6", "TX DMIC6"},
1617 {"TX DMIC MUX5", "DMIC7", "TX DMIC7"},
1618
1619 {"TX DEC5 MUX", "SWR_MIC", "TX SMIC MUX5"},
Sudheer Papothie456c2c2019-03-05 07:08:45 +05301620 {"TX SMIC MUX5", NULL, "TX_SWR_CLK"},
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301621 {"TX SMIC MUX5", "ADC0", "TX SWR_ADC0"},
1622 {"TX SMIC MUX5", "ADC1", "TX SWR_ADC1"},
1623 {"TX SMIC MUX5", "ADC2", "TX SWR_ADC2"},
1624 {"TX SMIC MUX5", "ADC3", "TX SWR_ADC3"},
1625 {"TX SMIC MUX5", "SWR_DMIC0", "TX SWR_DMIC0"},
1626 {"TX SMIC MUX5", "SWR_DMIC1", "TX SWR_DMIC1"},
1627 {"TX SMIC MUX5", "SWR_DMIC2", "TX SWR_DMIC2"},
1628 {"TX SMIC MUX5", "SWR_DMIC3", "TX SWR_DMIC3"},
1629 {"TX SMIC MUX5", "SWR_DMIC4", "TX SWR_DMIC4"},
1630 {"TX SMIC MUX5", "SWR_DMIC5", "TX SWR_DMIC5"},
1631 {"TX SMIC MUX5", "SWR_DMIC6", "TX SWR_DMIC6"},
1632 {"TX SMIC MUX5", "SWR_DMIC7", "TX SWR_DMIC7"},
1633
1634 {"TX DEC6 MUX", "MSM_DMIC", "TX DMIC MUX6"},
1635 {"TX DMIC MUX6", "DMIC0", "TX DMIC0"},
1636 {"TX DMIC MUX6", "DMIC1", "TX DMIC1"},
1637 {"TX DMIC MUX6", "DMIC2", "TX DMIC2"},
1638 {"TX DMIC MUX6", "DMIC3", "TX DMIC3"},
1639 {"TX DMIC MUX6", "DMIC4", "TX DMIC4"},
1640 {"TX DMIC MUX6", "DMIC5", "TX DMIC5"},
1641 {"TX DMIC MUX6", "DMIC6", "TX DMIC6"},
1642 {"TX DMIC MUX6", "DMIC7", "TX DMIC7"},
1643
1644 {"TX DEC6 MUX", "SWR_MIC", "TX SMIC MUX6"},
Sudheer Papothie456c2c2019-03-05 07:08:45 +05301645 {"TX SMIC MUX6", NULL, "TX_SWR_CLK"},
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301646 {"TX SMIC MUX6", "ADC0", "TX SWR_ADC0"},
1647 {"TX SMIC MUX6", "ADC1", "TX SWR_ADC1"},
1648 {"TX SMIC MUX6", "ADC2", "TX SWR_ADC2"},
1649 {"TX SMIC MUX6", "ADC3", "TX SWR_ADC3"},
1650 {"TX SMIC MUX6", "SWR_DMIC0", "TX SWR_DMIC0"},
1651 {"TX SMIC MUX6", "SWR_DMIC1", "TX SWR_DMIC1"},
1652 {"TX SMIC MUX6", "SWR_DMIC2", "TX SWR_DMIC2"},
1653 {"TX SMIC MUX6", "SWR_DMIC3", "TX SWR_DMIC3"},
1654 {"TX SMIC MUX6", "SWR_DMIC4", "TX SWR_DMIC4"},
1655 {"TX SMIC MUX6", "SWR_DMIC5", "TX SWR_DMIC5"},
1656 {"TX SMIC MUX6", "SWR_DMIC6", "TX SWR_DMIC6"},
1657 {"TX SMIC MUX6", "SWR_DMIC7", "TX SWR_DMIC7"},
1658
1659 {"TX DEC7 MUX", "MSM_DMIC", "TX DMIC MUX7"},
1660 {"TX DMIC MUX7", "DMIC0", "TX DMIC0"},
1661 {"TX DMIC MUX7", "DMIC1", "TX DMIC1"},
1662 {"TX DMIC MUX7", "DMIC2", "TX DMIC2"},
1663 {"TX DMIC MUX7", "DMIC3", "TX DMIC3"},
1664 {"TX DMIC MUX7", "DMIC4", "TX DMIC4"},
1665 {"TX DMIC MUX7", "DMIC5", "TX DMIC5"},
1666 {"TX DMIC MUX7", "DMIC6", "TX DMIC6"},
1667 {"TX DMIC MUX7", "DMIC7", "TX DMIC7"},
1668
1669 {"TX DEC7 MUX", "SWR_MIC", "TX SMIC MUX7"},
Sudheer Papothie456c2c2019-03-05 07:08:45 +05301670 {"TX SMIC MUX7", NULL, "TX_SWR_CLK"},
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301671 {"TX SMIC MUX7", "ADC0", "TX SWR_ADC0"},
1672 {"TX SMIC MUX7", "ADC1", "TX SWR_ADC1"},
1673 {"TX SMIC MUX7", "ADC2", "TX SWR_ADC2"},
1674 {"TX SMIC MUX7", "ADC3", "TX SWR_ADC3"},
1675 {"TX SMIC MUX7", "SWR_DMIC0", "TX SWR_DMIC0"},
1676 {"TX SMIC MUX7", "SWR_DMIC1", "TX SWR_DMIC1"},
1677 {"TX SMIC MUX7", "SWR_DMIC2", "TX SWR_DMIC2"},
1678 {"TX SMIC MUX7", "SWR_DMIC3", "TX SWR_DMIC3"},
1679 {"TX SMIC MUX7", "SWR_DMIC4", "TX SWR_DMIC4"},
1680 {"TX SMIC MUX7", "SWR_DMIC5", "TX SWR_DMIC5"},
1681 {"TX SMIC MUX7", "SWR_DMIC6", "TX SWR_DMIC6"},
1682 {"TX SMIC MUX7", "SWR_DMIC7", "TX SWR_DMIC7"},
1683};
1684
1685static const struct snd_kcontrol_new tx_macro_snd_controls[] = {
1686 SOC_SINGLE_SX_TLV("TX_DEC0 Volume",
1687 BOLERO_CDC_TX0_TX_VOL_CTL,
1688 0, -84, 40, digital_gain),
1689 SOC_SINGLE_SX_TLV("TX_DEC1 Volume",
1690 BOLERO_CDC_TX1_TX_VOL_CTL,
1691 0, -84, 40, digital_gain),
1692 SOC_SINGLE_SX_TLV("TX_DEC2 Volume",
1693 BOLERO_CDC_TX2_TX_VOL_CTL,
1694 0, -84, 40, digital_gain),
1695 SOC_SINGLE_SX_TLV("TX_DEC3 Volume",
1696 BOLERO_CDC_TX3_TX_VOL_CTL,
1697 0, -84, 40, digital_gain),
1698 SOC_SINGLE_SX_TLV("TX_DEC4 Volume",
1699 BOLERO_CDC_TX4_TX_VOL_CTL,
1700 0, -84, 40, digital_gain),
1701 SOC_SINGLE_SX_TLV("TX_DEC5 Volume",
1702 BOLERO_CDC_TX5_TX_VOL_CTL,
1703 0, -84, 40, digital_gain),
1704 SOC_SINGLE_SX_TLV("TX_DEC6 Volume",
1705 BOLERO_CDC_TX6_TX_VOL_CTL,
1706 0, -84, 40, digital_gain),
1707 SOC_SINGLE_SX_TLV("TX_DEC7 Volume",
1708 BOLERO_CDC_TX7_TX_VOL_CTL,
1709 0, -84, 40, digital_gain),
Karthikeyan Mani765eaab2019-07-18 16:27:01 -07001710
Karthikeyan Mani1dcd5a32019-08-22 14:37:13 -07001711 SOC_ENUM_EXT("DEC0 MODE", dec_mode_mux_enum,
1712 tx_macro_dec_mode_get, tx_macro_dec_mode_put),
1713
1714 SOC_ENUM_EXT("DEC1 MODE", dec_mode_mux_enum,
1715 tx_macro_dec_mode_get, tx_macro_dec_mode_put),
1716
1717 SOC_ENUM_EXT("DEC2 MODE", dec_mode_mux_enum,
1718 tx_macro_dec_mode_get, tx_macro_dec_mode_put),
1719
1720 SOC_ENUM_EXT("DEC3 MODE", dec_mode_mux_enum,
1721 tx_macro_dec_mode_get, tx_macro_dec_mode_put),
1722
1723 SOC_ENUM_EXT("DEC4 MODE", dec_mode_mux_enum,
1724 tx_macro_dec_mode_get, tx_macro_dec_mode_put),
1725
1726 SOC_ENUM_EXT("DEC5 MODE", dec_mode_mux_enum,
1727 tx_macro_dec_mode_get, tx_macro_dec_mode_put),
1728
1729 SOC_ENUM_EXT("DEC6 MODE", dec_mode_mux_enum,
1730 tx_macro_dec_mode_get, tx_macro_dec_mode_put),
1731
1732 SOC_ENUM_EXT("DEC7 MODE", dec_mode_mux_enum,
1733 tx_macro_dec_mode_get, tx_macro_dec_mode_put),
1734
Karthikeyan Mani765eaab2019-07-18 16:27:01 -07001735 SOC_SINGLE_EXT("DEC0_BCS Switch", SND_SOC_NOPM, 0, 1, 0,
1736 tx_macro_get_bcs, tx_macro_set_bcs),
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301737};
1738
Sudheer Papothi06a4c642019-08-08 05:17:46 +05301739static int tx_macro_register_event_listener(struct snd_soc_component *component,
1740 bool enable)
1741{
1742 struct device *tx_dev = NULL;
1743 struct tx_macro_priv *tx_priv = NULL;
1744 int ret = 0;
1745
1746 if (!component)
1747 return -EINVAL;
1748
1749 tx_dev = bolero_get_device_ptr(component->dev, TX_MACRO);
1750 if (!tx_dev) {
1751 dev_err(component->dev,
1752 "%s: null device for macro!\n", __func__);
1753 return -EINVAL;
1754 }
1755 tx_priv = dev_get_drvdata(tx_dev);
1756 if (!tx_priv) {
1757 dev_err(component->dev,
1758 "%s: priv is null for macro!\n", __func__);
1759 return -EINVAL;
1760 }
1761 if (tx_priv->swr_ctrl_data) {
Sudheer Papothibc3f1e52019-09-17 04:03:10 +05301762 if (enable) {
Sudheer Papothi06a4c642019-08-08 05:17:46 +05301763 ret = swrm_wcd_notify(
1764 tx_priv->swr_ctrl_data[0].tx_swr_pdev,
1765 SWR_REGISTER_WAKEUP, NULL);
Sudheer Papothibc3f1e52019-09-17 04:03:10 +05301766 msm_cdc_pinctrl_set_wakeup_capable(
1767 tx_priv->tx_swr_gpio_p, false);
1768 } else {
1769 msm_cdc_pinctrl_set_wakeup_capable(
1770 tx_priv->tx_swr_gpio_p, true);
Sudheer Papothi06a4c642019-08-08 05:17:46 +05301771 ret = swrm_wcd_notify(
1772 tx_priv->swr_ctrl_data[0].tx_swr_pdev,
1773 SWR_DEREGISTER_WAKEUP, NULL);
Sudheer Papothibc3f1e52019-09-17 04:03:10 +05301774 }
Sudheer Papothi06a4c642019-08-08 05:17:46 +05301775 }
1776
1777 return ret;
1778}
1779
Sudheer Papothia7397942019-03-19 03:14:23 +05301780static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv,
1781 struct regmap *regmap, int clk_type,
1782 bool enable)
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301783{
Meng Wang69b55c82019-05-29 11:04:29 +08001784 int ret = 0, clk_tx_ret = 0;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301785
Sudheer Papothi7601cc62019-03-30 03:00:52 +05301786 dev_dbg(tx_priv->dev,
1787 "%s: clock type %s, enable: %s tx_mclk_users: %d\n",
Sudheer Papothia7397942019-03-19 03:14:23 +05301788 __func__, (clk_type ? "VA_MCLK" : "TX_MCLK"),
Sudheer Papothi7601cc62019-03-30 03:00:52 +05301789 (enable ? "enable" : "disable"), tx_priv->tx_mclk_users);
Tanya Dixit8530fb92018-09-14 16:01:25 +05301790
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301791 if (enable) {
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07001792 if (tx_priv->swr_clk_users == 0) {
1793 ret = msm_cdc_pinctrl_select_active_state(
Karthikeyan Mani01f1ba42019-02-26 18:48:15 -08001794 tx_priv->tx_swr_gpio_p);
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07001795 if (ret < 0) {
1796 dev_err_ratelimited(tx_priv->dev,
1797 "%s: tx swr pinctrl enable failed\n",
1798 __func__);
1799 goto exit;
1800 }
1801 }
Sudheer Papothia7397942019-03-19 03:14:23 +05301802
Meng Wang69b55c82019-05-29 11:04:29 +08001803 clk_tx_ret = bolero_clk_rsc_request_clock(tx_priv->dev,
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301804 TX_CORE_CLK,
1805 TX_CORE_CLK,
1806 true);
1807 if (clk_type == TX_MCLK) {
1808 ret = tx_macro_mclk_enable(tx_priv, 1);
1809 if (ret < 0) {
1810 if (tx_priv->swr_clk_users == 0)
1811 msm_cdc_pinctrl_select_sleep_state(
1812 tx_priv->tx_swr_gpio_p);
1813 dev_err_ratelimited(tx_priv->dev,
1814 "%s: request clock enable failed\n",
1815 __func__);
1816 goto done;
1817 }
1818 }
1819 if (clk_type == VA_MCLK) {
Sudheer Papothia7397942019-03-19 03:14:23 +05301820 ret = bolero_clk_rsc_request_clock(tx_priv->dev,
1821 TX_CORE_CLK,
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301822 VA_CORE_CLK,
Sudheer Papothia7397942019-03-19 03:14:23 +05301823 true);
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301824 if (ret < 0) {
1825 if (tx_priv->swr_clk_users == 0)
Sudheer Papothia7397942019-03-19 03:14:23 +05301826 msm_cdc_pinctrl_select_sleep_state(
1827 tx_priv->tx_swr_gpio_p);
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301828 dev_err_ratelimited(tx_priv->dev,
1829 "%s: swr request clk failed\n",
1830 __func__);
1831 goto done;
Sudheer Papothia7397942019-03-19 03:14:23 +05301832 }
Sudheer Papothi296867b2019-06-20 09:24:09 +05301833 bolero_clk_rsc_fs_gen_request(tx_priv->dev,
1834 true);
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301835 if (tx_priv->tx_mclk_users == 0) {
1836 regmap_update_bits(regmap,
1837 BOLERO_CDC_TX_TOP_CSR_FREQ_MCLK,
1838 0x01, 0x01);
1839 regmap_update_bits(regmap,
1840 BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL,
1841 0x01, 0x01);
1842 regmap_update_bits(regmap,
1843 BOLERO_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL,
1844 0x01, 0x01);
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301845 }
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301846 }
1847 if (tx_priv->swr_clk_users == 0) {
Sudheer Papothi7601cc62019-03-30 03:00:52 +05301848 dev_dbg(tx_priv->dev, "%s: reset_swr: %d\n",
1849 __func__, tx_priv->reset_swr);
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05301850 if (tx_priv->reset_swr)
1851 regmap_update_bits(regmap,
1852 BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL,
1853 0x02, 0x02);
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301854 regmap_update_bits(regmap,
1855 BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL,
1856 0x01, 0x01);
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05301857 if (tx_priv->reset_swr)
1858 regmap_update_bits(regmap,
1859 BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL,
1860 0x02, 0x00);
1861 tx_priv->reset_swr = false;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301862 }
Meng Wang69b55c82019-05-29 11:04:29 +08001863 if (!clk_tx_ret)
1864 ret = bolero_clk_rsc_request_clock(tx_priv->dev,
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301865 TX_CORE_CLK,
1866 TX_CORE_CLK,
1867 false);
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301868 tx_priv->swr_clk_users++;
1869 } else {
1870 if (tx_priv->swr_clk_users <= 0) {
Sudheer Papothia7397942019-03-19 03:14:23 +05301871 dev_err_ratelimited(tx_priv->dev,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301872 "tx swrm clock users already 0\n");
1873 tx_priv->swr_clk_users = 0;
Sudheer Papothia7397942019-03-19 03:14:23 +05301874 return 0;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301875 }
Meng Wang69b55c82019-05-29 11:04:29 +08001876 clk_tx_ret = bolero_clk_rsc_request_clock(tx_priv->dev,
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301877 TX_CORE_CLK,
1878 TX_CORE_CLK,
1879 true);
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301880 tx_priv->swr_clk_users--;
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301881 if (tx_priv->swr_clk_users == 0)
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301882 regmap_update_bits(regmap,
1883 BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL,
1884 0x01, 0x00);
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301885 if (clk_type == TX_MCLK)
1886 tx_macro_mclk_enable(tx_priv, 0);
1887 if (clk_type == VA_MCLK) {
1888 if (tx_priv->tx_mclk_users == 0) {
1889 regmap_update_bits(regmap,
1890 BOLERO_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL,
1891 0x01, 0x00);
1892 regmap_update_bits(regmap,
1893 BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL,
1894 0x01, 0x00);
Sudheer Papothia7397942019-03-19 03:14:23 +05301895 }
Sudheer Papothi296867b2019-06-20 09:24:09 +05301896 bolero_clk_rsc_fs_gen_request(tx_priv->dev,
1897 false);
Sudheer Papothia7397942019-03-19 03:14:23 +05301898 ret = bolero_clk_rsc_request_clock(tx_priv->dev,
1899 TX_CORE_CLK,
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301900 VA_CORE_CLK,
Sudheer Papothia7397942019-03-19 03:14:23 +05301901 false);
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301902 if (ret < 0) {
1903 dev_err_ratelimited(tx_priv->dev,
1904 "%s: swr request clk failed\n",
1905 __func__);
1906 goto done;
1907 }
1908 }
Meng Wang69b55c82019-05-29 11:04:29 +08001909 if (!clk_tx_ret)
1910 ret = bolero_clk_rsc_request_clock(tx_priv->dev,
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301911 TX_CORE_CLK,
1912 TX_CORE_CLK,
1913 false);
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07001914 if (tx_priv->swr_clk_users == 0) {
1915 ret = msm_cdc_pinctrl_select_sleep_state(
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301916 tx_priv->tx_swr_gpio_p);
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07001917 if (ret < 0) {
1918 dev_err_ratelimited(tx_priv->dev,
1919 "%s: tx swr pinctrl disable failed\n",
1920 __func__);
1921 goto exit;
1922 }
1923 }
Laxminath Kasam989fccf2018-06-15 16:53:31 +05301924 }
Sudheer Papothia7397942019-03-19 03:14:23 +05301925 return 0;
1926
1927done:
Meng Wang69b55c82019-05-29 11:04:29 +08001928 if (!clk_tx_ret)
1929 bolero_clk_rsc_request_clock(tx_priv->dev,
Sudheer Papothia7397942019-03-19 03:14:23 +05301930 TX_CORE_CLK,
1931 TX_CORE_CLK,
1932 false);
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07001933exit:
Sudheer Papothia7397942019-03-19 03:14:23 +05301934 return ret;
1935}
1936
Sudheer Papothi6cc7f522019-06-28 11:04:03 +05301937static int tx_macro_clk_switch(struct snd_soc_component *component)
1938{
1939 struct device *tx_dev = NULL;
1940 struct tx_macro_priv *tx_priv = NULL;
1941 int ret = 0;
1942
1943 if (!component)
1944 return -EINVAL;
1945
1946 tx_dev = bolero_get_device_ptr(component->dev, TX_MACRO);
1947 if (!tx_dev) {
1948 dev_err(component->dev,
1949 "%s: null device for macro!\n", __func__);
1950 return -EINVAL;
1951 }
1952 tx_priv = dev_get_drvdata(tx_dev);
1953 if (!tx_priv) {
1954 dev_err(component->dev,
1955 "%s: priv is null for macro!\n", __func__);
1956 return -EINVAL;
1957 }
1958 if (tx_priv->swr_ctrl_data) {
1959 ret = swrm_wcd_notify(
1960 tx_priv->swr_ctrl_data[0].tx_swr_pdev,
1961 SWR_REQ_CLK_SWITCH, NULL);
1962 }
1963
1964 return ret;
1965}
1966
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07001967static int tx_macro_core_vote(void *handle, bool enable)
1968{
1969 struct tx_macro_priv *tx_priv = (struct tx_macro_priv *) handle;
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07001970
1971 if (tx_priv == NULL) {
1972 pr_err("%s: tx priv data is NULL\n", __func__);
1973 return -EINVAL;
1974 }
1975 if (enable) {
1976 pm_runtime_get_sync(tx_priv->dev);
1977 pm_runtime_put_autosuspend(tx_priv->dev);
1978 pm_runtime_mark_last_busy(tx_priv->dev);
1979 }
1980
Aditya Bavanarid577af92019-10-03 21:09:19 +05301981 if (bolero_check_core_votes(tx_priv->dev))
1982 return 0;
1983 else
1984 return -EINVAL;
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07001985}
1986
Sudheer Papothia7397942019-03-19 03:14:23 +05301987static int tx_macro_swrm_clock(void *handle, bool enable)
1988{
1989 struct tx_macro_priv *tx_priv = (struct tx_macro_priv *) handle;
1990 struct regmap *regmap = dev_get_regmap(tx_priv->dev->parent, NULL);
1991 int ret = 0;
1992
1993 if (regmap == NULL) {
1994 dev_err(tx_priv->dev, "%s: regmap is NULL\n", __func__);
1995 return -EINVAL;
1996 }
1997
1998 mutex_lock(&tx_priv->swr_clk_lock);
Sudheer Papothicf3b4062019-05-10 10:48:43 +05301999 dev_dbg(tx_priv->dev,
2000 "%s: swrm clock %s tx_swr_clk_cnt: %d va_swr_clk_cnt: %d\n",
2001 __func__, (enable ? "enable" : "disable"),
2002 tx_priv->tx_swr_clk_cnt, tx_priv->va_swr_clk_cnt);
Sudheer Papothia7397942019-03-19 03:14:23 +05302003
2004 if (enable) {
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302005 pm_runtime_get_sync(tx_priv->dev);
Sudheer Papothicf3b4062019-05-10 10:48:43 +05302006 if (tx_priv->va_swr_clk_cnt && !tx_priv->tx_swr_clk_cnt) {
Sudheer Papothia7397942019-03-19 03:14:23 +05302007 ret = tx_macro_tx_va_mclk_enable(tx_priv, regmap,
2008 VA_MCLK, enable);
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07002009 if (ret) {
2010 pm_runtime_mark_last_busy(tx_priv->dev);
2011 pm_runtime_put_autosuspend(tx_priv->dev);
Sudheer Papothia7397942019-03-19 03:14:23 +05302012 goto done;
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07002013 }
Sudheer Papothicf3b4062019-05-10 10:48:43 +05302014 tx_priv->va_clk_status++;
Sudheer Papothia7397942019-03-19 03:14:23 +05302015 } else {
Sudheer Papothia7397942019-03-19 03:14:23 +05302016 ret = tx_macro_tx_va_mclk_enable(tx_priv, regmap,
2017 TX_MCLK, enable);
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07002018 if (ret) {
2019 pm_runtime_mark_last_busy(tx_priv->dev);
2020 pm_runtime_put_autosuspend(tx_priv->dev);
Sudheer Papothia7397942019-03-19 03:14:23 +05302021 goto done;
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07002022 }
Sudheer Papothicf3b4062019-05-10 10:48:43 +05302023 tx_priv->tx_clk_status++;
Sudheer Papothia7397942019-03-19 03:14:23 +05302024 }
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302025 pm_runtime_mark_last_busy(tx_priv->dev);
2026 pm_runtime_put_autosuspend(tx_priv->dev);
Sudheer Papothia7397942019-03-19 03:14:23 +05302027 } else {
Sudheer Papothicf3b4062019-05-10 10:48:43 +05302028 if (tx_priv->va_clk_status && !tx_priv->tx_clk_status) {
Sudheer Papothia7397942019-03-19 03:14:23 +05302029 ret = tx_macro_tx_va_mclk_enable(tx_priv, regmap,
2030 VA_MCLK, enable);
2031 if (ret)
2032 goto done;
Sudheer Papothicf3b4062019-05-10 10:48:43 +05302033 --tx_priv->va_clk_status;
2034 } else if (!tx_priv->va_clk_status && tx_priv->tx_clk_status) {
Sudheer Papothia7397942019-03-19 03:14:23 +05302035 ret = tx_macro_tx_va_mclk_enable(tx_priv, regmap,
2036 TX_MCLK, enable);
Sudheer Papothicf3b4062019-05-10 10:48:43 +05302037 if (ret)
2038 goto done;
2039 --tx_priv->tx_clk_status;
2040 } else if (tx_priv->va_clk_status && tx_priv->tx_clk_status) {
2041 if (!tx_priv->va_swr_clk_cnt && tx_priv->tx_swr_clk_cnt) {
2042 ret = tx_macro_tx_va_mclk_enable(tx_priv, regmap,
2043 VA_MCLK, enable);
Sudheer Papothia7397942019-03-19 03:14:23 +05302044 if (ret)
2045 goto done;
Sudheer Papothicf3b4062019-05-10 10:48:43 +05302046 --tx_priv->va_clk_status;
2047 } else {
2048 ret = tx_macro_tx_va_mclk_enable(tx_priv, regmap,
2049 TX_MCLK, enable);
2050 if (ret)
2051 goto done;
2052 --tx_priv->tx_clk_status;
Sudheer Papothia7397942019-03-19 03:14:23 +05302053 }
Sudheer Papothicf3b4062019-05-10 10:48:43 +05302054
2055 } else {
2056 dev_dbg(tx_priv->dev,
2057 "%s: Both clocks are disabled\n", __func__);
Sudheer Papothia7397942019-03-19 03:14:23 +05302058 }
2059 }
Sudheer Papothicf3b4062019-05-10 10:48:43 +05302060
2061 dev_dbg(tx_priv->dev,
2062 "%s: swrm clock users %d tx_clk_sts_cnt: %d va_clk_sts_cnt: %d\n",
2063 __func__, tx_priv->swr_clk_users, tx_priv->tx_clk_status,
2064 tx_priv->va_clk_status);
Sudheer Papothia7397942019-03-19 03:14:23 +05302065done:
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302066 mutex_unlock(&tx_priv->swr_clk_lock);
2067 return ret;
2068}
2069
2070static int tx_macro_validate_dmic_sample_rate(u32 dmic_sample_rate,
2071 struct tx_macro_priv *tx_priv)
2072{
2073 u32 div_factor = TX_MACRO_CLK_DIV_2;
2074 u32 mclk_rate = TX_MACRO_MCLK_FREQ;
2075
2076 if (dmic_sample_rate == TX_MACRO_DMIC_SAMPLE_RATE_UNDEFINED ||
2077 mclk_rate % dmic_sample_rate != 0)
2078 goto undefined_rate;
2079
2080 div_factor = mclk_rate / dmic_sample_rate;
2081
2082 switch (div_factor) {
2083 case 2:
2084 tx_priv->dmic_clk_div = TX_MACRO_CLK_DIV_2;
2085 break;
2086 case 3:
2087 tx_priv->dmic_clk_div = TX_MACRO_CLK_DIV_3;
2088 break;
2089 case 4:
2090 tx_priv->dmic_clk_div = TX_MACRO_CLK_DIV_4;
2091 break;
2092 case 6:
2093 tx_priv->dmic_clk_div = TX_MACRO_CLK_DIV_6;
2094 break;
2095 case 8:
2096 tx_priv->dmic_clk_div = TX_MACRO_CLK_DIV_8;
2097 break;
2098 case 16:
2099 tx_priv->dmic_clk_div = TX_MACRO_CLK_DIV_16;
2100 break;
2101 default:
2102 /* Any other DIV factor is invalid */
2103 goto undefined_rate;
2104 }
2105
2106 /* Valid dmic DIV factors */
2107 dev_dbg(tx_priv->dev, "%s: DMIC_DIV = %u, mclk_rate = %u\n",
2108 __func__, div_factor, mclk_rate);
2109
2110 return dmic_sample_rate;
2111
2112undefined_rate:
2113 dev_dbg(tx_priv->dev, "%s: Invalid rate %d, for mclk %d\n",
2114 __func__, dmic_sample_rate, mclk_rate);
2115 dmic_sample_rate = TX_MACRO_DMIC_SAMPLE_RATE_UNDEFINED;
2116
2117 return dmic_sample_rate;
2118}
2119
Sudheer Papothi72fef482019-08-30 11:00:20 +05302120static const struct tx_macro_reg_mask_val tx_macro_reg_init[] = {
Vatsal Bucha126be652019-09-11 11:32:55 +05302121 {BOLERO_CDC_TX0_TX_PATH_SEC7, 0x3F, 0x02},
Sudheer Papothi72fef482019-08-30 11:00:20 +05302122};
2123
Meng Wang15c825d2018-09-06 10:49:18 +08002124static int tx_macro_init(struct snd_soc_component *component)
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302125{
Meng Wang15c825d2018-09-06 10:49:18 +08002126 struct snd_soc_dapm_context *dapm =
2127 snd_soc_component_get_dapm(component);
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302128 int ret = 0, i = 0;
2129 struct device *tx_dev = NULL;
2130 struct tx_macro_priv *tx_priv = NULL;
2131
Meng Wang15c825d2018-09-06 10:49:18 +08002132 tx_dev = bolero_get_device_ptr(component->dev, TX_MACRO);
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302133 if (!tx_dev) {
Meng Wang15c825d2018-09-06 10:49:18 +08002134 dev_err(component->dev,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302135 "%s: null device for macro!\n", __func__);
2136 return -EINVAL;
2137 }
2138 tx_priv = dev_get_drvdata(tx_dev);
2139 if (!tx_priv) {
Meng Wang15c825d2018-09-06 10:49:18 +08002140 dev_err(component->dev,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302141 "%s: priv is null for macro!\n", __func__);
2142 return -EINVAL;
2143 }
2144 ret = snd_soc_dapm_new_controls(dapm, tx_macro_dapm_widgets,
2145 ARRAY_SIZE(tx_macro_dapm_widgets));
2146 if (ret < 0) {
2147 dev_err(tx_dev, "%s: Failed to add controls\n", __func__);
2148 return ret;
2149 }
2150
2151 ret = snd_soc_dapm_add_routes(dapm, tx_audio_map,
2152 ARRAY_SIZE(tx_audio_map));
2153 if (ret < 0) {
2154 dev_err(tx_dev, "%s: Failed to add routes\n", __func__);
2155 return ret;
2156 }
2157
2158 ret = snd_soc_dapm_new_widgets(dapm->card);
2159 if (ret < 0) {
2160 dev_err(tx_dev, "%s: Failed to add widgets\n", __func__);
2161 return ret;
2162 }
2163
Meng Wang15c825d2018-09-06 10:49:18 +08002164 ret = snd_soc_add_component_controls(component, tx_macro_snd_controls,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302165 ARRAY_SIZE(tx_macro_snd_controls));
2166 if (ret < 0) {
2167 dev_err(tx_dev, "%s: Failed to add snd_ctls\n", __func__);
2168 return ret;
2169 }
Laxminath Kasam638b5602018-09-24 13:19:52 +05302170
2171 snd_soc_dapm_ignore_suspend(dapm, "TX_AIF1 Capture");
2172 snd_soc_dapm_ignore_suspend(dapm, "TX_AIF2 Capture");
Karthikeyan Manif3bb8182019-07-11 14:38:54 -07002173 snd_soc_dapm_ignore_suspend(dapm, "TX_AIF3 Capture");
Laxminath Kasam638b5602018-09-24 13:19:52 +05302174 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC0");
2175 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC1");
2176 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC2");
2177 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC3");
Vatsal Bucha39ead2c2018-12-14 12:22:46 +05302178 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC0");
2179 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC1");
2180 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC2");
2181 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC3");
2182 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC4");
2183 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC5");
2184 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC6");
2185 snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC7");
Laxminath Kasam638b5602018-09-24 13:19:52 +05302186 snd_soc_dapm_sync(dapm);
2187
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302188 for (i = 0; i < NUM_DECIMATORS; i++) {
2189 tx_priv->tx_hpf_work[i].tx_priv = tx_priv;
2190 tx_priv->tx_hpf_work[i].decimator = i;
2191 INIT_DELAYED_WORK(&tx_priv->tx_hpf_work[i].dwork,
2192 tx_macro_tx_hpf_corner_freq_callback);
2193 }
2194
2195 for (i = 0; i < NUM_DECIMATORS; i++) {
2196 tx_priv->tx_mute_dwork[i].tx_priv = tx_priv;
2197 tx_priv->tx_mute_dwork[i].decimator = i;
2198 INIT_DELAYED_WORK(&tx_priv->tx_mute_dwork[i].dwork,
2199 tx_macro_mute_update_callback);
2200 }
Meng Wang15c825d2018-09-06 10:49:18 +08002201 tx_priv->component = component;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302202
Sudheer Papothi72fef482019-08-30 11:00:20 +05302203 for (i = 0; i < ARRAY_SIZE(tx_macro_reg_init); i++)
2204 snd_soc_component_update_bits(component,
2205 tx_macro_reg_init[i].reg,
2206 tx_macro_reg_init[i].mask,
2207 tx_macro_reg_init[i].val);
2208
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302209 return 0;
2210}
2211
Meng Wang15c825d2018-09-06 10:49:18 +08002212static int tx_macro_deinit(struct snd_soc_component *component)
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302213{
2214 struct device *tx_dev = NULL;
2215 struct tx_macro_priv *tx_priv = NULL;
2216
Meng Wang15c825d2018-09-06 10:49:18 +08002217 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302218 return -EINVAL;
2219
Meng Wang15c825d2018-09-06 10:49:18 +08002220 tx_priv->component = NULL;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302221 return 0;
2222}
2223
2224static void tx_macro_add_child_devices(struct work_struct *work)
2225{
2226 struct tx_macro_priv *tx_priv = NULL;
2227 struct platform_device *pdev = NULL;
2228 struct device_node *node = NULL;
2229 struct tx_macro_swr_ctrl_data *swr_ctrl_data = NULL, *temp = NULL;
2230 int ret = 0;
2231 u16 count = 0, ctrl_num = 0;
2232 struct tx_macro_swr_ctrl_platform_data *platdata = NULL;
2233 char plat_dev_name[TX_MACRO_SWR_STRING_LEN] = "";
2234 bool tx_swr_master_node = false;
2235
2236 tx_priv = container_of(work, struct tx_macro_priv,
2237 tx_macro_add_child_devices_work);
2238 if (!tx_priv) {
2239 pr_err("%s: Memory for tx_priv does not exist\n",
2240 __func__);
2241 return;
2242 }
2243
2244 if (!tx_priv->dev) {
2245 pr_err("%s: tx dev does not exist\n", __func__);
2246 return;
2247 }
2248
2249 if (!tx_priv->dev->of_node) {
2250 dev_err(tx_priv->dev,
2251 "%s: DT node for tx_priv does not exist\n", __func__);
2252 return;
2253 }
2254
2255 platdata = &tx_priv->swr_plat_data;
2256 tx_priv->child_count = 0;
2257
2258 for_each_available_child_of_node(tx_priv->dev->of_node, node) {
2259 tx_swr_master_node = false;
2260 if (strnstr(node->name, "tx_swr_master",
2261 strlen("tx_swr_master")) != NULL)
2262 tx_swr_master_node = true;
2263
2264 if (tx_swr_master_node)
2265 strlcpy(plat_dev_name, "tx_swr_ctrl",
2266 (TX_MACRO_SWR_STRING_LEN - 1));
2267 else
2268 strlcpy(plat_dev_name, node->name,
2269 (TX_MACRO_SWR_STRING_LEN - 1));
2270
2271 pdev = platform_device_alloc(plat_dev_name, -1);
2272 if (!pdev) {
2273 dev_err(tx_priv->dev, "%s: pdev memory alloc failed\n",
2274 __func__);
2275 ret = -ENOMEM;
2276 goto err;
2277 }
2278 pdev->dev.parent = tx_priv->dev;
2279 pdev->dev.of_node = node;
2280
2281 if (tx_swr_master_node) {
2282 ret = platform_device_add_data(pdev, platdata,
2283 sizeof(*platdata));
2284 if (ret) {
2285 dev_err(&pdev->dev,
2286 "%s: cannot add plat data ctrl:%d\n",
2287 __func__, ctrl_num);
2288 goto fail_pdev_add;
2289 }
2290 }
2291
2292 ret = platform_device_add(pdev);
2293 if (ret) {
2294 dev_err(&pdev->dev,
2295 "%s: Cannot add platform device\n",
2296 __func__);
2297 goto fail_pdev_add;
2298 }
2299
2300 if (tx_swr_master_node) {
2301 temp = krealloc(swr_ctrl_data,
2302 (ctrl_num + 1) * sizeof(
2303 struct tx_macro_swr_ctrl_data),
2304 GFP_KERNEL);
2305 if (!temp) {
2306 ret = -ENOMEM;
2307 goto fail_pdev_add;
2308 }
2309 swr_ctrl_data = temp;
2310 swr_ctrl_data[ctrl_num].tx_swr_pdev = pdev;
2311 ctrl_num++;
2312 dev_dbg(&pdev->dev,
2313 "%s: Added soundwire ctrl device(s)\n",
2314 __func__);
2315 tx_priv->swr_ctrl_data = swr_ctrl_data;
2316 }
2317 if (tx_priv->child_count < TX_MACRO_CHILD_DEVICES_MAX)
2318 tx_priv->pdev_child_devices[
2319 tx_priv->child_count++] = pdev;
2320 else
2321 goto err;
2322 }
2323 return;
2324fail_pdev_add:
2325 for (count = 0; count < tx_priv->child_count; count++)
2326 platform_device_put(tx_priv->pdev_child_devices[count]);
2327err:
2328 return;
2329}
2330
Sudheer Papothia3e969d2018-10-27 06:22:10 +05302331static int tx_macro_set_port_map(struct snd_soc_component *component,
2332 u32 usecase, u32 size, void *data)
2333{
2334 struct device *tx_dev = NULL;
2335 struct tx_macro_priv *tx_priv = NULL;
2336 struct swrm_port_config port_cfg;
2337 int ret = 0;
2338
2339 if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
2340 return -EINVAL;
2341
2342 memset(&port_cfg, 0, sizeof(port_cfg));
2343 port_cfg.uc = usecase;
2344 port_cfg.size = size;
2345 port_cfg.params = data;
2346
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07002347 if (tx_priv->swr_ctrl_data)
2348 ret = swrm_wcd_notify(
2349 tx_priv->swr_ctrl_data[0].tx_swr_pdev,
2350 SWR_SET_PORT_MAP, &port_cfg);
Sudheer Papothia3e969d2018-10-27 06:22:10 +05302351
2352 return ret;
2353}
2354
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302355static void tx_macro_init_ops(struct macro_ops *ops,
2356 char __iomem *tx_io_base)
2357{
2358 memset(ops, 0, sizeof(struct macro_ops));
2359 ops->init = tx_macro_init;
2360 ops->exit = tx_macro_deinit;
2361 ops->io_base = tx_io_base;
2362 ops->dai_ptr = tx_macro_dai;
2363 ops->num_dais = ARRAY_SIZE(tx_macro_dai);
Laxminath Kasamfb0d6832018-09-22 01:49:52 +05302364 ops->event_handler = tx_macro_event_handler;
Aditya Bavanaric4e96122018-11-14 14:46:38 +05302365 ops->reg_wake_irq = tx_macro_reg_wake_irq;
Sudheer Papothia3e969d2018-10-27 06:22:10 +05302366 ops->set_port_map = tx_macro_set_port_map;
Sudheer Papothi6cc7f522019-06-28 11:04:03 +05302367 ops->clk_switch = tx_macro_clk_switch;
Sudheer Papothi06a4c642019-08-08 05:17:46 +05302368 ops->reg_evt_listener = tx_macro_register_event_listener;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302369}
2370
2371static int tx_macro_probe(struct platform_device *pdev)
2372{
2373 struct macro_ops ops = {0};
2374 struct tx_macro_priv *tx_priv = NULL;
2375 u32 tx_base_addr = 0, sample_rate = 0;
2376 char __iomem *tx_io_base = NULL;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302377 int ret = 0;
2378 const char *dmic_sample_rate = "qcom,tx-dmic-sample-rate";
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07002379 u32 is_used_tx_swr_gpio = 1;
2380 const char *is_used_tx_swr_gpio_dt = "qcom,is-used-swr-gpio";
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302381
2382 tx_priv = devm_kzalloc(&pdev->dev, sizeof(struct tx_macro_priv),
2383 GFP_KERNEL);
2384 if (!tx_priv)
2385 return -ENOMEM;
2386 platform_set_drvdata(pdev, tx_priv);
2387
2388 tx_priv->dev = &pdev->dev;
2389 ret = of_property_read_u32(pdev->dev.of_node, "reg",
2390 &tx_base_addr);
2391 if (ret) {
2392 dev_err(&pdev->dev, "%s: could not find %s entry in dt\n",
2393 __func__, "reg");
2394 return ret;
2395 }
2396 dev_set_drvdata(&pdev->dev, tx_priv);
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07002397 if (of_find_property(pdev->dev.of_node, is_used_tx_swr_gpio_dt,
2398 NULL)) {
2399 ret = of_property_read_u32(pdev->dev.of_node,
2400 is_used_tx_swr_gpio_dt,
2401 &is_used_tx_swr_gpio);
2402 if (ret) {
2403 dev_err(&pdev->dev, "%s: error reading %s in dt\n",
2404 __func__, is_used_tx_swr_gpio_dt);
2405 is_used_tx_swr_gpio = 1;
2406 }
2407 }
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302408 tx_priv->tx_swr_gpio_p = of_parse_phandle(pdev->dev.of_node,
2409 "qcom,tx-swr-gpios", 0);
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07002410 if (!tx_priv->tx_swr_gpio_p && is_used_tx_swr_gpio) {
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302411 dev_err(&pdev->dev, "%s: swr_gpios handle not provided!\n",
2412 __func__);
2413 return -EINVAL;
2414 }
Karthikeyan Manib44e4552019-09-09 23:06:04 -07002415 if (msm_cdc_pinctrl_get_state(tx_priv->tx_swr_gpio_p) < 0 &&
2416 is_used_tx_swr_gpio) {
Karthikeyan Mani326536d2019-06-03 13:29:43 -07002417 dev_err(&pdev->dev, "%s: failed to get swr pin state\n",
2418 __func__);
2419 return -EPROBE_DEFER;
2420 }
2421
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302422 tx_io_base = devm_ioremap(&pdev->dev,
2423 tx_base_addr, TX_MACRO_MAX_OFFSET);
2424 if (!tx_io_base) {
2425 dev_err(&pdev->dev, "%s: ioremap failed\n", __func__);
2426 return -ENOMEM;
2427 }
2428 tx_priv->tx_io_base = tx_io_base;
2429 ret = of_property_read_u32(pdev->dev.of_node, dmic_sample_rate,
2430 &sample_rate);
2431 if (ret) {
2432 dev_err(&pdev->dev,
2433 "%s: could not find sample_rate entry in dt\n",
2434 __func__);
2435 tx_priv->dmic_clk_div = TX_MACRO_CLK_DIV_2;
2436 } else {
2437 if (tx_macro_validate_dmic_sample_rate(
2438 sample_rate, tx_priv) == TX_MACRO_DMIC_SAMPLE_RATE_UNDEFINED)
2439 return -EINVAL;
2440 }
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05302441 tx_priv->reset_swr = true;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302442 INIT_WORK(&tx_priv->tx_macro_add_child_devices_work,
2443 tx_macro_add_child_devices);
2444 tx_priv->swr_plat_data.handle = (void *) tx_priv;
2445 tx_priv->swr_plat_data.read = NULL;
2446 tx_priv->swr_plat_data.write = NULL;
2447 tx_priv->swr_plat_data.bulk_write = NULL;
2448 tx_priv->swr_plat_data.clk = tx_macro_swrm_clock;
Karthikeyan Mani8d40a062019-09-05 16:44:49 -07002449 tx_priv->swr_plat_data.core_vote = tx_macro_core_vote;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302450 tx_priv->swr_plat_data.handle_irq = NULL;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302451
2452 mutex_init(&tx_priv->mclk_lock);
2453 mutex_init(&tx_priv->swr_clk_lock);
2454 tx_macro_init_ops(&ops, tx_io_base);
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07002455 ops.clk_id_req = TX_CORE_CLK;
2456 ops.default_clk_id = TX_CORE_CLK;
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302457 ret = bolero_register_macro(&pdev->dev, TX_MACRO, &ops);
2458 if (ret) {
2459 dev_err(&pdev->dev,
2460 "%s: register macro failed\n", __func__);
2461 goto err_reg_macro;
2462 }
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07002463
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302464 schedule_work(&tx_priv->tx_macro_add_child_devices_work);
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302465 pm_runtime_set_autosuspend_delay(&pdev->dev, AUTO_SUSPEND_DELAY);
2466 pm_runtime_use_autosuspend(&pdev->dev);
2467 pm_runtime_set_suspended(&pdev->dev);
Sudheer Papothi296867b2019-06-20 09:24:09 +05302468 pm_suspend_ignore_children(&pdev->dev, true);
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302469 pm_runtime_enable(&pdev->dev);
2470
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302471 return 0;
2472err_reg_macro:
2473 mutex_destroy(&tx_priv->mclk_lock);
2474 mutex_destroy(&tx_priv->swr_clk_lock);
2475 return ret;
2476}
2477
2478static int tx_macro_remove(struct platform_device *pdev)
2479{
2480 struct tx_macro_priv *tx_priv = NULL;
2481 u16 count = 0;
2482
2483 tx_priv = platform_get_drvdata(pdev);
2484
2485 if (!tx_priv)
2486 return -EINVAL;
2487
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07002488 if (tx_priv->swr_ctrl_data)
2489 kfree(tx_priv->swr_ctrl_data);
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302490 for (count = 0; count < tx_priv->child_count &&
2491 count < TX_MACRO_CHILD_DEVICES_MAX; count++)
2492 platform_device_unregister(tx_priv->pdev_child_devices[count]);
2493
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302494 pm_runtime_disable(&pdev->dev);
2495 pm_runtime_set_suspended(&pdev->dev);
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302496 mutex_destroy(&tx_priv->mclk_lock);
2497 mutex_destroy(&tx_priv->swr_clk_lock);
2498 bolero_unregister_macro(&pdev->dev, TX_MACRO);
2499 return 0;
2500}
2501
2502
2503static const struct of_device_id tx_macro_dt_match[] = {
2504 {.compatible = "qcom,tx-macro"},
2505 {}
2506};
2507
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302508static const struct dev_pm_ops bolero_dev_pm_ops = {
2509 SET_RUNTIME_PM_OPS(
2510 bolero_runtime_suspend,
2511 bolero_runtime_resume,
2512 NULL
2513 )
2514};
2515
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302516static struct platform_driver tx_macro_driver = {
2517 .driver = {
2518 .name = "tx_macro",
2519 .owner = THIS_MODULE,
Sudheer Papothi7601cc62019-03-30 03:00:52 +05302520 .pm = &bolero_dev_pm_ops,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302521 .of_match_table = tx_macro_dt_match,
Xiaojun Sang53cd13a2018-06-29 15:14:37 +08002522 .suppress_bind_attrs = true,
Laxminath Kasam989fccf2018-06-15 16:53:31 +05302523 },
2524 .probe = tx_macro_probe,
2525 .remove = tx_macro_remove,
2526};
2527
2528module_platform_driver(tx_macro_driver);
2529
2530MODULE_DESCRIPTION("TX macro driver");
2531MODULE_LICENSE("GPL v2");