blob: b6e0ec6c05b3a887eb2914d463bdcb6c4c7ac106 [file] [log] [blame]
Laxminath Kasame68e94f2016-12-09 12:08:00 +05301/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/module.h>
14#include <linux/init.h>
15#include <linux/io.h>
16#include <linux/platform_device.h>
17#include <linux/printk.h>
18#include <linux/debugfs.h>
19#include <linux/delay.h>
20#include <linux/qdsp6v2/apr.h>
21#include <linux/workqueue.h>
22#include <linux/regmap.h>
23#include <sound/q6afe-v2.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/tlv.h>
Neeraj Upadhyay49934422016-12-27 19:03:35 +053029#include "sdm660-cdc-registers.h"
Laxminath Kasame68e94f2016-12-09 12:08:00 +053030#include "msm-digital-cdc.h"
31#include "msm-cdc-common.h"
Neeraj Upadhyay49934422016-12-27 19:03:35 +053032#include "../../msm/sdm660-common.h"
Laxminath Kasame68e94f2016-12-09 12:08:00 +053033
34#define DRV_NAME "msm_digital_codec"
35#define MCLK_RATE_9P6MHZ 9600000
36#define MCLK_RATE_12P288MHZ 12288000
37#define TX_MUX_CTL_CUT_OFF_FREQ_MASK 0x30
38#define CF_MIN_3DB_4HZ 0x0
39#define CF_MIN_3DB_75HZ 0x1
40#define CF_MIN_3DB_150HZ 0x2
41
42#define MSM_DIG_CDC_VERSION_ENTRY_SIZE 32
43
44static unsigned long rx_digital_gain_reg[] = {
45 MSM89XX_CDC_CORE_RX1_VOL_CTL_B2_CTL,
46 MSM89XX_CDC_CORE_RX2_VOL_CTL_B2_CTL,
47 MSM89XX_CDC_CORE_RX3_VOL_CTL_B2_CTL,
48};
49
50static unsigned long tx_digital_gain_reg[] = {
51 MSM89XX_CDC_CORE_TX1_VOL_CTL_GAIN,
52 MSM89XX_CDC_CORE_TX2_VOL_CTL_GAIN,
Laxminath Kasama5cc5332017-02-04 01:36:04 +053053 MSM89XX_CDC_CORE_TX3_VOL_CTL_GAIN,
54 MSM89XX_CDC_CORE_TX4_VOL_CTL_GAIN,
55 MSM89XX_CDC_CORE_TX5_VOL_CTL_GAIN,
Laxminath Kasame68e94f2016-12-09 12:08:00 +053056};
57
58static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0);
59
60struct snd_soc_codec *registered_digcodec;
61struct hpf_work tx_hpf_work[NUM_DECIMATORS];
62
63/* Codec supports 2 IIR filters */
64enum {
65 IIR1 = 0,
66 IIR2,
67 IIR_MAX,
68};
69
70static int msm_digcdc_clock_control(bool flag)
71{
72 int ret = -EINVAL;
73 struct msm_asoc_mach_data *pdata = NULL;
74
75 pdata = snd_soc_card_get_drvdata(registered_digcodec->component.card);
76
Laxminath Kasam716a45b2017-02-13 19:36:27 +053077 mutex_lock(&pdata->cdc_int_mclk0_mutex);
Laxminath Kasame68e94f2016-12-09 12:08:00 +053078 if (flag) {
79 if (atomic_read(&pdata->int_mclk0_enabled) == false) {
80 pdata->digital_cdc_core_clk.enable = 1;
81 ret = afe_set_lpass_clock_v2(
Divya Ojhaa2d24382017-03-07 11:16:45 +053082 AFE_PORT_ID_INT0_MI2S_RX,
Laxminath Kasame68e94f2016-12-09 12:08:00 +053083 &pdata->digital_cdc_core_clk);
84 if (ret < 0) {
85 pr_err("%s:failed to enable the MCLK\n",
86 __func__);
Laxminath Kasam716a45b2017-02-13 19:36:27 +053087 mutex_unlock(&pdata->cdc_int_mclk0_mutex);
Laxminath Kasame68e94f2016-12-09 12:08:00 +053088 return ret;
89 }
90 pr_debug("enabled digital codec core clk\n");
91 atomic_set(&pdata->int_mclk0_enabled, true);
92 schedule_delayed_work(&pdata->disable_int_mclk0_work,
93 50);
94 }
95 } else {
96 dev_dbg(registered_digcodec->dev,
97 "disable MCLK, workq to disable set already\n");
98 }
Laxminath Kasam716a45b2017-02-13 19:36:27 +053099 mutex_unlock(&pdata->cdc_int_mclk0_mutex);
Laxminath Kasame68e94f2016-12-09 12:08:00 +0530100 return 0;
101}
102
103static void enable_digital_callback(void *flag)
104{
105 msm_digcdc_clock_control(true);
106}
107
108static void disable_digital_callback(void *flag)
109{
110 pr_debug("disable mclk happens in workq\n");
111}
112
113static int msm_dig_cdc_put_dec_enum(struct snd_kcontrol *kcontrol,
114 struct snd_ctl_elem_value *ucontrol)
115{
116 struct snd_soc_dapm_widget_list *wlist =
117 dapm_kcontrol_get_wlist(kcontrol);
118 struct snd_soc_dapm_widget *w = wlist->widgets[0];
119 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
120 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
121 unsigned int dec_mux, decimator;
122 char *dec_name = NULL;
123 char *widget_name = NULL;
124 char *temp;
125 u16 tx_mux_ctl_reg;
126 u8 adc_dmic_sel = 0x0;
127 int ret = 0;
128 char *dec_num;
129
130 if (ucontrol->value.enumerated.item[0] > e->items) {
131 dev_err(codec->dev, "%s: Invalid enum value: %d\n",
132 __func__, ucontrol->value.enumerated.item[0]);
133 return -EINVAL;
134 }
135 dec_mux = ucontrol->value.enumerated.item[0];
136
137 widget_name = kstrndup(w->name, 15, GFP_KERNEL);
138 if (!widget_name) {
139 dev_err(codec->dev, "%s: failed to copy string\n",
140 __func__);
141 return -ENOMEM;
142 }
143 temp = widget_name;
144
145 dec_name = strsep(&widget_name, " ");
146 widget_name = temp;
147 if (!dec_name) {
148 dev_err(codec->dev, "%s: Invalid decimator = %s\n",
149 __func__, w->name);
150 ret = -EINVAL;
151 goto out;
152 }
153
154 dec_num = strpbrk(dec_name, "12345");
155 if (dec_num == NULL) {
156 dev_err(codec->dev, "%s: Invalid DEC selected\n", __func__);
157 ret = -EINVAL;
158 goto out;
159 }
160
161 ret = kstrtouint(dec_num, 10, &decimator);
162 if (ret < 0) {
163 dev_err(codec->dev, "%s: Invalid decimator = %s\n",
164 __func__, dec_name);
165 ret = -EINVAL;
166 goto out;
167 }
168
169 dev_dbg(w->dapm->dev, "%s(): widget = %s decimator = %u dec_mux = %u\n"
170 , __func__, w->name, decimator, dec_mux);
171
172 switch (decimator) {
173 case 1:
174 case 2:
175 case 3:
176 case 4:
177 case 5:
178 if ((dec_mux == 4) || (dec_mux == 5) ||
179 (dec_mux == 6) || (dec_mux == 7))
180 adc_dmic_sel = 0x1;
181 else
182 adc_dmic_sel = 0x0;
183 break;
184 default:
185 dev_err(codec->dev, "%s: Invalid Decimator = %u\n",
186 __func__, decimator);
187 ret = -EINVAL;
188 goto out;
189 }
190
191 tx_mux_ctl_reg =
192 MSM89XX_CDC_CORE_TX1_MUX_CTL + 32 * (decimator - 1);
193
194 snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x1, adc_dmic_sel);
195
196 ret = snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
197
198out:
199 kfree(widget_name);
200 return ret;
201}
202
203
204static int msm_dig_cdc_codec_config_compander(struct snd_soc_codec *codec,
205 int interp_n, int event)
206{
207 struct msm_dig_priv *dig_cdc = snd_soc_codec_get_drvdata(codec);
208
209 dev_dbg(codec->dev, "%s: event %d shift %d, enabled %d\n",
210 __func__, event, interp_n,
211 dig_cdc->comp_enabled[interp_n]);
212
213 /* compander is not enabled */
214 if (!dig_cdc->comp_enabled[interp_n])
215 return 0;
216
217 switch (dig_cdc->comp_enabled[interp_n]) {
218 case COMPANDER_1:
219 if (SND_SOC_DAPM_EVENT_ON(event)) {
220 /* Enable Compander Clock */
221 snd_soc_update_bits(codec,
222 MSM89XX_CDC_CORE_COMP0_B2_CTL, 0x0F, 0x09);
223 snd_soc_update_bits(codec,
224 MSM89XX_CDC_CORE_CLK_RX_B2_CTL, 0x01, 0x01);
225 snd_soc_update_bits(codec,
226 MSM89XX_CDC_CORE_COMP0_B1_CTL,
227 1 << interp_n, 1 << interp_n);
228 snd_soc_update_bits(codec,
229 MSM89XX_CDC_CORE_COMP0_B3_CTL, 0xFF, 0x01);
230 snd_soc_update_bits(codec,
231 MSM89XX_CDC_CORE_COMP0_B2_CTL, 0xF0, 0x50);
232 /* add sleep for compander to settle */
233 usleep_range(1000, 1100);
234 snd_soc_update_bits(codec,
235 MSM89XX_CDC_CORE_COMP0_B3_CTL, 0xFF, 0x28);
236 snd_soc_update_bits(codec,
237 MSM89XX_CDC_CORE_COMP0_B2_CTL, 0xF0, 0xB0);
238
239 /* Enable Compander GPIO */
240 if (dig_cdc->codec_hph_comp_gpio)
Laxminath Kasamad0f6962016-12-14 20:00:35 +0530241 dig_cdc->codec_hph_comp_gpio(1, codec);
Laxminath Kasame68e94f2016-12-09 12:08:00 +0530242 } else if (SND_SOC_DAPM_EVENT_OFF(event)) {
243 /* Disable Compander GPIO */
244 if (dig_cdc->codec_hph_comp_gpio)
Laxminath Kasamad0f6962016-12-14 20:00:35 +0530245 dig_cdc->codec_hph_comp_gpio(0, codec);
Laxminath Kasame68e94f2016-12-09 12:08:00 +0530246
247 snd_soc_update_bits(codec,
248 MSM89XX_CDC_CORE_COMP0_B2_CTL, 0x0F, 0x05);
249 snd_soc_update_bits(codec,
250 MSM89XX_CDC_CORE_COMP0_B1_CTL,
251 1 << interp_n, 0);
252 snd_soc_update_bits(codec,
253 MSM89XX_CDC_CORE_CLK_RX_B2_CTL, 0x01, 0x00);
254 }
255 break;
256 default:
257 dev_dbg(codec->dev, "%s: Invalid compander %d\n", __func__,
258 dig_cdc->comp_enabled[interp_n]);
259 break;
260 };
261
262 return 0;
263}
264
265/**
266 * msm_dig_cdc_hph_comp_cb - registers callback to codec by machine driver.
267 *
268 * @codec_hph_comp_gpio: function pointer to set comp gpio at machine driver
269 * @codec: codec pointer
270 *
271 */
272void msm_dig_cdc_hph_comp_cb(
Laxminath Kasamad0f6962016-12-14 20:00:35 +0530273 int (*codec_hph_comp_gpio)(bool enable, struct snd_soc_codec *codec),
274 struct snd_soc_codec *codec)
Laxminath Kasame68e94f2016-12-09 12:08:00 +0530275{
276 struct msm_dig_priv *dig_cdc = snd_soc_codec_get_drvdata(codec);
277
278 pr_debug("%s: Enter\n", __func__);
279 dig_cdc->codec_hph_comp_gpio = codec_hph_comp_gpio;
280}
281EXPORT_SYMBOL(msm_dig_cdc_hph_comp_cb);
282
283static int msm_dig_cdc_codec_enable_interpolator(struct snd_soc_dapm_widget *w,
284 struct snd_kcontrol *kcontrol,
285 int event)
286{
287 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
Laxminath Kasame0582ba2017-03-04 16:58:20 +0530288 struct msm_dig_priv *msm_dig_cdc = snd_soc_codec_get_drvdata(codec);
Laxminath Kasame68e94f2016-12-09 12:08:00 +0530289
290 dev_dbg(codec->dev, "%s %d %s\n", __func__, event, w->name);
291
292 if (w->shift >= MSM89XX_RX_MAX || w->shift < 0) {
293 dev_err(codec->dev, "%s: wrong RX index: %d\n",
294 __func__, w->shift);
295 return -EINVAL;
296 }
297 switch (event) {
298 case SND_SOC_DAPM_POST_PMU:
299 msm_dig_cdc_codec_config_compander(codec, w->shift, event);
300 /* apply the digital gain after the interpolator is enabled*/
301 if ((w->shift) < ARRAY_SIZE(rx_digital_gain_reg))
302 snd_soc_write(codec,
303 rx_digital_gain_reg[w->shift],
304 snd_soc_read(codec,
305 rx_digital_gain_reg[w->shift])
306 );
307 break;
308 case SND_SOC_DAPM_POST_PMD:
309 msm_dig_cdc_codec_config_compander(codec, w->shift, event);
310 snd_soc_update_bits(codec,
311 MSM89XX_CDC_CORE_CLK_RX_RESET_CTL,
312 1 << w->shift, 1 << w->shift);
313 snd_soc_update_bits(codec,
314 MSM89XX_CDC_CORE_CLK_RX_RESET_CTL,
315 1 << w->shift, 0x0);
316 /*
317 * disable the mute enabled during the PMD of this device
318 */
319 if ((w->shift == 0) &&
320 (msm_dig_cdc->mute_mask & HPHL_PA_DISABLE)) {
321 pr_debug("disabling HPHL mute\n");
322 snd_soc_update_bits(codec,
323 MSM89XX_CDC_CORE_RX1_B6_CTL, 0x01, 0x00);
324 msm_dig_cdc->mute_mask &= ~(HPHL_PA_DISABLE);
325 } else if ((w->shift == 1) &&
326 (msm_dig_cdc->mute_mask & HPHR_PA_DISABLE)) {
327 pr_debug("disabling HPHR mute\n");
328 snd_soc_update_bits(codec,
329 MSM89XX_CDC_CORE_RX2_B6_CTL, 0x01, 0x00);
330 msm_dig_cdc->mute_mask &= ~(HPHR_PA_DISABLE);
331 } else if ((w->shift == 2) &&
332 (msm_dig_cdc->mute_mask & SPKR_PA_DISABLE)) {
333 pr_debug("disabling SPKR mute\n");
334 snd_soc_update_bits(codec,
335 MSM89XX_CDC_CORE_RX3_B6_CTL, 0x01, 0x00);
336 msm_dig_cdc->mute_mask &= ~(SPKR_PA_DISABLE);
337 }
338 }
339 return 0;
340}
341
Laxminath Kasame68e94f2016-12-09 12:08:00 +0530342static int msm_dig_cdc_get_iir_enable_audio_mixer(
343 struct snd_kcontrol *kcontrol,
344 struct snd_ctl_elem_value *ucontrol)
345{
346 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
347 int iir_idx = ((struct soc_multi_mixer_control *)
348 kcontrol->private_value)->reg;
349 int band_idx = ((struct soc_multi_mixer_control *)
350 kcontrol->private_value)->shift;
351
352 ucontrol->value.integer.value[0] =
353 (snd_soc_read(codec,
354 (MSM89XX_CDC_CORE_IIR1_CTL + 64 * iir_idx)) &
355 (1 << band_idx)) != 0;
356
357 dev_dbg(codec->dev, "%s: IIR #%d band #%d enable %d\n", __func__,
358 iir_idx, band_idx,
359 (uint32_t)ucontrol->value.integer.value[0]);
360 return 0;
361}
362
363static int msm_dig_cdc_put_iir_enable_audio_mixer(
364 struct snd_kcontrol *kcontrol,
365 struct snd_ctl_elem_value *ucontrol)
366{
367 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
368 int iir_idx = ((struct soc_multi_mixer_control *)
369 kcontrol->private_value)->reg;
370 int band_idx = ((struct soc_multi_mixer_control *)
371 kcontrol->private_value)->shift;
372 int value = ucontrol->value.integer.value[0];
373
374 /* Mask first 5 bits, 6-8 are reserved */
375 snd_soc_update_bits(codec,
376 (MSM89XX_CDC_CORE_IIR1_CTL + 64 * iir_idx),
377 (1 << band_idx), (value << band_idx));
378
379 dev_dbg(codec->dev, "%s: IIR #%d band #%d enable %d\n", __func__,
380 iir_idx, band_idx,
381 ((snd_soc_read(codec,
382 (MSM89XX_CDC_CORE_IIR1_CTL + 64 * iir_idx)) &
383 (1 << band_idx)) != 0));
384
385 return 0;
386}
387
388static uint32_t get_iir_band_coeff(struct snd_soc_codec *codec,
389 int iir_idx, int band_idx,
390 int coeff_idx)
391{
392 uint32_t value = 0;
393
394 /* Address does not automatically update if reading */
395 snd_soc_write(codec,
396 (MSM89XX_CDC_CORE_IIR1_COEF_B1_CTL + 64 * iir_idx),
397 ((band_idx * BAND_MAX + coeff_idx)
398 * sizeof(uint32_t)) & 0x7F);
399
400 value |= snd_soc_read(codec,
401 (MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL + 64 * iir_idx));
402
403 snd_soc_write(codec,
404 (MSM89XX_CDC_CORE_IIR1_COEF_B1_CTL + 64 * iir_idx),
405 ((band_idx * BAND_MAX + coeff_idx)
406 * sizeof(uint32_t) + 1) & 0x7F);
407
408 value |= (snd_soc_read(codec,
409 (MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL + 64 * iir_idx)) << 8);
410
411 snd_soc_write(codec,
412 (MSM89XX_CDC_CORE_IIR1_COEF_B1_CTL + 64 * iir_idx),
413 ((band_idx * BAND_MAX + coeff_idx)
414 * sizeof(uint32_t) + 2) & 0x7F);
415
416 value |= (snd_soc_read(codec,
417 (MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL + 64 * iir_idx)) << 16);
418
419 snd_soc_write(codec,
420 (MSM89XX_CDC_CORE_IIR1_COEF_B1_CTL + 64 * iir_idx),
421 ((band_idx * BAND_MAX + coeff_idx)
422 * sizeof(uint32_t) + 3) & 0x7F);
423
424 /* Mask bits top 2 bits since they are reserved */
425 value |= ((snd_soc_read(codec, (MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL
426 + 64 * iir_idx)) & 0x3f) << 24);
427
428 return value;
429
430}
431
432static void set_iir_band_coeff(struct snd_soc_codec *codec,
433 int iir_idx, int band_idx,
434 uint32_t value)
435{
436 snd_soc_write(codec,
437 (MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL + 64 * iir_idx),
438 (value & 0xFF));
439
440 snd_soc_write(codec,
441 (MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL + 64 * iir_idx),
442 (value >> 8) & 0xFF);
443
444 snd_soc_write(codec,
445 (MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL + 64 * iir_idx),
446 (value >> 16) & 0xFF);
447
448 /* Mask top 2 bits, 7-8 are reserved */
449 snd_soc_write(codec,
450 (MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL + 64 * iir_idx),
451 (value >> 24) & 0x3F);
452
453}
454
455static int msm_dig_cdc_get_iir_band_audio_mixer(
456 struct snd_kcontrol *kcontrol,
457 struct snd_ctl_elem_value *ucontrol)
458{
459 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
460 int iir_idx = ((struct soc_multi_mixer_control *)
461 kcontrol->private_value)->reg;
462 int band_idx = ((struct soc_multi_mixer_control *)
463 kcontrol->private_value)->shift;
464
465 ucontrol->value.integer.value[0] =
466 get_iir_band_coeff(codec, iir_idx, band_idx, 0);
467 ucontrol->value.integer.value[1] =
468 get_iir_band_coeff(codec, iir_idx, band_idx, 1);
469 ucontrol->value.integer.value[2] =
470 get_iir_band_coeff(codec, iir_idx, band_idx, 2);
471 ucontrol->value.integer.value[3] =
472 get_iir_band_coeff(codec, iir_idx, band_idx, 3);
473 ucontrol->value.integer.value[4] =
474 get_iir_band_coeff(codec, iir_idx, band_idx, 4);
475
476 dev_dbg(codec->dev, "%s: IIR #%d band #%d b0 = 0x%x\n"
477 "%s: IIR #%d band #%d b1 = 0x%x\n"
478 "%s: IIR #%d band #%d b2 = 0x%x\n"
479 "%s: IIR #%d band #%d a1 = 0x%x\n"
480 "%s: IIR #%d band #%d a2 = 0x%x\n",
481 __func__, iir_idx, band_idx,
482 (uint32_t)ucontrol->value.integer.value[0],
483 __func__, iir_idx, band_idx,
484 (uint32_t)ucontrol->value.integer.value[1],
485 __func__, iir_idx, band_idx,
486 (uint32_t)ucontrol->value.integer.value[2],
487 __func__, iir_idx, band_idx,
488 (uint32_t)ucontrol->value.integer.value[3],
489 __func__, iir_idx, band_idx,
490 (uint32_t)ucontrol->value.integer.value[4]);
491 return 0;
492}
493
494static int msm_dig_cdc_put_iir_band_audio_mixer(
495 struct snd_kcontrol *kcontrol,
496 struct snd_ctl_elem_value *ucontrol)
497{
498 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
499 int iir_idx = ((struct soc_multi_mixer_control *)
500 kcontrol->private_value)->reg;
501 int band_idx = ((struct soc_multi_mixer_control *)
502 kcontrol->private_value)->shift;
503
504 /* Mask top bit it is reserved */
505 /* Updates addr automatically for each B2 write */
506 snd_soc_write(codec,
507 (MSM89XX_CDC_CORE_IIR1_COEF_B1_CTL + 64 * iir_idx),
508 (band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F);
509
510
511 set_iir_band_coeff(codec, iir_idx, band_idx,
512 ucontrol->value.integer.value[0]);
513 set_iir_band_coeff(codec, iir_idx, band_idx,
514 ucontrol->value.integer.value[1]);
515 set_iir_band_coeff(codec, iir_idx, band_idx,
516 ucontrol->value.integer.value[2]);
517 set_iir_band_coeff(codec, iir_idx, band_idx,
518 ucontrol->value.integer.value[3]);
519 set_iir_band_coeff(codec, iir_idx, band_idx,
520 ucontrol->value.integer.value[4]);
521
522 dev_dbg(codec->dev, "%s: IIR #%d band #%d b0 = 0x%x\n"
523 "%s: IIR #%d band #%d b1 = 0x%x\n"
524 "%s: IIR #%d band #%d b2 = 0x%x\n"
525 "%s: IIR #%d band #%d a1 = 0x%x\n"
526 "%s: IIR #%d band #%d a2 = 0x%x\n",
527 __func__, iir_idx, band_idx,
528 get_iir_band_coeff(codec, iir_idx, band_idx, 0),
529 __func__, iir_idx, band_idx,
530 get_iir_band_coeff(codec, iir_idx, band_idx, 1),
531 __func__, iir_idx, band_idx,
532 get_iir_band_coeff(codec, iir_idx, band_idx, 2),
533 __func__, iir_idx, band_idx,
534 get_iir_band_coeff(codec, iir_idx, band_idx, 3),
535 __func__, iir_idx, band_idx,
536 get_iir_band_coeff(codec, iir_idx, band_idx, 4));
537 return 0;
538}
539
540static void tx_hpf_corner_freq_callback(struct work_struct *work)
541{
542 struct delayed_work *hpf_delayed_work;
543 struct hpf_work *hpf_work;
544 struct snd_soc_codec *codec;
Laxminath Kasame0582ba2017-03-04 16:58:20 +0530545 struct msm_dig_priv *msm_dig_cdc;
Laxminath Kasame68e94f2016-12-09 12:08:00 +0530546 u16 tx_mux_ctl_reg;
547 u8 hpf_cut_of_freq;
548
549 hpf_delayed_work = to_delayed_work(work);
550 hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork);
551 codec = hpf_work->dig_cdc->codec;
Laxminath Kasame0582ba2017-03-04 16:58:20 +0530552 msm_dig_cdc = hpf_work->dig_cdc;
Laxminath Kasame68e94f2016-12-09 12:08:00 +0530553 hpf_cut_of_freq = hpf_work->tx_hpf_cut_of_freq;
554
555 tx_mux_ctl_reg = MSM89XX_CDC_CORE_TX1_MUX_CTL +
556 (hpf_work->decimator - 1) * 32;
557
558 dev_dbg(codec->dev, "%s(): decimator %u hpf_cut_of_freq 0x%x\n",
559 __func__, hpf_work->decimator, (unsigned int)hpf_cut_of_freq);
560 msm_dig_cdc->update_clkdiv(msm_dig_cdc->handle, 0x51);
561
562 snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x30, hpf_cut_of_freq << 4);
563}
564
565static int msm_dig_cdc_codec_set_iir_gain(struct snd_soc_dapm_widget *w,
566 struct snd_kcontrol *kcontrol, int event)
567{
568 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
569 int value = 0, reg;
570
571 switch (event) {
572 case SND_SOC_DAPM_POST_PMU:
573 if (w->shift == 0)
574 reg = MSM89XX_CDC_CORE_IIR1_GAIN_B1_CTL;
575 else if (w->shift == 1)
576 reg = MSM89XX_CDC_CORE_IIR2_GAIN_B1_CTL;
577 else
578 goto ret;
579 value = snd_soc_read(codec, reg);
580 snd_soc_write(codec, reg, value);
581 break;
582 default:
583 pr_err("%s: event = %d not expected\n", __func__, event);
584 }
585ret:
586 return 0;
587}
588
589static int msm_dig_cdc_compander_get(struct snd_kcontrol *kcontrol,
590 struct snd_ctl_elem_value *ucontrol)
591{
592 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
593 struct msm_dig_priv *dig_cdc = snd_soc_codec_get_drvdata(codec);
594 int comp_idx = ((struct soc_multi_mixer_control *)
595 kcontrol->private_value)->reg;
596 int rx_idx = ((struct soc_multi_mixer_control *)
597 kcontrol->private_value)->shift;
598
599 dev_dbg(codec->dev, "%s: msm_dig_cdc->comp[%d]_enabled[%d] = %d\n",
600 __func__, comp_idx, rx_idx,
601 dig_cdc->comp_enabled[rx_idx]);
602
603 ucontrol->value.integer.value[0] = dig_cdc->comp_enabled[rx_idx];
604
605 dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
606 __func__, ucontrol->value.integer.value[0]);
607
608 return 0;
609}
610
611static int msm_dig_cdc_compander_set(struct snd_kcontrol *kcontrol,
612 struct snd_ctl_elem_value *ucontrol)
613{
614 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
615 struct msm_dig_priv *dig_cdc = snd_soc_codec_get_drvdata(codec);
616 int comp_idx = ((struct soc_multi_mixer_control *)
617 kcontrol->private_value)->reg;
618 int rx_idx = ((struct soc_multi_mixer_control *)
619 kcontrol->private_value)->shift;
620 int value = ucontrol->value.integer.value[0];
621
622 dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
623 __func__, ucontrol->value.integer.value[0]);
624
625 if (dig_cdc->version >= DIANGU) {
626 if (!value)
627 dig_cdc->comp_enabled[rx_idx] = 0;
628 else
629 dig_cdc->comp_enabled[rx_idx] = comp_idx;
630 }
631
632 dev_dbg(codec->dev, "%s: msm_dig_cdc->comp[%d]_enabled[%d] = %d\n",
633 __func__, comp_idx, rx_idx,
634 dig_cdc->comp_enabled[rx_idx]);
635
636 return 0;
637}
638
639static const struct snd_kcontrol_new compander_kcontrols[] = {
640 SOC_SINGLE_EXT("COMP0 RX1", COMPANDER_1, MSM89XX_RX1, 1, 0,
641 msm_dig_cdc_compander_get, msm_dig_cdc_compander_set),
642
643 SOC_SINGLE_EXT("COMP0 RX2", COMPANDER_1, MSM89XX_RX2, 1, 0,
644 msm_dig_cdc_compander_get, msm_dig_cdc_compander_set),
645
646};
647
648static int msm_dig_cdc_set_interpolator_rate(struct snd_soc_dai *dai,
649 u8 rx_fs_rate_reg_val,
650 u32 sample_rate)
651{
652 snd_soc_update_bits(dai->codec,
653 MSM89XX_CDC_CORE_RX1_B5_CTL, 0xF0, rx_fs_rate_reg_val);
654 snd_soc_update_bits(dai->codec,
655 MSM89XX_CDC_CORE_RX2_B5_CTL, 0xF0, rx_fs_rate_reg_val);
656 return 0;
657}
658
659static int msm_dig_cdc_hw_params(struct snd_pcm_substream *substream,
660 struct snd_pcm_hw_params *params,
661 struct snd_soc_dai *dai)
662{
663 u8 tx_fs_rate, rx_fs_rate, rx_clk_fs_rate;
664 int ret;
665
666 dev_dbg(dai->codec->dev,
667 "%s: dai_name = %s DAI-ID %x rate %d num_ch %d format %d\n",
668 __func__, dai->name, dai->id, params_rate(params),
669 params_channels(params), params_format(params));
670
671 switch (params_rate(params)) {
672 case 8000:
673 tx_fs_rate = 0x00;
674 rx_fs_rate = 0x00;
675 rx_clk_fs_rate = 0x00;
676 break;
677 case 16000:
678 tx_fs_rate = 0x20;
679 rx_fs_rate = 0x20;
680 rx_clk_fs_rate = 0x01;
681 break;
682 case 32000:
683 tx_fs_rate = 0x40;
684 rx_fs_rate = 0x40;
685 rx_clk_fs_rate = 0x02;
686 break;
687 case 44100:
688 case 48000:
689 tx_fs_rate = 0x60;
690 rx_fs_rate = 0x60;
691 rx_clk_fs_rate = 0x03;
692 break;
693 case 96000:
694 tx_fs_rate = 0x80;
695 rx_fs_rate = 0x80;
696 rx_clk_fs_rate = 0x04;
697 break;
698 case 192000:
699 tx_fs_rate = 0xA0;
700 rx_fs_rate = 0xA0;
701 rx_clk_fs_rate = 0x05;
702 break;
703 default:
704 dev_err(dai->codec->dev,
705 "%s: Invalid sampling rate %d\n", __func__,
706 params_rate(params));
707 return -EINVAL;
708 }
709
710 snd_soc_update_bits(dai->codec,
711 MSM89XX_CDC_CORE_CLK_RX_I2S_CTL, 0x0F, rx_clk_fs_rate);
712
713 switch (substream->stream) {
714 case SNDRV_PCM_STREAM_CAPTURE:
715 break;
716 case SNDRV_PCM_STREAM_PLAYBACK:
717 ret = msm_dig_cdc_set_interpolator_rate(dai, rx_fs_rate,
718 params_rate(params));
719 if (ret < 0) {
720 dev_err(dai->codec->dev,
721 "%s: set decimator rate failed %d\n", __func__,
722 ret);
723 return ret;
724 }
725 break;
726 default:
727 dev_err(dai->codec->dev,
728 "%s: Invalid stream type %d\n", __func__,
729 substream->stream);
730 return -EINVAL;
731 }
732 switch (params_format(params)) {
733 case SNDRV_PCM_FORMAT_S16_LE:
734 snd_soc_update_bits(dai->codec,
735 MSM89XX_CDC_CORE_CLK_RX_I2S_CTL, 0x20, 0x20);
736 break;
737 case SNDRV_PCM_FORMAT_S24_LE:
Laxminath Kasama5cc5332017-02-04 01:36:04 +0530738 case SNDRV_PCM_FORMAT_S24_3LE:
Laxminath Kasame68e94f2016-12-09 12:08:00 +0530739 snd_soc_update_bits(dai->codec,
740 MSM89XX_CDC_CORE_CLK_RX_I2S_CTL, 0x20, 0x00);
741 break;
742 default:
743 dev_err(dai->codec->dev, "%s: wrong format selected\n",
744 __func__);
745 return -EINVAL;
746 }
747 return 0;
748}
749
750static int msm_dig_cdc_codec_enable_dmic(struct snd_soc_dapm_widget *w,
751 struct snd_kcontrol *kcontrol,
752 int event)
753{
754 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
755 struct msm_dig_priv *dig_cdc = snd_soc_codec_get_drvdata(codec);
756 u8 dmic_clk_en;
757 u16 dmic_clk_reg;
758 s32 *dmic_clk_cnt;
759 unsigned int dmic;
760 int ret;
761 char *dmic_num = strpbrk(w->name, "1234");
762
763 if (dmic_num == NULL) {
764 dev_err(codec->dev, "%s: Invalid DMIC\n", __func__);
765 return -EINVAL;
766 }
767
768 ret = kstrtouint(dmic_num, 10, &dmic);
769 if (ret < 0) {
770 dev_err(codec->dev,
771 "%s: Invalid DMIC line on the codec\n", __func__);
772 return -EINVAL;
773 }
774
775 switch (dmic) {
776 case 1:
777 case 2:
778 dmic_clk_en = 0x01;
779 dmic_clk_cnt = &(dig_cdc->dmic_1_2_clk_cnt);
780 dmic_clk_reg = MSM89XX_CDC_CORE_CLK_DMIC_B1_CTL;
781 dev_dbg(codec->dev,
782 "%s() event %d DMIC%d dmic_1_2_clk_cnt %d\n",
783 __func__, event, dmic, *dmic_clk_cnt);
784 break;
785 case 3:
786 case 4:
787 dmic_clk_en = 0x01;
788 dmic_clk_cnt = &(dig_cdc->dmic_3_4_clk_cnt);
789 dmic_clk_reg = MSM89XX_CDC_CORE_CLK_DMIC_B2_CTL;
790 dev_dbg(codec->dev,
791 "%s() event %d DMIC%d dmic_3_4_clk_cnt %d\n",
792 __func__, event, dmic, *dmic_clk_cnt);
793 break;
794 default:
795 dev_err(codec->dev, "%s: Invalid DMIC Selection\n", __func__);
796 return -EINVAL;
797 }
798
799 switch (event) {
800 case SND_SOC_DAPM_PRE_PMU:
801 (*dmic_clk_cnt)++;
802 if (*dmic_clk_cnt == 1) {
803 snd_soc_update_bits(codec, dmic_clk_reg,
Laxminath Kasam24f049a2017-01-24 18:05:32 +0530804 0x0E, 0x04);
Laxminath Kasame68e94f2016-12-09 12:08:00 +0530805 snd_soc_update_bits(codec, dmic_clk_reg,
806 dmic_clk_en, dmic_clk_en);
807 }
808 snd_soc_update_bits(codec,
Laxminath Kasama5cc5332017-02-04 01:36:04 +0530809 MSM89XX_CDC_CORE_TX1_DMIC_CTL + (dmic - 1) * 0x20,
810 0x07, 0x02);
Laxminath Kasame68e94f2016-12-09 12:08:00 +0530811 break;
812 case SND_SOC_DAPM_POST_PMD:
813 (*dmic_clk_cnt)--;
814 if (*dmic_clk_cnt == 0)
815 snd_soc_update_bits(codec, dmic_clk_reg,
816 dmic_clk_en, 0);
817 break;
818 }
819 return 0;
820}
821
822static int msm_dig_cdc_codec_enable_dec(struct snd_soc_dapm_widget *w,
823 struct snd_kcontrol *kcontrol,
824 int event)
825{
826 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
827 struct msm_asoc_mach_data *pdata = NULL;
828 unsigned int decimator;
Laxminath Kasame0582ba2017-03-04 16:58:20 +0530829 struct msm_dig_priv *msm_dig_cdc = snd_soc_codec_get_drvdata(codec);
Laxminath Kasame68e94f2016-12-09 12:08:00 +0530830 char *dec_name = NULL;
831 char *widget_name = NULL;
832 char *temp;
833 int ret = 0, i;
834 u16 dec_reset_reg, tx_vol_ctl_reg, tx_mux_ctl_reg;
835 u8 dec_hpf_cut_of_freq;
836 int offset;
837 char *dec_num;
838
839 pdata = snd_soc_card_get_drvdata(codec->component.card);
840 dev_dbg(codec->dev, "%s %d\n", __func__, event);
841
842 widget_name = kstrndup(w->name, 15, GFP_KERNEL);
843 if (!widget_name)
844 return -ENOMEM;
845 temp = widget_name;
846
847 dec_name = strsep(&widget_name, " ");
848 widget_name = temp;
849 if (!dec_name) {
850 dev_err(codec->dev,
851 "%s: Invalid decimator = %s\n", __func__, w->name);
852 ret = -EINVAL;
853 goto out;
854 }
855
856 dec_num = strpbrk(dec_name, "12345");
857 if (dec_num == NULL) {
858 dev_err(codec->dev, "%s: Invalid Decimator\n", __func__);
859 ret = -EINVAL;
860 goto out;
861 }
862
863 ret = kstrtouint(dec_num, 10, &decimator);
864 if (ret < 0) {
865 dev_err(codec->dev,
866 "%s: Invalid decimator = %s\n", __func__, dec_name);
867 ret = -EINVAL;
868 goto out;
869 }
870
871 dev_dbg(codec->dev,
872 "%s(): widget = %s dec_name = %s decimator = %u\n", __func__,
873 w->name, dec_name, decimator);
874
875 if (w->reg == MSM89XX_CDC_CORE_CLK_TX_CLK_EN_B1_CTL) {
876 dec_reset_reg = MSM89XX_CDC_CORE_CLK_TX_RESET_B1_CTL;
877 offset = 0;
878 } else {
879 dev_err(codec->dev, "%s: Error, incorrect dec\n", __func__);
880 ret = -EINVAL;
881 goto out;
882 }
883
884 tx_vol_ctl_reg = MSM89XX_CDC_CORE_TX1_VOL_CTL_CFG +
885 32 * (decimator - 1);
886 tx_mux_ctl_reg = MSM89XX_CDC_CORE_TX1_MUX_CTL +
887 32 * (decimator - 1);
Laxminath Kasama5cc5332017-02-04 01:36:04 +0530888 if (decimator == 5) {
889 tx_vol_ctl_reg = MSM89XX_CDC_CORE_TX5_VOL_CTL_CFG;
890 tx_mux_ctl_reg = MSM89XX_CDC_CORE_TX5_MUX_CTL;
891 }
Laxminath Kasame68e94f2016-12-09 12:08:00 +0530892
893 switch (event) {
894 case SND_SOC_DAPM_PRE_PMU:
895 /* Enableable TX digital mute */
896 snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x01);
897 for (i = 0; i < NUM_DECIMATORS; i++) {
898 if (decimator == i + 1)
Laxminath Kasame0582ba2017-03-04 16:58:20 +0530899 msm_dig_cdc->dec_active[i] = true;
Laxminath Kasame68e94f2016-12-09 12:08:00 +0530900 }
901
902 dec_hpf_cut_of_freq = snd_soc_read(codec, tx_mux_ctl_reg);
903
904 dec_hpf_cut_of_freq = (dec_hpf_cut_of_freq & 0x30) >> 4;
905
906 tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq =
907 dec_hpf_cut_of_freq;
908
909 if (dec_hpf_cut_of_freq != CF_MIN_3DB_150HZ) {
910
911 /* set cut of freq to CF_MIN_3DB_150HZ (0x1); */
912 snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x30,
913 CF_MIN_3DB_150HZ << 4);
914 }
915 msm_dig_cdc->update_clkdiv(msm_dig_cdc->handle, 0x42);
916 break;
917 case SND_SOC_DAPM_POST_PMU:
918 /* enable HPF */
919 snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x08, 0x00);
920
921 if (tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq !=
922 CF_MIN_3DB_150HZ) {
923
924 schedule_delayed_work(&tx_hpf_work[decimator - 1].dwork,
925 msecs_to_jiffies(300));
926 }
927 /* apply the digital gain after the decimator is enabled*/
928 if ((w->shift) < ARRAY_SIZE(tx_digital_gain_reg))
929 snd_soc_write(codec,
930 tx_digital_gain_reg[w->shift + offset],
931 snd_soc_read(codec,
932 tx_digital_gain_reg[w->shift + offset])
933 );
934 if (pdata->lb_mode) {
935 pr_debug("%s: loopback mode unmute the DEC\n",
936 __func__);
937 snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x00);
938 }
939 snd_soc_update_bits(codec, tx_vol_ctl_reg,
940 0x01, 0x00);
941
942 break;
943 case SND_SOC_DAPM_PRE_PMD:
944 snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x01);
945 msleep(20);
946 snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x08, 0x08);
947 cancel_delayed_work_sync(&tx_hpf_work[decimator - 1].dwork);
948 break;
949 case SND_SOC_DAPM_POST_PMD:
950 snd_soc_update_bits(codec, dec_reset_reg, 1 << w->shift,
951 1 << w->shift);
952 snd_soc_update_bits(codec, dec_reset_reg, 1 << w->shift, 0x0);
953 snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x08, 0x08);
954 snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x30,
955 (tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq) << 4);
956 snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x00);
957 for (i = 0; i < NUM_DECIMATORS; i++) {
958 if (decimator == i + 1)
Laxminath Kasame0582ba2017-03-04 16:58:20 +0530959 msm_dig_cdc->dec_active[i] = false;
Laxminath Kasame68e94f2016-12-09 12:08:00 +0530960 }
961 break;
962 }
963out:
964 kfree(widget_name);
965 return ret;
966}
967
968static int msm_dig_cdc_event_notify(struct notifier_block *block,
969 unsigned long val,
970 void *data)
971{
972 enum dig_cdc_notify_event event = (enum dig_cdc_notify_event)val;
973 struct snd_soc_codec *codec = registered_digcodec;
Laxminath Kasame0582ba2017-03-04 16:58:20 +0530974 struct msm_dig_priv *msm_dig_cdc = snd_soc_codec_get_drvdata(codec);
Laxminath Kasame68e94f2016-12-09 12:08:00 +0530975 struct msm_asoc_mach_data *pdata = NULL;
976
977 pdata = snd_soc_card_get_drvdata(codec->component.card);
978
979 switch (event) {
980 case DIG_CDC_EVENT_CLK_ON:
981 snd_soc_update_bits(codec,
982 MSM89XX_CDC_CORE_CLK_PDM_CTL, 0x03, 0x03);
983 if (pdata->mclk_freq == MCLK_RATE_12P288MHZ ||
984 pdata->native_clk_set)
985 snd_soc_update_bits(codec,
986 MSM89XX_CDC_CORE_TOP_CTL, 0x01, 0x00);
987 else if (pdata->mclk_freq == MCLK_RATE_9P6MHZ)
988 snd_soc_update_bits(codec,
989 MSM89XX_CDC_CORE_TOP_CTL, 0x01, 0x01);
990 snd_soc_update_bits(codec,
991 MSM89XX_CDC_CORE_CLK_MCLK_CTL, 0x01, 0x01);
992 break;
993 case DIG_CDC_EVENT_CLK_OFF:
994 snd_soc_update_bits(codec,
995 MSM89XX_CDC_CORE_CLK_PDM_CTL, 0x03, 0x00);
996 snd_soc_update_bits(codec,
997 MSM89XX_CDC_CORE_CLK_MCLK_CTL, 0x01, 0x00);
998 break;
999 case DIG_CDC_EVENT_RX1_MUTE_ON:
1000 snd_soc_update_bits(codec,
1001 MSM89XX_CDC_CORE_RX1_B6_CTL, 0x01, 0x01);
1002 msm_dig_cdc->mute_mask |= HPHL_PA_DISABLE;
1003 break;
1004 case DIG_CDC_EVENT_RX1_MUTE_OFF:
1005 snd_soc_update_bits(codec,
1006 MSM89XX_CDC_CORE_RX1_B6_CTL, 0x01, 0x00);
1007 msm_dig_cdc->mute_mask &= (~HPHL_PA_DISABLE);
1008 break;
1009 case DIG_CDC_EVENT_RX2_MUTE_ON:
1010 snd_soc_update_bits(codec,
1011 MSM89XX_CDC_CORE_RX2_B6_CTL, 0x01, 0x01);
1012 msm_dig_cdc->mute_mask |= HPHR_PA_DISABLE;
1013 break;
1014 case DIG_CDC_EVENT_RX2_MUTE_OFF:
1015 snd_soc_update_bits(codec,
1016 MSM89XX_CDC_CORE_RX2_B6_CTL, 0x01, 0x00);
1017 msm_dig_cdc->mute_mask &= (~HPHR_PA_DISABLE);
1018 break;
1019 case DIG_CDC_EVENT_RX3_MUTE_ON:
1020 snd_soc_update_bits(codec,
1021 MSM89XX_CDC_CORE_RX3_B6_CTL, 0x01, 0x01);
1022 msm_dig_cdc->mute_mask |= SPKR_PA_DISABLE;
1023 break;
1024 case DIG_CDC_EVENT_RX3_MUTE_OFF:
1025 snd_soc_update_bits(codec,
1026 MSM89XX_CDC_CORE_RX3_B6_CTL, 0x01, 0x00);
1027 msm_dig_cdc->mute_mask &= (~SPKR_PA_DISABLE);
1028 break;
1029 case DIG_CDC_EVENT_PRE_RX1_INT_ON:
1030 snd_soc_update_bits(codec,
1031 MSM89XX_CDC_CORE_RX1_B3_CTL, 0x1C, 0x14);
1032 snd_soc_update_bits(codec,
1033 MSM89XX_CDC_CORE_RX1_B4_CTL, 0x18, 0x10);
1034 snd_soc_update_bits(codec,
1035 MSM89XX_CDC_CORE_RX1_B3_CTL, 0x80, 0x80);
1036 break;
1037 case DIG_CDC_EVENT_PRE_RX2_INT_ON:
1038 snd_soc_update_bits(codec,
1039 MSM89XX_CDC_CORE_RX2_B3_CTL, 0x1C, 0x14);
1040 snd_soc_update_bits(codec,
1041 MSM89XX_CDC_CORE_RX2_B4_CTL, 0x18, 0x10);
1042 snd_soc_update_bits(codec,
1043 MSM89XX_CDC_CORE_RX2_B3_CTL, 0x80, 0x80);
1044 break;
1045 case DIG_CDC_EVENT_POST_RX1_INT_OFF:
1046 snd_soc_update_bits(codec,
1047 MSM89XX_CDC_CORE_RX1_B3_CTL, 0x1C, 0x00);
1048 snd_soc_update_bits(codec,
1049 MSM89XX_CDC_CORE_RX1_B4_CTL, 0x18, 0xFF);
1050 snd_soc_update_bits(codec,
1051 MSM89XX_CDC_CORE_RX1_B3_CTL, 0x80, 0x00);
1052 break;
1053 case DIG_CDC_EVENT_POST_RX2_INT_OFF:
1054 snd_soc_update_bits(codec,
1055 MSM89XX_CDC_CORE_RX2_B3_CTL, 0x1C, 0x00);
1056 snd_soc_update_bits(codec,
1057 MSM89XX_CDC_CORE_RX2_B4_CTL, 0x18, 0xFF);
1058 snd_soc_update_bits(codec,
1059 MSM89XX_CDC_CORE_RX2_B3_CTL, 0x80, 0x00);
1060 break;
1061 case DIG_CDC_EVENT_SSR_DOWN:
1062 regcache_cache_only(msm_dig_cdc->regmap, true);
1063 break;
1064 case DIG_CDC_EVENT_SSR_UP:
1065 regcache_cache_only(msm_dig_cdc->regmap, false);
1066 regcache_mark_dirty(msm_dig_cdc->regmap);
1067 regcache_sync(msm_dig_cdc->regmap);
1068 break;
1069 case DIG_CDC_EVENT_INVALID:
1070 default:
1071 break;
1072 }
1073 return 0;
1074}
1075
1076static ssize_t msm_dig_codec_version_read(struct snd_info_entry *entry,
1077 void *file_private_data,
1078 struct file *file,
1079 char __user *buf, size_t count,
1080 loff_t pos)
1081{
1082 struct msm_dig_priv *msm_dig;
1083 char buffer[MSM_DIG_CDC_VERSION_ENTRY_SIZE];
1084 int len = 0;
1085
1086 msm_dig = (struct msm_dig_priv *) entry->private_data;
1087 if (!msm_dig) {
1088 pr_err("%s: msm_dig priv is null\n", __func__);
1089 return -EINVAL;
1090 }
1091
1092 switch (msm_dig->version) {
1093 case DRAX_CDC:
Laxminath Kasama7bf1bc2017-02-04 01:40:31 +05301094 len = snprintf(buffer, sizeof(buffer), "SDM660-CDC_1_0\n");
Laxminath Kasame68e94f2016-12-09 12:08:00 +05301095 break;
1096 default:
1097 len = snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n");
1098 }
1099
1100 return simple_read_from_buffer(buf, count, &pos, buffer, len);
1101}
1102
1103static struct snd_info_entry_ops msm_dig_codec_info_ops = {
1104 .read = msm_dig_codec_version_read,
1105};
1106
1107/*
1108 * msm_dig_codec_info_create_codec_entry - creates msm_dig module
1109 * @codec_root: The parent directory
1110 * @codec: Codec instance
1111 *
1112 * Creates msm_dig module and version entry under the given
1113 * parent directory.
1114 *
1115 * Return: 0 on success or negative error code on failure.
1116 */
1117int msm_dig_codec_info_create_codec_entry(struct snd_info_entry *codec_root,
1118 struct snd_soc_codec *codec)
1119{
1120 struct snd_info_entry *version_entry;
1121 struct msm_dig_priv *msm_dig;
1122 struct snd_soc_card *card;
1123
1124 if (!codec_root || !codec)
1125 return -EINVAL;
1126
1127 msm_dig = snd_soc_codec_get_drvdata(codec);
1128 card = codec->component.card;
1129 msm_dig->entry = snd_register_module_info(codec_root->module,
Laxminath Kasam4e444572017-01-15 20:00:11 +05301130 "msm_digital_codec",
Laxminath Kasame68e94f2016-12-09 12:08:00 +05301131 codec_root);
1132 if (!msm_dig->entry) {
1133 dev_dbg(codec->dev, "%s: failed to create msm_digital entry\n",
1134 __func__);
1135 return -ENOMEM;
1136 }
1137
1138 version_entry = snd_info_create_card_entry(card->snd_card,
1139 "version",
1140 msm_dig->entry);
1141 if (!version_entry) {
1142 dev_dbg(codec->dev, "%s: failed to create msm_digital version entry\n",
1143 __func__);
1144 return -ENOMEM;
1145 }
1146
1147 version_entry->private_data = msm_dig;
1148 version_entry->size = MSM_DIG_CDC_VERSION_ENTRY_SIZE;
1149 version_entry->content = SNDRV_INFO_CONTENT_DATA;
1150 version_entry->c.ops = &msm_dig_codec_info_ops;
1151
1152 if (snd_info_register(version_entry) < 0) {
1153 snd_info_free_entry(version_entry);
1154 return -ENOMEM;
1155 }
1156 msm_dig->version_entry = version_entry;
Laxminath Kasame0582ba2017-03-04 16:58:20 +05301157 if (msm_dig->get_cdc_version)
1158 msm_dig->version = msm_dig->get_cdc_version(msm_dig->handle);
1159 else
1160 msm_dig->version = DRAX_CDC;
1161
Laxminath Kasame68e94f2016-12-09 12:08:00 +05301162 return 0;
1163}
1164EXPORT_SYMBOL(msm_dig_codec_info_create_codec_entry);
1165
1166static int msm_dig_cdc_soc_probe(struct snd_soc_codec *codec)
1167{
Laxminath Kasame0582ba2017-03-04 16:58:20 +05301168 struct msm_dig_priv *msm_dig_cdc = dev_get_drvdata(codec->dev);
Divya Ojhaa2d24382017-03-07 11:16:45 +05301169 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
Laxminath Kasame68e94f2016-12-09 12:08:00 +05301170 int i, ret;
1171
Laxminath Kasame0582ba2017-03-04 16:58:20 +05301172 msm_dig_cdc->codec = codec;
Laxminath Kasame68e94f2016-12-09 12:08:00 +05301173
1174 snd_soc_add_codec_controls(codec, compander_kcontrols,
1175 ARRAY_SIZE(compander_kcontrols));
1176
1177 for (i = 0; i < NUM_DECIMATORS; i++) {
Laxminath Kasame0582ba2017-03-04 16:58:20 +05301178 tx_hpf_work[i].dig_cdc = msm_dig_cdc;
Laxminath Kasame68e94f2016-12-09 12:08:00 +05301179 tx_hpf_work[i].decimator = i + 1;
1180 INIT_DELAYED_WORK(&tx_hpf_work[i].dwork,
1181 tx_hpf_corner_freq_callback);
1182 }
1183
1184 for (i = 0; i < MSM89XX_RX_MAX; i++)
Laxminath Kasame0582ba2017-03-04 16:58:20 +05301185 msm_dig_cdc->comp_enabled[i] = COMPANDER_NONE;
Laxminath Kasame68e94f2016-12-09 12:08:00 +05301186
1187 /* Register event notifier */
1188 msm_dig_cdc->nblock.notifier_call = msm_dig_cdc_event_notify;
1189 if (msm_dig_cdc->register_notifier) {
1190 ret = msm_dig_cdc->register_notifier(msm_dig_cdc->handle,
1191 &msm_dig_cdc->nblock,
1192 true);
1193 if (ret) {
1194 pr_err("%s: Failed to register notifier %d\n",
1195 __func__, ret);
1196 return ret;
1197 }
1198 }
Laxminath Kasame68e94f2016-12-09 12:08:00 +05301199 registered_digcodec = codec;
Laxminath Kasame0582ba2017-03-04 16:58:20 +05301200
Divya Ojhaa2d24382017-03-07 11:16:45 +05301201 snd_soc_dapm_ignore_suspend(dapm, "AIF1 Playback");
1202 snd_soc_dapm_ignore_suspend(dapm, "AIF1 Capture");
1203 snd_soc_dapm_ignore_suspend(dapm, "ADC1_IN");
1204 snd_soc_dapm_ignore_suspend(dapm, "ADC2_IN");
1205 snd_soc_dapm_ignore_suspend(dapm, "ADC3_IN");
1206 snd_soc_dapm_ignore_suspend(dapm, "PDM_OUT_RX1");
1207 snd_soc_dapm_ignore_suspend(dapm, "PDM_OUT_RX2");
1208 snd_soc_dapm_ignore_suspend(dapm, "PDM_OUT_RX3");
1209
Laxminath Kasame68e94f2016-12-09 12:08:00 +05301210 return 0;
1211}
1212
1213static int msm_dig_cdc_soc_remove(struct snd_soc_codec *codec)
1214{
Laxminath Kasame0582ba2017-03-04 16:58:20 +05301215 struct msm_dig_priv *msm_dig_cdc = dev_get_drvdata(codec->dev);
Laxminath Kasame68e94f2016-12-09 12:08:00 +05301216
1217 if (msm_dig_cdc->register_notifier)
1218 msm_dig_cdc->register_notifier(msm_dig_cdc->handle,
1219 &msm_dig_cdc->nblock,
1220 false);
1221 iounmap(msm_dig_cdc->dig_base);
1222 return 0;
1223}
1224
1225static const struct snd_soc_dapm_route audio_dig_map[] = {
1226 {"RX_I2S_CLK", NULL, "CDC_CONN"},
1227 {"I2S RX1", NULL, "RX_I2S_CLK"},
1228 {"I2S RX2", NULL, "RX_I2S_CLK"},
1229 {"I2S RX3", NULL, "RX_I2S_CLK"},
1230
1231 {"I2S TX1", NULL, "TX_I2S_CLK"},
1232 {"I2S TX2", NULL, "TX_I2S_CLK"},
1233 {"I2S TX3", NULL, "TX_I2S_CLK"},
1234 {"I2S TX4", NULL, "TX_I2S_CLK"},
1235 {"I2S TX5", NULL, "TX_I2S_CLK"},
1236 {"I2S TX6", NULL, "TX_I2S_CLK"},
1237
1238 {"I2S TX1", NULL, "DEC1 MUX"},
1239 {"I2S TX2", NULL, "DEC2 MUX"},
Laxminath Kasama5cc5332017-02-04 01:36:04 +05301240 {"I2S TX3", NULL, "I2S TX2 INP1"},
1241 {"I2S TX4", NULL, "I2S TX2 INP2"},
Laxminath Kasame68e94f2016-12-09 12:08:00 +05301242 {"I2S TX5", NULL, "DEC3 MUX"},
Laxminath Kasama5cc5332017-02-04 01:36:04 +05301243 {"I2S TX6", NULL, "I2S TX3 INP2"},
1244
1245 {"I2S TX2 INP1", "RX_MIX1", "RX1 MIX2"},
1246 {"I2S TX2 INP1", "DEC3", "DEC3 MUX"},
1247 {"I2S TX2 INP2", "RX_MIX2", "RX2 MIX2"},
1248 {"I2S TX2 INP2", "RX_MIX3", "RX3 MIX1"},
1249 {"I2S TX2 INP2", "DEC4", "DEC4 MUX"},
1250 {"I2S TX3 INP2", "DEC4", "DEC4 MUX"},
1251 {"I2S TX3 INP2", "DEC5", "DEC5 MUX"},
Laxminath Kasame68e94f2016-12-09 12:08:00 +05301252
1253 {"PDM_OUT_RX1", NULL, "RX1 CHAIN"},
1254 {"PDM_OUT_RX2", NULL, "RX2 CHAIN"},
1255 {"PDM_OUT_RX3", NULL, "RX3 CHAIN"},
1256
1257 {"RX1 CHAIN", NULL, "RX1 MIX2"},
1258 {"RX2 CHAIN", NULL, "RX2 MIX2"},
1259 {"RX3 CHAIN", NULL, "RX3 MIX1"},
1260
1261 {"RX1 MIX1", NULL, "RX1 MIX1 INP1"},
1262 {"RX1 MIX1", NULL, "RX1 MIX1 INP2"},
1263 {"RX1 MIX1", NULL, "RX1 MIX1 INP3"},
1264 {"RX2 MIX1", NULL, "RX2 MIX1 INP1"},
1265 {"RX2 MIX1", NULL, "RX2 MIX1 INP2"},
1266 {"RX3 MIX1", NULL, "RX3 MIX1 INP1"},
1267 {"RX3 MIX1", NULL, "RX3 MIX1 INP2"},
1268 {"RX1 MIX2", NULL, "RX1 MIX1"},
1269 {"RX1 MIX2", NULL, "RX1 MIX2 INP1"},
1270 {"RX2 MIX2", NULL, "RX2 MIX1"},
1271 {"RX2 MIX2", NULL, "RX2 MIX2 INP1"},
1272
1273 {"RX1 MIX1 INP1", "RX1", "I2S RX1"},
1274 {"RX1 MIX1 INP1", "RX2", "I2S RX2"},
1275 {"RX1 MIX1 INP1", "RX3", "I2S RX3"},
1276 {"RX1 MIX1 INP1", "IIR1", "IIR1"},
1277 {"RX1 MIX1 INP1", "IIR2", "IIR2"},
1278 {"RX1 MIX1 INP2", "RX1", "I2S RX1"},
1279 {"RX1 MIX1 INP2", "RX2", "I2S RX2"},
1280 {"RX1 MIX1 INP2", "RX3", "I2S RX3"},
1281 {"RX1 MIX1 INP2", "IIR1", "IIR1"},
1282 {"RX1 MIX1 INP2", "IIR2", "IIR2"},
1283 {"RX1 MIX1 INP3", "RX1", "I2S RX1"},
1284 {"RX1 MIX1 INP3", "RX2", "I2S RX2"},
1285 {"RX1 MIX1 INP3", "RX3", "I2S RX3"},
1286
1287 {"RX2 MIX1 INP1", "RX1", "I2S RX1"},
1288 {"RX2 MIX1 INP1", "RX2", "I2S RX2"},
1289 {"RX2 MIX1 INP1", "RX3", "I2S RX3"},
1290 {"RX2 MIX1 INP1", "IIR1", "IIR1"},
1291 {"RX2 MIX1 INP1", "IIR2", "IIR2"},
1292 {"RX2 MIX1 INP2", "RX1", "I2S RX1"},
1293 {"RX2 MIX1 INP2", "RX2", "I2S RX2"},
1294 {"RX2 MIX1 INP2", "RX3", "I2S RX3"},
1295 {"RX2 MIX1 INP2", "IIR1", "IIR1"},
1296 {"RX2 MIX1 INP2", "IIR2", "IIR2"},
1297
1298 {"RX3 MIX1 INP1", "RX1", "I2S RX1"},
1299 {"RX3 MIX1 INP1", "RX2", "I2S RX2"},
1300 {"RX3 MIX1 INP1", "RX3", "I2S RX3"},
1301 {"RX3 MIX1 INP1", "IIR1", "IIR1"},
1302 {"RX3 MIX1 INP1", "IIR2", "IIR2"},
1303 {"RX3 MIX1 INP2", "RX1", "I2S RX1"},
1304 {"RX3 MIX1 INP2", "RX2", "I2S RX2"},
1305 {"RX3 MIX1 INP2", "RX3", "I2S RX3"},
1306 {"RX3 MIX1 INP2", "IIR1", "IIR1"},
1307 {"RX3 MIX1 INP2", "IIR2", "IIR2"},
1308
1309 {"RX1 MIX2 INP1", "IIR1", "IIR1"},
1310 {"RX2 MIX2 INP1", "IIR1", "IIR1"},
1311 {"RX1 MIX2 INP1", "IIR2", "IIR2"},
1312 {"RX2 MIX2 INP1", "IIR2", "IIR2"},
1313
1314 /* Decimator Inputs */
1315 {"DEC1 MUX", "DMIC1", "DMIC1"},
1316 {"DEC1 MUX", "DMIC2", "DMIC2"},
1317 {"DEC1 MUX", "DMIC3", "DMIC3"},
1318 {"DEC1 MUX", "DMIC4", "DMIC4"},
1319 {"DEC1 MUX", "ADC1", "ADC1_IN"},
1320 {"DEC1 MUX", "ADC2", "ADC2_IN"},
1321 {"DEC1 MUX", "ADC3", "ADC3_IN"},
1322 {"DEC1 MUX", NULL, "CDC_CONN"},
1323
1324 {"DEC2 MUX", "DMIC1", "DMIC1"},
1325 {"DEC2 MUX", "DMIC2", "DMIC2"},
1326 {"DEC2 MUX", "DMIC3", "DMIC3"},
1327 {"DEC2 MUX", "DMIC4", "DMIC4"},
1328 {"DEC2 MUX", "ADC1", "ADC1_IN"},
1329 {"DEC2 MUX", "ADC2", "ADC2_IN"},
1330 {"DEC2 MUX", "ADC3", "ADC3_IN"},
1331 {"DEC2 MUX", NULL, "CDC_CONN"},
1332
1333 {"DEC3 MUX", "DMIC1", "DMIC1"},
1334 {"DEC3 MUX", "DMIC2", "DMIC2"},
1335 {"DEC3 MUX", "DMIC3", "DMIC3"},
1336 {"DEC3 MUX", "DMIC4", "DMIC4"},
1337 {"DEC3 MUX", "ADC1", "ADC1_IN"},
1338 {"DEC3 MUX", "ADC2", "ADC2_IN"},
1339 {"DEC3 MUX", "ADC3", "ADC3_IN"},
1340 {"DEC3 MUX", NULL, "CDC_CONN"},
1341
1342 {"DEC4 MUX", "DMIC1", "DMIC1"},
1343 {"DEC4 MUX", "DMIC2", "DMIC2"},
1344 {"DEC4 MUX", "DMIC3", "DMIC3"},
1345 {"DEC4 MUX", "DMIC4", "DMIC4"},
1346 {"DEC4 MUX", "ADC1", "ADC1_IN"},
1347 {"DEC4 MUX", "ADC2", "ADC2_IN"},
1348 {"DEC4 MUX", "ADC3", "ADC3_IN"},
1349 {"DEC4 MUX", NULL, "CDC_CONN"},
1350
1351 {"DEC5 MUX", "DMIC1", "DMIC1"},
1352 {"DEC5 MUX", "DMIC2", "DMIC2"},
1353 {"DEC5 MUX", "DMIC3", "DMIC3"},
1354 {"DEC5 MUX", "DMIC4", "DMIC4"},
1355 {"DEC5 MUX", "ADC1", "ADC1_IN"},
1356 {"DEC5 MUX", "ADC2", "ADC2_IN"},
1357 {"DEC5 MUX", "ADC3", "ADC3_IN"},
1358 {"DEC5 MUX", NULL, "CDC_CONN"},
1359
1360 {"IIR1", NULL, "IIR1 INP1 MUX"},
1361 {"IIR1 INP1 MUX", "DEC1", "DEC1 MUX"},
1362 {"IIR1 INP1 MUX", "DEC2", "DEC2 MUX"},
1363 {"IIR1 INP1 MUX", "DEC3", "DEC3 MUX"},
1364 {"IIR1 INP1 MUX", "DEC4", "DEC4 MUX"},
1365 {"IIR2", NULL, "IIR2 INP1 MUX"},
1366 {"IIR2 INP1 MUX", "DEC1", "DEC1 MUX"},
1367 {"IIR2 INP1 MUX", "DEC2", "DEC2 MUX"},
1368 {"IIR1 INP1 MUX", "DEC3", "DEC3 MUX"},
1369 {"IIR1 INP1 MUX", "DEC4", "DEC4 MUX"},
1370};
1371
Laxminath Kasama5cc5332017-02-04 01:36:04 +05301372
1373static const char * const i2s_tx2_inp1_text[] = {
1374 "ZERO", "RX_MIX1", "DEC3"
1375};
1376
1377static const char * const i2s_tx2_inp2_text[] = {
1378 "ZERO", "RX_MIX2", "RX_MIX3", "DEC4"
1379};
1380
1381static const char * const i2s_tx3_inp2_text[] = {
1382 "DEC4", "DEC5"
1383};
1384
Laxminath Kasame68e94f2016-12-09 12:08:00 +05301385static const char * const rx_mix1_text[] = {
1386 "ZERO", "IIR1", "IIR2", "RX1", "RX2", "RX3"
1387};
1388
1389static const char * const rx_mix2_text[] = {
1390 "ZERO", "IIR1", "IIR2"
1391};
1392
1393static const char * const dec_mux_text[] = {
1394 "ZERO", "ADC1", "ADC2", "ADC3", "DMIC1", "DMIC2", "DMIC3", "DMIC4"
1395};
1396
1397static const char * const iir_inp1_text[] = {
1398 "ZERO", "DEC1", "DEC2", "RX1", "RX2", "RX3", "DEC3", "DEC4"
1399};
Laxminath Kasama5cc5332017-02-04 01:36:04 +05301400
1401/* I2S TX MUXes */
1402static const struct soc_enum i2s_tx2_inp1_chain_enum =
1403 SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_TX_I2S_SD1_CTL,
1404 2, 3, i2s_tx2_inp1_text);
1405
1406static const struct soc_enum i2s_tx2_inp2_chain_enum =
1407 SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_TX_I2S_SD1_CTL,
1408 0, 4, i2s_tx2_inp2_text);
1409
1410static const struct soc_enum i2s_tx3_inp2_chain_enum =
1411 SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_TX_I2S_SD1_CTL,
1412 4, 2, i2s_tx3_inp2_text);
1413
Laxminath Kasame68e94f2016-12-09 12:08:00 +05301414/* RX1 MIX1 */
1415static const struct soc_enum rx_mix1_inp1_chain_enum =
1416 SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX1_B1_CTL,
1417 0, 6, rx_mix1_text);
1418
1419static const struct soc_enum rx_mix1_inp2_chain_enum =
1420 SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX1_B1_CTL,
1421 3, 6, rx_mix1_text);
1422
1423static const struct soc_enum rx_mix1_inp3_chain_enum =
1424 SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX1_B2_CTL,
1425 0, 6, rx_mix1_text);
1426
1427/* RX1 MIX2 */
1428static const struct soc_enum rx_mix2_inp1_chain_enum =
1429 SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX1_B3_CTL,
1430 0, 3, rx_mix2_text);
1431
1432/* RX2 MIX1 */
1433static const struct soc_enum rx2_mix1_inp1_chain_enum =
1434 SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX2_B1_CTL,
1435 0, 6, rx_mix1_text);
1436
1437static const struct soc_enum rx2_mix1_inp2_chain_enum =
1438 SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX2_B1_CTL,
1439 3, 6, rx_mix1_text);
1440
1441static const struct soc_enum rx2_mix1_inp3_chain_enum =
1442 SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX2_B1_CTL,
1443 0, 6, rx_mix1_text);
1444
1445/* RX2 MIX2 */
1446static const struct soc_enum rx2_mix2_inp1_chain_enum =
1447 SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX2_B3_CTL,
1448 0, 3, rx_mix2_text);
1449
1450/* RX3 MIX1 */
1451static const struct soc_enum rx3_mix1_inp1_chain_enum =
1452 SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX3_B1_CTL,
1453 0, 6, rx_mix1_text);
1454
1455static const struct soc_enum rx3_mix1_inp2_chain_enum =
1456 SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX3_B1_CTL,
1457 3, 6, rx_mix1_text);
1458
1459static const struct soc_enum rx3_mix1_inp3_chain_enum =
1460 SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX3_B1_CTL,
1461 0, 6, rx_mix1_text);
1462
1463/* DEC */
1464static const struct soc_enum dec1_mux_enum =
1465 SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_TX_B1_CTL,
1466 0, 8, dec_mux_text);
1467
1468static const struct soc_enum dec2_mux_enum =
1469 SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_TX_B1_CTL,
1470 3, 8, dec_mux_text);
1471
1472static const struct soc_enum dec3_mux_enum =
1473 SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_TX_B2_CTL,
1474 0, 8, dec_mux_text);
1475
1476static const struct soc_enum dec4_mux_enum =
1477 SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_TX_B2_CTL,
1478 3, 8, dec_mux_text);
1479
1480static const struct soc_enum decsva_mux_enum =
1481 SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_TX_B3_CTL,
1482 0, 8, dec_mux_text);
1483
1484static const struct soc_enum iir1_inp1_mux_enum =
1485 SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_EQ1_B1_CTL,
1486 0, 8, iir_inp1_text);
1487
1488static const struct soc_enum iir2_inp1_mux_enum =
1489 SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_EQ2_B1_CTL,
1490 0, 8, iir_inp1_text);
1491
1492/*cut of frequency for high pass filter*/
1493static const char * const cf_text[] = {
1494 "MIN_3DB_4Hz", "MIN_3DB_75Hz", "MIN_3DB_150Hz"
1495};
1496
1497static const struct soc_enum cf_rxmix1_enum =
1498 SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_RX1_B4_CTL, 0, 3, cf_text);
1499
1500static const struct soc_enum cf_rxmix2_enum =
1501 SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_RX2_B4_CTL, 0, 3, cf_text);
1502
1503static const struct soc_enum cf_rxmix3_enum =
1504 SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_RX3_B4_CTL, 0, 3, cf_text);
1505
1506static const struct snd_kcontrol_new rx3_mix1_inp1_mux =
1507 SOC_DAPM_ENUM("RX3 MIX1 INP1 Mux", rx3_mix1_inp1_chain_enum);
1508
1509#define MSM89XX_DEC_ENUM(xname, xenum) \
1510{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
1511 .info = snd_soc_info_enum_double, \
1512 .get = snd_soc_dapm_get_enum_double, \
1513 .put = msm_dig_cdc_put_dec_enum, \
1514 .private_value = (unsigned long)&xenum }
1515
1516static const struct snd_kcontrol_new dec1_mux =
1517 MSM89XX_DEC_ENUM("DEC1 MUX Mux", dec1_mux_enum);
1518
1519static const struct snd_kcontrol_new dec2_mux =
1520 MSM89XX_DEC_ENUM("DEC2 MUX Mux", dec2_mux_enum);
1521
1522static const struct snd_kcontrol_new dec3_mux =
1523 MSM89XX_DEC_ENUM("DEC3 MUX Mux", dec3_mux_enum);
1524
1525static const struct snd_kcontrol_new dec4_mux =
1526 MSM89XX_DEC_ENUM("DEC4 MUX Mux", dec4_mux_enum);
1527
1528static const struct snd_kcontrol_new decsva_mux =
1529 MSM89XX_DEC_ENUM("DEC5 MUX Mux", decsva_mux_enum);
1530
Laxminath Kasama5cc5332017-02-04 01:36:04 +05301531static const struct snd_kcontrol_new i2s_tx2_inp1_mux =
1532 SOC_DAPM_ENUM("I2S TX2 INP1 Mux", i2s_tx2_inp1_chain_enum);
1533
1534static const struct snd_kcontrol_new i2s_tx2_inp2_mux =
1535 SOC_DAPM_ENUM("I2S TX2 INP2 Mux", i2s_tx2_inp2_chain_enum);
1536
1537static const struct snd_kcontrol_new i2s_tx3_inp2_mux =
1538 SOC_DAPM_ENUM("I2S TX3 INP2 Mux", i2s_tx3_inp2_chain_enum);
1539
Laxminath Kasame68e94f2016-12-09 12:08:00 +05301540static const struct snd_kcontrol_new iir1_inp1_mux =
1541 SOC_DAPM_ENUM("IIR1 INP1 Mux", iir1_inp1_mux_enum);
1542
1543static const struct snd_kcontrol_new iir2_inp1_mux =
1544 SOC_DAPM_ENUM("IIR2 INP1 Mux", iir2_inp1_mux_enum);
1545
1546static const struct snd_kcontrol_new rx_mix1_inp1_mux =
1547 SOC_DAPM_ENUM("RX1 MIX1 INP1 Mux", rx_mix1_inp1_chain_enum);
1548
1549static const struct snd_kcontrol_new rx_mix1_inp2_mux =
1550 SOC_DAPM_ENUM("RX1 MIX1 INP2 Mux", rx_mix1_inp2_chain_enum);
1551
1552static const struct snd_kcontrol_new rx_mix1_inp3_mux =
1553 SOC_DAPM_ENUM("RX1 MIX1 INP3 Mux", rx_mix1_inp3_chain_enum);
1554
1555static const struct snd_kcontrol_new rx2_mix1_inp1_mux =
1556 SOC_DAPM_ENUM("RX2 MIX1 INP1 Mux", rx2_mix1_inp1_chain_enum);
1557
1558static const struct snd_kcontrol_new rx2_mix1_inp2_mux =
1559 SOC_DAPM_ENUM("RX2 MIX1 INP2 Mux", rx2_mix1_inp2_chain_enum);
1560
1561static const struct snd_kcontrol_new rx2_mix1_inp3_mux =
1562 SOC_DAPM_ENUM("RX2 MIX1 INP3 Mux", rx2_mix1_inp3_chain_enum);
1563
1564static const struct snd_kcontrol_new rx3_mix1_inp2_mux =
1565 SOC_DAPM_ENUM("RX3 MIX1 INP2 Mux", rx3_mix1_inp2_chain_enum);
1566
1567static const struct snd_kcontrol_new rx3_mix1_inp3_mux =
1568 SOC_DAPM_ENUM("RX3 MIX1 INP3 Mux", rx3_mix1_inp3_chain_enum);
1569
1570static const struct snd_kcontrol_new rx1_mix2_inp1_mux =
1571 SOC_DAPM_ENUM("RX1 MIX2 INP1 Mux", rx_mix2_inp1_chain_enum);
1572
1573static const struct snd_kcontrol_new rx2_mix2_inp1_mux =
1574 SOC_DAPM_ENUM("RX2 MIX2 INP1 Mux", rx2_mix2_inp1_chain_enum);
1575
1576static const struct snd_soc_dapm_widget msm_dig_dapm_widgets[] = {
1577 SND_SOC_DAPM_AIF_IN("I2S RX1", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
1578 SND_SOC_DAPM_AIF_IN("I2S RX2", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
1579 SND_SOC_DAPM_AIF_IN("I2S RX3", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
1580
1581 SND_SOC_DAPM_AIF_OUT("I2S TX1", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0),
1582 SND_SOC_DAPM_AIF_OUT("I2S TX2", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0),
1583 SND_SOC_DAPM_AIF_OUT("I2S TX3", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0),
1584 SND_SOC_DAPM_AIF_OUT("I2S TX4", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0),
1585 SND_SOC_DAPM_AIF_OUT("I2S TX5", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0),
1586 SND_SOC_DAPM_AIF_OUT("I2S TX6", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0),
1587
1588 SND_SOC_DAPM_MIXER_E("RX1 MIX2", MSM89XX_CDC_CORE_CLK_RX_B1_CTL,
1589 MSM89XX_RX1, 0, NULL, 0,
1590 msm_dig_cdc_codec_enable_interpolator,
1591 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1592 SND_SOC_DAPM_MIXER_E("RX2 MIX2", MSM89XX_CDC_CORE_CLK_RX_B1_CTL,
1593 MSM89XX_RX2, 0, NULL, 0,
1594 msm_dig_cdc_codec_enable_interpolator,
1595 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1596 SND_SOC_DAPM_MIXER_E("RX3 MIX1", MSM89XX_CDC_CORE_CLK_RX_B1_CTL,
1597 MSM89XX_RX3, 0, NULL, 0,
1598 msm_dig_cdc_codec_enable_interpolator,
1599 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1600
1601 SND_SOC_DAPM_MIXER("RX1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
1602 SND_SOC_DAPM_MIXER("RX2 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
1603
Laxminath Kasam24f049a2017-01-24 18:05:32 +05301604 SND_SOC_DAPM_MIXER("RX1 CHAIN", SND_SOC_NOPM, 0, 0, NULL, 0),
1605 SND_SOC_DAPM_MIXER("RX2 CHAIN", SND_SOC_NOPM, 0, 0, NULL, 0),
1606 SND_SOC_DAPM_MIXER("RX3 CHAIN", SND_SOC_NOPM, 0, 0, NULL, 0),
Laxminath Kasame68e94f2016-12-09 12:08:00 +05301607
1608 SND_SOC_DAPM_MUX("RX1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
1609 &rx_mix1_inp1_mux),
1610 SND_SOC_DAPM_MUX("RX1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
1611 &rx_mix1_inp2_mux),
1612 SND_SOC_DAPM_MUX("RX1 MIX1 INP3", SND_SOC_NOPM, 0, 0,
1613 &rx_mix1_inp3_mux),
1614
1615 SND_SOC_DAPM_MUX("RX2 MIX1 INP1", SND_SOC_NOPM, 0, 0,
1616 &rx2_mix1_inp1_mux),
1617 SND_SOC_DAPM_MUX("RX2 MIX1 INP2", SND_SOC_NOPM, 0, 0,
1618 &rx2_mix1_inp2_mux),
1619 SND_SOC_DAPM_MUX("RX2 MIX1 INP3", SND_SOC_NOPM, 0, 0,
1620 &rx2_mix1_inp3_mux),
1621
1622 SND_SOC_DAPM_MUX("RX3 MIX1 INP1", SND_SOC_NOPM, 0, 0,
1623 &rx3_mix1_inp1_mux),
1624 SND_SOC_DAPM_MUX("RX3 MIX1 INP2", SND_SOC_NOPM, 0, 0,
1625 &rx3_mix1_inp2_mux),
1626 SND_SOC_DAPM_MUX("RX3 MIX1 INP3", SND_SOC_NOPM, 0, 0,
1627 &rx3_mix1_inp3_mux),
1628
1629 SND_SOC_DAPM_MUX("RX1 MIX2 INP1", SND_SOC_NOPM, 0, 0,
1630 &rx1_mix2_inp1_mux),
1631 SND_SOC_DAPM_MUX("RX2 MIX2 INP1", SND_SOC_NOPM, 0, 0,
1632 &rx2_mix2_inp1_mux),
1633
1634 SND_SOC_DAPM_SUPPLY_S("CDC_CONN", -2, MSM89XX_CDC_CORE_CLK_OTHR_CTL,
1635 2, 0, NULL, 0),
1636
1637 SND_SOC_DAPM_MUX_E("DEC1 MUX",
1638 MSM89XX_CDC_CORE_CLK_TX_CLK_EN_B1_CTL, 0, 0,
1639 &dec1_mux, msm_dig_cdc_codec_enable_dec,
1640 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1641 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1642
1643 SND_SOC_DAPM_MUX_E("DEC2 MUX",
1644 MSM89XX_CDC_CORE_CLK_TX_CLK_EN_B1_CTL, 1, 0,
1645 &dec2_mux, msm_dig_cdc_codec_enable_dec,
1646 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1647 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1648
1649 SND_SOC_DAPM_MUX_E("DEC3 MUX",
1650 MSM89XX_CDC_CORE_CLK_TX_CLK_EN_B1_CTL, 2, 0,
1651 &dec3_mux, msm_dig_cdc_codec_enable_dec,
1652 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1653 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1654
1655 SND_SOC_DAPM_MUX_E("DEC4 MUX",
1656 MSM89XX_CDC_CORE_CLK_TX_CLK_EN_B1_CTL, 3, 0,
1657 &dec4_mux, msm_dig_cdc_codec_enable_dec,
1658 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1659 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1660
1661 SND_SOC_DAPM_MUX_E("DEC5 MUX",
1662 MSM89XX_CDC_CORE_CLK_TX_CLK_EN_B1_CTL, 4, 0,
1663 &decsva_mux, msm_dig_cdc_codec_enable_dec,
1664 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1665 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1666
1667 /* Sidetone */
1668 SND_SOC_DAPM_MUX("IIR1 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp1_mux),
1669 SND_SOC_DAPM_PGA_E("IIR1", MSM89XX_CDC_CORE_CLK_SD_CTL, 0, 0, NULL, 0,
1670 msm_dig_cdc_codec_set_iir_gain, SND_SOC_DAPM_POST_PMU),
1671
1672 SND_SOC_DAPM_MUX("IIR2 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir2_inp1_mux),
1673 SND_SOC_DAPM_PGA_E("IIR2", MSM89XX_CDC_CORE_CLK_SD_CTL, 1, 0, NULL, 0,
1674 msm_dig_cdc_codec_set_iir_gain, SND_SOC_DAPM_POST_PMU),
1675
1676 SND_SOC_DAPM_SUPPLY("RX_I2S_CLK",
1677 MSM89XX_CDC_CORE_CLK_RX_I2S_CTL, 4, 0, NULL, 0),
1678 SND_SOC_DAPM_SUPPLY("TX_I2S_CLK",
1679 MSM89XX_CDC_CORE_CLK_TX_I2S_CTL, 4, 0, NULL, 0),
1680
Laxminath Kasama5cc5332017-02-04 01:36:04 +05301681
1682 SND_SOC_DAPM_MUX("I2S TX2 INP1", SND_SOC_NOPM, 0, 0,
1683 &i2s_tx2_inp1_mux),
1684 SND_SOC_DAPM_MUX("I2S TX2 INP2", SND_SOC_NOPM, 0, 0,
1685 &i2s_tx2_inp2_mux),
1686 SND_SOC_DAPM_MUX("I2S TX3 INP2", SND_SOC_NOPM, 0, 0,
1687 &i2s_tx3_inp2_mux),
1688
Laxminath Kasame68e94f2016-12-09 12:08:00 +05301689 /* Digital Mic Inputs */
1690 SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0,
1691 msm_dig_cdc_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
1692 SND_SOC_DAPM_POST_PMD),
1693
1694 SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 0, 0,
1695 msm_dig_cdc_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
1696 SND_SOC_DAPM_POST_PMD),
1697
1698 SND_SOC_DAPM_ADC_E("DMIC3", NULL, SND_SOC_NOPM, 0, 0,
1699 msm_dig_cdc_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
1700 SND_SOC_DAPM_POST_PMD),
1701
1702 SND_SOC_DAPM_ADC_E("DMIC4", NULL, SND_SOC_NOPM, 0, 0,
1703 msm_dig_cdc_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
1704 SND_SOC_DAPM_POST_PMD),
1705
1706 SND_SOC_DAPM_INPUT("ADC1_IN"),
1707 SND_SOC_DAPM_INPUT("ADC2_IN"),
1708 SND_SOC_DAPM_INPUT("ADC3_IN"),
1709 SND_SOC_DAPM_OUTPUT("PDM_OUT_RX1"),
1710 SND_SOC_DAPM_OUTPUT("PDM_OUT_RX2"),
1711 SND_SOC_DAPM_OUTPUT("PDM_OUT_RX3"),
1712};
1713
1714static const struct soc_enum cf_dec1_enum =
1715 SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_TX1_MUX_CTL, 4, 3, cf_text);
1716
1717static const struct soc_enum cf_dec2_enum =
1718 SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_TX2_MUX_CTL, 4, 3, cf_text);
1719
1720static const struct soc_enum cf_dec3_enum =
1721 SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_TX3_MUX_CTL, 4, 3, cf_text);
1722
1723static const struct soc_enum cf_dec4_enum =
1724 SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_TX4_MUX_CTL, 4, 3, cf_text);
1725
1726static const struct soc_enum cf_decsva_enum =
1727 SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_TX5_MUX_CTL, 4, 3, cf_text);
1728
1729static const struct snd_kcontrol_new msm_dig_snd_controls[] = {
1730 SOC_SINGLE_SX_TLV("DEC1 Volume",
1731 MSM89XX_CDC_CORE_TX1_VOL_CTL_GAIN,
1732 0, -84, 40, digital_gain),
1733 SOC_SINGLE_SX_TLV("DEC2 Volume",
1734 MSM89XX_CDC_CORE_TX2_VOL_CTL_GAIN,
1735 0, -84, 40, digital_gain),
1736 SOC_SINGLE_SX_TLV("DEC3 Volume",
1737 MSM89XX_CDC_CORE_TX3_VOL_CTL_GAIN,
1738 0, -84, 40, digital_gain),
1739 SOC_SINGLE_SX_TLV("DEC4 Volume",
1740 MSM89XX_CDC_CORE_TX4_VOL_CTL_GAIN,
1741 0, -84, 40, digital_gain),
1742 SOC_SINGLE_SX_TLV("DEC5 Volume",
1743 MSM89XX_CDC_CORE_TX5_VOL_CTL_GAIN,
1744 0, -84, 40, digital_gain),
1745
1746 SOC_SINGLE_SX_TLV("IIR1 INP1 Volume",
1747 MSM89XX_CDC_CORE_IIR1_GAIN_B1_CTL,
1748 0, -84, 40, digital_gain),
1749 SOC_SINGLE_SX_TLV("IIR1 INP2 Volume",
1750 MSM89XX_CDC_CORE_IIR1_GAIN_B2_CTL,
1751 0, -84, 40, digital_gain),
1752 SOC_SINGLE_SX_TLV("IIR1 INP3 Volume",
1753 MSM89XX_CDC_CORE_IIR1_GAIN_B3_CTL,
1754 0, -84, 40, digital_gain),
1755 SOC_SINGLE_SX_TLV("IIR1 INP4 Volume",
1756 MSM89XX_CDC_CORE_IIR1_GAIN_B4_CTL,
1757 0, -84, 40, digital_gain),
1758 SOC_SINGLE_SX_TLV("IIR2 INP1 Volume",
1759 MSM89XX_CDC_CORE_IIR2_GAIN_B1_CTL,
1760 0, -84, 40, digital_gain),
1761
1762 SOC_SINGLE_SX_TLV("RX1 Digital Volume",
1763 MSM89XX_CDC_CORE_RX1_VOL_CTL_B2_CTL,
1764 0, -84, 40, digital_gain),
1765 SOC_SINGLE_SX_TLV("RX2 Digital Volume",
1766 MSM89XX_CDC_CORE_RX2_VOL_CTL_B2_CTL,
1767 0, -84, 40, digital_gain),
1768 SOC_SINGLE_SX_TLV("RX3 Digital Volume",
1769 MSM89XX_CDC_CORE_RX3_VOL_CTL_B2_CTL,
1770 0, -84, 40, digital_gain),
1771
1772 SOC_SINGLE_EXT("IIR1 Enable Band1", IIR1, BAND1, 1, 0,
1773 msm_dig_cdc_get_iir_enable_audio_mixer,
1774 msm_dig_cdc_put_iir_enable_audio_mixer),
1775 SOC_SINGLE_EXT("IIR1 Enable Band2", IIR1, BAND2, 1, 0,
1776 msm_dig_cdc_get_iir_enable_audio_mixer,
1777 msm_dig_cdc_put_iir_enable_audio_mixer),
1778 SOC_SINGLE_EXT("IIR1 Enable Band3", IIR1, BAND3, 1, 0,
1779 msm_dig_cdc_get_iir_enable_audio_mixer,
1780 msm_dig_cdc_put_iir_enable_audio_mixer),
1781 SOC_SINGLE_EXT("IIR1 Enable Band4", IIR1, BAND4, 1, 0,
1782 msm_dig_cdc_get_iir_enable_audio_mixer,
1783 msm_dig_cdc_put_iir_enable_audio_mixer),
1784 SOC_SINGLE_EXT("IIR1 Enable Band5", IIR1, BAND5, 1, 0,
1785 msm_dig_cdc_get_iir_enable_audio_mixer,
1786 msm_dig_cdc_put_iir_enable_audio_mixer),
1787
1788 SOC_SINGLE_EXT("IIR2 Enable Band1", IIR2, BAND1, 1, 0,
1789 msm_dig_cdc_get_iir_enable_audio_mixer,
1790 msm_dig_cdc_put_iir_enable_audio_mixer),
1791 SOC_SINGLE_EXT("IIR2 Enable Band2", IIR2, BAND2, 1, 0,
1792 msm_dig_cdc_get_iir_enable_audio_mixer,
1793 msm_dig_cdc_put_iir_enable_audio_mixer),
1794 SOC_SINGLE_EXT("IIR2 Enable Band3", IIR2, BAND3, 1, 0,
1795 msm_dig_cdc_get_iir_enable_audio_mixer,
1796 msm_dig_cdc_put_iir_enable_audio_mixer),
1797 SOC_SINGLE_EXT("IIR2 Enable Band4", IIR2, BAND4, 1, 0,
1798 msm_dig_cdc_get_iir_enable_audio_mixer,
1799 msm_dig_cdc_put_iir_enable_audio_mixer),
1800 SOC_SINGLE_EXT("IIR2 Enable Band5", IIR2, BAND5, 1, 0,
1801 msm_dig_cdc_get_iir_enable_audio_mixer,
1802 msm_dig_cdc_put_iir_enable_audio_mixer),
1803
1804 SOC_SINGLE_MULTI_EXT("IIR1 Band1", IIR1, BAND1, 255, 0, 5,
1805 msm_dig_cdc_get_iir_band_audio_mixer,
1806 msm_dig_cdc_put_iir_band_audio_mixer),
1807 SOC_SINGLE_MULTI_EXT("IIR1 Band2", IIR1, BAND2, 255, 0, 5,
1808 msm_dig_cdc_get_iir_band_audio_mixer,
1809 msm_dig_cdc_put_iir_band_audio_mixer),
1810 SOC_SINGLE_MULTI_EXT("IIR1 Band3", IIR1, BAND3, 255, 0, 5,
1811 msm_dig_cdc_get_iir_band_audio_mixer,
1812 msm_dig_cdc_put_iir_band_audio_mixer),
1813 SOC_SINGLE_MULTI_EXT("IIR1 Band4", IIR1, BAND4, 255, 0, 5,
1814 msm_dig_cdc_get_iir_band_audio_mixer,
1815 msm_dig_cdc_put_iir_band_audio_mixer),
1816 SOC_SINGLE_MULTI_EXT("IIR1 Band5", IIR1, BAND5, 255, 0, 5,
1817 msm_dig_cdc_get_iir_band_audio_mixer,
1818 msm_dig_cdc_put_iir_band_audio_mixer),
1819
1820 SOC_SINGLE_MULTI_EXT("IIR2 Band1", IIR2, BAND1, 255, 0, 5,
1821 msm_dig_cdc_get_iir_band_audio_mixer,
1822 msm_dig_cdc_put_iir_band_audio_mixer),
1823 SOC_SINGLE_MULTI_EXT("IIR2 Band2", IIR2, BAND2, 255, 0, 5,
1824 msm_dig_cdc_get_iir_band_audio_mixer,
1825 msm_dig_cdc_put_iir_band_audio_mixer),
1826 SOC_SINGLE_MULTI_EXT("IIR2 Band3", IIR2, BAND3, 255, 0, 5,
1827 msm_dig_cdc_get_iir_band_audio_mixer,
1828 msm_dig_cdc_put_iir_band_audio_mixer),
1829 SOC_SINGLE_MULTI_EXT("IIR2 Band4", IIR2, BAND4, 255, 0, 5,
1830 msm_dig_cdc_get_iir_band_audio_mixer,
1831 msm_dig_cdc_put_iir_band_audio_mixer),
1832 SOC_SINGLE_MULTI_EXT("IIR2 Band5", IIR2, BAND5, 255, 0, 5,
1833 msm_dig_cdc_get_iir_band_audio_mixer,
1834 msm_dig_cdc_put_iir_band_audio_mixer),
1835
1836 SOC_SINGLE("RX1 HPF Switch",
1837 MSM89XX_CDC_CORE_RX1_B5_CTL, 2, 1, 0),
1838 SOC_SINGLE("RX2 HPF Switch",
1839 MSM89XX_CDC_CORE_RX2_B5_CTL, 2, 1, 0),
1840 SOC_SINGLE("RX3 HPF Switch",
1841 MSM89XX_CDC_CORE_RX3_B5_CTL, 2, 1, 0),
1842
1843 SOC_ENUM("RX1 HPF cut off", cf_rxmix1_enum),
1844 SOC_ENUM("RX2 HPF cut off", cf_rxmix2_enum),
1845 SOC_ENUM("RX3 HPF cut off", cf_rxmix3_enum),
1846
1847 SOC_ENUM("TX1 HPF cut off", cf_dec1_enum),
1848 SOC_ENUM("TX2 HPF cut off", cf_dec2_enum),
1849 SOC_ENUM("TX3 HPF cut off", cf_dec3_enum),
1850 SOC_ENUM("TX4 HPF cut off", cf_dec4_enum),
1851 SOC_ENUM("TX5 HPF cut off", cf_decsva_enum),
1852 SOC_SINGLE("TX1 HPF Switch",
1853 MSM89XX_CDC_CORE_TX1_MUX_CTL, 3, 1, 0),
1854 SOC_SINGLE("TX2 HPF Switch",
1855 MSM89XX_CDC_CORE_TX2_MUX_CTL, 3, 1, 0),
1856 SOC_SINGLE("TX3 HPF Switch",
1857 MSM89XX_CDC_CORE_TX3_MUX_CTL, 3, 1, 0),
1858 SOC_SINGLE("TX4 HPF Switch",
1859 MSM89XX_CDC_CORE_TX4_MUX_CTL, 3, 1, 0),
1860 SOC_SINGLE("TX5 HPF Switch",
1861 MSM89XX_CDC_CORE_TX5_MUX_CTL, 3, 1, 0),
1862};
1863
1864static int msm_dig_cdc_digital_mute(struct snd_soc_dai *dai, int mute)
1865{
1866 struct snd_soc_codec *codec = NULL;
1867 u16 tx_vol_ctl_reg = 0;
1868 u8 decimator = 0, i;
1869 struct msm_dig_priv *dig_cdc;
1870
1871 pr_debug("%s: Digital Mute val = %d\n", __func__, mute);
1872
1873 if (!dai || !dai->codec) {
1874 pr_err("%s: Invalid params\n", __func__);
1875 return -EINVAL;
1876 }
1877 codec = dai->codec;
1878 dig_cdc = snd_soc_codec_get_drvdata(codec);
1879
1880 if (dai->id == AIF1_PB) {
1881 dev_dbg(codec->dev, "%s: Not capture use case skip\n",
1882 __func__);
1883 return 0;
1884 }
1885
1886 mute = (mute) ? 1 : 0;
1887 if (!mute) {
1888 /*
1889 * 15 ms is an emperical value for the mute time
1890 * that was arrived by checking the pop level
1891 * to be inaudible
1892 */
1893 usleep_range(15000, 15010);
1894 }
1895
1896 if (dai->id == AIF3_SVA) {
1897 snd_soc_update_bits(codec,
1898 MSM89XX_CDC_CORE_TX5_VOL_CTL_CFG, 0x01, mute);
1899 goto ret;
1900 }
1901 for (i = 0; i < (NUM_DECIMATORS - 1); i++) {
1902 if (dig_cdc->dec_active[i])
1903 decimator = i + 1;
1904 if (decimator && decimator < NUM_DECIMATORS) {
1905 /* mute/unmute decimators corresponding to Tx DAI's */
1906 tx_vol_ctl_reg =
1907 MSM89XX_CDC_CORE_TX1_VOL_CTL_CFG +
1908 32 * (decimator - 1);
1909 snd_soc_update_bits(codec, tx_vol_ctl_reg,
1910 0x01, mute);
1911 }
1912 decimator = 0;
1913 }
1914ret:
1915 return 0;
1916}
1917
1918static struct snd_soc_dai_ops msm_dig_dai_ops = {
1919 .hw_params = msm_dig_cdc_hw_params,
1920 .digital_mute = msm_dig_cdc_digital_mute,
1921};
1922
1923
1924static struct snd_soc_dai_driver msm_codec_dais[] = {
1925 {
1926 .name = "msm_dig_cdc_dai_rx1",
1927 .id = AIF1_PB,
1928 .playback = { /* Support maximum range */
1929 .stream_name = "AIF1 Playback",
1930 .channels_min = 1,
1931 .channels_max = 2,
Laxminath Kasam9ac31762017-03-17 14:54:24 +05301932 .rates = SNDRV_PCM_RATE_8000_192000,
1933 .rate_max = 192000,
1934 .rate_min = 8000,
1935 .formats = SNDRV_PCM_FMTBIT_S16_LE |
1936 SNDRV_PCM_FMTBIT_S24_LE |
1937 SNDRV_PCM_FMTBIT_S24_3LE,
Laxminath Kasame68e94f2016-12-09 12:08:00 +05301938 },
1939 .ops = &msm_dig_dai_ops,
1940 },
1941 {
1942 .name = "msm_dig_cdc_dai_tx1",
1943 .id = AIF1_CAP,
1944 .capture = { /* Support maximum range */
1945 .stream_name = "AIF1 Capture",
1946 .channels_min = 1,
1947 .channels_max = 4,
1948 .rates = SNDRV_PCM_RATE_8000_48000,
1949 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1950 },
1951 .ops = &msm_dig_dai_ops,
1952 },
1953 {
1954 .name = "msm_dig_cdc_dai_tx2",
1955 .id = AIF3_SVA,
1956 .capture = { /* Support maximum range */
1957 .stream_name = "AIF2 Capture",
1958 .channels_min = 1,
1959 .channels_max = 2,
1960 .rates = SNDRV_PCM_RATE_8000_48000,
1961 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1962 },
1963 .ops = &msm_dig_dai_ops,
1964 },
1965 {
1966 .name = "msm_dig_cdc_dai_vifeed",
1967 .id = AIF2_VIFEED,
1968 .capture = { /* Support maximum range */
1969 .stream_name = "AIF2 Capture",
1970 .channels_min = 1,
1971 .channels_max = 2,
1972 .rates = SNDRV_PCM_RATE_8000_48000,
1973 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1974 },
1975 .ops = &msm_dig_dai_ops,
1976 },
1977};
1978
1979static struct regmap *msm_digital_get_regmap(struct device *dev)
1980{
Laxminath Kasame0582ba2017-03-04 16:58:20 +05301981 struct msm_dig_priv *msm_dig_cdc = dev_get_drvdata(dev);
Laxminath Kasame68e94f2016-12-09 12:08:00 +05301982
1983 return msm_dig_cdc->regmap;
1984}
1985
Divya Ojhaa2d24382017-03-07 11:16:45 +05301986static int msm_dig_cdc_suspend(struct snd_soc_codec *codec)
1987{
1988 struct msm_dig_priv *msm_dig_cdc = dev_get_drvdata(codec->dev);
1989
1990 msm_dig_cdc->dapm_bias_off = 1;
1991 return 0;
1992}
1993
1994static int msm_dig_cdc_resume(struct snd_soc_codec *codec)
1995{
1996 struct msm_dig_priv *msm_dig_cdc = dev_get_drvdata(codec->dev);
1997
1998 msm_dig_cdc->dapm_bias_off = 0;
1999 return 0;
2000}
2001
Laxminath Kasame68e94f2016-12-09 12:08:00 +05302002static struct snd_soc_codec_driver soc_msm_dig_codec = {
2003 .probe = msm_dig_cdc_soc_probe,
2004 .remove = msm_dig_cdc_soc_remove,
Divya Ojhaa2d24382017-03-07 11:16:45 +05302005 .suspend = msm_dig_cdc_suspend,
2006 .resume = msm_dig_cdc_resume,
Laxminath Kasame68e94f2016-12-09 12:08:00 +05302007 .controls = msm_dig_snd_controls,
2008 .num_controls = ARRAY_SIZE(msm_dig_snd_controls),
2009 .dapm_widgets = msm_dig_dapm_widgets,
2010 .num_dapm_widgets = ARRAY_SIZE(msm_dig_dapm_widgets),
2011 .dapm_routes = audio_dig_map,
2012 .num_dapm_routes = ARRAY_SIZE(audio_dig_map),
2013 .get_regmap = msm_digital_get_regmap,
2014};
2015
2016const struct regmap_config msm_digital_regmap_config = {
2017 .reg_bits = 32,
2018 .reg_stride = 4,
Aditya Bavanari831fe582017-03-06 12:35:37 +05302019 .val_bits = 8,
Laxminath Kasame68e94f2016-12-09 12:08:00 +05302020 .lock = enable_digital_callback,
2021 .unlock = disable_digital_callback,
2022 .cache_type = REGCACHE_FLAT,
2023 .reg_defaults = msm89xx_cdc_core_defaults,
2024 .num_reg_defaults = MSM89XX_CDC_CORE_MAX_REGISTER,
2025 .readable_reg = msm89xx_cdc_core_readable_reg,
2026 .volatile_reg = msm89xx_cdc_core_volatile_reg,
2027 .reg_format_endian = REGMAP_ENDIAN_NATIVE,
2028 .val_format_endian = REGMAP_ENDIAN_NATIVE,
2029 .max_register = MSM89XX_CDC_CORE_MAX_REGISTER,
2030};
2031
2032static int msm_dig_cdc_probe(struct platform_device *pdev)
2033{
2034 int ret;
2035 u32 dig_cdc_addr;
Laxminath Kasame0582ba2017-03-04 16:58:20 +05302036 struct msm_dig_priv *msm_dig_cdc;
Laxminath Kasame68e94f2016-12-09 12:08:00 +05302037 struct dig_ctrl_platform_data *pdata;
2038
Laxminath Kasame0582ba2017-03-04 16:58:20 +05302039 msm_dig_cdc = devm_kzalloc(&pdev->dev, sizeof(struct msm_dig_priv),
Laxminath Kasame68e94f2016-12-09 12:08:00 +05302040 GFP_KERNEL);
2041 if (!msm_dig_cdc)
2042 return -ENOMEM;
2043 pdata = dev_get_platdata(&pdev->dev);
2044 if (!pdata) {
2045 dev_err(&pdev->dev, "%s: pdata from parent is NULL\n",
2046 __func__);
2047 ret = -EINVAL;
2048 goto rtn;
2049 }
Laxminath Kasame68e94f2016-12-09 12:08:00 +05302050
2051 ret = of_property_read_u32(pdev->dev.of_node, "reg",
2052 &dig_cdc_addr);
2053 if (ret) {
2054 dev_err(&pdev->dev, "%s: could not find %s entry in dt\n",
2055 __func__, "reg");
2056 return ret;
2057 }
2058
2059 msm_dig_cdc->dig_base = ioremap(dig_cdc_addr,
2060 MSM89XX_CDC_CORE_MAX_REGISTER);
2061 if (msm_dig_cdc->dig_base == NULL) {
2062 dev_err(&pdev->dev, "%s ioremap failed\n", __func__);
2063 return -ENOMEM;
2064 }
2065 msm_dig_cdc->regmap =
2066 devm_regmap_init_mmio_clk(&pdev->dev, NULL,
2067 msm_dig_cdc->dig_base, &msm_digital_regmap_config);
2068
2069 msm_dig_cdc->update_clkdiv = pdata->update_clkdiv;
2070 msm_dig_cdc->get_cdc_version = pdata->get_cdc_version;
2071 msm_dig_cdc->handle = pdata->handle;
2072 msm_dig_cdc->register_notifier = pdata->register_notifier;
2073
Laxminath Kasame0582ba2017-03-04 16:58:20 +05302074 dev_set_drvdata(&pdev->dev, msm_dig_cdc);
Laxminath Kasame68e94f2016-12-09 12:08:00 +05302075 snd_soc_register_codec(&pdev->dev, &soc_msm_dig_codec,
2076 msm_codec_dais, ARRAY_SIZE(msm_codec_dais));
2077 dev_dbg(&pdev->dev, "%s: registered DIG CODEC 0x%x\n",
2078 __func__, dig_cdc_addr);
2079rtn:
2080 return ret;
2081}
2082
2083static int msm_dig_cdc_remove(struct platform_device *pdev)
2084{
2085 snd_soc_unregister_codec(&pdev->dev);
2086 return 0;
2087}
2088
Divya Ojhaa2d24382017-03-07 11:16:45 +05302089#ifdef CONFIG_PM
2090static int msm_dig_suspend(struct device *dev)
2091{
Laxminath Kasam5abbe122017-03-12 18:50:16 +05302092 struct msm_asoc_mach_data *pdata;
Divya Ojhaa2d24382017-03-07 11:16:45 +05302093 struct msm_dig_priv *msm_dig_cdc = dev_get_drvdata(dev);
2094
Laxminath Kasam5abbe122017-03-12 18:50:16 +05302095 if (!registered_digcodec || !msm_dig_cdc) {
2096 pr_debug("%s:digcodec not initialized, return\n", __func__);
2097 return 0;
2098 }
2099 pdata = snd_soc_card_get_drvdata(registered_digcodec->component.card);
2100 if (!pdata) {
2101 pr_debug("%s:card not initialized, return\n", __func__);
2102 return 0;
2103 }
Divya Ojhaa2d24382017-03-07 11:16:45 +05302104 if (msm_dig_cdc->dapm_bias_off) {
2105 pr_debug("%s: mclk cnt = %d, mclk_enabled = %d\n",
2106 __func__, atomic_read(&pdata->int_mclk0_rsc_ref),
2107 atomic_read(&pdata->int_mclk0_enabled));
2108
2109 if (atomic_read(&pdata->int_mclk0_enabled) == true) {
2110 cancel_delayed_work_sync(
2111 &pdata->disable_int_mclk0_work);
2112 mutex_lock(&pdata->cdc_int_mclk0_mutex);
2113 pdata->digital_cdc_core_clk.enable = 0;
2114 afe_set_lpass_clock_v2(AFE_PORT_ID_INT0_MI2S_RX,
2115 &pdata->digital_cdc_core_clk);
2116 atomic_set(&pdata->int_mclk0_enabled, false);
2117 mutex_unlock(&pdata->cdc_int_mclk0_mutex);
2118 }
2119 }
2120
2121 return 0;
2122}
2123
2124static int msm_dig_resume(struct device *dev)
2125{
2126 return 0;
2127}
2128
2129static const struct dev_pm_ops msm_dig_pm_ops = {
2130 .suspend = msm_dig_suspend,
2131 .resume = msm_dig_resume,
2132};
2133#endif
2134
Laxminath Kasame68e94f2016-12-09 12:08:00 +05302135static const struct of_device_id msm_dig_cdc_of_match[] = {
2136 {.compatible = "qcom,msm-digital-codec"},
2137 {},
2138};
2139
2140static struct platform_driver msm_digcodec_driver = {
2141 .driver = {
2142 .owner = THIS_MODULE,
2143 .name = DRV_NAME,
2144 .of_match_table = msm_dig_cdc_of_match,
Divya Ojhaa2d24382017-03-07 11:16:45 +05302145#ifdef CONFIG_PM
2146 .pm = &msm_dig_pm_ops,
2147#endif
Laxminath Kasame68e94f2016-12-09 12:08:00 +05302148 },
2149 .probe = msm_dig_cdc_probe,
2150 .remove = msm_dig_cdc_remove,
2151};
2152module_platform_driver(msm_digcodec_driver);
2153
2154MODULE_DESCRIPTION("MSM Audio Digital codec driver");
2155MODULE_LICENSE("GPL v2");