blob: ee33ee8227deed55cadca59bbc4c8edbf3e7cf81 [file] [log] [blame]
Banajit Goswamide8271c2017-01-18 00:28:59 -08001/*
2 * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
3 *
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>
25#include <linux/mfd/wcd9xxx/core.h>
26#include <linux/mfd/wcd9xxx/wcd9xxx-irq.h>
27#include <linux/mfd/wcd9xxx/wcd9xxx_registers.h>
28#include <linux/mfd/wcd9335/registers.h>
29#include <linux/mfd/wcd9xxx/pdata.h>
30#include <linux/regulator/consumer.h>
31#include <linux/clk.h>
32#include <linux/delay.h>
33#include <linux/pm_runtime.h>
34#include <linux/kernel.h>
35#include <linux/gpio.h>
36#include <linux/soundwire/swr-wcd.h>
37#include <sound/pcm.h>
38#include <sound/pcm_params.h>
39#include <sound/soc.h>
40#include <sound/soc-dapm.h>
41#include <sound/tlv.h>
42#include <sound/info.h>
43#include "wcd9335.h"
44#include "wcd-mbhc-v2.h"
45#include "wcd9xxx-common-v2.h"
46#include "wcd9xxx-resmgr-v2.h"
47#include "wcd_cpe_core.h"
48#include "wcdcal-hwdep.h"
49
50#define TASHA_RX_PORT_START_NUMBER 16
51
52#define WCD9335_RATES_MASK (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
53 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
54 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
55/* Fractional Rates */
56#define WCD9335_FRAC_RATES_MASK (SNDRV_PCM_RATE_44100)
57
58#define WCD9335_MIX_RATES_MASK (SNDRV_PCM_RATE_48000 |\
59 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
60
61#define TASHA_FORMATS_S16_S24_LE (SNDRV_PCM_FMTBIT_S16_LE | \
62 SNDRV_PCM_FMTBIT_S24_LE | \
63 SNDRV_PCM_FMTBIT_S24_3LE)
64
65#define TASHA_FORMATS_S16_S24_S32_LE (SNDRV_PCM_FMTBIT_S16_LE | \
66 SNDRV_PCM_FMTBIT_S24_LE | \
67 SNDRV_PCM_FMTBIT_S24_3LE | \
68 SNDRV_PCM_FMTBIT_S32_LE)
69
70#define TASHA_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
71
72/*
73 * Timeout in milli seconds and it is the wait time for
74 * slim channel removal interrupt to receive.
75 */
76#define TASHA_SLIM_CLOSE_TIMEOUT 1000
77#define TASHA_SLIM_IRQ_OVERFLOW (1 << 0)
78#define TASHA_SLIM_IRQ_UNDERFLOW (1 << 1)
79#define TASHA_SLIM_IRQ_PORT_CLOSED (1 << 2)
80#define TASHA_MCLK_CLK_12P288MHZ 12288000
81#define TASHA_MCLK_CLK_9P6MHZ 9600000
82
83#define TASHA_SLIM_PGD_PORT_INT_TX_EN0 (TASHA_SLIM_PGD_PORT_INT_EN0 + 2)
84
85#define TASHA_NUM_INTERPOLATORS 9
86#define TASHA_NUM_DECIMATORS 9
87
88#define BYTE_BIT_MASK(nr) (1 << ((nr) % BITS_PER_BYTE))
89#define TASHA_MAD_AUDIO_FIRMWARE_PATH "wcd9335/wcd9335_mad_audio.bin"
90#define TASHA_CPE_SS_ERR_STATUS_MEM_ACCESS (1 << 0)
91#define TASHA_CPE_SS_ERR_STATUS_WDOG_BITE (1 << 1)
92
93#define TASHA_CPE_FATAL_IRQS \
94 (TASHA_CPE_SS_ERR_STATUS_WDOG_BITE | \
95 TASHA_CPE_SS_ERR_STATUS_MEM_ACCESS)
96
97#define SLIM_BW_CLK_GEAR_9 6200000
98#define SLIM_BW_UNVOTE 0
99
100#define CPE_FLL_CLK_75MHZ 75000000
101#define CPE_FLL_CLK_150MHZ 150000000
102#define WCD9335_REG_BITS 8
103
104#define WCD9335_MAX_VALID_ADC_MUX 13
105#define WCD9335_INVALID_ADC_MUX 9
106
107#define TASHA_DIG_CORE_REG_MIN WCD9335_CDC_ANC0_CLK_RESET_CTL
108#define TASHA_DIG_CORE_REG_MAX 0xDFF
109
110/* Convert from vout ctl to micbias voltage in mV */
111#define WCD_VOUT_CTL_TO_MICB(v) (1000 + v * 50)
112
113#define TASHA_ZDET_NUM_MEASUREMENTS 150
114#define TASHA_MBHC_GET_C1(c) ((c & 0xC000) >> 14)
115#define TASHA_MBHC_GET_X1(x) (x & 0x3FFF)
116/* z value compared in milliOhm */
117#define TASHA_MBHC_IS_SECOND_RAMP_REQUIRED(z) ((z > 400000) || (z < 32000))
118#define TASHA_MBHC_ZDET_CONST (86 * 16384)
119#define TASHA_MBHC_MOISTURE_VREF V_45_MV
120#define TASHA_MBHC_MOISTURE_IREF I_3P0_UA
121
122#define TASHA_VERSION_ENTRY_SIZE 17
123
124#define WCD9335_AMIC_PWR_LEVEL_LP 0
125#define WCD9335_AMIC_PWR_LEVEL_DEFAULT 1
126#define WCD9335_AMIC_PWR_LEVEL_HP 2
127#define WCD9335_AMIC_PWR_LVL_MASK 0x60
128#define WCD9335_AMIC_PWR_LVL_SHIFT 0x5
129
130#define WCD9335_DEC_PWR_LVL_MASK 0x06
131#define WCD9335_DEC_PWR_LVL_LP 0x02
132#define WCD9335_DEC_PWR_LVL_HP 0x04
133#define WCD9335_DEC_PWR_LVL_DF 0x00
134#define WCD9335_STRING_LEN 100
135
136#define CALCULATE_VOUT_D(req_mv) (((req_mv - 650) * 10) / 25)
137
138static int cpe_debug_mode;
139
140#define TASHA_MAX_MICBIAS 4
141#define DAPM_MICBIAS1_STANDALONE "MIC BIAS1 Standalone"
142#define DAPM_MICBIAS2_STANDALONE "MIC BIAS2 Standalone"
143#define DAPM_MICBIAS3_STANDALONE "MIC BIAS3 Standalone"
144#define DAPM_MICBIAS4_STANDALONE "MIC BIAS4 Standalone"
145
146#define DAPM_LDO_H_STANDALONE "LDO_H"
147module_param(cpe_debug_mode, int, 0664);
148MODULE_PARM_DESC(cpe_debug_mode, "boot cpe in debug mode");
149
150#define TASHA_DIG_CORE_COLLAPSE_TIMER_MS (5 * 1000)
151
152#define MAX_ON_DEMAND_SUPPLY_NAME_LENGTH 64
153
154static char on_demand_supply_name[][MAX_ON_DEMAND_SUPPLY_NAME_LENGTH] = {
155 "cdc-vdd-mic-bias",
156};
157
158enum {
159 POWER_COLLAPSE,
160 POWER_RESUME,
161};
162
163enum tasha_sido_voltage {
164 SIDO_VOLTAGE_SVS_MV = 950,
165 SIDO_VOLTAGE_NOMINAL_MV = 1100,
166};
167
168static enum codec_variant codec_ver;
169
170static int dig_core_collapse_enable = 1;
171module_param(dig_core_collapse_enable, int, 0664);
172MODULE_PARM_DESC(dig_core_collapse_enable, "enable/disable power gating");
173
174/* dig_core_collapse timer in seconds */
175static int dig_core_collapse_timer = (TASHA_DIG_CORE_COLLAPSE_TIMER_MS/1000);
176module_param(dig_core_collapse_timer, int, 0664);
177MODULE_PARM_DESC(dig_core_collapse_timer, "timer for power gating");
178
179/* SVS Scaling enable/disable */
180static int svs_scaling_enabled = 1;
181module_param(svs_scaling_enabled, int, 0664);
182MODULE_PARM_DESC(svs_scaling_enabled, "enable/disable svs scaling");
183
184/* SVS buck setting */
185static int sido_buck_svs_voltage = SIDO_VOLTAGE_SVS_MV;
186module_param(sido_buck_svs_voltage, int, 0664);
187MODULE_PARM_DESC(sido_buck_svs_voltage,
188 "setting for SVS voltage for SIDO BUCK");
189
190#define TASHA_TX_UNMUTE_DELAY_MS 25
191
192static int tx_unmute_delay = TASHA_TX_UNMUTE_DELAY_MS;
193module_param(tx_unmute_delay, int, 0664);
194MODULE_PARM_DESC(tx_unmute_delay, "delay to unmute the tx path");
195
196static struct afe_param_slimbus_slave_port_cfg tasha_slimbus_slave_port_cfg = {
197 .minor_version = 1,
198 .slimbus_dev_id = AFE_SLIMBUS_DEVICE_1,
199 .slave_dev_pgd_la = 0,
200 .slave_dev_intfdev_la = 0,
201 .bit_width = 16,
202 .data_format = 0,
203 .num_channels = 1
204};
205
206struct tasha_mbhc_zdet_param {
207 u16 ldo_ctl;
208 u16 noff;
209 u16 nshift;
210 u16 btn5;
211 u16 btn6;
212 u16 btn7;
213};
214
215static struct afe_param_cdc_reg_page_cfg tasha_cdc_reg_page_cfg = {
216 .minor_version = AFE_API_VERSION_CDC_REG_PAGE_CFG,
217 .enable = 1,
218 .proc_id = AFE_CDC_REG_PAGE_ASSIGN_PROC_ID_1,
219};
220
221static struct afe_param_cdc_reg_cfg audio_reg_cfg[] = {
222 {
223 1,
224 (TASHA_REGISTER_START_OFFSET + WCD9335_SOC_MAD_MAIN_CTL_1),
225 HW_MAD_AUDIO_ENABLE, 0x1, WCD9335_REG_BITS, 0
226 },
227 {
228 1,
229 (TASHA_REGISTER_START_OFFSET + WCD9335_SOC_MAD_AUDIO_CTL_3),
230 HW_MAD_AUDIO_SLEEP_TIME, 0xF, WCD9335_REG_BITS, 0
231 },
232 {
233 1,
234 (TASHA_REGISTER_START_OFFSET + WCD9335_SOC_MAD_AUDIO_CTL_4),
235 HW_MAD_TX_AUDIO_SWITCH_OFF, 0x1, WCD9335_REG_BITS, 0
236 },
237 {
238 1,
239 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_CFG),
240 MAD_AUDIO_INT_DEST_SELECT_REG, 0x2, WCD9335_REG_BITS, 0
241 },
242 {
243 1,
244 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_PIN2_MASK3),
245 MAD_AUDIO_INT_MASK_REG, 0x1, WCD9335_REG_BITS, 0
246 },
247 {
248 1,
249 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_PIN2_STATUS3),
250 MAD_AUDIO_INT_STATUS_REG, 0x1, WCD9335_REG_BITS, 0
251 },
252 {
253 1,
254 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_PIN2_CLEAR3),
255 MAD_AUDIO_INT_CLEAR_REG, 0x1, WCD9335_REG_BITS, 0
256 },
257 {
258 1,
259 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_CFG),
260 VBAT_INT_DEST_SELECT_REG, 0x2, WCD9335_REG_BITS, 0
261 },
262 {
263 1,
264 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_PIN2_MASK3),
265 VBAT_INT_MASK_REG, 0x08, WCD9335_REG_BITS, 0
266 },
267 {
268 1,
269 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_PIN2_STATUS3),
270 VBAT_INT_STATUS_REG, 0x08, WCD9335_REG_BITS, 0
271 },
272 {
273 1,
274 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_PIN2_CLEAR3),
275 VBAT_INT_CLEAR_REG, 0x08, WCD9335_REG_BITS, 0
276 },
277 {
278 1,
279 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_CFG),
280 VBAT_RELEASE_INT_DEST_SELECT_REG, 0x2, WCD9335_REG_BITS, 0
281 },
282 {
283 1,
284 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_PIN2_MASK3),
285 VBAT_RELEASE_INT_MASK_REG, 0x10, WCD9335_REG_BITS, 0
286 },
287 {
288 1,
289 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_PIN2_STATUS3),
290 VBAT_RELEASE_INT_STATUS_REG, 0x10, WCD9335_REG_BITS, 0
291 },
292 {
293 1,
294 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_PIN2_CLEAR3),
295 VBAT_RELEASE_INT_CLEAR_REG, 0x10, WCD9335_REG_BITS, 0
296 },
297 {
298 1,
299 (TASHA_REGISTER_START_OFFSET + TASHA_SB_PGD_PORT_TX_BASE),
300 SB_PGD_PORT_TX_WATERMARK_N, 0x1E, WCD9335_REG_BITS, 0x1
301 },
302 {
303 1,
304 (TASHA_REGISTER_START_OFFSET + TASHA_SB_PGD_PORT_TX_BASE),
305 SB_PGD_PORT_TX_ENABLE_N, 0x1, WCD9335_REG_BITS, 0x1
306 },
307 {
308 1,
309 (TASHA_REGISTER_START_OFFSET + TASHA_SB_PGD_PORT_RX_BASE),
310 SB_PGD_PORT_RX_WATERMARK_N, 0x1E, WCD9335_REG_BITS, 0x1
311 },
312 {
313 1,
314 (TASHA_REGISTER_START_OFFSET + TASHA_SB_PGD_PORT_RX_BASE),
315 SB_PGD_PORT_RX_ENABLE_N, 0x1, WCD9335_REG_BITS, 0x1
316 },
317 { 1,
318 (TASHA_REGISTER_START_OFFSET + WCD9335_CDC_ANC0_IIR_ADAPT_CTL),
319 AANC_FF_GAIN_ADAPTIVE, 0x4, WCD9335_REG_BITS, 0
320 },
321 { 1,
322 (TASHA_REGISTER_START_OFFSET + WCD9335_CDC_ANC0_IIR_ADAPT_CTL),
323 AANC_FFGAIN_ADAPTIVE_EN, 0x8, WCD9335_REG_BITS, 0
324 },
325 {
326 1,
327 (TASHA_REGISTER_START_OFFSET + WCD9335_CDC_ANC0_FF_A_GAIN_CTL),
328 AANC_GAIN_CONTROL, 0xFF, WCD9335_REG_BITS, 0
329 },
330};
331
332static struct afe_param_cdc_reg_cfg_data tasha_audio_reg_cfg = {
333 .num_registers = ARRAY_SIZE(audio_reg_cfg),
334 .reg_data = audio_reg_cfg,
335};
336
337static struct afe_param_id_cdc_aanc_version tasha_cdc_aanc_version = {
338 .cdc_aanc_minor_version = AFE_API_VERSION_CDC_AANC_VERSION,
339 .aanc_hw_version = AANC_HW_BLOCK_VERSION_2,
340};
341
342enum {
343 VI_SENSE_1,
344 VI_SENSE_2,
345 AIF4_SWITCH_VALUE,
346 AUDIO_NOMINAL,
347 CPE_NOMINAL,
348 HPH_PA_DELAY,
349 SB_CLK_GEAR,
350 ANC_MIC_AMIC1,
351 ANC_MIC_AMIC2,
352 ANC_MIC_AMIC3,
353 ANC_MIC_AMIC4,
354 ANC_MIC_AMIC5,
355 ANC_MIC_AMIC6,
356 CLASSH_CONFIG,
357};
358
359enum {
360 AIF1_PB = 0,
361 AIF1_CAP,
362 AIF2_PB,
363 AIF2_CAP,
364 AIF3_PB,
365 AIF3_CAP,
366 AIF4_PB,
367 AIF_MIX1_PB,
368 AIF4_MAD_TX,
369 AIF4_VIFEED,
370 AIF5_CPE_TX,
371 NUM_CODEC_DAIS,
372};
373
374enum {
375 INTn_1_MIX_INP_SEL_ZERO = 0,
376 INTn_1_MIX_INP_SEL_DEC0,
377 INTn_1_MIX_INP_SEL_DEC1,
378 INTn_1_MIX_INP_SEL_IIR0,
379 INTn_1_MIX_INP_SEL_IIR1,
380 INTn_1_MIX_INP_SEL_RX0,
381 INTn_1_MIX_INP_SEL_RX1,
382 INTn_1_MIX_INP_SEL_RX2,
383 INTn_1_MIX_INP_SEL_RX3,
384 INTn_1_MIX_INP_SEL_RX4,
385 INTn_1_MIX_INP_SEL_RX5,
386 INTn_1_MIX_INP_SEL_RX6,
387 INTn_1_MIX_INP_SEL_RX7,
388
389};
390
391#define IS_VALID_NATIVE_FIFO_PORT(inp) \
392 ((inp >= INTn_1_MIX_INP_SEL_RX0) && \
393 (inp <= INTn_1_MIX_INP_SEL_RX3))
394
395enum {
396 INTn_2_INP_SEL_ZERO = 0,
397 INTn_2_INP_SEL_RX0,
398 INTn_2_INP_SEL_RX1,
399 INTn_2_INP_SEL_RX2,
400 INTn_2_INP_SEL_RX3,
401 INTn_2_INP_SEL_RX4,
402 INTn_2_INP_SEL_RX5,
403 INTn_2_INP_SEL_RX6,
404 INTn_2_INP_SEL_RX7,
405 INTn_2_INP_SEL_PROXIMITY,
406};
407
408enum {
409 INTERP_EAR = 0,
410 INTERP_HPHL,
411 INTERP_HPHR,
412 INTERP_LO1,
413 INTERP_LO2,
414 INTERP_LO3,
415 INTERP_LO4,
416 INTERP_SPKR1,
417 INTERP_SPKR2,
418};
419
420struct interp_sample_rate {
421 int sample_rate;
422 int rate_val;
423};
424
425static struct interp_sample_rate int_prim_sample_rate_val[] = {
426 {8000, 0x0}, /* 8K */
427 {16000, 0x1}, /* 16K */
428 {24000, -EINVAL},/* 24K */
429 {32000, 0x3}, /* 32K */
430 {48000, 0x4}, /* 48K */
431 {96000, 0x5}, /* 96K */
432 {192000, 0x6}, /* 192K */
433 {384000, 0x7}, /* 384K */
434 {44100, 0x8}, /* 44.1K */
435};
436
437static struct interp_sample_rate int_mix_sample_rate_val[] = {
438 {48000, 0x4}, /* 48K */
439 {96000, 0x5}, /* 96K */
440 {192000, 0x6}, /* 192K */
441};
442
443static const struct wcd9xxx_ch tasha_rx_chs[TASHA_RX_MAX] = {
444 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER, 0),
445 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 1, 1),
446 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 2, 2),
447 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 3, 3),
448 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 4, 4),
449 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 5, 5),
450 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 6, 6),
451 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 7, 7),
452 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 8, 8),
453 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 9, 9),
454 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 10, 10),
455 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 11, 11),
456 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 12, 12),
457};
458
459static const struct wcd9xxx_ch tasha_tx_chs[TASHA_TX_MAX] = {
460 WCD9XXX_CH(0, 0),
461 WCD9XXX_CH(1, 1),
462 WCD9XXX_CH(2, 2),
463 WCD9XXX_CH(3, 3),
464 WCD9XXX_CH(4, 4),
465 WCD9XXX_CH(5, 5),
466 WCD9XXX_CH(6, 6),
467 WCD9XXX_CH(7, 7),
468 WCD9XXX_CH(8, 8),
469 WCD9XXX_CH(9, 9),
470 WCD9XXX_CH(10, 10),
471 WCD9XXX_CH(11, 11),
472 WCD9XXX_CH(12, 12),
473 WCD9XXX_CH(13, 13),
474 WCD9XXX_CH(14, 14),
475 WCD9XXX_CH(15, 15),
476};
477
478static const u32 vport_slim_check_table[NUM_CODEC_DAIS] = {
479 /* Needs to define in the same order of DAI enum definitions */
480 0,
481 BIT(AIF2_CAP) | BIT(AIF3_CAP) | BIT(AIF4_MAD_TX) | BIT(AIF5_CPE_TX),
482 0,
483 BIT(AIF1_CAP) | BIT(AIF3_CAP) | BIT(AIF4_MAD_TX) | BIT(AIF5_CPE_TX),
484 0,
485 BIT(AIF1_CAP) | BIT(AIF2_CAP) | BIT(AIF4_MAD_TX) | BIT(AIF5_CPE_TX),
486 0,
487 0,
488 BIT(AIF1_CAP) | BIT(AIF2_CAP) | BIT(AIF3_CAP) | BIT(AIF5_CPE_TX),
489 0,
490 BIT(AIF1_CAP) | BIT(AIF2_CAP) | BIT(AIF3_CAP) | BIT(AIF4_MAD_TX),
491};
492
493static const u32 vport_i2s_check_table[NUM_CODEC_DAIS] = {
494 0, /* AIF1_PB */
495 BIT(AIF2_CAP), /* AIF1_CAP */
496 0, /* AIF2_PB */
497 BIT(AIF1_CAP), /* AIF2_CAP */
498};
499
500/* Codec supports 2 IIR filters */
501enum {
502 IIR0 = 0,
503 IIR1,
504 IIR_MAX,
505};
506
507/* Each IIR has 5 Filter Stages */
508enum {
509 BAND1 = 0,
510 BAND2,
511 BAND3,
512 BAND4,
513 BAND5,
514 BAND_MAX,
515};
516
517enum {
518 COMPANDER_1, /* HPH_L */
519 COMPANDER_2, /* HPH_R */
520 COMPANDER_3, /* LO1_DIFF */
521 COMPANDER_4, /* LO2_DIFF */
522 COMPANDER_5, /* LO3_SE */
523 COMPANDER_6, /* LO4_SE */
524 COMPANDER_7, /* SWR SPK CH1 */
525 COMPANDER_8, /* SWR SPK CH2 */
526 COMPANDER_MAX,
527};
528
529enum {
530 SRC_IN_HPHL,
531 SRC_IN_LO1,
532 SRC_IN_HPHR,
533 SRC_IN_LO2,
534 SRC_IN_SPKRL,
535 SRC_IN_LO3,
536 SRC_IN_SPKRR,
537 SRC_IN_LO4,
538};
539
540enum {
541 SPLINE_SRC0,
542 SPLINE_SRC1,
543 SPLINE_SRC2,
544 SPLINE_SRC3,
545 SPLINE_SRC_MAX,
546};
547
548/* wcd9335 interrupt table */
549static const struct intr_data wcd9335_intr_table[] = {
550 {WCD9XXX_IRQ_SLIMBUS, false},
551 {WCD9335_IRQ_MBHC_SW_DET, true},
552 {WCD9335_IRQ_MBHC_BUTTON_PRESS_DET, true},
553 {WCD9335_IRQ_MBHC_BUTTON_RELEASE_DET, true},
554 {WCD9335_IRQ_MBHC_ELECT_INS_REM_DET, true},
555 {WCD9335_IRQ_MBHC_ELECT_INS_REM_LEG_DET, true},
556 {WCD9335_IRQ_FLL_LOCK_LOSS, false},
557 {WCD9335_IRQ_HPH_PA_CNPL_COMPLETE, false},
558 {WCD9335_IRQ_HPH_PA_CNPR_COMPLETE, false},
559 {WCD9335_IRQ_EAR_PA_CNP_COMPLETE, false},
560 {WCD9335_IRQ_LINE_PA1_CNP_COMPLETE, false},
561 {WCD9335_IRQ_LINE_PA2_CNP_COMPLETE, false},
562 {WCD9335_IRQ_LINE_PA3_CNP_COMPLETE, false},
563 {WCD9335_IRQ_LINE_PA4_CNP_COMPLETE, false},
564 {WCD9335_IRQ_HPH_PA_OCPL_FAULT, false},
565 {WCD9335_IRQ_HPH_PA_OCPR_FAULT, false},
566 {WCD9335_IRQ_EAR_PA_OCP_FAULT, false},
567 {WCD9335_IRQ_SOUNDWIRE, false},
568 {WCD9335_IRQ_VDD_DIG_RAMP_COMPLETE, false},
569 {WCD9335_IRQ_RCO_ERROR, false},
570 {WCD9335_IRQ_SVA_ERROR, false},
571 {WCD9335_IRQ_MAD_AUDIO, false},
572 {WCD9335_IRQ_MAD_BEACON, false},
573 {WCD9335_IRQ_SVA_OUTBOX1, true},
574 {WCD9335_IRQ_SVA_OUTBOX2, true},
575 {WCD9335_IRQ_MAD_ULTRASOUND, false},
576 {WCD9335_IRQ_VBAT_ATTACK, false},
577 {WCD9335_IRQ_VBAT_RESTORE, false},
578};
579
580static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0);
581static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1);
582static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1);
583
584static struct snd_soc_dai_driver tasha_dai[];
585static int wcd9335_get_micb_vout_ctl_val(u32 micb_mv);
586
587static int tasha_config_compander(struct snd_soc_codec *, int, int);
588static void tasha_codec_set_tx_hold(struct snd_soc_codec *, u16, bool);
589static int tasha_codec_internal_rco_ctrl(struct snd_soc_codec *codec,
590 bool enable);
591
592/* Hold instance to soundwire platform device */
593struct tasha_swr_ctrl_data {
594 struct platform_device *swr_pdev;
595 struct ida swr_ida;
596};
597
598struct wcd_swr_ctrl_platform_data {
599 void *handle; /* holds codec private data */
600 int (*read)(void *handle, int reg);
601 int (*write)(void *handle, int reg, int val);
602 int (*bulk_write)(void *handle, u32 *reg, u32 *val, size_t len);
603 int (*clk)(void *handle, bool enable);
604 int (*handle_irq)(void *handle,
605 irqreturn_t (*swrm_irq_handler)(int irq,
606 void *data),
607 void *swrm_handle,
608 int action);
609};
610
611static struct wcd_mbhc_register
612 wcd_mbhc_registers[WCD_MBHC_REG_FUNC_MAX] = {
613 WCD_MBHC_REGISTER("WCD_MBHC_L_DET_EN",
614 WCD9335_ANA_MBHC_MECH, 0x80, 7, 0),
615 WCD_MBHC_REGISTER("WCD_MBHC_GND_DET_EN",
616 WCD9335_ANA_MBHC_MECH, 0x40, 6, 0),
617 WCD_MBHC_REGISTER("WCD_MBHC_MECH_DETECTION_TYPE",
618 WCD9335_ANA_MBHC_MECH, 0x20, 5, 0),
619 WCD_MBHC_REGISTER("WCD_MBHC_MIC_CLAMP_CTL",
620 WCD9335_MBHC_PLUG_DETECT_CTL, 0x30, 4, 0),
621 WCD_MBHC_REGISTER("WCD_MBHC_ELECT_DETECTION_TYPE",
622 WCD9335_ANA_MBHC_ELECT, 0x08, 3, 0),
623 WCD_MBHC_REGISTER("WCD_MBHC_HS_L_DET_PULL_UP_CTRL",
624 WCD9335_MBHC_PLUG_DETECT_CTL, 0xC0, 6, 0),
625 WCD_MBHC_REGISTER("WCD_MBHC_HS_L_DET_PULL_UP_COMP_CTRL",
626 WCD9335_ANA_MBHC_MECH, 0x04, 2, 0),
627 WCD_MBHC_REGISTER("WCD_MBHC_HPHL_PLUG_TYPE",
628 WCD9335_ANA_MBHC_MECH, 0x10, 4, 0),
629 WCD_MBHC_REGISTER("WCD_MBHC_GND_PLUG_TYPE",
630 WCD9335_ANA_MBHC_MECH, 0x08, 3, 0),
631 WCD_MBHC_REGISTER("WCD_MBHC_SW_HPH_LP_100K_TO_GND",
632 WCD9335_ANA_MBHC_MECH, 0x01, 0, 0),
633 WCD_MBHC_REGISTER("WCD_MBHC_ELECT_SCHMT_ISRC",
634 WCD9335_ANA_MBHC_ELECT, 0x06, 1, 0),
635 WCD_MBHC_REGISTER("WCD_MBHC_FSM_EN",
636 WCD9335_ANA_MBHC_ELECT, 0x80, 7, 0),
637 WCD_MBHC_REGISTER("WCD_MBHC_INSREM_DBNC",
638 WCD9335_MBHC_PLUG_DETECT_CTL, 0x0F, 0, 0),
639 WCD_MBHC_REGISTER("WCD_MBHC_BTN_DBNC",
640 WCD9335_MBHC_CTL_1, 0x03, 0, 0),
641 WCD_MBHC_REGISTER("WCD_MBHC_HS_VREF",
642 WCD9335_MBHC_CTL_2, 0x03, 0, 0),
643 WCD_MBHC_REGISTER("WCD_MBHC_HS_COMP_RESULT",
644 WCD9335_ANA_MBHC_RESULT_3, 0x08, 3, 0),
645 WCD_MBHC_REGISTER("WCD_MBHC_MIC_SCHMT_RESULT",
646 WCD9335_ANA_MBHC_RESULT_3, 0x20, 5, 0),
647 WCD_MBHC_REGISTER("WCD_MBHC_HPHL_SCHMT_RESULT",
648 WCD9335_ANA_MBHC_RESULT_3, 0x80, 7, 0),
649 WCD_MBHC_REGISTER("WCD_MBHC_HPHR_SCHMT_RESULT",
650 WCD9335_ANA_MBHC_RESULT_3, 0x40, 6, 0),
651 WCD_MBHC_REGISTER("WCD_MBHC_OCP_FSM_EN",
652 WCD9335_HPH_OCP_CTL, 0x10, 4, 0),
653 WCD_MBHC_REGISTER("WCD_MBHC_BTN_RESULT",
654 WCD9335_ANA_MBHC_RESULT_3, 0x07, 0, 0),
655 WCD_MBHC_REGISTER("WCD_MBHC_BTN_ISRC_CTL",
656 WCD9335_ANA_MBHC_ELECT, 0x70, 4, 0),
657 WCD_MBHC_REGISTER("WCD_MBHC_ELECT_RESULT",
658 WCD9335_ANA_MBHC_RESULT_3, 0xFF, 0, 0),
659 WCD_MBHC_REGISTER("WCD_MBHC_MICB_CTRL",
660 WCD9335_ANA_MICB2, 0xC0, 6, 0),
661 WCD_MBHC_REGISTER("WCD_MBHC_HPH_CNP_WG_TIME",
662 WCD9335_HPH_CNP_WG_TIME, 0xFF, 0, 0),
663 WCD_MBHC_REGISTER("WCD_MBHC_HPHR_PA_EN",
664 WCD9335_ANA_HPH, 0x40, 6, 0),
665 WCD_MBHC_REGISTER("WCD_MBHC_HPHL_PA_EN",
666 WCD9335_ANA_HPH, 0x80, 7, 0),
667 WCD_MBHC_REGISTER("WCD_MBHC_HPH_PA_EN",
668 WCD9335_ANA_HPH, 0xC0, 6, 0),
669 WCD_MBHC_REGISTER("WCD_MBHC_SWCH_LEVEL_REMOVE",
670 WCD9335_ANA_MBHC_RESULT_3, 0x10, 4, 0),
671 WCD_MBHC_REGISTER("WCD_MBHC_PULLDOWN_CTRL",
672 0, 0, 0, 0),
673 WCD_MBHC_REGISTER("WCD_MBHC_ANC_DET_EN",
674 WCD9335_ANA_MBHC_ZDET, 0x01, 0, 0),
675 /*
676 * MBHC FSM status register is only available in Tasha 2.0.
677 * So, init with 0 later once the version is known, then values
678 * will be updated.
679 */
680 WCD_MBHC_REGISTER("WCD_MBHC_FSM_STATUS",
681 0, 0, 0, 0),
682 WCD_MBHC_REGISTER("WCD_MBHC_MUX_CTL",
683 WCD9335_MBHC_CTL_2, 0x70, 4, 0),
684};
685
686static const struct wcd_mbhc_intr intr_ids = {
687 .mbhc_sw_intr = WCD9335_IRQ_MBHC_SW_DET,
688 .mbhc_btn_press_intr = WCD9335_IRQ_MBHC_BUTTON_PRESS_DET,
689 .mbhc_btn_release_intr = WCD9335_IRQ_MBHC_BUTTON_RELEASE_DET,
690 .mbhc_hs_ins_intr = WCD9335_IRQ_MBHC_ELECT_INS_REM_LEG_DET,
691 .mbhc_hs_rem_intr = WCD9335_IRQ_MBHC_ELECT_INS_REM_DET,
692 .hph_left_ocp = WCD9335_IRQ_HPH_PA_OCPL_FAULT,
693 .hph_right_ocp = WCD9335_IRQ_HPH_PA_OCPR_FAULT,
694};
695
696struct wcd_vbat {
697 bool is_enabled;
698 bool adc_config;
699 /* Variables to cache Vbat ADC output values */
700 u16 dcp1;
701 u16 dcp2;
702};
703
704struct hpf_work {
705 struct tasha_priv *tasha;
706 u8 decimator;
707 u8 hpf_cut_off_freq;
708 struct delayed_work dwork;
709};
710
711#define WCD9335_SPK_ANC_EN_DELAY_MS 350
712static int spk_anc_en_delay = WCD9335_SPK_ANC_EN_DELAY_MS;
713module_param(spk_anc_en_delay, int, 0664);
714MODULE_PARM_DESC(spk_anc_en_delay, "delay to enable anc in speaker path");
715
716struct spk_anc_work {
717 struct tasha_priv *tasha;
718 struct delayed_work dwork;
719};
720
721struct tx_mute_work {
722 struct tasha_priv *tasha;
723 u8 decimator;
724 struct delayed_work dwork;
725};
726
727struct tasha_priv {
728 struct device *dev;
729 struct wcd9xxx *wcd9xxx;
730
731 struct snd_soc_codec *codec;
732 u32 adc_count;
733 u32 rx_bias_count;
734 s32 dmic_0_1_clk_cnt;
735 s32 dmic_2_3_clk_cnt;
736 s32 dmic_4_5_clk_cnt;
737 s32 ldo_h_users;
738 s32 micb_ref[TASHA_MAX_MICBIAS];
739 s32 pullup_ref[TASHA_MAX_MICBIAS];
740
741 u32 anc_slot;
742 bool anc_func;
743
744 /* Vbat module */
745 struct wcd_vbat vbat;
746
747 /* cal info for codec */
748 struct fw_info *fw_data;
749
750 /*track tasha interface type*/
751 u8 intf_type;
752
753 /* num of slim ports required */
754 struct wcd9xxx_codec_dai_data dai[NUM_CODEC_DAIS];
755
756 /* SoundWire data structure */
757 struct tasha_swr_ctrl_data *swr_ctrl_data;
758 int nr;
759
760 /*compander*/
761 int comp_enabled[COMPANDER_MAX];
762
763 /* Maintain the status of AUX PGA */
764 int aux_pga_cnt;
765 u8 aux_l_gain;
766 u8 aux_r_gain;
767
768 bool spkr_pa_widget_on;
769 struct regulator *spkdrv_reg;
770 struct regulator *spkdrv2_reg;
771
772 bool mbhc_started;
773 /* class h specific data */
774 struct wcd_clsh_cdc_data clsh_d;
775
776 struct afe_param_cdc_slimbus_slave_cfg slimbus_slave_cfg;
777
778 /*
779 * list used to save/restore registers at start and
780 * end of impedance measurement
781 */
782 struct list_head reg_save_restore;
783
784 /* handle to cpe core */
785 struct wcd_cpe_core *cpe_core;
786 u32 current_cpe_clk_freq;
787 enum tasha_sido_voltage sido_voltage;
788 int sido_ccl_cnt;
789
790 u32 ana_rx_supplies;
791 /* Multiplication factor used for impedance detection */
792 int zdet_gain_mul_fact;
793
794 /* to track the status */
795 unsigned long status_mask;
796
797 struct work_struct tasha_add_child_devices_work;
798 struct wcd_swr_ctrl_platform_data swr_plat_data;
799
800 /* Port values for Rx and Tx codec_dai */
801 unsigned int rx_port_value[TASHA_RX_MAX];
802 unsigned int tx_port_value;
803
804 unsigned int vi_feed_value;
805 /* Tasha Interpolator Mode Select for EAR, HPH_L and HPH_R */
806 u32 hph_mode;
807
808 u16 prim_int_users[TASHA_NUM_INTERPOLATORS];
809 int spl_src_users[SPLINE_SRC_MAX];
810
811 struct wcd9xxx_resmgr_v2 *resmgr;
812 struct delayed_work power_gate_work;
813 struct mutex power_lock;
814 struct mutex sido_lock;
815
816 /* mbhc module */
817 struct wcd_mbhc mbhc;
818 struct blocking_notifier_head notifier;
819 struct mutex micb_lock;
820
821 struct clk *wcd_ext_clk;
822 struct clk *wcd_native_clk;
823 struct mutex swr_read_lock;
824 struct mutex swr_write_lock;
825 struct mutex swr_clk_lock;
826 int swr_clk_users;
827 int native_clk_users;
828 int (*zdet_gpio_cb)(struct snd_soc_codec *codec, bool high);
829
830 struct snd_info_entry *entry;
831 struct snd_info_entry *version_entry;
832 int power_active_ref;
833
834 struct on_demand_supply on_demand_list[ON_DEMAND_SUPPLIES_MAX];
835
836 int (*machine_codec_event_cb)(struct snd_soc_codec *codec,
837 enum wcd9335_codec_event);
838 int spkr_gain_offset;
839 int spkr_mode;
840 int ear_spkr_gain;
841 struct hpf_work tx_hpf_work[TASHA_NUM_DECIMATORS];
842 struct tx_mute_work tx_mute_dwork[TASHA_NUM_DECIMATORS];
843 struct spk_anc_work spk_anc_dwork;
844 struct mutex codec_mutex;
845 int hph_l_gain;
846 int hph_r_gain;
847 int rx_7_count;
848 int rx_8_count;
849 bool clk_mode;
850 bool clk_internal;
851
852 /* Lock to protect mclk enablement */
853 struct mutex mclk_lock;
854};
855
856static int tasha_codec_vote_max_bw(struct snd_soc_codec *codec,
857 bool vote);
858
859static const struct tasha_reg_mask_val tasha_spkr_default[] = {
860 {WCD9335_CDC_COMPANDER7_CTL3, 0x80, 0x80},
861 {WCD9335_CDC_COMPANDER8_CTL3, 0x80, 0x80},
862 {WCD9335_CDC_COMPANDER7_CTL7, 0x01, 0x01},
863 {WCD9335_CDC_COMPANDER8_CTL7, 0x01, 0x01},
864 {WCD9335_CDC_BOOST0_BOOST_CTL, 0x7C, 0x50},
865 {WCD9335_CDC_BOOST1_BOOST_CTL, 0x7C, 0x50},
866};
867
868static const struct tasha_reg_mask_val tasha_spkr_mode1[] = {
869 {WCD9335_CDC_COMPANDER7_CTL3, 0x80, 0x00},
870 {WCD9335_CDC_COMPANDER8_CTL3, 0x80, 0x00},
871 {WCD9335_CDC_COMPANDER7_CTL7, 0x01, 0x00},
872 {WCD9335_CDC_COMPANDER8_CTL7, 0x01, 0x00},
873 {WCD9335_CDC_BOOST0_BOOST_CTL, 0x7C, 0x44},
874 {WCD9335_CDC_BOOST1_BOOST_CTL, 0x7C, 0x44},
875};
876
877/*
878 * wcd9335_get_codec_info: Get codec specific information
879 *
880 * @wcd9xxx: pointer to wcd9xxx structure
881 * @wcd_type: pointer to wcd9xxx_codec_type structure
882 *
883 * Returns 0 for success or negative error code for failure
884 */
885int wcd9335_get_codec_info(struct wcd9xxx *wcd9xxx,
886 struct wcd9xxx_codec_type *wcd_type)
887{
888 u16 id_minor, id_major;
889 struct regmap *wcd_regmap;
890 int rc, val, version = 0;
891
892 if (!wcd9xxx || !wcd_type)
893 return -EINVAL;
894
895 if (!wcd9xxx->regmap) {
896 dev_err(wcd9xxx->dev, "%s: wcd9xxx regmap is null!\n",
897 __func__);
898 return -EINVAL;
899 }
900 wcd_regmap = wcd9xxx->regmap;
901
902 rc = regmap_bulk_read(wcd_regmap, WCD9335_CHIP_TIER_CTRL_CHIP_ID_BYTE0,
903 (u8 *)&id_minor, sizeof(u16));
904 if (rc)
905 return -EINVAL;
906
907 rc = regmap_bulk_read(wcd_regmap, WCD9335_CHIP_TIER_CTRL_CHIP_ID_BYTE2,
908 (u8 *)&id_major, sizeof(u16));
909 if (rc)
910 return -EINVAL;
911
912 dev_info(wcd9xxx->dev, "%s: wcd9xxx chip id major 0x%x, minor 0x%x\n",
913 __func__, id_major, id_minor);
914
915 /* Version detection */
916 if (id_major == TASHA_MAJOR) {
917 regmap_read(wcd_regmap, WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT0,
918 &val);
919 version = ((u8)val & 0x80) >> 7;
920 } else if (id_major == TASHA2P0_MAJOR)
921 version = 2;
922 else
923 dev_err(wcd9xxx->dev, "%s: wcd9335 version unknown (major 0x%x, minor 0x%x)\n",
924 __func__, id_major, id_minor);
925
926 /* Fill codec type info */
927 wcd_type->id_major = id_major;
928 wcd_type->id_minor = id_minor;
929 wcd_type->num_irqs = WCD9335_NUM_IRQS;
930 wcd_type->version = version;
931 wcd_type->slim_slave_type = WCD9XXX_SLIM_SLAVE_ADDR_TYPE_1;
932 wcd_type->i2c_chip_status = 0x01;
933 wcd_type->intr_tbl = wcd9335_intr_table;
934 wcd_type->intr_tbl_size = ARRAY_SIZE(wcd9335_intr_table);
935
936 wcd_type->intr_reg[WCD9XXX_INTR_STATUS_BASE] =
937 WCD9335_INTR_PIN1_STATUS0;
938 wcd_type->intr_reg[WCD9XXX_INTR_CLEAR_BASE] =
939 WCD9335_INTR_PIN1_CLEAR0;
940 wcd_type->intr_reg[WCD9XXX_INTR_MASK_BASE] =
941 WCD9335_INTR_PIN1_MASK0;
942 wcd_type->intr_reg[WCD9XXX_INTR_LEVEL_BASE] =
943 WCD9335_INTR_LEVEL0;
944 wcd_type->intr_reg[WCD9XXX_INTR_CLR_COMMIT] =
945 WCD9335_INTR_CLR_COMMIT;
946
947 return rc;
948}
949EXPORT_SYMBOL(wcd9335_get_codec_info);
950
951/*
952 * wcd9335_bringdown: Bringdown WCD Codec
953 *
954 * @wcd9xxx: Pointer to wcd9xxx structure
955 *
956 * Returns 0 for success or negative error code for failure
957 */
958int wcd9335_bringdown(struct wcd9xxx *wcd9xxx)
959{
960 if (!wcd9xxx || !wcd9xxx->regmap)
961 return -EINVAL;
962
963 regmap_write(wcd9xxx->regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL,
964 0x04);
965
966 return 0;
967}
968EXPORT_SYMBOL(wcd9335_bringdown);
969
970/*
971 * wcd9335_bringup: Bringup WCD Codec
972 *
973 * @wcd9xxx: Pointer to the wcd9xxx structure
974 *
975 * Returns 0 for success or negative error code for failure
976 */
977int wcd9335_bringup(struct wcd9xxx *wcd9xxx)
978{
979 int ret = 0;
980 int val, byte0;
981 struct regmap *wcd_regmap;
982
983 if (!wcd9xxx)
984 return -EINVAL;
985
986 if (!wcd9xxx->regmap) {
987 dev_err(wcd9xxx->dev, "%s: wcd9xxx regmap is null!\n",
988 __func__);
989 return -EINVAL;
990 }
991 wcd_regmap = wcd9xxx->regmap;
992
993 regmap_read(wcd_regmap, WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT0, &val);
994 regmap_read(wcd_regmap, WCD9335_CHIP_TIER_CTRL_CHIP_ID_BYTE0, &byte0);
995
996 if ((val < 0) || (byte0 < 0)) {
997 dev_err(wcd9xxx->dev, "%s: tasha codec version detection fail!\n",
998 __func__);
999 return -EINVAL;
1000 }
1001 if ((val & 0x80) && (byte0 == 0x0)) {
1002 dev_info(wcd9xxx->dev, "%s: wcd9335 codec version is v1.1\n",
1003 __func__);
1004 regmap_write(wcd_regmap, WCD9335_CODEC_RPM_RST_CTL, 0x01);
1005 regmap_write(wcd_regmap, WCD9335_SIDO_SIDO_CCL_2, 0xFC);
1006 regmap_write(wcd_regmap, WCD9335_SIDO_SIDO_CCL_4, 0x21);
1007 regmap_write(wcd_regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL,
1008 0x5);
1009 regmap_write(wcd_regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL,
1010 0x7);
1011 regmap_write(wcd_regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL,
1012 0x3);
1013 regmap_write(wcd_regmap, WCD9335_CODEC_RPM_RST_CTL, 0x3);
1014 } else if (byte0 == 0x1) {
1015 dev_info(wcd9xxx->dev, "%s: wcd9335 codec version is v2.0\n",
1016 __func__);
1017 regmap_write(wcd_regmap, WCD9335_CODEC_RPM_RST_CTL, 0x01);
1018 regmap_write(wcd_regmap, WCD9335_SIDO_SIDO_TEST_2, 0x00);
1019 regmap_write(wcd_regmap, WCD9335_SIDO_SIDO_CCL_8, 0x6F);
1020 regmap_write(wcd_regmap, WCD9335_BIAS_VBG_FINE_ADJ, 0x65);
1021 regmap_write(wcd_regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL,
1022 0x5);
1023 regmap_write(wcd_regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL,
1024 0x7);
1025 regmap_write(wcd_regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL,
1026 0x3);
1027 regmap_write(wcd_regmap, WCD9335_CODEC_RPM_RST_CTL, 0x3);
1028 } else if ((byte0 == 0) && (!(val & 0x80))) {
1029 dev_info(wcd9xxx->dev, "%s: wcd9335 codec version is v1.0\n",
1030 __func__);
1031 regmap_write(wcd_regmap, WCD9335_CODEC_RPM_RST_CTL, 0x01);
1032 regmap_write(wcd_regmap, WCD9335_SIDO_SIDO_CCL_2, 0xFC);
1033 regmap_write(wcd_regmap, WCD9335_SIDO_SIDO_CCL_4, 0x21);
1034 regmap_write(wcd_regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL,
1035 0x3);
1036 regmap_write(wcd_regmap, WCD9335_CODEC_RPM_RST_CTL, 0x3);
1037 } else {
1038 dev_err(wcd9xxx->dev, "%s: tasha codec version unknown\n",
1039 __func__);
1040 ret = -EINVAL;
1041 }
1042
1043 return ret;
1044}
1045EXPORT_SYMBOL(wcd9335_bringup);
1046
1047/**
1048 * tasha_set_spkr_gain_offset - offset the speaker path
1049 * gain with the given offset value.
1050 *
1051 * @codec: codec instance
1052 * @offset: Indicates speaker path gain offset value.
1053 *
1054 * Returns 0 on success or -EINVAL on error.
1055 */
1056int tasha_set_spkr_gain_offset(struct snd_soc_codec *codec, int offset)
1057{
1058 struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec);
1059
1060 if (!priv)
1061 return -EINVAL;
1062
1063 priv->spkr_gain_offset = offset;
1064 return 0;
1065}
1066EXPORT_SYMBOL(tasha_set_spkr_gain_offset);
1067
1068/**
1069 * tasha_set_spkr_mode - Configures speaker compander and smartboost
1070 * settings based on speaker mode.
1071 *
1072 * @codec: codec instance
1073 * @mode: Indicates speaker configuration mode.
1074 *
1075 * Returns 0 on success or -EINVAL on error.
1076 */
1077int tasha_set_spkr_mode(struct snd_soc_codec *codec, int mode)
1078{
1079 struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec);
1080 int i;
1081 const struct tasha_reg_mask_val *regs;
1082 int size;
1083
1084 if (!priv)
1085 return -EINVAL;
1086
1087 switch (mode) {
1088 case SPKR_MODE_1:
1089 regs = tasha_spkr_mode1;
1090 size = ARRAY_SIZE(tasha_spkr_mode1);
1091 break;
1092 default:
1093 regs = tasha_spkr_default;
1094 size = ARRAY_SIZE(tasha_spkr_default);
1095 break;
1096 }
1097
1098 priv->spkr_mode = mode;
1099 for (i = 0; i < size; i++)
1100 snd_soc_update_bits(codec, regs[i].reg,
1101 regs[i].mask, regs[i].val);
1102 return 0;
1103}
1104EXPORT_SYMBOL(tasha_set_spkr_mode);
1105
1106static void tasha_enable_sido_buck(struct snd_soc_codec *codec)
1107{
1108 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
1109
1110 snd_soc_update_bits(codec, WCD9335_ANA_RCO, 0x80, 0x80);
1111 snd_soc_update_bits(codec, WCD9335_ANA_BUCK_CTL, 0x02, 0x02);
1112 /* 100us sleep needed after IREF settings */
1113 usleep_range(100, 110);
1114 snd_soc_update_bits(codec, WCD9335_ANA_BUCK_CTL, 0x04, 0x04);
1115 /* 100us sleep needed after VREF settings */
1116 usleep_range(100, 110);
1117 tasha->resmgr->sido_input_src = SIDO_SOURCE_RCO_BG;
1118}
1119
1120static void tasha_cdc_sido_ccl_enable(struct tasha_priv *tasha, bool ccl_flag)
1121{
1122 struct snd_soc_codec *codec = tasha->codec;
1123
1124 if (!codec)
1125 return;
1126
1127 if (!TASHA_IS_2_0(tasha->wcd9xxx)) {
1128 dev_dbg(codec->dev, "%s: tasha version < 2p0, return\n",
1129 __func__);
1130 return;
1131 }
1132 dev_dbg(codec->dev, "%s: sido_ccl_cnt=%d, ccl_flag:%d\n",
1133 __func__, tasha->sido_ccl_cnt, ccl_flag);
1134 if (ccl_flag) {
1135 if (++tasha->sido_ccl_cnt == 1)
1136 snd_soc_update_bits(codec,
1137 WCD9335_SIDO_SIDO_CCL_10, 0xFF, 0x6E);
1138 } else {
1139 if (tasha->sido_ccl_cnt == 0) {
1140 dev_dbg(codec->dev, "%s: sido_ccl already disabled\n",
1141 __func__);
1142 return;
1143 }
1144 if (--tasha->sido_ccl_cnt == 0)
1145 snd_soc_update_bits(codec,
1146 WCD9335_SIDO_SIDO_CCL_10, 0xFF, 0x02);
1147 }
1148}
1149
1150static bool tasha_cdc_is_svs_enabled(struct tasha_priv *tasha)
1151{
1152 if (TASHA_IS_2_0(tasha->wcd9xxx) &&
1153 svs_scaling_enabled)
1154 return true;
1155
1156 return false;
1157}
1158
1159static int tasha_cdc_req_mclk_enable(struct tasha_priv *tasha,
1160 bool enable)
1161{
1162 int ret = 0;
1163
1164 mutex_lock(&tasha->mclk_lock);
1165 if (enable) {
1166 tasha_cdc_sido_ccl_enable(tasha, true);
1167 ret = clk_prepare_enable(tasha->wcd_ext_clk);
1168 if (ret) {
1169 dev_err(tasha->dev, "%s: ext clk enable failed\n",
1170 __func__);
1171 goto unlock_mutex;
1172 }
1173 /* get BG */
1174 wcd_resmgr_enable_master_bias(tasha->resmgr);
1175 /* get MCLK */
1176 wcd_resmgr_enable_clk_block(tasha->resmgr, WCD_CLK_MCLK);
1177 } else {
1178 /* put MCLK */
1179 wcd_resmgr_disable_clk_block(tasha->resmgr, WCD_CLK_MCLK);
1180 /* put BG */
1181 wcd_resmgr_disable_master_bias(tasha->resmgr);
1182 clk_disable_unprepare(tasha->wcd_ext_clk);
1183 tasha_cdc_sido_ccl_enable(tasha, false);
1184 }
1185unlock_mutex:
1186 mutex_unlock(&tasha->mclk_lock);
1187 return ret;
1188}
1189
1190static int tasha_cdc_check_sido_value(enum tasha_sido_voltage req_mv)
1191{
1192 if ((req_mv != SIDO_VOLTAGE_SVS_MV) &&
1193 (req_mv != SIDO_VOLTAGE_NOMINAL_MV))
1194 return -EINVAL;
1195
1196 return 0;
1197}
1198
1199static void tasha_codec_apply_sido_voltage(
1200 struct tasha_priv *tasha,
1201 enum tasha_sido_voltage req_mv)
1202{
1203 u32 vout_d_val;
1204 struct snd_soc_codec *codec = tasha->codec;
1205 int ret;
1206
1207 if (!codec)
1208 return;
1209
1210 if (!tasha_cdc_is_svs_enabled(tasha))
1211 return;
1212
1213 if ((sido_buck_svs_voltage != SIDO_VOLTAGE_SVS_MV) &&
1214 (sido_buck_svs_voltage != SIDO_VOLTAGE_NOMINAL_MV))
1215 sido_buck_svs_voltage = SIDO_VOLTAGE_SVS_MV;
1216
1217 ret = tasha_cdc_check_sido_value(req_mv);
1218 if (ret < 0) {
1219 dev_dbg(codec->dev, "%s: requested mv=%d not in range\n",
1220 __func__, req_mv);
1221 return;
1222 }
1223 if (req_mv == tasha->sido_voltage) {
1224 dev_dbg(codec->dev, "%s: Already at requested mv=%d\n",
1225 __func__, req_mv);
1226 return;
1227 }
1228 if (req_mv == sido_buck_svs_voltage) {
1229 if (test_bit(AUDIO_NOMINAL, &tasha->status_mask) ||
1230 test_bit(CPE_NOMINAL, &tasha->status_mask)) {
1231 dev_dbg(codec->dev,
1232 "%s: nominal client running, status_mask=%lu\n",
1233 __func__, tasha->status_mask);
1234 return;
1235 }
1236 }
1237 /* compute the vout_d step value */
1238 vout_d_val = CALCULATE_VOUT_D(req_mv);
1239 snd_soc_write(codec, WCD9335_ANA_BUCK_VOUT_D, vout_d_val & 0xFF);
1240 snd_soc_update_bits(codec, WCD9335_ANA_BUCK_CTL, 0x80, 0x80);
1241
1242 /* 1 msec sleep required after SIDO Vout_D voltage change */
1243 usleep_range(1000, 1100);
1244 tasha->sido_voltage = req_mv;
1245 dev_dbg(codec->dev,
1246 "%s: updated SIDO buck Vout_D to %d, vout_d step = %u\n",
1247 __func__, tasha->sido_voltage, vout_d_val);
1248
1249 snd_soc_update_bits(codec, WCD9335_ANA_BUCK_CTL,
1250 0x80, 0x00);
1251}
1252
1253static int tasha_codec_update_sido_voltage(
1254 struct tasha_priv *tasha,
1255 enum tasha_sido_voltage req_mv)
1256{
1257 int ret = 0;
1258
1259 if (!tasha_cdc_is_svs_enabled(tasha))
1260 return ret;
1261
1262 mutex_lock(&tasha->sido_lock);
1263 /* enable mclk before setting SIDO voltage */
1264 ret = tasha_cdc_req_mclk_enable(tasha, true);
1265 if (ret) {
1266 dev_err(tasha->dev, "%s: ext clk enable failed\n",
1267 __func__);
1268 goto err;
1269 }
1270 tasha_codec_apply_sido_voltage(tasha, req_mv);
1271 tasha_cdc_req_mclk_enable(tasha, false);
1272
1273err:
1274 mutex_unlock(&tasha->sido_lock);
1275 return ret;
1276}
1277
1278int tasha_enable_efuse_sensing(struct snd_soc_codec *codec)
1279{
1280 struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec);
1281
1282 tasha_cdc_mclk_enable(codec, true, false);
1283
1284 if (!TASHA_IS_2_0(priv->wcd9xxx))
1285 snd_soc_update_bits(codec, WCD9335_CHIP_TIER_CTRL_EFUSE_CTL,
1286 0x1E, 0x02);
1287 snd_soc_update_bits(codec, WCD9335_CHIP_TIER_CTRL_EFUSE_CTL,
1288 0x01, 0x01);
1289 /*
1290 * 5ms sleep required after enabling efuse control
1291 * before checking the status.
1292 */
1293 usleep_range(5000, 5500);
1294 if (!(snd_soc_read(codec, WCD9335_CHIP_TIER_CTRL_EFUSE_STATUS) & 0x01))
1295 WARN(1, "%s: Efuse sense is not complete\n", __func__);
1296
1297 if (TASHA_IS_2_0(priv->wcd9xxx)) {
1298 if (!(snd_soc_read(codec,
1299 WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT0) & 0x40))
1300 snd_soc_update_bits(codec, WCD9335_HPH_R_ATEST,
1301 0x04, 0x00);
1302 tasha_enable_sido_buck(codec);
1303 }
1304
1305 tasha_cdc_mclk_enable(codec, false, false);
1306
1307 return 0;
1308}
1309EXPORT_SYMBOL(tasha_enable_efuse_sensing);
1310
1311void *tasha_get_afe_config(struct snd_soc_codec *codec,
1312 enum afe_config_type config_type)
1313{
1314 struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec);
1315
1316 switch (config_type) {
1317 case AFE_SLIMBUS_SLAVE_CONFIG:
1318 return &priv->slimbus_slave_cfg;
1319 case AFE_CDC_REGISTERS_CONFIG:
1320 return &tasha_audio_reg_cfg;
1321 case AFE_SLIMBUS_SLAVE_PORT_CONFIG:
1322 return &tasha_slimbus_slave_port_cfg;
1323 case AFE_AANC_VERSION:
1324 return &tasha_cdc_aanc_version;
1325 case AFE_CLIP_BANK_SEL:
1326 return NULL;
1327 case AFE_CDC_CLIP_REGISTERS_CONFIG:
1328 return NULL;
1329 case AFE_CDC_REGISTER_PAGE_CONFIG:
1330 return &tasha_cdc_reg_page_cfg;
1331 default:
1332 dev_err(codec->dev, "%s: Unknown config_type 0x%x\n",
1333 __func__, config_type);
1334 return NULL;
1335 }
1336}
1337EXPORT_SYMBOL(tasha_get_afe_config);
1338
1339/*
1340 * tasha_event_register: Registers a machine driver callback
1341 * function with codec private data for post ADSP sub-system
1342 * restart (SSR). This callback function will be called from
1343 * codec driver once codec comes out of reset after ADSP SSR.
1344 *
1345 * @machine_event_cb: callback function from machine driver
1346 * @codec: Codec instance
1347 *
1348 * Return: none
1349 */
1350void tasha_event_register(
1351 int (*machine_event_cb)(struct snd_soc_codec *codec,
1352 enum wcd9335_codec_event),
1353 struct snd_soc_codec *codec)
1354{
1355 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
1356
1357 if (tasha)
1358 tasha->machine_codec_event_cb = machine_event_cb;
1359 else
1360 dev_dbg(codec->dev, "%s: Invalid tasha_priv data\n", __func__);
1361}
1362EXPORT_SYMBOL(tasha_event_register);
1363
1364static int tasha_mbhc_request_irq(struct snd_soc_codec *codec,
1365 int irq, irq_handler_t handler,
1366 const char *name, void *data)
1367{
1368 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
1369 struct wcd9xxx *wcd9xxx = tasha->wcd9xxx;
1370 struct wcd9xxx_core_resource *core_res =
1371 &wcd9xxx->core_res;
1372
1373 return wcd9xxx_request_irq(core_res, irq, handler, name, data);
1374}
1375
1376static void tasha_mbhc_irq_control(struct snd_soc_codec *codec,
1377 int irq, bool enable)
1378{
1379 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
1380 struct wcd9xxx *wcd9xxx = tasha->wcd9xxx;
1381 struct wcd9xxx_core_resource *core_res =
1382 &wcd9xxx->core_res;
1383 if (enable)
1384 wcd9xxx_enable_irq(core_res, irq);
1385 else
1386 wcd9xxx_disable_irq(core_res, irq);
1387}
1388
1389static int tasha_mbhc_free_irq(struct snd_soc_codec *codec,
1390 int irq, void *data)
1391{
1392 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
1393 struct wcd9xxx *wcd9xxx = tasha->wcd9xxx;
1394 struct wcd9xxx_core_resource *core_res =
1395 &wcd9xxx->core_res;
1396
1397 wcd9xxx_free_irq(core_res, irq, data);
1398 return 0;
1399}
1400
1401static void tasha_mbhc_clk_setup(struct snd_soc_codec *codec,
1402 bool enable)
1403{
1404 if (enable)
1405 snd_soc_update_bits(codec, WCD9335_MBHC_CTL_1,
1406 0x80, 0x80);
1407 else
1408 snd_soc_update_bits(codec, WCD9335_MBHC_CTL_1,
1409 0x80, 0x00);
1410}
1411
1412static int tasha_mbhc_btn_to_num(struct snd_soc_codec *codec)
1413{
1414 return snd_soc_read(codec, WCD9335_ANA_MBHC_RESULT_3) & 0x7;
1415}
1416
1417static void tasha_mbhc_mbhc_bias_control(struct snd_soc_codec *codec,
1418 bool enable)
1419{
1420 if (enable)
1421 snd_soc_update_bits(codec, WCD9335_ANA_MBHC_ELECT,
1422 0x01, 0x01);
1423 else
1424 snd_soc_update_bits(codec, WCD9335_ANA_MBHC_ELECT,
1425 0x01, 0x00);
1426}
1427
1428static void tasha_mbhc_program_btn_thr(struct snd_soc_codec *codec,
1429 s16 *btn_low, s16 *btn_high,
1430 int num_btn, bool is_micbias)
1431{
1432 int i;
1433 int vth;
1434
1435 if (num_btn > WCD_MBHC_DEF_BUTTONS) {
1436 dev_err(codec->dev, "%s: invalid number of buttons: %d\n",
1437 __func__, num_btn);
1438 return;
1439 }
1440 /*
1441 * Tasha just needs one set of thresholds for button detection
1442 * due to micbias voltage ramp to pullup upon button press. So
1443 * btn_low and is_micbias are ignored and always program button
1444 * thresholds using btn_high.
1445 */
1446 for (i = 0; i < num_btn; i++) {
1447 vth = ((btn_high[i] * 2) / 25) & 0x3F;
1448 snd_soc_update_bits(codec, WCD9335_ANA_MBHC_BTN0 + i,
1449 0xFC, vth << 2);
1450 dev_dbg(codec->dev, "%s: btn_high[%d]: %d, vth: %d\n",
1451 __func__, i, btn_high[i], vth);
1452 }
1453}
1454
1455static bool tasha_mbhc_lock_sleep(struct wcd_mbhc *mbhc, bool lock)
1456{
1457 struct snd_soc_codec *codec = mbhc->codec;
1458 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
1459 struct wcd9xxx *wcd9xxx = tasha->wcd9xxx;
1460 struct wcd9xxx_core_resource *core_res =
1461 &wcd9xxx->core_res;
1462 if (lock)
1463 return wcd9xxx_lock_sleep(core_res);
1464 else {
1465 wcd9xxx_unlock_sleep(core_res);
1466 return 0;
1467 }
1468}
1469
1470static int tasha_mbhc_register_notifier(struct wcd_mbhc *mbhc,
1471 struct notifier_block *nblock,
1472 bool enable)
1473{
1474 struct snd_soc_codec *codec = mbhc->codec;
1475 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
1476
1477 if (enable)
1478 return blocking_notifier_chain_register(&tasha->notifier,
1479 nblock);
1480 else
1481 return blocking_notifier_chain_unregister(&tasha->notifier,
1482 nblock);
1483}
1484
1485static bool tasha_mbhc_micb_en_status(struct wcd_mbhc *mbhc, int micb_num)
1486{
1487 u8 val;
1488
1489 if (micb_num == MIC_BIAS_2) {
1490 val = (snd_soc_read(mbhc->codec, WCD9335_ANA_MICB2) >> 6);
1491 if (val == 0x01)
1492 return true;
1493 }
1494 return false;
1495}
1496
1497static bool tasha_mbhc_hph_pa_on_status(struct snd_soc_codec *codec)
1498{
1499 return (snd_soc_read(codec, WCD9335_ANA_HPH) & 0xC0) ? true : false;
1500}
1501
1502static void tasha_mbhc_hph_l_pull_up_control(struct snd_soc_codec *codec,
1503 enum mbhc_hs_pullup_iref pull_up_cur)
1504{
1505 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
1506
1507 if (!tasha)
1508 return;
1509
1510 /* Default pull up current to 2uA */
1511 if (pull_up_cur < I_OFF || pull_up_cur > I_3P0_UA ||
1512 pull_up_cur == I_DEFAULT)
1513 pull_up_cur = I_2P0_UA;
1514
1515 dev_dbg(codec->dev, "%s: HS pull up current:%d\n",
1516 __func__, pull_up_cur);
1517
1518 if (TASHA_IS_2_0(tasha->wcd9xxx))
1519 snd_soc_update_bits(codec, WCD9335_MBHC_PLUG_DETECT_CTL,
1520 0xC0, pull_up_cur << 6);
1521 else
1522 snd_soc_update_bits(codec, WCD9335_MBHC_PLUG_DETECT_CTL,
1523 0xC0, 0x40);
1524}
1525
1526static int tasha_enable_ext_mb_source(struct wcd_mbhc *mbhc,
1527 bool turn_on)
1528{
1529 struct snd_soc_codec *codec = mbhc->codec;
1530 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
1531 int ret = 0;
1532 struct on_demand_supply *supply;
1533
1534 if (!tasha)
1535 return -EINVAL;
1536
1537 supply = &tasha->on_demand_list[ON_DEMAND_MICBIAS];
1538 if (!supply->supply) {
1539 dev_dbg(codec->dev, "%s: warning supply not present ond for %s\n",
1540 __func__, "onDemand Micbias");
1541 return ret;
1542 }
1543
1544 dev_dbg(codec->dev, "%s turn_on: %d count: %d\n", __func__, turn_on,
1545 supply->ondemand_supply_count);
1546
1547 if (turn_on) {
1548 if (!(supply->ondemand_supply_count)) {
1549 ret = snd_soc_dapm_force_enable_pin(
1550 snd_soc_codec_get_dapm(codec),
1551 "MICBIAS_REGULATOR");
1552 snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec));
1553 }
1554 supply->ondemand_supply_count++;
1555 } else {
1556 if (supply->ondemand_supply_count > 0)
1557 supply->ondemand_supply_count--;
1558 if (!(supply->ondemand_supply_count)) {
1559 ret = snd_soc_dapm_disable_pin(
1560 snd_soc_codec_get_dapm(codec),
1561 "MICBIAS_REGULATOR");
1562 snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec));
1563 }
1564 }
1565
1566 if (ret)
1567 dev_err(codec->dev, "%s: Failed to %s external micbias source\n",
1568 __func__, turn_on ? "enable" : "disabled");
1569 else
1570 dev_dbg(codec->dev, "%s: %s external micbias source\n",
1571 __func__, turn_on ? "Enabled" : "Disabled");
1572
1573 return ret;
1574}
1575
1576static int tasha_micbias_control(struct snd_soc_codec *codec,
1577 int micb_num,
1578 int req, bool is_dapm)
1579{
1580 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
1581 int micb_index = micb_num - 1;
1582 u16 micb_reg;
1583 int pre_off_event = 0, post_off_event = 0;
1584 int post_on_event = 0, post_dapm_off = 0;
1585 int post_dapm_on = 0;
1586
1587 if ((micb_index < 0) || (micb_index > TASHA_MAX_MICBIAS - 1)) {
1588 dev_err(codec->dev, "%s: Invalid micbias index, micb_ind:%d\n",
1589 __func__, micb_index);
1590 return -EINVAL;
1591 }
1592 switch (micb_num) {
1593 case MIC_BIAS_1:
1594 micb_reg = WCD9335_ANA_MICB1;
1595 break;
1596 case MIC_BIAS_2:
1597 micb_reg = WCD9335_ANA_MICB2;
1598 pre_off_event = WCD_EVENT_PRE_MICBIAS_2_OFF;
1599 post_off_event = WCD_EVENT_POST_MICBIAS_2_OFF;
1600 post_on_event = WCD_EVENT_POST_MICBIAS_2_ON;
1601 post_dapm_on = WCD_EVENT_POST_DAPM_MICBIAS_2_ON;
1602 post_dapm_off = WCD_EVENT_POST_DAPM_MICBIAS_2_OFF;
1603 break;
1604 case MIC_BIAS_3:
1605 micb_reg = WCD9335_ANA_MICB3;
1606 break;
1607 case MIC_BIAS_4:
1608 micb_reg = WCD9335_ANA_MICB4;
1609 break;
1610 default:
1611 dev_err(codec->dev, "%s: Invalid micbias number: %d\n",
1612 __func__, micb_num);
1613 return -EINVAL;
1614 }
1615 mutex_lock(&tasha->micb_lock);
1616
1617 switch (req) {
1618 case MICB_PULLUP_ENABLE:
1619 tasha->pullup_ref[micb_index]++;
1620 if ((tasha->pullup_ref[micb_index] == 1) &&
1621 (tasha->micb_ref[micb_index] == 0))
1622 snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80);
1623 break;
1624 case MICB_PULLUP_DISABLE:
1625 if (tasha->pullup_ref[micb_index] > 0)
1626 tasha->pullup_ref[micb_index]--;
1627 if ((tasha->pullup_ref[micb_index] == 0) &&
1628 (tasha->micb_ref[micb_index] == 0))
1629 snd_soc_update_bits(codec, micb_reg, 0xC0, 0x00);
1630 break;
1631 case MICB_ENABLE:
1632 tasha->micb_ref[micb_index]++;
1633 if (tasha->micb_ref[micb_index] == 1) {
1634 snd_soc_update_bits(codec, micb_reg, 0xC0, 0x40);
1635 if (post_on_event)
1636 blocking_notifier_call_chain(&tasha->notifier,
1637 post_on_event, &tasha->mbhc);
1638 }
1639 if (is_dapm && post_dapm_on)
1640 blocking_notifier_call_chain(&tasha->notifier,
1641 post_dapm_on, &tasha->mbhc);
1642 break;
1643 case MICB_DISABLE:
1644 if (tasha->micb_ref[micb_index] > 0)
1645 tasha->micb_ref[micb_index]--;
1646 if ((tasha->micb_ref[micb_index] == 0) &&
1647 (tasha->pullup_ref[micb_index] > 0))
1648 snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80);
1649 else if ((tasha->micb_ref[micb_index] == 0) &&
1650 (tasha->pullup_ref[micb_index] == 0)) {
1651 if (pre_off_event)
1652 blocking_notifier_call_chain(&tasha->notifier,
1653 pre_off_event, &tasha->mbhc);
1654 snd_soc_update_bits(codec, micb_reg, 0xC0, 0x00);
1655 if (post_off_event)
1656 blocking_notifier_call_chain(&tasha->notifier,
1657 post_off_event, &tasha->mbhc);
1658 }
1659 if (is_dapm && post_dapm_off)
1660 blocking_notifier_call_chain(&tasha->notifier,
1661 post_dapm_off, &tasha->mbhc);
1662 break;
1663 };
1664
1665 dev_dbg(codec->dev, "%s: micb_num:%d, micb_ref: %d, pullup_ref: %d\n",
1666 __func__, micb_num, tasha->micb_ref[micb_index],
1667 tasha->pullup_ref[micb_index]);
1668
1669 mutex_unlock(&tasha->micb_lock);
1670
1671 return 0;
1672}
1673
1674static int tasha_mbhc_request_micbias(struct snd_soc_codec *codec,
1675 int micb_num, int req)
1676{
1677 int ret;
1678
1679 /*
1680 * If micbias is requested, make sure that there
1681 * is vote to enable mclk
1682 */
1683 if (req == MICB_ENABLE)
1684 tasha_cdc_mclk_enable(codec, true, false);
1685
1686 ret = tasha_micbias_control(codec, micb_num, req, false);
1687
1688 /*
1689 * Release vote for mclk while requesting for
1690 * micbias disable
1691 */
1692 if (req == MICB_DISABLE)
1693 tasha_cdc_mclk_enable(codec, false, false);
1694
1695 return ret;
1696}
1697
1698static void tasha_mbhc_micb_ramp_control(struct snd_soc_codec *codec,
1699 bool enable)
1700{
1701 if (enable) {
1702 snd_soc_update_bits(codec, WCD9335_ANA_MICB2_RAMP,
1703 0x1C, 0x0C);
1704 snd_soc_update_bits(codec, WCD9335_ANA_MICB2_RAMP,
1705 0x80, 0x80);
1706 } else {
1707 snd_soc_update_bits(codec, WCD9335_ANA_MICB2_RAMP,
1708 0x80, 0x00);
1709 snd_soc_update_bits(codec, WCD9335_ANA_MICB2_RAMP,
1710 0x1C, 0x00);
1711 }
1712}
1713
1714static struct firmware_cal *tasha_get_hwdep_fw_cal(struct wcd_mbhc *mbhc,
1715 enum wcd_cal_type type)
1716{
1717 struct tasha_priv *tasha;
1718 struct firmware_cal *hwdep_cal;
1719 struct snd_soc_codec *codec = mbhc->codec;
1720
1721 if (!codec) {
1722 pr_err("%s: NULL codec pointer\n", __func__);
1723 return NULL;
1724 }
1725 tasha = snd_soc_codec_get_drvdata(codec);
1726 hwdep_cal = wcdcal_get_fw_cal(tasha->fw_data, type);
1727 if (!hwdep_cal)
1728 dev_err(codec->dev, "%s: cal not sent by %d\n",
1729 __func__, type);
1730
1731 return hwdep_cal;
1732}
1733
1734static int tasha_mbhc_micb_adjust_voltage(struct snd_soc_codec *codec,
1735 int req_volt,
1736 int micb_num)
1737{
1738 int cur_vout_ctl, req_vout_ctl;
1739 int micb_reg, micb_val, micb_en;
1740
1741 switch (micb_num) {
1742 case MIC_BIAS_1:
1743 micb_reg = WCD9335_ANA_MICB1;
1744 break;
1745 case MIC_BIAS_2:
1746 micb_reg = WCD9335_ANA_MICB2;
1747 break;
1748 case MIC_BIAS_3:
1749 micb_reg = WCD9335_ANA_MICB3;
1750 break;
1751 case MIC_BIAS_4:
1752 micb_reg = WCD9335_ANA_MICB4;
1753 break;
1754 default:
1755 return -EINVAL;
1756 }
1757
1758 /*
1759 * If requested micbias voltage is same as current micbias
1760 * voltage, then just return. Otherwise, adjust voltage as
1761 * per requested value. If micbias is already enabled, then
1762 * to avoid slow micbias ramp-up or down enable pull-up
1763 * momentarily, change the micbias value and then re-enable
1764 * micbias.
1765 */
1766 micb_val = snd_soc_read(codec, micb_reg);
1767 micb_en = (micb_val & 0xC0) >> 6;
1768 cur_vout_ctl = micb_val & 0x3F;
1769
1770 req_vout_ctl = wcd9335_get_micb_vout_ctl_val(req_volt);
Xiaoyu Ye1a2d8bd92017-01-31 18:54:15 -08001771 if (req_vout_ctl < 0)
Banajit Goswamide8271c2017-01-18 00:28:59 -08001772 return -EINVAL;
1773 if (cur_vout_ctl == req_vout_ctl)
1774 return 0;
1775
1776 dev_dbg(codec->dev, "%s: micb_num: %d, cur_mv: %d, req_mv: %d, micb_en: %d\n",
1777 __func__, micb_num, WCD_VOUT_CTL_TO_MICB(cur_vout_ctl),
1778 req_volt, micb_en);
1779
1780 if (micb_en == 0x1)
1781 snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80);
1782
1783 snd_soc_update_bits(codec, micb_reg, 0x3F, req_vout_ctl);
1784
1785 if (micb_en == 0x1) {
1786 snd_soc_update_bits(codec, micb_reg, 0xC0, 0x40);
1787 /*
1788 * Add 2ms delay as per HW requirement after enabling
1789 * micbias
1790 */
1791 usleep_range(2000, 2100);
1792 }
1793
1794 return 0;
1795}
1796
1797static int tasha_mbhc_micb_ctrl_threshold_mic(struct snd_soc_codec *codec,
1798 int micb_num, bool req_en)
1799{
1800 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
1801 struct wcd9xxx_pdata *pdata = dev_get_platdata(codec->dev->parent);
1802 int rc, micb_mv;
1803
1804 if (micb_num != MIC_BIAS_2)
1805 return -EINVAL;
1806
1807 /*
1808 * If device tree micbias level is already above the minimum
1809 * voltage needed to detect threshold microphone, then do
1810 * not change the micbias, just return.
1811 */
1812 if (pdata->micbias.micb2_mv >= WCD_MBHC_THR_HS_MICB_MV)
1813 return 0;
1814
1815 micb_mv = req_en ? WCD_MBHC_THR_HS_MICB_MV : pdata->micbias.micb2_mv;
1816
1817 mutex_lock(&tasha->micb_lock);
1818 rc = tasha_mbhc_micb_adjust_voltage(codec, micb_mv, MIC_BIAS_2);
1819 mutex_unlock(&tasha->micb_lock);
1820
1821 return rc;
1822}
1823
1824static inline void tasha_mbhc_get_result_params(struct wcd9xxx *wcd9xxx,
1825 s16 *d1_a, u16 noff,
1826 int32_t *zdet)
1827{
1828 int i;
1829 int val, val1;
1830 s16 c1;
1831 s32 x1, d1;
1832 int32_t denom;
1833 int minCode_param[] = {
1834 3277, 1639, 820, 410, 205, 103, 52, 26
1835 };
1836
1837 regmap_update_bits(wcd9xxx->regmap, WCD9335_ANA_MBHC_ZDET, 0x20, 0x20);
1838 for (i = 0; i < TASHA_ZDET_NUM_MEASUREMENTS; i++) {
1839 regmap_read(wcd9xxx->regmap, WCD9335_ANA_MBHC_RESULT_2, &val);
1840 if (val & 0x80)
1841 break;
1842 }
1843 val = val << 0x8;
1844 regmap_read(wcd9xxx->regmap, WCD9335_ANA_MBHC_RESULT_1, &val1);
1845 val |= val1;
1846 regmap_update_bits(wcd9xxx->regmap, WCD9335_ANA_MBHC_ZDET, 0x20, 0x00);
1847 x1 = TASHA_MBHC_GET_X1(val);
1848 c1 = TASHA_MBHC_GET_C1(val);
1849 /* If ramp is not complete, give additional 5ms */
1850 if ((c1 < 2) && x1)
1851 usleep_range(5000, 5050);
1852
1853 if (!c1 || !x1) {
1854 dev_dbg(wcd9xxx->dev,
1855 "%s: Impedance detect ramp error, c1=%d, x1=0x%x\n",
1856 __func__, c1, x1);
1857 goto ramp_down;
1858 }
1859 d1 = d1_a[c1];
1860 denom = (x1 * d1) - (1 << (14 - noff));
1861 if (denom > 0)
1862 *zdet = (TASHA_MBHC_ZDET_CONST * 1000) / denom;
1863 else if (x1 < minCode_param[noff])
1864 *zdet = TASHA_ZDET_FLOATING_IMPEDANCE;
1865
1866 dev_dbg(wcd9xxx->dev, "%s: d1=%d, c1=%d, x1=0x%x, z_val=%d(milliOhm)\n",
1867 __func__, d1, c1, x1, *zdet);
1868ramp_down:
1869 i = 0;
1870 while (x1) {
1871 regmap_bulk_read(wcd9xxx->regmap,
1872 WCD9335_ANA_MBHC_RESULT_1, (u8 *)&val, 2);
1873 x1 = TASHA_MBHC_GET_X1(val);
1874 i++;
1875 if (i == TASHA_ZDET_NUM_MEASUREMENTS)
1876 break;
1877 }
1878}
1879
1880/*
1881 * tasha_mbhc_zdet_gpio_ctrl: Register callback function for
1882 * controlling the switch on hifi amps. Default switch state
1883 * will put a 51ohm load in parallel to the hph load. So,
1884 * impedance detection function will pull the gpio high
1885 * to make the switch open.
1886 *
1887 * @zdet_gpio_cb: callback function from machine driver
1888 * @codec: Codec instance
1889 *
1890 * Return: none
1891 */
1892void tasha_mbhc_zdet_gpio_ctrl(
1893 int (*zdet_gpio_cb)(struct snd_soc_codec *codec, bool high),
1894 struct snd_soc_codec *codec)
1895{
1896 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
1897
1898 tasha->zdet_gpio_cb = zdet_gpio_cb;
1899}
1900EXPORT_SYMBOL(tasha_mbhc_zdet_gpio_ctrl);
1901
1902static void tasha_mbhc_zdet_ramp(struct snd_soc_codec *codec,
1903 struct tasha_mbhc_zdet_param *zdet_param,
1904 int32_t *zl, int32_t *zr, s16 *d1_a)
1905{
1906 struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent);
1907 int32_t zdet = 0;
1908
1909 snd_soc_update_bits(codec, WCD9335_MBHC_ZDET_ANA_CTL, 0x70,
1910 zdet_param->ldo_ctl << 4);
1911 snd_soc_update_bits(codec, WCD9335_ANA_MBHC_BTN5, 0xFC,
1912 zdet_param->btn5);
1913 snd_soc_update_bits(codec, WCD9335_ANA_MBHC_BTN6, 0xFC,
1914 zdet_param->btn6);
1915 snd_soc_update_bits(codec, WCD9335_ANA_MBHC_BTN7, 0xFC,
1916 zdet_param->btn7);
1917 snd_soc_update_bits(codec, WCD9335_MBHC_ZDET_ANA_CTL, 0x0F,
1918 zdet_param->noff);
1919 snd_soc_update_bits(codec, WCD9335_MBHC_ZDET_RAMP_CTL, 0x0F,
1920 zdet_param->nshift);
1921
1922 if (!zl)
1923 goto z_right;
1924 /* Start impedance measurement for HPH_L */
1925 regmap_update_bits(wcd9xxx->regmap,
1926 WCD9335_ANA_MBHC_ZDET, 0x80, 0x80);
1927 dev_dbg(wcd9xxx->dev, "%s: ramp for HPH_L, noff = %d\n",
1928 __func__, zdet_param->noff);
1929 tasha_mbhc_get_result_params(wcd9xxx, d1_a, zdet_param->noff, &zdet);
1930 regmap_update_bits(wcd9xxx->regmap,
1931 WCD9335_ANA_MBHC_ZDET, 0x80, 0x00);
1932
1933 *zl = zdet;
1934
1935z_right:
1936 if (!zr)
1937 return;
1938 /* Start impedance measurement for HPH_R */
1939 regmap_update_bits(wcd9xxx->regmap,
1940 WCD9335_ANA_MBHC_ZDET, 0x40, 0x40);
1941 dev_dbg(wcd9xxx->dev, "%s: ramp for HPH_R, noff = %d\n",
1942 __func__, zdet_param->noff);
1943 tasha_mbhc_get_result_params(wcd9xxx, d1_a, zdet_param->noff, &zdet);
1944 regmap_update_bits(wcd9xxx->regmap,
1945 WCD9335_ANA_MBHC_ZDET, 0x40, 0x00);
1946
1947 *zr = zdet;
1948}
1949
1950static inline void tasha_wcd_mbhc_qfuse_cal(struct snd_soc_codec *codec,
1951 int32_t *z_val, int flag_l_r)
1952{
1953 s16 q1;
1954 int q1_cal;
1955
1956 if (*z_val < (TASHA_ZDET_VAL_400/1000))
1957 q1 = snd_soc_read(codec,
1958 WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT1 + (2 * flag_l_r));
1959 else
1960 q1 = snd_soc_read(codec,
1961 WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT2 + (2 * flag_l_r));
1962 if (q1 & 0x80)
1963 q1_cal = (10000 - ((q1 & 0x7F) * 25));
1964 else
1965 q1_cal = (10000 + (q1 * 25));
1966 if (q1_cal > 0)
1967 *z_val = ((*z_val) * 10000) / q1_cal;
1968}
1969
1970static void tasha_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl,
1971 uint32_t *zr)
1972{
1973 struct snd_soc_codec *codec = mbhc->codec;
1974 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
1975 struct wcd9xxx *wcd9xxx = tasha->wcd9xxx;
1976 s16 reg0, reg1, reg2, reg3, reg4;
1977 int32_t z1L, z1R, z1Ls;
1978 int zMono, z_diff1, z_diff2;
1979 bool is_fsm_disable = false;
1980 bool is_change = false;
1981 struct tasha_mbhc_zdet_param zdet_param[] = {
1982 {4, 0, 4, 0x08, 0x14, 0x18}, /* < 32ohm */
1983 {2, 0, 3, 0x18, 0x7C, 0x90}, /* 32ohm < Z < 400ohm */
1984 {1, 4, 5, 0x18, 0x7C, 0x90}, /* 400ohm < Z < 1200ohm */
1985 {1, 6, 7, 0x18, 0x7C, 0x90}, /* >1200ohm */
1986 };
1987 struct tasha_mbhc_zdet_param *zdet_param_ptr = NULL;
1988 s16 d1_a[][4] = {
1989 {0, 30, 90, 30},
1990 {0, 30, 30, 5},
1991 {0, 30, 30, 5},
1992 {0, 30, 30, 5},
1993 };
1994 s16 *d1 = NULL;
1995
1996 if (!TASHA_IS_2_0(wcd9xxx)) {
1997 dev_dbg(codec->dev, "%s: Z-det is not supported for this codec version\n",
1998 __func__);
1999 *zl = 0;
2000 *zr = 0;
2001 return;
2002 }
2003 WCD_MBHC_RSC_ASSERT_LOCKED(mbhc);
2004
2005 if (tasha->zdet_gpio_cb)
2006 is_change = tasha->zdet_gpio_cb(codec, true);
2007
2008 reg0 = snd_soc_read(codec, WCD9335_ANA_MBHC_BTN5);
2009 reg1 = snd_soc_read(codec, WCD9335_ANA_MBHC_BTN6);
2010 reg2 = snd_soc_read(codec, WCD9335_ANA_MBHC_BTN7);
2011 reg3 = snd_soc_read(codec, WCD9335_MBHC_CTL_1);
2012 reg4 = snd_soc_read(codec, WCD9335_MBHC_ZDET_ANA_CTL);
2013
2014 if (snd_soc_read(codec, WCD9335_ANA_MBHC_ELECT) & 0x80) {
2015 is_fsm_disable = true;
2016 regmap_update_bits(wcd9xxx->regmap,
2017 WCD9335_ANA_MBHC_ELECT, 0x80, 0x00);
2018 }
2019
2020 /* For NO-jack, disable L_DET_EN before Z-det measurements */
2021 if (mbhc->hphl_swh)
2022 regmap_update_bits(wcd9xxx->regmap,
2023 WCD9335_ANA_MBHC_MECH, 0x80, 0x00);
2024
2025 /* Enable AZ */
2026 snd_soc_update_bits(codec, WCD9335_MBHC_CTL_1, 0x0C, 0x04);
2027 /* Turn off 100k pull down on HPHL */
2028 regmap_update_bits(wcd9xxx->regmap,
2029 WCD9335_ANA_MBHC_MECH, 0x01, 0x00);
2030
2031 /* First get impedance on Left */
2032 d1 = d1_a[1];
2033 zdet_param_ptr = &zdet_param[1];
2034 tasha_mbhc_zdet_ramp(codec, zdet_param_ptr, &z1L, NULL, d1);
2035
2036 if (!TASHA_MBHC_IS_SECOND_RAMP_REQUIRED(z1L))
2037 goto left_ch_impedance;
2038
2039 /* second ramp for left ch */
2040 if (z1L < TASHA_ZDET_VAL_32) {
2041 zdet_param_ptr = &zdet_param[0];
2042 d1 = d1_a[0];
2043 } else if ((z1L > TASHA_ZDET_VAL_400) && (z1L <= TASHA_ZDET_VAL_1200)) {
2044 zdet_param_ptr = &zdet_param[2];
2045 d1 = d1_a[2];
2046 } else if (z1L > TASHA_ZDET_VAL_1200) {
2047 zdet_param_ptr = &zdet_param[3];
2048 d1 = d1_a[3];
2049 }
2050 tasha_mbhc_zdet_ramp(codec, zdet_param_ptr, &z1L, NULL, d1);
2051
2052left_ch_impedance:
2053 if ((z1L == TASHA_ZDET_FLOATING_IMPEDANCE) ||
2054 (z1L > TASHA_ZDET_VAL_100K)) {
2055 *zl = TASHA_ZDET_FLOATING_IMPEDANCE;
2056 zdet_param_ptr = &zdet_param[1];
2057 d1 = d1_a[1];
2058 } else {
2059 *zl = z1L/1000;
2060 tasha_wcd_mbhc_qfuse_cal(codec, zl, 0);
2061 }
2062 dev_dbg(codec->dev, "%s: impedance on HPH_L = %d(ohms)\n",
2063 __func__, *zl);
2064
2065 /* start of right impedance ramp and calculation */
2066 tasha_mbhc_zdet_ramp(codec, zdet_param_ptr, NULL, &z1R, d1);
2067 if (TASHA_MBHC_IS_SECOND_RAMP_REQUIRED(z1R)) {
2068 if (((z1R > TASHA_ZDET_VAL_1200) &&
2069 (zdet_param_ptr->noff == 0x6)) ||
2070 ((*zl) != TASHA_ZDET_FLOATING_IMPEDANCE))
2071 goto right_ch_impedance;
2072 /* second ramp for right ch */
2073 if (z1R < TASHA_ZDET_VAL_32) {
2074 zdet_param_ptr = &zdet_param[0];
2075 d1 = d1_a[0];
2076 } else if ((z1R > TASHA_ZDET_VAL_400) &&
2077 (z1R <= TASHA_ZDET_VAL_1200)) {
2078 zdet_param_ptr = &zdet_param[2];
2079 d1 = d1_a[2];
2080 } else if (z1R > TASHA_ZDET_VAL_1200) {
2081 zdet_param_ptr = &zdet_param[3];
2082 d1 = d1_a[3];
2083 }
2084 tasha_mbhc_zdet_ramp(codec, zdet_param_ptr, NULL, &z1R, d1);
2085 }
2086right_ch_impedance:
2087 if ((z1R == TASHA_ZDET_FLOATING_IMPEDANCE) ||
2088 (z1R > TASHA_ZDET_VAL_100K)) {
2089 *zr = TASHA_ZDET_FLOATING_IMPEDANCE;
2090 } else {
2091 *zr = z1R/1000;
2092 tasha_wcd_mbhc_qfuse_cal(codec, zr, 1);
2093 }
2094 dev_dbg(codec->dev, "%s: impedance on HPH_R = %d(ohms)\n",
2095 __func__, *zr);
2096
2097 /* mono/stereo detection */
2098 if ((*zl == TASHA_ZDET_FLOATING_IMPEDANCE) &&
2099 (*zr == TASHA_ZDET_FLOATING_IMPEDANCE)) {
2100 dev_dbg(codec->dev,
2101 "%s: plug type is invalid or extension cable\n",
2102 __func__);
2103 goto zdet_complete;
2104 }
2105 if ((*zl == TASHA_ZDET_FLOATING_IMPEDANCE) ||
2106 (*zr == TASHA_ZDET_FLOATING_IMPEDANCE) ||
2107 ((*zl < WCD_MONO_HS_MIN_THR) && (*zr > WCD_MONO_HS_MIN_THR)) ||
2108 ((*zl > WCD_MONO_HS_MIN_THR) && (*zr < WCD_MONO_HS_MIN_THR))) {
2109 dev_dbg(codec->dev,
2110 "%s: Mono plug type with one ch floating or shorted to GND\n",
2111 __func__);
2112 mbhc->hph_type = WCD_MBHC_HPH_MONO;
2113 goto zdet_complete;
2114 }
2115 snd_soc_update_bits(codec, WCD9335_HPH_R_ATEST, 0x02, 0x02);
2116 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x40, 0x01);
2117 if (*zl < (TASHA_ZDET_VAL_32/1000))
2118 tasha_mbhc_zdet_ramp(codec, &zdet_param[0], &z1Ls, NULL, d1);
2119 else
2120 tasha_mbhc_zdet_ramp(codec, &zdet_param[1], &z1Ls, NULL, d1);
2121 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x40, 0x00);
2122 snd_soc_update_bits(codec, WCD9335_HPH_R_ATEST, 0x02, 0x00);
2123 z1Ls /= 1000;
2124 tasha_wcd_mbhc_qfuse_cal(codec, &z1Ls, 0);
2125 /* parallel of left Z and 9 ohm pull down resistor */
2126 zMono = ((*zl) * 9) / ((*zl) + 9);
2127 z_diff1 = (z1Ls > zMono) ? (z1Ls - zMono) : (zMono - z1Ls);
2128 z_diff2 = ((*zl) > z1Ls) ? ((*zl) - z1Ls) : (z1Ls - (*zl));
2129 if ((z_diff1 * (*zl + z1Ls)) > (z_diff2 * (z1Ls + zMono))) {
2130 dev_dbg(codec->dev, "%s: stereo plug type detected\n",
2131 __func__);
2132 mbhc->hph_type = WCD_MBHC_HPH_STEREO;
2133 } else {
2134 dev_dbg(codec->dev, "%s: MONO plug type detected\n",
2135 __func__);
2136 mbhc->hph_type = WCD_MBHC_HPH_MONO;
2137 }
2138
2139zdet_complete:
2140 snd_soc_write(codec, WCD9335_ANA_MBHC_BTN5, reg0);
2141 snd_soc_write(codec, WCD9335_ANA_MBHC_BTN6, reg1);
2142 snd_soc_write(codec, WCD9335_ANA_MBHC_BTN7, reg2);
2143 /* Turn on 100k pull down on HPHL */
2144 regmap_update_bits(wcd9xxx->regmap,
2145 WCD9335_ANA_MBHC_MECH, 0x01, 0x01);
2146
2147 /* For NO-jack, re-enable L_DET_EN after Z-det measurements */
2148 if (mbhc->hphl_swh)
2149 regmap_update_bits(wcd9xxx->regmap,
2150 WCD9335_ANA_MBHC_MECH, 0x80, 0x80);
2151
2152 snd_soc_write(codec, WCD9335_MBHC_ZDET_ANA_CTL, reg4);
2153 snd_soc_write(codec, WCD9335_MBHC_CTL_1, reg3);
2154 if (is_fsm_disable)
2155 regmap_update_bits(wcd9xxx->regmap,
2156 WCD9335_ANA_MBHC_ELECT, 0x80, 0x80);
2157 if (tasha->zdet_gpio_cb && is_change)
2158 tasha->zdet_gpio_cb(codec, false);
2159}
2160
2161static void tasha_mbhc_gnd_det_ctrl(struct snd_soc_codec *codec, bool enable)
2162{
2163 if (enable) {
2164 snd_soc_update_bits(codec, WCD9335_ANA_MBHC_MECH,
2165 0x02, 0x02);
2166 snd_soc_update_bits(codec, WCD9335_ANA_MBHC_MECH,
2167 0x40, 0x40);
2168 } else {
2169 snd_soc_update_bits(codec, WCD9335_ANA_MBHC_MECH,
2170 0x40, 0x00);
2171 snd_soc_update_bits(codec, WCD9335_ANA_MBHC_MECH,
2172 0x02, 0x00);
2173 }
2174}
2175
2176static void tasha_mbhc_hph_pull_down_ctrl(struct snd_soc_codec *codec,
2177 bool enable)
2178{
2179 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
2180
2181 if (enable) {
2182 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2,
2183 0x40, 0x40);
2184 if (TASHA_IS_2_0(tasha->wcd9xxx))
2185 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2,
2186 0x10, 0x10);
2187 } else {
2188 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2,
2189 0x40, 0x00);
2190 if (TASHA_IS_2_0(tasha->wcd9xxx))
2191 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2,
2192 0x10, 0x00);
2193 }
2194}
2195
2196static void tasha_mbhc_moisture_config(struct wcd_mbhc *mbhc)
2197{
2198 struct snd_soc_codec *codec = mbhc->codec;
2199
2200 if (TASHA_MBHC_MOISTURE_VREF == V_OFF)
2201 return;
2202
2203 /* Donot enable moisture detection if jack type is NC */
2204 if (!mbhc->hphl_swh) {
2205 dev_dbg(codec->dev, "%s: disable moisture detection for NC\n",
2206 __func__);
2207 return;
2208 }
2209
2210 snd_soc_update_bits(codec, WCD9335_MBHC_CTL_2,
2211 0x0C, TASHA_MBHC_MOISTURE_VREF << 2);
2212 tasha_mbhc_hph_l_pull_up_control(codec, TASHA_MBHC_MOISTURE_IREF);
2213}
2214
2215static const struct wcd_mbhc_cb mbhc_cb = {
2216 .request_irq = tasha_mbhc_request_irq,
2217 .irq_control = tasha_mbhc_irq_control,
2218 .free_irq = tasha_mbhc_free_irq,
2219 .clk_setup = tasha_mbhc_clk_setup,
2220 .map_btn_code_to_num = tasha_mbhc_btn_to_num,
2221 .enable_mb_source = tasha_enable_ext_mb_source,
2222 .mbhc_bias = tasha_mbhc_mbhc_bias_control,
2223 .set_btn_thr = tasha_mbhc_program_btn_thr,
2224 .lock_sleep = tasha_mbhc_lock_sleep,
2225 .register_notifier = tasha_mbhc_register_notifier,
2226 .micbias_enable_status = tasha_mbhc_micb_en_status,
2227 .hph_pa_on_status = tasha_mbhc_hph_pa_on_status,
2228 .hph_pull_up_control = tasha_mbhc_hph_l_pull_up_control,
2229 .mbhc_micbias_control = tasha_mbhc_request_micbias,
2230 .mbhc_micb_ramp_control = tasha_mbhc_micb_ramp_control,
2231 .get_hwdep_fw_cal = tasha_get_hwdep_fw_cal,
2232 .mbhc_micb_ctrl_thr_mic = tasha_mbhc_micb_ctrl_threshold_mic,
2233 .compute_impedance = tasha_wcd_mbhc_calc_impedance,
2234 .mbhc_gnd_det_ctrl = tasha_mbhc_gnd_det_ctrl,
2235 .hph_pull_down_ctrl = tasha_mbhc_hph_pull_down_ctrl,
2236 .mbhc_moisture_config = tasha_mbhc_moisture_config,
2237};
2238
2239static int tasha_get_anc_slot(struct snd_kcontrol *kcontrol,
2240 struct snd_ctl_elem_value *ucontrol)
2241{
2242 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
2243 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
2244
2245 ucontrol->value.integer.value[0] = tasha->anc_slot;
2246 return 0;
2247}
2248
2249static int tasha_put_anc_slot(struct snd_kcontrol *kcontrol,
2250 struct snd_ctl_elem_value *ucontrol)
2251{
2252 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
2253 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
2254
2255 tasha->anc_slot = ucontrol->value.integer.value[0];
2256 return 0;
2257}
2258
2259static int tasha_get_anc_func(struct snd_kcontrol *kcontrol,
2260 struct snd_ctl_elem_value *ucontrol)
2261{
2262 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
2263 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
2264
2265 ucontrol->value.integer.value[0] = (tasha->anc_func == true ? 1 : 0);
2266 return 0;
2267}
2268
2269static int tasha_put_anc_func(struct snd_kcontrol *kcontrol,
2270 struct snd_ctl_elem_value *ucontrol)
2271{
2272 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
2273 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
2274 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
2275
2276 mutex_lock(&tasha->codec_mutex);
2277 tasha->anc_func = (!ucontrol->value.integer.value[0] ? false : true);
2278
2279 dev_dbg(codec->dev, "%s: anc_func %x", __func__, tasha->anc_func);
2280
2281 if (tasha->anc_func == true) {
2282 snd_soc_dapm_enable_pin(dapm, "ANC LINEOUT2 PA");
2283 snd_soc_dapm_enable_pin(dapm, "ANC LINEOUT2");
2284 snd_soc_dapm_enable_pin(dapm, "ANC LINEOUT1 PA");
2285 snd_soc_dapm_enable_pin(dapm, "ANC LINEOUT1");
2286 snd_soc_dapm_enable_pin(dapm, "ANC HPHR PA");
2287 snd_soc_dapm_enable_pin(dapm, "ANC HPHR");
2288 snd_soc_dapm_enable_pin(dapm, "ANC HPHL PA");
2289 snd_soc_dapm_enable_pin(dapm, "ANC HPHL");
2290 snd_soc_dapm_enable_pin(dapm, "ANC EAR PA");
2291 snd_soc_dapm_enable_pin(dapm, "ANC EAR");
2292 snd_soc_dapm_enable_pin(dapm, "ANC SPK1 PA");
2293 snd_soc_dapm_disable_pin(dapm, "LINEOUT2");
2294 snd_soc_dapm_disable_pin(dapm, "LINEOUT2 PA");
2295 snd_soc_dapm_disable_pin(dapm, "LINEOUT1");
2296 snd_soc_dapm_disable_pin(dapm, "LINEOUT1 PA");
2297 snd_soc_dapm_disable_pin(dapm, "HPHR");
2298 snd_soc_dapm_disable_pin(dapm, "HPHL");
2299 snd_soc_dapm_disable_pin(dapm, "HPHR PA");
2300 snd_soc_dapm_disable_pin(dapm, "HPHL PA");
2301 snd_soc_dapm_disable_pin(dapm, "EAR PA");
2302 snd_soc_dapm_disable_pin(dapm, "EAR");
2303 } else {
2304 snd_soc_dapm_disable_pin(dapm, "ANC LINEOUT2 PA");
2305 snd_soc_dapm_disable_pin(dapm, "ANC LINEOUT2");
2306 snd_soc_dapm_disable_pin(dapm, "ANC LINEOUT1 PA");
2307 snd_soc_dapm_disable_pin(dapm, "ANC LINEOUT1");
2308 snd_soc_dapm_disable_pin(dapm, "ANC HPHR");
2309 snd_soc_dapm_disable_pin(dapm, "ANC HPHL");
2310 snd_soc_dapm_disable_pin(dapm, "ANC HPHR PA");
2311 snd_soc_dapm_disable_pin(dapm, "ANC HPHL PA");
2312 snd_soc_dapm_disable_pin(dapm, "ANC EAR PA");
2313 snd_soc_dapm_disable_pin(dapm, "ANC EAR");
2314 snd_soc_dapm_disable_pin(dapm, "ANC SPK1 PA");
2315 snd_soc_dapm_enable_pin(dapm, "LINEOUT2");
2316 snd_soc_dapm_enable_pin(dapm, "LINEOUT2 PA");
2317 snd_soc_dapm_enable_pin(dapm, "LINEOUT1");
2318 snd_soc_dapm_enable_pin(dapm, "LINEOUT1 PA");
2319 snd_soc_dapm_enable_pin(dapm, "HPHR");
2320 snd_soc_dapm_enable_pin(dapm, "HPHL");
2321 snd_soc_dapm_enable_pin(dapm, "HPHR PA");
2322 snd_soc_dapm_enable_pin(dapm, "HPHL PA");
2323 snd_soc_dapm_enable_pin(dapm, "EAR PA");
2324 snd_soc_dapm_enable_pin(dapm, "EAR");
2325 }
2326 mutex_unlock(&tasha->codec_mutex);
2327 snd_soc_dapm_sync(dapm);
2328 return 0;
2329}
2330
2331static int tasha_get_clkmode(struct snd_kcontrol *kcontrol,
2332 struct snd_ctl_elem_value *ucontrol)
2333{
2334 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
2335 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
2336
2337 ucontrol->value.enumerated.item[0] = tasha->clk_mode;
2338 dev_dbg(codec->dev, "%s: clk_mode: %d\n", __func__, tasha->clk_mode);
2339
2340 return 0;
2341}
2342
2343static int tasha_put_clkmode(struct snd_kcontrol *kcontrol,
2344 struct snd_ctl_elem_value *ucontrol)
2345{
2346 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
2347 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
2348
2349 tasha->clk_mode = ucontrol->value.enumerated.item[0];
2350 dev_dbg(codec->dev, "%s: clk_mode: %d\n", __func__, tasha->clk_mode);
2351
2352 return 0;
2353}
2354
2355static int tasha_get_iir_enable_audio_mixer(
2356 struct snd_kcontrol *kcontrol,
2357 struct snd_ctl_elem_value *ucontrol)
2358{
2359 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
2360 int iir_idx = ((struct soc_multi_mixer_control *)
2361 kcontrol->private_value)->reg;
2362 int band_idx = ((struct soc_multi_mixer_control *)
2363 kcontrol->private_value)->shift;
2364 /* IIR filter band registers are at integer multiples of 16 */
2365 u16 iir_reg = WCD9335_CDC_SIDETONE_IIR0_IIR_CTL + 16 * iir_idx;
2366
2367 ucontrol->value.integer.value[0] = (snd_soc_read(codec, iir_reg) &
2368 (1 << band_idx)) != 0;
2369
2370 dev_dbg(codec->dev, "%s: IIR #%d band #%d enable %d\n", __func__,
2371 iir_idx, band_idx,
2372 (uint32_t)ucontrol->value.integer.value[0]);
2373 return 0;
2374}
2375
2376static int tasha_hph_impedance_get(struct snd_kcontrol *kcontrol,
2377 struct snd_ctl_elem_value *ucontrol)
2378{
2379 uint32_t zl, zr;
2380 bool hphr;
2381 struct soc_multi_mixer_control *mc;
2382 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
2383 struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec);
2384
2385 mc = (struct soc_multi_mixer_control *)(kcontrol->private_value);
2386 hphr = mc->shift;
2387 wcd_mbhc_get_impedance(&priv->mbhc, &zl, &zr);
2388 dev_dbg(codec->dev, "%s: zl=%u(ohms), zr=%u(ohms)\n", __func__, zl, zr);
2389 ucontrol->value.integer.value[0] = hphr ? zr : zl;
2390
2391 return 0;
2392}
2393
2394static const struct snd_kcontrol_new impedance_detect_controls[] = {
2395 SOC_SINGLE_EXT("HPHL Impedance", 0, 0, UINT_MAX, 0,
2396 tasha_hph_impedance_get, NULL),
2397 SOC_SINGLE_EXT("HPHR Impedance", 0, 1, UINT_MAX, 0,
2398 tasha_hph_impedance_get, NULL),
2399};
2400
2401static int tasha_get_hph_type(struct snd_kcontrol *kcontrol,
2402 struct snd_ctl_elem_value *ucontrol)
2403{
2404 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
2405 struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec);
2406 struct wcd_mbhc *mbhc;
2407
2408 if (!priv) {
2409 dev_dbg(codec->dev, "%s: wcd9335 private data is NULL\n",
2410 __func__);
2411 return 0;
2412 }
2413
2414 mbhc = &priv->mbhc;
2415 if (!mbhc) {
2416 dev_dbg(codec->dev, "%s: mbhc not initialized\n", __func__);
2417 return 0;
2418 }
2419
2420 ucontrol->value.integer.value[0] = (u32) mbhc->hph_type;
2421 dev_dbg(codec->dev, "%s: hph_type = %u\n", __func__, mbhc->hph_type);
2422
2423 return 0;
2424}
2425
2426static const struct snd_kcontrol_new hph_type_detect_controls[] = {
2427 SOC_SINGLE_EXT("HPH Type", 0, 0, UINT_MAX, 0,
2428 tasha_get_hph_type, NULL),
2429};
2430
2431static int tasha_vi_feed_mixer_get(struct snd_kcontrol *kcontrol,
2432 struct snd_ctl_elem_value *ucontrol)
2433{
2434 struct snd_soc_dapm_widget_list *wlist =
2435 dapm_kcontrol_get_wlist(kcontrol);
2436 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2437 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
2438 struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec);
2439
2440 ucontrol->value.integer.value[0] = tasha_p->vi_feed_value;
2441
2442 return 0;
2443}
2444
2445static int tasha_vi_feed_mixer_put(struct snd_kcontrol *kcontrol,
2446 struct snd_ctl_elem_value *ucontrol)
2447{
2448 struct snd_soc_dapm_widget_list *wlist =
2449 dapm_kcontrol_get_wlist(kcontrol);
2450 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2451 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
2452 struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec);
2453 struct wcd9xxx *core = tasha_p->wcd9xxx;
2454 struct soc_multi_mixer_control *mixer =
2455 ((struct soc_multi_mixer_control *)kcontrol->private_value);
2456 u32 dai_id = widget->shift;
2457 u32 port_id = mixer->shift;
2458 u32 enable = ucontrol->value.integer.value[0];
2459
2460 dev_dbg(codec->dev, "%s: enable: %d, port_id:%d, dai_id: %d\n",
2461 __func__, enable, port_id, dai_id);
2462
2463 tasha_p->vi_feed_value = ucontrol->value.integer.value[0];
2464
2465 mutex_lock(&tasha_p->codec_mutex);
2466 if (enable) {
2467 if (port_id == TASHA_TX14 && !test_bit(VI_SENSE_1,
2468 &tasha_p->status_mask)) {
2469 list_add_tail(&core->tx_chs[TASHA_TX14].list,
2470 &tasha_p->dai[dai_id].wcd9xxx_ch_list);
2471 set_bit(VI_SENSE_1, &tasha_p->status_mask);
2472 }
2473 if (port_id == TASHA_TX15 && !test_bit(VI_SENSE_2,
2474 &tasha_p->status_mask)) {
2475 list_add_tail(&core->tx_chs[TASHA_TX15].list,
2476 &tasha_p->dai[dai_id].wcd9xxx_ch_list);
2477 set_bit(VI_SENSE_2, &tasha_p->status_mask);
2478 }
2479 } else {
2480 if (port_id == TASHA_TX14 && test_bit(VI_SENSE_1,
2481 &tasha_p->status_mask)) {
2482 list_del_init(&core->tx_chs[TASHA_TX14].list);
2483 clear_bit(VI_SENSE_1, &tasha_p->status_mask);
2484 }
2485 if (port_id == TASHA_TX15 && test_bit(VI_SENSE_2,
2486 &tasha_p->status_mask)) {
2487 list_del_init(&core->tx_chs[TASHA_TX15].list);
2488 clear_bit(VI_SENSE_2, &tasha_p->status_mask);
2489 }
2490 }
2491 mutex_unlock(&tasha_p->codec_mutex);
2492 snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, NULL);
2493
2494 return 0;
2495}
2496
2497/* virtual port entries */
2498static int slim_tx_mixer_get(struct snd_kcontrol *kcontrol,
2499 struct snd_ctl_elem_value *ucontrol)
2500{
2501 struct snd_soc_dapm_widget_list *wlist =
2502 dapm_kcontrol_get_wlist(kcontrol);
2503 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2504 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
2505 struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec);
2506
2507 ucontrol->value.integer.value[0] = tasha_p->tx_port_value;
2508 return 0;
2509}
2510
2511static int slim_tx_mixer_put(struct snd_kcontrol *kcontrol,
2512 struct snd_ctl_elem_value *ucontrol)
2513{
2514 struct snd_soc_dapm_widget_list *wlist =
2515 dapm_kcontrol_get_wlist(kcontrol);
2516 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2517 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
2518 struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec);
2519 struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent);
2520 struct snd_soc_dapm_update *update = NULL;
2521 struct soc_multi_mixer_control *mixer =
2522 ((struct soc_multi_mixer_control *)kcontrol->private_value);
2523 u32 dai_id = widget->shift;
2524 u32 port_id = mixer->shift;
2525 u32 enable = ucontrol->value.integer.value[0];
2526 u32 vtable;
2527
2528
2529 dev_dbg(codec->dev, "%s: wname %s cname %s value %u shift %d item %ld\n",
2530 __func__,
2531 widget->name, ucontrol->id.name, tasha_p->tx_port_value,
2532 widget->shift, ucontrol->value.integer.value[0]);
2533
2534 mutex_lock(&tasha_p->codec_mutex);
2535
2536 if (tasha_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
2537 if (dai_id != AIF1_CAP) {
2538 dev_err(codec->dev, "%s: invalid AIF for I2C mode\n",
2539 __func__);
2540 mutex_unlock(&tasha_p->codec_mutex);
2541 return -EINVAL;
2542 }
2543 vtable = vport_slim_check_table[dai_id];
2544 } else {
2545 if (dai_id >= ARRAY_SIZE(vport_i2s_check_table)) {
2546 dev_err(codec->dev, "%s: dai_id: %d, out of bounds\n",
2547 __func__, dai_id);
2548 return -EINVAL;
2549 }
2550 vtable = vport_i2s_check_table[dai_id];
2551 }
2552 switch (dai_id) {
2553 case AIF1_CAP:
2554 case AIF2_CAP:
2555 case AIF3_CAP:
2556 /* only add to the list if value not set */
2557 if (enable && !(tasha_p->tx_port_value & 1 << port_id)) {
2558
2559 if (wcd9xxx_tx_vport_validation(vtable, port_id,
2560 tasha_p->dai, NUM_CODEC_DAIS)) {
2561 dev_dbg(codec->dev, "%s: TX%u is used by other virtual port\n",
2562 __func__, port_id);
2563 mutex_unlock(&tasha_p->codec_mutex);
2564 return 0;
2565 }
2566 tasha_p->tx_port_value |= 1 << port_id;
2567 list_add_tail(&core->tx_chs[port_id].list,
2568 &tasha_p->dai[dai_id].wcd9xxx_ch_list
2569 );
2570 } else if (!enable && (tasha_p->tx_port_value &
2571 1 << port_id)) {
2572 tasha_p->tx_port_value &= ~(1 << port_id);
2573 list_del_init(&core->tx_chs[port_id].list);
2574 } else {
2575 if (enable)
2576 dev_dbg(codec->dev, "%s: TX%u port is used by\n"
2577 "this virtual port\n",
2578 __func__, port_id);
2579 else
2580 dev_dbg(codec->dev, "%s: TX%u port is not used by\n"
2581 "this virtual port\n",
2582 __func__, port_id);
2583 /* avoid update power function */
2584 mutex_unlock(&tasha_p->codec_mutex);
2585 return 0;
2586 }
2587 break;
2588 case AIF4_MAD_TX:
2589 case AIF5_CPE_TX:
2590 break;
2591 default:
2592 pr_err("Unknown AIF %d\n", dai_id);
2593 mutex_unlock(&tasha_p->codec_mutex);
2594 return -EINVAL;
2595 }
2596 pr_debug("%s: name %s sname %s updated value %u shift %d\n", __func__,
2597 widget->name, widget->sname, tasha_p->tx_port_value,
2598 widget->shift);
2599
2600 mutex_unlock(&tasha_p->codec_mutex);
2601 snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, update);
2602
2603 return 0;
2604}
2605
2606static int slim_rx_mux_get(struct snd_kcontrol *kcontrol,
2607 struct snd_ctl_elem_value *ucontrol)
2608{
2609 struct snd_soc_dapm_widget_list *wlist =
2610 dapm_kcontrol_get_wlist(kcontrol);
2611 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2612 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
2613 struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec);
2614
2615 ucontrol->value.enumerated.item[0] =
2616 tasha_p->rx_port_value[widget->shift];
2617 return 0;
2618}
2619
2620static const char *const slim_rx_mux_text[] = {
2621 "ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB", "AIF4_PB", "AIF_MIX1_PB"
2622};
2623
2624static int slim_rx_mux_put(struct snd_kcontrol *kcontrol,
2625 struct snd_ctl_elem_value *ucontrol)
2626{
2627 struct snd_soc_dapm_widget_list *wlist =
2628 dapm_kcontrol_get_wlist(kcontrol);
2629 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2630 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
2631 struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec);
2632 struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent);
2633 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
2634 struct snd_soc_dapm_update *update = NULL;
2635 unsigned int rx_port_value;
2636 u32 port_id = widget->shift;
2637
2638 tasha_p->rx_port_value[port_id] = ucontrol->value.enumerated.item[0];
2639 rx_port_value = tasha_p->rx_port_value[port_id];
2640
2641 pr_debug("%s: wname %s cname %s value %u shift %d item %ld\n", __func__,
2642 widget->name, ucontrol->id.name, rx_port_value,
2643 widget->shift, ucontrol->value.integer.value[0]);
2644
2645 mutex_lock(&tasha_p->codec_mutex);
2646
2647 if (tasha_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
2648 if (rx_port_value > 2) {
2649 dev_err(codec->dev, "%s: invalid AIF for I2C mode\n",
2650 __func__);
2651 goto err;
2652 }
2653 }
2654 /* value need to match the Virtual port and AIF number */
2655 switch (rx_port_value) {
2656 case 0:
2657 list_del_init(&core->rx_chs[port_id].list);
2658 break;
2659 case 1:
2660 if (wcd9xxx_rx_vport_validation(port_id +
2661 TASHA_RX_PORT_START_NUMBER,
2662 &tasha_p->dai[AIF1_PB].wcd9xxx_ch_list)) {
2663 dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n",
2664 __func__, port_id);
2665 goto rtn;
2666 }
2667 list_add_tail(&core->rx_chs[port_id].list,
2668 &tasha_p->dai[AIF1_PB].wcd9xxx_ch_list);
2669 break;
2670 case 2:
2671 if (wcd9xxx_rx_vport_validation(port_id +
2672 TASHA_RX_PORT_START_NUMBER,
2673 &tasha_p->dai[AIF2_PB].wcd9xxx_ch_list)) {
2674 dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n",
2675 __func__, port_id);
2676 goto rtn;
2677 }
2678 list_add_tail(&core->rx_chs[port_id].list,
2679 &tasha_p->dai[AIF2_PB].wcd9xxx_ch_list);
2680 break;
2681 case 3:
2682 if (wcd9xxx_rx_vport_validation(port_id +
2683 TASHA_RX_PORT_START_NUMBER,
2684 &tasha_p->dai[AIF3_PB].wcd9xxx_ch_list)) {
2685 dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n",
2686 __func__, port_id);
2687 goto rtn;
2688 }
2689 list_add_tail(&core->rx_chs[port_id].list,
2690 &tasha_p->dai[AIF3_PB].wcd9xxx_ch_list);
2691 break;
2692 case 4:
2693 if (wcd9xxx_rx_vport_validation(port_id +
2694 TASHA_RX_PORT_START_NUMBER,
2695 &tasha_p->dai[AIF4_PB].wcd9xxx_ch_list)) {
2696 dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n",
2697 __func__, port_id);
2698 goto rtn;
2699 }
2700 list_add_tail(&core->rx_chs[port_id].list,
2701 &tasha_p->dai[AIF4_PB].wcd9xxx_ch_list);
2702 break;
2703 case 5:
2704 if (wcd9xxx_rx_vport_validation(port_id +
2705 TASHA_RX_PORT_START_NUMBER,
2706 &tasha_p->dai[AIF_MIX1_PB].wcd9xxx_ch_list)) {
2707 dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n",
2708 __func__, port_id);
2709 goto rtn;
2710 }
2711 list_add_tail(&core->rx_chs[port_id].list,
2712 &tasha_p->dai[AIF_MIX1_PB].wcd9xxx_ch_list);
2713 break;
2714 default:
2715 pr_err("Unknown AIF %d\n", rx_port_value);
2716 goto err;
2717 }
2718rtn:
2719 mutex_unlock(&tasha_p->codec_mutex);
2720 snd_soc_dapm_mux_update_power(widget->dapm, kcontrol,
2721 rx_port_value, e, update);
2722
2723 return 0;
2724err:
2725 mutex_unlock(&tasha_p->codec_mutex);
2726 return -EINVAL;
2727}
2728
2729static const struct soc_enum slim_rx_mux_enum =
2730 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(slim_rx_mux_text), slim_rx_mux_text);
2731
2732static const struct snd_kcontrol_new slim_rx_mux[TASHA_RX_MAX] = {
2733 SOC_DAPM_ENUM_EXT("SLIM RX0 Mux", slim_rx_mux_enum,
2734 slim_rx_mux_get, slim_rx_mux_put),
2735 SOC_DAPM_ENUM_EXT("SLIM RX1 Mux", slim_rx_mux_enum,
2736 slim_rx_mux_get, slim_rx_mux_put),
2737 SOC_DAPM_ENUM_EXT("SLIM RX2 Mux", slim_rx_mux_enum,
2738 slim_rx_mux_get, slim_rx_mux_put),
2739 SOC_DAPM_ENUM_EXT("SLIM RX3 Mux", slim_rx_mux_enum,
2740 slim_rx_mux_get, slim_rx_mux_put),
2741 SOC_DAPM_ENUM_EXT("SLIM RX4 Mux", slim_rx_mux_enum,
2742 slim_rx_mux_get, slim_rx_mux_put),
2743 SOC_DAPM_ENUM_EXT("SLIM RX5 Mux", slim_rx_mux_enum,
2744 slim_rx_mux_get, slim_rx_mux_put),
2745 SOC_DAPM_ENUM_EXT("SLIM RX6 Mux", slim_rx_mux_enum,
2746 slim_rx_mux_get, slim_rx_mux_put),
2747 SOC_DAPM_ENUM_EXT("SLIM RX7 Mux", slim_rx_mux_enum,
2748 slim_rx_mux_get, slim_rx_mux_put),
2749};
2750
2751static const struct snd_kcontrol_new aif4_vi_mixer[] = {
2752 SOC_SINGLE_EXT("SPKR_VI_1", SND_SOC_NOPM, TASHA_TX14, 1, 0,
2753 tasha_vi_feed_mixer_get, tasha_vi_feed_mixer_put),
2754 SOC_SINGLE_EXT("SPKR_VI_2", SND_SOC_NOPM, TASHA_TX15, 1, 0,
2755 tasha_vi_feed_mixer_get, tasha_vi_feed_mixer_put),
2756};
2757
2758static const struct snd_kcontrol_new aif1_cap_mixer[] = {
2759 SOC_SINGLE_EXT("SLIM TX0", SND_SOC_NOPM, TASHA_TX0, 1, 0,
2760 slim_tx_mixer_get, slim_tx_mixer_put),
2761 SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, TASHA_TX1, 1, 0,
2762 slim_tx_mixer_get, slim_tx_mixer_put),
2763 SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, TASHA_TX2, 1, 0,
2764 slim_tx_mixer_get, slim_tx_mixer_put),
2765 SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, TASHA_TX3, 1, 0,
2766 slim_tx_mixer_get, slim_tx_mixer_put),
2767 SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, TASHA_TX4, 1, 0,
2768 slim_tx_mixer_get, slim_tx_mixer_put),
2769 SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, TASHA_TX5, 1, 0,
2770 slim_tx_mixer_get, slim_tx_mixer_put),
2771 SOC_SINGLE_EXT("SLIM TX6", SND_SOC_NOPM, TASHA_TX6, 1, 0,
2772 slim_tx_mixer_get, slim_tx_mixer_put),
2773 SOC_SINGLE_EXT("SLIM TX7", SND_SOC_NOPM, TASHA_TX7, 1, 0,
2774 slim_tx_mixer_get, slim_tx_mixer_put),
2775 SOC_SINGLE_EXT("SLIM TX8", SND_SOC_NOPM, TASHA_TX8, 1, 0,
2776 slim_tx_mixer_get, slim_tx_mixer_put),
2777 SOC_SINGLE_EXT("SLIM TX9", SND_SOC_NOPM, TASHA_TX9, 1, 0,
2778 slim_tx_mixer_get, slim_tx_mixer_put),
2779 SOC_SINGLE_EXT("SLIM TX10", SND_SOC_NOPM, TASHA_TX10, 1, 0,
2780 slim_tx_mixer_get, slim_tx_mixer_put),
2781 SOC_SINGLE_EXT("SLIM TX11", SND_SOC_NOPM, TASHA_TX11, 1, 0,
2782 slim_tx_mixer_get, slim_tx_mixer_put),
2783 SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, TASHA_TX13, 1, 0,
2784 slim_tx_mixer_get, slim_tx_mixer_put),
2785};
2786
2787static const struct snd_kcontrol_new aif2_cap_mixer[] = {
2788 SOC_SINGLE_EXT("SLIM TX0", SND_SOC_NOPM, TASHA_TX0, 1, 0,
2789 slim_tx_mixer_get, slim_tx_mixer_put),
2790 SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, TASHA_TX1, 1, 0,
2791 slim_tx_mixer_get, slim_tx_mixer_put),
2792 SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, TASHA_TX2, 1, 0,
2793 slim_tx_mixer_get, slim_tx_mixer_put),
2794 SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, TASHA_TX3, 1, 0,
2795 slim_tx_mixer_get, slim_tx_mixer_put),
2796 SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, TASHA_TX4, 1, 0,
2797 slim_tx_mixer_get, slim_tx_mixer_put),
2798 SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, TASHA_TX5, 1, 0,
2799 slim_tx_mixer_get, slim_tx_mixer_put),
2800 SOC_SINGLE_EXT("SLIM TX6", SND_SOC_NOPM, TASHA_TX6, 1, 0,
2801 slim_tx_mixer_get, slim_tx_mixer_put),
2802 SOC_SINGLE_EXT("SLIM TX7", SND_SOC_NOPM, TASHA_TX7, 1, 0,
2803 slim_tx_mixer_get, slim_tx_mixer_put),
2804 SOC_SINGLE_EXT("SLIM TX8", SND_SOC_NOPM, TASHA_TX8, 1, 0,
2805 slim_tx_mixer_get, slim_tx_mixer_put),
2806 SOC_SINGLE_EXT("SLIM TX9", SND_SOC_NOPM, TASHA_TX9, 1, 0,
2807 slim_tx_mixer_get, slim_tx_mixer_put),
2808 SOC_SINGLE_EXT("SLIM TX10", SND_SOC_NOPM, TASHA_TX10, 1, 0,
2809 slim_tx_mixer_get, slim_tx_mixer_put),
2810 SOC_SINGLE_EXT("SLIM TX11", SND_SOC_NOPM, TASHA_TX11, 1, 0,
2811 slim_tx_mixer_get, slim_tx_mixer_put),
2812 SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, TASHA_TX13, 1, 0,
2813 slim_tx_mixer_get, slim_tx_mixer_put),
2814};
2815
2816static const struct snd_kcontrol_new aif3_cap_mixer[] = {
2817 SOC_SINGLE_EXT("SLIM TX0", SND_SOC_NOPM, TASHA_TX0, 1, 0,
2818 slim_tx_mixer_get, slim_tx_mixer_put),
2819 SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, TASHA_TX1, 1, 0,
2820 slim_tx_mixer_get, slim_tx_mixer_put),
2821 SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, TASHA_TX2, 1, 0,
2822 slim_tx_mixer_get, slim_tx_mixer_put),
2823 SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, TASHA_TX3, 1, 0,
2824 slim_tx_mixer_get, slim_tx_mixer_put),
2825 SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, TASHA_TX4, 1, 0,
2826 slim_tx_mixer_get, slim_tx_mixer_put),
2827 SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, TASHA_TX5, 1, 0,
2828 slim_tx_mixer_get, slim_tx_mixer_put),
2829 SOC_SINGLE_EXT("SLIM TX6", SND_SOC_NOPM, TASHA_TX6, 1, 0,
2830 slim_tx_mixer_get, slim_tx_mixer_put),
2831 SOC_SINGLE_EXT("SLIM TX7", SND_SOC_NOPM, TASHA_TX7, 1, 0,
2832 slim_tx_mixer_get, slim_tx_mixer_put),
2833 SOC_SINGLE_EXT("SLIM TX8", SND_SOC_NOPM, TASHA_TX8, 1, 0,
2834 slim_tx_mixer_get, slim_tx_mixer_put),
2835 SOC_SINGLE_EXT("SLIM TX9", SND_SOC_NOPM, TASHA_TX9, 1, 0,
2836 slim_tx_mixer_get, slim_tx_mixer_put),
2837 SOC_SINGLE_EXT("SLIM TX10", SND_SOC_NOPM, TASHA_TX10, 1, 0,
2838 slim_tx_mixer_get, slim_tx_mixer_put),
2839 SOC_SINGLE_EXT("SLIM TX11", SND_SOC_NOPM, TASHA_TX11, 1, 0,
2840 slim_tx_mixer_get, slim_tx_mixer_put),
2841 SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, TASHA_TX13, 1, 0,
2842 slim_tx_mixer_get, slim_tx_mixer_put),
2843};
2844
2845static const struct snd_kcontrol_new aif4_mad_mixer[] = {
2846 SOC_SINGLE_EXT("SLIM TX12", SND_SOC_NOPM, TASHA_TX12, 1, 0,
2847 slim_tx_mixer_get, slim_tx_mixer_put),
2848 SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, TASHA_TX13, 1, 0,
2849 slim_tx_mixer_get, slim_tx_mixer_put),
2850 SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, 0, 1, 0,
2851 slim_tx_mixer_get, slim_tx_mixer_put),
2852
2853};
2854
2855static const struct snd_kcontrol_new rx_int1_spline_mix_switch[] = {
2856 SOC_DAPM_SINGLE("HPHL Switch", SND_SOC_NOPM, 0, 1, 0)
2857};
2858
2859static const struct snd_kcontrol_new rx_int2_spline_mix_switch[] = {
2860 SOC_DAPM_SINGLE("HPHR Switch", SND_SOC_NOPM, 0, 1, 0)
2861};
2862
2863static const struct snd_kcontrol_new rx_int3_spline_mix_switch[] = {
2864 SOC_DAPM_SINGLE("LO1 Switch", SND_SOC_NOPM, 0, 1, 0)
2865};
2866
2867static const struct snd_kcontrol_new rx_int4_spline_mix_switch[] = {
2868 SOC_DAPM_SINGLE("LO2 Switch", SND_SOC_NOPM, 0, 1, 0)
2869};
2870
2871static const struct snd_kcontrol_new rx_int5_spline_mix_switch[] = {
2872 SOC_DAPM_SINGLE("LO3 Switch", SND_SOC_NOPM, 0, 1, 0)
2873};
2874
2875static const struct snd_kcontrol_new rx_int6_spline_mix_switch[] = {
2876 SOC_DAPM_SINGLE("LO4 Switch", SND_SOC_NOPM, 0, 1, 0)
2877};
2878
2879static const struct snd_kcontrol_new rx_int7_spline_mix_switch[] = {
2880 SOC_DAPM_SINGLE("SPKRL Switch", SND_SOC_NOPM, 0, 1, 0)
2881};
2882
2883static const struct snd_kcontrol_new rx_int8_spline_mix_switch[] = {
2884 SOC_DAPM_SINGLE("SPKRR Switch", SND_SOC_NOPM, 0, 1, 0)
2885};
2886
2887static const struct snd_kcontrol_new rx_int5_vbat_mix_switch[] = {
2888 SOC_DAPM_SINGLE("LO3 VBAT Enable", SND_SOC_NOPM, 0, 1, 0)
2889};
2890
2891static const struct snd_kcontrol_new rx_int6_vbat_mix_switch[] = {
2892 SOC_DAPM_SINGLE("LO4 VBAT Enable", SND_SOC_NOPM, 0, 1, 0)
2893};
2894
2895static const struct snd_kcontrol_new rx_int7_vbat_mix_switch[] = {
2896 SOC_DAPM_SINGLE("SPKRL VBAT Enable", SND_SOC_NOPM, 0, 1, 0)
2897};
2898
2899static const struct snd_kcontrol_new rx_int8_vbat_mix_switch[] = {
2900 SOC_DAPM_SINGLE("SPKRR VBAT Enable", SND_SOC_NOPM, 0, 1, 0)
2901};
2902
2903static const struct snd_kcontrol_new cpe_in_mix_switch[] = {
2904 SOC_DAPM_SINGLE("MAD_BYPASS", SND_SOC_NOPM, 0, 1, 0)
2905};
2906
2907
2908
2909static int tasha_put_iir_enable_audio_mixer(
2910 struct snd_kcontrol *kcontrol,
2911 struct snd_ctl_elem_value *ucontrol)
2912{
2913 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
2914 int iir_idx = ((struct soc_multi_mixer_control *)
2915 kcontrol->private_value)->reg;
2916 int band_idx = ((struct soc_multi_mixer_control *)
2917 kcontrol->private_value)->shift;
2918 bool iir_band_en_status;
2919 int value = ucontrol->value.integer.value[0];
2920 u16 iir_reg = WCD9335_CDC_SIDETONE_IIR0_IIR_CTL + 16 * iir_idx;
2921
2922 /* Mask first 5 bits, 6-8 are reserved */
2923 snd_soc_update_bits(codec, iir_reg, (1 << band_idx),
2924 (value << band_idx));
2925
2926 iir_band_en_status = ((snd_soc_read(codec, iir_reg) &
2927 (1 << band_idx)) != 0);
2928 pr_debug("%s: IIR #%d band #%d enable %d\n", __func__,
2929 iir_idx, band_idx, iir_band_en_status);
2930 return 0;
2931}
2932
2933static uint32_t get_iir_band_coeff(struct snd_soc_codec *codec,
2934 int iir_idx, int band_idx,
2935 int coeff_idx)
2936{
2937 uint32_t value = 0;
2938
2939 /* Address does not automatically update if reading */
2940 snd_soc_write(codec,
2941 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx),
2942 ((band_idx * BAND_MAX + coeff_idx)
2943 * sizeof(uint32_t)) & 0x7F);
2944
2945 value |= snd_soc_read(codec,
2946 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx));
2947
2948 snd_soc_write(codec,
2949 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx),
2950 ((band_idx * BAND_MAX + coeff_idx)
2951 * sizeof(uint32_t) + 1) & 0x7F);
2952
2953 value |= (snd_soc_read(codec,
2954 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL +
2955 16 * iir_idx)) << 8);
2956
2957 snd_soc_write(codec,
2958 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx),
2959 ((band_idx * BAND_MAX + coeff_idx)
2960 * sizeof(uint32_t) + 2) & 0x7F);
2961
2962 value |= (snd_soc_read(codec,
2963 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL +
2964 16 * iir_idx)) << 16);
2965
2966 snd_soc_write(codec,
2967 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx),
2968 ((band_idx * BAND_MAX + coeff_idx)
2969 * sizeof(uint32_t) + 3) & 0x7F);
2970
2971 /* Mask bits top 2 bits since they are reserved */
2972 value |= ((snd_soc_read(codec,
2973 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL +
2974 16 * iir_idx)) & 0x3F) << 24);
2975
2976 return value;
2977}
2978
2979static int tasha_get_iir_band_audio_mixer(
2980 struct snd_kcontrol *kcontrol,
2981 struct snd_ctl_elem_value *ucontrol)
2982{
2983 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
2984 int iir_idx = ((struct soc_multi_mixer_control *)
2985 kcontrol->private_value)->reg;
2986 int band_idx = ((struct soc_multi_mixer_control *)
2987 kcontrol->private_value)->shift;
2988
2989 ucontrol->value.integer.value[0] =
2990 get_iir_band_coeff(codec, iir_idx, band_idx, 0);
2991 ucontrol->value.integer.value[1] =
2992 get_iir_band_coeff(codec, iir_idx, band_idx, 1);
2993 ucontrol->value.integer.value[2] =
2994 get_iir_band_coeff(codec, iir_idx, band_idx, 2);
2995 ucontrol->value.integer.value[3] =
2996 get_iir_band_coeff(codec, iir_idx, band_idx, 3);
2997 ucontrol->value.integer.value[4] =
2998 get_iir_band_coeff(codec, iir_idx, band_idx, 4);
2999
3000 pr_debug("%s: IIR #%d band #%d b0 = 0x%x\n"
3001 "%s: IIR #%d band #%d b1 = 0x%x\n"
3002 "%s: IIR #%d band #%d b2 = 0x%x\n"
3003 "%s: IIR #%d band #%d a1 = 0x%x\n"
3004 "%s: IIR #%d band #%d a2 = 0x%x\n",
3005 __func__, iir_idx, band_idx,
3006 (uint32_t)ucontrol->value.integer.value[0],
3007 __func__, iir_idx, band_idx,
3008 (uint32_t)ucontrol->value.integer.value[1],
3009 __func__, iir_idx, band_idx,
3010 (uint32_t)ucontrol->value.integer.value[2],
3011 __func__, iir_idx, band_idx,
3012 (uint32_t)ucontrol->value.integer.value[3],
3013 __func__, iir_idx, band_idx,
3014 (uint32_t)ucontrol->value.integer.value[4]);
3015 return 0;
3016}
3017
3018static void set_iir_band_coeff(struct snd_soc_codec *codec,
3019 int iir_idx, int band_idx,
3020 uint32_t value)
3021{
3022 snd_soc_write(codec,
3023 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx),
3024 (value & 0xFF));
3025
3026 snd_soc_write(codec,
3027 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx),
3028 (value >> 8) & 0xFF);
3029
3030 snd_soc_write(codec,
3031 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx),
3032 (value >> 16) & 0xFF);
3033
3034 /* Mask top 2 bits, 7-8 are reserved */
3035 snd_soc_write(codec,
3036 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx),
3037 (value >> 24) & 0x3F);
3038}
3039
3040static void tasha_codec_enable_int_port(struct wcd9xxx_codec_dai_data *dai,
3041 struct snd_soc_codec *codec)
3042{
3043 struct wcd9xxx_ch *ch;
3044 int port_num = 0;
3045 unsigned short reg = 0;
3046 u8 val = 0;
3047 struct tasha_priv *tasha_p;
3048
3049 if (!dai || !codec) {
3050 pr_err("%s: Invalid params\n", __func__);
3051 return;
3052 }
3053
3054 tasha_p = snd_soc_codec_get_drvdata(codec);
3055 list_for_each_entry(ch, &dai->wcd9xxx_ch_list, list) {
3056 if (ch->port >= TASHA_RX_PORT_START_NUMBER) {
3057 port_num = ch->port - TASHA_RX_PORT_START_NUMBER;
3058 reg = TASHA_SLIM_PGD_PORT_INT_EN0 + (port_num / 8);
3059 val = wcd9xxx_interface_reg_read(tasha_p->wcd9xxx,
3060 reg);
3061 if (!(val & BYTE_BIT_MASK(port_num))) {
3062 val |= BYTE_BIT_MASK(port_num);
3063 wcd9xxx_interface_reg_write(
3064 tasha_p->wcd9xxx, reg, val);
3065 val = wcd9xxx_interface_reg_read(
3066 tasha_p->wcd9xxx, reg);
3067 }
3068 } else {
3069 port_num = ch->port;
3070 reg = TASHA_SLIM_PGD_PORT_INT_TX_EN0 + (port_num / 8);
3071 val = wcd9xxx_interface_reg_read(tasha_p->wcd9xxx,
3072 reg);
3073 if (!(val & BYTE_BIT_MASK(port_num))) {
3074 val |= BYTE_BIT_MASK(port_num);
3075 wcd9xxx_interface_reg_write(tasha_p->wcd9xxx,
3076 reg, val);
3077 val = wcd9xxx_interface_reg_read(
3078 tasha_p->wcd9xxx, reg);
3079 }
3080 }
3081 }
3082}
3083
3084static int tasha_codec_enable_slim_chmask(struct wcd9xxx_codec_dai_data *dai,
3085 bool up)
3086{
3087 int ret = 0;
3088 struct wcd9xxx_ch *ch;
3089
3090 if (up) {
3091 list_for_each_entry(ch, &dai->wcd9xxx_ch_list, list) {
3092 ret = wcd9xxx_get_slave_port(ch->ch_num);
3093 if (ret < 0) {
3094 pr_err("%s: Invalid slave port ID: %d\n",
3095 __func__, ret);
3096 ret = -EINVAL;
3097 } else {
3098 set_bit(ret, &dai->ch_mask);
3099 }
3100 }
3101 } else {
3102 ret = wait_event_timeout(dai->dai_wait, (dai->ch_mask == 0),
3103 msecs_to_jiffies(
3104 TASHA_SLIM_CLOSE_TIMEOUT));
3105 if (!ret) {
3106 pr_err("%s: Slim close tx/rx wait timeout, ch_mask:0x%lx\n",
3107 __func__, dai->ch_mask);
3108 ret = -ETIMEDOUT;
3109 } else {
3110 ret = 0;
3111 }
3112 }
3113 return ret;
3114}
3115
3116static int tasha_codec_enable_slimrx(struct snd_soc_dapm_widget *w,
3117 struct snd_kcontrol *kcontrol,
3118 int event)
3119{
3120 struct wcd9xxx *core;
3121 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
3122 struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec);
3123 int ret = 0;
3124 struct wcd9xxx_codec_dai_data *dai;
3125
3126 core = dev_get_drvdata(codec->dev->parent);
3127
3128 dev_dbg(codec->dev, "%s: event called! codec name %s num_dai %d\n"
3129 "stream name %s event %d\n",
3130 __func__, codec->component.name,
3131 codec->component.num_dai, w->sname, event);
3132
3133 /* Execute the callback only if interface type is slimbus */
3134 if (tasha_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS)
3135 return 0;
3136
3137 dai = &tasha_p->dai[w->shift];
3138 dev_dbg(codec->dev, "%s: w->name %s w->shift %d event %d\n",
3139 __func__, w->name, w->shift, event);
3140
3141 switch (event) {
3142 case SND_SOC_DAPM_POST_PMU:
3143 dai->bus_down_in_recovery = false;
3144 tasha_codec_enable_int_port(dai, codec);
3145 (void) tasha_codec_enable_slim_chmask(dai, true);
3146 ret = wcd9xxx_cfg_slim_sch_rx(core, &dai->wcd9xxx_ch_list,
3147 dai->rate, dai->bit_width,
3148 &dai->grph);
3149 break;
3150 case SND_SOC_DAPM_PRE_PMD:
3151 if (!test_bit(SB_CLK_GEAR, &tasha_p->status_mask)) {
3152 tasha_codec_vote_max_bw(codec, true);
3153 set_bit(SB_CLK_GEAR, &tasha_p->status_mask);
3154 }
3155 break;
3156 case SND_SOC_DAPM_POST_PMD:
3157 ret = wcd9xxx_disconnect_port(core, &dai->wcd9xxx_ch_list,
3158 dai->grph);
3159 dev_dbg(codec->dev, "%s: Disconnect RX port, ret = %d\n",
3160 __func__, ret);
3161
3162 if (!dai->bus_down_in_recovery)
3163 ret = tasha_codec_enable_slim_chmask(dai, false);
3164 else
3165 dev_dbg(codec->dev,
3166 "%s: bus in recovery skip enable slim_chmask",
3167 __func__);
3168 ret = wcd9xxx_close_slim_sch_rx(core, &dai->wcd9xxx_ch_list,
3169 dai->grph);
3170 break;
3171 }
3172 return ret;
3173}
3174
3175static int tasha_codec_enable_slimvi_feedback(struct snd_soc_dapm_widget *w,
3176 struct snd_kcontrol *kcontrol,
3177 int event)
3178{
3179 struct wcd9xxx *core = NULL;
3180 struct snd_soc_codec *codec = NULL;
3181 struct tasha_priv *tasha_p = NULL;
3182 int ret = 0;
3183 struct wcd9xxx_codec_dai_data *dai = NULL;
3184
3185 if (!w) {
3186 pr_err("%s invalid params\n", __func__);
3187 return -EINVAL;
3188 }
3189 codec = snd_soc_dapm_to_codec(w->dapm);
3190 tasha_p = snd_soc_codec_get_drvdata(codec);
3191 core = tasha_p->wcd9xxx;
3192
3193 dev_dbg(codec->dev, "%s: num_dai %d stream name %s\n",
3194 __func__, codec->component.num_dai, w->sname);
3195
3196 /* Execute the callback only if interface type is slimbus */
3197 if (tasha_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
3198 dev_err(codec->dev, "%s Interface is not correct", __func__);
3199 return 0;
3200 }
3201
3202 dev_dbg(codec->dev, "%s(): w->name %s event %d w->shift %d\n",
3203 __func__, w->name, event, w->shift);
3204 if (w->shift != AIF4_VIFEED) {
3205 pr_err("%s Error in enabling the tx path\n", __func__);
3206 ret = -EINVAL;
3207 goto out_vi;
3208 }
3209 dai = &tasha_p->dai[w->shift];
3210 switch (event) {
3211 case SND_SOC_DAPM_POST_PMU:
3212 if (test_bit(VI_SENSE_1, &tasha_p->status_mask)) {
3213 dev_dbg(codec->dev, "%s: spkr1 enabled\n", __func__);
3214 /* Enable V&I sensing */
3215 snd_soc_update_bits(codec,
3216 WCD9335_CDC_TX9_SPKR_PROT_PATH_CTL, 0x20, 0x20);
3217 snd_soc_update_bits(codec,
3218 WCD9335_CDC_TX10_SPKR_PROT_PATH_CTL, 0x20,
3219 0x20);
3220 snd_soc_update_bits(codec,
3221 WCD9335_CDC_TX9_SPKR_PROT_PATH_CTL, 0x0F, 0x00);
3222 snd_soc_update_bits(codec,
3223 WCD9335_CDC_TX10_SPKR_PROT_PATH_CTL, 0x0F,
3224 0x00);
3225 snd_soc_update_bits(codec,
3226 WCD9335_CDC_TX9_SPKR_PROT_PATH_CTL, 0x10, 0x10);
3227 snd_soc_update_bits(codec,
3228 WCD9335_CDC_TX10_SPKR_PROT_PATH_CTL, 0x10,
3229 0x10);
3230 snd_soc_update_bits(codec,
3231 WCD9335_CDC_TX9_SPKR_PROT_PATH_CTL, 0x20, 0x00);
3232 snd_soc_update_bits(codec,
3233 WCD9335_CDC_TX10_SPKR_PROT_PATH_CTL, 0x20,
3234 0x00);
3235 }
3236 if (test_bit(VI_SENSE_2, &tasha_p->status_mask)) {
3237 pr_debug("%s: spkr2 enabled\n", __func__);
3238 /* Enable V&I sensing */
3239 snd_soc_update_bits(codec,
3240 WCD9335_CDC_TX11_SPKR_PROT_PATH_CTL, 0x20,
3241 0x20);
3242 snd_soc_update_bits(codec,
3243 WCD9335_CDC_TX12_SPKR_PROT_PATH_CTL, 0x20,
3244 0x20);
3245 snd_soc_update_bits(codec,
3246 WCD9335_CDC_TX11_SPKR_PROT_PATH_CTL, 0x0F,
3247 0x00);
3248 snd_soc_update_bits(codec,
3249 WCD9335_CDC_TX12_SPKR_PROT_PATH_CTL, 0x0F,
3250 0x00);
3251 snd_soc_update_bits(codec,
3252 WCD9335_CDC_TX11_SPKR_PROT_PATH_CTL, 0x10,
3253 0x10);
3254 snd_soc_update_bits(codec,
3255 WCD9335_CDC_TX12_SPKR_PROT_PATH_CTL, 0x10,
3256 0x10);
3257 snd_soc_update_bits(codec,
3258 WCD9335_CDC_TX11_SPKR_PROT_PATH_CTL, 0x20,
3259 0x00);
3260 snd_soc_update_bits(codec,
3261 WCD9335_CDC_TX12_SPKR_PROT_PATH_CTL, 0x20,
3262 0x00);
3263 }
3264 dai->bus_down_in_recovery = false;
3265 tasha_codec_enable_int_port(dai, codec);
3266 (void) tasha_codec_enable_slim_chmask(dai, true);
3267 ret = wcd9xxx_cfg_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
3268 dai->rate, dai->bit_width,
3269 &dai->grph);
3270 break;
3271 case SND_SOC_DAPM_POST_PMD:
3272 ret = wcd9xxx_close_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
3273 dai->grph);
3274 if (ret)
3275 dev_err(codec->dev, "%s error in close_slim_sch_tx %d\n",
3276 __func__, ret);
3277 if (!dai->bus_down_in_recovery)
3278 ret = tasha_codec_enable_slim_chmask(dai, false);
3279 if (ret < 0) {
3280 ret = wcd9xxx_disconnect_port(core,
3281 &dai->wcd9xxx_ch_list,
3282 dai->grph);
3283 dev_dbg(codec->dev, "%s: Disconnect TX port, ret = %d\n",
3284 __func__, ret);
3285 }
3286 if (test_bit(VI_SENSE_1, &tasha_p->status_mask)) {
3287 /* Disable V&I sensing */
3288 dev_dbg(codec->dev, "%s: spkr1 disabled\n", __func__);
3289 snd_soc_update_bits(codec,
3290 WCD9335_CDC_TX9_SPKR_PROT_PATH_CTL, 0x20, 0x20);
3291 snd_soc_update_bits(codec,
3292 WCD9335_CDC_TX10_SPKR_PROT_PATH_CTL, 0x20,
3293 0x20);
3294 snd_soc_update_bits(codec,
3295 WCD9335_CDC_TX9_SPKR_PROT_PATH_CTL, 0x10, 0x00);
3296 snd_soc_update_bits(codec,
3297 WCD9335_CDC_TX10_SPKR_PROT_PATH_CTL, 0x10,
3298 0x00);
3299 }
3300 if (test_bit(VI_SENSE_2, &tasha_p->status_mask)) {
3301 /* Disable V&I sensing */
3302 dev_dbg(codec->dev, "%s: spkr2 disabled\n", __func__);
3303 snd_soc_update_bits(codec,
3304 WCD9335_CDC_TX11_SPKR_PROT_PATH_CTL, 0x20,
3305 0x20);
3306 snd_soc_update_bits(codec,
3307 WCD9335_CDC_TX12_SPKR_PROT_PATH_CTL, 0x20,
3308 0x20);
3309 snd_soc_update_bits(codec,
3310 WCD9335_CDC_TX11_SPKR_PROT_PATH_CTL, 0x10,
3311 0x00);
3312 snd_soc_update_bits(codec,
3313 WCD9335_CDC_TX12_SPKR_PROT_PATH_CTL, 0x10,
3314 0x00);
3315 }
3316 break;
3317 }
3318out_vi:
3319 return ret;
3320}
3321
3322/*
3323 * __tasha_codec_enable_slimtx: Enable the slimbus slave port
3324 * for TX path
3325 * @codec: Handle to the codec for which the slave port is to be
3326 * enabled.
3327 * @dai_data: The dai specific data for dai which is enabled.
3328 */
3329static int __tasha_codec_enable_slimtx(struct snd_soc_codec *codec,
3330 int event, struct wcd9xxx_codec_dai_data *dai)
3331{
3332 struct wcd9xxx *core;
3333 struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec);
3334 int ret = 0;
3335
3336 /* Execute the callback only if interface type is slimbus */
3337 if (tasha_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS)
3338 return 0;
3339
3340 dev_dbg(codec->dev,
3341 "%s: event = %d\n", __func__, event);
3342 core = dev_get_drvdata(codec->dev->parent);
3343
3344 switch (event) {
3345 case SND_SOC_DAPM_POST_PMU:
3346 dai->bus_down_in_recovery = false;
3347 tasha_codec_enable_int_port(dai, codec);
3348 (void) tasha_codec_enable_slim_chmask(dai, true);
3349 ret = wcd9xxx_cfg_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
3350 dai->rate, dai->bit_width,
3351 &dai->grph);
3352 break;
3353 case SND_SOC_DAPM_POST_PMD:
3354 ret = wcd9xxx_close_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
3355 dai->grph);
3356 if (!dai->bus_down_in_recovery)
3357 ret = tasha_codec_enable_slim_chmask(dai, false);
3358 if (ret < 0) {
3359 ret = wcd9xxx_disconnect_port(core,
3360 &dai->wcd9xxx_ch_list,
3361 dai->grph);
3362 pr_debug("%s: Disconnect TX port, ret = %d\n",
3363 __func__, ret);
3364 }
3365
3366 break;
3367 }
3368
3369 return ret;
3370}
3371
3372static int tasha_codec_enable_slimtx(struct snd_soc_dapm_widget *w,
3373 struct snd_kcontrol *kcontrol,
3374 int event)
3375{
3376 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
3377 struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec);
3378 struct wcd9xxx_codec_dai_data *dai;
3379
3380 dev_dbg(codec->dev,
3381 "%s: w->name %s, w->shift = %d, num_dai %d stream name %s\n",
3382 __func__, w->name, w->shift,
3383 codec->component.num_dai, w->sname);
3384
3385 dai = &tasha_p->dai[w->shift];
3386 return __tasha_codec_enable_slimtx(codec, event, dai);
3387}
3388
3389static void tasha_codec_cpe_pp_set_cfg(struct snd_soc_codec *codec, int event)
3390{
3391 struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec);
3392 struct wcd9xxx_codec_dai_data *dai;
3393 u8 bit_width, rate, buf_period;
3394
3395 dai = &tasha_p->dai[AIF4_MAD_TX];
3396 switch (event) {
3397 case SND_SOC_DAPM_POST_PMU:
3398 switch (dai->bit_width) {
3399 case 32:
3400 bit_width = 0xF;
3401 break;
3402 case 24:
3403 bit_width = 0xE;
3404 break;
3405 case 20:
3406 bit_width = 0xD;
3407 break;
3408 case 16:
3409 default:
3410 bit_width = 0x0;
3411 break;
3412 }
3413 snd_soc_update_bits(codec, WCD9335_CPE_SS_TX_PP_CFG, 0x0F,
3414 bit_width);
3415
3416 switch (dai->rate) {
3417 case 384000:
3418 rate = 0x30;
3419 break;
3420 case 192000:
3421 rate = 0x20;
3422 break;
3423 case 48000:
3424 rate = 0x10;
3425 break;
3426 case 16000:
3427 default:
3428 rate = 0x00;
3429 break;
3430 }
3431 snd_soc_update_bits(codec, WCD9335_CPE_SS_TX_PP_CFG, 0x70,
3432 rate);
3433
3434 buf_period = (dai->rate * (dai->bit_width/8)) / (16*1000);
3435 snd_soc_update_bits(codec, WCD9335_CPE_SS_TX_PP_BUF_INT_PERIOD,
3436 0xFF, buf_period);
3437 dev_dbg(codec->dev, "%s: PP buffer period= 0x%x\n",
3438 __func__, buf_period);
3439 break;
3440
3441 case SND_SOC_DAPM_POST_PMD:
3442 snd_soc_write(codec, WCD9335_CPE_SS_TX_PP_CFG, 0x3C);
3443 snd_soc_write(codec, WCD9335_CPE_SS_TX_PP_BUF_INT_PERIOD, 0x60);
3444 break;
3445
3446 default:
3447 break;
3448 }
3449}
3450
3451/*
3452 * tasha_codec_get_mad_port_id: Callback function that will be invoked
3453 * to get the port ID for MAD.
3454 * @codec: Handle to the codec
3455 * @port_id: cpe port_id needs to enable
3456 */
3457static int tasha_codec_get_mad_port_id(struct snd_soc_codec *codec,
3458 u16 *port_id)
3459{
3460 struct tasha_priv *tasha_p;
3461 struct wcd9xxx_codec_dai_data *dai;
3462 struct wcd9xxx_ch *ch;
3463
3464 if (!port_id || !codec)
3465 return -EINVAL;
3466
3467 tasha_p = snd_soc_codec_get_drvdata(codec);
3468 if (!tasha_p)
3469 return -EINVAL;
3470
3471 dai = &tasha_p->dai[AIF4_MAD_TX];
3472 list_for_each_entry(ch, &dai->wcd9xxx_ch_list, list) {
3473 if (ch->port == TASHA_TX12)
3474 *port_id = WCD_CPE_AFE_OUT_PORT_2;
3475 else if (ch->port == TASHA_TX13)
3476 *port_id = WCD_CPE_AFE_OUT_PORT_4;
3477 else {
3478 dev_err(codec->dev, "%s: invalid mad_port = %d\n",
3479 __func__, ch->port);
3480 return -EINVAL;
3481 }
3482 }
3483 dev_dbg(codec->dev, "%s: port_id = %d\n", __func__, *port_id);
3484
3485 return 0;
3486}
3487
3488/*
3489 * tasha_codec_enable_slimtx_mad: Callback function that will be invoked
3490 * to setup the slave port for MAD.
3491 * @codec: Handle to the codec
3492 * @event: Indicates whether to enable or disable the slave port
3493 */
3494static int tasha_codec_enable_slimtx_mad(struct snd_soc_codec *codec,
3495 u8 event)
3496{
3497 struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec);
3498 struct wcd9xxx_codec_dai_data *dai;
3499 struct wcd9xxx_ch *ch;
3500 int dapm_event = SND_SOC_DAPM_POST_PMU;
3501 u16 port = 0;
3502 int ret = 0;
3503
3504 dai = &tasha_p->dai[AIF4_MAD_TX];
3505
3506 if (event == 0)
3507 dapm_event = SND_SOC_DAPM_POST_PMD;
3508
3509 dev_dbg(codec->dev,
3510 "%s: mad_channel, event = 0x%x\n",
3511 __func__, event);
3512
3513 list_for_each_entry(ch, &dai->wcd9xxx_ch_list, list) {
3514 dev_dbg(codec->dev, "%s: mad_port = %d, event = 0x%x\n",
3515 __func__, ch->port, event);
3516 if (ch->port == TASHA_TX13) {
3517 tasha_codec_cpe_pp_set_cfg(codec, dapm_event);
3518 port = TASHA_TX13;
3519 break;
3520 }
3521 }
3522
3523 ret = __tasha_codec_enable_slimtx(codec, dapm_event, dai);
3524
3525 if (port == TASHA_TX13) {
3526 switch (dapm_event) {
3527 case SND_SOC_DAPM_POST_PMU:
3528 snd_soc_update_bits(codec,
3529 WCD9335_CODEC_RPM_PWR_CPE_DRAM1_SHUTDOWN,
3530 0x20, 0x00);
3531 snd_soc_update_bits(codec,
3532 WCD9335_DATA_HUB_DATA_HUB_SB_TX13_INP_CFG,
3533 0x03, 0x02);
3534 snd_soc_update_bits(codec, WCD9335_CPE_SS_CFG,
3535 0x80, 0x80);
3536 break;
3537 case SND_SOC_DAPM_POST_PMD:
3538 snd_soc_update_bits(codec,
3539 WCD9335_CODEC_RPM_PWR_CPE_DRAM1_SHUTDOWN,
3540 0x20, 0x20);
3541 snd_soc_update_bits(codec,
3542 WCD9335_DATA_HUB_DATA_HUB_SB_TX13_INP_CFG,
3543 0x03, 0x00);
3544 snd_soc_update_bits(codec, WCD9335_CPE_SS_CFG,
3545 0x80, 0x00);
3546 break;
3547 }
3548 }
3549
3550 return ret;
3551}
3552
3553static int tasha_put_iir_band_audio_mixer(
3554 struct snd_kcontrol *kcontrol,
3555 struct snd_ctl_elem_value *ucontrol)
3556{
3557 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
3558 int iir_idx = ((struct soc_multi_mixer_control *)
3559 kcontrol->private_value)->reg;
3560 int band_idx = ((struct soc_multi_mixer_control *)
3561 kcontrol->private_value)->shift;
3562
3563 /*
3564 * Mask top bit it is reserved
3565 * Updates addr automatically for each B2 write
3566 */
3567 snd_soc_write(codec,
3568 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx),
3569 (band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F);
3570
3571 set_iir_band_coeff(codec, iir_idx, band_idx,
3572 ucontrol->value.integer.value[0]);
3573 set_iir_band_coeff(codec, iir_idx, band_idx,
3574 ucontrol->value.integer.value[1]);
3575 set_iir_band_coeff(codec, iir_idx, band_idx,
3576 ucontrol->value.integer.value[2]);
3577 set_iir_band_coeff(codec, iir_idx, band_idx,
3578 ucontrol->value.integer.value[3]);
3579 set_iir_band_coeff(codec, iir_idx, band_idx,
3580 ucontrol->value.integer.value[4]);
3581
3582 pr_debug("%s: IIR #%d band #%d b0 = 0x%x\n"
3583 "%s: IIR #%d band #%d b1 = 0x%x\n"
3584 "%s: IIR #%d band #%d b2 = 0x%x\n"
3585 "%s: IIR #%d band #%d a1 = 0x%x\n"
3586 "%s: IIR #%d band #%d a2 = 0x%x\n",
3587 __func__, iir_idx, band_idx,
3588 get_iir_band_coeff(codec, iir_idx, band_idx, 0),
3589 __func__, iir_idx, band_idx,
3590 get_iir_band_coeff(codec, iir_idx, band_idx, 1),
3591 __func__, iir_idx, band_idx,
3592 get_iir_band_coeff(codec, iir_idx, band_idx, 2),
3593 __func__, iir_idx, band_idx,
3594 get_iir_band_coeff(codec, iir_idx, band_idx, 3),
3595 __func__, iir_idx, band_idx,
3596 get_iir_band_coeff(codec, iir_idx, band_idx, 4));
3597 return 0;
3598}
3599
3600static int tasha_get_compander(struct snd_kcontrol *kcontrol,
3601 struct snd_ctl_elem_value *ucontrol)
3602{
3603
3604 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
3605 int comp = ((struct soc_multi_mixer_control *)
3606 kcontrol->private_value)->shift;
3607 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
3608
3609 ucontrol->value.integer.value[0] = tasha->comp_enabled[comp];
3610 return 0;
3611}
3612
3613static int tasha_set_compander(struct snd_kcontrol *kcontrol,
3614 struct snd_ctl_elem_value *ucontrol)
3615{
3616 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
3617 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
3618 int comp = ((struct soc_multi_mixer_control *)
3619 kcontrol->private_value)->shift;
3620 int value = ucontrol->value.integer.value[0];
3621
3622 pr_debug("%s: Compander %d enable current %d, new %d\n",
3623 __func__, comp + 1, tasha->comp_enabled[comp], value);
3624 tasha->comp_enabled[comp] = value;
3625
3626 /* Any specific register configuration for compander */
3627 switch (comp) {
3628 case COMPANDER_1:
3629 /* Set Gain Source Select based on compander enable/disable */
3630 snd_soc_update_bits(codec, WCD9335_HPH_L_EN, 0x20,
3631 (value ? 0x00:0x20));
3632 break;
3633 case COMPANDER_2:
3634 snd_soc_update_bits(codec, WCD9335_HPH_R_EN, 0x20,
3635 (value ? 0x00:0x20));
3636 break;
3637 case COMPANDER_3:
3638 break;
3639 case COMPANDER_4:
3640 break;
3641 case COMPANDER_5:
3642 snd_soc_update_bits(codec, WCD9335_SE_LO_LO3_GAIN, 0x20,
3643 (value ? 0x00:0x20));
3644 break;
3645 case COMPANDER_6:
3646 snd_soc_update_bits(codec, WCD9335_SE_LO_LO4_GAIN, 0x20,
3647 (value ? 0x00:0x20));
3648 break;
3649 case COMPANDER_7:
3650 break;
3651 case COMPANDER_8:
3652 break;
3653 default:
3654 /*
3655 * if compander is not enabled for any interpolator,
3656 * it does not cause any audio failure, so do not
3657 * return error in this case, but just print a log
3658 */
3659 dev_warn(codec->dev, "%s: unknown compander: %d\n",
3660 __func__, comp);
3661 };
3662 return 0;
3663}
3664
3665static void tasha_codec_init_flyback(struct snd_soc_codec *codec)
3666{
3667 snd_soc_update_bits(codec, WCD9335_HPH_L_EN, 0xC0, 0x00);
3668 snd_soc_update_bits(codec, WCD9335_HPH_R_EN, 0xC0, 0x00);
3669 snd_soc_update_bits(codec, WCD9335_RX_BIAS_FLYB_BUFF, 0x0F, 0x00);
3670 snd_soc_update_bits(codec, WCD9335_RX_BIAS_FLYB_BUFF, 0xF0, 0x00);
3671}
3672
3673static int tasha_codec_enable_rx_bias(struct snd_soc_dapm_widget *w,
3674 struct snd_kcontrol *kcontrol, int event)
3675{
3676 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
3677 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
3678
3679 dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
3680
3681 switch (event) {
3682 case SND_SOC_DAPM_PRE_PMU:
3683 tasha->rx_bias_count++;
3684 if (tasha->rx_bias_count == 1) {
3685 if (TASHA_IS_2_0(tasha->wcd9xxx))
3686 tasha_codec_init_flyback(codec);
3687 snd_soc_update_bits(codec, WCD9335_ANA_RX_SUPPLIES,
3688 0x01, 0x01);
3689 }
3690 break;
3691 case SND_SOC_DAPM_POST_PMD:
3692 tasha->rx_bias_count--;
3693 if (!tasha->rx_bias_count)
3694 snd_soc_update_bits(codec, WCD9335_ANA_RX_SUPPLIES,
3695 0x01, 0x00);
3696 break;
3697 };
3698 dev_dbg(codec->dev, "%s: Current RX BIAS user count: %d\n", __func__,
3699 tasha->rx_bias_count);
3700
3701 return 0;
3702}
3703
3704static void tasha_realign_anc_coeff(struct snd_soc_codec *codec,
3705 u16 reg1, u16 reg2)
3706{
3707 u8 val1, val2, tmpval1, tmpval2;
3708
3709 snd_soc_write(codec, reg1, 0x00);
3710 tmpval1 = snd_soc_read(codec, reg2);
3711 tmpval2 = snd_soc_read(codec, reg2);
3712 snd_soc_write(codec, reg1, 0x00);
3713 snd_soc_write(codec, reg2, 0xFF);
3714 snd_soc_write(codec, reg1, 0x01);
3715 snd_soc_write(codec, reg2, 0xFF);
3716
3717 snd_soc_write(codec, reg1, 0x00);
3718 val1 = snd_soc_read(codec, reg2);
3719 val2 = snd_soc_read(codec, reg2);
3720
3721 if (val1 == 0x0F && val2 == 0xFF) {
3722 dev_dbg(codec->dev, "%s: ANC0 co-eff index re-aligned\n",
3723 __func__);
3724 snd_soc_read(codec, reg2);
3725 snd_soc_write(codec, reg1, 0x00);
3726 snd_soc_write(codec, reg2, tmpval2);
3727 snd_soc_write(codec, reg1, 0x01);
3728 snd_soc_write(codec, reg2, tmpval1);
3729 } else if (val1 == 0xFF && val2 == 0x0F) {
3730 dev_dbg(codec->dev, "%s: ANC1 co-eff index already aligned\n",
3731 __func__);
3732 snd_soc_write(codec, reg1, 0x00);
3733 snd_soc_write(codec, reg2, tmpval1);
3734 snd_soc_write(codec, reg1, 0x01);
3735 snd_soc_write(codec, reg2, tmpval2);
3736 } else {
3737 dev_err(codec->dev, "%s: ANC0 co-eff index not aligned\n",
3738 __func__);
3739 }
3740}
3741
3742static int tasha_codec_enable_anc(struct snd_soc_dapm_widget *w,
3743 struct snd_kcontrol *kcontrol, int event)
3744{
3745 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
3746 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
3747 const char *filename;
3748 const struct firmware *fw;
3749 int i;
3750 int ret = 0;
3751 int num_anc_slots;
3752 struct wcd9xxx_anc_header *anc_head;
3753 struct firmware_cal *hwdep_cal = NULL;
3754 u32 anc_writes_size = 0;
3755 u32 anc_cal_size = 0;
3756 int anc_size_remaining;
3757 u32 *anc_ptr;
3758 u16 reg;
3759 u8 mask, val;
3760 size_t cal_size;
3761 const void *data;
3762
3763 if (!tasha->anc_func)
3764 return 0;
3765
3766 switch (event) {
3767 case SND_SOC_DAPM_PRE_PMU:
3768 hwdep_cal = wcdcal_get_fw_cal(tasha->fw_data, WCD9XXX_ANC_CAL);
3769 if (hwdep_cal) {
3770 data = hwdep_cal->data;
3771 cal_size = hwdep_cal->size;
3772 dev_dbg(codec->dev, "%s: using hwdep calibration\n",
3773 __func__);
3774 } else {
3775 filename = "wcd9335/wcd9335_anc.bin";
3776 ret = request_firmware(&fw, filename, codec->dev);
3777 if (ret != 0) {
3778 dev_err(codec->dev,
3779 "Failed to acquire ANC data: %d\n", ret);
3780 return -ENODEV;
3781 }
3782 if (!fw) {
3783 dev_err(codec->dev, "failed to get anc fw");
3784 return -ENODEV;
3785 }
3786 data = fw->data;
3787 cal_size = fw->size;
3788 dev_dbg(codec->dev,
3789 "%s: using request_firmware calibration\n", __func__);
3790 }
3791 if (cal_size < sizeof(struct wcd9xxx_anc_header)) {
3792 dev_err(codec->dev, "Not enough data\n");
3793 ret = -ENOMEM;
3794 goto err;
3795 }
3796 /* First number is the number of register writes */
3797 anc_head = (struct wcd9xxx_anc_header *)(data);
3798 anc_ptr = (u32 *)(data +
3799 sizeof(struct wcd9xxx_anc_header));
3800 anc_size_remaining = cal_size -
3801 sizeof(struct wcd9xxx_anc_header);
3802 num_anc_slots = anc_head->num_anc_slots;
3803
3804 if (tasha->anc_slot >= num_anc_slots) {
3805 dev_err(codec->dev, "Invalid ANC slot selected\n");
3806 ret = -EINVAL;
3807 goto err;
3808 }
3809 for (i = 0; i < num_anc_slots; i++) {
3810 if (anc_size_remaining < TASHA_PACKED_REG_SIZE) {
3811 dev_err(codec->dev,
3812 "Invalid register format\n");
3813 ret = -EINVAL;
3814 goto err;
3815 }
3816 anc_writes_size = (u32)(*anc_ptr);
3817 anc_size_remaining -= sizeof(u32);
3818 anc_ptr += 1;
3819
3820 if (anc_writes_size * TASHA_PACKED_REG_SIZE
3821 > anc_size_remaining) {
3822 dev_err(codec->dev,
3823 "Invalid register format\n");
3824 ret = -EINVAL;
3825 goto err;
3826 }
3827
3828 if (tasha->anc_slot == i)
3829 break;
3830
3831 anc_size_remaining -= (anc_writes_size *
3832 TASHA_PACKED_REG_SIZE);
3833 anc_ptr += anc_writes_size;
3834 }
3835 if (i == num_anc_slots) {
3836 dev_err(codec->dev, "Selected ANC slot not present\n");
3837 ret = -EINVAL;
3838 goto err;
3839 }
3840
3841 i = 0;
3842 anc_cal_size = anc_writes_size;
3843
3844 if (!strcmp(w->name, "RX INT0 DAC") ||
3845 !strcmp(w->name, "ANC SPK1 PA"))
3846 tasha_realign_anc_coeff(codec,
3847 WCD9335_CDC_ANC0_IIR_COEFF_1_CTL,
3848 WCD9335_CDC_ANC0_IIR_COEFF_2_CTL);
3849
3850 if (!strcmp(w->name, "RX INT1 DAC") ||
3851 !strcmp(w->name, "RX INT3 DAC")) {
3852 tasha_realign_anc_coeff(codec,
3853 WCD9335_CDC_ANC0_IIR_COEFF_1_CTL,
3854 WCD9335_CDC_ANC0_IIR_COEFF_2_CTL);
3855 anc_writes_size = anc_cal_size / 2;
3856 snd_soc_update_bits(codec,
3857 WCD9335_CDC_ANC0_CLK_RESET_CTL, 0x39, 0x39);
3858 } else if (!strcmp(w->name, "RX INT2 DAC") ||
3859 !strcmp(w->name, "RX INT4 DAC")) {
3860 tasha_realign_anc_coeff(codec,
3861 WCD9335_CDC_ANC1_IIR_COEFF_1_CTL,
3862 WCD9335_CDC_ANC1_IIR_COEFF_2_CTL);
3863 i = anc_cal_size / 2;
3864 snd_soc_update_bits(codec,
3865 WCD9335_CDC_ANC1_CLK_RESET_CTL, 0x39, 0x39);
3866 }
3867
3868 for (; i < anc_writes_size; i++) {
3869 TASHA_CODEC_UNPACK_ENTRY(anc_ptr[i], reg, mask, val);
3870 snd_soc_write(codec, reg, (val & mask));
3871 }
3872 if (!strcmp(w->name, "RX INT1 DAC") ||
3873 !strcmp(w->name, "RX INT3 DAC")) {
3874 snd_soc_update_bits(codec,
3875 WCD9335_CDC_ANC0_CLK_RESET_CTL, 0x08, 0x08);
3876 } else if (!strcmp(w->name, "RX INT2 DAC") ||
3877 !strcmp(w->name, "RX INT4 DAC")) {
3878 snd_soc_update_bits(codec,
3879 WCD9335_CDC_ANC1_CLK_RESET_CTL, 0x08, 0x08);
3880 }
3881
3882 if (!hwdep_cal)
3883 release_firmware(fw);
3884 break;
3885 case SND_SOC_DAPM_POST_PMU:
3886 /* Remove ANC Rx from reset */
3887 snd_soc_update_bits(codec, WCD9335_CDC_ANC0_CLK_RESET_CTL,
3888 0x08, 0x00);
3889 snd_soc_update_bits(codec, WCD9335_CDC_ANC1_CLK_RESET_CTL,
3890 0x08, 0x00);
3891 break;
3892 case SND_SOC_DAPM_POST_PMD:
3893 if (!strcmp(w->name, "ANC HPHL PA") ||
3894 !strcmp(w->name, "ANC EAR PA") ||
3895 !strcmp(w->name, "ANC SPK1 PA") ||
3896 !strcmp(w->name, "ANC LINEOUT1 PA")) {
3897 snd_soc_update_bits(codec,
3898 WCD9335_CDC_ANC0_MODE_1_CTL, 0x30, 0x00);
3899 msleep(50);
3900 snd_soc_update_bits(codec,
3901 WCD9335_CDC_ANC0_MODE_1_CTL, 0x01, 0x00);
3902 snd_soc_update_bits(codec,
3903 WCD9335_CDC_ANC0_CLK_RESET_CTL, 0x38, 0x38);
3904 snd_soc_update_bits(codec,
3905 WCD9335_CDC_ANC0_CLK_RESET_CTL, 0x07, 0x00);
3906 snd_soc_update_bits(codec,
3907 WCD9335_CDC_ANC0_CLK_RESET_CTL, 0x38, 0x00);
3908 } else if (!strcmp(w->name, "ANC HPHR PA") ||
3909 !strcmp(w->name, "ANC LINEOUT2 PA")) {
3910 snd_soc_update_bits(codec,
3911 WCD9335_CDC_ANC1_MODE_1_CTL, 0x30, 0x00);
3912 msleep(50);
3913 snd_soc_update_bits(codec,
3914 WCD9335_CDC_ANC1_MODE_1_CTL, 0x01, 0x00);
3915 snd_soc_update_bits(codec,
3916 WCD9335_CDC_ANC1_CLK_RESET_CTL, 0x38, 0x38);
3917 snd_soc_update_bits(codec,
3918 WCD9335_CDC_ANC1_CLK_RESET_CTL, 0x07, 0x00);
3919 snd_soc_update_bits(codec,
3920 WCD9335_CDC_ANC1_CLK_RESET_CTL, 0x38, 0x00);
3921 }
3922 break;
3923 }
3924
3925 return 0;
3926err:
3927 if (!hwdep_cal)
3928 release_firmware(fw);
3929 return ret;
3930}
3931
3932static void tasha_codec_clear_anc_tx_hold(struct tasha_priv *tasha)
3933{
3934 if (test_and_clear_bit(ANC_MIC_AMIC1, &tasha->status_mask))
3935 tasha_codec_set_tx_hold(tasha->codec, WCD9335_ANA_AMIC1, false);
3936 if (test_and_clear_bit(ANC_MIC_AMIC2, &tasha->status_mask))
3937 tasha_codec_set_tx_hold(tasha->codec, WCD9335_ANA_AMIC2, false);
3938 if (test_and_clear_bit(ANC_MIC_AMIC3, &tasha->status_mask))
3939 tasha_codec_set_tx_hold(tasha->codec, WCD9335_ANA_AMIC3, false);
3940 if (test_and_clear_bit(ANC_MIC_AMIC4, &tasha->status_mask))
3941 tasha_codec_set_tx_hold(tasha->codec, WCD9335_ANA_AMIC4, false);
3942 if (test_and_clear_bit(ANC_MIC_AMIC5, &tasha->status_mask))
3943 tasha_codec_set_tx_hold(tasha->codec, WCD9335_ANA_AMIC5, false);
3944 if (test_and_clear_bit(ANC_MIC_AMIC6, &tasha->status_mask))
3945 tasha_codec_set_tx_hold(tasha->codec, WCD9335_ANA_AMIC6, false);
3946}
3947
3948static void tasha_codec_hph_post_pa_config(struct tasha_priv *tasha,
3949 int mode, int event)
3950{
3951 u8 scale_val = 0;
3952
3953 if (!TASHA_IS_2_0(tasha->wcd9xxx))
3954 return;
3955
3956 switch (event) {
3957 case SND_SOC_DAPM_POST_PMU:
3958 switch (mode) {
3959 case CLS_H_HIFI:
3960 scale_val = 0x3;
3961 break;
3962 case CLS_H_LOHIFI:
3963 scale_val = 0x1;
3964 break;
3965 }
3966 if (tasha->anc_func) {
3967 /* Clear Tx FE HOLD if both PAs are enabled */
3968 if ((snd_soc_read(tasha->codec, WCD9335_ANA_HPH) &
3969 0xC0) == 0xC0) {
3970 tasha_codec_clear_anc_tx_hold(tasha);
3971 }
3972 }
3973 break;
3974 case SND_SOC_DAPM_PRE_PMD:
3975 scale_val = 0x6;
3976 break;
3977 }
3978
3979 if (scale_val)
3980 snd_soc_update_bits(tasha->codec, WCD9335_HPH_PA_CTL1, 0x0E,
3981 scale_val << 1);
3982 if (SND_SOC_DAPM_EVENT_ON(event)) {
3983 if (tasha->comp_enabled[COMPANDER_1] ||
3984 tasha->comp_enabled[COMPANDER_2]) {
3985 snd_soc_update_bits(tasha->codec, WCD9335_HPH_L_EN,
3986 0x20, 0x00);
3987 snd_soc_update_bits(tasha->codec, WCD9335_HPH_R_EN,
3988 0x20, 0x00);
3989 snd_soc_update_bits(tasha->codec, WCD9335_HPH_AUTO_CHOP,
3990 0x20, 0x20);
3991 }
3992 snd_soc_update_bits(tasha->codec, WCD9335_HPH_L_EN, 0x1F,
3993 tasha->hph_l_gain);
3994 snd_soc_update_bits(tasha->codec, WCD9335_HPH_R_EN, 0x1F,
3995 tasha->hph_r_gain);
3996 }
3997
3998 if (SND_SOC_DAPM_EVENT_OFF(event)) {
3999 snd_soc_update_bits(tasha->codec, WCD9335_HPH_AUTO_CHOP, 0x20,
4000 0x00);
4001 }
4002}
4003
4004static void tasha_codec_override(struct snd_soc_codec *codec,
4005 int mode,
4006 int event)
4007{
4008 if (mode == CLS_AB) {
4009 switch (event) {
4010 case SND_SOC_DAPM_POST_PMU:
4011 if (!(snd_soc_read(codec,
4012 WCD9335_CDC_RX2_RX_PATH_CTL) & 0x10) &&
4013 (!(snd_soc_read(codec,
4014 WCD9335_CDC_RX1_RX_PATH_CTL) & 0x10)))
4015 snd_soc_update_bits(codec,
4016 WCD9XXX_A_ANA_RX_SUPPLIES, 0x02, 0x02);
4017 break;
4018 case SND_SOC_DAPM_POST_PMD:
4019 snd_soc_update_bits(codec,
4020 WCD9XXX_A_ANA_RX_SUPPLIES, 0x02, 0x00);
4021 break;
4022 }
4023 }
4024}
4025
4026static int tasha_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
4027 struct snd_kcontrol *kcontrol,
4028 int event)
4029{
4030 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
4031 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
4032 int hph_mode = tasha->hph_mode;
4033 int ret = 0;
4034
4035 dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
4036
4037 switch (event) {
4038 case SND_SOC_DAPM_PRE_PMU:
4039 if ((!(strcmp(w->name, "ANC HPHR PA"))) &&
4040 (test_bit(HPH_PA_DELAY, &tasha->status_mask))) {
4041 snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0xC0, 0xC0);
4042 }
4043 set_bit(HPH_PA_DELAY, &tasha->status_mask);
4044 break;
4045 case SND_SOC_DAPM_POST_PMU:
4046 if (!(strcmp(w->name, "ANC HPHR PA"))) {
4047 if ((snd_soc_read(codec, WCD9335_ANA_HPH) & 0xC0)
4048 != 0xC0)
4049 /*
4050 * If PA_EN is not set (potentially in ANC case)
4051 * then do nothing for POST_PMU and let left
4052 * channel handle everything.
4053 */
4054 break;
4055 }
4056 /*
4057 * 7ms sleep is required after PA is enabled as per
4058 * HW requirement
4059 */
4060 if (test_bit(HPH_PA_DELAY, &tasha->status_mask)) {
4061 usleep_range(7000, 7100);
4062 clear_bit(HPH_PA_DELAY, &tasha->status_mask);
4063 }
4064 tasha_codec_hph_post_pa_config(tasha, hph_mode, event);
4065 snd_soc_update_bits(codec, WCD9335_CDC_RX2_RX_PATH_CTL,
4066 0x10, 0x00);
4067 /* Remove mix path mute if it is enabled */
4068 if ((snd_soc_read(codec, WCD9335_CDC_RX2_RX_PATH_MIX_CTL)) &
4069 0x10)
4070 snd_soc_update_bits(codec,
4071 WCD9335_CDC_RX2_RX_PATH_MIX_CTL,
4072 0x10, 0x00);
4073
4074 if (!(strcmp(w->name, "ANC HPHR PA"))) {
4075 /* Do everything needed for left channel */
4076 snd_soc_update_bits(codec, WCD9335_CDC_RX1_RX_PATH_CTL,
4077 0x10, 0x00);
4078 /* Remove mix path mute if it is enabled */
4079 if ((snd_soc_read(codec,
4080 WCD9335_CDC_RX1_RX_PATH_MIX_CTL)) &
4081 0x10)
4082 snd_soc_update_bits(codec,
4083 WCD9335_CDC_RX1_RX_PATH_MIX_CTL,
4084 0x10, 0x00);
4085 /* Remove ANC Rx from reset */
4086 ret = tasha_codec_enable_anc(w, kcontrol, event);
4087 }
4088 tasha_codec_override(codec, hph_mode, event);
4089 break;
4090
4091 case SND_SOC_DAPM_PRE_PMD:
4092 blocking_notifier_call_chain(&tasha->notifier,
4093 WCD_EVENT_PRE_HPHR_PA_OFF,
4094 &tasha->mbhc);
4095 tasha_codec_hph_post_pa_config(tasha, hph_mode, event);
4096 if (!(strcmp(w->name, "ANC HPHR PA")))
4097 snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0x40, 0x00);
4098 break;
4099 case SND_SOC_DAPM_POST_PMD:
4100 /* 5ms sleep is required after PA is disabled as per
4101 * HW requirement
4102 */
4103 usleep_range(5000, 5500);
4104 tasha_codec_override(codec, hph_mode, event);
4105 blocking_notifier_call_chain(&tasha->notifier,
4106 WCD_EVENT_POST_HPHR_PA_OFF,
4107 &tasha->mbhc);
4108
4109 if (!(strcmp(w->name, "ANC HPHR PA"))) {
4110 ret = tasha_codec_enable_anc(w, kcontrol, event);
4111 snd_soc_update_bits(codec,
4112 WCD9335_CDC_RX2_RX_PATH_CFG0, 0x10, 0x00);
4113 }
4114 break;
4115 };
4116
4117 return ret;
4118}
4119
4120static int tasha_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
4121 struct snd_kcontrol *kcontrol,
4122 int event)
4123{
4124 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
4125 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
4126 int hph_mode = tasha->hph_mode;
4127 int ret = 0;
4128
4129 dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
4130
4131 switch (event) {
4132 case SND_SOC_DAPM_PRE_PMU:
4133 if ((!(strcmp(w->name, "ANC HPHL PA"))) &&
4134 (test_bit(HPH_PA_DELAY, &tasha->status_mask))) {
4135 snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0xC0, 0xC0);
4136 }
4137 set_bit(HPH_PA_DELAY, &tasha->status_mask);
4138 break;
4139 case SND_SOC_DAPM_POST_PMU:
4140 if (!(strcmp(w->name, "ANC HPHL PA"))) {
4141 if ((snd_soc_read(codec, WCD9335_ANA_HPH) & 0xC0)
4142 != 0xC0)
4143 /*
4144 * If PA_EN is not set (potentially in ANC case)
4145 * then do nothing for POST_PMU and let right
4146 * channel handle everything.
4147 */
4148 break;
4149 }
4150 /*
4151 * 7ms sleep is required after PA is enabled as per
4152 * HW requirement
4153 */
4154 if (test_bit(HPH_PA_DELAY, &tasha->status_mask)) {
4155 usleep_range(7000, 7100);
4156 clear_bit(HPH_PA_DELAY, &tasha->status_mask);
4157 }
4158
4159 tasha_codec_hph_post_pa_config(tasha, hph_mode, event);
4160 snd_soc_update_bits(codec, WCD9335_CDC_RX1_RX_PATH_CTL,
4161 0x10, 0x00);
4162 /* Remove mix path mute if it is enabled */
4163 if ((snd_soc_read(codec, WCD9335_CDC_RX1_RX_PATH_MIX_CTL)) &
4164 0x10)
4165 snd_soc_update_bits(codec,
4166 WCD9335_CDC_RX1_RX_PATH_MIX_CTL,
4167 0x10, 0x00);
4168
4169 if (!(strcmp(w->name, "ANC HPHL PA"))) {
4170 /* Do everything needed for right channel */
4171 snd_soc_update_bits(codec, WCD9335_CDC_RX2_RX_PATH_CTL,
4172 0x10, 0x00);
4173 /* Remove mix path mute if it is enabled */
4174 if ((snd_soc_read(codec,
4175 WCD9335_CDC_RX2_RX_PATH_MIX_CTL)) &
4176 0x10)
4177 snd_soc_update_bits(codec,
4178 WCD9335_CDC_RX2_RX_PATH_MIX_CTL,
4179 0x10, 0x00);
4180
4181 /* Remove ANC Rx from reset */
4182 ret = tasha_codec_enable_anc(w, kcontrol, event);
4183 }
4184 tasha_codec_override(codec, hph_mode, event);
4185 break;
4186 case SND_SOC_DAPM_PRE_PMD:
4187 blocking_notifier_call_chain(&tasha->notifier,
4188 WCD_EVENT_PRE_HPHL_PA_OFF,
4189 &tasha->mbhc);
4190 tasha_codec_hph_post_pa_config(tasha, hph_mode, event);
4191 if (!(strcmp(w->name, "ANC HPHL PA")))
4192 snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0x80, 0x00);
4193 break;
4194 case SND_SOC_DAPM_POST_PMD:
4195 /* 5ms sleep is required after PA is disabled as per
4196 * HW requirement
4197 */
4198 usleep_range(5000, 5500);
4199 tasha_codec_override(codec, hph_mode, event);
4200 blocking_notifier_call_chain(&tasha->notifier,
4201 WCD_EVENT_POST_HPHL_PA_OFF,
4202 &tasha->mbhc);
4203
4204 if (!(strcmp(w->name, "ANC HPHL PA"))) {
4205 ret = tasha_codec_enable_anc(w, kcontrol, event);
4206 snd_soc_update_bits(codec,
4207 WCD9335_CDC_RX1_RX_PATH_CFG0, 0x10, 0x00);
4208 }
4209 break;
4210 };
4211
4212 return ret;
4213}
4214
4215static int tasha_codec_enable_lineout_pa(struct snd_soc_dapm_widget *w,
4216 struct snd_kcontrol *kcontrol,
4217 int event)
4218{
4219 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
4220 u16 lineout_vol_reg = 0, lineout_mix_vol_reg = 0;
4221 int ret = 0;
4222
4223 dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
4224
4225 if (w->reg == WCD9335_ANA_LO_1_2) {
4226 if (w->shift == 7) {
4227 lineout_vol_reg = WCD9335_CDC_RX3_RX_PATH_CTL;
4228 lineout_mix_vol_reg = WCD9335_CDC_RX3_RX_PATH_MIX_CTL;
4229 } else if (w->shift == 6) {
4230 lineout_vol_reg = WCD9335_CDC_RX4_RX_PATH_CTL;
4231 lineout_mix_vol_reg = WCD9335_CDC_RX4_RX_PATH_MIX_CTL;
4232 }
4233 } else if (w->reg == WCD9335_ANA_LO_3_4) {
4234 if (w->shift == 7) {
4235 lineout_vol_reg = WCD9335_CDC_RX5_RX_PATH_CTL;
4236 lineout_mix_vol_reg = WCD9335_CDC_RX5_RX_PATH_MIX_CTL;
4237 } else if (w->shift == 6) {
4238 lineout_vol_reg = WCD9335_CDC_RX6_RX_PATH_CTL;
4239 lineout_mix_vol_reg = WCD9335_CDC_RX6_RX_PATH_MIX_CTL;
4240 }
4241 } else {
4242 dev_err(codec->dev, "%s: Error enabling lineout PA\n",
4243 __func__);
4244 return -EINVAL;
4245 }
4246
4247 switch (event) {
4248 case SND_SOC_DAPM_POST_PMU:
4249 /* 5ms sleep is required after PA is enabled as per
4250 * HW requirement
4251 */
4252 usleep_range(5000, 5500);
4253 snd_soc_update_bits(codec, lineout_vol_reg,
4254 0x10, 0x00);
4255 /* Remove mix path mute if it is enabled */
4256 if ((snd_soc_read(codec, lineout_mix_vol_reg)) & 0x10)
4257 snd_soc_update_bits(codec,
4258 lineout_mix_vol_reg,
4259 0x10, 0x00);
4260 if (!(strcmp(w->name, "ANC LINEOUT1 PA")) ||
4261 !(strcmp(w->name, "ANC LINEOUT2 PA")))
4262 ret = tasha_codec_enable_anc(w, kcontrol, event);
4263 tasha_codec_override(codec, CLS_AB, event);
4264 break;
4265 case SND_SOC_DAPM_POST_PMD:
4266 /* 5ms sleep is required after PA is disabled as per
4267 * HW requirement
4268 */
4269 usleep_range(5000, 5500);
4270 tasha_codec_override(codec, CLS_AB, event);
4271 if (!(strcmp(w->name, "ANC LINEOUT1 PA")) ||
4272 !(strcmp(w->name, "ANC LINEOUT2 PA"))) {
4273 ret = tasha_codec_enable_anc(w, kcontrol, event);
4274 if (!(strcmp(w->name, "ANC LINEOUT1 PA")))
4275 snd_soc_update_bits(codec,
4276 WCD9335_CDC_RX3_RX_PATH_CFG0, 0x10, 0x10);
4277 else
4278 snd_soc_update_bits(codec,
4279 WCD9335_CDC_RX4_RX_PATH_CFG0, 0x10, 0x10);
4280 }
4281 break;
4282 };
4283
4284 return ret;
4285}
4286
4287static void tasha_spk_anc_update_callback(struct work_struct *work)
4288{
4289 struct spk_anc_work *spk_anc_dwork;
4290 struct tasha_priv *tasha;
4291 struct delayed_work *delayed_work;
4292 struct snd_soc_codec *codec;
4293
4294 delayed_work = to_delayed_work(work);
4295 spk_anc_dwork = container_of(delayed_work, struct spk_anc_work, dwork);
4296 tasha = spk_anc_dwork->tasha;
4297 codec = tasha->codec;
4298
4299 snd_soc_update_bits(codec, WCD9335_CDC_RX7_RX_PATH_CFG0, 0x10, 0x10);
4300}
4301
4302static int tasha_codec_enable_spk_anc(struct snd_soc_dapm_widget *w,
4303 struct snd_kcontrol *kcontrol,
4304 int event)
4305{
4306 int ret = 0;
4307 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
4308 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
4309
4310 dev_dbg(codec->dev, "%s %s %d %d\n", __func__, w->name, event,
4311 tasha->anc_func);
4312
4313 if (!tasha->anc_func)
4314 return 0;
4315
4316 switch (event) {
4317 case SND_SOC_DAPM_PRE_PMU:
4318 ret = tasha_codec_enable_anc(w, kcontrol, event);
4319 schedule_delayed_work(&tasha->spk_anc_dwork.dwork,
4320 msecs_to_jiffies(spk_anc_en_delay));
4321 break;
4322 case SND_SOC_DAPM_POST_PMD:
4323 cancel_delayed_work_sync(&tasha->spk_anc_dwork.dwork);
4324 snd_soc_update_bits(codec, WCD9335_CDC_RX7_RX_PATH_CFG0,
4325 0x10, 0x00);
4326 ret = tasha_codec_enable_anc(w, kcontrol, event);
4327 break;
4328 }
4329 return ret;
4330}
4331
4332static int tasha_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
4333 struct snd_kcontrol *kcontrol,
4334 int event)
4335{
4336 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
4337 int ret = 0;
4338
4339 dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
4340
4341 switch (event) {
4342 case SND_SOC_DAPM_POST_PMU:
4343 /* 5ms sleep is required after PA is enabled as per
4344 * HW requirement
4345 */
4346 usleep_range(5000, 5500);
4347 snd_soc_update_bits(codec, WCD9335_CDC_RX0_RX_PATH_CTL,
4348 0x10, 0x00);
4349 /* Remove mix path mute if it is enabled */
4350 if ((snd_soc_read(codec, WCD9335_CDC_RX0_RX_PATH_MIX_CTL)) &
4351 0x10)
4352 snd_soc_update_bits(codec,
4353 WCD9335_CDC_RX0_RX_PATH_MIX_CTL,
4354 0x10, 0x00);
4355 break;
4356 case SND_SOC_DAPM_POST_PMD:
4357 /* 5ms sleep is required after PA is disabled as per
4358 * HW requirement
4359 */
4360 usleep_range(5000, 5500);
4361
4362 if (!(strcmp(w->name, "ANC EAR PA"))) {
4363 ret = tasha_codec_enable_anc(w, kcontrol, event);
4364 snd_soc_update_bits(codec,
4365 WCD9335_CDC_RX0_RX_PATH_CFG0, 0x10, 0x00);
4366 }
4367 break;
4368 };
4369
4370 return ret;
4371}
4372
4373static void tasha_codec_hph_mode_gain_opt(struct snd_soc_codec *codec,
4374 u8 gain)
4375{
4376 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
4377 u8 hph_l_en, hph_r_en;
4378 u8 l_val, r_val;
4379 u8 hph_pa_status;
4380 bool is_hphl_pa, is_hphr_pa;
4381
4382 hph_pa_status = snd_soc_read(codec, WCD9335_ANA_HPH);
4383 is_hphl_pa = hph_pa_status >> 7;
4384 is_hphr_pa = (hph_pa_status & 0x40) >> 6;
4385
4386 hph_l_en = snd_soc_read(codec, WCD9335_HPH_L_EN);
4387 hph_r_en = snd_soc_read(codec, WCD9335_HPH_R_EN);
4388
4389 l_val = (hph_l_en & 0xC0) | 0x20 | gain;
4390 r_val = (hph_r_en & 0xC0) | 0x20 | gain;
4391
4392 /*
4393 * Set HPH_L & HPH_R gain source selection to REGISTER
4394 * for better click and pop only if corresponding PAs are
4395 * not enabled. Also cache the values of the HPHL/R
4396 * PA gains to be applied after PAs are enabled
4397 */
4398 if ((l_val != hph_l_en) && !is_hphl_pa) {
4399 snd_soc_write(codec, WCD9335_HPH_L_EN, l_val);
4400 tasha->hph_l_gain = hph_l_en & 0x1F;
4401 }
4402
4403 if ((r_val != hph_r_en) && !is_hphr_pa) {
4404 snd_soc_write(codec, WCD9335_HPH_R_EN, r_val);
4405 tasha->hph_r_gain = hph_r_en & 0x1F;
4406 }
4407}
4408
4409static void tasha_codec_hph_lohifi_config(struct snd_soc_codec *codec,
4410 int event)
4411{
4412 if (SND_SOC_DAPM_EVENT_ON(event)) {
4413 snd_soc_update_bits(codec, WCD9335_RX_BIAS_HPH_PA, 0x0F, 0x06);
4414 snd_soc_update_bits(codec, WCD9335_RX_BIAS_HPH_RDACBUFF_CNP2,
4415 0xF0, 0x40);
4416 snd_soc_update_bits(codec, WCD9335_HPH_CNP_WG_CTL, 0x07, 0x03);
4417 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x08, 0x08);
4418 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL1, 0x0E, 0x0C);
4419 tasha_codec_hph_mode_gain_opt(codec, 0x11);
4420 }
4421
4422 if (SND_SOC_DAPM_EVENT_OFF(event)) {
4423 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x08, 0x00);
4424 snd_soc_update_bits(codec, WCD9335_HPH_CNP_WG_CTL, 0x07, 0x02);
4425 snd_soc_write(codec, WCD9335_RX_BIAS_HPH_RDACBUFF_CNP2, 0x8A);
4426 snd_soc_update_bits(codec, WCD9335_RX_BIAS_HPH_PA, 0x0F, 0x0A);
4427 }
4428}
4429
4430static void tasha_codec_hph_lp_config(struct snd_soc_codec *codec,
4431 int event)
4432{
4433 if (SND_SOC_DAPM_EVENT_ON(event)) {
4434 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL1, 0x0E, 0x0C);
4435 tasha_codec_hph_mode_gain_opt(codec, 0x10);
4436 snd_soc_update_bits(codec, WCD9335_HPH_CNP_WG_CTL, 0x07, 0x03);
4437 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x08, 0x08);
4438 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x04, 0x04);
4439 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x20, 0x20);
4440 snd_soc_update_bits(codec, WCD9335_HPH_RDAC_LDO_CTL, 0x07,
4441 0x01);
4442 snd_soc_update_bits(codec, WCD9335_HPH_RDAC_LDO_CTL, 0x70,
4443 0x10);
4444 snd_soc_update_bits(codec, WCD9335_RX_BIAS_HPH_RDAC_LDO,
4445 0x0F, 0x01);
4446 snd_soc_update_bits(codec, WCD9335_RX_BIAS_HPH_RDAC_LDO,
4447 0xF0, 0x10);
4448 }
4449
4450 if (SND_SOC_DAPM_EVENT_OFF(event)) {
4451 snd_soc_write(codec, WCD9335_RX_BIAS_HPH_RDAC_LDO, 0x88);
4452 snd_soc_write(codec, WCD9335_HPH_RDAC_LDO_CTL, 0x33);
4453 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x20, 0x00);
4454 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x04, 0x00);
4455 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x08, 0x00);
4456 snd_soc_update_bits(codec, WCD9335_HPH_CNP_WG_CTL, 0x07, 0x02);
4457 snd_soc_update_bits(codec, WCD9335_HPH_R_EN, 0xC0, 0x80);
4458 snd_soc_update_bits(codec, WCD9335_HPH_L_EN, 0xC0, 0x80);
4459 }
4460}
4461
4462static void tasha_codec_hph_hifi_config(struct snd_soc_codec *codec,
4463 int event)
4464{
4465 if (SND_SOC_DAPM_EVENT_ON(event)) {
4466 snd_soc_update_bits(codec, WCD9335_HPH_CNP_WG_CTL, 0x07, 0x03);
4467 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x08, 0x08);
4468 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL1, 0x0E, 0x0C);
4469 tasha_codec_hph_mode_gain_opt(codec, 0x11);
4470 }
4471
4472 if (SND_SOC_DAPM_EVENT_OFF(event)) {
4473 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x08, 0x00);
4474 snd_soc_update_bits(codec, WCD9335_HPH_CNP_WG_CTL, 0x07, 0x02);
4475 }
4476}
4477
4478static void tasha_codec_hph_mode_config(struct snd_soc_codec *codec,
4479 int event, int mode)
4480{
4481 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
4482
4483 if (!TASHA_IS_2_0(tasha->wcd9xxx))
4484 return;
4485
4486 switch (mode) {
4487 case CLS_H_LP:
4488 tasha_codec_hph_lp_config(codec, event);
4489 break;
4490 case CLS_H_LOHIFI:
4491 tasha_codec_hph_lohifi_config(codec, event);
4492 break;
4493 case CLS_H_HIFI:
4494 tasha_codec_hph_hifi_config(codec, event);
4495 break;
4496 }
4497}
4498
4499static int tasha_codec_hphr_dac_event(struct snd_soc_dapm_widget *w,
4500 struct snd_kcontrol *kcontrol,
4501 int event)
4502{
4503 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
4504 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
4505 struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent);
4506 int hph_mode = tasha->hph_mode;
4507 u8 dem_inp;
4508 int ret = 0;
4509
4510 dev_dbg(codec->dev, "%s wname: %s event: %d hph_mode: %d\n", __func__,
4511 w->name, event, hph_mode);
4512
4513 switch (event) {
4514 case SND_SOC_DAPM_PRE_PMU:
4515 if (tasha->anc_func) {
4516 ret = tasha_codec_enable_anc(w, kcontrol, event);
4517 /* 40 msec delay is needed to avoid click and pop */
4518 msleep(40);
4519 }
4520
4521 /* Read DEM INP Select */
4522 dem_inp = snd_soc_read(codec, WCD9335_CDC_RX2_RX_PATH_SEC0) &
4523 0x03;
4524 if (((hph_mode == CLS_H_HIFI) || (hph_mode == CLS_H_LOHIFI) ||
4525 (hph_mode == CLS_H_LP)) && (dem_inp != 0x01)) {
4526 dev_err(codec->dev, "%s: DEM Input not set correctly, hph_mode: %d\n",
4527 __func__, hph_mode);
4528 return -EINVAL;
4529 }
4530 wcd_clsh_fsm(codec, &tasha->clsh_d,
4531 WCD_CLSH_EVENT_PRE_DAC,
4532 WCD_CLSH_STATE_HPHR,
4533 ((hph_mode == CLS_H_LOHIFI) ?
4534 CLS_H_HIFI : hph_mode));
4535
4536 tasha_codec_hph_mode_config(codec, event, hph_mode);
4537
4538 if (tasha->anc_func)
4539 snd_soc_update_bits(codec,
4540 WCD9335_CDC_RX2_RX_PATH_CFG0, 0x10, 0x10);
4541
4542 break;
4543 case SND_SOC_DAPM_POST_PMU:
4544 /* 1000us required as per HW requirement */
4545 usleep_range(1000, 1100);
4546 if ((hph_mode == CLS_H_LP) &&
4547 (TASHA_IS_1_1(wcd9xxx))) {
4548 snd_soc_update_bits(codec, WCD9335_HPH_L_DAC_CTL,
4549 0x03, 0x03);
4550 }
4551 break;
4552 case SND_SOC_DAPM_PRE_PMD:
4553 if ((hph_mode == CLS_H_LP) &&
4554 (TASHA_IS_1_1(wcd9xxx))) {
4555 snd_soc_update_bits(codec, WCD9335_HPH_L_DAC_CTL,
4556 0x03, 0x00);
4557 }
4558 break;
4559 case SND_SOC_DAPM_POST_PMD:
4560 /* 1000us required as per HW requirement */
4561 usleep_range(1000, 1100);
4562
4563 if (!(wcd_clsh_get_clsh_state(&tasha->clsh_d) &
4564 WCD_CLSH_STATE_HPHL))
4565 tasha_codec_hph_mode_config(codec, event, hph_mode);
4566
4567 wcd_clsh_fsm(codec, &tasha->clsh_d,
4568 WCD_CLSH_EVENT_POST_PA,
4569 WCD_CLSH_STATE_HPHR,
4570 ((hph_mode == CLS_H_LOHIFI) ?
4571 CLS_H_HIFI : hph_mode));
4572 break;
4573 };
4574
4575 return ret;
4576}
4577
4578static int tasha_codec_hphl_dac_event(struct snd_soc_dapm_widget *w,
4579 struct snd_kcontrol *kcontrol,
4580 int event)
4581{
4582 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
4583 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
4584 struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent);
4585 int hph_mode = tasha->hph_mode;
4586 u8 dem_inp;
4587 int ret = 0;
4588 uint32_t impedl = 0, impedr = 0;
4589
4590 dev_dbg(codec->dev, "%s wname: %s event: %d hph_mode: %d\n", __func__,
4591 w->name, event, hph_mode);
4592
4593 switch (event) {
4594 case SND_SOC_DAPM_PRE_PMU:
4595 if (tasha->anc_func) {
4596 ret = tasha_codec_enable_anc(w, kcontrol, event);
4597 /* 40 msec delay is needed to avoid click and pop */
4598 msleep(40);
4599 }
4600
4601 /* Read DEM INP Select */
4602 dem_inp = snd_soc_read(codec, WCD9335_CDC_RX1_RX_PATH_SEC0) &
4603 0x03;
4604 if (((hph_mode == CLS_H_HIFI) || (hph_mode == CLS_H_LOHIFI) ||
4605 (hph_mode == CLS_H_LP)) && (dem_inp != 0x01)) {
4606 dev_err(codec->dev, "%s: DEM Input not set correctly, hph_mode: %d\n",
4607 __func__, hph_mode);
4608 return -EINVAL;
4609 }
4610 wcd_clsh_fsm(codec, &tasha->clsh_d,
4611 WCD_CLSH_EVENT_PRE_DAC,
4612 WCD_CLSH_STATE_HPHL,
4613 ((hph_mode == CLS_H_LOHIFI) ?
4614 CLS_H_HIFI : hph_mode));
4615
4616 tasha_codec_hph_mode_config(codec, event, hph_mode);
4617
4618 if (tasha->anc_func)
4619 snd_soc_update_bits(codec,
4620 WCD9335_CDC_RX1_RX_PATH_CFG0, 0x10, 0x10);
4621
4622 ret = wcd_mbhc_get_impedance(&tasha->mbhc,
4623 &impedl, &impedr);
4624 if (!ret) {
4625 wcd_clsh_imped_config(codec, impedl, false);
4626 set_bit(CLASSH_CONFIG, &tasha->status_mask);
4627 } else {
4628 dev_dbg(codec->dev, "%s: Failed to get mbhc impedance %d\n",
4629 __func__, ret);
4630 ret = 0;
4631 }
4632
4633
4634 break;
4635 case SND_SOC_DAPM_POST_PMU:
4636 /* 1000us required as per HW requirement */
4637 usleep_range(1000, 1100);
4638 if ((hph_mode == CLS_H_LP) &&
4639 (TASHA_IS_1_1(wcd9xxx))) {
4640 snd_soc_update_bits(codec, WCD9335_HPH_L_DAC_CTL,
4641 0x03, 0x03);
4642 }
4643 break;
4644 case SND_SOC_DAPM_PRE_PMD:
4645 if ((hph_mode == CLS_H_LP) &&
4646 (TASHA_IS_1_1(wcd9xxx))) {
4647 snd_soc_update_bits(codec, WCD9335_HPH_L_DAC_CTL,
4648 0x03, 0x00);
4649 }
4650 break;
4651 case SND_SOC_DAPM_POST_PMD:
4652 /* 1000us required as per HW requirement */
4653 usleep_range(1000, 1100);
4654
4655 if (!(wcd_clsh_get_clsh_state(&tasha->clsh_d) &
4656 WCD_CLSH_STATE_HPHR))
4657 tasha_codec_hph_mode_config(codec, event, hph_mode);
4658 wcd_clsh_fsm(codec, &tasha->clsh_d,
4659 WCD_CLSH_EVENT_POST_PA,
4660 WCD_CLSH_STATE_HPHL,
4661 ((hph_mode == CLS_H_LOHIFI) ?
4662 CLS_H_HIFI : hph_mode));
4663
4664 if (test_bit(CLASSH_CONFIG, &tasha->status_mask)) {
4665 wcd_clsh_imped_config(codec, impedl, true);
4666 clear_bit(CLASSH_CONFIG, &tasha->status_mask);
4667 } else
4668 dev_dbg(codec->dev, "%s: Failed to get mbhc impedance %d\n",
4669 __func__, ret);
4670
4671
4672 break;
4673 };
4674
4675 return ret;
4676}
4677
4678static int tasha_codec_lineout_dac_event(struct snd_soc_dapm_widget *w,
4679 struct snd_kcontrol *kcontrol,
4680 int event)
4681{
4682 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
4683 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
4684 int ret = 0;
4685
4686 dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
4687
4688 switch (event) {
4689 case SND_SOC_DAPM_PRE_PMU:
4690 if (tasha->anc_func &&
4691 (!strcmp(w->name, "RX INT3 DAC") ||
4692 !strcmp(w->name, "RX INT4 DAC")))
4693 ret = tasha_codec_enable_anc(w, kcontrol, event);
4694
4695 wcd_clsh_fsm(codec, &tasha->clsh_d,
4696 WCD_CLSH_EVENT_PRE_DAC,
4697 WCD_CLSH_STATE_LO,
4698 CLS_AB);
4699
4700 if (tasha->anc_func) {
4701 if (!strcmp(w->name, "RX INT3 DAC"))
4702 snd_soc_update_bits(codec,
4703 WCD9335_CDC_RX3_RX_PATH_CFG0, 0x10, 0x10);
4704 else if (!strcmp(w->name, "RX INT4 DAC"))
4705 snd_soc_update_bits(codec,
4706 WCD9335_CDC_RX4_RX_PATH_CFG0, 0x10, 0x10);
4707 }
4708 break;
4709 case SND_SOC_DAPM_POST_PMD:
4710 wcd_clsh_fsm(codec, &tasha->clsh_d,
4711 WCD_CLSH_EVENT_POST_PA,
4712 WCD_CLSH_STATE_LO,
4713 CLS_AB);
4714 break;
4715 }
4716
4717 return 0;
4718}
4719
4720static const struct snd_soc_dapm_widget tasha_dapm_i2s_widgets[] = {
4721 SND_SOC_DAPM_SUPPLY("RX_I2S_CTL", WCD9335_DATA_HUB_DATA_HUB_RX_I2S_CTL,
4722 0, 0, NULL, 0),
4723 SND_SOC_DAPM_SUPPLY("TX_I2S_CTL", WCD9335_DATA_HUB_DATA_HUB_TX_I2S_CTL,
4724 0, 0, NULL, 0),
4725};
4726
4727static int tasha_codec_ear_dac_event(struct snd_soc_dapm_widget *w,
4728 struct snd_kcontrol *kcontrol,
4729 int event)
4730{
4731 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
4732 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
4733 int ret = 0;
4734
4735 dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
4736
4737 switch (event) {
4738 case SND_SOC_DAPM_PRE_PMU:
4739 if (tasha->anc_func)
4740 ret = tasha_codec_enable_anc(w, kcontrol, event);
4741
4742 wcd_clsh_fsm(codec, &tasha->clsh_d,
4743 WCD_CLSH_EVENT_PRE_DAC,
4744 WCD_CLSH_STATE_EAR,
4745 CLS_H_NORMAL);
4746 if (tasha->anc_func)
4747 snd_soc_update_bits(codec,
4748 WCD9335_CDC_RX0_RX_PATH_CFG0, 0x10, 0x10);
4749
4750 break;
4751 case SND_SOC_DAPM_POST_PMU:
4752 break;
4753 case SND_SOC_DAPM_PRE_PMD:
4754 break;
4755 case SND_SOC_DAPM_POST_PMD:
4756 wcd_clsh_fsm(codec, &tasha->clsh_d,
4757 WCD_CLSH_EVENT_POST_PA,
4758 WCD_CLSH_STATE_EAR,
4759 CLS_H_NORMAL);
4760 break;
4761 };
4762
4763 return ret;
4764}
4765
4766static int tasha_codec_spk_boost_event(struct snd_soc_dapm_widget *w,
4767 struct snd_kcontrol *kcontrol,
4768 int event)
4769{
4770 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
4771 u16 boost_path_ctl, boost_path_cfg1;
4772 u16 reg, reg_mix;
4773
4774 dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
4775
4776 if (!strcmp(w->name, "RX INT7 CHAIN")) {
4777 boost_path_ctl = WCD9335_CDC_BOOST0_BOOST_PATH_CTL;
4778 boost_path_cfg1 = WCD9335_CDC_RX7_RX_PATH_CFG1;
4779 reg = WCD9335_CDC_RX7_RX_PATH_CTL;
4780 reg_mix = WCD9335_CDC_RX7_RX_PATH_MIX_CTL;
4781 } else if (!strcmp(w->name, "RX INT8 CHAIN")) {
4782 boost_path_ctl = WCD9335_CDC_BOOST1_BOOST_PATH_CTL;
4783 boost_path_cfg1 = WCD9335_CDC_RX8_RX_PATH_CFG1;
4784 reg = WCD9335_CDC_RX8_RX_PATH_CTL;
4785 reg_mix = WCD9335_CDC_RX8_RX_PATH_MIX_CTL;
4786 } else {
4787 dev_err(codec->dev, "%s: unknown widget: %s\n",
4788 __func__, w->name);
4789 return -EINVAL;
4790 }
4791
4792 switch (event) {
4793 case SND_SOC_DAPM_PRE_PMU:
4794 snd_soc_update_bits(codec, boost_path_ctl, 0x10, 0x10);
4795 snd_soc_update_bits(codec, boost_path_cfg1, 0x01, 0x01);
4796 snd_soc_update_bits(codec, reg, 0x10, 0x00);
4797 if ((snd_soc_read(codec, reg_mix)) & 0x10)
4798 snd_soc_update_bits(codec, reg_mix, 0x10, 0x00);
4799 break;
4800 case SND_SOC_DAPM_POST_PMD:
4801 snd_soc_update_bits(codec, boost_path_cfg1, 0x01, 0x00);
4802 snd_soc_update_bits(codec, boost_path_ctl, 0x10, 0x00);
4803 break;
4804 };
4805
4806 return 0;
4807}
4808
4809static u16 tasha_interp_get_primary_reg(u16 reg, u16 *ind)
4810{
4811 u16 prim_int_reg = 0;
4812
4813 switch (reg) {
4814 case WCD9335_CDC_RX0_RX_PATH_CTL:
4815 case WCD9335_CDC_RX0_RX_PATH_MIX_CTL:
4816 prim_int_reg = WCD9335_CDC_RX0_RX_PATH_CTL;
4817 *ind = 0;
4818 break;
4819 case WCD9335_CDC_RX1_RX_PATH_CTL:
4820 case WCD9335_CDC_RX1_RX_PATH_MIX_CTL:
4821 prim_int_reg = WCD9335_CDC_RX1_RX_PATH_CTL;
4822 *ind = 1;
4823 break;
4824 case WCD9335_CDC_RX2_RX_PATH_CTL:
4825 case WCD9335_CDC_RX2_RX_PATH_MIX_CTL:
4826 prim_int_reg = WCD9335_CDC_RX2_RX_PATH_CTL;
4827 *ind = 2;
4828 break;
4829 case WCD9335_CDC_RX3_RX_PATH_CTL:
4830 case WCD9335_CDC_RX3_RX_PATH_MIX_CTL:
4831 prim_int_reg = WCD9335_CDC_RX3_RX_PATH_CTL;
4832 *ind = 3;
4833 break;
4834 case WCD9335_CDC_RX4_RX_PATH_CTL:
4835 case WCD9335_CDC_RX4_RX_PATH_MIX_CTL:
4836 prim_int_reg = WCD9335_CDC_RX4_RX_PATH_CTL;
4837 *ind = 4;
4838 break;
4839 case WCD9335_CDC_RX5_RX_PATH_CTL:
4840 case WCD9335_CDC_RX5_RX_PATH_MIX_CTL:
4841 prim_int_reg = WCD9335_CDC_RX5_RX_PATH_CTL;
4842 *ind = 5;
4843 break;
4844 case WCD9335_CDC_RX6_RX_PATH_CTL:
4845 case WCD9335_CDC_RX6_RX_PATH_MIX_CTL:
4846 prim_int_reg = WCD9335_CDC_RX6_RX_PATH_CTL;
4847 *ind = 6;
4848 break;
4849 case WCD9335_CDC_RX7_RX_PATH_CTL:
4850 case WCD9335_CDC_RX7_RX_PATH_MIX_CTL:
4851 prim_int_reg = WCD9335_CDC_RX7_RX_PATH_CTL;
4852 *ind = 7;
4853 break;
4854 case WCD9335_CDC_RX8_RX_PATH_CTL:
4855 case WCD9335_CDC_RX8_RX_PATH_MIX_CTL:
4856 prim_int_reg = WCD9335_CDC_RX8_RX_PATH_CTL;
4857 *ind = 8;
4858 break;
4859 };
4860
4861 return prim_int_reg;
4862}
4863
4864static void tasha_codec_hd2_control(struct snd_soc_codec *codec,
4865 u16 prim_int_reg, int event)
4866{
4867 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
4868 u16 hd2_scale_reg;
4869 u16 hd2_enable_reg = 0;
4870
4871 if (!TASHA_IS_2_0(tasha->wcd9xxx))
4872 return;
4873
4874 if (prim_int_reg == WCD9335_CDC_RX1_RX_PATH_CTL) {
4875 hd2_scale_reg = WCD9335_CDC_RX1_RX_PATH_SEC3;
4876 hd2_enable_reg = WCD9335_CDC_RX1_RX_PATH_CFG0;
4877 }
4878 if (prim_int_reg == WCD9335_CDC_RX2_RX_PATH_CTL) {
4879 hd2_scale_reg = WCD9335_CDC_RX2_RX_PATH_SEC3;
4880 hd2_enable_reg = WCD9335_CDC_RX2_RX_PATH_CFG0;
4881 }
4882
4883 if (hd2_enable_reg && SND_SOC_DAPM_EVENT_ON(event)) {
4884 snd_soc_update_bits(codec, hd2_scale_reg, 0x3C, 0x10);
4885 snd_soc_update_bits(codec, hd2_scale_reg, 0x03, 0x01);
4886 snd_soc_update_bits(codec, hd2_enable_reg, 0x04, 0x04);
4887 }
4888
4889 if (hd2_enable_reg && SND_SOC_DAPM_EVENT_OFF(event)) {
4890 snd_soc_update_bits(codec, hd2_enable_reg, 0x04, 0x00);
4891 snd_soc_update_bits(codec, hd2_scale_reg, 0x03, 0x00);
4892 snd_soc_update_bits(codec, hd2_scale_reg, 0x3C, 0x00);
4893 }
4894}
4895
4896static int tasha_codec_enable_prim_interpolator(
4897 struct snd_soc_codec *codec,
4898 u16 reg, int event)
4899{
4900 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
4901 u16 prim_int_reg;
4902 u16 ind = 0;
4903
4904 prim_int_reg = tasha_interp_get_primary_reg(reg, &ind);
4905
4906 switch (event) {
4907 case SND_SOC_DAPM_PRE_PMU:
4908 tasha->prim_int_users[ind]++;
4909 if (tasha->prim_int_users[ind] == 1) {
4910 snd_soc_update_bits(codec, prim_int_reg,
4911 0x10, 0x10);
4912 tasha_codec_hd2_control(codec, prim_int_reg, event);
4913 snd_soc_update_bits(codec, prim_int_reg,
4914 1 << 0x5, 1 << 0x5);
4915 }
4916 if ((reg != prim_int_reg) &&
4917 ((snd_soc_read(codec, prim_int_reg)) & 0x10))
4918 snd_soc_update_bits(codec, reg, 0x10, 0x10);
4919 break;
4920 case SND_SOC_DAPM_POST_PMD:
4921 tasha->prim_int_users[ind]--;
4922 if (tasha->prim_int_users[ind] == 0) {
4923 snd_soc_update_bits(codec, prim_int_reg,
4924 1 << 0x5, 0 << 0x5);
4925 snd_soc_update_bits(codec, prim_int_reg,
4926 0x40, 0x40);
4927 snd_soc_update_bits(codec, prim_int_reg,
4928 0x40, 0x00);
4929 tasha_codec_hd2_control(codec, prim_int_reg, event);
4930 }
4931 break;
4932 };
4933
4934 dev_dbg(codec->dev, "%s: primary interpolator: INT%d, users: %d\n",
4935 __func__, ind, tasha->prim_int_users[ind]);
4936 return 0;
4937}
4938
4939static int tasha_codec_enable_spline_src(struct snd_soc_codec *codec,
4940 int src_num,
4941 int event)
4942{
4943 u16 src_paired_reg;
4944 struct tasha_priv *tasha;
4945 u16 rx_path_cfg_reg = WCD9335_CDC_RX1_RX_PATH_CFG0;
4946 u16 rx_path_ctl_reg = WCD9335_CDC_RX1_RX_PATH_CTL;
4947 int *src_users, count, spl_src = SPLINE_SRC0;
4948 u16 src_clk_reg = WCD9335_SPLINE_SRC0_CLK_RST_CTL_0;
4949
4950 tasha = snd_soc_codec_get_drvdata(codec);
4951
4952 switch (src_num) {
4953 case SRC_IN_HPHL:
4954 rx_path_cfg_reg = WCD9335_CDC_RX1_RX_PATH_CFG0;
4955 src_clk_reg = WCD9335_SPLINE_SRC0_CLK_RST_CTL_0;
4956 src_paired_reg = WCD9335_SPLINE_SRC1_CLK_RST_CTL_0;
4957 rx_path_ctl_reg = WCD9335_CDC_RX1_RX_PATH_CTL;
4958 spl_src = SPLINE_SRC0;
4959 break;
4960 case SRC_IN_LO1:
4961 rx_path_cfg_reg = WCD9335_CDC_RX3_RX_PATH_CFG0;
4962 src_clk_reg = WCD9335_SPLINE_SRC0_CLK_RST_CTL_0;
4963 src_paired_reg = WCD9335_SPLINE_SRC1_CLK_RST_CTL_0;
4964 rx_path_ctl_reg = WCD9335_CDC_RX3_RX_PATH_CTL;
4965 spl_src = SPLINE_SRC0;
4966 break;
4967 case SRC_IN_HPHR:
4968 rx_path_cfg_reg = WCD9335_CDC_RX2_RX_PATH_CFG0;
4969 src_clk_reg = WCD9335_SPLINE_SRC1_CLK_RST_CTL_0;
4970 src_paired_reg = WCD9335_SPLINE_SRC0_CLK_RST_CTL_0;
4971 rx_path_ctl_reg = WCD9335_CDC_RX2_RX_PATH_CTL;
4972 spl_src = SPLINE_SRC1;
4973 break;
4974 case SRC_IN_LO2:
4975 rx_path_cfg_reg = WCD9335_CDC_RX4_RX_PATH_CFG0;
4976 src_clk_reg = WCD9335_SPLINE_SRC1_CLK_RST_CTL_0;
4977 src_paired_reg = WCD9335_SPLINE_SRC0_CLK_RST_CTL_0;
4978 rx_path_ctl_reg = WCD9335_CDC_RX4_RX_PATH_CTL;
4979 spl_src = SPLINE_SRC1;
4980 break;
4981 case SRC_IN_SPKRL:
4982 rx_path_cfg_reg = WCD9335_CDC_RX7_RX_PATH_CFG0;
4983 src_clk_reg = WCD9335_SPLINE_SRC2_CLK_RST_CTL_0;
4984 src_paired_reg = WCD9335_SPLINE_SRC3_CLK_RST_CTL_0;
4985 rx_path_ctl_reg = WCD9335_CDC_RX7_RX_PATH_CTL;
4986 spl_src = SPLINE_SRC2;
4987 break;
4988 case SRC_IN_LO3:
4989 rx_path_cfg_reg = WCD9335_CDC_RX5_RX_PATH_CFG0;
4990 src_clk_reg = WCD9335_SPLINE_SRC2_CLK_RST_CTL_0;
4991 src_paired_reg = WCD9335_SPLINE_SRC3_CLK_RST_CTL_0;
4992 rx_path_ctl_reg = WCD9335_CDC_RX5_RX_PATH_CTL;
4993 spl_src = SPLINE_SRC2;
4994 break;
4995 case SRC_IN_SPKRR:
4996 rx_path_cfg_reg = WCD9335_CDC_RX8_RX_PATH_CFG0;
4997 src_clk_reg = WCD9335_SPLINE_SRC3_CLK_RST_CTL_0;
4998 src_paired_reg = WCD9335_SPLINE_SRC2_CLK_RST_CTL_0;
4999 rx_path_ctl_reg = WCD9335_CDC_RX8_RX_PATH_CTL;
5000 spl_src = SPLINE_SRC3;
5001 break;
5002 case SRC_IN_LO4:
5003 rx_path_cfg_reg = WCD9335_CDC_RX6_RX_PATH_CFG0;
5004 src_clk_reg = WCD9335_SPLINE_SRC3_CLK_RST_CTL_0;
5005 src_paired_reg = WCD9335_SPLINE_SRC2_CLK_RST_CTL_0;
5006 rx_path_ctl_reg = WCD9335_CDC_RX6_RX_PATH_CTL;
5007 spl_src = SPLINE_SRC3;
5008 break;
5009 };
5010
5011 src_users = &tasha->spl_src_users[spl_src];
5012
5013 switch (event) {
5014 case SND_SOC_DAPM_PRE_PMU:
5015 count = *src_users;
5016 count++;
5017 if (count == 1) {
5018 if ((snd_soc_read(codec, src_clk_reg) & 0x02) ||
5019 (snd_soc_read(codec, src_paired_reg) & 0x02)) {
5020 snd_soc_update_bits(codec, src_clk_reg, 0x02,
5021 0x00);
5022 snd_soc_update_bits(codec, src_paired_reg,
5023 0x02, 0x00);
5024 }
5025 snd_soc_update_bits(codec, src_clk_reg, 0x01, 0x01);
5026 snd_soc_update_bits(codec, rx_path_cfg_reg, 0x80,
5027 0x80);
5028 }
5029 *src_users = count;
5030 break;
5031 case SND_SOC_DAPM_POST_PMD:
5032 count = *src_users;
5033 count--;
5034 if (count == 0) {
5035 snd_soc_update_bits(codec, rx_path_cfg_reg, 0x80,
5036 0x00);
5037 snd_soc_update_bits(codec, src_clk_reg, 0x03, 0x02);
5038 /* default sample rate */
5039 snd_soc_update_bits(codec, rx_path_ctl_reg, 0x0f,
5040 0x04);
5041 }
5042 *src_users = count;
5043 break;
5044 };
5045
5046 dev_dbg(codec->dev, "%s: Spline SRC%d, users: %d\n",
5047 __func__, spl_src, *src_users);
5048 return 0;
5049}
5050
5051static int tasha_codec_enable_spline_resampler(struct snd_soc_dapm_widget *w,
5052 struct snd_kcontrol *kcontrol,
5053 int event)
5054{
5055 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
5056 int ret = 0;
5057 u8 src_in;
5058
5059 src_in = snd_soc_read(codec, WCD9335_CDC_RX_INP_MUX_SPLINE_SRC_CFG0);
5060 if (!(src_in & 0xFF)) {
5061 dev_err(codec->dev, "%s: Spline SRC%u input not selected\n",
5062 __func__, w->shift);
5063 return -EINVAL;
5064 }
5065
5066 switch (w->shift) {
5067 case SPLINE_SRC0:
5068 ret = tasha_codec_enable_spline_src(codec,
5069 ((src_in & 0x03) == 1) ? SRC_IN_HPHL : SRC_IN_LO1,
5070 event);
5071 break;
5072 case SPLINE_SRC1:
5073 ret = tasha_codec_enable_spline_src(codec,
5074 ((src_in & 0x0C) == 4) ? SRC_IN_HPHR : SRC_IN_LO2,
5075 event);
5076 break;
5077 case SPLINE_SRC2:
5078 ret = tasha_codec_enable_spline_src(codec,
5079 ((src_in & 0x30) == 0x10) ? SRC_IN_LO3 : SRC_IN_SPKRL,
5080 event);
5081 break;
5082 case SPLINE_SRC3:
5083 ret = tasha_codec_enable_spline_src(codec,
5084 ((src_in & 0xC0) == 0x40) ? SRC_IN_LO4 : SRC_IN_SPKRR,
5085 event);
5086 break;
5087 default:
5088 dev_err(codec->dev, "%s: Invalid spline src:%u\n", __func__,
5089 w->shift);
5090 ret = -EINVAL;
5091 };
5092
5093 return ret;
5094}
5095
5096static int tasha_codec_enable_swr(struct snd_soc_dapm_widget *w,
5097 struct snd_kcontrol *kcontrol, int event)
5098{
5099 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
5100 struct tasha_priv *tasha;
5101 int i, ch_cnt;
5102
5103 tasha = snd_soc_codec_get_drvdata(codec);
5104
5105 if (!tasha->nr)
5106 return 0;
5107
5108 switch (event) {
5109 case SND_SOC_DAPM_PRE_PMU:
5110 if ((strnstr(w->name, "INT7_", sizeof("RX INT7_"))) &&
5111 !tasha->rx_7_count)
5112 tasha->rx_7_count++;
5113 if ((strnstr(w->name, "INT8_", sizeof("RX INT8_"))) &&
5114 !tasha->rx_8_count)
5115 tasha->rx_8_count++;
5116 ch_cnt = tasha->rx_7_count + tasha->rx_8_count;
5117
5118 for (i = 0; i < tasha->nr; i++) {
5119 swrm_wcd_notify(tasha->swr_ctrl_data[i].swr_pdev,
5120 SWR_DEVICE_UP, NULL);
5121 swrm_wcd_notify(tasha->swr_ctrl_data[i].swr_pdev,
5122 SWR_SET_NUM_RX_CH, &ch_cnt);
5123 }
5124 break;
5125 case SND_SOC_DAPM_POST_PMD:
5126 if ((strnstr(w->name, "INT7_", sizeof("RX INT7_"))) &&
5127 tasha->rx_7_count)
5128 tasha->rx_7_count--;
5129 if ((strnstr(w->name, "INT8_", sizeof("RX INT8_"))) &&
5130 tasha->rx_8_count)
5131 tasha->rx_8_count--;
5132 ch_cnt = tasha->rx_7_count + tasha->rx_8_count;
5133
5134 for (i = 0; i < tasha->nr; i++)
5135 swrm_wcd_notify(tasha->swr_ctrl_data[i].swr_pdev,
5136 SWR_SET_NUM_RX_CH, &ch_cnt);
5137
5138 break;
5139 }
5140 dev_dbg(tasha->dev, "%s: current swr ch cnt: %d\n",
5141 __func__, tasha->rx_7_count + tasha->rx_8_count);
5142
5143 return 0;
5144}
5145
5146static int tasha_codec_config_ear_spkr_gain(struct snd_soc_codec *codec,
5147 int event, int gain_reg)
5148{
5149 int comp_gain_offset, val;
5150 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
5151
5152 switch (tasha->spkr_mode) {
5153 /* Compander gain in SPKR_MODE1 case is 12 dB */
5154 case SPKR_MODE_1:
5155 comp_gain_offset = -12;
5156 break;
5157 /* Default case compander gain is 15 dB */
5158 default:
5159 comp_gain_offset = -15;
5160 break;
5161 }
5162
5163 switch (event) {
5164 case SND_SOC_DAPM_POST_PMU:
5165 /* Apply ear spkr gain only if compander is enabled */
5166 if (tasha->comp_enabled[COMPANDER_7] &&
5167 (gain_reg == WCD9335_CDC_RX7_RX_VOL_CTL ||
5168 gain_reg == WCD9335_CDC_RX7_RX_VOL_MIX_CTL) &&
5169 (tasha->ear_spkr_gain != 0)) {
5170 /* For example, val is -8(-12+5-1) for 4dB of gain */
5171 val = comp_gain_offset + tasha->ear_spkr_gain - 1;
5172 snd_soc_write(codec, gain_reg, val);
5173
5174 dev_dbg(codec->dev, "%s: RX7 Volume %d dB\n",
5175 __func__, val);
5176 }
5177 break;
5178 case SND_SOC_DAPM_POST_PMD:
5179 /*
5180 * Reset RX7 volume to 0 dB if compander is enabled and
5181 * ear_spkr_gain is non-zero.
5182 */
5183 if (tasha->comp_enabled[COMPANDER_7] &&
5184 (gain_reg == WCD9335_CDC_RX7_RX_VOL_CTL ||
5185 gain_reg == WCD9335_CDC_RX7_RX_VOL_MIX_CTL) &&
5186 (tasha->ear_spkr_gain != 0)) {
5187 snd_soc_write(codec, gain_reg, 0x0);
5188
5189 dev_dbg(codec->dev, "%s: Reset RX7 Volume to 0 dB\n",
5190 __func__);
5191 }
5192 break;
5193 }
5194
5195 return 0;
5196}
5197
5198static int tasha_codec_enable_mix_path(struct snd_soc_dapm_widget *w,
5199 struct snd_kcontrol *kcontrol, int event)
5200{
5201 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
5202 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
5203 u16 gain_reg;
5204 int offset_val = 0;
5205 int val = 0;
5206
5207 dev_dbg(codec->dev, "%s %d %s\n", __func__, event, w->name);
5208
5209 switch (w->reg) {
5210 case WCD9335_CDC_RX0_RX_PATH_MIX_CTL:
5211 gain_reg = WCD9335_CDC_RX0_RX_VOL_MIX_CTL;
5212 break;
5213 case WCD9335_CDC_RX1_RX_PATH_MIX_CTL:
5214 gain_reg = WCD9335_CDC_RX1_RX_VOL_MIX_CTL;
5215 break;
5216 case WCD9335_CDC_RX2_RX_PATH_MIX_CTL:
5217 gain_reg = WCD9335_CDC_RX2_RX_VOL_MIX_CTL;
5218 break;
5219 case WCD9335_CDC_RX3_RX_PATH_MIX_CTL:
5220 gain_reg = WCD9335_CDC_RX3_RX_VOL_MIX_CTL;
5221 break;
5222 case WCD9335_CDC_RX4_RX_PATH_MIX_CTL:
5223 gain_reg = WCD9335_CDC_RX4_RX_VOL_MIX_CTL;
5224 break;
5225 case WCD9335_CDC_RX5_RX_PATH_MIX_CTL:
5226 gain_reg = WCD9335_CDC_RX5_RX_VOL_MIX_CTL;
5227 break;
5228 case WCD9335_CDC_RX6_RX_PATH_MIX_CTL:
5229 gain_reg = WCD9335_CDC_RX6_RX_VOL_MIX_CTL;
5230 break;
5231 case WCD9335_CDC_RX7_RX_PATH_MIX_CTL:
5232 gain_reg = WCD9335_CDC_RX7_RX_VOL_MIX_CTL;
5233 break;
5234 case WCD9335_CDC_RX8_RX_PATH_MIX_CTL:
5235 gain_reg = WCD9335_CDC_RX8_RX_VOL_MIX_CTL;
5236 break;
5237 default:
5238 dev_err(codec->dev, "%s: No gain register avail for %s\n",
5239 __func__, w->name);
5240 return 0;
5241 };
5242
5243 switch (event) {
5244 case SND_SOC_DAPM_POST_PMU:
5245 if ((tasha->spkr_gain_offset == RX_GAIN_OFFSET_M1P5_DB) &&
5246 (tasha->comp_enabled[COMPANDER_7] ||
5247 tasha->comp_enabled[COMPANDER_8]) &&
5248 (gain_reg == WCD9335_CDC_RX7_RX_VOL_MIX_CTL ||
5249 gain_reg == WCD9335_CDC_RX8_RX_VOL_MIX_CTL)) {
5250 snd_soc_update_bits(codec, WCD9335_CDC_RX7_RX_PATH_SEC1,
5251 0x01, 0x01);
5252 snd_soc_update_bits(codec,
5253 WCD9335_CDC_RX7_RX_PATH_MIX_SEC0,
5254 0x01, 0x01);
5255 snd_soc_update_bits(codec, WCD9335_CDC_RX8_RX_PATH_SEC1,
5256 0x01, 0x01);
5257 snd_soc_update_bits(codec,
5258 WCD9335_CDC_RX8_RX_PATH_MIX_SEC0,
5259 0x01, 0x01);
5260 offset_val = -2;
5261 }
5262 val = snd_soc_read(codec, gain_reg);
5263 val += offset_val;
5264 snd_soc_write(codec, gain_reg, val);
5265 tasha_codec_config_ear_spkr_gain(codec, event, gain_reg);
5266 break;
5267 case SND_SOC_DAPM_POST_PMD:
5268 if ((tasha->spkr_gain_offset == RX_GAIN_OFFSET_M1P5_DB) &&
5269 (tasha->comp_enabled[COMPANDER_7] ||
5270 tasha->comp_enabled[COMPANDER_8]) &&
5271 (gain_reg == WCD9335_CDC_RX7_RX_VOL_MIX_CTL ||
5272 gain_reg == WCD9335_CDC_RX8_RX_VOL_MIX_CTL)) {
5273 snd_soc_update_bits(codec, WCD9335_CDC_RX7_RX_PATH_SEC1,
5274 0x01, 0x00);
5275 snd_soc_update_bits(codec,
5276 WCD9335_CDC_RX7_RX_PATH_MIX_SEC0,
5277 0x01, 0x00);
5278 snd_soc_update_bits(codec, WCD9335_CDC_RX8_RX_PATH_SEC1,
5279 0x01, 0x00);
5280 snd_soc_update_bits(codec,
5281 WCD9335_CDC_RX8_RX_PATH_MIX_SEC0,
5282 0x01, 0x00);
5283 offset_val = 2;
5284 val = snd_soc_read(codec, gain_reg);
5285 val += offset_val;
5286 snd_soc_write(codec, gain_reg, val);
5287 }
5288 tasha_codec_config_ear_spkr_gain(codec, event, gain_reg);
5289 break;
5290 };
5291
5292 return 0;
5293}
5294
5295static int __tasha_cdc_native_clk_enable(struct tasha_priv *tasha,
5296 bool enable)
5297{
5298 int ret = 0;
5299 struct snd_soc_codec *codec = tasha->codec;
5300
5301 if (!tasha->wcd_native_clk) {
5302 dev_err(tasha->dev, "%s: wcd native clock is NULL\n", __func__);
5303 return -EINVAL;
5304 }
5305
5306 dev_dbg(tasha->dev, "%s: native_clk_enable = %u\n", __func__, enable);
5307
5308 if (enable) {
5309 ret = clk_prepare_enable(tasha->wcd_native_clk);
5310 if (ret) {
5311 dev_err(tasha->dev, "%s: native clk enable failed\n",
5312 __func__);
5313 goto err;
5314 }
5315 if (++tasha->native_clk_users == 1) {
5316 snd_soc_update_bits(codec, WCD9335_CLOCK_TEST_CTL,
5317 0x10, 0x10);
5318 snd_soc_update_bits(codec, WCD9335_CLOCK_TEST_CTL,
5319 0x80, 0x80);
5320 snd_soc_update_bits(codec, WCD9335_CODEC_RPM_CLK_GATE,
5321 0x04, 0x00);
5322 snd_soc_update_bits(codec,
5323 WCD9335_CDC_CLK_RST_CTRL_MCLK_CONTROL,
5324 0x02, 0x02);
5325 }
5326 } else {
5327 if (tasha->native_clk_users &&
5328 (--tasha->native_clk_users == 0)) {
5329 snd_soc_update_bits(codec,
5330 WCD9335_CDC_CLK_RST_CTRL_MCLK_CONTROL,
5331 0x02, 0x00);
5332 snd_soc_update_bits(codec, WCD9335_CODEC_RPM_CLK_GATE,
5333 0x04, 0x04);
5334 snd_soc_update_bits(codec, WCD9335_CLOCK_TEST_CTL,
5335 0x80, 0x00);
5336 snd_soc_update_bits(codec, WCD9335_CLOCK_TEST_CTL,
5337 0x10, 0x00);
5338 }
5339 clk_disable_unprepare(tasha->wcd_native_clk);
5340 }
5341
5342 dev_dbg(codec->dev, "%s: native_clk_users: %d\n", __func__,
5343 tasha->native_clk_users);
5344err:
5345 return ret;
5346}
5347
5348static int tasha_codec_get_native_fifo_sync_mask(struct snd_soc_codec *codec,
5349 int interp_n)
5350{
5351 int mask = 0;
5352 u16 reg;
5353 u8 val1, val2, inp0 = 0;
5354 u8 inp1 = 0, inp2 = 0;
5355
5356 reg = WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG0 + (2 * interp_n) - 2;
5357
5358 val1 = snd_soc_read(codec, reg);
5359 val2 = snd_soc_read(codec, reg + 1);
5360
5361 inp0 = val1 & 0x0F;
5362 inp1 = (val1 >> 4) & 0x0F;
5363 inp2 = (val2 >> 4) & 0x0F;
5364
5365 if (IS_VALID_NATIVE_FIFO_PORT(inp0))
5366 mask |= (1 << (inp0 - 5));
5367 if (IS_VALID_NATIVE_FIFO_PORT(inp1))
5368 mask |= (1 << (inp1 - 5));
5369 if (IS_VALID_NATIVE_FIFO_PORT(inp2))
5370 mask |= (1 << (inp2 - 5));
5371
5372 dev_dbg(codec->dev, "%s: native fifo mask: 0x%x\n", __func__, mask);
5373 if (!mask)
5374 dev_err(codec->dev, "native fifo err,int:%d,inp0:%d,inp1:%d,inp2:%d\n",
5375 interp_n, inp0, inp1, inp2);
5376 return mask;
5377}
5378
5379static int tasha_enable_native_supply(struct snd_soc_dapm_widget *w,
5380 struct snd_kcontrol *kcontrol, int event)
5381{
5382 int mask;
5383 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
5384 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
5385 u16 interp_reg;
5386
5387 dev_dbg(codec->dev, "%s: event: %d, shift:%d\n", __func__, event,
5388 w->shift);
5389
5390 if (w->shift < INTERP_HPHL || w->shift > INTERP_LO2)
5391 return -EINVAL;
5392
5393 interp_reg = WCD9335_CDC_RX1_RX_PATH_CTL + 20 * (w->shift - 1);
5394
5395 mask = tasha_codec_get_native_fifo_sync_mask(codec, w->shift);
5396 if (!mask)
5397 return -EINVAL;
5398
5399 switch (event) {
5400 case SND_SOC_DAPM_PRE_PMU:
5401 /* Adjust interpolator rate to 44P1_NATIVE */
5402 snd_soc_update_bits(codec, interp_reg, 0x0F, 0x09);
5403 __tasha_cdc_native_clk_enable(tasha, true);
5404 snd_soc_update_bits(codec, WCD9335_DATA_HUB_NATIVE_FIFO_SYNC,
5405 mask, mask);
5406 break;
5407 case SND_SOC_DAPM_PRE_PMD:
5408 snd_soc_update_bits(codec, WCD9335_DATA_HUB_NATIVE_FIFO_SYNC,
5409 mask, 0x0);
5410 __tasha_cdc_native_clk_enable(tasha, false);
5411 /* Adjust interpolator rate to default */
5412 snd_soc_update_bits(codec, interp_reg, 0x0F, 0x04);
5413 break;
5414 }
5415
5416 return 0;
5417}
5418
5419static int tasha_codec_enable_interpolator(struct snd_soc_dapm_widget *w,
5420 struct snd_kcontrol *kcontrol, int event)
5421{
5422 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
5423 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
5424 u16 gain_reg;
5425 u16 reg;
5426 int val;
5427 int offset_val = 0;
5428
5429 dev_dbg(codec->dev, "%s %d %s\n", __func__, event, w->name);
5430
5431 if (!(strcmp(w->name, "RX INT0 INTERP"))) {
5432 reg = WCD9335_CDC_RX0_RX_PATH_CTL;
5433 gain_reg = WCD9335_CDC_RX0_RX_VOL_CTL;
5434 } else if (!(strcmp(w->name, "RX INT1 INTERP"))) {
5435 reg = WCD9335_CDC_RX1_RX_PATH_CTL;
5436 gain_reg = WCD9335_CDC_RX1_RX_VOL_CTL;
5437 } else if (!(strcmp(w->name, "RX INT2 INTERP"))) {
5438 reg = WCD9335_CDC_RX2_RX_PATH_CTL;
5439 gain_reg = WCD9335_CDC_RX2_RX_VOL_CTL;
5440 } else if (!(strcmp(w->name, "RX INT3 INTERP"))) {
5441 reg = WCD9335_CDC_RX3_RX_PATH_CTL;
5442 gain_reg = WCD9335_CDC_RX3_RX_VOL_CTL;
5443 } else if (!(strcmp(w->name, "RX INT4 INTERP"))) {
5444 reg = WCD9335_CDC_RX4_RX_PATH_CTL;
5445 gain_reg = WCD9335_CDC_RX4_RX_VOL_CTL;
5446 } else if (!(strcmp(w->name, "RX INT5 INTERP"))) {
5447 reg = WCD9335_CDC_RX5_RX_PATH_CTL;
5448 gain_reg = WCD9335_CDC_RX5_RX_VOL_CTL;
5449 } else if (!(strcmp(w->name, "RX INT6 INTERP"))) {
5450 reg = WCD9335_CDC_RX6_RX_PATH_CTL;
5451 gain_reg = WCD9335_CDC_RX6_RX_VOL_CTL;
5452 } else if (!(strcmp(w->name, "RX INT7 INTERP"))) {
5453 reg = WCD9335_CDC_RX7_RX_PATH_CTL;
5454 gain_reg = WCD9335_CDC_RX7_RX_VOL_CTL;
5455 } else if (!(strcmp(w->name, "RX INT8 INTERP"))) {
5456 reg = WCD9335_CDC_RX8_RX_PATH_CTL;
5457 gain_reg = WCD9335_CDC_RX8_RX_VOL_CTL;
5458 } else {
5459 dev_err(codec->dev, "%s: Interpolator reg not found\n",
5460 __func__);
5461 return -EINVAL;
5462 }
5463
5464 switch (event) {
5465 case SND_SOC_DAPM_PRE_PMU:
5466 if (!test_bit(SB_CLK_GEAR, &tasha->status_mask)) {
5467 tasha_codec_vote_max_bw(codec, true);
5468 set_bit(SB_CLK_GEAR, &tasha->status_mask);
5469 }
5470 /* Reset if needed */
5471 tasha_codec_enable_prim_interpolator(codec, reg, event);
5472 break;
5473 case SND_SOC_DAPM_POST_PMU:
5474 tasha_config_compander(codec, w->shift, event);
5475 /* apply gain after int clk is enabled */
5476 if ((tasha->spkr_gain_offset == RX_GAIN_OFFSET_M1P5_DB) &&
5477 (tasha->comp_enabled[COMPANDER_7] ||
5478 tasha->comp_enabled[COMPANDER_8]) &&
5479 (gain_reg == WCD9335_CDC_RX7_RX_VOL_CTL ||
5480 gain_reg == WCD9335_CDC_RX8_RX_VOL_CTL)) {
5481 snd_soc_update_bits(codec, WCD9335_CDC_RX7_RX_PATH_SEC1,
5482 0x01, 0x01);
5483 snd_soc_update_bits(codec,
5484 WCD9335_CDC_RX7_RX_PATH_MIX_SEC0,
5485 0x01, 0x01);
5486 snd_soc_update_bits(codec, WCD9335_CDC_RX8_RX_PATH_SEC1,
5487 0x01, 0x01);
5488 snd_soc_update_bits(codec,
5489 WCD9335_CDC_RX8_RX_PATH_MIX_SEC0,
5490 0x01, 0x01);
5491 offset_val = -2;
5492 }
5493 val = snd_soc_read(codec, gain_reg);
5494 val += offset_val;
5495 snd_soc_write(codec, gain_reg, val);
5496 tasha_codec_config_ear_spkr_gain(codec, event, gain_reg);
5497 break;
5498 case SND_SOC_DAPM_POST_PMD:
5499 tasha_config_compander(codec, w->shift, event);
5500 tasha_codec_enable_prim_interpolator(codec, reg, event);
5501 if ((tasha->spkr_gain_offset == RX_GAIN_OFFSET_M1P5_DB) &&
5502 (tasha->comp_enabled[COMPANDER_7] ||
5503 tasha->comp_enabled[COMPANDER_8]) &&
5504 (gain_reg == WCD9335_CDC_RX7_RX_VOL_CTL ||
5505 gain_reg == WCD9335_CDC_RX8_RX_VOL_CTL)) {
5506 snd_soc_update_bits(codec, WCD9335_CDC_RX7_RX_PATH_SEC1,
5507 0x01, 0x00);
5508 snd_soc_update_bits(codec,
5509 WCD9335_CDC_RX7_RX_PATH_MIX_SEC0,
5510 0x01, 0x00);
5511 snd_soc_update_bits(codec, WCD9335_CDC_RX8_RX_PATH_SEC1,
5512 0x01, 0x00);
5513 snd_soc_update_bits(codec,
5514 WCD9335_CDC_RX8_RX_PATH_MIX_SEC0,
5515 0x01, 0x00);
5516 offset_val = 2;
5517 val = snd_soc_read(codec, gain_reg);
5518 val += offset_val;
5519 snd_soc_write(codec, gain_reg, val);
5520 }
5521 tasha_codec_config_ear_spkr_gain(codec, event, gain_reg);
5522 break;
5523 };
5524
5525 return 0;
5526}
5527
5528static int tasha_codec_set_iir_gain(struct snd_soc_dapm_widget *w,
5529 struct snd_kcontrol *kcontrol, int event)
5530{
5531 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
5532
5533 dev_dbg(codec->dev, "%s: event = %d\n", __func__, event);
5534
5535 switch (event) {
5536 case SND_SOC_DAPM_POST_PMU: /* fall through */
5537 case SND_SOC_DAPM_PRE_PMD:
5538 if (strnstr(w->name, "IIR0", sizeof("IIR0"))) {
5539 snd_soc_write(codec,
5540 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL,
5541 snd_soc_read(codec,
5542 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL));
5543 snd_soc_write(codec,
5544 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL,
5545 snd_soc_read(codec,
5546 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL));
5547 snd_soc_write(codec,
5548 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL,
5549 snd_soc_read(codec,
5550 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL));
5551 snd_soc_write(codec,
5552 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL,
5553 snd_soc_read(codec,
5554 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL));
5555 } else {
5556 snd_soc_write(codec,
5557 WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B1_CTL,
5558 snd_soc_read(codec,
5559 WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B1_CTL));
5560 snd_soc_write(codec,
5561 WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B2_CTL,
5562 snd_soc_read(codec,
5563 WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B2_CTL));
5564 snd_soc_write(codec,
5565 WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B3_CTL,
5566 snd_soc_read(codec,
5567 WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B3_CTL));
5568 }
5569 break;
5570 }
5571 return 0;
5572}
5573
5574static int tasha_codec_enable_on_demand_supply(
5575 struct snd_soc_dapm_widget *w,
5576 struct snd_kcontrol *kcontrol, int event)
5577{
5578 int ret = 0;
5579 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
5580 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
5581 struct on_demand_supply *supply;
5582
5583 if (w->shift >= ON_DEMAND_SUPPLIES_MAX) {
5584 dev_err(codec->dev, "%s: error index > MAX Demand supplies",
5585 __func__);
5586 ret = -EINVAL;
5587 goto out;
5588 }
5589
5590 dev_dbg(codec->dev, "%s: supply: %s event: %d\n",
5591 __func__, on_demand_supply_name[w->shift], event);
5592
5593 supply = &tasha->on_demand_list[w->shift];
5594 WARN_ONCE(!supply->supply, "%s isn't defined\n",
5595 on_demand_supply_name[w->shift]);
5596 if (!supply->supply) {
5597 dev_err(codec->dev, "%s: err supply not present ond for %d",
5598 __func__, w->shift);
5599 goto out;
5600 }
5601
5602 switch (event) {
5603 case SND_SOC_DAPM_PRE_PMU:
5604 ret = regulator_enable(supply->supply);
5605 if (ret)
5606 dev_err(codec->dev, "%s: Failed to enable %s\n",
5607 __func__,
5608 on_demand_supply_name[w->shift]);
5609 break;
5610 case SND_SOC_DAPM_POST_PMD:
5611 ret = regulator_disable(supply->supply);
5612 if (ret)
5613 dev_err(codec->dev, "%s: Failed to disable %s\n",
5614 __func__,
5615 on_demand_supply_name[w->shift]);
5616 break;
5617 default:
5618 break;
5619 };
5620
5621out:
5622 return ret;
5623}
5624
5625static int tasha_codec_find_amic_input(struct snd_soc_codec *codec,
5626 int adc_mux_n)
5627{
5628 u16 mask, shift, adc_mux_in_reg;
5629 u16 amic_mux_sel_reg;
5630 bool is_amic;
5631
5632 if (adc_mux_n < 0 || adc_mux_n > WCD9335_MAX_VALID_ADC_MUX ||
5633 adc_mux_n == WCD9335_INVALID_ADC_MUX)
5634 return 0;
5635
5636 /* Check whether adc mux input is AMIC or DMIC */
5637 if (adc_mux_n < 4) {
5638 adc_mux_in_reg = WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG1 +
5639 2 * adc_mux_n;
5640 amic_mux_sel_reg = WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG0 +
5641 2 * adc_mux_n;
5642 mask = 0x03;
5643 shift = 0;
5644 } else {
5645 adc_mux_in_reg = WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0 +
5646 adc_mux_n - 4;
5647 amic_mux_sel_reg = adc_mux_in_reg;
5648 mask = 0xC0;
5649 shift = 6;
5650 }
5651 is_amic = (((snd_soc_read(codec, adc_mux_in_reg) & mask) >> shift)
5652 == 1);
5653 if (!is_amic)
5654 return 0;
5655
5656 return snd_soc_read(codec, amic_mux_sel_reg) & 0x07;
5657}
5658
5659static void tasha_codec_set_tx_hold(struct snd_soc_codec *codec,
5660 u16 amic_reg, bool set)
5661{
5662 u8 mask = 0x20;
5663 u8 val;
5664
5665 if (amic_reg == WCD9335_ANA_AMIC1 ||
5666 amic_reg == WCD9335_ANA_AMIC3 ||
5667 amic_reg == WCD9335_ANA_AMIC5)
5668 mask = 0x40;
5669
5670 val = set ? mask : 0x00;
5671
5672 switch (amic_reg) {
5673 case WCD9335_ANA_AMIC1:
5674 case WCD9335_ANA_AMIC2:
5675 snd_soc_update_bits(codec, WCD9335_ANA_AMIC2, mask, val);
5676 break;
5677 case WCD9335_ANA_AMIC3:
5678 case WCD9335_ANA_AMIC4:
5679 snd_soc_update_bits(codec, WCD9335_ANA_AMIC4, mask, val);
5680 break;
5681 case WCD9335_ANA_AMIC5:
5682 case WCD9335_ANA_AMIC6:
5683 snd_soc_update_bits(codec, WCD9335_ANA_AMIC6, mask, val);
5684 break;
5685 default:
5686 dev_dbg(codec->dev, "%s: invalid amic: %d\n",
5687 __func__, amic_reg);
5688 break;
5689 }
5690}
5691
5692static int tasha_codec_tx_adc_cfg(struct snd_soc_dapm_widget *w,
5693 struct snd_kcontrol *kcontrol, int event)
5694{
5695 int adc_mux_n = w->shift;
5696 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
5697 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
5698 int amic_n;
5699
5700 dev_dbg(codec->dev, "%s: event: %d\n", __func__, event);
5701
5702 switch (event) {
5703 case SND_SOC_DAPM_POST_PMU:
5704 amic_n = tasha_codec_find_amic_input(codec, adc_mux_n);
5705 if (amic_n) {
5706 /*
5707 * Prevent ANC Rx pop by leaving Tx FE in HOLD
5708 * state until PA is up. Track AMIC being used
5709 * so we can release the HOLD later.
5710 */
5711 set_bit(ANC_MIC_AMIC1 + amic_n - 1,
5712 &tasha->status_mask);
5713 }
5714 break;
5715 default:
5716 break;
5717 }
5718
5719 return 0;
5720}
5721
5722static u16 tasha_codec_get_amic_pwlvl_reg(struct snd_soc_codec *codec, int amic)
5723{
5724 u16 pwr_level_reg = 0;
5725
5726 switch (amic) {
5727 case 1:
5728 case 2:
5729 pwr_level_reg = WCD9335_ANA_AMIC1;
5730 break;
5731
5732 case 3:
5733 case 4:
5734 pwr_level_reg = WCD9335_ANA_AMIC3;
5735 break;
5736
5737 case 5:
5738 case 6:
5739 pwr_level_reg = WCD9335_ANA_AMIC5;
5740 break;
5741 default:
5742 dev_dbg(codec->dev, "%s: invalid amic: %d\n",
5743 __func__, amic);
5744 break;
5745 }
5746
5747 return pwr_level_reg;
5748}
5749
5750#define TX_HPF_CUT_OFF_FREQ_MASK 0x60
5751#define CF_MIN_3DB_4HZ 0x0
5752#define CF_MIN_3DB_75HZ 0x1
5753#define CF_MIN_3DB_150HZ 0x2
5754
5755static void tasha_tx_hpf_corner_freq_callback(struct work_struct *work)
5756{
5757 struct delayed_work *hpf_delayed_work;
5758 struct hpf_work *hpf_work;
5759 struct tasha_priv *tasha;
5760 struct snd_soc_codec *codec;
5761 u16 dec_cfg_reg, amic_reg;
5762 u8 hpf_cut_off_freq;
5763 int amic_n;
5764
5765 hpf_delayed_work = to_delayed_work(work);
5766 hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork);
5767 tasha = hpf_work->tasha;
5768 codec = tasha->codec;
5769 hpf_cut_off_freq = hpf_work->hpf_cut_off_freq;
5770
5771 dec_cfg_reg = WCD9335_CDC_TX0_TX_PATH_CFG0 + 16 * hpf_work->decimator;
5772
5773 dev_dbg(codec->dev, "%s: decimator %u hpf_cut_of_freq 0x%x\n",
5774 __func__, hpf_work->decimator, hpf_cut_off_freq);
5775
5776 amic_n = tasha_codec_find_amic_input(codec, hpf_work->decimator);
5777 if (amic_n) {
5778 amic_reg = WCD9335_ANA_AMIC1 + amic_n - 1;
5779 tasha_codec_set_tx_hold(codec, amic_reg, false);
5780 }
5781 tasha_codec_vote_max_bw(codec, true);
5782 snd_soc_update_bits(codec, dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK,
5783 hpf_cut_off_freq << 5);
5784 tasha_codec_vote_max_bw(codec, false);
5785}
5786
5787static void tasha_tx_mute_update_callback(struct work_struct *work)
5788{
5789 struct tx_mute_work *tx_mute_dwork;
5790 struct tasha_priv *tasha;
5791 struct delayed_work *delayed_work;
5792 struct snd_soc_codec *codec;
5793 u16 tx_vol_ctl_reg, hpf_gate_reg;
5794
5795 delayed_work = to_delayed_work(work);
5796 tx_mute_dwork = container_of(delayed_work, struct tx_mute_work, dwork);
5797 tasha = tx_mute_dwork->tasha;
5798 codec = tasha->codec;
5799
5800 tx_vol_ctl_reg = WCD9335_CDC_TX0_TX_PATH_CTL +
5801 16 * tx_mute_dwork->decimator;
5802 hpf_gate_reg = WCD9335_CDC_TX0_TX_PATH_SEC2 +
5803 16 * tx_mute_dwork->decimator;
5804 snd_soc_update_bits(codec, hpf_gate_reg, 0x01, 0x01);
5805 snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x00);
5806}
5807
5808static int tasha_codec_enable_dec(struct snd_soc_dapm_widget *w,
5809 struct snd_kcontrol *kcontrol, int event)
5810{
5811 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
5812 unsigned int decimator;
5813 char *dec_adc_mux_name = NULL;
5814 char *widget_name = NULL;
5815 char *wname;
5816 int ret = 0, amic_n;
5817 u16 tx_vol_ctl_reg, pwr_level_reg = 0, dec_cfg_reg, hpf_gate_reg;
5818 u16 tx_gain_ctl_reg;
5819 char *dec;
5820 u8 hpf_cut_off_freq;
5821 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
5822
5823 dev_dbg(codec->dev, "%s %d\n", __func__, event);
5824
5825 widget_name = kstrndup(w->name, 15, GFP_KERNEL);
5826 if (!widget_name)
5827 return -ENOMEM;
5828
5829 wname = widget_name;
5830 dec_adc_mux_name = strsep(&widget_name, " ");
5831 if (!dec_adc_mux_name) {
5832 dev_err(codec->dev, "%s: Invalid decimator = %s\n",
5833 __func__, w->name);
5834 ret = -EINVAL;
5835 goto out;
5836 }
5837 dec_adc_mux_name = widget_name;
5838
5839 dec = strpbrk(dec_adc_mux_name, "012345678");
5840 if (!dec) {
5841 dev_err(codec->dev, "%s: decimator index not found\n",
5842 __func__);
5843 ret = -EINVAL;
5844 goto out;
5845 }
5846
5847 ret = kstrtouint(dec, 10, &decimator);
5848 if (ret < 0) {
5849 dev_err(codec->dev, "%s: Invalid decimator = %s\n",
5850 __func__, wname);
5851 ret = -EINVAL;
5852 goto out;
5853 }
5854
5855 dev_dbg(codec->dev, "%s(): widget = %s decimator = %u\n", __func__,
5856 w->name, decimator);
5857
5858 tx_vol_ctl_reg = WCD9335_CDC_TX0_TX_PATH_CTL + 16 * decimator;
5859 hpf_gate_reg = WCD9335_CDC_TX0_TX_PATH_SEC2 + 16 * decimator;
5860 dec_cfg_reg = WCD9335_CDC_TX0_TX_PATH_CFG0 + 16 * decimator;
5861 tx_gain_ctl_reg = WCD9335_CDC_TX0_TX_VOL_CTL + 16 * decimator;
5862
5863 switch (event) {
5864 case SND_SOC_DAPM_PRE_PMU:
5865 amic_n = tasha_codec_find_amic_input(codec, decimator);
5866 if (amic_n)
5867 pwr_level_reg = tasha_codec_get_amic_pwlvl_reg(codec,
5868 amic_n);
5869
5870 if (pwr_level_reg) {
5871 switch ((snd_soc_read(codec, pwr_level_reg) &
5872 WCD9335_AMIC_PWR_LVL_MASK) >>
5873 WCD9335_AMIC_PWR_LVL_SHIFT) {
5874 case WCD9335_AMIC_PWR_LEVEL_LP:
5875 snd_soc_update_bits(codec, dec_cfg_reg,
5876 WCD9335_DEC_PWR_LVL_MASK,
5877 WCD9335_DEC_PWR_LVL_LP);
5878 break;
5879
5880 case WCD9335_AMIC_PWR_LEVEL_HP:
5881 snd_soc_update_bits(codec, dec_cfg_reg,
5882 WCD9335_DEC_PWR_LVL_MASK,
5883 WCD9335_DEC_PWR_LVL_HP);
5884 break;
5885 case WCD9335_AMIC_PWR_LEVEL_DEFAULT:
5886 default:
5887 snd_soc_update_bits(codec, dec_cfg_reg,
5888 WCD9335_DEC_PWR_LVL_MASK,
5889 WCD9335_DEC_PWR_LVL_DF);
5890 break;
5891 }
5892 }
5893 hpf_cut_off_freq = (snd_soc_read(codec, dec_cfg_reg) &
5894 TX_HPF_CUT_OFF_FREQ_MASK) >> 5;
5895 tasha->tx_hpf_work[decimator].hpf_cut_off_freq =
5896 hpf_cut_off_freq;
5897
5898 if (hpf_cut_off_freq != CF_MIN_3DB_150HZ)
5899 snd_soc_update_bits(codec, dec_cfg_reg,
5900 TX_HPF_CUT_OFF_FREQ_MASK,
5901 CF_MIN_3DB_150HZ << 5);
5902 /* Enable TX PGA Mute */
5903 snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x10);
5904 /* Enable APC */
5905 snd_soc_update_bits(codec, dec_cfg_reg, 0x08, 0x08);
5906 break;
5907 case SND_SOC_DAPM_POST_PMU:
5908 snd_soc_update_bits(codec, hpf_gate_reg, 0x01, 0x00);
5909
5910 if (decimator == 0) {
5911 snd_soc_write(codec, WCD9335_MBHC_ZDET_RAMP_CTL, 0x83);
5912 snd_soc_write(codec, WCD9335_MBHC_ZDET_RAMP_CTL, 0xA3);
5913 snd_soc_write(codec, WCD9335_MBHC_ZDET_RAMP_CTL, 0x83);
5914 snd_soc_write(codec, WCD9335_MBHC_ZDET_RAMP_CTL, 0x03);
5915 }
5916 /* schedule work queue to Remove Mute */
5917 schedule_delayed_work(&tasha->tx_mute_dwork[decimator].dwork,
5918 msecs_to_jiffies(tx_unmute_delay));
5919 if (tasha->tx_hpf_work[decimator].hpf_cut_off_freq !=
5920 CF_MIN_3DB_150HZ)
5921 schedule_delayed_work(
5922 &tasha->tx_hpf_work[decimator].dwork,
5923 msecs_to_jiffies(300));
5924 /* apply gain after decimator is enabled */
5925 snd_soc_write(codec, tx_gain_ctl_reg,
5926 snd_soc_read(codec, tx_gain_ctl_reg));
5927 break;
5928 case SND_SOC_DAPM_PRE_PMD:
5929 hpf_cut_off_freq =
5930 tasha->tx_hpf_work[decimator].hpf_cut_off_freq;
5931 snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x10);
5932 snd_soc_update_bits(codec, dec_cfg_reg, 0x08, 0x00);
5933 if (cancel_delayed_work_sync(
5934 &tasha->tx_hpf_work[decimator].dwork)) {
5935 if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) {
5936 tasha_codec_vote_max_bw(codec, true);
5937 snd_soc_update_bits(codec, dec_cfg_reg,
5938 TX_HPF_CUT_OFF_FREQ_MASK,
5939 hpf_cut_off_freq << 5);
5940 tasha_codec_vote_max_bw(codec, false);
5941 }
5942 }
5943 cancel_delayed_work_sync(
5944 &tasha->tx_mute_dwork[decimator].dwork);
5945 break;
5946 case SND_SOC_DAPM_POST_PMD:
5947 snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x00);
5948 break;
5949 };
5950out:
5951 kfree(wname);
5952 return ret;
5953}
5954
5955static u32 tasha_get_dmic_sample_rate(struct snd_soc_codec *codec,
5956 unsigned int dmic, struct wcd9xxx_pdata *pdata)
5957{
5958 u8 tx_stream_fs;
5959 u8 adc_mux_index = 0, adc_mux_sel = 0;
5960 bool dec_found = false;
5961 u16 adc_mux_ctl_reg, tx_fs_reg;
5962 u32 dmic_fs;
5963
5964 while (dec_found == 0 && adc_mux_index < WCD9335_MAX_VALID_ADC_MUX) {
5965 if (adc_mux_index < 4) {
5966 adc_mux_ctl_reg = WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG0 +
5967 (adc_mux_index * 2);
5968 adc_mux_sel = ((snd_soc_read(codec, adc_mux_ctl_reg) &
5969 0x78) >> 3) - 1;
5970 } else if (adc_mux_index < 9) {
5971 adc_mux_ctl_reg = WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0 +
5972 ((adc_mux_index - 4) * 1);
5973 adc_mux_sel = ((snd_soc_read(codec, adc_mux_ctl_reg) &
5974 0x38) >> 3) - 1;
5975 } else if (adc_mux_index == 9) {
5976 ++adc_mux_index;
5977 continue;
5978 }
5979 if (adc_mux_sel == dmic)
5980 dec_found = true;
5981 else
5982 ++adc_mux_index;
5983 }
5984
5985 if (dec_found == true && adc_mux_index <= 8) {
5986 tx_fs_reg = WCD9335_CDC_TX0_TX_PATH_CTL + (16 * adc_mux_index);
5987 tx_stream_fs = snd_soc_read(codec, tx_fs_reg) & 0x0F;
5988 dmic_fs = tx_stream_fs <= 4 ? WCD9XXX_DMIC_SAMPLE_RATE_2P4MHZ :
5989 WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ;
5990
5991 /*
5992 * Check for ECPP path selection and DEC1 not connected to
5993 * any other audio path to apply ECPP DMIC sample rate
5994 */
5995 if ((adc_mux_index == 1) &&
5996 ((snd_soc_read(codec, WCD9335_CPE_SS_US_EC_MUX_CFG)
5997 & 0x0F) == 0x0A) &&
5998 ((snd_soc_read(codec, WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0)
5999 & 0x0C) == 0x00)) {
6000 dmic_fs = pdata->ecpp_dmic_sample_rate;
6001 }
6002 } else {
6003 dmic_fs = pdata->dmic_sample_rate;
6004 }
6005
6006 return dmic_fs;
6007}
6008
6009static u8 tasha_get_dmic_clk_val(struct snd_soc_codec *codec,
6010 u32 mclk_rate, u32 dmic_clk_rate)
6011{
6012 u32 div_factor;
6013 u8 dmic_ctl_val;
6014
6015 dev_dbg(codec->dev,
6016 "%s: mclk_rate = %d, dmic_sample_rate = %d\n",
6017 __func__, mclk_rate, dmic_clk_rate);
6018
6019 /* Default value to return in case of error */
6020 if (mclk_rate == TASHA_MCLK_CLK_9P6MHZ)
6021 dmic_ctl_val = WCD9335_DMIC_CLK_DIV_2;
6022 else
6023 dmic_ctl_val = WCD9335_DMIC_CLK_DIV_3;
6024
6025 if (dmic_clk_rate == 0) {
6026 dev_err(codec->dev,
6027 "%s: dmic_sample_rate cannot be 0\n",
6028 __func__);
6029 goto done;
6030 }
6031
6032 div_factor = mclk_rate / dmic_clk_rate;
6033 switch (div_factor) {
6034 case 2:
6035 dmic_ctl_val = WCD9335_DMIC_CLK_DIV_2;
6036 break;
6037 case 3:
6038 dmic_ctl_val = WCD9335_DMIC_CLK_DIV_3;
6039 break;
6040 case 4:
6041 dmic_ctl_val = WCD9335_DMIC_CLK_DIV_4;
6042 break;
6043 case 6:
6044 dmic_ctl_val = WCD9335_DMIC_CLK_DIV_6;
6045 break;
6046 case 8:
6047 dmic_ctl_val = WCD9335_DMIC_CLK_DIV_8;
6048 break;
6049 case 16:
6050 dmic_ctl_val = WCD9335_DMIC_CLK_DIV_16;
6051 break;
6052 default:
6053 dev_err(codec->dev,
6054 "%s: Invalid div_factor %u, clk_rate(%u), dmic_rate(%u)\n",
6055 __func__, div_factor, mclk_rate, dmic_clk_rate);
6056 break;
6057 }
6058
6059done:
6060 return dmic_ctl_val;
6061}
6062
6063static int tasha_codec_enable_adc(struct snd_soc_dapm_widget *w,
6064 struct snd_kcontrol *kcontrol, int event)
6065{
6066 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
6067
6068 dev_dbg(codec->dev, "%s: event:%d\n", __func__, event);
6069
6070 switch (event) {
6071 case SND_SOC_DAPM_PRE_PMU:
6072 tasha_codec_set_tx_hold(codec, w->reg, true);
6073 break;
6074 default:
6075 break;
6076 }
6077
6078 return 0;
6079}
6080
6081static int tasha_codec_enable_dmic(struct snd_soc_dapm_widget *w,
6082 struct snd_kcontrol *kcontrol, int event)
6083{
6084 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
6085 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
6086 struct wcd9xxx_pdata *pdata = dev_get_platdata(codec->dev->parent);
6087 u8 dmic_clk_en = 0x01;
6088 u16 dmic_clk_reg;
6089 s32 *dmic_clk_cnt;
6090 u8 dmic_rate_val, dmic_rate_shift = 1;
6091 unsigned int dmic;
6092 u32 dmic_sample_rate;
6093 int ret;
6094 char *wname;
6095
6096 wname = strpbrk(w->name, "012345");
6097 if (!wname) {
6098 dev_err(codec->dev, "%s: widget not found\n", __func__);
6099 return -EINVAL;
6100 }
6101
6102 ret = kstrtouint(wname, 10, &dmic);
6103 if (ret < 0) {
6104 dev_err(codec->dev, "%s: Invalid DMIC line on the codec\n",
6105 __func__);
6106 return -EINVAL;
6107 }
6108
6109 switch (dmic) {
6110 case 0:
6111 case 1:
6112 dmic_clk_cnt = &(tasha->dmic_0_1_clk_cnt);
6113 dmic_clk_reg = WCD9335_CPE_SS_DMIC0_CTL;
6114 break;
6115 case 2:
6116 case 3:
6117 dmic_clk_cnt = &(tasha->dmic_2_3_clk_cnt);
6118 dmic_clk_reg = WCD9335_CPE_SS_DMIC1_CTL;
6119 break;
6120 case 4:
6121 case 5:
6122 dmic_clk_cnt = &(tasha->dmic_4_5_clk_cnt);
6123 dmic_clk_reg = WCD9335_CPE_SS_DMIC2_CTL;
6124 break;
6125 default:
6126 dev_err(codec->dev, "%s: Invalid DMIC Selection\n",
6127 __func__);
6128 return -EINVAL;
6129 };
6130 dev_dbg(codec->dev, "%s: event %d DMIC%d dmic_clk_cnt %d\n",
6131 __func__, event, dmic, *dmic_clk_cnt);
6132
6133 switch (event) {
6134 case SND_SOC_DAPM_PRE_PMU:
6135 dmic_sample_rate = tasha_get_dmic_sample_rate(codec, dmic,
6136 pdata);
6137 dmic_rate_val =
6138 tasha_get_dmic_clk_val(codec,
6139 pdata->mclk_rate,
6140 dmic_sample_rate);
6141
6142 (*dmic_clk_cnt)++;
6143 if (*dmic_clk_cnt == 1) {
6144 snd_soc_update_bits(codec, dmic_clk_reg,
6145 0x07 << dmic_rate_shift,
6146 dmic_rate_val << dmic_rate_shift);
6147 snd_soc_update_bits(codec, dmic_clk_reg,
6148 dmic_clk_en, dmic_clk_en);
6149 }
6150
6151 break;
6152 case SND_SOC_DAPM_POST_PMD:
6153 dmic_rate_val =
6154 tasha_get_dmic_clk_val(codec,
6155 pdata->mclk_rate,
6156 pdata->mad_dmic_sample_rate);
6157 (*dmic_clk_cnt)--;
6158 if (*dmic_clk_cnt == 0) {
6159 snd_soc_update_bits(codec, dmic_clk_reg,
6160 dmic_clk_en, 0);
6161 snd_soc_update_bits(codec, dmic_clk_reg,
6162 0x07 << dmic_rate_shift,
6163 dmic_rate_val << dmic_rate_shift);
6164 }
6165 break;
6166 };
6167
6168 return 0;
6169}
6170
6171static int __tasha_codec_enable_micbias(struct snd_soc_dapm_widget *w,
6172 int event)
6173{
6174 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
6175 int micb_num;
6176
6177 dev_dbg(codec->dev, "%s: wname: %s, event: %d\n",
6178 __func__, w->name, event);
6179
6180 if (strnstr(w->name, "MIC BIAS1", sizeof("MIC BIAS1")))
6181 micb_num = MIC_BIAS_1;
6182 else if (strnstr(w->name, "MIC BIAS2", sizeof("MIC BIAS2")))
6183 micb_num = MIC_BIAS_2;
6184 else if (strnstr(w->name, "MIC BIAS3", sizeof("MIC BIAS3")))
6185 micb_num = MIC_BIAS_3;
6186 else if (strnstr(w->name, "MIC BIAS4", sizeof("MIC BIAS4")))
6187 micb_num = MIC_BIAS_4;
6188 else
6189 return -EINVAL;
6190
6191 switch (event) {
6192 case SND_SOC_DAPM_PRE_PMU:
6193 /*
6194 * MIC BIAS can also be requested by MBHC,
6195 * so use ref count to handle micbias pullup
6196 * and enable requests
6197 */
6198 tasha_micbias_control(codec, micb_num, MICB_ENABLE, true);
6199 break;
6200 case SND_SOC_DAPM_POST_PMU:
6201 /* wait for cnp time */
6202 usleep_range(1000, 1100);
6203 break;
6204 case SND_SOC_DAPM_POST_PMD:
6205 tasha_micbias_control(codec, micb_num, MICB_DISABLE, true);
6206 break;
6207 };
6208
6209 return 0;
6210}
6211
6212static int tasha_codec_ldo_h_control(struct snd_soc_dapm_widget *w,
6213 int event)
6214{
6215 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
6216 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
6217
6218 if (SND_SOC_DAPM_EVENT_ON(event)) {
6219 tasha->ldo_h_users++;
6220
6221 if (tasha->ldo_h_users == 1)
6222 snd_soc_update_bits(codec, WCD9335_LDOH_MODE,
6223 0x80, 0x80);
6224 }
6225
6226 if (SND_SOC_DAPM_EVENT_OFF(event)) {
6227 tasha->ldo_h_users--;
6228
6229 if (tasha->ldo_h_users < 0)
6230 tasha->ldo_h_users = 0;
6231
6232 if (tasha->ldo_h_users == 0)
6233 snd_soc_update_bits(codec, WCD9335_LDOH_MODE,
6234 0x80, 0x00);
6235 }
6236
6237 return 0;
6238}
6239
6240static int tasha_codec_force_enable_ldo_h(struct snd_soc_dapm_widget *w,
6241 struct snd_kcontrol *kcontrol,
6242 int event)
6243{
6244 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
6245 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
6246
6247 switch (event) {
6248 case SND_SOC_DAPM_PRE_PMU:
6249 wcd_resmgr_enable_master_bias(tasha->resmgr);
6250 tasha_codec_ldo_h_control(w, event);
6251 break;
6252 case SND_SOC_DAPM_POST_PMD:
6253 tasha_codec_ldo_h_control(w, event);
6254 wcd_resmgr_disable_master_bias(tasha->resmgr);
6255 break;
6256 }
6257
6258 return 0;
6259}
6260
6261static int tasha_codec_force_enable_micbias(struct snd_soc_dapm_widget *w,
6262 struct snd_kcontrol *kcontrol,
6263 int event)
6264{
6265 int ret = 0;
6266 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
6267 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
6268
6269 switch (event) {
6270 case SND_SOC_DAPM_PRE_PMU:
6271 wcd_resmgr_enable_master_bias(tasha->resmgr);
6272 tasha_cdc_mclk_enable(codec, true, true);
6273 ret = __tasha_codec_enable_micbias(w, SND_SOC_DAPM_PRE_PMU);
6274 /* Wait for 1ms for better cnp */
6275 usleep_range(1000, 1100);
6276 tasha_cdc_mclk_enable(codec, false, true);
6277 break;
6278 case SND_SOC_DAPM_POST_PMD:
6279 ret = __tasha_codec_enable_micbias(w, SND_SOC_DAPM_POST_PMD);
6280 wcd_resmgr_disable_master_bias(tasha->resmgr);
6281 break;
6282 }
6283
6284 return ret;
6285}
6286
6287static int tasha_codec_enable_micbias(struct snd_soc_dapm_widget *w,
6288 struct snd_kcontrol *kcontrol, int event)
6289{
6290 return __tasha_codec_enable_micbias(w, event);
6291}
6292
6293static int tasha_codec_enable_standalone_ldo_h(struct snd_soc_codec *codec,
6294 bool enable)
6295{
6296 int rc;
6297
6298 if (enable)
6299 rc = snd_soc_dapm_force_enable_pin(
6300 snd_soc_codec_get_dapm(codec),
6301 DAPM_LDO_H_STANDALONE);
6302 else
6303 rc = snd_soc_dapm_disable_pin(
6304 snd_soc_codec_get_dapm(codec),
6305 DAPM_LDO_H_STANDALONE);
6306
6307 if (!rc)
6308 snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec));
6309 else
6310 dev_err(codec->dev, "%s: ldo_h force %s pin failed\n",
6311 __func__, (enable ? "enable" : "disable"));
6312
6313 return rc;
6314}
6315
6316/*
6317 * tasha_codec_enable_standalone_micbias - enable micbias standalone
6318 * @codec: pointer to codec instance
6319 * @micb_num: number of micbias to be enabled
6320 * @enable: true to enable micbias or false to disable
6321 *
6322 * This function is used to enable micbias (1, 2, 3 or 4) during
6323 * standalone independent of whether TX use-case is running or not
6324 *
6325 * Return: error code in case of failure or 0 for success
6326 */
6327int tasha_codec_enable_standalone_micbias(struct snd_soc_codec *codec,
6328 int micb_num,
6329 bool enable)
6330{
6331 const char * const micb_names[] = {
6332 DAPM_MICBIAS1_STANDALONE, DAPM_MICBIAS2_STANDALONE,
6333 DAPM_MICBIAS3_STANDALONE, DAPM_MICBIAS4_STANDALONE
6334 };
6335 int micb_index = micb_num - 1;
6336 int rc;
6337
6338 if (!codec) {
6339 pr_err("%s: Codec memory is NULL\n", __func__);
6340 return -EINVAL;
6341 }
6342
6343 if ((micb_index < 0) || (micb_index > TASHA_MAX_MICBIAS - 1)) {
6344 dev_err(codec->dev, "%s: Invalid micbias index, micb_ind:%d\n",
6345 __func__, micb_index);
6346 return -EINVAL;
6347 }
6348
6349 if (enable)
6350 rc = snd_soc_dapm_force_enable_pin(
6351 snd_soc_codec_get_dapm(codec),
6352 micb_names[micb_index]);
6353 else
6354 rc = snd_soc_dapm_disable_pin(snd_soc_codec_get_dapm(codec),
6355 micb_names[micb_index]);
6356
6357 if (!rc)
6358 snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec));
6359 else
6360 dev_err(codec->dev, "%s: micbias%d force %s pin failed\n",
6361 __func__, micb_num, (enable ? "enable" : "disable"));
6362
6363 return rc;
6364}
6365EXPORT_SYMBOL(tasha_codec_enable_standalone_micbias);
6366
6367static const char *const tasha_anc_func_text[] = {"OFF", "ON"};
6368static const struct soc_enum tasha_anc_func_enum =
6369 SOC_ENUM_SINGLE_EXT(2, tasha_anc_func_text);
6370
6371static const char *const tasha_clkmode_text[] = {"EXTERNAL", "INTERNAL"};
6372static SOC_ENUM_SINGLE_EXT_DECL(tasha_clkmode_enum, tasha_clkmode_text);
6373
6374/* Cutoff frequency for high pass filter */
6375static const char * const cf_text[] = {
6376 "CF_NEG_3DB_4HZ", "CF_NEG_3DB_75HZ", "CF_NEG_3DB_150HZ"
6377};
6378
6379static const char * const rx_cf_text[] = {
6380 "CF_NEG_3DB_4HZ", "CF_NEG_3DB_75HZ", "CF_NEG_3DB_150HZ",
6381 "CF_NEG_3DB_0P48HZ"
6382};
6383
6384static const struct soc_enum cf_dec0_enum =
6385 SOC_ENUM_SINGLE(WCD9335_CDC_TX0_TX_PATH_CFG0, 5, 3, cf_text);
6386
6387static const struct soc_enum cf_dec1_enum =
6388 SOC_ENUM_SINGLE(WCD9335_CDC_TX1_TX_PATH_CFG0, 5, 3, cf_text);
6389
6390static const struct soc_enum cf_dec2_enum =
6391 SOC_ENUM_SINGLE(WCD9335_CDC_TX2_TX_PATH_CFG0, 5, 3, cf_text);
6392
6393static const struct soc_enum cf_dec3_enum =
6394 SOC_ENUM_SINGLE(WCD9335_CDC_TX3_TX_PATH_CFG0, 5, 3, cf_text);
6395
6396static const struct soc_enum cf_dec4_enum =
6397 SOC_ENUM_SINGLE(WCD9335_CDC_TX4_TX_PATH_CFG0, 5, 3, cf_text);
6398
6399static const struct soc_enum cf_dec5_enum =
6400 SOC_ENUM_SINGLE(WCD9335_CDC_TX5_TX_PATH_CFG0, 5, 3, cf_text);
6401
6402static const struct soc_enum cf_dec6_enum =
6403 SOC_ENUM_SINGLE(WCD9335_CDC_TX6_TX_PATH_CFG0, 5, 3, cf_text);
6404
6405static const struct soc_enum cf_dec7_enum =
6406 SOC_ENUM_SINGLE(WCD9335_CDC_TX7_TX_PATH_CFG0, 5, 3, cf_text);
6407
6408static const struct soc_enum cf_dec8_enum =
6409 SOC_ENUM_SINGLE(WCD9335_CDC_TX8_TX_PATH_CFG0, 5, 3, cf_text);
6410
6411static const struct soc_enum cf_int0_1_enum =
6412 SOC_ENUM_SINGLE(WCD9335_CDC_RX0_RX_PATH_CFG2, 0, 4, rx_cf_text);
6413
6414static SOC_ENUM_SINGLE_DECL(cf_int0_2_enum, WCD9335_CDC_RX0_RX_PATH_MIX_CFG, 2,
6415 rx_cf_text);
6416
6417static const struct soc_enum cf_int1_1_enum =
6418 SOC_ENUM_SINGLE(WCD9335_CDC_RX1_RX_PATH_CFG2, 0, 4, rx_cf_text);
6419
6420static SOC_ENUM_SINGLE_DECL(cf_int1_2_enum, WCD9335_CDC_RX1_RX_PATH_MIX_CFG, 2,
6421 rx_cf_text);
6422
6423static const struct soc_enum cf_int2_1_enum =
6424 SOC_ENUM_SINGLE(WCD9335_CDC_RX2_RX_PATH_CFG2, 0, 4, rx_cf_text);
6425
6426static SOC_ENUM_SINGLE_DECL(cf_int2_2_enum, WCD9335_CDC_RX2_RX_PATH_MIX_CFG, 2,
6427 rx_cf_text);
6428
6429static const struct soc_enum cf_int3_1_enum =
6430 SOC_ENUM_SINGLE(WCD9335_CDC_RX3_RX_PATH_CFG2, 0, 4, rx_cf_text);
6431
6432static SOC_ENUM_SINGLE_DECL(cf_int3_2_enum, WCD9335_CDC_RX3_RX_PATH_MIX_CFG, 2,
6433 rx_cf_text);
6434
6435static const struct soc_enum cf_int4_1_enum =
6436 SOC_ENUM_SINGLE(WCD9335_CDC_RX4_RX_PATH_CFG2, 0, 4, rx_cf_text);
6437
6438static SOC_ENUM_SINGLE_DECL(cf_int4_2_enum, WCD9335_CDC_RX4_RX_PATH_MIX_CFG, 2,
6439 rx_cf_text);
6440
6441static const struct soc_enum cf_int5_1_enum =
6442 SOC_ENUM_SINGLE(WCD9335_CDC_RX5_RX_PATH_CFG2, 0, 4, rx_cf_text);
6443
6444static SOC_ENUM_SINGLE_DECL(cf_int5_2_enum, WCD9335_CDC_RX5_RX_PATH_MIX_CFG, 2,
6445 rx_cf_text);
6446
6447static const struct soc_enum cf_int6_1_enum =
6448 SOC_ENUM_SINGLE(WCD9335_CDC_RX6_RX_PATH_CFG2, 0, 4, rx_cf_text);
6449
6450static SOC_ENUM_SINGLE_DECL(cf_int6_2_enum, WCD9335_CDC_RX6_RX_PATH_MIX_CFG, 2,
6451 rx_cf_text);
6452
6453static const struct soc_enum cf_int7_1_enum =
6454 SOC_ENUM_SINGLE(WCD9335_CDC_RX7_RX_PATH_CFG2, 0, 4, rx_cf_text);
6455
6456static SOC_ENUM_SINGLE_DECL(cf_int7_2_enum, WCD9335_CDC_RX7_RX_PATH_MIX_CFG, 2,
6457 rx_cf_text);
6458
6459static const struct soc_enum cf_int8_1_enum =
6460 SOC_ENUM_SINGLE(WCD9335_CDC_RX8_RX_PATH_CFG2, 0, 4, rx_cf_text);
6461
6462static SOC_ENUM_SINGLE_DECL(cf_int8_2_enum, WCD9335_CDC_RX8_RX_PATH_MIX_CFG, 2,
6463 rx_cf_text);
6464
6465static const struct snd_soc_dapm_route audio_i2s_map[] = {
6466 {"SLIM RX0 MUX", NULL, "RX_I2S_CTL"},
6467 {"SLIM RX1 MUX", NULL, "RX_I2S_CTL"},
6468 {"SLIM RX2 MUX", NULL, "RX_I2S_CTL"},
6469 {"SLIM RX3 MUX", NULL, "RX_I2S_CTL"},
6470
6471 {"SLIM TX6 MUX", NULL, "TX_I2S_CTL"},
6472 {"SLIM TX7 MUX", NULL, "TX_I2S_CTL"},
6473 {"SLIM TX8 MUX", NULL, "TX_I2S_CTL"},
6474 {"SLIM TX11 MUX", NULL, "TX_I2S_CTL"},
6475};
6476
6477static const struct snd_soc_dapm_route audio_map[] = {
6478
6479 /* MAD */
6480 {"MAD_SEL MUX", "SPE", "MAD_CPE_INPUT"},
6481 {"MAD_SEL MUX", "MSM", "MADINPUT"},
6482 {"MADONOFF", "Switch", "MAD_SEL MUX"},
6483 {"MAD_BROADCAST", "Switch", "MAD_SEL MUX"},
6484 {"TX13 INP MUX", "CPE_TX_PP", "MADONOFF"},
6485
6486 /* CPE HW MAD bypass */
6487 {"CPE IN Mixer", "MAD_BYPASS", "SLIM TX1 MUX"},
6488
6489 {"AIF4_MAD Mixer", "SLIM TX1", "CPE IN Mixer"},
6490 {"AIF4_MAD Mixer", "SLIM TX12", "MADONOFF"},
6491 {"AIF4_MAD Mixer", "SLIM TX13", "TX13 INP MUX"},
6492 {"AIF4 MAD", NULL, "AIF4_MAD Mixer"},
6493 {"AIF4 MAD", NULL, "AIF4"},
6494
6495 {"EC BUF MUX INP", "DEC1", "ADC MUX1"},
6496 {"AIF5 CPE", NULL, "EC BUF MUX INP"},
6497
6498 /* SLIMBUS Connections */
6499 {"AIF1 CAP", NULL, "AIF1_CAP Mixer"},
6500 {"AIF2 CAP", NULL, "AIF2_CAP Mixer"},
6501 {"AIF3 CAP", NULL, "AIF3_CAP Mixer"},
6502
6503 /* VI Feedback */
6504 {"AIF4_VI Mixer", "SPKR_VI_1", "VIINPUT"},
6505 {"AIF4_VI Mixer", "SPKR_VI_2", "VIINPUT"},
6506 {"AIF4 VI", NULL, "AIF4_VI Mixer"},
6507
6508 /* SLIM_MIXER("AIF1_CAP Mixer"),*/
6509 {"AIF1_CAP Mixer", "SLIM TX0", "SLIM TX0 MUX"},
6510 {"AIF1_CAP Mixer", "SLIM TX1", "SLIM TX1 MUX"},
6511 {"AIF1_CAP Mixer", "SLIM TX2", "SLIM TX2 MUX"},
6512 {"AIF1_CAP Mixer", "SLIM TX3", "SLIM TX3 MUX"},
6513 {"AIF1_CAP Mixer", "SLIM TX4", "SLIM TX4 MUX"},
6514 {"AIF1_CAP Mixer", "SLIM TX5", "SLIM TX5 MUX"},
6515 {"AIF1_CAP Mixer", "SLIM TX6", "SLIM TX6 MUX"},
6516 {"AIF1_CAP Mixer", "SLIM TX7", "SLIM TX7 MUX"},
6517 {"AIF1_CAP Mixer", "SLIM TX8", "SLIM TX8 MUX"},
6518 {"AIF1_CAP Mixer", "SLIM TX9", "SLIM TX9 MUX"},
6519 {"AIF1_CAP Mixer", "SLIM TX10", "SLIM TX10 MUX"},
6520 {"AIF1_CAP Mixer", "SLIM TX11", "SLIM TX11 MUX"},
6521 {"AIF1_CAP Mixer", "SLIM TX13", "TX13 INP MUX"},
6522 /* SLIM_MIXER("AIF2_CAP Mixer"),*/
6523 {"AIF2_CAP Mixer", "SLIM TX0", "SLIM TX0 MUX"},
6524 {"AIF2_CAP Mixer", "SLIM TX1", "SLIM TX1 MUX"},
6525 {"AIF2_CAP Mixer", "SLIM TX2", "SLIM TX2 MUX"},
6526 {"AIF2_CAP Mixer", "SLIM TX3", "SLIM TX3 MUX"},
6527 {"AIF2_CAP Mixer", "SLIM TX4", "SLIM TX4 MUX"},
6528 {"AIF2_CAP Mixer", "SLIM TX5", "SLIM TX5 MUX"},
6529 {"AIF2_CAP Mixer", "SLIM TX6", "SLIM TX6 MUX"},
6530 {"AIF2_CAP Mixer", "SLIM TX7", "SLIM TX7 MUX"},
6531 {"AIF2_CAP Mixer", "SLIM TX8", "SLIM TX8 MUX"},
6532 {"AIF2_CAP Mixer", "SLIM TX9", "SLIM TX9 MUX"},
6533 {"AIF2_CAP Mixer", "SLIM TX10", "SLIM TX10 MUX"},
6534 {"AIF2_CAP Mixer", "SLIM TX11", "SLIM TX11 MUX"},
6535 {"AIF2_CAP Mixer", "SLIM TX13", "TX13 INP MUX"},
6536 /* SLIM_MIXER("AIF3_CAP Mixer"),*/
6537 {"AIF3_CAP Mixer", "SLIM TX0", "SLIM TX0 MUX"},
6538 {"AIF3_CAP Mixer", "SLIM TX1", "SLIM TX1 MUX"},
6539 {"AIF3_CAP Mixer", "SLIM TX2", "SLIM TX2 MUX"},
6540 {"AIF3_CAP Mixer", "SLIM TX3", "SLIM TX3 MUX"},
6541 {"AIF3_CAP Mixer", "SLIM TX4", "SLIM TX4 MUX"},
6542 {"AIF3_CAP Mixer", "SLIM TX5", "SLIM TX5 MUX"},
6543 {"AIF3_CAP Mixer", "SLIM TX6", "SLIM TX6 MUX"},
6544 {"AIF3_CAP Mixer", "SLIM TX7", "SLIM TX7 MUX"},
6545 {"AIF3_CAP Mixer", "SLIM TX8", "SLIM TX8 MUX"},
6546 {"AIF3_CAP Mixer", "SLIM TX9", "SLIM TX9 MUX"},
6547 {"AIF3_CAP Mixer", "SLIM TX10", "SLIM TX10 MUX"},
6548 {"AIF3_CAP Mixer", "SLIM TX11", "SLIM TX11 MUX"},
6549 {"AIF3_CAP Mixer", "SLIM TX13", "TX13 INP MUX"},
6550
6551 {"SLIM TX0 MUX", "DEC0", "ADC MUX0"},
6552 {"SLIM TX0 MUX", "RX_MIX_TX0", "RX MIX TX0 MUX"},
6553 {"SLIM TX0 MUX", "DEC0_192", "ADC US MUX0"},
6554
6555 {"SLIM TX1 MUX", "DEC1", "ADC MUX1"},
6556 {"SLIM TX1 MUX", "RX_MIX_TX1", "RX MIX TX1 MUX"},
6557 {"SLIM TX1 MUX", "DEC1_192", "ADC US MUX1"},
6558
6559 {"SLIM TX2 MUX", "DEC2", "ADC MUX2"},
6560 {"SLIM TX2 MUX", "RX_MIX_TX2", "RX MIX TX2 MUX"},
6561 {"SLIM TX2 MUX", "DEC2_192", "ADC US MUX2"},
6562
6563 {"SLIM TX3 MUX", "DEC3", "ADC MUX3"},
6564 {"SLIM TX3 MUX", "RX_MIX_TX3", "RX MIX TX3 MUX"},
6565 {"SLIM TX3 MUX", "DEC3_192", "ADC US MUX3"},
6566
6567 {"SLIM TX4 MUX", "DEC4", "ADC MUX4"},
6568 {"SLIM TX4 MUX", "RX_MIX_TX4", "RX MIX TX4 MUX"},
6569 {"SLIM TX4 MUX", "DEC4_192", "ADC US MUX4"},
6570
6571 {"SLIM TX5 MUX", "DEC5", "ADC MUX5"},
6572 {"SLIM TX5 MUX", "RX_MIX_TX5", "RX MIX TX5 MUX"},
6573 {"SLIM TX5 MUX", "DEC5_192", "ADC US MUX5"},
6574
6575 {"SLIM TX6 MUX", "DEC6", "ADC MUX6"},
6576 {"SLIM TX6 MUX", "RX_MIX_TX6", "RX MIX TX6 MUX"},
6577 {"SLIM TX6 MUX", "DEC6_192", "ADC US MUX6"},
6578
6579 {"SLIM TX7 MUX", "DEC7", "ADC MUX7"},
6580 {"SLIM TX7 MUX", "RX_MIX_TX7", "RX MIX TX7 MUX"},
6581 {"SLIM TX7 MUX", "DEC7_192", "ADC US MUX7"},
6582
6583 {"SLIM TX8 MUX", "DEC8", "ADC MUX8"},
6584 {"SLIM TX8 MUX", "RX_MIX_TX8", "RX MIX TX8 MUX"},
6585 {"SLIM TX8 MUX", "DEC8_192", "ADC US MUX8"},
6586
6587 {"SLIM TX9 MUX", "DEC7", "ADC MUX7"},
6588 {"SLIM TX9 MUX", "DEC7_192", "ADC US MUX7"},
6589 {"SLIM TX10 MUX", "DEC6", "ADC MUX6"},
6590 {"SLIM TX10 MUX", "DEC6_192", "ADC US MUX6"},
6591
6592 {"SLIM TX11 MUX", "DEC_0_5", "SLIM TX11 INP1 MUX"},
6593 {"SLIM TX11 MUX", "DEC_9_12", "SLIM TX11 INP1 MUX"},
6594 {"SLIM TX11 INP1 MUX", "DEC0", "ADC MUX0"},
6595 {"SLIM TX11 INP1 MUX", "DEC1", "ADC MUX1"},
6596 {"SLIM TX11 INP1 MUX", "DEC2", "ADC MUX2"},
6597 {"SLIM TX11 INP1 MUX", "DEC3", "ADC MUX3"},
6598 {"SLIM TX11 INP1 MUX", "DEC4", "ADC MUX4"},
6599 {"SLIM TX11 INP1 MUX", "DEC5", "ADC MUX5"},
6600 {"SLIM TX11 INP1 MUX", "RX_MIX_TX5", "RX MIX TX5 MUX"},
6601
6602 {"TX13 INP MUX", "MAD_BRDCST", "MAD_BROADCAST"},
6603 {"TX13 INP MUX", "CDC_DEC_5", "SLIM TX13 MUX"},
6604 {"SLIM TX13 MUX", "DEC5", "ADC MUX5"},
6605
6606 {"RX MIX TX0 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
6607 {"RX MIX TX0 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
6608 {"RX MIX TX0 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
6609 {"RX MIX TX0 MUX", "RX_MIX3", "RX INT3 SEC MIX"},
6610 {"RX MIX TX0 MUX", "RX_MIX4", "RX INT4 SEC MIX"},
6611 {"RX MIX TX0 MUX", "RX_MIX5", "RX INT5 SEC MIX"},
6612 {"RX MIX TX0 MUX", "RX_MIX6", "RX INT6 SEC MIX"},
6613 {"RX MIX TX0 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
6614 {"RX MIX TX0 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
6615 {"RX MIX TX0 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"},
6616 {"RX MIX TX0 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"},
6617 {"RX MIX TX0 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"},
6618 {"RX MIX TX0 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"},
6619
6620 {"RX MIX TX1 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
6621 {"RX MIX TX1 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
6622 {"RX MIX TX1 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
6623 {"RX MIX TX1 MUX", "RX_MIX3", "RX INT3 SEC MIX"},
6624 {"RX MIX TX1 MUX", "RX_MIX4", "RX INT4 SEC MIX"},
6625 {"RX MIX TX1 MUX", "RX_MIX5", "RX INT5 SEC MIX"},
6626 {"RX MIX TX1 MUX", "RX_MIX6", "RX INT6 SEC MIX"},
6627 {"RX MIX TX1 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
6628 {"RX MIX TX1 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
6629 {"RX MIX TX1 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"},
6630 {"RX MIX TX1 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"},
6631 {"RX MIX TX1 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"},
6632 {"RX MIX TX1 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"},
6633
6634 {"RX MIX TX2 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
6635 {"RX MIX TX2 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
6636 {"RX MIX TX2 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
6637 {"RX MIX TX2 MUX", "RX_MIX3", "RX INT3 SEC MIX"},
6638 {"RX MIX TX2 MUX", "RX_MIX4", "RX INT4 SEC MIX"},
6639 {"RX MIX TX2 MUX", "RX_MIX5", "RX INT5 SEC MIX"},
6640 {"RX MIX TX2 MUX", "RX_MIX6", "RX INT6 SEC MIX"},
6641 {"RX MIX TX2 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
6642 {"RX MIX TX2 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
6643 {"RX MIX TX2 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"},
6644 {"RX MIX TX2 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"},
6645 {"RX MIX TX2 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"},
6646 {"RX MIX TX2 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"},
6647
6648 {"RX MIX TX3 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
6649 {"RX MIX TX3 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
6650 {"RX MIX TX3 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
6651 {"RX MIX TX3 MUX", "RX_MIX3", "RX INT3 SEC MIX"},
6652 {"RX MIX TX3 MUX", "RX_MIX4", "RX INT4 SEC MIX"},
6653 {"RX MIX TX3 MUX", "RX_MIX5", "RX INT5 SEC MIX"},
6654 {"RX MIX TX3 MUX", "RX_MIX6", "RX INT6 SEC MIX"},
6655 {"RX MIX TX3 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
6656 {"RX MIX TX3 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
6657 {"RX MIX TX3 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"},
6658 {"RX MIX TX3 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"},
6659 {"RX MIX TX3 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"},
6660 {"RX MIX TX3 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"},
6661
6662 {"RX MIX TX4 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
6663 {"RX MIX TX4 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
6664 {"RX MIX TX4 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
6665 {"RX MIX TX4 MUX", "RX_MIX3", "RX INT3 SEC MIX"},
6666 {"RX MIX TX4 MUX", "RX_MIX4", "RX INT4 SEC MIX"},
6667 {"RX MIX TX4 MUX", "RX_MIX5", "RX INT5 SEC MIX"},
6668 {"RX MIX TX4 MUX", "RX_MIX6", "RX INT6 SEC MIX"},
6669 {"RX MIX TX4 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
6670 {"RX MIX TX4 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
6671 {"RX MIX TX4 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"},
6672 {"RX MIX TX4 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"},
6673 {"RX MIX TX4 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"},
6674 {"RX MIX TX4 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"},
6675
6676 {"RX MIX TX5 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
6677 {"RX MIX TX5 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
6678 {"RX MIX TX5 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
6679 {"RX MIX TX5 MUX", "RX_MIX3", "RX INT3 SEC MIX"},
6680 {"RX MIX TX5 MUX", "RX_MIX4", "RX INT4 SEC MIX"},
6681 {"RX MIX TX5 MUX", "RX_MIX5", "RX INT5 SEC MIX"},
6682 {"RX MIX TX5 MUX", "RX_MIX6", "RX INT6 SEC MIX"},
6683 {"RX MIX TX5 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
6684 {"RX MIX TX5 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
6685 {"RX MIX TX5 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"},
6686 {"RX MIX TX5 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"},
6687 {"RX MIX TX5 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"},
6688 {"RX MIX TX5 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"},
6689
6690 {"RX MIX TX6 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
6691 {"RX MIX TX6 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
6692 {"RX MIX TX6 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
6693 {"RX MIX TX6 MUX", "RX_MIX3", "RX INT3 SEC MIX"},
6694 {"RX MIX TX6 MUX", "RX_MIX4", "RX INT4 SEC MIX"},
6695 {"RX MIX TX6 MUX", "RX_MIX5", "RX INT5 SEC MIX"},
6696 {"RX MIX TX6 MUX", "RX_MIX6", "RX INT6 SEC MIX"},
6697 {"RX MIX TX6 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
6698 {"RX MIX TX6 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
6699 {"RX MIX TX6 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"},
6700 {"RX MIX TX6 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"},
6701 {"RX MIX TX6 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"},
6702 {"RX MIX TX6 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"},
6703
6704 {"RX MIX TX7 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
6705 {"RX MIX TX7 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
6706 {"RX MIX TX7 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
6707 {"RX MIX TX7 MUX", "RX_MIX3", "RX INT3 SEC MIX"},
6708 {"RX MIX TX7 MUX", "RX_MIX4", "RX INT4 SEC MIX"},
6709 {"RX MIX TX7 MUX", "RX_MIX5", "RX INT5 SEC MIX"},
6710 {"RX MIX TX7 MUX", "RX_MIX6", "RX INT6 SEC MIX"},
6711 {"RX MIX TX7 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
6712 {"RX MIX TX7 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
6713 {"RX MIX TX7 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"},
6714 {"RX MIX TX7 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"},
6715 {"RX MIX TX7 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"},
6716 {"RX MIX TX7 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"},
6717
6718 {"RX MIX TX8 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
6719 {"RX MIX TX8 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
6720 {"RX MIX TX8 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
6721 {"RX MIX TX8 MUX", "RX_MIX3", "RX INT3 SEC MIX"},
6722 {"RX MIX TX8 MUX", "RX_MIX4", "RX INT4 SEC MIX"},
6723 {"RX MIX TX8 MUX", "RX_MIX5", "RX INT5 SEC MIX"},
6724 {"RX MIX TX8 MUX", "RX_MIX6", "RX INT6 SEC MIX"},
6725 {"RX MIX TX8 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
6726 {"RX MIX TX8 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
6727 {"RX MIX TX8 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"},
6728 {"RX MIX TX8 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"},
6729 {"RX MIX TX8 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"},
6730 {"RX MIX TX8 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"},
6731
6732 {"ADC US MUX0", "US_Switch", "ADC MUX0"},
6733 {"ADC US MUX1", "US_Switch", "ADC MUX1"},
6734 {"ADC US MUX2", "US_Switch", "ADC MUX2"},
6735 {"ADC US MUX3", "US_Switch", "ADC MUX3"},
6736 {"ADC US MUX4", "US_Switch", "ADC MUX4"},
6737 {"ADC US MUX5", "US_Switch", "ADC MUX5"},
6738 {"ADC US MUX6", "US_Switch", "ADC MUX6"},
6739 {"ADC US MUX7", "US_Switch", "ADC MUX7"},
6740 {"ADC US MUX8", "US_Switch", "ADC MUX8"},
6741 {"ADC MUX0", "DMIC", "DMIC MUX0"},
6742 {"ADC MUX0", "AMIC", "AMIC MUX0"},
6743 {"ADC MUX1", "DMIC", "DMIC MUX1"},
6744 {"ADC MUX1", "AMIC", "AMIC MUX1"},
6745 {"ADC MUX2", "DMIC", "DMIC MUX2"},
6746 {"ADC MUX2", "AMIC", "AMIC MUX2"},
6747 {"ADC MUX3", "DMIC", "DMIC MUX3"},
6748 {"ADC MUX3", "AMIC", "AMIC MUX3"},
6749 {"ADC MUX4", "DMIC", "DMIC MUX4"},
6750 {"ADC MUX4", "AMIC", "AMIC MUX4"},
6751 {"ADC MUX5", "DMIC", "DMIC MUX5"},
6752 {"ADC MUX5", "AMIC", "AMIC MUX5"},
6753 {"ADC MUX6", "DMIC", "DMIC MUX6"},
6754 {"ADC MUX6", "AMIC", "AMIC MUX6"},
6755 {"ADC MUX7", "DMIC", "DMIC MUX7"},
6756 {"ADC MUX7", "AMIC", "AMIC MUX7"},
6757 {"ADC MUX8", "DMIC", "DMIC MUX8"},
6758 {"ADC MUX8", "AMIC", "AMIC MUX8"},
6759 {"ADC MUX10", "DMIC", "DMIC MUX10"},
6760 {"ADC MUX10", "AMIC", "AMIC MUX10"},
6761 {"ADC MUX11", "DMIC", "DMIC MUX11"},
6762 {"ADC MUX11", "AMIC", "AMIC MUX11"},
6763 {"ADC MUX12", "DMIC", "DMIC MUX12"},
6764 {"ADC MUX12", "AMIC", "AMIC MUX12"},
6765 {"ADC MUX13", "DMIC", "DMIC MUX13"},
6766 {"ADC MUX13", "AMIC", "AMIC MUX13"},
6767
6768 {"ADC MUX0", "ANC_FB_TUNE1", "ADC MUX10"},
6769 {"ADC MUX0", "ANC_FB_TUNE1", "ADC MUX11"},
6770 {"ADC MUX0", "ANC_FB_TUNE2", "ADC MUX12"},
6771 {"ADC MUX0", "ANC_FB_TUNE2", "ADC MUX13"},
6772 {"ADC MUX1", "ANC_FB_TUNE1", "ADC MUX10"},
6773 {"ADC MUX1", "ANC_FB_TUNE1", "ADC MUX11"},
6774 {"ADC MUX1", "ANC_FB_TUNE2", "ADC MUX12"},
6775 {"ADC MUX1", "ANC_FB_TUNE2", "ADC MUX13"},
6776 {"ADC MUX2", "ANC_FB_TUNE1", "ADC MUX10"},
6777 {"ADC MUX2", "ANC_FB_TUNE1", "ADC MUX11"},
6778 {"ADC MUX2", "ANC_FB_TUNE2", "ADC MUX12"},
6779 {"ADC MUX2", "ANC_FB_TUNE2", "ADC MUX13"},
6780 {"ADC MUX3", "ANC_FB_TUNE1", "ADC MUX10"},
6781 {"ADC MUX3", "ANC_FB_TUNE1", "ADC MUX11"},
6782 {"ADC MUX3", "ANC_FB_TUNE2", "ADC MUX12"},
6783 {"ADC MUX3", "ANC_FB_TUNE2", "ADC MUX13"},
6784 {"ADC MUX4", "ANC_FB_TUNE1", "ADC MUX10"},
6785 {"ADC MUX4", "ANC_FB_TUNE1", "ADC MUX11"},
6786 {"ADC MUX4", "ANC_FB_TUNE2", "ADC MUX12"},
6787 {"ADC MUX4", "ANC_FB_TUNE2", "ADC MUX13"},
6788 {"ADC MUX5", "ANC_FB_TUNE1", "ADC MUX10"},
6789 {"ADC MUX5", "ANC_FB_TUNE1", "ADC MUX11"},
6790 {"ADC MUX5", "ANC_FB_TUNE2", "ADC MUX12"},
6791 {"ADC MUX5", "ANC_FB_TUNE2", "ADC MUX13"},
6792 {"ADC MUX6", "ANC_FB_TUNE1", "ADC MUX10"},
6793 {"ADC MUX6", "ANC_FB_TUNE1", "ADC MUX11"},
6794 {"ADC MUX6", "ANC_FB_TUNE2", "ADC MUX12"},
6795 {"ADC MUX6", "ANC_FB_TUNE2", "ADC MUX13"},
6796 {"ADC MUX7", "ANC_FB_TUNE1", "ADC MUX10"},
6797 {"ADC MUX7", "ANC_FB_TUNE1", "ADC MUX11"},
6798 {"ADC MUX7", "ANC_FB_TUNE2", "ADC MUX12"},
6799 {"ADC MUX7", "ANC_FB_TUNE2", "ADC MUX13"},
6800 {"ADC MUX8", "ANC_FB_TUNE1", "ADC MUX10"},
6801 {"ADC MUX8", "ANC_FB_TUNE1", "ADC MUX11"},
6802 {"ADC MUX8", "ANC_FB_TUNE2", "ADC MUX12"},
6803 {"ADC MUX8", "ANC_FB_TUNE2", "ADC MUX13"},
6804
6805 {"DMIC MUX0", "DMIC0", "DMIC0"},
6806 {"DMIC MUX0", "DMIC1", "DMIC1"},
6807 {"DMIC MUX0", "DMIC2", "DMIC2"},
6808 {"DMIC MUX0", "DMIC3", "DMIC3"},
6809 {"DMIC MUX0", "DMIC4", "DMIC4"},
6810 {"DMIC MUX0", "DMIC5", "DMIC5"},
6811 {"AMIC MUX0", "ADC1", "ADC1"},
6812 {"AMIC MUX0", "ADC2", "ADC2"},
6813 {"AMIC MUX0", "ADC3", "ADC3"},
6814 {"AMIC MUX0", "ADC4", "ADC4"},
6815 {"AMIC MUX0", "ADC5", "ADC5"},
6816 {"AMIC MUX0", "ADC6", "ADC6"},
6817
6818 {"DMIC MUX1", "DMIC0", "DMIC0"},
6819 {"DMIC MUX1", "DMIC1", "DMIC1"},
6820 {"DMIC MUX1", "DMIC2", "DMIC2"},
6821 {"DMIC MUX1", "DMIC3", "DMIC3"},
6822 {"DMIC MUX1", "DMIC4", "DMIC4"},
6823 {"DMIC MUX1", "DMIC5", "DMIC5"},
6824 {"AMIC MUX1", "ADC1", "ADC1"},
6825 {"AMIC MUX1", "ADC2", "ADC2"},
6826 {"AMIC MUX1", "ADC3", "ADC3"},
6827 {"AMIC MUX1", "ADC4", "ADC4"},
6828 {"AMIC MUX1", "ADC5", "ADC5"},
6829 {"AMIC MUX1", "ADC6", "ADC6"},
6830
6831 {"DMIC MUX2", "DMIC0", "DMIC0"},
6832 {"DMIC MUX2", "DMIC1", "DMIC1"},
6833 {"DMIC MUX2", "DMIC2", "DMIC2"},
6834 {"DMIC MUX2", "DMIC3", "DMIC3"},
6835 {"DMIC MUX2", "DMIC4", "DMIC4"},
6836 {"DMIC MUX2", "DMIC5", "DMIC5"},
6837 {"AMIC MUX2", "ADC1", "ADC1"},
6838 {"AMIC MUX2", "ADC2", "ADC2"},
6839 {"AMIC MUX2", "ADC3", "ADC3"},
6840 {"AMIC MUX2", "ADC4", "ADC4"},
6841 {"AMIC MUX2", "ADC5", "ADC5"},
6842 {"AMIC MUX2", "ADC6", "ADC6"},
6843
6844 {"DMIC MUX3", "DMIC0", "DMIC0"},
6845 {"DMIC MUX3", "DMIC1", "DMIC1"},
6846 {"DMIC MUX3", "DMIC2", "DMIC2"},
6847 {"DMIC MUX3", "DMIC3", "DMIC3"},
6848 {"DMIC MUX3", "DMIC4", "DMIC4"},
6849 {"DMIC MUX3", "DMIC5", "DMIC5"},
6850 {"AMIC MUX3", "ADC1", "ADC1"},
6851 {"AMIC MUX3", "ADC2", "ADC2"},
6852 {"AMIC MUX3", "ADC3", "ADC3"},
6853 {"AMIC MUX3", "ADC4", "ADC4"},
6854 {"AMIC MUX3", "ADC5", "ADC5"},
6855 {"AMIC MUX3", "ADC6", "ADC6"},
6856
6857 {"DMIC MUX4", "DMIC0", "DMIC0"},
6858 {"DMIC MUX4", "DMIC1", "DMIC1"},
6859 {"DMIC MUX4", "DMIC2", "DMIC2"},
6860 {"DMIC MUX4", "DMIC3", "DMIC3"},
6861 {"DMIC MUX4", "DMIC4", "DMIC4"},
6862 {"DMIC MUX4", "DMIC5", "DMIC5"},
6863 {"AMIC MUX4", "ADC1", "ADC1"},
6864 {"AMIC MUX4", "ADC2", "ADC2"},
6865 {"AMIC MUX4", "ADC3", "ADC3"},
6866 {"AMIC MUX4", "ADC4", "ADC4"},
6867 {"AMIC MUX4", "ADC5", "ADC5"},
6868 {"AMIC MUX4", "ADC6", "ADC6"},
6869
6870 {"DMIC MUX5", "DMIC0", "DMIC0"},
6871 {"DMIC MUX5", "DMIC1", "DMIC1"},
6872 {"DMIC MUX5", "DMIC2", "DMIC2"},
6873 {"DMIC MUX5", "DMIC3", "DMIC3"},
6874 {"DMIC MUX5", "DMIC4", "DMIC4"},
6875 {"DMIC MUX5", "DMIC5", "DMIC5"},
6876 {"AMIC MUX5", "ADC1", "ADC1"},
6877 {"AMIC MUX5", "ADC2", "ADC2"},
6878 {"AMIC MUX5", "ADC3", "ADC3"},
6879 {"AMIC MUX5", "ADC4", "ADC4"},
6880 {"AMIC MUX5", "ADC5", "ADC5"},
6881 {"AMIC MUX5", "ADC6", "ADC6"},
6882
6883 {"DMIC MUX6", "DMIC0", "DMIC0"},
6884 {"DMIC MUX6", "DMIC1", "DMIC1"},
6885 {"DMIC MUX6", "DMIC2", "DMIC2"},
6886 {"DMIC MUX6", "DMIC3", "DMIC3"},
6887 {"DMIC MUX6", "DMIC4", "DMIC4"},
6888 {"DMIC MUX6", "DMIC5", "DMIC5"},
6889 {"AMIC MUX6", "ADC1", "ADC1"},
6890 {"AMIC MUX6", "ADC2", "ADC2"},
6891 {"AMIC MUX6", "ADC3", "ADC3"},
6892 {"AMIC MUX6", "ADC4", "ADC4"},
6893 {"AMIC MUX6", "ADC5", "ADC5"},
6894 {"AMIC MUX6", "ADC6", "ADC6"},
6895
6896 {"DMIC MUX7", "DMIC0", "DMIC0"},
6897 {"DMIC MUX7", "DMIC1", "DMIC1"},
6898 {"DMIC MUX7", "DMIC2", "DMIC2"},
6899 {"DMIC MUX7", "DMIC3", "DMIC3"},
6900 {"DMIC MUX7", "DMIC4", "DMIC4"},
6901 {"DMIC MUX7", "DMIC5", "DMIC5"},
6902 {"AMIC MUX7", "ADC1", "ADC1"},
6903 {"AMIC MUX7", "ADC2", "ADC2"},
6904 {"AMIC MUX7", "ADC3", "ADC3"},
6905 {"AMIC MUX7", "ADC4", "ADC4"},
6906 {"AMIC MUX7", "ADC5", "ADC5"},
6907 {"AMIC MUX7", "ADC6", "ADC6"},
6908
6909 {"DMIC MUX8", "DMIC0", "DMIC0"},
6910 {"DMIC MUX8", "DMIC1", "DMIC1"},
6911 {"DMIC MUX8", "DMIC2", "DMIC2"},
6912 {"DMIC MUX8", "DMIC3", "DMIC3"},
6913 {"DMIC MUX8", "DMIC4", "DMIC4"},
6914 {"DMIC MUX8", "DMIC5", "DMIC5"},
6915 {"AMIC MUX8", "ADC1", "ADC1"},
6916 {"AMIC MUX8", "ADC2", "ADC2"},
6917 {"AMIC MUX8", "ADC3", "ADC3"},
6918 {"AMIC MUX8", "ADC4", "ADC4"},
6919 {"AMIC MUX8", "ADC5", "ADC5"},
6920 {"AMIC MUX8", "ADC6", "ADC6"},
6921
6922 {"DMIC MUX10", "DMIC0", "DMIC0"},
6923 {"DMIC MUX10", "DMIC1", "DMIC1"},
6924 {"DMIC MUX10", "DMIC2", "DMIC2"},
6925 {"DMIC MUX10", "DMIC3", "DMIC3"},
6926 {"DMIC MUX10", "DMIC4", "DMIC4"},
6927 {"DMIC MUX10", "DMIC5", "DMIC5"},
6928 {"AMIC MUX10", "ADC1", "ADC1"},
6929 {"AMIC MUX10", "ADC2", "ADC2"},
6930 {"AMIC MUX10", "ADC3", "ADC3"},
6931 {"AMIC MUX10", "ADC4", "ADC4"},
6932 {"AMIC MUX10", "ADC5", "ADC5"},
6933 {"AMIC MUX10", "ADC6", "ADC6"},
6934
6935 {"DMIC MUX11", "DMIC0", "DMIC0"},
6936 {"DMIC MUX11", "DMIC1", "DMIC1"},
6937 {"DMIC MUX11", "DMIC2", "DMIC2"},
6938 {"DMIC MUX11", "DMIC3", "DMIC3"},
6939 {"DMIC MUX11", "DMIC4", "DMIC4"},
6940 {"DMIC MUX11", "DMIC5", "DMIC5"},
6941 {"AMIC MUX11", "ADC1", "ADC1"},
6942 {"AMIC MUX11", "ADC2", "ADC2"},
6943 {"AMIC MUX11", "ADC3", "ADC3"},
6944 {"AMIC MUX11", "ADC4", "ADC4"},
6945 {"AMIC MUX11", "ADC5", "ADC5"},
6946 {"AMIC MUX11", "ADC6", "ADC6"},
6947
6948 {"DMIC MUX12", "DMIC0", "DMIC0"},
6949 {"DMIC MUX12", "DMIC1", "DMIC1"},
6950 {"DMIC MUX12", "DMIC2", "DMIC2"},
6951 {"DMIC MUX12", "DMIC3", "DMIC3"},
6952 {"DMIC MUX12", "DMIC4", "DMIC4"},
6953 {"DMIC MUX12", "DMIC5", "DMIC5"},
6954 {"AMIC MUX12", "ADC1", "ADC1"},
6955 {"AMIC MUX12", "ADC2", "ADC2"},
6956 {"AMIC MUX12", "ADC3", "ADC3"},
6957 {"AMIC MUX12", "ADC4", "ADC4"},
6958 {"AMIC MUX12", "ADC5", "ADC5"},
6959 {"AMIC MUX12", "ADC6", "ADC6"},
6960
6961 {"DMIC MUX13", "DMIC0", "DMIC0"},
6962 {"DMIC MUX13", "DMIC1", "DMIC1"},
6963 {"DMIC MUX13", "DMIC2", "DMIC2"},
6964 {"DMIC MUX13", "DMIC3", "DMIC3"},
6965 {"DMIC MUX13", "DMIC4", "DMIC4"},
6966 {"DMIC MUX13", "DMIC5", "DMIC5"},
6967 {"AMIC MUX13", "ADC1", "ADC1"},
6968 {"AMIC MUX13", "ADC2", "ADC2"},
6969 {"AMIC MUX13", "ADC3", "ADC3"},
6970 {"AMIC MUX13", "ADC4", "ADC4"},
6971 {"AMIC MUX13", "ADC5", "ADC5"},
6972 {"AMIC MUX13", "ADC6", "ADC6"},
6973 /* ADC Connections */
6974 {"ADC1", NULL, "AMIC1"},
6975 {"ADC2", NULL, "AMIC2"},
6976 {"ADC3", NULL, "AMIC3"},
6977 {"ADC4", NULL, "AMIC4"},
6978 {"ADC5", NULL, "AMIC5"},
6979 {"ADC6", NULL, "AMIC6"},
6980
6981 {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP0"},
6982 {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP1"},
6983 {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP2"},
6984 {"RX INT1_1 MIX1", NULL, "RX INT1_1 MIX1 INP0"},
6985 {"RX INT1_1 MIX1", NULL, "RX INT1_1 MIX1 INP1"},
6986 {"RX INT1_1 MIX1", NULL, "RX INT1_1 MIX1 INP2"},
6987 {"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP0"},
6988 {"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP1"},
6989 {"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP2"},
6990 {"RX INT3_1 MIX1", NULL, "RX INT3_1 MIX1 INP0"},
6991 {"RX INT3_1 MIX1", NULL, "RX INT3_1 MIX1 INP1"},
6992 {"RX INT3_1 MIX1", NULL, "RX INT3_1 MIX1 INP2"},
6993 {"RX INT4_1 MIX1", NULL, "RX INT4_1 MIX1 INP0"},
6994 {"RX INT4_1 MIX1", NULL, "RX INT4_1 MIX1 INP1"},
6995 {"RX INT4_1 MIX1", NULL, "RX INT4_1 MIX1 INP2"},
6996 {"RX INT5_1 MIX1", NULL, "RX INT5_1 MIX1 INP0"},
6997 {"RX INT5_1 MIX1", NULL, "RX INT5_1 MIX1 INP1"},
6998 {"RX INT5_1 MIX1", NULL, "RX INT5_1 MIX1 INP2"},
6999 {"RX INT6_1 MIX1", NULL, "RX INT6_1 MIX1 INP0"},
7000 {"RX INT6_1 MIX1", NULL, "RX INT6_1 MIX1 INP1"},
7001 {"RX INT6_1 MIX1", NULL, "RX INT6_1 MIX1 INP2"},
7002 {"RX INT7_1 MIX1", NULL, "RX INT7_1 MIX1 INP0"},
7003 {"RX INT7_1 MIX1", NULL, "RX INT7_1 MIX1 INP1"},
7004 {"RX INT7_1 MIX1", NULL, "RX INT7_1 MIX1 INP2"},
7005 {"RX INT8_1 MIX1", NULL, "RX INT8_1 MIX1 INP0"},
7006 {"RX INT8_1 MIX1", NULL, "RX INT8_1 MIX1 INP1"},
7007 {"RX INT8_1 MIX1", NULL, "RX INT8_1 MIX1 INP2"},
7008
7009 {"RX INT0 SEC MIX", NULL, "RX INT0_1 MIX1"},
7010 {"RX INT0 MIX2", NULL, "RX INT0 SEC MIX"},
7011 {"RX INT0 MIX2", NULL, "RX INT0 MIX2 INP"},
7012 {"RX INT0 INTERP", NULL, "RX INT0 MIX2"},
7013 {"RX INT0 DEM MUX", "CLSH_DSM_OUT", "RX INT0 INTERP"},
7014 {"RX INT0 DAC", NULL, "RX INT0 DEM MUX"},
7015 {"RX INT0 DAC", NULL, "RX_BIAS"},
7016 {"EAR PA", NULL, "RX INT0 DAC"},
7017 {"EAR", NULL, "EAR PA"},
7018
7019 {"SPL SRC0 MUX", "SRC_IN_HPHL", "RX INT1_1 MIX1"},
7020 {"RX INT1 SPLINE MIX", NULL, "RX INT1_1 MIX1"},
7021 {"RX INT1 SPLINE MIX", "HPHL Switch", "SPL SRC0 MUX"},
7022 {"RX INT1_1 NATIVE MUX", "ON", "RX INT1_1 MIX1"},
7023 {"RX INT1 SPLINE MIX", NULL, "RX INT1_1 NATIVE MUX"},
7024 {"RX INT1_1 NATIVE MUX", NULL, "RX INT1 NATIVE SUPPLY"},
7025 {"RX INT1 SEC MIX", NULL, "RX INT1 SPLINE MIX"},
7026 {"RX INT1 MIX2", NULL, "RX INT1 SEC MIX"},
7027 {"RX INT1 MIX2", NULL, "RX INT1 MIX2 INP"},
7028 {"RX INT1 INTERP", NULL, "RX INT1 MIX2"},
7029 {"RX INT1 DEM MUX", "CLSH_DSM_OUT", "RX INT1 INTERP"},
7030 {"RX INT1 DAC", NULL, "RX INT1 DEM MUX"},
7031 {"RX INT1 DAC", NULL, "RX_BIAS"},
7032 {"HPHL PA", NULL, "RX INT1 DAC"},
7033 {"HPHL", NULL, "HPHL PA"},
7034
7035 {"SPL SRC1 MUX", "SRC_IN_HPHR", "RX INT2_1 MIX1"},
7036 {"RX INT2 SPLINE MIX", NULL, "RX INT2_1 MIX1"},
7037 {"RX INT2 SPLINE MIX", "HPHR Switch", "SPL SRC1 MUX"},
7038 {"RX INT2_1 NATIVE MUX", "ON", "RX INT2_1 MIX1"},
7039 {"RX INT2 SPLINE MIX", NULL, "RX INT2_1 NATIVE MUX"},
7040 {"RX INT2_1 NATIVE MUX", NULL, "RX INT2 NATIVE SUPPLY"},
7041 {"RX INT2 SEC MIX", NULL, "RX INT2 SPLINE MIX"},
7042 {"RX INT2 MIX2", NULL, "RX INT2 SEC MIX"},
7043 {"RX INT2 MIX2", NULL, "RX INT2 MIX2 INP"},
7044 {"RX INT2 INTERP", NULL, "RX INT2 MIX2"},
7045 {"RX INT2 DEM MUX", "CLSH_DSM_OUT", "RX INT2 INTERP"},
7046 {"RX INT2 DAC", NULL, "RX INT2 DEM MUX"},
7047 {"RX INT2 DAC", NULL, "RX_BIAS"},
7048 {"HPHR PA", NULL, "RX INT2 DAC"},
7049 {"HPHR", NULL, "HPHR PA"},
7050
7051 {"SPL SRC0 MUX", "SRC_IN_LO1", "RX INT3_1 MIX1"},
7052 {"RX INT3 SPLINE MIX", NULL, "RX INT3_1 MIX1"},
7053 {"RX INT3 SPLINE MIX", "LO1 Switch", "SPL SRC0 MUX"},
7054 {"RX INT3_1 NATIVE MUX", "ON", "RX INT3_1 MIX1"},
7055 {"RX INT3 SPLINE MIX", NULL, "RX INT3_1 NATIVE MUX"},
7056 {"RX INT3_1 NATIVE MUX", NULL, "RX INT3 NATIVE SUPPLY"},
7057 {"RX INT3 SEC MIX", NULL, "RX INT3 SPLINE MIX"},
7058 {"RX INT3 MIX2", NULL, "RX INT3 SEC MIX"},
7059 {"RX INT3 MIX2", NULL, "RX INT3 MIX2 INP"},
7060 {"RX INT3 INTERP", NULL, "RX INT3 MIX2"},
7061 {"RX INT3 DAC", NULL, "RX INT3 INTERP"},
7062 {"RX INT3 DAC", NULL, "RX_BIAS"},
7063 {"LINEOUT1 PA", NULL, "RX INT3 DAC"},
7064 {"LINEOUT1", NULL, "LINEOUT1 PA"},
7065
7066 {"SPL SRC1 MUX", "SRC_IN_LO2", "RX INT4_1 MIX1"},
7067 {"RX INT4 SPLINE MIX", NULL, "RX INT4_1 MIX1"},
7068 {"RX INT4 SPLINE MIX", "LO2 Switch", "SPL SRC1 MUX"},
7069 {"RX INT4_1 NATIVE MUX", "ON", "RX INT4_1 MIX1"},
7070 {"RX INT4 SPLINE MIX", NULL, "RX INT4_1 NATIVE MUX"},
7071 {"RX INT4_1 NATIVE MUX", NULL, "RX INT4 NATIVE SUPPLY"},
7072 {"RX INT4 SEC MIX", NULL, "RX INT4 SPLINE MIX"},
7073 {"RX INT4 MIX2", NULL, "RX INT4 SEC MIX"},
7074 {"RX INT4 MIX2", NULL, "RX INT4 MIX2 INP"},
7075 {"RX INT4 INTERP", NULL, "RX INT4 MIX2"},
7076 {"RX INT4 DAC", NULL, "RX INT4 INTERP"},
7077 {"RX INT4 DAC", NULL, "RX_BIAS"},
7078 {"LINEOUT2 PA", NULL, "RX INT4 DAC"},
7079 {"LINEOUT2", NULL, "LINEOUT2 PA"},
7080
7081 {"SPL SRC2 MUX", "SRC_IN_LO3", "RX INT5_1 MIX1"},
7082 {"RX INT5 SPLINE MIX", NULL, "RX INT5_1 MIX1"},
7083 {"RX INT5 SPLINE MIX", "LO3 Switch", "SPL SRC2 MUX"},
7084 {"RX INT5 SEC MIX", NULL, "RX INT5 SPLINE MIX"},
7085 {"RX INT5 MIX2", NULL, "RX INT5 SEC MIX"},
7086 {"RX INT5 INTERP", NULL, "RX INT5 MIX2"},
7087
7088 {"RX INT5 VBAT", "LO3 VBAT Enable", "RX INT5 INTERP"},
7089 {"RX INT5 DAC", NULL, "RX INT5 VBAT"},
7090
7091 {"RX INT5 DAC", NULL, "RX INT5 INTERP"},
7092 {"RX INT5 DAC", NULL, "RX_BIAS"},
7093 {"LINEOUT3 PA", NULL, "RX INT5 DAC"},
7094 {"LINEOUT3", NULL, "LINEOUT3 PA"},
7095
7096 {"SPL SRC3 MUX", "SRC_IN_LO4", "RX INT6_1 MIX1"},
7097 {"RX INT6 SPLINE MIX", NULL, "RX INT6_1 MIX1"},
7098 {"RX INT6 SPLINE MIX", "LO4 Switch", "SPL SRC3 MUX"},
7099 {"RX INT6 SEC MIX", NULL, "RX INT6 SPLINE MIX"},
7100 {"RX INT6 MIX2", NULL, "RX INT6 SEC MIX"},
7101 {"RX INT6 INTERP", NULL, "RX INT6 MIX2"},
7102
7103 {"RX INT6 VBAT", "LO4 VBAT Enable", "RX INT6 INTERP"},
7104 {"RX INT6 DAC", NULL, "RX INT6 VBAT"},
7105
7106 {"RX INT6 DAC", NULL, "RX INT6 INTERP"},
7107 {"RX INT6 DAC", NULL, "RX_BIAS"},
7108 {"LINEOUT4 PA", NULL, "RX INT6 DAC"},
7109 {"LINEOUT4", NULL, "LINEOUT4 PA"},
7110
7111 {"SPL SRC2 MUX", "SRC_IN_SPKRL", "RX INT7_1 MIX1"},
7112 {"RX INT7 SPLINE MIX", NULL, "RX INT7_1 MIX1"},
7113 {"RX INT7 SPLINE MIX", "SPKRL Switch", "SPL SRC2 MUX"},
7114 {"RX INT7 SEC MIX", NULL, "RX INT7 SPLINE MIX"},
7115 {"RX INT7 MIX2", NULL, "RX INT7 SEC MIX"},
7116 {"RX INT7 MIX2", NULL, "RX INT7 MIX2 INP"},
7117
7118 {"RX INT7 INTERP", NULL, "RX INT7 MIX2"},
7119
7120 {"RX INT7 VBAT", "SPKRL VBAT Enable", "RX INT7 INTERP"},
7121 {"RX INT7 CHAIN", NULL, "RX INT7 VBAT"},
7122
7123 {"RX INT7 CHAIN", NULL, "RX INT7 INTERP"},
7124 {"RX INT7 CHAIN", NULL, "RX_BIAS"},
7125 {"SPK1 OUT", NULL, "RX INT7 CHAIN"},
7126
7127 {"ANC SPKR PA Enable", "Switch", "RX INT7 CHAIN"},
7128 {"ANC SPK1 PA", NULL, "ANC SPKR PA Enable"},
7129 {"SPK1 OUT", NULL, "ANC SPK1 PA"},
7130
7131 {"SPL SRC3 MUX", "SRC_IN_SPKRR", "RX INT8_1 MIX1"},
7132 {"RX INT8 SPLINE MIX", NULL, "RX INT8_1 MIX1"},
7133 {"RX INT8 SPLINE MIX", "SPKRR Switch", "SPL SRC3 MUX"},
7134 {"RX INT8 SEC MIX", NULL, "RX INT8 SPLINE MIX"},
7135 {"RX INT8 INTERP", NULL, "RX INT8 SEC MIX"},
7136
7137 {"RX INT8 VBAT", "SPKRR VBAT Enable", "RX INT8 INTERP"},
7138 {"RX INT8 CHAIN", NULL, "RX INT8 VBAT"},
7139
7140 {"RX INT8 CHAIN", NULL, "RX INT8 INTERP"},
7141 {"RX INT8 CHAIN", NULL, "RX_BIAS"},
7142 {"SPK2 OUT", NULL, "RX INT8 CHAIN"},
7143
7144 {"ANC0 FB MUX", "ANC_IN_EAR", "RX INT0 MIX2"},
7145 {"ANC0 FB MUX", "ANC_IN_HPHL", "RX INT1 MIX2"},
7146 {"ANC0 FB MUX", "ANC_IN_LO1", "RX INT3 MIX2"},
7147 {"ANC0 FB MUX", "ANC_IN_EAR_SPKR", "RX INT7 MIX2"},
7148 {"ANC1 FB MUX", "ANC_IN_HPHR", "RX INT2 MIX2"},
7149 {"ANC1 FB MUX", "ANC_IN_LO2", "RX INT4 MIX2"},
7150
7151 {"ANC HPHL Enable", "Switch", "ADC MUX10"},
7152 {"ANC HPHL Enable", "Switch", "ADC MUX11"},
7153 {"RX INT1 MIX2", NULL, "ANC HPHL Enable"},
7154
7155 {"ANC HPHR Enable", "Switch", "ADC MUX12"},
7156 {"ANC HPHR Enable", "Switch", "ADC MUX13"},
7157 {"RX INT2 MIX2", NULL, "ANC HPHR Enable"},
7158
7159 {"ANC EAR Enable", "Switch", "ADC MUX10"},
7160 {"ANC EAR Enable", "Switch", "ADC MUX11"},
7161 {"RX INT0 MIX2", NULL, "ANC EAR Enable"},
7162
7163 {"ANC OUT EAR SPKR Enable", "Switch", "ADC MUX10"},
7164 {"ANC OUT EAR SPKR Enable", "Switch", "ADC MUX11"},
7165 {"RX INT7 MIX2", NULL, "ANC OUT EAR SPKR Enable"},
7166
7167 {"ANC LINEOUT1 Enable", "Switch", "ADC MUX10"},
7168 {"ANC LINEOUT1 Enable", "Switch", "ADC MUX11"},
7169 {"RX INT3 MIX2", NULL, "ANC LINEOUT1 Enable"},
7170
7171 {"ANC LINEOUT2 Enable", "Switch", "ADC MUX12"},
7172 {"ANC LINEOUT2 Enable", "Switch", "ADC MUX13"},
7173 {"RX INT4 MIX2", NULL, "ANC LINEOUT2 Enable"},
7174
7175 {"ANC EAR PA", NULL, "RX INT0 DAC"},
7176 {"ANC EAR", NULL, "ANC EAR PA"},
7177 {"ANC HPHL PA", NULL, "RX INT1 DAC"},
7178 {"ANC HPHL", NULL, "ANC HPHL PA"},
7179 {"ANC HPHR PA", NULL, "RX INT2 DAC"},
7180 {"ANC HPHR", NULL, "ANC HPHR PA"},
7181 {"ANC LINEOUT1 PA", NULL, "RX INT3 DAC"},
7182 {"ANC LINEOUT1", NULL, "ANC LINEOUT1 PA"},
7183 {"ANC LINEOUT2 PA", NULL, "RX INT4 DAC"},
7184 {"ANC LINEOUT2", NULL, "ANC LINEOUT2 PA"},
7185
7186 /* SLIM_MUX("AIF1_PB", "AIF1 PB"),*/
7187 {"SLIM RX0 MUX", "AIF1_PB", "AIF1 PB"},
7188 {"SLIM RX1 MUX", "AIF1_PB", "AIF1 PB"},
7189 {"SLIM RX2 MUX", "AIF1_PB", "AIF1 PB"},
7190 {"SLIM RX3 MUX", "AIF1_PB", "AIF1 PB"},
7191 {"SLIM RX4 MUX", "AIF1_PB", "AIF1 PB"},
7192 {"SLIM RX5 MUX", "AIF1_PB", "AIF1 PB"},
7193 {"SLIM RX6 MUX", "AIF1_PB", "AIF1 PB"},
7194 {"SLIM RX7 MUX", "AIF1_PB", "AIF1 PB"},
7195 /* SLIM_MUX("AIF2_PB", "AIF2 PB"),*/
7196 {"SLIM RX0 MUX", "AIF2_PB", "AIF2 PB"},
7197 {"SLIM RX1 MUX", "AIF2_PB", "AIF2 PB"},
7198 {"SLIM RX2 MUX", "AIF2_PB", "AIF2 PB"},
7199 {"SLIM RX3 MUX", "AIF2_PB", "AIF2 PB"},
7200 {"SLIM RX4 MUX", "AIF2_PB", "AIF2 PB"},
7201 {"SLIM RX5 MUX", "AIF2_PB", "AIF2 PB"},
7202 {"SLIM RX6 MUX", "AIF2_PB", "AIF2 PB"},
7203 {"SLIM RX7 MUX", "AIF2_PB", "AIF2 PB"},
7204 /* SLIM_MUX("AIF3_PB", "AIF3 PB"),*/
7205 {"SLIM RX0 MUX", "AIF3_PB", "AIF3 PB"},
7206 {"SLIM RX1 MUX", "AIF3_PB", "AIF3 PB"},
7207 {"SLIM RX2 MUX", "AIF3_PB", "AIF3 PB"},
7208 {"SLIM RX3 MUX", "AIF3_PB", "AIF3 PB"},
7209 {"SLIM RX4 MUX", "AIF3_PB", "AIF3 PB"},
7210 {"SLIM RX5 MUX", "AIF3_PB", "AIF3 PB"},
7211 {"SLIM RX6 MUX", "AIF3_PB", "AIF3 PB"},
7212 {"SLIM RX7 MUX", "AIF3_PB", "AIF3 PB"},
7213 /* SLIM_MUX("AIF4_PB", "AIF4 PB"),*/
7214 {"SLIM RX0 MUX", "AIF4_PB", "AIF4 PB"},
7215 {"SLIM RX1 MUX", "AIF4_PB", "AIF4 PB"},
7216 {"SLIM RX2 MUX", "AIF4_PB", "AIF4 PB"},
7217 {"SLIM RX3 MUX", "AIF4_PB", "AIF4 PB"},
7218 {"SLIM RX4 MUX", "AIF4_PB", "AIF4 PB"},
7219 {"SLIM RX5 MUX", "AIF4_PB", "AIF4 PB"},
7220 {"SLIM RX6 MUX", "AIF4_PB", "AIF4 PB"},
7221 {"SLIM RX7 MUX", "AIF4_PB", "AIF4 PB"},
7222
7223 /* SLIM_MUX("AIF_MIX1_PB", "AIF MIX1 PB"),*/
7224 {"SLIM RX0 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"},
7225 {"SLIM RX1 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"},
7226 {"SLIM RX2 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"},
7227 {"SLIM RX3 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"},
7228 {"SLIM RX4 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"},
7229 {"SLIM RX5 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"},
7230 {"SLIM RX6 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"},
7231 {"SLIM RX7 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"},
7232
7233 {"SLIM RX0", NULL, "SLIM RX0 MUX"},
7234 {"SLIM RX1", NULL, "SLIM RX1 MUX"},
7235 {"SLIM RX2", NULL, "SLIM RX2 MUX"},
7236 {"SLIM RX3", NULL, "SLIM RX3 MUX"},
7237 {"SLIM RX4", NULL, "SLIM RX4 MUX"},
7238 {"SLIM RX5", NULL, "SLIM RX5 MUX"},
7239 {"SLIM RX6", NULL, "SLIM RX6 MUX"},
7240 {"SLIM RX7", NULL, "SLIM RX7 MUX"},
7241
7242 {"RX INT0_1 MIX1 INP0", "RX0", "SLIM RX0"},
7243 {"RX INT0_1 MIX1 INP0", "RX1", "SLIM RX1"},
7244 {"RX INT0_1 MIX1 INP0", "RX2", "SLIM RX2"},
7245 {"RX INT0_1 MIX1 INP0", "RX3", "SLIM RX3"},
7246 {"RX INT0_1 MIX1 INP0", "RX4", "SLIM RX4"},
7247 {"RX INT0_1 MIX1 INP0", "RX5", "SLIM RX5"},
7248 {"RX INT0_1 MIX1 INP0", "RX6", "SLIM RX6"},
7249 {"RX INT0_1 MIX1 INP0", "RX7", "SLIM RX7"},
7250 {"RX INT0_1 MIX1 INP0", "IIR0", "IIR0"},
7251 {"RX INT0_1 MIX1 INP0", "IIR1", "IIR1"},
7252 {"RX INT0_1 MIX1 INP1", "RX0", "SLIM RX0"},
7253 {"RX INT0_1 MIX1 INP1", "RX1", "SLIM RX1"},
7254 {"RX INT0_1 MIX1 INP1", "RX2", "SLIM RX2"},
7255 {"RX INT0_1 MIX1 INP1", "RX3", "SLIM RX3"},
7256 {"RX INT0_1 MIX1 INP1", "RX4", "SLIM RX4"},
7257 {"RX INT0_1 MIX1 INP1", "RX5", "SLIM RX5"},
7258 {"RX INT0_1 MIX1 INP1", "RX6", "SLIM RX6"},
7259 {"RX INT0_1 MIX1 INP1", "RX7", "SLIM RX7"},
7260 {"RX INT0_1 MIX1 INP1", "IIR0", "IIR0"},
7261 {"RX INT0_1 MIX1 INP1", "IIR1", "IIR1"},
7262 {"RX INT0_1 MIX1 INP2", "RX0", "SLIM RX0"},
7263 {"RX INT0_1 MIX1 INP2", "RX1", "SLIM RX1"},
7264 {"RX INT0_1 MIX1 INP2", "RX2", "SLIM RX2"},
7265 {"RX INT0_1 MIX1 INP2", "RX3", "SLIM RX3"},
7266 {"RX INT0_1 MIX1 INP2", "RX4", "SLIM RX4"},
7267 {"RX INT0_1 MIX1 INP2", "RX5", "SLIM RX5"},
7268 {"RX INT0_1 MIX1 INP2", "RX6", "SLIM RX6"},
7269 {"RX INT0_1 MIX1 INP2", "RX7", "SLIM RX7"},
7270 {"RX INT0_1 MIX1 INP2", "IIR0", "IIR0"},
7271 {"RX INT0_1 MIX1 INP2", "IIR1", "IIR1"},
7272
7273 /* MIXing path INT0 */
7274 {"RX INT0_2 MUX", "RX0", "SLIM RX0"},
7275 {"RX INT0_2 MUX", "RX1", "SLIM RX1"},
7276 {"RX INT0_2 MUX", "RX2", "SLIM RX2"},
7277 {"RX INT0_2 MUX", "RX3", "SLIM RX3"},
7278 {"RX INT0_2 MUX", "RX4", "SLIM RX4"},
7279 {"RX INT0_2 MUX", "RX5", "SLIM RX5"},
7280 {"RX INT0_2 MUX", "RX6", "SLIM RX6"},
7281 {"RX INT0_2 MUX", "RX7", "SLIM RX7"},
7282 {"RX INT0 SEC MIX", NULL, "RX INT0_2 MUX"},
7283
7284 /* MIXing path INT1 */
7285 {"RX INT1_2 MUX", "RX0", "SLIM RX0"},
7286 {"RX INT1_2 MUX", "RX1", "SLIM RX1"},
7287 {"RX INT1_2 MUX", "RX2", "SLIM RX2"},
7288 {"RX INT1_2 MUX", "RX3", "SLIM RX3"},
7289 {"RX INT1_2 MUX", "RX4", "SLIM RX4"},
7290 {"RX INT1_2 MUX", "RX5", "SLIM RX5"},
7291 {"RX INT1_2 MUX", "RX6", "SLIM RX6"},
7292 {"RX INT1_2 MUX", "RX7", "SLIM RX7"},
7293 {"RX INT1 SEC MIX", NULL, "RX INT1_2 MUX"},
7294
7295 /* MIXing path INT2 */
7296 {"RX INT2_2 MUX", "RX0", "SLIM RX0"},
7297 {"RX INT2_2 MUX", "RX1", "SLIM RX1"},
7298 {"RX INT2_2 MUX", "RX2", "SLIM RX2"},
7299 {"RX INT2_2 MUX", "RX3", "SLIM RX3"},
7300 {"RX INT2_2 MUX", "RX4", "SLIM RX4"},
7301 {"RX INT2_2 MUX", "RX5", "SLIM RX5"},
7302 {"RX INT2_2 MUX", "RX6", "SLIM RX6"},
7303 {"RX INT2_2 MUX", "RX7", "SLIM RX7"},
7304 {"RX INT2 SEC MIX", NULL, "RX INT2_2 MUX"},
7305
7306 /* MIXing path INT3 */
7307 {"RX INT3_2 MUX", "RX0", "SLIM RX0"},
7308 {"RX INT3_2 MUX", "RX1", "SLIM RX1"},
7309 {"RX INT3_2 MUX", "RX2", "SLIM RX2"},
7310 {"RX INT3_2 MUX", "RX3", "SLIM RX3"},
7311 {"RX INT3_2 MUX", "RX4", "SLIM RX4"},
7312 {"RX INT3_2 MUX", "RX5", "SLIM RX5"},
7313 {"RX INT3_2 MUX", "RX6", "SLIM RX6"},
7314 {"RX INT3_2 MUX", "RX7", "SLIM RX7"},
7315 {"RX INT3 SEC MIX", NULL, "RX INT3_2 MUX"},
7316
7317 /* MIXing path INT4 */
7318 {"RX INT4_2 MUX", "RX0", "SLIM RX0"},
7319 {"RX INT4_2 MUX", "RX1", "SLIM RX1"},
7320 {"RX INT4_2 MUX", "RX2", "SLIM RX2"},
7321 {"RX INT4_2 MUX", "RX3", "SLIM RX3"},
7322 {"RX INT4_2 MUX", "RX4", "SLIM RX4"},
7323 {"RX INT4_2 MUX", "RX5", "SLIM RX5"},
7324 {"RX INT4_2 MUX", "RX6", "SLIM RX6"},
7325 {"RX INT4_2 MUX", "RX7", "SLIM RX7"},
7326 {"RX INT4 SEC MIX", NULL, "RX INT4_2 MUX"},
7327
7328 /* MIXing path INT5 */
7329 {"RX INT5_2 MUX", "RX0", "SLIM RX0"},
7330 {"RX INT5_2 MUX", "RX1", "SLIM RX1"},
7331 {"RX INT5_2 MUX", "RX2", "SLIM RX2"},
7332 {"RX INT5_2 MUX", "RX3", "SLIM RX3"},
7333 {"RX INT5_2 MUX", "RX4", "SLIM RX4"},
7334 {"RX INT5_2 MUX", "RX5", "SLIM RX5"},
7335 {"RX INT5_2 MUX", "RX6", "SLIM RX6"},
7336 {"RX INT5_2 MUX", "RX7", "SLIM RX7"},
7337 {"RX INT5 SEC MIX", NULL, "RX INT5_2 MUX"},
7338
7339 /* MIXing path INT6 */
7340 {"RX INT6_2 MUX", "RX0", "SLIM RX0"},
7341 {"RX INT6_2 MUX", "RX1", "SLIM RX1"},
7342 {"RX INT6_2 MUX", "RX2", "SLIM RX2"},
7343 {"RX INT6_2 MUX", "RX3", "SLIM RX3"},
7344 {"RX INT6_2 MUX", "RX4", "SLIM RX4"},
7345 {"RX INT6_2 MUX", "RX5", "SLIM RX5"},
7346 {"RX INT6_2 MUX", "RX6", "SLIM RX6"},
7347 {"RX INT6_2 MUX", "RX7", "SLIM RX7"},
7348 {"RX INT6 SEC MIX", NULL, "RX INT6_2 MUX"},
7349
7350 /* MIXing path INT7 */
7351 {"RX INT7_2 MUX", "RX0", "SLIM RX0"},
7352 {"RX INT7_2 MUX", "RX1", "SLIM RX1"},
7353 {"RX INT7_2 MUX", "RX2", "SLIM RX2"},
7354 {"RX INT7_2 MUX", "RX3", "SLIM RX3"},
7355 {"RX INT7_2 MUX", "RX4", "SLIM RX4"},
7356 {"RX INT7_2 MUX", "RX5", "SLIM RX5"},
7357 {"RX INT7_2 MUX", "RX6", "SLIM RX6"},
7358 {"RX INT7_2 MUX", "RX7", "SLIM RX7"},
7359 {"RX INT7 SEC MIX", NULL, "RX INT7_2 MUX"},
7360
7361 /* MIXing path INT8 */
7362 {"RX INT8_2 MUX", "RX0", "SLIM RX0"},
7363 {"RX INT8_2 MUX", "RX1", "SLIM RX1"},
7364 {"RX INT8_2 MUX", "RX2", "SLIM RX2"},
7365 {"RX INT8_2 MUX", "RX3", "SLIM RX3"},
7366 {"RX INT8_2 MUX", "RX4", "SLIM RX4"},
7367 {"RX INT8_2 MUX", "RX5", "SLIM RX5"},
7368 {"RX INT8_2 MUX", "RX6", "SLIM RX6"},
7369 {"RX INT8_2 MUX", "RX7", "SLIM RX7"},
7370 {"RX INT8 SEC MIX", NULL, "RX INT8_2 MUX"},
7371
7372 {"RX INT1_1 MIX1 INP0", "RX0", "SLIM RX0"},
7373 {"RX INT1_1 MIX1 INP0", "RX1", "SLIM RX1"},
7374 {"RX INT1_1 MIX1 INP0", "RX2", "SLIM RX2"},
7375 {"RX INT1_1 MIX1 INP0", "RX3", "SLIM RX3"},
7376 {"RX INT1_1 MIX1 INP0", "RX4", "SLIM RX4"},
7377 {"RX INT1_1 MIX1 INP0", "RX5", "SLIM RX5"},
7378 {"RX INT1_1 MIX1 INP0", "RX6", "SLIM RX6"},
7379 {"RX INT1_1 MIX1 INP0", "RX7", "SLIM RX7"},
7380 {"RX INT1_1 MIX1 INP0", "IIR0", "IIR0"},
7381 {"RX INT1_1 MIX1 INP0", "IIR1", "IIR1"},
7382 {"RX INT1_1 MIX1 INP1", "RX0", "SLIM RX0"},
7383 {"RX INT1_1 MIX1 INP1", "RX1", "SLIM RX1"},
7384 {"RX INT1_1 MIX1 INP1", "RX2", "SLIM RX2"},
7385 {"RX INT1_1 MIX1 INP1", "RX3", "SLIM RX3"},
7386 {"RX INT1_1 MIX1 INP1", "RX4", "SLIM RX4"},
7387 {"RX INT1_1 MIX1 INP1", "RX5", "SLIM RX5"},
7388 {"RX INT1_1 MIX1 INP1", "RX6", "SLIM RX6"},
7389 {"RX INT1_1 MIX1 INP1", "RX7", "SLIM RX7"},
7390 {"RX INT1_1 MIX1 INP1", "IIR0", "IIR0"},
7391 {"RX INT1_1 MIX1 INP1", "IIR1", "IIR1"},
7392 {"RX INT1_1 MIX1 INP2", "RX0", "SLIM RX0"},
7393 {"RX INT1_1 MIX1 INP2", "RX1", "SLIM RX1"},
7394 {"RX INT1_1 MIX1 INP2", "RX2", "SLIM RX2"},
7395 {"RX INT1_1 MIX1 INP2", "RX3", "SLIM RX3"},
7396 {"RX INT1_1 MIX1 INP2", "RX4", "SLIM RX4"},
7397 {"RX INT1_1 MIX1 INP2", "RX5", "SLIM RX5"},
7398 {"RX INT1_1 MIX1 INP2", "RX6", "SLIM RX6"},
7399 {"RX INT1_1 MIX1 INP2", "RX7", "SLIM RX7"},
7400 {"RX INT1_1 MIX1 INP2", "IIR0", "IIR0"},
7401 {"RX INT1_1 MIX1 INP2", "IIR1", "IIR1"},
7402 {"RX INT2_1 MIX1 INP0", "RX0", "SLIM RX0"},
7403 {"RX INT2_1 MIX1 INP0", "RX1", "SLIM RX1"},
7404 {"RX INT2_1 MIX1 INP0", "RX2", "SLIM RX2"},
7405 {"RX INT2_1 MIX1 INP0", "RX3", "SLIM RX3"},
7406 {"RX INT2_1 MIX1 INP0", "RX4", "SLIM RX4"},
7407 {"RX INT2_1 MIX1 INP0", "RX5", "SLIM RX5"},
7408 {"RX INT2_1 MIX1 INP0", "RX6", "SLIM RX6"},
7409 {"RX INT2_1 MIX1 INP0", "RX7", "SLIM RX7"},
7410 {"RX INT2_1 MIX1 INP0", "IIR0", "IIR0"},
7411 {"RX INT2_1 MIX1 INP0", "IIR1", "IIR1"},
7412 {"RX INT2_1 MIX1 INP1", "RX0", "SLIM RX0"},
7413 {"RX INT2_1 MIX1 INP1", "RX1", "SLIM RX1"},
7414 {"RX INT2_1 MIX1 INP1", "RX2", "SLIM RX2"},
7415 {"RX INT2_1 MIX1 INP1", "RX3", "SLIM RX3"},
7416 {"RX INT2_1 MIX1 INP1", "RX4", "SLIM RX4"},
7417 {"RX INT2_1 MIX1 INP1", "RX5", "SLIM RX5"},
7418 {"RX INT2_1 MIX1 INP1", "RX6", "SLIM RX6"},
7419 {"RX INT2_1 MIX1 INP1", "RX7", "SLIM RX7"},
7420 {"RX INT2_1 MIX1 INP1", "IIR0", "IIR0"},
7421 {"RX INT2_1 MIX1 INP1", "IIR1", "IIR1"},
7422 {"RX INT2_1 MIX1 INP2", "RX0", "SLIM RX0"},
7423 {"RX INT2_1 MIX1 INP2", "RX1", "SLIM RX1"},
7424 {"RX INT2_1 MIX1 INP2", "RX2", "SLIM RX2"},
7425 {"RX INT2_1 MIX1 INP2", "RX3", "SLIM RX3"},
7426 {"RX INT2_1 MIX1 INP2", "RX4", "SLIM RX4"},
7427 {"RX INT2_1 MIX1 INP2", "RX5", "SLIM RX5"},
7428 {"RX INT2_1 MIX1 INP2", "RX6", "SLIM RX6"},
7429 {"RX INT2_1 MIX1 INP2", "RX7", "SLIM RX7"},
7430 {"RX INT2_1 MIX1 INP2", "IIR0", "IIR0"},
7431 {"RX INT2_1 MIX1 INP2", "IIR1", "IIR1"},
7432
7433 {"RX INT3_1 MIX1 INP0", "RX0", "SLIM RX0"},
7434 {"RX INT3_1 MIX1 INP0", "RX1", "SLIM RX1"},
7435 {"RX INT3_1 MIX1 INP0", "RX2", "SLIM RX2"},
7436 {"RX INT3_1 MIX1 INP0", "RX3", "SLIM RX3"},
7437 {"RX INT3_1 MIX1 INP0", "RX4", "SLIM RX4"},
7438 {"RX INT3_1 MIX1 INP0", "RX5", "SLIM RX5"},
7439 {"RX INT3_1 MIX1 INP0", "RX6", "SLIM RX6"},
7440 {"RX INT3_1 MIX1 INP0", "RX7", "SLIM RX7"},
7441 {"RX INT3_1 MIX1 INP0", "IIR0", "IIR0"},
7442 {"RX INT3_1 MIX1 INP0", "IIR1", "IIR1"},
7443 {"RX INT3_1 MIX1 INP1", "RX0", "SLIM RX0"},
7444 {"RX INT3_1 MIX1 INP1", "RX1", "SLIM RX1"},
7445 {"RX INT3_1 MIX1 INP1", "RX2", "SLIM RX2"},
7446 {"RX INT3_1 MIX1 INP1", "RX3", "SLIM RX3"},
7447 {"RX INT3_1 MIX1 INP1", "RX4", "SLIM RX4"},
7448 {"RX INT3_1 MIX1 INP1", "RX5", "SLIM RX5"},
7449 {"RX INT3_1 MIX1 INP1", "RX6", "SLIM RX6"},
7450 {"RX INT3_1 MIX1 INP1", "RX7", "SLIM RX7"},
7451 {"RX INT3_1 MIX1 INP1", "IIR0", "IIR0"},
7452 {"RX INT3_1 MIX1 INP1", "IIR1", "IIR1"},
7453 {"RX INT3_1 MIX1 INP2", "RX0", "SLIM RX0"},
7454 {"RX INT3_1 MIX1 INP2", "RX1", "SLIM RX1"},
7455 {"RX INT3_1 MIX1 INP2", "RX2", "SLIM RX2"},
7456 {"RX INT3_1 MIX1 INP2", "RX3", "SLIM RX3"},
7457 {"RX INT3_1 MIX1 INP2", "RX4", "SLIM RX4"},
7458 {"RX INT3_1 MIX1 INP2", "RX5", "SLIM RX5"},
7459 {"RX INT3_1 MIX1 INP2", "RX6", "SLIM RX6"},
7460 {"RX INT3_1 MIX1 INP2", "RX7", "SLIM RX7"},
7461 {"RX INT3_1 MIX1 INP2", "IIR0", "IIR0"},
7462 {"RX INT3_1 MIX1 INP2", "IIR1", "IIR1"},
7463
7464 {"RX INT4_1 MIX1 INP0", "RX0", "SLIM RX0"},
7465 {"RX INT4_1 MIX1 INP0", "RX1", "SLIM RX1"},
7466 {"RX INT4_1 MIX1 INP0", "RX2", "SLIM RX2"},
7467 {"RX INT4_1 MIX1 INP0", "RX3", "SLIM RX3"},
7468 {"RX INT4_1 MIX1 INP0", "RX4", "SLIM RX4"},
7469 {"RX INT4_1 MIX1 INP0", "RX5", "SLIM RX5"},
7470 {"RX INT4_1 MIX1 INP0", "RX6", "SLIM RX6"},
7471 {"RX INT4_1 MIX1 INP0", "RX7", "SLIM RX7"},
7472 {"RX INT4_1 MIX1 INP0", "IIR0", "IIR0"},
7473 {"RX INT4_1 MIX1 INP0", "IIR1", "IIR1"},
7474 {"RX INT4_1 MIX1 INP1", "RX0", "SLIM RX0"},
7475 {"RX INT4_1 MIX1 INP1", "RX1", "SLIM RX1"},
7476 {"RX INT4_1 MIX1 INP1", "RX2", "SLIM RX2"},
7477 {"RX INT4_1 MIX1 INP1", "RX3", "SLIM RX3"},
7478 {"RX INT4_1 MIX1 INP1", "RX4", "SLIM RX4"},
7479 {"RX INT4_1 MIX1 INP1", "RX5", "SLIM RX5"},
7480 {"RX INT4_1 MIX1 INP1", "RX6", "SLIM RX6"},
7481 {"RX INT4_1 MIX1 INP1", "RX7", "SLIM RX7"},
7482 {"RX INT4_1 MIX1 INP1", "IIR0", "IIR0"},
7483 {"RX INT4_1 MIX1 INP1", "IIR1", "IIR1"},
7484 {"RX INT4_1 MIX1 INP2", "RX0", "SLIM RX0"},
7485 {"RX INT4_1 MIX1 INP2", "RX1", "SLIM RX1"},
7486 {"RX INT4_1 MIX1 INP2", "RX2", "SLIM RX2"},
7487 {"RX INT4_1 MIX1 INP2", "RX3", "SLIM RX3"},
7488 {"RX INT4_1 MIX1 INP2", "RX4", "SLIM RX4"},
7489 {"RX INT4_1 MIX1 INP2", "RX5", "SLIM RX5"},
7490 {"RX INT4_1 MIX1 INP2", "RX6", "SLIM RX6"},
7491 {"RX INT4_1 MIX1 INP2", "RX7", "SLIM RX7"},
7492 {"RX INT4_1 MIX1 INP2", "IIR0", "IIR0"},
7493 {"RX INT4_1 MIX1 INP2", "IIR1", "IIR1"},
7494
7495 {"RX INT5_1 MIX1 INP0", "RX0", "SLIM RX0"},
7496 {"RX INT5_1 MIX1 INP0", "RX1", "SLIM RX1"},
7497 {"RX INT5_1 MIX1 INP0", "RX2", "SLIM RX2"},
7498 {"RX INT5_1 MIX1 INP0", "RX3", "SLIM RX3"},
7499 {"RX INT5_1 MIX1 INP0", "RX4", "SLIM RX4"},
7500 {"RX INT5_1 MIX1 INP0", "RX5", "SLIM RX5"},
7501 {"RX INT5_1 MIX1 INP0", "RX6", "SLIM RX6"},
7502 {"RX INT5_1 MIX1 INP0", "RX7", "SLIM RX7"},
7503 {"RX INT5_1 MIX1 INP0", "IIR0", "IIR0"},
7504 {"RX INT5_1 MIX1 INP0", "IIR1", "IIR1"},
7505 {"RX INT5_1 MIX1 INP1", "RX0", "SLIM RX0"},
7506 {"RX INT5_1 MIX1 INP1", "RX1", "SLIM RX1"},
7507 {"RX INT5_1 MIX1 INP1", "RX2", "SLIM RX2"},
7508 {"RX INT5_1 MIX1 INP1", "RX3", "SLIM RX3"},
7509 {"RX INT5_1 MIX1 INP1", "RX4", "SLIM RX4"},
7510 {"RX INT5_1 MIX1 INP1", "RX5", "SLIM RX5"},
7511 {"RX INT5_1 MIX1 INP1", "RX6", "SLIM RX6"},
7512 {"RX INT5_1 MIX1 INP1", "RX7", "SLIM RX7"},
7513 {"RX INT5_1 MIX1 INP1", "IIR0", "IIR0"},
7514 {"RX INT5_1 MIX1 INP1", "IIR1", "IIR1"},
7515 {"RX INT5_1 MIX1 INP2", "RX0", "SLIM RX0"},
7516 {"RX INT5_1 MIX1 INP2", "RX1", "SLIM RX1"},
7517 {"RX INT5_1 MIX1 INP2", "RX2", "SLIM RX2"},
7518 {"RX INT5_1 MIX1 INP2", "RX3", "SLIM RX3"},
7519 {"RX INT5_1 MIX1 INP2", "RX4", "SLIM RX4"},
7520 {"RX INT5_1 MIX1 INP2", "RX5", "SLIM RX5"},
7521 {"RX INT5_1 MIX1 INP2", "RX6", "SLIM RX6"},
7522 {"RX INT5_1 MIX1 INP2", "RX7", "SLIM RX7"},
7523 {"RX INT5_1 MIX1 INP2", "IIR0", "IIR0"},
7524 {"RX INT5_1 MIX1 INP2", "IIR1", "IIR1"},
7525
7526 {"RX INT6_1 MIX1 INP0", "RX0", "SLIM RX0"},
7527 {"RX INT6_1 MIX1 INP0", "RX1", "SLIM RX1"},
7528 {"RX INT6_1 MIX1 INP0", "RX2", "SLIM RX2"},
7529 {"RX INT6_1 MIX1 INP0", "RX3", "SLIM RX3"},
7530 {"RX INT6_1 MIX1 INP0", "RX4", "SLIM RX4"},
7531 {"RX INT6_1 MIX1 INP0", "RX5", "SLIM RX5"},
7532 {"RX INT6_1 MIX1 INP0", "RX6", "SLIM RX6"},
7533 {"RX INT6_1 MIX1 INP0", "RX7", "SLIM RX7"},
7534 {"RX INT6_1 MIX1 INP0", "IIR0", "IIR0"},
7535 {"RX INT6_1 MIX1 INP0", "IIR1", "IIR1"},
7536 {"RX INT6_1 MIX1 INP1", "RX0", "SLIM RX0"},
7537 {"RX INT6_1 MIX1 INP1", "RX1", "SLIM RX1"},
7538 {"RX INT6_1 MIX1 INP1", "RX2", "SLIM RX2"},
7539 {"RX INT6_1 MIX1 INP1", "RX3", "SLIM RX3"},
7540 {"RX INT6_1 MIX1 INP1", "RX4", "SLIM RX4"},
7541 {"RX INT6_1 MIX1 INP1", "RX5", "SLIM RX5"},
7542 {"RX INT6_1 MIX1 INP1", "RX6", "SLIM RX6"},
7543 {"RX INT6_1 MIX1 INP1", "RX7", "SLIM RX7"},
7544 {"RX INT6_1 MIX1 INP1", "IIR0", "IIR0"},
7545 {"RX INT6_1 MIX1 INP1", "IIR1", "IIR1"},
7546 {"RX INT6_1 MIX1 INP2", "RX0", "SLIM RX0"},
7547 {"RX INT6_1 MIX1 INP2", "RX1", "SLIM RX1"},
7548 {"RX INT6_1 MIX1 INP2", "RX2", "SLIM RX2"},
7549 {"RX INT6_1 MIX1 INP2", "RX3", "SLIM RX3"},
7550 {"RX INT6_1 MIX1 INP2", "RX4", "SLIM RX4"},
7551 {"RX INT6_1 MIX1 INP2", "RX5", "SLIM RX5"},
7552 {"RX INT6_1 MIX1 INP2", "RX6", "SLIM RX6"},
7553 {"RX INT6_1 MIX1 INP2", "RX7", "SLIM RX7"},
7554 {"RX INT6_1 MIX1 INP2", "IIR0", "IIR0"},
7555 {"RX INT6_1 MIX1 INP2", "IIR1", "IIR1"},
7556
7557 {"RX INT7_1 MIX1 INP0", "RX0", "SLIM RX0"},
7558 {"RX INT7_1 MIX1 INP0", "RX1", "SLIM RX1"},
7559 {"RX INT7_1 MIX1 INP0", "RX2", "SLIM RX2"},
7560 {"RX INT7_1 MIX1 INP0", "RX3", "SLIM RX3"},
7561 {"RX INT7_1 MIX1 INP0", "RX4", "SLIM RX4"},
7562 {"RX INT7_1 MIX1 INP0", "RX5", "SLIM RX5"},
7563 {"RX INT7_1 MIX1 INP0", "RX6", "SLIM RX6"},
7564 {"RX INT7_1 MIX1 INP0", "RX7", "SLIM RX7"},
7565 {"RX INT7_1 MIX1 INP0", "IIR0", "IIR0"},
7566 {"RX INT7_1 MIX1 INP0", "IIR1", "IIR1"},
7567 {"RX INT7_1 MIX1 INP1", "RX0", "SLIM RX0"},
7568 {"RX INT7_1 MIX1 INP1", "RX1", "SLIM RX1"},
7569 {"RX INT7_1 MIX1 INP1", "RX2", "SLIM RX2"},
7570 {"RX INT7_1 MIX1 INP1", "RX3", "SLIM RX3"},
7571 {"RX INT7_1 MIX1 INP1", "RX4", "SLIM RX4"},
7572 {"RX INT7_1 MIX1 INP1", "RX5", "SLIM RX5"},
7573 {"RX INT7_1 MIX1 INP1", "RX6", "SLIM RX6"},
7574 {"RX INT7_1 MIX1 INP1", "RX7", "SLIM RX7"},
7575 {"RX INT7_1 MIX1 INP1", "IIR0", "IIR0"},
7576 {"RX INT7_1 MIX1 INP1", "IIR1", "IIR1"},
7577 {"RX INT7_1 MIX1 INP2", "RX0", "SLIM RX0"},
7578 {"RX INT7_1 MIX1 INP2", "RX1", "SLIM RX1"},
7579 {"RX INT7_1 MIX1 INP2", "RX2", "SLIM RX2"},
7580 {"RX INT7_1 MIX1 INP2", "RX3", "SLIM RX3"},
7581 {"RX INT7_1 MIX1 INP2", "RX4", "SLIM RX4"},
7582 {"RX INT7_1 MIX1 INP2", "RX5", "SLIM RX5"},
7583 {"RX INT7_1 MIX1 INP2", "RX6", "SLIM RX6"},
7584 {"RX INT7_1 MIX1 INP2", "RX7", "SLIM RX7"},
7585 {"RX INT7_1 MIX1 INP2", "IIR0", "IIR0"},
7586 {"RX INT7_1 MIX1 INP2", "IIR1", "IIR1"},
7587
7588 {"RX INT8_1 MIX1 INP0", "RX0", "SLIM RX0"},
7589 {"RX INT8_1 MIX1 INP0", "RX1", "SLIM RX1"},
7590 {"RX INT8_1 MIX1 INP0", "RX2", "SLIM RX2"},
7591 {"RX INT8_1 MIX1 INP0", "RX3", "SLIM RX3"},
7592 {"RX INT8_1 MIX1 INP0", "RX4", "SLIM RX4"},
7593 {"RX INT8_1 MIX1 INP0", "RX5", "SLIM RX5"},
7594 {"RX INT8_1 MIX1 INP0", "RX6", "SLIM RX6"},
7595 {"RX INT8_1 MIX1 INP0", "RX7", "SLIM RX7"},
7596 {"RX INT8_1 MIX1 INP0", "IIR0", "IIR0"},
7597 {"RX INT8_1 MIX1 INP0", "IIR1", "IIR1"},
7598 {"RX INT8_1 MIX1 INP1", "RX0", "SLIM RX0"},
7599 {"RX INT8_1 MIX1 INP1", "RX1", "SLIM RX1"},
7600 {"RX INT8_1 MIX1 INP1", "RX2", "SLIM RX2"},
7601 {"RX INT8_1 MIX1 INP1", "RX3", "SLIM RX3"},
7602 {"RX INT8_1 MIX1 INP1", "RX4", "SLIM RX4"},
7603 {"RX INT8_1 MIX1 INP1", "RX5", "SLIM RX5"},
7604 {"RX INT8_1 MIX1 INP1", "RX6", "SLIM RX6"},
7605 {"RX INT8_1 MIX1 INP1", "RX7", "SLIM RX7"},
7606 {"RX INT8_1 MIX1 INP1", "IIR0", "IIR0"},
7607 {"RX INT8_1 MIX1 INP1", "IIR1", "IIR1"},
7608 {"RX INT8_1 MIX1 INP2", "RX0", "SLIM RX0"},
7609 {"RX INT8_1 MIX1 INP2", "RX1", "SLIM RX1"},
7610 {"RX INT8_1 MIX1 INP2", "RX2", "SLIM RX2"},
7611 {"RX INT8_1 MIX1 INP2", "RX3", "SLIM RX3"},
7612 {"RX INT8_1 MIX1 INP2", "RX4", "SLIM RX4"},
7613 {"RX INT8_1 MIX1 INP2", "RX5", "SLIM RX5"},
7614 {"RX INT8_1 MIX1 INP2", "RX6", "SLIM RX6"},
7615 {"RX INT8_1 MIX1 INP2", "RX7", "SLIM RX7"},
7616 {"RX INT8_1 MIX1 INP2", "IIR0", "IIR0"},
7617 {"RX INT8_1 MIX1 INP2", "IIR1", "IIR1"},
7618
7619 /* SRC0, SRC1 inputs to Sidetone RX Mixer
7620 * on RX0, RX1, RX2, RX3, RX4 and RX7 chains
7621 */
7622 {"IIR0", NULL, "IIR0 INP0 MUX"},
7623 {"IIR0 INP0 MUX", "DEC0", "ADC MUX0"},
7624 {"IIR0 INP0 MUX", "DEC1", "ADC MUX1"},
7625 {"IIR0 INP0 MUX", "DEC2", "ADC MUX2"},
7626 {"IIR0 INP0 MUX", "DEC3", "ADC MUX3"},
7627 {"IIR0 INP0 MUX", "DEC4", "ADC MUX4"},
7628 {"IIR0 INP0 MUX", "DEC5", "ADC MUX5"},
7629 {"IIR0 INP0 MUX", "DEC6", "ADC MUX6"},
7630 {"IIR0 INP0 MUX", "DEC7", "ADC MUX7"},
7631 {"IIR0 INP0 MUX", "DEC8", "ADC MUX8"},
7632 {"IIR0 INP0 MUX", "RX0", "SLIM RX0"},
7633 {"IIR0 INP0 MUX", "RX1", "SLIM RX1"},
7634 {"IIR0 INP0 MUX", "RX2", "SLIM RX2"},
7635 {"IIR0 INP0 MUX", "RX3", "SLIM RX3"},
7636 {"IIR0 INP0 MUX", "RX4", "SLIM RX4"},
7637 {"IIR0 INP0 MUX", "RX5", "SLIM RX5"},
7638 {"IIR0 INP0 MUX", "RX6", "SLIM RX6"},
7639 {"IIR0 INP0 MUX", "RX7", "SLIM RX7"},
7640 {"IIR0", NULL, "IIR0 INP1 MUX"},
7641 {"IIR0 INP1 MUX", "DEC0", "ADC MUX0"},
7642 {"IIR0 INP1 MUX", "DEC1", "ADC MUX1"},
7643 {"IIR0 INP1 MUX", "DEC2", "ADC MUX2"},
7644 {"IIR0 INP1 MUX", "DEC3", "ADC MUX3"},
7645 {"IIR0 INP1 MUX", "DEC4", "ADC MUX4"},
7646 {"IIR0 INP1 MUX", "DEC5", "ADC MUX5"},
7647 {"IIR0 INP1 MUX", "DEC6", "ADC MUX6"},
7648 {"IIR0 INP1 MUX", "DEC7", "ADC MUX7"},
7649 {"IIR0 INP1 MUX", "DEC8", "ADC MUX8"},
7650 {"IIR0 INP1 MUX", "RX0", "SLIM RX0"},
7651 {"IIR0 INP1 MUX", "RX1", "SLIM RX1"},
7652 {"IIR0 INP1 MUX", "RX2", "SLIM RX2"},
7653 {"IIR0 INP1 MUX", "RX3", "SLIM RX3"},
7654 {"IIR0 INP1 MUX", "RX4", "SLIM RX4"},
7655 {"IIR0 INP1 MUX", "RX5", "SLIM RX5"},
7656 {"IIR0 INP1 MUX", "RX6", "SLIM RX6"},
7657 {"IIR0 INP1 MUX", "RX7", "SLIM RX7"},
7658 {"IIR0", NULL, "IIR0 INP2 MUX"},
7659 {"IIR0 INP2 MUX", "DEC0", "ADC MUX0"},
7660 {"IIR0 INP2 MUX", "DEC1", "ADC MUX1"},
7661 {"IIR0 INP2 MUX", "DEC2", "ADC MUX2"},
7662 {"IIR0 INP2 MUX", "DEC3", "ADC MUX3"},
7663 {"IIR0 INP2 MUX", "DEC4", "ADC MUX4"},
7664 {"IIR0 INP2 MUX", "DEC5", "ADC MUX5"},
7665 {"IIR0 INP2 MUX", "DEC6", "ADC MUX6"},
7666 {"IIR0 INP2 MUX", "DEC7", "ADC MUX7"},
7667 {"IIR0 INP2 MUX", "DEC8", "ADC MUX8"},
7668 {"IIR0 INP2 MUX", "RX0", "SLIM RX0"},
7669 {"IIR0 INP2 MUX", "RX1", "SLIM RX1"},
7670 {"IIR0 INP2 MUX", "RX2", "SLIM RX2"},
7671 {"IIR0 INP2 MUX", "RX3", "SLIM RX3"},
7672 {"IIR0 INP2 MUX", "RX4", "SLIM RX4"},
7673 {"IIR0 INP2 MUX", "RX5", "SLIM RX5"},
7674 {"IIR0 INP2 MUX", "RX6", "SLIM RX6"},
7675 {"IIR0 INP2 MUX", "RX7", "SLIM RX7"},
7676 {"IIR0", NULL, "IIR0 INP3 MUX"},
7677 {"IIR0 INP3 MUX", "DEC0", "ADC MUX0"},
7678 {"IIR0 INP3 MUX", "DEC1", "ADC MUX1"},
7679 {"IIR0 INP3 MUX", "DEC2", "ADC MUX2"},
7680 {"IIR0 INP3 MUX", "DEC3", "ADC MUX3"},
7681 {"IIR0 INP3 MUX", "DEC4", "ADC MUX4"},
7682 {"IIR0 INP3 MUX", "DEC5", "ADC MUX5"},
7683 {"IIR0 INP3 MUX", "DEC6", "ADC MUX6"},
7684 {"IIR0 INP3 MUX", "DEC7", "ADC MUX7"},
7685 {"IIR0 INP3 MUX", "DEC8", "ADC MUX8"},
7686 {"IIR0 INP3 MUX", "RX0", "SLIM RX0"},
7687 {"IIR0 INP3 MUX", "RX1", "SLIM RX1"},
7688 {"IIR0 INP3 MUX", "RX2", "SLIM RX2"},
7689 {"IIR0 INP3 MUX", "RX3", "SLIM RX3"},
7690 {"IIR0 INP3 MUX", "RX4", "SLIM RX4"},
7691 {"IIR0 INP3 MUX", "RX5", "SLIM RX5"},
7692 {"IIR0 INP3 MUX", "RX6", "SLIM RX6"},
7693 {"IIR0 INP3 MUX", "RX7", "SLIM RX7"},
7694
7695 {"IIR1", NULL, "IIR1 INP0 MUX"},
7696 {"IIR1 INP0 MUX", "DEC0", "ADC MUX0"},
7697 {"IIR1 INP0 MUX", "DEC1", "ADC MUX1"},
7698 {"IIR1 INP0 MUX", "DEC2", "ADC MUX2"},
7699 {"IIR1 INP0 MUX", "DEC3", "ADC MUX3"},
7700 {"IIR1 INP0 MUX", "DEC4", "ADC MUX4"},
7701 {"IIR1 INP0 MUX", "DEC5", "ADC MUX5"},
7702 {"IIR1 INP0 MUX", "DEC6", "ADC MUX6"},
7703 {"IIR1 INP0 MUX", "DEC7", "ADC MUX7"},
7704 {"IIR1 INP0 MUX", "DEC8", "ADC MUX8"},
7705 {"IIR1 INP0 MUX", "RX0", "SLIM RX0"},
7706 {"IIR1 INP0 MUX", "RX1", "SLIM RX1"},
7707 {"IIR1 INP0 MUX", "RX2", "SLIM RX2"},
7708 {"IIR1 INP0 MUX", "RX3", "SLIM RX3"},
7709 {"IIR1 INP0 MUX", "RX4", "SLIM RX4"},
7710 {"IIR1 INP0 MUX", "RX5", "SLIM RX5"},
7711 {"IIR1 INP0 MUX", "RX6", "SLIM RX6"},
7712 {"IIR1 INP0 MUX", "RX7", "SLIM RX7"},
7713 {"IIR1", NULL, "IIR1 INP1 MUX"},
7714 {"IIR1 INP1 MUX", "DEC0", "ADC MUX0"},
7715 {"IIR1 INP1 MUX", "DEC1", "ADC MUX1"},
7716 {"IIR1 INP1 MUX", "DEC2", "ADC MUX2"},
7717 {"IIR1 INP1 MUX", "DEC3", "ADC MUX3"},
7718 {"IIR1 INP1 MUX", "DEC4", "ADC MUX4"},
7719 {"IIR1 INP1 MUX", "DEC5", "ADC MUX5"},
7720 {"IIR1 INP1 MUX", "DEC6", "ADC MUX6"},
7721 {"IIR1 INP1 MUX", "DEC7", "ADC MUX7"},
7722 {"IIR1 INP1 MUX", "DEC8", "ADC MUX8"},
7723 {"IIR1 INP1 MUX", "RX0", "SLIM RX0"},
7724 {"IIR1 INP1 MUX", "RX1", "SLIM RX1"},
7725 {"IIR1 INP1 MUX", "RX2", "SLIM RX2"},
7726 {"IIR1 INP1 MUX", "RX3", "SLIM RX3"},
7727 {"IIR1 INP1 MUX", "RX4", "SLIM RX4"},
7728 {"IIR1 INP1 MUX", "RX5", "SLIM RX5"},
7729 {"IIR1 INP1 MUX", "RX6", "SLIM RX6"},
7730 {"IIR1 INP1 MUX", "RX7", "SLIM RX7"},
7731 {"IIR1", NULL, "IIR1 INP2 MUX"},
7732 {"IIR1 INP2 MUX", "DEC0", "ADC MUX0"},
7733 {"IIR1 INP2 MUX", "DEC1", "ADC MUX1"},
7734 {"IIR1 INP2 MUX", "DEC2", "ADC MUX2"},
7735 {"IIR1 INP2 MUX", "DEC3", "ADC MUX3"},
7736 {"IIR1 INP2 MUX", "DEC4", "ADC MUX4"},
7737 {"IIR1 INP2 MUX", "DEC5", "ADC MUX5"},
7738 {"IIR1 INP2 MUX", "DEC6", "ADC MUX6"},
7739 {"IIR1 INP2 MUX", "DEC7", "ADC MUX7"},
7740 {"IIR1 INP2 MUX", "DEC8", "ADC MUX8"},
7741 {"IIR1 INP2 MUX", "RX0", "SLIM RX0"},
7742 {"IIR1 INP2 MUX", "RX1", "SLIM RX1"},
7743 {"IIR1 INP2 MUX", "RX2", "SLIM RX2"},
7744 {"IIR1 INP2 MUX", "RX3", "SLIM RX3"},
7745 {"IIR1 INP2 MUX", "RX4", "SLIM RX4"},
7746 {"IIR1 INP2 MUX", "RX5", "SLIM RX5"},
7747 {"IIR1 INP2 MUX", "RX6", "SLIM RX6"},
7748 {"IIR1 INP2 MUX", "RX7", "SLIM RX7"},
7749 {"IIR1", NULL, "IIR1 INP3 MUX"},
7750 {"IIR1 INP3 MUX", "DEC0", "ADC MUX0"},
7751 {"IIR1 INP3 MUX", "DEC1", "ADC MUX1"},
7752 {"IIR1 INP3 MUX", "DEC2", "ADC MUX2"},
7753 {"IIR1 INP3 MUX", "DEC3", "ADC MUX3"},
7754 {"IIR1 INP3 MUX", "DEC4", "ADC MUX4"},
7755 {"IIR1 INP3 MUX", "DEC5", "ADC MUX5"},
7756 {"IIR1 INP3 MUX", "DEC6", "ADC MUX6"},
7757 {"IIR1 INP3 MUX", "DEC7", "ADC MUX7"},
7758 {"IIR1 INP3 MUX", "DEC8", "ADC MUX8"},
7759 {"IIR1 INP3 MUX", "RX0", "SLIM RX0"},
7760 {"IIR1 INP3 MUX", "RX1", "SLIM RX1"},
7761 {"IIR1 INP3 MUX", "RX2", "SLIM RX2"},
7762 {"IIR1 INP3 MUX", "RX3", "SLIM RX3"},
7763 {"IIR1 INP3 MUX", "RX4", "SLIM RX4"},
7764 {"IIR1 INP3 MUX", "RX5", "SLIM RX5"},
7765 {"IIR1 INP3 MUX", "RX6", "SLIM RX6"},
7766 {"IIR1 INP3 MUX", "RX7", "SLIM RX7"},
7767
7768 {"SRC0", NULL, "IIR0"},
7769 {"SRC1", NULL, "IIR1"},
7770 {"RX INT0 MIX2 INP", "SRC0", "SRC0"},
7771 {"RX INT0 MIX2 INP", "SRC1", "SRC1"},
7772 {"RX INT1 MIX2 INP", "SRC0", "SRC0"},
7773 {"RX INT1 MIX2 INP", "SRC1", "SRC1"},
7774 {"RX INT2 MIX2 INP", "SRC0", "SRC0"},
7775 {"RX INT2 MIX2 INP", "SRC1", "SRC1"},
7776 {"RX INT3 MIX2 INP", "SRC0", "SRC0"},
7777 {"RX INT3 MIX2 INP", "SRC1", "SRC1"},
7778 {"RX INT4 MIX2 INP", "SRC0", "SRC0"},
7779 {"RX INT4 MIX2 INP", "SRC1", "SRC1"},
7780 {"RX INT7 MIX2 INP", "SRC0", "SRC0"},
7781 {"RX INT7 MIX2 INP", "SRC1", "SRC1"},
7782};
7783
7784static int tasha_amic_pwr_lvl_get(struct snd_kcontrol *kcontrol,
7785 struct snd_ctl_elem_value *ucontrol)
7786{
7787 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
7788 u16 amic_reg;
7789
7790 if (!strcmp(kcontrol->id.name, "AMIC_1_2 PWR MODE"))
7791 amic_reg = WCD9335_ANA_AMIC1;
7792 if (!strcmp(kcontrol->id.name, "AMIC_3_4 PWR MODE"))
7793 amic_reg = WCD9335_ANA_AMIC3;
7794 if (!strcmp(kcontrol->id.name, "AMIC_5_6 PWR MODE"))
7795 amic_reg = WCD9335_ANA_AMIC5;
7796
7797 ucontrol->value.integer.value[0] =
7798 (snd_soc_read(codec, amic_reg) & WCD9335_AMIC_PWR_LVL_MASK) >>
7799 WCD9335_AMIC_PWR_LVL_SHIFT;
7800
7801 return 0;
7802}
7803
7804static int tasha_amic_pwr_lvl_put(struct snd_kcontrol *kcontrol,
7805 struct snd_ctl_elem_value *ucontrol)
7806{
7807 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
7808 u32 mode_val;
7809 u16 amic_reg;
7810
7811 mode_val = ucontrol->value.enumerated.item[0];
7812
7813 dev_dbg(codec->dev, "%s: mode: %d\n",
7814 __func__, mode_val);
7815
7816 if (!strcmp(kcontrol->id.name, "AMIC_1_2 PWR MODE"))
7817 amic_reg = WCD9335_ANA_AMIC1;
7818 if (!strcmp(kcontrol->id.name, "AMIC_3_4 PWR MODE"))
7819 amic_reg = WCD9335_ANA_AMIC3;
7820 if (!strcmp(kcontrol->id.name, "AMIC_5_6 PWR MODE"))
7821 amic_reg = WCD9335_ANA_AMIC5;
7822
7823 snd_soc_update_bits(codec, amic_reg, WCD9335_AMIC_PWR_LVL_MASK,
7824 mode_val << WCD9335_AMIC_PWR_LVL_SHIFT);
7825
7826 return 0;
7827}
7828
7829static int tasha_rx_hph_mode_get(struct snd_kcontrol *kcontrol,
7830 struct snd_ctl_elem_value *ucontrol)
7831{
7832 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
7833 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
7834
7835 ucontrol->value.integer.value[0] = tasha->hph_mode;
7836 return 0;
7837}
7838
7839static int tasha_rx_hph_mode_put(struct snd_kcontrol *kcontrol,
7840 struct snd_ctl_elem_value *ucontrol)
7841{
7842 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
7843 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
7844 u32 mode_val;
7845
7846 mode_val = ucontrol->value.enumerated.item[0];
7847
7848 dev_dbg(codec->dev, "%s: mode: %d\n",
7849 __func__, mode_val);
7850
7851 if (mode_val == 0) {
7852 dev_warn(codec->dev, "%s:Invalid HPH Mode, default to Cls-H HiFi\n",
7853 __func__);
7854 mode_val = CLS_H_HIFI;
7855 }
7856 tasha->hph_mode = mode_val;
7857 return 0;
7858}
7859
7860static const char *const tasha_conn_mad_text[] = {
7861 "NOTUSED1", "ADC1", "ADC2", "ADC3", "ADC4", "ADC5", "ADC6",
7862 "NOTUSED2", "DMIC0", "DMIC1", "DMIC2", "DMIC3", "DMIC4",
7863 "DMIC5", "NOTUSED3", "NOTUSED4"
7864};
7865
7866static const struct soc_enum tasha_conn_mad_enum =
7867 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tasha_conn_mad_text),
7868 tasha_conn_mad_text);
7869
7870static int tasha_enable_ldo_h_get(struct snd_kcontrol *kcontrol,
7871 struct snd_ctl_elem_value *ucontrol)
7872{
7873 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
7874 u8 val = 0;
7875
7876 if (codec)
7877 val = snd_soc_read(codec, WCD9335_LDOH_MODE) & 0x80;
7878
7879 ucontrol->value.integer.value[0] = !!val;
7880
7881 return 0;
7882}
7883
7884static int tasha_enable_ldo_h_put(struct snd_kcontrol *kcontrol,
7885 struct snd_ctl_elem_value *ucontrol)
7886{
7887 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
7888 int value = ucontrol->value.integer.value[0];
7889 bool enable;
7890
7891 enable = !!value;
7892 if (codec)
7893 tasha_codec_enable_standalone_ldo_h(codec, enable);
7894
7895 return 0;
7896}
7897
7898static int tasha_mad_input_get(struct snd_kcontrol *kcontrol,
7899 struct snd_ctl_elem_value *ucontrol)
7900{
7901 u8 tasha_mad_input;
7902 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
7903
7904 tasha_mad_input = snd_soc_read(codec,
7905 WCD9335_SOC_MAD_INP_SEL) & 0x0F;
7906 ucontrol->value.integer.value[0] = tasha_mad_input;
7907
7908 dev_dbg(codec->dev,
7909 "%s: tasha_mad_input = %s\n", __func__,
7910 tasha_conn_mad_text[tasha_mad_input]);
7911 return 0;
7912}
7913
7914static int tasha_mad_input_put(struct snd_kcontrol *kcontrol,
7915 struct snd_ctl_elem_value *ucontrol)
7916{
7917 u8 tasha_mad_input;
7918 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
7919 struct snd_soc_card *card = codec->component.card;
7920 char mad_amic_input_widget[6];
7921 const char *mad_input_widget;
7922 const char *source_widget = NULL;
7923 u32 adc, i, mic_bias_found = 0;
7924 int ret = 0;
7925 char *mad_input;
7926
7927 tasha_mad_input = ucontrol->value.integer.value[0];
7928
Karthikeyan Mani63955b42016-12-14 11:46:35 -08007929 if (tasha_mad_input >= ARRAY_SIZE(tasha_conn_mad_text)) {
7930 dev_err(codec->dev,
7931 "%s: tasha_mad_input = %d out of bounds\n",
7932 __func__, tasha_mad_input);
7933 return -EINVAL;
7934 }
7935
Banajit Goswamide8271c2017-01-18 00:28:59 -08007936 if (!strcmp(tasha_conn_mad_text[tasha_mad_input], "NOTUSED1") ||
7937 !strcmp(tasha_conn_mad_text[tasha_mad_input], "NOTUSED2") ||
7938 !strcmp(tasha_conn_mad_text[tasha_mad_input], "NOTUSED3") ||
7939 !strcmp(tasha_conn_mad_text[tasha_mad_input], "NOTUSED4")) {
7940 dev_err(codec->dev,
7941 "%s: Unsupported tasha_mad_input = %s\n",
7942 __func__, tasha_conn_mad_text[tasha_mad_input]);
7943 return -EINVAL;
7944 }
7945
7946 if (strnstr(tasha_conn_mad_text[tasha_mad_input],
7947 "ADC", sizeof("ADC"))) {
7948 mad_input = strpbrk(tasha_conn_mad_text[tasha_mad_input],
7949 "123456");
7950 if (!mad_input) {
7951 dev_err(codec->dev, "%s: Invalid MAD input %s\n",
7952 __func__,
7953 tasha_conn_mad_text[tasha_mad_input]);
7954 return -EINVAL;
7955 }
7956 ret = kstrtouint(mad_input, 10, &adc);
7957 if ((ret < 0) || (adc > 6)) {
7958 dev_err(codec->dev,
7959 "%s: Invalid ADC = %s\n", __func__,
7960 tasha_conn_mad_text[tasha_mad_input]);
7961 ret = -EINVAL;
7962 }
7963
7964 snprintf(mad_amic_input_widget, 6, "%s%u", "AMIC", adc);
7965
7966 mad_input_widget = mad_amic_input_widget;
7967 } else {
7968 /* DMIC type input widget*/
7969 mad_input_widget = tasha_conn_mad_text[tasha_mad_input];
7970 }
7971
7972 dev_dbg(codec->dev,
7973 "%s: tasha input widget = %s\n", __func__,
7974 mad_input_widget);
7975
7976 for (i = 0; i < card->num_of_dapm_routes; i++) {
7977 if (!strcmp(card->of_dapm_routes[i].sink, mad_input_widget)) {
7978 source_widget = card->of_dapm_routes[i].source;
7979 if (!source_widget) {
7980 dev_err(codec->dev,
7981 "%s: invalid source widget\n",
7982 __func__);
7983 return -EINVAL;
7984 }
7985
7986 if (strnstr(source_widget,
7987 "MIC BIAS1", sizeof("MIC BIAS1"))) {
7988 mic_bias_found = 1;
7989 break;
7990 } else if (strnstr(source_widget,
7991 "MIC BIAS2", sizeof("MIC BIAS2"))) {
7992 mic_bias_found = 2;
7993 break;
7994 } else if (strnstr(source_widget,
7995 "MIC BIAS3", sizeof("MIC BIAS3"))) {
7996 mic_bias_found = 3;
7997 break;
7998 } else if (strnstr(source_widget,
7999 "MIC BIAS4", sizeof("MIC BIAS4"))) {
8000 mic_bias_found = 4;
8001 break;
8002 }
8003 }
8004 }
8005
8006 if (!mic_bias_found) {
8007 dev_err(codec->dev,
8008 "%s: mic bias source not found for input = %s\n",
8009 __func__, mad_input_widget);
8010 return -EINVAL;
8011 }
8012
8013 dev_dbg(codec->dev,
8014 "%s: mic_bias found = %d\n", __func__,
8015 mic_bias_found);
8016
8017 snd_soc_update_bits(codec, WCD9335_SOC_MAD_INP_SEL,
8018 0x0F, tasha_mad_input);
8019 snd_soc_update_bits(codec, WCD9335_ANA_MAD_SETUP,
8020 0x07, mic_bias_found);
8021
8022 return 0;
8023}
8024
8025static int tasha_pinctl_mode_get(struct snd_kcontrol *kcontrol,
8026 struct snd_ctl_elem_value *ucontrol)
8027{
8028 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
8029 u16 ctl_reg;
8030 u8 reg_val, pinctl_position;
8031
8032 pinctl_position = ((struct soc_multi_mixer_control *)
8033 kcontrol->private_value)->shift;
8034 switch (pinctl_position >> 3) {
8035 case 0:
8036 ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_0;
8037 break;
8038 case 1:
8039 ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_1;
8040 break;
8041 case 2:
8042 ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_2;
8043 break;
8044 case 3:
8045 ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_3;
8046 break;
8047 default:
8048 dev_err(codec->dev, "%s: Invalid pinctl position = %d\n",
8049 __func__, pinctl_position);
8050 return -EINVAL;
8051 }
8052
8053 reg_val = snd_soc_read(codec, ctl_reg);
8054 reg_val = (reg_val >> (pinctl_position & 0x07)) & 0x1;
8055 ucontrol->value.integer.value[0] = reg_val;
8056
8057 return 0;
8058}
8059
8060static int tasha_pinctl_mode_put(struct snd_kcontrol *kcontrol,
8061 struct snd_ctl_elem_value *ucontrol)
8062{
8063 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
8064 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
8065 u16 ctl_reg, cfg_reg;
8066 u8 ctl_val, cfg_val, pinctl_position, pinctl_mode, mask;
8067
8068 /* 1- high or low; 0- high Z */
8069 pinctl_mode = ucontrol->value.integer.value[0];
8070 pinctl_position = ((struct soc_multi_mixer_control *)
8071 kcontrol->private_value)->shift;
8072
8073 switch (pinctl_position >> 3) {
8074 case 0:
8075 ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_0;
8076 break;
8077 case 1:
8078 ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_1;
8079 break;
8080 case 2:
8081 ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_2;
8082 break;
8083 case 3:
8084 ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_3;
8085 break;
8086 default:
8087 dev_err(codec->dev, "%s: Invalid pinctl position = %d\n",
8088 __func__, pinctl_position);
8089 return -EINVAL;
8090 }
8091
8092 ctl_val = pinctl_mode << (pinctl_position & 0x07);
8093 mask = 1 << (pinctl_position & 0x07);
8094 snd_soc_update_bits(codec, ctl_reg, mask, ctl_val);
8095
8096 cfg_reg = WCD9335_TLMM_BIST_MODE_PINCFG + pinctl_position;
8097 if (!pinctl_mode) {
8098 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS)
8099 cfg_val = 0x4;
8100 else
8101 cfg_val = 0xC;
8102 } else {
8103 cfg_val = 0;
8104 }
8105 snd_soc_update_bits(codec, cfg_reg, 0x07, cfg_val);
8106
8107 dev_dbg(codec->dev, "%s: reg=0x%x mask=0x%x val=%d reg=0x%x val=%d\n",
8108 __func__, ctl_reg, mask, ctl_val, cfg_reg, cfg_val);
8109
8110 return 0;
8111}
8112
8113static void wcd_vbat_adc_out_config_2_0(struct wcd_vbat *vbat,
8114 struct snd_soc_codec *codec)
8115{
8116 u8 val1, val2;
8117
8118 /*
8119 * Measure dcp1 by using "ALT" branch of band gap
8120 * voltage(Vbg) and use it in FAST mode
8121 */
8122 snd_soc_update_bits(codec, WCD9335_BIAS_CTL, 0x82, 0x82);
8123 snd_soc_update_bits(codec, WCD9335_CDC_VBAT_VBAT_PATH_CTL, 0x10, 0x10);
8124 snd_soc_update_bits(codec, WCD9335_CDC_VBAT_VBAT_DEBUG1, 0x01, 0x01);
8125 snd_soc_update_bits(codec, WCD9335_ANA_VBADC, 0x80, 0x80);
8126 snd_soc_update_bits(codec, WCD9335_VBADC_SUBBLOCK_EN, 0x20, 0x00);
8127
8128 snd_soc_update_bits(codec, WCD9335_VBADC_FE_CTRL, 0x20, 0x20);
8129 /* Wait 100 usec after calibration select as Vbg */
8130 usleep_range(100, 110);
8131
8132 snd_soc_update_bits(codec, WCD9335_VBADC_ADC_IO, 0x40, 0x40);
8133 val1 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTMSB);
8134 val2 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTLSB);
8135 snd_soc_update_bits(codec, WCD9335_VBADC_ADC_IO, 0x40, 0x00);
8136
8137 vbat->dcp1 = (((val1 & 0xFF) << 3) | (val2 & 0x07));
8138
8139 snd_soc_update_bits(codec, WCD9335_BIAS_CTL, 0x40, 0x40);
8140 /* Wait 100 usec after selecting Vbg as 1.05V */
8141 usleep_range(100, 110);
8142
8143 snd_soc_update_bits(codec, WCD9335_VBADC_ADC_IO, 0x40, 0x40);
8144 val1 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTMSB);
8145 val2 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTLSB);
8146 snd_soc_update_bits(codec, WCD9335_VBADC_ADC_IO, 0x40, 0x00);
8147
8148 vbat->dcp2 = (((val1 & 0xFF) << 3) | (val2 & 0x07));
8149
8150 dev_dbg(codec->dev, "%s: dcp1:0x%x, dcp2:0x%x\n",
8151 __func__, vbat->dcp1, vbat->dcp2);
8152
8153 snd_soc_write(codec, WCD9335_BIAS_CTL, 0x28);
8154 /* Wait 100 usec after selecting Vbg as 0.85V */
8155 usleep_range(100, 110);
8156
8157 snd_soc_update_bits(codec, WCD9335_VBADC_FE_CTRL, 0x20, 0x00);
8158 snd_soc_update_bits(codec, WCD9335_VBADC_SUBBLOCK_EN, 0x20, 0x20);
8159 snd_soc_update_bits(codec, WCD9335_ANA_VBADC, 0x80, 0x00);
8160
8161 snd_soc_update_bits(codec, WCD9335_CDC_VBAT_VBAT_PATH_CTL, 0x10, 0x00);
8162 snd_soc_update_bits(codec, WCD9335_CDC_VBAT_VBAT_DEBUG1, 0x01, 0x00);
8163}
8164
8165static void wcd_vbat_adc_out_config_1_x(struct wcd_vbat *vbat,
8166 struct snd_soc_codec *codec)
8167{
8168 u8 val1, val2;
8169
8170 /*
8171 * Measure dcp1 by applying band gap voltage(Vbg)
8172 * of 0.85V
8173 */
8174 snd_soc_write(codec, WCD9335_ANA_BIAS, 0x20);
8175 snd_soc_write(codec, WCD9335_BIAS_CTL, 0x28);
8176 snd_soc_write(codec, WCD9335_BIAS_VBG_FINE_ADJ, 0x05);
8177 snd_soc_write(codec, WCD9335_ANA_BIAS, 0xA0);
8178 /* Wait 2 sec after enabling band gap bias */
8179 usleep_range(2000000, 2000100);
8180
8181 snd_soc_write(codec, WCD9335_ANA_CLK_TOP, 0x82);
8182 snd_soc_write(codec, WCD9335_ANA_CLK_TOP, 0x87);
8183 snd_soc_update_bits(codec, WCD9335_CDC_VBAT_VBAT_PATH_CTL, 0x10, 0x10);
8184 snd_soc_write(codec, WCD9335_CDC_VBAT_VBAT_CFG, 0x0D);
8185 snd_soc_write(codec, WCD9335_CDC_VBAT_VBAT_DEBUG1, 0x01);
8186
8187 snd_soc_write(codec, WCD9335_ANA_VBADC, 0x80);
8188 snd_soc_write(codec, WCD9335_VBADC_SUBBLOCK_EN, 0xDE);
8189 snd_soc_write(codec, WCD9335_VBADC_FE_CTRL, 0x3C);
8190 /* Wait 1 msec after calibration select as Vbg */
8191 usleep_range(1000, 1100);
8192
8193 snd_soc_write(codec, WCD9335_VBADC_ADC_IO, 0xC0);
8194 val1 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTMSB);
8195 val2 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTLSB);
8196 snd_soc_write(codec, WCD9335_VBADC_ADC_IO, 0x80);
8197
8198 vbat->dcp1 = (((val1 & 0xFF) << 3) | (val2 & 0x07));
8199
8200 /*
8201 * Measure dcp2 by applying band gap voltage(Vbg)
8202 * of 1.05V
8203 */
8204 snd_soc_write(codec, WCD9335_ANA_BIAS, 0x80);
8205 snd_soc_write(codec, WCD9335_ANA_BIAS, 0xC0);
8206 snd_soc_write(codec, WCD9335_BIAS_CTL, 0x68);
8207 /* Wait 2 msec after selecting Vbg as 1.05V */
8208 usleep_range(2000, 2100);
8209
8210 snd_soc_write(codec, WCD9335_ANA_BIAS, 0x80);
8211 /* Wait 1 sec after enabling band gap bias */
8212 usleep_range(1000000, 1000100);
8213
8214 snd_soc_write(codec, WCD9335_VBADC_ADC_IO, 0xC0);
8215 val1 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTMSB);
8216 val2 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTLSB);
8217 snd_soc_write(codec, WCD9335_VBADC_ADC_IO, 0x80);
8218
8219 vbat->dcp2 = (((val1 & 0xFF) << 3) | (val2 & 0x07));
8220
8221 dev_dbg(codec->dev, "%s: dcp1:0x%x, dcp2:0x%x\n",
8222 __func__, vbat->dcp1, vbat->dcp2);
8223
8224 /* Reset the Vbat ADC configuration */
8225 snd_soc_write(codec, WCD9335_ANA_BIAS, 0x80);
8226 snd_soc_write(codec, WCD9335_ANA_BIAS, 0xC0);
8227
8228 snd_soc_write(codec, WCD9335_BIAS_CTL, 0x28);
8229 /* Wait 2 msec after selecting Vbg as 0.85V */
8230 usleep_range(2000, 2100);
8231
8232 snd_soc_write(codec, WCD9335_ANA_BIAS, 0xA0);
8233 /* Wait 1 sec after enabling band gap bias */
8234 usleep_range(1000000, 1000100);
8235
8236 snd_soc_write(codec, WCD9335_VBADC_FE_CTRL, 0x1C);
8237 snd_soc_write(codec, WCD9335_VBADC_SUBBLOCK_EN, 0xFE);
8238 snd_soc_write(codec, WCD9335_VBADC_ADC_IO, 0x80);
8239 snd_soc_write(codec, WCD9335_ANA_VBADC, 0x00);
8240
8241 snd_soc_write(codec, WCD9335_CDC_VBAT_VBAT_DEBUG1, 0x00);
8242 snd_soc_write(codec, WCD9335_CDC_VBAT_VBAT_PATH_CTL, 0x00);
8243 snd_soc_write(codec, WCD9335_CDC_VBAT_VBAT_CFG, 0x0A);
8244}
8245
8246static void wcd_vbat_adc_out_config(struct wcd_vbat *vbat,
8247 struct snd_soc_codec *codec)
8248{
8249 struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent);
8250
8251 if (!vbat->adc_config) {
8252 tasha_cdc_mclk_enable(codec, true, false);
8253
8254 if (TASHA_IS_2_0(wcd9xxx))
8255 wcd_vbat_adc_out_config_2_0(vbat, codec);
8256 else
8257 wcd_vbat_adc_out_config_1_x(vbat, codec);
8258
8259 tasha_cdc_mclk_enable(codec, false, false);
8260 vbat->adc_config = true;
8261 }
8262}
8263
8264static int tasha_update_vbat_reg_config(struct snd_soc_codec *codec)
8265{
8266 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
8267 struct firmware_cal *hwdep_cal = NULL;
8268 struct vbat_monitor_reg *vbat_reg_ptr = NULL;
8269 const void *data;
8270 size_t cal_size, vbat_size_remaining;
8271 int ret = 0, i;
8272 u32 vbat_writes_size = 0;
8273 u16 reg;
8274 u8 mask, val, old_val;
8275
8276 hwdep_cal = wcdcal_get_fw_cal(tasha->fw_data, WCD9XXX_VBAT_CAL);
8277 if (hwdep_cal) {
8278 data = hwdep_cal->data;
8279 cal_size = hwdep_cal->size;
8280 dev_dbg(codec->dev, "%s: using hwdep calibration\n",
8281 __func__);
8282 } else {
8283 dev_err(codec->dev, "%s: Vbat cal not received\n",
8284 __func__);
8285 ret = -EINVAL;
8286 goto done;
8287 }
8288
8289 if (cal_size < sizeof(*vbat_reg_ptr)) {
8290 dev_err(codec->dev,
8291 "%s: Incorrect size %zd for Vbat Cal, expected %zd\n",
8292 __func__, cal_size, sizeof(*vbat_reg_ptr));
8293 ret = -EINVAL;
8294 goto done;
8295 }
8296
8297 vbat_reg_ptr = (struct vbat_monitor_reg *) (data);
8298
8299 if (!vbat_reg_ptr) {
8300 dev_err(codec->dev,
8301 "%s: Invalid calibration data for Vbat\n",
8302 __func__);
8303 ret = -EINVAL;
8304 goto done;
8305 }
8306
8307 vbat_writes_size = vbat_reg_ptr->size;
8308 vbat_size_remaining = cal_size - sizeof(u32);
8309 dev_dbg(codec->dev, "%s: vbat_writes_sz: %d, vbat_sz_remaining: %zd\n",
8310 __func__, vbat_writes_size, vbat_size_remaining);
8311
8312 if ((vbat_writes_size * TASHA_PACKED_REG_SIZE)
8313 > vbat_size_remaining) {
8314 pr_err("%s: Incorrect Vbat calibration data\n", __func__);
8315 ret = -EINVAL;
8316 goto done;
8317 }
8318
8319 for (i = 0 ; i < vbat_writes_size; i++) {
8320 TASHA_CODEC_UNPACK_ENTRY(vbat_reg_ptr->writes[i],
8321 reg, mask, val);
8322 old_val = snd_soc_read(codec, reg);
8323 snd_soc_write(codec, reg, (old_val & ~mask) | (val & mask));
8324 }
8325
8326done:
8327 return ret;
8328}
8329
8330static int tasha_vbat_adc_data_get(struct snd_kcontrol *kcontrol,
8331 struct snd_ctl_elem_value *ucontrol)
8332{
8333 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
8334 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
8335
8336 wcd_vbat_adc_out_config(&tasha->vbat, codec);
8337
8338 ucontrol->value.integer.value[0] = tasha->vbat.dcp1;
8339 ucontrol->value.integer.value[1] = tasha->vbat.dcp2;
8340
8341 dev_dbg(codec->dev,
8342 "%s: Vbat ADC output values, Dcp1 : %lu, Dcp2: %lu\n",
8343 __func__, ucontrol->value.integer.value[0],
8344 ucontrol->value.integer.value[1]);
8345
8346 return 0;
8347}
8348
8349static const char * const tasha_vbat_gsm_mode_text[] = {
8350 "OFF", "ON"};
8351
8352static const struct soc_enum tasha_vbat_gsm_mode_enum =
8353 SOC_ENUM_SINGLE_EXT(2, tasha_vbat_gsm_mode_text);
8354
8355static int tasha_vbat_gsm_mode_func_get(struct snd_kcontrol *kcontrol,
8356 struct snd_ctl_elem_value *ucontrol)
8357{
8358 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
8359
8360 ucontrol->value.integer.value[0] =
8361 ((snd_soc_read(codec, WCD9335_CDC_VBAT_VBAT_CFG) & 0x04) ?
8362 1 : 0);
8363
8364 dev_dbg(codec->dev, "%s: value: %lu\n", __func__,
8365 ucontrol->value.integer.value[0]);
8366
8367 return 0;
8368}
8369
8370static int tasha_vbat_gsm_mode_func_put(struct snd_kcontrol *kcontrol,
8371 struct snd_ctl_elem_value *ucontrol)
8372{
8373 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
8374
8375 dev_dbg(codec->dev, "%s: value: %lu\n", __func__,
8376 ucontrol->value.integer.value[0]);
8377
8378 /* Set Vbat register configuration for GSM mode bit based on value */
8379 if (ucontrol->value.integer.value[0])
8380 snd_soc_update_bits(codec, WCD9335_CDC_VBAT_VBAT_CFG,
8381 0x04, 0x04);
8382 else
8383 snd_soc_update_bits(codec, WCD9335_CDC_VBAT_VBAT_CFG,
8384 0x04, 0x00);
8385
8386 return 0;
8387}
8388
8389static int tasha_codec_vbat_enable_event(struct snd_soc_dapm_widget *w,
8390 struct snd_kcontrol *kcontrol,
8391 int event)
8392{
8393 int ret = 0;
8394 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
8395 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
8396 u16 vbat_path_ctl, vbat_cfg, vbat_path_cfg;
8397
8398 vbat_path_ctl = WCD9335_CDC_VBAT_VBAT_PATH_CTL;
8399 vbat_cfg = WCD9335_CDC_VBAT_VBAT_CFG;
8400 vbat_path_cfg = WCD9335_CDC_RX8_RX_PATH_CFG1;
8401
8402 if (!strcmp(w->name, "RX INT8 VBAT"))
8403 vbat_path_cfg = WCD9335_CDC_RX8_RX_PATH_CFG1;
8404 else if (!strcmp(w->name, "RX INT7 VBAT"))
8405 vbat_path_cfg = WCD9335_CDC_RX7_RX_PATH_CFG1;
8406 else if (!strcmp(w->name, "RX INT6 VBAT"))
8407 vbat_path_cfg = WCD9335_CDC_RX6_RX_PATH_CFG1;
8408 else if (!strcmp(w->name, "RX INT5 VBAT"))
8409 vbat_path_cfg = WCD9335_CDC_RX5_RX_PATH_CFG1;
8410
8411 switch (event) {
8412 case SND_SOC_DAPM_PRE_PMU:
8413 ret = tasha_update_vbat_reg_config(codec);
8414 if (ret) {
8415 dev_dbg(codec->dev,
8416 "%s : VBAT isn't calibrated, So not enabling it\n",
8417 __func__);
8418 return 0;
8419 }
8420 snd_soc_write(codec, WCD9335_ANA_VBADC, 0x80);
8421 snd_soc_update_bits(codec, vbat_path_cfg, 0x02, 0x02);
8422 snd_soc_update_bits(codec, vbat_path_ctl, 0x10, 0x10);
8423 snd_soc_update_bits(codec, vbat_cfg, 0x01, 0x01);
8424 tasha->vbat.is_enabled = true;
8425 break;
8426 case SND_SOC_DAPM_POST_PMD:
8427 if (tasha->vbat.is_enabled) {
8428 snd_soc_update_bits(codec, vbat_cfg, 0x01, 0x00);
8429 snd_soc_update_bits(codec, vbat_path_ctl, 0x10, 0x00);
8430 snd_soc_update_bits(codec, vbat_path_cfg, 0x02, 0x00);
8431 snd_soc_write(codec, WCD9335_ANA_VBADC, 0x00);
8432 tasha->vbat.is_enabled = false;
8433 }
8434 break;
8435 };
8436
8437 return ret;
8438}
8439
8440static const char * const rx_hph_mode_mux_text[] = {
8441 "CLS_H_INVALID", "CLS_H_HIFI", "CLS_H_LP", "CLS_AB", "CLS_H_LOHIFI"
8442};
8443
8444static const struct soc_enum rx_hph_mode_mux_enum =
8445 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_hph_mode_mux_text),
8446 rx_hph_mode_mux_text);
8447
8448static const char * const amic_pwr_lvl_text[] = {
8449 "LOW_PWR", "DEFAULT", "HIGH_PERF"
8450};
8451
8452static const struct soc_enum amic_pwr_lvl_enum =
8453 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(amic_pwr_lvl_text),
8454 amic_pwr_lvl_text);
8455
8456static const struct snd_kcontrol_new tasha_snd_controls[] = {
8457 SOC_SINGLE_SX_TLV("RX0 Digital Volume", WCD9335_CDC_RX0_RX_VOL_CTL,
8458 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8459 SOC_SINGLE_SX_TLV("RX1 Digital Volume", WCD9335_CDC_RX1_RX_VOL_CTL,
8460 0, -84, 40, digital_gain),
8461 SOC_SINGLE_SX_TLV("RX2 Digital Volume", WCD9335_CDC_RX2_RX_VOL_CTL,
8462 0, -84, 40, digital_gain),
8463 SOC_SINGLE_SX_TLV("RX3 Digital Volume", WCD9335_CDC_RX3_RX_VOL_CTL,
8464 0, -84, 40, digital_gain),
8465 SOC_SINGLE_SX_TLV("RX4 Digital Volume", WCD9335_CDC_RX4_RX_VOL_CTL,
8466 0, -84, 40, digital_gain),
8467 SOC_SINGLE_SX_TLV("RX5 Digital Volume", WCD9335_CDC_RX5_RX_VOL_CTL,
8468 0, -84, 40, digital_gain),
8469 SOC_SINGLE_SX_TLV("RX6 Digital Volume", WCD9335_CDC_RX6_RX_VOL_CTL,
8470 0, -84, 40, digital_gain),
8471 SOC_SINGLE_SX_TLV("RX7 Digital Volume", WCD9335_CDC_RX7_RX_VOL_CTL,
8472 0, -84, 40, digital_gain),
8473 SOC_SINGLE_SX_TLV("RX8 Digital Volume", WCD9335_CDC_RX8_RX_VOL_CTL,
8474 0, -84, 40, digital_gain),
8475
8476 SOC_SINGLE_SX_TLV("RX0 Mix Digital Volume",
8477 WCD9335_CDC_RX0_RX_VOL_MIX_CTL,
8478 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8479 SOC_SINGLE_SX_TLV("RX1 Mix Digital Volume",
8480 WCD9335_CDC_RX1_RX_VOL_MIX_CTL,
8481 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8482 SOC_SINGLE_SX_TLV("RX2 Mix Digital Volume",
8483 WCD9335_CDC_RX2_RX_VOL_MIX_CTL,
8484 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8485 SOC_SINGLE_SX_TLV("RX3 Mix Digital Volume",
8486 WCD9335_CDC_RX3_RX_VOL_MIX_CTL,
8487 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8488 SOC_SINGLE_SX_TLV("RX4 Mix Digital Volume",
8489 WCD9335_CDC_RX4_RX_VOL_MIX_CTL,
8490 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8491 SOC_SINGLE_SX_TLV("RX5 Mix Digital Volume",
8492 WCD9335_CDC_RX5_RX_VOL_MIX_CTL,
8493 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8494 SOC_SINGLE_SX_TLV("RX6 Mix Digital Volume",
8495 WCD9335_CDC_RX6_RX_VOL_MIX_CTL,
8496 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8497 SOC_SINGLE_SX_TLV("RX7 Mix Digital Volume",
8498 WCD9335_CDC_RX7_RX_VOL_MIX_CTL,
8499 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8500 SOC_SINGLE_SX_TLV("RX8 Mix Digital Volume",
8501 WCD9335_CDC_RX8_RX_VOL_MIX_CTL,
8502 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8503
8504 SOC_SINGLE_SX_TLV("DEC0 Volume", WCD9335_CDC_TX0_TX_VOL_CTL, 0,
8505 -84, 40, digital_gain),
8506 SOC_SINGLE_SX_TLV("DEC1 Volume", WCD9335_CDC_TX1_TX_VOL_CTL, 0,
8507 -84, 40, digital_gain),
8508 SOC_SINGLE_SX_TLV("DEC2 Volume", WCD9335_CDC_TX2_TX_VOL_CTL, 0,
8509 -84, 40, digital_gain),
8510 SOC_SINGLE_SX_TLV("DEC3 Volume", WCD9335_CDC_TX3_TX_VOL_CTL, 0,
8511 -84, 40, digital_gain),
8512 SOC_SINGLE_SX_TLV("DEC4 Volume", WCD9335_CDC_TX4_TX_VOL_CTL, 0,
8513 -84, 40, digital_gain),
8514 SOC_SINGLE_SX_TLV("DEC5 Volume", WCD9335_CDC_TX5_TX_VOL_CTL, 0,
8515 -84, 40, digital_gain),
8516 SOC_SINGLE_SX_TLV("DEC6 Volume", WCD9335_CDC_TX6_TX_VOL_CTL, 0,
8517 -84, 40, digital_gain),
8518 SOC_SINGLE_SX_TLV("DEC7 Volume", WCD9335_CDC_TX7_TX_VOL_CTL, 0,
8519 -84, 40, digital_gain),
8520 SOC_SINGLE_SX_TLV("DEC8 Volume", WCD9335_CDC_TX8_TX_VOL_CTL, 0,
8521 -84, 40, digital_gain),
8522
8523 SOC_SINGLE_SX_TLV("IIR0 INP0 Volume",
8524 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL, 0, -84,
8525 40, digital_gain),
8526 SOC_SINGLE_SX_TLV("IIR0 INP1 Volume",
8527 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL, 0, -84,
8528 40, digital_gain),
8529 SOC_SINGLE_SX_TLV("IIR0 INP2 Volume",
8530 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL, 0, -84,
8531 40, digital_gain),
8532 SOC_SINGLE_SX_TLV("IIR0 INP3 Volume",
8533 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL, 0, -84,
8534 40, digital_gain),
8535 SOC_SINGLE_SX_TLV("IIR1 INP0 Volume",
8536 WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B1_CTL, 0, -84,
8537 40, digital_gain),
8538 SOC_SINGLE_SX_TLV("IIR1 INP1 Volume",
8539 WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B2_CTL, 0, -84,
8540 40, digital_gain),
8541 SOC_SINGLE_SX_TLV("IIR1 INP2 Volume",
8542 WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B3_CTL, 0, -84,
8543 40, digital_gain),
8544 SOC_SINGLE_SX_TLV("IIR1 INP3 Volume",
8545 WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B4_CTL, 0, -84,
8546 40, digital_gain),
8547
8548 SOC_SINGLE_EXT("ANC Slot", SND_SOC_NOPM, 0, 100, 0, tasha_get_anc_slot,
8549 tasha_put_anc_slot),
8550 SOC_ENUM_EXT("ANC Function", tasha_anc_func_enum, tasha_get_anc_func,
8551 tasha_put_anc_func),
8552
8553 SOC_ENUM_EXT("CLK MODE", tasha_clkmode_enum, tasha_get_clkmode,
8554 tasha_put_clkmode),
8555
8556 SOC_ENUM("TX0 HPF cut off", cf_dec0_enum),
8557 SOC_ENUM("TX1 HPF cut off", cf_dec1_enum),
8558 SOC_ENUM("TX2 HPF cut off", cf_dec2_enum),
8559 SOC_ENUM("TX3 HPF cut off", cf_dec3_enum),
8560 SOC_ENUM("TX4 HPF cut off", cf_dec4_enum),
8561 SOC_ENUM("TX5 HPF cut off", cf_dec5_enum),
8562 SOC_ENUM("TX6 HPF cut off", cf_dec6_enum),
8563 SOC_ENUM("TX7 HPF cut off", cf_dec7_enum),
8564 SOC_ENUM("TX8 HPF cut off", cf_dec8_enum),
8565
8566 SOC_ENUM("RX INT0_1 HPF cut off", cf_int0_1_enum),
8567 SOC_ENUM("RX INT0_2 HPF cut off", cf_int0_2_enum),
8568 SOC_ENUM("RX INT1_1 HPF cut off", cf_int1_1_enum),
8569 SOC_ENUM("RX INT1_2 HPF cut off", cf_int1_2_enum),
8570 SOC_ENUM("RX INT2_1 HPF cut off", cf_int2_1_enum),
8571 SOC_ENUM("RX INT2_2 HPF cut off", cf_int2_2_enum),
8572 SOC_ENUM("RX INT3_1 HPF cut off", cf_int3_1_enum),
8573 SOC_ENUM("RX INT3_2 HPF cut off", cf_int3_2_enum),
8574 SOC_ENUM("RX INT4_1 HPF cut off", cf_int4_1_enum),
8575 SOC_ENUM("RX INT4_2 HPF cut off", cf_int4_2_enum),
8576 SOC_ENUM("RX INT5_1 HPF cut off", cf_int5_1_enum),
8577 SOC_ENUM("RX INT5_2 HPF cut off", cf_int5_2_enum),
8578 SOC_ENUM("RX INT6_1 HPF cut off", cf_int6_1_enum),
8579 SOC_ENUM("RX INT6_2 HPF cut off", cf_int6_2_enum),
8580 SOC_ENUM("RX INT7_1 HPF cut off", cf_int7_1_enum),
8581 SOC_ENUM("RX INT7_2 HPF cut off", cf_int7_2_enum),
8582 SOC_ENUM("RX INT8_1 HPF cut off", cf_int8_1_enum),
8583 SOC_ENUM("RX INT8_2 HPF cut off", cf_int8_2_enum),
8584
8585 SOC_SINGLE_EXT("IIR0 Enable Band1", IIR0, BAND1, 1, 0,
8586 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8587 SOC_SINGLE_EXT("IIR0 Enable Band2", IIR0, BAND2, 1, 0,
8588 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8589 SOC_SINGLE_EXT("IIR0 Enable Band3", IIR0, BAND3, 1, 0,
8590 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8591 SOC_SINGLE_EXT("IIR0 Enable Band4", IIR0, BAND4, 1, 0,
8592 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8593 SOC_SINGLE_EXT("IIR0 Enable Band5", IIR0, BAND5, 1, 0,
8594 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8595 SOC_SINGLE_EXT("IIR1 Enable Band1", IIR1, BAND1, 1, 0,
8596 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8597 SOC_SINGLE_EXT("IIR1 Enable Band2", IIR1, BAND2, 1, 0,
8598 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8599 SOC_SINGLE_EXT("IIR1 Enable Band3", IIR1, BAND3, 1, 0,
8600 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8601 SOC_SINGLE_EXT("IIR1 Enable Band4", IIR1, BAND4, 1, 0,
8602 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8603 SOC_SINGLE_EXT("IIR1 Enable Band5", IIR1, BAND5, 1, 0,
8604 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8605
8606 SOC_SINGLE_MULTI_EXT("IIR0 Band1", IIR0, BAND1, 255, 0, 5,
8607 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8608 SOC_SINGLE_MULTI_EXT("IIR0 Band2", IIR0, BAND2, 255, 0, 5,
8609 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8610 SOC_SINGLE_MULTI_EXT("IIR0 Band3", IIR0, BAND3, 255, 0, 5,
8611 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8612 SOC_SINGLE_MULTI_EXT("IIR0 Band4", IIR0, BAND4, 255, 0, 5,
8613 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8614 SOC_SINGLE_MULTI_EXT("IIR0 Band5", IIR0, BAND5, 255, 0, 5,
8615 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8616 SOC_SINGLE_MULTI_EXT("IIR1 Band1", IIR1, BAND1, 255, 0, 5,
8617 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8618 SOC_SINGLE_MULTI_EXT("IIR1 Band2", IIR1, BAND2, 255, 0, 5,
8619 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8620 SOC_SINGLE_MULTI_EXT("IIR1 Band3", IIR1, BAND3, 255, 0, 5,
8621 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8622 SOC_SINGLE_MULTI_EXT("IIR1 Band4", IIR1, BAND4, 255, 0, 5,
8623 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8624 SOC_SINGLE_MULTI_EXT("IIR1 Band5", IIR1, BAND5, 255, 0, 5,
8625 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8626
8627 SOC_SINGLE_EXT("COMP1 Switch", SND_SOC_NOPM, COMPANDER_1, 1, 0,
8628 tasha_get_compander, tasha_set_compander),
8629 SOC_SINGLE_EXT("COMP2 Switch", SND_SOC_NOPM, COMPANDER_2, 1, 0,
8630 tasha_get_compander, tasha_set_compander),
8631 SOC_SINGLE_EXT("COMP3 Switch", SND_SOC_NOPM, COMPANDER_3, 1, 0,
8632 tasha_get_compander, tasha_set_compander),
8633 SOC_SINGLE_EXT("COMP4 Switch", SND_SOC_NOPM, COMPANDER_4, 1, 0,
8634 tasha_get_compander, tasha_set_compander),
8635 SOC_SINGLE_EXT("COMP5 Switch", SND_SOC_NOPM, COMPANDER_5, 1, 0,
8636 tasha_get_compander, tasha_set_compander),
8637 SOC_SINGLE_EXT("COMP6 Switch", SND_SOC_NOPM, COMPANDER_6, 1, 0,
8638 tasha_get_compander, tasha_set_compander),
8639 SOC_SINGLE_EXT("COMP7 Switch", SND_SOC_NOPM, COMPANDER_7, 1, 0,
8640 tasha_get_compander, tasha_set_compander),
8641 SOC_SINGLE_EXT("COMP8 Switch", SND_SOC_NOPM, COMPANDER_8, 1, 0,
8642 tasha_get_compander, tasha_set_compander),
8643
8644 SOC_ENUM_EXT("RX HPH Mode", rx_hph_mode_mux_enum,
8645 tasha_rx_hph_mode_get, tasha_rx_hph_mode_put),
8646
8647 SOC_ENUM_EXT("MAD Input", tasha_conn_mad_enum,
8648 tasha_mad_input_get, tasha_mad_input_put),
8649 SOC_SINGLE_EXT("LDO_H Enable", SND_SOC_NOPM, 0, 1, 0,
8650 tasha_enable_ldo_h_get, tasha_enable_ldo_h_put),
8651
8652 SOC_SINGLE_EXT("DMIC1_CLK_PIN_MODE", SND_SOC_NOPM, 17, 1, 0,
8653 tasha_pinctl_mode_get, tasha_pinctl_mode_put),
8654
8655 SOC_SINGLE_EXT("DMIC1_DATA_PIN_MODE", SND_SOC_NOPM, 18, 1, 0,
8656 tasha_pinctl_mode_get, tasha_pinctl_mode_put),
8657
8658 SOC_SINGLE_EXT("DMIC2_CLK_PIN_MODE", SND_SOC_NOPM, 19, 1, 0,
8659 tasha_pinctl_mode_get, tasha_pinctl_mode_put),
8660
8661 SOC_SINGLE_EXT("DMIC2_DATA_PIN_MODE", SND_SOC_NOPM, 20, 1, 0,
8662 tasha_pinctl_mode_get, tasha_pinctl_mode_put),
8663
8664 SOC_SINGLE_EXT("DMIC3_CLK_PIN_MODE", SND_SOC_NOPM, 21, 1, 0,
8665 tasha_pinctl_mode_get, tasha_pinctl_mode_put),
8666
8667 SOC_SINGLE_EXT("DMIC3_DATA_PIN_MODE", SND_SOC_NOPM, 22, 1, 0,
8668 tasha_pinctl_mode_get, tasha_pinctl_mode_put),
8669 SOC_ENUM_EXT("AMIC_1_2 PWR MODE", amic_pwr_lvl_enum,
8670 tasha_amic_pwr_lvl_get, tasha_amic_pwr_lvl_put),
8671 SOC_ENUM_EXT("AMIC_3_4 PWR MODE", amic_pwr_lvl_enum,
8672 tasha_amic_pwr_lvl_get, tasha_amic_pwr_lvl_put),
8673 SOC_ENUM_EXT("AMIC_5_6 PWR MODE", amic_pwr_lvl_enum,
8674 tasha_amic_pwr_lvl_get, tasha_amic_pwr_lvl_put),
8675
8676 SOC_SINGLE_MULTI_EXT("Vbat ADC data", SND_SOC_NOPM, 0, 0xFFFF, 0, 2,
8677 tasha_vbat_adc_data_get, NULL),
8678
8679 SOC_ENUM_EXT("GSM mode Enable", tasha_vbat_gsm_mode_enum,
8680 tasha_vbat_gsm_mode_func_get,
8681 tasha_vbat_gsm_mode_func_put),
8682};
8683
8684static int tasha_put_dec_enum(struct snd_kcontrol *kcontrol,
8685 struct snd_ctl_elem_value *ucontrol)
8686{
8687 struct snd_soc_dapm_widget_list *wlist =
8688 dapm_kcontrol_get_wlist(kcontrol);
8689 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
8690 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
8691 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
8692 unsigned int val;
8693 u16 mic_sel_reg;
8694 u8 mic_sel;
8695
8696 val = ucontrol->value.enumerated.item[0];
8697 if (val > e->items - 1)
8698 return -EINVAL;
8699
8700 dev_dbg(codec->dev, "%s: wname: %s, val: 0x%x\n", __func__,
8701 widget->name, val);
8702
8703 switch (e->reg) {
8704 case WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG1:
8705 mic_sel_reg = WCD9335_CDC_TX0_TX_PATH_CFG0;
8706 break;
8707 case WCD9335_CDC_TX_INP_MUX_ADC_MUX1_CFG1:
8708 mic_sel_reg = WCD9335_CDC_TX1_TX_PATH_CFG0;
8709 break;
8710 case WCD9335_CDC_TX_INP_MUX_ADC_MUX2_CFG1:
8711 mic_sel_reg = WCD9335_CDC_TX2_TX_PATH_CFG0;
8712 break;
8713 case WCD9335_CDC_TX_INP_MUX_ADC_MUX3_CFG1:
8714 mic_sel_reg = WCD9335_CDC_TX3_TX_PATH_CFG0;
8715 break;
8716 case WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0:
8717 mic_sel_reg = WCD9335_CDC_TX4_TX_PATH_CFG0;
8718 break;
8719 case WCD9335_CDC_TX_INP_MUX_ADC_MUX5_CFG0:
8720 mic_sel_reg = WCD9335_CDC_TX5_TX_PATH_CFG0;
8721 break;
8722 case WCD9335_CDC_TX_INP_MUX_ADC_MUX6_CFG0:
8723 mic_sel_reg = WCD9335_CDC_TX6_TX_PATH_CFG0;
8724 break;
8725 case WCD9335_CDC_TX_INP_MUX_ADC_MUX7_CFG0:
8726 mic_sel_reg = WCD9335_CDC_TX7_TX_PATH_CFG0;
8727 break;
8728 case WCD9335_CDC_TX_INP_MUX_ADC_MUX8_CFG0:
8729 mic_sel_reg = WCD9335_CDC_TX8_TX_PATH_CFG0;
8730 break;
8731 default:
8732 dev_err(codec->dev, "%s: e->reg: 0x%x not expected\n",
8733 __func__, e->reg);
8734 return -EINVAL;
8735 }
8736
8737 /* ADC: 0, DMIC: 1 */
8738 mic_sel = val ? 0x0 : 0x1;
8739 snd_soc_update_bits(codec, mic_sel_reg, 1 << 7, mic_sel << 7);
8740
8741 return snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
8742}
8743
8744static int tasha_int_dem_inp_mux_put(struct snd_kcontrol *kcontrol,
8745 struct snd_ctl_elem_value *ucontrol)
8746{
8747 struct snd_soc_dapm_widget_list *wlist =
8748 dapm_kcontrol_get_wlist(kcontrol);
8749 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
8750 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
8751 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
8752 unsigned int val;
8753 unsigned short look_ahead_dly_reg = WCD9335_CDC_RX0_RX_PATH_CFG0;
8754
8755 val = ucontrol->value.enumerated.item[0];
8756 if (val >= e->items)
8757 return -EINVAL;
8758
8759 dev_dbg(codec->dev, "%s: wname: %s, val: 0x%x\n", __func__,
8760 widget->name, val);
8761
8762 if (e->reg == WCD9335_CDC_RX0_RX_PATH_SEC0)
8763 look_ahead_dly_reg = WCD9335_CDC_RX0_RX_PATH_CFG0;
8764 else if (e->reg == WCD9335_CDC_RX1_RX_PATH_SEC0)
8765 look_ahead_dly_reg = WCD9335_CDC_RX1_RX_PATH_CFG0;
8766 else if (e->reg == WCD9335_CDC_RX2_RX_PATH_SEC0)
8767 look_ahead_dly_reg = WCD9335_CDC_RX2_RX_PATH_CFG0;
8768
8769 /* Set Look Ahead Delay */
8770 snd_soc_update_bits(codec, look_ahead_dly_reg,
8771 0x08, (val ? 0x08 : 0x00));
8772 /* Set DEM INP Select */
8773 return snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
8774}
8775
8776static int tasha_ear_pa_gain_get(struct snd_kcontrol *kcontrol,
8777 struct snd_ctl_elem_value *ucontrol)
8778{
8779 u8 ear_pa_gain;
8780 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
8781
8782 ear_pa_gain = snd_soc_read(codec, WCD9335_ANA_EAR);
8783
8784 ear_pa_gain = (ear_pa_gain & 0x70) >> 4;
8785
8786 ucontrol->value.integer.value[0] = ear_pa_gain;
8787
8788 dev_dbg(codec->dev, "%s: ear_pa_gain = 0x%x\n", __func__,
8789 ear_pa_gain);
8790
8791 return 0;
8792}
8793
8794static int tasha_ear_pa_gain_put(struct snd_kcontrol *kcontrol,
8795 struct snd_ctl_elem_value *ucontrol)
8796{
8797 u8 ear_pa_gain;
8798 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
8799
8800 dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
8801 __func__, ucontrol->value.integer.value[0]);
8802
8803 ear_pa_gain = ucontrol->value.integer.value[0] << 4;
8804
8805 snd_soc_update_bits(codec, WCD9335_ANA_EAR, 0x70, ear_pa_gain);
8806 return 0;
8807}
8808
8809static int tasha_ear_spkr_pa_gain_get(struct snd_kcontrol *kcontrol,
8810 struct snd_ctl_elem_value *ucontrol)
8811{
8812 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
8813 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
8814
8815 ucontrol->value.integer.value[0] = tasha->ear_spkr_gain;
8816
8817 dev_dbg(codec->dev, "%s: ear_spkr_gain = %ld\n", __func__,
8818 ucontrol->value.integer.value[0]);
8819
8820 return 0;
8821}
8822
8823static int tasha_ear_spkr_pa_gain_put(struct snd_kcontrol *kcontrol,
8824 struct snd_ctl_elem_value *ucontrol)
8825{
8826 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
8827 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
8828
8829 dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
8830 __func__, ucontrol->value.integer.value[0]);
8831
8832 tasha->ear_spkr_gain = ucontrol->value.integer.value[0];
8833
8834 return 0;
8835}
8836
8837static int tasha_config_compander(struct snd_soc_codec *codec, int interp_n,
8838 int event)
8839{
8840 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
8841 int comp;
8842 u16 comp_ctl0_reg, rx_path_cfg0_reg;
8843
8844 /* EAR does not have compander */
8845 if (!interp_n)
8846 return 0;
8847
8848 comp = interp_n - 1;
8849 dev_dbg(codec->dev, "%s: event %d compander %d, enabled %d\n",
8850 __func__, event, comp + 1, tasha->comp_enabled[comp]);
8851
8852 if (!tasha->comp_enabled[comp])
8853 return 0;
8854
8855 comp_ctl0_reg = WCD9335_CDC_COMPANDER1_CTL0 + (comp * 8);
8856 rx_path_cfg0_reg = WCD9335_CDC_RX1_RX_PATH_CFG0 + (comp * 20);
8857
8858 if (SND_SOC_DAPM_EVENT_ON(event)) {
8859 /* Enable Compander Clock */
8860 snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x01);
8861 snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02);
8862 snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00);
8863 snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x02);
8864 }
8865
8866 if (SND_SOC_DAPM_EVENT_OFF(event)) {
8867 snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x04);
8868 snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x00);
8869 snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02);
8870 snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00);
8871 snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x00);
8872 snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x00);
8873 }
8874
8875 return 0;
8876}
8877
8878static int tasha_codec_config_mad(struct snd_soc_codec *codec)
8879{
8880 int ret = 0;
8881 int idx;
8882 const struct firmware *fw;
8883 struct firmware_cal *hwdep_cal = NULL;
8884 struct wcd_mad_audio_cal *mad_cal = NULL;
8885 const void *data;
8886 const char *filename = TASHA_MAD_AUDIO_FIRMWARE_PATH;
8887 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
8888 size_t cal_size;
8889
8890 hwdep_cal = wcdcal_get_fw_cal(tasha->fw_data, WCD9XXX_MAD_CAL);
8891 if (hwdep_cal) {
8892 data = hwdep_cal->data;
8893 cal_size = hwdep_cal->size;
8894 dev_dbg(codec->dev, "%s: using hwdep calibration\n",
8895 __func__);
8896 } else {
8897 ret = request_firmware(&fw, filename, codec->dev);
8898 if (ret || !fw) {
8899 dev_err(codec->dev,
8900 "%s: MAD firmware acquire failed, err = %d\n",
8901 __func__, ret);
8902 return -ENODEV;
8903 }
8904 data = fw->data;
8905 cal_size = fw->size;
8906 dev_dbg(codec->dev, "%s: using request_firmware calibration\n",
8907 __func__);
8908 }
8909
8910 if (cal_size < sizeof(*mad_cal)) {
8911 dev_err(codec->dev,
8912 "%s: Incorrect size %zd for MAD Cal, expected %zd\n",
8913 __func__, cal_size, sizeof(*mad_cal));
8914 ret = -ENOMEM;
8915 goto done;
8916 }
8917
8918 mad_cal = (struct wcd_mad_audio_cal *) (data);
8919 if (!mad_cal) {
8920 dev_err(codec->dev,
8921 "%s: Invalid calibration data\n",
8922 __func__);
8923 ret = -EINVAL;
8924 goto done;
8925 }
8926
8927 snd_soc_write(codec, WCD9335_SOC_MAD_MAIN_CTL_2,
8928 mad_cal->microphone_info.cycle_time);
8929 snd_soc_update_bits(codec, WCD9335_SOC_MAD_MAIN_CTL_1, 0xFF << 3,
8930 ((uint16_t)mad_cal->microphone_info.settle_time)
8931 << 3);
8932
8933 /* Audio */
8934 snd_soc_write(codec, WCD9335_SOC_MAD_AUDIO_CTL_8,
8935 mad_cal->audio_info.rms_omit_samples);
8936 snd_soc_update_bits(codec, WCD9335_SOC_MAD_AUDIO_CTL_1,
8937 0x07 << 4, mad_cal->audio_info.rms_comp_time << 4);
8938 snd_soc_update_bits(codec, WCD9335_SOC_MAD_AUDIO_CTL_2, 0x03 << 2,
8939 mad_cal->audio_info.detection_mechanism << 2);
8940 snd_soc_write(codec, WCD9335_SOC_MAD_AUDIO_CTL_7,
8941 mad_cal->audio_info.rms_diff_threshold & 0x3F);
8942 snd_soc_write(codec, WCD9335_SOC_MAD_AUDIO_CTL_5,
8943 mad_cal->audio_info.rms_threshold_lsb);
8944 snd_soc_write(codec, WCD9335_SOC_MAD_AUDIO_CTL_6,
8945 mad_cal->audio_info.rms_threshold_msb);
8946
8947 for (idx = 0; idx < ARRAY_SIZE(mad_cal->audio_info.iir_coefficients);
8948 idx++) {
8949 snd_soc_update_bits(codec, WCD9335_SOC_MAD_AUDIO_IIR_CTL_PTR,
8950 0x3F, idx);
8951 snd_soc_write(codec, WCD9335_SOC_MAD_AUDIO_IIR_CTL_VAL,
8952 mad_cal->audio_info.iir_coefficients[idx]);
8953 dev_dbg(codec->dev, "%s:MAD Audio IIR Coef[%d] = 0X%x",
8954 __func__, idx,
8955 mad_cal->audio_info.iir_coefficients[idx]);
8956 }
8957
8958 /* Beacon */
8959 snd_soc_write(codec, WCD9335_SOC_MAD_BEACON_CTL_8,
8960 mad_cal->beacon_info.rms_omit_samples);
8961 snd_soc_update_bits(codec, WCD9335_SOC_MAD_BEACON_CTL_1,
8962 0x07 << 4, mad_cal->beacon_info.rms_comp_time << 4);
8963 snd_soc_update_bits(codec, WCD9335_SOC_MAD_BEACON_CTL_2, 0x03 << 2,
8964 mad_cal->beacon_info.detection_mechanism << 2);
8965 snd_soc_write(codec, WCD9335_SOC_MAD_BEACON_CTL_7,
8966 mad_cal->beacon_info.rms_diff_threshold & 0x1F);
8967 snd_soc_write(codec, WCD9335_SOC_MAD_BEACON_CTL_5,
8968 mad_cal->beacon_info.rms_threshold_lsb);
8969 snd_soc_write(codec, WCD9335_SOC_MAD_BEACON_CTL_6,
8970 mad_cal->beacon_info.rms_threshold_msb);
8971
8972 for (idx = 0; idx < ARRAY_SIZE(mad_cal->beacon_info.iir_coefficients);
8973 idx++) {
8974 snd_soc_update_bits(codec, WCD9335_SOC_MAD_BEACON_IIR_CTL_PTR,
8975 0x3F, idx);
8976 snd_soc_write(codec, WCD9335_SOC_MAD_BEACON_IIR_CTL_VAL,
8977 mad_cal->beacon_info.iir_coefficients[idx]);
8978 dev_dbg(codec->dev, "%s:MAD Beacon IIR Coef[%d] = 0X%x",
8979 __func__, idx,
8980 mad_cal->beacon_info.iir_coefficients[idx]);
8981 }
8982
8983 /* Ultrasound */
8984 snd_soc_update_bits(codec, WCD9335_SOC_MAD_ULTR_CTL_1,
8985 0x07 << 4,
8986 mad_cal->ultrasound_info.rms_comp_time << 4);
8987 snd_soc_update_bits(codec, WCD9335_SOC_MAD_ULTR_CTL_2, 0x03 << 2,
8988 mad_cal->ultrasound_info.detection_mechanism << 2);
8989 snd_soc_write(codec, WCD9335_SOC_MAD_ULTR_CTL_7,
8990 mad_cal->ultrasound_info.rms_diff_threshold & 0x1F);
8991 snd_soc_write(codec, WCD9335_SOC_MAD_ULTR_CTL_5,
8992 mad_cal->ultrasound_info.rms_threshold_lsb);
8993 snd_soc_write(codec, WCD9335_SOC_MAD_ULTR_CTL_6,
8994 mad_cal->ultrasound_info.rms_threshold_msb);
8995
8996done:
8997 if (!hwdep_cal)
8998 release_firmware(fw);
8999
9000 return ret;
9001}
9002
9003static int tasha_codec_enable_mad(struct snd_soc_dapm_widget *w,
9004 struct snd_kcontrol *kcontrol, int event)
9005{
9006 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
9007 int ret = 0;
9008
9009 dev_dbg(codec->dev,
9010 "%s: event = %d\n", __func__, event);
9011
9012 /* Return if CPE INPUT is DEC1 */
9013 if (snd_soc_read(codec, WCD9335_CPE_SS_SVA_CFG) & 0x01)
9014 return ret;
9015
9016 switch (event) {
9017 case SND_SOC_DAPM_PRE_PMU:
9018
9019 /* Turn on MAD clk */
9020 snd_soc_update_bits(codec, WCD9335_CPE_SS_MAD_CTL,
9021 0x01, 0x01);
9022
9023 /* Undo reset for MAD */
9024 snd_soc_update_bits(codec, WCD9335_CPE_SS_MAD_CTL,
9025 0x02, 0x00);
9026 ret = tasha_codec_config_mad(codec);
9027 if (ret)
9028 dev_err(codec->dev,
9029 "%s: Failed to config MAD, err = %d\n",
9030 __func__, ret);
9031 break;
9032 case SND_SOC_DAPM_POST_PMD:
9033 /* Reset the MAD block */
9034 snd_soc_update_bits(codec, WCD9335_CPE_SS_MAD_CTL,
9035 0x02, 0x02);
9036 /* Turn off MAD clk */
9037 snd_soc_update_bits(codec, WCD9335_CPE_SS_MAD_CTL,
9038 0x01, 0x00);
9039 break;
9040 }
9041
9042 return ret;
9043}
9044
9045static int tasha_codec_configure_cpe_input(struct snd_soc_dapm_widget *w,
9046 struct snd_kcontrol *kcontrol, int event)
9047{
9048 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
9049
9050 dev_dbg(codec->dev,
9051 "%s: event = %d\n", __func__, event);
9052
9053 switch (event) {
9054 case SND_SOC_DAPM_PRE_PMU:
9055 /* Configure CPE input as DEC1 */
9056 snd_soc_update_bits(codec, WCD9335_CPE_SS_SVA_CFG,
9057 0x01, 0x01);
9058
9059 /* Configure DEC1 Tx out with sample rate as 16K */
9060 snd_soc_update_bits(codec, WCD9335_CDC_TX1_TX_PATH_CTL,
9061 0x0F, 0x01);
9062
9063 break;
9064 case SND_SOC_DAPM_POST_PMD:
9065 /* Reset DEC1 Tx out sample rate */
9066 snd_soc_update_bits(codec, WCD9335_CDC_TX1_TX_PATH_CTL,
9067 0x0F, 0x04);
9068 snd_soc_update_bits(codec, WCD9335_CPE_SS_SVA_CFG,
9069 0x01, 0x00);
9070
9071 break;
9072 }
9073
9074 return 0;
9075}
9076
9077
9078static int tasha_codec_aif4_mixer_switch_get(struct snd_kcontrol *kcontrol,
9079 struct snd_ctl_elem_value *ucontrol)
9080{
9081 struct snd_soc_dapm_widget_list *wlist =
9082 dapm_kcontrol_get_wlist(kcontrol);
9083 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
9084 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
9085 struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec);
9086
9087 if (test_bit(AIF4_SWITCH_VALUE, &tasha_p->status_mask))
9088 ucontrol->value.integer.value[0] = 1;
9089 else
9090 ucontrol->value.integer.value[0] = 0;
9091
9092 dev_dbg(codec->dev, "%s: AIF4 switch value = %ld\n",
9093 __func__, ucontrol->value.integer.value[0]);
9094 return 0;
9095}
9096
9097static int tasha_codec_aif4_mixer_switch_put(struct snd_kcontrol *kcontrol,
9098 struct snd_ctl_elem_value *ucontrol)
9099{
9100 struct snd_soc_dapm_widget_list *wlist =
9101 dapm_kcontrol_get_wlist(kcontrol);
9102 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
9103 struct snd_soc_dapm_update *update = NULL;
9104 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
9105 struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec);
9106
9107 dev_dbg(codec->dev, "%s: AIF4 switch value = %ld\n",
9108 __func__, ucontrol->value.integer.value[0]);
9109
9110 if (ucontrol->value.integer.value[0]) {
9111 snd_soc_dapm_mixer_update_power(widget->dapm,
9112 kcontrol, 1, update);
9113 set_bit(AIF4_SWITCH_VALUE, &tasha_p->status_mask);
9114 } else {
9115 snd_soc_dapm_mixer_update_power(widget->dapm,
9116 kcontrol, 0, update);
9117 clear_bit(AIF4_SWITCH_VALUE, &tasha_p->status_mask);
9118 }
9119
9120 return 1;
9121}
9122
9123static const char * const tasha_ear_pa_gain_text[] = {
9124 "G_6_DB", "G_4P5_DB", "G_3_DB", "G_1P5_DB",
9125 "G_0_DB", "G_M2P5_DB", "UNDEFINED", "G_M12_DB"
9126};
9127
9128static const char * const tasha_ear_spkr_pa_gain_text[] = {
9129 "G_DEFAULT", "G_0_DB", "G_1_DB", "G_2_DB", "G_3_DB", "G_4_DB",
9130 "G_5_DB", "G_6_DB"
9131};
9132
9133static const struct soc_enum tasha_ear_pa_gain_enum =
9134 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tasha_ear_pa_gain_text),
9135 tasha_ear_pa_gain_text);
9136
9137static const struct soc_enum tasha_ear_spkr_pa_gain_enum =
9138 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tasha_ear_spkr_pa_gain_text),
9139 tasha_ear_spkr_pa_gain_text);
9140
9141static const struct snd_kcontrol_new tasha_analog_gain_controls[] = {
9142 SOC_ENUM_EXT("EAR PA Gain", tasha_ear_pa_gain_enum,
9143 tasha_ear_pa_gain_get, tasha_ear_pa_gain_put),
9144
9145 SOC_ENUM_EXT("EAR SPKR PA Gain", tasha_ear_spkr_pa_gain_enum,
9146 tasha_ear_spkr_pa_gain_get, tasha_ear_spkr_pa_gain_put),
9147
9148 SOC_SINGLE_TLV("HPHL Volume", WCD9335_HPH_L_EN, 0, 20, 1,
9149 line_gain),
9150 SOC_SINGLE_TLV("HPHR Volume", WCD9335_HPH_R_EN, 0, 20, 1,
9151 line_gain),
9152 SOC_SINGLE_TLV("LINEOUT1 Volume", WCD9335_DIFF_LO_LO1_COMPANDER,
9153 3, 16, 1, line_gain),
9154 SOC_SINGLE_TLV("LINEOUT2 Volume", WCD9335_DIFF_LO_LO2_COMPANDER,
9155 3, 16, 1, line_gain),
9156 SOC_SINGLE_TLV("LINEOUT3 Volume", WCD9335_SE_LO_LO3_GAIN, 0, 20, 1,
9157 line_gain),
9158 SOC_SINGLE_TLV("LINEOUT4 Volume", WCD9335_SE_LO_LO4_GAIN, 0, 20, 1,
9159 line_gain),
9160
9161 SOC_SINGLE_TLV("ADC1 Volume", WCD9335_ANA_AMIC1, 0, 20, 0,
9162 analog_gain),
9163 SOC_SINGLE_TLV("ADC2 Volume", WCD9335_ANA_AMIC2, 0, 20, 0,
9164 analog_gain),
9165 SOC_SINGLE_TLV("ADC3 Volume", WCD9335_ANA_AMIC3, 0, 20, 0,
9166 analog_gain),
9167 SOC_SINGLE_TLV("ADC4 Volume", WCD9335_ANA_AMIC4, 0, 20, 0,
9168 analog_gain),
9169 SOC_SINGLE_TLV("ADC5 Volume", WCD9335_ANA_AMIC5, 0, 20, 0,
9170 analog_gain),
9171 SOC_SINGLE_TLV("ADC6 Volume", WCD9335_ANA_AMIC6, 0, 20, 0,
9172 analog_gain),
9173};
9174
9175static const char * const spl_src0_mux_text[] = {
9176 "ZERO", "SRC_IN_HPHL", "SRC_IN_LO1",
9177};
9178
9179static const char * const spl_src1_mux_text[] = {
9180 "ZERO", "SRC_IN_HPHR", "SRC_IN_LO2",
9181};
9182
9183static const char * const spl_src2_mux_text[] = {
9184 "ZERO", "SRC_IN_LO3", "SRC_IN_SPKRL",
9185};
9186
9187static const char * const spl_src3_mux_text[] = {
9188 "ZERO", "SRC_IN_LO4", "SRC_IN_SPKRR",
9189};
9190
9191static const char * const rx_int0_7_mix_mux_text[] = {
9192 "ZERO", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5",
9193 "RX6", "RX7", "PROXIMITY"
9194};
9195
9196static const char * const rx_int_mix_mux_text[] = {
9197 "ZERO", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5",
9198 "RX6", "RX7"
9199};
9200
9201static const char * const rx_prim_mix_text[] = {
9202 "ZERO", "DEC0", "DEC1", "IIR0", "IIR1", "RX0", "RX1", "RX2",
9203 "RX3", "RX4", "RX5", "RX6", "RX7"
9204};
9205
9206static const char * const rx_sidetone_mix_text[] = {
9207 "ZERO", "SRC0", "SRC1", "SRC_SUM"
9208};
9209
9210static const char * const sb_tx0_mux_text[] = {
9211 "ZERO", "RX_MIX_TX0", "DEC0", "DEC0_192"
9212};
9213
9214static const char * const sb_tx1_mux_text[] = {
9215 "ZERO", "RX_MIX_TX1", "DEC1", "DEC1_192"
9216};
9217
9218static const char * const sb_tx2_mux_text[] = {
9219 "ZERO", "RX_MIX_TX2", "DEC2", "DEC2_192"
9220};
9221
9222static const char * const sb_tx3_mux_text[] = {
9223 "ZERO", "RX_MIX_TX3", "DEC3", "DEC3_192"
9224};
9225
9226static const char * const sb_tx4_mux_text[] = {
9227 "ZERO", "RX_MIX_TX4", "DEC4", "DEC4_192"
9228};
9229
9230static const char * const sb_tx5_mux_text[] = {
9231 "ZERO", "RX_MIX_TX5", "DEC5", "DEC5_192"
9232};
9233
9234static const char * const sb_tx6_mux_text[] = {
9235 "ZERO", "RX_MIX_TX6", "DEC6", "DEC6_192"
9236};
9237
9238static const char * const sb_tx7_mux_text[] = {
9239 "ZERO", "RX_MIX_TX7", "DEC7", "DEC7_192"
9240};
9241
9242static const char * const sb_tx8_mux_text[] = {
9243 "ZERO", "RX_MIX_TX8", "DEC8", "DEC8_192"
9244};
9245
9246static const char * const sb_tx9_mux_text[] = {
9247 "ZERO", "DEC7", "DEC7_192"
9248};
9249
9250static const char * const sb_tx10_mux_text[] = {
9251 "ZERO", "DEC6", "DEC6_192"
9252};
9253
9254static const char * const sb_tx11_mux_text[] = {
9255 "DEC_0_5", "DEC_9_12", "MAD_AUDIO", "MAD_BRDCST"
9256};
9257
9258static const char * const sb_tx11_inp1_mux_text[] = {
9259 "ZERO", "DEC0", "DEC1", "DEC2", "DEC3", "DEC4",
9260 "DEC5", "RX_MIX_TX5", "DEC9_10", "DEC11_12"
9261};
9262
9263static const char * const sb_tx13_mux_text[] = {
9264 "ZERO", "DEC5", "DEC5_192"
9265};
9266
9267static const char * const tx13_inp_mux_text[] = {
9268 "CDC_DEC_5", "MAD_BRDCST", "CPE_TX_PP"
9269};
9270
9271static const char * const iir_inp_mux_text[] = {
9272 "ZERO", "DEC0", "DEC1", "DEC2", "DEC3", "DEC4", "DEC5", "DEC6",
9273 "DEC7", "DEC8", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5", "RX6", "RX7"
9274};
9275
9276static const char * const rx_int_dem_inp_mux_text[] = {
9277 "NORMAL_DSM_OUT", "CLSH_DSM_OUT",
9278};
9279
9280static const char * const rx_int0_interp_mux_text[] = {
9281 "ZERO", "RX INT0 MIX2",
9282};
9283
9284static const char * const rx_int1_interp_mux_text[] = {
9285 "ZERO", "RX INT1 MIX2",
9286};
9287
9288static const char * const rx_int2_interp_mux_text[] = {
9289 "ZERO", "RX INT2 MIX2",
9290};
9291
9292static const char * const rx_int3_interp_mux_text[] = {
9293 "ZERO", "RX INT3 MIX2",
9294};
9295
9296static const char * const rx_int4_interp_mux_text[] = {
9297 "ZERO", "RX INT4 MIX2",
9298};
9299
9300static const char * const rx_int5_interp_mux_text[] = {
9301 "ZERO", "RX INT5 MIX2",
9302};
9303
9304static const char * const rx_int6_interp_mux_text[] = {
9305 "ZERO", "RX INT6 MIX2",
9306};
9307
9308static const char * const rx_int7_interp_mux_text[] = {
9309 "ZERO", "RX INT7 MIX2",
9310};
9311
9312static const char * const rx_int8_interp_mux_text[] = {
9313 "ZERO", "RX INT8 SEC MIX"
9314};
9315
9316static const char * const mad_sel_text[] = {
9317 "SPE", "MSM"
9318};
9319
9320static const char * const adc_mux_text[] = {
9321 "DMIC", "AMIC", "ANC_FB_TUNE1", "ANC_FB_TUNE2"
9322};
9323
9324static const char * const dmic_mux_text[] = {
9325 "ZERO", "DMIC0", "DMIC1", "DMIC2", "DMIC3", "DMIC4", "DMIC5",
9326 "SMIC0", "SMIC1", "SMIC2", "SMIC3"
9327};
9328
9329static const char * const dmic_mux_alt_text[] = {
9330 "ZERO", "DMIC0", "DMIC1", "DMIC2", "DMIC3", "DMIC4", "DMIC5",
9331};
9332
9333static const char * const amic_mux_text[] = {
9334 "ZERO", "ADC1", "ADC2", "ADC3", "ADC4", "ADC5", "ADC6"
9335};
9336
9337static const char * const rx_echo_mux_text[] = {
9338 "ZERO", "RX_MIX0", "RX_MIX1", "RX_MIX2", "RX_MIX3", "RX_MIX4",
9339 "RX_MIX5", "RX_MIX6", "RX_MIX7", "RX_MIX8", "RX_MIX_VBAT5",
9340 "RX_MIX_VBAT6", "RX_MIX_VBAT7", "RX_MIX_VBAT8"
9341};
9342
9343static const char * const anc0_fb_mux_text[] = {
9344 "ZERO", "ANC_IN_HPHL", "ANC_IN_EAR", "ANC_IN_EAR_SPKR",
9345 "ANC_IN_LO1"
9346};
9347
9348static const char * const anc1_fb_mux_text[] = {
9349 "ZERO", "ANC_IN_HPHR", "ANC_IN_LO2"
9350};
9351
9352static const char * const native_mux_text[] = {
9353 "OFF", "ON",
9354};
9355
9356static const struct soc_enum spl_src0_mux_chain_enum =
9357 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SPLINE_SRC_CFG0, 0, 3,
9358 spl_src0_mux_text);
9359
9360static const struct soc_enum spl_src1_mux_chain_enum =
9361 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SPLINE_SRC_CFG0, 2, 3,
9362 spl_src1_mux_text);
9363
9364static const struct soc_enum spl_src2_mux_chain_enum =
9365 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SPLINE_SRC_CFG0, 4, 3,
9366 spl_src2_mux_text);
9367
9368static const struct soc_enum spl_src3_mux_chain_enum =
9369 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SPLINE_SRC_CFG0, 6, 3,
9370 spl_src3_mux_text);
9371
9372static const struct soc_enum rx_int0_2_mux_chain_enum =
9373 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG1, 0, 10,
9374 rx_int0_7_mix_mux_text);
9375
9376static const struct soc_enum rx_int1_2_mux_chain_enum =
9377 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG1, 0, 9,
9378 rx_int_mix_mux_text);
9379
9380static const struct soc_enum rx_int2_2_mux_chain_enum =
9381 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG1, 0, 9,
9382 rx_int_mix_mux_text);
9383
9384static const struct soc_enum rx_int3_2_mux_chain_enum =
9385 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG1, 0, 9,
9386 rx_int_mix_mux_text);
9387
9388static const struct soc_enum rx_int4_2_mux_chain_enum =
9389 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG1, 0, 9,
9390 rx_int_mix_mux_text);
9391
9392static const struct soc_enum rx_int5_2_mux_chain_enum =
9393 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG1, 0, 9,
9394 rx_int_mix_mux_text);
9395
9396static const struct soc_enum rx_int6_2_mux_chain_enum =
9397 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG1, 0, 9,
9398 rx_int_mix_mux_text);
9399
9400static const struct soc_enum rx_int7_2_mux_chain_enum =
9401 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG1, 0, 10,
9402 rx_int0_7_mix_mux_text);
9403
9404static const struct soc_enum rx_int8_2_mux_chain_enum =
9405 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG1, 0, 9,
9406 rx_int_mix_mux_text);
9407
9408static const struct soc_enum int1_1_native_enum =
9409 SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(native_mux_text),
9410 native_mux_text);
9411
9412static const struct soc_enum int2_1_native_enum =
9413 SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(native_mux_text),
9414 native_mux_text);
9415
9416static const struct soc_enum int3_1_native_enum =
9417 SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(native_mux_text),
9418 native_mux_text);
9419
9420static const struct soc_enum int4_1_native_enum =
9421 SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(native_mux_text),
9422 native_mux_text);
9423
9424static const struct soc_enum rx_int0_1_mix_inp0_chain_enum =
9425 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG0, 0, 13,
9426 rx_prim_mix_text);
9427
9428static const struct soc_enum rx_int0_1_mix_inp1_chain_enum =
9429 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG0, 4, 13,
9430 rx_prim_mix_text);
9431
9432static const struct soc_enum rx_int0_1_mix_inp2_chain_enum =
9433 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG1, 4, 13,
9434 rx_prim_mix_text);
9435
9436static const struct soc_enum rx_int1_1_mix_inp0_chain_enum =
9437 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG0, 0, 13,
9438 rx_prim_mix_text);
9439
9440static const struct soc_enum rx_int1_1_mix_inp1_chain_enum =
9441 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG0, 4, 13,
9442 rx_prim_mix_text);
9443
9444static const struct soc_enum rx_int1_1_mix_inp2_chain_enum =
9445 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG1, 4, 13,
9446 rx_prim_mix_text);
9447
9448static const struct soc_enum rx_int2_1_mix_inp0_chain_enum =
9449 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG0, 0, 13,
9450 rx_prim_mix_text);
9451
9452static const struct soc_enum rx_int2_1_mix_inp1_chain_enum =
9453 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG0, 4, 13,
9454 rx_prim_mix_text);
9455
9456static const struct soc_enum rx_int2_1_mix_inp2_chain_enum =
9457 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG1, 4, 13,
9458 rx_prim_mix_text);
9459
9460static const struct soc_enum rx_int3_1_mix_inp0_chain_enum =
9461 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG0, 0, 13,
9462 rx_prim_mix_text);
9463
9464static const struct soc_enum rx_int3_1_mix_inp1_chain_enum =
9465 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG0, 4, 13,
9466 rx_prim_mix_text);
9467
9468static const struct soc_enum rx_int3_1_mix_inp2_chain_enum =
9469 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG1, 4, 13,
9470 rx_prim_mix_text);
9471
9472static const struct soc_enum rx_int4_1_mix_inp0_chain_enum =
9473 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG0, 0, 13,
9474 rx_prim_mix_text);
9475
9476static const struct soc_enum rx_int4_1_mix_inp1_chain_enum =
9477 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG0, 4, 13,
9478 rx_prim_mix_text);
9479
9480static const struct soc_enum rx_int4_1_mix_inp2_chain_enum =
9481 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG1, 4, 13,
9482 rx_prim_mix_text);
9483
9484static const struct soc_enum rx_int5_1_mix_inp0_chain_enum =
9485 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG0, 0, 13,
9486 rx_prim_mix_text);
9487
9488static const struct soc_enum rx_int5_1_mix_inp1_chain_enum =
9489 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG0, 4, 13,
9490 rx_prim_mix_text);
9491
9492static const struct soc_enum rx_int5_1_mix_inp2_chain_enum =
9493 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG1, 4, 13,
9494 rx_prim_mix_text);
9495
9496static const struct soc_enum rx_int6_1_mix_inp0_chain_enum =
9497 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG0, 0, 13,
9498 rx_prim_mix_text);
9499
9500static const struct soc_enum rx_int6_1_mix_inp1_chain_enum =
9501 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG0, 4, 13,
9502 rx_prim_mix_text);
9503
9504static const struct soc_enum rx_int6_1_mix_inp2_chain_enum =
9505 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG1, 4, 13,
9506 rx_prim_mix_text);
9507
9508static const struct soc_enum rx_int7_1_mix_inp0_chain_enum =
9509 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG0, 0, 13,
9510 rx_prim_mix_text);
9511
9512static const struct soc_enum rx_int7_1_mix_inp1_chain_enum =
9513 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG0, 4, 13,
9514 rx_prim_mix_text);
9515
9516static const struct soc_enum rx_int7_1_mix_inp2_chain_enum =
9517 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG1, 4, 13,
9518 rx_prim_mix_text);
9519
9520static const struct soc_enum rx_int8_1_mix_inp0_chain_enum =
9521 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG0, 0, 13,
9522 rx_prim_mix_text);
9523
9524static const struct soc_enum rx_int8_1_mix_inp1_chain_enum =
9525 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG0, 4, 13,
9526 rx_prim_mix_text);
9527
9528static const struct soc_enum rx_int8_1_mix_inp2_chain_enum =
9529 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG1, 4, 13,
9530 rx_prim_mix_text);
9531
9532static const struct soc_enum rx_int0_sidetone_mix_chain_enum =
9533 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 0, 4,
9534 rx_sidetone_mix_text);
9535
9536static const struct soc_enum rx_int1_sidetone_mix_chain_enum =
9537 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 2, 4,
9538 rx_sidetone_mix_text);
9539
9540static const struct soc_enum rx_int2_sidetone_mix_chain_enum =
9541 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 4, 4,
9542 rx_sidetone_mix_text);
9543
9544static const struct soc_enum rx_int3_sidetone_mix_chain_enum =
9545 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 6, 4,
9546 rx_sidetone_mix_text);
9547
9548static const struct soc_enum rx_int4_sidetone_mix_chain_enum =
9549 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SIDETONE_SRC_CFG1, 0, 4,
9550 rx_sidetone_mix_text);
9551
9552static const struct soc_enum rx_int7_sidetone_mix_chain_enum =
9553 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SIDETONE_SRC_CFG1, 2, 4,
9554 rx_sidetone_mix_text);
9555
9556static const struct soc_enum tx_adc_mux0_chain_enum =
9557 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG1, 0, 4,
9558 adc_mux_text);
9559
9560static const struct soc_enum tx_adc_mux1_chain_enum =
9561 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX1_CFG1, 0, 4,
9562 adc_mux_text);
9563
9564static const struct soc_enum tx_adc_mux2_chain_enum =
9565 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX2_CFG1, 0, 4,
9566 adc_mux_text);
9567
9568static const struct soc_enum tx_adc_mux3_chain_enum =
9569 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX3_CFG1, 0, 4,
9570 adc_mux_text);
9571
9572static const struct soc_enum tx_adc_mux4_chain_enum =
9573 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0, 6, 4,
9574 adc_mux_text);
9575
9576static const struct soc_enum tx_adc_mux5_chain_enum =
9577 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX5_CFG0, 6, 4,
9578 adc_mux_text);
9579
9580static const struct soc_enum tx_adc_mux6_chain_enum =
9581 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX6_CFG0, 6, 4,
9582 adc_mux_text);
9583
9584static const struct soc_enum tx_adc_mux7_chain_enum =
9585 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 6, 4,
9586 adc_mux_text);
9587
9588static const struct soc_enum tx_adc_mux8_chain_enum =
9589 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX8_CFG0, 6, 4,
9590 adc_mux_text);
9591
9592static const struct soc_enum tx_adc_mux10_chain_enum =
9593 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX10_CFG0, 6, 4,
9594 adc_mux_text);
9595
9596static const struct soc_enum tx_adc_mux11_chain_enum =
9597 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX11_CFG0, 6, 4,
9598 adc_mux_text);
9599
9600static const struct soc_enum tx_adc_mux12_chain_enum =
9601 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX12_CFG0, 6, 4,
9602 adc_mux_text);
9603
9604static const struct soc_enum tx_adc_mux13_chain_enum =
9605 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX13_CFG0, 6, 4,
9606 adc_mux_text);
9607
9608static const struct soc_enum tx_dmic_mux0_enum =
9609 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG0, 3, 11,
9610 dmic_mux_text);
9611
9612static const struct soc_enum tx_dmic_mux1_enum =
9613 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX1_CFG0, 3, 11,
9614 dmic_mux_text);
9615
9616static const struct soc_enum tx_dmic_mux2_enum =
9617 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX2_CFG0, 3, 11,
9618 dmic_mux_text);
9619
9620static const struct soc_enum tx_dmic_mux3_enum =
9621 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX3_CFG0, 3, 11,
9622 dmic_mux_text);
9623
9624static const struct soc_enum tx_dmic_mux4_enum =
9625 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0, 3, 7,
9626 dmic_mux_alt_text);
9627
9628static const struct soc_enum tx_dmic_mux5_enum =
9629 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX5_CFG0, 3, 7,
9630 dmic_mux_alt_text);
9631
9632static const struct soc_enum tx_dmic_mux6_enum =
9633 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX6_CFG0, 3, 7,
9634 dmic_mux_alt_text);
9635
9636static const struct soc_enum tx_dmic_mux7_enum =
9637 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 3, 7,
9638 dmic_mux_alt_text);
9639
9640static const struct soc_enum tx_dmic_mux8_enum =
9641 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX8_CFG0, 3, 7,
9642 dmic_mux_alt_text);
9643
9644static const struct soc_enum tx_dmic_mux10_enum =
9645 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX10_CFG0, 3, 7,
9646 dmic_mux_alt_text);
9647
9648static const struct soc_enum tx_dmic_mux11_enum =
9649 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX11_CFG0, 3, 7,
9650 dmic_mux_alt_text);
9651
9652static const struct soc_enum tx_dmic_mux12_enum =
9653 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX12_CFG0, 3, 7,
9654 dmic_mux_alt_text);
9655
9656static const struct soc_enum tx_dmic_mux13_enum =
9657 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX13_CFG0, 3, 7,
9658 dmic_mux_alt_text);
9659
9660static const struct soc_enum tx_amic_mux0_enum =
9661 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG0, 0, 7,
9662 amic_mux_text);
9663
9664static const struct soc_enum tx_amic_mux1_enum =
9665 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX1_CFG0, 0, 7,
9666 amic_mux_text);
9667
9668static const struct soc_enum tx_amic_mux2_enum =
9669 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX2_CFG0, 0, 7,
9670 amic_mux_text);
9671
9672static const struct soc_enum tx_amic_mux3_enum =
9673 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX3_CFG0, 0, 7,
9674 amic_mux_text);
9675
9676static const struct soc_enum tx_amic_mux4_enum =
9677 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0, 0, 7,
9678 amic_mux_text);
9679
9680static const struct soc_enum tx_amic_mux5_enum =
9681 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX5_CFG0, 0, 7,
9682 amic_mux_text);
9683
9684static const struct soc_enum tx_amic_mux6_enum =
9685 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX6_CFG0, 0, 7,
9686 amic_mux_text);
9687
9688static const struct soc_enum tx_amic_mux7_enum =
9689 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 0, 7,
9690 amic_mux_text);
9691
9692static const struct soc_enum tx_amic_mux8_enum =
9693 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX8_CFG0, 0, 7,
9694 amic_mux_text);
9695
9696static const struct soc_enum tx_amic_mux10_enum =
9697 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX10_CFG0, 0, 7,
9698 amic_mux_text);
9699
9700static const struct soc_enum tx_amic_mux11_enum =
9701 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX11_CFG0, 0, 7,
9702 amic_mux_text);
9703
9704static const struct soc_enum tx_amic_mux12_enum =
9705 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX12_CFG0, 0, 7,
9706 amic_mux_text);
9707
9708static const struct soc_enum tx_amic_mux13_enum =
9709 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX13_CFG0, 0, 7,
9710 amic_mux_text);
9711
9712static const struct soc_enum sb_tx0_mux_enum =
9713 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0, 0, 4,
9714 sb_tx0_mux_text);
9715
9716static const struct soc_enum sb_tx1_mux_enum =
9717 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0, 2, 4,
9718 sb_tx1_mux_text);
9719
9720static const struct soc_enum sb_tx2_mux_enum =
9721 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0, 4, 4,
9722 sb_tx2_mux_text);
9723
9724static const struct soc_enum sb_tx3_mux_enum =
9725 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0, 6, 4,
9726 sb_tx3_mux_text);
9727
9728static const struct soc_enum sb_tx4_mux_enum =
9729 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1, 0, 4,
9730 sb_tx4_mux_text);
9731
9732static const struct soc_enum sb_tx5_mux_enum =
9733 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1, 2, 4,
9734 sb_tx5_mux_text);
9735
9736static const struct soc_enum sb_tx6_mux_enum =
9737 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1, 4, 4,
9738 sb_tx6_mux_text);
9739
9740static const struct soc_enum sb_tx7_mux_enum =
9741 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1, 6, 4,
9742 sb_tx7_mux_text);
9743
9744static const struct soc_enum sb_tx8_mux_enum =
9745 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG2, 0, 4,
9746 sb_tx8_mux_text);
9747
9748static const struct soc_enum sb_tx9_mux_enum =
9749 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG2, 2, 3,
9750 sb_tx9_mux_text);
9751
9752static const struct soc_enum sb_tx10_mux_enum =
9753 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG2, 4, 3,
9754 sb_tx10_mux_text);
9755
9756static const struct soc_enum sb_tx11_mux_enum =
9757 SOC_ENUM_SINGLE(WCD9335_DATA_HUB_DATA_HUB_SB_TX11_INP_CFG, 0, 4,
9758 sb_tx11_mux_text);
9759
9760static const struct soc_enum sb_tx11_inp1_mux_enum =
9761 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG3, 0, 10,
9762 sb_tx11_inp1_mux_text);
9763
9764static const struct soc_enum sb_tx13_mux_enum =
9765 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG3, 4, 3,
9766 sb_tx13_mux_text);
9767
9768static const struct soc_enum tx13_inp_mux_enum =
9769 SOC_ENUM_SINGLE(WCD9335_DATA_HUB_DATA_HUB_SB_TX13_INP_CFG, 0, 3,
9770 tx13_inp_mux_text);
9771
9772static const struct soc_enum rx_mix_tx0_mux_enum =
9773 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG0, 0, 14,
9774 rx_echo_mux_text);
9775
9776static const struct soc_enum rx_mix_tx1_mux_enum =
9777 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG0, 4, 14,
9778 rx_echo_mux_text);
9779
9780static const struct soc_enum rx_mix_tx2_mux_enum =
9781 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG1, 0, 14,
9782 rx_echo_mux_text);
9783
9784static const struct soc_enum rx_mix_tx3_mux_enum =
9785 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG1, 4, 14,
9786 rx_echo_mux_text);
9787
9788static const struct soc_enum rx_mix_tx4_mux_enum =
9789 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG2, 0, 14,
9790 rx_echo_mux_text);
9791
9792static const struct soc_enum rx_mix_tx5_mux_enum =
9793 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG2, 4, 14,
9794 rx_echo_mux_text);
9795
9796static const struct soc_enum rx_mix_tx6_mux_enum =
9797 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG3, 0, 14,
9798 rx_echo_mux_text);
9799
9800static const struct soc_enum rx_mix_tx7_mux_enum =
9801 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG3, 4, 14,
9802 rx_echo_mux_text);
9803
9804static const struct soc_enum rx_mix_tx8_mux_enum =
9805 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG4, 0, 14,
9806 rx_echo_mux_text);
9807
9808static const struct soc_enum iir0_inp0_mux_enum =
9809 SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG0, 0, 18,
9810 iir_inp_mux_text);
9811
9812static const struct soc_enum iir0_inp1_mux_enum =
9813 SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG1, 0, 18,
9814 iir_inp_mux_text);
9815
9816static const struct soc_enum iir0_inp2_mux_enum =
9817 SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG2, 0, 18,
9818 iir_inp_mux_text);
9819
9820static const struct soc_enum iir0_inp3_mux_enum =
9821 SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG3, 0, 18,
9822 iir_inp_mux_text);
9823
9824static const struct soc_enum iir1_inp0_mux_enum =
9825 SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG0, 0, 18,
9826 iir_inp_mux_text);
9827
9828static const struct soc_enum iir1_inp1_mux_enum =
9829 SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG1, 0, 18,
9830 iir_inp_mux_text);
9831
9832static const struct soc_enum iir1_inp2_mux_enum =
9833 SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG2, 0, 18,
9834 iir_inp_mux_text);
9835
9836static const struct soc_enum iir1_inp3_mux_enum =
9837 SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG3, 0, 18,
9838 iir_inp_mux_text);
9839
9840static const struct soc_enum rx_int0_dem_inp_mux_enum =
9841 SOC_ENUM_SINGLE(WCD9335_CDC_RX0_RX_PATH_SEC0, 0,
9842 ARRAY_SIZE(rx_int_dem_inp_mux_text),
9843 rx_int_dem_inp_mux_text);
9844
9845static const struct soc_enum rx_int1_dem_inp_mux_enum =
9846 SOC_ENUM_SINGLE(WCD9335_CDC_RX1_RX_PATH_SEC0, 0,
9847 ARRAY_SIZE(rx_int_dem_inp_mux_text),
9848 rx_int_dem_inp_mux_text);
9849
9850static const struct soc_enum rx_int2_dem_inp_mux_enum =
9851 SOC_ENUM_SINGLE(WCD9335_CDC_RX2_RX_PATH_SEC0, 0,
9852 ARRAY_SIZE(rx_int_dem_inp_mux_text),
9853 rx_int_dem_inp_mux_text);
9854
9855static const struct soc_enum rx_int0_interp_mux_enum =
9856 SOC_ENUM_SINGLE(WCD9335_CDC_RX0_RX_PATH_CTL, 5, 2,
9857 rx_int0_interp_mux_text);
9858
9859static const struct soc_enum rx_int1_interp_mux_enum =
9860 SOC_ENUM_SINGLE(WCD9335_CDC_RX1_RX_PATH_CTL, 5, 2,
9861 rx_int1_interp_mux_text);
9862
9863static const struct soc_enum rx_int2_interp_mux_enum =
9864 SOC_ENUM_SINGLE(WCD9335_CDC_RX2_RX_PATH_CTL, 5, 2,
9865 rx_int2_interp_mux_text);
9866
9867static const struct soc_enum rx_int3_interp_mux_enum =
9868 SOC_ENUM_SINGLE(WCD9335_CDC_RX3_RX_PATH_CTL, 5, 2,
9869 rx_int3_interp_mux_text);
9870
9871static const struct soc_enum rx_int4_interp_mux_enum =
9872 SOC_ENUM_SINGLE(WCD9335_CDC_RX4_RX_PATH_CTL, 5, 2,
9873 rx_int4_interp_mux_text);
9874
9875static const struct soc_enum rx_int5_interp_mux_enum =
9876 SOC_ENUM_SINGLE(WCD9335_CDC_RX5_RX_PATH_CTL, 5, 2,
9877 rx_int5_interp_mux_text);
9878
9879static const struct soc_enum rx_int6_interp_mux_enum =
9880 SOC_ENUM_SINGLE(WCD9335_CDC_RX6_RX_PATH_CTL, 5, 2,
9881 rx_int6_interp_mux_text);
9882
9883static const struct soc_enum rx_int7_interp_mux_enum =
9884 SOC_ENUM_SINGLE(WCD9335_CDC_RX7_RX_PATH_CTL, 5, 2,
9885 rx_int7_interp_mux_text);
9886
9887static const struct soc_enum rx_int8_interp_mux_enum =
9888 SOC_ENUM_SINGLE(WCD9335_CDC_RX8_RX_PATH_CTL, 5, 2,
9889 rx_int8_interp_mux_text);
9890
9891static const struct soc_enum mad_sel_enum =
9892 SOC_ENUM_SINGLE(WCD9335_CPE_SS_CFG, 0, 2, mad_sel_text);
9893
9894static const struct soc_enum anc0_fb_mux_enum =
9895 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_ANC_CFG0, 0, 5,
9896 anc0_fb_mux_text);
9897
9898static const struct soc_enum anc1_fb_mux_enum =
9899 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_ANC_CFG0, 3, 3,
9900 anc1_fb_mux_text);
9901
9902static const struct snd_kcontrol_new rx_int0_dem_inp_mux =
9903 SOC_DAPM_ENUM_EXT("RX INT0 DEM MUX Mux", rx_int0_dem_inp_mux_enum,
9904 snd_soc_dapm_get_enum_double,
9905 tasha_int_dem_inp_mux_put);
9906
9907static const struct snd_kcontrol_new rx_int1_dem_inp_mux =
9908 SOC_DAPM_ENUM_EXT("RX INT1 DEM MUX Mux", rx_int1_dem_inp_mux_enum,
9909 snd_soc_dapm_get_enum_double,
9910 tasha_int_dem_inp_mux_put);
9911
9912static const struct snd_kcontrol_new rx_int2_dem_inp_mux =
9913 SOC_DAPM_ENUM_EXT("RX INT2 DEM MUX Mux", rx_int2_dem_inp_mux_enum,
9914 snd_soc_dapm_get_enum_double,
9915 tasha_int_dem_inp_mux_put);
9916
9917static const struct snd_kcontrol_new spl_src0_mux =
9918 SOC_DAPM_ENUM("SPL SRC0 MUX Mux", spl_src0_mux_chain_enum);
9919
9920static const struct snd_kcontrol_new spl_src1_mux =
9921 SOC_DAPM_ENUM("SPL SRC1 MUX Mux", spl_src1_mux_chain_enum);
9922
9923static const struct snd_kcontrol_new spl_src2_mux =
9924 SOC_DAPM_ENUM("SPL SRC2 MUX Mux", spl_src2_mux_chain_enum);
9925
9926static const struct snd_kcontrol_new spl_src3_mux =
9927 SOC_DAPM_ENUM("SPL SRC3 MUX Mux", spl_src3_mux_chain_enum);
9928
9929static const struct snd_kcontrol_new rx_int0_2_mux =
9930 SOC_DAPM_ENUM("RX INT0_2 MUX Mux", rx_int0_2_mux_chain_enum);
9931
9932static const struct snd_kcontrol_new rx_int1_2_mux =
9933 SOC_DAPM_ENUM("RX INT1_2 MUX Mux", rx_int1_2_mux_chain_enum);
9934
9935static const struct snd_kcontrol_new rx_int2_2_mux =
9936 SOC_DAPM_ENUM("RX INT2_2 MUX Mux", rx_int2_2_mux_chain_enum);
9937
9938static const struct snd_kcontrol_new rx_int3_2_mux =
9939 SOC_DAPM_ENUM("RX INT3_2 MUX Mux", rx_int3_2_mux_chain_enum);
9940
9941static const struct snd_kcontrol_new rx_int4_2_mux =
9942 SOC_DAPM_ENUM("RX INT4_2 MUX Mux", rx_int4_2_mux_chain_enum);
9943
9944static const struct snd_kcontrol_new rx_int5_2_mux =
9945 SOC_DAPM_ENUM("RX INT5_2 MUX Mux", rx_int5_2_mux_chain_enum);
9946
9947static const struct snd_kcontrol_new rx_int6_2_mux =
9948 SOC_DAPM_ENUM("RX INT6_2 MUX Mux", rx_int6_2_mux_chain_enum);
9949
9950static const struct snd_kcontrol_new rx_int7_2_mux =
9951 SOC_DAPM_ENUM("RX INT7_2 MUX Mux", rx_int7_2_mux_chain_enum);
9952
9953static const struct snd_kcontrol_new rx_int8_2_mux =
9954 SOC_DAPM_ENUM("RX INT8_2 MUX Mux", rx_int8_2_mux_chain_enum);
9955
9956static const struct snd_kcontrol_new int1_1_native_mux =
9957 SOC_DAPM_ENUM("RX INT1_1 NATIVE MUX Mux", int1_1_native_enum);
9958
9959static const struct snd_kcontrol_new int2_1_native_mux =
9960 SOC_DAPM_ENUM("RX INT2_1 NATIVE MUX Mux", int2_1_native_enum);
9961
9962static const struct snd_kcontrol_new int3_1_native_mux =
9963 SOC_DAPM_ENUM("RX INT3_1 NATIVE MUX Mux", int3_1_native_enum);
9964
9965static const struct snd_kcontrol_new int4_1_native_mux =
9966 SOC_DAPM_ENUM("RX INT4_1 NATIVE MUX Mux", int4_1_native_enum);
9967
9968static const struct snd_kcontrol_new rx_int0_1_mix_inp0_mux =
9969 SOC_DAPM_ENUM("RX INT0_1 MIX1 INP0 Mux", rx_int0_1_mix_inp0_chain_enum);
9970
9971static const struct snd_kcontrol_new rx_int0_1_mix_inp1_mux =
9972 SOC_DAPM_ENUM("RX INT0_1 MIX1 INP1 Mux", rx_int0_1_mix_inp1_chain_enum);
9973
9974static const struct snd_kcontrol_new rx_int0_1_mix_inp2_mux =
9975 SOC_DAPM_ENUM("RX INT0_1 MIX1 INP2 Mux", rx_int0_1_mix_inp2_chain_enum);
9976
9977static const struct snd_kcontrol_new rx_int1_1_mix_inp0_mux =
9978 SOC_DAPM_ENUM("RX INT1_1 MIX1 INP0 Mux", rx_int1_1_mix_inp0_chain_enum);
9979
9980static const struct snd_kcontrol_new rx_int1_1_mix_inp1_mux =
9981 SOC_DAPM_ENUM("RX INT1_1 MIX1 INP1 Mux", rx_int1_1_mix_inp1_chain_enum);
9982
9983static const struct snd_kcontrol_new rx_int1_1_mix_inp2_mux =
9984 SOC_DAPM_ENUM("RX INT1_1 MIX1 INP2 Mux", rx_int1_1_mix_inp2_chain_enum);
9985
9986static const struct snd_kcontrol_new rx_int2_1_mix_inp0_mux =
9987 SOC_DAPM_ENUM("RX INT2_1 MIX1 INP0 Mux", rx_int2_1_mix_inp0_chain_enum);
9988
9989static const struct snd_kcontrol_new rx_int2_1_mix_inp1_mux =
9990 SOC_DAPM_ENUM("RX INT2_1 MIX1 INP1 Mux", rx_int2_1_mix_inp1_chain_enum);
9991
9992static const struct snd_kcontrol_new rx_int2_1_mix_inp2_mux =
9993 SOC_DAPM_ENUM("RX INT2_1 MIX1 INP2 Mux", rx_int2_1_mix_inp2_chain_enum);
9994
9995static const struct snd_kcontrol_new rx_int3_1_mix_inp0_mux =
9996 SOC_DAPM_ENUM("RX INT3_1 MIX1 INP0 Mux", rx_int3_1_mix_inp0_chain_enum);
9997
9998static const struct snd_kcontrol_new rx_int3_1_mix_inp1_mux =
9999 SOC_DAPM_ENUM("RX INT3_1 MIX1 INP1 Mux", rx_int3_1_mix_inp1_chain_enum);
10000
10001static const struct snd_kcontrol_new rx_int3_1_mix_inp2_mux =
10002 SOC_DAPM_ENUM("RX INT3_1 MIX1 INP2 Mux", rx_int3_1_mix_inp2_chain_enum);
10003
10004static const struct snd_kcontrol_new rx_int4_1_mix_inp0_mux =
10005 SOC_DAPM_ENUM("RX INT4_1 MIX1 INP0 Mux", rx_int4_1_mix_inp0_chain_enum);
10006
10007static const struct snd_kcontrol_new rx_int4_1_mix_inp1_mux =
10008 SOC_DAPM_ENUM("RX INT4_1 MIX1 INP1 Mux", rx_int4_1_mix_inp1_chain_enum);
10009
10010static const struct snd_kcontrol_new rx_int4_1_mix_inp2_mux =
10011 SOC_DAPM_ENUM("RX INT4_1 MIX1 INP2 Mux", rx_int4_1_mix_inp2_chain_enum);
10012
10013static const struct snd_kcontrol_new rx_int5_1_mix_inp0_mux =
10014 SOC_DAPM_ENUM("RX INT5_1 MIX1 INP0 Mux", rx_int5_1_mix_inp0_chain_enum);
10015
10016static const struct snd_kcontrol_new rx_int5_1_mix_inp1_mux =
10017 SOC_DAPM_ENUM("RX INT5_1 MIX1 INP1 Mux", rx_int5_1_mix_inp1_chain_enum);
10018
10019static const struct snd_kcontrol_new rx_int5_1_mix_inp2_mux =
10020 SOC_DAPM_ENUM("RX INT5_1 MIX1 INP2 Mux", rx_int5_1_mix_inp2_chain_enum);
10021
10022static const struct snd_kcontrol_new rx_int6_1_mix_inp0_mux =
10023 SOC_DAPM_ENUM("RX INT6_1 MIX1 INP0 Mux", rx_int6_1_mix_inp0_chain_enum);
10024
10025static const struct snd_kcontrol_new rx_int6_1_mix_inp1_mux =
10026 SOC_DAPM_ENUM("RX INT6_1 MIX1 INP1 Mux", rx_int6_1_mix_inp1_chain_enum);
10027
10028static const struct snd_kcontrol_new rx_int6_1_mix_inp2_mux =
10029 SOC_DAPM_ENUM("RX INT6_1 MIX1 INP2 Mux", rx_int6_1_mix_inp2_chain_enum);
10030
10031static const struct snd_kcontrol_new rx_int7_1_mix_inp0_mux =
10032 SOC_DAPM_ENUM("RX INT7_1 MIX1 INP0 Mux", rx_int7_1_mix_inp0_chain_enum);
10033
10034static const struct snd_kcontrol_new rx_int7_1_mix_inp1_mux =
10035 SOC_DAPM_ENUM("RX INT7_1 MIX1 INP1 Mux", rx_int7_1_mix_inp1_chain_enum);
10036
10037static const struct snd_kcontrol_new rx_int7_1_mix_inp2_mux =
10038 SOC_DAPM_ENUM("RX INT7_1 MIX1 INP2 Mux", rx_int7_1_mix_inp2_chain_enum);
10039
10040static const struct snd_kcontrol_new rx_int8_1_mix_inp0_mux =
10041 SOC_DAPM_ENUM("RX INT8_1 MIX1 INP0 Mux", rx_int8_1_mix_inp0_chain_enum);
10042
10043static const struct snd_kcontrol_new rx_int8_1_mix_inp1_mux =
10044 SOC_DAPM_ENUM("RX INT8_1 MIX1 INP1 Mux", rx_int8_1_mix_inp1_chain_enum);
10045
10046static const struct snd_kcontrol_new rx_int8_1_mix_inp2_mux =
10047 SOC_DAPM_ENUM("RX INT8_1 MIX1 INP2 Mux", rx_int8_1_mix_inp2_chain_enum);
10048
10049static const struct snd_kcontrol_new rx_int0_mix2_inp_mux =
10050 SOC_DAPM_ENUM("RX INT0 MIX2 INP Mux", rx_int0_sidetone_mix_chain_enum);
10051
10052static const struct snd_kcontrol_new rx_int1_mix2_inp_mux =
10053 SOC_DAPM_ENUM("RX INT1 MIX2 INP Mux", rx_int1_sidetone_mix_chain_enum);
10054
10055static const struct snd_kcontrol_new rx_int2_mix2_inp_mux =
10056 SOC_DAPM_ENUM("RX INT2 MIX2 INP Mux", rx_int2_sidetone_mix_chain_enum);
10057
10058static const struct snd_kcontrol_new rx_int3_mix2_inp_mux =
10059 SOC_DAPM_ENUM("RX INT3 MIX2 INP Mux", rx_int3_sidetone_mix_chain_enum);
10060
10061static const struct snd_kcontrol_new rx_int4_mix2_inp_mux =
10062 SOC_DAPM_ENUM("RX INT4 MIX2 INP Mux", rx_int4_sidetone_mix_chain_enum);
10063
10064static const struct snd_kcontrol_new rx_int7_mix2_inp_mux =
10065 SOC_DAPM_ENUM("RX INT7 MIX2 INP Mux", rx_int7_sidetone_mix_chain_enum);
10066
10067static const struct snd_kcontrol_new tx_adc_mux0 =
10068 SOC_DAPM_ENUM_EXT("ADC MUX0 Mux", tx_adc_mux0_chain_enum,
10069 snd_soc_dapm_get_enum_double,
10070 tasha_put_dec_enum);
10071
10072static const struct snd_kcontrol_new tx_adc_mux1 =
10073 SOC_DAPM_ENUM_EXT("ADC MUX1 Mux", tx_adc_mux1_chain_enum,
10074 snd_soc_dapm_get_enum_double,
10075 tasha_put_dec_enum);
10076
10077static const struct snd_kcontrol_new tx_adc_mux2 =
10078 SOC_DAPM_ENUM_EXT("ADC MUX2 Mux", tx_adc_mux2_chain_enum,
10079 snd_soc_dapm_get_enum_double,
10080 tasha_put_dec_enum);
10081
10082static const struct snd_kcontrol_new tx_adc_mux3 =
10083 SOC_DAPM_ENUM_EXT("ADC MUX3 Mux", tx_adc_mux3_chain_enum,
10084 snd_soc_dapm_get_enum_double,
10085 tasha_put_dec_enum);
10086
10087static const struct snd_kcontrol_new tx_adc_mux4 =
10088 SOC_DAPM_ENUM_EXT("ADC MUX4 Mux", tx_adc_mux4_chain_enum,
10089 snd_soc_dapm_get_enum_double,
10090 tasha_put_dec_enum);
10091
10092static const struct snd_kcontrol_new tx_adc_mux5 =
10093 SOC_DAPM_ENUM_EXT("ADC MUX5 Mux", tx_adc_mux5_chain_enum,
10094 snd_soc_dapm_get_enum_double,
10095 tasha_put_dec_enum);
10096
10097static const struct snd_kcontrol_new tx_adc_mux6 =
10098 SOC_DAPM_ENUM_EXT("ADC MUX6 Mux", tx_adc_mux6_chain_enum,
10099 snd_soc_dapm_get_enum_double,
10100 tasha_put_dec_enum);
10101
10102static const struct snd_kcontrol_new tx_adc_mux7 =
10103 SOC_DAPM_ENUM_EXT("ADC MUX7 Mux", tx_adc_mux7_chain_enum,
10104 snd_soc_dapm_get_enum_double,
10105 tasha_put_dec_enum);
10106
10107static const struct snd_kcontrol_new tx_adc_mux8 =
10108 SOC_DAPM_ENUM_EXT("ADC MUX8 Mux", tx_adc_mux8_chain_enum,
10109 snd_soc_dapm_get_enum_double,
10110 tasha_put_dec_enum);
10111
10112static const struct snd_kcontrol_new tx_adc_mux10 =
10113 SOC_DAPM_ENUM("ADC MUX10 Mux", tx_adc_mux10_chain_enum);
10114
10115static const struct snd_kcontrol_new tx_adc_mux11 =
10116 SOC_DAPM_ENUM("ADC MUX11 Mux", tx_adc_mux11_chain_enum);
10117
10118static const struct snd_kcontrol_new tx_adc_mux12 =
10119 SOC_DAPM_ENUM("ADC MUX12 Mux", tx_adc_mux12_chain_enum);
10120
10121static const struct snd_kcontrol_new tx_adc_mux13 =
10122 SOC_DAPM_ENUM("ADC MUX13 Mux", tx_adc_mux13_chain_enum);
10123
10124static const struct snd_kcontrol_new tx_dmic_mux0 =
10125 SOC_DAPM_ENUM("DMIC MUX0 Mux", tx_dmic_mux0_enum);
10126
10127static const struct snd_kcontrol_new tx_dmic_mux1 =
10128 SOC_DAPM_ENUM("DMIC MUX1 Mux", tx_dmic_mux1_enum);
10129
10130static const struct snd_kcontrol_new tx_dmic_mux2 =
10131 SOC_DAPM_ENUM("DMIC MUX2 Mux", tx_dmic_mux2_enum);
10132
10133static const struct snd_kcontrol_new tx_dmic_mux3 =
10134 SOC_DAPM_ENUM("DMIC MUX3 Mux", tx_dmic_mux3_enum);
10135
10136static const struct snd_kcontrol_new tx_dmic_mux4 =
10137 SOC_DAPM_ENUM("DMIC MUX4 Mux", tx_dmic_mux4_enum);
10138
10139static const struct snd_kcontrol_new tx_dmic_mux5 =
10140 SOC_DAPM_ENUM("DMIC MUX5 Mux", tx_dmic_mux5_enum);
10141
10142static const struct snd_kcontrol_new tx_dmic_mux6 =
10143 SOC_DAPM_ENUM("DMIC MUX6 Mux", tx_dmic_mux6_enum);
10144
10145static const struct snd_kcontrol_new tx_dmic_mux7 =
10146 SOC_DAPM_ENUM("DMIC MUX7 Mux", tx_dmic_mux7_enum);
10147
10148static const struct snd_kcontrol_new tx_dmic_mux8 =
10149 SOC_DAPM_ENUM("DMIC MUX8 Mux", tx_dmic_mux8_enum);
10150
10151static const struct snd_kcontrol_new tx_dmic_mux10 =
10152 SOC_DAPM_ENUM("DMIC MUX10 Mux", tx_dmic_mux10_enum);
10153
10154static const struct snd_kcontrol_new tx_dmic_mux11 =
10155 SOC_DAPM_ENUM("DMIC MUX11 Mux", tx_dmic_mux11_enum);
10156
10157static const struct snd_kcontrol_new tx_dmic_mux12 =
10158 SOC_DAPM_ENUM("DMIC MUX12 Mux", tx_dmic_mux12_enum);
10159
10160static const struct snd_kcontrol_new tx_dmic_mux13 =
10161 SOC_DAPM_ENUM("DMIC MUX13 Mux", tx_dmic_mux13_enum);
10162
10163static const struct snd_kcontrol_new tx_amic_mux0 =
10164 SOC_DAPM_ENUM("AMIC MUX0 Mux", tx_amic_mux0_enum);
10165
10166static const struct snd_kcontrol_new tx_amic_mux1 =
10167 SOC_DAPM_ENUM("AMIC MUX1 Mux", tx_amic_mux1_enum);
10168
10169static const struct snd_kcontrol_new tx_amic_mux2 =
10170 SOC_DAPM_ENUM("AMIC MUX2 Mux", tx_amic_mux2_enum);
10171
10172static const struct snd_kcontrol_new tx_amic_mux3 =
10173 SOC_DAPM_ENUM("AMIC MUX3 Mux", tx_amic_mux3_enum);
10174
10175static const struct snd_kcontrol_new tx_amic_mux4 =
10176 SOC_DAPM_ENUM("AMIC MUX4 Mux", tx_amic_mux4_enum);
10177
10178static const struct snd_kcontrol_new tx_amic_mux5 =
10179 SOC_DAPM_ENUM("AMIC MUX5 Mux", tx_amic_mux5_enum);
10180
10181static const struct snd_kcontrol_new tx_amic_mux6 =
10182 SOC_DAPM_ENUM("AMIC MUX6 Mux", tx_amic_mux6_enum);
10183
10184static const struct snd_kcontrol_new tx_amic_mux7 =
10185 SOC_DAPM_ENUM("AMIC MUX7 Mux", tx_amic_mux7_enum);
10186
10187static const struct snd_kcontrol_new tx_amic_mux8 =
10188 SOC_DAPM_ENUM("AMIC MUX8 Mux", tx_amic_mux8_enum);
10189
10190static const struct snd_kcontrol_new tx_amic_mux10 =
10191 SOC_DAPM_ENUM("AMIC MUX10 Mux", tx_amic_mux10_enum);
10192
10193static const struct snd_kcontrol_new tx_amic_mux11 =
10194 SOC_DAPM_ENUM("AMIC MUX11 Mux", tx_amic_mux11_enum);
10195
10196static const struct snd_kcontrol_new tx_amic_mux12 =
10197 SOC_DAPM_ENUM("AMIC MUX12 Mux", tx_amic_mux12_enum);
10198
10199static const struct snd_kcontrol_new tx_amic_mux13 =
10200 SOC_DAPM_ENUM("AMIC MUX13 Mux", tx_amic_mux13_enum);
10201
10202static const struct snd_kcontrol_new sb_tx0_mux =
10203 SOC_DAPM_ENUM("SLIM TX0 MUX Mux", sb_tx0_mux_enum);
10204
10205static const struct snd_kcontrol_new sb_tx1_mux =
10206 SOC_DAPM_ENUM("SLIM TX1 MUX Mux", sb_tx1_mux_enum);
10207
10208static const struct snd_kcontrol_new sb_tx2_mux =
10209 SOC_DAPM_ENUM("SLIM TX2 MUX Mux", sb_tx2_mux_enum);
10210
10211static const struct snd_kcontrol_new sb_tx3_mux =
10212 SOC_DAPM_ENUM("SLIM TX3 MUX Mux", sb_tx3_mux_enum);
10213
10214static const struct snd_kcontrol_new sb_tx4_mux =
10215 SOC_DAPM_ENUM("SLIM TX4 MUX Mux", sb_tx4_mux_enum);
10216
10217static const struct snd_kcontrol_new sb_tx5_mux =
10218 SOC_DAPM_ENUM("SLIM TX5 MUX Mux", sb_tx5_mux_enum);
10219
10220static const struct snd_kcontrol_new sb_tx6_mux =
10221 SOC_DAPM_ENUM("SLIM TX6 MUX Mux", sb_tx6_mux_enum);
10222
10223static const struct snd_kcontrol_new sb_tx7_mux =
10224 SOC_DAPM_ENUM("SLIM TX7 MUX Mux", sb_tx7_mux_enum);
10225
10226static const struct snd_kcontrol_new sb_tx8_mux =
10227 SOC_DAPM_ENUM("SLIM TX8 MUX Mux", sb_tx8_mux_enum);
10228
10229static const struct snd_kcontrol_new sb_tx9_mux =
10230 SOC_DAPM_ENUM("SLIM TX9 MUX Mux", sb_tx9_mux_enum);
10231
10232static const struct snd_kcontrol_new sb_tx10_mux =
10233 SOC_DAPM_ENUM("SLIM TX10 MUX Mux", sb_tx10_mux_enum);
10234
10235static const struct snd_kcontrol_new sb_tx11_mux =
10236 SOC_DAPM_ENUM("SLIM TX11 MUX Mux", sb_tx11_mux_enum);
10237
10238static const struct snd_kcontrol_new sb_tx11_inp1_mux =
10239 SOC_DAPM_ENUM("SLIM TX11 INP1 MUX Mux", sb_tx11_inp1_mux_enum);
10240
10241static const struct snd_kcontrol_new sb_tx13_mux =
10242 SOC_DAPM_ENUM("SLIM TX13 MUX Mux", sb_tx13_mux_enum);
10243
10244static const struct snd_kcontrol_new tx13_inp_mux =
10245 SOC_DAPM_ENUM("TX13 INP MUX Mux", tx13_inp_mux_enum);
10246
10247static const struct snd_kcontrol_new rx_mix_tx0_mux =
10248 SOC_DAPM_ENUM("RX MIX TX0 MUX Mux", rx_mix_tx0_mux_enum);
10249
10250static const struct snd_kcontrol_new rx_mix_tx1_mux =
10251 SOC_DAPM_ENUM("RX MIX TX1 MUX Mux", rx_mix_tx1_mux_enum);
10252
10253static const struct snd_kcontrol_new rx_mix_tx2_mux =
10254 SOC_DAPM_ENUM("RX MIX TX2 MUX Mux", rx_mix_tx2_mux_enum);
10255
10256static const struct snd_kcontrol_new rx_mix_tx3_mux =
10257 SOC_DAPM_ENUM("RX MIX TX3 MUX Mux", rx_mix_tx3_mux_enum);
10258
10259static const struct snd_kcontrol_new rx_mix_tx4_mux =
10260 SOC_DAPM_ENUM("RX MIX TX4 MUX Mux", rx_mix_tx4_mux_enum);
10261
10262static const struct snd_kcontrol_new rx_mix_tx5_mux =
10263 SOC_DAPM_ENUM("RX MIX TX5 MUX Mux", rx_mix_tx5_mux_enum);
10264
10265static const struct snd_kcontrol_new rx_mix_tx6_mux =
10266 SOC_DAPM_ENUM("RX MIX TX6 MUX Mux", rx_mix_tx6_mux_enum);
10267
10268static const struct snd_kcontrol_new rx_mix_tx7_mux =
10269 SOC_DAPM_ENUM("RX MIX TX7 MUX Mux", rx_mix_tx7_mux_enum);
10270
10271static const struct snd_kcontrol_new rx_mix_tx8_mux =
10272 SOC_DAPM_ENUM("RX MIX TX8 MUX Mux", rx_mix_tx8_mux_enum);
10273
10274static const struct snd_kcontrol_new iir0_inp0_mux =
10275 SOC_DAPM_ENUM("IIR0 INP0 Mux", iir0_inp0_mux_enum);
10276
10277static const struct snd_kcontrol_new iir0_inp1_mux =
10278 SOC_DAPM_ENUM("IIR0 INP1 Mux", iir0_inp1_mux_enum);
10279
10280static const struct snd_kcontrol_new iir0_inp2_mux =
10281 SOC_DAPM_ENUM("IIR0 INP2 Mux", iir0_inp2_mux_enum);
10282
10283static const struct snd_kcontrol_new iir0_inp3_mux =
10284 SOC_DAPM_ENUM("IIR0 INP3 Mux", iir0_inp3_mux_enum);
10285
10286static const struct snd_kcontrol_new iir1_inp0_mux =
10287 SOC_DAPM_ENUM("IIR1 INP0 Mux", iir1_inp0_mux_enum);
10288
10289static const struct snd_kcontrol_new iir1_inp1_mux =
10290 SOC_DAPM_ENUM("IIR1 INP1 Mux", iir1_inp1_mux_enum);
10291
10292static const struct snd_kcontrol_new iir1_inp2_mux =
10293 SOC_DAPM_ENUM("IIR1 INP2 Mux", iir1_inp2_mux_enum);
10294
10295static const struct snd_kcontrol_new iir1_inp3_mux =
10296 SOC_DAPM_ENUM("IIR1 INP3 Mux", iir1_inp3_mux_enum);
10297
10298static const struct snd_kcontrol_new rx_int0_interp_mux =
10299 SOC_DAPM_ENUM("RX INT0 INTERP Mux", rx_int0_interp_mux_enum);
10300
10301static const struct snd_kcontrol_new rx_int1_interp_mux =
10302 SOC_DAPM_ENUM("RX INT1 INTERP Mux", rx_int1_interp_mux_enum);
10303
10304static const struct snd_kcontrol_new rx_int2_interp_mux =
10305 SOC_DAPM_ENUM("RX INT2 INTERP Mux", rx_int2_interp_mux_enum);
10306
10307static const struct snd_kcontrol_new rx_int3_interp_mux =
10308 SOC_DAPM_ENUM("RX INT3 INTERP Mux", rx_int3_interp_mux_enum);
10309
10310static const struct snd_kcontrol_new rx_int4_interp_mux =
10311 SOC_DAPM_ENUM("RX INT4 INTERP Mux", rx_int4_interp_mux_enum);
10312
10313static const struct snd_kcontrol_new rx_int5_interp_mux =
10314 SOC_DAPM_ENUM("RX INT5 INTERP Mux", rx_int5_interp_mux_enum);
10315
10316static const struct snd_kcontrol_new rx_int6_interp_mux =
10317 SOC_DAPM_ENUM("RX INT6 INTERP Mux", rx_int6_interp_mux_enum);
10318
10319static const struct snd_kcontrol_new rx_int7_interp_mux =
10320 SOC_DAPM_ENUM("RX INT7 INTERP Mux", rx_int7_interp_mux_enum);
10321
10322static const struct snd_kcontrol_new rx_int8_interp_mux =
10323 SOC_DAPM_ENUM("RX INT8 INTERP Mux", rx_int8_interp_mux_enum);
10324
10325static const struct snd_kcontrol_new mad_sel_mux =
10326 SOC_DAPM_ENUM("MAD_SEL MUX Mux", mad_sel_enum);
10327
10328static const struct snd_kcontrol_new aif4_mad_switch =
10329 SOC_DAPM_SINGLE("Switch", WCD9335_CPE_SS_CFG, 5, 1, 0);
10330
10331static const struct snd_kcontrol_new mad_brdcst_switch =
10332 SOC_DAPM_SINGLE("Switch", WCD9335_CPE_SS_CFG, 6, 1, 0);
10333
10334static const struct snd_kcontrol_new aif4_switch_mixer_controls =
10335 SOC_SINGLE_EXT("Switch", SND_SOC_NOPM,
10336 0, 1, 0, tasha_codec_aif4_mixer_switch_get,
10337 tasha_codec_aif4_mixer_switch_put);
10338
10339static const struct snd_kcontrol_new anc_hphl_switch =
10340 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
10341
10342static const struct snd_kcontrol_new anc_hphr_switch =
10343 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
10344
10345static const struct snd_kcontrol_new anc_ear_switch =
10346 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
10347
10348static const struct snd_kcontrol_new anc_ear_spkr_switch =
10349 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
10350
10351static const struct snd_kcontrol_new anc_lineout1_switch =
10352 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
10353
10354static const struct snd_kcontrol_new anc_lineout2_switch =
10355 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
10356
10357static const struct snd_kcontrol_new anc_spkr_pa_switch =
10358 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
10359
10360static const struct snd_kcontrol_new adc_us_mux0_switch =
10361 SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
10362
10363static const struct snd_kcontrol_new adc_us_mux1_switch =
10364 SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
10365
10366static const struct snd_kcontrol_new adc_us_mux2_switch =
10367 SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
10368
10369static const struct snd_kcontrol_new adc_us_mux3_switch =
10370 SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
10371
10372static const struct snd_kcontrol_new adc_us_mux4_switch =
10373 SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
10374
10375static const struct snd_kcontrol_new adc_us_mux5_switch =
10376 SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
10377
10378static const struct snd_kcontrol_new adc_us_mux6_switch =
10379 SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
10380
10381static const struct snd_kcontrol_new adc_us_mux7_switch =
10382 SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
10383
10384static const struct snd_kcontrol_new adc_us_mux8_switch =
10385 SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
10386
10387static const struct snd_kcontrol_new anc0_fb_mux =
10388 SOC_DAPM_ENUM("ANC0 FB MUX Mux", anc0_fb_mux_enum);
10389
10390static const struct snd_kcontrol_new anc1_fb_mux =
10391 SOC_DAPM_ENUM("ANC1 FB MUX Mux", anc1_fb_mux_enum);
10392
10393static int tasha_codec_ec_buf_mux_enable(struct snd_soc_dapm_widget *w,
10394 struct snd_kcontrol *kcontrol,
10395 int event)
10396{
10397 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
10398
10399 dev_dbg(codec->dev, "%s: event = %d name = %s\n",
10400 __func__, event, w->name);
10401
10402 switch (event) {
10403 case SND_SOC_DAPM_POST_PMU:
10404 snd_soc_write(codec, WCD9335_CPE_SS_EC_BUF_INT_PERIOD, 0x3B);
10405 snd_soc_update_bits(codec, WCD9335_CPE_SS_CFG, 0x08, 0x08);
10406 snd_soc_update_bits(codec, WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0,
10407 0x08, 0x08);
10408 break;
10409 case SND_SOC_DAPM_POST_PMD:
10410 snd_soc_update_bits(codec, WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0,
10411 0x08, 0x00);
10412 snd_soc_update_bits(codec, WCD9335_CPE_SS_CFG, 0x08, 0x00);
10413 snd_soc_write(codec, WCD9335_CPE_SS_EC_BUF_INT_PERIOD, 0x00);
10414 break;
10415 }
10416
10417 return 0;
10418};
10419
10420static const char * const ec_buf_mux_text[] = {
10421 "ZERO", "RXMIXEC", "SB_RX0", "SB_RX1", "SB_RX2", "SB_RX3",
10422 "I2S_RX_SD0_L", "I2S_RX_SD0_R", "I2S_RX_SD1_L", "I2S_RX_SD1_R",
10423 "DEC1"
10424};
10425
10426static SOC_ENUM_SINGLE_DECL(ec_buf_mux_enum, WCD9335_CPE_SS_US_EC_MUX_CFG,
10427 0, ec_buf_mux_text);
10428
10429static const struct snd_kcontrol_new ec_buf_mux =
10430 SOC_DAPM_ENUM("EC BUF Mux", ec_buf_mux_enum);
10431
10432static const struct snd_soc_dapm_widget tasha_dapm_widgets[] = {
10433 SND_SOC_DAPM_OUTPUT("EAR"),
10434 SND_SOC_DAPM_OUTPUT("ANC EAR"),
10435 SND_SOC_DAPM_AIF_IN_E("AIF1 PB", "AIF1 Playback", 0, SND_SOC_NOPM,
10436 AIF1_PB, 0, tasha_codec_enable_slimrx,
10437 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD |
10438 SND_SOC_DAPM_POST_PMD),
10439 SND_SOC_DAPM_AIF_IN_E("AIF2 PB", "AIF2 Playback", 0, SND_SOC_NOPM,
10440 AIF2_PB, 0, tasha_codec_enable_slimrx,
10441 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD |
10442 SND_SOC_DAPM_POST_PMD),
10443 SND_SOC_DAPM_AIF_IN_E("AIF3 PB", "AIF3 Playback", 0, SND_SOC_NOPM,
10444 AIF3_PB, 0, tasha_codec_enable_slimrx,
10445 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD |
10446 SND_SOC_DAPM_POST_PMD),
10447 SND_SOC_DAPM_AIF_IN_E("AIF4 PB", "AIF4 Playback", 0, SND_SOC_NOPM,
10448 AIF4_PB, 0, tasha_codec_enable_slimrx,
10449 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD |
10450 SND_SOC_DAPM_POST_PMD),
10451 SND_SOC_DAPM_AIF_IN_E("AIF MIX1 PB", "AIF Mix Playback", 0,
10452 SND_SOC_NOPM, AIF_MIX1_PB, 0,
10453 tasha_codec_enable_slimrx,
10454 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD |
10455 SND_SOC_DAPM_POST_PMD),
10456
10457 SND_SOC_DAPM_MUX("SLIM RX0 MUX", SND_SOC_NOPM, TASHA_RX0, 0,
10458 &slim_rx_mux[TASHA_RX0]),
10459 SND_SOC_DAPM_MUX("SLIM RX1 MUX", SND_SOC_NOPM, TASHA_RX1, 0,
10460 &slim_rx_mux[TASHA_RX1]),
10461 SND_SOC_DAPM_MUX("SLIM RX2 MUX", SND_SOC_NOPM, TASHA_RX2, 0,
10462 &slim_rx_mux[TASHA_RX2]),
10463 SND_SOC_DAPM_MUX("SLIM RX3 MUX", SND_SOC_NOPM, TASHA_RX3, 0,
10464 &slim_rx_mux[TASHA_RX3]),
10465 SND_SOC_DAPM_MUX("SLIM RX4 MUX", SND_SOC_NOPM, TASHA_RX4, 0,
10466 &slim_rx_mux[TASHA_RX4]),
10467 SND_SOC_DAPM_MUX("SLIM RX5 MUX", SND_SOC_NOPM, TASHA_RX5, 0,
10468 &slim_rx_mux[TASHA_RX5]),
10469 SND_SOC_DAPM_MUX("SLIM RX6 MUX", SND_SOC_NOPM, TASHA_RX6, 0,
10470 &slim_rx_mux[TASHA_RX6]),
10471 SND_SOC_DAPM_MUX("SLIM RX7 MUX", SND_SOC_NOPM, TASHA_RX7, 0,
10472 &slim_rx_mux[TASHA_RX7]),
10473
10474 SND_SOC_DAPM_MIXER("SLIM RX0", SND_SOC_NOPM, 0, 0, NULL, 0),
10475 SND_SOC_DAPM_MIXER("SLIM RX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10476 SND_SOC_DAPM_MIXER("SLIM RX2", SND_SOC_NOPM, 0, 0, NULL, 0),
10477 SND_SOC_DAPM_MIXER("SLIM RX3", SND_SOC_NOPM, 0, 0, NULL, 0),
10478 SND_SOC_DAPM_MIXER("SLIM RX4", SND_SOC_NOPM, 0, 0, NULL, 0),
10479 SND_SOC_DAPM_MIXER("SLIM RX5", SND_SOC_NOPM, 0, 0, NULL, 0),
10480 SND_SOC_DAPM_MIXER("SLIM RX6", SND_SOC_NOPM, 0, 0, NULL, 0),
10481 SND_SOC_DAPM_MIXER("SLIM RX7", SND_SOC_NOPM, 0, 0, NULL, 0),
10482
10483 SND_SOC_DAPM_MUX_E("SPL SRC0 MUX", SND_SOC_NOPM, SPLINE_SRC0, 0,
10484 &spl_src0_mux, tasha_codec_enable_spline_resampler,
10485 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10486 SND_SOC_DAPM_MUX_E("SPL SRC1 MUX", SND_SOC_NOPM, SPLINE_SRC1, 0,
10487 &spl_src1_mux, tasha_codec_enable_spline_resampler,
10488 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10489 SND_SOC_DAPM_MUX_E("SPL SRC2 MUX", SND_SOC_NOPM, SPLINE_SRC2, 0,
10490 &spl_src2_mux, tasha_codec_enable_spline_resampler,
10491 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10492 SND_SOC_DAPM_MUX_E("SPL SRC3 MUX", SND_SOC_NOPM, SPLINE_SRC3, 0,
10493 &spl_src3_mux, tasha_codec_enable_spline_resampler,
10494 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10495
10496 SND_SOC_DAPM_MUX_E("RX INT0_2 MUX", WCD9335_CDC_RX0_RX_PATH_MIX_CTL,
10497 5, 0, &rx_int0_2_mux, tasha_codec_enable_mix_path,
10498 SND_SOC_DAPM_POST_PMU),
10499 SND_SOC_DAPM_MUX_E("RX INT1_2 MUX", WCD9335_CDC_RX1_RX_PATH_MIX_CTL,
10500 5, 0, &rx_int1_2_mux, tasha_codec_enable_mix_path,
10501 SND_SOC_DAPM_POST_PMU),
10502 SND_SOC_DAPM_MUX_E("RX INT2_2 MUX", WCD9335_CDC_RX2_RX_PATH_MIX_CTL,
10503 5, 0, &rx_int2_2_mux, tasha_codec_enable_mix_path,
10504 SND_SOC_DAPM_POST_PMU),
10505 SND_SOC_DAPM_MUX_E("RX INT3_2 MUX", WCD9335_CDC_RX3_RX_PATH_MIX_CTL,
10506 5, 0, &rx_int3_2_mux, tasha_codec_enable_mix_path,
10507 SND_SOC_DAPM_POST_PMU),
10508 SND_SOC_DAPM_MUX_E("RX INT4_2 MUX", WCD9335_CDC_RX4_RX_PATH_MIX_CTL,
10509 5, 0, &rx_int4_2_mux, tasha_codec_enable_mix_path,
10510 SND_SOC_DAPM_POST_PMU),
10511 SND_SOC_DAPM_MUX_E("RX INT5_2 MUX", WCD9335_CDC_RX5_RX_PATH_MIX_CTL,
10512 5, 0, &rx_int5_2_mux, tasha_codec_enable_mix_path,
10513 SND_SOC_DAPM_POST_PMU),
10514 SND_SOC_DAPM_MUX_E("RX INT6_2 MUX", WCD9335_CDC_RX6_RX_PATH_MIX_CTL,
10515 5, 0, &rx_int6_2_mux, tasha_codec_enable_mix_path,
10516 SND_SOC_DAPM_POST_PMU),
10517 SND_SOC_DAPM_MUX_E("RX INT7_2 MUX", WCD9335_CDC_RX7_RX_PATH_MIX_CTL,
10518 5, 0, &rx_int7_2_mux, tasha_codec_enable_mix_path,
10519 SND_SOC_DAPM_POST_PMU),
10520 SND_SOC_DAPM_MUX_E("RX INT8_2 MUX", WCD9335_CDC_RX8_RX_PATH_MIX_CTL,
10521 5, 0, &rx_int8_2_mux, tasha_codec_enable_mix_path,
10522 SND_SOC_DAPM_POST_PMU),
10523
10524 SND_SOC_DAPM_MUX("RX INT0_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
10525 &rx_int0_1_mix_inp0_mux),
10526 SND_SOC_DAPM_MUX("RX INT0_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
10527 &rx_int0_1_mix_inp1_mux),
10528 SND_SOC_DAPM_MUX("RX INT0_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
10529 &rx_int0_1_mix_inp2_mux),
10530 SND_SOC_DAPM_MUX("RX INT1_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
10531 &rx_int1_1_mix_inp0_mux),
10532 SND_SOC_DAPM_MUX("RX INT1_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
10533 &rx_int1_1_mix_inp1_mux),
10534 SND_SOC_DAPM_MUX("RX INT1_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
10535 &rx_int1_1_mix_inp2_mux),
10536 SND_SOC_DAPM_MUX("RX INT2_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
10537 &rx_int2_1_mix_inp0_mux),
10538 SND_SOC_DAPM_MUX("RX INT2_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
10539 &rx_int2_1_mix_inp1_mux),
10540 SND_SOC_DAPM_MUX("RX INT2_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
10541 &rx_int2_1_mix_inp2_mux),
10542 SND_SOC_DAPM_MUX("RX INT3_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
10543 &rx_int3_1_mix_inp0_mux),
10544 SND_SOC_DAPM_MUX("RX INT3_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
10545 &rx_int3_1_mix_inp1_mux),
10546 SND_SOC_DAPM_MUX("RX INT3_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
10547 &rx_int3_1_mix_inp2_mux),
10548 SND_SOC_DAPM_MUX("RX INT4_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
10549 &rx_int4_1_mix_inp0_mux),
10550 SND_SOC_DAPM_MUX("RX INT4_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
10551 &rx_int4_1_mix_inp1_mux),
10552 SND_SOC_DAPM_MUX("RX INT4_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
10553 &rx_int4_1_mix_inp2_mux),
10554 SND_SOC_DAPM_MUX("RX INT5_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
10555 &rx_int5_1_mix_inp0_mux),
10556 SND_SOC_DAPM_MUX("RX INT5_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
10557 &rx_int5_1_mix_inp1_mux),
10558 SND_SOC_DAPM_MUX("RX INT5_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
10559 &rx_int5_1_mix_inp2_mux),
10560 SND_SOC_DAPM_MUX("RX INT6_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
10561 &rx_int6_1_mix_inp0_mux),
10562 SND_SOC_DAPM_MUX("RX INT6_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
10563 &rx_int6_1_mix_inp1_mux),
10564 SND_SOC_DAPM_MUX("RX INT6_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
10565 &rx_int6_1_mix_inp2_mux),
10566 SND_SOC_DAPM_MUX_E("RX INT7_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
10567 &rx_int7_1_mix_inp0_mux, tasha_codec_enable_swr,
10568 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10569 SND_SOC_DAPM_MUX_E("RX INT7_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
10570 &rx_int7_1_mix_inp1_mux, tasha_codec_enable_swr,
10571 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10572 SND_SOC_DAPM_MUX_E("RX INT7_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
10573 &rx_int7_1_mix_inp2_mux, tasha_codec_enable_swr,
10574 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10575 SND_SOC_DAPM_MUX_E("RX INT8_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
10576 &rx_int8_1_mix_inp0_mux, tasha_codec_enable_swr,
10577 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10578 SND_SOC_DAPM_MUX_E("RX INT8_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
10579 &rx_int8_1_mix_inp1_mux, tasha_codec_enable_swr,
10580 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10581 SND_SOC_DAPM_MUX_E("RX INT8_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
10582 &rx_int8_1_mix_inp2_mux, tasha_codec_enable_swr,
10583 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10584
10585 SND_SOC_DAPM_MIXER("RX INT0_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10586 SND_SOC_DAPM_MIXER("RX INT0 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
10587 SND_SOC_DAPM_MIXER("RX INT1_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10588 SND_SOC_DAPM_MIXER("RX INT1 SPLINE MIX", SND_SOC_NOPM, 0, 0,
10589 rx_int1_spline_mix_switch,
10590 ARRAY_SIZE(rx_int1_spline_mix_switch)),
10591 SND_SOC_DAPM_MIXER("RX INT1 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
10592 SND_SOC_DAPM_MIXER("RX INT2_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10593 SND_SOC_DAPM_MIXER("RX INT2 SPLINE MIX", SND_SOC_NOPM, 0, 0,
10594 rx_int2_spline_mix_switch,
10595 ARRAY_SIZE(rx_int2_spline_mix_switch)),
10596 SND_SOC_DAPM_MIXER("RX INT2 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
10597 SND_SOC_DAPM_MIXER("RX INT3_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10598 SND_SOC_DAPM_MIXER("RX INT3 SPLINE MIX", SND_SOC_NOPM, 0, 0,
10599 rx_int3_spline_mix_switch,
10600 ARRAY_SIZE(rx_int3_spline_mix_switch)),
10601 SND_SOC_DAPM_MIXER("RX INT3 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
10602 SND_SOC_DAPM_MIXER("RX INT4_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10603 SND_SOC_DAPM_MIXER("RX INT4 SPLINE MIX", SND_SOC_NOPM, 0, 0,
10604 rx_int4_spline_mix_switch,
10605 ARRAY_SIZE(rx_int4_spline_mix_switch)),
10606 SND_SOC_DAPM_MIXER("RX INT4 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
10607 SND_SOC_DAPM_MIXER("RX INT5_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10608 SND_SOC_DAPM_MIXER("RX INT5 SPLINE MIX", SND_SOC_NOPM, 0, 0,
10609 rx_int5_spline_mix_switch,
10610 ARRAY_SIZE(rx_int5_spline_mix_switch)),
10611 SND_SOC_DAPM_MIXER("RX INT5 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
10612
10613 SND_SOC_DAPM_MIXER("RX INT6_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10614 SND_SOC_DAPM_MIXER("RX INT6 SPLINE MIX", SND_SOC_NOPM, 0, 0,
10615 rx_int6_spline_mix_switch,
10616 ARRAY_SIZE(rx_int6_spline_mix_switch)),
10617 SND_SOC_DAPM_MIXER("RX INT6 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
10618
10619 SND_SOC_DAPM_MIXER("RX INT7_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10620 SND_SOC_DAPM_MIXER("RX INT7 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
10621 SND_SOC_DAPM_MIXER("RX INT7 SPLINE MIX", SND_SOC_NOPM, 0, 0,
10622 rx_int7_spline_mix_switch,
10623 ARRAY_SIZE(rx_int7_spline_mix_switch)),
10624
10625 SND_SOC_DAPM_MIXER("RX INT8_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10626 SND_SOC_DAPM_MIXER("RX INT8 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
10627 SND_SOC_DAPM_MIXER("RX INT8 SPLINE MIX", SND_SOC_NOPM, 0, 0,
10628 rx_int8_spline_mix_switch,
10629 ARRAY_SIZE(rx_int8_spline_mix_switch)),
10630
10631 SND_SOC_DAPM_MIXER("RX INT0 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
10632 SND_SOC_DAPM_MIXER("RX INT1 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
10633 SND_SOC_DAPM_MIXER("RX INT2 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
10634 SND_SOC_DAPM_MIXER("RX INT3 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
10635 SND_SOC_DAPM_MIXER("RX INT4 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
10636 SND_SOC_DAPM_MIXER("RX INT5 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
10637 SND_SOC_DAPM_MIXER("RX INT6 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
10638 SND_SOC_DAPM_MIXER("RX INT7 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
10639 SND_SOC_DAPM_MIXER_E("RX INT7 CHAIN", SND_SOC_NOPM, 0, 0,
10640 NULL, 0, tasha_codec_spk_boost_event,
10641 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10642 SND_SOC_DAPM_MIXER_E("RX INT8 CHAIN", SND_SOC_NOPM, 0, 0,
10643 NULL, 0, tasha_codec_spk_boost_event,
10644 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10645
10646 SND_SOC_DAPM_MIXER_E("RX INT5 VBAT", SND_SOC_NOPM, 0, 0,
10647 rx_int5_vbat_mix_switch,
10648 ARRAY_SIZE(rx_int5_vbat_mix_switch),
10649 tasha_codec_vbat_enable_event,
10650 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10651 SND_SOC_DAPM_MIXER_E("RX INT6 VBAT", SND_SOC_NOPM, 0, 0,
10652 rx_int6_vbat_mix_switch,
10653 ARRAY_SIZE(rx_int6_vbat_mix_switch),
10654 tasha_codec_vbat_enable_event,
10655 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10656 SND_SOC_DAPM_MIXER_E("RX INT7 VBAT", SND_SOC_NOPM, 0, 0,
10657 rx_int7_vbat_mix_switch,
10658 ARRAY_SIZE(rx_int7_vbat_mix_switch),
10659 tasha_codec_vbat_enable_event,
10660 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10661 SND_SOC_DAPM_MIXER_E("RX INT8 VBAT", SND_SOC_NOPM, 0, 0,
10662 rx_int8_vbat_mix_switch,
10663 ARRAY_SIZE(rx_int8_vbat_mix_switch),
10664 tasha_codec_vbat_enable_event,
10665 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10666
10667 SND_SOC_DAPM_MUX("RX INT0 MIX2 INP", WCD9335_CDC_RX0_RX_PATH_CFG1, 4,
10668 0, &rx_int0_mix2_inp_mux),
10669 SND_SOC_DAPM_MUX("RX INT1 MIX2 INP", WCD9335_CDC_RX1_RX_PATH_CFG1, 4,
10670 0, &rx_int1_mix2_inp_mux),
10671 SND_SOC_DAPM_MUX("RX INT2 MIX2 INP", WCD9335_CDC_RX2_RX_PATH_CFG1, 4,
10672 0, &rx_int2_mix2_inp_mux),
10673 SND_SOC_DAPM_MUX("RX INT3 MIX2 INP", WCD9335_CDC_RX3_RX_PATH_CFG1, 4,
10674 0, &rx_int3_mix2_inp_mux),
10675 SND_SOC_DAPM_MUX("RX INT4 MIX2 INP", WCD9335_CDC_RX4_RX_PATH_CFG1, 4,
10676 0, &rx_int4_mix2_inp_mux),
10677 SND_SOC_DAPM_MUX("RX INT7 MIX2 INP", WCD9335_CDC_RX7_RX_PATH_CFG1, 4,
10678 0, &rx_int7_mix2_inp_mux),
10679
10680 SND_SOC_DAPM_MUX("SLIM TX0 MUX", SND_SOC_NOPM, TASHA_TX0, 0,
10681 &sb_tx0_mux),
10682 SND_SOC_DAPM_MUX("SLIM TX1 MUX", SND_SOC_NOPM, TASHA_TX1, 0,
10683 &sb_tx1_mux),
10684 SND_SOC_DAPM_MUX("SLIM TX2 MUX", SND_SOC_NOPM, TASHA_TX2, 0,
10685 &sb_tx2_mux),
10686 SND_SOC_DAPM_MUX("SLIM TX3 MUX", SND_SOC_NOPM, TASHA_TX3, 0,
10687 &sb_tx3_mux),
10688 SND_SOC_DAPM_MUX("SLIM TX4 MUX", SND_SOC_NOPM, TASHA_TX4, 0,
10689 &sb_tx4_mux),
10690 SND_SOC_DAPM_MUX("SLIM TX5 MUX", SND_SOC_NOPM, TASHA_TX5, 0,
10691 &sb_tx5_mux),
10692 SND_SOC_DAPM_MUX("SLIM TX6 MUX", SND_SOC_NOPM, TASHA_TX6, 0,
10693 &sb_tx6_mux),
10694 SND_SOC_DAPM_MUX("SLIM TX7 MUX", SND_SOC_NOPM, TASHA_TX7, 0,
10695 &sb_tx7_mux),
10696 SND_SOC_DAPM_MUX("SLIM TX8 MUX", SND_SOC_NOPM, TASHA_TX8, 0,
10697 &sb_tx8_mux),
10698 SND_SOC_DAPM_MUX("SLIM TX9 MUX", SND_SOC_NOPM, TASHA_TX9, 0,
10699 &sb_tx9_mux),
10700 SND_SOC_DAPM_MUX("SLIM TX10 MUX", SND_SOC_NOPM, TASHA_TX10, 0,
10701 &sb_tx10_mux),
10702 SND_SOC_DAPM_MUX("SLIM TX11 MUX", SND_SOC_NOPM, TASHA_TX11, 0,
10703 &sb_tx11_mux),
10704 SND_SOC_DAPM_MUX("SLIM TX11 INP1 MUX", SND_SOC_NOPM, TASHA_TX11, 0,
10705 &sb_tx11_inp1_mux),
10706 SND_SOC_DAPM_MUX("SLIM TX13 MUX", SND_SOC_NOPM, TASHA_TX13, 0,
10707 &sb_tx13_mux),
10708 SND_SOC_DAPM_MUX("TX13 INP MUX", SND_SOC_NOPM, 0, 0,
10709 &tx13_inp_mux),
10710
10711 SND_SOC_DAPM_MUX_E("ADC MUX0", WCD9335_CDC_TX0_TX_PATH_CTL, 5, 0,
10712 &tx_adc_mux0, tasha_codec_enable_dec,
10713 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10714 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
10715
10716 SND_SOC_DAPM_MUX_E("ADC MUX1", WCD9335_CDC_TX1_TX_PATH_CTL, 5, 0,
10717 &tx_adc_mux1, tasha_codec_enable_dec,
10718 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10719 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
10720
10721 SND_SOC_DAPM_MUX_E("ADC MUX2", WCD9335_CDC_TX2_TX_PATH_CTL, 5, 0,
10722 &tx_adc_mux2, tasha_codec_enable_dec,
10723 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10724 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
10725
10726 SND_SOC_DAPM_MUX_E("ADC MUX3", WCD9335_CDC_TX3_TX_PATH_CTL, 5, 0,
10727 &tx_adc_mux3, tasha_codec_enable_dec,
10728 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10729 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
10730
10731 SND_SOC_DAPM_MUX_E("ADC MUX4", WCD9335_CDC_TX4_TX_PATH_CTL, 5, 0,
10732 &tx_adc_mux4, tasha_codec_enable_dec,
10733 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10734 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
10735
10736 SND_SOC_DAPM_MUX_E("ADC MUX5", WCD9335_CDC_TX5_TX_PATH_CTL, 5, 0,
10737 &tx_adc_mux5, tasha_codec_enable_dec,
10738 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10739 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
10740
10741 SND_SOC_DAPM_MUX_E("ADC MUX6", WCD9335_CDC_TX6_TX_PATH_CTL, 5, 0,
10742 &tx_adc_mux6, tasha_codec_enable_dec,
10743 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10744 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
10745
10746 SND_SOC_DAPM_MUX_E("ADC MUX7", WCD9335_CDC_TX7_TX_PATH_CTL, 5, 0,
10747 &tx_adc_mux7, tasha_codec_enable_dec,
10748 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10749 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
10750
10751 SND_SOC_DAPM_MUX_E("ADC MUX8", WCD9335_CDC_TX8_TX_PATH_CTL, 5, 0,
10752 &tx_adc_mux8, tasha_codec_enable_dec,
10753 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10754 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
10755
10756 SND_SOC_DAPM_MUX_E("ADC MUX10", SND_SOC_NOPM, 10, 0,
10757 &tx_adc_mux10, tasha_codec_tx_adc_cfg,
10758 SND_SOC_DAPM_POST_PMU),
10759
10760 SND_SOC_DAPM_MUX_E("ADC MUX11", SND_SOC_NOPM, 11, 0,
10761 &tx_adc_mux11, tasha_codec_tx_adc_cfg,
10762 SND_SOC_DAPM_POST_PMU),
10763
10764 SND_SOC_DAPM_MUX_E("ADC MUX12", SND_SOC_NOPM, 12, 0,
10765 &tx_adc_mux12, tasha_codec_tx_adc_cfg,
10766 SND_SOC_DAPM_POST_PMU),
10767
10768 SND_SOC_DAPM_MUX_E("ADC MUX13", SND_SOC_NOPM, 13, 0,
10769 &tx_adc_mux13, tasha_codec_tx_adc_cfg,
10770 SND_SOC_DAPM_POST_PMU),
10771
10772 SND_SOC_DAPM_MUX("DMIC MUX0", SND_SOC_NOPM, 0, 0,
10773 &tx_dmic_mux0),
10774 SND_SOC_DAPM_MUX("DMIC MUX1", SND_SOC_NOPM, 0, 0,
10775 &tx_dmic_mux1),
10776 SND_SOC_DAPM_MUX("DMIC MUX2", SND_SOC_NOPM, 0, 0,
10777 &tx_dmic_mux2),
10778 SND_SOC_DAPM_MUX("DMIC MUX3", SND_SOC_NOPM, 0, 0,
10779 &tx_dmic_mux3),
10780 SND_SOC_DAPM_MUX("DMIC MUX4", SND_SOC_NOPM, 0, 0,
10781 &tx_dmic_mux4),
10782 SND_SOC_DAPM_MUX("DMIC MUX5", SND_SOC_NOPM, 0, 0,
10783 &tx_dmic_mux5),
10784 SND_SOC_DAPM_MUX("DMIC MUX6", SND_SOC_NOPM, 0, 0,
10785 &tx_dmic_mux6),
10786 SND_SOC_DAPM_MUX("DMIC MUX7", SND_SOC_NOPM, 0, 0,
10787 &tx_dmic_mux7),
10788 SND_SOC_DAPM_MUX("DMIC MUX8", SND_SOC_NOPM, 0, 0,
10789 &tx_dmic_mux8),
10790 SND_SOC_DAPM_MUX("DMIC MUX10", SND_SOC_NOPM, 0, 0,
10791 &tx_dmic_mux10),
10792 SND_SOC_DAPM_MUX("DMIC MUX11", SND_SOC_NOPM, 0, 0,
10793 &tx_dmic_mux11),
10794 SND_SOC_DAPM_MUX("DMIC MUX12", SND_SOC_NOPM, 0, 0,
10795 &tx_dmic_mux12),
10796 SND_SOC_DAPM_MUX("DMIC MUX13", SND_SOC_NOPM, 0, 0,
10797 &tx_dmic_mux13),
10798
10799 SND_SOC_DAPM_MUX("AMIC MUX0", SND_SOC_NOPM, 0, 0,
10800 &tx_amic_mux0),
10801 SND_SOC_DAPM_MUX("AMIC MUX1", SND_SOC_NOPM, 0, 0,
10802 &tx_amic_mux1),
10803 SND_SOC_DAPM_MUX("AMIC MUX2", SND_SOC_NOPM, 0, 0,
10804 &tx_amic_mux2),
10805 SND_SOC_DAPM_MUX("AMIC MUX3", SND_SOC_NOPM, 0, 0,
10806 &tx_amic_mux3),
10807 SND_SOC_DAPM_MUX("AMIC MUX4", SND_SOC_NOPM, 0, 0,
10808 &tx_amic_mux4),
10809 SND_SOC_DAPM_MUX("AMIC MUX5", SND_SOC_NOPM, 0, 0,
10810 &tx_amic_mux5),
10811 SND_SOC_DAPM_MUX("AMIC MUX6", SND_SOC_NOPM, 0, 0,
10812 &tx_amic_mux6),
10813 SND_SOC_DAPM_MUX("AMIC MUX7", SND_SOC_NOPM, 0, 0,
10814 &tx_amic_mux7),
10815 SND_SOC_DAPM_MUX("AMIC MUX8", SND_SOC_NOPM, 0, 0,
10816 &tx_amic_mux8),
10817 SND_SOC_DAPM_MUX("AMIC MUX10", SND_SOC_NOPM, 0, 0,
10818 &tx_amic_mux10),
10819 SND_SOC_DAPM_MUX("AMIC MUX11", SND_SOC_NOPM, 0, 0,
10820 &tx_amic_mux11),
10821 SND_SOC_DAPM_MUX("AMIC MUX12", SND_SOC_NOPM, 0, 0,
10822 &tx_amic_mux12),
10823 SND_SOC_DAPM_MUX("AMIC MUX13", SND_SOC_NOPM, 0, 0,
10824 &tx_amic_mux13),
10825
10826 SND_SOC_DAPM_ADC_E("ADC1", NULL, WCD9335_ANA_AMIC1, 7, 0,
10827 tasha_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
10828 SND_SOC_DAPM_ADC_E("ADC2", NULL, WCD9335_ANA_AMIC2, 7, 0,
10829 tasha_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
10830 SND_SOC_DAPM_ADC_E("ADC3", NULL, WCD9335_ANA_AMIC3, 7, 0,
10831 tasha_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
10832 SND_SOC_DAPM_ADC_E("ADC4", NULL, WCD9335_ANA_AMIC4, 7, 0,
10833 tasha_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
10834 SND_SOC_DAPM_ADC_E("ADC5", NULL, WCD9335_ANA_AMIC5, 7, 0,
10835 tasha_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
10836 SND_SOC_DAPM_ADC_E("ADC6", NULL, WCD9335_ANA_AMIC6, 7, 0,
10837 tasha_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
10838
10839 SND_SOC_DAPM_SUPPLY("RX INT1 NATIVE SUPPLY", SND_SOC_NOPM,
10840 INTERP_HPHL, 0, tasha_enable_native_supply,
10841 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
10842
10843 SND_SOC_DAPM_SUPPLY("RX INT2 NATIVE SUPPLY", SND_SOC_NOPM,
10844 INTERP_HPHR, 0, tasha_enable_native_supply,
10845 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
10846
10847 SND_SOC_DAPM_SUPPLY("RX INT3 NATIVE SUPPLY", SND_SOC_NOPM,
10848 INTERP_LO1, 0, tasha_enable_native_supply,
10849 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
10850
10851 SND_SOC_DAPM_SUPPLY("RX INT4 NATIVE SUPPLY", SND_SOC_NOPM,
10852 INTERP_LO2, 0, tasha_enable_native_supply,
10853 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
10854
10855 SND_SOC_DAPM_INPUT("AMIC1"),
10856 SND_SOC_DAPM_MICBIAS_E("MIC BIAS1", SND_SOC_NOPM, 0, 0,
10857 tasha_codec_enable_micbias,
10858 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10859 SND_SOC_DAPM_POST_PMD),
10860 SND_SOC_DAPM_MICBIAS_E("MIC BIAS2", SND_SOC_NOPM, 0, 0,
10861 tasha_codec_enable_micbias,
10862 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10863 SND_SOC_DAPM_POST_PMD),
10864 SND_SOC_DAPM_MICBIAS_E("MIC BIAS3", SND_SOC_NOPM, 0, 0,
10865 tasha_codec_enable_micbias,
10866 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10867 SND_SOC_DAPM_POST_PMD),
10868 SND_SOC_DAPM_MICBIAS_E("MIC BIAS4", SND_SOC_NOPM, 0, 0,
10869 tasha_codec_enable_micbias,
10870 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10871 SND_SOC_DAPM_POST_PMD),
10872
10873 SND_SOC_DAPM_MICBIAS_E(DAPM_MICBIAS1_STANDALONE, SND_SOC_NOPM, 0, 0,
10874 tasha_codec_force_enable_micbias,
10875 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10876 SND_SOC_DAPM_MICBIAS_E(DAPM_MICBIAS2_STANDALONE, SND_SOC_NOPM, 0, 0,
10877 tasha_codec_force_enable_micbias,
10878 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10879 SND_SOC_DAPM_MICBIAS_E(DAPM_MICBIAS3_STANDALONE, SND_SOC_NOPM, 0, 0,
10880 tasha_codec_force_enable_micbias,
10881 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10882 SND_SOC_DAPM_MICBIAS_E(DAPM_MICBIAS4_STANDALONE, SND_SOC_NOPM, 0, 0,
10883 tasha_codec_force_enable_micbias,
10884 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10885 SND_SOC_DAPM_SUPPLY(DAPM_LDO_H_STANDALONE, SND_SOC_NOPM, 0, 0,
10886 tasha_codec_force_enable_ldo_h,
10887 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10888
10889 SND_SOC_DAPM_MUX("ANC0 FB MUX", SND_SOC_NOPM, 0, 0, &anc0_fb_mux),
10890 SND_SOC_DAPM_MUX("ANC1 FB MUX", SND_SOC_NOPM, 0, 0, &anc1_fb_mux),
10891
10892 SND_SOC_DAPM_INPUT("AMIC2"),
10893 SND_SOC_DAPM_INPUT("AMIC3"),
10894 SND_SOC_DAPM_INPUT("AMIC4"),
10895 SND_SOC_DAPM_INPUT("AMIC5"),
10896 SND_SOC_DAPM_INPUT("AMIC6"),
10897
10898 SND_SOC_DAPM_AIF_OUT_E("AIF1 CAP", "AIF1 Capture", 0, SND_SOC_NOPM,
10899 AIF1_CAP, 0, tasha_codec_enable_slimtx,
10900 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
10901
10902 SND_SOC_DAPM_AIF_OUT_E("AIF2 CAP", "AIF2 Capture", 0, SND_SOC_NOPM,
10903 AIF2_CAP, 0, tasha_codec_enable_slimtx,
10904 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
10905
10906 SND_SOC_DAPM_AIF_OUT_E("AIF3 CAP", "AIF3 Capture", 0, SND_SOC_NOPM,
10907 AIF3_CAP, 0, tasha_codec_enable_slimtx,
10908 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
10909
10910 SND_SOC_DAPM_AIF_OUT_E("AIF4 VI", "VIfeed", 0, SND_SOC_NOPM,
10911 AIF4_VIFEED, 0, tasha_codec_enable_slimvi_feedback,
10912 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
10913 SND_SOC_DAPM_MIXER("AIF4_VI Mixer", SND_SOC_NOPM, AIF4_VIFEED, 0,
10914 aif4_vi_mixer, ARRAY_SIZE(aif4_vi_mixer)),
10915
10916 SND_SOC_DAPM_MIXER("AIF1_CAP Mixer", SND_SOC_NOPM, AIF1_CAP, 0,
10917 aif1_cap_mixer, ARRAY_SIZE(aif1_cap_mixer)),
10918
10919 SND_SOC_DAPM_MIXER("AIF2_CAP Mixer", SND_SOC_NOPM, AIF2_CAP, 0,
10920 aif2_cap_mixer, ARRAY_SIZE(aif2_cap_mixer)),
10921
10922 SND_SOC_DAPM_MIXER("AIF3_CAP Mixer", SND_SOC_NOPM, AIF3_CAP, 0,
10923 aif3_cap_mixer, ARRAY_SIZE(aif3_cap_mixer)),
10924
10925 SND_SOC_DAPM_MIXER("AIF4_MAD Mixer", SND_SOC_NOPM, AIF4_MAD_TX, 0,
10926 aif4_mad_mixer, ARRAY_SIZE(aif4_mad_mixer)),
10927
10928 SND_SOC_DAPM_INPUT("VIINPUT"),
10929
10930 SND_SOC_DAPM_AIF_OUT("AIF5 CPE", "AIF5 CPE TX", 0, SND_SOC_NOPM,
10931 AIF5_CPE_TX, 0),
10932
10933 SND_SOC_DAPM_MUX_E("EC BUF MUX INP", SND_SOC_NOPM, 0, 0, &ec_buf_mux,
10934 tasha_codec_ec_buf_mux_enable,
10935 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
10936
10937 /* Digital Mic Inputs */
10938 SND_SOC_DAPM_ADC_E("DMIC0", NULL, SND_SOC_NOPM, 0, 0,
10939 tasha_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
10940 SND_SOC_DAPM_POST_PMD),
10941
10942 SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0,
10943 tasha_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
10944 SND_SOC_DAPM_POST_PMD),
10945
10946 SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 0, 0,
10947 tasha_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
10948 SND_SOC_DAPM_POST_PMD),
10949
10950 SND_SOC_DAPM_ADC_E("DMIC3", NULL, SND_SOC_NOPM, 0, 0,
10951 tasha_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
10952 SND_SOC_DAPM_POST_PMD),
10953
10954 SND_SOC_DAPM_ADC_E("DMIC4", NULL, SND_SOC_NOPM, 0, 0,
10955 tasha_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
10956 SND_SOC_DAPM_POST_PMD),
10957
10958 SND_SOC_DAPM_ADC_E("DMIC5", NULL, SND_SOC_NOPM, 0, 0,
10959 tasha_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
10960 SND_SOC_DAPM_POST_PMD),
10961
10962 SND_SOC_DAPM_MUX("IIR0 INP0 MUX", SND_SOC_NOPM, 0, 0, &iir0_inp0_mux),
10963 SND_SOC_DAPM_MUX("IIR0 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir0_inp1_mux),
10964 SND_SOC_DAPM_MUX("IIR0 INP2 MUX", SND_SOC_NOPM, 0, 0, &iir0_inp2_mux),
10965 SND_SOC_DAPM_MUX("IIR0 INP3 MUX", SND_SOC_NOPM, 0, 0, &iir0_inp3_mux),
10966 SND_SOC_DAPM_MUX("IIR1 INP0 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp0_mux),
10967 SND_SOC_DAPM_MUX("IIR1 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp1_mux),
10968 SND_SOC_DAPM_MUX("IIR1 INP2 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp2_mux),
10969 SND_SOC_DAPM_MUX("IIR1 INP3 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp3_mux),
10970
10971 SND_SOC_DAPM_MIXER_E("IIR0", WCD9335_CDC_SIDETONE_IIR0_IIR_PATH_CTL,
10972 4, 0, NULL, 0, tasha_codec_set_iir_gain,
10973 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
10974 SND_SOC_DAPM_MIXER_E("IIR1", WCD9335_CDC_SIDETONE_IIR1_IIR_PATH_CTL,
10975 4, 0, NULL, 0, tasha_codec_set_iir_gain,
10976 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
10977 SND_SOC_DAPM_MIXER("SRC0", WCD9335_CDC_SIDETONE_SRC0_ST_SRC_PATH_CTL,
10978 4, 0, NULL, 0),
10979 SND_SOC_DAPM_MIXER("SRC1", WCD9335_CDC_SIDETONE_SRC1_ST_SRC_PATH_CTL,
10980 4, 0, NULL, 0),
10981 SND_SOC_DAPM_MIXER_E("CPE IN Mixer", SND_SOC_NOPM, 0, 0,
10982 cpe_in_mix_switch,
10983 ARRAY_SIZE(cpe_in_mix_switch),
10984 tasha_codec_configure_cpe_input,
10985 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10986
10987 SND_SOC_DAPM_MUX("RX INT1_1 NATIVE MUX", SND_SOC_NOPM, 0, 0,
10988 &int1_1_native_mux),
10989 SND_SOC_DAPM_MUX("RX INT2_1 NATIVE MUX", SND_SOC_NOPM, 0, 0,
10990 &int2_1_native_mux),
10991 SND_SOC_DAPM_MUX("RX INT3_1 NATIVE MUX", SND_SOC_NOPM, 0, 0,
10992 &int3_1_native_mux),
10993 SND_SOC_DAPM_MUX("RX INT4_1 NATIVE MUX", SND_SOC_NOPM, 0, 0,
10994 &int4_1_native_mux),
10995 SND_SOC_DAPM_MUX("RX MIX TX0 MUX", SND_SOC_NOPM, 0, 0,
10996 &rx_mix_tx0_mux),
10997 SND_SOC_DAPM_MUX("RX MIX TX1 MUX", SND_SOC_NOPM, 0, 0,
10998 &rx_mix_tx1_mux),
10999 SND_SOC_DAPM_MUX("RX MIX TX2 MUX", SND_SOC_NOPM, 0, 0,
11000 &rx_mix_tx2_mux),
11001 SND_SOC_DAPM_MUX("RX MIX TX3 MUX", SND_SOC_NOPM, 0, 0,
11002 &rx_mix_tx3_mux),
11003 SND_SOC_DAPM_MUX("RX MIX TX4 MUX", SND_SOC_NOPM, 0, 0,
11004 &rx_mix_tx4_mux),
11005 SND_SOC_DAPM_MUX("RX MIX TX5 MUX", SND_SOC_NOPM, 0, 0,
11006 &rx_mix_tx5_mux),
11007 SND_SOC_DAPM_MUX("RX MIX TX6 MUX", SND_SOC_NOPM, 0, 0,
11008 &rx_mix_tx6_mux),
11009 SND_SOC_DAPM_MUX("RX MIX TX7 MUX", SND_SOC_NOPM, 0, 0,
11010 &rx_mix_tx7_mux),
11011 SND_SOC_DAPM_MUX("RX MIX TX8 MUX", SND_SOC_NOPM, 0, 0,
11012 &rx_mix_tx8_mux),
11013
11014 SND_SOC_DAPM_MUX("RX INT0 DEM MUX", SND_SOC_NOPM, 0, 0,
11015 &rx_int0_dem_inp_mux),
11016 SND_SOC_DAPM_MUX("RX INT1 DEM MUX", SND_SOC_NOPM, 0, 0,
11017 &rx_int1_dem_inp_mux),
11018 SND_SOC_DAPM_MUX("RX INT2 DEM MUX", SND_SOC_NOPM, 0, 0,
11019 &rx_int2_dem_inp_mux),
11020
11021 SND_SOC_DAPM_MUX_E("RX INT0 INTERP", SND_SOC_NOPM,
11022 INTERP_EAR, 0, &rx_int0_interp_mux,
11023 tasha_codec_enable_interpolator,
11024 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11025 SND_SOC_DAPM_POST_PMD),
11026 SND_SOC_DAPM_MUX_E("RX INT1 INTERP", SND_SOC_NOPM,
11027 INTERP_HPHL, 0, &rx_int1_interp_mux,
11028 tasha_codec_enable_interpolator,
11029 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11030 SND_SOC_DAPM_POST_PMD),
11031 SND_SOC_DAPM_MUX_E("RX INT2 INTERP", SND_SOC_NOPM,
11032 INTERP_HPHR, 0, &rx_int2_interp_mux,
11033 tasha_codec_enable_interpolator,
11034 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11035 SND_SOC_DAPM_POST_PMD),
11036 SND_SOC_DAPM_MUX_E("RX INT3 INTERP", SND_SOC_NOPM,
11037 INTERP_LO1, 0, &rx_int3_interp_mux,
11038 tasha_codec_enable_interpolator,
11039 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11040 SND_SOC_DAPM_POST_PMD),
11041 SND_SOC_DAPM_MUX_E("RX INT4 INTERP", SND_SOC_NOPM,
11042 INTERP_LO2, 0, &rx_int4_interp_mux,
11043 tasha_codec_enable_interpolator,
11044 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11045 SND_SOC_DAPM_POST_PMD),
11046 SND_SOC_DAPM_MUX_E("RX INT5 INTERP", SND_SOC_NOPM,
11047 INTERP_LO3, 0, &rx_int5_interp_mux,
11048 tasha_codec_enable_interpolator,
11049 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11050 SND_SOC_DAPM_POST_PMD),
11051 SND_SOC_DAPM_MUX_E("RX INT6 INTERP", SND_SOC_NOPM,
11052 INTERP_LO4, 0, &rx_int6_interp_mux,
11053 tasha_codec_enable_interpolator,
11054 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11055 SND_SOC_DAPM_POST_PMD),
11056 SND_SOC_DAPM_MUX_E("RX INT7 INTERP", SND_SOC_NOPM,
11057 INTERP_SPKR1, 0, &rx_int7_interp_mux,
11058 tasha_codec_enable_interpolator,
11059 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11060 SND_SOC_DAPM_POST_PMD),
11061 SND_SOC_DAPM_MUX_E("RX INT8 INTERP", SND_SOC_NOPM,
11062 INTERP_SPKR2, 0, &rx_int8_interp_mux,
11063 tasha_codec_enable_interpolator,
11064 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11065 SND_SOC_DAPM_POST_PMD),
11066
11067 SND_SOC_DAPM_DAC_E("RX INT0 DAC", NULL, SND_SOC_NOPM,
11068 0, 0, tasha_codec_ear_dac_event,
11069 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11070 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11071 SND_SOC_DAPM_DAC_E("RX INT1 DAC", NULL, WCD9335_ANA_HPH,
11072 5, 0, tasha_codec_hphl_dac_event,
11073 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11074 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11075 SND_SOC_DAPM_DAC_E("RX INT2 DAC", NULL, WCD9335_ANA_HPH,
11076 4, 0, tasha_codec_hphr_dac_event,
11077 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11078 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11079 SND_SOC_DAPM_DAC_E("RX INT3 DAC", NULL, SND_SOC_NOPM,
11080 0, 0, tasha_codec_lineout_dac_event,
11081 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
11082 SND_SOC_DAPM_DAC_E("RX INT4 DAC", NULL, SND_SOC_NOPM,
11083 0, 0, tasha_codec_lineout_dac_event,
11084 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
11085 SND_SOC_DAPM_DAC_E("RX INT5 DAC", NULL, SND_SOC_NOPM,
11086 0, 0, tasha_codec_lineout_dac_event,
11087 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
11088 SND_SOC_DAPM_DAC_E("RX INT6 DAC", NULL, SND_SOC_NOPM,
11089 0, 0, tasha_codec_lineout_dac_event,
11090 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
11091 SND_SOC_DAPM_PGA_E("HPHL PA", WCD9335_ANA_HPH, 7, 0, NULL, 0,
11092 tasha_codec_enable_hphl_pa,
11093 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11094 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11095 SND_SOC_DAPM_PGA_E("HPHR PA", WCD9335_ANA_HPH, 6, 0, NULL, 0,
11096 tasha_codec_enable_hphr_pa,
11097 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11098 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11099 SND_SOC_DAPM_PGA_E("EAR PA", WCD9335_ANA_EAR, 7, 0, NULL, 0,
11100 tasha_codec_enable_ear_pa,
11101 SND_SOC_DAPM_POST_PMU |
11102 SND_SOC_DAPM_POST_PMD),
11103 SND_SOC_DAPM_PGA_E("LINEOUT1 PA", WCD9335_ANA_LO_1_2, 7, 0, NULL, 0,
11104 tasha_codec_enable_lineout_pa,
11105 SND_SOC_DAPM_POST_PMU |
11106 SND_SOC_DAPM_POST_PMD),
11107 SND_SOC_DAPM_PGA_E("LINEOUT2 PA", WCD9335_ANA_LO_1_2, 6, 0, NULL, 0,
11108 tasha_codec_enable_lineout_pa,
11109 SND_SOC_DAPM_POST_PMU |
11110 SND_SOC_DAPM_POST_PMD),
11111 SND_SOC_DAPM_PGA_E("LINEOUT3 PA", WCD9335_ANA_LO_3_4, 7, 0, NULL, 0,
11112 tasha_codec_enable_lineout_pa,
11113 SND_SOC_DAPM_POST_PMU |
11114 SND_SOC_DAPM_POST_PMD),
11115 SND_SOC_DAPM_PGA_E("LINEOUT4 PA", WCD9335_ANA_LO_3_4, 6, 0, NULL, 0,
11116 tasha_codec_enable_lineout_pa,
11117 SND_SOC_DAPM_POST_PMU |
11118 SND_SOC_DAPM_POST_PMD),
11119 SND_SOC_DAPM_PGA_E("ANC EAR PA", WCD9335_ANA_EAR, 7, 0, NULL, 0,
11120 tasha_codec_enable_ear_pa,
11121 SND_SOC_DAPM_POST_PMU |
11122 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11123 SND_SOC_DAPM_PGA_E("ANC HPHL PA", SND_SOC_NOPM, 0, 0, NULL, 0,
11124 tasha_codec_enable_hphl_pa,
11125 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11126 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11127 SND_SOC_DAPM_PGA_E("ANC HPHR PA", SND_SOC_NOPM, 0, 0, NULL, 0,
11128 tasha_codec_enable_hphr_pa,
11129 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11130 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11131 SND_SOC_DAPM_PGA_E("ANC LINEOUT1 PA", WCD9335_ANA_LO_1_2,
11132 7, 0, NULL, 0,
11133 tasha_codec_enable_lineout_pa,
11134 SND_SOC_DAPM_POST_PMU |
11135 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11136 SND_SOC_DAPM_PGA_E("ANC LINEOUT2 PA", WCD9335_ANA_LO_1_2,
11137 6, 0, NULL, 0,
11138 tasha_codec_enable_lineout_pa,
11139 SND_SOC_DAPM_POST_PMU |
11140 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11141 SND_SOC_DAPM_PGA_E("ANC SPK1 PA", SND_SOC_NOPM, 0, 0, NULL, 0,
11142 tasha_codec_enable_spk_anc,
11143 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
11144
11145 SND_SOC_DAPM_OUTPUT("HPHL"),
11146 SND_SOC_DAPM_OUTPUT("HPHR"),
11147 SND_SOC_DAPM_OUTPUT("ANC HPHL"),
11148 SND_SOC_DAPM_OUTPUT("ANC HPHR"),
11149 SND_SOC_DAPM_SUPPLY("RX_BIAS", SND_SOC_NOPM, 0, 0,
11150 tasha_codec_enable_rx_bias, SND_SOC_DAPM_PRE_PMU |
11151 SND_SOC_DAPM_POST_PMD),
11152 SND_SOC_DAPM_OUTPUT("SPK1 OUT"),
11153 SND_SOC_DAPM_OUTPUT("SPK2 OUT"),
11154 SND_SOC_DAPM_OUTPUT("LINEOUT1"),
11155 SND_SOC_DAPM_OUTPUT("LINEOUT2"),
11156 SND_SOC_DAPM_OUTPUT("LINEOUT3"),
11157 SND_SOC_DAPM_OUTPUT("LINEOUT4"),
11158 SND_SOC_DAPM_OUTPUT("ANC LINEOUT1"),
11159 SND_SOC_DAPM_OUTPUT("ANC LINEOUT2"),
11160 SND_SOC_DAPM_SUPPLY("MICBIAS_REGULATOR", SND_SOC_NOPM,
11161 ON_DEMAND_MICBIAS, 0,
11162 tasha_codec_enable_on_demand_supply,
11163 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
11164
11165 SND_SOC_DAPM_SWITCH("ADC US MUX0", WCD9335_CDC_TX0_TX_PATH_192_CTL, 0,
11166 0, &adc_us_mux0_switch),
11167 SND_SOC_DAPM_SWITCH("ADC US MUX1", WCD9335_CDC_TX1_TX_PATH_192_CTL, 0,
11168 0, &adc_us_mux1_switch),
11169 SND_SOC_DAPM_SWITCH("ADC US MUX2", WCD9335_CDC_TX2_TX_PATH_192_CTL, 0,
11170 0, &adc_us_mux2_switch),
11171 SND_SOC_DAPM_SWITCH("ADC US MUX3", WCD9335_CDC_TX3_TX_PATH_192_CTL, 0,
11172 0, &adc_us_mux3_switch),
11173 SND_SOC_DAPM_SWITCH("ADC US MUX4", WCD9335_CDC_TX4_TX_PATH_192_CTL, 0,
11174 0, &adc_us_mux4_switch),
11175 SND_SOC_DAPM_SWITCH("ADC US MUX5", WCD9335_CDC_TX5_TX_PATH_192_CTL, 0,
11176 0, &adc_us_mux5_switch),
11177 SND_SOC_DAPM_SWITCH("ADC US MUX6", WCD9335_CDC_TX6_TX_PATH_192_CTL, 0,
11178 0, &adc_us_mux6_switch),
11179 SND_SOC_DAPM_SWITCH("ADC US MUX7", WCD9335_CDC_TX7_TX_PATH_192_CTL, 0,
11180 0, &adc_us_mux7_switch),
11181 SND_SOC_DAPM_SWITCH("ADC US MUX8", WCD9335_CDC_TX8_TX_PATH_192_CTL, 0,
11182 0, &adc_us_mux8_switch),
11183 /* MAD related widgets */
11184 SND_SOC_DAPM_AIF_OUT_E("AIF4 MAD", "AIF4 MAD TX", 0,
11185 SND_SOC_NOPM, 0, 0,
11186 tasha_codec_enable_mad,
11187 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
11188
11189 SND_SOC_DAPM_MUX("MAD_SEL MUX", SND_SOC_NOPM, 0, 0,
11190 &mad_sel_mux),
11191 SND_SOC_DAPM_INPUT("MAD_CPE_INPUT"),
11192 SND_SOC_DAPM_INPUT("MADINPUT"),
11193 SND_SOC_DAPM_SWITCH("MADONOFF", SND_SOC_NOPM, 0, 0,
11194 &aif4_mad_switch),
11195 SND_SOC_DAPM_SWITCH("MAD_BROADCAST", SND_SOC_NOPM, 0, 0,
11196 &mad_brdcst_switch),
11197 SND_SOC_DAPM_SWITCH("AIF4", SND_SOC_NOPM, 0, 0,
11198 &aif4_switch_mixer_controls),
11199 SND_SOC_DAPM_SWITCH("ANC HPHL Enable", SND_SOC_NOPM, 0, 0,
11200 &anc_hphl_switch),
11201 SND_SOC_DAPM_SWITCH("ANC HPHR Enable", SND_SOC_NOPM, 0, 0,
11202 &anc_hphr_switch),
11203 SND_SOC_DAPM_SWITCH("ANC EAR Enable", SND_SOC_NOPM, 0, 0,
11204 &anc_ear_switch),
11205 SND_SOC_DAPM_SWITCH("ANC OUT EAR SPKR Enable", SND_SOC_NOPM, 0, 0,
11206 &anc_ear_spkr_switch),
11207 SND_SOC_DAPM_SWITCH("ANC LINEOUT1 Enable", SND_SOC_NOPM, 0, 0,
11208 &anc_lineout1_switch),
11209 SND_SOC_DAPM_SWITCH("ANC LINEOUT2 Enable", SND_SOC_NOPM, 0, 0,
11210 &anc_lineout2_switch),
11211 SND_SOC_DAPM_SWITCH("ANC SPKR PA Enable", SND_SOC_NOPM, 0, 0,
11212 &anc_spkr_pa_switch),
11213};
11214
11215static int tasha_get_channel_map(struct snd_soc_dai *dai,
11216 unsigned int *tx_num, unsigned int *tx_slot,
11217 unsigned int *rx_num, unsigned int *rx_slot)
11218{
11219 struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(dai->codec);
11220 u32 i = 0;
11221 struct wcd9xxx_ch *ch;
11222
11223 switch (dai->id) {
11224 case AIF1_PB:
11225 case AIF2_PB:
11226 case AIF3_PB:
11227 case AIF4_PB:
11228 case AIF_MIX1_PB:
11229 if (!rx_slot || !rx_num) {
11230 pr_err("%s: Invalid rx_slot %pK or rx_num %pK\n",
11231 __func__, rx_slot, rx_num);
11232 return -EINVAL;
11233 }
11234 list_for_each_entry(ch, &tasha_p->dai[dai->id].wcd9xxx_ch_list,
11235 list) {
11236 pr_debug("%s: slot_num %u ch->ch_num %d\n",
11237 __func__, i, ch->ch_num);
11238 rx_slot[i++] = ch->ch_num;
11239 }
11240 pr_debug("%s: rx_num %d\n", __func__, i);
11241 *rx_num = i;
11242 break;
11243 case AIF1_CAP:
11244 case AIF2_CAP:
11245 case AIF3_CAP:
11246 case AIF4_MAD_TX:
11247 case AIF4_VIFEED:
11248 if (!tx_slot || !tx_num) {
11249 pr_err("%s: Invalid tx_slot %pK or tx_num %pK\n",
11250 __func__, tx_slot, tx_num);
11251 return -EINVAL;
11252 }
11253 list_for_each_entry(ch, &tasha_p->dai[dai->id].wcd9xxx_ch_list,
11254 list) {
11255 pr_debug("%s: slot_num %u ch->ch_num %d\n",
11256 __func__, i, ch->ch_num);
11257 tx_slot[i++] = ch->ch_num;
11258 }
11259 pr_debug("%s: tx_num %d\n", __func__, i);
11260 *tx_num = i;
11261 break;
11262
11263 default:
11264 pr_err("%s: Invalid DAI ID %x\n", __func__, dai->id);
11265 break;
11266 }
11267
11268 return 0;
11269}
11270
11271static int tasha_set_channel_map(struct snd_soc_dai *dai,
11272 unsigned int tx_num, unsigned int *tx_slot,
11273 unsigned int rx_num, unsigned int *rx_slot)
11274{
11275 struct tasha_priv *tasha;
11276 struct wcd9xxx *core;
11277 struct wcd9xxx_codec_dai_data *dai_data = NULL;
11278
11279 if (!dai) {
11280 pr_err("%s: dai is empty\n", __func__);
11281 return -EINVAL;
11282 }
11283 tasha = snd_soc_codec_get_drvdata(dai->codec);
11284 core = dev_get_drvdata(dai->codec->dev->parent);
11285
11286 if (!tx_slot || !rx_slot) {
11287 pr_err("%s: Invalid tx_slot=%pK, rx_slot=%pK\n",
11288 __func__, tx_slot, rx_slot);
11289 return -EINVAL;
11290 }
11291 pr_debug("%s(): dai_name = %s DAI-ID %x tx_ch %d rx_ch %d\n"
11292 "tasha->intf_type %d\n",
11293 __func__, dai->name, dai->id, tx_num, rx_num,
11294 tasha->intf_type);
11295
11296 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
11297 wcd9xxx_init_slimslave(core, core->slim->laddr,
11298 tx_num, tx_slot, rx_num, rx_slot);
11299 /* Reserve TX12/TX13 for MAD data channel */
11300 dai_data = &tasha->dai[AIF4_MAD_TX];
11301 if (dai_data) {
11302 if (TASHA_IS_2_0(tasha->wcd9xxx))
11303 list_add_tail(&core->tx_chs[TASHA_TX13].list,
11304 &dai_data->wcd9xxx_ch_list);
11305 else
11306 list_add_tail(&core->tx_chs[TASHA_TX12].list,
11307 &dai_data->wcd9xxx_ch_list);
11308 }
11309 }
11310 return 0;
11311}
11312
11313static int tasha_startup(struct snd_pcm_substream *substream,
11314 struct snd_soc_dai *dai)
11315{
11316 pr_debug("%s(): substream = %s stream = %d\n", __func__,
11317 substream->name, substream->stream);
11318
11319 return 0;
11320}
11321
11322static void tasha_shutdown(struct snd_pcm_substream *substream,
11323 struct snd_soc_dai *dai)
11324{
11325 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(dai->codec);
11326
11327 pr_debug("%s(): substream = %s stream = %d\n", __func__,
11328 substream->name, substream->stream);
11329
11330 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C)
11331 return;
11332
11333 if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) &&
11334 test_bit(SB_CLK_GEAR, &tasha->status_mask)) {
11335 tasha_codec_vote_max_bw(dai->codec, false);
11336 clear_bit(SB_CLK_GEAR, &tasha->status_mask);
11337 }
11338}
11339
11340static int tasha_set_decimator_rate(struct snd_soc_dai *dai,
11341 u8 tx_fs_rate_reg_val, u32 sample_rate)
11342{
11343 struct snd_soc_codec *codec = dai->codec;
11344 struct wcd9xxx_ch *ch;
11345 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
11346 u32 tx_port = 0;
11347 u8 shift = 0, shift_val = 0, tx_mux_sel = 0;
11348 int decimator = -1;
11349 u16 tx_port_reg = 0, tx_fs_reg = 0;
11350
11351 list_for_each_entry(ch, &tasha->dai[dai->id].wcd9xxx_ch_list, list) {
11352 tx_port = ch->port;
11353 dev_dbg(codec->dev, "%s: dai->id = %d, tx_port = %d",
11354 __func__, dai->id, tx_port);
11355
11356 if ((tx_port < 0) || (tx_port == 12) || (tx_port >= 14)) {
11357 dev_err(codec->dev, "%s: Invalid SLIM TX%u port. DAI ID: %d\n",
11358 __func__, tx_port, dai->id);
11359 return -EINVAL;
11360 }
11361 /* Find the SB TX MUX input - which decimator is connected */
11362 if (tx_port < 4) {
11363 tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0;
11364 shift = (tx_port << 1);
11365 shift_val = 0x03;
11366 } else if ((tx_port >= 4) && (tx_port < 8)) {
11367 tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1;
11368 shift = ((tx_port - 4) << 1);
11369 shift_val = 0x03;
11370 } else if ((tx_port >= 8) && (tx_port < 11)) {
11371 tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG2;
11372 shift = ((tx_port - 8) << 1);
11373 shift_val = 0x03;
11374 } else if (tx_port == 11) {
11375 tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG3;
11376 shift = 0;
11377 shift_val = 0x0F;
11378 } else if (tx_port == 13) {
11379 tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG3;
11380 shift = 4;
11381 shift_val = 0x03;
11382 }
11383 tx_mux_sel = snd_soc_read(codec, tx_port_reg) &
11384 (shift_val << shift);
11385 tx_mux_sel = tx_mux_sel >> shift;
11386
11387 if (tx_port <= 8) {
11388 if ((tx_mux_sel == 0x2) || (tx_mux_sel == 0x3))
11389 decimator = tx_port;
11390 } else if (tx_port <= 10) {
11391 if ((tx_mux_sel == 0x1) || (tx_mux_sel == 0x2))
11392 decimator = ((tx_port == 9) ? 7 : 6);
11393 } else if (tx_port == 11) {
11394 if ((tx_mux_sel >= 1) && (tx_mux_sel < 7))
11395 decimator = tx_mux_sel - 1;
11396 } else if (tx_port == 13) {
11397 if ((tx_mux_sel == 0x1) || (tx_mux_sel == 0x2))
11398 decimator = 5;
11399 }
11400
11401 if (decimator >= 0) {
11402 tx_fs_reg = WCD9335_CDC_TX0_TX_PATH_CTL +
11403 16 * decimator;
11404 dev_dbg(codec->dev, "%s: set DEC%u (-> SLIM_TX%u) rate to %u\n",
11405 __func__, decimator, tx_port, sample_rate);
11406 snd_soc_update_bits(codec, tx_fs_reg, 0x0F,
11407 tx_fs_rate_reg_val);
11408 } else if ((tx_port <= 8) && (tx_mux_sel == 0x01)) {
11409 /* Check if the TX Mux input is RX MIX TXn */
11410 dev_dbg(codec->dev, "%s: RX_MIX_TX%u going to SLIM TX%u\n",
11411 __func__, tx_port, tx_port);
11412 } else {
11413 dev_err(codec->dev, "%s: ERROR: Invalid decimator: %d\n",
11414 __func__, decimator);
11415 return -EINVAL;
11416 }
11417 }
11418 return 0;
11419}
11420
11421static int tasha_set_mix_interpolator_rate(struct snd_soc_dai *dai,
11422 u8 int_mix_fs_rate_reg_val,
11423 u32 sample_rate)
11424{
11425 u8 int_2_inp;
11426 u32 j;
11427 u16 int_mux_cfg1, int_fs_reg;
11428 u8 int_mux_cfg1_val;
11429 struct snd_soc_codec *codec = dai->codec;
11430 struct wcd9xxx_ch *ch;
11431 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
11432
11433 list_for_each_entry(ch, &tasha->dai[dai->id].wcd9xxx_ch_list, list) {
11434 int_2_inp = ch->port + INTn_2_INP_SEL_RX0 -
11435 TASHA_RX_PORT_START_NUMBER;
11436 if ((int_2_inp < INTn_2_INP_SEL_RX0) ||
11437 (int_2_inp > INTn_2_INP_SEL_RX7)) {
11438 pr_err("%s: Invalid RX%u port, Dai ID is %d\n",
11439 __func__,
11440 (ch->port - TASHA_RX_PORT_START_NUMBER),
11441 dai->id);
11442 return -EINVAL;
11443 }
11444
11445 int_mux_cfg1 = WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG1;
11446 for (j = 0; j < TASHA_NUM_INTERPOLATORS; j++) {
11447 int_mux_cfg1_val = snd_soc_read(codec, int_mux_cfg1) &
11448 0x0F;
11449 if (int_mux_cfg1_val == int_2_inp) {
11450 int_fs_reg = WCD9335_CDC_RX0_RX_PATH_MIX_CTL +
11451 20 * j;
11452 pr_debug("%s: AIF_MIX_PB DAI(%d) connected to INT%u_2\n",
11453 __func__, dai->id, j);
11454 pr_debug("%s: set INT%u_2 sample rate to %u\n",
11455 __func__, j, sample_rate);
11456 snd_soc_update_bits(codec, int_fs_reg,
11457 0x0F, int_mix_fs_rate_reg_val);
11458 }
11459 int_mux_cfg1 += 2;
11460 }
11461 }
11462 return 0;
11463}
11464
11465static int tasha_set_prim_interpolator_rate(struct snd_soc_dai *dai,
11466 u8 int_prim_fs_rate_reg_val,
11467 u32 sample_rate)
11468{
11469 u8 int_1_mix1_inp;
11470 u32 j;
11471 u16 int_mux_cfg0, int_mux_cfg1;
11472 u16 int_fs_reg;
11473 u8 int_mux_cfg0_val, int_mux_cfg1_val;
11474 u8 inp0_sel, inp1_sel, inp2_sel;
11475 struct snd_soc_codec *codec = dai->codec;
11476 struct wcd9xxx_ch *ch;
11477 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
11478
11479 list_for_each_entry(ch, &tasha->dai[dai->id].wcd9xxx_ch_list, list) {
11480 int_1_mix1_inp = ch->port + INTn_1_MIX_INP_SEL_RX0 -
11481 TASHA_RX_PORT_START_NUMBER;
11482 if ((int_1_mix1_inp < INTn_1_MIX_INP_SEL_RX0) ||
11483 (int_1_mix1_inp > INTn_1_MIX_INP_SEL_RX7)) {
11484 pr_err("%s: Invalid RX%u port, Dai ID is %d\n",
11485 __func__,
11486 (ch->port - TASHA_RX_PORT_START_NUMBER),
11487 dai->id);
11488 return -EINVAL;
11489 }
11490
11491 int_mux_cfg0 = WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG0;
11492
11493 /*
11494 * Loop through all interpolator MUX inputs and find out
11495 * to which interpolator input, the slim rx port
11496 * is connected
11497 */
11498 for (j = 0; j < TASHA_NUM_INTERPOLATORS; j++) {
11499 int_mux_cfg1 = int_mux_cfg0 + 1;
11500
11501 int_mux_cfg0_val = snd_soc_read(codec, int_mux_cfg0);
11502 int_mux_cfg1_val = snd_soc_read(codec, int_mux_cfg1);
11503 inp0_sel = int_mux_cfg0_val & 0x0F;
11504 inp1_sel = (int_mux_cfg0_val >> 4) & 0x0F;
11505 inp2_sel = (int_mux_cfg1_val >> 4) & 0x0F;
11506 if ((inp0_sel == int_1_mix1_inp) ||
11507 (inp1_sel == int_1_mix1_inp) ||
11508 (inp2_sel == int_1_mix1_inp)) {
11509 int_fs_reg = WCD9335_CDC_RX0_RX_PATH_CTL +
11510 20 * j;
11511 pr_debug("%s: AIF_PB DAI(%d) connected to INT%u_1\n",
11512 __func__, dai->id, j);
11513 pr_debug("%s: set INT%u_1 sample rate to %u\n",
11514 __func__, j, sample_rate);
11515 /* sample_rate is in Hz */
11516 if ((j == 0) && (sample_rate == 44100)) {
11517 pr_info("%s: Cannot set 44.1KHz on INT0\n",
11518 __func__);
11519 } else
11520 snd_soc_update_bits(codec, int_fs_reg,
11521 0x0F, int_prim_fs_rate_reg_val);
11522 }
11523 int_mux_cfg0 += 2;
11524 }
11525 }
11526
11527 return 0;
11528}
11529
11530
11531static int tasha_set_interpolator_rate(struct snd_soc_dai *dai,
11532 u32 sample_rate)
11533{
11534 int rate_val = 0;
11535 int i, ret;
11536
11537 /* set mixing path rate */
11538 for (i = 0; i < ARRAY_SIZE(int_mix_sample_rate_val); i++) {
11539 if (sample_rate ==
11540 int_mix_sample_rate_val[i].sample_rate) {
11541 rate_val =
11542 int_mix_sample_rate_val[i].rate_val;
11543 break;
11544 }
11545 }
11546 if ((i == ARRAY_SIZE(int_mix_sample_rate_val)) ||
11547 (rate_val < 0))
11548 goto prim_rate;
11549 ret = tasha_set_mix_interpolator_rate(dai,
11550 (u8) rate_val, sample_rate);
11551prim_rate:
11552 /* set primary path sample rate */
11553 for (i = 0; i < ARRAY_SIZE(int_prim_sample_rate_val); i++) {
11554 if (sample_rate ==
11555 int_prim_sample_rate_val[i].sample_rate) {
11556 rate_val =
11557 int_prim_sample_rate_val[i].rate_val;
11558 break;
11559 }
11560 }
11561 if ((i == ARRAY_SIZE(int_prim_sample_rate_val)) ||
11562 (rate_val < 0))
11563 return -EINVAL;
11564 ret = tasha_set_prim_interpolator_rate(dai,
11565 (u8) rate_val, sample_rate);
11566 return ret;
11567}
11568
11569static int tasha_prepare(struct snd_pcm_substream *substream,
11570 struct snd_soc_dai *dai)
11571{
11572 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(dai->codec);
11573
11574 pr_debug("%s(): substream = %s stream = %d\n", __func__,
11575 substream->name, substream->stream);
11576 if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) &&
11577 test_bit(SB_CLK_GEAR, &tasha->status_mask)) {
11578 tasha_codec_vote_max_bw(dai->codec, false);
11579 clear_bit(SB_CLK_GEAR, &tasha->status_mask);
11580 }
11581 return 0;
11582}
11583
11584static int tasha_hw_params(struct snd_pcm_substream *substream,
11585 struct snd_pcm_hw_params *params,
11586 struct snd_soc_dai *dai)
11587{
11588 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(dai->codec);
11589 int ret;
11590 int tx_fs_rate = -EINVAL;
11591 int rx_fs_rate = -EINVAL;
11592 int i2s_bit_mode;
11593 struct snd_soc_codec *codec = dai->codec;
11594
11595 pr_debug("%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__,
11596 dai->name, dai->id, params_rate(params),
11597 params_channels(params));
11598
11599 switch (substream->stream) {
11600 case SNDRV_PCM_STREAM_PLAYBACK:
11601 ret = tasha_set_interpolator_rate(dai, params_rate(params));
11602 if (ret) {
11603 pr_err("%s: cannot set sample rate: %u\n",
11604 __func__, params_rate(params));
11605 return ret;
11606 }
11607 switch (params_width(params)) {
11608 case 16:
11609 tasha->dai[dai->id].bit_width = 16;
11610 i2s_bit_mode = 0x01;
11611 break;
11612 case 24:
11613 tasha->dai[dai->id].bit_width = 24;
11614 i2s_bit_mode = 0x00;
11615 break;
11616 default:
11617 return -EINVAL;
11618 }
11619 tasha->dai[dai->id].rate = params_rate(params);
11620 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
11621 switch (params_rate(params)) {
11622 case 8000:
11623 rx_fs_rate = 0;
11624 break;
11625 case 16000:
11626 rx_fs_rate = 1;
11627 break;
11628 case 32000:
11629 rx_fs_rate = 2;
11630 break;
11631 case 48000:
11632 rx_fs_rate = 3;
11633 break;
11634 case 96000:
11635 rx_fs_rate = 4;
11636 break;
11637 case 192000:
11638 rx_fs_rate = 5;
11639 break;
11640 default:
11641 dev_err(tasha->dev,
11642 "%s: Invalid RX sample rate: %d\n",
11643 __func__, params_rate(params));
11644 return -EINVAL;
11645 };
11646 snd_soc_update_bits(codec,
11647 WCD9335_DATA_HUB_DATA_HUB_RX_I2S_CTL,
11648 0x20, i2s_bit_mode << 5);
11649 snd_soc_update_bits(codec,
11650 WCD9335_DATA_HUB_DATA_HUB_RX_I2S_CTL,
11651 0x1c, (rx_fs_rate << 2));
11652 }
11653 break;
11654 case SNDRV_PCM_STREAM_CAPTURE:
11655 switch (params_rate(params)) {
11656 case 8000:
11657 tx_fs_rate = 0;
11658 break;
11659 case 16000:
11660 tx_fs_rate = 1;
11661 break;
11662 case 32000:
11663 tx_fs_rate = 3;
11664 break;
11665 case 48000:
11666 tx_fs_rate = 4;
11667 break;
11668 case 96000:
11669 tx_fs_rate = 5;
11670 break;
11671 case 192000:
11672 tx_fs_rate = 6;
11673 break;
11674 case 384000:
11675 tx_fs_rate = 7;
11676 break;
11677 default:
11678 dev_err(tasha->dev, "%s: Invalid TX sample rate: %d\n",
11679 __func__, params_rate(params));
11680 return -EINVAL;
11681
11682 };
11683 if (dai->id != AIF4_VIFEED &&
11684 dai->id != AIF4_MAD_TX) {
11685 ret = tasha_set_decimator_rate(dai, tx_fs_rate,
11686 params_rate(params));
11687 if (ret < 0) {
11688 dev_err(tasha->dev, "%s: cannot set TX Decimator rate: %d\n",
11689 __func__, tx_fs_rate);
11690 return ret;
11691 }
11692 }
11693 tasha->dai[dai->id].rate = params_rate(params);
11694 switch (params_width(params)) {
11695 case 16:
11696 tasha->dai[dai->id].bit_width = 16;
11697 i2s_bit_mode = 0x01;
11698 break;
11699 case 24:
11700 tasha->dai[dai->id].bit_width = 24;
11701 i2s_bit_mode = 0x00;
11702 break;
11703 case 32:
11704 tasha->dai[dai->id].bit_width = 32;
11705 i2s_bit_mode = 0x00;
11706 break;
11707 default:
11708 dev_err(tasha->dev, "%s: Invalid format 0x%x\n",
11709 __func__, params_width(params));
11710 return -EINVAL;
11711 };
11712 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
11713 snd_soc_update_bits(codec,
11714 WCD9335_DATA_HUB_DATA_HUB_TX_I2S_CTL,
11715 0x20, i2s_bit_mode << 5);
11716 if (tx_fs_rate > 1)
11717 tx_fs_rate--;
11718 snd_soc_update_bits(codec,
11719 WCD9335_DATA_HUB_DATA_HUB_TX_I2S_CTL,
11720 0x1c, tx_fs_rate << 2);
11721 snd_soc_update_bits(codec,
11722 WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD0_L_CFG,
11723 0x05, 0x05);
11724
11725 snd_soc_update_bits(codec,
11726 WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD0_R_CFG,
11727 0x05, 0x05);
11728
11729 snd_soc_update_bits(codec,
11730 WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD1_L_CFG,
11731 0x05, 0x05);
11732
11733 snd_soc_update_bits(codec,
11734 WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD1_R_CFG,
11735 0x05, 0x05);
11736 }
11737 break;
11738 default:
11739 pr_err("%s: Invalid stream type %d\n", __func__,
11740 substream->stream);
11741 return -EINVAL;
11742 };
11743 if (dai->id == AIF4_VIFEED)
11744 tasha->dai[dai->id].bit_width = 32;
11745
11746 return 0;
11747}
11748
11749static int tasha_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
11750{
11751 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(dai->codec);
11752
11753 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
11754 case SND_SOC_DAIFMT_CBS_CFS:
11755 /* CPU is master */
11756 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
11757 if (dai->id == AIF1_CAP)
11758 snd_soc_update_bits(dai->codec,
11759 WCD9335_DATA_HUB_DATA_HUB_TX_I2S_CTL,
11760 0x2, 0);
11761 else if (dai->id == AIF1_PB)
11762 snd_soc_update_bits(dai->codec,
11763 WCD9335_DATA_HUB_DATA_HUB_RX_I2S_CTL,
11764 0x2, 0);
11765 }
11766 break;
11767 case SND_SOC_DAIFMT_CBM_CFM:
11768 /* CPU is slave */
11769 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
11770 if (dai->id == AIF1_CAP)
11771 snd_soc_update_bits(dai->codec,
11772 WCD9335_DATA_HUB_DATA_HUB_TX_I2S_CTL,
11773 0x2, 0x2);
11774 else if (dai->id == AIF1_PB)
11775 snd_soc_update_bits(dai->codec,
11776 WCD9335_DATA_HUB_DATA_HUB_RX_I2S_CTL,
11777 0x2, 0x2);
11778 }
11779 break;
11780 default:
11781 return -EINVAL;
11782 }
11783 return 0;
11784}
11785
11786static int tasha_set_dai_sysclk(struct snd_soc_dai *dai,
11787 int clk_id, unsigned int freq, int dir)
11788{
11789 pr_debug("%s\n", __func__);
11790 return 0;
11791}
11792
11793static struct snd_soc_dai_ops tasha_dai_ops = {
11794 .startup = tasha_startup,
11795 .shutdown = tasha_shutdown,
11796 .hw_params = tasha_hw_params,
11797 .prepare = tasha_prepare,
11798 .set_sysclk = tasha_set_dai_sysclk,
11799 .set_fmt = tasha_set_dai_fmt,
11800 .set_channel_map = tasha_set_channel_map,
11801 .get_channel_map = tasha_get_channel_map,
11802};
11803
11804static struct snd_soc_dai_driver tasha_dai[] = {
11805 {
11806 .name = "tasha_rx1",
11807 .id = AIF1_PB,
11808 .playback = {
11809 .stream_name = "AIF1 Playback",
11810 .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK,
11811 .formats = TASHA_FORMATS_S16_S24_LE,
11812 .rate_max = 192000,
11813 .rate_min = 8000,
11814 .channels_min = 1,
11815 .channels_max = 2,
11816 },
11817 .ops = &tasha_dai_ops,
11818 },
11819 {
11820 .name = "tasha_tx1",
11821 .id = AIF1_CAP,
11822 .capture = {
11823 .stream_name = "AIF1 Capture",
11824 .rates = WCD9335_RATES_MASK,
11825 .formats = TASHA_FORMATS_S16_S24_LE,
11826 .rate_max = 192000,
11827 .rate_min = 8000,
11828 .channels_min = 1,
11829 .channels_max = 4,
11830 },
11831 .ops = &tasha_dai_ops,
11832 },
11833 {
11834 .name = "tasha_rx2",
11835 .id = AIF2_PB,
11836 .playback = {
11837 .stream_name = "AIF2 Playback",
11838 .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK,
11839 .formats = TASHA_FORMATS_S16_S24_LE,
11840 .rate_min = 8000,
11841 .rate_max = 192000,
11842 .channels_min = 1,
11843 .channels_max = 2,
11844 },
11845 .ops = &tasha_dai_ops,
11846 },
11847 {
11848 .name = "tasha_tx2",
11849 .id = AIF2_CAP,
11850 .capture = {
11851 .stream_name = "AIF2 Capture",
11852 .rates = WCD9335_RATES_MASK,
11853 .formats = TASHA_FORMATS_S16_S24_LE,
11854 .rate_max = 192000,
11855 .rate_min = 8000,
11856 .channels_min = 1,
11857 .channels_max = 8,
11858 },
11859 .ops = &tasha_dai_ops,
11860 },
11861 {
11862 .name = "tasha_rx3",
11863 .id = AIF3_PB,
11864 .playback = {
11865 .stream_name = "AIF3 Playback",
11866 .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK,
11867 .formats = TASHA_FORMATS_S16_S24_LE,
11868 .rate_min = 8000,
11869 .rate_max = 192000,
11870 .channels_min = 1,
11871 .channels_max = 2,
11872 },
11873 .ops = &tasha_dai_ops,
11874 },
11875 {
11876 .name = "tasha_tx3",
11877 .id = AIF3_CAP,
11878 .capture = {
11879 .stream_name = "AIF3 Capture",
11880 .rates = WCD9335_RATES_MASK,
11881 .formats = TASHA_FORMATS_S16_S24_LE,
11882 .rate_max = 48000,
11883 .rate_min = 8000,
11884 .channels_min = 1,
11885 .channels_max = 2,
11886 },
11887 .ops = &tasha_dai_ops,
11888 },
11889 {
11890 .name = "tasha_rx4",
11891 .id = AIF4_PB,
11892 .playback = {
11893 .stream_name = "AIF4 Playback",
11894 .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK,
11895 .formats = TASHA_FORMATS_S16_S24_LE,
11896 .rate_min = 8000,
11897 .rate_max = 192000,
11898 .channels_min = 1,
11899 .channels_max = 2,
11900 },
11901 .ops = &tasha_dai_ops,
11902 },
11903 {
11904 .name = "tasha_mix_rx1",
11905 .id = AIF_MIX1_PB,
11906 .playback = {
11907 .stream_name = "AIF Mix Playback",
11908 .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK,
11909 .formats = TASHA_FORMATS_S16_S24_LE,
11910 .rate_min = 8000,
11911 .rate_max = 192000,
11912 .channels_min = 1,
11913 .channels_max = 8,
11914 },
11915 .ops = &tasha_dai_ops,
11916 },
11917 {
11918 .name = "tasha_mad1",
11919 .id = AIF4_MAD_TX,
11920 .capture = {
11921 .stream_name = "AIF4 MAD TX",
11922 .rates = SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 |
11923 SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_384000,
11924 .formats = TASHA_FORMATS_S16_S24_S32_LE,
11925 .rate_min = 16000,
11926 .rate_max = 384000,
11927 .channels_min = 1,
11928 .channels_max = 1,
11929 },
11930 .ops = &tasha_dai_ops,
11931 },
11932 {
11933 .name = "tasha_vifeedback",
11934 .id = AIF4_VIFEED,
11935 .capture = {
11936 .stream_name = "VIfeed",
11937 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000,
11938 .formats = TASHA_FORMATS_S16_S24_S32_LE,
11939 .rate_max = 48000,
11940 .rate_min = 8000,
11941 .channels_min = 1,
11942 .channels_max = 4,
11943 },
11944 .ops = &tasha_dai_ops,
11945 },
11946 {
11947 .name = "tasha_cpe",
11948 .id = AIF5_CPE_TX,
11949 .capture = {
11950 .stream_name = "AIF5 CPE TX",
11951 .rates = SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000,
11952 .formats = TASHA_FORMATS_S16_S24_S32_LE,
11953 .rate_min = 16000,
11954 .rate_max = 48000,
11955 .channels_min = 1,
11956 .channels_max = 1,
11957 },
11958 },
11959};
11960
11961static struct snd_soc_dai_driver tasha_i2s_dai[] = {
11962 {
11963 .name = "tasha_i2s_rx1",
11964 .id = AIF1_PB,
11965 .playback = {
11966 .stream_name = "AIF1 Playback",
11967 .rates = WCD9335_RATES_MASK,
11968 .formats = TASHA_FORMATS_S16_S24_LE,
11969 .rate_max = 192000,
11970 .rate_min = 8000,
11971 .channels_min = 1,
11972 .channels_max = 2,
11973 },
11974 .ops = &tasha_dai_ops,
11975 },
11976 {
11977 .name = "tasha_i2s_tx1",
11978 .id = AIF1_CAP,
11979 .capture = {
11980 .stream_name = "AIF1 Capture",
11981 .rates = WCD9335_RATES_MASK,
11982 .formats = TASHA_FORMATS_S16_S24_LE,
11983 .rate_max = 192000,
11984 .rate_min = 8000,
11985 .channels_min = 1,
11986 .channels_max = 4,
11987 },
11988 .ops = &tasha_dai_ops,
11989 },
11990 {
11991 .name = "tasha_i2s_rx2",
11992 .id = AIF2_PB,
11993 .playback = {
11994 .stream_name = "AIF2 Playback",
11995 .rates = WCD9335_RATES_MASK,
11996 .formats = TASHA_FORMATS_S16_S24_LE,
11997 .rate_max = 192000,
11998 .rate_min = 8000,
11999 .channels_min = 1,
12000 .channels_max = 2,
12001 },
12002 .ops = &tasha_dai_ops,
12003 },
12004 {
12005 .name = "tasha_i2s_tx2",
12006 .id = AIF2_CAP,
12007 .capture = {
12008 .stream_name = "AIF2 Capture",
12009 .rates = WCD9335_RATES_MASK,
12010 .formats = TASHA_FORMATS_S16_S24_LE,
12011 .rate_max = 192000,
12012 .rate_min = 8000,
12013 .channels_min = 1,
12014 .channels_max = 4,
12015 },
12016 .ops = &tasha_dai_ops,
12017 },
12018};
12019
12020static void tasha_codec_power_gate_digital_core(struct tasha_priv *tasha)
12021{
12022 struct snd_soc_codec *codec = tasha->codec;
12023
12024 if (!codec)
12025 return;
12026
12027 mutex_lock(&tasha->power_lock);
12028 dev_dbg(codec->dev, "%s: Entering power gating function, %d\n",
12029 __func__, tasha->power_active_ref);
12030
12031 if (tasha->power_active_ref > 0)
12032 goto exit;
12033
12034 wcd9xxx_set_power_state(tasha->wcd9xxx,
12035 WCD_REGION_POWER_COLLAPSE_BEGIN,
12036 WCD9XXX_DIG_CORE_REGION_1);
12037 snd_soc_update_bits(codec, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL,
12038 0x04, 0x04);
12039 snd_soc_update_bits(codec, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL,
12040 0x01, 0x00);
12041 snd_soc_update_bits(codec, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL,
12042 0x02, 0x00);
12043 clear_bit(AUDIO_NOMINAL, &tasha->status_mask);
12044 tasha_codec_update_sido_voltage(tasha, sido_buck_svs_voltage);
12045 wcd9xxx_set_power_state(tasha->wcd9xxx, WCD_REGION_POWER_DOWN,
12046 WCD9XXX_DIG_CORE_REGION_1);
12047exit:
12048 dev_dbg(codec->dev, "%s: Exiting power gating function, %d\n",
12049 __func__, tasha->power_active_ref);
12050 mutex_unlock(&tasha->power_lock);
12051}
12052
12053static void tasha_codec_power_gate_work(struct work_struct *work)
12054{
12055 struct tasha_priv *tasha;
12056 struct delayed_work *dwork;
12057 struct snd_soc_codec *codec;
12058
12059 dwork = to_delayed_work(work);
12060 tasha = container_of(dwork, struct tasha_priv, power_gate_work);
12061 codec = tasha->codec;
12062
12063 if (!codec)
12064 return;
12065
12066 tasha_codec_power_gate_digital_core(tasha);
12067}
12068
12069/* called under power_lock acquisition */
12070static int tasha_dig_core_remove_power_collapse(struct snd_soc_codec *codec)
12071{
12072 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
12073
12074 tasha_codec_vote_max_bw(codec, true);
12075 snd_soc_write(codec, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x5);
12076 snd_soc_write(codec, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x7);
12077 snd_soc_write(codec, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x3);
12078 snd_soc_update_bits(codec, WCD9335_CODEC_RPM_RST_CTL, 0x02, 0x00);
12079 snd_soc_update_bits(codec, WCD9335_CODEC_RPM_RST_CTL, 0x02, 0x02);
12080
12081 wcd9xxx_set_power_state(tasha->wcd9xxx,
12082 WCD_REGION_POWER_COLLAPSE_REMOVE,
12083 WCD9XXX_DIG_CORE_REGION_1);
12084 regcache_mark_dirty(codec->component.regmap);
12085 regcache_sync_region(codec->component.regmap,
12086 TASHA_DIG_CORE_REG_MIN, TASHA_DIG_CORE_REG_MAX);
12087 tasha_codec_vote_max_bw(codec, false);
12088
12089 return 0;
12090}
12091
12092static int tasha_dig_core_power_collapse(struct tasha_priv *tasha,
12093 int req_state)
12094{
12095 struct snd_soc_codec *codec;
12096 int cur_state;
12097
12098 /* Exit if feature is disabled */
12099 if (!dig_core_collapse_enable)
12100 return 0;
12101
12102 mutex_lock(&tasha->power_lock);
12103 if (req_state == POWER_COLLAPSE)
12104 tasha->power_active_ref--;
12105 else if (req_state == POWER_RESUME)
12106 tasha->power_active_ref++;
12107 else
12108 goto unlock_mutex;
12109
12110 if (tasha->power_active_ref < 0) {
12111 dev_dbg(tasha->dev, "%s: power_active_ref is negative\n",
12112 __func__);
12113 goto unlock_mutex;
12114 }
12115
12116 codec = tasha->codec;
12117 if (!codec)
12118 goto unlock_mutex;
12119
12120 if (req_state == POWER_COLLAPSE) {
12121 if (tasha->power_active_ref == 0) {
12122 schedule_delayed_work(&tasha->power_gate_work,
12123 msecs_to_jiffies(dig_core_collapse_timer * 1000));
12124 }
12125 } else if (req_state == POWER_RESUME) {
12126 if (tasha->power_active_ref == 1) {
12127 /*
12128 * At this point, there can be two cases:
12129 * 1. Core already in power collapse state
12130 * 2. Timer kicked in and still did not expire or
12131 * waiting for the power_lock
12132 */
12133 cur_state = wcd9xxx_get_current_power_state(
12134 tasha->wcd9xxx,
12135 WCD9XXX_DIG_CORE_REGION_1);
12136 if (cur_state == WCD_REGION_POWER_DOWN)
12137 tasha_dig_core_remove_power_collapse(codec);
12138 else {
12139 mutex_unlock(&tasha->power_lock);
12140 cancel_delayed_work_sync(
12141 &tasha->power_gate_work);
12142 mutex_lock(&tasha->power_lock);
12143 }
12144 }
12145 }
12146
12147unlock_mutex:
12148 mutex_unlock(&tasha->power_lock);
12149
12150 return 0;
12151}
12152
12153static int __tasha_cdc_mclk_enable_locked(struct tasha_priv *tasha,
12154 bool enable)
12155{
12156 int ret = 0;
12157
12158 if (!tasha->wcd_ext_clk) {
12159 dev_err(tasha->dev, "%s: wcd ext clock is NULL\n", __func__);
12160 return -EINVAL;
12161 }
12162
12163 dev_dbg(tasha->dev, "%s: mclk_enable = %u\n", __func__, enable);
12164
12165 if (enable) {
12166 tasha_dig_core_power_collapse(tasha, POWER_RESUME);
12167 ret = tasha_cdc_req_mclk_enable(tasha, true);
12168 if (ret)
12169 goto err;
12170
12171 set_bit(AUDIO_NOMINAL, &tasha->status_mask);
12172 tasha_codec_apply_sido_voltage(tasha,
12173 SIDO_VOLTAGE_NOMINAL_MV);
12174 } else {
12175 if (!dig_core_collapse_enable) {
12176 clear_bit(AUDIO_NOMINAL, &tasha->status_mask);
12177 tasha_codec_update_sido_voltage(tasha,
12178 sido_buck_svs_voltage);
12179 }
12180 tasha_cdc_req_mclk_enable(tasha, false);
12181 tasha_dig_core_power_collapse(tasha, POWER_COLLAPSE);
12182 }
12183
12184err:
12185 return ret;
12186}
12187
12188static int __tasha_cdc_mclk_enable(struct tasha_priv *tasha,
12189 bool enable)
12190{
12191 int ret;
12192
12193 WCD9XXX_V2_BG_CLK_LOCK(tasha->resmgr);
12194 ret = __tasha_cdc_mclk_enable_locked(tasha, enable);
12195 WCD9XXX_V2_BG_CLK_UNLOCK(tasha->resmgr);
12196
12197 return ret;
12198}
12199
12200int tasha_cdc_mclk_enable(struct snd_soc_codec *codec, int enable, bool dapm)
12201{
12202 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
12203
12204 return __tasha_cdc_mclk_enable(tasha, enable);
12205}
12206EXPORT_SYMBOL(tasha_cdc_mclk_enable);
12207
12208int tasha_cdc_mclk_tx_enable(struct snd_soc_codec *codec, int enable, bool dapm)
12209{
12210 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
12211 int ret = 0;
12212
12213 dev_dbg(tasha->dev, "%s: clk_mode: %d, enable: %d, clk_internal: %d\n",
12214 __func__, tasha->clk_mode, enable, tasha->clk_internal);
12215 if (tasha->clk_mode || tasha->clk_internal) {
12216 if (enable) {
12217 tasha_cdc_sido_ccl_enable(tasha, true);
12218 wcd_resmgr_enable_master_bias(tasha->resmgr);
12219 tasha_dig_core_power_collapse(tasha, POWER_RESUME);
12220 snd_soc_update_bits(codec,
12221 WCD9335_CDC_CLK_RST_CTRL_FS_CNT_CONTROL,
12222 0x01, 0x01);
12223 snd_soc_update_bits(codec,
12224 WCD9335_CDC_CLK_RST_CTRL_MCLK_CONTROL,
12225 0x01, 0x01);
12226 set_bit(CPE_NOMINAL, &tasha->status_mask);
12227 tasha_codec_update_sido_voltage(tasha,
12228 SIDO_VOLTAGE_NOMINAL_MV);
12229 tasha->clk_internal = true;
12230 } else {
12231 tasha->clk_internal = false;
12232 clear_bit(CPE_NOMINAL, &tasha->status_mask);
12233 tasha_codec_update_sido_voltage(tasha,
12234 sido_buck_svs_voltage);
12235 tasha_dig_core_power_collapse(tasha, POWER_COLLAPSE);
12236 wcd_resmgr_disable_master_bias(tasha->resmgr);
12237 tasha_cdc_sido_ccl_enable(tasha, false);
12238 }
12239 } else {
12240 ret = __tasha_cdc_mclk_enable(tasha, enable);
12241 }
12242 return ret;
12243}
12244EXPORT_SYMBOL(tasha_cdc_mclk_tx_enable);
12245
12246static ssize_t tasha_codec_version_read(struct snd_info_entry *entry,
12247 void *file_private_data, struct file *file,
12248 char __user *buf, size_t count, loff_t pos)
12249{
12250 struct tasha_priv *tasha;
12251 struct wcd9xxx *wcd9xxx;
12252 char buffer[TASHA_VERSION_ENTRY_SIZE];
12253 int len = 0;
12254
12255 tasha = (struct tasha_priv *) entry->private_data;
12256 if (!tasha) {
12257 pr_err("%s: tasha priv is null\n", __func__);
12258 return -EINVAL;
12259 }
12260
12261 wcd9xxx = tasha->wcd9xxx;
12262
12263 if (wcd9xxx->codec_type->id_major == TASHA_MAJOR) {
12264 if (TASHA_IS_1_0(wcd9xxx))
12265 len = snprintf(buffer, sizeof(buffer), "WCD9335_1_0\n");
12266 else if (TASHA_IS_1_1(wcd9xxx))
12267 len = snprintf(buffer, sizeof(buffer), "WCD9335_1_1\n");
12268 else
12269 snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n");
12270 } else if (wcd9xxx->codec_type->id_major == TASHA2P0_MAJOR) {
12271 len = snprintf(buffer, sizeof(buffer), "WCD9335_2_0\n");
12272 } else
12273 len = snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n");
12274
12275 return simple_read_from_buffer(buf, count, &pos, buffer, len);
12276}
12277
12278static struct snd_info_entry_ops tasha_codec_info_ops = {
12279 .read = tasha_codec_version_read,
12280};
12281
12282/*
12283 * tasha_codec_info_create_codec_entry - creates wcd9335 module
12284 * @codec_root: The parent directory
12285 * @codec: Codec instance
12286 *
12287 * Creates wcd9335 module and version entry under the given
12288 * parent directory.
12289 *
12290 * Return: 0 on success or negative error code on failure.
12291 */
12292int tasha_codec_info_create_codec_entry(struct snd_info_entry *codec_root,
12293 struct snd_soc_codec *codec)
12294{
12295 struct snd_info_entry *version_entry;
12296 struct tasha_priv *tasha;
12297 struct snd_soc_card *card;
12298
12299 if (!codec_root || !codec)
12300 return -EINVAL;
12301
12302 tasha = snd_soc_codec_get_drvdata(codec);
12303 card = codec->component.card;
Banajit Goswami7f40ea42017-01-30 13:32:41 -080012304 tasha->entry = snd_info_create_subdir(codec_root->module,
12305 "tasha", codec_root);
Banajit Goswamide8271c2017-01-18 00:28:59 -080012306 if (!tasha->entry) {
12307 dev_dbg(codec->dev, "%s: failed to create wcd9335 entry\n",
12308 __func__);
12309 return -ENOMEM;
12310 }
12311
12312 version_entry = snd_info_create_card_entry(card->snd_card,
12313 "version",
12314 tasha->entry);
12315 if (!version_entry) {
12316 dev_dbg(codec->dev, "%s: failed to create wcd9335 version entry\n",
12317 __func__);
12318 return -ENOMEM;
12319 }
12320
12321 version_entry->private_data = tasha;
12322 version_entry->size = TASHA_VERSION_ENTRY_SIZE;
12323 version_entry->content = SNDRV_INFO_CONTENT_DATA;
12324 version_entry->c.ops = &tasha_codec_info_ops;
12325
12326 if (snd_info_register(version_entry) < 0) {
12327 snd_info_free_entry(version_entry);
12328 return -ENOMEM;
12329 }
12330 tasha->version_entry = version_entry;
12331
12332 return 0;
12333}
12334EXPORT_SYMBOL(tasha_codec_info_create_codec_entry);
12335
12336static int __tasha_codec_internal_rco_ctrl(
12337 struct snd_soc_codec *codec, bool enable)
12338{
12339 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
12340 int ret = 0;
12341
12342 if (enable) {
12343 tasha_cdc_sido_ccl_enable(tasha, true);
12344 if (wcd_resmgr_get_clk_type(tasha->resmgr) ==
12345 WCD_CLK_RCO) {
12346 ret = wcd_resmgr_enable_clk_block(tasha->resmgr,
12347 WCD_CLK_RCO);
12348 } else {
12349 ret = tasha_cdc_req_mclk_enable(tasha, true);
12350 ret |= wcd_resmgr_enable_clk_block(tasha->resmgr,
12351 WCD_CLK_RCO);
12352 ret |= tasha_cdc_req_mclk_enable(tasha, false);
12353 }
12354
12355 } else {
12356 ret = wcd_resmgr_disable_clk_block(tasha->resmgr,
12357 WCD_CLK_RCO);
12358 tasha_cdc_sido_ccl_enable(tasha, false);
12359 }
12360
12361 if (ret) {
12362 dev_err(codec->dev, "%s: Error in %s RCO\n",
12363 __func__, (enable ? "enabling" : "disabling"));
12364 ret = -EINVAL;
12365 }
12366
12367 return ret;
12368}
12369
12370/*
12371 * tasha_codec_internal_rco_ctrl()
12372 * Make sure that the caller does not acquire
12373 * BG_CLK_LOCK.
12374 */
12375static int tasha_codec_internal_rco_ctrl(struct snd_soc_codec *codec,
12376 bool enable)
12377{
12378 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
12379 int ret = 0;
12380
12381 WCD9XXX_V2_BG_CLK_LOCK(tasha->resmgr);
12382 ret = __tasha_codec_internal_rco_ctrl(codec, enable);
12383 WCD9XXX_V2_BG_CLK_UNLOCK(tasha->resmgr);
12384 return ret;
12385}
12386
12387/*
12388 * tasha_mbhc_hs_detect: starts mbhc insertion/removal functionality
12389 * @codec: handle to snd_soc_codec *
12390 * @mbhc_cfg: handle to mbhc configuration structure
12391 * return 0 if mbhc_start is success or error code in case of failure
12392 */
12393int tasha_mbhc_hs_detect(struct snd_soc_codec *codec,
12394 struct wcd_mbhc_config *mbhc_cfg)
12395{
12396 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
12397
12398 return wcd_mbhc_start(&tasha->mbhc, mbhc_cfg);
12399}
12400EXPORT_SYMBOL(tasha_mbhc_hs_detect);
12401
12402/*
12403 * tasha_mbhc_hs_detect_exit: stop mbhc insertion/removal functionality
12404 * @codec: handle to snd_soc_codec *
12405 */
12406void tasha_mbhc_hs_detect_exit(struct snd_soc_codec *codec)
12407{
12408 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
12409
12410 wcd_mbhc_stop(&tasha->mbhc);
12411}
12412EXPORT_SYMBOL(tasha_mbhc_hs_detect_exit);
12413
12414static int wcd9335_get_micb_vout_ctl_val(u32 micb_mv)
12415{
12416 /* min micbias voltage is 1V and maximum is 2.85V */
12417 if (micb_mv < 1000 || micb_mv > 2850) {
12418 pr_err("%s: unsupported micbias voltage\n", __func__);
12419 return -EINVAL;
12420 }
12421
12422 return (micb_mv - 1000) / 50;
12423}
12424
12425static const struct tasha_reg_mask_val tasha_reg_update_reset_val_1_1[] = {
12426 {WCD9335_RCO_CTRL_2, 0xFF, 0x47},
12427 {WCD9335_FLYBACK_VNEG_DAC_CTRL_4, 0xFF, 0x60},
12428};
12429
12430static const struct tasha_reg_mask_val tasha_codec_reg_init_val_1_1[] = {
12431 {WCD9335_FLYBACK_VNEG_DAC_CTRL_1, 0xFF, 0x65},
12432 {WCD9335_FLYBACK_VNEG_DAC_CTRL_2, 0xFF, 0x52},
12433 {WCD9335_FLYBACK_VNEG_DAC_CTRL_3, 0xFF, 0xAF},
12434 {WCD9335_FLYBACK_VNEG_DAC_CTRL_4, 0xFF, 0x60},
12435 {WCD9335_FLYBACK_VNEG_CTRL_3, 0xFF, 0xF4},
12436 {WCD9335_FLYBACK_VNEG_CTRL_9, 0xFF, 0x40},
12437 {WCD9335_FLYBACK_VNEG_CTRL_2, 0xFF, 0x4F},
12438 {WCD9335_FLYBACK_EN, 0xFF, 0x6E},
12439 {WCD9335_CDC_RX2_RX_PATH_SEC0, 0xF8, 0xF8},
12440 {WCD9335_CDC_RX1_RX_PATH_SEC0, 0xF8, 0xF8},
12441};
12442
12443static const struct tasha_reg_mask_val tasha_codec_reg_init_val_1_0[] = {
12444 {WCD9335_FLYBACK_VNEG_CTRL_3, 0xFF, 0x54},
12445 {WCD9335_CDC_RX2_RX_PATH_SEC0, 0xFC, 0xFC},
12446 {WCD9335_CDC_RX1_RX_PATH_SEC0, 0xFC, 0xFC},
12447};
12448
12449static const struct tasha_reg_mask_val tasha_codec_reg_init_val_2_0[] = {
12450 {WCD9335_RCO_CTRL_2, 0x0F, 0x08},
12451 {WCD9335_RX_BIAS_FLYB_MID_RST, 0xF0, 0x10},
12452 {WCD9335_FLYBACK_CTRL_1, 0x20, 0x20},
12453 {WCD9335_HPH_OCP_CTL, 0xFF, 0x7A},
12454 {WCD9335_HPH_L_TEST, 0x01, 0x01},
12455 {WCD9335_HPH_R_TEST, 0x01, 0x01},
12456 {WCD9335_CDC_BOOST0_BOOST_CFG1, 0x3F, 0x12},
12457 {WCD9335_CDC_BOOST0_BOOST_CFG2, 0x1C, 0x08},
12458 {WCD9335_CDC_COMPANDER7_CTL7, 0x1E, 0x18},
12459 {WCD9335_CDC_BOOST1_BOOST_CFG1, 0x3F, 0x12},
12460 {WCD9335_CDC_BOOST1_BOOST_CFG2, 0x1C, 0x08},
12461 {WCD9335_CDC_COMPANDER8_CTL7, 0x1E, 0x18},
12462 {WCD9335_CDC_TX0_TX_PATH_SEC7, 0xFF, 0x45},
12463 {WCD9335_CDC_RX0_RX_PATH_SEC0, 0xFC, 0xF4},
12464 {WCD9335_HPH_REFBUFF_LP_CTL, 0x08, 0x08},
12465 {WCD9335_HPH_REFBUFF_LP_CTL, 0x06, 0x02},
12466 {WCD9335_DIFF_LO_CORE_OUT_PROG, 0xFC, 0xA0},
12467 {WCD9335_SE_LO_COM1, 0xFF, 0xC0},
12468 {WCD9335_CDC_RX3_RX_PATH_SEC0, 0xFC, 0xF4},
12469 {WCD9335_CDC_RX4_RX_PATH_SEC0, 0xFC, 0xF4},
12470 {WCD9335_CDC_RX5_RX_PATH_SEC0, 0xFC, 0xF8},
12471 {WCD9335_CDC_RX6_RX_PATH_SEC0, 0xFC, 0xF8},
12472};
12473
12474static const struct tasha_reg_mask_val tasha_codec_reg_defaults[] = {
12475 {WCD9335_CODEC_RPM_CLK_GATE, 0x03, 0x00},
12476 {WCD9335_CODEC_RPM_CLK_MCLK_CFG, 0x03, 0x01},
12477 {WCD9335_CODEC_RPM_CLK_MCLK_CFG, 0x04, 0x04},
12478};
12479
12480static const struct tasha_reg_mask_val tasha_codec_reg_i2c_defaults[] = {
12481 {WCD9335_ANA_CLK_TOP, 0x20, 0x20},
12482 {WCD9335_CODEC_RPM_CLK_GATE, 0x03, 0x01},
12483 {WCD9335_CODEC_RPM_CLK_MCLK_CFG, 0x03, 0x00},
12484 {WCD9335_CODEC_RPM_CLK_MCLK_CFG, 0x05, 0x05},
12485 {WCD9335_DATA_HUB_DATA_HUB_RX0_INP_CFG, 0x01, 0x01},
12486 {WCD9335_DATA_HUB_DATA_HUB_RX1_INP_CFG, 0x01, 0x01},
12487 {WCD9335_DATA_HUB_DATA_HUB_RX2_INP_CFG, 0x01, 0x01},
12488 {WCD9335_DATA_HUB_DATA_HUB_RX3_INP_CFG, 0x01, 0x01},
12489 {WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD0_L_CFG, 0x05, 0x05},
12490 {WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD0_R_CFG, 0x05, 0x05},
12491 {WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD1_L_CFG, 0x05, 0x05},
12492 {WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD1_R_CFG, 0x05, 0x05},
12493};
12494
12495static const struct tasha_reg_mask_val tasha_codec_reg_init_common_val[] = {
12496 /* Rbuckfly/R_EAR(32) */
12497 {WCD9335_CDC_CLSH_K2_MSB, 0x0F, 0x00},
12498 {WCD9335_CDC_CLSH_K2_LSB, 0xFF, 0x60},
12499 {WCD9335_CPE_SS_DMIC_CFG, 0x80, 0x00},
12500 {WCD9335_CDC_BOOST0_BOOST_CTL, 0x70, 0x50},
12501 {WCD9335_CDC_BOOST1_BOOST_CTL, 0x70, 0x50},
12502 {WCD9335_CDC_RX7_RX_PATH_CFG1, 0x08, 0x08},
12503 {WCD9335_CDC_RX8_RX_PATH_CFG1, 0x08, 0x08},
12504 {WCD9335_ANA_LO_1_2, 0x3C, 0X3C},
12505 {WCD9335_DIFF_LO_COM_SWCAP_REFBUF_FREQ, 0x70, 0x00},
12506 {WCD9335_SOC_MAD_AUDIO_CTL_2, 0x03, 0x03},
12507 {WCD9335_CDC_TOP_TOP_CFG1, 0x02, 0x02},
12508 {WCD9335_CDC_TOP_TOP_CFG1, 0x01, 0x01},
12509 {WCD9335_EAR_CMBUFF, 0x08, 0x00},
12510 {WCD9335_CDC_TX9_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
12511 {WCD9335_CDC_TX10_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
12512 {WCD9335_CDC_TX11_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
12513 {WCD9335_CDC_TX12_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
12514 {WCD9335_CDC_COMPANDER7_CTL3, 0x80, 0x80},
12515 {WCD9335_CDC_COMPANDER8_CTL3, 0x80, 0x80},
12516 {WCD9335_CDC_COMPANDER7_CTL7, 0x01, 0x01},
12517 {WCD9335_CDC_COMPANDER8_CTL7, 0x01, 0x01},
12518 {WCD9335_CDC_RX0_RX_PATH_CFG0, 0x01, 0x01},
12519 {WCD9335_CDC_RX1_RX_PATH_CFG0, 0x01, 0x01},
12520 {WCD9335_CDC_RX2_RX_PATH_CFG0, 0x01, 0x01},
12521 {WCD9335_CDC_RX3_RX_PATH_CFG0, 0x01, 0x01},
12522 {WCD9335_CDC_RX4_RX_PATH_CFG0, 0x01, 0x01},
12523 {WCD9335_CDC_RX5_RX_PATH_CFG0, 0x01, 0x01},
12524 {WCD9335_CDC_RX6_RX_PATH_CFG0, 0x01, 0x01},
12525 {WCD9335_CDC_RX7_RX_PATH_CFG0, 0x01, 0x01},
12526 {WCD9335_CDC_RX8_RX_PATH_CFG0, 0x01, 0x01},
12527 {WCD9335_CDC_RX0_RX_PATH_MIX_CFG, 0x01, 0x01},
12528 {WCD9335_CDC_RX1_RX_PATH_MIX_CFG, 0x01, 0x01},
12529 {WCD9335_CDC_RX2_RX_PATH_MIX_CFG, 0x01, 0x01},
12530 {WCD9335_CDC_RX3_RX_PATH_MIX_CFG, 0x01, 0x01},
12531 {WCD9335_CDC_RX4_RX_PATH_MIX_CFG, 0x01, 0x01},
12532 {WCD9335_CDC_RX5_RX_PATH_MIX_CFG, 0x01, 0x01},
12533 {WCD9335_CDC_RX6_RX_PATH_MIX_CFG, 0x01, 0x01},
12534 {WCD9335_CDC_RX7_RX_PATH_MIX_CFG, 0x01, 0x01},
12535 {WCD9335_CDC_RX8_RX_PATH_MIX_CFG, 0x01, 0x01},
12536 {WCD9335_VBADC_IBIAS_FE, 0x0C, 0x08},
12537};
12538
12539static const struct tasha_reg_mask_val tasha_codec_reg_init_1_x_val[] = {
12540 /* Enable TX HPF Filter & Linear Phase */
12541 {WCD9335_CDC_TX0_TX_PATH_CFG0, 0x11, 0x11},
12542 {WCD9335_CDC_TX1_TX_PATH_CFG0, 0x11, 0x11},
12543 {WCD9335_CDC_TX2_TX_PATH_CFG0, 0x11, 0x11},
12544 {WCD9335_CDC_TX3_TX_PATH_CFG0, 0x11, 0x11},
12545 {WCD9335_CDC_TX4_TX_PATH_CFG0, 0x11, 0x11},
12546 {WCD9335_CDC_TX5_TX_PATH_CFG0, 0x11, 0x11},
12547 {WCD9335_CDC_TX6_TX_PATH_CFG0, 0x11, 0x11},
12548 {WCD9335_CDC_TX7_TX_PATH_CFG0, 0x11, 0x11},
12549 {WCD9335_CDC_TX8_TX_PATH_CFG0, 0x11, 0x11},
12550 {WCD9335_CDC_RX0_RX_PATH_SEC0, 0xF8, 0xF8},
12551 {WCD9335_CDC_RX0_RX_PATH_SEC1, 0x08, 0x08},
12552 {WCD9335_CDC_RX1_RX_PATH_SEC1, 0x08, 0x08},
12553 {WCD9335_CDC_RX2_RX_PATH_SEC1, 0x08, 0x08},
12554 {WCD9335_CDC_RX3_RX_PATH_SEC1, 0x08, 0x08},
12555 {WCD9335_CDC_RX4_RX_PATH_SEC1, 0x08, 0x08},
12556 {WCD9335_CDC_RX5_RX_PATH_SEC1, 0x08, 0x08},
12557 {WCD9335_CDC_RX6_RX_PATH_SEC1, 0x08, 0x08},
12558 {WCD9335_CDC_RX7_RX_PATH_SEC1, 0x08, 0x08},
12559 {WCD9335_CDC_RX8_RX_PATH_SEC1, 0x08, 0x08},
12560 {WCD9335_CDC_RX0_RX_PATH_MIX_SEC0, 0x08, 0x08},
12561 {WCD9335_CDC_RX1_RX_PATH_MIX_SEC0, 0x08, 0x08},
12562 {WCD9335_CDC_RX2_RX_PATH_MIX_SEC0, 0x08, 0x08},
12563 {WCD9335_CDC_RX3_RX_PATH_MIX_SEC0, 0x08, 0x08},
12564 {WCD9335_CDC_RX4_RX_PATH_MIX_SEC0, 0x08, 0x08},
12565 {WCD9335_CDC_RX5_RX_PATH_MIX_SEC0, 0x08, 0x08},
12566 {WCD9335_CDC_RX6_RX_PATH_MIX_SEC0, 0x08, 0x08},
12567 {WCD9335_CDC_RX7_RX_PATH_MIX_SEC0, 0x08, 0x08},
12568 {WCD9335_CDC_RX8_RX_PATH_MIX_SEC0, 0x08, 0x08},
12569 {WCD9335_CDC_TX0_TX_PATH_SEC2, 0x01, 0x01},
12570 {WCD9335_CDC_TX1_TX_PATH_SEC2, 0x01, 0x01},
12571 {WCD9335_CDC_TX2_TX_PATH_SEC2, 0x01, 0x01},
12572 {WCD9335_CDC_TX3_TX_PATH_SEC2, 0x01, 0x01},
12573 {WCD9335_CDC_TX4_TX_PATH_SEC2, 0x01, 0x01},
12574 {WCD9335_CDC_TX5_TX_PATH_SEC2, 0x01, 0x01},
12575 {WCD9335_CDC_TX6_TX_PATH_SEC2, 0x01, 0x01},
12576 {WCD9335_CDC_TX7_TX_PATH_SEC2, 0x01, 0x01},
12577 {WCD9335_CDC_TX8_TX_PATH_SEC2, 0x01, 0x01},
12578 {WCD9335_CDC_RX3_RX_PATH_SEC0, 0xF8, 0xF0},
12579 {WCD9335_CDC_RX4_RX_PATH_SEC0, 0xF8, 0xF0},
12580 {WCD9335_CDC_RX5_RX_PATH_SEC0, 0xF8, 0xF8},
12581 {WCD9335_CDC_RX6_RX_PATH_SEC0, 0xF8, 0xF8},
12582 {WCD9335_RX_OCP_COUNT, 0xFF, 0xFF},
12583 {WCD9335_HPH_OCP_CTL, 0xF0, 0x70},
12584 {WCD9335_CPE_SS_CPAR_CFG, 0xFF, 0x00},
12585 {WCD9335_FLYBACK_VNEG_CTRL_1, 0xFF, 0x63},
12586 {WCD9335_FLYBACK_VNEG_CTRL_4, 0xFF, 0x7F},
12587 {WCD9335_CLASSH_CTRL_VCL_1, 0xFF, 0x60},
12588 {WCD9335_CLASSH_CTRL_CCL_5, 0xFF, 0x40},
12589 {WCD9335_RX_TIMER_DIV, 0xFF, 0x32},
12590 {WCD9335_SE_LO_COM2, 0xFF, 0x01},
12591 {WCD9335_MBHC_ZDET_ANA_CTL, 0x0F, 0x07},
12592 {WCD9335_RX_BIAS_HPH_PA, 0xF0, 0x60},
12593 {WCD9335_HPH_RDAC_LDO_CTL, 0x88, 0x88},
12594 {WCD9335_HPH_L_EN, 0x20, 0x20},
12595 {WCD9335_HPH_R_EN, 0x20, 0x20},
12596 {WCD9335_DIFF_LO_CORE_OUT_PROG, 0xFC, 0xD8},
12597 {WCD9335_CDC_RX5_RX_PATH_SEC3, 0xBD, 0xBD},
12598 {WCD9335_CDC_RX6_RX_PATH_SEC3, 0xBD, 0xBD},
12599 {WCD9335_DIFF_LO_COM_PA_FREQ, 0x70, 0x40},
12600};
12601
12602static void tasha_update_reg_reset_values(struct snd_soc_codec *codec)
12603{
12604 u32 i;
12605 struct wcd9xxx *tasha_core = dev_get_drvdata(codec->dev->parent);
12606
12607 if (TASHA_IS_1_1(tasha_core)) {
12608 for (i = 0; i < ARRAY_SIZE(tasha_reg_update_reset_val_1_1);
12609 i++)
12610 snd_soc_write(codec,
12611 tasha_reg_update_reset_val_1_1[i].reg,
12612 tasha_reg_update_reset_val_1_1[i].val);
12613 }
12614}
12615
12616static void tasha_codec_init_reg(struct snd_soc_codec *codec)
12617{
12618 u32 i;
12619 struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent);
12620
12621 for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_init_common_val); i++)
12622 snd_soc_update_bits(codec,
12623 tasha_codec_reg_init_common_val[i].reg,
12624 tasha_codec_reg_init_common_val[i].mask,
12625 tasha_codec_reg_init_common_val[i].val);
12626
12627 if (TASHA_IS_1_1(wcd9xxx) ||
12628 TASHA_IS_1_0(wcd9xxx))
12629 for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_init_1_x_val); i++)
12630 snd_soc_update_bits(codec,
12631 tasha_codec_reg_init_1_x_val[i].reg,
12632 tasha_codec_reg_init_1_x_val[i].mask,
12633 tasha_codec_reg_init_1_x_val[i].val);
12634
12635 if (TASHA_IS_1_1(wcd9xxx)) {
12636 for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_init_val_1_1); i++)
12637 snd_soc_update_bits(codec,
12638 tasha_codec_reg_init_val_1_1[i].reg,
12639 tasha_codec_reg_init_val_1_1[i].mask,
12640 tasha_codec_reg_init_val_1_1[i].val);
12641 } else if (TASHA_IS_1_0(wcd9xxx)) {
12642 for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_init_val_1_0); i++)
12643 snd_soc_update_bits(codec,
12644 tasha_codec_reg_init_val_1_0[i].reg,
12645 tasha_codec_reg_init_val_1_0[i].mask,
12646 tasha_codec_reg_init_val_1_0[i].val);
12647 } else if (TASHA_IS_2_0(wcd9xxx)) {
12648 for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_init_val_2_0); i++)
12649 snd_soc_update_bits(codec,
12650 tasha_codec_reg_init_val_2_0[i].reg,
12651 tasha_codec_reg_init_val_2_0[i].mask,
12652 tasha_codec_reg_init_val_2_0[i].val);
12653 }
12654}
12655
12656static void tasha_update_reg_defaults(struct tasha_priv *tasha)
12657{
12658 u32 i;
12659 struct wcd9xxx *wcd9xxx;
12660
12661 wcd9xxx = tasha->wcd9xxx;
12662 for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_defaults); i++)
12663 regmap_update_bits(wcd9xxx->regmap,
12664 tasha_codec_reg_defaults[i].reg,
12665 tasha_codec_reg_defaults[i].mask,
12666 tasha_codec_reg_defaults[i].val);
12667
12668 tasha->intf_type = wcd9xxx_get_intf_type();
12669 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C)
12670 for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_i2c_defaults); i++)
12671 regmap_update_bits(wcd9xxx->regmap,
12672 tasha_codec_reg_i2c_defaults[i].reg,
12673 tasha_codec_reg_i2c_defaults[i].mask,
12674 tasha_codec_reg_i2c_defaults[i].val);
12675
12676}
12677
12678static void tasha_slim_interface_init_reg(struct snd_soc_codec *codec)
12679{
12680 int i;
12681 struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec);
12682
12683 for (i = 0; i < WCD9XXX_SLIM_NUM_PORT_REG; i++)
12684 wcd9xxx_interface_reg_write(priv->wcd9xxx,
12685 TASHA_SLIM_PGD_PORT_INT_EN0 + i,
12686 0xFF);
12687}
12688
12689static irqreturn_t tasha_slimbus_irq(int irq, void *data)
12690{
12691 struct tasha_priv *priv = data;
12692 unsigned long status = 0;
12693 int i, j, port_id, k;
12694 u32 bit;
12695 u8 val, int_val = 0;
12696 bool tx, cleared;
12697 unsigned short reg = 0;
12698
12699 for (i = TASHA_SLIM_PGD_PORT_INT_STATUS_RX_0, j = 0;
12700 i <= TASHA_SLIM_PGD_PORT_INT_STATUS_TX_1; i++, j++) {
12701 val = wcd9xxx_interface_reg_read(priv->wcd9xxx, i);
12702 status |= ((u32)val << (8 * j));
12703 }
12704
12705 for_each_set_bit(j, &status, 32) {
12706 tx = (j >= 16 ? true : false);
12707 port_id = (tx ? j - 16 : j);
12708 val = wcd9xxx_interface_reg_read(priv->wcd9xxx,
12709 TASHA_SLIM_PGD_PORT_INT_RX_SOURCE0 + j);
12710 if (val) {
12711 if (!tx)
12712 reg = TASHA_SLIM_PGD_PORT_INT_EN0 +
12713 (port_id / 8);
12714 else
12715 reg = TASHA_SLIM_PGD_PORT_INT_TX_EN0 +
12716 (port_id / 8);
12717 int_val = wcd9xxx_interface_reg_read(
12718 priv->wcd9xxx, reg);
12719 /*
12720 * Ignore interrupts for ports for which the
12721 * interrupts are not specifically enabled.
12722 */
12723 if (!(int_val & (1 << (port_id % 8))))
12724 continue;
12725 }
12726 if (val & TASHA_SLIM_IRQ_OVERFLOW)
12727 pr_err_ratelimited(
12728 "%s: overflow error on %s port %d, value %x\n",
12729 __func__, (tx ? "TX" : "RX"), port_id, val);
12730 if (val & TASHA_SLIM_IRQ_UNDERFLOW)
12731 pr_err_ratelimited(
12732 "%s: underflow error on %s port %d, value %x\n",
12733 __func__, (tx ? "TX" : "RX"), port_id, val);
12734 if ((val & TASHA_SLIM_IRQ_OVERFLOW) ||
12735 (val & TASHA_SLIM_IRQ_UNDERFLOW)) {
12736 if (!tx)
12737 reg = TASHA_SLIM_PGD_PORT_INT_EN0 +
12738 (port_id / 8);
12739 else
12740 reg = TASHA_SLIM_PGD_PORT_INT_TX_EN0 +
12741 (port_id / 8);
12742 int_val = wcd9xxx_interface_reg_read(
12743 priv->wcd9xxx, reg);
12744 if (int_val & (1 << (port_id % 8))) {
12745 int_val = int_val ^ (1 << (port_id % 8));
12746 wcd9xxx_interface_reg_write(priv->wcd9xxx,
12747 reg, int_val);
12748 }
12749 }
12750 if (val & TASHA_SLIM_IRQ_PORT_CLOSED) {
12751 /*
12752 * INT SOURCE register starts from RX to TX
12753 * but port number in the ch_mask is in opposite way
12754 */
12755 bit = (tx ? j - 16 : j + 16);
12756 pr_debug("%s: %s port %d closed value %x, bit %u\n",
12757 __func__, (tx ? "TX" : "RX"), port_id, val,
12758 bit);
12759 for (k = 0, cleared = false; k < NUM_CODEC_DAIS; k++) {
12760 pr_debug("%s: priv->dai[%d].ch_mask = 0x%lx\n",
12761 __func__, k, priv->dai[k].ch_mask);
12762 if (test_and_clear_bit(bit,
12763 &priv->dai[k].ch_mask)) {
12764 cleared = true;
12765 if (!priv->dai[k].ch_mask)
12766 wake_up(&priv->dai[k].dai_wait);
12767 /*
12768 * There are cases when multiple DAIs
12769 * might be using the same slimbus
12770 * channel. Hence don't break here.
12771 */
12772 }
12773 }
12774 WARN(!cleared,
12775 "Couldn't find slimbus %s port %d for closing\n",
12776 (tx ? "TX" : "RX"), port_id);
12777 }
12778 wcd9xxx_interface_reg_write(priv->wcd9xxx,
12779 TASHA_SLIM_PGD_PORT_INT_CLR_RX_0 +
12780 (j / 8),
12781 1 << (j % 8));
12782 }
12783
12784 return IRQ_HANDLED;
12785}
12786
12787static int tasha_setup_irqs(struct tasha_priv *tasha)
12788{
12789 int ret = 0;
12790 struct snd_soc_codec *codec = tasha->codec;
12791 struct wcd9xxx *wcd9xxx = tasha->wcd9xxx;
12792 struct wcd9xxx_core_resource *core_res =
12793 &wcd9xxx->core_res;
12794
12795 ret = wcd9xxx_request_irq(core_res, WCD9XXX_IRQ_SLIMBUS,
12796 tasha_slimbus_irq, "SLIMBUS Slave", tasha);
12797 if (ret)
12798 pr_err("%s: Failed to request irq %d\n", __func__,
12799 WCD9XXX_IRQ_SLIMBUS);
12800 else
12801 tasha_slim_interface_init_reg(codec);
12802
12803 return ret;
12804}
12805
12806static void tasha_init_slim_slave_cfg(struct snd_soc_codec *codec)
12807{
12808 struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec);
12809 struct afe_param_cdc_slimbus_slave_cfg *cfg;
12810 struct wcd9xxx *wcd9xxx = priv->wcd9xxx;
12811 uint64_t eaddr = 0;
12812
12813 cfg = &priv->slimbus_slave_cfg;
12814 cfg->minor_version = 1;
12815 cfg->tx_slave_port_offset = 0;
12816 cfg->rx_slave_port_offset = 16;
12817
12818 memcpy(&eaddr, &wcd9xxx->slim->e_addr, sizeof(wcd9xxx->slim->e_addr));
12819 WARN_ON(sizeof(wcd9xxx->slim->e_addr) != 6);
12820 cfg->device_enum_addr_lsw = eaddr & 0xFFFFFFFF;
12821 cfg->device_enum_addr_msw = eaddr >> 32;
12822
12823 dev_dbg(codec->dev, "%s: slimbus logical address 0x%llx\n",
12824 __func__, eaddr);
12825}
12826
12827static void tasha_cleanup_irqs(struct tasha_priv *tasha)
12828{
12829 struct wcd9xxx *wcd9xxx = tasha->wcd9xxx;
12830 struct wcd9xxx_core_resource *core_res =
12831 &wcd9xxx->core_res;
12832
12833 wcd9xxx_free_irq(core_res, WCD9XXX_IRQ_SLIMBUS, tasha);
12834}
12835
12836static int tasha_handle_pdata(struct tasha_priv *tasha,
12837 struct wcd9xxx_pdata *pdata)
12838{
12839 struct snd_soc_codec *codec = tasha->codec;
12840 u8 dmic_ctl_val, mad_dmic_ctl_val;
12841 u8 anc_ctl_value;
12842 u32 def_dmic_rate, dmic_clk_drv;
12843 int vout_ctl_1, vout_ctl_2, vout_ctl_3, vout_ctl_4;
12844 int rc = 0;
12845
12846 if (!pdata) {
12847 dev_err(codec->dev, "%s: NULL pdata\n", __func__);
12848 return -ENODEV;
12849 }
12850
12851 /* set micbias voltage */
12852 vout_ctl_1 = wcd9335_get_micb_vout_ctl_val(pdata->micbias.micb1_mv);
12853 vout_ctl_2 = wcd9335_get_micb_vout_ctl_val(pdata->micbias.micb2_mv);
12854 vout_ctl_3 = wcd9335_get_micb_vout_ctl_val(pdata->micbias.micb3_mv);
12855 vout_ctl_4 = wcd9335_get_micb_vout_ctl_val(pdata->micbias.micb4_mv);
Xiaoyu Ye1a2d8bd92017-01-31 18:54:15 -080012856 if (vout_ctl_1 < 0 || vout_ctl_2 < 0 ||
12857 vout_ctl_3 < 0 || vout_ctl_4 < 0) {
Banajit Goswamide8271c2017-01-18 00:28:59 -080012858 rc = -EINVAL;
12859 goto done;
12860 }
12861 snd_soc_update_bits(codec, WCD9335_ANA_MICB1, 0x3F, vout_ctl_1);
12862 snd_soc_update_bits(codec, WCD9335_ANA_MICB2, 0x3F, vout_ctl_2);
12863 snd_soc_update_bits(codec, WCD9335_ANA_MICB3, 0x3F, vout_ctl_3);
12864 snd_soc_update_bits(codec, WCD9335_ANA_MICB4, 0x3F, vout_ctl_4);
12865
12866 /* Set the DMIC sample rate */
12867 switch (pdata->mclk_rate) {
12868 case TASHA_MCLK_CLK_9P6MHZ:
12869 def_dmic_rate = WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ;
12870 break;
12871 case TASHA_MCLK_CLK_12P288MHZ:
12872 def_dmic_rate = WCD9XXX_DMIC_SAMPLE_RATE_4P096MHZ;
12873 break;
12874 default:
12875 /* should never happen */
12876 dev_err(codec->dev, "%s: Invalid mclk_rate %d\n",
12877 __func__, pdata->mclk_rate);
12878 rc = -EINVAL;
12879 goto done;
12880 };
12881
12882 if (pdata->dmic_sample_rate ==
12883 WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED) {
12884 dev_info(codec->dev, "%s: dmic_rate invalid default = %d\n",
12885 __func__, def_dmic_rate);
12886 pdata->dmic_sample_rate = def_dmic_rate;
12887 }
12888 if (pdata->mad_dmic_sample_rate ==
12889 WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED) {
12890 dev_info(codec->dev, "%s: mad_dmic_rate invalid default = %d\n",
12891 __func__, def_dmic_rate);
12892 /*
12893 * use dmic_sample_rate as the default for MAD
12894 * if mad dmic sample rate is undefined
12895 */
12896 pdata->mad_dmic_sample_rate = pdata->dmic_sample_rate;
12897 }
12898 if (pdata->ecpp_dmic_sample_rate ==
12899 WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED) {
12900 dev_info(codec->dev,
12901 "%s: ecpp_dmic_rate invalid default = %d\n",
12902 __func__, def_dmic_rate);
12903 /*
12904 * use dmic_sample_rate as the default for ECPP DMIC
12905 * if ecpp dmic sample rate is undefined
12906 */
12907 pdata->ecpp_dmic_sample_rate = pdata->dmic_sample_rate;
12908 }
12909
12910 if (pdata->dmic_clk_drv ==
12911 WCD9XXX_DMIC_CLK_DRIVE_UNDEFINED) {
12912 pdata->dmic_clk_drv = WCD9335_DMIC_CLK_DRIVE_DEFAULT;
12913 dev_info(codec->dev,
12914 "%s: dmic_clk_strength invalid, default = %d\n",
12915 __func__, pdata->dmic_clk_drv);
12916 }
12917
12918 switch (pdata->dmic_clk_drv) {
12919 case 2:
12920 dmic_clk_drv = 0;
12921 break;
12922 case 4:
12923 dmic_clk_drv = 1;
12924 break;
12925 case 8:
12926 dmic_clk_drv = 2;
12927 break;
12928 case 16:
12929 dmic_clk_drv = 3;
12930 break;
12931 default:
12932 dev_err(codec->dev,
12933 "%s: invalid dmic_clk_drv %d, using default\n",
12934 __func__, pdata->dmic_clk_drv);
12935 dmic_clk_drv = 0;
12936 break;
12937 }
12938
12939 snd_soc_update_bits(codec, WCD9335_TEST_DEBUG_PAD_DRVCTL,
12940 0x0C, dmic_clk_drv << 2);
12941
12942 /*
12943 * Default the DMIC clk rates to mad_dmic_sample_rate,
12944 * whereas, the anc/txfe dmic rates to dmic_sample_rate
12945 * since the anc/txfe are independent of mad block.
12946 */
12947 mad_dmic_ctl_val = tasha_get_dmic_clk_val(tasha->codec,
12948 pdata->mclk_rate,
12949 pdata->mad_dmic_sample_rate);
12950 snd_soc_update_bits(codec, WCD9335_CPE_SS_DMIC0_CTL,
12951 0x0E, mad_dmic_ctl_val << 1);
12952 snd_soc_update_bits(codec, WCD9335_CPE_SS_DMIC1_CTL,
12953 0x0E, mad_dmic_ctl_val << 1);
12954 snd_soc_update_bits(codec, WCD9335_CPE_SS_DMIC2_CTL,
12955 0x0E, mad_dmic_ctl_val << 1);
12956
12957 dmic_ctl_val = tasha_get_dmic_clk_val(tasha->codec,
12958 pdata->mclk_rate,
12959 pdata->dmic_sample_rate);
12960
12961 if (dmic_ctl_val == WCD9335_DMIC_CLK_DIV_2)
12962 anc_ctl_value = WCD9335_ANC_DMIC_X2_FULL_RATE;
12963 else
12964 anc_ctl_value = WCD9335_ANC_DMIC_X2_HALF_RATE;
12965
12966 snd_soc_update_bits(codec, WCD9335_CDC_ANC0_MODE_2_CTL,
12967 0x40, anc_ctl_value << 6);
12968 snd_soc_update_bits(codec, WCD9335_CDC_ANC0_MODE_2_CTL,
12969 0x20, anc_ctl_value << 5);
12970 snd_soc_update_bits(codec, WCD9335_CDC_ANC1_MODE_2_CTL,
12971 0x40, anc_ctl_value << 6);
12972 snd_soc_update_bits(codec, WCD9335_CDC_ANC1_MODE_2_CTL,
12973 0x20, anc_ctl_value << 5);
12974done:
12975 return rc;
12976}
12977
12978static struct wcd_cpe_core *tasha_codec_get_cpe_core(
12979 struct snd_soc_codec *codec)
12980{
12981 struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec);
12982
12983 return priv->cpe_core;
12984}
12985
12986static int tasha_codec_cpe_fll_update_divider(
12987 struct snd_soc_codec *codec, u32 cpe_fll_rate)
12988{
12989 struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent);
12990 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
12991
12992 u32 div_val = 0, l_val = 0;
12993 u32 computed_cpe_fll;
12994
12995 if (cpe_fll_rate != CPE_FLL_CLK_75MHZ &&
12996 cpe_fll_rate != CPE_FLL_CLK_150MHZ) {
12997 dev_err(codec->dev,
12998 "%s: Invalid CPE fll rate request %u\n",
12999 __func__, cpe_fll_rate);
13000 return -EINVAL;
13001 }
13002
13003 if (wcd9xxx->mclk_rate == TASHA_MCLK_CLK_12P288MHZ) {
13004 /* update divider to 10 and enable 5x divider */
13005 snd_soc_write(codec, WCD9335_CPE_FLL_USER_CTL_1,
13006 0x55);
13007 div_val = 10;
13008 } else if (wcd9xxx->mclk_rate == TASHA_MCLK_CLK_9P6MHZ) {
13009 /* update divider to 8 and enable 2x divider */
13010 snd_soc_update_bits(codec, WCD9335_CPE_FLL_USER_CTL_0,
13011 0x7C, 0x70);
13012 snd_soc_update_bits(codec, WCD9335_CPE_FLL_USER_CTL_1,
13013 0xE0, 0x20);
13014 div_val = 8;
13015 } else {
13016 dev_err(codec->dev,
13017 "%s: Invalid MCLK rate %u\n",
13018 __func__, wcd9xxx->mclk_rate);
13019 return -EINVAL;
13020 }
13021
13022 l_val = ((cpe_fll_rate / 1000) * div_val) /
13023 (wcd9xxx->mclk_rate / 1000);
13024
13025 /* If l_val was integer truncated, increment l_val once */
13026 computed_cpe_fll = (wcd9xxx->mclk_rate / div_val) * l_val;
13027 if (computed_cpe_fll < cpe_fll_rate)
13028 l_val++;
13029
13030
13031 /* update L value LSB and MSB */
13032 snd_soc_write(codec, WCD9335_CPE_FLL_L_VAL_CTL_0,
13033 (l_val & 0xFF));
13034 snd_soc_write(codec, WCD9335_CPE_FLL_L_VAL_CTL_1,
13035 ((l_val >> 8) & 0xFF));
13036
13037 tasha->current_cpe_clk_freq = cpe_fll_rate;
13038 dev_dbg(codec->dev,
13039 "%s: updated l_val to %u for cpe_clk %u and mclk %u\n",
13040 __func__, l_val, cpe_fll_rate, wcd9xxx->mclk_rate);
13041
13042 return 0;
13043}
13044
13045static int __tasha_cdc_change_cpe_clk(struct snd_soc_codec *codec,
13046 u32 clk_freq)
13047{
13048 int ret = 0;
13049 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
13050
13051 if (!tasha_cdc_is_svs_enabled(tasha)) {
13052 dev_dbg(codec->dev,
13053 "%s: SVS not enabled or tasha is not 2p0, return\n",
13054 __func__);
13055 return 0;
13056 }
13057 dev_dbg(codec->dev, "%s: clk_freq = %u\n", __func__, clk_freq);
13058
13059 if (clk_freq == CPE_FLL_CLK_75MHZ) {
13060 /* Change to SVS */
13061 snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE,
13062 0x08, 0x08);
13063 if (tasha_codec_cpe_fll_update_divider(codec, clk_freq)) {
13064 ret = -EINVAL;
13065 goto done;
13066 }
13067
13068 snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE,
13069 0x10, 0x10);
13070
13071 clear_bit(CPE_NOMINAL, &tasha->status_mask);
13072 tasha_codec_update_sido_voltage(tasha, sido_buck_svs_voltage);
13073
13074 } else if (clk_freq == CPE_FLL_CLK_150MHZ) {
13075 /* change to nominal */
13076 snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE,
13077 0x08, 0x08);
13078
13079 set_bit(CPE_NOMINAL, &tasha->status_mask);
13080 tasha_codec_update_sido_voltage(tasha, SIDO_VOLTAGE_NOMINAL_MV);
13081
13082 if (tasha_codec_cpe_fll_update_divider(codec, clk_freq)) {
13083 ret = -EINVAL;
13084 goto done;
13085 }
13086 snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE,
13087 0x10, 0x10);
13088 } else {
13089 dev_err(codec->dev,
13090 "%s: Invalid clk_freq request %d for CPE FLL\n",
13091 __func__, clk_freq);
13092 ret = -EINVAL;
13093 }
13094
13095done:
13096 snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE,
13097 0x10, 0x00);
13098 snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE,
13099 0x08, 0x00);
13100 return ret;
13101}
13102
13103
13104static int tasha_codec_cpe_fll_enable(struct snd_soc_codec *codec,
13105 bool enable)
13106{
13107 struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent);
13108 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
13109 u8 clk_sel_reg_val = 0x00;
13110
13111 dev_dbg(codec->dev, "%s: enable = %s\n",
13112 __func__, enable ? "true" : "false");
13113
13114 if (enable) {
13115 if (tasha_cdc_is_svs_enabled(tasha)) {
13116 /* FLL enable is always at SVS */
13117 if (__tasha_cdc_change_cpe_clk(codec,
13118 CPE_FLL_CLK_75MHZ)) {
13119 dev_err(codec->dev,
13120 "%s: clk change to %d failed\n",
13121 __func__, CPE_FLL_CLK_75MHZ);
13122 return -EINVAL;
13123 }
13124 } else {
13125 if (tasha_codec_cpe_fll_update_divider(codec,
13126 CPE_FLL_CLK_75MHZ)) {
13127 dev_err(codec->dev,
13128 "%s: clk change to %d failed\n",
13129 __func__, CPE_FLL_CLK_75MHZ);
13130 return -EINVAL;
13131 }
13132 }
13133
13134 if (TASHA_IS_1_0(wcd9xxx)) {
13135 tasha_cdc_mclk_enable(codec, true, false);
13136 clk_sel_reg_val = 0x02;
13137 }
13138
13139 /* Setup CPE reference clk */
13140 snd_soc_update_bits(codec, WCD9335_ANA_CLK_TOP,
13141 0x02, clk_sel_reg_val);
13142
13143 /* enable CPE FLL reference clk */
13144 snd_soc_update_bits(codec, WCD9335_ANA_CLK_TOP,
13145 0x01, 0x01);
13146
13147 /* program the PLL */
13148 snd_soc_update_bits(codec, WCD9335_CPE_FLL_USER_CTL_0,
13149 0x01, 0x01);
13150
13151 /* TEST clk setting */
13152 snd_soc_update_bits(codec, WCD9335_CPE_FLL_TEST_CTL_0,
13153 0x80, 0x80);
13154 /* set FLL mode to HW controlled */
13155 snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE,
13156 0x60, 0x00);
13157 snd_soc_write(codec, WCD9335_CPE_FLL_FLL_MODE, 0x80);
13158 } else {
13159 /* disable CPE FLL reference clk */
13160 snd_soc_update_bits(codec, WCD9335_ANA_CLK_TOP,
13161 0x01, 0x00);
13162 /* undo TEST clk setting */
13163 snd_soc_update_bits(codec, WCD9335_CPE_FLL_TEST_CTL_0,
13164 0x80, 0x00);
13165 /* undo FLL mode to HW control */
13166 snd_soc_write(codec, WCD9335_CPE_FLL_FLL_MODE, 0x00);
13167 snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE,
13168 0x60, 0x20);
13169 /* undo the PLL */
13170 snd_soc_update_bits(codec, WCD9335_CPE_FLL_USER_CTL_0,
13171 0x01, 0x00);
13172
13173 if (TASHA_IS_1_0(wcd9xxx))
13174 tasha_cdc_mclk_enable(codec, false, false);
13175
13176 /*
13177 * FLL could get disabled while at nominal,
13178 * scale it back to SVS
13179 */
13180 if (tasha_cdc_is_svs_enabled(tasha))
13181 __tasha_cdc_change_cpe_clk(codec,
13182 CPE_FLL_CLK_75MHZ);
13183 }
13184
13185 return 0;
13186
13187}
13188
13189static void tasha_cdc_query_cpe_clk_plan(void *data,
13190 struct cpe_svc_cfg_clk_plan *clk_freq)
13191{
13192 struct snd_soc_codec *codec = data;
13193 struct tasha_priv *tasha;
13194 u32 cpe_clk_khz;
13195
13196 if (!codec) {
13197 pr_err("%s: Invalid codec handle\n",
13198 __func__);
13199 return;
13200 }
13201
13202 tasha = snd_soc_codec_get_drvdata(codec);
13203 cpe_clk_khz = tasha->current_cpe_clk_freq / 1000;
13204
13205 dev_dbg(codec->dev,
13206 "%s: current_clk_freq = %u\n",
13207 __func__, tasha->current_cpe_clk_freq);
13208
13209 clk_freq->current_clk_feq = cpe_clk_khz;
13210 clk_freq->num_clk_freqs = 2;
13211
13212 if (tasha_cdc_is_svs_enabled(tasha)) {
13213 clk_freq->clk_freqs[0] = CPE_FLL_CLK_75MHZ / 1000;
13214 clk_freq->clk_freqs[1] = CPE_FLL_CLK_150MHZ / 1000;
13215 } else {
13216 clk_freq->clk_freqs[0] = CPE_FLL_CLK_75MHZ;
13217 clk_freq->clk_freqs[1] = CPE_FLL_CLK_150MHZ;
13218 }
13219}
13220
13221static void tasha_cdc_change_cpe_clk(void *data,
13222 u32 clk_freq)
13223{
13224 struct snd_soc_codec *codec = data;
13225 struct tasha_priv *tasha;
13226 u32 cpe_clk_khz, req_freq = 0;
13227
13228 if (!codec) {
13229 pr_err("%s: Invalid codec handle\n",
13230 __func__);
13231 return;
13232 }
13233
13234 tasha = snd_soc_codec_get_drvdata(codec);
13235 cpe_clk_khz = tasha->current_cpe_clk_freq / 1000;
13236
13237 if (tasha_cdc_is_svs_enabled(tasha)) {
13238 if ((clk_freq * 1000) <= CPE_FLL_CLK_75MHZ)
13239 req_freq = CPE_FLL_CLK_75MHZ;
13240 else
13241 req_freq = CPE_FLL_CLK_150MHZ;
13242 }
13243
13244 dev_dbg(codec->dev,
13245 "%s: requested clk_freq = %u, current clk_freq = %u\n",
13246 __func__, clk_freq * 1000,
13247 tasha->current_cpe_clk_freq);
13248
13249 if (tasha_cdc_is_svs_enabled(tasha)) {
13250 if (__tasha_cdc_change_cpe_clk(codec, req_freq))
13251 dev_err(codec->dev,
13252 "%s: clock/voltage scaling failed\n",
13253 __func__);
13254 }
13255}
13256
13257static int tasha_codec_slim_reserve_bw(struct snd_soc_codec *codec,
13258 u32 bw_ops, bool commit)
13259{
13260 struct wcd9xxx *wcd9xxx;
13261
13262 if (!codec) {
13263 pr_err("%s: Invalid handle to codec\n",
13264 __func__);
13265 return -EINVAL;
13266 }
13267
13268 wcd9xxx = dev_get_drvdata(codec->dev->parent);
13269
13270 if (!wcd9xxx) {
13271 dev_err(codec->dev, "%s: Invalid parent drv_data\n",
13272 __func__);
13273 return -EINVAL;
13274 }
13275
13276 return wcd9xxx_slim_reserve_bw(wcd9xxx, bw_ops, commit);
13277}
13278
13279static int tasha_codec_vote_max_bw(struct snd_soc_codec *codec,
13280 bool vote)
13281{
13282 u32 bw_ops;
13283 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
13284
13285 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C)
13286 return 0;
13287
13288 if (vote)
13289 bw_ops = SLIM_BW_CLK_GEAR_9;
13290 else
13291 bw_ops = SLIM_BW_UNVOTE;
13292
13293 return tasha_codec_slim_reserve_bw(codec,
13294 bw_ops, true);
13295}
13296
13297static int tasha_cpe_err_irq_control(struct snd_soc_codec *codec,
13298 enum cpe_err_irq_cntl_type cntl_type, u8 *status)
13299{
13300 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
13301 u8 irq_bits;
13302
13303 if (TASHA_IS_2_0(tasha->wcd9xxx))
13304 irq_bits = 0xFF;
13305 else
13306 irq_bits = 0x3F;
13307
13308 if (status)
13309 irq_bits = (*status) & irq_bits;
13310
13311 switch (cntl_type) {
13312 case CPE_ERR_IRQ_MASK:
13313 snd_soc_update_bits(codec,
13314 WCD9335_CPE_SS_SS_ERROR_INT_MASK,
13315 irq_bits, irq_bits);
13316 break;
13317 case CPE_ERR_IRQ_UNMASK:
13318 snd_soc_update_bits(codec,
13319 WCD9335_CPE_SS_SS_ERROR_INT_MASK,
13320 irq_bits, 0x00);
13321 break;
13322 case CPE_ERR_IRQ_CLEAR:
13323 snd_soc_write(codec, WCD9335_CPE_SS_SS_ERROR_INT_CLEAR,
13324 irq_bits);
13325 break;
13326 case CPE_ERR_IRQ_STATUS:
13327 if (!status)
13328 return -EINVAL;
13329 *status = snd_soc_read(codec,
13330 WCD9335_CPE_SS_SS_ERROR_INT_STATUS);
13331 break;
13332 }
13333
13334 return 0;
13335}
13336
13337static const struct wcd_cpe_cdc_cb cpe_cb = {
13338 .cdc_clk_en = tasha_codec_internal_rco_ctrl,
13339 .cpe_clk_en = tasha_codec_cpe_fll_enable,
13340 .get_afe_out_port_id = tasha_codec_get_mad_port_id,
13341 .lab_cdc_ch_ctl = tasha_codec_enable_slimtx_mad,
13342 .cdc_ext_clk = tasha_cdc_mclk_enable,
13343 .bus_vote_bw = tasha_codec_vote_max_bw,
13344 .cpe_err_irq_control = tasha_cpe_err_irq_control,
13345};
13346
13347static struct cpe_svc_init_param cpe_svc_params = {
13348 .version = CPE_SVC_INIT_PARAM_V1,
13349 .query_freq_plans_cb = tasha_cdc_query_cpe_clk_plan,
13350 .change_freq_plan_cb = tasha_cdc_change_cpe_clk,
13351};
13352
13353static int tasha_cpe_initialize(struct snd_soc_codec *codec)
13354{
13355 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
13356 struct wcd_cpe_params cpe_params;
13357
13358 memset(&cpe_params, 0,
13359 sizeof(struct wcd_cpe_params));
13360 cpe_params.codec = codec;
13361 cpe_params.get_cpe_core = tasha_codec_get_cpe_core;
13362 cpe_params.cdc_cb = &cpe_cb;
13363 cpe_params.dbg_mode = cpe_debug_mode;
13364 cpe_params.cdc_major_ver = CPE_SVC_CODEC_WCD9335;
13365 cpe_params.cdc_minor_ver = CPE_SVC_CODEC_V1P0;
13366 cpe_params.cdc_id = CPE_SVC_CODEC_WCD9335;
13367
13368 cpe_params.cdc_irq_info.cpe_engine_irq =
13369 WCD9335_IRQ_SVA_OUTBOX1;
13370 cpe_params.cdc_irq_info.cpe_err_irq =
13371 WCD9335_IRQ_SVA_ERROR;
13372 cpe_params.cdc_irq_info.cpe_fatal_irqs =
13373 TASHA_CPE_FATAL_IRQS;
13374
13375 cpe_svc_params.context = codec;
13376 cpe_params.cpe_svc_params = &cpe_svc_params;
13377
13378 tasha->cpe_core = wcd_cpe_init("cpe_9335", codec,
13379 &cpe_params);
13380 if (IS_ERR_OR_NULL(tasha->cpe_core)) {
13381 dev_err(codec->dev,
13382 "%s: Failed to enable CPE\n",
13383 __func__);
13384 return -EINVAL;
13385 }
13386
13387 return 0;
13388}
13389
13390static const struct wcd_resmgr_cb tasha_resmgr_cb = {
13391 .cdc_rco_ctrl = __tasha_codec_internal_rco_ctrl,
13392};
13393
13394static int tasha_device_down(struct wcd9xxx *wcd9xxx)
13395{
13396 struct snd_soc_codec *codec;
13397 struct tasha_priv *priv;
13398 int count;
13399 int i = 0;
13400
13401 codec = (struct snd_soc_codec *)(wcd9xxx->ssr_priv);
13402 priv = snd_soc_codec_get_drvdata(codec);
13403 wcd_cpe_ssr_event(priv->cpe_core, WCD_CPE_BUS_DOWN_EVENT);
13404 for (i = 0; i < priv->nr; i++)
13405 swrm_wcd_notify(priv->swr_ctrl_data[i].swr_pdev,
13406 SWR_DEVICE_DOWN, NULL);
13407 snd_soc_card_change_online_state(codec->component.card, 0);
13408 for (count = 0; count < NUM_CODEC_DAIS; count++)
13409 priv->dai[count].bus_down_in_recovery = true;
13410
13411 priv->resmgr->sido_input_src = SIDO_SOURCE_INTERNAL;
13412
13413 return 0;
13414}
13415
13416static int tasha_post_reset_cb(struct wcd9xxx *wcd9xxx)
13417{
13418 int i, ret = 0;
13419 struct wcd9xxx *control;
13420 struct snd_soc_codec *codec;
13421 struct tasha_priv *tasha;
13422 struct wcd9xxx_pdata *pdata;
13423
13424 codec = (struct snd_soc_codec *)(wcd9xxx->ssr_priv);
13425 tasha = snd_soc_codec_get_drvdata(codec);
13426 control = dev_get_drvdata(codec->dev->parent);
13427
13428 wcd9xxx_set_power_state(tasha->wcd9xxx,
13429 WCD_REGION_POWER_COLLAPSE_REMOVE,
13430 WCD9XXX_DIG_CORE_REGION_1);
13431
13432 mutex_lock(&tasha->codec_mutex);
13433
13434 tasha_slimbus_slave_port_cfg.slave_dev_intfdev_la =
13435 control->slim_slave->laddr;
13436 tasha_slimbus_slave_port_cfg.slave_dev_pgd_la =
13437 control->slim->laddr;
13438 tasha_init_slim_slave_cfg(codec);
13439 if (tasha->machine_codec_event_cb)
13440 tasha->machine_codec_event_cb(codec,
13441 WCD9335_CODEC_EVENT_CODEC_UP);
13442 snd_soc_card_change_online_state(codec->component.card, 1);
13443
13444 /* Class-H Init*/
13445 wcd_clsh_init(&tasha->clsh_d);
13446 /* Default HPH Mode to Class-H HiFi */
13447 tasha->hph_mode = CLS_H_HIFI;
13448
13449 for (i = 0; i < TASHA_MAX_MICBIAS; i++)
13450 tasha->micb_ref[i] = 0;
13451
13452 tasha_update_reg_defaults(tasha);
13453
13454 tasha->codec = codec;
13455 for (i = 0; i < COMPANDER_MAX; i++)
13456 tasha->comp_enabled[i] = 0;
13457
13458 dev_dbg(codec->dev, "%s: MCLK Rate = %x\n",
13459 __func__, control->mclk_rate);
13460
13461 if (control->mclk_rate == TASHA_MCLK_CLK_12P288MHZ)
13462 snd_soc_update_bits(codec, WCD9335_CODEC_RPM_CLK_MCLK_CFG,
13463 0x03, 0x00);
13464 else if (control->mclk_rate == TASHA_MCLK_CLK_9P6MHZ)
13465 snd_soc_update_bits(codec, WCD9335_CODEC_RPM_CLK_MCLK_CFG,
13466 0x03, 0x01);
13467 tasha_codec_init_reg(codec);
13468
13469 wcd_resmgr_post_ssr_v2(tasha->resmgr);
13470
13471 tasha_enable_efuse_sensing(codec);
13472
13473 regcache_mark_dirty(codec->component.regmap);
13474 regcache_sync(codec->component.regmap);
13475
13476 pdata = dev_get_platdata(codec->dev->parent);
13477 ret = tasha_handle_pdata(tasha, pdata);
Xiaoyu Ye1a2d8bd92017-01-31 18:54:15 -080013478 if (ret < 0)
Banajit Goswamide8271c2017-01-18 00:28:59 -080013479 dev_err(codec->dev, "%s: invalid pdata\n", __func__);
13480
13481 /* MBHC Init */
13482 wcd_mbhc_deinit(&tasha->mbhc);
13483 tasha->mbhc_started = false;
13484
13485 /* Initialize MBHC module */
13486 ret = wcd_mbhc_init(&tasha->mbhc, codec, &mbhc_cb, &intr_ids,
13487 wcd_mbhc_registers, TASHA_ZDET_SUPPORTED);
13488 if (ret)
13489 dev_err(codec->dev, "%s: mbhc initialization failed\n",
13490 __func__);
13491 else
13492 tasha_mbhc_hs_detect(codec, tasha->mbhc.mbhc_cfg);
13493
13494 tasha_cleanup_irqs(tasha);
13495 ret = tasha_setup_irqs(tasha);
13496 if (ret) {
13497 dev_err(codec->dev, "%s: tasha irq setup failed %d\n",
13498 __func__, ret);
13499 goto err;
13500 }
13501
13502 tasha_set_spkr_mode(codec, tasha->spkr_mode);
13503 wcd_cpe_ssr_event(tasha->cpe_core, WCD_CPE_BUS_UP_EVENT);
13504
13505err:
13506 mutex_unlock(&tasha->codec_mutex);
13507 return ret;
13508}
13509
13510static struct regulator *tasha_codec_find_ondemand_regulator(
13511 struct snd_soc_codec *codec, const char *name)
13512{
13513 int i;
13514 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
13515 struct wcd9xxx *wcd9xxx = tasha->wcd9xxx;
13516 struct wcd9xxx_pdata *pdata = dev_get_platdata(codec->dev->parent);
13517
13518 for (i = 0; i < wcd9xxx->num_of_supplies; ++i) {
13519 if (pdata->regulator[i].ondemand &&
13520 wcd9xxx->supplies[i].supply &&
13521 !strcmp(wcd9xxx->supplies[i].supply, name))
13522 return wcd9xxx->supplies[i].consumer;
13523 }
13524
13525 dev_dbg(tasha->dev, "Warning: regulator not found:%s\n",
13526 name);
13527 return NULL;
13528}
13529
Banajit Goswami2be7b482017-02-03 23:32:37 -080013530static int tasha_codec_probe(struct snd_soc_codec *codec)
Banajit Goswamide8271c2017-01-18 00:28:59 -080013531{
13532 struct wcd9xxx *control;
13533 struct tasha_priv *tasha;
13534 struct wcd9xxx_pdata *pdata;
13535 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
13536 int i, ret;
13537 void *ptr = NULL;
13538 struct regulator *supply;
13539
13540 control = dev_get_drvdata(codec->dev->parent);
13541
13542 dev_info(codec->dev, "%s()\n", __func__);
13543 tasha = snd_soc_codec_get_drvdata(codec);
13544 tasha->intf_type = wcd9xxx_get_intf_type();
13545
13546 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
13547 control->dev_down = tasha_device_down;
13548 control->post_reset = tasha_post_reset_cb;
13549 control->ssr_priv = (void *)codec;
13550 }
13551
13552 /* Resource Manager post Init */
13553 ret = wcd_resmgr_post_init(tasha->resmgr, &tasha_resmgr_cb, codec);
13554 if (ret) {
13555 dev_err(codec->dev, "%s: wcd resmgr post init failed\n",
13556 __func__);
13557 goto err;
13558 }
13559 /* Class-H Init*/
13560 wcd_clsh_init(&tasha->clsh_d);
13561 /* Default HPH Mode to Class-H HiFi */
13562 tasha->hph_mode = CLS_H_HIFI;
13563
13564 tasha->codec = codec;
13565 for (i = 0; i < COMPANDER_MAX; i++)
13566 tasha->comp_enabled[i] = 0;
13567
13568 tasha->spkr_gain_offset = RX_GAIN_OFFSET_0_DB;
13569 tasha->intf_type = wcd9xxx_get_intf_type();
13570 tasha_update_reg_reset_values(codec);
13571 pr_debug("%s: MCLK Rate = %x\n", __func__, control->mclk_rate);
13572 if (control->mclk_rate == TASHA_MCLK_CLK_12P288MHZ)
13573 snd_soc_update_bits(codec, WCD9335_CODEC_RPM_CLK_MCLK_CFG,
13574 0x03, 0x00);
13575 else if (control->mclk_rate == TASHA_MCLK_CLK_9P6MHZ)
13576 snd_soc_update_bits(codec, WCD9335_CODEC_RPM_CLK_MCLK_CFG,
13577 0x03, 0x01);
13578 tasha_codec_init_reg(codec);
13579
13580 tasha_enable_efuse_sensing(codec);
13581
13582 pdata = dev_get_platdata(codec->dev->parent);
13583 ret = tasha_handle_pdata(tasha, pdata);
Xiaoyu Ye1a2d8bd92017-01-31 18:54:15 -080013584 if (ret < 0) {
Banajit Goswamide8271c2017-01-18 00:28:59 -080013585 pr_err("%s: bad pdata\n", __func__);
13586 goto err;
13587 }
13588
13589 supply = tasha_codec_find_ondemand_regulator(codec,
13590 on_demand_supply_name[ON_DEMAND_MICBIAS]);
13591 if (supply) {
13592 tasha->on_demand_list[ON_DEMAND_MICBIAS].supply = supply;
13593 tasha->on_demand_list[ON_DEMAND_MICBIAS].ondemand_supply_count =
13594 0;
13595 }
13596
13597 tasha->fw_data = devm_kzalloc(codec->dev,
13598 sizeof(*(tasha->fw_data)), GFP_KERNEL);
13599 if (!tasha->fw_data)
13600 goto err;
13601 set_bit(WCD9XXX_ANC_CAL, tasha->fw_data->cal_bit);
13602 set_bit(WCD9XXX_MBHC_CAL, tasha->fw_data->cal_bit);
13603 set_bit(WCD9XXX_MAD_CAL, tasha->fw_data->cal_bit);
13604 set_bit(WCD9XXX_VBAT_CAL, tasha->fw_data->cal_bit);
13605
13606 ret = wcd_cal_create_hwdep(tasha->fw_data,
13607 WCD9XXX_CODEC_HWDEP_NODE, codec);
13608 if (ret < 0) {
13609 dev_err(codec->dev, "%s hwdep failed %d\n", __func__, ret);
13610 goto err_hwdep;
13611 }
13612
13613 /* Initialize MBHC module */
13614 if (TASHA_IS_2_0(tasha->wcd9xxx)) {
13615 wcd_mbhc_registers[WCD_MBHC_FSM_STATUS].reg =
13616 WCD9335_MBHC_FSM_STATUS;
13617 wcd_mbhc_registers[WCD_MBHC_FSM_STATUS].mask = 0x01;
13618 }
13619 ret = wcd_mbhc_init(&tasha->mbhc, codec, &mbhc_cb, &intr_ids,
13620 wcd_mbhc_registers, TASHA_ZDET_SUPPORTED);
13621 if (ret) {
13622 pr_err("%s: mbhc initialization failed\n", __func__);
13623 goto err_hwdep;
13624 }
13625
13626 ptr = devm_kzalloc(codec->dev, (sizeof(tasha_rx_chs) +
13627 sizeof(tasha_tx_chs)), GFP_KERNEL);
13628 if (!ptr) {
13629 ret = -ENOMEM;
13630 goto err_hwdep;
13631 }
13632
13633 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
13634 snd_soc_dapm_new_controls(dapm, tasha_dapm_i2s_widgets,
13635 ARRAY_SIZE(tasha_dapm_i2s_widgets));
13636 snd_soc_dapm_add_routes(dapm, audio_i2s_map,
13637 ARRAY_SIZE(audio_i2s_map));
13638 for (i = 0; i < ARRAY_SIZE(tasha_i2s_dai); i++) {
13639 INIT_LIST_HEAD(&tasha->dai[i].wcd9xxx_ch_list);
13640 init_waitqueue_head(&tasha->dai[i].dai_wait);
13641 }
13642 } else if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
13643 for (i = 0; i < NUM_CODEC_DAIS; i++) {
13644 INIT_LIST_HEAD(&tasha->dai[i].wcd9xxx_ch_list);
13645 init_waitqueue_head(&tasha->dai[i].dai_wait);
13646 }
13647 tasha_slimbus_slave_port_cfg.slave_dev_intfdev_la =
13648 control->slim_slave->laddr;
13649 tasha_slimbus_slave_port_cfg.slave_dev_pgd_la =
13650 control->slim->laddr;
13651 tasha_slimbus_slave_port_cfg.slave_port_mapping[0] =
13652 TASHA_TX13;
13653 tasha_init_slim_slave_cfg(codec);
13654 }
13655
13656 snd_soc_add_codec_controls(codec, impedance_detect_controls,
13657 ARRAY_SIZE(impedance_detect_controls));
13658 snd_soc_add_codec_controls(codec, hph_type_detect_controls,
13659 ARRAY_SIZE(hph_type_detect_controls));
13660
13661 snd_soc_add_codec_controls(codec,
13662 tasha_analog_gain_controls,
13663 ARRAY_SIZE(tasha_analog_gain_controls));
13664 control->num_rx_port = TASHA_RX_MAX;
13665 control->rx_chs = ptr;
13666 memcpy(control->rx_chs, tasha_rx_chs, sizeof(tasha_rx_chs));
13667 control->num_tx_port = TASHA_TX_MAX;
13668 control->tx_chs = ptr + sizeof(tasha_rx_chs);
13669 memcpy(control->tx_chs, tasha_tx_chs, sizeof(tasha_tx_chs));
13670
13671 snd_soc_dapm_ignore_suspend(dapm, "AIF1 Playback");
13672 snd_soc_dapm_ignore_suspend(dapm, "AIF1 Capture");
13673 snd_soc_dapm_ignore_suspend(dapm, "AIF2 Playback");
13674 snd_soc_dapm_ignore_suspend(dapm, "AIF2 Capture");
13675
13676 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
13677 snd_soc_dapm_ignore_suspend(dapm, "AIF3 Playback");
13678 snd_soc_dapm_ignore_suspend(dapm, "AIF3 Capture");
13679 snd_soc_dapm_ignore_suspend(dapm, "AIF4 Playback");
13680 snd_soc_dapm_ignore_suspend(dapm, "AIF Mix Playback");
13681 snd_soc_dapm_ignore_suspend(dapm, "AIF4 MAD TX");
13682 snd_soc_dapm_ignore_suspend(dapm, "VIfeed");
13683 snd_soc_dapm_ignore_suspend(dapm, "AIF5 CPE TX");
13684 }
13685
13686 snd_soc_dapm_sync(dapm);
13687
13688 ret = tasha_setup_irqs(tasha);
13689 if (ret) {
13690 pr_err("%s: tasha irq setup failed %d\n", __func__, ret);
13691 goto err_pdata;
13692 }
13693
13694 ret = tasha_cpe_initialize(codec);
13695 if (ret) {
13696 dev_err(codec->dev,
13697 "%s: cpe initialization failed, err = %d\n",
13698 __func__, ret);
13699 /* Do not fail probe if CPE failed */
13700 ret = 0;
13701 }
13702
13703 for (i = 0; i < TASHA_NUM_DECIMATORS; i++) {
13704 tasha->tx_hpf_work[i].tasha = tasha;
13705 tasha->tx_hpf_work[i].decimator = i;
13706 INIT_DELAYED_WORK(&tasha->tx_hpf_work[i].dwork,
13707 tasha_tx_hpf_corner_freq_callback);
13708 }
13709
13710 for (i = 0; i < TASHA_NUM_DECIMATORS; i++) {
13711 tasha->tx_mute_dwork[i].tasha = tasha;
13712 tasha->tx_mute_dwork[i].decimator = i;
13713 INIT_DELAYED_WORK(&tasha->tx_mute_dwork[i].dwork,
13714 tasha_tx_mute_update_callback);
13715 }
13716
13717 tasha->spk_anc_dwork.tasha = tasha;
13718 INIT_DELAYED_WORK(&tasha->spk_anc_dwork.dwork,
13719 tasha_spk_anc_update_callback);
13720
13721 mutex_lock(&tasha->codec_mutex);
13722 snd_soc_dapm_disable_pin(dapm, "ANC LINEOUT1");
13723 snd_soc_dapm_disable_pin(dapm, "ANC LINEOUT2");
13724 snd_soc_dapm_disable_pin(dapm, "ANC LINEOUT1 PA");
13725 snd_soc_dapm_disable_pin(dapm, "ANC LINEOUT2 PA");
13726 snd_soc_dapm_disable_pin(dapm, "ANC HPHL");
13727 snd_soc_dapm_disable_pin(dapm, "ANC HPHR");
13728 snd_soc_dapm_disable_pin(dapm, "ANC HPHL PA");
13729 snd_soc_dapm_disable_pin(dapm, "ANC HPHR PA");
13730 snd_soc_dapm_disable_pin(dapm, "ANC EAR PA");
13731 snd_soc_dapm_disable_pin(dapm, "ANC EAR");
13732 snd_soc_dapm_disable_pin(dapm, "ANC SPK1 PA");
13733 mutex_unlock(&tasha->codec_mutex);
13734 snd_soc_dapm_sync(dapm);
13735
13736 return ret;
13737
13738err_pdata:
13739 devm_kfree(codec->dev, ptr);
13740 control->rx_chs = NULL;
13741 control->tx_chs = NULL;
13742err_hwdep:
13743 devm_kfree(codec->dev, tasha->fw_data);
13744 tasha->fw_data = NULL;
13745err:
13746 return ret;
13747}
13748
Banajit Goswami2be7b482017-02-03 23:32:37 -080013749static int tasha_codec_remove(struct snd_soc_codec *codec)
Banajit Goswamide8271c2017-01-18 00:28:59 -080013750{
13751 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
13752 struct wcd9xxx *control;
13753
13754 control = dev_get_drvdata(codec->dev->parent);
13755 control->rx_chs = NULL;
13756 control->tx_chs = NULL;
13757
13758 tasha_cleanup_irqs(tasha);
13759 /* Cleanup MBHC */
13760 /* Cleanup resmgr */
Banajit Goswamie0b20e12017-02-05 18:11:11 -080013761
13762 return 0;
Banajit Goswamide8271c2017-01-18 00:28:59 -080013763}
13764
13765static struct regmap *tasha_get_regmap(struct device *dev)
13766{
13767 struct wcd9xxx *control = dev_get_drvdata(dev->parent);
13768
13769 return control->regmap;
13770}
13771
13772static struct snd_soc_codec_driver soc_codec_dev_tasha = {
Banajit Goswami2be7b482017-02-03 23:32:37 -080013773 .probe = tasha_codec_probe,
13774 .remove = tasha_codec_remove,
Banajit Goswamide8271c2017-01-18 00:28:59 -080013775 .get_regmap = tasha_get_regmap,
Banajit Goswami8e306f02016-12-15 20:49:07 -080013776 .component_driver = {
Banajit Goswamiaf472112017-01-29 22:15:11 -080013777 .controls = tasha_snd_controls,
13778 .num_controls = ARRAY_SIZE(tasha_snd_controls),
Banajit Goswami8e306f02016-12-15 20:49:07 -080013779 .dapm_widgets = tasha_dapm_widgets,
13780 .num_dapm_widgets = ARRAY_SIZE(tasha_dapm_widgets),
13781 .dapm_routes = audio_map,
13782 .num_dapm_routes = ARRAY_SIZE(audio_map),
13783 },
Banajit Goswamide8271c2017-01-18 00:28:59 -080013784};
13785
13786#ifdef CONFIG_PM
13787static int tasha_suspend(struct device *dev)
13788{
13789 struct platform_device *pdev = to_platform_device(dev);
13790 struct tasha_priv *tasha = platform_get_drvdata(pdev);
13791
13792 dev_dbg(dev, "%s: system suspend\n", __func__);
13793 if (cancel_delayed_work_sync(&tasha->power_gate_work))
13794 tasha_codec_power_gate_digital_core(tasha);
13795
13796 return 0;
13797}
13798
13799static int tasha_resume(struct device *dev)
13800{
13801 struct platform_device *pdev = to_platform_device(dev);
13802 struct tasha_priv *tasha = platform_get_drvdata(pdev);
13803
13804 if (!tasha) {
13805 dev_err(dev, "%s: tasha private data is NULL\n", __func__);
13806 return -EINVAL;
13807 }
13808 dev_dbg(dev, "%s: system resume\n", __func__);
13809 return 0;
13810}
13811
13812static const struct dev_pm_ops tasha_pm_ops = {
13813 .suspend = tasha_suspend,
13814 .resume = tasha_resume,
13815};
13816#endif
13817
13818static int tasha_swrm_read(void *handle, int reg)
13819{
13820 struct tasha_priv *tasha;
13821 struct wcd9xxx *wcd9xxx;
13822 unsigned short swr_rd_addr_base;
13823 unsigned short swr_rd_data_base;
13824 int val, ret;
13825
13826 if (!handle) {
13827 pr_err("%s: NULL handle\n", __func__);
13828 return -EINVAL;
13829 }
13830 tasha = (struct tasha_priv *)handle;
13831 wcd9xxx = tasha->wcd9xxx;
13832
13833 dev_dbg(tasha->dev, "%s: Reading soundwire register, 0x%x\n",
13834 __func__, reg);
13835 swr_rd_addr_base = WCD9335_SWR_AHB_BRIDGE_RD_ADDR_0;
13836 swr_rd_data_base = WCD9335_SWR_AHB_BRIDGE_RD_DATA_0;
13837 /* read_lock */
13838 mutex_lock(&tasha->swr_read_lock);
13839 ret = regmap_bulk_write(wcd9xxx->regmap, swr_rd_addr_base,
13840 (u8 *)&reg, 4);
13841 if (ret < 0) {
13842 pr_err("%s: RD Addr Failure\n", __func__);
13843 goto err;
13844 }
13845 /* Check for RD status */
13846 ret = regmap_bulk_read(wcd9xxx->regmap, swr_rd_data_base,
13847 (u8 *)&val, 4);
13848 if (ret < 0) {
13849 pr_err("%s: RD Data Failure\n", __func__);
13850 goto err;
13851 }
13852 ret = val;
13853err:
13854 /* read_unlock */
13855 mutex_unlock(&tasha->swr_read_lock);
13856 return ret;
13857}
13858
13859static int tasha_swrm_i2s_bulk_write(struct wcd9xxx *wcd9xxx,
13860 struct wcd9xxx_reg_val *bulk_reg,
13861 size_t len)
13862{
13863 int i, ret = 0;
13864 unsigned short swr_wr_addr_base;
13865 unsigned short swr_wr_data_base;
13866
13867 swr_wr_addr_base = WCD9335_SWR_AHB_BRIDGE_WR_ADDR_0;
13868 swr_wr_data_base = WCD9335_SWR_AHB_BRIDGE_WR_DATA_0;
13869
13870 for (i = 0; i < (len * 2); i += 2) {
13871 /* First Write the Data to register */
13872 ret = regmap_bulk_write(wcd9xxx->regmap,
13873 swr_wr_data_base, bulk_reg[i].buf, 4);
13874 if (ret < 0) {
13875 dev_err(wcd9xxx->dev, "%s: WR Data Failure\n",
13876 __func__);
13877 break;
13878 }
13879 /* Next Write Address */
13880 ret = regmap_bulk_write(wcd9xxx->regmap,
13881 swr_wr_addr_base, bulk_reg[i+1].buf, 4);
13882 if (ret < 0) {
13883 dev_err(wcd9xxx->dev, "%s: WR Addr Failure\n",
13884 __func__);
13885 break;
13886 }
13887 }
13888 return ret;
13889}
13890
13891static int tasha_swrm_bulk_write(void *handle, u32 *reg, u32 *val, size_t len)
13892{
13893 struct tasha_priv *tasha;
13894 struct wcd9xxx *wcd9xxx;
13895 struct wcd9xxx_reg_val *bulk_reg;
13896 unsigned short swr_wr_addr_base;
13897 unsigned short swr_wr_data_base;
13898 int i, j, ret;
13899
13900 if (!handle) {
13901 pr_err("%s: NULL handle\n", __func__);
13902 return -EINVAL;
13903 }
13904 if (len <= 0) {
13905 pr_err("%s: Invalid size: %zu\n", __func__, len);
13906 return -EINVAL;
13907 }
13908 tasha = (struct tasha_priv *)handle;
13909 wcd9xxx = tasha->wcd9xxx;
13910
13911 swr_wr_addr_base = WCD9335_SWR_AHB_BRIDGE_WR_ADDR_0;
13912 swr_wr_data_base = WCD9335_SWR_AHB_BRIDGE_WR_DATA_0;
13913
13914 bulk_reg = kzalloc((2 * len * sizeof(struct wcd9xxx_reg_val)),
13915 GFP_KERNEL);
13916 if (!bulk_reg)
13917 return -ENOMEM;
13918
13919 for (i = 0, j = 0; i < (len * 2); i += 2, j++) {
13920 bulk_reg[i].reg = swr_wr_data_base;
13921 bulk_reg[i].buf = (u8 *)(&val[j]);
13922 bulk_reg[i].bytes = 4;
13923 bulk_reg[i+1].reg = swr_wr_addr_base;
13924 bulk_reg[i+1].buf = (u8 *)(&reg[j]);
13925 bulk_reg[i+1].bytes = 4;
13926 }
13927 mutex_lock(&tasha->swr_write_lock);
13928
13929 if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C) {
13930 ret = tasha_swrm_i2s_bulk_write(wcd9xxx, bulk_reg, len);
13931 if (ret) {
13932 dev_err(tasha->dev, "%s: i2s bulk write failed, ret: %d\n",
13933 __func__, ret);
13934 }
13935 } else {
13936 ret = wcd9xxx_slim_bulk_write(wcd9xxx, bulk_reg,
13937 (len * 2), false);
13938 if (ret) {
13939 dev_err(tasha->dev, "%s: swrm bulk write failed, ret: %d\n",
13940 __func__, ret);
13941 }
13942 }
13943
13944 mutex_unlock(&tasha->swr_write_lock);
13945 kfree(bulk_reg);
13946
13947 return ret;
13948}
13949
13950static int tasha_swrm_write(void *handle, int reg, int val)
13951{
13952 struct tasha_priv *tasha;
13953 struct wcd9xxx *wcd9xxx;
13954 unsigned short swr_wr_addr_base;
13955 unsigned short swr_wr_data_base;
13956 struct wcd9xxx_reg_val bulk_reg[2];
13957 int ret;
13958
13959 if (!handle) {
13960 pr_err("%s: NULL handle\n", __func__);
13961 return -EINVAL;
13962 }
13963 tasha = (struct tasha_priv *)handle;
13964 wcd9xxx = tasha->wcd9xxx;
13965
13966 swr_wr_addr_base = WCD9335_SWR_AHB_BRIDGE_WR_ADDR_0;
13967 swr_wr_data_base = WCD9335_SWR_AHB_BRIDGE_WR_DATA_0;
13968
13969 /* First Write the Data to register */
13970 bulk_reg[0].reg = swr_wr_data_base;
13971 bulk_reg[0].buf = (u8 *)(&val);
13972 bulk_reg[0].bytes = 4;
13973 bulk_reg[1].reg = swr_wr_addr_base;
13974 bulk_reg[1].buf = (u8 *)(&reg);
13975 bulk_reg[1].bytes = 4;
13976
13977 mutex_lock(&tasha->swr_write_lock);
13978
13979 if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C) {
13980 ret = tasha_swrm_i2s_bulk_write(wcd9xxx, bulk_reg, 1);
13981 if (ret) {
13982 dev_err(tasha->dev, "%s: i2s swrm write failed, ret: %d\n",
13983 __func__, ret);
13984 }
13985 } else {
13986 ret = wcd9xxx_slim_bulk_write(wcd9xxx, bulk_reg, 2, false);
13987 if (ret < 0)
13988 pr_err("%s: WR Data Failure\n", __func__);
13989 }
13990
13991 mutex_unlock(&tasha->swr_write_lock);
13992 return ret;
13993}
13994
13995static int tasha_swrm_clock(void *handle, bool enable)
13996{
13997 struct tasha_priv *tasha = (struct tasha_priv *) handle;
13998
13999 mutex_lock(&tasha->swr_clk_lock);
14000
14001 dev_dbg(tasha->dev, "%s: swrm clock %s\n",
14002 __func__, (enable?"enable" : "disable"));
14003 if (enable) {
14004 tasha->swr_clk_users++;
14005 if (tasha->swr_clk_users == 1) {
14006 if (TASHA_IS_2_0(tasha->wcd9xxx))
14007 regmap_update_bits(
14008 tasha->wcd9xxx->regmap,
14009 WCD9335_TEST_DEBUG_NPL_DLY_TEST_1,
14010 0x10, 0x00);
14011 __tasha_cdc_mclk_enable(tasha, true);
14012 regmap_update_bits(tasha->wcd9xxx->regmap,
14013 WCD9335_CDC_CLK_RST_CTRL_SWR_CONTROL,
14014 0x01, 0x01);
14015 }
14016 } else {
14017 tasha->swr_clk_users--;
14018 if (tasha->swr_clk_users == 0) {
14019 regmap_update_bits(tasha->wcd9xxx->regmap,
14020 WCD9335_CDC_CLK_RST_CTRL_SWR_CONTROL,
14021 0x01, 0x00);
14022 __tasha_cdc_mclk_enable(tasha, false);
14023 if (TASHA_IS_2_0(tasha->wcd9xxx))
14024 regmap_update_bits(
14025 tasha->wcd9xxx->regmap,
14026 WCD9335_TEST_DEBUG_NPL_DLY_TEST_1,
14027 0x10, 0x10);
14028 }
14029 }
14030 dev_dbg(tasha->dev, "%s: swrm clock users %d\n",
14031 __func__, tasha->swr_clk_users);
14032 mutex_unlock(&tasha->swr_clk_lock);
14033 return 0;
14034}
14035
14036static int tasha_swrm_handle_irq(void *handle,
14037 irqreturn_t (*swrm_irq_handler)(int irq,
14038 void *data),
14039 void *swrm_handle,
14040 int action)
14041{
14042 struct tasha_priv *tasha;
14043 int ret = 0;
14044 struct wcd9xxx *wcd9xxx;
14045
14046 if (!handle) {
14047 pr_err("%s: null handle received\n", __func__);
14048 return -EINVAL;
14049 }
14050 tasha = (struct tasha_priv *) handle;
14051 wcd9xxx = tasha->wcd9xxx;
14052
14053 if (action) {
14054 ret = wcd9xxx_request_irq(&wcd9xxx->core_res,
14055 WCD9335_IRQ_SOUNDWIRE,
14056 swrm_irq_handler,
14057 "Tasha SWR Master", swrm_handle);
14058 if (ret)
14059 dev_err(tasha->dev, "%s: Failed to request irq %d\n",
14060 __func__, WCD9335_IRQ_SOUNDWIRE);
14061 } else
14062 wcd9xxx_free_irq(&wcd9xxx->core_res, WCD9335_IRQ_SOUNDWIRE,
14063 swrm_handle);
14064
14065 return ret;
14066}
14067
14068static void tasha_add_child_devices(struct work_struct *work)
14069{
14070 struct tasha_priv *tasha;
14071 struct platform_device *pdev;
14072 struct device_node *node;
14073 struct wcd9xxx *wcd9xxx;
14074 struct tasha_swr_ctrl_data *swr_ctrl_data = NULL, *temp;
14075 int ret, ctrl_num = 0;
14076 struct wcd_swr_ctrl_platform_data *platdata;
14077 char plat_dev_name[WCD9335_STRING_LEN];
14078
14079 tasha = container_of(work, struct tasha_priv,
14080 tasha_add_child_devices_work);
14081 if (!tasha) {
14082 pr_err("%s: Memory for WCD9335 does not exist\n",
14083 __func__);
14084 return;
14085 }
14086 wcd9xxx = tasha->wcd9xxx;
14087 if (!wcd9xxx) {
14088 pr_err("%s: Memory for WCD9XXX does not exist\n",
14089 __func__);
14090 return;
14091 }
14092 if (!wcd9xxx->dev->of_node) {
14093 pr_err("%s: DT node for wcd9xxx does not exist\n",
14094 __func__);
14095 return;
14096 }
14097
14098 platdata = &tasha->swr_plat_data;
14099
14100 for_each_child_of_node(wcd9xxx->dev->of_node, node) {
14101 if (!strcmp(node->name, "swr_master"))
14102 strlcpy(plat_dev_name, "tasha_swr_ctrl",
14103 (WCD9335_STRING_LEN - 1));
14104 else if (strnstr(node->name, "msm_cdc_pinctrl",
14105 strlen("msm_cdc_pinctrl")) != NULL)
14106 strlcpy(plat_dev_name, node->name,
14107 (WCD9335_STRING_LEN - 1));
14108 else
14109 continue;
14110
14111 pdev = platform_device_alloc(plat_dev_name, -1);
14112 if (!pdev) {
14113 dev_err(wcd9xxx->dev, "%s: pdev memory alloc failed\n",
14114 __func__);
14115 ret = -ENOMEM;
14116 goto err;
14117 }
14118 pdev->dev.parent = tasha->dev;
14119 pdev->dev.of_node = node;
14120
14121 if (!strcmp(node->name, "swr_master")) {
14122 ret = platform_device_add_data(pdev, platdata,
14123 sizeof(*platdata));
14124 if (ret) {
14125 dev_err(&pdev->dev,
14126 "%s: cannot add plat data ctrl:%d\n",
14127 __func__, ctrl_num);
14128 goto fail_pdev_add;
14129 }
14130 }
14131
14132 ret = platform_device_add(pdev);
14133 if (ret) {
14134 dev_err(&pdev->dev,
14135 "%s: Cannot add platform device\n",
14136 __func__);
14137 goto fail_pdev_add;
14138 }
14139
14140 if (!strcmp(node->name, "swr_master")) {
14141 temp = krealloc(swr_ctrl_data,
14142 (ctrl_num + 1) * sizeof(
14143 struct tasha_swr_ctrl_data),
14144 GFP_KERNEL);
14145 if (!temp) {
14146 dev_err(wcd9xxx->dev, "out of memory\n");
14147 ret = -ENOMEM;
14148 goto err;
14149 }
14150 swr_ctrl_data = temp;
14151 swr_ctrl_data[ctrl_num].swr_pdev = pdev;
14152 ctrl_num++;
14153 dev_dbg(&pdev->dev,
14154 "%s: Added soundwire ctrl device(s)\n",
14155 __func__);
14156 tasha->nr = ctrl_num;
14157 tasha->swr_ctrl_data = swr_ctrl_data;
14158 }
14159 }
14160
14161 return;
14162fail_pdev_add:
14163 platform_device_put(pdev);
14164err:
14165 return;
14166}
14167
14168/*
14169 * tasha_codec_ver: to get tasha codec version
14170 * @codec: handle to snd_soc_codec *
14171 * return enum codec_variant - version
14172 */
14173enum codec_variant tasha_codec_ver(void)
14174{
14175 return codec_ver;
14176}
14177EXPORT_SYMBOL(tasha_codec_ver);
14178
14179static int __tasha_enable_efuse_sensing(struct tasha_priv *tasha)
14180{
14181 int val, rc;
14182
14183 __tasha_cdc_mclk_enable(tasha, true);
14184
14185 regmap_update_bits(tasha->wcd9xxx->regmap,
14186 WCD9335_CHIP_TIER_CTRL_EFUSE_CTL, 0x1E, 0x20);
14187 regmap_update_bits(tasha->wcd9xxx->regmap,
14188 WCD9335_CHIP_TIER_CTRL_EFUSE_CTL, 0x01, 0x01);
14189
14190 /*
14191 * 5ms sleep required after enabling efuse control
14192 * before checking the status.
14193 */
14194 usleep_range(5000, 5500);
14195 rc = regmap_read(tasha->wcd9xxx->regmap,
14196 WCD9335_CHIP_TIER_CTRL_EFUSE_STATUS, &val);
14197
14198 if (rc || (!(val & 0x01)))
14199 WARN(1, "%s: Efuse sense is not complete\n", __func__);
14200
14201 __tasha_cdc_mclk_enable(tasha, false);
14202
14203 return rc;
14204}
14205
14206void tasha_get_codec_ver(struct tasha_priv *tasha)
14207{
14208 int i;
14209 int val;
14210 struct tasha_reg_mask_val codec_reg[] = {
14211 {WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT10, 0xFF, 0xFF},
14212 {WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT11, 0xFF, 0x83},
14213 {WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT12, 0xFF, 0x0A},
14214 };
14215
14216 __tasha_enable_efuse_sensing(tasha);
14217 for (i = 0; i < ARRAY_SIZE(codec_reg); i++) {
14218 regmap_read(tasha->wcd9xxx->regmap, codec_reg[i].reg, &val);
14219 if (!(val && codec_reg[i].val)) {
14220 codec_ver = WCD9335;
14221 goto ret;
14222 }
14223 }
14224 codec_ver = WCD9326;
14225ret:
14226 pr_debug("%s: codec is %d\n", __func__, codec_ver);
14227}
14228EXPORT_SYMBOL(tasha_get_codec_ver);
14229
14230static int tasha_probe(struct platform_device *pdev)
14231{
14232 int ret = 0;
14233 struct tasha_priv *tasha;
14234 struct clk *wcd_ext_clk, *wcd_native_clk;
14235 struct wcd9xxx_resmgr_v2 *resmgr;
14236 struct wcd9xxx_power_region *cdc_pwr;
14237
14238 if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C) {
14239 if (apr_get_subsys_state() == APR_SUBSYS_DOWN) {
14240 dev_err(&pdev->dev, "%s: dsp down\n", __func__);
14241 return -EPROBE_DEFER;
14242 }
14243 }
14244
14245 tasha = devm_kzalloc(&pdev->dev, sizeof(struct tasha_priv),
14246 GFP_KERNEL);
14247 if (!tasha)
14248 return -ENOMEM;
14249 platform_set_drvdata(pdev, tasha);
14250
14251 tasha->wcd9xxx = dev_get_drvdata(pdev->dev.parent);
14252 tasha->dev = &pdev->dev;
14253 INIT_DELAYED_WORK(&tasha->power_gate_work, tasha_codec_power_gate_work);
14254 mutex_init(&tasha->power_lock);
14255 mutex_init(&tasha->sido_lock);
14256 INIT_WORK(&tasha->tasha_add_child_devices_work,
14257 tasha_add_child_devices);
14258 BLOCKING_INIT_NOTIFIER_HEAD(&tasha->notifier);
14259 mutex_init(&tasha->micb_lock);
14260 mutex_init(&tasha->swr_read_lock);
14261 mutex_init(&tasha->swr_write_lock);
14262 mutex_init(&tasha->swr_clk_lock);
14263 mutex_init(&tasha->mclk_lock);
14264
14265 cdc_pwr = devm_kzalloc(&pdev->dev, sizeof(struct wcd9xxx_power_region),
14266 GFP_KERNEL);
14267 if (!cdc_pwr) {
14268 ret = -ENOMEM;
14269 goto err_cdc_pwr;
14270 }
14271 tasha->wcd9xxx->wcd9xxx_pwr[WCD9XXX_DIG_CORE_REGION_1] = cdc_pwr;
14272 cdc_pwr->pwr_collapse_reg_min = TASHA_DIG_CORE_REG_MIN;
14273 cdc_pwr->pwr_collapse_reg_max = TASHA_DIG_CORE_REG_MAX;
14274 wcd9xxx_set_power_state(tasha->wcd9xxx,
14275 WCD_REGION_POWER_COLLAPSE_REMOVE,
14276 WCD9XXX_DIG_CORE_REGION_1);
14277
14278 mutex_init(&tasha->codec_mutex);
14279 /*
14280 * Init resource manager so that if child nodes such as SoundWire
14281 * requests for clock, resource manager can honor the request
14282 */
14283 resmgr = wcd_resmgr_init(&tasha->wcd9xxx->core_res, NULL);
14284 if (IS_ERR(resmgr)) {
14285 ret = PTR_ERR(resmgr);
14286 dev_err(&pdev->dev, "%s: Failed to initialize wcd resmgr\n",
14287 __func__);
14288 goto err_resmgr;
14289 }
14290 tasha->resmgr = resmgr;
14291 tasha->swr_plat_data.handle = (void *) tasha;
14292 tasha->swr_plat_data.read = tasha_swrm_read;
14293 tasha->swr_plat_data.write = tasha_swrm_write;
14294 tasha->swr_plat_data.bulk_write = tasha_swrm_bulk_write;
14295 tasha->swr_plat_data.clk = tasha_swrm_clock;
14296 tasha->swr_plat_data.handle_irq = tasha_swrm_handle_irq;
14297
14298 /* Register for Clock */
14299 wcd_ext_clk = clk_get(tasha->wcd9xxx->dev, "wcd_clk");
14300 if (IS_ERR(wcd_ext_clk)) {
14301 dev_err(tasha->wcd9xxx->dev, "%s: clk get %s failed\n",
14302 __func__, "wcd_ext_clk");
14303 goto err_clk;
14304 }
14305 tasha->wcd_ext_clk = wcd_ext_clk;
14306 tasha->sido_voltage = SIDO_VOLTAGE_NOMINAL_MV;
14307 set_bit(AUDIO_NOMINAL, &tasha->status_mask);
14308 tasha->sido_ccl_cnt = 0;
14309
14310 /* Register native clk for 44.1 playback */
14311 wcd_native_clk = clk_get(tasha->wcd9xxx->dev, "wcd_native_clk");
14312 if (IS_ERR(wcd_native_clk))
14313 dev_dbg(tasha->wcd9xxx->dev, "%s: clk get %s failed\n",
14314 __func__, "wcd_native_clk");
14315 else
14316 tasha->wcd_native_clk = wcd_native_clk;
14317
14318 if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_SLIMBUS)
14319 ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_tasha,
14320 tasha_dai, ARRAY_SIZE(tasha_dai));
14321 else if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C)
14322 ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_tasha,
14323 tasha_i2s_dai,
14324 ARRAY_SIZE(tasha_i2s_dai));
14325 else
14326 ret = -EINVAL;
14327 if (ret) {
14328 dev_err(&pdev->dev, "%s: Codec registration failed, ret = %d\n",
14329 __func__, ret);
14330 goto err_cdc_reg;
14331 }
14332 /* Update codec register default values */
14333 tasha_update_reg_defaults(tasha);
14334 schedule_work(&tasha->tasha_add_child_devices_work);
14335 tasha_get_codec_ver(tasha);
14336
14337 dev_info(&pdev->dev, "%s: Tasha driver probe done\n", __func__);
14338 return ret;
14339
14340err_cdc_reg:
14341 clk_put(tasha->wcd_ext_clk);
14342 if (tasha->wcd_native_clk)
14343 clk_put(tasha->wcd_native_clk);
14344err_clk:
14345 wcd_resmgr_remove(tasha->resmgr);
14346err_resmgr:
14347 devm_kfree(&pdev->dev, cdc_pwr);
14348err_cdc_pwr:
14349 mutex_destroy(&tasha->mclk_lock);
14350 devm_kfree(&pdev->dev, tasha);
14351 return ret;
14352}
14353
14354static int tasha_remove(struct platform_device *pdev)
14355{
14356 struct tasha_priv *tasha;
14357
14358 tasha = platform_get_drvdata(pdev);
14359
14360 mutex_destroy(&tasha->codec_mutex);
14361 clk_put(tasha->wcd_ext_clk);
14362 if (tasha->wcd_native_clk)
14363 clk_put(tasha->wcd_native_clk);
14364 mutex_destroy(&tasha->mclk_lock);
14365 devm_kfree(&pdev->dev, tasha);
14366 snd_soc_unregister_codec(&pdev->dev);
14367 return 0;
14368}
14369
14370static struct platform_driver tasha_codec_driver = {
14371 .probe = tasha_probe,
14372 .remove = tasha_remove,
14373 .driver = {
14374 .name = "tasha_codec",
14375 .owner = THIS_MODULE,
14376#ifdef CONFIG_PM
14377 .pm = &tasha_pm_ops,
14378#endif
14379 },
14380};
14381
14382module_platform_driver(tasha_codec_driver);
14383
14384MODULE_DESCRIPTION("Tasha Codec driver");
14385MODULE_LICENSE("GPL v2");