blob: d8c4ca06c1f710944a9d696e0796a0c0cef66566 [file] [log] [blame]
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301/*
Xiaojun Sangc9af54a2018-02-12 19:03:02 +08002 * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13#include <linux/module.h>
14#include <linux/init.h>
15#include <linux/firmware.h>
16#include <linux/slab.h>
17#include <linux/platform_device.h>
18#include <linux/device.h>
19#include <linux/printk.h>
20#include <linux/ratelimit.h>
21#include <linux/debugfs.h>
22#include <linux/wait.h>
23#include <linux/bitops.h>
24#include <linux/regmap.h>
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053025#include <linux/regulator/consumer.h>
26#include <linux/clk.h>
27#include <linux/delay.h>
28#include <linux/pm_runtime.h>
29#include <linux/kernel.h>
30#include <linux/gpio.h>
Laxminath Kasam605b42f2017-08-01 22:02:15 +053031#include <linux/mfd/wcd9xxx/wcd9xxx_registers.h>
32#include <soc/swr-wcd.h>
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053033#include <sound/pcm.h>
34#include <sound/pcm_params.h>
35#include <sound/soc.h>
36#include <sound/soc-dapm.h>
37#include <sound/tlv.h>
38#include <sound/info.h>
Laxminath Kasam605b42f2017-08-01 22:02:15 +053039#include "core.h"
40#include "pdata.h"
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053041#include "wcd9335.h"
42#include "wcd-mbhc-v2.h"
43#include "wcd9xxx-common-v2.h"
44#include "wcd9xxx-resmgr-v2.h"
Laxminath Kasam605b42f2017-08-01 22:02:15 +053045#include "wcd9xxx-irq.h"
46#include "wcd9335_registers.h"
47#include "wcd9335_irq.h"
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053048#include "wcd_cpe_core.h"
49#include "wcdcal-hwdep.h"
50#include "wcd-mbhc-v2-api.h"
51
52#define TASHA_RX_PORT_START_NUMBER 16
53
54#define WCD9335_RATES_MASK (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
55 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
56 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
57/* Fractional Rates */
58#define WCD9335_FRAC_RATES_MASK (SNDRV_PCM_RATE_44100)
59
60#define WCD9335_MIX_RATES_MASK (SNDRV_PCM_RATE_48000 |\
61 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
62
63#define TASHA_FORMATS_S16_S24_LE (SNDRV_PCM_FMTBIT_S16_LE | \
64 SNDRV_PCM_FMTBIT_S24_LE | \
65 SNDRV_PCM_FMTBIT_S24_3LE)
66
67#define TASHA_FORMATS_S16_S24_S32_LE (SNDRV_PCM_FMTBIT_S16_LE | \
68 SNDRV_PCM_FMTBIT_S24_LE | \
69 SNDRV_PCM_FMTBIT_S24_3LE | \
70 SNDRV_PCM_FMTBIT_S32_LE)
71
72#define TASHA_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
73
74/*
75 * Timeout in milli seconds and it is the wait time for
76 * slim channel removal interrupt to receive.
77 */
78#define TASHA_SLIM_CLOSE_TIMEOUT 1000
79#define TASHA_SLIM_IRQ_OVERFLOW (1 << 0)
80#define TASHA_SLIM_IRQ_UNDERFLOW (1 << 1)
81#define TASHA_SLIM_IRQ_PORT_CLOSED (1 << 2)
82#define TASHA_MCLK_CLK_12P288MHZ 12288000
83#define TASHA_MCLK_CLK_9P6MHZ 9600000
84
85#define TASHA_SLIM_PGD_PORT_INT_TX_EN0 (TASHA_SLIM_PGD_PORT_INT_EN0 + 2)
86
87#define TASHA_NUM_INTERPOLATORS 9
88#define TASHA_NUM_DECIMATORS 9
89
Meng Wang3b194492017-09-27 12:20:22 +080090#define WCD9335_CHILD_DEVICES_MAX 6
91
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053092#define BYTE_BIT_MASK(nr) (1 << ((nr) % BITS_PER_BYTE))
93#define TASHA_MAD_AUDIO_FIRMWARE_PATH "wcd9335/wcd9335_mad_audio.bin"
94#define TASHA_CPE_SS_ERR_STATUS_MEM_ACCESS (1 << 0)
95#define TASHA_CPE_SS_ERR_STATUS_WDOG_BITE (1 << 1)
96
97#define TASHA_CPE_FATAL_IRQS \
98 (TASHA_CPE_SS_ERR_STATUS_WDOG_BITE | \
99 TASHA_CPE_SS_ERR_STATUS_MEM_ACCESS)
100
101#define SLIM_BW_CLK_GEAR_9 6200000
102#define SLIM_BW_UNVOTE 0
103
104#define CPE_FLL_CLK_75MHZ 75000000
105#define CPE_FLL_CLK_150MHZ 150000000
106#define WCD9335_REG_BITS 8
107
108#define WCD9335_MAX_VALID_ADC_MUX 13
109#define WCD9335_INVALID_ADC_MUX 9
110
111#define TASHA_DIG_CORE_REG_MIN WCD9335_CDC_ANC0_CLK_RESET_CTL
112#define TASHA_DIG_CORE_REG_MAX 0xDFF
113
114/* Convert from vout ctl to micbias voltage in mV */
115#define WCD_VOUT_CTL_TO_MICB(v) (1000 + v * 50)
116
Laxminath Kasam8f7ccc22017-08-28 17:35:04 +0530117#define TASHA_ZDET_NUM_MEASUREMENTS 900
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530118#define TASHA_MBHC_GET_C1(c) ((c & 0xC000) >> 14)
119#define TASHA_MBHC_GET_X1(x) (x & 0x3FFF)
120/* z value compared in milliOhm */
121#define TASHA_MBHC_IS_SECOND_RAMP_REQUIRED(z) ((z > 400000) || (z < 32000))
122#define TASHA_MBHC_ZDET_CONST (86 * 16384)
123#define TASHA_MBHC_MOISTURE_VREF V_45_MV
124#define TASHA_MBHC_MOISTURE_IREF I_3P0_UA
125
126#define TASHA_VERSION_ENTRY_SIZE 17
127
128#define WCD9335_AMIC_PWR_LEVEL_LP 0
129#define WCD9335_AMIC_PWR_LEVEL_DEFAULT 1
130#define WCD9335_AMIC_PWR_LEVEL_HP 2
131#define WCD9335_AMIC_PWR_LVL_MASK 0x60
132#define WCD9335_AMIC_PWR_LVL_SHIFT 0x5
133
134#define WCD9335_DEC_PWR_LVL_MASK 0x06
135#define WCD9335_DEC_PWR_LVL_LP 0x02
136#define WCD9335_DEC_PWR_LVL_HP 0x04
137#define WCD9335_DEC_PWR_LVL_DF 0x00
138#define WCD9335_STRING_LEN 100
139
140#define CALCULATE_VOUT_D(req_mv) (((req_mv - 650) * 10) / 25)
141
142static int cpe_debug_mode;
143
144#define TASHA_MAX_MICBIAS 4
145#define DAPM_MICBIAS1_STANDALONE "MIC BIAS1 Standalone"
146#define DAPM_MICBIAS2_STANDALONE "MIC BIAS2 Standalone"
147#define DAPM_MICBIAS3_STANDALONE "MIC BIAS3 Standalone"
148#define DAPM_MICBIAS4_STANDALONE "MIC BIAS4 Standalone"
149
150#define DAPM_LDO_H_STANDALONE "LDO_H"
151module_param(cpe_debug_mode, int, 0664);
152MODULE_PARM_DESC(cpe_debug_mode, "boot cpe in debug mode");
153
154#define TASHA_DIG_CORE_COLLAPSE_TIMER_MS (5 * 1000)
155
156#define MAX_ON_DEMAND_SUPPLY_NAME_LENGTH 64
157
158static char on_demand_supply_name[][MAX_ON_DEMAND_SUPPLY_NAME_LENGTH] = {
159 "cdc-vdd-mic-bias",
160};
161
162enum {
163 POWER_COLLAPSE,
164 POWER_RESUME,
165};
166
167enum tasha_sido_voltage {
168 SIDO_VOLTAGE_SVS_MV = 950,
169 SIDO_VOLTAGE_NOMINAL_MV = 1100,
170};
171
172static enum codec_variant codec_ver;
173
174static int dig_core_collapse_enable = 1;
175module_param(dig_core_collapse_enable, int, 0664);
176MODULE_PARM_DESC(dig_core_collapse_enable, "enable/disable power gating");
177
178/* dig_core_collapse timer in seconds */
179static int dig_core_collapse_timer = (TASHA_DIG_CORE_COLLAPSE_TIMER_MS/1000);
180module_param(dig_core_collapse_timer, int, 0664);
181MODULE_PARM_DESC(dig_core_collapse_timer, "timer for power gating");
182
183/* SVS Scaling enable/disable */
184static int svs_scaling_enabled = 1;
185module_param(svs_scaling_enabled, int, 0664);
186MODULE_PARM_DESC(svs_scaling_enabled, "enable/disable svs scaling");
187
188/* SVS buck setting */
189static int sido_buck_svs_voltage = SIDO_VOLTAGE_SVS_MV;
190module_param(sido_buck_svs_voltage, int, 0664);
191MODULE_PARM_DESC(sido_buck_svs_voltage,
192 "setting for SVS voltage for SIDO BUCK");
193
194#define TASHA_TX_UNMUTE_DELAY_MS 40
195
196static int tx_unmute_delay = TASHA_TX_UNMUTE_DELAY_MS;
197module_param(tx_unmute_delay, int, 0664);
198MODULE_PARM_DESC(tx_unmute_delay, "delay to unmute the tx path");
199
200static struct afe_param_slimbus_slave_port_cfg tasha_slimbus_slave_port_cfg = {
201 .minor_version = 1,
202 .slimbus_dev_id = AFE_SLIMBUS_DEVICE_1,
203 .slave_dev_pgd_la = 0,
204 .slave_dev_intfdev_la = 0,
205 .bit_width = 16,
206 .data_format = 0,
207 .num_channels = 1
208};
209
210struct tasha_mbhc_zdet_param {
211 u16 ldo_ctl;
212 u16 noff;
213 u16 nshift;
214 u16 btn5;
215 u16 btn6;
216 u16 btn7;
217};
218
219static struct afe_param_cdc_reg_page_cfg tasha_cdc_reg_page_cfg = {
220 .minor_version = AFE_API_VERSION_CDC_REG_PAGE_CFG,
221 .enable = 1,
222 .proc_id = AFE_CDC_REG_PAGE_ASSIGN_PROC_ID_1,
223};
224
225static struct afe_param_cdc_reg_cfg audio_reg_cfg[] = {
226 {
227 1,
228 (TASHA_REGISTER_START_OFFSET + WCD9335_SOC_MAD_MAIN_CTL_1),
229 HW_MAD_AUDIO_ENABLE, 0x1, WCD9335_REG_BITS, 0
230 },
231 {
232 1,
233 (TASHA_REGISTER_START_OFFSET + WCD9335_SOC_MAD_AUDIO_CTL_3),
234 HW_MAD_AUDIO_SLEEP_TIME, 0xF, WCD9335_REG_BITS, 0
235 },
236 {
237 1,
238 (TASHA_REGISTER_START_OFFSET + WCD9335_SOC_MAD_AUDIO_CTL_4),
239 HW_MAD_TX_AUDIO_SWITCH_OFF, 0x1, WCD9335_REG_BITS, 0
240 },
241 {
242 1,
243 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_CFG),
244 MAD_AUDIO_INT_DEST_SELECT_REG, 0x2, WCD9335_REG_BITS, 0
245 },
246 {
247 1,
248 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_PIN2_MASK3),
249 MAD_AUDIO_INT_MASK_REG, 0x1, WCD9335_REG_BITS, 0
250 },
251 {
252 1,
253 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_PIN2_STATUS3),
254 MAD_AUDIO_INT_STATUS_REG, 0x1, WCD9335_REG_BITS, 0
255 },
256 {
257 1,
258 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_PIN2_CLEAR3),
259 MAD_AUDIO_INT_CLEAR_REG, 0x1, WCD9335_REG_BITS, 0
260 },
261 {
262 1,
263 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_CFG),
264 VBAT_INT_DEST_SELECT_REG, 0x2, WCD9335_REG_BITS, 0
265 },
266 {
267 1,
268 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_PIN2_MASK3),
269 VBAT_INT_MASK_REG, 0x08, WCD9335_REG_BITS, 0
270 },
271 {
272 1,
273 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_PIN2_STATUS3),
274 VBAT_INT_STATUS_REG, 0x08, WCD9335_REG_BITS, 0
275 },
276 {
277 1,
278 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_PIN2_CLEAR3),
279 VBAT_INT_CLEAR_REG, 0x08, WCD9335_REG_BITS, 0
280 },
281 {
282 1,
283 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_CFG),
284 VBAT_RELEASE_INT_DEST_SELECT_REG, 0x2, WCD9335_REG_BITS, 0
285 },
286 {
287 1,
288 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_PIN2_MASK3),
289 VBAT_RELEASE_INT_MASK_REG, 0x10, WCD9335_REG_BITS, 0
290 },
291 {
292 1,
293 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_PIN2_STATUS3),
294 VBAT_RELEASE_INT_STATUS_REG, 0x10, WCD9335_REG_BITS, 0
295 },
296 {
297 1,
298 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_PIN2_CLEAR3),
299 VBAT_RELEASE_INT_CLEAR_REG, 0x10, WCD9335_REG_BITS, 0
300 },
301 {
302 1,
303 (TASHA_REGISTER_START_OFFSET + TASHA_SB_PGD_PORT_TX_BASE),
304 SB_PGD_PORT_TX_WATERMARK_N, 0x1E, WCD9335_REG_BITS, 0x1
305 },
306 {
307 1,
308 (TASHA_REGISTER_START_OFFSET + TASHA_SB_PGD_PORT_TX_BASE),
309 SB_PGD_PORT_TX_ENABLE_N, 0x1, WCD9335_REG_BITS, 0x1
310 },
311 {
312 1,
313 (TASHA_REGISTER_START_OFFSET + TASHA_SB_PGD_PORT_RX_BASE),
314 SB_PGD_PORT_RX_WATERMARK_N, 0x1E, WCD9335_REG_BITS, 0x1
315 },
316 {
317 1,
318 (TASHA_REGISTER_START_OFFSET + TASHA_SB_PGD_PORT_RX_BASE),
319 SB_PGD_PORT_RX_ENABLE_N, 0x1, WCD9335_REG_BITS, 0x1
320 },
321 { 1,
322 (TASHA_REGISTER_START_OFFSET + WCD9335_CDC_ANC0_IIR_ADAPT_CTL),
323 AANC_FF_GAIN_ADAPTIVE, 0x4, WCD9335_REG_BITS, 0
324 },
325 { 1,
326 (TASHA_REGISTER_START_OFFSET + WCD9335_CDC_ANC0_IIR_ADAPT_CTL),
327 AANC_FFGAIN_ADAPTIVE_EN, 0x8, WCD9335_REG_BITS, 0
328 },
329 {
330 1,
331 (TASHA_REGISTER_START_OFFSET + WCD9335_CDC_ANC0_FF_A_GAIN_CTL),
332 AANC_GAIN_CONTROL, 0xFF, WCD9335_REG_BITS, 0
333 },
334};
335
336static struct afe_param_cdc_reg_cfg_data tasha_audio_reg_cfg = {
337 .num_registers = ARRAY_SIZE(audio_reg_cfg),
338 .reg_data = audio_reg_cfg,
339};
340
341static struct afe_param_id_cdc_aanc_version tasha_cdc_aanc_version = {
342 .cdc_aanc_minor_version = AFE_API_VERSION_CDC_AANC_VERSION,
343 .aanc_hw_version = AANC_HW_BLOCK_VERSION_2,
344};
345
346enum {
347 VI_SENSE_1,
348 VI_SENSE_2,
349 AIF4_SWITCH_VALUE,
350 AUDIO_NOMINAL,
351 CPE_NOMINAL,
352 HPH_PA_DELAY,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530353 ANC_MIC_AMIC1,
354 ANC_MIC_AMIC2,
355 ANC_MIC_AMIC3,
356 ANC_MIC_AMIC4,
357 ANC_MIC_AMIC5,
358 ANC_MIC_AMIC6,
359 CLASSH_CONFIG,
360};
361
362enum {
363 AIF1_PB = 0,
364 AIF1_CAP,
365 AIF2_PB,
366 AIF2_CAP,
367 AIF3_PB,
368 AIF3_CAP,
369 AIF4_PB,
370 AIF_MIX1_PB,
371 AIF4_MAD_TX,
372 AIF4_VIFEED,
373 AIF5_CPE_TX,
374 NUM_CODEC_DAIS,
375};
376
377enum {
378 INTn_1_MIX_INP_SEL_ZERO = 0,
379 INTn_1_MIX_INP_SEL_DEC0,
380 INTn_1_MIX_INP_SEL_DEC1,
381 INTn_1_MIX_INP_SEL_IIR0,
382 INTn_1_MIX_INP_SEL_IIR1,
383 INTn_1_MIX_INP_SEL_RX0,
384 INTn_1_MIX_INP_SEL_RX1,
385 INTn_1_MIX_INP_SEL_RX2,
386 INTn_1_MIX_INP_SEL_RX3,
387 INTn_1_MIX_INP_SEL_RX4,
388 INTn_1_MIX_INP_SEL_RX5,
389 INTn_1_MIX_INP_SEL_RX6,
390 INTn_1_MIX_INP_SEL_RX7,
391
392};
393
394#define IS_VALID_NATIVE_FIFO_PORT(inp) \
395 ((inp >= INTn_1_MIX_INP_SEL_RX0) && \
396 (inp <= INTn_1_MIX_INP_SEL_RX3))
397
398enum {
399 INTn_2_INP_SEL_ZERO = 0,
400 INTn_2_INP_SEL_RX0,
401 INTn_2_INP_SEL_RX1,
402 INTn_2_INP_SEL_RX2,
403 INTn_2_INP_SEL_RX3,
404 INTn_2_INP_SEL_RX4,
405 INTn_2_INP_SEL_RX5,
406 INTn_2_INP_SEL_RX6,
407 INTn_2_INP_SEL_RX7,
408 INTn_2_INP_SEL_PROXIMITY,
409};
410
411enum {
412 INTERP_EAR = 0,
413 INTERP_HPHL,
414 INTERP_HPHR,
415 INTERP_LO1,
416 INTERP_LO2,
417 INTERP_LO3,
418 INTERP_LO4,
419 INTERP_SPKR1,
420 INTERP_SPKR2,
421};
422
423struct interp_sample_rate {
424 int sample_rate;
425 int rate_val;
426};
427
428static struct interp_sample_rate int_prim_sample_rate_val[] = {
429 {8000, 0x0}, /* 8K */
430 {16000, 0x1}, /* 16K */
431 {24000, -EINVAL},/* 24K */
432 {32000, 0x3}, /* 32K */
433 {48000, 0x4}, /* 48K */
434 {96000, 0x5}, /* 96K */
435 {192000, 0x6}, /* 192K */
436 {384000, 0x7}, /* 384K */
437 {44100, 0x8}, /* 44.1K */
438};
439
440static struct interp_sample_rate int_mix_sample_rate_val[] = {
441 {48000, 0x4}, /* 48K */
442 {96000, 0x5}, /* 96K */
443 {192000, 0x6}, /* 192K */
444};
445
446static const struct wcd9xxx_ch tasha_rx_chs[TASHA_RX_MAX] = {
447 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER, 0),
448 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 1, 1),
449 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 2, 2),
450 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 3, 3),
451 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 4, 4),
452 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 5, 5),
453 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 6, 6),
454 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 7, 7),
455 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 8, 8),
456 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 9, 9),
457 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 10, 10),
458 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 11, 11),
459 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 12, 12),
460};
461
462static const struct wcd9xxx_ch tasha_tx_chs[TASHA_TX_MAX] = {
463 WCD9XXX_CH(0, 0),
464 WCD9XXX_CH(1, 1),
465 WCD9XXX_CH(2, 2),
466 WCD9XXX_CH(3, 3),
467 WCD9XXX_CH(4, 4),
468 WCD9XXX_CH(5, 5),
469 WCD9XXX_CH(6, 6),
470 WCD9XXX_CH(7, 7),
471 WCD9XXX_CH(8, 8),
472 WCD9XXX_CH(9, 9),
473 WCD9XXX_CH(10, 10),
474 WCD9XXX_CH(11, 11),
475 WCD9XXX_CH(12, 12),
476 WCD9XXX_CH(13, 13),
477 WCD9XXX_CH(14, 14),
478 WCD9XXX_CH(15, 15),
479};
480
481static const u32 vport_slim_check_table[NUM_CODEC_DAIS] = {
482 /* Needs to define in the same order of DAI enum definitions */
483 0,
484 BIT(AIF2_CAP) | BIT(AIF3_CAP) | BIT(AIF4_MAD_TX) | BIT(AIF5_CPE_TX),
485 0,
486 BIT(AIF1_CAP) | BIT(AIF3_CAP) | BIT(AIF4_MAD_TX) | BIT(AIF5_CPE_TX),
487 0,
488 BIT(AIF1_CAP) | BIT(AIF2_CAP) | BIT(AIF4_MAD_TX) | BIT(AIF5_CPE_TX),
489 0,
490 0,
491 BIT(AIF1_CAP) | BIT(AIF2_CAP) | BIT(AIF3_CAP) | BIT(AIF5_CPE_TX),
492 0,
493 BIT(AIF1_CAP) | BIT(AIF2_CAP) | BIT(AIF3_CAP) | BIT(AIF4_MAD_TX),
494};
495
496static const u32 vport_i2s_check_table[NUM_CODEC_DAIS] = {
497 0, /* AIF1_PB */
498 BIT(AIF2_CAP), /* AIF1_CAP */
499 0, /* AIF2_PB */
500 BIT(AIF1_CAP), /* AIF2_CAP */
501};
502
503/* Codec supports 2 IIR filters */
504enum {
505 IIR0 = 0,
506 IIR1,
507 IIR_MAX,
508};
509
510/* Each IIR has 5 Filter Stages */
511enum {
512 BAND1 = 0,
513 BAND2,
514 BAND3,
515 BAND4,
516 BAND5,
517 BAND_MAX,
518};
519
520enum {
521 COMPANDER_1, /* HPH_L */
522 COMPANDER_2, /* HPH_R */
523 COMPANDER_3, /* LO1_DIFF */
524 COMPANDER_4, /* LO2_DIFF */
525 COMPANDER_5, /* LO3_SE */
526 COMPANDER_6, /* LO4_SE */
527 COMPANDER_7, /* SWR SPK CH1 */
528 COMPANDER_8, /* SWR SPK CH2 */
529 COMPANDER_MAX,
530};
531
532enum {
533 SRC_IN_HPHL,
534 SRC_IN_LO1,
535 SRC_IN_HPHR,
536 SRC_IN_LO2,
537 SRC_IN_SPKRL,
538 SRC_IN_LO3,
539 SRC_IN_SPKRR,
540 SRC_IN_LO4,
541};
542
543enum {
544 SPLINE_SRC0,
545 SPLINE_SRC1,
546 SPLINE_SRC2,
547 SPLINE_SRC3,
548 SPLINE_SRC_MAX,
549};
550
551static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0);
552static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1);
553static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1);
554
555static struct snd_soc_dai_driver tasha_dai[];
556static int wcd9335_get_micb_vout_ctl_val(u32 micb_mv);
557
558static int tasha_config_compander(struct snd_soc_codec *, int, int);
559static void tasha_codec_set_tx_hold(struct snd_soc_codec *, u16, bool);
560static int tasha_codec_internal_rco_ctrl(struct snd_soc_codec *codec,
561 bool enable);
562
563/* Hold instance to soundwire platform device */
564struct tasha_swr_ctrl_data {
565 struct platform_device *swr_pdev;
566 struct ida swr_ida;
567};
568
569struct wcd_swr_ctrl_platform_data {
570 void *handle; /* holds codec private data */
571 int (*read)(void *handle, int reg);
572 int (*write)(void *handle, int reg, int val);
573 int (*bulk_write)(void *handle, u32 *reg, u32 *val, size_t len);
574 int (*clk)(void *handle, bool enable);
575 int (*handle_irq)(void *handle,
576 irqreturn_t (*swrm_irq_handler)(int irq,
577 void *data),
578 void *swrm_handle,
579 int action);
580};
581
582static struct wcd_mbhc_register
583 wcd_mbhc_registers[WCD_MBHC_REG_FUNC_MAX] = {
584 WCD_MBHC_REGISTER("WCD_MBHC_L_DET_EN",
585 WCD9335_ANA_MBHC_MECH, 0x80, 7, 0),
586 WCD_MBHC_REGISTER("WCD_MBHC_GND_DET_EN",
587 WCD9335_ANA_MBHC_MECH, 0x40, 6, 0),
588 WCD_MBHC_REGISTER("WCD_MBHC_MECH_DETECTION_TYPE",
589 WCD9335_ANA_MBHC_MECH, 0x20, 5, 0),
590 WCD_MBHC_REGISTER("WCD_MBHC_MIC_CLAMP_CTL",
591 WCD9335_MBHC_PLUG_DETECT_CTL, 0x30, 4, 0),
592 WCD_MBHC_REGISTER("WCD_MBHC_ELECT_DETECTION_TYPE",
593 WCD9335_ANA_MBHC_ELECT, 0x08, 3, 0),
594 WCD_MBHC_REGISTER("WCD_MBHC_HS_L_DET_PULL_UP_CTRL",
595 WCD9335_MBHC_PLUG_DETECT_CTL, 0xC0, 6, 0),
596 WCD_MBHC_REGISTER("WCD_MBHC_HS_L_DET_PULL_UP_COMP_CTRL",
597 WCD9335_ANA_MBHC_MECH, 0x04, 2, 0),
598 WCD_MBHC_REGISTER("WCD_MBHC_HPHL_PLUG_TYPE",
599 WCD9335_ANA_MBHC_MECH, 0x10, 4, 0),
600 WCD_MBHC_REGISTER("WCD_MBHC_GND_PLUG_TYPE",
601 WCD9335_ANA_MBHC_MECH, 0x08, 3, 0),
602 WCD_MBHC_REGISTER("WCD_MBHC_SW_HPH_LP_100K_TO_GND",
603 WCD9335_ANA_MBHC_MECH, 0x01, 0, 0),
604 WCD_MBHC_REGISTER("WCD_MBHC_ELECT_SCHMT_ISRC",
605 WCD9335_ANA_MBHC_ELECT, 0x06, 1, 0),
606 WCD_MBHC_REGISTER("WCD_MBHC_FSM_EN",
607 WCD9335_ANA_MBHC_ELECT, 0x80, 7, 0),
608 WCD_MBHC_REGISTER("WCD_MBHC_INSREM_DBNC",
609 WCD9335_MBHC_PLUG_DETECT_CTL, 0x0F, 0, 0),
610 WCD_MBHC_REGISTER("WCD_MBHC_BTN_DBNC",
611 WCD9335_MBHC_CTL_1, 0x03, 0, 0),
612 WCD_MBHC_REGISTER("WCD_MBHC_HS_VREF",
613 WCD9335_MBHC_CTL_2, 0x03, 0, 0),
614 WCD_MBHC_REGISTER("WCD_MBHC_HS_COMP_RESULT",
615 WCD9335_ANA_MBHC_RESULT_3, 0x08, 3, 0),
616 WCD_MBHC_REGISTER("WCD_MBHC_MIC_SCHMT_RESULT",
617 WCD9335_ANA_MBHC_RESULT_3, 0x20, 5, 0),
618 WCD_MBHC_REGISTER("WCD_MBHC_HPHL_SCHMT_RESULT",
619 WCD9335_ANA_MBHC_RESULT_3, 0x80, 7, 0),
620 WCD_MBHC_REGISTER("WCD_MBHC_HPHR_SCHMT_RESULT",
621 WCD9335_ANA_MBHC_RESULT_3, 0x40, 6, 0),
622 WCD_MBHC_REGISTER("WCD_MBHC_OCP_FSM_EN",
623 WCD9335_HPH_OCP_CTL, 0x10, 4, 0),
624 WCD_MBHC_REGISTER("WCD_MBHC_BTN_RESULT",
625 WCD9335_ANA_MBHC_RESULT_3, 0x07, 0, 0),
626 WCD_MBHC_REGISTER("WCD_MBHC_BTN_ISRC_CTL",
627 WCD9335_ANA_MBHC_ELECT, 0x70, 4, 0),
628 WCD_MBHC_REGISTER("WCD_MBHC_ELECT_RESULT",
629 WCD9335_ANA_MBHC_RESULT_3, 0xFF, 0, 0),
630 WCD_MBHC_REGISTER("WCD_MBHC_MICB_CTRL",
631 WCD9335_ANA_MICB2, 0xC0, 6, 0),
632 WCD_MBHC_REGISTER("WCD_MBHC_HPH_CNP_WG_TIME",
633 WCD9335_HPH_CNP_WG_TIME, 0xFF, 0, 0),
634 WCD_MBHC_REGISTER("WCD_MBHC_HPHR_PA_EN",
635 WCD9335_ANA_HPH, 0x40, 6, 0),
636 WCD_MBHC_REGISTER("WCD_MBHC_HPHL_PA_EN",
637 WCD9335_ANA_HPH, 0x80, 7, 0),
638 WCD_MBHC_REGISTER("WCD_MBHC_HPH_PA_EN",
639 WCD9335_ANA_HPH, 0xC0, 6, 0),
640 WCD_MBHC_REGISTER("WCD_MBHC_SWCH_LEVEL_REMOVE",
641 WCD9335_ANA_MBHC_RESULT_3, 0x10, 4, 0),
642 WCD_MBHC_REGISTER("WCD_MBHC_PULLDOWN_CTRL",
643 0, 0, 0, 0),
644 WCD_MBHC_REGISTER("WCD_MBHC_ANC_DET_EN",
645 WCD9335_ANA_MBHC_ZDET, 0x01, 0, 0),
646 /*
647 * MBHC FSM status register is only available in Tasha 2.0.
648 * So, init with 0 later once the version is known, then values
649 * will be updated.
650 */
651 WCD_MBHC_REGISTER("WCD_MBHC_FSM_STATUS",
652 0, 0, 0, 0),
653 WCD_MBHC_REGISTER("WCD_MBHC_MUX_CTL",
654 WCD9335_MBHC_CTL_2, 0x70, 4, 0),
Meng Wang6f901622017-09-19 10:21:57 +0800655 WCD_MBHC_REGISTER("WCD_MBHC_MOISTURE_STATUS",
656 WCD9335_MBHC_FSM_STATUS, 0X20, 5, 0),
657 WCD_MBHC_REGISTER("WCD_MBHC_HPHR_GND",
658 WCD9335_HPH_PA_CTL2, 0x40, 6, 0),
659 WCD_MBHC_REGISTER("WCD_MBHC_HPHL_GND",
660 WCD9335_HPH_PA_CTL2, 0x10, 4, 0),
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530661};
662
663static const struct wcd_mbhc_intr intr_ids = {
664 .mbhc_sw_intr = WCD9335_IRQ_MBHC_SW_DET,
665 .mbhc_btn_press_intr = WCD9335_IRQ_MBHC_BUTTON_PRESS_DET,
666 .mbhc_btn_release_intr = WCD9335_IRQ_MBHC_BUTTON_RELEASE_DET,
667 .mbhc_hs_ins_intr = WCD9335_IRQ_MBHC_ELECT_INS_REM_LEG_DET,
668 .mbhc_hs_rem_intr = WCD9335_IRQ_MBHC_ELECT_INS_REM_DET,
669 .hph_left_ocp = WCD9335_IRQ_HPH_PA_OCPL_FAULT,
670 .hph_right_ocp = WCD9335_IRQ_HPH_PA_OCPR_FAULT,
671};
672
673struct wcd_vbat {
674 bool is_enabled;
675 bool adc_config;
676 /* Variables to cache Vbat ADC output values */
677 u16 dcp1;
678 u16 dcp2;
679};
680
681struct hpf_work {
682 struct tasha_priv *tasha;
683 u8 decimator;
684 u8 hpf_cut_off_freq;
685 struct delayed_work dwork;
686};
687
688#define WCD9335_SPK_ANC_EN_DELAY_MS 350
689static int spk_anc_en_delay = WCD9335_SPK_ANC_EN_DELAY_MS;
690module_param(spk_anc_en_delay, int, 0664);
691MODULE_PARM_DESC(spk_anc_en_delay, "delay to enable anc in speaker path");
692
693struct spk_anc_work {
694 struct tasha_priv *tasha;
695 struct delayed_work dwork;
696};
697
698struct tx_mute_work {
699 struct tasha_priv *tasha;
700 u8 decimator;
701 struct delayed_work dwork;
702};
703
704struct tasha_priv {
705 struct device *dev;
706 struct wcd9xxx *wcd9xxx;
707
708 struct snd_soc_codec *codec;
709 u32 adc_count;
710 u32 rx_bias_count;
711 s32 dmic_0_1_clk_cnt;
712 s32 dmic_2_3_clk_cnt;
713 s32 dmic_4_5_clk_cnt;
714 s32 ldo_h_users;
715 s32 micb_ref[TASHA_MAX_MICBIAS];
716 s32 pullup_ref[TASHA_MAX_MICBIAS];
717
718 u32 anc_slot;
719 bool anc_func;
720
721 /* Vbat module */
722 struct wcd_vbat vbat;
723
724 /* cal info for codec */
725 struct fw_info *fw_data;
726
727 /*track tasha interface type*/
728 u8 intf_type;
729
730 /* num of slim ports required */
731 struct wcd9xxx_codec_dai_data dai[NUM_CODEC_DAIS];
732
733 /* SoundWire data structure */
734 struct tasha_swr_ctrl_data *swr_ctrl_data;
735 int nr;
736
737 /*compander*/
738 int comp_enabled[COMPANDER_MAX];
739
740 /* Maintain the status of AUX PGA */
741 int aux_pga_cnt;
742 u8 aux_l_gain;
743 u8 aux_r_gain;
744
745 bool spkr_pa_widget_on;
746 struct regulator *spkdrv_reg;
747 struct regulator *spkdrv2_reg;
748
749 bool mbhc_started;
750 /* class h specific data */
751 struct wcd_clsh_cdc_data clsh_d;
752
753 struct afe_param_cdc_slimbus_slave_cfg slimbus_slave_cfg;
754
755 /*
756 * list used to save/restore registers at start and
757 * end of impedance measurement
758 */
759 struct list_head reg_save_restore;
760
761 /* handle to cpe core */
762 struct wcd_cpe_core *cpe_core;
763 u32 current_cpe_clk_freq;
764 enum tasha_sido_voltage sido_voltage;
765 int sido_ccl_cnt;
766
767 u32 ana_rx_supplies;
768 /* Multiplication factor used for impedance detection */
769 int zdet_gain_mul_fact;
770
771 /* to track the status */
772 unsigned long status_mask;
773
774 struct work_struct tasha_add_child_devices_work;
775 struct wcd_swr_ctrl_platform_data swr_plat_data;
776
777 /* Port values for Rx and Tx codec_dai */
778 unsigned int rx_port_value[TASHA_RX_MAX];
779 unsigned int tx_port_value;
780
781 unsigned int vi_feed_value;
782 /* Tasha Interpolator Mode Select for EAR, HPH_L and HPH_R */
783 u32 hph_mode;
784
785 u16 prim_int_users[TASHA_NUM_INTERPOLATORS];
786 int spl_src_users[SPLINE_SRC_MAX];
787
788 struct wcd9xxx_resmgr_v2 *resmgr;
789 struct delayed_work power_gate_work;
790 struct mutex power_lock;
791 struct mutex sido_lock;
792
793 /* mbhc module */
794 struct wcd_mbhc mbhc;
795 struct blocking_notifier_head notifier;
796 struct mutex micb_lock;
797
798 struct clk *wcd_ext_clk;
799 struct clk *wcd_native_clk;
800 struct mutex swr_read_lock;
801 struct mutex swr_write_lock;
802 struct mutex swr_clk_lock;
803 int swr_clk_users;
804 int native_clk_users;
805 int (*zdet_gpio_cb)(struct snd_soc_codec *codec, bool high);
806
807 struct snd_info_entry *entry;
808 struct snd_info_entry *version_entry;
809 int power_active_ref;
810
811 struct on_demand_supply on_demand_list[ON_DEMAND_SUPPLIES_MAX];
812
813 int (*machine_codec_event_cb)(struct snd_soc_codec *codec,
814 enum wcd9335_codec_event);
815 int spkr_gain_offset;
816 int spkr_mode;
817 int ear_spkr_gain;
818 struct hpf_work tx_hpf_work[TASHA_NUM_DECIMATORS];
819 struct tx_mute_work tx_mute_dwork[TASHA_NUM_DECIMATORS];
820 struct spk_anc_work spk_anc_dwork;
821 struct mutex codec_mutex;
822 int hph_l_gain;
823 int hph_r_gain;
824 int rx_7_count;
825 int rx_8_count;
826 bool clk_mode;
827 bool clk_internal;
Asish Bhattacharya84f7f732017-07-25 16:29:27 +0530828 /* Lock to prevent multiple functions voting at same time */
829 struct mutex sb_clk_gear_lock;
830 /* Count for functions voting or un-voting */
831 u32 ref_count;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530832 /* Lock to protect mclk enablement */
833 struct mutex mclk_lock;
Meng Wang3b194492017-09-27 12:20:22 +0800834
835 struct platform_device *pdev_child_devices
836 [WCD9335_CHILD_DEVICES_MAX];
837 int child_count;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530838};
839
840static int tasha_codec_vote_max_bw(struct snd_soc_codec *codec,
841 bool vote);
842
843static const struct tasha_reg_mask_val tasha_spkr_default[] = {
844 {WCD9335_CDC_COMPANDER7_CTL3, 0x80, 0x80},
845 {WCD9335_CDC_COMPANDER8_CTL3, 0x80, 0x80},
846 {WCD9335_CDC_COMPANDER7_CTL7, 0x01, 0x01},
847 {WCD9335_CDC_COMPANDER8_CTL7, 0x01, 0x01},
Xiaojun Sangc9af54a2018-02-12 19:03:02 +0800848 {WCD9335_CDC_BOOST0_BOOST_CTL, 0x7C, 0x58},
849 {WCD9335_CDC_BOOST1_BOOST_CTL, 0x7C, 0x58},
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530850};
851
852static const struct tasha_reg_mask_val tasha_spkr_mode1[] = {
853 {WCD9335_CDC_COMPANDER7_CTL3, 0x80, 0x00},
854 {WCD9335_CDC_COMPANDER8_CTL3, 0x80, 0x00},
855 {WCD9335_CDC_COMPANDER7_CTL7, 0x01, 0x00},
856 {WCD9335_CDC_COMPANDER8_CTL7, 0x01, 0x00},
857 {WCD9335_CDC_BOOST0_BOOST_CTL, 0x7C, 0x44},
858 {WCD9335_CDC_BOOST1_BOOST_CTL, 0x7C, 0x44},
859};
860
861/**
862 * tasha_set_spkr_gain_offset - offset the speaker path
863 * gain with the given offset value.
864 *
865 * @codec: codec instance
866 * @offset: Indicates speaker path gain offset value.
867 *
868 * Returns 0 on success or -EINVAL on error.
869 */
870int tasha_set_spkr_gain_offset(struct snd_soc_codec *codec, int offset)
871{
872 struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec);
873
874 if (!priv)
875 return -EINVAL;
876
877 priv->spkr_gain_offset = offset;
878 return 0;
879}
880EXPORT_SYMBOL(tasha_set_spkr_gain_offset);
881
882/**
883 * tasha_set_spkr_mode - Configures speaker compander and smartboost
884 * settings based on speaker mode.
885 *
886 * @codec: codec instance
887 * @mode: Indicates speaker configuration mode.
888 *
889 * Returns 0 on success or -EINVAL on error.
890 */
891int tasha_set_spkr_mode(struct snd_soc_codec *codec, int mode)
892{
893 struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec);
894 int i;
895 const struct tasha_reg_mask_val *regs;
896 int size;
897
898 if (!priv)
899 return -EINVAL;
900
901 switch (mode) {
902 case SPKR_MODE_1:
903 regs = tasha_spkr_mode1;
904 size = ARRAY_SIZE(tasha_spkr_mode1);
905 break;
906 default:
907 regs = tasha_spkr_default;
908 size = ARRAY_SIZE(tasha_spkr_default);
909 break;
910 }
911
912 priv->spkr_mode = mode;
913 for (i = 0; i < size; i++)
914 snd_soc_update_bits(codec, regs[i].reg,
915 regs[i].mask, regs[i].val);
916 return 0;
917}
918EXPORT_SYMBOL(tasha_set_spkr_mode);
919
920static void tasha_enable_sido_buck(struct snd_soc_codec *codec)
921{
922 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
923
924 snd_soc_update_bits(codec, WCD9335_ANA_RCO, 0x80, 0x80);
925 snd_soc_update_bits(codec, WCD9335_ANA_BUCK_CTL, 0x02, 0x02);
926 /* 100us sleep needed after IREF settings */
927 usleep_range(100, 110);
928 snd_soc_update_bits(codec, WCD9335_ANA_BUCK_CTL, 0x04, 0x04);
929 /* 100us sleep needed after VREF settings */
930 usleep_range(100, 110);
931 tasha->resmgr->sido_input_src = SIDO_SOURCE_RCO_BG;
932}
933
934static void tasha_cdc_sido_ccl_enable(struct tasha_priv *tasha, bool ccl_flag)
935{
936 struct snd_soc_codec *codec = tasha->codec;
937
938 if (!codec)
939 return;
940
941 if (!TASHA_IS_2_0(tasha->wcd9xxx)) {
942 dev_dbg(codec->dev, "%s: tasha version < 2p0, return\n",
943 __func__);
944 return;
945 }
946 dev_dbg(codec->dev, "%s: sido_ccl_cnt=%d, ccl_flag:%d\n",
947 __func__, tasha->sido_ccl_cnt, ccl_flag);
948 if (ccl_flag) {
949 if (++tasha->sido_ccl_cnt == 1)
950 snd_soc_update_bits(codec,
951 WCD9335_SIDO_SIDO_CCL_10, 0xFF, 0x6E);
952 } else {
953 if (tasha->sido_ccl_cnt == 0) {
954 dev_dbg(codec->dev, "%s: sido_ccl already disabled\n",
955 __func__);
956 return;
957 }
958 if (--tasha->sido_ccl_cnt == 0)
959 snd_soc_update_bits(codec,
960 WCD9335_SIDO_SIDO_CCL_10, 0xFF, 0x02);
961 }
962}
963
964static bool tasha_cdc_is_svs_enabled(struct tasha_priv *tasha)
965{
966 if (TASHA_IS_2_0(tasha->wcd9xxx) &&
967 svs_scaling_enabled)
968 return true;
969
970 return false;
971}
972
973static int tasha_cdc_req_mclk_enable(struct tasha_priv *tasha,
974 bool enable)
975{
976 int ret = 0;
977
978 mutex_lock(&tasha->mclk_lock);
979 if (enable) {
980 tasha_cdc_sido_ccl_enable(tasha, true);
981 ret = clk_prepare_enable(tasha->wcd_ext_clk);
982 if (ret) {
983 dev_err(tasha->dev, "%s: ext clk enable failed\n",
984 __func__);
985 goto unlock_mutex;
986 }
987 /* get BG */
988 wcd_resmgr_enable_master_bias(tasha->resmgr);
989 /* get MCLK */
990 wcd_resmgr_enable_clk_block(tasha->resmgr, WCD_CLK_MCLK);
991 } else {
992 /* put MCLK */
993 wcd_resmgr_disable_clk_block(tasha->resmgr, WCD_CLK_MCLK);
994 /* put BG */
995 wcd_resmgr_disable_master_bias(tasha->resmgr);
996 clk_disable_unprepare(tasha->wcd_ext_clk);
997 tasha_cdc_sido_ccl_enable(tasha, false);
998 }
999unlock_mutex:
1000 mutex_unlock(&tasha->mclk_lock);
1001 return ret;
1002}
1003
1004static int tasha_cdc_check_sido_value(enum tasha_sido_voltage req_mv)
1005{
1006 if ((req_mv != SIDO_VOLTAGE_SVS_MV) &&
1007 (req_mv != SIDO_VOLTAGE_NOMINAL_MV))
1008 return -EINVAL;
1009
1010 return 0;
1011}
1012
1013static void tasha_codec_apply_sido_voltage(
1014 struct tasha_priv *tasha,
1015 enum tasha_sido_voltage req_mv)
1016{
1017 u32 vout_d_val;
1018 struct snd_soc_codec *codec = tasha->codec;
1019 int ret;
1020
1021 if (!codec)
1022 return;
1023
1024 if (!tasha_cdc_is_svs_enabled(tasha))
1025 return;
1026
1027 if ((sido_buck_svs_voltage != SIDO_VOLTAGE_SVS_MV) &&
1028 (sido_buck_svs_voltage != SIDO_VOLTAGE_NOMINAL_MV))
1029 sido_buck_svs_voltage = SIDO_VOLTAGE_SVS_MV;
1030
1031 ret = tasha_cdc_check_sido_value(req_mv);
1032 if (ret < 0) {
1033 dev_dbg(codec->dev, "%s: requested mv=%d not in range\n",
1034 __func__, req_mv);
1035 return;
1036 }
1037 if (req_mv == tasha->sido_voltage) {
1038 dev_dbg(codec->dev, "%s: Already at requested mv=%d\n",
1039 __func__, req_mv);
1040 return;
1041 }
1042 if (req_mv == sido_buck_svs_voltage) {
1043 if (test_bit(AUDIO_NOMINAL, &tasha->status_mask) ||
1044 test_bit(CPE_NOMINAL, &tasha->status_mask)) {
1045 dev_dbg(codec->dev,
1046 "%s: nominal client running, status_mask=%lu\n",
1047 __func__, tasha->status_mask);
1048 return;
1049 }
1050 }
1051 /* compute the vout_d step value */
1052 vout_d_val = CALCULATE_VOUT_D(req_mv);
1053 snd_soc_write(codec, WCD9335_ANA_BUCK_VOUT_D, vout_d_val & 0xFF);
1054 snd_soc_update_bits(codec, WCD9335_ANA_BUCK_CTL, 0x80, 0x80);
1055
1056 /* 1 msec sleep required after SIDO Vout_D voltage change */
1057 usleep_range(1000, 1100);
1058 tasha->sido_voltage = req_mv;
1059 dev_dbg(codec->dev,
1060 "%s: updated SIDO buck Vout_D to %d, vout_d step = %u\n",
1061 __func__, tasha->sido_voltage, vout_d_val);
1062
1063 snd_soc_update_bits(codec, WCD9335_ANA_BUCK_CTL,
1064 0x80, 0x00);
1065}
1066
1067static int tasha_codec_update_sido_voltage(
1068 struct tasha_priv *tasha,
1069 enum tasha_sido_voltage req_mv)
1070{
1071 int ret = 0;
1072
1073 if (!tasha_cdc_is_svs_enabled(tasha))
1074 return ret;
1075
1076 mutex_lock(&tasha->sido_lock);
1077 /* enable mclk before setting SIDO voltage */
1078 ret = tasha_cdc_req_mclk_enable(tasha, true);
1079 if (ret) {
1080 dev_err(tasha->dev, "%s: ext clk enable failed\n",
1081 __func__);
1082 goto err;
1083 }
1084 tasha_codec_apply_sido_voltage(tasha, req_mv);
1085 tasha_cdc_req_mclk_enable(tasha, false);
1086
1087err:
1088 mutex_unlock(&tasha->sido_lock);
1089 return ret;
1090}
1091
1092int tasha_enable_efuse_sensing(struct snd_soc_codec *codec)
1093{
1094 struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec);
1095
1096 tasha_cdc_mclk_enable(codec, true, false);
1097
1098 if (!TASHA_IS_2_0(priv->wcd9xxx))
1099 snd_soc_update_bits(codec, WCD9335_CHIP_TIER_CTRL_EFUSE_CTL,
1100 0x1E, 0x02);
1101 snd_soc_update_bits(codec, WCD9335_CHIP_TIER_CTRL_EFUSE_CTL,
1102 0x01, 0x01);
1103 /*
1104 * 5ms sleep required after enabling efuse control
1105 * before checking the status.
1106 */
1107 usleep_range(5000, 5500);
1108 if (!(snd_soc_read(codec, WCD9335_CHIP_TIER_CTRL_EFUSE_STATUS) & 0x01))
1109 WARN(1, "%s: Efuse sense is not complete\n", __func__);
1110
1111 if (TASHA_IS_2_0(priv->wcd9xxx)) {
1112 if (!(snd_soc_read(codec,
1113 WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT0) & 0x40))
1114 snd_soc_update_bits(codec, WCD9335_HPH_R_ATEST,
1115 0x04, 0x00);
1116 tasha_enable_sido_buck(codec);
1117 }
1118
1119 tasha_cdc_mclk_enable(codec, false, false);
1120
1121 return 0;
1122}
1123EXPORT_SYMBOL(tasha_enable_efuse_sensing);
1124
1125void *tasha_get_afe_config(struct snd_soc_codec *codec,
1126 enum afe_config_type config_type)
1127{
1128 struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec);
1129
1130 switch (config_type) {
1131 case AFE_SLIMBUS_SLAVE_CONFIG:
1132 return &priv->slimbus_slave_cfg;
1133 case AFE_CDC_REGISTERS_CONFIG:
1134 return &tasha_audio_reg_cfg;
1135 case AFE_SLIMBUS_SLAVE_PORT_CONFIG:
1136 return &tasha_slimbus_slave_port_cfg;
1137 case AFE_AANC_VERSION:
1138 return &tasha_cdc_aanc_version;
1139 case AFE_CLIP_BANK_SEL:
1140 return NULL;
1141 case AFE_CDC_CLIP_REGISTERS_CONFIG:
1142 return NULL;
1143 case AFE_CDC_REGISTER_PAGE_CONFIG:
1144 return &tasha_cdc_reg_page_cfg;
1145 default:
1146 dev_err(codec->dev, "%s: Unknown config_type 0x%x\n",
1147 __func__, config_type);
1148 return NULL;
1149 }
1150}
1151EXPORT_SYMBOL(tasha_get_afe_config);
1152
1153/*
1154 * tasha_event_register: Registers a machine driver callback
1155 * function with codec private data for post ADSP sub-system
1156 * restart (SSR). This callback function will be called from
1157 * codec driver once codec comes out of reset after ADSP SSR.
1158 *
1159 * @machine_event_cb: callback function from machine driver
1160 * @codec: Codec instance
1161 *
1162 * Return: none
1163 */
1164void tasha_event_register(
1165 int (*machine_event_cb)(struct snd_soc_codec *codec,
1166 enum wcd9335_codec_event),
1167 struct snd_soc_codec *codec)
1168{
1169 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
1170
1171 if (tasha)
1172 tasha->machine_codec_event_cb = machine_event_cb;
1173 else
1174 dev_dbg(codec->dev, "%s: Invalid tasha_priv data\n", __func__);
1175}
1176EXPORT_SYMBOL(tasha_event_register);
1177
1178static int tasha_mbhc_request_irq(struct snd_soc_codec *codec,
1179 int irq, irq_handler_t handler,
1180 const char *name, void *data)
1181{
1182 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
1183 struct wcd9xxx *wcd9xxx = tasha->wcd9xxx;
1184 struct wcd9xxx_core_resource *core_res =
1185 &wcd9xxx->core_res;
1186
1187 return wcd9xxx_request_irq(core_res, irq, handler, name, data);
1188}
1189
1190static void tasha_mbhc_irq_control(struct snd_soc_codec *codec,
1191 int irq, bool enable)
1192{
1193 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
1194 struct wcd9xxx *wcd9xxx = tasha->wcd9xxx;
1195 struct wcd9xxx_core_resource *core_res =
1196 &wcd9xxx->core_res;
1197 if (enable)
1198 wcd9xxx_enable_irq(core_res, irq);
1199 else
1200 wcd9xxx_disable_irq(core_res, irq);
1201}
1202
1203static int tasha_mbhc_free_irq(struct snd_soc_codec *codec,
1204 int irq, void *data)
1205{
1206 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
1207 struct wcd9xxx *wcd9xxx = tasha->wcd9xxx;
1208 struct wcd9xxx_core_resource *core_res =
1209 &wcd9xxx->core_res;
1210
1211 wcd9xxx_free_irq(core_res, irq, data);
1212 return 0;
1213}
1214
1215static void tasha_mbhc_clk_setup(struct snd_soc_codec *codec,
1216 bool enable)
1217{
1218 if (enable)
1219 snd_soc_update_bits(codec, WCD9335_MBHC_CTL_1,
1220 0x80, 0x80);
1221 else
1222 snd_soc_update_bits(codec, WCD9335_MBHC_CTL_1,
1223 0x80, 0x00);
1224}
1225
1226static int tasha_mbhc_btn_to_num(struct snd_soc_codec *codec)
1227{
1228 return snd_soc_read(codec, WCD9335_ANA_MBHC_RESULT_3) & 0x7;
1229}
1230
1231static void tasha_mbhc_mbhc_bias_control(struct snd_soc_codec *codec,
1232 bool enable)
1233{
1234 if (enable)
1235 snd_soc_update_bits(codec, WCD9335_ANA_MBHC_ELECT,
1236 0x01, 0x01);
1237 else
1238 snd_soc_update_bits(codec, WCD9335_ANA_MBHC_ELECT,
1239 0x01, 0x00);
1240}
1241
1242static void tasha_mbhc_program_btn_thr(struct snd_soc_codec *codec,
1243 s16 *btn_low, s16 *btn_high,
1244 int num_btn, bool is_micbias)
1245{
1246 int i;
1247 int vth;
1248
1249 if (num_btn > WCD_MBHC_DEF_BUTTONS) {
1250 dev_err(codec->dev, "%s: invalid number of buttons: %d\n",
1251 __func__, num_btn);
1252 return;
1253 }
1254 /*
1255 * Tasha just needs one set of thresholds for button detection
1256 * due to micbias voltage ramp to pullup upon button press. So
1257 * btn_low and is_micbias are ignored and always program button
1258 * thresholds using btn_high.
1259 */
1260 for (i = 0; i < num_btn; i++) {
1261 vth = ((btn_high[i] * 2) / 25) & 0x3F;
1262 snd_soc_update_bits(codec, WCD9335_ANA_MBHC_BTN0 + i,
1263 0xFC, vth << 2);
1264 dev_dbg(codec->dev, "%s: btn_high[%d]: %d, vth: %d\n",
1265 __func__, i, btn_high[i], vth);
1266 }
1267}
1268
1269static bool tasha_mbhc_lock_sleep(struct wcd_mbhc *mbhc, bool lock)
1270{
1271 struct snd_soc_codec *codec = mbhc->codec;
1272 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
1273 struct wcd9xxx *wcd9xxx = tasha->wcd9xxx;
1274 struct wcd9xxx_core_resource *core_res =
1275 &wcd9xxx->core_res;
1276 if (lock)
1277 return wcd9xxx_lock_sleep(core_res);
1278 else {
1279 wcd9xxx_unlock_sleep(core_res);
1280 return 0;
1281 }
1282}
1283
1284static int tasha_mbhc_register_notifier(struct wcd_mbhc *mbhc,
1285 struct notifier_block *nblock,
1286 bool enable)
1287{
1288 struct snd_soc_codec *codec = mbhc->codec;
1289 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
1290
1291 if (enable)
1292 return blocking_notifier_chain_register(&tasha->notifier,
1293 nblock);
1294 else
1295 return blocking_notifier_chain_unregister(&tasha->notifier,
1296 nblock);
1297}
1298
1299static bool tasha_mbhc_micb_en_status(struct wcd_mbhc *mbhc, int micb_num)
1300{
1301 u8 val;
1302
1303 if (micb_num == MIC_BIAS_2) {
1304 val = (snd_soc_read(mbhc->codec, WCD9335_ANA_MICB2) >> 6);
1305 if (val == 0x01)
1306 return true;
1307 }
1308 return false;
1309}
1310
1311static bool tasha_mbhc_hph_pa_on_status(struct snd_soc_codec *codec)
1312{
1313 return (snd_soc_read(codec, WCD9335_ANA_HPH) & 0xC0) ? true : false;
1314}
1315
1316static void tasha_mbhc_hph_l_pull_up_control(struct snd_soc_codec *codec,
1317 enum mbhc_hs_pullup_iref pull_up_cur)
1318{
1319 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
1320
1321 if (!tasha)
1322 return;
1323
1324 /* Default pull up current to 2uA */
1325 if (pull_up_cur < I_OFF || pull_up_cur > I_3P0_UA ||
1326 pull_up_cur == I_DEFAULT)
1327 pull_up_cur = I_2P0_UA;
1328
1329 dev_dbg(codec->dev, "%s: HS pull up current:%d\n",
1330 __func__, pull_up_cur);
1331
1332 if (TASHA_IS_2_0(tasha->wcd9xxx))
1333 snd_soc_update_bits(codec, WCD9335_MBHC_PLUG_DETECT_CTL,
1334 0xC0, pull_up_cur << 6);
1335 else
1336 snd_soc_update_bits(codec, WCD9335_MBHC_PLUG_DETECT_CTL,
1337 0xC0, 0x40);
1338}
1339
1340static int tasha_enable_ext_mb_source(struct wcd_mbhc *mbhc,
1341 bool turn_on)
1342{
1343 struct snd_soc_codec *codec = mbhc->codec;
1344 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
1345 int ret = 0;
1346 struct on_demand_supply *supply;
1347
1348 if (!tasha)
1349 return -EINVAL;
1350
1351 supply = &tasha->on_demand_list[ON_DEMAND_MICBIAS];
1352 if (!supply->supply) {
1353 dev_dbg(codec->dev, "%s: warning supply not present ond for %s\n",
1354 __func__, "onDemand Micbias");
1355 return ret;
1356 }
1357
1358 dev_dbg(codec->dev, "%s turn_on: %d count: %d\n", __func__, turn_on,
1359 supply->ondemand_supply_count);
1360
1361 if (turn_on) {
1362 if (!(supply->ondemand_supply_count)) {
1363 ret = snd_soc_dapm_force_enable_pin(
1364 snd_soc_codec_get_dapm(codec),
1365 "MICBIAS_REGULATOR");
1366 snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec));
1367 }
1368 supply->ondemand_supply_count++;
1369 } else {
1370 if (supply->ondemand_supply_count > 0)
1371 supply->ondemand_supply_count--;
1372 if (!(supply->ondemand_supply_count)) {
1373 ret = snd_soc_dapm_disable_pin(
1374 snd_soc_codec_get_dapm(codec),
1375 "MICBIAS_REGULATOR");
1376 snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec));
1377 }
1378 }
1379
1380 if (ret)
1381 dev_err(codec->dev, "%s: Failed to %s external micbias source\n",
1382 __func__, turn_on ? "enable" : "disabled");
1383 else
1384 dev_dbg(codec->dev, "%s: %s external micbias source\n",
1385 __func__, turn_on ? "Enabled" : "Disabled");
1386
1387 return ret;
1388}
1389
1390static int tasha_micbias_control(struct snd_soc_codec *codec,
1391 int micb_num,
1392 int req, bool is_dapm)
1393{
1394 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
1395 int micb_index = micb_num - 1;
1396 u16 micb_reg;
1397 int pre_off_event = 0, post_off_event = 0;
1398 int post_on_event = 0, post_dapm_off = 0;
1399 int post_dapm_on = 0;
1400
1401 if ((micb_index < 0) || (micb_index > TASHA_MAX_MICBIAS - 1)) {
1402 dev_err(codec->dev, "%s: Invalid micbias index, micb_ind:%d\n",
1403 __func__, micb_index);
1404 return -EINVAL;
1405 }
1406 switch (micb_num) {
1407 case MIC_BIAS_1:
1408 micb_reg = WCD9335_ANA_MICB1;
1409 break;
1410 case MIC_BIAS_2:
1411 micb_reg = WCD9335_ANA_MICB2;
1412 pre_off_event = WCD_EVENT_PRE_MICBIAS_2_OFF;
1413 post_off_event = WCD_EVENT_POST_MICBIAS_2_OFF;
1414 post_on_event = WCD_EVENT_POST_MICBIAS_2_ON;
1415 post_dapm_on = WCD_EVENT_POST_DAPM_MICBIAS_2_ON;
1416 post_dapm_off = WCD_EVENT_POST_DAPM_MICBIAS_2_OFF;
1417 break;
1418 case MIC_BIAS_3:
1419 micb_reg = WCD9335_ANA_MICB3;
1420 break;
1421 case MIC_BIAS_4:
1422 micb_reg = WCD9335_ANA_MICB4;
1423 break;
1424 default:
1425 dev_err(codec->dev, "%s: Invalid micbias number: %d\n",
1426 __func__, micb_num);
1427 return -EINVAL;
1428 }
1429 mutex_lock(&tasha->micb_lock);
1430
1431 switch (req) {
1432 case MICB_PULLUP_ENABLE:
1433 tasha->pullup_ref[micb_index]++;
1434 if ((tasha->pullup_ref[micb_index] == 1) &&
1435 (tasha->micb_ref[micb_index] == 0))
1436 snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80);
1437 break;
1438 case MICB_PULLUP_DISABLE:
1439 if (tasha->pullup_ref[micb_index] > 0)
1440 tasha->pullup_ref[micb_index]--;
1441 if ((tasha->pullup_ref[micb_index] == 0) &&
1442 (tasha->micb_ref[micb_index] == 0))
1443 snd_soc_update_bits(codec, micb_reg, 0xC0, 0x00);
1444 break;
1445 case MICB_ENABLE:
1446 tasha->micb_ref[micb_index]++;
1447 if (tasha->micb_ref[micb_index] == 1) {
1448 snd_soc_update_bits(codec, micb_reg, 0xC0, 0x40);
1449 if (post_on_event)
1450 blocking_notifier_call_chain(&tasha->notifier,
1451 post_on_event, &tasha->mbhc);
1452 }
1453 if (is_dapm && post_dapm_on)
1454 blocking_notifier_call_chain(&tasha->notifier,
1455 post_dapm_on, &tasha->mbhc);
1456 break;
1457 case MICB_DISABLE:
1458 if (tasha->micb_ref[micb_index] > 0)
1459 tasha->micb_ref[micb_index]--;
1460 if ((tasha->micb_ref[micb_index] == 0) &&
1461 (tasha->pullup_ref[micb_index] > 0))
1462 snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80);
1463 else if ((tasha->micb_ref[micb_index] == 0) &&
1464 (tasha->pullup_ref[micb_index] == 0)) {
1465 if (pre_off_event)
1466 blocking_notifier_call_chain(&tasha->notifier,
1467 pre_off_event, &tasha->mbhc);
1468 snd_soc_update_bits(codec, micb_reg, 0xC0, 0x00);
1469 if (post_off_event)
1470 blocking_notifier_call_chain(&tasha->notifier,
1471 post_off_event, &tasha->mbhc);
1472 }
1473 if (is_dapm && post_dapm_off)
1474 blocking_notifier_call_chain(&tasha->notifier,
1475 post_dapm_off, &tasha->mbhc);
1476 break;
1477 };
1478
1479 dev_dbg(codec->dev, "%s: micb_num:%d, micb_ref: %d, pullup_ref: %d\n",
1480 __func__, micb_num, tasha->micb_ref[micb_index],
1481 tasha->pullup_ref[micb_index]);
1482
1483 mutex_unlock(&tasha->micb_lock);
1484
1485 return 0;
1486}
1487
1488static int tasha_mbhc_request_micbias(struct snd_soc_codec *codec,
1489 int micb_num, int req)
1490{
1491 int ret;
1492
1493 /*
1494 * If micbias is requested, make sure that there
1495 * is vote to enable mclk
1496 */
1497 if (req == MICB_ENABLE)
1498 tasha_cdc_mclk_enable(codec, true, false);
1499
1500 ret = tasha_micbias_control(codec, micb_num, req, false);
1501
1502 /*
1503 * Release vote for mclk while requesting for
1504 * micbias disable
1505 */
1506 if (req == MICB_DISABLE)
1507 tasha_cdc_mclk_enable(codec, false, false);
1508
1509 return ret;
1510}
1511
1512static void tasha_mbhc_micb_ramp_control(struct snd_soc_codec *codec,
1513 bool enable)
1514{
1515 if (enable) {
1516 snd_soc_update_bits(codec, WCD9335_ANA_MICB2_RAMP,
1517 0x1C, 0x0C);
1518 snd_soc_update_bits(codec, WCD9335_ANA_MICB2_RAMP,
1519 0x80, 0x80);
1520 } else {
1521 snd_soc_update_bits(codec, WCD9335_ANA_MICB2_RAMP,
1522 0x80, 0x00);
1523 snd_soc_update_bits(codec, WCD9335_ANA_MICB2_RAMP,
1524 0x1C, 0x00);
1525 }
1526}
1527
1528static struct firmware_cal *tasha_get_hwdep_fw_cal(struct wcd_mbhc *mbhc,
1529 enum wcd_cal_type type)
1530{
1531 struct tasha_priv *tasha;
1532 struct firmware_cal *hwdep_cal;
1533 struct snd_soc_codec *codec = mbhc->codec;
1534
1535 if (!codec) {
1536 pr_err("%s: NULL codec pointer\n", __func__);
1537 return NULL;
1538 }
1539 tasha = snd_soc_codec_get_drvdata(codec);
1540 hwdep_cal = wcdcal_get_fw_cal(tasha->fw_data, type);
1541 if (!hwdep_cal)
1542 dev_err(codec->dev, "%s: cal not sent by %d\n",
1543 __func__, type);
1544
1545 return hwdep_cal;
1546}
1547
1548static int tasha_mbhc_micb_adjust_voltage(struct snd_soc_codec *codec,
1549 int req_volt,
1550 int micb_num)
1551{
1552 int cur_vout_ctl, req_vout_ctl;
1553 int micb_reg, micb_val, micb_en;
1554
1555 switch (micb_num) {
1556 case MIC_BIAS_1:
1557 micb_reg = WCD9335_ANA_MICB1;
1558 break;
1559 case MIC_BIAS_2:
1560 micb_reg = WCD9335_ANA_MICB2;
1561 break;
1562 case MIC_BIAS_3:
1563 micb_reg = WCD9335_ANA_MICB3;
1564 break;
1565 case MIC_BIAS_4:
1566 micb_reg = WCD9335_ANA_MICB4;
1567 break;
1568 default:
1569 return -EINVAL;
1570 }
1571
1572 /*
1573 * If requested micbias voltage is same as current micbias
1574 * voltage, then just return. Otherwise, adjust voltage as
1575 * per requested value. If micbias is already enabled, then
1576 * to avoid slow micbias ramp-up or down enable pull-up
1577 * momentarily, change the micbias value and then re-enable
1578 * micbias.
1579 */
1580 micb_val = snd_soc_read(codec, micb_reg);
1581 micb_en = (micb_val & 0xC0) >> 6;
1582 cur_vout_ctl = micb_val & 0x3F;
1583
1584 req_vout_ctl = wcd9335_get_micb_vout_ctl_val(req_volt);
1585 if (req_vout_ctl < 0)
1586 return -EINVAL;
1587 if (cur_vout_ctl == req_vout_ctl)
1588 return 0;
1589
1590 dev_dbg(codec->dev, "%s: micb_num: %d, cur_mv: %d, req_mv: %d, micb_en: %d\n",
1591 __func__, micb_num, WCD_VOUT_CTL_TO_MICB(cur_vout_ctl),
1592 req_volt, micb_en);
1593
1594 if (micb_en == 0x1)
1595 snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80);
1596
1597 snd_soc_update_bits(codec, micb_reg, 0x3F, req_vout_ctl);
1598
1599 if (micb_en == 0x1) {
1600 snd_soc_update_bits(codec, micb_reg, 0xC0, 0x40);
1601 /*
1602 * Add 2ms delay as per HW requirement after enabling
1603 * micbias
1604 */
1605 usleep_range(2000, 2100);
1606 }
1607
1608 return 0;
1609}
1610
1611static int tasha_mbhc_micb_ctrl_threshold_mic(struct snd_soc_codec *codec,
1612 int micb_num, bool req_en)
1613{
1614 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
1615 struct wcd9xxx_pdata *pdata = dev_get_platdata(codec->dev->parent);
1616 int rc, micb_mv;
1617
1618 if (micb_num != MIC_BIAS_2)
1619 return -EINVAL;
1620
1621 /*
1622 * If device tree micbias level is already above the minimum
1623 * voltage needed to detect threshold microphone, then do
1624 * not change the micbias, just return.
1625 */
1626 if (pdata->micbias.micb2_mv >= WCD_MBHC_THR_HS_MICB_MV)
1627 return 0;
1628
1629 micb_mv = req_en ? WCD_MBHC_THR_HS_MICB_MV : pdata->micbias.micb2_mv;
1630
1631 mutex_lock(&tasha->micb_lock);
1632 rc = tasha_mbhc_micb_adjust_voltage(codec, micb_mv, MIC_BIAS_2);
1633 mutex_unlock(&tasha->micb_lock);
1634
1635 return rc;
1636}
1637
1638static inline void tasha_mbhc_get_result_params(struct wcd9xxx *wcd9xxx,
1639 s16 *d1_a, u16 noff,
1640 int32_t *zdet)
1641{
1642 int i;
1643 int val, val1;
1644 s16 c1;
1645 s32 x1, d1;
1646 int32_t denom;
1647 int minCode_param[] = {
1648 3277, 1639, 820, 410, 205, 103, 52, 26
1649 };
1650
1651 regmap_update_bits(wcd9xxx->regmap, WCD9335_ANA_MBHC_ZDET, 0x20, 0x20);
1652 for (i = 0; i < TASHA_ZDET_NUM_MEASUREMENTS; i++) {
1653 regmap_read(wcd9xxx->regmap, WCD9335_ANA_MBHC_RESULT_2, &val);
1654 if (val & 0x80)
1655 break;
1656 }
1657 val = val << 0x8;
1658 regmap_read(wcd9xxx->regmap, WCD9335_ANA_MBHC_RESULT_1, &val1);
1659 val |= val1;
1660 regmap_update_bits(wcd9xxx->regmap, WCD9335_ANA_MBHC_ZDET, 0x20, 0x00);
1661 x1 = TASHA_MBHC_GET_X1(val);
1662 c1 = TASHA_MBHC_GET_C1(val);
1663 /* If ramp is not complete, give additional 5ms */
1664 if ((c1 < 2) && x1)
1665 usleep_range(5000, 5050);
1666
1667 if (!c1 || !x1) {
1668 dev_dbg(wcd9xxx->dev,
1669 "%s: Impedance detect ramp error, c1=%d, x1=0x%x\n",
1670 __func__, c1, x1);
1671 goto ramp_down;
1672 }
1673 d1 = d1_a[c1];
1674 denom = (x1 * d1) - (1 << (14 - noff));
1675 if (denom > 0)
1676 *zdet = (TASHA_MBHC_ZDET_CONST * 1000) / denom;
1677 else if (x1 < minCode_param[noff])
1678 *zdet = TASHA_ZDET_FLOATING_IMPEDANCE;
1679
1680 dev_dbg(wcd9xxx->dev, "%s: d1=%d, c1=%d, x1=0x%x, z_val=%d(milliOhm)\n",
1681 __func__, d1, c1, x1, *zdet);
1682ramp_down:
1683 i = 0;
1684 while (x1) {
1685 regmap_bulk_read(wcd9xxx->regmap,
1686 WCD9335_ANA_MBHC_RESULT_1, (u8 *)&val, 2);
1687 x1 = TASHA_MBHC_GET_X1(val);
1688 i++;
1689 if (i == TASHA_ZDET_NUM_MEASUREMENTS)
1690 break;
1691 }
1692}
1693
1694/*
1695 * tasha_mbhc_zdet_gpio_ctrl: Register callback function for
1696 * controlling the switch on hifi amps. Default switch state
1697 * will put a 51ohm load in parallel to the hph load. So,
1698 * impedance detection function will pull the gpio high
1699 * to make the switch open.
1700 *
1701 * @zdet_gpio_cb: callback function from machine driver
1702 * @codec: Codec instance
1703 *
1704 * Return: none
1705 */
1706void tasha_mbhc_zdet_gpio_ctrl(
1707 int (*zdet_gpio_cb)(struct snd_soc_codec *codec, bool high),
1708 struct snd_soc_codec *codec)
1709{
1710 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
1711
1712 tasha->zdet_gpio_cb = zdet_gpio_cb;
1713}
1714EXPORT_SYMBOL(tasha_mbhc_zdet_gpio_ctrl);
1715
1716static void tasha_mbhc_zdet_ramp(struct snd_soc_codec *codec,
1717 struct tasha_mbhc_zdet_param *zdet_param,
1718 int32_t *zl, int32_t *zr, s16 *d1_a)
1719{
1720 struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent);
1721 int32_t zdet = 0;
1722
1723 snd_soc_update_bits(codec, WCD9335_MBHC_ZDET_ANA_CTL, 0x70,
1724 zdet_param->ldo_ctl << 4);
1725 snd_soc_update_bits(codec, WCD9335_ANA_MBHC_BTN5, 0xFC,
1726 zdet_param->btn5);
1727 snd_soc_update_bits(codec, WCD9335_ANA_MBHC_BTN6, 0xFC,
1728 zdet_param->btn6);
1729 snd_soc_update_bits(codec, WCD9335_ANA_MBHC_BTN7, 0xFC,
1730 zdet_param->btn7);
1731 snd_soc_update_bits(codec, WCD9335_MBHC_ZDET_ANA_CTL, 0x0F,
1732 zdet_param->noff);
1733 snd_soc_update_bits(codec, WCD9335_MBHC_ZDET_RAMP_CTL, 0x0F,
1734 zdet_param->nshift);
1735
1736 if (!zl)
1737 goto z_right;
1738 /* Start impedance measurement for HPH_L */
1739 regmap_update_bits(wcd9xxx->regmap,
1740 WCD9335_ANA_MBHC_ZDET, 0x80, 0x80);
1741 dev_dbg(wcd9xxx->dev, "%s: ramp for HPH_L, noff = %d\n",
1742 __func__, zdet_param->noff);
1743 tasha_mbhc_get_result_params(wcd9xxx, d1_a, zdet_param->noff, &zdet);
1744 regmap_update_bits(wcd9xxx->regmap,
1745 WCD9335_ANA_MBHC_ZDET, 0x80, 0x00);
1746
1747 *zl = zdet;
1748
1749z_right:
1750 if (!zr)
1751 return;
1752 /* Start impedance measurement for HPH_R */
1753 regmap_update_bits(wcd9xxx->regmap,
1754 WCD9335_ANA_MBHC_ZDET, 0x40, 0x40);
1755 dev_dbg(wcd9xxx->dev, "%s: ramp for HPH_R, noff = %d\n",
1756 __func__, zdet_param->noff);
1757 tasha_mbhc_get_result_params(wcd9xxx, d1_a, zdet_param->noff, &zdet);
1758 regmap_update_bits(wcd9xxx->regmap,
1759 WCD9335_ANA_MBHC_ZDET, 0x40, 0x00);
1760
1761 *zr = zdet;
1762}
1763
1764static inline void tasha_wcd_mbhc_qfuse_cal(struct snd_soc_codec *codec,
1765 int32_t *z_val, int flag_l_r)
1766{
1767 s16 q1;
1768 int q1_cal;
1769
1770 if (*z_val < (TASHA_ZDET_VAL_400/1000))
1771 q1 = snd_soc_read(codec,
1772 WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT1 + (2 * flag_l_r));
1773 else
1774 q1 = snd_soc_read(codec,
1775 WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT2 + (2 * flag_l_r));
1776 if (q1 & 0x80)
1777 q1_cal = (10000 - ((q1 & 0x7F) * 25));
1778 else
1779 q1_cal = (10000 + (q1 * 25));
1780 if (q1_cal > 0)
1781 *z_val = ((*z_val) * 10000) / q1_cal;
1782}
1783
1784static void tasha_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl,
1785 uint32_t *zr)
1786{
1787 struct snd_soc_codec *codec = mbhc->codec;
1788 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
1789 struct wcd9xxx *wcd9xxx = tasha->wcd9xxx;
1790 s16 reg0, reg1, reg2, reg3, reg4;
1791 int32_t z1L, z1R, z1Ls;
1792 int zMono, z_diff1, z_diff2;
1793 bool is_fsm_disable = false;
1794 bool is_change = false;
1795 struct tasha_mbhc_zdet_param zdet_param[] = {
1796 {4, 0, 4, 0x08, 0x14, 0x18}, /* < 32ohm */
1797 {2, 0, 3, 0x18, 0x7C, 0x90}, /* 32ohm < Z < 400ohm */
1798 {1, 4, 5, 0x18, 0x7C, 0x90}, /* 400ohm < Z < 1200ohm */
1799 {1, 6, 7, 0x18, 0x7C, 0x90}, /* >1200ohm */
1800 };
1801 struct tasha_mbhc_zdet_param *zdet_param_ptr = NULL;
1802 s16 d1_a[][4] = {
1803 {0, 30, 90, 30},
1804 {0, 30, 30, 5},
1805 {0, 30, 30, 5},
1806 {0, 30, 30, 5},
1807 };
1808 s16 *d1 = NULL;
1809
1810 if (!TASHA_IS_2_0(wcd9xxx)) {
1811 dev_dbg(codec->dev, "%s: Z-det is not supported for this codec version\n",
1812 __func__);
1813 *zl = 0;
1814 *zr = 0;
1815 return;
1816 }
1817 WCD_MBHC_RSC_ASSERT_LOCKED(mbhc);
1818
1819 if (tasha->zdet_gpio_cb)
1820 is_change = tasha->zdet_gpio_cb(codec, true);
1821
1822 reg0 = snd_soc_read(codec, WCD9335_ANA_MBHC_BTN5);
1823 reg1 = snd_soc_read(codec, WCD9335_ANA_MBHC_BTN6);
1824 reg2 = snd_soc_read(codec, WCD9335_ANA_MBHC_BTN7);
1825 reg3 = snd_soc_read(codec, WCD9335_MBHC_CTL_1);
1826 reg4 = snd_soc_read(codec, WCD9335_MBHC_ZDET_ANA_CTL);
1827
1828 if (snd_soc_read(codec, WCD9335_ANA_MBHC_ELECT) & 0x80) {
1829 is_fsm_disable = true;
1830 regmap_update_bits(wcd9xxx->regmap,
1831 WCD9335_ANA_MBHC_ELECT, 0x80, 0x00);
1832 }
1833
1834 /* For NO-jack, disable L_DET_EN before Z-det measurements */
1835 if (mbhc->hphl_swh)
1836 regmap_update_bits(wcd9xxx->regmap,
1837 WCD9335_ANA_MBHC_MECH, 0x80, 0x00);
1838
1839 /* Enable AZ */
1840 snd_soc_update_bits(codec, WCD9335_MBHC_CTL_1, 0x0C, 0x04);
1841 /* Turn off 100k pull down on HPHL */
1842 regmap_update_bits(wcd9xxx->regmap,
1843 WCD9335_ANA_MBHC_MECH, 0x01, 0x00);
1844
1845 /* First get impedance on Left */
1846 d1 = d1_a[1];
1847 zdet_param_ptr = &zdet_param[1];
1848 tasha_mbhc_zdet_ramp(codec, zdet_param_ptr, &z1L, NULL, d1);
1849
1850 if (!TASHA_MBHC_IS_SECOND_RAMP_REQUIRED(z1L))
1851 goto left_ch_impedance;
1852
1853 /* second ramp for left ch */
1854 if (z1L < TASHA_ZDET_VAL_32) {
1855 zdet_param_ptr = &zdet_param[0];
1856 d1 = d1_a[0];
1857 } else if ((z1L > TASHA_ZDET_VAL_400) && (z1L <= TASHA_ZDET_VAL_1200)) {
1858 zdet_param_ptr = &zdet_param[2];
1859 d1 = d1_a[2];
1860 } else if (z1L > TASHA_ZDET_VAL_1200) {
1861 zdet_param_ptr = &zdet_param[3];
1862 d1 = d1_a[3];
1863 }
1864 tasha_mbhc_zdet_ramp(codec, zdet_param_ptr, &z1L, NULL, d1);
1865
1866left_ch_impedance:
1867 if ((z1L == TASHA_ZDET_FLOATING_IMPEDANCE) ||
1868 (z1L > TASHA_ZDET_VAL_100K)) {
1869 *zl = TASHA_ZDET_FLOATING_IMPEDANCE;
1870 zdet_param_ptr = &zdet_param[1];
1871 d1 = d1_a[1];
1872 } else {
1873 *zl = z1L/1000;
1874 tasha_wcd_mbhc_qfuse_cal(codec, zl, 0);
1875 }
1876 dev_dbg(codec->dev, "%s: impedance on HPH_L = %d(ohms)\n",
1877 __func__, *zl);
1878
1879 /* start of right impedance ramp and calculation */
1880 tasha_mbhc_zdet_ramp(codec, zdet_param_ptr, NULL, &z1R, d1);
1881 if (TASHA_MBHC_IS_SECOND_RAMP_REQUIRED(z1R)) {
1882 if (((z1R > TASHA_ZDET_VAL_1200) &&
1883 (zdet_param_ptr->noff == 0x6)) ||
1884 ((*zl) != TASHA_ZDET_FLOATING_IMPEDANCE))
1885 goto right_ch_impedance;
1886 /* second ramp for right ch */
1887 if (z1R < TASHA_ZDET_VAL_32) {
1888 zdet_param_ptr = &zdet_param[0];
1889 d1 = d1_a[0];
1890 } else if ((z1R > TASHA_ZDET_VAL_400) &&
1891 (z1R <= TASHA_ZDET_VAL_1200)) {
1892 zdet_param_ptr = &zdet_param[2];
1893 d1 = d1_a[2];
1894 } else if (z1R > TASHA_ZDET_VAL_1200) {
1895 zdet_param_ptr = &zdet_param[3];
1896 d1 = d1_a[3];
1897 }
1898 tasha_mbhc_zdet_ramp(codec, zdet_param_ptr, NULL, &z1R, d1);
1899 }
1900right_ch_impedance:
1901 if ((z1R == TASHA_ZDET_FLOATING_IMPEDANCE) ||
1902 (z1R > TASHA_ZDET_VAL_100K)) {
1903 *zr = TASHA_ZDET_FLOATING_IMPEDANCE;
1904 } else {
1905 *zr = z1R/1000;
1906 tasha_wcd_mbhc_qfuse_cal(codec, zr, 1);
1907 }
1908 dev_dbg(codec->dev, "%s: impedance on HPH_R = %d(ohms)\n",
1909 __func__, *zr);
1910
1911 /* mono/stereo detection */
1912 if ((*zl == TASHA_ZDET_FLOATING_IMPEDANCE) &&
1913 (*zr == TASHA_ZDET_FLOATING_IMPEDANCE)) {
1914 dev_dbg(codec->dev,
1915 "%s: plug type is invalid or extension cable\n",
1916 __func__);
1917 goto zdet_complete;
1918 }
1919 if ((*zl == TASHA_ZDET_FLOATING_IMPEDANCE) ||
1920 (*zr == TASHA_ZDET_FLOATING_IMPEDANCE) ||
1921 ((*zl < WCD_MONO_HS_MIN_THR) && (*zr > WCD_MONO_HS_MIN_THR)) ||
1922 ((*zl > WCD_MONO_HS_MIN_THR) && (*zr < WCD_MONO_HS_MIN_THR))) {
1923 dev_dbg(codec->dev,
1924 "%s: Mono plug type with one ch floating or shorted to GND\n",
1925 __func__);
1926 mbhc->hph_type = WCD_MBHC_HPH_MONO;
1927 goto zdet_complete;
1928 }
1929 snd_soc_update_bits(codec, WCD9335_HPH_R_ATEST, 0x02, 0x02);
1930 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x40, 0x01);
1931 if (*zl < (TASHA_ZDET_VAL_32/1000))
1932 tasha_mbhc_zdet_ramp(codec, &zdet_param[0], &z1Ls, NULL, d1);
1933 else
1934 tasha_mbhc_zdet_ramp(codec, &zdet_param[1], &z1Ls, NULL, d1);
1935 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x40, 0x00);
1936 snd_soc_update_bits(codec, WCD9335_HPH_R_ATEST, 0x02, 0x00);
1937 z1Ls /= 1000;
1938 tasha_wcd_mbhc_qfuse_cal(codec, &z1Ls, 0);
1939 /* parallel of left Z and 9 ohm pull down resistor */
1940 zMono = ((*zl) * 9) / ((*zl) + 9);
1941 z_diff1 = (z1Ls > zMono) ? (z1Ls - zMono) : (zMono - z1Ls);
1942 z_diff2 = ((*zl) > z1Ls) ? ((*zl) - z1Ls) : (z1Ls - (*zl));
1943 if ((z_diff1 * (*zl + z1Ls)) > (z_diff2 * (z1Ls + zMono))) {
1944 dev_dbg(codec->dev, "%s: stereo plug type detected\n",
1945 __func__);
1946 mbhc->hph_type = WCD_MBHC_HPH_STEREO;
1947 } else {
1948 dev_dbg(codec->dev, "%s: MONO plug type detected\n",
1949 __func__);
1950 mbhc->hph_type = WCD_MBHC_HPH_MONO;
1951 }
1952
1953zdet_complete:
1954 snd_soc_write(codec, WCD9335_ANA_MBHC_BTN5, reg0);
1955 snd_soc_write(codec, WCD9335_ANA_MBHC_BTN6, reg1);
1956 snd_soc_write(codec, WCD9335_ANA_MBHC_BTN7, reg2);
1957 /* Turn on 100k pull down on HPHL */
1958 regmap_update_bits(wcd9xxx->regmap,
1959 WCD9335_ANA_MBHC_MECH, 0x01, 0x01);
1960
1961 /* For NO-jack, re-enable L_DET_EN after Z-det measurements */
1962 if (mbhc->hphl_swh)
1963 regmap_update_bits(wcd9xxx->regmap,
1964 WCD9335_ANA_MBHC_MECH, 0x80, 0x80);
1965
1966 snd_soc_write(codec, WCD9335_MBHC_ZDET_ANA_CTL, reg4);
1967 snd_soc_write(codec, WCD9335_MBHC_CTL_1, reg3);
1968 if (is_fsm_disable)
1969 regmap_update_bits(wcd9xxx->regmap,
1970 WCD9335_ANA_MBHC_ELECT, 0x80, 0x80);
1971 if (tasha->zdet_gpio_cb && is_change)
1972 tasha->zdet_gpio_cb(codec, false);
1973}
1974
1975static void tasha_mbhc_gnd_det_ctrl(struct snd_soc_codec *codec, bool enable)
1976{
1977 if (enable) {
1978 snd_soc_update_bits(codec, WCD9335_ANA_MBHC_MECH,
1979 0x02, 0x02);
1980 snd_soc_update_bits(codec, WCD9335_ANA_MBHC_MECH,
1981 0x40, 0x40);
1982 } else {
1983 snd_soc_update_bits(codec, WCD9335_ANA_MBHC_MECH,
1984 0x40, 0x00);
1985 snd_soc_update_bits(codec, WCD9335_ANA_MBHC_MECH,
1986 0x02, 0x00);
1987 }
1988}
1989
1990static void tasha_mbhc_hph_pull_down_ctrl(struct snd_soc_codec *codec,
1991 bool enable)
1992{
1993 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
1994
1995 if (enable) {
1996 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2,
1997 0x40, 0x40);
1998 if (TASHA_IS_2_0(tasha->wcd9xxx))
1999 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2,
2000 0x10, 0x10);
2001 } else {
2002 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2,
2003 0x40, 0x00);
2004 if (TASHA_IS_2_0(tasha->wcd9xxx))
2005 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2,
2006 0x10, 0x00);
2007 }
2008}
2009
2010static void tasha_mbhc_moisture_config(struct wcd_mbhc *mbhc)
2011{
2012 struct snd_soc_codec *codec = mbhc->codec;
2013
2014 if (mbhc->moist_vref == V_OFF)
2015 return;
2016
2017 /* Donot enable moisture detection if jack type is NC */
2018 if (!mbhc->hphl_swh) {
2019 dev_dbg(codec->dev, "%s: disable moisture detection for NC\n",
2020 __func__);
2021 return;
2022 }
2023
2024 snd_soc_update_bits(codec, WCD9335_MBHC_CTL_2,
2025 0x0C, mbhc->moist_vref << 2);
2026 tasha_mbhc_hph_l_pull_up_control(codec, mbhc->moist_iref);
2027}
2028
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05302029static void tasha_update_anc_state(struct snd_soc_codec *codec, bool enable,
2030 int anc_num)
2031{
2032 if (enable)
2033 snd_soc_update_bits(codec, WCD9335_CDC_RX1_RX_PATH_CFG0 +
2034 (20 * anc_num), 0x10, 0x10);
2035 else
2036 snd_soc_update_bits(codec, WCD9335_CDC_RX1_RX_PATH_CFG0 +
2037 (20 * anc_num), 0x10, 0x00);
2038}
2039
2040static bool tasha_is_anc_on(struct wcd_mbhc *mbhc)
2041{
2042 bool anc_on = false;
2043 u16 ancl, ancr;
2044
2045 ancl =
2046 (snd_soc_read(mbhc->codec, WCD9335_CDC_RX1_RX_PATH_CFG0)) & 0x10;
2047 ancr =
2048 (snd_soc_read(mbhc->codec, WCD9335_CDC_RX2_RX_PATH_CFG0)) & 0x10;
2049
2050 anc_on = !!(ancl | ancr);
2051
2052 return anc_on;
2053}
2054
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302055static const struct wcd_mbhc_cb mbhc_cb = {
2056 .request_irq = tasha_mbhc_request_irq,
2057 .irq_control = tasha_mbhc_irq_control,
2058 .free_irq = tasha_mbhc_free_irq,
2059 .clk_setup = tasha_mbhc_clk_setup,
2060 .map_btn_code_to_num = tasha_mbhc_btn_to_num,
2061 .enable_mb_source = tasha_enable_ext_mb_source,
2062 .mbhc_bias = tasha_mbhc_mbhc_bias_control,
2063 .set_btn_thr = tasha_mbhc_program_btn_thr,
2064 .lock_sleep = tasha_mbhc_lock_sleep,
2065 .register_notifier = tasha_mbhc_register_notifier,
2066 .micbias_enable_status = tasha_mbhc_micb_en_status,
2067 .hph_pa_on_status = tasha_mbhc_hph_pa_on_status,
2068 .hph_pull_up_control = tasha_mbhc_hph_l_pull_up_control,
2069 .mbhc_micbias_control = tasha_mbhc_request_micbias,
2070 .mbhc_micb_ramp_control = tasha_mbhc_micb_ramp_control,
2071 .get_hwdep_fw_cal = tasha_get_hwdep_fw_cal,
2072 .mbhc_micb_ctrl_thr_mic = tasha_mbhc_micb_ctrl_threshold_mic,
2073 .compute_impedance = tasha_wcd_mbhc_calc_impedance,
2074 .mbhc_gnd_det_ctrl = tasha_mbhc_gnd_det_ctrl,
2075 .hph_pull_down_ctrl = tasha_mbhc_hph_pull_down_ctrl,
2076 .mbhc_moisture_config = tasha_mbhc_moisture_config,
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05302077 .update_anc_state = tasha_update_anc_state,
2078 .is_anc_on = tasha_is_anc_on,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302079};
2080
2081static int tasha_get_anc_slot(struct snd_kcontrol *kcontrol,
2082 struct snd_ctl_elem_value *ucontrol)
2083{
2084 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
2085 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
2086
2087 ucontrol->value.integer.value[0] = tasha->anc_slot;
2088 return 0;
2089}
2090
2091static int tasha_put_anc_slot(struct snd_kcontrol *kcontrol,
2092 struct snd_ctl_elem_value *ucontrol)
2093{
2094 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
2095 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
2096
2097 tasha->anc_slot = ucontrol->value.integer.value[0];
2098 return 0;
2099}
2100
2101static int tasha_get_anc_func(struct snd_kcontrol *kcontrol,
2102 struct snd_ctl_elem_value *ucontrol)
2103{
2104 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
2105 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
2106
2107 ucontrol->value.integer.value[0] = (tasha->anc_func == true ? 1 : 0);
2108 return 0;
2109}
2110
2111static int tasha_put_anc_func(struct snd_kcontrol *kcontrol,
2112 struct snd_ctl_elem_value *ucontrol)
2113{
2114 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
2115 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
2116 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
2117
2118 mutex_lock(&tasha->codec_mutex);
2119 tasha->anc_func = (!ucontrol->value.integer.value[0] ? false : true);
2120
2121 dev_dbg(codec->dev, "%s: anc_func %x", __func__, tasha->anc_func);
2122
2123 if (tasha->anc_func == true) {
2124 snd_soc_dapm_enable_pin(dapm, "ANC LINEOUT2 PA");
2125 snd_soc_dapm_enable_pin(dapm, "ANC LINEOUT2");
2126 snd_soc_dapm_enable_pin(dapm, "ANC LINEOUT1 PA");
2127 snd_soc_dapm_enable_pin(dapm, "ANC LINEOUT1");
2128 snd_soc_dapm_enable_pin(dapm, "ANC HPHR PA");
2129 snd_soc_dapm_enable_pin(dapm, "ANC HPHR");
2130 snd_soc_dapm_enable_pin(dapm, "ANC HPHL PA");
2131 snd_soc_dapm_enable_pin(dapm, "ANC HPHL");
2132 snd_soc_dapm_enable_pin(dapm, "ANC EAR PA");
2133 snd_soc_dapm_enable_pin(dapm, "ANC EAR");
2134 snd_soc_dapm_enable_pin(dapm, "ANC SPK1 PA");
2135 snd_soc_dapm_disable_pin(dapm, "LINEOUT2");
2136 snd_soc_dapm_disable_pin(dapm, "LINEOUT2 PA");
2137 snd_soc_dapm_disable_pin(dapm, "LINEOUT1");
2138 snd_soc_dapm_disable_pin(dapm, "LINEOUT1 PA");
2139 snd_soc_dapm_disable_pin(dapm, "HPHR");
2140 snd_soc_dapm_disable_pin(dapm, "HPHL");
2141 snd_soc_dapm_disable_pin(dapm, "HPHR PA");
2142 snd_soc_dapm_disable_pin(dapm, "HPHL PA");
2143 snd_soc_dapm_disable_pin(dapm, "EAR PA");
2144 snd_soc_dapm_disable_pin(dapm, "EAR");
2145 } else {
2146 snd_soc_dapm_disable_pin(dapm, "ANC LINEOUT2 PA");
2147 snd_soc_dapm_disable_pin(dapm, "ANC LINEOUT2");
2148 snd_soc_dapm_disable_pin(dapm, "ANC LINEOUT1 PA");
2149 snd_soc_dapm_disable_pin(dapm, "ANC LINEOUT1");
2150 snd_soc_dapm_disable_pin(dapm, "ANC HPHR");
2151 snd_soc_dapm_disable_pin(dapm, "ANC HPHL");
2152 snd_soc_dapm_disable_pin(dapm, "ANC HPHR PA");
2153 snd_soc_dapm_disable_pin(dapm, "ANC HPHL PA");
2154 snd_soc_dapm_disable_pin(dapm, "ANC EAR PA");
2155 snd_soc_dapm_disable_pin(dapm, "ANC EAR");
2156 snd_soc_dapm_disable_pin(dapm, "ANC SPK1 PA");
2157 snd_soc_dapm_enable_pin(dapm, "LINEOUT2");
2158 snd_soc_dapm_enable_pin(dapm, "LINEOUT2 PA");
2159 snd_soc_dapm_enable_pin(dapm, "LINEOUT1");
2160 snd_soc_dapm_enable_pin(dapm, "LINEOUT1 PA");
2161 snd_soc_dapm_enable_pin(dapm, "HPHR");
2162 snd_soc_dapm_enable_pin(dapm, "HPHL");
2163 snd_soc_dapm_enable_pin(dapm, "HPHR PA");
2164 snd_soc_dapm_enable_pin(dapm, "HPHL PA");
2165 snd_soc_dapm_enable_pin(dapm, "EAR PA");
2166 snd_soc_dapm_enable_pin(dapm, "EAR");
2167 }
2168 mutex_unlock(&tasha->codec_mutex);
2169 snd_soc_dapm_sync(dapm);
2170 return 0;
2171}
2172
2173static int tasha_get_clkmode(struct snd_kcontrol *kcontrol,
2174 struct snd_ctl_elem_value *ucontrol)
2175{
2176 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
2177 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
2178
2179 ucontrol->value.enumerated.item[0] = tasha->clk_mode;
2180 dev_dbg(codec->dev, "%s: clk_mode: %d\n", __func__, tasha->clk_mode);
2181
2182 return 0;
2183}
2184
2185static int tasha_put_clkmode(struct snd_kcontrol *kcontrol,
2186 struct snd_ctl_elem_value *ucontrol)
2187{
2188 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
2189 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
2190
2191 tasha->clk_mode = ucontrol->value.enumerated.item[0];
2192 dev_dbg(codec->dev, "%s: clk_mode: %d\n", __func__, tasha->clk_mode);
2193
2194 return 0;
2195}
2196
2197static int tasha_get_iir_enable_audio_mixer(
2198 struct snd_kcontrol *kcontrol,
2199 struct snd_ctl_elem_value *ucontrol)
2200{
2201 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
2202 int iir_idx = ((struct soc_multi_mixer_control *)
2203 kcontrol->private_value)->reg;
2204 int band_idx = ((struct soc_multi_mixer_control *)
2205 kcontrol->private_value)->shift;
2206 /* IIR filter band registers are at integer multiples of 16 */
2207 u16 iir_reg = WCD9335_CDC_SIDETONE_IIR0_IIR_CTL + 16 * iir_idx;
2208
2209 ucontrol->value.integer.value[0] = (snd_soc_read(codec, iir_reg) &
2210 (1 << band_idx)) != 0;
2211
2212 dev_dbg(codec->dev, "%s: IIR #%d band #%d enable %d\n", __func__,
2213 iir_idx, band_idx,
2214 (uint32_t)ucontrol->value.integer.value[0]);
2215 return 0;
2216}
2217
2218static int tasha_hph_impedance_get(struct snd_kcontrol *kcontrol,
2219 struct snd_ctl_elem_value *ucontrol)
2220{
2221 uint32_t zl, zr;
2222 bool hphr;
2223 struct soc_multi_mixer_control *mc;
2224 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
2225 struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec);
2226
2227 mc = (struct soc_multi_mixer_control *)(kcontrol->private_value);
2228 hphr = mc->shift;
2229 wcd_mbhc_get_impedance(&priv->mbhc, &zl, &zr);
2230 dev_dbg(codec->dev, "%s: zl=%u(ohms), zr=%u(ohms)\n", __func__, zl, zr);
2231 ucontrol->value.integer.value[0] = hphr ? zr : zl;
2232
2233 return 0;
2234}
2235
2236static const struct snd_kcontrol_new impedance_detect_controls[] = {
2237 SOC_SINGLE_EXT("HPHL Impedance", 0, 0, UINT_MAX, 0,
2238 tasha_hph_impedance_get, NULL),
2239 SOC_SINGLE_EXT("HPHR Impedance", 0, 1, UINT_MAX, 0,
2240 tasha_hph_impedance_get, NULL),
2241};
2242
2243static int tasha_get_hph_type(struct snd_kcontrol *kcontrol,
2244 struct snd_ctl_elem_value *ucontrol)
2245{
2246 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
2247 struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec);
2248 struct wcd_mbhc *mbhc;
2249
2250 if (!priv) {
2251 dev_dbg(codec->dev, "%s: wcd9335 private data is NULL\n",
2252 __func__);
2253 return 0;
2254 }
2255
2256 mbhc = &priv->mbhc;
2257 if (!mbhc) {
2258 dev_dbg(codec->dev, "%s: mbhc not initialized\n", __func__);
2259 return 0;
2260 }
2261
2262 ucontrol->value.integer.value[0] = (u32) mbhc->hph_type;
2263 dev_dbg(codec->dev, "%s: hph_type = %u\n", __func__, mbhc->hph_type);
2264
2265 return 0;
2266}
2267
2268static const struct snd_kcontrol_new hph_type_detect_controls[] = {
2269 SOC_SINGLE_EXT("HPH Type", 0, 0, UINT_MAX, 0,
2270 tasha_get_hph_type, NULL),
2271};
2272
2273static int tasha_vi_feed_mixer_get(struct snd_kcontrol *kcontrol,
2274 struct snd_ctl_elem_value *ucontrol)
2275{
Asish Bhattacharya34504582017-08-08 12:55:01 +05302276 struct snd_soc_dapm_widget *widget =
2277 snd_soc_dapm_kcontrol_widget(kcontrol);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302278 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
2279 struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec);
2280
2281 ucontrol->value.integer.value[0] = tasha_p->vi_feed_value;
2282
2283 return 0;
2284}
2285
2286static int tasha_vi_feed_mixer_put(struct snd_kcontrol *kcontrol,
2287 struct snd_ctl_elem_value *ucontrol)
2288{
Asish Bhattacharya34504582017-08-08 12:55:01 +05302289 struct snd_soc_dapm_widget *widget =
2290 snd_soc_dapm_kcontrol_widget(kcontrol);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302291 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
2292 struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec);
2293 struct wcd9xxx *core = tasha_p->wcd9xxx;
2294 struct soc_multi_mixer_control *mixer =
2295 ((struct soc_multi_mixer_control *)kcontrol->private_value);
2296 u32 dai_id = widget->shift;
2297 u32 port_id = mixer->shift;
2298 u32 enable = ucontrol->value.integer.value[0];
2299
2300 dev_dbg(codec->dev, "%s: enable: %d, port_id:%d, dai_id: %d\n",
2301 __func__, enable, port_id, dai_id);
2302
2303 tasha_p->vi_feed_value = ucontrol->value.integer.value[0];
2304
2305 mutex_lock(&tasha_p->codec_mutex);
2306 if (enable) {
2307 if (port_id == TASHA_TX14 && !test_bit(VI_SENSE_1,
2308 &tasha_p->status_mask)) {
2309 list_add_tail(&core->tx_chs[TASHA_TX14].list,
2310 &tasha_p->dai[dai_id].wcd9xxx_ch_list);
2311 set_bit(VI_SENSE_1, &tasha_p->status_mask);
2312 }
2313 if (port_id == TASHA_TX15 && !test_bit(VI_SENSE_2,
2314 &tasha_p->status_mask)) {
2315 list_add_tail(&core->tx_chs[TASHA_TX15].list,
2316 &tasha_p->dai[dai_id].wcd9xxx_ch_list);
2317 set_bit(VI_SENSE_2, &tasha_p->status_mask);
2318 }
2319 } else {
2320 if (port_id == TASHA_TX14 && test_bit(VI_SENSE_1,
2321 &tasha_p->status_mask)) {
2322 list_del_init(&core->tx_chs[TASHA_TX14].list);
2323 clear_bit(VI_SENSE_1, &tasha_p->status_mask);
2324 }
2325 if (port_id == TASHA_TX15 && test_bit(VI_SENSE_2,
2326 &tasha_p->status_mask)) {
2327 list_del_init(&core->tx_chs[TASHA_TX15].list);
2328 clear_bit(VI_SENSE_2, &tasha_p->status_mask);
2329 }
2330 }
2331 mutex_unlock(&tasha_p->codec_mutex);
2332 snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, NULL);
2333
2334 return 0;
2335}
2336
2337/* virtual port entries */
2338static int slim_tx_mixer_get(struct snd_kcontrol *kcontrol,
2339 struct snd_ctl_elem_value *ucontrol)
2340{
Asish Bhattacharya34504582017-08-08 12:55:01 +05302341 struct snd_soc_dapm_widget *widget =
2342 snd_soc_dapm_kcontrol_widget(kcontrol);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302343 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
2344 struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec);
2345
2346 ucontrol->value.integer.value[0] = tasha_p->tx_port_value;
2347 return 0;
2348}
2349
2350static int slim_tx_mixer_put(struct snd_kcontrol *kcontrol,
2351 struct snd_ctl_elem_value *ucontrol)
2352{
Asish Bhattacharya34504582017-08-08 12:55:01 +05302353 struct snd_soc_dapm_widget *widget =
2354 snd_soc_dapm_kcontrol_widget(kcontrol);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302355 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
2356 struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec);
2357 struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent);
2358 struct snd_soc_dapm_update *update = NULL;
2359 struct soc_multi_mixer_control *mixer =
2360 ((struct soc_multi_mixer_control *)kcontrol->private_value);
2361 u32 dai_id = widget->shift;
2362 u32 port_id = mixer->shift;
2363 u32 enable = ucontrol->value.integer.value[0];
2364 u32 vtable;
2365
2366
2367 dev_dbg(codec->dev, "%s: wname %s cname %s value %u shift %d item %ld\n",
2368 __func__,
2369 widget->name, ucontrol->id.name, tasha_p->tx_port_value,
2370 widget->shift, ucontrol->value.integer.value[0]);
2371
2372 mutex_lock(&tasha_p->codec_mutex);
2373
Raja Mallika1edfcf2018-06-08 20:04:42 +05302374 if (tasha_p->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
Vaishnavi Kommaraju15ad81e2018-07-31 18:02:56 +05302375 if (dai_id >= ARRAY_SIZE(vport_slim_check_table)) {
2376 dev_err(codec->dev, "%s: dai_id: %d, out of bounds\n",
2377 __func__, dai_id);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302378 mutex_unlock(&tasha_p->codec_mutex);
2379 return -EINVAL;
2380 }
2381 vtable = vport_slim_check_table[dai_id];
2382 } else {
2383 if (dai_id >= ARRAY_SIZE(vport_i2s_check_table)) {
2384 dev_err(codec->dev, "%s: dai_id: %d, out of bounds\n",
2385 __func__, dai_id);
2386 return -EINVAL;
2387 }
2388 vtable = vport_i2s_check_table[dai_id];
2389 }
2390 switch (dai_id) {
2391 case AIF1_CAP:
2392 case AIF2_CAP:
2393 case AIF3_CAP:
2394 /* only add to the list if value not set */
2395 if (enable && !(tasha_p->tx_port_value & 1 << port_id)) {
2396
2397 if (wcd9xxx_tx_vport_validation(vtable, port_id,
2398 tasha_p->dai, NUM_CODEC_DAIS)) {
2399 dev_dbg(codec->dev, "%s: TX%u is used by other virtual port\n",
2400 __func__, port_id);
2401 mutex_unlock(&tasha_p->codec_mutex);
2402 return 0;
2403 }
2404 tasha_p->tx_port_value |= 1 << port_id;
2405 list_add_tail(&core->tx_chs[port_id].list,
2406 &tasha_p->dai[dai_id].wcd9xxx_ch_list
2407 );
2408 } else if (!enable && (tasha_p->tx_port_value &
2409 1 << port_id)) {
2410 tasha_p->tx_port_value &= ~(1 << port_id);
2411 list_del_init(&core->tx_chs[port_id].list);
2412 } else {
2413 if (enable)
2414 dev_dbg(codec->dev, "%s: TX%u port is used by\n"
2415 "this virtual port\n",
2416 __func__, port_id);
2417 else
2418 dev_dbg(codec->dev, "%s: TX%u port is not used by\n"
2419 "this virtual port\n",
2420 __func__, port_id);
2421 /* avoid update power function */
2422 mutex_unlock(&tasha_p->codec_mutex);
2423 return 0;
2424 }
2425 break;
2426 case AIF4_MAD_TX:
2427 case AIF5_CPE_TX:
2428 break;
2429 default:
2430 pr_err("Unknown AIF %d\n", dai_id);
2431 mutex_unlock(&tasha_p->codec_mutex);
2432 return -EINVAL;
2433 }
2434 pr_debug("%s: name %s sname %s updated value %u shift %d\n", __func__,
2435 widget->name, widget->sname, tasha_p->tx_port_value,
2436 widget->shift);
2437
2438 mutex_unlock(&tasha_p->codec_mutex);
2439 snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, update);
2440
2441 return 0;
2442}
2443
2444static int slim_rx_mux_get(struct snd_kcontrol *kcontrol,
2445 struct snd_ctl_elem_value *ucontrol)
2446{
Asish Bhattacharya34504582017-08-08 12:55:01 +05302447 struct snd_soc_dapm_widget *widget =
2448 snd_soc_dapm_kcontrol_widget(kcontrol);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302449 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
2450 struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec);
2451
2452 ucontrol->value.enumerated.item[0] =
2453 tasha_p->rx_port_value[widget->shift];
2454 return 0;
2455}
2456
2457static const char *const slim_rx_mux_text[] = {
2458 "ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB", "AIF4_PB", "AIF_MIX1_PB"
2459};
2460
2461static int slim_rx_mux_put(struct snd_kcontrol *kcontrol,
2462 struct snd_ctl_elem_value *ucontrol)
2463{
Asish Bhattacharya34504582017-08-08 12:55:01 +05302464 struct snd_soc_dapm_widget *widget =
2465 snd_soc_dapm_kcontrol_widget(kcontrol);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302466 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
2467 struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec);
2468 struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent);
2469 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
2470 struct snd_soc_dapm_update *update = NULL;
2471 unsigned int rx_port_value;
2472 u32 port_id = widget->shift;
2473
2474 tasha_p->rx_port_value[port_id] = ucontrol->value.enumerated.item[0];
2475 rx_port_value = tasha_p->rx_port_value[port_id];
2476
2477 pr_debug("%s: wname %s cname %s value %u shift %d item %ld\n", __func__,
2478 widget->name, ucontrol->id.name, rx_port_value,
2479 widget->shift, ucontrol->value.integer.value[0]);
2480
2481 mutex_lock(&tasha_p->codec_mutex);
2482
2483 if (tasha_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
2484 if (rx_port_value > 2) {
2485 dev_err(codec->dev, "%s: invalid AIF for I2C mode\n",
2486 __func__);
2487 goto err;
2488 }
2489 }
2490 /* value need to match the Virtual port and AIF number */
2491 switch (rx_port_value) {
2492 case 0:
2493 list_del_init(&core->rx_chs[port_id].list);
2494 break;
2495 case 1:
2496 if (wcd9xxx_rx_vport_validation(port_id +
2497 TASHA_RX_PORT_START_NUMBER,
2498 &tasha_p->dai[AIF1_PB].wcd9xxx_ch_list)) {
2499 dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n",
2500 __func__, port_id);
2501 goto rtn;
2502 }
2503 list_add_tail(&core->rx_chs[port_id].list,
2504 &tasha_p->dai[AIF1_PB].wcd9xxx_ch_list);
2505 break;
2506 case 2:
2507 if (wcd9xxx_rx_vport_validation(port_id +
2508 TASHA_RX_PORT_START_NUMBER,
2509 &tasha_p->dai[AIF2_PB].wcd9xxx_ch_list)) {
2510 dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n",
2511 __func__, port_id);
2512 goto rtn;
2513 }
2514 list_add_tail(&core->rx_chs[port_id].list,
2515 &tasha_p->dai[AIF2_PB].wcd9xxx_ch_list);
2516 break;
2517 case 3:
2518 if (wcd9xxx_rx_vport_validation(port_id +
2519 TASHA_RX_PORT_START_NUMBER,
2520 &tasha_p->dai[AIF3_PB].wcd9xxx_ch_list)) {
2521 dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n",
2522 __func__, port_id);
2523 goto rtn;
2524 }
2525 list_add_tail(&core->rx_chs[port_id].list,
2526 &tasha_p->dai[AIF3_PB].wcd9xxx_ch_list);
2527 break;
2528 case 4:
2529 if (wcd9xxx_rx_vport_validation(port_id +
2530 TASHA_RX_PORT_START_NUMBER,
2531 &tasha_p->dai[AIF4_PB].wcd9xxx_ch_list)) {
2532 dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n",
2533 __func__, port_id);
2534 goto rtn;
2535 }
2536 list_add_tail(&core->rx_chs[port_id].list,
2537 &tasha_p->dai[AIF4_PB].wcd9xxx_ch_list);
2538 break;
2539 case 5:
2540 if (wcd9xxx_rx_vport_validation(port_id +
2541 TASHA_RX_PORT_START_NUMBER,
2542 &tasha_p->dai[AIF_MIX1_PB].wcd9xxx_ch_list)) {
2543 dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n",
2544 __func__, port_id);
2545 goto rtn;
2546 }
2547 list_add_tail(&core->rx_chs[port_id].list,
2548 &tasha_p->dai[AIF_MIX1_PB].wcd9xxx_ch_list);
2549 break;
2550 default:
2551 pr_err("Unknown AIF %d\n", rx_port_value);
2552 goto err;
2553 }
2554rtn:
2555 mutex_unlock(&tasha_p->codec_mutex);
2556 snd_soc_dapm_mux_update_power(widget->dapm, kcontrol,
2557 rx_port_value, e, update);
2558
2559 return 0;
2560err:
2561 mutex_unlock(&tasha_p->codec_mutex);
2562 return -EINVAL;
2563}
2564
2565static const struct soc_enum slim_rx_mux_enum =
2566 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(slim_rx_mux_text), slim_rx_mux_text);
2567
2568static const struct snd_kcontrol_new slim_rx_mux[TASHA_RX_MAX] = {
2569 SOC_DAPM_ENUM_EXT("SLIM RX0 Mux", slim_rx_mux_enum,
2570 slim_rx_mux_get, slim_rx_mux_put),
2571 SOC_DAPM_ENUM_EXT("SLIM RX1 Mux", slim_rx_mux_enum,
2572 slim_rx_mux_get, slim_rx_mux_put),
2573 SOC_DAPM_ENUM_EXT("SLIM RX2 Mux", slim_rx_mux_enum,
2574 slim_rx_mux_get, slim_rx_mux_put),
2575 SOC_DAPM_ENUM_EXT("SLIM RX3 Mux", slim_rx_mux_enum,
2576 slim_rx_mux_get, slim_rx_mux_put),
2577 SOC_DAPM_ENUM_EXT("SLIM RX4 Mux", slim_rx_mux_enum,
2578 slim_rx_mux_get, slim_rx_mux_put),
2579 SOC_DAPM_ENUM_EXT("SLIM RX5 Mux", slim_rx_mux_enum,
2580 slim_rx_mux_get, slim_rx_mux_put),
2581 SOC_DAPM_ENUM_EXT("SLIM RX6 Mux", slim_rx_mux_enum,
2582 slim_rx_mux_get, slim_rx_mux_put),
2583 SOC_DAPM_ENUM_EXT("SLIM RX7 Mux", slim_rx_mux_enum,
2584 slim_rx_mux_get, slim_rx_mux_put),
2585};
2586
2587static const struct snd_kcontrol_new aif4_vi_mixer[] = {
2588 SOC_SINGLE_EXT("SPKR_VI_1", SND_SOC_NOPM, TASHA_TX14, 1, 0,
2589 tasha_vi_feed_mixer_get, tasha_vi_feed_mixer_put),
2590 SOC_SINGLE_EXT("SPKR_VI_2", SND_SOC_NOPM, TASHA_TX15, 1, 0,
2591 tasha_vi_feed_mixer_get, tasha_vi_feed_mixer_put),
2592};
2593
2594static const struct snd_kcontrol_new aif1_cap_mixer[] = {
2595 SOC_SINGLE_EXT("SLIM TX0", SND_SOC_NOPM, TASHA_TX0, 1, 0,
2596 slim_tx_mixer_get, slim_tx_mixer_put),
2597 SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, TASHA_TX1, 1, 0,
2598 slim_tx_mixer_get, slim_tx_mixer_put),
2599 SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, TASHA_TX2, 1, 0,
2600 slim_tx_mixer_get, slim_tx_mixer_put),
2601 SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, TASHA_TX3, 1, 0,
2602 slim_tx_mixer_get, slim_tx_mixer_put),
2603 SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, TASHA_TX4, 1, 0,
2604 slim_tx_mixer_get, slim_tx_mixer_put),
2605 SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, TASHA_TX5, 1, 0,
2606 slim_tx_mixer_get, slim_tx_mixer_put),
2607 SOC_SINGLE_EXT("SLIM TX6", SND_SOC_NOPM, TASHA_TX6, 1, 0,
2608 slim_tx_mixer_get, slim_tx_mixer_put),
2609 SOC_SINGLE_EXT("SLIM TX7", SND_SOC_NOPM, TASHA_TX7, 1, 0,
2610 slim_tx_mixer_get, slim_tx_mixer_put),
2611 SOC_SINGLE_EXT("SLIM TX8", SND_SOC_NOPM, TASHA_TX8, 1, 0,
2612 slim_tx_mixer_get, slim_tx_mixer_put),
2613 SOC_SINGLE_EXT("SLIM TX9", SND_SOC_NOPM, TASHA_TX9, 1, 0,
2614 slim_tx_mixer_get, slim_tx_mixer_put),
2615 SOC_SINGLE_EXT("SLIM TX10", SND_SOC_NOPM, TASHA_TX10, 1, 0,
2616 slim_tx_mixer_get, slim_tx_mixer_put),
2617 SOC_SINGLE_EXT("SLIM TX11", SND_SOC_NOPM, TASHA_TX11, 1, 0,
2618 slim_tx_mixer_get, slim_tx_mixer_put),
2619 SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, TASHA_TX13, 1, 0,
2620 slim_tx_mixer_get, slim_tx_mixer_put),
2621};
2622
2623static const struct snd_kcontrol_new aif2_cap_mixer[] = {
2624 SOC_SINGLE_EXT("SLIM TX0", SND_SOC_NOPM, TASHA_TX0, 1, 0,
2625 slim_tx_mixer_get, slim_tx_mixer_put),
2626 SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, TASHA_TX1, 1, 0,
2627 slim_tx_mixer_get, slim_tx_mixer_put),
2628 SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, TASHA_TX2, 1, 0,
2629 slim_tx_mixer_get, slim_tx_mixer_put),
2630 SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, TASHA_TX3, 1, 0,
2631 slim_tx_mixer_get, slim_tx_mixer_put),
2632 SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, TASHA_TX4, 1, 0,
2633 slim_tx_mixer_get, slim_tx_mixer_put),
2634 SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, TASHA_TX5, 1, 0,
2635 slim_tx_mixer_get, slim_tx_mixer_put),
2636 SOC_SINGLE_EXT("SLIM TX6", SND_SOC_NOPM, TASHA_TX6, 1, 0,
2637 slim_tx_mixer_get, slim_tx_mixer_put),
2638 SOC_SINGLE_EXT("SLIM TX7", SND_SOC_NOPM, TASHA_TX7, 1, 0,
2639 slim_tx_mixer_get, slim_tx_mixer_put),
2640 SOC_SINGLE_EXT("SLIM TX8", SND_SOC_NOPM, TASHA_TX8, 1, 0,
2641 slim_tx_mixer_get, slim_tx_mixer_put),
2642 SOC_SINGLE_EXT("SLIM TX9", SND_SOC_NOPM, TASHA_TX9, 1, 0,
2643 slim_tx_mixer_get, slim_tx_mixer_put),
2644 SOC_SINGLE_EXT("SLIM TX10", SND_SOC_NOPM, TASHA_TX10, 1, 0,
2645 slim_tx_mixer_get, slim_tx_mixer_put),
2646 SOC_SINGLE_EXT("SLIM TX11", SND_SOC_NOPM, TASHA_TX11, 1, 0,
2647 slim_tx_mixer_get, slim_tx_mixer_put),
2648 SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, TASHA_TX13, 1, 0,
2649 slim_tx_mixer_get, slim_tx_mixer_put),
2650};
2651
2652static const struct snd_kcontrol_new aif3_cap_mixer[] = {
2653 SOC_SINGLE_EXT("SLIM TX0", SND_SOC_NOPM, TASHA_TX0, 1, 0,
2654 slim_tx_mixer_get, slim_tx_mixer_put),
2655 SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, TASHA_TX1, 1, 0,
2656 slim_tx_mixer_get, slim_tx_mixer_put),
2657 SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, TASHA_TX2, 1, 0,
2658 slim_tx_mixer_get, slim_tx_mixer_put),
2659 SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, TASHA_TX3, 1, 0,
2660 slim_tx_mixer_get, slim_tx_mixer_put),
2661 SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, TASHA_TX4, 1, 0,
2662 slim_tx_mixer_get, slim_tx_mixer_put),
2663 SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, TASHA_TX5, 1, 0,
2664 slim_tx_mixer_get, slim_tx_mixer_put),
2665 SOC_SINGLE_EXT("SLIM TX6", SND_SOC_NOPM, TASHA_TX6, 1, 0,
2666 slim_tx_mixer_get, slim_tx_mixer_put),
2667 SOC_SINGLE_EXT("SLIM TX7", SND_SOC_NOPM, TASHA_TX7, 1, 0,
2668 slim_tx_mixer_get, slim_tx_mixer_put),
2669 SOC_SINGLE_EXT("SLIM TX8", SND_SOC_NOPM, TASHA_TX8, 1, 0,
2670 slim_tx_mixer_get, slim_tx_mixer_put),
2671 SOC_SINGLE_EXT("SLIM TX9", SND_SOC_NOPM, TASHA_TX9, 1, 0,
2672 slim_tx_mixer_get, slim_tx_mixer_put),
2673 SOC_SINGLE_EXT("SLIM TX10", SND_SOC_NOPM, TASHA_TX10, 1, 0,
2674 slim_tx_mixer_get, slim_tx_mixer_put),
2675 SOC_SINGLE_EXT("SLIM TX11", SND_SOC_NOPM, TASHA_TX11, 1, 0,
2676 slim_tx_mixer_get, slim_tx_mixer_put),
2677 SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, TASHA_TX13, 1, 0,
2678 slim_tx_mixer_get, slim_tx_mixer_put),
2679};
2680
2681static const struct snd_kcontrol_new aif4_mad_mixer[] = {
2682 SOC_SINGLE_EXT("SLIM TX12", SND_SOC_NOPM, TASHA_TX12, 1, 0,
2683 slim_tx_mixer_get, slim_tx_mixer_put),
2684 SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, TASHA_TX13, 1, 0,
2685 slim_tx_mixer_get, slim_tx_mixer_put),
2686 SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, 0, 1, 0,
2687 slim_tx_mixer_get, slim_tx_mixer_put),
2688
2689};
2690
2691static const struct snd_kcontrol_new rx_int1_spline_mix_switch[] = {
2692 SOC_DAPM_SINGLE("HPHL Switch", SND_SOC_NOPM, 0, 1, 0)
2693};
2694
2695static const struct snd_kcontrol_new rx_int2_spline_mix_switch[] = {
2696 SOC_DAPM_SINGLE("HPHR Switch", SND_SOC_NOPM, 0, 1, 0)
2697};
2698
2699static const struct snd_kcontrol_new rx_int3_spline_mix_switch[] = {
2700 SOC_DAPM_SINGLE("LO1 Switch", SND_SOC_NOPM, 0, 1, 0)
2701};
2702
2703static const struct snd_kcontrol_new rx_int4_spline_mix_switch[] = {
2704 SOC_DAPM_SINGLE("LO2 Switch", SND_SOC_NOPM, 0, 1, 0)
2705};
2706
2707static const struct snd_kcontrol_new rx_int5_spline_mix_switch[] = {
2708 SOC_DAPM_SINGLE("LO3 Switch", SND_SOC_NOPM, 0, 1, 0)
2709};
2710
2711static const struct snd_kcontrol_new rx_int6_spline_mix_switch[] = {
2712 SOC_DAPM_SINGLE("LO4 Switch", SND_SOC_NOPM, 0, 1, 0)
2713};
2714
2715static const struct snd_kcontrol_new rx_int7_spline_mix_switch[] = {
2716 SOC_DAPM_SINGLE("SPKRL Switch", SND_SOC_NOPM, 0, 1, 0)
2717};
2718
2719static const struct snd_kcontrol_new rx_int8_spline_mix_switch[] = {
2720 SOC_DAPM_SINGLE("SPKRR Switch", SND_SOC_NOPM, 0, 1, 0)
2721};
2722
2723static const struct snd_kcontrol_new rx_int5_vbat_mix_switch[] = {
2724 SOC_DAPM_SINGLE("LO3 VBAT Enable", SND_SOC_NOPM, 0, 1, 0)
2725};
2726
2727static const struct snd_kcontrol_new rx_int6_vbat_mix_switch[] = {
2728 SOC_DAPM_SINGLE("LO4 VBAT Enable", SND_SOC_NOPM, 0, 1, 0)
2729};
2730
2731static const struct snd_kcontrol_new rx_int7_vbat_mix_switch[] = {
2732 SOC_DAPM_SINGLE("SPKRL VBAT Enable", SND_SOC_NOPM, 0, 1, 0)
2733};
2734
2735static const struct snd_kcontrol_new rx_int8_vbat_mix_switch[] = {
2736 SOC_DAPM_SINGLE("SPKRR VBAT Enable", SND_SOC_NOPM, 0, 1, 0)
2737};
2738
2739static const struct snd_kcontrol_new cpe_in_mix_switch[] = {
2740 SOC_DAPM_SINGLE("MAD_BYPASS", SND_SOC_NOPM, 0, 1, 0)
2741};
2742
2743
2744
2745static int tasha_put_iir_enable_audio_mixer(
2746 struct snd_kcontrol *kcontrol,
2747 struct snd_ctl_elem_value *ucontrol)
2748{
2749 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
2750 int iir_idx = ((struct soc_multi_mixer_control *)
2751 kcontrol->private_value)->reg;
2752 int band_idx = ((struct soc_multi_mixer_control *)
2753 kcontrol->private_value)->shift;
2754 bool iir_band_en_status;
2755 int value = ucontrol->value.integer.value[0];
2756 u16 iir_reg = WCD9335_CDC_SIDETONE_IIR0_IIR_CTL + 16 * iir_idx;
2757
2758 /* Mask first 5 bits, 6-8 are reserved */
2759 snd_soc_update_bits(codec, iir_reg, (1 << band_idx),
2760 (value << band_idx));
2761
2762 iir_band_en_status = ((snd_soc_read(codec, iir_reg) &
2763 (1 << band_idx)) != 0);
2764 pr_debug("%s: IIR #%d band #%d enable %d\n", __func__,
2765 iir_idx, band_idx, iir_band_en_status);
2766 return 0;
2767}
2768
2769static uint32_t get_iir_band_coeff(struct snd_soc_codec *codec,
2770 int iir_idx, int band_idx,
2771 int coeff_idx)
2772{
2773 uint32_t value = 0;
2774
2775 /* Address does not automatically update if reading */
2776 snd_soc_write(codec,
2777 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx),
2778 ((band_idx * BAND_MAX + coeff_idx)
2779 * sizeof(uint32_t)) & 0x7F);
2780
2781 value |= snd_soc_read(codec,
2782 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx));
2783
2784 snd_soc_write(codec,
2785 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx),
2786 ((band_idx * BAND_MAX + coeff_idx)
2787 * sizeof(uint32_t) + 1) & 0x7F);
2788
2789 value |= (snd_soc_read(codec,
2790 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL +
2791 16 * iir_idx)) << 8);
2792
2793 snd_soc_write(codec,
2794 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx),
2795 ((band_idx * BAND_MAX + coeff_idx)
2796 * sizeof(uint32_t) + 2) & 0x7F);
2797
2798 value |= (snd_soc_read(codec,
2799 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL +
2800 16 * iir_idx)) << 16);
2801
2802 snd_soc_write(codec,
2803 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx),
2804 ((band_idx * BAND_MAX + coeff_idx)
2805 * sizeof(uint32_t) + 3) & 0x7F);
2806
2807 /* Mask bits top 2 bits since they are reserved */
2808 value |= ((snd_soc_read(codec,
2809 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL +
2810 16 * iir_idx)) & 0x3F) << 24);
2811
2812 return value;
2813}
2814
2815static int tasha_get_iir_band_audio_mixer(
2816 struct snd_kcontrol *kcontrol,
2817 struct snd_ctl_elem_value *ucontrol)
2818{
2819 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
2820 int iir_idx = ((struct soc_multi_mixer_control *)
2821 kcontrol->private_value)->reg;
2822 int band_idx = ((struct soc_multi_mixer_control *)
2823 kcontrol->private_value)->shift;
2824
2825 ucontrol->value.integer.value[0] =
2826 get_iir_band_coeff(codec, iir_idx, band_idx, 0);
2827 ucontrol->value.integer.value[1] =
2828 get_iir_band_coeff(codec, iir_idx, band_idx, 1);
2829 ucontrol->value.integer.value[2] =
2830 get_iir_band_coeff(codec, iir_idx, band_idx, 2);
2831 ucontrol->value.integer.value[3] =
2832 get_iir_band_coeff(codec, iir_idx, band_idx, 3);
2833 ucontrol->value.integer.value[4] =
2834 get_iir_band_coeff(codec, iir_idx, band_idx, 4);
2835
2836 pr_debug("%s: IIR #%d band #%d b0 = 0x%x\n"
2837 "%s: IIR #%d band #%d b1 = 0x%x\n"
2838 "%s: IIR #%d band #%d b2 = 0x%x\n"
2839 "%s: IIR #%d band #%d a1 = 0x%x\n"
2840 "%s: IIR #%d band #%d a2 = 0x%x\n",
2841 __func__, iir_idx, band_idx,
2842 (uint32_t)ucontrol->value.integer.value[0],
2843 __func__, iir_idx, band_idx,
2844 (uint32_t)ucontrol->value.integer.value[1],
2845 __func__, iir_idx, band_idx,
2846 (uint32_t)ucontrol->value.integer.value[2],
2847 __func__, iir_idx, band_idx,
2848 (uint32_t)ucontrol->value.integer.value[3],
2849 __func__, iir_idx, band_idx,
2850 (uint32_t)ucontrol->value.integer.value[4]);
2851 return 0;
2852}
2853
2854static void set_iir_band_coeff(struct snd_soc_codec *codec,
2855 int iir_idx, int band_idx,
2856 uint32_t value)
2857{
2858 snd_soc_write(codec,
2859 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx),
2860 (value & 0xFF));
2861
2862 snd_soc_write(codec,
2863 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx),
2864 (value >> 8) & 0xFF);
2865
2866 snd_soc_write(codec,
2867 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx),
2868 (value >> 16) & 0xFF);
2869
2870 /* Mask top 2 bits, 7-8 are reserved */
2871 snd_soc_write(codec,
2872 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx),
2873 (value >> 24) & 0x3F);
2874}
2875
2876static void tasha_codec_enable_int_port(struct wcd9xxx_codec_dai_data *dai,
2877 struct snd_soc_codec *codec)
2878{
2879 struct wcd9xxx_ch *ch;
2880 int port_num = 0;
2881 unsigned short reg = 0;
2882 u8 val = 0;
2883 struct tasha_priv *tasha_p;
2884
2885 if (!dai || !codec) {
2886 pr_err("%s: Invalid params\n", __func__);
2887 return;
2888 }
2889
2890 tasha_p = snd_soc_codec_get_drvdata(codec);
2891 list_for_each_entry(ch, &dai->wcd9xxx_ch_list, list) {
2892 if (ch->port >= TASHA_RX_PORT_START_NUMBER) {
2893 port_num = ch->port - TASHA_RX_PORT_START_NUMBER;
2894 reg = TASHA_SLIM_PGD_PORT_INT_EN0 + (port_num / 8);
2895 val = wcd9xxx_interface_reg_read(tasha_p->wcd9xxx,
2896 reg);
2897 if (!(val & BYTE_BIT_MASK(port_num))) {
2898 val |= BYTE_BIT_MASK(port_num);
2899 wcd9xxx_interface_reg_write(
2900 tasha_p->wcd9xxx, reg, val);
2901 val = wcd9xxx_interface_reg_read(
2902 tasha_p->wcd9xxx, reg);
2903 }
2904 } else {
2905 port_num = ch->port;
2906 reg = TASHA_SLIM_PGD_PORT_INT_TX_EN0 + (port_num / 8);
2907 val = wcd9xxx_interface_reg_read(tasha_p->wcd9xxx,
2908 reg);
2909 if (!(val & BYTE_BIT_MASK(port_num))) {
2910 val |= BYTE_BIT_MASK(port_num);
2911 wcd9xxx_interface_reg_write(tasha_p->wcd9xxx,
2912 reg, val);
2913 val = wcd9xxx_interface_reg_read(
2914 tasha_p->wcd9xxx, reg);
2915 }
2916 }
2917 }
2918}
2919
2920static int tasha_codec_enable_slim_chmask(struct wcd9xxx_codec_dai_data *dai,
2921 bool up)
2922{
2923 int ret = 0;
2924 struct wcd9xxx_ch *ch;
2925
2926 if (up) {
2927 list_for_each_entry(ch, &dai->wcd9xxx_ch_list, list) {
2928 ret = wcd9xxx_get_slave_port(ch->ch_num);
2929 if (ret < 0) {
2930 pr_err("%s: Invalid slave port ID: %d\n",
2931 __func__, ret);
2932 ret = -EINVAL;
2933 } else {
2934 set_bit(ret, &dai->ch_mask);
2935 }
2936 }
2937 } else {
2938 ret = wait_event_timeout(dai->dai_wait, (dai->ch_mask == 0),
2939 msecs_to_jiffies(
2940 TASHA_SLIM_CLOSE_TIMEOUT));
2941 if (!ret) {
2942 pr_err("%s: Slim close tx/rx wait timeout, ch_mask:0x%lx\n",
2943 __func__, dai->ch_mask);
2944 ret = -ETIMEDOUT;
2945 } else {
2946 ret = 0;
2947 }
2948 }
2949 return ret;
2950}
2951
2952static int tasha_codec_enable_slimrx(struct snd_soc_dapm_widget *w,
2953 struct snd_kcontrol *kcontrol,
2954 int event)
2955{
2956 struct wcd9xxx *core;
2957 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
2958 struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec);
2959 int ret = 0;
2960 struct wcd9xxx_codec_dai_data *dai;
2961
2962 core = dev_get_drvdata(codec->dev->parent);
2963
2964 dev_dbg(codec->dev, "%s: event called! codec name %s num_dai %d\n"
2965 "stream name %s event %d\n",
2966 __func__, codec->component.name,
2967 codec->component.num_dai, w->sname, event);
2968
2969 /* Execute the callback only if interface type is slimbus */
2970 if (tasha_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS)
2971 return 0;
2972
2973 dai = &tasha_p->dai[w->shift];
2974 dev_dbg(codec->dev, "%s: w->name %s w->shift %d event %d\n",
2975 __func__, w->name, w->shift, event);
2976
2977 switch (event) {
2978 case SND_SOC_DAPM_POST_PMU:
2979 dai->bus_down_in_recovery = false;
2980 tasha_codec_enable_int_port(dai, codec);
2981 (void) tasha_codec_enable_slim_chmask(dai, true);
2982 ret = wcd9xxx_cfg_slim_sch_rx(core, &dai->wcd9xxx_ch_list,
2983 dai->rate, dai->bit_width,
2984 &dai->grph);
2985 break;
2986 case SND_SOC_DAPM_PRE_PMD:
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05302987 tasha_codec_vote_max_bw(codec, true);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302988 break;
2989 case SND_SOC_DAPM_POST_PMD:
2990 ret = wcd9xxx_disconnect_port(core, &dai->wcd9xxx_ch_list,
2991 dai->grph);
2992 dev_dbg(codec->dev, "%s: Disconnect RX port, ret = %d\n",
2993 __func__, ret);
2994
2995 if (!dai->bus_down_in_recovery)
2996 ret = tasha_codec_enable_slim_chmask(dai, false);
2997 else
2998 dev_dbg(codec->dev,
2999 "%s: bus in recovery skip enable slim_chmask",
3000 __func__);
3001 ret = wcd9xxx_close_slim_sch_rx(core, &dai->wcd9xxx_ch_list,
3002 dai->grph);
3003 break;
3004 }
3005 return ret;
3006}
3007
3008static int tasha_codec_enable_slimvi_feedback(struct snd_soc_dapm_widget *w,
3009 struct snd_kcontrol *kcontrol,
3010 int event)
3011{
3012 struct wcd9xxx *core = NULL;
3013 struct snd_soc_codec *codec = NULL;
3014 struct tasha_priv *tasha_p = NULL;
3015 int ret = 0;
3016 struct wcd9xxx_codec_dai_data *dai = NULL;
3017
3018 if (!w) {
3019 pr_err("%s invalid params\n", __func__);
3020 return -EINVAL;
3021 }
3022 codec = snd_soc_dapm_to_codec(w->dapm);
3023 tasha_p = snd_soc_codec_get_drvdata(codec);
3024 core = tasha_p->wcd9xxx;
3025
3026 dev_dbg(codec->dev, "%s: num_dai %d stream name %s\n",
3027 __func__, codec->component.num_dai, w->sname);
3028
3029 /* Execute the callback only if interface type is slimbus */
3030 if (tasha_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
3031 dev_err(codec->dev, "%s Interface is not correct", __func__);
3032 return 0;
3033 }
3034
3035 dev_dbg(codec->dev, "%s(): w->name %s event %d w->shift %d\n",
3036 __func__, w->name, event, w->shift);
3037 if (w->shift != AIF4_VIFEED) {
3038 pr_err("%s Error in enabling the tx path\n", __func__);
3039 ret = -EINVAL;
3040 goto out_vi;
3041 }
3042 dai = &tasha_p->dai[w->shift];
3043 switch (event) {
3044 case SND_SOC_DAPM_POST_PMU:
3045 if (test_bit(VI_SENSE_1, &tasha_p->status_mask)) {
3046 dev_dbg(codec->dev, "%s: spkr1 enabled\n", __func__);
3047 /* Enable V&I sensing */
3048 snd_soc_update_bits(codec,
3049 WCD9335_CDC_TX9_SPKR_PROT_PATH_CTL, 0x20, 0x20);
3050 snd_soc_update_bits(codec,
3051 WCD9335_CDC_TX10_SPKR_PROT_PATH_CTL, 0x20,
3052 0x20);
3053 snd_soc_update_bits(codec,
3054 WCD9335_CDC_TX9_SPKR_PROT_PATH_CTL, 0x0F, 0x00);
3055 snd_soc_update_bits(codec,
3056 WCD9335_CDC_TX10_SPKR_PROT_PATH_CTL, 0x0F,
3057 0x00);
3058 snd_soc_update_bits(codec,
3059 WCD9335_CDC_TX9_SPKR_PROT_PATH_CTL, 0x10, 0x10);
3060 snd_soc_update_bits(codec,
3061 WCD9335_CDC_TX10_SPKR_PROT_PATH_CTL, 0x10,
3062 0x10);
3063 snd_soc_update_bits(codec,
3064 WCD9335_CDC_TX9_SPKR_PROT_PATH_CTL, 0x20, 0x00);
3065 snd_soc_update_bits(codec,
3066 WCD9335_CDC_TX10_SPKR_PROT_PATH_CTL, 0x20,
3067 0x00);
3068 }
3069 if (test_bit(VI_SENSE_2, &tasha_p->status_mask)) {
3070 pr_debug("%s: spkr2 enabled\n", __func__);
3071 /* Enable V&I sensing */
3072 snd_soc_update_bits(codec,
3073 WCD9335_CDC_TX11_SPKR_PROT_PATH_CTL, 0x20,
3074 0x20);
3075 snd_soc_update_bits(codec,
3076 WCD9335_CDC_TX12_SPKR_PROT_PATH_CTL, 0x20,
3077 0x20);
3078 snd_soc_update_bits(codec,
3079 WCD9335_CDC_TX11_SPKR_PROT_PATH_CTL, 0x0F,
3080 0x00);
3081 snd_soc_update_bits(codec,
3082 WCD9335_CDC_TX12_SPKR_PROT_PATH_CTL, 0x0F,
3083 0x00);
3084 snd_soc_update_bits(codec,
3085 WCD9335_CDC_TX11_SPKR_PROT_PATH_CTL, 0x10,
3086 0x10);
3087 snd_soc_update_bits(codec,
3088 WCD9335_CDC_TX12_SPKR_PROT_PATH_CTL, 0x10,
3089 0x10);
3090 snd_soc_update_bits(codec,
3091 WCD9335_CDC_TX11_SPKR_PROT_PATH_CTL, 0x20,
3092 0x00);
3093 snd_soc_update_bits(codec,
3094 WCD9335_CDC_TX12_SPKR_PROT_PATH_CTL, 0x20,
3095 0x00);
3096 }
3097 dai->bus_down_in_recovery = false;
3098 tasha_codec_enable_int_port(dai, codec);
3099 (void) tasha_codec_enable_slim_chmask(dai, true);
3100 ret = wcd9xxx_cfg_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
3101 dai->rate, dai->bit_width,
3102 &dai->grph);
3103 break;
3104 case SND_SOC_DAPM_POST_PMD:
3105 ret = wcd9xxx_close_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
3106 dai->grph);
3107 if (ret)
3108 dev_err(codec->dev, "%s error in close_slim_sch_tx %d\n",
3109 __func__, ret);
3110 if (!dai->bus_down_in_recovery)
3111 ret = tasha_codec_enable_slim_chmask(dai, false);
3112 if (ret < 0) {
3113 ret = wcd9xxx_disconnect_port(core,
3114 &dai->wcd9xxx_ch_list,
3115 dai->grph);
3116 dev_dbg(codec->dev, "%s: Disconnect TX port, ret = %d\n",
3117 __func__, ret);
3118 }
3119 if (test_bit(VI_SENSE_1, &tasha_p->status_mask)) {
3120 /* Disable V&I sensing */
3121 dev_dbg(codec->dev, "%s: spkr1 disabled\n", __func__);
3122 snd_soc_update_bits(codec,
3123 WCD9335_CDC_TX9_SPKR_PROT_PATH_CTL, 0x20, 0x20);
3124 snd_soc_update_bits(codec,
3125 WCD9335_CDC_TX10_SPKR_PROT_PATH_CTL, 0x20,
3126 0x20);
3127 snd_soc_update_bits(codec,
3128 WCD9335_CDC_TX9_SPKR_PROT_PATH_CTL, 0x10, 0x00);
3129 snd_soc_update_bits(codec,
3130 WCD9335_CDC_TX10_SPKR_PROT_PATH_CTL, 0x10,
3131 0x00);
3132 }
3133 if (test_bit(VI_SENSE_2, &tasha_p->status_mask)) {
3134 /* Disable V&I sensing */
3135 dev_dbg(codec->dev, "%s: spkr2 disabled\n", __func__);
3136 snd_soc_update_bits(codec,
3137 WCD9335_CDC_TX11_SPKR_PROT_PATH_CTL, 0x20,
3138 0x20);
3139 snd_soc_update_bits(codec,
3140 WCD9335_CDC_TX12_SPKR_PROT_PATH_CTL, 0x20,
3141 0x20);
3142 snd_soc_update_bits(codec,
3143 WCD9335_CDC_TX11_SPKR_PROT_PATH_CTL, 0x10,
3144 0x00);
3145 snd_soc_update_bits(codec,
3146 WCD9335_CDC_TX12_SPKR_PROT_PATH_CTL, 0x10,
3147 0x00);
3148 }
3149 break;
3150 }
3151out_vi:
3152 return ret;
3153}
3154
3155/*
3156 * __tasha_codec_enable_slimtx: Enable the slimbus slave port
3157 * for TX path
3158 * @codec: Handle to the codec for which the slave port is to be
3159 * enabled.
3160 * @dai_data: The dai specific data for dai which is enabled.
3161 */
3162static int __tasha_codec_enable_slimtx(struct snd_soc_codec *codec,
3163 int event, struct wcd9xxx_codec_dai_data *dai)
3164{
3165 struct wcd9xxx *core;
3166 struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec);
3167 int ret = 0;
3168
3169 /* Execute the callback only if interface type is slimbus */
3170 if (tasha_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS)
3171 return 0;
3172
3173 dev_dbg(codec->dev,
3174 "%s: event = %d\n", __func__, event);
3175 core = dev_get_drvdata(codec->dev->parent);
3176
3177 switch (event) {
3178 case SND_SOC_DAPM_POST_PMU:
3179 dai->bus_down_in_recovery = false;
3180 tasha_codec_enable_int_port(dai, codec);
3181 (void) tasha_codec_enable_slim_chmask(dai, true);
3182 ret = wcd9xxx_cfg_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
3183 dai->rate, dai->bit_width,
3184 &dai->grph);
3185 break;
3186 case SND_SOC_DAPM_POST_PMD:
3187 ret = wcd9xxx_close_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
3188 dai->grph);
3189 if (!dai->bus_down_in_recovery)
3190 ret = tasha_codec_enable_slim_chmask(dai, false);
3191 if (ret < 0) {
3192 ret = wcd9xxx_disconnect_port(core,
3193 &dai->wcd9xxx_ch_list,
3194 dai->grph);
3195 pr_debug("%s: Disconnect TX port, ret = %d\n",
3196 __func__, ret);
3197 }
3198
3199 break;
3200 }
3201
3202 return ret;
3203}
3204
3205static int tasha_codec_enable_slimtx(struct snd_soc_dapm_widget *w,
3206 struct snd_kcontrol *kcontrol,
3207 int event)
3208{
3209 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
3210 struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec);
3211 struct wcd9xxx_codec_dai_data *dai;
3212
3213 dev_dbg(codec->dev,
3214 "%s: w->name %s, w->shift = %d, num_dai %d stream name %s\n",
3215 __func__, w->name, w->shift,
3216 codec->component.num_dai, w->sname);
3217
3218 dai = &tasha_p->dai[w->shift];
3219 return __tasha_codec_enable_slimtx(codec, event, dai);
3220}
3221
3222static void tasha_codec_cpe_pp_set_cfg(struct snd_soc_codec *codec, int event)
3223{
3224 struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec);
3225 struct wcd9xxx_codec_dai_data *dai;
3226 u8 bit_width, rate, buf_period;
3227
3228 dai = &tasha_p->dai[AIF4_MAD_TX];
3229 switch (event) {
3230 case SND_SOC_DAPM_POST_PMU:
3231 switch (dai->bit_width) {
3232 case 32:
3233 bit_width = 0xF;
3234 break;
3235 case 24:
3236 bit_width = 0xE;
3237 break;
3238 case 20:
3239 bit_width = 0xD;
3240 break;
3241 case 16:
3242 default:
3243 bit_width = 0x0;
3244 break;
3245 }
3246 snd_soc_update_bits(codec, WCD9335_CPE_SS_TX_PP_CFG, 0x0F,
3247 bit_width);
3248
3249 switch (dai->rate) {
3250 case 384000:
3251 rate = 0x30;
3252 break;
3253 case 192000:
3254 rate = 0x20;
3255 break;
3256 case 48000:
3257 rate = 0x10;
3258 break;
3259 case 16000:
3260 default:
3261 rate = 0x00;
3262 break;
3263 }
3264 snd_soc_update_bits(codec, WCD9335_CPE_SS_TX_PP_CFG, 0x70,
3265 rate);
3266
3267 buf_period = (dai->rate * (dai->bit_width/8)) / (16*1000);
3268 snd_soc_update_bits(codec, WCD9335_CPE_SS_TX_PP_BUF_INT_PERIOD,
3269 0xFF, buf_period);
3270 dev_dbg(codec->dev, "%s: PP buffer period= 0x%x\n",
3271 __func__, buf_period);
3272 break;
3273
3274 case SND_SOC_DAPM_POST_PMD:
3275 snd_soc_write(codec, WCD9335_CPE_SS_TX_PP_CFG, 0x3C);
3276 snd_soc_write(codec, WCD9335_CPE_SS_TX_PP_BUF_INT_PERIOD, 0x60);
3277 break;
3278
3279 default:
3280 break;
3281 }
3282}
3283
3284/*
3285 * tasha_codec_get_mad_port_id: Callback function that will be invoked
3286 * to get the port ID for MAD.
3287 * @codec: Handle to the codec
3288 * @port_id: cpe port_id needs to enable
3289 */
3290static int tasha_codec_get_mad_port_id(struct snd_soc_codec *codec,
3291 u16 *port_id)
3292{
3293 struct tasha_priv *tasha_p;
3294 struct wcd9xxx_codec_dai_data *dai;
3295 struct wcd9xxx_ch *ch;
3296
3297 if (!port_id || !codec)
3298 return -EINVAL;
3299
3300 tasha_p = snd_soc_codec_get_drvdata(codec);
3301 if (!tasha_p)
3302 return -EINVAL;
3303
3304 dai = &tasha_p->dai[AIF4_MAD_TX];
3305 list_for_each_entry(ch, &dai->wcd9xxx_ch_list, list) {
3306 if (ch->port == TASHA_TX12)
3307 *port_id = WCD_CPE_AFE_OUT_PORT_2;
3308 else if (ch->port == TASHA_TX13)
3309 *port_id = WCD_CPE_AFE_OUT_PORT_4;
3310 else {
3311 dev_err(codec->dev, "%s: invalid mad_port = %d\n",
3312 __func__, ch->port);
3313 return -EINVAL;
3314 }
3315 }
3316 dev_dbg(codec->dev, "%s: port_id = %d\n", __func__, *port_id);
3317
3318 return 0;
3319}
3320
3321/*
3322 * tasha_codec_enable_slimtx_mad: Callback function that will be invoked
3323 * to setup the slave port for MAD.
3324 * @codec: Handle to the codec
3325 * @event: Indicates whether to enable or disable the slave port
3326 */
3327static int tasha_codec_enable_slimtx_mad(struct snd_soc_codec *codec,
3328 u8 event)
3329{
3330 struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec);
3331 struct wcd9xxx_codec_dai_data *dai;
3332 struct wcd9xxx_ch *ch;
3333 int dapm_event = SND_SOC_DAPM_POST_PMU;
3334 u16 port = 0;
3335 int ret = 0;
3336
3337 dai = &tasha_p->dai[AIF4_MAD_TX];
3338
3339 if (event == 0)
3340 dapm_event = SND_SOC_DAPM_POST_PMD;
3341
3342 dev_dbg(codec->dev,
3343 "%s: mad_channel, event = 0x%x\n",
3344 __func__, event);
3345
3346 list_for_each_entry(ch, &dai->wcd9xxx_ch_list, list) {
3347 dev_dbg(codec->dev, "%s: mad_port = %d, event = 0x%x\n",
3348 __func__, ch->port, event);
3349 if (ch->port == TASHA_TX13) {
3350 tasha_codec_cpe_pp_set_cfg(codec, dapm_event);
3351 port = TASHA_TX13;
3352 break;
3353 }
3354 }
3355
3356 ret = __tasha_codec_enable_slimtx(codec, dapm_event, dai);
3357
3358 if (port == TASHA_TX13) {
3359 switch (dapm_event) {
3360 case SND_SOC_DAPM_POST_PMU:
3361 snd_soc_update_bits(codec,
3362 WCD9335_CODEC_RPM_PWR_CPE_DRAM1_SHUTDOWN,
3363 0x20, 0x00);
3364 snd_soc_update_bits(codec,
3365 WCD9335_DATA_HUB_DATA_HUB_SB_TX13_INP_CFG,
3366 0x03, 0x02);
3367 snd_soc_update_bits(codec, WCD9335_CPE_SS_CFG,
3368 0x80, 0x80);
3369 break;
3370 case SND_SOC_DAPM_POST_PMD:
3371 snd_soc_update_bits(codec,
3372 WCD9335_CODEC_RPM_PWR_CPE_DRAM1_SHUTDOWN,
3373 0x20, 0x20);
3374 snd_soc_update_bits(codec,
3375 WCD9335_DATA_HUB_DATA_HUB_SB_TX13_INP_CFG,
3376 0x03, 0x00);
3377 snd_soc_update_bits(codec, WCD9335_CPE_SS_CFG,
3378 0x80, 0x00);
3379 break;
3380 }
3381 }
3382
3383 return ret;
3384}
3385
3386static int tasha_put_iir_band_audio_mixer(
3387 struct snd_kcontrol *kcontrol,
3388 struct snd_ctl_elem_value *ucontrol)
3389{
3390 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
3391 int iir_idx = ((struct soc_multi_mixer_control *)
3392 kcontrol->private_value)->reg;
3393 int band_idx = ((struct soc_multi_mixer_control *)
3394 kcontrol->private_value)->shift;
3395
3396 /*
3397 * Mask top bit it is reserved
3398 * Updates addr automatically for each B2 write
3399 */
3400 snd_soc_write(codec,
3401 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx),
3402 (band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F);
3403
3404 set_iir_band_coeff(codec, iir_idx, band_idx,
3405 ucontrol->value.integer.value[0]);
3406 set_iir_band_coeff(codec, iir_idx, band_idx,
3407 ucontrol->value.integer.value[1]);
3408 set_iir_band_coeff(codec, iir_idx, band_idx,
3409 ucontrol->value.integer.value[2]);
3410 set_iir_band_coeff(codec, iir_idx, band_idx,
3411 ucontrol->value.integer.value[3]);
3412 set_iir_band_coeff(codec, iir_idx, band_idx,
3413 ucontrol->value.integer.value[4]);
3414
3415 pr_debug("%s: IIR #%d band #%d b0 = 0x%x\n"
3416 "%s: IIR #%d band #%d b1 = 0x%x\n"
3417 "%s: IIR #%d band #%d b2 = 0x%x\n"
3418 "%s: IIR #%d band #%d a1 = 0x%x\n"
3419 "%s: IIR #%d band #%d a2 = 0x%x\n",
3420 __func__, iir_idx, band_idx,
3421 get_iir_band_coeff(codec, iir_idx, band_idx, 0),
3422 __func__, iir_idx, band_idx,
3423 get_iir_band_coeff(codec, iir_idx, band_idx, 1),
3424 __func__, iir_idx, band_idx,
3425 get_iir_band_coeff(codec, iir_idx, band_idx, 2),
3426 __func__, iir_idx, band_idx,
3427 get_iir_band_coeff(codec, iir_idx, band_idx, 3),
3428 __func__, iir_idx, band_idx,
3429 get_iir_band_coeff(codec, iir_idx, band_idx, 4));
3430 return 0;
3431}
3432
3433static int tasha_get_compander(struct snd_kcontrol *kcontrol,
3434 struct snd_ctl_elem_value *ucontrol)
3435{
3436
3437 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
3438 int comp = ((struct soc_multi_mixer_control *)
3439 kcontrol->private_value)->shift;
3440 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
3441
3442 ucontrol->value.integer.value[0] = tasha->comp_enabled[comp];
3443 return 0;
3444}
3445
3446static int tasha_set_compander(struct snd_kcontrol *kcontrol,
3447 struct snd_ctl_elem_value *ucontrol)
3448{
3449 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
3450 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
3451 int comp = ((struct soc_multi_mixer_control *)
3452 kcontrol->private_value)->shift;
3453 int value = ucontrol->value.integer.value[0];
3454
3455 pr_debug("%s: Compander %d enable current %d, new %d\n",
3456 __func__, comp + 1, tasha->comp_enabled[comp], value);
3457 tasha->comp_enabled[comp] = value;
3458
3459 /* Any specific register configuration for compander */
3460 switch (comp) {
3461 case COMPANDER_1:
3462 /* Set Gain Source Select based on compander enable/disable */
3463 snd_soc_update_bits(codec, WCD9335_HPH_L_EN, 0x20,
3464 (value ? 0x00:0x20));
3465 break;
3466 case COMPANDER_2:
3467 snd_soc_update_bits(codec, WCD9335_HPH_R_EN, 0x20,
3468 (value ? 0x00:0x20));
3469 break;
3470 case COMPANDER_3:
3471 break;
3472 case COMPANDER_4:
3473 break;
3474 case COMPANDER_5:
3475 snd_soc_update_bits(codec, WCD9335_SE_LO_LO3_GAIN, 0x20,
3476 (value ? 0x00:0x20));
3477 break;
3478 case COMPANDER_6:
3479 snd_soc_update_bits(codec, WCD9335_SE_LO_LO4_GAIN, 0x20,
3480 (value ? 0x00:0x20));
3481 break;
3482 case COMPANDER_7:
3483 break;
3484 case COMPANDER_8:
3485 break;
3486 default:
3487 /*
3488 * if compander is not enabled for any interpolator,
3489 * it does not cause any audio failure, so do not
3490 * return error in this case, but just print a log
3491 */
3492 dev_warn(codec->dev, "%s: unknown compander: %d\n",
3493 __func__, comp);
3494 };
3495 return 0;
3496}
3497
3498static void tasha_codec_init_flyback(struct snd_soc_codec *codec)
3499{
3500 snd_soc_update_bits(codec, WCD9335_HPH_L_EN, 0xC0, 0x00);
3501 snd_soc_update_bits(codec, WCD9335_HPH_R_EN, 0xC0, 0x00);
3502 snd_soc_update_bits(codec, WCD9335_RX_BIAS_FLYB_BUFF, 0x0F, 0x00);
3503 snd_soc_update_bits(codec, WCD9335_RX_BIAS_FLYB_BUFF, 0xF0, 0x00);
3504}
3505
3506static int tasha_codec_enable_rx_bias(struct snd_soc_dapm_widget *w,
3507 struct snd_kcontrol *kcontrol, int event)
3508{
3509 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
3510 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
3511
3512 dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
3513
3514 switch (event) {
3515 case SND_SOC_DAPM_PRE_PMU:
3516 tasha->rx_bias_count++;
3517 if (tasha->rx_bias_count == 1) {
3518 if (TASHA_IS_2_0(tasha->wcd9xxx))
3519 tasha_codec_init_flyback(codec);
3520 snd_soc_update_bits(codec, WCD9335_ANA_RX_SUPPLIES,
3521 0x01, 0x01);
3522 }
3523 break;
3524 case SND_SOC_DAPM_POST_PMD:
3525 tasha->rx_bias_count--;
3526 if (!tasha->rx_bias_count)
3527 snd_soc_update_bits(codec, WCD9335_ANA_RX_SUPPLIES,
3528 0x01, 0x00);
3529 break;
3530 };
3531 dev_dbg(codec->dev, "%s: Current RX BIAS user count: %d\n", __func__,
3532 tasha->rx_bias_count);
3533
3534 return 0;
3535}
3536
3537static void tasha_realign_anc_coeff(struct snd_soc_codec *codec,
3538 u16 reg1, u16 reg2)
3539{
3540 u8 val1, val2, tmpval1, tmpval2;
3541
3542 snd_soc_write(codec, reg1, 0x00);
3543 tmpval1 = snd_soc_read(codec, reg2);
3544 tmpval2 = snd_soc_read(codec, reg2);
3545 snd_soc_write(codec, reg1, 0x00);
3546 snd_soc_write(codec, reg2, 0xFF);
3547 snd_soc_write(codec, reg1, 0x01);
3548 snd_soc_write(codec, reg2, 0xFF);
3549
3550 snd_soc_write(codec, reg1, 0x00);
3551 val1 = snd_soc_read(codec, reg2);
3552 val2 = snd_soc_read(codec, reg2);
3553
3554 if (val1 == 0x0F && val2 == 0xFF) {
3555 dev_dbg(codec->dev, "%s: ANC0 co-eff index re-aligned\n",
3556 __func__);
3557 snd_soc_read(codec, reg2);
3558 snd_soc_write(codec, reg1, 0x00);
3559 snd_soc_write(codec, reg2, tmpval2);
3560 snd_soc_write(codec, reg1, 0x01);
3561 snd_soc_write(codec, reg2, tmpval1);
3562 } else if (val1 == 0xFF && val2 == 0x0F) {
3563 dev_dbg(codec->dev, "%s: ANC1 co-eff index already aligned\n",
3564 __func__);
3565 snd_soc_write(codec, reg1, 0x00);
3566 snd_soc_write(codec, reg2, tmpval1);
3567 snd_soc_write(codec, reg1, 0x01);
3568 snd_soc_write(codec, reg2, tmpval2);
3569 } else {
3570 dev_err(codec->dev, "%s: ANC0 co-eff index not aligned\n",
3571 __func__);
3572 }
3573}
3574
3575static int tasha_codec_enable_anc(struct snd_soc_dapm_widget *w,
3576 struct snd_kcontrol *kcontrol, int event)
3577{
3578 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
3579 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
3580 const char *filename;
3581 const struct firmware *fw;
3582 int i;
3583 int ret = 0;
3584 int num_anc_slots;
3585 struct wcd9xxx_anc_header *anc_head;
3586 struct firmware_cal *hwdep_cal = NULL;
3587 u32 anc_writes_size = 0;
3588 u32 anc_cal_size = 0;
3589 int anc_size_remaining;
3590 u32 *anc_ptr;
3591 u16 reg;
3592 u8 mask, val;
3593 size_t cal_size;
3594 const void *data;
3595
3596 if (!tasha->anc_func)
3597 return 0;
3598
3599 switch (event) {
3600 case SND_SOC_DAPM_PRE_PMU:
3601 hwdep_cal = wcdcal_get_fw_cal(tasha->fw_data, WCD9XXX_ANC_CAL);
3602 if (hwdep_cal) {
3603 data = hwdep_cal->data;
3604 cal_size = hwdep_cal->size;
3605 dev_dbg(codec->dev, "%s: using hwdep calibration\n",
3606 __func__);
3607 } else {
3608 filename = "wcd9335/wcd9335_anc.bin";
3609 ret = request_firmware(&fw, filename, codec->dev);
3610 if (ret != 0) {
3611 dev_err(codec->dev,
3612 "Failed to acquire ANC data: %d\n", ret);
3613 return -ENODEV;
3614 }
3615 if (!fw) {
3616 dev_err(codec->dev, "failed to get anc fw");
3617 return -ENODEV;
3618 }
3619 data = fw->data;
3620 cal_size = fw->size;
3621 dev_dbg(codec->dev,
3622 "%s: using request_firmware calibration\n", __func__);
3623 }
3624 if (cal_size < sizeof(struct wcd9xxx_anc_header)) {
3625 dev_err(codec->dev, "Not enough data\n");
3626 ret = -ENOMEM;
3627 goto err;
3628 }
3629 /* First number is the number of register writes */
3630 anc_head = (struct wcd9xxx_anc_header *)(data);
3631 anc_ptr = (u32 *)(data +
3632 sizeof(struct wcd9xxx_anc_header));
3633 anc_size_remaining = cal_size -
3634 sizeof(struct wcd9xxx_anc_header);
3635 num_anc_slots = anc_head->num_anc_slots;
3636
3637 if (tasha->anc_slot >= num_anc_slots) {
3638 dev_err(codec->dev, "Invalid ANC slot selected\n");
3639 ret = -EINVAL;
3640 goto err;
3641 }
3642 for (i = 0; i < num_anc_slots; i++) {
3643 if (anc_size_remaining < TASHA_PACKED_REG_SIZE) {
3644 dev_err(codec->dev,
3645 "Invalid register format\n");
3646 ret = -EINVAL;
3647 goto err;
3648 }
3649 anc_writes_size = (u32)(*anc_ptr);
3650 anc_size_remaining -= sizeof(u32);
3651 anc_ptr += 1;
3652
3653 if (anc_writes_size * TASHA_PACKED_REG_SIZE
3654 > anc_size_remaining) {
3655 dev_err(codec->dev,
3656 "Invalid register format\n");
3657 ret = -EINVAL;
3658 goto err;
3659 }
3660
3661 if (tasha->anc_slot == i)
3662 break;
3663
3664 anc_size_remaining -= (anc_writes_size *
3665 TASHA_PACKED_REG_SIZE);
3666 anc_ptr += anc_writes_size;
3667 }
3668 if (i == num_anc_slots) {
3669 dev_err(codec->dev, "Selected ANC slot not present\n");
3670 ret = -EINVAL;
3671 goto err;
3672 }
3673
3674 i = 0;
3675 anc_cal_size = anc_writes_size;
3676
3677 if (!strcmp(w->name, "RX INT0 DAC") ||
3678 !strcmp(w->name, "ANC SPK1 PA"))
3679 tasha_realign_anc_coeff(codec,
3680 WCD9335_CDC_ANC0_IIR_COEFF_1_CTL,
3681 WCD9335_CDC_ANC0_IIR_COEFF_2_CTL);
3682
3683 if (!strcmp(w->name, "RX INT1 DAC") ||
3684 !strcmp(w->name, "RX INT3 DAC")) {
3685 tasha_realign_anc_coeff(codec,
3686 WCD9335_CDC_ANC0_IIR_COEFF_1_CTL,
3687 WCD9335_CDC_ANC0_IIR_COEFF_2_CTL);
3688 anc_writes_size = anc_cal_size / 2;
3689 snd_soc_update_bits(codec,
3690 WCD9335_CDC_ANC0_CLK_RESET_CTL, 0x39, 0x39);
3691 } else if (!strcmp(w->name, "RX INT2 DAC") ||
3692 !strcmp(w->name, "RX INT4 DAC")) {
3693 tasha_realign_anc_coeff(codec,
3694 WCD9335_CDC_ANC1_IIR_COEFF_1_CTL,
3695 WCD9335_CDC_ANC1_IIR_COEFF_2_CTL);
3696 i = anc_cal_size / 2;
3697 snd_soc_update_bits(codec,
3698 WCD9335_CDC_ANC1_CLK_RESET_CTL, 0x39, 0x39);
3699 }
3700
3701 for (; i < anc_writes_size; i++) {
3702 TASHA_CODEC_UNPACK_ENTRY(anc_ptr[i], reg, mask, val);
3703 snd_soc_write(codec, reg, (val & mask));
3704 }
3705 if (!strcmp(w->name, "RX INT1 DAC") ||
3706 !strcmp(w->name, "RX INT3 DAC")) {
3707 snd_soc_update_bits(codec,
3708 WCD9335_CDC_ANC0_CLK_RESET_CTL, 0x08, 0x08);
3709 } else if (!strcmp(w->name, "RX INT2 DAC") ||
3710 !strcmp(w->name, "RX INT4 DAC")) {
3711 snd_soc_update_bits(codec,
3712 WCD9335_CDC_ANC1_CLK_RESET_CTL, 0x08, 0x08);
3713 }
3714
3715 if (!hwdep_cal)
3716 release_firmware(fw);
3717 break;
3718 case SND_SOC_DAPM_POST_PMU:
3719 /* Remove ANC Rx from reset */
3720 snd_soc_update_bits(codec, WCD9335_CDC_ANC0_CLK_RESET_CTL,
3721 0x08, 0x00);
3722 snd_soc_update_bits(codec, WCD9335_CDC_ANC1_CLK_RESET_CTL,
3723 0x08, 0x00);
3724 break;
3725 case SND_SOC_DAPM_POST_PMD:
3726 if (!strcmp(w->name, "ANC HPHL PA") ||
3727 !strcmp(w->name, "ANC EAR PA") ||
3728 !strcmp(w->name, "ANC SPK1 PA") ||
3729 !strcmp(w->name, "ANC LINEOUT1 PA")) {
3730 snd_soc_update_bits(codec,
3731 WCD9335_CDC_ANC0_MODE_1_CTL, 0x30, 0x00);
3732 msleep(50);
3733 snd_soc_update_bits(codec,
3734 WCD9335_CDC_ANC0_MODE_1_CTL, 0x01, 0x00);
3735 snd_soc_update_bits(codec,
3736 WCD9335_CDC_ANC0_CLK_RESET_CTL, 0x38, 0x38);
3737 snd_soc_update_bits(codec,
3738 WCD9335_CDC_ANC0_CLK_RESET_CTL, 0x07, 0x00);
3739 snd_soc_update_bits(codec,
3740 WCD9335_CDC_ANC0_CLK_RESET_CTL, 0x38, 0x00);
3741 } else if (!strcmp(w->name, "ANC HPHR PA") ||
3742 !strcmp(w->name, "ANC LINEOUT2 PA")) {
3743 snd_soc_update_bits(codec,
3744 WCD9335_CDC_ANC1_MODE_1_CTL, 0x30, 0x00);
3745 msleep(50);
3746 snd_soc_update_bits(codec,
3747 WCD9335_CDC_ANC1_MODE_1_CTL, 0x01, 0x00);
3748 snd_soc_update_bits(codec,
3749 WCD9335_CDC_ANC1_CLK_RESET_CTL, 0x38, 0x38);
3750 snd_soc_update_bits(codec,
3751 WCD9335_CDC_ANC1_CLK_RESET_CTL, 0x07, 0x00);
3752 snd_soc_update_bits(codec,
3753 WCD9335_CDC_ANC1_CLK_RESET_CTL, 0x38, 0x00);
3754 }
3755 break;
3756 }
3757
3758 return 0;
3759err:
3760 if (!hwdep_cal)
3761 release_firmware(fw);
3762 return ret;
3763}
3764
3765static void tasha_codec_clear_anc_tx_hold(struct tasha_priv *tasha)
3766{
3767 if (test_and_clear_bit(ANC_MIC_AMIC1, &tasha->status_mask))
3768 tasha_codec_set_tx_hold(tasha->codec, WCD9335_ANA_AMIC1, false);
3769 if (test_and_clear_bit(ANC_MIC_AMIC2, &tasha->status_mask))
3770 tasha_codec_set_tx_hold(tasha->codec, WCD9335_ANA_AMIC2, false);
3771 if (test_and_clear_bit(ANC_MIC_AMIC3, &tasha->status_mask))
3772 tasha_codec_set_tx_hold(tasha->codec, WCD9335_ANA_AMIC3, false);
3773 if (test_and_clear_bit(ANC_MIC_AMIC4, &tasha->status_mask))
3774 tasha_codec_set_tx_hold(tasha->codec, WCD9335_ANA_AMIC4, false);
3775 if (test_and_clear_bit(ANC_MIC_AMIC5, &tasha->status_mask))
3776 tasha_codec_set_tx_hold(tasha->codec, WCD9335_ANA_AMIC5, false);
3777 if (test_and_clear_bit(ANC_MIC_AMIC6, &tasha->status_mask))
3778 tasha_codec_set_tx_hold(tasha->codec, WCD9335_ANA_AMIC6, false);
3779}
3780
3781static void tasha_codec_hph_post_pa_config(struct tasha_priv *tasha,
3782 int mode, int event)
3783{
3784 u8 scale_val = 0;
3785
3786 if (!TASHA_IS_2_0(tasha->wcd9xxx))
3787 return;
3788
3789 switch (event) {
3790 case SND_SOC_DAPM_POST_PMU:
3791 switch (mode) {
3792 case CLS_H_HIFI:
3793 scale_val = 0x3;
3794 break;
3795 case CLS_H_LOHIFI:
3796 scale_val = 0x1;
3797 break;
3798 }
3799 if (tasha->anc_func) {
3800 /* Clear Tx FE HOLD if both PAs are enabled */
3801 if ((snd_soc_read(tasha->codec, WCD9335_ANA_HPH) &
3802 0xC0) == 0xC0) {
3803 tasha_codec_clear_anc_tx_hold(tasha);
3804 }
3805 }
3806 break;
3807 case SND_SOC_DAPM_PRE_PMD:
3808 scale_val = 0x6;
3809 break;
3810 }
3811
3812 if (scale_val)
3813 snd_soc_update_bits(tasha->codec, WCD9335_HPH_PA_CTL1, 0x0E,
3814 scale_val << 1);
3815 if (SND_SOC_DAPM_EVENT_ON(event)) {
3816 if (tasha->comp_enabled[COMPANDER_1] ||
3817 tasha->comp_enabled[COMPANDER_2]) {
3818 snd_soc_update_bits(tasha->codec, WCD9335_HPH_L_EN,
3819 0x20, 0x00);
3820 snd_soc_update_bits(tasha->codec, WCD9335_HPH_R_EN,
3821 0x20, 0x00);
3822 snd_soc_update_bits(tasha->codec, WCD9335_HPH_AUTO_CHOP,
3823 0x20, 0x20);
3824 }
3825 snd_soc_update_bits(tasha->codec, WCD9335_HPH_L_EN, 0x1F,
3826 tasha->hph_l_gain);
3827 snd_soc_update_bits(tasha->codec, WCD9335_HPH_R_EN, 0x1F,
3828 tasha->hph_r_gain);
3829 }
3830
3831 if (SND_SOC_DAPM_EVENT_OFF(event)) {
3832 snd_soc_update_bits(tasha->codec, WCD9335_HPH_AUTO_CHOP, 0x20,
3833 0x00);
3834 }
3835}
3836
3837static void tasha_codec_override(struct snd_soc_codec *codec,
3838 int mode,
3839 int event)
3840{
3841 if (mode == CLS_AB) {
3842 switch (event) {
3843 case SND_SOC_DAPM_POST_PMU:
3844 if (!(snd_soc_read(codec,
3845 WCD9335_CDC_RX2_RX_PATH_CTL) & 0x10) &&
3846 (!(snd_soc_read(codec,
3847 WCD9335_CDC_RX1_RX_PATH_CTL) & 0x10)))
3848 snd_soc_update_bits(codec,
3849 WCD9XXX_A_ANA_RX_SUPPLIES, 0x02, 0x02);
3850 break;
3851 case SND_SOC_DAPM_POST_PMD:
3852 snd_soc_update_bits(codec,
3853 WCD9XXX_A_ANA_RX_SUPPLIES, 0x02, 0x00);
3854 break;
3855 }
3856 }
3857}
3858
3859static int tasha_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
3860 struct snd_kcontrol *kcontrol,
3861 int event)
3862{
3863 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
3864 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
3865 int hph_mode = tasha->hph_mode;
3866 int ret = 0;
3867
3868 dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
3869
3870 switch (event) {
3871 case SND_SOC_DAPM_PRE_PMU:
3872 if ((!(strcmp(w->name, "ANC HPHR PA"))) &&
3873 (test_bit(HPH_PA_DELAY, &tasha->status_mask))) {
3874 snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0xC0, 0xC0);
3875 }
3876 set_bit(HPH_PA_DELAY, &tasha->status_mask);
Vatsal Buchae9a50072017-09-06 17:40:11 +05303877 if (!(strcmp(w->name, "HPHR PA")))
3878 snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0x40, 0x40);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303879 break;
3880 case SND_SOC_DAPM_POST_PMU:
3881 if (!(strcmp(w->name, "ANC HPHR PA"))) {
3882 if ((snd_soc_read(codec, WCD9335_ANA_HPH) & 0xC0)
3883 != 0xC0)
3884 /*
3885 * If PA_EN is not set (potentially in ANC case)
3886 * then do nothing for POST_PMU and let left
3887 * channel handle everything.
3888 */
3889 break;
3890 }
3891 /*
3892 * 7ms sleep is required after PA is enabled as per
3893 * HW requirement
3894 */
3895 if (test_bit(HPH_PA_DELAY, &tasha->status_mask)) {
3896 usleep_range(7000, 7100);
3897 clear_bit(HPH_PA_DELAY, &tasha->status_mask);
3898 }
3899 tasha_codec_hph_post_pa_config(tasha, hph_mode, event);
3900 snd_soc_update_bits(codec, WCD9335_CDC_RX2_RX_PATH_CTL,
3901 0x10, 0x00);
3902 /* Remove mix path mute if it is enabled */
3903 if ((snd_soc_read(codec, WCD9335_CDC_RX2_RX_PATH_MIX_CTL)) &
3904 0x10)
3905 snd_soc_update_bits(codec,
3906 WCD9335_CDC_RX2_RX_PATH_MIX_CTL,
3907 0x10, 0x00);
3908
3909 if (!(strcmp(w->name, "ANC HPHR PA"))) {
3910 /* Do everything needed for left channel */
3911 snd_soc_update_bits(codec, WCD9335_CDC_RX1_RX_PATH_CTL,
3912 0x10, 0x00);
3913 /* Remove mix path mute if it is enabled */
3914 if ((snd_soc_read(codec,
3915 WCD9335_CDC_RX1_RX_PATH_MIX_CTL)) &
3916 0x10)
3917 snd_soc_update_bits(codec,
3918 WCD9335_CDC_RX1_RX_PATH_MIX_CTL,
3919 0x10, 0x00);
3920 /* Remove ANC Rx from reset */
3921 ret = tasha_codec_enable_anc(w, kcontrol, event);
3922 }
3923 tasha_codec_override(codec, hph_mode, event);
3924 break;
3925
3926 case SND_SOC_DAPM_PRE_PMD:
3927 blocking_notifier_call_chain(&tasha->notifier,
3928 WCD_EVENT_PRE_HPHR_PA_OFF,
3929 &tasha->mbhc);
3930 tasha_codec_hph_post_pa_config(tasha, hph_mode, event);
Vatsal Buchae9a50072017-09-06 17:40:11 +05303931 if (!(strcmp(w->name, "ANC HPHR PA")) ||
3932 !(strcmp(w->name, "HPHR PA")))
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303933 snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0x40, 0x00);
3934 break;
3935 case SND_SOC_DAPM_POST_PMD:
3936 /* 5ms sleep is required after PA is disabled as per
3937 * HW requirement
3938 */
3939 usleep_range(5000, 5500);
3940 tasha_codec_override(codec, hph_mode, event);
3941 blocking_notifier_call_chain(&tasha->notifier,
3942 WCD_EVENT_POST_HPHR_PA_OFF,
3943 &tasha->mbhc);
3944
3945 if (!(strcmp(w->name, "ANC HPHR PA"))) {
3946 ret = tasha_codec_enable_anc(w, kcontrol, event);
3947 snd_soc_update_bits(codec,
3948 WCD9335_CDC_RX2_RX_PATH_CFG0, 0x10, 0x00);
3949 }
3950 break;
3951 };
3952
3953 return ret;
3954}
3955
3956static int tasha_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
3957 struct snd_kcontrol *kcontrol,
3958 int event)
3959{
3960 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
3961 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
3962 int hph_mode = tasha->hph_mode;
3963 int ret = 0;
3964
3965 dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
3966
3967 switch (event) {
3968 case SND_SOC_DAPM_PRE_PMU:
3969 if ((!(strcmp(w->name, "ANC HPHL PA"))) &&
3970 (test_bit(HPH_PA_DELAY, &tasha->status_mask))) {
3971 snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0xC0, 0xC0);
3972 }
Vatsal Buchae9a50072017-09-06 17:40:11 +05303973 if (!(strcmp(w->name, "HPHL PA")))
3974 snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0x80, 0x80);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303975 set_bit(HPH_PA_DELAY, &tasha->status_mask);
3976 break;
3977 case SND_SOC_DAPM_POST_PMU:
3978 if (!(strcmp(w->name, "ANC HPHL PA"))) {
3979 if ((snd_soc_read(codec, WCD9335_ANA_HPH) & 0xC0)
3980 != 0xC0)
3981 /*
3982 * If PA_EN is not set (potentially in ANC case)
3983 * then do nothing for POST_PMU and let right
3984 * channel handle everything.
3985 */
3986 break;
3987 }
3988 /*
3989 * 7ms sleep is required after PA is enabled as per
3990 * HW requirement
3991 */
3992 if (test_bit(HPH_PA_DELAY, &tasha->status_mask)) {
3993 usleep_range(7000, 7100);
3994 clear_bit(HPH_PA_DELAY, &tasha->status_mask);
3995 }
3996
3997 tasha_codec_hph_post_pa_config(tasha, hph_mode, event);
3998 snd_soc_update_bits(codec, WCD9335_CDC_RX1_RX_PATH_CTL,
3999 0x10, 0x00);
4000 /* Remove mix path mute if it is enabled */
4001 if ((snd_soc_read(codec, WCD9335_CDC_RX1_RX_PATH_MIX_CTL)) &
4002 0x10)
4003 snd_soc_update_bits(codec,
4004 WCD9335_CDC_RX1_RX_PATH_MIX_CTL,
4005 0x10, 0x00);
4006
4007 if (!(strcmp(w->name, "ANC HPHL PA"))) {
4008 /* Do everything needed for right channel */
4009 snd_soc_update_bits(codec, WCD9335_CDC_RX2_RX_PATH_CTL,
4010 0x10, 0x00);
4011 /* Remove mix path mute if it is enabled */
4012 if ((snd_soc_read(codec,
4013 WCD9335_CDC_RX2_RX_PATH_MIX_CTL)) &
4014 0x10)
4015 snd_soc_update_bits(codec,
4016 WCD9335_CDC_RX2_RX_PATH_MIX_CTL,
4017 0x10, 0x00);
4018
4019 /* Remove ANC Rx from reset */
4020 ret = tasha_codec_enable_anc(w, kcontrol, event);
4021 }
4022 tasha_codec_override(codec, hph_mode, event);
4023 break;
4024 case SND_SOC_DAPM_PRE_PMD:
4025 blocking_notifier_call_chain(&tasha->notifier,
4026 WCD_EVENT_PRE_HPHL_PA_OFF,
4027 &tasha->mbhc);
4028 tasha_codec_hph_post_pa_config(tasha, hph_mode, event);
Vatsal Buchae9a50072017-09-06 17:40:11 +05304029 if (!(strcmp(w->name, "ANC HPHL PA")) ||
4030 !(strcmp(w->name, "HPHL PA")))
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304031 snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0x80, 0x00);
4032 break;
4033 case SND_SOC_DAPM_POST_PMD:
4034 /* 5ms sleep is required after PA is disabled as per
4035 * HW requirement
4036 */
4037 usleep_range(5000, 5500);
4038 tasha_codec_override(codec, hph_mode, event);
4039 blocking_notifier_call_chain(&tasha->notifier,
4040 WCD_EVENT_POST_HPHL_PA_OFF,
4041 &tasha->mbhc);
4042
4043 if (!(strcmp(w->name, "ANC HPHL PA"))) {
4044 ret = tasha_codec_enable_anc(w, kcontrol, event);
4045 snd_soc_update_bits(codec,
4046 WCD9335_CDC_RX1_RX_PATH_CFG0, 0x10, 0x00);
4047 }
4048 break;
4049 };
4050
4051 return ret;
4052}
4053
4054static int tasha_codec_enable_lineout_pa(struct snd_soc_dapm_widget *w,
4055 struct snd_kcontrol *kcontrol,
4056 int event)
4057{
4058 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
4059 u16 lineout_vol_reg = 0, lineout_mix_vol_reg = 0;
4060 int ret = 0;
4061
4062 dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
4063
4064 if (w->reg == WCD9335_ANA_LO_1_2) {
4065 if (w->shift == 7) {
4066 lineout_vol_reg = WCD9335_CDC_RX3_RX_PATH_CTL;
4067 lineout_mix_vol_reg = WCD9335_CDC_RX3_RX_PATH_MIX_CTL;
4068 } else if (w->shift == 6) {
4069 lineout_vol_reg = WCD9335_CDC_RX4_RX_PATH_CTL;
4070 lineout_mix_vol_reg = WCD9335_CDC_RX4_RX_PATH_MIX_CTL;
4071 }
4072 } else if (w->reg == WCD9335_ANA_LO_3_4) {
4073 if (w->shift == 7) {
4074 lineout_vol_reg = WCD9335_CDC_RX5_RX_PATH_CTL;
4075 lineout_mix_vol_reg = WCD9335_CDC_RX5_RX_PATH_MIX_CTL;
4076 } else if (w->shift == 6) {
4077 lineout_vol_reg = WCD9335_CDC_RX6_RX_PATH_CTL;
4078 lineout_mix_vol_reg = WCD9335_CDC_RX6_RX_PATH_MIX_CTL;
4079 }
4080 } else {
4081 dev_err(codec->dev, "%s: Error enabling lineout PA\n",
4082 __func__);
4083 return -EINVAL;
4084 }
4085
4086 switch (event) {
4087 case SND_SOC_DAPM_POST_PMU:
4088 /* 5ms sleep is required after PA is enabled as per
4089 * HW requirement
4090 */
4091 usleep_range(5000, 5500);
4092 snd_soc_update_bits(codec, lineout_vol_reg,
4093 0x10, 0x00);
4094 /* Remove mix path mute if it is enabled */
4095 if ((snd_soc_read(codec, lineout_mix_vol_reg)) & 0x10)
4096 snd_soc_update_bits(codec,
4097 lineout_mix_vol_reg,
4098 0x10, 0x00);
4099 if (!(strcmp(w->name, "ANC LINEOUT1 PA")) ||
4100 !(strcmp(w->name, "ANC LINEOUT2 PA")))
4101 ret = tasha_codec_enable_anc(w, kcontrol, event);
4102 tasha_codec_override(codec, CLS_AB, event);
4103 break;
4104 case SND_SOC_DAPM_POST_PMD:
4105 /* 5ms sleep is required after PA is disabled as per
4106 * HW requirement
4107 */
4108 usleep_range(5000, 5500);
4109 tasha_codec_override(codec, CLS_AB, event);
4110 if (!(strcmp(w->name, "ANC LINEOUT1 PA")) ||
4111 !(strcmp(w->name, "ANC LINEOUT2 PA"))) {
4112 ret = tasha_codec_enable_anc(w, kcontrol, event);
4113 if (!(strcmp(w->name, "ANC LINEOUT1 PA")))
4114 snd_soc_update_bits(codec,
4115 WCD9335_CDC_RX3_RX_PATH_CFG0, 0x10, 0x10);
4116 else
4117 snd_soc_update_bits(codec,
4118 WCD9335_CDC_RX4_RX_PATH_CFG0, 0x10, 0x10);
4119 }
4120 break;
4121 };
4122
4123 return ret;
4124}
4125
4126static void tasha_spk_anc_update_callback(struct work_struct *work)
4127{
4128 struct spk_anc_work *spk_anc_dwork;
4129 struct tasha_priv *tasha;
4130 struct delayed_work *delayed_work;
4131 struct snd_soc_codec *codec;
4132
4133 delayed_work = to_delayed_work(work);
4134 spk_anc_dwork = container_of(delayed_work, struct spk_anc_work, dwork);
4135 tasha = spk_anc_dwork->tasha;
4136 codec = tasha->codec;
4137
4138 snd_soc_update_bits(codec, WCD9335_CDC_RX7_RX_PATH_CFG0, 0x10, 0x10);
4139}
4140
4141static int tasha_codec_enable_spk_anc(struct snd_soc_dapm_widget *w,
4142 struct snd_kcontrol *kcontrol,
4143 int event)
4144{
4145 int ret = 0;
4146 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
4147 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
4148
4149 dev_dbg(codec->dev, "%s %s %d %d\n", __func__, w->name, event,
4150 tasha->anc_func);
4151
4152 if (!tasha->anc_func)
4153 return 0;
4154
4155 switch (event) {
4156 case SND_SOC_DAPM_PRE_PMU:
4157 ret = tasha_codec_enable_anc(w, kcontrol, event);
4158 schedule_delayed_work(&tasha->spk_anc_dwork.dwork,
4159 msecs_to_jiffies(spk_anc_en_delay));
4160 break;
4161 case SND_SOC_DAPM_POST_PMD:
4162 cancel_delayed_work_sync(&tasha->spk_anc_dwork.dwork);
4163 snd_soc_update_bits(codec, WCD9335_CDC_RX7_RX_PATH_CFG0,
4164 0x10, 0x00);
4165 ret = tasha_codec_enable_anc(w, kcontrol, event);
4166 break;
4167 }
4168 return ret;
4169}
4170
4171static int tasha_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
4172 struct snd_kcontrol *kcontrol,
4173 int event)
4174{
4175 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
4176 int ret = 0;
4177
4178 dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
4179
4180 switch (event) {
4181 case SND_SOC_DAPM_POST_PMU:
4182 /* 5ms sleep is required after PA is enabled as per
4183 * HW requirement
4184 */
4185 usleep_range(5000, 5500);
4186 snd_soc_update_bits(codec, WCD9335_CDC_RX0_RX_PATH_CTL,
4187 0x10, 0x00);
4188 /* Remove mix path mute if it is enabled */
4189 if ((snd_soc_read(codec, WCD9335_CDC_RX0_RX_PATH_MIX_CTL)) &
4190 0x10)
4191 snd_soc_update_bits(codec,
4192 WCD9335_CDC_RX0_RX_PATH_MIX_CTL,
4193 0x10, 0x00);
4194 break;
4195 case SND_SOC_DAPM_POST_PMD:
4196 /* 5ms sleep is required after PA is disabled as per
4197 * HW requirement
4198 */
4199 usleep_range(5000, 5500);
4200
4201 if (!(strcmp(w->name, "ANC EAR PA"))) {
4202 ret = tasha_codec_enable_anc(w, kcontrol, event);
4203 snd_soc_update_bits(codec,
4204 WCD9335_CDC_RX0_RX_PATH_CFG0, 0x10, 0x00);
4205 }
4206 break;
4207 };
4208
4209 return ret;
4210}
4211
4212static void tasha_codec_hph_mode_gain_opt(struct snd_soc_codec *codec,
4213 u8 gain)
4214{
4215 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
4216 u8 hph_l_en, hph_r_en;
4217 u8 l_val, r_val;
4218 u8 hph_pa_status;
4219 bool is_hphl_pa, is_hphr_pa;
4220
4221 hph_pa_status = snd_soc_read(codec, WCD9335_ANA_HPH);
4222 is_hphl_pa = hph_pa_status >> 7;
4223 is_hphr_pa = (hph_pa_status & 0x40) >> 6;
4224
4225 hph_l_en = snd_soc_read(codec, WCD9335_HPH_L_EN);
4226 hph_r_en = snd_soc_read(codec, WCD9335_HPH_R_EN);
4227
4228 l_val = (hph_l_en & 0xC0) | 0x20 | gain;
4229 r_val = (hph_r_en & 0xC0) | 0x20 | gain;
4230
4231 /*
4232 * Set HPH_L & HPH_R gain source selection to REGISTER
4233 * for better click and pop only if corresponding PAs are
4234 * not enabled. Also cache the values of the HPHL/R
4235 * PA gains to be applied after PAs are enabled
4236 */
4237 if ((l_val != hph_l_en) && !is_hphl_pa) {
4238 snd_soc_write(codec, WCD9335_HPH_L_EN, l_val);
4239 tasha->hph_l_gain = hph_l_en & 0x1F;
4240 }
4241
4242 if ((r_val != hph_r_en) && !is_hphr_pa) {
4243 snd_soc_write(codec, WCD9335_HPH_R_EN, r_val);
4244 tasha->hph_r_gain = hph_r_en & 0x1F;
4245 }
4246}
4247
4248static void tasha_codec_hph_lohifi_config(struct snd_soc_codec *codec,
4249 int event)
4250{
4251 if (SND_SOC_DAPM_EVENT_ON(event)) {
4252 snd_soc_update_bits(codec, WCD9335_RX_BIAS_HPH_PA, 0x0F, 0x06);
4253 snd_soc_update_bits(codec, WCD9335_RX_BIAS_HPH_RDACBUFF_CNP2,
4254 0xF0, 0x40);
4255 snd_soc_update_bits(codec, WCD9335_HPH_CNP_WG_CTL, 0x07, 0x03);
4256 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x08, 0x08);
4257 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL1, 0x0E, 0x0C);
4258 tasha_codec_hph_mode_gain_opt(codec, 0x11);
4259 }
4260
4261 if (SND_SOC_DAPM_EVENT_OFF(event)) {
4262 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x08, 0x00);
4263 snd_soc_update_bits(codec, WCD9335_HPH_CNP_WG_CTL, 0x07, 0x02);
4264 snd_soc_write(codec, WCD9335_RX_BIAS_HPH_RDACBUFF_CNP2, 0x8A);
4265 snd_soc_update_bits(codec, WCD9335_RX_BIAS_HPH_PA, 0x0F, 0x0A);
4266 }
4267}
4268
4269static void tasha_codec_hph_lp_config(struct snd_soc_codec *codec,
4270 int event)
4271{
4272 if (SND_SOC_DAPM_EVENT_ON(event)) {
4273 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL1, 0x0E, 0x0C);
4274 tasha_codec_hph_mode_gain_opt(codec, 0x10);
4275 snd_soc_update_bits(codec, WCD9335_HPH_CNP_WG_CTL, 0x07, 0x03);
4276 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x08, 0x08);
4277 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x04, 0x04);
4278 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x20, 0x20);
4279 snd_soc_update_bits(codec, WCD9335_HPH_RDAC_LDO_CTL, 0x07,
4280 0x01);
4281 snd_soc_update_bits(codec, WCD9335_HPH_RDAC_LDO_CTL, 0x70,
4282 0x10);
4283 snd_soc_update_bits(codec, WCD9335_RX_BIAS_HPH_RDAC_LDO,
4284 0x0F, 0x01);
4285 snd_soc_update_bits(codec, WCD9335_RX_BIAS_HPH_RDAC_LDO,
4286 0xF0, 0x10);
4287 }
4288
4289 if (SND_SOC_DAPM_EVENT_OFF(event)) {
4290 snd_soc_write(codec, WCD9335_RX_BIAS_HPH_RDAC_LDO, 0x88);
4291 snd_soc_write(codec, WCD9335_HPH_RDAC_LDO_CTL, 0x33);
4292 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x20, 0x00);
4293 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x04, 0x00);
4294 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x08, 0x00);
4295 snd_soc_update_bits(codec, WCD9335_HPH_CNP_WG_CTL, 0x07, 0x02);
4296 snd_soc_update_bits(codec, WCD9335_HPH_R_EN, 0xC0, 0x80);
4297 snd_soc_update_bits(codec, WCD9335_HPH_L_EN, 0xC0, 0x80);
4298 }
4299}
4300
4301static void tasha_codec_hph_hifi_config(struct snd_soc_codec *codec,
4302 int event)
4303{
4304 if (SND_SOC_DAPM_EVENT_ON(event)) {
4305 snd_soc_update_bits(codec, WCD9335_HPH_CNP_WG_CTL, 0x07, 0x03);
4306 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x08, 0x08);
4307 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL1, 0x0E, 0x0C);
4308 tasha_codec_hph_mode_gain_opt(codec, 0x11);
4309 }
4310
4311 if (SND_SOC_DAPM_EVENT_OFF(event)) {
4312 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x08, 0x00);
4313 snd_soc_update_bits(codec, WCD9335_HPH_CNP_WG_CTL, 0x07, 0x02);
4314 }
4315}
4316
4317static void tasha_codec_hph_mode_config(struct snd_soc_codec *codec,
4318 int event, int mode)
4319{
4320 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
4321
4322 if (!TASHA_IS_2_0(tasha->wcd9xxx))
4323 return;
4324
4325 switch (mode) {
4326 case CLS_H_LP:
4327 tasha_codec_hph_lp_config(codec, event);
4328 break;
4329 case CLS_H_LOHIFI:
4330 tasha_codec_hph_lohifi_config(codec, event);
4331 break;
4332 case CLS_H_HIFI:
4333 tasha_codec_hph_hifi_config(codec, event);
4334 break;
4335 }
4336}
4337
4338static int tasha_codec_hphr_dac_event(struct snd_soc_dapm_widget *w,
4339 struct snd_kcontrol *kcontrol,
4340 int event)
4341{
4342 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
4343 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
4344 struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent);
4345 int hph_mode = tasha->hph_mode;
4346 u8 dem_inp;
4347 int ret = 0;
4348
4349 dev_dbg(codec->dev, "%s wname: %s event: %d hph_mode: %d\n", __func__,
4350 w->name, event, hph_mode);
4351
4352 switch (event) {
4353 case SND_SOC_DAPM_PRE_PMU:
4354 if (tasha->anc_func) {
4355 ret = tasha_codec_enable_anc(w, kcontrol, event);
4356 /* 40 msec delay is needed to avoid click and pop */
4357 msleep(40);
4358 }
4359
4360 /* Read DEM INP Select */
4361 dem_inp = snd_soc_read(codec, WCD9335_CDC_RX2_RX_PATH_SEC0) &
4362 0x03;
4363 if (((hph_mode == CLS_H_HIFI) || (hph_mode == CLS_H_LOHIFI) ||
4364 (hph_mode == CLS_H_LP)) && (dem_inp != 0x01)) {
4365 dev_err(codec->dev, "%s: DEM Input not set correctly, hph_mode: %d\n",
4366 __func__, hph_mode);
4367 return -EINVAL;
4368 }
4369 wcd_clsh_fsm(codec, &tasha->clsh_d,
4370 WCD_CLSH_EVENT_PRE_DAC,
4371 WCD_CLSH_STATE_HPHR,
4372 ((hph_mode == CLS_H_LOHIFI) ?
4373 CLS_H_HIFI : hph_mode));
4374
Vatsal Buchae9a50072017-09-06 17:40:11 +05304375 if (!(strcmp(w->name, "RX INT2 DAC")))
4376 snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0x10, 0x10);
4377
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304378 tasha_codec_hph_mode_config(codec, event, hph_mode);
4379
4380 if (tasha->anc_func)
4381 snd_soc_update_bits(codec,
4382 WCD9335_CDC_RX2_RX_PATH_CFG0, 0x10, 0x10);
4383
4384 break;
4385 case SND_SOC_DAPM_POST_PMU:
4386 /* 1000us required as per HW requirement */
4387 usleep_range(1000, 1100);
4388 if ((hph_mode == CLS_H_LP) &&
4389 (TASHA_IS_1_1(wcd9xxx))) {
4390 snd_soc_update_bits(codec, WCD9335_HPH_L_DAC_CTL,
4391 0x03, 0x03);
4392 }
4393 break;
4394 case SND_SOC_DAPM_PRE_PMD:
4395 if ((hph_mode == CLS_H_LP) &&
4396 (TASHA_IS_1_1(wcd9xxx))) {
4397 snd_soc_update_bits(codec, WCD9335_HPH_L_DAC_CTL,
4398 0x03, 0x00);
4399 }
Vatsal Buchae9a50072017-09-06 17:40:11 +05304400 if (!(strcmp(w->name, "RX INT2 DAC")))
4401 snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0x10, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304402 break;
4403 case SND_SOC_DAPM_POST_PMD:
4404 /* 1000us required as per HW requirement */
4405 usleep_range(1000, 1100);
4406
4407 if (!(wcd_clsh_get_clsh_state(&tasha->clsh_d) &
4408 WCD_CLSH_STATE_HPHL))
4409 tasha_codec_hph_mode_config(codec, event, hph_mode);
4410
4411 wcd_clsh_fsm(codec, &tasha->clsh_d,
4412 WCD_CLSH_EVENT_POST_PA,
4413 WCD_CLSH_STATE_HPHR,
4414 ((hph_mode == CLS_H_LOHIFI) ?
4415 CLS_H_HIFI : hph_mode));
4416 break;
4417 };
4418
4419 return ret;
4420}
4421
4422static int tasha_codec_hphl_dac_event(struct snd_soc_dapm_widget *w,
4423 struct snd_kcontrol *kcontrol,
4424 int event)
4425{
4426 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
4427 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
4428 struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent);
4429 int hph_mode = tasha->hph_mode;
4430 u8 dem_inp;
4431 int ret = 0;
4432 uint32_t impedl = 0, impedr = 0;
4433
4434 dev_dbg(codec->dev, "%s wname: %s event: %d hph_mode: %d\n", __func__,
4435 w->name, event, hph_mode);
4436
4437 switch (event) {
4438 case SND_SOC_DAPM_PRE_PMU:
4439 if (tasha->anc_func) {
4440 ret = tasha_codec_enable_anc(w, kcontrol, event);
4441 /* 40 msec delay is needed to avoid click and pop */
4442 msleep(40);
4443 }
4444
4445 /* Read DEM INP Select */
4446 dem_inp = snd_soc_read(codec, WCD9335_CDC_RX1_RX_PATH_SEC0) &
4447 0x03;
4448 if (((hph_mode == CLS_H_HIFI) || (hph_mode == CLS_H_LOHIFI) ||
4449 (hph_mode == CLS_H_LP)) && (dem_inp != 0x01)) {
4450 dev_err(codec->dev, "%s: DEM Input not set correctly, hph_mode: %d\n",
4451 __func__, hph_mode);
4452 return -EINVAL;
4453 }
4454 wcd_clsh_fsm(codec, &tasha->clsh_d,
4455 WCD_CLSH_EVENT_PRE_DAC,
4456 WCD_CLSH_STATE_HPHL,
4457 ((hph_mode == CLS_H_LOHIFI) ?
4458 CLS_H_HIFI : hph_mode));
4459
Vatsal Buchae9a50072017-09-06 17:40:11 +05304460 if (!(strcmp(w->name, "RX INT1 DAC")))
4461 snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0x20, 0x20);
4462
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304463 tasha_codec_hph_mode_config(codec, event, hph_mode);
4464
4465 if (tasha->anc_func)
4466 snd_soc_update_bits(codec,
4467 WCD9335_CDC_RX1_RX_PATH_CFG0, 0x10, 0x10);
4468
4469 ret = wcd_mbhc_get_impedance(&tasha->mbhc,
4470 &impedl, &impedr);
4471 if (!ret) {
4472 wcd_clsh_imped_config(codec, impedl, false);
4473 set_bit(CLASSH_CONFIG, &tasha->status_mask);
4474 } else {
4475 dev_dbg(codec->dev, "%s: Failed to get mbhc impedance %d\n",
4476 __func__, ret);
4477 ret = 0;
4478 }
4479
4480
4481 break;
4482 case SND_SOC_DAPM_POST_PMU:
4483 /* 1000us required as per HW requirement */
4484 usleep_range(1000, 1100);
4485 if ((hph_mode == CLS_H_LP) &&
4486 (TASHA_IS_1_1(wcd9xxx))) {
4487 snd_soc_update_bits(codec, WCD9335_HPH_L_DAC_CTL,
4488 0x03, 0x03);
4489 }
4490 break;
4491 case SND_SOC_DAPM_PRE_PMD:
Vatsal Buchae9a50072017-09-06 17:40:11 +05304492 if (!(strcmp(w->name, "RX INT1 DAC")))
4493 snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0x20, 0x00);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304494 if ((hph_mode == CLS_H_LP) &&
4495 (TASHA_IS_1_1(wcd9xxx))) {
4496 snd_soc_update_bits(codec, WCD9335_HPH_L_DAC_CTL,
4497 0x03, 0x00);
4498 }
4499 break;
4500 case SND_SOC_DAPM_POST_PMD:
4501 /* 1000us required as per HW requirement */
4502 usleep_range(1000, 1100);
4503
4504 if (!(wcd_clsh_get_clsh_state(&tasha->clsh_d) &
4505 WCD_CLSH_STATE_HPHR))
4506 tasha_codec_hph_mode_config(codec, event, hph_mode);
4507 wcd_clsh_fsm(codec, &tasha->clsh_d,
4508 WCD_CLSH_EVENT_POST_PA,
4509 WCD_CLSH_STATE_HPHL,
4510 ((hph_mode == CLS_H_LOHIFI) ?
4511 CLS_H_HIFI : hph_mode));
4512
4513 if (test_bit(CLASSH_CONFIG, &tasha->status_mask)) {
4514 wcd_clsh_imped_config(codec, impedl, true);
4515 clear_bit(CLASSH_CONFIG, &tasha->status_mask);
4516 } else
4517 dev_dbg(codec->dev, "%s: Failed to get mbhc impedance %d\n",
4518 __func__, ret);
4519
4520
4521 break;
4522 };
4523
4524 return ret;
4525}
4526
4527static int tasha_codec_lineout_dac_event(struct snd_soc_dapm_widget *w,
4528 struct snd_kcontrol *kcontrol,
4529 int event)
4530{
4531 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
4532 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
4533 int ret = 0;
4534
4535 dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
4536
4537 switch (event) {
4538 case SND_SOC_DAPM_PRE_PMU:
4539 if (tasha->anc_func &&
4540 (!strcmp(w->name, "RX INT3 DAC") ||
4541 !strcmp(w->name, "RX INT4 DAC")))
4542 ret = tasha_codec_enable_anc(w, kcontrol, event);
4543
4544 wcd_clsh_fsm(codec, &tasha->clsh_d,
4545 WCD_CLSH_EVENT_PRE_DAC,
4546 WCD_CLSH_STATE_LO,
4547 CLS_AB);
4548
4549 if (tasha->anc_func) {
4550 if (!strcmp(w->name, "RX INT3 DAC"))
4551 snd_soc_update_bits(codec,
4552 WCD9335_CDC_RX3_RX_PATH_CFG0, 0x10, 0x10);
4553 else if (!strcmp(w->name, "RX INT4 DAC"))
4554 snd_soc_update_bits(codec,
4555 WCD9335_CDC_RX4_RX_PATH_CFG0, 0x10, 0x10);
4556 }
4557 break;
4558 case SND_SOC_DAPM_POST_PMD:
4559 wcd_clsh_fsm(codec, &tasha->clsh_d,
4560 WCD_CLSH_EVENT_POST_PA,
4561 WCD_CLSH_STATE_LO,
4562 CLS_AB);
4563 break;
4564 }
4565
4566 return 0;
4567}
4568
4569static const struct snd_soc_dapm_widget tasha_dapm_i2s_widgets[] = {
4570 SND_SOC_DAPM_SUPPLY("RX_I2S_CTL", WCD9335_DATA_HUB_DATA_HUB_RX_I2S_CTL,
4571 0, 0, NULL, 0),
4572 SND_SOC_DAPM_SUPPLY("TX_I2S_CTL", WCD9335_DATA_HUB_DATA_HUB_TX_I2S_CTL,
4573 0, 0, NULL, 0),
4574};
4575
4576static int tasha_codec_ear_dac_event(struct snd_soc_dapm_widget *w,
4577 struct snd_kcontrol *kcontrol,
4578 int event)
4579{
4580 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
4581 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
4582 int ret = 0;
4583
4584 dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
4585
4586 switch (event) {
4587 case SND_SOC_DAPM_PRE_PMU:
4588 if (tasha->anc_func)
4589 ret = tasha_codec_enable_anc(w, kcontrol, event);
4590
4591 wcd_clsh_fsm(codec, &tasha->clsh_d,
4592 WCD_CLSH_EVENT_PRE_DAC,
4593 WCD_CLSH_STATE_EAR,
4594 CLS_H_NORMAL);
4595 if (tasha->anc_func)
4596 snd_soc_update_bits(codec,
4597 WCD9335_CDC_RX0_RX_PATH_CFG0, 0x10, 0x10);
4598
4599 break;
4600 case SND_SOC_DAPM_POST_PMU:
4601 break;
4602 case SND_SOC_DAPM_PRE_PMD:
4603 break;
4604 case SND_SOC_DAPM_POST_PMD:
4605 wcd_clsh_fsm(codec, &tasha->clsh_d,
4606 WCD_CLSH_EVENT_POST_PA,
4607 WCD_CLSH_STATE_EAR,
4608 CLS_H_NORMAL);
4609 break;
4610 };
4611
4612 return ret;
4613}
4614
4615static int tasha_codec_spk_boost_event(struct snd_soc_dapm_widget *w,
4616 struct snd_kcontrol *kcontrol,
4617 int event)
4618{
4619 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
4620 u16 boost_path_ctl, boost_path_cfg1;
4621 u16 reg, reg_mix;
4622
4623 dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
4624
4625 if (!strcmp(w->name, "RX INT7 CHAIN")) {
4626 boost_path_ctl = WCD9335_CDC_BOOST0_BOOST_PATH_CTL;
4627 boost_path_cfg1 = WCD9335_CDC_RX7_RX_PATH_CFG1;
4628 reg = WCD9335_CDC_RX7_RX_PATH_CTL;
4629 reg_mix = WCD9335_CDC_RX7_RX_PATH_MIX_CTL;
4630 } else if (!strcmp(w->name, "RX INT8 CHAIN")) {
4631 boost_path_ctl = WCD9335_CDC_BOOST1_BOOST_PATH_CTL;
4632 boost_path_cfg1 = WCD9335_CDC_RX8_RX_PATH_CFG1;
4633 reg = WCD9335_CDC_RX8_RX_PATH_CTL;
4634 reg_mix = WCD9335_CDC_RX8_RX_PATH_MIX_CTL;
4635 } else {
4636 dev_err(codec->dev, "%s: unknown widget: %s\n",
4637 __func__, w->name);
4638 return -EINVAL;
4639 }
4640
4641 switch (event) {
4642 case SND_SOC_DAPM_PRE_PMU:
4643 snd_soc_update_bits(codec, boost_path_ctl, 0x10, 0x10);
4644 snd_soc_update_bits(codec, boost_path_cfg1, 0x01, 0x01);
4645 snd_soc_update_bits(codec, reg, 0x10, 0x00);
4646 if ((snd_soc_read(codec, reg_mix)) & 0x10)
4647 snd_soc_update_bits(codec, reg_mix, 0x10, 0x00);
4648 break;
4649 case SND_SOC_DAPM_POST_PMD:
4650 snd_soc_update_bits(codec, boost_path_cfg1, 0x01, 0x00);
4651 snd_soc_update_bits(codec, boost_path_ctl, 0x10, 0x00);
4652 break;
4653 };
4654
4655 return 0;
4656}
4657
4658static u16 tasha_interp_get_primary_reg(u16 reg, u16 *ind)
4659{
4660 u16 prim_int_reg = 0;
4661
4662 switch (reg) {
4663 case WCD9335_CDC_RX0_RX_PATH_CTL:
4664 case WCD9335_CDC_RX0_RX_PATH_MIX_CTL:
4665 prim_int_reg = WCD9335_CDC_RX0_RX_PATH_CTL;
4666 *ind = 0;
4667 break;
4668 case WCD9335_CDC_RX1_RX_PATH_CTL:
4669 case WCD9335_CDC_RX1_RX_PATH_MIX_CTL:
4670 prim_int_reg = WCD9335_CDC_RX1_RX_PATH_CTL;
4671 *ind = 1;
4672 break;
4673 case WCD9335_CDC_RX2_RX_PATH_CTL:
4674 case WCD9335_CDC_RX2_RX_PATH_MIX_CTL:
4675 prim_int_reg = WCD9335_CDC_RX2_RX_PATH_CTL;
4676 *ind = 2;
4677 break;
4678 case WCD9335_CDC_RX3_RX_PATH_CTL:
4679 case WCD9335_CDC_RX3_RX_PATH_MIX_CTL:
4680 prim_int_reg = WCD9335_CDC_RX3_RX_PATH_CTL;
4681 *ind = 3;
4682 break;
4683 case WCD9335_CDC_RX4_RX_PATH_CTL:
4684 case WCD9335_CDC_RX4_RX_PATH_MIX_CTL:
4685 prim_int_reg = WCD9335_CDC_RX4_RX_PATH_CTL;
4686 *ind = 4;
4687 break;
4688 case WCD9335_CDC_RX5_RX_PATH_CTL:
4689 case WCD9335_CDC_RX5_RX_PATH_MIX_CTL:
4690 prim_int_reg = WCD9335_CDC_RX5_RX_PATH_CTL;
4691 *ind = 5;
4692 break;
4693 case WCD9335_CDC_RX6_RX_PATH_CTL:
4694 case WCD9335_CDC_RX6_RX_PATH_MIX_CTL:
4695 prim_int_reg = WCD9335_CDC_RX6_RX_PATH_CTL;
4696 *ind = 6;
4697 break;
4698 case WCD9335_CDC_RX7_RX_PATH_CTL:
4699 case WCD9335_CDC_RX7_RX_PATH_MIX_CTL:
4700 prim_int_reg = WCD9335_CDC_RX7_RX_PATH_CTL;
4701 *ind = 7;
4702 break;
4703 case WCD9335_CDC_RX8_RX_PATH_CTL:
4704 case WCD9335_CDC_RX8_RX_PATH_MIX_CTL:
4705 prim_int_reg = WCD9335_CDC_RX8_RX_PATH_CTL;
4706 *ind = 8;
4707 break;
4708 };
4709
4710 return prim_int_reg;
4711}
4712
4713static void tasha_codec_hd2_control(struct snd_soc_codec *codec,
4714 u16 prim_int_reg, int event)
4715{
4716 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
4717 u16 hd2_scale_reg;
4718 u16 hd2_enable_reg = 0;
4719
4720 if (!TASHA_IS_2_0(tasha->wcd9xxx))
4721 return;
4722
4723 if (prim_int_reg == WCD9335_CDC_RX1_RX_PATH_CTL) {
4724 hd2_scale_reg = WCD9335_CDC_RX1_RX_PATH_SEC3;
4725 hd2_enable_reg = WCD9335_CDC_RX1_RX_PATH_CFG0;
4726 }
4727 if (prim_int_reg == WCD9335_CDC_RX2_RX_PATH_CTL) {
4728 hd2_scale_reg = WCD9335_CDC_RX2_RX_PATH_SEC3;
4729 hd2_enable_reg = WCD9335_CDC_RX2_RX_PATH_CFG0;
4730 }
4731
4732 if (hd2_enable_reg && SND_SOC_DAPM_EVENT_ON(event)) {
4733 snd_soc_update_bits(codec, hd2_scale_reg, 0x3C, 0x10);
4734 snd_soc_update_bits(codec, hd2_scale_reg, 0x03, 0x01);
4735 snd_soc_update_bits(codec, hd2_enable_reg, 0x04, 0x04);
4736 }
4737
4738 if (hd2_enable_reg && SND_SOC_DAPM_EVENT_OFF(event)) {
4739 snd_soc_update_bits(codec, hd2_enable_reg, 0x04, 0x00);
4740 snd_soc_update_bits(codec, hd2_scale_reg, 0x03, 0x00);
4741 snd_soc_update_bits(codec, hd2_scale_reg, 0x3C, 0x00);
4742 }
4743}
4744
4745static int tasha_codec_enable_prim_interpolator(
4746 struct snd_soc_codec *codec,
4747 u16 reg, int event)
4748{
4749 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
4750 u16 prim_int_reg;
4751 u16 ind = 0;
4752
4753 prim_int_reg = tasha_interp_get_primary_reg(reg, &ind);
4754
4755 switch (event) {
4756 case SND_SOC_DAPM_PRE_PMU:
4757 tasha->prim_int_users[ind]++;
4758 if (tasha->prim_int_users[ind] == 1) {
4759 snd_soc_update_bits(codec, prim_int_reg,
4760 0x10, 0x10);
4761 tasha_codec_hd2_control(codec, prim_int_reg, event);
4762 snd_soc_update_bits(codec, prim_int_reg,
4763 1 << 0x5, 1 << 0x5);
4764 }
4765 if ((reg != prim_int_reg) &&
4766 ((snd_soc_read(codec, prim_int_reg)) & 0x10))
4767 snd_soc_update_bits(codec, reg, 0x10, 0x10);
4768 break;
4769 case SND_SOC_DAPM_POST_PMD:
4770 tasha->prim_int_users[ind]--;
4771 if (tasha->prim_int_users[ind] == 0) {
4772 snd_soc_update_bits(codec, prim_int_reg,
4773 1 << 0x5, 0 << 0x5);
4774 snd_soc_update_bits(codec, prim_int_reg,
4775 0x40, 0x40);
4776 snd_soc_update_bits(codec, prim_int_reg,
4777 0x40, 0x00);
4778 tasha_codec_hd2_control(codec, prim_int_reg, event);
4779 }
4780 break;
4781 };
4782
4783 dev_dbg(codec->dev, "%s: primary interpolator: INT%d, users: %d\n",
4784 __func__, ind, tasha->prim_int_users[ind]);
4785 return 0;
4786}
4787
4788static int tasha_codec_enable_spline_src(struct snd_soc_codec *codec,
4789 int src_num,
4790 int event)
4791{
4792 u16 src_paired_reg = 0;
4793 struct tasha_priv *tasha;
4794 u16 rx_path_cfg_reg = WCD9335_CDC_RX1_RX_PATH_CFG0;
4795 u16 rx_path_ctl_reg = WCD9335_CDC_RX1_RX_PATH_CTL;
4796 int *src_users, count, spl_src = SPLINE_SRC0;
4797 u16 src_clk_reg = WCD9335_SPLINE_SRC0_CLK_RST_CTL_0;
4798
4799 tasha = snd_soc_codec_get_drvdata(codec);
4800
4801 switch (src_num) {
4802 case SRC_IN_HPHL:
4803 rx_path_cfg_reg = WCD9335_CDC_RX1_RX_PATH_CFG0;
4804 src_clk_reg = WCD9335_SPLINE_SRC0_CLK_RST_CTL_0;
4805 src_paired_reg = WCD9335_SPLINE_SRC1_CLK_RST_CTL_0;
4806 rx_path_ctl_reg = WCD9335_CDC_RX1_RX_PATH_CTL;
4807 spl_src = SPLINE_SRC0;
4808 break;
4809 case SRC_IN_LO1:
4810 rx_path_cfg_reg = WCD9335_CDC_RX3_RX_PATH_CFG0;
4811 src_clk_reg = WCD9335_SPLINE_SRC0_CLK_RST_CTL_0;
4812 src_paired_reg = WCD9335_SPLINE_SRC1_CLK_RST_CTL_0;
4813 rx_path_ctl_reg = WCD9335_CDC_RX3_RX_PATH_CTL;
4814 spl_src = SPLINE_SRC0;
4815 break;
4816 case SRC_IN_HPHR:
4817 rx_path_cfg_reg = WCD9335_CDC_RX2_RX_PATH_CFG0;
4818 src_clk_reg = WCD9335_SPLINE_SRC1_CLK_RST_CTL_0;
4819 src_paired_reg = WCD9335_SPLINE_SRC0_CLK_RST_CTL_0;
4820 rx_path_ctl_reg = WCD9335_CDC_RX2_RX_PATH_CTL;
4821 spl_src = SPLINE_SRC1;
4822 break;
4823 case SRC_IN_LO2:
4824 rx_path_cfg_reg = WCD9335_CDC_RX4_RX_PATH_CFG0;
4825 src_clk_reg = WCD9335_SPLINE_SRC1_CLK_RST_CTL_0;
4826 src_paired_reg = WCD9335_SPLINE_SRC0_CLK_RST_CTL_0;
4827 rx_path_ctl_reg = WCD9335_CDC_RX4_RX_PATH_CTL;
4828 spl_src = SPLINE_SRC1;
4829 break;
4830 case SRC_IN_SPKRL:
4831 rx_path_cfg_reg = WCD9335_CDC_RX7_RX_PATH_CFG0;
4832 src_clk_reg = WCD9335_SPLINE_SRC2_CLK_RST_CTL_0;
4833 src_paired_reg = WCD9335_SPLINE_SRC3_CLK_RST_CTL_0;
4834 rx_path_ctl_reg = WCD9335_CDC_RX7_RX_PATH_CTL;
4835 spl_src = SPLINE_SRC2;
4836 break;
4837 case SRC_IN_LO3:
4838 rx_path_cfg_reg = WCD9335_CDC_RX5_RX_PATH_CFG0;
4839 src_clk_reg = WCD9335_SPLINE_SRC2_CLK_RST_CTL_0;
4840 src_paired_reg = WCD9335_SPLINE_SRC3_CLK_RST_CTL_0;
4841 rx_path_ctl_reg = WCD9335_CDC_RX5_RX_PATH_CTL;
4842 spl_src = SPLINE_SRC2;
4843 break;
4844 case SRC_IN_SPKRR:
4845 rx_path_cfg_reg = WCD9335_CDC_RX8_RX_PATH_CFG0;
4846 src_clk_reg = WCD9335_SPLINE_SRC3_CLK_RST_CTL_0;
4847 src_paired_reg = WCD9335_SPLINE_SRC2_CLK_RST_CTL_0;
4848 rx_path_ctl_reg = WCD9335_CDC_RX8_RX_PATH_CTL;
4849 spl_src = SPLINE_SRC3;
4850 break;
4851 case SRC_IN_LO4:
4852 rx_path_cfg_reg = WCD9335_CDC_RX6_RX_PATH_CFG0;
4853 src_clk_reg = WCD9335_SPLINE_SRC3_CLK_RST_CTL_0;
4854 src_paired_reg = WCD9335_SPLINE_SRC2_CLK_RST_CTL_0;
4855 rx_path_ctl_reg = WCD9335_CDC_RX6_RX_PATH_CTL;
4856 spl_src = SPLINE_SRC3;
4857 break;
4858 };
4859
4860 src_users = &tasha->spl_src_users[spl_src];
4861
4862 switch (event) {
4863 case SND_SOC_DAPM_PRE_PMU:
4864 count = *src_users;
4865 count++;
4866 if (count == 1) {
4867 if ((snd_soc_read(codec, src_clk_reg) & 0x02) ||
4868 (snd_soc_read(codec, src_paired_reg) & 0x02)) {
4869 snd_soc_update_bits(codec, src_clk_reg, 0x02,
4870 0x00);
4871 snd_soc_update_bits(codec, src_paired_reg,
4872 0x02, 0x00);
4873 }
4874 snd_soc_update_bits(codec, src_clk_reg, 0x01, 0x01);
4875 snd_soc_update_bits(codec, rx_path_cfg_reg, 0x80,
4876 0x80);
4877 }
4878 *src_users = count;
4879 break;
4880 case SND_SOC_DAPM_POST_PMD:
4881 count = *src_users;
4882 count--;
4883 if (count == 0) {
4884 snd_soc_update_bits(codec, rx_path_cfg_reg, 0x80,
4885 0x00);
4886 snd_soc_update_bits(codec, src_clk_reg, 0x03, 0x02);
4887 /* default sample rate */
4888 snd_soc_update_bits(codec, rx_path_ctl_reg, 0x0f,
4889 0x04);
4890 }
4891 *src_users = count;
4892 break;
4893 };
4894
4895 dev_dbg(codec->dev, "%s: Spline SRC%d, users: %d\n",
4896 __func__, spl_src, *src_users);
4897 return 0;
4898}
4899
4900static int tasha_codec_enable_spline_resampler(struct snd_soc_dapm_widget *w,
4901 struct snd_kcontrol *kcontrol,
4902 int event)
4903{
4904 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
4905 int ret = 0;
4906 u8 src_in;
4907
4908 src_in = snd_soc_read(codec, WCD9335_CDC_RX_INP_MUX_SPLINE_SRC_CFG0);
4909 if (!(src_in & 0xFF)) {
4910 dev_err(codec->dev, "%s: Spline SRC%u input not selected\n",
4911 __func__, w->shift);
4912 return -EINVAL;
4913 }
4914
4915 switch (w->shift) {
4916 case SPLINE_SRC0:
4917 ret = tasha_codec_enable_spline_src(codec,
4918 ((src_in & 0x03) == 1) ? SRC_IN_HPHL : SRC_IN_LO1,
4919 event);
4920 break;
4921 case SPLINE_SRC1:
4922 ret = tasha_codec_enable_spline_src(codec,
4923 ((src_in & 0x0C) == 4) ? SRC_IN_HPHR : SRC_IN_LO2,
4924 event);
4925 break;
4926 case SPLINE_SRC2:
4927 ret = tasha_codec_enable_spline_src(codec,
4928 ((src_in & 0x30) == 0x10) ? SRC_IN_LO3 : SRC_IN_SPKRL,
4929 event);
4930 break;
4931 case SPLINE_SRC3:
4932 ret = tasha_codec_enable_spline_src(codec,
4933 ((src_in & 0xC0) == 0x40) ? SRC_IN_LO4 : SRC_IN_SPKRR,
4934 event);
4935 break;
4936 default:
4937 dev_err(codec->dev, "%s: Invalid spline src:%u\n", __func__,
4938 w->shift);
4939 ret = -EINVAL;
4940 };
4941
4942 return ret;
4943}
4944
4945static int tasha_codec_enable_swr(struct snd_soc_dapm_widget *w,
4946 struct snd_kcontrol *kcontrol, int event)
4947{
4948 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
4949 struct tasha_priv *tasha;
4950 int i, ch_cnt;
4951
4952 tasha = snd_soc_codec_get_drvdata(codec);
4953
4954 if (!tasha->nr)
4955 return 0;
4956
4957 switch (event) {
4958 case SND_SOC_DAPM_PRE_PMU:
4959 if ((strnstr(w->name, "INT7_", sizeof("RX INT7_"))) &&
4960 !tasha->rx_7_count)
4961 tasha->rx_7_count++;
4962 if ((strnstr(w->name, "INT8_", sizeof("RX INT8_"))) &&
4963 !tasha->rx_8_count)
4964 tasha->rx_8_count++;
4965 ch_cnt = tasha->rx_7_count + tasha->rx_8_count;
4966
4967 for (i = 0; i < tasha->nr; i++) {
4968 swrm_wcd_notify(tasha->swr_ctrl_data[i].swr_pdev,
4969 SWR_DEVICE_UP, NULL);
4970 swrm_wcd_notify(tasha->swr_ctrl_data[i].swr_pdev,
4971 SWR_SET_NUM_RX_CH, &ch_cnt);
4972 }
4973 break;
4974 case SND_SOC_DAPM_POST_PMD:
4975 if ((strnstr(w->name, "INT7_", sizeof("RX INT7_"))) &&
4976 tasha->rx_7_count)
4977 tasha->rx_7_count--;
4978 if ((strnstr(w->name, "INT8_", sizeof("RX INT8_"))) &&
4979 tasha->rx_8_count)
4980 tasha->rx_8_count--;
4981 ch_cnt = tasha->rx_7_count + tasha->rx_8_count;
4982
4983 for (i = 0; i < tasha->nr; i++)
4984 swrm_wcd_notify(tasha->swr_ctrl_data[i].swr_pdev,
4985 SWR_SET_NUM_RX_CH, &ch_cnt);
4986
4987 break;
4988 }
4989 dev_dbg(tasha->dev, "%s: current swr ch cnt: %d\n",
4990 __func__, tasha->rx_7_count + tasha->rx_8_count);
4991
4992 return 0;
4993}
4994
4995static int tasha_codec_config_ear_spkr_gain(struct snd_soc_codec *codec,
4996 int event, int gain_reg)
4997{
4998 int comp_gain_offset, val;
4999 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
5000
5001 switch (tasha->spkr_mode) {
5002 /* Compander gain in SPKR_MODE1 case is 12 dB */
5003 case SPKR_MODE_1:
5004 comp_gain_offset = -12;
5005 break;
5006 /* Default case compander gain is 15 dB */
5007 default:
5008 comp_gain_offset = -15;
5009 break;
5010 }
5011
5012 switch (event) {
5013 case SND_SOC_DAPM_POST_PMU:
5014 /* Apply ear spkr gain only if compander is enabled */
5015 if (tasha->comp_enabled[COMPANDER_7] &&
5016 (gain_reg == WCD9335_CDC_RX7_RX_VOL_CTL ||
5017 gain_reg == WCD9335_CDC_RX7_RX_VOL_MIX_CTL) &&
5018 (tasha->ear_spkr_gain != 0)) {
5019 /* For example, val is -8(-12+5-1) for 4dB of gain */
5020 val = comp_gain_offset + tasha->ear_spkr_gain - 1;
5021 snd_soc_write(codec, gain_reg, val);
5022
5023 dev_dbg(codec->dev, "%s: RX7 Volume %d dB\n",
5024 __func__, val);
5025 }
5026 break;
5027 case SND_SOC_DAPM_POST_PMD:
5028 /*
5029 * Reset RX7 volume to 0 dB if compander is enabled and
5030 * ear_spkr_gain is non-zero.
5031 */
5032 if (tasha->comp_enabled[COMPANDER_7] &&
5033 (gain_reg == WCD9335_CDC_RX7_RX_VOL_CTL ||
5034 gain_reg == WCD9335_CDC_RX7_RX_VOL_MIX_CTL) &&
5035 (tasha->ear_spkr_gain != 0)) {
5036 snd_soc_write(codec, gain_reg, 0x0);
5037
5038 dev_dbg(codec->dev, "%s: Reset RX7 Volume to 0 dB\n",
5039 __func__);
5040 }
5041 break;
5042 }
5043
5044 return 0;
5045}
5046
5047static int tasha_codec_enable_mix_path(struct snd_soc_dapm_widget *w,
5048 struct snd_kcontrol *kcontrol, int event)
5049{
5050 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
5051 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
5052 u16 gain_reg;
5053 int offset_val = 0;
5054 int val = 0;
5055
5056 dev_dbg(codec->dev, "%s %d %s\n", __func__, event, w->name);
5057
5058 switch (w->reg) {
5059 case WCD9335_CDC_RX0_RX_PATH_MIX_CTL:
5060 gain_reg = WCD9335_CDC_RX0_RX_VOL_MIX_CTL;
5061 break;
5062 case WCD9335_CDC_RX1_RX_PATH_MIX_CTL:
5063 gain_reg = WCD9335_CDC_RX1_RX_VOL_MIX_CTL;
5064 break;
5065 case WCD9335_CDC_RX2_RX_PATH_MIX_CTL:
5066 gain_reg = WCD9335_CDC_RX2_RX_VOL_MIX_CTL;
5067 break;
5068 case WCD9335_CDC_RX3_RX_PATH_MIX_CTL:
5069 gain_reg = WCD9335_CDC_RX3_RX_VOL_MIX_CTL;
5070 break;
5071 case WCD9335_CDC_RX4_RX_PATH_MIX_CTL:
5072 gain_reg = WCD9335_CDC_RX4_RX_VOL_MIX_CTL;
5073 break;
5074 case WCD9335_CDC_RX5_RX_PATH_MIX_CTL:
5075 gain_reg = WCD9335_CDC_RX5_RX_VOL_MIX_CTL;
5076 break;
5077 case WCD9335_CDC_RX6_RX_PATH_MIX_CTL:
5078 gain_reg = WCD9335_CDC_RX6_RX_VOL_MIX_CTL;
5079 break;
5080 case WCD9335_CDC_RX7_RX_PATH_MIX_CTL:
5081 gain_reg = WCD9335_CDC_RX7_RX_VOL_MIX_CTL;
5082 break;
5083 case WCD9335_CDC_RX8_RX_PATH_MIX_CTL:
5084 gain_reg = WCD9335_CDC_RX8_RX_VOL_MIX_CTL;
5085 break;
5086 default:
5087 dev_err(codec->dev, "%s: No gain register avail for %s\n",
5088 __func__, w->name);
5089 return 0;
5090 };
5091
5092 switch (event) {
5093 case SND_SOC_DAPM_POST_PMU:
5094 if ((tasha->spkr_gain_offset == RX_GAIN_OFFSET_M1P5_DB) &&
5095 (tasha->comp_enabled[COMPANDER_7] ||
5096 tasha->comp_enabled[COMPANDER_8]) &&
5097 (gain_reg == WCD9335_CDC_RX7_RX_VOL_MIX_CTL ||
5098 gain_reg == WCD9335_CDC_RX8_RX_VOL_MIX_CTL)) {
5099 snd_soc_update_bits(codec, WCD9335_CDC_RX7_RX_PATH_SEC1,
5100 0x01, 0x01);
5101 snd_soc_update_bits(codec,
5102 WCD9335_CDC_RX7_RX_PATH_MIX_SEC0,
5103 0x01, 0x01);
5104 snd_soc_update_bits(codec, WCD9335_CDC_RX8_RX_PATH_SEC1,
5105 0x01, 0x01);
5106 snd_soc_update_bits(codec,
5107 WCD9335_CDC_RX8_RX_PATH_MIX_SEC0,
5108 0x01, 0x01);
5109 offset_val = -2;
5110 }
5111 val = snd_soc_read(codec, gain_reg);
5112 val += offset_val;
5113 snd_soc_write(codec, gain_reg, val);
5114 tasha_codec_config_ear_spkr_gain(codec, event, gain_reg);
5115 break;
5116 case SND_SOC_DAPM_POST_PMD:
5117 if ((tasha->spkr_gain_offset == RX_GAIN_OFFSET_M1P5_DB) &&
5118 (tasha->comp_enabled[COMPANDER_7] ||
5119 tasha->comp_enabled[COMPANDER_8]) &&
5120 (gain_reg == WCD9335_CDC_RX7_RX_VOL_MIX_CTL ||
5121 gain_reg == WCD9335_CDC_RX8_RX_VOL_MIX_CTL)) {
5122 snd_soc_update_bits(codec, WCD9335_CDC_RX7_RX_PATH_SEC1,
5123 0x01, 0x00);
5124 snd_soc_update_bits(codec,
5125 WCD9335_CDC_RX7_RX_PATH_MIX_SEC0,
5126 0x01, 0x00);
5127 snd_soc_update_bits(codec, WCD9335_CDC_RX8_RX_PATH_SEC1,
5128 0x01, 0x00);
5129 snd_soc_update_bits(codec,
5130 WCD9335_CDC_RX8_RX_PATH_MIX_SEC0,
5131 0x01, 0x00);
5132 offset_val = 2;
5133 val = snd_soc_read(codec, gain_reg);
5134 val += offset_val;
5135 snd_soc_write(codec, gain_reg, val);
5136 }
5137 tasha_codec_config_ear_spkr_gain(codec, event, gain_reg);
5138 break;
5139 };
5140
5141 return 0;
5142}
5143
5144static int __tasha_cdc_native_clk_enable(struct tasha_priv *tasha,
5145 bool enable)
5146{
5147 int ret = 0;
5148 struct snd_soc_codec *codec = tasha->codec;
5149
5150 if (!tasha->wcd_native_clk) {
5151 dev_err(tasha->dev, "%s: wcd native clock is NULL\n", __func__);
5152 return -EINVAL;
5153 }
5154
5155 dev_dbg(tasha->dev, "%s: native_clk_enable = %u\n", __func__, enable);
5156
5157 if (enable) {
5158 ret = clk_prepare_enable(tasha->wcd_native_clk);
5159 if (ret) {
5160 dev_err(tasha->dev, "%s: native clk enable failed\n",
5161 __func__);
5162 goto err;
5163 }
5164 if (++tasha->native_clk_users == 1) {
5165 snd_soc_update_bits(codec, WCD9335_CLOCK_TEST_CTL,
5166 0x10, 0x10);
5167 snd_soc_update_bits(codec, WCD9335_CLOCK_TEST_CTL,
5168 0x80, 0x80);
5169 snd_soc_update_bits(codec, WCD9335_CODEC_RPM_CLK_GATE,
5170 0x04, 0x00);
5171 snd_soc_update_bits(codec,
5172 WCD9335_CDC_CLK_RST_CTRL_MCLK_CONTROL,
5173 0x02, 0x02);
5174 }
5175 } else {
5176 if (tasha->native_clk_users &&
5177 (--tasha->native_clk_users == 0)) {
5178 snd_soc_update_bits(codec,
5179 WCD9335_CDC_CLK_RST_CTRL_MCLK_CONTROL,
5180 0x02, 0x00);
5181 snd_soc_update_bits(codec, WCD9335_CODEC_RPM_CLK_GATE,
5182 0x04, 0x04);
5183 snd_soc_update_bits(codec, WCD9335_CLOCK_TEST_CTL,
5184 0x80, 0x00);
5185 snd_soc_update_bits(codec, WCD9335_CLOCK_TEST_CTL,
5186 0x10, 0x00);
5187 }
5188 clk_disable_unprepare(tasha->wcd_native_clk);
5189 }
5190
5191 dev_dbg(codec->dev, "%s: native_clk_users: %d\n", __func__,
5192 tasha->native_clk_users);
5193err:
5194 return ret;
5195}
5196
5197static int tasha_codec_get_native_fifo_sync_mask(struct snd_soc_codec *codec,
5198 int interp_n)
5199{
5200 int mask = 0;
5201 u16 reg;
5202 u8 val1, val2, inp0 = 0;
5203 u8 inp1 = 0, inp2 = 0;
5204
5205 reg = WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG0 + (2 * interp_n) - 2;
5206
5207 val1 = snd_soc_read(codec, reg);
5208 val2 = snd_soc_read(codec, reg + 1);
5209
5210 inp0 = val1 & 0x0F;
5211 inp1 = (val1 >> 4) & 0x0F;
5212 inp2 = (val2 >> 4) & 0x0F;
5213
5214 if (IS_VALID_NATIVE_FIFO_PORT(inp0))
5215 mask |= (1 << (inp0 - 5));
5216 if (IS_VALID_NATIVE_FIFO_PORT(inp1))
5217 mask |= (1 << (inp1 - 5));
5218 if (IS_VALID_NATIVE_FIFO_PORT(inp2))
5219 mask |= (1 << (inp2 - 5));
5220
5221 dev_dbg(codec->dev, "%s: native fifo mask: 0x%x\n", __func__, mask);
5222 if (!mask)
5223 dev_err(codec->dev, "native fifo err,int:%d,inp0:%d,inp1:%d,inp2:%d\n",
5224 interp_n, inp0, inp1, inp2);
5225 return mask;
5226}
5227
5228static int tasha_enable_native_supply(struct snd_soc_dapm_widget *w,
5229 struct snd_kcontrol *kcontrol, int event)
5230{
5231 int mask;
5232 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
5233 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
5234 u16 interp_reg;
5235
5236 dev_dbg(codec->dev, "%s: event: %d, shift:%d\n", __func__, event,
5237 w->shift);
5238
5239 if (w->shift < INTERP_HPHL || w->shift > INTERP_LO2)
5240 return -EINVAL;
5241
5242 interp_reg = WCD9335_CDC_RX1_RX_PATH_CTL + 20 * (w->shift - 1);
5243
5244 mask = tasha_codec_get_native_fifo_sync_mask(codec, w->shift);
5245 if (!mask)
5246 return -EINVAL;
5247
5248 switch (event) {
5249 case SND_SOC_DAPM_PRE_PMU:
5250 /* Adjust interpolator rate to 44P1_NATIVE */
5251 snd_soc_update_bits(codec, interp_reg, 0x0F, 0x09);
5252 __tasha_cdc_native_clk_enable(tasha, true);
5253 snd_soc_update_bits(codec, WCD9335_DATA_HUB_NATIVE_FIFO_SYNC,
5254 mask, mask);
5255 break;
5256 case SND_SOC_DAPM_PRE_PMD:
5257 snd_soc_update_bits(codec, WCD9335_DATA_HUB_NATIVE_FIFO_SYNC,
5258 mask, 0x0);
5259 __tasha_cdc_native_clk_enable(tasha, false);
5260 /* Adjust interpolator rate to default */
5261 snd_soc_update_bits(codec, interp_reg, 0x0F, 0x04);
5262 break;
5263 }
5264
5265 return 0;
5266}
5267
5268static int tasha_codec_enable_interpolator(struct snd_soc_dapm_widget *w,
5269 struct snd_kcontrol *kcontrol, int event)
5270{
5271 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
5272 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
5273 u16 gain_reg;
5274 u16 reg;
5275 int val;
5276 int offset_val = 0;
5277
5278 dev_dbg(codec->dev, "%s %d %s\n", __func__, event, w->name);
5279
5280 if (!(strcmp(w->name, "RX INT0 INTERP"))) {
5281 reg = WCD9335_CDC_RX0_RX_PATH_CTL;
5282 gain_reg = WCD9335_CDC_RX0_RX_VOL_CTL;
5283 } else if (!(strcmp(w->name, "RX INT1 INTERP"))) {
5284 reg = WCD9335_CDC_RX1_RX_PATH_CTL;
5285 gain_reg = WCD9335_CDC_RX1_RX_VOL_CTL;
5286 } else if (!(strcmp(w->name, "RX INT2 INTERP"))) {
5287 reg = WCD9335_CDC_RX2_RX_PATH_CTL;
5288 gain_reg = WCD9335_CDC_RX2_RX_VOL_CTL;
5289 } else if (!(strcmp(w->name, "RX INT3 INTERP"))) {
5290 reg = WCD9335_CDC_RX3_RX_PATH_CTL;
5291 gain_reg = WCD9335_CDC_RX3_RX_VOL_CTL;
5292 } else if (!(strcmp(w->name, "RX INT4 INTERP"))) {
5293 reg = WCD9335_CDC_RX4_RX_PATH_CTL;
5294 gain_reg = WCD9335_CDC_RX4_RX_VOL_CTL;
5295 } else if (!(strcmp(w->name, "RX INT5 INTERP"))) {
5296 reg = WCD9335_CDC_RX5_RX_PATH_CTL;
5297 gain_reg = WCD9335_CDC_RX5_RX_VOL_CTL;
5298 } else if (!(strcmp(w->name, "RX INT6 INTERP"))) {
5299 reg = WCD9335_CDC_RX6_RX_PATH_CTL;
5300 gain_reg = WCD9335_CDC_RX6_RX_VOL_CTL;
5301 } else if (!(strcmp(w->name, "RX INT7 INTERP"))) {
5302 reg = WCD9335_CDC_RX7_RX_PATH_CTL;
5303 gain_reg = WCD9335_CDC_RX7_RX_VOL_CTL;
5304 } else if (!(strcmp(w->name, "RX INT8 INTERP"))) {
5305 reg = WCD9335_CDC_RX8_RX_PATH_CTL;
5306 gain_reg = WCD9335_CDC_RX8_RX_VOL_CTL;
5307 } else {
5308 dev_err(codec->dev, "%s: Interpolator reg not found\n",
5309 __func__);
5310 return -EINVAL;
5311 }
5312
5313 switch (event) {
5314 case SND_SOC_DAPM_PRE_PMU:
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05305315 tasha_codec_vote_max_bw(codec, true);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05305316 /* Reset if needed */
5317 tasha_codec_enable_prim_interpolator(codec, reg, event);
5318 break;
5319 case SND_SOC_DAPM_POST_PMU:
5320 tasha_config_compander(codec, w->shift, event);
5321 /* apply gain after int clk is enabled */
5322 if ((tasha->spkr_gain_offset == RX_GAIN_OFFSET_M1P5_DB) &&
5323 (tasha->comp_enabled[COMPANDER_7] ||
5324 tasha->comp_enabled[COMPANDER_8]) &&
5325 (gain_reg == WCD9335_CDC_RX7_RX_VOL_CTL ||
5326 gain_reg == WCD9335_CDC_RX8_RX_VOL_CTL)) {
5327 snd_soc_update_bits(codec, WCD9335_CDC_RX7_RX_PATH_SEC1,
5328 0x01, 0x01);
5329 snd_soc_update_bits(codec,
5330 WCD9335_CDC_RX7_RX_PATH_MIX_SEC0,
5331 0x01, 0x01);
5332 snd_soc_update_bits(codec, WCD9335_CDC_RX8_RX_PATH_SEC1,
5333 0x01, 0x01);
5334 snd_soc_update_bits(codec,
5335 WCD9335_CDC_RX8_RX_PATH_MIX_SEC0,
5336 0x01, 0x01);
5337 offset_val = -2;
5338 }
5339 val = snd_soc_read(codec, gain_reg);
5340 val += offset_val;
5341 snd_soc_write(codec, gain_reg, val);
5342 tasha_codec_config_ear_spkr_gain(codec, event, gain_reg);
5343 break;
5344 case SND_SOC_DAPM_POST_PMD:
5345 tasha_config_compander(codec, w->shift, event);
5346 tasha_codec_enable_prim_interpolator(codec, reg, event);
5347 if ((tasha->spkr_gain_offset == RX_GAIN_OFFSET_M1P5_DB) &&
5348 (tasha->comp_enabled[COMPANDER_7] ||
5349 tasha->comp_enabled[COMPANDER_8]) &&
5350 (gain_reg == WCD9335_CDC_RX7_RX_VOL_CTL ||
5351 gain_reg == WCD9335_CDC_RX8_RX_VOL_CTL)) {
5352 snd_soc_update_bits(codec, WCD9335_CDC_RX7_RX_PATH_SEC1,
5353 0x01, 0x00);
5354 snd_soc_update_bits(codec,
5355 WCD9335_CDC_RX7_RX_PATH_MIX_SEC0,
5356 0x01, 0x00);
5357 snd_soc_update_bits(codec, WCD9335_CDC_RX8_RX_PATH_SEC1,
5358 0x01, 0x00);
5359 snd_soc_update_bits(codec,
5360 WCD9335_CDC_RX8_RX_PATH_MIX_SEC0,
5361 0x01, 0x00);
5362 offset_val = 2;
5363 val = snd_soc_read(codec, gain_reg);
5364 val += offset_val;
5365 snd_soc_write(codec, gain_reg, val);
5366 }
5367 tasha_codec_config_ear_spkr_gain(codec, event, gain_reg);
5368 break;
5369 };
5370
5371 return 0;
5372}
5373
5374static int tasha_codec_set_iir_gain(struct snd_soc_dapm_widget *w,
5375 struct snd_kcontrol *kcontrol, int event)
5376{
5377 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
5378
5379 dev_dbg(codec->dev, "%s: event = %d\n", __func__, event);
5380
5381 switch (event) {
5382 case SND_SOC_DAPM_POST_PMU: /* fall through */
5383 case SND_SOC_DAPM_PRE_PMD:
5384 if (strnstr(w->name, "IIR0", sizeof("IIR0"))) {
5385 snd_soc_write(codec,
5386 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL,
5387 snd_soc_read(codec,
5388 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL));
5389 snd_soc_write(codec,
5390 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL,
5391 snd_soc_read(codec,
5392 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL));
5393 snd_soc_write(codec,
5394 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL,
5395 snd_soc_read(codec,
5396 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL));
5397 snd_soc_write(codec,
5398 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL,
5399 snd_soc_read(codec,
5400 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL));
5401 } else {
5402 snd_soc_write(codec,
5403 WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B1_CTL,
5404 snd_soc_read(codec,
5405 WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B1_CTL));
5406 snd_soc_write(codec,
5407 WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B2_CTL,
5408 snd_soc_read(codec,
5409 WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B2_CTL));
5410 snd_soc_write(codec,
5411 WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B3_CTL,
5412 snd_soc_read(codec,
5413 WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B3_CTL));
5414 }
5415 break;
5416 }
5417 return 0;
5418}
5419
5420static int tasha_codec_enable_on_demand_supply(
5421 struct snd_soc_dapm_widget *w,
5422 struct snd_kcontrol *kcontrol, int event)
5423{
5424 int ret = 0;
5425 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
5426 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
5427 struct on_demand_supply *supply;
5428
5429 if (w->shift >= ON_DEMAND_SUPPLIES_MAX) {
5430 dev_err(codec->dev, "%s: error index > MAX Demand supplies",
5431 __func__);
5432 ret = -EINVAL;
5433 goto out;
5434 }
5435
5436 dev_dbg(codec->dev, "%s: supply: %s event: %d\n",
5437 __func__, on_demand_supply_name[w->shift], event);
5438
5439 supply = &tasha->on_demand_list[w->shift];
5440 WARN_ONCE(!supply->supply, "%s isn't defined\n",
5441 on_demand_supply_name[w->shift]);
5442 if (!supply->supply) {
5443 dev_err(codec->dev, "%s: err supply not present ond for %d",
5444 __func__, w->shift);
5445 goto out;
5446 }
5447
5448 switch (event) {
5449 case SND_SOC_DAPM_PRE_PMU:
5450 ret = regulator_enable(supply->supply);
5451 if (ret)
5452 dev_err(codec->dev, "%s: Failed to enable %s\n",
5453 __func__,
5454 on_demand_supply_name[w->shift]);
5455 break;
5456 case SND_SOC_DAPM_POST_PMD:
5457 ret = regulator_disable(supply->supply);
5458 if (ret)
5459 dev_err(codec->dev, "%s: Failed to disable %s\n",
5460 __func__,
5461 on_demand_supply_name[w->shift]);
5462 break;
5463 default:
5464 break;
5465 };
5466
5467out:
5468 return ret;
5469}
5470
5471static int tasha_codec_find_amic_input(struct snd_soc_codec *codec,
5472 int adc_mux_n)
5473{
5474 u16 mask, shift, adc_mux_in_reg;
5475 u16 amic_mux_sel_reg;
5476 bool is_amic;
5477
5478 if (adc_mux_n < 0 || adc_mux_n > WCD9335_MAX_VALID_ADC_MUX ||
5479 adc_mux_n == WCD9335_INVALID_ADC_MUX)
5480 return 0;
5481
5482 /* Check whether adc mux input is AMIC or DMIC */
5483 if (adc_mux_n < 4) {
5484 adc_mux_in_reg = WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG1 +
5485 2 * adc_mux_n;
5486 amic_mux_sel_reg = WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG0 +
5487 2 * adc_mux_n;
5488 mask = 0x03;
5489 shift = 0;
5490 } else {
5491 adc_mux_in_reg = WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0 +
5492 adc_mux_n - 4;
5493 amic_mux_sel_reg = adc_mux_in_reg;
5494 mask = 0xC0;
5495 shift = 6;
5496 }
5497 is_amic = (((snd_soc_read(codec, adc_mux_in_reg) & mask) >> shift)
5498 == 1);
5499 if (!is_amic)
5500 return 0;
5501
5502 return snd_soc_read(codec, amic_mux_sel_reg) & 0x07;
5503}
5504
5505static void tasha_codec_set_tx_hold(struct snd_soc_codec *codec,
5506 u16 amic_reg, bool set)
5507{
5508 u8 mask = 0x20;
5509 u8 val;
5510
5511 if (amic_reg == WCD9335_ANA_AMIC1 ||
5512 amic_reg == WCD9335_ANA_AMIC3 ||
5513 amic_reg == WCD9335_ANA_AMIC5)
5514 mask = 0x40;
5515
5516 val = set ? mask : 0x00;
5517
5518 switch (amic_reg) {
5519 case WCD9335_ANA_AMIC1:
5520 case WCD9335_ANA_AMIC2:
5521 snd_soc_update_bits(codec, WCD9335_ANA_AMIC2, mask, val);
5522 break;
5523 case WCD9335_ANA_AMIC3:
5524 case WCD9335_ANA_AMIC4:
5525 snd_soc_update_bits(codec, WCD9335_ANA_AMIC4, mask, val);
5526 break;
5527 case WCD9335_ANA_AMIC5:
5528 case WCD9335_ANA_AMIC6:
5529 snd_soc_update_bits(codec, WCD9335_ANA_AMIC6, mask, val);
5530 break;
5531 default:
5532 dev_dbg(codec->dev, "%s: invalid amic: %d\n",
5533 __func__, amic_reg);
5534 break;
5535 }
5536}
5537
5538static int tasha_codec_tx_adc_cfg(struct snd_soc_dapm_widget *w,
5539 struct snd_kcontrol *kcontrol, int event)
5540{
5541 int adc_mux_n = w->shift;
5542 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
5543 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
5544 int amic_n;
5545
5546 dev_dbg(codec->dev, "%s: event: %d\n", __func__, event);
5547
5548 switch (event) {
5549 case SND_SOC_DAPM_POST_PMU:
5550 amic_n = tasha_codec_find_amic_input(codec, adc_mux_n);
5551 if (amic_n) {
5552 /*
5553 * Prevent ANC Rx pop by leaving Tx FE in HOLD
5554 * state until PA is up. Track AMIC being used
5555 * so we can release the HOLD later.
5556 */
5557 set_bit(ANC_MIC_AMIC1 + amic_n - 1,
5558 &tasha->status_mask);
5559 }
5560 break;
5561 default:
5562 break;
5563 }
5564
5565 return 0;
5566}
5567
5568static u16 tasha_codec_get_amic_pwlvl_reg(struct snd_soc_codec *codec, int amic)
5569{
5570 u16 pwr_level_reg = 0;
5571
5572 switch (amic) {
5573 case 1:
5574 case 2:
5575 pwr_level_reg = WCD9335_ANA_AMIC1;
5576 break;
5577
5578 case 3:
5579 case 4:
5580 pwr_level_reg = WCD9335_ANA_AMIC3;
5581 break;
5582
5583 case 5:
5584 case 6:
5585 pwr_level_reg = WCD9335_ANA_AMIC5;
5586 break;
5587 default:
5588 dev_dbg(codec->dev, "%s: invalid amic: %d\n",
5589 __func__, amic);
5590 break;
5591 }
5592
5593 return pwr_level_reg;
5594}
5595
5596#define TX_HPF_CUT_OFF_FREQ_MASK 0x60
5597#define CF_MIN_3DB_4HZ 0x0
5598#define CF_MIN_3DB_75HZ 0x1
5599#define CF_MIN_3DB_150HZ 0x2
5600
5601static void tasha_tx_hpf_corner_freq_callback(struct work_struct *work)
5602{
5603 struct delayed_work *hpf_delayed_work;
5604 struct hpf_work *hpf_work;
5605 struct tasha_priv *tasha;
5606 struct snd_soc_codec *codec;
5607 u16 dec_cfg_reg, amic_reg;
5608 u8 hpf_cut_off_freq;
5609 int amic_n;
5610
5611 hpf_delayed_work = to_delayed_work(work);
5612 hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork);
5613 tasha = hpf_work->tasha;
5614 codec = tasha->codec;
5615 hpf_cut_off_freq = hpf_work->hpf_cut_off_freq;
5616
5617 dec_cfg_reg = WCD9335_CDC_TX0_TX_PATH_CFG0 + 16 * hpf_work->decimator;
5618
5619 dev_dbg(codec->dev, "%s: decimator %u hpf_cut_of_freq 0x%x\n",
5620 __func__, hpf_work->decimator, hpf_cut_off_freq);
5621
5622 amic_n = tasha_codec_find_amic_input(codec, hpf_work->decimator);
5623 if (amic_n) {
5624 amic_reg = WCD9335_ANA_AMIC1 + amic_n - 1;
5625 tasha_codec_set_tx_hold(codec, amic_reg, false);
5626 }
5627 tasha_codec_vote_max_bw(codec, true);
5628 snd_soc_update_bits(codec, dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK,
5629 hpf_cut_off_freq << 5);
5630 tasha_codec_vote_max_bw(codec, false);
5631}
5632
5633static void tasha_tx_mute_update_callback(struct work_struct *work)
5634{
5635 struct tx_mute_work *tx_mute_dwork;
5636 struct tasha_priv *tasha;
5637 struct delayed_work *delayed_work;
5638 struct snd_soc_codec *codec;
5639 u16 tx_vol_ctl_reg, hpf_gate_reg;
5640
5641 delayed_work = to_delayed_work(work);
5642 tx_mute_dwork = container_of(delayed_work, struct tx_mute_work, dwork);
5643 tasha = tx_mute_dwork->tasha;
5644 codec = tasha->codec;
5645
5646 tx_vol_ctl_reg = WCD9335_CDC_TX0_TX_PATH_CTL +
5647 16 * tx_mute_dwork->decimator;
5648 hpf_gate_reg = WCD9335_CDC_TX0_TX_PATH_SEC2 +
5649 16 * tx_mute_dwork->decimator;
5650 snd_soc_update_bits(codec, hpf_gate_reg, 0x01, 0x01);
5651 snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x00);
5652}
5653
5654static int tasha_codec_enable_dec(struct snd_soc_dapm_widget *w,
5655 struct snd_kcontrol *kcontrol, int event)
5656{
5657 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
5658 unsigned int decimator;
5659 char *dec_adc_mux_name = NULL;
5660 char *widget_name = NULL;
5661 char *wname;
5662 int ret = 0, amic_n;
5663 u16 tx_vol_ctl_reg, pwr_level_reg = 0, dec_cfg_reg, hpf_gate_reg;
5664 u16 tx_gain_ctl_reg;
5665 char *dec;
5666 u8 hpf_cut_off_freq;
5667 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
5668
5669 dev_dbg(codec->dev, "%s %d\n", __func__, event);
5670
5671 widget_name = kstrndup(w->name, 15, GFP_KERNEL);
5672 if (!widget_name)
5673 return -ENOMEM;
5674
5675 wname = widget_name;
5676 dec_adc_mux_name = strsep(&widget_name, " ");
5677 if (!dec_adc_mux_name) {
5678 dev_err(codec->dev, "%s: Invalid decimator = %s\n",
5679 __func__, w->name);
5680 ret = -EINVAL;
5681 goto out;
5682 }
5683 dec_adc_mux_name = widget_name;
5684
5685 dec = strpbrk(dec_adc_mux_name, "012345678");
5686 if (!dec) {
5687 dev_err(codec->dev, "%s: decimator index not found\n",
5688 __func__);
5689 ret = -EINVAL;
5690 goto out;
5691 }
5692
5693 ret = kstrtouint(dec, 10, &decimator);
5694 if (ret < 0) {
5695 dev_err(codec->dev, "%s: Invalid decimator = %s\n",
5696 __func__, wname);
5697 ret = -EINVAL;
5698 goto out;
5699 }
5700
5701 dev_dbg(codec->dev, "%s(): widget = %s decimator = %u\n", __func__,
5702 w->name, decimator);
5703
5704 tx_vol_ctl_reg = WCD9335_CDC_TX0_TX_PATH_CTL + 16 * decimator;
5705 hpf_gate_reg = WCD9335_CDC_TX0_TX_PATH_SEC2 + 16 * decimator;
5706 dec_cfg_reg = WCD9335_CDC_TX0_TX_PATH_CFG0 + 16 * decimator;
5707 tx_gain_ctl_reg = WCD9335_CDC_TX0_TX_VOL_CTL + 16 * decimator;
5708
5709 switch (event) {
5710 case SND_SOC_DAPM_PRE_PMU:
5711 amic_n = tasha_codec_find_amic_input(codec, decimator);
5712 if (amic_n)
5713 pwr_level_reg = tasha_codec_get_amic_pwlvl_reg(codec,
5714 amic_n);
5715
5716 if (pwr_level_reg) {
5717 switch ((snd_soc_read(codec, pwr_level_reg) &
5718 WCD9335_AMIC_PWR_LVL_MASK) >>
5719 WCD9335_AMIC_PWR_LVL_SHIFT) {
5720 case WCD9335_AMIC_PWR_LEVEL_LP:
5721 snd_soc_update_bits(codec, dec_cfg_reg,
5722 WCD9335_DEC_PWR_LVL_MASK,
5723 WCD9335_DEC_PWR_LVL_LP);
5724 break;
5725
5726 case WCD9335_AMIC_PWR_LEVEL_HP:
5727 snd_soc_update_bits(codec, dec_cfg_reg,
5728 WCD9335_DEC_PWR_LVL_MASK,
5729 WCD9335_DEC_PWR_LVL_HP);
5730 break;
5731 case WCD9335_AMIC_PWR_LEVEL_DEFAULT:
5732 default:
5733 snd_soc_update_bits(codec, dec_cfg_reg,
5734 WCD9335_DEC_PWR_LVL_MASK,
5735 WCD9335_DEC_PWR_LVL_DF);
5736 break;
5737 }
5738 }
5739 hpf_cut_off_freq = (snd_soc_read(codec, dec_cfg_reg) &
5740 TX_HPF_CUT_OFF_FREQ_MASK) >> 5;
5741 tasha->tx_hpf_work[decimator].hpf_cut_off_freq =
5742 hpf_cut_off_freq;
5743
5744 if (hpf_cut_off_freq != CF_MIN_3DB_150HZ)
5745 snd_soc_update_bits(codec, dec_cfg_reg,
5746 TX_HPF_CUT_OFF_FREQ_MASK,
5747 CF_MIN_3DB_150HZ << 5);
5748 /* Enable TX PGA Mute */
5749 snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x10);
5750 break;
5751 case SND_SOC_DAPM_POST_PMU:
5752 snd_soc_update_bits(codec, hpf_gate_reg, 0x01, 0x00);
5753
5754 if (decimator == 0) {
5755 snd_soc_write(codec, WCD9335_MBHC_ZDET_RAMP_CTL, 0x83);
5756 snd_soc_write(codec, WCD9335_MBHC_ZDET_RAMP_CTL, 0xA3);
5757 snd_soc_write(codec, WCD9335_MBHC_ZDET_RAMP_CTL, 0x83);
5758 snd_soc_write(codec, WCD9335_MBHC_ZDET_RAMP_CTL, 0x03);
5759 }
5760 /* schedule work queue to Remove Mute */
5761 schedule_delayed_work(&tasha->tx_mute_dwork[decimator].dwork,
5762 msecs_to_jiffies(tx_unmute_delay));
5763 if (tasha->tx_hpf_work[decimator].hpf_cut_off_freq !=
5764 CF_MIN_3DB_150HZ)
5765 schedule_delayed_work(
5766 &tasha->tx_hpf_work[decimator].dwork,
5767 msecs_to_jiffies(300));
5768 /* apply gain after decimator is enabled */
5769 snd_soc_write(codec, tx_gain_ctl_reg,
5770 snd_soc_read(codec, tx_gain_ctl_reg));
5771 break;
5772 case SND_SOC_DAPM_PRE_PMD:
5773 hpf_cut_off_freq =
5774 tasha->tx_hpf_work[decimator].hpf_cut_off_freq;
5775 snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x10);
5776 if (cancel_delayed_work_sync(
5777 &tasha->tx_hpf_work[decimator].dwork)) {
5778 if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) {
5779 tasha_codec_vote_max_bw(codec, true);
5780 snd_soc_update_bits(codec, dec_cfg_reg,
5781 TX_HPF_CUT_OFF_FREQ_MASK,
5782 hpf_cut_off_freq << 5);
5783 tasha_codec_vote_max_bw(codec, false);
5784 }
5785 }
5786 cancel_delayed_work_sync(
5787 &tasha->tx_mute_dwork[decimator].dwork);
5788 break;
5789 case SND_SOC_DAPM_POST_PMD:
5790 snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x00);
5791 break;
5792 };
5793out:
5794 kfree(wname);
5795 return ret;
5796}
5797
5798static u32 tasha_get_dmic_sample_rate(struct snd_soc_codec *codec,
5799 unsigned int dmic, struct wcd9xxx_pdata *pdata)
5800{
5801 u8 tx_stream_fs;
5802 u8 adc_mux_index = 0, adc_mux_sel = 0;
5803 bool dec_found = false;
5804 u16 adc_mux_ctl_reg, tx_fs_reg;
5805 u32 dmic_fs;
5806
5807 while (dec_found == 0 && adc_mux_index < WCD9335_MAX_VALID_ADC_MUX) {
5808 if (adc_mux_index < 4) {
5809 adc_mux_ctl_reg = WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG0 +
5810 (adc_mux_index * 2);
5811 adc_mux_sel = ((snd_soc_read(codec, adc_mux_ctl_reg) &
5812 0x78) >> 3) - 1;
5813 } else if (adc_mux_index < 9) {
5814 adc_mux_ctl_reg = WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0 +
5815 ((adc_mux_index - 4) * 1);
5816 adc_mux_sel = ((snd_soc_read(codec, adc_mux_ctl_reg) &
5817 0x38) >> 3) - 1;
5818 } else if (adc_mux_index == 9) {
5819 ++adc_mux_index;
5820 continue;
5821 }
5822 if (adc_mux_sel == dmic)
5823 dec_found = true;
5824 else
5825 ++adc_mux_index;
5826 }
5827
5828 if (dec_found == true && adc_mux_index <= 8) {
5829 tx_fs_reg = WCD9335_CDC_TX0_TX_PATH_CTL + (16 * adc_mux_index);
5830 tx_stream_fs = snd_soc_read(codec, tx_fs_reg) & 0x0F;
5831 dmic_fs = tx_stream_fs <= 4 ? WCD9XXX_DMIC_SAMPLE_RATE_2P4MHZ :
5832 WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ;
5833
5834 /*
5835 * Check for ECPP path selection and DEC1 not connected to
5836 * any other audio path to apply ECPP DMIC sample rate
5837 */
5838 if ((adc_mux_index == 1) &&
5839 ((snd_soc_read(codec, WCD9335_CPE_SS_US_EC_MUX_CFG)
5840 & 0x0F) == 0x0A) &&
5841 ((snd_soc_read(codec, WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0)
5842 & 0x0C) == 0x00)) {
5843 dmic_fs = pdata->ecpp_dmic_sample_rate;
5844 }
5845 } else {
5846 dmic_fs = pdata->dmic_sample_rate;
5847 }
5848
5849 return dmic_fs;
5850}
5851
5852static u8 tasha_get_dmic_clk_val(struct snd_soc_codec *codec,
5853 u32 mclk_rate, u32 dmic_clk_rate)
5854{
5855 u32 div_factor;
5856 u8 dmic_ctl_val;
5857
5858 dev_dbg(codec->dev,
5859 "%s: mclk_rate = %d, dmic_sample_rate = %d\n",
5860 __func__, mclk_rate, dmic_clk_rate);
5861
5862 /* Default value to return in case of error */
5863 if (mclk_rate == TASHA_MCLK_CLK_9P6MHZ)
5864 dmic_ctl_val = WCD9335_DMIC_CLK_DIV_2;
5865 else
5866 dmic_ctl_val = WCD9335_DMIC_CLK_DIV_3;
5867
5868 if (dmic_clk_rate == 0) {
5869 dev_err(codec->dev,
5870 "%s: dmic_sample_rate cannot be 0\n",
5871 __func__);
5872 goto done;
5873 }
5874
5875 div_factor = mclk_rate / dmic_clk_rate;
5876 switch (div_factor) {
5877 case 2:
5878 dmic_ctl_val = WCD9335_DMIC_CLK_DIV_2;
5879 break;
5880 case 3:
5881 dmic_ctl_val = WCD9335_DMIC_CLK_DIV_3;
5882 break;
5883 case 4:
5884 dmic_ctl_val = WCD9335_DMIC_CLK_DIV_4;
5885 break;
5886 case 6:
5887 dmic_ctl_val = WCD9335_DMIC_CLK_DIV_6;
5888 break;
5889 case 8:
5890 dmic_ctl_val = WCD9335_DMIC_CLK_DIV_8;
5891 break;
5892 case 16:
5893 dmic_ctl_val = WCD9335_DMIC_CLK_DIV_16;
5894 break;
5895 default:
5896 dev_err(codec->dev,
5897 "%s: Invalid div_factor %u, clk_rate(%u), dmic_rate(%u)\n",
5898 __func__, div_factor, mclk_rate, dmic_clk_rate);
5899 break;
5900 }
5901
5902done:
5903 return dmic_ctl_val;
5904}
5905
5906static int tasha_codec_enable_adc(struct snd_soc_dapm_widget *w,
5907 struct snd_kcontrol *kcontrol, int event)
5908{
5909 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
5910
5911 dev_dbg(codec->dev, "%s: event:%d\n", __func__, event);
5912
5913 switch (event) {
5914 case SND_SOC_DAPM_PRE_PMU:
5915 tasha_codec_set_tx_hold(codec, w->reg, true);
5916 break;
5917 default:
5918 break;
5919 }
5920
5921 return 0;
5922}
5923
5924static int tasha_codec_enable_dmic(struct snd_soc_dapm_widget *w,
5925 struct snd_kcontrol *kcontrol, int event)
5926{
5927 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
5928 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
5929 struct wcd9xxx_pdata *pdata = dev_get_platdata(codec->dev->parent);
5930 u8 dmic_clk_en = 0x01;
5931 u16 dmic_clk_reg;
5932 s32 *dmic_clk_cnt;
5933 u8 dmic_rate_val, dmic_rate_shift = 1;
5934 unsigned int dmic;
5935 u32 dmic_sample_rate;
5936 int ret;
5937 char *wname;
5938
5939 wname = strpbrk(w->name, "012345");
5940 if (!wname) {
5941 dev_err(codec->dev, "%s: widget not found\n", __func__);
5942 return -EINVAL;
5943 }
5944
5945 ret = kstrtouint(wname, 10, &dmic);
5946 if (ret < 0) {
5947 dev_err(codec->dev, "%s: Invalid DMIC line on the codec\n",
5948 __func__);
5949 return -EINVAL;
5950 }
5951
5952 switch (dmic) {
5953 case 0:
5954 case 1:
5955 dmic_clk_cnt = &(tasha->dmic_0_1_clk_cnt);
5956 dmic_clk_reg = WCD9335_CPE_SS_DMIC0_CTL;
5957 break;
5958 case 2:
5959 case 3:
5960 dmic_clk_cnt = &(tasha->dmic_2_3_clk_cnt);
5961 dmic_clk_reg = WCD9335_CPE_SS_DMIC1_CTL;
5962 break;
5963 case 4:
5964 case 5:
5965 dmic_clk_cnt = &(tasha->dmic_4_5_clk_cnt);
5966 dmic_clk_reg = WCD9335_CPE_SS_DMIC2_CTL;
5967 break;
5968 default:
5969 dev_err(codec->dev, "%s: Invalid DMIC Selection\n",
5970 __func__);
5971 return -EINVAL;
5972 };
5973 dev_dbg(codec->dev, "%s: event %d DMIC%d dmic_clk_cnt %d\n",
5974 __func__, event, dmic, *dmic_clk_cnt);
5975
5976 switch (event) {
5977 case SND_SOC_DAPM_PRE_PMU:
5978 dmic_sample_rate = tasha_get_dmic_sample_rate(codec, dmic,
5979 pdata);
5980 dmic_rate_val =
5981 tasha_get_dmic_clk_val(codec,
5982 pdata->mclk_rate,
5983 dmic_sample_rate);
5984
5985 (*dmic_clk_cnt)++;
5986 if (*dmic_clk_cnt == 1) {
5987 snd_soc_update_bits(codec, dmic_clk_reg,
5988 0x07 << dmic_rate_shift,
5989 dmic_rate_val << dmic_rate_shift);
5990 snd_soc_update_bits(codec, dmic_clk_reg,
5991 dmic_clk_en, dmic_clk_en);
5992 }
5993
5994 break;
5995 case SND_SOC_DAPM_POST_PMD:
5996 dmic_rate_val =
5997 tasha_get_dmic_clk_val(codec,
5998 pdata->mclk_rate,
5999 pdata->mad_dmic_sample_rate);
6000 (*dmic_clk_cnt)--;
6001 if (*dmic_clk_cnt == 0) {
6002 snd_soc_update_bits(codec, dmic_clk_reg,
6003 dmic_clk_en, 0);
6004 snd_soc_update_bits(codec, dmic_clk_reg,
6005 0x07 << dmic_rate_shift,
6006 dmic_rate_val << dmic_rate_shift);
6007 }
6008 break;
6009 };
6010
6011 return 0;
6012}
6013
6014static int __tasha_codec_enable_micbias(struct snd_soc_dapm_widget *w,
6015 int event)
6016{
6017 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
6018 int micb_num;
6019
6020 dev_dbg(codec->dev, "%s: wname: %s, event: %d\n",
6021 __func__, w->name, event);
6022
6023 if (strnstr(w->name, "MIC BIAS1", sizeof("MIC BIAS1")))
6024 micb_num = MIC_BIAS_1;
6025 else if (strnstr(w->name, "MIC BIAS2", sizeof("MIC BIAS2")))
6026 micb_num = MIC_BIAS_2;
6027 else if (strnstr(w->name, "MIC BIAS3", sizeof("MIC BIAS3")))
6028 micb_num = MIC_BIAS_3;
6029 else if (strnstr(w->name, "MIC BIAS4", sizeof("MIC BIAS4")))
6030 micb_num = MIC_BIAS_4;
6031 else
6032 return -EINVAL;
6033
6034 switch (event) {
6035 case SND_SOC_DAPM_PRE_PMU:
6036 /*
6037 * MIC BIAS can also be requested by MBHC,
6038 * so use ref count to handle micbias pullup
6039 * and enable requests
6040 */
6041 tasha_micbias_control(codec, micb_num, MICB_ENABLE, true);
6042 break;
6043 case SND_SOC_DAPM_POST_PMU:
6044 /* wait for cnp time */
6045 usleep_range(1000, 1100);
6046 break;
6047 case SND_SOC_DAPM_POST_PMD:
6048 tasha_micbias_control(codec, micb_num, MICB_DISABLE, true);
6049 break;
6050 };
6051
6052 return 0;
6053}
6054
6055static int tasha_codec_ldo_h_control(struct snd_soc_dapm_widget *w,
6056 int event)
6057{
6058 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
6059 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
6060
6061 if (SND_SOC_DAPM_EVENT_ON(event)) {
6062 tasha->ldo_h_users++;
6063
6064 if (tasha->ldo_h_users == 1)
6065 snd_soc_update_bits(codec, WCD9335_LDOH_MODE,
6066 0x80, 0x80);
6067 }
6068
6069 if (SND_SOC_DAPM_EVENT_OFF(event)) {
6070 tasha->ldo_h_users--;
6071
6072 if (tasha->ldo_h_users < 0)
6073 tasha->ldo_h_users = 0;
6074
6075 if (tasha->ldo_h_users == 0)
6076 snd_soc_update_bits(codec, WCD9335_LDOH_MODE,
6077 0x80, 0x00);
6078 }
6079
6080 return 0;
6081}
6082
6083static int tasha_codec_force_enable_ldo_h(struct snd_soc_dapm_widget *w,
6084 struct snd_kcontrol *kcontrol,
6085 int event)
6086{
6087 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
6088 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
6089
6090 switch (event) {
6091 case SND_SOC_DAPM_PRE_PMU:
6092 wcd_resmgr_enable_master_bias(tasha->resmgr);
6093 tasha_codec_ldo_h_control(w, event);
6094 break;
6095 case SND_SOC_DAPM_POST_PMD:
6096 tasha_codec_ldo_h_control(w, event);
6097 wcd_resmgr_disable_master_bias(tasha->resmgr);
6098 break;
6099 }
6100
6101 return 0;
6102}
6103
6104static int tasha_codec_force_enable_micbias(struct snd_soc_dapm_widget *w,
6105 struct snd_kcontrol *kcontrol,
6106 int event)
6107{
6108 int ret = 0;
6109 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
6110 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
6111
6112 switch (event) {
6113 case SND_SOC_DAPM_PRE_PMU:
6114 wcd_resmgr_enable_master_bias(tasha->resmgr);
6115 tasha_cdc_mclk_enable(codec, true, true);
6116 ret = __tasha_codec_enable_micbias(w, SND_SOC_DAPM_PRE_PMU);
6117 /* Wait for 1ms for better cnp */
6118 usleep_range(1000, 1100);
6119 tasha_cdc_mclk_enable(codec, false, true);
6120 break;
6121 case SND_SOC_DAPM_POST_PMD:
6122 ret = __tasha_codec_enable_micbias(w, SND_SOC_DAPM_POST_PMD);
6123 wcd_resmgr_disable_master_bias(tasha->resmgr);
6124 break;
6125 }
6126
6127 return ret;
6128}
6129
6130static int tasha_codec_enable_micbias(struct snd_soc_dapm_widget *w,
6131 struct snd_kcontrol *kcontrol, int event)
6132{
6133 return __tasha_codec_enable_micbias(w, event);
6134}
6135
6136static int tasha_codec_enable_standalone_ldo_h(struct snd_soc_codec *codec,
6137 bool enable)
6138{
6139 int rc;
6140
6141 if (enable)
6142 rc = snd_soc_dapm_force_enable_pin(
6143 snd_soc_codec_get_dapm(codec),
6144 DAPM_LDO_H_STANDALONE);
6145 else
6146 rc = snd_soc_dapm_disable_pin(
6147 snd_soc_codec_get_dapm(codec),
6148 DAPM_LDO_H_STANDALONE);
6149
6150 if (!rc)
6151 snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec));
6152 else
6153 dev_err(codec->dev, "%s: ldo_h force %s pin failed\n",
6154 __func__, (enable ? "enable" : "disable"));
6155
6156 return rc;
6157}
6158
6159/*
6160 * tasha_codec_enable_standalone_micbias - enable micbias standalone
6161 * @codec: pointer to codec instance
6162 * @micb_num: number of micbias to be enabled
6163 * @enable: true to enable micbias or false to disable
6164 *
6165 * This function is used to enable micbias (1, 2, 3 or 4) during
6166 * standalone independent of whether TX use-case is running or not
6167 *
6168 * Return: error code in case of failure or 0 for success
6169 */
6170int tasha_codec_enable_standalone_micbias(struct snd_soc_codec *codec,
6171 int micb_num,
6172 bool enable)
6173{
6174 const char * const micb_names[] = {
6175 DAPM_MICBIAS1_STANDALONE, DAPM_MICBIAS2_STANDALONE,
6176 DAPM_MICBIAS3_STANDALONE, DAPM_MICBIAS4_STANDALONE
6177 };
6178 int micb_index = micb_num - 1;
6179 int rc;
6180
6181 if (!codec) {
6182 pr_err("%s: Codec memory is NULL\n", __func__);
6183 return -EINVAL;
6184 }
6185
6186 if ((micb_index < 0) || (micb_index > TASHA_MAX_MICBIAS - 1)) {
6187 dev_err(codec->dev, "%s: Invalid micbias index, micb_ind:%d\n",
6188 __func__, micb_index);
6189 return -EINVAL;
6190 }
6191
6192 if (enable)
6193 rc = snd_soc_dapm_force_enable_pin(
6194 snd_soc_codec_get_dapm(codec),
6195 micb_names[micb_index]);
6196 else
6197 rc = snd_soc_dapm_disable_pin(snd_soc_codec_get_dapm(codec),
6198 micb_names[micb_index]);
6199
6200 if (!rc)
6201 snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec));
6202 else
6203 dev_err(codec->dev, "%s: micbias%d force %s pin failed\n",
6204 __func__, micb_num, (enable ? "enable" : "disable"));
6205
6206 return rc;
6207}
6208EXPORT_SYMBOL(tasha_codec_enable_standalone_micbias);
6209
6210static const char *const tasha_anc_func_text[] = {"OFF", "ON"};
6211static const struct soc_enum tasha_anc_func_enum =
6212 SOC_ENUM_SINGLE_EXT(2, tasha_anc_func_text);
6213
6214static const char *const tasha_clkmode_text[] = {"EXTERNAL", "INTERNAL"};
6215static SOC_ENUM_SINGLE_EXT_DECL(tasha_clkmode_enum, tasha_clkmode_text);
6216
6217/* Cutoff frequency for high pass filter */
6218static const char * const cf_text[] = {
6219 "CF_NEG_3DB_4HZ", "CF_NEG_3DB_75HZ", "CF_NEG_3DB_150HZ"
6220};
6221
6222static const char * const rx_cf_text[] = {
6223 "CF_NEG_3DB_4HZ", "CF_NEG_3DB_75HZ", "CF_NEG_3DB_150HZ",
6224 "CF_NEG_3DB_0P48HZ"
6225};
6226
6227static const struct soc_enum cf_dec0_enum =
6228 SOC_ENUM_SINGLE(WCD9335_CDC_TX0_TX_PATH_CFG0, 5, 3, cf_text);
6229
6230static const struct soc_enum cf_dec1_enum =
6231 SOC_ENUM_SINGLE(WCD9335_CDC_TX1_TX_PATH_CFG0, 5, 3, cf_text);
6232
6233static const struct soc_enum cf_dec2_enum =
6234 SOC_ENUM_SINGLE(WCD9335_CDC_TX2_TX_PATH_CFG0, 5, 3, cf_text);
6235
6236static const struct soc_enum cf_dec3_enum =
6237 SOC_ENUM_SINGLE(WCD9335_CDC_TX3_TX_PATH_CFG0, 5, 3, cf_text);
6238
6239static const struct soc_enum cf_dec4_enum =
6240 SOC_ENUM_SINGLE(WCD9335_CDC_TX4_TX_PATH_CFG0, 5, 3, cf_text);
6241
6242static const struct soc_enum cf_dec5_enum =
6243 SOC_ENUM_SINGLE(WCD9335_CDC_TX5_TX_PATH_CFG0, 5, 3, cf_text);
6244
6245static const struct soc_enum cf_dec6_enum =
6246 SOC_ENUM_SINGLE(WCD9335_CDC_TX6_TX_PATH_CFG0, 5, 3, cf_text);
6247
6248static const struct soc_enum cf_dec7_enum =
6249 SOC_ENUM_SINGLE(WCD9335_CDC_TX7_TX_PATH_CFG0, 5, 3, cf_text);
6250
6251static const struct soc_enum cf_dec8_enum =
6252 SOC_ENUM_SINGLE(WCD9335_CDC_TX8_TX_PATH_CFG0, 5, 3, cf_text);
6253
6254static const struct soc_enum cf_int0_1_enum =
6255 SOC_ENUM_SINGLE(WCD9335_CDC_RX0_RX_PATH_CFG2, 0, 4, rx_cf_text);
6256
6257static SOC_ENUM_SINGLE_DECL(cf_int0_2_enum, WCD9335_CDC_RX0_RX_PATH_MIX_CFG, 2,
6258 rx_cf_text);
6259
6260static const struct soc_enum cf_int1_1_enum =
6261 SOC_ENUM_SINGLE(WCD9335_CDC_RX1_RX_PATH_CFG2, 0, 4, rx_cf_text);
6262
6263static SOC_ENUM_SINGLE_DECL(cf_int1_2_enum, WCD9335_CDC_RX1_RX_PATH_MIX_CFG, 2,
6264 rx_cf_text);
6265
6266static const struct soc_enum cf_int2_1_enum =
6267 SOC_ENUM_SINGLE(WCD9335_CDC_RX2_RX_PATH_CFG2, 0, 4, rx_cf_text);
6268
6269static SOC_ENUM_SINGLE_DECL(cf_int2_2_enum, WCD9335_CDC_RX2_RX_PATH_MIX_CFG, 2,
6270 rx_cf_text);
6271
6272static const struct soc_enum cf_int3_1_enum =
6273 SOC_ENUM_SINGLE(WCD9335_CDC_RX3_RX_PATH_CFG2, 0, 4, rx_cf_text);
6274
6275static SOC_ENUM_SINGLE_DECL(cf_int3_2_enum, WCD9335_CDC_RX3_RX_PATH_MIX_CFG, 2,
6276 rx_cf_text);
6277
6278static const struct soc_enum cf_int4_1_enum =
6279 SOC_ENUM_SINGLE(WCD9335_CDC_RX4_RX_PATH_CFG2, 0, 4, rx_cf_text);
6280
6281static SOC_ENUM_SINGLE_DECL(cf_int4_2_enum, WCD9335_CDC_RX4_RX_PATH_MIX_CFG, 2,
6282 rx_cf_text);
6283
6284static const struct soc_enum cf_int5_1_enum =
6285 SOC_ENUM_SINGLE(WCD9335_CDC_RX5_RX_PATH_CFG2, 0, 4, rx_cf_text);
6286
6287static SOC_ENUM_SINGLE_DECL(cf_int5_2_enum, WCD9335_CDC_RX5_RX_PATH_MIX_CFG, 2,
6288 rx_cf_text);
6289
6290static const struct soc_enum cf_int6_1_enum =
6291 SOC_ENUM_SINGLE(WCD9335_CDC_RX6_RX_PATH_CFG2, 0, 4, rx_cf_text);
6292
6293static SOC_ENUM_SINGLE_DECL(cf_int6_2_enum, WCD9335_CDC_RX6_RX_PATH_MIX_CFG, 2,
6294 rx_cf_text);
6295
6296static const struct soc_enum cf_int7_1_enum =
6297 SOC_ENUM_SINGLE(WCD9335_CDC_RX7_RX_PATH_CFG2, 0, 4, rx_cf_text);
6298
6299static SOC_ENUM_SINGLE_DECL(cf_int7_2_enum, WCD9335_CDC_RX7_RX_PATH_MIX_CFG, 2,
6300 rx_cf_text);
6301
6302static const struct soc_enum cf_int8_1_enum =
6303 SOC_ENUM_SINGLE(WCD9335_CDC_RX8_RX_PATH_CFG2, 0, 4, rx_cf_text);
6304
6305static SOC_ENUM_SINGLE_DECL(cf_int8_2_enum, WCD9335_CDC_RX8_RX_PATH_MIX_CFG, 2,
6306 rx_cf_text);
6307
6308static const struct snd_soc_dapm_route audio_i2s_map[] = {
6309 {"SLIM RX0 MUX", NULL, "RX_I2S_CTL"},
6310 {"SLIM RX1 MUX", NULL, "RX_I2S_CTL"},
6311 {"SLIM RX2 MUX", NULL, "RX_I2S_CTL"},
6312 {"SLIM RX3 MUX", NULL, "RX_I2S_CTL"},
6313
6314 {"SLIM TX6 MUX", NULL, "TX_I2S_CTL"},
6315 {"SLIM TX7 MUX", NULL, "TX_I2S_CTL"},
6316 {"SLIM TX8 MUX", NULL, "TX_I2S_CTL"},
6317 {"SLIM TX11 MUX", NULL, "TX_I2S_CTL"},
6318};
6319
6320static const struct snd_soc_dapm_route audio_map[] = {
6321
6322 /* MAD */
6323 {"MAD_SEL MUX", "SPE", "MAD_CPE_INPUT"},
6324 {"MAD_SEL MUX", "MSM", "MADINPUT"},
6325 {"MADONOFF", "Switch", "MAD_SEL MUX"},
6326 {"MAD_BROADCAST", "Switch", "MAD_SEL MUX"},
6327 {"TX13 INP MUX", "CPE_TX_PP", "MADONOFF"},
6328
6329 /* CPE HW MAD bypass */
6330 {"CPE IN Mixer", "MAD_BYPASS", "SLIM TX1 MUX"},
6331
6332 {"AIF4_MAD Mixer", "SLIM TX1", "CPE IN Mixer"},
6333 {"AIF4_MAD Mixer", "SLIM TX12", "MADONOFF"},
6334 {"AIF4_MAD Mixer", "SLIM TX13", "TX13 INP MUX"},
6335 {"AIF4 MAD", NULL, "AIF4_MAD Mixer"},
6336 {"AIF4 MAD", NULL, "AIF4"},
6337
6338 {"EC BUF MUX INP", "DEC1", "ADC MUX1"},
6339 {"AIF5 CPE", NULL, "EC BUF MUX INP"},
6340
6341 /* SLIMBUS Connections */
6342 {"AIF1 CAP", NULL, "AIF1_CAP Mixer"},
6343 {"AIF2 CAP", NULL, "AIF2_CAP Mixer"},
6344 {"AIF3 CAP", NULL, "AIF3_CAP Mixer"},
6345
6346 /* VI Feedback */
6347 {"AIF4_VI Mixer", "SPKR_VI_1", "VIINPUT"},
6348 {"AIF4_VI Mixer", "SPKR_VI_2", "VIINPUT"},
6349 {"AIF4 VI", NULL, "AIF4_VI Mixer"},
6350
6351 /* SLIM_MIXER("AIF1_CAP Mixer"),*/
6352 {"AIF1_CAP Mixer", "SLIM TX0", "SLIM TX0 MUX"},
6353 {"AIF1_CAP Mixer", "SLIM TX1", "SLIM TX1 MUX"},
6354 {"AIF1_CAP Mixer", "SLIM TX2", "SLIM TX2 MUX"},
6355 {"AIF1_CAP Mixer", "SLIM TX3", "SLIM TX3 MUX"},
6356 {"AIF1_CAP Mixer", "SLIM TX4", "SLIM TX4 MUX"},
6357 {"AIF1_CAP Mixer", "SLIM TX5", "SLIM TX5 MUX"},
6358 {"AIF1_CAP Mixer", "SLIM TX6", "SLIM TX6 MUX"},
6359 {"AIF1_CAP Mixer", "SLIM TX7", "SLIM TX7 MUX"},
6360 {"AIF1_CAP Mixer", "SLIM TX8", "SLIM TX8 MUX"},
6361 {"AIF1_CAP Mixer", "SLIM TX9", "SLIM TX9 MUX"},
6362 {"AIF1_CAP Mixer", "SLIM TX10", "SLIM TX10 MUX"},
6363 {"AIF1_CAP Mixer", "SLIM TX11", "SLIM TX11 MUX"},
6364 {"AIF1_CAP Mixer", "SLIM TX13", "TX13 INP MUX"},
6365 /* SLIM_MIXER("AIF2_CAP Mixer"),*/
6366 {"AIF2_CAP Mixer", "SLIM TX0", "SLIM TX0 MUX"},
6367 {"AIF2_CAP Mixer", "SLIM TX1", "SLIM TX1 MUX"},
6368 {"AIF2_CAP Mixer", "SLIM TX2", "SLIM TX2 MUX"},
6369 {"AIF2_CAP Mixer", "SLIM TX3", "SLIM TX3 MUX"},
6370 {"AIF2_CAP Mixer", "SLIM TX4", "SLIM TX4 MUX"},
6371 {"AIF2_CAP Mixer", "SLIM TX5", "SLIM TX5 MUX"},
6372 {"AIF2_CAP Mixer", "SLIM TX6", "SLIM TX6 MUX"},
6373 {"AIF2_CAP Mixer", "SLIM TX7", "SLIM TX7 MUX"},
6374 {"AIF2_CAP Mixer", "SLIM TX8", "SLIM TX8 MUX"},
6375 {"AIF2_CAP Mixer", "SLIM TX9", "SLIM TX9 MUX"},
6376 {"AIF2_CAP Mixer", "SLIM TX10", "SLIM TX10 MUX"},
6377 {"AIF2_CAP Mixer", "SLIM TX11", "SLIM TX11 MUX"},
6378 {"AIF2_CAP Mixer", "SLIM TX13", "TX13 INP MUX"},
6379 /* SLIM_MIXER("AIF3_CAP Mixer"),*/
6380 {"AIF3_CAP Mixer", "SLIM TX0", "SLIM TX0 MUX"},
6381 {"AIF3_CAP Mixer", "SLIM TX1", "SLIM TX1 MUX"},
6382 {"AIF3_CAP Mixer", "SLIM TX2", "SLIM TX2 MUX"},
6383 {"AIF3_CAP Mixer", "SLIM TX3", "SLIM TX3 MUX"},
6384 {"AIF3_CAP Mixer", "SLIM TX4", "SLIM TX4 MUX"},
6385 {"AIF3_CAP Mixer", "SLIM TX5", "SLIM TX5 MUX"},
6386 {"AIF3_CAP Mixer", "SLIM TX6", "SLIM TX6 MUX"},
6387 {"AIF3_CAP Mixer", "SLIM TX7", "SLIM TX7 MUX"},
6388 {"AIF3_CAP Mixer", "SLIM TX8", "SLIM TX8 MUX"},
6389 {"AIF3_CAP Mixer", "SLIM TX9", "SLIM TX9 MUX"},
6390 {"AIF3_CAP Mixer", "SLIM TX10", "SLIM TX10 MUX"},
6391 {"AIF3_CAP Mixer", "SLIM TX11", "SLIM TX11 MUX"},
6392 {"AIF3_CAP Mixer", "SLIM TX13", "TX13 INP MUX"},
6393
6394 {"SLIM TX0 MUX", "DEC0", "ADC MUX0"},
6395 {"SLIM TX0 MUX", "RX_MIX_TX0", "RX MIX TX0 MUX"},
6396 {"SLIM TX0 MUX", "DEC0_192", "ADC US MUX0"},
6397
6398 {"SLIM TX1 MUX", "DEC1", "ADC MUX1"},
6399 {"SLIM TX1 MUX", "RX_MIX_TX1", "RX MIX TX1 MUX"},
6400 {"SLIM TX1 MUX", "DEC1_192", "ADC US MUX1"},
6401
6402 {"SLIM TX2 MUX", "DEC2", "ADC MUX2"},
6403 {"SLIM TX2 MUX", "RX_MIX_TX2", "RX MIX TX2 MUX"},
6404 {"SLIM TX2 MUX", "DEC2_192", "ADC US MUX2"},
6405
6406 {"SLIM TX3 MUX", "DEC3", "ADC MUX3"},
6407 {"SLIM TX3 MUX", "RX_MIX_TX3", "RX MIX TX3 MUX"},
6408 {"SLIM TX3 MUX", "DEC3_192", "ADC US MUX3"},
6409
6410 {"SLIM TX4 MUX", "DEC4", "ADC MUX4"},
6411 {"SLIM TX4 MUX", "RX_MIX_TX4", "RX MIX TX4 MUX"},
6412 {"SLIM TX4 MUX", "DEC4_192", "ADC US MUX4"},
6413
6414 {"SLIM TX5 MUX", "DEC5", "ADC MUX5"},
6415 {"SLIM TX5 MUX", "RX_MIX_TX5", "RX MIX TX5 MUX"},
6416 {"SLIM TX5 MUX", "DEC5_192", "ADC US MUX5"},
6417
6418 {"SLIM TX6 MUX", "DEC6", "ADC MUX6"},
6419 {"SLIM TX6 MUX", "RX_MIX_TX6", "RX MIX TX6 MUX"},
6420 {"SLIM TX6 MUX", "DEC6_192", "ADC US MUX6"},
6421
6422 {"SLIM TX7 MUX", "DEC7", "ADC MUX7"},
6423 {"SLIM TX7 MUX", "RX_MIX_TX7", "RX MIX TX7 MUX"},
6424 {"SLIM TX7 MUX", "DEC7_192", "ADC US MUX7"},
6425
6426 {"SLIM TX8 MUX", "DEC8", "ADC MUX8"},
6427 {"SLIM TX8 MUX", "RX_MIX_TX8", "RX MIX TX8 MUX"},
6428 {"SLIM TX8 MUX", "DEC8_192", "ADC US MUX8"},
6429
6430 {"SLIM TX9 MUX", "DEC7", "ADC MUX7"},
6431 {"SLIM TX9 MUX", "DEC7_192", "ADC US MUX7"},
6432 {"SLIM TX10 MUX", "DEC6", "ADC MUX6"},
6433 {"SLIM TX10 MUX", "DEC6_192", "ADC US MUX6"},
6434
6435 {"SLIM TX11 MUX", "DEC_0_5", "SLIM TX11 INP1 MUX"},
6436 {"SLIM TX11 MUX", "DEC_9_12", "SLIM TX11 INP1 MUX"},
6437 {"SLIM TX11 INP1 MUX", "DEC0", "ADC MUX0"},
6438 {"SLIM TX11 INP1 MUX", "DEC1", "ADC MUX1"},
6439 {"SLIM TX11 INP1 MUX", "DEC2", "ADC MUX2"},
6440 {"SLIM TX11 INP1 MUX", "DEC3", "ADC MUX3"},
6441 {"SLIM TX11 INP1 MUX", "DEC4", "ADC MUX4"},
6442 {"SLIM TX11 INP1 MUX", "DEC5", "ADC MUX5"},
6443 {"SLIM TX11 INP1 MUX", "RX_MIX_TX5", "RX MIX TX5 MUX"},
6444
6445 {"TX13 INP MUX", "MAD_BRDCST", "MAD_BROADCAST"},
6446 {"TX13 INP MUX", "CDC_DEC_5", "SLIM TX13 MUX"},
6447 {"SLIM TX13 MUX", "DEC5", "ADC MUX5"},
6448
6449 {"RX MIX TX0 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
6450 {"RX MIX TX0 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
6451 {"RX MIX TX0 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
6452 {"RX MIX TX0 MUX", "RX_MIX3", "RX INT3 SEC MIX"},
6453 {"RX MIX TX0 MUX", "RX_MIX4", "RX INT4 SEC MIX"},
6454 {"RX MIX TX0 MUX", "RX_MIX5", "RX INT5 SEC MIX"},
6455 {"RX MIX TX0 MUX", "RX_MIX6", "RX INT6 SEC MIX"},
6456 {"RX MIX TX0 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
6457 {"RX MIX TX0 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
6458 {"RX MIX TX0 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"},
6459 {"RX MIX TX0 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"},
6460 {"RX MIX TX0 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"},
6461 {"RX MIX TX0 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"},
6462
6463 {"RX MIX TX1 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
6464 {"RX MIX TX1 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
6465 {"RX MIX TX1 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
6466 {"RX MIX TX1 MUX", "RX_MIX3", "RX INT3 SEC MIX"},
6467 {"RX MIX TX1 MUX", "RX_MIX4", "RX INT4 SEC MIX"},
6468 {"RX MIX TX1 MUX", "RX_MIX5", "RX INT5 SEC MIX"},
6469 {"RX MIX TX1 MUX", "RX_MIX6", "RX INT6 SEC MIX"},
6470 {"RX MIX TX1 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
6471 {"RX MIX TX1 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
6472 {"RX MIX TX1 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"},
6473 {"RX MIX TX1 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"},
6474 {"RX MIX TX1 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"},
6475 {"RX MIX TX1 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"},
6476
6477 {"RX MIX TX2 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
6478 {"RX MIX TX2 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
6479 {"RX MIX TX2 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
6480 {"RX MIX TX2 MUX", "RX_MIX3", "RX INT3 SEC MIX"},
6481 {"RX MIX TX2 MUX", "RX_MIX4", "RX INT4 SEC MIX"},
6482 {"RX MIX TX2 MUX", "RX_MIX5", "RX INT5 SEC MIX"},
6483 {"RX MIX TX2 MUX", "RX_MIX6", "RX INT6 SEC MIX"},
6484 {"RX MIX TX2 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
6485 {"RX MIX TX2 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
6486 {"RX MIX TX2 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"},
6487 {"RX MIX TX2 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"},
6488 {"RX MIX TX2 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"},
6489 {"RX MIX TX2 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"},
6490
6491 {"RX MIX TX3 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
6492 {"RX MIX TX3 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
6493 {"RX MIX TX3 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
6494 {"RX MIX TX3 MUX", "RX_MIX3", "RX INT3 SEC MIX"},
6495 {"RX MIX TX3 MUX", "RX_MIX4", "RX INT4 SEC MIX"},
6496 {"RX MIX TX3 MUX", "RX_MIX5", "RX INT5 SEC MIX"},
6497 {"RX MIX TX3 MUX", "RX_MIX6", "RX INT6 SEC MIX"},
6498 {"RX MIX TX3 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
6499 {"RX MIX TX3 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
6500 {"RX MIX TX3 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"},
6501 {"RX MIX TX3 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"},
6502 {"RX MIX TX3 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"},
6503 {"RX MIX TX3 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"},
6504
6505 {"RX MIX TX4 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
6506 {"RX MIX TX4 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
6507 {"RX MIX TX4 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
6508 {"RX MIX TX4 MUX", "RX_MIX3", "RX INT3 SEC MIX"},
6509 {"RX MIX TX4 MUX", "RX_MIX4", "RX INT4 SEC MIX"},
6510 {"RX MIX TX4 MUX", "RX_MIX5", "RX INT5 SEC MIX"},
6511 {"RX MIX TX4 MUX", "RX_MIX6", "RX INT6 SEC MIX"},
6512 {"RX MIX TX4 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
6513 {"RX MIX TX4 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
6514 {"RX MIX TX4 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"},
6515 {"RX MIX TX4 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"},
6516 {"RX MIX TX4 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"},
6517 {"RX MIX TX4 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"},
6518
6519 {"RX MIX TX5 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
6520 {"RX MIX TX5 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
6521 {"RX MIX TX5 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
6522 {"RX MIX TX5 MUX", "RX_MIX3", "RX INT3 SEC MIX"},
6523 {"RX MIX TX5 MUX", "RX_MIX4", "RX INT4 SEC MIX"},
6524 {"RX MIX TX5 MUX", "RX_MIX5", "RX INT5 SEC MIX"},
6525 {"RX MIX TX5 MUX", "RX_MIX6", "RX INT6 SEC MIX"},
6526 {"RX MIX TX5 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
6527 {"RX MIX TX5 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
6528 {"RX MIX TX5 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"},
6529 {"RX MIX TX5 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"},
6530 {"RX MIX TX5 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"},
6531 {"RX MIX TX5 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"},
6532
6533 {"RX MIX TX6 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
6534 {"RX MIX TX6 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
6535 {"RX MIX TX6 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
6536 {"RX MIX TX6 MUX", "RX_MIX3", "RX INT3 SEC MIX"},
6537 {"RX MIX TX6 MUX", "RX_MIX4", "RX INT4 SEC MIX"},
6538 {"RX MIX TX6 MUX", "RX_MIX5", "RX INT5 SEC MIX"},
6539 {"RX MIX TX6 MUX", "RX_MIX6", "RX INT6 SEC MIX"},
6540 {"RX MIX TX6 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
6541 {"RX MIX TX6 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
6542 {"RX MIX TX6 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"},
6543 {"RX MIX TX6 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"},
6544 {"RX MIX TX6 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"},
6545 {"RX MIX TX6 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"},
6546
6547 {"RX MIX TX7 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
6548 {"RX MIX TX7 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
6549 {"RX MIX TX7 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
6550 {"RX MIX TX7 MUX", "RX_MIX3", "RX INT3 SEC MIX"},
6551 {"RX MIX TX7 MUX", "RX_MIX4", "RX INT4 SEC MIX"},
6552 {"RX MIX TX7 MUX", "RX_MIX5", "RX INT5 SEC MIX"},
6553 {"RX MIX TX7 MUX", "RX_MIX6", "RX INT6 SEC MIX"},
6554 {"RX MIX TX7 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
6555 {"RX MIX TX7 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
6556 {"RX MIX TX7 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"},
6557 {"RX MIX TX7 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"},
6558 {"RX MIX TX7 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"},
6559 {"RX MIX TX7 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"},
6560
6561 {"RX MIX TX8 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
6562 {"RX MIX TX8 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
6563 {"RX MIX TX8 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
6564 {"RX MIX TX8 MUX", "RX_MIX3", "RX INT3 SEC MIX"},
6565 {"RX MIX TX8 MUX", "RX_MIX4", "RX INT4 SEC MIX"},
6566 {"RX MIX TX8 MUX", "RX_MIX5", "RX INT5 SEC MIX"},
6567 {"RX MIX TX8 MUX", "RX_MIX6", "RX INT6 SEC MIX"},
6568 {"RX MIX TX8 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
6569 {"RX MIX TX8 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
6570 {"RX MIX TX8 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"},
6571 {"RX MIX TX8 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"},
6572 {"RX MIX TX8 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"},
6573 {"RX MIX TX8 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"},
6574
6575 {"ADC US MUX0", "US_Switch", "ADC MUX0"},
6576 {"ADC US MUX1", "US_Switch", "ADC MUX1"},
6577 {"ADC US MUX2", "US_Switch", "ADC MUX2"},
6578 {"ADC US MUX3", "US_Switch", "ADC MUX3"},
6579 {"ADC US MUX4", "US_Switch", "ADC MUX4"},
6580 {"ADC US MUX5", "US_Switch", "ADC MUX5"},
6581 {"ADC US MUX6", "US_Switch", "ADC MUX6"},
6582 {"ADC US MUX7", "US_Switch", "ADC MUX7"},
6583 {"ADC US MUX8", "US_Switch", "ADC MUX8"},
6584 {"ADC MUX0", "DMIC", "DMIC MUX0"},
6585 {"ADC MUX0", "AMIC", "AMIC MUX0"},
6586 {"ADC MUX1", "DMIC", "DMIC MUX1"},
6587 {"ADC MUX1", "AMIC", "AMIC MUX1"},
6588 {"ADC MUX2", "DMIC", "DMIC MUX2"},
6589 {"ADC MUX2", "AMIC", "AMIC MUX2"},
6590 {"ADC MUX3", "DMIC", "DMIC MUX3"},
6591 {"ADC MUX3", "AMIC", "AMIC MUX3"},
6592 {"ADC MUX4", "DMIC", "DMIC MUX4"},
6593 {"ADC MUX4", "AMIC", "AMIC MUX4"},
6594 {"ADC MUX5", "DMIC", "DMIC MUX5"},
6595 {"ADC MUX5", "AMIC", "AMIC MUX5"},
6596 {"ADC MUX6", "DMIC", "DMIC MUX6"},
6597 {"ADC MUX6", "AMIC", "AMIC MUX6"},
6598 {"ADC MUX7", "DMIC", "DMIC MUX7"},
6599 {"ADC MUX7", "AMIC", "AMIC MUX7"},
6600 {"ADC MUX8", "DMIC", "DMIC MUX8"},
6601 {"ADC MUX8", "AMIC", "AMIC MUX8"},
6602 {"ADC MUX10", "DMIC", "DMIC MUX10"},
6603 {"ADC MUX10", "AMIC", "AMIC MUX10"},
6604 {"ADC MUX11", "DMIC", "DMIC MUX11"},
6605 {"ADC MUX11", "AMIC", "AMIC MUX11"},
6606 {"ADC MUX12", "DMIC", "DMIC MUX12"},
6607 {"ADC MUX12", "AMIC", "AMIC MUX12"},
6608 {"ADC MUX13", "DMIC", "DMIC MUX13"},
6609 {"ADC MUX13", "AMIC", "AMIC MUX13"},
6610
6611 {"ADC MUX0", "ANC_FB_TUNE1", "ADC MUX10"},
6612 {"ADC MUX0", "ANC_FB_TUNE1", "ADC MUX11"},
6613 {"ADC MUX0", "ANC_FB_TUNE2", "ADC MUX12"},
6614 {"ADC MUX0", "ANC_FB_TUNE2", "ADC MUX13"},
6615 {"ADC MUX1", "ANC_FB_TUNE1", "ADC MUX10"},
6616 {"ADC MUX1", "ANC_FB_TUNE1", "ADC MUX11"},
6617 {"ADC MUX1", "ANC_FB_TUNE2", "ADC MUX12"},
6618 {"ADC MUX1", "ANC_FB_TUNE2", "ADC MUX13"},
6619 {"ADC MUX2", "ANC_FB_TUNE1", "ADC MUX10"},
6620 {"ADC MUX2", "ANC_FB_TUNE1", "ADC MUX11"},
6621 {"ADC MUX2", "ANC_FB_TUNE2", "ADC MUX12"},
6622 {"ADC MUX2", "ANC_FB_TUNE2", "ADC MUX13"},
6623 {"ADC MUX3", "ANC_FB_TUNE1", "ADC MUX10"},
6624 {"ADC MUX3", "ANC_FB_TUNE1", "ADC MUX11"},
6625 {"ADC MUX3", "ANC_FB_TUNE2", "ADC MUX12"},
6626 {"ADC MUX3", "ANC_FB_TUNE2", "ADC MUX13"},
6627 {"ADC MUX4", "ANC_FB_TUNE1", "ADC MUX10"},
6628 {"ADC MUX4", "ANC_FB_TUNE1", "ADC MUX11"},
6629 {"ADC MUX4", "ANC_FB_TUNE2", "ADC MUX12"},
6630 {"ADC MUX4", "ANC_FB_TUNE2", "ADC MUX13"},
6631 {"ADC MUX5", "ANC_FB_TUNE1", "ADC MUX10"},
6632 {"ADC MUX5", "ANC_FB_TUNE1", "ADC MUX11"},
6633 {"ADC MUX5", "ANC_FB_TUNE2", "ADC MUX12"},
6634 {"ADC MUX5", "ANC_FB_TUNE2", "ADC MUX13"},
6635 {"ADC MUX6", "ANC_FB_TUNE1", "ADC MUX10"},
6636 {"ADC MUX6", "ANC_FB_TUNE1", "ADC MUX11"},
6637 {"ADC MUX6", "ANC_FB_TUNE2", "ADC MUX12"},
6638 {"ADC MUX6", "ANC_FB_TUNE2", "ADC MUX13"},
6639 {"ADC MUX7", "ANC_FB_TUNE1", "ADC MUX10"},
6640 {"ADC MUX7", "ANC_FB_TUNE1", "ADC MUX11"},
6641 {"ADC MUX7", "ANC_FB_TUNE2", "ADC MUX12"},
6642 {"ADC MUX7", "ANC_FB_TUNE2", "ADC MUX13"},
6643 {"ADC MUX8", "ANC_FB_TUNE1", "ADC MUX10"},
6644 {"ADC MUX8", "ANC_FB_TUNE1", "ADC MUX11"},
6645 {"ADC MUX8", "ANC_FB_TUNE2", "ADC MUX12"},
6646 {"ADC MUX8", "ANC_FB_TUNE2", "ADC MUX13"},
6647
6648 {"DMIC MUX0", "DMIC0", "DMIC0"},
6649 {"DMIC MUX0", "DMIC1", "DMIC1"},
6650 {"DMIC MUX0", "DMIC2", "DMIC2"},
6651 {"DMIC MUX0", "DMIC3", "DMIC3"},
6652 {"DMIC MUX0", "DMIC4", "DMIC4"},
6653 {"DMIC MUX0", "DMIC5", "DMIC5"},
6654 {"AMIC MUX0", "ADC1", "ADC1"},
6655 {"AMIC MUX0", "ADC2", "ADC2"},
6656 {"AMIC MUX0", "ADC3", "ADC3"},
6657 {"AMIC MUX0", "ADC4", "ADC4"},
6658 {"AMIC MUX0", "ADC5", "ADC5"},
6659 {"AMIC MUX0", "ADC6", "ADC6"},
6660
6661 {"DMIC MUX1", "DMIC0", "DMIC0"},
6662 {"DMIC MUX1", "DMIC1", "DMIC1"},
6663 {"DMIC MUX1", "DMIC2", "DMIC2"},
6664 {"DMIC MUX1", "DMIC3", "DMIC3"},
6665 {"DMIC MUX1", "DMIC4", "DMIC4"},
6666 {"DMIC MUX1", "DMIC5", "DMIC5"},
6667 {"AMIC MUX1", "ADC1", "ADC1"},
6668 {"AMIC MUX1", "ADC2", "ADC2"},
6669 {"AMIC MUX1", "ADC3", "ADC3"},
6670 {"AMIC MUX1", "ADC4", "ADC4"},
6671 {"AMIC MUX1", "ADC5", "ADC5"},
6672 {"AMIC MUX1", "ADC6", "ADC6"},
6673
6674 {"DMIC MUX2", "DMIC0", "DMIC0"},
6675 {"DMIC MUX2", "DMIC1", "DMIC1"},
6676 {"DMIC MUX2", "DMIC2", "DMIC2"},
6677 {"DMIC MUX2", "DMIC3", "DMIC3"},
6678 {"DMIC MUX2", "DMIC4", "DMIC4"},
6679 {"DMIC MUX2", "DMIC5", "DMIC5"},
6680 {"AMIC MUX2", "ADC1", "ADC1"},
6681 {"AMIC MUX2", "ADC2", "ADC2"},
6682 {"AMIC MUX2", "ADC3", "ADC3"},
6683 {"AMIC MUX2", "ADC4", "ADC4"},
6684 {"AMIC MUX2", "ADC5", "ADC5"},
6685 {"AMIC MUX2", "ADC6", "ADC6"},
6686
6687 {"DMIC MUX3", "DMIC0", "DMIC0"},
6688 {"DMIC MUX3", "DMIC1", "DMIC1"},
6689 {"DMIC MUX3", "DMIC2", "DMIC2"},
6690 {"DMIC MUX3", "DMIC3", "DMIC3"},
6691 {"DMIC MUX3", "DMIC4", "DMIC4"},
6692 {"DMIC MUX3", "DMIC5", "DMIC5"},
6693 {"AMIC MUX3", "ADC1", "ADC1"},
6694 {"AMIC MUX3", "ADC2", "ADC2"},
6695 {"AMIC MUX3", "ADC3", "ADC3"},
6696 {"AMIC MUX3", "ADC4", "ADC4"},
6697 {"AMIC MUX3", "ADC5", "ADC5"},
6698 {"AMIC MUX3", "ADC6", "ADC6"},
6699
6700 {"DMIC MUX4", "DMIC0", "DMIC0"},
6701 {"DMIC MUX4", "DMIC1", "DMIC1"},
6702 {"DMIC MUX4", "DMIC2", "DMIC2"},
6703 {"DMIC MUX4", "DMIC3", "DMIC3"},
6704 {"DMIC MUX4", "DMIC4", "DMIC4"},
6705 {"DMIC MUX4", "DMIC5", "DMIC5"},
6706 {"AMIC MUX4", "ADC1", "ADC1"},
6707 {"AMIC MUX4", "ADC2", "ADC2"},
6708 {"AMIC MUX4", "ADC3", "ADC3"},
6709 {"AMIC MUX4", "ADC4", "ADC4"},
6710 {"AMIC MUX4", "ADC5", "ADC5"},
6711 {"AMIC MUX4", "ADC6", "ADC6"},
6712
6713 {"DMIC MUX5", "DMIC0", "DMIC0"},
6714 {"DMIC MUX5", "DMIC1", "DMIC1"},
6715 {"DMIC MUX5", "DMIC2", "DMIC2"},
6716 {"DMIC MUX5", "DMIC3", "DMIC3"},
6717 {"DMIC MUX5", "DMIC4", "DMIC4"},
6718 {"DMIC MUX5", "DMIC5", "DMIC5"},
6719 {"AMIC MUX5", "ADC1", "ADC1"},
6720 {"AMIC MUX5", "ADC2", "ADC2"},
6721 {"AMIC MUX5", "ADC3", "ADC3"},
6722 {"AMIC MUX5", "ADC4", "ADC4"},
6723 {"AMIC MUX5", "ADC5", "ADC5"},
6724 {"AMIC MUX5", "ADC6", "ADC6"},
6725
6726 {"DMIC MUX6", "DMIC0", "DMIC0"},
6727 {"DMIC MUX6", "DMIC1", "DMIC1"},
6728 {"DMIC MUX6", "DMIC2", "DMIC2"},
6729 {"DMIC MUX6", "DMIC3", "DMIC3"},
6730 {"DMIC MUX6", "DMIC4", "DMIC4"},
6731 {"DMIC MUX6", "DMIC5", "DMIC5"},
6732 {"AMIC MUX6", "ADC1", "ADC1"},
6733 {"AMIC MUX6", "ADC2", "ADC2"},
6734 {"AMIC MUX6", "ADC3", "ADC3"},
6735 {"AMIC MUX6", "ADC4", "ADC4"},
6736 {"AMIC MUX6", "ADC5", "ADC5"},
6737 {"AMIC MUX6", "ADC6", "ADC6"},
6738
6739 {"DMIC MUX7", "DMIC0", "DMIC0"},
6740 {"DMIC MUX7", "DMIC1", "DMIC1"},
6741 {"DMIC MUX7", "DMIC2", "DMIC2"},
6742 {"DMIC MUX7", "DMIC3", "DMIC3"},
6743 {"DMIC MUX7", "DMIC4", "DMIC4"},
6744 {"DMIC MUX7", "DMIC5", "DMIC5"},
6745 {"AMIC MUX7", "ADC1", "ADC1"},
6746 {"AMIC MUX7", "ADC2", "ADC2"},
6747 {"AMIC MUX7", "ADC3", "ADC3"},
6748 {"AMIC MUX7", "ADC4", "ADC4"},
6749 {"AMIC MUX7", "ADC5", "ADC5"},
6750 {"AMIC MUX7", "ADC6", "ADC6"},
6751
6752 {"DMIC MUX8", "DMIC0", "DMIC0"},
6753 {"DMIC MUX8", "DMIC1", "DMIC1"},
6754 {"DMIC MUX8", "DMIC2", "DMIC2"},
6755 {"DMIC MUX8", "DMIC3", "DMIC3"},
6756 {"DMIC MUX8", "DMIC4", "DMIC4"},
6757 {"DMIC MUX8", "DMIC5", "DMIC5"},
6758 {"AMIC MUX8", "ADC1", "ADC1"},
6759 {"AMIC MUX8", "ADC2", "ADC2"},
6760 {"AMIC MUX8", "ADC3", "ADC3"},
6761 {"AMIC MUX8", "ADC4", "ADC4"},
6762 {"AMIC MUX8", "ADC5", "ADC5"},
6763 {"AMIC MUX8", "ADC6", "ADC6"},
6764
6765 {"DMIC MUX10", "DMIC0", "DMIC0"},
6766 {"DMIC MUX10", "DMIC1", "DMIC1"},
6767 {"DMIC MUX10", "DMIC2", "DMIC2"},
6768 {"DMIC MUX10", "DMIC3", "DMIC3"},
6769 {"DMIC MUX10", "DMIC4", "DMIC4"},
6770 {"DMIC MUX10", "DMIC5", "DMIC5"},
6771 {"AMIC MUX10", "ADC1", "ADC1"},
6772 {"AMIC MUX10", "ADC2", "ADC2"},
6773 {"AMIC MUX10", "ADC3", "ADC3"},
6774 {"AMIC MUX10", "ADC4", "ADC4"},
6775 {"AMIC MUX10", "ADC5", "ADC5"},
6776 {"AMIC MUX10", "ADC6", "ADC6"},
6777
6778 {"DMIC MUX11", "DMIC0", "DMIC0"},
6779 {"DMIC MUX11", "DMIC1", "DMIC1"},
6780 {"DMIC MUX11", "DMIC2", "DMIC2"},
6781 {"DMIC MUX11", "DMIC3", "DMIC3"},
6782 {"DMIC MUX11", "DMIC4", "DMIC4"},
6783 {"DMIC MUX11", "DMIC5", "DMIC5"},
6784 {"AMIC MUX11", "ADC1", "ADC1"},
6785 {"AMIC MUX11", "ADC2", "ADC2"},
6786 {"AMIC MUX11", "ADC3", "ADC3"},
6787 {"AMIC MUX11", "ADC4", "ADC4"},
6788 {"AMIC MUX11", "ADC5", "ADC5"},
6789 {"AMIC MUX11", "ADC6", "ADC6"},
6790
6791 {"DMIC MUX12", "DMIC0", "DMIC0"},
6792 {"DMIC MUX12", "DMIC1", "DMIC1"},
6793 {"DMIC MUX12", "DMIC2", "DMIC2"},
6794 {"DMIC MUX12", "DMIC3", "DMIC3"},
6795 {"DMIC MUX12", "DMIC4", "DMIC4"},
6796 {"DMIC MUX12", "DMIC5", "DMIC5"},
6797 {"AMIC MUX12", "ADC1", "ADC1"},
6798 {"AMIC MUX12", "ADC2", "ADC2"},
6799 {"AMIC MUX12", "ADC3", "ADC3"},
6800 {"AMIC MUX12", "ADC4", "ADC4"},
6801 {"AMIC MUX12", "ADC5", "ADC5"},
6802 {"AMIC MUX12", "ADC6", "ADC6"},
6803
6804 {"DMIC MUX13", "DMIC0", "DMIC0"},
6805 {"DMIC MUX13", "DMIC1", "DMIC1"},
6806 {"DMIC MUX13", "DMIC2", "DMIC2"},
6807 {"DMIC MUX13", "DMIC3", "DMIC3"},
6808 {"DMIC MUX13", "DMIC4", "DMIC4"},
6809 {"DMIC MUX13", "DMIC5", "DMIC5"},
6810 {"AMIC MUX13", "ADC1", "ADC1"},
6811 {"AMIC MUX13", "ADC2", "ADC2"},
6812 {"AMIC MUX13", "ADC3", "ADC3"},
6813 {"AMIC MUX13", "ADC4", "ADC4"},
6814 {"AMIC MUX13", "ADC5", "ADC5"},
6815 {"AMIC MUX13", "ADC6", "ADC6"},
6816 /* ADC Connections */
6817 {"ADC1", NULL, "AMIC1"},
6818 {"ADC2", NULL, "AMIC2"},
6819 {"ADC3", NULL, "AMIC3"},
6820 {"ADC4", NULL, "AMIC4"},
6821 {"ADC5", NULL, "AMIC5"},
6822 {"ADC6", NULL, "AMIC6"},
6823
6824 {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP0"},
6825 {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP1"},
6826 {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP2"},
6827 {"RX INT1_1 MIX1", NULL, "RX INT1_1 MIX1 INP0"},
6828 {"RX INT1_1 MIX1", NULL, "RX INT1_1 MIX1 INP1"},
6829 {"RX INT1_1 MIX1", NULL, "RX INT1_1 MIX1 INP2"},
6830 {"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP0"},
6831 {"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP1"},
6832 {"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP2"},
6833 {"RX INT3_1 MIX1", NULL, "RX INT3_1 MIX1 INP0"},
6834 {"RX INT3_1 MIX1", NULL, "RX INT3_1 MIX1 INP1"},
6835 {"RX INT3_1 MIX1", NULL, "RX INT3_1 MIX1 INP2"},
6836 {"RX INT4_1 MIX1", NULL, "RX INT4_1 MIX1 INP0"},
6837 {"RX INT4_1 MIX1", NULL, "RX INT4_1 MIX1 INP1"},
6838 {"RX INT4_1 MIX1", NULL, "RX INT4_1 MIX1 INP2"},
6839 {"RX INT5_1 MIX1", NULL, "RX INT5_1 MIX1 INP0"},
6840 {"RX INT5_1 MIX1", NULL, "RX INT5_1 MIX1 INP1"},
6841 {"RX INT5_1 MIX1", NULL, "RX INT5_1 MIX1 INP2"},
6842 {"RX INT6_1 MIX1", NULL, "RX INT6_1 MIX1 INP0"},
6843 {"RX INT6_1 MIX1", NULL, "RX INT6_1 MIX1 INP1"},
6844 {"RX INT6_1 MIX1", NULL, "RX INT6_1 MIX1 INP2"},
6845 {"RX INT7_1 MIX1", NULL, "RX INT7_1 MIX1 INP0"},
6846 {"RX INT7_1 MIX1", NULL, "RX INT7_1 MIX1 INP1"},
6847 {"RX INT7_1 MIX1", NULL, "RX INT7_1 MIX1 INP2"},
6848 {"RX INT8_1 MIX1", NULL, "RX INT8_1 MIX1 INP0"},
6849 {"RX INT8_1 MIX1", NULL, "RX INT8_1 MIX1 INP1"},
6850 {"RX INT8_1 MIX1", NULL, "RX INT8_1 MIX1 INP2"},
6851
6852 {"RX INT0 SEC MIX", NULL, "RX INT0_1 MIX1"},
6853 {"RX INT0 MIX2", NULL, "RX INT0 SEC MIX"},
6854 {"RX INT0 MIX2", NULL, "RX INT0 MIX2 INP"},
6855 {"RX INT0 INTERP", NULL, "RX INT0 MIX2"},
6856 {"RX INT0 DEM MUX", "CLSH_DSM_OUT", "RX INT0 INTERP"},
6857 {"RX INT0 DAC", NULL, "RX INT0 DEM MUX"},
6858 {"RX INT0 DAC", NULL, "RX_BIAS"},
6859 {"EAR PA", NULL, "RX INT0 DAC"},
6860 {"EAR", NULL, "EAR PA"},
6861
6862 {"SPL SRC0 MUX", "SRC_IN_HPHL", "RX INT1_1 MIX1"},
6863 {"RX INT1 SPLINE MIX", NULL, "RX INT1_1 MIX1"},
6864 {"RX INT1 SPLINE MIX", "HPHL Switch", "SPL SRC0 MUX"},
6865 {"RX INT1_1 NATIVE MUX", "ON", "RX INT1_1 MIX1"},
6866 {"RX INT1 SPLINE MIX", NULL, "RX INT1_1 NATIVE MUX"},
6867 {"RX INT1_1 NATIVE MUX", NULL, "RX INT1 NATIVE SUPPLY"},
6868 {"RX INT1 SEC MIX", NULL, "RX INT1 SPLINE MIX"},
6869 {"RX INT1 MIX2", NULL, "RX INT1 SEC MIX"},
6870 {"RX INT1 MIX2", NULL, "RX INT1 MIX2 INP"},
6871 {"RX INT1 INTERP", NULL, "RX INT1 MIX2"},
6872 {"RX INT1 DEM MUX", "CLSH_DSM_OUT", "RX INT1 INTERP"},
6873 {"RX INT1 DAC", NULL, "RX INT1 DEM MUX"},
6874 {"RX INT1 DAC", NULL, "RX_BIAS"},
6875 {"HPHL PA", NULL, "RX INT1 DAC"},
6876 {"HPHL", NULL, "HPHL PA"},
6877
6878 {"SPL SRC1 MUX", "SRC_IN_HPHR", "RX INT2_1 MIX1"},
6879 {"RX INT2 SPLINE MIX", NULL, "RX INT2_1 MIX1"},
6880 {"RX INT2 SPLINE MIX", "HPHR Switch", "SPL SRC1 MUX"},
6881 {"RX INT2_1 NATIVE MUX", "ON", "RX INT2_1 MIX1"},
6882 {"RX INT2 SPLINE MIX", NULL, "RX INT2_1 NATIVE MUX"},
6883 {"RX INT2_1 NATIVE MUX", NULL, "RX INT2 NATIVE SUPPLY"},
6884 {"RX INT2 SEC MIX", NULL, "RX INT2 SPLINE MIX"},
6885 {"RX INT2 MIX2", NULL, "RX INT2 SEC MIX"},
6886 {"RX INT2 MIX2", NULL, "RX INT2 MIX2 INP"},
6887 {"RX INT2 INTERP", NULL, "RX INT2 MIX2"},
6888 {"RX INT2 DEM MUX", "CLSH_DSM_OUT", "RX INT2 INTERP"},
6889 {"RX INT2 DAC", NULL, "RX INT2 DEM MUX"},
6890 {"RX INT2 DAC", NULL, "RX_BIAS"},
6891 {"HPHR PA", NULL, "RX INT2 DAC"},
6892 {"HPHR", NULL, "HPHR PA"},
6893
6894 {"SPL SRC0 MUX", "SRC_IN_LO1", "RX INT3_1 MIX1"},
6895 {"RX INT3 SPLINE MIX", NULL, "RX INT3_1 MIX1"},
6896 {"RX INT3 SPLINE MIX", "LO1 Switch", "SPL SRC0 MUX"},
6897 {"RX INT3_1 NATIVE MUX", "ON", "RX INT3_1 MIX1"},
6898 {"RX INT3 SPLINE MIX", NULL, "RX INT3_1 NATIVE MUX"},
6899 {"RX INT3_1 NATIVE MUX", NULL, "RX INT3 NATIVE SUPPLY"},
6900 {"RX INT3 SEC MIX", NULL, "RX INT3 SPLINE MIX"},
6901 {"RX INT3 MIX2", NULL, "RX INT3 SEC MIX"},
6902 {"RX INT3 MIX2", NULL, "RX INT3 MIX2 INP"},
6903 {"RX INT3 INTERP", NULL, "RX INT3 MIX2"},
6904 {"RX INT3 DAC", NULL, "RX INT3 INTERP"},
6905 {"RX INT3 DAC", NULL, "RX_BIAS"},
6906 {"LINEOUT1 PA", NULL, "RX INT3 DAC"},
6907 {"LINEOUT1", NULL, "LINEOUT1 PA"},
6908
6909 {"SPL SRC1 MUX", "SRC_IN_LO2", "RX INT4_1 MIX1"},
6910 {"RX INT4 SPLINE MIX", NULL, "RX INT4_1 MIX1"},
6911 {"RX INT4 SPLINE MIX", "LO2 Switch", "SPL SRC1 MUX"},
6912 {"RX INT4_1 NATIVE MUX", "ON", "RX INT4_1 MIX1"},
6913 {"RX INT4 SPLINE MIX", NULL, "RX INT4_1 NATIVE MUX"},
6914 {"RX INT4_1 NATIVE MUX", NULL, "RX INT4 NATIVE SUPPLY"},
6915 {"RX INT4 SEC MIX", NULL, "RX INT4 SPLINE MIX"},
6916 {"RX INT4 MIX2", NULL, "RX INT4 SEC MIX"},
6917 {"RX INT4 MIX2", NULL, "RX INT4 MIX2 INP"},
6918 {"RX INT4 INTERP", NULL, "RX INT4 MIX2"},
6919 {"RX INT4 DAC", NULL, "RX INT4 INTERP"},
6920 {"RX INT4 DAC", NULL, "RX_BIAS"},
6921 {"LINEOUT2 PA", NULL, "RX INT4 DAC"},
6922 {"LINEOUT2", NULL, "LINEOUT2 PA"},
6923
6924 {"SPL SRC2 MUX", "SRC_IN_LO3", "RX INT5_1 MIX1"},
6925 {"RX INT5 SPLINE MIX", NULL, "RX INT5_1 MIX1"},
6926 {"RX INT5 SPLINE MIX", "LO3 Switch", "SPL SRC2 MUX"},
6927 {"RX INT5 SEC MIX", NULL, "RX INT5 SPLINE MIX"},
6928 {"RX INT5 MIX2", NULL, "RX INT5 SEC MIX"},
6929 {"RX INT5 INTERP", NULL, "RX INT5 MIX2"},
6930
6931 {"RX INT5 VBAT", "LO3 VBAT Enable", "RX INT5 INTERP"},
6932 {"RX INT5 DAC", NULL, "RX INT5 VBAT"},
6933
6934 {"RX INT5 DAC", NULL, "RX INT5 INTERP"},
6935 {"RX INT5 DAC", NULL, "RX_BIAS"},
6936 {"LINEOUT3 PA", NULL, "RX INT5 DAC"},
6937 {"LINEOUT3", NULL, "LINEOUT3 PA"},
6938
6939 {"SPL SRC3 MUX", "SRC_IN_LO4", "RX INT6_1 MIX1"},
6940 {"RX INT6 SPLINE MIX", NULL, "RX INT6_1 MIX1"},
6941 {"RX INT6 SPLINE MIX", "LO4 Switch", "SPL SRC3 MUX"},
6942 {"RX INT6 SEC MIX", NULL, "RX INT6 SPLINE MIX"},
6943 {"RX INT6 MIX2", NULL, "RX INT6 SEC MIX"},
6944 {"RX INT6 INTERP", NULL, "RX INT6 MIX2"},
6945
6946 {"RX INT6 VBAT", "LO4 VBAT Enable", "RX INT6 INTERP"},
6947 {"RX INT6 DAC", NULL, "RX INT6 VBAT"},
6948
6949 {"RX INT6 DAC", NULL, "RX INT6 INTERP"},
6950 {"RX INT6 DAC", NULL, "RX_BIAS"},
6951 {"LINEOUT4 PA", NULL, "RX INT6 DAC"},
6952 {"LINEOUT4", NULL, "LINEOUT4 PA"},
6953
6954 {"SPL SRC2 MUX", "SRC_IN_SPKRL", "RX INT7_1 MIX1"},
6955 {"RX INT7 SPLINE MIX", NULL, "RX INT7_1 MIX1"},
6956 {"RX INT7 SPLINE MIX", "SPKRL Switch", "SPL SRC2 MUX"},
6957 {"RX INT7 SEC MIX", NULL, "RX INT7 SPLINE MIX"},
6958 {"RX INT7 MIX2", NULL, "RX INT7 SEC MIX"},
6959 {"RX INT7 MIX2", NULL, "RX INT7 MIX2 INP"},
6960
6961 {"RX INT7 INTERP", NULL, "RX INT7 MIX2"},
6962
6963 {"RX INT7 VBAT", "SPKRL VBAT Enable", "RX INT7 INTERP"},
6964 {"RX INT7 CHAIN", NULL, "RX INT7 VBAT"},
6965
6966 {"RX INT7 CHAIN", NULL, "RX INT7 INTERP"},
6967 {"RX INT7 CHAIN", NULL, "RX_BIAS"},
6968 {"SPK1 OUT", NULL, "RX INT7 CHAIN"},
6969
6970 {"ANC SPKR PA Enable", "Switch", "RX INT7 CHAIN"},
6971 {"ANC SPK1 PA", NULL, "ANC SPKR PA Enable"},
6972 {"SPK1 OUT", NULL, "ANC SPK1 PA"},
6973
6974 {"SPL SRC3 MUX", "SRC_IN_SPKRR", "RX INT8_1 MIX1"},
6975 {"RX INT8 SPLINE MIX", NULL, "RX INT8_1 MIX1"},
6976 {"RX INT8 SPLINE MIX", "SPKRR Switch", "SPL SRC3 MUX"},
6977 {"RX INT8 SEC MIX", NULL, "RX INT8 SPLINE MIX"},
6978 {"RX INT8 INTERP", NULL, "RX INT8 SEC MIX"},
6979
6980 {"RX INT8 VBAT", "SPKRR VBAT Enable", "RX INT8 INTERP"},
6981 {"RX INT8 CHAIN", NULL, "RX INT8 VBAT"},
6982
6983 {"RX INT8 CHAIN", NULL, "RX INT8 INTERP"},
6984 {"RX INT8 CHAIN", NULL, "RX_BIAS"},
6985 {"SPK2 OUT", NULL, "RX INT8 CHAIN"},
6986
6987 {"ANC0 FB MUX", "ANC_IN_EAR", "RX INT0 MIX2"},
6988 {"ANC0 FB MUX", "ANC_IN_HPHL", "RX INT1 MIX2"},
6989 {"ANC0 FB MUX", "ANC_IN_LO1", "RX INT3 MIX2"},
6990 {"ANC0 FB MUX", "ANC_IN_EAR_SPKR", "RX INT7 MIX2"},
6991 {"ANC1 FB MUX", "ANC_IN_HPHR", "RX INT2 MIX2"},
6992 {"ANC1 FB MUX", "ANC_IN_LO2", "RX INT4 MIX2"},
6993
6994 {"ANC HPHL Enable", "Switch", "ADC MUX10"},
6995 {"ANC HPHL Enable", "Switch", "ADC MUX11"},
6996 {"RX INT1 MIX2", NULL, "ANC HPHL Enable"},
6997
6998 {"ANC HPHR Enable", "Switch", "ADC MUX12"},
6999 {"ANC HPHR Enable", "Switch", "ADC MUX13"},
7000 {"RX INT2 MIX2", NULL, "ANC HPHR Enable"},
7001
7002 {"ANC EAR Enable", "Switch", "ADC MUX10"},
7003 {"ANC EAR Enable", "Switch", "ADC MUX11"},
7004 {"RX INT0 MIX2", NULL, "ANC EAR Enable"},
7005
7006 {"ANC OUT EAR SPKR Enable", "Switch", "ADC MUX10"},
7007 {"ANC OUT EAR SPKR Enable", "Switch", "ADC MUX11"},
7008 {"RX INT7 MIX2", NULL, "ANC OUT EAR SPKR Enable"},
7009
7010 {"ANC LINEOUT1 Enable", "Switch", "ADC MUX10"},
7011 {"ANC LINEOUT1 Enable", "Switch", "ADC MUX11"},
7012 {"RX INT3 MIX2", NULL, "ANC LINEOUT1 Enable"},
7013
7014 {"ANC LINEOUT2 Enable", "Switch", "ADC MUX12"},
7015 {"ANC LINEOUT2 Enable", "Switch", "ADC MUX13"},
7016 {"RX INT4 MIX2", NULL, "ANC LINEOUT2 Enable"},
7017
7018 {"ANC EAR PA", NULL, "RX INT0 DAC"},
7019 {"ANC EAR", NULL, "ANC EAR PA"},
7020 {"ANC HPHL PA", NULL, "RX INT1 DAC"},
7021 {"ANC HPHL", NULL, "ANC HPHL PA"},
7022 {"ANC HPHR PA", NULL, "RX INT2 DAC"},
7023 {"ANC HPHR", NULL, "ANC HPHR PA"},
7024 {"ANC LINEOUT1 PA", NULL, "RX INT3 DAC"},
7025 {"ANC LINEOUT1", NULL, "ANC LINEOUT1 PA"},
7026 {"ANC LINEOUT2 PA", NULL, "RX INT4 DAC"},
7027 {"ANC LINEOUT2", NULL, "ANC LINEOUT2 PA"},
7028
7029 /* SLIM_MUX("AIF1_PB", "AIF1 PB"),*/
7030 {"SLIM RX0 MUX", "AIF1_PB", "AIF1 PB"},
7031 {"SLIM RX1 MUX", "AIF1_PB", "AIF1 PB"},
7032 {"SLIM RX2 MUX", "AIF1_PB", "AIF1 PB"},
7033 {"SLIM RX3 MUX", "AIF1_PB", "AIF1 PB"},
7034 {"SLIM RX4 MUX", "AIF1_PB", "AIF1 PB"},
7035 {"SLIM RX5 MUX", "AIF1_PB", "AIF1 PB"},
7036 {"SLIM RX6 MUX", "AIF1_PB", "AIF1 PB"},
7037 {"SLIM RX7 MUX", "AIF1_PB", "AIF1 PB"},
7038 /* SLIM_MUX("AIF2_PB", "AIF2 PB"),*/
7039 {"SLIM RX0 MUX", "AIF2_PB", "AIF2 PB"},
7040 {"SLIM RX1 MUX", "AIF2_PB", "AIF2 PB"},
7041 {"SLIM RX2 MUX", "AIF2_PB", "AIF2 PB"},
7042 {"SLIM RX3 MUX", "AIF2_PB", "AIF2 PB"},
7043 {"SLIM RX4 MUX", "AIF2_PB", "AIF2 PB"},
7044 {"SLIM RX5 MUX", "AIF2_PB", "AIF2 PB"},
7045 {"SLIM RX6 MUX", "AIF2_PB", "AIF2 PB"},
7046 {"SLIM RX7 MUX", "AIF2_PB", "AIF2 PB"},
7047 /* SLIM_MUX("AIF3_PB", "AIF3 PB"),*/
7048 {"SLIM RX0 MUX", "AIF3_PB", "AIF3 PB"},
7049 {"SLIM RX1 MUX", "AIF3_PB", "AIF3 PB"},
7050 {"SLIM RX2 MUX", "AIF3_PB", "AIF3 PB"},
7051 {"SLIM RX3 MUX", "AIF3_PB", "AIF3 PB"},
7052 {"SLIM RX4 MUX", "AIF3_PB", "AIF3 PB"},
7053 {"SLIM RX5 MUX", "AIF3_PB", "AIF3 PB"},
7054 {"SLIM RX6 MUX", "AIF3_PB", "AIF3 PB"},
7055 {"SLIM RX7 MUX", "AIF3_PB", "AIF3 PB"},
7056 /* SLIM_MUX("AIF4_PB", "AIF4 PB"),*/
7057 {"SLIM RX0 MUX", "AIF4_PB", "AIF4 PB"},
7058 {"SLIM RX1 MUX", "AIF4_PB", "AIF4 PB"},
7059 {"SLIM RX2 MUX", "AIF4_PB", "AIF4 PB"},
7060 {"SLIM RX3 MUX", "AIF4_PB", "AIF4 PB"},
7061 {"SLIM RX4 MUX", "AIF4_PB", "AIF4 PB"},
7062 {"SLIM RX5 MUX", "AIF4_PB", "AIF4 PB"},
7063 {"SLIM RX6 MUX", "AIF4_PB", "AIF4 PB"},
7064 {"SLIM RX7 MUX", "AIF4_PB", "AIF4 PB"},
7065
7066 /* SLIM_MUX("AIF_MIX1_PB", "AIF MIX1 PB"),*/
7067 {"SLIM RX0 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"},
7068 {"SLIM RX1 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"},
7069 {"SLIM RX2 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"},
7070 {"SLIM RX3 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"},
7071 {"SLIM RX4 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"},
7072 {"SLIM RX5 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"},
7073 {"SLIM RX6 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"},
7074 {"SLIM RX7 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"},
7075
7076 {"SLIM RX0", NULL, "SLIM RX0 MUX"},
7077 {"SLIM RX1", NULL, "SLIM RX1 MUX"},
7078 {"SLIM RX2", NULL, "SLIM RX2 MUX"},
7079 {"SLIM RX3", NULL, "SLIM RX3 MUX"},
7080 {"SLIM RX4", NULL, "SLIM RX4 MUX"},
7081 {"SLIM RX5", NULL, "SLIM RX5 MUX"},
7082 {"SLIM RX6", NULL, "SLIM RX6 MUX"},
7083 {"SLIM RX7", NULL, "SLIM RX7 MUX"},
7084
7085 {"RX INT0_1 MIX1 INP0", "RX0", "SLIM RX0"},
7086 {"RX INT0_1 MIX1 INP0", "RX1", "SLIM RX1"},
7087 {"RX INT0_1 MIX1 INP0", "RX2", "SLIM RX2"},
7088 {"RX INT0_1 MIX1 INP0", "RX3", "SLIM RX3"},
7089 {"RX INT0_1 MIX1 INP0", "RX4", "SLIM RX4"},
7090 {"RX INT0_1 MIX1 INP0", "RX5", "SLIM RX5"},
7091 {"RX INT0_1 MIX1 INP0", "RX6", "SLIM RX6"},
7092 {"RX INT0_1 MIX1 INP0", "RX7", "SLIM RX7"},
7093 {"RX INT0_1 MIX1 INP0", "IIR0", "IIR0"},
7094 {"RX INT0_1 MIX1 INP0", "IIR1", "IIR1"},
7095 {"RX INT0_1 MIX1 INP1", "RX0", "SLIM RX0"},
7096 {"RX INT0_1 MIX1 INP1", "RX1", "SLIM RX1"},
7097 {"RX INT0_1 MIX1 INP1", "RX2", "SLIM RX2"},
7098 {"RX INT0_1 MIX1 INP1", "RX3", "SLIM RX3"},
7099 {"RX INT0_1 MIX1 INP1", "RX4", "SLIM RX4"},
7100 {"RX INT0_1 MIX1 INP1", "RX5", "SLIM RX5"},
7101 {"RX INT0_1 MIX1 INP1", "RX6", "SLIM RX6"},
7102 {"RX INT0_1 MIX1 INP1", "RX7", "SLIM RX7"},
7103 {"RX INT0_1 MIX1 INP1", "IIR0", "IIR0"},
7104 {"RX INT0_1 MIX1 INP1", "IIR1", "IIR1"},
7105 {"RX INT0_1 MIX1 INP2", "RX0", "SLIM RX0"},
7106 {"RX INT0_1 MIX1 INP2", "RX1", "SLIM RX1"},
7107 {"RX INT0_1 MIX1 INP2", "RX2", "SLIM RX2"},
7108 {"RX INT0_1 MIX1 INP2", "RX3", "SLIM RX3"},
7109 {"RX INT0_1 MIX1 INP2", "RX4", "SLIM RX4"},
7110 {"RX INT0_1 MIX1 INP2", "RX5", "SLIM RX5"},
7111 {"RX INT0_1 MIX1 INP2", "RX6", "SLIM RX6"},
7112 {"RX INT0_1 MIX1 INP2", "RX7", "SLIM RX7"},
7113 {"RX INT0_1 MIX1 INP2", "IIR0", "IIR0"},
7114 {"RX INT0_1 MIX1 INP2", "IIR1", "IIR1"},
7115
7116 /* MIXing path INT0 */
7117 {"RX INT0_2 MUX", "RX0", "SLIM RX0"},
7118 {"RX INT0_2 MUX", "RX1", "SLIM RX1"},
7119 {"RX INT0_2 MUX", "RX2", "SLIM RX2"},
7120 {"RX INT0_2 MUX", "RX3", "SLIM RX3"},
7121 {"RX INT0_2 MUX", "RX4", "SLIM RX4"},
7122 {"RX INT0_2 MUX", "RX5", "SLIM RX5"},
7123 {"RX INT0_2 MUX", "RX6", "SLIM RX6"},
7124 {"RX INT0_2 MUX", "RX7", "SLIM RX7"},
7125 {"RX INT0 SEC MIX", NULL, "RX INT0_2 MUX"},
7126
7127 /* MIXing path INT1 */
7128 {"RX INT1_2 MUX", "RX0", "SLIM RX0"},
7129 {"RX INT1_2 MUX", "RX1", "SLIM RX1"},
7130 {"RX INT1_2 MUX", "RX2", "SLIM RX2"},
7131 {"RX INT1_2 MUX", "RX3", "SLIM RX3"},
7132 {"RX INT1_2 MUX", "RX4", "SLIM RX4"},
7133 {"RX INT1_2 MUX", "RX5", "SLIM RX5"},
7134 {"RX INT1_2 MUX", "RX6", "SLIM RX6"},
7135 {"RX INT1_2 MUX", "RX7", "SLIM RX7"},
7136 {"RX INT1 SEC MIX", NULL, "RX INT1_2 MUX"},
7137
7138 /* MIXing path INT2 */
7139 {"RX INT2_2 MUX", "RX0", "SLIM RX0"},
7140 {"RX INT2_2 MUX", "RX1", "SLIM RX1"},
7141 {"RX INT2_2 MUX", "RX2", "SLIM RX2"},
7142 {"RX INT2_2 MUX", "RX3", "SLIM RX3"},
7143 {"RX INT2_2 MUX", "RX4", "SLIM RX4"},
7144 {"RX INT2_2 MUX", "RX5", "SLIM RX5"},
7145 {"RX INT2_2 MUX", "RX6", "SLIM RX6"},
7146 {"RX INT2_2 MUX", "RX7", "SLIM RX7"},
7147 {"RX INT2 SEC MIX", NULL, "RX INT2_2 MUX"},
7148
7149 /* MIXing path INT3 */
7150 {"RX INT3_2 MUX", "RX0", "SLIM RX0"},
7151 {"RX INT3_2 MUX", "RX1", "SLIM RX1"},
7152 {"RX INT3_2 MUX", "RX2", "SLIM RX2"},
7153 {"RX INT3_2 MUX", "RX3", "SLIM RX3"},
7154 {"RX INT3_2 MUX", "RX4", "SLIM RX4"},
7155 {"RX INT3_2 MUX", "RX5", "SLIM RX5"},
7156 {"RX INT3_2 MUX", "RX6", "SLIM RX6"},
7157 {"RX INT3_2 MUX", "RX7", "SLIM RX7"},
7158 {"RX INT3 SEC MIX", NULL, "RX INT3_2 MUX"},
7159
7160 /* MIXing path INT4 */
7161 {"RX INT4_2 MUX", "RX0", "SLIM RX0"},
7162 {"RX INT4_2 MUX", "RX1", "SLIM RX1"},
7163 {"RX INT4_2 MUX", "RX2", "SLIM RX2"},
7164 {"RX INT4_2 MUX", "RX3", "SLIM RX3"},
7165 {"RX INT4_2 MUX", "RX4", "SLIM RX4"},
7166 {"RX INT4_2 MUX", "RX5", "SLIM RX5"},
7167 {"RX INT4_2 MUX", "RX6", "SLIM RX6"},
7168 {"RX INT4_2 MUX", "RX7", "SLIM RX7"},
7169 {"RX INT4 SEC MIX", NULL, "RX INT4_2 MUX"},
7170
7171 /* MIXing path INT5 */
7172 {"RX INT5_2 MUX", "RX0", "SLIM RX0"},
7173 {"RX INT5_2 MUX", "RX1", "SLIM RX1"},
7174 {"RX INT5_2 MUX", "RX2", "SLIM RX2"},
7175 {"RX INT5_2 MUX", "RX3", "SLIM RX3"},
7176 {"RX INT5_2 MUX", "RX4", "SLIM RX4"},
7177 {"RX INT5_2 MUX", "RX5", "SLIM RX5"},
7178 {"RX INT5_2 MUX", "RX6", "SLIM RX6"},
7179 {"RX INT5_2 MUX", "RX7", "SLIM RX7"},
7180 {"RX INT5 SEC MIX", NULL, "RX INT5_2 MUX"},
7181
7182 /* MIXing path INT6 */
7183 {"RX INT6_2 MUX", "RX0", "SLIM RX0"},
7184 {"RX INT6_2 MUX", "RX1", "SLIM RX1"},
7185 {"RX INT6_2 MUX", "RX2", "SLIM RX2"},
7186 {"RX INT6_2 MUX", "RX3", "SLIM RX3"},
7187 {"RX INT6_2 MUX", "RX4", "SLIM RX4"},
7188 {"RX INT6_2 MUX", "RX5", "SLIM RX5"},
7189 {"RX INT6_2 MUX", "RX6", "SLIM RX6"},
7190 {"RX INT6_2 MUX", "RX7", "SLIM RX7"},
7191 {"RX INT6 SEC MIX", NULL, "RX INT6_2 MUX"},
7192
7193 /* MIXing path INT7 */
7194 {"RX INT7_2 MUX", "RX0", "SLIM RX0"},
7195 {"RX INT7_2 MUX", "RX1", "SLIM RX1"},
7196 {"RX INT7_2 MUX", "RX2", "SLIM RX2"},
7197 {"RX INT7_2 MUX", "RX3", "SLIM RX3"},
7198 {"RX INT7_2 MUX", "RX4", "SLIM RX4"},
7199 {"RX INT7_2 MUX", "RX5", "SLIM RX5"},
7200 {"RX INT7_2 MUX", "RX6", "SLIM RX6"},
7201 {"RX INT7_2 MUX", "RX7", "SLIM RX7"},
7202 {"RX INT7 SEC MIX", NULL, "RX INT7_2 MUX"},
7203
7204 /* MIXing path INT8 */
7205 {"RX INT8_2 MUX", "RX0", "SLIM RX0"},
7206 {"RX INT8_2 MUX", "RX1", "SLIM RX1"},
7207 {"RX INT8_2 MUX", "RX2", "SLIM RX2"},
7208 {"RX INT8_2 MUX", "RX3", "SLIM RX3"},
7209 {"RX INT8_2 MUX", "RX4", "SLIM RX4"},
7210 {"RX INT8_2 MUX", "RX5", "SLIM RX5"},
7211 {"RX INT8_2 MUX", "RX6", "SLIM RX6"},
7212 {"RX INT8_2 MUX", "RX7", "SLIM RX7"},
7213 {"RX INT8 SEC MIX", NULL, "RX INT8_2 MUX"},
7214
7215 {"RX INT1_1 MIX1 INP0", "RX0", "SLIM RX0"},
7216 {"RX INT1_1 MIX1 INP0", "RX1", "SLIM RX1"},
7217 {"RX INT1_1 MIX1 INP0", "RX2", "SLIM RX2"},
7218 {"RX INT1_1 MIX1 INP0", "RX3", "SLIM RX3"},
7219 {"RX INT1_1 MIX1 INP0", "RX4", "SLIM RX4"},
7220 {"RX INT1_1 MIX1 INP0", "RX5", "SLIM RX5"},
7221 {"RX INT1_1 MIX1 INP0", "RX6", "SLIM RX6"},
7222 {"RX INT1_1 MIX1 INP0", "RX7", "SLIM RX7"},
7223 {"RX INT1_1 MIX1 INP0", "IIR0", "IIR0"},
7224 {"RX INT1_1 MIX1 INP0", "IIR1", "IIR1"},
7225 {"RX INT1_1 MIX1 INP1", "RX0", "SLIM RX0"},
7226 {"RX INT1_1 MIX1 INP1", "RX1", "SLIM RX1"},
7227 {"RX INT1_1 MIX1 INP1", "RX2", "SLIM RX2"},
7228 {"RX INT1_1 MIX1 INP1", "RX3", "SLIM RX3"},
7229 {"RX INT1_1 MIX1 INP1", "RX4", "SLIM RX4"},
7230 {"RX INT1_1 MIX1 INP1", "RX5", "SLIM RX5"},
7231 {"RX INT1_1 MIX1 INP1", "RX6", "SLIM RX6"},
7232 {"RX INT1_1 MIX1 INP1", "RX7", "SLIM RX7"},
7233 {"RX INT1_1 MIX1 INP1", "IIR0", "IIR0"},
7234 {"RX INT1_1 MIX1 INP1", "IIR1", "IIR1"},
7235 {"RX INT1_1 MIX1 INP2", "RX0", "SLIM RX0"},
7236 {"RX INT1_1 MIX1 INP2", "RX1", "SLIM RX1"},
7237 {"RX INT1_1 MIX1 INP2", "RX2", "SLIM RX2"},
7238 {"RX INT1_1 MIX1 INP2", "RX3", "SLIM RX3"},
7239 {"RX INT1_1 MIX1 INP2", "RX4", "SLIM RX4"},
7240 {"RX INT1_1 MIX1 INP2", "RX5", "SLIM RX5"},
7241 {"RX INT1_1 MIX1 INP2", "RX6", "SLIM RX6"},
7242 {"RX INT1_1 MIX1 INP2", "RX7", "SLIM RX7"},
7243 {"RX INT1_1 MIX1 INP2", "IIR0", "IIR0"},
7244 {"RX INT1_1 MIX1 INP2", "IIR1", "IIR1"},
7245 {"RX INT2_1 MIX1 INP0", "RX0", "SLIM RX0"},
7246 {"RX INT2_1 MIX1 INP0", "RX1", "SLIM RX1"},
7247 {"RX INT2_1 MIX1 INP0", "RX2", "SLIM RX2"},
7248 {"RX INT2_1 MIX1 INP0", "RX3", "SLIM RX3"},
7249 {"RX INT2_1 MIX1 INP0", "RX4", "SLIM RX4"},
7250 {"RX INT2_1 MIX1 INP0", "RX5", "SLIM RX5"},
7251 {"RX INT2_1 MIX1 INP0", "RX6", "SLIM RX6"},
7252 {"RX INT2_1 MIX1 INP0", "RX7", "SLIM RX7"},
7253 {"RX INT2_1 MIX1 INP0", "IIR0", "IIR0"},
7254 {"RX INT2_1 MIX1 INP0", "IIR1", "IIR1"},
7255 {"RX INT2_1 MIX1 INP1", "RX0", "SLIM RX0"},
7256 {"RX INT2_1 MIX1 INP1", "RX1", "SLIM RX1"},
7257 {"RX INT2_1 MIX1 INP1", "RX2", "SLIM RX2"},
7258 {"RX INT2_1 MIX1 INP1", "RX3", "SLIM RX3"},
7259 {"RX INT2_1 MIX1 INP1", "RX4", "SLIM RX4"},
7260 {"RX INT2_1 MIX1 INP1", "RX5", "SLIM RX5"},
7261 {"RX INT2_1 MIX1 INP1", "RX6", "SLIM RX6"},
7262 {"RX INT2_1 MIX1 INP1", "RX7", "SLIM RX7"},
7263 {"RX INT2_1 MIX1 INP1", "IIR0", "IIR0"},
7264 {"RX INT2_1 MIX1 INP1", "IIR1", "IIR1"},
7265 {"RX INT2_1 MIX1 INP2", "RX0", "SLIM RX0"},
7266 {"RX INT2_1 MIX1 INP2", "RX1", "SLIM RX1"},
7267 {"RX INT2_1 MIX1 INP2", "RX2", "SLIM RX2"},
7268 {"RX INT2_1 MIX1 INP2", "RX3", "SLIM RX3"},
7269 {"RX INT2_1 MIX1 INP2", "RX4", "SLIM RX4"},
7270 {"RX INT2_1 MIX1 INP2", "RX5", "SLIM RX5"},
7271 {"RX INT2_1 MIX1 INP2", "RX6", "SLIM RX6"},
7272 {"RX INT2_1 MIX1 INP2", "RX7", "SLIM RX7"},
7273 {"RX INT2_1 MIX1 INP2", "IIR0", "IIR0"},
7274 {"RX INT2_1 MIX1 INP2", "IIR1", "IIR1"},
7275
7276 {"RX INT3_1 MIX1 INP0", "RX0", "SLIM RX0"},
7277 {"RX INT3_1 MIX1 INP0", "RX1", "SLIM RX1"},
7278 {"RX INT3_1 MIX1 INP0", "RX2", "SLIM RX2"},
7279 {"RX INT3_1 MIX1 INP0", "RX3", "SLIM RX3"},
7280 {"RX INT3_1 MIX1 INP0", "RX4", "SLIM RX4"},
7281 {"RX INT3_1 MIX1 INP0", "RX5", "SLIM RX5"},
7282 {"RX INT3_1 MIX1 INP0", "RX6", "SLIM RX6"},
7283 {"RX INT3_1 MIX1 INP0", "RX7", "SLIM RX7"},
7284 {"RX INT3_1 MIX1 INP0", "IIR0", "IIR0"},
7285 {"RX INT3_1 MIX1 INP0", "IIR1", "IIR1"},
7286 {"RX INT3_1 MIX1 INP1", "RX0", "SLIM RX0"},
7287 {"RX INT3_1 MIX1 INP1", "RX1", "SLIM RX1"},
7288 {"RX INT3_1 MIX1 INP1", "RX2", "SLIM RX2"},
7289 {"RX INT3_1 MIX1 INP1", "RX3", "SLIM RX3"},
7290 {"RX INT3_1 MIX1 INP1", "RX4", "SLIM RX4"},
7291 {"RX INT3_1 MIX1 INP1", "RX5", "SLIM RX5"},
7292 {"RX INT3_1 MIX1 INP1", "RX6", "SLIM RX6"},
7293 {"RX INT3_1 MIX1 INP1", "RX7", "SLIM RX7"},
7294 {"RX INT3_1 MIX1 INP1", "IIR0", "IIR0"},
7295 {"RX INT3_1 MIX1 INP1", "IIR1", "IIR1"},
7296 {"RX INT3_1 MIX1 INP2", "RX0", "SLIM RX0"},
7297 {"RX INT3_1 MIX1 INP2", "RX1", "SLIM RX1"},
7298 {"RX INT3_1 MIX1 INP2", "RX2", "SLIM RX2"},
7299 {"RX INT3_1 MIX1 INP2", "RX3", "SLIM RX3"},
7300 {"RX INT3_1 MIX1 INP2", "RX4", "SLIM RX4"},
7301 {"RX INT3_1 MIX1 INP2", "RX5", "SLIM RX5"},
7302 {"RX INT3_1 MIX1 INP2", "RX6", "SLIM RX6"},
7303 {"RX INT3_1 MIX1 INP2", "RX7", "SLIM RX7"},
7304 {"RX INT3_1 MIX1 INP2", "IIR0", "IIR0"},
7305 {"RX INT3_1 MIX1 INP2", "IIR1", "IIR1"},
7306
7307 {"RX INT4_1 MIX1 INP0", "RX0", "SLIM RX0"},
7308 {"RX INT4_1 MIX1 INP0", "RX1", "SLIM RX1"},
7309 {"RX INT4_1 MIX1 INP0", "RX2", "SLIM RX2"},
7310 {"RX INT4_1 MIX1 INP0", "RX3", "SLIM RX3"},
7311 {"RX INT4_1 MIX1 INP0", "RX4", "SLIM RX4"},
7312 {"RX INT4_1 MIX1 INP0", "RX5", "SLIM RX5"},
7313 {"RX INT4_1 MIX1 INP0", "RX6", "SLIM RX6"},
7314 {"RX INT4_1 MIX1 INP0", "RX7", "SLIM RX7"},
7315 {"RX INT4_1 MIX1 INP0", "IIR0", "IIR0"},
7316 {"RX INT4_1 MIX1 INP0", "IIR1", "IIR1"},
7317 {"RX INT4_1 MIX1 INP1", "RX0", "SLIM RX0"},
7318 {"RX INT4_1 MIX1 INP1", "RX1", "SLIM RX1"},
7319 {"RX INT4_1 MIX1 INP1", "RX2", "SLIM RX2"},
7320 {"RX INT4_1 MIX1 INP1", "RX3", "SLIM RX3"},
7321 {"RX INT4_1 MIX1 INP1", "RX4", "SLIM RX4"},
7322 {"RX INT4_1 MIX1 INP1", "RX5", "SLIM RX5"},
7323 {"RX INT4_1 MIX1 INP1", "RX6", "SLIM RX6"},
7324 {"RX INT4_1 MIX1 INP1", "RX7", "SLIM RX7"},
7325 {"RX INT4_1 MIX1 INP1", "IIR0", "IIR0"},
7326 {"RX INT4_1 MIX1 INP1", "IIR1", "IIR1"},
7327 {"RX INT4_1 MIX1 INP2", "RX0", "SLIM RX0"},
7328 {"RX INT4_1 MIX1 INP2", "RX1", "SLIM RX1"},
7329 {"RX INT4_1 MIX1 INP2", "RX2", "SLIM RX2"},
7330 {"RX INT4_1 MIX1 INP2", "RX3", "SLIM RX3"},
7331 {"RX INT4_1 MIX1 INP2", "RX4", "SLIM RX4"},
7332 {"RX INT4_1 MIX1 INP2", "RX5", "SLIM RX5"},
7333 {"RX INT4_1 MIX1 INP2", "RX6", "SLIM RX6"},
7334 {"RX INT4_1 MIX1 INP2", "RX7", "SLIM RX7"},
7335 {"RX INT4_1 MIX1 INP2", "IIR0", "IIR0"},
7336 {"RX INT4_1 MIX1 INP2", "IIR1", "IIR1"},
7337
7338 {"RX INT5_1 MIX1 INP0", "RX0", "SLIM RX0"},
7339 {"RX INT5_1 MIX1 INP0", "RX1", "SLIM RX1"},
7340 {"RX INT5_1 MIX1 INP0", "RX2", "SLIM RX2"},
7341 {"RX INT5_1 MIX1 INP0", "RX3", "SLIM RX3"},
7342 {"RX INT5_1 MIX1 INP0", "RX4", "SLIM RX4"},
7343 {"RX INT5_1 MIX1 INP0", "RX5", "SLIM RX5"},
7344 {"RX INT5_1 MIX1 INP0", "RX6", "SLIM RX6"},
7345 {"RX INT5_1 MIX1 INP0", "RX7", "SLIM RX7"},
7346 {"RX INT5_1 MIX1 INP0", "IIR0", "IIR0"},
7347 {"RX INT5_1 MIX1 INP0", "IIR1", "IIR1"},
7348 {"RX INT5_1 MIX1 INP1", "RX0", "SLIM RX0"},
7349 {"RX INT5_1 MIX1 INP1", "RX1", "SLIM RX1"},
7350 {"RX INT5_1 MIX1 INP1", "RX2", "SLIM RX2"},
7351 {"RX INT5_1 MIX1 INP1", "RX3", "SLIM RX3"},
7352 {"RX INT5_1 MIX1 INP1", "RX4", "SLIM RX4"},
7353 {"RX INT5_1 MIX1 INP1", "RX5", "SLIM RX5"},
7354 {"RX INT5_1 MIX1 INP1", "RX6", "SLIM RX6"},
7355 {"RX INT5_1 MIX1 INP1", "RX7", "SLIM RX7"},
7356 {"RX INT5_1 MIX1 INP1", "IIR0", "IIR0"},
7357 {"RX INT5_1 MIX1 INP1", "IIR1", "IIR1"},
7358 {"RX INT5_1 MIX1 INP2", "RX0", "SLIM RX0"},
7359 {"RX INT5_1 MIX1 INP2", "RX1", "SLIM RX1"},
7360 {"RX INT5_1 MIX1 INP2", "RX2", "SLIM RX2"},
7361 {"RX INT5_1 MIX1 INP2", "RX3", "SLIM RX3"},
7362 {"RX INT5_1 MIX1 INP2", "RX4", "SLIM RX4"},
7363 {"RX INT5_1 MIX1 INP2", "RX5", "SLIM RX5"},
7364 {"RX INT5_1 MIX1 INP2", "RX6", "SLIM RX6"},
7365 {"RX INT5_1 MIX1 INP2", "RX7", "SLIM RX7"},
7366 {"RX INT5_1 MIX1 INP2", "IIR0", "IIR0"},
7367 {"RX INT5_1 MIX1 INP2", "IIR1", "IIR1"},
7368
7369 {"RX INT6_1 MIX1 INP0", "RX0", "SLIM RX0"},
7370 {"RX INT6_1 MIX1 INP0", "RX1", "SLIM RX1"},
7371 {"RX INT6_1 MIX1 INP0", "RX2", "SLIM RX2"},
7372 {"RX INT6_1 MIX1 INP0", "RX3", "SLIM RX3"},
7373 {"RX INT6_1 MIX1 INP0", "RX4", "SLIM RX4"},
7374 {"RX INT6_1 MIX1 INP0", "RX5", "SLIM RX5"},
7375 {"RX INT6_1 MIX1 INP0", "RX6", "SLIM RX6"},
7376 {"RX INT6_1 MIX1 INP0", "RX7", "SLIM RX7"},
7377 {"RX INT6_1 MIX1 INP0", "IIR0", "IIR0"},
7378 {"RX INT6_1 MIX1 INP0", "IIR1", "IIR1"},
7379 {"RX INT6_1 MIX1 INP1", "RX0", "SLIM RX0"},
7380 {"RX INT6_1 MIX1 INP1", "RX1", "SLIM RX1"},
7381 {"RX INT6_1 MIX1 INP1", "RX2", "SLIM RX2"},
7382 {"RX INT6_1 MIX1 INP1", "RX3", "SLIM RX3"},
7383 {"RX INT6_1 MIX1 INP1", "RX4", "SLIM RX4"},
7384 {"RX INT6_1 MIX1 INP1", "RX5", "SLIM RX5"},
7385 {"RX INT6_1 MIX1 INP1", "RX6", "SLIM RX6"},
7386 {"RX INT6_1 MIX1 INP1", "RX7", "SLIM RX7"},
7387 {"RX INT6_1 MIX1 INP1", "IIR0", "IIR0"},
7388 {"RX INT6_1 MIX1 INP1", "IIR1", "IIR1"},
7389 {"RX INT6_1 MIX1 INP2", "RX0", "SLIM RX0"},
7390 {"RX INT6_1 MIX1 INP2", "RX1", "SLIM RX1"},
7391 {"RX INT6_1 MIX1 INP2", "RX2", "SLIM RX2"},
7392 {"RX INT6_1 MIX1 INP2", "RX3", "SLIM RX3"},
7393 {"RX INT6_1 MIX1 INP2", "RX4", "SLIM RX4"},
7394 {"RX INT6_1 MIX1 INP2", "RX5", "SLIM RX5"},
7395 {"RX INT6_1 MIX1 INP2", "RX6", "SLIM RX6"},
7396 {"RX INT6_1 MIX1 INP2", "RX7", "SLIM RX7"},
7397 {"RX INT6_1 MIX1 INP2", "IIR0", "IIR0"},
7398 {"RX INT6_1 MIX1 INP2", "IIR1", "IIR1"},
7399
7400 {"RX INT7_1 MIX1 INP0", "RX0", "SLIM RX0"},
7401 {"RX INT7_1 MIX1 INP0", "RX1", "SLIM RX1"},
7402 {"RX INT7_1 MIX1 INP0", "RX2", "SLIM RX2"},
7403 {"RX INT7_1 MIX1 INP0", "RX3", "SLIM RX3"},
7404 {"RX INT7_1 MIX1 INP0", "RX4", "SLIM RX4"},
7405 {"RX INT7_1 MIX1 INP0", "RX5", "SLIM RX5"},
7406 {"RX INT7_1 MIX1 INP0", "RX6", "SLIM RX6"},
7407 {"RX INT7_1 MIX1 INP0", "RX7", "SLIM RX7"},
7408 {"RX INT7_1 MIX1 INP0", "IIR0", "IIR0"},
7409 {"RX INT7_1 MIX1 INP0", "IIR1", "IIR1"},
7410 {"RX INT7_1 MIX1 INP1", "RX0", "SLIM RX0"},
7411 {"RX INT7_1 MIX1 INP1", "RX1", "SLIM RX1"},
7412 {"RX INT7_1 MIX1 INP1", "RX2", "SLIM RX2"},
7413 {"RX INT7_1 MIX1 INP1", "RX3", "SLIM RX3"},
7414 {"RX INT7_1 MIX1 INP1", "RX4", "SLIM RX4"},
7415 {"RX INT7_1 MIX1 INP1", "RX5", "SLIM RX5"},
7416 {"RX INT7_1 MIX1 INP1", "RX6", "SLIM RX6"},
7417 {"RX INT7_1 MIX1 INP1", "RX7", "SLIM RX7"},
7418 {"RX INT7_1 MIX1 INP1", "IIR0", "IIR0"},
7419 {"RX INT7_1 MIX1 INP1", "IIR1", "IIR1"},
7420 {"RX INT7_1 MIX1 INP2", "RX0", "SLIM RX0"},
7421 {"RX INT7_1 MIX1 INP2", "RX1", "SLIM RX1"},
7422 {"RX INT7_1 MIX1 INP2", "RX2", "SLIM RX2"},
7423 {"RX INT7_1 MIX1 INP2", "RX3", "SLIM RX3"},
7424 {"RX INT7_1 MIX1 INP2", "RX4", "SLIM RX4"},
7425 {"RX INT7_1 MIX1 INP2", "RX5", "SLIM RX5"},
7426 {"RX INT7_1 MIX1 INP2", "RX6", "SLIM RX6"},
7427 {"RX INT7_1 MIX1 INP2", "RX7", "SLIM RX7"},
7428 {"RX INT7_1 MIX1 INP2", "IIR0", "IIR0"},
7429 {"RX INT7_1 MIX1 INP2", "IIR1", "IIR1"},
7430
7431 {"RX INT8_1 MIX1 INP0", "RX0", "SLIM RX0"},
7432 {"RX INT8_1 MIX1 INP0", "RX1", "SLIM RX1"},
7433 {"RX INT8_1 MIX1 INP0", "RX2", "SLIM RX2"},
7434 {"RX INT8_1 MIX1 INP0", "RX3", "SLIM RX3"},
7435 {"RX INT8_1 MIX1 INP0", "RX4", "SLIM RX4"},
7436 {"RX INT8_1 MIX1 INP0", "RX5", "SLIM RX5"},
7437 {"RX INT8_1 MIX1 INP0", "RX6", "SLIM RX6"},
7438 {"RX INT8_1 MIX1 INP0", "RX7", "SLIM RX7"},
7439 {"RX INT8_1 MIX1 INP0", "IIR0", "IIR0"},
7440 {"RX INT8_1 MIX1 INP0", "IIR1", "IIR1"},
7441 {"RX INT8_1 MIX1 INP1", "RX0", "SLIM RX0"},
7442 {"RX INT8_1 MIX1 INP1", "RX1", "SLIM RX1"},
7443 {"RX INT8_1 MIX1 INP1", "RX2", "SLIM RX2"},
7444 {"RX INT8_1 MIX1 INP1", "RX3", "SLIM RX3"},
7445 {"RX INT8_1 MIX1 INP1", "RX4", "SLIM RX4"},
7446 {"RX INT8_1 MIX1 INP1", "RX5", "SLIM RX5"},
7447 {"RX INT8_1 MIX1 INP1", "RX6", "SLIM RX6"},
7448 {"RX INT8_1 MIX1 INP1", "RX7", "SLIM RX7"},
7449 {"RX INT8_1 MIX1 INP1", "IIR0", "IIR0"},
7450 {"RX INT8_1 MIX1 INP1", "IIR1", "IIR1"},
7451 {"RX INT8_1 MIX1 INP2", "RX0", "SLIM RX0"},
7452 {"RX INT8_1 MIX1 INP2", "RX1", "SLIM RX1"},
7453 {"RX INT8_1 MIX1 INP2", "RX2", "SLIM RX2"},
7454 {"RX INT8_1 MIX1 INP2", "RX3", "SLIM RX3"},
7455 {"RX INT8_1 MIX1 INP2", "RX4", "SLIM RX4"},
7456 {"RX INT8_1 MIX1 INP2", "RX5", "SLIM RX5"},
7457 {"RX INT8_1 MIX1 INP2", "RX6", "SLIM RX6"},
7458 {"RX INT8_1 MIX1 INP2", "RX7", "SLIM RX7"},
7459 {"RX INT8_1 MIX1 INP2", "IIR0", "IIR0"},
7460 {"RX INT8_1 MIX1 INP2", "IIR1", "IIR1"},
7461
7462 /* SRC0, SRC1 inputs to Sidetone RX Mixer
7463 * on RX0, RX1, RX2, RX3, RX4 and RX7 chains
7464 */
7465 {"IIR0", NULL, "IIR0 INP0 MUX"},
7466 {"IIR0 INP0 MUX", "DEC0", "ADC MUX0"},
7467 {"IIR0 INP0 MUX", "DEC1", "ADC MUX1"},
7468 {"IIR0 INP0 MUX", "DEC2", "ADC MUX2"},
7469 {"IIR0 INP0 MUX", "DEC3", "ADC MUX3"},
7470 {"IIR0 INP0 MUX", "DEC4", "ADC MUX4"},
7471 {"IIR0 INP0 MUX", "DEC5", "ADC MUX5"},
7472 {"IIR0 INP0 MUX", "DEC6", "ADC MUX6"},
7473 {"IIR0 INP0 MUX", "DEC7", "ADC MUX7"},
7474 {"IIR0 INP0 MUX", "DEC8", "ADC MUX8"},
7475 {"IIR0 INP0 MUX", "RX0", "SLIM RX0"},
7476 {"IIR0 INP0 MUX", "RX1", "SLIM RX1"},
7477 {"IIR0 INP0 MUX", "RX2", "SLIM RX2"},
7478 {"IIR0 INP0 MUX", "RX3", "SLIM RX3"},
7479 {"IIR0 INP0 MUX", "RX4", "SLIM RX4"},
7480 {"IIR0 INP0 MUX", "RX5", "SLIM RX5"},
7481 {"IIR0 INP0 MUX", "RX6", "SLIM RX6"},
7482 {"IIR0 INP0 MUX", "RX7", "SLIM RX7"},
7483 {"IIR0", NULL, "IIR0 INP1 MUX"},
7484 {"IIR0 INP1 MUX", "DEC0", "ADC MUX0"},
7485 {"IIR0 INP1 MUX", "DEC1", "ADC MUX1"},
7486 {"IIR0 INP1 MUX", "DEC2", "ADC MUX2"},
7487 {"IIR0 INP1 MUX", "DEC3", "ADC MUX3"},
7488 {"IIR0 INP1 MUX", "DEC4", "ADC MUX4"},
7489 {"IIR0 INP1 MUX", "DEC5", "ADC MUX5"},
7490 {"IIR0 INP1 MUX", "DEC6", "ADC MUX6"},
7491 {"IIR0 INP1 MUX", "DEC7", "ADC MUX7"},
7492 {"IIR0 INP1 MUX", "DEC8", "ADC MUX8"},
7493 {"IIR0 INP1 MUX", "RX0", "SLIM RX0"},
7494 {"IIR0 INP1 MUX", "RX1", "SLIM RX1"},
7495 {"IIR0 INP1 MUX", "RX2", "SLIM RX2"},
7496 {"IIR0 INP1 MUX", "RX3", "SLIM RX3"},
7497 {"IIR0 INP1 MUX", "RX4", "SLIM RX4"},
7498 {"IIR0 INP1 MUX", "RX5", "SLIM RX5"},
7499 {"IIR0 INP1 MUX", "RX6", "SLIM RX6"},
7500 {"IIR0 INP1 MUX", "RX7", "SLIM RX7"},
7501 {"IIR0", NULL, "IIR0 INP2 MUX"},
7502 {"IIR0 INP2 MUX", "DEC0", "ADC MUX0"},
7503 {"IIR0 INP2 MUX", "DEC1", "ADC MUX1"},
7504 {"IIR0 INP2 MUX", "DEC2", "ADC MUX2"},
7505 {"IIR0 INP2 MUX", "DEC3", "ADC MUX3"},
7506 {"IIR0 INP2 MUX", "DEC4", "ADC MUX4"},
7507 {"IIR0 INP2 MUX", "DEC5", "ADC MUX5"},
7508 {"IIR0 INP2 MUX", "DEC6", "ADC MUX6"},
7509 {"IIR0 INP2 MUX", "DEC7", "ADC MUX7"},
7510 {"IIR0 INP2 MUX", "DEC8", "ADC MUX8"},
7511 {"IIR0 INP2 MUX", "RX0", "SLIM RX0"},
7512 {"IIR0 INP2 MUX", "RX1", "SLIM RX1"},
7513 {"IIR0 INP2 MUX", "RX2", "SLIM RX2"},
7514 {"IIR0 INP2 MUX", "RX3", "SLIM RX3"},
7515 {"IIR0 INP2 MUX", "RX4", "SLIM RX4"},
7516 {"IIR0 INP2 MUX", "RX5", "SLIM RX5"},
7517 {"IIR0 INP2 MUX", "RX6", "SLIM RX6"},
7518 {"IIR0 INP2 MUX", "RX7", "SLIM RX7"},
7519 {"IIR0", NULL, "IIR0 INP3 MUX"},
7520 {"IIR0 INP3 MUX", "DEC0", "ADC MUX0"},
7521 {"IIR0 INP3 MUX", "DEC1", "ADC MUX1"},
7522 {"IIR0 INP3 MUX", "DEC2", "ADC MUX2"},
7523 {"IIR0 INP3 MUX", "DEC3", "ADC MUX3"},
7524 {"IIR0 INP3 MUX", "DEC4", "ADC MUX4"},
7525 {"IIR0 INP3 MUX", "DEC5", "ADC MUX5"},
7526 {"IIR0 INP3 MUX", "DEC6", "ADC MUX6"},
7527 {"IIR0 INP3 MUX", "DEC7", "ADC MUX7"},
7528 {"IIR0 INP3 MUX", "DEC8", "ADC MUX8"},
7529 {"IIR0 INP3 MUX", "RX0", "SLIM RX0"},
7530 {"IIR0 INP3 MUX", "RX1", "SLIM RX1"},
7531 {"IIR0 INP3 MUX", "RX2", "SLIM RX2"},
7532 {"IIR0 INP3 MUX", "RX3", "SLIM RX3"},
7533 {"IIR0 INP3 MUX", "RX4", "SLIM RX4"},
7534 {"IIR0 INP3 MUX", "RX5", "SLIM RX5"},
7535 {"IIR0 INP3 MUX", "RX6", "SLIM RX6"},
7536 {"IIR0 INP3 MUX", "RX7", "SLIM RX7"},
7537
7538 {"IIR1", NULL, "IIR1 INP0 MUX"},
7539 {"IIR1 INP0 MUX", "DEC0", "ADC MUX0"},
7540 {"IIR1 INP0 MUX", "DEC1", "ADC MUX1"},
7541 {"IIR1 INP0 MUX", "DEC2", "ADC MUX2"},
7542 {"IIR1 INP0 MUX", "DEC3", "ADC MUX3"},
7543 {"IIR1 INP0 MUX", "DEC4", "ADC MUX4"},
7544 {"IIR1 INP0 MUX", "DEC5", "ADC MUX5"},
7545 {"IIR1 INP0 MUX", "DEC6", "ADC MUX6"},
7546 {"IIR1 INP0 MUX", "DEC7", "ADC MUX7"},
7547 {"IIR1 INP0 MUX", "DEC8", "ADC MUX8"},
7548 {"IIR1 INP0 MUX", "RX0", "SLIM RX0"},
7549 {"IIR1 INP0 MUX", "RX1", "SLIM RX1"},
7550 {"IIR1 INP0 MUX", "RX2", "SLIM RX2"},
7551 {"IIR1 INP0 MUX", "RX3", "SLIM RX3"},
7552 {"IIR1 INP0 MUX", "RX4", "SLIM RX4"},
7553 {"IIR1 INP0 MUX", "RX5", "SLIM RX5"},
7554 {"IIR1 INP0 MUX", "RX6", "SLIM RX6"},
7555 {"IIR1 INP0 MUX", "RX7", "SLIM RX7"},
7556 {"IIR1", NULL, "IIR1 INP1 MUX"},
7557 {"IIR1 INP1 MUX", "DEC0", "ADC MUX0"},
7558 {"IIR1 INP1 MUX", "DEC1", "ADC MUX1"},
7559 {"IIR1 INP1 MUX", "DEC2", "ADC MUX2"},
7560 {"IIR1 INP1 MUX", "DEC3", "ADC MUX3"},
7561 {"IIR1 INP1 MUX", "DEC4", "ADC MUX4"},
7562 {"IIR1 INP1 MUX", "DEC5", "ADC MUX5"},
7563 {"IIR1 INP1 MUX", "DEC6", "ADC MUX6"},
7564 {"IIR1 INP1 MUX", "DEC7", "ADC MUX7"},
7565 {"IIR1 INP1 MUX", "DEC8", "ADC MUX8"},
7566 {"IIR1 INP1 MUX", "RX0", "SLIM RX0"},
7567 {"IIR1 INP1 MUX", "RX1", "SLIM RX1"},
7568 {"IIR1 INP1 MUX", "RX2", "SLIM RX2"},
7569 {"IIR1 INP1 MUX", "RX3", "SLIM RX3"},
7570 {"IIR1 INP1 MUX", "RX4", "SLIM RX4"},
7571 {"IIR1 INP1 MUX", "RX5", "SLIM RX5"},
7572 {"IIR1 INP1 MUX", "RX6", "SLIM RX6"},
7573 {"IIR1 INP1 MUX", "RX7", "SLIM RX7"},
7574 {"IIR1", NULL, "IIR1 INP2 MUX"},
7575 {"IIR1 INP2 MUX", "DEC0", "ADC MUX0"},
7576 {"IIR1 INP2 MUX", "DEC1", "ADC MUX1"},
7577 {"IIR1 INP2 MUX", "DEC2", "ADC MUX2"},
7578 {"IIR1 INP2 MUX", "DEC3", "ADC MUX3"},
7579 {"IIR1 INP2 MUX", "DEC4", "ADC MUX4"},
7580 {"IIR1 INP2 MUX", "DEC5", "ADC MUX5"},
7581 {"IIR1 INP2 MUX", "DEC6", "ADC MUX6"},
7582 {"IIR1 INP2 MUX", "DEC7", "ADC MUX7"},
7583 {"IIR1 INP2 MUX", "DEC8", "ADC MUX8"},
7584 {"IIR1 INP2 MUX", "RX0", "SLIM RX0"},
7585 {"IIR1 INP2 MUX", "RX1", "SLIM RX1"},
7586 {"IIR1 INP2 MUX", "RX2", "SLIM RX2"},
7587 {"IIR1 INP2 MUX", "RX3", "SLIM RX3"},
7588 {"IIR1 INP2 MUX", "RX4", "SLIM RX4"},
7589 {"IIR1 INP2 MUX", "RX5", "SLIM RX5"},
7590 {"IIR1 INP2 MUX", "RX6", "SLIM RX6"},
7591 {"IIR1 INP2 MUX", "RX7", "SLIM RX7"},
7592 {"IIR1", NULL, "IIR1 INP3 MUX"},
7593 {"IIR1 INP3 MUX", "DEC0", "ADC MUX0"},
7594 {"IIR1 INP3 MUX", "DEC1", "ADC MUX1"},
7595 {"IIR1 INP3 MUX", "DEC2", "ADC MUX2"},
7596 {"IIR1 INP3 MUX", "DEC3", "ADC MUX3"},
7597 {"IIR1 INP3 MUX", "DEC4", "ADC MUX4"},
7598 {"IIR1 INP3 MUX", "DEC5", "ADC MUX5"},
7599 {"IIR1 INP3 MUX", "DEC6", "ADC MUX6"},
7600 {"IIR1 INP3 MUX", "DEC7", "ADC MUX7"},
7601 {"IIR1 INP3 MUX", "DEC8", "ADC MUX8"},
7602 {"IIR1 INP3 MUX", "RX0", "SLIM RX0"},
7603 {"IIR1 INP3 MUX", "RX1", "SLIM RX1"},
7604 {"IIR1 INP3 MUX", "RX2", "SLIM RX2"},
7605 {"IIR1 INP3 MUX", "RX3", "SLIM RX3"},
7606 {"IIR1 INP3 MUX", "RX4", "SLIM RX4"},
7607 {"IIR1 INP3 MUX", "RX5", "SLIM RX5"},
7608 {"IIR1 INP3 MUX", "RX6", "SLIM RX6"},
7609 {"IIR1 INP3 MUX", "RX7", "SLIM RX7"},
7610
7611 {"SRC0", NULL, "IIR0"},
7612 {"SRC1", NULL, "IIR1"},
7613 {"RX INT0 MIX2 INP", "SRC0", "SRC0"},
7614 {"RX INT0 MIX2 INP", "SRC1", "SRC1"},
7615 {"RX INT1 MIX2 INP", "SRC0", "SRC0"},
7616 {"RX INT1 MIX2 INP", "SRC1", "SRC1"},
7617 {"RX INT2 MIX2 INP", "SRC0", "SRC0"},
7618 {"RX INT2 MIX2 INP", "SRC1", "SRC1"},
7619 {"RX INT3 MIX2 INP", "SRC0", "SRC0"},
7620 {"RX INT3 MIX2 INP", "SRC1", "SRC1"},
7621 {"RX INT4 MIX2 INP", "SRC0", "SRC0"},
7622 {"RX INT4 MIX2 INP", "SRC1", "SRC1"},
7623 {"RX INT7 MIX2 INP", "SRC0", "SRC0"},
7624 {"RX INT7 MIX2 INP", "SRC1", "SRC1"},
7625};
7626
7627static int tasha_amic_pwr_lvl_get(struct snd_kcontrol *kcontrol,
7628 struct snd_ctl_elem_value *ucontrol)
7629{
7630 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
7631 u16 amic_reg;
7632
7633 if (!strcmp(kcontrol->id.name, "AMIC_1_2 PWR MODE"))
7634 amic_reg = WCD9335_ANA_AMIC1;
7635 if (!strcmp(kcontrol->id.name, "AMIC_3_4 PWR MODE"))
7636 amic_reg = WCD9335_ANA_AMIC3;
7637 if (!strcmp(kcontrol->id.name, "AMIC_5_6 PWR MODE"))
7638 amic_reg = WCD9335_ANA_AMIC5;
7639
7640 ucontrol->value.integer.value[0] =
7641 (snd_soc_read(codec, amic_reg) & WCD9335_AMIC_PWR_LVL_MASK) >>
7642 WCD9335_AMIC_PWR_LVL_SHIFT;
7643
7644 return 0;
7645}
7646
7647static int tasha_amic_pwr_lvl_put(struct snd_kcontrol *kcontrol,
7648 struct snd_ctl_elem_value *ucontrol)
7649{
7650 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
7651 u32 mode_val;
7652 u16 amic_reg;
7653
7654 mode_val = ucontrol->value.enumerated.item[0];
7655
7656 dev_dbg(codec->dev, "%s: mode: %d\n",
7657 __func__, mode_val);
7658
7659 if (!strcmp(kcontrol->id.name, "AMIC_1_2 PWR MODE"))
7660 amic_reg = WCD9335_ANA_AMIC1;
7661 if (!strcmp(kcontrol->id.name, "AMIC_3_4 PWR MODE"))
7662 amic_reg = WCD9335_ANA_AMIC3;
7663 if (!strcmp(kcontrol->id.name, "AMIC_5_6 PWR MODE"))
7664 amic_reg = WCD9335_ANA_AMIC5;
7665
7666 snd_soc_update_bits(codec, amic_reg, WCD9335_AMIC_PWR_LVL_MASK,
7667 mode_val << WCD9335_AMIC_PWR_LVL_SHIFT);
7668
7669 return 0;
7670}
7671
7672static int tasha_rx_hph_mode_get(struct snd_kcontrol *kcontrol,
7673 struct snd_ctl_elem_value *ucontrol)
7674{
7675 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
7676 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
7677
7678 ucontrol->value.integer.value[0] = tasha->hph_mode;
7679 return 0;
7680}
7681
7682static int tasha_rx_hph_mode_put(struct snd_kcontrol *kcontrol,
7683 struct snd_ctl_elem_value *ucontrol)
7684{
7685 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
7686 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
7687 u32 mode_val;
7688
7689 mode_val = ucontrol->value.enumerated.item[0];
7690
7691 dev_dbg(codec->dev, "%s: mode: %d\n",
7692 __func__, mode_val);
7693
7694 if (mode_val == 0) {
7695 dev_warn(codec->dev, "%s:Invalid HPH Mode, default to Cls-H HiFi\n",
7696 __func__);
7697 mode_val = CLS_H_HIFI;
7698 }
7699 tasha->hph_mode = mode_val;
7700 return 0;
7701}
7702
7703static const char *const tasha_conn_mad_text[] = {
7704 "NOTUSED1", "ADC1", "ADC2", "ADC3", "ADC4", "ADC5", "ADC6",
7705 "NOTUSED2", "DMIC0", "DMIC1", "DMIC2", "DMIC3", "DMIC4",
7706 "DMIC5", "NOTUSED3", "NOTUSED4"
7707};
7708
7709static const struct soc_enum tasha_conn_mad_enum =
7710 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tasha_conn_mad_text),
7711 tasha_conn_mad_text);
7712
7713static int tasha_enable_ldo_h_get(struct snd_kcontrol *kcontrol,
7714 struct snd_ctl_elem_value *ucontrol)
7715{
7716 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
7717 u8 val = 0;
7718
7719 if (codec)
7720 val = snd_soc_read(codec, WCD9335_LDOH_MODE) & 0x80;
7721
7722 ucontrol->value.integer.value[0] = !!val;
7723
7724 return 0;
7725}
7726
7727static int tasha_enable_ldo_h_put(struct snd_kcontrol *kcontrol,
7728 struct snd_ctl_elem_value *ucontrol)
7729{
7730 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
7731 int value = ucontrol->value.integer.value[0];
7732 bool enable;
7733
7734 enable = !!value;
7735 if (codec)
7736 tasha_codec_enable_standalone_ldo_h(codec, enable);
7737
7738 return 0;
7739}
7740
7741static int tasha_mad_input_get(struct snd_kcontrol *kcontrol,
7742 struct snd_ctl_elem_value *ucontrol)
7743{
7744 u8 tasha_mad_input;
7745 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
7746
7747 tasha_mad_input = snd_soc_read(codec,
7748 WCD9335_SOC_MAD_INP_SEL) & 0x0F;
7749 ucontrol->value.integer.value[0] = tasha_mad_input;
7750
7751 dev_dbg(codec->dev,
7752 "%s: tasha_mad_input = %s\n", __func__,
7753 tasha_conn_mad_text[tasha_mad_input]);
7754 return 0;
7755}
7756
7757static int tasha_mad_input_put(struct snd_kcontrol *kcontrol,
7758 struct snd_ctl_elem_value *ucontrol)
7759{
7760 u8 tasha_mad_input;
7761 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
7762 struct snd_soc_card *card = codec->component.card;
7763 char mad_amic_input_widget[6];
7764 const char *mad_input_widget;
7765 const char *source_widget = NULL;
7766 u32 adc, i, mic_bias_found = 0;
7767 int ret = 0;
7768 char *mad_input;
7769
7770 tasha_mad_input = ucontrol->value.integer.value[0];
7771
7772 if (tasha_mad_input >= ARRAY_SIZE(tasha_conn_mad_text)) {
7773 dev_err(codec->dev,
7774 "%s: tasha_mad_input = %d out of bounds\n",
7775 __func__, tasha_mad_input);
7776 return -EINVAL;
7777 }
7778
7779 if (!strcmp(tasha_conn_mad_text[tasha_mad_input], "NOTUSED1") ||
7780 !strcmp(tasha_conn_mad_text[tasha_mad_input], "NOTUSED2") ||
7781 !strcmp(tasha_conn_mad_text[tasha_mad_input], "NOTUSED3") ||
7782 !strcmp(tasha_conn_mad_text[tasha_mad_input], "NOTUSED4")) {
7783 dev_err(codec->dev,
7784 "%s: Unsupported tasha_mad_input = %s\n",
7785 __func__, tasha_conn_mad_text[tasha_mad_input]);
7786 return -EINVAL;
7787 }
7788
7789 if (strnstr(tasha_conn_mad_text[tasha_mad_input],
7790 "ADC", sizeof("ADC"))) {
7791 mad_input = strpbrk(tasha_conn_mad_text[tasha_mad_input],
7792 "123456");
7793 if (!mad_input) {
7794 dev_err(codec->dev, "%s: Invalid MAD input %s\n",
7795 __func__,
7796 tasha_conn_mad_text[tasha_mad_input]);
7797 return -EINVAL;
7798 }
7799 ret = kstrtouint(mad_input, 10, &adc);
7800 if ((ret < 0) || (adc > 6)) {
7801 dev_err(codec->dev,
7802 "%s: Invalid ADC = %s\n", __func__,
7803 tasha_conn_mad_text[tasha_mad_input]);
7804 ret = -EINVAL;
7805 }
7806
7807 snprintf(mad_amic_input_widget, 6, "%s%u", "AMIC", adc);
7808
7809 mad_input_widget = mad_amic_input_widget;
7810 } else {
7811 /* DMIC type input widget*/
7812 mad_input_widget = tasha_conn_mad_text[tasha_mad_input];
7813 }
7814
7815 dev_dbg(codec->dev,
7816 "%s: tasha input widget = %s\n", __func__,
7817 mad_input_widget);
7818
7819 for (i = 0; i < card->num_of_dapm_routes; i++) {
7820 if (!strcmp(card->of_dapm_routes[i].sink, mad_input_widget)) {
7821 source_widget = card->of_dapm_routes[i].source;
7822 if (!source_widget) {
7823 dev_err(codec->dev,
7824 "%s: invalid source widget\n",
7825 __func__);
7826 return -EINVAL;
7827 }
7828
7829 if (strnstr(source_widget,
7830 "MIC BIAS1", sizeof("MIC BIAS1"))) {
7831 mic_bias_found = 1;
7832 break;
7833 } else if (strnstr(source_widget,
7834 "MIC BIAS2", sizeof("MIC BIAS2"))) {
7835 mic_bias_found = 2;
7836 break;
7837 } else if (strnstr(source_widget,
7838 "MIC BIAS3", sizeof("MIC BIAS3"))) {
7839 mic_bias_found = 3;
7840 break;
7841 } else if (strnstr(source_widget,
7842 "MIC BIAS4", sizeof("MIC BIAS4"))) {
7843 mic_bias_found = 4;
7844 break;
7845 }
7846 }
7847 }
7848
7849 if (!mic_bias_found) {
7850 dev_err(codec->dev,
7851 "%s: mic bias source not found for input = %s\n",
7852 __func__, mad_input_widget);
7853 return -EINVAL;
7854 }
7855
7856 dev_dbg(codec->dev,
7857 "%s: mic_bias found = %d\n", __func__,
7858 mic_bias_found);
7859
7860 snd_soc_update_bits(codec, WCD9335_SOC_MAD_INP_SEL,
7861 0x0F, tasha_mad_input);
7862 snd_soc_update_bits(codec, WCD9335_ANA_MAD_SETUP,
7863 0x07, mic_bias_found);
7864
7865 return 0;
7866}
7867
7868static int tasha_pinctl_mode_get(struct snd_kcontrol *kcontrol,
7869 struct snd_ctl_elem_value *ucontrol)
7870{
7871 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
7872 u16 ctl_reg;
7873 u8 reg_val, pinctl_position;
7874
7875 pinctl_position = ((struct soc_multi_mixer_control *)
7876 kcontrol->private_value)->shift;
7877 switch (pinctl_position >> 3) {
7878 case 0:
7879 ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_0;
7880 break;
7881 case 1:
7882 ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_1;
7883 break;
7884 case 2:
7885 ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_2;
7886 break;
7887 case 3:
7888 ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_3;
7889 break;
7890 default:
7891 dev_err(codec->dev, "%s: Invalid pinctl position = %d\n",
7892 __func__, pinctl_position);
7893 return -EINVAL;
7894 }
7895
7896 reg_val = snd_soc_read(codec, ctl_reg);
7897 reg_val = (reg_val >> (pinctl_position & 0x07)) & 0x1;
7898 ucontrol->value.integer.value[0] = reg_val;
7899
7900 return 0;
7901}
7902
7903static int tasha_pinctl_mode_put(struct snd_kcontrol *kcontrol,
7904 struct snd_ctl_elem_value *ucontrol)
7905{
7906 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
7907 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
7908 u16 ctl_reg, cfg_reg;
7909 u8 ctl_val, cfg_val, pinctl_position, pinctl_mode, mask;
7910
7911 /* 1- high or low; 0- high Z */
7912 pinctl_mode = ucontrol->value.integer.value[0];
7913 pinctl_position = ((struct soc_multi_mixer_control *)
7914 kcontrol->private_value)->shift;
7915
7916 switch (pinctl_position >> 3) {
7917 case 0:
7918 ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_0;
7919 break;
7920 case 1:
7921 ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_1;
7922 break;
7923 case 2:
7924 ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_2;
7925 break;
7926 case 3:
7927 ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_3;
7928 break;
7929 default:
7930 dev_err(codec->dev, "%s: Invalid pinctl position = %d\n",
7931 __func__, pinctl_position);
7932 return -EINVAL;
7933 }
7934
7935 ctl_val = pinctl_mode << (pinctl_position & 0x07);
7936 mask = 1 << (pinctl_position & 0x07);
7937 snd_soc_update_bits(codec, ctl_reg, mask, ctl_val);
7938
7939 cfg_reg = WCD9335_TLMM_BIST_MODE_PINCFG + pinctl_position;
7940 if (!pinctl_mode) {
7941 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS)
7942 cfg_val = 0x4;
7943 else
7944 cfg_val = 0xC;
7945 } else {
7946 cfg_val = 0;
7947 }
7948 snd_soc_update_bits(codec, cfg_reg, 0x07, cfg_val);
7949
7950 dev_dbg(codec->dev, "%s: reg=0x%x mask=0x%x val=%d reg=0x%x val=%d\n",
7951 __func__, ctl_reg, mask, ctl_val, cfg_reg, cfg_val);
7952
7953 return 0;
7954}
7955
7956static void wcd_vbat_adc_out_config_2_0(struct wcd_vbat *vbat,
7957 struct snd_soc_codec *codec)
7958{
7959 u8 val1, val2;
7960
7961 /*
7962 * Measure dcp1 by using "ALT" branch of band gap
7963 * voltage(Vbg) and use it in FAST mode
7964 */
7965 snd_soc_update_bits(codec, WCD9335_BIAS_CTL, 0x82, 0x82);
7966 snd_soc_update_bits(codec, WCD9335_CDC_VBAT_VBAT_PATH_CTL, 0x10, 0x10);
7967 snd_soc_update_bits(codec, WCD9335_CDC_VBAT_VBAT_DEBUG1, 0x01, 0x01);
7968 snd_soc_update_bits(codec, WCD9335_ANA_VBADC, 0x80, 0x80);
7969 snd_soc_update_bits(codec, WCD9335_VBADC_SUBBLOCK_EN, 0x20, 0x00);
7970
7971 snd_soc_update_bits(codec, WCD9335_VBADC_FE_CTRL, 0x20, 0x20);
7972 /* Wait 100 usec after calibration select as Vbg */
7973 usleep_range(100, 110);
7974
7975 snd_soc_update_bits(codec, WCD9335_VBADC_ADC_IO, 0x40, 0x40);
7976 val1 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTMSB);
7977 val2 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTLSB);
7978 snd_soc_update_bits(codec, WCD9335_VBADC_ADC_IO, 0x40, 0x00);
7979
7980 vbat->dcp1 = (((val1 & 0xFF) << 3) | (val2 & 0x07));
7981
7982 snd_soc_update_bits(codec, WCD9335_BIAS_CTL, 0x40, 0x40);
7983 /* Wait 100 usec after selecting Vbg as 1.05V */
7984 usleep_range(100, 110);
7985
7986 snd_soc_update_bits(codec, WCD9335_VBADC_ADC_IO, 0x40, 0x40);
7987 val1 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTMSB);
7988 val2 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTLSB);
7989 snd_soc_update_bits(codec, WCD9335_VBADC_ADC_IO, 0x40, 0x00);
7990
7991 vbat->dcp2 = (((val1 & 0xFF) << 3) | (val2 & 0x07));
7992
7993 dev_dbg(codec->dev, "%s: dcp1:0x%x, dcp2:0x%x\n",
7994 __func__, vbat->dcp1, vbat->dcp2);
7995
7996 snd_soc_write(codec, WCD9335_BIAS_CTL, 0x28);
7997 /* Wait 100 usec after selecting Vbg as 0.85V */
7998 usleep_range(100, 110);
7999
8000 snd_soc_update_bits(codec, WCD9335_VBADC_FE_CTRL, 0x20, 0x00);
8001 snd_soc_update_bits(codec, WCD9335_VBADC_SUBBLOCK_EN, 0x20, 0x20);
8002 snd_soc_update_bits(codec, WCD9335_ANA_VBADC, 0x80, 0x00);
8003
8004 snd_soc_update_bits(codec, WCD9335_CDC_VBAT_VBAT_PATH_CTL, 0x10, 0x00);
8005 snd_soc_update_bits(codec, WCD9335_CDC_VBAT_VBAT_DEBUG1, 0x01, 0x00);
8006}
8007
8008static void wcd_vbat_adc_out_config_1_x(struct wcd_vbat *vbat,
8009 struct snd_soc_codec *codec)
8010{
8011 u8 val1, val2;
8012
8013 /*
8014 * Measure dcp1 by applying band gap voltage(Vbg)
8015 * of 0.85V
8016 */
8017 snd_soc_write(codec, WCD9335_ANA_BIAS, 0x20);
8018 snd_soc_write(codec, WCD9335_BIAS_CTL, 0x28);
8019 snd_soc_write(codec, WCD9335_BIAS_VBG_FINE_ADJ, 0x05);
8020 snd_soc_write(codec, WCD9335_ANA_BIAS, 0xA0);
8021 /* Wait 2 sec after enabling band gap bias */
8022 usleep_range(2000000, 2000100);
8023
8024 snd_soc_write(codec, WCD9335_ANA_CLK_TOP, 0x82);
8025 snd_soc_write(codec, WCD9335_ANA_CLK_TOP, 0x87);
8026 snd_soc_update_bits(codec, WCD9335_CDC_VBAT_VBAT_PATH_CTL, 0x10, 0x10);
8027 snd_soc_write(codec, WCD9335_CDC_VBAT_VBAT_CFG, 0x0D);
8028 snd_soc_write(codec, WCD9335_CDC_VBAT_VBAT_DEBUG1, 0x01);
8029
8030 snd_soc_write(codec, WCD9335_ANA_VBADC, 0x80);
8031 snd_soc_write(codec, WCD9335_VBADC_SUBBLOCK_EN, 0xDE);
8032 snd_soc_write(codec, WCD9335_VBADC_FE_CTRL, 0x3C);
8033 /* Wait 1 msec after calibration select as Vbg */
8034 usleep_range(1000, 1100);
8035
8036 snd_soc_write(codec, WCD9335_VBADC_ADC_IO, 0xC0);
8037 val1 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTMSB);
8038 val2 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTLSB);
8039 snd_soc_write(codec, WCD9335_VBADC_ADC_IO, 0x80);
8040
8041 vbat->dcp1 = (((val1 & 0xFF) << 3) | (val2 & 0x07));
8042
8043 /*
8044 * Measure dcp2 by applying band gap voltage(Vbg)
8045 * of 1.05V
8046 */
8047 snd_soc_write(codec, WCD9335_ANA_BIAS, 0x80);
8048 snd_soc_write(codec, WCD9335_ANA_BIAS, 0xC0);
8049 snd_soc_write(codec, WCD9335_BIAS_CTL, 0x68);
8050 /* Wait 2 msec after selecting Vbg as 1.05V */
8051 usleep_range(2000, 2100);
8052
8053 snd_soc_write(codec, WCD9335_ANA_BIAS, 0x80);
8054 /* Wait 1 sec after enabling band gap bias */
8055 usleep_range(1000000, 1000100);
8056
8057 snd_soc_write(codec, WCD9335_VBADC_ADC_IO, 0xC0);
8058 val1 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTMSB);
8059 val2 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTLSB);
8060 snd_soc_write(codec, WCD9335_VBADC_ADC_IO, 0x80);
8061
8062 vbat->dcp2 = (((val1 & 0xFF) << 3) | (val2 & 0x07));
8063
8064 dev_dbg(codec->dev, "%s: dcp1:0x%x, dcp2:0x%x\n",
8065 __func__, vbat->dcp1, vbat->dcp2);
8066
8067 /* Reset the Vbat ADC configuration */
8068 snd_soc_write(codec, WCD9335_ANA_BIAS, 0x80);
8069 snd_soc_write(codec, WCD9335_ANA_BIAS, 0xC0);
8070
8071 snd_soc_write(codec, WCD9335_BIAS_CTL, 0x28);
8072 /* Wait 2 msec after selecting Vbg as 0.85V */
8073 usleep_range(2000, 2100);
8074
8075 snd_soc_write(codec, WCD9335_ANA_BIAS, 0xA0);
8076 /* Wait 1 sec after enabling band gap bias */
8077 usleep_range(1000000, 1000100);
8078
8079 snd_soc_write(codec, WCD9335_VBADC_FE_CTRL, 0x1C);
8080 snd_soc_write(codec, WCD9335_VBADC_SUBBLOCK_EN, 0xFE);
8081 snd_soc_write(codec, WCD9335_VBADC_ADC_IO, 0x80);
8082 snd_soc_write(codec, WCD9335_ANA_VBADC, 0x00);
8083
8084 snd_soc_write(codec, WCD9335_CDC_VBAT_VBAT_DEBUG1, 0x00);
8085 snd_soc_write(codec, WCD9335_CDC_VBAT_VBAT_PATH_CTL, 0x00);
8086 snd_soc_write(codec, WCD9335_CDC_VBAT_VBAT_CFG, 0x0A);
8087}
8088
8089static void wcd_vbat_adc_out_config(struct wcd_vbat *vbat,
8090 struct snd_soc_codec *codec)
8091{
8092 struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent);
8093
8094 if (!vbat->adc_config) {
8095 tasha_cdc_mclk_enable(codec, true, false);
8096
8097 if (TASHA_IS_2_0(wcd9xxx))
8098 wcd_vbat_adc_out_config_2_0(vbat, codec);
8099 else
8100 wcd_vbat_adc_out_config_1_x(vbat, codec);
8101
8102 tasha_cdc_mclk_enable(codec, false, false);
8103 vbat->adc_config = true;
8104 }
8105}
8106
8107static int tasha_update_vbat_reg_config(struct snd_soc_codec *codec)
8108{
8109 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
8110 struct firmware_cal *hwdep_cal = NULL;
8111 struct vbat_monitor_reg *vbat_reg_ptr = NULL;
8112 const void *data;
8113 size_t cal_size, vbat_size_remaining;
8114 int ret = 0, i;
8115 u32 vbat_writes_size = 0;
8116 u16 reg;
8117 u8 mask, val, old_val;
8118
8119 hwdep_cal = wcdcal_get_fw_cal(tasha->fw_data, WCD9XXX_VBAT_CAL);
8120 if (hwdep_cal) {
8121 data = hwdep_cal->data;
8122 cal_size = hwdep_cal->size;
8123 dev_dbg(codec->dev, "%s: using hwdep calibration\n",
8124 __func__);
8125 } else {
8126 dev_err(codec->dev, "%s: Vbat cal not received\n",
8127 __func__);
8128 ret = -EINVAL;
8129 goto done;
8130 }
8131
8132 if (cal_size < sizeof(*vbat_reg_ptr)) {
8133 dev_err(codec->dev,
8134 "%s: Incorrect size %zd for Vbat Cal, expected %zd\n",
8135 __func__, cal_size, sizeof(*vbat_reg_ptr));
8136 ret = -EINVAL;
8137 goto done;
8138 }
8139
8140 vbat_reg_ptr = (struct vbat_monitor_reg *) (data);
8141
8142 if (!vbat_reg_ptr) {
8143 dev_err(codec->dev,
8144 "%s: Invalid calibration data for Vbat\n",
8145 __func__);
8146 ret = -EINVAL;
8147 goto done;
8148 }
8149
8150 vbat_writes_size = vbat_reg_ptr->size;
8151 vbat_size_remaining = cal_size - sizeof(u32);
8152 dev_dbg(codec->dev, "%s: vbat_writes_sz: %d, vbat_sz_remaining: %zd\n",
8153 __func__, vbat_writes_size, vbat_size_remaining);
8154
8155 if ((vbat_writes_size * TASHA_PACKED_REG_SIZE)
8156 > vbat_size_remaining) {
8157 pr_err("%s: Incorrect Vbat calibration data\n", __func__);
8158 ret = -EINVAL;
8159 goto done;
8160 }
8161
8162 for (i = 0 ; i < vbat_writes_size; i++) {
8163 TASHA_CODEC_UNPACK_ENTRY(vbat_reg_ptr->writes[i],
8164 reg, mask, val);
8165 old_val = snd_soc_read(codec, reg);
8166 snd_soc_write(codec, reg, (old_val & ~mask) | (val & mask));
8167 }
8168
8169done:
8170 return ret;
8171}
8172
8173static int tasha_vbat_adc_data_get(struct snd_kcontrol *kcontrol,
8174 struct snd_ctl_elem_value *ucontrol)
8175{
8176 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
8177 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
8178
8179 wcd_vbat_adc_out_config(&tasha->vbat, codec);
8180
8181 ucontrol->value.integer.value[0] = tasha->vbat.dcp1;
8182 ucontrol->value.integer.value[1] = tasha->vbat.dcp2;
8183
8184 dev_dbg(codec->dev,
8185 "%s: Vbat ADC output values, Dcp1 : %lu, Dcp2: %lu\n",
8186 __func__, ucontrol->value.integer.value[0],
8187 ucontrol->value.integer.value[1]);
8188
8189 return 0;
8190}
8191
8192static const char * const tasha_vbat_gsm_mode_text[] = {
8193 "OFF", "ON"};
8194
8195static const struct soc_enum tasha_vbat_gsm_mode_enum =
8196 SOC_ENUM_SINGLE_EXT(2, tasha_vbat_gsm_mode_text);
8197
8198static int tasha_vbat_gsm_mode_func_get(struct snd_kcontrol *kcontrol,
8199 struct snd_ctl_elem_value *ucontrol)
8200{
8201 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
8202
8203 ucontrol->value.integer.value[0] =
8204 ((snd_soc_read(codec, WCD9335_CDC_VBAT_VBAT_CFG) & 0x04) ?
8205 1 : 0);
8206
8207 dev_dbg(codec->dev, "%s: value: %lu\n", __func__,
8208 ucontrol->value.integer.value[0]);
8209
8210 return 0;
8211}
8212
8213static int tasha_vbat_gsm_mode_func_put(struct snd_kcontrol *kcontrol,
8214 struct snd_ctl_elem_value *ucontrol)
8215{
8216 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
8217
8218 dev_dbg(codec->dev, "%s: value: %lu\n", __func__,
8219 ucontrol->value.integer.value[0]);
8220
8221 /* Set Vbat register configuration for GSM mode bit based on value */
8222 if (ucontrol->value.integer.value[0])
8223 snd_soc_update_bits(codec, WCD9335_CDC_VBAT_VBAT_CFG,
8224 0x04, 0x04);
8225 else
8226 snd_soc_update_bits(codec, WCD9335_CDC_VBAT_VBAT_CFG,
8227 0x04, 0x00);
8228
8229 return 0;
8230}
8231
8232static int tasha_codec_vbat_enable_event(struct snd_soc_dapm_widget *w,
8233 struct snd_kcontrol *kcontrol,
8234 int event)
8235{
8236 int ret = 0;
8237 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
8238 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
8239 u16 vbat_path_ctl, vbat_cfg, vbat_path_cfg;
8240
8241 vbat_path_ctl = WCD9335_CDC_VBAT_VBAT_PATH_CTL;
8242 vbat_cfg = WCD9335_CDC_VBAT_VBAT_CFG;
8243 vbat_path_cfg = WCD9335_CDC_RX8_RX_PATH_CFG1;
8244
8245 if (!strcmp(w->name, "RX INT8 VBAT"))
8246 vbat_path_cfg = WCD9335_CDC_RX8_RX_PATH_CFG1;
8247 else if (!strcmp(w->name, "RX INT7 VBAT"))
8248 vbat_path_cfg = WCD9335_CDC_RX7_RX_PATH_CFG1;
8249 else if (!strcmp(w->name, "RX INT6 VBAT"))
8250 vbat_path_cfg = WCD9335_CDC_RX6_RX_PATH_CFG1;
8251 else if (!strcmp(w->name, "RX INT5 VBAT"))
8252 vbat_path_cfg = WCD9335_CDC_RX5_RX_PATH_CFG1;
8253
8254 switch (event) {
8255 case SND_SOC_DAPM_PRE_PMU:
8256 ret = tasha_update_vbat_reg_config(codec);
8257 if (ret) {
8258 dev_dbg(codec->dev,
8259 "%s : VBAT isn't calibrated, So not enabling it\n",
8260 __func__);
8261 return 0;
8262 }
8263 snd_soc_write(codec, WCD9335_ANA_VBADC, 0x80);
8264 snd_soc_update_bits(codec, vbat_path_cfg, 0x02, 0x02);
8265 snd_soc_update_bits(codec, vbat_path_ctl, 0x10, 0x10);
8266 snd_soc_update_bits(codec, vbat_cfg, 0x01, 0x01);
8267 tasha->vbat.is_enabled = true;
8268 break;
8269 case SND_SOC_DAPM_POST_PMD:
8270 if (tasha->vbat.is_enabled) {
8271 snd_soc_update_bits(codec, vbat_cfg, 0x01, 0x00);
8272 snd_soc_update_bits(codec, vbat_path_ctl, 0x10, 0x00);
8273 snd_soc_update_bits(codec, vbat_path_cfg, 0x02, 0x00);
8274 snd_soc_write(codec, WCD9335_ANA_VBADC, 0x00);
8275 tasha->vbat.is_enabled = false;
8276 }
8277 break;
8278 };
8279
8280 return ret;
8281}
8282
8283static const char * const rx_hph_mode_mux_text[] = {
8284 "CLS_H_INVALID", "CLS_H_HIFI", "CLS_H_LP", "CLS_AB", "CLS_H_LOHIFI"
8285};
8286
8287static const struct soc_enum rx_hph_mode_mux_enum =
8288 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_hph_mode_mux_text),
8289 rx_hph_mode_mux_text);
8290
8291static const char * const amic_pwr_lvl_text[] = {
8292 "LOW_PWR", "DEFAULT", "HIGH_PERF"
8293};
8294
8295static const struct soc_enum amic_pwr_lvl_enum =
8296 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(amic_pwr_lvl_text),
8297 amic_pwr_lvl_text);
8298
8299static const struct snd_kcontrol_new tasha_snd_controls[] = {
8300 SOC_SINGLE_SX_TLV("RX0 Digital Volume", WCD9335_CDC_RX0_RX_VOL_CTL,
8301 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8302 SOC_SINGLE_SX_TLV("RX1 Digital Volume", WCD9335_CDC_RX1_RX_VOL_CTL,
8303 0, -84, 40, digital_gain),
8304 SOC_SINGLE_SX_TLV("RX2 Digital Volume", WCD9335_CDC_RX2_RX_VOL_CTL,
8305 0, -84, 40, digital_gain),
8306 SOC_SINGLE_SX_TLV("RX3 Digital Volume", WCD9335_CDC_RX3_RX_VOL_CTL,
8307 0, -84, 40, digital_gain),
8308 SOC_SINGLE_SX_TLV("RX4 Digital Volume", WCD9335_CDC_RX4_RX_VOL_CTL,
8309 0, -84, 40, digital_gain),
8310 SOC_SINGLE_SX_TLV("RX5 Digital Volume", WCD9335_CDC_RX5_RX_VOL_CTL,
8311 0, -84, 40, digital_gain),
8312 SOC_SINGLE_SX_TLV("RX6 Digital Volume", WCD9335_CDC_RX6_RX_VOL_CTL,
8313 0, -84, 40, digital_gain),
8314 SOC_SINGLE_SX_TLV("RX7 Digital Volume", WCD9335_CDC_RX7_RX_VOL_CTL,
8315 0, -84, 40, digital_gain),
8316 SOC_SINGLE_SX_TLV("RX8 Digital Volume", WCD9335_CDC_RX8_RX_VOL_CTL,
8317 0, -84, 40, digital_gain),
8318
8319 SOC_SINGLE_SX_TLV("RX0 Mix Digital Volume",
8320 WCD9335_CDC_RX0_RX_VOL_MIX_CTL,
8321 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8322 SOC_SINGLE_SX_TLV("RX1 Mix Digital Volume",
8323 WCD9335_CDC_RX1_RX_VOL_MIX_CTL,
8324 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8325 SOC_SINGLE_SX_TLV("RX2 Mix Digital Volume",
8326 WCD9335_CDC_RX2_RX_VOL_MIX_CTL,
8327 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8328 SOC_SINGLE_SX_TLV("RX3 Mix Digital Volume",
8329 WCD9335_CDC_RX3_RX_VOL_MIX_CTL,
8330 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8331 SOC_SINGLE_SX_TLV("RX4 Mix Digital Volume",
8332 WCD9335_CDC_RX4_RX_VOL_MIX_CTL,
8333 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8334 SOC_SINGLE_SX_TLV("RX5 Mix Digital Volume",
8335 WCD9335_CDC_RX5_RX_VOL_MIX_CTL,
8336 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8337 SOC_SINGLE_SX_TLV("RX6 Mix Digital Volume",
8338 WCD9335_CDC_RX6_RX_VOL_MIX_CTL,
8339 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8340 SOC_SINGLE_SX_TLV("RX7 Mix Digital Volume",
8341 WCD9335_CDC_RX7_RX_VOL_MIX_CTL,
8342 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8343 SOC_SINGLE_SX_TLV("RX8 Mix Digital Volume",
8344 WCD9335_CDC_RX8_RX_VOL_MIX_CTL,
8345 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8346
8347 SOC_SINGLE_SX_TLV("DEC0 Volume", WCD9335_CDC_TX0_TX_VOL_CTL, 0,
8348 -84, 40, digital_gain),
8349 SOC_SINGLE_SX_TLV("DEC1 Volume", WCD9335_CDC_TX1_TX_VOL_CTL, 0,
8350 -84, 40, digital_gain),
8351 SOC_SINGLE_SX_TLV("DEC2 Volume", WCD9335_CDC_TX2_TX_VOL_CTL, 0,
8352 -84, 40, digital_gain),
8353 SOC_SINGLE_SX_TLV("DEC3 Volume", WCD9335_CDC_TX3_TX_VOL_CTL, 0,
8354 -84, 40, digital_gain),
8355 SOC_SINGLE_SX_TLV("DEC4 Volume", WCD9335_CDC_TX4_TX_VOL_CTL, 0,
8356 -84, 40, digital_gain),
8357 SOC_SINGLE_SX_TLV("DEC5 Volume", WCD9335_CDC_TX5_TX_VOL_CTL, 0,
8358 -84, 40, digital_gain),
8359 SOC_SINGLE_SX_TLV("DEC6 Volume", WCD9335_CDC_TX6_TX_VOL_CTL, 0,
8360 -84, 40, digital_gain),
8361 SOC_SINGLE_SX_TLV("DEC7 Volume", WCD9335_CDC_TX7_TX_VOL_CTL, 0,
8362 -84, 40, digital_gain),
8363 SOC_SINGLE_SX_TLV("DEC8 Volume", WCD9335_CDC_TX8_TX_VOL_CTL, 0,
8364 -84, 40, digital_gain),
8365
8366 SOC_SINGLE_SX_TLV("IIR0 INP0 Volume",
8367 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL, 0, -84,
8368 40, digital_gain),
8369 SOC_SINGLE_SX_TLV("IIR0 INP1 Volume",
8370 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL, 0, -84,
8371 40, digital_gain),
8372 SOC_SINGLE_SX_TLV("IIR0 INP2 Volume",
8373 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL, 0, -84,
8374 40, digital_gain),
8375 SOC_SINGLE_SX_TLV("IIR0 INP3 Volume",
8376 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL, 0, -84,
8377 40, digital_gain),
8378 SOC_SINGLE_SX_TLV("IIR1 INP0 Volume",
8379 WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B1_CTL, 0, -84,
8380 40, digital_gain),
8381 SOC_SINGLE_SX_TLV("IIR1 INP1 Volume",
8382 WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B2_CTL, 0, -84,
8383 40, digital_gain),
8384 SOC_SINGLE_SX_TLV("IIR1 INP2 Volume",
8385 WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B3_CTL, 0, -84,
8386 40, digital_gain),
8387 SOC_SINGLE_SX_TLV("IIR1 INP3 Volume",
8388 WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B4_CTL, 0, -84,
8389 40, digital_gain),
8390
8391 SOC_SINGLE_EXT("ANC Slot", SND_SOC_NOPM, 0, 100, 0, tasha_get_anc_slot,
8392 tasha_put_anc_slot),
8393 SOC_ENUM_EXT("ANC Function", tasha_anc_func_enum, tasha_get_anc_func,
8394 tasha_put_anc_func),
8395
8396 SOC_ENUM_EXT("CLK MODE", tasha_clkmode_enum, tasha_get_clkmode,
8397 tasha_put_clkmode),
8398
8399 SOC_ENUM("TX0 HPF cut off", cf_dec0_enum),
8400 SOC_ENUM("TX1 HPF cut off", cf_dec1_enum),
8401 SOC_ENUM("TX2 HPF cut off", cf_dec2_enum),
8402 SOC_ENUM("TX3 HPF cut off", cf_dec3_enum),
8403 SOC_ENUM("TX4 HPF cut off", cf_dec4_enum),
8404 SOC_ENUM("TX5 HPF cut off", cf_dec5_enum),
8405 SOC_ENUM("TX6 HPF cut off", cf_dec6_enum),
8406 SOC_ENUM("TX7 HPF cut off", cf_dec7_enum),
8407 SOC_ENUM("TX8 HPF cut off", cf_dec8_enum),
8408
8409 SOC_ENUM("RX INT0_1 HPF cut off", cf_int0_1_enum),
8410 SOC_ENUM("RX INT0_2 HPF cut off", cf_int0_2_enum),
8411 SOC_ENUM("RX INT1_1 HPF cut off", cf_int1_1_enum),
8412 SOC_ENUM("RX INT1_2 HPF cut off", cf_int1_2_enum),
8413 SOC_ENUM("RX INT2_1 HPF cut off", cf_int2_1_enum),
8414 SOC_ENUM("RX INT2_2 HPF cut off", cf_int2_2_enum),
8415 SOC_ENUM("RX INT3_1 HPF cut off", cf_int3_1_enum),
8416 SOC_ENUM("RX INT3_2 HPF cut off", cf_int3_2_enum),
8417 SOC_ENUM("RX INT4_1 HPF cut off", cf_int4_1_enum),
8418 SOC_ENUM("RX INT4_2 HPF cut off", cf_int4_2_enum),
8419 SOC_ENUM("RX INT5_1 HPF cut off", cf_int5_1_enum),
8420 SOC_ENUM("RX INT5_2 HPF cut off", cf_int5_2_enum),
8421 SOC_ENUM("RX INT6_1 HPF cut off", cf_int6_1_enum),
8422 SOC_ENUM("RX INT6_2 HPF cut off", cf_int6_2_enum),
8423 SOC_ENUM("RX INT7_1 HPF cut off", cf_int7_1_enum),
8424 SOC_ENUM("RX INT7_2 HPF cut off", cf_int7_2_enum),
8425 SOC_ENUM("RX INT8_1 HPF cut off", cf_int8_1_enum),
8426 SOC_ENUM("RX INT8_2 HPF cut off", cf_int8_2_enum),
8427
8428 SOC_SINGLE_EXT("IIR0 Enable Band1", IIR0, BAND1, 1, 0,
8429 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8430 SOC_SINGLE_EXT("IIR0 Enable Band2", IIR0, BAND2, 1, 0,
8431 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8432 SOC_SINGLE_EXT("IIR0 Enable Band3", IIR0, BAND3, 1, 0,
8433 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8434 SOC_SINGLE_EXT("IIR0 Enable Band4", IIR0, BAND4, 1, 0,
8435 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8436 SOC_SINGLE_EXT("IIR0 Enable Band5", IIR0, BAND5, 1, 0,
8437 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8438 SOC_SINGLE_EXT("IIR1 Enable Band1", IIR1, BAND1, 1, 0,
8439 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8440 SOC_SINGLE_EXT("IIR1 Enable Band2", IIR1, BAND2, 1, 0,
8441 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8442 SOC_SINGLE_EXT("IIR1 Enable Band3", IIR1, BAND3, 1, 0,
8443 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8444 SOC_SINGLE_EXT("IIR1 Enable Band4", IIR1, BAND4, 1, 0,
8445 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8446 SOC_SINGLE_EXT("IIR1 Enable Band5", IIR1, BAND5, 1, 0,
8447 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8448
8449 SOC_SINGLE_MULTI_EXT("IIR0 Band1", IIR0, BAND1, 255, 0, 5,
8450 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8451 SOC_SINGLE_MULTI_EXT("IIR0 Band2", IIR0, BAND2, 255, 0, 5,
8452 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8453 SOC_SINGLE_MULTI_EXT("IIR0 Band3", IIR0, BAND3, 255, 0, 5,
8454 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8455 SOC_SINGLE_MULTI_EXT("IIR0 Band4", IIR0, BAND4, 255, 0, 5,
8456 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8457 SOC_SINGLE_MULTI_EXT("IIR0 Band5", IIR0, BAND5, 255, 0, 5,
8458 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8459 SOC_SINGLE_MULTI_EXT("IIR1 Band1", IIR1, BAND1, 255, 0, 5,
8460 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8461 SOC_SINGLE_MULTI_EXT("IIR1 Band2", IIR1, BAND2, 255, 0, 5,
8462 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8463 SOC_SINGLE_MULTI_EXT("IIR1 Band3", IIR1, BAND3, 255, 0, 5,
8464 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8465 SOC_SINGLE_MULTI_EXT("IIR1 Band4", IIR1, BAND4, 255, 0, 5,
8466 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8467 SOC_SINGLE_MULTI_EXT("IIR1 Band5", IIR1, BAND5, 255, 0, 5,
8468 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8469
8470 SOC_SINGLE_EXT("COMP1 Switch", SND_SOC_NOPM, COMPANDER_1, 1, 0,
8471 tasha_get_compander, tasha_set_compander),
8472 SOC_SINGLE_EXT("COMP2 Switch", SND_SOC_NOPM, COMPANDER_2, 1, 0,
8473 tasha_get_compander, tasha_set_compander),
8474 SOC_SINGLE_EXT("COMP3 Switch", SND_SOC_NOPM, COMPANDER_3, 1, 0,
8475 tasha_get_compander, tasha_set_compander),
8476 SOC_SINGLE_EXT("COMP4 Switch", SND_SOC_NOPM, COMPANDER_4, 1, 0,
8477 tasha_get_compander, tasha_set_compander),
8478 SOC_SINGLE_EXT("COMP5 Switch", SND_SOC_NOPM, COMPANDER_5, 1, 0,
8479 tasha_get_compander, tasha_set_compander),
8480 SOC_SINGLE_EXT("COMP6 Switch", SND_SOC_NOPM, COMPANDER_6, 1, 0,
8481 tasha_get_compander, tasha_set_compander),
8482 SOC_SINGLE_EXT("COMP7 Switch", SND_SOC_NOPM, COMPANDER_7, 1, 0,
8483 tasha_get_compander, tasha_set_compander),
8484 SOC_SINGLE_EXT("COMP8 Switch", SND_SOC_NOPM, COMPANDER_8, 1, 0,
8485 tasha_get_compander, tasha_set_compander),
8486
8487 SOC_ENUM_EXT("RX HPH Mode", rx_hph_mode_mux_enum,
8488 tasha_rx_hph_mode_get, tasha_rx_hph_mode_put),
8489
8490 SOC_ENUM_EXT("MAD Input", tasha_conn_mad_enum,
8491 tasha_mad_input_get, tasha_mad_input_put),
8492 SOC_SINGLE_EXT("LDO_H Enable", SND_SOC_NOPM, 0, 1, 0,
8493 tasha_enable_ldo_h_get, tasha_enable_ldo_h_put),
8494
8495 SOC_SINGLE_EXT("DMIC1_CLK_PIN_MODE", SND_SOC_NOPM, 17, 1, 0,
8496 tasha_pinctl_mode_get, tasha_pinctl_mode_put),
8497
8498 SOC_SINGLE_EXT("DMIC1_DATA_PIN_MODE", SND_SOC_NOPM, 18, 1, 0,
8499 tasha_pinctl_mode_get, tasha_pinctl_mode_put),
8500
8501 SOC_SINGLE_EXT("DMIC2_CLK_PIN_MODE", SND_SOC_NOPM, 19, 1, 0,
8502 tasha_pinctl_mode_get, tasha_pinctl_mode_put),
8503
8504 SOC_SINGLE_EXT("DMIC2_DATA_PIN_MODE", SND_SOC_NOPM, 20, 1, 0,
8505 tasha_pinctl_mode_get, tasha_pinctl_mode_put),
8506
8507 SOC_SINGLE_EXT("DMIC3_CLK_PIN_MODE", SND_SOC_NOPM, 21, 1, 0,
8508 tasha_pinctl_mode_get, tasha_pinctl_mode_put),
8509
8510 SOC_SINGLE_EXT("DMIC3_DATA_PIN_MODE", SND_SOC_NOPM, 22, 1, 0,
8511 tasha_pinctl_mode_get, tasha_pinctl_mode_put),
8512 SOC_ENUM_EXT("AMIC_1_2 PWR MODE", amic_pwr_lvl_enum,
8513 tasha_amic_pwr_lvl_get, tasha_amic_pwr_lvl_put),
8514 SOC_ENUM_EXT("AMIC_3_4 PWR MODE", amic_pwr_lvl_enum,
8515 tasha_amic_pwr_lvl_get, tasha_amic_pwr_lvl_put),
8516 SOC_ENUM_EXT("AMIC_5_6 PWR MODE", amic_pwr_lvl_enum,
8517 tasha_amic_pwr_lvl_get, tasha_amic_pwr_lvl_put),
8518
8519 SOC_SINGLE_MULTI_EXT("Vbat ADC data", SND_SOC_NOPM, 0, 0xFFFF, 0, 2,
8520 tasha_vbat_adc_data_get, NULL),
8521
8522 SOC_ENUM_EXT("GSM mode Enable", tasha_vbat_gsm_mode_enum,
8523 tasha_vbat_gsm_mode_func_get,
8524 tasha_vbat_gsm_mode_func_put),
8525};
8526
8527static int tasha_put_dec_enum(struct snd_kcontrol *kcontrol,
8528 struct snd_ctl_elem_value *ucontrol)
8529{
Asish Bhattacharya34504582017-08-08 12:55:01 +05308530 struct snd_soc_dapm_widget *widget =
8531 snd_soc_dapm_kcontrol_widget(kcontrol);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308532 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
8533 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
8534 unsigned int val;
8535 u16 mic_sel_reg;
8536 u8 mic_sel;
8537
8538 val = ucontrol->value.enumerated.item[0];
8539 if (val > e->items - 1)
8540 return -EINVAL;
8541
8542 dev_dbg(codec->dev, "%s: wname: %s, val: 0x%x\n", __func__,
8543 widget->name, val);
8544
8545 switch (e->reg) {
8546 case WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG1:
8547 mic_sel_reg = WCD9335_CDC_TX0_TX_PATH_CFG0;
8548 break;
8549 case WCD9335_CDC_TX_INP_MUX_ADC_MUX1_CFG1:
8550 mic_sel_reg = WCD9335_CDC_TX1_TX_PATH_CFG0;
8551 break;
8552 case WCD9335_CDC_TX_INP_MUX_ADC_MUX2_CFG1:
8553 mic_sel_reg = WCD9335_CDC_TX2_TX_PATH_CFG0;
8554 break;
8555 case WCD9335_CDC_TX_INP_MUX_ADC_MUX3_CFG1:
8556 mic_sel_reg = WCD9335_CDC_TX3_TX_PATH_CFG0;
8557 break;
8558 case WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0:
8559 mic_sel_reg = WCD9335_CDC_TX4_TX_PATH_CFG0;
8560 break;
8561 case WCD9335_CDC_TX_INP_MUX_ADC_MUX5_CFG0:
8562 mic_sel_reg = WCD9335_CDC_TX5_TX_PATH_CFG0;
8563 break;
8564 case WCD9335_CDC_TX_INP_MUX_ADC_MUX6_CFG0:
8565 mic_sel_reg = WCD9335_CDC_TX6_TX_PATH_CFG0;
8566 break;
8567 case WCD9335_CDC_TX_INP_MUX_ADC_MUX7_CFG0:
8568 mic_sel_reg = WCD9335_CDC_TX7_TX_PATH_CFG0;
8569 break;
8570 case WCD9335_CDC_TX_INP_MUX_ADC_MUX8_CFG0:
8571 mic_sel_reg = WCD9335_CDC_TX8_TX_PATH_CFG0;
8572 break;
8573 default:
8574 dev_err(codec->dev, "%s: e->reg: 0x%x not expected\n",
8575 __func__, e->reg);
8576 return -EINVAL;
8577 }
8578
8579 /* ADC: 0, DMIC: 1 */
8580 mic_sel = val ? 0x0 : 0x1;
8581 snd_soc_update_bits(codec, mic_sel_reg, 1 << 7, mic_sel << 7);
8582
8583 return snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
8584}
8585
8586static int tasha_int_dem_inp_mux_put(struct snd_kcontrol *kcontrol,
8587 struct snd_ctl_elem_value *ucontrol)
8588{
Asish Bhattacharya34504582017-08-08 12:55:01 +05308589 struct snd_soc_dapm_widget *widget =
8590 snd_soc_dapm_kcontrol_widget(kcontrol);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308591 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
8592 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
8593 unsigned int val;
8594 unsigned short look_ahead_dly_reg = WCD9335_CDC_RX0_RX_PATH_CFG0;
8595
8596 val = ucontrol->value.enumerated.item[0];
8597 if (val >= e->items)
8598 return -EINVAL;
8599
8600 dev_dbg(codec->dev, "%s: wname: %s, val: 0x%x\n", __func__,
8601 widget->name, val);
8602
8603 if (e->reg == WCD9335_CDC_RX0_RX_PATH_SEC0)
8604 look_ahead_dly_reg = WCD9335_CDC_RX0_RX_PATH_CFG0;
8605 else if (e->reg == WCD9335_CDC_RX1_RX_PATH_SEC0)
8606 look_ahead_dly_reg = WCD9335_CDC_RX1_RX_PATH_CFG0;
8607 else if (e->reg == WCD9335_CDC_RX2_RX_PATH_SEC0)
8608 look_ahead_dly_reg = WCD9335_CDC_RX2_RX_PATH_CFG0;
8609
8610 /* Set Look Ahead Delay */
8611 snd_soc_update_bits(codec, look_ahead_dly_reg,
8612 0x08, (val ? 0x08 : 0x00));
8613 /* Set DEM INP Select */
8614 return snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
8615}
8616
8617static int tasha_ear_pa_gain_get(struct snd_kcontrol *kcontrol,
8618 struct snd_ctl_elem_value *ucontrol)
8619{
8620 u8 ear_pa_gain;
8621 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
8622
8623 ear_pa_gain = snd_soc_read(codec, WCD9335_ANA_EAR);
8624
8625 ear_pa_gain = (ear_pa_gain & 0x70) >> 4;
8626
8627 ucontrol->value.integer.value[0] = ear_pa_gain;
8628
8629 dev_dbg(codec->dev, "%s: ear_pa_gain = 0x%x\n", __func__,
8630 ear_pa_gain);
8631
8632 return 0;
8633}
8634
8635static int tasha_ear_pa_gain_put(struct snd_kcontrol *kcontrol,
8636 struct snd_ctl_elem_value *ucontrol)
8637{
8638 u8 ear_pa_gain;
8639 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
8640
8641 dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
8642 __func__, ucontrol->value.integer.value[0]);
8643
8644 ear_pa_gain = ucontrol->value.integer.value[0] << 4;
8645
8646 snd_soc_update_bits(codec, WCD9335_ANA_EAR, 0x70, ear_pa_gain);
8647 return 0;
8648}
8649
8650static int tasha_ear_spkr_pa_gain_get(struct snd_kcontrol *kcontrol,
8651 struct snd_ctl_elem_value *ucontrol)
8652{
8653 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
8654 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
8655
8656 ucontrol->value.integer.value[0] = tasha->ear_spkr_gain;
8657
8658 dev_dbg(codec->dev, "%s: ear_spkr_gain = %ld\n", __func__,
8659 ucontrol->value.integer.value[0]);
8660
8661 return 0;
8662}
8663
8664static int tasha_ear_spkr_pa_gain_put(struct snd_kcontrol *kcontrol,
8665 struct snd_ctl_elem_value *ucontrol)
8666{
8667 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
8668 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
8669
8670 dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
8671 __func__, ucontrol->value.integer.value[0]);
8672
8673 tasha->ear_spkr_gain = ucontrol->value.integer.value[0];
8674
8675 return 0;
8676}
8677
Xiaojun Sang24daae82017-09-22 16:50:24 +08008678static int tasha_spkr_left_boost_stage_get(struct snd_kcontrol *kcontrol,
8679 struct snd_ctl_elem_value *ucontrol)
8680{
8681 u8 bst_state_max = 0;
8682 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
8683
8684 bst_state_max = snd_soc_read(codec, WCD9335_CDC_BOOST0_BOOST_CTL);
8685 bst_state_max = (bst_state_max & 0x0c) >> 2;
8686 ucontrol->value.integer.value[0] = bst_state_max;
8687 dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
8688 __func__, ucontrol->value.integer.value[0]);
8689
8690 return 0;
8691}
8692
8693static int tasha_spkr_left_boost_stage_put(struct snd_kcontrol *kcontrol,
8694 struct snd_ctl_elem_value *ucontrol)
8695{
8696 u8 bst_state_max;
8697 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
8698
8699 dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
8700 __func__, ucontrol->value.integer.value[0]);
8701 bst_state_max = ucontrol->value.integer.value[0] << 2;
8702 snd_soc_update_bits(codec, WCD9335_CDC_BOOST0_BOOST_CTL,
8703 0x0c, bst_state_max);
8704
8705 return 0;
8706}
8707
8708static int tasha_spkr_right_boost_stage_get(struct snd_kcontrol *kcontrol,
8709 struct snd_ctl_elem_value *ucontrol)
8710{
8711 u8 bst_state_max = 0;
8712 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
8713
8714 bst_state_max = snd_soc_read(codec, WCD9335_CDC_BOOST1_BOOST_CTL);
8715 bst_state_max = (bst_state_max & 0x0c) >> 2;
8716 ucontrol->value.integer.value[0] = bst_state_max;
8717 dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
8718 __func__, ucontrol->value.integer.value[0]);
8719
8720 return 0;
8721}
8722
8723static int tasha_spkr_right_boost_stage_put(struct snd_kcontrol *kcontrol,
8724 struct snd_ctl_elem_value *ucontrol)
8725{
8726 u8 bst_state_max;
8727 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
8728
8729 dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
8730 __func__, ucontrol->value.integer.value[0]);
8731 bst_state_max = ucontrol->value.integer.value[0] << 2;
8732 snd_soc_update_bits(codec, WCD9335_CDC_BOOST1_BOOST_CTL,
8733 0x0c, bst_state_max);
8734
8735 return 0;
8736}
8737
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308738static int tasha_config_compander(struct snd_soc_codec *codec, int interp_n,
8739 int event)
8740{
8741 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
8742 int comp;
8743 u16 comp_ctl0_reg, rx_path_cfg0_reg;
8744
8745 /* EAR does not have compander */
8746 if (!interp_n)
8747 return 0;
8748
8749 comp = interp_n - 1;
8750 dev_dbg(codec->dev, "%s: event %d compander %d, enabled %d\n",
8751 __func__, event, comp + 1, tasha->comp_enabled[comp]);
8752
8753 if (!tasha->comp_enabled[comp])
8754 return 0;
8755
8756 comp_ctl0_reg = WCD9335_CDC_COMPANDER1_CTL0 + (comp * 8);
8757 rx_path_cfg0_reg = WCD9335_CDC_RX1_RX_PATH_CFG0 + (comp * 20);
8758
8759 if (SND_SOC_DAPM_EVENT_ON(event)) {
8760 /* Enable Compander Clock */
8761 snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x01);
8762 snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02);
8763 snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00);
8764 snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x02);
8765 }
8766
8767 if (SND_SOC_DAPM_EVENT_OFF(event)) {
8768 snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x04);
8769 snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x00);
8770 snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02);
8771 snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00);
8772 snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x00);
8773 snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x00);
8774 }
8775
8776 return 0;
8777}
8778
8779static int tasha_codec_config_mad(struct snd_soc_codec *codec)
8780{
8781 int ret = 0;
8782 int idx;
8783 const struct firmware *fw;
8784 struct firmware_cal *hwdep_cal = NULL;
8785 struct wcd_mad_audio_cal *mad_cal = NULL;
8786 const void *data;
8787 const char *filename = TASHA_MAD_AUDIO_FIRMWARE_PATH;
8788 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
8789 size_t cal_size;
8790
8791 hwdep_cal = wcdcal_get_fw_cal(tasha->fw_data, WCD9XXX_MAD_CAL);
8792 if (hwdep_cal) {
8793 data = hwdep_cal->data;
8794 cal_size = hwdep_cal->size;
8795 dev_dbg(codec->dev, "%s: using hwdep calibration\n",
8796 __func__);
8797 } else {
8798 ret = request_firmware(&fw, filename, codec->dev);
8799 if (ret || !fw) {
8800 dev_err(codec->dev,
8801 "%s: MAD firmware acquire failed, err = %d\n",
8802 __func__, ret);
8803 return -ENODEV;
8804 }
8805 data = fw->data;
8806 cal_size = fw->size;
8807 dev_dbg(codec->dev, "%s: using request_firmware calibration\n",
8808 __func__);
8809 }
8810
8811 if (cal_size < sizeof(*mad_cal)) {
8812 dev_err(codec->dev,
8813 "%s: Incorrect size %zd for MAD Cal, expected %zd\n",
8814 __func__, cal_size, sizeof(*mad_cal));
8815 ret = -ENOMEM;
8816 goto done;
8817 }
8818
8819 mad_cal = (struct wcd_mad_audio_cal *) (data);
8820 if (!mad_cal) {
8821 dev_err(codec->dev,
8822 "%s: Invalid calibration data\n",
8823 __func__);
8824 ret = -EINVAL;
8825 goto done;
8826 }
8827
8828 snd_soc_write(codec, WCD9335_SOC_MAD_MAIN_CTL_2,
8829 mad_cal->microphone_info.cycle_time);
8830 snd_soc_update_bits(codec, WCD9335_SOC_MAD_MAIN_CTL_1, 0xFF << 3,
8831 ((uint16_t)mad_cal->microphone_info.settle_time)
8832 << 3);
8833
8834 /* Audio */
8835 snd_soc_write(codec, WCD9335_SOC_MAD_AUDIO_CTL_8,
8836 mad_cal->audio_info.rms_omit_samples);
8837 snd_soc_update_bits(codec, WCD9335_SOC_MAD_AUDIO_CTL_1,
8838 0x07 << 4, mad_cal->audio_info.rms_comp_time << 4);
8839 snd_soc_update_bits(codec, WCD9335_SOC_MAD_AUDIO_CTL_2, 0x03 << 2,
8840 mad_cal->audio_info.detection_mechanism << 2);
8841 snd_soc_write(codec, WCD9335_SOC_MAD_AUDIO_CTL_7,
8842 mad_cal->audio_info.rms_diff_threshold & 0x3F);
8843 snd_soc_write(codec, WCD9335_SOC_MAD_AUDIO_CTL_5,
8844 mad_cal->audio_info.rms_threshold_lsb);
8845 snd_soc_write(codec, WCD9335_SOC_MAD_AUDIO_CTL_6,
8846 mad_cal->audio_info.rms_threshold_msb);
8847
8848 for (idx = 0; idx < ARRAY_SIZE(mad_cal->audio_info.iir_coefficients);
8849 idx++) {
8850 snd_soc_update_bits(codec, WCD9335_SOC_MAD_AUDIO_IIR_CTL_PTR,
8851 0x3F, idx);
8852 snd_soc_write(codec, WCD9335_SOC_MAD_AUDIO_IIR_CTL_VAL,
8853 mad_cal->audio_info.iir_coefficients[idx]);
8854 dev_dbg(codec->dev, "%s:MAD Audio IIR Coef[%d] = 0X%x",
8855 __func__, idx,
8856 mad_cal->audio_info.iir_coefficients[idx]);
8857 }
8858
8859 /* Beacon */
8860 snd_soc_write(codec, WCD9335_SOC_MAD_BEACON_CTL_8,
8861 mad_cal->beacon_info.rms_omit_samples);
8862 snd_soc_update_bits(codec, WCD9335_SOC_MAD_BEACON_CTL_1,
8863 0x07 << 4, mad_cal->beacon_info.rms_comp_time << 4);
8864 snd_soc_update_bits(codec, WCD9335_SOC_MAD_BEACON_CTL_2, 0x03 << 2,
8865 mad_cal->beacon_info.detection_mechanism << 2);
8866 snd_soc_write(codec, WCD9335_SOC_MAD_BEACON_CTL_7,
8867 mad_cal->beacon_info.rms_diff_threshold & 0x1F);
8868 snd_soc_write(codec, WCD9335_SOC_MAD_BEACON_CTL_5,
8869 mad_cal->beacon_info.rms_threshold_lsb);
8870 snd_soc_write(codec, WCD9335_SOC_MAD_BEACON_CTL_6,
8871 mad_cal->beacon_info.rms_threshold_msb);
8872
8873 for (idx = 0; idx < ARRAY_SIZE(mad_cal->beacon_info.iir_coefficients);
8874 idx++) {
8875 snd_soc_update_bits(codec, WCD9335_SOC_MAD_BEACON_IIR_CTL_PTR,
8876 0x3F, idx);
8877 snd_soc_write(codec, WCD9335_SOC_MAD_BEACON_IIR_CTL_VAL,
8878 mad_cal->beacon_info.iir_coefficients[idx]);
8879 dev_dbg(codec->dev, "%s:MAD Beacon IIR Coef[%d] = 0X%x",
8880 __func__, idx,
8881 mad_cal->beacon_info.iir_coefficients[idx]);
8882 }
8883
8884 /* Ultrasound */
8885 snd_soc_update_bits(codec, WCD9335_SOC_MAD_ULTR_CTL_1,
8886 0x07 << 4,
8887 mad_cal->ultrasound_info.rms_comp_time << 4);
8888 snd_soc_update_bits(codec, WCD9335_SOC_MAD_ULTR_CTL_2, 0x03 << 2,
8889 mad_cal->ultrasound_info.detection_mechanism << 2);
8890 snd_soc_write(codec, WCD9335_SOC_MAD_ULTR_CTL_7,
8891 mad_cal->ultrasound_info.rms_diff_threshold & 0x1F);
8892 snd_soc_write(codec, WCD9335_SOC_MAD_ULTR_CTL_5,
8893 mad_cal->ultrasound_info.rms_threshold_lsb);
8894 snd_soc_write(codec, WCD9335_SOC_MAD_ULTR_CTL_6,
8895 mad_cal->ultrasound_info.rms_threshold_msb);
8896
8897done:
8898 if (!hwdep_cal)
8899 release_firmware(fw);
8900
8901 return ret;
8902}
8903
8904static int tasha_codec_enable_mad(struct snd_soc_dapm_widget *w,
8905 struct snd_kcontrol *kcontrol, int event)
8906{
8907 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
8908 int ret = 0;
8909
8910 dev_dbg(codec->dev,
8911 "%s: event = %d\n", __func__, event);
8912
8913 /* Return if CPE INPUT is DEC1 */
8914 if (snd_soc_read(codec, WCD9335_CPE_SS_SVA_CFG) & 0x01)
8915 return ret;
8916
8917 switch (event) {
8918 case SND_SOC_DAPM_PRE_PMU:
8919
8920 /* Turn on MAD clk */
8921 snd_soc_update_bits(codec, WCD9335_CPE_SS_MAD_CTL,
8922 0x01, 0x01);
8923
8924 /* Undo reset for MAD */
8925 snd_soc_update_bits(codec, WCD9335_CPE_SS_MAD_CTL,
8926 0x02, 0x00);
8927 ret = tasha_codec_config_mad(codec);
8928 if (ret)
8929 dev_err(codec->dev,
8930 "%s: Failed to config MAD, err = %d\n",
8931 __func__, ret);
8932 break;
8933 case SND_SOC_DAPM_POST_PMD:
8934 /* Reset the MAD block */
8935 snd_soc_update_bits(codec, WCD9335_CPE_SS_MAD_CTL,
8936 0x02, 0x02);
8937 /* Turn off MAD clk */
8938 snd_soc_update_bits(codec, WCD9335_CPE_SS_MAD_CTL,
8939 0x01, 0x00);
8940 break;
8941 }
8942
8943 return ret;
8944}
8945
8946static int tasha_codec_configure_cpe_input(struct snd_soc_dapm_widget *w,
8947 struct snd_kcontrol *kcontrol, int event)
8948{
8949 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
8950
8951 dev_dbg(codec->dev,
8952 "%s: event = %d\n", __func__, event);
8953
8954 switch (event) {
8955 case SND_SOC_DAPM_PRE_PMU:
8956 /* Configure CPE input as DEC1 */
8957 snd_soc_update_bits(codec, WCD9335_CPE_SS_SVA_CFG,
8958 0x01, 0x01);
8959
8960 /* Configure DEC1 Tx out with sample rate as 16K */
8961 snd_soc_update_bits(codec, WCD9335_CDC_TX1_TX_PATH_CTL,
8962 0x0F, 0x01);
8963
8964 break;
8965 case SND_SOC_DAPM_POST_PMD:
8966 /* Reset DEC1 Tx out sample rate */
8967 snd_soc_update_bits(codec, WCD9335_CDC_TX1_TX_PATH_CTL,
8968 0x0F, 0x04);
8969 snd_soc_update_bits(codec, WCD9335_CPE_SS_SVA_CFG,
8970 0x01, 0x00);
8971
8972 break;
8973 }
8974
8975 return 0;
8976}
8977
8978
8979static int tasha_codec_aif4_mixer_switch_get(struct snd_kcontrol *kcontrol,
8980 struct snd_ctl_elem_value *ucontrol)
8981{
Asish Bhattacharya34504582017-08-08 12:55:01 +05308982 struct snd_soc_dapm_widget *widget =
8983 snd_soc_dapm_kcontrol_widget(kcontrol);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308984 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
8985 struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec);
8986
8987 if (test_bit(AIF4_SWITCH_VALUE, &tasha_p->status_mask))
8988 ucontrol->value.integer.value[0] = 1;
8989 else
8990 ucontrol->value.integer.value[0] = 0;
8991
8992 dev_dbg(codec->dev, "%s: AIF4 switch value = %ld\n",
8993 __func__, ucontrol->value.integer.value[0]);
8994 return 0;
8995}
8996
8997static int tasha_codec_aif4_mixer_switch_put(struct snd_kcontrol *kcontrol,
8998 struct snd_ctl_elem_value *ucontrol)
8999{
Asish Bhattacharya34504582017-08-08 12:55:01 +05309000 struct snd_soc_dapm_widget *widget =
9001 snd_soc_dapm_kcontrol_widget(kcontrol);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309002 struct snd_soc_dapm_update *update = NULL;
9003 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
9004 struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec);
9005
9006 dev_dbg(codec->dev, "%s: AIF4 switch value = %ld\n",
9007 __func__, ucontrol->value.integer.value[0]);
9008
9009 if (ucontrol->value.integer.value[0]) {
9010 snd_soc_dapm_mixer_update_power(widget->dapm,
9011 kcontrol, 1, update);
9012 set_bit(AIF4_SWITCH_VALUE, &tasha_p->status_mask);
9013 } else {
9014 snd_soc_dapm_mixer_update_power(widget->dapm,
9015 kcontrol, 0, update);
9016 clear_bit(AIF4_SWITCH_VALUE, &tasha_p->status_mask);
9017 }
9018
9019 return 1;
9020}
9021
9022static const char * const tasha_ear_pa_gain_text[] = {
9023 "G_6_DB", "G_4P5_DB", "G_3_DB", "G_1P5_DB",
9024 "G_0_DB", "G_M2P5_DB", "UNDEFINED", "G_M12_DB"
9025};
9026
9027static const char * const tasha_ear_spkr_pa_gain_text[] = {
9028 "G_DEFAULT", "G_0_DB", "G_1_DB", "G_2_DB", "G_3_DB", "G_4_DB",
9029 "G_5_DB", "G_6_DB"
9030};
9031
Xiaojun Sang24daae82017-09-22 16:50:24 +08009032static const char * const tasha_speaker_boost_stage_text[] = {
9033 "NO_MAX_STATE", "MAX_STATE_1", "MAX_STATE_2"
9034};
9035
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309036static const struct soc_enum tasha_ear_pa_gain_enum =
9037 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tasha_ear_pa_gain_text),
9038 tasha_ear_pa_gain_text);
9039
9040static const struct soc_enum tasha_ear_spkr_pa_gain_enum =
9041 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tasha_ear_spkr_pa_gain_text),
9042 tasha_ear_spkr_pa_gain_text);
9043
Xiaojun Sang24daae82017-09-22 16:50:24 +08009044static const struct soc_enum tasha_spkr_boost_stage_enum =
9045 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tasha_speaker_boost_stage_text),
9046 tasha_speaker_boost_stage_text);
9047
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309048static const struct snd_kcontrol_new tasha_analog_gain_controls[] = {
9049 SOC_ENUM_EXT("EAR PA Gain", tasha_ear_pa_gain_enum,
9050 tasha_ear_pa_gain_get, tasha_ear_pa_gain_put),
9051
9052 SOC_ENUM_EXT("EAR SPKR PA Gain", tasha_ear_spkr_pa_gain_enum,
9053 tasha_ear_spkr_pa_gain_get, tasha_ear_spkr_pa_gain_put),
9054
Xiaojun Sang24daae82017-09-22 16:50:24 +08009055 SOC_ENUM_EXT("SPKR Left Boost Max State", tasha_spkr_boost_stage_enum,
9056 tasha_spkr_left_boost_stage_get,
9057 tasha_spkr_left_boost_stage_put),
9058
9059 SOC_ENUM_EXT("SPKR Right Boost Max State", tasha_spkr_boost_stage_enum,
9060 tasha_spkr_right_boost_stage_get,
9061 tasha_spkr_right_boost_stage_put),
9062
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05309063 SOC_SINGLE_TLV("HPHL Volume", WCD9335_HPH_L_EN, 0, 20, 1,
9064 line_gain),
9065 SOC_SINGLE_TLV("HPHR Volume", WCD9335_HPH_R_EN, 0, 20, 1,
9066 line_gain),
9067 SOC_SINGLE_TLV("LINEOUT1 Volume", WCD9335_DIFF_LO_LO1_COMPANDER,
9068 3, 16, 1, line_gain),
9069 SOC_SINGLE_TLV("LINEOUT2 Volume", WCD9335_DIFF_LO_LO2_COMPANDER,
9070 3, 16, 1, line_gain),
9071 SOC_SINGLE_TLV("LINEOUT3 Volume", WCD9335_SE_LO_LO3_GAIN, 0, 20, 1,
9072 line_gain),
9073 SOC_SINGLE_TLV("LINEOUT4 Volume", WCD9335_SE_LO_LO4_GAIN, 0, 20, 1,
9074 line_gain),
9075
9076 SOC_SINGLE_TLV("ADC1 Volume", WCD9335_ANA_AMIC1, 0, 20, 0,
9077 analog_gain),
9078 SOC_SINGLE_TLV("ADC2 Volume", WCD9335_ANA_AMIC2, 0, 20, 0,
9079 analog_gain),
9080 SOC_SINGLE_TLV("ADC3 Volume", WCD9335_ANA_AMIC3, 0, 20, 0,
9081 analog_gain),
9082 SOC_SINGLE_TLV("ADC4 Volume", WCD9335_ANA_AMIC4, 0, 20, 0,
9083 analog_gain),
9084 SOC_SINGLE_TLV("ADC5 Volume", WCD9335_ANA_AMIC5, 0, 20, 0,
9085 analog_gain),
9086 SOC_SINGLE_TLV("ADC6 Volume", WCD9335_ANA_AMIC6, 0, 20, 0,
9087 analog_gain),
9088};
9089
9090static const char * const spl_src0_mux_text[] = {
9091 "ZERO", "SRC_IN_HPHL", "SRC_IN_LO1",
9092};
9093
9094static const char * const spl_src1_mux_text[] = {
9095 "ZERO", "SRC_IN_HPHR", "SRC_IN_LO2",
9096};
9097
9098static const char * const spl_src2_mux_text[] = {
9099 "ZERO", "SRC_IN_LO3", "SRC_IN_SPKRL",
9100};
9101
9102static const char * const spl_src3_mux_text[] = {
9103 "ZERO", "SRC_IN_LO4", "SRC_IN_SPKRR",
9104};
9105
9106static const char * const rx_int0_7_mix_mux_text[] = {
9107 "ZERO", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5",
9108 "RX6", "RX7", "PROXIMITY"
9109};
9110
9111static const char * const rx_int_mix_mux_text[] = {
9112 "ZERO", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5",
9113 "RX6", "RX7"
9114};
9115
9116static const char * const rx_prim_mix_text[] = {
9117 "ZERO", "DEC0", "DEC1", "IIR0", "IIR1", "RX0", "RX1", "RX2",
9118 "RX3", "RX4", "RX5", "RX6", "RX7"
9119};
9120
9121static const char * const rx_sidetone_mix_text[] = {
9122 "ZERO", "SRC0", "SRC1", "SRC_SUM"
9123};
9124
9125static const char * const sb_tx0_mux_text[] = {
9126 "ZERO", "RX_MIX_TX0", "DEC0", "DEC0_192"
9127};
9128
9129static const char * const sb_tx1_mux_text[] = {
9130 "ZERO", "RX_MIX_TX1", "DEC1", "DEC1_192"
9131};
9132
9133static const char * const sb_tx2_mux_text[] = {
9134 "ZERO", "RX_MIX_TX2", "DEC2", "DEC2_192"
9135};
9136
9137static const char * const sb_tx3_mux_text[] = {
9138 "ZERO", "RX_MIX_TX3", "DEC3", "DEC3_192"
9139};
9140
9141static const char * const sb_tx4_mux_text[] = {
9142 "ZERO", "RX_MIX_TX4", "DEC4", "DEC4_192"
9143};
9144
9145static const char * const sb_tx5_mux_text[] = {
9146 "ZERO", "RX_MIX_TX5", "DEC5", "DEC5_192"
9147};
9148
9149static const char * const sb_tx6_mux_text[] = {
9150 "ZERO", "RX_MIX_TX6", "DEC6", "DEC6_192"
9151};
9152
9153static const char * const sb_tx7_mux_text[] = {
9154 "ZERO", "RX_MIX_TX7", "DEC7", "DEC7_192"
9155};
9156
9157static const char * const sb_tx8_mux_text[] = {
9158 "ZERO", "RX_MIX_TX8", "DEC8", "DEC8_192"
9159};
9160
9161static const char * const sb_tx9_mux_text[] = {
9162 "ZERO", "DEC7", "DEC7_192"
9163};
9164
9165static const char * const sb_tx10_mux_text[] = {
9166 "ZERO", "DEC6", "DEC6_192"
9167};
9168
9169static const char * const sb_tx11_mux_text[] = {
9170 "DEC_0_5", "DEC_9_12", "MAD_AUDIO", "MAD_BRDCST"
9171};
9172
9173static const char * const sb_tx11_inp1_mux_text[] = {
9174 "ZERO", "DEC0", "DEC1", "DEC2", "DEC3", "DEC4",
9175 "DEC5", "RX_MIX_TX5", "DEC9_10", "DEC11_12"
9176};
9177
9178static const char * const sb_tx13_mux_text[] = {
9179 "ZERO", "DEC5", "DEC5_192"
9180};
9181
9182static const char * const tx13_inp_mux_text[] = {
9183 "CDC_DEC_5", "MAD_BRDCST", "CPE_TX_PP"
9184};
9185
9186static const char * const iir_inp_mux_text[] = {
9187 "ZERO", "DEC0", "DEC1", "DEC2", "DEC3", "DEC4", "DEC5", "DEC6",
9188 "DEC7", "DEC8", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5", "RX6", "RX7"
9189};
9190
9191static const char * const rx_int_dem_inp_mux_text[] = {
9192 "NORMAL_DSM_OUT", "CLSH_DSM_OUT",
9193};
9194
9195static const char * const rx_int0_interp_mux_text[] = {
9196 "ZERO", "RX INT0 MIX2",
9197};
9198
9199static const char * const rx_int1_interp_mux_text[] = {
9200 "ZERO", "RX INT1 MIX2",
9201};
9202
9203static const char * const rx_int2_interp_mux_text[] = {
9204 "ZERO", "RX INT2 MIX2",
9205};
9206
9207static const char * const rx_int3_interp_mux_text[] = {
9208 "ZERO", "RX INT3 MIX2",
9209};
9210
9211static const char * const rx_int4_interp_mux_text[] = {
9212 "ZERO", "RX INT4 MIX2",
9213};
9214
9215static const char * const rx_int5_interp_mux_text[] = {
9216 "ZERO", "RX INT5 MIX2",
9217};
9218
9219static const char * const rx_int6_interp_mux_text[] = {
9220 "ZERO", "RX INT6 MIX2",
9221};
9222
9223static const char * const rx_int7_interp_mux_text[] = {
9224 "ZERO", "RX INT7 MIX2",
9225};
9226
9227static const char * const rx_int8_interp_mux_text[] = {
9228 "ZERO", "RX INT8 SEC MIX"
9229};
9230
9231static const char * const mad_sel_text[] = {
9232 "SPE", "MSM"
9233};
9234
9235static const char * const adc_mux_text[] = {
9236 "DMIC", "AMIC", "ANC_FB_TUNE1", "ANC_FB_TUNE2"
9237};
9238
9239static const char * const dmic_mux_text[] = {
9240 "ZERO", "DMIC0", "DMIC1", "DMIC2", "DMIC3", "DMIC4", "DMIC5",
9241 "SMIC0", "SMIC1", "SMIC2", "SMIC3"
9242};
9243
9244static const char * const dmic_mux_alt_text[] = {
9245 "ZERO", "DMIC0", "DMIC1", "DMIC2", "DMIC3", "DMIC4", "DMIC5",
9246};
9247
9248static const char * const amic_mux_text[] = {
9249 "ZERO", "ADC1", "ADC2", "ADC3", "ADC4", "ADC5", "ADC6"
9250};
9251
9252static const char * const rx_echo_mux_text[] = {
9253 "ZERO", "RX_MIX0", "RX_MIX1", "RX_MIX2", "RX_MIX3", "RX_MIX4",
9254 "RX_MIX5", "RX_MIX6", "RX_MIX7", "RX_MIX8", "RX_MIX_VBAT5",
9255 "RX_MIX_VBAT6", "RX_MIX_VBAT7", "RX_MIX_VBAT8"
9256};
9257
9258static const char * const anc0_fb_mux_text[] = {
9259 "ZERO", "ANC_IN_HPHL", "ANC_IN_EAR", "ANC_IN_EAR_SPKR",
9260 "ANC_IN_LO1"
9261};
9262
9263static const char * const anc1_fb_mux_text[] = {
9264 "ZERO", "ANC_IN_HPHR", "ANC_IN_LO2"
9265};
9266
9267static const char * const native_mux_text[] = {
9268 "OFF", "ON",
9269};
9270
9271static const struct soc_enum spl_src0_mux_chain_enum =
9272 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SPLINE_SRC_CFG0, 0, 3,
9273 spl_src0_mux_text);
9274
9275static const struct soc_enum spl_src1_mux_chain_enum =
9276 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SPLINE_SRC_CFG0, 2, 3,
9277 spl_src1_mux_text);
9278
9279static const struct soc_enum spl_src2_mux_chain_enum =
9280 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SPLINE_SRC_CFG0, 4, 3,
9281 spl_src2_mux_text);
9282
9283static const struct soc_enum spl_src3_mux_chain_enum =
9284 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SPLINE_SRC_CFG0, 6, 3,
9285 spl_src3_mux_text);
9286
9287static const struct soc_enum rx_int0_2_mux_chain_enum =
9288 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG1, 0, 10,
9289 rx_int0_7_mix_mux_text);
9290
9291static const struct soc_enum rx_int1_2_mux_chain_enum =
9292 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG1, 0, 9,
9293 rx_int_mix_mux_text);
9294
9295static const struct soc_enum rx_int2_2_mux_chain_enum =
9296 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG1, 0, 9,
9297 rx_int_mix_mux_text);
9298
9299static const struct soc_enum rx_int3_2_mux_chain_enum =
9300 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG1, 0, 9,
9301 rx_int_mix_mux_text);
9302
9303static const struct soc_enum rx_int4_2_mux_chain_enum =
9304 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG1, 0, 9,
9305 rx_int_mix_mux_text);
9306
9307static const struct soc_enum rx_int5_2_mux_chain_enum =
9308 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG1, 0, 9,
9309 rx_int_mix_mux_text);
9310
9311static const struct soc_enum rx_int6_2_mux_chain_enum =
9312 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG1, 0, 9,
9313 rx_int_mix_mux_text);
9314
9315static const struct soc_enum rx_int7_2_mux_chain_enum =
9316 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG1, 0, 10,
9317 rx_int0_7_mix_mux_text);
9318
9319static const struct soc_enum rx_int8_2_mux_chain_enum =
9320 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG1, 0, 9,
9321 rx_int_mix_mux_text);
9322
9323static const struct soc_enum int1_1_native_enum =
9324 SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(native_mux_text),
9325 native_mux_text);
9326
9327static const struct soc_enum int2_1_native_enum =
9328 SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(native_mux_text),
9329 native_mux_text);
9330
9331static const struct soc_enum int3_1_native_enum =
9332 SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(native_mux_text),
9333 native_mux_text);
9334
9335static const struct soc_enum int4_1_native_enum =
9336 SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(native_mux_text),
9337 native_mux_text);
9338
9339static const struct soc_enum rx_int0_1_mix_inp0_chain_enum =
9340 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG0, 0, 13,
9341 rx_prim_mix_text);
9342
9343static const struct soc_enum rx_int0_1_mix_inp1_chain_enum =
9344 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG0, 4, 13,
9345 rx_prim_mix_text);
9346
9347static const struct soc_enum rx_int0_1_mix_inp2_chain_enum =
9348 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG1, 4, 13,
9349 rx_prim_mix_text);
9350
9351static const struct soc_enum rx_int1_1_mix_inp0_chain_enum =
9352 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG0, 0, 13,
9353 rx_prim_mix_text);
9354
9355static const struct soc_enum rx_int1_1_mix_inp1_chain_enum =
9356 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG0, 4, 13,
9357 rx_prim_mix_text);
9358
9359static const struct soc_enum rx_int1_1_mix_inp2_chain_enum =
9360 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG1, 4, 13,
9361 rx_prim_mix_text);
9362
9363static const struct soc_enum rx_int2_1_mix_inp0_chain_enum =
9364 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG0, 0, 13,
9365 rx_prim_mix_text);
9366
9367static const struct soc_enum rx_int2_1_mix_inp1_chain_enum =
9368 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG0, 4, 13,
9369 rx_prim_mix_text);
9370
9371static const struct soc_enum rx_int2_1_mix_inp2_chain_enum =
9372 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG1, 4, 13,
9373 rx_prim_mix_text);
9374
9375static const struct soc_enum rx_int3_1_mix_inp0_chain_enum =
9376 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG0, 0, 13,
9377 rx_prim_mix_text);
9378
9379static const struct soc_enum rx_int3_1_mix_inp1_chain_enum =
9380 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG0, 4, 13,
9381 rx_prim_mix_text);
9382
9383static const struct soc_enum rx_int3_1_mix_inp2_chain_enum =
9384 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG1, 4, 13,
9385 rx_prim_mix_text);
9386
9387static const struct soc_enum rx_int4_1_mix_inp0_chain_enum =
9388 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG0, 0, 13,
9389 rx_prim_mix_text);
9390
9391static const struct soc_enum rx_int4_1_mix_inp1_chain_enum =
9392 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG0, 4, 13,
9393 rx_prim_mix_text);
9394
9395static const struct soc_enum rx_int4_1_mix_inp2_chain_enum =
9396 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG1, 4, 13,
9397 rx_prim_mix_text);
9398
9399static const struct soc_enum rx_int5_1_mix_inp0_chain_enum =
9400 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG0, 0, 13,
9401 rx_prim_mix_text);
9402
9403static const struct soc_enum rx_int5_1_mix_inp1_chain_enum =
9404 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG0, 4, 13,
9405 rx_prim_mix_text);
9406
9407static const struct soc_enum rx_int5_1_mix_inp2_chain_enum =
9408 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG1, 4, 13,
9409 rx_prim_mix_text);
9410
9411static const struct soc_enum rx_int6_1_mix_inp0_chain_enum =
9412 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG0, 0, 13,
9413 rx_prim_mix_text);
9414
9415static const struct soc_enum rx_int6_1_mix_inp1_chain_enum =
9416 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG0, 4, 13,
9417 rx_prim_mix_text);
9418
9419static const struct soc_enum rx_int6_1_mix_inp2_chain_enum =
9420 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG1, 4, 13,
9421 rx_prim_mix_text);
9422
9423static const struct soc_enum rx_int7_1_mix_inp0_chain_enum =
9424 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG0, 0, 13,
9425 rx_prim_mix_text);
9426
9427static const struct soc_enum rx_int7_1_mix_inp1_chain_enum =
9428 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG0, 4, 13,
9429 rx_prim_mix_text);
9430
9431static const struct soc_enum rx_int7_1_mix_inp2_chain_enum =
9432 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG1, 4, 13,
9433 rx_prim_mix_text);
9434
9435static const struct soc_enum rx_int8_1_mix_inp0_chain_enum =
9436 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG0, 0, 13,
9437 rx_prim_mix_text);
9438
9439static const struct soc_enum rx_int8_1_mix_inp1_chain_enum =
9440 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG0, 4, 13,
9441 rx_prim_mix_text);
9442
9443static const struct soc_enum rx_int8_1_mix_inp2_chain_enum =
9444 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG1, 4, 13,
9445 rx_prim_mix_text);
9446
9447static const struct soc_enum rx_int0_sidetone_mix_chain_enum =
9448 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 0, 4,
9449 rx_sidetone_mix_text);
9450
9451static const struct soc_enum rx_int1_sidetone_mix_chain_enum =
9452 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 2, 4,
9453 rx_sidetone_mix_text);
9454
9455static const struct soc_enum rx_int2_sidetone_mix_chain_enum =
9456 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 4, 4,
9457 rx_sidetone_mix_text);
9458
9459static const struct soc_enum rx_int3_sidetone_mix_chain_enum =
9460 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 6, 4,
9461 rx_sidetone_mix_text);
9462
9463static const struct soc_enum rx_int4_sidetone_mix_chain_enum =
9464 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SIDETONE_SRC_CFG1, 0, 4,
9465 rx_sidetone_mix_text);
9466
9467static const struct soc_enum rx_int7_sidetone_mix_chain_enum =
9468 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SIDETONE_SRC_CFG1, 2, 4,
9469 rx_sidetone_mix_text);
9470
9471static const struct soc_enum tx_adc_mux0_chain_enum =
9472 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG1, 0, 4,
9473 adc_mux_text);
9474
9475static const struct soc_enum tx_adc_mux1_chain_enum =
9476 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX1_CFG1, 0, 4,
9477 adc_mux_text);
9478
9479static const struct soc_enum tx_adc_mux2_chain_enum =
9480 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX2_CFG1, 0, 4,
9481 adc_mux_text);
9482
9483static const struct soc_enum tx_adc_mux3_chain_enum =
9484 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX3_CFG1, 0, 4,
9485 adc_mux_text);
9486
9487static const struct soc_enum tx_adc_mux4_chain_enum =
9488 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0, 6, 4,
9489 adc_mux_text);
9490
9491static const struct soc_enum tx_adc_mux5_chain_enum =
9492 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX5_CFG0, 6, 4,
9493 adc_mux_text);
9494
9495static const struct soc_enum tx_adc_mux6_chain_enum =
9496 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX6_CFG0, 6, 4,
9497 adc_mux_text);
9498
9499static const struct soc_enum tx_adc_mux7_chain_enum =
9500 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 6, 4,
9501 adc_mux_text);
9502
9503static const struct soc_enum tx_adc_mux8_chain_enum =
9504 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX8_CFG0, 6, 4,
9505 adc_mux_text);
9506
9507static const struct soc_enum tx_adc_mux10_chain_enum =
9508 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX10_CFG0, 6, 4,
9509 adc_mux_text);
9510
9511static const struct soc_enum tx_adc_mux11_chain_enum =
9512 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX11_CFG0, 6, 4,
9513 adc_mux_text);
9514
9515static const struct soc_enum tx_adc_mux12_chain_enum =
9516 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX12_CFG0, 6, 4,
9517 adc_mux_text);
9518
9519static const struct soc_enum tx_adc_mux13_chain_enum =
9520 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX13_CFG0, 6, 4,
9521 adc_mux_text);
9522
9523static const struct soc_enum tx_dmic_mux0_enum =
9524 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG0, 3, 11,
9525 dmic_mux_text);
9526
9527static const struct soc_enum tx_dmic_mux1_enum =
9528 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX1_CFG0, 3, 11,
9529 dmic_mux_text);
9530
9531static const struct soc_enum tx_dmic_mux2_enum =
9532 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX2_CFG0, 3, 11,
9533 dmic_mux_text);
9534
9535static const struct soc_enum tx_dmic_mux3_enum =
9536 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX3_CFG0, 3, 11,
9537 dmic_mux_text);
9538
9539static const struct soc_enum tx_dmic_mux4_enum =
9540 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0, 3, 7,
9541 dmic_mux_alt_text);
9542
9543static const struct soc_enum tx_dmic_mux5_enum =
9544 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX5_CFG0, 3, 7,
9545 dmic_mux_alt_text);
9546
9547static const struct soc_enum tx_dmic_mux6_enum =
9548 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX6_CFG0, 3, 7,
9549 dmic_mux_alt_text);
9550
9551static const struct soc_enum tx_dmic_mux7_enum =
9552 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 3, 7,
9553 dmic_mux_alt_text);
9554
9555static const struct soc_enum tx_dmic_mux8_enum =
9556 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX8_CFG0, 3, 7,
9557 dmic_mux_alt_text);
9558
9559static const struct soc_enum tx_dmic_mux10_enum =
9560 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX10_CFG0, 3, 7,
9561 dmic_mux_alt_text);
9562
9563static const struct soc_enum tx_dmic_mux11_enum =
9564 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX11_CFG0, 3, 7,
9565 dmic_mux_alt_text);
9566
9567static const struct soc_enum tx_dmic_mux12_enum =
9568 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX12_CFG0, 3, 7,
9569 dmic_mux_alt_text);
9570
9571static const struct soc_enum tx_dmic_mux13_enum =
9572 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX13_CFG0, 3, 7,
9573 dmic_mux_alt_text);
9574
9575static const struct soc_enum tx_amic_mux0_enum =
9576 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG0, 0, 7,
9577 amic_mux_text);
9578
9579static const struct soc_enum tx_amic_mux1_enum =
9580 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX1_CFG0, 0, 7,
9581 amic_mux_text);
9582
9583static const struct soc_enum tx_amic_mux2_enum =
9584 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX2_CFG0, 0, 7,
9585 amic_mux_text);
9586
9587static const struct soc_enum tx_amic_mux3_enum =
9588 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX3_CFG0, 0, 7,
9589 amic_mux_text);
9590
9591static const struct soc_enum tx_amic_mux4_enum =
9592 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0, 0, 7,
9593 amic_mux_text);
9594
9595static const struct soc_enum tx_amic_mux5_enum =
9596 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX5_CFG0, 0, 7,
9597 amic_mux_text);
9598
9599static const struct soc_enum tx_amic_mux6_enum =
9600 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX6_CFG0, 0, 7,
9601 amic_mux_text);
9602
9603static const struct soc_enum tx_amic_mux7_enum =
9604 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 0, 7,
9605 amic_mux_text);
9606
9607static const struct soc_enum tx_amic_mux8_enum =
9608 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX8_CFG0, 0, 7,
9609 amic_mux_text);
9610
9611static const struct soc_enum tx_amic_mux10_enum =
9612 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX10_CFG0, 0, 7,
9613 amic_mux_text);
9614
9615static const struct soc_enum tx_amic_mux11_enum =
9616 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX11_CFG0, 0, 7,
9617 amic_mux_text);
9618
9619static const struct soc_enum tx_amic_mux12_enum =
9620 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX12_CFG0, 0, 7,
9621 amic_mux_text);
9622
9623static const struct soc_enum tx_amic_mux13_enum =
9624 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX13_CFG0, 0, 7,
9625 amic_mux_text);
9626
9627static const struct soc_enum sb_tx0_mux_enum =
9628 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0, 0, 4,
9629 sb_tx0_mux_text);
9630
9631static const struct soc_enum sb_tx1_mux_enum =
9632 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0, 2, 4,
9633 sb_tx1_mux_text);
9634
9635static const struct soc_enum sb_tx2_mux_enum =
9636 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0, 4, 4,
9637 sb_tx2_mux_text);
9638
9639static const struct soc_enum sb_tx3_mux_enum =
9640 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0, 6, 4,
9641 sb_tx3_mux_text);
9642
9643static const struct soc_enum sb_tx4_mux_enum =
9644 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1, 0, 4,
9645 sb_tx4_mux_text);
9646
9647static const struct soc_enum sb_tx5_mux_enum =
9648 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1, 2, 4,
9649 sb_tx5_mux_text);
9650
9651static const struct soc_enum sb_tx6_mux_enum =
9652 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1, 4, 4,
9653 sb_tx6_mux_text);
9654
9655static const struct soc_enum sb_tx7_mux_enum =
9656 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1, 6, 4,
9657 sb_tx7_mux_text);
9658
9659static const struct soc_enum sb_tx8_mux_enum =
9660 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG2, 0, 4,
9661 sb_tx8_mux_text);
9662
9663static const struct soc_enum sb_tx9_mux_enum =
9664 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG2, 2, 3,
9665 sb_tx9_mux_text);
9666
9667static const struct soc_enum sb_tx10_mux_enum =
9668 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG2, 4, 3,
9669 sb_tx10_mux_text);
9670
9671static const struct soc_enum sb_tx11_mux_enum =
9672 SOC_ENUM_SINGLE(WCD9335_DATA_HUB_DATA_HUB_SB_TX11_INP_CFG, 0, 4,
9673 sb_tx11_mux_text);
9674
9675static const struct soc_enum sb_tx11_inp1_mux_enum =
9676 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG3, 0, 10,
9677 sb_tx11_inp1_mux_text);
9678
9679static const struct soc_enum sb_tx13_mux_enum =
9680 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG3, 4, 3,
9681 sb_tx13_mux_text);
9682
9683static const struct soc_enum tx13_inp_mux_enum =
9684 SOC_ENUM_SINGLE(WCD9335_DATA_HUB_DATA_HUB_SB_TX13_INP_CFG, 0, 3,
9685 tx13_inp_mux_text);
9686
9687static const struct soc_enum rx_mix_tx0_mux_enum =
9688 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG0, 0, 14,
9689 rx_echo_mux_text);
9690
9691static const struct soc_enum rx_mix_tx1_mux_enum =
9692 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG0, 4, 14,
9693 rx_echo_mux_text);
9694
9695static const struct soc_enum rx_mix_tx2_mux_enum =
9696 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG1, 0, 14,
9697 rx_echo_mux_text);
9698
9699static const struct soc_enum rx_mix_tx3_mux_enum =
9700 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG1, 4, 14,
9701 rx_echo_mux_text);
9702
9703static const struct soc_enum rx_mix_tx4_mux_enum =
9704 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG2, 0, 14,
9705 rx_echo_mux_text);
9706
9707static const struct soc_enum rx_mix_tx5_mux_enum =
9708 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG2, 4, 14,
9709 rx_echo_mux_text);
9710
9711static const struct soc_enum rx_mix_tx6_mux_enum =
9712 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG3, 0, 14,
9713 rx_echo_mux_text);
9714
9715static const struct soc_enum rx_mix_tx7_mux_enum =
9716 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG3, 4, 14,
9717 rx_echo_mux_text);
9718
9719static const struct soc_enum rx_mix_tx8_mux_enum =
9720 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG4, 0, 14,
9721 rx_echo_mux_text);
9722
9723static const struct soc_enum iir0_inp0_mux_enum =
9724 SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG0, 0, 18,
9725 iir_inp_mux_text);
9726
9727static const struct soc_enum iir0_inp1_mux_enum =
9728 SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG1, 0, 18,
9729 iir_inp_mux_text);
9730
9731static const struct soc_enum iir0_inp2_mux_enum =
9732 SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG2, 0, 18,
9733 iir_inp_mux_text);
9734
9735static const struct soc_enum iir0_inp3_mux_enum =
9736 SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG3, 0, 18,
9737 iir_inp_mux_text);
9738
9739static const struct soc_enum iir1_inp0_mux_enum =
9740 SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG0, 0, 18,
9741 iir_inp_mux_text);
9742
9743static const struct soc_enum iir1_inp1_mux_enum =
9744 SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG1, 0, 18,
9745 iir_inp_mux_text);
9746
9747static const struct soc_enum iir1_inp2_mux_enum =
9748 SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG2, 0, 18,
9749 iir_inp_mux_text);
9750
9751static const struct soc_enum iir1_inp3_mux_enum =
9752 SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG3, 0, 18,
9753 iir_inp_mux_text);
9754
9755static const struct soc_enum rx_int0_dem_inp_mux_enum =
9756 SOC_ENUM_SINGLE(WCD9335_CDC_RX0_RX_PATH_SEC0, 0,
9757 ARRAY_SIZE(rx_int_dem_inp_mux_text),
9758 rx_int_dem_inp_mux_text);
9759
9760static const struct soc_enum rx_int1_dem_inp_mux_enum =
9761 SOC_ENUM_SINGLE(WCD9335_CDC_RX1_RX_PATH_SEC0, 0,
9762 ARRAY_SIZE(rx_int_dem_inp_mux_text),
9763 rx_int_dem_inp_mux_text);
9764
9765static const struct soc_enum rx_int2_dem_inp_mux_enum =
9766 SOC_ENUM_SINGLE(WCD9335_CDC_RX2_RX_PATH_SEC0, 0,
9767 ARRAY_SIZE(rx_int_dem_inp_mux_text),
9768 rx_int_dem_inp_mux_text);
9769
9770static const struct soc_enum rx_int0_interp_mux_enum =
9771 SOC_ENUM_SINGLE(WCD9335_CDC_RX0_RX_PATH_CTL, 5, 2,
9772 rx_int0_interp_mux_text);
9773
9774static const struct soc_enum rx_int1_interp_mux_enum =
9775 SOC_ENUM_SINGLE(WCD9335_CDC_RX1_RX_PATH_CTL, 5, 2,
9776 rx_int1_interp_mux_text);
9777
9778static const struct soc_enum rx_int2_interp_mux_enum =
9779 SOC_ENUM_SINGLE(WCD9335_CDC_RX2_RX_PATH_CTL, 5, 2,
9780 rx_int2_interp_mux_text);
9781
9782static const struct soc_enum rx_int3_interp_mux_enum =
9783 SOC_ENUM_SINGLE(WCD9335_CDC_RX3_RX_PATH_CTL, 5, 2,
9784 rx_int3_interp_mux_text);
9785
9786static const struct soc_enum rx_int4_interp_mux_enum =
9787 SOC_ENUM_SINGLE(WCD9335_CDC_RX4_RX_PATH_CTL, 5, 2,
9788 rx_int4_interp_mux_text);
9789
9790static const struct soc_enum rx_int5_interp_mux_enum =
9791 SOC_ENUM_SINGLE(WCD9335_CDC_RX5_RX_PATH_CTL, 5, 2,
9792 rx_int5_interp_mux_text);
9793
9794static const struct soc_enum rx_int6_interp_mux_enum =
9795 SOC_ENUM_SINGLE(WCD9335_CDC_RX6_RX_PATH_CTL, 5, 2,
9796 rx_int6_interp_mux_text);
9797
9798static const struct soc_enum rx_int7_interp_mux_enum =
9799 SOC_ENUM_SINGLE(WCD9335_CDC_RX7_RX_PATH_CTL, 5, 2,
9800 rx_int7_interp_mux_text);
9801
9802static const struct soc_enum rx_int8_interp_mux_enum =
9803 SOC_ENUM_SINGLE(WCD9335_CDC_RX8_RX_PATH_CTL, 5, 2,
9804 rx_int8_interp_mux_text);
9805
9806static const struct soc_enum mad_sel_enum =
9807 SOC_ENUM_SINGLE(WCD9335_CPE_SS_CFG, 0, 2, mad_sel_text);
9808
9809static const struct soc_enum anc0_fb_mux_enum =
9810 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_ANC_CFG0, 0, 5,
9811 anc0_fb_mux_text);
9812
9813static const struct soc_enum anc1_fb_mux_enum =
9814 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_ANC_CFG0, 3, 3,
9815 anc1_fb_mux_text);
9816
9817static const struct snd_kcontrol_new rx_int0_dem_inp_mux =
9818 SOC_DAPM_ENUM_EXT("RX INT0 DEM MUX Mux", rx_int0_dem_inp_mux_enum,
9819 snd_soc_dapm_get_enum_double,
9820 tasha_int_dem_inp_mux_put);
9821
9822static const struct snd_kcontrol_new rx_int1_dem_inp_mux =
9823 SOC_DAPM_ENUM_EXT("RX INT1 DEM MUX Mux", rx_int1_dem_inp_mux_enum,
9824 snd_soc_dapm_get_enum_double,
9825 tasha_int_dem_inp_mux_put);
9826
9827static const struct snd_kcontrol_new rx_int2_dem_inp_mux =
9828 SOC_DAPM_ENUM_EXT("RX INT2 DEM MUX Mux", rx_int2_dem_inp_mux_enum,
9829 snd_soc_dapm_get_enum_double,
9830 tasha_int_dem_inp_mux_put);
9831
9832static const struct snd_kcontrol_new spl_src0_mux =
9833 SOC_DAPM_ENUM("SPL SRC0 MUX Mux", spl_src0_mux_chain_enum);
9834
9835static const struct snd_kcontrol_new spl_src1_mux =
9836 SOC_DAPM_ENUM("SPL SRC1 MUX Mux", spl_src1_mux_chain_enum);
9837
9838static const struct snd_kcontrol_new spl_src2_mux =
9839 SOC_DAPM_ENUM("SPL SRC2 MUX Mux", spl_src2_mux_chain_enum);
9840
9841static const struct snd_kcontrol_new spl_src3_mux =
9842 SOC_DAPM_ENUM("SPL SRC3 MUX Mux", spl_src3_mux_chain_enum);
9843
9844static const struct snd_kcontrol_new rx_int0_2_mux =
9845 SOC_DAPM_ENUM("RX INT0_2 MUX Mux", rx_int0_2_mux_chain_enum);
9846
9847static const struct snd_kcontrol_new rx_int1_2_mux =
9848 SOC_DAPM_ENUM("RX INT1_2 MUX Mux", rx_int1_2_mux_chain_enum);
9849
9850static const struct snd_kcontrol_new rx_int2_2_mux =
9851 SOC_DAPM_ENUM("RX INT2_2 MUX Mux", rx_int2_2_mux_chain_enum);
9852
9853static const struct snd_kcontrol_new rx_int3_2_mux =
9854 SOC_DAPM_ENUM("RX INT3_2 MUX Mux", rx_int3_2_mux_chain_enum);
9855
9856static const struct snd_kcontrol_new rx_int4_2_mux =
9857 SOC_DAPM_ENUM("RX INT4_2 MUX Mux", rx_int4_2_mux_chain_enum);
9858
9859static const struct snd_kcontrol_new rx_int5_2_mux =
9860 SOC_DAPM_ENUM("RX INT5_2 MUX Mux", rx_int5_2_mux_chain_enum);
9861
9862static const struct snd_kcontrol_new rx_int6_2_mux =
9863 SOC_DAPM_ENUM("RX INT6_2 MUX Mux", rx_int6_2_mux_chain_enum);
9864
9865static const struct snd_kcontrol_new rx_int7_2_mux =
9866 SOC_DAPM_ENUM("RX INT7_2 MUX Mux", rx_int7_2_mux_chain_enum);
9867
9868static const struct snd_kcontrol_new rx_int8_2_mux =
9869 SOC_DAPM_ENUM("RX INT8_2 MUX Mux", rx_int8_2_mux_chain_enum);
9870
9871static const struct snd_kcontrol_new int1_1_native_mux =
9872 SOC_DAPM_ENUM("RX INT1_1 NATIVE MUX Mux", int1_1_native_enum);
9873
9874static const struct snd_kcontrol_new int2_1_native_mux =
9875 SOC_DAPM_ENUM("RX INT2_1 NATIVE MUX Mux", int2_1_native_enum);
9876
9877static const struct snd_kcontrol_new int3_1_native_mux =
9878 SOC_DAPM_ENUM("RX INT3_1 NATIVE MUX Mux", int3_1_native_enum);
9879
9880static const struct snd_kcontrol_new int4_1_native_mux =
9881 SOC_DAPM_ENUM("RX INT4_1 NATIVE MUX Mux", int4_1_native_enum);
9882
9883static const struct snd_kcontrol_new rx_int0_1_mix_inp0_mux =
9884 SOC_DAPM_ENUM("RX INT0_1 MIX1 INP0 Mux", rx_int0_1_mix_inp0_chain_enum);
9885
9886static const struct snd_kcontrol_new rx_int0_1_mix_inp1_mux =
9887 SOC_DAPM_ENUM("RX INT0_1 MIX1 INP1 Mux", rx_int0_1_mix_inp1_chain_enum);
9888
9889static const struct snd_kcontrol_new rx_int0_1_mix_inp2_mux =
9890 SOC_DAPM_ENUM("RX INT0_1 MIX1 INP2 Mux", rx_int0_1_mix_inp2_chain_enum);
9891
9892static const struct snd_kcontrol_new rx_int1_1_mix_inp0_mux =
9893 SOC_DAPM_ENUM("RX INT1_1 MIX1 INP0 Mux", rx_int1_1_mix_inp0_chain_enum);
9894
9895static const struct snd_kcontrol_new rx_int1_1_mix_inp1_mux =
9896 SOC_DAPM_ENUM("RX INT1_1 MIX1 INP1 Mux", rx_int1_1_mix_inp1_chain_enum);
9897
9898static const struct snd_kcontrol_new rx_int1_1_mix_inp2_mux =
9899 SOC_DAPM_ENUM("RX INT1_1 MIX1 INP2 Mux", rx_int1_1_mix_inp2_chain_enum);
9900
9901static const struct snd_kcontrol_new rx_int2_1_mix_inp0_mux =
9902 SOC_DAPM_ENUM("RX INT2_1 MIX1 INP0 Mux", rx_int2_1_mix_inp0_chain_enum);
9903
9904static const struct snd_kcontrol_new rx_int2_1_mix_inp1_mux =
9905 SOC_DAPM_ENUM("RX INT2_1 MIX1 INP1 Mux", rx_int2_1_mix_inp1_chain_enum);
9906
9907static const struct snd_kcontrol_new rx_int2_1_mix_inp2_mux =
9908 SOC_DAPM_ENUM("RX INT2_1 MIX1 INP2 Mux", rx_int2_1_mix_inp2_chain_enum);
9909
9910static const struct snd_kcontrol_new rx_int3_1_mix_inp0_mux =
9911 SOC_DAPM_ENUM("RX INT3_1 MIX1 INP0 Mux", rx_int3_1_mix_inp0_chain_enum);
9912
9913static const struct snd_kcontrol_new rx_int3_1_mix_inp1_mux =
9914 SOC_DAPM_ENUM("RX INT3_1 MIX1 INP1 Mux", rx_int3_1_mix_inp1_chain_enum);
9915
9916static const struct snd_kcontrol_new rx_int3_1_mix_inp2_mux =
9917 SOC_DAPM_ENUM("RX INT3_1 MIX1 INP2 Mux", rx_int3_1_mix_inp2_chain_enum);
9918
9919static const struct snd_kcontrol_new rx_int4_1_mix_inp0_mux =
9920 SOC_DAPM_ENUM("RX INT4_1 MIX1 INP0 Mux", rx_int4_1_mix_inp0_chain_enum);
9921
9922static const struct snd_kcontrol_new rx_int4_1_mix_inp1_mux =
9923 SOC_DAPM_ENUM("RX INT4_1 MIX1 INP1 Mux", rx_int4_1_mix_inp1_chain_enum);
9924
9925static const struct snd_kcontrol_new rx_int4_1_mix_inp2_mux =
9926 SOC_DAPM_ENUM("RX INT4_1 MIX1 INP2 Mux", rx_int4_1_mix_inp2_chain_enum);
9927
9928static const struct snd_kcontrol_new rx_int5_1_mix_inp0_mux =
9929 SOC_DAPM_ENUM("RX INT5_1 MIX1 INP0 Mux", rx_int5_1_mix_inp0_chain_enum);
9930
9931static const struct snd_kcontrol_new rx_int5_1_mix_inp1_mux =
9932 SOC_DAPM_ENUM("RX INT5_1 MIX1 INP1 Mux", rx_int5_1_mix_inp1_chain_enum);
9933
9934static const struct snd_kcontrol_new rx_int5_1_mix_inp2_mux =
9935 SOC_DAPM_ENUM("RX INT5_1 MIX1 INP2 Mux", rx_int5_1_mix_inp2_chain_enum);
9936
9937static const struct snd_kcontrol_new rx_int6_1_mix_inp0_mux =
9938 SOC_DAPM_ENUM("RX INT6_1 MIX1 INP0 Mux", rx_int6_1_mix_inp0_chain_enum);
9939
9940static const struct snd_kcontrol_new rx_int6_1_mix_inp1_mux =
9941 SOC_DAPM_ENUM("RX INT6_1 MIX1 INP1 Mux", rx_int6_1_mix_inp1_chain_enum);
9942
9943static const struct snd_kcontrol_new rx_int6_1_mix_inp2_mux =
9944 SOC_DAPM_ENUM("RX INT6_1 MIX1 INP2 Mux", rx_int6_1_mix_inp2_chain_enum);
9945
9946static const struct snd_kcontrol_new rx_int7_1_mix_inp0_mux =
9947 SOC_DAPM_ENUM("RX INT7_1 MIX1 INP0 Mux", rx_int7_1_mix_inp0_chain_enum);
9948
9949static const struct snd_kcontrol_new rx_int7_1_mix_inp1_mux =
9950 SOC_DAPM_ENUM("RX INT7_1 MIX1 INP1 Mux", rx_int7_1_mix_inp1_chain_enum);
9951
9952static const struct snd_kcontrol_new rx_int7_1_mix_inp2_mux =
9953 SOC_DAPM_ENUM("RX INT7_1 MIX1 INP2 Mux", rx_int7_1_mix_inp2_chain_enum);
9954
9955static const struct snd_kcontrol_new rx_int8_1_mix_inp0_mux =
9956 SOC_DAPM_ENUM("RX INT8_1 MIX1 INP0 Mux", rx_int8_1_mix_inp0_chain_enum);
9957
9958static const struct snd_kcontrol_new rx_int8_1_mix_inp1_mux =
9959 SOC_DAPM_ENUM("RX INT8_1 MIX1 INP1 Mux", rx_int8_1_mix_inp1_chain_enum);
9960
9961static const struct snd_kcontrol_new rx_int8_1_mix_inp2_mux =
9962 SOC_DAPM_ENUM("RX INT8_1 MIX1 INP2 Mux", rx_int8_1_mix_inp2_chain_enum);
9963
9964static const struct snd_kcontrol_new rx_int0_mix2_inp_mux =
9965 SOC_DAPM_ENUM("RX INT0 MIX2 INP Mux", rx_int0_sidetone_mix_chain_enum);
9966
9967static const struct snd_kcontrol_new rx_int1_mix2_inp_mux =
9968 SOC_DAPM_ENUM("RX INT1 MIX2 INP Mux", rx_int1_sidetone_mix_chain_enum);
9969
9970static const struct snd_kcontrol_new rx_int2_mix2_inp_mux =
9971 SOC_DAPM_ENUM("RX INT2 MIX2 INP Mux", rx_int2_sidetone_mix_chain_enum);
9972
9973static const struct snd_kcontrol_new rx_int3_mix2_inp_mux =
9974 SOC_DAPM_ENUM("RX INT3 MIX2 INP Mux", rx_int3_sidetone_mix_chain_enum);
9975
9976static const struct snd_kcontrol_new rx_int4_mix2_inp_mux =
9977 SOC_DAPM_ENUM("RX INT4 MIX2 INP Mux", rx_int4_sidetone_mix_chain_enum);
9978
9979static const struct snd_kcontrol_new rx_int7_mix2_inp_mux =
9980 SOC_DAPM_ENUM("RX INT7 MIX2 INP Mux", rx_int7_sidetone_mix_chain_enum);
9981
9982static const struct snd_kcontrol_new tx_adc_mux0 =
9983 SOC_DAPM_ENUM_EXT("ADC MUX0 Mux", tx_adc_mux0_chain_enum,
9984 snd_soc_dapm_get_enum_double,
9985 tasha_put_dec_enum);
9986
9987static const struct snd_kcontrol_new tx_adc_mux1 =
9988 SOC_DAPM_ENUM_EXT("ADC MUX1 Mux", tx_adc_mux1_chain_enum,
9989 snd_soc_dapm_get_enum_double,
9990 tasha_put_dec_enum);
9991
9992static const struct snd_kcontrol_new tx_adc_mux2 =
9993 SOC_DAPM_ENUM_EXT("ADC MUX2 Mux", tx_adc_mux2_chain_enum,
9994 snd_soc_dapm_get_enum_double,
9995 tasha_put_dec_enum);
9996
9997static const struct snd_kcontrol_new tx_adc_mux3 =
9998 SOC_DAPM_ENUM_EXT("ADC MUX3 Mux", tx_adc_mux3_chain_enum,
9999 snd_soc_dapm_get_enum_double,
10000 tasha_put_dec_enum);
10001
10002static const struct snd_kcontrol_new tx_adc_mux4 =
10003 SOC_DAPM_ENUM_EXT("ADC MUX4 Mux", tx_adc_mux4_chain_enum,
10004 snd_soc_dapm_get_enum_double,
10005 tasha_put_dec_enum);
10006
10007static const struct snd_kcontrol_new tx_adc_mux5 =
10008 SOC_DAPM_ENUM_EXT("ADC MUX5 Mux", tx_adc_mux5_chain_enum,
10009 snd_soc_dapm_get_enum_double,
10010 tasha_put_dec_enum);
10011
10012static const struct snd_kcontrol_new tx_adc_mux6 =
10013 SOC_DAPM_ENUM_EXT("ADC MUX6 Mux", tx_adc_mux6_chain_enum,
10014 snd_soc_dapm_get_enum_double,
10015 tasha_put_dec_enum);
10016
10017static const struct snd_kcontrol_new tx_adc_mux7 =
10018 SOC_DAPM_ENUM_EXT("ADC MUX7 Mux", tx_adc_mux7_chain_enum,
10019 snd_soc_dapm_get_enum_double,
10020 tasha_put_dec_enum);
10021
10022static const struct snd_kcontrol_new tx_adc_mux8 =
10023 SOC_DAPM_ENUM_EXT("ADC MUX8 Mux", tx_adc_mux8_chain_enum,
10024 snd_soc_dapm_get_enum_double,
10025 tasha_put_dec_enum);
10026
10027static const struct snd_kcontrol_new tx_adc_mux10 =
10028 SOC_DAPM_ENUM("ADC MUX10 Mux", tx_adc_mux10_chain_enum);
10029
10030static const struct snd_kcontrol_new tx_adc_mux11 =
10031 SOC_DAPM_ENUM("ADC MUX11 Mux", tx_adc_mux11_chain_enum);
10032
10033static const struct snd_kcontrol_new tx_adc_mux12 =
10034 SOC_DAPM_ENUM("ADC MUX12 Mux", tx_adc_mux12_chain_enum);
10035
10036static const struct snd_kcontrol_new tx_adc_mux13 =
10037 SOC_DAPM_ENUM("ADC MUX13 Mux", tx_adc_mux13_chain_enum);
10038
10039static const struct snd_kcontrol_new tx_dmic_mux0 =
10040 SOC_DAPM_ENUM("DMIC MUX0 Mux", tx_dmic_mux0_enum);
10041
10042static const struct snd_kcontrol_new tx_dmic_mux1 =
10043 SOC_DAPM_ENUM("DMIC MUX1 Mux", tx_dmic_mux1_enum);
10044
10045static const struct snd_kcontrol_new tx_dmic_mux2 =
10046 SOC_DAPM_ENUM("DMIC MUX2 Mux", tx_dmic_mux2_enum);
10047
10048static const struct snd_kcontrol_new tx_dmic_mux3 =
10049 SOC_DAPM_ENUM("DMIC MUX3 Mux", tx_dmic_mux3_enum);
10050
10051static const struct snd_kcontrol_new tx_dmic_mux4 =
10052 SOC_DAPM_ENUM("DMIC MUX4 Mux", tx_dmic_mux4_enum);
10053
10054static const struct snd_kcontrol_new tx_dmic_mux5 =
10055 SOC_DAPM_ENUM("DMIC MUX5 Mux", tx_dmic_mux5_enum);
10056
10057static const struct snd_kcontrol_new tx_dmic_mux6 =
10058 SOC_DAPM_ENUM("DMIC MUX6 Mux", tx_dmic_mux6_enum);
10059
10060static const struct snd_kcontrol_new tx_dmic_mux7 =
10061 SOC_DAPM_ENUM("DMIC MUX7 Mux", tx_dmic_mux7_enum);
10062
10063static const struct snd_kcontrol_new tx_dmic_mux8 =
10064 SOC_DAPM_ENUM("DMIC MUX8 Mux", tx_dmic_mux8_enum);
10065
10066static const struct snd_kcontrol_new tx_dmic_mux10 =
10067 SOC_DAPM_ENUM("DMIC MUX10 Mux", tx_dmic_mux10_enum);
10068
10069static const struct snd_kcontrol_new tx_dmic_mux11 =
10070 SOC_DAPM_ENUM("DMIC MUX11 Mux", tx_dmic_mux11_enum);
10071
10072static const struct snd_kcontrol_new tx_dmic_mux12 =
10073 SOC_DAPM_ENUM("DMIC MUX12 Mux", tx_dmic_mux12_enum);
10074
10075static const struct snd_kcontrol_new tx_dmic_mux13 =
10076 SOC_DAPM_ENUM("DMIC MUX13 Mux", tx_dmic_mux13_enum);
10077
10078static const struct snd_kcontrol_new tx_amic_mux0 =
10079 SOC_DAPM_ENUM("AMIC MUX0 Mux", tx_amic_mux0_enum);
10080
10081static const struct snd_kcontrol_new tx_amic_mux1 =
10082 SOC_DAPM_ENUM("AMIC MUX1 Mux", tx_amic_mux1_enum);
10083
10084static const struct snd_kcontrol_new tx_amic_mux2 =
10085 SOC_DAPM_ENUM("AMIC MUX2 Mux", tx_amic_mux2_enum);
10086
10087static const struct snd_kcontrol_new tx_amic_mux3 =
10088 SOC_DAPM_ENUM("AMIC MUX3 Mux", tx_amic_mux3_enum);
10089
10090static const struct snd_kcontrol_new tx_amic_mux4 =
10091 SOC_DAPM_ENUM("AMIC MUX4 Mux", tx_amic_mux4_enum);
10092
10093static const struct snd_kcontrol_new tx_amic_mux5 =
10094 SOC_DAPM_ENUM("AMIC MUX5 Mux", tx_amic_mux5_enum);
10095
10096static const struct snd_kcontrol_new tx_amic_mux6 =
10097 SOC_DAPM_ENUM("AMIC MUX6 Mux", tx_amic_mux6_enum);
10098
10099static const struct snd_kcontrol_new tx_amic_mux7 =
10100 SOC_DAPM_ENUM("AMIC MUX7 Mux", tx_amic_mux7_enum);
10101
10102static const struct snd_kcontrol_new tx_amic_mux8 =
10103 SOC_DAPM_ENUM("AMIC MUX8 Mux", tx_amic_mux8_enum);
10104
10105static const struct snd_kcontrol_new tx_amic_mux10 =
10106 SOC_DAPM_ENUM("AMIC MUX10 Mux", tx_amic_mux10_enum);
10107
10108static const struct snd_kcontrol_new tx_amic_mux11 =
10109 SOC_DAPM_ENUM("AMIC MUX11 Mux", tx_amic_mux11_enum);
10110
10111static const struct snd_kcontrol_new tx_amic_mux12 =
10112 SOC_DAPM_ENUM("AMIC MUX12 Mux", tx_amic_mux12_enum);
10113
10114static const struct snd_kcontrol_new tx_amic_mux13 =
10115 SOC_DAPM_ENUM("AMIC MUX13 Mux", tx_amic_mux13_enum);
10116
10117static const struct snd_kcontrol_new sb_tx0_mux =
10118 SOC_DAPM_ENUM("SLIM TX0 MUX Mux", sb_tx0_mux_enum);
10119
10120static const struct snd_kcontrol_new sb_tx1_mux =
10121 SOC_DAPM_ENUM("SLIM TX1 MUX Mux", sb_tx1_mux_enum);
10122
10123static const struct snd_kcontrol_new sb_tx2_mux =
10124 SOC_DAPM_ENUM("SLIM TX2 MUX Mux", sb_tx2_mux_enum);
10125
10126static const struct snd_kcontrol_new sb_tx3_mux =
10127 SOC_DAPM_ENUM("SLIM TX3 MUX Mux", sb_tx3_mux_enum);
10128
10129static const struct snd_kcontrol_new sb_tx4_mux =
10130 SOC_DAPM_ENUM("SLIM TX4 MUX Mux", sb_tx4_mux_enum);
10131
10132static const struct snd_kcontrol_new sb_tx5_mux =
10133 SOC_DAPM_ENUM("SLIM TX5 MUX Mux", sb_tx5_mux_enum);
10134
10135static const struct snd_kcontrol_new sb_tx6_mux =
10136 SOC_DAPM_ENUM("SLIM TX6 MUX Mux", sb_tx6_mux_enum);
10137
10138static const struct snd_kcontrol_new sb_tx7_mux =
10139 SOC_DAPM_ENUM("SLIM TX7 MUX Mux", sb_tx7_mux_enum);
10140
10141static const struct snd_kcontrol_new sb_tx8_mux =
10142 SOC_DAPM_ENUM("SLIM TX8 MUX Mux", sb_tx8_mux_enum);
10143
10144static const struct snd_kcontrol_new sb_tx9_mux =
10145 SOC_DAPM_ENUM("SLIM TX9 MUX Mux", sb_tx9_mux_enum);
10146
10147static const struct snd_kcontrol_new sb_tx10_mux =
10148 SOC_DAPM_ENUM("SLIM TX10 MUX Mux", sb_tx10_mux_enum);
10149
10150static const struct snd_kcontrol_new sb_tx11_mux =
10151 SOC_DAPM_ENUM("SLIM TX11 MUX Mux", sb_tx11_mux_enum);
10152
10153static const struct snd_kcontrol_new sb_tx11_inp1_mux =
10154 SOC_DAPM_ENUM("SLIM TX11 INP1 MUX Mux", sb_tx11_inp1_mux_enum);
10155
10156static const struct snd_kcontrol_new sb_tx13_mux =
10157 SOC_DAPM_ENUM("SLIM TX13 MUX Mux", sb_tx13_mux_enum);
10158
10159static const struct snd_kcontrol_new tx13_inp_mux =
10160 SOC_DAPM_ENUM("TX13 INP MUX Mux", tx13_inp_mux_enum);
10161
10162static const struct snd_kcontrol_new rx_mix_tx0_mux =
10163 SOC_DAPM_ENUM("RX MIX TX0 MUX Mux", rx_mix_tx0_mux_enum);
10164
10165static const struct snd_kcontrol_new rx_mix_tx1_mux =
10166 SOC_DAPM_ENUM("RX MIX TX1 MUX Mux", rx_mix_tx1_mux_enum);
10167
10168static const struct snd_kcontrol_new rx_mix_tx2_mux =
10169 SOC_DAPM_ENUM("RX MIX TX2 MUX Mux", rx_mix_tx2_mux_enum);
10170
10171static const struct snd_kcontrol_new rx_mix_tx3_mux =
10172 SOC_DAPM_ENUM("RX MIX TX3 MUX Mux", rx_mix_tx3_mux_enum);
10173
10174static const struct snd_kcontrol_new rx_mix_tx4_mux =
10175 SOC_DAPM_ENUM("RX MIX TX4 MUX Mux", rx_mix_tx4_mux_enum);
10176
10177static const struct snd_kcontrol_new rx_mix_tx5_mux =
10178 SOC_DAPM_ENUM("RX MIX TX5 MUX Mux", rx_mix_tx5_mux_enum);
10179
10180static const struct snd_kcontrol_new rx_mix_tx6_mux =
10181 SOC_DAPM_ENUM("RX MIX TX6 MUX Mux", rx_mix_tx6_mux_enum);
10182
10183static const struct snd_kcontrol_new rx_mix_tx7_mux =
10184 SOC_DAPM_ENUM("RX MIX TX7 MUX Mux", rx_mix_tx7_mux_enum);
10185
10186static const struct snd_kcontrol_new rx_mix_tx8_mux =
10187 SOC_DAPM_ENUM("RX MIX TX8 MUX Mux", rx_mix_tx8_mux_enum);
10188
10189static const struct snd_kcontrol_new iir0_inp0_mux =
10190 SOC_DAPM_ENUM("IIR0 INP0 Mux", iir0_inp0_mux_enum);
10191
10192static const struct snd_kcontrol_new iir0_inp1_mux =
10193 SOC_DAPM_ENUM("IIR0 INP1 Mux", iir0_inp1_mux_enum);
10194
10195static const struct snd_kcontrol_new iir0_inp2_mux =
10196 SOC_DAPM_ENUM("IIR0 INP2 Mux", iir0_inp2_mux_enum);
10197
10198static const struct snd_kcontrol_new iir0_inp3_mux =
10199 SOC_DAPM_ENUM("IIR0 INP3 Mux", iir0_inp3_mux_enum);
10200
10201static const struct snd_kcontrol_new iir1_inp0_mux =
10202 SOC_DAPM_ENUM("IIR1 INP0 Mux", iir1_inp0_mux_enum);
10203
10204static const struct snd_kcontrol_new iir1_inp1_mux =
10205 SOC_DAPM_ENUM("IIR1 INP1 Mux", iir1_inp1_mux_enum);
10206
10207static const struct snd_kcontrol_new iir1_inp2_mux =
10208 SOC_DAPM_ENUM("IIR1 INP2 Mux", iir1_inp2_mux_enum);
10209
10210static const struct snd_kcontrol_new iir1_inp3_mux =
10211 SOC_DAPM_ENUM("IIR1 INP3 Mux", iir1_inp3_mux_enum);
10212
10213static const struct snd_kcontrol_new rx_int0_interp_mux =
10214 SOC_DAPM_ENUM("RX INT0 INTERP Mux", rx_int0_interp_mux_enum);
10215
10216static const struct snd_kcontrol_new rx_int1_interp_mux =
10217 SOC_DAPM_ENUM("RX INT1 INTERP Mux", rx_int1_interp_mux_enum);
10218
10219static const struct snd_kcontrol_new rx_int2_interp_mux =
10220 SOC_DAPM_ENUM("RX INT2 INTERP Mux", rx_int2_interp_mux_enum);
10221
10222static const struct snd_kcontrol_new rx_int3_interp_mux =
10223 SOC_DAPM_ENUM("RX INT3 INTERP Mux", rx_int3_interp_mux_enum);
10224
10225static const struct snd_kcontrol_new rx_int4_interp_mux =
10226 SOC_DAPM_ENUM("RX INT4 INTERP Mux", rx_int4_interp_mux_enum);
10227
10228static const struct snd_kcontrol_new rx_int5_interp_mux =
10229 SOC_DAPM_ENUM("RX INT5 INTERP Mux", rx_int5_interp_mux_enum);
10230
10231static const struct snd_kcontrol_new rx_int6_interp_mux =
10232 SOC_DAPM_ENUM("RX INT6 INTERP Mux", rx_int6_interp_mux_enum);
10233
10234static const struct snd_kcontrol_new rx_int7_interp_mux =
10235 SOC_DAPM_ENUM("RX INT7 INTERP Mux", rx_int7_interp_mux_enum);
10236
10237static const struct snd_kcontrol_new rx_int8_interp_mux =
10238 SOC_DAPM_ENUM("RX INT8 INTERP Mux", rx_int8_interp_mux_enum);
10239
10240static const struct snd_kcontrol_new mad_sel_mux =
10241 SOC_DAPM_ENUM("MAD_SEL MUX Mux", mad_sel_enum);
10242
10243static const struct snd_kcontrol_new aif4_mad_switch =
10244 SOC_DAPM_SINGLE("Switch", WCD9335_CPE_SS_CFG, 5, 1, 0);
10245
10246static const struct snd_kcontrol_new mad_brdcst_switch =
10247 SOC_DAPM_SINGLE("Switch", WCD9335_CPE_SS_CFG, 6, 1, 0);
10248
10249static const struct snd_kcontrol_new aif4_switch_mixer_controls =
10250 SOC_SINGLE_EXT("Switch", SND_SOC_NOPM,
10251 0, 1, 0, tasha_codec_aif4_mixer_switch_get,
10252 tasha_codec_aif4_mixer_switch_put);
10253
10254static const struct snd_kcontrol_new anc_hphl_switch =
10255 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
10256
10257static const struct snd_kcontrol_new anc_hphr_switch =
10258 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
10259
10260static const struct snd_kcontrol_new anc_ear_switch =
10261 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
10262
10263static const struct snd_kcontrol_new anc_ear_spkr_switch =
10264 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
10265
10266static const struct snd_kcontrol_new anc_lineout1_switch =
10267 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
10268
10269static const struct snd_kcontrol_new anc_lineout2_switch =
10270 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
10271
10272static const struct snd_kcontrol_new anc_spkr_pa_switch =
10273 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
10274
10275static const struct snd_kcontrol_new adc_us_mux0_switch =
10276 SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
10277
10278static const struct snd_kcontrol_new adc_us_mux1_switch =
10279 SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
10280
10281static const struct snd_kcontrol_new adc_us_mux2_switch =
10282 SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
10283
10284static const struct snd_kcontrol_new adc_us_mux3_switch =
10285 SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
10286
10287static const struct snd_kcontrol_new adc_us_mux4_switch =
10288 SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
10289
10290static const struct snd_kcontrol_new adc_us_mux5_switch =
10291 SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
10292
10293static const struct snd_kcontrol_new adc_us_mux6_switch =
10294 SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
10295
10296static const struct snd_kcontrol_new adc_us_mux7_switch =
10297 SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
10298
10299static const struct snd_kcontrol_new adc_us_mux8_switch =
10300 SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
10301
10302static const struct snd_kcontrol_new anc0_fb_mux =
10303 SOC_DAPM_ENUM("ANC0 FB MUX Mux", anc0_fb_mux_enum);
10304
10305static const struct snd_kcontrol_new anc1_fb_mux =
10306 SOC_DAPM_ENUM("ANC1 FB MUX Mux", anc1_fb_mux_enum);
10307
10308static int tasha_codec_ec_buf_mux_enable(struct snd_soc_dapm_widget *w,
10309 struct snd_kcontrol *kcontrol,
10310 int event)
10311{
10312 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
10313
10314 dev_dbg(codec->dev, "%s: event = %d name = %s\n",
10315 __func__, event, w->name);
10316
10317 switch (event) {
10318 case SND_SOC_DAPM_POST_PMU:
10319 snd_soc_write(codec, WCD9335_CPE_SS_EC_BUF_INT_PERIOD, 0x3B);
10320 snd_soc_update_bits(codec, WCD9335_CPE_SS_CFG, 0x08, 0x08);
10321 snd_soc_update_bits(codec, WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0,
10322 0x08, 0x08);
10323 break;
10324 case SND_SOC_DAPM_POST_PMD:
10325 snd_soc_update_bits(codec, WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0,
10326 0x08, 0x00);
10327 snd_soc_update_bits(codec, WCD9335_CPE_SS_CFG, 0x08, 0x00);
10328 snd_soc_write(codec, WCD9335_CPE_SS_EC_BUF_INT_PERIOD, 0x00);
10329 break;
10330 }
10331
10332 return 0;
10333};
10334
10335static const char * const ec_buf_mux_text[] = {
10336 "ZERO", "RXMIXEC", "SB_RX0", "SB_RX1", "SB_RX2", "SB_RX3",
10337 "I2S_RX_SD0_L", "I2S_RX_SD0_R", "I2S_RX_SD1_L", "I2S_RX_SD1_R",
10338 "DEC1"
10339};
10340
10341static SOC_ENUM_SINGLE_DECL(ec_buf_mux_enum, WCD9335_CPE_SS_US_EC_MUX_CFG,
10342 0, ec_buf_mux_text);
10343
10344static const struct snd_kcontrol_new ec_buf_mux =
10345 SOC_DAPM_ENUM("EC BUF Mux", ec_buf_mux_enum);
10346
10347static const struct snd_soc_dapm_widget tasha_dapm_widgets[] = {
10348 SND_SOC_DAPM_OUTPUT("EAR"),
10349 SND_SOC_DAPM_OUTPUT("ANC EAR"),
10350 SND_SOC_DAPM_AIF_IN_E("AIF1 PB", "AIF1 Playback", 0, SND_SOC_NOPM,
10351 AIF1_PB, 0, tasha_codec_enable_slimrx,
10352 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD |
10353 SND_SOC_DAPM_POST_PMD),
10354 SND_SOC_DAPM_AIF_IN_E("AIF2 PB", "AIF2 Playback", 0, SND_SOC_NOPM,
10355 AIF2_PB, 0, tasha_codec_enable_slimrx,
10356 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD |
10357 SND_SOC_DAPM_POST_PMD),
10358 SND_SOC_DAPM_AIF_IN_E("AIF3 PB", "AIF3 Playback", 0, SND_SOC_NOPM,
10359 AIF3_PB, 0, tasha_codec_enable_slimrx,
10360 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD |
10361 SND_SOC_DAPM_POST_PMD),
10362 SND_SOC_DAPM_AIF_IN_E("AIF4 PB", "AIF4 Playback", 0, SND_SOC_NOPM,
10363 AIF4_PB, 0, tasha_codec_enable_slimrx,
10364 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD |
10365 SND_SOC_DAPM_POST_PMD),
10366 SND_SOC_DAPM_AIF_IN_E("AIF MIX1 PB", "AIF Mix Playback", 0,
10367 SND_SOC_NOPM, AIF_MIX1_PB, 0,
10368 tasha_codec_enable_slimrx,
10369 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD |
10370 SND_SOC_DAPM_POST_PMD),
10371
10372 SND_SOC_DAPM_MUX("SLIM RX0 MUX", SND_SOC_NOPM, TASHA_RX0, 0,
10373 &slim_rx_mux[TASHA_RX0]),
10374 SND_SOC_DAPM_MUX("SLIM RX1 MUX", SND_SOC_NOPM, TASHA_RX1, 0,
10375 &slim_rx_mux[TASHA_RX1]),
10376 SND_SOC_DAPM_MUX("SLIM RX2 MUX", SND_SOC_NOPM, TASHA_RX2, 0,
10377 &slim_rx_mux[TASHA_RX2]),
10378 SND_SOC_DAPM_MUX("SLIM RX3 MUX", SND_SOC_NOPM, TASHA_RX3, 0,
10379 &slim_rx_mux[TASHA_RX3]),
10380 SND_SOC_DAPM_MUX("SLIM RX4 MUX", SND_SOC_NOPM, TASHA_RX4, 0,
10381 &slim_rx_mux[TASHA_RX4]),
10382 SND_SOC_DAPM_MUX("SLIM RX5 MUX", SND_SOC_NOPM, TASHA_RX5, 0,
10383 &slim_rx_mux[TASHA_RX5]),
10384 SND_SOC_DAPM_MUX("SLIM RX6 MUX", SND_SOC_NOPM, TASHA_RX6, 0,
10385 &slim_rx_mux[TASHA_RX6]),
10386 SND_SOC_DAPM_MUX("SLIM RX7 MUX", SND_SOC_NOPM, TASHA_RX7, 0,
10387 &slim_rx_mux[TASHA_RX7]),
10388
10389 SND_SOC_DAPM_MIXER("SLIM RX0", SND_SOC_NOPM, 0, 0, NULL, 0),
10390 SND_SOC_DAPM_MIXER("SLIM RX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10391 SND_SOC_DAPM_MIXER("SLIM RX2", SND_SOC_NOPM, 0, 0, NULL, 0),
10392 SND_SOC_DAPM_MIXER("SLIM RX3", SND_SOC_NOPM, 0, 0, NULL, 0),
10393 SND_SOC_DAPM_MIXER("SLIM RX4", SND_SOC_NOPM, 0, 0, NULL, 0),
10394 SND_SOC_DAPM_MIXER("SLIM RX5", SND_SOC_NOPM, 0, 0, NULL, 0),
10395 SND_SOC_DAPM_MIXER("SLIM RX6", SND_SOC_NOPM, 0, 0, NULL, 0),
10396 SND_SOC_DAPM_MIXER("SLIM RX7", SND_SOC_NOPM, 0, 0, NULL, 0),
10397
10398 SND_SOC_DAPM_MUX_E("SPL SRC0 MUX", SND_SOC_NOPM, SPLINE_SRC0, 0,
10399 &spl_src0_mux, tasha_codec_enable_spline_resampler,
10400 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10401 SND_SOC_DAPM_MUX_E("SPL SRC1 MUX", SND_SOC_NOPM, SPLINE_SRC1, 0,
10402 &spl_src1_mux, tasha_codec_enable_spline_resampler,
10403 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10404 SND_SOC_DAPM_MUX_E("SPL SRC2 MUX", SND_SOC_NOPM, SPLINE_SRC2, 0,
10405 &spl_src2_mux, tasha_codec_enable_spline_resampler,
10406 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10407 SND_SOC_DAPM_MUX_E("SPL SRC3 MUX", SND_SOC_NOPM, SPLINE_SRC3, 0,
10408 &spl_src3_mux, tasha_codec_enable_spline_resampler,
10409 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10410
10411 SND_SOC_DAPM_MUX_E("RX INT0_2 MUX", WCD9335_CDC_RX0_RX_PATH_MIX_CTL,
10412 5, 0, &rx_int0_2_mux, tasha_codec_enable_mix_path,
10413 SND_SOC_DAPM_POST_PMU),
10414 SND_SOC_DAPM_MUX_E("RX INT1_2 MUX", WCD9335_CDC_RX1_RX_PATH_MIX_CTL,
10415 5, 0, &rx_int1_2_mux, tasha_codec_enable_mix_path,
10416 SND_SOC_DAPM_POST_PMU),
10417 SND_SOC_DAPM_MUX_E("RX INT2_2 MUX", WCD9335_CDC_RX2_RX_PATH_MIX_CTL,
10418 5, 0, &rx_int2_2_mux, tasha_codec_enable_mix_path,
10419 SND_SOC_DAPM_POST_PMU),
10420 SND_SOC_DAPM_MUX_E("RX INT3_2 MUX", WCD9335_CDC_RX3_RX_PATH_MIX_CTL,
10421 5, 0, &rx_int3_2_mux, tasha_codec_enable_mix_path,
10422 SND_SOC_DAPM_POST_PMU),
10423 SND_SOC_DAPM_MUX_E("RX INT4_2 MUX", WCD9335_CDC_RX4_RX_PATH_MIX_CTL,
10424 5, 0, &rx_int4_2_mux, tasha_codec_enable_mix_path,
10425 SND_SOC_DAPM_POST_PMU),
10426 SND_SOC_DAPM_MUX_E("RX INT5_2 MUX", WCD9335_CDC_RX5_RX_PATH_MIX_CTL,
10427 5, 0, &rx_int5_2_mux, tasha_codec_enable_mix_path,
10428 SND_SOC_DAPM_POST_PMU),
10429 SND_SOC_DAPM_MUX_E("RX INT6_2 MUX", WCD9335_CDC_RX6_RX_PATH_MIX_CTL,
10430 5, 0, &rx_int6_2_mux, tasha_codec_enable_mix_path,
10431 SND_SOC_DAPM_POST_PMU),
10432 SND_SOC_DAPM_MUX_E("RX INT7_2 MUX", WCD9335_CDC_RX7_RX_PATH_MIX_CTL,
10433 5, 0, &rx_int7_2_mux, tasha_codec_enable_mix_path,
10434 SND_SOC_DAPM_POST_PMU),
10435 SND_SOC_DAPM_MUX_E("RX INT8_2 MUX", WCD9335_CDC_RX8_RX_PATH_MIX_CTL,
10436 5, 0, &rx_int8_2_mux, tasha_codec_enable_mix_path,
10437 SND_SOC_DAPM_POST_PMU),
10438
10439 SND_SOC_DAPM_MUX("RX INT0_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
10440 &rx_int0_1_mix_inp0_mux),
10441 SND_SOC_DAPM_MUX("RX INT0_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
10442 &rx_int0_1_mix_inp1_mux),
10443 SND_SOC_DAPM_MUX("RX INT0_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
10444 &rx_int0_1_mix_inp2_mux),
10445 SND_SOC_DAPM_MUX("RX INT1_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
10446 &rx_int1_1_mix_inp0_mux),
10447 SND_SOC_DAPM_MUX("RX INT1_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
10448 &rx_int1_1_mix_inp1_mux),
10449 SND_SOC_DAPM_MUX("RX INT1_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
10450 &rx_int1_1_mix_inp2_mux),
10451 SND_SOC_DAPM_MUX("RX INT2_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
10452 &rx_int2_1_mix_inp0_mux),
10453 SND_SOC_DAPM_MUX("RX INT2_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
10454 &rx_int2_1_mix_inp1_mux),
10455 SND_SOC_DAPM_MUX("RX INT2_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
10456 &rx_int2_1_mix_inp2_mux),
10457 SND_SOC_DAPM_MUX("RX INT3_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
10458 &rx_int3_1_mix_inp0_mux),
10459 SND_SOC_DAPM_MUX("RX INT3_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
10460 &rx_int3_1_mix_inp1_mux),
10461 SND_SOC_DAPM_MUX("RX INT3_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
10462 &rx_int3_1_mix_inp2_mux),
10463 SND_SOC_DAPM_MUX("RX INT4_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
10464 &rx_int4_1_mix_inp0_mux),
10465 SND_SOC_DAPM_MUX("RX INT4_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
10466 &rx_int4_1_mix_inp1_mux),
10467 SND_SOC_DAPM_MUX("RX INT4_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
10468 &rx_int4_1_mix_inp2_mux),
10469 SND_SOC_DAPM_MUX("RX INT5_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
10470 &rx_int5_1_mix_inp0_mux),
10471 SND_SOC_DAPM_MUX("RX INT5_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
10472 &rx_int5_1_mix_inp1_mux),
10473 SND_SOC_DAPM_MUX("RX INT5_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
10474 &rx_int5_1_mix_inp2_mux),
10475 SND_SOC_DAPM_MUX("RX INT6_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
10476 &rx_int6_1_mix_inp0_mux),
10477 SND_SOC_DAPM_MUX("RX INT6_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
10478 &rx_int6_1_mix_inp1_mux),
10479 SND_SOC_DAPM_MUX("RX INT6_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
10480 &rx_int6_1_mix_inp2_mux),
10481 SND_SOC_DAPM_MUX_E("RX INT7_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
10482 &rx_int7_1_mix_inp0_mux, tasha_codec_enable_swr,
10483 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10484 SND_SOC_DAPM_MUX_E("RX INT7_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
10485 &rx_int7_1_mix_inp1_mux, tasha_codec_enable_swr,
10486 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10487 SND_SOC_DAPM_MUX_E("RX INT7_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
10488 &rx_int7_1_mix_inp2_mux, tasha_codec_enable_swr,
10489 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10490 SND_SOC_DAPM_MUX_E("RX INT8_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
10491 &rx_int8_1_mix_inp0_mux, tasha_codec_enable_swr,
10492 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10493 SND_SOC_DAPM_MUX_E("RX INT8_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
10494 &rx_int8_1_mix_inp1_mux, tasha_codec_enable_swr,
10495 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10496 SND_SOC_DAPM_MUX_E("RX INT8_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
10497 &rx_int8_1_mix_inp2_mux, tasha_codec_enable_swr,
10498 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10499
10500 SND_SOC_DAPM_MIXER("RX INT0_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10501 SND_SOC_DAPM_MIXER("RX INT0 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
10502 SND_SOC_DAPM_MIXER("RX INT1_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10503 SND_SOC_DAPM_MIXER("RX INT1 SPLINE MIX", SND_SOC_NOPM, 0, 0,
10504 rx_int1_spline_mix_switch,
10505 ARRAY_SIZE(rx_int1_spline_mix_switch)),
10506 SND_SOC_DAPM_MIXER("RX INT1 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
10507 SND_SOC_DAPM_MIXER("RX INT2_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10508 SND_SOC_DAPM_MIXER("RX INT2 SPLINE MIX", SND_SOC_NOPM, 0, 0,
10509 rx_int2_spline_mix_switch,
10510 ARRAY_SIZE(rx_int2_spline_mix_switch)),
10511 SND_SOC_DAPM_MIXER("RX INT2 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
10512 SND_SOC_DAPM_MIXER("RX INT3_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10513 SND_SOC_DAPM_MIXER("RX INT3 SPLINE MIX", SND_SOC_NOPM, 0, 0,
10514 rx_int3_spline_mix_switch,
10515 ARRAY_SIZE(rx_int3_spline_mix_switch)),
10516 SND_SOC_DAPM_MIXER("RX INT3 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
10517 SND_SOC_DAPM_MIXER("RX INT4_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10518 SND_SOC_DAPM_MIXER("RX INT4 SPLINE MIX", SND_SOC_NOPM, 0, 0,
10519 rx_int4_spline_mix_switch,
10520 ARRAY_SIZE(rx_int4_spline_mix_switch)),
10521 SND_SOC_DAPM_MIXER("RX INT4 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
10522 SND_SOC_DAPM_MIXER("RX INT5_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10523 SND_SOC_DAPM_MIXER("RX INT5 SPLINE MIX", SND_SOC_NOPM, 0, 0,
10524 rx_int5_spline_mix_switch,
10525 ARRAY_SIZE(rx_int5_spline_mix_switch)),
10526 SND_SOC_DAPM_MIXER("RX INT5 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
10527
10528 SND_SOC_DAPM_MIXER("RX INT6_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10529 SND_SOC_DAPM_MIXER("RX INT6 SPLINE MIX", SND_SOC_NOPM, 0, 0,
10530 rx_int6_spline_mix_switch,
10531 ARRAY_SIZE(rx_int6_spline_mix_switch)),
10532 SND_SOC_DAPM_MIXER("RX INT6 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
10533
10534 SND_SOC_DAPM_MIXER("RX INT7_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10535 SND_SOC_DAPM_MIXER("RX INT7 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
10536 SND_SOC_DAPM_MIXER("RX INT7 SPLINE MIX", SND_SOC_NOPM, 0, 0,
10537 rx_int7_spline_mix_switch,
10538 ARRAY_SIZE(rx_int7_spline_mix_switch)),
10539
10540 SND_SOC_DAPM_MIXER("RX INT8_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10541 SND_SOC_DAPM_MIXER("RX INT8 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
10542 SND_SOC_DAPM_MIXER("RX INT8 SPLINE MIX", SND_SOC_NOPM, 0, 0,
10543 rx_int8_spline_mix_switch,
10544 ARRAY_SIZE(rx_int8_spline_mix_switch)),
10545
10546 SND_SOC_DAPM_MIXER("RX INT0 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
10547 SND_SOC_DAPM_MIXER("RX INT1 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
10548 SND_SOC_DAPM_MIXER("RX INT2 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
10549 SND_SOC_DAPM_MIXER("RX INT3 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
10550 SND_SOC_DAPM_MIXER("RX INT4 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
10551 SND_SOC_DAPM_MIXER("RX INT5 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
10552 SND_SOC_DAPM_MIXER("RX INT6 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
10553 SND_SOC_DAPM_MIXER("RX INT7 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
10554 SND_SOC_DAPM_MIXER_E("RX INT7 CHAIN", SND_SOC_NOPM, 0, 0,
10555 NULL, 0, tasha_codec_spk_boost_event,
10556 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10557 SND_SOC_DAPM_MIXER_E("RX INT8 CHAIN", SND_SOC_NOPM, 0, 0,
10558 NULL, 0, tasha_codec_spk_boost_event,
10559 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10560
10561 SND_SOC_DAPM_MIXER_E("RX INT5 VBAT", SND_SOC_NOPM, 0, 0,
10562 rx_int5_vbat_mix_switch,
10563 ARRAY_SIZE(rx_int5_vbat_mix_switch),
10564 tasha_codec_vbat_enable_event,
10565 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10566 SND_SOC_DAPM_MIXER_E("RX INT6 VBAT", SND_SOC_NOPM, 0, 0,
10567 rx_int6_vbat_mix_switch,
10568 ARRAY_SIZE(rx_int6_vbat_mix_switch),
10569 tasha_codec_vbat_enable_event,
10570 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10571 SND_SOC_DAPM_MIXER_E("RX INT7 VBAT", SND_SOC_NOPM, 0, 0,
10572 rx_int7_vbat_mix_switch,
10573 ARRAY_SIZE(rx_int7_vbat_mix_switch),
10574 tasha_codec_vbat_enable_event,
10575 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10576 SND_SOC_DAPM_MIXER_E("RX INT8 VBAT", SND_SOC_NOPM, 0, 0,
10577 rx_int8_vbat_mix_switch,
10578 ARRAY_SIZE(rx_int8_vbat_mix_switch),
10579 tasha_codec_vbat_enable_event,
10580 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10581
10582 SND_SOC_DAPM_MUX("RX INT0 MIX2 INP", WCD9335_CDC_RX0_RX_PATH_CFG1, 4,
10583 0, &rx_int0_mix2_inp_mux),
10584 SND_SOC_DAPM_MUX("RX INT1 MIX2 INP", WCD9335_CDC_RX1_RX_PATH_CFG1, 4,
10585 0, &rx_int1_mix2_inp_mux),
10586 SND_SOC_DAPM_MUX("RX INT2 MIX2 INP", WCD9335_CDC_RX2_RX_PATH_CFG1, 4,
10587 0, &rx_int2_mix2_inp_mux),
10588 SND_SOC_DAPM_MUX("RX INT3 MIX2 INP", WCD9335_CDC_RX3_RX_PATH_CFG1, 4,
10589 0, &rx_int3_mix2_inp_mux),
10590 SND_SOC_DAPM_MUX("RX INT4 MIX2 INP", WCD9335_CDC_RX4_RX_PATH_CFG1, 4,
10591 0, &rx_int4_mix2_inp_mux),
10592 SND_SOC_DAPM_MUX("RX INT7 MIX2 INP", WCD9335_CDC_RX7_RX_PATH_CFG1, 4,
10593 0, &rx_int7_mix2_inp_mux),
10594
10595 SND_SOC_DAPM_MUX("SLIM TX0 MUX", SND_SOC_NOPM, TASHA_TX0, 0,
10596 &sb_tx0_mux),
10597 SND_SOC_DAPM_MUX("SLIM TX1 MUX", SND_SOC_NOPM, TASHA_TX1, 0,
10598 &sb_tx1_mux),
10599 SND_SOC_DAPM_MUX("SLIM TX2 MUX", SND_SOC_NOPM, TASHA_TX2, 0,
10600 &sb_tx2_mux),
10601 SND_SOC_DAPM_MUX("SLIM TX3 MUX", SND_SOC_NOPM, TASHA_TX3, 0,
10602 &sb_tx3_mux),
10603 SND_SOC_DAPM_MUX("SLIM TX4 MUX", SND_SOC_NOPM, TASHA_TX4, 0,
10604 &sb_tx4_mux),
10605 SND_SOC_DAPM_MUX("SLIM TX5 MUX", SND_SOC_NOPM, TASHA_TX5, 0,
10606 &sb_tx5_mux),
10607 SND_SOC_DAPM_MUX("SLIM TX6 MUX", SND_SOC_NOPM, TASHA_TX6, 0,
10608 &sb_tx6_mux),
10609 SND_SOC_DAPM_MUX("SLIM TX7 MUX", SND_SOC_NOPM, TASHA_TX7, 0,
10610 &sb_tx7_mux),
10611 SND_SOC_DAPM_MUX("SLIM TX8 MUX", SND_SOC_NOPM, TASHA_TX8, 0,
10612 &sb_tx8_mux),
10613 SND_SOC_DAPM_MUX("SLIM TX9 MUX", SND_SOC_NOPM, TASHA_TX9, 0,
10614 &sb_tx9_mux),
10615 SND_SOC_DAPM_MUX("SLIM TX10 MUX", SND_SOC_NOPM, TASHA_TX10, 0,
10616 &sb_tx10_mux),
10617 SND_SOC_DAPM_MUX("SLIM TX11 MUX", SND_SOC_NOPM, TASHA_TX11, 0,
10618 &sb_tx11_mux),
10619 SND_SOC_DAPM_MUX("SLIM TX11 INP1 MUX", SND_SOC_NOPM, TASHA_TX11, 0,
10620 &sb_tx11_inp1_mux),
10621 SND_SOC_DAPM_MUX("SLIM TX13 MUX", SND_SOC_NOPM, TASHA_TX13, 0,
10622 &sb_tx13_mux),
10623 SND_SOC_DAPM_MUX("TX13 INP MUX", SND_SOC_NOPM, 0, 0,
10624 &tx13_inp_mux),
10625
10626 SND_SOC_DAPM_MUX_E("ADC MUX0", WCD9335_CDC_TX0_TX_PATH_CTL, 5, 0,
10627 &tx_adc_mux0, tasha_codec_enable_dec,
10628 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10629 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
10630
10631 SND_SOC_DAPM_MUX_E("ADC MUX1", WCD9335_CDC_TX1_TX_PATH_CTL, 5, 0,
10632 &tx_adc_mux1, tasha_codec_enable_dec,
10633 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10634 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
10635
10636 SND_SOC_DAPM_MUX_E("ADC MUX2", WCD9335_CDC_TX2_TX_PATH_CTL, 5, 0,
10637 &tx_adc_mux2, tasha_codec_enable_dec,
10638 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10639 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
10640
10641 SND_SOC_DAPM_MUX_E("ADC MUX3", WCD9335_CDC_TX3_TX_PATH_CTL, 5, 0,
10642 &tx_adc_mux3, tasha_codec_enable_dec,
10643 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10644 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
10645
10646 SND_SOC_DAPM_MUX_E("ADC MUX4", WCD9335_CDC_TX4_TX_PATH_CTL, 5, 0,
10647 &tx_adc_mux4, tasha_codec_enable_dec,
10648 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10649 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
10650
10651 SND_SOC_DAPM_MUX_E("ADC MUX5", WCD9335_CDC_TX5_TX_PATH_CTL, 5, 0,
10652 &tx_adc_mux5, tasha_codec_enable_dec,
10653 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10654 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
10655
10656 SND_SOC_DAPM_MUX_E("ADC MUX6", WCD9335_CDC_TX6_TX_PATH_CTL, 5, 0,
10657 &tx_adc_mux6, tasha_codec_enable_dec,
10658 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10659 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
10660
10661 SND_SOC_DAPM_MUX_E("ADC MUX7", WCD9335_CDC_TX7_TX_PATH_CTL, 5, 0,
10662 &tx_adc_mux7, tasha_codec_enable_dec,
10663 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10664 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
10665
10666 SND_SOC_DAPM_MUX_E("ADC MUX8", WCD9335_CDC_TX8_TX_PATH_CTL, 5, 0,
10667 &tx_adc_mux8, tasha_codec_enable_dec,
10668 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10669 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
10670
10671 SND_SOC_DAPM_MUX_E("ADC MUX10", SND_SOC_NOPM, 10, 0,
10672 &tx_adc_mux10, tasha_codec_tx_adc_cfg,
10673 SND_SOC_DAPM_POST_PMU),
10674
10675 SND_SOC_DAPM_MUX_E("ADC MUX11", SND_SOC_NOPM, 11, 0,
10676 &tx_adc_mux11, tasha_codec_tx_adc_cfg,
10677 SND_SOC_DAPM_POST_PMU),
10678
10679 SND_SOC_DAPM_MUX_E("ADC MUX12", SND_SOC_NOPM, 12, 0,
10680 &tx_adc_mux12, tasha_codec_tx_adc_cfg,
10681 SND_SOC_DAPM_POST_PMU),
10682
10683 SND_SOC_DAPM_MUX_E("ADC MUX13", SND_SOC_NOPM, 13, 0,
10684 &tx_adc_mux13, tasha_codec_tx_adc_cfg,
10685 SND_SOC_DAPM_POST_PMU),
10686
10687 SND_SOC_DAPM_MUX("DMIC MUX0", SND_SOC_NOPM, 0, 0,
10688 &tx_dmic_mux0),
10689 SND_SOC_DAPM_MUX("DMIC MUX1", SND_SOC_NOPM, 0, 0,
10690 &tx_dmic_mux1),
10691 SND_SOC_DAPM_MUX("DMIC MUX2", SND_SOC_NOPM, 0, 0,
10692 &tx_dmic_mux2),
10693 SND_SOC_DAPM_MUX("DMIC MUX3", SND_SOC_NOPM, 0, 0,
10694 &tx_dmic_mux3),
10695 SND_SOC_DAPM_MUX("DMIC MUX4", SND_SOC_NOPM, 0, 0,
10696 &tx_dmic_mux4),
10697 SND_SOC_DAPM_MUX("DMIC MUX5", SND_SOC_NOPM, 0, 0,
10698 &tx_dmic_mux5),
10699 SND_SOC_DAPM_MUX("DMIC MUX6", SND_SOC_NOPM, 0, 0,
10700 &tx_dmic_mux6),
10701 SND_SOC_DAPM_MUX("DMIC MUX7", SND_SOC_NOPM, 0, 0,
10702 &tx_dmic_mux7),
10703 SND_SOC_DAPM_MUX("DMIC MUX8", SND_SOC_NOPM, 0, 0,
10704 &tx_dmic_mux8),
10705 SND_SOC_DAPM_MUX("DMIC MUX10", SND_SOC_NOPM, 0, 0,
10706 &tx_dmic_mux10),
10707 SND_SOC_DAPM_MUX("DMIC MUX11", SND_SOC_NOPM, 0, 0,
10708 &tx_dmic_mux11),
10709 SND_SOC_DAPM_MUX("DMIC MUX12", SND_SOC_NOPM, 0, 0,
10710 &tx_dmic_mux12),
10711 SND_SOC_DAPM_MUX("DMIC MUX13", SND_SOC_NOPM, 0, 0,
10712 &tx_dmic_mux13),
10713
10714 SND_SOC_DAPM_MUX("AMIC MUX0", SND_SOC_NOPM, 0, 0,
10715 &tx_amic_mux0),
10716 SND_SOC_DAPM_MUX("AMIC MUX1", SND_SOC_NOPM, 0, 0,
10717 &tx_amic_mux1),
10718 SND_SOC_DAPM_MUX("AMIC MUX2", SND_SOC_NOPM, 0, 0,
10719 &tx_amic_mux2),
10720 SND_SOC_DAPM_MUX("AMIC MUX3", SND_SOC_NOPM, 0, 0,
10721 &tx_amic_mux3),
10722 SND_SOC_DAPM_MUX("AMIC MUX4", SND_SOC_NOPM, 0, 0,
10723 &tx_amic_mux4),
10724 SND_SOC_DAPM_MUX("AMIC MUX5", SND_SOC_NOPM, 0, 0,
10725 &tx_amic_mux5),
10726 SND_SOC_DAPM_MUX("AMIC MUX6", SND_SOC_NOPM, 0, 0,
10727 &tx_amic_mux6),
10728 SND_SOC_DAPM_MUX("AMIC MUX7", SND_SOC_NOPM, 0, 0,
10729 &tx_amic_mux7),
10730 SND_SOC_DAPM_MUX("AMIC MUX8", SND_SOC_NOPM, 0, 0,
10731 &tx_amic_mux8),
10732 SND_SOC_DAPM_MUX("AMIC MUX10", SND_SOC_NOPM, 0, 0,
10733 &tx_amic_mux10),
10734 SND_SOC_DAPM_MUX("AMIC MUX11", SND_SOC_NOPM, 0, 0,
10735 &tx_amic_mux11),
10736 SND_SOC_DAPM_MUX("AMIC MUX12", SND_SOC_NOPM, 0, 0,
10737 &tx_amic_mux12),
10738 SND_SOC_DAPM_MUX("AMIC MUX13", SND_SOC_NOPM, 0, 0,
10739 &tx_amic_mux13),
10740
10741 SND_SOC_DAPM_ADC_E("ADC1", NULL, WCD9335_ANA_AMIC1, 7, 0,
10742 tasha_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
10743 SND_SOC_DAPM_ADC_E("ADC2", NULL, WCD9335_ANA_AMIC2, 7, 0,
10744 tasha_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
10745 SND_SOC_DAPM_ADC_E("ADC3", NULL, WCD9335_ANA_AMIC3, 7, 0,
10746 tasha_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
10747 SND_SOC_DAPM_ADC_E("ADC4", NULL, WCD9335_ANA_AMIC4, 7, 0,
10748 tasha_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
10749 SND_SOC_DAPM_ADC_E("ADC5", NULL, WCD9335_ANA_AMIC5, 7, 0,
10750 tasha_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
10751 SND_SOC_DAPM_ADC_E("ADC6", NULL, WCD9335_ANA_AMIC6, 7, 0,
10752 tasha_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
10753
10754 SND_SOC_DAPM_SUPPLY("RX INT1 NATIVE SUPPLY", SND_SOC_NOPM,
10755 INTERP_HPHL, 0, tasha_enable_native_supply,
10756 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
10757
10758 SND_SOC_DAPM_SUPPLY("RX INT2 NATIVE SUPPLY", SND_SOC_NOPM,
10759 INTERP_HPHR, 0, tasha_enable_native_supply,
10760 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
10761
10762 SND_SOC_DAPM_SUPPLY("RX INT3 NATIVE SUPPLY", SND_SOC_NOPM,
10763 INTERP_LO1, 0, tasha_enable_native_supply,
10764 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
10765
10766 SND_SOC_DAPM_SUPPLY("RX INT4 NATIVE SUPPLY", SND_SOC_NOPM,
10767 INTERP_LO2, 0, tasha_enable_native_supply,
10768 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
10769
10770 SND_SOC_DAPM_INPUT("AMIC1"),
10771 SND_SOC_DAPM_MICBIAS_E("MIC BIAS1", SND_SOC_NOPM, 0, 0,
10772 tasha_codec_enable_micbias,
10773 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10774 SND_SOC_DAPM_POST_PMD),
10775 SND_SOC_DAPM_MICBIAS_E("MIC BIAS2", SND_SOC_NOPM, 0, 0,
10776 tasha_codec_enable_micbias,
10777 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10778 SND_SOC_DAPM_POST_PMD),
10779 SND_SOC_DAPM_MICBIAS_E("MIC BIAS3", SND_SOC_NOPM, 0, 0,
10780 tasha_codec_enable_micbias,
10781 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10782 SND_SOC_DAPM_POST_PMD),
10783 SND_SOC_DAPM_MICBIAS_E("MIC BIAS4", SND_SOC_NOPM, 0, 0,
10784 tasha_codec_enable_micbias,
10785 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10786 SND_SOC_DAPM_POST_PMD),
10787
10788 SND_SOC_DAPM_MICBIAS_E(DAPM_MICBIAS1_STANDALONE, SND_SOC_NOPM, 0, 0,
10789 tasha_codec_force_enable_micbias,
10790 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10791 SND_SOC_DAPM_MICBIAS_E(DAPM_MICBIAS2_STANDALONE, SND_SOC_NOPM, 0, 0,
10792 tasha_codec_force_enable_micbias,
10793 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10794 SND_SOC_DAPM_MICBIAS_E(DAPM_MICBIAS3_STANDALONE, SND_SOC_NOPM, 0, 0,
10795 tasha_codec_force_enable_micbias,
10796 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10797 SND_SOC_DAPM_MICBIAS_E(DAPM_MICBIAS4_STANDALONE, SND_SOC_NOPM, 0, 0,
10798 tasha_codec_force_enable_micbias,
10799 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10800 SND_SOC_DAPM_SUPPLY(DAPM_LDO_H_STANDALONE, SND_SOC_NOPM, 0, 0,
10801 tasha_codec_force_enable_ldo_h,
10802 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10803
10804 SND_SOC_DAPM_MUX("ANC0 FB MUX", SND_SOC_NOPM, 0, 0, &anc0_fb_mux),
10805 SND_SOC_DAPM_MUX("ANC1 FB MUX", SND_SOC_NOPM, 0, 0, &anc1_fb_mux),
10806
10807 SND_SOC_DAPM_INPUT("AMIC2"),
10808 SND_SOC_DAPM_INPUT("AMIC3"),
10809 SND_SOC_DAPM_INPUT("AMIC4"),
10810 SND_SOC_DAPM_INPUT("AMIC5"),
10811 SND_SOC_DAPM_INPUT("AMIC6"),
10812
10813 SND_SOC_DAPM_AIF_OUT_E("AIF1 CAP", "AIF1 Capture", 0, SND_SOC_NOPM,
10814 AIF1_CAP, 0, tasha_codec_enable_slimtx,
10815 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
10816
10817 SND_SOC_DAPM_AIF_OUT_E("AIF2 CAP", "AIF2 Capture", 0, SND_SOC_NOPM,
10818 AIF2_CAP, 0, tasha_codec_enable_slimtx,
10819 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
10820
10821 SND_SOC_DAPM_AIF_OUT_E("AIF3 CAP", "AIF3 Capture", 0, SND_SOC_NOPM,
10822 AIF3_CAP, 0, tasha_codec_enable_slimtx,
10823 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
10824
10825 SND_SOC_DAPM_AIF_OUT_E("AIF4 VI", "VIfeed", 0, SND_SOC_NOPM,
10826 AIF4_VIFEED, 0, tasha_codec_enable_slimvi_feedback,
10827 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
10828 SND_SOC_DAPM_MIXER("AIF4_VI Mixer", SND_SOC_NOPM, AIF4_VIFEED, 0,
10829 aif4_vi_mixer, ARRAY_SIZE(aif4_vi_mixer)),
10830
10831 SND_SOC_DAPM_MIXER("AIF1_CAP Mixer", SND_SOC_NOPM, AIF1_CAP, 0,
10832 aif1_cap_mixer, ARRAY_SIZE(aif1_cap_mixer)),
10833
10834 SND_SOC_DAPM_MIXER("AIF2_CAP Mixer", SND_SOC_NOPM, AIF2_CAP, 0,
10835 aif2_cap_mixer, ARRAY_SIZE(aif2_cap_mixer)),
10836
10837 SND_SOC_DAPM_MIXER("AIF3_CAP Mixer", SND_SOC_NOPM, AIF3_CAP, 0,
10838 aif3_cap_mixer, ARRAY_SIZE(aif3_cap_mixer)),
10839
10840 SND_SOC_DAPM_MIXER("AIF4_MAD Mixer", SND_SOC_NOPM, AIF4_MAD_TX, 0,
10841 aif4_mad_mixer, ARRAY_SIZE(aif4_mad_mixer)),
10842
10843 SND_SOC_DAPM_INPUT("VIINPUT"),
10844
10845 SND_SOC_DAPM_AIF_OUT("AIF5 CPE", "AIF5 CPE TX", 0, SND_SOC_NOPM,
10846 AIF5_CPE_TX, 0),
10847
10848 SND_SOC_DAPM_MUX_E("EC BUF MUX INP", SND_SOC_NOPM, 0, 0, &ec_buf_mux,
10849 tasha_codec_ec_buf_mux_enable,
10850 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
10851
10852 /* Digital Mic Inputs */
10853 SND_SOC_DAPM_ADC_E("DMIC0", NULL, SND_SOC_NOPM, 0, 0,
10854 tasha_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
10855 SND_SOC_DAPM_POST_PMD),
10856
10857 SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0,
10858 tasha_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
10859 SND_SOC_DAPM_POST_PMD),
10860
10861 SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 0, 0,
10862 tasha_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
10863 SND_SOC_DAPM_POST_PMD),
10864
10865 SND_SOC_DAPM_ADC_E("DMIC3", NULL, SND_SOC_NOPM, 0, 0,
10866 tasha_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
10867 SND_SOC_DAPM_POST_PMD),
10868
10869 SND_SOC_DAPM_ADC_E("DMIC4", NULL, SND_SOC_NOPM, 0, 0,
10870 tasha_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
10871 SND_SOC_DAPM_POST_PMD),
10872
10873 SND_SOC_DAPM_ADC_E("DMIC5", NULL, SND_SOC_NOPM, 0, 0,
10874 tasha_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
10875 SND_SOC_DAPM_POST_PMD),
10876
10877 SND_SOC_DAPM_MUX("IIR0 INP0 MUX", SND_SOC_NOPM, 0, 0, &iir0_inp0_mux),
10878 SND_SOC_DAPM_MUX("IIR0 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir0_inp1_mux),
10879 SND_SOC_DAPM_MUX("IIR0 INP2 MUX", SND_SOC_NOPM, 0, 0, &iir0_inp2_mux),
10880 SND_SOC_DAPM_MUX("IIR0 INP3 MUX", SND_SOC_NOPM, 0, 0, &iir0_inp3_mux),
10881 SND_SOC_DAPM_MUX("IIR1 INP0 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp0_mux),
10882 SND_SOC_DAPM_MUX("IIR1 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp1_mux),
10883 SND_SOC_DAPM_MUX("IIR1 INP2 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp2_mux),
10884 SND_SOC_DAPM_MUX("IIR1 INP3 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp3_mux),
10885
10886 SND_SOC_DAPM_MIXER_E("IIR0", WCD9335_CDC_SIDETONE_IIR0_IIR_PATH_CTL,
10887 4, 0, NULL, 0, tasha_codec_set_iir_gain,
10888 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
10889 SND_SOC_DAPM_MIXER_E("IIR1", WCD9335_CDC_SIDETONE_IIR1_IIR_PATH_CTL,
10890 4, 0, NULL, 0, tasha_codec_set_iir_gain,
10891 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
10892 SND_SOC_DAPM_MIXER("SRC0", WCD9335_CDC_SIDETONE_SRC0_ST_SRC_PATH_CTL,
10893 4, 0, NULL, 0),
10894 SND_SOC_DAPM_MIXER("SRC1", WCD9335_CDC_SIDETONE_SRC1_ST_SRC_PATH_CTL,
10895 4, 0, NULL, 0),
10896 SND_SOC_DAPM_MIXER_E("CPE IN Mixer", SND_SOC_NOPM, 0, 0,
10897 cpe_in_mix_switch,
10898 ARRAY_SIZE(cpe_in_mix_switch),
10899 tasha_codec_configure_cpe_input,
10900 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10901
10902 SND_SOC_DAPM_MUX("RX INT1_1 NATIVE MUX", SND_SOC_NOPM, 0, 0,
10903 &int1_1_native_mux),
10904 SND_SOC_DAPM_MUX("RX INT2_1 NATIVE MUX", SND_SOC_NOPM, 0, 0,
10905 &int2_1_native_mux),
10906 SND_SOC_DAPM_MUX("RX INT3_1 NATIVE MUX", SND_SOC_NOPM, 0, 0,
10907 &int3_1_native_mux),
10908 SND_SOC_DAPM_MUX("RX INT4_1 NATIVE MUX", SND_SOC_NOPM, 0, 0,
10909 &int4_1_native_mux),
10910 SND_SOC_DAPM_MUX("RX MIX TX0 MUX", SND_SOC_NOPM, 0, 0,
10911 &rx_mix_tx0_mux),
10912 SND_SOC_DAPM_MUX("RX MIX TX1 MUX", SND_SOC_NOPM, 0, 0,
10913 &rx_mix_tx1_mux),
10914 SND_SOC_DAPM_MUX("RX MIX TX2 MUX", SND_SOC_NOPM, 0, 0,
10915 &rx_mix_tx2_mux),
10916 SND_SOC_DAPM_MUX("RX MIX TX3 MUX", SND_SOC_NOPM, 0, 0,
10917 &rx_mix_tx3_mux),
10918 SND_SOC_DAPM_MUX("RX MIX TX4 MUX", SND_SOC_NOPM, 0, 0,
10919 &rx_mix_tx4_mux),
10920 SND_SOC_DAPM_MUX("RX MIX TX5 MUX", SND_SOC_NOPM, 0, 0,
10921 &rx_mix_tx5_mux),
10922 SND_SOC_DAPM_MUX("RX MIX TX6 MUX", SND_SOC_NOPM, 0, 0,
10923 &rx_mix_tx6_mux),
10924 SND_SOC_DAPM_MUX("RX MIX TX7 MUX", SND_SOC_NOPM, 0, 0,
10925 &rx_mix_tx7_mux),
10926 SND_SOC_DAPM_MUX("RX MIX TX8 MUX", SND_SOC_NOPM, 0, 0,
10927 &rx_mix_tx8_mux),
10928
10929 SND_SOC_DAPM_MUX("RX INT0 DEM MUX", SND_SOC_NOPM, 0, 0,
10930 &rx_int0_dem_inp_mux),
10931 SND_SOC_DAPM_MUX("RX INT1 DEM MUX", SND_SOC_NOPM, 0, 0,
10932 &rx_int1_dem_inp_mux),
10933 SND_SOC_DAPM_MUX("RX INT2 DEM MUX", SND_SOC_NOPM, 0, 0,
10934 &rx_int2_dem_inp_mux),
10935
10936 SND_SOC_DAPM_MUX_E("RX INT0 INTERP", SND_SOC_NOPM,
10937 INTERP_EAR, 0, &rx_int0_interp_mux,
10938 tasha_codec_enable_interpolator,
10939 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10940 SND_SOC_DAPM_POST_PMD),
10941 SND_SOC_DAPM_MUX_E("RX INT1 INTERP", SND_SOC_NOPM,
10942 INTERP_HPHL, 0, &rx_int1_interp_mux,
10943 tasha_codec_enable_interpolator,
10944 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10945 SND_SOC_DAPM_POST_PMD),
10946 SND_SOC_DAPM_MUX_E("RX INT2 INTERP", SND_SOC_NOPM,
10947 INTERP_HPHR, 0, &rx_int2_interp_mux,
10948 tasha_codec_enable_interpolator,
10949 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10950 SND_SOC_DAPM_POST_PMD),
10951 SND_SOC_DAPM_MUX_E("RX INT3 INTERP", SND_SOC_NOPM,
10952 INTERP_LO1, 0, &rx_int3_interp_mux,
10953 tasha_codec_enable_interpolator,
10954 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10955 SND_SOC_DAPM_POST_PMD),
10956 SND_SOC_DAPM_MUX_E("RX INT4 INTERP", SND_SOC_NOPM,
10957 INTERP_LO2, 0, &rx_int4_interp_mux,
10958 tasha_codec_enable_interpolator,
10959 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10960 SND_SOC_DAPM_POST_PMD),
10961 SND_SOC_DAPM_MUX_E("RX INT5 INTERP", SND_SOC_NOPM,
10962 INTERP_LO3, 0, &rx_int5_interp_mux,
10963 tasha_codec_enable_interpolator,
10964 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10965 SND_SOC_DAPM_POST_PMD),
10966 SND_SOC_DAPM_MUX_E("RX INT6 INTERP", SND_SOC_NOPM,
10967 INTERP_LO4, 0, &rx_int6_interp_mux,
10968 tasha_codec_enable_interpolator,
10969 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10970 SND_SOC_DAPM_POST_PMD),
10971 SND_SOC_DAPM_MUX_E("RX INT7 INTERP", SND_SOC_NOPM,
10972 INTERP_SPKR1, 0, &rx_int7_interp_mux,
10973 tasha_codec_enable_interpolator,
10974 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10975 SND_SOC_DAPM_POST_PMD),
10976 SND_SOC_DAPM_MUX_E("RX INT8 INTERP", SND_SOC_NOPM,
10977 INTERP_SPKR2, 0, &rx_int8_interp_mux,
10978 tasha_codec_enable_interpolator,
10979 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10980 SND_SOC_DAPM_POST_PMD),
10981
10982 SND_SOC_DAPM_DAC_E("RX INT0 DAC", NULL, SND_SOC_NOPM,
10983 0, 0, tasha_codec_ear_dac_event,
10984 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10985 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
Vatsal Buchae9a50072017-09-06 17:40:11 +053010986 SND_SOC_DAPM_DAC_E("RX INT1 DAC", NULL, SND_SOC_NOPM,
10987 0, 0, tasha_codec_hphl_dac_event,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053010988 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10989 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
Vatsal Buchae9a50072017-09-06 17:40:11 +053010990 SND_SOC_DAPM_DAC_E("RX INT2 DAC", NULL, SND_SOC_NOPM,
10991 0, 0, tasha_codec_hphr_dac_event,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053010992 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10993 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
10994 SND_SOC_DAPM_DAC_E("RX INT3 DAC", NULL, SND_SOC_NOPM,
10995 0, 0, tasha_codec_lineout_dac_event,
10996 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10997 SND_SOC_DAPM_DAC_E("RX INT4 DAC", NULL, SND_SOC_NOPM,
10998 0, 0, tasha_codec_lineout_dac_event,
10999 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
11000 SND_SOC_DAPM_DAC_E("RX INT5 DAC", NULL, SND_SOC_NOPM,
11001 0, 0, tasha_codec_lineout_dac_event,
11002 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
11003 SND_SOC_DAPM_DAC_E("RX INT6 DAC", NULL, SND_SOC_NOPM,
11004 0, 0, tasha_codec_lineout_dac_event,
11005 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
Vatsal Buchae9a50072017-09-06 17:40:11 +053011006 SND_SOC_DAPM_PGA_E("HPHL PA", SND_SOC_NOPM, 0, 0, NULL, 0,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053011007 tasha_codec_enable_hphl_pa,
11008 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11009 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
Vatsal Buchae9a50072017-09-06 17:40:11 +053011010 SND_SOC_DAPM_PGA_E("HPHR PA", SND_SOC_NOPM, 0, 0, NULL, 0,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053011011 tasha_codec_enable_hphr_pa,
11012 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11013 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11014 SND_SOC_DAPM_PGA_E("EAR PA", WCD9335_ANA_EAR, 7, 0, NULL, 0,
11015 tasha_codec_enable_ear_pa,
11016 SND_SOC_DAPM_POST_PMU |
11017 SND_SOC_DAPM_POST_PMD),
11018 SND_SOC_DAPM_PGA_E("LINEOUT1 PA", WCD9335_ANA_LO_1_2, 7, 0, NULL, 0,
11019 tasha_codec_enable_lineout_pa,
11020 SND_SOC_DAPM_POST_PMU |
11021 SND_SOC_DAPM_POST_PMD),
11022 SND_SOC_DAPM_PGA_E("LINEOUT2 PA", WCD9335_ANA_LO_1_2, 6, 0, NULL, 0,
11023 tasha_codec_enable_lineout_pa,
11024 SND_SOC_DAPM_POST_PMU |
11025 SND_SOC_DAPM_POST_PMD),
11026 SND_SOC_DAPM_PGA_E("LINEOUT3 PA", WCD9335_ANA_LO_3_4, 7, 0, NULL, 0,
11027 tasha_codec_enable_lineout_pa,
11028 SND_SOC_DAPM_POST_PMU |
11029 SND_SOC_DAPM_POST_PMD),
11030 SND_SOC_DAPM_PGA_E("LINEOUT4 PA", WCD9335_ANA_LO_3_4, 6, 0, NULL, 0,
11031 tasha_codec_enable_lineout_pa,
11032 SND_SOC_DAPM_POST_PMU |
11033 SND_SOC_DAPM_POST_PMD),
11034 SND_SOC_DAPM_PGA_E("ANC EAR PA", WCD9335_ANA_EAR, 7, 0, NULL, 0,
11035 tasha_codec_enable_ear_pa,
11036 SND_SOC_DAPM_POST_PMU |
11037 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11038 SND_SOC_DAPM_PGA_E("ANC HPHL PA", SND_SOC_NOPM, 0, 0, NULL, 0,
11039 tasha_codec_enable_hphl_pa,
11040 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11041 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11042 SND_SOC_DAPM_PGA_E("ANC HPHR PA", SND_SOC_NOPM, 0, 0, NULL, 0,
11043 tasha_codec_enable_hphr_pa,
11044 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11045 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11046 SND_SOC_DAPM_PGA_E("ANC LINEOUT1 PA", WCD9335_ANA_LO_1_2,
11047 7, 0, NULL, 0,
11048 tasha_codec_enable_lineout_pa,
11049 SND_SOC_DAPM_POST_PMU |
11050 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11051 SND_SOC_DAPM_PGA_E("ANC LINEOUT2 PA", WCD9335_ANA_LO_1_2,
11052 6, 0, NULL, 0,
11053 tasha_codec_enable_lineout_pa,
11054 SND_SOC_DAPM_POST_PMU |
11055 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11056 SND_SOC_DAPM_PGA_E("ANC SPK1 PA", SND_SOC_NOPM, 0, 0, NULL, 0,
11057 tasha_codec_enable_spk_anc,
11058 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
11059
11060 SND_SOC_DAPM_OUTPUT("HPHL"),
11061 SND_SOC_DAPM_OUTPUT("HPHR"),
11062 SND_SOC_DAPM_OUTPUT("ANC HPHL"),
11063 SND_SOC_DAPM_OUTPUT("ANC HPHR"),
11064 SND_SOC_DAPM_SUPPLY("RX_BIAS", SND_SOC_NOPM, 0, 0,
11065 tasha_codec_enable_rx_bias, SND_SOC_DAPM_PRE_PMU |
11066 SND_SOC_DAPM_POST_PMD),
11067 SND_SOC_DAPM_OUTPUT("SPK1 OUT"),
11068 SND_SOC_DAPM_OUTPUT("SPK2 OUT"),
11069 SND_SOC_DAPM_OUTPUT("LINEOUT1"),
11070 SND_SOC_DAPM_OUTPUT("LINEOUT2"),
11071 SND_SOC_DAPM_OUTPUT("LINEOUT3"),
11072 SND_SOC_DAPM_OUTPUT("LINEOUT4"),
11073 SND_SOC_DAPM_OUTPUT("ANC LINEOUT1"),
11074 SND_SOC_DAPM_OUTPUT("ANC LINEOUT2"),
11075 SND_SOC_DAPM_SUPPLY("MICBIAS_REGULATOR", SND_SOC_NOPM,
11076 ON_DEMAND_MICBIAS, 0,
11077 tasha_codec_enable_on_demand_supply,
11078 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
11079
11080 SND_SOC_DAPM_SWITCH("ADC US MUX0", WCD9335_CDC_TX0_TX_PATH_192_CTL, 0,
11081 0, &adc_us_mux0_switch),
11082 SND_SOC_DAPM_SWITCH("ADC US MUX1", WCD9335_CDC_TX1_TX_PATH_192_CTL, 0,
11083 0, &adc_us_mux1_switch),
11084 SND_SOC_DAPM_SWITCH("ADC US MUX2", WCD9335_CDC_TX2_TX_PATH_192_CTL, 0,
11085 0, &adc_us_mux2_switch),
11086 SND_SOC_DAPM_SWITCH("ADC US MUX3", WCD9335_CDC_TX3_TX_PATH_192_CTL, 0,
11087 0, &adc_us_mux3_switch),
11088 SND_SOC_DAPM_SWITCH("ADC US MUX4", WCD9335_CDC_TX4_TX_PATH_192_CTL, 0,
11089 0, &adc_us_mux4_switch),
11090 SND_SOC_DAPM_SWITCH("ADC US MUX5", WCD9335_CDC_TX5_TX_PATH_192_CTL, 0,
11091 0, &adc_us_mux5_switch),
11092 SND_SOC_DAPM_SWITCH("ADC US MUX6", WCD9335_CDC_TX6_TX_PATH_192_CTL, 0,
11093 0, &adc_us_mux6_switch),
11094 SND_SOC_DAPM_SWITCH("ADC US MUX7", WCD9335_CDC_TX7_TX_PATH_192_CTL, 0,
11095 0, &adc_us_mux7_switch),
11096 SND_SOC_DAPM_SWITCH("ADC US MUX8", WCD9335_CDC_TX8_TX_PATH_192_CTL, 0,
11097 0, &adc_us_mux8_switch),
11098 /* MAD related widgets */
11099 SND_SOC_DAPM_AIF_OUT_E("AIF4 MAD", "AIF4 MAD TX", 0,
11100 SND_SOC_NOPM, 0, 0,
11101 tasha_codec_enable_mad,
11102 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
11103
11104 SND_SOC_DAPM_MUX("MAD_SEL MUX", SND_SOC_NOPM, 0, 0,
11105 &mad_sel_mux),
11106 SND_SOC_DAPM_INPUT("MAD_CPE_INPUT"),
11107 SND_SOC_DAPM_INPUT("MADINPUT"),
11108 SND_SOC_DAPM_SWITCH("MADONOFF", SND_SOC_NOPM, 0, 0,
11109 &aif4_mad_switch),
11110 SND_SOC_DAPM_SWITCH("MAD_BROADCAST", SND_SOC_NOPM, 0, 0,
11111 &mad_brdcst_switch),
11112 SND_SOC_DAPM_SWITCH("AIF4", SND_SOC_NOPM, 0, 0,
11113 &aif4_switch_mixer_controls),
11114 SND_SOC_DAPM_SWITCH("ANC HPHL Enable", SND_SOC_NOPM, 0, 0,
11115 &anc_hphl_switch),
11116 SND_SOC_DAPM_SWITCH("ANC HPHR Enable", SND_SOC_NOPM, 0, 0,
11117 &anc_hphr_switch),
11118 SND_SOC_DAPM_SWITCH("ANC EAR Enable", SND_SOC_NOPM, 0, 0,
11119 &anc_ear_switch),
11120 SND_SOC_DAPM_SWITCH("ANC OUT EAR SPKR Enable", SND_SOC_NOPM, 0, 0,
11121 &anc_ear_spkr_switch),
11122 SND_SOC_DAPM_SWITCH("ANC LINEOUT1 Enable", SND_SOC_NOPM, 0, 0,
11123 &anc_lineout1_switch),
11124 SND_SOC_DAPM_SWITCH("ANC LINEOUT2 Enable", SND_SOC_NOPM, 0, 0,
11125 &anc_lineout2_switch),
11126 SND_SOC_DAPM_SWITCH("ANC SPKR PA Enable", SND_SOC_NOPM, 0, 0,
11127 &anc_spkr_pa_switch),
11128};
11129
11130static int tasha_get_channel_map(struct snd_soc_dai *dai,
11131 unsigned int *tx_num, unsigned int *tx_slot,
11132 unsigned int *rx_num, unsigned int *rx_slot)
11133{
11134 struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(dai->codec);
11135 u32 i = 0;
11136 struct wcd9xxx_ch *ch;
11137
11138 switch (dai->id) {
11139 case AIF1_PB:
11140 case AIF2_PB:
11141 case AIF3_PB:
11142 case AIF4_PB:
11143 case AIF_MIX1_PB:
11144 if (!rx_slot || !rx_num) {
11145 pr_err("%s: Invalid rx_slot %pK or rx_num %pK\n",
11146 __func__, rx_slot, rx_num);
11147 return -EINVAL;
11148 }
11149 list_for_each_entry(ch, &tasha_p->dai[dai->id].wcd9xxx_ch_list,
11150 list) {
11151 pr_debug("%s: slot_num %u ch->ch_num %d\n",
11152 __func__, i, ch->ch_num);
11153 rx_slot[i++] = ch->ch_num;
11154 }
11155 pr_debug("%s: rx_num %d\n", __func__, i);
11156 *rx_num = i;
11157 break;
11158 case AIF1_CAP:
11159 case AIF2_CAP:
11160 case AIF3_CAP:
11161 case AIF4_MAD_TX:
11162 case AIF4_VIFEED:
11163 if (!tx_slot || !tx_num) {
11164 pr_err("%s: Invalid tx_slot %pK or tx_num %pK\n",
11165 __func__, tx_slot, tx_num);
11166 return -EINVAL;
11167 }
11168 list_for_each_entry(ch, &tasha_p->dai[dai->id].wcd9xxx_ch_list,
11169 list) {
11170 pr_debug("%s: slot_num %u ch->ch_num %d\n",
11171 __func__, i, ch->ch_num);
11172 tx_slot[i++] = ch->ch_num;
11173 }
11174 pr_debug("%s: tx_num %d\n", __func__, i);
11175 *tx_num = i;
11176 break;
11177
11178 default:
11179 pr_err("%s: Invalid DAI ID %x\n", __func__, dai->id);
11180 break;
11181 }
11182
11183 return 0;
11184}
11185
11186static int tasha_set_channel_map(struct snd_soc_dai *dai,
11187 unsigned int tx_num, unsigned int *tx_slot,
11188 unsigned int rx_num, unsigned int *rx_slot)
11189{
11190 struct tasha_priv *tasha;
11191 struct wcd9xxx *core;
11192 struct wcd9xxx_codec_dai_data *dai_data = NULL;
11193
11194 if (!dai) {
11195 pr_err("%s: dai is empty\n", __func__);
11196 return -EINVAL;
11197 }
11198 tasha = snd_soc_codec_get_drvdata(dai->codec);
11199 core = dev_get_drvdata(dai->codec->dev->parent);
11200
11201 if (!tx_slot || !rx_slot) {
11202 pr_err("%s: Invalid tx_slot=%pK, rx_slot=%pK\n",
11203 __func__, tx_slot, rx_slot);
11204 return -EINVAL;
11205 }
11206 pr_debug("%s(): dai_name = %s DAI-ID %x tx_ch %d rx_ch %d\n"
11207 "tasha->intf_type %d\n",
11208 __func__, dai->name, dai->id, tx_num, rx_num,
11209 tasha->intf_type);
11210
11211 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
11212 wcd9xxx_init_slimslave(core, core->slim->laddr,
11213 tx_num, tx_slot, rx_num, rx_slot);
11214 /* Reserve TX12/TX13 for MAD data channel */
11215 dai_data = &tasha->dai[AIF4_MAD_TX];
11216 if (dai_data) {
11217 if (TASHA_IS_2_0(tasha->wcd9xxx))
11218 list_add_tail(&core->tx_chs[TASHA_TX13].list,
11219 &dai_data->wcd9xxx_ch_list);
11220 else
11221 list_add_tail(&core->tx_chs[TASHA_TX12].list,
11222 &dai_data->wcd9xxx_ch_list);
11223 }
11224 }
11225 return 0;
11226}
11227
11228static int tasha_startup(struct snd_pcm_substream *substream,
11229 struct snd_soc_dai *dai)
11230{
11231 pr_debug("%s(): substream = %s stream = %d\n", __func__,
11232 substream->name, substream->stream);
11233
11234 return 0;
11235}
11236
11237static void tasha_shutdown(struct snd_pcm_substream *substream,
11238 struct snd_soc_dai *dai)
11239{
11240 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(dai->codec);
11241
11242 pr_debug("%s(): substream = %s stream = %d\n", __func__,
11243 substream->name, substream->stream);
11244
11245 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C)
11246 return;
11247
Asish Bhattacharya84f7f732017-07-25 16:29:27 +053011248 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053011249 tasha_codec_vote_max_bw(dai->codec, false);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053011250}
11251
11252static int tasha_set_decimator_rate(struct snd_soc_dai *dai,
11253 u8 tx_fs_rate_reg_val, u32 sample_rate)
11254{
11255 struct snd_soc_codec *codec = dai->codec;
11256 struct wcd9xxx_ch *ch;
11257 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
11258 u32 tx_port = 0;
11259 u8 shift = 0, shift_val = 0, tx_mux_sel = 0;
11260 int decimator = -1;
11261 u16 tx_port_reg = 0, tx_fs_reg = 0;
11262
11263 list_for_each_entry(ch, &tasha->dai[dai->id].wcd9xxx_ch_list, list) {
11264 tx_port = ch->port;
11265 dev_dbg(codec->dev, "%s: dai->id = %d, tx_port = %d",
11266 __func__, dai->id, tx_port);
11267
11268 if ((tx_port < 0) || (tx_port == 12) || (tx_port >= 14)) {
11269 dev_err(codec->dev, "%s: Invalid SLIM TX%u port. DAI ID: %d\n",
11270 __func__, tx_port, dai->id);
11271 return -EINVAL;
11272 }
11273 /* Find the SB TX MUX input - which decimator is connected */
11274 if (tx_port < 4) {
11275 tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0;
11276 shift = (tx_port << 1);
11277 shift_val = 0x03;
11278 } else if ((tx_port >= 4) && (tx_port < 8)) {
11279 tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1;
11280 shift = ((tx_port - 4) << 1);
11281 shift_val = 0x03;
11282 } else if ((tx_port >= 8) && (tx_port < 11)) {
11283 tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG2;
11284 shift = ((tx_port - 8) << 1);
11285 shift_val = 0x03;
11286 } else if (tx_port == 11) {
11287 tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG3;
11288 shift = 0;
11289 shift_val = 0x0F;
11290 } else if (tx_port == 13) {
11291 tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG3;
11292 shift = 4;
11293 shift_val = 0x03;
11294 }
11295 tx_mux_sel = snd_soc_read(codec, tx_port_reg) &
11296 (shift_val << shift);
11297 tx_mux_sel = tx_mux_sel >> shift;
11298
11299 if (tx_port <= 8) {
11300 if ((tx_mux_sel == 0x2) || (tx_mux_sel == 0x3))
11301 decimator = tx_port;
11302 } else if (tx_port <= 10) {
11303 if ((tx_mux_sel == 0x1) || (tx_mux_sel == 0x2))
11304 decimator = ((tx_port == 9) ? 7 : 6);
11305 } else if (tx_port == 11) {
11306 if ((tx_mux_sel >= 1) && (tx_mux_sel < 7))
11307 decimator = tx_mux_sel - 1;
11308 } else if (tx_port == 13) {
11309 if ((tx_mux_sel == 0x1) || (tx_mux_sel == 0x2))
11310 decimator = 5;
11311 }
11312
11313 if (decimator >= 0) {
11314 tx_fs_reg = WCD9335_CDC_TX0_TX_PATH_CTL +
11315 16 * decimator;
11316 dev_dbg(codec->dev, "%s: set DEC%u (-> SLIM_TX%u) rate to %u\n",
11317 __func__, decimator, tx_port, sample_rate);
11318 snd_soc_update_bits(codec, tx_fs_reg, 0x0F,
11319 tx_fs_rate_reg_val);
11320 } else if ((tx_port <= 8) && (tx_mux_sel == 0x01)) {
11321 /* Check if the TX Mux input is RX MIX TXn */
11322 dev_dbg(codec->dev, "%s: RX_MIX_TX%u going to SLIM TX%u\n",
11323 __func__, tx_port, tx_port);
11324 } else {
11325 dev_err(codec->dev, "%s: ERROR: Invalid decimator: %d\n",
11326 __func__, decimator);
11327 return -EINVAL;
11328 }
11329 }
11330 return 0;
11331}
11332
11333static int tasha_set_mix_interpolator_rate(struct snd_soc_dai *dai,
11334 u8 int_mix_fs_rate_reg_val,
11335 u32 sample_rate)
11336{
11337 u8 int_2_inp;
11338 u32 j;
11339 u16 int_mux_cfg1, int_fs_reg;
11340 u8 int_mux_cfg1_val;
11341 struct snd_soc_codec *codec = dai->codec;
11342 struct wcd9xxx_ch *ch;
11343 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
11344
11345 list_for_each_entry(ch, &tasha->dai[dai->id].wcd9xxx_ch_list, list) {
11346 int_2_inp = ch->port + INTn_2_INP_SEL_RX0 -
11347 TASHA_RX_PORT_START_NUMBER;
11348 if ((int_2_inp < INTn_2_INP_SEL_RX0) ||
11349 (int_2_inp > INTn_2_INP_SEL_RX7)) {
11350 pr_err("%s: Invalid RX%u port, Dai ID is %d\n",
11351 __func__,
11352 (ch->port - TASHA_RX_PORT_START_NUMBER),
11353 dai->id);
11354 return -EINVAL;
11355 }
11356
11357 int_mux_cfg1 = WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG1;
11358 for (j = 0; j < TASHA_NUM_INTERPOLATORS; j++) {
11359 int_mux_cfg1_val = snd_soc_read(codec, int_mux_cfg1) &
11360 0x0F;
11361 if (int_mux_cfg1_val == int_2_inp) {
11362 int_fs_reg = WCD9335_CDC_RX0_RX_PATH_MIX_CTL +
11363 20 * j;
11364 pr_debug("%s: AIF_MIX_PB DAI(%d) connected to INT%u_2\n",
11365 __func__, dai->id, j);
11366 pr_debug("%s: set INT%u_2 sample rate to %u\n",
11367 __func__, j, sample_rate);
11368 snd_soc_update_bits(codec, int_fs_reg,
11369 0x0F, int_mix_fs_rate_reg_val);
11370 }
11371 int_mux_cfg1 += 2;
11372 }
11373 }
11374 return 0;
11375}
11376
11377static int tasha_set_prim_interpolator_rate(struct snd_soc_dai *dai,
11378 u8 int_prim_fs_rate_reg_val,
11379 u32 sample_rate)
11380{
11381 u8 int_1_mix1_inp;
11382 u32 j;
11383 u16 int_mux_cfg0, int_mux_cfg1;
11384 u16 int_fs_reg;
11385 u8 int_mux_cfg0_val, int_mux_cfg1_val;
11386 u8 inp0_sel, inp1_sel, inp2_sel;
11387 struct snd_soc_codec *codec = dai->codec;
11388 struct wcd9xxx_ch *ch;
11389 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
11390
11391 list_for_each_entry(ch, &tasha->dai[dai->id].wcd9xxx_ch_list, list) {
11392 int_1_mix1_inp = ch->port + INTn_1_MIX_INP_SEL_RX0 -
11393 TASHA_RX_PORT_START_NUMBER;
11394 if ((int_1_mix1_inp < INTn_1_MIX_INP_SEL_RX0) ||
11395 (int_1_mix1_inp > INTn_1_MIX_INP_SEL_RX7)) {
11396 pr_err("%s: Invalid RX%u port, Dai ID is %d\n",
11397 __func__,
11398 (ch->port - TASHA_RX_PORT_START_NUMBER),
11399 dai->id);
11400 return -EINVAL;
11401 }
11402
11403 int_mux_cfg0 = WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG0;
11404
11405 /*
11406 * Loop through all interpolator MUX inputs and find out
11407 * to which interpolator input, the slim rx port
11408 * is connected
11409 */
11410 for (j = 0; j < TASHA_NUM_INTERPOLATORS; j++) {
11411 int_mux_cfg1 = int_mux_cfg0 + 1;
11412
11413 int_mux_cfg0_val = snd_soc_read(codec, int_mux_cfg0);
11414 int_mux_cfg1_val = snd_soc_read(codec, int_mux_cfg1);
11415 inp0_sel = int_mux_cfg0_val & 0x0F;
11416 inp1_sel = (int_mux_cfg0_val >> 4) & 0x0F;
11417 inp2_sel = (int_mux_cfg1_val >> 4) & 0x0F;
11418 if ((inp0_sel == int_1_mix1_inp) ||
11419 (inp1_sel == int_1_mix1_inp) ||
11420 (inp2_sel == int_1_mix1_inp)) {
11421 int_fs_reg = WCD9335_CDC_RX0_RX_PATH_CTL +
11422 20 * j;
11423 pr_debug("%s: AIF_PB DAI(%d) connected to INT%u_1\n",
11424 __func__, dai->id, j);
11425 pr_debug("%s: set INT%u_1 sample rate to %u\n",
11426 __func__, j, sample_rate);
11427 /* sample_rate is in Hz */
11428 if ((j == 0) && (sample_rate == 44100)) {
11429 pr_info("%s: Cannot set 44.1KHz on INT0\n",
11430 __func__);
11431 } else
11432 snd_soc_update_bits(codec, int_fs_reg,
11433 0x0F, int_prim_fs_rate_reg_val);
11434 }
11435 int_mux_cfg0 += 2;
11436 }
11437 }
11438
11439 return 0;
11440}
11441
11442
11443static int tasha_set_interpolator_rate(struct snd_soc_dai *dai,
11444 u32 sample_rate)
11445{
11446 int rate_val = 0;
11447 int i, ret;
11448
11449 /* set mixing path rate */
11450 for (i = 0; i < ARRAY_SIZE(int_mix_sample_rate_val); i++) {
11451 if (sample_rate ==
11452 int_mix_sample_rate_val[i].sample_rate) {
11453 rate_val =
11454 int_mix_sample_rate_val[i].rate_val;
11455 break;
11456 }
11457 }
11458 if ((i == ARRAY_SIZE(int_mix_sample_rate_val)) ||
11459 (rate_val < 0))
11460 goto prim_rate;
11461 ret = tasha_set_mix_interpolator_rate(dai,
11462 (u8) rate_val, sample_rate);
11463prim_rate:
11464 /* set primary path sample rate */
11465 for (i = 0; i < ARRAY_SIZE(int_prim_sample_rate_val); i++) {
11466 if (sample_rate ==
11467 int_prim_sample_rate_val[i].sample_rate) {
11468 rate_val =
11469 int_prim_sample_rate_val[i].rate_val;
11470 break;
11471 }
11472 }
11473 if ((i == ARRAY_SIZE(int_prim_sample_rate_val)) ||
11474 (rate_val < 0))
11475 return -EINVAL;
11476 ret = tasha_set_prim_interpolator_rate(dai,
11477 (u8) rate_val, sample_rate);
11478 return ret;
11479}
11480
11481static int tasha_prepare(struct snd_pcm_substream *substream,
11482 struct snd_soc_dai *dai)
11483{
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053011484 pr_debug("%s(): substream = %s stream = %d\n", __func__,
11485 substream->name, substream->stream);
Asish Bhattacharya84f7f732017-07-25 16:29:27 +053011486
11487 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053011488 tasha_codec_vote_max_bw(dai->codec, false);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053011489 return 0;
11490}
11491
11492static int tasha_hw_params(struct snd_pcm_substream *substream,
11493 struct snd_pcm_hw_params *params,
11494 struct snd_soc_dai *dai)
11495{
11496 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(dai->codec);
11497 int ret;
11498 int tx_fs_rate = -EINVAL;
11499 int rx_fs_rate = -EINVAL;
11500 int i2s_bit_mode;
11501 struct snd_soc_codec *codec = dai->codec;
11502
11503 pr_debug("%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__,
11504 dai->name, dai->id, params_rate(params),
11505 params_channels(params));
11506
11507 switch (substream->stream) {
11508 case SNDRV_PCM_STREAM_PLAYBACK:
11509 ret = tasha_set_interpolator_rate(dai, params_rate(params));
11510 if (ret) {
11511 pr_err("%s: cannot set sample rate: %u\n",
11512 __func__, params_rate(params));
11513 return ret;
11514 }
11515 switch (params_width(params)) {
11516 case 16:
11517 tasha->dai[dai->id].bit_width = 16;
11518 i2s_bit_mode = 0x01;
11519 break;
11520 case 24:
11521 tasha->dai[dai->id].bit_width = 24;
11522 i2s_bit_mode = 0x00;
11523 break;
11524 default:
11525 return -EINVAL;
11526 }
11527 tasha->dai[dai->id].rate = params_rate(params);
11528 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
11529 switch (params_rate(params)) {
11530 case 8000:
11531 rx_fs_rate = 0;
11532 break;
11533 case 16000:
11534 rx_fs_rate = 1;
11535 break;
11536 case 32000:
11537 rx_fs_rate = 2;
11538 break;
11539 case 48000:
11540 rx_fs_rate = 3;
11541 break;
11542 case 96000:
11543 rx_fs_rate = 4;
11544 break;
11545 case 192000:
11546 rx_fs_rate = 5;
11547 break;
11548 default:
11549 dev_err(tasha->dev,
11550 "%s: Invalid RX sample rate: %d\n",
11551 __func__, params_rate(params));
11552 return -EINVAL;
11553 };
11554 snd_soc_update_bits(codec,
11555 WCD9335_DATA_HUB_DATA_HUB_RX_I2S_CTL,
11556 0x20, i2s_bit_mode << 5);
11557 snd_soc_update_bits(codec,
11558 WCD9335_DATA_HUB_DATA_HUB_RX_I2S_CTL,
11559 0x1c, (rx_fs_rate << 2));
11560 }
11561 break;
11562 case SNDRV_PCM_STREAM_CAPTURE:
11563 switch (params_rate(params)) {
11564 case 8000:
11565 tx_fs_rate = 0;
11566 break;
11567 case 16000:
11568 tx_fs_rate = 1;
11569 break;
11570 case 32000:
11571 tx_fs_rate = 3;
11572 break;
11573 case 48000:
11574 tx_fs_rate = 4;
11575 break;
11576 case 96000:
11577 tx_fs_rate = 5;
11578 break;
11579 case 192000:
11580 tx_fs_rate = 6;
11581 break;
11582 case 384000:
11583 tx_fs_rate = 7;
11584 break;
11585 default:
11586 dev_err(tasha->dev, "%s: Invalid TX sample rate: %d\n",
11587 __func__, params_rate(params));
11588 return -EINVAL;
11589
11590 };
11591 if (dai->id != AIF4_VIFEED &&
11592 dai->id != AIF4_MAD_TX) {
11593 ret = tasha_set_decimator_rate(dai, tx_fs_rate,
11594 params_rate(params));
11595 if (ret < 0) {
11596 dev_err(tasha->dev, "%s: cannot set TX Decimator rate: %d\n",
11597 __func__, tx_fs_rate);
11598 return ret;
11599 }
11600 }
11601 tasha->dai[dai->id].rate = params_rate(params);
11602 switch (params_width(params)) {
11603 case 16:
11604 tasha->dai[dai->id].bit_width = 16;
11605 i2s_bit_mode = 0x01;
11606 break;
11607 case 24:
11608 tasha->dai[dai->id].bit_width = 24;
11609 i2s_bit_mode = 0x00;
11610 break;
11611 case 32:
11612 tasha->dai[dai->id].bit_width = 32;
11613 i2s_bit_mode = 0x00;
11614 break;
11615 default:
11616 dev_err(tasha->dev, "%s: Invalid format 0x%x\n",
11617 __func__, params_width(params));
11618 return -EINVAL;
11619 };
11620 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
11621 snd_soc_update_bits(codec,
11622 WCD9335_DATA_HUB_DATA_HUB_TX_I2S_CTL,
11623 0x20, i2s_bit_mode << 5);
11624 if (tx_fs_rate > 1)
11625 tx_fs_rate--;
11626 snd_soc_update_bits(codec,
11627 WCD9335_DATA_HUB_DATA_HUB_TX_I2S_CTL,
11628 0x1c, tx_fs_rate << 2);
11629 snd_soc_update_bits(codec,
11630 WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD0_L_CFG,
11631 0x05, 0x05);
11632
11633 snd_soc_update_bits(codec,
11634 WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD0_R_CFG,
11635 0x05, 0x05);
11636
11637 snd_soc_update_bits(codec,
11638 WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD1_L_CFG,
11639 0x05, 0x05);
11640
11641 snd_soc_update_bits(codec,
11642 WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD1_R_CFG,
11643 0x05, 0x05);
11644 }
11645 break;
11646 default:
11647 pr_err("%s: Invalid stream type %d\n", __func__,
11648 substream->stream);
11649 return -EINVAL;
11650 };
11651 if (dai->id == AIF4_VIFEED)
11652 tasha->dai[dai->id].bit_width = 32;
11653
11654 return 0;
11655}
11656
11657static int tasha_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
11658{
11659 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(dai->codec);
11660
11661 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
11662 case SND_SOC_DAIFMT_CBS_CFS:
11663 /* CPU is master */
11664 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
11665 if (dai->id == AIF1_CAP)
11666 snd_soc_update_bits(dai->codec,
11667 WCD9335_DATA_HUB_DATA_HUB_TX_I2S_CTL,
11668 0x2, 0);
11669 else if (dai->id == AIF1_PB)
11670 snd_soc_update_bits(dai->codec,
11671 WCD9335_DATA_HUB_DATA_HUB_RX_I2S_CTL,
11672 0x2, 0);
11673 }
11674 break;
11675 case SND_SOC_DAIFMT_CBM_CFM:
11676 /* CPU is slave */
11677 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
11678 if (dai->id == AIF1_CAP)
11679 snd_soc_update_bits(dai->codec,
11680 WCD9335_DATA_HUB_DATA_HUB_TX_I2S_CTL,
11681 0x2, 0x2);
11682 else if (dai->id == AIF1_PB)
11683 snd_soc_update_bits(dai->codec,
11684 WCD9335_DATA_HUB_DATA_HUB_RX_I2S_CTL,
11685 0x2, 0x2);
11686 }
11687 break;
11688 default:
11689 return -EINVAL;
11690 }
11691 return 0;
11692}
11693
11694static int tasha_set_dai_sysclk(struct snd_soc_dai *dai,
11695 int clk_id, unsigned int freq, int dir)
11696{
11697 pr_debug("%s\n", __func__);
11698 return 0;
11699}
11700
11701static struct snd_soc_dai_ops tasha_dai_ops = {
11702 .startup = tasha_startup,
11703 .shutdown = tasha_shutdown,
11704 .hw_params = tasha_hw_params,
11705 .prepare = tasha_prepare,
11706 .set_sysclk = tasha_set_dai_sysclk,
11707 .set_fmt = tasha_set_dai_fmt,
11708 .set_channel_map = tasha_set_channel_map,
11709 .get_channel_map = tasha_get_channel_map,
11710};
11711
11712static struct snd_soc_dai_driver tasha_dai[] = {
11713 {
11714 .name = "tasha_rx1",
11715 .id = AIF1_PB,
11716 .playback = {
11717 .stream_name = "AIF1 Playback",
11718 .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK,
11719 .formats = TASHA_FORMATS_S16_S24_LE,
11720 .rate_max = 192000,
11721 .rate_min = 8000,
11722 .channels_min = 1,
11723 .channels_max = 2,
11724 },
11725 .ops = &tasha_dai_ops,
11726 },
11727 {
11728 .name = "tasha_tx1",
11729 .id = AIF1_CAP,
11730 .capture = {
11731 .stream_name = "AIF1 Capture",
11732 .rates = WCD9335_RATES_MASK,
11733 .formats = TASHA_FORMATS_S16_S24_LE,
11734 .rate_max = 192000,
11735 .rate_min = 8000,
11736 .channels_min = 1,
11737 .channels_max = 4,
11738 },
11739 .ops = &tasha_dai_ops,
11740 },
11741 {
11742 .name = "tasha_rx2",
11743 .id = AIF2_PB,
11744 .playback = {
11745 .stream_name = "AIF2 Playback",
11746 .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK,
11747 .formats = TASHA_FORMATS_S16_S24_LE,
11748 .rate_min = 8000,
11749 .rate_max = 192000,
11750 .channels_min = 1,
11751 .channels_max = 2,
11752 },
11753 .ops = &tasha_dai_ops,
11754 },
11755 {
11756 .name = "tasha_tx2",
11757 .id = AIF2_CAP,
11758 .capture = {
11759 .stream_name = "AIF2 Capture",
11760 .rates = WCD9335_RATES_MASK,
11761 .formats = TASHA_FORMATS_S16_S24_LE,
11762 .rate_max = 192000,
11763 .rate_min = 8000,
11764 .channels_min = 1,
11765 .channels_max = 8,
11766 },
11767 .ops = &tasha_dai_ops,
11768 },
11769 {
11770 .name = "tasha_rx3",
11771 .id = AIF3_PB,
11772 .playback = {
11773 .stream_name = "AIF3 Playback",
11774 .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK,
11775 .formats = TASHA_FORMATS_S16_S24_LE,
11776 .rate_min = 8000,
11777 .rate_max = 192000,
11778 .channels_min = 1,
11779 .channels_max = 2,
11780 },
11781 .ops = &tasha_dai_ops,
11782 },
11783 {
11784 .name = "tasha_tx3",
11785 .id = AIF3_CAP,
11786 .capture = {
11787 .stream_name = "AIF3 Capture",
11788 .rates = WCD9335_RATES_MASK,
11789 .formats = TASHA_FORMATS_S16_S24_LE,
11790 .rate_max = 48000,
11791 .rate_min = 8000,
11792 .channels_min = 1,
11793 .channels_max = 2,
11794 },
11795 .ops = &tasha_dai_ops,
11796 },
11797 {
11798 .name = "tasha_rx4",
11799 .id = AIF4_PB,
11800 .playback = {
11801 .stream_name = "AIF4 Playback",
11802 .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK,
11803 .formats = TASHA_FORMATS_S16_S24_LE,
11804 .rate_min = 8000,
11805 .rate_max = 192000,
11806 .channels_min = 1,
11807 .channels_max = 2,
11808 },
11809 .ops = &tasha_dai_ops,
11810 },
11811 {
11812 .name = "tasha_mix_rx1",
11813 .id = AIF_MIX1_PB,
11814 .playback = {
11815 .stream_name = "AIF Mix Playback",
11816 .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK,
11817 .formats = TASHA_FORMATS_S16_S24_LE,
11818 .rate_min = 8000,
11819 .rate_max = 192000,
11820 .channels_min = 1,
11821 .channels_max = 8,
11822 },
11823 .ops = &tasha_dai_ops,
11824 },
11825 {
11826 .name = "tasha_mad1",
11827 .id = AIF4_MAD_TX,
11828 .capture = {
11829 .stream_name = "AIF4 MAD TX",
11830 .rates = SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 |
11831 SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_384000,
11832 .formats = TASHA_FORMATS_S16_S24_S32_LE,
11833 .rate_min = 16000,
11834 .rate_max = 384000,
11835 .channels_min = 1,
11836 .channels_max = 1,
11837 },
11838 .ops = &tasha_dai_ops,
11839 },
11840 {
11841 .name = "tasha_vifeedback",
11842 .id = AIF4_VIFEED,
11843 .capture = {
11844 .stream_name = "VIfeed",
11845 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000,
11846 .formats = TASHA_FORMATS_S16_S24_S32_LE,
11847 .rate_max = 48000,
11848 .rate_min = 8000,
11849 .channels_min = 1,
11850 .channels_max = 4,
11851 },
11852 .ops = &tasha_dai_ops,
11853 },
11854 {
11855 .name = "tasha_cpe",
11856 .id = AIF5_CPE_TX,
11857 .capture = {
11858 .stream_name = "AIF5 CPE TX",
11859 .rates = SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000,
11860 .formats = TASHA_FORMATS_S16_S24_S32_LE,
11861 .rate_min = 16000,
11862 .rate_max = 48000,
11863 .channels_min = 1,
11864 .channels_max = 1,
11865 },
11866 },
11867};
11868
11869static struct snd_soc_dai_driver tasha_i2s_dai[] = {
11870 {
11871 .name = "tasha_i2s_rx1",
11872 .id = AIF1_PB,
11873 .playback = {
11874 .stream_name = "AIF1 Playback",
11875 .rates = WCD9335_RATES_MASK,
11876 .formats = TASHA_FORMATS_S16_S24_LE,
11877 .rate_max = 192000,
11878 .rate_min = 8000,
11879 .channels_min = 1,
11880 .channels_max = 2,
11881 },
11882 .ops = &tasha_dai_ops,
11883 },
11884 {
11885 .name = "tasha_i2s_tx1",
11886 .id = AIF1_CAP,
11887 .capture = {
11888 .stream_name = "AIF1 Capture",
11889 .rates = WCD9335_RATES_MASK,
11890 .formats = TASHA_FORMATS_S16_S24_LE,
11891 .rate_max = 192000,
11892 .rate_min = 8000,
11893 .channels_min = 1,
11894 .channels_max = 4,
11895 },
11896 .ops = &tasha_dai_ops,
11897 },
11898 {
11899 .name = "tasha_i2s_rx2",
11900 .id = AIF2_PB,
11901 .playback = {
11902 .stream_name = "AIF2 Playback",
11903 .rates = WCD9335_RATES_MASK,
11904 .formats = TASHA_FORMATS_S16_S24_LE,
11905 .rate_max = 192000,
11906 .rate_min = 8000,
11907 .channels_min = 1,
11908 .channels_max = 2,
11909 },
11910 .ops = &tasha_dai_ops,
11911 },
11912 {
11913 .name = "tasha_i2s_tx2",
11914 .id = AIF2_CAP,
11915 .capture = {
11916 .stream_name = "AIF2 Capture",
11917 .rates = WCD9335_RATES_MASK,
11918 .formats = TASHA_FORMATS_S16_S24_LE,
11919 .rate_max = 192000,
11920 .rate_min = 8000,
11921 .channels_min = 1,
11922 .channels_max = 4,
11923 },
11924 .ops = &tasha_dai_ops,
11925 },
Raja Mallika6396202018-06-01 07:48:38 +053011926 {
11927 .name = "tasha_mad1",
11928 .id = AIF4_MAD_TX,
11929 .capture = {
11930 .stream_name = "AIF4 MAD TX",
11931 .rates = SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 |
11932 SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_384000,
11933 .formats = TASHA_FORMATS_S16_S24_S32_LE,
11934 .rate_min = 16000,
11935 .rate_max = 384000,
11936 .channels_min = 1,
11937 .channels_max = 1,
11938 },
11939 .ops = &tasha_dai_ops,
11940 },
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053011941};
11942
11943static void tasha_codec_power_gate_digital_core(struct tasha_priv *tasha)
11944{
11945 struct snd_soc_codec *codec = tasha->codec;
11946
11947 if (!codec)
11948 return;
11949
11950 mutex_lock(&tasha->power_lock);
11951 dev_dbg(codec->dev, "%s: Entering power gating function, %d\n",
11952 __func__, tasha->power_active_ref);
11953
11954 if (tasha->power_active_ref > 0)
11955 goto exit;
11956
11957 wcd9xxx_set_power_state(tasha->wcd9xxx,
11958 WCD_REGION_POWER_COLLAPSE_BEGIN,
11959 WCD9XXX_DIG_CORE_REGION_1);
11960 snd_soc_update_bits(codec, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL,
11961 0x04, 0x04);
11962 snd_soc_update_bits(codec, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL,
11963 0x01, 0x00);
11964 snd_soc_update_bits(codec, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL,
11965 0x02, 0x00);
11966 clear_bit(AUDIO_NOMINAL, &tasha->status_mask);
11967 tasha_codec_update_sido_voltage(tasha, sido_buck_svs_voltage);
11968 wcd9xxx_set_power_state(tasha->wcd9xxx, WCD_REGION_POWER_DOWN,
11969 WCD9XXX_DIG_CORE_REGION_1);
11970exit:
11971 dev_dbg(codec->dev, "%s: Exiting power gating function, %d\n",
11972 __func__, tasha->power_active_ref);
11973 mutex_unlock(&tasha->power_lock);
11974}
11975
11976static void tasha_codec_power_gate_work(struct work_struct *work)
11977{
11978 struct tasha_priv *tasha;
11979 struct delayed_work *dwork;
11980 struct snd_soc_codec *codec;
11981
11982 dwork = to_delayed_work(work);
11983 tasha = container_of(dwork, struct tasha_priv, power_gate_work);
11984 codec = tasha->codec;
11985
11986 if (!codec)
11987 return;
11988
11989 tasha_codec_power_gate_digital_core(tasha);
11990}
11991
11992/* called under power_lock acquisition */
11993static int tasha_dig_core_remove_power_collapse(struct snd_soc_codec *codec)
11994{
11995 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
11996
11997 tasha_codec_vote_max_bw(codec, true);
11998 snd_soc_write(codec, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x5);
11999 snd_soc_write(codec, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x7);
12000 snd_soc_write(codec, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x3);
12001 snd_soc_update_bits(codec, WCD9335_CODEC_RPM_RST_CTL, 0x02, 0x00);
12002 snd_soc_update_bits(codec, WCD9335_CODEC_RPM_RST_CTL, 0x02, 0x02);
12003
12004 wcd9xxx_set_power_state(tasha->wcd9xxx,
12005 WCD_REGION_POWER_COLLAPSE_REMOVE,
12006 WCD9XXX_DIG_CORE_REGION_1);
12007 regcache_mark_dirty(codec->component.regmap);
12008 regcache_sync_region(codec->component.regmap,
12009 TASHA_DIG_CORE_REG_MIN, TASHA_DIG_CORE_REG_MAX);
12010 tasha_codec_vote_max_bw(codec, false);
12011
12012 return 0;
12013}
12014
12015static int tasha_dig_core_power_collapse(struct tasha_priv *tasha,
12016 int req_state)
12017{
12018 struct snd_soc_codec *codec;
12019 int cur_state;
12020
12021 /* Exit if feature is disabled */
12022 if (!dig_core_collapse_enable)
12023 return 0;
12024
12025 mutex_lock(&tasha->power_lock);
12026 if (req_state == POWER_COLLAPSE)
12027 tasha->power_active_ref--;
12028 else if (req_state == POWER_RESUME)
12029 tasha->power_active_ref++;
12030 else
12031 goto unlock_mutex;
12032
12033 if (tasha->power_active_ref < 0) {
12034 dev_dbg(tasha->dev, "%s: power_active_ref is negative\n",
12035 __func__);
12036 goto unlock_mutex;
12037 }
12038
12039 codec = tasha->codec;
12040 if (!codec)
12041 goto unlock_mutex;
12042
12043 if (req_state == POWER_COLLAPSE) {
12044 if (tasha->power_active_ref == 0) {
12045 schedule_delayed_work(&tasha->power_gate_work,
12046 msecs_to_jiffies(dig_core_collapse_timer * 1000));
12047 }
12048 } else if (req_state == POWER_RESUME) {
12049 if (tasha->power_active_ref == 1) {
12050 /*
12051 * At this point, there can be two cases:
12052 * 1. Core already in power collapse state
12053 * 2. Timer kicked in and still did not expire or
12054 * waiting for the power_lock
12055 */
12056 cur_state = wcd9xxx_get_current_power_state(
12057 tasha->wcd9xxx,
12058 WCD9XXX_DIG_CORE_REGION_1);
12059 if (cur_state == WCD_REGION_POWER_DOWN)
12060 tasha_dig_core_remove_power_collapse(codec);
12061 else {
12062 mutex_unlock(&tasha->power_lock);
12063 cancel_delayed_work_sync(
12064 &tasha->power_gate_work);
12065 mutex_lock(&tasha->power_lock);
12066 }
12067 }
12068 }
12069
12070unlock_mutex:
12071 mutex_unlock(&tasha->power_lock);
12072
12073 return 0;
12074}
12075
12076static int __tasha_cdc_mclk_enable_locked(struct tasha_priv *tasha,
12077 bool enable)
12078{
12079 int ret = 0;
12080
12081 if (!tasha->wcd_ext_clk) {
12082 dev_err(tasha->dev, "%s: wcd ext clock is NULL\n", __func__);
12083 return -EINVAL;
12084 }
12085
12086 dev_dbg(tasha->dev, "%s: mclk_enable = %u\n", __func__, enable);
12087
12088 if (enable) {
12089 tasha_dig_core_power_collapse(tasha, POWER_RESUME);
12090 ret = tasha_cdc_req_mclk_enable(tasha, true);
12091 if (ret)
12092 goto err;
12093
12094 set_bit(AUDIO_NOMINAL, &tasha->status_mask);
12095 tasha_codec_apply_sido_voltage(tasha,
12096 SIDO_VOLTAGE_NOMINAL_MV);
12097 } else {
12098 if (!dig_core_collapse_enable) {
12099 clear_bit(AUDIO_NOMINAL, &tasha->status_mask);
12100 tasha_codec_update_sido_voltage(tasha,
12101 sido_buck_svs_voltage);
12102 }
12103 tasha_cdc_req_mclk_enable(tasha, false);
12104 tasha_dig_core_power_collapse(tasha, POWER_COLLAPSE);
12105 }
12106
12107err:
12108 return ret;
12109}
12110
12111static int __tasha_cdc_mclk_enable(struct tasha_priv *tasha,
12112 bool enable)
12113{
12114 int ret;
12115
12116 WCD9XXX_V2_BG_CLK_LOCK(tasha->resmgr);
12117 ret = __tasha_cdc_mclk_enable_locked(tasha, enable);
12118 WCD9XXX_V2_BG_CLK_UNLOCK(tasha->resmgr);
12119
12120 return ret;
12121}
12122
12123int tasha_cdc_mclk_enable(struct snd_soc_codec *codec, int enable, bool dapm)
12124{
12125 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
12126
12127 return __tasha_cdc_mclk_enable(tasha, enable);
12128}
12129EXPORT_SYMBOL(tasha_cdc_mclk_enable);
12130
12131int tasha_cdc_mclk_tx_enable(struct snd_soc_codec *codec, int enable, bool dapm)
12132{
12133 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
12134 int ret = 0;
12135
12136 dev_dbg(tasha->dev, "%s: clk_mode: %d, enable: %d, clk_internal: %d\n",
12137 __func__, tasha->clk_mode, enable, tasha->clk_internal);
12138 if (tasha->clk_mode || tasha->clk_internal) {
12139 if (enable) {
12140 tasha_cdc_sido_ccl_enable(tasha, true);
12141 wcd_resmgr_enable_master_bias(tasha->resmgr);
12142 tasha_dig_core_power_collapse(tasha, POWER_RESUME);
12143 snd_soc_update_bits(codec,
12144 WCD9335_CDC_CLK_RST_CTRL_FS_CNT_CONTROL,
12145 0x01, 0x01);
12146 snd_soc_update_bits(codec,
12147 WCD9335_CDC_CLK_RST_CTRL_MCLK_CONTROL,
12148 0x01, 0x01);
12149 set_bit(CPE_NOMINAL, &tasha->status_mask);
12150 tasha_codec_update_sido_voltage(tasha,
12151 SIDO_VOLTAGE_NOMINAL_MV);
12152 tasha->clk_internal = true;
12153 } else {
12154 tasha->clk_internal = false;
12155 clear_bit(CPE_NOMINAL, &tasha->status_mask);
12156 tasha_codec_update_sido_voltage(tasha,
12157 sido_buck_svs_voltage);
12158 tasha_dig_core_power_collapse(tasha, POWER_COLLAPSE);
12159 wcd_resmgr_disable_master_bias(tasha->resmgr);
12160 tasha_cdc_sido_ccl_enable(tasha, false);
12161 }
12162 } else {
12163 ret = __tasha_cdc_mclk_enable(tasha, enable);
12164 }
12165 return ret;
12166}
12167EXPORT_SYMBOL(tasha_cdc_mclk_tx_enable);
12168
12169static ssize_t tasha_codec_version_read(struct snd_info_entry *entry,
12170 void *file_private_data, struct file *file,
12171 char __user *buf, size_t count, loff_t pos)
12172{
12173 struct tasha_priv *tasha;
12174 struct wcd9xxx *wcd9xxx;
12175 char buffer[TASHA_VERSION_ENTRY_SIZE];
12176 int len = 0;
12177
12178 tasha = (struct tasha_priv *) entry->private_data;
12179 if (!tasha) {
12180 pr_err("%s: tasha priv is null\n", __func__);
12181 return -EINVAL;
12182 }
12183
12184 wcd9xxx = tasha->wcd9xxx;
12185
12186 if (wcd9xxx->codec_type->id_major == TASHA_MAJOR) {
12187 if (TASHA_IS_1_0(wcd9xxx))
12188 len = snprintf(buffer, sizeof(buffer), "WCD9335_1_0\n");
12189 else if (TASHA_IS_1_1(wcd9xxx))
12190 len = snprintf(buffer, sizeof(buffer), "WCD9335_1_1\n");
12191 else
12192 snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n");
12193 } else if (wcd9xxx->codec_type->id_major == TASHA2P0_MAJOR) {
12194 len = snprintf(buffer, sizeof(buffer), "WCD9335_2_0\n");
12195 } else
12196 len = snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n");
12197
12198 return simple_read_from_buffer(buf, count, &pos, buffer, len);
12199}
12200
12201static struct snd_info_entry_ops tasha_codec_info_ops = {
12202 .read = tasha_codec_version_read,
12203};
12204
12205/*
12206 * tasha_codec_info_create_codec_entry - creates wcd9335 module
12207 * @codec_root: The parent directory
12208 * @codec: Codec instance
12209 *
12210 * Creates wcd9335 module and version entry under the given
12211 * parent directory.
12212 *
12213 * Return: 0 on success or negative error code on failure.
12214 */
12215int tasha_codec_info_create_codec_entry(struct snd_info_entry *codec_root,
12216 struct snd_soc_codec *codec)
12217{
12218 struct snd_info_entry *version_entry;
12219 struct tasha_priv *tasha;
12220 struct snd_soc_card *card;
12221
12222 if (!codec_root || !codec)
12223 return -EINVAL;
12224
12225 tasha = snd_soc_codec_get_drvdata(codec);
12226 card = codec->component.card;
12227 tasha->entry = snd_info_create_subdir(codec_root->module,
12228 "tasha", codec_root);
12229 if (!tasha->entry) {
12230 dev_dbg(codec->dev, "%s: failed to create wcd9335 entry\n",
12231 __func__);
12232 return -ENOMEM;
12233 }
12234
12235 version_entry = snd_info_create_card_entry(card->snd_card,
12236 "version",
12237 tasha->entry);
12238 if (!version_entry) {
12239 dev_dbg(codec->dev, "%s: failed to create wcd9335 version entry\n",
12240 __func__);
12241 return -ENOMEM;
12242 }
12243
12244 version_entry->private_data = tasha;
12245 version_entry->size = TASHA_VERSION_ENTRY_SIZE;
12246 version_entry->content = SNDRV_INFO_CONTENT_DATA;
12247 version_entry->c.ops = &tasha_codec_info_ops;
12248
12249 if (snd_info_register(version_entry) < 0) {
12250 snd_info_free_entry(version_entry);
12251 return -ENOMEM;
12252 }
12253 tasha->version_entry = version_entry;
12254
12255 return 0;
12256}
12257EXPORT_SYMBOL(tasha_codec_info_create_codec_entry);
12258
12259static int __tasha_codec_internal_rco_ctrl(
12260 struct snd_soc_codec *codec, bool enable)
12261{
12262 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
12263 int ret = 0;
12264
12265 if (enable) {
12266 tasha_cdc_sido_ccl_enable(tasha, true);
12267 if (wcd_resmgr_get_clk_type(tasha->resmgr) ==
12268 WCD_CLK_RCO) {
12269 ret = wcd_resmgr_enable_clk_block(tasha->resmgr,
12270 WCD_CLK_RCO);
12271 } else {
12272 ret = tasha_cdc_req_mclk_enable(tasha, true);
12273 ret |= wcd_resmgr_enable_clk_block(tasha->resmgr,
12274 WCD_CLK_RCO);
12275 ret |= tasha_cdc_req_mclk_enable(tasha, false);
12276 }
12277
12278 } else {
12279 ret = wcd_resmgr_disable_clk_block(tasha->resmgr,
12280 WCD_CLK_RCO);
12281 tasha_cdc_sido_ccl_enable(tasha, false);
12282 }
12283
12284 if (ret) {
12285 dev_err(codec->dev, "%s: Error in %s RCO\n",
12286 __func__, (enable ? "enabling" : "disabling"));
12287 ret = -EINVAL;
12288 }
12289
12290 return ret;
12291}
12292
12293/*
12294 * tasha_codec_internal_rco_ctrl()
12295 * Make sure that the caller does not acquire
12296 * BG_CLK_LOCK.
12297 */
12298static int tasha_codec_internal_rco_ctrl(struct snd_soc_codec *codec,
12299 bool enable)
12300{
12301 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
12302 int ret = 0;
12303
12304 WCD9XXX_V2_BG_CLK_LOCK(tasha->resmgr);
12305 ret = __tasha_codec_internal_rco_ctrl(codec, enable);
12306 WCD9XXX_V2_BG_CLK_UNLOCK(tasha->resmgr);
12307 return ret;
12308}
12309
12310/*
12311 * tasha_mbhc_hs_detect: starts mbhc insertion/removal functionality
12312 * @codec: handle to snd_soc_codec *
12313 * @mbhc_cfg: handle to mbhc configuration structure
12314 * return 0 if mbhc_start is success or error code in case of failure
12315 */
12316int tasha_mbhc_hs_detect(struct snd_soc_codec *codec,
12317 struct wcd_mbhc_config *mbhc_cfg)
12318{
12319 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
12320
12321 return wcd_mbhc_start(&tasha->mbhc, mbhc_cfg);
12322}
12323EXPORT_SYMBOL(tasha_mbhc_hs_detect);
12324
12325/*
12326 * tasha_mbhc_hs_detect_exit: stop mbhc insertion/removal functionality
12327 * @codec: handle to snd_soc_codec *
12328 */
12329void tasha_mbhc_hs_detect_exit(struct snd_soc_codec *codec)
12330{
12331 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
12332
12333 wcd_mbhc_stop(&tasha->mbhc);
12334}
12335EXPORT_SYMBOL(tasha_mbhc_hs_detect_exit);
12336
12337static int wcd9335_get_micb_vout_ctl_val(u32 micb_mv)
12338{
12339 /* min micbias voltage is 1V and maximum is 2.85V */
12340 if (micb_mv < 1000 || micb_mv > 2850) {
12341 pr_err("%s: unsupported micbias voltage\n", __func__);
12342 return -EINVAL;
12343 }
12344
12345 return (micb_mv - 1000) / 50;
12346}
12347
12348static const struct tasha_reg_mask_val tasha_reg_update_reset_val_1_1[] = {
12349 {WCD9335_RCO_CTRL_2, 0xFF, 0x47},
12350 {WCD9335_FLYBACK_VNEG_DAC_CTRL_4, 0xFF, 0x60},
12351};
12352
12353static const struct tasha_reg_mask_val tasha_codec_reg_init_val_1_1[] = {
12354 {WCD9335_FLYBACK_VNEG_DAC_CTRL_1, 0xFF, 0x65},
12355 {WCD9335_FLYBACK_VNEG_DAC_CTRL_2, 0xFF, 0x52},
12356 {WCD9335_FLYBACK_VNEG_DAC_CTRL_3, 0xFF, 0xAF},
12357 {WCD9335_FLYBACK_VNEG_DAC_CTRL_4, 0xFF, 0x60},
12358 {WCD9335_FLYBACK_VNEG_CTRL_3, 0xFF, 0xF4},
12359 {WCD9335_FLYBACK_VNEG_CTRL_9, 0xFF, 0x40},
12360 {WCD9335_FLYBACK_VNEG_CTRL_2, 0xFF, 0x4F},
12361 {WCD9335_FLYBACK_EN, 0xFF, 0x6E},
12362 {WCD9335_CDC_RX2_RX_PATH_SEC0, 0xF8, 0xF8},
12363 {WCD9335_CDC_RX1_RX_PATH_SEC0, 0xF8, 0xF8},
12364};
12365
12366static const struct tasha_reg_mask_val tasha_codec_reg_init_val_1_0[] = {
12367 {WCD9335_FLYBACK_VNEG_CTRL_3, 0xFF, 0x54},
12368 {WCD9335_CDC_RX2_RX_PATH_SEC0, 0xFC, 0xFC},
12369 {WCD9335_CDC_RX1_RX_PATH_SEC0, 0xFC, 0xFC},
12370};
12371
12372static const struct tasha_reg_mask_val tasha_codec_reg_init_val_2_0[] = {
12373 {WCD9335_RCO_CTRL_2, 0x0F, 0x08},
12374 {WCD9335_RX_BIAS_FLYB_MID_RST, 0xF0, 0x10},
12375 {WCD9335_FLYBACK_CTRL_1, 0x20, 0x20},
12376 {WCD9335_HPH_OCP_CTL, 0xFF, 0x7A},
12377 {WCD9335_HPH_L_TEST, 0x01, 0x01},
12378 {WCD9335_HPH_R_TEST, 0x01, 0x01},
12379 {WCD9335_CDC_BOOST0_BOOST_CFG1, 0x3F, 0x12},
12380 {WCD9335_CDC_BOOST0_BOOST_CFG2, 0x1C, 0x08},
12381 {WCD9335_CDC_COMPANDER7_CTL7, 0x1E, 0x18},
12382 {WCD9335_CDC_BOOST1_BOOST_CFG1, 0x3F, 0x12},
12383 {WCD9335_CDC_BOOST1_BOOST_CFG2, 0x1C, 0x08},
12384 {WCD9335_CDC_COMPANDER8_CTL7, 0x1E, 0x18},
12385 {WCD9335_CDC_TX0_TX_PATH_SEC7, 0xFF, 0x45},
12386 {WCD9335_CDC_RX0_RX_PATH_SEC0, 0xFC, 0xF4},
12387 {WCD9335_HPH_REFBUFF_LP_CTL, 0x08, 0x08},
12388 {WCD9335_HPH_REFBUFF_LP_CTL, 0x06, 0x02},
12389 {WCD9335_DIFF_LO_CORE_OUT_PROG, 0xFC, 0xA0},
12390 {WCD9335_SE_LO_COM1, 0xFF, 0xC0},
12391 {WCD9335_CDC_RX3_RX_PATH_SEC0, 0xFC, 0xF4},
12392 {WCD9335_CDC_RX4_RX_PATH_SEC0, 0xFC, 0xF4},
12393 {WCD9335_CDC_RX5_RX_PATH_SEC0, 0xFC, 0xF8},
12394 {WCD9335_CDC_RX6_RX_PATH_SEC0, 0xFC, 0xF8},
12395};
12396
12397static const struct tasha_reg_mask_val tasha_codec_reg_defaults[] = {
12398 {WCD9335_CODEC_RPM_CLK_GATE, 0x03, 0x00},
12399 {WCD9335_CODEC_RPM_CLK_MCLK_CFG, 0x03, 0x01},
12400 {WCD9335_CODEC_RPM_CLK_MCLK_CFG, 0x04, 0x04},
12401};
12402
12403static const struct tasha_reg_mask_val tasha_codec_reg_i2c_defaults[] = {
12404 {WCD9335_ANA_CLK_TOP, 0x20, 0x20},
12405 {WCD9335_CODEC_RPM_CLK_GATE, 0x03, 0x01},
12406 {WCD9335_CODEC_RPM_CLK_MCLK_CFG, 0x03, 0x00},
12407 {WCD9335_CODEC_RPM_CLK_MCLK_CFG, 0x05, 0x05},
12408 {WCD9335_DATA_HUB_DATA_HUB_RX0_INP_CFG, 0x01, 0x01},
12409 {WCD9335_DATA_HUB_DATA_HUB_RX1_INP_CFG, 0x01, 0x01},
12410 {WCD9335_DATA_HUB_DATA_HUB_RX2_INP_CFG, 0x01, 0x01},
12411 {WCD9335_DATA_HUB_DATA_HUB_RX3_INP_CFG, 0x01, 0x01},
12412 {WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD0_L_CFG, 0x05, 0x05},
12413 {WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD0_R_CFG, 0x05, 0x05},
12414 {WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD1_L_CFG, 0x05, 0x05},
12415 {WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD1_R_CFG, 0x05, 0x05},
12416};
12417
12418static const struct tasha_reg_mask_val tasha_codec_reg_init_common_val[] = {
12419 /* Rbuckfly/R_EAR(32) */
12420 {WCD9335_CDC_CLSH_K2_MSB, 0x0F, 0x00},
12421 {WCD9335_CDC_CLSH_K2_LSB, 0xFF, 0x60},
12422 {WCD9335_CPE_SS_DMIC_CFG, 0x80, 0x00},
Xiaojun Sangc9af54a2018-02-12 19:03:02 +080012423 {WCD9335_CDC_BOOST0_BOOST_CTL, 0x7C, 0x58},
12424 {WCD9335_CDC_BOOST1_BOOST_CTL, 0x7C, 0x58},
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012425 {WCD9335_CDC_RX7_RX_PATH_CFG1, 0x08, 0x08},
12426 {WCD9335_CDC_RX8_RX_PATH_CFG1, 0x08, 0x08},
12427 {WCD9335_ANA_LO_1_2, 0x3C, 0X3C},
12428 {WCD9335_DIFF_LO_COM_SWCAP_REFBUF_FREQ, 0x70, 0x00},
12429 {WCD9335_SOC_MAD_AUDIO_CTL_2, 0x03, 0x03},
12430 {WCD9335_CDC_TOP_TOP_CFG1, 0x02, 0x02},
12431 {WCD9335_CDC_TOP_TOP_CFG1, 0x01, 0x01},
12432 {WCD9335_EAR_CMBUFF, 0x08, 0x00},
12433 {WCD9335_CDC_TX9_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
12434 {WCD9335_CDC_TX10_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
12435 {WCD9335_CDC_TX11_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
12436 {WCD9335_CDC_TX12_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
12437 {WCD9335_CDC_COMPANDER7_CTL3, 0x80, 0x80},
12438 {WCD9335_CDC_COMPANDER8_CTL3, 0x80, 0x80},
12439 {WCD9335_CDC_COMPANDER7_CTL7, 0x01, 0x01},
12440 {WCD9335_CDC_COMPANDER8_CTL7, 0x01, 0x01},
12441 {WCD9335_CDC_RX0_RX_PATH_CFG0, 0x01, 0x01},
12442 {WCD9335_CDC_RX1_RX_PATH_CFG0, 0x01, 0x01},
12443 {WCD9335_CDC_RX2_RX_PATH_CFG0, 0x01, 0x01},
12444 {WCD9335_CDC_RX3_RX_PATH_CFG0, 0x01, 0x01},
12445 {WCD9335_CDC_RX4_RX_PATH_CFG0, 0x01, 0x01},
12446 {WCD9335_CDC_RX5_RX_PATH_CFG0, 0x01, 0x01},
12447 {WCD9335_CDC_RX6_RX_PATH_CFG0, 0x01, 0x01},
12448 {WCD9335_CDC_RX7_RX_PATH_CFG0, 0x01, 0x01},
12449 {WCD9335_CDC_RX8_RX_PATH_CFG0, 0x01, 0x01},
12450 {WCD9335_CDC_RX0_RX_PATH_MIX_CFG, 0x01, 0x01},
12451 {WCD9335_CDC_RX1_RX_PATH_MIX_CFG, 0x01, 0x01},
12452 {WCD9335_CDC_RX2_RX_PATH_MIX_CFG, 0x01, 0x01},
12453 {WCD9335_CDC_RX3_RX_PATH_MIX_CFG, 0x01, 0x01},
12454 {WCD9335_CDC_RX4_RX_PATH_MIX_CFG, 0x01, 0x01},
12455 {WCD9335_CDC_RX5_RX_PATH_MIX_CFG, 0x01, 0x01},
12456 {WCD9335_CDC_RX6_RX_PATH_MIX_CFG, 0x01, 0x01},
12457 {WCD9335_CDC_RX7_RX_PATH_MIX_CFG, 0x01, 0x01},
12458 {WCD9335_CDC_RX8_RX_PATH_MIX_CFG, 0x01, 0x01},
12459 {WCD9335_VBADC_IBIAS_FE, 0x0C, 0x08},
12460};
12461
12462static const struct tasha_reg_mask_val tasha_codec_reg_init_1_x_val[] = {
12463 /* Enable TX HPF Filter & Linear Phase */
12464 {WCD9335_CDC_TX0_TX_PATH_CFG0, 0x11, 0x11},
12465 {WCD9335_CDC_TX1_TX_PATH_CFG0, 0x11, 0x11},
12466 {WCD9335_CDC_TX2_TX_PATH_CFG0, 0x11, 0x11},
12467 {WCD9335_CDC_TX3_TX_PATH_CFG0, 0x11, 0x11},
12468 {WCD9335_CDC_TX4_TX_PATH_CFG0, 0x11, 0x11},
12469 {WCD9335_CDC_TX5_TX_PATH_CFG0, 0x11, 0x11},
12470 {WCD9335_CDC_TX6_TX_PATH_CFG0, 0x11, 0x11},
12471 {WCD9335_CDC_TX7_TX_PATH_CFG0, 0x11, 0x11},
12472 {WCD9335_CDC_TX8_TX_PATH_CFG0, 0x11, 0x11},
12473 {WCD9335_CDC_RX0_RX_PATH_SEC0, 0xF8, 0xF8},
12474 {WCD9335_CDC_RX0_RX_PATH_SEC1, 0x08, 0x08},
12475 {WCD9335_CDC_RX1_RX_PATH_SEC1, 0x08, 0x08},
12476 {WCD9335_CDC_RX2_RX_PATH_SEC1, 0x08, 0x08},
12477 {WCD9335_CDC_RX3_RX_PATH_SEC1, 0x08, 0x08},
12478 {WCD9335_CDC_RX4_RX_PATH_SEC1, 0x08, 0x08},
12479 {WCD9335_CDC_RX5_RX_PATH_SEC1, 0x08, 0x08},
12480 {WCD9335_CDC_RX6_RX_PATH_SEC1, 0x08, 0x08},
12481 {WCD9335_CDC_RX7_RX_PATH_SEC1, 0x08, 0x08},
12482 {WCD9335_CDC_RX8_RX_PATH_SEC1, 0x08, 0x08},
12483 {WCD9335_CDC_RX0_RX_PATH_MIX_SEC0, 0x08, 0x08},
12484 {WCD9335_CDC_RX1_RX_PATH_MIX_SEC0, 0x08, 0x08},
12485 {WCD9335_CDC_RX2_RX_PATH_MIX_SEC0, 0x08, 0x08},
12486 {WCD9335_CDC_RX3_RX_PATH_MIX_SEC0, 0x08, 0x08},
12487 {WCD9335_CDC_RX4_RX_PATH_MIX_SEC0, 0x08, 0x08},
12488 {WCD9335_CDC_RX5_RX_PATH_MIX_SEC0, 0x08, 0x08},
12489 {WCD9335_CDC_RX6_RX_PATH_MIX_SEC0, 0x08, 0x08},
12490 {WCD9335_CDC_RX7_RX_PATH_MIX_SEC0, 0x08, 0x08},
12491 {WCD9335_CDC_RX8_RX_PATH_MIX_SEC0, 0x08, 0x08},
12492 {WCD9335_CDC_TX0_TX_PATH_SEC2, 0x01, 0x01},
12493 {WCD9335_CDC_TX1_TX_PATH_SEC2, 0x01, 0x01},
12494 {WCD9335_CDC_TX2_TX_PATH_SEC2, 0x01, 0x01},
12495 {WCD9335_CDC_TX3_TX_PATH_SEC2, 0x01, 0x01},
12496 {WCD9335_CDC_TX4_TX_PATH_SEC2, 0x01, 0x01},
12497 {WCD9335_CDC_TX5_TX_PATH_SEC2, 0x01, 0x01},
12498 {WCD9335_CDC_TX6_TX_PATH_SEC2, 0x01, 0x01},
12499 {WCD9335_CDC_TX7_TX_PATH_SEC2, 0x01, 0x01},
12500 {WCD9335_CDC_TX8_TX_PATH_SEC2, 0x01, 0x01},
12501 {WCD9335_CDC_RX3_RX_PATH_SEC0, 0xF8, 0xF0},
12502 {WCD9335_CDC_RX4_RX_PATH_SEC0, 0xF8, 0xF0},
12503 {WCD9335_CDC_RX5_RX_PATH_SEC0, 0xF8, 0xF8},
12504 {WCD9335_CDC_RX6_RX_PATH_SEC0, 0xF8, 0xF8},
12505 {WCD9335_RX_OCP_COUNT, 0xFF, 0xFF},
12506 {WCD9335_HPH_OCP_CTL, 0xF0, 0x70},
12507 {WCD9335_CPE_SS_CPAR_CFG, 0xFF, 0x00},
12508 {WCD9335_FLYBACK_VNEG_CTRL_1, 0xFF, 0x63},
12509 {WCD9335_FLYBACK_VNEG_CTRL_4, 0xFF, 0x7F},
12510 {WCD9335_CLASSH_CTRL_VCL_1, 0xFF, 0x60},
12511 {WCD9335_CLASSH_CTRL_CCL_5, 0xFF, 0x40},
12512 {WCD9335_RX_TIMER_DIV, 0xFF, 0x32},
12513 {WCD9335_SE_LO_COM2, 0xFF, 0x01},
12514 {WCD9335_MBHC_ZDET_ANA_CTL, 0x0F, 0x07},
12515 {WCD9335_RX_BIAS_HPH_PA, 0xF0, 0x60},
12516 {WCD9335_HPH_RDAC_LDO_CTL, 0x88, 0x88},
12517 {WCD9335_HPH_L_EN, 0x20, 0x20},
12518 {WCD9335_HPH_R_EN, 0x20, 0x20},
12519 {WCD9335_DIFF_LO_CORE_OUT_PROG, 0xFC, 0xD8},
12520 {WCD9335_CDC_RX5_RX_PATH_SEC3, 0xBD, 0xBD},
12521 {WCD9335_CDC_RX6_RX_PATH_SEC3, 0xBD, 0xBD},
12522 {WCD9335_DIFF_LO_COM_PA_FREQ, 0x70, 0x40},
12523};
12524
12525static void tasha_update_reg_reset_values(struct snd_soc_codec *codec)
12526{
12527 u32 i;
12528 struct wcd9xxx *tasha_core = dev_get_drvdata(codec->dev->parent);
12529
12530 if (TASHA_IS_1_1(tasha_core)) {
12531 for (i = 0; i < ARRAY_SIZE(tasha_reg_update_reset_val_1_1);
12532 i++)
12533 snd_soc_write(codec,
12534 tasha_reg_update_reset_val_1_1[i].reg,
12535 tasha_reg_update_reset_val_1_1[i].val);
12536 }
12537}
12538
12539static void tasha_codec_init_reg(struct snd_soc_codec *codec)
12540{
12541 u32 i;
12542 struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent);
12543
12544 for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_init_common_val); i++)
12545 snd_soc_update_bits(codec,
12546 tasha_codec_reg_init_common_val[i].reg,
12547 tasha_codec_reg_init_common_val[i].mask,
12548 tasha_codec_reg_init_common_val[i].val);
12549
12550 if (TASHA_IS_1_1(wcd9xxx) ||
12551 TASHA_IS_1_0(wcd9xxx))
12552 for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_init_1_x_val); i++)
12553 snd_soc_update_bits(codec,
12554 tasha_codec_reg_init_1_x_val[i].reg,
12555 tasha_codec_reg_init_1_x_val[i].mask,
12556 tasha_codec_reg_init_1_x_val[i].val);
12557
12558 if (TASHA_IS_1_1(wcd9xxx)) {
12559 for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_init_val_1_1); i++)
12560 snd_soc_update_bits(codec,
12561 tasha_codec_reg_init_val_1_1[i].reg,
12562 tasha_codec_reg_init_val_1_1[i].mask,
12563 tasha_codec_reg_init_val_1_1[i].val);
12564 } else if (TASHA_IS_1_0(wcd9xxx)) {
12565 for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_init_val_1_0); i++)
12566 snd_soc_update_bits(codec,
12567 tasha_codec_reg_init_val_1_0[i].reg,
12568 tasha_codec_reg_init_val_1_0[i].mask,
12569 tasha_codec_reg_init_val_1_0[i].val);
12570 } else if (TASHA_IS_2_0(wcd9xxx)) {
12571 for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_init_val_2_0); i++)
12572 snd_soc_update_bits(codec,
12573 tasha_codec_reg_init_val_2_0[i].reg,
12574 tasha_codec_reg_init_val_2_0[i].mask,
12575 tasha_codec_reg_init_val_2_0[i].val);
12576 }
12577}
12578
12579static void tasha_update_reg_defaults(struct tasha_priv *tasha)
12580{
12581 u32 i;
12582 struct wcd9xxx *wcd9xxx;
12583
12584 wcd9xxx = tasha->wcd9xxx;
12585 for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_defaults); i++)
12586 regmap_update_bits(wcd9xxx->regmap,
12587 tasha_codec_reg_defaults[i].reg,
12588 tasha_codec_reg_defaults[i].mask,
12589 tasha_codec_reg_defaults[i].val);
12590
12591 tasha->intf_type = wcd9xxx_get_intf_type();
12592 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C)
12593 for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_i2c_defaults); i++)
12594 regmap_update_bits(wcd9xxx->regmap,
12595 tasha_codec_reg_i2c_defaults[i].reg,
12596 tasha_codec_reg_i2c_defaults[i].mask,
12597 tasha_codec_reg_i2c_defaults[i].val);
12598
12599}
12600
12601static void tasha_slim_interface_init_reg(struct snd_soc_codec *codec)
12602{
12603 int i;
12604 struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec);
12605
12606 for (i = 0; i < WCD9XXX_SLIM_NUM_PORT_REG; i++)
12607 wcd9xxx_interface_reg_write(priv->wcd9xxx,
12608 TASHA_SLIM_PGD_PORT_INT_EN0 + i,
12609 0xFF);
12610}
12611
12612static irqreturn_t tasha_slimbus_irq(int irq, void *data)
12613{
12614 struct tasha_priv *priv = data;
12615 unsigned long status = 0;
12616 int i, j, port_id, k;
12617 u32 bit;
12618 u8 val, int_val = 0;
12619 bool tx, cleared;
12620 unsigned short reg = 0;
12621
12622 for (i = TASHA_SLIM_PGD_PORT_INT_STATUS_RX_0, j = 0;
12623 i <= TASHA_SLIM_PGD_PORT_INT_STATUS_TX_1; i++, j++) {
12624 val = wcd9xxx_interface_reg_read(priv->wcd9xxx, i);
12625 status |= ((u32)val << (8 * j));
12626 }
12627
12628 for_each_set_bit(j, &status, 32) {
12629 tx = (j >= 16 ? true : false);
12630 port_id = (tx ? j - 16 : j);
12631 val = wcd9xxx_interface_reg_read(priv->wcd9xxx,
12632 TASHA_SLIM_PGD_PORT_INT_RX_SOURCE0 + j);
12633 if (val) {
12634 if (!tx)
12635 reg = TASHA_SLIM_PGD_PORT_INT_EN0 +
12636 (port_id / 8);
12637 else
12638 reg = TASHA_SLIM_PGD_PORT_INT_TX_EN0 +
12639 (port_id / 8);
12640 int_val = wcd9xxx_interface_reg_read(
12641 priv->wcd9xxx, reg);
12642 /*
12643 * Ignore interrupts for ports for which the
12644 * interrupts are not specifically enabled.
12645 */
12646 if (!(int_val & (1 << (port_id % 8))))
12647 continue;
12648 }
12649 if (val & TASHA_SLIM_IRQ_OVERFLOW)
12650 pr_err_ratelimited(
12651 "%s: overflow error on %s port %d, value %x\n",
12652 __func__, (tx ? "TX" : "RX"), port_id, val);
12653 if (val & TASHA_SLIM_IRQ_UNDERFLOW)
12654 pr_err_ratelimited(
12655 "%s: underflow error on %s port %d, value %x\n",
12656 __func__, (tx ? "TX" : "RX"), port_id, val);
12657 if ((val & TASHA_SLIM_IRQ_OVERFLOW) ||
12658 (val & TASHA_SLIM_IRQ_UNDERFLOW)) {
12659 if (!tx)
12660 reg = TASHA_SLIM_PGD_PORT_INT_EN0 +
12661 (port_id / 8);
12662 else
12663 reg = TASHA_SLIM_PGD_PORT_INT_TX_EN0 +
12664 (port_id / 8);
12665 int_val = wcd9xxx_interface_reg_read(
12666 priv->wcd9xxx, reg);
12667 if (int_val & (1 << (port_id % 8))) {
12668 int_val = int_val ^ (1 << (port_id % 8));
12669 wcd9xxx_interface_reg_write(priv->wcd9xxx,
12670 reg, int_val);
12671 }
12672 }
12673 if (val & TASHA_SLIM_IRQ_PORT_CLOSED) {
12674 /*
12675 * INT SOURCE register starts from RX to TX
12676 * but port number in the ch_mask is in opposite way
12677 */
12678 bit = (tx ? j - 16 : j + 16);
12679 pr_debug("%s: %s port %d closed value %x, bit %u\n",
12680 __func__, (tx ? "TX" : "RX"), port_id, val,
12681 bit);
12682 for (k = 0, cleared = false; k < NUM_CODEC_DAIS; k++) {
12683 pr_debug("%s: priv->dai[%d].ch_mask = 0x%lx\n",
12684 __func__, k, priv->dai[k].ch_mask);
12685 if (test_and_clear_bit(bit,
12686 &priv->dai[k].ch_mask)) {
12687 cleared = true;
12688 if (!priv->dai[k].ch_mask)
12689 wake_up(&priv->dai[k].dai_wait);
12690 /*
12691 * There are cases when multiple DAIs
12692 * might be using the same slimbus
12693 * channel. Hence don't break here.
12694 */
12695 }
12696 }
12697 WARN(!cleared,
12698 "Couldn't find slimbus %s port %d for closing\n",
12699 (tx ? "TX" : "RX"), port_id);
12700 }
12701 wcd9xxx_interface_reg_write(priv->wcd9xxx,
12702 TASHA_SLIM_PGD_PORT_INT_CLR_RX_0 +
12703 (j / 8),
12704 1 << (j % 8));
12705 }
12706
12707 return IRQ_HANDLED;
12708}
12709
12710static int tasha_setup_irqs(struct tasha_priv *tasha)
12711{
12712 int ret = 0;
12713 struct snd_soc_codec *codec = tasha->codec;
12714 struct wcd9xxx *wcd9xxx = tasha->wcd9xxx;
12715 struct wcd9xxx_core_resource *core_res =
12716 &wcd9xxx->core_res;
12717
12718 ret = wcd9xxx_request_irq(core_res, WCD9XXX_IRQ_SLIMBUS,
12719 tasha_slimbus_irq, "SLIMBUS Slave", tasha);
12720 if (ret)
12721 pr_err("%s: Failed to request irq %d\n", __func__,
12722 WCD9XXX_IRQ_SLIMBUS);
12723 else
12724 tasha_slim_interface_init_reg(codec);
12725
12726 return ret;
12727}
12728
12729static void tasha_init_slim_slave_cfg(struct snd_soc_codec *codec)
12730{
12731 struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec);
12732 struct afe_param_cdc_slimbus_slave_cfg *cfg;
12733 struct wcd9xxx *wcd9xxx = priv->wcd9xxx;
12734 uint64_t eaddr = 0;
12735
12736 cfg = &priv->slimbus_slave_cfg;
12737 cfg->minor_version = 1;
12738 cfg->tx_slave_port_offset = 0;
12739 cfg->rx_slave_port_offset = 16;
12740
12741 memcpy(&eaddr, &wcd9xxx->slim->e_addr, sizeof(wcd9xxx->slim->e_addr));
12742 WARN_ON(sizeof(wcd9xxx->slim->e_addr) != 6);
12743 cfg->device_enum_addr_lsw = eaddr & 0xFFFFFFFF;
12744 cfg->device_enum_addr_msw = eaddr >> 32;
12745
12746 dev_dbg(codec->dev, "%s: slimbus logical address 0x%llx\n",
12747 __func__, eaddr);
12748}
12749
12750static void tasha_cleanup_irqs(struct tasha_priv *tasha)
12751{
12752 struct wcd9xxx *wcd9xxx = tasha->wcd9xxx;
12753 struct wcd9xxx_core_resource *core_res =
12754 &wcd9xxx->core_res;
12755
12756 wcd9xxx_free_irq(core_res, WCD9XXX_IRQ_SLIMBUS, tasha);
12757}
12758
12759static int tasha_handle_pdata(struct tasha_priv *tasha,
12760 struct wcd9xxx_pdata *pdata)
12761{
12762 struct snd_soc_codec *codec = tasha->codec;
12763 u8 dmic_ctl_val, mad_dmic_ctl_val;
12764 u8 anc_ctl_value;
12765 u32 def_dmic_rate, dmic_clk_drv;
12766 int vout_ctl_1, vout_ctl_2, vout_ctl_3, vout_ctl_4;
12767 int rc = 0;
12768
12769 if (!pdata) {
12770 dev_err(codec->dev, "%s: NULL pdata\n", __func__);
12771 return -ENODEV;
12772 }
12773
12774 /* set micbias voltage */
12775 vout_ctl_1 = wcd9335_get_micb_vout_ctl_val(pdata->micbias.micb1_mv);
12776 vout_ctl_2 = wcd9335_get_micb_vout_ctl_val(pdata->micbias.micb2_mv);
12777 vout_ctl_3 = wcd9335_get_micb_vout_ctl_val(pdata->micbias.micb3_mv);
12778 vout_ctl_4 = wcd9335_get_micb_vout_ctl_val(pdata->micbias.micb4_mv);
12779 if (vout_ctl_1 < 0 || vout_ctl_2 < 0 ||
12780 vout_ctl_3 < 0 || vout_ctl_4 < 0) {
12781 rc = -EINVAL;
12782 goto done;
12783 }
12784 snd_soc_update_bits(codec, WCD9335_ANA_MICB1, 0x3F, vout_ctl_1);
12785 snd_soc_update_bits(codec, WCD9335_ANA_MICB2, 0x3F, vout_ctl_2);
12786 snd_soc_update_bits(codec, WCD9335_ANA_MICB3, 0x3F, vout_ctl_3);
12787 snd_soc_update_bits(codec, WCD9335_ANA_MICB4, 0x3F, vout_ctl_4);
12788
12789 /* Set the DMIC sample rate */
12790 switch (pdata->mclk_rate) {
12791 case TASHA_MCLK_CLK_9P6MHZ:
12792 def_dmic_rate = WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ;
12793 break;
12794 case TASHA_MCLK_CLK_12P288MHZ:
12795 def_dmic_rate = WCD9XXX_DMIC_SAMPLE_RATE_4P096MHZ;
12796 break;
12797 default:
12798 /* should never happen */
12799 dev_err(codec->dev, "%s: Invalid mclk_rate %d\n",
12800 __func__, pdata->mclk_rate);
12801 rc = -EINVAL;
12802 goto done;
12803 };
12804
12805 if (pdata->dmic_sample_rate ==
12806 WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED) {
12807 dev_info(codec->dev, "%s: dmic_rate invalid default = %d\n",
12808 __func__, def_dmic_rate);
12809 pdata->dmic_sample_rate = def_dmic_rate;
12810 }
12811 if (pdata->mad_dmic_sample_rate ==
12812 WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED) {
12813 dev_info(codec->dev, "%s: mad_dmic_rate invalid default = %d\n",
12814 __func__, def_dmic_rate);
12815 /*
12816 * use dmic_sample_rate as the default for MAD
12817 * if mad dmic sample rate is undefined
12818 */
12819 pdata->mad_dmic_sample_rate = pdata->dmic_sample_rate;
12820 }
12821 if (pdata->ecpp_dmic_sample_rate ==
12822 WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED) {
12823 dev_info(codec->dev,
12824 "%s: ecpp_dmic_rate invalid default = %d\n",
12825 __func__, def_dmic_rate);
12826 /*
12827 * use dmic_sample_rate as the default for ECPP DMIC
12828 * if ecpp dmic sample rate is undefined
12829 */
12830 pdata->ecpp_dmic_sample_rate = pdata->dmic_sample_rate;
12831 }
12832
12833 if (pdata->dmic_clk_drv ==
12834 WCD9XXX_DMIC_CLK_DRIVE_UNDEFINED) {
12835 pdata->dmic_clk_drv = WCD9335_DMIC_CLK_DRIVE_DEFAULT;
12836 dev_info(codec->dev,
12837 "%s: dmic_clk_strength invalid, default = %d\n",
12838 __func__, pdata->dmic_clk_drv);
12839 }
12840
12841 switch (pdata->dmic_clk_drv) {
12842 case 2:
12843 dmic_clk_drv = 0;
12844 break;
12845 case 4:
12846 dmic_clk_drv = 1;
12847 break;
12848 case 8:
12849 dmic_clk_drv = 2;
12850 break;
12851 case 16:
12852 dmic_clk_drv = 3;
12853 break;
12854 default:
12855 dev_err(codec->dev,
12856 "%s: invalid dmic_clk_drv %d, using default\n",
12857 __func__, pdata->dmic_clk_drv);
12858 dmic_clk_drv = 0;
12859 break;
12860 }
12861
12862 snd_soc_update_bits(codec, WCD9335_TEST_DEBUG_PAD_DRVCTL,
12863 0x0C, dmic_clk_drv << 2);
12864
12865 /*
12866 * Default the DMIC clk rates to mad_dmic_sample_rate,
12867 * whereas, the anc/txfe dmic rates to dmic_sample_rate
12868 * since the anc/txfe are independent of mad block.
12869 */
12870 mad_dmic_ctl_val = tasha_get_dmic_clk_val(tasha->codec,
12871 pdata->mclk_rate,
12872 pdata->mad_dmic_sample_rate);
12873 snd_soc_update_bits(codec, WCD9335_CPE_SS_DMIC0_CTL,
12874 0x0E, mad_dmic_ctl_val << 1);
12875 snd_soc_update_bits(codec, WCD9335_CPE_SS_DMIC1_CTL,
12876 0x0E, mad_dmic_ctl_val << 1);
12877 snd_soc_update_bits(codec, WCD9335_CPE_SS_DMIC2_CTL,
12878 0x0E, mad_dmic_ctl_val << 1);
12879
12880 dmic_ctl_val = tasha_get_dmic_clk_val(tasha->codec,
12881 pdata->mclk_rate,
12882 pdata->dmic_sample_rate);
12883
12884 if (dmic_ctl_val == WCD9335_DMIC_CLK_DIV_2)
12885 anc_ctl_value = WCD9335_ANC_DMIC_X2_FULL_RATE;
12886 else
12887 anc_ctl_value = WCD9335_ANC_DMIC_X2_HALF_RATE;
12888
12889 snd_soc_update_bits(codec, WCD9335_CDC_ANC0_MODE_2_CTL,
12890 0x40, anc_ctl_value << 6);
12891 snd_soc_update_bits(codec, WCD9335_CDC_ANC0_MODE_2_CTL,
12892 0x20, anc_ctl_value << 5);
12893 snd_soc_update_bits(codec, WCD9335_CDC_ANC1_MODE_2_CTL,
12894 0x40, anc_ctl_value << 6);
12895 snd_soc_update_bits(codec, WCD9335_CDC_ANC1_MODE_2_CTL,
12896 0x20, anc_ctl_value << 5);
12897done:
12898 return rc;
12899}
12900
12901static struct wcd_cpe_core *tasha_codec_get_cpe_core(
12902 struct snd_soc_codec *codec)
12903{
12904 struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec);
12905
12906 return priv->cpe_core;
12907}
12908
12909static int tasha_codec_cpe_fll_update_divider(
12910 struct snd_soc_codec *codec, u32 cpe_fll_rate)
12911{
12912 struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent);
12913 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
12914
12915 u32 div_val = 0, l_val = 0;
12916 u32 computed_cpe_fll;
12917
12918 if (cpe_fll_rate != CPE_FLL_CLK_75MHZ &&
12919 cpe_fll_rate != CPE_FLL_CLK_150MHZ) {
12920 dev_err(codec->dev,
12921 "%s: Invalid CPE fll rate request %u\n",
12922 __func__, cpe_fll_rate);
12923 return -EINVAL;
12924 }
12925
12926 if (wcd9xxx->mclk_rate == TASHA_MCLK_CLK_12P288MHZ) {
12927 /* update divider to 10 and enable 5x divider */
12928 snd_soc_write(codec, WCD9335_CPE_FLL_USER_CTL_1,
12929 0x55);
12930 div_val = 10;
12931 } else if (wcd9xxx->mclk_rate == TASHA_MCLK_CLK_9P6MHZ) {
12932 /* update divider to 8 and enable 2x divider */
12933 snd_soc_update_bits(codec, WCD9335_CPE_FLL_USER_CTL_0,
12934 0x7C, 0x70);
12935 snd_soc_update_bits(codec, WCD9335_CPE_FLL_USER_CTL_1,
12936 0xE0, 0x20);
12937 div_val = 8;
12938 } else {
12939 dev_err(codec->dev,
12940 "%s: Invalid MCLK rate %u\n",
12941 __func__, wcd9xxx->mclk_rate);
12942 return -EINVAL;
12943 }
12944
12945 l_val = ((cpe_fll_rate / 1000) * div_val) /
12946 (wcd9xxx->mclk_rate / 1000);
12947
12948 /* If l_val was integer truncated, increment l_val once */
12949 computed_cpe_fll = (wcd9xxx->mclk_rate / div_val) * l_val;
12950 if (computed_cpe_fll < cpe_fll_rate)
12951 l_val++;
12952
12953
12954 /* update L value LSB and MSB */
12955 snd_soc_write(codec, WCD9335_CPE_FLL_L_VAL_CTL_0,
12956 (l_val & 0xFF));
12957 snd_soc_write(codec, WCD9335_CPE_FLL_L_VAL_CTL_1,
12958 ((l_val >> 8) & 0xFF));
12959
12960 tasha->current_cpe_clk_freq = cpe_fll_rate;
12961 dev_dbg(codec->dev,
12962 "%s: updated l_val to %u for cpe_clk %u and mclk %u\n",
12963 __func__, l_val, cpe_fll_rate, wcd9xxx->mclk_rate);
12964
12965 return 0;
12966}
12967
12968static int __tasha_cdc_change_cpe_clk(struct snd_soc_codec *codec,
12969 u32 clk_freq)
12970{
12971 int ret = 0;
12972 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
12973
12974 if (!tasha_cdc_is_svs_enabled(tasha)) {
12975 dev_dbg(codec->dev,
12976 "%s: SVS not enabled or tasha is not 2p0, return\n",
12977 __func__);
12978 return 0;
12979 }
12980 dev_dbg(codec->dev, "%s: clk_freq = %u\n", __func__, clk_freq);
12981
12982 if (clk_freq == CPE_FLL_CLK_75MHZ) {
12983 /* Change to SVS */
12984 snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE,
12985 0x08, 0x08);
12986 if (tasha_codec_cpe_fll_update_divider(codec, clk_freq)) {
12987 ret = -EINVAL;
12988 goto done;
12989 }
12990
12991 snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE,
12992 0x10, 0x10);
12993
12994 clear_bit(CPE_NOMINAL, &tasha->status_mask);
12995 tasha_codec_update_sido_voltage(tasha, sido_buck_svs_voltage);
12996
12997 } else if (clk_freq == CPE_FLL_CLK_150MHZ) {
12998 /* change to nominal */
12999 snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE,
13000 0x08, 0x08);
13001
13002 set_bit(CPE_NOMINAL, &tasha->status_mask);
13003 tasha_codec_update_sido_voltage(tasha, SIDO_VOLTAGE_NOMINAL_MV);
13004
13005 if (tasha_codec_cpe_fll_update_divider(codec, clk_freq)) {
13006 ret = -EINVAL;
13007 goto done;
13008 }
13009 snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE,
13010 0x10, 0x10);
13011 } else {
13012 dev_err(codec->dev,
13013 "%s: Invalid clk_freq request %d for CPE FLL\n",
13014 __func__, clk_freq);
13015 ret = -EINVAL;
13016 }
13017
13018done:
13019 snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE,
13020 0x10, 0x00);
13021 snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE,
13022 0x08, 0x00);
13023 return ret;
13024}
13025
13026
13027static int tasha_codec_cpe_fll_enable(struct snd_soc_codec *codec,
13028 bool enable)
13029{
13030 struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent);
13031 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
13032 u8 clk_sel_reg_val = 0x00;
13033
13034 dev_dbg(codec->dev, "%s: enable = %s\n",
13035 __func__, enable ? "true" : "false");
13036
13037 if (enable) {
13038 if (tasha_cdc_is_svs_enabled(tasha)) {
13039 /* FLL enable is always at SVS */
13040 if (__tasha_cdc_change_cpe_clk(codec,
13041 CPE_FLL_CLK_75MHZ)) {
13042 dev_err(codec->dev,
13043 "%s: clk change to %d failed\n",
13044 __func__, CPE_FLL_CLK_75MHZ);
13045 return -EINVAL;
13046 }
13047 } else {
13048 if (tasha_codec_cpe_fll_update_divider(codec,
13049 CPE_FLL_CLK_75MHZ)) {
13050 dev_err(codec->dev,
13051 "%s: clk change to %d failed\n",
13052 __func__, CPE_FLL_CLK_75MHZ);
13053 return -EINVAL;
13054 }
13055 }
13056
13057 if (TASHA_IS_1_0(wcd9xxx)) {
13058 tasha_cdc_mclk_enable(codec, true, false);
13059 clk_sel_reg_val = 0x02;
13060 }
13061
13062 /* Setup CPE reference clk */
13063 snd_soc_update_bits(codec, WCD9335_ANA_CLK_TOP,
13064 0x02, clk_sel_reg_val);
13065
13066 /* enable CPE FLL reference clk */
13067 snd_soc_update_bits(codec, WCD9335_ANA_CLK_TOP,
13068 0x01, 0x01);
13069
13070 /* program the PLL */
13071 snd_soc_update_bits(codec, WCD9335_CPE_FLL_USER_CTL_0,
13072 0x01, 0x01);
13073
13074 /* TEST clk setting */
13075 snd_soc_update_bits(codec, WCD9335_CPE_FLL_TEST_CTL_0,
13076 0x80, 0x80);
13077 /* set FLL mode to HW controlled */
13078 snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE,
13079 0x60, 0x00);
13080 snd_soc_write(codec, WCD9335_CPE_FLL_FLL_MODE, 0x80);
13081 } else {
13082 /* disable CPE FLL reference clk */
13083 snd_soc_update_bits(codec, WCD9335_ANA_CLK_TOP,
13084 0x01, 0x00);
13085 /* undo TEST clk setting */
13086 snd_soc_update_bits(codec, WCD9335_CPE_FLL_TEST_CTL_0,
13087 0x80, 0x00);
13088 /* undo FLL mode to HW control */
13089 snd_soc_write(codec, WCD9335_CPE_FLL_FLL_MODE, 0x00);
13090 snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE,
13091 0x60, 0x20);
13092 /* undo the PLL */
13093 snd_soc_update_bits(codec, WCD9335_CPE_FLL_USER_CTL_0,
13094 0x01, 0x00);
13095
13096 if (TASHA_IS_1_0(wcd9xxx))
13097 tasha_cdc_mclk_enable(codec, false, false);
13098
13099 /*
13100 * FLL could get disabled while at nominal,
13101 * scale it back to SVS
13102 */
13103 if (tasha_cdc_is_svs_enabled(tasha))
13104 __tasha_cdc_change_cpe_clk(codec,
13105 CPE_FLL_CLK_75MHZ);
13106 }
13107
13108 return 0;
13109
13110}
13111
13112static void tasha_cdc_query_cpe_clk_plan(void *data,
13113 struct cpe_svc_cfg_clk_plan *clk_freq)
13114{
13115 struct snd_soc_codec *codec = data;
13116 struct tasha_priv *tasha;
13117 u32 cpe_clk_khz;
13118
13119 if (!codec) {
13120 pr_err("%s: Invalid codec handle\n",
13121 __func__);
13122 return;
13123 }
13124
13125 tasha = snd_soc_codec_get_drvdata(codec);
13126 cpe_clk_khz = tasha->current_cpe_clk_freq / 1000;
13127
13128 dev_dbg(codec->dev,
13129 "%s: current_clk_freq = %u\n",
13130 __func__, tasha->current_cpe_clk_freq);
13131
13132 clk_freq->current_clk_feq = cpe_clk_khz;
13133 clk_freq->num_clk_freqs = 2;
13134
13135 if (tasha_cdc_is_svs_enabled(tasha)) {
13136 clk_freq->clk_freqs[0] = CPE_FLL_CLK_75MHZ / 1000;
13137 clk_freq->clk_freqs[1] = CPE_FLL_CLK_150MHZ / 1000;
13138 } else {
13139 clk_freq->clk_freqs[0] = CPE_FLL_CLK_75MHZ;
13140 clk_freq->clk_freqs[1] = CPE_FLL_CLK_150MHZ;
13141 }
13142}
13143
13144static void tasha_cdc_change_cpe_clk(void *data,
13145 u32 clk_freq)
13146{
13147 struct snd_soc_codec *codec = data;
13148 struct tasha_priv *tasha;
13149 u32 cpe_clk_khz, req_freq = 0;
13150
13151 if (!codec) {
13152 pr_err("%s: Invalid codec handle\n",
13153 __func__);
13154 return;
13155 }
13156
13157 tasha = snd_soc_codec_get_drvdata(codec);
13158 cpe_clk_khz = tasha->current_cpe_clk_freq / 1000;
13159
13160 if (tasha_cdc_is_svs_enabled(tasha)) {
13161 if ((clk_freq * 1000) <= CPE_FLL_CLK_75MHZ)
13162 req_freq = CPE_FLL_CLK_75MHZ;
13163 else
13164 req_freq = CPE_FLL_CLK_150MHZ;
13165 }
13166
13167 dev_dbg(codec->dev,
13168 "%s: requested clk_freq = %u, current clk_freq = %u\n",
13169 __func__, clk_freq * 1000,
13170 tasha->current_cpe_clk_freq);
13171
13172 if (tasha_cdc_is_svs_enabled(tasha)) {
13173 if (__tasha_cdc_change_cpe_clk(codec, req_freq))
13174 dev_err(codec->dev,
13175 "%s: clock/voltage scaling failed\n",
13176 __func__);
13177 }
13178}
13179
13180static int tasha_codec_slim_reserve_bw(struct snd_soc_codec *codec,
13181 u32 bw_ops, bool commit)
13182{
13183 struct wcd9xxx *wcd9xxx;
13184
13185 if (!codec) {
13186 pr_err("%s: Invalid handle to codec\n",
13187 __func__);
13188 return -EINVAL;
13189 }
13190
13191 wcd9xxx = dev_get_drvdata(codec->dev->parent);
13192
13193 if (!wcd9xxx) {
13194 dev_err(codec->dev, "%s: Invalid parent drv_data\n",
13195 __func__);
13196 return -EINVAL;
13197 }
13198
13199 return wcd9xxx_slim_reserve_bw(wcd9xxx, bw_ops, commit);
13200}
13201
13202static int tasha_codec_vote_max_bw(struct snd_soc_codec *codec,
13203 bool vote)
13204{
13205 u32 bw_ops;
13206 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
13207
13208 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C)
13209 return 0;
13210
Asish Bhattacharya84f7f732017-07-25 16:29:27 +053013211 mutex_lock(&tasha->sb_clk_gear_lock);
13212 if (vote) {
13213 tasha->ref_count++;
13214 if (tasha->ref_count == 1) {
13215 bw_ops = SLIM_BW_CLK_GEAR_9;
13216 tasha_codec_slim_reserve_bw(codec,
13217 bw_ops, true);
13218 }
13219 } else if (!vote && tasha->ref_count > 0) {
13220 tasha->ref_count--;
13221 if (tasha->ref_count == 0) {
13222 bw_ops = SLIM_BW_UNVOTE;
13223 tasha_codec_slim_reserve_bw(codec,
13224 bw_ops, true);
13225 }
13226 };
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013227
Asish Bhattacharya84f7f732017-07-25 16:29:27 +053013228 dev_dbg(codec->dev, "%s Value of counter after vote or un-vote is %d\n",
13229 __func__, tasha->ref_count);
13230
13231 mutex_unlock(&tasha->sb_clk_gear_lock);
13232
13233 return 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013234}
13235
13236static int tasha_cpe_err_irq_control(struct snd_soc_codec *codec,
13237 enum cpe_err_irq_cntl_type cntl_type, u8 *status)
13238{
13239 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
13240 u8 irq_bits;
13241
13242 if (TASHA_IS_2_0(tasha->wcd9xxx))
13243 irq_bits = 0xFF;
13244 else
13245 irq_bits = 0x3F;
13246
13247 if (status)
13248 irq_bits = (*status) & irq_bits;
13249
13250 switch (cntl_type) {
13251 case CPE_ERR_IRQ_MASK:
13252 snd_soc_update_bits(codec,
13253 WCD9335_CPE_SS_SS_ERROR_INT_MASK,
13254 irq_bits, irq_bits);
13255 break;
13256 case CPE_ERR_IRQ_UNMASK:
13257 snd_soc_update_bits(codec,
13258 WCD9335_CPE_SS_SS_ERROR_INT_MASK,
13259 irq_bits, 0x00);
13260 break;
13261 case CPE_ERR_IRQ_CLEAR:
13262 snd_soc_write(codec, WCD9335_CPE_SS_SS_ERROR_INT_CLEAR,
13263 irq_bits);
13264 break;
13265 case CPE_ERR_IRQ_STATUS:
13266 if (!status)
13267 return -EINVAL;
13268 *status = snd_soc_read(codec,
13269 WCD9335_CPE_SS_SS_ERROR_INT_STATUS);
13270 break;
13271 }
13272
13273 return 0;
13274}
13275
13276static const struct wcd_cpe_cdc_cb cpe_cb = {
13277 .cdc_clk_en = tasha_codec_internal_rco_ctrl,
13278 .cpe_clk_en = tasha_codec_cpe_fll_enable,
13279 .get_afe_out_port_id = tasha_codec_get_mad_port_id,
13280 .lab_cdc_ch_ctl = tasha_codec_enable_slimtx_mad,
13281 .cdc_ext_clk = tasha_cdc_mclk_enable,
13282 .bus_vote_bw = tasha_codec_vote_max_bw,
13283 .cpe_err_irq_control = tasha_cpe_err_irq_control,
13284};
13285
13286static struct cpe_svc_init_param cpe_svc_params = {
13287 .version = CPE_SVC_INIT_PARAM_V1,
13288 .query_freq_plans_cb = tasha_cdc_query_cpe_clk_plan,
13289 .change_freq_plan_cb = tasha_cdc_change_cpe_clk,
13290};
13291
13292static int tasha_cpe_initialize(struct snd_soc_codec *codec)
13293{
13294 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
13295 struct wcd_cpe_params cpe_params;
13296
13297 memset(&cpe_params, 0,
13298 sizeof(struct wcd_cpe_params));
13299 cpe_params.codec = codec;
13300 cpe_params.get_cpe_core = tasha_codec_get_cpe_core;
13301 cpe_params.cdc_cb = &cpe_cb;
13302 cpe_params.dbg_mode = cpe_debug_mode;
13303 cpe_params.cdc_major_ver = CPE_SVC_CODEC_WCD9335;
13304 cpe_params.cdc_minor_ver = CPE_SVC_CODEC_V1P0;
13305 cpe_params.cdc_id = CPE_SVC_CODEC_WCD9335;
13306
13307 cpe_params.cdc_irq_info.cpe_engine_irq =
13308 WCD9335_IRQ_SVA_OUTBOX1;
13309 cpe_params.cdc_irq_info.cpe_err_irq =
13310 WCD9335_IRQ_SVA_ERROR;
13311 cpe_params.cdc_irq_info.cpe_fatal_irqs =
13312 TASHA_CPE_FATAL_IRQS;
13313
13314 cpe_svc_params.context = codec;
13315 cpe_params.cpe_svc_params = &cpe_svc_params;
13316
13317 tasha->cpe_core = wcd_cpe_init("cpe_9335", codec,
13318 &cpe_params);
13319 if (IS_ERR_OR_NULL(tasha->cpe_core)) {
13320 dev_err(codec->dev,
13321 "%s: Failed to enable CPE\n",
13322 __func__);
13323 return -EINVAL;
13324 }
13325
13326 return 0;
13327}
13328
13329static const struct wcd_resmgr_cb tasha_resmgr_cb = {
13330 .cdc_rco_ctrl = __tasha_codec_internal_rco_ctrl,
13331};
13332
13333static int tasha_device_down(struct wcd9xxx *wcd9xxx)
13334{
13335 struct snd_soc_codec *codec;
13336 struct tasha_priv *priv;
13337 int count;
13338 int i = 0;
13339
13340 codec = (struct snd_soc_codec *)(wcd9xxx->ssr_priv);
13341 priv = snd_soc_codec_get_drvdata(codec);
13342 wcd_cpe_ssr_event(priv->cpe_core, WCD_CPE_BUS_DOWN_EVENT);
13343 for (i = 0; i < priv->nr; i++)
13344 swrm_wcd_notify(priv->swr_ctrl_data[i].swr_pdev,
13345 SWR_DEVICE_DOWN, NULL);
13346 snd_soc_card_change_online_state(codec->component.card, 0);
13347 for (count = 0; count < NUM_CODEC_DAIS; count++)
13348 priv->dai[count].bus_down_in_recovery = true;
13349
13350 priv->resmgr->sido_input_src = SIDO_SOURCE_INTERNAL;
13351
13352 return 0;
13353}
13354
13355static int tasha_post_reset_cb(struct wcd9xxx *wcd9xxx)
13356{
13357 int i, ret = 0;
13358 struct wcd9xxx *control;
13359 struct snd_soc_codec *codec;
13360 struct tasha_priv *tasha;
13361 struct wcd9xxx_pdata *pdata;
13362
13363 codec = (struct snd_soc_codec *)(wcd9xxx->ssr_priv);
13364 tasha = snd_soc_codec_get_drvdata(codec);
13365 control = dev_get_drvdata(codec->dev->parent);
13366
13367 wcd9xxx_set_power_state(tasha->wcd9xxx,
13368 WCD_REGION_POWER_COLLAPSE_REMOVE,
13369 WCD9XXX_DIG_CORE_REGION_1);
13370
13371 mutex_lock(&tasha->codec_mutex);
13372
13373 tasha_slimbus_slave_port_cfg.slave_dev_intfdev_la =
13374 control->slim_slave->laddr;
13375 tasha_slimbus_slave_port_cfg.slave_dev_pgd_la =
13376 control->slim->laddr;
13377 tasha_init_slim_slave_cfg(codec);
13378 if (tasha->machine_codec_event_cb)
13379 tasha->machine_codec_event_cb(codec,
13380 WCD9335_CODEC_EVENT_CODEC_UP);
13381 snd_soc_card_change_online_state(codec->component.card, 1);
13382
13383 /* Class-H Init*/
13384 wcd_clsh_init(&tasha->clsh_d);
13385
13386 for (i = 0; i < TASHA_MAX_MICBIAS; i++)
13387 tasha->micb_ref[i] = 0;
13388
13389 tasha_update_reg_defaults(tasha);
13390
13391 tasha->codec = codec;
13392
13393 dev_dbg(codec->dev, "%s: MCLK Rate = %x\n",
13394 __func__, control->mclk_rate);
13395
13396 if (control->mclk_rate == TASHA_MCLK_CLK_12P288MHZ)
13397 snd_soc_update_bits(codec, WCD9335_CODEC_RPM_CLK_MCLK_CFG,
13398 0x03, 0x00);
13399 else if (control->mclk_rate == TASHA_MCLK_CLK_9P6MHZ)
13400 snd_soc_update_bits(codec, WCD9335_CODEC_RPM_CLK_MCLK_CFG,
13401 0x03, 0x01);
13402 tasha_codec_init_reg(codec);
13403
13404 wcd_resmgr_post_ssr_v2(tasha->resmgr);
13405
13406 tasha_enable_efuse_sensing(codec);
13407
13408 regcache_mark_dirty(codec->component.regmap);
13409 regcache_sync(codec->component.regmap);
13410
13411 pdata = dev_get_platdata(codec->dev->parent);
13412 ret = tasha_handle_pdata(tasha, pdata);
13413 if (ret < 0)
13414 dev_err(codec->dev, "%s: invalid pdata\n", __func__);
13415
Asish Bhattacharya84f7f732017-07-25 16:29:27 +053013416 /* Reset reference counter for voting for max bw */
13417 tasha->ref_count = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013418 /* MBHC Init */
13419 wcd_mbhc_deinit(&tasha->mbhc);
13420 tasha->mbhc_started = false;
13421
13422 /* Initialize MBHC module */
13423 ret = wcd_mbhc_init(&tasha->mbhc, codec, &mbhc_cb, &intr_ids,
13424 wcd_mbhc_registers, TASHA_ZDET_SUPPORTED);
13425 if (ret)
13426 dev_err(codec->dev, "%s: mbhc initialization failed\n",
13427 __func__);
13428 else
13429 tasha_mbhc_hs_detect(codec, tasha->mbhc.mbhc_cfg);
13430
13431 tasha_cleanup_irqs(tasha);
13432 ret = tasha_setup_irqs(tasha);
13433 if (ret) {
13434 dev_err(codec->dev, "%s: tasha irq setup failed %d\n",
13435 __func__, ret);
13436 goto err;
13437 }
13438
13439 tasha_set_spkr_mode(codec, tasha->spkr_mode);
13440 wcd_cpe_ssr_event(tasha->cpe_core, WCD_CPE_BUS_UP_EVENT);
13441
13442err:
13443 mutex_unlock(&tasha->codec_mutex);
13444 return ret;
13445}
13446
13447static struct regulator *tasha_codec_find_ondemand_regulator(
13448 struct snd_soc_codec *codec, const char *name)
13449{
13450 int i;
13451 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
13452 struct wcd9xxx *wcd9xxx = tasha->wcd9xxx;
13453 struct wcd9xxx_pdata *pdata = dev_get_platdata(codec->dev->parent);
13454
13455 for (i = 0; i < wcd9xxx->num_of_supplies; ++i) {
13456 if (pdata->regulator[i].ondemand &&
13457 wcd9xxx->supplies[i].supply &&
13458 !strcmp(wcd9xxx->supplies[i].supply, name))
13459 return wcd9xxx->supplies[i].consumer;
13460 }
13461
13462 dev_dbg(tasha->dev, "Warning: regulator not found:%s\n",
13463 name);
13464 return NULL;
13465}
13466
13467static int tasha_codec_probe(struct snd_soc_codec *codec)
13468{
13469 struct wcd9xxx *control;
13470 struct tasha_priv *tasha;
13471 struct wcd9xxx_pdata *pdata;
13472 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
13473 int i, ret;
13474 void *ptr = NULL;
13475 struct regulator *supply;
13476
13477 control = dev_get_drvdata(codec->dev->parent);
13478
13479 dev_info(codec->dev, "%s()\n", __func__);
13480 tasha = snd_soc_codec_get_drvdata(codec);
13481 tasha->intf_type = wcd9xxx_get_intf_type();
13482
13483 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
13484 control->dev_down = tasha_device_down;
13485 control->post_reset = tasha_post_reset_cb;
13486 control->ssr_priv = (void *)codec;
13487 }
13488
13489 /* Resource Manager post Init */
13490 ret = wcd_resmgr_post_init(tasha->resmgr, &tasha_resmgr_cb, codec);
13491 if (ret) {
13492 dev_err(codec->dev, "%s: wcd resmgr post init failed\n",
13493 __func__);
13494 goto err;
13495 }
13496 /* Class-H Init*/
13497 wcd_clsh_init(&tasha->clsh_d);
13498 /* Default HPH Mode to Class-H HiFi */
13499 tasha->hph_mode = CLS_H_HIFI;
13500
13501 tasha->codec = codec;
13502 for (i = 0; i < COMPANDER_MAX; i++)
13503 tasha->comp_enabled[i] = 0;
13504
13505 tasha->spkr_gain_offset = RX_GAIN_OFFSET_0_DB;
13506 tasha->intf_type = wcd9xxx_get_intf_type();
13507 tasha_update_reg_reset_values(codec);
13508 pr_debug("%s: MCLK Rate = %x\n", __func__, control->mclk_rate);
13509 if (control->mclk_rate == TASHA_MCLK_CLK_12P288MHZ)
13510 snd_soc_update_bits(codec, WCD9335_CODEC_RPM_CLK_MCLK_CFG,
13511 0x03, 0x00);
13512 else if (control->mclk_rate == TASHA_MCLK_CLK_9P6MHZ)
13513 snd_soc_update_bits(codec, WCD9335_CODEC_RPM_CLK_MCLK_CFG,
13514 0x03, 0x01);
13515 tasha_codec_init_reg(codec);
13516
13517 tasha_enable_efuse_sensing(codec);
13518
13519 pdata = dev_get_platdata(codec->dev->parent);
13520 ret = tasha_handle_pdata(tasha, pdata);
13521 if (ret < 0) {
13522 pr_err("%s: bad pdata\n", __func__);
13523 goto err;
13524 }
13525
13526 supply = tasha_codec_find_ondemand_regulator(codec,
13527 on_demand_supply_name[ON_DEMAND_MICBIAS]);
13528 if (supply) {
13529 tasha->on_demand_list[ON_DEMAND_MICBIAS].supply = supply;
13530 tasha->on_demand_list[ON_DEMAND_MICBIAS].ondemand_supply_count =
13531 0;
13532 }
13533
13534 tasha->fw_data = devm_kzalloc(codec->dev,
13535 sizeof(*(tasha->fw_data)), GFP_KERNEL);
13536 if (!tasha->fw_data)
13537 goto err;
13538 set_bit(WCD9XXX_ANC_CAL, tasha->fw_data->cal_bit);
13539 set_bit(WCD9XXX_MBHC_CAL, tasha->fw_data->cal_bit);
13540 set_bit(WCD9XXX_MAD_CAL, tasha->fw_data->cal_bit);
13541 set_bit(WCD9XXX_VBAT_CAL, tasha->fw_data->cal_bit);
13542
13543 ret = wcd_cal_create_hwdep(tasha->fw_data,
13544 WCD9XXX_CODEC_HWDEP_NODE, codec);
13545 if (ret < 0) {
13546 dev_err(codec->dev, "%s hwdep failed %d\n", __func__, ret);
13547 goto err_hwdep;
13548 }
13549
13550 /* Initialize MBHC module */
13551 if (TASHA_IS_2_0(tasha->wcd9xxx)) {
13552 wcd_mbhc_registers[WCD_MBHC_FSM_STATUS].reg =
13553 WCD9335_MBHC_FSM_STATUS;
13554 wcd_mbhc_registers[WCD_MBHC_FSM_STATUS].mask = 0x01;
13555 }
13556 ret = wcd_mbhc_init(&tasha->mbhc, codec, &mbhc_cb, &intr_ids,
13557 wcd_mbhc_registers, TASHA_ZDET_SUPPORTED);
13558 if (ret) {
13559 pr_err("%s: mbhc initialization failed\n", __func__);
13560 goto err_hwdep;
13561 }
13562
13563 ptr = devm_kzalloc(codec->dev, (sizeof(tasha_rx_chs) +
13564 sizeof(tasha_tx_chs)), GFP_KERNEL);
13565 if (!ptr) {
13566 ret = -ENOMEM;
13567 goto err_hwdep;
13568 }
13569
13570 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
13571 snd_soc_dapm_new_controls(dapm, tasha_dapm_i2s_widgets,
13572 ARRAY_SIZE(tasha_dapm_i2s_widgets));
13573 snd_soc_dapm_add_routes(dapm, audio_i2s_map,
13574 ARRAY_SIZE(audio_i2s_map));
13575 for (i = 0; i < ARRAY_SIZE(tasha_i2s_dai); i++) {
13576 INIT_LIST_HEAD(&tasha->dai[i].wcd9xxx_ch_list);
13577 init_waitqueue_head(&tasha->dai[i].dai_wait);
13578 }
13579 } else if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
13580 for (i = 0; i < NUM_CODEC_DAIS; i++) {
13581 INIT_LIST_HEAD(&tasha->dai[i].wcd9xxx_ch_list);
13582 init_waitqueue_head(&tasha->dai[i].dai_wait);
13583 }
13584 tasha_slimbus_slave_port_cfg.slave_dev_intfdev_la =
13585 control->slim_slave->laddr;
13586 tasha_slimbus_slave_port_cfg.slave_dev_pgd_la =
13587 control->slim->laddr;
13588 tasha_slimbus_slave_port_cfg.slave_port_mapping[0] =
13589 TASHA_TX13;
13590 tasha_init_slim_slave_cfg(codec);
13591 }
13592
13593 snd_soc_add_codec_controls(codec, impedance_detect_controls,
13594 ARRAY_SIZE(impedance_detect_controls));
13595 snd_soc_add_codec_controls(codec, hph_type_detect_controls,
13596 ARRAY_SIZE(hph_type_detect_controls));
13597
13598 snd_soc_add_codec_controls(codec,
13599 tasha_analog_gain_controls,
13600 ARRAY_SIZE(tasha_analog_gain_controls));
13601 control->num_rx_port = TASHA_RX_MAX;
13602 control->rx_chs = ptr;
13603 memcpy(control->rx_chs, tasha_rx_chs, sizeof(tasha_rx_chs));
13604 control->num_tx_port = TASHA_TX_MAX;
13605 control->tx_chs = ptr + sizeof(tasha_rx_chs);
13606 memcpy(control->tx_chs, tasha_tx_chs, sizeof(tasha_tx_chs));
13607
13608 snd_soc_dapm_ignore_suspend(dapm, "AIF1 Playback");
13609 snd_soc_dapm_ignore_suspend(dapm, "AIF1 Capture");
13610 snd_soc_dapm_ignore_suspend(dapm, "AIF2 Playback");
13611 snd_soc_dapm_ignore_suspend(dapm, "AIF2 Capture");
13612
13613 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
13614 snd_soc_dapm_ignore_suspend(dapm, "AIF3 Playback");
13615 snd_soc_dapm_ignore_suspend(dapm, "AIF3 Capture");
13616 snd_soc_dapm_ignore_suspend(dapm, "AIF4 Playback");
13617 snd_soc_dapm_ignore_suspend(dapm, "AIF Mix Playback");
13618 snd_soc_dapm_ignore_suspend(dapm, "AIF4 MAD TX");
13619 snd_soc_dapm_ignore_suspend(dapm, "VIfeed");
13620 snd_soc_dapm_ignore_suspend(dapm, "AIF5 CPE TX");
13621 }
13622
13623 snd_soc_dapm_sync(dapm);
13624
13625 ret = tasha_setup_irqs(tasha);
13626 if (ret) {
13627 pr_err("%s: tasha irq setup failed %d\n", __func__, ret);
13628 goto err_pdata;
13629 }
13630
13631 ret = tasha_cpe_initialize(codec);
13632 if (ret) {
13633 dev_err(codec->dev,
13634 "%s: cpe initialization failed, err = %d\n",
13635 __func__, ret);
13636 /* Do not fail probe if CPE failed */
13637 ret = 0;
13638 }
13639
13640 for (i = 0; i < TASHA_NUM_DECIMATORS; i++) {
13641 tasha->tx_hpf_work[i].tasha = tasha;
13642 tasha->tx_hpf_work[i].decimator = i;
13643 INIT_DELAYED_WORK(&tasha->tx_hpf_work[i].dwork,
13644 tasha_tx_hpf_corner_freq_callback);
13645 }
13646
13647 for (i = 0; i < TASHA_NUM_DECIMATORS; i++) {
13648 tasha->tx_mute_dwork[i].tasha = tasha;
13649 tasha->tx_mute_dwork[i].decimator = i;
13650 INIT_DELAYED_WORK(&tasha->tx_mute_dwork[i].dwork,
13651 tasha_tx_mute_update_callback);
13652 }
13653
13654 tasha->spk_anc_dwork.tasha = tasha;
13655 INIT_DELAYED_WORK(&tasha->spk_anc_dwork.dwork,
13656 tasha_spk_anc_update_callback);
13657
13658 mutex_lock(&tasha->codec_mutex);
13659 snd_soc_dapm_disable_pin(dapm, "ANC LINEOUT1");
13660 snd_soc_dapm_disable_pin(dapm, "ANC LINEOUT2");
13661 snd_soc_dapm_disable_pin(dapm, "ANC LINEOUT1 PA");
13662 snd_soc_dapm_disable_pin(dapm, "ANC LINEOUT2 PA");
13663 snd_soc_dapm_disable_pin(dapm, "ANC HPHL");
13664 snd_soc_dapm_disable_pin(dapm, "ANC HPHR");
13665 snd_soc_dapm_disable_pin(dapm, "ANC HPHL PA");
13666 snd_soc_dapm_disable_pin(dapm, "ANC HPHR PA");
13667 snd_soc_dapm_disable_pin(dapm, "ANC EAR PA");
13668 snd_soc_dapm_disable_pin(dapm, "ANC EAR");
13669 snd_soc_dapm_disable_pin(dapm, "ANC SPK1 PA");
13670 mutex_unlock(&tasha->codec_mutex);
13671 snd_soc_dapm_sync(dapm);
13672
13673 return ret;
13674
13675err_pdata:
13676 devm_kfree(codec->dev, ptr);
13677 control->rx_chs = NULL;
13678 control->tx_chs = NULL;
13679err_hwdep:
13680 devm_kfree(codec->dev, tasha->fw_data);
13681 tasha->fw_data = NULL;
13682err:
13683 return ret;
13684}
13685
13686static int tasha_codec_remove(struct snd_soc_codec *codec)
13687{
13688 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
13689 struct wcd9xxx *control;
13690
13691 control = dev_get_drvdata(codec->dev->parent);
Meng Wang3b194492017-09-27 12:20:22 +080013692 control->num_rx_port = 0;
13693 control->num_tx_port = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013694 control->rx_chs = NULL;
13695 control->tx_chs = NULL;
13696
13697 tasha_cleanup_irqs(tasha);
13698 /* Cleanup MBHC */
Meng Wang3b194492017-09-27 12:20:22 +080013699 wcd_mbhc_deinit(&tasha->mbhc);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013700 /* Cleanup resmgr */
13701
13702 return 0;
13703}
13704
13705static struct regmap *tasha_get_regmap(struct device *dev)
13706{
13707 struct wcd9xxx *control = dev_get_drvdata(dev->parent);
13708
13709 return control->regmap;
13710}
13711
13712static struct snd_soc_codec_driver soc_codec_dev_tasha = {
13713 .probe = tasha_codec_probe,
13714 .remove = tasha_codec_remove,
13715 .get_regmap = tasha_get_regmap,
13716 .component_driver = {
13717 .controls = tasha_snd_controls,
13718 .num_controls = ARRAY_SIZE(tasha_snd_controls),
13719 .dapm_widgets = tasha_dapm_widgets,
13720 .num_dapm_widgets = ARRAY_SIZE(tasha_dapm_widgets),
13721 .dapm_routes = audio_map,
13722 .num_dapm_routes = ARRAY_SIZE(audio_map),
13723 },
13724};
13725
13726#ifdef CONFIG_PM
13727static int tasha_suspend(struct device *dev)
13728{
13729 struct platform_device *pdev = to_platform_device(dev);
13730 struct tasha_priv *tasha = platform_get_drvdata(pdev);
13731
13732 dev_dbg(dev, "%s: system suspend\n", __func__);
13733 if (cancel_delayed_work_sync(&tasha->power_gate_work))
13734 tasha_codec_power_gate_digital_core(tasha);
13735
13736 return 0;
13737}
13738
13739static int tasha_resume(struct device *dev)
13740{
13741 struct platform_device *pdev = to_platform_device(dev);
13742 struct tasha_priv *tasha = platform_get_drvdata(pdev);
13743
13744 if (!tasha) {
13745 dev_err(dev, "%s: tasha private data is NULL\n", __func__);
13746 return -EINVAL;
13747 }
13748 dev_dbg(dev, "%s: system resume\n", __func__);
13749 return 0;
13750}
13751
13752static const struct dev_pm_ops tasha_pm_ops = {
13753 .suspend = tasha_suspend,
13754 .resume = tasha_resume,
13755};
13756#endif
13757
13758static int tasha_swrm_read(void *handle, int reg)
13759{
13760 struct tasha_priv *tasha;
13761 struct wcd9xxx *wcd9xxx;
13762 unsigned short swr_rd_addr_base;
13763 unsigned short swr_rd_data_base;
13764 int val, ret;
13765
13766 if (!handle) {
13767 pr_err("%s: NULL handle\n", __func__);
13768 return -EINVAL;
13769 }
13770 tasha = (struct tasha_priv *)handle;
13771 wcd9xxx = tasha->wcd9xxx;
13772
13773 dev_dbg(tasha->dev, "%s: Reading soundwire register, 0x%x\n",
13774 __func__, reg);
13775 swr_rd_addr_base = WCD9335_SWR_AHB_BRIDGE_RD_ADDR_0;
13776 swr_rd_data_base = WCD9335_SWR_AHB_BRIDGE_RD_DATA_0;
13777 /* read_lock */
13778 mutex_lock(&tasha->swr_read_lock);
13779 ret = regmap_bulk_write(wcd9xxx->regmap, swr_rd_addr_base,
13780 (u8 *)&reg, 4);
13781 if (ret < 0) {
13782 pr_err("%s: RD Addr Failure\n", __func__);
13783 goto err;
13784 }
13785 /* Check for RD status */
13786 ret = regmap_bulk_read(wcd9xxx->regmap, swr_rd_data_base,
13787 (u8 *)&val, 4);
13788 if (ret < 0) {
13789 pr_err("%s: RD Data Failure\n", __func__);
13790 goto err;
13791 }
13792 ret = val;
13793err:
13794 /* read_unlock */
13795 mutex_unlock(&tasha->swr_read_lock);
13796 return ret;
13797}
13798
13799static int tasha_swrm_i2s_bulk_write(struct wcd9xxx *wcd9xxx,
13800 struct wcd9xxx_reg_val *bulk_reg,
13801 size_t len)
13802{
13803 int i, ret = 0;
13804 unsigned short swr_wr_addr_base;
13805 unsigned short swr_wr_data_base;
13806
13807 swr_wr_addr_base = WCD9335_SWR_AHB_BRIDGE_WR_ADDR_0;
13808 swr_wr_data_base = WCD9335_SWR_AHB_BRIDGE_WR_DATA_0;
13809
13810 for (i = 0; i < (len * 2); i += 2) {
13811 /* First Write the Data to register */
13812 ret = regmap_bulk_write(wcd9xxx->regmap,
13813 swr_wr_data_base, bulk_reg[i].buf, 4);
13814 if (ret < 0) {
13815 dev_err(wcd9xxx->dev, "%s: WR Data Failure\n",
13816 __func__);
13817 break;
13818 }
13819 /* Next Write Address */
13820 ret = regmap_bulk_write(wcd9xxx->regmap,
13821 swr_wr_addr_base, bulk_reg[i+1].buf, 4);
13822 if (ret < 0) {
13823 dev_err(wcd9xxx->dev, "%s: WR Addr Failure\n",
13824 __func__);
13825 break;
13826 }
13827 }
13828 return ret;
13829}
13830
13831static int tasha_swrm_bulk_write(void *handle, u32 *reg, u32 *val, size_t len)
13832{
13833 struct tasha_priv *tasha;
13834 struct wcd9xxx *wcd9xxx;
13835 struct wcd9xxx_reg_val *bulk_reg;
13836 unsigned short swr_wr_addr_base;
13837 unsigned short swr_wr_data_base;
13838 int i, j, ret;
13839
13840 if (!handle) {
13841 pr_err("%s: NULL handle\n", __func__);
13842 return -EINVAL;
13843 }
13844 if (len <= 0) {
13845 pr_err("%s: Invalid size: %zu\n", __func__, len);
13846 return -EINVAL;
13847 }
13848 tasha = (struct tasha_priv *)handle;
13849 wcd9xxx = tasha->wcd9xxx;
13850
13851 swr_wr_addr_base = WCD9335_SWR_AHB_BRIDGE_WR_ADDR_0;
13852 swr_wr_data_base = WCD9335_SWR_AHB_BRIDGE_WR_DATA_0;
13853
13854 bulk_reg = kzalloc((2 * len * sizeof(struct wcd9xxx_reg_val)),
13855 GFP_KERNEL);
13856 if (!bulk_reg)
13857 return -ENOMEM;
13858
13859 for (i = 0, j = 0; i < (len * 2); i += 2, j++) {
13860 bulk_reg[i].reg = swr_wr_data_base;
13861 bulk_reg[i].buf = (u8 *)(&val[j]);
13862 bulk_reg[i].bytes = 4;
13863 bulk_reg[i+1].reg = swr_wr_addr_base;
13864 bulk_reg[i+1].buf = (u8 *)(&reg[j]);
13865 bulk_reg[i+1].bytes = 4;
13866 }
13867 mutex_lock(&tasha->swr_write_lock);
13868
13869 if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C) {
13870 ret = tasha_swrm_i2s_bulk_write(wcd9xxx, bulk_reg, len);
13871 if (ret) {
13872 dev_err(tasha->dev, "%s: i2s bulk write failed, ret: %d\n",
13873 __func__, ret);
13874 }
13875 } else {
13876 ret = wcd9xxx_slim_bulk_write(wcd9xxx, bulk_reg,
13877 (len * 2), false);
13878 if (ret) {
13879 dev_err(tasha->dev, "%s: swrm bulk write failed, ret: %d\n",
13880 __func__, ret);
13881 }
13882 }
13883
13884 mutex_unlock(&tasha->swr_write_lock);
13885 kfree(bulk_reg);
13886
13887 return ret;
13888}
13889
13890static int tasha_swrm_write(void *handle, int reg, int val)
13891{
13892 struct tasha_priv *tasha;
13893 struct wcd9xxx *wcd9xxx;
13894 unsigned short swr_wr_addr_base;
13895 unsigned short swr_wr_data_base;
13896 struct wcd9xxx_reg_val bulk_reg[2];
13897 int ret;
13898
13899 if (!handle) {
13900 pr_err("%s: NULL handle\n", __func__);
13901 return -EINVAL;
13902 }
13903 tasha = (struct tasha_priv *)handle;
13904 wcd9xxx = tasha->wcd9xxx;
13905
13906 swr_wr_addr_base = WCD9335_SWR_AHB_BRIDGE_WR_ADDR_0;
13907 swr_wr_data_base = WCD9335_SWR_AHB_BRIDGE_WR_DATA_0;
13908
13909 /* First Write the Data to register */
13910 bulk_reg[0].reg = swr_wr_data_base;
13911 bulk_reg[0].buf = (u8 *)(&val);
13912 bulk_reg[0].bytes = 4;
13913 bulk_reg[1].reg = swr_wr_addr_base;
13914 bulk_reg[1].buf = (u8 *)(&reg);
13915 bulk_reg[1].bytes = 4;
13916
13917 mutex_lock(&tasha->swr_write_lock);
13918
13919 if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C) {
13920 ret = tasha_swrm_i2s_bulk_write(wcd9xxx, bulk_reg, 1);
13921 if (ret) {
13922 dev_err(tasha->dev, "%s: i2s swrm write failed, ret: %d\n",
13923 __func__, ret);
13924 }
13925 } else {
13926 ret = wcd9xxx_slim_bulk_write(wcd9xxx, bulk_reg, 2, false);
13927 if (ret < 0)
13928 pr_err("%s: WR Data Failure\n", __func__);
13929 }
13930
13931 mutex_unlock(&tasha->swr_write_lock);
13932 return ret;
13933}
13934
13935static int tasha_swrm_clock(void *handle, bool enable)
13936{
13937 struct tasha_priv *tasha = (struct tasha_priv *) handle;
13938
13939 mutex_lock(&tasha->swr_clk_lock);
13940
13941 dev_dbg(tasha->dev, "%s: swrm clock %s\n",
13942 __func__, (enable?"enable" : "disable"));
13943 if (enable) {
13944 tasha->swr_clk_users++;
13945 if (tasha->swr_clk_users == 1) {
13946 if (TASHA_IS_2_0(tasha->wcd9xxx))
13947 regmap_update_bits(
13948 tasha->wcd9xxx->regmap,
13949 WCD9335_TEST_DEBUG_NPL_DLY_TEST_1,
13950 0x10, 0x00);
13951 __tasha_cdc_mclk_enable(tasha, true);
13952 regmap_update_bits(tasha->wcd9xxx->regmap,
13953 WCD9335_CDC_CLK_RST_CTRL_SWR_CONTROL,
13954 0x01, 0x01);
13955 }
13956 } else {
13957 tasha->swr_clk_users--;
13958 if (tasha->swr_clk_users == 0) {
13959 regmap_update_bits(tasha->wcd9xxx->regmap,
13960 WCD9335_CDC_CLK_RST_CTRL_SWR_CONTROL,
13961 0x01, 0x00);
13962 __tasha_cdc_mclk_enable(tasha, false);
13963 if (TASHA_IS_2_0(tasha->wcd9xxx))
13964 regmap_update_bits(
13965 tasha->wcd9xxx->regmap,
13966 WCD9335_TEST_DEBUG_NPL_DLY_TEST_1,
13967 0x10, 0x10);
13968 }
13969 }
13970 dev_dbg(tasha->dev, "%s: swrm clock users %d\n",
13971 __func__, tasha->swr_clk_users);
13972 mutex_unlock(&tasha->swr_clk_lock);
13973 return 0;
13974}
13975
13976static int tasha_swrm_handle_irq(void *handle,
13977 irqreturn_t (*swrm_irq_handler)(int irq,
13978 void *data),
13979 void *swrm_handle,
13980 int action)
13981{
13982 struct tasha_priv *tasha;
13983 int ret = 0;
13984 struct wcd9xxx *wcd9xxx;
13985
13986 if (!handle) {
13987 pr_err("%s: null handle received\n", __func__);
13988 return -EINVAL;
13989 }
13990 tasha = (struct tasha_priv *) handle;
13991 wcd9xxx = tasha->wcd9xxx;
13992
13993 if (action) {
13994 ret = wcd9xxx_request_irq(&wcd9xxx->core_res,
13995 WCD9335_IRQ_SOUNDWIRE,
13996 swrm_irq_handler,
13997 "Tasha SWR Master", swrm_handle);
13998 if (ret)
13999 dev_err(tasha->dev, "%s: Failed to request irq %d\n",
14000 __func__, WCD9335_IRQ_SOUNDWIRE);
14001 } else
14002 wcd9xxx_free_irq(&wcd9xxx->core_res, WCD9335_IRQ_SOUNDWIRE,
14003 swrm_handle);
14004
14005 return ret;
14006}
14007
14008static void tasha_add_child_devices(struct work_struct *work)
14009{
14010 struct tasha_priv *tasha;
14011 struct platform_device *pdev;
14012 struct device_node *node;
14013 struct wcd9xxx *wcd9xxx;
14014 struct tasha_swr_ctrl_data *swr_ctrl_data = NULL, *temp;
14015 int ret, ctrl_num = 0;
14016 struct wcd_swr_ctrl_platform_data *platdata;
14017 char plat_dev_name[WCD9335_STRING_LEN];
14018
14019 tasha = container_of(work, struct tasha_priv,
14020 tasha_add_child_devices_work);
14021 if (!tasha) {
14022 pr_err("%s: Memory for WCD9335 does not exist\n",
14023 __func__);
14024 return;
14025 }
14026 wcd9xxx = tasha->wcd9xxx;
14027 if (!wcd9xxx) {
14028 pr_err("%s: Memory for WCD9XXX does not exist\n",
14029 __func__);
14030 return;
14031 }
14032 if (!wcd9xxx->dev->of_node) {
14033 pr_err("%s: DT node for wcd9xxx does not exist\n",
14034 __func__);
14035 return;
14036 }
14037
14038 platdata = &tasha->swr_plat_data;
Meng Wang3b194492017-09-27 12:20:22 +080014039 tasha->child_count = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053014040
14041 for_each_child_of_node(wcd9xxx->dev->of_node, node) {
14042 if (!strcmp(node->name, "swr_master"))
14043 strlcpy(plat_dev_name, "tasha_swr_ctrl",
14044 (WCD9335_STRING_LEN - 1));
14045 else if (strnstr(node->name, "msm_cdc_pinctrl",
14046 strlen("msm_cdc_pinctrl")) != NULL)
14047 strlcpy(plat_dev_name, node->name,
14048 (WCD9335_STRING_LEN - 1));
14049 else
14050 continue;
14051
14052 pdev = platform_device_alloc(plat_dev_name, -1);
14053 if (!pdev) {
14054 dev_err(wcd9xxx->dev, "%s: pdev memory alloc failed\n",
14055 __func__);
14056 ret = -ENOMEM;
14057 goto err;
14058 }
14059 pdev->dev.parent = tasha->dev;
14060 pdev->dev.of_node = node;
14061
14062 if (!strcmp(node->name, "swr_master")) {
14063 ret = platform_device_add_data(pdev, platdata,
14064 sizeof(*platdata));
14065 if (ret) {
14066 dev_err(&pdev->dev,
14067 "%s: cannot add plat data ctrl:%d\n",
14068 __func__, ctrl_num);
14069 goto fail_pdev_add;
14070 }
14071 }
14072
14073 ret = platform_device_add(pdev);
14074 if (ret) {
14075 dev_err(&pdev->dev,
14076 "%s: Cannot add platform device\n",
14077 __func__);
14078 goto fail_pdev_add;
14079 }
14080
14081 if (!strcmp(node->name, "swr_master")) {
14082 temp = krealloc(swr_ctrl_data,
14083 (ctrl_num + 1) * sizeof(
14084 struct tasha_swr_ctrl_data),
14085 GFP_KERNEL);
14086 if (!temp) {
14087 dev_err(wcd9xxx->dev, "out of memory\n");
14088 ret = -ENOMEM;
14089 goto err;
14090 }
14091 swr_ctrl_data = temp;
14092 swr_ctrl_data[ctrl_num].swr_pdev = pdev;
14093 ctrl_num++;
14094 dev_dbg(&pdev->dev,
14095 "%s: Added soundwire ctrl device(s)\n",
14096 __func__);
14097 tasha->nr = ctrl_num;
14098 tasha->swr_ctrl_data = swr_ctrl_data;
14099 }
Meng Wang3b194492017-09-27 12:20:22 +080014100
14101 if (tasha->child_count < WCD9335_CHILD_DEVICES_MAX)
14102 tasha->pdev_child_devices[tasha->child_count++] = pdev;
14103 else
14104 goto err;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053014105 }
14106
14107 return;
14108fail_pdev_add:
14109 platform_device_put(pdev);
14110err:
14111 return;
14112}
14113
14114/*
14115 * tasha_codec_ver: to get tasha codec version
14116 * @codec: handle to snd_soc_codec *
14117 * return enum codec_variant - version
14118 */
14119enum codec_variant tasha_codec_ver(void)
14120{
14121 return codec_ver;
14122}
14123EXPORT_SYMBOL(tasha_codec_ver);
14124
14125static int __tasha_enable_efuse_sensing(struct tasha_priv *tasha)
14126{
14127 int val, rc;
14128
14129 __tasha_cdc_mclk_enable(tasha, true);
14130
14131 regmap_update_bits(tasha->wcd9xxx->regmap,
14132 WCD9335_CHIP_TIER_CTRL_EFUSE_CTL, 0x1E, 0x20);
14133 regmap_update_bits(tasha->wcd9xxx->regmap,
14134 WCD9335_CHIP_TIER_CTRL_EFUSE_CTL, 0x01, 0x01);
14135
14136 /*
14137 * 5ms sleep required after enabling efuse control
14138 * before checking the status.
14139 */
14140 usleep_range(5000, 5500);
14141 rc = regmap_read(tasha->wcd9xxx->regmap,
14142 WCD9335_CHIP_TIER_CTRL_EFUSE_STATUS, &val);
14143
14144 if (rc || (!(val & 0x01)))
14145 WARN(1, "%s: Efuse sense is not complete\n", __func__);
14146
14147 __tasha_cdc_mclk_enable(tasha, false);
14148
14149 return rc;
14150}
14151
14152void tasha_get_codec_ver(struct tasha_priv *tasha)
14153{
14154 int i;
14155 int val;
14156 struct tasha_reg_mask_val codec_reg[] = {
14157 {WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT10, 0xFF, 0xFF},
14158 {WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT11, 0xFF, 0x83},
14159 {WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT12, 0xFF, 0x0A},
14160 };
14161
14162 __tasha_enable_efuse_sensing(tasha);
14163 for (i = 0; i < ARRAY_SIZE(codec_reg); i++) {
14164 regmap_read(tasha->wcd9xxx->regmap, codec_reg[i].reg, &val);
14165 if (!(val && codec_reg[i].val)) {
14166 codec_ver = WCD9335;
14167 goto ret;
14168 }
14169 }
14170 codec_ver = WCD9326;
14171ret:
14172 pr_debug("%s: codec is %d\n", __func__, codec_ver);
14173}
14174EXPORT_SYMBOL(tasha_get_codec_ver);
14175
14176static int tasha_probe(struct platform_device *pdev)
14177{
14178 int ret = 0;
14179 struct tasha_priv *tasha;
14180 struct clk *wcd_ext_clk, *wcd_native_clk;
14181 struct wcd9xxx_resmgr_v2 *resmgr;
14182 struct wcd9xxx_power_region *cdc_pwr;
14183
14184 if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C) {
14185 if (apr_get_subsys_state() == APR_SUBSYS_DOWN) {
14186 dev_err(&pdev->dev, "%s: dsp down\n", __func__);
14187 return -EPROBE_DEFER;
14188 }
14189 }
14190
14191 tasha = devm_kzalloc(&pdev->dev, sizeof(struct tasha_priv),
14192 GFP_KERNEL);
14193 if (!tasha)
14194 return -ENOMEM;
14195 platform_set_drvdata(pdev, tasha);
14196
14197 tasha->wcd9xxx = dev_get_drvdata(pdev->dev.parent);
14198 tasha->dev = &pdev->dev;
14199 INIT_DELAYED_WORK(&tasha->power_gate_work, tasha_codec_power_gate_work);
14200 mutex_init(&tasha->power_lock);
14201 mutex_init(&tasha->sido_lock);
14202 INIT_WORK(&tasha->tasha_add_child_devices_work,
14203 tasha_add_child_devices);
14204 BLOCKING_INIT_NOTIFIER_HEAD(&tasha->notifier);
14205 mutex_init(&tasha->micb_lock);
14206 mutex_init(&tasha->swr_read_lock);
14207 mutex_init(&tasha->swr_write_lock);
14208 mutex_init(&tasha->swr_clk_lock);
Asish Bhattacharya84f7f732017-07-25 16:29:27 +053014209 mutex_init(&tasha->sb_clk_gear_lock);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053014210 mutex_init(&tasha->mclk_lock);
14211
14212 cdc_pwr = devm_kzalloc(&pdev->dev, sizeof(struct wcd9xxx_power_region),
14213 GFP_KERNEL);
14214 if (!cdc_pwr) {
14215 ret = -ENOMEM;
14216 goto err_cdc_pwr;
14217 }
14218 tasha->wcd9xxx->wcd9xxx_pwr[WCD9XXX_DIG_CORE_REGION_1] = cdc_pwr;
14219 cdc_pwr->pwr_collapse_reg_min = TASHA_DIG_CORE_REG_MIN;
14220 cdc_pwr->pwr_collapse_reg_max = TASHA_DIG_CORE_REG_MAX;
14221 wcd9xxx_set_power_state(tasha->wcd9xxx,
14222 WCD_REGION_POWER_COLLAPSE_REMOVE,
14223 WCD9XXX_DIG_CORE_REGION_1);
14224
14225 mutex_init(&tasha->codec_mutex);
14226 /*
14227 * Init resource manager so that if child nodes such as SoundWire
14228 * requests for clock, resource manager can honor the request
14229 */
14230 resmgr = wcd_resmgr_init(&tasha->wcd9xxx->core_res, NULL);
14231 if (IS_ERR(resmgr)) {
14232 ret = PTR_ERR(resmgr);
14233 dev_err(&pdev->dev, "%s: Failed to initialize wcd resmgr\n",
14234 __func__);
14235 goto err_resmgr;
14236 }
14237 tasha->resmgr = resmgr;
14238 tasha->swr_plat_data.handle = (void *) tasha;
14239 tasha->swr_plat_data.read = tasha_swrm_read;
14240 tasha->swr_plat_data.write = tasha_swrm_write;
14241 tasha->swr_plat_data.bulk_write = tasha_swrm_bulk_write;
14242 tasha->swr_plat_data.clk = tasha_swrm_clock;
14243 tasha->swr_plat_data.handle_irq = tasha_swrm_handle_irq;
14244
14245 /* Register for Clock */
14246 wcd_ext_clk = clk_get(tasha->wcd9xxx->dev, "wcd_clk");
14247 if (IS_ERR(wcd_ext_clk)) {
14248 dev_err(tasha->wcd9xxx->dev, "%s: clk get %s failed\n",
14249 __func__, "wcd_ext_clk");
14250 goto err_clk;
14251 }
14252 tasha->wcd_ext_clk = wcd_ext_clk;
14253 tasha->sido_voltage = SIDO_VOLTAGE_NOMINAL_MV;
14254 set_bit(AUDIO_NOMINAL, &tasha->status_mask);
14255 tasha->sido_ccl_cnt = 0;
14256
14257 /* Register native clk for 44.1 playback */
14258 wcd_native_clk = clk_get(tasha->wcd9xxx->dev, "wcd_native_clk");
14259 if (IS_ERR(wcd_native_clk))
14260 dev_dbg(tasha->wcd9xxx->dev, "%s: clk get %s failed\n",
14261 __func__, "wcd_native_clk");
14262 else
14263 tasha->wcd_native_clk = wcd_native_clk;
14264
14265 if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_SLIMBUS)
14266 ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_tasha,
14267 tasha_dai, ARRAY_SIZE(tasha_dai));
14268 else if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C)
14269 ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_tasha,
14270 tasha_i2s_dai,
14271 ARRAY_SIZE(tasha_i2s_dai));
14272 else
14273 ret = -EINVAL;
14274 if (ret) {
14275 dev_err(&pdev->dev, "%s: Codec registration failed, ret = %d\n",
14276 __func__, ret);
14277 goto err_cdc_reg;
14278 }
14279 /* Update codec register default values */
14280 tasha_update_reg_defaults(tasha);
14281 schedule_work(&tasha->tasha_add_child_devices_work);
14282 tasha_get_codec_ver(tasha);
14283
14284 dev_info(&pdev->dev, "%s: Tasha driver probe done\n", __func__);
14285 return ret;
14286
14287err_cdc_reg:
14288 clk_put(tasha->wcd_ext_clk);
14289 if (tasha->wcd_native_clk)
14290 clk_put(tasha->wcd_native_clk);
14291err_clk:
14292 wcd_resmgr_remove(tasha->resmgr);
14293err_resmgr:
14294 devm_kfree(&pdev->dev, cdc_pwr);
14295err_cdc_pwr:
14296 mutex_destroy(&tasha->mclk_lock);
14297 devm_kfree(&pdev->dev, tasha);
14298 return ret;
14299}
14300
14301static int tasha_remove(struct platform_device *pdev)
14302{
14303 struct tasha_priv *tasha;
Meng Wang3b194492017-09-27 12:20:22 +080014304 int count = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053014305
14306 tasha = platform_get_drvdata(pdev);
14307
Meng Wang3b194492017-09-27 12:20:22 +080014308 if (!tasha)
14309 return -EINVAL;
14310
14311 for (count = 0; count < tasha->child_count &&
14312 count < WCD9335_CHILD_DEVICES_MAX; count++)
14313 platform_device_unregister(tasha->pdev_child_devices[count]);
14314
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053014315 mutex_destroy(&tasha->codec_mutex);
14316 clk_put(tasha->wcd_ext_clk);
14317 if (tasha->wcd_native_clk)
14318 clk_put(tasha->wcd_native_clk);
14319 mutex_destroy(&tasha->mclk_lock);
Asish Bhattacharya84f7f732017-07-25 16:29:27 +053014320 mutex_destroy(&tasha->sb_clk_gear_lock);
Meng Wang3b194492017-09-27 12:20:22 +080014321 snd_soc_unregister_codec(&pdev->dev);
14322 devm_kfree(&pdev->dev, tasha);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053014323 return 0;
14324}
14325
14326static struct platform_driver tasha_codec_driver = {
14327 .probe = tasha_probe,
14328 .remove = tasha_remove,
14329 .driver = {
14330 .name = "tasha_codec",
14331 .owner = THIS_MODULE,
14332#ifdef CONFIG_PM
14333 .pm = &tasha_pm_ops,
14334#endif
14335 },
14336};
14337
14338module_platform_driver(tasha_codec_driver);
14339
14340MODULE_DESCRIPTION("Tasha Codec driver");
14341MODULE_LICENSE("GPL v2");