blob: dedf4dca3c3b4b23b6aa1933d59638a73e3004de [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"
Sudheer Papothifc7d3f42016-12-06 03:42:10 +053049#include "wcd-mbhc-v2-api.h"
Banajit Goswamide8271c2017-01-18 00:28:59 -080050
51#define TASHA_RX_PORT_START_NUMBER 16
52
53#define WCD9335_RATES_MASK (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
54 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
55 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
56/* Fractional Rates */
57#define WCD9335_FRAC_RATES_MASK (SNDRV_PCM_RATE_44100)
58
59#define WCD9335_MIX_RATES_MASK (SNDRV_PCM_RATE_48000 |\
60 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
61
62#define TASHA_FORMATS_S16_S24_LE (SNDRV_PCM_FMTBIT_S16_LE | \
63 SNDRV_PCM_FMTBIT_S24_LE | \
64 SNDRV_PCM_FMTBIT_S24_3LE)
65
66#define TASHA_FORMATS_S16_S24_S32_LE (SNDRV_PCM_FMTBIT_S16_LE | \
67 SNDRV_PCM_FMTBIT_S24_LE | \
68 SNDRV_PCM_FMTBIT_S24_3LE | \
69 SNDRV_PCM_FMTBIT_S32_LE)
70
71#define TASHA_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
72
73/*
74 * Timeout in milli seconds and it is the wait time for
75 * slim channel removal interrupt to receive.
76 */
77#define TASHA_SLIM_CLOSE_TIMEOUT 1000
78#define TASHA_SLIM_IRQ_OVERFLOW (1 << 0)
79#define TASHA_SLIM_IRQ_UNDERFLOW (1 << 1)
80#define TASHA_SLIM_IRQ_PORT_CLOSED (1 << 2)
81#define TASHA_MCLK_CLK_12P288MHZ 12288000
82#define TASHA_MCLK_CLK_9P6MHZ 9600000
83
84#define TASHA_SLIM_PGD_PORT_INT_TX_EN0 (TASHA_SLIM_PGD_PORT_INT_EN0 + 2)
85
86#define TASHA_NUM_INTERPOLATORS 9
87#define TASHA_NUM_DECIMATORS 9
88
89#define BYTE_BIT_MASK(nr) (1 << ((nr) % BITS_PER_BYTE))
90#define TASHA_MAD_AUDIO_FIRMWARE_PATH "wcd9335/wcd9335_mad_audio.bin"
91#define TASHA_CPE_SS_ERR_STATUS_MEM_ACCESS (1 << 0)
92#define TASHA_CPE_SS_ERR_STATUS_WDOG_BITE (1 << 1)
93
94#define TASHA_CPE_FATAL_IRQS \
95 (TASHA_CPE_SS_ERR_STATUS_WDOG_BITE | \
96 TASHA_CPE_SS_ERR_STATUS_MEM_ACCESS)
97
98#define SLIM_BW_CLK_GEAR_9 6200000
99#define SLIM_BW_UNVOTE 0
100
101#define CPE_FLL_CLK_75MHZ 75000000
102#define CPE_FLL_CLK_150MHZ 150000000
103#define WCD9335_REG_BITS 8
104
105#define WCD9335_MAX_VALID_ADC_MUX 13
106#define WCD9335_INVALID_ADC_MUX 9
107
108#define TASHA_DIG_CORE_REG_MIN WCD9335_CDC_ANC0_CLK_RESET_CTL
109#define TASHA_DIG_CORE_REG_MAX 0xDFF
110
111/* Convert from vout ctl to micbias voltage in mV */
112#define WCD_VOUT_CTL_TO_MICB(v) (1000 + v * 50)
113
114#define TASHA_ZDET_NUM_MEASUREMENTS 150
115#define TASHA_MBHC_GET_C1(c) ((c & 0xC000) >> 14)
116#define TASHA_MBHC_GET_X1(x) (x & 0x3FFF)
117/* z value compared in milliOhm */
118#define TASHA_MBHC_IS_SECOND_RAMP_REQUIRED(z) ((z > 400000) || (z < 32000))
119#define TASHA_MBHC_ZDET_CONST (86 * 16384)
120#define TASHA_MBHC_MOISTURE_VREF V_45_MV
121#define TASHA_MBHC_MOISTURE_IREF I_3P0_UA
122
123#define TASHA_VERSION_ENTRY_SIZE 17
124
125#define WCD9335_AMIC_PWR_LEVEL_LP 0
126#define WCD9335_AMIC_PWR_LEVEL_DEFAULT 1
127#define WCD9335_AMIC_PWR_LEVEL_HP 2
128#define WCD9335_AMIC_PWR_LVL_MASK 0x60
129#define WCD9335_AMIC_PWR_LVL_SHIFT 0x5
130
131#define WCD9335_DEC_PWR_LVL_MASK 0x06
132#define WCD9335_DEC_PWR_LVL_LP 0x02
133#define WCD9335_DEC_PWR_LVL_HP 0x04
134#define WCD9335_DEC_PWR_LVL_DF 0x00
135#define WCD9335_STRING_LEN 100
136
137#define CALCULATE_VOUT_D(req_mv) (((req_mv - 650) * 10) / 25)
138
139static int cpe_debug_mode;
140
141#define TASHA_MAX_MICBIAS 4
142#define DAPM_MICBIAS1_STANDALONE "MIC BIAS1 Standalone"
143#define DAPM_MICBIAS2_STANDALONE "MIC BIAS2 Standalone"
144#define DAPM_MICBIAS3_STANDALONE "MIC BIAS3 Standalone"
145#define DAPM_MICBIAS4_STANDALONE "MIC BIAS4 Standalone"
146
147#define DAPM_LDO_H_STANDALONE "LDO_H"
148module_param(cpe_debug_mode, int, 0664);
149MODULE_PARM_DESC(cpe_debug_mode, "boot cpe in debug mode");
150
151#define TASHA_DIG_CORE_COLLAPSE_TIMER_MS (5 * 1000)
152
153#define MAX_ON_DEMAND_SUPPLY_NAME_LENGTH 64
154
155static char on_demand_supply_name[][MAX_ON_DEMAND_SUPPLY_NAME_LENGTH] = {
156 "cdc-vdd-mic-bias",
157};
158
159enum {
160 POWER_COLLAPSE,
161 POWER_RESUME,
162};
163
164enum tasha_sido_voltage {
165 SIDO_VOLTAGE_SVS_MV = 950,
166 SIDO_VOLTAGE_NOMINAL_MV = 1100,
167};
168
169static enum codec_variant codec_ver;
170
171static int dig_core_collapse_enable = 1;
172module_param(dig_core_collapse_enable, int, 0664);
173MODULE_PARM_DESC(dig_core_collapse_enable, "enable/disable power gating");
174
175/* dig_core_collapse timer in seconds */
176static int dig_core_collapse_timer = (TASHA_DIG_CORE_COLLAPSE_TIMER_MS/1000);
177module_param(dig_core_collapse_timer, int, 0664);
178MODULE_PARM_DESC(dig_core_collapse_timer, "timer for power gating");
179
180/* SVS Scaling enable/disable */
181static int svs_scaling_enabled = 1;
182module_param(svs_scaling_enabled, int, 0664);
183MODULE_PARM_DESC(svs_scaling_enabled, "enable/disable svs scaling");
184
185/* SVS buck setting */
186static int sido_buck_svs_voltage = SIDO_VOLTAGE_SVS_MV;
187module_param(sido_buck_svs_voltage, int, 0664);
188MODULE_PARM_DESC(sido_buck_svs_voltage,
189 "setting for SVS voltage for SIDO BUCK");
190
191#define TASHA_TX_UNMUTE_DELAY_MS 25
192
193static int tx_unmute_delay = TASHA_TX_UNMUTE_DELAY_MS;
194module_param(tx_unmute_delay, int, 0664);
195MODULE_PARM_DESC(tx_unmute_delay, "delay to unmute the tx path");
196
197static struct afe_param_slimbus_slave_port_cfg tasha_slimbus_slave_port_cfg = {
198 .minor_version = 1,
199 .slimbus_dev_id = AFE_SLIMBUS_DEVICE_1,
200 .slave_dev_pgd_la = 0,
201 .slave_dev_intfdev_la = 0,
202 .bit_width = 16,
203 .data_format = 0,
204 .num_channels = 1
205};
206
207struct tasha_mbhc_zdet_param {
208 u16 ldo_ctl;
209 u16 noff;
210 u16 nshift;
211 u16 btn5;
212 u16 btn6;
213 u16 btn7;
214};
215
216static struct afe_param_cdc_reg_page_cfg tasha_cdc_reg_page_cfg = {
217 .minor_version = AFE_API_VERSION_CDC_REG_PAGE_CFG,
218 .enable = 1,
219 .proc_id = AFE_CDC_REG_PAGE_ASSIGN_PROC_ID_1,
220};
221
222static struct afe_param_cdc_reg_cfg audio_reg_cfg[] = {
223 {
224 1,
225 (TASHA_REGISTER_START_OFFSET + WCD9335_SOC_MAD_MAIN_CTL_1),
226 HW_MAD_AUDIO_ENABLE, 0x1, WCD9335_REG_BITS, 0
227 },
228 {
229 1,
230 (TASHA_REGISTER_START_OFFSET + WCD9335_SOC_MAD_AUDIO_CTL_3),
231 HW_MAD_AUDIO_SLEEP_TIME, 0xF, WCD9335_REG_BITS, 0
232 },
233 {
234 1,
235 (TASHA_REGISTER_START_OFFSET + WCD9335_SOC_MAD_AUDIO_CTL_4),
236 HW_MAD_TX_AUDIO_SWITCH_OFF, 0x1, WCD9335_REG_BITS, 0
237 },
238 {
239 1,
240 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_CFG),
241 MAD_AUDIO_INT_DEST_SELECT_REG, 0x2, WCD9335_REG_BITS, 0
242 },
243 {
244 1,
245 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_PIN2_MASK3),
246 MAD_AUDIO_INT_MASK_REG, 0x1, WCD9335_REG_BITS, 0
247 },
248 {
249 1,
250 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_PIN2_STATUS3),
251 MAD_AUDIO_INT_STATUS_REG, 0x1, WCD9335_REG_BITS, 0
252 },
253 {
254 1,
255 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_PIN2_CLEAR3),
256 MAD_AUDIO_INT_CLEAR_REG, 0x1, WCD9335_REG_BITS, 0
257 },
258 {
259 1,
260 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_CFG),
261 VBAT_INT_DEST_SELECT_REG, 0x2, WCD9335_REG_BITS, 0
262 },
263 {
264 1,
265 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_PIN2_MASK3),
266 VBAT_INT_MASK_REG, 0x08, WCD9335_REG_BITS, 0
267 },
268 {
269 1,
270 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_PIN2_STATUS3),
271 VBAT_INT_STATUS_REG, 0x08, WCD9335_REG_BITS, 0
272 },
273 {
274 1,
275 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_PIN2_CLEAR3),
276 VBAT_INT_CLEAR_REG, 0x08, WCD9335_REG_BITS, 0
277 },
278 {
279 1,
280 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_CFG),
281 VBAT_RELEASE_INT_DEST_SELECT_REG, 0x2, WCD9335_REG_BITS, 0
282 },
283 {
284 1,
285 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_PIN2_MASK3),
286 VBAT_RELEASE_INT_MASK_REG, 0x10, WCD9335_REG_BITS, 0
287 },
288 {
289 1,
290 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_PIN2_STATUS3),
291 VBAT_RELEASE_INT_STATUS_REG, 0x10, WCD9335_REG_BITS, 0
292 },
293 {
294 1,
295 (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_PIN2_CLEAR3),
296 VBAT_RELEASE_INT_CLEAR_REG, 0x10, WCD9335_REG_BITS, 0
297 },
298 {
299 1,
300 (TASHA_REGISTER_START_OFFSET + TASHA_SB_PGD_PORT_TX_BASE),
301 SB_PGD_PORT_TX_WATERMARK_N, 0x1E, WCD9335_REG_BITS, 0x1
302 },
303 {
304 1,
305 (TASHA_REGISTER_START_OFFSET + TASHA_SB_PGD_PORT_TX_BASE),
306 SB_PGD_PORT_TX_ENABLE_N, 0x1, WCD9335_REG_BITS, 0x1
307 },
308 {
309 1,
310 (TASHA_REGISTER_START_OFFSET + TASHA_SB_PGD_PORT_RX_BASE),
311 SB_PGD_PORT_RX_WATERMARK_N, 0x1E, WCD9335_REG_BITS, 0x1
312 },
313 {
314 1,
315 (TASHA_REGISTER_START_OFFSET + TASHA_SB_PGD_PORT_RX_BASE),
316 SB_PGD_PORT_RX_ENABLE_N, 0x1, WCD9335_REG_BITS, 0x1
317 },
318 { 1,
319 (TASHA_REGISTER_START_OFFSET + WCD9335_CDC_ANC0_IIR_ADAPT_CTL),
320 AANC_FF_GAIN_ADAPTIVE, 0x4, WCD9335_REG_BITS, 0
321 },
322 { 1,
323 (TASHA_REGISTER_START_OFFSET + WCD9335_CDC_ANC0_IIR_ADAPT_CTL),
324 AANC_FFGAIN_ADAPTIVE_EN, 0x8, WCD9335_REG_BITS, 0
325 },
326 {
327 1,
328 (TASHA_REGISTER_START_OFFSET + WCD9335_CDC_ANC0_FF_A_GAIN_CTL),
329 AANC_GAIN_CONTROL, 0xFF, WCD9335_REG_BITS, 0
330 },
331};
332
333static struct afe_param_cdc_reg_cfg_data tasha_audio_reg_cfg = {
334 .num_registers = ARRAY_SIZE(audio_reg_cfg),
335 .reg_data = audio_reg_cfg,
336};
337
338static struct afe_param_id_cdc_aanc_version tasha_cdc_aanc_version = {
339 .cdc_aanc_minor_version = AFE_API_VERSION_CDC_AANC_VERSION,
340 .aanc_hw_version = AANC_HW_BLOCK_VERSION_2,
341};
342
343enum {
344 VI_SENSE_1,
345 VI_SENSE_2,
346 AIF4_SWITCH_VALUE,
347 AUDIO_NOMINAL,
348 CPE_NOMINAL,
349 HPH_PA_DELAY,
350 SB_CLK_GEAR,
351 ANC_MIC_AMIC1,
352 ANC_MIC_AMIC2,
353 ANC_MIC_AMIC3,
354 ANC_MIC_AMIC4,
355 ANC_MIC_AMIC5,
356 ANC_MIC_AMIC6,
357 CLASSH_CONFIG,
358};
359
360enum {
361 AIF1_PB = 0,
362 AIF1_CAP,
363 AIF2_PB,
364 AIF2_CAP,
365 AIF3_PB,
366 AIF3_CAP,
367 AIF4_PB,
368 AIF_MIX1_PB,
369 AIF4_MAD_TX,
370 AIF4_VIFEED,
371 AIF5_CPE_TX,
372 NUM_CODEC_DAIS,
373};
374
375enum {
376 INTn_1_MIX_INP_SEL_ZERO = 0,
377 INTn_1_MIX_INP_SEL_DEC0,
378 INTn_1_MIX_INP_SEL_DEC1,
379 INTn_1_MIX_INP_SEL_IIR0,
380 INTn_1_MIX_INP_SEL_IIR1,
381 INTn_1_MIX_INP_SEL_RX0,
382 INTn_1_MIX_INP_SEL_RX1,
383 INTn_1_MIX_INP_SEL_RX2,
384 INTn_1_MIX_INP_SEL_RX3,
385 INTn_1_MIX_INP_SEL_RX4,
386 INTn_1_MIX_INP_SEL_RX5,
387 INTn_1_MIX_INP_SEL_RX6,
388 INTn_1_MIX_INP_SEL_RX7,
389
390};
391
392#define IS_VALID_NATIVE_FIFO_PORT(inp) \
393 ((inp >= INTn_1_MIX_INP_SEL_RX0) && \
394 (inp <= INTn_1_MIX_INP_SEL_RX3))
395
396enum {
397 INTn_2_INP_SEL_ZERO = 0,
398 INTn_2_INP_SEL_RX0,
399 INTn_2_INP_SEL_RX1,
400 INTn_2_INP_SEL_RX2,
401 INTn_2_INP_SEL_RX3,
402 INTn_2_INP_SEL_RX4,
403 INTn_2_INP_SEL_RX5,
404 INTn_2_INP_SEL_RX6,
405 INTn_2_INP_SEL_RX7,
406 INTn_2_INP_SEL_PROXIMITY,
407};
408
409enum {
410 INTERP_EAR = 0,
411 INTERP_HPHL,
412 INTERP_HPHR,
413 INTERP_LO1,
414 INTERP_LO2,
415 INTERP_LO3,
416 INTERP_LO4,
417 INTERP_SPKR1,
418 INTERP_SPKR2,
419};
420
421struct interp_sample_rate {
422 int sample_rate;
423 int rate_val;
424};
425
426static struct interp_sample_rate int_prim_sample_rate_val[] = {
427 {8000, 0x0}, /* 8K */
428 {16000, 0x1}, /* 16K */
429 {24000, -EINVAL},/* 24K */
430 {32000, 0x3}, /* 32K */
431 {48000, 0x4}, /* 48K */
432 {96000, 0x5}, /* 96K */
433 {192000, 0x6}, /* 192K */
434 {384000, 0x7}, /* 384K */
435 {44100, 0x8}, /* 44.1K */
436};
437
438static struct interp_sample_rate int_mix_sample_rate_val[] = {
439 {48000, 0x4}, /* 48K */
440 {96000, 0x5}, /* 96K */
441 {192000, 0x6}, /* 192K */
442};
443
444static const struct wcd9xxx_ch tasha_rx_chs[TASHA_RX_MAX] = {
445 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER, 0),
446 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 1, 1),
447 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 2, 2),
448 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 3, 3),
449 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 4, 4),
450 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 5, 5),
451 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 6, 6),
452 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 7, 7),
453 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 8, 8),
454 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 9, 9),
455 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 10, 10),
456 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 11, 11),
457 WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 12, 12),
458};
459
460static const struct wcd9xxx_ch tasha_tx_chs[TASHA_TX_MAX] = {
461 WCD9XXX_CH(0, 0),
462 WCD9XXX_CH(1, 1),
463 WCD9XXX_CH(2, 2),
464 WCD9XXX_CH(3, 3),
465 WCD9XXX_CH(4, 4),
466 WCD9XXX_CH(5, 5),
467 WCD9XXX_CH(6, 6),
468 WCD9XXX_CH(7, 7),
469 WCD9XXX_CH(8, 8),
470 WCD9XXX_CH(9, 9),
471 WCD9XXX_CH(10, 10),
472 WCD9XXX_CH(11, 11),
473 WCD9XXX_CH(12, 12),
474 WCD9XXX_CH(13, 13),
475 WCD9XXX_CH(14, 14),
476 WCD9XXX_CH(15, 15),
477};
478
479static const u32 vport_slim_check_table[NUM_CODEC_DAIS] = {
480 /* Needs to define in the same order of DAI enum definitions */
481 0,
482 BIT(AIF2_CAP) | BIT(AIF3_CAP) | BIT(AIF4_MAD_TX) | BIT(AIF5_CPE_TX),
483 0,
484 BIT(AIF1_CAP) | BIT(AIF3_CAP) | BIT(AIF4_MAD_TX) | BIT(AIF5_CPE_TX),
485 0,
486 BIT(AIF1_CAP) | BIT(AIF2_CAP) | BIT(AIF4_MAD_TX) | BIT(AIF5_CPE_TX),
487 0,
488 0,
489 BIT(AIF1_CAP) | BIT(AIF2_CAP) | BIT(AIF3_CAP) | BIT(AIF5_CPE_TX),
490 0,
491 BIT(AIF1_CAP) | BIT(AIF2_CAP) | BIT(AIF3_CAP) | BIT(AIF4_MAD_TX),
492};
493
494static const u32 vport_i2s_check_table[NUM_CODEC_DAIS] = {
495 0, /* AIF1_PB */
496 BIT(AIF2_CAP), /* AIF1_CAP */
497 0, /* AIF2_PB */
498 BIT(AIF1_CAP), /* AIF2_CAP */
499};
500
501/* Codec supports 2 IIR filters */
502enum {
503 IIR0 = 0,
504 IIR1,
505 IIR_MAX,
506};
507
508/* Each IIR has 5 Filter Stages */
509enum {
510 BAND1 = 0,
511 BAND2,
512 BAND3,
513 BAND4,
514 BAND5,
515 BAND_MAX,
516};
517
518enum {
519 COMPANDER_1, /* HPH_L */
520 COMPANDER_2, /* HPH_R */
521 COMPANDER_3, /* LO1_DIFF */
522 COMPANDER_4, /* LO2_DIFF */
523 COMPANDER_5, /* LO3_SE */
524 COMPANDER_6, /* LO4_SE */
525 COMPANDER_7, /* SWR SPK CH1 */
526 COMPANDER_8, /* SWR SPK CH2 */
527 COMPANDER_MAX,
528};
529
530enum {
531 SRC_IN_HPHL,
532 SRC_IN_LO1,
533 SRC_IN_HPHR,
534 SRC_IN_LO2,
535 SRC_IN_SPKRL,
536 SRC_IN_LO3,
537 SRC_IN_SPKRR,
538 SRC_IN_LO4,
539};
540
541enum {
542 SPLINE_SRC0,
543 SPLINE_SRC1,
544 SPLINE_SRC2,
545 SPLINE_SRC3,
546 SPLINE_SRC_MAX,
547};
548
549/* wcd9335 interrupt table */
550static const struct intr_data wcd9335_intr_table[] = {
551 {WCD9XXX_IRQ_SLIMBUS, false},
552 {WCD9335_IRQ_MBHC_SW_DET, true},
553 {WCD9335_IRQ_MBHC_BUTTON_PRESS_DET, true},
554 {WCD9335_IRQ_MBHC_BUTTON_RELEASE_DET, true},
555 {WCD9335_IRQ_MBHC_ELECT_INS_REM_DET, true},
556 {WCD9335_IRQ_MBHC_ELECT_INS_REM_LEG_DET, true},
557 {WCD9335_IRQ_FLL_LOCK_LOSS, false},
558 {WCD9335_IRQ_HPH_PA_CNPL_COMPLETE, false},
559 {WCD9335_IRQ_HPH_PA_CNPR_COMPLETE, false},
560 {WCD9335_IRQ_EAR_PA_CNP_COMPLETE, false},
561 {WCD9335_IRQ_LINE_PA1_CNP_COMPLETE, false},
562 {WCD9335_IRQ_LINE_PA2_CNP_COMPLETE, false},
563 {WCD9335_IRQ_LINE_PA3_CNP_COMPLETE, false},
564 {WCD9335_IRQ_LINE_PA4_CNP_COMPLETE, false},
565 {WCD9335_IRQ_HPH_PA_OCPL_FAULT, false},
566 {WCD9335_IRQ_HPH_PA_OCPR_FAULT, false},
567 {WCD9335_IRQ_EAR_PA_OCP_FAULT, false},
568 {WCD9335_IRQ_SOUNDWIRE, false},
569 {WCD9335_IRQ_VDD_DIG_RAMP_COMPLETE, false},
570 {WCD9335_IRQ_RCO_ERROR, false},
571 {WCD9335_IRQ_SVA_ERROR, false},
572 {WCD9335_IRQ_MAD_AUDIO, false},
573 {WCD9335_IRQ_MAD_BEACON, false},
574 {WCD9335_IRQ_SVA_OUTBOX1, true},
575 {WCD9335_IRQ_SVA_OUTBOX2, true},
576 {WCD9335_IRQ_MAD_ULTRASOUND, false},
577 {WCD9335_IRQ_VBAT_ATTACK, false},
578 {WCD9335_IRQ_VBAT_RESTORE, false},
579};
580
581static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0);
582static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1);
583static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1);
584
585static struct snd_soc_dai_driver tasha_dai[];
586static int wcd9335_get_micb_vout_ctl_val(u32 micb_mv);
587
588static int tasha_config_compander(struct snd_soc_codec *, int, int);
589static void tasha_codec_set_tx_hold(struct snd_soc_codec *, u16, bool);
590static int tasha_codec_internal_rco_ctrl(struct snd_soc_codec *codec,
591 bool enable);
592
593/* Hold instance to soundwire platform device */
594struct tasha_swr_ctrl_data {
595 struct platform_device *swr_pdev;
596 struct ida swr_ida;
597};
598
599struct wcd_swr_ctrl_platform_data {
600 void *handle; /* holds codec private data */
601 int (*read)(void *handle, int reg);
602 int (*write)(void *handle, int reg, int val);
603 int (*bulk_write)(void *handle, u32 *reg, u32 *val, size_t len);
604 int (*clk)(void *handle, bool enable);
605 int (*handle_irq)(void *handle,
606 irqreturn_t (*swrm_irq_handler)(int irq,
607 void *data),
608 void *swrm_handle,
609 int action);
610};
611
612static struct wcd_mbhc_register
613 wcd_mbhc_registers[WCD_MBHC_REG_FUNC_MAX] = {
614 WCD_MBHC_REGISTER("WCD_MBHC_L_DET_EN",
615 WCD9335_ANA_MBHC_MECH, 0x80, 7, 0),
616 WCD_MBHC_REGISTER("WCD_MBHC_GND_DET_EN",
617 WCD9335_ANA_MBHC_MECH, 0x40, 6, 0),
618 WCD_MBHC_REGISTER("WCD_MBHC_MECH_DETECTION_TYPE",
619 WCD9335_ANA_MBHC_MECH, 0x20, 5, 0),
620 WCD_MBHC_REGISTER("WCD_MBHC_MIC_CLAMP_CTL",
621 WCD9335_MBHC_PLUG_DETECT_CTL, 0x30, 4, 0),
622 WCD_MBHC_REGISTER("WCD_MBHC_ELECT_DETECTION_TYPE",
623 WCD9335_ANA_MBHC_ELECT, 0x08, 3, 0),
624 WCD_MBHC_REGISTER("WCD_MBHC_HS_L_DET_PULL_UP_CTRL",
625 WCD9335_MBHC_PLUG_DETECT_CTL, 0xC0, 6, 0),
626 WCD_MBHC_REGISTER("WCD_MBHC_HS_L_DET_PULL_UP_COMP_CTRL",
627 WCD9335_ANA_MBHC_MECH, 0x04, 2, 0),
628 WCD_MBHC_REGISTER("WCD_MBHC_HPHL_PLUG_TYPE",
629 WCD9335_ANA_MBHC_MECH, 0x10, 4, 0),
630 WCD_MBHC_REGISTER("WCD_MBHC_GND_PLUG_TYPE",
631 WCD9335_ANA_MBHC_MECH, 0x08, 3, 0),
632 WCD_MBHC_REGISTER("WCD_MBHC_SW_HPH_LP_100K_TO_GND",
633 WCD9335_ANA_MBHC_MECH, 0x01, 0, 0),
634 WCD_MBHC_REGISTER("WCD_MBHC_ELECT_SCHMT_ISRC",
635 WCD9335_ANA_MBHC_ELECT, 0x06, 1, 0),
636 WCD_MBHC_REGISTER("WCD_MBHC_FSM_EN",
637 WCD9335_ANA_MBHC_ELECT, 0x80, 7, 0),
638 WCD_MBHC_REGISTER("WCD_MBHC_INSREM_DBNC",
639 WCD9335_MBHC_PLUG_DETECT_CTL, 0x0F, 0, 0),
640 WCD_MBHC_REGISTER("WCD_MBHC_BTN_DBNC",
641 WCD9335_MBHC_CTL_1, 0x03, 0, 0),
642 WCD_MBHC_REGISTER("WCD_MBHC_HS_VREF",
643 WCD9335_MBHC_CTL_2, 0x03, 0, 0),
644 WCD_MBHC_REGISTER("WCD_MBHC_HS_COMP_RESULT",
645 WCD9335_ANA_MBHC_RESULT_3, 0x08, 3, 0),
646 WCD_MBHC_REGISTER("WCD_MBHC_MIC_SCHMT_RESULT",
647 WCD9335_ANA_MBHC_RESULT_3, 0x20, 5, 0),
648 WCD_MBHC_REGISTER("WCD_MBHC_HPHL_SCHMT_RESULT",
649 WCD9335_ANA_MBHC_RESULT_3, 0x80, 7, 0),
650 WCD_MBHC_REGISTER("WCD_MBHC_HPHR_SCHMT_RESULT",
651 WCD9335_ANA_MBHC_RESULT_3, 0x40, 6, 0),
652 WCD_MBHC_REGISTER("WCD_MBHC_OCP_FSM_EN",
653 WCD9335_HPH_OCP_CTL, 0x10, 4, 0),
654 WCD_MBHC_REGISTER("WCD_MBHC_BTN_RESULT",
655 WCD9335_ANA_MBHC_RESULT_3, 0x07, 0, 0),
656 WCD_MBHC_REGISTER("WCD_MBHC_BTN_ISRC_CTL",
657 WCD9335_ANA_MBHC_ELECT, 0x70, 4, 0),
658 WCD_MBHC_REGISTER("WCD_MBHC_ELECT_RESULT",
659 WCD9335_ANA_MBHC_RESULT_3, 0xFF, 0, 0),
660 WCD_MBHC_REGISTER("WCD_MBHC_MICB_CTRL",
661 WCD9335_ANA_MICB2, 0xC0, 6, 0),
662 WCD_MBHC_REGISTER("WCD_MBHC_HPH_CNP_WG_TIME",
663 WCD9335_HPH_CNP_WG_TIME, 0xFF, 0, 0),
664 WCD_MBHC_REGISTER("WCD_MBHC_HPHR_PA_EN",
665 WCD9335_ANA_HPH, 0x40, 6, 0),
666 WCD_MBHC_REGISTER("WCD_MBHC_HPHL_PA_EN",
667 WCD9335_ANA_HPH, 0x80, 7, 0),
668 WCD_MBHC_REGISTER("WCD_MBHC_HPH_PA_EN",
669 WCD9335_ANA_HPH, 0xC0, 6, 0),
670 WCD_MBHC_REGISTER("WCD_MBHC_SWCH_LEVEL_REMOVE",
671 WCD9335_ANA_MBHC_RESULT_3, 0x10, 4, 0),
672 WCD_MBHC_REGISTER("WCD_MBHC_PULLDOWN_CTRL",
673 0, 0, 0, 0),
674 WCD_MBHC_REGISTER("WCD_MBHC_ANC_DET_EN",
675 WCD9335_ANA_MBHC_ZDET, 0x01, 0, 0),
676 /*
677 * MBHC FSM status register is only available in Tasha 2.0.
678 * So, init with 0 later once the version is known, then values
679 * will be updated.
680 */
681 WCD_MBHC_REGISTER("WCD_MBHC_FSM_STATUS",
682 0, 0, 0, 0),
683 WCD_MBHC_REGISTER("WCD_MBHC_MUX_CTL",
684 WCD9335_MBHC_CTL_2, 0x70, 4, 0),
685};
686
687static const struct wcd_mbhc_intr intr_ids = {
688 .mbhc_sw_intr = WCD9335_IRQ_MBHC_SW_DET,
689 .mbhc_btn_press_intr = WCD9335_IRQ_MBHC_BUTTON_PRESS_DET,
690 .mbhc_btn_release_intr = WCD9335_IRQ_MBHC_BUTTON_RELEASE_DET,
691 .mbhc_hs_ins_intr = WCD9335_IRQ_MBHC_ELECT_INS_REM_LEG_DET,
692 .mbhc_hs_rem_intr = WCD9335_IRQ_MBHC_ELECT_INS_REM_DET,
693 .hph_left_ocp = WCD9335_IRQ_HPH_PA_OCPL_FAULT,
694 .hph_right_ocp = WCD9335_IRQ_HPH_PA_OCPR_FAULT,
695};
696
697struct wcd_vbat {
698 bool is_enabled;
699 bool adc_config;
700 /* Variables to cache Vbat ADC output values */
701 u16 dcp1;
702 u16 dcp2;
703};
704
705struct hpf_work {
706 struct tasha_priv *tasha;
707 u8 decimator;
708 u8 hpf_cut_off_freq;
709 struct delayed_work dwork;
710};
711
712#define WCD9335_SPK_ANC_EN_DELAY_MS 350
713static int spk_anc_en_delay = WCD9335_SPK_ANC_EN_DELAY_MS;
714module_param(spk_anc_en_delay, int, 0664);
715MODULE_PARM_DESC(spk_anc_en_delay, "delay to enable anc in speaker path");
716
717struct spk_anc_work {
718 struct tasha_priv *tasha;
719 struct delayed_work dwork;
720};
721
722struct tx_mute_work {
723 struct tasha_priv *tasha;
724 u8 decimator;
725 struct delayed_work dwork;
726};
727
728struct tasha_priv {
729 struct device *dev;
730 struct wcd9xxx *wcd9xxx;
731
732 struct snd_soc_codec *codec;
733 u32 adc_count;
734 u32 rx_bias_count;
735 s32 dmic_0_1_clk_cnt;
736 s32 dmic_2_3_clk_cnt;
737 s32 dmic_4_5_clk_cnt;
738 s32 ldo_h_users;
739 s32 micb_ref[TASHA_MAX_MICBIAS];
740 s32 pullup_ref[TASHA_MAX_MICBIAS];
741
742 u32 anc_slot;
743 bool anc_func;
744
745 /* Vbat module */
746 struct wcd_vbat vbat;
747
748 /* cal info for codec */
749 struct fw_info *fw_data;
750
751 /*track tasha interface type*/
752 u8 intf_type;
753
754 /* num of slim ports required */
755 struct wcd9xxx_codec_dai_data dai[NUM_CODEC_DAIS];
756
757 /* SoundWire data structure */
758 struct tasha_swr_ctrl_data *swr_ctrl_data;
759 int nr;
760
761 /*compander*/
762 int comp_enabled[COMPANDER_MAX];
763
764 /* Maintain the status of AUX PGA */
765 int aux_pga_cnt;
766 u8 aux_l_gain;
767 u8 aux_r_gain;
768
769 bool spkr_pa_widget_on;
770 struct regulator *spkdrv_reg;
771 struct regulator *spkdrv2_reg;
772
773 bool mbhc_started;
774 /* class h specific data */
775 struct wcd_clsh_cdc_data clsh_d;
776
777 struct afe_param_cdc_slimbus_slave_cfg slimbus_slave_cfg;
778
779 /*
780 * list used to save/restore registers at start and
781 * end of impedance measurement
782 */
783 struct list_head reg_save_restore;
784
785 /* handle to cpe core */
786 struct wcd_cpe_core *cpe_core;
787 u32 current_cpe_clk_freq;
788 enum tasha_sido_voltage sido_voltage;
789 int sido_ccl_cnt;
790
791 u32 ana_rx_supplies;
792 /* Multiplication factor used for impedance detection */
793 int zdet_gain_mul_fact;
794
795 /* to track the status */
796 unsigned long status_mask;
797
798 struct work_struct tasha_add_child_devices_work;
799 struct wcd_swr_ctrl_platform_data swr_plat_data;
800
801 /* Port values for Rx and Tx codec_dai */
802 unsigned int rx_port_value[TASHA_RX_MAX];
803 unsigned int tx_port_value;
804
805 unsigned int vi_feed_value;
806 /* Tasha Interpolator Mode Select for EAR, HPH_L and HPH_R */
807 u32 hph_mode;
808
809 u16 prim_int_users[TASHA_NUM_INTERPOLATORS];
810 int spl_src_users[SPLINE_SRC_MAX];
811
812 struct wcd9xxx_resmgr_v2 *resmgr;
813 struct delayed_work power_gate_work;
814 struct mutex power_lock;
815 struct mutex sido_lock;
816
817 /* mbhc module */
818 struct wcd_mbhc mbhc;
819 struct blocking_notifier_head notifier;
820 struct mutex micb_lock;
821
822 struct clk *wcd_ext_clk;
823 struct clk *wcd_native_clk;
824 struct mutex swr_read_lock;
825 struct mutex swr_write_lock;
826 struct mutex swr_clk_lock;
827 int swr_clk_users;
828 int native_clk_users;
829 int (*zdet_gpio_cb)(struct snd_soc_codec *codec, bool high);
830
831 struct snd_info_entry *entry;
832 struct snd_info_entry *version_entry;
833 int power_active_ref;
834
835 struct on_demand_supply on_demand_list[ON_DEMAND_SUPPLIES_MAX];
836
837 int (*machine_codec_event_cb)(struct snd_soc_codec *codec,
838 enum wcd9335_codec_event);
839 int spkr_gain_offset;
840 int spkr_mode;
841 int ear_spkr_gain;
842 struct hpf_work tx_hpf_work[TASHA_NUM_DECIMATORS];
843 struct tx_mute_work tx_mute_dwork[TASHA_NUM_DECIMATORS];
844 struct spk_anc_work spk_anc_dwork;
845 struct mutex codec_mutex;
846 int hph_l_gain;
847 int hph_r_gain;
848 int rx_7_count;
849 int rx_8_count;
850 bool clk_mode;
851 bool clk_internal;
852
853 /* Lock to protect mclk enablement */
854 struct mutex mclk_lock;
855};
856
857static int tasha_codec_vote_max_bw(struct snd_soc_codec *codec,
858 bool vote);
859
860static const struct tasha_reg_mask_val tasha_spkr_default[] = {
861 {WCD9335_CDC_COMPANDER7_CTL3, 0x80, 0x80},
862 {WCD9335_CDC_COMPANDER8_CTL3, 0x80, 0x80},
863 {WCD9335_CDC_COMPANDER7_CTL7, 0x01, 0x01},
864 {WCD9335_CDC_COMPANDER8_CTL7, 0x01, 0x01},
865 {WCD9335_CDC_BOOST0_BOOST_CTL, 0x7C, 0x50},
866 {WCD9335_CDC_BOOST1_BOOST_CTL, 0x7C, 0x50},
867};
868
869static const struct tasha_reg_mask_val tasha_spkr_mode1[] = {
870 {WCD9335_CDC_COMPANDER7_CTL3, 0x80, 0x00},
871 {WCD9335_CDC_COMPANDER8_CTL3, 0x80, 0x00},
872 {WCD9335_CDC_COMPANDER7_CTL7, 0x01, 0x00},
873 {WCD9335_CDC_COMPANDER8_CTL7, 0x01, 0x00},
874 {WCD9335_CDC_BOOST0_BOOST_CTL, 0x7C, 0x44},
875 {WCD9335_CDC_BOOST1_BOOST_CTL, 0x7C, 0x44},
876};
877
878/*
879 * wcd9335_get_codec_info: Get codec specific information
880 *
881 * @wcd9xxx: pointer to wcd9xxx structure
882 * @wcd_type: pointer to wcd9xxx_codec_type structure
883 *
884 * Returns 0 for success or negative error code for failure
885 */
886int wcd9335_get_codec_info(struct wcd9xxx *wcd9xxx,
887 struct wcd9xxx_codec_type *wcd_type)
888{
889 u16 id_minor, id_major;
890 struct regmap *wcd_regmap;
891 int rc, val, version = 0;
892
893 if (!wcd9xxx || !wcd_type)
894 return -EINVAL;
895
896 if (!wcd9xxx->regmap) {
897 dev_err(wcd9xxx->dev, "%s: wcd9xxx regmap is null!\n",
898 __func__);
899 return -EINVAL;
900 }
901 wcd_regmap = wcd9xxx->regmap;
902
903 rc = regmap_bulk_read(wcd_regmap, WCD9335_CHIP_TIER_CTRL_CHIP_ID_BYTE0,
904 (u8 *)&id_minor, sizeof(u16));
905 if (rc)
906 return -EINVAL;
907
908 rc = regmap_bulk_read(wcd_regmap, WCD9335_CHIP_TIER_CTRL_CHIP_ID_BYTE2,
909 (u8 *)&id_major, sizeof(u16));
910 if (rc)
911 return -EINVAL;
912
913 dev_info(wcd9xxx->dev, "%s: wcd9xxx chip id major 0x%x, minor 0x%x\n",
914 __func__, id_major, id_minor);
915
916 /* Version detection */
917 if (id_major == TASHA_MAJOR) {
918 regmap_read(wcd_regmap, WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT0,
919 &val);
920 version = ((u8)val & 0x80) >> 7;
921 } else if (id_major == TASHA2P0_MAJOR)
922 version = 2;
923 else
924 dev_err(wcd9xxx->dev, "%s: wcd9335 version unknown (major 0x%x, minor 0x%x)\n",
925 __func__, id_major, id_minor);
926
927 /* Fill codec type info */
928 wcd_type->id_major = id_major;
929 wcd_type->id_minor = id_minor;
930 wcd_type->num_irqs = WCD9335_NUM_IRQS;
931 wcd_type->version = version;
932 wcd_type->slim_slave_type = WCD9XXX_SLIM_SLAVE_ADDR_TYPE_1;
933 wcd_type->i2c_chip_status = 0x01;
934 wcd_type->intr_tbl = wcd9335_intr_table;
935 wcd_type->intr_tbl_size = ARRAY_SIZE(wcd9335_intr_table);
936
937 wcd_type->intr_reg[WCD9XXX_INTR_STATUS_BASE] =
938 WCD9335_INTR_PIN1_STATUS0;
939 wcd_type->intr_reg[WCD9XXX_INTR_CLEAR_BASE] =
940 WCD9335_INTR_PIN1_CLEAR0;
941 wcd_type->intr_reg[WCD9XXX_INTR_MASK_BASE] =
942 WCD9335_INTR_PIN1_MASK0;
943 wcd_type->intr_reg[WCD9XXX_INTR_LEVEL_BASE] =
944 WCD9335_INTR_LEVEL0;
945 wcd_type->intr_reg[WCD9XXX_INTR_CLR_COMMIT] =
946 WCD9335_INTR_CLR_COMMIT;
947
948 return rc;
949}
950EXPORT_SYMBOL(wcd9335_get_codec_info);
951
952/*
953 * wcd9335_bringdown: Bringdown WCD Codec
954 *
955 * @wcd9xxx: Pointer to wcd9xxx structure
956 *
957 * Returns 0 for success or negative error code for failure
958 */
959int wcd9335_bringdown(struct wcd9xxx *wcd9xxx)
960{
961 if (!wcd9xxx || !wcd9xxx->regmap)
962 return -EINVAL;
963
964 regmap_write(wcd9xxx->regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL,
965 0x04);
966
967 return 0;
968}
969EXPORT_SYMBOL(wcd9335_bringdown);
970
971/*
972 * wcd9335_bringup: Bringup WCD Codec
973 *
974 * @wcd9xxx: Pointer to the wcd9xxx structure
975 *
976 * Returns 0 for success or negative error code for failure
977 */
978int wcd9335_bringup(struct wcd9xxx *wcd9xxx)
979{
980 int ret = 0;
981 int val, byte0;
982 struct regmap *wcd_regmap;
983
984 if (!wcd9xxx)
985 return -EINVAL;
986
987 if (!wcd9xxx->regmap) {
988 dev_err(wcd9xxx->dev, "%s: wcd9xxx regmap is null!\n",
989 __func__);
990 return -EINVAL;
991 }
992 wcd_regmap = wcd9xxx->regmap;
993
994 regmap_read(wcd_regmap, WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT0, &val);
995 regmap_read(wcd_regmap, WCD9335_CHIP_TIER_CTRL_CHIP_ID_BYTE0, &byte0);
996
997 if ((val < 0) || (byte0 < 0)) {
998 dev_err(wcd9xxx->dev, "%s: tasha codec version detection fail!\n",
999 __func__);
1000 return -EINVAL;
1001 }
1002 if ((val & 0x80) && (byte0 == 0x0)) {
1003 dev_info(wcd9xxx->dev, "%s: wcd9335 codec version is v1.1\n",
1004 __func__);
1005 regmap_write(wcd_regmap, WCD9335_CODEC_RPM_RST_CTL, 0x01);
1006 regmap_write(wcd_regmap, WCD9335_SIDO_SIDO_CCL_2, 0xFC);
1007 regmap_write(wcd_regmap, WCD9335_SIDO_SIDO_CCL_4, 0x21);
1008 regmap_write(wcd_regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL,
1009 0x5);
1010 regmap_write(wcd_regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL,
1011 0x7);
1012 regmap_write(wcd_regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL,
1013 0x3);
1014 regmap_write(wcd_regmap, WCD9335_CODEC_RPM_RST_CTL, 0x3);
1015 } else if (byte0 == 0x1) {
1016 dev_info(wcd9xxx->dev, "%s: wcd9335 codec version is v2.0\n",
1017 __func__);
1018 regmap_write(wcd_regmap, WCD9335_CODEC_RPM_RST_CTL, 0x01);
1019 regmap_write(wcd_regmap, WCD9335_SIDO_SIDO_TEST_2, 0x00);
1020 regmap_write(wcd_regmap, WCD9335_SIDO_SIDO_CCL_8, 0x6F);
1021 regmap_write(wcd_regmap, WCD9335_BIAS_VBG_FINE_ADJ, 0x65);
1022 regmap_write(wcd_regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL,
1023 0x5);
1024 regmap_write(wcd_regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL,
1025 0x7);
1026 regmap_write(wcd_regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL,
1027 0x3);
1028 regmap_write(wcd_regmap, WCD9335_CODEC_RPM_RST_CTL, 0x3);
1029 } else if ((byte0 == 0) && (!(val & 0x80))) {
1030 dev_info(wcd9xxx->dev, "%s: wcd9335 codec version is v1.0\n",
1031 __func__);
1032 regmap_write(wcd_regmap, WCD9335_CODEC_RPM_RST_CTL, 0x01);
1033 regmap_write(wcd_regmap, WCD9335_SIDO_SIDO_CCL_2, 0xFC);
1034 regmap_write(wcd_regmap, WCD9335_SIDO_SIDO_CCL_4, 0x21);
1035 regmap_write(wcd_regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL,
1036 0x3);
1037 regmap_write(wcd_regmap, WCD9335_CODEC_RPM_RST_CTL, 0x3);
1038 } else {
1039 dev_err(wcd9xxx->dev, "%s: tasha codec version unknown\n",
1040 __func__);
1041 ret = -EINVAL;
1042 }
1043
1044 return ret;
1045}
1046EXPORT_SYMBOL(wcd9335_bringup);
1047
1048/**
1049 * tasha_set_spkr_gain_offset - offset the speaker path
1050 * gain with the given offset value.
1051 *
1052 * @codec: codec instance
1053 * @offset: Indicates speaker path gain offset value.
1054 *
1055 * Returns 0 on success or -EINVAL on error.
1056 */
1057int tasha_set_spkr_gain_offset(struct snd_soc_codec *codec, int offset)
1058{
1059 struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec);
1060
1061 if (!priv)
1062 return -EINVAL;
1063
1064 priv->spkr_gain_offset = offset;
1065 return 0;
1066}
1067EXPORT_SYMBOL(tasha_set_spkr_gain_offset);
1068
1069/**
1070 * tasha_set_spkr_mode - Configures speaker compander and smartboost
1071 * settings based on speaker mode.
1072 *
1073 * @codec: codec instance
1074 * @mode: Indicates speaker configuration mode.
1075 *
1076 * Returns 0 on success or -EINVAL on error.
1077 */
1078int tasha_set_spkr_mode(struct snd_soc_codec *codec, int mode)
1079{
1080 struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec);
1081 int i;
1082 const struct tasha_reg_mask_val *regs;
1083 int size;
1084
1085 if (!priv)
1086 return -EINVAL;
1087
1088 switch (mode) {
1089 case SPKR_MODE_1:
1090 regs = tasha_spkr_mode1;
1091 size = ARRAY_SIZE(tasha_spkr_mode1);
1092 break;
1093 default:
1094 regs = tasha_spkr_default;
1095 size = ARRAY_SIZE(tasha_spkr_default);
1096 break;
1097 }
1098
1099 priv->spkr_mode = mode;
1100 for (i = 0; i < size; i++)
1101 snd_soc_update_bits(codec, regs[i].reg,
1102 regs[i].mask, regs[i].val);
1103 return 0;
1104}
1105EXPORT_SYMBOL(tasha_set_spkr_mode);
1106
1107static void tasha_enable_sido_buck(struct snd_soc_codec *codec)
1108{
1109 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
1110
1111 snd_soc_update_bits(codec, WCD9335_ANA_RCO, 0x80, 0x80);
1112 snd_soc_update_bits(codec, WCD9335_ANA_BUCK_CTL, 0x02, 0x02);
1113 /* 100us sleep needed after IREF settings */
1114 usleep_range(100, 110);
1115 snd_soc_update_bits(codec, WCD9335_ANA_BUCK_CTL, 0x04, 0x04);
1116 /* 100us sleep needed after VREF settings */
1117 usleep_range(100, 110);
1118 tasha->resmgr->sido_input_src = SIDO_SOURCE_RCO_BG;
1119}
1120
1121static void tasha_cdc_sido_ccl_enable(struct tasha_priv *tasha, bool ccl_flag)
1122{
1123 struct snd_soc_codec *codec = tasha->codec;
1124
1125 if (!codec)
1126 return;
1127
1128 if (!TASHA_IS_2_0(tasha->wcd9xxx)) {
1129 dev_dbg(codec->dev, "%s: tasha version < 2p0, return\n",
1130 __func__);
1131 return;
1132 }
1133 dev_dbg(codec->dev, "%s: sido_ccl_cnt=%d, ccl_flag:%d\n",
1134 __func__, tasha->sido_ccl_cnt, ccl_flag);
1135 if (ccl_flag) {
1136 if (++tasha->sido_ccl_cnt == 1)
1137 snd_soc_update_bits(codec,
1138 WCD9335_SIDO_SIDO_CCL_10, 0xFF, 0x6E);
1139 } else {
1140 if (tasha->sido_ccl_cnt == 0) {
1141 dev_dbg(codec->dev, "%s: sido_ccl already disabled\n",
1142 __func__);
1143 return;
1144 }
1145 if (--tasha->sido_ccl_cnt == 0)
1146 snd_soc_update_bits(codec,
1147 WCD9335_SIDO_SIDO_CCL_10, 0xFF, 0x02);
1148 }
1149}
1150
1151static bool tasha_cdc_is_svs_enabled(struct tasha_priv *tasha)
1152{
1153 if (TASHA_IS_2_0(tasha->wcd9xxx) &&
1154 svs_scaling_enabled)
1155 return true;
1156
1157 return false;
1158}
1159
1160static int tasha_cdc_req_mclk_enable(struct tasha_priv *tasha,
1161 bool enable)
1162{
1163 int ret = 0;
1164
1165 mutex_lock(&tasha->mclk_lock);
1166 if (enable) {
1167 tasha_cdc_sido_ccl_enable(tasha, true);
1168 ret = clk_prepare_enable(tasha->wcd_ext_clk);
1169 if (ret) {
1170 dev_err(tasha->dev, "%s: ext clk enable failed\n",
1171 __func__);
1172 goto unlock_mutex;
1173 }
1174 /* get BG */
1175 wcd_resmgr_enable_master_bias(tasha->resmgr);
1176 /* get MCLK */
1177 wcd_resmgr_enable_clk_block(tasha->resmgr, WCD_CLK_MCLK);
1178 } else {
1179 /* put MCLK */
1180 wcd_resmgr_disable_clk_block(tasha->resmgr, WCD_CLK_MCLK);
1181 /* put BG */
1182 wcd_resmgr_disable_master_bias(tasha->resmgr);
1183 clk_disable_unprepare(tasha->wcd_ext_clk);
1184 tasha_cdc_sido_ccl_enable(tasha, false);
1185 }
1186unlock_mutex:
1187 mutex_unlock(&tasha->mclk_lock);
1188 return ret;
1189}
1190
1191static int tasha_cdc_check_sido_value(enum tasha_sido_voltage req_mv)
1192{
1193 if ((req_mv != SIDO_VOLTAGE_SVS_MV) &&
1194 (req_mv != SIDO_VOLTAGE_NOMINAL_MV))
1195 return -EINVAL;
1196
1197 return 0;
1198}
1199
1200static void tasha_codec_apply_sido_voltage(
1201 struct tasha_priv *tasha,
1202 enum tasha_sido_voltage req_mv)
1203{
1204 u32 vout_d_val;
1205 struct snd_soc_codec *codec = tasha->codec;
1206 int ret;
1207
1208 if (!codec)
1209 return;
1210
1211 if (!tasha_cdc_is_svs_enabled(tasha))
1212 return;
1213
1214 if ((sido_buck_svs_voltage != SIDO_VOLTAGE_SVS_MV) &&
1215 (sido_buck_svs_voltage != SIDO_VOLTAGE_NOMINAL_MV))
1216 sido_buck_svs_voltage = SIDO_VOLTAGE_SVS_MV;
1217
1218 ret = tasha_cdc_check_sido_value(req_mv);
1219 if (ret < 0) {
1220 dev_dbg(codec->dev, "%s: requested mv=%d not in range\n",
1221 __func__, req_mv);
1222 return;
1223 }
1224 if (req_mv == tasha->sido_voltage) {
1225 dev_dbg(codec->dev, "%s: Already at requested mv=%d\n",
1226 __func__, req_mv);
1227 return;
1228 }
1229 if (req_mv == sido_buck_svs_voltage) {
1230 if (test_bit(AUDIO_NOMINAL, &tasha->status_mask) ||
1231 test_bit(CPE_NOMINAL, &tasha->status_mask)) {
1232 dev_dbg(codec->dev,
1233 "%s: nominal client running, status_mask=%lu\n",
1234 __func__, tasha->status_mask);
1235 return;
1236 }
1237 }
1238 /* compute the vout_d step value */
1239 vout_d_val = CALCULATE_VOUT_D(req_mv);
1240 snd_soc_write(codec, WCD9335_ANA_BUCK_VOUT_D, vout_d_val & 0xFF);
1241 snd_soc_update_bits(codec, WCD9335_ANA_BUCK_CTL, 0x80, 0x80);
1242
1243 /* 1 msec sleep required after SIDO Vout_D voltage change */
1244 usleep_range(1000, 1100);
1245 tasha->sido_voltage = req_mv;
1246 dev_dbg(codec->dev,
1247 "%s: updated SIDO buck Vout_D to %d, vout_d step = %u\n",
1248 __func__, tasha->sido_voltage, vout_d_val);
1249
1250 snd_soc_update_bits(codec, WCD9335_ANA_BUCK_CTL,
1251 0x80, 0x00);
1252}
1253
1254static int tasha_codec_update_sido_voltage(
1255 struct tasha_priv *tasha,
1256 enum tasha_sido_voltage req_mv)
1257{
1258 int ret = 0;
1259
1260 if (!tasha_cdc_is_svs_enabled(tasha))
1261 return ret;
1262
1263 mutex_lock(&tasha->sido_lock);
1264 /* enable mclk before setting SIDO voltage */
1265 ret = tasha_cdc_req_mclk_enable(tasha, true);
1266 if (ret) {
1267 dev_err(tasha->dev, "%s: ext clk enable failed\n",
1268 __func__);
1269 goto err;
1270 }
1271 tasha_codec_apply_sido_voltage(tasha, req_mv);
1272 tasha_cdc_req_mclk_enable(tasha, false);
1273
1274err:
1275 mutex_unlock(&tasha->sido_lock);
1276 return ret;
1277}
1278
1279int tasha_enable_efuse_sensing(struct snd_soc_codec *codec)
1280{
1281 struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec);
1282
1283 tasha_cdc_mclk_enable(codec, true, false);
1284
1285 if (!TASHA_IS_2_0(priv->wcd9xxx))
1286 snd_soc_update_bits(codec, WCD9335_CHIP_TIER_CTRL_EFUSE_CTL,
1287 0x1E, 0x02);
1288 snd_soc_update_bits(codec, WCD9335_CHIP_TIER_CTRL_EFUSE_CTL,
1289 0x01, 0x01);
1290 /*
1291 * 5ms sleep required after enabling efuse control
1292 * before checking the status.
1293 */
1294 usleep_range(5000, 5500);
1295 if (!(snd_soc_read(codec, WCD9335_CHIP_TIER_CTRL_EFUSE_STATUS) & 0x01))
1296 WARN(1, "%s: Efuse sense is not complete\n", __func__);
1297
1298 if (TASHA_IS_2_0(priv->wcd9xxx)) {
1299 if (!(snd_soc_read(codec,
1300 WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT0) & 0x40))
1301 snd_soc_update_bits(codec, WCD9335_HPH_R_ATEST,
1302 0x04, 0x00);
1303 tasha_enable_sido_buck(codec);
1304 }
1305
1306 tasha_cdc_mclk_enable(codec, false, false);
1307
1308 return 0;
1309}
1310EXPORT_SYMBOL(tasha_enable_efuse_sensing);
1311
1312void *tasha_get_afe_config(struct snd_soc_codec *codec,
1313 enum afe_config_type config_type)
1314{
1315 struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec);
1316
1317 switch (config_type) {
1318 case AFE_SLIMBUS_SLAVE_CONFIG:
1319 return &priv->slimbus_slave_cfg;
1320 case AFE_CDC_REGISTERS_CONFIG:
1321 return &tasha_audio_reg_cfg;
1322 case AFE_SLIMBUS_SLAVE_PORT_CONFIG:
1323 return &tasha_slimbus_slave_port_cfg;
1324 case AFE_AANC_VERSION:
1325 return &tasha_cdc_aanc_version;
1326 case AFE_CLIP_BANK_SEL:
1327 return NULL;
1328 case AFE_CDC_CLIP_REGISTERS_CONFIG:
1329 return NULL;
1330 case AFE_CDC_REGISTER_PAGE_CONFIG:
1331 return &tasha_cdc_reg_page_cfg;
1332 default:
1333 dev_err(codec->dev, "%s: Unknown config_type 0x%x\n",
1334 __func__, config_type);
1335 return NULL;
1336 }
1337}
1338EXPORT_SYMBOL(tasha_get_afe_config);
1339
1340/*
1341 * tasha_event_register: Registers a machine driver callback
1342 * function with codec private data for post ADSP sub-system
1343 * restart (SSR). This callback function will be called from
1344 * codec driver once codec comes out of reset after ADSP SSR.
1345 *
1346 * @machine_event_cb: callback function from machine driver
1347 * @codec: Codec instance
1348 *
1349 * Return: none
1350 */
1351void tasha_event_register(
1352 int (*machine_event_cb)(struct snd_soc_codec *codec,
1353 enum wcd9335_codec_event),
1354 struct snd_soc_codec *codec)
1355{
1356 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
1357
1358 if (tasha)
1359 tasha->machine_codec_event_cb = machine_event_cb;
1360 else
1361 dev_dbg(codec->dev, "%s: Invalid tasha_priv data\n", __func__);
1362}
1363EXPORT_SYMBOL(tasha_event_register);
1364
1365static int tasha_mbhc_request_irq(struct snd_soc_codec *codec,
1366 int irq, irq_handler_t handler,
1367 const char *name, void *data)
1368{
1369 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
1370 struct wcd9xxx *wcd9xxx = tasha->wcd9xxx;
1371 struct wcd9xxx_core_resource *core_res =
1372 &wcd9xxx->core_res;
1373
1374 return wcd9xxx_request_irq(core_res, irq, handler, name, data);
1375}
1376
1377static void tasha_mbhc_irq_control(struct snd_soc_codec *codec,
1378 int irq, bool enable)
1379{
1380 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
1381 struct wcd9xxx *wcd9xxx = tasha->wcd9xxx;
1382 struct wcd9xxx_core_resource *core_res =
1383 &wcd9xxx->core_res;
1384 if (enable)
1385 wcd9xxx_enable_irq(core_res, irq);
1386 else
1387 wcd9xxx_disable_irq(core_res, irq);
1388}
1389
1390static int tasha_mbhc_free_irq(struct snd_soc_codec *codec,
1391 int irq, void *data)
1392{
1393 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
1394 struct wcd9xxx *wcd9xxx = tasha->wcd9xxx;
1395 struct wcd9xxx_core_resource *core_res =
1396 &wcd9xxx->core_res;
1397
1398 wcd9xxx_free_irq(core_res, irq, data);
1399 return 0;
1400}
1401
1402static void tasha_mbhc_clk_setup(struct snd_soc_codec *codec,
1403 bool enable)
1404{
1405 if (enable)
1406 snd_soc_update_bits(codec, WCD9335_MBHC_CTL_1,
1407 0x80, 0x80);
1408 else
1409 snd_soc_update_bits(codec, WCD9335_MBHC_CTL_1,
1410 0x80, 0x00);
1411}
1412
1413static int tasha_mbhc_btn_to_num(struct snd_soc_codec *codec)
1414{
1415 return snd_soc_read(codec, WCD9335_ANA_MBHC_RESULT_3) & 0x7;
1416}
1417
1418static void tasha_mbhc_mbhc_bias_control(struct snd_soc_codec *codec,
1419 bool enable)
1420{
1421 if (enable)
1422 snd_soc_update_bits(codec, WCD9335_ANA_MBHC_ELECT,
1423 0x01, 0x01);
1424 else
1425 snd_soc_update_bits(codec, WCD9335_ANA_MBHC_ELECT,
1426 0x01, 0x00);
1427}
1428
1429static void tasha_mbhc_program_btn_thr(struct snd_soc_codec *codec,
1430 s16 *btn_low, s16 *btn_high,
1431 int num_btn, bool is_micbias)
1432{
1433 int i;
1434 int vth;
1435
1436 if (num_btn > WCD_MBHC_DEF_BUTTONS) {
1437 dev_err(codec->dev, "%s: invalid number of buttons: %d\n",
1438 __func__, num_btn);
1439 return;
1440 }
1441 /*
1442 * Tasha just needs one set of thresholds for button detection
1443 * due to micbias voltage ramp to pullup upon button press. So
1444 * btn_low and is_micbias are ignored and always program button
1445 * thresholds using btn_high.
1446 */
1447 for (i = 0; i < num_btn; i++) {
1448 vth = ((btn_high[i] * 2) / 25) & 0x3F;
1449 snd_soc_update_bits(codec, WCD9335_ANA_MBHC_BTN0 + i,
1450 0xFC, vth << 2);
1451 dev_dbg(codec->dev, "%s: btn_high[%d]: %d, vth: %d\n",
1452 __func__, i, btn_high[i], vth);
1453 }
1454}
1455
1456static bool tasha_mbhc_lock_sleep(struct wcd_mbhc *mbhc, bool lock)
1457{
1458 struct snd_soc_codec *codec = mbhc->codec;
1459 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
1460 struct wcd9xxx *wcd9xxx = tasha->wcd9xxx;
1461 struct wcd9xxx_core_resource *core_res =
1462 &wcd9xxx->core_res;
1463 if (lock)
1464 return wcd9xxx_lock_sleep(core_res);
1465 else {
1466 wcd9xxx_unlock_sleep(core_res);
1467 return 0;
1468 }
1469}
1470
1471static int tasha_mbhc_register_notifier(struct wcd_mbhc *mbhc,
1472 struct notifier_block *nblock,
1473 bool enable)
1474{
1475 struct snd_soc_codec *codec = mbhc->codec;
1476 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
1477
1478 if (enable)
1479 return blocking_notifier_chain_register(&tasha->notifier,
1480 nblock);
1481 else
1482 return blocking_notifier_chain_unregister(&tasha->notifier,
1483 nblock);
1484}
1485
1486static bool tasha_mbhc_micb_en_status(struct wcd_mbhc *mbhc, int micb_num)
1487{
1488 u8 val;
1489
1490 if (micb_num == MIC_BIAS_2) {
1491 val = (snd_soc_read(mbhc->codec, WCD9335_ANA_MICB2) >> 6);
1492 if (val == 0x01)
1493 return true;
1494 }
1495 return false;
1496}
1497
1498static bool tasha_mbhc_hph_pa_on_status(struct snd_soc_codec *codec)
1499{
1500 return (snd_soc_read(codec, WCD9335_ANA_HPH) & 0xC0) ? true : false;
1501}
1502
1503static void tasha_mbhc_hph_l_pull_up_control(struct snd_soc_codec *codec,
1504 enum mbhc_hs_pullup_iref pull_up_cur)
1505{
1506 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
1507
1508 if (!tasha)
1509 return;
1510
1511 /* Default pull up current to 2uA */
1512 if (pull_up_cur < I_OFF || pull_up_cur > I_3P0_UA ||
1513 pull_up_cur == I_DEFAULT)
1514 pull_up_cur = I_2P0_UA;
1515
1516 dev_dbg(codec->dev, "%s: HS pull up current:%d\n",
1517 __func__, pull_up_cur);
1518
1519 if (TASHA_IS_2_0(tasha->wcd9xxx))
1520 snd_soc_update_bits(codec, WCD9335_MBHC_PLUG_DETECT_CTL,
1521 0xC0, pull_up_cur << 6);
1522 else
1523 snd_soc_update_bits(codec, WCD9335_MBHC_PLUG_DETECT_CTL,
1524 0xC0, 0x40);
1525}
1526
1527static int tasha_enable_ext_mb_source(struct wcd_mbhc *mbhc,
1528 bool turn_on)
1529{
1530 struct snd_soc_codec *codec = mbhc->codec;
1531 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
1532 int ret = 0;
1533 struct on_demand_supply *supply;
1534
1535 if (!tasha)
1536 return -EINVAL;
1537
1538 supply = &tasha->on_demand_list[ON_DEMAND_MICBIAS];
1539 if (!supply->supply) {
1540 dev_dbg(codec->dev, "%s: warning supply not present ond for %s\n",
1541 __func__, "onDemand Micbias");
1542 return ret;
1543 }
1544
1545 dev_dbg(codec->dev, "%s turn_on: %d count: %d\n", __func__, turn_on,
1546 supply->ondemand_supply_count);
1547
1548 if (turn_on) {
1549 if (!(supply->ondemand_supply_count)) {
1550 ret = snd_soc_dapm_force_enable_pin(
1551 snd_soc_codec_get_dapm(codec),
1552 "MICBIAS_REGULATOR");
1553 snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec));
1554 }
1555 supply->ondemand_supply_count++;
1556 } else {
1557 if (supply->ondemand_supply_count > 0)
1558 supply->ondemand_supply_count--;
1559 if (!(supply->ondemand_supply_count)) {
1560 ret = snd_soc_dapm_disable_pin(
1561 snd_soc_codec_get_dapm(codec),
1562 "MICBIAS_REGULATOR");
1563 snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec));
1564 }
1565 }
1566
1567 if (ret)
1568 dev_err(codec->dev, "%s: Failed to %s external micbias source\n",
1569 __func__, turn_on ? "enable" : "disabled");
1570 else
1571 dev_dbg(codec->dev, "%s: %s external micbias source\n",
1572 __func__, turn_on ? "Enabled" : "Disabled");
1573
1574 return ret;
1575}
1576
1577static int tasha_micbias_control(struct snd_soc_codec *codec,
1578 int micb_num,
1579 int req, bool is_dapm)
1580{
1581 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
1582 int micb_index = micb_num - 1;
1583 u16 micb_reg;
1584 int pre_off_event = 0, post_off_event = 0;
1585 int post_on_event = 0, post_dapm_off = 0;
1586 int post_dapm_on = 0;
1587
1588 if ((micb_index < 0) || (micb_index > TASHA_MAX_MICBIAS - 1)) {
1589 dev_err(codec->dev, "%s: Invalid micbias index, micb_ind:%d\n",
1590 __func__, micb_index);
1591 return -EINVAL;
1592 }
1593 switch (micb_num) {
1594 case MIC_BIAS_1:
1595 micb_reg = WCD9335_ANA_MICB1;
1596 break;
1597 case MIC_BIAS_2:
1598 micb_reg = WCD9335_ANA_MICB2;
1599 pre_off_event = WCD_EVENT_PRE_MICBIAS_2_OFF;
1600 post_off_event = WCD_EVENT_POST_MICBIAS_2_OFF;
1601 post_on_event = WCD_EVENT_POST_MICBIAS_2_ON;
1602 post_dapm_on = WCD_EVENT_POST_DAPM_MICBIAS_2_ON;
1603 post_dapm_off = WCD_EVENT_POST_DAPM_MICBIAS_2_OFF;
1604 break;
1605 case MIC_BIAS_3:
1606 micb_reg = WCD9335_ANA_MICB3;
1607 break;
1608 case MIC_BIAS_4:
1609 micb_reg = WCD9335_ANA_MICB4;
1610 break;
1611 default:
1612 dev_err(codec->dev, "%s: Invalid micbias number: %d\n",
1613 __func__, micb_num);
1614 return -EINVAL;
1615 }
1616 mutex_lock(&tasha->micb_lock);
1617
1618 switch (req) {
1619 case MICB_PULLUP_ENABLE:
1620 tasha->pullup_ref[micb_index]++;
1621 if ((tasha->pullup_ref[micb_index] == 1) &&
1622 (tasha->micb_ref[micb_index] == 0))
1623 snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80);
1624 break;
1625 case MICB_PULLUP_DISABLE:
1626 if (tasha->pullup_ref[micb_index] > 0)
1627 tasha->pullup_ref[micb_index]--;
1628 if ((tasha->pullup_ref[micb_index] == 0) &&
1629 (tasha->micb_ref[micb_index] == 0))
1630 snd_soc_update_bits(codec, micb_reg, 0xC0, 0x00);
1631 break;
1632 case MICB_ENABLE:
1633 tasha->micb_ref[micb_index]++;
1634 if (tasha->micb_ref[micb_index] == 1) {
1635 snd_soc_update_bits(codec, micb_reg, 0xC0, 0x40);
1636 if (post_on_event)
1637 blocking_notifier_call_chain(&tasha->notifier,
1638 post_on_event, &tasha->mbhc);
1639 }
1640 if (is_dapm && post_dapm_on)
1641 blocking_notifier_call_chain(&tasha->notifier,
1642 post_dapm_on, &tasha->mbhc);
1643 break;
1644 case MICB_DISABLE:
1645 if (tasha->micb_ref[micb_index] > 0)
1646 tasha->micb_ref[micb_index]--;
1647 if ((tasha->micb_ref[micb_index] == 0) &&
1648 (tasha->pullup_ref[micb_index] > 0))
1649 snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80);
1650 else if ((tasha->micb_ref[micb_index] == 0) &&
1651 (tasha->pullup_ref[micb_index] == 0)) {
1652 if (pre_off_event)
1653 blocking_notifier_call_chain(&tasha->notifier,
1654 pre_off_event, &tasha->mbhc);
1655 snd_soc_update_bits(codec, micb_reg, 0xC0, 0x00);
1656 if (post_off_event)
1657 blocking_notifier_call_chain(&tasha->notifier,
1658 post_off_event, &tasha->mbhc);
1659 }
1660 if (is_dapm && post_dapm_off)
1661 blocking_notifier_call_chain(&tasha->notifier,
1662 post_dapm_off, &tasha->mbhc);
1663 break;
1664 };
1665
1666 dev_dbg(codec->dev, "%s: micb_num:%d, micb_ref: %d, pullup_ref: %d\n",
1667 __func__, micb_num, tasha->micb_ref[micb_index],
1668 tasha->pullup_ref[micb_index]);
1669
1670 mutex_unlock(&tasha->micb_lock);
1671
1672 return 0;
1673}
1674
1675static int tasha_mbhc_request_micbias(struct snd_soc_codec *codec,
1676 int micb_num, int req)
1677{
1678 int ret;
1679
1680 /*
1681 * If micbias is requested, make sure that there
1682 * is vote to enable mclk
1683 */
1684 if (req == MICB_ENABLE)
1685 tasha_cdc_mclk_enable(codec, true, false);
1686
1687 ret = tasha_micbias_control(codec, micb_num, req, false);
1688
1689 /*
1690 * Release vote for mclk while requesting for
1691 * micbias disable
1692 */
1693 if (req == MICB_DISABLE)
1694 tasha_cdc_mclk_enable(codec, false, false);
1695
1696 return ret;
1697}
1698
1699static void tasha_mbhc_micb_ramp_control(struct snd_soc_codec *codec,
1700 bool enable)
1701{
1702 if (enable) {
1703 snd_soc_update_bits(codec, WCD9335_ANA_MICB2_RAMP,
1704 0x1C, 0x0C);
1705 snd_soc_update_bits(codec, WCD9335_ANA_MICB2_RAMP,
1706 0x80, 0x80);
1707 } else {
1708 snd_soc_update_bits(codec, WCD9335_ANA_MICB2_RAMP,
1709 0x80, 0x00);
1710 snd_soc_update_bits(codec, WCD9335_ANA_MICB2_RAMP,
1711 0x1C, 0x00);
1712 }
1713}
1714
1715static struct firmware_cal *tasha_get_hwdep_fw_cal(struct wcd_mbhc *mbhc,
1716 enum wcd_cal_type type)
1717{
1718 struct tasha_priv *tasha;
1719 struct firmware_cal *hwdep_cal;
1720 struct snd_soc_codec *codec = mbhc->codec;
1721
1722 if (!codec) {
1723 pr_err("%s: NULL codec pointer\n", __func__);
1724 return NULL;
1725 }
1726 tasha = snd_soc_codec_get_drvdata(codec);
1727 hwdep_cal = wcdcal_get_fw_cal(tasha->fw_data, type);
1728 if (!hwdep_cal)
1729 dev_err(codec->dev, "%s: cal not sent by %d\n",
1730 __func__, type);
1731
1732 return hwdep_cal;
1733}
1734
1735static int tasha_mbhc_micb_adjust_voltage(struct snd_soc_codec *codec,
1736 int req_volt,
1737 int micb_num)
1738{
1739 int cur_vout_ctl, req_vout_ctl;
1740 int micb_reg, micb_val, micb_en;
1741
1742 switch (micb_num) {
1743 case MIC_BIAS_1:
1744 micb_reg = WCD9335_ANA_MICB1;
1745 break;
1746 case MIC_BIAS_2:
1747 micb_reg = WCD9335_ANA_MICB2;
1748 break;
1749 case MIC_BIAS_3:
1750 micb_reg = WCD9335_ANA_MICB3;
1751 break;
1752 case MIC_BIAS_4:
1753 micb_reg = WCD9335_ANA_MICB4;
1754 break;
1755 default:
1756 return -EINVAL;
1757 }
1758
1759 /*
1760 * If requested micbias voltage is same as current micbias
1761 * voltage, then just return. Otherwise, adjust voltage as
1762 * per requested value. If micbias is already enabled, then
1763 * to avoid slow micbias ramp-up or down enable pull-up
1764 * momentarily, change the micbias value and then re-enable
1765 * micbias.
1766 */
1767 micb_val = snd_soc_read(codec, micb_reg);
1768 micb_en = (micb_val & 0xC0) >> 6;
1769 cur_vout_ctl = micb_val & 0x3F;
1770
1771 req_vout_ctl = wcd9335_get_micb_vout_ctl_val(req_volt);
Xiaoyu Ye1a2d8bd92017-01-31 18:54:15 -08001772 if (req_vout_ctl < 0)
Banajit Goswamide8271c2017-01-18 00:28:59 -08001773 return -EINVAL;
1774 if (cur_vout_ctl == req_vout_ctl)
1775 return 0;
1776
1777 dev_dbg(codec->dev, "%s: micb_num: %d, cur_mv: %d, req_mv: %d, micb_en: %d\n",
1778 __func__, micb_num, WCD_VOUT_CTL_TO_MICB(cur_vout_ctl),
1779 req_volt, micb_en);
1780
1781 if (micb_en == 0x1)
1782 snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80);
1783
1784 snd_soc_update_bits(codec, micb_reg, 0x3F, req_vout_ctl);
1785
1786 if (micb_en == 0x1) {
1787 snd_soc_update_bits(codec, micb_reg, 0xC0, 0x40);
1788 /*
1789 * Add 2ms delay as per HW requirement after enabling
1790 * micbias
1791 */
1792 usleep_range(2000, 2100);
1793 }
1794
1795 return 0;
1796}
1797
1798static int tasha_mbhc_micb_ctrl_threshold_mic(struct snd_soc_codec *codec,
1799 int micb_num, bool req_en)
1800{
1801 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
1802 struct wcd9xxx_pdata *pdata = dev_get_platdata(codec->dev->parent);
1803 int rc, micb_mv;
1804
1805 if (micb_num != MIC_BIAS_2)
1806 return -EINVAL;
1807
1808 /*
1809 * If device tree micbias level is already above the minimum
1810 * voltage needed to detect threshold microphone, then do
1811 * not change the micbias, just return.
1812 */
1813 if (pdata->micbias.micb2_mv >= WCD_MBHC_THR_HS_MICB_MV)
1814 return 0;
1815
1816 micb_mv = req_en ? WCD_MBHC_THR_HS_MICB_MV : pdata->micbias.micb2_mv;
1817
1818 mutex_lock(&tasha->micb_lock);
1819 rc = tasha_mbhc_micb_adjust_voltage(codec, micb_mv, MIC_BIAS_2);
1820 mutex_unlock(&tasha->micb_lock);
1821
1822 return rc;
1823}
1824
1825static inline void tasha_mbhc_get_result_params(struct wcd9xxx *wcd9xxx,
1826 s16 *d1_a, u16 noff,
1827 int32_t *zdet)
1828{
1829 int i;
1830 int val, val1;
1831 s16 c1;
1832 s32 x1, d1;
1833 int32_t denom;
1834 int minCode_param[] = {
1835 3277, 1639, 820, 410, 205, 103, 52, 26
1836 };
1837
1838 regmap_update_bits(wcd9xxx->regmap, WCD9335_ANA_MBHC_ZDET, 0x20, 0x20);
1839 for (i = 0; i < TASHA_ZDET_NUM_MEASUREMENTS; i++) {
1840 regmap_read(wcd9xxx->regmap, WCD9335_ANA_MBHC_RESULT_2, &val);
1841 if (val & 0x80)
1842 break;
1843 }
1844 val = val << 0x8;
1845 regmap_read(wcd9xxx->regmap, WCD9335_ANA_MBHC_RESULT_1, &val1);
1846 val |= val1;
1847 regmap_update_bits(wcd9xxx->regmap, WCD9335_ANA_MBHC_ZDET, 0x20, 0x00);
1848 x1 = TASHA_MBHC_GET_X1(val);
1849 c1 = TASHA_MBHC_GET_C1(val);
1850 /* If ramp is not complete, give additional 5ms */
1851 if ((c1 < 2) && x1)
1852 usleep_range(5000, 5050);
1853
1854 if (!c1 || !x1) {
1855 dev_dbg(wcd9xxx->dev,
1856 "%s: Impedance detect ramp error, c1=%d, x1=0x%x\n",
1857 __func__, c1, x1);
1858 goto ramp_down;
1859 }
1860 d1 = d1_a[c1];
1861 denom = (x1 * d1) - (1 << (14 - noff));
1862 if (denom > 0)
1863 *zdet = (TASHA_MBHC_ZDET_CONST * 1000) / denom;
1864 else if (x1 < minCode_param[noff])
1865 *zdet = TASHA_ZDET_FLOATING_IMPEDANCE;
1866
1867 dev_dbg(wcd9xxx->dev, "%s: d1=%d, c1=%d, x1=0x%x, z_val=%d(milliOhm)\n",
1868 __func__, d1, c1, x1, *zdet);
1869ramp_down:
1870 i = 0;
1871 while (x1) {
1872 regmap_bulk_read(wcd9xxx->regmap,
1873 WCD9335_ANA_MBHC_RESULT_1, (u8 *)&val, 2);
1874 x1 = TASHA_MBHC_GET_X1(val);
1875 i++;
1876 if (i == TASHA_ZDET_NUM_MEASUREMENTS)
1877 break;
1878 }
1879}
1880
1881/*
1882 * tasha_mbhc_zdet_gpio_ctrl: Register callback function for
1883 * controlling the switch on hifi amps. Default switch state
1884 * will put a 51ohm load in parallel to the hph load. So,
1885 * impedance detection function will pull the gpio high
1886 * to make the switch open.
1887 *
1888 * @zdet_gpio_cb: callback function from machine driver
1889 * @codec: Codec instance
1890 *
1891 * Return: none
1892 */
1893void tasha_mbhc_zdet_gpio_ctrl(
1894 int (*zdet_gpio_cb)(struct snd_soc_codec *codec, bool high),
1895 struct snd_soc_codec *codec)
1896{
1897 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
1898
1899 tasha->zdet_gpio_cb = zdet_gpio_cb;
1900}
1901EXPORT_SYMBOL(tasha_mbhc_zdet_gpio_ctrl);
1902
1903static void tasha_mbhc_zdet_ramp(struct snd_soc_codec *codec,
1904 struct tasha_mbhc_zdet_param *zdet_param,
1905 int32_t *zl, int32_t *zr, s16 *d1_a)
1906{
1907 struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent);
1908 int32_t zdet = 0;
1909
1910 snd_soc_update_bits(codec, WCD9335_MBHC_ZDET_ANA_CTL, 0x70,
1911 zdet_param->ldo_ctl << 4);
1912 snd_soc_update_bits(codec, WCD9335_ANA_MBHC_BTN5, 0xFC,
1913 zdet_param->btn5);
1914 snd_soc_update_bits(codec, WCD9335_ANA_MBHC_BTN6, 0xFC,
1915 zdet_param->btn6);
1916 snd_soc_update_bits(codec, WCD9335_ANA_MBHC_BTN7, 0xFC,
1917 zdet_param->btn7);
1918 snd_soc_update_bits(codec, WCD9335_MBHC_ZDET_ANA_CTL, 0x0F,
1919 zdet_param->noff);
1920 snd_soc_update_bits(codec, WCD9335_MBHC_ZDET_RAMP_CTL, 0x0F,
1921 zdet_param->nshift);
1922
1923 if (!zl)
1924 goto z_right;
1925 /* Start impedance measurement for HPH_L */
1926 regmap_update_bits(wcd9xxx->regmap,
1927 WCD9335_ANA_MBHC_ZDET, 0x80, 0x80);
1928 dev_dbg(wcd9xxx->dev, "%s: ramp for HPH_L, noff = %d\n",
1929 __func__, zdet_param->noff);
1930 tasha_mbhc_get_result_params(wcd9xxx, d1_a, zdet_param->noff, &zdet);
1931 regmap_update_bits(wcd9xxx->regmap,
1932 WCD9335_ANA_MBHC_ZDET, 0x80, 0x00);
1933
1934 *zl = zdet;
1935
1936z_right:
1937 if (!zr)
1938 return;
1939 /* Start impedance measurement for HPH_R */
1940 regmap_update_bits(wcd9xxx->regmap,
1941 WCD9335_ANA_MBHC_ZDET, 0x40, 0x40);
1942 dev_dbg(wcd9xxx->dev, "%s: ramp for HPH_R, noff = %d\n",
1943 __func__, zdet_param->noff);
1944 tasha_mbhc_get_result_params(wcd9xxx, d1_a, zdet_param->noff, &zdet);
1945 regmap_update_bits(wcd9xxx->regmap,
1946 WCD9335_ANA_MBHC_ZDET, 0x40, 0x00);
1947
1948 *zr = zdet;
1949}
1950
1951static inline void tasha_wcd_mbhc_qfuse_cal(struct snd_soc_codec *codec,
1952 int32_t *z_val, int flag_l_r)
1953{
1954 s16 q1;
1955 int q1_cal;
1956
1957 if (*z_val < (TASHA_ZDET_VAL_400/1000))
1958 q1 = snd_soc_read(codec,
1959 WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT1 + (2 * flag_l_r));
1960 else
1961 q1 = snd_soc_read(codec,
1962 WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT2 + (2 * flag_l_r));
1963 if (q1 & 0x80)
1964 q1_cal = (10000 - ((q1 & 0x7F) * 25));
1965 else
1966 q1_cal = (10000 + (q1 * 25));
1967 if (q1_cal > 0)
1968 *z_val = ((*z_val) * 10000) / q1_cal;
1969}
1970
1971static void tasha_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl,
1972 uint32_t *zr)
1973{
1974 struct snd_soc_codec *codec = mbhc->codec;
1975 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
1976 struct wcd9xxx *wcd9xxx = tasha->wcd9xxx;
1977 s16 reg0, reg1, reg2, reg3, reg4;
1978 int32_t z1L, z1R, z1Ls;
1979 int zMono, z_diff1, z_diff2;
1980 bool is_fsm_disable = false;
1981 bool is_change = false;
1982 struct tasha_mbhc_zdet_param zdet_param[] = {
1983 {4, 0, 4, 0x08, 0x14, 0x18}, /* < 32ohm */
1984 {2, 0, 3, 0x18, 0x7C, 0x90}, /* 32ohm < Z < 400ohm */
1985 {1, 4, 5, 0x18, 0x7C, 0x90}, /* 400ohm < Z < 1200ohm */
1986 {1, 6, 7, 0x18, 0x7C, 0x90}, /* >1200ohm */
1987 };
1988 struct tasha_mbhc_zdet_param *zdet_param_ptr = NULL;
1989 s16 d1_a[][4] = {
1990 {0, 30, 90, 30},
1991 {0, 30, 30, 5},
1992 {0, 30, 30, 5},
1993 {0, 30, 30, 5},
1994 };
1995 s16 *d1 = NULL;
1996
1997 if (!TASHA_IS_2_0(wcd9xxx)) {
1998 dev_dbg(codec->dev, "%s: Z-det is not supported for this codec version\n",
1999 __func__);
2000 *zl = 0;
2001 *zr = 0;
2002 return;
2003 }
2004 WCD_MBHC_RSC_ASSERT_LOCKED(mbhc);
2005
2006 if (tasha->zdet_gpio_cb)
2007 is_change = tasha->zdet_gpio_cb(codec, true);
2008
2009 reg0 = snd_soc_read(codec, WCD9335_ANA_MBHC_BTN5);
2010 reg1 = snd_soc_read(codec, WCD9335_ANA_MBHC_BTN6);
2011 reg2 = snd_soc_read(codec, WCD9335_ANA_MBHC_BTN7);
2012 reg3 = snd_soc_read(codec, WCD9335_MBHC_CTL_1);
2013 reg4 = snd_soc_read(codec, WCD9335_MBHC_ZDET_ANA_CTL);
2014
2015 if (snd_soc_read(codec, WCD9335_ANA_MBHC_ELECT) & 0x80) {
2016 is_fsm_disable = true;
2017 regmap_update_bits(wcd9xxx->regmap,
2018 WCD9335_ANA_MBHC_ELECT, 0x80, 0x00);
2019 }
2020
2021 /* For NO-jack, disable L_DET_EN before Z-det measurements */
2022 if (mbhc->hphl_swh)
2023 regmap_update_bits(wcd9xxx->regmap,
2024 WCD9335_ANA_MBHC_MECH, 0x80, 0x00);
2025
2026 /* Enable AZ */
2027 snd_soc_update_bits(codec, WCD9335_MBHC_CTL_1, 0x0C, 0x04);
2028 /* Turn off 100k pull down on HPHL */
2029 regmap_update_bits(wcd9xxx->regmap,
2030 WCD9335_ANA_MBHC_MECH, 0x01, 0x00);
2031
2032 /* First get impedance on Left */
2033 d1 = d1_a[1];
2034 zdet_param_ptr = &zdet_param[1];
2035 tasha_mbhc_zdet_ramp(codec, zdet_param_ptr, &z1L, NULL, d1);
2036
2037 if (!TASHA_MBHC_IS_SECOND_RAMP_REQUIRED(z1L))
2038 goto left_ch_impedance;
2039
2040 /* second ramp for left ch */
2041 if (z1L < TASHA_ZDET_VAL_32) {
2042 zdet_param_ptr = &zdet_param[0];
2043 d1 = d1_a[0];
2044 } else if ((z1L > TASHA_ZDET_VAL_400) && (z1L <= TASHA_ZDET_VAL_1200)) {
2045 zdet_param_ptr = &zdet_param[2];
2046 d1 = d1_a[2];
2047 } else if (z1L > TASHA_ZDET_VAL_1200) {
2048 zdet_param_ptr = &zdet_param[3];
2049 d1 = d1_a[3];
2050 }
2051 tasha_mbhc_zdet_ramp(codec, zdet_param_ptr, &z1L, NULL, d1);
2052
2053left_ch_impedance:
2054 if ((z1L == TASHA_ZDET_FLOATING_IMPEDANCE) ||
2055 (z1L > TASHA_ZDET_VAL_100K)) {
2056 *zl = TASHA_ZDET_FLOATING_IMPEDANCE;
2057 zdet_param_ptr = &zdet_param[1];
2058 d1 = d1_a[1];
2059 } else {
2060 *zl = z1L/1000;
2061 tasha_wcd_mbhc_qfuse_cal(codec, zl, 0);
2062 }
2063 dev_dbg(codec->dev, "%s: impedance on HPH_L = %d(ohms)\n",
2064 __func__, *zl);
2065
2066 /* start of right impedance ramp and calculation */
2067 tasha_mbhc_zdet_ramp(codec, zdet_param_ptr, NULL, &z1R, d1);
2068 if (TASHA_MBHC_IS_SECOND_RAMP_REQUIRED(z1R)) {
2069 if (((z1R > TASHA_ZDET_VAL_1200) &&
2070 (zdet_param_ptr->noff == 0x6)) ||
2071 ((*zl) != TASHA_ZDET_FLOATING_IMPEDANCE))
2072 goto right_ch_impedance;
2073 /* second ramp for right ch */
2074 if (z1R < TASHA_ZDET_VAL_32) {
2075 zdet_param_ptr = &zdet_param[0];
2076 d1 = d1_a[0];
2077 } else if ((z1R > TASHA_ZDET_VAL_400) &&
2078 (z1R <= TASHA_ZDET_VAL_1200)) {
2079 zdet_param_ptr = &zdet_param[2];
2080 d1 = d1_a[2];
2081 } else if (z1R > TASHA_ZDET_VAL_1200) {
2082 zdet_param_ptr = &zdet_param[3];
2083 d1 = d1_a[3];
2084 }
2085 tasha_mbhc_zdet_ramp(codec, zdet_param_ptr, NULL, &z1R, d1);
2086 }
2087right_ch_impedance:
2088 if ((z1R == TASHA_ZDET_FLOATING_IMPEDANCE) ||
2089 (z1R > TASHA_ZDET_VAL_100K)) {
2090 *zr = TASHA_ZDET_FLOATING_IMPEDANCE;
2091 } else {
2092 *zr = z1R/1000;
2093 tasha_wcd_mbhc_qfuse_cal(codec, zr, 1);
2094 }
2095 dev_dbg(codec->dev, "%s: impedance on HPH_R = %d(ohms)\n",
2096 __func__, *zr);
2097
2098 /* mono/stereo detection */
2099 if ((*zl == TASHA_ZDET_FLOATING_IMPEDANCE) &&
2100 (*zr == TASHA_ZDET_FLOATING_IMPEDANCE)) {
2101 dev_dbg(codec->dev,
2102 "%s: plug type is invalid or extension cable\n",
2103 __func__);
2104 goto zdet_complete;
2105 }
2106 if ((*zl == TASHA_ZDET_FLOATING_IMPEDANCE) ||
2107 (*zr == TASHA_ZDET_FLOATING_IMPEDANCE) ||
2108 ((*zl < WCD_MONO_HS_MIN_THR) && (*zr > WCD_MONO_HS_MIN_THR)) ||
2109 ((*zl > WCD_MONO_HS_MIN_THR) && (*zr < WCD_MONO_HS_MIN_THR))) {
2110 dev_dbg(codec->dev,
2111 "%s: Mono plug type with one ch floating or shorted to GND\n",
2112 __func__);
2113 mbhc->hph_type = WCD_MBHC_HPH_MONO;
2114 goto zdet_complete;
2115 }
2116 snd_soc_update_bits(codec, WCD9335_HPH_R_ATEST, 0x02, 0x02);
2117 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x40, 0x01);
2118 if (*zl < (TASHA_ZDET_VAL_32/1000))
2119 tasha_mbhc_zdet_ramp(codec, &zdet_param[0], &z1Ls, NULL, d1);
2120 else
2121 tasha_mbhc_zdet_ramp(codec, &zdet_param[1], &z1Ls, NULL, d1);
2122 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x40, 0x00);
2123 snd_soc_update_bits(codec, WCD9335_HPH_R_ATEST, 0x02, 0x00);
2124 z1Ls /= 1000;
2125 tasha_wcd_mbhc_qfuse_cal(codec, &z1Ls, 0);
2126 /* parallel of left Z and 9 ohm pull down resistor */
2127 zMono = ((*zl) * 9) / ((*zl) + 9);
2128 z_diff1 = (z1Ls > zMono) ? (z1Ls - zMono) : (zMono - z1Ls);
2129 z_diff2 = ((*zl) > z1Ls) ? ((*zl) - z1Ls) : (z1Ls - (*zl));
2130 if ((z_diff1 * (*zl + z1Ls)) > (z_diff2 * (z1Ls + zMono))) {
2131 dev_dbg(codec->dev, "%s: stereo plug type detected\n",
2132 __func__);
2133 mbhc->hph_type = WCD_MBHC_HPH_STEREO;
2134 } else {
2135 dev_dbg(codec->dev, "%s: MONO plug type detected\n",
2136 __func__);
2137 mbhc->hph_type = WCD_MBHC_HPH_MONO;
2138 }
2139
2140zdet_complete:
2141 snd_soc_write(codec, WCD9335_ANA_MBHC_BTN5, reg0);
2142 snd_soc_write(codec, WCD9335_ANA_MBHC_BTN6, reg1);
2143 snd_soc_write(codec, WCD9335_ANA_MBHC_BTN7, reg2);
2144 /* Turn on 100k pull down on HPHL */
2145 regmap_update_bits(wcd9xxx->regmap,
2146 WCD9335_ANA_MBHC_MECH, 0x01, 0x01);
2147
2148 /* For NO-jack, re-enable L_DET_EN after Z-det measurements */
2149 if (mbhc->hphl_swh)
2150 regmap_update_bits(wcd9xxx->regmap,
2151 WCD9335_ANA_MBHC_MECH, 0x80, 0x80);
2152
2153 snd_soc_write(codec, WCD9335_MBHC_ZDET_ANA_CTL, reg4);
2154 snd_soc_write(codec, WCD9335_MBHC_CTL_1, reg3);
2155 if (is_fsm_disable)
2156 regmap_update_bits(wcd9xxx->regmap,
2157 WCD9335_ANA_MBHC_ELECT, 0x80, 0x80);
2158 if (tasha->zdet_gpio_cb && is_change)
2159 tasha->zdet_gpio_cb(codec, false);
2160}
2161
2162static void tasha_mbhc_gnd_det_ctrl(struct snd_soc_codec *codec, bool enable)
2163{
2164 if (enable) {
2165 snd_soc_update_bits(codec, WCD9335_ANA_MBHC_MECH,
2166 0x02, 0x02);
2167 snd_soc_update_bits(codec, WCD9335_ANA_MBHC_MECH,
2168 0x40, 0x40);
2169 } else {
2170 snd_soc_update_bits(codec, WCD9335_ANA_MBHC_MECH,
2171 0x40, 0x00);
2172 snd_soc_update_bits(codec, WCD9335_ANA_MBHC_MECH,
2173 0x02, 0x00);
2174 }
2175}
2176
2177static void tasha_mbhc_hph_pull_down_ctrl(struct snd_soc_codec *codec,
2178 bool enable)
2179{
2180 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
2181
2182 if (enable) {
2183 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2,
2184 0x40, 0x40);
2185 if (TASHA_IS_2_0(tasha->wcd9xxx))
2186 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2,
2187 0x10, 0x10);
2188 } else {
2189 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2,
2190 0x40, 0x00);
2191 if (TASHA_IS_2_0(tasha->wcd9xxx))
2192 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2,
2193 0x10, 0x00);
2194 }
2195}
2196
2197static void tasha_mbhc_moisture_config(struct wcd_mbhc *mbhc)
2198{
2199 struct snd_soc_codec *codec = mbhc->codec;
2200
Yeleswarapu Nagaradhesh7bb4cae2016-12-22 10:50:05 +05302201 if (mbhc->moist_vref == V_OFF)
Banajit Goswamide8271c2017-01-18 00:28:59 -08002202 return;
2203
2204 /* Donot enable moisture detection if jack type is NC */
2205 if (!mbhc->hphl_swh) {
2206 dev_dbg(codec->dev, "%s: disable moisture detection for NC\n",
2207 __func__);
2208 return;
2209 }
2210
2211 snd_soc_update_bits(codec, WCD9335_MBHC_CTL_2,
Yeleswarapu Nagaradhesh7bb4cae2016-12-22 10:50:05 +05302212 0x0C, mbhc->moist_vref << 2);
2213 tasha_mbhc_hph_l_pull_up_control(codec, mbhc->moist_iref);
Banajit Goswamide8271c2017-01-18 00:28:59 -08002214}
2215
2216static const struct wcd_mbhc_cb mbhc_cb = {
2217 .request_irq = tasha_mbhc_request_irq,
2218 .irq_control = tasha_mbhc_irq_control,
2219 .free_irq = tasha_mbhc_free_irq,
2220 .clk_setup = tasha_mbhc_clk_setup,
2221 .map_btn_code_to_num = tasha_mbhc_btn_to_num,
2222 .enable_mb_source = tasha_enable_ext_mb_source,
2223 .mbhc_bias = tasha_mbhc_mbhc_bias_control,
2224 .set_btn_thr = tasha_mbhc_program_btn_thr,
2225 .lock_sleep = tasha_mbhc_lock_sleep,
2226 .register_notifier = tasha_mbhc_register_notifier,
2227 .micbias_enable_status = tasha_mbhc_micb_en_status,
2228 .hph_pa_on_status = tasha_mbhc_hph_pa_on_status,
2229 .hph_pull_up_control = tasha_mbhc_hph_l_pull_up_control,
2230 .mbhc_micbias_control = tasha_mbhc_request_micbias,
2231 .mbhc_micb_ramp_control = tasha_mbhc_micb_ramp_control,
2232 .get_hwdep_fw_cal = tasha_get_hwdep_fw_cal,
2233 .mbhc_micb_ctrl_thr_mic = tasha_mbhc_micb_ctrl_threshold_mic,
2234 .compute_impedance = tasha_wcd_mbhc_calc_impedance,
2235 .mbhc_gnd_det_ctrl = tasha_mbhc_gnd_det_ctrl,
2236 .hph_pull_down_ctrl = tasha_mbhc_hph_pull_down_ctrl,
2237 .mbhc_moisture_config = tasha_mbhc_moisture_config,
2238};
2239
2240static int tasha_get_anc_slot(struct snd_kcontrol *kcontrol,
2241 struct snd_ctl_elem_value *ucontrol)
2242{
2243 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
2244 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
2245
2246 ucontrol->value.integer.value[0] = tasha->anc_slot;
2247 return 0;
2248}
2249
2250static int tasha_put_anc_slot(struct snd_kcontrol *kcontrol,
2251 struct snd_ctl_elem_value *ucontrol)
2252{
2253 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
2254 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
2255
2256 tasha->anc_slot = ucontrol->value.integer.value[0];
2257 return 0;
2258}
2259
2260static int tasha_get_anc_func(struct snd_kcontrol *kcontrol,
2261 struct snd_ctl_elem_value *ucontrol)
2262{
2263 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
2264 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
2265
2266 ucontrol->value.integer.value[0] = (tasha->anc_func == true ? 1 : 0);
2267 return 0;
2268}
2269
2270static int tasha_put_anc_func(struct snd_kcontrol *kcontrol,
2271 struct snd_ctl_elem_value *ucontrol)
2272{
2273 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
2274 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
2275 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
2276
2277 mutex_lock(&tasha->codec_mutex);
2278 tasha->anc_func = (!ucontrol->value.integer.value[0] ? false : true);
2279
2280 dev_dbg(codec->dev, "%s: anc_func %x", __func__, tasha->anc_func);
2281
2282 if (tasha->anc_func == true) {
2283 snd_soc_dapm_enable_pin(dapm, "ANC LINEOUT2 PA");
2284 snd_soc_dapm_enable_pin(dapm, "ANC LINEOUT2");
2285 snd_soc_dapm_enable_pin(dapm, "ANC LINEOUT1 PA");
2286 snd_soc_dapm_enable_pin(dapm, "ANC LINEOUT1");
2287 snd_soc_dapm_enable_pin(dapm, "ANC HPHR PA");
2288 snd_soc_dapm_enable_pin(dapm, "ANC HPHR");
2289 snd_soc_dapm_enable_pin(dapm, "ANC HPHL PA");
2290 snd_soc_dapm_enable_pin(dapm, "ANC HPHL");
2291 snd_soc_dapm_enable_pin(dapm, "ANC EAR PA");
2292 snd_soc_dapm_enable_pin(dapm, "ANC EAR");
2293 snd_soc_dapm_enable_pin(dapm, "ANC SPK1 PA");
2294 snd_soc_dapm_disable_pin(dapm, "LINEOUT2");
2295 snd_soc_dapm_disable_pin(dapm, "LINEOUT2 PA");
2296 snd_soc_dapm_disable_pin(dapm, "LINEOUT1");
2297 snd_soc_dapm_disable_pin(dapm, "LINEOUT1 PA");
2298 snd_soc_dapm_disable_pin(dapm, "HPHR");
2299 snd_soc_dapm_disable_pin(dapm, "HPHL");
2300 snd_soc_dapm_disable_pin(dapm, "HPHR PA");
2301 snd_soc_dapm_disable_pin(dapm, "HPHL PA");
2302 snd_soc_dapm_disable_pin(dapm, "EAR PA");
2303 snd_soc_dapm_disable_pin(dapm, "EAR");
2304 } else {
2305 snd_soc_dapm_disable_pin(dapm, "ANC LINEOUT2 PA");
2306 snd_soc_dapm_disable_pin(dapm, "ANC LINEOUT2");
2307 snd_soc_dapm_disable_pin(dapm, "ANC LINEOUT1 PA");
2308 snd_soc_dapm_disable_pin(dapm, "ANC LINEOUT1");
2309 snd_soc_dapm_disable_pin(dapm, "ANC HPHR");
2310 snd_soc_dapm_disable_pin(dapm, "ANC HPHL");
2311 snd_soc_dapm_disable_pin(dapm, "ANC HPHR PA");
2312 snd_soc_dapm_disable_pin(dapm, "ANC HPHL PA");
2313 snd_soc_dapm_disable_pin(dapm, "ANC EAR PA");
2314 snd_soc_dapm_disable_pin(dapm, "ANC EAR");
2315 snd_soc_dapm_disable_pin(dapm, "ANC SPK1 PA");
2316 snd_soc_dapm_enable_pin(dapm, "LINEOUT2");
2317 snd_soc_dapm_enable_pin(dapm, "LINEOUT2 PA");
2318 snd_soc_dapm_enable_pin(dapm, "LINEOUT1");
2319 snd_soc_dapm_enable_pin(dapm, "LINEOUT1 PA");
2320 snd_soc_dapm_enable_pin(dapm, "HPHR");
2321 snd_soc_dapm_enable_pin(dapm, "HPHL");
2322 snd_soc_dapm_enable_pin(dapm, "HPHR PA");
2323 snd_soc_dapm_enable_pin(dapm, "HPHL PA");
2324 snd_soc_dapm_enable_pin(dapm, "EAR PA");
2325 snd_soc_dapm_enable_pin(dapm, "EAR");
2326 }
2327 mutex_unlock(&tasha->codec_mutex);
2328 snd_soc_dapm_sync(dapm);
2329 return 0;
2330}
2331
2332static int tasha_get_clkmode(struct snd_kcontrol *kcontrol,
2333 struct snd_ctl_elem_value *ucontrol)
2334{
2335 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
2336 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
2337
2338 ucontrol->value.enumerated.item[0] = tasha->clk_mode;
2339 dev_dbg(codec->dev, "%s: clk_mode: %d\n", __func__, tasha->clk_mode);
2340
2341 return 0;
2342}
2343
2344static int tasha_put_clkmode(struct snd_kcontrol *kcontrol,
2345 struct snd_ctl_elem_value *ucontrol)
2346{
2347 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
2348 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
2349
2350 tasha->clk_mode = ucontrol->value.enumerated.item[0];
2351 dev_dbg(codec->dev, "%s: clk_mode: %d\n", __func__, tasha->clk_mode);
2352
2353 return 0;
2354}
2355
2356static int tasha_get_iir_enable_audio_mixer(
2357 struct snd_kcontrol *kcontrol,
2358 struct snd_ctl_elem_value *ucontrol)
2359{
2360 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
2361 int iir_idx = ((struct soc_multi_mixer_control *)
2362 kcontrol->private_value)->reg;
2363 int band_idx = ((struct soc_multi_mixer_control *)
2364 kcontrol->private_value)->shift;
2365 /* IIR filter band registers are at integer multiples of 16 */
2366 u16 iir_reg = WCD9335_CDC_SIDETONE_IIR0_IIR_CTL + 16 * iir_idx;
2367
2368 ucontrol->value.integer.value[0] = (snd_soc_read(codec, iir_reg) &
2369 (1 << band_idx)) != 0;
2370
2371 dev_dbg(codec->dev, "%s: IIR #%d band #%d enable %d\n", __func__,
2372 iir_idx, band_idx,
2373 (uint32_t)ucontrol->value.integer.value[0]);
2374 return 0;
2375}
2376
2377static int tasha_hph_impedance_get(struct snd_kcontrol *kcontrol,
2378 struct snd_ctl_elem_value *ucontrol)
2379{
2380 uint32_t zl, zr;
2381 bool hphr;
2382 struct soc_multi_mixer_control *mc;
2383 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
2384 struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec);
2385
2386 mc = (struct soc_multi_mixer_control *)(kcontrol->private_value);
2387 hphr = mc->shift;
2388 wcd_mbhc_get_impedance(&priv->mbhc, &zl, &zr);
2389 dev_dbg(codec->dev, "%s: zl=%u(ohms), zr=%u(ohms)\n", __func__, zl, zr);
2390 ucontrol->value.integer.value[0] = hphr ? zr : zl;
2391
2392 return 0;
2393}
2394
2395static const struct snd_kcontrol_new impedance_detect_controls[] = {
2396 SOC_SINGLE_EXT("HPHL Impedance", 0, 0, UINT_MAX, 0,
2397 tasha_hph_impedance_get, NULL),
2398 SOC_SINGLE_EXT("HPHR Impedance", 0, 1, UINT_MAX, 0,
2399 tasha_hph_impedance_get, NULL),
2400};
2401
2402static int tasha_get_hph_type(struct snd_kcontrol *kcontrol,
2403 struct snd_ctl_elem_value *ucontrol)
2404{
2405 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
2406 struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec);
2407 struct wcd_mbhc *mbhc;
2408
2409 if (!priv) {
2410 dev_dbg(codec->dev, "%s: wcd9335 private data is NULL\n",
2411 __func__);
2412 return 0;
2413 }
2414
2415 mbhc = &priv->mbhc;
2416 if (!mbhc) {
2417 dev_dbg(codec->dev, "%s: mbhc not initialized\n", __func__);
2418 return 0;
2419 }
2420
2421 ucontrol->value.integer.value[0] = (u32) mbhc->hph_type;
2422 dev_dbg(codec->dev, "%s: hph_type = %u\n", __func__, mbhc->hph_type);
2423
2424 return 0;
2425}
2426
2427static const struct snd_kcontrol_new hph_type_detect_controls[] = {
2428 SOC_SINGLE_EXT("HPH Type", 0, 0, UINT_MAX, 0,
2429 tasha_get_hph_type, NULL),
2430};
2431
2432static int tasha_vi_feed_mixer_get(struct snd_kcontrol *kcontrol,
2433 struct snd_ctl_elem_value *ucontrol)
2434{
2435 struct snd_soc_dapm_widget_list *wlist =
2436 dapm_kcontrol_get_wlist(kcontrol);
2437 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2438 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
2439 struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec);
2440
2441 ucontrol->value.integer.value[0] = tasha_p->vi_feed_value;
2442
2443 return 0;
2444}
2445
2446static int tasha_vi_feed_mixer_put(struct snd_kcontrol *kcontrol,
2447 struct snd_ctl_elem_value *ucontrol)
2448{
2449 struct snd_soc_dapm_widget_list *wlist =
2450 dapm_kcontrol_get_wlist(kcontrol);
2451 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2452 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
2453 struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec);
2454 struct wcd9xxx *core = tasha_p->wcd9xxx;
2455 struct soc_multi_mixer_control *mixer =
2456 ((struct soc_multi_mixer_control *)kcontrol->private_value);
2457 u32 dai_id = widget->shift;
2458 u32 port_id = mixer->shift;
2459 u32 enable = ucontrol->value.integer.value[0];
2460
2461 dev_dbg(codec->dev, "%s: enable: %d, port_id:%d, dai_id: %d\n",
2462 __func__, enable, port_id, dai_id);
2463
2464 tasha_p->vi_feed_value = ucontrol->value.integer.value[0];
2465
2466 mutex_lock(&tasha_p->codec_mutex);
2467 if (enable) {
2468 if (port_id == TASHA_TX14 && !test_bit(VI_SENSE_1,
2469 &tasha_p->status_mask)) {
2470 list_add_tail(&core->tx_chs[TASHA_TX14].list,
2471 &tasha_p->dai[dai_id].wcd9xxx_ch_list);
2472 set_bit(VI_SENSE_1, &tasha_p->status_mask);
2473 }
2474 if (port_id == TASHA_TX15 && !test_bit(VI_SENSE_2,
2475 &tasha_p->status_mask)) {
2476 list_add_tail(&core->tx_chs[TASHA_TX15].list,
2477 &tasha_p->dai[dai_id].wcd9xxx_ch_list);
2478 set_bit(VI_SENSE_2, &tasha_p->status_mask);
2479 }
2480 } else {
2481 if (port_id == TASHA_TX14 && test_bit(VI_SENSE_1,
2482 &tasha_p->status_mask)) {
2483 list_del_init(&core->tx_chs[TASHA_TX14].list);
2484 clear_bit(VI_SENSE_1, &tasha_p->status_mask);
2485 }
2486 if (port_id == TASHA_TX15 && test_bit(VI_SENSE_2,
2487 &tasha_p->status_mask)) {
2488 list_del_init(&core->tx_chs[TASHA_TX15].list);
2489 clear_bit(VI_SENSE_2, &tasha_p->status_mask);
2490 }
2491 }
2492 mutex_unlock(&tasha_p->codec_mutex);
2493 snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, NULL);
2494
2495 return 0;
2496}
2497
2498/* virtual port entries */
2499static int slim_tx_mixer_get(struct snd_kcontrol *kcontrol,
2500 struct snd_ctl_elem_value *ucontrol)
2501{
2502 struct snd_soc_dapm_widget_list *wlist =
2503 dapm_kcontrol_get_wlist(kcontrol);
2504 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2505 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
2506 struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec);
2507
2508 ucontrol->value.integer.value[0] = tasha_p->tx_port_value;
2509 return 0;
2510}
2511
2512static int slim_tx_mixer_put(struct snd_kcontrol *kcontrol,
2513 struct snd_ctl_elem_value *ucontrol)
2514{
2515 struct snd_soc_dapm_widget_list *wlist =
2516 dapm_kcontrol_get_wlist(kcontrol);
2517 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2518 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
2519 struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec);
2520 struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent);
2521 struct snd_soc_dapm_update *update = NULL;
2522 struct soc_multi_mixer_control *mixer =
2523 ((struct soc_multi_mixer_control *)kcontrol->private_value);
2524 u32 dai_id = widget->shift;
2525 u32 port_id = mixer->shift;
2526 u32 enable = ucontrol->value.integer.value[0];
2527 u32 vtable;
2528
2529
2530 dev_dbg(codec->dev, "%s: wname %s cname %s value %u shift %d item %ld\n",
2531 __func__,
2532 widget->name, ucontrol->id.name, tasha_p->tx_port_value,
2533 widget->shift, ucontrol->value.integer.value[0]);
2534
2535 mutex_lock(&tasha_p->codec_mutex);
2536
2537 if (tasha_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
2538 if (dai_id != AIF1_CAP) {
2539 dev_err(codec->dev, "%s: invalid AIF for I2C mode\n",
2540 __func__);
2541 mutex_unlock(&tasha_p->codec_mutex);
2542 return -EINVAL;
2543 }
2544 vtable = vport_slim_check_table[dai_id];
2545 } else {
2546 if (dai_id >= ARRAY_SIZE(vport_i2s_check_table)) {
2547 dev_err(codec->dev, "%s: dai_id: %d, out of bounds\n",
2548 __func__, dai_id);
2549 return -EINVAL;
2550 }
2551 vtable = vport_i2s_check_table[dai_id];
2552 }
2553 switch (dai_id) {
2554 case AIF1_CAP:
2555 case AIF2_CAP:
2556 case AIF3_CAP:
2557 /* only add to the list if value not set */
2558 if (enable && !(tasha_p->tx_port_value & 1 << port_id)) {
2559
2560 if (wcd9xxx_tx_vport_validation(vtable, port_id,
2561 tasha_p->dai, NUM_CODEC_DAIS)) {
2562 dev_dbg(codec->dev, "%s: TX%u is used by other virtual port\n",
2563 __func__, port_id);
2564 mutex_unlock(&tasha_p->codec_mutex);
2565 return 0;
2566 }
2567 tasha_p->tx_port_value |= 1 << port_id;
2568 list_add_tail(&core->tx_chs[port_id].list,
2569 &tasha_p->dai[dai_id].wcd9xxx_ch_list
2570 );
2571 } else if (!enable && (tasha_p->tx_port_value &
2572 1 << port_id)) {
2573 tasha_p->tx_port_value &= ~(1 << port_id);
2574 list_del_init(&core->tx_chs[port_id].list);
2575 } else {
2576 if (enable)
2577 dev_dbg(codec->dev, "%s: TX%u port is used by\n"
2578 "this virtual port\n",
2579 __func__, port_id);
2580 else
2581 dev_dbg(codec->dev, "%s: TX%u port is not used by\n"
2582 "this virtual port\n",
2583 __func__, port_id);
2584 /* avoid update power function */
2585 mutex_unlock(&tasha_p->codec_mutex);
2586 return 0;
2587 }
2588 break;
2589 case AIF4_MAD_TX:
2590 case AIF5_CPE_TX:
2591 break;
2592 default:
2593 pr_err("Unknown AIF %d\n", dai_id);
2594 mutex_unlock(&tasha_p->codec_mutex);
2595 return -EINVAL;
2596 }
2597 pr_debug("%s: name %s sname %s updated value %u shift %d\n", __func__,
2598 widget->name, widget->sname, tasha_p->tx_port_value,
2599 widget->shift);
2600
2601 mutex_unlock(&tasha_p->codec_mutex);
2602 snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, update);
2603
2604 return 0;
2605}
2606
2607static int slim_rx_mux_get(struct snd_kcontrol *kcontrol,
2608 struct snd_ctl_elem_value *ucontrol)
2609{
2610 struct snd_soc_dapm_widget_list *wlist =
2611 dapm_kcontrol_get_wlist(kcontrol);
2612 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2613 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
2614 struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec);
2615
2616 ucontrol->value.enumerated.item[0] =
2617 tasha_p->rx_port_value[widget->shift];
2618 return 0;
2619}
2620
2621static const char *const slim_rx_mux_text[] = {
2622 "ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB", "AIF4_PB", "AIF_MIX1_PB"
2623};
2624
2625static int slim_rx_mux_put(struct snd_kcontrol *kcontrol,
2626 struct snd_ctl_elem_value *ucontrol)
2627{
2628 struct snd_soc_dapm_widget_list *wlist =
2629 dapm_kcontrol_get_wlist(kcontrol);
2630 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2631 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
2632 struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec);
2633 struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent);
2634 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
2635 struct snd_soc_dapm_update *update = NULL;
2636 unsigned int rx_port_value;
2637 u32 port_id = widget->shift;
2638
2639 tasha_p->rx_port_value[port_id] = ucontrol->value.enumerated.item[0];
2640 rx_port_value = tasha_p->rx_port_value[port_id];
2641
2642 pr_debug("%s: wname %s cname %s value %u shift %d item %ld\n", __func__,
2643 widget->name, ucontrol->id.name, rx_port_value,
2644 widget->shift, ucontrol->value.integer.value[0]);
2645
2646 mutex_lock(&tasha_p->codec_mutex);
2647
2648 if (tasha_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
2649 if (rx_port_value > 2) {
2650 dev_err(codec->dev, "%s: invalid AIF for I2C mode\n",
2651 __func__);
2652 goto err;
2653 }
2654 }
2655 /* value need to match the Virtual port and AIF number */
2656 switch (rx_port_value) {
2657 case 0:
2658 list_del_init(&core->rx_chs[port_id].list);
2659 break;
2660 case 1:
2661 if (wcd9xxx_rx_vport_validation(port_id +
2662 TASHA_RX_PORT_START_NUMBER,
2663 &tasha_p->dai[AIF1_PB].wcd9xxx_ch_list)) {
2664 dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n",
2665 __func__, port_id);
2666 goto rtn;
2667 }
2668 list_add_tail(&core->rx_chs[port_id].list,
2669 &tasha_p->dai[AIF1_PB].wcd9xxx_ch_list);
2670 break;
2671 case 2:
2672 if (wcd9xxx_rx_vport_validation(port_id +
2673 TASHA_RX_PORT_START_NUMBER,
2674 &tasha_p->dai[AIF2_PB].wcd9xxx_ch_list)) {
2675 dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n",
2676 __func__, port_id);
2677 goto rtn;
2678 }
2679 list_add_tail(&core->rx_chs[port_id].list,
2680 &tasha_p->dai[AIF2_PB].wcd9xxx_ch_list);
2681 break;
2682 case 3:
2683 if (wcd9xxx_rx_vport_validation(port_id +
2684 TASHA_RX_PORT_START_NUMBER,
2685 &tasha_p->dai[AIF3_PB].wcd9xxx_ch_list)) {
2686 dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n",
2687 __func__, port_id);
2688 goto rtn;
2689 }
2690 list_add_tail(&core->rx_chs[port_id].list,
2691 &tasha_p->dai[AIF3_PB].wcd9xxx_ch_list);
2692 break;
2693 case 4:
2694 if (wcd9xxx_rx_vport_validation(port_id +
2695 TASHA_RX_PORT_START_NUMBER,
2696 &tasha_p->dai[AIF4_PB].wcd9xxx_ch_list)) {
2697 dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n",
2698 __func__, port_id);
2699 goto rtn;
2700 }
2701 list_add_tail(&core->rx_chs[port_id].list,
2702 &tasha_p->dai[AIF4_PB].wcd9xxx_ch_list);
2703 break;
2704 case 5:
2705 if (wcd9xxx_rx_vport_validation(port_id +
2706 TASHA_RX_PORT_START_NUMBER,
2707 &tasha_p->dai[AIF_MIX1_PB].wcd9xxx_ch_list)) {
2708 dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n",
2709 __func__, port_id);
2710 goto rtn;
2711 }
2712 list_add_tail(&core->rx_chs[port_id].list,
2713 &tasha_p->dai[AIF_MIX1_PB].wcd9xxx_ch_list);
2714 break;
2715 default:
2716 pr_err("Unknown AIF %d\n", rx_port_value);
2717 goto err;
2718 }
2719rtn:
2720 mutex_unlock(&tasha_p->codec_mutex);
2721 snd_soc_dapm_mux_update_power(widget->dapm, kcontrol,
2722 rx_port_value, e, update);
2723
2724 return 0;
2725err:
2726 mutex_unlock(&tasha_p->codec_mutex);
2727 return -EINVAL;
2728}
2729
2730static const struct soc_enum slim_rx_mux_enum =
2731 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(slim_rx_mux_text), slim_rx_mux_text);
2732
2733static const struct snd_kcontrol_new slim_rx_mux[TASHA_RX_MAX] = {
2734 SOC_DAPM_ENUM_EXT("SLIM RX0 Mux", slim_rx_mux_enum,
2735 slim_rx_mux_get, slim_rx_mux_put),
2736 SOC_DAPM_ENUM_EXT("SLIM RX1 Mux", slim_rx_mux_enum,
2737 slim_rx_mux_get, slim_rx_mux_put),
2738 SOC_DAPM_ENUM_EXT("SLIM RX2 Mux", slim_rx_mux_enum,
2739 slim_rx_mux_get, slim_rx_mux_put),
2740 SOC_DAPM_ENUM_EXT("SLIM RX3 Mux", slim_rx_mux_enum,
2741 slim_rx_mux_get, slim_rx_mux_put),
2742 SOC_DAPM_ENUM_EXT("SLIM RX4 Mux", slim_rx_mux_enum,
2743 slim_rx_mux_get, slim_rx_mux_put),
2744 SOC_DAPM_ENUM_EXT("SLIM RX5 Mux", slim_rx_mux_enum,
2745 slim_rx_mux_get, slim_rx_mux_put),
2746 SOC_DAPM_ENUM_EXT("SLIM RX6 Mux", slim_rx_mux_enum,
2747 slim_rx_mux_get, slim_rx_mux_put),
2748 SOC_DAPM_ENUM_EXT("SLIM RX7 Mux", slim_rx_mux_enum,
2749 slim_rx_mux_get, slim_rx_mux_put),
2750};
2751
2752static const struct snd_kcontrol_new aif4_vi_mixer[] = {
2753 SOC_SINGLE_EXT("SPKR_VI_1", SND_SOC_NOPM, TASHA_TX14, 1, 0,
2754 tasha_vi_feed_mixer_get, tasha_vi_feed_mixer_put),
2755 SOC_SINGLE_EXT("SPKR_VI_2", SND_SOC_NOPM, TASHA_TX15, 1, 0,
2756 tasha_vi_feed_mixer_get, tasha_vi_feed_mixer_put),
2757};
2758
2759static const struct snd_kcontrol_new aif1_cap_mixer[] = {
2760 SOC_SINGLE_EXT("SLIM TX0", SND_SOC_NOPM, TASHA_TX0, 1, 0,
2761 slim_tx_mixer_get, slim_tx_mixer_put),
2762 SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, TASHA_TX1, 1, 0,
2763 slim_tx_mixer_get, slim_tx_mixer_put),
2764 SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, TASHA_TX2, 1, 0,
2765 slim_tx_mixer_get, slim_tx_mixer_put),
2766 SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, TASHA_TX3, 1, 0,
2767 slim_tx_mixer_get, slim_tx_mixer_put),
2768 SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, TASHA_TX4, 1, 0,
2769 slim_tx_mixer_get, slim_tx_mixer_put),
2770 SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, TASHA_TX5, 1, 0,
2771 slim_tx_mixer_get, slim_tx_mixer_put),
2772 SOC_SINGLE_EXT("SLIM TX6", SND_SOC_NOPM, TASHA_TX6, 1, 0,
2773 slim_tx_mixer_get, slim_tx_mixer_put),
2774 SOC_SINGLE_EXT("SLIM TX7", SND_SOC_NOPM, TASHA_TX7, 1, 0,
2775 slim_tx_mixer_get, slim_tx_mixer_put),
2776 SOC_SINGLE_EXT("SLIM TX8", SND_SOC_NOPM, TASHA_TX8, 1, 0,
2777 slim_tx_mixer_get, slim_tx_mixer_put),
2778 SOC_SINGLE_EXT("SLIM TX9", SND_SOC_NOPM, TASHA_TX9, 1, 0,
2779 slim_tx_mixer_get, slim_tx_mixer_put),
2780 SOC_SINGLE_EXT("SLIM TX10", SND_SOC_NOPM, TASHA_TX10, 1, 0,
2781 slim_tx_mixer_get, slim_tx_mixer_put),
2782 SOC_SINGLE_EXT("SLIM TX11", SND_SOC_NOPM, TASHA_TX11, 1, 0,
2783 slim_tx_mixer_get, slim_tx_mixer_put),
2784 SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, TASHA_TX13, 1, 0,
2785 slim_tx_mixer_get, slim_tx_mixer_put),
2786};
2787
2788static const struct snd_kcontrol_new aif2_cap_mixer[] = {
2789 SOC_SINGLE_EXT("SLIM TX0", SND_SOC_NOPM, TASHA_TX0, 1, 0,
2790 slim_tx_mixer_get, slim_tx_mixer_put),
2791 SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, TASHA_TX1, 1, 0,
2792 slim_tx_mixer_get, slim_tx_mixer_put),
2793 SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, TASHA_TX2, 1, 0,
2794 slim_tx_mixer_get, slim_tx_mixer_put),
2795 SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, TASHA_TX3, 1, 0,
2796 slim_tx_mixer_get, slim_tx_mixer_put),
2797 SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, TASHA_TX4, 1, 0,
2798 slim_tx_mixer_get, slim_tx_mixer_put),
2799 SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, TASHA_TX5, 1, 0,
2800 slim_tx_mixer_get, slim_tx_mixer_put),
2801 SOC_SINGLE_EXT("SLIM TX6", SND_SOC_NOPM, TASHA_TX6, 1, 0,
2802 slim_tx_mixer_get, slim_tx_mixer_put),
2803 SOC_SINGLE_EXT("SLIM TX7", SND_SOC_NOPM, TASHA_TX7, 1, 0,
2804 slim_tx_mixer_get, slim_tx_mixer_put),
2805 SOC_SINGLE_EXT("SLIM TX8", SND_SOC_NOPM, TASHA_TX8, 1, 0,
2806 slim_tx_mixer_get, slim_tx_mixer_put),
2807 SOC_SINGLE_EXT("SLIM TX9", SND_SOC_NOPM, TASHA_TX9, 1, 0,
2808 slim_tx_mixer_get, slim_tx_mixer_put),
2809 SOC_SINGLE_EXT("SLIM TX10", SND_SOC_NOPM, TASHA_TX10, 1, 0,
2810 slim_tx_mixer_get, slim_tx_mixer_put),
2811 SOC_SINGLE_EXT("SLIM TX11", SND_SOC_NOPM, TASHA_TX11, 1, 0,
2812 slim_tx_mixer_get, slim_tx_mixer_put),
2813 SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, TASHA_TX13, 1, 0,
2814 slim_tx_mixer_get, slim_tx_mixer_put),
2815};
2816
2817static const struct snd_kcontrol_new aif3_cap_mixer[] = {
2818 SOC_SINGLE_EXT("SLIM TX0", SND_SOC_NOPM, TASHA_TX0, 1, 0,
2819 slim_tx_mixer_get, slim_tx_mixer_put),
2820 SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, TASHA_TX1, 1, 0,
2821 slim_tx_mixer_get, slim_tx_mixer_put),
2822 SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, TASHA_TX2, 1, 0,
2823 slim_tx_mixer_get, slim_tx_mixer_put),
2824 SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, TASHA_TX3, 1, 0,
2825 slim_tx_mixer_get, slim_tx_mixer_put),
2826 SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, TASHA_TX4, 1, 0,
2827 slim_tx_mixer_get, slim_tx_mixer_put),
2828 SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, TASHA_TX5, 1, 0,
2829 slim_tx_mixer_get, slim_tx_mixer_put),
2830 SOC_SINGLE_EXT("SLIM TX6", SND_SOC_NOPM, TASHA_TX6, 1, 0,
2831 slim_tx_mixer_get, slim_tx_mixer_put),
2832 SOC_SINGLE_EXT("SLIM TX7", SND_SOC_NOPM, TASHA_TX7, 1, 0,
2833 slim_tx_mixer_get, slim_tx_mixer_put),
2834 SOC_SINGLE_EXT("SLIM TX8", SND_SOC_NOPM, TASHA_TX8, 1, 0,
2835 slim_tx_mixer_get, slim_tx_mixer_put),
2836 SOC_SINGLE_EXT("SLIM TX9", SND_SOC_NOPM, TASHA_TX9, 1, 0,
2837 slim_tx_mixer_get, slim_tx_mixer_put),
2838 SOC_SINGLE_EXT("SLIM TX10", SND_SOC_NOPM, TASHA_TX10, 1, 0,
2839 slim_tx_mixer_get, slim_tx_mixer_put),
2840 SOC_SINGLE_EXT("SLIM TX11", SND_SOC_NOPM, TASHA_TX11, 1, 0,
2841 slim_tx_mixer_get, slim_tx_mixer_put),
2842 SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, TASHA_TX13, 1, 0,
2843 slim_tx_mixer_get, slim_tx_mixer_put),
2844};
2845
2846static const struct snd_kcontrol_new aif4_mad_mixer[] = {
2847 SOC_SINGLE_EXT("SLIM TX12", SND_SOC_NOPM, TASHA_TX12, 1, 0,
2848 slim_tx_mixer_get, slim_tx_mixer_put),
2849 SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, TASHA_TX13, 1, 0,
2850 slim_tx_mixer_get, slim_tx_mixer_put),
2851 SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, 0, 1, 0,
2852 slim_tx_mixer_get, slim_tx_mixer_put),
2853
2854};
2855
2856static const struct snd_kcontrol_new rx_int1_spline_mix_switch[] = {
2857 SOC_DAPM_SINGLE("HPHL Switch", SND_SOC_NOPM, 0, 1, 0)
2858};
2859
2860static const struct snd_kcontrol_new rx_int2_spline_mix_switch[] = {
2861 SOC_DAPM_SINGLE("HPHR Switch", SND_SOC_NOPM, 0, 1, 0)
2862};
2863
2864static const struct snd_kcontrol_new rx_int3_spline_mix_switch[] = {
2865 SOC_DAPM_SINGLE("LO1 Switch", SND_SOC_NOPM, 0, 1, 0)
2866};
2867
2868static const struct snd_kcontrol_new rx_int4_spline_mix_switch[] = {
2869 SOC_DAPM_SINGLE("LO2 Switch", SND_SOC_NOPM, 0, 1, 0)
2870};
2871
2872static const struct snd_kcontrol_new rx_int5_spline_mix_switch[] = {
2873 SOC_DAPM_SINGLE("LO3 Switch", SND_SOC_NOPM, 0, 1, 0)
2874};
2875
2876static const struct snd_kcontrol_new rx_int6_spline_mix_switch[] = {
2877 SOC_DAPM_SINGLE("LO4 Switch", SND_SOC_NOPM, 0, 1, 0)
2878};
2879
2880static const struct snd_kcontrol_new rx_int7_spline_mix_switch[] = {
2881 SOC_DAPM_SINGLE("SPKRL Switch", SND_SOC_NOPM, 0, 1, 0)
2882};
2883
2884static const struct snd_kcontrol_new rx_int8_spline_mix_switch[] = {
2885 SOC_DAPM_SINGLE("SPKRR Switch", SND_SOC_NOPM, 0, 1, 0)
2886};
2887
2888static const struct snd_kcontrol_new rx_int5_vbat_mix_switch[] = {
2889 SOC_DAPM_SINGLE("LO3 VBAT Enable", SND_SOC_NOPM, 0, 1, 0)
2890};
2891
2892static const struct snd_kcontrol_new rx_int6_vbat_mix_switch[] = {
2893 SOC_DAPM_SINGLE("LO4 VBAT Enable", SND_SOC_NOPM, 0, 1, 0)
2894};
2895
2896static const struct snd_kcontrol_new rx_int7_vbat_mix_switch[] = {
2897 SOC_DAPM_SINGLE("SPKRL VBAT Enable", SND_SOC_NOPM, 0, 1, 0)
2898};
2899
2900static const struct snd_kcontrol_new rx_int8_vbat_mix_switch[] = {
2901 SOC_DAPM_SINGLE("SPKRR VBAT Enable", SND_SOC_NOPM, 0, 1, 0)
2902};
2903
2904static const struct snd_kcontrol_new cpe_in_mix_switch[] = {
2905 SOC_DAPM_SINGLE("MAD_BYPASS", SND_SOC_NOPM, 0, 1, 0)
2906};
2907
2908
2909
2910static int tasha_put_iir_enable_audio_mixer(
2911 struct snd_kcontrol *kcontrol,
2912 struct snd_ctl_elem_value *ucontrol)
2913{
2914 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
2915 int iir_idx = ((struct soc_multi_mixer_control *)
2916 kcontrol->private_value)->reg;
2917 int band_idx = ((struct soc_multi_mixer_control *)
2918 kcontrol->private_value)->shift;
2919 bool iir_band_en_status;
2920 int value = ucontrol->value.integer.value[0];
2921 u16 iir_reg = WCD9335_CDC_SIDETONE_IIR0_IIR_CTL + 16 * iir_idx;
2922
2923 /* Mask first 5 bits, 6-8 are reserved */
2924 snd_soc_update_bits(codec, iir_reg, (1 << band_idx),
2925 (value << band_idx));
2926
2927 iir_band_en_status = ((snd_soc_read(codec, iir_reg) &
2928 (1 << band_idx)) != 0);
2929 pr_debug("%s: IIR #%d band #%d enable %d\n", __func__,
2930 iir_idx, band_idx, iir_band_en_status);
2931 return 0;
2932}
2933
2934static uint32_t get_iir_band_coeff(struct snd_soc_codec *codec,
2935 int iir_idx, int band_idx,
2936 int coeff_idx)
2937{
2938 uint32_t value = 0;
2939
2940 /* Address does not automatically update if reading */
2941 snd_soc_write(codec,
2942 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx),
2943 ((band_idx * BAND_MAX + coeff_idx)
2944 * sizeof(uint32_t)) & 0x7F);
2945
2946 value |= snd_soc_read(codec,
2947 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx));
2948
2949 snd_soc_write(codec,
2950 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx),
2951 ((band_idx * BAND_MAX + coeff_idx)
2952 * sizeof(uint32_t) + 1) & 0x7F);
2953
2954 value |= (snd_soc_read(codec,
2955 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL +
2956 16 * iir_idx)) << 8);
2957
2958 snd_soc_write(codec,
2959 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx),
2960 ((band_idx * BAND_MAX + coeff_idx)
2961 * sizeof(uint32_t) + 2) & 0x7F);
2962
2963 value |= (snd_soc_read(codec,
2964 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL +
2965 16 * iir_idx)) << 16);
2966
2967 snd_soc_write(codec,
2968 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx),
2969 ((band_idx * BAND_MAX + coeff_idx)
2970 * sizeof(uint32_t) + 3) & 0x7F);
2971
2972 /* Mask bits top 2 bits since they are reserved */
2973 value |= ((snd_soc_read(codec,
2974 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL +
2975 16 * iir_idx)) & 0x3F) << 24);
2976
2977 return value;
2978}
2979
2980static int tasha_get_iir_band_audio_mixer(
2981 struct snd_kcontrol *kcontrol,
2982 struct snd_ctl_elem_value *ucontrol)
2983{
2984 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
2985 int iir_idx = ((struct soc_multi_mixer_control *)
2986 kcontrol->private_value)->reg;
2987 int band_idx = ((struct soc_multi_mixer_control *)
2988 kcontrol->private_value)->shift;
2989
2990 ucontrol->value.integer.value[0] =
2991 get_iir_band_coeff(codec, iir_idx, band_idx, 0);
2992 ucontrol->value.integer.value[1] =
2993 get_iir_band_coeff(codec, iir_idx, band_idx, 1);
2994 ucontrol->value.integer.value[2] =
2995 get_iir_band_coeff(codec, iir_idx, band_idx, 2);
2996 ucontrol->value.integer.value[3] =
2997 get_iir_band_coeff(codec, iir_idx, band_idx, 3);
2998 ucontrol->value.integer.value[4] =
2999 get_iir_band_coeff(codec, iir_idx, band_idx, 4);
3000
3001 pr_debug("%s: IIR #%d band #%d b0 = 0x%x\n"
3002 "%s: IIR #%d band #%d b1 = 0x%x\n"
3003 "%s: IIR #%d band #%d b2 = 0x%x\n"
3004 "%s: IIR #%d band #%d a1 = 0x%x\n"
3005 "%s: IIR #%d band #%d a2 = 0x%x\n",
3006 __func__, iir_idx, band_idx,
3007 (uint32_t)ucontrol->value.integer.value[0],
3008 __func__, iir_idx, band_idx,
3009 (uint32_t)ucontrol->value.integer.value[1],
3010 __func__, iir_idx, band_idx,
3011 (uint32_t)ucontrol->value.integer.value[2],
3012 __func__, iir_idx, band_idx,
3013 (uint32_t)ucontrol->value.integer.value[3],
3014 __func__, iir_idx, band_idx,
3015 (uint32_t)ucontrol->value.integer.value[4]);
3016 return 0;
3017}
3018
3019static void set_iir_band_coeff(struct snd_soc_codec *codec,
3020 int iir_idx, int band_idx,
3021 uint32_t value)
3022{
3023 snd_soc_write(codec,
3024 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx),
3025 (value & 0xFF));
3026
3027 snd_soc_write(codec,
3028 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx),
3029 (value >> 8) & 0xFF);
3030
3031 snd_soc_write(codec,
3032 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx),
3033 (value >> 16) & 0xFF);
3034
3035 /* Mask top 2 bits, 7-8 are reserved */
3036 snd_soc_write(codec,
3037 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx),
3038 (value >> 24) & 0x3F);
3039}
3040
3041static void tasha_codec_enable_int_port(struct wcd9xxx_codec_dai_data *dai,
3042 struct snd_soc_codec *codec)
3043{
3044 struct wcd9xxx_ch *ch;
3045 int port_num = 0;
3046 unsigned short reg = 0;
3047 u8 val = 0;
3048 struct tasha_priv *tasha_p;
3049
3050 if (!dai || !codec) {
3051 pr_err("%s: Invalid params\n", __func__);
3052 return;
3053 }
3054
3055 tasha_p = snd_soc_codec_get_drvdata(codec);
3056 list_for_each_entry(ch, &dai->wcd9xxx_ch_list, list) {
3057 if (ch->port >= TASHA_RX_PORT_START_NUMBER) {
3058 port_num = ch->port - TASHA_RX_PORT_START_NUMBER;
3059 reg = TASHA_SLIM_PGD_PORT_INT_EN0 + (port_num / 8);
3060 val = wcd9xxx_interface_reg_read(tasha_p->wcd9xxx,
3061 reg);
3062 if (!(val & BYTE_BIT_MASK(port_num))) {
3063 val |= BYTE_BIT_MASK(port_num);
3064 wcd9xxx_interface_reg_write(
3065 tasha_p->wcd9xxx, reg, val);
3066 val = wcd9xxx_interface_reg_read(
3067 tasha_p->wcd9xxx, reg);
3068 }
3069 } else {
3070 port_num = ch->port;
3071 reg = TASHA_SLIM_PGD_PORT_INT_TX_EN0 + (port_num / 8);
3072 val = wcd9xxx_interface_reg_read(tasha_p->wcd9xxx,
3073 reg);
3074 if (!(val & BYTE_BIT_MASK(port_num))) {
3075 val |= BYTE_BIT_MASK(port_num);
3076 wcd9xxx_interface_reg_write(tasha_p->wcd9xxx,
3077 reg, val);
3078 val = wcd9xxx_interface_reg_read(
3079 tasha_p->wcd9xxx, reg);
3080 }
3081 }
3082 }
3083}
3084
3085static int tasha_codec_enable_slim_chmask(struct wcd9xxx_codec_dai_data *dai,
3086 bool up)
3087{
3088 int ret = 0;
3089 struct wcd9xxx_ch *ch;
3090
3091 if (up) {
3092 list_for_each_entry(ch, &dai->wcd9xxx_ch_list, list) {
3093 ret = wcd9xxx_get_slave_port(ch->ch_num);
3094 if (ret < 0) {
3095 pr_err("%s: Invalid slave port ID: %d\n",
3096 __func__, ret);
3097 ret = -EINVAL;
3098 } else {
3099 set_bit(ret, &dai->ch_mask);
3100 }
3101 }
3102 } else {
3103 ret = wait_event_timeout(dai->dai_wait, (dai->ch_mask == 0),
3104 msecs_to_jiffies(
3105 TASHA_SLIM_CLOSE_TIMEOUT));
3106 if (!ret) {
3107 pr_err("%s: Slim close tx/rx wait timeout, ch_mask:0x%lx\n",
3108 __func__, dai->ch_mask);
3109 ret = -ETIMEDOUT;
3110 } else {
3111 ret = 0;
3112 }
3113 }
3114 return ret;
3115}
3116
3117static int tasha_codec_enable_slimrx(struct snd_soc_dapm_widget *w,
3118 struct snd_kcontrol *kcontrol,
3119 int event)
3120{
3121 struct wcd9xxx *core;
3122 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
3123 struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec);
3124 int ret = 0;
3125 struct wcd9xxx_codec_dai_data *dai;
3126
3127 core = dev_get_drvdata(codec->dev->parent);
3128
3129 dev_dbg(codec->dev, "%s: event called! codec name %s num_dai %d\n"
3130 "stream name %s event %d\n",
3131 __func__, codec->component.name,
3132 codec->component.num_dai, w->sname, event);
3133
3134 /* Execute the callback only if interface type is slimbus */
3135 if (tasha_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS)
3136 return 0;
3137
3138 dai = &tasha_p->dai[w->shift];
3139 dev_dbg(codec->dev, "%s: w->name %s w->shift %d event %d\n",
3140 __func__, w->name, w->shift, event);
3141
3142 switch (event) {
3143 case SND_SOC_DAPM_POST_PMU:
3144 dai->bus_down_in_recovery = false;
3145 tasha_codec_enable_int_port(dai, codec);
3146 (void) tasha_codec_enable_slim_chmask(dai, true);
3147 ret = wcd9xxx_cfg_slim_sch_rx(core, &dai->wcd9xxx_ch_list,
3148 dai->rate, dai->bit_width,
3149 &dai->grph);
3150 break;
3151 case SND_SOC_DAPM_PRE_PMD:
3152 if (!test_bit(SB_CLK_GEAR, &tasha_p->status_mask)) {
3153 tasha_codec_vote_max_bw(codec, true);
3154 set_bit(SB_CLK_GEAR, &tasha_p->status_mask);
3155 }
3156 break;
3157 case SND_SOC_DAPM_POST_PMD:
3158 ret = wcd9xxx_disconnect_port(core, &dai->wcd9xxx_ch_list,
3159 dai->grph);
3160 dev_dbg(codec->dev, "%s: Disconnect RX port, ret = %d\n",
3161 __func__, ret);
3162
3163 if (!dai->bus_down_in_recovery)
3164 ret = tasha_codec_enable_slim_chmask(dai, false);
3165 else
3166 dev_dbg(codec->dev,
3167 "%s: bus in recovery skip enable slim_chmask",
3168 __func__);
3169 ret = wcd9xxx_close_slim_sch_rx(core, &dai->wcd9xxx_ch_list,
3170 dai->grph);
3171 break;
3172 }
3173 return ret;
3174}
3175
3176static int tasha_codec_enable_slimvi_feedback(struct snd_soc_dapm_widget *w,
3177 struct snd_kcontrol *kcontrol,
3178 int event)
3179{
3180 struct wcd9xxx *core = NULL;
3181 struct snd_soc_codec *codec = NULL;
3182 struct tasha_priv *tasha_p = NULL;
3183 int ret = 0;
3184 struct wcd9xxx_codec_dai_data *dai = NULL;
3185
3186 if (!w) {
3187 pr_err("%s invalid params\n", __func__);
3188 return -EINVAL;
3189 }
3190 codec = snd_soc_dapm_to_codec(w->dapm);
3191 tasha_p = snd_soc_codec_get_drvdata(codec);
3192 core = tasha_p->wcd9xxx;
3193
3194 dev_dbg(codec->dev, "%s: num_dai %d stream name %s\n",
3195 __func__, codec->component.num_dai, w->sname);
3196
3197 /* Execute the callback only if interface type is slimbus */
3198 if (tasha_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
3199 dev_err(codec->dev, "%s Interface is not correct", __func__);
3200 return 0;
3201 }
3202
3203 dev_dbg(codec->dev, "%s(): w->name %s event %d w->shift %d\n",
3204 __func__, w->name, event, w->shift);
3205 if (w->shift != AIF4_VIFEED) {
3206 pr_err("%s Error in enabling the tx path\n", __func__);
3207 ret = -EINVAL;
3208 goto out_vi;
3209 }
3210 dai = &tasha_p->dai[w->shift];
3211 switch (event) {
3212 case SND_SOC_DAPM_POST_PMU:
3213 if (test_bit(VI_SENSE_1, &tasha_p->status_mask)) {
3214 dev_dbg(codec->dev, "%s: spkr1 enabled\n", __func__);
3215 /* Enable V&I sensing */
3216 snd_soc_update_bits(codec,
3217 WCD9335_CDC_TX9_SPKR_PROT_PATH_CTL, 0x20, 0x20);
3218 snd_soc_update_bits(codec,
3219 WCD9335_CDC_TX10_SPKR_PROT_PATH_CTL, 0x20,
3220 0x20);
3221 snd_soc_update_bits(codec,
3222 WCD9335_CDC_TX9_SPKR_PROT_PATH_CTL, 0x0F, 0x00);
3223 snd_soc_update_bits(codec,
3224 WCD9335_CDC_TX10_SPKR_PROT_PATH_CTL, 0x0F,
3225 0x00);
3226 snd_soc_update_bits(codec,
3227 WCD9335_CDC_TX9_SPKR_PROT_PATH_CTL, 0x10, 0x10);
3228 snd_soc_update_bits(codec,
3229 WCD9335_CDC_TX10_SPKR_PROT_PATH_CTL, 0x10,
3230 0x10);
3231 snd_soc_update_bits(codec,
3232 WCD9335_CDC_TX9_SPKR_PROT_PATH_CTL, 0x20, 0x00);
3233 snd_soc_update_bits(codec,
3234 WCD9335_CDC_TX10_SPKR_PROT_PATH_CTL, 0x20,
3235 0x00);
3236 }
3237 if (test_bit(VI_SENSE_2, &tasha_p->status_mask)) {
3238 pr_debug("%s: spkr2 enabled\n", __func__);
3239 /* Enable V&I sensing */
3240 snd_soc_update_bits(codec,
3241 WCD9335_CDC_TX11_SPKR_PROT_PATH_CTL, 0x20,
3242 0x20);
3243 snd_soc_update_bits(codec,
3244 WCD9335_CDC_TX12_SPKR_PROT_PATH_CTL, 0x20,
3245 0x20);
3246 snd_soc_update_bits(codec,
3247 WCD9335_CDC_TX11_SPKR_PROT_PATH_CTL, 0x0F,
3248 0x00);
3249 snd_soc_update_bits(codec,
3250 WCD9335_CDC_TX12_SPKR_PROT_PATH_CTL, 0x0F,
3251 0x00);
3252 snd_soc_update_bits(codec,
3253 WCD9335_CDC_TX11_SPKR_PROT_PATH_CTL, 0x10,
3254 0x10);
3255 snd_soc_update_bits(codec,
3256 WCD9335_CDC_TX12_SPKR_PROT_PATH_CTL, 0x10,
3257 0x10);
3258 snd_soc_update_bits(codec,
3259 WCD9335_CDC_TX11_SPKR_PROT_PATH_CTL, 0x20,
3260 0x00);
3261 snd_soc_update_bits(codec,
3262 WCD9335_CDC_TX12_SPKR_PROT_PATH_CTL, 0x20,
3263 0x00);
3264 }
3265 dai->bus_down_in_recovery = false;
3266 tasha_codec_enable_int_port(dai, codec);
3267 (void) tasha_codec_enable_slim_chmask(dai, true);
3268 ret = wcd9xxx_cfg_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
3269 dai->rate, dai->bit_width,
3270 &dai->grph);
3271 break;
3272 case SND_SOC_DAPM_POST_PMD:
3273 ret = wcd9xxx_close_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
3274 dai->grph);
3275 if (ret)
3276 dev_err(codec->dev, "%s error in close_slim_sch_tx %d\n",
3277 __func__, ret);
3278 if (!dai->bus_down_in_recovery)
3279 ret = tasha_codec_enable_slim_chmask(dai, false);
3280 if (ret < 0) {
3281 ret = wcd9xxx_disconnect_port(core,
3282 &dai->wcd9xxx_ch_list,
3283 dai->grph);
3284 dev_dbg(codec->dev, "%s: Disconnect TX port, ret = %d\n",
3285 __func__, ret);
3286 }
3287 if (test_bit(VI_SENSE_1, &tasha_p->status_mask)) {
3288 /* Disable V&I sensing */
3289 dev_dbg(codec->dev, "%s: spkr1 disabled\n", __func__);
3290 snd_soc_update_bits(codec,
3291 WCD9335_CDC_TX9_SPKR_PROT_PATH_CTL, 0x20, 0x20);
3292 snd_soc_update_bits(codec,
3293 WCD9335_CDC_TX10_SPKR_PROT_PATH_CTL, 0x20,
3294 0x20);
3295 snd_soc_update_bits(codec,
3296 WCD9335_CDC_TX9_SPKR_PROT_PATH_CTL, 0x10, 0x00);
3297 snd_soc_update_bits(codec,
3298 WCD9335_CDC_TX10_SPKR_PROT_PATH_CTL, 0x10,
3299 0x00);
3300 }
3301 if (test_bit(VI_SENSE_2, &tasha_p->status_mask)) {
3302 /* Disable V&I sensing */
3303 dev_dbg(codec->dev, "%s: spkr2 disabled\n", __func__);
3304 snd_soc_update_bits(codec,
3305 WCD9335_CDC_TX11_SPKR_PROT_PATH_CTL, 0x20,
3306 0x20);
3307 snd_soc_update_bits(codec,
3308 WCD9335_CDC_TX12_SPKR_PROT_PATH_CTL, 0x20,
3309 0x20);
3310 snd_soc_update_bits(codec,
3311 WCD9335_CDC_TX11_SPKR_PROT_PATH_CTL, 0x10,
3312 0x00);
3313 snd_soc_update_bits(codec,
3314 WCD9335_CDC_TX12_SPKR_PROT_PATH_CTL, 0x10,
3315 0x00);
3316 }
3317 break;
3318 }
3319out_vi:
3320 return ret;
3321}
3322
3323/*
3324 * __tasha_codec_enable_slimtx: Enable the slimbus slave port
3325 * for TX path
3326 * @codec: Handle to the codec for which the slave port is to be
3327 * enabled.
3328 * @dai_data: The dai specific data for dai which is enabled.
3329 */
3330static int __tasha_codec_enable_slimtx(struct snd_soc_codec *codec,
3331 int event, struct wcd9xxx_codec_dai_data *dai)
3332{
3333 struct wcd9xxx *core;
3334 struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec);
3335 int ret = 0;
3336
3337 /* Execute the callback only if interface type is slimbus */
3338 if (tasha_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS)
3339 return 0;
3340
3341 dev_dbg(codec->dev,
3342 "%s: event = %d\n", __func__, event);
3343 core = dev_get_drvdata(codec->dev->parent);
3344
3345 switch (event) {
3346 case SND_SOC_DAPM_POST_PMU:
3347 dai->bus_down_in_recovery = false;
3348 tasha_codec_enable_int_port(dai, codec);
3349 (void) tasha_codec_enable_slim_chmask(dai, true);
3350 ret = wcd9xxx_cfg_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
3351 dai->rate, dai->bit_width,
3352 &dai->grph);
3353 break;
3354 case SND_SOC_DAPM_POST_PMD:
3355 ret = wcd9xxx_close_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
3356 dai->grph);
3357 if (!dai->bus_down_in_recovery)
3358 ret = tasha_codec_enable_slim_chmask(dai, false);
3359 if (ret < 0) {
3360 ret = wcd9xxx_disconnect_port(core,
3361 &dai->wcd9xxx_ch_list,
3362 dai->grph);
3363 pr_debug("%s: Disconnect TX port, ret = %d\n",
3364 __func__, ret);
3365 }
3366
3367 break;
3368 }
3369
3370 return ret;
3371}
3372
3373static int tasha_codec_enable_slimtx(struct snd_soc_dapm_widget *w,
3374 struct snd_kcontrol *kcontrol,
3375 int event)
3376{
3377 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
3378 struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec);
3379 struct wcd9xxx_codec_dai_data *dai;
3380
3381 dev_dbg(codec->dev,
3382 "%s: w->name %s, w->shift = %d, num_dai %d stream name %s\n",
3383 __func__, w->name, w->shift,
3384 codec->component.num_dai, w->sname);
3385
3386 dai = &tasha_p->dai[w->shift];
3387 return __tasha_codec_enable_slimtx(codec, event, dai);
3388}
3389
3390static void tasha_codec_cpe_pp_set_cfg(struct snd_soc_codec *codec, int event)
3391{
3392 struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec);
3393 struct wcd9xxx_codec_dai_data *dai;
3394 u8 bit_width, rate, buf_period;
3395
3396 dai = &tasha_p->dai[AIF4_MAD_TX];
3397 switch (event) {
3398 case SND_SOC_DAPM_POST_PMU:
3399 switch (dai->bit_width) {
3400 case 32:
3401 bit_width = 0xF;
3402 break;
3403 case 24:
3404 bit_width = 0xE;
3405 break;
3406 case 20:
3407 bit_width = 0xD;
3408 break;
3409 case 16:
3410 default:
3411 bit_width = 0x0;
3412 break;
3413 }
3414 snd_soc_update_bits(codec, WCD9335_CPE_SS_TX_PP_CFG, 0x0F,
3415 bit_width);
3416
3417 switch (dai->rate) {
3418 case 384000:
3419 rate = 0x30;
3420 break;
3421 case 192000:
3422 rate = 0x20;
3423 break;
3424 case 48000:
3425 rate = 0x10;
3426 break;
3427 case 16000:
3428 default:
3429 rate = 0x00;
3430 break;
3431 }
3432 snd_soc_update_bits(codec, WCD9335_CPE_SS_TX_PP_CFG, 0x70,
3433 rate);
3434
3435 buf_period = (dai->rate * (dai->bit_width/8)) / (16*1000);
3436 snd_soc_update_bits(codec, WCD9335_CPE_SS_TX_PP_BUF_INT_PERIOD,
3437 0xFF, buf_period);
3438 dev_dbg(codec->dev, "%s: PP buffer period= 0x%x\n",
3439 __func__, buf_period);
3440 break;
3441
3442 case SND_SOC_DAPM_POST_PMD:
3443 snd_soc_write(codec, WCD9335_CPE_SS_TX_PP_CFG, 0x3C);
3444 snd_soc_write(codec, WCD9335_CPE_SS_TX_PP_BUF_INT_PERIOD, 0x60);
3445 break;
3446
3447 default:
3448 break;
3449 }
3450}
3451
3452/*
3453 * tasha_codec_get_mad_port_id: Callback function that will be invoked
3454 * to get the port ID for MAD.
3455 * @codec: Handle to the codec
3456 * @port_id: cpe port_id needs to enable
3457 */
3458static int tasha_codec_get_mad_port_id(struct snd_soc_codec *codec,
3459 u16 *port_id)
3460{
3461 struct tasha_priv *tasha_p;
3462 struct wcd9xxx_codec_dai_data *dai;
3463 struct wcd9xxx_ch *ch;
3464
3465 if (!port_id || !codec)
3466 return -EINVAL;
3467
3468 tasha_p = snd_soc_codec_get_drvdata(codec);
3469 if (!tasha_p)
3470 return -EINVAL;
3471
3472 dai = &tasha_p->dai[AIF4_MAD_TX];
3473 list_for_each_entry(ch, &dai->wcd9xxx_ch_list, list) {
3474 if (ch->port == TASHA_TX12)
3475 *port_id = WCD_CPE_AFE_OUT_PORT_2;
3476 else if (ch->port == TASHA_TX13)
3477 *port_id = WCD_CPE_AFE_OUT_PORT_4;
3478 else {
3479 dev_err(codec->dev, "%s: invalid mad_port = %d\n",
3480 __func__, ch->port);
3481 return -EINVAL;
3482 }
3483 }
3484 dev_dbg(codec->dev, "%s: port_id = %d\n", __func__, *port_id);
3485
3486 return 0;
3487}
3488
3489/*
3490 * tasha_codec_enable_slimtx_mad: Callback function that will be invoked
3491 * to setup the slave port for MAD.
3492 * @codec: Handle to the codec
3493 * @event: Indicates whether to enable or disable the slave port
3494 */
3495static int tasha_codec_enable_slimtx_mad(struct snd_soc_codec *codec,
3496 u8 event)
3497{
3498 struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec);
3499 struct wcd9xxx_codec_dai_data *dai;
3500 struct wcd9xxx_ch *ch;
3501 int dapm_event = SND_SOC_DAPM_POST_PMU;
3502 u16 port = 0;
3503 int ret = 0;
3504
3505 dai = &tasha_p->dai[AIF4_MAD_TX];
3506
3507 if (event == 0)
3508 dapm_event = SND_SOC_DAPM_POST_PMD;
3509
3510 dev_dbg(codec->dev,
3511 "%s: mad_channel, event = 0x%x\n",
3512 __func__, event);
3513
3514 list_for_each_entry(ch, &dai->wcd9xxx_ch_list, list) {
3515 dev_dbg(codec->dev, "%s: mad_port = %d, event = 0x%x\n",
3516 __func__, ch->port, event);
3517 if (ch->port == TASHA_TX13) {
3518 tasha_codec_cpe_pp_set_cfg(codec, dapm_event);
3519 port = TASHA_TX13;
3520 break;
3521 }
3522 }
3523
3524 ret = __tasha_codec_enable_slimtx(codec, dapm_event, dai);
3525
3526 if (port == TASHA_TX13) {
3527 switch (dapm_event) {
3528 case SND_SOC_DAPM_POST_PMU:
3529 snd_soc_update_bits(codec,
3530 WCD9335_CODEC_RPM_PWR_CPE_DRAM1_SHUTDOWN,
3531 0x20, 0x00);
3532 snd_soc_update_bits(codec,
3533 WCD9335_DATA_HUB_DATA_HUB_SB_TX13_INP_CFG,
3534 0x03, 0x02);
3535 snd_soc_update_bits(codec, WCD9335_CPE_SS_CFG,
3536 0x80, 0x80);
3537 break;
3538 case SND_SOC_DAPM_POST_PMD:
3539 snd_soc_update_bits(codec,
3540 WCD9335_CODEC_RPM_PWR_CPE_DRAM1_SHUTDOWN,
3541 0x20, 0x20);
3542 snd_soc_update_bits(codec,
3543 WCD9335_DATA_HUB_DATA_HUB_SB_TX13_INP_CFG,
3544 0x03, 0x00);
3545 snd_soc_update_bits(codec, WCD9335_CPE_SS_CFG,
3546 0x80, 0x00);
3547 break;
3548 }
3549 }
3550
3551 return ret;
3552}
3553
3554static int tasha_put_iir_band_audio_mixer(
3555 struct snd_kcontrol *kcontrol,
3556 struct snd_ctl_elem_value *ucontrol)
3557{
3558 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
3559 int iir_idx = ((struct soc_multi_mixer_control *)
3560 kcontrol->private_value)->reg;
3561 int band_idx = ((struct soc_multi_mixer_control *)
3562 kcontrol->private_value)->shift;
3563
3564 /*
3565 * Mask top bit it is reserved
3566 * Updates addr automatically for each B2 write
3567 */
3568 snd_soc_write(codec,
3569 (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx),
3570 (band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F);
3571
3572 set_iir_band_coeff(codec, iir_idx, band_idx,
3573 ucontrol->value.integer.value[0]);
3574 set_iir_band_coeff(codec, iir_idx, band_idx,
3575 ucontrol->value.integer.value[1]);
3576 set_iir_band_coeff(codec, iir_idx, band_idx,
3577 ucontrol->value.integer.value[2]);
3578 set_iir_band_coeff(codec, iir_idx, band_idx,
3579 ucontrol->value.integer.value[3]);
3580 set_iir_band_coeff(codec, iir_idx, band_idx,
3581 ucontrol->value.integer.value[4]);
3582
3583 pr_debug("%s: IIR #%d band #%d b0 = 0x%x\n"
3584 "%s: IIR #%d band #%d b1 = 0x%x\n"
3585 "%s: IIR #%d band #%d b2 = 0x%x\n"
3586 "%s: IIR #%d band #%d a1 = 0x%x\n"
3587 "%s: IIR #%d band #%d a2 = 0x%x\n",
3588 __func__, iir_idx, band_idx,
3589 get_iir_band_coeff(codec, iir_idx, band_idx, 0),
3590 __func__, iir_idx, band_idx,
3591 get_iir_band_coeff(codec, iir_idx, band_idx, 1),
3592 __func__, iir_idx, band_idx,
3593 get_iir_band_coeff(codec, iir_idx, band_idx, 2),
3594 __func__, iir_idx, band_idx,
3595 get_iir_band_coeff(codec, iir_idx, band_idx, 3),
3596 __func__, iir_idx, band_idx,
3597 get_iir_band_coeff(codec, iir_idx, band_idx, 4));
3598 return 0;
3599}
3600
3601static int tasha_get_compander(struct snd_kcontrol *kcontrol,
3602 struct snd_ctl_elem_value *ucontrol)
3603{
3604
3605 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
3606 int comp = ((struct soc_multi_mixer_control *)
3607 kcontrol->private_value)->shift;
3608 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
3609
3610 ucontrol->value.integer.value[0] = tasha->comp_enabled[comp];
3611 return 0;
3612}
3613
3614static int tasha_set_compander(struct snd_kcontrol *kcontrol,
3615 struct snd_ctl_elem_value *ucontrol)
3616{
3617 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
3618 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
3619 int comp = ((struct soc_multi_mixer_control *)
3620 kcontrol->private_value)->shift;
3621 int value = ucontrol->value.integer.value[0];
3622
3623 pr_debug("%s: Compander %d enable current %d, new %d\n",
3624 __func__, comp + 1, tasha->comp_enabled[comp], value);
3625 tasha->comp_enabled[comp] = value;
3626
3627 /* Any specific register configuration for compander */
3628 switch (comp) {
3629 case COMPANDER_1:
3630 /* Set Gain Source Select based on compander enable/disable */
3631 snd_soc_update_bits(codec, WCD9335_HPH_L_EN, 0x20,
3632 (value ? 0x00:0x20));
3633 break;
3634 case COMPANDER_2:
3635 snd_soc_update_bits(codec, WCD9335_HPH_R_EN, 0x20,
3636 (value ? 0x00:0x20));
3637 break;
3638 case COMPANDER_3:
3639 break;
3640 case COMPANDER_4:
3641 break;
3642 case COMPANDER_5:
3643 snd_soc_update_bits(codec, WCD9335_SE_LO_LO3_GAIN, 0x20,
3644 (value ? 0x00:0x20));
3645 break;
3646 case COMPANDER_6:
3647 snd_soc_update_bits(codec, WCD9335_SE_LO_LO4_GAIN, 0x20,
3648 (value ? 0x00:0x20));
3649 break;
3650 case COMPANDER_7:
3651 break;
3652 case COMPANDER_8:
3653 break;
3654 default:
3655 /*
3656 * if compander is not enabled for any interpolator,
3657 * it does not cause any audio failure, so do not
3658 * return error in this case, but just print a log
3659 */
3660 dev_warn(codec->dev, "%s: unknown compander: %d\n",
3661 __func__, comp);
3662 };
3663 return 0;
3664}
3665
3666static void tasha_codec_init_flyback(struct snd_soc_codec *codec)
3667{
3668 snd_soc_update_bits(codec, WCD9335_HPH_L_EN, 0xC0, 0x00);
3669 snd_soc_update_bits(codec, WCD9335_HPH_R_EN, 0xC0, 0x00);
3670 snd_soc_update_bits(codec, WCD9335_RX_BIAS_FLYB_BUFF, 0x0F, 0x00);
3671 snd_soc_update_bits(codec, WCD9335_RX_BIAS_FLYB_BUFF, 0xF0, 0x00);
3672}
3673
3674static int tasha_codec_enable_rx_bias(struct snd_soc_dapm_widget *w,
3675 struct snd_kcontrol *kcontrol, int event)
3676{
3677 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
3678 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
3679
3680 dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
3681
3682 switch (event) {
3683 case SND_SOC_DAPM_PRE_PMU:
3684 tasha->rx_bias_count++;
3685 if (tasha->rx_bias_count == 1) {
3686 if (TASHA_IS_2_0(tasha->wcd9xxx))
3687 tasha_codec_init_flyback(codec);
3688 snd_soc_update_bits(codec, WCD9335_ANA_RX_SUPPLIES,
3689 0x01, 0x01);
3690 }
3691 break;
3692 case SND_SOC_DAPM_POST_PMD:
3693 tasha->rx_bias_count--;
3694 if (!tasha->rx_bias_count)
3695 snd_soc_update_bits(codec, WCD9335_ANA_RX_SUPPLIES,
3696 0x01, 0x00);
3697 break;
3698 };
3699 dev_dbg(codec->dev, "%s: Current RX BIAS user count: %d\n", __func__,
3700 tasha->rx_bias_count);
3701
3702 return 0;
3703}
3704
3705static void tasha_realign_anc_coeff(struct snd_soc_codec *codec,
3706 u16 reg1, u16 reg2)
3707{
3708 u8 val1, val2, tmpval1, tmpval2;
3709
3710 snd_soc_write(codec, reg1, 0x00);
3711 tmpval1 = snd_soc_read(codec, reg2);
3712 tmpval2 = snd_soc_read(codec, reg2);
3713 snd_soc_write(codec, reg1, 0x00);
3714 snd_soc_write(codec, reg2, 0xFF);
3715 snd_soc_write(codec, reg1, 0x01);
3716 snd_soc_write(codec, reg2, 0xFF);
3717
3718 snd_soc_write(codec, reg1, 0x00);
3719 val1 = snd_soc_read(codec, reg2);
3720 val2 = snd_soc_read(codec, reg2);
3721
3722 if (val1 == 0x0F && val2 == 0xFF) {
3723 dev_dbg(codec->dev, "%s: ANC0 co-eff index re-aligned\n",
3724 __func__);
3725 snd_soc_read(codec, reg2);
3726 snd_soc_write(codec, reg1, 0x00);
3727 snd_soc_write(codec, reg2, tmpval2);
3728 snd_soc_write(codec, reg1, 0x01);
3729 snd_soc_write(codec, reg2, tmpval1);
3730 } else if (val1 == 0xFF && val2 == 0x0F) {
3731 dev_dbg(codec->dev, "%s: ANC1 co-eff index already aligned\n",
3732 __func__);
3733 snd_soc_write(codec, reg1, 0x00);
3734 snd_soc_write(codec, reg2, tmpval1);
3735 snd_soc_write(codec, reg1, 0x01);
3736 snd_soc_write(codec, reg2, tmpval2);
3737 } else {
3738 dev_err(codec->dev, "%s: ANC0 co-eff index not aligned\n",
3739 __func__);
3740 }
3741}
3742
3743static int tasha_codec_enable_anc(struct snd_soc_dapm_widget *w,
3744 struct snd_kcontrol *kcontrol, int event)
3745{
3746 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
3747 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
3748 const char *filename;
3749 const struct firmware *fw;
3750 int i;
3751 int ret = 0;
3752 int num_anc_slots;
3753 struct wcd9xxx_anc_header *anc_head;
3754 struct firmware_cal *hwdep_cal = NULL;
3755 u32 anc_writes_size = 0;
3756 u32 anc_cal_size = 0;
3757 int anc_size_remaining;
3758 u32 *anc_ptr;
3759 u16 reg;
3760 u8 mask, val;
3761 size_t cal_size;
3762 const void *data;
3763
3764 if (!tasha->anc_func)
3765 return 0;
3766
3767 switch (event) {
3768 case SND_SOC_DAPM_PRE_PMU:
3769 hwdep_cal = wcdcal_get_fw_cal(tasha->fw_data, WCD9XXX_ANC_CAL);
3770 if (hwdep_cal) {
3771 data = hwdep_cal->data;
3772 cal_size = hwdep_cal->size;
3773 dev_dbg(codec->dev, "%s: using hwdep calibration\n",
3774 __func__);
3775 } else {
3776 filename = "wcd9335/wcd9335_anc.bin";
3777 ret = request_firmware(&fw, filename, codec->dev);
3778 if (ret != 0) {
3779 dev_err(codec->dev,
3780 "Failed to acquire ANC data: %d\n", ret);
3781 return -ENODEV;
3782 }
3783 if (!fw) {
3784 dev_err(codec->dev, "failed to get anc fw");
3785 return -ENODEV;
3786 }
3787 data = fw->data;
3788 cal_size = fw->size;
3789 dev_dbg(codec->dev,
3790 "%s: using request_firmware calibration\n", __func__);
3791 }
3792 if (cal_size < sizeof(struct wcd9xxx_anc_header)) {
3793 dev_err(codec->dev, "Not enough data\n");
3794 ret = -ENOMEM;
3795 goto err;
3796 }
3797 /* First number is the number of register writes */
3798 anc_head = (struct wcd9xxx_anc_header *)(data);
3799 anc_ptr = (u32 *)(data +
3800 sizeof(struct wcd9xxx_anc_header));
3801 anc_size_remaining = cal_size -
3802 sizeof(struct wcd9xxx_anc_header);
3803 num_anc_slots = anc_head->num_anc_slots;
3804
3805 if (tasha->anc_slot >= num_anc_slots) {
3806 dev_err(codec->dev, "Invalid ANC slot selected\n");
3807 ret = -EINVAL;
3808 goto err;
3809 }
3810 for (i = 0; i < num_anc_slots; i++) {
3811 if (anc_size_remaining < TASHA_PACKED_REG_SIZE) {
3812 dev_err(codec->dev,
3813 "Invalid register format\n");
3814 ret = -EINVAL;
3815 goto err;
3816 }
3817 anc_writes_size = (u32)(*anc_ptr);
3818 anc_size_remaining -= sizeof(u32);
3819 anc_ptr += 1;
3820
3821 if (anc_writes_size * TASHA_PACKED_REG_SIZE
3822 > anc_size_remaining) {
3823 dev_err(codec->dev,
3824 "Invalid register format\n");
3825 ret = -EINVAL;
3826 goto err;
3827 }
3828
3829 if (tasha->anc_slot == i)
3830 break;
3831
3832 anc_size_remaining -= (anc_writes_size *
3833 TASHA_PACKED_REG_SIZE);
3834 anc_ptr += anc_writes_size;
3835 }
3836 if (i == num_anc_slots) {
3837 dev_err(codec->dev, "Selected ANC slot not present\n");
3838 ret = -EINVAL;
3839 goto err;
3840 }
3841
3842 i = 0;
3843 anc_cal_size = anc_writes_size;
3844
3845 if (!strcmp(w->name, "RX INT0 DAC") ||
3846 !strcmp(w->name, "ANC SPK1 PA"))
3847 tasha_realign_anc_coeff(codec,
3848 WCD9335_CDC_ANC0_IIR_COEFF_1_CTL,
3849 WCD9335_CDC_ANC0_IIR_COEFF_2_CTL);
3850
3851 if (!strcmp(w->name, "RX INT1 DAC") ||
3852 !strcmp(w->name, "RX INT3 DAC")) {
3853 tasha_realign_anc_coeff(codec,
3854 WCD9335_CDC_ANC0_IIR_COEFF_1_CTL,
3855 WCD9335_CDC_ANC0_IIR_COEFF_2_CTL);
3856 anc_writes_size = anc_cal_size / 2;
3857 snd_soc_update_bits(codec,
3858 WCD9335_CDC_ANC0_CLK_RESET_CTL, 0x39, 0x39);
3859 } else if (!strcmp(w->name, "RX INT2 DAC") ||
3860 !strcmp(w->name, "RX INT4 DAC")) {
3861 tasha_realign_anc_coeff(codec,
3862 WCD9335_CDC_ANC1_IIR_COEFF_1_CTL,
3863 WCD9335_CDC_ANC1_IIR_COEFF_2_CTL);
3864 i = anc_cal_size / 2;
3865 snd_soc_update_bits(codec,
3866 WCD9335_CDC_ANC1_CLK_RESET_CTL, 0x39, 0x39);
3867 }
3868
3869 for (; i < anc_writes_size; i++) {
3870 TASHA_CODEC_UNPACK_ENTRY(anc_ptr[i], reg, mask, val);
3871 snd_soc_write(codec, reg, (val & mask));
3872 }
3873 if (!strcmp(w->name, "RX INT1 DAC") ||
3874 !strcmp(w->name, "RX INT3 DAC")) {
3875 snd_soc_update_bits(codec,
3876 WCD9335_CDC_ANC0_CLK_RESET_CTL, 0x08, 0x08);
3877 } else if (!strcmp(w->name, "RX INT2 DAC") ||
3878 !strcmp(w->name, "RX INT4 DAC")) {
3879 snd_soc_update_bits(codec,
3880 WCD9335_CDC_ANC1_CLK_RESET_CTL, 0x08, 0x08);
3881 }
3882
3883 if (!hwdep_cal)
3884 release_firmware(fw);
3885 break;
3886 case SND_SOC_DAPM_POST_PMU:
3887 /* Remove ANC Rx from reset */
3888 snd_soc_update_bits(codec, WCD9335_CDC_ANC0_CLK_RESET_CTL,
3889 0x08, 0x00);
3890 snd_soc_update_bits(codec, WCD9335_CDC_ANC1_CLK_RESET_CTL,
3891 0x08, 0x00);
3892 break;
3893 case SND_SOC_DAPM_POST_PMD:
3894 if (!strcmp(w->name, "ANC HPHL PA") ||
3895 !strcmp(w->name, "ANC EAR PA") ||
3896 !strcmp(w->name, "ANC SPK1 PA") ||
3897 !strcmp(w->name, "ANC LINEOUT1 PA")) {
3898 snd_soc_update_bits(codec,
3899 WCD9335_CDC_ANC0_MODE_1_CTL, 0x30, 0x00);
3900 msleep(50);
3901 snd_soc_update_bits(codec,
3902 WCD9335_CDC_ANC0_MODE_1_CTL, 0x01, 0x00);
3903 snd_soc_update_bits(codec,
3904 WCD9335_CDC_ANC0_CLK_RESET_CTL, 0x38, 0x38);
3905 snd_soc_update_bits(codec,
3906 WCD9335_CDC_ANC0_CLK_RESET_CTL, 0x07, 0x00);
3907 snd_soc_update_bits(codec,
3908 WCD9335_CDC_ANC0_CLK_RESET_CTL, 0x38, 0x00);
3909 } else if (!strcmp(w->name, "ANC HPHR PA") ||
3910 !strcmp(w->name, "ANC LINEOUT2 PA")) {
3911 snd_soc_update_bits(codec,
3912 WCD9335_CDC_ANC1_MODE_1_CTL, 0x30, 0x00);
3913 msleep(50);
3914 snd_soc_update_bits(codec,
3915 WCD9335_CDC_ANC1_MODE_1_CTL, 0x01, 0x00);
3916 snd_soc_update_bits(codec,
3917 WCD9335_CDC_ANC1_CLK_RESET_CTL, 0x38, 0x38);
3918 snd_soc_update_bits(codec,
3919 WCD9335_CDC_ANC1_CLK_RESET_CTL, 0x07, 0x00);
3920 snd_soc_update_bits(codec,
3921 WCD9335_CDC_ANC1_CLK_RESET_CTL, 0x38, 0x00);
3922 }
3923 break;
3924 }
3925
3926 return 0;
3927err:
3928 if (!hwdep_cal)
3929 release_firmware(fw);
3930 return ret;
3931}
3932
3933static void tasha_codec_clear_anc_tx_hold(struct tasha_priv *tasha)
3934{
3935 if (test_and_clear_bit(ANC_MIC_AMIC1, &tasha->status_mask))
3936 tasha_codec_set_tx_hold(tasha->codec, WCD9335_ANA_AMIC1, false);
3937 if (test_and_clear_bit(ANC_MIC_AMIC2, &tasha->status_mask))
3938 tasha_codec_set_tx_hold(tasha->codec, WCD9335_ANA_AMIC2, false);
3939 if (test_and_clear_bit(ANC_MIC_AMIC3, &tasha->status_mask))
3940 tasha_codec_set_tx_hold(tasha->codec, WCD9335_ANA_AMIC3, false);
3941 if (test_and_clear_bit(ANC_MIC_AMIC4, &tasha->status_mask))
3942 tasha_codec_set_tx_hold(tasha->codec, WCD9335_ANA_AMIC4, false);
3943 if (test_and_clear_bit(ANC_MIC_AMIC5, &tasha->status_mask))
3944 tasha_codec_set_tx_hold(tasha->codec, WCD9335_ANA_AMIC5, false);
3945 if (test_and_clear_bit(ANC_MIC_AMIC6, &tasha->status_mask))
3946 tasha_codec_set_tx_hold(tasha->codec, WCD9335_ANA_AMIC6, false);
3947}
3948
3949static void tasha_codec_hph_post_pa_config(struct tasha_priv *tasha,
3950 int mode, int event)
3951{
3952 u8 scale_val = 0;
3953
3954 if (!TASHA_IS_2_0(tasha->wcd9xxx))
3955 return;
3956
3957 switch (event) {
3958 case SND_SOC_DAPM_POST_PMU:
3959 switch (mode) {
3960 case CLS_H_HIFI:
3961 scale_val = 0x3;
3962 break;
3963 case CLS_H_LOHIFI:
3964 scale_val = 0x1;
3965 break;
3966 }
3967 if (tasha->anc_func) {
3968 /* Clear Tx FE HOLD if both PAs are enabled */
3969 if ((snd_soc_read(tasha->codec, WCD9335_ANA_HPH) &
3970 0xC0) == 0xC0) {
3971 tasha_codec_clear_anc_tx_hold(tasha);
3972 }
3973 }
3974 break;
3975 case SND_SOC_DAPM_PRE_PMD:
3976 scale_val = 0x6;
3977 break;
3978 }
3979
3980 if (scale_val)
3981 snd_soc_update_bits(tasha->codec, WCD9335_HPH_PA_CTL1, 0x0E,
3982 scale_val << 1);
3983 if (SND_SOC_DAPM_EVENT_ON(event)) {
3984 if (tasha->comp_enabled[COMPANDER_1] ||
3985 tasha->comp_enabled[COMPANDER_2]) {
3986 snd_soc_update_bits(tasha->codec, WCD9335_HPH_L_EN,
3987 0x20, 0x00);
3988 snd_soc_update_bits(tasha->codec, WCD9335_HPH_R_EN,
3989 0x20, 0x00);
3990 snd_soc_update_bits(tasha->codec, WCD9335_HPH_AUTO_CHOP,
3991 0x20, 0x20);
3992 }
3993 snd_soc_update_bits(tasha->codec, WCD9335_HPH_L_EN, 0x1F,
3994 tasha->hph_l_gain);
3995 snd_soc_update_bits(tasha->codec, WCD9335_HPH_R_EN, 0x1F,
3996 tasha->hph_r_gain);
3997 }
3998
3999 if (SND_SOC_DAPM_EVENT_OFF(event)) {
4000 snd_soc_update_bits(tasha->codec, WCD9335_HPH_AUTO_CHOP, 0x20,
4001 0x00);
4002 }
4003}
4004
4005static void tasha_codec_override(struct snd_soc_codec *codec,
4006 int mode,
4007 int event)
4008{
4009 if (mode == CLS_AB) {
4010 switch (event) {
4011 case SND_SOC_DAPM_POST_PMU:
4012 if (!(snd_soc_read(codec,
4013 WCD9335_CDC_RX2_RX_PATH_CTL) & 0x10) &&
4014 (!(snd_soc_read(codec,
4015 WCD9335_CDC_RX1_RX_PATH_CTL) & 0x10)))
4016 snd_soc_update_bits(codec,
4017 WCD9XXX_A_ANA_RX_SUPPLIES, 0x02, 0x02);
4018 break;
4019 case SND_SOC_DAPM_POST_PMD:
4020 snd_soc_update_bits(codec,
4021 WCD9XXX_A_ANA_RX_SUPPLIES, 0x02, 0x00);
4022 break;
4023 }
4024 }
4025}
4026
4027static int tasha_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
4028 struct snd_kcontrol *kcontrol,
4029 int event)
4030{
4031 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
4032 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
4033 int hph_mode = tasha->hph_mode;
4034 int ret = 0;
4035
4036 dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
4037
4038 switch (event) {
4039 case SND_SOC_DAPM_PRE_PMU:
4040 if ((!(strcmp(w->name, "ANC HPHR PA"))) &&
4041 (test_bit(HPH_PA_DELAY, &tasha->status_mask))) {
4042 snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0xC0, 0xC0);
4043 }
4044 set_bit(HPH_PA_DELAY, &tasha->status_mask);
4045 break;
4046 case SND_SOC_DAPM_POST_PMU:
4047 if (!(strcmp(w->name, "ANC HPHR PA"))) {
4048 if ((snd_soc_read(codec, WCD9335_ANA_HPH) & 0xC0)
4049 != 0xC0)
4050 /*
4051 * If PA_EN is not set (potentially in ANC case)
4052 * then do nothing for POST_PMU and let left
4053 * channel handle everything.
4054 */
4055 break;
4056 }
4057 /*
4058 * 7ms sleep is required after PA is enabled as per
4059 * HW requirement
4060 */
4061 if (test_bit(HPH_PA_DELAY, &tasha->status_mask)) {
4062 usleep_range(7000, 7100);
4063 clear_bit(HPH_PA_DELAY, &tasha->status_mask);
4064 }
4065 tasha_codec_hph_post_pa_config(tasha, hph_mode, event);
4066 snd_soc_update_bits(codec, WCD9335_CDC_RX2_RX_PATH_CTL,
4067 0x10, 0x00);
4068 /* Remove mix path mute if it is enabled */
4069 if ((snd_soc_read(codec, WCD9335_CDC_RX2_RX_PATH_MIX_CTL)) &
4070 0x10)
4071 snd_soc_update_bits(codec,
4072 WCD9335_CDC_RX2_RX_PATH_MIX_CTL,
4073 0x10, 0x00);
4074
4075 if (!(strcmp(w->name, "ANC HPHR PA"))) {
4076 /* Do everything needed for left channel */
4077 snd_soc_update_bits(codec, WCD9335_CDC_RX1_RX_PATH_CTL,
4078 0x10, 0x00);
4079 /* Remove mix path mute if it is enabled */
4080 if ((snd_soc_read(codec,
4081 WCD9335_CDC_RX1_RX_PATH_MIX_CTL)) &
4082 0x10)
4083 snd_soc_update_bits(codec,
4084 WCD9335_CDC_RX1_RX_PATH_MIX_CTL,
4085 0x10, 0x00);
4086 /* Remove ANC Rx from reset */
4087 ret = tasha_codec_enable_anc(w, kcontrol, event);
4088 }
4089 tasha_codec_override(codec, hph_mode, event);
4090 break;
4091
4092 case SND_SOC_DAPM_PRE_PMD:
4093 blocking_notifier_call_chain(&tasha->notifier,
4094 WCD_EVENT_PRE_HPHR_PA_OFF,
4095 &tasha->mbhc);
4096 tasha_codec_hph_post_pa_config(tasha, hph_mode, event);
4097 if (!(strcmp(w->name, "ANC HPHR PA")))
4098 snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0x40, 0x00);
4099 break;
4100 case SND_SOC_DAPM_POST_PMD:
4101 /* 5ms sleep is required after PA is disabled as per
4102 * HW requirement
4103 */
4104 usleep_range(5000, 5500);
4105 tasha_codec_override(codec, hph_mode, event);
4106 blocking_notifier_call_chain(&tasha->notifier,
4107 WCD_EVENT_POST_HPHR_PA_OFF,
4108 &tasha->mbhc);
4109
4110 if (!(strcmp(w->name, "ANC HPHR PA"))) {
4111 ret = tasha_codec_enable_anc(w, kcontrol, event);
4112 snd_soc_update_bits(codec,
4113 WCD9335_CDC_RX2_RX_PATH_CFG0, 0x10, 0x00);
4114 }
4115 break;
4116 };
4117
4118 return ret;
4119}
4120
4121static int tasha_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
4122 struct snd_kcontrol *kcontrol,
4123 int event)
4124{
4125 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
4126 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
4127 int hph_mode = tasha->hph_mode;
4128 int ret = 0;
4129
4130 dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
4131
4132 switch (event) {
4133 case SND_SOC_DAPM_PRE_PMU:
4134 if ((!(strcmp(w->name, "ANC HPHL PA"))) &&
4135 (test_bit(HPH_PA_DELAY, &tasha->status_mask))) {
4136 snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0xC0, 0xC0);
4137 }
4138 set_bit(HPH_PA_DELAY, &tasha->status_mask);
4139 break;
4140 case SND_SOC_DAPM_POST_PMU:
4141 if (!(strcmp(w->name, "ANC HPHL PA"))) {
4142 if ((snd_soc_read(codec, WCD9335_ANA_HPH) & 0xC0)
4143 != 0xC0)
4144 /*
4145 * If PA_EN is not set (potentially in ANC case)
4146 * then do nothing for POST_PMU and let right
4147 * channel handle everything.
4148 */
4149 break;
4150 }
4151 /*
4152 * 7ms sleep is required after PA is enabled as per
4153 * HW requirement
4154 */
4155 if (test_bit(HPH_PA_DELAY, &tasha->status_mask)) {
4156 usleep_range(7000, 7100);
4157 clear_bit(HPH_PA_DELAY, &tasha->status_mask);
4158 }
4159
4160 tasha_codec_hph_post_pa_config(tasha, hph_mode, event);
4161 snd_soc_update_bits(codec, WCD9335_CDC_RX1_RX_PATH_CTL,
4162 0x10, 0x00);
4163 /* Remove mix path mute if it is enabled */
4164 if ((snd_soc_read(codec, WCD9335_CDC_RX1_RX_PATH_MIX_CTL)) &
4165 0x10)
4166 snd_soc_update_bits(codec,
4167 WCD9335_CDC_RX1_RX_PATH_MIX_CTL,
4168 0x10, 0x00);
4169
4170 if (!(strcmp(w->name, "ANC HPHL PA"))) {
4171 /* Do everything needed for right channel */
4172 snd_soc_update_bits(codec, WCD9335_CDC_RX2_RX_PATH_CTL,
4173 0x10, 0x00);
4174 /* Remove mix path mute if it is enabled */
4175 if ((snd_soc_read(codec,
4176 WCD9335_CDC_RX2_RX_PATH_MIX_CTL)) &
4177 0x10)
4178 snd_soc_update_bits(codec,
4179 WCD9335_CDC_RX2_RX_PATH_MIX_CTL,
4180 0x10, 0x00);
4181
4182 /* Remove ANC Rx from reset */
4183 ret = tasha_codec_enable_anc(w, kcontrol, event);
4184 }
4185 tasha_codec_override(codec, hph_mode, event);
4186 break;
4187 case SND_SOC_DAPM_PRE_PMD:
4188 blocking_notifier_call_chain(&tasha->notifier,
4189 WCD_EVENT_PRE_HPHL_PA_OFF,
4190 &tasha->mbhc);
4191 tasha_codec_hph_post_pa_config(tasha, hph_mode, event);
4192 if (!(strcmp(w->name, "ANC HPHL PA")))
4193 snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0x80, 0x00);
4194 break;
4195 case SND_SOC_DAPM_POST_PMD:
4196 /* 5ms sleep is required after PA is disabled as per
4197 * HW requirement
4198 */
4199 usleep_range(5000, 5500);
4200 tasha_codec_override(codec, hph_mode, event);
4201 blocking_notifier_call_chain(&tasha->notifier,
4202 WCD_EVENT_POST_HPHL_PA_OFF,
4203 &tasha->mbhc);
4204
4205 if (!(strcmp(w->name, "ANC HPHL PA"))) {
4206 ret = tasha_codec_enable_anc(w, kcontrol, event);
4207 snd_soc_update_bits(codec,
4208 WCD9335_CDC_RX1_RX_PATH_CFG0, 0x10, 0x00);
4209 }
4210 break;
4211 };
4212
4213 return ret;
4214}
4215
4216static int tasha_codec_enable_lineout_pa(struct snd_soc_dapm_widget *w,
4217 struct snd_kcontrol *kcontrol,
4218 int event)
4219{
4220 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
4221 u16 lineout_vol_reg = 0, lineout_mix_vol_reg = 0;
4222 int ret = 0;
4223
4224 dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
4225
4226 if (w->reg == WCD9335_ANA_LO_1_2) {
4227 if (w->shift == 7) {
4228 lineout_vol_reg = WCD9335_CDC_RX3_RX_PATH_CTL;
4229 lineout_mix_vol_reg = WCD9335_CDC_RX3_RX_PATH_MIX_CTL;
4230 } else if (w->shift == 6) {
4231 lineout_vol_reg = WCD9335_CDC_RX4_RX_PATH_CTL;
4232 lineout_mix_vol_reg = WCD9335_CDC_RX4_RX_PATH_MIX_CTL;
4233 }
4234 } else if (w->reg == WCD9335_ANA_LO_3_4) {
4235 if (w->shift == 7) {
4236 lineout_vol_reg = WCD9335_CDC_RX5_RX_PATH_CTL;
4237 lineout_mix_vol_reg = WCD9335_CDC_RX5_RX_PATH_MIX_CTL;
4238 } else if (w->shift == 6) {
4239 lineout_vol_reg = WCD9335_CDC_RX6_RX_PATH_CTL;
4240 lineout_mix_vol_reg = WCD9335_CDC_RX6_RX_PATH_MIX_CTL;
4241 }
4242 } else {
4243 dev_err(codec->dev, "%s: Error enabling lineout PA\n",
4244 __func__);
4245 return -EINVAL;
4246 }
4247
4248 switch (event) {
4249 case SND_SOC_DAPM_POST_PMU:
4250 /* 5ms sleep is required after PA is enabled as per
4251 * HW requirement
4252 */
4253 usleep_range(5000, 5500);
4254 snd_soc_update_bits(codec, lineout_vol_reg,
4255 0x10, 0x00);
4256 /* Remove mix path mute if it is enabled */
4257 if ((snd_soc_read(codec, lineout_mix_vol_reg)) & 0x10)
4258 snd_soc_update_bits(codec,
4259 lineout_mix_vol_reg,
4260 0x10, 0x00);
4261 if (!(strcmp(w->name, "ANC LINEOUT1 PA")) ||
4262 !(strcmp(w->name, "ANC LINEOUT2 PA")))
4263 ret = tasha_codec_enable_anc(w, kcontrol, event);
4264 tasha_codec_override(codec, CLS_AB, event);
4265 break;
4266 case SND_SOC_DAPM_POST_PMD:
4267 /* 5ms sleep is required after PA is disabled as per
4268 * HW requirement
4269 */
4270 usleep_range(5000, 5500);
4271 tasha_codec_override(codec, CLS_AB, event);
4272 if (!(strcmp(w->name, "ANC LINEOUT1 PA")) ||
4273 !(strcmp(w->name, "ANC LINEOUT2 PA"))) {
4274 ret = tasha_codec_enable_anc(w, kcontrol, event);
4275 if (!(strcmp(w->name, "ANC LINEOUT1 PA")))
4276 snd_soc_update_bits(codec,
4277 WCD9335_CDC_RX3_RX_PATH_CFG0, 0x10, 0x10);
4278 else
4279 snd_soc_update_bits(codec,
4280 WCD9335_CDC_RX4_RX_PATH_CFG0, 0x10, 0x10);
4281 }
4282 break;
4283 };
4284
4285 return ret;
4286}
4287
4288static void tasha_spk_anc_update_callback(struct work_struct *work)
4289{
4290 struct spk_anc_work *spk_anc_dwork;
4291 struct tasha_priv *tasha;
4292 struct delayed_work *delayed_work;
4293 struct snd_soc_codec *codec;
4294
4295 delayed_work = to_delayed_work(work);
4296 spk_anc_dwork = container_of(delayed_work, struct spk_anc_work, dwork);
4297 tasha = spk_anc_dwork->tasha;
4298 codec = tasha->codec;
4299
4300 snd_soc_update_bits(codec, WCD9335_CDC_RX7_RX_PATH_CFG0, 0x10, 0x10);
4301}
4302
4303static int tasha_codec_enable_spk_anc(struct snd_soc_dapm_widget *w,
4304 struct snd_kcontrol *kcontrol,
4305 int event)
4306{
4307 int ret = 0;
4308 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
4309 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
4310
4311 dev_dbg(codec->dev, "%s %s %d %d\n", __func__, w->name, event,
4312 tasha->anc_func);
4313
4314 if (!tasha->anc_func)
4315 return 0;
4316
4317 switch (event) {
4318 case SND_SOC_DAPM_PRE_PMU:
4319 ret = tasha_codec_enable_anc(w, kcontrol, event);
4320 schedule_delayed_work(&tasha->spk_anc_dwork.dwork,
4321 msecs_to_jiffies(spk_anc_en_delay));
4322 break;
4323 case SND_SOC_DAPM_POST_PMD:
4324 cancel_delayed_work_sync(&tasha->spk_anc_dwork.dwork);
4325 snd_soc_update_bits(codec, WCD9335_CDC_RX7_RX_PATH_CFG0,
4326 0x10, 0x00);
4327 ret = tasha_codec_enable_anc(w, kcontrol, event);
4328 break;
4329 }
4330 return ret;
4331}
4332
4333static int tasha_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
4334 struct snd_kcontrol *kcontrol,
4335 int event)
4336{
4337 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
4338 int ret = 0;
4339
4340 dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
4341
4342 switch (event) {
4343 case SND_SOC_DAPM_POST_PMU:
4344 /* 5ms sleep is required after PA is enabled as per
4345 * HW requirement
4346 */
4347 usleep_range(5000, 5500);
4348 snd_soc_update_bits(codec, WCD9335_CDC_RX0_RX_PATH_CTL,
4349 0x10, 0x00);
4350 /* Remove mix path mute if it is enabled */
4351 if ((snd_soc_read(codec, WCD9335_CDC_RX0_RX_PATH_MIX_CTL)) &
4352 0x10)
4353 snd_soc_update_bits(codec,
4354 WCD9335_CDC_RX0_RX_PATH_MIX_CTL,
4355 0x10, 0x00);
4356 break;
4357 case SND_SOC_DAPM_POST_PMD:
4358 /* 5ms sleep is required after PA is disabled as per
4359 * HW requirement
4360 */
4361 usleep_range(5000, 5500);
4362
4363 if (!(strcmp(w->name, "ANC EAR PA"))) {
4364 ret = tasha_codec_enable_anc(w, kcontrol, event);
4365 snd_soc_update_bits(codec,
4366 WCD9335_CDC_RX0_RX_PATH_CFG0, 0x10, 0x00);
4367 }
4368 break;
4369 };
4370
4371 return ret;
4372}
4373
4374static void tasha_codec_hph_mode_gain_opt(struct snd_soc_codec *codec,
4375 u8 gain)
4376{
4377 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
4378 u8 hph_l_en, hph_r_en;
4379 u8 l_val, r_val;
4380 u8 hph_pa_status;
4381 bool is_hphl_pa, is_hphr_pa;
4382
4383 hph_pa_status = snd_soc_read(codec, WCD9335_ANA_HPH);
4384 is_hphl_pa = hph_pa_status >> 7;
4385 is_hphr_pa = (hph_pa_status & 0x40) >> 6;
4386
4387 hph_l_en = snd_soc_read(codec, WCD9335_HPH_L_EN);
4388 hph_r_en = snd_soc_read(codec, WCD9335_HPH_R_EN);
4389
4390 l_val = (hph_l_en & 0xC0) | 0x20 | gain;
4391 r_val = (hph_r_en & 0xC0) | 0x20 | gain;
4392
4393 /*
4394 * Set HPH_L & HPH_R gain source selection to REGISTER
4395 * for better click and pop only if corresponding PAs are
4396 * not enabled. Also cache the values of the HPHL/R
4397 * PA gains to be applied after PAs are enabled
4398 */
4399 if ((l_val != hph_l_en) && !is_hphl_pa) {
4400 snd_soc_write(codec, WCD9335_HPH_L_EN, l_val);
4401 tasha->hph_l_gain = hph_l_en & 0x1F;
4402 }
4403
4404 if ((r_val != hph_r_en) && !is_hphr_pa) {
4405 snd_soc_write(codec, WCD9335_HPH_R_EN, r_val);
4406 tasha->hph_r_gain = hph_r_en & 0x1F;
4407 }
4408}
4409
4410static void tasha_codec_hph_lohifi_config(struct snd_soc_codec *codec,
4411 int event)
4412{
4413 if (SND_SOC_DAPM_EVENT_ON(event)) {
4414 snd_soc_update_bits(codec, WCD9335_RX_BIAS_HPH_PA, 0x0F, 0x06);
4415 snd_soc_update_bits(codec, WCD9335_RX_BIAS_HPH_RDACBUFF_CNP2,
4416 0xF0, 0x40);
4417 snd_soc_update_bits(codec, WCD9335_HPH_CNP_WG_CTL, 0x07, 0x03);
4418 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x08, 0x08);
4419 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL1, 0x0E, 0x0C);
4420 tasha_codec_hph_mode_gain_opt(codec, 0x11);
4421 }
4422
4423 if (SND_SOC_DAPM_EVENT_OFF(event)) {
4424 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x08, 0x00);
4425 snd_soc_update_bits(codec, WCD9335_HPH_CNP_WG_CTL, 0x07, 0x02);
4426 snd_soc_write(codec, WCD9335_RX_BIAS_HPH_RDACBUFF_CNP2, 0x8A);
4427 snd_soc_update_bits(codec, WCD9335_RX_BIAS_HPH_PA, 0x0F, 0x0A);
4428 }
4429}
4430
4431static void tasha_codec_hph_lp_config(struct snd_soc_codec *codec,
4432 int event)
4433{
4434 if (SND_SOC_DAPM_EVENT_ON(event)) {
4435 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL1, 0x0E, 0x0C);
4436 tasha_codec_hph_mode_gain_opt(codec, 0x10);
4437 snd_soc_update_bits(codec, WCD9335_HPH_CNP_WG_CTL, 0x07, 0x03);
4438 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x08, 0x08);
4439 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x04, 0x04);
4440 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x20, 0x20);
4441 snd_soc_update_bits(codec, WCD9335_HPH_RDAC_LDO_CTL, 0x07,
4442 0x01);
4443 snd_soc_update_bits(codec, WCD9335_HPH_RDAC_LDO_CTL, 0x70,
4444 0x10);
4445 snd_soc_update_bits(codec, WCD9335_RX_BIAS_HPH_RDAC_LDO,
4446 0x0F, 0x01);
4447 snd_soc_update_bits(codec, WCD9335_RX_BIAS_HPH_RDAC_LDO,
4448 0xF0, 0x10);
4449 }
4450
4451 if (SND_SOC_DAPM_EVENT_OFF(event)) {
4452 snd_soc_write(codec, WCD9335_RX_BIAS_HPH_RDAC_LDO, 0x88);
4453 snd_soc_write(codec, WCD9335_HPH_RDAC_LDO_CTL, 0x33);
4454 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x20, 0x00);
4455 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x04, 0x00);
4456 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x08, 0x00);
4457 snd_soc_update_bits(codec, WCD9335_HPH_CNP_WG_CTL, 0x07, 0x02);
4458 snd_soc_update_bits(codec, WCD9335_HPH_R_EN, 0xC0, 0x80);
4459 snd_soc_update_bits(codec, WCD9335_HPH_L_EN, 0xC0, 0x80);
4460 }
4461}
4462
4463static void tasha_codec_hph_hifi_config(struct snd_soc_codec *codec,
4464 int event)
4465{
4466 if (SND_SOC_DAPM_EVENT_ON(event)) {
4467 snd_soc_update_bits(codec, WCD9335_HPH_CNP_WG_CTL, 0x07, 0x03);
4468 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x08, 0x08);
4469 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL1, 0x0E, 0x0C);
4470 tasha_codec_hph_mode_gain_opt(codec, 0x11);
4471 }
4472
4473 if (SND_SOC_DAPM_EVENT_OFF(event)) {
4474 snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x08, 0x00);
4475 snd_soc_update_bits(codec, WCD9335_HPH_CNP_WG_CTL, 0x07, 0x02);
4476 }
4477}
4478
4479static void tasha_codec_hph_mode_config(struct snd_soc_codec *codec,
4480 int event, int mode)
4481{
4482 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
4483
4484 if (!TASHA_IS_2_0(tasha->wcd9xxx))
4485 return;
4486
4487 switch (mode) {
4488 case CLS_H_LP:
4489 tasha_codec_hph_lp_config(codec, event);
4490 break;
4491 case CLS_H_LOHIFI:
4492 tasha_codec_hph_lohifi_config(codec, event);
4493 break;
4494 case CLS_H_HIFI:
4495 tasha_codec_hph_hifi_config(codec, event);
4496 break;
4497 }
4498}
4499
4500static int tasha_codec_hphr_dac_event(struct snd_soc_dapm_widget *w,
4501 struct snd_kcontrol *kcontrol,
4502 int event)
4503{
4504 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
4505 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
4506 struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent);
4507 int hph_mode = tasha->hph_mode;
4508 u8 dem_inp;
4509 int ret = 0;
4510
4511 dev_dbg(codec->dev, "%s wname: %s event: %d hph_mode: %d\n", __func__,
4512 w->name, event, hph_mode);
4513
4514 switch (event) {
4515 case SND_SOC_DAPM_PRE_PMU:
4516 if (tasha->anc_func) {
4517 ret = tasha_codec_enable_anc(w, kcontrol, event);
4518 /* 40 msec delay is needed to avoid click and pop */
4519 msleep(40);
4520 }
4521
4522 /* Read DEM INP Select */
4523 dem_inp = snd_soc_read(codec, WCD9335_CDC_RX2_RX_PATH_SEC0) &
4524 0x03;
4525 if (((hph_mode == CLS_H_HIFI) || (hph_mode == CLS_H_LOHIFI) ||
4526 (hph_mode == CLS_H_LP)) && (dem_inp != 0x01)) {
4527 dev_err(codec->dev, "%s: DEM Input not set correctly, hph_mode: %d\n",
4528 __func__, hph_mode);
4529 return -EINVAL;
4530 }
4531 wcd_clsh_fsm(codec, &tasha->clsh_d,
4532 WCD_CLSH_EVENT_PRE_DAC,
4533 WCD_CLSH_STATE_HPHR,
4534 ((hph_mode == CLS_H_LOHIFI) ?
4535 CLS_H_HIFI : hph_mode));
4536
4537 tasha_codec_hph_mode_config(codec, event, hph_mode);
4538
4539 if (tasha->anc_func)
4540 snd_soc_update_bits(codec,
4541 WCD9335_CDC_RX2_RX_PATH_CFG0, 0x10, 0x10);
4542
4543 break;
4544 case SND_SOC_DAPM_POST_PMU:
4545 /* 1000us required as per HW requirement */
4546 usleep_range(1000, 1100);
4547 if ((hph_mode == CLS_H_LP) &&
4548 (TASHA_IS_1_1(wcd9xxx))) {
4549 snd_soc_update_bits(codec, WCD9335_HPH_L_DAC_CTL,
4550 0x03, 0x03);
4551 }
4552 break;
4553 case SND_SOC_DAPM_PRE_PMD:
4554 if ((hph_mode == CLS_H_LP) &&
4555 (TASHA_IS_1_1(wcd9xxx))) {
4556 snd_soc_update_bits(codec, WCD9335_HPH_L_DAC_CTL,
4557 0x03, 0x00);
4558 }
4559 break;
4560 case SND_SOC_DAPM_POST_PMD:
4561 /* 1000us required as per HW requirement */
4562 usleep_range(1000, 1100);
4563
4564 if (!(wcd_clsh_get_clsh_state(&tasha->clsh_d) &
4565 WCD_CLSH_STATE_HPHL))
4566 tasha_codec_hph_mode_config(codec, event, hph_mode);
4567
4568 wcd_clsh_fsm(codec, &tasha->clsh_d,
4569 WCD_CLSH_EVENT_POST_PA,
4570 WCD_CLSH_STATE_HPHR,
4571 ((hph_mode == CLS_H_LOHIFI) ?
4572 CLS_H_HIFI : hph_mode));
4573 break;
4574 };
4575
4576 return ret;
4577}
4578
4579static int tasha_codec_hphl_dac_event(struct snd_soc_dapm_widget *w,
4580 struct snd_kcontrol *kcontrol,
4581 int event)
4582{
4583 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
4584 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
4585 struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent);
4586 int hph_mode = tasha->hph_mode;
4587 u8 dem_inp;
4588 int ret = 0;
4589 uint32_t impedl = 0, impedr = 0;
4590
4591 dev_dbg(codec->dev, "%s wname: %s event: %d hph_mode: %d\n", __func__,
4592 w->name, event, hph_mode);
4593
4594 switch (event) {
4595 case SND_SOC_DAPM_PRE_PMU:
4596 if (tasha->anc_func) {
4597 ret = tasha_codec_enable_anc(w, kcontrol, event);
4598 /* 40 msec delay is needed to avoid click and pop */
4599 msleep(40);
4600 }
4601
4602 /* Read DEM INP Select */
4603 dem_inp = snd_soc_read(codec, WCD9335_CDC_RX1_RX_PATH_SEC0) &
4604 0x03;
4605 if (((hph_mode == CLS_H_HIFI) || (hph_mode == CLS_H_LOHIFI) ||
4606 (hph_mode == CLS_H_LP)) && (dem_inp != 0x01)) {
4607 dev_err(codec->dev, "%s: DEM Input not set correctly, hph_mode: %d\n",
4608 __func__, hph_mode);
4609 return -EINVAL;
4610 }
4611 wcd_clsh_fsm(codec, &tasha->clsh_d,
4612 WCD_CLSH_EVENT_PRE_DAC,
4613 WCD_CLSH_STATE_HPHL,
4614 ((hph_mode == CLS_H_LOHIFI) ?
4615 CLS_H_HIFI : hph_mode));
4616
4617 tasha_codec_hph_mode_config(codec, event, hph_mode);
4618
4619 if (tasha->anc_func)
4620 snd_soc_update_bits(codec,
4621 WCD9335_CDC_RX1_RX_PATH_CFG0, 0x10, 0x10);
4622
4623 ret = wcd_mbhc_get_impedance(&tasha->mbhc,
4624 &impedl, &impedr);
4625 if (!ret) {
4626 wcd_clsh_imped_config(codec, impedl, false);
4627 set_bit(CLASSH_CONFIG, &tasha->status_mask);
4628 } else {
4629 dev_dbg(codec->dev, "%s: Failed to get mbhc impedance %d\n",
4630 __func__, ret);
4631 ret = 0;
4632 }
4633
4634
4635 break;
4636 case SND_SOC_DAPM_POST_PMU:
4637 /* 1000us required as per HW requirement */
4638 usleep_range(1000, 1100);
4639 if ((hph_mode == CLS_H_LP) &&
4640 (TASHA_IS_1_1(wcd9xxx))) {
4641 snd_soc_update_bits(codec, WCD9335_HPH_L_DAC_CTL,
4642 0x03, 0x03);
4643 }
4644 break;
4645 case SND_SOC_DAPM_PRE_PMD:
4646 if ((hph_mode == CLS_H_LP) &&
4647 (TASHA_IS_1_1(wcd9xxx))) {
4648 snd_soc_update_bits(codec, WCD9335_HPH_L_DAC_CTL,
4649 0x03, 0x00);
4650 }
4651 break;
4652 case SND_SOC_DAPM_POST_PMD:
4653 /* 1000us required as per HW requirement */
4654 usleep_range(1000, 1100);
4655
4656 if (!(wcd_clsh_get_clsh_state(&tasha->clsh_d) &
4657 WCD_CLSH_STATE_HPHR))
4658 tasha_codec_hph_mode_config(codec, event, hph_mode);
4659 wcd_clsh_fsm(codec, &tasha->clsh_d,
4660 WCD_CLSH_EVENT_POST_PA,
4661 WCD_CLSH_STATE_HPHL,
4662 ((hph_mode == CLS_H_LOHIFI) ?
4663 CLS_H_HIFI : hph_mode));
4664
4665 if (test_bit(CLASSH_CONFIG, &tasha->status_mask)) {
4666 wcd_clsh_imped_config(codec, impedl, true);
4667 clear_bit(CLASSH_CONFIG, &tasha->status_mask);
4668 } else
4669 dev_dbg(codec->dev, "%s: Failed to get mbhc impedance %d\n",
4670 __func__, ret);
4671
4672
4673 break;
4674 };
4675
4676 return ret;
4677}
4678
4679static int tasha_codec_lineout_dac_event(struct snd_soc_dapm_widget *w,
4680 struct snd_kcontrol *kcontrol,
4681 int event)
4682{
4683 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
4684 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
4685 int ret = 0;
4686
4687 dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
4688
4689 switch (event) {
4690 case SND_SOC_DAPM_PRE_PMU:
4691 if (tasha->anc_func &&
4692 (!strcmp(w->name, "RX INT3 DAC") ||
4693 !strcmp(w->name, "RX INT4 DAC")))
4694 ret = tasha_codec_enable_anc(w, kcontrol, event);
4695
4696 wcd_clsh_fsm(codec, &tasha->clsh_d,
4697 WCD_CLSH_EVENT_PRE_DAC,
4698 WCD_CLSH_STATE_LO,
4699 CLS_AB);
4700
4701 if (tasha->anc_func) {
4702 if (!strcmp(w->name, "RX INT3 DAC"))
4703 snd_soc_update_bits(codec,
4704 WCD9335_CDC_RX3_RX_PATH_CFG0, 0x10, 0x10);
4705 else if (!strcmp(w->name, "RX INT4 DAC"))
4706 snd_soc_update_bits(codec,
4707 WCD9335_CDC_RX4_RX_PATH_CFG0, 0x10, 0x10);
4708 }
4709 break;
4710 case SND_SOC_DAPM_POST_PMD:
4711 wcd_clsh_fsm(codec, &tasha->clsh_d,
4712 WCD_CLSH_EVENT_POST_PA,
4713 WCD_CLSH_STATE_LO,
4714 CLS_AB);
4715 break;
4716 }
4717
4718 return 0;
4719}
4720
4721static const struct snd_soc_dapm_widget tasha_dapm_i2s_widgets[] = {
4722 SND_SOC_DAPM_SUPPLY("RX_I2S_CTL", WCD9335_DATA_HUB_DATA_HUB_RX_I2S_CTL,
4723 0, 0, NULL, 0),
4724 SND_SOC_DAPM_SUPPLY("TX_I2S_CTL", WCD9335_DATA_HUB_DATA_HUB_TX_I2S_CTL,
4725 0, 0, NULL, 0),
4726};
4727
4728static int tasha_codec_ear_dac_event(struct snd_soc_dapm_widget *w,
4729 struct snd_kcontrol *kcontrol,
4730 int event)
4731{
4732 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
4733 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
4734 int ret = 0;
4735
4736 dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
4737
4738 switch (event) {
4739 case SND_SOC_DAPM_PRE_PMU:
4740 if (tasha->anc_func)
4741 ret = tasha_codec_enable_anc(w, kcontrol, event);
4742
4743 wcd_clsh_fsm(codec, &tasha->clsh_d,
4744 WCD_CLSH_EVENT_PRE_DAC,
4745 WCD_CLSH_STATE_EAR,
4746 CLS_H_NORMAL);
4747 if (tasha->anc_func)
4748 snd_soc_update_bits(codec,
4749 WCD9335_CDC_RX0_RX_PATH_CFG0, 0x10, 0x10);
4750
4751 break;
4752 case SND_SOC_DAPM_POST_PMU:
4753 break;
4754 case SND_SOC_DAPM_PRE_PMD:
4755 break;
4756 case SND_SOC_DAPM_POST_PMD:
4757 wcd_clsh_fsm(codec, &tasha->clsh_d,
4758 WCD_CLSH_EVENT_POST_PA,
4759 WCD_CLSH_STATE_EAR,
4760 CLS_H_NORMAL);
4761 break;
4762 };
4763
4764 return ret;
4765}
4766
4767static int tasha_codec_spk_boost_event(struct snd_soc_dapm_widget *w,
4768 struct snd_kcontrol *kcontrol,
4769 int event)
4770{
4771 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
4772 u16 boost_path_ctl, boost_path_cfg1;
4773 u16 reg, reg_mix;
4774
4775 dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
4776
4777 if (!strcmp(w->name, "RX INT7 CHAIN")) {
4778 boost_path_ctl = WCD9335_CDC_BOOST0_BOOST_PATH_CTL;
4779 boost_path_cfg1 = WCD9335_CDC_RX7_RX_PATH_CFG1;
4780 reg = WCD9335_CDC_RX7_RX_PATH_CTL;
4781 reg_mix = WCD9335_CDC_RX7_RX_PATH_MIX_CTL;
4782 } else if (!strcmp(w->name, "RX INT8 CHAIN")) {
4783 boost_path_ctl = WCD9335_CDC_BOOST1_BOOST_PATH_CTL;
4784 boost_path_cfg1 = WCD9335_CDC_RX8_RX_PATH_CFG1;
4785 reg = WCD9335_CDC_RX8_RX_PATH_CTL;
4786 reg_mix = WCD9335_CDC_RX8_RX_PATH_MIX_CTL;
4787 } else {
4788 dev_err(codec->dev, "%s: unknown widget: %s\n",
4789 __func__, w->name);
4790 return -EINVAL;
4791 }
4792
4793 switch (event) {
4794 case SND_SOC_DAPM_PRE_PMU:
4795 snd_soc_update_bits(codec, boost_path_ctl, 0x10, 0x10);
4796 snd_soc_update_bits(codec, boost_path_cfg1, 0x01, 0x01);
4797 snd_soc_update_bits(codec, reg, 0x10, 0x00);
4798 if ((snd_soc_read(codec, reg_mix)) & 0x10)
4799 snd_soc_update_bits(codec, reg_mix, 0x10, 0x00);
4800 break;
4801 case SND_SOC_DAPM_POST_PMD:
4802 snd_soc_update_bits(codec, boost_path_cfg1, 0x01, 0x00);
4803 snd_soc_update_bits(codec, boost_path_ctl, 0x10, 0x00);
4804 break;
4805 };
4806
4807 return 0;
4808}
4809
4810static u16 tasha_interp_get_primary_reg(u16 reg, u16 *ind)
4811{
4812 u16 prim_int_reg = 0;
4813
4814 switch (reg) {
4815 case WCD9335_CDC_RX0_RX_PATH_CTL:
4816 case WCD9335_CDC_RX0_RX_PATH_MIX_CTL:
4817 prim_int_reg = WCD9335_CDC_RX0_RX_PATH_CTL;
4818 *ind = 0;
4819 break;
4820 case WCD9335_CDC_RX1_RX_PATH_CTL:
4821 case WCD9335_CDC_RX1_RX_PATH_MIX_CTL:
4822 prim_int_reg = WCD9335_CDC_RX1_RX_PATH_CTL;
4823 *ind = 1;
4824 break;
4825 case WCD9335_CDC_RX2_RX_PATH_CTL:
4826 case WCD9335_CDC_RX2_RX_PATH_MIX_CTL:
4827 prim_int_reg = WCD9335_CDC_RX2_RX_PATH_CTL;
4828 *ind = 2;
4829 break;
4830 case WCD9335_CDC_RX3_RX_PATH_CTL:
4831 case WCD9335_CDC_RX3_RX_PATH_MIX_CTL:
4832 prim_int_reg = WCD9335_CDC_RX3_RX_PATH_CTL;
4833 *ind = 3;
4834 break;
4835 case WCD9335_CDC_RX4_RX_PATH_CTL:
4836 case WCD9335_CDC_RX4_RX_PATH_MIX_CTL:
4837 prim_int_reg = WCD9335_CDC_RX4_RX_PATH_CTL;
4838 *ind = 4;
4839 break;
4840 case WCD9335_CDC_RX5_RX_PATH_CTL:
4841 case WCD9335_CDC_RX5_RX_PATH_MIX_CTL:
4842 prim_int_reg = WCD9335_CDC_RX5_RX_PATH_CTL;
4843 *ind = 5;
4844 break;
4845 case WCD9335_CDC_RX6_RX_PATH_CTL:
4846 case WCD9335_CDC_RX6_RX_PATH_MIX_CTL:
4847 prim_int_reg = WCD9335_CDC_RX6_RX_PATH_CTL;
4848 *ind = 6;
4849 break;
4850 case WCD9335_CDC_RX7_RX_PATH_CTL:
4851 case WCD9335_CDC_RX7_RX_PATH_MIX_CTL:
4852 prim_int_reg = WCD9335_CDC_RX7_RX_PATH_CTL;
4853 *ind = 7;
4854 break;
4855 case WCD9335_CDC_RX8_RX_PATH_CTL:
4856 case WCD9335_CDC_RX8_RX_PATH_MIX_CTL:
4857 prim_int_reg = WCD9335_CDC_RX8_RX_PATH_CTL;
4858 *ind = 8;
4859 break;
4860 };
4861
4862 return prim_int_reg;
4863}
4864
4865static void tasha_codec_hd2_control(struct snd_soc_codec *codec,
4866 u16 prim_int_reg, int event)
4867{
4868 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
4869 u16 hd2_scale_reg;
4870 u16 hd2_enable_reg = 0;
4871
4872 if (!TASHA_IS_2_0(tasha->wcd9xxx))
4873 return;
4874
4875 if (prim_int_reg == WCD9335_CDC_RX1_RX_PATH_CTL) {
4876 hd2_scale_reg = WCD9335_CDC_RX1_RX_PATH_SEC3;
4877 hd2_enable_reg = WCD9335_CDC_RX1_RX_PATH_CFG0;
4878 }
4879 if (prim_int_reg == WCD9335_CDC_RX2_RX_PATH_CTL) {
4880 hd2_scale_reg = WCD9335_CDC_RX2_RX_PATH_SEC3;
4881 hd2_enable_reg = WCD9335_CDC_RX2_RX_PATH_CFG0;
4882 }
4883
4884 if (hd2_enable_reg && SND_SOC_DAPM_EVENT_ON(event)) {
4885 snd_soc_update_bits(codec, hd2_scale_reg, 0x3C, 0x10);
4886 snd_soc_update_bits(codec, hd2_scale_reg, 0x03, 0x01);
4887 snd_soc_update_bits(codec, hd2_enable_reg, 0x04, 0x04);
4888 }
4889
4890 if (hd2_enable_reg && SND_SOC_DAPM_EVENT_OFF(event)) {
4891 snd_soc_update_bits(codec, hd2_enable_reg, 0x04, 0x00);
4892 snd_soc_update_bits(codec, hd2_scale_reg, 0x03, 0x00);
4893 snd_soc_update_bits(codec, hd2_scale_reg, 0x3C, 0x00);
4894 }
4895}
4896
4897static int tasha_codec_enable_prim_interpolator(
4898 struct snd_soc_codec *codec,
4899 u16 reg, int event)
4900{
4901 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
4902 u16 prim_int_reg;
4903 u16 ind = 0;
4904
4905 prim_int_reg = tasha_interp_get_primary_reg(reg, &ind);
4906
4907 switch (event) {
4908 case SND_SOC_DAPM_PRE_PMU:
4909 tasha->prim_int_users[ind]++;
4910 if (tasha->prim_int_users[ind] == 1) {
4911 snd_soc_update_bits(codec, prim_int_reg,
4912 0x10, 0x10);
4913 tasha_codec_hd2_control(codec, prim_int_reg, event);
4914 snd_soc_update_bits(codec, prim_int_reg,
4915 1 << 0x5, 1 << 0x5);
4916 }
4917 if ((reg != prim_int_reg) &&
4918 ((snd_soc_read(codec, prim_int_reg)) & 0x10))
4919 snd_soc_update_bits(codec, reg, 0x10, 0x10);
4920 break;
4921 case SND_SOC_DAPM_POST_PMD:
4922 tasha->prim_int_users[ind]--;
4923 if (tasha->prim_int_users[ind] == 0) {
4924 snd_soc_update_bits(codec, prim_int_reg,
4925 1 << 0x5, 0 << 0x5);
4926 snd_soc_update_bits(codec, prim_int_reg,
4927 0x40, 0x40);
4928 snd_soc_update_bits(codec, prim_int_reg,
4929 0x40, 0x00);
4930 tasha_codec_hd2_control(codec, prim_int_reg, event);
4931 }
4932 break;
4933 };
4934
4935 dev_dbg(codec->dev, "%s: primary interpolator: INT%d, users: %d\n",
4936 __func__, ind, tasha->prim_int_users[ind]);
4937 return 0;
4938}
4939
4940static int tasha_codec_enable_spline_src(struct snd_soc_codec *codec,
4941 int src_num,
4942 int event)
4943{
4944 u16 src_paired_reg;
4945 struct tasha_priv *tasha;
4946 u16 rx_path_cfg_reg = WCD9335_CDC_RX1_RX_PATH_CFG0;
4947 u16 rx_path_ctl_reg = WCD9335_CDC_RX1_RX_PATH_CTL;
4948 int *src_users, count, spl_src = SPLINE_SRC0;
4949 u16 src_clk_reg = WCD9335_SPLINE_SRC0_CLK_RST_CTL_0;
4950
4951 tasha = snd_soc_codec_get_drvdata(codec);
4952
4953 switch (src_num) {
4954 case SRC_IN_HPHL:
4955 rx_path_cfg_reg = WCD9335_CDC_RX1_RX_PATH_CFG0;
4956 src_clk_reg = WCD9335_SPLINE_SRC0_CLK_RST_CTL_0;
4957 src_paired_reg = WCD9335_SPLINE_SRC1_CLK_RST_CTL_0;
4958 rx_path_ctl_reg = WCD9335_CDC_RX1_RX_PATH_CTL;
4959 spl_src = SPLINE_SRC0;
4960 break;
4961 case SRC_IN_LO1:
4962 rx_path_cfg_reg = WCD9335_CDC_RX3_RX_PATH_CFG0;
4963 src_clk_reg = WCD9335_SPLINE_SRC0_CLK_RST_CTL_0;
4964 src_paired_reg = WCD9335_SPLINE_SRC1_CLK_RST_CTL_0;
4965 rx_path_ctl_reg = WCD9335_CDC_RX3_RX_PATH_CTL;
4966 spl_src = SPLINE_SRC0;
4967 break;
4968 case SRC_IN_HPHR:
4969 rx_path_cfg_reg = WCD9335_CDC_RX2_RX_PATH_CFG0;
4970 src_clk_reg = WCD9335_SPLINE_SRC1_CLK_RST_CTL_0;
4971 src_paired_reg = WCD9335_SPLINE_SRC0_CLK_RST_CTL_0;
4972 rx_path_ctl_reg = WCD9335_CDC_RX2_RX_PATH_CTL;
4973 spl_src = SPLINE_SRC1;
4974 break;
4975 case SRC_IN_LO2:
4976 rx_path_cfg_reg = WCD9335_CDC_RX4_RX_PATH_CFG0;
4977 src_clk_reg = WCD9335_SPLINE_SRC1_CLK_RST_CTL_0;
4978 src_paired_reg = WCD9335_SPLINE_SRC0_CLK_RST_CTL_0;
4979 rx_path_ctl_reg = WCD9335_CDC_RX4_RX_PATH_CTL;
4980 spl_src = SPLINE_SRC1;
4981 break;
4982 case SRC_IN_SPKRL:
4983 rx_path_cfg_reg = WCD9335_CDC_RX7_RX_PATH_CFG0;
4984 src_clk_reg = WCD9335_SPLINE_SRC2_CLK_RST_CTL_0;
4985 src_paired_reg = WCD9335_SPLINE_SRC3_CLK_RST_CTL_0;
4986 rx_path_ctl_reg = WCD9335_CDC_RX7_RX_PATH_CTL;
4987 spl_src = SPLINE_SRC2;
4988 break;
4989 case SRC_IN_LO3:
4990 rx_path_cfg_reg = WCD9335_CDC_RX5_RX_PATH_CFG0;
4991 src_clk_reg = WCD9335_SPLINE_SRC2_CLK_RST_CTL_0;
4992 src_paired_reg = WCD9335_SPLINE_SRC3_CLK_RST_CTL_0;
4993 rx_path_ctl_reg = WCD9335_CDC_RX5_RX_PATH_CTL;
4994 spl_src = SPLINE_SRC2;
4995 break;
4996 case SRC_IN_SPKRR:
4997 rx_path_cfg_reg = WCD9335_CDC_RX8_RX_PATH_CFG0;
4998 src_clk_reg = WCD9335_SPLINE_SRC3_CLK_RST_CTL_0;
4999 src_paired_reg = WCD9335_SPLINE_SRC2_CLK_RST_CTL_0;
5000 rx_path_ctl_reg = WCD9335_CDC_RX8_RX_PATH_CTL;
5001 spl_src = SPLINE_SRC3;
5002 break;
5003 case SRC_IN_LO4:
5004 rx_path_cfg_reg = WCD9335_CDC_RX6_RX_PATH_CFG0;
5005 src_clk_reg = WCD9335_SPLINE_SRC3_CLK_RST_CTL_0;
5006 src_paired_reg = WCD9335_SPLINE_SRC2_CLK_RST_CTL_0;
5007 rx_path_ctl_reg = WCD9335_CDC_RX6_RX_PATH_CTL;
5008 spl_src = SPLINE_SRC3;
5009 break;
5010 };
5011
5012 src_users = &tasha->spl_src_users[spl_src];
5013
5014 switch (event) {
5015 case SND_SOC_DAPM_PRE_PMU:
5016 count = *src_users;
5017 count++;
5018 if (count == 1) {
5019 if ((snd_soc_read(codec, src_clk_reg) & 0x02) ||
5020 (snd_soc_read(codec, src_paired_reg) & 0x02)) {
5021 snd_soc_update_bits(codec, src_clk_reg, 0x02,
5022 0x00);
5023 snd_soc_update_bits(codec, src_paired_reg,
5024 0x02, 0x00);
5025 }
5026 snd_soc_update_bits(codec, src_clk_reg, 0x01, 0x01);
5027 snd_soc_update_bits(codec, rx_path_cfg_reg, 0x80,
5028 0x80);
5029 }
5030 *src_users = count;
5031 break;
5032 case SND_SOC_DAPM_POST_PMD:
5033 count = *src_users;
5034 count--;
5035 if (count == 0) {
5036 snd_soc_update_bits(codec, rx_path_cfg_reg, 0x80,
5037 0x00);
5038 snd_soc_update_bits(codec, src_clk_reg, 0x03, 0x02);
5039 /* default sample rate */
5040 snd_soc_update_bits(codec, rx_path_ctl_reg, 0x0f,
5041 0x04);
5042 }
5043 *src_users = count;
5044 break;
5045 };
5046
5047 dev_dbg(codec->dev, "%s: Spline SRC%d, users: %d\n",
5048 __func__, spl_src, *src_users);
5049 return 0;
5050}
5051
5052static int tasha_codec_enable_spline_resampler(struct snd_soc_dapm_widget *w,
5053 struct snd_kcontrol *kcontrol,
5054 int event)
5055{
5056 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
5057 int ret = 0;
5058 u8 src_in;
5059
5060 src_in = snd_soc_read(codec, WCD9335_CDC_RX_INP_MUX_SPLINE_SRC_CFG0);
5061 if (!(src_in & 0xFF)) {
5062 dev_err(codec->dev, "%s: Spline SRC%u input not selected\n",
5063 __func__, w->shift);
5064 return -EINVAL;
5065 }
5066
5067 switch (w->shift) {
5068 case SPLINE_SRC0:
5069 ret = tasha_codec_enable_spline_src(codec,
5070 ((src_in & 0x03) == 1) ? SRC_IN_HPHL : SRC_IN_LO1,
5071 event);
5072 break;
5073 case SPLINE_SRC1:
5074 ret = tasha_codec_enable_spline_src(codec,
5075 ((src_in & 0x0C) == 4) ? SRC_IN_HPHR : SRC_IN_LO2,
5076 event);
5077 break;
5078 case SPLINE_SRC2:
5079 ret = tasha_codec_enable_spline_src(codec,
5080 ((src_in & 0x30) == 0x10) ? SRC_IN_LO3 : SRC_IN_SPKRL,
5081 event);
5082 break;
5083 case SPLINE_SRC3:
5084 ret = tasha_codec_enable_spline_src(codec,
5085 ((src_in & 0xC0) == 0x40) ? SRC_IN_LO4 : SRC_IN_SPKRR,
5086 event);
5087 break;
5088 default:
5089 dev_err(codec->dev, "%s: Invalid spline src:%u\n", __func__,
5090 w->shift);
5091 ret = -EINVAL;
5092 };
5093
5094 return ret;
5095}
5096
5097static int tasha_codec_enable_swr(struct snd_soc_dapm_widget *w,
5098 struct snd_kcontrol *kcontrol, int event)
5099{
5100 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
5101 struct tasha_priv *tasha;
5102 int i, ch_cnt;
5103
5104 tasha = snd_soc_codec_get_drvdata(codec);
5105
5106 if (!tasha->nr)
5107 return 0;
5108
5109 switch (event) {
5110 case SND_SOC_DAPM_PRE_PMU:
5111 if ((strnstr(w->name, "INT7_", sizeof("RX INT7_"))) &&
5112 !tasha->rx_7_count)
5113 tasha->rx_7_count++;
5114 if ((strnstr(w->name, "INT8_", sizeof("RX INT8_"))) &&
5115 !tasha->rx_8_count)
5116 tasha->rx_8_count++;
5117 ch_cnt = tasha->rx_7_count + tasha->rx_8_count;
5118
5119 for (i = 0; i < tasha->nr; i++) {
5120 swrm_wcd_notify(tasha->swr_ctrl_data[i].swr_pdev,
5121 SWR_DEVICE_UP, NULL);
5122 swrm_wcd_notify(tasha->swr_ctrl_data[i].swr_pdev,
5123 SWR_SET_NUM_RX_CH, &ch_cnt);
5124 }
5125 break;
5126 case SND_SOC_DAPM_POST_PMD:
5127 if ((strnstr(w->name, "INT7_", sizeof("RX INT7_"))) &&
5128 tasha->rx_7_count)
5129 tasha->rx_7_count--;
5130 if ((strnstr(w->name, "INT8_", sizeof("RX INT8_"))) &&
5131 tasha->rx_8_count)
5132 tasha->rx_8_count--;
5133 ch_cnt = tasha->rx_7_count + tasha->rx_8_count;
5134
5135 for (i = 0; i < tasha->nr; i++)
5136 swrm_wcd_notify(tasha->swr_ctrl_data[i].swr_pdev,
5137 SWR_SET_NUM_RX_CH, &ch_cnt);
5138
5139 break;
5140 }
5141 dev_dbg(tasha->dev, "%s: current swr ch cnt: %d\n",
5142 __func__, tasha->rx_7_count + tasha->rx_8_count);
5143
5144 return 0;
5145}
5146
5147static int tasha_codec_config_ear_spkr_gain(struct snd_soc_codec *codec,
5148 int event, int gain_reg)
5149{
5150 int comp_gain_offset, val;
5151 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
5152
5153 switch (tasha->spkr_mode) {
5154 /* Compander gain in SPKR_MODE1 case is 12 dB */
5155 case SPKR_MODE_1:
5156 comp_gain_offset = -12;
5157 break;
5158 /* Default case compander gain is 15 dB */
5159 default:
5160 comp_gain_offset = -15;
5161 break;
5162 }
5163
5164 switch (event) {
5165 case SND_SOC_DAPM_POST_PMU:
5166 /* Apply ear spkr gain only if compander is enabled */
5167 if (tasha->comp_enabled[COMPANDER_7] &&
5168 (gain_reg == WCD9335_CDC_RX7_RX_VOL_CTL ||
5169 gain_reg == WCD9335_CDC_RX7_RX_VOL_MIX_CTL) &&
5170 (tasha->ear_spkr_gain != 0)) {
5171 /* For example, val is -8(-12+5-1) for 4dB of gain */
5172 val = comp_gain_offset + tasha->ear_spkr_gain - 1;
5173 snd_soc_write(codec, gain_reg, val);
5174
5175 dev_dbg(codec->dev, "%s: RX7 Volume %d dB\n",
5176 __func__, val);
5177 }
5178 break;
5179 case SND_SOC_DAPM_POST_PMD:
5180 /*
5181 * Reset RX7 volume to 0 dB if compander is enabled and
5182 * ear_spkr_gain is non-zero.
5183 */
5184 if (tasha->comp_enabled[COMPANDER_7] &&
5185 (gain_reg == WCD9335_CDC_RX7_RX_VOL_CTL ||
5186 gain_reg == WCD9335_CDC_RX7_RX_VOL_MIX_CTL) &&
5187 (tasha->ear_spkr_gain != 0)) {
5188 snd_soc_write(codec, gain_reg, 0x0);
5189
5190 dev_dbg(codec->dev, "%s: Reset RX7 Volume to 0 dB\n",
5191 __func__);
5192 }
5193 break;
5194 }
5195
5196 return 0;
5197}
5198
5199static int tasha_codec_enable_mix_path(struct snd_soc_dapm_widget *w,
5200 struct snd_kcontrol *kcontrol, int event)
5201{
5202 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
5203 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
5204 u16 gain_reg;
5205 int offset_val = 0;
5206 int val = 0;
5207
5208 dev_dbg(codec->dev, "%s %d %s\n", __func__, event, w->name);
5209
5210 switch (w->reg) {
5211 case WCD9335_CDC_RX0_RX_PATH_MIX_CTL:
5212 gain_reg = WCD9335_CDC_RX0_RX_VOL_MIX_CTL;
5213 break;
5214 case WCD9335_CDC_RX1_RX_PATH_MIX_CTL:
5215 gain_reg = WCD9335_CDC_RX1_RX_VOL_MIX_CTL;
5216 break;
5217 case WCD9335_CDC_RX2_RX_PATH_MIX_CTL:
5218 gain_reg = WCD9335_CDC_RX2_RX_VOL_MIX_CTL;
5219 break;
5220 case WCD9335_CDC_RX3_RX_PATH_MIX_CTL:
5221 gain_reg = WCD9335_CDC_RX3_RX_VOL_MIX_CTL;
5222 break;
5223 case WCD9335_CDC_RX4_RX_PATH_MIX_CTL:
5224 gain_reg = WCD9335_CDC_RX4_RX_VOL_MIX_CTL;
5225 break;
5226 case WCD9335_CDC_RX5_RX_PATH_MIX_CTL:
5227 gain_reg = WCD9335_CDC_RX5_RX_VOL_MIX_CTL;
5228 break;
5229 case WCD9335_CDC_RX6_RX_PATH_MIX_CTL:
5230 gain_reg = WCD9335_CDC_RX6_RX_VOL_MIX_CTL;
5231 break;
5232 case WCD9335_CDC_RX7_RX_PATH_MIX_CTL:
5233 gain_reg = WCD9335_CDC_RX7_RX_VOL_MIX_CTL;
5234 break;
5235 case WCD9335_CDC_RX8_RX_PATH_MIX_CTL:
5236 gain_reg = WCD9335_CDC_RX8_RX_VOL_MIX_CTL;
5237 break;
5238 default:
5239 dev_err(codec->dev, "%s: No gain register avail for %s\n",
5240 __func__, w->name);
5241 return 0;
5242 };
5243
5244 switch (event) {
5245 case SND_SOC_DAPM_POST_PMU:
5246 if ((tasha->spkr_gain_offset == RX_GAIN_OFFSET_M1P5_DB) &&
5247 (tasha->comp_enabled[COMPANDER_7] ||
5248 tasha->comp_enabled[COMPANDER_8]) &&
5249 (gain_reg == WCD9335_CDC_RX7_RX_VOL_MIX_CTL ||
5250 gain_reg == WCD9335_CDC_RX8_RX_VOL_MIX_CTL)) {
5251 snd_soc_update_bits(codec, WCD9335_CDC_RX7_RX_PATH_SEC1,
5252 0x01, 0x01);
5253 snd_soc_update_bits(codec,
5254 WCD9335_CDC_RX7_RX_PATH_MIX_SEC0,
5255 0x01, 0x01);
5256 snd_soc_update_bits(codec, WCD9335_CDC_RX8_RX_PATH_SEC1,
5257 0x01, 0x01);
5258 snd_soc_update_bits(codec,
5259 WCD9335_CDC_RX8_RX_PATH_MIX_SEC0,
5260 0x01, 0x01);
5261 offset_val = -2;
5262 }
5263 val = snd_soc_read(codec, gain_reg);
5264 val += offset_val;
5265 snd_soc_write(codec, gain_reg, val);
5266 tasha_codec_config_ear_spkr_gain(codec, event, gain_reg);
5267 break;
5268 case SND_SOC_DAPM_POST_PMD:
5269 if ((tasha->spkr_gain_offset == RX_GAIN_OFFSET_M1P5_DB) &&
5270 (tasha->comp_enabled[COMPANDER_7] ||
5271 tasha->comp_enabled[COMPANDER_8]) &&
5272 (gain_reg == WCD9335_CDC_RX7_RX_VOL_MIX_CTL ||
5273 gain_reg == WCD9335_CDC_RX8_RX_VOL_MIX_CTL)) {
5274 snd_soc_update_bits(codec, WCD9335_CDC_RX7_RX_PATH_SEC1,
5275 0x01, 0x00);
5276 snd_soc_update_bits(codec,
5277 WCD9335_CDC_RX7_RX_PATH_MIX_SEC0,
5278 0x01, 0x00);
5279 snd_soc_update_bits(codec, WCD9335_CDC_RX8_RX_PATH_SEC1,
5280 0x01, 0x00);
5281 snd_soc_update_bits(codec,
5282 WCD9335_CDC_RX8_RX_PATH_MIX_SEC0,
5283 0x01, 0x00);
5284 offset_val = 2;
5285 val = snd_soc_read(codec, gain_reg);
5286 val += offset_val;
5287 snd_soc_write(codec, gain_reg, val);
5288 }
5289 tasha_codec_config_ear_spkr_gain(codec, event, gain_reg);
5290 break;
5291 };
5292
5293 return 0;
5294}
5295
5296static int __tasha_cdc_native_clk_enable(struct tasha_priv *tasha,
5297 bool enable)
5298{
5299 int ret = 0;
5300 struct snd_soc_codec *codec = tasha->codec;
5301
5302 if (!tasha->wcd_native_clk) {
5303 dev_err(tasha->dev, "%s: wcd native clock is NULL\n", __func__);
5304 return -EINVAL;
5305 }
5306
5307 dev_dbg(tasha->dev, "%s: native_clk_enable = %u\n", __func__, enable);
5308
5309 if (enable) {
5310 ret = clk_prepare_enable(tasha->wcd_native_clk);
5311 if (ret) {
5312 dev_err(tasha->dev, "%s: native clk enable failed\n",
5313 __func__);
5314 goto err;
5315 }
5316 if (++tasha->native_clk_users == 1) {
5317 snd_soc_update_bits(codec, WCD9335_CLOCK_TEST_CTL,
5318 0x10, 0x10);
5319 snd_soc_update_bits(codec, WCD9335_CLOCK_TEST_CTL,
5320 0x80, 0x80);
5321 snd_soc_update_bits(codec, WCD9335_CODEC_RPM_CLK_GATE,
5322 0x04, 0x00);
5323 snd_soc_update_bits(codec,
5324 WCD9335_CDC_CLK_RST_CTRL_MCLK_CONTROL,
5325 0x02, 0x02);
5326 }
5327 } else {
5328 if (tasha->native_clk_users &&
5329 (--tasha->native_clk_users == 0)) {
5330 snd_soc_update_bits(codec,
5331 WCD9335_CDC_CLK_RST_CTRL_MCLK_CONTROL,
5332 0x02, 0x00);
5333 snd_soc_update_bits(codec, WCD9335_CODEC_RPM_CLK_GATE,
5334 0x04, 0x04);
5335 snd_soc_update_bits(codec, WCD9335_CLOCK_TEST_CTL,
5336 0x80, 0x00);
5337 snd_soc_update_bits(codec, WCD9335_CLOCK_TEST_CTL,
5338 0x10, 0x00);
5339 }
5340 clk_disable_unprepare(tasha->wcd_native_clk);
5341 }
5342
5343 dev_dbg(codec->dev, "%s: native_clk_users: %d\n", __func__,
5344 tasha->native_clk_users);
5345err:
5346 return ret;
5347}
5348
5349static int tasha_codec_get_native_fifo_sync_mask(struct snd_soc_codec *codec,
5350 int interp_n)
5351{
5352 int mask = 0;
5353 u16 reg;
5354 u8 val1, val2, inp0 = 0;
5355 u8 inp1 = 0, inp2 = 0;
5356
5357 reg = WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG0 + (2 * interp_n) - 2;
5358
5359 val1 = snd_soc_read(codec, reg);
5360 val2 = snd_soc_read(codec, reg + 1);
5361
5362 inp0 = val1 & 0x0F;
5363 inp1 = (val1 >> 4) & 0x0F;
5364 inp2 = (val2 >> 4) & 0x0F;
5365
5366 if (IS_VALID_NATIVE_FIFO_PORT(inp0))
5367 mask |= (1 << (inp0 - 5));
5368 if (IS_VALID_NATIVE_FIFO_PORT(inp1))
5369 mask |= (1 << (inp1 - 5));
5370 if (IS_VALID_NATIVE_FIFO_PORT(inp2))
5371 mask |= (1 << (inp2 - 5));
5372
5373 dev_dbg(codec->dev, "%s: native fifo mask: 0x%x\n", __func__, mask);
5374 if (!mask)
5375 dev_err(codec->dev, "native fifo err,int:%d,inp0:%d,inp1:%d,inp2:%d\n",
5376 interp_n, inp0, inp1, inp2);
5377 return mask;
5378}
5379
5380static int tasha_enable_native_supply(struct snd_soc_dapm_widget *w,
5381 struct snd_kcontrol *kcontrol, int event)
5382{
5383 int mask;
5384 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
5385 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
5386 u16 interp_reg;
5387
5388 dev_dbg(codec->dev, "%s: event: %d, shift:%d\n", __func__, event,
5389 w->shift);
5390
5391 if (w->shift < INTERP_HPHL || w->shift > INTERP_LO2)
5392 return -EINVAL;
5393
5394 interp_reg = WCD9335_CDC_RX1_RX_PATH_CTL + 20 * (w->shift - 1);
5395
5396 mask = tasha_codec_get_native_fifo_sync_mask(codec, w->shift);
5397 if (!mask)
5398 return -EINVAL;
5399
5400 switch (event) {
5401 case SND_SOC_DAPM_PRE_PMU:
5402 /* Adjust interpolator rate to 44P1_NATIVE */
5403 snd_soc_update_bits(codec, interp_reg, 0x0F, 0x09);
5404 __tasha_cdc_native_clk_enable(tasha, true);
5405 snd_soc_update_bits(codec, WCD9335_DATA_HUB_NATIVE_FIFO_SYNC,
5406 mask, mask);
5407 break;
5408 case SND_SOC_DAPM_PRE_PMD:
5409 snd_soc_update_bits(codec, WCD9335_DATA_HUB_NATIVE_FIFO_SYNC,
5410 mask, 0x0);
5411 __tasha_cdc_native_clk_enable(tasha, false);
5412 /* Adjust interpolator rate to default */
5413 snd_soc_update_bits(codec, interp_reg, 0x0F, 0x04);
5414 break;
5415 }
5416
5417 return 0;
5418}
5419
5420static int tasha_codec_enable_interpolator(struct snd_soc_dapm_widget *w,
5421 struct snd_kcontrol *kcontrol, int event)
5422{
5423 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
5424 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
5425 u16 gain_reg;
5426 u16 reg;
5427 int val;
5428 int offset_val = 0;
5429
5430 dev_dbg(codec->dev, "%s %d %s\n", __func__, event, w->name);
5431
5432 if (!(strcmp(w->name, "RX INT0 INTERP"))) {
5433 reg = WCD9335_CDC_RX0_RX_PATH_CTL;
5434 gain_reg = WCD9335_CDC_RX0_RX_VOL_CTL;
5435 } else if (!(strcmp(w->name, "RX INT1 INTERP"))) {
5436 reg = WCD9335_CDC_RX1_RX_PATH_CTL;
5437 gain_reg = WCD9335_CDC_RX1_RX_VOL_CTL;
5438 } else if (!(strcmp(w->name, "RX INT2 INTERP"))) {
5439 reg = WCD9335_CDC_RX2_RX_PATH_CTL;
5440 gain_reg = WCD9335_CDC_RX2_RX_VOL_CTL;
5441 } else if (!(strcmp(w->name, "RX INT3 INTERP"))) {
5442 reg = WCD9335_CDC_RX3_RX_PATH_CTL;
5443 gain_reg = WCD9335_CDC_RX3_RX_VOL_CTL;
5444 } else if (!(strcmp(w->name, "RX INT4 INTERP"))) {
5445 reg = WCD9335_CDC_RX4_RX_PATH_CTL;
5446 gain_reg = WCD9335_CDC_RX4_RX_VOL_CTL;
5447 } else if (!(strcmp(w->name, "RX INT5 INTERP"))) {
5448 reg = WCD9335_CDC_RX5_RX_PATH_CTL;
5449 gain_reg = WCD9335_CDC_RX5_RX_VOL_CTL;
5450 } else if (!(strcmp(w->name, "RX INT6 INTERP"))) {
5451 reg = WCD9335_CDC_RX6_RX_PATH_CTL;
5452 gain_reg = WCD9335_CDC_RX6_RX_VOL_CTL;
5453 } else if (!(strcmp(w->name, "RX INT7 INTERP"))) {
5454 reg = WCD9335_CDC_RX7_RX_PATH_CTL;
5455 gain_reg = WCD9335_CDC_RX7_RX_VOL_CTL;
5456 } else if (!(strcmp(w->name, "RX INT8 INTERP"))) {
5457 reg = WCD9335_CDC_RX8_RX_PATH_CTL;
5458 gain_reg = WCD9335_CDC_RX8_RX_VOL_CTL;
5459 } else {
5460 dev_err(codec->dev, "%s: Interpolator reg not found\n",
5461 __func__);
5462 return -EINVAL;
5463 }
5464
5465 switch (event) {
5466 case SND_SOC_DAPM_PRE_PMU:
5467 if (!test_bit(SB_CLK_GEAR, &tasha->status_mask)) {
5468 tasha_codec_vote_max_bw(codec, true);
5469 set_bit(SB_CLK_GEAR, &tasha->status_mask);
5470 }
5471 /* Reset if needed */
5472 tasha_codec_enable_prim_interpolator(codec, reg, event);
5473 break;
5474 case SND_SOC_DAPM_POST_PMU:
5475 tasha_config_compander(codec, w->shift, event);
5476 /* apply gain after int clk is enabled */
5477 if ((tasha->spkr_gain_offset == RX_GAIN_OFFSET_M1P5_DB) &&
5478 (tasha->comp_enabled[COMPANDER_7] ||
5479 tasha->comp_enabled[COMPANDER_8]) &&
5480 (gain_reg == WCD9335_CDC_RX7_RX_VOL_CTL ||
5481 gain_reg == WCD9335_CDC_RX8_RX_VOL_CTL)) {
5482 snd_soc_update_bits(codec, WCD9335_CDC_RX7_RX_PATH_SEC1,
5483 0x01, 0x01);
5484 snd_soc_update_bits(codec,
5485 WCD9335_CDC_RX7_RX_PATH_MIX_SEC0,
5486 0x01, 0x01);
5487 snd_soc_update_bits(codec, WCD9335_CDC_RX8_RX_PATH_SEC1,
5488 0x01, 0x01);
5489 snd_soc_update_bits(codec,
5490 WCD9335_CDC_RX8_RX_PATH_MIX_SEC0,
5491 0x01, 0x01);
5492 offset_val = -2;
5493 }
5494 val = snd_soc_read(codec, gain_reg);
5495 val += offset_val;
5496 snd_soc_write(codec, gain_reg, val);
5497 tasha_codec_config_ear_spkr_gain(codec, event, gain_reg);
5498 break;
5499 case SND_SOC_DAPM_POST_PMD:
5500 tasha_config_compander(codec, w->shift, event);
5501 tasha_codec_enable_prim_interpolator(codec, reg, event);
5502 if ((tasha->spkr_gain_offset == RX_GAIN_OFFSET_M1P5_DB) &&
5503 (tasha->comp_enabled[COMPANDER_7] ||
5504 tasha->comp_enabled[COMPANDER_8]) &&
5505 (gain_reg == WCD9335_CDC_RX7_RX_VOL_CTL ||
5506 gain_reg == WCD9335_CDC_RX8_RX_VOL_CTL)) {
5507 snd_soc_update_bits(codec, WCD9335_CDC_RX7_RX_PATH_SEC1,
5508 0x01, 0x00);
5509 snd_soc_update_bits(codec,
5510 WCD9335_CDC_RX7_RX_PATH_MIX_SEC0,
5511 0x01, 0x00);
5512 snd_soc_update_bits(codec, WCD9335_CDC_RX8_RX_PATH_SEC1,
5513 0x01, 0x00);
5514 snd_soc_update_bits(codec,
5515 WCD9335_CDC_RX8_RX_PATH_MIX_SEC0,
5516 0x01, 0x00);
5517 offset_val = 2;
5518 val = snd_soc_read(codec, gain_reg);
5519 val += offset_val;
5520 snd_soc_write(codec, gain_reg, val);
5521 }
5522 tasha_codec_config_ear_spkr_gain(codec, event, gain_reg);
5523 break;
5524 };
5525
5526 return 0;
5527}
5528
5529static int tasha_codec_set_iir_gain(struct snd_soc_dapm_widget *w,
5530 struct snd_kcontrol *kcontrol, int event)
5531{
5532 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
5533
5534 dev_dbg(codec->dev, "%s: event = %d\n", __func__, event);
5535
5536 switch (event) {
5537 case SND_SOC_DAPM_POST_PMU: /* fall through */
5538 case SND_SOC_DAPM_PRE_PMD:
5539 if (strnstr(w->name, "IIR0", sizeof("IIR0"))) {
5540 snd_soc_write(codec,
5541 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL,
5542 snd_soc_read(codec,
5543 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL));
5544 snd_soc_write(codec,
5545 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL,
5546 snd_soc_read(codec,
5547 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL));
5548 snd_soc_write(codec,
5549 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL,
5550 snd_soc_read(codec,
5551 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL));
5552 snd_soc_write(codec,
5553 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL,
5554 snd_soc_read(codec,
5555 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL));
5556 } else {
5557 snd_soc_write(codec,
5558 WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B1_CTL,
5559 snd_soc_read(codec,
5560 WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B1_CTL));
5561 snd_soc_write(codec,
5562 WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B2_CTL,
5563 snd_soc_read(codec,
5564 WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B2_CTL));
5565 snd_soc_write(codec,
5566 WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B3_CTL,
5567 snd_soc_read(codec,
5568 WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B3_CTL));
5569 }
5570 break;
5571 }
5572 return 0;
5573}
5574
5575static int tasha_codec_enable_on_demand_supply(
5576 struct snd_soc_dapm_widget *w,
5577 struct snd_kcontrol *kcontrol, int event)
5578{
5579 int ret = 0;
5580 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
5581 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
5582 struct on_demand_supply *supply;
5583
5584 if (w->shift >= ON_DEMAND_SUPPLIES_MAX) {
5585 dev_err(codec->dev, "%s: error index > MAX Demand supplies",
5586 __func__);
5587 ret = -EINVAL;
5588 goto out;
5589 }
5590
5591 dev_dbg(codec->dev, "%s: supply: %s event: %d\n",
5592 __func__, on_demand_supply_name[w->shift], event);
5593
5594 supply = &tasha->on_demand_list[w->shift];
5595 WARN_ONCE(!supply->supply, "%s isn't defined\n",
5596 on_demand_supply_name[w->shift]);
5597 if (!supply->supply) {
5598 dev_err(codec->dev, "%s: err supply not present ond for %d",
5599 __func__, w->shift);
5600 goto out;
5601 }
5602
5603 switch (event) {
5604 case SND_SOC_DAPM_PRE_PMU:
5605 ret = regulator_enable(supply->supply);
5606 if (ret)
5607 dev_err(codec->dev, "%s: Failed to enable %s\n",
5608 __func__,
5609 on_demand_supply_name[w->shift]);
5610 break;
5611 case SND_SOC_DAPM_POST_PMD:
5612 ret = regulator_disable(supply->supply);
5613 if (ret)
5614 dev_err(codec->dev, "%s: Failed to disable %s\n",
5615 __func__,
5616 on_demand_supply_name[w->shift]);
5617 break;
5618 default:
5619 break;
5620 };
5621
5622out:
5623 return ret;
5624}
5625
5626static int tasha_codec_find_amic_input(struct snd_soc_codec *codec,
5627 int adc_mux_n)
5628{
5629 u16 mask, shift, adc_mux_in_reg;
5630 u16 amic_mux_sel_reg;
5631 bool is_amic;
5632
5633 if (adc_mux_n < 0 || adc_mux_n > WCD9335_MAX_VALID_ADC_MUX ||
5634 adc_mux_n == WCD9335_INVALID_ADC_MUX)
5635 return 0;
5636
5637 /* Check whether adc mux input is AMIC or DMIC */
5638 if (adc_mux_n < 4) {
5639 adc_mux_in_reg = WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG1 +
5640 2 * adc_mux_n;
5641 amic_mux_sel_reg = WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG0 +
5642 2 * adc_mux_n;
5643 mask = 0x03;
5644 shift = 0;
5645 } else {
5646 adc_mux_in_reg = WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0 +
5647 adc_mux_n - 4;
5648 amic_mux_sel_reg = adc_mux_in_reg;
5649 mask = 0xC0;
5650 shift = 6;
5651 }
5652 is_amic = (((snd_soc_read(codec, adc_mux_in_reg) & mask) >> shift)
5653 == 1);
5654 if (!is_amic)
5655 return 0;
5656
5657 return snd_soc_read(codec, amic_mux_sel_reg) & 0x07;
5658}
5659
5660static void tasha_codec_set_tx_hold(struct snd_soc_codec *codec,
5661 u16 amic_reg, bool set)
5662{
5663 u8 mask = 0x20;
5664 u8 val;
5665
5666 if (amic_reg == WCD9335_ANA_AMIC1 ||
5667 amic_reg == WCD9335_ANA_AMIC3 ||
5668 amic_reg == WCD9335_ANA_AMIC5)
5669 mask = 0x40;
5670
5671 val = set ? mask : 0x00;
5672
5673 switch (amic_reg) {
5674 case WCD9335_ANA_AMIC1:
5675 case WCD9335_ANA_AMIC2:
5676 snd_soc_update_bits(codec, WCD9335_ANA_AMIC2, mask, val);
5677 break;
5678 case WCD9335_ANA_AMIC3:
5679 case WCD9335_ANA_AMIC4:
5680 snd_soc_update_bits(codec, WCD9335_ANA_AMIC4, mask, val);
5681 break;
5682 case WCD9335_ANA_AMIC5:
5683 case WCD9335_ANA_AMIC6:
5684 snd_soc_update_bits(codec, WCD9335_ANA_AMIC6, mask, val);
5685 break;
5686 default:
5687 dev_dbg(codec->dev, "%s: invalid amic: %d\n",
5688 __func__, amic_reg);
5689 break;
5690 }
5691}
5692
5693static int tasha_codec_tx_adc_cfg(struct snd_soc_dapm_widget *w,
5694 struct snd_kcontrol *kcontrol, int event)
5695{
5696 int adc_mux_n = w->shift;
5697 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
5698 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
5699 int amic_n;
5700
5701 dev_dbg(codec->dev, "%s: event: %d\n", __func__, event);
5702
5703 switch (event) {
5704 case SND_SOC_DAPM_POST_PMU:
5705 amic_n = tasha_codec_find_amic_input(codec, adc_mux_n);
5706 if (amic_n) {
5707 /*
5708 * Prevent ANC Rx pop by leaving Tx FE in HOLD
5709 * state until PA is up. Track AMIC being used
5710 * so we can release the HOLD later.
5711 */
5712 set_bit(ANC_MIC_AMIC1 + amic_n - 1,
5713 &tasha->status_mask);
5714 }
5715 break;
5716 default:
5717 break;
5718 }
5719
5720 return 0;
5721}
5722
5723static u16 tasha_codec_get_amic_pwlvl_reg(struct snd_soc_codec *codec, int amic)
5724{
5725 u16 pwr_level_reg = 0;
5726
5727 switch (amic) {
5728 case 1:
5729 case 2:
5730 pwr_level_reg = WCD9335_ANA_AMIC1;
5731 break;
5732
5733 case 3:
5734 case 4:
5735 pwr_level_reg = WCD9335_ANA_AMIC3;
5736 break;
5737
5738 case 5:
5739 case 6:
5740 pwr_level_reg = WCD9335_ANA_AMIC5;
5741 break;
5742 default:
5743 dev_dbg(codec->dev, "%s: invalid amic: %d\n",
5744 __func__, amic);
5745 break;
5746 }
5747
5748 return pwr_level_reg;
5749}
5750
5751#define TX_HPF_CUT_OFF_FREQ_MASK 0x60
5752#define CF_MIN_3DB_4HZ 0x0
5753#define CF_MIN_3DB_75HZ 0x1
5754#define CF_MIN_3DB_150HZ 0x2
5755
5756static void tasha_tx_hpf_corner_freq_callback(struct work_struct *work)
5757{
5758 struct delayed_work *hpf_delayed_work;
5759 struct hpf_work *hpf_work;
5760 struct tasha_priv *tasha;
5761 struct snd_soc_codec *codec;
5762 u16 dec_cfg_reg, amic_reg;
5763 u8 hpf_cut_off_freq;
5764 int amic_n;
5765
5766 hpf_delayed_work = to_delayed_work(work);
5767 hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork);
5768 tasha = hpf_work->tasha;
5769 codec = tasha->codec;
5770 hpf_cut_off_freq = hpf_work->hpf_cut_off_freq;
5771
5772 dec_cfg_reg = WCD9335_CDC_TX0_TX_PATH_CFG0 + 16 * hpf_work->decimator;
5773
5774 dev_dbg(codec->dev, "%s: decimator %u hpf_cut_of_freq 0x%x\n",
5775 __func__, hpf_work->decimator, hpf_cut_off_freq);
5776
5777 amic_n = tasha_codec_find_amic_input(codec, hpf_work->decimator);
5778 if (amic_n) {
5779 amic_reg = WCD9335_ANA_AMIC1 + amic_n - 1;
5780 tasha_codec_set_tx_hold(codec, amic_reg, false);
5781 }
5782 tasha_codec_vote_max_bw(codec, true);
5783 snd_soc_update_bits(codec, dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK,
5784 hpf_cut_off_freq << 5);
5785 tasha_codec_vote_max_bw(codec, false);
5786}
5787
5788static void tasha_tx_mute_update_callback(struct work_struct *work)
5789{
5790 struct tx_mute_work *tx_mute_dwork;
5791 struct tasha_priv *tasha;
5792 struct delayed_work *delayed_work;
5793 struct snd_soc_codec *codec;
5794 u16 tx_vol_ctl_reg, hpf_gate_reg;
5795
5796 delayed_work = to_delayed_work(work);
5797 tx_mute_dwork = container_of(delayed_work, struct tx_mute_work, dwork);
5798 tasha = tx_mute_dwork->tasha;
5799 codec = tasha->codec;
5800
5801 tx_vol_ctl_reg = WCD9335_CDC_TX0_TX_PATH_CTL +
5802 16 * tx_mute_dwork->decimator;
5803 hpf_gate_reg = WCD9335_CDC_TX0_TX_PATH_SEC2 +
5804 16 * tx_mute_dwork->decimator;
5805 snd_soc_update_bits(codec, hpf_gate_reg, 0x01, 0x01);
5806 snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x00);
5807}
5808
5809static int tasha_codec_enable_dec(struct snd_soc_dapm_widget *w,
5810 struct snd_kcontrol *kcontrol, int event)
5811{
5812 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
5813 unsigned int decimator;
5814 char *dec_adc_mux_name = NULL;
5815 char *widget_name = NULL;
5816 char *wname;
5817 int ret = 0, amic_n;
5818 u16 tx_vol_ctl_reg, pwr_level_reg = 0, dec_cfg_reg, hpf_gate_reg;
5819 u16 tx_gain_ctl_reg;
5820 char *dec;
5821 u8 hpf_cut_off_freq;
5822 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
5823
5824 dev_dbg(codec->dev, "%s %d\n", __func__, event);
5825
5826 widget_name = kstrndup(w->name, 15, GFP_KERNEL);
5827 if (!widget_name)
5828 return -ENOMEM;
5829
5830 wname = widget_name;
5831 dec_adc_mux_name = strsep(&widget_name, " ");
5832 if (!dec_adc_mux_name) {
5833 dev_err(codec->dev, "%s: Invalid decimator = %s\n",
5834 __func__, w->name);
5835 ret = -EINVAL;
5836 goto out;
5837 }
5838 dec_adc_mux_name = widget_name;
5839
5840 dec = strpbrk(dec_adc_mux_name, "012345678");
5841 if (!dec) {
5842 dev_err(codec->dev, "%s: decimator index not found\n",
5843 __func__);
5844 ret = -EINVAL;
5845 goto out;
5846 }
5847
5848 ret = kstrtouint(dec, 10, &decimator);
5849 if (ret < 0) {
5850 dev_err(codec->dev, "%s: Invalid decimator = %s\n",
5851 __func__, wname);
5852 ret = -EINVAL;
5853 goto out;
5854 }
5855
5856 dev_dbg(codec->dev, "%s(): widget = %s decimator = %u\n", __func__,
5857 w->name, decimator);
5858
5859 tx_vol_ctl_reg = WCD9335_CDC_TX0_TX_PATH_CTL + 16 * decimator;
5860 hpf_gate_reg = WCD9335_CDC_TX0_TX_PATH_SEC2 + 16 * decimator;
5861 dec_cfg_reg = WCD9335_CDC_TX0_TX_PATH_CFG0 + 16 * decimator;
5862 tx_gain_ctl_reg = WCD9335_CDC_TX0_TX_VOL_CTL + 16 * decimator;
5863
5864 switch (event) {
5865 case SND_SOC_DAPM_PRE_PMU:
5866 amic_n = tasha_codec_find_amic_input(codec, decimator);
5867 if (amic_n)
5868 pwr_level_reg = tasha_codec_get_amic_pwlvl_reg(codec,
5869 amic_n);
5870
5871 if (pwr_level_reg) {
5872 switch ((snd_soc_read(codec, pwr_level_reg) &
5873 WCD9335_AMIC_PWR_LVL_MASK) >>
5874 WCD9335_AMIC_PWR_LVL_SHIFT) {
5875 case WCD9335_AMIC_PWR_LEVEL_LP:
5876 snd_soc_update_bits(codec, dec_cfg_reg,
5877 WCD9335_DEC_PWR_LVL_MASK,
5878 WCD9335_DEC_PWR_LVL_LP);
5879 break;
5880
5881 case WCD9335_AMIC_PWR_LEVEL_HP:
5882 snd_soc_update_bits(codec, dec_cfg_reg,
5883 WCD9335_DEC_PWR_LVL_MASK,
5884 WCD9335_DEC_PWR_LVL_HP);
5885 break;
5886 case WCD9335_AMIC_PWR_LEVEL_DEFAULT:
5887 default:
5888 snd_soc_update_bits(codec, dec_cfg_reg,
5889 WCD9335_DEC_PWR_LVL_MASK,
5890 WCD9335_DEC_PWR_LVL_DF);
5891 break;
5892 }
5893 }
5894 hpf_cut_off_freq = (snd_soc_read(codec, dec_cfg_reg) &
5895 TX_HPF_CUT_OFF_FREQ_MASK) >> 5;
5896 tasha->tx_hpf_work[decimator].hpf_cut_off_freq =
5897 hpf_cut_off_freq;
5898
5899 if (hpf_cut_off_freq != CF_MIN_3DB_150HZ)
5900 snd_soc_update_bits(codec, dec_cfg_reg,
5901 TX_HPF_CUT_OFF_FREQ_MASK,
5902 CF_MIN_3DB_150HZ << 5);
5903 /* Enable TX PGA Mute */
5904 snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x10);
5905 /* Enable APC */
5906 snd_soc_update_bits(codec, dec_cfg_reg, 0x08, 0x08);
5907 break;
5908 case SND_SOC_DAPM_POST_PMU:
5909 snd_soc_update_bits(codec, hpf_gate_reg, 0x01, 0x00);
5910
5911 if (decimator == 0) {
5912 snd_soc_write(codec, WCD9335_MBHC_ZDET_RAMP_CTL, 0x83);
5913 snd_soc_write(codec, WCD9335_MBHC_ZDET_RAMP_CTL, 0xA3);
5914 snd_soc_write(codec, WCD9335_MBHC_ZDET_RAMP_CTL, 0x83);
5915 snd_soc_write(codec, WCD9335_MBHC_ZDET_RAMP_CTL, 0x03);
5916 }
5917 /* schedule work queue to Remove Mute */
5918 schedule_delayed_work(&tasha->tx_mute_dwork[decimator].dwork,
5919 msecs_to_jiffies(tx_unmute_delay));
5920 if (tasha->tx_hpf_work[decimator].hpf_cut_off_freq !=
5921 CF_MIN_3DB_150HZ)
5922 schedule_delayed_work(
5923 &tasha->tx_hpf_work[decimator].dwork,
5924 msecs_to_jiffies(300));
5925 /* apply gain after decimator is enabled */
5926 snd_soc_write(codec, tx_gain_ctl_reg,
5927 snd_soc_read(codec, tx_gain_ctl_reg));
5928 break;
5929 case SND_SOC_DAPM_PRE_PMD:
5930 hpf_cut_off_freq =
5931 tasha->tx_hpf_work[decimator].hpf_cut_off_freq;
5932 snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x10);
5933 snd_soc_update_bits(codec, dec_cfg_reg, 0x08, 0x00);
5934 if (cancel_delayed_work_sync(
5935 &tasha->tx_hpf_work[decimator].dwork)) {
5936 if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) {
5937 tasha_codec_vote_max_bw(codec, true);
5938 snd_soc_update_bits(codec, dec_cfg_reg,
5939 TX_HPF_CUT_OFF_FREQ_MASK,
5940 hpf_cut_off_freq << 5);
5941 tasha_codec_vote_max_bw(codec, false);
5942 }
5943 }
5944 cancel_delayed_work_sync(
5945 &tasha->tx_mute_dwork[decimator].dwork);
5946 break;
5947 case SND_SOC_DAPM_POST_PMD:
5948 snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x00);
5949 break;
5950 };
5951out:
5952 kfree(wname);
5953 return ret;
5954}
5955
5956static u32 tasha_get_dmic_sample_rate(struct snd_soc_codec *codec,
5957 unsigned int dmic, struct wcd9xxx_pdata *pdata)
5958{
5959 u8 tx_stream_fs;
5960 u8 adc_mux_index = 0, adc_mux_sel = 0;
5961 bool dec_found = false;
5962 u16 adc_mux_ctl_reg, tx_fs_reg;
5963 u32 dmic_fs;
5964
5965 while (dec_found == 0 && adc_mux_index < WCD9335_MAX_VALID_ADC_MUX) {
5966 if (adc_mux_index < 4) {
5967 adc_mux_ctl_reg = WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG0 +
5968 (adc_mux_index * 2);
5969 adc_mux_sel = ((snd_soc_read(codec, adc_mux_ctl_reg) &
5970 0x78) >> 3) - 1;
5971 } else if (adc_mux_index < 9) {
5972 adc_mux_ctl_reg = WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0 +
5973 ((adc_mux_index - 4) * 1);
5974 adc_mux_sel = ((snd_soc_read(codec, adc_mux_ctl_reg) &
5975 0x38) >> 3) - 1;
5976 } else if (adc_mux_index == 9) {
5977 ++adc_mux_index;
5978 continue;
5979 }
5980 if (adc_mux_sel == dmic)
5981 dec_found = true;
5982 else
5983 ++adc_mux_index;
5984 }
5985
5986 if (dec_found == true && adc_mux_index <= 8) {
5987 tx_fs_reg = WCD9335_CDC_TX0_TX_PATH_CTL + (16 * adc_mux_index);
5988 tx_stream_fs = snd_soc_read(codec, tx_fs_reg) & 0x0F;
5989 dmic_fs = tx_stream_fs <= 4 ? WCD9XXX_DMIC_SAMPLE_RATE_2P4MHZ :
5990 WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ;
5991
5992 /*
5993 * Check for ECPP path selection and DEC1 not connected to
5994 * any other audio path to apply ECPP DMIC sample rate
5995 */
5996 if ((adc_mux_index == 1) &&
5997 ((snd_soc_read(codec, WCD9335_CPE_SS_US_EC_MUX_CFG)
5998 & 0x0F) == 0x0A) &&
5999 ((snd_soc_read(codec, WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0)
6000 & 0x0C) == 0x00)) {
6001 dmic_fs = pdata->ecpp_dmic_sample_rate;
6002 }
6003 } else {
6004 dmic_fs = pdata->dmic_sample_rate;
6005 }
6006
6007 return dmic_fs;
6008}
6009
6010static u8 tasha_get_dmic_clk_val(struct snd_soc_codec *codec,
6011 u32 mclk_rate, u32 dmic_clk_rate)
6012{
6013 u32 div_factor;
6014 u8 dmic_ctl_val;
6015
6016 dev_dbg(codec->dev,
6017 "%s: mclk_rate = %d, dmic_sample_rate = %d\n",
6018 __func__, mclk_rate, dmic_clk_rate);
6019
6020 /* Default value to return in case of error */
6021 if (mclk_rate == TASHA_MCLK_CLK_9P6MHZ)
6022 dmic_ctl_val = WCD9335_DMIC_CLK_DIV_2;
6023 else
6024 dmic_ctl_val = WCD9335_DMIC_CLK_DIV_3;
6025
6026 if (dmic_clk_rate == 0) {
6027 dev_err(codec->dev,
6028 "%s: dmic_sample_rate cannot be 0\n",
6029 __func__);
6030 goto done;
6031 }
6032
6033 div_factor = mclk_rate / dmic_clk_rate;
6034 switch (div_factor) {
6035 case 2:
6036 dmic_ctl_val = WCD9335_DMIC_CLK_DIV_2;
6037 break;
6038 case 3:
6039 dmic_ctl_val = WCD9335_DMIC_CLK_DIV_3;
6040 break;
6041 case 4:
6042 dmic_ctl_val = WCD9335_DMIC_CLK_DIV_4;
6043 break;
6044 case 6:
6045 dmic_ctl_val = WCD9335_DMIC_CLK_DIV_6;
6046 break;
6047 case 8:
6048 dmic_ctl_val = WCD9335_DMIC_CLK_DIV_8;
6049 break;
6050 case 16:
6051 dmic_ctl_val = WCD9335_DMIC_CLK_DIV_16;
6052 break;
6053 default:
6054 dev_err(codec->dev,
6055 "%s: Invalid div_factor %u, clk_rate(%u), dmic_rate(%u)\n",
6056 __func__, div_factor, mclk_rate, dmic_clk_rate);
6057 break;
6058 }
6059
6060done:
6061 return dmic_ctl_val;
6062}
6063
6064static int tasha_codec_enable_adc(struct snd_soc_dapm_widget *w,
6065 struct snd_kcontrol *kcontrol, int event)
6066{
6067 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
6068
6069 dev_dbg(codec->dev, "%s: event:%d\n", __func__, event);
6070
6071 switch (event) {
6072 case SND_SOC_DAPM_PRE_PMU:
6073 tasha_codec_set_tx_hold(codec, w->reg, true);
6074 break;
6075 default:
6076 break;
6077 }
6078
6079 return 0;
6080}
6081
6082static int tasha_codec_enable_dmic(struct snd_soc_dapm_widget *w,
6083 struct snd_kcontrol *kcontrol, int event)
6084{
6085 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
6086 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
6087 struct wcd9xxx_pdata *pdata = dev_get_platdata(codec->dev->parent);
6088 u8 dmic_clk_en = 0x01;
6089 u16 dmic_clk_reg;
6090 s32 *dmic_clk_cnt;
6091 u8 dmic_rate_val, dmic_rate_shift = 1;
6092 unsigned int dmic;
6093 u32 dmic_sample_rate;
6094 int ret;
6095 char *wname;
6096
6097 wname = strpbrk(w->name, "012345");
6098 if (!wname) {
6099 dev_err(codec->dev, "%s: widget not found\n", __func__);
6100 return -EINVAL;
6101 }
6102
6103 ret = kstrtouint(wname, 10, &dmic);
6104 if (ret < 0) {
6105 dev_err(codec->dev, "%s: Invalid DMIC line on the codec\n",
6106 __func__);
6107 return -EINVAL;
6108 }
6109
6110 switch (dmic) {
6111 case 0:
6112 case 1:
6113 dmic_clk_cnt = &(tasha->dmic_0_1_clk_cnt);
6114 dmic_clk_reg = WCD9335_CPE_SS_DMIC0_CTL;
6115 break;
6116 case 2:
6117 case 3:
6118 dmic_clk_cnt = &(tasha->dmic_2_3_clk_cnt);
6119 dmic_clk_reg = WCD9335_CPE_SS_DMIC1_CTL;
6120 break;
6121 case 4:
6122 case 5:
6123 dmic_clk_cnt = &(tasha->dmic_4_5_clk_cnt);
6124 dmic_clk_reg = WCD9335_CPE_SS_DMIC2_CTL;
6125 break;
6126 default:
6127 dev_err(codec->dev, "%s: Invalid DMIC Selection\n",
6128 __func__);
6129 return -EINVAL;
6130 };
6131 dev_dbg(codec->dev, "%s: event %d DMIC%d dmic_clk_cnt %d\n",
6132 __func__, event, dmic, *dmic_clk_cnt);
6133
6134 switch (event) {
6135 case SND_SOC_DAPM_PRE_PMU:
6136 dmic_sample_rate = tasha_get_dmic_sample_rate(codec, dmic,
6137 pdata);
6138 dmic_rate_val =
6139 tasha_get_dmic_clk_val(codec,
6140 pdata->mclk_rate,
6141 dmic_sample_rate);
6142
6143 (*dmic_clk_cnt)++;
6144 if (*dmic_clk_cnt == 1) {
6145 snd_soc_update_bits(codec, dmic_clk_reg,
6146 0x07 << dmic_rate_shift,
6147 dmic_rate_val << dmic_rate_shift);
6148 snd_soc_update_bits(codec, dmic_clk_reg,
6149 dmic_clk_en, dmic_clk_en);
6150 }
6151
6152 break;
6153 case SND_SOC_DAPM_POST_PMD:
6154 dmic_rate_val =
6155 tasha_get_dmic_clk_val(codec,
6156 pdata->mclk_rate,
6157 pdata->mad_dmic_sample_rate);
6158 (*dmic_clk_cnt)--;
6159 if (*dmic_clk_cnt == 0) {
6160 snd_soc_update_bits(codec, dmic_clk_reg,
6161 dmic_clk_en, 0);
6162 snd_soc_update_bits(codec, dmic_clk_reg,
6163 0x07 << dmic_rate_shift,
6164 dmic_rate_val << dmic_rate_shift);
6165 }
6166 break;
6167 };
6168
6169 return 0;
6170}
6171
6172static int __tasha_codec_enable_micbias(struct snd_soc_dapm_widget *w,
6173 int event)
6174{
6175 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
6176 int micb_num;
6177
6178 dev_dbg(codec->dev, "%s: wname: %s, event: %d\n",
6179 __func__, w->name, event);
6180
6181 if (strnstr(w->name, "MIC BIAS1", sizeof("MIC BIAS1")))
6182 micb_num = MIC_BIAS_1;
6183 else if (strnstr(w->name, "MIC BIAS2", sizeof("MIC BIAS2")))
6184 micb_num = MIC_BIAS_2;
6185 else if (strnstr(w->name, "MIC BIAS3", sizeof("MIC BIAS3")))
6186 micb_num = MIC_BIAS_3;
6187 else if (strnstr(w->name, "MIC BIAS4", sizeof("MIC BIAS4")))
6188 micb_num = MIC_BIAS_4;
6189 else
6190 return -EINVAL;
6191
6192 switch (event) {
6193 case SND_SOC_DAPM_PRE_PMU:
6194 /*
6195 * MIC BIAS can also be requested by MBHC,
6196 * so use ref count to handle micbias pullup
6197 * and enable requests
6198 */
6199 tasha_micbias_control(codec, micb_num, MICB_ENABLE, true);
6200 break;
6201 case SND_SOC_DAPM_POST_PMU:
6202 /* wait for cnp time */
6203 usleep_range(1000, 1100);
6204 break;
6205 case SND_SOC_DAPM_POST_PMD:
6206 tasha_micbias_control(codec, micb_num, MICB_DISABLE, true);
6207 break;
6208 };
6209
6210 return 0;
6211}
6212
6213static int tasha_codec_ldo_h_control(struct snd_soc_dapm_widget *w,
6214 int event)
6215{
6216 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
6217 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
6218
6219 if (SND_SOC_DAPM_EVENT_ON(event)) {
6220 tasha->ldo_h_users++;
6221
6222 if (tasha->ldo_h_users == 1)
6223 snd_soc_update_bits(codec, WCD9335_LDOH_MODE,
6224 0x80, 0x80);
6225 }
6226
6227 if (SND_SOC_DAPM_EVENT_OFF(event)) {
6228 tasha->ldo_h_users--;
6229
6230 if (tasha->ldo_h_users < 0)
6231 tasha->ldo_h_users = 0;
6232
6233 if (tasha->ldo_h_users == 0)
6234 snd_soc_update_bits(codec, WCD9335_LDOH_MODE,
6235 0x80, 0x00);
6236 }
6237
6238 return 0;
6239}
6240
6241static int tasha_codec_force_enable_ldo_h(struct snd_soc_dapm_widget *w,
6242 struct snd_kcontrol *kcontrol,
6243 int event)
6244{
6245 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
6246 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
6247
6248 switch (event) {
6249 case SND_SOC_DAPM_PRE_PMU:
6250 wcd_resmgr_enable_master_bias(tasha->resmgr);
6251 tasha_codec_ldo_h_control(w, event);
6252 break;
6253 case SND_SOC_DAPM_POST_PMD:
6254 tasha_codec_ldo_h_control(w, event);
6255 wcd_resmgr_disable_master_bias(tasha->resmgr);
6256 break;
6257 }
6258
6259 return 0;
6260}
6261
6262static int tasha_codec_force_enable_micbias(struct snd_soc_dapm_widget *w,
6263 struct snd_kcontrol *kcontrol,
6264 int event)
6265{
6266 int ret = 0;
6267 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
6268 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
6269
6270 switch (event) {
6271 case SND_SOC_DAPM_PRE_PMU:
6272 wcd_resmgr_enable_master_bias(tasha->resmgr);
6273 tasha_cdc_mclk_enable(codec, true, true);
6274 ret = __tasha_codec_enable_micbias(w, SND_SOC_DAPM_PRE_PMU);
6275 /* Wait for 1ms for better cnp */
6276 usleep_range(1000, 1100);
6277 tasha_cdc_mclk_enable(codec, false, true);
6278 break;
6279 case SND_SOC_DAPM_POST_PMD:
6280 ret = __tasha_codec_enable_micbias(w, SND_SOC_DAPM_POST_PMD);
6281 wcd_resmgr_disable_master_bias(tasha->resmgr);
6282 break;
6283 }
6284
6285 return ret;
6286}
6287
6288static int tasha_codec_enable_micbias(struct snd_soc_dapm_widget *w,
6289 struct snd_kcontrol *kcontrol, int event)
6290{
6291 return __tasha_codec_enable_micbias(w, event);
6292}
6293
6294static int tasha_codec_enable_standalone_ldo_h(struct snd_soc_codec *codec,
6295 bool enable)
6296{
6297 int rc;
6298
6299 if (enable)
6300 rc = snd_soc_dapm_force_enable_pin(
6301 snd_soc_codec_get_dapm(codec),
6302 DAPM_LDO_H_STANDALONE);
6303 else
6304 rc = snd_soc_dapm_disable_pin(
6305 snd_soc_codec_get_dapm(codec),
6306 DAPM_LDO_H_STANDALONE);
6307
6308 if (!rc)
6309 snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec));
6310 else
6311 dev_err(codec->dev, "%s: ldo_h force %s pin failed\n",
6312 __func__, (enable ? "enable" : "disable"));
6313
6314 return rc;
6315}
6316
6317/*
6318 * tasha_codec_enable_standalone_micbias - enable micbias standalone
6319 * @codec: pointer to codec instance
6320 * @micb_num: number of micbias to be enabled
6321 * @enable: true to enable micbias or false to disable
6322 *
6323 * This function is used to enable micbias (1, 2, 3 or 4) during
6324 * standalone independent of whether TX use-case is running or not
6325 *
6326 * Return: error code in case of failure or 0 for success
6327 */
6328int tasha_codec_enable_standalone_micbias(struct snd_soc_codec *codec,
6329 int micb_num,
6330 bool enable)
6331{
6332 const char * const micb_names[] = {
6333 DAPM_MICBIAS1_STANDALONE, DAPM_MICBIAS2_STANDALONE,
6334 DAPM_MICBIAS3_STANDALONE, DAPM_MICBIAS4_STANDALONE
6335 };
6336 int micb_index = micb_num - 1;
6337 int rc;
6338
6339 if (!codec) {
6340 pr_err("%s: Codec memory is NULL\n", __func__);
6341 return -EINVAL;
6342 }
6343
6344 if ((micb_index < 0) || (micb_index > TASHA_MAX_MICBIAS - 1)) {
6345 dev_err(codec->dev, "%s: Invalid micbias index, micb_ind:%d\n",
6346 __func__, micb_index);
6347 return -EINVAL;
6348 }
6349
6350 if (enable)
6351 rc = snd_soc_dapm_force_enable_pin(
6352 snd_soc_codec_get_dapm(codec),
6353 micb_names[micb_index]);
6354 else
6355 rc = snd_soc_dapm_disable_pin(snd_soc_codec_get_dapm(codec),
6356 micb_names[micb_index]);
6357
6358 if (!rc)
6359 snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec));
6360 else
6361 dev_err(codec->dev, "%s: micbias%d force %s pin failed\n",
6362 __func__, micb_num, (enable ? "enable" : "disable"));
6363
6364 return rc;
6365}
6366EXPORT_SYMBOL(tasha_codec_enable_standalone_micbias);
6367
6368static const char *const tasha_anc_func_text[] = {"OFF", "ON"};
6369static const struct soc_enum tasha_anc_func_enum =
6370 SOC_ENUM_SINGLE_EXT(2, tasha_anc_func_text);
6371
6372static const char *const tasha_clkmode_text[] = {"EXTERNAL", "INTERNAL"};
6373static SOC_ENUM_SINGLE_EXT_DECL(tasha_clkmode_enum, tasha_clkmode_text);
6374
6375/* Cutoff frequency for high pass filter */
6376static const char * const cf_text[] = {
6377 "CF_NEG_3DB_4HZ", "CF_NEG_3DB_75HZ", "CF_NEG_3DB_150HZ"
6378};
6379
6380static const char * const rx_cf_text[] = {
6381 "CF_NEG_3DB_4HZ", "CF_NEG_3DB_75HZ", "CF_NEG_3DB_150HZ",
6382 "CF_NEG_3DB_0P48HZ"
6383};
6384
6385static const struct soc_enum cf_dec0_enum =
6386 SOC_ENUM_SINGLE(WCD9335_CDC_TX0_TX_PATH_CFG0, 5, 3, cf_text);
6387
6388static const struct soc_enum cf_dec1_enum =
6389 SOC_ENUM_SINGLE(WCD9335_CDC_TX1_TX_PATH_CFG0, 5, 3, cf_text);
6390
6391static const struct soc_enum cf_dec2_enum =
6392 SOC_ENUM_SINGLE(WCD9335_CDC_TX2_TX_PATH_CFG0, 5, 3, cf_text);
6393
6394static const struct soc_enum cf_dec3_enum =
6395 SOC_ENUM_SINGLE(WCD9335_CDC_TX3_TX_PATH_CFG0, 5, 3, cf_text);
6396
6397static const struct soc_enum cf_dec4_enum =
6398 SOC_ENUM_SINGLE(WCD9335_CDC_TX4_TX_PATH_CFG0, 5, 3, cf_text);
6399
6400static const struct soc_enum cf_dec5_enum =
6401 SOC_ENUM_SINGLE(WCD9335_CDC_TX5_TX_PATH_CFG0, 5, 3, cf_text);
6402
6403static const struct soc_enum cf_dec6_enum =
6404 SOC_ENUM_SINGLE(WCD9335_CDC_TX6_TX_PATH_CFG0, 5, 3, cf_text);
6405
6406static const struct soc_enum cf_dec7_enum =
6407 SOC_ENUM_SINGLE(WCD9335_CDC_TX7_TX_PATH_CFG0, 5, 3, cf_text);
6408
6409static const struct soc_enum cf_dec8_enum =
6410 SOC_ENUM_SINGLE(WCD9335_CDC_TX8_TX_PATH_CFG0, 5, 3, cf_text);
6411
6412static const struct soc_enum cf_int0_1_enum =
6413 SOC_ENUM_SINGLE(WCD9335_CDC_RX0_RX_PATH_CFG2, 0, 4, rx_cf_text);
6414
6415static SOC_ENUM_SINGLE_DECL(cf_int0_2_enum, WCD9335_CDC_RX0_RX_PATH_MIX_CFG, 2,
6416 rx_cf_text);
6417
6418static const struct soc_enum cf_int1_1_enum =
6419 SOC_ENUM_SINGLE(WCD9335_CDC_RX1_RX_PATH_CFG2, 0, 4, rx_cf_text);
6420
6421static SOC_ENUM_SINGLE_DECL(cf_int1_2_enum, WCD9335_CDC_RX1_RX_PATH_MIX_CFG, 2,
6422 rx_cf_text);
6423
6424static const struct soc_enum cf_int2_1_enum =
6425 SOC_ENUM_SINGLE(WCD9335_CDC_RX2_RX_PATH_CFG2, 0, 4, rx_cf_text);
6426
6427static SOC_ENUM_SINGLE_DECL(cf_int2_2_enum, WCD9335_CDC_RX2_RX_PATH_MIX_CFG, 2,
6428 rx_cf_text);
6429
6430static const struct soc_enum cf_int3_1_enum =
6431 SOC_ENUM_SINGLE(WCD9335_CDC_RX3_RX_PATH_CFG2, 0, 4, rx_cf_text);
6432
6433static SOC_ENUM_SINGLE_DECL(cf_int3_2_enum, WCD9335_CDC_RX3_RX_PATH_MIX_CFG, 2,
6434 rx_cf_text);
6435
6436static const struct soc_enum cf_int4_1_enum =
6437 SOC_ENUM_SINGLE(WCD9335_CDC_RX4_RX_PATH_CFG2, 0, 4, rx_cf_text);
6438
6439static SOC_ENUM_SINGLE_DECL(cf_int4_2_enum, WCD9335_CDC_RX4_RX_PATH_MIX_CFG, 2,
6440 rx_cf_text);
6441
6442static const struct soc_enum cf_int5_1_enum =
6443 SOC_ENUM_SINGLE(WCD9335_CDC_RX5_RX_PATH_CFG2, 0, 4, rx_cf_text);
6444
6445static SOC_ENUM_SINGLE_DECL(cf_int5_2_enum, WCD9335_CDC_RX5_RX_PATH_MIX_CFG, 2,
6446 rx_cf_text);
6447
6448static const struct soc_enum cf_int6_1_enum =
6449 SOC_ENUM_SINGLE(WCD9335_CDC_RX6_RX_PATH_CFG2, 0, 4, rx_cf_text);
6450
6451static SOC_ENUM_SINGLE_DECL(cf_int6_2_enum, WCD9335_CDC_RX6_RX_PATH_MIX_CFG, 2,
6452 rx_cf_text);
6453
6454static const struct soc_enum cf_int7_1_enum =
6455 SOC_ENUM_SINGLE(WCD9335_CDC_RX7_RX_PATH_CFG2, 0, 4, rx_cf_text);
6456
6457static SOC_ENUM_SINGLE_DECL(cf_int7_2_enum, WCD9335_CDC_RX7_RX_PATH_MIX_CFG, 2,
6458 rx_cf_text);
6459
6460static const struct soc_enum cf_int8_1_enum =
6461 SOC_ENUM_SINGLE(WCD9335_CDC_RX8_RX_PATH_CFG2, 0, 4, rx_cf_text);
6462
6463static SOC_ENUM_SINGLE_DECL(cf_int8_2_enum, WCD9335_CDC_RX8_RX_PATH_MIX_CFG, 2,
6464 rx_cf_text);
6465
6466static const struct snd_soc_dapm_route audio_i2s_map[] = {
6467 {"SLIM RX0 MUX", NULL, "RX_I2S_CTL"},
6468 {"SLIM RX1 MUX", NULL, "RX_I2S_CTL"},
6469 {"SLIM RX2 MUX", NULL, "RX_I2S_CTL"},
6470 {"SLIM RX3 MUX", NULL, "RX_I2S_CTL"},
6471
6472 {"SLIM TX6 MUX", NULL, "TX_I2S_CTL"},
6473 {"SLIM TX7 MUX", NULL, "TX_I2S_CTL"},
6474 {"SLIM TX8 MUX", NULL, "TX_I2S_CTL"},
6475 {"SLIM TX11 MUX", NULL, "TX_I2S_CTL"},
6476};
6477
6478static const struct snd_soc_dapm_route audio_map[] = {
6479
6480 /* MAD */
6481 {"MAD_SEL MUX", "SPE", "MAD_CPE_INPUT"},
6482 {"MAD_SEL MUX", "MSM", "MADINPUT"},
6483 {"MADONOFF", "Switch", "MAD_SEL MUX"},
6484 {"MAD_BROADCAST", "Switch", "MAD_SEL MUX"},
6485 {"TX13 INP MUX", "CPE_TX_PP", "MADONOFF"},
6486
6487 /* CPE HW MAD bypass */
6488 {"CPE IN Mixer", "MAD_BYPASS", "SLIM TX1 MUX"},
6489
6490 {"AIF4_MAD Mixer", "SLIM TX1", "CPE IN Mixer"},
6491 {"AIF4_MAD Mixer", "SLIM TX12", "MADONOFF"},
6492 {"AIF4_MAD Mixer", "SLIM TX13", "TX13 INP MUX"},
6493 {"AIF4 MAD", NULL, "AIF4_MAD Mixer"},
6494 {"AIF4 MAD", NULL, "AIF4"},
6495
6496 {"EC BUF MUX INP", "DEC1", "ADC MUX1"},
6497 {"AIF5 CPE", NULL, "EC BUF MUX INP"},
6498
6499 /* SLIMBUS Connections */
6500 {"AIF1 CAP", NULL, "AIF1_CAP Mixer"},
6501 {"AIF2 CAP", NULL, "AIF2_CAP Mixer"},
6502 {"AIF3 CAP", NULL, "AIF3_CAP Mixer"},
6503
6504 /* VI Feedback */
6505 {"AIF4_VI Mixer", "SPKR_VI_1", "VIINPUT"},
6506 {"AIF4_VI Mixer", "SPKR_VI_2", "VIINPUT"},
6507 {"AIF4 VI", NULL, "AIF4_VI Mixer"},
6508
6509 /* SLIM_MIXER("AIF1_CAP Mixer"),*/
6510 {"AIF1_CAP Mixer", "SLIM TX0", "SLIM TX0 MUX"},
6511 {"AIF1_CAP Mixer", "SLIM TX1", "SLIM TX1 MUX"},
6512 {"AIF1_CAP Mixer", "SLIM TX2", "SLIM TX2 MUX"},
6513 {"AIF1_CAP Mixer", "SLIM TX3", "SLIM TX3 MUX"},
6514 {"AIF1_CAP Mixer", "SLIM TX4", "SLIM TX4 MUX"},
6515 {"AIF1_CAP Mixer", "SLIM TX5", "SLIM TX5 MUX"},
6516 {"AIF1_CAP Mixer", "SLIM TX6", "SLIM TX6 MUX"},
6517 {"AIF1_CAP Mixer", "SLIM TX7", "SLIM TX7 MUX"},
6518 {"AIF1_CAP Mixer", "SLIM TX8", "SLIM TX8 MUX"},
6519 {"AIF1_CAP Mixer", "SLIM TX9", "SLIM TX9 MUX"},
6520 {"AIF1_CAP Mixer", "SLIM TX10", "SLIM TX10 MUX"},
6521 {"AIF1_CAP Mixer", "SLIM TX11", "SLIM TX11 MUX"},
6522 {"AIF1_CAP Mixer", "SLIM TX13", "TX13 INP MUX"},
6523 /* SLIM_MIXER("AIF2_CAP Mixer"),*/
6524 {"AIF2_CAP Mixer", "SLIM TX0", "SLIM TX0 MUX"},
6525 {"AIF2_CAP Mixer", "SLIM TX1", "SLIM TX1 MUX"},
6526 {"AIF2_CAP Mixer", "SLIM TX2", "SLIM TX2 MUX"},
6527 {"AIF2_CAP Mixer", "SLIM TX3", "SLIM TX3 MUX"},
6528 {"AIF2_CAP Mixer", "SLIM TX4", "SLIM TX4 MUX"},
6529 {"AIF2_CAP Mixer", "SLIM TX5", "SLIM TX5 MUX"},
6530 {"AIF2_CAP Mixer", "SLIM TX6", "SLIM TX6 MUX"},
6531 {"AIF2_CAP Mixer", "SLIM TX7", "SLIM TX7 MUX"},
6532 {"AIF2_CAP Mixer", "SLIM TX8", "SLIM TX8 MUX"},
6533 {"AIF2_CAP Mixer", "SLIM TX9", "SLIM TX9 MUX"},
6534 {"AIF2_CAP Mixer", "SLIM TX10", "SLIM TX10 MUX"},
6535 {"AIF2_CAP Mixer", "SLIM TX11", "SLIM TX11 MUX"},
6536 {"AIF2_CAP Mixer", "SLIM TX13", "TX13 INP MUX"},
6537 /* SLIM_MIXER("AIF3_CAP Mixer"),*/
6538 {"AIF3_CAP Mixer", "SLIM TX0", "SLIM TX0 MUX"},
6539 {"AIF3_CAP Mixer", "SLIM TX1", "SLIM TX1 MUX"},
6540 {"AIF3_CAP Mixer", "SLIM TX2", "SLIM TX2 MUX"},
6541 {"AIF3_CAP Mixer", "SLIM TX3", "SLIM TX3 MUX"},
6542 {"AIF3_CAP Mixer", "SLIM TX4", "SLIM TX4 MUX"},
6543 {"AIF3_CAP Mixer", "SLIM TX5", "SLIM TX5 MUX"},
6544 {"AIF3_CAP Mixer", "SLIM TX6", "SLIM TX6 MUX"},
6545 {"AIF3_CAP Mixer", "SLIM TX7", "SLIM TX7 MUX"},
6546 {"AIF3_CAP Mixer", "SLIM TX8", "SLIM TX8 MUX"},
6547 {"AIF3_CAP Mixer", "SLIM TX9", "SLIM TX9 MUX"},
6548 {"AIF3_CAP Mixer", "SLIM TX10", "SLIM TX10 MUX"},
6549 {"AIF3_CAP Mixer", "SLIM TX11", "SLIM TX11 MUX"},
6550 {"AIF3_CAP Mixer", "SLIM TX13", "TX13 INP MUX"},
6551
6552 {"SLIM TX0 MUX", "DEC0", "ADC MUX0"},
6553 {"SLIM TX0 MUX", "RX_MIX_TX0", "RX MIX TX0 MUX"},
6554 {"SLIM TX0 MUX", "DEC0_192", "ADC US MUX0"},
6555
6556 {"SLIM TX1 MUX", "DEC1", "ADC MUX1"},
6557 {"SLIM TX1 MUX", "RX_MIX_TX1", "RX MIX TX1 MUX"},
6558 {"SLIM TX1 MUX", "DEC1_192", "ADC US MUX1"},
6559
6560 {"SLIM TX2 MUX", "DEC2", "ADC MUX2"},
6561 {"SLIM TX2 MUX", "RX_MIX_TX2", "RX MIX TX2 MUX"},
6562 {"SLIM TX2 MUX", "DEC2_192", "ADC US MUX2"},
6563
6564 {"SLIM TX3 MUX", "DEC3", "ADC MUX3"},
6565 {"SLIM TX3 MUX", "RX_MIX_TX3", "RX MIX TX3 MUX"},
6566 {"SLIM TX3 MUX", "DEC3_192", "ADC US MUX3"},
6567
6568 {"SLIM TX4 MUX", "DEC4", "ADC MUX4"},
6569 {"SLIM TX4 MUX", "RX_MIX_TX4", "RX MIX TX4 MUX"},
6570 {"SLIM TX4 MUX", "DEC4_192", "ADC US MUX4"},
6571
6572 {"SLIM TX5 MUX", "DEC5", "ADC MUX5"},
6573 {"SLIM TX5 MUX", "RX_MIX_TX5", "RX MIX TX5 MUX"},
6574 {"SLIM TX5 MUX", "DEC5_192", "ADC US MUX5"},
6575
6576 {"SLIM TX6 MUX", "DEC6", "ADC MUX6"},
6577 {"SLIM TX6 MUX", "RX_MIX_TX6", "RX MIX TX6 MUX"},
6578 {"SLIM TX6 MUX", "DEC6_192", "ADC US MUX6"},
6579
6580 {"SLIM TX7 MUX", "DEC7", "ADC MUX7"},
6581 {"SLIM TX7 MUX", "RX_MIX_TX7", "RX MIX TX7 MUX"},
6582 {"SLIM TX7 MUX", "DEC7_192", "ADC US MUX7"},
6583
6584 {"SLIM TX8 MUX", "DEC8", "ADC MUX8"},
6585 {"SLIM TX8 MUX", "RX_MIX_TX8", "RX MIX TX8 MUX"},
6586 {"SLIM TX8 MUX", "DEC8_192", "ADC US MUX8"},
6587
6588 {"SLIM TX9 MUX", "DEC7", "ADC MUX7"},
6589 {"SLIM TX9 MUX", "DEC7_192", "ADC US MUX7"},
6590 {"SLIM TX10 MUX", "DEC6", "ADC MUX6"},
6591 {"SLIM TX10 MUX", "DEC6_192", "ADC US MUX6"},
6592
6593 {"SLIM TX11 MUX", "DEC_0_5", "SLIM TX11 INP1 MUX"},
6594 {"SLIM TX11 MUX", "DEC_9_12", "SLIM TX11 INP1 MUX"},
6595 {"SLIM TX11 INP1 MUX", "DEC0", "ADC MUX0"},
6596 {"SLIM TX11 INP1 MUX", "DEC1", "ADC MUX1"},
6597 {"SLIM TX11 INP1 MUX", "DEC2", "ADC MUX2"},
6598 {"SLIM TX11 INP1 MUX", "DEC3", "ADC MUX3"},
6599 {"SLIM TX11 INP1 MUX", "DEC4", "ADC MUX4"},
6600 {"SLIM TX11 INP1 MUX", "DEC5", "ADC MUX5"},
6601 {"SLIM TX11 INP1 MUX", "RX_MIX_TX5", "RX MIX TX5 MUX"},
6602
6603 {"TX13 INP MUX", "MAD_BRDCST", "MAD_BROADCAST"},
6604 {"TX13 INP MUX", "CDC_DEC_5", "SLIM TX13 MUX"},
6605 {"SLIM TX13 MUX", "DEC5", "ADC MUX5"},
6606
6607 {"RX MIX TX0 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
6608 {"RX MIX TX0 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
6609 {"RX MIX TX0 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
6610 {"RX MIX TX0 MUX", "RX_MIX3", "RX INT3 SEC MIX"},
6611 {"RX MIX TX0 MUX", "RX_MIX4", "RX INT4 SEC MIX"},
6612 {"RX MIX TX0 MUX", "RX_MIX5", "RX INT5 SEC MIX"},
6613 {"RX MIX TX0 MUX", "RX_MIX6", "RX INT6 SEC MIX"},
6614 {"RX MIX TX0 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
6615 {"RX MIX TX0 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
6616 {"RX MIX TX0 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"},
6617 {"RX MIX TX0 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"},
6618 {"RX MIX TX0 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"},
6619 {"RX MIX TX0 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"},
6620
6621 {"RX MIX TX1 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
6622 {"RX MIX TX1 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
6623 {"RX MIX TX1 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
6624 {"RX MIX TX1 MUX", "RX_MIX3", "RX INT3 SEC MIX"},
6625 {"RX MIX TX1 MUX", "RX_MIX4", "RX INT4 SEC MIX"},
6626 {"RX MIX TX1 MUX", "RX_MIX5", "RX INT5 SEC MIX"},
6627 {"RX MIX TX1 MUX", "RX_MIX6", "RX INT6 SEC MIX"},
6628 {"RX MIX TX1 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
6629 {"RX MIX TX1 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
6630 {"RX MIX TX1 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"},
6631 {"RX MIX TX1 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"},
6632 {"RX MIX TX1 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"},
6633 {"RX MIX TX1 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"},
6634
6635 {"RX MIX TX2 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
6636 {"RX MIX TX2 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
6637 {"RX MIX TX2 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
6638 {"RX MIX TX2 MUX", "RX_MIX3", "RX INT3 SEC MIX"},
6639 {"RX MIX TX2 MUX", "RX_MIX4", "RX INT4 SEC MIX"},
6640 {"RX MIX TX2 MUX", "RX_MIX5", "RX INT5 SEC MIX"},
6641 {"RX MIX TX2 MUX", "RX_MIX6", "RX INT6 SEC MIX"},
6642 {"RX MIX TX2 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
6643 {"RX MIX TX2 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
6644 {"RX MIX TX2 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"},
6645 {"RX MIX TX2 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"},
6646 {"RX MIX TX2 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"},
6647 {"RX MIX TX2 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"},
6648
6649 {"RX MIX TX3 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
6650 {"RX MIX TX3 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
6651 {"RX MIX TX3 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
6652 {"RX MIX TX3 MUX", "RX_MIX3", "RX INT3 SEC MIX"},
6653 {"RX MIX TX3 MUX", "RX_MIX4", "RX INT4 SEC MIX"},
6654 {"RX MIX TX3 MUX", "RX_MIX5", "RX INT5 SEC MIX"},
6655 {"RX MIX TX3 MUX", "RX_MIX6", "RX INT6 SEC MIX"},
6656 {"RX MIX TX3 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
6657 {"RX MIX TX3 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
6658 {"RX MIX TX3 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"},
6659 {"RX MIX TX3 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"},
6660 {"RX MIX TX3 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"},
6661 {"RX MIX TX3 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"},
6662
6663 {"RX MIX TX4 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
6664 {"RX MIX TX4 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
6665 {"RX MIX TX4 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
6666 {"RX MIX TX4 MUX", "RX_MIX3", "RX INT3 SEC MIX"},
6667 {"RX MIX TX4 MUX", "RX_MIX4", "RX INT4 SEC MIX"},
6668 {"RX MIX TX4 MUX", "RX_MIX5", "RX INT5 SEC MIX"},
6669 {"RX MIX TX4 MUX", "RX_MIX6", "RX INT6 SEC MIX"},
6670 {"RX MIX TX4 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
6671 {"RX MIX TX4 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
6672 {"RX MIX TX4 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"},
6673 {"RX MIX TX4 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"},
6674 {"RX MIX TX4 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"},
6675 {"RX MIX TX4 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"},
6676
6677 {"RX MIX TX5 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
6678 {"RX MIX TX5 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
6679 {"RX MIX TX5 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
6680 {"RX MIX TX5 MUX", "RX_MIX3", "RX INT3 SEC MIX"},
6681 {"RX MIX TX5 MUX", "RX_MIX4", "RX INT4 SEC MIX"},
6682 {"RX MIX TX5 MUX", "RX_MIX5", "RX INT5 SEC MIX"},
6683 {"RX MIX TX5 MUX", "RX_MIX6", "RX INT6 SEC MIX"},
6684 {"RX MIX TX5 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
6685 {"RX MIX TX5 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
6686 {"RX MIX TX5 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"},
6687 {"RX MIX TX5 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"},
6688 {"RX MIX TX5 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"},
6689 {"RX MIX TX5 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"},
6690
6691 {"RX MIX TX6 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
6692 {"RX MIX TX6 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
6693 {"RX MIX TX6 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
6694 {"RX MIX TX6 MUX", "RX_MIX3", "RX INT3 SEC MIX"},
6695 {"RX MIX TX6 MUX", "RX_MIX4", "RX INT4 SEC MIX"},
6696 {"RX MIX TX6 MUX", "RX_MIX5", "RX INT5 SEC MIX"},
6697 {"RX MIX TX6 MUX", "RX_MIX6", "RX INT6 SEC MIX"},
6698 {"RX MIX TX6 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
6699 {"RX MIX TX6 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
6700 {"RX MIX TX6 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"},
6701 {"RX MIX TX6 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"},
6702 {"RX MIX TX6 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"},
6703 {"RX MIX TX6 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"},
6704
6705 {"RX MIX TX7 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
6706 {"RX MIX TX7 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
6707 {"RX MIX TX7 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
6708 {"RX MIX TX7 MUX", "RX_MIX3", "RX INT3 SEC MIX"},
6709 {"RX MIX TX7 MUX", "RX_MIX4", "RX INT4 SEC MIX"},
6710 {"RX MIX TX7 MUX", "RX_MIX5", "RX INT5 SEC MIX"},
6711 {"RX MIX TX7 MUX", "RX_MIX6", "RX INT6 SEC MIX"},
6712 {"RX MIX TX7 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
6713 {"RX MIX TX7 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
6714 {"RX MIX TX7 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"},
6715 {"RX MIX TX7 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"},
6716 {"RX MIX TX7 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"},
6717 {"RX MIX TX7 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"},
6718
6719 {"RX MIX TX8 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
6720 {"RX MIX TX8 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
6721 {"RX MIX TX8 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
6722 {"RX MIX TX8 MUX", "RX_MIX3", "RX INT3 SEC MIX"},
6723 {"RX MIX TX8 MUX", "RX_MIX4", "RX INT4 SEC MIX"},
6724 {"RX MIX TX8 MUX", "RX_MIX5", "RX INT5 SEC MIX"},
6725 {"RX MIX TX8 MUX", "RX_MIX6", "RX INT6 SEC MIX"},
6726 {"RX MIX TX8 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
6727 {"RX MIX TX8 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
6728 {"RX MIX TX8 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"},
6729 {"RX MIX TX8 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"},
6730 {"RX MIX TX8 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"},
6731 {"RX MIX TX8 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"},
6732
6733 {"ADC US MUX0", "US_Switch", "ADC MUX0"},
6734 {"ADC US MUX1", "US_Switch", "ADC MUX1"},
6735 {"ADC US MUX2", "US_Switch", "ADC MUX2"},
6736 {"ADC US MUX3", "US_Switch", "ADC MUX3"},
6737 {"ADC US MUX4", "US_Switch", "ADC MUX4"},
6738 {"ADC US MUX5", "US_Switch", "ADC MUX5"},
6739 {"ADC US MUX6", "US_Switch", "ADC MUX6"},
6740 {"ADC US MUX7", "US_Switch", "ADC MUX7"},
6741 {"ADC US MUX8", "US_Switch", "ADC MUX8"},
6742 {"ADC MUX0", "DMIC", "DMIC MUX0"},
6743 {"ADC MUX0", "AMIC", "AMIC MUX0"},
6744 {"ADC MUX1", "DMIC", "DMIC MUX1"},
6745 {"ADC MUX1", "AMIC", "AMIC MUX1"},
6746 {"ADC MUX2", "DMIC", "DMIC MUX2"},
6747 {"ADC MUX2", "AMIC", "AMIC MUX2"},
6748 {"ADC MUX3", "DMIC", "DMIC MUX3"},
6749 {"ADC MUX3", "AMIC", "AMIC MUX3"},
6750 {"ADC MUX4", "DMIC", "DMIC MUX4"},
6751 {"ADC MUX4", "AMIC", "AMIC MUX4"},
6752 {"ADC MUX5", "DMIC", "DMIC MUX5"},
6753 {"ADC MUX5", "AMIC", "AMIC MUX5"},
6754 {"ADC MUX6", "DMIC", "DMIC MUX6"},
6755 {"ADC MUX6", "AMIC", "AMIC MUX6"},
6756 {"ADC MUX7", "DMIC", "DMIC MUX7"},
6757 {"ADC MUX7", "AMIC", "AMIC MUX7"},
6758 {"ADC MUX8", "DMIC", "DMIC MUX8"},
6759 {"ADC MUX8", "AMIC", "AMIC MUX8"},
6760 {"ADC MUX10", "DMIC", "DMIC MUX10"},
6761 {"ADC MUX10", "AMIC", "AMIC MUX10"},
6762 {"ADC MUX11", "DMIC", "DMIC MUX11"},
6763 {"ADC MUX11", "AMIC", "AMIC MUX11"},
6764 {"ADC MUX12", "DMIC", "DMIC MUX12"},
6765 {"ADC MUX12", "AMIC", "AMIC MUX12"},
6766 {"ADC MUX13", "DMIC", "DMIC MUX13"},
6767 {"ADC MUX13", "AMIC", "AMIC MUX13"},
6768
6769 {"ADC MUX0", "ANC_FB_TUNE1", "ADC MUX10"},
6770 {"ADC MUX0", "ANC_FB_TUNE1", "ADC MUX11"},
6771 {"ADC MUX0", "ANC_FB_TUNE2", "ADC MUX12"},
6772 {"ADC MUX0", "ANC_FB_TUNE2", "ADC MUX13"},
6773 {"ADC MUX1", "ANC_FB_TUNE1", "ADC MUX10"},
6774 {"ADC MUX1", "ANC_FB_TUNE1", "ADC MUX11"},
6775 {"ADC MUX1", "ANC_FB_TUNE2", "ADC MUX12"},
6776 {"ADC MUX1", "ANC_FB_TUNE2", "ADC MUX13"},
6777 {"ADC MUX2", "ANC_FB_TUNE1", "ADC MUX10"},
6778 {"ADC MUX2", "ANC_FB_TUNE1", "ADC MUX11"},
6779 {"ADC MUX2", "ANC_FB_TUNE2", "ADC MUX12"},
6780 {"ADC MUX2", "ANC_FB_TUNE2", "ADC MUX13"},
6781 {"ADC MUX3", "ANC_FB_TUNE1", "ADC MUX10"},
6782 {"ADC MUX3", "ANC_FB_TUNE1", "ADC MUX11"},
6783 {"ADC MUX3", "ANC_FB_TUNE2", "ADC MUX12"},
6784 {"ADC MUX3", "ANC_FB_TUNE2", "ADC MUX13"},
6785 {"ADC MUX4", "ANC_FB_TUNE1", "ADC MUX10"},
6786 {"ADC MUX4", "ANC_FB_TUNE1", "ADC MUX11"},
6787 {"ADC MUX4", "ANC_FB_TUNE2", "ADC MUX12"},
6788 {"ADC MUX4", "ANC_FB_TUNE2", "ADC MUX13"},
6789 {"ADC MUX5", "ANC_FB_TUNE1", "ADC MUX10"},
6790 {"ADC MUX5", "ANC_FB_TUNE1", "ADC MUX11"},
6791 {"ADC MUX5", "ANC_FB_TUNE2", "ADC MUX12"},
6792 {"ADC MUX5", "ANC_FB_TUNE2", "ADC MUX13"},
6793 {"ADC MUX6", "ANC_FB_TUNE1", "ADC MUX10"},
6794 {"ADC MUX6", "ANC_FB_TUNE1", "ADC MUX11"},
6795 {"ADC MUX6", "ANC_FB_TUNE2", "ADC MUX12"},
6796 {"ADC MUX6", "ANC_FB_TUNE2", "ADC MUX13"},
6797 {"ADC MUX7", "ANC_FB_TUNE1", "ADC MUX10"},
6798 {"ADC MUX7", "ANC_FB_TUNE1", "ADC MUX11"},
6799 {"ADC MUX7", "ANC_FB_TUNE2", "ADC MUX12"},
6800 {"ADC MUX7", "ANC_FB_TUNE2", "ADC MUX13"},
6801 {"ADC MUX8", "ANC_FB_TUNE1", "ADC MUX10"},
6802 {"ADC MUX8", "ANC_FB_TUNE1", "ADC MUX11"},
6803 {"ADC MUX8", "ANC_FB_TUNE2", "ADC MUX12"},
6804 {"ADC MUX8", "ANC_FB_TUNE2", "ADC MUX13"},
6805
6806 {"DMIC MUX0", "DMIC0", "DMIC0"},
6807 {"DMIC MUX0", "DMIC1", "DMIC1"},
6808 {"DMIC MUX0", "DMIC2", "DMIC2"},
6809 {"DMIC MUX0", "DMIC3", "DMIC3"},
6810 {"DMIC MUX0", "DMIC4", "DMIC4"},
6811 {"DMIC MUX0", "DMIC5", "DMIC5"},
6812 {"AMIC MUX0", "ADC1", "ADC1"},
6813 {"AMIC MUX0", "ADC2", "ADC2"},
6814 {"AMIC MUX0", "ADC3", "ADC3"},
6815 {"AMIC MUX0", "ADC4", "ADC4"},
6816 {"AMIC MUX0", "ADC5", "ADC5"},
6817 {"AMIC MUX0", "ADC6", "ADC6"},
6818
6819 {"DMIC MUX1", "DMIC0", "DMIC0"},
6820 {"DMIC MUX1", "DMIC1", "DMIC1"},
6821 {"DMIC MUX1", "DMIC2", "DMIC2"},
6822 {"DMIC MUX1", "DMIC3", "DMIC3"},
6823 {"DMIC MUX1", "DMIC4", "DMIC4"},
6824 {"DMIC MUX1", "DMIC5", "DMIC5"},
6825 {"AMIC MUX1", "ADC1", "ADC1"},
6826 {"AMIC MUX1", "ADC2", "ADC2"},
6827 {"AMIC MUX1", "ADC3", "ADC3"},
6828 {"AMIC MUX1", "ADC4", "ADC4"},
6829 {"AMIC MUX1", "ADC5", "ADC5"},
6830 {"AMIC MUX1", "ADC6", "ADC6"},
6831
6832 {"DMIC MUX2", "DMIC0", "DMIC0"},
6833 {"DMIC MUX2", "DMIC1", "DMIC1"},
6834 {"DMIC MUX2", "DMIC2", "DMIC2"},
6835 {"DMIC MUX2", "DMIC3", "DMIC3"},
6836 {"DMIC MUX2", "DMIC4", "DMIC4"},
6837 {"DMIC MUX2", "DMIC5", "DMIC5"},
6838 {"AMIC MUX2", "ADC1", "ADC1"},
6839 {"AMIC MUX2", "ADC2", "ADC2"},
6840 {"AMIC MUX2", "ADC3", "ADC3"},
6841 {"AMIC MUX2", "ADC4", "ADC4"},
6842 {"AMIC MUX2", "ADC5", "ADC5"},
6843 {"AMIC MUX2", "ADC6", "ADC6"},
6844
6845 {"DMIC MUX3", "DMIC0", "DMIC0"},
6846 {"DMIC MUX3", "DMIC1", "DMIC1"},
6847 {"DMIC MUX3", "DMIC2", "DMIC2"},
6848 {"DMIC MUX3", "DMIC3", "DMIC3"},
6849 {"DMIC MUX3", "DMIC4", "DMIC4"},
6850 {"DMIC MUX3", "DMIC5", "DMIC5"},
6851 {"AMIC MUX3", "ADC1", "ADC1"},
6852 {"AMIC MUX3", "ADC2", "ADC2"},
6853 {"AMIC MUX3", "ADC3", "ADC3"},
6854 {"AMIC MUX3", "ADC4", "ADC4"},
6855 {"AMIC MUX3", "ADC5", "ADC5"},
6856 {"AMIC MUX3", "ADC6", "ADC6"},
6857
6858 {"DMIC MUX4", "DMIC0", "DMIC0"},
6859 {"DMIC MUX4", "DMIC1", "DMIC1"},
6860 {"DMIC MUX4", "DMIC2", "DMIC2"},
6861 {"DMIC MUX4", "DMIC3", "DMIC3"},
6862 {"DMIC MUX4", "DMIC4", "DMIC4"},
6863 {"DMIC MUX4", "DMIC5", "DMIC5"},
6864 {"AMIC MUX4", "ADC1", "ADC1"},
6865 {"AMIC MUX4", "ADC2", "ADC2"},
6866 {"AMIC MUX4", "ADC3", "ADC3"},
6867 {"AMIC MUX4", "ADC4", "ADC4"},
6868 {"AMIC MUX4", "ADC5", "ADC5"},
6869 {"AMIC MUX4", "ADC6", "ADC6"},
6870
6871 {"DMIC MUX5", "DMIC0", "DMIC0"},
6872 {"DMIC MUX5", "DMIC1", "DMIC1"},
6873 {"DMIC MUX5", "DMIC2", "DMIC2"},
6874 {"DMIC MUX5", "DMIC3", "DMIC3"},
6875 {"DMIC MUX5", "DMIC4", "DMIC4"},
6876 {"DMIC MUX5", "DMIC5", "DMIC5"},
6877 {"AMIC MUX5", "ADC1", "ADC1"},
6878 {"AMIC MUX5", "ADC2", "ADC2"},
6879 {"AMIC MUX5", "ADC3", "ADC3"},
6880 {"AMIC MUX5", "ADC4", "ADC4"},
6881 {"AMIC MUX5", "ADC5", "ADC5"},
6882 {"AMIC MUX5", "ADC6", "ADC6"},
6883
6884 {"DMIC MUX6", "DMIC0", "DMIC0"},
6885 {"DMIC MUX6", "DMIC1", "DMIC1"},
6886 {"DMIC MUX6", "DMIC2", "DMIC2"},
6887 {"DMIC MUX6", "DMIC3", "DMIC3"},
6888 {"DMIC MUX6", "DMIC4", "DMIC4"},
6889 {"DMIC MUX6", "DMIC5", "DMIC5"},
6890 {"AMIC MUX6", "ADC1", "ADC1"},
6891 {"AMIC MUX6", "ADC2", "ADC2"},
6892 {"AMIC MUX6", "ADC3", "ADC3"},
6893 {"AMIC MUX6", "ADC4", "ADC4"},
6894 {"AMIC MUX6", "ADC5", "ADC5"},
6895 {"AMIC MUX6", "ADC6", "ADC6"},
6896
6897 {"DMIC MUX7", "DMIC0", "DMIC0"},
6898 {"DMIC MUX7", "DMIC1", "DMIC1"},
6899 {"DMIC MUX7", "DMIC2", "DMIC2"},
6900 {"DMIC MUX7", "DMIC3", "DMIC3"},
6901 {"DMIC MUX7", "DMIC4", "DMIC4"},
6902 {"DMIC MUX7", "DMIC5", "DMIC5"},
6903 {"AMIC MUX7", "ADC1", "ADC1"},
6904 {"AMIC MUX7", "ADC2", "ADC2"},
6905 {"AMIC MUX7", "ADC3", "ADC3"},
6906 {"AMIC MUX7", "ADC4", "ADC4"},
6907 {"AMIC MUX7", "ADC5", "ADC5"},
6908 {"AMIC MUX7", "ADC6", "ADC6"},
6909
6910 {"DMIC MUX8", "DMIC0", "DMIC0"},
6911 {"DMIC MUX8", "DMIC1", "DMIC1"},
6912 {"DMIC MUX8", "DMIC2", "DMIC2"},
6913 {"DMIC MUX8", "DMIC3", "DMIC3"},
6914 {"DMIC MUX8", "DMIC4", "DMIC4"},
6915 {"DMIC MUX8", "DMIC5", "DMIC5"},
6916 {"AMIC MUX8", "ADC1", "ADC1"},
6917 {"AMIC MUX8", "ADC2", "ADC2"},
6918 {"AMIC MUX8", "ADC3", "ADC3"},
6919 {"AMIC MUX8", "ADC4", "ADC4"},
6920 {"AMIC MUX8", "ADC5", "ADC5"},
6921 {"AMIC MUX8", "ADC6", "ADC6"},
6922
6923 {"DMIC MUX10", "DMIC0", "DMIC0"},
6924 {"DMIC MUX10", "DMIC1", "DMIC1"},
6925 {"DMIC MUX10", "DMIC2", "DMIC2"},
6926 {"DMIC MUX10", "DMIC3", "DMIC3"},
6927 {"DMIC MUX10", "DMIC4", "DMIC4"},
6928 {"DMIC MUX10", "DMIC5", "DMIC5"},
6929 {"AMIC MUX10", "ADC1", "ADC1"},
6930 {"AMIC MUX10", "ADC2", "ADC2"},
6931 {"AMIC MUX10", "ADC3", "ADC3"},
6932 {"AMIC MUX10", "ADC4", "ADC4"},
6933 {"AMIC MUX10", "ADC5", "ADC5"},
6934 {"AMIC MUX10", "ADC6", "ADC6"},
6935
6936 {"DMIC MUX11", "DMIC0", "DMIC0"},
6937 {"DMIC MUX11", "DMIC1", "DMIC1"},
6938 {"DMIC MUX11", "DMIC2", "DMIC2"},
6939 {"DMIC MUX11", "DMIC3", "DMIC3"},
6940 {"DMIC MUX11", "DMIC4", "DMIC4"},
6941 {"DMIC MUX11", "DMIC5", "DMIC5"},
6942 {"AMIC MUX11", "ADC1", "ADC1"},
6943 {"AMIC MUX11", "ADC2", "ADC2"},
6944 {"AMIC MUX11", "ADC3", "ADC3"},
6945 {"AMIC MUX11", "ADC4", "ADC4"},
6946 {"AMIC MUX11", "ADC5", "ADC5"},
6947 {"AMIC MUX11", "ADC6", "ADC6"},
6948
6949 {"DMIC MUX12", "DMIC0", "DMIC0"},
6950 {"DMIC MUX12", "DMIC1", "DMIC1"},
6951 {"DMIC MUX12", "DMIC2", "DMIC2"},
6952 {"DMIC MUX12", "DMIC3", "DMIC3"},
6953 {"DMIC MUX12", "DMIC4", "DMIC4"},
6954 {"DMIC MUX12", "DMIC5", "DMIC5"},
6955 {"AMIC MUX12", "ADC1", "ADC1"},
6956 {"AMIC MUX12", "ADC2", "ADC2"},
6957 {"AMIC MUX12", "ADC3", "ADC3"},
6958 {"AMIC MUX12", "ADC4", "ADC4"},
6959 {"AMIC MUX12", "ADC5", "ADC5"},
6960 {"AMIC MUX12", "ADC6", "ADC6"},
6961
6962 {"DMIC MUX13", "DMIC0", "DMIC0"},
6963 {"DMIC MUX13", "DMIC1", "DMIC1"},
6964 {"DMIC MUX13", "DMIC2", "DMIC2"},
6965 {"DMIC MUX13", "DMIC3", "DMIC3"},
6966 {"DMIC MUX13", "DMIC4", "DMIC4"},
6967 {"DMIC MUX13", "DMIC5", "DMIC5"},
6968 {"AMIC MUX13", "ADC1", "ADC1"},
6969 {"AMIC MUX13", "ADC2", "ADC2"},
6970 {"AMIC MUX13", "ADC3", "ADC3"},
6971 {"AMIC MUX13", "ADC4", "ADC4"},
6972 {"AMIC MUX13", "ADC5", "ADC5"},
6973 {"AMIC MUX13", "ADC6", "ADC6"},
6974 /* ADC Connections */
6975 {"ADC1", NULL, "AMIC1"},
6976 {"ADC2", NULL, "AMIC2"},
6977 {"ADC3", NULL, "AMIC3"},
6978 {"ADC4", NULL, "AMIC4"},
6979 {"ADC5", NULL, "AMIC5"},
6980 {"ADC6", NULL, "AMIC6"},
6981
6982 {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP0"},
6983 {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP1"},
6984 {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP2"},
6985 {"RX INT1_1 MIX1", NULL, "RX INT1_1 MIX1 INP0"},
6986 {"RX INT1_1 MIX1", NULL, "RX INT1_1 MIX1 INP1"},
6987 {"RX INT1_1 MIX1", NULL, "RX INT1_1 MIX1 INP2"},
6988 {"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP0"},
6989 {"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP1"},
6990 {"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP2"},
6991 {"RX INT3_1 MIX1", NULL, "RX INT3_1 MIX1 INP0"},
6992 {"RX INT3_1 MIX1", NULL, "RX INT3_1 MIX1 INP1"},
6993 {"RX INT3_1 MIX1", NULL, "RX INT3_1 MIX1 INP2"},
6994 {"RX INT4_1 MIX1", NULL, "RX INT4_1 MIX1 INP0"},
6995 {"RX INT4_1 MIX1", NULL, "RX INT4_1 MIX1 INP1"},
6996 {"RX INT4_1 MIX1", NULL, "RX INT4_1 MIX1 INP2"},
6997 {"RX INT5_1 MIX1", NULL, "RX INT5_1 MIX1 INP0"},
6998 {"RX INT5_1 MIX1", NULL, "RX INT5_1 MIX1 INP1"},
6999 {"RX INT5_1 MIX1", NULL, "RX INT5_1 MIX1 INP2"},
7000 {"RX INT6_1 MIX1", NULL, "RX INT6_1 MIX1 INP0"},
7001 {"RX INT6_1 MIX1", NULL, "RX INT6_1 MIX1 INP1"},
7002 {"RX INT6_1 MIX1", NULL, "RX INT6_1 MIX1 INP2"},
7003 {"RX INT7_1 MIX1", NULL, "RX INT7_1 MIX1 INP0"},
7004 {"RX INT7_1 MIX1", NULL, "RX INT7_1 MIX1 INP1"},
7005 {"RX INT7_1 MIX1", NULL, "RX INT7_1 MIX1 INP2"},
7006 {"RX INT8_1 MIX1", NULL, "RX INT8_1 MIX1 INP0"},
7007 {"RX INT8_1 MIX1", NULL, "RX INT8_1 MIX1 INP1"},
7008 {"RX INT8_1 MIX1", NULL, "RX INT8_1 MIX1 INP2"},
7009
7010 {"RX INT0 SEC MIX", NULL, "RX INT0_1 MIX1"},
7011 {"RX INT0 MIX2", NULL, "RX INT0 SEC MIX"},
7012 {"RX INT0 MIX2", NULL, "RX INT0 MIX2 INP"},
7013 {"RX INT0 INTERP", NULL, "RX INT0 MIX2"},
7014 {"RX INT0 DEM MUX", "CLSH_DSM_OUT", "RX INT0 INTERP"},
7015 {"RX INT0 DAC", NULL, "RX INT0 DEM MUX"},
7016 {"RX INT0 DAC", NULL, "RX_BIAS"},
7017 {"EAR PA", NULL, "RX INT0 DAC"},
7018 {"EAR", NULL, "EAR PA"},
7019
7020 {"SPL SRC0 MUX", "SRC_IN_HPHL", "RX INT1_1 MIX1"},
7021 {"RX INT1 SPLINE MIX", NULL, "RX INT1_1 MIX1"},
7022 {"RX INT1 SPLINE MIX", "HPHL Switch", "SPL SRC0 MUX"},
7023 {"RX INT1_1 NATIVE MUX", "ON", "RX INT1_1 MIX1"},
7024 {"RX INT1 SPLINE MIX", NULL, "RX INT1_1 NATIVE MUX"},
7025 {"RX INT1_1 NATIVE MUX", NULL, "RX INT1 NATIVE SUPPLY"},
7026 {"RX INT1 SEC MIX", NULL, "RX INT1 SPLINE MIX"},
7027 {"RX INT1 MIX2", NULL, "RX INT1 SEC MIX"},
7028 {"RX INT1 MIX2", NULL, "RX INT1 MIX2 INP"},
7029 {"RX INT1 INTERP", NULL, "RX INT1 MIX2"},
7030 {"RX INT1 DEM MUX", "CLSH_DSM_OUT", "RX INT1 INTERP"},
7031 {"RX INT1 DAC", NULL, "RX INT1 DEM MUX"},
7032 {"RX INT1 DAC", NULL, "RX_BIAS"},
7033 {"HPHL PA", NULL, "RX INT1 DAC"},
7034 {"HPHL", NULL, "HPHL PA"},
7035
7036 {"SPL SRC1 MUX", "SRC_IN_HPHR", "RX INT2_1 MIX1"},
7037 {"RX INT2 SPLINE MIX", NULL, "RX INT2_1 MIX1"},
7038 {"RX INT2 SPLINE MIX", "HPHR Switch", "SPL SRC1 MUX"},
7039 {"RX INT2_1 NATIVE MUX", "ON", "RX INT2_1 MIX1"},
7040 {"RX INT2 SPLINE MIX", NULL, "RX INT2_1 NATIVE MUX"},
7041 {"RX INT2_1 NATIVE MUX", NULL, "RX INT2 NATIVE SUPPLY"},
7042 {"RX INT2 SEC MIX", NULL, "RX INT2 SPLINE MIX"},
7043 {"RX INT2 MIX2", NULL, "RX INT2 SEC MIX"},
7044 {"RX INT2 MIX2", NULL, "RX INT2 MIX2 INP"},
7045 {"RX INT2 INTERP", NULL, "RX INT2 MIX2"},
7046 {"RX INT2 DEM MUX", "CLSH_DSM_OUT", "RX INT2 INTERP"},
7047 {"RX INT2 DAC", NULL, "RX INT2 DEM MUX"},
7048 {"RX INT2 DAC", NULL, "RX_BIAS"},
7049 {"HPHR PA", NULL, "RX INT2 DAC"},
7050 {"HPHR", NULL, "HPHR PA"},
7051
7052 {"SPL SRC0 MUX", "SRC_IN_LO1", "RX INT3_1 MIX1"},
7053 {"RX INT3 SPLINE MIX", NULL, "RX INT3_1 MIX1"},
7054 {"RX INT3 SPLINE MIX", "LO1 Switch", "SPL SRC0 MUX"},
7055 {"RX INT3_1 NATIVE MUX", "ON", "RX INT3_1 MIX1"},
7056 {"RX INT3 SPLINE MIX", NULL, "RX INT3_1 NATIVE MUX"},
7057 {"RX INT3_1 NATIVE MUX", NULL, "RX INT3 NATIVE SUPPLY"},
7058 {"RX INT3 SEC MIX", NULL, "RX INT3 SPLINE MIX"},
7059 {"RX INT3 MIX2", NULL, "RX INT3 SEC MIX"},
7060 {"RX INT3 MIX2", NULL, "RX INT3 MIX2 INP"},
7061 {"RX INT3 INTERP", NULL, "RX INT3 MIX2"},
7062 {"RX INT3 DAC", NULL, "RX INT3 INTERP"},
7063 {"RX INT3 DAC", NULL, "RX_BIAS"},
7064 {"LINEOUT1 PA", NULL, "RX INT3 DAC"},
7065 {"LINEOUT1", NULL, "LINEOUT1 PA"},
7066
7067 {"SPL SRC1 MUX", "SRC_IN_LO2", "RX INT4_1 MIX1"},
7068 {"RX INT4 SPLINE MIX", NULL, "RX INT4_1 MIX1"},
7069 {"RX INT4 SPLINE MIX", "LO2 Switch", "SPL SRC1 MUX"},
7070 {"RX INT4_1 NATIVE MUX", "ON", "RX INT4_1 MIX1"},
7071 {"RX INT4 SPLINE MIX", NULL, "RX INT4_1 NATIVE MUX"},
7072 {"RX INT4_1 NATIVE MUX", NULL, "RX INT4 NATIVE SUPPLY"},
7073 {"RX INT4 SEC MIX", NULL, "RX INT4 SPLINE MIX"},
7074 {"RX INT4 MIX2", NULL, "RX INT4 SEC MIX"},
7075 {"RX INT4 MIX2", NULL, "RX INT4 MIX2 INP"},
7076 {"RX INT4 INTERP", NULL, "RX INT4 MIX2"},
7077 {"RX INT4 DAC", NULL, "RX INT4 INTERP"},
7078 {"RX INT4 DAC", NULL, "RX_BIAS"},
7079 {"LINEOUT2 PA", NULL, "RX INT4 DAC"},
7080 {"LINEOUT2", NULL, "LINEOUT2 PA"},
7081
7082 {"SPL SRC2 MUX", "SRC_IN_LO3", "RX INT5_1 MIX1"},
7083 {"RX INT5 SPLINE MIX", NULL, "RX INT5_1 MIX1"},
7084 {"RX INT5 SPLINE MIX", "LO3 Switch", "SPL SRC2 MUX"},
7085 {"RX INT5 SEC MIX", NULL, "RX INT5 SPLINE MIX"},
7086 {"RX INT5 MIX2", NULL, "RX INT5 SEC MIX"},
7087 {"RX INT5 INTERP", NULL, "RX INT5 MIX2"},
7088
7089 {"RX INT5 VBAT", "LO3 VBAT Enable", "RX INT5 INTERP"},
7090 {"RX INT5 DAC", NULL, "RX INT5 VBAT"},
7091
7092 {"RX INT5 DAC", NULL, "RX INT5 INTERP"},
7093 {"RX INT5 DAC", NULL, "RX_BIAS"},
7094 {"LINEOUT3 PA", NULL, "RX INT5 DAC"},
7095 {"LINEOUT3", NULL, "LINEOUT3 PA"},
7096
7097 {"SPL SRC3 MUX", "SRC_IN_LO4", "RX INT6_1 MIX1"},
7098 {"RX INT6 SPLINE MIX", NULL, "RX INT6_1 MIX1"},
7099 {"RX INT6 SPLINE MIX", "LO4 Switch", "SPL SRC3 MUX"},
7100 {"RX INT6 SEC MIX", NULL, "RX INT6 SPLINE MIX"},
7101 {"RX INT6 MIX2", NULL, "RX INT6 SEC MIX"},
7102 {"RX INT6 INTERP", NULL, "RX INT6 MIX2"},
7103
7104 {"RX INT6 VBAT", "LO4 VBAT Enable", "RX INT6 INTERP"},
7105 {"RX INT6 DAC", NULL, "RX INT6 VBAT"},
7106
7107 {"RX INT6 DAC", NULL, "RX INT6 INTERP"},
7108 {"RX INT6 DAC", NULL, "RX_BIAS"},
7109 {"LINEOUT4 PA", NULL, "RX INT6 DAC"},
7110 {"LINEOUT4", NULL, "LINEOUT4 PA"},
7111
7112 {"SPL SRC2 MUX", "SRC_IN_SPKRL", "RX INT7_1 MIX1"},
7113 {"RX INT7 SPLINE MIX", NULL, "RX INT7_1 MIX1"},
7114 {"RX INT7 SPLINE MIX", "SPKRL Switch", "SPL SRC2 MUX"},
7115 {"RX INT7 SEC MIX", NULL, "RX INT7 SPLINE MIX"},
7116 {"RX INT7 MIX2", NULL, "RX INT7 SEC MIX"},
7117 {"RX INT7 MIX2", NULL, "RX INT7 MIX2 INP"},
7118
7119 {"RX INT7 INTERP", NULL, "RX INT7 MIX2"},
7120
7121 {"RX INT7 VBAT", "SPKRL VBAT Enable", "RX INT7 INTERP"},
7122 {"RX INT7 CHAIN", NULL, "RX INT7 VBAT"},
7123
7124 {"RX INT7 CHAIN", NULL, "RX INT7 INTERP"},
7125 {"RX INT7 CHAIN", NULL, "RX_BIAS"},
7126 {"SPK1 OUT", NULL, "RX INT7 CHAIN"},
7127
7128 {"ANC SPKR PA Enable", "Switch", "RX INT7 CHAIN"},
7129 {"ANC SPK1 PA", NULL, "ANC SPKR PA Enable"},
7130 {"SPK1 OUT", NULL, "ANC SPK1 PA"},
7131
7132 {"SPL SRC3 MUX", "SRC_IN_SPKRR", "RX INT8_1 MIX1"},
7133 {"RX INT8 SPLINE MIX", NULL, "RX INT8_1 MIX1"},
7134 {"RX INT8 SPLINE MIX", "SPKRR Switch", "SPL SRC3 MUX"},
7135 {"RX INT8 SEC MIX", NULL, "RX INT8 SPLINE MIX"},
7136 {"RX INT8 INTERP", NULL, "RX INT8 SEC MIX"},
7137
7138 {"RX INT8 VBAT", "SPKRR VBAT Enable", "RX INT8 INTERP"},
7139 {"RX INT8 CHAIN", NULL, "RX INT8 VBAT"},
7140
7141 {"RX INT8 CHAIN", NULL, "RX INT8 INTERP"},
7142 {"RX INT8 CHAIN", NULL, "RX_BIAS"},
7143 {"SPK2 OUT", NULL, "RX INT8 CHAIN"},
7144
7145 {"ANC0 FB MUX", "ANC_IN_EAR", "RX INT0 MIX2"},
7146 {"ANC0 FB MUX", "ANC_IN_HPHL", "RX INT1 MIX2"},
7147 {"ANC0 FB MUX", "ANC_IN_LO1", "RX INT3 MIX2"},
7148 {"ANC0 FB MUX", "ANC_IN_EAR_SPKR", "RX INT7 MIX2"},
7149 {"ANC1 FB MUX", "ANC_IN_HPHR", "RX INT2 MIX2"},
7150 {"ANC1 FB MUX", "ANC_IN_LO2", "RX INT4 MIX2"},
7151
7152 {"ANC HPHL Enable", "Switch", "ADC MUX10"},
7153 {"ANC HPHL Enable", "Switch", "ADC MUX11"},
7154 {"RX INT1 MIX2", NULL, "ANC HPHL Enable"},
7155
7156 {"ANC HPHR Enable", "Switch", "ADC MUX12"},
7157 {"ANC HPHR Enable", "Switch", "ADC MUX13"},
7158 {"RX INT2 MIX2", NULL, "ANC HPHR Enable"},
7159
7160 {"ANC EAR Enable", "Switch", "ADC MUX10"},
7161 {"ANC EAR Enable", "Switch", "ADC MUX11"},
7162 {"RX INT0 MIX2", NULL, "ANC EAR Enable"},
7163
7164 {"ANC OUT EAR SPKR Enable", "Switch", "ADC MUX10"},
7165 {"ANC OUT EAR SPKR Enable", "Switch", "ADC MUX11"},
7166 {"RX INT7 MIX2", NULL, "ANC OUT EAR SPKR Enable"},
7167
7168 {"ANC LINEOUT1 Enable", "Switch", "ADC MUX10"},
7169 {"ANC LINEOUT1 Enable", "Switch", "ADC MUX11"},
7170 {"RX INT3 MIX2", NULL, "ANC LINEOUT1 Enable"},
7171
7172 {"ANC LINEOUT2 Enable", "Switch", "ADC MUX12"},
7173 {"ANC LINEOUT2 Enable", "Switch", "ADC MUX13"},
7174 {"RX INT4 MIX2", NULL, "ANC LINEOUT2 Enable"},
7175
7176 {"ANC EAR PA", NULL, "RX INT0 DAC"},
7177 {"ANC EAR", NULL, "ANC EAR PA"},
7178 {"ANC HPHL PA", NULL, "RX INT1 DAC"},
7179 {"ANC HPHL", NULL, "ANC HPHL PA"},
7180 {"ANC HPHR PA", NULL, "RX INT2 DAC"},
7181 {"ANC HPHR", NULL, "ANC HPHR PA"},
7182 {"ANC LINEOUT1 PA", NULL, "RX INT3 DAC"},
7183 {"ANC LINEOUT1", NULL, "ANC LINEOUT1 PA"},
7184 {"ANC LINEOUT2 PA", NULL, "RX INT4 DAC"},
7185 {"ANC LINEOUT2", NULL, "ANC LINEOUT2 PA"},
7186
7187 /* SLIM_MUX("AIF1_PB", "AIF1 PB"),*/
7188 {"SLIM RX0 MUX", "AIF1_PB", "AIF1 PB"},
7189 {"SLIM RX1 MUX", "AIF1_PB", "AIF1 PB"},
7190 {"SLIM RX2 MUX", "AIF1_PB", "AIF1 PB"},
7191 {"SLIM RX3 MUX", "AIF1_PB", "AIF1 PB"},
7192 {"SLIM RX4 MUX", "AIF1_PB", "AIF1 PB"},
7193 {"SLIM RX5 MUX", "AIF1_PB", "AIF1 PB"},
7194 {"SLIM RX6 MUX", "AIF1_PB", "AIF1 PB"},
7195 {"SLIM RX7 MUX", "AIF1_PB", "AIF1 PB"},
7196 /* SLIM_MUX("AIF2_PB", "AIF2 PB"),*/
7197 {"SLIM RX0 MUX", "AIF2_PB", "AIF2 PB"},
7198 {"SLIM RX1 MUX", "AIF2_PB", "AIF2 PB"},
7199 {"SLIM RX2 MUX", "AIF2_PB", "AIF2 PB"},
7200 {"SLIM RX3 MUX", "AIF2_PB", "AIF2 PB"},
7201 {"SLIM RX4 MUX", "AIF2_PB", "AIF2 PB"},
7202 {"SLIM RX5 MUX", "AIF2_PB", "AIF2 PB"},
7203 {"SLIM RX6 MUX", "AIF2_PB", "AIF2 PB"},
7204 {"SLIM RX7 MUX", "AIF2_PB", "AIF2 PB"},
7205 /* SLIM_MUX("AIF3_PB", "AIF3 PB"),*/
7206 {"SLIM RX0 MUX", "AIF3_PB", "AIF3 PB"},
7207 {"SLIM RX1 MUX", "AIF3_PB", "AIF3 PB"},
7208 {"SLIM RX2 MUX", "AIF3_PB", "AIF3 PB"},
7209 {"SLIM RX3 MUX", "AIF3_PB", "AIF3 PB"},
7210 {"SLIM RX4 MUX", "AIF3_PB", "AIF3 PB"},
7211 {"SLIM RX5 MUX", "AIF3_PB", "AIF3 PB"},
7212 {"SLIM RX6 MUX", "AIF3_PB", "AIF3 PB"},
7213 {"SLIM RX7 MUX", "AIF3_PB", "AIF3 PB"},
7214 /* SLIM_MUX("AIF4_PB", "AIF4 PB"),*/
7215 {"SLIM RX0 MUX", "AIF4_PB", "AIF4 PB"},
7216 {"SLIM RX1 MUX", "AIF4_PB", "AIF4 PB"},
7217 {"SLIM RX2 MUX", "AIF4_PB", "AIF4 PB"},
7218 {"SLIM RX3 MUX", "AIF4_PB", "AIF4 PB"},
7219 {"SLIM RX4 MUX", "AIF4_PB", "AIF4 PB"},
7220 {"SLIM RX5 MUX", "AIF4_PB", "AIF4 PB"},
7221 {"SLIM RX6 MUX", "AIF4_PB", "AIF4 PB"},
7222 {"SLIM RX7 MUX", "AIF4_PB", "AIF4 PB"},
7223
7224 /* SLIM_MUX("AIF_MIX1_PB", "AIF MIX1 PB"),*/
7225 {"SLIM RX0 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"},
7226 {"SLIM RX1 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"},
7227 {"SLIM RX2 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"},
7228 {"SLIM RX3 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"},
7229 {"SLIM RX4 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"},
7230 {"SLIM RX5 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"},
7231 {"SLIM RX6 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"},
7232 {"SLIM RX7 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"},
7233
7234 {"SLIM RX0", NULL, "SLIM RX0 MUX"},
7235 {"SLIM RX1", NULL, "SLIM RX1 MUX"},
7236 {"SLIM RX2", NULL, "SLIM RX2 MUX"},
7237 {"SLIM RX3", NULL, "SLIM RX3 MUX"},
7238 {"SLIM RX4", NULL, "SLIM RX4 MUX"},
7239 {"SLIM RX5", NULL, "SLIM RX5 MUX"},
7240 {"SLIM RX6", NULL, "SLIM RX6 MUX"},
7241 {"SLIM RX7", NULL, "SLIM RX7 MUX"},
7242
7243 {"RX INT0_1 MIX1 INP0", "RX0", "SLIM RX0"},
7244 {"RX INT0_1 MIX1 INP0", "RX1", "SLIM RX1"},
7245 {"RX INT0_1 MIX1 INP0", "RX2", "SLIM RX2"},
7246 {"RX INT0_1 MIX1 INP0", "RX3", "SLIM RX3"},
7247 {"RX INT0_1 MIX1 INP0", "RX4", "SLIM RX4"},
7248 {"RX INT0_1 MIX1 INP0", "RX5", "SLIM RX5"},
7249 {"RX INT0_1 MIX1 INP0", "RX6", "SLIM RX6"},
7250 {"RX INT0_1 MIX1 INP0", "RX7", "SLIM RX7"},
7251 {"RX INT0_1 MIX1 INP0", "IIR0", "IIR0"},
7252 {"RX INT0_1 MIX1 INP0", "IIR1", "IIR1"},
7253 {"RX INT0_1 MIX1 INP1", "RX0", "SLIM RX0"},
7254 {"RX INT0_1 MIX1 INP1", "RX1", "SLIM RX1"},
7255 {"RX INT0_1 MIX1 INP1", "RX2", "SLIM RX2"},
7256 {"RX INT0_1 MIX1 INP1", "RX3", "SLIM RX3"},
7257 {"RX INT0_1 MIX1 INP1", "RX4", "SLIM RX4"},
7258 {"RX INT0_1 MIX1 INP1", "RX5", "SLIM RX5"},
7259 {"RX INT0_1 MIX1 INP1", "RX6", "SLIM RX6"},
7260 {"RX INT0_1 MIX1 INP1", "RX7", "SLIM RX7"},
7261 {"RX INT0_1 MIX1 INP1", "IIR0", "IIR0"},
7262 {"RX INT0_1 MIX1 INP1", "IIR1", "IIR1"},
7263 {"RX INT0_1 MIX1 INP2", "RX0", "SLIM RX0"},
7264 {"RX INT0_1 MIX1 INP2", "RX1", "SLIM RX1"},
7265 {"RX INT0_1 MIX1 INP2", "RX2", "SLIM RX2"},
7266 {"RX INT0_1 MIX1 INP2", "RX3", "SLIM RX3"},
7267 {"RX INT0_1 MIX1 INP2", "RX4", "SLIM RX4"},
7268 {"RX INT0_1 MIX1 INP2", "RX5", "SLIM RX5"},
7269 {"RX INT0_1 MIX1 INP2", "RX6", "SLIM RX6"},
7270 {"RX INT0_1 MIX1 INP2", "RX7", "SLIM RX7"},
7271 {"RX INT0_1 MIX1 INP2", "IIR0", "IIR0"},
7272 {"RX INT0_1 MIX1 INP2", "IIR1", "IIR1"},
7273
7274 /* MIXing path INT0 */
7275 {"RX INT0_2 MUX", "RX0", "SLIM RX0"},
7276 {"RX INT0_2 MUX", "RX1", "SLIM RX1"},
7277 {"RX INT0_2 MUX", "RX2", "SLIM RX2"},
7278 {"RX INT0_2 MUX", "RX3", "SLIM RX3"},
7279 {"RX INT0_2 MUX", "RX4", "SLIM RX4"},
7280 {"RX INT0_2 MUX", "RX5", "SLIM RX5"},
7281 {"RX INT0_2 MUX", "RX6", "SLIM RX6"},
7282 {"RX INT0_2 MUX", "RX7", "SLIM RX7"},
7283 {"RX INT0 SEC MIX", NULL, "RX INT0_2 MUX"},
7284
7285 /* MIXing path INT1 */
7286 {"RX INT1_2 MUX", "RX0", "SLIM RX0"},
7287 {"RX INT1_2 MUX", "RX1", "SLIM RX1"},
7288 {"RX INT1_2 MUX", "RX2", "SLIM RX2"},
7289 {"RX INT1_2 MUX", "RX3", "SLIM RX3"},
7290 {"RX INT1_2 MUX", "RX4", "SLIM RX4"},
7291 {"RX INT1_2 MUX", "RX5", "SLIM RX5"},
7292 {"RX INT1_2 MUX", "RX6", "SLIM RX6"},
7293 {"RX INT1_2 MUX", "RX7", "SLIM RX7"},
7294 {"RX INT1 SEC MIX", NULL, "RX INT1_2 MUX"},
7295
7296 /* MIXing path INT2 */
7297 {"RX INT2_2 MUX", "RX0", "SLIM RX0"},
7298 {"RX INT2_2 MUX", "RX1", "SLIM RX1"},
7299 {"RX INT2_2 MUX", "RX2", "SLIM RX2"},
7300 {"RX INT2_2 MUX", "RX3", "SLIM RX3"},
7301 {"RX INT2_2 MUX", "RX4", "SLIM RX4"},
7302 {"RX INT2_2 MUX", "RX5", "SLIM RX5"},
7303 {"RX INT2_2 MUX", "RX6", "SLIM RX6"},
7304 {"RX INT2_2 MUX", "RX7", "SLIM RX7"},
7305 {"RX INT2 SEC MIX", NULL, "RX INT2_2 MUX"},
7306
7307 /* MIXing path INT3 */
7308 {"RX INT3_2 MUX", "RX0", "SLIM RX0"},
7309 {"RX INT3_2 MUX", "RX1", "SLIM RX1"},
7310 {"RX INT3_2 MUX", "RX2", "SLIM RX2"},
7311 {"RX INT3_2 MUX", "RX3", "SLIM RX3"},
7312 {"RX INT3_2 MUX", "RX4", "SLIM RX4"},
7313 {"RX INT3_2 MUX", "RX5", "SLIM RX5"},
7314 {"RX INT3_2 MUX", "RX6", "SLIM RX6"},
7315 {"RX INT3_2 MUX", "RX7", "SLIM RX7"},
7316 {"RX INT3 SEC MIX", NULL, "RX INT3_2 MUX"},
7317
7318 /* MIXing path INT4 */
7319 {"RX INT4_2 MUX", "RX0", "SLIM RX0"},
7320 {"RX INT4_2 MUX", "RX1", "SLIM RX1"},
7321 {"RX INT4_2 MUX", "RX2", "SLIM RX2"},
7322 {"RX INT4_2 MUX", "RX3", "SLIM RX3"},
7323 {"RX INT4_2 MUX", "RX4", "SLIM RX4"},
7324 {"RX INT4_2 MUX", "RX5", "SLIM RX5"},
7325 {"RX INT4_2 MUX", "RX6", "SLIM RX6"},
7326 {"RX INT4_2 MUX", "RX7", "SLIM RX7"},
7327 {"RX INT4 SEC MIX", NULL, "RX INT4_2 MUX"},
7328
7329 /* MIXing path INT5 */
7330 {"RX INT5_2 MUX", "RX0", "SLIM RX0"},
7331 {"RX INT5_2 MUX", "RX1", "SLIM RX1"},
7332 {"RX INT5_2 MUX", "RX2", "SLIM RX2"},
7333 {"RX INT5_2 MUX", "RX3", "SLIM RX3"},
7334 {"RX INT5_2 MUX", "RX4", "SLIM RX4"},
7335 {"RX INT5_2 MUX", "RX5", "SLIM RX5"},
7336 {"RX INT5_2 MUX", "RX6", "SLIM RX6"},
7337 {"RX INT5_2 MUX", "RX7", "SLIM RX7"},
7338 {"RX INT5 SEC MIX", NULL, "RX INT5_2 MUX"},
7339
7340 /* MIXing path INT6 */
7341 {"RX INT6_2 MUX", "RX0", "SLIM RX0"},
7342 {"RX INT6_2 MUX", "RX1", "SLIM RX1"},
7343 {"RX INT6_2 MUX", "RX2", "SLIM RX2"},
7344 {"RX INT6_2 MUX", "RX3", "SLIM RX3"},
7345 {"RX INT6_2 MUX", "RX4", "SLIM RX4"},
7346 {"RX INT6_2 MUX", "RX5", "SLIM RX5"},
7347 {"RX INT6_2 MUX", "RX6", "SLIM RX6"},
7348 {"RX INT6_2 MUX", "RX7", "SLIM RX7"},
7349 {"RX INT6 SEC MIX", NULL, "RX INT6_2 MUX"},
7350
7351 /* MIXing path INT7 */
7352 {"RX INT7_2 MUX", "RX0", "SLIM RX0"},
7353 {"RX INT7_2 MUX", "RX1", "SLIM RX1"},
7354 {"RX INT7_2 MUX", "RX2", "SLIM RX2"},
7355 {"RX INT7_2 MUX", "RX3", "SLIM RX3"},
7356 {"RX INT7_2 MUX", "RX4", "SLIM RX4"},
7357 {"RX INT7_2 MUX", "RX5", "SLIM RX5"},
7358 {"RX INT7_2 MUX", "RX6", "SLIM RX6"},
7359 {"RX INT7_2 MUX", "RX7", "SLIM RX7"},
7360 {"RX INT7 SEC MIX", NULL, "RX INT7_2 MUX"},
7361
7362 /* MIXing path INT8 */
7363 {"RX INT8_2 MUX", "RX0", "SLIM RX0"},
7364 {"RX INT8_2 MUX", "RX1", "SLIM RX1"},
7365 {"RX INT8_2 MUX", "RX2", "SLIM RX2"},
7366 {"RX INT8_2 MUX", "RX3", "SLIM RX3"},
7367 {"RX INT8_2 MUX", "RX4", "SLIM RX4"},
7368 {"RX INT8_2 MUX", "RX5", "SLIM RX5"},
7369 {"RX INT8_2 MUX", "RX6", "SLIM RX6"},
7370 {"RX INT8_2 MUX", "RX7", "SLIM RX7"},
7371 {"RX INT8 SEC MIX", NULL, "RX INT8_2 MUX"},
7372
7373 {"RX INT1_1 MIX1 INP0", "RX0", "SLIM RX0"},
7374 {"RX INT1_1 MIX1 INP0", "RX1", "SLIM RX1"},
7375 {"RX INT1_1 MIX1 INP0", "RX2", "SLIM RX2"},
7376 {"RX INT1_1 MIX1 INP0", "RX3", "SLIM RX3"},
7377 {"RX INT1_1 MIX1 INP0", "RX4", "SLIM RX4"},
7378 {"RX INT1_1 MIX1 INP0", "RX5", "SLIM RX5"},
7379 {"RX INT1_1 MIX1 INP0", "RX6", "SLIM RX6"},
7380 {"RX INT1_1 MIX1 INP0", "RX7", "SLIM RX7"},
7381 {"RX INT1_1 MIX1 INP0", "IIR0", "IIR0"},
7382 {"RX INT1_1 MIX1 INP0", "IIR1", "IIR1"},
7383 {"RX INT1_1 MIX1 INP1", "RX0", "SLIM RX0"},
7384 {"RX INT1_1 MIX1 INP1", "RX1", "SLIM RX1"},
7385 {"RX INT1_1 MIX1 INP1", "RX2", "SLIM RX2"},
7386 {"RX INT1_1 MIX1 INP1", "RX3", "SLIM RX3"},
7387 {"RX INT1_1 MIX1 INP1", "RX4", "SLIM RX4"},
7388 {"RX INT1_1 MIX1 INP1", "RX5", "SLIM RX5"},
7389 {"RX INT1_1 MIX1 INP1", "RX6", "SLIM RX6"},
7390 {"RX INT1_1 MIX1 INP1", "RX7", "SLIM RX7"},
7391 {"RX INT1_1 MIX1 INP1", "IIR0", "IIR0"},
7392 {"RX INT1_1 MIX1 INP1", "IIR1", "IIR1"},
7393 {"RX INT1_1 MIX1 INP2", "RX0", "SLIM RX0"},
7394 {"RX INT1_1 MIX1 INP2", "RX1", "SLIM RX1"},
7395 {"RX INT1_1 MIX1 INP2", "RX2", "SLIM RX2"},
7396 {"RX INT1_1 MIX1 INP2", "RX3", "SLIM RX3"},
7397 {"RX INT1_1 MIX1 INP2", "RX4", "SLIM RX4"},
7398 {"RX INT1_1 MIX1 INP2", "RX5", "SLIM RX5"},
7399 {"RX INT1_1 MIX1 INP2", "RX6", "SLIM RX6"},
7400 {"RX INT1_1 MIX1 INP2", "RX7", "SLIM RX7"},
7401 {"RX INT1_1 MIX1 INP2", "IIR0", "IIR0"},
7402 {"RX INT1_1 MIX1 INP2", "IIR1", "IIR1"},
7403 {"RX INT2_1 MIX1 INP0", "RX0", "SLIM RX0"},
7404 {"RX INT2_1 MIX1 INP0", "RX1", "SLIM RX1"},
7405 {"RX INT2_1 MIX1 INP0", "RX2", "SLIM RX2"},
7406 {"RX INT2_1 MIX1 INP0", "RX3", "SLIM RX3"},
7407 {"RX INT2_1 MIX1 INP0", "RX4", "SLIM RX4"},
7408 {"RX INT2_1 MIX1 INP0", "RX5", "SLIM RX5"},
7409 {"RX INT2_1 MIX1 INP0", "RX6", "SLIM RX6"},
7410 {"RX INT2_1 MIX1 INP0", "RX7", "SLIM RX7"},
7411 {"RX INT2_1 MIX1 INP0", "IIR0", "IIR0"},
7412 {"RX INT2_1 MIX1 INP0", "IIR1", "IIR1"},
7413 {"RX INT2_1 MIX1 INP1", "RX0", "SLIM RX0"},
7414 {"RX INT2_1 MIX1 INP1", "RX1", "SLIM RX1"},
7415 {"RX INT2_1 MIX1 INP1", "RX2", "SLIM RX2"},
7416 {"RX INT2_1 MIX1 INP1", "RX3", "SLIM RX3"},
7417 {"RX INT2_1 MIX1 INP1", "RX4", "SLIM RX4"},
7418 {"RX INT2_1 MIX1 INP1", "RX5", "SLIM RX5"},
7419 {"RX INT2_1 MIX1 INP1", "RX6", "SLIM RX6"},
7420 {"RX INT2_1 MIX1 INP1", "RX7", "SLIM RX7"},
7421 {"RX INT2_1 MIX1 INP1", "IIR0", "IIR0"},
7422 {"RX INT2_1 MIX1 INP1", "IIR1", "IIR1"},
7423 {"RX INT2_1 MIX1 INP2", "RX0", "SLIM RX0"},
7424 {"RX INT2_1 MIX1 INP2", "RX1", "SLIM RX1"},
7425 {"RX INT2_1 MIX1 INP2", "RX2", "SLIM RX2"},
7426 {"RX INT2_1 MIX1 INP2", "RX3", "SLIM RX3"},
7427 {"RX INT2_1 MIX1 INP2", "RX4", "SLIM RX4"},
7428 {"RX INT2_1 MIX1 INP2", "RX5", "SLIM RX5"},
7429 {"RX INT2_1 MIX1 INP2", "RX6", "SLIM RX6"},
7430 {"RX INT2_1 MIX1 INP2", "RX7", "SLIM RX7"},
7431 {"RX INT2_1 MIX1 INP2", "IIR0", "IIR0"},
7432 {"RX INT2_1 MIX1 INP2", "IIR1", "IIR1"},
7433
7434 {"RX INT3_1 MIX1 INP0", "RX0", "SLIM RX0"},
7435 {"RX INT3_1 MIX1 INP0", "RX1", "SLIM RX1"},
7436 {"RX INT3_1 MIX1 INP0", "RX2", "SLIM RX2"},
7437 {"RX INT3_1 MIX1 INP0", "RX3", "SLIM RX3"},
7438 {"RX INT3_1 MIX1 INP0", "RX4", "SLIM RX4"},
7439 {"RX INT3_1 MIX1 INP0", "RX5", "SLIM RX5"},
7440 {"RX INT3_1 MIX1 INP0", "RX6", "SLIM RX6"},
7441 {"RX INT3_1 MIX1 INP0", "RX7", "SLIM RX7"},
7442 {"RX INT3_1 MIX1 INP0", "IIR0", "IIR0"},
7443 {"RX INT3_1 MIX1 INP0", "IIR1", "IIR1"},
7444 {"RX INT3_1 MIX1 INP1", "RX0", "SLIM RX0"},
7445 {"RX INT3_1 MIX1 INP1", "RX1", "SLIM RX1"},
7446 {"RX INT3_1 MIX1 INP1", "RX2", "SLIM RX2"},
7447 {"RX INT3_1 MIX1 INP1", "RX3", "SLIM RX3"},
7448 {"RX INT3_1 MIX1 INP1", "RX4", "SLIM RX4"},
7449 {"RX INT3_1 MIX1 INP1", "RX5", "SLIM RX5"},
7450 {"RX INT3_1 MIX1 INP1", "RX6", "SLIM RX6"},
7451 {"RX INT3_1 MIX1 INP1", "RX7", "SLIM RX7"},
7452 {"RX INT3_1 MIX1 INP1", "IIR0", "IIR0"},
7453 {"RX INT3_1 MIX1 INP1", "IIR1", "IIR1"},
7454 {"RX INT3_1 MIX1 INP2", "RX0", "SLIM RX0"},
7455 {"RX INT3_1 MIX1 INP2", "RX1", "SLIM RX1"},
7456 {"RX INT3_1 MIX1 INP2", "RX2", "SLIM RX2"},
7457 {"RX INT3_1 MIX1 INP2", "RX3", "SLIM RX3"},
7458 {"RX INT3_1 MIX1 INP2", "RX4", "SLIM RX4"},
7459 {"RX INT3_1 MIX1 INP2", "RX5", "SLIM RX5"},
7460 {"RX INT3_1 MIX1 INP2", "RX6", "SLIM RX6"},
7461 {"RX INT3_1 MIX1 INP2", "RX7", "SLIM RX7"},
7462 {"RX INT3_1 MIX1 INP2", "IIR0", "IIR0"},
7463 {"RX INT3_1 MIX1 INP2", "IIR1", "IIR1"},
7464
7465 {"RX INT4_1 MIX1 INP0", "RX0", "SLIM RX0"},
7466 {"RX INT4_1 MIX1 INP0", "RX1", "SLIM RX1"},
7467 {"RX INT4_1 MIX1 INP0", "RX2", "SLIM RX2"},
7468 {"RX INT4_1 MIX1 INP0", "RX3", "SLIM RX3"},
7469 {"RX INT4_1 MIX1 INP0", "RX4", "SLIM RX4"},
7470 {"RX INT4_1 MIX1 INP0", "RX5", "SLIM RX5"},
7471 {"RX INT4_1 MIX1 INP0", "RX6", "SLIM RX6"},
7472 {"RX INT4_1 MIX1 INP0", "RX7", "SLIM RX7"},
7473 {"RX INT4_1 MIX1 INP0", "IIR0", "IIR0"},
7474 {"RX INT4_1 MIX1 INP0", "IIR1", "IIR1"},
7475 {"RX INT4_1 MIX1 INP1", "RX0", "SLIM RX0"},
7476 {"RX INT4_1 MIX1 INP1", "RX1", "SLIM RX1"},
7477 {"RX INT4_1 MIX1 INP1", "RX2", "SLIM RX2"},
7478 {"RX INT4_1 MIX1 INP1", "RX3", "SLIM RX3"},
7479 {"RX INT4_1 MIX1 INP1", "RX4", "SLIM RX4"},
7480 {"RX INT4_1 MIX1 INP1", "RX5", "SLIM RX5"},
7481 {"RX INT4_1 MIX1 INP1", "RX6", "SLIM RX6"},
7482 {"RX INT4_1 MIX1 INP1", "RX7", "SLIM RX7"},
7483 {"RX INT4_1 MIX1 INP1", "IIR0", "IIR0"},
7484 {"RX INT4_1 MIX1 INP1", "IIR1", "IIR1"},
7485 {"RX INT4_1 MIX1 INP2", "RX0", "SLIM RX0"},
7486 {"RX INT4_1 MIX1 INP2", "RX1", "SLIM RX1"},
7487 {"RX INT4_1 MIX1 INP2", "RX2", "SLIM RX2"},
7488 {"RX INT4_1 MIX1 INP2", "RX3", "SLIM RX3"},
7489 {"RX INT4_1 MIX1 INP2", "RX4", "SLIM RX4"},
7490 {"RX INT4_1 MIX1 INP2", "RX5", "SLIM RX5"},
7491 {"RX INT4_1 MIX1 INP2", "RX6", "SLIM RX6"},
7492 {"RX INT4_1 MIX1 INP2", "RX7", "SLIM RX7"},
7493 {"RX INT4_1 MIX1 INP2", "IIR0", "IIR0"},
7494 {"RX INT4_1 MIX1 INP2", "IIR1", "IIR1"},
7495
7496 {"RX INT5_1 MIX1 INP0", "RX0", "SLIM RX0"},
7497 {"RX INT5_1 MIX1 INP0", "RX1", "SLIM RX1"},
7498 {"RX INT5_1 MIX1 INP0", "RX2", "SLIM RX2"},
7499 {"RX INT5_1 MIX1 INP0", "RX3", "SLIM RX3"},
7500 {"RX INT5_1 MIX1 INP0", "RX4", "SLIM RX4"},
7501 {"RX INT5_1 MIX1 INP0", "RX5", "SLIM RX5"},
7502 {"RX INT5_1 MIX1 INP0", "RX6", "SLIM RX6"},
7503 {"RX INT5_1 MIX1 INP0", "RX7", "SLIM RX7"},
7504 {"RX INT5_1 MIX1 INP0", "IIR0", "IIR0"},
7505 {"RX INT5_1 MIX1 INP0", "IIR1", "IIR1"},
7506 {"RX INT5_1 MIX1 INP1", "RX0", "SLIM RX0"},
7507 {"RX INT5_1 MIX1 INP1", "RX1", "SLIM RX1"},
7508 {"RX INT5_1 MIX1 INP1", "RX2", "SLIM RX2"},
7509 {"RX INT5_1 MIX1 INP1", "RX3", "SLIM RX3"},
7510 {"RX INT5_1 MIX1 INP1", "RX4", "SLIM RX4"},
7511 {"RX INT5_1 MIX1 INP1", "RX5", "SLIM RX5"},
7512 {"RX INT5_1 MIX1 INP1", "RX6", "SLIM RX6"},
7513 {"RX INT5_1 MIX1 INP1", "RX7", "SLIM RX7"},
7514 {"RX INT5_1 MIX1 INP1", "IIR0", "IIR0"},
7515 {"RX INT5_1 MIX1 INP1", "IIR1", "IIR1"},
7516 {"RX INT5_1 MIX1 INP2", "RX0", "SLIM RX0"},
7517 {"RX INT5_1 MIX1 INP2", "RX1", "SLIM RX1"},
7518 {"RX INT5_1 MIX1 INP2", "RX2", "SLIM RX2"},
7519 {"RX INT5_1 MIX1 INP2", "RX3", "SLIM RX3"},
7520 {"RX INT5_1 MIX1 INP2", "RX4", "SLIM RX4"},
7521 {"RX INT5_1 MIX1 INP2", "RX5", "SLIM RX5"},
7522 {"RX INT5_1 MIX1 INP2", "RX6", "SLIM RX6"},
7523 {"RX INT5_1 MIX1 INP2", "RX7", "SLIM RX7"},
7524 {"RX INT5_1 MIX1 INP2", "IIR0", "IIR0"},
7525 {"RX INT5_1 MIX1 INP2", "IIR1", "IIR1"},
7526
7527 {"RX INT6_1 MIX1 INP0", "RX0", "SLIM RX0"},
7528 {"RX INT6_1 MIX1 INP0", "RX1", "SLIM RX1"},
7529 {"RX INT6_1 MIX1 INP0", "RX2", "SLIM RX2"},
7530 {"RX INT6_1 MIX1 INP0", "RX3", "SLIM RX3"},
7531 {"RX INT6_1 MIX1 INP0", "RX4", "SLIM RX4"},
7532 {"RX INT6_1 MIX1 INP0", "RX5", "SLIM RX5"},
7533 {"RX INT6_1 MIX1 INP0", "RX6", "SLIM RX6"},
7534 {"RX INT6_1 MIX1 INP0", "RX7", "SLIM RX7"},
7535 {"RX INT6_1 MIX1 INP0", "IIR0", "IIR0"},
7536 {"RX INT6_1 MIX1 INP0", "IIR1", "IIR1"},
7537 {"RX INT6_1 MIX1 INP1", "RX0", "SLIM RX0"},
7538 {"RX INT6_1 MIX1 INP1", "RX1", "SLIM RX1"},
7539 {"RX INT6_1 MIX1 INP1", "RX2", "SLIM RX2"},
7540 {"RX INT6_1 MIX1 INP1", "RX3", "SLIM RX3"},
7541 {"RX INT6_1 MIX1 INP1", "RX4", "SLIM RX4"},
7542 {"RX INT6_1 MIX1 INP1", "RX5", "SLIM RX5"},
7543 {"RX INT6_1 MIX1 INP1", "RX6", "SLIM RX6"},
7544 {"RX INT6_1 MIX1 INP1", "RX7", "SLIM RX7"},
7545 {"RX INT6_1 MIX1 INP1", "IIR0", "IIR0"},
7546 {"RX INT6_1 MIX1 INP1", "IIR1", "IIR1"},
7547 {"RX INT6_1 MIX1 INP2", "RX0", "SLIM RX0"},
7548 {"RX INT6_1 MIX1 INP2", "RX1", "SLIM RX1"},
7549 {"RX INT6_1 MIX1 INP2", "RX2", "SLIM RX2"},
7550 {"RX INT6_1 MIX1 INP2", "RX3", "SLIM RX3"},
7551 {"RX INT6_1 MIX1 INP2", "RX4", "SLIM RX4"},
7552 {"RX INT6_1 MIX1 INP2", "RX5", "SLIM RX5"},
7553 {"RX INT6_1 MIX1 INP2", "RX6", "SLIM RX6"},
7554 {"RX INT6_1 MIX1 INP2", "RX7", "SLIM RX7"},
7555 {"RX INT6_1 MIX1 INP2", "IIR0", "IIR0"},
7556 {"RX INT6_1 MIX1 INP2", "IIR1", "IIR1"},
7557
7558 {"RX INT7_1 MIX1 INP0", "RX0", "SLIM RX0"},
7559 {"RX INT7_1 MIX1 INP0", "RX1", "SLIM RX1"},
7560 {"RX INT7_1 MIX1 INP0", "RX2", "SLIM RX2"},
7561 {"RX INT7_1 MIX1 INP0", "RX3", "SLIM RX3"},
7562 {"RX INT7_1 MIX1 INP0", "RX4", "SLIM RX4"},
7563 {"RX INT7_1 MIX1 INP0", "RX5", "SLIM RX5"},
7564 {"RX INT7_1 MIX1 INP0", "RX6", "SLIM RX6"},
7565 {"RX INT7_1 MIX1 INP0", "RX7", "SLIM RX7"},
7566 {"RX INT7_1 MIX1 INP0", "IIR0", "IIR0"},
7567 {"RX INT7_1 MIX1 INP0", "IIR1", "IIR1"},
7568 {"RX INT7_1 MIX1 INP1", "RX0", "SLIM RX0"},
7569 {"RX INT7_1 MIX1 INP1", "RX1", "SLIM RX1"},
7570 {"RX INT7_1 MIX1 INP1", "RX2", "SLIM RX2"},
7571 {"RX INT7_1 MIX1 INP1", "RX3", "SLIM RX3"},
7572 {"RX INT7_1 MIX1 INP1", "RX4", "SLIM RX4"},
7573 {"RX INT7_1 MIX1 INP1", "RX5", "SLIM RX5"},
7574 {"RX INT7_1 MIX1 INP1", "RX6", "SLIM RX6"},
7575 {"RX INT7_1 MIX1 INP1", "RX7", "SLIM RX7"},
7576 {"RX INT7_1 MIX1 INP1", "IIR0", "IIR0"},
7577 {"RX INT7_1 MIX1 INP1", "IIR1", "IIR1"},
7578 {"RX INT7_1 MIX1 INP2", "RX0", "SLIM RX0"},
7579 {"RX INT7_1 MIX1 INP2", "RX1", "SLIM RX1"},
7580 {"RX INT7_1 MIX1 INP2", "RX2", "SLIM RX2"},
7581 {"RX INT7_1 MIX1 INP2", "RX3", "SLIM RX3"},
7582 {"RX INT7_1 MIX1 INP2", "RX4", "SLIM RX4"},
7583 {"RX INT7_1 MIX1 INP2", "RX5", "SLIM RX5"},
7584 {"RX INT7_1 MIX1 INP2", "RX6", "SLIM RX6"},
7585 {"RX INT7_1 MIX1 INP2", "RX7", "SLIM RX7"},
7586 {"RX INT7_1 MIX1 INP2", "IIR0", "IIR0"},
7587 {"RX INT7_1 MIX1 INP2", "IIR1", "IIR1"},
7588
7589 {"RX INT8_1 MIX1 INP0", "RX0", "SLIM RX0"},
7590 {"RX INT8_1 MIX1 INP0", "RX1", "SLIM RX1"},
7591 {"RX INT8_1 MIX1 INP0", "RX2", "SLIM RX2"},
7592 {"RX INT8_1 MIX1 INP0", "RX3", "SLIM RX3"},
7593 {"RX INT8_1 MIX1 INP0", "RX4", "SLIM RX4"},
7594 {"RX INT8_1 MIX1 INP0", "RX5", "SLIM RX5"},
7595 {"RX INT8_1 MIX1 INP0", "RX6", "SLIM RX6"},
7596 {"RX INT8_1 MIX1 INP0", "RX7", "SLIM RX7"},
7597 {"RX INT8_1 MIX1 INP0", "IIR0", "IIR0"},
7598 {"RX INT8_1 MIX1 INP0", "IIR1", "IIR1"},
7599 {"RX INT8_1 MIX1 INP1", "RX0", "SLIM RX0"},
7600 {"RX INT8_1 MIX1 INP1", "RX1", "SLIM RX1"},
7601 {"RX INT8_1 MIX1 INP1", "RX2", "SLIM RX2"},
7602 {"RX INT8_1 MIX1 INP1", "RX3", "SLIM RX3"},
7603 {"RX INT8_1 MIX1 INP1", "RX4", "SLIM RX4"},
7604 {"RX INT8_1 MIX1 INP1", "RX5", "SLIM RX5"},
7605 {"RX INT8_1 MIX1 INP1", "RX6", "SLIM RX6"},
7606 {"RX INT8_1 MIX1 INP1", "RX7", "SLIM RX7"},
7607 {"RX INT8_1 MIX1 INP1", "IIR0", "IIR0"},
7608 {"RX INT8_1 MIX1 INP1", "IIR1", "IIR1"},
7609 {"RX INT8_1 MIX1 INP2", "RX0", "SLIM RX0"},
7610 {"RX INT8_1 MIX1 INP2", "RX1", "SLIM RX1"},
7611 {"RX INT8_1 MIX1 INP2", "RX2", "SLIM RX2"},
7612 {"RX INT8_1 MIX1 INP2", "RX3", "SLIM RX3"},
7613 {"RX INT8_1 MIX1 INP2", "RX4", "SLIM RX4"},
7614 {"RX INT8_1 MIX1 INP2", "RX5", "SLIM RX5"},
7615 {"RX INT8_1 MIX1 INP2", "RX6", "SLIM RX6"},
7616 {"RX INT8_1 MIX1 INP2", "RX7", "SLIM RX7"},
7617 {"RX INT8_1 MIX1 INP2", "IIR0", "IIR0"},
7618 {"RX INT8_1 MIX1 INP2", "IIR1", "IIR1"},
7619
7620 /* SRC0, SRC1 inputs to Sidetone RX Mixer
7621 * on RX0, RX1, RX2, RX3, RX4 and RX7 chains
7622 */
7623 {"IIR0", NULL, "IIR0 INP0 MUX"},
7624 {"IIR0 INP0 MUX", "DEC0", "ADC MUX0"},
7625 {"IIR0 INP0 MUX", "DEC1", "ADC MUX1"},
7626 {"IIR0 INP0 MUX", "DEC2", "ADC MUX2"},
7627 {"IIR0 INP0 MUX", "DEC3", "ADC MUX3"},
7628 {"IIR0 INP0 MUX", "DEC4", "ADC MUX4"},
7629 {"IIR0 INP0 MUX", "DEC5", "ADC MUX5"},
7630 {"IIR0 INP0 MUX", "DEC6", "ADC MUX6"},
7631 {"IIR0 INP0 MUX", "DEC7", "ADC MUX7"},
7632 {"IIR0 INP0 MUX", "DEC8", "ADC MUX8"},
7633 {"IIR0 INP0 MUX", "RX0", "SLIM RX0"},
7634 {"IIR0 INP0 MUX", "RX1", "SLIM RX1"},
7635 {"IIR0 INP0 MUX", "RX2", "SLIM RX2"},
7636 {"IIR0 INP0 MUX", "RX3", "SLIM RX3"},
7637 {"IIR0 INP0 MUX", "RX4", "SLIM RX4"},
7638 {"IIR0 INP0 MUX", "RX5", "SLIM RX5"},
7639 {"IIR0 INP0 MUX", "RX6", "SLIM RX6"},
7640 {"IIR0 INP0 MUX", "RX7", "SLIM RX7"},
7641 {"IIR0", NULL, "IIR0 INP1 MUX"},
7642 {"IIR0 INP1 MUX", "DEC0", "ADC MUX0"},
7643 {"IIR0 INP1 MUX", "DEC1", "ADC MUX1"},
7644 {"IIR0 INP1 MUX", "DEC2", "ADC MUX2"},
7645 {"IIR0 INP1 MUX", "DEC3", "ADC MUX3"},
7646 {"IIR0 INP1 MUX", "DEC4", "ADC MUX4"},
7647 {"IIR0 INP1 MUX", "DEC5", "ADC MUX5"},
7648 {"IIR0 INP1 MUX", "DEC6", "ADC MUX6"},
7649 {"IIR0 INP1 MUX", "DEC7", "ADC MUX7"},
7650 {"IIR0 INP1 MUX", "DEC8", "ADC MUX8"},
7651 {"IIR0 INP1 MUX", "RX0", "SLIM RX0"},
7652 {"IIR0 INP1 MUX", "RX1", "SLIM RX1"},
7653 {"IIR0 INP1 MUX", "RX2", "SLIM RX2"},
7654 {"IIR0 INP1 MUX", "RX3", "SLIM RX3"},
7655 {"IIR0 INP1 MUX", "RX4", "SLIM RX4"},
7656 {"IIR0 INP1 MUX", "RX5", "SLIM RX5"},
7657 {"IIR0 INP1 MUX", "RX6", "SLIM RX6"},
7658 {"IIR0 INP1 MUX", "RX7", "SLIM RX7"},
7659 {"IIR0", NULL, "IIR0 INP2 MUX"},
7660 {"IIR0 INP2 MUX", "DEC0", "ADC MUX0"},
7661 {"IIR0 INP2 MUX", "DEC1", "ADC MUX1"},
7662 {"IIR0 INP2 MUX", "DEC2", "ADC MUX2"},
7663 {"IIR0 INP2 MUX", "DEC3", "ADC MUX3"},
7664 {"IIR0 INP2 MUX", "DEC4", "ADC MUX4"},
7665 {"IIR0 INP2 MUX", "DEC5", "ADC MUX5"},
7666 {"IIR0 INP2 MUX", "DEC6", "ADC MUX6"},
7667 {"IIR0 INP2 MUX", "DEC7", "ADC MUX7"},
7668 {"IIR0 INP2 MUX", "DEC8", "ADC MUX8"},
7669 {"IIR0 INP2 MUX", "RX0", "SLIM RX0"},
7670 {"IIR0 INP2 MUX", "RX1", "SLIM RX1"},
7671 {"IIR0 INP2 MUX", "RX2", "SLIM RX2"},
7672 {"IIR0 INP2 MUX", "RX3", "SLIM RX3"},
7673 {"IIR0 INP2 MUX", "RX4", "SLIM RX4"},
7674 {"IIR0 INP2 MUX", "RX5", "SLIM RX5"},
7675 {"IIR0 INP2 MUX", "RX6", "SLIM RX6"},
7676 {"IIR0 INP2 MUX", "RX7", "SLIM RX7"},
7677 {"IIR0", NULL, "IIR0 INP3 MUX"},
7678 {"IIR0 INP3 MUX", "DEC0", "ADC MUX0"},
7679 {"IIR0 INP3 MUX", "DEC1", "ADC MUX1"},
7680 {"IIR0 INP3 MUX", "DEC2", "ADC MUX2"},
7681 {"IIR0 INP3 MUX", "DEC3", "ADC MUX3"},
7682 {"IIR0 INP3 MUX", "DEC4", "ADC MUX4"},
7683 {"IIR0 INP3 MUX", "DEC5", "ADC MUX5"},
7684 {"IIR0 INP3 MUX", "DEC6", "ADC MUX6"},
7685 {"IIR0 INP3 MUX", "DEC7", "ADC MUX7"},
7686 {"IIR0 INP3 MUX", "DEC8", "ADC MUX8"},
7687 {"IIR0 INP3 MUX", "RX0", "SLIM RX0"},
7688 {"IIR0 INP3 MUX", "RX1", "SLIM RX1"},
7689 {"IIR0 INP3 MUX", "RX2", "SLIM RX2"},
7690 {"IIR0 INP3 MUX", "RX3", "SLIM RX3"},
7691 {"IIR0 INP3 MUX", "RX4", "SLIM RX4"},
7692 {"IIR0 INP3 MUX", "RX5", "SLIM RX5"},
7693 {"IIR0 INP3 MUX", "RX6", "SLIM RX6"},
7694 {"IIR0 INP3 MUX", "RX7", "SLIM RX7"},
7695
7696 {"IIR1", NULL, "IIR1 INP0 MUX"},
7697 {"IIR1 INP0 MUX", "DEC0", "ADC MUX0"},
7698 {"IIR1 INP0 MUX", "DEC1", "ADC MUX1"},
7699 {"IIR1 INP0 MUX", "DEC2", "ADC MUX2"},
7700 {"IIR1 INP0 MUX", "DEC3", "ADC MUX3"},
7701 {"IIR1 INP0 MUX", "DEC4", "ADC MUX4"},
7702 {"IIR1 INP0 MUX", "DEC5", "ADC MUX5"},
7703 {"IIR1 INP0 MUX", "DEC6", "ADC MUX6"},
7704 {"IIR1 INP0 MUX", "DEC7", "ADC MUX7"},
7705 {"IIR1 INP0 MUX", "DEC8", "ADC MUX8"},
7706 {"IIR1 INP0 MUX", "RX0", "SLIM RX0"},
7707 {"IIR1 INP0 MUX", "RX1", "SLIM RX1"},
7708 {"IIR1 INP0 MUX", "RX2", "SLIM RX2"},
7709 {"IIR1 INP0 MUX", "RX3", "SLIM RX3"},
7710 {"IIR1 INP0 MUX", "RX4", "SLIM RX4"},
7711 {"IIR1 INP0 MUX", "RX5", "SLIM RX5"},
7712 {"IIR1 INP0 MUX", "RX6", "SLIM RX6"},
7713 {"IIR1 INP0 MUX", "RX7", "SLIM RX7"},
7714 {"IIR1", NULL, "IIR1 INP1 MUX"},
7715 {"IIR1 INP1 MUX", "DEC0", "ADC MUX0"},
7716 {"IIR1 INP1 MUX", "DEC1", "ADC MUX1"},
7717 {"IIR1 INP1 MUX", "DEC2", "ADC MUX2"},
7718 {"IIR1 INP1 MUX", "DEC3", "ADC MUX3"},
7719 {"IIR1 INP1 MUX", "DEC4", "ADC MUX4"},
7720 {"IIR1 INP1 MUX", "DEC5", "ADC MUX5"},
7721 {"IIR1 INP1 MUX", "DEC6", "ADC MUX6"},
7722 {"IIR1 INP1 MUX", "DEC7", "ADC MUX7"},
7723 {"IIR1 INP1 MUX", "DEC8", "ADC MUX8"},
7724 {"IIR1 INP1 MUX", "RX0", "SLIM RX0"},
7725 {"IIR1 INP1 MUX", "RX1", "SLIM RX1"},
7726 {"IIR1 INP1 MUX", "RX2", "SLIM RX2"},
7727 {"IIR1 INP1 MUX", "RX3", "SLIM RX3"},
7728 {"IIR1 INP1 MUX", "RX4", "SLIM RX4"},
7729 {"IIR1 INP1 MUX", "RX5", "SLIM RX5"},
7730 {"IIR1 INP1 MUX", "RX6", "SLIM RX6"},
7731 {"IIR1 INP1 MUX", "RX7", "SLIM RX7"},
7732 {"IIR1", NULL, "IIR1 INP2 MUX"},
7733 {"IIR1 INP2 MUX", "DEC0", "ADC MUX0"},
7734 {"IIR1 INP2 MUX", "DEC1", "ADC MUX1"},
7735 {"IIR1 INP2 MUX", "DEC2", "ADC MUX2"},
7736 {"IIR1 INP2 MUX", "DEC3", "ADC MUX3"},
7737 {"IIR1 INP2 MUX", "DEC4", "ADC MUX4"},
7738 {"IIR1 INP2 MUX", "DEC5", "ADC MUX5"},
7739 {"IIR1 INP2 MUX", "DEC6", "ADC MUX6"},
7740 {"IIR1 INP2 MUX", "DEC7", "ADC MUX7"},
7741 {"IIR1 INP2 MUX", "DEC8", "ADC MUX8"},
7742 {"IIR1 INP2 MUX", "RX0", "SLIM RX0"},
7743 {"IIR1 INP2 MUX", "RX1", "SLIM RX1"},
7744 {"IIR1 INP2 MUX", "RX2", "SLIM RX2"},
7745 {"IIR1 INP2 MUX", "RX3", "SLIM RX3"},
7746 {"IIR1 INP2 MUX", "RX4", "SLIM RX4"},
7747 {"IIR1 INP2 MUX", "RX5", "SLIM RX5"},
7748 {"IIR1 INP2 MUX", "RX6", "SLIM RX6"},
7749 {"IIR1 INP2 MUX", "RX7", "SLIM RX7"},
7750 {"IIR1", NULL, "IIR1 INP3 MUX"},
7751 {"IIR1 INP3 MUX", "DEC0", "ADC MUX0"},
7752 {"IIR1 INP3 MUX", "DEC1", "ADC MUX1"},
7753 {"IIR1 INP3 MUX", "DEC2", "ADC MUX2"},
7754 {"IIR1 INP3 MUX", "DEC3", "ADC MUX3"},
7755 {"IIR1 INP3 MUX", "DEC4", "ADC MUX4"},
7756 {"IIR1 INP3 MUX", "DEC5", "ADC MUX5"},
7757 {"IIR1 INP3 MUX", "DEC6", "ADC MUX6"},
7758 {"IIR1 INP3 MUX", "DEC7", "ADC MUX7"},
7759 {"IIR1 INP3 MUX", "DEC8", "ADC MUX8"},
7760 {"IIR1 INP3 MUX", "RX0", "SLIM RX0"},
7761 {"IIR1 INP3 MUX", "RX1", "SLIM RX1"},
7762 {"IIR1 INP3 MUX", "RX2", "SLIM RX2"},
7763 {"IIR1 INP3 MUX", "RX3", "SLIM RX3"},
7764 {"IIR1 INP3 MUX", "RX4", "SLIM RX4"},
7765 {"IIR1 INP3 MUX", "RX5", "SLIM RX5"},
7766 {"IIR1 INP3 MUX", "RX6", "SLIM RX6"},
7767 {"IIR1 INP3 MUX", "RX7", "SLIM RX7"},
7768
7769 {"SRC0", NULL, "IIR0"},
7770 {"SRC1", NULL, "IIR1"},
7771 {"RX INT0 MIX2 INP", "SRC0", "SRC0"},
7772 {"RX INT0 MIX2 INP", "SRC1", "SRC1"},
7773 {"RX INT1 MIX2 INP", "SRC0", "SRC0"},
7774 {"RX INT1 MIX2 INP", "SRC1", "SRC1"},
7775 {"RX INT2 MIX2 INP", "SRC0", "SRC0"},
7776 {"RX INT2 MIX2 INP", "SRC1", "SRC1"},
7777 {"RX INT3 MIX2 INP", "SRC0", "SRC0"},
7778 {"RX INT3 MIX2 INP", "SRC1", "SRC1"},
7779 {"RX INT4 MIX2 INP", "SRC0", "SRC0"},
7780 {"RX INT4 MIX2 INP", "SRC1", "SRC1"},
7781 {"RX INT7 MIX2 INP", "SRC0", "SRC0"},
7782 {"RX INT7 MIX2 INP", "SRC1", "SRC1"},
7783};
7784
7785static int tasha_amic_pwr_lvl_get(struct snd_kcontrol *kcontrol,
7786 struct snd_ctl_elem_value *ucontrol)
7787{
7788 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
7789 u16 amic_reg;
7790
7791 if (!strcmp(kcontrol->id.name, "AMIC_1_2 PWR MODE"))
7792 amic_reg = WCD9335_ANA_AMIC1;
7793 if (!strcmp(kcontrol->id.name, "AMIC_3_4 PWR MODE"))
7794 amic_reg = WCD9335_ANA_AMIC3;
7795 if (!strcmp(kcontrol->id.name, "AMIC_5_6 PWR MODE"))
7796 amic_reg = WCD9335_ANA_AMIC5;
7797
7798 ucontrol->value.integer.value[0] =
7799 (snd_soc_read(codec, amic_reg) & WCD9335_AMIC_PWR_LVL_MASK) >>
7800 WCD9335_AMIC_PWR_LVL_SHIFT;
7801
7802 return 0;
7803}
7804
7805static int tasha_amic_pwr_lvl_put(struct snd_kcontrol *kcontrol,
7806 struct snd_ctl_elem_value *ucontrol)
7807{
7808 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
7809 u32 mode_val;
7810 u16 amic_reg;
7811
7812 mode_val = ucontrol->value.enumerated.item[0];
7813
7814 dev_dbg(codec->dev, "%s: mode: %d\n",
7815 __func__, mode_val);
7816
7817 if (!strcmp(kcontrol->id.name, "AMIC_1_2 PWR MODE"))
7818 amic_reg = WCD9335_ANA_AMIC1;
7819 if (!strcmp(kcontrol->id.name, "AMIC_3_4 PWR MODE"))
7820 amic_reg = WCD9335_ANA_AMIC3;
7821 if (!strcmp(kcontrol->id.name, "AMIC_5_6 PWR MODE"))
7822 amic_reg = WCD9335_ANA_AMIC5;
7823
7824 snd_soc_update_bits(codec, amic_reg, WCD9335_AMIC_PWR_LVL_MASK,
7825 mode_val << WCD9335_AMIC_PWR_LVL_SHIFT);
7826
7827 return 0;
7828}
7829
7830static int tasha_rx_hph_mode_get(struct snd_kcontrol *kcontrol,
7831 struct snd_ctl_elem_value *ucontrol)
7832{
7833 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
7834 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
7835
7836 ucontrol->value.integer.value[0] = tasha->hph_mode;
7837 return 0;
7838}
7839
7840static int tasha_rx_hph_mode_put(struct snd_kcontrol *kcontrol,
7841 struct snd_ctl_elem_value *ucontrol)
7842{
7843 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
7844 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
7845 u32 mode_val;
7846
7847 mode_val = ucontrol->value.enumerated.item[0];
7848
7849 dev_dbg(codec->dev, "%s: mode: %d\n",
7850 __func__, mode_val);
7851
7852 if (mode_val == 0) {
7853 dev_warn(codec->dev, "%s:Invalid HPH Mode, default to Cls-H HiFi\n",
7854 __func__);
7855 mode_val = CLS_H_HIFI;
7856 }
7857 tasha->hph_mode = mode_val;
7858 return 0;
7859}
7860
7861static const char *const tasha_conn_mad_text[] = {
7862 "NOTUSED1", "ADC1", "ADC2", "ADC3", "ADC4", "ADC5", "ADC6",
7863 "NOTUSED2", "DMIC0", "DMIC1", "DMIC2", "DMIC3", "DMIC4",
7864 "DMIC5", "NOTUSED3", "NOTUSED4"
7865};
7866
7867static const struct soc_enum tasha_conn_mad_enum =
7868 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tasha_conn_mad_text),
7869 tasha_conn_mad_text);
7870
7871static int tasha_enable_ldo_h_get(struct snd_kcontrol *kcontrol,
7872 struct snd_ctl_elem_value *ucontrol)
7873{
7874 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
7875 u8 val = 0;
7876
7877 if (codec)
7878 val = snd_soc_read(codec, WCD9335_LDOH_MODE) & 0x80;
7879
7880 ucontrol->value.integer.value[0] = !!val;
7881
7882 return 0;
7883}
7884
7885static int tasha_enable_ldo_h_put(struct snd_kcontrol *kcontrol,
7886 struct snd_ctl_elem_value *ucontrol)
7887{
7888 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
7889 int value = ucontrol->value.integer.value[0];
7890 bool enable;
7891
7892 enable = !!value;
7893 if (codec)
7894 tasha_codec_enable_standalone_ldo_h(codec, enable);
7895
7896 return 0;
7897}
7898
7899static int tasha_mad_input_get(struct snd_kcontrol *kcontrol,
7900 struct snd_ctl_elem_value *ucontrol)
7901{
7902 u8 tasha_mad_input;
7903 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
7904
7905 tasha_mad_input = snd_soc_read(codec,
7906 WCD9335_SOC_MAD_INP_SEL) & 0x0F;
7907 ucontrol->value.integer.value[0] = tasha_mad_input;
7908
7909 dev_dbg(codec->dev,
7910 "%s: tasha_mad_input = %s\n", __func__,
7911 tasha_conn_mad_text[tasha_mad_input]);
7912 return 0;
7913}
7914
7915static int tasha_mad_input_put(struct snd_kcontrol *kcontrol,
7916 struct snd_ctl_elem_value *ucontrol)
7917{
7918 u8 tasha_mad_input;
7919 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
7920 struct snd_soc_card *card = codec->component.card;
7921 char mad_amic_input_widget[6];
7922 const char *mad_input_widget;
7923 const char *source_widget = NULL;
7924 u32 adc, i, mic_bias_found = 0;
7925 int ret = 0;
7926 char *mad_input;
7927
7928 tasha_mad_input = ucontrol->value.integer.value[0];
7929
Karthikeyan Mani63955b42016-12-14 11:46:35 -08007930 if (tasha_mad_input >= ARRAY_SIZE(tasha_conn_mad_text)) {
7931 dev_err(codec->dev,
7932 "%s: tasha_mad_input = %d out of bounds\n",
7933 __func__, tasha_mad_input);
7934 return -EINVAL;
7935 }
7936
Banajit Goswamide8271c2017-01-18 00:28:59 -08007937 if (!strcmp(tasha_conn_mad_text[tasha_mad_input], "NOTUSED1") ||
7938 !strcmp(tasha_conn_mad_text[tasha_mad_input], "NOTUSED2") ||
7939 !strcmp(tasha_conn_mad_text[tasha_mad_input], "NOTUSED3") ||
7940 !strcmp(tasha_conn_mad_text[tasha_mad_input], "NOTUSED4")) {
7941 dev_err(codec->dev,
7942 "%s: Unsupported tasha_mad_input = %s\n",
7943 __func__, tasha_conn_mad_text[tasha_mad_input]);
7944 return -EINVAL;
7945 }
7946
7947 if (strnstr(tasha_conn_mad_text[tasha_mad_input],
7948 "ADC", sizeof("ADC"))) {
7949 mad_input = strpbrk(tasha_conn_mad_text[tasha_mad_input],
7950 "123456");
7951 if (!mad_input) {
7952 dev_err(codec->dev, "%s: Invalid MAD input %s\n",
7953 __func__,
7954 tasha_conn_mad_text[tasha_mad_input]);
7955 return -EINVAL;
7956 }
7957 ret = kstrtouint(mad_input, 10, &adc);
7958 if ((ret < 0) || (adc > 6)) {
7959 dev_err(codec->dev,
7960 "%s: Invalid ADC = %s\n", __func__,
7961 tasha_conn_mad_text[tasha_mad_input]);
7962 ret = -EINVAL;
7963 }
7964
7965 snprintf(mad_amic_input_widget, 6, "%s%u", "AMIC", adc);
7966
7967 mad_input_widget = mad_amic_input_widget;
7968 } else {
7969 /* DMIC type input widget*/
7970 mad_input_widget = tasha_conn_mad_text[tasha_mad_input];
7971 }
7972
7973 dev_dbg(codec->dev,
7974 "%s: tasha input widget = %s\n", __func__,
7975 mad_input_widget);
7976
7977 for (i = 0; i < card->num_of_dapm_routes; i++) {
7978 if (!strcmp(card->of_dapm_routes[i].sink, mad_input_widget)) {
7979 source_widget = card->of_dapm_routes[i].source;
7980 if (!source_widget) {
7981 dev_err(codec->dev,
7982 "%s: invalid source widget\n",
7983 __func__);
7984 return -EINVAL;
7985 }
7986
7987 if (strnstr(source_widget,
7988 "MIC BIAS1", sizeof("MIC BIAS1"))) {
7989 mic_bias_found = 1;
7990 break;
7991 } else if (strnstr(source_widget,
7992 "MIC BIAS2", sizeof("MIC BIAS2"))) {
7993 mic_bias_found = 2;
7994 break;
7995 } else if (strnstr(source_widget,
7996 "MIC BIAS3", sizeof("MIC BIAS3"))) {
7997 mic_bias_found = 3;
7998 break;
7999 } else if (strnstr(source_widget,
8000 "MIC BIAS4", sizeof("MIC BIAS4"))) {
8001 mic_bias_found = 4;
8002 break;
8003 }
8004 }
8005 }
8006
8007 if (!mic_bias_found) {
8008 dev_err(codec->dev,
8009 "%s: mic bias source not found for input = %s\n",
8010 __func__, mad_input_widget);
8011 return -EINVAL;
8012 }
8013
8014 dev_dbg(codec->dev,
8015 "%s: mic_bias found = %d\n", __func__,
8016 mic_bias_found);
8017
8018 snd_soc_update_bits(codec, WCD9335_SOC_MAD_INP_SEL,
8019 0x0F, tasha_mad_input);
8020 snd_soc_update_bits(codec, WCD9335_ANA_MAD_SETUP,
8021 0x07, mic_bias_found);
8022
8023 return 0;
8024}
8025
8026static int tasha_pinctl_mode_get(struct snd_kcontrol *kcontrol,
8027 struct snd_ctl_elem_value *ucontrol)
8028{
8029 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
8030 u16 ctl_reg;
8031 u8 reg_val, pinctl_position;
8032
8033 pinctl_position = ((struct soc_multi_mixer_control *)
8034 kcontrol->private_value)->shift;
8035 switch (pinctl_position >> 3) {
8036 case 0:
8037 ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_0;
8038 break;
8039 case 1:
8040 ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_1;
8041 break;
8042 case 2:
8043 ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_2;
8044 break;
8045 case 3:
8046 ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_3;
8047 break;
8048 default:
8049 dev_err(codec->dev, "%s: Invalid pinctl position = %d\n",
8050 __func__, pinctl_position);
8051 return -EINVAL;
8052 }
8053
8054 reg_val = snd_soc_read(codec, ctl_reg);
8055 reg_val = (reg_val >> (pinctl_position & 0x07)) & 0x1;
8056 ucontrol->value.integer.value[0] = reg_val;
8057
8058 return 0;
8059}
8060
8061static int tasha_pinctl_mode_put(struct snd_kcontrol *kcontrol,
8062 struct snd_ctl_elem_value *ucontrol)
8063{
8064 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
8065 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
8066 u16 ctl_reg, cfg_reg;
8067 u8 ctl_val, cfg_val, pinctl_position, pinctl_mode, mask;
8068
8069 /* 1- high or low; 0- high Z */
8070 pinctl_mode = ucontrol->value.integer.value[0];
8071 pinctl_position = ((struct soc_multi_mixer_control *)
8072 kcontrol->private_value)->shift;
8073
8074 switch (pinctl_position >> 3) {
8075 case 0:
8076 ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_0;
8077 break;
8078 case 1:
8079 ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_1;
8080 break;
8081 case 2:
8082 ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_2;
8083 break;
8084 case 3:
8085 ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_3;
8086 break;
8087 default:
8088 dev_err(codec->dev, "%s: Invalid pinctl position = %d\n",
8089 __func__, pinctl_position);
8090 return -EINVAL;
8091 }
8092
8093 ctl_val = pinctl_mode << (pinctl_position & 0x07);
8094 mask = 1 << (pinctl_position & 0x07);
8095 snd_soc_update_bits(codec, ctl_reg, mask, ctl_val);
8096
8097 cfg_reg = WCD9335_TLMM_BIST_MODE_PINCFG + pinctl_position;
8098 if (!pinctl_mode) {
8099 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS)
8100 cfg_val = 0x4;
8101 else
8102 cfg_val = 0xC;
8103 } else {
8104 cfg_val = 0;
8105 }
8106 snd_soc_update_bits(codec, cfg_reg, 0x07, cfg_val);
8107
8108 dev_dbg(codec->dev, "%s: reg=0x%x mask=0x%x val=%d reg=0x%x val=%d\n",
8109 __func__, ctl_reg, mask, ctl_val, cfg_reg, cfg_val);
8110
8111 return 0;
8112}
8113
8114static void wcd_vbat_adc_out_config_2_0(struct wcd_vbat *vbat,
8115 struct snd_soc_codec *codec)
8116{
8117 u8 val1, val2;
8118
8119 /*
8120 * Measure dcp1 by using "ALT" branch of band gap
8121 * voltage(Vbg) and use it in FAST mode
8122 */
8123 snd_soc_update_bits(codec, WCD9335_BIAS_CTL, 0x82, 0x82);
8124 snd_soc_update_bits(codec, WCD9335_CDC_VBAT_VBAT_PATH_CTL, 0x10, 0x10);
8125 snd_soc_update_bits(codec, WCD9335_CDC_VBAT_VBAT_DEBUG1, 0x01, 0x01);
8126 snd_soc_update_bits(codec, WCD9335_ANA_VBADC, 0x80, 0x80);
8127 snd_soc_update_bits(codec, WCD9335_VBADC_SUBBLOCK_EN, 0x20, 0x00);
8128
8129 snd_soc_update_bits(codec, WCD9335_VBADC_FE_CTRL, 0x20, 0x20);
8130 /* Wait 100 usec after calibration select as Vbg */
8131 usleep_range(100, 110);
8132
8133 snd_soc_update_bits(codec, WCD9335_VBADC_ADC_IO, 0x40, 0x40);
8134 val1 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTMSB);
8135 val2 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTLSB);
8136 snd_soc_update_bits(codec, WCD9335_VBADC_ADC_IO, 0x40, 0x00);
8137
8138 vbat->dcp1 = (((val1 & 0xFF) << 3) | (val2 & 0x07));
8139
8140 snd_soc_update_bits(codec, WCD9335_BIAS_CTL, 0x40, 0x40);
8141 /* Wait 100 usec after selecting Vbg as 1.05V */
8142 usleep_range(100, 110);
8143
8144 snd_soc_update_bits(codec, WCD9335_VBADC_ADC_IO, 0x40, 0x40);
8145 val1 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTMSB);
8146 val2 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTLSB);
8147 snd_soc_update_bits(codec, WCD9335_VBADC_ADC_IO, 0x40, 0x00);
8148
8149 vbat->dcp2 = (((val1 & 0xFF) << 3) | (val2 & 0x07));
8150
8151 dev_dbg(codec->dev, "%s: dcp1:0x%x, dcp2:0x%x\n",
8152 __func__, vbat->dcp1, vbat->dcp2);
8153
8154 snd_soc_write(codec, WCD9335_BIAS_CTL, 0x28);
8155 /* Wait 100 usec after selecting Vbg as 0.85V */
8156 usleep_range(100, 110);
8157
8158 snd_soc_update_bits(codec, WCD9335_VBADC_FE_CTRL, 0x20, 0x00);
8159 snd_soc_update_bits(codec, WCD9335_VBADC_SUBBLOCK_EN, 0x20, 0x20);
8160 snd_soc_update_bits(codec, WCD9335_ANA_VBADC, 0x80, 0x00);
8161
8162 snd_soc_update_bits(codec, WCD9335_CDC_VBAT_VBAT_PATH_CTL, 0x10, 0x00);
8163 snd_soc_update_bits(codec, WCD9335_CDC_VBAT_VBAT_DEBUG1, 0x01, 0x00);
8164}
8165
8166static void wcd_vbat_adc_out_config_1_x(struct wcd_vbat *vbat,
8167 struct snd_soc_codec *codec)
8168{
8169 u8 val1, val2;
8170
8171 /*
8172 * Measure dcp1 by applying band gap voltage(Vbg)
8173 * of 0.85V
8174 */
8175 snd_soc_write(codec, WCD9335_ANA_BIAS, 0x20);
8176 snd_soc_write(codec, WCD9335_BIAS_CTL, 0x28);
8177 snd_soc_write(codec, WCD9335_BIAS_VBG_FINE_ADJ, 0x05);
8178 snd_soc_write(codec, WCD9335_ANA_BIAS, 0xA0);
8179 /* Wait 2 sec after enabling band gap bias */
8180 usleep_range(2000000, 2000100);
8181
8182 snd_soc_write(codec, WCD9335_ANA_CLK_TOP, 0x82);
8183 snd_soc_write(codec, WCD9335_ANA_CLK_TOP, 0x87);
8184 snd_soc_update_bits(codec, WCD9335_CDC_VBAT_VBAT_PATH_CTL, 0x10, 0x10);
8185 snd_soc_write(codec, WCD9335_CDC_VBAT_VBAT_CFG, 0x0D);
8186 snd_soc_write(codec, WCD9335_CDC_VBAT_VBAT_DEBUG1, 0x01);
8187
8188 snd_soc_write(codec, WCD9335_ANA_VBADC, 0x80);
8189 snd_soc_write(codec, WCD9335_VBADC_SUBBLOCK_EN, 0xDE);
8190 snd_soc_write(codec, WCD9335_VBADC_FE_CTRL, 0x3C);
8191 /* Wait 1 msec after calibration select as Vbg */
8192 usleep_range(1000, 1100);
8193
8194 snd_soc_write(codec, WCD9335_VBADC_ADC_IO, 0xC0);
8195 val1 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTMSB);
8196 val2 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTLSB);
8197 snd_soc_write(codec, WCD9335_VBADC_ADC_IO, 0x80);
8198
8199 vbat->dcp1 = (((val1 & 0xFF) << 3) | (val2 & 0x07));
8200
8201 /*
8202 * Measure dcp2 by applying band gap voltage(Vbg)
8203 * of 1.05V
8204 */
8205 snd_soc_write(codec, WCD9335_ANA_BIAS, 0x80);
8206 snd_soc_write(codec, WCD9335_ANA_BIAS, 0xC0);
8207 snd_soc_write(codec, WCD9335_BIAS_CTL, 0x68);
8208 /* Wait 2 msec after selecting Vbg as 1.05V */
8209 usleep_range(2000, 2100);
8210
8211 snd_soc_write(codec, WCD9335_ANA_BIAS, 0x80);
8212 /* Wait 1 sec after enabling band gap bias */
8213 usleep_range(1000000, 1000100);
8214
8215 snd_soc_write(codec, WCD9335_VBADC_ADC_IO, 0xC0);
8216 val1 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTMSB);
8217 val2 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTLSB);
8218 snd_soc_write(codec, WCD9335_VBADC_ADC_IO, 0x80);
8219
8220 vbat->dcp2 = (((val1 & 0xFF) << 3) | (val2 & 0x07));
8221
8222 dev_dbg(codec->dev, "%s: dcp1:0x%x, dcp2:0x%x\n",
8223 __func__, vbat->dcp1, vbat->dcp2);
8224
8225 /* Reset the Vbat ADC configuration */
8226 snd_soc_write(codec, WCD9335_ANA_BIAS, 0x80);
8227 snd_soc_write(codec, WCD9335_ANA_BIAS, 0xC0);
8228
8229 snd_soc_write(codec, WCD9335_BIAS_CTL, 0x28);
8230 /* Wait 2 msec after selecting Vbg as 0.85V */
8231 usleep_range(2000, 2100);
8232
8233 snd_soc_write(codec, WCD9335_ANA_BIAS, 0xA0);
8234 /* Wait 1 sec after enabling band gap bias */
8235 usleep_range(1000000, 1000100);
8236
8237 snd_soc_write(codec, WCD9335_VBADC_FE_CTRL, 0x1C);
8238 snd_soc_write(codec, WCD9335_VBADC_SUBBLOCK_EN, 0xFE);
8239 snd_soc_write(codec, WCD9335_VBADC_ADC_IO, 0x80);
8240 snd_soc_write(codec, WCD9335_ANA_VBADC, 0x00);
8241
8242 snd_soc_write(codec, WCD9335_CDC_VBAT_VBAT_DEBUG1, 0x00);
8243 snd_soc_write(codec, WCD9335_CDC_VBAT_VBAT_PATH_CTL, 0x00);
8244 snd_soc_write(codec, WCD9335_CDC_VBAT_VBAT_CFG, 0x0A);
8245}
8246
8247static void wcd_vbat_adc_out_config(struct wcd_vbat *vbat,
8248 struct snd_soc_codec *codec)
8249{
8250 struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent);
8251
8252 if (!vbat->adc_config) {
8253 tasha_cdc_mclk_enable(codec, true, false);
8254
8255 if (TASHA_IS_2_0(wcd9xxx))
8256 wcd_vbat_adc_out_config_2_0(vbat, codec);
8257 else
8258 wcd_vbat_adc_out_config_1_x(vbat, codec);
8259
8260 tasha_cdc_mclk_enable(codec, false, false);
8261 vbat->adc_config = true;
8262 }
8263}
8264
8265static int tasha_update_vbat_reg_config(struct snd_soc_codec *codec)
8266{
8267 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
8268 struct firmware_cal *hwdep_cal = NULL;
8269 struct vbat_monitor_reg *vbat_reg_ptr = NULL;
8270 const void *data;
8271 size_t cal_size, vbat_size_remaining;
8272 int ret = 0, i;
8273 u32 vbat_writes_size = 0;
8274 u16 reg;
8275 u8 mask, val, old_val;
8276
8277 hwdep_cal = wcdcal_get_fw_cal(tasha->fw_data, WCD9XXX_VBAT_CAL);
8278 if (hwdep_cal) {
8279 data = hwdep_cal->data;
8280 cal_size = hwdep_cal->size;
8281 dev_dbg(codec->dev, "%s: using hwdep calibration\n",
8282 __func__);
8283 } else {
8284 dev_err(codec->dev, "%s: Vbat cal not received\n",
8285 __func__);
8286 ret = -EINVAL;
8287 goto done;
8288 }
8289
8290 if (cal_size < sizeof(*vbat_reg_ptr)) {
8291 dev_err(codec->dev,
8292 "%s: Incorrect size %zd for Vbat Cal, expected %zd\n",
8293 __func__, cal_size, sizeof(*vbat_reg_ptr));
8294 ret = -EINVAL;
8295 goto done;
8296 }
8297
8298 vbat_reg_ptr = (struct vbat_monitor_reg *) (data);
8299
8300 if (!vbat_reg_ptr) {
8301 dev_err(codec->dev,
8302 "%s: Invalid calibration data for Vbat\n",
8303 __func__);
8304 ret = -EINVAL;
8305 goto done;
8306 }
8307
8308 vbat_writes_size = vbat_reg_ptr->size;
8309 vbat_size_remaining = cal_size - sizeof(u32);
8310 dev_dbg(codec->dev, "%s: vbat_writes_sz: %d, vbat_sz_remaining: %zd\n",
8311 __func__, vbat_writes_size, vbat_size_remaining);
8312
8313 if ((vbat_writes_size * TASHA_PACKED_REG_SIZE)
8314 > vbat_size_remaining) {
8315 pr_err("%s: Incorrect Vbat calibration data\n", __func__);
8316 ret = -EINVAL;
8317 goto done;
8318 }
8319
8320 for (i = 0 ; i < vbat_writes_size; i++) {
8321 TASHA_CODEC_UNPACK_ENTRY(vbat_reg_ptr->writes[i],
8322 reg, mask, val);
8323 old_val = snd_soc_read(codec, reg);
8324 snd_soc_write(codec, reg, (old_val & ~mask) | (val & mask));
8325 }
8326
8327done:
8328 return ret;
8329}
8330
8331static int tasha_vbat_adc_data_get(struct snd_kcontrol *kcontrol,
8332 struct snd_ctl_elem_value *ucontrol)
8333{
8334 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
8335 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
8336
8337 wcd_vbat_adc_out_config(&tasha->vbat, codec);
8338
8339 ucontrol->value.integer.value[0] = tasha->vbat.dcp1;
8340 ucontrol->value.integer.value[1] = tasha->vbat.dcp2;
8341
8342 dev_dbg(codec->dev,
8343 "%s: Vbat ADC output values, Dcp1 : %lu, Dcp2: %lu\n",
8344 __func__, ucontrol->value.integer.value[0],
8345 ucontrol->value.integer.value[1]);
8346
8347 return 0;
8348}
8349
8350static const char * const tasha_vbat_gsm_mode_text[] = {
8351 "OFF", "ON"};
8352
8353static const struct soc_enum tasha_vbat_gsm_mode_enum =
8354 SOC_ENUM_SINGLE_EXT(2, tasha_vbat_gsm_mode_text);
8355
8356static int tasha_vbat_gsm_mode_func_get(struct snd_kcontrol *kcontrol,
8357 struct snd_ctl_elem_value *ucontrol)
8358{
8359 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
8360
8361 ucontrol->value.integer.value[0] =
8362 ((snd_soc_read(codec, WCD9335_CDC_VBAT_VBAT_CFG) & 0x04) ?
8363 1 : 0);
8364
8365 dev_dbg(codec->dev, "%s: value: %lu\n", __func__,
8366 ucontrol->value.integer.value[0]);
8367
8368 return 0;
8369}
8370
8371static int tasha_vbat_gsm_mode_func_put(struct snd_kcontrol *kcontrol,
8372 struct snd_ctl_elem_value *ucontrol)
8373{
8374 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
8375
8376 dev_dbg(codec->dev, "%s: value: %lu\n", __func__,
8377 ucontrol->value.integer.value[0]);
8378
8379 /* Set Vbat register configuration for GSM mode bit based on value */
8380 if (ucontrol->value.integer.value[0])
8381 snd_soc_update_bits(codec, WCD9335_CDC_VBAT_VBAT_CFG,
8382 0x04, 0x04);
8383 else
8384 snd_soc_update_bits(codec, WCD9335_CDC_VBAT_VBAT_CFG,
8385 0x04, 0x00);
8386
8387 return 0;
8388}
8389
8390static int tasha_codec_vbat_enable_event(struct snd_soc_dapm_widget *w,
8391 struct snd_kcontrol *kcontrol,
8392 int event)
8393{
8394 int ret = 0;
8395 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
8396 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
8397 u16 vbat_path_ctl, vbat_cfg, vbat_path_cfg;
8398
8399 vbat_path_ctl = WCD9335_CDC_VBAT_VBAT_PATH_CTL;
8400 vbat_cfg = WCD9335_CDC_VBAT_VBAT_CFG;
8401 vbat_path_cfg = WCD9335_CDC_RX8_RX_PATH_CFG1;
8402
8403 if (!strcmp(w->name, "RX INT8 VBAT"))
8404 vbat_path_cfg = WCD9335_CDC_RX8_RX_PATH_CFG1;
8405 else if (!strcmp(w->name, "RX INT7 VBAT"))
8406 vbat_path_cfg = WCD9335_CDC_RX7_RX_PATH_CFG1;
8407 else if (!strcmp(w->name, "RX INT6 VBAT"))
8408 vbat_path_cfg = WCD9335_CDC_RX6_RX_PATH_CFG1;
8409 else if (!strcmp(w->name, "RX INT5 VBAT"))
8410 vbat_path_cfg = WCD9335_CDC_RX5_RX_PATH_CFG1;
8411
8412 switch (event) {
8413 case SND_SOC_DAPM_PRE_PMU:
8414 ret = tasha_update_vbat_reg_config(codec);
8415 if (ret) {
8416 dev_dbg(codec->dev,
8417 "%s : VBAT isn't calibrated, So not enabling it\n",
8418 __func__);
8419 return 0;
8420 }
8421 snd_soc_write(codec, WCD9335_ANA_VBADC, 0x80);
8422 snd_soc_update_bits(codec, vbat_path_cfg, 0x02, 0x02);
8423 snd_soc_update_bits(codec, vbat_path_ctl, 0x10, 0x10);
8424 snd_soc_update_bits(codec, vbat_cfg, 0x01, 0x01);
8425 tasha->vbat.is_enabled = true;
8426 break;
8427 case SND_SOC_DAPM_POST_PMD:
8428 if (tasha->vbat.is_enabled) {
8429 snd_soc_update_bits(codec, vbat_cfg, 0x01, 0x00);
8430 snd_soc_update_bits(codec, vbat_path_ctl, 0x10, 0x00);
8431 snd_soc_update_bits(codec, vbat_path_cfg, 0x02, 0x00);
8432 snd_soc_write(codec, WCD9335_ANA_VBADC, 0x00);
8433 tasha->vbat.is_enabled = false;
8434 }
8435 break;
8436 };
8437
8438 return ret;
8439}
8440
8441static const char * const rx_hph_mode_mux_text[] = {
8442 "CLS_H_INVALID", "CLS_H_HIFI", "CLS_H_LP", "CLS_AB", "CLS_H_LOHIFI"
8443};
8444
8445static const struct soc_enum rx_hph_mode_mux_enum =
8446 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_hph_mode_mux_text),
8447 rx_hph_mode_mux_text);
8448
8449static const char * const amic_pwr_lvl_text[] = {
8450 "LOW_PWR", "DEFAULT", "HIGH_PERF"
8451};
8452
8453static const struct soc_enum amic_pwr_lvl_enum =
8454 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(amic_pwr_lvl_text),
8455 amic_pwr_lvl_text);
8456
8457static const struct snd_kcontrol_new tasha_snd_controls[] = {
8458 SOC_SINGLE_SX_TLV("RX0 Digital Volume", WCD9335_CDC_RX0_RX_VOL_CTL,
8459 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8460 SOC_SINGLE_SX_TLV("RX1 Digital Volume", WCD9335_CDC_RX1_RX_VOL_CTL,
8461 0, -84, 40, digital_gain),
8462 SOC_SINGLE_SX_TLV("RX2 Digital Volume", WCD9335_CDC_RX2_RX_VOL_CTL,
8463 0, -84, 40, digital_gain),
8464 SOC_SINGLE_SX_TLV("RX3 Digital Volume", WCD9335_CDC_RX3_RX_VOL_CTL,
8465 0, -84, 40, digital_gain),
8466 SOC_SINGLE_SX_TLV("RX4 Digital Volume", WCD9335_CDC_RX4_RX_VOL_CTL,
8467 0, -84, 40, digital_gain),
8468 SOC_SINGLE_SX_TLV("RX5 Digital Volume", WCD9335_CDC_RX5_RX_VOL_CTL,
8469 0, -84, 40, digital_gain),
8470 SOC_SINGLE_SX_TLV("RX6 Digital Volume", WCD9335_CDC_RX6_RX_VOL_CTL,
8471 0, -84, 40, digital_gain),
8472 SOC_SINGLE_SX_TLV("RX7 Digital Volume", WCD9335_CDC_RX7_RX_VOL_CTL,
8473 0, -84, 40, digital_gain),
8474 SOC_SINGLE_SX_TLV("RX8 Digital Volume", WCD9335_CDC_RX8_RX_VOL_CTL,
8475 0, -84, 40, digital_gain),
8476
8477 SOC_SINGLE_SX_TLV("RX0 Mix Digital Volume",
8478 WCD9335_CDC_RX0_RX_VOL_MIX_CTL,
8479 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8480 SOC_SINGLE_SX_TLV("RX1 Mix Digital Volume",
8481 WCD9335_CDC_RX1_RX_VOL_MIX_CTL,
8482 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8483 SOC_SINGLE_SX_TLV("RX2 Mix Digital Volume",
8484 WCD9335_CDC_RX2_RX_VOL_MIX_CTL,
8485 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8486 SOC_SINGLE_SX_TLV("RX3 Mix Digital Volume",
8487 WCD9335_CDC_RX3_RX_VOL_MIX_CTL,
8488 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8489 SOC_SINGLE_SX_TLV("RX4 Mix Digital Volume",
8490 WCD9335_CDC_RX4_RX_VOL_MIX_CTL,
8491 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8492 SOC_SINGLE_SX_TLV("RX5 Mix Digital Volume",
8493 WCD9335_CDC_RX5_RX_VOL_MIX_CTL,
8494 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8495 SOC_SINGLE_SX_TLV("RX6 Mix Digital Volume",
8496 WCD9335_CDC_RX6_RX_VOL_MIX_CTL,
8497 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8498 SOC_SINGLE_SX_TLV("RX7 Mix Digital Volume",
8499 WCD9335_CDC_RX7_RX_VOL_MIX_CTL,
8500 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8501 SOC_SINGLE_SX_TLV("RX8 Mix Digital Volume",
8502 WCD9335_CDC_RX8_RX_VOL_MIX_CTL,
8503 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
8504
8505 SOC_SINGLE_SX_TLV("DEC0 Volume", WCD9335_CDC_TX0_TX_VOL_CTL, 0,
8506 -84, 40, digital_gain),
8507 SOC_SINGLE_SX_TLV("DEC1 Volume", WCD9335_CDC_TX1_TX_VOL_CTL, 0,
8508 -84, 40, digital_gain),
8509 SOC_SINGLE_SX_TLV("DEC2 Volume", WCD9335_CDC_TX2_TX_VOL_CTL, 0,
8510 -84, 40, digital_gain),
8511 SOC_SINGLE_SX_TLV("DEC3 Volume", WCD9335_CDC_TX3_TX_VOL_CTL, 0,
8512 -84, 40, digital_gain),
8513 SOC_SINGLE_SX_TLV("DEC4 Volume", WCD9335_CDC_TX4_TX_VOL_CTL, 0,
8514 -84, 40, digital_gain),
8515 SOC_SINGLE_SX_TLV("DEC5 Volume", WCD9335_CDC_TX5_TX_VOL_CTL, 0,
8516 -84, 40, digital_gain),
8517 SOC_SINGLE_SX_TLV("DEC6 Volume", WCD9335_CDC_TX6_TX_VOL_CTL, 0,
8518 -84, 40, digital_gain),
8519 SOC_SINGLE_SX_TLV("DEC7 Volume", WCD9335_CDC_TX7_TX_VOL_CTL, 0,
8520 -84, 40, digital_gain),
8521 SOC_SINGLE_SX_TLV("DEC8 Volume", WCD9335_CDC_TX8_TX_VOL_CTL, 0,
8522 -84, 40, digital_gain),
8523
8524 SOC_SINGLE_SX_TLV("IIR0 INP0 Volume",
8525 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL, 0, -84,
8526 40, digital_gain),
8527 SOC_SINGLE_SX_TLV("IIR0 INP1 Volume",
8528 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL, 0, -84,
8529 40, digital_gain),
8530 SOC_SINGLE_SX_TLV("IIR0 INP2 Volume",
8531 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL, 0, -84,
8532 40, digital_gain),
8533 SOC_SINGLE_SX_TLV("IIR0 INP3 Volume",
8534 WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL, 0, -84,
8535 40, digital_gain),
8536 SOC_SINGLE_SX_TLV("IIR1 INP0 Volume",
8537 WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B1_CTL, 0, -84,
8538 40, digital_gain),
8539 SOC_SINGLE_SX_TLV("IIR1 INP1 Volume",
8540 WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B2_CTL, 0, -84,
8541 40, digital_gain),
8542 SOC_SINGLE_SX_TLV("IIR1 INP2 Volume",
8543 WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B3_CTL, 0, -84,
8544 40, digital_gain),
8545 SOC_SINGLE_SX_TLV("IIR1 INP3 Volume",
8546 WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B4_CTL, 0, -84,
8547 40, digital_gain),
8548
8549 SOC_SINGLE_EXT("ANC Slot", SND_SOC_NOPM, 0, 100, 0, tasha_get_anc_slot,
8550 tasha_put_anc_slot),
8551 SOC_ENUM_EXT("ANC Function", tasha_anc_func_enum, tasha_get_anc_func,
8552 tasha_put_anc_func),
8553
8554 SOC_ENUM_EXT("CLK MODE", tasha_clkmode_enum, tasha_get_clkmode,
8555 tasha_put_clkmode),
8556
8557 SOC_ENUM("TX0 HPF cut off", cf_dec0_enum),
8558 SOC_ENUM("TX1 HPF cut off", cf_dec1_enum),
8559 SOC_ENUM("TX2 HPF cut off", cf_dec2_enum),
8560 SOC_ENUM("TX3 HPF cut off", cf_dec3_enum),
8561 SOC_ENUM("TX4 HPF cut off", cf_dec4_enum),
8562 SOC_ENUM("TX5 HPF cut off", cf_dec5_enum),
8563 SOC_ENUM("TX6 HPF cut off", cf_dec6_enum),
8564 SOC_ENUM("TX7 HPF cut off", cf_dec7_enum),
8565 SOC_ENUM("TX8 HPF cut off", cf_dec8_enum),
8566
8567 SOC_ENUM("RX INT0_1 HPF cut off", cf_int0_1_enum),
8568 SOC_ENUM("RX INT0_2 HPF cut off", cf_int0_2_enum),
8569 SOC_ENUM("RX INT1_1 HPF cut off", cf_int1_1_enum),
8570 SOC_ENUM("RX INT1_2 HPF cut off", cf_int1_2_enum),
8571 SOC_ENUM("RX INT2_1 HPF cut off", cf_int2_1_enum),
8572 SOC_ENUM("RX INT2_2 HPF cut off", cf_int2_2_enum),
8573 SOC_ENUM("RX INT3_1 HPF cut off", cf_int3_1_enum),
8574 SOC_ENUM("RX INT3_2 HPF cut off", cf_int3_2_enum),
8575 SOC_ENUM("RX INT4_1 HPF cut off", cf_int4_1_enum),
8576 SOC_ENUM("RX INT4_2 HPF cut off", cf_int4_2_enum),
8577 SOC_ENUM("RX INT5_1 HPF cut off", cf_int5_1_enum),
8578 SOC_ENUM("RX INT5_2 HPF cut off", cf_int5_2_enum),
8579 SOC_ENUM("RX INT6_1 HPF cut off", cf_int6_1_enum),
8580 SOC_ENUM("RX INT6_2 HPF cut off", cf_int6_2_enum),
8581 SOC_ENUM("RX INT7_1 HPF cut off", cf_int7_1_enum),
8582 SOC_ENUM("RX INT7_2 HPF cut off", cf_int7_2_enum),
8583 SOC_ENUM("RX INT8_1 HPF cut off", cf_int8_1_enum),
8584 SOC_ENUM("RX INT8_2 HPF cut off", cf_int8_2_enum),
8585
8586 SOC_SINGLE_EXT("IIR0 Enable Band1", IIR0, BAND1, 1, 0,
8587 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8588 SOC_SINGLE_EXT("IIR0 Enable Band2", IIR0, BAND2, 1, 0,
8589 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8590 SOC_SINGLE_EXT("IIR0 Enable Band3", IIR0, BAND3, 1, 0,
8591 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8592 SOC_SINGLE_EXT("IIR0 Enable Band4", IIR0, BAND4, 1, 0,
8593 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8594 SOC_SINGLE_EXT("IIR0 Enable Band5", IIR0, BAND5, 1, 0,
8595 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8596 SOC_SINGLE_EXT("IIR1 Enable Band1", IIR1, BAND1, 1, 0,
8597 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8598 SOC_SINGLE_EXT("IIR1 Enable Band2", IIR1, BAND2, 1, 0,
8599 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8600 SOC_SINGLE_EXT("IIR1 Enable Band3", IIR1, BAND3, 1, 0,
8601 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8602 SOC_SINGLE_EXT("IIR1 Enable Band4", IIR1, BAND4, 1, 0,
8603 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8604 SOC_SINGLE_EXT("IIR1 Enable Band5", IIR1, BAND5, 1, 0,
8605 tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
8606
8607 SOC_SINGLE_MULTI_EXT("IIR0 Band1", IIR0, BAND1, 255, 0, 5,
8608 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8609 SOC_SINGLE_MULTI_EXT("IIR0 Band2", IIR0, BAND2, 255, 0, 5,
8610 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8611 SOC_SINGLE_MULTI_EXT("IIR0 Band3", IIR0, BAND3, 255, 0, 5,
8612 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8613 SOC_SINGLE_MULTI_EXT("IIR0 Band4", IIR0, BAND4, 255, 0, 5,
8614 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8615 SOC_SINGLE_MULTI_EXT("IIR0 Band5", IIR0, BAND5, 255, 0, 5,
8616 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8617 SOC_SINGLE_MULTI_EXT("IIR1 Band1", IIR1, BAND1, 255, 0, 5,
8618 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8619 SOC_SINGLE_MULTI_EXT("IIR1 Band2", IIR1, BAND2, 255, 0, 5,
8620 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8621 SOC_SINGLE_MULTI_EXT("IIR1 Band3", IIR1, BAND3, 255, 0, 5,
8622 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8623 SOC_SINGLE_MULTI_EXT("IIR1 Band4", IIR1, BAND4, 255, 0, 5,
8624 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8625 SOC_SINGLE_MULTI_EXT("IIR1 Band5", IIR1, BAND5, 255, 0, 5,
8626 tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer),
8627
8628 SOC_SINGLE_EXT("COMP1 Switch", SND_SOC_NOPM, COMPANDER_1, 1, 0,
8629 tasha_get_compander, tasha_set_compander),
8630 SOC_SINGLE_EXT("COMP2 Switch", SND_SOC_NOPM, COMPANDER_2, 1, 0,
8631 tasha_get_compander, tasha_set_compander),
8632 SOC_SINGLE_EXT("COMP3 Switch", SND_SOC_NOPM, COMPANDER_3, 1, 0,
8633 tasha_get_compander, tasha_set_compander),
8634 SOC_SINGLE_EXT("COMP4 Switch", SND_SOC_NOPM, COMPANDER_4, 1, 0,
8635 tasha_get_compander, tasha_set_compander),
8636 SOC_SINGLE_EXT("COMP5 Switch", SND_SOC_NOPM, COMPANDER_5, 1, 0,
8637 tasha_get_compander, tasha_set_compander),
8638 SOC_SINGLE_EXT("COMP6 Switch", SND_SOC_NOPM, COMPANDER_6, 1, 0,
8639 tasha_get_compander, tasha_set_compander),
8640 SOC_SINGLE_EXT("COMP7 Switch", SND_SOC_NOPM, COMPANDER_7, 1, 0,
8641 tasha_get_compander, tasha_set_compander),
8642 SOC_SINGLE_EXT("COMP8 Switch", SND_SOC_NOPM, COMPANDER_8, 1, 0,
8643 tasha_get_compander, tasha_set_compander),
8644
8645 SOC_ENUM_EXT("RX HPH Mode", rx_hph_mode_mux_enum,
8646 tasha_rx_hph_mode_get, tasha_rx_hph_mode_put),
8647
8648 SOC_ENUM_EXT("MAD Input", tasha_conn_mad_enum,
8649 tasha_mad_input_get, tasha_mad_input_put),
8650 SOC_SINGLE_EXT("LDO_H Enable", SND_SOC_NOPM, 0, 1, 0,
8651 tasha_enable_ldo_h_get, tasha_enable_ldo_h_put),
8652
8653 SOC_SINGLE_EXT("DMIC1_CLK_PIN_MODE", SND_SOC_NOPM, 17, 1, 0,
8654 tasha_pinctl_mode_get, tasha_pinctl_mode_put),
8655
8656 SOC_SINGLE_EXT("DMIC1_DATA_PIN_MODE", SND_SOC_NOPM, 18, 1, 0,
8657 tasha_pinctl_mode_get, tasha_pinctl_mode_put),
8658
8659 SOC_SINGLE_EXT("DMIC2_CLK_PIN_MODE", SND_SOC_NOPM, 19, 1, 0,
8660 tasha_pinctl_mode_get, tasha_pinctl_mode_put),
8661
8662 SOC_SINGLE_EXT("DMIC2_DATA_PIN_MODE", SND_SOC_NOPM, 20, 1, 0,
8663 tasha_pinctl_mode_get, tasha_pinctl_mode_put),
8664
8665 SOC_SINGLE_EXT("DMIC3_CLK_PIN_MODE", SND_SOC_NOPM, 21, 1, 0,
8666 tasha_pinctl_mode_get, tasha_pinctl_mode_put),
8667
8668 SOC_SINGLE_EXT("DMIC3_DATA_PIN_MODE", SND_SOC_NOPM, 22, 1, 0,
8669 tasha_pinctl_mode_get, tasha_pinctl_mode_put),
8670 SOC_ENUM_EXT("AMIC_1_2 PWR MODE", amic_pwr_lvl_enum,
8671 tasha_amic_pwr_lvl_get, tasha_amic_pwr_lvl_put),
8672 SOC_ENUM_EXT("AMIC_3_4 PWR MODE", amic_pwr_lvl_enum,
8673 tasha_amic_pwr_lvl_get, tasha_amic_pwr_lvl_put),
8674 SOC_ENUM_EXT("AMIC_5_6 PWR MODE", amic_pwr_lvl_enum,
8675 tasha_amic_pwr_lvl_get, tasha_amic_pwr_lvl_put),
8676
8677 SOC_SINGLE_MULTI_EXT("Vbat ADC data", SND_SOC_NOPM, 0, 0xFFFF, 0, 2,
8678 tasha_vbat_adc_data_get, NULL),
8679
8680 SOC_ENUM_EXT("GSM mode Enable", tasha_vbat_gsm_mode_enum,
8681 tasha_vbat_gsm_mode_func_get,
8682 tasha_vbat_gsm_mode_func_put),
8683};
8684
8685static int tasha_put_dec_enum(struct snd_kcontrol *kcontrol,
8686 struct snd_ctl_elem_value *ucontrol)
8687{
8688 struct snd_soc_dapm_widget_list *wlist =
8689 dapm_kcontrol_get_wlist(kcontrol);
8690 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
8691 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
8692 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
8693 unsigned int val;
8694 u16 mic_sel_reg;
8695 u8 mic_sel;
8696
8697 val = ucontrol->value.enumerated.item[0];
8698 if (val > e->items - 1)
8699 return -EINVAL;
8700
8701 dev_dbg(codec->dev, "%s: wname: %s, val: 0x%x\n", __func__,
8702 widget->name, val);
8703
8704 switch (e->reg) {
8705 case WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG1:
8706 mic_sel_reg = WCD9335_CDC_TX0_TX_PATH_CFG0;
8707 break;
8708 case WCD9335_CDC_TX_INP_MUX_ADC_MUX1_CFG1:
8709 mic_sel_reg = WCD9335_CDC_TX1_TX_PATH_CFG0;
8710 break;
8711 case WCD9335_CDC_TX_INP_MUX_ADC_MUX2_CFG1:
8712 mic_sel_reg = WCD9335_CDC_TX2_TX_PATH_CFG0;
8713 break;
8714 case WCD9335_CDC_TX_INP_MUX_ADC_MUX3_CFG1:
8715 mic_sel_reg = WCD9335_CDC_TX3_TX_PATH_CFG0;
8716 break;
8717 case WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0:
8718 mic_sel_reg = WCD9335_CDC_TX4_TX_PATH_CFG0;
8719 break;
8720 case WCD9335_CDC_TX_INP_MUX_ADC_MUX5_CFG0:
8721 mic_sel_reg = WCD9335_CDC_TX5_TX_PATH_CFG0;
8722 break;
8723 case WCD9335_CDC_TX_INP_MUX_ADC_MUX6_CFG0:
8724 mic_sel_reg = WCD9335_CDC_TX6_TX_PATH_CFG0;
8725 break;
8726 case WCD9335_CDC_TX_INP_MUX_ADC_MUX7_CFG0:
8727 mic_sel_reg = WCD9335_CDC_TX7_TX_PATH_CFG0;
8728 break;
8729 case WCD9335_CDC_TX_INP_MUX_ADC_MUX8_CFG0:
8730 mic_sel_reg = WCD9335_CDC_TX8_TX_PATH_CFG0;
8731 break;
8732 default:
8733 dev_err(codec->dev, "%s: e->reg: 0x%x not expected\n",
8734 __func__, e->reg);
8735 return -EINVAL;
8736 }
8737
8738 /* ADC: 0, DMIC: 1 */
8739 mic_sel = val ? 0x0 : 0x1;
8740 snd_soc_update_bits(codec, mic_sel_reg, 1 << 7, mic_sel << 7);
8741
8742 return snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
8743}
8744
8745static int tasha_int_dem_inp_mux_put(struct snd_kcontrol *kcontrol,
8746 struct snd_ctl_elem_value *ucontrol)
8747{
8748 struct snd_soc_dapm_widget_list *wlist =
8749 dapm_kcontrol_get_wlist(kcontrol);
8750 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
8751 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
8752 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
8753 unsigned int val;
8754 unsigned short look_ahead_dly_reg = WCD9335_CDC_RX0_RX_PATH_CFG0;
8755
8756 val = ucontrol->value.enumerated.item[0];
8757 if (val >= e->items)
8758 return -EINVAL;
8759
8760 dev_dbg(codec->dev, "%s: wname: %s, val: 0x%x\n", __func__,
8761 widget->name, val);
8762
8763 if (e->reg == WCD9335_CDC_RX0_RX_PATH_SEC0)
8764 look_ahead_dly_reg = WCD9335_CDC_RX0_RX_PATH_CFG0;
8765 else if (e->reg == WCD9335_CDC_RX1_RX_PATH_SEC0)
8766 look_ahead_dly_reg = WCD9335_CDC_RX1_RX_PATH_CFG0;
8767 else if (e->reg == WCD9335_CDC_RX2_RX_PATH_SEC0)
8768 look_ahead_dly_reg = WCD9335_CDC_RX2_RX_PATH_CFG0;
8769
8770 /* Set Look Ahead Delay */
8771 snd_soc_update_bits(codec, look_ahead_dly_reg,
8772 0x08, (val ? 0x08 : 0x00));
8773 /* Set DEM INP Select */
8774 return snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
8775}
8776
8777static int tasha_ear_pa_gain_get(struct snd_kcontrol *kcontrol,
8778 struct snd_ctl_elem_value *ucontrol)
8779{
8780 u8 ear_pa_gain;
8781 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
8782
8783 ear_pa_gain = snd_soc_read(codec, WCD9335_ANA_EAR);
8784
8785 ear_pa_gain = (ear_pa_gain & 0x70) >> 4;
8786
8787 ucontrol->value.integer.value[0] = ear_pa_gain;
8788
8789 dev_dbg(codec->dev, "%s: ear_pa_gain = 0x%x\n", __func__,
8790 ear_pa_gain);
8791
8792 return 0;
8793}
8794
8795static int tasha_ear_pa_gain_put(struct snd_kcontrol *kcontrol,
8796 struct snd_ctl_elem_value *ucontrol)
8797{
8798 u8 ear_pa_gain;
8799 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
8800
8801 dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
8802 __func__, ucontrol->value.integer.value[0]);
8803
8804 ear_pa_gain = ucontrol->value.integer.value[0] << 4;
8805
8806 snd_soc_update_bits(codec, WCD9335_ANA_EAR, 0x70, ear_pa_gain);
8807 return 0;
8808}
8809
8810static int tasha_ear_spkr_pa_gain_get(struct snd_kcontrol *kcontrol,
8811 struct snd_ctl_elem_value *ucontrol)
8812{
8813 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
8814 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
8815
8816 ucontrol->value.integer.value[0] = tasha->ear_spkr_gain;
8817
8818 dev_dbg(codec->dev, "%s: ear_spkr_gain = %ld\n", __func__,
8819 ucontrol->value.integer.value[0]);
8820
8821 return 0;
8822}
8823
8824static int tasha_ear_spkr_pa_gain_put(struct snd_kcontrol *kcontrol,
8825 struct snd_ctl_elem_value *ucontrol)
8826{
8827 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
8828 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
8829
8830 dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
8831 __func__, ucontrol->value.integer.value[0]);
8832
8833 tasha->ear_spkr_gain = ucontrol->value.integer.value[0];
8834
8835 return 0;
8836}
8837
8838static int tasha_config_compander(struct snd_soc_codec *codec, int interp_n,
8839 int event)
8840{
8841 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
8842 int comp;
8843 u16 comp_ctl0_reg, rx_path_cfg0_reg;
8844
8845 /* EAR does not have compander */
8846 if (!interp_n)
8847 return 0;
8848
8849 comp = interp_n - 1;
8850 dev_dbg(codec->dev, "%s: event %d compander %d, enabled %d\n",
8851 __func__, event, comp + 1, tasha->comp_enabled[comp]);
8852
8853 if (!tasha->comp_enabled[comp])
8854 return 0;
8855
8856 comp_ctl0_reg = WCD9335_CDC_COMPANDER1_CTL0 + (comp * 8);
8857 rx_path_cfg0_reg = WCD9335_CDC_RX1_RX_PATH_CFG0 + (comp * 20);
8858
8859 if (SND_SOC_DAPM_EVENT_ON(event)) {
8860 /* Enable Compander Clock */
8861 snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x01);
8862 snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02);
8863 snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00);
8864 snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x02);
8865 }
8866
8867 if (SND_SOC_DAPM_EVENT_OFF(event)) {
8868 snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x04);
8869 snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x00);
8870 snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02);
8871 snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00);
8872 snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x00);
8873 snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x00);
8874 }
8875
8876 return 0;
8877}
8878
8879static int tasha_codec_config_mad(struct snd_soc_codec *codec)
8880{
8881 int ret = 0;
8882 int idx;
8883 const struct firmware *fw;
8884 struct firmware_cal *hwdep_cal = NULL;
8885 struct wcd_mad_audio_cal *mad_cal = NULL;
8886 const void *data;
8887 const char *filename = TASHA_MAD_AUDIO_FIRMWARE_PATH;
8888 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
8889 size_t cal_size;
8890
8891 hwdep_cal = wcdcal_get_fw_cal(tasha->fw_data, WCD9XXX_MAD_CAL);
8892 if (hwdep_cal) {
8893 data = hwdep_cal->data;
8894 cal_size = hwdep_cal->size;
8895 dev_dbg(codec->dev, "%s: using hwdep calibration\n",
8896 __func__);
8897 } else {
8898 ret = request_firmware(&fw, filename, codec->dev);
8899 if (ret || !fw) {
8900 dev_err(codec->dev,
8901 "%s: MAD firmware acquire failed, err = %d\n",
8902 __func__, ret);
8903 return -ENODEV;
8904 }
8905 data = fw->data;
8906 cal_size = fw->size;
8907 dev_dbg(codec->dev, "%s: using request_firmware calibration\n",
8908 __func__);
8909 }
8910
8911 if (cal_size < sizeof(*mad_cal)) {
8912 dev_err(codec->dev,
8913 "%s: Incorrect size %zd for MAD Cal, expected %zd\n",
8914 __func__, cal_size, sizeof(*mad_cal));
8915 ret = -ENOMEM;
8916 goto done;
8917 }
8918
8919 mad_cal = (struct wcd_mad_audio_cal *) (data);
8920 if (!mad_cal) {
8921 dev_err(codec->dev,
8922 "%s: Invalid calibration data\n",
8923 __func__);
8924 ret = -EINVAL;
8925 goto done;
8926 }
8927
8928 snd_soc_write(codec, WCD9335_SOC_MAD_MAIN_CTL_2,
8929 mad_cal->microphone_info.cycle_time);
8930 snd_soc_update_bits(codec, WCD9335_SOC_MAD_MAIN_CTL_1, 0xFF << 3,
8931 ((uint16_t)mad_cal->microphone_info.settle_time)
8932 << 3);
8933
8934 /* Audio */
8935 snd_soc_write(codec, WCD9335_SOC_MAD_AUDIO_CTL_8,
8936 mad_cal->audio_info.rms_omit_samples);
8937 snd_soc_update_bits(codec, WCD9335_SOC_MAD_AUDIO_CTL_1,
8938 0x07 << 4, mad_cal->audio_info.rms_comp_time << 4);
8939 snd_soc_update_bits(codec, WCD9335_SOC_MAD_AUDIO_CTL_2, 0x03 << 2,
8940 mad_cal->audio_info.detection_mechanism << 2);
8941 snd_soc_write(codec, WCD9335_SOC_MAD_AUDIO_CTL_7,
8942 mad_cal->audio_info.rms_diff_threshold & 0x3F);
8943 snd_soc_write(codec, WCD9335_SOC_MAD_AUDIO_CTL_5,
8944 mad_cal->audio_info.rms_threshold_lsb);
8945 snd_soc_write(codec, WCD9335_SOC_MAD_AUDIO_CTL_6,
8946 mad_cal->audio_info.rms_threshold_msb);
8947
8948 for (idx = 0; idx < ARRAY_SIZE(mad_cal->audio_info.iir_coefficients);
8949 idx++) {
8950 snd_soc_update_bits(codec, WCD9335_SOC_MAD_AUDIO_IIR_CTL_PTR,
8951 0x3F, idx);
8952 snd_soc_write(codec, WCD9335_SOC_MAD_AUDIO_IIR_CTL_VAL,
8953 mad_cal->audio_info.iir_coefficients[idx]);
8954 dev_dbg(codec->dev, "%s:MAD Audio IIR Coef[%d] = 0X%x",
8955 __func__, idx,
8956 mad_cal->audio_info.iir_coefficients[idx]);
8957 }
8958
8959 /* Beacon */
8960 snd_soc_write(codec, WCD9335_SOC_MAD_BEACON_CTL_8,
8961 mad_cal->beacon_info.rms_omit_samples);
8962 snd_soc_update_bits(codec, WCD9335_SOC_MAD_BEACON_CTL_1,
8963 0x07 << 4, mad_cal->beacon_info.rms_comp_time << 4);
8964 snd_soc_update_bits(codec, WCD9335_SOC_MAD_BEACON_CTL_2, 0x03 << 2,
8965 mad_cal->beacon_info.detection_mechanism << 2);
8966 snd_soc_write(codec, WCD9335_SOC_MAD_BEACON_CTL_7,
8967 mad_cal->beacon_info.rms_diff_threshold & 0x1F);
8968 snd_soc_write(codec, WCD9335_SOC_MAD_BEACON_CTL_5,
8969 mad_cal->beacon_info.rms_threshold_lsb);
8970 snd_soc_write(codec, WCD9335_SOC_MAD_BEACON_CTL_6,
8971 mad_cal->beacon_info.rms_threshold_msb);
8972
8973 for (idx = 0; idx < ARRAY_SIZE(mad_cal->beacon_info.iir_coefficients);
8974 idx++) {
8975 snd_soc_update_bits(codec, WCD9335_SOC_MAD_BEACON_IIR_CTL_PTR,
8976 0x3F, idx);
8977 snd_soc_write(codec, WCD9335_SOC_MAD_BEACON_IIR_CTL_VAL,
8978 mad_cal->beacon_info.iir_coefficients[idx]);
8979 dev_dbg(codec->dev, "%s:MAD Beacon IIR Coef[%d] = 0X%x",
8980 __func__, idx,
8981 mad_cal->beacon_info.iir_coefficients[idx]);
8982 }
8983
8984 /* Ultrasound */
8985 snd_soc_update_bits(codec, WCD9335_SOC_MAD_ULTR_CTL_1,
8986 0x07 << 4,
8987 mad_cal->ultrasound_info.rms_comp_time << 4);
8988 snd_soc_update_bits(codec, WCD9335_SOC_MAD_ULTR_CTL_2, 0x03 << 2,
8989 mad_cal->ultrasound_info.detection_mechanism << 2);
8990 snd_soc_write(codec, WCD9335_SOC_MAD_ULTR_CTL_7,
8991 mad_cal->ultrasound_info.rms_diff_threshold & 0x1F);
8992 snd_soc_write(codec, WCD9335_SOC_MAD_ULTR_CTL_5,
8993 mad_cal->ultrasound_info.rms_threshold_lsb);
8994 snd_soc_write(codec, WCD9335_SOC_MAD_ULTR_CTL_6,
8995 mad_cal->ultrasound_info.rms_threshold_msb);
8996
8997done:
8998 if (!hwdep_cal)
8999 release_firmware(fw);
9000
9001 return ret;
9002}
9003
9004static int tasha_codec_enable_mad(struct snd_soc_dapm_widget *w,
9005 struct snd_kcontrol *kcontrol, int event)
9006{
9007 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
9008 int ret = 0;
9009
9010 dev_dbg(codec->dev,
9011 "%s: event = %d\n", __func__, event);
9012
9013 /* Return if CPE INPUT is DEC1 */
9014 if (snd_soc_read(codec, WCD9335_CPE_SS_SVA_CFG) & 0x01)
9015 return ret;
9016
9017 switch (event) {
9018 case SND_SOC_DAPM_PRE_PMU:
9019
9020 /* Turn on MAD clk */
9021 snd_soc_update_bits(codec, WCD9335_CPE_SS_MAD_CTL,
9022 0x01, 0x01);
9023
9024 /* Undo reset for MAD */
9025 snd_soc_update_bits(codec, WCD9335_CPE_SS_MAD_CTL,
9026 0x02, 0x00);
9027 ret = tasha_codec_config_mad(codec);
9028 if (ret)
9029 dev_err(codec->dev,
9030 "%s: Failed to config MAD, err = %d\n",
9031 __func__, ret);
9032 break;
9033 case SND_SOC_DAPM_POST_PMD:
9034 /* Reset the MAD block */
9035 snd_soc_update_bits(codec, WCD9335_CPE_SS_MAD_CTL,
9036 0x02, 0x02);
9037 /* Turn off MAD clk */
9038 snd_soc_update_bits(codec, WCD9335_CPE_SS_MAD_CTL,
9039 0x01, 0x00);
9040 break;
9041 }
9042
9043 return ret;
9044}
9045
9046static int tasha_codec_configure_cpe_input(struct snd_soc_dapm_widget *w,
9047 struct snd_kcontrol *kcontrol, int event)
9048{
9049 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
9050
9051 dev_dbg(codec->dev,
9052 "%s: event = %d\n", __func__, event);
9053
9054 switch (event) {
9055 case SND_SOC_DAPM_PRE_PMU:
9056 /* Configure CPE input as DEC1 */
9057 snd_soc_update_bits(codec, WCD9335_CPE_SS_SVA_CFG,
9058 0x01, 0x01);
9059
9060 /* Configure DEC1 Tx out with sample rate as 16K */
9061 snd_soc_update_bits(codec, WCD9335_CDC_TX1_TX_PATH_CTL,
9062 0x0F, 0x01);
9063
9064 break;
9065 case SND_SOC_DAPM_POST_PMD:
9066 /* Reset DEC1 Tx out sample rate */
9067 snd_soc_update_bits(codec, WCD9335_CDC_TX1_TX_PATH_CTL,
9068 0x0F, 0x04);
9069 snd_soc_update_bits(codec, WCD9335_CPE_SS_SVA_CFG,
9070 0x01, 0x00);
9071
9072 break;
9073 }
9074
9075 return 0;
9076}
9077
9078
9079static int tasha_codec_aif4_mixer_switch_get(struct snd_kcontrol *kcontrol,
9080 struct snd_ctl_elem_value *ucontrol)
9081{
9082 struct snd_soc_dapm_widget_list *wlist =
9083 dapm_kcontrol_get_wlist(kcontrol);
9084 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
9085 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
9086 struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec);
9087
9088 if (test_bit(AIF4_SWITCH_VALUE, &tasha_p->status_mask))
9089 ucontrol->value.integer.value[0] = 1;
9090 else
9091 ucontrol->value.integer.value[0] = 0;
9092
9093 dev_dbg(codec->dev, "%s: AIF4 switch value = %ld\n",
9094 __func__, ucontrol->value.integer.value[0]);
9095 return 0;
9096}
9097
9098static int tasha_codec_aif4_mixer_switch_put(struct snd_kcontrol *kcontrol,
9099 struct snd_ctl_elem_value *ucontrol)
9100{
9101 struct snd_soc_dapm_widget_list *wlist =
9102 dapm_kcontrol_get_wlist(kcontrol);
9103 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
9104 struct snd_soc_dapm_update *update = NULL;
9105 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
9106 struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec);
9107
9108 dev_dbg(codec->dev, "%s: AIF4 switch value = %ld\n",
9109 __func__, ucontrol->value.integer.value[0]);
9110
9111 if (ucontrol->value.integer.value[0]) {
9112 snd_soc_dapm_mixer_update_power(widget->dapm,
9113 kcontrol, 1, update);
9114 set_bit(AIF4_SWITCH_VALUE, &tasha_p->status_mask);
9115 } else {
9116 snd_soc_dapm_mixer_update_power(widget->dapm,
9117 kcontrol, 0, update);
9118 clear_bit(AIF4_SWITCH_VALUE, &tasha_p->status_mask);
9119 }
9120
9121 return 1;
9122}
9123
9124static const char * const tasha_ear_pa_gain_text[] = {
9125 "G_6_DB", "G_4P5_DB", "G_3_DB", "G_1P5_DB",
9126 "G_0_DB", "G_M2P5_DB", "UNDEFINED", "G_M12_DB"
9127};
9128
9129static const char * const tasha_ear_spkr_pa_gain_text[] = {
9130 "G_DEFAULT", "G_0_DB", "G_1_DB", "G_2_DB", "G_3_DB", "G_4_DB",
9131 "G_5_DB", "G_6_DB"
9132};
9133
9134static const struct soc_enum tasha_ear_pa_gain_enum =
9135 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tasha_ear_pa_gain_text),
9136 tasha_ear_pa_gain_text);
9137
9138static const struct soc_enum tasha_ear_spkr_pa_gain_enum =
9139 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tasha_ear_spkr_pa_gain_text),
9140 tasha_ear_spkr_pa_gain_text);
9141
9142static const struct snd_kcontrol_new tasha_analog_gain_controls[] = {
9143 SOC_ENUM_EXT("EAR PA Gain", tasha_ear_pa_gain_enum,
9144 tasha_ear_pa_gain_get, tasha_ear_pa_gain_put),
9145
9146 SOC_ENUM_EXT("EAR SPKR PA Gain", tasha_ear_spkr_pa_gain_enum,
9147 tasha_ear_spkr_pa_gain_get, tasha_ear_spkr_pa_gain_put),
9148
9149 SOC_SINGLE_TLV("HPHL Volume", WCD9335_HPH_L_EN, 0, 20, 1,
9150 line_gain),
9151 SOC_SINGLE_TLV("HPHR Volume", WCD9335_HPH_R_EN, 0, 20, 1,
9152 line_gain),
9153 SOC_SINGLE_TLV("LINEOUT1 Volume", WCD9335_DIFF_LO_LO1_COMPANDER,
9154 3, 16, 1, line_gain),
9155 SOC_SINGLE_TLV("LINEOUT2 Volume", WCD9335_DIFF_LO_LO2_COMPANDER,
9156 3, 16, 1, line_gain),
9157 SOC_SINGLE_TLV("LINEOUT3 Volume", WCD9335_SE_LO_LO3_GAIN, 0, 20, 1,
9158 line_gain),
9159 SOC_SINGLE_TLV("LINEOUT4 Volume", WCD9335_SE_LO_LO4_GAIN, 0, 20, 1,
9160 line_gain),
9161
9162 SOC_SINGLE_TLV("ADC1 Volume", WCD9335_ANA_AMIC1, 0, 20, 0,
9163 analog_gain),
9164 SOC_SINGLE_TLV("ADC2 Volume", WCD9335_ANA_AMIC2, 0, 20, 0,
9165 analog_gain),
9166 SOC_SINGLE_TLV("ADC3 Volume", WCD9335_ANA_AMIC3, 0, 20, 0,
9167 analog_gain),
9168 SOC_SINGLE_TLV("ADC4 Volume", WCD9335_ANA_AMIC4, 0, 20, 0,
9169 analog_gain),
9170 SOC_SINGLE_TLV("ADC5 Volume", WCD9335_ANA_AMIC5, 0, 20, 0,
9171 analog_gain),
9172 SOC_SINGLE_TLV("ADC6 Volume", WCD9335_ANA_AMIC6, 0, 20, 0,
9173 analog_gain),
9174};
9175
9176static const char * const spl_src0_mux_text[] = {
9177 "ZERO", "SRC_IN_HPHL", "SRC_IN_LO1",
9178};
9179
9180static const char * const spl_src1_mux_text[] = {
9181 "ZERO", "SRC_IN_HPHR", "SRC_IN_LO2",
9182};
9183
9184static const char * const spl_src2_mux_text[] = {
9185 "ZERO", "SRC_IN_LO3", "SRC_IN_SPKRL",
9186};
9187
9188static const char * const spl_src3_mux_text[] = {
9189 "ZERO", "SRC_IN_LO4", "SRC_IN_SPKRR",
9190};
9191
9192static const char * const rx_int0_7_mix_mux_text[] = {
9193 "ZERO", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5",
9194 "RX6", "RX7", "PROXIMITY"
9195};
9196
9197static const char * const rx_int_mix_mux_text[] = {
9198 "ZERO", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5",
9199 "RX6", "RX7"
9200};
9201
9202static const char * const rx_prim_mix_text[] = {
9203 "ZERO", "DEC0", "DEC1", "IIR0", "IIR1", "RX0", "RX1", "RX2",
9204 "RX3", "RX4", "RX5", "RX6", "RX7"
9205};
9206
9207static const char * const rx_sidetone_mix_text[] = {
9208 "ZERO", "SRC0", "SRC1", "SRC_SUM"
9209};
9210
9211static const char * const sb_tx0_mux_text[] = {
9212 "ZERO", "RX_MIX_TX0", "DEC0", "DEC0_192"
9213};
9214
9215static const char * const sb_tx1_mux_text[] = {
9216 "ZERO", "RX_MIX_TX1", "DEC1", "DEC1_192"
9217};
9218
9219static const char * const sb_tx2_mux_text[] = {
9220 "ZERO", "RX_MIX_TX2", "DEC2", "DEC2_192"
9221};
9222
9223static const char * const sb_tx3_mux_text[] = {
9224 "ZERO", "RX_MIX_TX3", "DEC3", "DEC3_192"
9225};
9226
9227static const char * const sb_tx4_mux_text[] = {
9228 "ZERO", "RX_MIX_TX4", "DEC4", "DEC4_192"
9229};
9230
9231static const char * const sb_tx5_mux_text[] = {
9232 "ZERO", "RX_MIX_TX5", "DEC5", "DEC5_192"
9233};
9234
9235static const char * const sb_tx6_mux_text[] = {
9236 "ZERO", "RX_MIX_TX6", "DEC6", "DEC6_192"
9237};
9238
9239static const char * const sb_tx7_mux_text[] = {
9240 "ZERO", "RX_MIX_TX7", "DEC7", "DEC7_192"
9241};
9242
9243static const char * const sb_tx8_mux_text[] = {
9244 "ZERO", "RX_MIX_TX8", "DEC8", "DEC8_192"
9245};
9246
9247static const char * const sb_tx9_mux_text[] = {
9248 "ZERO", "DEC7", "DEC7_192"
9249};
9250
9251static const char * const sb_tx10_mux_text[] = {
9252 "ZERO", "DEC6", "DEC6_192"
9253};
9254
9255static const char * const sb_tx11_mux_text[] = {
9256 "DEC_0_5", "DEC_9_12", "MAD_AUDIO", "MAD_BRDCST"
9257};
9258
9259static const char * const sb_tx11_inp1_mux_text[] = {
9260 "ZERO", "DEC0", "DEC1", "DEC2", "DEC3", "DEC4",
9261 "DEC5", "RX_MIX_TX5", "DEC9_10", "DEC11_12"
9262};
9263
9264static const char * const sb_tx13_mux_text[] = {
9265 "ZERO", "DEC5", "DEC5_192"
9266};
9267
9268static const char * const tx13_inp_mux_text[] = {
9269 "CDC_DEC_5", "MAD_BRDCST", "CPE_TX_PP"
9270};
9271
9272static const char * const iir_inp_mux_text[] = {
9273 "ZERO", "DEC0", "DEC1", "DEC2", "DEC3", "DEC4", "DEC5", "DEC6",
9274 "DEC7", "DEC8", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5", "RX6", "RX7"
9275};
9276
9277static const char * const rx_int_dem_inp_mux_text[] = {
9278 "NORMAL_DSM_OUT", "CLSH_DSM_OUT",
9279};
9280
9281static const char * const rx_int0_interp_mux_text[] = {
9282 "ZERO", "RX INT0 MIX2",
9283};
9284
9285static const char * const rx_int1_interp_mux_text[] = {
9286 "ZERO", "RX INT1 MIX2",
9287};
9288
9289static const char * const rx_int2_interp_mux_text[] = {
9290 "ZERO", "RX INT2 MIX2",
9291};
9292
9293static const char * const rx_int3_interp_mux_text[] = {
9294 "ZERO", "RX INT3 MIX2",
9295};
9296
9297static const char * const rx_int4_interp_mux_text[] = {
9298 "ZERO", "RX INT4 MIX2",
9299};
9300
9301static const char * const rx_int5_interp_mux_text[] = {
9302 "ZERO", "RX INT5 MIX2",
9303};
9304
9305static const char * const rx_int6_interp_mux_text[] = {
9306 "ZERO", "RX INT6 MIX2",
9307};
9308
9309static const char * const rx_int7_interp_mux_text[] = {
9310 "ZERO", "RX INT7 MIX2",
9311};
9312
9313static const char * const rx_int8_interp_mux_text[] = {
9314 "ZERO", "RX INT8 SEC MIX"
9315};
9316
9317static const char * const mad_sel_text[] = {
9318 "SPE", "MSM"
9319};
9320
9321static const char * const adc_mux_text[] = {
9322 "DMIC", "AMIC", "ANC_FB_TUNE1", "ANC_FB_TUNE2"
9323};
9324
9325static const char * const dmic_mux_text[] = {
9326 "ZERO", "DMIC0", "DMIC1", "DMIC2", "DMIC3", "DMIC4", "DMIC5",
9327 "SMIC0", "SMIC1", "SMIC2", "SMIC3"
9328};
9329
9330static const char * const dmic_mux_alt_text[] = {
9331 "ZERO", "DMIC0", "DMIC1", "DMIC2", "DMIC3", "DMIC4", "DMIC5",
9332};
9333
9334static const char * const amic_mux_text[] = {
9335 "ZERO", "ADC1", "ADC2", "ADC3", "ADC4", "ADC5", "ADC6"
9336};
9337
9338static const char * const rx_echo_mux_text[] = {
9339 "ZERO", "RX_MIX0", "RX_MIX1", "RX_MIX2", "RX_MIX3", "RX_MIX4",
9340 "RX_MIX5", "RX_MIX6", "RX_MIX7", "RX_MIX8", "RX_MIX_VBAT5",
9341 "RX_MIX_VBAT6", "RX_MIX_VBAT7", "RX_MIX_VBAT8"
9342};
9343
9344static const char * const anc0_fb_mux_text[] = {
9345 "ZERO", "ANC_IN_HPHL", "ANC_IN_EAR", "ANC_IN_EAR_SPKR",
9346 "ANC_IN_LO1"
9347};
9348
9349static const char * const anc1_fb_mux_text[] = {
9350 "ZERO", "ANC_IN_HPHR", "ANC_IN_LO2"
9351};
9352
9353static const char * const native_mux_text[] = {
9354 "OFF", "ON",
9355};
9356
9357static const struct soc_enum spl_src0_mux_chain_enum =
9358 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SPLINE_SRC_CFG0, 0, 3,
9359 spl_src0_mux_text);
9360
9361static const struct soc_enum spl_src1_mux_chain_enum =
9362 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SPLINE_SRC_CFG0, 2, 3,
9363 spl_src1_mux_text);
9364
9365static const struct soc_enum spl_src2_mux_chain_enum =
9366 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SPLINE_SRC_CFG0, 4, 3,
9367 spl_src2_mux_text);
9368
9369static const struct soc_enum spl_src3_mux_chain_enum =
9370 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SPLINE_SRC_CFG0, 6, 3,
9371 spl_src3_mux_text);
9372
9373static const struct soc_enum rx_int0_2_mux_chain_enum =
9374 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG1, 0, 10,
9375 rx_int0_7_mix_mux_text);
9376
9377static const struct soc_enum rx_int1_2_mux_chain_enum =
9378 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG1, 0, 9,
9379 rx_int_mix_mux_text);
9380
9381static const struct soc_enum rx_int2_2_mux_chain_enum =
9382 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG1, 0, 9,
9383 rx_int_mix_mux_text);
9384
9385static const struct soc_enum rx_int3_2_mux_chain_enum =
9386 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG1, 0, 9,
9387 rx_int_mix_mux_text);
9388
9389static const struct soc_enum rx_int4_2_mux_chain_enum =
9390 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG1, 0, 9,
9391 rx_int_mix_mux_text);
9392
9393static const struct soc_enum rx_int5_2_mux_chain_enum =
9394 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG1, 0, 9,
9395 rx_int_mix_mux_text);
9396
9397static const struct soc_enum rx_int6_2_mux_chain_enum =
9398 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG1, 0, 9,
9399 rx_int_mix_mux_text);
9400
9401static const struct soc_enum rx_int7_2_mux_chain_enum =
9402 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG1, 0, 10,
9403 rx_int0_7_mix_mux_text);
9404
9405static const struct soc_enum rx_int8_2_mux_chain_enum =
9406 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG1, 0, 9,
9407 rx_int_mix_mux_text);
9408
9409static const struct soc_enum int1_1_native_enum =
9410 SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(native_mux_text),
9411 native_mux_text);
9412
9413static const struct soc_enum int2_1_native_enum =
9414 SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(native_mux_text),
9415 native_mux_text);
9416
9417static const struct soc_enum int3_1_native_enum =
9418 SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(native_mux_text),
9419 native_mux_text);
9420
9421static const struct soc_enum int4_1_native_enum =
9422 SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(native_mux_text),
9423 native_mux_text);
9424
9425static const struct soc_enum rx_int0_1_mix_inp0_chain_enum =
9426 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG0, 0, 13,
9427 rx_prim_mix_text);
9428
9429static const struct soc_enum rx_int0_1_mix_inp1_chain_enum =
9430 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG0, 4, 13,
9431 rx_prim_mix_text);
9432
9433static const struct soc_enum rx_int0_1_mix_inp2_chain_enum =
9434 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG1, 4, 13,
9435 rx_prim_mix_text);
9436
9437static const struct soc_enum rx_int1_1_mix_inp0_chain_enum =
9438 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG0, 0, 13,
9439 rx_prim_mix_text);
9440
9441static const struct soc_enum rx_int1_1_mix_inp1_chain_enum =
9442 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG0, 4, 13,
9443 rx_prim_mix_text);
9444
9445static const struct soc_enum rx_int1_1_mix_inp2_chain_enum =
9446 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG1, 4, 13,
9447 rx_prim_mix_text);
9448
9449static const struct soc_enum rx_int2_1_mix_inp0_chain_enum =
9450 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG0, 0, 13,
9451 rx_prim_mix_text);
9452
9453static const struct soc_enum rx_int2_1_mix_inp1_chain_enum =
9454 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG0, 4, 13,
9455 rx_prim_mix_text);
9456
9457static const struct soc_enum rx_int2_1_mix_inp2_chain_enum =
9458 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG1, 4, 13,
9459 rx_prim_mix_text);
9460
9461static const struct soc_enum rx_int3_1_mix_inp0_chain_enum =
9462 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG0, 0, 13,
9463 rx_prim_mix_text);
9464
9465static const struct soc_enum rx_int3_1_mix_inp1_chain_enum =
9466 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG0, 4, 13,
9467 rx_prim_mix_text);
9468
9469static const struct soc_enum rx_int3_1_mix_inp2_chain_enum =
9470 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG1, 4, 13,
9471 rx_prim_mix_text);
9472
9473static const struct soc_enum rx_int4_1_mix_inp0_chain_enum =
9474 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG0, 0, 13,
9475 rx_prim_mix_text);
9476
9477static const struct soc_enum rx_int4_1_mix_inp1_chain_enum =
9478 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG0, 4, 13,
9479 rx_prim_mix_text);
9480
9481static const struct soc_enum rx_int4_1_mix_inp2_chain_enum =
9482 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG1, 4, 13,
9483 rx_prim_mix_text);
9484
9485static const struct soc_enum rx_int5_1_mix_inp0_chain_enum =
9486 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG0, 0, 13,
9487 rx_prim_mix_text);
9488
9489static const struct soc_enum rx_int5_1_mix_inp1_chain_enum =
9490 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG0, 4, 13,
9491 rx_prim_mix_text);
9492
9493static const struct soc_enum rx_int5_1_mix_inp2_chain_enum =
9494 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG1, 4, 13,
9495 rx_prim_mix_text);
9496
9497static const struct soc_enum rx_int6_1_mix_inp0_chain_enum =
9498 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG0, 0, 13,
9499 rx_prim_mix_text);
9500
9501static const struct soc_enum rx_int6_1_mix_inp1_chain_enum =
9502 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG0, 4, 13,
9503 rx_prim_mix_text);
9504
9505static const struct soc_enum rx_int6_1_mix_inp2_chain_enum =
9506 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG1, 4, 13,
9507 rx_prim_mix_text);
9508
9509static const struct soc_enum rx_int7_1_mix_inp0_chain_enum =
9510 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG0, 0, 13,
9511 rx_prim_mix_text);
9512
9513static const struct soc_enum rx_int7_1_mix_inp1_chain_enum =
9514 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG0, 4, 13,
9515 rx_prim_mix_text);
9516
9517static const struct soc_enum rx_int7_1_mix_inp2_chain_enum =
9518 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG1, 4, 13,
9519 rx_prim_mix_text);
9520
9521static const struct soc_enum rx_int8_1_mix_inp0_chain_enum =
9522 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG0, 0, 13,
9523 rx_prim_mix_text);
9524
9525static const struct soc_enum rx_int8_1_mix_inp1_chain_enum =
9526 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG0, 4, 13,
9527 rx_prim_mix_text);
9528
9529static const struct soc_enum rx_int8_1_mix_inp2_chain_enum =
9530 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG1, 4, 13,
9531 rx_prim_mix_text);
9532
9533static const struct soc_enum rx_int0_sidetone_mix_chain_enum =
9534 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 0, 4,
9535 rx_sidetone_mix_text);
9536
9537static const struct soc_enum rx_int1_sidetone_mix_chain_enum =
9538 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 2, 4,
9539 rx_sidetone_mix_text);
9540
9541static const struct soc_enum rx_int2_sidetone_mix_chain_enum =
9542 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 4, 4,
9543 rx_sidetone_mix_text);
9544
9545static const struct soc_enum rx_int3_sidetone_mix_chain_enum =
9546 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 6, 4,
9547 rx_sidetone_mix_text);
9548
9549static const struct soc_enum rx_int4_sidetone_mix_chain_enum =
9550 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SIDETONE_SRC_CFG1, 0, 4,
9551 rx_sidetone_mix_text);
9552
9553static const struct soc_enum rx_int7_sidetone_mix_chain_enum =
9554 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SIDETONE_SRC_CFG1, 2, 4,
9555 rx_sidetone_mix_text);
9556
9557static const struct soc_enum tx_adc_mux0_chain_enum =
9558 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG1, 0, 4,
9559 adc_mux_text);
9560
9561static const struct soc_enum tx_adc_mux1_chain_enum =
9562 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX1_CFG1, 0, 4,
9563 adc_mux_text);
9564
9565static const struct soc_enum tx_adc_mux2_chain_enum =
9566 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX2_CFG1, 0, 4,
9567 adc_mux_text);
9568
9569static const struct soc_enum tx_adc_mux3_chain_enum =
9570 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX3_CFG1, 0, 4,
9571 adc_mux_text);
9572
9573static const struct soc_enum tx_adc_mux4_chain_enum =
9574 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0, 6, 4,
9575 adc_mux_text);
9576
9577static const struct soc_enum tx_adc_mux5_chain_enum =
9578 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX5_CFG0, 6, 4,
9579 adc_mux_text);
9580
9581static const struct soc_enum tx_adc_mux6_chain_enum =
9582 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX6_CFG0, 6, 4,
9583 adc_mux_text);
9584
9585static const struct soc_enum tx_adc_mux7_chain_enum =
9586 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 6, 4,
9587 adc_mux_text);
9588
9589static const struct soc_enum tx_adc_mux8_chain_enum =
9590 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX8_CFG0, 6, 4,
9591 adc_mux_text);
9592
9593static const struct soc_enum tx_adc_mux10_chain_enum =
9594 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX10_CFG0, 6, 4,
9595 adc_mux_text);
9596
9597static const struct soc_enum tx_adc_mux11_chain_enum =
9598 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX11_CFG0, 6, 4,
9599 adc_mux_text);
9600
9601static const struct soc_enum tx_adc_mux12_chain_enum =
9602 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX12_CFG0, 6, 4,
9603 adc_mux_text);
9604
9605static const struct soc_enum tx_adc_mux13_chain_enum =
9606 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX13_CFG0, 6, 4,
9607 adc_mux_text);
9608
9609static const struct soc_enum tx_dmic_mux0_enum =
9610 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG0, 3, 11,
9611 dmic_mux_text);
9612
9613static const struct soc_enum tx_dmic_mux1_enum =
9614 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX1_CFG0, 3, 11,
9615 dmic_mux_text);
9616
9617static const struct soc_enum tx_dmic_mux2_enum =
9618 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX2_CFG0, 3, 11,
9619 dmic_mux_text);
9620
9621static const struct soc_enum tx_dmic_mux3_enum =
9622 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX3_CFG0, 3, 11,
9623 dmic_mux_text);
9624
9625static const struct soc_enum tx_dmic_mux4_enum =
9626 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0, 3, 7,
9627 dmic_mux_alt_text);
9628
9629static const struct soc_enum tx_dmic_mux5_enum =
9630 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX5_CFG0, 3, 7,
9631 dmic_mux_alt_text);
9632
9633static const struct soc_enum tx_dmic_mux6_enum =
9634 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX6_CFG0, 3, 7,
9635 dmic_mux_alt_text);
9636
9637static const struct soc_enum tx_dmic_mux7_enum =
9638 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 3, 7,
9639 dmic_mux_alt_text);
9640
9641static const struct soc_enum tx_dmic_mux8_enum =
9642 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX8_CFG0, 3, 7,
9643 dmic_mux_alt_text);
9644
9645static const struct soc_enum tx_dmic_mux10_enum =
9646 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX10_CFG0, 3, 7,
9647 dmic_mux_alt_text);
9648
9649static const struct soc_enum tx_dmic_mux11_enum =
9650 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX11_CFG0, 3, 7,
9651 dmic_mux_alt_text);
9652
9653static const struct soc_enum tx_dmic_mux12_enum =
9654 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX12_CFG0, 3, 7,
9655 dmic_mux_alt_text);
9656
9657static const struct soc_enum tx_dmic_mux13_enum =
9658 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX13_CFG0, 3, 7,
9659 dmic_mux_alt_text);
9660
9661static const struct soc_enum tx_amic_mux0_enum =
9662 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG0, 0, 7,
9663 amic_mux_text);
9664
9665static const struct soc_enum tx_amic_mux1_enum =
9666 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX1_CFG0, 0, 7,
9667 amic_mux_text);
9668
9669static const struct soc_enum tx_amic_mux2_enum =
9670 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX2_CFG0, 0, 7,
9671 amic_mux_text);
9672
9673static const struct soc_enum tx_amic_mux3_enum =
9674 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX3_CFG0, 0, 7,
9675 amic_mux_text);
9676
9677static const struct soc_enum tx_amic_mux4_enum =
9678 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0, 0, 7,
9679 amic_mux_text);
9680
9681static const struct soc_enum tx_amic_mux5_enum =
9682 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX5_CFG0, 0, 7,
9683 amic_mux_text);
9684
9685static const struct soc_enum tx_amic_mux6_enum =
9686 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX6_CFG0, 0, 7,
9687 amic_mux_text);
9688
9689static const struct soc_enum tx_amic_mux7_enum =
9690 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 0, 7,
9691 amic_mux_text);
9692
9693static const struct soc_enum tx_amic_mux8_enum =
9694 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX8_CFG0, 0, 7,
9695 amic_mux_text);
9696
9697static const struct soc_enum tx_amic_mux10_enum =
9698 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX10_CFG0, 0, 7,
9699 amic_mux_text);
9700
9701static const struct soc_enum tx_amic_mux11_enum =
9702 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX11_CFG0, 0, 7,
9703 amic_mux_text);
9704
9705static const struct soc_enum tx_amic_mux12_enum =
9706 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX12_CFG0, 0, 7,
9707 amic_mux_text);
9708
9709static const struct soc_enum tx_amic_mux13_enum =
9710 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX13_CFG0, 0, 7,
9711 amic_mux_text);
9712
9713static const struct soc_enum sb_tx0_mux_enum =
9714 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0, 0, 4,
9715 sb_tx0_mux_text);
9716
9717static const struct soc_enum sb_tx1_mux_enum =
9718 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0, 2, 4,
9719 sb_tx1_mux_text);
9720
9721static const struct soc_enum sb_tx2_mux_enum =
9722 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0, 4, 4,
9723 sb_tx2_mux_text);
9724
9725static const struct soc_enum sb_tx3_mux_enum =
9726 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0, 6, 4,
9727 sb_tx3_mux_text);
9728
9729static const struct soc_enum sb_tx4_mux_enum =
9730 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1, 0, 4,
9731 sb_tx4_mux_text);
9732
9733static const struct soc_enum sb_tx5_mux_enum =
9734 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1, 2, 4,
9735 sb_tx5_mux_text);
9736
9737static const struct soc_enum sb_tx6_mux_enum =
9738 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1, 4, 4,
9739 sb_tx6_mux_text);
9740
9741static const struct soc_enum sb_tx7_mux_enum =
9742 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1, 6, 4,
9743 sb_tx7_mux_text);
9744
9745static const struct soc_enum sb_tx8_mux_enum =
9746 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG2, 0, 4,
9747 sb_tx8_mux_text);
9748
9749static const struct soc_enum sb_tx9_mux_enum =
9750 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG2, 2, 3,
9751 sb_tx9_mux_text);
9752
9753static const struct soc_enum sb_tx10_mux_enum =
9754 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG2, 4, 3,
9755 sb_tx10_mux_text);
9756
9757static const struct soc_enum sb_tx11_mux_enum =
9758 SOC_ENUM_SINGLE(WCD9335_DATA_HUB_DATA_HUB_SB_TX11_INP_CFG, 0, 4,
9759 sb_tx11_mux_text);
9760
9761static const struct soc_enum sb_tx11_inp1_mux_enum =
9762 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG3, 0, 10,
9763 sb_tx11_inp1_mux_text);
9764
9765static const struct soc_enum sb_tx13_mux_enum =
9766 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG3, 4, 3,
9767 sb_tx13_mux_text);
9768
9769static const struct soc_enum tx13_inp_mux_enum =
9770 SOC_ENUM_SINGLE(WCD9335_DATA_HUB_DATA_HUB_SB_TX13_INP_CFG, 0, 3,
9771 tx13_inp_mux_text);
9772
9773static const struct soc_enum rx_mix_tx0_mux_enum =
9774 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG0, 0, 14,
9775 rx_echo_mux_text);
9776
9777static const struct soc_enum rx_mix_tx1_mux_enum =
9778 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG0, 4, 14,
9779 rx_echo_mux_text);
9780
9781static const struct soc_enum rx_mix_tx2_mux_enum =
9782 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG1, 0, 14,
9783 rx_echo_mux_text);
9784
9785static const struct soc_enum rx_mix_tx3_mux_enum =
9786 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG1, 4, 14,
9787 rx_echo_mux_text);
9788
9789static const struct soc_enum rx_mix_tx4_mux_enum =
9790 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG2, 0, 14,
9791 rx_echo_mux_text);
9792
9793static const struct soc_enum rx_mix_tx5_mux_enum =
9794 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG2, 4, 14,
9795 rx_echo_mux_text);
9796
9797static const struct soc_enum rx_mix_tx6_mux_enum =
9798 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG3, 0, 14,
9799 rx_echo_mux_text);
9800
9801static const struct soc_enum rx_mix_tx7_mux_enum =
9802 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG3, 4, 14,
9803 rx_echo_mux_text);
9804
9805static const struct soc_enum rx_mix_tx8_mux_enum =
9806 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG4, 0, 14,
9807 rx_echo_mux_text);
9808
9809static const struct soc_enum iir0_inp0_mux_enum =
9810 SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG0, 0, 18,
9811 iir_inp_mux_text);
9812
9813static const struct soc_enum iir0_inp1_mux_enum =
9814 SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG1, 0, 18,
9815 iir_inp_mux_text);
9816
9817static const struct soc_enum iir0_inp2_mux_enum =
9818 SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG2, 0, 18,
9819 iir_inp_mux_text);
9820
9821static const struct soc_enum iir0_inp3_mux_enum =
9822 SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG3, 0, 18,
9823 iir_inp_mux_text);
9824
9825static const struct soc_enum iir1_inp0_mux_enum =
9826 SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG0, 0, 18,
9827 iir_inp_mux_text);
9828
9829static const struct soc_enum iir1_inp1_mux_enum =
9830 SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG1, 0, 18,
9831 iir_inp_mux_text);
9832
9833static const struct soc_enum iir1_inp2_mux_enum =
9834 SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG2, 0, 18,
9835 iir_inp_mux_text);
9836
9837static const struct soc_enum iir1_inp3_mux_enum =
9838 SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG3, 0, 18,
9839 iir_inp_mux_text);
9840
9841static const struct soc_enum rx_int0_dem_inp_mux_enum =
9842 SOC_ENUM_SINGLE(WCD9335_CDC_RX0_RX_PATH_SEC0, 0,
9843 ARRAY_SIZE(rx_int_dem_inp_mux_text),
9844 rx_int_dem_inp_mux_text);
9845
9846static const struct soc_enum rx_int1_dem_inp_mux_enum =
9847 SOC_ENUM_SINGLE(WCD9335_CDC_RX1_RX_PATH_SEC0, 0,
9848 ARRAY_SIZE(rx_int_dem_inp_mux_text),
9849 rx_int_dem_inp_mux_text);
9850
9851static const struct soc_enum rx_int2_dem_inp_mux_enum =
9852 SOC_ENUM_SINGLE(WCD9335_CDC_RX2_RX_PATH_SEC0, 0,
9853 ARRAY_SIZE(rx_int_dem_inp_mux_text),
9854 rx_int_dem_inp_mux_text);
9855
9856static const struct soc_enum rx_int0_interp_mux_enum =
9857 SOC_ENUM_SINGLE(WCD9335_CDC_RX0_RX_PATH_CTL, 5, 2,
9858 rx_int0_interp_mux_text);
9859
9860static const struct soc_enum rx_int1_interp_mux_enum =
9861 SOC_ENUM_SINGLE(WCD9335_CDC_RX1_RX_PATH_CTL, 5, 2,
9862 rx_int1_interp_mux_text);
9863
9864static const struct soc_enum rx_int2_interp_mux_enum =
9865 SOC_ENUM_SINGLE(WCD9335_CDC_RX2_RX_PATH_CTL, 5, 2,
9866 rx_int2_interp_mux_text);
9867
9868static const struct soc_enum rx_int3_interp_mux_enum =
9869 SOC_ENUM_SINGLE(WCD9335_CDC_RX3_RX_PATH_CTL, 5, 2,
9870 rx_int3_interp_mux_text);
9871
9872static const struct soc_enum rx_int4_interp_mux_enum =
9873 SOC_ENUM_SINGLE(WCD9335_CDC_RX4_RX_PATH_CTL, 5, 2,
9874 rx_int4_interp_mux_text);
9875
9876static const struct soc_enum rx_int5_interp_mux_enum =
9877 SOC_ENUM_SINGLE(WCD9335_CDC_RX5_RX_PATH_CTL, 5, 2,
9878 rx_int5_interp_mux_text);
9879
9880static const struct soc_enum rx_int6_interp_mux_enum =
9881 SOC_ENUM_SINGLE(WCD9335_CDC_RX6_RX_PATH_CTL, 5, 2,
9882 rx_int6_interp_mux_text);
9883
9884static const struct soc_enum rx_int7_interp_mux_enum =
9885 SOC_ENUM_SINGLE(WCD9335_CDC_RX7_RX_PATH_CTL, 5, 2,
9886 rx_int7_interp_mux_text);
9887
9888static const struct soc_enum rx_int8_interp_mux_enum =
9889 SOC_ENUM_SINGLE(WCD9335_CDC_RX8_RX_PATH_CTL, 5, 2,
9890 rx_int8_interp_mux_text);
9891
9892static const struct soc_enum mad_sel_enum =
9893 SOC_ENUM_SINGLE(WCD9335_CPE_SS_CFG, 0, 2, mad_sel_text);
9894
9895static const struct soc_enum anc0_fb_mux_enum =
9896 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_ANC_CFG0, 0, 5,
9897 anc0_fb_mux_text);
9898
9899static const struct soc_enum anc1_fb_mux_enum =
9900 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_ANC_CFG0, 3, 3,
9901 anc1_fb_mux_text);
9902
9903static const struct snd_kcontrol_new rx_int0_dem_inp_mux =
9904 SOC_DAPM_ENUM_EXT("RX INT0 DEM MUX Mux", rx_int0_dem_inp_mux_enum,
9905 snd_soc_dapm_get_enum_double,
9906 tasha_int_dem_inp_mux_put);
9907
9908static const struct snd_kcontrol_new rx_int1_dem_inp_mux =
9909 SOC_DAPM_ENUM_EXT("RX INT1 DEM MUX Mux", rx_int1_dem_inp_mux_enum,
9910 snd_soc_dapm_get_enum_double,
9911 tasha_int_dem_inp_mux_put);
9912
9913static const struct snd_kcontrol_new rx_int2_dem_inp_mux =
9914 SOC_DAPM_ENUM_EXT("RX INT2 DEM MUX Mux", rx_int2_dem_inp_mux_enum,
9915 snd_soc_dapm_get_enum_double,
9916 tasha_int_dem_inp_mux_put);
9917
9918static const struct snd_kcontrol_new spl_src0_mux =
9919 SOC_DAPM_ENUM("SPL SRC0 MUX Mux", spl_src0_mux_chain_enum);
9920
9921static const struct snd_kcontrol_new spl_src1_mux =
9922 SOC_DAPM_ENUM("SPL SRC1 MUX Mux", spl_src1_mux_chain_enum);
9923
9924static const struct snd_kcontrol_new spl_src2_mux =
9925 SOC_DAPM_ENUM("SPL SRC2 MUX Mux", spl_src2_mux_chain_enum);
9926
9927static const struct snd_kcontrol_new spl_src3_mux =
9928 SOC_DAPM_ENUM("SPL SRC3 MUX Mux", spl_src3_mux_chain_enum);
9929
9930static const struct snd_kcontrol_new rx_int0_2_mux =
9931 SOC_DAPM_ENUM("RX INT0_2 MUX Mux", rx_int0_2_mux_chain_enum);
9932
9933static const struct snd_kcontrol_new rx_int1_2_mux =
9934 SOC_DAPM_ENUM("RX INT1_2 MUX Mux", rx_int1_2_mux_chain_enum);
9935
9936static const struct snd_kcontrol_new rx_int2_2_mux =
9937 SOC_DAPM_ENUM("RX INT2_2 MUX Mux", rx_int2_2_mux_chain_enum);
9938
9939static const struct snd_kcontrol_new rx_int3_2_mux =
9940 SOC_DAPM_ENUM("RX INT3_2 MUX Mux", rx_int3_2_mux_chain_enum);
9941
9942static const struct snd_kcontrol_new rx_int4_2_mux =
9943 SOC_DAPM_ENUM("RX INT4_2 MUX Mux", rx_int4_2_mux_chain_enum);
9944
9945static const struct snd_kcontrol_new rx_int5_2_mux =
9946 SOC_DAPM_ENUM("RX INT5_2 MUX Mux", rx_int5_2_mux_chain_enum);
9947
9948static const struct snd_kcontrol_new rx_int6_2_mux =
9949 SOC_DAPM_ENUM("RX INT6_2 MUX Mux", rx_int6_2_mux_chain_enum);
9950
9951static const struct snd_kcontrol_new rx_int7_2_mux =
9952 SOC_DAPM_ENUM("RX INT7_2 MUX Mux", rx_int7_2_mux_chain_enum);
9953
9954static const struct snd_kcontrol_new rx_int8_2_mux =
9955 SOC_DAPM_ENUM("RX INT8_2 MUX Mux", rx_int8_2_mux_chain_enum);
9956
9957static const struct snd_kcontrol_new int1_1_native_mux =
9958 SOC_DAPM_ENUM("RX INT1_1 NATIVE MUX Mux", int1_1_native_enum);
9959
9960static const struct snd_kcontrol_new int2_1_native_mux =
9961 SOC_DAPM_ENUM("RX INT2_1 NATIVE MUX Mux", int2_1_native_enum);
9962
9963static const struct snd_kcontrol_new int3_1_native_mux =
9964 SOC_DAPM_ENUM("RX INT3_1 NATIVE MUX Mux", int3_1_native_enum);
9965
9966static const struct snd_kcontrol_new int4_1_native_mux =
9967 SOC_DAPM_ENUM("RX INT4_1 NATIVE MUX Mux", int4_1_native_enum);
9968
9969static const struct snd_kcontrol_new rx_int0_1_mix_inp0_mux =
9970 SOC_DAPM_ENUM("RX INT0_1 MIX1 INP0 Mux", rx_int0_1_mix_inp0_chain_enum);
9971
9972static const struct snd_kcontrol_new rx_int0_1_mix_inp1_mux =
9973 SOC_DAPM_ENUM("RX INT0_1 MIX1 INP1 Mux", rx_int0_1_mix_inp1_chain_enum);
9974
9975static const struct snd_kcontrol_new rx_int0_1_mix_inp2_mux =
9976 SOC_DAPM_ENUM("RX INT0_1 MIX1 INP2 Mux", rx_int0_1_mix_inp2_chain_enum);
9977
9978static const struct snd_kcontrol_new rx_int1_1_mix_inp0_mux =
9979 SOC_DAPM_ENUM("RX INT1_1 MIX1 INP0 Mux", rx_int1_1_mix_inp0_chain_enum);
9980
9981static const struct snd_kcontrol_new rx_int1_1_mix_inp1_mux =
9982 SOC_DAPM_ENUM("RX INT1_1 MIX1 INP1 Mux", rx_int1_1_mix_inp1_chain_enum);
9983
9984static const struct snd_kcontrol_new rx_int1_1_mix_inp2_mux =
9985 SOC_DAPM_ENUM("RX INT1_1 MIX1 INP2 Mux", rx_int1_1_mix_inp2_chain_enum);
9986
9987static const struct snd_kcontrol_new rx_int2_1_mix_inp0_mux =
9988 SOC_DAPM_ENUM("RX INT2_1 MIX1 INP0 Mux", rx_int2_1_mix_inp0_chain_enum);
9989
9990static const struct snd_kcontrol_new rx_int2_1_mix_inp1_mux =
9991 SOC_DAPM_ENUM("RX INT2_1 MIX1 INP1 Mux", rx_int2_1_mix_inp1_chain_enum);
9992
9993static const struct snd_kcontrol_new rx_int2_1_mix_inp2_mux =
9994 SOC_DAPM_ENUM("RX INT2_1 MIX1 INP2 Mux", rx_int2_1_mix_inp2_chain_enum);
9995
9996static const struct snd_kcontrol_new rx_int3_1_mix_inp0_mux =
9997 SOC_DAPM_ENUM("RX INT3_1 MIX1 INP0 Mux", rx_int3_1_mix_inp0_chain_enum);
9998
9999static const struct snd_kcontrol_new rx_int3_1_mix_inp1_mux =
10000 SOC_DAPM_ENUM("RX INT3_1 MIX1 INP1 Mux", rx_int3_1_mix_inp1_chain_enum);
10001
10002static const struct snd_kcontrol_new rx_int3_1_mix_inp2_mux =
10003 SOC_DAPM_ENUM("RX INT3_1 MIX1 INP2 Mux", rx_int3_1_mix_inp2_chain_enum);
10004
10005static const struct snd_kcontrol_new rx_int4_1_mix_inp0_mux =
10006 SOC_DAPM_ENUM("RX INT4_1 MIX1 INP0 Mux", rx_int4_1_mix_inp0_chain_enum);
10007
10008static const struct snd_kcontrol_new rx_int4_1_mix_inp1_mux =
10009 SOC_DAPM_ENUM("RX INT4_1 MIX1 INP1 Mux", rx_int4_1_mix_inp1_chain_enum);
10010
10011static const struct snd_kcontrol_new rx_int4_1_mix_inp2_mux =
10012 SOC_DAPM_ENUM("RX INT4_1 MIX1 INP2 Mux", rx_int4_1_mix_inp2_chain_enum);
10013
10014static const struct snd_kcontrol_new rx_int5_1_mix_inp0_mux =
10015 SOC_DAPM_ENUM("RX INT5_1 MIX1 INP0 Mux", rx_int5_1_mix_inp0_chain_enum);
10016
10017static const struct snd_kcontrol_new rx_int5_1_mix_inp1_mux =
10018 SOC_DAPM_ENUM("RX INT5_1 MIX1 INP1 Mux", rx_int5_1_mix_inp1_chain_enum);
10019
10020static const struct snd_kcontrol_new rx_int5_1_mix_inp2_mux =
10021 SOC_DAPM_ENUM("RX INT5_1 MIX1 INP2 Mux", rx_int5_1_mix_inp2_chain_enum);
10022
10023static const struct snd_kcontrol_new rx_int6_1_mix_inp0_mux =
10024 SOC_DAPM_ENUM("RX INT6_1 MIX1 INP0 Mux", rx_int6_1_mix_inp0_chain_enum);
10025
10026static const struct snd_kcontrol_new rx_int6_1_mix_inp1_mux =
10027 SOC_DAPM_ENUM("RX INT6_1 MIX1 INP1 Mux", rx_int6_1_mix_inp1_chain_enum);
10028
10029static const struct snd_kcontrol_new rx_int6_1_mix_inp2_mux =
10030 SOC_DAPM_ENUM("RX INT6_1 MIX1 INP2 Mux", rx_int6_1_mix_inp2_chain_enum);
10031
10032static const struct snd_kcontrol_new rx_int7_1_mix_inp0_mux =
10033 SOC_DAPM_ENUM("RX INT7_1 MIX1 INP0 Mux", rx_int7_1_mix_inp0_chain_enum);
10034
10035static const struct snd_kcontrol_new rx_int7_1_mix_inp1_mux =
10036 SOC_DAPM_ENUM("RX INT7_1 MIX1 INP1 Mux", rx_int7_1_mix_inp1_chain_enum);
10037
10038static const struct snd_kcontrol_new rx_int7_1_mix_inp2_mux =
10039 SOC_DAPM_ENUM("RX INT7_1 MIX1 INP2 Mux", rx_int7_1_mix_inp2_chain_enum);
10040
10041static const struct snd_kcontrol_new rx_int8_1_mix_inp0_mux =
10042 SOC_DAPM_ENUM("RX INT8_1 MIX1 INP0 Mux", rx_int8_1_mix_inp0_chain_enum);
10043
10044static const struct snd_kcontrol_new rx_int8_1_mix_inp1_mux =
10045 SOC_DAPM_ENUM("RX INT8_1 MIX1 INP1 Mux", rx_int8_1_mix_inp1_chain_enum);
10046
10047static const struct snd_kcontrol_new rx_int8_1_mix_inp2_mux =
10048 SOC_DAPM_ENUM("RX INT8_1 MIX1 INP2 Mux", rx_int8_1_mix_inp2_chain_enum);
10049
10050static const struct snd_kcontrol_new rx_int0_mix2_inp_mux =
10051 SOC_DAPM_ENUM("RX INT0 MIX2 INP Mux", rx_int0_sidetone_mix_chain_enum);
10052
10053static const struct snd_kcontrol_new rx_int1_mix2_inp_mux =
10054 SOC_DAPM_ENUM("RX INT1 MIX2 INP Mux", rx_int1_sidetone_mix_chain_enum);
10055
10056static const struct snd_kcontrol_new rx_int2_mix2_inp_mux =
10057 SOC_DAPM_ENUM("RX INT2 MIX2 INP Mux", rx_int2_sidetone_mix_chain_enum);
10058
10059static const struct snd_kcontrol_new rx_int3_mix2_inp_mux =
10060 SOC_DAPM_ENUM("RX INT3 MIX2 INP Mux", rx_int3_sidetone_mix_chain_enum);
10061
10062static const struct snd_kcontrol_new rx_int4_mix2_inp_mux =
10063 SOC_DAPM_ENUM("RX INT4 MIX2 INP Mux", rx_int4_sidetone_mix_chain_enum);
10064
10065static const struct snd_kcontrol_new rx_int7_mix2_inp_mux =
10066 SOC_DAPM_ENUM("RX INT7 MIX2 INP Mux", rx_int7_sidetone_mix_chain_enum);
10067
10068static const struct snd_kcontrol_new tx_adc_mux0 =
10069 SOC_DAPM_ENUM_EXT("ADC MUX0 Mux", tx_adc_mux0_chain_enum,
10070 snd_soc_dapm_get_enum_double,
10071 tasha_put_dec_enum);
10072
10073static const struct snd_kcontrol_new tx_adc_mux1 =
10074 SOC_DAPM_ENUM_EXT("ADC MUX1 Mux", tx_adc_mux1_chain_enum,
10075 snd_soc_dapm_get_enum_double,
10076 tasha_put_dec_enum);
10077
10078static const struct snd_kcontrol_new tx_adc_mux2 =
10079 SOC_DAPM_ENUM_EXT("ADC MUX2 Mux", tx_adc_mux2_chain_enum,
10080 snd_soc_dapm_get_enum_double,
10081 tasha_put_dec_enum);
10082
10083static const struct snd_kcontrol_new tx_adc_mux3 =
10084 SOC_DAPM_ENUM_EXT("ADC MUX3 Mux", tx_adc_mux3_chain_enum,
10085 snd_soc_dapm_get_enum_double,
10086 tasha_put_dec_enum);
10087
10088static const struct snd_kcontrol_new tx_adc_mux4 =
10089 SOC_DAPM_ENUM_EXT("ADC MUX4 Mux", tx_adc_mux4_chain_enum,
10090 snd_soc_dapm_get_enum_double,
10091 tasha_put_dec_enum);
10092
10093static const struct snd_kcontrol_new tx_adc_mux5 =
10094 SOC_DAPM_ENUM_EXT("ADC MUX5 Mux", tx_adc_mux5_chain_enum,
10095 snd_soc_dapm_get_enum_double,
10096 tasha_put_dec_enum);
10097
10098static const struct snd_kcontrol_new tx_adc_mux6 =
10099 SOC_DAPM_ENUM_EXT("ADC MUX6 Mux", tx_adc_mux6_chain_enum,
10100 snd_soc_dapm_get_enum_double,
10101 tasha_put_dec_enum);
10102
10103static const struct snd_kcontrol_new tx_adc_mux7 =
10104 SOC_DAPM_ENUM_EXT("ADC MUX7 Mux", tx_adc_mux7_chain_enum,
10105 snd_soc_dapm_get_enum_double,
10106 tasha_put_dec_enum);
10107
10108static const struct snd_kcontrol_new tx_adc_mux8 =
10109 SOC_DAPM_ENUM_EXT("ADC MUX8 Mux", tx_adc_mux8_chain_enum,
10110 snd_soc_dapm_get_enum_double,
10111 tasha_put_dec_enum);
10112
10113static const struct snd_kcontrol_new tx_adc_mux10 =
10114 SOC_DAPM_ENUM("ADC MUX10 Mux", tx_adc_mux10_chain_enum);
10115
10116static const struct snd_kcontrol_new tx_adc_mux11 =
10117 SOC_DAPM_ENUM("ADC MUX11 Mux", tx_adc_mux11_chain_enum);
10118
10119static const struct snd_kcontrol_new tx_adc_mux12 =
10120 SOC_DAPM_ENUM("ADC MUX12 Mux", tx_adc_mux12_chain_enum);
10121
10122static const struct snd_kcontrol_new tx_adc_mux13 =
10123 SOC_DAPM_ENUM("ADC MUX13 Mux", tx_adc_mux13_chain_enum);
10124
10125static const struct snd_kcontrol_new tx_dmic_mux0 =
10126 SOC_DAPM_ENUM("DMIC MUX0 Mux", tx_dmic_mux0_enum);
10127
10128static const struct snd_kcontrol_new tx_dmic_mux1 =
10129 SOC_DAPM_ENUM("DMIC MUX1 Mux", tx_dmic_mux1_enum);
10130
10131static const struct snd_kcontrol_new tx_dmic_mux2 =
10132 SOC_DAPM_ENUM("DMIC MUX2 Mux", tx_dmic_mux2_enum);
10133
10134static const struct snd_kcontrol_new tx_dmic_mux3 =
10135 SOC_DAPM_ENUM("DMIC MUX3 Mux", tx_dmic_mux3_enum);
10136
10137static const struct snd_kcontrol_new tx_dmic_mux4 =
10138 SOC_DAPM_ENUM("DMIC MUX4 Mux", tx_dmic_mux4_enum);
10139
10140static const struct snd_kcontrol_new tx_dmic_mux5 =
10141 SOC_DAPM_ENUM("DMIC MUX5 Mux", tx_dmic_mux5_enum);
10142
10143static const struct snd_kcontrol_new tx_dmic_mux6 =
10144 SOC_DAPM_ENUM("DMIC MUX6 Mux", tx_dmic_mux6_enum);
10145
10146static const struct snd_kcontrol_new tx_dmic_mux7 =
10147 SOC_DAPM_ENUM("DMIC MUX7 Mux", tx_dmic_mux7_enum);
10148
10149static const struct snd_kcontrol_new tx_dmic_mux8 =
10150 SOC_DAPM_ENUM("DMIC MUX8 Mux", tx_dmic_mux8_enum);
10151
10152static const struct snd_kcontrol_new tx_dmic_mux10 =
10153 SOC_DAPM_ENUM("DMIC MUX10 Mux", tx_dmic_mux10_enum);
10154
10155static const struct snd_kcontrol_new tx_dmic_mux11 =
10156 SOC_DAPM_ENUM("DMIC MUX11 Mux", tx_dmic_mux11_enum);
10157
10158static const struct snd_kcontrol_new tx_dmic_mux12 =
10159 SOC_DAPM_ENUM("DMIC MUX12 Mux", tx_dmic_mux12_enum);
10160
10161static const struct snd_kcontrol_new tx_dmic_mux13 =
10162 SOC_DAPM_ENUM("DMIC MUX13 Mux", tx_dmic_mux13_enum);
10163
10164static const struct snd_kcontrol_new tx_amic_mux0 =
10165 SOC_DAPM_ENUM("AMIC MUX0 Mux", tx_amic_mux0_enum);
10166
10167static const struct snd_kcontrol_new tx_amic_mux1 =
10168 SOC_DAPM_ENUM("AMIC MUX1 Mux", tx_amic_mux1_enum);
10169
10170static const struct snd_kcontrol_new tx_amic_mux2 =
10171 SOC_DAPM_ENUM("AMIC MUX2 Mux", tx_amic_mux2_enum);
10172
10173static const struct snd_kcontrol_new tx_amic_mux3 =
10174 SOC_DAPM_ENUM("AMIC MUX3 Mux", tx_amic_mux3_enum);
10175
10176static const struct snd_kcontrol_new tx_amic_mux4 =
10177 SOC_DAPM_ENUM("AMIC MUX4 Mux", tx_amic_mux4_enum);
10178
10179static const struct snd_kcontrol_new tx_amic_mux5 =
10180 SOC_DAPM_ENUM("AMIC MUX5 Mux", tx_amic_mux5_enum);
10181
10182static const struct snd_kcontrol_new tx_amic_mux6 =
10183 SOC_DAPM_ENUM("AMIC MUX6 Mux", tx_amic_mux6_enum);
10184
10185static const struct snd_kcontrol_new tx_amic_mux7 =
10186 SOC_DAPM_ENUM("AMIC MUX7 Mux", tx_amic_mux7_enum);
10187
10188static const struct snd_kcontrol_new tx_amic_mux8 =
10189 SOC_DAPM_ENUM("AMIC MUX8 Mux", tx_amic_mux8_enum);
10190
10191static const struct snd_kcontrol_new tx_amic_mux10 =
10192 SOC_DAPM_ENUM("AMIC MUX10 Mux", tx_amic_mux10_enum);
10193
10194static const struct snd_kcontrol_new tx_amic_mux11 =
10195 SOC_DAPM_ENUM("AMIC MUX11 Mux", tx_amic_mux11_enum);
10196
10197static const struct snd_kcontrol_new tx_amic_mux12 =
10198 SOC_DAPM_ENUM("AMIC MUX12 Mux", tx_amic_mux12_enum);
10199
10200static const struct snd_kcontrol_new tx_amic_mux13 =
10201 SOC_DAPM_ENUM("AMIC MUX13 Mux", tx_amic_mux13_enum);
10202
10203static const struct snd_kcontrol_new sb_tx0_mux =
10204 SOC_DAPM_ENUM("SLIM TX0 MUX Mux", sb_tx0_mux_enum);
10205
10206static const struct snd_kcontrol_new sb_tx1_mux =
10207 SOC_DAPM_ENUM("SLIM TX1 MUX Mux", sb_tx1_mux_enum);
10208
10209static const struct snd_kcontrol_new sb_tx2_mux =
10210 SOC_DAPM_ENUM("SLIM TX2 MUX Mux", sb_tx2_mux_enum);
10211
10212static const struct snd_kcontrol_new sb_tx3_mux =
10213 SOC_DAPM_ENUM("SLIM TX3 MUX Mux", sb_tx3_mux_enum);
10214
10215static const struct snd_kcontrol_new sb_tx4_mux =
10216 SOC_DAPM_ENUM("SLIM TX4 MUX Mux", sb_tx4_mux_enum);
10217
10218static const struct snd_kcontrol_new sb_tx5_mux =
10219 SOC_DAPM_ENUM("SLIM TX5 MUX Mux", sb_tx5_mux_enum);
10220
10221static const struct snd_kcontrol_new sb_tx6_mux =
10222 SOC_DAPM_ENUM("SLIM TX6 MUX Mux", sb_tx6_mux_enum);
10223
10224static const struct snd_kcontrol_new sb_tx7_mux =
10225 SOC_DAPM_ENUM("SLIM TX7 MUX Mux", sb_tx7_mux_enum);
10226
10227static const struct snd_kcontrol_new sb_tx8_mux =
10228 SOC_DAPM_ENUM("SLIM TX8 MUX Mux", sb_tx8_mux_enum);
10229
10230static const struct snd_kcontrol_new sb_tx9_mux =
10231 SOC_DAPM_ENUM("SLIM TX9 MUX Mux", sb_tx9_mux_enum);
10232
10233static const struct snd_kcontrol_new sb_tx10_mux =
10234 SOC_DAPM_ENUM("SLIM TX10 MUX Mux", sb_tx10_mux_enum);
10235
10236static const struct snd_kcontrol_new sb_tx11_mux =
10237 SOC_DAPM_ENUM("SLIM TX11 MUX Mux", sb_tx11_mux_enum);
10238
10239static const struct snd_kcontrol_new sb_tx11_inp1_mux =
10240 SOC_DAPM_ENUM("SLIM TX11 INP1 MUX Mux", sb_tx11_inp1_mux_enum);
10241
10242static const struct snd_kcontrol_new sb_tx13_mux =
10243 SOC_DAPM_ENUM("SLIM TX13 MUX Mux", sb_tx13_mux_enum);
10244
10245static const struct snd_kcontrol_new tx13_inp_mux =
10246 SOC_DAPM_ENUM("TX13 INP MUX Mux", tx13_inp_mux_enum);
10247
10248static const struct snd_kcontrol_new rx_mix_tx0_mux =
10249 SOC_DAPM_ENUM("RX MIX TX0 MUX Mux", rx_mix_tx0_mux_enum);
10250
10251static const struct snd_kcontrol_new rx_mix_tx1_mux =
10252 SOC_DAPM_ENUM("RX MIX TX1 MUX Mux", rx_mix_tx1_mux_enum);
10253
10254static const struct snd_kcontrol_new rx_mix_tx2_mux =
10255 SOC_DAPM_ENUM("RX MIX TX2 MUX Mux", rx_mix_tx2_mux_enum);
10256
10257static const struct snd_kcontrol_new rx_mix_tx3_mux =
10258 SOC_DAPM_ENUM("RX MIX TX3 MUX Mux", rx_mix_tx3_mux_enum);
10259
10260static const struct snd_kcontrol_new rx_mix_tx4_mux =
10261 SOC_DAPM_ENUM("RX MIX TX4 MUX Mux", rx_mix_tx4_mux_enum);
10262
10263static const struct snd_kcontrol_new rx_mix_tx5_mux =
10264 SOC_DAPM_ENUM("RX MIX TX5 MUX Mux", rx_mix_tx5_mux_enum);
10265
10266static const struct snd_kcontrol_new rx_mix_tx6_mux =
10267 SOC_DAPM_ENUM("RX MIX TX6 MUX Mux", rx_mix_tx6_mux_enum);
10268
10269static const struct snd_kcontrol_new rx_mix_tx7_mux =
10270 SOC_DAPM_ENUM("RX MIX TX7 MUX Mux", rx_mix_tx7_mux_enum);
10271
10272static const struct snd_kcontrol_new rx_mix_tx8_mux =
10273 SOC_DAPM_ENUM("RX MIX TX8 MUX Mux", rx_mix_tx8_mux_enum);
10274
10275static const struct snd_kcontrol_new iir0_inp0_mux =
10276 SOC_DAPM_ENUM("IIR0 INP0 Mux", iir0_inp0_mux_enum);
10277
10278static const struct snd_kcontrol_new iir0_inp1_mux =
10279 SOC_DAPM_ENUM("IIR0 INP1 Mux", iir0_inp1_mux_enum);
10280
10281static const struct snd_kcontrol_new iir0_inp2_mux =
10282 SOC_DAPM_ENUM("IIR0 INP2 Mux", iir0_inp2_mux_enum);
10283
10284static const struct snd_kcontrol_new iir0_inp3_mux =
10285 SOC_DAPM_ENUM("IIR0 INP3 Mux", iir0_inp3_mux_enum);
10286
10287static const struct snd_kcontrol_new iir1_inp0_mux =
10288 SOC_DAPM_ENUM("IIR1 INP0 Mux", iir1_inp0_mux_enum);
10289
10290static const struct snd_kcontrol_new iir1_inp1_mux =
10291 SOC_DAPM_ENUM("IIR1 INP1 Mux", iir1_inp1_mux_enum);
10292
10293static const struct snd_kcontrol_new iir1_inp2_mux =
10294 SOC_DAPM_ENUM("IIR1 INP2 Mux", iir1_inp2_mux_enum);
10295
10296static const struct snd_kcontrol_new iir1_inp3_mux =
10297 SOC_DAPM_ENUM("IIR1 INP3 Mux", iir1_inp3_mux_enum);
10298
10299static const struct snd_kcontrol_new rx_int0_interp_mux =
10300 SOC_DAPM_ENUM("RX INT0 INTERP Mux", rx_int0_interp_mux_enum);
10301
10302static const struct snd_kcontrol_new rx_int1_interp_mux =
10303 SOC_DAPM_ENUM("RX INT1 INTERP Mux", rx_int1_interp_mux_enum);
10304
10305static const struct snd_kcontrol_new rx_int2_interp_mux =
10306 SOC_DAPM_ENUM("RX INT2 INTERP Mux", rx_int2_interp_mux_enum);
10307
10308static const struct snd_kcontrol_new rx_int3_interp_mux =
10309 SOC_DAPM_ENUM("RX INT3 INTERP Mux", rx_int3_interp_mux_enum);
10310
10311static const struct snd_kcontrol_new rx_int4_interp_mux =
10312 SOC_DAPM_ENUM("RX INT4 INTERP Mux", rx_int4_interp_mux_enum);
10313
10314static const struct snd_kcontrol_new rx_int5_interp_mux =
10315 SOC_DAPM_ENUM("RX INT5 INTERP Mux", rx_int5_interp_mux_enum);
10316
10317static const struct snd_kcontrol_new rx_int6_interp_mux =
10318 SOC_DAPM_ENUM("RX INT6 INTERP Mux", rx_int6_interp_mux_enum);
10319
10320static const struct snd_kcontrol_new rx_int7_interp_mux =
10321 SOC_DAPM_ENUM("RX INT7 INTERP Mux", rx_int7_interp_mux_enum);
10322
10323static const struct snd_kcontrol_new rx_int8_interp_mux =
10324 SOC_DAPM_ENUM("RX INT8 INTERP Mux", rx_int8_interp_mux_enum);
10325
10326static const struct snd_kcontrol_new mad_sel_mux =
10327 SOC_DAPM_ENUM("MAD_SEL MUX Mux", mad_sel_enum);
10328
10329static const struct snd_kcontrol_new aif4_mad_switch =
10330 SOC_DAPM_SINGLE("Switch", WCD9335_CPE_SS_CFG, 5, 1, 0);
10331
10332static const struct snd_kcontrol_new mad_brdcst_switch =
10333 SOC_DAPM_SINGLE("Switch", WCD9335_CPE_SS_CFG, 6, 1, 0);
10334
10335static const struct snd_kcontrol_new aif4_switch_mixer_controls =
10336 SOC_SINGLE_EXT("Switch", SND_SOC_NOPM,
10337 0, 1, 0, tasha_codec_aif4_mixer_switch_get,
10338 tasha_codec_aif4_mixer_switch_put);
10339
10340static const struct snd_kcontrol_new anc_hphl_switch =
10341 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
10342
10343static const struct snd_kcontrol_new anc_hphr_switch =
10344 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
10345
10346static const struct snd_kcontrol_new anc_ear_switch =
10347 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
10348
10349static const struct snd_kcontrol_new anc_ear_spkr_switch =
10350 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
10351
10352static const struct snd_kcontrol_new anc_lineout1_switch =
10353 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
10354
10355static const struct snd_kcontrol_new anc_lineout2_switch =
10356 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
10357
10358static const struct snd_kcontrol_new anc_spkr_pa_switch =
10359 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
10360
10361static const struct snd_kcontrol_new adc_us_mux0_switch =
10362 SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
10363
10364static const struct snd_kcontrol_new adc_us_mux1_switch =
10365 SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
10366
10367static const struct snd_kcontrol_new adc_us_mux2_switch =
10368 SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
10369
10370static const struct snd_kcontrol_new adc_us_mux3_switch =
10371 SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
10372
10373static const struct snd_kcontrol_new adc_us_mux4_switch =
10374 SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
10375
10376static const struct snd_kcontrol_new adc_us_mux5_switch =
10377 SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
10378
10379static const struct snd_kcontrol_new adc_us_mux6_switch =
10380 SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
10381
10382static const struct snd_kcontrol_new adc_us_mux7_switch =
10383 SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
10384
10385static const struct snd_kcontrol_new adc_us_mux8_switch =
10386 SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
10387
10388static const struct snd_kcontrol_new anc0_fb_mux =
10389 SOC_DAPM_ENUM("ANC0 FB MUX Mux", anc0_fb_mux_enum);
10390
10391static const struct snd_kcontrol_new anc1_fb_mux =
10392 SOC_DAPM_ENUM("ANC1 FB MUX Mux", anc1_fb_mux_enum);
10393
10394static int tasha_codec_ec_buf_mux_enable(struct snd_soc_dapm_widget *w,
10395 struct snd_kcontrol *kcontrol,
10396 int event)
10397{
10398 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
10399
10400 dev_dbg(codec->dev, "%s: event = %d name = %s\n",
10401 __func__, event, w->name);
10402
10403 switch (event) {
10404 case SND_SOC_DAPM_POST_PMU:
10405 snd_soc_write(codec, WCD9335_CPE_SS_EC_BUF_INT_PERIOD, 0x3B);
10406 snd_soc_update_bits(codec, WCD9335_CPE_SS_CFG, 0x08, 0x08);
10407 snd_soc_update_bits(codec, WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0,
10408 0x08, 0x08);
10409 break;
10410 case SND_SOC_DAPM_POST_PMD:
10411 snd_soc_update_bits(codec, WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0,
10412 0x08, 0x00);
10413 snd_soc_update_bits(codec, WCD9335_CPE_SS_CFG, 0x08, 0x00);
10414 snd_soc_write(codec, WCD9335_CPE_SS_EC_BUF_INT_PERIOD, 0x00);
10415 break;
10416 }
10417
10418 return 0;
10419};
10420
10421static const char * const ec_buf_mux_text[] = {
10422 "ZERO", "RXMIXEC", "SB_RX0", "SB_RX1", "SB_RX2", "SB_RX3",
10423 "I2S_RX_SD0_L", "I2S_RX_SD0_R", "I2S_RX_SD1_L", "I2S_RX_SD1_R",
10424 "DEC1"
10425};
10426
10427static SOC_ENUM_SINGLE_DECL(ec_buf_mux_enum, WCD9335_CPE_SS_US_EC_MUX_CFG,
10428 0, ec_buf_mux_text);
10429
10430static const struct snd_kcontrol_new ec_buf_mux =
10431 SOC_DAPM_ENUM("EC BUF Mux", ec_buf_mux_enum);
10432
10433static const struct snd_soc_dapm_widget tasha_dapm_widgets[] = {
10434 SND_SOC_DAPM_OUTPUT("EAR"),
10435 SND_SOC_DAPM_OUTPUT("ANC EAR"),
10436 SND_SOC_DAPM_AIF_IN_E("AIF1 PB", "AIF1 Playback", 0, SND_SOC_NOPM,
10437 AIF1_PB, 0, tasha_codec_enable_slimrx,
10438 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD |
10439 SND_SOC_DAPM_POST_PMD),
10440 SND_SOC_DAPM_AIF_IN_E("AIF2 PB", "AIF2 Playback", 0, SND_SOC_NOPM,
10441 AIF2_PB, 0, tasha_codec_enable_slimrx,
10442 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD |
10443 SND_SOC_DAPM_POST_PMD),
10444 SND_SOC_DAPM_AIF_IN_E("AIF3 PB", "AIF3 Playback", 0, SND_SOC_NOPM,
10445 AIF3_PB, 0, tasha_codec_enable_slimrx,
10446 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD |
10447 SND_SOC_DAPM_POST_PMD),
10448 SND_SOC_DAPM_AIF_IN_E("AIF4 PB", "AIF4 Playback", 0, SND_SOC_NOPM,
10449 AIF4_PB, 0, tasha_codec_enable_slimrx,
10450 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD |
10451 SND_SOC_DAPM_POST_PMD),
10452 SND_SOC_DAPM_AIF_IN_E("AIF MIX1 PB", "AIF Mix Playback", 0,
10453 SND_SOC_NOPM, AIF_MIX1_PB, 0,
10454 tasha_codec_enable_slimrx,
10455 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD |
10456 SND_SOC_DAPM_POST_PMD),
10457
10458 SND_SOC_DAPM_MUX("SLIM RX0 MUX", SND_SOC_NOPM, TASHA_RX0, 0,
10459 &slim_rx_mux[TASHA_RX0]),
10460 SND_SOC_DAPM_MUX("SLIM RX1 MUX", SND_SOC_NOPM, TASHA_RX1, 0,
10461 &slim_rx_mux[TASHA_RX1]),
10462 SND_SOC_DAPM_MUX("SLIM RX2 MUX", SND_SOC_NOPM, TASHA_RX2, 0,
10463 &slim_rx_mux[TASHA_RX2]),
10464 SND_SOC_DAPM_MUX("SLIM RX3 MUX", SND_SOC_NOPM, TASHA_RX3, 0,
10465 &slim_rx_mux[TASHA_RX3]),
10466 SND_SOC_DAPM_MUX("SLIM RX4 MUX", SND_SOC_NOPM, TASHA_RX4, 0,
10467 &slim_rx_mux[TASHA_RX4]),
10468 SND_SOC_DAPM_MUX("SLIM RX5 MUX", SND_SOC_NOPM, TASHA_RX5, 0,
10469 &slim_rx_mux[TASHA_RX5]),
10470 SND_SOC_DAPM_MUX("SLIM RX6 MUX", SND_SOC_NOPM, TASHA_RX6, 0,
10471 &slim_rx_mux[TASHA_RX6]),
10472 SND_SOC_DAPM_MUX("SLIM RX7 MUX", SND_SOC_NOPM, TASHA_RX7, 0,
10473 &slim_rx_mux[TASHA_RX7]),
10474
10475 SND_SOC_DAPM_MIXER("SLIM RX0", SND_SOC_NOPM, 0, 0, NULL, 0),
10476 SND_SOC_DAPM_MIXER("SLIM RX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10477 SND_SOC_DAPM_MIXER("SLIM RX2", SND_SOC_NOPM, 0, 0, NULL, 0),
10478 SND_SOC_DAPM_MIXER("SLIM RX3", SND_SOC_NOPM, 0, 0, NULL, 0),
10479 SND_SOC_DAPM_MIXER("SLIM RX4", SND_SOC_NOPM, 0, 0, NULL, 0),
10480 SND_SOC_DAPM_MIXER("SLIM RX5", SND_SOC_NOPM, 0, 0, NULL, 0),
10481 SND_SOC_DAPM_MIXER("SLIM RX6", SND_SOC_NOPM, 0, 0, NULL, 0),
10482 SND_SOC_DAPM_MIXER("SLIM RX7", SND_SOC_NOPM, 0, 0, NULL, 0),
10483
10484 SND_SOC_DAPM_MUX_E("SPL SRC0 MUX", SND_SOC_NOPM, SPLINE_SRC0, 0,
10485 &spl_src0_mux, tasha_codec_enable_spline_resampler,
10486 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10487 SND_SOC_DAPM_MUX_E("SPL SRC1 MUX", SND_SOC_NOPM, SPLINE_SRC1, 0,
10488 &spl_src1_mux, tasha_codec_enable_spline_resampler,
10489 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10490 SND_SOC_DAPM_MUX_E("SPL SRC2 MUX", SND_SOC_NOPM, SPLINE_SRC2, 0,
10491 &spl_src2_mux, tasha_codec_enable_spline_resampler,
10492 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10493 SND_SOC_DAPM_MUX_E("SPL SRC3 MUX", SND_SOC_NOPM, SPLINE_SRC3, 0,
10494 &spl_src3_mux, tasha_codec_enable_spline_resampler,
10495 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10496
10497 SND_SOC_DAPM_MUX_E("RX INT0_2 MUX", WCD9335_CDC_RX0_RX_PATH_MIX_CTL,
10498 5, 0, &rx_int0_2_mux, tasha_codec_enable_mix_path,
10499 SND_SOC_DAPM_POST_PMU),
10500 SND_SOC_DAPM_MUX_E("RX INT1_2 MUX", WCD9335_CDC_RX1_RX_PATH_MIX_CTL,
10501 5, 0, &rx_int1_2_mux, tasha_codec_enable_mix_path,
10502 SND_SOC_DAPM_POST_PMU),
10503 SND_SOC_DAPM_MUX_E("RX INT2_2 MUX", WCD9335_CDC_RX2_RX_PATH_MIX_CTL,
10504 5, 0, &rx_int2_2_mux, tasha_codec_enable_mix_path,
10505 SND_SOC_DAPM_POST_PMU),
10506 SND_SOC_DAPM_MUX_E("RX INT3_2 MUX", WCD9335_CDC_RX3_RX_PATH_MIX_CTL,
10507 5, 0, &rx_int3_2_mux, tasha_codec_enable_mix_path,
10508 SND_SOC_DAPM_POST_PMU),
10509 SND_SOC_DAPM_MUX_E("RX INT4_2 MUX", WCD9335_CDC_RX4_RX_PATH_MIX_CTL,
10510 5, 0, &rx_int4_2_mux, tasha_codec_enable_mix_path,
10511 SND_SOC_DAPM_POST_PMU),
10512 SND_SOC_DAPM_MUX_E("RX INT5_2 MUX", WCD9335_CDC_RX5_RX_PATH_MIX_CTL,
10513 5, 0, &rx_int5_2_mux, tasha_codec_enable_mix_path,
10514 SND_SOC_DAPM_POST_PMU),
10515 SND_SOC_DAPM_MUX_E("RX INT6_2 MUX", WCD9335_CDC_RX6_RX_PATH_MIX_CTL,
10516 5, 0, &rx_int6_2_mux, tasha_codec_enable_mix_path,
10517 SND_SOC_DAPM_POST_PMU),
10518 SND_SOC_DAPM_MUX_E("RX INT7_2 MUX", WCD9335_CDC_RX7_RX_PATH_MIX_CTL,
10519 5, 0, &rx_int7_2_mux, tasha_codec_enable_mix_path,
10520 SND_SOC_DAPM_POST_PMU),
10521 SND_SOC_DAPM_MUX_E("RX INT8_2 MUX", WCD9335_CDC_RX8_RX_PATH_MIX_CTL,
10522 5, 0, &rx_int8_2_mux, tasha_codec_enable_mix_path,
10523 SND_SOC_DAPM_POST_PMU),
10524
10525 SND_SOC_DAPM_MUX("RX INT0_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
10526 &rx_int0_1_mix_inp0_mux),
10527 SND_SOC_DAPM_MUX("RX INT0_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
10528 &rx_int0_1_mix_inp1_mux),
10529 SND_SOC_DAPM_MUX("RX INT0_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
10530 &rx_int0_1_mix_inp2_mux),
10531 SND_SOC_DAPM_MUX("RX INT1_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
10532 &rx_int1_1_mix_inp0_mux),
10533 SND_SOC_DAPM_MUX("RX INT1_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
10534 &rx_int1_1_mix_inp1_mux),
10535 SND_SOC_DAPM_MUX("RX INT1_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
10536 &rx_int1_1_mix_inp2_mux),
10537 SND_SOC_DAPM_MUX("RX INT2_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
10538 &rx_int2_1_mix_inp0_mux),
10539 SND_SOC_DAPM_MUX("RX INT2_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
10540 &rx_int2_1_mix_inp1_mux),
10541 SND_SOC_DAPM_MUX("RX INT2_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
10542 &rx_int2_1_mix_inp2_mux),
10543 SND_SOC_DAPM_MUX("RX INT3_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
10544 &rx_int3_1_mix_inp0_mux),
10545 SND_SOC_DAPM_MUX("RX INT3_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
10546 &rx_int3_1_mix_inp1_mux),
10547 SND_SOC_DAPM_MUX("RX INT3_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
10548 &rx_int3_1_mix_inp2_mux),
10549 SND_SOC_DAPM_MUX("RX INT4_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
10550 &rx_int4_1_mix_inp0_mux),
10551 SND_SOC_DAPM_MUX("RX INT4_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
10552 &rx_int4_1_mix_inp1_mux),
10553 SND_SOC_DAPM_MUX("RX INT4_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
10554 &rx_int4_1_mix_inp2_mux),
10555 SND_SOC_DAPM_MUX("RX INT5_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
10556 &rx_int5_1_mix_inp0_mux),
10557 SND_SOC_DAPM_MUX("RX INT5_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
10558 &rx_int5_1_mix_inp1_mux),
10559 SND_SOC_DAPM_MUX("RX INT5_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
10560 &rx_int5_1_mix_inp2_mux),
10561 SND_SOC_DAPM_MUX("RX INT6_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
10562 &rx_int6_1_mix_inp0_mux),
10563 SND_SOC_DAPM_MUX("RX INT6_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
10564 &rx_int6_1_mix_inp1_mux),
10565 SND_SOC_DAPM_MUX("RX INT6_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
10566 &rx_int6_1_mix_inp2_mux),
10567 SND_SOC_DAPM_MUX_E("RX INT7_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
10568 &rx_int7_1_mix_inp0_mux, tasha_codec_enable_swr,
10569 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10570 SND_SOC_DAPM_MUX_E("RX INT7_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
10571 &rx_int7_1_mix_inp1_mux, tasha_codec_enable_swr,
10572 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10573 SND_SOC_DAPM_MUX_E("RX INT7_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
10574 &rx_int7_1_mix_inp2_mux, tasha_codec_enable_swr,
10575 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10576 SND_SOC_DAPM_MUX_E("RX INT8_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
10577 &rx_int8_1_mix_inp0_mux, tasha_codec_enable_swr,
10578 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10579 SND_SOC_DAPM_MUX_E("RX INT8_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
10580 &rx_int8_1_mix_inp1_mux, tasha_codec_enable_swr,
10581 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10582 SND_SOC_DAPM_MUX_E("RX INT8_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
10583 &rx_int8_1_mix_inp2_mux, tasha_codec_enable_swr,
10584 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10585
10586 SND_SOC_DAPM_MIXER("RX INT0_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10587 SND_SOC_DAPM_MIXER("RX INT0 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
10588 SND_SOC_DAPM_MIXER("RX INT1_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10589 SND_SOC_DAPM_MIXER("RX INT1 SPLINE MIX", SND_SOC_NOPM, 0, 0,
10590 rx_int1_spline_mix_switch,
10591 ARRAY_SIZE(rx_int1_spline_mix_switch)),
10592 SND_SOC_DAPM_MIXER("RX INT1 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
10593 SND_SOC_DAPM_MIXER("RX INT2_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10594 SND_SOC_DAPM_MIXER("RX INT2 SPLINE MIX", SND_SOC_NOPM, 0, 0,
10595 rx_int2_spline_mix_switch,
10596 ARRAY_SIZE(rx_int2_spline_mix_switch)),
10597 SND_SOC_DAPM_MIXER("RX INT2 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
10598 SND_SOC_DAPM_MIXER("RX INT3_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10599 SND_SOC_DAPM_MIXER("RX INT3 SPLINE MIX", SND_SOC_NOPM, 0, 0,
10600 rx_int3_spline_mix_switch,
10601 ARRAY_SIZE(rx_int3_spline_mix_switch)),
10602 SND_SOC_DAPM_MIXER("RX INT3 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
10603 SND_SOC_DAPM_MIXER("RX INT4_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10604 SND_SOC_DAPM_MIXER("RX INT4 SPLINE MIX", SND_SOC_NOPM, 0, 0,
10605 rx_int4_spline_mix_switch,
10606 ARRAY_SIZE(rx_int4_spline_mix_switch)),
10607 SND_SOC_DAPM_MIXER("RX INT4 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
10608 SND_SOC_DAPM_MIXER("RX INT5_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10609 SND_SOC_DAPM_MIXER("RX INT5 SPLINE MIX", SND_SOC_NOPM, 0, 0,
10610 rx_int5_spline_mix_switch,
10611 ARRAY_SIZE(rx_int5_spline_mix_switch)),
10612 SND_SOC_DAPM_MIXER("RX INT5 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
10613
10614 SND_SOC_DAPM_MIXER("RX INT6_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10615 SND_SOC_DAPM_MIXER("RX INT6 SPLINE MIX", SND_SOC_NOPM, 0, 0,
10616 rx_int6_spline_mix_switch,
10617 ARRAY_SIZE(rx_int6_spline_mix_switch)),
10618 SND_SOC_DAPM_MIXER("RX INT6 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
10619
10620 SND_SOC_DAPM_MIXER("RX INT7_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10621 SND_SOC_DAPM_MIXER("RX INT7 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
10622 SND_SOC_DAPM_MIXER("RX INT7 SPLINE MIX", SND_SOC_NOPM, 0, 0,
10623 rx_int7_spline_mix_switch,
10624 ARRAY_SIZE(rx_int7_spline_mix_switch)),
10625
10626 SND_SOC_DAPM_MIXER("RX INT8_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
10627 SND_SOC_DAPM_MIXER("RX INT8 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
10628 SND_SOC_DAPM_MIXER("RX INT8 SPLINE MIX", SND_SOC_NOPM, 0, 0,
10629 rx_int8_spline_mix_switch,
10630 ARRAY_SIZE(rx_int8_spline_mix_switch)),
10631
10632 SND_SOC_DAPM_MIXER("RX INT0 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
10633 SND_SOC_DAPM_MIXER("RX INT1 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
10634 SND_SOC_DAPM_MIXER("RX INT2 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
10635 SND_SOC_DAPM_MIXER("RX INT3 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
10636 SND_SOC_DAPM_MIXER("RX INT4 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
10637 SND_SOC_DAPM_MIXER("RX INT5 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
10638 SND_SOC_DAPM_MIXER("RX INT6 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
10639 SND_SOC_DAPM_MIXER("RX INT7 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
10640 SND_SOC_DAPM_MIXER_E("RX INT7 CHAIN", SND_SOC_NOPM, 0, 0,
10641 NULL, 0, tasha_codec_spk_boost_event,
10642 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10643 SND_SOC_DAPM_MIXER_E("RX INT8 CHAIN", SND_SOC_NOPM, 0, 0,
10644 NULL, 0, tasha_codec_spk_boost_event,
10645 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10646
10647 SND_SOC_DAPM_MIXER_E("RX INT5 VBAT", SND_SOC_NOPM, 0, 0,
10648 rx_int5_vbat_mix_switch,
10649 ARRAY_SIZE(rx_int5_vbat_mix_switch),
10650 tasha_codec_vbat_enable_event,
10651 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10652 SND_SOC_DAPM_MIXER_E("RX INT6 VBAT", SND_SOC_NOPM, 0, 0,
10653 rx_int6_vbat_mix_switch,
10654 ARRAY_SIZE(rx_int6_vbat_mix_switch),
10655 tasha_codec_vbat_enable_event,
10656 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10657 SND_SOC_DAPM_MIXER_E("RX INT7 VBAT", SND_SOC_NOPM, 0, 0,
10658 rx_int7_vbat_mix_switch,
10659 ARRAY_SIZE(rx_int7_vbat_mix_switch),
10660 tasha_codec_vbat_enable_event,
10661 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10662 SND_SOC_DAPM_MIXER_E("RX INT8 VBAT", SND_SOC_NOPM, 0, 0,
10663 rx_int8_vbat_mix_switch,
10664 ARRAY_SIZE(rx_int8_vbat_mix_switch),
10665 tasha_codec_vbat_enable_event,
10666 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10667
10668 SND_SOC_DAPM_MUX("RX INT0 MIX2 INP", WCD9335_CDC_RX0_RX_PATH_CFG1, 4,
10669 0, &rx_int0_mix2_inp_mux),
10670 SND_SOC_DAPM_MUX("RX INT1 MIX2 INP", WCD9335_CDC_RX1_RX_PATH_CFG1, 4,
10671 0, &rx_int1_mix2_inp_mux),
10672 SND_SOC_DAPM_MUX("RX INT2 MIX2 INP", WCD9335_CDC_RX2_RX_PATH_CFG1, 4,
10673 0, &rx_int2_mix2_inp_mux),
10674 SND_SOC_DAPM_MUX("RX INT3 MIX2 INP", WCD9335_CDC_RX3_RX_PATH_CFG1, 4,
10675 0, &rx_int3_mix2_inp_mux),
10676 SND_SOC_DAPM_MUX("RX INT4 MIX2 INP", WCD9335_CDC_RX4_RX_PATH_CFG1, 4,
10677 0, &rx_int4_mix2_inp_mux),
10678 SND_SOC_DAPM_MUX("RX INT7 MIX2 INP", WCD9335_CDC_RX7_RX_PATH_CFG1, 4,
10679 0, &rx_int7_mix2_inp_mux),
10680
10681 SND_SOC_DAPM_MUX("SLIM TX0 MUX", SND_SOC_NOPM, TASHA_TX0, 0,
10682 &sb_tx0_mux),
10683 SND_SOC_DAPM_MUX("SLIM TX1 MUX", SND_SOC_NOPM, TASHA_TX1, 0,
10684 &sb_tx1_mux),
10685 SND_SOC_DAPM_MUX("SLIM TX2 MUX", SND_SOC_NOPM, TASHA_TX2, 0,
10686 &sb_tx2_mux),
10687 SND_SOC_DAPM_MUX("SLIM TX3 MUX", SND_SOC_NOPM, TASHA_TX3, 0,
10688 &sb_tx3_mux),
10689 SND_SOC_DAPM_MUX("SLIM TX4 MUX", SND_SOC_NOPM, TASHA_TX4, 0,
10690 &sb_tx4_mux),
10691 SND_SOC_DAPM_MUX("SLIM TX5 MUX", SND_SOC_NOPM, TASHA_TX5, 0,
10692 &sb_tx5_mux),
10693 SND_SOC_DAPM_MUX("SLIM TX6 MUX", SND_SOC_NOPM, TASHA_TX6, 0,
10694 &sb_tx6_mux),
10695 SND_SOC_DAPM_MUX("SLIM TX7 MUX", SND_SOC_NOPM, TASHA_TX7, 0,
10696 &sb_tx7_mux),
10697 SND_SOC_DAPM_MUX("SLIM TX8 MUX", SND_SOC_NOPM, TASHA_TX8, 0,
10698 &sb_tx8_mux),
10699 SND_SOC_DAPM_MUX("SLIM TX9 MUX", SND_SOC_NOPM, TASHA_TX9, 0,
10700 &sb_tx9_mux),
10701 SND_SOC_DAPM_MUX("SLIM TX10 MUX", SND_SOC_NOPM, TASHA_TX10, 0,
10702 &sb_tx10_mux),
10703 SND_SOC_DAPM_MUX("SLIM TX11 MUX", SND_SOC_NOPM, TASHA_TX11, 0,
10704 &sb_tx11_mux),
10705 SND_SOC_DAPM_MUX("SLIM TX11 INP1 MUX", SND_SOC_NOPM, TASHA_TX11, 0,
10706 &sb_tx11_inp1_mux),
10707 SND_SOC_DAPM_MUX("SLIM TX13 MUX", SND_SOC_NOPM, TASHA_TX13, 0,
10708 &sb_tx13_mux),
10709 SND_SOC_DAPM_MUX("TX13 INP MUX", SND_SOC_NOPM, 0, 0,
10710 &tx13_inp_mux),
10711
10712 SND_SOC_DAPM_MUX_E("ADC MUX0", WCD9335_CDC_TX0_TX_PATH_CTL, 5, 0,
10713 &tx_adc_mux0, tasha_codec_enable_dec,
10714 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10715 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
10716
10717 SND_SOC_DAPM_MUX_E("ADC MUX1", WCD9335_CDC_TX1_TX_PATH_CTL, 5, 0,
10718 &tx_adc_mux1, tasha_codec_enable_dec,
10719 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10720 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
10721
10722 SND_SOC_DAPM_MUX_E("ADC MUX2", WCD9335_CDC_TX2_TX_PATH_CTL, 5, 0,
10723 &tx_adc_mux2, tasha_codec_enable_dec,
10724 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10725 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
10726
10727 SND_SOC_DAPM_MUX_E("ADC MUX3", WCD9335_CDC_TX3_TX_PATH_CTL, 5, 0,
10728 &tx_adc_mux3, tasha_codec_enable_dec,
10729 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10730 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
10731
10732 SND_SOC_DAPM_MUX_E("ADC MUX4", WCD9335_CDC_TX4_TX_PATH_CTL, 5, 0,
10733 &tx_adc_mux4, tasha_codec_enable_dec,
10734 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10735 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
10736
10737 SND_SOC_DAPM_MUX_E("ADC MUX5", WCD9335_CDC_TX5_TX_PATH_CTL, 5, 0,
10738 &tx_adc_mux5, tasha_codec_enable_dec,
10739 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10740 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
10741
10742 SND_SOC_DAPM_MUX_E("ADC MUX6", WCD9335_CDC_TX6_TX_PATH_CTL, 5, 0,
10743 &tx_adc_mux6, tasha_codec_enable_dec,
10744 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10745 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
10746
10747 SND_SOC_DAPM_MUX_E("ADC MUX7", WCD9335_CDC_TX7_TX_PATH_CTL, 5, 0,
10748 &tx_adc_mux7, tasha_codec_enable_dec,
10749 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10750 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
10751
10752 SND_SOC_DAPM_MUX_E("ADC MUX8", WCD9335_CDC_TX8_TX_PATH_CTL, 5, 0,
10753 &tx_adc_mux8, tasha_codec_enable_dec,
10754 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10755 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
10756
10757 SND_SOC_DAPM_MUX_E("ADC MUX10", SND_SOC_NOPM, 10, 0,
10758 &tx_adc_mux10, tasha_codec_tx_adc_cfg,
10759 SND_SOC_DAPM_POST_PMU),
10760
10761 SND_SOC_DAPM_MUX_E("ADC MUX11", SND_SOC_NOPM, 11, 0,
10762 &tx_adc_mux11, tasha_codec_tx_adc_cfg,
10763 SND_SOC_DAPM_POST_PMU),
10764
10765 SND_SOC_DAPM_MUX_E("ADC MUX12", SND_SOC_NOPM, 12, 0,
10766 &tx_adc_mux12, tasha_codec_tx_adc_cfg,
10767 SND_SOC_DAPM_POST_PMU),
10768
10769 SND_SOC_DAPM_MUX_E("ADC MUX13", SND_SOC_NOPM, 13, 0,
10770 &tx_adc_mux13, tasha_codec_tx_adc_cfg,
10771 SND_SOC_DAPM_POST_PMU),
10772
10773 SND_SOC_DAPM_MUX("DMIC MUX0", SND_SOC_NOPM, 0, 0,
10774 &tx_dmic_mux0),
10775 SND_SOC_DAPM_MUX("DMIC MUX1", SND_SOC_NOPM, 0, 0,
10776 &tx_dmic_mux1),
10777 SND_SOC_DAPM_MUX("DMIC MUX2", SND_SOC_NOPM, 0, 0,
10778 &tx_dmic_mux2),
10779 SND_SOC_DAPM_MUX("DMIC MUX3", SND_SOC_NOPM, 0, 0,
10780 &tx_dmic_mux3),
10781 SND_SOC_DAPM_MUX("DMIC MUX4", SND_SOC_NOPM, 0, 0,
10782 &tx_dmic_mux4),
10783 SND_SOC_DAPM_MUX("DMIC MUX5", SND_SOC_NOPM, 0, 0,
10784 &tx_dmic_mux5),
10785 SND_SOC_DAPM_MUX("DMIC MUX6", SND_SOC_NOPM, 0, 0,
10786 &tx_dmic_mux6),
10787 SND_SOC_DAPM_MUX("DMIC MUX7", SND_SOC_NOPM, 0, 0,
10788 &tx_dmic_mux7),
10789 SND_SOC_DAPM_MUX("DMIC MUX8", SND_SOC_NOPM, 0, 0,
10790 &tx_dmic_mux8),
10791 SND_SOC_DAPM_MUX("DMIC MUX10", SND_SOC_NOPM, 0, 0,
10792 &tx_dmic_mux10),
10793 SND_SOC_DAPM_MUX("DMIC MUX11", SND_SOC_NOPM, 0, 0,
10794 &tx_dmic_mux11),
10795 SND_SOC_DAPM_MUX("DMIC MUX12", SND_SOC_NOPM, 0, 0,
10796 &tx_dmic_mux12),
10797 SND_SOC_DAPM_MUX("DMIC MUX13", SND_SOC_NOPM, 0, 0,
10798 &tx_dmic_mux13),
10799
10800 SND_SOC_DAPM_MUX("AMIC MUX0", SND_SOC_NOPM, 0, 0,
10801 &tx_amic_mux0),
10802 SND_SOC_DAPM_MUX("AMIC MUX1", SND_SOC_NOPM, 0, 0,
10803 &tx_amic_mux1),
10804 SND_SOC_DAPM_MUX("AMIC MUX2", SND_SOC_NOPM, 0, 0,
10805 &tx_amic_mux2),
10806 SND_SOC_DAPM_MUX("AMIC MUX3", SND_SOC_NOPM, 0, 0,
10807 &tx_amic_mux3),
10808 SND_SOC_DAPM_MUX("AMIC MUX4", SND_SOC_NOPM, 0, 0,
10809 &tx_amic_mux4),
10810 SND_SOC_DAPM_MUX("AMIC MUX5", SND_SOC_NOPM, 0, 0,
10811 &tx_amic_mux5),
10812 SND_SOC_DAPM_MUX("AMIC MUX6", SND_SOC_NOPM, 0, 0,
10813 &tx_amic_mux6),
10814 SND_SOC_DAPM_MUX("AMIC MUX7", SND_SOC_NOPM, 0, 0,
10815 &tx_amic_mux7),
10816 SND_SOC_DAPM_MUX("AMIC MUX8", SND_SOC_NOPM, 0, 0,
10817 &tx_amic_mux8),
10818 SND_SOC_DAPM_MUX("AMIC MUX10", SND_SOC_NOPM, 0, 0,
10819 &tx_amic_mux10),
10820 SND_SOC_DAPM_MUX("AMIC MUX11", SND_SOC_NOPM, 0, 0,
10821 &tx_amic_mux11),
10822 SND_SOC_DAPM_MUX("AMIC MUX12", SND_SOC_NOPM, 0, 0,
10823 &tx_amic_mux12),
10824 SND_SOC_DAPM_MUX("AMIC MUX13", SND_SOC_NOPM, 0, 0,
10825 &tx_amic_mux13),
10826
10827 SND_SOC_DAPM_ADC_E("ADC1", NULL, WCD9335_ANA_AMIC1, 7, 0,
10828 tasha_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
10829 SND_SOC_DAPM_ADC_E("ADC2", NULL, WCD9335_ANA_AMIC2, 7, 0,
10830 tasha_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
10831 SND_SOC_DAPM_ADC_E("ADC3", NULL, WCD9335_ANA_AMIC3, 7, 0,
10832 tasha_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
10833 SND_SOC_DAPM_ADC_E("ADC4", NULL, WCD9335_ANA_AMIC4, 7, 0,
10834 tasha_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
10835 SND_SOC_DAPM_ADC_E("ADC5", NULL, WCD9335_ANA_AMIC5, 7, 0,
10836 tasha_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
10837 SND_SOC_DAPM_ADC_E("ADC6", NULL, WCD9335_ANA_AMIC6, 7, 0,
10838 tasha_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
10839
10840 SND_SOC_DAPM_SUPPLY("RX INT1 NATIVE SUPPLY", SND_SOC_NOPM,
10841 INTERP_HPHL, 0, tasha_enable_native_supply,
10842 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
10843
10844 SND_SOC_DAPM_SUPPLY("RX INT2 NATIVE SUPPLY", SND_SOC_NOPM,
10845 INTERP_HPHR, 0, tasha_enable_native_supply,
10846 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
10847
10848 SND_SOC_DAPM_SUPPLY("RX INT3 NATIVE SUPPLY", SND_SOC_NOPM,
10849 INTERP_LO1, 0, tasha_enable_native_supply,
10850 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
10851
10852 SND_SOC_DAPM_SUPPLY("RX INT4 NATIVE SUPPLY", SND_SOC_NOPM,
10853 INTERP_LO2, 0, tasha_enable_native_supply,
10854 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
10855
10856 SND_SOC_DAPM_INPUT("AMIC1"),
10857 SND_SOC_DAPM_MICBIAS_E("MIC BIAS1", SND_SOC_NOPM, 0, 0,
10858 tasha_codec_enable_micbias,
10859 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10860 SND_SOC_DAPM_POST_PMD),
10861 SND_SOC_DAPM_MICBIAS_E("MIC BIAS2", SND_SOC_NOPM, 0, 0,
10862 tasha_codec_enable_micbias,
10863 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10864 SND_SOC_DAPM_POST_PMD),
10865 SND_SOC_DAPM_MICBIAS_E("MIC BIAS3", SND_SOC_NOPM, 0, 0,
10866 tasha_codec_enable_micbias,
10867 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10868 SND_SOC_DAPM_POST_PMD),
10869 SND_SOC_DAPM_MICBIAS_E("MIC BIAS4", SND_SOC_NOPM, 0, 0,
10870 tasha_codec_enable_micbias,
10871 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
10872 SND_SOC_DAPM_POST_PMD),
10873
10874 SND_SOC_DAPM_MICBIAS_E(DAPM_MICBIAS1_STANDALONE, SND_SOC_NOPM, 0, 0,
10875 tasha_codec_force_enable_micbias,
10876 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10877 SND_SOC_DAPM_MICBIAS_E(DAPM_MICBIAS2_STANDALONE, SND_SOC_NOPM, 0, 0,
10878 tasha_codec_force_enable_micbias,
10879 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10880 SND_SOC_DAPM_MICBIAS_E(DAPM_MICBIAS3_STANDALONE, SND_SOC_NOPM, 0, 0,
10881 tasha_codec_force_enable_micbias,
10882 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10883 SND_SOC_DAPM_MICBIAS_E(DAPM_MICBIAS4_STANDALONE, SND_SOC_NOPM, 0, 0,
10884 tasha_codec_force_enable_micbias,
10885 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10886 SND_SOC_DAPM_SUPPLY(DAPM_LDO_H_STANDALONE, SND_SOC_NOPM, 0, 0,
10887 tasha_codec_force_enable_ldo_h,
10888 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10889
10890 SND_SOC_DAPM_MUX("ANC0 FB MUX", SND_SOC_NOPM, 0, 0, &anc0_fb_mux),
10891 SND_SOC_DAPM_MUX("ANC1 FB MUX", SND_SOC_NOPM, 0, 0, &anc1_fb_mux),
10892
10893 SND_SOC_DAPM_INPUT("AMIC2"),
10894 SND_SOC_DAPM_INPUT("AMIC3"),
10895 SND_SOC_DAPM_INPUT("AMIC4"),
10896 SND_SOC_DAPM_INPUT("AMIC5"),
10897 SND_SOC_DAPM_INPUT("AMIC6"),
10898
10899 SND_SOC_DAPM_AIF_OUT_E("AIF1 CAP", "AIF1 Capture", 0, SND_SOC_NOPM,
10900 AIF1_CAP, 0, tasha_codec_enable_slimtx,
10901 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
10902
10903 SND_SOC_DAPM_AIF_OUT_E("AIF2 CAP", "AIF2 Capture", 0, SND_SOC_NOPM,
10904 AIF2_CAP, 0, tasha_codec_enable_slimtx,
10905 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
10906
10907 SND_SOC_DAPM_AIF_OUT_E("AIF3 CAP", "AIF3 Capture", 0, SND_SOC_NOPM,
10908 AIF3_CAP, 0, tasha_codec_enable_slimtx,
10909 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
10910
10911 SND_SOC_DAPM_AIF_OUT_E("AIF4 VI", "VIfeed", 0, SND_SOC_NOPM,
10912 AIF4_VIFEED, 0, tasha_codec_enable_slimvi_feedback,
10913 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
10914 SND_SOC_DAPM_MIXER("AIF4_VI Mixer", SND_SOC_NOPM, AIF4_VIFEED, 0,
10915 aif4_vi_mixer, ARRAY_SIZE(aif4_vi_mixer)),
10916
10917 SND_SOC_DAPM_MIXER("AIF1_CAP Mixer", SND_SOC_NOPM, AIF1_CAP, 0,
10918 aif1_cap_mixer, ARRAY_SIZE(aif1_cap_mixer)),
10919
10920 SND_SOC_DAPM_MIXER("AIF2_CAP Mixer", SND_SOC_NOPM, AIF2_CAP, 0,
10921 aif2_cap_mixer, ARRAY_SIZE(aif2_cap_mixer)),
10922
10923 SND_SOC_DAPM_MIXER("AIF3_CAP Mixer", SND_SOC_NOPM, AIF3_CAP, 0,
10924 aif3_cap_mixer, ARRAY_SIZE(aif3_cap_mixer)),
10925
10926 SND_SOC_DAPM_MIXER("AIF4_MAD Mixer", SND_SOC_NOPM, AIF4_MAD_TX, 0,
10927 aif4_mad_mixer, ARRAY_SIZE(aif4_mad_mixer)),
10928
10929 SND_SOC_DAPM_INPUT("VIINPUT"),
10930
10931 SND_SOC_DAPM_AIF_OUT("AIF5 CPE", "AIF5 CPE TX", 0, SND_SOC_NOPM,
10932 AIF5_CPE_TX, 0),
10933
10934 SND_SOC_DAPM_MUX_E("EC BUF MUX INP", SND_SOC_NOPM, 0, 0, &ec_buf_mux,
10935 tasha_codec_ec_buf_mux_enable,
10936 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
10937
10938 /* Digital Mic Inputs */
10939 SND_SOC_DAPM_ADC_E("DMIC0", NULL, SND_SOC_NOPM, 0, 0,
10940 tasha_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
10941 SND_SOC_DAPM_POST_PMD),
10942
10943 SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0,
10944 tasha_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
10945 SND_SOC_DAPM_POST_PMD),
10946
10947 SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 0, 0,
10948 tasha_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
10949 SND_SOC_DAPM_POST_PMD),
10950
10951 SND_SOC_DAPM_ADC_E("DMIC3", NULL, SND_SOC_NOPM, 0, 0,
10952 tasha_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
10953 SND_SOC_DAPM_POST_PMD),
10954
10955 SND_SOC_DAPM_ADC_E("DMIC4", NULL, SND_SOC_NOPM, 0, 0,
10956 tasha_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
10957 SND_SOC_DAPM_POST_PMD),
10958
10959 SND_SOC_DAPM_ADC_E("DMIC5", NULL, SND_SOC_NOPM, 0, 0,
10960 tasha_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
10961 SND_SOC_DAPM_POST_PMD),
10962
10963 SND_SOC_DAPM_MUX("IIR0 INP0 MUX", SND_SOC_NOPM, 0, 0, &iir0_inp0_mux),
10964 SND_SOC_DAPM_MUX("IIR0 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir0_inp1_mux),
10965 SND_SOC_DAPM_MUX("IIR0 INP2 MUX", SND_SOC_NOPM, 0, 0, &iir0_inp2_mux),
10966 SND_SOC_DAPM_MUX("IIR0 INP3 MUX", SND_SOC_NOPM, 0, 0, &iir0_inp3_mux),
10967 SND_SOC_DAPM_MUX("IIR1 INP0 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp0_mux),
10968 SND_SOC_DAPM_MUX("IIR1 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp1_mux),
10969 SND_SOC_DAPM_MUX("IIR1 INP2 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp2_mux),
10970 SND_SOC_DAPM_MUX("IIR1 INP3 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp3_mux),
10971
10972 SND_SOC_DAPM_MIXER_E("IIR0", WCD9335_CDC_SIDETONE_IIR0_IIR_PATH_CTL,
10973 4, 0, NULL, 0, tasha_codec_set_iir_gain,
10974 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
10975 SND_SOC_DAPM_MIXER_E("IIR1", WCD9335_CDC_SIDETONE_IIR1_IIR_PATH_CTL,
10976 4, 0, NULL, 0, tasha_codec_set_iir_gain,
10977 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
10978 SND_SOC_DAPM_MIXER("SRC0", WCD9335_CDC_SIDETONE_SRC0_ST_SRC_PATH_CTL,
10979 4, 0, NULL, 0),
10980 SND_SOC_DAPM_MIXER("SRC1", WCD9335_CDC_SIDETONE_SRC1_ST_SRC_PATH_CTL,
10981 4, 0, NULL, 0),
10982 SND_SOC_DAPM_MIXER_E("CPE IN Mixer", SND_SOC_NOPM, 0, 0,
10983 cpe_in_mix_switch,
10984 ARRAY_SIZE(cpe_in_mix_switch),
10985 tasha_codec_configure_cpe_input,
10986 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
10987
10988 SND_SOC_DAPM_MUX("RX INT1_1 NATIVE MUX", SND_SOC_NOPM, 0, 0,
10989 &int1_1_native_mux),
10990 SND_SOC_DAPM_MUX("RX INT2_1 NATIVE MUX", SND_SOC_NOPM, 0, 0,
10991 &int2_1_native_mux),
10992 SND_SOC_DAPM_MUX("RX INT3_1 NATIVE MUX", SND_SOC_NOPM, 0, 0,
10993 &int3_1_native_mux),
10994 SND_SOC_DAPM_MUX("RX INT4_1 NATIVE MUX", SND_SOC_NOPM, 0, 0,
10995 &int4_1_native_mux),
10996 SND_SOC_DAPM_MUX("RX MIX TX0 MUX", SND_SOC_NOPM, 0, 0,
10997 &rx_mix_tx0_mux),
10998 SND_SOC_DAPM_MUX("RX MIX TX1 MUX", SND_SOC_NOPM, 0, 0,
10999 &rx_mix_tx1_mux),
11000 SND_SOC_DAPM_MUX("RX MIX TX2 MUX", SND_SOC_NOPM, 0, 0,
11001 &rx_mix_tx2_mux),
11002 SND_SOC_DAPM_MUX("RX MIX TX3 MUX", SND_SOC_NOPM, 0, 0,
11003 &rx_mix_tx3_mux),
11004 SND_SOC_DAPM_MUX("RX MIX TX4 MUX", SND_SOC_NOPM, 0, 0,
11005 &rx_mix_tx4_mux),
11006 SND_SOC_DAPM_MUX("RX MIX TX5 MUX", SND_SOC_NOPM, 0, 0,
11007 &rx_mix_tx5_mux),
11008 SND_SOC_DAPM_MUX("RX MIX TX6 MUX", SND_SOC_NOPM, 0, 0,
11009 &rx_mix_tx6_mux),
11010 SND_SOC_DAPM_MUX("RX MIX TX7 MUX", SND_SOC_NOPM, 0, 0,
11011 &rx_mix_tx7_mux),
11012 SND_SOC_DAPM_MUX("RX MIX TX8 MUX", SND_SOC_NOPM, 0, 0,
11013 &rx_mix_tx8_mux),
11014
11015 SND_SOC_DAPM_MUX("RX INT0 DEM MUX", SND_SOC_NOPM, 0, 0,
11016 &rx_int0_dem_inp_mux),
11017 SND_SOC_DAPM_MUX("RX INT1 DEM MUX", SND_SOC_NOPM, 0, 0,
11018 &rx_int1_dem_inp_mux),
11019 SND_SOC_DAPM_MUX("RX INT2 DEM MUX", SND_SOC_NOPM, 0, 0,
11020 &rx_int2_dem_inp_mux),
11021
11022 SND_SOC_DAPM_MUX_E("RX INT0 INTERP", SND_SOC_NOPM,
11023 INTERP_EAR, 0, &rx_int0_interp_mux,
11024 tasha_codec_enable_interpolator,
11025 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11026 SND_SOC_DAPM_POST_PMD),
11027 SND_SOC_DAPM_MUX_E("RX INT1 INTERP", SND_SOC_NOPM,
11028 INTERP_HPHL, 0, &rx_int1_interp_mux,
11029 tasha_codec_enable_interpolator,
11030 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11031 SND_SOC_DAPM_POST_PMD),
11032 SND_SOC_DAPM_MUX_E("RX INT2 INTERP", SND_SOC_NOPM,
11033 INTERP_HPHR, 0, &rx_int2_interp_mux,
11034 tasha_codec_enable_interpolator,
11035 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11036 SND_SOC_DAPM_POST_PMD),
11037 SND_SOC_DAPM_MUX_E("RX INT3 INTERP", SND_SOC_NOPM,
11038 INTERP_LO1, 0, &rx_int3_interp_mux,
11039 tasha_codec_enable_interpolator,
11040 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11041 SND_SOC_DAPM_POST_PMD),
11042 SND_SOC_DAPM_MUX_E("RX INT4 INTERP", SND_SOC_NOPM,
11043 INTERP_LO2, 0, &rx_int4_interp_mux,
11044 tasha_codec_enable_interpolator,
11045 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11046 SND_SOC_DAPM_POST_PMD),
11047 SND_SOC_DAPM_MUX_E("RX INT5 INTERP", SND_SOC_NOPM,
11048 INTERP_LO3, 0, &rx_int5_interp_mux,
11049 tasha_codec_enable_interpolator,
11050 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11051 SND_SOC_DAPM_POST_PMD),
11052 SND_SOC_DAPM_MUX_E("RX INT6 INTERP", SND_SOC_NOPM,
11053 INTERP_LO4, 0, &rx_int6_interp_mux,
11054 tasha_codec_enable_interpolator,
11055 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11056 SND_SOC_DAPM_POST_PMD),
11057 SND_SOC_DAPM_MUX_E("RX INT7 INTERP", SND_SOC_NOPM,
11058 INTERP_SPKR1, 0, &rx_int7_interp_mux,
11059 tasha_codec_enable_interpolator,
11060 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11061 SND_SOC_DAPM_POST_PMD),
11062 SND_SOC_DAPM_MUX_E("RX INT8 INTERP", SND_SOC_NOPM,
11063 INTERP_SPKR2, 0, &rx_int8_interp_mux,
11064 tasha_codec_enable_interpolator,
11065 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11066 SND_SOC_DAPM_POST_PMD),
11067
11068 SND_SOC_DAPM_DAC_E("RX INT0 DAC", NULL, SND_SOC_NOPM,
11069 0, 0, tasha_codec_ear_dac_event,
11070 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11071 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11072 SND_SOC_DAPM_DAC_E("RX INT1 DAC", NULL, WCD9335_ANA_HPH,
11073 5, 0, tasha_codec_hphl_dac_event,
11074 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11075 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11076 SND_SOC_DAPM_DAC_E("RX INT2 DAC", NULL, WCD9335_ANA_HPH,
11077 4, 0, tasha_codec_hphr_dac_event,
11078 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11079 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11080 SND_SOC_DAPM_DAC_E("RX INT3 DAC", NULL, SND_SOC_NOPM,
11081 0, 0, tasha_codec_lineout_dac_event,
11082 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
11083 SND_SOC_DAPM_DAC_E("RX INT4 DAC", NULL, SND_SOC_NOPM,
11084 0, 0, tasha_codec_lineout_dac_event,
11085 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
11086 SND_SOC_DAPM_DAC_E("RX INT5 DAC", NULL, SND_SOC_NOPM,
11087 0, 0, tasha_codec_lineout_dac_event,
11088 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
11089 SND_SOC_DAPM_DAC_E("RX INT6 DAC", NULL, SND_SOC_NOPM,
11090 0, 0, tasha_codec_lineout_dac_event,
11091 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
11092 SND_SOC_DAPM_PGA_E("HPHL PA", WCD9335_ANA_HPH, 7, 0, NULL, 0,
11093 tasha_codec_enable_hphl_pa,
11094 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11095 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11096 SND_SOC_DAPM_PGA_E("HPHR PA", WCD9335_ANA_HPH, 6, 0, NULL, 0,
11097 tasha_codec_enable_hphr_pa,
11098 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11099 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11100 SND_SOC_DAPM_PGA_E("EAR PA", WCD9335_ANA_EAR, 7, 0, NULL, 0,
11101 tasha_codec_enable_ear_pa,
11102 SND_SOC_DAPM_POST_PMU |
11103 SND_SOC_DAPM_POST_PMD),
11104 SND_SOC_DAPM_PGA_E("LINEOUT1 PA", WCD9335_ANA_LO_1_2, 7, 0, NULL, 0,
11105 tasha_codec_enable_lineout_pa,
11106 SND_SOC_DAPM_POST_PMU |
11107 SND_SOC_DAPM_POST_PMD),
11108 SND_SOC_DAPM_PGA_E("LINEOUT2 PA", WCD9335_ANA_LO_1_2, 6, 0, NULL, 0,
11109 tasha_codec_enable_lineout_pa,
11110 SND_SOC_DAPM_POST_PMU |
11111 SND_SOC_DAPM_POST_PMD),
11112 SND_SOC_DAPM_PGA_E("LINEOUT3 PA", WCD9335_ANA_LO_3_4, 7, 0, NULL, 0,
11113 tasha_codec_enable_lineout_pa,
11114 SND_SOC_DAPM_POST_PMU |
11115 SND_SOC_DAPM_POST_PMD),
11116 SND_SOC_DAPM_PGA_E("LINEOUT4 PA", WCD9335_ANA_LO_3_4, 6, 0, NULL, 0,
11117 tasha_codec_enable_lineout_pa,
11118 SND_SOC_DAPM_POST_PMU |
11119 SND_SOC_DAPM_POST_PMD),
11120 SND_SOC_DAPM_PGA_E("ANC EAR PA", WCD9335_ANA_EAR, 7, 0, NULL, 0,
11121 tasha_codec_enable_ear_pa,
11122 SND_SOC_DAPM_POST_PMU |
11123 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11124 SND_SOC_DAPM_PGA_E("ANC HPHL PA", SND_SOC_NOPM, 0, 0, NULL, 0,
11125 tasha_codec_enable_hphl_pa,
11126 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11127 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11128 SND_SOC_DAPM_PGA_E("ANC HPHR PA", SND_SOC_NOPM, 0, 0, NULL, 0,
11129 tasha_codec_enable_hphr_pa,
11130 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
11131 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11132 SND_SOC_DAPM_PGA_E("ANC LINEOUT1 PA", WCD9335_ANA_LO_1_2,
11133 7, 0, NULL, 0,
11134 tasha_codec_enable_lineout_pa,
11135 SND_SOC_DAPM_POST_PMU |
11136 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11137 SND_SOC_DAPM_PGA_E("ANC LINEOUT2 PA", WCD9335_ANA_LO_1_2,
11138 6, 0, NULL, 0,
11139 tasha_codec_enable_lineout_pa,
11140 SND_SOC_DAPM_POST_PMU |
11141 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
11142 SND_SOC_DAPM_PGA_E("ANC SPK1 PA", SND_SOC_NOPM, 0, 0, NULL, 0,
11143 tasha_codec_enable_spk_anc,
11144 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
11145
11146 SND_SOC_DAPM_OUTPUT("HPHL"),
11147 SND_SOC_DAPM_OUTPUT("HPHR"),
11148 SND_SOC_DAPM_OUTPUT("ANC HPHL"),
11149 SND_SOC_DAPM_OUTPUT("ANC HPHR"),
11150 SND_SOC_DAPM_SUPPLY("RX_BIAS", SND_SOC_NOPM, 0, 0,
11151 tasha_codec_enable_rx_bias, SND_SOC_DAPM_PRE_PMU |
11152 SND_SOC_DAPM_POST_PMD),
11153 SND_SOC_DAPM_OUTPUT("SPK1 OUT"),
11154 SND_SOC_DAPM_OUTPUT("SPK2 OUT"),
11155 SND_SOC_DAPM_OUTPUT("LINEOUT1"),
11156 SND_SOC_DAPM_OUTPUT("LINEOUT2"),
11157 SND_SOC_DAPM_OUTPUT("LINEOUT3"),
11158 SND_SOC_DAPM_OUTPUT("LINEOUT4"),
11159 SND_SOC_DAPM_OUTPUT("ANC LINEOUT1"),
11160 SND_SOC_DAPM_OUTPUT("ANC LINEOUT2"),
11161 SND_SOC_DAPM_SUPPLY("MICBIAS_REGULATOR", SND_SOC_NOPM,
11162 ON_DEMAND_MICBIAS, 0,
11163 tasha_codec_enable_on_demand_supply,
11164 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
11165
11166 SND_SOC_DAPM_SWITCH("ADC US MUX0", WCD9335_CDC_TX0_TX_PATH_192_CTL, 0,
11167 0, &adc_us_mux0_switch),
11168 SND_SOC_DAPM_SWITCH("ADC US MUX1", WCD9335_CDC_TX1_TX_PATH_192_CTL, 0,
11169 0, &adc_us_mux1_switch),
11170 SND_SOC_DAPM_SWITCH("ADC US MUX2", WCD9335_CDC_TX2_TX_PATH_192_CTL, 0,
11171 0, &adc_us_mux2_switch),
11172 SND_SOC_DAPM_SWITCH("ADC US MUX3", WCD9335_CDC_TX3_TX_PATH_192_CTL, 0,
11173 0, &adc_us_mux3_switch),
11174 SND_SOC_DAPM_SWITCH("ADC US MUX4", WCD9335_CDC_TX4_TX_PATH_192_CTL, 0,
11175 0, &adc_us_mux4_switch),
11176 SND_SOC_DAPM_SWITCH("ADC US MUX5", WCD9335_CDC_TX5_TX_PATH_192_CTL, 0,
11177 0, &adc_us_mux5_switch),
11178 SND_SOC_DAPM_SWITCH("ADC US MUX6", WCD9335_CDC_TX6_TX_PATH_192_CTL, 0,
11179 0, &adc_us_mux6_switch),
11180 SND_SOC_DAPM_SWITCH("ADC US MUX7", WCD9335_CDC_TX7_TX_PATH_192_CTL, 0,
11181 0, &adc_us_mux7_switch),
11182 SND_SOC_DAPM_SWITCH("ADC US MUX8", WCD9335_CDC_TX8_TX_PATH_192_CTL, 0,
11183 0, &adc_us_mux8_switch),
11184 /* MAD related widgets */
11185 SND_SOC_DAPM_AIF_OUT_E("AIF4 MAD", "AIF4 MAD TX", 0,
11186 SND_SOC_NOPM, 0, 0,
11187 tasha_codec_enable_mad,
11188 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
11189
11190 SND_SOC_DAPM_MUX("MAD_SEL MUX", SND_SOC_NOPM, 0, 0,
11191 &mad_sel_mux),
11192 SND_SOC_DAPM_INPUT("MAD_CPE_INPUT"),
11193 SND_SOC_DAPM_INPUT("MADINPUT"),
11194 SND_SOC_DAPM_SWITCH("MADONOFF", SND_SOC_NOPM, 0, 0,
11195 &aif4_mad_switch),
11196 SND_SOC_DAPM_SWITCH("MAD_BROADCAST", SND_SOC_NOPM, 0, 0,
11197 &mad_brdcst_switch),
11198 SND_SOC_DAPM_SWITCH("AIF4", SND_SOC_NOPM, 0, 0,
11199 &aif4_switch_mixer_controls),
11200 SND_SOC_DAPM_SWITCH("ANC HPHL Enable", SND_SOC_NOPM, 0, 0,
11201 &anc_hphl_switch),
11202 SND_SOC_DAPM_SWITCH("ANC HPHR Enable", SND_SOC_NOPM, 0, 0,
11203 &anc_hphr_switch),
11204 SND_SOC_DAPM_SWITCH("ANC EAR Enable", SND_SOC_NOPM, 0, 0,
11205 &anc_ear_switch),
11206 SND_SOC_DAPM_SWITCH("ANC OUT EAR SPKR Enable", SND_SOC_NOPM, 0, 0,
11207 &anc_ear_spkr_switch),
11208 SND_SOC_DAPM_SWITCH("ANC LINEOUT1 Enable", SND_SOC_NOPM, 0, 0,
11209 &anc_lineout1_switch),
11210 SND_SOC_DAPM_SWITCH("ANC LINEOUT2 Enable", SND_SOC_NOPM, 0, 0,
11211 &anc_lineout2_switch),
11212 SND_SOC_DAPM_SWITCH("ANC SPKR PA Enable", SND_SOC_NOPM, 0, 0,
11213 &anc_spkr_pa_switch),
11214};
11215
11216static int tasha_get_channel_map(struct snd_soc_dai *dai,
11217 unsigned int *tx_num, unsigned int *tx_slot,
11218 unsigned int *rx_num, unsigned int *rx_slot)
11219{
11220 struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(dai->codec);
11221 u32 i = 0;
11222 struct wcd9xxx_ch *ch;
11223
11224 switch (dai->id) {
11225 case AIF1_PB:
11226 case AIF2_PB:
11227 case AIF3_PB:
11228 case AIF4_PB:
11229 case AIF_MIX1_PB:
11230 if (!rx_slot || !rx_num) {
11231 pr_err("%s: Invalid rx_slot %pK or rx_num %pK\n",
11232 __func__, rx_slot, rx_num);
11233 return -EINVAL;
11234 }
11235 list_for_each_entry(ch, &tasha_p->dai[dai->id].wcd9xxx_ch_list,
11236 list) {
11237 pr_debug("%s: slot_num %u ch->ch_num %d\n",
11238 __func__, i, ch->ch_num);
11239 rx_slot[i++] = ch->ch_num;
11240 }
11241 pr_debug("%s: rx_num %d\n", __func__, i);
11242 *rx_num = i;
11243 break;
11244 case AIF1_CAP:
11245 case AIF2_CAP:
11246 case AIF3_CAP:
11247 case AIF4_MAD_TX:
11248 case AIF4_VIFEED:
11249 if (!tx_slot || !tx_num) {
11250 pr_err("%s: Invalid tx_slot %pK or tx_num %pK\n",
11251 __func__, tx_slot, tx_num);
11252 return -EINVAL;
11253 }
11254 list_for_each_entry(ch, &tasha_p->dai[dai->id].wcd9xxx_ch_list,
11255 list) {
11256 pr_debug("%s: slot_num %u ch->ch_num %d\n",
11257 __func__, i, ch->ch_num);
11258 tx_slot[i++] = ch->ch_num;
11259 }
11260 pr_debug("%s: tx_num %d\n", __func__, i);
11261 *tx_num = i;
11262 break;
11263
11264 default:
11265 pr_err("%s: Invalid DAI ID %x\n", __func__, dai->id);
11266 break;
11267 }
11268
11269 return 0;
11270}
11271
11272static int tasha_set_channel_map(struct snd_soc_dai *dai,
11273 unsigned int tx_num, unsigned int *tx_slot,
11274 unsigned int rx_num, unsigned int *rx_slot)
11275{
11276 struct tasha_priv *tasha;
11277 struct wcd9xxx *core;
11278 struct wcd9xxx_codec_dai_data *dai_data = NULL;
11279
11280 if (!dai) {
11281 pr_err("%s: dai is empty\n", __func__);
11282 return -EINVAL;
11283 }
11284 tasha = snd_soc_codec_get_drvdata(dai->codec);
11285 core = dev_get_drvdata(dai->codec->dev->parent);
11286
11287 if (!tx_slot || !rx_slot) {
11288 pr_err("%s: Invalid tx_slot=%pK, rx_slot=%pK\n",
11289 __func__, tx_slot, rx_slot);
11290 return -EINVAL;
11291 }
11292 pr_debug("%s(): dai_name = %s DAI-ID %x tx_ch %d rx_ch %d\n"
11293 "tasha->intf_type %d\n",
11294 __func__, dai->name, dai->id, tx_num, rx_num,
11295 tasha->intf_type);
11296
11297 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
11298 wcd9xxx_init_slimslave(core, core->slim->laddr,
11299 tx_num, tx_slot, rx_num, rx_slot);
11300 /* Reserve TX12/TX13 for MAD data channel */
11301 dai_data = &tasha->dai[AIF4_MAD_TX];
11302 if (dai_data) {
11303 if (TASHA_IS_2_0(tasha->wcd9xxx))
11304 list_add_tail(&core->tx_chs[TASHA_TX13].list,
11305 &dai_data->wcd9xxx_ch_list);
11306 else
11307 list_add_tail(&core->tx_chs[TASHA_TX12].list,
11308 &dai_data->wcd9xxx_ch_list);
11309 }
11310 }
11311 return 0;
11312}
11313
11314static int tasha_startup(struct snd_pcm_substream *substream,
11315 struct snd_soc_dai *dai)
11316{
11317 pr_debug("%s(): substream = %s stream = %d\n", __func__,
11318 substream->name, substream->stream);
11319
11320 return 0;
11321}
11322
11323static void tasha_shutdown(struct snd_pcm_substream *substream,
11324 struct snd_soc_dai *dai)
11325{
11326 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(dai->codec);
11327
11328 pr_debug("%s(): substream = %s stream = %d\n", __func__,
11329 substream->name, substream->stream);
11330
11331 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C)
11332 return;
11333
11334 if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) &&
11335 test_bit(SB_CLK_GEAR, &tasha->status_mask)) {
11336 tasha_codec_vote_max_bw(dai->codec, false);
11337 clear_bit(SB_CLK_GEAR, &tasha->status_mask);
11338 }
11339}
11340
11341static int tasha_set_decimator_rate(struct snd_soc_dai *dai,
11342 u8 tx_fs_rate_reg_val, u32 sample_rate)
11343{
11344 struct snd_soc_codec *codec = dai->codec;
11345 struct wcd9xxx_ch *ch;
11346 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
11347 u32 tx_port = 0;
11348 u8 shift = 0, shift_val = 0, tx_mux_sel = 0;
11349 int decimator = -1;
11350 u16 tx_port_reg = 0, tx_fs_reg = 0;
11351
11352 list_for_each_entry(ch, &tasha->dai[dai->id].wcd9xxx_ch_list, list) {
11353 tx_port = ch->port;
11354 dev_dbg(codec->dev, "%s: dai->id = %d, tx_port = %d",
11355 __func__, dai->id, tx_port);
11356
11357 if ((tx_port < 0) || (tx_port == 12) || (tx_port >= 14)) {
11358 dev_err(codec->dev, "%s: Invalid SLIM TX%u port. DAI ID: %d\n",
11359 __func__, tx_port, dai->id);
11360 return -EINVAL;
11361 }
11362 /* Find the SB TX MUX input - which decimator is connected */
11363 if (tx_port < 4) {
11364 tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0;
11365 shift = (tx_port << 1);
11366 shift_val = 0x03;
11367 } else if ((tx_port >= 4) && (tx_port < 8)) {
11368 tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1;
11369 shift = ((tx_port - 4) << 1);
11370 shift_val = 0x03;
11371 } else if ((tx_port >= 8) && (tx_port < 11)) {
11372 tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG2;
11373 shift = ((tx_port - 8) << 1);
11374 shift_val = 0x03;
11375 } else if (tx_port == 11) {
11376 tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG3;
11377 shift = 0;
11378 shift_val = 0x0F;
11379 } else if (tx_port == 13) {
11380 tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG3;
11381 shift = 4;
11382 shift_val = 0x03;
11383 }
11384 tx_mux_sel = snd_soc_read(codec, tx_port_reg) &
11385 (shift_val << shift);
11386 tx_mux_sel = tx_mux_sel >> shift;
11387
11388 if (tx_port <= 8) {
11389 if ((tx_mux_sel == 0x2) || (tx_mux_sel == 0x3))
11390 decimator = tx_port;
11391 } else if (tx_port <= 10) {
11392 if ((tx_mux_sel == 0x1) || (tx_mux_sel == 0x2))
11393 decimator = ((tx_port == 9) ? 7 : 6);
11394 } else if (tx_port == 11) {
11395 if ((tx_mux_sel >= 1) && (tx_mux_sel < 7))
11396 decimator = tx_mux_sel - 1;
11397 } else if (tx_port == 13) {
11398 if ((tx_mux_sel == 0x1) || (tx_mux_sel == 0x2))
11399 decimator = 5;
11400 }
11401
11402 if (decimator >= 0) {
11403 tx_fs_reg = WCD9335_CDC_TX0_TX_PATH_CTL +
11404 16 * decimator;
11405 dev_dbg(codec->dev, "%s: set DEC%u (-> SLIM_TX%u) rate to %u\n",
11406 __func__, decimator, tx_port, sample_rate);
11407 snd_soc_update_bits(codec, tx_fs_reg, 0x0F,
11408 tx_fs_rate_reg_val);
11409 } else if ((tx_port <= 8) && (tx_mux_sel == 0x01)) {
11410 /* Check if the TX Mux input is RX MIX TXn */
11411 dev_dbg(codec->dev, "%s: RX_MIX_TX%u going to SLIM TX%u\n",
11412 __func__, tx_port, tx_port);
11413 } else {
11414 dev_err(codec->dev, "%s: ERROR: Invalid decimator: %d\n",
11415 __func__, decimator);
11416 return -EINVAL;
11417 }
11418 }
11419 return 0;
11420}
11421
11422static int tasha_set_mix_interpolator_rate(struct snd_soc_dai *dai,
11423 u8 int_mix_fs_rate_reg_val,
11424 u32 sample_rate)
11425{
11426 u8 int_2_inp;
11427 u32 j;
11428 u16 int_mux_cfg1, int_fs_reg;
11429 u8 int_mux_cfg1_val;
11430 struct snd_soc_codec *codec = dai->codec;
11431 struct wcd9xxx_ch *ch;
11432 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
11433
11434 list_for_each_entry(ch, &tasha->dai[dai->id].wcd9xxx_ch_list, list) {
11435 int_2_inp = ch->port + INTn_2_INP_SEL_RX0 -
11436 TASHA_RX_PORT_START_NUMBER;
11437 if ((int_2_inp < INTn_2_INP_SEL_RX0) ||
11438 (int_2_inp > INTn_2_INP_SEL_RX7)) {
11439 pr_err("%s: Invalid RX%u port, Dai ID is %d\n",
11440 __func__,
11441 (ch->port - TASHA_RX_PORT_START_NUMBER),
11442 dai->id);
11443 return -EINVAL;
11444 }
11445
11446 int_mux_cfg1 = WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG1;
11447 for (j = 0; j < TASHA_NUM_INTERPOLATORS; j++) {
11448 int_mux_cfg1_val = snd_soc_read(codec, int_mux_cfg1) &
11449 0x0F;
11450 if (int_mux_cfg1_val == int_2_inp) {
11451 int_fs_reg = WCD9335_CDC_RX0_RX_PATH_MIX_CTL +
11452 20 * j;
11453 pr_debug("%s: AIF_MIX_PB DAI(%d) connected to INT%u_2\n",
11454 __func__, dai->id, j);
11455 pr_debug("%s: set INT%u_2 sample rate to %u\n",
11456 __func__, j, sample_rate);
11457 snd_soc_update_bits(codec, int_fs_reg,
11458 0x0F, int_mix_fs_rate_reg_val);
11459 }
11460 int_mux_cfg1 += 2;
11461 }
11462 }
11463 return 0;
11464}
11465
11466static int tasha_set_prim_interpolator_rate(struct snd_soc_dai *dai,
11467 u8 int_prim_fs_rate_reg_val,
11468 u32 sample_rate)
11469{
11470 u8 int_1_mix1_inp;
11471 u32 j;
11472 u16 int_mux_cfg0, int_mux_cfg1;
11473 u16 int_fs_reg;
11474 u8 int_mux_cfg0_val, int_mux_cfg1_val;
11475 u8 inp0_sel, inp1_sel, inp2_sel;
11476 struct snd_soc_codec *codec = dai->codec;
11477 struct wcd9xxx_ch *ch;
11478 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
11479
11480 list_for_each_entry(ch, &tasha->dai[dai->id].wcd9xxx_ch_list, list) {
11481 int_1_mix1_inp = ch->port + INTn_1_MIX_INP_SEL_RX0 -
11482 TASHA_RX_PORT_START_NUMBER;
11483 if ((int_1_mix1_inp < INTn_1_MIX_INP_SEL_RX0) ||
11484 (int_1_mix1_inp > INTn_1_MIX_INP_SEL_RX7)) {
11485 pr_err("%s: Invalid RX%u port, Dai ID is %d\n",
11486 __func__,
11487 (ch->port - TASHA_RX_PORT_START_NUMBER),
11488 dai->id);
11489 return -EINVAL;
11490 }
11491
11492 int_mux_cfg0 = WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG0;
11493
11494 /*
11495 * Loop through all interpolator MUX inputs and find out
11496 * to which interpolator input, the slim rx port
11497 * is connected
11498 */
11499 for (j = 0; j < TASHA_NUM_INTERPOLATORS; j++) {
11500 int_mux_cfg1 = int_mux_cfg0 + 1;
11501
11502 int_mux_cfg0_val = snd_soc_read(codec, int_mux_cfg0);
11503 int_mux_cfg1_val = snd_soc_read(codec, int_mux_cfg1);
11504 inp0_sel = int_mux_cfg0_val & 0x0F;
11505 inp1_sel = (int_mux_cfg0_val >> 4) & 0x0F;
11506 inp2_sel = (int_mux_cfg1_val >> 4) & 0x0F;
11507 if ((inp0_sel == int_1_mix1_inp) ||
11508 (inp1_sel == int_1_mix1_inp) ||
11509 (inp2_sel == int_1_mix1_inp)) {
11510 int_fs_reg = WCD9335_CDC_RX0_RX_PATH_CTL +
11511 20 * j;
11512 pr_debug("%s: AIF_PB DAI(%d) connected to INT%u_1\n",
11513 __func__, dai->id, j);
11514 pr_debug("%s: set INT%u_1 sample rate to %u\n",
11515 __func__, j, sample_rate);
11516 /* sample_rate is in Hz */
11517 if ((j == 0) && (sample_rate == 44100)) {
11518 pr_info("%s: Cannot set 44.1KHz on INT0\n",
11519 __func__);
11520 } else
11521 snd_soc_update_bits(codec, int_fs_reg,
11522 0x0F, int_prim_fs_rate_reg_val);
11523 }
11524 int_mux_cfg0 += 2;
11525 }
11526 }
11527
11528 return 0;
11529}
11530
11531
11532static int tasha_set_interpolator_rate(struct snd_soc_dai *dai,
11533 u32 sample_rate)
11534{
11535 int rate_val = 0;
11536 int i, ret;
11537
11538 /* set mixing path rate */
11539 for (i = 0; i < ARRAY_SIZE(int_mix_sample_rate_val); i++) {
11540 if (sample_rate ==
11541 int_mix_sample_rate_val[i].sample_rate) {
11542 rate_val =
11543 int_mix_sample_rate_val[i].rate_val;
11544 break;
11545 }
11546 }
11547 if ((i == ARRAY_SIZE(int_mix_sample_rate_val)) ||
11548 (rate_val < 0))
11549 goto prim_rate;
11550 ret = tasha_set_mix_interpolator_rate(dai,
11551 (u8) rate_val, sample_rate);
11552prim_rate:
11553 /* set primary path sample rate */
11554 for (i = 0; i < ARRAY_SIZE(int_prim_sample_rate_val); i++) {
11555 if (sample_rate ==
11556 int_prim_sample_rate_val[i].sample_rate) {
11557 rate_val =
11558 int_prim_sample_rate_val[i].rate_val;
11559 break;
11560 }
11561 }
11562 if ((i == ARRAY_SIZE(int_prim_sample_rate_val)) ||
11563 (rate_val < 0))
11564 return -EINVAL;
11565 ret = tasha_set_prim_interpolator_rate(dai,
11566 (u8) rate_val, sample_rate);
11567 return ret;
11568}
11569
11570static int tasha_prepare(struct snd_pcm_substream *substream,
11571 struct snd_soc_dai *dai)
11572{
11573 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(dai->codec);
11574
11575 pr_debug("%s(): substream = %s stream = %d\n", __func__,
11576 substream->name, substream->stream);
11577 if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) &&
11578 test_bit(SB_CLK_GEAR, &tasha->status_mask)) {
11579 tasha_codec_vote_max_bw(dai->codec, false);
11580 clear_bit(SB_CLK_GEAR, &tasha->status_mask);
11581 }
11582 return 0;
11583}
11584
11585static int tasha_hw_params(struct snd_pcm_substream *substream,
11586 struct snd_pcm_hw_params *params,
11587 struct snd_soc_dai *dai)
11588{
11589 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(dai->codec);
11590 int ret;
11591 int tx_fs_rate = -EINVAL;
11592 int rx_fs_rate = -EINVAL;
11593 int i2s_bit_mode;
11594 struct snd_soc_codec *codec = dai->codec;
11595
11596 pr_debug("%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__,
11597 dai->name, dai->id, params_rate(params),
11598 params_channels(params));
11599
11600 switch (substream->stream) {
11601 case SNDRV_PCM_STREAM_PLAYBACK:
11602 ret = tasha_set_interpolator_rate(dai, params_rate(params));
11603 if (ret) {
11604 pr_err("%s: cannot set sample rate: %u\n",
11605 __func__, params_rate(params));
11606 return ret;
11607 }
11608 switch (params_width(params)) {
11609 case 16:
11610 tasha->dai[dai->id].bit_width = 16;
11611 i2s_bit_mode = 0x01;
11612 break;
11613 case 24:
11614 tasha->dai[dai->id].bit_width = 24;
11615 i2s_bit_mode = 0x00;
11616 break;
11617 default:
11618 return -EINVAL;
11619 }
11620 tasha->dai[dai->id].rate = params_rate(params);
11621 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
11622 switch (params_rate(params)) {
11623 case 8000:
11624 rx_fs_rate = 0;
11625 break;
11626 case 16000:
11627 rx_fs_rate = 1;
11628 break;
11629 case 32000:
11630 rx_fs_rate = 2;
11631 break;
11632 case 48000:
11633 rx_fs_rate = 3;
11634 break;
11635 case 96000:
11636 rx_fs_rate = 4;
11637 break;
11638 case 192000:
11639 rx_fs_rate = 5;
11640 break;
11641 default:
11642 dev_err(tasha->dev,
11643 "%s: Invalid RX sample rate: %d\n",
11644 __func__, params_rate(params));
11645 return -EINVAL;
11646 };
11647 snd_soc_update_bits(codec,
11648 WCD9335_DATA_HUB_DATA_HUB_RX_I2S_CTL,
11649 0x20, i2s_bit_mode << 5);
11650 snd_soc_update_bits(codec,
11651 WCD9335_DATA_HUB_DATA_HUB_RX_I2S_CTL,
11652 0x1c, (rx_fs_rate << 2));
11653 }
11654 break;
11655 case SNDRV_PCM_STREAM_CAPTURE:
11656 switch (params_rate(params)) {
11657 case 8000:
11658 tx_fs_rate = 0;
11659 break;
11660 case 16000:
11661 tx_fs_rate = 1;
11662 break;
11663 case 32000:
11664 tx_fs_rate = 3;
11665 break;
11666 case 48000:
11667 tx_fs_rate = 4;
11668 break;
11669 case 96000:
11670 tx_fs_rate = 5;
11671 break;
11672 case 192000:
11673 tx_fs_rate = 6;
11674 break;
11675 case 384000:
11676 tx_fs_rate = 7;
11677 break;
11678 default:
11679 dev_err(tasha->dev, "%s: Invalid TX sample rate: %d\n",
11680 __func__, params_rate(params));
11681 return -EINVAL;
11682
11683 };
11684 if (dai->id != AIF4_VIFEED &&
11685 dai->id != AIF4_MAD_TX) {
11686 ret = tasha_set_decimator_rate(dai, tx_fs_rate,
11687 params_rate(params));
11688 if (ret < 0) {
11689 dev_err(tasha->dev, "%s: cannot set TX Decimator rate: %d\n",
11690 __func__, tx_fs_rate);
11691 return ret;
11692 }
11693 }
11694 tasha->dai[dai->id].rate = params_rate(params);
11695 switch (params_width(params)) {
11696 case 16:
11697 tasha->dai[dai->id].bit_width = 16;
11698 i2s_bit_mode = 0x01;
11699 break;
11700 case 24:
11701 tasha->dai[dai->id].bit_width = 24;
11702 i2s_bit_mode = 0x00;
11703 break;
11704 case 32:
11705 tasha->dai[dai->id].bit_width = 32;
11706 i2s_bit_mode = 0x00;
11707 break;
11708 default:
11709 dev_err(tasha->dev, "%s: Invalid format 0x%x\n",
11710 __func__, params_width(params));
11711 return -EINVAL;
11712 };
11713 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
11714 snd_soc_update_bits(codec,
11715 WCD9335_DATA_HUB_DATA_HUB_TX_I2S_CTL,
11716 0x20, i2s_bit_mode << 5);
11717 if (tx_fs_rate > 1)
11718 tx_fs_rate--;
11719 snd_soc_update_bits(codec,
11720 WCD9335_DATA_HUB_DATA_HUB_TX_I2S_CTL,
11721 0x1c, tx_fs_rate << 2);
11722 snd_soc_update_bits(codec,
11723 WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD0_L_CFG,
11724 0x05, 0x05);
11725
11726 snd_soc_update_bits(codec,
11727 WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD0_R_CFG,
11728 0x05, 0x05);
11729
11730 snd_soc_update_bits(codec,
11731 WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD1_L_CFG,
11732 0x05, 0x05);
11733
11734 snd_soc_update_bits(codec,
11735 WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD1_R_CFG,
11736 0x05, 0x05);
11737 }
11738 break;
11739 default:
11740 pr_err("%s: Invalid stream type %d\n", __func__,
11741 substream->stream);
11742 return -EINVAL;
11743 };
11744 if (dai->id == AIF4_VIFEED)
11745 tasha->dai[dai->id].bit_width = 32;
11746
11747 return 0;
11748}
11749
11750static int tasha_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
11751{
11752 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(dai->codec);
11753
11754 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
11755 case SND_SOC_DAIFMT_CBS_CFS:
11756 /* CPU is master */
11757 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
11758 if (dai->id == AIF1_CAP)
11759 snd_soc_update_bits(dai->codec,
11760 WCD9335_DATA_HUB_DATA_HUB_TX_I2S_CTL,
11761 0x2, 0);
11762 else if (dai->id == AIF1_PB)
11763 snd_soc_update_bits(dai->codec,
11764 WCD9335_DATA_HUB_DATA_HUB_RX_I2S_CTL,
11765 0x2, 0);
11766 }
11767 break;
11768 case SND_SOC_DAIFMT_CBM_CFM:
11769 /* CPU is slave */
11770 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
11771 if (dai->id == AIF1_CAP)
11772 snd_soc_update_bits(dai->codec,
11773 WCD9335_DATA_HUB_DATA_HUB_TX_I2S_CTL,
11774 0x2, 0x2);
11775 else if (dai->id == AIF1_PB)
11776 snd_soc_update_bits(dai->codec,
11777 WCD9335_DATA_HUB_DATA_HUB_RX_I2S_CTL,
11778 0x2, 0x2);
11779 }
11780 break;
11781 default:
11782 return -EINVAL;
11783 }
11784 return 0;
11785}
11786
11787static int tasha_set_dai_sysclk(struct snd_soc_dai *dai,
11788 int clk_id, unsigned int freq, int dir)
11789{
11790 pr_debug("%s\n", __func__);
11791 return 0;
11792}
11793
11794static struct snd_soc_dai_ops tasha_dai_ops = {
11795 .startup = tasha_startup,
11796 .shutdown = tasha_shutdown,
11797 .hw_params = tasha_hw_params,
11798 .prepare = tasha_prepare,
11799 .set_sysclk = tasha_set_dai_sysclk,
11800 .set_fmt = tasha_set_dai_fmt,
11801 .set_channel_map = tasha_set_channel_map,
11802 .get_channel_map = tasha_get_channel_map,
11803};
11804
11805static struct snd_soc_dai_driver tasha_dai[] = {
11806 {
11807 .name = "tasha_rx1",
11808 .id = AIF1_PB,
11809 .playback = {
11810 .stream_name = "AIF1 Playback",
11811 .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK,
11812 .formats = TASHA_FORMATS_S16_S24_LE,
11813 .rate_max = 192000,
11814 .rate_min = 8000,
11815 .channels_min = 1,
11816 .channels_max = 2,
11817 },
11818 .ops = &tasha_dai_ops,
11819 },
11820 {
11821 .name = "tasha_tx1",
11822 .id = AIF1_CAP,
11823 .capture = {
11824 .stream_name = "AIF1 Capture",
11825 .rates = WCD9335_RATES_MASK,
11826 .formats = TASHA_FORMATS_S16_S24_LE,
11827 .rate_max = 192000,
11828 .rate_min = 8000,
11829 .channels_min = 1,
11830 .channels_max = 4,
11831 },
11832 .ops = &tasha_dai_ops,
11833 },
11834 {
11835 .name = "tasha_rx2",
11836 .id = AIF2_PB,
11837 .playback = {
11838 .stream_name = "AIF2 Playback",
11839 .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK,
11840 .formats = TASHA_FORMATS_S16_S24_LE,
11841 .rate_min = 8000,
11842 .rate_max = 192000,
11843 .channels_min = 1,
11844 .channels_max = 2,
11845 },
11846 .ops = &tasha_dai_ops,
11847 },
11848 {
11849 .name = "tasha_tx2",
11850 .id = AIF2_CAP,
11851 .capture = {
11852 .stream_name = "AIF2 Capture",
11853 .rates = WCD9335_RATES_MASK,
11854 .formats = TASHA_FORMATS_S16_S24_LE,
11855 .rate_max = 192000,
11856 .rate_min = 8000,
11857 .channels_min = 1,
11858 .channels_max = 8,
11859 },
11860 .ops = &tasha_dai_ops,
11861 },
11862 {
11863 .name = "tasha_rx3",
11864 .id = AIF3_PB,
11865 .playback = {
11866 .stream_name = "AIF3 Playback",
11867 .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK,
11868 .formats = TASHA_FORMATS_S16_S24_LE,
11869 .rate_min = 8000,
11870 .rate_max = 192000,
11871 .channels_min = 1,
11872 .channels_max = 2,
11873 },
11874 .ops = &tasha_dai_ops,
11875 },
11876 {
11877 .name = "tasha_tx3",
11878 .id = AIF3_CAP,
11879 .capture = {
11880 .stream_name = "AIF3 Capture",
11881 .rates = WCD9335_RATES_MASK,
11882 .formats = TASHA_FORMATS_S16_S24_LE,
11883 .rate_max = 48000,
11884 .rate_min = 8000,
11885 .channels_min = 1,
11886 .channels_max = 2,
11887 },
11888 .ops = &tasha_dai_ops,
11889 },
11890 {
11891 .name = "tasha_rx4",
11892 .id = AIF4_PB,
11893 .playback = {
11894 .stream_name = "AIF4 Playback",
11895 .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK,
11896 .formats = TASHA_FORMATS_S16_S24_LE,
11897 .rate_min = 8000,
11898 .rate_max = 192000,
11899 .channels_min = 1,
11900 .channels_max = 2,
11901 },
11902 .ops = &tasha_dai_ops,
11903 },
11904 {
11905 .name = "tasha_mix_rx1",
11906 .id = AIF_MIX1_PB,
11907 .playback = {
11908 .stream_name = "AIF Mix Playback",
11909 .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK,
11910 .formats = TASHA_FORMATS_S16_S24_LE,
11911 .rate_min = 8000,
11912 .rate_max = 192000,
11913 .channels_min = 1,
11914 .channels_max = 8,
11915 },
11916 .ops = &tasha_dai_ops,
11917 },
11918 {
11919 .name = "tasha_mad1",
11920 .id = AIF4_MAD_TX,
11921 .capture = {
11922 .stream_name = "AIF4 MAD TX",
11923 .rates = SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 |
11924 SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_384000,
11925 .formats = TASHA_FORMATS_S16_S24_S32_LE,
11926 .rate_min = 16000,
11927 .rate_max = 384000,
11928 .channels_min = 1,
11929 .channels_max = 1,
11930 },
11931 .ops = &tasha_dai_ops,
11932 },
11933 {
11934 .name = "tasha_vifeedback",
11935 .id = AIF4_VIFEED,
11936 .capture = {
11937 .stream_name = "VIfeed",
11938 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000,
11939 .formats = TASHA_FORMATS_S16_S24_S32_LE,
11940 .rate_max = 48000,
11941 .rate_min = 8000,
11942 .channels_min = 1,
11943 .channels_max = 4,
11944 },
11945 .ops = &tasha_dai_ops,
11946 },
11947 {
11948 .name = "tasha_cpe",
11949 .id = AIF5_CPE_TX,
11950 .capture = {
11951 .stream_name = "AIF5 CPE TX",
11952 .rates = SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000,
11953 .formats = TASHA_FORMATS_S16_S24_S32_LE,
11954 .rate_min = 16000,
11955 .rate_max = 48000,
11956 .channels_min = 1,
11957 .channels_max = 1,
11958 },
11959 },
11960};
11961
11962static struct snd_soc_dai_driver tasha_i2s_dai[] = {
11963 {
11964 .name = "tasha_i2s_rx1",
11965 .id = AIF1_PB,
11966 .playback = {
11967 .stream_name = "AIF1 Playback",
11968 .rates = WCD9335_RATES_MASK,
11969 .formats = TASHA_FORMATS_S16_S24_LE,
11970 .rate_max = 192000,
11971 .rate_min = 8000,
11972 .channels_min = 1,
11973 .channels_max = 2,
11974 },
11975 .ops = &tasha_dai_ops,
11976 },
11977 {
11978 .name = "tasha_i2s_tx1",
11979 .id = AIF1_CAP,
11980 .capture = {
11981 .stream_name = "AIF1 Capture",
11982 .rates = WCD9335_RATES_MASK,
11983 .formats = TASHA_FORMATS_S16_S24_LE,
11984 .rate_max = 192000,
11985 .rate_min = 8000,
11986 .channels_min = 1,
11987 .channels_max = 4,
11988 },
11989 .ops = &tasha_dai_ops,
11990 },
11991 {
11992 .name = "tasha_i2s_rx2",
11993 .id = AIF2_PB,
11994 .playback = {
11995 .stream_name = "AIF2 Playback",
11996 .rates = WCD9335_RATES_MASK,
11997 .formats = TASHA_FORMATS_S16_S24_LE,
11998 .rate_max = 192000,
11999 .rate_min = 8000,
12000 .channels_min = 1,
12001 .channels_max = 2,
12002 },
12003 .ops = &tasha_dai_ops,
12004 },
12005 {
12006 .name = "tasha_i2s_tx2",
12007 .id = AIF2_CAP,
12008 .capture = {
12009 .stream_name = "AIF2 Capture",
12010 .rates = WCD9335_RATES_MASK,
12011 .formats = TASHA_FORMATS_S16_S24_LE,
12012 .rate_max = 192000,
12013 .rate_min = 8000,
12014 .channels_min = 1,
12015 .channels_max = 4,
12016 },
12017 .ops = &tasha_dai_ops,
12018 },
12019};
12020
12021static void tasha_codec_power_gate_digital_core(struct tasha_priv *tasha)
12022{
12023 struct snd_soc_codec *codec = tasha->codec;
12024
12025 if (!codec)
12026 return;
12027
12028 mutex_lock(&tasha->power_lock);
12029 dev_dbg(codec->dev, "%s: Entering power gating function, %d\n",
12030 __func__, tasha->power_active_ref);
12031
12032 if (tasha->power_active_ref > 0)
12033 goto exit;
12034
12035 wcd9xxx_set_power_state(tasha->wcd9xxx,
12036 WCD_REGION_POWER_COLLAPSE_BEGIN,
12037 WCD9XXX_DIG_CORE_REGION_1);
12038 snd_soc_update_bits(codec, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL,
12039 0x04, 0x04);
12040 snd_soc_update_bits(codec, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL,
12041 0x01, 0x00);
12042 snd_soc_update_bits(codec, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL,
12043 0x02, 0x00);
12044 clear_bit(AUDIO_NOMINAL, &tasha->status_mask);
12045 tasha_codec_update_sido_voltage(tasha, sido_buck_svs_voltage);
12046 wcd9xxx_set_power_state(tasha->wcd9xxx, WCD_REGION_POWER_DOWN,
12047 WCD9XXX_DIG_CORE_REGION_1);
12048exit:
12049 dev_dbg(codec->dev, "%s: Exiting power gating function, %d\n",
12050 __func__, tasha->power_active_ref);
12051 mutex_unlock(&tasha->power_lock);
12052}
12053
12054static void tasha_codec_power_gate_work(struct work_struct *work)
12055{
12056 struct tasha_priv *tasha;
12057 struct delayed_work *dwork;
12058 struct snd_soc_codec *codec;
12059
12060 dwork = to_delayed_work(work);
12061 tasha = container_of(dwork, struct tasha_priv, power_gate_work);
12062 codec = tasha->codec;
12063
12064 if (!codec)
12065 return;
12066
12067 tasha_codec_power_gate_digital_core(tasha);
12068}
12069
12070/* called under power_lock acquisition */
12071static int tasha_dig_core_remove_power_collapse(struct snd_soc_codec *codec)
12072{
12073 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
12074
12075 tasha_codec_vote_max_bw(codec, true);
12076 snd_soc_write(codec, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x5);
12077 snd_soc_write(codec, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x7);
12078 snd_soc_write(codec, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x3);
12079 snd_soc_update_bits(codec, WCD9335_CODEC_RPM_RST_CTL, 0x02, 0x00);
12080 snd_soc_update_bits(codec, WCD9335_CODEC_RPM_RST_CTL, 0x02, 0x02);
12081
12082 wcd9xxx_set_power_state(tasha->wcd9xxx,
12083 WCD_REGION_POWER_COLLAPSE_REMOVE,
12084 WCD9XXX_DIG_CORE_REGION_1);
12085 regcache_mark_dirty(codec->component.regmap);
12086 regcache_sync_region(codec->component.regmap,
12087 TASHA_DIG_CORE_REG_MIN, TASHA_DIG_CORE_REG_MAX);
12088 tasha_codec_vote_max_bw(codec, false);
12089
12090 return 0;
12091}
12092
12093static int tasha_dig_core_power_collapse(struct tasha_priv *tasha,
12094 int req_state)
12095{
12096 struct snd_soc_codec *codec;
12097 int cur_state;
12098
12099 /* Exit if feature is disabled */
12100 if (!dig_core_collapse_enable)
12101 return 0;
12102
12103 mutex_lock(&tasha->power_lock);
12104 if (req_state == POWER_COLLAPSE)
12105 tasha->power_active_ref--;
12106 else if (req_state == POWER_RESUME)
12107 tasha->power_active_ref++;
12108 else
12109 goto unlock_mutex;
12110
12111 if (tasha->power_active_ref < 0) {
12112 dev_dbg(tasha->dev, "%s: power_active_ref is negative\n",
12113 __func__);
12114 goto unlock_mutex;
12115 }
12116
12117 codec = tasha->codec;
12118 if (!codec)
12119 goto unlock_mutex;
12120
12121 if (req_state == POWER_COLLAPSE) {
12122 if (tasha->power_active_ref == 0) {
12123 schedule_delayed_work(&tasha->power_gate_work,
12124 msecs_to_jiffies(dig_core_collapse_timer * 1000));
12125 }
12126 } else if (req_state == POWER_RESUME) {
12127 if (tasha->power_active_ref == 1) {
12128 /*
12129 * At this point, there can be two cases:
12130 * 1. Core already in power collapse state
12131 * 2. Timer kicked in and still did not expire or
12132 * waiting for the power_lock
12133 */
12134 cur_state = wcd9xxx_get_current_power_state(
12135 tasha->wcd9xxx,
12136 WCD9XXX_DIG_CORE_REGION_1);
12137 if (cur_state == WCD_REGION_POWER_DOWN)
12138 tasha_dig_core_remove_power_collapse(codec);
12139 else {
12140 mutex_unlock(&tasha->power_lock);
12141 cancel_delayed_work_sync(
12142 &tasha->power_gate_work);
12143 mutex_lock(&tasha->power_lock);
12144 }
12145 }
12146 }
12147
12148unlock_mutex:
12149 mutex_unlock(&tasha->power_lock);
12150
12151 return 0;
12152}
12153
12154static int __tasha_cdc_mclk_enable_locked(struct tasha_priv *tasha,
12155 bool enable)
12156{
12157 int ret = 0;
12158
12159 if (!tasha->wcd_ext_clk) {
12160 dev_err(tasha->dev, "%s: wcd ext clock is NULL\n", __func__);
12161 return -EINVAL;
12162 }
12163
12164 dev_dbg(tasha->dev, "%s: mclk_enable = %u\n", __func__, enable);
12165
12166 if (enable) {
12167 tasha_dig_core_power_collapse(tasha, POWER_RESUME);
12168 ret = tasha_cdc_req_mclk_enable(tasha, true);
12169 if (ret)
12170 goto err;
12171
12172 set_bit(AUDIO_NOMINAL, &tasha->status_mask);
12173 tasha_codec_apply_sido_voltage(tasha,
12174 SIDO_VOLTAGE_NOMINAL_MV);
12175 } else {
12176 if (!dig_core_collapse_enable) {
12177 clear_bit(AUDIO_NOMINAL, &tasha->status_mask);
12178 tasha_codec_update_sido_voltage(tasha,
12179 sido_buck_svs_voltage);
12180 }
12181 tasha_cdc_req_mclk_enable(tasha, false);
12182 tasha_dig_core_power_collapse(tasha, POWER_COLLAPSE);
12183 }
12184
12185err:
12186 return ret;
12187}
12188
12189static int __tasha_cdc_mclk_enable(struct tasha_priv *tasha,
12190 bool enable)
12191{
12192 int ret;
12193
12194 WCD9XXX_V2_BG_CLK_LOCK(tasha->resmgr);
12195 ret = __tasha_cdc_mclk_enable_locked(tasha, enable);
12196 WCD9XXX_V2_BG_CLK_UNLOCK(tasha->resmgr);
12197
12198 return ret;
12199}
12200
12201int tasha_cdc_mclk_enable(struct snd_soc_codec *codec, int enable, bool dapm)
12202{
12203 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
12204
12205 return __tasha_cdc_mclk_enable(tasha, enable);
12206}
12207EXPORT_SYMBOL(tasha_cdc_mclk_enable);
12208
12209int tasha_cdc_mclk_tx_enable(struct snd_soc_codec *codec, int enable, bool dapm)
12210{
12211 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
12212 int ret = 0;
12213
12214 dev_dbg(tasha->dev, "%s: clk_mode: %d, enable: %d, clk_internal: %d\n",
12215 __func__, tasha->clk_mode, enable, tasha->clk_internal);
12216 if (tasha->clk_mode || tasha->clk_internal) {
12217 if (enable) {
12218 tasha_cdc_sido_ccl_enable(tasha, true);
12219 wcd_resmgr_enable_master_bias(tasha->resmgr);
12220 tasha_dig_core_power_collapse(tasha, POWER_RESUME);
12221 snd_soc_update_bits(codec,
12222 WCD9335_CDC_CLK_RST_CTRL_FS_CNT_CONTROL,
12223 0x01, 0x01);
12224 snd_soc_update_bits(codec,
12225 WCD9335_CDC_CLK_RST_CTRL_MCLK_CONTROL,
12226 0x01, 0x01);
12227 set_bit(CPE_NOMINAL, &tasha->status_mask);
12228 tasha_codec_update_sido_voltage(tasha,
12229 SIDO_VOLTAGE_NOMINAL_MV);
12230 tasha->clk_internal = true;
12231 } else {
12232 tasha->clk_internal = false;
12233 clear_bit(CPE_NOMINAL, &tasha->status_mask);
12234 tasha_codec_update_sido_voltage(tasha,
12235 sido_buck_svs_voltage);
12236 tasha_dig_core_power_collapse(tasha, POWER_COLLAPSE);
12237 wcd_resmgr_disable_master_bias(tasha->resmgr);
12238 tasha_cdc_sido_ccl_enable(tasha, false);
12239 }
12240 } else {
12241 ret = __tasha_cdc_mclk_enable(tasha, enable);
12242 }
12243 return ret;
12244}
12245EXPORT_SYMBOL(tasha_cdc_mclk_tx_enable);
12246
12247static ssize_t tasha_codec_version_read(struct snd_info_entry *entry,
12248 void *file_private_data, struct file *file,
12249 char __user *buf, size_t count, loff_t pos)
12250{
12251 struct tasha_priv *tasha;
12252 struct wcd9xxx *wcd9xxx;
12253 char buffer[TASHA_VERSION_ENTRY_SIZE];
12254 int len = 0;
12255
12256 tasha = (struct tasha_priv *) entry->private_data;
12257 if (!tasha) {
12258 pr_err("%s: tasha priv is null\n", __func__);
12259 return -EINVAL;
12260 }
12261
12262 wcd9xxx = tasha->wcd9xxx;
12263
12264 if (wcd9xxx->codec_type->id_major == TASHA_MAJOR) {
12265 if (TASHA_IS_1_0(wcd9xxx))
12266 len = snprintf(buffer, sizeof(buffer), "WCD9335_1_0\n");
12267 else if (TASHA_IS_1_1(wcd9xxx))
12268 len = snprintf(buffer, sizeof(buffer), "WCD9335_1_1\n");
12269 else
12270 snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n");
12271 } else if (wcd9xxx->codec_type->id_major == TASHA2P0_MAJOR) {
12272 len = snprintf(buffer, sizeof(buffer), "WCD9335_2_0\n");
12273 } else
12274 len = snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n");
12275
12276 return simple_read_from_buffer(buf, count, &pos, buffer, len);
12277}
12278
12279static struct snd_info_entry_ops tasha_codec_info_ops = {
12280 .read = tasha_codec_version_read,
12281};
12282
12283/*
12284 * tasha_codec_info_create_codec_entry - creates wcd9335 module
12285 * @codec_root: The parent directory
12286 * @codec: Codec instance
12287 *
12288 * Creates wcd9335 module and version entry under the given
12289 * parent directory.
12290 *
12291 * Return: 0 on success or negative error code on failure.
12292 */
12293int tasha_codec_info_create_codec_entry(struct snd_info_entry *codec_root,
12294 struct snd_soc_codec *codec)
12295{
12296 struct snd_info_entry *version_entry;
12297 struct tasha_priv *tasha;
12298 struct snd_soc_card *card;
12299
12300 if (!codec_root || !codec)
12301 return -EINVAL;
12302
12303 tasha = snd_soc_codec_get_drvdata(codec);
12304 card = codec->component.card;
Banajit Goswami7f40ea42017-01-30 13:32:41 -080012305 tasha->entry = snd_info_create_subdir(codec_root->module,
12306 "tasha", codec_root);
Banajit Goswamide8271c2017-01-18 00:28:59 -080012307 if (!tasha->entry) {
12308 dev_dbg(codec->dev, "%s: failed to create wcd9335 entry\n",
12309 __func__);
12310 return -ENOMEM;
12311 }
12312
12313 version_entry = snd_info_create_card_entry(card->snd_card,
12314 "version",
12315 tasha->entry);
12316 if (!version_entry) {
12317 dev_dbg(codec->dev, "%s: failed to create wcd9335 version entry\n",
12318 __func__);
12319 return -ENOMEM;
12320 }
12321
12322 version_entry->private_data = tasha;
12323 version_entry->size = TASHA_VERSION_ENTRY_SIZE;
12324 version_entry->content = SNDRV_INFO_CONTENT_DATA;
12325 version_entry->c.ops = &tasha_codec_info_ops;
12326
12327 if (snd_info_register(version_entry) < 0) {
12328 snd_info_free_entry(version_entry);
12329 return -ENOMEM;
12330 }
12331 tasha->version_entry = version_entry;
12332
12333 return 0;
12334}
12335EXPORT_SYMBOL(tasha_codec_info_create_codec_entry);
12336
12337static int __tasha_codec_internal_rco_ctrl(
12338 struct snd_soc_codec *codec, bool enable)
12339{
12340 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
12341 int ret = 0;
12342
12343 if (enable) {
12344 tasha_cdc_sido_ccl_enable(tasha, true);
12345 if (wcd_resmgr_get_clk_type(tasha->resmgr) ==
12346 WCD_CLK_RCO) {
12347 ret = wcd_resmgr_enable_clk_block(tasha->resmgr,
12348 WCD_CLK_RCO);
12349 } else {
12350 ret = tasha_cdc_req_mclk_enable(tasha, true);
12351 ret |= wcd_resmgr_enable_clk_block(tasha->resmgr,
12352 WCD_CLK_RCO);
12353 ret |= tasha_cdc_req_mclk_enable(tasha, false);
12354 }
12355
12356 } else {
12357 ret = wcd_resmgr_disable_clk_block(tasha->resmgr,
12358 WCD_CLK_RCO);
12359 tasha_cdc_sido_ccl_enable(tasha, false);
12360 }
12361
12362 if (ret) {
12363 dev_err(codec->dev, "%s: Error in %s RCO\n",
12364 __func__, (enable ? "enabling" : "disabling"));
12365 ret = -EINVAL;
12366 }
12367
12368 return ret;
12369}
12370
12371/*
12372 * tasha_codec_internal_rco_ctrl()
12373 * Make sure that the caller does not acquire
12374 * BG_CLK_LOCK.
12375 */
12376static int tasha_codec_internal_rco_ctrl(struct snd_soc_codec *codec,
12377 bool enable)
12378{
12379 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
12380 int ret = 0;
12381
12382 WCD9XXX_V2_BG_CLK_LOCK(tasha->resmgr);
12383 ret = __tasha_codec_internal_rco_ctrl(codec, enable);
12384 WCD9XXX_V2_BG_CLK_UNLOCK(tasha->resmgr);
12385 return ret;
12386}
12387
12388/*
12389 * tasha_mbhc_hs_detect: starts mbhc insertion/removal functionality
12390 * @codec: handle to snd_soc_codec *
12391 * @mbhc_cfg: handle to mbhc configuration structure
12392 * return 0 if mbhc_start is success or error code in case of failure
12393 */
12394int tasha_mbhc_hs_detect(struct snd_soc_codec *codec,
12395 struct wcd_mbhc_config *mbhc_cfg)
12396{
12397 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
12398
12399 return wcd_mbhc_start(&tasha->mbhc, mbhc_cfg);
12400}
12401EXPORT_SYMBOL(tasha_mbhc_hs_detect);
12402
12403/*
12404 * tasha_mbhc_hs_detect_exit: stop mbhc insertion/removal functionality
12405 * @codec: handle to snd_soc_codec *
12406 */
12407void tasha_mbhc_hs_detect_exit(struct snd_soc_codec *codec)
12408{
12409 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
12410
12411 wcd_mbhc_stop(&tasha->mbhc);
12412}
12413EXPORT_SYMBOL(tasha_mbhc_hs_detect_exit);
12414
12415static int wcd9335_get_micb_vout_ctl_val(u32 micb_mv)
12416{
12417 /* min micbias voltage is 1V and maximum is 2.85V */
12418 if (micb_mv < 1000 || micb_mv > 2850) {
12419 pr_err("%s: unsupported micbias voltage\n", __func__);
12420 return -EINVAL;
12421 }
12422
12423 return (micb_mv - 1000) / 50;
12424}
12425
12426static const struct tasha_reg_mask_val tasha_reg_update_reset_val_1_1[] = {
12427 {WCD9335_RCO_CTRL_2, 0xFF, 0x47},
12428 {WCD9335_FLYBACK_VNEG_DAC_CTRL_4, 0xFF, 0x60},
12429};
12430
12431static const struct tasha_reg_mask_val tasha_codec_reg_init_val_1_1[] = {
12432 {WCD9335_FLYBACK_VNEG_DAC_CTRL_1, 0xFF, 0x65},
12433 {WCD9335_FLYBACK_VNEG_DAC_CTRL_2, 0xFF, 0x52},
12434 {WCD9335_FLYBACK_VNEG_DAC_CTRL_3, 0xFF, 0xAF},
12435 {WCD9335_FLYBACK_VNEG_DAC_CTRL_4, 0xFF, 0x60},
12436 {WCD9335_FLYBACK_VNEG_CTRL_3, 0xFF, 0xF4},
12437 {WCD9335_FLYBACK_VNEG_CTRL_9, 0xFF, 0x40},
12438 {WCD9335_FLYBACK_VNEG_CTRL_2, 0xFF, 0x4F},
12439 {WCD9335_FLYBACK_EN, 0xFF, 0x6E},
12440 {WCD9335_CDC_RX2_RX_PATH_SEC0, 0xF8, 0xF8},
12441 {WCD9335_CDC_RX1_RX_PATH_SEC0, 0xF8, 0xF8},
12442};
12443
12444static const struct tasha_reg_mask_val tasha_codec_reg_init_val_1_0[] = {
12445 {WCD9335_FLYBACK_VNEG_CTRL_3, 0xFF, 0x54},
12446 {WCD9335_CDC_RX2_RX_PATH_SEC0, 0xFC, 0xFC},
12447 {WCD9335_CDC_RX1_RX_PATH_SEC0, 0xFC, 0xFC},
12448};
12449
12450static const struct tasha_reg_mask_val tasha_codec_reg_init_val_2_0[] = {
12451 {WCD9335_RCO_CTRL_2, 0x0F, 0x08},
12452 {WCD9335_RX_BIAS_FLYB_MID_RST, 0xF0, 0x10},
12453 {WCD9335_FLYBACK_CTRL_1, 0x20, 0x20},
12454 {WCD9335_HPH_OCP_CTL, 0xFF, 0x7A},
12455 {WCD9335_HPH_L_TEST, 0x01, 0x01},
12456 {WCD9335_HPH_R_TEST, 0x01, 0x01},
12457 {WCD9335_CDC_BOOST0_BOOST_CFG1, 0x3F, 0x12},
12458 {WCD9335_CDC_BOOST0_BOOST_CFG2, 0x1C, 0x08},
12459 {WCD9335_CDC_COMPANDER7_CTL7, 0x1E, 0x18},
12460 {WCD9335_CDC_BOOST1_BOOST_CFG1, 0x3F, 0x12},
12461 {WCD9335_CDC_BOOST1_BOOST_CFG2, 0x1C, 0x08},
12462 {WCD9335_CDC_COMPANDER8_CTL7, 0x1E, 0x18},
12463 {WCD9335_CDC_TX0_TX_PATH_SEC7, 0xFF, 0x45},
12464 {WCD9335_CDC_RX0_RX_PATH_SEC0, 0xFC, 0xF4},
12465 {WCD9335_HPH_REFBUFF_LP_CTL, 0x08, 0x08},
12466 {WCD9335_HPH_REFBUFF_LP_CTL, 0x06, 0x02},
12467 {WCD9335_DIFF_LO_CORE_OUT_PROG, 0xFC, 0xA0},
12468 {WCD9335_SE_LO_COM1, 0xFF, 0xC0},
12469 {WCD9335_CDC_RX3_RX_PATH_SEC0, 0xFC, 0xF4},
12470 {WCD9335_CDC_RX4_RX_PATH_SEC0, 0xFC, 0xF4},
12471 {WCD9335_CDC_RX5_RX_PATH_SEC0, 0xFC, 0xF8},
12472 {WCD9335_CDC_RX6_RX_PATH_SEC0, 0xFC, 0xF8},
12473};
12474
12475static const struct tasha_reg_mask_val tasha_codec_reg_defaults[] = {
12476 {WCD9335_CODEC_RPM_CLK_GATE, 0x03, 0x00},
12477 {WCD9335_CODEC_RPM_CLK_MCLK_CFG, 0x03, 0x01},
12478 {WCD9335_CODEC_RPM_CLK_MCLK_CFG, 0x04, 0x04},
12479};
12480
12481static const struct tasha_reg_mask_val tasha_codec_reg_i2c_defaults[] = {
12482 {WCD9335_ANA_CLK_TOP, 0x20, 0x20},
12483 {WCD9335_CODEC_RPM_CLK_GATE, 0x03, 0x01},
12484 {WCD9335_CODEC_RPM_CLK_MCLK_CFG, 0x03, 0x00},
12485 {WCD9335_CODEC_RPM_CLK_MCLK_CFG, 0x05, 0x05},
12486 {WCD9335_DATA_HUB_DATA_HUB_RX0_INP_CFG, 0x01, 0x01},
12487 {WCD9335_DATA_HUB_DATA_HUB_RX1_INP_CFG, 0x01, 0x01},
12488 {WCD9335_DATA_HUB_DATA_HUB_RX2_INP_CFG, 0x01, 0x01},
12489 {WCD9335_DATA_HUB_DATA_HUB_RX3_INP_CFG, 0x01, 0x01},
12490 {WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD0_L_CFG, 0x05, 0x05},
12491 {WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD0_R_CFG, 0x05, 0x05},
12492 {WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD1_L_CFG, 0x05, 0x05},
12493 {WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD1_R_CFG, 0x05, 0x05},
12494};
12495
12496static const struct tasha_reg_mask_val tasha_codec_reg_init_common_val[] = {
12497 /* Rbuckfly/R_EAR(32) */
12498 {WCD9335_CDC_CLSH_K2_MSB, 0x0F, 0x00},
12499 {WCD9335_CDC_CLSH_K2_LSB, 0xFF, 0x60},
12500 {WCD9335_CPE_SS_DMIC_CFG, 0x80, 0x00},
12501 {WCD9335_CDC_BOOST0_BOOST_CTL, 0x70, 0x50},
12502 {WCD9335_CDC_BOOST1_BOOST_CTL, 0x70, 0x50},
12503 {WCD9335_CDC_RX7_RX_PATH_CFG1, 0x08, 0x08},
12504 {WCD9335_CDC_RX8_RX_PATH_CFG1, 0x08, 0x08},
12505 {WCD9335_ANA_LO_1_2, 0x3C, 0X3C},
12506 {WCD9335_DIFF_LO_COM_SWCAP_REFBUF_FREQ, 0x70, 0x00},
12507 {WCD9335_SOC_MAD_AUDIO_CTL_2, 0x03, 0x03},
12508 {WCD9335_CDC_TOP_TOP_CFG1, 0x02, 0x02},
12509 {WCD9335_CDC_TOP_TOP_CFG1, 0x01, 0x01},
12510 {WCD9335_EAR_CMBUFF, 0x08, 0x00},
12511 {WCD9335_CDC_TX9_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
12512 {WCD9335_CDC_TX10_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
12513 {WCD9335_CDC_TX11_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
12514 {WCD9335_CDC_TX12_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
12515 {WCD9335_CDC_COMPANDER7_CTL3, 0x80, 0x80},
12516 {WCD9335_CDC_COMPANDER8_CTL3, 0x80, 0x80},
12517 {WCD9335_CDC_COMPANDER7_CTL7, 0x01, 0x01},
12518 {WCD9335_CDC_COMPANDER8_CTL7, 0x01, 0x01},
12519 {WCD9335_CDC_RX0_RX_PATH_CFG0, 0x01, 0x01},
12520 {WCD9335_CDC_RX1_RX_PATH_CFG0, 0x01, 0x01},
12521 {WCD9335_CDC_RX2_RX_PATH_CFG0, 0x01, 0x01},
12522 {WCD9335_CDC_RX3_RX_PATH_CFG0, 0x01, 0x01},
12523 {WCD9335_CDC_RX4_RX_PATH_CFG0, 0x01, 0x01},
12524 {WCD9335_CDC_RX5_RX_PATH_CFG0, 0x01, 0x01},
12525 {WCD9335_CDC_RX6_RX_PATH_CFG0, 0x01, 0x01},
12526 {WCD9335_CDC_RX7_RX_PATH_CFG0, 0x01, 0x01},
12527 {WCD9335_CDC_RX8_RX_PATH_CFG0, 0x01, 0x01},
12528 {WCD9335_CDC_RX0_RX_PATH_MIX_CFG, 0x01, 0x01},
12529 {WCD9335_CDC_RX1_RX_PATH_MIX_CFG, 0x01, 0x01},
12530 {WCD9335_CDC_RX2_RX_PATH_MIX_CFG, 0x01, 0x01},
12531 {WCD9335_CDC_RX3_RX_PATH_MIX_CFG, 0x01, 0x01},
12532 {WCD9335_CDC_RX4_RX_PATH_MIX_CFG, 0x01, 0x01},
12533 {WCD9335_CDC_RX5_RX_PATH_MIX_CFG, 0x01, 0x01},
12534 {WCD9335_CDC_RX6_RX_PATH_MIX_CFG, 0x01, 0x01},
12535 {WCD9335_CDC_RX7_RX_PATH_MIX_CFG, 0x01, 0x01},
12536 {WCD9335_CDC_RX8_RX_PATH_MIX_CFG, 0x01, 0x01},
12537 {WCD9335_VBADC_IBIAS_FE, 0x0C, 0x08},
12538};
12539
12540static const struct tasha_reg_mask_val tasha_codec_reg_init_1_x_val[] = {
12541 /* Enable TX HPF Filter & Linear Phase */
12542 {WCD9335_CDC_TX0_TX_PATH_CFG0, 0x11, 0x11},
12543 {WCD9335_CDC_TX1_TX_PATH_CFG0, 0x11, 0x11},
12544 {WCD9335_CDC_TX2_TX_PATH_CFG0, 0x11, 0x11},
12545 {WCD9335_CDC_TX3_TX_PATH_CFG0, 0x11, 0x11},
12546 {WCD9335_CDC_TX4_TX_PATH_CFG0, 0x11, 0x11},
12547 {WCD9335_CDC_TX5_TX_PATH_CFG0, 0x11, 0x11},
12548 {WCD9335_CDC_TX6_TX_PATH_CFG0, 0x11, 0x11},
12549 {WCD9335_CDC_TX7_TX_PATH_CFG0, 0x11, 0x11},
12550 {WCD9335_CDC_TX8_TX_PATH_CFG0, 0x11, 0x11},
12551 {WCD9335_CDC_RX0_RX_PATH_SEC0, 0xF8, 0xF8},
12552 {WCD9335_CDC_RX0_RX_PATH_SEC1, 0x08, 0x08},
12553 {WCD9335_CDC_RX1_RX_PATH_SEC1, 0x08, 0x08},
12554 {WCD9335_CDC_RX2_RX_PATH_SEC1, 0x08, 0x08},
12555 {WCD9335_CDC_RX3_RX_PATH_SEC1, 0x08, 0x08},
12556 {WCD9335_CDC_RX4_RX_PATH_SEC1, 0x08, 0x08},
12557 {WCD9335_CDC_RX5_RX_PATH_SEC1, 0x08, 0x08},
12558 {WCD9335_CDC_RX6_RX_PATH_SEC1, 0x08, 0x08},
12559 {WCD9335_CDC_RX7_RX_PATH_SEC1, 0x08, 0x08},
12560 {WCD9335_CDC_RX8_RX_PATH_SEC1, 0x08, 0x08},
12561 {WCD9335_CDC_RX0_RX_PATH_MIX_SEC0, 0x08, 0x08},
12562 {WCD9335_CDC_RX1_RX_PATH_MIX_SEC0, 0x08, 0x08},
12563 {WCD9335_CDC_RX2_RX_PATH_MIX_SEC0, 0x08, 0x08},
12564 {WCD9335_CDC_RX3_RX_PATH_MIX_SEC0, 0x08, 0x08},
12565 {WCD9335_CDC_RX4_RX_PATH_MIX_SEC0, 0x08, 0x08},
12566 {WCD9335_CDC_RX5_RX_PATH_MIX_SEC0, 0x08, 0x08},
12567 {WCD9335_CDC_RX6_RX_PATH_MIX_SEC0, 0x08, 0x08},
12568 {WCD9335_CDC_RX7_RX_PATH_MIX_SEC0, 0x08, 0x08},
12569 {WCD9335_CDC_RX8_RX_PATH_MIX_SEC0, 0x08, 0x08},
12570 {WCD9335_CDC_TX0_TX_PATH_SEC2, 0x01, 0x01},
12571 {WCD9335_CDC_TX1_TX_PATH_SEC2, 0x01, 0x01},
12572 {WCD9335_CDC_TX2_TX_PATH_SEC2, 0x01, 0x01},
12573 {WCD9335_CDC_TX3_TX_PATH_SEC2, 0x01, 0x01},
12574 {WCD9335_CDC_TX4_TX_PATH_SEC2, 0x01, 0x01},
12575 {WCD9335_CDC_TX5_TX_PATH_SEC2, 0x01, 0x01},
12576 {WCD9335_CDC_TX6_TX_PATH_SEC2, 0x01, 0x01},
12577 {WCD9335_CDC_TX7_TX_PATH_SEC2, 0x01, 0x01},
12578 {WCD9335_CDC_TX8_TX_PATH_SEC2, 0x01, 0x01},
12579 {WCD9335_CDC_RX3_RX_PATH_SEC0, 0xF8, 0xF0},
12580 {WCD9335_CDC_RX4_RX_PATH_SEC0, 0xF8, 0xF0},
12581 {WCD9335_CDC_RX5_RX_PATH_SEC0, 0xF8, 0xF8},
12582 {WCD9335_CDC_RX6_RX_PATH_SEC0, 0xF8, 0xF8},
12583 {WCD9335_RX_OCP_COUNT, 0xFF, 0xFF},
12584 {WCD9335_HPH_OCP_CTL, 0xF0, 0x70},
12585 {WCD9335_CPE_SS_CPAR_CFG, 0xFF, 0x00},
12586 {WCD9335_FLYBACK_VNEG_CTRL_1, 0xFF, 0x63},
12587 {WCD9335_FLYBACK_VNEG_CTRL_4, 0xFF, 0x7F},
12588 {WCD9335_CLASSH_CTRL_VCL_1, 0xFF, 0x60},
12589 {WCD9335_CLASSH_CTRL_CCL_5, 0xFF, 0x40},
12590 {WCD9335_RX_TIMER_DIV, 0xFF, 0x32},
12591 {WCD9335_SE_LO_COM2, 0xFF, 0x01},
12592 {WCD9335_MBHC_ZDET_ANA_CTL, 0x0F, 0x07},
12593 {WCD9335_RX_BIAS_HPH_PA, 0xF0, 0x60},
12594 {WCD9335_HPH_RDAC_LDO_CTL, 0x88, 0x88},
12595 {WCD9335_HPH_L_EN, 0x20, 0x20},
12596 {WCD9335_HPH_R_EN, 0x20, 0x20},
12597 {WCD9335_DIFF_LO_CORE_OUT_PROG, 0xFC, 0xD8},
12598 {WCD9335_CDC_RX5_RX_PATH_SEC3, 0xBD, 0xBD},
12599 {WCD9335_CDC_RX6_RX_PATH_SEC3, 0xBD, 0xBD},
12600 {WCD9335_DIFF_LO_COM_PA_FREQ, 0x70, 0x40},
12601};
12602
12603static void tasha_update_reg_reset_values(struct snd_soc_codec *codec)
12604{
12605 u32 i;
12606 struct wcd9xxx *tasha_core = dev_get_drvdata(codec->dev->parent);
12607
12608 if (TASHA_IS_1_1(tasha_core)) {
12609 for (i = 0; i < ARRAY_SIZE(tasha_reg_update_reset_val_1_1);
12610 i++)
12611 snd_soc_write(codec,
12612 tasha_reg_update_reset_val_1_1[i].reg,
12613 tasha_reg_update_reset_val_1_1[i].val);
12614 }
12615}
12616
12617static void tasha_codec_init_reg(struct snd_soc_codec *codec)
12618{
12619 u32 i;
12620 struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent);
12621
12622 for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_init_common_val); i++)
12623 snd_soc_update_bits(codec,
12624 tasha_codec_reg_init_common_val[i].reg,
12625 tasha_codec_reg_init_common_val[i].mask,
12626 tasha_codec_reg_init_common_val[i].val);
12627
12628 if (TASHA_IS_1_1(wcd9xxx) ||
12629 TASHA_IS_1_0(wcd9xxx))
12630 for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_init_1_x_val); i++)
12631 snd_soc_update_bits(codec,
12632 tasha_codec_reg_init_1_x_val[i].reg,
12633 tasha_codec_reg_init_1_x_val[i].mask,
12634 tasha_codec_reg_init_1_x_val[i].val);
12635
12636 if (TASHA_IS_1_1(wcd9xxx)) {
12637 for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_init_val_1_1); i++)
12638 snd_soc_update_bits(codec,
12639 tasha_codec_reg_init_val_1_1[i].reg,
12640 tasha_codec_reg_init_val_1_1[i].mask,
12641 tasha_codec_reg_init_val_1_1[i].val);
12642 } else if (TASHA_IS_1_0(wcd9xxx)) {
12643 for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_init_val_1_0); i++)
12644 snd_soc_update_bits(codec,
12645 tasha_codec_reg_init_val_1_0[i].reg,
12646 tasha_codec_reg_init_val_1_0[i].mask,
12647 tasha_codec_reg_init_val_1_0[i].val);
12648 } else if (TASHA_IS_2_0(wcd9xxx)) {
12649 for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_init_val_2_0); i++)
12650 snd_soc_update_bits(codec,
12651 tasha_codec_reg_init_val_2_0[i].reg,
12652 tasha_codec_reg_init_val_2_0[i].mask,
12653 tasha_codec_reg_init_val_2_0[i].val);
12654 }
12655}
12656
12657static void tasha_update_reg_defaults(struct tasha_priv *tasha)
12658{
12659 u32 i;
12660 struct wcd9xxx *wcd9xxx;
12661
12662 wcd9xxx = tasha->wcd9xxx;
12663 for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_defaults); i++)
12664 regmap_update_bits(wcd9xxx->regmap,
12665 tasha_codec_reg_defaults[i].reg,
12666 tasha_codec_reg_defaults[i].mask,
12667 tasha_codec_reg_defaults[i].val);
12668
12669 tasha->intf_type = wcd9xxx_get_intf_type();
12670 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C)
12671 for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_i2c_defaults); i++)
12672 regmap_update_bits(wcd9xxx->regmap,
12673 tasha_codec_reg_i2c_defaults[i].reg,
12674 tasha_codec_reg_i2c_defaults[i].mask,
12675 tasha_codec_reg_i2c_defaults[i].val);
12676
12677}
12678
12679static void tasha_slim_interface_init_reg(struct snd_soc_codec *codec)
12680{
12681 int i;
12682 struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec);
12683
12684 for (i = 0; i < WCD9XXX_SLIM_NUM_PORT_REG; i++)
12685 wcd9xxx_interface_reg_write(priv->wcd9xxx,
12686 TASHA_SLIM_PGD_PORT_INT_EN0 + i,
12687 0xFF);
12688}
12689
12690static irqreturn_t tasha_slimbus_irq(int irq, void *data)
12691{
12692 struct tasha_priv *priv = data;
12693 unsigned long status = 0;
12694 int i, j, port_id, k;
12695 u32 bit;
12696 u8 val, int_val = 0;
12697 bool tx, cleared;
12698 unsigned short reg = 0;
12699
12700 for (i = TASHA_SLIM_PGD_PORT_INT_STATUS_RX_0, j = 0;
12701 i <= TASHA_SLIM_PGD_PORT_INT_STATUS_TX_1; i++, j++) {
12702 val = wcd9xxx_interface_reg_read(priv->wcd9xxx, i);
12703 status |= ((u32)val << (8 * j));
12704 }
12705
12706 for_each_set_bit(j, &status, 32) {
12707 tx = (j >= 16 ? true : false);
12708 port_id = (tx ? j - 16 : j);
12709 val = wcd9xxx_interface_reg_read(priv->wcd9xxx,
12710 TASHA_SLIM_PGD_PORT_INT_RX_SOURCE0 + j);
12711 if (val) {
12712 if (!tx)
12713 reg = TASHA_SLIM_PGD_PORT_INT_EN0 +
12714 (port_id / 8);
12715 else
12716 reg = TASHA_SLIM_PGD_PORT_INT_TX_EN0 +
12717 (port_id / 8);
12718 int_val = wcd9xxx_interface_reg_read(
12719 priv->wcd9xxx, reg);
12720 /*
12721 * Ignore interrupts for ports for which the
12722 * interrupts are not specifically enabled.
12723 */
12724 if (!(int_val & (1 << (port_id % 8))))
12725 continue;
12726 }
12727 if (val & TASHA_SLIM_IRQ_OVERFLOW)
12728 pr_err_ratelimited(
12729 "%s: overflow error on %s port %d, value %x\n",
12730 __func__, (tx ? "TX" : "RX"), port_id, val);
12731 if (val & TASHA_SLIM_IRQ_UNDERFLOW)
12732 pr_err_ratelimited(
12733 "%s: underflow error on %s port %d, value %x\n",
12734 __func__, (tx ? "TX" : "RX"), port_id, val);
12735 if ((val & TASHA_SLIM_IRQ_OVERFLOW) ||
12736 (val & TASHA_SLIM_IRQ_UNDERFLOW)) {
12737 if (!tx)
12738 reg = TASHA_SLIM_PGD_PORT_INT_EN0 +
12739 (port_id / 8);
12740 else
12741 reg = TASHA_SLIM_PGD_PORT_INT_TX_EN0 +
12742 (port_id / 8);
12743 int_val = wcd9xxx_interface_reg_read(
12744 priv->wcd9xxx, reg);
12745 if (int_val & (1 << (port_id % 8))) {
12746 int_val = int_val ^ (1 << (port_id % 8));
12747 wcd9xxx_interface_reg_write(priv->wcd9xxx,
12748 reg, int_val);
12749 }
12750 }
12751 if (val & TASHA_SLIM_IRQ_PORT_CLOSED) {
12752 /*
12753 * INT SOURCE register starts from RX to TX
12754 * but port number in the ch_mask is in opposite way
12755 */
12756 bit = (tx ? j - 16 : j + 16);
12757 pr_debug("%s: %s port %d closed value %x, bit %u\n",
12758 __func__, (tx ? "TX" : "RX"), port_id, val,
12759 bit);
12760 for (k = 0, cleared = false; k < NUM_CODEC_DAIS; k++) {
12761 pr_debug("%s: priv->dai[%d].ch_mask = 0x%lx\n",
12762 __func__, k, priv->dai[k].ch_mask);
12763 if (test_and_clear_bit(bit,
12764 &priv->dai[k].ch_mask)) {
12765 cleared = true;
12766 if (!priv->dai[k].ch_mask)
12767 wake_up(&priv->dai[k].dai_wait);
12768 /*
12769 * There are cases when multiple DAIs
12770 * might be using the same slimbus
12771 * channel. Hence don't break here.
12772 */
12773 }
12774 }
12775 WARN(!cleared,
12776 "Couldn't find slimbus %s port %d for closing\n",
12777 (tx ? "TX" : "RX"), port_id);
12778 }
12779 wcd9xxx_interface_reg_write(priv->wcd9xxx,
12780 TASHA_SLIM_PGD_PORT_INT_CLR_RX_0 +
12781 (j / 8),
12782 1 << (j % 8));
12783 }
12784
12785 return IRQ_HANDLED;
12786}
12787
12788static int tasha_setup_irqs(struct tasha_priv *tasha)
12789{
12790 int ret = 0;
12791 struct snd_soc_codec *codec = tasha->codec;
12792 struct wcd9xxx *wcd9xxx = tasha->wcd9xxx;
12793 struct wcd9xxx_core_resource *core_res =
12794 &wcd9xxx->core_res;
12795
12796 ret = wcd9xxx_request_irq(core_res, WCD9XXX_IRQ_SLIMBUS,
12797 tasha_slimbus_irq, "SLIMBUS Slave", tasha);
12798 if (ret)
12799 pr_err("%s: Failed to request irq %d\n", __func__,
12800 WCD9XXX_IRQ_SLIMBUS);
12801 else
12802 tasha_slim_interface_init_reg(codec);
12803
12804 return ret;
12805}
12806
12807static void tasha_init_slim_slave_cfg(struct snd_soc_codec *codec)
12808{
12809 struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec);
12810 struct afe_param_cdc_slimbus_slave_cfg *cfg;
12811 struct wcd9xxx *wcd9xxx = priv->wcd9xxx;
12812 uint64_t eaddr = 0;
12813
12814 cfg = &priv->slimbus_slave_cfg;
12815 cfg->minor_version = 1;
12816 cfg->tx_slave_port_offset = 0;
12817 cfg->rx_slave_port_offset = 16;
12818
12819 memcpy(&eaddr, &wcd9xxx->slim->e_addr, sizeof(wcd9xxx->slim->e_addr));
12820 WARN_ON(sizeof(wcd9xxx->slim->e_addr) != 6);
12821 cfg->device_enum_addr_lsw = eaddr & 0xFFFFFFFF;
12822 cfg->device_enum_addr_msw = eaddr >> 32;
12823
12824 dev_dbg(codec->dev, "%s: slimbus logical address 0x%llx\n",
12825 __func__, eaddr);
12826}
12827
12828static void tasha_cleanup_irqs(struct tasha_priv *tasha)
12829{
12830 struct wcd9xxx *wcd9xxx = tasha->wcd9xxx;
12831 struct wcd9xxx_core_resource *core_res =
12832 &wcd9xxx->core_res;
12833
12834 wcd9xxx_free_irq(core_res, WCD9XXX_IRQ_SLIMBUS, tasha);
12835}
12836
12837static int tasha_handle_pdata(struct tasha_priv *tasha,
12838 struct wcd9xxx_pdata *pdata)
12839{
12840 struct snd_soc_codec *codec = tasha->codec;
12841 u8 dmic_ctl_val, mad_dmic_ctl_val;
12842 u8 anc_ctl_value;
12843 u32 def_dmic_rate, dmic_clk_drv;
12844 int vout_ctl_1, vout_ctl_2, vout_ctl_3, vout_ctl_4;
12845 int rc = 0;
12846
12847 if (!pdata) {
12848 dev_err(codec->dev, "%s: NULL pdata\n", __func__);
12849 return -ENODEV;
12850 }
12851
12852 /* set micbias voltage */
12853 vout_ctl_1 = wcd9335_get_micb_vout_ctl_val(pdata->micbias.micb1_mv);
12854 vout_ctl_2 = wcd9335_get_micb_vout_ctl_val(pdata->micbias.micb2_mv);
12855 vout_ctl_3 = wcd9335_get_micb_vout_ctl_val(pdata->micbias.micb3_mv);
12856 vout_ctl_4 = wcd9335_get_micb_vout_ctl_val(pdata->micbias.micb4_mv);
Xiaoyu Ye1a2d8bd92017-01-31 18:54:15 -080012857 if (vout_ctl_1 < 0 || vout_ctl_2 < 0 ||
12858 vout_ctl_3 < 0 || vout_ctl_4 < 0) {
Banajit Goswamide8271c2017-01-18 00:28:59 -080012859 rc = -EINVAL;
12860 goto done;
12861 }
12862 snd_soc_update_bits(codec, WCD9335_ANA_MICB1, 0x3F, vout_ctl_1);
12863 snd_soc_update_bits(codec, WCD9335_ANA_MICB2, 0x3F, vout_ctl_2);
12864 snd_soc_update_bits(codec, WCD9335_ANA_MICB3, 0x3F, vout_ctl_3);
12865 snd_soc_update_bits(codec, WCD9335_ANA_MICB4, 0x3F, vout_ctl_4);
12866
12867 /* Set the DMIC sample rate */
12868 switch (pdata->mclk_rate) {
12869 case TASHA_MCLK_CLK_9P6MHZ:
12870 def_dmic_rate = WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ;
12871 break;
12872 case TASHA_MCLK_CLK_12P288MHZ:
12873 def_dmic_rate = WCD9XXX_DMIC_SAMPLE_RATE_4P096MHZ;
12874 break;
12875 default:
12876 /* should never happen */
12877 dev_err(codec->dev, "%s: Invalid mclk_rate %d\n",
12878 __func__, pdata->mclk_rate);
12879 rc = -EINVAL;
12880 goto done;
12881 };
12882
12883 if (pdata->dmic_sample_rate ==
12884 WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED) {
12885 dev_info(codec->dev, "%s: dmic_rate invalid default = %d\n",
12886 __func__, def_dmic_rate);
12887 pdata->dmic_sample_rate = def_dmic_rate;
12888 }
12889 if (pdata->mad_dmic_sample_rate ==
12890 WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED) {
12891 dev_info(codec->dev, "%s: mad_dmic_rate invalid default = %d\n",
12892 __func__, def_dmic_rate);
12893 /*
12894 * use dmic_sample_rate as the default for MAD
12895 * if mad dmic sample rate is undefined
12896 */
12897 pdata->mad_dmic_sample_rate = pdata->dmic_sample_rate;
12898 }
12899 if (pdata->ecpp_dmic_sample_rate ==
12900 WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED) {
12901 dev_info(codec->dev,
12902 "%s: ecpp_dmic_rate invalid default = %d\n",
12903 __func__, def_dmic_rate);
12904 /*
12905 * use dmic_sample_rate as the default for ECPP DMIC
12906 * if ecpp dmic sample rate is undefined
12907 */
12908 pdata->ecpp_dmic_sample_rate = pdata->dmic_sample_rate;
12909 }
12910
12911 if (pdata->dmic_clk_drv ==
12912 WCD9XXX_DMIC_CLK_DRIVE_UNDEFINED) {
12913 pdata->dmic_clk_drv = WCD9335_DMIC_CLK_DRIVE_DEFAULT;
12914 dev_info(codec->dev,
12915 "%s: dmic_clk_strength invalid, default = %d\n",
12916 __func__, pdata->dmic_clk_drv);
12917 }
12918
12919 switch (pdata->dmic_clk_drv) {
12920 case 2:
12921 dmic_clk_drv = 0;
12922 break;
12923 case 4:
12924 dmic_clk_drv = 1;
12925 break;
12926 case 8:
12927 dmic_clk_drv = 2;
12928 break;
12929 case 16:
12930 dmic_clk_drv = 3;
12931 break;
12932 default:
12933 dev_err(codec->dev,
12934 "%s: invalid dmic_clk_drv %d, using default\n",
12935 __func__, pdata->dmic_clk_drv);
12936 dmic_clk_drv = 0;
12937 break;
12938 }
12939
12940 snd_soc_update_bits(codec, WCD9335_TEST_DEBUG_PAD_DRVCTL,
12941 0x0C, dmic_clk_drv << 2);
12942
12943 /*
12944 * Default the DMIC clk rates to mad_dmic_sample_rate,
12945 * whereas, the anc/txfe dmic rates to dmic_sample_rate
12946 * since the anc/txfe are independent of mad block.
12947 */
12948 mad_dmic_ctl_val = tasha_get_dmic_clk_val(tasha->codec,
12949 pdata->mclk_rate,
12950 pdata->mad_dmic_sample_rate);
12951 snd_soc_update_bits(codec, WCD9335_CPE_SS_DMIC0_CTL,
12952 0x0E, mad_dmic_ctl_val << 1);
12953 snd_soc_update_bits(codec, WCD9335_CPE_SS_DMIC1_CTL,
12954 0x0E, mad_dmic_ctl_val << 1);
12955 snd_soc_update_bits(codec, WCD9335_CPE_SS_DMIC2_CTL,
12956 0x0E, mad_dmic_ctl_val << 1);
12957
12958 dmic_ctl_val = tasha_get_dmic_clk_val(tasha->codec,
12959 pdata->mclk_rate,
12960 pdata->dmic_sample_rate);
12961
12962 if (dmic_ctl_val == WCD9335_DMIC_CLK_DIV_2)
12963 anc_ctl_value = WCD9335_ANC_DMIC_X2_FULL_RATE;
12964 else
12965 anc_ctl_value = WCD9335_ANC_DMIC_X2_HALF_RATE;
12966
12967 snd_soc_update_bits(codec, WCD9335_CDC_ANC0_MODE_2_CTL,
12968 0x40, anc_ctl_value << 6);
12969 snd_soc_update_bits(codec, WCD9335_CDC_ANC0_MODE_2_CTL,
12970 0x20, anc_ctl_value << 5);
12971 snd_soc_update_bits(codec, WCD9335_CDC_ANC1_MODE_2_CTL,
12972 0x40, anc_ctl_value << 6);
12973 snd_soc_update_bits(codec, WCD9335_CDC_ANC1_MODE_2_CTL,
12974 0x20, anc_ctl_value << 5);
12975done:
12976 return rc;
12977}
12978
12979static struct wcd_cpe_core *tasha_codec_get_cpe_core(
12980 struct snd_soc_codec *codec)
12981{
12982 struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec);
12983
12984 return priv->cpe_core;
12985}
12986
12987static int tasha_codec_cpe_fll_update_divider(
12988 struct snd_soc_codec *codec, u32 cpe_fll_rate)
12989{
12990 struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent);
12991 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
12992
12993 u32 div_val = 0, l_val = 0;
12994 u32 computed_cpe_fll;
12995
12996 if (cpe_fll_rate != CPE_FLL_CLK_75MHZ &&
12997 cpe_fll_rate != CPE_FLL_CLK_150MHZ) {
12998 dev_err(codec->dev,
12999 "%s: Invalid CPE fll rate request %u\n",
13000 __func__, cpe_fll_rate);
13001 return -EINVAL;
13002 }
13003
13004 if (wcd9xxx->mclk_rate == TASHA_MCLK_CLK_12P288MHZ) {
13005 /* update divider to 10 and enable 5x divider */
13006 snd_soc_write(codec, WCD9335_CPE_FLL_USER_CTL_1,
13007 0x55);
13008 div_val = 10;
13009 } else if (wcd9xxx->mclk_rate == TASHA_MCLK_CLK_9P6MHZ) {
13010 /* update divider to 8 and enable 2x divider */
13011 snd_soc_update_bits(codec, WCD9335_CPE_FLL_USER_CTL_0,
13012 0x7C, 0x70);
13013 snd_soc_update_bits(codec, WCD9335_CPE_FLL_USER_CTL_1,
13014 0xE0, 0x20);
13015 div_val = 8;
13016 } else {
13017 dev_err(codec->dev,
13018 "%s: Invalid MCLK rate %u\n",
13019 __func__, wcd9xxx->mclk_rate);
13020 return -EINVAL;
13021 }
13022
13023 l_val = ((cpe_fll_rate / 1000) * div_val) /
13024 (wcd9xxx->mclk_rate / 1000);
13025
13026 /* If l_val was integer truncated, increment l_val once */
13027 computed_cpe_fll = (wcd9xxx->mclk_rate / div_val) * l_val;
13028 if (computed_cpe_fll < cpe_fll_rate)
13029 l_val++;
13030
13031
13032 /* update L value LSB and MSB */
13033 snd_soc_write(codec, WCD9335_CPE_FLL_L_VAL_CTL_0,
13034 (l_val & 0xFF));
13035 snd_soc_write(codec, WCD9335_CPE_FLL_L_VAL_CTL_1,
13036 ((l_val >> 8) & 0xFF));
13037
13038 tasha->current_cpe_clk_freq = cpe_fll_rate;
13039 dev_dbg(codec->dev,
13040 "%s: updated l_val to %u for cpe_clk %u and mclk %u\n",
13041 __func__, l_val, cpe_fll_rate, wcd9xxx->mclk_rate);
13042
13043 return 0;
13044}
13045
13046static int __tasha_cdc_change_cpe_clk(struct snd_soc_codec *codec,
13047 u32 clk_freq)
13048{
13049 int ret = 0;
13050 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
13051
13052 if (!tasha_cdc_is_svs_enabled(tasha)) {
13053 dev_dbg(codec->dev,
13054 "%s: SVS not enabled or tasha is not 2p0, return\n",
13055 __func__);
13056 return 0;
13057 }
13058 dev_dbg(codec->dev, "%s: clk_freq = %u\n", __func__, clk_freq);
13059
13060 if (clk_freq == CPE_FLL_CLK_75MHZ) {
13061 /* Change to SVS */
13062 snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE,
13063 0x08, 0x08);
13064 if (tasha_codec_cpe_fll_update_divider(codec, clk_freq)) {
13065 ret = -EINVAL;
13066 goto done;
13067 }
13068
13069 snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE,
13070 0x10, 0x10);
13071
13072 clear_bit(CPE_NOMINAL, &tasha->status_mask);
13073 tasha_codec_update_sido_voltage(tasha, sido_buck_svs_voltage);
13074
13075 } else if (clk_freq == CPE_FLL_CLK_150MHZ) {
13076 /* change to nominal */
13077 snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE,
13078 0x08, 0x08);
13079
13080 set_bit(CPE_NOMINAL, &tasha->status_mask);
13081 tasha_codec_update_sido_voltage(tasha, SIDO_VOLTAGE_NOMINAL_MV);
13082
13083 if (tasha_codec_cpe_fll_update_divider(codec, clk_freq)) {
13084 ret = -EINVAL;
13085 goto done;
13086 }
13087 snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE,
13088 0x10, 0x10);
13089 } else {
13090 dev_err(codec->dev,
13091 "%s: Invalid clk_freq request %d for CPE FLL\n",
13092 __func__, clk_freq);
13093 ret = -EINVAL;
13094 }
13095
13096done:
13097 snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE,
13098 0x10, 0x00);
13099 snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE,
13100 0x08, 0x00);
13101 return ret;
13102}
13103
13104
13105static int tasha_codec_cpe_fll_enable(struct snd_soc_codec *codec,
13106 bool enable)
13107{
13108 struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent);
13109 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
13110 u8 clk_sel_reg_val = 0x00;
13111
13112 dev_dbg(codec->dev, "%s: enable = %s\n",
13113 __func__, enable ? "true" : "false");
13114
13115 if (enable) {
13116 if (tasha_cdc_is_svs_enabled(tasha)) {
13117 /* FLL enable is always at SVS */
13118 if (__tasha_cdc_change_cpe_clk(codec,
13119 CPE_FLL_CLK_75MHZ)) {
13120 dev_err(codec->dev,
13121 "%s: clk change to %d failed\n",
13122 __func__, CPE_FLL_CLK_75MHZ);
13123 return -EINVAL;
13124 }
13125 } else {
13126 if (tasha_codec_cpe_fll_update_divider(codec,
13127 CPE_FLL_CLK_75MHZ)) {
13128 dev_err(codec->dev,
13129 "%s: clk change to %d failed\n",
13130 __func__, CPE_FLL_CLK_75MHZ);
13131 return -EINVAL;
13132 }
13133 }
13134
13135 if (TASHA_IS_1_0(wcd9xxx)) {
13136 tasha_cdc_mclk_enable(codec, true, false);
13137 clk_sel_reg_val = 0x02;
13138 }
13139
13140 /* Setup CPE reference clk */
13141 snd_soc_update_bits(codec, WCD9335_ANA_CLK_TOP,
13142 0x02, clk_sel_reg_val);
13143
13144 /* enable CPE FLL reference clk */
13145 snd_soc_update_bits(codec, WCD9335_ANA_CLK_TOP,
13146 0x01, 0x01);
13147
13148 /* program the PLL */
13149 snd_soc_update_bits(codec, WCD9335_CPE_FLL_USER_CTL_0,
13150 0x01, 0x01);
13151
13152 /* TEST clk setting */
13153 snd_soc_update_bits(codec, WCD9335_CPE_FLL_TEST_CTL_0,
13154 0x80, 0x80);
13155 /* set FLL mode to HW controlled */
13156 snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE,
13157 0x60, 0x00);
13158 snd_soc_write(codec, WCD9335_CPE_FLL_FLL_MODE, 0x80);
13159 } else {
13160 /* disable CPE FLL reference clk */
13161 snd_soc_update_bits(codec, WCD9335_ANA_CLK_TOP,
13162 0x01, 0x00);
13163 /* undo TEST clk setting */
13164 snd_soc_update_bits(codec, WCD9335_CPE_FLL_TEST_CTL_0,
13165 0x80, 0x00);
13166 /* undo FLL mode to HW control */
13167 snd_soc_write(codec, WCD9335_CPE_FLL_FLL_MODE, 0x00);
13168 snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE,
13169 0x60, 0x20);
13170 /* undo the PLL */
13171 snd_soc_update_bits(codec, WCD9335_CPE_FLL_USER_CTL_0,
13172 0x01, 0x00);
13173
13174 if (TASHA_IS_1_0(wcd9xxx))
13175 tasha_cdc_mclk_enable(codec, false, false);
13176
13177 /*
13178 * FLL could get disabled while at nominal,
13179 * scale it back to SVS
13180 */
13181 if (tasha_cdc_is_svs_enabled(tasha))
13182 __tasha_cdc_change_cpe_clk(codec,
13183 CPE_FLL_CLK_75MHZ);
13184 }
13185
13186 return 0;
13187
13188}
13189
13190static void tasha_cdc_query_cpe_clk_plan(void *data,
13191 struct cpe_svc_cfg_clk_plan *clk_freq)
13192{
13193 struct snd_soc_codec *codec = data;
13194 struct tasha_priv *tasha;
13195 u32 cpe_clk_khz;
13196
13197 if (!codec) {
13198 pr_err("%s: Invalid codec handle\n",
13199 __func__);
13200 return;
13201 }
13202
13203 tasha = snd_soc_codec_get_drvdata(codec);
13204 cpe_clk_khz = tasha->current_cpe_clk_freq / 1000;
13205
13206 dev_dbg(codec->dev,
13207 "%s: current_clk_freq = %u\n",
13208 __func__, tasha->current_cpe_clk_freq);
13209
13210 clk_freq->current_clk_feq = cpe_clk_khz;
13211 clk_freq->num_clk_freqs = 2;
13212
13213 if (tasha_cdc_is_svs_enabled(tasha)) {
13214 clk_freq->clk_freqs[0] = CPE_FLL_CLK_75MHZ / 1000;
13215 clk_freq->clk_freqs[1] = CPE_FLL_CLK_150MHZ / 1000;
13216 } else {
13217 clk_freq->clk_freqs[0] = CPE_FLL_CLK_75MHZ;
13218 clk_freq->clk_freqs[1] = CPE_FLL_CLK_150MHZ;
13219 }
13220}
13221
13222static void tasha_cdc_change_cpe_clk(void *data,
13223 u32 clk_freq)
13224{
13225 struct snd_soc_codec *codec = data;
13226 struct tasha_priv *tasha;
13227 u32 cpe_clk_khz, req_freq = 0;
13228
13229 if (!codec) {
13230 pr_err("%s: Invalid codec handle\n",
13231 __func__);
13232 return;
13233 }
13234
13235 tasha = snd_soc_codec_get_drvdata(codec);
13236 cpe_clk_khz = tasha->current_cpe_clk_freq / 1000;
13237
13238 if (tasha_cdc_is_svs_enabled(tasha)) {
13239 if ((clk_freq * 1000) <= CPE_FLL_CLK_75MHZ)
13240 req_freq = CPE_FLL_CLK_75MHZ;
13241 else
13242 req_freq = CPE_FLL_CLK_150MHZ;
13243 }
13244
13245 dev_dbg(codec->dev,
13246 "%s: requested clk_freq = %u, current clk_freq = %u\n",
13247 __func__, clk_freq * 1000,
13248 tasha->current_cpe_clk_freq);
13249
13250 if (tasha_cdc_is_svs_enabled(tasha)) {
13251 if (__tasha_cdc_change_cpe_clk(codec, req_freq))
13252 dev_err(codec->dev,
13253 "%s: clock/voltage scaling failed\n",
13254 __func__);
13255 }
13256}
13257
13258static int tasha_codec_slim_reserve_bw(struct snd_soc_codec *codec,
13259 u32 bw_ops, bool commit)
13260{
13261 struct wcd9xxx *wcd9xxx;
13262
13263 if (!codec) {
13264 pr_err("%s: Invalid handle to codec\n",
13265 __func__);
13266 return -EINVAL;
13267 }
13268
13269 wcd9xxx = dev_get_drvdata(codec->dev->parent);
13270
13271 if (!wcd9xxx) {
13272 dev_err(codec->dev, "%s: Invalid parent drv_data\n",
13273 __func__);
13274 return -EINVAL;
13275 }
13276
13277 return wcd9xxx_slim_reserve_bw(wcd9xxx, bw_ops, commit);
13278}
13279
13280static int tasha_codec_vote_max_bw(struct snd_soc_codec *codec,
13281 bool vote)
13282{
13283 u32 bw_ops;
13284 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
13285
13286 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C)
13287 return 0;
13288
13289 if (vote)
13290 bw_ops = SLIM_BW_CLK_GEAR_9;
13291 else
13292 bw_ops = SLIM_BW_UNVOTE;
13293
13294 return tasha_codec_slim_reserve_bw(codec,
13295 bw_ops, true);
13296}
13297
13298static int tasha_cpe_err_irq_control(struct snd_soc_codec *codec,
13299 enum cpe_err_irq_cntl_type cntl_type, u8 *status)
13300{
13301 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
13302 u8 irq_bits;
13303
13304 if (TASHA_IS_2_0(tasha->wcd9xxx))
13305 irq_bits = 0xFF;
13306 else
13307 irq_bits = 0x3F;
13308
13309 if (status)
13310 irq_bits = (*status) & irq_bits;
13311
13312 switch (cntl_type) {
13313 case CPE_ERR_IRQ_MASK:
13314 snd_soc_update_bits(codec,
13315 WCD9335_CPE_SS_SS_ERROR_INT_MASK,
13316 irq_bits, irq_bits);
13317 break;
13318 case CPE_ERR_IRQ_UNMASK:
13319 snd_soc_update_bits(codec,
13320 WCD9335_CPE_SS_SS_ERROR_INT_MASK,
13321 irq_bits, 0x00);
13322 break;
13323 case CPE_ERR_IRQ_CLEAR:
13324 snd_soc_write(codec, WCD9335_CPE_SS_SS_ERROR_INT_CLEAR,
13325 irq_bits);
13326 break;
13327 case CPE_ERR_IRQ_STATUS:
13328 if (!status)
13329 return -EINVAL;
13330 *status = snd_soc_read(codec,
13331 WCD9335_CPE_SS_SS_ERROR_INT_STATUS);
13332 break;
13333 }
13334
13335 return 0;
13336}
13337
13338static const struct wcd_cpe_cdc_cb cpe_cb = {
13339 .cdc_clk_en = tasha_codec_internal_rco_ctrl,
13340 .cpe_clk_en = tasha_codec_cpe_fll_enable,
13341 .get_afe_out_port_id = tasha_codec_get_mad_port_id,
13342 .lab_cdc_ch_ctl = tasha_codec_enable_slimtx_mad,
13343 .cdc_ext_clk = tasha_cdc_mclk_enable,
13344 .bus_vote_bw = tasha_codec_vote_max_bw,
13345 .cpe_err_irq_control = tasha_cpe_err_irq_control,
13346};
13347
13348static struct cpe_svc_init_param cpe_svc_params = {
13349 .version = CPE_SVC_INIT_PARAM_V1,
13350 .query_freq_plans_cb = tasha_cdc_query_cpe_clk_plan,
13351 .change_freq_plan_cb = tasha_cdc_change_cpe_clk,
13352};
13353
13354static int tasha_cpe_initialize(struct snd_soc_codec *codec)
13355{
13356 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
13357 struct wcd_cpe_params cpe_params;
13358
13359 memset(&cpe_params, 0,
13360 sizeof(struct wcd_cpe_params));
13361 cpe_params.codec = codec;
13362 cpe_params.get_cpe_core = tasha_codec_get_cpe_core;
13363 cpe_params.cdc_cb = &cpe_cb;
13364 cpe_params.dbg_mode = cpe_debug_mode;
13365 cpe_params.cdc_major_ver = CPE_SVC_CODEC_WCD9335;
13366 cpe_params.cdc_minor_ver = CPE_SVC_CODEC_V1P0;
13367 cpe_params.cdc_id = CPE_SVC_CODEC_WCD9335;
13368
13369 cpe_params.cdc_irq_info.cpe_engine_irq =
13370 WCD9335_IRQ_SVA_OUTBOX1;
13371 cpe_params.cdc_irq_info.cpe_err_irq =
13372 WCD9335_IRQ_SVA_ERROR;
13373 cpe_params.cdc_irq_info.cpe_fatal_irqs =
13374 TASHA_CPE_FATAL_IRQS;
13375
13376 cpe_svc_params.context = codec;
13377 cpe_params.cpe_svc_params = &cpe_svc_params;
13378
13379 tasha->cpe_core = wcd_cpe_init("cpe_9335", codec,
13380 &cpe_params);
13381 if (IS_ERR_OR_NULL(tasha->cpe_core)) {
13382 dev_err(codec->dev,
13383 "%s: Failed to enable CPE\n",
13384 __func__);
13385 return -EINVAL;
13386 }
13387
13388 return 0;
13389}
13390
13391static const struct wcd_resmgr_cb tasha_resmgr_cb = {
13392 .cdc_rco_ctrl = __tasha_codec_internal_rco_ctrl,
13393};
13394
13395static int tasha_device_down(struct wcd9xxx *wcd9xxx)
13396{
13397 struct snd_soc_codec *codec;
13398 struct tasha_priv *priv;
13399 int count;
13400 int i = 0;
13401
13402 codec = (struct snd_soc_codec *)(wcd9xxx->ssr_priv);
13403 priv = snd_soc_codec_get_drvdata(codec);
13404 wcd_cpe_ssr_event(priv->cpe_core, WCD_CPE_BUS_DOWN_EVENT);
13405 for (i = 0; i < priv->nr; i++)
13406 swrm_wcd_notify(priv->swr_ctrl_data[i].swr_pdev,
13407 SWR_DEVICE_DOWN, NULL);
13408 snd_soc_card_change_online_state(codec->component.card, 0);
13409 for (count = 0; count < NUM_CODEC_DAIS; count++)
13410 priv->dai[count].bus_down_in_recovery = true;
13411
13412 priv->resmgr->sido_input_src = SIDO_SOURCE_INTERNAL;
13413
13414 return 0;
13415}
13416
13417static int tasha_post_reset_cb(struct wcd9xxx *wcd9xxx)
13418{
13419 int i, ret = 0;
13420 struct wcd9xxx *control;
13421 struct snd_soc_codec *codec;
13422 struct tasha_priv *tasha;
13423 struct wcd9xxx_pdata *pdata;
13424
13425 codec = (struct snd_soc_codec *)(wcd9xxx->ssr_priv);
13426 tasha = snd_soc_codec_get_drvdata(codec);
13427 control = dev_get_drvdata(codec->dev->parent);
13428
13429 wcd9xxx_set_power_state(tasha->wcd9xxx,
13430 WCD_REGION_POWER_COLLAPSE_REMOVE,
13431 WCD9XXX_DIG_CORE_REGION_1);
13432
13433 mutex_lock(&tasha->codec_mutex);
13434
13435 tasha_slimbus_slave_port_cfg.slave_dev_intfdev_la =
13436 control->slim_slave->laddr;
13437 tasha_slimbus_slave_port_cfg.slave_dev_pgd_la =
13438 control->slim->laddr;
13439 tasha_init_slim_slave_cfg(codec);
13440 if (tasha->machine_codec_event_cb)
13441 tasha->machine_codec_event_cb(codec,
13442 WCD9335_CODEC_EVENT_CODEC_UP);
13443 snd_soc_card_change_online_state(codec->component.card, 1);
13444
13445 /* Class-H Init*/
13446 wcd_clsh_init(&tasha->clsh_d);
Banajit Goswamide8271c2017-01-18 00:28:59 -080013447
13448 for (i = 0; i < TASHA_MAX_MICBIAS; i++)
13449 tasha->micb_ref[i] = 0;
13450
13451 tasha_update_reg_defaults(tasha);
13452
13453 tasha->codec = codec;
Banajit Goswamide8271c2017-01-18 00:28:59 -080013454
13455 dev_dbg(codec->dev, "%s: MCLK Rate = %x\n",
13456 __func__, control->mclk_rate);
13457
13458 if (control->mclk_rate == TASHA_MCLK_CLK_12P288MHZ)
13459 snd_soc_update_bits(codec, WCD9335_CODEC_RPM_CLK_MCLK_CFG,
13460 0x03, 0x00);
13461 else if (control->mclk_rate == TASHA_MCLK_CLK_9P6MHZ)
13462 snd_soc_update_bits(codec, WCD9335_CODEC_RPM_CLK_MCLK_CFG,
13463 0x03, 0x01);
13464 tasha_codec_init_reg(codec);
13465
13466 wcd_resmgr_post_ssr_v2(tasha->resmgr);
13467
13468 tasha_enable_efuse_sensing(codec);
13469
13470 regcache_mark_dirty(codec->component.regmap);
13471 regcache_sync(codec->component.regmap);
13472
13473 pdata = dev_get_platdata(codec->dev->parent);
13474 ret = tasha_handle_pdata(tasha, pdata);
Xiaoyu Ye1a2d8bd92017-01-31 18:54:15 -080013475 if (ret < 0)
Banajit Goswamide8271c2017-01-18 00:28:59 -080013476 dev_err(codec->dev, "%s: invalid pdata\n", __func__);
13477
13478 /* MBHC Init */
13479 wcd_mbhc_deinit(&tasha->mbhc);
13480 tasha->mbhc_started = false;
13481
13482 /* Initialize MBHC module */
13483 ret = wcd_mbhc_init(&tasha->mbhc, codec, &mbhc_cb, &intr_ids,
13484 wcd_mbhc_registers, TASHA_ZDET_SUPPORTED);
13485 if (ret)
13486 dev_err(codec->dev, "%s: mbhc initialization failed\n",
13487 __func__);
13488 else
13489 tasha_mbhc_hs_detect(codec, tasha->mbhc.mbhc_cfg);
13490
13491 tasha_cleanup_irqs(tasha);
13492 ret = tasha_setup_irqs(tasha);
13493 if (ret) {
13494 dev_err(codec->dev, "%s: tasha irq setup failed %d\n",
13495 __func__, ret);
13496 goto err;
13497 }
13498
13499 tasha_set_spkr_mode(codec, tasha->spkr_mode);
13500 wcd_cpe_ssr_event(tasha->cpe_core, WCD_CPE_BUS_UP_EVENT);
13501
13502err:
13503 mutex_unlock(&tasha->codec_mutex);
13504 return ret;
13505}
13506
13507static struct regulator *tasha_codec_find_ondemand_regulator(
13508 struct snd_soc_codec *codec, const char *name)
13509{
13510 int i;
13511 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
13512 struct wcd9xxx *wcd9xxx = tasha->wcd9xxx;
13513 struct wcd9xxx_pdata *pdata = dev_get_platdata(codec->dev->parent);
13514
13515 for (i = 0; i < wcd9xxx->num_of_supplies; ++i) {
13516 if (pdata->regulator[i].ondemand &&
13517 wcd9xxx->supplies[i].supply &&
13518 !strcmp(wcd9xxx->supplies[i].supply, name))
13519 return wcd9xxx->supplies[i].consumer;
13520 }
13521
13522 dev_dbg(tasha->dev, "Warning: regulator not found:%s\n",
13523 name);
13524 return NULL;
13525}
13526
Banajit Goswami2be7b482017-02-03 23:32:37 -080013527static int tasha_codec_probe(struct snd_soc_codec *codec)
Banajit Goswamide8271c2017-01-18 00:28:59 -080013528{
13529 struct wcd9xxx *control;
13530 struct tasha_priv *tasha;
13531 struct wcd9xxx_pdata *pdata;
13532 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
13533 int i, ret;
13534 void *ptr = NULL;
13535 struct regulator *supply;
13536
13537 control = dev_get_drvdata(codec->dev->parent);
13538
13539 dev_info(codec->dev, "%s()\n", __func__);
13540 tasha = snd_soc_codec_get_drvdata(codec);
13541 tasha->intf_type = wcd9xxx_get_intf_type();
13542
13543 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
13544 control->dev_down = tasha_device_down;
13545 control->post_reset = tasha_post_reset_cb;
13546 control->ssr_priv = (void *)codec;
13547 }
13548
13549 /* Resource Manager post Init */
13550 ret = wcd_resmgr_post_init(tasha->resmgr, &tasha_resmgr_cb, codec);
13551 if (ret) {
13552 dev_err(codec->dev, "%s: wcd resmgr post init failed\n",
13553 __func__);
13554 goto err;
13555 }
13556 /* Class-H Init*/
13557 wcd_clsh_init(&tasha->clsh_d);
13558 /* Default HPH Mode to Class-H HiFi */
13559 tasha->hph_mode = CLS_H_HIFI;
13560
13561 tasha->codec = codec;
13562 for (i = 0; i < COMPANDER_MAX; i++)
13563 tasha->comp_enabled[i] = 0;
13564
13565 tasha->spkr_gain_offset = RX_GAIN_OFFSET_0_DB;
13566 tasha->intf_type = wcd9xxx_get_intf_type();
13567 tasha_update_reg_reset_values(codec);
13568 pr_debug("%s: MCLK Rate = %x\n", __func__, control->mclk_rate);
13569 if (control->mclk_rate == TASHA_MCLK_CLK_12P288MHZ)
13570 snd_soc_update_bits(codec, WCD9335_CODEC_RPM_CLK_MCLK_CFG,
13571 0x03, 0x00);
13572 else if (control->mclk_rate == TASHA_MCLK_CLK_9P6MHZ)
13573 snd_soc_update_bits(codec, WCD9335_CODEC_RPM_CLK_MCLK_CFG,
13574 0x03, 0x01);
13575 tasha_codec_init_reg(codec);
13576
13577 tasha_enable_efuse_sensing(codec);
13578
13579 pdata = dev_get_platdata(codec->dev->parent);
13580 ret = tasha_handle_pdata(tasha, pdata);
Xiaoyu Ye1a2d8bd92017-01-31 18:54:15 -080013581 if (ret < 0) {
Banajit Goswamide8271c2017-01-18 00:28:59 -080013582 pr_err("%s: bad pdata\n", __func__);
13583 goto err;
13584 }
13585
13586 supply = tasha_codec_find_ondemand_regulator(codec,
13587 on_demand_supply_name[ON_DEMAND_MICBIAS]);
13588 if (supply) {
13589 tasha->on_demand_list[ON_DEMAND_MICBIAS].supply = supply;
13590 tasha->on_demand_list[ON_DEMAND_MICBIAS].ondemand_supply_count =
13591 0;
13592 }
13593
13594 tasha->fw_data = devm_kzalloc(codec->dev,
13595 sizeof(*(tasha->fw_data)), GFP_KERNEL);
13596 if (!tasha->fw_data)
13597 goto err;
13598 set_bit(WCD9XXX_ANC_CAL, tasha->fw_data->cal_bit);
13599 set_bit(WCD9XXX_MBHC_CAL, tasha->fw_data->cal_bit);
13600 set_bit(WCD9XXX_MAD_CAL, tasha->fw_data->cal_bit);
13601 set_bit(WCD9XXX_VBAT_CAL, tasha->fw_data->cal_bit);
13602
13603 ret = wcd_cal_create_hwdep(tasha->fw_data,
13604 WCD9XXX_CODEC_HWDEP_NODE, codec);
13605 if (ret < 0) {
13606 dev_err(codec->dev, "%s hwdep failed %d\n", __func__, ret);
13607 goto err_hwdep;
13608 }
13609
13610 /* Initialize MBHC module */
13611 if (TASHA_IS_2_0(tasha->wcd9xxx)) {
13612 wcd_mbhc_registers[WCD_MBHC_FSM_STATUS].reg =
13613 WCD9335_MBHC_FSM_STATUS;
13614 wcd_mbhc_registers[WCD_MBHC_FSM_STATUS].mask = 0x01;
13615 }
13616 ret = wcd_mbhc_init(&tasha->mbhc, codec, &mbhc_cb, &intr_ids,
13617 wcd_mbhc_registers, TASHA_ZDET_SUPPORTED);
13618 if (ret) {
13619 pr_err("%s: mbhc initialization failed\n", __func__);
13620 goto err_hwdep;
13621 }
13622
13623 ptr = devm_kzalloc(codec->dev, (sizeof(tasha_rx_chs) +
13624 sizeof(tasha_tx_chs)), GFP_KERNEL);
13625 if (!ptr) {
13626 ret = -ENOMEM;
13627 goto err_hwdep;
13628 }
13629
13630 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
13631 snd_soc_dapm_new_controls(dapm, tasha_dapm_i2s_widgets,
13632 ARRAY_SIZE(tasha_dapm_i2s_widgets));
13633 snd_soc_dapm_add_routes(dapm, audio_i2s_map,
13634 ARRAY_SIZE(audio_i2s_map));
13635 for (i = 0; i < ARRAY_SIZE(tasha_i2s_dai); i++) {
13636 INIT_LIST_HEAD(&tasha->dai[i].wcd9xxx_ch_list);
13637 init_waitqueue_head(&tasha->dai[i].dai_wait);
13638 }
13639 } else if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
13640 for (i = 0; i < NUM_CODEC_DAIS; i++) {
13641 INIT_LIST_HEAD(&tasha->dai[i].wcd9xxx_ch_list);
13642 init_waitqueue_head(&tasha->dai[i].dai_wait);
13643 }
13644 tasha_slimbus_slave_port_cfg.slave_dev_intfdev_la =
13645 control->slim_slave->laddr;
13646 tasha_slimbus_slave_port_cfg.slave_dev_pgd_la =
13647 control->slim->laddr;
13648 tasha_slimbus_slave_port_cfg.slave_port_mapping[0] =
13649 TASHA_TX13;
13650 tasha_init_slim_slave_cfg(codec);
13651 }
13652
13653 snd_soc_add_codec_controls(codec, impedance_detect_controls,
13654 ARRAY_SIZE(impedance_detect_controls));
13655 snd_soc_add_codec_controls(codec, hph_type_detect_controls,
13656 ARRAY_SIZE(hph_type_detect_controls));
13657
13658 snd_soc_add_codec_controls(codec,
13659 tasha_analog_gain_controls,
13660 ARRAY_SIZE(tasha_analog_gain_controls));
13661 control->num_rx_port = TASHA_RX_MAX;
13662 control->rx_chs = ptr;
13663 memcpy(control->rx_chs, tasha_rx_chs, sizeof(tasha_rx_chs));
13664 control->num_tx_port = TASHA_TX_MAX;
13665 control->tx_chs = ptr + sizeof(tasha_rx_chs);
13666 memcpy(control->tx_chs, tasha_tx_chs, sizeof(tasha_tx_chs));
13667
13668 snd_soc_dapm_ignore_suspend(dapm, "AIF1 Playback");
13669 snd_soc_dapm_ignore_suspend(dapm, "AIF1 Capture");
13670 snd_soc_dapm_ignore_suspend(dapm, "AIF2 Playback");
13671 snd_soc_dapm_ignore_suspend(dapm, "AIF2 Capture");
13672
13673 if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
13674 snd_soc_dapm_ignore_suspend(dapm, "AIF3 Playback");
13675 snd_soc_dapm_ignore_suspend(dapm, "AIF3 Capture");
13676 snd_soc_dapm_ignore_suspend(dapm, "AIF4 Playback");
13677 snd_soc_dapm_ignore_suspend(dapm, "AIF Mix Playback");
13678 snd_soc_dapm_ignore_suspend(dapm, "AIF4 MAD TX");
13679 snd_soc_dapm_ignore_suspend(dapm, "VIfeed");
13680 snd_soc_dapm_ignore_suspend(dapm, "AIF5 CPE TX");
13681 }
13682
13683 snd_soc_dapm_sync(dapm);
13684
13685 ret = tasha_setup_irqs(tasha);
13686 if (ret) {
13687 pr_err("%s: tasha irq setup failed %d\n", __func__, ret);
13688 goto err_pdata;
13689 }
13690
13691 ret = tasha_cpe_initialize(codec);
13692 if (ret) {
13693 dev_err(codec->dev,
13694 "%s: cpe initialization failed, err = %d\n",
13695 __func__, ret);
13696 /* Do not fail probe if CPE failed */
13697 ret = 0;
13698 }
13699
13700 for (i = 0; i < TASHA_NUM_DECIMATORS; i++) {
13701 tasha->tx_hpf_work[i].tasha = tasha;
13702 tasha->tx_hpf_work[i].decimator = i;
13703 INIT_DELAYED_WORK(&tasha->tx_hpf_work[i].dwork,
13704 tasha_tx_hpf_corner_freq_callback);
13705 }
13706
13707 for (i = 0; i < TASHA_NUM_DECIMATORS; i++) {
13708 tasha->tx_mute_dwork[i].tasha = tasha;
13709 tasha->tx_mute_dwork[i].decimator = i;
13710 INIT_DELAYED_WORK(&tasha->tx_mute_dwork[i].dwork,
13711 tasha_tx_mute_update_callback);
13712 }
13713
13714 tasha->spk_anc_dwork.tasha = tasha;
13715 INIT_DELAYED_WORK(&tasha->spk_anc_dwork.dwork,
13716 tasha_spk_anc_update_callback);
13717
13718 mutex_lock(&tasha->codec_mutex);
13719 snd_soc_dapm_disable_pin(dapm, "ANC LINEOUT1");
13720 snd_soc_dapm_disable_pin(dapm, "ANC LINEOUT2");
13721 snd_soc_dapm_disable_pin(dapm, "ANC LINEOUT1 PA");
13722 snd_soc_dapm_disable_pin(dapm, "ANC LINEOUT2 PA");
13723 snd_soc_dapm_disable_pin(dapm, "ANC HPHL");
13724 snd_soc_dapm_disable_pin(dapm, "ANC HPHR");
13725 snd_soc_dapm_disable_pin(dapm, "ANC HPHL PA");
13726 snd_soc_dapm_disable_pin(dapm, "ANC HPHR PA");
13727 snd_soc_dapm_disable_pin(dapm, "ANC EAR PA");
13728 snd_soc_dapm_disable_pin(dapm, "ANC EAR");
13729 snd_soc_dapm_disable_pin(dapm, "ANC SPK1 PA");
13730 mutex_unlock(&tasha->codec_mutex);
13731 snd_soc_dapm_sync(dapm);
13732
13733 return ret;
13734
13735err_pdata:
13736 devm_kfree(codec->dev, ptr);
13737 control->rx_chs = NULL;
13738 control->tx_chs = NULL;
13739err_hwdep:
13740 devm_kfree(codec->dev, tasha->fw_data);
13741 tasha->fw_data = NULL;
13742err:
13743 return ret;
13744}
13745
Banajit Goswami2be7b482017-02-03 23:32:37 -080013746static int tasha_codec_remove(struct snd_soc_codec *codec)
Banajit Goswamide8271c2017-01-18 00:28:59 -080013747{
13748 struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
13749 struct wcd9xxx *control;
13750
13751 control = dev_get_drvdata(codec->dev->parent);
13752 control->rx_chs = NULL;
13753 control->tx_chs = NULL;
13754
13755 tasha_cleanup_irqs(tasha);
13756 /* Cleanup MBHC */
13757 /* Cleanup resmgr */
Banajit Goswamie0b20e12017-02-05 18:11:11 -080013758
13759 return 0;
Banajit Goswamide8271c2017-01-18 00:28:59 -080013760}
13761
13762static struct regmap *tasha_get_regmap(struct device *dev)
13763{
13764 struct wcd9xxx *control = dev_get_drvdata(dev->parent);
13765
13766 return control->regmap;
13767}
13768
13769static struct snd_soc_codec_driver soc_codec_dev_tasha = {
Banajit Goswami2be7b482017-02-03 23:32:37 -080013770 .probe = tasha_codec_probe,
13771 .remove = tasha_codec_remove,
Banajit Goswamide8271c2017-01-18 00:28:59 -080013772 .get_regmap = tasha_get_regmap,
Banajit Goswami8e306f02016-12-15 20:49:07 -080013773 .component_driver = {
Banajit Goswamiaf472112017-01-29 22:15:11 -080013774 .controls = tasha_snd_controls,
13775 .num_controls = ARRAY_SIZE(tasha_snd_controls),
Banajit Goswami8e306f02016-12-15 20:49:07 -080013776 .dapm_widgets = tasha_dapm_widgets,
13777 .num_dapm_widgets = ARRAY_SIZE(tasha_dapm_widgets),
13778 .dapm_routes = audio_map,
13779 .num_dapm_routes = ARRAY_SIZE(audio_map),
13780 },
Banajit Goswamide8271c2017-01-18 00:28:59 -080013781};
13782
13783#ifdef CONFIG_PM
13784static int tasha_suspend(struct device *dev)
13785{
13786 struct platform_device *pdev = to_platform_device(dev);
13787 struct tasha_priv *tasha = platform_get_drvdata(pdev);
13788
13789 dev_dbg(dev, "%s: system suspend\n", __func__);
13790 if (cancel_delayed_work_sync(&tasha->power_gate_work))
13791 tasha_codec_power_gate_digital_core(tasha);
13792
13793 return 0;
13794}
13795
13796static int tasha_resume(struct device *dev)
13797{
13798 struct platform_device *pdev = to_platform_device(dev);
13799 struct tasha_priv *tasha = platform_get_drvdata(pdev);
13800
13801 if (!tasha) {
13802 dev_err(dev, "%s: tasha private data is NULL\n", __func__);
13803 return -EINVAL;
13804 }
13805 dev_dbg(dev, "%s: system resume\n", __func__);
13806 return 0;
13807}
13808
13809static const struct dev_pm_ops tasha_pm_ops = {
13810 .suspend = tasha_suspend,
13811 .resume = tasha_resume,
13812};
13813#endif
13814
13815static int tasha_swrm_read(void *handle, int reg)
13816{
13817 struct tasha_priv *tasha;
13818 struct wcd9xxx *wcd9xxx;
13819 unsigned short swr_rd_addr_base;
13820 unsigned short swr_rd_data_base;
13821 int val, ret;
13822
13823 if (!handle) {
13824 pr_err("%s: NULL handle\n", __func__);
13825 return -EINVAL;
13826 }
13827 tasha = (struct tasha_priv *)handle;
13828 wcd9xxx = tasha->wcd9xxx;
13829
13830 dev_dbg(tasha->dev, "%s: Reading soundwire register, 0x%x\n",
13831 __func__, reg);
13832 swr_rd_addr_base = WCD9335_SWR_AHB_BRIDGE_RD_ADDR_0;
13833 swr_rd_data_base = WCD9335_SWR_AHB_BRIDGE_RD_DATA_0;
13834 /* read_lock */
13835 mutex_lock(&tasha->swr_read_lock);
13836 ret = regmap_bulk_write(wcd9xxx->regmap, swr_rd_addr_base,
13837 (u8 *)&reg, 4);
13838 if (ret < 0) {
13839 pr_err("%s: RD Addr Failure\n", __func__);
13840 goto err;
13841 }
13842 /* Check for RD status */
13843 ret = regmap_bulk_read(wcd9xxx->regmap, swr_rd_data_base,
13844 (u8 *)&val, 4);
13845 if (ret < 0) {
13846 pr_err("%s: RD Data Failure\n", __func__);
13847 goto err;
13848 }
13849 ret = val;
13850err:
13851 /* read_unlock */
13852 mutex_unlock(&tasha->swr_read_lock);
13853 return ret;
13854}
13855
13856static int tasha_swrm_i2s_bulk_write(struct wcd9xxx *wcd9xxx,
13857 struct wcd9xxx_reg_val *bulk_reg,
13858 size_t len)
13859{
13860 int i, ret = 0;
13861 unsigned short swr_wr_addr_base;
13862 unsigned short swr_wr_data_base;
13863
13864 swr_wr_addr_base = WCD9335_SWR_AHB_BRIDGE_WR_ADDR_0;
13865 swr_wr_data_base = WCD9335_SWR_AHB_BRIDGE_WR_DATA_0;
13866
13867 for (i = 0; i < (len * 2); i += 2) {
13868 /* First Write the Data to register */
13869 ret = regmap_bulk_write(wcd9xxx->regmap,
13870 swr_wr_data_base, bulk_reg[i].buf, 4);
13871 if (ret < 0) {
13872 dev_err(wcd9xxx->dev, "%s: WR Data Failure\n",
13873 __func__);
13874 break;
13875 }
13876 /* Next Write Address */
13877 ret = regmap_bulk_write(wcd9xxx->regmap,
13878 swr_wr_addr_base, bulk_reg[i+1].buf, 4);
13879 if (ret < 0) {
13880 dev_err(wcd9xxx->dev, "%s: WR Addr Failure\n",
13881 __func__);
13882 break;
13883 }
13884 }
13885 return ret;
13886}
13887
13888static int tasha_swrm_bulk_write(void *handle, u32 *reg, u32 *val, size_t len)
13889{
13890 struct tasha_priv *tasha;
13891 struct wcd9xxx *wcd9xxx;
13892 struct wcd9xxx_reg_val *bulk_reg;
13893 unsigned short swr_wr_addr_base;
13894 unsigned short swr_wr_data_base;
13895 int i, j, ret;
13896
13897 if (!handle) {
13898 pr_err("%s: NULL handle\n", __func__);
13899 return -EINVAL;
13900 }
13901 if (len <= 0) {
13902 pr_err("%s: Invalid size: %zu\n", __func__, len);
13903 return -EINVAL;
13904 }
13905 tasha = (struct tasha_priv *)handle;
13906 wcd9xxx = tasha->wcd9xxx;
13907
13908 swr_wr_addr_base = WCD9335_SWR_AHB_BRIDGE_WR_ADDR_0;
13909 swr_wr_data_base = WCD9335_SWR_AHB_BRIDGE_WR_DATA_0;
13910
13911 bulk_reg = kzalloc((2 * len * sizeof(struct wcd9xxx_reg_val)),
13912 GFP_KERNEL);
13913 if (!bulk_reg)
13914 return -ENOMEM;
13915
13916 for (i = 0, j = 0; i < (len * 2); i += 2, j++) {
13917 bulk_reg[i].reg = swr_wr_data_base;
13918 bulk_reg[i].buf = (u8 *)(&val[j]);
13919 bulk_reg[i].bytes = 4;
13920 bulk_reg[i+1].reg = swr_wr_addr_base;
13921 bulk_reg[i+1].buf = (u8 *)(&reg[j]);
13922 bulk_reg[i+1].bytes = 4;
13923 }
13924 mutex_lock(&tasha->swr_write_lock);
13925
13926 if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C) {
13927 ret = tasha_swrm_i2s_bulk_write(wcd9xxx, bulk_reg, len);
13928 if (ret) {
13929 dev_err(tasha->dev, "%s: i2s bulk write failed, ret: %d\n",
13930 __func__, ret);
13931 }
13932 } else {
13933 ret = wcd9xxx_slim_bulk_write(wcd9xxx, bulk_reg,
13934 (len * 2), false);
13935 if (ret) {
13936 dev_err(tasha->dev, "%s: swrm bulk write failed, ret: %d\n",
13937 __func__, ret);
13938 }
13939 }
13940
13941 mutex_unlock(&tasha->swr_write_lock);
13942 kfree(bulk_reg);
13943
13944 return ret;
13945}
13946
13947static int tasha_swrm_write(void *handle, int reg, int val)
13948{
13949 struct tasha_priv *tasha;
13950 struct wcd9xxx *wcd9xxx;
13951 unsigned short swr_wr_addr_base;
13952 unsigned short swr_wr_data_base;
13953 struct wcd9xxx_reg_val bulk_reg[2];
13954 int ret;
13955
13956 if (!handle) {
13957 pr_err("%s: NULL handle\n", __func__);
13958 return -EINVAL;
13959 }
13960 tasha = (struct tasha_priv *)handle;
13961 wcd9xxx = tasha->wcd9xxx;
13962
13963 swr_wr_addr_base = WCD9335_SWR_AHB_BRIDGE_WR_ADDR_0;
13964 swr_wr_data_base = WCD9335_SWR_AHB_BRIDGE_WR_DATA_0;
13965
13966 /* First Write the Data to register */
13967 bulk_reg[0].reg = swr_wr_data_base;
13968 bulk_reg[0].buf = (u8 *)(&val);
13969 bulk_reg[0].bytes = 4;
13970 bulk_reg[1].reg = swr_wr_addr_base;
13971 bulk_reg[1].buf = (u8 *)(&reg);
13972 bulk_reg[1].bytes = 4;
13973
13974 mutex_lock(&tasha->swr_write_lock);
13975
13976 if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C) {
13977 ret = tasha_swrm_i2s_bulk_write(wcd9xxx, bulk_reg, 1);
13978 if (ret) {
13979 dev_err(tasha->dev, "%s: i2s swrm write failed, ret: %d\n",
13980 __func__, ret);
13981 }
13982 } else {
13983 ret = wcd9xxx_slim_bulk_write(wcd9xxx, bulk_reg, 2, false);
13984 if (ret < 0)
13985 pr_err("%s: WR Data Failure\n", __func__);
13986 }
13987
13988 mutex_unlock(&tasha->swr_write_lock);
13989 return ret;
13990}
13991
13992static int tasha_swrm_clock(void *handle, bool enable)
13993{
13994 struct tasha_priv *tasha = (struct tasha_priv *) handle;
13995
13996 mutex_lock(&tasha->swr_clk_lock);
13997
13998 dev_dbg(tasha->dev, "%s: swrm clock %s\n",
13999 __func__, (enable?"enable" : "disable"));
14000 if (enable) {
14001 tasha->swr_clk_users++;
14002 if (tasha->swr_clk_users == 1) {
14003 if (TASHA_IS_2_0(tasha->wcd9xxx))
14004 regmap_update_bits(
14005 tasha->wcd9xxx->regmap,
14006 WCD9335_TEST_DEBUG_NPL_DLY_TEST_1,
14007 0x10, 0x00);
14008 __tasha_cdc_mclk_enable(tasha, true);
14009 regmap_update_bits(tasha->wcd9xxx->regmap,
14010 WCD9335_CDC_CLK_RST_CTRL_SWR_CONTROL,
14011 0x01, 0x01);
14012 }
14013 } else {
14014 tasha->swr_clk_users--;
14015 if (tasha->swr_clk_users == 0) {
14016 regmap_update_bits(tasha->wcd9xxx->regmap,
14017 WCD9335_CDC_CLK_RST_CTRL_SWR_CONTROL,
14018 0x01, 0x00);
14019 __tasha_cdc_mclk_enable(tasha, false);
14020 if (TASHA_IS_2_0(tasha->wcd9xxx))
14021 regmap_update_bits(
14022 tasha->wcd9xxx->regmap,
14023 WCD9335_TEST_DEBUG_NPL_DLY_TEST_1,
14024 0x10, 0x10);
14025 }
14026 }
14027 dev_dbg(tasha->dev, "%s: swrm clock users %d\n",
14028 __func__, tasha->swr_clk_users);
14029 mutex_unlock(&tasha->swr_clk_lock);
14030 return 0;
14031}
14032
14033static int tasha_swrm_handle_irq(void *handle,
14034 irqreturn_t (*swrm_irq_handler)(int irq,
14035 void *data),
14036 void *swrm_handle,
14037 int action)
14038{
14039 struct tasha_priv *tasha;
14040 int ret = 0;
14041 struct wcd9xxx *wcd9xxx;
14042
14043 if (!handle) {
14044 pr_err("%s: null handle received\n", __func__);
14045 return -EINVAL;
14046 }
14047 tasha = (struct tasha_priv *) handle;
14048 wcd9xxx = tasha->wcd9xxx;
14049
14050 if (action) {
14051 ret = wcd9xxx_request_irq(&wcd9xxx->core_res,
14052 WCD9335_IRQ_SOUNDWIRE,
14053 swrm_irq_handler,
14054 "Tasha SWR Master", swrm_handle);
14055 if (ret)
14056 dev_err(tasha->dev, "%s: Failed to request irq %d\n",
14057 __func__, WCD9335_IRQ_SOUNDWIRE);
14058 } else
14059 wcd9xxx_free_irq(&wcd9xxx->core_res, WCD9335_IRQ_SOUNDWIRE,
14060 swrm_handle);
14061
14062 return ret;
14063}
14064
14065static void tasha_add_child_devices(struct work_struct *work)
14066{
14067 struct tasha_priv *tasha;
14068 struct platform_device *pdev;
14069 struct device_node *node;
14070 struct wcd9xxx *wcd9xxx;
14071 struct tasha_swr_ctrl_data *swr_ctrl_data = NULL, *temp;
14072 int ret, ctrl_num = 0;
14073 struct wcd_swr_ctrl_platform_data *platdata;
14074 char plat_dev_name[WCD9335_STRING_LEN];
14075
14076 tasha = container_of(work, struct tasha_priv,
14077 tasha_add_child_devices_work);
14078 if (!tasha) {
14079 pr_err("%s: Memory for WCD9335 does not exist\n",
14080 __func__);
14081 return;
14082 }
14083 wcd9xxx = tasha->wcd9xxx;
14084 if (!wcd9xxx) {
14085 pr_err("%s: Memory for WCD9XXX does not exist\n",
14086 __func__);
14087 return;
14088 }
14089 if (!wcd9xxx->dev->of_node) {
14090 pr_err("%s: DT node for wcd9xxx does not exist\n",
14091 __func__);
14092 return;
14093 }
14094
14095 platdata = &tasha->swr_plat_data;
14096
14097 for_each_child_of_node(wcd9xxx->dev->of_node, node) {
14098 if (!strcmp(node->name, "swr_master"))
14099 strlcpy(plat_dev_name, "tasha_swr_ctrl",
14100 (WCD9335_STRING_LEN - 1));
14101 else if (strnstr(node->name, "msm_cdc_pinctrl",
14102 strlen("msm_cdc_pinctrl")) != NULL)
14103 strlcpy(plat_dev_name, node->name,
14104 (WCD9335_STRING_LEN - 1));
14105 else
14106 continue;
14107
14108 pdev = platform_device_alloc(plat_dev_name, -1);
14109 if (!pdev) {
14110 dev_err(wcd9xxx->dev, "%s: pdev memory alloc failed\n",
14111 __func__);
14112 ret = -ENOMEM;
14113 goto err;
14114 }
14115 pdev->dev.parent = tasha->dev;
14116 pdev->dev.of_node = node;
14117
14118 if (!strcmp(node->name, "swr_master")) {
14119 ret = platform_device_add_data(pdev, platdata,
14120 sizeof(*platdata));
14121 if (ret) {
14122 dev_err(&pdev->dev,
14123 "%s: cannot add plat data ctrl:%d\n",
14124 __func__, ctrl_num);
14125 goto fail_pdev_add;
14126 }
14127 }
14128
14129 ret = platform_device_add(pdev);
14130 if (ret) {
14131 dev_err(&pdev->dev,
14132 "%s: Cannot add platform device\n",
14133 __func__);
14134 goto fail_pdev_add;
14135 }
14136
14137 if (!strcmp(node->name, "swr_master")) {
14138 temp = krealloc(swr_ctrl_data,
14139 (ctrl_num + 1) * sizeof(
14140 struct tasha_swr_ctrl_data),
14141 GFP_KERNEL);
14142 if (!temp) {
14143 dev_err(wcd9xxx->dev, "out of memory\n");
14144 ret = -ENOMEM;
14145 goto err;
14146 }
14147 swr_ctrl_data = temp;
14148 swr_ctrl_data[ctrl_num].swr_pdev = pdev;
14149 ctrl_num++;
14150 dev_dbg(&pdev->dev,
14151 "%s: Added soundwire ctrl device(s)\n",
14152 __func__);
14153 tasha->nr = ctrl_num;
14154 tasha->swr_ctrl_data = swr_ctrl_data;
14155 }
14156 }
14157
14158 return;
14159fail_pdev_add:
14160 platform_device_put(pdev);
14161err:
14162 return;
14163}
14164
14165/*
14166 * tasha_codec_ver: to get tasha codec version
14167 * @codec: handle to snd_soc_codec *
14168 * return enum codec_variant - version
14169 */
14170enum codec_variant tasha_codec_ver(void)
14171{
14172 return codec_ver;
14173}
14174EXPORT_SYMBOL(tasha_codec_ver);
14175
14176static int __tasha_enable_efuse_sensing(struct tasha_priv *tasha)
14177{
14178 int val, rc;
14179
14180 __tasha_cdc_mclk_enable(tasha, true);
14181
14182 regmap_update_bits(tasha->wcd9xxx->regmap,
14183 WCD9335_CHIP_TIER_CTRL_EFUSE_CTL, 0x1E, 0x20);
14184 regmap_update_bits(tasha->wcd9xxx->regmap,
14185 WCD9335_CHIP_TIER_CTRL_EFUSE_CTL, 0x01, 0x01);
14186
14187 /*
14188 * 5ms sleep required after enabling efuse control
14189 * before checking the status.
14190 */
14191 usleep_range(5000, 5500);
14192 rc = regmap_read(tasha->wcd9xxx->regmap,
14193 WCD9335_CHIP_TIER_CTRL_EFUSE_STATUS, &val);
14194
14195 if (rc || (!(val & 0x01)))
14196 WARN(1, "%s: Efuse sense is not complete\n", __func__);
14197
14198 __tasha_cdc_mclk_enable(tasha, false);
14199
14200 return rc;
14201}
14202
14203void tasha_get_codec_ver(struct tasha_priv *tasha)
14204{
14205 int i;
14206 int val;
14207 struct tasha_reg_mask_val codec_reg[] = {
14208 {WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT10, 0xFF, 0xFF},
14209 {WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT11, 0xFF, 0x83},
14210 {WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT12, 0xFF, 0x0A},
14211 };
14212
14213 __tasha_enable_efuse_sensing(tasha);
14214 for (i = 0; i < ARRAY_SIZE(codec_reg); i++) {
14215 regmap_read(tasha->wcd9xxx->regmap, codec_reg[i].reg, &val);
14216 if (!(val && codec_reg[i].val)) {
14217 codec_ver = WCD9335;
14218 goto ret;
14219 }
14220 }
14221 codec_ver = WCD9326;
14222ret:
14223 pr_debug("%s: codec is %d\n", __func__, codec_ver);
14224}
14225EXPORT_SYMBOL(tasha_get_codec_ver);
14226
14227static int tasha_probe(struct platform_device *pdev)
14228{
14229 int ret = 0;
14230 struct tasha_priv *tasha;
14231 struct clk *wcd_ext_clk, *wcd_native_clk;
14232 struct wcd9xxx_resmgr_v2 *resmgr;
14233 struct wcd9xxx_power_region *cdc_pwr;
14234
14235 if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C) {
14236 if (apr_get_subsys_state() == APR_SUBSYS_DOWN) {
14237 dev_err(&pdev->dev, "%s: dsp down\n", __func__);
14238 return -EPROBE_DEFER;
14239 }
14240 }
14241
14242 tasha = devm_kzalloc(&pdev->dev, sizeof(struct tasha_priv),
14243 GFP_KERNEL);
14244 if (!tasha)
14245 return -ENOMEM;
14246 platform_set_drvdata(pdev, tasha);
14247
14248 tasha->wcd9xxx = dev_get_drvdata(pdev->dev.parent);
14249 tasha->dev = &pdev->dev;
14250 INIT_DELAYED_WORK(&tasha->power_gate_work, tasha_codec_power_gate_work);
14251 mutex_init(&tasha->power_lock);
14252 mutex_init(&tasha->sido_lock);
14253 INIT_WORK(&tasha->tasha_add_child_devices_work,
14254 tasha_add_child_devices);
14255 BLOCKING_INIT_NOTIFIER_HEAD(&tasha->notifier);
14256 mutex_init(&tasha->micb_lock);
14257 mutex_init(&tasha->swr_read_lock);
14258 mutex_init(&tasha->swr_write_lock);
14259 mutex_init(&tasha->swr_clk_lock);
14260 mutex_init(&tasha->mclk_lock);
14261
14262 cdc_pwr = devm_kzalloc(&pdev->dev, sizeof(struct wcd9xxx_power_region),
14263 GFP_KERNEL);
14264 if (!cdc_pwr) {
14265 ret = -ENOMEM;
14266 goto err_cdc_pwr;
14267 }
14268 tasha->wcd9xxx->wcd9xxx_pwr[WCD9XXX_DIG_CORE_REGION_1] = cdc_pwr;
14269 cdc_pwr->pwr_collapse_reg_min = TASHA_DIG_CORE_REG_MIN;
14270 cdc_pwr->pwr_collapse_reg_max = TASHA_DIG_CORE_REG_MAX;
14271 wcd9xxx_set_power_state(tasha->wcd9xxx,
14272 WCD_REGION_POWER_COLLAPSE_REMOVE,
14273 WCD9XXX_DIG_CORE_REGION_1);
14274
14275 mutex_init(&tasha->codec_mutex);
14276 /*
14277 * Init resource manager so that if child nodes such as SoundWire
14278 * requests for clock, resource manager can honor the request
14279 */
14280 resmgr = wcd_resmgr_init(&tasha->wcd9xxx->core_res, NULL);
14281 if (IS_ERR(resmgr)) {
14282 ret = PTR_ERR(resmgr);
14283 dev_err(&pdev->dev, "%s: Failed to initialize wcd resmgr\n",
14284 __func__);
14285 goto err_resmgr;
14286 }
14287 tasha->resmgr = resmgr;
14288 tasha->swr_plat_data.handle = (void *) tasha;
14289 tasha->swr_plat_data.read = tasha_swrm_read;
14290 tasha->swr_plat_data.write = tasha_swrm_write;
14291 tasha->swr_plat_data.bulk_write = tasha_swrm_bulk_write;
14292 tasha->swr_plat_data.clk = tasha_swrm_clock;
14293 tasha->swr_plat_data.handle_irq = tasha_swrm_handle_irq;
14294
14295 /* Register for Clock */
14296 wcd_ext_clk = clk_get(tasha->wcd9xxx->dev, "wcd_clk");
14297 if (IS_ERR(wcd_ext_clk)) {
14298 dev_err(tasha->wcd9xxx->dev, "%s: clk get %s failed\n",
14299 __func__, "wcd_ext_clk");
14300 goto err_clk;
14301 }
14302 tasha->wcd_ext_clk = wcd_ext_clk;
14303 tasha->sido_voltage = SIDO_VOLTAGE_NOMINAL_MV;
14304 set_bit(AUDIO_NOMINAL, &tasha->status_mask);
14305 tasha->sido_ccl_cnt = 0;
14306
14307 /* Register native clk for 44.1 playback */
14308 wcd_native_clk = clk_get(tasha->wcd9xxx->dev, "wcd_native_clk");
14309 if (IS_ERR(wcd_native_clk))
14310 dev_dbg(tasha->wcd9xxx->dev, "%s: clk get %s failed\n",
14311 __func__, "wcd_native_clk");
14312 else
14313 tasha->wcd_native_clk = wcd_native_clk;
14314
14315 if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_SLIMBUS)
14316 ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_tasha,
14317 tasha_dai, ARRAY_SIZE(tasha_dai));
14318 else if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C)
14319 ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_tasha,
14320 tasha_i2s_dai,
14321 ARRAY_SIZE(tasha_i2s_dai));
14322 else
14323 ret = -EINVAL;
14324 if (ret) {
14325 dev_err(&pdev->dev, "%s: Codec registration failed, ret = %d\n",
14326 __func__, ret);
14327 goto err_cdc_reg;
14328 }
14329 /* Update codec register default values */
14330 tasha_update_reg_defaults(tasha);
14331 schedule_work(&tasha->tasha_add_child_devices_work);
14332 tasha_get_codec_ver(tasha);
14333
14334 dev_info(&pdev->dev, "%s: Tasha driver probe done\n", __func__);
14335 return ret;
14336
14337err_cdc_reg:
14338 clk_put(tasha->wcd_ext_clk);
14339 if (tasha->wcd_native_clk)
14340 clk_put(tasha->wcd_native_clk);
14341err_clk:
14342 wcd_resmgr_remove(tasha->resmgr);
14343err_resmgr:
14344 devm_kfree(&pdev->dev, cdc_pwr);
14345err_cdc_pwr:
14346 mutex_destroy(&tasha->mclk_lock);
14347 devm_kfree(&pdev->dev, tasha);
14348 return ret;
14349}
14350
14351static int tasha_remove(struct platform_device *pdev)
14352{
14353 struct tasha_priv *tasha;
14354
14355 tasha = platform_get_drvdata(pdev);
14356
14357 mutex_destroy(&tasha->codec_mutex);
14358 clk_put(tasha->wcd_ext_clk);
14359 if (tasha->wcd_native_clk)
14360 clk_put(tasha->wcd_native_clk);
14361 mutex_destroy(&tasha->mclk_lock);
14362 devm_kfree(&pdev->dev, tasha);
14363 snd_soc_unregister_codec(&pdev->dev);
14364 return 0;
14365}
14366
14367static struct platform_driver tasha_codec_driver = {
14368 .probe = tasha_probe,
14369 .remove = tasha_remove,
14370 .driver = {
14371 .name = "tasha_codec",
14372 .owner = THIS_MODULE,
14373#ifdef CONFIG_PM
14374 .pm = &tasha_pm_ops,
14375#endif
14376 },
14377};
14378
14379module_platform_driver(tasha_codec_driver);
14380
14381MODULE_DESCRIPTION("Tasha Codec driver");
14382MODULE_LICENSE("GPL v2");